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