29 #ifndef RYTHMOS_STACKED_STEPPER_HPP
30 #define RYTHMOS_STACKED_STEPPER_HPP
33 #include "Rythmos_StepperBase.hpp"
34 #include "Thyra_ModelEvaluatorHelpers.hpp"
35 #include "Teuchos_ParameterListAcceptorDefaultBase.hpp"
36 #include "Teuchos_VerboseObjectParameterListHelpers.hpp"
37 #include "Teuchos_Assert.hpp"
38 #include "Teuchos_as.hpp"
41 #include "Rythmos_ForwardSensitivityModelEvaluatorBase.hpp"
45 template<
class Scalar>
46 class StackedStepperStepStrategyBase
49 virtual ~StackedStepperStepStrategyBase() {}
50 virtual void setupNextStepper(
52 Array<RCP<StepperBase<Scalar> > > &stepperArray
54 virtual Scalar evaluateStep(
55 Scalar local_dt_taken,
57 Array<RCP<StepperBase<Scalar> > > &stepperArray
61 template<
class Scalar>
62 class DefaultStackedStepperStepStrategy
63 :
virtual public StackedStepperStepStrategyBase<Scalar>
66 DefaultStackedStepperStepStrategy();
67 virtual ~DefaultStackedStepperStepStrategy();
68 void setupNextStepper(
70 Array<RCP<StepperBase<Scalar> > > &stepperArray
73 Scalar local_dt_taken,
75 Array<RCP<StepperBase<Scalar> > > &stepperArray
82 template<
class Scalar>
83 RCP<DefaultStackedStepperStepStrategy<Scalar> >
84 defaultStackedStepperStepStrategy();
87 template<
class Scalar>
88 RCP<DefaultStackedStepperStepStrategy<Scalar> >
89 defaultStackedStepperStepStrategy()
91 return Teuchos::rcp(
new DefaultStackedStepperStepStrategy<Scalar>());
94 template<
class Scalar>
95 DefaultStackedStepperStepStrategy<Scalar>::DefaultStackedStepperStepStrategy()
97 typedef Teuchos::ScalarTraits<Scalar> ST;
98 dt_taken_ = ST::nan();
102 template<
class Scalar>
103 DefaultStackedStepperStepStrategy<Scalar>::~DefaultStackedStepperStepStrategy()
108 template<
class Scalar>
109 void DefaultStackedStepperStepStrategy<Scalar>::setupNextStepper(
111 Array<RCP<StepperBase<Scalar> > > &stepperArray
115 RCP<StepperBase<Scalar> > baseStepper = stepperArray[0];
116 stepperArray[i]->setStepControlData(*baseStepper);
121 template<
class Scalar>
122 Scalar DefaultStackedStepperStepStrategy<Scalar>::evaluateStep(
123 Scalar local_dt_taken,
125 Array<RCP<StepperBase<Scalar> > > &stepperArray
129 dt_taken_ = local_dt_taken;
132 TEUCHOS_TEST_FOR_EXCEPTION( local_dt_taken != dt_taken_, std::logic_error,
133 "Error! sub-stepper["<<i<<
"] did not take the same "
134 "size step as the base stepper!"
142 template<
class Scalar>
143 class ForwardSensitivityStackedStepperStepStrategy
144 :
virtual public StackedStepperStepStrategyBase<Scalar>
147 ForwardSensitivityStackedStepperStepStrategy();
148 virtual ~ForwardSensitivityStackedStepperStepStrategy();
149 void setupNextStepper(
151 Array<RCP<StepperBase<Scalar> > > &stepperArray
154 Scalar local_dt_taken,
156 Array<RCP<StepperBase<Scalar> > > &stepperArray
158 void setStateBasePoint(
159 const Thyra::ModelEvaluatorBase::InArgs<Scalar> &stateBasePoint
163 Thyra::ModelEvaluatorBase::InArgs<Scalar> stateBasePoint_;
167 template<
class Scalar>
168 RCP<ForwardSensitivityStackedStepperStepStrategy<Scalar> >
169 forwardSensitivityStackedStepperStepStrategy();
172 template<
class Scalar>
173 RCP<ForwardSensitivityStackedStepperStepStrategy<Scalar> >
174 forwardSensitivityStackedStepperStepStrategy()
176 return Teuchos::rcp(
new ForwardSensitivityStackedStepperStepStrategy<Scalar>());
179 template<
class Scalar>
180 ForwardSensitivityStackedStepperStepStrategy<Scalar>::ForwardSensitivityStackedStepperStepStrategy()
182 typedef Teuchos::ScalarTraits<Scalar> ST;
183 dt_taken_ = ST::nan();
187 template<
class Scalar>
188 ForwardSensitivityStackedStepperStepStrategy<Scalar>::~ForwardSensitivityStackedStepperStepStrategy()
193 template<
class Scalar>
194 void ForwardSensitivityStackedStepperStepStrategy<Scalar>::setupNextStepper(
196 Array<RCP<StepperBase<Scalar> > > &stepperArray
199 typedef Thyra::ModelEvaluatorBase MEB;
201 RCP<StepperBase<Scalar> > baseStepper = stepperArray[0];
202 RCP<Thyra::ModelEvaluator<Scalar> > modelI =
205 Teuchos::rcp_const_cast<Thyra::ModelEvaluator<Scalar> >(
206 stepperArray[i]->getModel()
208 RCP<ForwardSensitivityModelEvaluatorBase<Scalar> > fwdSensME =
209 Teuchos::rcp_dynamic_cast<ForwardSensitivityModelEvaluatorBase<Scalar> > (
212 if (Teuchos::nonnull(fwdSensME)) {
213 bool forceUpToDateW =
true;
214 fwdSensME->initializePointState( Teuchos::inOutArg(*baseStepper), forceUpToDateW);
216 stepperArray[i]->setStepControlData(*baseStepper);
221 template<
class Scalar>
222 Scalar ForwardSensitivityStackedStepperStepStrategy<Scalar>::evaluateStep(
223 Scalar local_dt_taken,
225 Array<RCP<StepperBase<Scalar> > > &stepperArray
229 dt_taken_ = local_dt_taken;
232 TEUCHOS_TEST_FOR_EXCEPTION( local_dt_taken != dt_taken_, std::logic_error,
233 "Error! sub-stepper["<<i<<
"] did not take the same "
234 "size step as the base stepper!"
241 template<
class Scalar>
242 void ForwardSensitivityStackedStepperStepStrategy<Scalar>::setStateBasePoint(
243 const Thyra::ModelEvaluatorBase::InArgs<Scalar> &stateBasePoint
246 stateBasePoint_ = stateBasePoint;
250 template<
class Scalar>
252 :
virtual public StepperBase<Scalar>,
253 virtual public Teuchos::ParameterListAcceptorDefaultBase
258 typedef typename Teuchos::ScalarTraits<Scalar>::magnitudeType ScalarMag;
268 void addStepper(
const RCP<StepperBase<Scalar> >& stepper);
272 ArrayView<const RCP<StepperBase<Scalar> > > getNonconstSteppers()
const;
276 void setStackedStepperStepControlStrategy(
277 const RCP<StackedStepperStepStrategyBase<Scalar> >& stepControl
282 RCP<const StackedStepperStepStrategyBase<Scalar> >
283 getStackedStepperStepCongrolStrategy()
const;
291 void setParameterList(RCP<Teuchos::ParameterList>
const& paramList);
293 RCP<const Teuchos::ParameterList> getValidParameters()
const;
301 bool acceptsModel()
const;
305 const RCP<
const Thyra::ModelEvaluator<Scalar> >& model
309 void setNonconstModel(
310 const RCP<Thyra::ModelEvaluator<Scalar> >& model
319 RCP<const Thyra::ModelEvaluator<Scalar> > getModel()
const;
322 RCP<Thyra::ModelEvaluator<Scalar> > getNonconstModel();
336 void setInitialCondition(
337 const Thyra::ModelEvaluatorBase::InArgs<Scalar> &stacked_ic
342 Thyra::ModelEvaluatorBase::InArgs<Scalar> getInitialCondition()
const;
345 Scalar takeStep( Scalar dt, StepSizeType stepType );
348 const StepStatus<Scalar> getStepStatus()
const;
361 RCP<const Thyra::VectorSpaceBase<Scalar> >
366 const Array<Scalar>& time_vec,
367 const Array<Teuchos::RCP<
const Thyra::VectorBase<Scalar> > >& x_vec,
368 const Array<Teuchos::RCP<
const Thyra::VectorBase<Scalar> > >& xdot_vec
372 TimeRange<Scalar> getTimeRange()
const;
376 const Array<Scalar>& time_vec,
377 Array<RCP<
const Thyra::VectorBase<Scalar> > >* x_vec,
378 Array<RCP<
const Thyra::VectorBase<Scalar> > >* xdot_vec,
379 Array<ScalarMag>* accuracy_vec
383 void getNodes(Array<Scalar>* time_vec)
const;
386 void removeNodes(Array<Scalar>& time_vec);
389 int getOrder()
const;
395 mutable bool isInitialized_;
397 Array<RCP<StepperBase<Scalar> > > stepperArray_;
399 mutable Array<RCP<const Thyra::VectorSpaceBase<Scalar> > > xSpaceArray_;
402 mutable Teuchos::RCP<const Thyra::ProductVectorSpaceBase<Scalar> >
407 RCP<StackedStepperStepStrategyBase<Scalar> > stackedStepperStepStrategy_;
410 void setupSpaces_()
const;
419 template<
class Scalar>
421 RCP<StackedStepper<Scalar> >
424 return Teuchos::rcp(
new StackedStepper<Scalar>());
431 template<
class Scalar>
432 StackedStepper<Scalar>::StackedStepper()
433 : isInitialized_(false)
436 template<
class Scalar>
437 void StackedStepper<Scalar>::setupSpaces_()
const
440 if (!isInitialized_) {
441 for (
int i=0 ; i < as<int>(stepperArray_.size()) ; ++i) {
442 xSpaceArray_.push_back(stepperArray_[i]->get_x_space());
446 x_bar_space_ = Thyra::productVectorSpace<Scalar>(xSpaceArray_);
449 isInitialized_ =
true;
453 template<
class Scalar>
454 void StackedStepper<Scalar>::addStepper(
455 const RCP<StepperBase<Scalar> >& stepper
458 TEUCHOS_ASSERT(!is_null(stepper));
459 stepperArray_.push_back(stepper);
460 isInitialized_ =
false;
465 template<
class Scalar>
466 ArrayView<const RCP<StepperBase<Scalar> > >
467 StackedStepper<Scalar>::getNonconstSteppers()
const
469 return stepperArray_();
473 template<
class Scalar>
474 void StackedStepper<Scalar>::setStackedStepperStepControlStrategy(
475 const RCP<StackedStepperStepStrategyBase<Scalar> >& stepControl
478 TEUCHOS_ASSERT( Teuchos::nonnull(stepControl) );
479 stackedStepperStepStrategy_ = stepControl;
483 template<
class Scalar>
484 RCP<const StackedStepperStepStrategyBase<Scalar> >
485 StackedStepper<Scalar>::getStackedStepperStepCongrolStrategy()
const
487 return stackedStepperStepStrategy_;
491 template<
class Scalar>
492 void StackedStepper<Scalar>::setParameterList(
493 RCP<Teuchos::ParameterList>
const& paramList
496 TEUCHOS_TEST_FOR_EXCEPT(is_null(paramList));
497 paramList->validateParameters(*getValidParameters());
498 this->setMyParamList(paramList);
499 Teuchos::readVerboseObjectSublist(&*paramList,
this);
503 template<
class Scalar>
504 RCP<const Teuchos::ParameterList>
505 StackedStepper<Scalar>::getValidParameters()
const
507 static RCP<const ParameterList> validPL;
508 if (is_null(validPL) ) {
509 RCP<ParameterList> pl = Teuchos::parameterList();
510 Teuchos::setupVerboseObjectSublist(&*pl);
519 template<
class Scalar>
520 bool StackedStepper<Scalar>::acceptsModel()
const
525 template<
class Scalar>
526 void StackedStepper<Scalar>::setModel(
527 const RCP<
const Thyra::ModelEvaluator<Scalar> >& model
530 TEUCHOS_TEST_FOR_EXCEPT_MSG(
true,
531 "Error, this stepper subclass does not accept a model"
532 " as defined by the StepperBase interface!");
536 template<
class Scalar>
537 void StackedStepper<Scalar>::setNonconstModel(
538 const RCP<Thyra::ModelEvaluator<Scalar> >& model
541 TEUCHOS_TEST_FOR_EXCEPT_MSG(
true,
542 "Error, this stepper subclass does not accept a model"
543 " as defined by the StepperBase interface!");
547 template<
class Scalar>
548 RCP<const Thyra::ModelEvaluator<Scalar> >
549 StackedStepper<Scalar>::getModel()
const
551 TEUCHOS_TEST_FOR_EXCEPT(
true);
552 return Teuchos::null;
556 template<
class Scalar>
557 RCP<Thyra::ModelEvaluator<Scalar> >
558 StackedStepper<Scalar>::getNonconstModel()
560 TEUCHOS_TEST_FOR_EXCEPT(
true);
561 return Teuchos::null;
565 template<
class Scalar>
566 void StackedStepper<Scalar>::setInitialCondition(
567 const Thyra::ModelEvaluatorBase::InArgs<Scalar> &stacked_ic
570 TEUCHOS_TEST_FOR_EXCEPT(
true);
574 template<
class Scalar>
575 Thyra::ModelEvaluatorBase::InArgs<Scalar>
576 StackedStepper<Scalar>::getInitialCondition()
const
578 TEUCHOS_TEST_FOR_EXCEPT(
true);
579 Thyra::ModelEvaluatorBase::InArgs<Scalar> inArgs;
584 template<
class Scalar>
586 StackedStepper<Scalar>::takeStep(
587 Scalar dt, StepSizeType stepType
590 typedef Teuchos::ScalarTraits<Scalar> ST;
592 TEUCHOS_TEST_FOR_EXCEPTION( stepperArray_.size() == 0, std::logic_error,
593 "Error! Rythmos::StackedStepper::takeStep: "
594 "addStepper must be called at least once before takeStep!"
596 this->setupSpaces_();
598 RYTHMOS_FUNC_TIME_MONITOR(
"Rythmos:StackedStepper::takeStep");
600 if (Teuchos::is_null(stackedStepperStepStrategy_)) {
601 stackedStepperStepStrategy_ = defaultStackedStepperStepStrategy<Scalar>();
604 Scalar dt_taken = Scalar(-ST::one());
605 for (
int i=0 ; i<Teuchos::as<int>(stepperArray_.size()) ; ++i) {
606 stackedStepperStepStrategy_->setupNextStepper(i,stepperArray_);
607 Scalar local_dt_taken = stepperArray_[i]->takeStep(dt,stepType);
608 dt_taken = stackedStepperStepStrategy_->evaluateStep(
630 template<
class Scalar>
631 const StepStatus<Scalar>
632 StackedStepper<Scalar>::getStepStatus()
const
634 TEUCHOS_TEST_FOR_EXCEPT(
true);
635 const StepStatus<Scalar> stepStatus;
644 template<
class Scalar>
645 RCP<const Thyra::VectorSpaceBase<Scalar> >
646 StackedStepper<Scalar>::get_x_space()
const
648 this->setupSpaces_();
649 TEUCHOS_TEST_FOR_EXCEPTION( is_null(x_bar_space_), std::logic_error,
650 "Rythmos::StackedStepper::get_x_space(): "
651 "addStepper must be called at least once before get_x_space()!"
653 return(x_bar_space_);
657 template<
class Scalar>
658 void StackedStepper<Scalar>::addPoints(
659 const Array<Scalar>& time_vec,
660 const Array<Teuchos::RCP<
const Thyra::VectorBase<Scalar> > >& x_vec,
661 const Array<Teuchos::RCP<
const Thyra::VectorBase<Scalar> > >& xdot_vec
664 TEUCHOS_TEST_FOR_EXCEPT(
665 "Not implemented addPoints(...) yet but we could if we wanted!"
670 template<
class Scalar>
672 StackedStepper<Scalar>::getTimeRange()
const
674 TEUCHOS_TEST_FOR_EXCEPT(
true);
675 TimeRange<Scalar> tr;
680 template<
class Scalar>
681 void StackedStepper<Scalar>::getPoints(
682 const Array<Scalar>& time_vec,
683 Array<RCP<
const Thyra::VectorBase<Scalar> > >* x_bar_vec,
684 Array<RCP<
const Thyra::VectorBase<Scalar> > >* x_bar_dot_vec,
685 Array<ScalarMag>* accuracy_vec
689 this->setupSpaces_();
690 TEUCHOS_TEST_FOR_EXCEPTION( stepperArray_.size() == 0, std::logic_error,
691 "Rythmos::StackedStepper:getPoints: Error! "
692 "addStepper must be called at least once before getPoints!"
694 int numSteppers = as<int>(stepperArray_.size());
695 int numTimePoints = as<int>(time_vec.size());
698 Array<RCP<Thyra::VectorBase<Scalar> > > x_bar_vec_local;
699 if (x_bar_vec != NULL) {
700 x_bar_vec_local.clear();
702 for (
int n = 0 ; n < numTimePoints ; ++n) {
703 x_bar_vec_local.push_back(Thyra::createMember(this->get_x_space()));
704 x_bar_vec->push_back(x_bar_vec_local[n]);
709 Array<RCP<Thyra::VectorBase<Scalar> > > x_bar_dot_vec_local;
710 if (x_bar_dot_vec != NULL) {
711 x_bar_dot_vec_local.clear();
712 x_bar_dot_vec->clear();
713 for (
int n = 0 ; n < numTimePoints ; ++n) {
714 x_bar_dot_vec_local.push_back(Thyra::createMember(this->get_x_space()));
715 x_bar_dot_vec->push_back(x_bar_dot_vec_local[n]);
721 accuracy_vec->clear();
722 accuracy_vec->resize(numTimePoints);
725 for (
int i=0 ; i < numSteppers; ++i) {
726 Array<RCP<const Thyra::VectorBase<Scalar> > > sub_x_bar_vec;
727 Array<RCP<const Thyra::VectorBase<Scalar> > > sub_x_bar_dot_vec;
728 Array<ScalarMag> sub_accuracy_vec;
729 stepperArray_[i]->getPoints(
731 x_bar_vec ? &sub_x_bar_vec : 0,
732 x_bar_dot_vec ? &sub_x_bar_dot_vec : 0,
733 accuracy_vec ? &sub_accuracy_vec: 0
737 for (
int n=0; n < numTimePoints ; ++n ) {
739 RCP<Thyra::ProductVectorBase<Scalar> > x_bar_pv =
740 Teuchos::rcp_dynamic_cast<Thyra::ProductVectorBase<Scalar> >(
744 RCP<Thyra::VectorBase<Scalar> > xi =
745 x_bar_pv->getNonconstVectorBlock(i);
746 V_V(Teuchos::outArg(*xi),*sub_x_bar_vec[n]);
749 RCP<Thyra::ProductVectorBase<Scalar> > x_bar_dot_pv =
750 Teuchos::rcp_dynamic_cast<Thyra::ProductVectorBase<Scalar> >(
751 x_bar_dot_vec_local[n],
754 RCP<Thyra::VectorBase<Scalar> > xdoti =
755 x_bar_dot_pv->getNonconstVectorBlock(i);
756 V_V(Teuchos::outArg(*xdoti),*sub_x_bar_dot_vec[n]);
759 if ( (i == 0) && accuracy_vec) {
760 (*accuracy_vec)[n] = sub_accuracy_vec[n];
767 template<
class Scalar>
768 void StackedStepper<Scalar>::getNodes(
769 Array<Scalar>* time_vec
772 TEUCHOS_TEST_FOR_EXCEPT(
true);
776 template<
class Scalar>
777 void StackedStepper<Scalar>::removeNodes(
778 Array<Scalar>& time_vec
781 TEUCHOS_TEST_FOR_EXCEPT(
"Not implemented yet but we can!");
785 template<
class Scalar>
786 int StackedStepper<Scalar>::getOrder()
const
788 TEUCHOS_TEST_FOR_EXCEPT(
true);
799 #endif //RYTHMOS_STACKED_STEPPER_HPP
virtual 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)=0
Add points to the buffer.