MOOCHO/Thyra Adapter Software Version of the Day
NLPInterfacePack_NLPThyraModelEvaluatorBase.cpp
00001 // @HEADER
00002 // ***********************************************************************
00003 // 
00004 // Moocho: Multi-functional Object-Oriented arCHitecture for Optimization
00005 //                  Copyright (2003) 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 // Redistribution and use in source and binary forms, with or without
00011 // modification, are permitted provided that the following conditions are
00012 // met:
00013 //
00014 // 1. Redistributions of source code must retain the above copyright
00015 // notice, this list of conditions and the following disclaimer.
00016 //
00017 // 2. Redistributions in binary form must reproduce the above copyright
00018 // notice, this list of conditions and the following disclaimer in the
00019 // documentation and/or other materials provided with the distribution.
00020 //
00021 // 3. Neither the name of the Corporation nor the names of the
00022 // contributors may be used to endorse or promote products derived from
00023 // this software without specific prior written permission.
00024 //
00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00036 //
00037 // Questions? Contact Roscoe A. Bartlett (rabartl@sandia.gov) 
00038 // 
00039 // ***********************************************************************
00040 // @HEADER
00041 
00042 //
00043 // Note: I am using a BasisSystem here just to make it easy to generate
00044 // var_dep() and var_indep() and for not much else.
00045 //
00046 
00047 #include "NLPInterfacePack_NLPThyraModelEvaluatorBase.hpp"
00048 #include "AbstractLinAlgPack_LinAlgOpPack.hpp"
00049 #include "AbstractLinAlgPack_VectorOut.hpp"
00050 #include "AbstractLinAlgPack_ThyraAccessors.hpp"
00051 #include "AbstractLinAlgPack_VectorSpaceThyra.hpp"
00052 #include "AbstractLinAlgPack_VectorMutableThyra.hpp"
00053 #include "AbstractLinAlgPack_MatrixOpNonsingThyra.hpp"
00054 #include "AbstractLinAlgPack_BasisSystemComposite.hpp"
00055 #include "AbstractLinAlgPack_VectorSpaceBlocked.hpp"
00056 #include "AbstractLinAlgPack_VectorAuxiliaryOps.hpp"
00057 #include "AbstractLinAlgPack_MatrixSymPosDefCholFactor.hpp"
00058 #include "Thyra_DetachedVectorView.hpp"
00059 #include "Thyra_VectorStdOps.hpp"
00060 #include "Teuchos_AbstractFactoryStd.hpp"
00061 #include "Teuchos_Assert.hpp"
00062 #include "Teuchos_dyn_cast.hpp"
00063 
00064 namespace NLPInterfacePack {
00065   
00066 // Overridden public members from NLP
00067 
00068 void NLPThyraModelEvaluatorBase::initialize(bool test_setup)
00069 {
00070   x_guess_bounds_updated_ = false;
00071   updateInitialGuessAndBounds();
00072   if(initialized_) {
00073     NLPObjGrad::initialize(test_setup);
00074     return;
00075   }
00076   //TEUCHOS_TEST_FOR_EXCEPT(true); // Todo: push the variables in bounds!
00077   num_bounded_x_ = AbstractLinAlgPack::num_bounded(*xl_,*xu_,NLP::infinite_bound());
00078   NLPObjGrad::initialize(test_setup);
00079   initialized_ = true;
00080 }
00081 
00082 bool NLPThyraModelEvaluatorBase::is_initialized() const
00083 {
00084   return initialized_;
00085 }
00086 
00087 NLP::vec_space_ptr_t
00088 NLPThyraModelEvaluatorBase::space_x() const
00089 {
00090   return space_x_;
00091 }
00092 
00093 NLP::vec_space_ptr_t
00094 NLPThyraModelEvaluatorBase::space_c() const
00095 {
00096   return space_c_;
00097 }
00098 
00099 size_type NLPThyraModelEvaluatorBase::num_bounded_x() const
00100 {
00101   return num_bounded_x_;
00102 }
00103 
00104 void NLPThyraModelEvaluatorBase::force_xinit_in_bounds(bool force_xinit_in_bounds)
00105 {
00106   force_xinit_in_bounds_ = force_xinit_in_bounds;
00107 }
00108 
00109 bool NLPThyraModelEvaluatorBase::force_xinit_in_bounds() const
00110 {
00111   return force_xinit_in_bounds_;
00112 }
00113 
00114 const Vector& NLPThyraModelEvaluatorBase::xinit() const
00115 {
00116   updateInitialGuessAndBounds();
00117   return *xinit_;
00118 }
00119 
00120 const Vector& NLPThyraModelEvaluatorBase::xl() const
00121 {
00122   updateInitialGuessAndBounds();
00123   return *xl_;
00124 }
00125 
00126 const Vector& NLPThyraModelEvaluatorBase::xu() const
00127 {
00128   updateInitialGuessAndBounds();
00129   return *xu_;
00130 }
00131 
00132 value_type NLPThyraModelEvaluatorBase::max_var_bounds_viol() const
00133 {
00134   return 1e-5; // I have no idea?
00135 }
00136 
00137 void NLPThyraModelEvaluatorBase::set_f(value_type* f)
00138 {
00139   NLP::set_f(f);
00140   f_updated_ = false;
00141 }
00142 
00143 void NLPThyraModelEvaluatorBase::set_c(VectorMutable* c)
00144 {
00145   NLP::set_c(c);
00146   c_updated_ = false;
00147 }
00148 
00149 void NLPThyraModelEvaluatorBase::unset_quantities()
00150 {
00151   NLP::unset_quantities();
00152 }
00153 
00154 void NLPThyraModelEvaluatorBase::scale_f( value_type scale_f )
00155 {
00156   obj_scale_ = scale_f;
00157 }
00158 
00159 value_type NLPThyraModelEvaluatorBase::scale_f() const
00160 {
00161   return obj_scale_;
00162 }
00163 
00164 void NLPThyraModelEvaluatorBase::report_final_solution(
00165   const Vector&    x
00166   ,const Vector*   lambda
00167   ,const Vector*   nu
00168   ,bool            optimal
00169   )
00170 {
00171   using Teuchos::dyn_cast;
00172   using Teuchos::RCP;
00173   typedef Thyra::ModelEvaluatorBase MEB;
00174   using AbstractLinAlgPack::VectorMutableThyra;
00175   MEB::InArgs<value_type> model_finalPoint = model_->createInArgs();
00176   if( basis_sys_.get() ) {
00177     const Range1D
00178       var_dep   = basis_sys_->var_dep(),
00179       var_indep = basis_sys_->var_indep();
00180     RCP<const Vector> xD = x.sub_view(var_dep), xI;
00181     if(p_idx_>=0) xI = x.sub_view(var_indep);
00182     model_finalPoint.set_x(dyn_cast<const VectorMutableThyra>(*xD).thyra_vec().assert_not_null());
00183     if(p_idx_ >= 0)
00184       model_finalPoint.set_p(p_idx_,dyn_cast<const VectorMutableThyra>(*xI).thyra_vec().assert_not_null());
00185     else if( model_finalPoint.Np() >= 1 )
00186       model_finalPoint.set_p(0,model_->getNominalValues().get_p(0)); // Assume we will find in it zero!
00187   }
00188   else { // no dependent vars
00189     TEUCHOS_TEST_FOR_EXCEPT(p_idx_<0);
00190     model_finalPoint.set_p(p_idx_,dyn_cast<const VectorMutableThyra>(x).thyra_vec().assert_not_null());
00191   }
00192   model_->reportFinalPoint(model_finalPoint,optimal);
00193 }
00194 
00195 // Overridden public members from NLPObjGrad
00196 
00197 void NLPThyraModelEvaluatorBase::set_Gf(VectorMutable* Gf)
00198 {
00199   NLPObjGrad::set_Gf(Gf);
00200   Gf_updated_ = false;
00201 }
00202 
00203 // Overridden protected members from NLP
00204 
00205 void NLPThyraModelEvaluatorBase::imp_calc_f(
00206   const Vector& x, bool newx
00207   ,const ZeroOrderInfo& zero_order_info
00208   ) const
00209 {
00210   evalModel(x,newx,&zero_order_info,NULL);
00211 }
00212 
00213 void NLPThyraModelEvaluatorBase::imp_calc_c(
00214   const Vector& x, bool newx
00215   ,const ZeroOrderInfo& zero_order_info
00216   ) const
00217 {
00218   evalModel(x,newx,&zero_order_info,NULL);
00219 }
00220 
00221 // Overridden protected members from NLPObjGrad
00222 
00223 void NLPThyraModelEvaluatorBase::imp_calc_Gf(
00224   const Vector& x, bool newx
00225   ,const ObjGradInfo& obj_grad_info
00226   ) const
00227 {
00228   evalModel(x,newx,NULL,&obj_grad_info);
00229 }
00230 
00231 // Protected functions to be used by subclasses
00232 
00233 NLPThyraModelEvaluatorBase::NLPThyraModelEvaluatorBase()
00234   :showModelEvaluatorTrace_(false),initialized_(false)
00235   ,obj_scale_(1.0),has_bounds_(false)
00236   ,force_xinit_in_bounds_(true),num_bounded_x_(0)
00237   ,x_guess_bounds_updated_(false)
00238 {}
00239 
00240 void NLPThyraModelEvaluatorBase::initializeBase(
00241   const Teuchos::RCP<Thyra::ModelEvaluator<value_type> >  &model,
00242   const int p_idx,
00243   const int g_idx
00244   )
00245 {
00246 
00247   using Teuchos::dyn_cast;
00248   using AbstractLinAlgPack::VectorSpaceThyra;
00249   using AbstractLinAlgPack::VectorMutableThyra;
00250   using AbstractLinAlgPack::MatrixOpNonsingThyra;
00251   typedef ::Thyra::ModelEvaluatorBase MEB;
00252 
00253   initialized_ = false;
00254   x_guess_bounds_updated_ = false;
00255   model_g_updated_ = model_Dg_updated_ = f_updated_ = c_updated_ = Gf_updated_ = Gc_updated_ = false;
00256 
00257   const char msg_err[] = "NLPThyraModelEvaluatorBase::initialize(...): Errror!";
00258   Thyra::ModelEvaluatorBase::OutArgs<value_type> model_outArgs = model->createOutArgs();
00259   TEUCHOS_TEST_FOR_EXCEPTION( model.get() == NULL, std::invalid_argument, msg_err );
00260   TEUCHOS_TEST_FOR_EXCEPTION( p_idx >= 0 && ( p_idx > model_outArgs.Np()-1 ), std::invalid_argument, msg_err );
00261   TEUCHOS_TEST_FOR_EXCEPTION( g_idx >= 0 && ( g_idx > model_outArgs.Ng()-1 ), std::invalid_argument, msg_err );
00262   //
00263   Teuchos::RCP<const Thyra::VectorSpaceBase<value_type> > model_space_x(model->get_x_space());
00264   const bool no_model_x = (model_space_x.get() == NULL);
00265   Teuchos::RCP<const Thyra::VectorSpaceBase<value_type> > model_space_f(model->get_f_space());
00266   const bool no_model_f = (model_space_f.get() == NULL);
00267   //
00268   if( !no_model_f ) {
00269     TEUCHOS_TEST_FOR_EXCEPTION( !model_outArgs.supports(MEB::OUT_ARG_W), std::invalid_argument, msg_err );
00270     MEB::DerivativeProperties model_W_properties = model_outArgs.get_W_properties();
00271     TEUCHOS_TEST_FOR_EXCEPTION( model_W_properties.supportsAdjoint==false, std::invalid_argument, msg_err );
00272     TEUCHOS_TEST_FOR_EXCEPTION( model_W_properties.rank==MEB::DERIV_RANK_DEFICIENT, std::invalid_argument, msg_err );
00273     /*
00274     if(p_idx >= 0 ) {
00275       TEUCHOS_TEST_FOR_EXCEPTION( model_outArgs.supports(MEB::OUT_ARG_DfDp,p_idx).none(), std::invalid_argument, msg_err );
00276       if(g_idx >= 0) {
00277         TEUCHOS_TEST_FOR_EXCEPTION( model_outArgs.supports(MEB::OUT_ARG_DgDp,g_idx,p_idx).none(), std::invalid_argument, msg_err );
00278       }
00279     }
00280     if(g_idx >= 0) {
00281       TEUCHOS_TEST_FOR_EXCEPTION( model_outArgs.supports(MEB::OUT_ARG_DgDx,g_idx).none(), std::invalid_argument, msg_err );
00282     }
00283     */
00284   }
00285 
00286   model_ = model;
00287   p_idx_ = p_idx;
00288   g_idx_ = g_idx;
00289 
00290   if(p_idx >= 0 ) {
00291     DfDp_supports_op_ = model_outArgs.supports(MEB::OUT_ARG_DfDp,p_idx).supports(MEB::DERIV_LINEAR_OP);
00292     DfDp_supports_mv_ = model_outArgs.supports(MEB::OUT_ARG_DfDp,p_idx).supports(MEB::DERIV_MV_BY_COL);
00293   }
00294   else {
00295     DfDp_supports_op_ = false;
00296     DfDp_supports_mv_ = false;
00297   }
00298 
00299   VectorSpace::space_ptr_t space_xI;
00300   if(p_idx >= 0)
00301     space_xI = Teuchos::rcp(new VectorSpaceThyra(model_->get_p_space(p_idx)));
00302   VectorSpace::space_ptr_t space_xD;
00303   //
00304   if(!no_model_x) {
00305     space_xD = Teuchos::rcp(new VectorSpaceThyra(model_space_x));
00306     if (p_idx >= 0)  {
00307       VectorSpace::space_ptr_t spaces_xD_xI[] = { space_xD, space_xI };
00308       space_x_ = Teuchos::rcp(new VectorSpaceBlocked(spaces_xD_xI,2));
00309     }
00310     else {
00311       space_x_ = space_xD;
00312     }
00313   }
00314   else {
00315     space_x_ = space_xI;
00316   } 
00317   TEUCHOS_TEST_FOR_EXCEPT(!space_x_.get());
00318 
00319   if(!no_model_f)
00320     space_c_ = Teuchos::rcp(new VectorSpaceThyra(model_space_f));
00321   else
00322     space_c_ = Teuchos::null;
00323 
00324   xinit_ = space_x_->create_member();  *xinit_ = 0.0;
00325   xl_    = space_x_->create_member();  *xl_    = -NLP::infinite_bound();
00326   xu_    = space_x_->create_member();  *xu_    = +NLP::infinite_bound();
00327 
00328   if(!no_model_f) {
00329 
00330     factory_Gc_ = BasisSystemComposite::factory_Gc();
00331 
00332     basis_sys_ = Teuchos::rcp(
00333       new BasisSystemComposite(
00334         space_x_
00335         ,space_c_
00336         ,Teuchos::rcp(new Teuchos::AbstractFactoryStd<MatrixOpNonsing,MatrixOpNonsingThyra>())          // factory_C
00337         ,Teuchos::rcp(new Teuchos::AbstractFactoryStd<MatrixSymOp,MatrixSymPosDefCholFactor>())         // factory_transDtD
00338         ,Teuchos::rcp(new Teuchos::AbstractFactoryStd<MatrixSymOpNonsing,MatrixSymPosDefCholFactor>())  // factory_S
00339         )
00340       );
00341 
00342   }
00343   else {
00344 
00345     factory_Gc_ = Teuchos::null;
00346 
00347     basis_sys_ = Teuchos::null;
00348 
00349   }
00350   
00351   if(g_idx >= 0) {
00352     model_g_ = createMember(model_->get_g_space(g_idx));
00353   }
00354 
00355 }
00356 
00357 void NLPThyraModelEvaluatorBase::updateInitialGuessAndBounds() const
00358 {
00359 
00360   using Teuchos::dyn_cast;
00361   using AbstractLinAlgPack::VectorSpaceThyra;
00362   using AbstractLinAlgPack::VectorMutableThyra;
00363   using AbstractLinAlgPack::MatrixOpNonsingThyra;
00364   typedef ::Thyra::ModelEvaluatorBase MEB;
00365 
00366   if (x_guess_bounds_updated_)
00367     return;
00368 
00369   Thyra::ModelEvaluatorBase::OutArgs<value_type>
00370     model_outArgs = model_->createOutArgs();
00371   Teuchos::RCP<const Thyra::VectorSpaceBase<value_type> >
00372     model_space_x = model_->get_x_space();
00373   const bool
00374     no_model_x = (model_space_x.get() == NULL);
00375   Teuchos::RCP<const Thyra::VectorSpaceBase<value_type> >
00376     model_space_f = model_->get_f_space();
00377   const bool
00378     no_model_f = (model_space_f.get() == NULL);
00379 
00380   Thyra::ModelEvaluatorBase::InArgs<value_type>
00381     model_initialGuess = model_->getNominalValues(),
00382     model_lowerBounds = model_->getLowerBounds(),
00383     model_upperBounds = model_->getUpperBounds();
00384 
00385   if(!no_model_x) {
00386     VectorSpace::vec_mut_ptr_t xinit_D = xinit_->sub_view(basis_sys_->var_dep());
00387     copy_from_model_x( model_initialGuess.get_x().get(), &*xinit_D );
00388     VectorSpace::vec_mut_ptr_t xl_D = xl_->sub_view(basis_sys_->var_dep());
00389     copy_from_model_x( model_lowerBounds.get_x().get(), &*xl_D );
00390     VectorSpace::vec_mut_ptr_t xu_D = xu_->sub_view(basis_sys_->var_dep());
00391     copy_from_model_x( model_upperBounds.get_x().get(), &*xu_D );
00392   }
00393 
00394   if(p_idx_ >= 0) {
00395     Range1D var_indep = ( basis_sys_.get() ? basis_sys_->var_indep() : Range1D() );
00396     VectorSpace::vec_mut_ptr_t xinit_I = xinit_->sub_view(var_indep);
00397     copy_from_model_p( model_initialGuess.get_p(p_idx_).get(), &*xinit_I );
00398     VectorSpace::vec_mut_ptr_t xl_I = xl_->sub_view(var_indep);
00399     copy_from_model_p( model_lowerBounds.get_p(p_idx_).get(), &*xl_I );
00400     VectorSpace::vec_mut_ptr_t xu_I = xu_->sub_view(var_indep);
00401     copy_from_model_p( model_upperBounds.get_p(p_idx_).get(), &*xu_I );
00402   }
00403 
00404   x_guess_bounds_updated_ = true;
00405 
00406 }
00407 
00408 void NLPThyraModelEvaluatorBase::assert_is_initialized() const
00409 {
00410   TEUCHOS_TEST_FOR_EXCEPTION(
00411     !is_initialized(), NLP::UnInitialized
00412     ,"NLPThyraModelEvaluatorBase::assert_is_initialized() : Error, "
00413     "NLPThyraModelEvaluatorBase::initialize() has not been called yet."
00414     );
00415 }
00416 
00417 void NLPThyraModelEvaluatorBase::copy_from_model_x( const Thyra::VectorBase<value_type>* model_x, VectorMutable* x_D ) const
00418 {
00419   if(!model_x) return;
00420   *x_D = AbstractLinAlgPack::VectorMutableThyra(Teuchos::rcp(const_cast<Thyra::VectorBase<value_type>*>(model_x),false));
00421 }
00422 
00423 void NLPThyraModelEvaluatorBase::copy_from_model_p( const Thyra::VectorBase<value_type> *model_p, VectorMutable* x_I ) const
00424 {
00425   if(!model_p) return;
00426   *x_I = AbstractLinAlgPack::VectorMutableThyra(Teuchos::rcp(const_cast<Thyra::VectorBase<value_type>*>(model_p),false));
00427 }
00428 
00429 void NLPThyraModelEvaluatorBase::set_x(
00430   const Vector                                      &x
00431   ,Thyra::ModelEvaluatorBase::InArgs<value_type>    *model_inArgs_inout
00432   ) const
00433 {
00434   using Teuchos::dyn_cast;
00435   using Teuchos::RCP;
00436   using Teuchos::rcp_const_cast;
00437   using Teuchos::rcp_dynamic_cast;
00438   using AbstractLinAlgPack::VectorMutableThyra;
00439   typedef Thyra::ModelEvaluatorBase MEB;
00440   //
00441   // Set the input arguments
00442   //
00443   MEB::InArgs<value_type> &model_inArgs = *model_inArgs_inout;
00444   if( basis_sys_.get() ) {
00445     const Range1D
00446       var_dep   = basis_sys_->var_dep(),
00447       var_indep = basis_sys_->var_indep();
00448     RCP<const Vector> xD = x.sub_view(var_dep), xI;
00449     if(p_idx_>=0) xI = x.sub_view(var_indep);
00450     model_inArgs.set_x(dyn_cast<const VectorMutableThyra>(*xD).thyra_vec().assert_not_null());
00451     if(p_idx_ >= 0)
00452       model_inArgs.set_p(p_idx_,dyn_cast<const VectorMutableThyra>(*xI).thyra_vec().assert_not_null());
00453   }
00454   else { // no dependent vars
00455     TEUCHOS_TEST_FOR_EXCEPT(p_idx_<0);
00456     model_inArgs.set_p(p_idx_,dyn_cast<const VectorMutableThyra>(x).thyra_vec().assert_not_null());
00457   }
00458 }
00459 
00460 void NLPThyraModelEvaluatorBase::preprocessBaseInOutArgs(
00461   const Vector                                      &x
00462   ,bool                                             newx
00463   ,const ZeroOrderInfo                              *zero_order_info
00464   ,const ObjGradInfo                                *obj_grad_info
00465   ,const NLPFirstOrder::FirstOrderInfo              *first_order_info
00466   ,Thyra::ModelEvaluatorBase::InArgs<value_type>    *model_inArgs_inout
00467   ,Thyra::ModelEvaluatorBase::OutArgs<value_type>   *model_outArgs_inout
00468   ,MatrixOp*                                        *Gc_out
00469   ,VectorMutable*                                   *Gf_out
00470   ,value_type*                                      *f_out
00471   ,VectorMutable*                                   *c_out
00472   ) const
00473 {
00474   using Teuchos::dyn_cast;
00475   using Teuchos::RCP;
00476   using Teuchos::rcp_const_cast;
00477   using Teuchos::rcp_dynamic_cast;
00478   using AbstractLinAlgPack::VectorMutableThyra;
00479   using AbstractLinAlgPack::MatrixOpThyra;
00480   using AbstractLinAlgPack::MatrixOpNonsingThyra;
00481   typedef Thyra::ModelEvaluatorBase MEB;
00482   typedef MEB::DerivativeMultiVector<value_type> DerivMV;
00483   typedef MEB::Derivative<value_type> Deriv;
00484   //
00485   if(newx) model_g_updated_ = model_Dg_updated_ = f_updated_ = c_updated_ = Gf_updated_ = Gc_updated_ = false;
00486   //
00487   // Set the input arguments
00488   //
00489   MEB::InArgs<value_type> &model_inArgs = *model_inArgs_inout;
00490   set_x(x,&model_inArgs);
00491   //
00492   // Set the output arguments
00493   //
00494   MatrixOp            *Gc = NULL;
00495   VectorMutable       *Gf = NULL;
00496   value_type          *f  = NULL;
00497   VectorMutable       *c  = NULL;
00498   //
00499   if(zero_order_info) {
00500     f = zero_order_info->f;
00501     c = zero_order_info->c;
00502   }
00503   else if(obj_grad_info) {
00504     Gf = obj_grad_info->Gf;
00505     f  = obj_grad_info->f;
00506     c  = obj_grad_info->c;
00507   }
00508   else if(first_order_info) {
00509     Gc = first_order_info->Gc;
00510     Gf = first_order_info->Gf;
00511     f  = first_order_info->f;
00512     c  = first_order_info->c;
00513   }
00514   else {
00515     TEUCHOS_TEST_FOR_EXCEPT(true); // Should never be called!
00516   }
00517   //
00518   MEB::OutArgs<value_type> &model_outArgs = *model_outArgs_inout;
00519   if( f && (g_idx_>=0) && !f_updated_ ) {
00520     model_outArgs.set_g(g_idx_,model_g_.assert_not_null()); // ToDo: Make more general!
00521   }
00522   if( c && !c_updated_ ) {
00523     Teuchos::RCP<Thyra::VectorBase<value_type> > thyra_c;
00524     get_thyra_vector(*space_c_,c,&thyra_c);
00525     model_outArgs.set_f(thyra_c.assert_not_null());
00526   }
00527   if( Gf && !Gf_updated_ ) {
00528     if(g_idx_>=0) {
00529       if(p_idx_>=0) {
00530         const Range1D
00531           var_dep   = ( basis_sys_.get() ? basis_sys_->var_dep() : Range1D::Invalid ),
00532           var_indep = ( basis_sys_.get() ? basis_sys_->var_indep() : Range1D() );
00533         if( var_dep.size() ) {
00534           model_outArgs.set_DgDx(
00535             g_idx_
00536             ,DerivMV(
00537               rcp_const_cast<Thyra::VectorBase<value_type> >(
00538                 dyn_cast<VectorMutableThyra>(*Gf->sub_view(var_dep)).thyra_vec()
00539                 ).assert_not_null()
00540               ,MEB::DERIV_TRANS_MV_BY_ROW
00541               )
00542             );
00543         }
00544         model_outArgs.set_DgDp(
00545           g_idx_,p_idx_
00546           ,DerivMV(
00547             rcp_const_cast<Thyra::VectorBase<value_type> >(
00548               dyn_cast<VectorMutableThyra>(*Gf->sub_view(var_indep)).thyra_vec()
00549               ).assert_not_null()
00550             ,MEB::DERIV_TRANS_MV_BY_ROW
00551             )
00552           );
00553       }
00554     }
00555   }
00556   if(Gc_out) *Gc_out = Gc;
00557   if(Gf_out) *Gf_out = Gf;
00558   if(f_out)  *f_out  = f;
00559   if(c_out)  *c_out  = c;
00560 }
00561 
00562 void NLPThyraModelEvaluatorBase::postprocessBaseOutArgs(
00563   Thyra::ModelEvaluatorBase::OutArgs<value_type>        *model_outArgs_inout
00564   ,VectorMutable                                        *Gf
00565   ,value_type                                           *f
00566   ,VectorMutable                                        *c
00567   ) const
00568 {
00569   typedef Thyra::ModelEvaluatorBase MEB;
00570   MEB::OutArgs<value_type> &model_outArgs = *model_outArgs_inout;
00571   if( f && !f_updated_ ) {
00572     if(g_idx_>=0) {
00573       *f = obj_scale_ * ::Thyra::get_ele(*model_g_,0);
00574     }
00575     else {
00576       *f = 0.0;
00577     }
00578     f_updated_ = true;
00579   }
00580   if( c && !c_updated_ ) {
00581     Teuchos::RCP<Thyra::VectorBase<value_type> >
00582       thyra_c = model_outArgs.get_f();
00583     commit_thyra_vector(*space_c_,c,&thyra_c);
00584     model_outArgs.set_f(Teuchos::null);
00585     c_updated_ = true;
00586   }
00587   if( Gf && !Gf_updated_ ) {
00588     if(g_idx_>=0) {
00589       const Range1D
00590         var_dep   = ( basis_sys_.get() ? basis_sys_->var_dep() : Range1D::Invalid ),
00591         var_indep = ( basis_sys_.get() ? basis_sys_->var_indep() : Range1D() );
00592       if (obj_scale_ != 1.0 )
00593         Vt_S( Gf, obj_scale_ );
00594       if(var_dep.size())
00595         Gf->sub_view(var_dep)->has_changed();
00596       if(var_indep.size())
00597         Gf->sub_view(var_indep)->has_changed();
00598     }
00599     else {
00600       *Gf = 0.0;
00601     }
00602     Gf_updated_ = true;
00603   }
00604 }
00605 
00606 // private
00607 
00608 void NLPThyraModelEvaluatorBase::evalModel( 
00609   const Vector            &x
00610   ,bool                   newx
00611   ,const ZeroOrderInfo    *zero_order_info
00612   ,const ObjGradInfo      *obj_grad_info
00613   ) const
00614 {
00615   typedef Thyra::ModelEvaluatorBase MEB;
00616   //
00617   // Get output and verbosity
00618   //
00619   const Teuchos::RCP<Teuchos::FancyOStream>
00620     out = this->getOStream();
00621   const Teuchos::EVerbosityLevel
00622     verbLevel = ( showModelEvaluatorTrace() ? this->getVerbLevel() : Teuchos::VERB_NONE );
00623   Teuchos::OSTab tab(out);
00624   typedef Teuchos::VerboseObjectTempState<MEB> VOTSME;
00625   VOTSME modelOutputTempState(model_,out,verbLevel);
00626   if(out.get() && static_cast<int>(verbLevel) >= static_cast<int>(Teuchos::VERB_LOW))
00627     *out << "\nEntering MoochoPack::NLPThyraModelEvaluatorBase::evalModel(...) ...\n";
00628   //
00629   // Set the input and output arguments
00630   //
00631   MEB::InArgs<value_type>  model_inArgs  = model_->createInArgs();
00632   MEB::OutArgs<value_type> model_outArgs = model_->createOutArgs();
00633   VectorMutable       *Gf = NULL;
00634   value_type          *f  = NULL;
00635   VectorMutable       *c  = NULL;
00636   preprocessBaseInOutArgs(
00637     x,newx,zero_order_info,obj_grad_info,NULL
00638     ,&model_inArgs,&model_outArgs,NULL,&Gf,&f,&c
00639     );
00640   //
00641   // Evaluate the model
00642   //
00643   model_->evalModel(model_inArgs,model_outArgs);
00644   //
00645   // Postprocess the output arguments
00646   //
00647   postprocessBaseOutArgs(&model_outArgs,Gf,f,c);
00648   //
00649   if(out.get() && static_cast<int>(verbLevel) >= static_cast<int>(Teuchos::VERB_LOW))
00650     *out << "\nLeaving MoochoPack::NLPThyraModelEvaluatorBase::evalModel(...) ...\n";
00651 }
00652 
00653 } // end namespace NLPInterfacePack
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends