Tempus  Version of the Day
Time Integration
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
Tempus_StepperIMEX_RK_Partition_impl.hpp
Go to the documentation of this file.
1 // @HEADER
2 // ****************************************************************************
3 // Tempus: Copyright (2017) Sandia Corporation
4 //
5 // Distributed under BSD 3-clause license (See accompanying file Copyright.txt)
6 // ****************************************************************************
7 // @HEADER
8 
9 #ifndef Tempus_StepperIMEX_RK_Partition_impl_hpp
10 #define Tempus_StepperIMEX_RK_Partition_impl_hpp
11 
12 #include "Tempus_RKButcherTableauBuilder.hpp"
13 #include "Tempus_config.hpp"
15 #include "Tempus_WrapperModelEvaluatorPairPartIMEX_Basic.hpp"
16 #include "Teuchos_VerboseObjectParameterListHelpers.hpp"
17 #include "Thyra_VectorStdOps.hpp"
18 #include "NOX_Thyra.H"
19 
20 
21 namespace Tempus {
22 
23 // Forward Declaration for recursive includes (this Stepper <--> StepperFactory)
24 template<class Scalar> class StepperFactory;
25 
26 
27 template<class Scalar>
29 {
30  this->setTableaus(Teuchos::null, "Partitioned IMEX RK SSP2");
31  this->setParameterList(Teuchos::null);
32  this->modelWarning();
33 }
34 
35 
36 template<class Scalar>
38  const Teuchos::RCP<const Thyra::ModelEvaluator<Scalar> >& appModel,
39  Teuchos::RCP<Teuchos::ParameterList> pList)
40 {
41  this->setTableaus(pList, "Partitioned IMEX RK SSP2");
42  this->setParameterList(pList);
43 
44  if (appModel == Teuchos::null) {
45  this->modelWarning();
46  }
47  else {
48  this->setModel(appModel);
49  this->initialize();
50  }
51 }
52 
53 
54 template<class Scalar>
56  const Teuchos::RCP<const Thyra::ModelEvaluator<Scalar> >& appModel,
57  std::string stepperType)
58 {
59  this->setTableaus(Teuchos::null, stepperType);
60 
61  if (appModel == Teuchos::null) {
62  this->modelWarning();
63  }
64  else {
65  this->setModel(appModel);
66  this->initialize();
67  }
68 }
69 
70 
71 template<class Scalar>
73  const Teuchos::RCP<const Thyra::ModelEvaluator<Scalar> >& appModel,
74  std::string stepperType,
75  Teuchos::RCP<Teuchos::ParameterList> pList)
76 {
77  this->setTableaus(pList, stepperType);
78  this->setParameterList(pList);
79 
80  if (appModel == Teuchos::null) {
81  this->modelWarning();
82  }
83  else {
84  this->setModel(appModel);
85  this->initialize();
86  }
87 }
88 
89 
90 template<class Scalar>
92  Teuchos::RCP<Teuchos::ParameterList> pList,
93  std::string stepperType)
94 {
95  if (stepperType == "") {
96  if (pList == Teuchos::null)
97  stepperType = "Partitioned IMEX RK SSP2";
98  else
99  stepperType = pList->get<std::string>("Stepper Type",
100  "Partitioned IMEX RK SSP2");
101  }
102 
103  if (stepperType == "Partitioned IMEX RK 1st order") {
104  {
105  // Explicit Tableau
106  Teuchos::RCP<Teuchos::ParameterList> pl = Teuchos::parameterList();
107  pl->setName("IMEX-RK Explicit Stepper");
108  pl->set<std::string>("Stepper Type", "General ERK");
109 
110  // Tableau ParameterList
111  Teuchos::RCP<Teuchos::ParameterList> tableauPL = Teuchos::parameterList();
112  tableauPL->set<std::string>("A", "0.0 0.0; 1.0 0.0");
113  tableauPL->set<std::string>("b", "1.0 0.0");
114  tableauPL->set<std::string>("c", "0.0 1.0");
115  tableauPL->set<int>("order", 1);
116  pl->set("Tableau", *tableauPL);
117 
118  this->setExplicitTableau("General ERK", pl);
119  }
120  {
121  // Implicit Tableau
122  Teuchos::RCP<Teuchos::ParameterList> pl = Teuchos::parameterList();
123  pl->setName("IMEX-RK Implicit Stepper");
124  pl->set<std::string>("Stepper Type", "General DIRK");
125  pl->set("Solver Name", "");
126 
127  // Tableau ParameterList
128  Teuchos::RCP<Teuchos::ParameterList> tableauPL = Teuchos::parameterList();
129  tableauPL->set<std::string>("A", "0.0 0.0; 0.0 1.0");
130  tableauPL->set<std::string>("b", "0.0 1.0");
131  tableauPL->set<std::string>("c", "0.0 1.0");
132  tableauPL->set<int>("order", 1);
133  pl->set("Tableau", *tableauPL);
134 
135  this->setImplicitTableau("General DIRK", pl);
136  }
137  description_ = stepperType;
138  order_ = 1;
139 
140  } else if (stepperType == "Partitioned IMEX RK SSP2") {
141  typedef Teuchos::ScalarTraits<Scalar> ST;
142  // Explicit Tableau
143  this->setExplicitTableau("RK Explicit Trapezoidal", Teuchos::null);
144 
145  // Implicit Tableau
146  Teuchos::RCP<Teuchos::ParameterList> pl = Teuchos::parameterList();
147  pl->set<std::string>("Stepper Type", "SDIRK 2 Stage 3rd order");
148  pl->set("Solver Name", "");
149  const Scalar one = ST::one();
150  Scalar gamma = one - one/ST::squareroot(2*one);
151  pl->set<double>("gamma",gamma);
152  this->setImplicitTableau("SDIRK 2 Stage 3rd order", pl);
153 
154  description_ = stepperType;
155  order_ = 2;
156  } else if (stepperType == "Partitioned IMEX RK ARS 233") {
157  using std::to_string;
158  typedef Teuchos::ScalarTraits<Scalar> ST;
159  const Scalar one = ST::one();
160  const Scalar gammaN = (3*one+ST::squareroot(3*one))/(6*one);
161  std::string gamma = to_string( gammaN);
162  std::string one_gamma = to_string(1.0- gammaN);
163  std::string one_2gamma = to_string(1.0-2.0*gammaN);
164  std::string two_2gamma = to_string(2.0-2.0*gammaN);
165  std::string gamma_one = to_string( gammaN-1.0);
166  {
167  // Explicit Tableau
168  Teuchos::RCP<Teuchos::ParameterList> pl = Teuchos::parameterList();
169  pl->setName("IMEX-RK Explicit Stepper");
170  pl->set<std::string>("Stepper Type", "General ERK");
171 
172  // Tableau ParameterList
173  Teuchos::RCP<Teuchos::ParameterList> tableauPL = Teuchos::parameterList();
174  tableauPL->set<std::string>("A",
175  "0.0 0.0 0.0; "+gamma+" 0.0 0.0; "+gamma_one+" "+two_2gamma+" 0.0");
176  tableauPL->set<std::string>("b", "0.0 0.5 0.5");
177  tableauPL->set<std::string>("c", "0.0 "+gamma+" "+one_gamma);
178  tableauPL->set<int>("order", 2);
179  pl->set("Tableau", *tableauPL);
180 
181  this->setExplicitTableau("General ERK", pl);
182  }
183  {
184  // Implicit Tableau
185  Teuchos::RCP<Teuchos::ParameterList> pl = Teuchos::parameterList();
186  pl->setName("IMEX-RK Implicit Stepper");
187  pl->set<std::string>("Stepper Type", "General DIRK");
188  pl->set("Solver Name", "");
189 
190  // Tableau ParameterList
191  Teuchos::RCP<Teuchos::ParameterList> tableauPL = Teuchos::parameterList();
192  tableauPL->set<std::string>("A",
193  "0.0 0.0 0.0; 0.0 "+gamma+" 0.0; 0.0 "+one_2gamma+" "+gamma);
194  tableauPL->set<std::string>("b", "0.0 0.5 0.5");
195  tableauPL->set<std::string>("c", "0.0 "+gamma+" "+one_gamma);
196  tableauPL->set<int>("order", 3);
197  pl->set("Tableau", *tableauPL);
198 
199  this->setImplicitTableau("General DIRK", pl);
200  }
201  description_ = stepperType;
202  order_ = 3;
203 
204  } else if (stepperType == "General Partitioned IMEX RK") {
205  Teuchos::RCP<Teuchos::ParameterList> explicitPL = Teuchos::rcp(
206  new Teuchos::ParameterList(pList->sublist("IMEX-RK Explicit Stepper")));
207 
208  Teuchos::RCP<Teuchos::ParameterList> implicitPL = Teuchos::rcp(
209  new Teuchos::ParameterList(pList->sublist("IMEX-RK Implicit Stepper")));
210 
211  // TODO: should probably check the order of the tableau match
212  this->setExplicitTableau("General ERK", explicitPL);
213  this->setImplicitTableau("General DIRK", implicitPL);
214  description_ = stepperType;
215  order_ = pList->get<int>("overall order", 0);
216 
217  } else {
218  TEUCHOS_TEST_FOR_EXCEPTION( true, std::logic_error,
219  "Error - Not a valid StepperIMEX_RK_Partition type! Stepper Type = "
220  << stepperType << "\n"
221  << " Current valid types are: " << "\n"
222  << " 'Partitioned IMEX RK 1st order'" << "\n"
223  << " 'Partitioned IMEX RK SSP2'" << "\n"
224  << " 'Partitioned IMEX RK ARS 233'" << "\n"
225  << " 'General Partitioned IMEX RK'" << "\n");
226  }
227 
228  TEUCHOS_TEST_FOR_EXCEPTION(explicitTableau_==Teuchos::null,
229  std::runtime_error,
230  "Error - StepperIMEX_RK_Partition - Explicit tableau is null!");
231  TEUCHOS_TEST_FOR_EXCEPTION(implicitTableau_==Teuchos::null,
232  std::runtime_error,
233  "Error - StepperIMEX_RK_Partition - Implicit tableau is null!");
234  TEUCHOS_TEST_FOR_EXCEPTION(
235  explicitTableau_->numStages()!=implicitTableau_->numStages(),
236  std::runtime_error,
237  "Error - StepperIMEX_RK_Partition - Number of stages do not match!\n"
238  << " Explicit tableau = " << explicitTableau_->description() << "\n"
239  << " number of stages = " << explicitTableau_->numStages() << "\n"
240  << " Implicit tableau = " << implicitTableau_->description() << "\n"
241  << " number of stages = " << implicitTableau_->numStages() << "\n");
242 }
243 
244 
245 template<class Scalar>
247  std::string stepperType,
248  Teuchos::RCP<Teuchos::ParameterList> pList)
249 {
250  Teuchos::RCP<const RKButcherTableau<Scalar> > explicitTableau =
251  createRKBT<Scalar>(stepperType,pList);
252  this->setExplicitTableau(explicitTableau);
253 }
254 
255 
256 template<class Scalar>
258  Teuchos::RCP<const RKButcherTableau<Scalar> > explicitTableau)
259 {
260  TEUCHOS_TEST_FOR_EXCEPTION(explicitTableau->isImplicit() == true,
261  std::logic_error,
262  "Error - Received an implicit Tableau for setExplicitTableau()!\n" <<
263  " Tableau = " << explicitTableau->description() << "\n");
264  explicitTableau_ = explicitTableau;
265 }
266 
267 
268 template<class Scalar>
270  std::string stepperType,
271  Teuchos::RCP<Teuchos::ParameterList> pList)
272 {
273  Teuchos::RCP<const RKButcherTableau<Scalar> > implicitTableau =
274  createRKBT<Scalar>(stepperType,pList);
275  this->setImplicitTableau(implicitTableau);
276 }
277 
278 
279 template<class Scalar>
281  Teuchos::RCP<const RKButcherTableau<Scalar> > implicitTableau)
282 {
283  TEUCHOS_TEST_FOR_EXCEPTION( implicitTableau->isDIRK() != true,
284  std::logic_error,
285  "Error - Did not receive a DIRK Tableau for setImplicitTableau()!\n" <<
286  " Tableau = " << implicitTableau->description() << "\n");
287  implicitTableau_ = implicitTableau;
288 }
289 
290 template<class Scalar>
292  const Teuchos::RCP<const Thyra::ModelEvaluator<Scalar> >& appModel)
293 {
294  using Teuchos::RCP;
295  using Teuchos::rcp_const_cast;
296  using Teuchos::rcp_dynamic_cast;
297  RCP<Thyra::ModelEvaluator<Scalar> > ncModel =
298  rcp_const_cast<Thyra::ModelEvaluator<Scalar> > (appModel);
299  RCP<WrapperModelEvaluatorPairPartIMEX_Basic<Scalar> > modelPairIMEX =
300  rcp_dynamic_cast<WrapperModelEvaluatorPairPartIMEX_Basic<Scalar> >(ncModel);
301  TEUCHOS_TEST_FOR_EXCEPTION( modelPairIMEX == Teuchos::null, std::logic_error,
302  "Error - StepperIMEX_RK::setModel() was given a ModelEvaluator that\n"
303  " could not be cast to a WrapperModelEvaluatorPairPartIMEX_Basic!\n"
304  " From: " << appModel << "\n"
305  " To : " << modelPairIMEX << "\n"
306  " Likely have given the wrong ModelEvaluator to this Stepper.\n");
307 
308  setModelPair(modelPairIMEX);
309 }
310 
311 /** \brief Create WrapperModelPairIMEX from user-supplied ModelEvaluator pair.
312  *
313  * The user-supplied ME pair can contain any user-specific IMEX interactions
314  * between explicit and implicit MEs.
315  */
316 template<class Scalar>
319  mePairIMEX)
320 {
321  Teuchos::RCP<WrapperModelEvaluatorPairPartIMEX_Basic<Scalar> >
322  wrapperModelPairIMEX =
323  Teuchos::rcp_dynamic_cast<WrapperModelEvaluatorPairPartIMEX_Basic<Scalar> >
324  (this->wrapperModel_);
325  this->validExplicitODE (mePairIMEX->getExplicitModel());
326  this->validImplicitODE_DAE(mePairIMEX->getImplicitModel());
327  wrapperModelPairIMEX = mePairIMEX;
328  wrapperModelPairIMEX->initialize();
329 
330  this->wrapperModel_ = wrapperModelPairIMEX;
331 }
332 
333 /** \brief Create WrapperModelPairIMEX from explicit/implicit ModelEvaluators.
334  *
335  * Use the supplied explicit/implicit MEs to create a WrapperModelPairIMEX
336  * with basic IMEX interactions between explicit and implicit MEs.
337  */
338 template<class Scalar>
340  const Teuchos::RCP<const Thyra::ModelEvaluator<Scalar> >& explicitModel,
341  const Teuchos::RCP<const Thyra::ModelEvaluator<Scalar> >& implicitModel)
342 {
343  this->validExplicitODE (explicitModel);
344  this->validImplicitODE_DAE(implicitModel);
345  this->wrapperModel_ = Teuchos::rcp(
347  explicitModel, implicitModel));
348 }
349 
350 
351 template<class Scalar>
353  Teuchos::RCP<StepperObserver<Scalar> > obs)
354 {
355  if (obs == Teuchos::null) {
356  // Create default observer, otherwise keep current observer.
357  if (this->stepperObserver_ == Teuchos::null) {
358  stepperIMEX_RKPartObserver_ =
359  Teuchos::rcp(new StepperIMEX_RKPartObserver<Scalar>());
360  this->stepperObserver_ =
361  Teuchos::rcp_dynamic_cast<StepperObserver<Scalar> >
362  (stepperIMEX_RKPartObserver_);
363  }
364  } else {
365  this->stepperObserver_ = obs;
366  stepperIMEX_RKPartObserver_ =
367  Teuchos::rcp_dynamic_cast<StepperIMEX_RKPartObserver<Scalar> >
368  (this->stepperObserver_);
369  }
370 }
371 
372 
373 template<class Scalar>
375 {
376  TEUCHOS_TEST_FOR_EXCEPTION(
377  (explicitTableau_ == Teuchos::null) || (implicitTableau_ == Teuchos::null),
378  std::logic_error,
379  "Error - Need to set the Butcher Tableaus, setTableaus(), before calling "
380  "StepperIMEX_RK_Partition::initialize()\n");
381 
382  Teuchos::RCP<WrapperModelEvaluatorPairPartIMEX_Basic<Scalar> >
383  wrapperModelPairIMEX =
384  Teuchos::rcp_dynamic_cast<WrapperModelEvaluatorPairPartIMEX_Basic<Scalar> >
385  (this->wrapperModel_);
386  TEUCHOS_TEST_FOR_EXCEPTION( wrapperModelPairIMEX == Teuchos::null,
387  std::logic_error,
388  "Error - Need to set the model, setModel(), before calling "
389  "StepperIMEX_RK_Partition::initialize()\n");
390 
391  this->setTableaus(this->stepperPL_);
392  this->setParameterList(this->stepperPL_);
393  this->setSolver();
394  this->setObserver();
395 
396  // Initialize the stage vectors
397  const int numStages = explicitTableau_->numStages();
398  stageF_.resize(numStages);
399  stageGx_.resize(numStages);
400  for(int i=0; i < numStages; i++) {
401  stageF_[i] = Thyra::createMember(wrapperModelPairIMEX->
402  getExplicitModel()->get_f_space());
403  stageGx_[i] = Thyra::createMember(wrapperModelPairIMEX->
404  getImplicitModel()->get_f_space());
405  assign(stageF_[i].ptr(), Teuchos::ScalarTraits<Scalar>::zero());
406  assign(stageGx_[i].ptr(), Teuchos::ScalarTraits<Scalar>::zero());
407  }
408 
409  xTilde_ = Thyra::createMember(wrapperModelPairIMEX->
410  getImplicitModel()->get_x_space());
411  assign(xTilde_.ptr(), Teuchos::ScalarTraits<Scalar>::zero());
412 }
413 
414 
415 template<class Scalar>
417  const Teuchos::RCP<SolutionHistory<Scalar> >& solutionHistory)
418 {
419  using Teuchos::RCP;
420 
421  int numStates = solutionHistory->getNumStates();
422 
423  TEUCHOS_TEST_FOR_EXCEPTION(numStates < 1, std::logic_error,
424  "Error - setInitialConditions() needs at least one SolutionState\n"
425  " to set the initial condition. Number of States = " << numStates);
426 
427  if (numStates > 1) {
428  RCP<Teuchos::FancyOStream> out = this->getOStream();
429  Teuchos::OSTab ostab(out,1,"StepperIMEX_RK::setInitialConditions()");
430  *out << "Warning -- SolutionHistory has more than one state!\n"
431  << "Setting the initial conditions on the currentState.\n"<<std::endl;
432  }
433 
434  RCP<SolutionState<Scalar> > initialState = solutionHistory->getCurrentState();
435  RCP<Thyra::VectorBase<Scalar> > x = initialState->getX();
436 
437  // Use x from inArgs as ICs, if needed.
438  auto inArgs = this->wrapperModel_->getNominalValues();
439  if (x == Teuchos::null) {
440  TEUCHOS_TEST_FOR_EXCEPTION( (x == Teuchos::null) &&
441  (inArgs.get_x() == Teuchos::null), std::logic_error,
442  "Error - setInitialConditions() needs the ICs from the SolutionHistory\n"
443  " or getNominalValues()!\n");
444 
445  x = Teuchos::rcp_const_cast<Thyra::VectorBase<Scalar> >(inArgs.get_x());
446  initialState->setX(x);
447  }
448 
449 
450  // Perform IC Consistency
451  std::string icConsistency = this->getICConsistency();
452  TEUCHOS_TEST_FOR_EXCEPTION(icConsistency != "None", std::logic_error,
453  "Error - setInitialConditions() requested a consistency of '"
454  << icConsistency << "'.\n"
455  " But only 'None' is available for IMEX-RK!\n");
456 
457  TEUCHOS_TEST_FOR_EXCEPTION( this->getUseFSAL(), std::logic_error,
458  "Error - The First-Step-As-Last (FSAL) principle is not "
459  << "available for IMEX-RK. Set useFSAL=false.\n");
460 }
461 
462 
463 template <typename Scalar>
465  const Teuchos::RCP<const Thyra::VectorBase<Scalar> > & X,
466  const Teuchos::RCP<const Thyra::VectorBase<Scalar> > & Y,
467  Scalar time, Scalar stepSize, Scalar stageNumber,
468  const Teuchos::RCP<Thyra::VectorBase<Scalar> > & G) const
469 {
470  typedef Thyra::ModelEvaluatorBase MEB;
471  Teuchos::RCP<WrapperModelEvaluatorPairPartIMEX_Basic<Scalar> >
472  wrapperModelPairIMEX =
473  Teuchos::rcp_dynamic_cast<WrapperModelEvaluatorPairPartIMEX_Basic<Scalar> >
474  (this->wrapperModel_);
475  MEB::InArgs<Scalar> inArgs = wrapperModelPairIMEX->getInArgs();
476  inArgs.set_x(X);
477  inArgs.set_p(wrapperModelPairIMEX->getParameterIndex(), Y);
478  if (inArgs.supports(MEB::IN_ARG_t)) inArgs.set_t(time);
479  if (inArgs.supports(MEB::IN_ARG_step_size)) inArgs.set_step_size(stepSize);
480  if (inArgs.supports(MEB::IN_ARG_stage_number))
481  inArgs.set_stage_number(stageNumber);
482 
483  // For model evaluators whose state function f(x, x_dot, t) describes
484  // an implicit ODE, and which accept an optional x_dot input argument,
485  // make sure the latter is set to null in order to request the evaluation
486  // of a state function corresponding to the explicit ODE formulation
487  // x_dot = f(x, t)
488  if (inArgs.supports(MEB::IN_ARG_x_dot)) inArgs.set_x_dot(Teuchos::null);
489 
490  MEB::OutArgs<Scalar> outArgs = wrapperModelPairIMEX->getOutArgs();
491  outArgs.set_f(G);
492 
493  wrapperModelPairIMEX->getImplicitModel()->evalModel(inArgs,outArgs);
494  Thyra::Vt_S(G.ptr(), -1.0);
495 }
496 
497 
498 template <typename Scalar>
500  const Teuchos::RCP<const Thyra::VectorBase<Scalar> > & Z,
501  Scalar time, Scalar stepSize, Scalar stageNumber,
502  const Teuchos::RCP<Thyra::VectorBase<Scalar> > & F) const
503 {
504  typedef Thyra::ModelEvaluatorBase MEB;
505 
506  Teuchos::RCP<WrapperModelEvaluatorPairPartIMEX_Basic<Scalar> >
507  wrapperModelPairIMEX =
508  Teuchos::rcp_dynamic_cast<WrapperModelEvaluatorPairPartIMEX_Basic<Scalar> >
509  (this->wrapperModel_);
510  MEB::InArgs<Scalar> inArgs =
511  wrapperModelPairIMEX->getExplicitModel()->createInArgs();
512  inArgs.set_x(Z);
513  if (inArgs.supports(MEB::IN_ARG_t)) inArgs.set_t(time);
514  if (inArgs.supports(MEB::IN_ARG_step_size)) inArgs.set_step_size(stepSize);
515  if (inArgs.supports(MEB::IN_ARG_stage_number))
516  inArgs.set_stage_number(stageNumber);
517 
518  // For model evaluators whose state function f(x, x_dot, t) describes
519  // an implicit ODE, and which accept an optional x_dot input argument,
520  // make sure the latter is set to null in order to request the evaluation
521  // of a state function corresponding to the explicit ODE formulation
522  // x_dot = f(x, t)
523  if (inArgs.supports(MEB::IN_ARG_x_dot)) inArgs.set_x_dot(Teuchos::null);
524 
525  MEB::OutArgs<Scalar> outArgs =
526  wrapperModelPairIMEX->getExplicitModel()->createOutArgs();
527  outArgs.set_f(F);
528 
529  wrapperModelPairIMEX->getExplicitModel()->evalModel(inArgs, outArgs);
530  Thyra::Vt_S(F.ptr(), -1.0);
531 }
532 
533 
534 template<class Scalar>
536  const Teuchos::RCP<SolutionHistory<Scalar> >& solutionHistory)
537 {
538  using Teuchos::RCP;
539  using Teuchos::SerialDenseMatrix;
540  using Teuchos::SerialDenseVector;
541 
542  TEMPUS_FUNC_TIME_MONITOR("Tempus::StepperIMEX_RK_Partition::takeStep()");
543  {
544  TEUCHOS_TEST_FOR_EXCEPTION(solutionHistory->getNumStates() < 2,
545  std::logic_error,
546  "Error - StepperIMEX_RK_Partition<Scalar>::takeStep(...)\n"
547  "Need at least two SolutionStates for IMEX_RK_Partition.\n"
548  " Number of States = " << solutionHistory->getNumStates() << "\n"
549  "Try setting in \"Solution History\" \"Storage Type\" = \"Undo\"\n"
550  " or \"Storage Type\" = \"Static\" and \"Storage Limit\" = \"2\"\n");
551 
552  this->stepperObserver_->observeBeginTakeStep(solutionHistory, *this);
553  RCP<SolutionState<Scalar> > currentState=solutionHistory->getCurrentState();
554  RCP<SolutionState<Scalar> > workingState=solutionHistory->getWorkingState();
555  const Scalar dt = workingState->getTimeStep();
556  const Scalar time = currentState->getTime();
557 
558  const int numStages = explicitTableau_->numStages();
559  const SerialDenseMatrix<int,Scalar> & AHat = explicitTableau_->A();
560  const SerialDenseVector<int,Scalar> & bHat = explicitTableau_->b();
561  const SerialDenseVector<int,Scalar> & cHat = explicitTableau_->c();
562  const SerialDenseMatrix<int,Scalar> & A = implicitTableau_->A();
563  const SerialDenseVector<int,Scalar> & b = implicitTableau_->b();
564  const SerialDenseVector<int,Scalar> & c = implicitTableau_->c();
565 
566  Teuchos::RCP<WrapperModelEvaluatorPairPartIMEX_Basic<Scalar> >
567  wrapperModelPairIMEX =
568  Teuchos::rcp_dynamic_cast<WrapperModelEvaluatorPairPartIMEX_Basic<Scalar> >
569  (this->wrapperModel_);
570 
571  bool pass = true;
572  Thyra::SolveStatus<Scalar> sStatus;
573  stageZ_ = workingState->getX();
574  Thyra::assign(stageZ_.ptr(), *(currentState->getX()));
575  RCP<Thyra::VectorBase<Scalar> > stageY =
576  wrapperModelPairIMEX->getExplicitOnlyVector(stageZ_);
577  RCP<Thyra::VectorBase<Scalar> > stageX =
578  wrapperModelPairIMEX->getIMEXVector(stageZ_);
579 
580  // Compute stage solutions
581  for (int i = 0; i < numStages; ++i) {
582  if (!Teuchos::is_null(stepperIMEX_RKPartObserver_))
583  stepperIMEX_RKPartObserver_->observeBeginStage(solutionHistory, *this);
584 
585  Thyra::assign(stageY.ptr(),
586  *(wrapperModelPairIMEX->getExplicitOnlyVector(currentState->getX())));
587  Thyra::assign(xTilde_.ptr(),
588  *(wrapperModelPairIMEX->getIMEXVector(currentState->getX())));
589  for (int j = 0; j < i; ++j) {
590  if (AHat(i,j) != Teuchos::ScalarTraits<Scalar>::zero()) {
591  RCP<Thyra::VectorBase<Scalar> > stageFy =
592  wrapperModelPairIMEX->getExplicitOnlyVector(stageF_[j]);
593  RCP<Thyra::VectorBase<Scalar> > stageFx =
594  wrapperModelPairIMEX->getIMEXVector(stageF_[j]);
595  Thyra::Vp_StV(stageY.ptr(), -dt*AHat(i,j), *stageFy);
596  Thyra::Vp_StV(xTilde_.ptr(), -dt*AHat(i,j), *stageFx);
597  }
598  if (A (i,j) != Teuchos::ScalarTraits<Scalar>::zero())
599  Thyra::Vp_StV(xTilde_.ptr(), -dt*A (i,j), *(stageGx_[j]));
600  }
601 
602  Scalar ts = time + c(i)*dt;
603  Scalar tHats = time + cHat(i)*dt;
604  if (A(i,i) == Teuchos::ScalarTraits<Scalar>::zero()) {
605  // Explicit stage for the ImplicitODE_DAE
606  bool isNeeded = false;
607  for (int k=i+1; k<numStages; ++k) if (A(k,i) != 0.0) isNeeded = true;
608  if (b(i) != 0.0) isNeeded = true;
609  if (isNeeded == false) {
610  // stageGx_[i] is not needed.
611  assign(stageGx_[i].ptr(), Teuchos::ScalarTraits<Scalar>::zero());
612  } else {
613  Thyra::assign(stageX.ptr(), *xTilde_);
614  if (!Teuchos::is_null(stepperIMEX_RKPartObserver_))
615  stepperIMEX_RKPartObserver_->
616  observeBeforeImplicitExplicitly(solutionHistory, *this);
617  evalImplicitModelExplicitly(stageX, stageY, ts, dt, i, stageGx_[i]);
618  }
619  } else {
620  // Implicit stage for the ImplicitODE_DAE
621  const Scalar alpha = Scalar(1.0)/(dt*A(i,i));
622  const Scalar beta = Scalar(1.0);
623 
624  // Setup TimeDerivative
625  RCP<TimeDerivative<Scalar> > timeDer =
627  alpha, xTilde_.getConst()));
628 
629  // Setup InArgs and OutArgs
630  typedef Thyra::ModelEvaluatorBase MEB;
631  //MEB::InArgs<Scalar> inArgs = wrapperModelPairIMEX->getInArgs();
632  //MEB::OutArgs<Scalar> outArgs = wrapperModelPairIMEX->getOutArgs();
633  wrapperModelPairIMEX->setUseImplicitModel(true);
634  MEB::InArgs<Scalar> inArgs = wrapperModelPairIMEX->createInArgs();
635  MEB::OutArgs<Scalar> outArgs = wrapperModelPairIMEX->createOutArgs();
636  inArgs.set_x(stageX);
637  if (wrapperModelPairIMEX->getParameterIndex() >= 0)
638  inArgs.set_p(wrapperModelPairIMEX->getParameterIndex(), stageY);
639  if (inArgs.supports(MEB::IN_ARG_x_dot)) inArgs.set_x_dot(stageGx_[i]);
640  if (inArgs.supports(MEB::IN_ARG_t )) inArgs.set_t (ts);
641  if (inArgs.supports(MEB::IN_ARG_step_size)) inArgs.set_step_size(dt);
642  if (inArgs.supports(MEB::IN_ARG_alpha )) inArgs.set_alpha (alpha);
643  if (inArgs.supports(MEB::IN_ARG_beta )) inArgs.set_beta (beta);
644  if (inArgs.supports(MEB::IN_ARG_stage_number))
645  inArgs.set_stage_number(i);
646 
647  wrapperModelPairIMEX->setForSolve(timeDer, inArgs, outArgs);
648 
649  if (!Teuchos::is_null(stepperIMEX_RKPartObserver_))
650  stepperIMEX_RKPartObserver_->observeBeforeSolve(solutionHistory, *this);
651 
652  this->solver_->setModel(wrapperModelPairIMEX);
653  sStatus = this->solveImplicitODE(stageX);
654  if (sStatus.solveStatus != Thyra::SOLVE_STATUS_CONVERGED) pass = false;
655 
656  wrapperModelPairIMEX->setUseImplicitModel(false);
657 
658  if (!Teuchos::is_null(stepperIMEX_RKPartObserver_))
659  stepperIMEX_RKPartObserver_->observeAfterSolve(solutionHistory, *this);
660 
661  // Update contributions to stage values
662  Thyra::V_StVpStV(stageGx_[i].ptr(), -alpha, *stageX, alpha, *xTilde_);
663  }
664 
665  if (!Teuchos::is_null(stepperIMEX_RKPartObserver_))
666  stepperIMEX_RKPartObserver_->observeBeforeExplicit(solutionHistory,*this);
667  evalExplicitModel(stageZ_, tHats, dt, i, stageF_[i]);
668  if (!Teuchos::is_null(stepperIMEX_RKPartObserver_))
669  stepperIMEX_RKPartObserver_->observeEndStage(solutionHistory, *this);
670  }
671 
672  // Sum for solution: y_n = y_n-1 - dt*Sum{ bHat(i)*fy(i) }
673  // Sum for solution: x_n = x_n-1 - dt*Sum{ bHat(i)*fx(i) + b(i)*gx(i) }
674  Thyra::assign((workingState->getX()).ptr(), *(currentState->getX()));
675  RCP<Thyra::VectorBase<Scalar> > Z = workingState->getX();
676  RCP<Thyra::VectorBase<Scalar> > X = wrapperModelPairIMEX->getIMEXVector(Z);
677  for (int i=0; i < numStages; ++i) {
678  if (bHat(i) != Teuchos::ScalarTraits<Scalar>::zero())
679  Thyra::Vp_StV(Z.ptr(), -dt*bHat(i), *(stageF_[i]));
680  if (b (i) != Teuchos::ScalarTraits<Scalar>::zero())
681  Thyra::Vp_StV(X.ptr(), -dt*b (i), *(stageGx_[i]));
682  }
683 
684  if (pass == true) workingState->setSolutionStatus(Status::PASSED);
685  else workingState->setSolutionStatus(Status::FAILED);
686  workingState->setOrder(this->getOrder());
687  this->stepperObserver_->observeEndTakeStep(solutionHistory, *this);
688  }
689  return;
690 }
691 
692 /** \brief Provide a StepperState to the SolutionState.
693  * This Stepper does not have any special state data,
694  * so just provide the base class StepperState with the
695  * Stepper description. This can be checked to ensure
696  * that the input StepperState can be used by this Stepper.
697  */
698 template<class Scalar>
699 Teuchos::RCP<Tempus::StepperState<Scalar> >
702 {
703  Teuchos::RCP<Tempus::StepperState<Scalar> > stepperState =
704  rcp(new StepperState<Scalar>(description()));
705  return stepperState;
706 }
707 
708 
709 template<class Scalar>
711 {
712  return(description_);
713 }
714 
715 
716 template<class Scalar>
718  Teuchos::FancyOStream &out,
719  const Teuchos::EVerbosityLevel /* verbLevel */) const
720 {
721  out << description() << "::describe:" << std::endl
722  << "wrapperModelPairIMEX = " << this->wrapperModel_->description()
723  << std::endl;
724 }
725 
726 
727 template <class Scalar>
729  const Teuchos::RCP<Teuchos::ParameterList> & pList)
730 {
731  if (pList == Teuchos::null) {
732  // Create default parameters if null, otherwise keep current parameters.
733  if (this->stepperPL_ == Teuchos::null) this->stepperPL_ = this->getDefaultParameters();
734  } else {
735  this->stepperPL_ = pList;
736  }
737  // Can not validate because of optional Parameters.
738  //stepperPL_->validateParametersAndSetDefaults(*this->getValidParameters());
739 }
740 
741 
742 template<class Scalar>
743 Teuchos::RCP<const Teuchos::ParameterList>
745 {
746  Teuchos::RCP<Teuchos::ParameterList> pl = Teuchos::parameterList();
747  pl->setName("Default Stepper - Partitioned IMEX RK SSP2");
748  pl->set<std::string>("Stepper Type", "Partitioned IMEX RK SSP2");
749  this->getValidParametersBasic(pl);
750  pl->set<bool>("Initial Condition Consistency Check", false);
751  pl->set<bool> ("Zero Initial Guess", false);
752  pl->set<std::string>("Solver Name", "",
753  "Name of ParameterList containing the solver specifications.");
754 
755  return pl;
756 }
757 
758 template <class Scalar>
759 Teuchos::RCP<Teuchos::ParameterList>
761 {
762  using Teuchos::RCP;
763  using Teuchos::ParameterList;
764  using Teuchos::rcp_const_cast;
765 
766  RCP<ParameterList> pl =
767  rcp_const_cast<ParameterList>(this->getValidParameters());
768 
769  pl->set<std::string>("Solver Name", "Default Solver");
770  RCP<ParameterList> solverPL = this->defaultSolverParameters();
771  pl->set("Default Solver", *solverPL);
772 
773  return pl;
774 }
775 
776 template <class Scalar>
777 Teuchos::RCP<Teuchos::ParameterList>
779 {
780  return(this->stepperPL_);
781 }
782 
783 
784 template <class Scalar>
785 Teuchos::RCP<Teuchos::ParameterList>
787 {
788  Teuchos::RCP<Teuchos::ParameterList> temp_plist = this->stepperPL_;
789  this->stepperPL_ = Teuchos::null;
790  return(temp_plist);
791 }
792 
793 
794 } // namespace Tempus
795 #endif // Tempus_StepperIMEX_RK_Partition_impl_hpp
Teuchos::RCP< const Teuchos::ParameterList > getValidParameters() const
virtual void setImplicitTableau(std::string stepperType, Teuchos::RCP< Teuchos::ParameterList > pList)
Set the implicit tableau from ParameterList.
virtual void setModelPair(const Teuchos::RCP< WrapperModelEvaluatorPairPartIMEX_Basic< Scalar > > &modelPair)
Create WrapperModelPairIMEX from user-supplied ModelEvaluator pair.
Teuchos::RCP< Teuchos::ParameterList > unsetParameterList()
virtual Thyra::ModelEvaluatorBase::InArgs< Scalar > getInArgs()
Get InArgs the wrapper ModelEvalutor.
void evalExplicitModel(const Teuchos::RCP< const Thyra::VectorBase< Scalar > > &X, Scalar time, Scalar stepSize, Scalar stageNumber, const Teuchos::RCP< Thyra::VectorBase< Scalar > > &F) const
StepperIMEX_RKPartObserver class for StepperIMEX_RK_Partition.
StepperState is a simple class to hold state information about the stepper.
virtual Teuchos::RCP< Tempus::StepperState< Scalar > > getDefaultStepperState()
Provide a StepperState to the SolutionState. This Stepper does not have any special state data...
ModelEvaluator pair for implicit and explicit (IMEX) evaulations.
void setParameterList(const Teuchos::RCP< Teuchos::ParameterList > &pl)
Teuchos::RCP< Teuchos::ParameterList > getDefaultParameters() const
Teuchos::RCP< Teuchos::ParameterList > getNonconstParameterList()
void evalImplicitModelExplicitly(const Teuchos::RCP< const Thyra::VectorBase< Scalar > > &X, const Teuchos::RCP< const Thyra::VectorBase< Scalar > > &Y, Scalar time, Scalar stepSize, Scalar stageNumber, const Teuchos::RCP< Thyra::VectorBase< Scalar > > &G) const
StepperObserver class for Stepper class.
Teuchos::RCP< SolutionHistory< Scalar > > solutionHistory(Teuchos::RCP< Teuchos::ParameterList > pList=Teuchos::null)
Nonmember constructor.
SolutionHistory is basically a container of SolutionStates. SolutionHistory maintains a collection of...
virtual void setObserver(Teuchos::RCP< StepperObserver< Scalar > > obs=Teuchos::null)
Set Observer.
Time-derivative interface for Partitioned IMEX RK.
virtual void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const
virtual void setTableaus(Teuchos::RCP< Teuchos::ParameterList > pList, std::string stepperType="")
Set both the explicit and implicit tableau from ParameterList.
virtual Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > getExplicitModel() const
virtual void setModel(const Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > &appModel)
virtual void takeStep(const Teuchos::RCP< SolutionHistory< Scalar > > &solutionHistory)
Take the specified timestep, dt, and return true if successful.
virtual void setInitialConditions(const Teuchos::RCP< SolutionHistory< Scalar > > &solutionHistory)
Set the initial conditions and make them consistent.
virtual void initialize()
Initialize during construction and after changing input parameters.
virtual void setExplicitTableau(std::string stepperType, Teuchos::RCP< Teuchos::ParameterList > pList)
Set the explicit tableau from ParameterList.