00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #ifndef RYTHMOS_DIAGONALIMPLICITRK_MODEL_EVALUATOR_HPP
00031 #define RYTHMOS_DIAGONALIMPLICITRK_MODEL_EVALUATOR_HPP
00032
00033
00034 #include "Rythmos_Types.hpp"
00035 #include "Rythmos_RKButcherTableauHelpers.hpp"
00036 #include "Thyra_StateFuncModelEvaluatorBase.hpp"
00037 #include "Thyra_ModelEvaluatorHelpers.hpp"
00038 #include "Thyra_ModelEvaluatorDelegatorBase.hpp"
00039 #include "Thyra_DefaultProductVectorSpace.hpp"
00040 #include "Thyra_DefaultBlockedLinearOp.hpp"
00041 #include "Thyra_VectorStdOps.hpp"
00042 #include "Thyra_TestingTools.hpp"
00043 #include "Teuchos_as.hpp"
00044 #include "Teuchos_SerialDenseMatrix.hpp"
00045 #include "Teuchos_SerialDenseVector.hpp"
00046 #include "Teuchos_Assert.hpp"
00047
00048
00049 namespace Rythmos {
00050
00051
00053 template<class Scalar>
00054 class DiagonalImplicitRKModelEvaluator : virtual public Thyra::StateFuncModelEvaluatorBase<Scalar>
00055 {
00056 public:
00057
00060
00062 DiagonalImplicitRKModelEvaluator();
00063
00065 void initializeDIRKModel(
00066 const RCP<const Thyra::ModelEvaluator<Scalar> > &daeModel,
00067 const Thyra::ModelEvaluatorBase::InArgs<Scalar> &basePoint,
00068 const RCP<Thyra::LinearOpWithSolveFactoryBase<Scalar> > &dirk_W_factory,
00069 const RCP<const RKButcherTableauBase<Scalar> > &irkButcherTableau
00070 );
00071
00073 void setTimeStepPoint(
00074 const RCP<const Thyra::VectorBase<Scalar> > &x_old,
00075 const Scalar &t_old,
00076 const Scalar &delta_t
00077 );
00078
00080 void setStageSolution(
00081 int stageNumber,
00082 const Thyra::VectorBase<Scalar>& stage_solution
00083 );
00084
00086 void setCurrentStage(
00087 int currentStage
00088 );
00089
00091
00094
00096 RCP<const Thyra::VectorSpaceBase<Scalar> > get_x_space() const;
00098 RCP<const Thyra::VectorSpaceBase<Scalar> > get_f_space() const;
00100 RCP<Thyra::LinearOpBase<Scalar> > create_W_op() const;
00102 RCP<const Thyra::LinearOpWithSolveFactoryBase<Scalar> > get_W_factory() const;
00104 Thyra::ModelEvaluatorBase::InArgs<Scalar> getNominalValues() const;
00106 Thyra::ModelEvaluatorBase::InArgs<Scalar> createInArgs() const;
00107
00109
00110 private:
00111
00114
00116 Thyra::ModelEvaluatorBase::OutArgs<Scalar> createOutArgsImpl() const;
00118 void evalModelImpl(
00119 const Thyra::ModelEvaluatorBase::InArgs<Scalar>& inArgs,
00120 const Thyra::ModelEvaluatorBase::OutArgs<Scalar>& outArgs
00121 ) const;
00122
00124
00125
00126 private:
00127
00128 RCP<const Thyra::ModelEvaluator<Scalar> > daeModel_;
00129 Thyra::ModelEvaluatorBase::InArgs<Scalar> basePoint_;
00130 RCP<Thyra::LinearOpWithSolveFactoryBase<Scalar> > dirk_W_factory_;
00131 RCP<const RKButcherTableauBase<Scalar> > dirkButcherTableau_;
00132
00133 Thyra::ModelEvaluatorBase::InArgs<Scalar> inArgs_;
00134 Thyra::ModelEvaluatorBase::OutArgs<Scalar> outArgs_;
00135 Thyra::ModelEvaluatorBase::InArgs<Scalar> nominalValues_;
00136
00137 RCP<const Thyra::ProductVectorSpaceBase<Scalar> > stage_space_;
00138 RCP<Thyra::ProductVectorBase<Scalar> > stage_derivatives_;
00139
00140 bool setTimeStepPointCalled_;
00141 RCP<const Thyra::VectorBase<Scalar> > x_old_;
00142 Scalar t_old_;
00143 Scalar delta_t_;
00144 int currentStage_;
00145
00146 bool isInitialized_;
00147
00148 };
00149
00150
00155 template<class Scalar>
00156 RCP<DiagonalImplicitRKModelEvaluator<Scalar> >
00157 diagonalImplicitRKModelEvaluator(
00158 const RCP<const Thyra::ModelEvaluator<Scalar> > &daeModel,
00159 const Thyra::ModelEvaluatorBase::InArgs<Scalar> &basePoint,
00160 const RCP<Thyra::LinearOpWithSolveFactoryBase<Scalar> > &dirk_W_factory,
00161 const RCP<const RKButcherTableauBase<Scalar> > &irkButcherTableau
00162 )
00163 {
00164 RCP<DiagonalImplicitRKModelEvaluator<Scalar> >
00165 dirkModel = rcp(new DiagonalImplicitRKModelEvaluator<Scalar>());
00166 dirkModel->initializeDIRKModel(daeModel,basePoint,dirk_W_factory,irkButcherTableau);
00167 return dirkModel;
00168 }
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178 template<class Scalar>
00179 DiagonalImplicitRKModelEvaluator<Scalar>::DiagonalImplicitRKModelEvaluator()
00180 {
00181 setTimeStepPointCalled_ = false;
00182 isInitialized_ = false;
00183 currentStage_ = -1;
00184 }
00185
00186
00187
00188
00189
00190 template<class Scalar>
00191 void DiagonalImplicitRKModelEvaluator<Scalar>::initializeDIRKModel(
00192 const RCP<const Thyra::ModelEvaluator<Scalar> > &daeModel,
00193 const Thyra::ModelEvaluatorBase::InArgs<Scalar> &basePoint,
00194 const RCP<Thyra::LinearOpWithSolveFactoryBase<Scalar> > &dirk_W_factory,
00195 const RCP<const RKButcherTableauBase<Scalar> > &irkButcherTableau
00196 )
00197 {
00198 typedef ScalarTraits<Scalar> ST;
00199
00200
00201 TEST_FOR_EXCEPTION(
00202 is_null(basePoint.get_x()),
00203 std::logic_error,
00204 "Error! The basepoint x vector is null!"
00205 );
00206 TEST_FOR_EXCEPTION(
00207 is_null(daeModel),
00208 std::logic_error,
00209 "Error! The model evaluator pointer is null!"
00210 );
00211 TEST_FOR_EXCEPTION(
00212 !daeModel->get_x_space()->isCompatible(*(basePoint.get_x()->space())),
00213 std::logic_error,
00214 "Error! The basepoint input arguments are incompatible with the model evaluator vector space!"
00215 );
00216
00217
00218 daeModel_ = daeModel;
00219 basePoint_ = basePoint;
00220 dirk_W_factory_ = dirk_W_factory;
00221 dirkButcherTableau_ = irkButcherTableau;
00222
00223 const int numStages = dirkButcherTableau_->numStages();
00224
00225 using Teuchos::rcp_dynamic_cast;
00226 stage_space_ = productVectorSpace(daeModel_->get_x_space(),numStages);
00227 RCP<const Thyra::VectorSpaceBase<Scalar> > vs = rcp_dynamic_cast<const Thyra::VectorSpaceBase<Scalar> >(stage_space_,true);
00228 stage_derivatives_ = rcp_dynamic_cast<Thyra::ProductVectorBase<Scalar> >(createMember(vs),true);
00229 Thyra::V_S(&*stage_derivatives_,ST::zero());
00230
00231
00232 {
00233 typedef Thyra::ModelEvaluatorBase MEB;
00234 MEB::InArgsSetup<Scalar> inArgs;
00235 inArgs.setModelEvalDescription(this->description());
00236 inArgs.setSupports(MEB::IN_ARG_x);
00237 inArgs_ = inArgs;
00238 }
00239
00240 {
00241 typedef Thyra::ModelEvaluatorBase MEB;
00242 MEB::OutArgsSetup<Scalar> outArgs;
00243 outArgs.setModelEvalDescription(this->description());
00244 outArgs.setSupports(MEB::OUT_ARG_f);
00245 outArgs.setSupports(MEB::OUT_ARG_W_op);
00246 outArgs_ = outArgs;
00247 }
00248
00249 nominalValues_ = inArgs_;
00250
00251 isInitialized_ = true;
00252 }
00253
00254
00255 template<class Scalar>
00256 void DiagonalImplicitRKModelEvaluator<Scalar>::setTimeStepPoint(
00257 const RCP<const Thyra::VectorBase<Scalar> > &x_old,
00258 const Scalar &t_old,
00259 const Scalar &delta_t
00260 )
00261 {
00262 typedef ScalarTraits<Scalar> ST;
00263 TEST_FOR_EXCEPT( is_null(x_old) );
00264 TEST_FOR_EXCEPT( delta_t <= ST::zero() );
00265
00266 TEST_FOR_EXCEPTION(!daeModel_->get_x_space()->isCompatible(*(x_old->space())), std::logic_error,
00267 "Error! The incoming VectorBase object is not compatible with the DAE model that was provided at initialization!");
00268 x_old_ = x_old;
00269 t_old_ = t_old;
00270 delta_t_ = delta_t;
00271 setTimeStepPointCalled_ = true;
00272 }
00273
00274 template<class Scalar>
00275 void DiagonalImplicitRKModelEvaluator<Scalar>::setStageSolution(
00276 int stageNumber,
00277 const Thyra::VectorBase<Scalar>& stage_solution
00278 )
00279 {
00280 TEST_FOR_EXCEPT(stageNumber < 0);
00281 TEST_FOR_EXCEPT(stageNumber >= dirkButcherTableau_->numStages());
00282 Thyra::V_V(&*(stage_derivatives_->getNonconstVectorBlock(stageNumber)),stage_solution);
00283 }
00284
00285 template<class Scalar>
00286 void DiagonalImplicitRKModelEvaluator<Scalar>::setCurrentStage(
00287 int currentStage
00288 )
00289 {
00290 TEST_FOR_EXCEPT(currentStage < 0);
00291 TEST_FOR_EXCEPT(currentStage >= dirkButcherTableau_->numStages());
00292 currentStage_ = currentStage;
00293 }
00294
00295
00296
00297
00298
00299
00300 template<class Scalar>
00301 RCP<const Thyra::VectorSpaceBase<Scalar> >
00302 DiagonalImplicitRKModelEvaluator<Scalar>::get_x_space() const
00303 {
00304 TEST_FOR_EXCEPTION( !isInitialized_, std::logic_error,
00305 "Error, initializeDIRKModel must be called first!\n"
00306 );
00307 return daeModel_->get_x_space();
00308 }
00309
00310
00311 template<class Scalar>
00312 RCP<const Thyra::VectorSpaceBase<Scalar> >
00313 DiagonalImplicitRKModelEvaluator<Scalar>::get_f_space() const
00314 {
00315 TEST_FOR_EXCEPTION( !isInitialized_, std::logic_error,
00316 "Error, initializeDIRKModel must be called first!\n"
00317 );
00318 return daeModel_->get_f_space();
00319 }
00320
00321
00322 template<class Scalar>
00323 RCP<Thyra::LinearOpBase<Scalar> >
00324 DiagonalImplicitRKModelEvaluator<Scalar>::create_W_op() const
00325 {
00326 TEST_FOR_EXCEPTION( !isInitialized_, std::logic_error,
00327 "Error, initializeDIRKModel must be called first!\n"
00328 );
00329 return daeModel_->create_W_op();
00330 }
00331
00332
00333 template<class Scalar>
00334 RCP<const Thyra::LinearOpWithSolveFactoryBase<Scalar> >
00335 DiagonalImplicitRKModelEvaluator<Scalar>::get_W_factory() const
00336 {
00337 TEST_FOR_EXCEPTION( !isInitialized_, std::logic_error,
00338 "Error, initializeDIRKModel must be called first!\n"
00339 );
00340 return daeModel_->get_W_factory();
00341 }
00342
00343
00344 template<class Scalar>
00345 Thyra::ModelEvaluatorBase::InArgs<Scalar>
00346 DiagonalImplicitRKModelEvaluator<Scalar>::getNominalValues() const
00347 {
00348 TEST_FOR_EXCEPTION( !isInitialized_, std::logic_error,
00349 "Error, initializeDIRKModel must be called first!\n"
00350 );
00351 return nominalValues_;
00352 }
00353
00354
00355 template<class Scalar>
00356 Thyra::ModelEvaluatorBase::InArgs<Scalar>
00357 DiagonalImplicitRKModelEvaluator<Scalar>::createInArgs() const
00358 {
00359 TEST_FOR_EXCEPTION( !isInitialized_, std::logic_error,
00360 "Error, initializeDIRKModel must be called first!\n"
00361 );
00362 return inArgs_;
00363 }
00364
00365
00366
00367
00368
00369 template<class Scalar>
00370 Thyra::ModelEvaluatorBase::OutArgs<Scalar>
00371 DiagonalImplicitRKModelEvaluator<Scalar>::createOutArgsImpl() const
00372 {
00373 TEST_FOR_EXCEPTION( !isInitialized_, std::logic_error,
00374 "Error, initializeDIRKModel must be called first!\n"
00375 );
00376 return outArgs_;
00377 }
00378
00379
00380 template<class Scalar>
00381 void DiagonalImplicitRKModelEvaluator<Scalar>::evalModelImpl(
00382 const Thyra::ModelEvaluatorBase::InArgs<Scalar>& inArgs_stage,
00383 const Thyra::ModelEvaluatorBase::OutArgs<Scalar>& outArgs_stage
00384 ) const
00385 {
00386
00387 typedef ScalarTraits<Scalar> ST;
00388 typedef Thyra::ModelEvaluatorBase MEB;
00389
00390 TEST_FOR_EXCEPTION( !isInitialized_, std::logic_error,
00391 "Error! initializeDIRKModel must be called before evalModel\n"
00392 );
00393
00394 TEST_FOR_EXCEPTION( !setTimeStepPointCalled_, std::logic_error,
00395 "Error! setTimeStepPoint must be called before evalModel"
00396 );
00397
00398 TEST_FOR_EXCEPTION( currentStage_ == -1, std::logic_error,
00399 "Error! setCurrentStage must be called before evalModel"
00400 );
00401
00402 THYRA_MODEL_EVALUATOR_DECORATOR_EVAL_MODEL_GEN_BEGIN(
00403 "Rythmos::DiagonalImplicitRKModelEvaluator",inArgs_stage,outArgs_stage,daeModel_
00404 );
00405
00406
00407
00408
00409
00410 const RCP<const Thyra::VectorBase<Scalar> > x_in = inArgs_stage.get_x();
00411 const RCP<Thyra::VectorBase<Scalar> > f_out = outArgs_stage.get_f();
00412 const RCP<Thyra::LinearOpBase<Scalar> > W_op_out = outArgs_stage.get_W_op();
00413
00414
00415
00416
00417
00418 MEB::InArgs<Scalar> daeInArgs = daeModel_->createInArgs();
00419 MEB::OutArgs<Scalar> daeOutArgs = daeModel_->createOutArgs();
00420 const RCP<Thyra::VectorBase<Scalar> > x_i = createMember(daeModel_->get_x_space());
00421 daeInArgs.setArgs(basePoint_);
00422
00423
00424 V_V(&*(stage_derivatives_->getNonconstVectorBlock(currentStage_)),*x_in);
00425 assembleIRKState( currentStage_, dirkButcherTableau_->A(), delta_t_, *x_old_, *stage_derivatives_, outArg(*x_i) );
00426 daeInArgs.set_x( x_i );
00427 daeInArgs.set_x_dot( x_in );
00428 daeInArgs.set_t( t_old_ + dirkButcherTableau_->c()(currentStage_) * delta_t_ );
00429 daeInArgs.set_alpha(ST::one());
00430 daeInArgs.set_beta( delta_t_ * dirkButcherTableau_->A()(currentStage_,currentStage_) );
00431
00432
00433 if (!is_null(f_out))
00434 daeOutArgs.set_f( f_out );
00435 if (!is_null(W_op_out))
00436 daeOutArgs.set_W_op(W_op_out);
00437
00438
00439 daeModel_->evalModel( daeInArgs, daeOutArgs );
00440 daeOutArgs.set_f(Teuchos::null);
00441 daeOutArgs.set_W_op(Teuchos::null);
00442
00443 THYRA_MODEL_EVALUATOR_DECORATOR_EVAL_MODEL_END();
00444
00445 }
00446
00447
00448 }
00449
00450
00451 #endif // RYTHMOS_DIAGONALIMPLICITRK_MODEL_EVALUATOR_HPP