NLPInterfacePack_NLPThyraModelEvaluatorBase.cpp

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

Generated on Tue Oct 20 12:51:48 2009 for MOOCHO (Single Doxygen Collection) by doxygen 1.4.7