9 #ifndef Tempus_StepperExplicit_impl_hpp
10 #define Tempus_StepperExplicit_impl_hpp
16 template<
class Scalar>
18 const Teuchos::RCP<
const Thyra::ModelEvaluator<Scalar> >& appModel)
23 inArgs_ = appModel_->getNominalValues();
24 outArgs_ = appModel_->createOutArgs();
28 template<
class Scalar>
34 int numStates = solutionHistory->getNumStates();
36 TEUCHOS_TEST_FOR_EXCEPTION(numStates < 1, std::logic_error,
37 "Error - setInitialConditions() needs at least one SolutionState\n"
38 " to set the initial condition. Number of States = " << numStates);
41 RCP<Teuchos::FancyOStream> out = this->getOStream();
42 Teuchos::OSTab ostab(out,1,
"StepperExplicit::setInitialConditions()");
43 *out <<
"Warning -- SolutionHistory has more than one state!\n"
44 <<
"Setting the initial conditions on the currentState.\n"<<std::endl;
47 RCP<SolutionState<Scalar> > initialState = solutionHistory->getCurrentState();
48 RCP<Thyra::VectorBase<Scalar> > x = initialState->getX();
50 inArgs_ = appModel_->getNominalValues();
52 RCP<Thyra::VectorBase<Scalar> > xDot = initialState->getXDot();
56 TEUCHOS_TEST_FOR_EXCEPTION(
57 !((x != Teuchos::null && xDot != Teuchos::null) ||
58 (inArgs_.get_x() != Teuchos::null &&
59 inArgs_.get_x_dot() != Teuchos::null)), std::logic_error,
60 "Error - We need to set the initial conditions for x and xDot from\n"
61 " either initialState or appModel_->getNominalValues::InArgs\n"
62 " (but not from a mixture of the two).\n");
66 if (x == Teuchos::null) {
68 TEUCHOS_TEST_FOR_EXCEPTION( (x == Teuchos::null) &&
69 (inArgs_.get_x() == Teuchos::null), std::logic_error,
70 "Error - setInitialConditions needs the ICs from the SolutionHistory\n"
71 " or getNominalValues()!\n");
73 x = Teuchos::rcp_const_cast<Thyra::VectorBase<Scalar> >(inArgs_.get_x());
74 initialState->setX(x);
78 using Teuchos::rcp_const_cast;
80 if ( initialState->getX() == Teuchos::null ||
81 initialState->getXDot() == Teuchos::null ) {
82 TEUCHOS_TEST_FOR_EXCEPTION( (inArgs_.get_x() == Teuchos::null) ||
83 (inArgs_.get_x_dot() == Teuchos::null), std::logic_error,
84 "Error - setInitialConditions() needs the ICs from the initialState\n"
85 " or getNominalValues()!\n");
86 x = rcp_const_cast<Thyra::VectorBase<Scalar> >(inArgs_.get_x());
87 initialState->setX(x);
88 RCP<Thyra::VectorBase<Scalar> > xDot
89 = rcp_const_cast<Thyra::VectorBase<Scalar> >(inArgs_.get_x_dot());
90 initialState->setXDot(xDot);
95 std::string icConsistency = this->getICConsistency();
96 if (icConsistency ==
"None") {
98 if (initialState->getXDot() == Teuchos::null) {
99 RCP<Teuchos::FancyOStream> out = this->getOStream();
100 Teuchos::OSTab ostab(out,1,
"StepperExplicit::setInitialConditions()");
101 *out <<
"Warning -- Requested IC consistency of 'None' but\n"
102 <<
" initialState does not have an xDot.\n"
103 <<
" Setting a 'Consistent' xDot!\n" << std::endl;
105 evaluateExplicitODE(this->getStepperXDot(initialState), x,
106 initialState->getTime(), p);
107 initialState->setIsSynced(
true);
111 if (initialState->getXDotDot() == Teuchos::null) {
112 RCP<Teuchos::FancyOStream> out = this->getOStream();
113 Teuchos::OSTab ostab(out,1,
"StepperExplicit::setInitialConditions()");
114 *out <<
"Warning -- Requested IC consistency of 'None' but\n"
115 <<
" initialState does not have an xDotDot.\n"
116 <<
" Setting a 'Consistent' xDotDot!\n" << std::endl;
118 this->evaluateExplicitODE(this->getStepperXDotDot(initialState), x,
119 initialState->getXDot(),
120 initialState->getTime(), p);
121 initialState->setIsSynced(
true);
125 else if (icConsistency ==
"Zero") {
127 Thyra::assign(this->getStepperXDot(initialState).ptr(), Scalar(0.0));
129 Thyra::assign(this->getStepperXDotDot(initialState).ptr(), Scalar(0.0));
131 else if (icConsistency ==
"App") {
133 auto xDot = Teuchos::rcp_const_cast<Thyra::VectorBase<Scalar> >(
134 inArgs_.get_x_dot());
135 TEUCHOS_TEST_FOR_EXCEPTION(xDot == Teuchos::null, std::logic_error,
136 "Error - setInitialConditions() requested 'App' for IC consistency,\n"
137 " but 'App' returned a null pointer for xDot!\n");
138 Thyra::assign(this->getStepperXDot(initialState).ptr(), *xDot);
141 auto xDotDot = Teuchos::rcp_const_cast<Thyra::VectorBase<Scalar> >(
142 inArgs_.get_x_dot_dot());
143 TEUCHOS_TEST_FOR_EXCEPTION(xDotDot == Teuchos::null, std::logic_error,
144 "Error - setInitialConditions() requested 'App' for IC consistency,\n"
145 " but 'App' returned a null pointer for xDotDot!\n");
146 Thyra::assign(this->getStepperXDotDot(initialState).ptr(), *xDotDot);
149 else if (icConsistency ==
"Consistent") {
153 evaluateExplicitODE(this->getStepperXDot(initialState), x,
154 initialState->getTime(), p);
159 this->evaluateExplicitODE(initialState->getXDotDot(), x,
160 initialState->getXDot(),
161 initialState->getTime(), p);
165 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
166 "Error - setInitialConditions() invalid IC consistency, '"
167 << icConsistency <<
"'.\n");
172 initialState->setIsSynced(
true);
175 if (this->getICConsistencyCheck()) {
177 auto xDot = this->getStepperXDot(initialState);
178 auto f = initialState->getX()->clone_v();
180 evaluateExplicitODE(f, x, initialState->getTime(), p);
181 Thyra::Vp_StV(f.ptr(), Scalar(-1.0), *(xDot));
182 Scalar normX = Thyra::norm(*x);
183 Scalar reldiff = Scalar(0.0);
184 if (normX == Scalar(0.0)) reldiff = Thyra::norm(*f);
185 else reldiff = Thyra::norm(*f)/normX;
187 Scalar eps = Scalar(100.0)*std::abs(Teuchos::ScalarTraits<Scalar>::eps());
189 RCP<Teuchos::FancyOStream> out = this->getOStream();
190 Teuchos::OSTab ostab(out,1,
"StepperExplicit::setInitialConditions()");
191 *out <<
"Warning -- Failed consistency check but continuing!\n"
192 <<
" ||xDot-f(x,t)||/||x|| > eps" << std::endl
193 <<
" ||xDot-f(x,t)|| = " << Thyra::norm(*f) << std::endl
194 <<
" ||x|| = " << Thyra::norm(*x) << std::endl
195 <<
" ||xDot-f(x,t)||/||x|| = " << reldiff << std::endl
196 <<
" eps = " << eps << std::endl;
200 auto xDotDot = initialState->getXDotDot();
201 auto f = initialState->getX()->clone_v();
203 this->evaluateExplicitODE(f, x, initialState->getXDot(),
204 initialState->getTime(), p);
205 Thyra::Vp_StV(f.ptr(), Scalar(-1.0), *(xDotDot));
206 Scalar normX = Thyra::norm(*x);
207 Scalar reldiff = Scalar(0.0);
208 if (normX == Scalar(0.0)) reldiff = Thyra::norm(*f);
209 else reldiff = Thyra::norm(*f)/normX;
211 Scalar eps = Scalar(100.0)*std::abs(Teuchos::ScalarTraits<Scalar>::eps());
213 RCP<Teuchos::FancyOStream> out = this->getOStream();
214 Teuchos::OSTab ostab(out,1,
"StepperExplicit::setInitialConditions()");
215 *out <<
"Warning -- Failed consistency check but continuing!\n"
216 <<
" ||xDotDot-f(x,xDot,t)||/||x|| > eps" << std::endl
217 <<
" ||xDotDot-f(x,xDot,t)|| = " << Thyra::norm(*f)
219 <<
" ||x|| = " << Thyra::norm(*x)
221 <<
" ||xDotDot-f(x,xDot,t)||/||x|| = " << reldiff << std::endl
222 <<
" eps = " << eps << std::endl;
228 template<
class Scalar>
230 Teuchos::RCP<Thyra::NonlinearSolverBase<Scalar> > )
232 Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
233 Teuchos::OSTab ostab(out,1,
"StepperExplicit::setSolver()");
234 *out <<
"Warning -- No solver to set for StepperExplicit "
235 <<
"(i.e., explicit method).\n" << std::endl;
238 template<
class Scalar>
242 Teuchos::RCP<
const Thyra::VectorBase<Scalar> > x,
246 typedef Thyra::ModelEvaluatorBase MEB;
249 if (inArgs_.supports(MEB::IN_ARG_t)) inArgs_.set_t(time);
250 if (inArgs_.supports(MEB::IN_ARG_step_size))
251 inArgs_.set_step_size(p->timeStepSize_);
252 if (inArgs_.supports(MEB::IN_ARG_stage_number))
253 inArgs_.set_stage_number(p->stageNumber_);
260 if (inArgs_.supports(MEB::IN_ARG_x_dot)) inArgs_.set_x_dot(Teuchos::null);
262 outArgs_.set_f(xDot);
264 appModel_->evalModel(inArgs_, outArgs_);
267 template<
class Scalar>
271 Teuchos::RCP<
const Thyra::VectorBase<Scalar> > x,
272 Teuchos::RCP<
const Thyra::VectorBase<Scalar> > xDot,
276 typedef Thyra::ModelEvaluatorBase MEB;
279 if (inArgs_.supports(MEB::IN_ARG_x_dot)) inArgs_.set_x_dot(xDot);
280 if (inArgs_.supports(MEB::IN_ARG_t)) inArgs_.set_t(time);
281 if (inArgs_.supports(MEB::IN_ARG_step_size))
282 inArgs_.set_step_size(p->timeStepSize_);
283 if (inArgs_.supports(MEB::IN_ARG_stage_number))
284 inArgs_.set_stage_number(p->stageNumber_);
291 if (inArgs_.supports(MEB::IN_ARG_x_dot_dot))
292 inArgs_.set_x_dot_dot(Teuchos::null);
294 outArgs_.set_f(xDotDot);
296 appModel_->evalModel(inArgs_, outArgs_);
301 template<
class Scalar>
303 const Teuchos::EVerbosityLevel verbLevel)
const
305 out <<
"--- StepperExplicit ---\n";
306 out <<
" appModel_ = " << appModel_ << std::endl;
307 out <<
" inArgs_ = " << inArgs_ << std::endl;
308 out <<
" outArgs_ = " << outArgs_ << std::endl;
312 template<
class Scalar>
315 bool isValidSetup =
true;
317 if (appModel_ == Teuchos::null) {
318 isValidSetup =
false;
319 out <<
"The application ModelEvaluator is not set!\n";
327 #endif // Tempus_StepperExplicit_impl_hpp
virtual bool isValidSetup(Teuchos::FancyOStream &out) const
void validExplicitODE(const Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > &model)
Validate that the model supports explicit ODE evaluation, f(x,t) [=xdot].
virtual void setSolver(Teuchos::RCP< Thyra::NonlinearSolverBase< Scalar > > solver)
Set solver.
Stepper integrates second-order ODEs.
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
SolutionHistory is basically a container of SolutionStates. SolutionHistory maintains a collection of...
virtual void setModel(const Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > &appModel)
Stepper integrates first-order ODEs.
virtual void evaluateExplicitODE(Teuchos::RCP< Thyra::VectorBase< Scalar > > xDot, Teuchos::RCP< const Thyra::VectorBase< Scalar > > x, const Scalar time, const Teuchos::RCP< ExplicitODEParameters< Scalar > > &p)
Evaluate xDot = f(x,t).