9 #ifndef Tempus_StepperExplicitRK_impl_hpp
10 #define Tempus_StepperExplicitRK_impl_hpp
14 #include "Teuchos_VerboseObjectParameterListHelpers.hpp"
15 #include "Thyra_VectorStdOps.hpp"
21 template<
class Scalar>
24 this->setUseFSAL( this->getUseFSALDefault());
25 this->setICConsistency( this->getICConsistencyDefault());
26 this->setICConsistencyCheck( this->getICConsistencyCheckDefault());
27 this->setUseEmbedded( this->getUseEmbeddedDefault());
29 this->setStageNumber(-1);
31 #ifndef TEMPUS_HIDE_DEPRECATED_CODE
34 this->setAppAction(Teuchos::null);
38 #ifndef TEMPUS_HIDE_DEPRECATED_CODE
39 template<
class Scalar>
41 const Teuchos::RCP<
const Thyra::ModelEvaluator<Scalar> >& appModel,
44 std::string ICConsistency,
45 bool ICConsistencyCheck,
48 this->setUseFSAL( useFSAL);
49 this->setICConsistency( ICConsistency);
50 this->setICConsistencyCheck( ICConsistencyCheck);
51 this->setUseEmbedded( useEmbedded);
53 this->setStageNumber(-1);
55 this->stepperObserver_ =
57 this->setObserver(obs);
58 this->setAppAction(Teuchos::null);
60 if (appModel != Teuchos::null) {
61 this->setModel(appModel);
66 template<
class Scalar>
68 const Teuchos::RCP<
const Thyra::ModelEvaluator<Scalar> >& appModel,
70 std::string ICConsistency,
71 bool ICConsistencyCheck,
75 this->setUseFSAL( useFSAL);
76 this->setICConsistency( ICConsistency);
77 this->setICConsistencyCheck( ICConsistencyCheck);
78 this->setUseEmbedded( useEmbedded);
80 this->setStageNumber(-1);
82 #ifndef TEMPUS_HIDE_DEPRECATED_CODE
85 this->setAppAction(stepperRKAppAction);
87 if (appModel != Teuchos::null) {
88 this->setModel(appModel);
94 template<
class Scalar>
99 Scalar dt = Scalar(1.0e+99);
100 if (!this->getUseEmbedded())
return dt;
102 Teuchos::RCP<SolutionState<Scalar> > currentState=sh->getCurrentState();
103 const int order = currentState->getOrder();
104 const Scalar time = currentState->getTime();
105 const Scalar errorRel = currentState->getTolRel();
106 const Scalar errorAbs = currentState->getTolAbs();
108 Teuchos::RCP<Thyra::VectorBase<Scalar> > stageX, scratchX;
109 stageX = Thyra::createMember(this->appModel_->get_f_space());
110 scratchX = Thyra::createMember(this->appModel_->get_f_space());
111 Thyra::assign(stageX.ptr(), *(currentState->getX()));
113 std::vector<Teuchos::RCP<Thyra::VectorBase<Scalar> > > stageXDot(2);
114 for (
int i=0; i<2; ++i) {
115 stageXDot[i] = Thyra::createMember(this->appModel_->get_f_space());
116 assign(stageXDot[i].ptr(), Teuchos::ScalarTraits<Scalar>::zero());
120 typedef Thyra::ModelEvaluatorBase MEB;
121 MEB::InArgs<Scalar> inArgs = this->appModel_->getNominalValues();
122 MEB::OutArgs<Scalar> outArgs = this->appModel_->createOutArgs();
123 inArgs.set_x(stageX);
124 if (inArgs.supports(MEB::IN_ARG_t)) inArgs.set_t(time);
125 if (inArgs.supports(MEB::IN_ARG_x_dot)) inArgs.set_x_dot(Teuchos::null);
126 outArgs.set_f(stageXDot[0]);
127 this->appModel_->evalModel(inArgs, outArgs);
129 auto err_func = [] (Teuchos::RCP<Thyra::VectorBase<Scalar> > U,
130 const Scalar rtol,
const Scalar atol,
131 Teuchos::RCP<Thyra::VectorBase<Scalar> > absU)
134 Thyra::assign(absU.ptr(), *U);
135 Thyra::abs(*U, absU.ptr());
136 Thyra::Vt_S(absU.ptr(), rtol);
137 Thyra::Vp_S(absU.ptr(), atol);
138 Thyra::ele_wise_divide(Teuchos::as<Scalar>(1.0), *U, *absU, absU.ptr());
139 Scalar err = Thyra::norm_inf(*absU);
143 Scalar d0 = err_func(stageX, errorRel, errorAbs, scratchX);
144 Scalar d1 = err_func(stageXDot[0], errorRel, errorAbs, scratchX);
147 dt = Teuchos::as<Scalar>(0.01)*(d0/d1);
150 Thyra::Vp_StV(stageX.ptr(), dt, *(stageXDot[0]));
153 inArgs.set_x(stageX);
154 if (inArgs.supports(MEB::IN_ARG_t)) inArgs.set_t(time + dt);
155 if (inArgs.supports(MEB::IN_ARG_x_dot)) inArgs.set_x_dot(Teuchos::null);
156 outArgs.set_f(stageXDot[1]);
157 this->appModel_->evalModel(inArgs, outArgs);
161 Teuchos::RCP<Thyra::VectorBase<Scalar> > errX;
162 errX = Thyra::createMember(this->appModel_->get_f_space());
163 assign(errX.ptr(), Teuchos::ScalarTraits<Scalar>::zero());
164 Thyra::V_VmV(errX.ptr(), *(stageXDot[1]), *(stageXDot[0]));
165 Scalar d2 = err_func(errX, errorRel, errorAbs, scratchX) / dt;
168 Scalar max_d1_d2 = std::max(d1, d2);
169 Scalar h1 = std::pow((0.01/max_d1_d2),(1.0/(order+1)));
172 dt = std::min(100*dt, h1);
177 template<
class Scalar>
179 Teuchos::RCP<Teuchos::ParameterList> pl)
const
182 pl->set<
bool>(
"Use Embedded",
false,
183 "'Whether to use Embedded Stepper (if available) or not\n"
184 " 'true' - Stepper will compute embedded solution and is adaptive.\n"
185 " 'false' - Stepper is not embedded(adaptive).\n");
186 pl->set<std::string>(
"Description", this->getDescription());
190 #ifndef TEMPUS_HIDE_DEPRECATED_CODE
191 template<
class Scalar>
195 if (this->stepperObserver_ == Teuchos::null)
196 this->stepperObserver_ =
199 if (( obs == Teuchos::null ) and (this->stepperObserver_->getSize() >0 ) )
202 if (( obs == Teuchos::null ) and (this->stepperObserver_->getSize() == 0) )
207 this->stepperObserver_->addObserver(
210 Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
211 Teuchos::OSTab ostab(out,0,
"setObserver");
212 *out <<
"Tempus::StepperExplicit_RK::setObserver: Warning: An observer has been provided that";
213 *out <<
" does not support Tempus::StepperRKObserver. This observer WILL NOT be added.";
214 *out <<
" In the future, this will result in a runtime error!" << std::endl;
217 this->isInitialized_ =
false;
222 template<
class Scalar>
225 TEUCHOS_TEST_FOR_EXCEPTION( this->tableau_ == Teuchos::null, std::logic_error,
226 "Error - Need to set the tableau, before calling "
227 "StepperExplicitRK::initialize()\n");
229 TEUCHOS_TEST_FOR_EXCEPTION( this->appModel_==Teuchos::null, std::logic_error,
230 "Error - Need to set the model, setModel(), before calling "
231 "StepperExplicitRK::initialize()\n");
234 int numStages = this->tableau_->numStages();
235 stageXDot_.resize(numStages);
236 for (
int i=0; i<numStages; ++i) {
237 stageXDot_[i] = Thyra::createMember(this->appModel_->get_f_space());
238 assign(stageXDot_[i].ptr(), Teuchos::ScalarTraits<Scalar>::zero());
241 if ( this->tableau_->isEmbedded() and this->getUseEmbedded() ){
242 ee_ = Thyra::createMember(this->appModel_->get_f_space());
243 abs_u0 = Thyra::createMember(this->appModel_->get_f_space());
244 abs_u = Thyra::createMember(this->appModel_->get_f_space());
245 sc = Thyra::createMember(this->appModel_->get_f_space());
252 template<
class Scalar>
258 RCP<SolutionState<Scalar> > initialState = solutionHistory->getCurrentState();
261 if (initialState->getXDot() == Teuchos::null)
262 this->setStepperXDot(stageXDot_.back());
268 template<
class Scalar>
272 this->checkInitialized();
276 TEMPUS_FUNC_TIME_MONITOR(
"Tempus::StepperExplicitRK::takeStep()");
278 TEUCHOS_TEST_FOR_EXCEPTION(solutionHistory->getNumStates() < 2,
280 "Error - StepperExplicitRK<Scalar>::takeStep(...)\n"
281 "Need at least two SolutionStates for ExplicitRK.\n"
282 " Number of States = " << solutionHistory->getNumStates() <<
"\n"
283 "Try setting in \"Solution History\" \"Storage Type\" = \"Undo\"\n"
284 " or \"Storage Type\" = \"Static\" and \"Storage Limit\" = \"2\"\n");
286 #ifndef TEMPUS_HIDE_DEPRECATED_CODE
287 this->stepperObserver_->observeBeginTakeStep(solutionHistory, *
this);
289 RCP<StepperExplicitRK<Scalar> > thisStepper = Teuchos::rcpFromRef(*
this);
290 this->stepperRKAppAction_->execute(solutionHistory, thisStepper,
293 RCP<SolutionState<Scalar> > currentState=solutionHistory->getCurrentState();
294 RCP<SolutionState<Scalar> > workingState=solutionHistory->getWorkingState();
295 const Scalar dt = workingState->getTimeStep();
296 const Scalar time = currentState->getTime();
298 const int numStages = this->tableau_->numStages();
299 Teuchos::SerialDenseMatrix<int,Scalar> A = this->tableau_->A();
300 Teuchos::SerialDenseVector<int,Scalar> b = this->tableau_->b();
301 Teuchos::SerialDenseVector<int,Scalar> c = this->tableau_->c();
303 this->stageX_ = workingState->getX();
304 Thyra::assign(this->stageX_.ptr(), *(currentState->getX()));
307 for (
int i=0; i < numStages; ++i) {
308 this->setStageNumber(i);
309 #ifndef TEMPUS_HIDE_DEPRECATED_CODE
310 this->stepperObserver_->observeBeginStage(solutionHistory, *
this);
313 this->stepperObserver_
314 ->observeBeforeImplicitExplicitly(solutionHistory, *
this);
317 this->stepperObserver_->observeBeforeSolve(solutionHistory, *
this);
319 this->stepperRKAppAction_->execute(solutionHistory, thisStepper,
321 this->stepperRKAppAction_->execute(solutionHistory, thisStepper,
324 if ( i == 0 && this->getUseFSAL() &&
325 workingState->getNConsecutiveFailures() == 0 ) {
327 RCP<Thyra::VectorBase<Scalar> > tmp = stageXDot_[0];
328 stageXDot_[0] = stageXDot_.back();
329 stageXDot_.back() = tmp;
333 Thyra::assign(this->stageX_.ptr(), *(currentState->getX()));
334 for (
int j=0; j < i; ++j) {
335 if (A(i,j) != Teuchos::ScalarTraits<Scalar>::zero()) {
336 Thyra::Vp_StV(this->stageX_.ptr(), dt*A(i,j), *stageXDot_[j]);
339 const Scalar ts = time + c(i)*dt;
341 #ifndef TEMPUS_HIDE_DEPRECATED_CODE
343 this->stepperObserver_->observeAfterSolve(solutionHistory, *
this);
345 this->stepperObserver_->observeBeforeExplicit(solutionHistory, *
this);
347 this->stepperRKAppAction_->execute(solutionHistory, thisStepper,
349 this->stepperRKAppAction_->execute(solutionHistory, thisStepper,
355 this->evaluateExplicitODE(stageXDot_[i], this->stageX_, ts, p);
358 #ifndef TEMPUS_HIDE_DEPRECATED_CODE
359 this->stepperObserver_->observeEndStage(solutionHistory, *
this);
361 this->stepperRKAppAction_->execute(solutionHistory, thisStepper,
366 Thyra::assign((workingState->getX()).ptr(), *(currentState->getX()));
367 for (
int i=0; i < numStages; ++i) {
368 if (b(i) != Teuchos::ScalarTraits<Scalar>::zero()) {
369 Thyra::Vp_StV((workingState->getX()).ptr(), dt*b(i), *(stageXDot_[i]));
379 if (this->tableau_->isEmbedded() and this->getUseEmbedded()) {
381 const Scalar tolRel = workingState->getTolRel();
382 const Scalar tolAbs = workingState->getTolAbs();
386 Teuchos::SerialDenseVector<int,Scalar> errWght = b ;
387 errWght -= this->tableau_->bstar();
391 assign(ee_.ptr(), Teuchos::ScalarTraits<Scalar>::zero());
392 for (
int i=0; i < numStages; ++i) {
393 if (errWght(i) != Teuchos::ScalarTraits<Scalar>::zero()) {
394 Thyra::Vp_StV(ee_.ptr(), dt*errWght(i), *(stageXDot_[i]));
399 Thyra::abs( *(currentState->getX()), abs_u0.ptr());
400 Thyra::abs( *(workingState->getX()), abs_u.ptr());
401 Thyra::pair_wise_max_update(tolRel, *abs_u0, abs_u.ptr());
402 Thyra::add_scalar(tolAbs, abs_u.ptr());
405 assign(sc.ptr(), Teuchos::ScalarTraits<Scalar>::zero());
406 Thyra::ele_wise_divide(Teuchos::as<Scalar>(1.0), *ee_, *abs_u, sc.ptr());
407 Scalar err = std::abs(Thyra::norm_inf(*sc));
408 workingState->setErrorRel(err);
411 if (std::isinf(err) || std::isnan(err) || err > Teuchos::as<Scalar>(1.0))
415 workingState->setOrder(this->getOrder());
416 workingState->computeNorms(currentState);
417 #ifndef TEMPUS_HIDE_DEPRECATED_CODE
418 this->stepperObserver_->observeEndTakeStep(solutionHistory, *
this);
420 this->stepperRKAppAction_->execute(solutionHistory, thisStepper,
424 this->setStageNumber(-1);
435 template<
class Scalar>
439 Teuchos::RCP<Tempus::StepperState<Scalar> > stepperState =
445 template<
class Scalar>
447 Teuchos::FancyOStream &out,
448 const Teuchos::EVerbosityLevel verbLevel)
const
454 out <<
"--- StepperExplicitRK ---\n";
455 if (this->tableau_ != Teuchos::null) this->tableau_->describe(out, verbLevel);
456 out <<
" tableau_ = " << this->tableau_ << std::endl;
457 #ifndef TEMPUS_HIDE_DEPRECATED_CODE
458 out <<
" stepperObserver_ = " << stepperObserver_ << std::endl;
460 out <<
" stepperRKAppAction_= " << this->stepperRKAppAction_ << std::endl;
461 out <<
" stageX_ = " << this->stageX_ << std::endl;
462 out <<
" stageXDot_.size() = " << stageXDot_.size() << std::endl;
463 const int numStages = stageXDot_.size();
464 for (
int i=0; i<numStages; ++i)
465 out <<
" stageXDot_["<<i<<
"] = " << stageXDot_[i] << std::endl;
466 out <<
" useEmbedded_ = "
468 out <<
" ee_ = " << ee_ << std::endl;
469 out <<
" abs_u0 = " << abs_u0 << std::endl;
470 out <<
" abs_u = " << abs_u << std::endl;
471 out <<
" sc = " << sc << std::endl;
472 out <<
"-------------------------" << std::endl;
476 template<
class Scalar>
479 bool isValidSetup =
true;
484 if (this->tableau_ == Teuchos::null) {
485 isValidSetup =
false;
486 out <<
"The tableau is not set!\n";
489 #ifndef TEMPUS_HIDE_DEPRECATED_CODE
490 if (stepperObserver_ == Teuchos::null) {
491 isValidSetup =
false;
492 out <<
"The observer is not set!\n";
495 if (this->stepperRKAppAction_ == Teuchos::null) {
496 isValidSetup =
false;
497 out <<
"The AppAction is not set!\n";
504 template<
class Scalar>
505 Teuchos::RCP<const Teuchos::ParameterList>
508 Teuchos::RCP<Teuchos::ParameterList> pl = Teuchos::parameterList();
509 this->getValidParametersBasicERK(pl);
515 #endif // Tempus_StepperExplicitRK_impl_hpp
virtual void setupDefault()
Default setup for constructor.
const std::string toString(const Status status)
Convert Status to string.
virtual Scalar getInitTimeStep(const Teuchos::RCP< SolutionHistory< Scalar > > &solutionHistory) const
virtual void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const
virtual void initialize()
Initialize after construction and changing input parameters.
virtual bool isValidSetup(Teuchos::FancyOStream &out) const
virtual void setup(const Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > &appModel, const Teuchos::RCP< StepperRKObserverComposite< Scalar > > &obs, bool useFSAL, std::string ICConsistency, bool ICConsistencyCheck, bool useEmbedded)
Setup for constructor.
virtual void setInitialConditions(const Teuchos::RCP< SolutionHistory< Scalar > > &solutionHistory)
Set the initial conditions and make them consistent.
Thyra Base interface for time steppers.
StepperState is a simple class to hold state information about the stepper.
virtual void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const
Application Action for StepperRKBase.
Teuchos::RCP< const Teuchos::ParameterList > getValidParameters() const
virtual void setObserver(Teuchos::RCP< StepperObserver< Scalar > > obs=Teuchos::null)
Set Observer.
virtual void setInitialConditions(const Teuchos::RCP< SolutionHistory< Scalar > > &solutionHistory)
Set the initial conditions, make them consistent, and set needed memory.
virtual void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const
StepperObserver class for Stepper class.
SolutionHistory is basically a container of SolutionStates. SolutionHistory maintains a collection of...
void getValidParametersBasicERK(Teuchos::RCP< Teuchos::ParameterList > pl) const
virtual void takeStep(const Teuchos::RCP< SolutionHistory< Scalar > > &solutionHistory)
Take the specified timestep, dt, and return true if successful.
This observer is a composite observer,.
virtual void initialize()
Initialize during construction and after changing input parameters.
StepperRKObserver class for StepperRK.
virtual Teuchos::RCP< Tempus::StepperState< Scalar > > getDefaultStepperState()
Get a default (initial) StepperState.
Thyra Base interface for implicit time steppers.
void getValidParametersBasic(Teuchos::RCP< Teuchos::ParameterList > pl, std::string stepperType)
Provide basic parameters to Steppers.