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

Generated on Thu Sep 18 12:34:37 2008 for MOOCHO/Thyra Adapter Software by doxygen 1.3.9.1