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_IMPLICITRK_MODEL_EVALUATOR_HPP
00031 #define RYTHMOS_IMPLICITRK_MODEL_EVALUATOR_HPP
00032
00033
00034 #include "Rythmos_Types.hpp"
00035 #include "Rythmos_RKButcherTableau.hpp"
00036 #include "Thyra_StateFuncModelEvaluatorBase.hpp"
00037 #include "Thyra_ModelEvaluatorHelpers.hpp"
00038 #include "Thyra_DefaultProductVectorSpace.hpp"
00039 #include "Thyra_DefaultBlockedLinearOp.hpp"
00040 #include "Thyra_VectorStdOps.hpp"
00041 #include "Thyra_TestingTools.hpp"
00042 #include "Teuchos_as.hpp"
00043 #include "Teuchos_SerialDenseMatrix.hpp"
00044 #include "Teuchos_SerialDenseVector.hpp"
00045 #include "Teuchos_Assert.hpp"
00046
00047
00048 namespace Rythmos {
00049
00050
00052 template<class Scalar>
00053 class ImplicitRKModelEvaluator : virtual public Thyra::StateFuncModelEvaluatorBase<Scalar>
00054 {
00055 public:
00056
00059
00061 ImplicitRKModelEvaluator();
00062
00064 void initializeIRKModel(
00065 const RCP<const Thyra::ModelEvaluator<Scalar> > &daeModel,
00066 const Thyra::ModelEvaluatorBase::InArgs<Scalar> &basePoint,
00067 const RCP<Thyra::LinearOpWithSolveFactoryBase<Scalar> > &irk_W_factory,
00068 const RKButcherTableau<Scalar> &irkButcherTableau
00069 );
00070
00072 void setTimeStepPoint(
00073 const RCP<const Thyra::VectorBase<Scalar> > &x_old,
00074 const Scalar &t_old,
00075 const Scalar &delta_t
00076 );
00077
00079
00082
00084 RCP<const Thyra::VectorSpaceBase<Scalar> > get_x_space() const;
00086 RCP<const Thyra::VectorSpaceBase<Scalar> > get_f_space() const;
00088 RCP<Thyra::LinearOpBase<Scalar> > create_W_op() const;
00090 RCP<const Thyra::LinearOpWithSolveFactoryBase<Scalar> > get_W_factory() const;
00092 Thyra::ModelEvaluatorBase::InArgs<Scalar> getNominalValues() const;
00094 Thyra::ModelEvaluatorBase::InArgs<Scalar> createInArgs() const;
00095
00097
00098 private:
00099
00102
00104 Thyra::ModelEvaluatorBase::OutArgs<Scalar> createOutArgsImpl() const;
00106 void evalModelImpl(
00107 const Thyra::ModelEvaluatorBase::InArgs<Scalar>& inArgs,
00108 const Thyra::ModelEvaluatorBase::OutArgs<Scalar>& outArgs
00109 ) const;
00110
00112
00113
00114 private:
00115
00116 RCP<const Thyra::ModelEvaluator<Scalar> > daeModel_;
00117 Thyra::ModelEvaluatorBase::InArgs<Scalar> basePoint_;
00118 RCP<Thyra::LinearOpWithSolveFactoryBase<Scalar> > irk_W_factory_;
00119 RKButcherTableau<Scalar> irkButcherTableau_;
00120
00121 RCP<const Thyra::ProductVectorSpaceBase<Scalar> > x_bar_space_;
00122 RCP<const Thyra::ProductVectorSpaceBase<Scalar> > f_bar_space_;
00123 RCP<Thyra::LinearOpWithSolveFactoryBase<Scalar> > W_bar_factory_;
00124
00125 Thyra::ModelEvaluatorBase::InArgs<Scalar> nominalValues_;
00126
00127 bool setTimeStepPointCalled_;
00128 RCP<const Thyra::VectorBase<Scalar> > x_old_;
00129 Scalar t_old_;
00130 Scalar delta_t_;
00131
00132 };
00133
00134
00139 template<class Scalar>
00140 RCP<ImplicitRKModelEvaluator<Scalar> >
00141 implicitRKModelEvaluator(
00142 const RCP<const Thyra::ModelEvaluator<Scalar> > &daeModel,
00143 const Thyra::ModelEvaluatorBase::InArgs<Scalar> &basePoint,
00144 const RCP<Thyra::LinearOpWithSolveFactoryBase<Scalar> > &irk_W_factory,
00145 const RKButcherTableau<Scalar> &irkButcherTableau
00146 )
00147 {
00148 RCP<ImplicitRKModelEvaluator<Scalar> >
00149 irkModel = rcp(new ImplicitRKModelEvaluator<Scalar>());
00150 irkModel->initializeIRKModel(daeModel,basePoint,irk_W_factory,irkButcherTableau);
00151 return irkModel;
00152 }
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162 template<class Scalar>
00163 ImplicitRKModelEvaluator<Scalar>::ImplicitRKModelEvaluator()
00164 {
00165 setTimeStepPointCalled_ = false;
00166 }
00167
00168
00169
00170
00171
00172 template<class Scalar>
00173 void ImplicitRKModelEvaluator<Scalar>::initializeIRKModel(
00174 const RCP<const Thyra::ModelEvaluator<Scalar> > &daeModel,
00175 const Thyra::ModelEvaluatorBase::InArgs<Scalar> &basePoint,
00176 const RCP<Thyra::LinearOpWithSolveFactoryBase<Scalar> > &irk_W_factory,
00177 const RKButcherTableau<Scalar> &irkButcherTableau
00178 )
00179 {
00180
00181
00182 TEST_FOR_EXCEPTION(
00183 is_null(basePoint.get_x()),
00184 std::logic_error,
00185 "Error! The basepoint x vector is null!"
00186 );
00187 TEST_FOR_EXCEPTION(
00188 is_null(daeModel),
00189 std::logic_error,
00190 "Error! The model evaluator pointer is null!"
00191 );
00192 TEST_FOR_EXCEPTION(
00193 !daeModel->get_x_space()->isCompatible(*(basePoint.get_x()->space())),
00194 std::logic_error,
00195 "Error! The basepoint input arguments are incompatible with the model evaluator vector space!"
00196 );
00197 TEST_FOR_EXCEPT(is_null(irk_W_factory));
00198
00199 daeModel_ = daeModel;
00200 basePoint_ = basePoint;
00201 irk_W_factory_ = irk_W_factory;
00202 irkButcherTableau_ = irkButcherTableau;
00203
00204 const int numStages = irkButcherTableau_.numStages();
00205
00206 x_bar_space_ = productVectorSpace(daeModel_->get_x_space(),numStages);
00207 f_bar_space_ = productVectorSpace(daeModel_->get_f_space(),numStages);
00208
00209
00210 if (irk_W_factory_->acceptsPreconditionerFactory())
00211 irk_W_factory_->unsetPreconditionerFactory();
00212
00213
00214
00215
00216 }
00217
00218
00219 template<class Scalar>
00220 void ImplicitRKModelEvaluator<Scalar>::setTimeStepPoint(
00221 const RCP<const Thyra::VectorBase<Scalar> > &x_old,
00222 const Scalar &t_old,
00223 const Scalar &delta_t
00224 )
00225 {
00226 typedef ScalarTraits<Scalar> ST;
00227 TEST_FOR_EXCEPT( is_null(x_old) );
00228 TEST_FOR_EXCEPT( delta_t <= ST::zero() );
00229
00230 TEST_FOR_EXCEPTION(!daeModel_->get_x_space()->isCompatible(*(x_old->space())), std::logic_error,
00231 "Error! The incoming VectorBase object is not compatible with the DAE model that was provided at initialization!");
00232 x_old_ = x_old;
00233 t_old_ = t_old;
00234 delta_t_ = delta_t;
00235 setTimeStepPointCalled_ = true;
00236 }
00237
00238
00239
00240
00241
00242 template<class Scalar>
00243 RCP<const Thyra::VectorSpaceBase<Scalar> >
00244 ImplicitRKModelEvaluator<Scalar>::get_x_space() const
00245 {
00246 return x_bar_space_;
00247 }
00248
00249
00250 template<class Scalar>
00251 RCP<const Thyra::VectorSpaceBase<Scalar> >
00252 ImplicitRKModelEvaluator<Scalar>::get_f_space() const
00253 {
00254 return f_bar_space_;
00255 }
00256
00257
00258 template<class Scalar>
00259 RCP<Thyra::LinearOpBase<Scalar> >
00260 ImplicitRKModelEvaluator<Scalar>::create_W_op() const
00261 {
00262
00263 const int numStages = irkButcherTableau_.numStages();
00264 RCP<Thyra::PhysicallyBlockedLinearOpBase<Scalar> >
00265 W_op_bar = Thyra::defaultBlockedLinearOp<Scalar>();
00266 W_op_bar->beginBlockFill( f_bar_space_, x_bar_space_ );
00267 for ( int i = 0; i < numStages; ++i )
00268 for ( int j = 0; j < numStages; ++j )
00269 W_op_bar->setNonconstBlock( i, j, daeModel_->create_W_op() );
00270 W_op_bar->endBlockFill();
00271 return W_op_bar;
00272 }
00273
00274
00275 template<class Scalar>
00276 RCP<const Thyra::LinearOpWithSolveFactoryBase<Scalar> >
00277 ImplicitRKModelEvaluator<Scalar>::get_W_factory() const
00278 {
00279 return irk_W_factory_;
00280 }
00281
00282
00283 template<class Scalar>
00284 Thyra::ModelEvaluatorBase::InArgs<Scalar>
00285 ImplicitRKModelEvaluator<Scalar>::getNominalValues() const
00286 {
00287 return nominalValues_;
00288 }
00289
00290
00291 template<class Scalar>
00292 Thyra::ModelEvaluatorBase::InArgs<Scalar>
00293 ImplicitRKModelEvaluator<Scalar>::createInArgs() const
00294 {
00295 typedef Thyra::ModelEvaluatorBase MEB;
00296 MEB::InArgsSetup<Scalar> inArgs;
00297 inArgs.setModelEvalDescription(this->description());
00298 inArgs.setSupports(MEB::IN_ARG_x);
00299 return inArgs;
00300 }
00301
00302
00303
00304
00305
00306 template<class Scalar>
00307 Thyra::ModelEvaluatorBase::OutArgs<Scalar>
00308 ImplicitRKModelEvaluator<Scalar>::createOutArgsImpl() const
00309 {
00310 typedef Thyra::ModelEvaluatorBase MEB;
00311 MEB::OutArgsSetup<Scalar> outArgs;
00312 outArgs.setModelEvalDescription(this->description());
00313 outArgs.setSupports(MEB::OUT_ARG_f);
00314 outArgs.setSupports(MEB::OUT_ARG_W_op);
00315 return outArgs;
00316 }
00317
00318
00319 template<class Scalar>
00320 void ImplicitRKModelEvaluator<Scalar>::evalModelImpl(
00321 const Thyra::ModelEvaluatorBase::InArgs<Scalar>& inArgs_bar,
00322 const Thyra::ModelEvaluatorBase::OutArgs<Scalar>& outArgs_bar
00323 ) const
00324 {
00325
00326 using Teuchos::rcp_dynamic_cast;
00327 typedef ScalarTraits<Scalar> ST;
00328 typedef Thyra::ModelEvaluatorBase MEB;
00329 typedef Thyra::VectorBase<Scalar> VB;
00330 typedef Thyra::ProductVectorBase<Scalar> PVB;
00331 typedef Thyra::BlockedLinearOpBase<Scalar> BLWB;
00332
00333 TEST_FOR_EXCEPTION( !setTimeStepPointCalled_, std::logic_error,
00334 "Error! setTimeStepPoint must be called before evalModel"
00335 );
00336
00337 THYRA_MODEL_EVALUATOR_DECORATOR_EVAL_MODEL_GEN_BEGIN(
00338 "Rythmos::ImplicitRKModelEvaluator",inArgs_bar,outArgs_bar,daeModel_
00339 );
00340
00341
00342
00343
00344
00345 const RCP<const PVB> x_bar = rcp_dynamic_cast<const PVB>(inArgs_bar.get_x(), true);
00346 const RCP<PVB> f_bar = rcp_dynamic_cast<PVB>(outArgs_bar.get_f(), true);
00347 const RCP<BLWB> W_op_bar = rcp_dynamic_cast<BLWB>(outArgs_bar.get_W_op(), true);
00348
00349
00350
00351
00352
00353 MEB::InArgs<Scalar> daeInArgs = daeModel_->createInArgs();
00354 MEB::OutArgs<Scalar> daeOutArgs = daeModel_->createOutArgs();
00355 const RCP<VB> x_i = createMember(daeModel_->get_x_space());
00356 daeInArgs.setArgs(basePoint_);
00357
00358 const int numStages = irkButcherTableau_.numStages();
00359
00360 for ( int i = 0; i < numStages; ++i ) {
00361
00362
00363 assembleIRKState( i, irkButcherTableau_.A(), delta_t_, *x_old_, *x_bar, outArg(*x_i) );
00364 daeInArgs.set_x( x_i );
00365 daeInArgs.set_x_dot( x_bar->getVectorBlock(i) );
00366 daeInArgs.set_t( t_old_ + irkButcherTableau_.c()(i) * delta_t_ );
00367 daeInArgs.set_alpha(ST::one());
00368 daeInArgs.set_beta( delta_t_ * irkButcherTableau_.A()(i,0) );
00369
00370
00371 if (!is_null(f_bar))
00372 daeOutArgs.set_f( f_bar->getNonconstVectorBlock(i) );
00373 if (!is_null(W_op_bar))
00374 daeOutArgs.set_W_op(W_op_bar->getNonconstBlock(i,0));
00375
00376
00377 daeModel_->evalModel( daeInArgs, daeOutArgs );
00378 daeOutArgs.set_f(Teuchos::null);
00379 daeOutArgs.set_W_op(Teuchos::null);
00380
00381
00382 if (!is_null(W_op_bar)) {
00383 for ( int j = 1; j < numStages; ++j ) {
00384 daeInArgs.set_beta( delta_t_ * irkButcherTableau_.A()(i,j) );
00385 daeOutArgs.set_W_op(W_op_bar->getNonconstBlock(i,j));
00386 daeModel_->evalModel( daeInArgs, daeOutArgs );
00387 daeOutArgs.set_W_op(Teuchos::null);
00388 }
00389 }
00390
00391 }
00392
00393 THYRA_MODEL_EVALUATOR_DECORATOR_EVAL_MODEL_END();
00394
00395 }
00396
00397
00398 }
00399
00400
00401 #endif // RYTHMOS_IMPLICITRK_MODEL_EVALUATOR_HPP