Thyra Version of the Day
Loading...
Searching...
No Matches
Thyra_DefaultLumpedParameterModelEvaluator.hpp
1// @HEADER
2// *****************************************************************************
3// Thyra: Interfaces and Support for Abstract Numerical Algorithms
4//
5// Copyright 2004 NTESS and the Thyra contributors.
6// SPDX-License-Identifier: BSD-3-Clause
7// *****************************************************************************
8// @HEADER
9
10#ifndef THYRA_DEFAUL_LUMPED_PARAMETER_LUMPED_MODEL_EVALUATOR_HPP
11#define THYRA_DEFAUL_LUMPED_PARAMETER_LUMPED_MODEL_EVALUATOR_HPP
12
13
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"
22
23#include "sillyModifiedGramSchmidt.hpp" // This is just an example!
24
25
26namespace Thyra {
27
28
207template<class Scalar>
209 : virtual public ModelEvaluatorDelegatorBase<Scalar>
210 , virtual public Teuchos::ParameterListAcceptor
211{
212public:
213
216
219
221 void initialize(
222 const RCP<ModelEvaluator<Scalar> > &thyraModel
223 );
224
226 void uninitialize(
227 RCP<ModelEvaluator<Scalar> > *thyraModel
228 );
229
230 // 2007/07/30: rabartl: ToDo: Add functions to set and get the underlying
231 // basis matrix!
232
234
237
239 std::string description() const;
240
242
245
247 void setParameterList(RCP<Teuchos::ParameterList> const& paramList);
256
258
261
273 void reportFinalPoint(
274 const ModelEvaluatorBase::InArgs<Scalar> &finalPoint,
275 const bool wasSolved
276 );
277
279
280private:
281
284
286 ModelEvaluatorBase::OutArgs<Scalar> createOutArgsImpl() const;
288 void evalModelImpl(
291 ) const;
292
294
295private:
296
297 // ////////////////////////////////
298 // Private data members
299
300 mutable bool isInitialized_;
301 mutable bool nominalValuesAndBoundsUpdated_;
302
303 mutable RCP<const Teuchos::ParameterList> validParamList_;
305
306 // Parameters read from the parameter list
307 int p_idx_;
308 bool autogenerateBasisMatrix_;
309 int numberOfBasisColumns_;
310 bool nominalValueIsParameterBase_;
311 bool ignoreParameterBounds_;
312 Teuchos::EVerbosityLevel localVerbLevel_;
313 bool dumpBasisMatrix_;
314
315 // Reduced affine parameter model
317 mutable RCP<const VectorBase<Scalar> > p_orig_base_;
318
319 // Nominal values and bounds
320 mutable ModelEvaluatorBase::InArgs<Scalar> nominalValues_;
321 mutable ModelEvaluatorBase::InArgs<Scalar> lowerBounds_;
322 mutable ModelEvaluatorBase::InArgs<Scalar> upperBounds_;
323
324 // Static
325
326 static const std::string ParameterSubvectorIndex_name_;
327 static const int ParameterSubvectorIndex_default_;
328
329 static const std::string AutogenerateBasisMatrix_name_;
330 static const bool AutogenerateBasisMatrix_default_;
331
332 static const std::string NumberOfBasisColumns_name_;
333 static const int NumberOfBasisColumns_default_;
334
335 static const std::string NominalValueIsParameterBase_name_;
336 static const bool NominalValueIsParameterBase_default_;
337
338 static const std::string ParameterBaseVector_name_;
339
340 static const std::string IgnoreParameterBounds_name_;
341 static const bool IgnoreParameterBounds_default_;
342
343 static const std::string DumpBasisMatrix_name_;
344 static const bool DumpBasisMatrix_default_;
345
346 // ////////////////////////////////
347 // Private member functions
348
349 // These functions are used to implement late initialization so that the
350 // need for clients to order function calls is reduced.
351
352 // Finish enough initialization to defined spaces etc.
353 void finishInitialization() const;
354
355 // Generate the parameter basis matrix B.
356 void generateParameterBasisMatrix() const;
357
358 // Finish all of initialization needed to define nominal values, bounds, and
359 // p_orig_base. This calls finishInitialization().
360 void updateNominalValuesAndBounds() const;
361
362 // Map from p -> p_orig.
364 map_from_p_to_p_orig( const VectorBase<Scalar> &p ) const;
365
366 // Set up the arguments for DhDp_orig to be computed by the underlying model.
367 void setupWrappedParamDerivOutArgs(
368 const ModelEvaluatorBase::OutArgs<Scalar> &outArgs, // in
369 ModelEvaluatorBase::OutArgs<Scalar> *wrappedOutArgs // in/out
370 ) const;
371
372 // Create DhDp_orig needed to assembled DhDp
374 create_deriv_wrt_p_orig(
377 ) const;
378
379 // After DhDp_orig has been computed, assemble DhDp or DhDp^T for all deriv
380 // output arguments.
381 void assembleParamDerivOutArgs(
382 const ModelEvaluatorBase::OutArgs<Scalar> &wrappedOutArgs, // in
383 const ModelEvaluatorBase::OutArgs<Scalar> &outArgs // in/out
384 ) const;
385
386 // Given a single DhDp_orig, assemble DhDp
387 void assembleParamDeriv(
388 const ModelEvaluatorBase::Derivative<Scalar> &DhDp_orig, // in
389 const ModelEvaluatorBase::Derivative<Scalar> &DhDp // in/out
390 ) const;
391
392};
393
394
399template<class Scalar>
402 const RCP<ModelEvaluator<Scalar> > &thyraModel
403 )
404{
407 paramLumpedModel->initialize(thyraModel);
408 return paramLumpedModel;
409}
410
411
412// /////////////////////////////////
413// Implementations
414
415
416// Static data members
417
418
419template<class Scalar>
420const std::string
422= "Parameter Subvector Index";
423
424template<class Scalar>
425const int
427= 0;
428
429
430template<class Scalar>
431const std::string
433= "Auto-generate Basis Matrix";
434
435template<class Scalar>
436const bool
438= true;
439
440
441template<class Scalar>
442const std::string
444= "Number of Basis Columns";
445
446template<class Scalar>
447const int
449= 1;
450
451
452template<class Scalar>
453const std::string
455= "Nominal Value is Parameter Base";
456
457template<class Scalar>
458const bool
460= true;
461
462
463template<class Scalar>
464const std::string
466= "Parameter Base Vector";
467
468
469template<class Scalar>
470const std::string
472= "Ignore Parameter Bounds";
473
474template<class Scalar>
475const bool
477= false;
478
479
480template<class Scalar>
481const std::string
483= "Dump Basis Matrix";
484
485template<class Scalar>
486const bool
488= false;
489
490
491// Constructors/initializers/accessors/utilities
492
493
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_)
505{}
506
507
508template<class Scalar>
510 const RCP<ModelEvaluator<Scalar> > &thyraModel
511 )
512{
513 isInitialized_ = false;
514 nominalValuesAndBoundsUpdated_ = false;
516}
517
518
519template<class Scalar>
521 RCP<ModelEvaluator<Scalar> > *thyraModel
522 )
523{
524 isInitialized_ = false;
525 if(thyraModel) *thyraModel = this->getUnderlyingModel();
527}
528
529
530// Public functions overridden from Teuchos::Describable
531
532
533template<class Scalar>
534std::string
536{
538 thyraModel = this->getUnderlyingModel();
539 std::ostringstream oss;
540 oss << "Thyra::DefaultLumpedParameterModelEvaluator{";
541 oss << "thyraModel=";
542 if(thyraModel.get())
543 oss << "\'"<<thyraModel->description()<<"\'";
544 else
545 oss << "NULL";
546 oss << "}";
547 return oss.str();
548}
549
550
551// Overridden from Teuchos::ParameterListAcceptor
552
553
554template<class Scalar>
556 RCP<Teuchos::ParameterList> const& paramList
557 )
558{
559
560 using Teuchos::getParameterPtr;
561 using Teuchos::rcp;
562 using Teuchos::sublist;
563
564 isInitialized_ = false;
565 nominalValuesAndBoundsUpdated_ = false;
566
567 // Validate and set the parameter list
568 TEUCHOS_TEST_FOR_EXCEPT(is_null(paramList));
569 paramList->validateParameters(*getValidParameters(),0);
570 paramList_ = paramList;
571
572 // Read in parameters
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_ );
580 }
581 nominalValueIsParameterBase_ = paramList_->get(
582 NominalValueIsParameterBase_name_, NominalValueIsParameterBase_default_ );
583 if (!nominalValueIsParameterBase_) {
584 TEUCHOS_TEST_FOR_EXCEPT("ToDo: Implement reading parameter base vector from file!");
585 }
586 ignoreParameterBounds_ = paramList_->get(
587 IgnoreParameterBounds_name_, IgnoreParameterBounds_default_ );
588 dumpBasisMatrix_ = paramList_->get(
589 DumpBasisMatrix_name_, DumpBasisMatrix_default_ );
590
591 // Verbosity settings
592 localVerbLevel_ = this->readLocalVerbosityLevelValidatedParameter(*paramList_);
593 Teuchos::readVerboseObjectSublist(&*paramList_,this);
594
595#ifdef TEUCHOS_DEBUG
596 paramList_->validateParameters(*getValidParameters(),0);
597#endif
598
599}
600
601
602template<class Scalar>
608
609
610template<class Scalar>
613{
614 RCP<Teuchos::ParameterList> _paramList = paramList_;
615 paramList_ = Teuchos::null;
616 return _paramList;
617}
618
619
620template<class Scalar>
626
627
628template<class Scalar>
631{
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." );
650 /*
651 if(this->get_parameterBaseIO().get())
652 parameterBaseReader_.set_fileIO(this->get_parameterBaseIO());
653 pl->sublist(ParameterBaseVector_name_).setParameters(
654 *parameterBaseReader_.getValidParameters()
655 );
656 */
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;
666 }
667 return validParamList_;
668}
669
670
671// Overridden from ModelEvaulator.
672
673
674template<class Scalar>
677{
678 finishInitialization();
679 if (l == p_idx_)
680 return B_->domain();
681 return this->getUnderlyingModel()->get_p_space(l);
682}
683
684
685template<class Scalar>
688{
689 finishInitialization();
690 if (l == p_idx_)
691 return Teuchos::null; // Names for these parameters would be meaningless!
692 return this->getUnderlyingModel()->get_p_names(l);
693}
694
695
696template<class Scalar>
699{
700 updateNominalValuesAndBounds();
701 return nominalValues_;
702}
703
704
705template<class Scalar>
708{
709 updateNominalValuesAndBounds();
710 return lowerBounds_;
711}
712
713
714template<class Scalar>
717{
718 updateNominalValuesAndBounds();
719 return upperBounds_;
720}
721
722
723template<class Scalar>
725 const ModelEvaluatorBase::InArgs<Scalar> &finalPoint,
726 const bool wasSolved
727 )
728{
729
730 typedef ModelEvaluatorBase MEB;
731
732 // Make sure that everything has been initialized
733 updateNominalValuesAndBounds();
734
736 thyraModel = this->getNonconstUnderlyingModel();
737
738 // By default, copy all input arguments since they will all be the same
739 // except for the given reduced p. We will then replace the reduced p with
740 // p_orig below.
741 MEB::InArgs<Scalar> wrappedFinalPoint = thyraModel->createInArgs();
742 wrappedFinalPoint.setArgs(finalPoint);
743
744 // Replace p with p_orig.
746 if (!is_null(p=finalPoint.get_p(p_idx_))) {
747 wrappedFinalPoint.set_p(p_idx_, map_from_p_to_p_orig(*p));
748 }
749
750 thyraModel->reportFinalPoint(wrappedFinalPoint,wasSolved);
751
752}
753
754
755// Private functions overridden from ModelEvaulatorDefaultBase
756
757
758template<class Scalar>
761{
763 outArgs = this->getUnderlyingModel()->createOutArgs();
764 outArgs.setModelEvalDescription(this->description());
765 return outArgs;
766 // 2007/07/31: rabartl: ToDo: We need to manually set the forms of the
767 // derivatives that this class object will support! This needs to be based
768 // on tests of what the forms of derivatives the underlying model supports.
769}
770
771
772template<class Scalar>
773void DefaultLumpedParameterModelEvaluator<Scalar>::evalModelImpl(
774 const ModelEvaluatorBase::InArgs<Scalar> &inArgs,
775 const ModelEvaluatorBase::OutArgs<Scalar> &outArgs
776 ) const
777{
778
779 // This routine is pretty simple for the most part. By default, we just
780 // pass everything through to the underlying model evaluator except for
781 // arguments reated to the parameter subvector with index
782 // p_idx_.
783
784 using Teuchos::rcp;
785 using Teuchos::rcp_const_cast;
786 using Teuchos::rcp_dynamic_cast;
787 using Teuchos::OSTab;
789 typedef typename ST::magnitudeType ScalarMag;
790 typedef ModelEvaluatorBase MEB;
791
792 // Make sure that everything has been initialized
793 updateNominalValuesAndBounds();
794
795 THYRA_MODEL_EVALUATOR_DECORATOR_EVAL_MODEL_LOCALVERBLEVEL_BEGIN(
796 "Thyra::DefaultLumpedParameterModelEvaluator",inArgs,outArgs,localVerbLevel_
797 );
798
799 //
800 // A) Setup InArgs
801 //
802
803 // By default, copy all input arguments since they will all be the same
804 // except for the given reduced p. We will then replace the reduced p with
805 // p_orig below.
806 MEB::InArgs<Scalar> wrappedInArgs = thyraModel->createInArgs();
807 wrappedInArgs.setArgs(inArgs);
808
809 // Replace p with p_orig.
810 RCP<const VectorBase<Scalar> > p;
811 if (!is_null(p=wrappedInArgs.get_p(p_idx_))) {
812 if (
813 dumpBasisMatrix_
814 && includesVerbLevel(localVerbLevel,Teuchos::VERB_MEDIUM)
815 )
816 {
817 *out << "\nB = " << Teuchos::describe(*B_,Teuchos::VERB_EXTREME);
818 }
819 wrappedInArgs.set_p(p_idx_,map_from_p_to_p_orig(*p));
820 }
821
822 //
823 // B) Setup OutArgs
824 //
825
826 // By default, copy all output arguments since they will all be the same
827 // except for those derivatives w.r.t. p(p_idx). We will then replace the
828 // derivative objects w.r.t. given reduced p with the derivarive objects
829 // w.r.t. p_orig below.
830 MEB::OutArgs<Scalar> wrappedOutArgs = thyraModel->createOutArgs();
831 wrappedOutArgs.setArgs(outArgs);
832
833 // Set derivative output arguments for p_orig if derivatives for p are
834 // reqeusted in outArgs
835 setupWrappedParamDerivOutArgs(outArgs,&wrappedOutArgs);
836
837 //
838 // C) Evaluate the underlying model functions
839 //
840
841 if (includesVerbLevel(localVerbLevel,Teuchos::VERB_LOW))
842 *out << "\nEvaluating the fully parameterized underlying model ...\n";
843 // Compute the underlying functions in terms of p_orig, including
844 // derivatives w.r.t. p_orig.
845 thyraModel->evalModel(wrappedInArgs,wrappedOutArgs);
846
847 //
848 // D) Postprocess the output arguments
849 //
850
851 // Assemble the derivatives for p given derivatives for p_orig computed
852 // above.
853 assembleParamDerivOutArgs(wrappedOutArgs,outArgs);
854
855 THYRA_MODEL_EVALUATOR_DECORATOR_EVAL_MODEL_END();
856
857}
858
859
860// private
861
862
863template<class Scalar>
864void DefaultLumpedParameterModelEvaluator<Scalar>::finishInitialization() const
865{
866
867 typedef ScalarTraits<Scalar> ST;
868 typedef ModelEvaluatorBase MEB;
869
870 if (isInitialized_)
871 return;
872
873 //
874 // A) Get the underlying model
875 //
876
877 const RCP<const ModelEvaluator<Scalar> >
878 thyraModel = this->getUnderlyingModel();
879
881 is_null(thyraModel), std::logic_error,
882 "Error, the underlying model evaluator must be set!" );
883
884 //
885 // B) Create B for the reduced affine model for the given parameter subvector
886 //
887
888 if (autogenerateBasisMatrix_) {
889 generateParameterBasisMatrix();
890 }
891 else {
893 true, std::logic_error,
894 "Error, we don't handle a client-set parameter basis matrix yet!" );
895 }
896
897 isInitialized_ = true;
898
899}
900
901
902template<class Scalar>
903void DefaultLumpedParameterModelEvaluator<Scalar>::generateParameterBasisMatrix() const
904{
905
906 using Teuchos::as;
907 typedef ScalarTraits<Scalar> ST;
908
909 const RCP<const ModelEvaluator<Scalar> >
910 thyraModel = this->getUnderlyingModel();
911
912 const RCP<const VectorSpaceBase<Scalar> >
913 p_orig_space = thyraModel->get_p_space(p_idx_);
914
915 const Ordinal p_orig_dim = p_orig_space->dim();
916
918 !( 1 <= numberOfBasisColumns_ && numberOfBasisColumns_ <= p_orig_dim ),
919 std::logic_error,
920 "Error, the number of basis columns = " << numberOfBasisColumns_ << " does not\n"
921 "fall in the range [1,"<<p_orig_dim<<"]!" );
922
923 //
924 // Create and randomize B
925 //
926 // Here we make the first column all ones and then randomize columns 1
927 // through numberOfBasisColumns_-1 so that the average entry is 1.0 with a
928 // spread of 1.0. This is just to give as well a scaled starting matrix as
929 // possible that will hopefully yeild a well scaled orthonomal B after we
930 // are finished.
931
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()),
938 B.ptr() );
939 }
940
941 //
942 // Create an orthogonal form of B using a modified Gram Schmidt algorithm
943 //
944
945 RCP<MultiVectorBase<double> > R;
946 sillyModifiedGramSchmidt( B.ptr(), Teuchos::outArg(R) );
947
948 // Above:
949 // 1) On output, B will have orthonomal columns which makes it a good basis
950 // 2) We just discard the "R" factor since we don't need it for anything
951
952 B_ = B;
953
954}
955
956
957template<class Scalar>
958void DefaultLumpedParameterModelEvaluator<Scalar>::updateNominalValuesAndBounds() const
959{
960
961 typedef ScalarTraits<Scalar> ST;
962 typedef ModelEvaluatorBase MEB;
963
964 if (nominalValuesAndBoundsUpdated_)
965 return;
966
967 finishInitialization();
968
969 const RCP<const ModelEvaluator<Scalar> >
970 thyraModel = this->getUnderlyingModel();
971
972 const MEB::InArgs<Scalar> origNominalValues = thyraModel->getNominalValues();
973 const MEB::InArgs<Scalar> origLowerBounds = thyraModel->getLowerBounds();
974 const MEB::InArgs<Scalar> origUpperBounds = thyraModel->getUpperBounds();
975
976 // p_orig_base
977
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();
986 }
987 else {
989 true, std::logic_error,
990 "Error, we don't handle reading in the parameter base vector yet!" );
991 }
992
993 // Nominal values
994
995 nominalValues_ = origNominalValues;
996
997 if (nominalValueIsParameterBase_) {
998 // A value of p==0 will give p_orig = p_orig_init!
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);
1003 }
1004 else {
1006 true, std::logic_error,
1007 "Error, we don't handle creating p_init when p_orig_base != p_orig_init yet!" );
1008 }
1009
1010 // Bounds
1011
1012 lowerBounds_ = origLowerBounds;
1013 upperBounds_ = origUpperBounds;
1014
1015 lowerBounds_.set_p(p_idx_,Teuchos::null);
1016 upperBounds_.set_p(p_idx_,Teuchos::null);
1017
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_);
1022 if ( !is_null(p_orig_l) || !is_null(p_orig_u) ) {
1024 true, std::logic_error,
1025 "Error, we don't handle bounds on p_orig yet!" );
1026 }
1027 }
1028
1029 nominalValuesAndBoundsUpdated_ = true;
1030
1031}
1032
1033
1034template<class Scalar>
1035RCP<VectorBase<Scalar> >
1036DefaultLumpedParameterModelEvaluator<Scalar>::map_from_p_to_p_orig(
1037 const VectorBase<Scalar> &p
1038 ) const
1039{
1040 // p_orig = B*p + p_orig_base
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_ );
1044 return p_orig;
1045}
1046
1047
1048template<class Scalar>
1049void DefaultLumpedParameterModelEvaluator<Scalar>::setupWrappedParamDerivOutArgs(
1050 const ModelEvaluatorBase::OutArgs<Scalar> &outArgs, // in
1051 ModelEvaluatorBase::OutArgs<Scalar> *wrappedOutArgs_inout // in/out
1052 ) const
1053{
1054
1055 typedef ModelEvaluatorBase MEB;
1056 typedef MEB::Derivative<Scalar> Deriv;
1057
1058 TEUCHOS_TEST_FOR_EXCEPT(wrappedOutArgs_inout==0);
1059 MEB::OutArgs<Scalar> &wrappedOutArgs = *wrappedOutArgs_inout;
1060
1061 Deriv DfDp;
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));
1064 }
1065
1066 const int Ng = outArgs.Ng();
1067 for ( int j = 0; j < Ng; ++j ) {
1068 Deriv DgDp;
1069 if ( !(DgDp=outArgs.get_DgDp(j,p_idx_)).isEmpty() ) {
1070 wrappedOutArgs.set_DgDp(
1071 j, p_idx_,
1072 create_deriv_wrt_p_orig(DgDp,DgDp.getMultiVectorOrientation())
1073 );
1074 }
1075 }
1076
1077}
1078
1079
1080template<class Scalar>
1081ModelEvaluatorBase::Derivative<Scalar>
1082DefaultLumpedParameterModelEvaluator<Scalar>::create_deriv_wrt_p_orig(
1083 const ModelEvaluatorBase::Derivative<Scalar> &DhDp,
1085 ) const
1086{
1087
1088 typedef ModelEvaluatorBase MEB;
1089
1090 const RCP<const MultiVectorBase<Scalar> >
1091 DhDp_mv = DhDp.getMultiVector();
1093 is_null(DhDp_mv) || (DhDp.getMultiVectorOrientation() != requiredOrientation),
1094 std::logic_error,
1095 "Error, we currently can't handle non-multi-vector derivatives!" );
1096
1097 RCP<MultiVectorBase<Scalar> > DhDp_orig_mv;
1098 switch (requiredOrientation) {
1099 case MEB::DERIV_MV_BY_COL:
1100 // DhDp = DhDp_orig * B
1101 DhDp_orig_mv = createMembers(DhDp_mv->range(),B_->range()->dim());
1102 // Above, we could just request DhDp_orig as a LinearOpBase object since
1103 // we just need to apply it!
1104 break;
1105 case MEB::DERIV_TRANS_MV_BY_ROW:
1106 // (DhDp^T) = B^T * (DhDp_orig^T) [DhDp_orig_mv is transposed!]
1107 DhDp_orig_mv = createMembers(B_->range(),DhDp_mv->domain()->dim());
1108 // Above, we really do need DhDp_orig as the gradient form multi-vector
1109 // since it must be the RHS for a linear operator apply!
1110 break;
1111 default:
1112 TEUCHOS_TEST_FOR_EXCEPT(true); // Should never get here!
1113 }
1114
1115 return MEB::Derivative<Scalar>(DhDp_orig_mv,requiredOrientation);
1116
1117}
1118
1119
1120template<class Scalar>
1121void DefaultLumpedParameterModelEvaluator<Scalar>::assembleParamDerivOutArgs(
1122 const ModelEvaluatorBase::OutArgs<Scalar> &wrappedOutArgs, // in
1123 const ModelEvaluatorBase::OutArgs<Scalar> &outArgs // in/out
1124 ) const
1125{
1126
1127 typedef ModelEvaluatorBase MEB;
1128 typedef MEB::Derivative<Scalar> Deriv;
1129
1130 Deriv DfDp;
1131 if ( !(DfDp=outArgs.get_DfDp(p_idx_)).isEmpty() ) {
1132 assembleParamDeriv( wrappedOutArgs.get_DfDp(p_idx_), DfDp );
1133 }
1134
1135 const int Ng = outArgs.Ng();
1136 for ( int j = 0; j < Ng; ++j ) {
1137 Deriv DgDp;
1138 if ( !(DgDp=outArgs.get_DgDp(j,p_idx_)).isEmpty() ) {
1139 assembleParamDeriv( wrappedOutArgs.get_DgDp(j,p_idx_), DgDp );
1140 }
1141 }
1142
1143}
1144
1145
1146template<class Scalar>
1147void DefaultLumpedParameterModelEvaluator<Scalar>::assembleParamDeriv(
1148 const ModelEvaluatorBase::Derivative<Scalar> &DhDp_orig, // in
1149 const ModelEvaluatorBase::Derivative<Scalar> &DhDp // in/out
1150 ) const
1151{
1152
1153 typedef ModelEvaluatorBase MEB;
1154
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!" );
1160
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!" );
1166
1167 switch( DhDp_orig.getMultiVectorOrientation() ) {
1168 case MEB::DERIV_MV_BY_COL:
1169 // DhDp = DhDp_orig * B
1170#ifdef TEUCHSO_DEBUG
1172 DhDp.getMultiVectorOrientation() == MEB::DERIV_MV_BY_COL );
1173#endif
1174 apply( *DhDp_orig_mv, NOTRANS, *B_, DhDp_mv.ptr() );
1175 // Above, we could generalize DhDp_oirg to just be a general linear
1176 // operator.
1177 break;
1178 case MEB::DERIV_TRANS_MV_BY_ROW:
1179 // (DhDp^T) = B^T * (DhDp_orig^T) [DhDp_orig_mv is transposed!]
1180#ifdef TEUCHSO_DEBUG
1182 DhDp.getMultiVectorOrientation() == MEB::DERIV_TRANS_MV_BY_ROW );
1183#endif
1184 apply( *B_, CONJTRANS, *DhDp_orig_mv, DhDp_mv.ptr() );
1185 break;
1186 default:
1187 TEUCHOS_TEST_FOR_EXCEPT(true); // Should never get here!
1188 }
1189
1190}
1191
1192
1193} // namespace Thyra
1194
1195
1196#endif // THYRA_DEFAUL_LUMPED_PARAMETER_LUMPED_MODEL_EVALUATOR_HPP
T * get() const
Decorator class that wraps any ModelEvaluator object and lumps parameters together using a linear bas...
void setParameterList(RCP< Teuchos::ParameterList > const &paramList)
.
RCP< DefaultLumpedParameterModelEvaluator< Scalar > > defaultLumpedParameterModelEvaluator(const RCP< ModelEvaluator< Scalar > > &thyraModel)
Non-member constructor.
RCP< const VectorSpaceBase< Scalar > > get_p_space(int l) 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.
This is a base class that delegetes almost all function to a wrapped model evaluator object.
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)