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 #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
00106
00107
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
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
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
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
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
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
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
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 }
00300
00301 #endif // THYRA_DEFAULT_FINITE_DIFFERENCE_MODEL_EVALUATOR_HPP