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>
30 this->setParameterList(Teuchos::null);
34 template<
class Scalar>
36 const Teuchos::RCP<
const Thyra::ModelEvaluator<Scalar> >& appModel,
37 Teuchos::RCP<Teuchos::ParameterList> pList)
39 this->setTableau(pList);
40 this->setParameterList(pList);
42 if (appModel == Teuchos::null) {
46 this->setModel(appModel);
51 template<
class Scalar>
53 const Teuchos::RCP<
const Thyra::ModelEvaluator<Scalar> >& appModel,
54 std::string stepperType)
56 this->setTableau(stepperType);
58 if (appModel == Teuchos::null) {
62 this->setModel(appModel);
67 template<
class Scalar>
69 const Teuchos::RCP<
const Thyra::ModelEvaluator<Scalar> >& appModel,
70 std::string stepperType,
71 Teuchos::RCP<Teuchos::ParameterList> pList)
73 this->setTableau(stepperType);
74 this->setParameterList(pList);
76 if (appModel == Teuchos::null) {
80 this->setModel(appModel);
86 template<
class Scalar>
89 if (stepperType ==
"") {
92 Teuchos::RCP<const RKButcherTableau<Scalar> > DIRK_ButcherTableau =
93 createRKBT<Scalar>(stepperType, this->stepperPL_);
94 this->setTableau(DIRK_ButcherTableau);
99 template<
class Scalar>
102 if (pList == Teuchos::null) {
104 if (this->stepperPL_ == Teuchos::null)
105 this->stepperPL_ = this->getDefaultParameters();
107 this->stepperPL_ = pList;
110 std::string stepperType =
111 this->stepperPL_->template get<std::string>(
"Stepper Type",
112 "SDIRK 2 Stage 2nd order");
113 Teuchos::RCP<const RKButcherTableau<Scalar> > DIRK_ButcherTableau =
114 createRKBT<Scalar>(stepperType, this->stepperPL_);
115 this->setTableau(DIRK_ButcherTableau);
119 template<
class Scalar>
123 DIRK_ButcherTableau_ = DIRK_ButcherTableau;
125 TEUCHOS_TEST_FOR_EXCEPTION(DIRK_ButcherTableau_->isDIRK() !=
true,
127 "Error - StepperDIRK do not received a DIRK Butcher Tableau!\n" <<
128 " Tableau = " << DIRK_ButcherTableau_->description() <<
"\n");
132 template<
class Scalar>
136 if (obs == Teuchos::null) {
138 if (this->stepperObserver_ == Teuchos::null) {
139 stepperDIRKObserver_ =
141 this->stepperObserver_ =
143 (stepperDIRKObserver_);
146 this->stepperObserver_ = obs;
147 stepperDIRKObserver_ =
153 template<
class Scalar>
156 TEUCHOS_TEST_FOR_EXCEPTION( this->wrapperModel_ == Teuchos::null,
158 "Error - Need to set the model, setModel(), before calling "
159 "StepperDIRK::initialize()\n");
161 this->setTableau(this->stepperPL_);
162 this->setParameterList(this->stepperPL_);
167 const int numStages = DIRK_ButcherTableau_->numStages();
168 stageX_ = this->wrapperModel_->getNominalValues().get_x()->clone_v();
169 stageXDot_.resize(numStages);
170 for (
int i=0; i<numStages; ++i) {
171 stageXDot_[i] = Thyra::createMember(this->wrapperModel_->get_f_space());
172 assign(stageXDot_[i].ptr(), Teuchos::ScalarTraits<Scalar>::zero());
174 xTilde_ = Thyra::createMember(this->wrapperModel_->get_x_space());
175 assign(xTilde_.ptr(), Teuchos::ScalarTraits<Scalar>::zero());
177 if (DIRK_ButcherTableau_->isEmbedded() and this->getEmbedded()) {
178 ee_ = Thyra::createMember(this->wrapperModel_->get_f_space());
179 abs_u0 = Thyra::createMember(this->wrapperModel_->get_f_space());
180 abs_u = Thyra::createMember(this->wrapperModel_->get_f_space());
181 sc = Thyra::createMember(this->wrapperModel_->get_f_space());
186 template<
class Scalar>
192 RCP<SolutionState<Scalar> > initialState =
solutionHistory->getCurrentState();
195 if (initialState->getXDot() == Teuchos::null)
196 this->setStepperXDot(stageXDot_.back());
202 template<
class Scalar>
208 TEMPUS_FUNC_TIME_MONITOR(
"Tempus::StepperDIRK::takeStep()");
212 "Error - StepperDIRK<Scalar>::takeStep(...)\n"
213 "Need at least two SolutionStates for DIRK.\n"
215 "Try setting in \"Solution History\" \"Storage Type\" = \"Undo\"\n"
216 " or \"Storage Type\" = \"Static\" and \"Storage Limit\" = \"2\"\n");
219 RCP<SolutionState<Scalar> > currentState=
solutionHistory->getCurrentState();
220 RCP<SolutionState<Scalar> > workingState=
solutionHistory->getWorkingState();
221 const Scalar dt = workingState->getTimeStep();
222 const Scalar time = currentState->getTime();
224 const int numStages = DIRK_ButcherTableau_->numStages();
225 Teuchos::SerialDenseMatrix<int,Scalar> A = DIRK_ButcherTableau_->A();
226 Teuchos::SerialDenseVector<int,Scalar> b = DIRK_ButcherTableau_->b();
227 Teuchos::SerialDenseVector<int,Scalar> c = DIRK_ButcherTableau_->c();
231 Thyra::SolveStatus<Scalar> sStatus;
232 for (
int i=0; i < numStages; ++i) {
233 if (!Teuchos::is_null(stepperDIRKObserver_))
236 if ( i == 0 && this->getUseFSAL() &&
237 workingState->getNConsecutiveFailures() == 0 ) {
239 RCP<Thyra::VectorBase<Scalar> > tmp = stageXDot_[0];
240 stageXDot_[0] = stageXDot_.back();
241 stageXDot_.back() = tmp;
245 Thyra::assign(xTilde_.ptr(), *(currentState->getX()));
246 for (
int j=0; j < i; ++j) {
247 if (A(i,j) != Teuchos::ScalarTraits<Scalar>::zero()) {
248 Thyra::Vp_StV(xTilde_.ptr(), dt*A(i,j), *(stageXDot_[j]));
252 Scalar ts = time + c(i)*dt;
253 if (A(i,i) == Teuchos::ScalarTraits<Scalar>::zero()) {
255 bool isNeeded =
false;
256 for (
int k=i+1; k<numStages; ++k)
if (A(k,i) != 0.0) isNeeded =
true;
257 if (b(i) != 0.0) isNeeded =
true;
258 if (isNeeded ==
false) {
260 assign(stageXDot_[i].ptr(), Teuchos::ScalarTraits<Scalar>::zero());
262 typedef Thyra::ModelEvaluatorBase MEB;
263 MEB::InArgs<Scalar> inArgs = this->wrapperModel_->getInArgs();
264 MEB::OutArgs<Scalar> outArgs = this->wrapperModel_->getOutArgs();
265 inArgs.set_x(xTilde_);
266 if (inArgs.supports(MEB::IN_ARG_t)) inArgs.set_t(ts);
267 if (inArgs.supports(MEB::IN_ARG_x_dot))
268 inArgs.set_x_dot(Teuchos::null);
269 outArgs.set_f(stageXDot_[i]);
271 if (!Teuchos::is_null(stepperDIRKObserver_))
273 this->wrapperModel_->getAppModel()->evalModel(inArgs,outArgs);
277 const Scalar alpha = 1.0/(dt*A(i,i));
278 const Scalar beta = 1.0;
281 Teuchos::RCP<TimeDerivative<Scalar> > timeDer =
283 alpha,xTilde_.getConst()));
285 Teuchos::RCP<ImplicitODEParameters<Scalar> > p =
287 timeDer, dt, alpha, beta));
290 if (!Teuchos::is_null(stepperDIRKObserver_))
293 sStatus = this->solveImplicitODE(stageX_, stageXDot_[i], ts, p);
295 if (sStatus.solveStatus != Thyra::SOLVE_STATUS_CONVERGED) pass=
false;
297 if (!Teuchos::is_null(stepperDIRKObserver_))
300 timeDer->compute(stageX_, stageXDot_[i]);
304 if (!Teuchos::is_null(stepperDIRKObserver_))
309 Thyra::assign((workingState->getX()).ptr(), *(currentState->getX()));
310 for (
int i=0; i < numStages; ++i) {
311 if (b(i) != Teuchos::ScalarTraits<Scalar>::zero()) {
312 Thyra::Vp_StV((workingState->getX()).ptr(), dt*b(i), *(stageXDot_[i]));
316 if (DIRK_ButcherTableau_->isEmbedded() and this->getEmbedded()) {
317 RCP<SolutionStateMetaData<Scalar> > metaData=workingState->getMetaData();
318 const Scalar tolAbs = metaData->getTolRel();
319 const Scalar tolRel = metaData->getTolAbs();
323 Teuchos::SerialDenseVector<int,Scalar> errWght = b ;
324 errWght -= DIRK_ButcherTableau_->bstar();
328 assign(ee_.ptr(), Teuchos::ScalarTraits<Scalar>::zero());
329 for (
int i=0; i < numStages; ++i) {
330 if (errWght(i) != Teuchos::ScalarTraits<Scalar>::zero()) {
331 Thyra::Vp_StV(ee_.ptr(), dt*errWght(i), *(stageXDot_[i]));
336 Thyra::abs( *(currentState->getX()), abs_u0.ptr());
337 Thyra::abs( *(workingState->getX()), abs_u.ptr());
338 Thyra::pair_wise_max_update(tolRel, *abs_u0, abs_u.ptr());
339 Thyra::add_scalar(tolAbs, abs_u.ptr());
342 assign(sc.ptr(), Teuchos::ScalarTraits<Scalar>::zero());
343 Thyra::ele_wise_divide(Teuchos::as<Scalar>(1.0), *ee_, *abs_u, sc.ptr());
344 Scalar err = std::abs(Thyra::norm_inf(*sc));
345 metaData->setErrorRel(err);
348 if (std::isinf(err) || std::isnan(err) || err > Teuchos::as<Scalar>(1.0))
355 workingState->setOrder(this->getOrder());
367 template<
class Scalar>
368 Teuchos::RCP<Tempus::StepperState<Scalar> >
372 Teuchos::RCP<Tempus::StepperState<Scalar> > stepperState =
378 template<
class Scalar>
381 return(DIRK_ButcherTableau_->description());
385 template<
class Scalar>
387 Teuchos::FancyOStream &out,
388 const Teuchos::EVerbosityLevel )
const
390 out << description() <<
"::describe:" << std::endl
391 <<
"wrapperModel_ = " << this->wrapperModel_->description() << std::endl;
395 template <
class Scalar>
397 const Teuchos::RCP<Teuchos::ParameterList> & pList)
399 if (pList == Teuchos::null) {
401 if (this->stepperPL_ == Teuchos::null) this->stepperPL_ = this->getDefaultParameters();
403 this->stepperPL_ = pList;
410 template<
class Scalar>
411 Teuchos::RCP<const Teuchos::ParameterList>
414 Teuchos::RCP<Teuchos::ParameterList> pl = Teuchos::parameterList();
415 if (DIRK_ButcherTableau_ == Teuchos::null) {
416 auto DIRK_ButcherTableau =
417 createRKBT<Scalar>(
"SDIRK 2 Stage 2nd order", Teuchos::null);
418 pl->setParameters(*(DIRK_ButcherTableau->getValidParameters()));
420 pl->setParameters(*(DIRK_ButcherTableau_->getValidParameters()));
423 this->getValidParametersBasic(pl);
424 pl->set<
bool>(
"Initial Condition Consistency Check",
false);
425 pl->set<
bool>(
"Zero Initial Guess",
false);
429 template <
class Scalar>
430 Teuchos::RCP<Teuchos::ParameterList>
434 using Teuchos::ParameterList;
435 using Teuchos::rcp_const_cast;
437 RCP<ParameterList> pl =
438 rcp_const_cast<ParameterList>(this->getValidParameters());
440 pl->set<std::string>(
"Solver Name",
"Default Solver");
441 RCP<ParameterList> solverPL = this->defaultSolverParameters();
442 pl->set(
"Default Solver", *solverPL);
447 template <
class Scalar>
448 Teuchos::RCP<Teuchos::ParameterList>
451 return(this->stepperPL_);
455 template <
class Scalar>
456 Teuchos::RCP<Teuchos::ParameterList>
459 Teuchos::RCP<Teuchos::ParameterList> temp_plist = this->stepperPL_;
460 this->stepperPL_ = Teuchos::null;
466 #endif // Tempus_StepperDIRK_impl_hpp
virtual void setInitialConditions(const Teuchos::RCP< SolutionHistory< Scalar > > &solutionHistory)
Set the initial conditions and make them consistent.
virtual void setTableau(std::string stepperType)
StepperDIRKObserver class for StepperDIRK.
virtual Teuchos::RCP< Tempus::StepperState< Scalar > > getDefaultStepperState()
Get a default (initial) StepperState.
Teuchos::RCP< Teuchos::ParameterList > unsetParameterList()
StepperDIRK()
Default constructor.
StepperState is a simple class to hold state information about the stepper.
virtual void setInitialConditions(const Teuchos::RCP< SolutionHistory< Scalar > > &solutionHistory)
Set the initial conditions and make them consistent.
virtual void initialize()
Initialize during construction and after changing input parameters.
Time-derivative interface for DIRK.
virtual std::string description() const
StepperObserver class for Stepper class.
Teuchos::RCP< SolutionHistory< Scalar > > solutionHistory(Teuchos::RCP< Teuchos::ParameterList > pList=Teuchos::null)
Nonmember constructor.
Teuchos::RCP< Teuchos::ParameterList > getNonconstParameterList()
SolutionHistory is basically a container of SolutionStates. SolutionHistory maintains a collection of...
void setParameterList(const Teuchos::RCP< Teuchos::ParameterList > &pl)
Teuchos::RCP< const Teuchos::ParameterList > getValidParameters() const
virtual void setObserver(Teuchos::RCP< StepperObserver< Scalar > > obs=Teuchos::null)
Set Observer.
virtual void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const
Teuchos::RCP< Teuchos::ParameterList > getDefaultParameters() const
virtual void takeStep(const Teuchos::RCP< SolutionHistory< Scalar > > &solutionHistory)
Take the specified timestep, dt, and return true if successful.