Rythmos_TimeDiscretizedBackwardEulerModelEvaluator.hpp

00001 //@HEADER
00002 // ***********************************************************************
00003 //
00004 //                           Rythmos Package
00005 //                 Copyright (2006) Sandia Corporation
00006 //
00007 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
00008 // license for use of this work by or on behalf of the U.S. Government.
00009 //
00010 // This library is free software; you can redistribute it and/or modify
00011 // it under the terms of the GNU Lesser General Public License as
00012 // published by the Free Software Foundation; either version 2.1 of the
00013 // License, or (at your option) any later version.
00014 //
00015 // This library is distributed in the hope that it will be useful, but
00016 // WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018 // Lesser General Public License for more details.
00019 //
00020 // You should have received a copy of the GNU Lesser General Public
00021 // License along with this library; if not, write to the Free Software
00022 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00023 // USA
00024 // Questions? Contact Todd S. Coffey (tscoffe@sandia.gov)
00025 //
00026 // ***********************************************************************
00027 //@HEADER
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" // Default implementation
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 // Definition
00149 
00150 
00151 // Constructors/initializers/accessors
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) // Flag for uninitailized!
00160 {}
00161 
00162 
00163 // Overridden from TimeDiscretizedBackwardEulerModelEvaluatorBase
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   // ToDo: Validate that daeModel is of the right form!
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 // Public functions overridden from ModelEvaluator
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   // Create the block structure for W_op_bar right away!
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 // Private functions overridden from ModelEvaluatorDefaultBase
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   THYRA_MODEL_EVALUATOR_DECORATOR_EVAL_MODEL_GEN_BEGIN(
00309     "Rythmos::ImplicitRKModelEvaluator",inArgs_bar,outArgs_bar,daeModel_
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   // A) Unwrap the inArgs and outArgs to get at product vectors and block op
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   // B) Assemble f_bar and W_op_bar by looping over stages
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_; // ToDo: Define t_init!
00334 
00335   const Scalar oneOverDeltaT = 1.0/delta_t_;
00336 
00337   for ( int i = 0; i < numTimeSteps_; ++i ) {
00338 
00339     // B.1) Setup the DAE's inArgs for time step eqn f(i) ...
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 ); // x_dot_i = 1/dt * ( x[i] - x[i-1] )
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     // B.2) Setup the DAE's outArgs for f(i) and/or W(i,i) ...
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     // B.3) Compute f_bar(i) and/or W_op_bar(i,i) ...
00358     daeModel_->evalModel( daeInArgs, daeOutArgs );
00359     daeOutArgs.set_f(Teuchos::null);
00360     daeOutArgs.set_W_op(Teuchos::null);
00361     
00362     // B.4) Evaluate W_op_bar(i,i-1)
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   THYRA_MODEL_EVALUATOR_DECORATOR_EVAL_MODEL_END();
00378 */
00379 
00380 }
00381 
00382 
00383 } // namespace Rythmos
00384 
00385 
00386 #endif // RYTHMOS_TIME_DISCRETIZED_BACKWARD_EULER_MODEL_EVALUATOR_HPP
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends

Generated on Tue Oct 20 10:24:09 2009 for Rythmos - Transient Integration for Differential Equations by  doxygen 1.6.1