9 #ifndef Tempus_StepperExplicitRK_impl_hpp
10 #define Tempus_StepperExplicitRK_impl_hpp
13 #include "Teuchos_VerboseObjectParameterListHelpers.hpp"
14 #include "Thyra_VectorStdOps.hpp"
20 template<
class Scalar>
23 this->setUseFSAL( this->getUseFSALDefault());
24 this->setICConsistency( this->getICConsistencyDefault());
25 this->setICConsistencyCheck( this->getICConsistencyCheckDefault());
26 this->setUseEmbedded( this->getUseEmbeddedDefault());
28 this->stepperObserver_ =
33 template<
class Scalar>
35 const Teuchos::RCP<
const Thyra::ModelEvaluator<Scalar> >& appModel,
38 std::string ICConsistency,
39 bool ICConsistencyCheck,
42 this->setUseFSAL( useFSAL);
43 this->setICConsistency( ICConsistency);
44 this->setICConsistencyCheck( ICConsistencyCheck);
45 this->setUseEmbedded( useEmbedded);
47 this->stepperObserver_ =
49 this->setObserver(obs);
51 if (appModel != Teuchos::null) {
52 this->setModel(appModel);
58 template<
class Scalar>
63 Scalar dt = Scalar(1.0e+99);
64 if (!this->getUseEmbedded())
return dt;
66 Teuchos::RCP<SolutionState<Scalar> > currentState=sh->getCurrentState();
67 Teuchos::RCP<SolutionStateMetaData<Scalar> > metaData = currentState->getMetaData();
68 const int order = metaData->getOrder();
69 const Scalar time = metaData->getTime();
70 const Scalar errorAbs = metaData->getTolRel();
71 const Scalar errorRel = metaData->getTolAbs();
73 Teuchos::RCP<Thyra::VectorBase<Scalar> > stageX, scratchX;
74 stageX = Thyra::createMember(this->appModel_->get_f_space());
75 scratchX = Thyra::createMember(this->appModel_->get_f_space());
76 Thyra::assign(stageX.ptr(), *(currentState->getX()));
78 std::vector<Teuchos::RCP<Thyra::VectorBase<Scalar> > > stageXDot(2);
79 for (
int i=0; i<2; ++i) {
80 stageXDot[i] = Thyra::createMember(this->appModel_->get_f_space());
81 assign(stageXDot[i].ptr(), Teuchos::ScalarTraits<Scalar>::zero());
85 typedef Thyra::ModelEvaluatorBase MEB;
86 MEB::InArgs<Scalar> inArgs = this->appModel_->getNominalValues();
87 MEB::OutArgs<Scalar> outArgs = this->appModel_->createOutArgs();
89 if (inArgs.supports(MEB::IN_ARG_t)) inArgs.set_t(time);
90 if (inArgs.supports(MEB::IN_ARG_x_dot)) inArgs.set_x_dot(Teuchos::null);
91 outArgs.set_f(stageXDot[0]);
92 this->appModel_->evalModel(inArgs, outArgs);
94 auto err_func = [] (Teuchos::RCP<Thyra::VectorBase<Scalar> > U,
95 const Scalar rtol,
const Scalar atol,
96 Teuchos::RCP<Thyra::VectorBase<Scalar> > absU)
99 Thyra::assign(absU.ptr(), *U);
100 Thyra::abs(*U, absU.ptr());
101 Thyra::Vt_S(absU.ptr(), rtol);
102 Thyra::Vp_S(absU.ptr(), atol);
103 Thyra::ele_wise_divide(Teuchos::as<Scalar>(1.0), *U, *absU, absU.ptr());
104 Scalar err = Thyra::norm_inf(*absU);
108 Scalar d0 = err_func(stageX, errorRel, errorAbs, scratchX);
109 Scalar d1 = err_func(stageXDot[0], errorRel, errorAbs, scratchX);
112 dt = Teuchos::as<Scalar>(0.01)*(d0/d1);
115 Thyra::Vp_StV(stageX.ptr(), dt, *(stageXDot[0]));
118 inArgs.set_x(stageX);
119 if (inArgs.supports(MEB::IN_ARG_t)) inArgs.set_t(time + dt);
120 if (inArgs.supports(MEB::IN_ARG_x_dot)) inArgs.set_x_dot(Teuchos::null);
121 outArgs.set_f(stageXDot[1]);
122 this->appModel_->evalModel(inArgs, outArgs);
126 Teuchos::RCP<Thyra::VectorBase<Scalar> > errX;
127 errX = Thyra::createMember(this->appModel_->get_f_space());
128 assign(errX.ptr(), Teuchos::ScalarTraits<Scalar>::zero());
129 Thyra::V_VmV(errX.ptr(), *(stageXDot[1]), *(stageXDot[0]));
130 Scalar d2 = err_func(errX, errorRel, errorAbs, scratchX) / dt;
133 Scalar max_d1_d2 = std::max(d1, d2);
134 Scalar h1 = std::pow((0.01/max_d1_d2),(1.0/(order+1)));
137 dt = std::min(100*dt, h1);
142 template<
class Scalar>
144 Teuchos::RCP<Teuchos::ParameterList> pl)
const
147 pl->set<
bool>(
"Use Embedded",
false,
148 "'Whether to use Embedded Stepper (if available) or not\n"
149 " 'true' - Stepper will compute embedded solution and is adaptive.\n"
150 " 'false' - Stepper is not embedded(adaptive).\n");
151 pl->set<std::string>(
"Description", this->getDescription());
155 template<
class Scalar>
160 if (this->stepperObserver_ == Teuchos::null)
161 this->stepperObserver_ =
164 if (( obs == Teuchos::null ) and (this->stepperObserver_->getSize() >0 ) )
167 if (( obs == Teuchos::null ) and (this->stepperObserver_->getSize() == 0) )
172 this->stepperObserver_->addObserver(
175 Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
176 Teuchos::OSTab ostab(out,0,
"setObserver");
177 *out <<
"Tempus::StepperExplicit_RK::setObserver: Warning: An observer has been provided that";
178 *out <<
" does not support Tempus::StepperRKObserver. This observer WILL NOT be added.";
179 *out <<
" In the future, this will result in a runtime error!" << std::endl;
185 template<
class Scalar>
188 TEUCHOS_TEST_FOR_EXCEPTION( tableau_ == Teuchos::null, std::logic_error,
189 "Error - Need to set the tableau, before calling "
190 "StepperExplicitRK::initialize()\n");
192 TEUCHOS_TEST_FOR_EXCEPTION( this->appModel_==Teuchos::null, std::logic_error,
193 "Error - Need to set the model, setModel(), before calling "
194 "StepperExplicitRK::initialize()\n");
198 TEUCHOS_TEST_FOR_EXCEPTION( this->stepperObserver_->getSize() < 1
200 "Error - Composite Observer is empty!\n");
203 int numStages = tableau_->numStages();
204 stageX_ = Thyra::createMember(this->appModel_->get_f_space());
205 stageXDot_.resize(numStages);
206 for (
int i=0; i<numStages; ++i) {
207 stageXDot_[i] = Thyra::createMember(this->appModel_->get_f_space());
208 assign(stageXDot_[i].ptr(), Teuchos::ScalarTraits<Scalar>::zero());
211 if ( tableau_->isEmbedded() and this->getUseEmbedded() ){
212 ee_ = Thyra::createMember(this->appModel_->get_f_space());
213 abs_u0 = Thyra::createMember(this->appModel_->get_f_space());
214 abs_u = Thyra::createMember(this->appModel_->get_f_space());
215 sc = Thyra::createMember(this->appModel_->get_f_space());
220 template<
class Scalar>
226 RCP<SolutionState<Scalar> > initialState =
solutionHistory->getCurrentState();
229 if (initialState->getXDot() == Teuchos::null)
230 this->setStepperXDot(stageXDot_.back());
236 template<
class Scalar>
242 TEMPUS_FUNC_TIME_MONITOR(
"Tempus::StepperExplicitRK::takeStep()");
246 "Error - StepperExplicitRK<Scalar>::takeStep(...)\n"
247 "Need at least two SolutionStates for ExplicitRK.\n"
249 "Try setting in \"Solution History\" \"Storage Type\" = \"Undo\"\n"
250 " or \"Storage Type\" = \"Static\" and \"Storage Limit\" = \"2\"\n");
253 RCP<SolutionState<Scalar> > currentState=
solutionHistory->getCurrentState();
254 RCP<SolutionState<Scalar> > workingState=
solutionHistory->getWorkingState();
255 const Scalar dt = workingState->getTimeStep();
256 const Scalar time = currentState->getTime();
258 const int numStages = tableau_->numStages();
259 Teuchos::SerialDenseMatrix<int,Scalar> A = tableau_->A();
260 Teuchos::SerialDenseVector<int,Scalar> b = tableau_->b();
261 Teuchos::SerialDenseVector<int,Scalar> c = tableau_->c();
264 for (
int i=0; i < numStages; ++i) {
268 this->stepperObserver_
274 if ( i == 0 && this->getUseFSAL() &&
275 workingState->getNConsecutiveFailures() == 0 ) {
277 RCP<Thyra::VectorBase<Scalar> > tmp = stageXDot_[0];
278 stageXDot_[0] = stageXDot_.back();
279 stageXDot_.back() = tmp;
283 Thyra::assign(stageX_.ptr(), *(currentState->getX()));
284 for (
int j=0; j < i; ++j) {
285 if (A(i,j) != Teuchos::ScalarTraits<Scalar>::zero()) {
286 Thyra::Vp_StV(stageX_.ptr(), dt*A(i,j), *stageXDot_[j]);
289 const Scalar ts = time + c(i)*dt;
298 this->evaluateExplicitODE(stageXDot_[i], stageX_, ts, p);
305 Thyra::assign((workingState->getX()).ptr(), *(currentState->getX()));
306 for (
int i=0; i < numStages; ++i) {
307 if (b(i) != Teuchos::ScalarTraits<Scalar>::zero()) {
308 Thyra::Vp_StV((workingState->getX()).ptr(), dt*b(i), *(stageXDot_[i]));
318 if (tableau_->isEmbedded() and this->getUseEmbedded()) {
320 RCP<SolutionStateMetaData<Scalar> > metaData=workingState->getMetaData();
321 const Scalar tolAbs = metaData->getTolRel();
322 const Scalar tolRel = metaData->getTolAbs();
326 Teuchos::SerialDenseVector<int,Scalar> errWght = b ;
327 errWght -= tableau_->bstar();
331 assign(ee_.ptr(), Teuchos::ScalarTraits<Scalar>::zero());
332 for (
int i=0; i < numStages; ++i) {
333 if (errWght(i) != Teuchos::ScalarTraits<Scalar>::zero()) {
334 Thyra::Vp_StV(ee_.ptr(), dt*errWght(i), *(stageXDot_[i]));
339 Thyra::abs( *(currentState->getX()), abs_u0.ptr());
340 Thyra::abs( *(workingState->getX()), abs_u.ptr());
341 Thyra::pair_wise_max_update(tolRel, *abs_u0, abs_u.ptr());
342 Thyra::add_scalar(tolAbs, abs_u.ptr());
345 assign(sc.ptr(), Teuchos::ScalarTraits<Scalar>::zero());
346 Thyra::ele_wise_divide(Teuchos::as<Scalar>(1.0), *ee_, *abs_u, sc.ptr());
347 Scalar err = std::abs(Thyra::norm_inf(*sc));
348 metaData->setErrorRel(err);
351 if (std::isinf(err) || std::isnan(err) || err > Teuchos::as<Scalar>(1.0))
355 workingState->setOrder(this->getOrder());
368 template<
class Scalar>
372 Teuchos::RCP<Tempus::StepperState<Scalar> > stepperState =
378 template<
class Scalar>
380 Teuchos::FancyOStream &out,
381 const Teuchos::EVerbosityLevel )
const
383 out << this->getStepperType() <<
"::describe:" << std::endl
384 <<
"appModel_ = " << this->appModel_->description() << std::endl;
388 template<
class Scalar>
389 Teuchos::RCP<const Teuchos::ParameterList>
392 Teuchos::RCP<Teuchos::ParameterList> pl = Teuchos::parameterList();
393 this->getValidParametersBasicERK(pl);
399 #endif // Tempus_StepperExplicitRK_impl_hpp
virtual void setupDefault()
Default setup for constructor.
virtual Scalar getInitTimeStep(const Teuchos::RCP< SolutionHistory< Scalar > > &solutionHistory) const
virtual void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) 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.
StepperState is a simple class to hold state information about the stepper.
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.
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...
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.
void getValidParametersBasic(Teuchos::RCP< Teuchos::ParameterList > pl, std::string stepperType)
Provide basic parameters to Steppers.