Tempus  Version of the Day
Time Integration
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DahlquistTestModel_impl.hpp
Go to the documentation of this file.
1 //@HEADER
2 // *****************************************************************************
3 // Tempus: Time Integration and Sensitivity Analysis Package
4 //
5 // Copyright 2017 NTESS and the Tempus contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 //@HEADER
9 
10 #ifndef TEMPUS_TEST_DAHLQUIST_TEST_MODEL_IMPL_HPP
11 #define TEMPUS_TEST_DAHLQUIST_TEST_MODEL_IMPL_HPP
12 
13 #include "Thyra_DefaultSpmdVectorSpace.hpp"
14 #include "Thyra_DetachedVectorView.hpp"
15 #include "Thyra_DetachedMultiVectorView.hpp"
16 #include "Thyra_DefaultSerialDenseLinearOpWithSolveFactory.hpp"
17 #include "Thyra_DefaultMultiVectorLinearOpWithSolve.hpp"
18 #include "Thyra_DefaultLinearOpSource.hpp"
19 #include "Thyra_VectorStdOps.hpp"
20 #include "Thyra_MultiVectorStdOps.hpp"
21 #include "Thyra_DefaultMultiVectorProductVector.hpp"
22 
23 //#include <iostream>
24 
25 namespace Tempus_Test {
26 
27 template <class Scalar>
29 {
30  constructDahlquistTestModel(-1.0, false);
31 }
32 
33 template <class Scalar>
34 DahlquistTestModel<Scalar>::DahlquistTestModel(Scalar lambda, bool includeXDot)
35 {
36  constructDahlquistTestModel(lambda, includeXDot);
37 }
38 
39 template <class Scalar>
41  bool includeXDot)
42 {
43  lambda_ = lambda;
44  includeXDot_ = includeXDot;
45  isInitialized_ = false;
46  xIC_ = Scalar(1.0);
47  xDotIC_ = Scalar(lambda);
48  dim_ = 1;
49  haveIC_ = true;
50  Np_ = 1;
51  np_ = 1;
52  Ng_ = 1;
53  ng_ = dim_;
54  acceptModelParams_ = false;
55 
56  // Create x_space and f_space
57  x_space_ = Thyra::defaultSpmdVectorSpace<Scalar>(dim_);
58  f_space_ = Thyra::defaultSpmdVectorSpace<Scalar>(dim_);
59 
60  using Teuchos::RCP;
61  typedef Thyra::ModelEvaluatorBase MEB;
62  {
63  // Set up prototypical InArgs
64  MEB::InArgsSetup<Scalar> inArgs;
65  inArgs.setModelEvalDescription(this->description());
66  inArgs.setSupports(MEB::IN_ARG_t);
67  inArgs.setSupports(MEB::IN_ARG_x);
68  inArgs.setSupports(MEB::IN_ARG_x_dot);
69 
70  inArgs.setSupports(MEB::IN_ARG_beta);
71  inArgs.setSupports(MEB::IN_ARG_alpha);
72  if (acceptModelParams_) inArgs.set_Np(Np_);
73 
74  inArgs_ = inArgs;
75  }
76 
77  {
78  // Set up prototypical OutArgs
79  MEB::OutArgsSetup<Scalar> outArgs;
80  outArgs.setModelEvalDescription(this->description());
81  outArgs.setSupports(MEB::OUT_ARG_f);
82 
83  outArgs.setSupports(MEB::OUT_ARG_W_op);
84  if (acceptModelParams_) {
85  outArgs.set_Np_Ng(Np_, Ng_);
86  outArgs.setSupports(MEB::OUT_ARG_DfDp, 0, MEB::DERIV_MV_JACOBIAN_FORM);
87  outArgs.setSupports(MEB::OUT_ARG_DgDp, 0, 0, MEB::DERIV_MV_JACOBIAN_FORM);
88  outArgs.setSupports(MEB::OUT_ARG_DgDx, 0, MEB::DERIV_MV_GRADIENT_FORM);
89  }
90  outArgs_ = outArgs;
91  }
92 
93  // Set up nominal values (initial conditions)
94  nominalValues_ = inArgs_;
95  {
96  nominalValues_.set_t(Scalar(0.0));
97  const RCP<Thyra::VectorBase<Scalar> > x_ic = createMember(x_space_);
98  { // scope to delete DetachedVectorView
99  Thyra::DetachedVectorView<Scalar> x_ic_view(*x_ic);
100  x_ic_view[0] = xIC_;
101  }
102  nominalValues_.set_x(x_ic);
103  }
104 
105  if (includeXDot_) {
106  const RCP<Thyra::VectorBase<Scalar> > x_dot_ic = createMember(x_space_);
107  { // scope to delete DetachedVectorView
108  Thyra::DetachedVectorView<Scalar> x_dot_ic_view(*x_dot_ic);
109  x_dot_ic_view[0] = xDotIC_;
110  }
111  nominalValues_.set_x_dot(x_dot_ic);
112  }
113 
114  isInitialized_ = true;
115 }
116 
117 template <class Scalar>
120 {
122  double exact_t = t;
123  inArgs.set_t(exact_t);
124 
125  // Set the exact solution, x.
126  Teuchos::RCP<Thyra::VectorBase<Scalar> > exact_x = createMember(x_space_);
127  { // scope to delete DetachedVectorView
128  Thyra::DetachedVectorView<Scalar> exact_x_view(*exact_x);
129  exact_x_view[0] = exp(lambda_ * exact_t);
130  }
131  inArgs.set_x(exact_x);
132 
133  // Set the exact solution time derivative, xDot.
134  if (includeXDot_) {
136  createMember(x_space_);
137  { // scope to delete DetachedVectorView
138  Thyra::DetachedVectorView<Scalar> exact_x_dot_view(*exact_x_dot);
139  exact_x_dot_view[0] = lambda_ * exp(lambda_ * exact_t);
140  }
141  inArgs.set_x_dot(exact_x_dot);
142  }
143 
144  return inArgs;
145 }
146 
147 template <class Scalar>
150 {
151  return x_space_;
152 }
153 
154 template <class Scalar>
157 {
158  return f_space_;
159 }
160 
161 template <class Scalar>
164 {
165  return nominalValues_;
166 }
167 
168 template <class Scalar>
171 {
172  return inArgs_;
173 }
174 
175 template <class Scalar>
178 {
179  return outArgs_;
180 }
181 
182 template <class Scalar>
185  const Thyra::ModelEvaluatorBase::OutArgs<Scalar> &outArgs) const
186 {
187  using Teuchos::RCP;
188  using Teuchos::rcp_dynamic_cast;
190  using Thyra::VectorBase;
191  TEUCHOS_TEST_FOR_EXCEPTION(!isInitialized_, std::logic_error,
192  "Error, setupInOutArgs_ must be called first!\n");
193 
194  const RCP<const VectorBase<Scalar> > x_in = inArgs.get_x().assert_not_null();
196  const RCP<VectorBase<Scalar> > f_out = outArgs.get_f();
197  const RCP<Thyra::LinearOpBase<Scalar> > W_out = outArgs.get_W_op();
198 
199  if (inArgs.get_x_dot().is_null()) {
200  // Evaluate the Explicit ODE f(x,t) [= 0]
201  if (!is_null(f_out)) {
202  Thyra::DetachedVectorView<Scalar> f_out_view(*f_out);
203  f_out_view[0] = lambda_ * x_in_view[0];
204  }
205  else {
207  true, std::logic_error,
208  "Error -- Dahlquist Test Model requires f_out!\n");
209  }
210 
211  if (!is_null(W_out)) {
213  Teuchos::rcp_dynamic_cast<Thyra::MultiVectorBase<Scalar> >(W_out,
214  true);
215  Thyra::DetachedMultiVectorView<Scalar> matrix_view(*matrix);
216  matrix_view(0, 0) = lambda_;
217  }
218  }
219  else {
220  // Evaluate the implicit ODE f(xdot, x, t) [=0]
221  RCP<const VectorBase<Scalar> > x_dot_in;
222  x_dot_in = inArgs.get_x_dot().assert_not_null();
223  Scalar alpha = inArgs.get_alpha();
224  Scalar beta = inArgs.get_beta();
225 
226  if (!is_null(f_out)) {
227  Thyra::DetachedVectorView<Scalar> f_out_view(*f_out);
228  Thyra::ConstDetachedVectorView<Scalar> x_dot_in_view(*x_dot_in);
229  f_out_view[0] = x_dot_in_view[0] - lambda_ * x_in_view[0];
230  }
231 
232  if (!is_null(W_out)) {
234  Teuchos::rcp_dynamic_cast<Thyra::MultiVectorBase<Scalar> >(W_out,
235  true);
236  Thyra::DetachedMultiVectorView<Scalar> matrix_view(*matrix);
237  matrix_view(0, 0) = alpha - beta * lambda_; // d(f0)/d(x0_n)
238  // Note: alpha = d(xdot)/d(x_n) and beta = d(x)/d(x_n)
239  }
240  }
241 }
242 
243 template <class Scalar>
246 {
247  using Teuchos::RCP;
249  this->get_W_factory();
250  RCP<Thyra::LinearOpBase<Scalar> > matrix = this->create_W_op();
251  {
253  Teuchos::rcp_dynamic_cast<Thyra::MultiVectorBase<Scalar> >(matrix,
254  true);
255  {
256  RCP<Thyra::VectorBase<Scalar> > vec = Thyra::createMember(x_space_);
257  {
258  Thyra::DetachedVectorView<Scalar> vec_view(*vec);
259  vec_view[0] = lambda_;
260  }
261  V_V(multivec->col(0).ptr(), *vec);
262  }
263  }
265  Thyra::linearOpWithSolve<Scalar>(*W_factory, matrix);
266  return W;
267 }
268 
269 template <class Scalar>
272 {
273  // const int dim_ = 1;
275  Thyra::createMembers(x_space_, dim_);
276  return (matrix);
277 }
278 
279 template <class Scalar>
282 {
284  Thyra::defaultSerialDenseLinearOpWithSolveFactory<Scalar>();
285  return W_factory;
286 }
287 
288 template <class Scalar>
291 {
292  if (!acceptModelParams_) {
293  return Teuchos::null;
294  }
296  if (l == 0)
297  return p_space_;
298  else if (l == 1 || l == 2)
299  return DxDp_space_;
300  return Teuchos::null;
301 }
302 
303 template <class Scalar>
306 {
307  if (!acceptModelParams_) {
308  return Teuchos::null;
309  }
313  if (l == 0) {
314  p_strings->push_back("Model Coefficient: a");
315  // p_strings->push_back("Model Coefficient: f");
316  // p_strings->push_back("Model Coefficient: L");
317  }
318  else if (l == 1)
319  p_strings->push_back("DxDp");
320  else if (l == 2)
321  p_strings->push_back("Dx_dotDp");
322  return p_strings;
323 }
324 
325 template <class Scalar>
328 {
330  return g_space_;
331 }
332 
333 } // namespace Tempus_Test
334 #endif // TEMPUS_TEST_DAHLQUIST_TEST_MODEL_IMPL_HPP
Thyra::ModelEvaluatorBase::InArgs< Scalar > getNominalValues() const
void evalModelImpl(const Thyra::ModelEvaluatorBase::InArgs< Scalar > &inArgs_bar, const Thyra::ModelEvaluatorBase::OutArgs< Scalar > &outArgs_bar) const
bool is_null(const boost::shared_ptr< T > &p)
RCP< const VectorBase< Scalar > > get_x_dot() const
Teuchos::RCP< Thyra::LinearOpBase< Scalar > > create_W_op() const
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Evaluation< VectorBase< Scalar > > get_f() const
Teuchos::RCP< const Thyra::VectorSpaceBase< Scalar > > get_x_space() const
#define TEUCHOS_ASSERT_IN_RANGE_UPPER_EXCLUSIVE(index, lower_inclusive, upper_exclusive)
Thyra::ModelEvaluatorBase::OutArgs< Scalar > createOutArgsImpl() const
Thyra::ModelEvaluatorBase::InArgs< Scalar > createInArgs() const
void set_x(const RCP< const VectorBase< Scalar > > &x)
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Ptr< T > ptr() const
Thyra::ModelEvaluatorBase::InArgs< Scalar > getExactSolution(double t) const
Exact solution.
Teuchos::RCP< const Thyra::VectorSpaceBase< Scalar > > get_f_space() const
Teuchos::RCP< const Thyra::LinearOpWithSolveFactoryBase< Scalar > > get_W_factory() const
void set_x_dot(const RCP< const VectorBase< Scalar > > &x_dot)
Teuchos::RCP< const Thyra::VectorSpaceBase< Scalar > > get_g_space(int j) const
Teuchos::RCP< const Teuchos::Array< std::string > > get_p_names(int l) const
Teuchos::RCP< const Thyra::VectorSpaceBase< Scalar > > get_p_space(int l) const
Teuchos::RCP< Thyra::LinearOpWithSolveBase< Scalar > > create_W() const
void constructDahlquistTestModel(Scalar lambda, bool includeXDot)
RCP< LinearOpBase< Scalar > > get_W_op() const
RCP< const VectorBase< Scalar > > get_x() const