Tempus Version of the Day
Time Integration
Loading...
Searching...
No Matches
SteadyQuadraticModel_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_STEADY_QUADRATIC_MODEL_IMPL_HPP
11#define TEMPUS_TEST_STEADY_QUADRATIC_MODEL_IMPL_HPP
12
13#include "Teuchos_StandardParameterEntryValidators.hpp"
14
15#include "Thyra_DefaultSpmdVectorSpace.hpp"
16#include "Thyra_DetachedVectorView.hpp"
17#include "Thyra_DetachedMultiVectorView.hpp"
18#include "Thyra_DefaultSerialDenseLinearOpWithSolveFactory.hpp"
19#include "Thyra_DefaultMultiVectorLinearOpWithSolve.hpp"
20#include "Thyra_DefaultLinearOpSource.hpp"
21#include "Thyra_MultiVectorStdOps.hpp"
22#include "Thyra_VectorStdOps.hpp"
23#include "Thyra_DefaultMultiVectorProductVector.hpp"
24
25#include <iostream>
26
27namespace Tempus_Test {
28
29template <class Scalar>
31 Teuchos::RCP<Teuchos::ParameterList> pList_)
32{
33 isInitialized_ = false;
34 dim_ = 1;
35 Np_ = 3; // Number of parameter vectors (p, dx/dp, dx_dot/dp)
36 np_ = 1; // Number of parameters in this vector (3)
37 Ng_ = 1; // Number of observation functions (1)
38 ng_ = 1; // Number of elements in this observation function (1)
39 useDfDpAsTangent_ = false;
40 b_ = 1.0;
41
42 // Create x_space and f_space
43 x_space_ = Thyra::defaultSpmdVectorSpace<Scalar>(dim_);
44 f_space_ = Thyra::defaultSpmdVectorSpace<Scalar>(dim_);
45 // Create p_space and g_space
46 p_space_ = Thyra::defaultSpmdVectorSpace<Scalar>(np_);
47 g_space_ = Thyra::defaultSpmdVectorSpace<Scalar>(ng_);
48
49 setParameterList(pList_);
50
51 // Create DxDp product space
52 DxDp_space_ = Thyra::multiVectorProductVectorSpace(x_space_, np_);
53}
54
55template <class Scalar>
57{
58 if (b_ < 0.0) return b_;
59 return -b_;
60}
61
62template <class Scalar>
64{
65 if (b_ < 0.0) return 1.0;
66 return -1.0;
67}
68
69template <class Scalar>
70Teuchos::RCP<const Thyra::VectorSpaceBase<Scalar> >
72{
73 return x_space_;
74}
75
76template <class Scalar>
77Teuchos::RCP<const Thyra::VectorSpaceBase<Scalar> >
79{
80 return f_space_;
81}
82
83template <class Scalar>
84Thyra::ModelEvaluatorBase::InArgs<Scalar>
86{
87 TEUCHOS_TEST_FOR_EXCEPTION(!isInitialized_, std::logic_error,
88 "Error, setupInOutArgs_ must be called first!\n");
89 return nominalValues_;
90}
91
92template <class Scalar>
93Teuchos::RCP<Thyra::LinearOpWithSolveBase<Scalar> >
95{
96 using Teuchos::RCP;
97 RCP<const Thyra::LinearOpWithSolveFactoryBase<Scalar> > W_factory =
98 this->get_W_factory();
99 RCP<Thyra::LinearOpBase<Scalar> > matrix = this->create_W_op();
100 {
101 // 01/20/09 tscoffe: This is a total hack to provide a full rank matrix to
102 // linearOpWithSolve because it ends up factoring the matrix during
103 // initialization, which it really shouldn't do, or I'm doing something
104 // wrong here. The net effect is that I get exceptions thrown in
105 // optimized mode due to the matrix being rank deficient unless I do this.
106 RCP<Thyra::MultiVectorBase<Scalar> > multivec =
107 Teuchos::rcp_dynamic_cast<Thyra::MultiVectorBase<Scalar> >(matrix,
108 true);
109 {
110 RCP<Thyra::VectorBase<Scalar> > vec = Thyra::createMember(x_space_);
111 {
112 Thyra::DetachedVectorView<Scalar> vec_view(*vec);
113 vec_view[0] = 1.0;
114 }
115 V_V(multivec->col(0).ptr(), *vec);
116 }
117 }
118 RCP<Thyra::LinearOpWithSolveBase<Scalar> > W =
119 Thyra::linearOpWithSolve<Scalar>(*W_factory, matrix);
120 return W;
121}
122
123template <class Scalar>
124Teuchos::RCP<Thyra::LinearOpBase<Scalar> >
126{
127 Teuchos::RCP<Thyra::MultiVectorBase<Scalar> > matrix =
128 Thyra::createMembers(x_space_, dim_);
129 return (matrix);
130}
131
132template <class Scalar>
133Teuchos::RCP<const Thyra::LinearOpWithSolveFactoryBase<Scalar> >
135{
136 Teuchos::RCP<Thyra::LinearOpWithSolveFactoryBase<Scalar> > W_factory =
137 Thyra::defaultSerialDenseLinearOpWithSolveFactory<Scalar>();
138 return W_factory;
139}
140
141template <class Scalar>
142Thyra::ModelEvaluatorBase::InArgs<Scalar>
144{
145 setupInOutArgs_();
146 return inArgs_;
147}
148
149// Private functions overridden from ModelEvaluatorDefaultBase
150
151template <class Scalar>
152Thyra::ModelEvaluatorBase::OutArgs<Scalar>
154{
155 setupInOutArgs_();
156 return outArgs_;
157}
158
159template <class Scalar>
161 const Thyra::ModelEvaluatorBase::InArgs<Scalar> &inArgs,
162 const Thyra::ModelEvaluatorBase::OutArgs<Scalar> &outArgs) const
163{
164 typedef Thyra::DefaultMultiVectorProductVector<Scalar> DMVPV;
165 using Teuchos::RCP;
166 using Teuchos::rcp_dynamic_cast;
168 using Thyra::VectorBase;
169 TEUCHOS_TEST_FOR_EXCEPTION(!isInitialized_, std::logic_error,
170 "Error, setupInOutArgs_ must be called first!\n");
171
172 const RCP<const VectorBase<Scalar> > x_in = inArgs.get_x().assert_not_null();
173 Thyra::ConstDetachedVectorView<Scalar> x_in_view(*x_in);
174
175 Scalar b = b_;
176 const RCP<const VectorBase<Scalar> > p_in = inArgs.get_p(0);
177 if (p_in != Teuchos::null) {
178 Thyra::ConstDetachedVectorView<Scalar> p_in_view(*p_in);
179 b = p_in_view[0];
180 }
181
182 RCP<const MultiVectorBase<Scalar> > DxDp_in, DxdotDp_in;
183 if (inArgs.get_p(1) != Teuchos::null)
184 DxDp_in = rcp_dynamic_cast<const DMVPV>(inArgs.get_p(1))->getMultiVector();
185 if (inArgs.get_p(2) != Teuchos::null)
186 DxdotDp_in =
187 rcp_dynamic_cast<const DMVPV>(inArgs.get_p(2))->getMultiVector();
188
189 Scalar beta = inArgs.get_beta();
190
191 const RCP<VectorBase<Scalar> > f_out = outArgs.get_f();
192 const RCP<Thyra::LinearOpBase<Scalar> > W_out = outArgs.get_W_op();
193 RCP<Thyra::MultiVectorBase<Scalar> > DfDp_out;
194 Thyra::ModelEvaluatorBase::Derivative<Scalar> DfDp = outArgs.get_DfDp(0);
195 DfDp_out = DfDp.getMultiVector();
196
197 if (inArgs.get_x_dot().is_null()) {
198 // Evaluate the Explicit ODE f(x,t) [= 0]
199 if (!is_null(f_out)) {
200 Thyra::DetachedVectorView<Scalar> f_out_view(*f_out);
201 f_out_view[0] = x_in_view[0] * x_in_view[0] - b * b;
202 }
203 if (!is_null(W_out)) {
204 RCP<Thyra::MultiVectorBase<Scalar> > matrix =
205 Teuchos::rcp_dynamic_cast<Thyra::MultiVectorBase<Scalar> >(W_out,
206 true);
207 Thyra::DetachedMultiVectorView<Scalar> matrix_view(*matrix);
208 matrix_view(0, 0) = beta * 2.0 * x_in_view[0];
209 }
210 if (!is_null(DfDp_out)) {
211 Thyra::DetachedMultiVectorView<Scalar> DfDp_out_view(*DfDp_out);
212 DfDp_out_view(0, 0) = -2.0 * b;
213
214 // Compute df/dp + (df/dx) * (dx/dp)
215 if (useDfDpAsTangent_ && !is_null(DxDp_in)) {
216 Thyra::ConstDetachedMultiVectorView<Scalar> DxDp(*DxDp_in);
217 DfDp_out_view(0, 0) += 2.0 * x_in_view[0] * DxDp(0, 0);
218 }
219 }
220 }
221 else {
222 // Evaluate the implicit ODE f(xdot, x, t) [= 0]
223 RCP<const VectorBase<Scalar> > x_dot_in;
224 x_dot_in = inArgs.get_x_dot().assert_not_null();
225 Scalar alpha = inArgs.get_alpha();
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] - (x_in_view[0] * x_in_view[0] - b * b);
230 }
231 if (!is_null(W_out)) {
232 RCP<Thyra::MultiVectorBase<Scalar> > matrix =
233 Teuchos::rcp_dynamic_cast<Thyra::MultiVectorBase<Scalar> >(W_out,
234 true);
235 Thyra::DetachedMultiVectorView<Scalar> matrix_view(*matrix);
236 matrix_view(0, 0) = alpha - beta * 2.0 * x_in_view[0];
237 }
238 if (!is_null(DfDp_out)) {
239 Thyra::DetachedMultiVectorView<Scalar> DfDp_out_view(*DfDp_out);
240 DfDp_out_view(0, 0) = 2.0 * b;
241
242 // Compute df/dp + (df/dx_dot) * (dx_dot/dp) + (df/dx) * (dx/dp)
243 if (useDfDpAsTangent_ && !is_null(DxdotDp_in)) {
244 Thyra::ConstDetachedMultiVectorView<Scalar> DxdotDp(*DxdotDp_in);
245 DfDp_out_view(0, 0) += DxdotDp(0, 0);
246 }
247 if (useDfDpAsTangent_ && !is_null(DxDp_in)) {
248 Thyra::ConstDetachedMultiVectorView<Scalar> DxDp(*DxDp_in);
249 DfDp_out_view(0, 0) += -2.0 * x_in_view[0] * DxDp(0, 0);
250 }
251 }
252 }
253
254 // Responses: g = x
255 RCP<VectorBase<Scalar> > g_out = outArgs.get_g(0);
256 if (g_out != Teuchos::null) Thyra::assign(g_out.ptr(), *x_in);
257
258 RCP<Thyra::MultiVectorBase<Scalar> > DgDp_out =
259 outArgs.get_DgDp(0, 0).getMultiVector();
260 if (DgDp_out != Teuchos::null) Thyra::assign(DgDp_out.ptr(), Scalar(0.0));
261
262 RCP<Thyra::MultiVectorBase<Scalar> > DgDx_out =
263 outArgs.get_DgDx(0).getMultiVector();
264 if (DgDx_out != Teuchos::null) {
265 Thyra::DetachedMultiVectorView<Scalar> DgDx_out_view(*DgDx_out);
266 DgDx_out_view(0, 0) = 1.0;
267 }
268}
269
270template <class Scalar>
271Teuchos::RCP<const Thyra::VectorSpaceBase<Scalar> >
273{
274 TEUCHOS_ASSERT_IN_RANGE_UPPER_EXCLUSIVE(l, 0, Np_);
275 if (l == 0)
276 return p_space_;
277 else if (l == 1 || l == 2)
278 return DxDp_space_;
279 return Teuchos::null;
280}
281
282template <class Scalar>
283Teuchos::RCP<const Teuchos::Array<std::string> >
285{
286 TEUCHOS_ASSERT_IN_RANGE_UPPER_EXCLUSIVE(l, 0, Np_);
287 Teuchos::RCP<Teuchos::Array<std::string> > p_strings =
288 Teuchos::rcp(new Teuchos::Array<std::string>());
289 if (l == 0) {
290 p_strings->push_back("Model Coefficient: b");
291 }
292 else if (l == 1)
293 p_strings->push_back("DxDp");
294 else if (l == 2)
295 p_strings->push_back("Dx_dotDp");
296 return p_strings;
297}
298
299template <class Scalar>
300Teuchos::RCP<const Thyra::VectorSpaceBase<Scalar> >
302{
303 TEUCHOS_ASSERT_IN_RANGE_UPPER_EXCLUSIVE(j, 0, Ng_);
304 return g_space_;
305}
306
307// private
308
309template <class Scalar>
311{
312 if (isInitialized_) {
313 return;
314 }
315
316 {
317 // Set up prototypical InArgs
318 Thyra::ModelEvaluatorBase::InArgsSetup<Scalar> inArgs;
319 inArgs.setModelEvalDescription(this->description());
320 inArgs.setSupports(Thyra::ModelEvaluatorBase::IN_ARG_t);
321 inArgs.setSupports(Thyra::ModelEvaluatorBase::IN_ARG_x);
322 inArgs.setSupports(Thyra::ModelEvaluatorBase::IN_ARG_beta);
323 inArgs.setSupports(Thyra::ModelEvaluatorBase::IN_ARG_x_dot);
324 inArgs.setSupports(Thyra::ModelEvaluatorBase::IN_ARG_alpha);
325 inArgs.set_Np(Np_);
326 inArgs_ = inArgs;
327 }
328
329 {
330 // Set up prototypical OutArgs
331 Thyra::ModelEvaluatorBase::OutArgsSetup<Scalar> outArgs;
332 outArgs.setModelEvalDescription(this->description());
333 outArgs.setSupports(Thyra::ModelEvaluatorBase::OUT_ARG_f);
334 outArgs.setSupports(Thyra::ModelEvaluatorBase::OUT_ARG_W_op);
335 outArgs.set_Np_Ng(Np_, Ng_);
336 outArgs.setSupports(Thyra::ModelEvaluatorBase::OUT_ARG_DfDp, 0,
337 Thyra::ModelEvaluatorBase::DERIV_MV_JACOBIAN_FORM);
338 outArgs.setSupports(Thyra::ModelEvaluatorBase::OUT_ARG_DgDx, 0,
339 Thyra::ModelEvaluatorBase::DERIV_MV_GRADIENT_FORM);
340 outArgs.setSupports(Thyra::ModelEvaluatorBase::OUT_ARG_DgDp, 0, 0,
341 Thyra::ModelEvaluatorBase::DERIV_MV_GRADIENT_FORM);
342 outArgs_ = outArgs;
343 }
344
345 // Set up nominal values
346 nominalValues_ = inArgs_;
347 nominalValues_.set_t(0.0);
348 const Teuchos::RCP<Thyra::VectorBase<Scalar> > x_ic = createMember(x_space_);
349 { // scope to delete DetachedVectorView
350 Thyra::DetachedVectorView<Scalar> x_ic_view(*x_ic);
351 x_ic_view[0] = 0.0;
352 }
353 nominalValues_.set_x(x_ic);
354 const Teuchos::RCP<Thyra::VectorBase<Scalar> > p_ic = createMember(p_space_);
355 {
356 Thyra::DetachedVectorView<Scalar> p_ic_view(*p_ic);
357 p_ic_view[0] = b_;
358 }
359 nominalValues_.set_p(0, p_ic);
360
361 const Teuchos::RCP<Thyra::VectorBase<Scalar> > x_dot_ic =
362 createMember(x_space_);
363 { // scope to delete DetachedVectorView
364 Thyra::DetachedVectorView<Scalar> x_dot_ic_view(*x_dot_ic);
365 x_dot_ic_view[0] = 0.0;
366 }
367 nominalValues_.set_x_dot(x_dot_ic);
368
369 isInitialized_ = true;
370}
371
372template <class Scalar>
374 Teuchos::RCP<Teuchos::ParameterList> const &paramList)
375{
376 using Teuchos::get;
377 using Teuchos::ParameterList;
378 Teuchos::RCP<ParameterList> tmpPL =
379 Teuchos::rcp(new ParameterList("SteadyQuadraticModel"));
380 if (paramList != Teuchos::null) tmpPL = paramList;
381 tmpPL->validateParametersAndSetDefaults(*this->getValidParameters());
382 this->setMyParamList(tmpPL);
383 Teuchos::RCP<ParameterList> pl = this->getMyNonconstParamList();
384 useDfDpAsTangent_ = get<bool>(*pl, "Use DfDp as Tangent");
385 b_ = get<Scalar>(*pl, "Coeff b");
386 isInitialized_ = false; // For setup of new in/out args
387 setupInOutArgs_();
388}
389
390template <class Scalar>
391Teuchos::RCP<const Teuchos::ParameterList>
393{
394 static Teuchos::RCP<const Teuchos::ParameterList> validPL;
395 if (is_null(validPL)) {
396 Teuchos::RCP<Teuchos::ParameterList> pl = Teuchos::parameterList();
397 pl->set("Use DfDp as Tangent", false);
398 Teuchos::setDoubleParameter("Coeff b", 1.0, "Coefficient b in model", &*pl);
399 validPL = pl;
400 }
401 return validPL;
402}
403
404} // namespace Tempus_Test
405#endif // TEMPUS_TEST_STEADY_QUADRATIC_MODEL_IMPL_HPP
Teuchos::RCP< const Thyra::VectorSpaceBase< Scalar > > get_p_space(int l) const
Thyra::ModelEvaluatorBase::OutArgs< Scalar > createOutArgsImpl() const
Teuchos::RCP< const Thyra::VectorSpaceBase< Scalar > > get_g_space(int j) const
void evalModelImpl(const Thyra::ModelEvaluatorBase::InArgs< Scalar > &inArgs_bar, const Thyra::ModelEvaluatorBase::OutArgs< Scalar > &outArgs_bar) const
Teuchos::RCP< Thyra::LinearOpBase< Scalar > > create_W_op() const
Teuchos::RCP< Thyra::LinearOpWithSolveBase< Scalar > > create_W() const
Teuchos::RCP< const Teuchos::ParameterList > getValidParameters() const
Teuchos::RCP< const Thyra::LinearOpWithSolveFactoryBase< Scalar > > get_W_factory() const
Teuchos::RCP< const Teuchos::Array< std::string > > get_p_names(int l) const
Teuchos::RCP< const Thyra::VectorSpaceBase< Scalar > > get_f_space() const
Thyra::ModelEvaluatorBase::InArgs< Scalar > createInArgs() const
void setParameterList(Teuchos::RCP< Teuchos::ParameterList > const &paramList)
SteadyQuadraticModel(Teuchos::RCP< Teuchos::ParameterList > pList=Teuchos::null)
Teuchos::RCP< const Thyra::VectorSpaceBase< Scalar > > get_x_space() const
Thyra::ModelEvaluatorBase::InArgs< Scalar > getNominalValues() const