Tempus  Version of the Day
Time Integration
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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 
16 namespace Tempus {
17 
18 template <typename Scalar>
19 WrapperModelEvaluatorPairPartIMEX_Basic<
21  : timeDer_(Teuchos::null),
22  numExplicitOnlyBlocks_(0),
23  parameterIndex_(-1),
24  useImplicitModel_(false)
25 {
26 }
27 
28 template <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 
45 template <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 
61 template <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
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);
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 
107 template <typename Scalar>
109  const Teuchos::RCP<const Thyra::ModelEvaluator<Scalar> >& /* me */)
110 {
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 
119 template <typename Scalar>
122 {
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 
131 template <typename Scalar>
134 {
135  if (useImplicitModel_ == true) return implicitModel_->get_x_space();
136 
137  return explicitModel_->get_x_space();
138 }
139 
140 template <typename Scalar>
143 {
144  if (useImplicitModel_ == true) return implicitModel_->get_g_space(i);
145 
146  return explicitModel_->get_g_space(i);
147 }
148 
149 template <typename Scalar>
152 {
153  if (useImplicitModel_ == true) return implicitModel_->get_p_space(i);
154 
155  return explicitModel_->get_p_space(i);
156 }
157 
158 template <typename Scalar>
160  const Teuchos::RCP<const Thyra::ModelEvaluator<Scalar> >& model)
161 {
162  implicitModel_ = model;
163 }
164 
165 template <typename Scalar>
168  const Teuchos::RCP<Thyra::VectorBase<Scalar> >& full) const
169 {
170  using Teuchos::RCP;
171  using Teuchos::rcp_dynamic_cast;
172 
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);
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 
203 template <typename Scalar>
206  const Teuchos::RCP<const Thyra::VectorBase<Scalar> >& full) const
207 {
208  using Teuchos::RCP;
209  using Teuchos::rcp_dynamic_cast;
210 
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);
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 
243 template <typename Scalar>
246  const Teuchos::RCP<Thyra::VectorBase<Scalar> >& full) const
247 {
248  using Teuchos::RCP;
249  using Teuchos::rcp_dynamic_cast;
250 
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);
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 
270  !((numExplicitOnlyBlocks_ == 0 || full == Teuchos::null) ||
271  (numExplicitOnlyBlocks_ == 1)),
272  std::logic_error, "Error - Invalid values!\n");
273 
274  return vector;
275 }
276 
277 template <typename 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);
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 
304  !((numExplicitOnlyBlocks_ == 0 || full == Teuchos::null) ||
305  (numExplicitOnlyBlocks_ == 1)),
306  std::logic_error, "Error - Invalid values!\n");
307 
308  return vector;
309 }
310 
311 template <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 
358 template <typename Scalar>
361 {
362  if (useImplicitModel_ == true) return implicitModel_->get_f_space();
363 
364  return explicitModel_->get_f_space();
365 }
366 
367 template <typename Scalar>
370 {
371  typedef Thyra::ModelEvaluatorBase MEB;
372  MEB::InArgsSetup<Scalar> inArgs = this->createInArgs();
373  return std::move(inArgs);
374 }
375 
376 template <typename 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 
397 template <typename 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 
418 template <typename Scalar>
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< const Thyra::ModelEvaluator< Scalar > > getAppModel() const
Get the underlying application ModelEvaluator.
virtual Teuchos::RCP< const Thyra::VectorSpaceBase< Scalar > > get_g_space(int i) const
Get the g space.
virtual void setExplicitModel(const Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > &model)
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Evaluation< VectorBase< Scalar > > get_f() const
virtual Teuchos::RCP< Thyra::VectorBase< Scalar > > getExplicitOnlyVector(const Teuchos::RCP< Thyra::VectorBase< Scalar > > &full) const
Extract explicit-only vector from a full solution vector.
virtual Thyra::ModelEvaluatorBase::InArgs< Scalar > createInArgs() const
virtual void setParameterIndex(int parameterIndex=-1)
Set the parameter index for explicit-only vector.
virtual Teuchos::RCP< const Thyra::VectorSpaceBase< Scalar > > get_x_space() const
Get the x-solution space.
ModelEvaluator pair for implicit and explicit (IMEX) evaulations.
virtual Thyra::ModelEvaluatorBase::InArgs< Scalar > getNominalValues() const
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 Thyra::ModelEvaluatorBase::OutArgs< Scalar > createOutArgsImpl() const
virtual void setImplicitModel(const Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > &model)
basic_FancyOStream & setOutputToRootOnly(const int rootRank)
virtual void setAppModel(const Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > &me)
Set the underlying application ModelEvaluator.
virtual Teuchos::RCP< Thyra::VectorBase< Scalar > > getIMEXVector(const Teuchos::RCP< Thyra::VectorBase< Scalar > > &full) const
Extract IMEX vector from a full solution vector.
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.
RCP< LinearOpBase< Scalar > > get_W_op() const
RCP< const VectorBase< Scalar > > get_x() const
virtual void evalModelImpl(const Thyra::ModelEvaluatorBase::InArgs< Scalar > &in, const Thyra::ModelEvaluatorBase::OutArgs< Scalar > &out) const
RCP< const VectorBase< Scalar > > get_p(int l) const