00001
00002 #ifndef RYTHMOS_SIMPLE_INTEGRATION_CONTROL_STRATEGY_HPP
00003 #define RYTHMOS_SIMPLE_INTEGRATION_CONTROL_STRATEGY_HPP
00004
00005
00006 #include "Rythmos_IntegrationControlStrategyBase.hpp"
00007 #include "Rythmos_StepperBase.hpp"
00008 #include "Teuchos_ParameterListAcceptorDefaultBase.hpp"
00009 #include "Teuchos_VerboseObjectParameterListHelpers.hpp"
00010
00011
00012 namespace Rythmos {
00013
00014
00020 template<class Scalar>
00021 class SimpleIntegrationControlStrategy
00022 : virtual public IntegrationControlStrategyBase<Scalar>,
00023 virtual public Teuchos::ParameterListAcceptorDefaultBase
00024 {
00025 public:
00026
00029
00031 SimpleIntegrationControlStrategy();
00032
00034
00037
00039 void setParameterList(RCP<ParameterList> const& paramList);
00040
00042 RCP<const ParameterList> getValidParameters() const;
00043
00045
00048
00050 RCP<IntegrationControlStrategyBase<Scalar> >
00051 cloneIntegrationControlStrategy() const;
00052
00054 void resetIntegrationControlStrategy(
00055 const TimeRange<Scalar> &integrationTimeDomain
00056 );
00057
00059 StepControlInfo<Scalar>
00060 getNextStepControlInfo(
00061 const StepperBase<Scalar> &stepper,
00062 const StepControlInfo<Scalar> &stepCtrlInfoLast,
00063 const int timeStepIter
00064 );
00065
00067
00068 private:
00069
00070 bool takeVariableSteps_;
00071 Scalar max_dt_;
00072 int numTimeSteps_;
00073 Scalar fixed_dt_;
00074
00075 TimeRange<Scalar> integrationTimeDomain_;
00076
00077 static const std::string takeVariableSteps_name_;
00078 static const bool takeVariableSteps_default_;
00079
00080 static const std::string max_dt_name_;
00081 static const double max_dt_default_;
00082
00083 static const std::string numTimeSteps_name_;
00084 static const int numTimeSteps_default_;
00085
00086 static const std::string fixed_dt_name_;
00087 static const double fixed_dt_default_;
00088
00089 };
00090
00091
00096 template<class Scalar>
00097 RCP<SimpleIntegrationControlStrategy<Scalar> >
00098 simpleIntegrationControlStrategy()
00099 {
00100 RCP<SimpleIntegrationControlStrategy<Scalar> >
00101 integrationControl = Teuchos::rcp(new SimpleIntegrationControlStrategy<Scalar>());
00102 return integrationControl;
00103 }
00104
00105
00110 template<class Scalar>
00111 RCP<SimpleIntegrationControlStrategy<Scalar> >
00112 simpleIntegrationControlStrategy( const RCP<ParameterList> ¶mList )
00113 {
00114 RCP<SimpleIntegrationControlStrategy<Scalar> >
00115 integrationControl = Teuchos::rcp(new SimpleIntegrationControlStrategy<Scalar>());
00116 integrationControl->setParameterList(paramList);
00117 return integrationControl;
00118 }
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129 template<class Scalar>
00130 const std::string
00131 SimpleIntegrationControlStrategy<Scalar>::takeVariableSteps_name_
00132 = "Take Variable Steps";
00133
00134 template<class Scalar>
00135 const bool
00136 SimpleIntegrationControlStrategy<Scalar>::takeVariableSteps_default_
00137 = true;
00138
00139
00140 template<class Scalar>
00141 const std::string
00142 SimpleIntegrationControlStrategy<Scalar>::max_dt_name_
00143 = "Max dt";
00144
00145 template<class Scalar>
00146 const double
00147 SimpleIntegrationControlStrategy<Scalar>::max_dt_default_
00148 = std::numeric_limits<Scalar>::max();
00149
00150
00151 template<class Scalar>
00152 const std::string
00153 SimpleIntegrationControlStrategy<Scalar>::numTimeSteps_name_
00154 = "Number of Time Steps";
00155
00156 template<class Scalar>
00157 const int
00158 SimpleIntegrationControlStrategy<Scalar>::numTimeSteps_default_
00159 = -1;
00160
00161
00162 template<class Scalar>
00163 const std::string
00164 SimpleIntegrationControlStrategy<Scalar>::fixed_dt_name_
00165 = "Fixed dt";
00166
00167 template<class Scalar>
00168 const double
00169 SimpleIntegrationControlStrategy<Scalar>::fixed_dt_default_
00170 = -1.0;
00171
00172
00173
00174
00175
00176 template<class Scalar>
00177 SimpleIntegrationControlStrategy<Scalar>::SimpleIntegrationControlStrategy()
00178 :takeVariableSteps_(takeVariableSteps_default_),
00179 max_dt_(max_dt_default_),
00180 numTimeSteps_(numTimeSteps_default_),
00181 fixed_dt_(fixed_dt_default_)
00182 {}
00183
00184
00185
00186
00187
00188 template<class Scalar>
00189 void SimpleIntegrationControlStrategy<Scalar>::setParameterList(
00190 RCP<ParameterList> const& paramList
00191 )
00192 {
00193 using Teuchos::as;
00194 using Teuchos::get;
00195 typedef Teuchos::ScalarTraits<Scalar> ST;
00196 TEST_FOR_EXCEPT(is_null(paramList));
00197 paramList->validateParameters(*getValidParameters());
00198 this->setMyParamList(paramList);
00199 takeVariableSteps_ = paramList->get(
00200 takeVariableSteps_name_, takeVariableSteps_ );
00201 if (!takeVariableSteps_) {
00202 numTimeSteps_ = paramList->get(numTimeSteps_name_,numTimeSteps_);
00203 fixed_dt_ = paramList->get(fixed_dt_name_,fixed_dt_);
00204 TEST_FOR_EXCEPTION(
00205 numTimeSteps_ < 0 && fixed_dt_ <= ST::zero(), std::logic_error,
00206 "Error, when taking fixed steps, the user must set the parameters "
00207 "\""<<numTimeSteps_name_<<"\" > 0 or \""<<fixed_dt_name_<<"\" > 0.0!" );
00208 }
00209 else {
00210 max_dt_ = paramList->get(max_dt_name_,max_dt_);
00211 }
00212 Teuchos::readVerboseObjectSublist(&*paramList,this);
00213 }
00214
00215
00216 template<class Scalar>
00217 RCP<const ParameterList>
00218 SimpleIntegrationControlStrategy<Scalar>::getValidParameters() const
00219 {
00220 static RCP<const ParameterList> validPL;
00221 if (is_null(validPL) ) {
00222 RCP<ParameterList> pl = Teuchos::parameterList();
00223 pl->set(
00224 takeVariableSteps_name_, takeVariableSteps_default_,
00225 "Take variable time steps or fixed time steps.\n"
00226 "If set to false, then the parameter \"" + fixed_dt_name_ + "\"\n"
00227 "or \"" + numTimeSteps_name_ + "\" must be set!"
00228 );
00229 pl->set(
00230 max_dt_name_, max_dt_default_,
00231 "Gives the max size of the variable time steps. This is only read and used if\n"
00232 "\"" + takeVariableSteps_name_ + "\" is set to true."
00233 );
00234 pl->set(
00235 numTimeSteps_name_, numTimeSteps_default_,
00236 "Gives the number of fixed time steps. The actual step size gets computed\n"
00237 "on the fly given the size of the time domain.\n"
00238 "This is only read and used if \"" + takeVariableSteps_name_ + "\" is set to true\n"
00239 "and \"" + fixed_dt_name_ + "\" is not not to a number > 0.0."
00240 );
00241 pl->set(
00242 fixed_dt_name_, fixed_dt_default_,
00243 "Gives the size of the fixed time steps. This is only read and used if\n"
00244 "\"" + takeVariableSteps_name_ + "\" is set to false."
00245 );
00246 Teuchos::setupVerboseObjectSublist(&*pl);
00247 validPL = pl;
00248 }
00249 return validPL;
00250 }
00251
00252
00253
00254
00255
00256 template<class Scalar>
00257 RCP<IntegrationControlStrategyBase<Scalar> >
00258 SimpleIntegrationControlStrategy<Scalar>::cloneIntegrationControlStrategy() const
00259 {
00260 RCP<SimpleIntegrationControlStrategy<Scalar> >
00261 integrCtrlStry = simpleIntegrationControlStrategy<Scalar>();
00262 const RCP<const ParameterList> paramList = this->getParameterList();
00263 if (!is_null(paramList))
00264 integrCtrlStry->setParameterList(Teuchos::parameterList(*paramList));
00265 integrCtrlStry->takeVariableSteps_ = takeVariableSteps_;
00266 integrCtrlStry->max_dt_ = max_dt_;
00267 integrCtrlStry->numTimeSteps_ = numTimeSteps_;
00268 integrCtrlStry->fixed_dt_ = fixed_dt_;
00269 return integrCtrlStry;
00270 }
00271
00272
00273 template<class Scalar>
00274 void
00275 SimpleIntegrationControlStrategy<Scalar>::resetIntegrationControlStrategy(
00276 const TimeRange<Scalar> &integrationTimeDomain
00277 )
00278 {
00279 typedef Teuchos::ScalarTraits<Scalar> ST;
00280 #ifdef TEUCHOS_DEBUG
00281 TEUCHOS_ASSERT(integrationTimeDomain.length() > ST::zero());
00282 #endif
00283 integrationTimeDomain_ = integrationTimeDomain;
00284 if (takeVariableSteps_) {
00285 if (max_dt_ < ST::zero()) {
00286 max_dt_ = integrationTimeDomain_.length();
00287 }
00288 }
00289 else {
00290 if (fixed_dt_ < ST::zero()) {
00291 #ifdef TEUCHOS_DEBUG
00292 TEUCHOS_ASSERT(numTimeSteps_ > 0);
00293 #endif
00294 fixed_dt_ = integrationTimeDomain_.length()/numTimeSteps_;
00295 }
00296 }
00297 }
00298
00299
00300 template<class Scalar>
00301 StepControlInfo<Scalar>
00302 SimpleIntegrationControlStrategy<Scalar>::getNextStepControlInfo(
00303 const StepperBase<Scalar> &stepper,
00304 const StepControlInfo<Scalar> &stepCtrlInfoLast,
00305 const int timeStepIter
00306 )
00307 {
00308
00309 typedef Teuchos::ScalarTraits<Scalar> ST;
00310
00311 #ifdef TEUCHOS_DEBUG
00312 TEUCHOS_ASSERT(integrationTimeDomain_.length() > ST::zero());
00313 #endif
00314
00315 StepControlInfo<Scalar> trialStepCtrlInfo;
00316
00317 if (takeVariableSteps_) {
00318 trialStepCtrlInfo.stepType = STEP_TYPE_VARIABLE;
00319 trialStepCtrlInfo.stepSize = max_dt_;
00320 }
00321 else {
00322 trialStepCtrlInfo.stepType = STEP_TYPE_FIXED;
00323 trialStepCtrlInfo.stepSize = fixed_dt_;
00324 }
00325
00326 return trialStepCtrlInfo;
00327
00328 }
00329
00330
00331 }
00332
00333
00334 #endif // RYTHMOS_SIMPLE_INTEGRATION_CONTROL_STRATEGY_HPP