Tempus  Version of the Day
Time Integration
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
VanDerPolModel_impl.hpp
Go to the documentation of this file.
1 // @HEADER
2 // ****************************************************************************
3 // Tempus: Copyright (2017) Sandia Corporation
4 //
5 // Distributed under BSD 3-clause license (See accompanying file Copyright.txt)
6 // ****************************************************************************
7 // @HEADER
8 
9 #ifndef TEMPUS_TEST_VANDERPOL_MODEL_IMPL_HPP
10 #define TEMPUS_TEST_VANDERPOL_MODEL_IMPL_HPP
11 
12 #include "Teuchos_StandardParameterEntryValidators.hpp"
13 
14 #include "Thyra_DefaultSpmdVectorSpace.hpp"
15 #include "Thyra_DetachedVectorView.hpp"
16 #include "Thyra_DetachedMultiVectorView.hpp"
17 #include "Thyra_DefaultSerialDenseLinearOpWithSolveFactory.hpp"
18 #include "Thyra_DefaultMultiVectorLinearOpWithSolve.hpp"
19 #include "Thyra_DefaultLinearOpSource.hpp"
20 #include "Thyra_VectorStdOps.hpp"
21 
22 #include <iostream>
23 
24 namespace Tempus_Test {
25 
26 template <class Scalar>
29 {
30  isInitialized_ = false;
31  dim_ = 2;
32  Np_ = 1; // Number of parameter vectors (1)
33  np_ = 1; // Number of parameters in this vector (1)
34  Ng_ = 0; // Number of observation functions (0)
35  ng_ = 0; // Number of elements in this observation function (0)
36  acceptModelParams_ = false;
37  haveIC_ = true;
38  epsilon_ = 1.0e-06;
39  x0_ic_ = 2.0;
40  x1_ic_ = 0.0;
41  t0_ic_ = 0.0;
42 
43  // Create x_space and f_space
44  x_space_ = Thyra::defaultSpmdVectorSpace<Scalar>(dim_);
45  f_space_ = Thyra::defaultSpmdVectorSpace<Scalar>(dim_);
46  // Create p_space and g_space
47  p_space_ = Thyra::defaultSpmdVectorSpace<Scalar>(np_);
48  g_space_ = Thyra::defaultSpmdVectorSpace<Scalar>(ng_);
49 
50  setParameterList(pList_);
51 }
52 
53 template <class Scalar>
56 {
58  true, std::logic_error,
59  "Error - No exact solution for van der Pol problem!\n");
60  return (inArgs_);
61 }
62 
63 template <class Scalar>
66 {
68  !isInitialized_, std::logic_error,
69  "Error - No exact sensitivities for van der Pol problem!\n");
70  return (inArgs_);
71 }
72 
73 template <class Scalar>
76 {
77  return x_space_;
78 }
79 
80 template <class Scalar>
83 {
84  return f_space_;
85 }
86 
87 template <class Scalar>
90 {
91  TEUCHOS_TEST_FOR_EXCEPTION(!isInitialized_, std::logic_error,
92  "Error, setupInOutArgs_ must be called first!\n");
93  return nominalValues_;
94 }
95 
96 template <class Scalar>
99 {
100  using Teuchos::RCP;
102  this->get_W_factory();
103  RCP<Thyra::LinearOpBase<Scalar> > matrix = this->create_W_op();
104  {
105  // 01/20/09 tscoffe: This is a total hack to provide a full rank matrix to
106  // linearOpWithSolve because it ends up factoring the matrix during
107  // initialization, which it really shouldn't do, or I'm doing something
108  // wrong here. The net effect is that I get exceptions thrown in
109  // optimized mode due to the matrix being rank deficient unless I do this.
111  Teuchos::rcp_dynamic_cast<Thyra::MultiVectorBase<Scalar> >(matrix,
112  true);
113  {
114  RCP<Thyra::VectorBase<Scalar> > vec = Thyra::createMember(x_space_);
115  {
116  Thyra::DetachedVectorView<Scalar> vec_view(*vec);
117  vec_view[0] = 0.0;
118  vec_view[1] = 1.0;
119  }
120  V_V(multivec->col(0).ptr(), *vec);
121  {
122  Thyra::DetachedVectorView<Scalar> vec_view(*vec);
123  vec_view[0] = 1.0;
124  vec_view[1] = 0.0;
125  }
126  V_V(multivec->col(1).ptr(), *vec);
127  }
128  }
130  Thyra::linearOpWithSolve<Scalar>(*W_factory, matrix);
131 
132  return W;
133 }
134 
135 template <class Scalar>
137  const
138 {
140  Thyra::createMembers(x_space_, dim_);
141  return (matrix);
142 }
143 
144 template <class Scalar>
147 {
149  Thyra::defaultSerialDenseLinearOpWithSolveFactory<Scalar>();
150  return W_factory;
151 }
152 
153 template <class Scalar>
155  const
156 {
157  setupInOutArgs_();
158  return inArgs_;
159 }
160 
161 // Private functions overridden from ModelEvaluatorDefaultBase
162 
163 template <class Scalar>
166 {
167  setupInOutArgs_();
168  return outArgs_;
169 }
170 
171 template <class Scalar>
174  const Thyra::ModelEvaluatorBase::OutArgs<Scalar> &outArgs) const
175 {
176  using Teuchos::RCP;
177  TEUCHOS_TEST_FOR_EXCEPTION(!isInitialized_, std::logic_error,
178  "Error, setupInOutArgs_ must be called first!\n");
179 
181  inArgs.get_x().assert_not_null();
183 
184  // double t = inArgs.get_t();
185  Scalar epsilon = epsilon_;
186  if (acceptModelParams_) {
188  inArgs.get_p(0).assert_not_null();
190  epsilon = p_in_view[0];
191  }
192 
193  Scalar beta = inArgs.get_beta();
194 
195  const RCP<Thyra::VectorBase<Scalar> > f_out = outArgs.get_f();
196  const RCP<Thyra::LinearOpBase<Scalar> > W_out = outArgs.get_W_op();
198  if (acceptModelParams_) {
200  DfDp_out = DfDp.getMultiVector();
201  }
202 
203  if (inArgs.get_x_dot().is_null()) {
204  // Evaluate the Explicit ODE f(x,t) [= xdot]
205  if (!is_null(f_out)) {
206  Thyra::DetachedVectorView<Scalar> f_out_view(*f_out);
207  f_out_view[0] = x_in_view[1];
208  f_out_view[1] =
209  ((1.0 - x_in_view[0] * x_in_view[0]) * x_in_view[1] - x_in_view[0]) /
210  epsilon;
211  }
212  if (!is_null(W_out)) {
214  Teuchos::rcp_dynamic_cast<Thyra::MultiVectorBase<Scalar> >(W_out,
215  true);
216  Thyra::DetachedMultiVectorView<Scalar> matrix_view(*matrix);
217  matrix_view(0, 0) = 0.0; // d(f0)/d(x0_n)
218  matrix_view(0, 1) = +beta; // d(f0)/d(x1_n)
219  matrix_view(1, 0) = -beta * (2.0 * x_in_view[0] * x_in_view[1] + 1.0) /
220  epsilon; // d(f1)/d(x0_n)
221  matrix_view(1, 1) = beta * (1.0 - x_in_view[0] * x_in_view[0]) /
222  epsilon; // d(f1)/d(x1_n)
223  // Note: alpha = d(xdot)/d(x_n) and beta = d(x)/d(x_n)
224  }
225  if (!is_null(DfDp_out)) {
226  Thyra::DetachedMultiVectorView<Scalar> DfDp_out_view(*DfDp_out);
227  DfDp_out_view(0, 0) = 0.0;
228  DfDp_out_view(1, 0) =
229  -((1.0 - x_in_view[0] * x_in_view[0]) * x_in_view[1] - x_in_view[0]) /
230  (epsilon * epsilon);
231  }
232  }
233  else {
234  // Evaluate the implicit ODE f(xdot, x, t) [= 0]
236  x_dot_in = inArgs.get_x_dot().assert_not_null();
237  Scalar alpha = inArgs.get_alpha();
238  if (!is_null(f_out)) {
239  Thyra::DetachedVectorView<Scalar> f_out_view(*f_out);
240  Thyra::ConstDetachedVectorView<Scalar> x_dot_in_view(*x_dot_in);
241  f_out_view[0] = x_dot_in_view[0] - x_in_view[1];
242  f_out_view[1] =
243  x_dot_in_view[1] -
244  ((1.0 - x_in_view[0] * x_in_view[0]) * x_in_view[1] - x_in_view[0]) /
245  epsilon;
246  }
247  if (!is_null(W_out)) {
249  Teuchos::rcp_dynamic_cast<Thyra::MultiVectorBase<Scalar> >(W_out,
250  true);
251  Thyra::DetachedMultiVectorView<Scalar> matrix_view(*matrix);
252  matrix_view(0, 0) = alpha; // d(f0)/d(x0_n)
253  matrix_view(0, 1) = -beta; // d(f0)/d(x1_n)
254  matrix_view(1, 0) = beta * (2.0 * x_in_view[0] * x_in_view[1] + 1.0) /
255  epsilon; // d(f1)/d(x0_n)
256  matrix_view(1, 1) = alpha - beta * (1.0 - x_in_view[0] * x_in_view[0]) /
257  epsilon; // d(f1)/d(x1_n)
258  // Note: alpha = d(xdot)/d(x_n) and beta = d(x)/d(x_n)
259  }
260  if (!is_null(DfDp_out)) {
261  Thyra::DetachedMultiVectorView<Scalar> DfDp_out_view(*DfDp_out);
262  DfDp_out_view(0, 0) = 0.0;
263  DfDp_out_view(1, 0) =
264  ((1.0 - x_in_view[0] * x_in_view[0]) * x_in_view[1] - x_in_view[0]) /
265  (epsilon * epsilon);
266  }
267  }
268 }
269 
270 template <class Scalar>
273 {
274  if (!acceptModelParams_) {
275  return Teuchos::null;
276  }
278  return p_space_;
279 }
280 
281 template <class Scalar>
284 {
285  if (!acceptModelParams_) {
286  return Teuchos::null;
287  }
291  p_strings->push_back("Model Coefficient: epsilon");
292  return p_strings;
293 }
294 
295 template <class Scalar>
298 {
300  return g_space_;
301 }
302 
303 // private
304 
305 template <class Scalar>
307 {
308  if (isInitialized_) {
309  return;
310  }
311 
312  {
313  // Set up prototypical InArgs
315  inArgs.setModelEvalDescription(this->description());
316  inArgs.setSupports(Thyra::ModelEvaluatorBase::IN_ARG_t);
317  inArgs.setSupports(Thyra::ModelEvaluatorBase::IN_ARG_x);
318  inArgs.setSupports(Thyra::ModelEvaluatorBase::IN_ARG_beta);
319  inArgs.setSupports(Thyra::ModelEvaluatorBase::IN_ARG_x_dot);
320  inArgs.setSupports(Thyra::ModelEvaluatorBase::IN_ARG_alpha);
321  if (acceptModelParams_) {
322  inArgs.set_Np(Np_);
323  }
324  inArgs_ = inArgs;
325  }
326 
327  {
328  // Set up prototypical OutArgs
330  outArgs.setModelEvalDescription(this->description());
331  outArgs.setSupports(Thyra::ModelEvaluatorBase::OUT_ARG_f);
332  outArgs.setSupports(Thyra::ModelEvaluatorBase::OUT_ARG_W_op);
333  if (acceptModelParams_) {
334  outArgs.set_Np_Ng(Np_, Ng_);
335  outArgs.setSupports(Thyra::ModelEvaluatorBase::OUT_ARG_DfDp, 0,
336  Thyra::ModelEvaluatorBase::DERIV_MV_JACOBIAN_FORM);
337  }
338  outArgs_ = outArgs;
339  }
340 
341  // Set up nominal values
342  nominalValues_ = inArgs_;
343  if (haveIC_) {
344  using Teuchos::RCP;
345  nominalValues_.set_t(t0_ic_);
346  const RCP<Thyra::VectorBase<Scalar> > x_ic = createMember(x_space_);
347  { // scope to delete DetachedVectorView
348  Thyra::DetachedVectorView<Scalar> x_ic_view(*x_ic);
349  x_ic_view[0] = x0_ic_;
350  x_ic_view[1] = x1_ic_;
351  }
352  nominalValues_.set_x(x_ic);
353  if (acceptModelParams_) {
354  const RCP<Thyra::VectorBase<Scalar> > p_ic = createMember(p_space_);
355  {
356  Thyra::DetachedVectorView<Scalar> p_ic_view(*p_ic);
357  p_ic_view[0] = epsilon_;
358  }
359  nominalValues_.set_p(0, p_ic);
360  }
361  const RCP<Thyra::VectorBase<Scalar> > x_dot_ic = createMember(x_space_);
362  { // scope to delete DetachedVectorView
363  Thyra::DetachedVectorView<Scalar> x_dot_ic_view(*x_dot_ic);
364  x_dot_ic_view[0] = x1_ic_;
365  x_dot_ic_view[1] = ((1.0 - x0_ic_ * x0_ic_) * x1_ic_ - x0_ic_) / epsilon_;
366  }
367  nominalValues_.set_x_dot(x_dot_ic);
368  }
369 
370  isInitialized_ = true;
371 }
372 
373 template <class Scalar>
375  Teuchos::RCP<Teuchos::ParameterList> const &paramList)
376 {
377  using Teuchos::get;
380  Teuchos::rcp(new ParameterList("VanDerPolModel"));
381  if (paramList != Teuchos::null) tmpPL = paramList;
382  tmpPL->validateParametersAndSetDefaults(*this->getValidParameters());
383  this->setMyParamList(tmpPL);
384  Teuchos::RCP<ParameterList> pl = this->getMyNonconstParamList();
385  bool acceptModelParams = get<bool>(*pl, "Accept model parameters");
386  bool haveIC = get<bool>(*pl, "Provide nominal values");
387  if ((acceptModelParams != acceptModelParams_) || (haveIC != haveIC_)) {
388  isInitialized_ = false;
389  }
390  acceptModelParams_ = acceptModelParams;
391  haveIC_ = haveIC;
392  epsilon_ = get<Scalar>(*pl, "Coeff epsilon");
393  x0_ic_ = get<Scalar>(*pl, "IC x0");
394  x1_ic_ = get<Scalar>(*pl, "IC x1");
395  t0_ic_ = get<Scalar>(*pl, "IC t0");
396  setupInOutArgs_();
397 }
398 
399 template <class Scalar>
402 {
404  if (is_null(validPL)) {
405  Teuchos::RCP<Teuchos::ParameterList> pl = Teuchos::parameterList();
406  pl->set("Accept model parameters", false);
407  pl->set("Provide nominal values", true);
408  Teuchos::setDoubleParameter("Coeff epsilon", 1.0e-06,
409  "Coefficient a in model", &*pl);
410  Teuchos::setDoubleParameter("IC x0", 2.0, "Initial Condition for x0", &*pl);
411  Teuchos::setDoubleParameter("IC x1", 0.0, "Initial Condition for x1", &*pl);
412  Teuchos::setDoubleParameter("IC t0", 0.0, "Initial time t0", &*pl);
413  Teuchos::setIntParameter("Number of Time Step Sizes", 1,
414  "Number time step sizes for convergence study",
415  &*pl);
416  validPL = pl;
417  }
418  return validPL;
419 }
420 
421 } // namespace Tempus_Test
422 #endif // TEMPUS_TEST_VANDERPOL_MODEL_IMPL_HPP
Teuchos::RCP< const Teuchos::ParameterList > getValidParameters() const
bool is_null(const boost::shared_ptr< T > &p)
Derivative< Scalar > get_DfDp(int l) const
RCP< const VectorBase< Scalar > > get_x_dot() const
void setModelEvalDescription(const std::string &modelEvalDescription)
ParameterList & set(std::string const &name, T const &value, std::string const &docString="", RCP< const ParameterEntryValidator > const &validator=null)
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Evaluation< VectorBase< Scalar > > get_f() const
Thyra::ModelEvaluatorBase::InArgs< Scalar > getNominalValues() const
Thyra::ModelEvaluatorBase::InArgs< Scalar > getExactSolution(double t) const
Thyra::ModelEvaluatorBase::InArgs< Scalar > createInArgs() const
Teuchos::RCP< const Thyra::LinearOpWithSolveFactoryBase< Scalar > > get_W_factory() const
VanDerPolModel(Teuchos::RCP< Teuchos::ParameterList > pList=Teuchos::null)
#define TEUCHOS_ASSERT_IN_RANGE_UPPER_EXCLUSIVE(index, lower_inclusive, upper_exclusive)
void setSupports(EInArgsMembers arg, bool supports=true)
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Teuchos::RCP< Thyra::LinearOpBase< Scalar > > create_W_op() const
Teuchos::RCP< Thyra::LinearOpWithSolveBase< Scalar > > create_W() const
Ptr< T > ptr() const
void validateParametersAndSetDefaults(ParameterList const &validParamList, int const depth=1000)
void evalModelImpl(const Thyra::ModelEvaluatorBase::InArgs< Scalar > &inArgs_bar, const Thyra::ModelEvaluatorBase::OutArgs< Scalar > &outArgs_bar) const
Teuchos::RCP< const Teuchos::Array< std::string > > get_p_names(int l) const
Teuchos::RCP< const Thyra::VectorSpaceBase< Scalar > > get_g_space(int j) const
void setSupports(EOutArgsMembers arg, bool supports=true)
void setParameterList(Teuchos::RCP< Teuchos::ParameterList > const &paramList)
Teuchos::RCP< const Thyra::VectorSpaceBase< Scalar > > get_x_space() const
Thyra::ModelEvaluatorBase::InArgs< Scalar > getExactSensSolution(int j, double t) const
Teuchos::RCP< const Thyra::VectorSpaceBase< Scalar > > get_p_space(int l) const
void setModelEvalDescription(const std::string &modelEvalDescription)
RCP< LinearOpBase< Scalar > > get_W_op() const
RCP< const VectorBase< Scalar > > get_x() const
Thyra::ModelEvaluatorBase::OutArgs< Scalar > createOutArgsImpl() const
RCP< const VectorBase< Scalar > > get_p(int l) const
Teuchos::RCP< const Thyra::VectorSpaceBase< Scalar > > get_f_space() const
RCP< MultiVectorBase< Scalar > > getMultiVector() const