Rythmos - Transient Integration for Differential Equations Version of the Day
Rythmos_AdjointModelEvaluator.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 #ifndef RYTHMOS_ADJOINT_MODEL_EVALUATOR_HPP
00030 #define RYTHMOS_ADJOINT_MODEL_EVALUATOR_HPP
00031 
00032 
00033 #include "Rythmos_IntegratorBase.hpp"
00034 #include "Thyra_ModelEvaluator.hpp" // Interface
00035 #include "Thyra_StateFuncModelEvaluatorBase.hpp" // Implementation
00036 #include "Thyra_ModelEvaluatorDelegatorBase.hpp"
00037 #include "Thyra_DefaultScaledAdjointLinearOp.hpp"
00038 #include "Thyra_DefaultAdjointLinearOpWithSolve.hpp"
00039 #include "Thyra_VectorStdOps.hpp"
00040 #include "Thyra_MultiVectorStdOps.hpp"
00041 #include "Teuchos_implicit_cast.hpp"
00042 #include "Teuchos_Assert.hpp"
00043 
00044 
00045 namespace Rythmos {
00046 
00047 
00172 template<class Scalar>
00173 class AdjointModelEvaluator
00174   : virtual public Thyra::StateFuncModelEvaluatorBase<Scalar>
00175 {
00176 public:
00177 
00180 
00182   AdjointModelEvaluator();
00183 
00185   void setFwdStateModel(
00186     const RCP<const Thyra::ModelEvaluator<Scalar> > &fwdStateModel,
00187     const Thyra::ModelEvaluatorBase::InArgs<Scalar> &basePoint );
00188 
00192   void setFwdTimeRange( const TimeRange<Scalar> &fwdTimeRange );
00193 
00206   void setFwdStateSolutionBuffer(
00207     const RCP<const InterpolationBufferBase<Scalar> > &fwdStateSolutionBuffer );
00208   
00210 
00213 
00215   RCP<const Thyra::VectorSpaceBase<Scalar> > get_x_space() const;
00217   RCP<const Thyra::VectorSpaceBase<Scalar> > get_f_space() const;
00219   Thyra::ModelEvaluatorBase::InArgs<Scalar> getNominalValues() const;
00221   RCP<Thyra::LinearOpWithSolveBase<Scalar> > create_W() const;
00223   RCP<Thyra::LinearOpBase<Scalar> > create_W_op() const;
00225   Thyra::ModelEvaluatorBase::InArgs<Scalar> createInArgs() const;
00226 
00228 
00229 private:
00230 
00233 
00235   Thyra::ModelEvaluatorBase::OutArgs<Scalar> createOutArgsImpl() const;
00237   void evalModelImpl(
00238     const Thyra::ModelEvaluatorBase::InArgs<Scalar> &inArgs_bar,
00239     const Thyra::ModelEvaluatorBase::OutArgs<Scalar> &outArgs_bar
00240     ) const;
00241 
00243 
00244 private:
00245 
00246   // /////////////////////////
00247   // Private data members
00248 
00249   RCP<const Thyra::ModelEvaluator<Scalar> > fwdStateModel_;
00250   Thyra::ModelEvaluatorBase::InArgs<Scalar> basePoint_;
00251   TimeRange<Scalar> fwdTimeRange_;
00252   RCP<const InterpolationBufferBase<Scalar> > fwdStateSolutionBuffer_;
00253 
00254   mutable bool isInitialized_;
00255   mutable Thyra::ModelEvaluatorBase::InArgs<Scalar> prototypeInArgs_bar_;
00256   mutable Thyra::ModelEvaluatorBase::OutArgs<Scalar> prototypeOutArgs_bar_;
00257   mutable Thyra::ModelEvaluatorBase::InArgs<Scalar> adjointNominalValues_;
00258   mutable RCP<Thyra::LinearOpBase<Scalar> > my_W_bar_adj_op_;
00259   mutable RCP<Thyra::LinearOpBase<Scalar> > my_d_f_d_x_dot_op_;
00260 
00261   // /////////////////////////
00262   // Private member functions
00263 
00264   // Just-in-time initialization function
00265   void initialize() const;
00266 
00267 };
00268 
00269 
00274 template<class Scalar>
00275 RCP<AdjointModelEvaluator<Scalar> >
00276 adjointModelEvaluator(
00277   const RCP<const Thyra::ModelEvaluator<Scalar> > &fwdStateModel,
00278   const TimeRange<Scalar> &fwdTimeRange
00279   )
00280 {
00281   RCP<AdjointModelEvaluator<Scalar> >
00282     adjointModel = Teuchos::rcp(new AdjointModelEvaluator<Scalar>);
00283   adjointModel->setFwdStateModel(fwdStateModel, fwdStateModel->getNominalValues());
00284   adjointModel->setFwdTimeRange(fwdTimeRange);
00285   return adjointModel;
00286 }
00287 
00288 
00289 // /////////////////////////////////
00290 // Implementations
00291 
00292 
00293 // Constructors/Intializers/Accessors
00294 
00295 
00296 template<class Scalar>
00297 AdjointModelEvaluator<Scalar>::AdjointModelEvaluator()
00298   :isInitialized_(false)
00299 {}
00300 
00301 
00302 template<class Scalar>
00303 void AdjointModelEvaluator<Scalar>::setFwdStateModel(
00304   const RCP<const Thyra::ModelEvaluator<Scalar> > &fwdStateModel,
00305   const Thyra::ModelEvaluatorBase::InArgs<Scalar> &basePoint
00306   )
00307 {
00308   TEUCHOS_TEST_FOR_EXCEPT(is_null(fwdStateModel));
00309   fwdStateModel_ = fwdStateModel;
00310   basePoint_ = basePoint;
00311   isInitialized_ = false;
00312 }
00313 
00314 
00315 template<class Scalar>
00316 void AdjointModelEvaluator<Scalar>::setFwdTimeRange(
00317   const TimeRange<Scalar> &fwdTimeRange )
00318 {
00319   fwdTimeRange_ = fwdTimeRange;
00320 }
00321 
00322 
00323 template<class Scalar>
00324 void AdjointModelEvaluator<Scalar>::setFwdStateSolutionBuffer(
00325   const RCP<const InterpolationBufferBase<Scalar> > &fwdStateSolutionBuffer )
00326 {
00327   TEUCHOS_TEST_FOR_EXCEPT(is_null(fwdStateSolutionBuffer));
00328   fwdStateSolutionBuffer_ = fwdStateSolutionBuffer;
00329 }
00330 
00331 
00332 // Public functions overridden from ModelEvaulator
00333 
00334 
00335 template<class Scalar>
00336 RCP<const Thyra::VectorSpaceBase<Scalar> >
00337 AdjointModelEvaluator<Scalar>::get_x_space() const
00338 {
00339   initialize();
00340   return fwdStateModel_->get_f_space();
00341 }
00342 
00343 
00344 template<class Scalar>
00345 RCP<const Thyra::VectorSpaceBase<Scalar> >
00346 AdjointModelEvaluator<Scalar>::get_f_space() const
00347 {
00348   initialize();
00349   return fwdStateModel_->get_x_space();
00350 }
00351 
00352 
00353 template<class Scalar>
00354 Thyra::ModelEvaluatorBase::InArgs<Scalar>
00355 AdjointModelEvaluator<Scalar>::getNominalValues() const
00356 {
00357   initialize();
00358   return adjointNominalValues_;
00359 }
00360 
00361 
00362 template<class Scalar>
00363 RCP<Thyra::LinearOpWithSolveBase<Scalar> >
00364 AdjointModelEvaluator<Scalar>::create_W() const
00365 {
00366   initialize();
00367   return Thyra::nonconstAdjointLows<Scalar>(fwdStateModel_->create_W());
00368 }
00369 
00370 
00371 template<class Scalar>
00372 RCP<Thyra::LinearOpBase<Scalar> >
00373 AdjointModelEvaluator<Scalar>::create_W_op() const
00374 {
00375   initialize();
00376   return Thyra::nonconstAdjoint<Scalar>(fwdStateModel_->create_W_op());
00377 }
00378 
00379 
00380 template<class Scalar>
00381 Thyra::ModelEvaluatorBase::InArgs<Scalar>
00382 AdjointModelEvaluator<Scalar>::createInArgs() const
00383 {
00384   initialize();
00385   return prototypeInArgs_bar_;
00386 }
00387 
00388 
00389 // Private functions overridden from ModelEvaulatorDefaultBase
00390 
00391 
00392 template<class Scalar>
00393 Thyra::ModelEvaluatorBase::OutArgs<Scalar>
00394 AdjointModelEvaluator<Scalar>::createOutArgsImpl() const
00395 {
00396   initialize();
00397   return prototypeOutArgs_bar_;
00398 }
00399 
00400 
00401 template<class Scalar>
00402 void AdjointModelEvaluator<Scalar>::evalModelImpl(
00403   const Thyra::ModelEvaluatorBase::InArgs<Scalar> &inArgs_bar,
00404   const Thyra::ModelEvaluatorBase::OutArgs<Scalar> &outArgs_bar
00405   ) const
00406 {
00407 
00408   using Teuchos::rcp_dynamic_cast;
00409   using Teuchos::describe;
00410   typedef Teuchos::ScalarTraits<Scalar> ST;
00411   typedef Thyra::ModelEvaluatorBase MEB;
00412   typedef Thyra::DefaultScaledAdjointLinearOp<Scalar> DSALO;
00413   typedef Thyra::DefaultAdjointLinearOpWithSolve<Scalar> DALOWS;
00414   typedef Teuchos::VerboseObjectTempState<Thyra::ModelEvaluatorBase> VOTSME;
00415 
00416   //
00417   // A) Header stuff
00418   //
00419 
00420   THYRA_MODEL_EVALUATOR_DECORATOR_EVAL_MODEL_GEN_BEGIN(
00421     "AdjointModelEvaluator", inArgs_bar, outArgs_bar, Teuchos::null );
00422 
00423   initialize();
00424 
00425   VOTSME fwdStateModel_outputTempState(fwdStateModel_,out,verbLevel);
00426 
00427   //const bool trace = includesVerbLevel(verbLevel, Teuchos::VERB_LOW);
00428   const bool dumpAll = includesVerbLevel(localVerbLevel, Teuchos::VERB_EXTREME);
00429 
00430   //
00431   // B) Unpack the input and output arguments to see what we have to compute
00432   //
00433 
00434   // B.1) InArgs
00435 
00436   const Scalar t_bar = inArgs_bar.get_t();
00437   const RCP<const Thyra::VectorBase<Scalar> >
00438     lambda_rev_dot = inArgs_bar.get_x_dot().assert_not_null(), // x_bar_dot
00439     lambda = inArgs_bar.get_x().assert_not_null(); // x_bar
00440   const Scalar alpha_bar = inArgs_bar.get_alpha();
00441   const Scalar beta_bar = inArgs_bar.get_beta();
00442 
00443   if (dumpAll) {
00444     *out << "\nlambda_rev_dot = " << describe(*lambda_rev_dot, Teuchos::VERB_EXTREME);
00445     *out << "\nlambda = " << describe(*lambda, Teuchos::VERB_EXTREME);
00446     *out << "\nalpha_bar = " << alpha_bar << "\n";
00447     *out << "\nbeta_bar = " << beta_bar << "\n";
00448   }
00449 
00450   // B.2) OutArgs
00451 
00452   const RCP<Thyra::VectorBase<Scalar> > f_bar = outArgs_bar.get_f();
00453 
00454   RCP<DALOWS> W_bar;
00455   if (outArgs_bar.supports(MEB::OUT_ARG_W))
00456     W_bar = rcp_dynamic_cast<DALOWS>(outArgs_bar.get_W(), true);
00457 
00458   RCP<DSALO> W_bar_op;
00459   if (outArgs_bar.supports(MEB::OUT_ARG_W_op))
00460     W_bar_op = rcp_dynamic_cast<DSALO>(outArgs_bar.get_W_op(), true);
00461 
00462   if (dumpAll) {
00463     if (!is_null(W_bar)) {
00464       *out << "\nW_bar = " << describe(*W_bar, Teuchos::VERB_EXTREME);
00465     }
00466     if (!is_null(W_bar_op)) {
00467       *out << "\nW_bar_op = " << describe(*W_bar_op, Teuchos::VERB_EXTREME);
00468     }
00469   }
00470   
00471   //
00472   // C) Evaluate the needed quantities from the underlying forward Model
00473   //
00474 
00475   MEB::InArgs<Scalar> fwdInArgs = fwdStateModel_->createInArgs();
00476 
00477   // C.1) Set the required input arguments
00478 
00479   fwdInArgs = basePoint_;
00480 
00481   if (!is_null(fwdStateSolutionBuffer_)) {
00482     const Scalar t = fwdTimeRange_.length() - t_bar;
00483     RCP<const Thyra::VectorBase<Scalar> > x, x_dot;
00484     get_x_and_x_dot<Scalar>( *fwdStateSolutionBuffer_, t,
00485       outArg(x), outArg(x_dot) );
00486     fwdInArgs.set_x(x);
00487     fwdInArgs.set_x_dot(x);
00488   }
00489   else {
00490     // If we don't have an IB object to get the state from, we will assume
00491     // that the problem is linear and, therefore, we can pass in any old value
00492     // of x, x_dot, and t and get the W_bar_adj object that we need.  For this
00493     // purpose, we will assume the model's base point will do.
00494 
00495     // 2008/05/14: rabartl: ToDo: Implement real variable dependancy
00496     // communication support to make sure that this is okay!  If the model is
00497     // really nonlinear we need to check for this and throw if the user did
00498     // not set up a fwdStateSolutionBuffer object!
00499   }
00500 
00501 
00502   // C.2) Evaluate W_bar_adj if needed
00503 
00504   RCP<Thyra::LinearOpWithSolveBase<Scalar> > W_bar_adj;
00505   RCP<Thyra::LinearOpBase<Scalar> > W_bar_adj_op;
00506   {
00507 
00508     MEB::OutArgs<Scalar> fwdOutArgs = fwdStateModel_->createOutArgs();
00509     
00510     // Get or create W_bar_adj or W_bar_adj_op if needed
00511     if (!is_null(W_bar)) {
00512       // If we have W_bar, the W_bar_adj was already created in
00513       // this->create_W()
00514       W_bar_adj = W_bar->getNonconstOp();
00515       W_bar_adj_op = W_bar_adj;
00516     }
00517     else if (!is_null(W_bar_op)) {
00518       // If we have W_bar_op, the W_bar_adj_op was already created in
00519       // this->create_W_op()
00520       W_bar_adj_op = W_bar_op->getNonconstOp();
00521     }
00522     else if (!is_null(f_bar)) {
00523       TEUCHOS_TEST_FOR_EXCEPT_MSG(true, "ToDo: Unit test this code!");
00524       // If the user did not pass in W_bar or W_bar_op, then we need to create
00525       // our own local LOB form W_bar_adj_op of W_bar_adj in order to evaluate
00526       // the residual f_bar
00527       if (is_null(my_W_bar_adj_op_)) {
00528         my_W_bar_adj_op_ = fwdStateModel_->create_W_op();
00529       }
00530       W_bar_adj_op = my_W_bar_adj_op_;
00531     }
00532     
00533     // Set W_bar_adj or W_bar_adj_op on the OutArgs object
00534     if (!is_null(W_bar_adj)) {
00535       fwdOutArgs.set_W(W_bar_adj);
00536     }
00537     else if (!is_null(W_bar_adj_op)) {
00538       fwdOutArgs.set_W_op(W_bar_adj_op);
00539     }
00540     
00541     // Set alpha and beta on OutArgs object
00542     if (!is_null(W_bar_adj) || !is_null(W_bar_adj_op)) {
00543       fwdInArgs.set_alpha(alpha_bar);
00544       fwdInArgs.set_beta(beta_bar);
00545     }
00546     
00547     // Evaluate the model
00548     if (!is_null(W_bar_adj) || !is_null(W_bar_adj_op)) {
00549       fwdStateModel_->evalModel( fwdInArgs, fwdOutArgs );
00550     }
00551     
00552     // Print the objects if requested
00553     if (!is_null(W_bar_adj) && dumpAll)
00554       *out << "\nW_bar_adj = " << describe(*W_bar_adj, Teuchos::VERB_EXTREME);
00555     if (!is_null(W_bar_adj_op) && dumpAll)
00556       *out << "\nW_bar_adj_op = " << describe(*W_bar_adj_op, Teuchos::VERB_EXTREME);
00557 
00558   }
00559   
00560   // C.3) Evaluate d(f)/d(x_dot) if needed
00561 
00562   RCP<Thyra::LinearOpBase<Scalar> > d_f_d_x_dot_op;
00563   if (!is_null(f_bar)) {
00564     if (is_null(my_d_f_d_x_dot_op_)) {
00565       my_d_f_d_x_dot_op_ = fwdStateModel_->create_W_op();
00566     }
00567     d_f_d_x_dot_op = my_d_f_d_x_dot_op_;
00568     MEB::OutArgs<Scalar> fwdOutArgs = fwdStateModel_->createOutArgs();
00569     fwdOutArgs.set_W_op(d_f_d_x_dot_op);
00570     fwdInArgs.set_alpha(ST::one());
00571     fwdInArgs.set_beta(ST::zero());
00572     fwdStateModel_->evalModel( fwdInArgs, fwdOutArgs );
00573     if (dumpAll) {
00574       *out << "\nd_f_d_x_dot_op = " << describe(*d_f_d_x_dot_op, Teuchos::VERB_EXTREME);
00575     }
00576   }
00577 
00578   //
00579   // D) Evaluate the adjoint equation residual:
00580   //
00581   //   f_bar = d(f)/d(x_dot)^T * lambda_hat + 1/beta_bar * W_bar_adj^T * lambda
00582   //           - d(g)/d(x)^T
00583   //
00584 
00585   if (!is_null(f_bar)) {
00586 
00587     // D.1) lambda_hat = lambda_rev_dot - alpha_bar/beta_bar * lambda
00588     const RCP<Thyra::VectorBase<Scalar> >
00589       lambda_hat = createMember(lambda_rev_dot->space());
00590     Thyra::V_VpStV<Scalar>( outArg(*lambda_hat),
00591       *lambda_rev_dot, -alpha_bar/beta_bar, *lambda );
00592     if (dumpAll)
00593       *out << "\nlambda_hat = " << describe(*lambda_hat, Teuchos::VERB_EXTREME);
00594 
00595     // D.2) f_bar = d(f)/d(x_dot)^T * lambda_hat
00596     Thyra::apply<Scalar>( *d_f_d_x_dot_op, Thyra::CONJTRANS, *lambda_hat,
00597       outArg(*f_bar) );
00598 
00599     // D.3) f_bar += 1/beta_bar * W_bar_adj^T * lambda
00600     Thyra::apply<Scalar>( *W_bar_adj_op, Thyra::CONJTRANS, *lambda,
00601       outArg(*f_bar), 1.0/beta_bar, ST::one() );
00602 
00603     // D.4) f_bar += - d(g)/d(x)^T
00604     // 2008/05/15: rabart: ToDo: Implement once we add support for
00605     // distributed response functions
00606 
00607     if (dumpAll)
00608       *out << "\nf_bar = " << describe(*f_bar, Teuchos::VERB_EXTREME);
00609 
00610   }
00611 
00612   if (dumpAll) {
00613     if (!is_null(W_bar)) {
00614       *out << "\nW_bar = " << describe(*W_bar, Teuchos::VERB_EXTREME);
00615     }
00616     if (!is_null(W_bar_op)) {
00617       *out << "\nW_bar_op = " << describe(*W_bar_op, Teuchos::VERB_EXTREME);
00618     }
00619   }
00620 
00621 
00622   //
00623   // E) Do any remaining post processing
00624   //
00625 
00626   THYRA_MODEL_EVALUATOR_DECORATOR_EVAL_MODEL_END();
00627 
00628 }
00629 
00630 
00631 // private
00632 
00633 
00634 template<class Scalar>
00635 void AdjointModelEvaluator<Scalar>::initialize() const
00636 {
00637 
00638   typedef Thyra::ModelEvaluatorBase MEB;
00639 
00640   if (isInitialized_)
00641     return;
00642 
00643   //
00644   // A) Validate the that forward Model is of the correct form!
00645   //
00646 
00647   MEB::InArgs<Scalar> fwdStateModelInArgs = fwdStateModel_->createInArgs();
00648   MEB::OutArgs<Scalar> fwdStateModelOutArgs = fwdStateModel_->createOutArgs();
00649 
00650 #ifdef HAVE_RYTHMOS_DEBUG
00651   TEUCHOS_ASSERT( fwdStateModelInArgs.supports(MEB::IN_ARG_x_dot) );
00652   TEUCHOS_ASSERT( fwdStateModelInArgs.supports(MEB::IN_ARG_x) );
00653   TEUCHOS_ASSERT( fwdStateModelInArgs.supports(MEB::IN_ARG_t) );
00654   TEUCHOS_ASSERT( fwdStateModelInArgs.supports(MEB::IN_ARG_alpha) );
00655   TEUCHOS_ASSERT( fwdStateModelInArgs.supports(MEB::IN_ARG_beta) );
00656   TEUCHOS_ASSERT( fwdStateModelOutArgs.supports(MEB::OUT_ARG_f) );
00657   TEUCHOS_ASSERT( fwdStateModelOutArgs.supports(MEB::OUT_ARG_W) );
00658 #endif
00659 
00660   //
00661   // B) Set up the prototypical InArgs and OutArgs
00662   //
00663 
00664   {
00665     MEB::InArgsSetup<Scalar> inArgs_bar;
00666     inArgs_bar.setModelEvalDescription(this->description());
00667     inArgs_bar.setSupports( MEB::IN_ARG_x_dot );
00668     inArgs_bar.setSupports( MEB::IN_ARG_x );
00669     inArgs_bar.setSupports( MEB::IN_ARG_t );
00670     inArgs_bar.setSupports( MEB::IN_ARG_alpha );
00671     inArgs_bar.setSupports( MEB::IN_ARG_beta );
00672     prototypeInArgs_bar_ = inArgs_bar;
00673   }
00674 
00675   {
00676     MEB::OutArgsSetup<Scalar> outArgs_bar;
00677     outArgs_bar.setModelEvalDescription(this->description());
00678     outArgs_bar.setSupports(MEB::OUT_ARG_f);
00679     if (fwdStateModelOutArgs.supports(MEB::OUT_ARG_W) ) {
00680       outArgs_bar.setSupports(MEB::OUT_ARG_W);
00681       outArgs_bar.set_W_properties(fwdStateModelOutArgs.get_W_properties());
00682     }
00683     if (fwdStateModelOutArgs.supports(MEB::OUT_ARG_W_op) ) {
00684       outArgs_bar.setSupports(MEB::OUT_ARG_W_op);
00685       outArgs_bar.set_W_properties(fwdStateModelOutArgs.get_W_properties());
00686     }
00687     prototypeOutArgs_bar_ = outArgs_bar;
00688   }
00689 
00690   //
00691   // D) Set up the nominal values for the adjoint
00692   //
00693 
00694   // Copy structure
00695   adjointNominalValues_ = prototypeInArgs_bar_;
00696   // Just set a zero initial condition for the adjoint
00697   const RCP<Thyra::VectorBase<Scalar> > zero_lambda_vec =
00698     createMember(fwdStateModel_->get_f_space());
00699   V_S( zero_lambda_vec.ptr(), ScalarTraits<Scalar>::zero() );
00700   adjointNominalValues_.set_x_dot(zero_lambda_vec);
00701   adjointNominalValues_.set_x(zero_lambda_vec);
00702 
00703   //
00704   // E) Wipe out other cached objects
00705   //
00706 
00707   my_W_bar_adj_op_ = Teuchos::null;
00708   my_d_f_d_x_dot_op_ = Teuchos::null;
00709 
00710   //
00711   // F) We are initialized!
00712   //
00713 
00714   isInitialized_ = true;
00715 
00716 }
00717 
00718 
00719 } // namespace Rythmos
00720 
00721 
00722 #endif // RYTHMOS_ADJOINT_MODEL_EVALUATOR_HPP
 All Classes Functions Variables Typedefs Friends