10#ifndef THYRA_DEFAUL_LUMPED_PARAMETER_LUMPED_MODEL_EVALUATOR_HPP
11#define THYRA_DEFAUL_LUMPED_PARAMETER_LUMPED_MODEL_EVALUATOR_HPP
14#include "Thyra_ModelEvaluatorDelegatorBase.hpp"
15#include "Thyra_ModelEvaluatorHelpers.hpp"
16#include "Thyra_DetachedVectorView.hpp"
17#include "Teuchos_ParameterListAcceptor.hpp"
18#include "Teuchos_VerboseObjectParameterListHelpers.hpp"
19#include "Teuchos_Time.hpp"
20#include "Teuchos_Assert.hpp"
21#include "Teuchos_as.hpp"
23#include "sillyModifiedGramSchmidt.hpp"
207template<
class Scalar>
300 mutable bool isInitialized_;
301 mutable bool nominalValuesAndBoundsUpdated_;
308 bool autogenerateBasisMatrix_;
309 int numberOfBasisColumns_;
310 bool nominalValueIsParameterBase_;
311 bool ignoreParameterBounds_;
313 bool dumpBasisMatrix_;
326 static const std::string ParameterSubvectorIndex_name_;
327 static const int ParameterSubvectorIndex_default_;
329 static const std::string AutogenerateBasisMatrix_name_;
330 static const bool AutogenerateBasisMatrix_default_;
332 static const std::string NumberOfBasisColumns_name_;
333 static const int NumberOfBasisColumns_default_;
335 static const std::string NominalValueIsParameterBase_name_;
336 static const bool NominalValueIsParameterBase_default_;
338 static const std::string ParameterBaseVector_name_;
340 static const std::string IgnoreParameterBounds_name_;
341 static const bool IgnoreParameterBounds_default_;
343 static const std::string DumpBasisMatrix_name_;
344 static const bool DumpBasisMatrix_default_;
353 void finishInitialization()
const;
356 void generateParameterBasisMatrix()
const;
360 void updateNominalValuesAndBounds()
const;
367 void setupWrappedParamDerivOutArgs(
374 create_deriv_wrt_p_orig(
381 void assembleParamDerivOutArgs(
387 void assembleParamDeriv(
399template<
class Scalar>
407 paramLumpedModel->initialize(thyraModel);
408 return paramLumpedModel;
419template<
class Scalar>
422=
"Parameter Subvector Index";
424template<
class Scalar>
430template<
class Scalar>
433=
"Auto-generate Basis Matrix";
435template<
class Scalar>
441template<
class Scalar>
444=
"Number of Basis Columns";
446template<
class Scalar>
452template<
class Scalar>
455=
"Nominal Value is Parameter Base";
457template<
class Scalar>
463template<
class Scalar>
466=
"Parameter Base Vector";
469template<
class Scalar>
472=
"Ignore Parameter Bounds";
474template<
class Scalar>
480template<
class Scalar>
483=
"Dump Basis Matrix";
485template<
class Scalar>
494template<
class Scalar>
496 :isInitialized_(false),
497 nominalValuesAndBoundsUpdated_(false),
498 p_idx_(ParameterSubvectorIndex_default_),
499 autogenerateBasisMatrix_(AutogenerateBasisMatrix_default_),
500 numberOfBasisColumns_(NumberOfBasisColumns_default_),
501 nominalValueIsParameterBase_(NominalValueIsParameterBase_default_),
502 ignoreParameterBounds_(IgnoreParameterBounds_default_),
503 localVerbLevel_(
Teuchos::VERB_DEFAULT),
504 dumpBasisMatrix_(DumpBasisMatrix_default_)
508template<
class Scalar>
513 isInitialized_ =
false;
514 nominalValuesAndBoundsUpdated_ =
false;
519template<
class Scalar>
524 isInitialized_ =
false;
525 if(thyraModel) *thyraModel = this->getUnderlyingModel();
533template<
class Scalar>
538 thyraModel = this->getUnderlyingModel();
539 std::ostringstream oss;
540 oss <<
"Thyra::DefaultLumpedParameterModelEvaluator{";
541 oss <<
"thyraModel=";
543 oss <<
"\'"<<thyraModel->description()<<
"\'";
554template<
class Scalar>
560 using Teuchos::getParameterPtr;
562 using Teuchos::sublist;
564 isInitialized_ =
false;
565 nominalValuesAndBoundsUpdated_ =
false;
569 paramList->validateParameters(*getValidParameters(),0);
570 paramList_ = paramList;
573 p_idx_ = paramList_->
get(
574 ParameterSubvectorIndex_name_, ParameterSubvectorIndex_default_ );
575 autogenerateBasisMatrix_ = paramList_->get(
576 AutogenerateBasisMatrix_name_, AutogenerateBasisMatrix_default_ );
577 if (autogenerateBasisMatrix_) {
578 numberOfBasisColumns_ = paramList_->get(
579 NumberOfBasisColumns_name_, NumberOfBasisColumns_default_ );
581 nominalValueIsParameterBase_ = paramList_->get(
582 NominalValueIsParameterBase_name_, NominalValueIsParameterBase_default_ );
583 if (!nominalValueIsParameterBase_) {
586 ignoreParameterBounds_ = paramList_->get(
587 IgnoreParameterBounds_name_, IgnoreParameterBounds_default_ );
588 dumpBasisMatrix_ = paramList_->get(
589 DumpBasisMatrix_name_, DumpBasisMatrix_default_ );
592 localVerbLevel_ = this->readLocalVerbosityLevelValidatedParameter(*paramList_);
593 Teuchos::readVerboseObjectSublist(&*paramList_,
this);
596 paramList_->validateParameters(*getValidParameters(),0);
602template<
class Scalar>
610template<
class Scalar>
620template<
class Scalar>
628template<
class Scalar>
632 if(validParamList_.get()==NULL) {
635 pl->set( ParameterSubvectorIndex_name_, ParameterSubvectorIndex_default_,
636 "Determines the index of the parameter subvector in the underlying model\n"
637 "for which the reduced basis representation will be determined." );
638 pl->set( AutogenerateBasisMatrix_name_, AutogenerateBasisMatrix_default_,
639 "If true, then a basis matrix will be auto-generated for a given number\n"
640 " of basis vectors." );
641 pl->set( NumberOfBasisColumns_name_, NumberOfBasisColumns_default_,
642 "If a basis is auto-generated, then this parameter gives the number\n"
643 "of columns in the basis matrix that will be created. Warning! This\n"
644 "number must be less than or equal to the number of original parameters\n"
645 "or an exception will be thrown!" );
646 pl->set( NominalValueIsParameterBase_name_, NominalValueIsParameterBase_default_,
647 "If true, then the nominal values for the full parameter subvector from the\n"
648 "underlying model will be used for p_orig_base. This allows p==0 to give\n"
649 "the nominal values for the parameters." );
657 pl->set( IgnoreParameterBounds_name_, IgnoreParameterBounds_default_,
658 "If true, then any bounds on the parameter subvector will be ignored." );
659 pl->set( DumpBasisMatrix_name_, DumpBasisMatrix_default_,
660 "If true, then the basis matrix will be printed the first time it is created\n"
661 "as part of the verbose output and as part of the Describable::describe(...)\n"
662 "output for any verbositiy level >= \"low\"." );
663 this->setLocalVerbosityLevelValidatedParameter(&*pl);
664 Teuchos::setupVerboseObjectSublist(&*pl);
665 validParamList_ = pl;
667 return validParamList_;
674template<
class Scalar>
678 finishInitialization();
681 return this->getUnderlyingModel()->get_p_space(l);
685template<
class Scalar>
689 finishInitialization();
692 return this->getUnderlyingModel()->get_p_names(l);
696template<
class Scalar>
700 updateNominalValuesAndBounds();
701 return nominalValues_;
705template<
class Scalar>
709 updateNominalValuesAndBounds();
714template<
class Scalar>
718 updateNominalValuesAndBounds();
723template<
class Scalar>
733 updateNominalValuesAndBounds();
736 thyraModel = this->getNonconstUnderlyingModel();
741 MEB::InArgs<Scalar> wrappedFinalPoint = thyraModel->createInArgs();
742 wrappedFinalPoint.setArgs(finalPoint);
746 if (!is_null(p=finalPoint.
get_p(p_idx_))) {
747 wrappedFinalPoint.set_p(p_idx_, map_from_p_to_p_orig(*p));
750 thyraModel->reportFinalPoint(wrappedFinalPoint,wasSolved);
758template<
class Scalar>
763 outArgs = this->getUnderlyingModel()->createOutArgs();
772template<
class Scalar>
773void DefaultLumpedParameterModelEvaluator<Scalar>::evalModelImpl(
774 const ModelEvaluatorBase::InArgs<Scalar> &inArgs,
775 const ModelEvaluatorBase::OutArgs<Scalar> &outArgs
785 using Teuchos::rcp_const_cast;
786 using Teuchos::rcp_dynamic_cast;
789 typedef typename ST::magnitudeType ScalarMag;
790 typedef ModelEvaluatorBase MEB;
793 updateNominalValuesAndBounds();
795 THYRA_MODEL_EVALUATOR_DECORATOR_EVAL_MODEL_LOCALVERBLEVEL_BEGIN(
796 "Thyra::DefaultLumpedParameterModelEvaluator",inArgs,outArgs,localVerbLevel_
806 MEB::InArgs<Scalar> wrappedInArgs = thyraModel->createInArgs();
807 wrappedInArgs.setArgs(inArgs);
810 RCP<const VectorBase<Scalar> > p;
811 if (!is_null(p=wrappedInArgs.get_p(p_idx_))) {
819 wrappedInArgs.set_p(p_idx_,map_from_p_to_p_orig(*p));
830 MEB::OutArgs<Scalar> wrappedOutArgs = thyraModel->createOutArgs();
831 wrappedOutArgs.setArgs(outArgs);
835 setupWrappedParamDerivOutArgs(outArgs,&wrappedOutArgs);
842 *out <<
"\nEvaluating the fully parameterized underlying model ...\n";
845 thyraModel->evalModel(wrappedInArgs,wrappedOutArgs);
853 assembleParamDerivOutArgs(wrappedOutArgs,outArgs);
855 THYRA_MODEL_EVALUATOR_DECORATOR_EVAL_MODEL_END();
863template<
class Scalar>
864void DefaultLumpedParameterModelEvaluator<Scalar>::finishInitialization()
const
867 typedef ScalarTraits<Scalar> ST;
868 typedef ModelEvaluatorBase MEB;
877 const RCP<const ModelEvaluator<Scalar> >
878 thyraModel = this->getUnderlyingModel();
881 is_null(thyraModel), std::logic_error,
882 "Error, the underlying model evaluator must be set!" );
888 if (autogenerateBasisMatrix_) {
889 generateParameterBasisMatrix();
893 true, std::logic_error,
894 "Error, we don't handle a client-set parameter basis matrix yet!" );
897 isInitialized_ =
true;
902template<
class Scalar>
903void DefaultLumpedParameterModelEvaluator<Scalar>::generateParameterBasisMatrix()
const
907 typedef ScalarTraits<Scalar> ST;
909 const RCP<const ModelEvaluator<Scalar> >
910 thyraModel = this->getUnderlyingModel();
912 const RCP<const VectorSpaceBase<Scalar> >
913 p_orig_space = thyraModel->get_p_space(p_idx_);
915 const Ordinal p_orig_dim = p_orig_space->dim();
918 !( 1 <= numberOfBasisColumns_ && numberOfBasisColumns_ <= p_orig_dim ),
920 "Error, the number of basis columns = " << numberOfBasisColumns_ <<
" does not\n"
921 "fall in the range [1,"<<p_orig_dim<<
"]!" );
932 const RCP<MultiVectorBase<Scalar> >
933 B = createMembers(p_orig_space,numberOfBasisColumns_);
934 assign( B->col(0).ptr(), ST::one() );
935 if (numberOfBasisColumns_ > 1) {
936 seed_randomize<double>(0);
937 Thyra::randomize( as<Scalar>(0.5*ST::one()), as<Scalar>(1.5*ST::one()),
945 RCP<MultiVectorBase<double> > R;
946 sillyModifiedGramSchmidt( B.ptr(), Teuchos::outArg(R) );
957template<
class Scalar>
958void DefaultLumpedParameterModelEvaluator<Scalar>::updateNominalValuesAndBounds()
const
961 typedef ScalarTraits<Scalar> ST;
962 typedef ModelEvaluatorBase MEB;
964 if (nominalValuesAndBoundsUpdated_)
967 finishInitialization();
969 const RCP<const ModelEvaluator<Scalar> >
970 thyraModel = this->getUnderlyingModel();
972 const MEB::InArgs<Scalar> origNominalValues = thyraModel->getNominalValues();
973 const MEB::InArgs<Scalar> origLowerBounds = thyraModel->getLowerBounds();
974 const MEB::InArgs<Scalar> origUpperBounds = thyraModel->getUpperBounds();
978 if (nominalValueIsParameterBase_) {
979 const RCP<const VectorBase<Scalar> >
980 p_orig_init = origNominalValues.get_p(p_idx_);
982 is_null(p_orig_init), std::logic_error,
983 "Error, if the user requested that the nominal values be used\n"
984 "as the base vector p_orig_base then that vector has to exist!" );
985 p_orig_base_ = p_orig_init->clone_v();
989 true, std::logic_error,
990 "Error, we don't handle reading in the parameter base vector yet!" );
995 nominalValues_ = origNominalValues;
997 if (nominalValueIsParameterBase_) {
999 const RCP<VectorBase<Scalar> >
1000 p_init = createMember(B_->domain());
1001 assign( p_init.ptr(), ST::zero() );
1002 nominalValues_.set_p(p_idx_, p_init);
1006 true, std::logic_error,
1007 "Error, we don't handle creating p_init when p_orig_base != p_orig_init yet!" );
1012 lowerBounds_ = origLowerBounds;
1013 upperBounds_ = origUpperBounds;
1018 if (!ignoreParameterBounds_) {
1019 const RCP<const VectorBase<Scalar> >
1020 p_orig_l = origLowerBounds.get_p(p_idx_),
1021 p_orig_u = origUpperBounds.get_p(p_idx_);
1024 true, std::logic_error,
1025 "Error, we don't handle bounds on p_orig yet!" );
1029 nominalValuesAndBoundsUpdated_ =
true;
1034template<
class Scalar>
1035RCP<VectorBase<Scalar> >
1036DefaultLumpedParameterModelEvaluator<Scalar>::map_from_p_to_p_orig(
1037 const VectorBase<Scalar> &p
1041 const RCP<VectorBase<Scalar> > p_orig = createMember(B_->range());
1042 apply( *B_,
NOTRANS, p, p_orig.ptr() );
1043 Vp_V( p_orig.ptr(), *p_orig_base_ );
1048template<
class Scalar>
1049void DefaultLumpedParameterModelEvaluator<Scalar>::setupWrappedParamDerivOutArgs(
1050 const ModelEvaluatorBase::OutArgs<Scalar> &outArgs,
1051 ModelEvaluatorBase::OutArgs<Scalar> *wrappedOutArgs_inout
1055 typedef ModelEvaluatorBase MEB;
1056 typedef MEB::Derivative<Scalar> Deriv;
1059 MEB::OutArgs<Scalar> &wrappedOutArgs = *wrappedOutArgs_inout;
1062 if ( !(DfDp=outArgs.get_DfDp(p_idx_)).isEmpty() ) {
1063 wrappedOutArgs.set_DfDp(p_idx_,create_deriv_wrt_p_orig(DfDp,MEB::DERIV_MV_BY_COL));
1066 const int Ng = outArgs.Ng();
1067 for (
int j = 0; j < Ng; ++j ) {
1069 if ( !(DgDp=outArgs.get_DgDp(j,p_idx_)).isEmpty() ) {
1070 wrappedOutArgs.set_DgDp(
1072 create_deriv_wrt_p_orig(DgDp,DgDp.getMultiVectorOrientation())
1080template<
class Scalar>
1081ModelEvaluatorBase::Derivative<Scalar>
1082DefaultLumpedParameterModelEvaluator<Scalar>::create_deriv_wrt_p_orig(
1083 const ModelEvaluatorBase::Derivative<Scalar> &DhDp,
1088 typedef ModelEvaluatorBase MEB;
1090 const RCP<const MultiVectorBase<Scalar> >
1091 DhDp_mv = DhDp.getMultiVector();
1093 is_null(DhDp_mv) || (DhDp.getMultiVectorOrientation() != requiredOrientation),
1095 "Error, we currently can't handle non-multi-vector derivatives!" );
1097 RCP<MultiVectorBase<Scalar> > DhDp_orig_mv;
1098 switch (requiredOrientation) {
1099 case MEB::DERIV_MV_BY_COL:
1101 DhDp_orig_mv = createMembers(DhDp_mv->range(),B_->range()->dim());
1105 case MEB::DERIV_TRANS_MV_BY_ROW:
1107 DhDp_orig_mv = createMembers(B_->range(),DhDp_mv->domain()->dim());
1115 return MEB::Derivative<Scalar>(DhDp_orig_mv,requiredOrientation);
1120template<
class Scalar>
1121void DefaultLumpedParameterModelEvaluator<Scalar>::assembleParamDerivOutArgs(
1122 const ModelEvaluatorBase::OutArgs<Scalar> &wrappedOutArgs,
1123 const ModelEvaluatorBase::OutArgs<Scalar> &outArgs
1127 typedef ModelEvaluatorBase MEB;
1128 typedef MEB::Derivative<Scalar> Deriv;
1131 if ( !(DfDp=outArgs.get_DfDp(p_idx_)).isEmpty() ) {
1132 assembleParamDeriv( wrappedOutArgs.get_DfDp(p_idx_), DfDp );
1135 const int Ng = outArgs.Ng();
1136 for (
int j = 0; j < Ng; ++j ) {
1138 if ( !(DgDp=outArgs.get_DgDp(j,p_idx_)).isEmpty() ) {
1139 assembleParamDeriv( wrappedOutArgs.get_DgDp(j,p_idx_), DgDp );
1146template<
class Scalar>
1147void DefaultLumpedParameterModelEvaluator<Scalar>::assembleParamDeriv(
1148 const ModelEvaluatorBase::Derivative<Scalar> &DhDp_orig,
1149 const ModelEvaluatorBase::Derivative<Scalar> &DhDp
1153 typedef ModelEvaluatorBase MEB;
1155 const RCP<const MultiVectorBase<Scalar> >
1156 DhDp_orig_mv = DhDp_orig.getMultiVector();
1158 is_null(DhDp_orig_mv), std::logic_error,
1159 "Error, we currently can't handle non-multi-vector derivatives!" );
1161 const RCP<MultiVectorBase<Scalar> >
1162 DhDp_mv = DhDp.getMultiVector();
1164 is_null(DhDp_mv), std::logic_error,
1165 "Error, we currently can't handle non-multi-vector derivatives!" );
1167 switch( DhDp_orig.getMultiVectorOrientation() ) {
1168 case MEB::DERIV_MV_BY_COL:
1172 DhDp.getMultiVectorOrientation() == MEB::DERIV_MV_BY_COL );
1174 apply( *DhDp_orig_mv,
NOTRANS, *B_, DhDp_mv.ptr() );
1178 case MEB::DERIV_TRANS_MV_BY_ROW:
1182 DhDp.getMultiVectorOrientation() == MEB::DERIV_TRANS_MV_BY_ROW );
1184 apply( *B_,
CONJTRANS, *DhDp_orig_mv, DhDp_mv.ptr() );
Decorator class that wraps any ModelEvaluator object and lumps parameters together using a linear bas...
RCP< const Array< std::string > > get_p_names(int l) const
RCP< Teuchos::ParameterList > getNonconstParameterList()
void setParameterList(RCP< Teuchos::ParameterList > const ¶mList)
.
RCP< DefaultLumpedParameterModelEvaluator< Scalar > > defaultLumpedParameterModelEvaluator(const RCP< ModelEvaluator< Scalar > > &thyraModel)
Non-member constructor.
RCP< const Teuchos::ParameterList > getParameterList() const
RCP< const VectorSpaceBase< Scalar > > get_p_space(int l) const
ModelEvaluatorBase::InArgs< Scalar > getLowerBounds() const
ModelEvaluatorBase::InArgs< Scalar > getUpperBounds() const
RCP< Teuchos::ParameterList > unsetParameterList()
DefaultLumpedParameterModelEvaluator()
RCP< const Teuchos::ParameterList > getValidParameters() const
ModelEvaluatorBase::InArgs< Scalar > getNominalValues() const
std::string description() const
void initialize(const RCP< ModelEvaluator< Scalar > > &thyraModel)
void reportFinalPoint(const ModelEvaluatorBase::InArgs< Scalar > &finalPoint, const bool wasSolved)
Simple aggregate class that stores a derivative object as a general linear operator or as a multi-vec...
Concrete aggregate class for all input arguments computable by a ModelEvaluator subclass object.
RCP< const VectorBase< Scalar > > get_p(int l) const
Get p(l) where 0 <= l && l < this->Np().
Protected subclass of OutArgs that only ModelEvaluator subclasses can access to set up the selection ...
void setModelEvalDescription(const std::string &modelEvalDescription)
Concrete aggregate class for all output arguments computable by a ModelEvaluator subclass object.
Base subclass for ModelEvaluator that defines some basic types.
EDerivativeMultiVectorOrientation
This is a base class that delegetes almost all function to a wrapped model evaluator object.
void uninitialize()
Uninitialize.
void initialize(const RCP< ModelEvaluator< Scalar > > &model)
Initialize given a non-const model evaluator.
Pure abstract base interface for evaluating a stateless "model" that can be mapped into a number of d...
Abstract interface for finite-dimensional dense vectors.
#define TEUCHOS_ASSERT(assertion_test)
#define TEUCHOS_TEST_FOR_EXCEPT(throw_exception_test)
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
bool is_null(const std::shared_ptr< T > &p)
Teuchos::Ordinal Ordinal
Type for the dimension of a vector space. `*.
@ NOTRANS
Use the non-transposed operator.
@ CONJTRANS
Use the transposed operator with complex-conjugate clements (same as TRANS for real scalar types).
TypeTo as(const TypeFrom &t)
T_To & dyn_cast(T_From &from)
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
TEUCHOSCORE_LIB_DLL_EXPORT bool includesVerbLevel(const EVerbosityLevel verbLevel, const EVerbosityLevel requestedVerbLevel, const bool isDefaultLevel=false)