42 #include "NLPInterfacePack_NLPDirectThyraModelEvaluator.hpp"
43 #include "AbstractLinAlgPack_LinAlgOpPack.hpp"
44 #include "AbstractLinAlgPack_VectorOut.hpp"
45 #include "AbstractLinAlgPack_ThyraAccessors.hpp"
46 #include "AbstractLinAlgPack_VectorSpaceThyra.hpp"
47 #include "AbstractLinAlgPack_VectorMutableThyra.hpp"
48 #include "AbstractLinAlgPack_MultiVectorMutableThyra.hpp"
49 #include "AbstractLinAlgPack_MatrixOpNonsingThyra.hpp"
50 #include "AbstractLinAlgPack_VectorSpaceBlocked.hpp"
51 #include "AbstractLinAlgPack_VectorAuxiliaryOps.hpp"
52 #include "AbstractLinAlgPack_VectorDenseEncap.hpp"
53 #include "AbstractLinAlgPack_BasisSystem.hpp"
54 #include "AbstractLinAlgPack_LinAlgOpPack.hpp"
55 #include "Thyra_ModelEvaluatorHelpers.hpp"
56 #include "Thyra_DetachedVectorView.hpp"
57 #include "Thyra_VectorStdOps.hpp"
58 #include "Thyra_MultiVectorStdOps.hpp"
59 #include "Teuchos_AbstractFactoryStd.hpp"
60 #include "Teuchos_Assert.hpp"
61 #include "Teuchos_dyn_cast.hpp"
63 namespace NLPInterfacePack {
66 :DfDp_is_const_(false)
73 ,
const objDirecFiniteDiffCalculator_ptr_t objDirecFiniteDiffCalculator
74 ,
const conDirecFiniteDiffCalculator_ptr_t conDirecFiniteDiffCalculator
76 :DfDp_is_const_(false)
80 ,objDirecFiniteDiffCalculator,conDirecFiniteDiffCalculator
88 ,
const objDirecFiniteDiffCalculator_ptr_t objDirecFiniteDiffCalculator
89 ,
const conDirecFiniteDiffCalculator_ptr_t conDirecFiniteDiffCalculator
93 if(objDirecFiniteDiffCalculator.get())
94 this->set_objDirecFiniteDiffCalculator(objDirecFiniteDiffCalculator);
95 if(conDirecFiniteDiffCalculator.get())
96 this->set_conDirecFiniteDiffCalculator(conDirecFiniteDiffCalculator);
99 MEB::DerivativeProperties model_W_properties = model_outArgs.
get_W_properties();
102 (conDirecFiniteDiffCalculator_.get()==0 && !model_outArgs.
supports(MEB::OUT_ARG_DfDp,p_idx).supports(MEB::DERIV_MV_BY_COL))
103 ,std::invalid_argument
104 ,
"Error, model must support computing DfDp("<<p_idx<<
") as a"
105 " column-oriented multi-vector if not using finite differences!"
108 DfDp_is_const_ =
false;
132 if(objDirecFiniteDiffCalculator_.get())
141 return ( objDirecFiniteDiffCalculator_.get() != NULL );
145 const Vector& x,
const Vector& d,
bool newx
150 MEB::InArgs<value_type> basePoint = model_->createInArgs();
151 MEB::InArgs<value_type> directions = model_->createInArgs();
152 MEB::OutArgs<value_type> baseFunc = model_->createOutArgs();
153 MEB::OutArgs<value_type> variations = model_->createOutArgs();
155 set_x(d,&directions);
156 variations.set_g(g_idx_,createMember(model_->get_g_space(g_idx_)));
157 objDirecFiniteDiffCalculator_->calcVariations(
158 *model_,basePoint,directions,baseFunc,variations
160 return Thyra::get_ele(*variations.get_g(g_idx_),0);
167 return basis_sys_->var_dep();
172 return basis_sys_->var_indep();
178 return basis_sys_->factory_D();
184 return basis_sys_->factory_S();
205 using Teuchos::rcp_const_cast;
206 using Teuchos::rcp_dynamic_cast;
214 typedef MEB::DerivativeMultiVector<value_type> DerivMV;
215 typedef MEB::Derivative<value_type> Deriv;
220 out = this->getOStream();
222 verbLevel = ( showModelEvaluatorTrace() ? this->getVerbLevel() :
Teuchos::VERB_NONE );
225 VOTSME modelOutputTempState(model_,out,verbLevel);
227 VOTSDFDC objDirecFiniteDiffCalculatorOutputTempState(objDirecFiniteDiffCalculator_,out,verbLevel);
228 VOTSDFDC conDirecFiniteDiffCalculatorOutputTempState(conDirecFiniteDiffCalculator_,out,verbLevel);
229 const bool trace =
static_cast<int>(verbLevel) >= static_cast<int>(
Teuchos::VERB_LOW);
230 if(out.
get() && trace)
231 *out <<
"\nEntering MoochoPack::NLPDirectThyraModelEvaluator::calc_point(...) ...\n";
238 objDirecFiniteDiffCalculator_.get()!=NULL && Gf!=NULL, std::logic_error
239 ,
"Error, can not compute full gradient vector Gf when using directional finite differences!"
249 MEB::InArgs<value_type> model_inArgs = model_->createInArgs();
250 MEB::OutArgs<value_type> model_outArgs = model_->createOutArgs();
252 obj_grad_info.
Gf =
Gf;
254 if(recalc_c) obj_grad_info.
c =
c;
256 x,
true,NULL,&obj_grad_info,NULL
257 ,&model_inArgs,&model_outArgs,NULL,NULL,NULL,NULL
259 if( py || rGf || D ) {
260 if(thyra_C_.
get()==NULL)
261 thyra_C_ = model_->create_W();
264 bool new_thyra_N =
false;
266 if(thyra_N_.
get()==NULL) {
267 thyra_N_ = Thyra::create_DfDp_mv(*model_,p_idx_,MEB::DERIV_MV_BY_COL).getMultiVector();
271 !conDirecFiniteDiffCalculator_.get()
274 || model_outArgs.get_DfDp_properties(p_idx_).linearity!=MEB::DERIV_LINEARITY_CONST )
277 model_outArgs.set_DfDp(p_idx_,DerivMV(thyra_N_.
assert_not_null(),MEB::DERIV_MV_BY_COL));
280 if ( !
is_null(model_outArgs.get_W()) || !
is_null(model_outArgs.get_W_op()) ) {
281 if (model_inArgs.supports(MEB::IN_ARG_alpha))
282 model_inArgs.set_alpha(0.0);
283 if (model_inArgs.supports(MEB::IN_ARG_beta))
284 model_inArgs.set_beta(1.0);
289 model_->evalModel(model_inArgs,model_outArgs);
295 const VectorSpaceThyra *
space_c;
296 const VectorSpaceThyra *space_xD;
299 RCP<MatrixOp> D_used =
rcp(D,
false);
300 RCP<Thyra::MultiVectorBase<value_type> > thyra_D;
302 if( py || ( ( rGf || D ) && conDirecFiniteDiffCalculator_.get() ) ) {
303 space_c = &
dyn_cast<
const VectorSpaceThyra>(c->space()),
304 space_xD = &dyn_cast<const VectorSpaceThyra>(py->space());
305 get_thyra_vector(*space_c,*c,&thyra_c);
306 get_thyra_vector(*space_xD,py,&thyra_py);
310 if(!D) D_used = this->
factory_D()->create();
314 dyn_cast<MultiVectorMutableThyra>(*D_used).thyra_multi_vec()
322 !
is_null(conDirecFiniteDiffCalculator_)
324 ( new_thyra_N || !DfDp_is_const() )
327 if(out.
get() && trace)
328 *out <<
"\nComputing thyra_N using directional finite differences ...\n";
333 MEB::OutArgs<value_type>
334 model_fdOutArgs = conDirecFiniteDiffCalculator_->createOutArgs(
335 *model_,SelectedDerivatives().supports(MEB::OUT_ARG_DfDp,0)
337 model_fdOutArgs.set_DfDp(p_idx_,DerivMV(thyra_N_.
assert_not_null(),MEB::DERIV_MV_BY_COL));
338 conDirecFiniteDiffCalculator_->calcDerivatives(
346 if( ( D || rGf ) && py ) {
348 if(out.
get() && trace)
349 *out <<
"\nSolving C*[py,D] = -[c,N] simultaneously ...\n";
350 const int nind = thyra_N_->domain()->dim();
351 RCP<Thyra::MultiVectorBase<value_type> >
352 thyra_cN = Thyra::createMembers(thyra_N_->range(),nind+1);
355 RCP<Thyra::MultiVectorBase<value_type> >
356 thyra_pyD = Thyra::createMembers(thyra_D->range(),nind+1);
359 solveStatus = Thyra::solve(*thyra_C_,
Thyra::NOTRANS, *thyra_cN, thyra_pyD.ptr());
360 if(out.
get() && trace) {
362 <<
"\nsolve status:\n";
363 OSTab(out).o() << solveStatus;
365 Thyra::scale(-1.0, thyra_pyD.ptr());
372 if(out.
get() && trace)
373 *out <<
"\nSolving C*py = -c ...\n";
378 *out <<
"\nsolve status:\n";
379 OSTab(out).o() << solveStatus;
384 if(out.
get() && trace)
385 *out <<
"\nSolving C*D = -N ...\n";
389 if(out.
get() && trace) {
391 <<
"\nsolve status:\n";
392 OSTab(out).o() << solveStatus;
394 Thyra::scale(-1.0, thyra_D.ptr());
398 free_thyra_vector(*space_c,*c,&thyra_c);
399 commit_thyra_vector(*space_xD,py,&thyra_py);
405 var_dep = basis_sys_->var_dep(),
407 if(objDirecFiniteDiffCalculator_.get()) {
408 if(out.
get() && trace)
409 *out <<
"\nComputing rGf using directional finite differences ...\n";
416 TVecPtr e_i = createMember(model_->get_p_space(p_idx_));
418 MEB::InArgs<value_type> dir = model_->createInArgs();
419 dir.set_p(p_idx_,e_i);
420 MEB::OutArgs<value_type> bfunc = model_->createOutArgs();
422 bfunc.set_g(g_idx_,createMember(model_->get_g_space(g_idx_)));
423 Thyra::set_ele(0, *f, bfunc.get_g(g_idx_).ptr());
425 MEB::OutArgs<value_type> var = model_->createOutArgs();
426 var.set_g(g_idx_,createMember(model_->get_g_space(g_idx_)));
428 for(
int i = 0; i < np; ++i ) {
429 set_ele(i, 1.0, e_i.ptr());
430 dir.set_x(thyra_D->col(i));
431 objDirecFiniteDiffCalculator_->calcVariations(
432 *model_,model_inArgs,dir,bfunc,var
434 dir.set_x(Teuchos::null);
435 Thyra::set_ele(i, 0.0, e_i.ptr());
436 d_rGf()[i] = Thyra::get_ele(*var.get_g(g_idx_),0);
440 LinAlgOpPack::V_MtV( rGf, *D_used,
BLAS_Cpp::trans, *Gf->sub_view(var_dep) );
447 if(out.
get() && trace)
448 *out <<
"\nLeaving MoochoPack::NLPDirectThyraModelEvaluator::calc_point(...) ...\n";
void initialize(bool test_setup)
vec_space_ptr_t space_c() const
bool is_null(const boost::shared_ptr< T > &p)
void postprocessBaseOutArgs(Thyra::ModelEvaluatorBase::OutArgs< value_type > *model_outArgs_inout, VectorMutable *Gf, value_type *f, VectorMutable *c) const
basic_OSTab< char > OSTab
void Vt_S(VectorMutable *v_lhs, const value_type &alpha)
basic_FancyOStream< char > FancyOStream
VectorSpace adapter subclass for Thyra::VectorSpaceBase<value_type> .
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
void initializeBase(const Teuchos::RCP< Thyra::ModelEvaluator< value_type > > &model, const int p_idx, const int g_idx)
Initialize given a Thyra::ModelEvaluator and a description of how to interpret it.
const mat_sym_nonsing_fcty_ptr_t factory_S() const
T_To & dyn_cast(T_From &from)
const mat_fcty_ptr_t factory_D() const
const ObjGradInfo obj_grad_info() const
bool supports(EOutArgsMembers arg) const
void initialize(bool test_setup)
void assign(MatrixOp *M_lhs, const MatrixOp &M_rhs, BLAS_Cpp::Transp trans_rhs)
void initialize(const Teuchos::RCP< Thyra::ModelEvaluator< value_type > > &model, const int p_idx, const int g_idx, const objDirecFiniteDiffCalculator_ptr_t objDirecFiniteDiffCalculator=Teuchos::null, const conDirecFiniteDiffCalculator_ptr_t conDirecFiniteDiffCalculator=Teuchos::null)
.Initialize given a Thyra::ModelEvaluator and a description of how to interpret it.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
VectorMutable adapter subclass for Thyra::VectorBase.
void preprocessBaseInOutArgs(const Vector &x, bool newx, const ZeroOrderInfo *zero_order_info, const ObjGradInfo *obj_grad_info, const NLPFirstOrder::FirstOrderInfo *first_order_info, Thyra::ModelEvaluatorBase::InArgs< value_type > *model_inArgs_inout, Thyra::ModelEvaluatorBase::OutArgs< value_type > *model_outArgs_inout, MatrixOp **Gc_out, VectorMutable **Gf_out, value_type **f_out, VectorMutable **c_out) const
value_type calc_Gf_prod(const Vector &x, const Vector &d, bool newx) const
const RCP< T > & assert_not_null() const
MatrixOp adapter subclass for Thyra::LinearOpBase.
MatrixOpNonsing adapter subclass for Thyra::Nonlin::LinearOpWithSolve.
bool supports_Gf_prod() const
NLPDirectThyraModelEvaluator()
Initialize to uninitialized.
void calc_point(const Vector &x, value_type *f, VectorMutable *c, bool recalc_c, VectorMutable *Gf, VectorMutable *py, VectorMutable *rGf, MatrixOp *GcU, MatrixOp *D, MatrixOp *Uz) const
bool nonnull(const boost::shared_ptr< T > &p)
MultiVectorMutable adapter subclass for Thyra::MultiVectorBase.
void set_x(const Vector &x, Thyra::ModelEvaluatorBase::InArgs< value_type > *model_inArgs_inout) const
void calc_semi_newton_step(const Vector &x, VectorMutable *c, bool recalc_c, VectorMutable *py) const
virtual VectorMutable & Gf()
Range1D var_indep() const
#define TEUCHOS_TEST_FOR_EXCEPT(throw_exception_test)
DerivativeProperties get_W_properties() const
virtual VectorMutable & c()
void Vp_V(VectorMutable *v_lhs, const V &V_rhs)