29 #ifndef Rythmos_ExplicitRK_STEPPER_DEF_H
30 #define Rythmos_ExplicitRK_STEPPER_DEF_H
32 #include "Rythmos_ExplicitRKStepper_decl.hpp"
34 #include "Rythmos_RKButcherTableau.hpp"
35 #include "Rythmos_RKButcherTableauHelpers.hpp"
36 #include "Rythmos_RKButcherTableauBuilder.hpp"
37 #include "Rythmos_StepperHelpers.hpp"
38 #include "Rythmos_LinearInterpolator.hpp"
39 #include "Rythmos_InterpolatorBaseHelpers.hpp"
41 #include "Teuchos_VerboseObjectParameterListHelpers.hpp"
43 #include "Thyra_ModelEvaluatorHelpers.hpp"
44 #include "Thyra_MultiVectorStdOps.hpp"
45 #include "Thyra_VectorStdOps.hpp"
51 template<
class Scalar>
52 RCP<ExplicitRKStepper<Scalar> > explicitRKStepper()
54 RCP<ExplicitRKStepper<Scalar> > stepper = rcp(
new ExplicitRKStepper<Scalar>());
58 template<
class Scalar>
59 RCP<ExplicitRKStepper<Scalar> > explicitRKStepper(
60 const Teuchos::RCP<Thyra::ModelEvaluator<Scalar> >& model
63 RCP<RKButcherTableauBase<Scalar> > rkbt = createRKBT<Scalar>(
"Explicit 4 Stage");
65 RCP<ExplicitRKStepper<Scalar> > stepper = rcp(
new ExplicitRKStepper<Scalar>());
66 stepper->setModel(model);
67 stepper->setRKButcherTableau(rkbt);
71 template<
class Scalar>
72 RCP<ExplicitRKStepper<Scalar> > explicitRKStepper(
73 const Teuchos::RCP<Thyra::ModelEvaluator<Scalar> >& model,
74 const RCP<
const RKButcherTableauBase<Scalar> >& rkbt
77 RCP<ExplicitRKStepper<Scalar> > stepper = rcp(
new ExplicitRKStepper<Scalar>());
78 stepper->setModel(model);
79 stepper->setRKButcherTableau(rkbt);
83 template<
class Scalar>
86 this->defaultInitializeAll_();
87 Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream();
89 erkButcherTableau_ = rKButcherTableau<Scalar>();
93 template<
class Scalar>
96 model_ = Teuchos::null;
97 solution_vector_ = Teuchos::null;
98 solution_vector_old_ = Teuchos::null;
100 ktemp_vector_ = Teuchos::null;
102 erkButcherTableau_ = Teuchos::null;
107 parameterList_ = Teuchos::null;
108 isInitialized_ =
false;
109 haveInitialCondition_ =
false;
112 template<
class Scalar>
115 TEUCHOS_ASSERT( !is_null(rkbt) );
116 validateERKButcherTableau(*rkbt);
117 int numStages_old = erkButcherTableau_->numStages();
118 int numStages_new = rkbt->numStages();
119 TEUCHOS_TEST_FOR_EXCEPTION( numStages_new == 0, std::logic_error,
120 "Error! The Runge-Kutta Butcher tableau has no stages!"
122 if (!is_null(model_)) {
123 int numNewStages = numStages_new - numStages_old;
124 if ( numNewStages > 0 ) {
125 k_vector_.reserve(numStages_new);
126 for (
int i=0 ; i<numNewStages ; ++i) {
127 k_vector_.push_back(Thyra::createMember(model_->get_f_space()));
131 erkButcherTableau_ = rkbt;
134 template<
class Scalar>
137 return erkButcherTableau_;
140 template<
class Scalar>
143 if (!isInitialized_) {
144 TEUCHOS_ASSERT( !is_null(model_) );
145 TEUCHOS_ASSERT( !is_null(erkButcherTableau_) );
146 TEUCHOS_ASSERT( haveInitialCondition_ );
147 TEUCHOS_TEST_FOR_EXCEPTION( erkButcherTableau_->numStages() == 0, std::logic_error,
148 "Error! The Runge-Kutta Butcher tableau has no stages!"
150 ktemp_vector_ = Thyra::createMember(model_->get_f_space());
152 int numStages = erkButcherTableau_->numStages();
153 k_vector_.reserve(numStages);
154 for (
int i=0 ; i<numStages ; ++i) {
155 k_vector_.push_back(Thyra::createMember(model_->get_f_space()));
158 #ifdef HAVE_RYTHMOS_DEBUG
159 THYRA_ASSERT_VEC_SPACES(
160 "Rythmos::ExplicitRKStepper::initialize_(...)",
161 *solution_vector_->space(), *model_->get_x_space() );
162 #endif // HAVE_RYTHMOS_DEBUG
163 isInitialized_ =
true;
167 template<
class Scalar>
172 template<
class Scalar>
175 TEUCHOS_ASSERT( !is_null(model_) );
176 return(model_->get_x_space());
179 template<
class Scalar>
183 RCP<FancyOStream> out = this->getOStream();
184 Teuchos::EVerbosityLevel verbLevel = this->getVerbLevel();
185 Teuchos::OSTab ostab(out,1,
"takeStep");
186 Scalar stepSizeTaken;
192 if ( !is_null(out) && as<int>(verbLevel) >= as<int>(Teuchos::VERB_LOW) ) {
195 << Teuchos::TypeNameTraits<ExplicitRKStepper<Scalar> >::name()
196 <<
"::takeStep("<<dt<<
","<<toString(stepSizeType)<<
") ...\n";
200 if (stepSizeType == STEP_TYPE_FIXED) {
201 stepSizeTaken = takeFixedStep_(dt , stepSizeType);
202 return stepSizeTaken;
204 isVariableStep_ =
true;
206 stepControl_->setOStream(out);
207 stepControl_->setVerbLevel(verbLevel);
209 rkNewtonConvergenceStatus_ = -1;
211 while (rkNewtonConvergenceStatus_ < 0){
213 stepControl_->setRequestedStepSize(*
this, dt, stepSizeType);
214 stepControl_->nextStepSize(*
this, &dt, &stepSizeType, &desiredOrder);
216 stepSizeTaken = takeVariableStep_(dt, stepSizeType);
219 return stepSizeTaken;
226 template<
class Scalar>
229 typedef typename Thyra::ModelEvaluatorBase::InArgs<Scalar>::ScalarMag TScalarMag;
233 V_V(solution_vector_old_.ptr(), *solution_vector_);
235 Scalar current_dt = dt;
236 Scalar t = timeRange_.upper();
238 AttemptedStepStatusFlag status;
243 int stages = erkButcherTableau_->numStages();
244 Teuchos::SerialDenseMatrix<int,Scalar> A = erkButcherTableau_->A();
245 Teuchos::SerialDenseVector<int,Scalar> b = erkButcherTableau_->b();
246 Teuchos::SerialDenseVector<int,Scalar> c = erkButcherTableau_->c();
250 for (
int s=0 ; s < stages ; ++s) {
251 Thyra::assign(ktemp_vector_.ptr(), *solution_vector_);
252 for (
int j=0 ; j < s ; ++j) {
253 if (A(s,j) != ST::zero()) {
254 Thyra::Vp_StV(ktemp_vector_.ptr(), A(s,j), *k_vector_[j]);
257 TScalarMag ts = t_ + c(s)*dt;
258 TScalarMag scaled_dt = (s == 0)? Scalar(dt/stages) : c(s)*dt;
262 eval_model_explicit<Scalar>(*model_,basePoint_,*ktemp_vector_,ts,Teuchos::outArg(*k_vector_[s]), scaled_dt, c(s));
263 Thyra::Vt_S(k_vector_[s].ptr(),dt);
266 for (
int s=0 ; s < stages ; ++s) {
267 if (b(s) != ST::zero()) {
268 Thyra::Vp_StV(solution_vector_.ptr(), b(s), *k_vector_[s]);
273 rkNewtonConvergenceStatus_ = 0;
274 stepControl_->setCorrection(*
this, solution_vector_, Teuchos::null , rkNewtonConvergenceStatus_);
275 bool stepPass = stepControl_->acceptStep(*
this, &LETvalue_);
277 if (erkButcherTableau_->isEmbeddedMethod() ){
279 Teuchos::SerialDenseVector<int,Scalar> bhat = erkButcherTableau_->bhat();
282 for (
int s=0 ; s < stages ; ++s) {
283 if (bhat(s) != ST::zero()) {
286 Thyra::Vp_StV(solution_hat_vector_.ptr(), bhat(s), *k_vector_[s]);
291 Thyra::V_VmV(ee_.ptr(), *solution_vector_, *solution_hat_vector_);
293 stepControl_->setCorrection(*
this, solution_vector_, ee_ , rkNewtonConvergenceStatus_);
296 stepControl_->setCorrection(*
this, solution_vector_, Teuchos::null, rkNewtonConvergenceStatus_);
299 stepPass = stepControl_->acceptStep(*
this, &LETvalue_);
302 stepLETStatus_ = STEP_LET_STATUS_FAILED;
303 rkNewtonConvergenceStatus_ = -1;
305 stepLETStatus_ = STEP_LET_STATUS_PASSED;
306 rkNewtonConvergenceStatus_ = 0;
309 if (rkNewtonConvergenceStatus_ == 0) {
312 timeRange_ = timeRange(t,t+current_dt);
316 stepControl_->completeStep(*
this);
318 dt_to_return = current_dt;
322 rkNewtonConvergenceStatus_ = -1;
323 status = stepControl_-> rejectStep(*
this);
325 dt_to_return = dt_old;
331 return( dt_to_return );
335 template<
class Scalar>
336 Scalar ExplicitRKStepper<Scalar>::takeFixedStep_(Scalar dt, StepSizeType flag)
338 typedef typename Thyra::ModelEvaluatorBase::InArgs<Scalar>::ScalarMag TScalarMag;
340 #ifdef HAVE_RYTHMOS_DEBUG
341 TEUCHOS_TEST_FOR_EXCEPTION( flag == STEP_TYPE_VARIABLE, std::logic_error,
342 "Error! ExplicitRKStepper does not support variable time steps at this time."
344 #endif // HAVE_RYTHMOS_DEBUG
345 if ((flag == STEP_TYPE_VARIABLE) || (dt == ST::zero())) {
346 return(Scalar(-ST::one()));
349 V_V(solution_vector_old_.ptr(), *solution_vector_);
354 int stages = erkButcherTableau_->numStages();
355 Teuchos::SerialDenseMatrix<int,Scalar> A = erkButcherTableau_->A();
356 Teuchos::SerialDenseVector<int,Scalar> b = erkButcherTableau_->b();
357 Teuchos::SerialDenseVector<int,Scalar> c = erkButcherTableau_->c();
359 for (
int s=0 ; s < stages ; ++s) {
360 Thyra::assign(ktemp_vector_.ptr(), *solution_vector_);
361 for (
int j=0 ; j < s ; ++j) {
362 if (A(s,j) != ST::zero()) {
363 Thyra::Vp_StV(ktemp_vector_.ptr(), A(s,j), *k_vector_[j]);
366 TScalarMag ts = t_ + c(s)*dt;
367 TScalarMag scaled_dt = (s == 0)? Scalar(dt/stages) : c(s)*dt;
369 eval_model_explicit<Scalar>(*model_,basePoint_,*ktemp_vector_,ts,Teuchos::outArg(*k_vector_[s]), scaled_dt, c(s));
370 Thyra::Vt_S(k_vector_[s].ptr(),dt);
373 for (
int s=0 ; s < stages ; ++s) {
374 if (b(s) != ST::zero()) {
375 Thyra::Vp_StV(solution_vector_.ptr(), b(s), *k_vector_[s]);
387 template<
class Scalar>
392 if (!haveInitialCondition_) {
393 stepStatus.
stepStatus = STEP_STATUS_UNINITIALIZED;
394 }
else if (numSteps_ == 0) {
396 stepStatus.
order = erkButcherTableau_->order();
397 stepStatus.
time = t_;
398 stepStatus.
solution = solution_vector_;
400 stepStatus.
stepStatus = STEP_STATUS_CONVERGED;
402 stepStatus.
order = erkButcherTableau_->order();
403 stepStatus.
time = t_;
404 stepStatus.
solution = solution_vector_;
410 template<
class Scalar>
412 Teuchos::FancyOStream &out,
413 const Teuchos::EVerbosityLevel verbLevel
416 if ( (static_cast<int>(verbLevel) == static_cast<int>(Teuchos::VERB_DEFAULT) ) ||
417 (static_cast<int>(verbLevel) >= static_cast<int>(Teuchos::VERB_LOW) )
419 out << this->description() <<
"::describe" << std::endl;
420 out <<
"model = " << model_->description() << std::endl;
421 out << erkButcherTableau_->numStages() <<
" stage Explicit RK method" << std::endl;
422 }
else if (static_cast<int>(verbLevel) >= static_cast<int>(Teuchos::VERB_LOW)) {
423 out <<
"solution_vector = " << std::endl;
424 out << Teuchos::describe(*solution_vector_,verbLevel);
425 }
else if (static_cast<int>(verbLevel) >= static_cast<int>(Teuchos::VERB_MEDIUM)) {
426 }
else if (static_cast<int>(verbLevel) >= static_cast<int>(Teuchos::VERB_HIGH)) {
427 out <<
"model = " << std::endl;
428 out << Teuchos::describe(*model_,verbLevel);
429 int stages = erkButcherTableau_->numStages();
430 for (
int i=0 ; i<stages ; ++i) {
431 out <<
"k_vector[" << i <<
"] = " << std::endl;
432 out << Teuchos::describe(*k_vector_[i],verbLevel);
434 out <<
"ktemp_vector = " << std::endl;
435 out << Teuchos::describe(*ktemp_vector_,verbLevel);
436 out <<
"ERK Butcher Tableau A matrix: " << erkButcherTableau_->A() << std::endl;
437 out <<
"ERK Butcher Tableau b vector: " << erkButcherTableau_->b() << std::endl;
438 out <<
"ERK Butcher Tableau c vector: " << erkButcherTableau_->c() << std::endl;
439 out <<
"t = " << t_ << std::endl;
443 template<
class Scalar>
446 ,
const Array<Teuchos::RCP<
const Thyra::VectorBase<Scalar> > >&
447 ,
const Array<Teuchos::RCP<
const Thyra::VectorBase<Scalar> > >&
450 TEUCHOS_TEST_FOR_EXCEPTION(
true,std::logic_error,
"Error, addPoints is not implemented for ExplicitRKStepper at this time.\n");
453 template<
class Scalar>
456 if (!haveInitialCondition_) {
457 return(invalidTimeRange<Scalar>());
463 template<
class Scalar>
465 const Array<Scalar>& time_vec,
466 Array<RCP<
const Thyra::VectorBase<Scalar> > >* x_vec,
467 Array<RCP<
const Thyra::VectorBase<Scalar> > >* xdot_vec,
468 Array<ScalarMag>* accuracy_vec
471 TEUCHOS_ASSERT( haveInitialCondition_ );
472 using Teuchos::constOptInArg;
474 defaultGetPoints<Scalar>(
475 t_old_, constOptInArg(*solution_vector_old_),
476 Ptr<const VectorBase<Scalar> >(null),
477 t_, constOptInArg(*solution_vector_),
478 Ptr<const VectorBase<Scalar> >(null),
479 time_vec,ptr(x_vec), ptr(xdot_vec), ptr(accuracy_vec),
480 Ptr<InterpolatorBase<Scalar> >(null)
484 template<
class Scalar>
487 TEUCHOS_ASSERT( time_vec != NULL );
489 if (!haveInitialCondition_) {
492 time_vec->push_back(t_old_);
494 time_vec->push_back(t_);
498 template<
class Scalar>
501 TEUCHOS_TEST_FOR_EXCEPTION(
true,std::logic_error,
"Error, removeNodes is not implemented for ExplicitRKStepper at this time.\n");
504 template<
class Scalar>
507 return(erkButcherTableau_->order());
510 template <
class Scalar>
513 TEUCHOS_TEST_FOR_EXCEPT(is_null(paramList));
514 paramList->validateParametersAndSetDefaults(*this->getValidParameters());
515 parameterList_ = paramList;
516 Teuchos::readVerboseObjectSublist(&*parameterList_,
this);
519 template <
class Scalar>
522 return(parameterList_);
525 template <
class Scalar>
528 Teuchos::RCP<Teuchos::ParameterList> temp_param_list = parameterList_;
529 parameterList_ = Teuchos::null;
530 return(temp_param_list);
533 template<
class Scalar>
534 RCP<const Teuchos::ParameterList>
537 using Teuchos::ParameterList;
538 static RCP<const ParameterList> validPL;
539 if (is_null(validPL)) {
540 RCP<ParameterList> pl = Teuchos::parameterList();
541 Teuchos::setupVerboseObjectSublist(&*pl);
547 template<
class Scalar>
550 TEUCHOS_TEST_FOR_EXCEPT( is_null(model) );
551 TEUCHOS_TEST_FOR_EXCEPT( !is_null(model_) );
552 assertValidModel( *
this, *model );
557 template<
class Scalar>
560 this->setModel(model);
564 template<
class Scalar>
565 Teuchos::RCP<const Thyra::ModelEvaluator<Scalar> >
572 template<
class Scalar>
573 Teuchos::RCP<Thyra::ModelEvaluator<Scalar> >
576 return Teuchos::null;
580 template<
class Scalar>
582 const Thyra::ModelEvaluatorBase::InArgs<Scalar> &initialCondition
588 basePoint_ = initialCondition;
592 RCP<const Thyra::VectorBase<Scalar> >
593 x_init = initialCondition.get_x();
595 #ifdef HAVE_RYTHMOS_DEBUG
596 TEUCHOS_TEST_FOR_EXCEPTION(
597 is_null(x_init), std::logic_error,
598 "Error, if the client passes in an intial condition to setInitialCondition(...),\n"
599 "then x can not be null!" );
602 solution_vector_ = x_init->clone_v();
603 solution_vector_old_ = x_init->clone_v();
606 solution_hat_vector_ = x_init->clone_v();
607 ee_ = x_init->clone_v();
611 t_ = initialCondition.get_t();
614 haveInitialCondition_ =
true;
619 template<
class Scalar>
620 Thyra::ModelEvaluatorBase::InArgs<Scalar>
626 template<
class Scalar>
632 template<
class Scalar>
637 RCP<ExplicitRKStepper<Scalar> >
640 if (!is_null(model_)) {
641 stepper->setModel(model_);
644 if (!is_null(erkButcherTableau_)) {
646 stepper->setRKButcherTableau(erkButcherTableau_);
649 if (!is_null(parameterList_)) {
650 stepper->setParameterList(Teuchos::parameterList(*parameterList_));
657 template<
class Scalar>
660 return(stepControl_);
663 template<
class Scalar>
666 return(stepControl_);
669 template<
class Scalar>
672 TEUCHOS_TEST_FOR_EXCEPTION(stepControl == Teuchos::null,std::logic_error,
"Error, stepControl == Teuchos::null!\n");
673 stepControl_ = stepControl;
681 #define RYTHMOS_EXPLICIT_RK_STEPPER_INSTANT(SCALAR) \
683 template class ExplicitRKStepper< SCALAR >; \
685 template RCP< ExplicitRKStepper< SCALAR > > \
686 explicitRKStepper(); \
688 template RCP< ExplicitRKStepper< SCALAR > > \
690 const RCP<Thyra::ModelEvaluator< SCALAR > >& model \
693 template RCP< ExplicitRKStepper< SCALAR > > \
695 const RCP<Thyra::ModelEvaluator< SCALAR > >& model, \
696 const RCP<const RKButcherTableauBase< SCALAR > >& rkbt \
701 #endif //Rythmos_ExplicitRK_STEPPER_DEF_H
Teuchos::RCP< Teuchos::ParameterList > unsetParameterList()
Scalar takeStep(Scalar dt, StepSizeType flag)
void setStepControlStrategy(const RCP< StepControlStrategyBase< Scalar > > &stepControlStrategy)
Teuchos::RCP< const Thyra::VectorSpaceBase< Scalar > > get_x_space() const
Teuchos::RCP< Teuchos::ParameterList > getNonconstParameterList()
RCP< const Teuchos::ParameterList > getValidParameters() const
The member functions in the StepControlStrategyBase move you between these states in the following fa...
void getNodes(Array< Scalar > *time_vec) const
Get interpolation nodes.
void setParameterList(Teuchos::RCP< Teuchos::ParameterList > const ¶mList)
Redefined from Teuchos::ParameterListAcceptor.
RCP< const StepControlStrategyBase< Scalar > > getStepControlStrategy() const
const StepStatus< Scalar > getStepStatus() const
void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const
int getOrder() const
Get order of interpolation.
void setRKButcherTableau(const RCP< const RKButcherTableauBase< Scalar > > &rkbt)
Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > getModel() const
void setModel(const Teuchos::RCP< const Thyra::ModelEvaluator< Scalar > > &model)
void getPoints(const Array< Scalar > &time_vec, Array< RCP< const VectorBase< Scalar > > > *x_vec, Array< RCP< const VectorBase< Scalar > > > *xdot_vec, Array< ScalarMag > *accuracy_vec) const
Get values from buffer.
void removeNodes(Array< Scalar > &time_vec)
Remove interpolation nodes.
Thyra::ModelEvaluatorBase::InArgs< Scalar > getInitialCondition() const
RCP< StepperBase< Scalar > > cloneStepperAlgorithm() const
RCP< const RKButcherTableauBase< Scalar > > getRKButcherTableau() const
RCP< const Thyra::VectorBase< Scalar > > solution
RCP< StepControlStrategyBase< Scalar > > getNonconstStepControlStrategy()
RCP< Thyra::ModelEvaluator< Scalar > > getNonconstModel()
bool supportsCloning() const
void setNonconstModel(const Teuchos::RCP< Thyra::ModelEvaluator< Scalar > > &model)
TimeRange< Scalar > getTimeRange() const
void addPoints(const Array< Scalar > &time_vec, const Array< Teuchos::RCP< const Thyra::VectorBase< Scalar > > > &x_vec, const Array< Teuchos::RCP< const Thyra::VectorBase< Scalar > > > &xdot_vec)
void setInitialCondition(const Thyra::ModelEvaluatorBase::InArgs< Scalar > &initialCondition)