Tempus Version of the Day
Time Integration
Loading...
Searching...
No Matches
Tempus_WrapperModelEvaluatorPairPartIMEX_Basic_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_ModelEvaluatorPairPartIMEX_Basic_impl_hpp
11#define Tempus_ModelEvaluatorPairPartIMEX_Basic_impl_hpp
12
13#include "Thyra_ProductVectorBase.hpp"
14#include "Thyra_ProductVectorSpaceBase.hpp"
15
16namespace Tempus {
17
18template <typename Scalar>
19WrapperModelEvaluatorPairPartIMEX_Basic<
20 Scalar>::WrapperModelEvaluatorPairPartIMEX_Basic()
21 : timeDer_(Teuchos::null),
22 numExplicitOnlyBlocks_(0),
23 parameterIndex_(-1),
24 useImplicitModel_(false)
25{
26}
27
28template <typename Scalar>
31 const Teuchos::RCP<const Thyra::ModelEvaluator<Scalar> >& explicitModel,
32 const Teuchos::RCP<const Thyra::ModelEvaluator<Scalar> >& implicitModel,
33 int numExplicitOnlyBlocks, int parameterIndex)
34 : timeDer_(Teuchos::null),
35 numExplicitOnlyBlocks_(numExplicitOnlyBlocks),
36 parameterIndex_(parameterIndex),
37 useImplicitModel_(false)
38{
39 setExplicitModel(explicitModel);
40 setImplicitModel(implicitModel);
42 initialize();
43}
44
45template <typename Scalar>
47 const Teuchos::RCP<const Thyra::ModelEvaluator<Scalar> >& explicitModel,
48 const Teuchos::RCP<const Thyra::ModelEvaluator<Scalar> >& implicitModel,
49 int numExplicitOnlyBlocks, int parameterIndex)
50{
51 timeDer_ = Teuchos::null;
52 numExplicitOnlyBlocks_ = numExplicitOnlyBlocks;
53 parameterIndex_ = parameterIndex;
54 useImplicitModel_ = false;
55 setExplicitModel(explicitModel);
56 setImplicitModel(implicitModel);
57 setParameterIndex();
58 initialize();
59}
60
61template <typename Scalar>
63{
64 using Teuchos::RCP;
65
66 useImplicitModel_ = true;
67 wrapperImplicitInArgs_ = this->createInArgs();
68 wrapperImplicitOutArgs_ = this->createOutArgs();
69 useImplicitModel_ = false;
70
71 RCP<const Thyra::VectorBase<Scalar> > z =
72 explicitModel_->getNominalValues().get_x();
73
74 // A Thyra::VectorSpace requirement
75 TEUCHOS_TEST_FOR_EXCEPTION(
76 !(getIMEXVector(z)->space()->isCompatible(
77 *(implicitModel_->get_x_space()))),
78 std::logic_error,
79 "Error - WrapperModelEvaluatorPairIMEX_Basic::initialize()\n"
80 << " Explicit and Implicit vector x spaces are incompatible!\n"
81 << " Explicit vector x space = "
82 << *(getIMEXVector(z)->space())
83 << "\n Implicit vector x space = "
84 << *(implicitModel_->get_x_space()) << "\n");
85
86 // Valid number of blocks?
87 RCP<const Thyra::ProductVectorBase<Scalar> > zPVector =
88 Teuchos::rcp_dynamic_cast<const Thyra::ProductVectorBase<Scalar> >(z);
89 TEUCHOS_TEST_FOR_EXCEPTION(
90 zPVector == Teuchos::null, std::logic_error,
91 "Error - WrapperModelEvaluatorPairPartIMEX_Basic::initialize()\n"
92 " was given a VectorBase that could not be cast to a\n"
93 " ProductVectorBase!\n");
94
95 int numBlocks = zPVector->productSpace()->numBlocks();
96
97 TEUCHOS_TEST_FOR_EXCEPTION(
98 !(0 <= numExplicitOnlyBlocks_ && numExplicitOnlyBlocks_ < numBlocks),
99 std::logic_error,
100 "Error - WrapperModelEvaluatorPairPartIMEX_Basic::initialize()\n"
101 << "Invalid number of explicit-only blocks = "
102 << numExplicitOnlyBlocks_
103 << "\nShould be in the interval [0, numBlocks) = [0, "
104 << numBlocks << ")\n");
105}
106
107template <typename Scalar>
109 const Teuchos::RCP<const Thyra::ModelEvaluator<Scalar> >& /* me */)
110{
111 TEUCHOS_TEST_FOR_EXCEPTION(
112 true, std::logic_error,
113 "Error - WrapperModelEvaluatorPairPartIMEX_Basic<Scalar>::setAppModel\n"
114 " should not be used. One should instead use setExplicitModel,\n"
115 " setImplicitModel, or create a new "
116 "WrapperModelEvaluatorPairPartIMEX.\n");
117}
118
119template <typename Scalar>
120Teuchos::RCP<const Thyra::ModelEvaluator<Scalar> >
122{
123 TEUCHOS_TEST_FOR_EXCEPTION(
124 true, std::logic_error,
125 "Error - WrapperModelEvaluatorPairPartIMEX_Basic<Scalar>::getAppModel\n"
126 " should not be used. One should instead use getExplicitModel,\n"
127 " getImplicitModel, or directly use WrapperModelEvaluatorPairPartIMEX\n"
128 " object.\n");
129}
130
131template <typename Scalar>
132Teuchos::RCP<const Thyra::VectorSpaceBase<Scalar> >
134{
135 if (useImplicitModel_ == true) return implicitModel_->get_x_space();
136
137 return explicitModel_->get_x_space();
138}
139
140template <typename Scalar>
141Teuchos::RCP<const Thyra::VectorSpaceBase<Scalar> >
143{
144 if (useImplicitModel_ == true) return implicitModel_->get_g_space(i);
145
146 return explicitModel_->get_g_space(i);
147}
148
149template <typename Scalar>
150Teuchos::RCP<const Thyra::VectorSpaceBase<Scalar> >
152{
153 if (useImplicitModel_ == true) return implicitModel_->get_p_space(i);
154
155 return explicitModel_->get_p_space(i);
156}
157
158template <typename Scalar>
160 const Teuchos::RCP<const Thyra::ModelEvaluator<Scalar> >& model)
161{
162 implicitModel_ = model;
163}
164
165template <typename Scalar>
166Teuchos::RCP<Thyra::VectorBase<Scalar> >
168 const Teuchos::RCP<Thyra::VectorBase<Scalar> >& full) const
169{
170 using Teuchos::RCP;
171 using Teuchos::rcp_dynamic_cast;
172
173 Teuchos::RCP<Thyra::VectorBase<Scalar> > vector;
174 if (full == Teuchos::null) {
175 vector = Teuchos::null;
176 }
177 else if (numExplicitOnlyBlocks_ == 0) {
178 vector = full;
179 }
180 else {
181 RCP<Thyra::ProductVectorBase<Scalar> > blk_full =
182 rcp_dynamic_cast<Thyra::ProductVectorBase<Scalar> >(full);
183 TEUCHOS_TEST_FOR_EXCEPTION(
184 blk_full == Teuchos::null, std::logic_error,
185 "Error - WrapperModelEvaluatorPairPartIMEX_Basic::getIMEXVector()\n"
186 " was given a VectorBase that could not be cast to a\n"
187 " ProductVectorBase!\n");
188 int numBlocks = blk_full->productSpace()->numBlocks();
189
190 // special case where the implicit terms are not blocked
191 if (numBlocks == numExplicitOnlyBlocks_ + 1)
192 vector = blk_full->getNonconstVectorBlock(numExplicitOnlyBlocks_);
193
194 TEUCHOS_TEST_FOR_EXCEPTION(
195 !(numExplicitOnlyBlocks_ == 0 || full == Teuchos::null ||
196 numBlocks == numExplicitOnlyBlocks_ + 1),
197 std::logic_error, "Error - Invalid values!\n");
198 }
199
200 return vector;
201}
202
203template <typename Scalar>
204Teuchos::RCP<const Thyra::VectorBase<Scalar> >
206 const Teuchos::RCP<const Thyra::VectorBase<Scalar> >& full) const
207{
208 using Teuchos::RCP;
209 using Teuchos::rcp_dynamic_cast;
210
211 Teuchos::RCP<const Thyra::VectorBase<Scalar> > vector;
212 if (full == Teuchos::null) {
213 vector = Teuchos::null;
214 }
215 else if (numExplicitOnlyBlocks_ == 0) {
216 vector = full;
217 }
218 else {
219 // special case where the implicit terms are not blocked
220
221 RCP<const Thyra::ProductVectorBase<Scalar> > blk_full =
222 rcp_dynamic_cast<const Thyra::ProductVectorBase<Scalar> >(full);
223 TEUCHOS_TEST_FOR_EXCEPTION(
224 blk_full == Teuchos::null, std::logic_error,
225 "Error - WrapperModelEvaluatorPairPartIMEX_Basic::getIMEXVector()\n"
226 " was given a VectorBase that could not be cast to a\n"
227 " ProductVectorBase!\n");
228 int numBlocks = blk_full->productSpace()->numBlocks();
229
230 // special case where the implicit terms are not blocked
231 if (numBlocks == numExplicitOnlyBlocks_ + 1)
232 vector = blk_full->getVectorBlock(numExplicitOnlyBlocks_);
233
234 TEUCHOS_TEST_FOR_EXCEPTION(
235 !(numExplicitOnlyBlocks_ == 0 || full == Teuchos::null ||
236 numBlocks == numExplicitOnlyBlocks_ + 1),
237 std::logic_error, "Error - Invalid values!\n");
238 }
239
240 return vector;
241}
242
243template <typename Scalar>
244Teuchos::RCP<Thyra::VectorBase<Scalar> >
246 const Teuchos::RCP<Thyra::VectorBase<Scalar> >& full) const
247{
248 using Teuchos::RCP;
249 using Teuchos::rcp_dynamic_cast;
250
251 Teuchos::RCP<Thyra::VectorBase<Scalar> > vector;
252 if (numExplicitOnlyBlocks_ == 0 || full == Teuchos::null) {
253 vector = Teuchos::null;
254 }
255 else if (numExplicitOnlyBlocks_ == 1) {
256 // special case where the explicit terms are not blocked
257
258 RCP<Thyra::ProductVectorBase<Scalar> > blk_full =
259 rcp_dynamic_cast<Thyra::ProductVectorBase<Scalar> >(full);
260 TEUCHOS_TEST_FOR_EXCEPTION(
261 blk_full == Teuchos::null, std::logic_error,
262 "Error - WrapperModelEvaluatorPairPartIMEX_Basic::getExplicitOnlyVector\n"
263 << " given a VectorBase that could not be cast to a ProductVectorBase!\n"
264 << " full = " << *full << "\n");
265
266 vector = blk_full->getNonconstVectorBlock(0);
267 }
268
269 TEUCHOS_TEST_FOR_EXCEPTION(
270 !((numExplicitOnlyBlocks_ == 0 || full == Teuchos::null) ||
271 (numExplicitOnlyBlocks_ == 1)),
272 std::logic_error, "Error - Invalid values!\n");
273
274 return vector;
275}
276
277template <typename Scalar>
278Teuchos::RCP<const Thyra::VectorBase<Scalar> >
280 const Teuchos::RCP<const Thyra::VectorBase<Scalar> >& full) const
281{
282 using Teuchos::RCP;
283 using Teuchos::rcp_dynamic_cast;
284
285 RCP<const Thyra::VectorBase<Scalar> > vector;
286 if (numExplicitOnlyBlocks_ == 0 || full == Teuchos::null) {
287 vector = Teuchos::null;
288 }
289 else if (numExplicitOnlyBlocks_ == 1) {
290 // special case where the explicit terms are not blocked
291
292 RCP<const Thyra::ProductVectorBase<Scalar> > blk_full =
293 rcp_dynamic_cast<const Thyra::ProductVectorBase<Scalar> >(full);
294 TEUCHOS_TEST_FOR_EXCEPTION(
295 blk_full == Teuchos::null, std::logic_error,
296 "Error - WrapperModelEvaluatorPairPartIMEX_Basic::getExplicitOnlyVector\n"
297 << " given a VectorBase that could not be cast to a ProductVectorBase!\n"
298 << " full = " << *full << "\n");
299
300 vector = blk_full->getVectorBlock(0);
301 }
302
303 TEUCHOS_TEST_FOR_EXCEPTION(
304 !((numExplicitOnlyBlocks_ == 0 || full == Teuchos::null) ||
305 (numExplicitOnlyBlocks_ == 1)),
306 std::logic_error, "Error - Invalid values!\n");
307
308 return vector;
309}
310
311template <typename Scalar>
313 int parameterIndex)
314{
315 if (implicitModel_->Np() == 0) {
316 if (parameterIndex >= 0) {
317 Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
318 out->setOutputToRootOnly(0);
319 Teuchos::OSTab ostab(
320 out, 1,
321 "WrapperModelEvaluatorPairPartIMEX_Basic::setParameterIndex()");
322 *out << "Warning -- \n"
323 << " Invalid input parameter index = " << parameterIndex << "\n"
324 << " Should not be set since Np = " << implicitModel_->Np() << "\n"
325 << " Not setting parameter index." << std::endl;
326 }
327 if (parameterIndex_ >= 0) {
328 Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
329 out->setOutputToRootOnly(0);
330 Teuchos::OSTab ostab(
331 out, 1,
332 "WrapperModelEvaluatorPairPartIMEX_Basic::setParameterIndex()");
333 *out << "Warning -- \n"
334 << " Invalid parameter index = " << parameterIndex_ << "\n"
335 << " Should not be set since Np = " << implicitModel_->Np() << "\n"
336 << " Resetting to parameter index to unset state." << std::endl;
337 parameterIndex_ = -1;
338 }
339 }
340 else {
341 if (parameterIndex >= 0) {
342 parameterIndex_ = parameterIndex;
343 }
344 else if (parameterIndex_ < 0) {
345 parameterIndex_ = 0;
346 for (int i = 0; i < implicitModel_->Np(); i++) {
347 if ((*implicitModel_->get_p_names(i))[0] == "EXPLICIT_ONLY_VECTOR") {
348 parameterIndex_ = i;
349 break;
350 }
351 }
352 }
353 }
354
355 return;
356}
357
358template <typename Scalar>
359Teuchos::RCP<const Thyra::VectorSpaceBase<Scalar> >
361{
362 if (useImplicitModel_ == true) return implicitModel_->get_f_space();
363
364 return explicitModel_->get_f_space();
365}
366
367template <typename Scalar>
368Thyra::ModelEvaluatorBase::InArgs<Scalar>
370{
371 typedef Thyra::ModelEvaluatorBase MEB;
372 MEB::InArgsSetup<Scalar> inArgs = this->createInArgs();
373 return std::move(inArgs);
374}
375
376template <typename Scalar>
377Thyra::ModelEvaluatorBase::InArgs<Scalar>
379{
380 typedef Thyra::ModelEvaluatorBase MEB;
381 MEB::InArgs<Scalar> implicitInArgs = implicitModel_->getNominalValues();
382 MEB::InArgs<Scalar> explicitInArgs = explicitModel_->getNominalValues();
383 const int np = std::max(implicitInArgs.Np(), explicitInArgs.Np());
384 if (useImplicitModel_ == true) {
385 MEB::InArgsSetup<Scalar> inArgs(implicitInArgs);
386 inArgs.setModelEvalDescription(this->description());
387 inArgs.set_Np(np);
388 return std::move(inArgs);
389 }
390
391 MEB::InArgsSetup<Scalar> inArgs(explicitInArgs);
392 inArgs.setModelEvalDescription(this->description());
393 inArgs.set_Np(np);
394 return std::move(inArgs);
395}
396
397template <typename Scalar>
398Thyra::ModelEvaluatorBase::OutArgs<Scalar>
400{
401 typedef Thyra::ModelEvaluatorBase MEB;
402 MEB::OutArgs<Scalar> implicitOutArgs = implicitModel_->createOutArgs();
403 MEB::OutArgs<Scalar> explicitOutArgs = explicitModel_->createOutArgs();
404 const int np = std::max(implicitOutArgs.Np(), explicitOutArgs.Np());
405 if (useImplicitModel_ == true) {
406 MEB::OutArgsSetup<Scalar> outArgs(implicitOutArgs);
407 outArgs.setModelEvalDescription(this->description());
408 outArgs.set_Np_Ng(np, implicitOutArgs.Ng());
409 return std::move(outArgs);
410 }
411
412 MEB::OutArgsSetup<Scalar> outArgs(explicitOutArgs);
413 outArgs.setModelEvalDescription(this->description());
414 outArgs.set_Np_Ng(np, explicitOutArgs.Ng());
415 return std::move(outArgs);
416}
417
418template <typename Scalar>
420 const Thyra::ModelEvaluatorBase::InArgs<Scalar>& inArgs,
421 const Thyra::ModelEvaluatorBase::OutArgs<Scalar>& outArgs) const
422{
423 typedef Thyra::ModelEvaluatorBase MEB;
424 using Teuchos::RCP;
425
426 RCP<const Thyra::VectorBase<Scalar> > x = inArgs.get_x();
427 RCP<Thyra::VectorBase<Scalar> > x_dot =
428 Thyra::createMember(implicitModel_->get_x_space());
429 timeDer_->compute(x, x_dot);
430
431 MEB::InArgs<Scalar> appImplicitInArgs(wrapperImplicitInArgs_);
432 MEB::OutArgs<Scalar> appImplicitOutArgs(wrapperImplicitOutArgs_);
433 appImplicitInArgs.set_x(x);
434 appImplicitInArgs.set_x_dot(x_dot);
435 for (int i = 0; i < implicitModel_->Np(); ++i) {
436 // Copy over parameters except for the parameter for explicit-only vector!
437 if ((inArgs.get_p(i) != Teuchos::null) && (i != parameterIndex_))
438 appImplicitInArgs.set_p(i, inArgs.get_p(i));
439 }
440
441 appImplicitOutArgs.set_f(outArgs.get_f());
442 appImplicitOutArgs.set_W_op(outArgs.get_W_op());
443
444 implicitModel_->evalModel(appImplicitInArgs, appImplicitOutArgs);
445}
446
447} // end namespace Tempus
448
449#endif // Tempus_ModelEvaluatorPairPartIMEX_Basic_impl_hpp
virtual Teuchos::RCP< Thyra::VectorBase< Scalar > > getIMEXVector(const Teuchos::RCP< Thyra::VectorBase< Scalar > > &full) const
Extract IMEX vector from a full solution vector.
virtual void setParameterIndex(int parameterIndex=-1)
Set the parameter index for explicit-only vector.
virtual Teuchos::RCP< Thyra::VectorBase< Scalar > > getExplicitOnlyVector(const Teuchos::RCP< Thyra::VectorBase< Scalar > > &full) const
Extract explicit-only vector from a full solution vector.
void setup(const Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > &explicitModel, const Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > &implicitModel, int numExplicitOnlyBlocks=0, int parameterIndex=-1)
Setup ME when using default constructor – for derived classes.
virtual void evalModelImpl(const Thyra::ModelEvaluatorBase::InArgs< Scalar > &in, const Thyra::ModelEvaluatorBase::OutArgs< Scalar > &out) const
virtual Teuchos::RCP< const Thyra::VectorSpaceBase< Scalar > > get_f_space() const
virtual Teuchos::RCP< const Thyra::VectorSpaceBase< Scalar > > get_p_space(int i) const
Get the p space.
virtual Teuchos::RCP< const Thyra::VectorSpaceBase< Scalar > > get_g_space(int i) const
Get the g space.
virtual Thyra::ModelEvaluatorBase::InArgs< Scalar > getNominalValues() const
virtual Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > getAppModel() const
Get the underlying application ModelEvaluator.
virtual Teuchos::RCP< const Thyra::VectorSpaceBase< Scalar > > get_x_space() const
Get the x-solution space.
virtual Thyra::ModelEvaluatorBase::OutArgs< Scalar > createOutArgsImpl() const
virtual void setAppModel(const Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > &me)
Set the underlying application ModelEvaluator.
virtual void setExplicitModel(const Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > &model)
virtual void setImplicitModel(const Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > &model)
virtual Thyra::ModelEvaluatorBase::InArgs< Scalar > createInArgs() const