Tempus Version of the Day
Time Integration
Loading...
Searching...
No Matches
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
25namespace Tempus_Test {
26
27template <class Scalar>
29{
30 constructDahlquistTestModel(-1.0, false);
31}
32
33template <class Scalar>
34DahlquistTestModel<Scalar>::DahlquistTestModel(Scalar lambda, bool includeXDot)
35{
36 constructDahlquistTestModel(lambda, includeXDot);
37}
38
39template <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
117template <class Scalar>
118Thyra::ModelEvaluatorBase::InArgs<Scalar>
120{
121 Thyra::ModelEvaluatorBase::InArgs<Scalar> inArgs = inArgs_;
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_) {
135 Teuchos::RCP<Thyra::VectorBase<Scalar> > exact_x_dot =
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
147template <class Scalar>
148Teuchos::RCP<const Thyra::VectorSpaceBase<Scalar> >
150{
151 return x_space_;
152}
153
154template <class Scalar>
155Teuchos::RCP<const Thyra::VectorSpaceBase<Scalar> >
157{
158 return f_space_;
159}
160
161template <class Scalar>
162Thyra::ModelEvaluatorBase::InArgs<Scalar>
164{
165 return nominalValues_;
166}
167
168template <class Scalar>
169Thyra::ModelEvaluatorBase::InArgs<Scalar>
171{
172 return inArgs_;
173}
174
175template <class Scalar>
176Thyra::ModelEvaluatorBase::OutArgs<Scalar>
178{
179 return outArgs_;
180}
181
182template <class Scalar>
184 const Thyra::ModelEvaluatorBase::InArgs<Scalar> &inArgs,
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();
195 Thyra::ConstDetachedVectorView<Scalar> x_in_view(*x_in);
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 {
206 TEUCHOS_TEST_FOR_EXCEPTION(
207 true, std::logic_error,
208 "Error -- Dahlquist Test Model requires f_out!\n");
209 }
210
211 if (!is_null(W_out)) {
212 RCP<Thyra::MultiVectorBase<Scalar> > matrix =
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)) {
233 RCP<Thyra::MultiVectorBase<Scalar> > matrix =
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
243template <class Scalar>
244Teuchos::RCP<Thyra::LinearOpWithSolveBase<Scalar> >
246{
247 using Teuchos::RCP;
248 RCP<const Thyra::LinearOpWithSolveFactoryBase<Scalar> > W_factory =
249 this->get_W_factory();
250 RCP<Thyra::LinearOpBase<Scalar> > matrix = this->create_W_op();
251 {
252 RCP<Thyra::MultiVectorBase<Scalar> > multivec =
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 }
264 RCP<Thyra::LinearOpWithSolveBase<Scalar> > W =
265 Thyra::linearOpWithSolve<Scalar>(*W_factory, matrix);
266 return W;
267}
268
269template <class Scalar>
270Teuchos::RCP<Thyra::LinearOpBase<Scalar> >
272{
273 // const int dim_ = 1;
274 Teuchos::RCP<Thyra::MultiVectorBase<Scalar> > matrix =
275 Thyra::createMembers(x_space_, dim_);
276 return (matrix);
277}
278
279template <class Scalar>
280Teuchos::RCP<const Thyra::LinearOpWithSolveFactoryBase<Scalar> >
282{
283 Teuchos::RCP<Thyra::LinearOpWithSolveFactoryBase<Scalar> > W_factory =
284 Thyra::defaultSerialDenseLinearOpWithSolveFactory<Scalar>();
285 return W_factory;
286}
287
288template <class Scalar>
289Teuchos::RCP<const Thyra::VectorSpaceBase<Scalar> >
291{
292 if (!acceptModelParams_) {
293 return Teuchos::null;
294 }
295 TEUCHOS_ASSERT_IN_RANGE_UPPER_EXCLUSIVE(l, 0, Np_);
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
303template <class Scalar>
304Teuchos::RCP<const Teuchos::Array<std::string> >
306{
307 if (!acceptModelParams_) {
308 return Teuchos::null;
309 }
310 TEUCHOS_ASSERT_IN_RANGE_UPPER_EXCLUSIVE(l, 0, Np_);
311 Teuchos::RCP<Teuchos::Array<std::string> > p_strings =
312 Teuchos::rcp(new Teuchos::Array<std::string>());
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
325template <class Scalar>
326Teuchos::RCP<const Thyra::VectorSpaceBase<Scalar> >
328{
329 TEUCHOS_ASSERT_IN_RANGE_UPPER_EXCLUSIVE(j, 0, Ng_);
330 return g_space_;
331}
332
333} // namespace Tempus_Test
334#endif // TEMPUS_TEST_DAHLQUIST_TEST_MODEL_IMPL_HPP
Teuchos::RCP< const Thyra::VectorSpaceBase< Scalar > > get_g_space(int j) const
Thyra::ModelEvaluatorBase::OutArgs< Scalar > createOutArgsImpl() const
Teuchos::RCP< const Thyra::VectorSpaceBase< Scalar > > get_f_space() const
void constructDahlquistTestModel(Scalar lambda, bool includeXDot)
Teuchos::RCP< Thyra::LinearOpWithSolveBase< Scalar > > create_W() const
Teuchos::RCP< const Thyra::VectorSpaceBase< Scalar > > get_x_space() const
Teuchos::RCP< Thyra::LinearOpBase< Scalar > > create_W_op() const
Thyra::ModelEvaluatorBase::InArgs< Scalar > getExactSolution(double t) const
Exact solution.
Teuchos::RCP< const Thyra::LinearOpWithSolveFactoryBase< Scalar > > get_W_factory() const
Teuchos::RCP< const Thyra::VectorSpaceBase< Scalar > > get_p_space(int l) const
void evalModelImpl(const Thyra::ModelEvaluatorBase::InArgs< Scalar > &inArgs_bar, const Thyra::ModelEvaluatorBase::OutArgs< Scalar > &outArgs_bar) const
Thyra::ModelEvaluatorBase::InArgs< Scalar > createInArgs() const
Thyra::ModelEvaluatorBase::InArgs< Scalar > getNominalValues() const
Teuchos::RCP< const Teuchos::Array< std::string > > get_p_names(int l) const