Rythmos_ImplicitRKModelEvaluator.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_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 // Definition
00157 
00158 
00159 // Constructors/initializers/accessors
00160 
00161 
00162 template<class Scalar>
00163 ImplicitRKModelEvaluator<Scalar>::ImplicitRKModelEvaluator()
00164 {
00165   setTimeStepPointCalled_ = false;
00166 }
00167 
00168 
00169 // Overridden from ImplicitRKModelEvaluatorBase
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   // ToDo: Assert input arguments!
00181   // How do I verify the basePoint is an authentic InArgs from daeModel?
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   // HACK! Remove the preconditioner factory for now!
00210   if (irk_W_factory_->acceptsPreconditionerFactory())
00211     irk_W_factory_->unsetPreconditionerFactory();
00212 
00213   // ToDo: create the block diagonal preconditioner factory and set this on
00214   // irk_W_factory_!
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   // Verify x_old is compatible with the vector space in the DAE Model.
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 // Overridden from ModelEvaluator
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   // Create the block structure for W_op_bar right away!
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 // Private functions overridden from ModelEvaluatorDefaultBase
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   // A) Unwrap the inArgs and outArgs to get at product vectors and block op
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   // B) Assemble f_bar and W_op_bar by looping over stages
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     // B.1) Setup the DAE's inArgs for stage f(i) ...
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     // B.2) Setup the DAE's outArgs for stage f(i) ...
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     // B.3) Compute f_bar(i) and/or W_op_bar(i,0) ...
00377     daeModel_->evalModel( daeInArgs, daeOutArgs );
00378     daeOutArgs.set_f(Teuchos::null);
00379     daeOutArgs.set_W_op(Teuchos::null);
00380     
00381     // B.4) Evaluate the rest of the W_op_bar(i,j=1...numStages-1) ...
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 } // namespace Rythmos
00399 
00400 
00401 #endif // RYTHMOS_IMPLICITRK_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