Rythmos_TimeDiscretizedBackwardEulerModelEvaluator.hpp
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_TIME_DISCRETIZED_BACKWARD_EULER_MODEL_EVALUATOR_HPP
00031 #define RYTHMOS_TIME_DISCRETIZED_BACKWARD_EULER_MODEL_EVALUATOR_HPP
00032
00033
00034 #include "Rythmos_Types.hpp"
00035 #include "Thyra_StateFuncModelEvaluatorBase.hpp"
00036 #include "Thyra_DefaultProductVectorSpace.hpp"
00037 #include "Thyra_DefaultBlockedLinearOp.hpp"
00038 #include "Thyra_DefaultBlockedTriangularLinearOpWithSolveFactory.hpp"
00039
00040
00041 namespace Rythmos {
00042
00043
00048 template<class Scalar>
00049 class TimeDiscretizedBackwardEulerModelEvaluator
00050 : virtual public Thyra::StateFuncModelEvaluatorBase<Scalar>
00051 {
00052 public:
00053
00056
00058 TimeDiscretizedBackwardEulerModelEvaluator();
00059
00061
00064
00066 void initialize(
00067 const RCP<const Thyra::ModelEvaluator<Scalar> > &daeModel,
00068 const Thyra::ModelEvaluatorBase::InArgs<Scalar> &initCond,
00069 const Scalar finalTime,
00070 const int numTimeSteps,
00071 const RCP<Thyra::LinearOpWithSolveFactoryBase<Scalar> > &W_bar_factory = Teuchos::null
00072 );
00073
00075
00078
00080 RCP<const Thyra::VectorSpaceBase<Scalar> > get_x_space() const;
00082 RCP<const Thyra::VectorSpaceBase<Scalar> > get_f_space() const;
00084 RCP<Thyra::LinearOpBase<Scalar> > create_W_op() const;
00086 RCP<const Thyra::LinearOpWithSolveFactoryBase<Scalar> > get_W_factory() const;
00088 Thyra::ModelEvaluatorBase::InArgs<Scalar> getNominalValues() const;
00090 Thyra::ModelEvaluatorBase::InArgs<Scalar> createInArgs() const;
00091
00093
00094 private:
00095
00098
00100 Thyra::ModelEvaluatorBase::OutArgs<Scalar> createOutArgsImpl() const;
00102 void evalModelImpl(
00103 const Thyra::ModelEvaluatorBase::InArgs<Scalar>& inArgs,
00104 const Thyra::ModelEvaluatorBase::OutArgs<Scalar>& outArgs
00105 ) const;
00106
00108
00109 private:
00110
00111 RCP<const Thyra::ModelEvaluator<Scalar> > daeModel_;
00112 Thyra::ModelEvaluatorBase::InArgs<Scalar> initCond_;
00113 Scalar finalTime_;
00114 int numTimeSteps_;
00115
00116 Scalar initTime_;
00117 Scalar delta_t_;
00118
00119 RCP<const Thyra::ProductVectorSpaceBase<Scalar> > x_bar_space_;
00120 RCP<const Thyra::ProductVectorSpaceBase<Scalar> > f_bar_space_;
00121 RCP<Thyra::LinearOpWithSolveFactoryBase<Scalar> > W_bar_factory_;
00122
00123 };
00124
00125
00130 template<class Scalar>
00131 RCP<TimeDiscretizedBackwardEulerModelEvaluator<Scalar> >
00132 timeDiscretizedBackwardEulerModelEvaluator(
00133 const RCP<const Thyra::ModelEvaluator<Scalar> > &daeModel,
00134 const Thyra::ModelEvaluatorBase::InArgs<Scalar> &initCond,
00135 const Scalar finalTime,
00136 const int numTimeSteps,
00137 const RCP<Thyra::LinearOpWithSolveFactoryBase<Scalar> > &W_bar_factory
00138 )
00139 {
00140 RCP<TimeDiscretizedBackwardEulerModelEvaluator<Scalar> >
00141 model(new TimeDiscretizedBackwardEulerModelEvaluator<Scalar>());
00142 model->initialize(daeModel,initCond,finalTime,numTimeSteps,W_bar_factory);
00143 return model;
00144 }
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154 template<class Scalar>
00155 TimeDiscretizedBackwardEulerModelEvaluator<Scalar>::TimeDiscretizedBackwardEulerModelEvaluator()
00156 :finalTime_(-1.0),
00157 numTimeSteps_(-1),
00158 initTime_(0.0),
00159 delta_t_(-1.0)
00160 {}
00161
00162
00163
00164
00165
00166 template<class Scalar>
00167 void TimeDiscretizedBackwardEulerModelEvaluator<Scalar>::initialize(
00168 const RCP<const Thyra::ModelEvaluator<Scalar> > &daeModel,
00169 const Thyra::ModelEvaluatorBase::InArgs<Scalar> &initCond,
00170 const Scalar finalTime,
00171 const int numTimeSteps,
00172 const RCP<Thyra::LinearOpWithSolveFactoryBase<Scalar> > &W_bar_factory
00173 )
00174 {
00175
00176 TEST_FOR_EXCEPT(is_null(daeModel));
00177 TEST_FOR_EXCEPT(is_null(initCond.get_x()));
00178 TEST_FOR_EXCEPT(is_null(initCond.get_x_dot()));
00179 TEST_FOR_EXCEPT(finalTime <= initCond.get_t());
00180 TEST_FOR_EXCEPT(numTimeSteps <= 0);
00181
00182
00183 daeModel_ = daeModel;
00184 initCond_ = initCond;
00185 finalTime_ = finalTime;
00186 numTimeSteps_ = numTimeSteps;
00187
00188 initTime_ = initCond.get_t();
00189 delta_t_ = (finalTime_ - initTime_) / numTimeSteps_;
00190
00191 x_bar_space_ = productVectorSpace(daeModel_->get_x_space(),numTimeSteps_);
00192 f_bar_space_ = productVectorSpace(daeModel_->get_f_space(),numTimeSteps_);
00193
00194 if (!is_null(W_bar_factory)) {
00195 W_bar_factory_ = W_bar_factory;
00196 }
00197 else {
00198 W_bar_factory_ =
00199 Thyra::defaultBlockedTriangularLinearOpWithSolveFactory<Scalar>(
00200 daeModel_->get_W_factory()
00201 );
00202 }
00203
00204 }
00205
00206
00207
00208
00209
00210 template<class Scalar>
00211 RCP<const Thyra::VectorSpaceBase<Scalar> >
00212 TimeDiscretizedBackwardEulerModelEvaluator<Scalar>::get_x_space() const
00213 {
00214 return x_bar_space_;
00215 }
00216
00217
00218 template<class Scalar>
00219 RCP<const Thyra::VectorSpaceBase<Scalar> >
00220 TimeDiscretizedBackwardEulerModelEvaluator<Scalar>::get_f_space() const
00221 {
00222 return f_bar_space_;
00223 }
00224
00225
00226 template<class Scalar>
00227 RCP<Thyra::LinearOpBase<Scalar> >
00228 TimeDiscretizedBackwardEulerModelEvaluator<Scalar>::create_W_op() const
00229 {
00230
00231 RCP<Thyra::PhysicallyBlockedLinearOpBase<Scalar> >
00232 W_op_bar = Thyra::defaultBlockedLinearOp<Scalar>();
00233 W_op_bar->beginBlockFill( f_bar_space_, x_bar_space_ );
00234 for ( int k = 0; k < numTimeSteps_; ++k ) {
00235 W_op_bar->setNonconstBlock( k, k, daeModel_->create_W_op() );
00236 if (k > 0)
00237 W_op_bar->setNonconstBlock( k, k-1, daeModel_->create_W_op() );
00238 }
00239 W_op_bar->endBlockFill();
00240 return W_op_bar;
00241 }
00242
00243
00244 template<class Scalar>
00245 RCP<const Thyra::LinearOpWithSolveFactoryBase<Scalar> >
00246 TimeDiscretizedBackwardEulerModelEvaluator<Scalar>::get_W_factory() const
00247 {
00248 return W_bar_factory_;
00249 }
00250
00251
00252 template<class Scalar>
00253 Thyra::ModelEvaluatorBase::InArgs<Scalar>
00254 TimeDiscretizedBackwardEulerModelEvaluator<Scalar>::getNominalValues() const
00255 {
00256 typedef Thyra::ModelEvaluatorBase MEB;
00257 TEST_FOR_EXCEPT(true);
00258 return MEB::InArgs<Scalar>();
00259 }
00260
00261
00262 template<class Scalar>
00263 Thyra::ModelEvaluatorBase::InArgs<Scalar>
00264 TimeDiscretizedBackwardEulerModelEvaluator<Scalar>::createInArgs() const
00265 {
00266 typedef Thyra::ModelEvaluatorBase MEB;
00267 MEB::InArgsSetup<Scalar> inArgs;
00268 inArgs.setModelEvalDescription(this->description());
00269 inArgs.setSupports(MEB::IN_ARG_x);
00270 return inArgs;
00271 }
00272
00273
00274
00275
00276
00277 template<class Scalar>
00278 Thyra::ModelEvaluatorBase::OutArgs<Scalar>
00279 TimeDiscretizedBackwardEulerModelEvaluator<Scalar>::createOutArgsImpl() const
00280 {
00281 typedef Thyra::ModelEvaluatorBase MEB;
00282 MEB::OutArgs<Scalar> daeOutArgs = daeModel_->createOutArgs();
00283 MEB::OutArgsSetup<Scalar> outArgs;
00284 outArgs.setModelEvalDescription(this->description());
00285 outArgs.setSupports(MEB::OUT_ARG_f);
00286 outArgs.setSupports(MEB::OUT_ARG_W_op);
00287 outArgs.set_W_properties(daeOutArgs.get_W_properties());
00288 return outArgs;
00289 }
00290
00291
00292 template<class Scalar>
00293 void TimeDiscretizedBackwardEulerModelEvaluator<Scalar>::evalModelImpl(
00294 const Thyra::ModelEvaluatorBase::InArgs<Scalar>& inArgs_bar,
00295 const Thyra::ModelEvaluatorBase::OutArgs<Scalar>& outArgs_bar
00296 ) const
00297 {
00298
00299
00300 using Teuchos::rcp_dynamic_cast;
00301 typedef ScalarTraits<Scalar> ST;
00302 typedef Thyra::ModelEvaluatorBase MEB;
00303 typedef Thyra::VectorBase<Scalar> VB;
00304 typedef Thyra::ProductVectorBase<Scalar> PVB;
00305 typedef Thyra::BlockedLinearOpBase<Scalar> BLWB;
00306
00307
00308
00309
00310
00311
00312
00313 TEST_FOR_EXCEPTION( delta_t_ <= 0.0, std::logic_error,
00314 "Error, you have not initialized this object correctly!" );
00315
00316
00317
00318
00319
00320 const RCP<const PVB> x_bar = rcp_dynamic_cast<const PVB>(inArgs_bar.get_x(), true);
00321 const RCP<PVB> f_bar = rcp_dynamic_cast<PVB>(outArgs_bar.get_f(), true);
00322 RCP<BLWB> W_op_bar = rcp_dynamic_cast<BLWB>(outArgs_bar.get_W_op(), true);
00323
00324
00325
00326
00327
00328 MEB::InArgs<Scalar> daeInArgs = daeModel_->createInArgs();
00329 MEB::OutArgs<Scalar> daeOutArgs = daeModel_->createOutArgs();
00330 const RCP<VB> x_dot_i = createMember(daeModel_->get_x_space());
00331 daeInArgs.setArgs(initCond_);
00332
00333 Scalar t_i = initTime_;
00334
00335 const Scalar oneOverDeltaT = 1.0/delta_t_;
00336
00337 for ( int i = 0; i < numTimeSteps_; ++i ) {
00338
00339
00340 const RCP<const Thyra::VectorBase<Scalar> >
00341 x_i = x_bar->getVectorBlock(i),
00342 x_im1 = ( i==0 ? initCond_.get_x() : x_bar->getVectorBlock(i-1) );
00343 V_VmV( &*x_dot_i, *x_i, *x_im1 );
00344 Vt_S( &*x_dot_i, oneOverDeltaT );
00345 daeInArgs.set_x_dot( x_dot_i );
00346 daeInArgs.set_x( x_i );
00347 daeInArgs.set_t( t_i );
00348 daeInArgs.set_alpha( oneOverDeltaT );
00349 daeInArgs.set_beta( 1.0 );
00350
00351
00352 if (!is_null(f_bar))
00353 daeOutArgs.set_f( f_bar->getNonconstVectorBlock(i) );
00354 if (!is_null(W_op_bar))
00355 daeOutArgs.set_W_op(W_op_bar->getNonconstBlock(i,i).assert_not_null());
00356
00357
00358 daeModel_->evalModel( daeInArgs, daeOutArgs );
00359 daeOutArgs.set_f(Teuchos::null);
00360 daeOutArgs.set_W_op(Teuchos::null);
00361
00362
00363 if ( !is_null(W_op_bar) && i > 0 ) {
00364 daeInArgs.set_alpha( -oneOverDeltaT );
00365 daeInArgs.set_beta( 0.0 );
00366 daeOutArgs.set_W_op(W_op_bar->getNonconstBlock(i,i-1).assert_not_null());
00367 daeModel_->evalModel( daeInArgs, daeOutArgs );
00368 daeOutArgs.set_W_op(Teuchos::null);
00369 }
00370
00371
00372 t_i += delta_t_;
00373
00374 }
00375
00376
00377
00378
00379
00380 }
00381
00382
00383 }
00384
00385
00386 #endif // RYTHMOS_TIME_DISCRETIZED_BACKWARD_EULER_MODEL_EVALUATOR_HPP