Tempus Version of the Day
Time Integration
Loading...
Searching...
No Matches
Tempus_StepperExplicit_impl.hpp
Go to the documentation of this file.
1//@HEADER
2// *****************************************************************************
3// Tempus: Time Integration and Sensitivity Analysis Package
4//
5// Copyright 2017 NTESS and the Tempus contributors.
6// SPDX-License-Identifier: BSD-3-Clause
7// *****************************************************************************
8//@HEADER
9
10#ifndef Tempus_StepperExplicit_impl_hpp
11#define Tempus_StepperExplicit_impl_hpp
12
13#include "Thyra_VectorStdOps.hpp"
14
15namespace Tempus {
16
17template <class Scalar>
19 const Teuchos::RCP<const Thyra::ModelEvaluator<Scalar> >& appModel)
20{
21 validExplicitODE(appModel);
22 appModel_ = appModel;
23
24 inArgs_ = appModel_->getNominalValues();
25 outArgs_ = appModel_->createOutArgs();
26}
27
28template <class Scalar>
30 const Teuchos::RCP<SolutionHistory<Scalar> >& solutionHistory)
31{
32 using Teuchos::RCP;
33
34 int numStates = solutionHistory->getNumStates();
35
36 TEUCHOS_TEST_FOR_EXCEPTION(
37 numStates < 1, std::logic_error,
38 "Error - setInitialConditions() needs at least one SolutionState\n"
39 " to set the initial condition. Number of States = "
40 << numStates);
41
42 if (numStates > 1) {
43 RCP<Teuchos::FancyOStream> out = this->getOStream();
44 Teuchos::OSTab ostab(out, 1, "StepperExplicit::setInitialConditions()");
45 *out << "Warning -- SolutionHistory has more than one state!\n"
46 << "Setting the initial conditions on the currentState.\n"
47 << std::endl;
48 }
49
50 RCP<SolutionState<Scalar> > initialState = solutionHistory->getCurrentState();
51 RCP<Thyra::VectorBase<Scalar> > x = initialState->getX();
52 RCP<Thyra::VectorBase<Scalar> > xDot = initialState->getXDot();
53 if (xDot == Teuchos::null) xDot = this->getStepperXDot();
54
55 inArgs_ = appModel_->getNominalValues();
56 if (this->getOrderODE() == SECOND_ORDER_ODE) {
57 RCP<Thyra::VectorBase<Scalar> > initialXDot = initialState->getXDot();
58 // If initialState has x and xDot set, treat them as the initial conditions.
59 // Otherwise use the x and xDot from getNominalValues() as the ICs.
60 TEUCHOS_TEST_FOR_EXCEPTION(
61 !((x != Teuchos::null && initialXDot != Teuchos::null) ||
62 (inArgs_.get_x() != Teuchos::null &&
63 inArgs_.get_x_dot() != Teuchos::null)),
64 std::logic_error,
65 "Error - We need to set the initial conditions for x and xDot from\n"
66 " either initialState or appModel_->getNominalValues::InArgs\n"
67 " (but not from a mixture of the two).\n");
68 }
69
70 if (this->getOrderODE() == FIRST_ORDER_ODE) {
71 if (x == Teuchos::null) {
72 // Use x from inArgs as ICs.
73 TEUCHOS_TEST_FOR_EXCEPTION(
74 (x == Teuchos::null) && (inArgs_.get_x() == Teuchos::null),
75 std::logic_error,
76 "Error - setInitialConditions needs the ICs from the "
77 "SolutionHistory\n"
78 " or getNominalValues()!\n");
79
80 x = Teuchos::rcp_const_cast<Thyra::VectorBase<Scalar> >(inArgs_.get_x());
81 initialState->setX(x);
82 }
83 }
84 else if (this->getOrderODE() == SECOND_ORDER_ODE) {
85 using Teuchos::rcp_const_cast;
86 // Use the x and x_dot from getNominalValues() as the ICs.
87 if (initialState->getX() == Teuchos::null ||
88 initialState->getXDot() == Teuchos::null) {
89 TEUCHOS_TEST_FOR_EXCEPTION(
90 (inArgs_.get_x() == Teuchos::null) ||
91 (inArgs_.get_x_dot() == Teuchos::null),
92 std::logic_error,
93 "Error - setInitialConditions() needs the ICs from the initialState\n"
94 " or getNominalValues()!\n");
95 x = rcp_const_cast<Thyra::VectorBase<Scalar> >(inArgs_.get_x());
96 initialState->setX(x);
97 RCP<Thyra::VectorBase<Scalar> > x_dot =
98 rcp_const_cast<Thyra::VectorBase<Scalar> >(inArgs_.get_x_dot());
99 initialState->setXDot(x_dot);
100 }
101 }
102
103 // Perform IC Consistency
104 std::string icConsistency = this->getICConsistency();
105 if (icConsistency == "None") {
106 if (this->getOrderODE() == FIRST_ORDER_ODE) {
107 if (initialState->getXDot() == Teuchos::null) {
108 RCP<Teuchos::FancyOStream> out = this->getOStream();
109 Teuchos::OSTab ostab(out, 1, "StepperExplicit::setInitialConditions()");
110 *out << "Warning -- Requested IC consistency of 'None' but\n"
111 << " initialState does not have an xDot.\n"
112 << " Setting a 'Consistent' xDot!\n"
113 << std::endl;
114 auto p = Teuchos::rcp(new ExplicitODEParameters<Scalar>(0.0));
115 evaluateExplicitODE(xDot, x, initialState->getTime(), p);
116 initialState->setIsSynced(true);
117 }
118 }
119 else if (this->getOrderODE() == SECOND_ORDER_ODE) {
120 if (initialState->getXDotDot() == Teuchos::null) {
121 RCP<Teuchos::FancyOStream> out = this->getOStream();
122 Teuchos::OSTab ostab(out, 1, "StepperExplicit::setInitialConditions()");
123 *out << "Warning -- Requested IC consistency of 'None' but\n"
124 << " initialState does not have an xDotDot.\n"
125 << " Setting a 'Consistent' xDotDot!\n"
126 << std::endl;
127 auto p = Teuchos::rcp(new ExplicitODEParameters<Scalar>(0.0));
128 this->evaluateExplicitODE(this->getStepperXDotDot(initialState), x,
129 initialState->getXDot(),
130 initialState->getTime(), p);
131 initialState->setIsSynced(true);
132 }
133 }
134 }
135 else if (icConsistency == "Zero") {
136 if (this->getOrderODE() == FIRST_ORDER_ODE)
137 Thyra::assign(xDot.ptr(), Scalar(0.0));
138 else if (this->getOrderODE() == SECOND_ORDER_ODE)
139 Thyra::assign(this->getStepperXDotDot(initialState).ptr(), Scalar(0.0));
140 }
141 else if (icConsistency == "App") {
142 if (this->getOrderODE() == FIRST_ORDER_ODE) {
143 auto x_dot = Teuchos::rcp_const_cast<Thyra::VectorBase<Scalar> >(
144 inArgs_.get_x_dot());
145 TEUCHOS_TEST_FOR_EXCEPTION(
146 xDot == Teuchos::null, std::logic_error,
147 "Error - setInitialConditions() requested 'App' for IC consistency,\n"
148 " but 'App' returned a null pointer for xDot!\n");
149 Thyra::assign(xDot.ptr(), *x_dot);
150 }
151 else if (this->getOrderODE() == SECOND_ORDER_ODE) {
152 auto xDotDot = Teuchos::rcp_const_cast<Thyra::VectorBase<Scalar> >(
153 inArgs_.get_x_dot_dot());
154 TEUCHOS_TEST_FOR_EXCEPTION(
155 xDotDot == Teuchos::null, std::logic_error,
156 "Error - setInitialConditions() requested 'App' for IC consistency,\n"
157 " but 'App' returned a null pointer for xDotDot!\n");
158 Thyra::assign(this->getStepperXDotDot(initialState).ptr(), *xDotDot);
159 }
160 }
161 else if (icConsistency == "Consistent") {
162 if (this->getOrderODE() == FIRST_ORDER_ODE) {
163 // Evaluate xDot = f(x,t).
164 auto p = Teuchos::rcp(new ExplicitODEParameters<Scalar>(0.0));
165 evaluateExplicitODE(xDot, x, initialState->getTime(), p);
166 }
167 else if (this->getOrderODE() == SECOND_ORDER_ODE) {
168 // Evaluate xDotDot = f(x,xDot,t).
169 auto p = Teuchos::rcp(new ExplicitODEParameters<Scalar>(0.0));
170 this->evaluateExplicitODE(initialState->getXDotDot(), x,
171 initialState->getXDot(),
172 initialState->getTime(), p);
173 }
174 }
175 else {
176 TEUCHOS_TEST_FOR_EXCEPTION(
177 true, std::logic_error,
178 "Error - setInitialConditions() invalid IC consistency, '"
179 << icConsistency << "'.\n");
180 }
181
182 // At this point, x, and xDot (and xDotDot) sync'ed or consistent
183 // at the same time level for the initialState.
184 initialState->setIsSynced(true);
185
186 // Test for consistency.
187 if (this->getICConsistencyCheck()) {
188 if (this->getOrderODE() == FIRST_ORDER_ODE) {
189 auto f = initialState->getX()->clone_v();
190 auto p = Teuchos::rcp(new ExplicitODEParameters<Scalar>(0.0));
191 evaluateExplicitODE(f, x, initialState->getTime(), p);
192 Thyra::Vp_StV(f.ptr(), Scalar(-1.0), *(xDot));
193 Scalar normX = Thyra::norm(*x);
194 Scalar reldiff = Scalar(0.0);
195 if (normX == Scalar(0.0))
196 reldiff = Thyra::norm(*f);
197 else
198 reldiff = Thyra::norm(*f) / normX;
199
200 Scalar eps =
201 Scalar(100.0) * std::abs(Teuchos::ScalarTraits<Scalar>::eps());
202 RCP<Teuchos::FancyOStream> out = this->getOStream();
203 Teuchos::OSTab ostab(out, 1, "StepperExplicit::setInitialConditions()");
204 if (reldiff < eps) {
205 *out << "\n---------------------------------------------------\n"
206 << "Info -- Stepper = " << this->getStepperType() << "\n"
207 << " Initial condition PASSED consistency check!\n"
208 << " (||xDot-f(x,t)||/||x|| = " << reldiff << ") < "
209 << "(eps = " << eps << ")" << std::endl
210 << "---------------------------------------------------\n"
211 << std::endl;
212 }
213 else {
214 *out << "\n---------------------------------------------------\n"
215 << "Info -- Stepper = " << this->getStepperType() << "\n"
216 << " Initial condition FAILED consistency check but continuing!\n"
217 << " (||xDot-f(x,t)||/||x|| = " << reldiff << ") > "
218 << "(eps = " << eps << ")" << std::endl
219 << " ||xDot-f(x,t)|| = " << Thyra::norm(*f) << std::endl
220 << " ||x|| = " << Thyra::norm(*x) << std::endl
221 << "---------------------------------------------------\n"
222 << std::endl;
223 }
224 }
225 else if (this->getOrderODE() == SECOND_ORDER_ODE) {
226 auto xDotDot = initialState->getXDotDot();
227 auto f = initialState->getX()->clone_v();
228 auto p = Teuchos::rcp(new ExplicitODEParameters<Scalar>(0.0));
229 this->evaluateExplicitODE(f, x, initialState->getXDot(),
230 initialState->getTime(), p);
231 Thyra::Vp_StV(f.ptr(), Scalar(-1.0), *(xDotDot));
232 Scalar normX = Thyra::norm(*x);
233 Scalar reldiff = Scalar(0.0);
234 if (normX == Scalar(0.0))
235 reldiff = Thyra::norm(*f);
236 else
237 reldiff = Thyra::norm(*f) / normX;
238
239 Scalar eps =
240 Scalar(100.0) * std::abs(Teuchos::ScalarTraits<Scalar>::eps());
241 RCP<Teuchos::FancyOStream> out = this->getOStream();
242 Teuchos::OSTab ostab(out, 1, "StepperExplicit::setInitialConditions()");
243 if (reldiff < eps) {
244 *out << "\n---------------------------------------------------\n"
245 << "Info -- Stepper = " << this->getStepperType() << "\n"
246 << " Initial condition PASSED consistency check!\n"
247 << " (||xDotDot-f(x,xDot,t)||/||x|| = " << reldiff << ") > "
248 << "(eps = " << eps << ")" << std::endl
249 << "---------------------------------------------------\n"
250 << std::endl;
251 }
252 else {
253 *out << "\n---------------------------------------------------\n"
254 << "Info -- Stepper = " << this->getStepperType() << "\n"
255 << "Initial condition FAILED consistency check but continuing!\n"
256 << " (||xDotDot-f(x,xDot,t)||/||x|| = " << reldiff << ") > "
257 << "(eps = " << eps << ")" << std::endl
258 << " ||xDotDot-f(x,xDot,t)|| = " << Thyra::norm(*f) << std::endl
259 << " ||x|| = " << Thyra::norm(*x) << std::endl
260 << "---------------------------------------------------\n"
261 << std::endl;
262 }
263 }
264 }
265}
266
267template <class Scalar>
269 Teuchos::RCP<Thyra::NonlinearSolverBase<Scalar> > /* solver */)
270{
271 Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
272 Teuchos::OSTab ostab(out, 1, "StepperExplicit::setSolver()");
273 *out << "Warning -- No solver to set for StepperExplicit "
274 << "(i.e., explicit method).\n"
275 << std::endl;
276 return;
277}
278template <class Scalar>
280 Teuchos::RCP<Thyra::VectorBase<Scalar> > xDot,
281 Teuchos::RCP<const Thyra::VectorBase<Scalar> > x, const Scalar time,
282 const Teuchos::RCP<ExplicitODEParameters<Scalar> >& p)
283{
284 typedef Thyra::ModelEvaluatorBase MEB;
285
286 inArgs_.set_x(x);
287 if (inArgs_.supports(MEB::IN_ARG_t)) inArgs_.set_t(time);
288 if (inArgs_.supports(MEB::IN_ARG_step_size))
289 inArgs_.set_step_size(p->timeStepSize_);
290 if (inArgs_.supports(MEB::IN_ARG_stage_number))
291 inArgs_.set_stage_number(p->stageNumber_);
292
293 // For model evaluators whose state function f(x, xDot, t) describes
294 // an implicit ODE, and which accept an optional xDot input argument,
295 // make sure the latter is set to null in order to request the evaluation
296 // of a state function corresponding to the explicit ODE formulation
297 // xDot = f(x, t).
298 if (inArgs_.supports(MEB::IN_ARG_x_dot)) inArgs_.set_x_dot(Teuchos::null);
299
300 outArgs_.set_f(xDot);
301
302 appModel_->evalModel(inArgs_, outArgs_);
303}
304
305template <class Scalar>
307 Teuchos::RCP<Thyra::VectorBase<Scalar> > xDotDot,
308 Teuchos::RCP<const Thyra::VectorBase<Scalar> > x,
309 Teuchos::RCP<const Thyra::VectorBase<Scalar> > xDot, const Scalar time,
310 const Teuchos::RCP<ExplicitODEParameters<Scalar> >& p)
311{
312 typedef Thyra::ModelEvaluatorBase MEB;
313
314 inArgs_.set_x(x);
315 if (inArgs_.supports(MEB::IN_ARG_x_dot)) inArgs_.set_x_dot(xDot);
316 if (inArgs_.supports(MEB::IN_ARG_t)) inArgs_.set_t(time);
317 if (inArgs_.supports(MEB::IN_ARG_step_size))
318 inArgs_.set_step_size(p->timeStepSize_);
319 if (inArgs_.supports(MEB::IN_ARG_stage_number))
320 inArgs_.set_stage_number(p->stageNumber_);
321
322 // For model evaluators whose state function f(x, xDot, xDotDot, t) describes
323 // an implicit ODE, and which accept an optional xDotDot input argument,
324 // make sure the latter is set to null in order to request the evaluation
325 // of a state function corresponding to the explicit ODE formulation
326 // xDotDot = f(x, xDot, t).
327 if (inArgs_.supports(MEB::IN_ARG_x_dot_dot))
328 inArgs_.set_x_dot_dot(Teuchos::null);
329
330 outArgs_.set_f(xDotDot);
331
332 appModel_->evalModel(inArgs_, outArgs_);
333}
334
335template <class Scalar>
337 Teuchos::FancyOStream& out, const Teuchos::EVerbosityLevel verbLevel) const
338{
339 auto l_out = Teuchos::fancyOStream(out.getOStream());
340 Teuchos::OSTab ostab(*l_out, 2, this->description());
341 l_out->setOutputToRootOnly(0);
342
343 *l_out << "--- StepperExplicit ---\n"
344 << " appModel_ = " << appModel_ << std::endl
345 << " inArgs_ = " << inArgs_ << std::endl
346 << " outArgs_ = " << outArgs_ << std::endl;
347}
348
349template <class Scalar>
350bool StepperExplicit<Scalar>::isValidSetup(Teuchos::FancyOStream& out) const
351{
352 out.setOutputToRootOnly(0);
353 bool isValidSetup = true;
354
355 if (appModel_ == Teuchos::null) {
356 isValidSetup = false;
357 out << "The application ModelEvaluator is not set!\n";
358 }
359
360 return isValidSetup;
361}
362
363template <class Scalar>
365 Teuchos::RCP<Teuchos::ParameterList> pl)
366{
367 if (pl != Teuchos::null) {
368 pl->validateParametersAndSetDefaults(*this->getValidParameters(), 0);
369 this->setStepperValues(pl);
370 }
371}
372
373} // namespace Tempus
374#endif // Tempus_StepperExplicit_impl_hpp
SolutionHistory is basically a container of SolutionStates. SolutionHistory maintains a collection of...
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).
virtual void setInitialConditions(const Teuchos::RCP< SolutionHistory< Scalar > > &solutionHistory)
Set the initial conditions, make them consistent, and set needed memory.
virtual void setModel(const Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > &appModel)
Set model.
void setStepperExplicitValues(Teuchos::RCP< Teuchos::ParameterList > pl)
Set StepperExplicit member data from the ParameterList.
virtual bool isValidSetup(Teuchos::FancyOStream &out) const
virtual void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const
virtual void setSolver(Teuchos::RCP< Thyra::NonlinearSolverBase< Scalar > > solver)
Set solver.
@ SECOND_ORDER_ODE
Stepper integrates second-order ODEs.
@ FIRST_ORDER_ODE
Stepper integrates first-order ODEs.
void validExplicitODE(const Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > &model)
Validate that the model supports explicit ODE evaluation, f(x,t) [=xdot].