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