29 #ifndef RYTHMOS_EXPLICIT_TAYLOR_POLYNOMIAL_STEPPER_H 
   30 #define RYTHMOS_EXPLICIT_TAYLOR_POLYNOMIAL_STEPPER_H 
   32 #include "Rythmos_StepperBase.hpp" 
   33 #include "Rythmos_StepperHelpers.hpp" 
   34 #include "Teuchos_RCP.hpp" 
   35 #include "Teuchos_ParameterList.hpp" 
   36 #include "Teuchos_VerboseObjectParameterListHelpers.hpp" 
   37 #include "Thyra_VectorBase.hpp" 
   38 #include "Thyra_ModelEvaluator.hpp" 
   39 #include "Thyra_ModelEvaluatorHelpers.hpp" 
   40 #include "Thyra_PolynomialVectorTraits.hpp" 
   41 #include "RTOpPack_RTOpTHelpers.hpp" 
   53 RTOP_ROP_1_REDUCT_SCALAR( ROpLogNormInf,
 
   54   typename ScalarTraits<Scalar>::magnitudeType, 
 
   55   RTOpPack::REDUCT_TYPE_MAX 
 
   59   typedef ScalarTraits<Scalar> ST;
 
   60   typedef typename ST::magnitudeType ScalarMag;
 
   61   const ScalarMag mag = std::log(as<ScalarMag>(1e-100) + ST::magnitude(v0));
 
   62   reduct = TEUCHOS_MAX( mag, reduct );
 
  162 template<
class Scalar>
 
  168   typedef typename Teuchos::ScalarTraits<Scalar>::magnitudeType 
ScalarMag;
 
  177   RCP<const Thyra::VectorSpaceBase<Scalar> > 
get_x_space() 
const;
 
  180   void setModel(
const RCP<
const Thyra::ModelEvaluator<Scalar> >& model);
 
  186   RCP<const Thyra::ModelEvaluator<Scalar> > 
getModel() 
const;
 
  193     const Thyra::ModelEvaluatorBase::InArgs<Scalar> &initialCondition
 
  200   Scalar 
takeStep(Scalar dt, StepSizeType flag);
 
  223     Teuchos::FancyOStream &out,
 
  224     const Teuchos::EVerbosityLevel verbLevel = Teuchos::Describable::verbLevel_default
 
  230     const Array<Scalar>& time_vec
 
  231     ,
const Array<RCP<
const Thyra::VectorBase<Scalar> > >& x_vec
 
  232     ,
const Array<RCP<
const Thyra::VectorBase<Scalar> > >& xdot_vec
 
  237     const Array<Scalar>& time_vec
 
  238     ,Array<RCP<
const Thyra::VectorBase<Scalar> > >* x_vec
 
  239     ,Array<RCP<
const Thyra::VectorBase<Scalar> > >* xdot_vec
 
  240     ,Array<ScalarMag>* accuracy_vec) 
const;
 
  252   void getNodes(Array<Scalar>* time_vec) 
const;
 
  263   void defaultInitializAll_();
 
  266   void computeTaylorSeriesSolution_();
 
  272   ScalarMag estimateLogRadius_();
 
  275   RCP<const Thyra::ModelEvaluator<Scalar> > model_;
 
  278   RCP<Teuchos::ParameterList> parameterList_;
 
  281   RCP<Thyra::VectorBase<Scalar> > x_vector_;
 
  284   RCP<Thyra::VectorBase<Scalar> > x_vector_old_;
 
  287   RCP<Thyra::VectorBase<Scalar> > x_dot_vector_;
 
  290   RCP<Thyra::VectorBase<Scalar> > x_dot_vector_old_;
 
  293   RCP<Thyra::VectorBase<Scalar> > f_vector_;
 
  296   RCP<Teuchos::Polynomial<Thyra::VectorBase<Scalar> > > x_poly_;
 
  299   RCP<Teuchos::Polynomial<Thyra::VectorBase<Scalar> > > f_poly_;
 
  302   Thyra::ModelEvaluatorBase::InArgs<Scalar> basePoint_;
 
  305   bool haveInitialCondition_;
 
  323   ScalarMag local_error_tolerance_;
 
  326   Scalar min_step_size_;
 
  329   Scalar max_step_size_;
 
  332   unsigned int degree_;
 
  340 template <
typename Scalar>
 
  341 typename Teuchos::ScalarTraits<Scalar>::magnitudeType
 
  342 log_norm_inf(
const Thyra::VectorBase<Scalar>& x)
 
  344   ROpLogNormInf<Scalar> log_norm_inf_op;
 
  345   RCP<RTOpPack::ReductTarget> log_norm_inf_targ =
 
  346     log_norm_inf_op.reduct_obj_create();
 
  347   Thyra::applyOp<Scalar>(log_norm_inf_op,
 
  348     Teuchos::tuple(Teuchos::ptrFromRef(x))(), Teuchos::null,
 
  349     log_norm_inf_targ.ptr());
 
  350   return log_norm_inf_op(*log_norm_inf_targ);
 
  355 template<
class Scalar>
 
  356 RCP<ExplicitTaylorPolynomialStepper<Scalar> > explicitTaylorPolynomialStepper()
 
  358   RCP<ExplicitTaylorPolynomialStepper<Scalar> > stepper = rcp(
new ExplicitTaylorPolynomialStepper<Scalar>());
 
  363 template<
class Scalar>
 
  366   this->defaultInitializAll_();
 
  371 template<
class Scalar>
 
  377 template<
class Scalar>
 
  380   typedef Teuchos::ScalarTraits<Scalar> ST;
 
  381   Scalar nan = ST::nan();
 
  382   model_ = Teuchos::null;
 
  383   parameterList_ = Teuchos::null;
 
  384   x_vector_ = Teuchos::null;
 
  385   x_vector_old_ = Teuchos::null;
 
  386   x_dot_vector_ = Teuchos::null;
 
  387   x_dot_vector_old_ = Teuchos::null;
 
  388   f_vector_ = Teuchos::null;
 
  389   x_poly_ = Teuchos::null;
 
  390   f_poly_ = Teuchos::null;
 
  391   haveInitialCondition_ = 
false;
 
  397   local_error_tolerance_ = nan;
 
  398   min_step_size_ = nan;
 
  399   max_step_size_ = nan;
 
  405 template<
class Scalar>
 
  407   const RCP<
const Thyra::ModelEvaluator<Scalar> >& model
 
  410   TEUCHOS_TEST_FOR_EXCEPT( is_null(model) );
 
  411   assertValidModel( *
this, *model );
 
  414   f_vector_ = Thyra::createMember(model_->get_f_space());
 
  418 template<
class Scalar>
 
  420   const RCP<Thyra::ModelEvaluator<Scalar> >& model
 
  423   this->setModel(model); 
 
  427 template<
class Scalar>
 
  428 RCP<const Thyra::ModelEvaluator<Scalar> >
 
  435 template<
class Scalar>
 
  436 RCP<Thyra::ModelEvaluator<Scalar> >
 
  439   return Teuchos::null;
 
  443 template<
class Scalar>
 
  445   const Thyra::ModelEvaluatorBase::InArgs<Scalar> &initialCondition
 
  448   typedef Teuchos::ScalarTraits<Scalar> ST;
 
  449   typedef Thyra::ModelEvaluatorBase MEB;
 
  450   basePoint_ = initialCondition;
 
  451   if (initialCondition.supports(MEB::IN_ARG_t)) {
 
  452     t_ = initialCondition.get_t();
 
  457   x_vector_ = initialCondition.get_x()->clone_v();
 
  458   x_dot_vector_ = x_vector_->clone_v();
 
  459   x_vector_old_ = x_vector_->clone_v();
 
  460   x_dot_vector_old_ = x_dot_vector_->clone_v();
 
  461   haveInitialCondition_ = 
true;
 
  465 template<
class Scalar>
 
  466 Thyra::ModelEvaluatorBase::InArgs<Scalar>
 
  473 template<
class Scalar>
 
  477   typedef Teuchos::ScalarTraits<Scalar> ST;
 
  478   TEUCHOS_ASSERT( haveInitialCondition_ );
 
  479   TEUCHOS_ASSERT( !is_null(model_) );
 
  480   TEUCHOS_ASSERT( !is_null(parameterList_) ); 
 
  482   V_V(outArg(*x_vector_old_),*x_vector_); 
 
  483   V_V(outArg(*x_dot_vector_old_),*x_dot_vector_); 
 
  485   if (x_poly_ == Teuchos::null) {
 
  486     x_poly_ = Teuchos::rcp(
new Teuchos::Polynomial<Thyra::VectorBase<Scalar> >(0,*x_vector_,degree_));
 
  489   if (f_poly_ == Teuchos::null) {
 
  490     f_poly_ = Teuchos::rcp(
new Teuchos::Polynomial<Thyra::VectorBase<Scalar> >(0, *f_vector_, degree_));
 
  492   if (flag == STEP_TYPE_VARIABLE) {
 
  500     computeTaylorSeriesSolution_();
 
  503     Scalar rho = estimateLogRadius_();
 
  506     Scalar shadowed_dt = std::exp(linc_ - rho);
 
  509     if (shadowed_dt > max_step_size_) {
 
  510       shadowed_dt = max_step_size_;
 
  514     if (t_+shadowed_dt > t_final_) {
 
  515       shadowed_dt = t_final_-t_;
 
  518     ScalarMag local_error;
 
  523       x_poly_->evaluate(shadowed_dt, x_vector_.get(), x_dot_vector_.get());
 
  526       eval_model_explicit<Scalar>(*model_,basePoint_,*x_vector_,t_+shadowed_dt,Teuchos::outArg(*f_vector_));
 
  529       Thyra::Vp_StV(x_dot_vector_.ptr(), -ST::one(),
 
  531       local_error = norm_inf(*x_dot_vector_);
 
  533       if (local_error > local_error_tolerance_) {
 
  537     } 
while (local_error > local_error_tolerance_ && shadowed_dt > min_step_size_);
 
  540     TEUCHOS_TEST_FOR_EXCEPTION(shadowed_dt < min_step_size_,
 
  542       "ExplicitTaylorPolynomialStepper<Scalar>::takeStep(): " 
  543       << 
"Step size reached minimum step size " 
  544       << min_step_size_ << 
".  Failing step." );
 
  559       dt_ = Teuchos::ScalarTraits<Scalar>::zero();
 
  564     computeTaylorSeriesSolution_();
 
  567     if (dt > max_step_size_) {
 
  572     if (t_+dt > t_final_) {
 
  577     x_poly_->evaluate(dt, x_vector_.get());
 
  591 template<
class Scalar>
 
  598   if (!haveInitialCondition_) {
 
  599     stepStatus.
stepStatus = STEP_STATUS_UNINITIALIZED;
 
  601   else if (numSteps_ == 0) {
 
  604     stepStatus.
order = this->getOrder();
 
  605     stepStatus.
time = t_;
 
  608     if (!is_null(model_)) {
 
  613     stepStatus.
stepStatus = STEP_STATUS_CONVERGED;
 
  615     stepStatus.
order = this->getOrder();
 
  616     stepStatus.
time = t_;
 
  625 template<
class Scalar>
 
  628   typedef Teuchos::ScalarTraits<Scalar> ST;
 
  630   TEUCHOS_TEST_FOR_EXCEPT(is_null(paramList));
 
  631   paramList->validateParameters(*this->getValidParameters());
 
  632   parameterList_ = paramList;
 
  633   Teuchos::readVerboseObjectSublist(&*parameterList_,
this);
 
  636   t_initial_ = parameterList_->get(
"Initial Time", ST::zero());
 
  639   t_final_ = parameterList_->get(
"Final Time", ST::one());
 
  642   local_error_tolerance_ =
 
  643     parameterList_->get(
"Local Error Tolerance", ScalarMag(1.0e-10));
 
  646   min_step_size_ = parameterList_->get(
"Minimum Step Size", Scalar(1.0e-10));
 
  649   max_step_size_ = parameterList_->get(
"Maximum Step Size", Scalar(1.0));
 
  652   degree_ = parameterList_->get(
"Taylor Polynomial Degree", Teuchos::as<unsigned int>(40));
 
  654   linc_ = Scalar(-16.0*std::log(10.0)/degree_);
 
  659 template<
class Scalar>
 
  660 RCP<Teuchos::ParameterList>
 
  663   return parameterList_;
 
  667 template<
class Scalar>
 
  668 RCP<Teuchos::ParameterList>
 
  671   RCP<Teuchos::ParameterList> temp_param_list = parameterList_;
 
  672   parameterList_ = Teuchos::null;
 
  673   return temp_param_list;
 
  677 template<
class Scalar>
 
  678 RCP<const Teuchos::ParameterList>
 
  681   typedef ScalarTraits<Scalar> ST;
 
  682   static RCP<const ParameterList> validPL;
 
  683   if (is_null(validPL)) {
 
  684     RCP<ParameterList> pl = Teuchos::parameterList();
 
  686     pl->set<Scalar>(
"Initial Time", ST::zero());
 
  687     pl->set<Scalar>(
"Final Time", ST::one());
 
  688     pl->set<ScalarMag>(
"Local Error Tolerance", ScalarMag(1.0e-10));
 
  689     pl->set<Scalar>(
"Minimum Step Size", Scalar(1.0e-10));
 
  690     pl->set<Scalar>(
"Maximum Step Size", Scalar(1.0));
 
  691     pl->set<
unsigned int>(
"Taylor Polynomial Degree", 40);
 
  693     Teuchos::setupVerboseObjectSublist(&*pl);
 
  700 template<
class Scalar>
 
  703   std::string name = 
"Rythmos::ExplicitTaylorPolynomialStepper";
 
  708 template<
class Scalar>
 
  710   Teuchos::FancyOStream &out,
 
  711   const Teuchos::EVerbosityLevel verbLevel
 
  714   if (verbLevel == Teuchos::VERB_EXTREME) {
 
  715     out << description() << 
"::describe" << std::endl;
 
  716     out << 
"model_ = " << std::endl;
 
  717     out << Teuchos::describe(*model_, verbLevel) << std::endl;
 
  718     out << 
"x_vector_ = " << std::endl;
 
  719     out << Teuchos::describe(*x_vector_, verbLevel) << std::endl;
 
  720     out << 
"x_dot_vector_ = " << std::endl;
 
  721     out << Teuchos::describe(*x_dot_vector_, verbLevel) << std::endl;
 
  722     out << 
"f_vector_ = " << std::endl;
 
  723     out << Teuchos::describe(*f_vector_, verbLevel) << std::endl;
 
  724     out << 
"x_poly_ = " << std::endl;
 
  725     out << Teuchos::describe(*x_poly_, verbLevel) << std::endl;
 
  726     out << 
"f_poly_ = " << std::endl;
 
  727     out << Teuchos::describe(*f_poly_, verbLevel) << std::endl;
 
  728     out << 
"t_ = " << t_ << std::endl;
 
  729     out << 
"t_initial_ = " << t_initial_ << std::endl;
 
  730     out << 
"t_final_ = " << t_final_ << std::endl;
 
  731     out << 
"local_error_tolerance_ = " << local_error_tolerance_ << std::endl;
 
  732     out << 
"min_step_size_ = " << min_step_size_ << std::endl;
 
  733     out << 
"max_step_size_ = " << max_step_size_ << std::endl;
 
  734     out << 
"degree_ = " << degree_ << std::endl;
 
  735     out << 
"linc_ = " << linc_ << std::endl;
 
  740 template<
class Scalar>
 
  743   ,
const Array<RCP<
const Thyra::VectorBase<Scalar> > >& 
 
  744   ,
const Array<RCP<
const Thyra::VectorBase<Scalar> > >& 
 
  747   TEUCHOS_TEST_FOR_EXCEPTION(
true,std::logic_error,
"Error, addPoints is not implemented for the ExplicitTaylorPolynomialStepper.\n");
 
  751 template<
class Scalar>
 
  753   const Array<Scalar>& time_vec
 
  754   ,Array<RCP<
const Thyra::VectorBase<Scalar> > >* x_vec
 
  755   ,Array<RCP<
const Thyra::VectorBase<Scalar> > >* xdot_vec
 
  756   ,Array<ScalarMag>* accuracy_vec)
 const 
  758   TEUCHOS_ASSERT( haveInitialCondition_ );
 
  759   using Teuchos::constOptInArg;
 
  761   defaultGetPoints<Scalar>(
 
  762     t_-dt_,constOptInArg(*x_vector_old_),constOptInArg(*x_dot_vector_old_),
 
  763     t_,constOptInArg(*x_vector_),constOptInArg(*x_dot_vector_),
 
  764     time_vec,ptr(x_vec),ptr(xdot_vec),ptr(accuracy_vec),
 
  765     Ptr<InterpolatorBase<Scalar> >(null)
 
  770 template<
class Scalar>
 
  773   if (!haveInitialCondition_) {
 
  774     return invalidTimeRange<Scalar>();
 
  781 template<
class Scalar>
 
  784   TEUCHOS_ASSERT( time_vec != NULL );
 
  786   if (!haveInitialCondition_) {
 
  789     time_vec->push_back(t_);
 
  792     time_vec->push_back(t_-dt_);
 
  797 template<
class Scalar>
 
  800   TEUCHOS_TEST_FOR_EXCEPTION(
true,std::logic_error,
"Error, removeNodes is not implemented for the ExplicitTaylorPolynomialStepper.\n");
 
  804 template<
class Scalar>
 
  816 template<
class Scalar>
 
  820   RCP<Thyra::VectorBase<Scalar> > tmp;
 
  823   x_poly_->setDegree(0);
 
  824   f_poly_->setDegree(0);
 
  827   x_poly_->setCoefficient(0, *x_vector_);
 
  829   for (
unsigned int k=1; k<=degree_; k++) {
 
  832     eval_model_explicit_poly(*model_, basePoint_, *x_poly_, t_, Teuchos::outArg(*f_poly_));
 
  834     x_poly_->setDegree(k);
 
  835     f_poly_->setDegree(k);
 
  838     tmp = x_poly_->getCoefficient(k);
 
  839     copy(*(f_poly_->getCoefficient(k-1)), tmp.ptr());
 
  840     scale(Scalar(1.0)/Scalar(k), tmp.ptr());
 
  846 template<
class Scalar>
 
  847 typename ExplicitTaylorPolynomialStepper<Scalar>::ScalarMag
 
  848 ExplicitTaylorPolynomialStepper<Scalar>::estimateLogRadius_()
 
  852   for (
unsigned int k=degree_/2; k<=degree_; k++) {
 
  853     tmp = log_norm_inf(*(x_poly_->getCoefficient(k))) / k;
 
  862 template<
class Scalar>
 
  865   if (haveInitialCondition_) {
 
  866     return(x_vector_->space());
 
  868     return Teuchos::null;
 
  875 #endif // RYTHMOS_EXPLICIT_TAYLOR_POLYNOMIAL_STEPPER_H 
std::string description() const 
void getNodes(Array< Scalar > *time_vec) const 
Get interpolation nodes. 
const StepStatus< Scalar > getStepStatus() const 
Base class for defining stepper functionality. 
Thyra::ModelEvaluatorBase::InArgs< Scalar > getInitialCondition() const 
ExplicitTaylorPolynomialStepper()
Constructor. 
void addPoints(const Array< Scalar > &time_vec, const Array< RCP< const Thyra::VectorBase< Scalar > > > &x_vec, const Array< RCP< const Thyra::VectorBase< Scalar > > > &xdot_vec)
void setInitialCondition(const Thyra::ModelEvaluatorBase::InArgs< Scalar > &initialCondition)
RCP< const Thyra::VectorSpaceBase< Scalar > > get_x_space() const 
Return the space for x and x_dot 
void removeNodes(Array< Scalar > &time_vec)
Remove interpolation nodes. 
void setModel(const RCP< const Thyra::ModelEvaluator< Scalar > > &model)
Set model. 
RCP< const Thyra::ModelEvaluator< Scalar > > getModel() const 
void setNonconstModel(const RCP< Thyra::ModelEvaluator< Scalar > > &model)
Set model. 
void setParameterList(RCP< Teuchos::ParameterList > const ¶mList)
Redefined from Teuchos::ParameterListAcceptor. 
~ExplicitTaylorPolynomialStepper()
Destructor. 
RCP< const Thyra::VectorBase< Scalar > > residual
RCP< const Thyra::VectorBase< Scalar > > solutionDot
Teuchos::ScalarTraits< Scalar >::magnitudeType ScalarMag
Typename of magnitude of scalars. 
Base class for an interpolation buffer. 
void getPoints(const Array< Scalar > &time_vec, Array< RCP< const Thyra::VectorBase< Scalar > > > *x_vec, Array< RCP< const Thyra::VectorBase< Scalar > > > *xdot_vec, Array< ScalarMag > *accuracy_vec) const 
Get values from buffer. 
RCP< Thyra::ModelEvaluator< Scalar > > getNonconstModel()
RCP< Teuchos::ParameterList > unsetParameterList()
Scalar takeStep(Scalar dt, StepSizeType flag)
Take a time step of magnitude dt. 
int getOrder() const 
Get order of interpolation. 
Implementation of Rythmos::Stepper for explicit Taylor polynomial time integration of ODEs...
void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel=Teuchos::Describable::verbLevel_default) const 
void setRange(const TimeRange< Scalar > &range, const InterpolationBufferBase< Scalar > &IB)
Fill data in from another interpolation buffer. 
RCP< const Thyra::VectorBase< Scalar > > solution
RCP< const Teuchos::ParameterList > getValidParameters() const 
RCP< Teuchos::ParameterList > getNonconstParameterList()
TimeRange< Scalar > getTimeRange() const