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"
207 template<
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(
399 template<
class Scalar>
407 paramLumpedModel->initialize(thyraModel);
408 return paramLumpedModel;
419 template<
class Scalar>
422 =
"Parameter Subvector Index";
424 template<
class Scalar>
430 template<
class Scalar>
433 =
"Auto-generate Basis Matrix";
435 template<
class Scalar>
441 template<
class Scalar>
444 =
"Number of Basis Columns";
446 template<
class Scalar>
452 template<
class Scalar>
455 =
"Nominal Value is Parameter Base";
457 template<
class Scalar>
463 template<
class Scalar>
466 =
"Parameter Base Vector";
469 template<
class Scalar>
472 =
"Ignore Parameter Bounds";
474 template<
class Scalar>
480 template<
class Scalar>
483 =
"Dump Basis Matrix";
485 template<
class Scalar>
494 template<
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_),
504 dumpBasisMatrix_(DumpBasisMatrix_default_)
508 template<
class Scalar>
513 isInitialized_ =
false;
514 nominalValuesAndBoundsUpdated_ =
false;
519 template<
class Scalar>
524 isInitialized_ =
false;
525 if(thyraModel) *thyraModel = this->getUnderlyingModel();
533 template<
class Scalar>
538 thyraModel = this->getUnderlyingModel();
539 std::ostringstream oss;
540 oss <<
"Thyra::DefaultLumpedParameterModelEvaluator{";
541 oss <<
"thyraModel=";
543 oss <<
"\'"<<thyraModel->description()<<
"\'";
554 template<
class Scalar>
560 using Teuchos::getParameterPtr;
562 using Teuchos::sublist;
564 isInitialized_ =
false;
565 nominalValuesAndBoundsUpdated_ =
false;
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);
602 template<
class Scalar>
610 template<
class Scalar>
615 paramList_ = Teuchos::null;
620 template<
class Scalar>
628 template<
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_;
674 template<
class Scalar>
678 finishInitialization();
681 return this->getUnderlyingModel()->get_p_space(l);
685 template<
class Scalar>
689 finishInitialization();
691 return Teuchos::null;
692 return this->getUnderlyingModel()->get_p_names(l);
696 template<
class Scalar>
700 updateNominalValuesAndBounds();
701 return nominalValues_;
705 template<
class Scalar>
709 updateNominalValuesAndBounds();
714 template<
class Scalar>
718 updateNominalValuesAndBounds();
723 template<
class Scalar>
733 updateNominalValuesAndBounds();
736 thyraModel = this->getNonconstUnderlyingModel();
741 MEB::InArgs<Scalar> wrappedFinalPoint = thyraModel->createInArgs();
742 wrappedFinalPoint.setArgs(finalPoint);
747 wrappedFinalPoint.set_p(p_idx_, map_from_p_to_p_orig(*p));
750 thyraModel->reportFinalPoint(wrappedFinalPoint,wasSolved);
758 template<
class Scalar>
763 outArgs = this->getUnderlyingModel()->createOutArgs();
772 template<
class Scalar>
773 void 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();
863 template<
class Scalar>
864 void 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;
902 template<
class Scalar>
903 void 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) );
957 template<
class Scalar>
958 void 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;
1015 lowerBounds_.set_p(p_idx_,Teuchos::null);
1016 upperBounds_.set_p(p_idx_,Teuchos::null);
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;
1034 template<
class Scalar>
1035 RCP<VectorBase<Scalar> >
1036 DefaultLumpedParameterModelEvaluator<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_ );
1048 template<
class Scalar>
1049 void 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())
1080 template<
class Scalar>
1081 ModelEvaluatorBase::Derivative<Scalar>
1082 DefaultLumpedParameterModelEvaluator<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);
1120 template<
class Scalar>
1121 void 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 );
1146 template<
class Scalar>
1147 void 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:
1170 #ifdef TEUCHSO_DEBUG
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:
1180 #ifdef TEUCHSO_DEBUG
1182 DhDp.getMultiVectorOrientation() == MEB::DERIV_TRANS_MV_BY_ROW );
1184 apply( *B_,
CONJTRANS, *DhDp_orig_mv, DhDp_mv.ptr() );
1196 #endif // THYRA_DEFAUL_LUMPED_PARAMETER_LUMPED_MODEL_EVALUATOR_HPP
void reportFinalPoint(const ModelEvaluatorBase::InArgs< Scalar > &finalPoint, const bool wasSolved)
Pure abstract base interface for evaluating a stateless "model" that can be mapped into a number of d...
Decorator class that wraps any ModelEvaluator object and lumps parameters together using a linear bas...
bool is_null(const boost::shared_ptr< T > &p)
basic_OSTab< char > OSTab
RCP< const VectorSpaceBase< Scalar > > get_p_space(int l) const
Concrete aggregate class for all output arguments computable by a ModelEvaluator subclass object...
EDerivativeMultiVectorOrientation
RCP< const Array< std::string > > get_p_names(int l) const
void uninitialize()
Uninitialize.
T & get(const std::string &name, T def_value)
RCP< const Teuchos::ParameterList > getParameterList() const
This is a base class that delegetes almost all function to a wrapped model evaluator object...
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Use the non-transposed operator.
void initialize(const RCP< ModelEvaluator< Scalar > > &model)
Initialize given a non-const model evaluator.
Simple aggregate class that stores a derivative object as a general linear operator or as a multi-vec...
Use the transposed operator with complex-conjugate clements (same as TRANS for real scalar types)...
std::string description() const
ModelEvaluatorBase::InArgs< Scalar > getUpperBounds() const
ParameterList & set(std::string const &name, T &&value, std::string const &docString="", RCP< const ParameterEntryValidator > const &validator=null)
void setParameterList(RCP< Teuchos::ParameterList > const ¶mList)
ModelEvaluatorBase::InArgs< Scalar > getNominalValues() const
DefaultLumpedParameterModelEvaluator()
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Teuchos::Ordinal Ordinal
Type for the dimension of a vector space. `*.
ModelEvaluatorBase::InArgs< Scalar > getLowerBounds() const
Abstract interface for finite-dimensional dense vectors.
void initialize(const RCP< ModelEvaluator< Scalar > > &thyraModel)
TEUCHOSCORE_LIB_DLL_EXPORT bool includesVerbLevel(const EVerbosityLevel verbLevel, const EVerbosityLevel requestedVerbLevel, const bool isDefaultLevel=false)
void validateParameters(ParameterList const &validParamList, int const depth=1000, EValidateUsed const validateUsed=VALIDATE_USED_ENABLED, EValidateDefaults const validateDefaults=VALIDATE_DEFAULTS_ENABLED) const
RCP< const Teuchos::ParameterList > getValidParameters() const
RCP< Teuchos::ParameterList > getNonconstParameterList()
Base subclass for ModelEvaluator that defines some basic types.
RCP< DefaultLumpedParameterModelEvaluator< Scalar > > defaultLumpedParameterModelEvaluator(const RCP< ModelEvaluator< Scalar > > &thyraModel)
Non-member constructor.
TypeTo as(const TypeFrom &t)
#define TEUCHOS_ASSERT(assertion_test)
void setModelEvalDescription(const std::string &modelEvalDescription)
#define TEUCHOS_TEST_FOR_EXCEPT(throw_exception_test)
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 ...
RCP< Teuchos::ParameterList > unsetParameterList()
Concrete aggregate class for all input arguments computable by a ModelEvaluator subclass object...