Thyra_DefaultFiniteDifferenceModelEvaluator.hpp

Go to the documentation of this file.
00001 // @HEADER
00002 // ***********************************************************************
00003 // 
00004 //    Thyra: Interfaces and Support for Abstract Numerical Algorithms
00005 //                 Copyright (2004) 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 Michael A. Heroux (maherou@sandia.gov) 
00025 // 
00026 // ***********************************************************************
00027 // @HEADER
00028 
00029 #ifndef THYRA_DEFAULT_FINITE_DIFFERENCE_MODEL_EVALUATOR_HPP
00030 #define THYRA_DEFAULT_FINITE_DIFFERENCE_MODEL_EVALUATOR_HPP
00031 
00032 #include "Thyra_ModelEvaluatorDelegatorBase.hpp"
00033 #include "Thyra_LinearOpWithSolveFactoryBase.hpp"
00034 #include "Thyra_DetachedVectorView.hpp"
00035 #include "Thyra_DirectionalFiniteDiffCalculator.hpp"
00036 #include "Teuchos_StandardMemberCompositionMacros.hpp"
00037 #include "Teuchos_StandardCompositionMacros.hpp"
00038 #include "Teuchos_Time.hpp"
00039 
00040 namespace Thyra {
00041 
00047 template<class Scalar>
00048 class DefaultFiniteDifferenceModelEvaluator
00049   : virtual public ModelEvaluatorDelegatorBase<Scalar>
00050 {
00051 public:
00052 
00055 
00057   STANDARD_COMPOSITION_MEMBERS( Thyra::DirectionalFiniteDiffCalculator<Scalar>, direcFiniteDiffCalculator )
00058 
00059   
00060   DefaultFiniteDifferenceModelEvaluator();
00061 
00063   DefaultFiniteDifferenceModelEvaluator(
00064     const Teuchos::RefCountPtr<ModelEvaluator<Scalar> >                          &thyraModel
00065     ,const Teuchos::RefCountPtr<Thyra::DirectionalFiniteDiffCalculator<Scalar> > &direcFiniteDiffCalculator
00066     );
00067 
00069   void initialize(
00070     const Teuchos::RefCountPtr<ModelEvaluator<Scalar> >                          &thyraModel
00071     ,const Teuchos::RefCountPtr<Thyra::DirectionalFiniteDiffCalculator<Scalar> > &direcFiniteDiffCalculator
00072     );
00073 
00075   void uninitialize(
00076     Teuchos::RefCountPtr<ModelEvaluator<Scalar> >                          *thyraModel
00077     ,Teuchos::RefCountPtr<Thyra::DirectionalFiniteDiffCalculator<Scalar> > *direcFiniteDiffCalculator
00078     );
00079 
00081 
00085   ModelEvaluatorBase::OutArgs<Scalar> createOutArgs() const;
00087   void evalModel(
00088     const ModelEvaluatorBase::InArgs<Scalar>    &inArgs
00089     ,const ModelEvaluatorBase::OutArgs<Scalar>  &outArgs
00090     ) const;
00091 
00093 
00096 
00098   std::string description() const;
00099 
00101   
00102 };
00103 
00104 // /////////////////////////////////
00105 // Implementations
00106 
00107 // Constructors/initializers/accessors/utilities
00108 
00109 template<class Scalar>
00110 DefaultFiniteDifferenceModelEvaluator<Scalar>::DefaultFiniteDifferenceModelEvaluator()
00111 {}
00112 
00113 template<class Scalar>
00114 DefaultFiniteDifferenceModelEvaluator<Scalar>::DefaultFiniteDifferenceModelEvaluator(
00115   const Teuchos::RefCountPtr<ModelEvaluator<Scalar> >                          &thyraModel
00116   ,const Teuchos::RefCountPtr<Thyra::DirectionalFiniteDiffCalculator<Scalar> > &direcFiniteDiffCalculator
00117   )
00118 {
00119   initialize(thyraModel,direcFiniteDiffCalculator);
00120 }
00121 
00122 template<class Scalar>
00123 void DefaultFiniteDifferenceModelEvaluator<Scalar>::initialize(
00124   const Teuchos::RefCountPtr<ModelEvaluator<Scalar> >                          &thyraModel
00125   ,const Teuchos::RefCountPtr<Thyra::DirectionalFiniteDiffCalculator<Scalar> > &direcFiniteDiffCalculator
00126   )
00127 {
00128   this->ModelEvaluatorDelegatorBase<Scalar>::initialize(thyraModel);
00129   direcFiniteDiffCalculator_ = direcFiniteDiffCalculator;
00130 }
00131 
00132 template<class Scalar>
00133 void DefaultFiniteDifferenceModelEvaluator<Scalar>::uninitialize(
00134   Teuchos::RefCountPtr<ModelEvaluator<Scalar> >                          *thyraModel
00135   ,Teuchos::RefCountPtr<Thyra::DirectionalFiniteDiffCalculator<Scalar> > *direcFiniteDiffCalculator
00136   )
00137 {
00138   if(thyraModel) *thyraModel = this->getUnderlyingModel();
00139   this->ModelEvaluatorDelegatorBase<Scalar>::uninitialize();
00140   if(direcFiniteDiffCalculator) *direcFiniteDiffCalculator = direcFiniteDiffCalculator_;
00141   direcFiniteDiffCalculator_ = Teuchos::null;
00142 }
00143 
00144 // Overridden from ModelEvaulator.
00145 
00146 template<class Scalar>
00147 ModelEvaluatorBase::OutArgs<Scalar>
00148 DefaultFiniteDifferenceModelEvaluator<Scalar>::createOutArgs() const
00149 {
00150   typedef ModelEvaluatorBase MEB;
00151   const Teuchos::RefCountPtr<const ModelEvaluator<Scalar> >
00152     thyraModel = this->getUnderlyingModel();
00153   const MEB::OutArgs<Scalar> wrappedOutArgs = thyraModel->createOutArgs();
00154   const int Np = wrappedOutArgs.Np(), Ng = wrappedOutArgs.Ng();
00155   MEB::OutArgsSetup<Scalar> outArgs;
00156   outArgs.setModelEvalDescription(this->description());
00157   outArgs.set_Np_Ng(Np,Ng);
00158   outArgs.setSupports(wrappedOutArgs);
00159   // Just support derivatives of DgDp for now!
00160   for( int j = 0; j < Ng; ++j ) {
00161     for( int l = 0; l < Np; ++l ) {
00162       outArgs.setSupports(MEB::OUT_ARG_DgDp,j,l,MEB::DERIV_TRANS_MV_BY_ROW);
00163     }
00164   }
00165   // ToDo: Add support for more derivatives as needed!
00166   return outArgs;
00167 }
00168 
00169 template<class Scalar>
00170 void DefaultFiniteDifferenceModelEvaluator<Scalar>::evalModel(
00171   const ModelEvaluatorBase::InArgs<Scalar>     &inArgs
00172   ,const ModelEvaluatorBase::OutArgs<Scalar>   &outArgs
00173   ) const
00174 {
00175   typedef ModelEvaluatorBase MEB;
00176   using Teuchos::RefCountPtr;
00177   using Teuchos::rcp;
00178   using Teuchos::rcp_const_cast;
00179   using Teuchos::rcp_dynamic_cast;
00180   using Teuchos::OSTab;
00181   typedef Teuchos::ScalarTraits<Scalar>  ST;
00182   typedef typename ST::magnitudeType ScalarMag;
00183 
00184   typedef RefCountPtr<VectorBase<Scalar> >         V_ptr;
00185   typedef RefCountPtr<const VectorBase<Scalar> >   CV_ptr;
00186   typedef RefCountPtr<MultiVectorBase<Scalar> >    MV_ptr;
00187 
00188   Teuchos::Time totalTimer(""), timer("");
00189   totalTimer.start(true);
00190 
00191   const Teuchos::RefCountPtr<Teuchos::FancyOStream> out       = this->getOStream();
00192   const Teuchos::EVerbosityLevel                    verbLevel = this->getVerbLevel();
00193   Teuchos::OSTab tab(out);
00194   if(out.get() && static_cast<int>(verbLevel) >= static_cast<int>(Teuchos::VERB_LOW))
00195     *out << "\nEntering Thyra::DefaultFiniteDifferenceModelEvaluator<Scalar>::evalModel(...) ...\n";
00196 
00197   if(out.get() && static_cast<int>(verbLevel) >= static_cast<int>(Teuchos::VERB_EXTREME))
00198     *out
00199       << "\ninArgs =\n" << Teuchos::describe(inArgs,verbLevel)
00200       << "\noutArgs on input =\n" << Teuchos::describe(outArgs,Teuchos::VERB_LOW);
00201 
00202   const Teuchos::RefCountPtr<const ModelEvaluator<Scalar> >
00203     thyraModel = this->getUnderlyingModel();
00204 
00205   typedef Teuchos::VerboseObjectTempState<ModelEvaluatorBase> VOTSME;
00206   VOTSME thyraModel_outputTempState(thyraModel,out,verbLevel);
00207 
00208   //
00209   // Just do the g_0(p_0) case for now!
00210   //
00211 
00212   const RefCountPtr<const VectorSpaceBase<Scalar> >
00213     p_space = thyraModel->get_p_space(0),
00214     g_space = thyraModel->get_g_space(0);
00215 
00216   //
00217   // Compute the base point
00218   //
00219 
00220   if(out.get() && static_cast<int>(verbLevel) >= static_cast<int>(Teuchos::VERB_LOW))
00221     *out << "\nComputing the base point ...\n";
00222 
00223   const int Np = outArgs.Np();
00224   const int Ng = outArgs.Ng();
00225   MEB::InArgs<Scalar>  wrappedInArgs = inArgs;
00226   MEB::OutArgs<Scalar> baseFunc = thyraModel->createOutArgs();
00227   if( outArgs.supports(MEB::OUT_ARG_f) && outArgs.get_f().get() )
00228     baseFunc.set_f(outArgs.get_f());
00229   for( int j = 0; j < Ng; ++j ) {
00230     V_ptr g_j;
00231     if( (g_j=outArgs.get_g(j)).get() )
00232       baseFunc.set_g(j,g_j);
00233   }
00234   thyraModel->evalModel(wrappedInArgs,baseFunc);
00235 
00236   bool failed = baseFunc.isFailed();
00237   
00238   if(!failed) {
00239     //
00240     // Compute the derivatives
00241     //
00242     MEB::OutArgs<Scalar> deriv = thyraModel->createOutArgs();
00243     for( int l = 0; l < Np; ++l ) {
00244       if( outArgs.supports(MEB::OUT_ARG_DfDp,l).none()==false
00245           && outArgs.get_DfDp(l).isEmpty()==false )
00246       {
00247         deriv.set_DfDp(l,outArgs.get_DfDp(l));
00248       }
00249       for( int j = 0; j < Ng; ++j ) {
00250         if( outArgs.supports(MEB::OUT_ARG_DgDp,j,l).none()==false
00251             && outArgs.get_DgDp(j,l).isEmpty()==false )
00252         {
00253           deriv.set_DgDp(j,l,outArgs.get_DgDp(j,l));
00254         }
00255       }
00256     }
00257     direcFiniteDiffCalculator_->calcDerivatives(
00258       *thyraModel,inArgs,baseFunc,deriv
00259       );
00260   }
00261 
00262   if(failed) {
00263     if(out.get() && static_cast<int>(verbLevel) >= static_cast<int>(Teuchos::VERB_LOW))
00264       *out
00265         << "\nEvaluation failed, returning NaNs ...\n";
00266     outArgs.setFailed();
00267   }
00268 
00269   if(out.get() && static_cast<int>(verbLevel) >= static_cast<int>(Teuchos::VERB_EXTREME))
00270     *out
00271       << "\noutArgs on output =\n" << Teuchos::describe(outArgs,verbLevel);
00272   
00273   totalTimer.stop();
00274   if(out.get() && static_cast<int>(verbLevel) >= static_cast<int>(Teuchos::VERB_LOW))
00275     *out
00276       << "\nTotal evaluation time = "<<totalTimer.totalElapsedTime()<<" sec\n"
00277       << "\nLeaving Thyra::DefaultFiniteDifferenceModelEvaluator<Scalar>::evalModel(...) ...\n";
00278   
00279 }
00280 
00281 // Public functions overridden from Teuchos::Describable
00282 
00283 template<class Scalar>
00284 std::string DefaultFiniteDifferenceModelEvaluator<Scalar>::description() const
00285 {
00286   const Teuchos::RefCountPtr<const ModelEvaluator<Scalar> >
00287     thyraModel = this->getUnderlyingModel();
00288   std::ostringstream oss;
00289   oss << "Thyra::DefaultFiniteDifferenceModelEvaluator{";
00290   oss << "thyraModel=";
00291   if(thyraModel.get())
00292     oss << "\'"<<thyraModel->description()<<"\'";
00293   else
00294     oss << "NULL";
00295   oss << "}";
00296   return oss.str();
00297 }
00298 
00299 } // namespace Thyra
00300 
00301 #endif // THYRA_DEFAULT_FINITE_DIFFERENCE_MODEL_EVALUATOR_HPP

Generated on Thu Sep 18 12:33:02 2008 for Thyra Package Browser (Single Doxygen Collection) by doxygen 1.3.9.1