9 #ifndef Tempus_StepperDIRK_impl_hpp
10 #define Tempus_StepperDIRK_impl_hpp
12 #include "Tempus_RKButcherTableauBuilder.hpp"
13 #include "Tempus_config.hpp"
15 #include "Tempus_WrapperModelEvaluatorBasic.hpp"
16 #include "Teuchos_VerboseObjectParameterListHelpers.hpp"
17 #include "Thyra_VectorStdOps.hpp"
18 #include "NOX_Thyra.H"
24 template<
class Scalar>
class StepperFactory;
26 template<
class Scalar>
28 const Teuchos::RCP<
const Thyra::ModelEvaluator<Scalar> >& appModel,
29 std::string stepperType)
31 this->setTableau(stepperType);
32 this->setModel(appModel);
36 template<
class Scalar>
38 const Teuchos::RCP<
const Thyra::ModelEvaluator<Scalar> >& appModel,
39 Teuchos::RCP<Teuchos::ParameterList> pList)
41 this->setTableau(pList);
42 this->setParameterList(pList);
43 this->setModel(appModel);
47 template<
class Scalar>
49 const Teuchos::RCP<
const Thyra::ModelEvaluator<Scalar> >& appModel,
50 std::string stepperType,
51 Teuchos::RCP<Teuchos::ParameterList> pList)
53 this->setTableau(stepperType);
54 this->setParameterList(pList);
55 this->setModel(appModel);
60 template<
class Scalar>
63 if (stepperType ==
"") {
66 DIRK_ButcherTableau_ = createRKBT<Scalar>(stepperType, this->stepperPL_);
69 TEUCHOS_TEST_FOR_EXCEPTION( DIRK_ButcherTableau_->isDIRK() !=
true,
71 "Error - StepperDIRK did not receive a DIRK Butcher Tableau!\n"
72 <<
" Stepper Type = " << stepperType <<
"\n");
73 description_ = DIRK_ButcherTableau_->description();
77 template<
class Scalar>
80 if (pList == Teuchos::null) {
82 if (this->stepperPL_ == Teuchos::null)
83 this->stepperPL_ = this->getDefaultParameters();
85 this->stepperPL_ = pList;
88 std::string stepperType =
89 this->stepperPL_->template get<std::string>(
"Stepper Type",
90 "SDIRK 2 Stage 2nd order");
91 DIRK_ButcherTableau_ = createRKBT<Scalar>(stepperType, this->stepperPL_);
93 TEUCHOS_TEST_FOR_EXCEPTION( DIRK_ButcherTableau_->isDIRK() !=
true,
95 "Error - StepperDIRK did not receive a DIRK Butcher Tableau!\n"
96 <<
" Stepper Type = " << stepperType <<
"\n");
97 description_ = DIRK_ButcherTableau_->description();
101 template<
class Scalar>
105 if (obs == Teuchos::null) {
107 if (stepperObserver_ == Teuchos::null) {
108 stepperDIRKObserver_ =
112 (stepperDIRKObserver_);
115 stepperObserver_ = obs;
116 stepperDIRKObserver_ =
122 template<
class Scalar>
125 TEUCHOS_TEST_FOR_EXCEPTION( this->wrapperModel_ == Teuchos::null,
127 "Error - Need to set the model, setModel(), before calling "
128 "StepperDIRK::initialize()\n");
130 this->setTableau(this->stepperPL_);
131 this->setParameterList(this->stepperPL_);
136 const int numStages = DIRK_ButcherTableau_->numStages();
137 stageX_ = this->wrapperModel_->getNominalValues().get_x()->clone_v();
138 stageXDot_.resize(numStages);
139 for (
int i=0; i<numStages; ++i) {
140 stageXDot_[i] = Thyra::createMember(this->wrapperModel_->get_f_space());
141 assign(stageXDot_[i].ptr(), Teuchos::ScalarTraits<Scalar>::zero());
143 xTilde_ = Thyra::createMember(this->wrapperModel_->get_x_space());
144 assign(xTilde_.ptr(), Teuchos::ScalarTraits<Scalar>::zero());
146 if (DIRK_ButcherTableau_->isEmbedded() and this->getEmbedded()) {
147 ee_ = Thyra::createMember(this->wrapperModel_->get_f_space());
148 abs_u0 = Thyra::createMember(this->wrapperModel_->get_f_space());
149 abs_u = Thyra::createMember(this->wrapperModel_->get_f_space());
150 sc = Thyra::createMember(this->wrapperModel_->get_f_space());
154 template<
class Scalar>
160 TEMPUS_FUNC_TIME_MONITOR(
"Tempus::StepperDIRK::takeStep()");
164 "Error - StepperDIRK<Scalar>::takeStep(...)\n"
165 "Need at least two SolutionStates for DIRK.\n"
167 "Try setting in \"Solution History\" \"Storage Type\" = \"Undo\"\n"
168 " or \"Storage Type\" = \"Static\" and \"Storage Limit\" = \"2\"\n");
171 RCP<SolutionState<Scalar> > currentState=
solutionHistory->getCurrentState();
172 RCP<SolutionState<Scalar> > workingState=
solutionHistory->getWorkingState();
173 const Scalar dt = workingState->getTimeStep();
174 const Scalar time = currentState->getTime();
176 const int numStages = DIRK_ButcherTableau_->numStages();
177 Teuchos::SerialDenseMatrix<int,Scalar> A = DIRK_ButcherTableau_->A();
178 Teuchos::SerialDenseVector<int,Scalar> b = DIRK_ButcherTableau_->b();
179 Teuchos::SerialDenseVector<int,Scalar> c = DIRK_ButcherTableau_->c();
183 Thyra::SolveStatus<Scalar> sStatus;
184 for (
int i=0; i < numStages; ++i) {
185 if (!Teuchos::is_null(stepperDIRKObserver_))
187 Thyra::assign(xTilde_.ptr(), *(currentState->getX()));
188 for (
int j=0; j < i; ++j) {
189 if (A(i,j) != Teuchos::ScalarTraits<Scalar>::zero()) {
190 Thyra::Vp_StV(xTilde_.ptr(), dt*A(i,j), *(stageXDot_[j]));
194 Scalar ts = time + c(i)*dt;
195 if (A(i,i) == Teuchos::ScalarTraits<Scalar>::zero()) {
197 bool isNeeded =
false;
198 for (
int k=i+1; k<numStages; ++k)
if (A(k,i) != 0.0) isNeeded =
true;
199 if (b(i) != 0.0) isNeeded =
true;
200 if (isNeeded ==
false) {
202 assign(stageXDot_[i].ptr(), Teuchos::ScalarTraits<Scalar>::zero());
204 typedef Thyra::ModelEvaluatorBase MEB;
205 MEB::InArgs<Scalar> inArgs = this->wrapperModel_->getInArgs();
206 MEB::OutArgs<Scalar> outArgs = this->wrapperModel_->getOutArgs();
207 inArgs.set_x(xTilde_);
208 if (inArgs.supports(MEB::IN_ARG_t)) inArgs.set_t(ts);
209 if (inArgs.supports(MEB::IN_ARG_x_dot))
210 inArgs.set_x_dot(Teuchos::null);
211 outArgs.set_f(stageXDot_[i]);
213 if (!Teuchos::is_null(stepperDIRKObserver_))
215 this->wrapperModel_->getAppModel()->evalModel(inArgs,outArgs);
219 Scalar alpha = 1.0/(dt*A(i,i));
222 Teuchos::RCP<TimeDerivative<Scalar> > timeDer =
224 alpha,xTilde_.getConst()));
227 typedef Thyra::ModelEvaluatorBase MEB;
228 MEB::InArgs<Scalar> inArgs = this->wrapperModel_->getInArgs();
229 MEB::OutArgs<Scalar> outArgs = this->wrapperModel_->getOutArgs();
230 inArgs.set_x(stageX_);
231 if (inArgs.supports(MEB::IN_ARG_x_dot)) inArgs.set_x_dot(stageXDot_[i]);
232 if (inArgs.supports(MEB::IN_ARG_t )) inArgs.set_t (ts);
233 if (inArgs.supports(MEB::IN_ARG_step_size)) inArgs.set_step_size(dt);
234 if (inArgs.supports(MEB::IN_ARG_alpha )) inArgs.set_alpha (alpha);
235 if (inArgs.supports(MEB::IN_ARG_beta )) inArgs.set_beta (1.0);
237 this->wrapperModel_->setForSolve(timeDer, inArgs, outArgs);
239 if (!Teuchos::is_null(stepperDIRKObserver_))
242 sStatus = this->solveImplicitODE(stageX_);
244 if (sStatus.solveStatus != Thyra::SOLVE_STATUS_CONVERGED ) pass=
false;
246 if (!Teuchos::is_null(stepperDIRKObserver_))
249 timeDer->compute(stageX_, stageXDot_[i]);
251 if (!Teuchos::is_null(stepperDIRKObserver_))
256 Thyra::assign((workingState->getX()).ptr(), *(currentState->getX()));
257 for (
int i=0; i < numStages; ++i) {
258 if (b(i) != Teuchos::ScalarTraits<Scalar>::zero()) {
259 Thyra::Vp_StV((workingState->getX()).ptr(), dt*b(i), *(stageXDot_[i]));
263 if (DIRK_ButcherTableau_->isEmbedded() and this->getEmbedded()) {
264 RCP<SolutionStateMetaData<Scalar> > metaData = workingState->getMetaData();
265 const Scalar tolAbs = metaData->getTolRel();
266 const Scalar tolRel = metaData->getTolAbs();
270 Teuchos::SerialDenseVector<int,Scalar> errWght = b ;
271 errWght -= DIRK_ButcherTableau_->bstar();
275 assign(ee_.ptr(), Teuchos::ScalarTraits<Scalar>::zero());
276 for (
int i=0; i < numStages; ++i) {
277 if (errWght(i) != Teuchos::ScalarTraits<Scalar>::zero()) {
278 Thyra::Vp_StV(ee_.ptr(), dt*errWght(i), *(stageXDot_[i]));
283 Thyra::abs( *(currentState->getX()), abs_u0.ptr());
284 Thyra::abs( *(workingState->getX()), abs_u.ptr());
285 Thyra::pair_wise_max_update(tolRel, *abs_u0, abs_u.ptr());
286 Thyra::add_scalar(tolAbs, abs_u.ptr());
289 assign(sc.ptr(), Teuchos::ScalarTraits<Scalar>::zero());
290 Thyra::ele_wise_divide(Teuchos::as<Scalar>(1.0), *ee_, *abs_u, sc.ptr());
291 Scalar err = Thyra::norm_inf(*sc);
292 metaData->setErrorRel(err);
298 if (pass ==
true) workingState->setSolutionStatus(
Status::PASSED);
300 workingState->setOrder(this->getOrder());
312 template<
class Scalar>
313 Teuchos::RCP<Tempus::StepperState<Scalar> >
317 Teuchos::RCP<Tempus::StepperState<Scalar> > stepperState =
323 template<
class Scalar>
326 return(description_);
330 template<
class Scalar>
332 Teuchos::FancyOStream &out,
333 const Teuchos::EVerbosityLevel verbLevel)
const
335 out << description() <<
"::describe:" << std::endl
336 <<
"wrapperModel_ = " << this->wrapperModel_->description() << std::endl;
340 template <
class Scalar>
342 const Teuchos::RCP<Teuchos::ParameterList> & pList)
344 if (pList == Teuchos::null) {
346 if (this->stepperPL_ == Teuchos::null) this->stepperPL_ = this->getDefaultParameters();
348 this->stepperPL_ = pList;
355 template<
class Scalar>
356 Teuchos::RCP<const Teuchos::ParameterList>
359 Teuchos::RCP<Teuchos::ParameterList> pl = Teuchos::parameterList();
360 *pl = *(DIRK_ButcherTableau_->getValidParameters());
361 pl->set<
bool> (
"Zero Initial Guess",
false);
365 template <
class Scalar>
366 Teuchos::RCP<Teuchos::ParameterList>
369 Teuchos::RCP<Teuchos::ParameterList> pl = Teuchos::parameterList();
370 if (DIRK_ButcherTableau_ == Teuchos::null) {
371 auto DIRK_ButcherTableau =
372 createRKBT<Scalar>(
"SDIRK 2 Stage 2nd order", Teuchos::null);
373 pl->setParameters(*(DIRK_ButcherTableau->getValidParameters()));
375 pl->setParameters(*(DIRK_ButcherTableau_->getValidParameters()));
377 pl->set<std::string>(
"Solver Name",
"Default Solver");
378 pl->set<
bool> (
"Zero Initial Guess",
false);
379 Teuchos::RCP<Teuchos::ParameterList> solverPL=this->defaultSolverParameters();
380 pl->set(
"Default Solver", *solverPL);
385 template <
class Scalar>
386 Teuchos::RCP<Teuchos::ParameterList>
389 return(this->stepperPL_);
393 template <
class Scalar>
394 Teuchos::RCP<Teuchos::ParameterList>
397 Teuchos::RCP<Teuchos::ParameterList> temp_plist = this->stepperPL_;
398 this->stepperPL_ = Teuchos::null;
404 #endif // Tempus_StepperDIRK_impl_hpp