Thyra  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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 
26 namespace Thyra {
27 
28 
207 template<class Scalar>
209  : virtual public ModelEvaluatorDelegatorBase<Scalar>
210  , virtual public Teuchos::ParameterListAcceptor
211 {
212 public:
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 
280 private:
281 
284 
286  ModelEvaluatorBase::OutArgs<Scalar> createOutArgsImpl() const;
288  void evalModelImpl(
291  ) const;
292 
294 
295 private:
296 
297  // ////////////////////////////////
298  // Private data members
299 
300  mutable bool isInitialized_;
301  mutable bool nominalValuesAndBoundsUpdated_;
302 
303  mutable RCP<const Teuchos::ParameterList> validParamList_;
304  RCP<Teuchos::ParameterList> paramList_;
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 
399 template<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 
419 template<class Scalar>
420 const std::string
422 = "Parameter Subvector Index";
423 
424 template<class Scalar>
425 const int
427 = 0;
428 
429 
430 template<class Scalar>
431 const std::string
433 = "Auto-generate Basis Matrix";
434 
435 template<class Scalar>
436 const bool
438 = true;
439 
440 
441 template<class Scalar>
442 const std::string
444 = "Number of Basis Columns";
445 
446 template<class Scalar>
447 const int
449 = 1;
450 
451 
452 template<class Scalar>
453 const std::string
455 = "Nominal Value is Parameter Base";
456 
457 template<class Scalar>
458 const bool
460 = true;
461 
462 
463 template<class Scalar>
464 const std::string
466 = "Parameter Base Vector";
467 
468 
469 template<class Scalar>
470 const std::string
472 = "Ignore Parameter Bounds";
473 
474 template<class Scalar>
475 const bool
477 = false;
478 
479 
480 template<class Scalar>
481 const std::string
483 = "Dump Basis Matrix";
484 
485 template<class Scalar>
486 const bool
488 = false;
489 
490 
491 // Constructors/initializers/accessors/utilities
492 
493 
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_),
503  localVerbLevel_(Teuchos::VERB_DEFAULT),
504  dumpBasisMatrix_(DumpBasisMatrix_default_)
505 {}
506 
507 
508 template<class Scalar>
510  const RCP<ModelEvaluator<Scalar> > &thyraModel
511  )
512 {
513  isInitialized_ = false;
514  nominalValuesAndBoundsUpdated_ = false;
516 }
517 
518 
519 template<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 
533 template<class Scalar>
534 std::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 
554 template<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 
602 template<class Scalar>
605 {
606  return paramList_;
607 }
608 
609 
610 template<class Scalar>
613 {
614  RCP<Teuchos::ParameterList> _paramList = paramList_;
615  paramList_ = Teuchos::null;
616  return _paramList;
617 }
618 
619 
620 template<class Scalar>
623 {
624  return paramList_;
625 }
626 
627 
628 template<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 
674 template<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 
685 template<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 
696 template<class Scalar>
699 {
700  updateNominalValuesAndBounds();
701  return nominalValues_;
702 }
703 
704 
705 template<class Scalar>
708 {
709  updateNominalValuesAndBounds();
710  return lowerBounds_;
711 }
712 
713 
714 template<class Scalar>
717 {
718  updateNominalValuesAndBounds();
719  return upperBounds_;
720 }
721 
722 
723 template<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 
758 template<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 
772 template<class Scalar>
773 void 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 
863 template<class Scalar>
864 void 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 
902 template<class Scalar>
903 void 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 
957 template<class Scalar>
958 void 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 
1034 template<class Scalar>
1035 RCP<VectorBase<Scalar> >
1036 DefaultLumpedParameterModelEvaluator<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 
1048 template<class Scalar>
1049 void 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 
1080 template<class Scalar>
1081 ModelEvaluatorBase::Derivative<Scalar>
1082 DefaultLumpedParameterModelEvaluator<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 
1120 template<class Scalar>
1121 void 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 
1146 template<class Scalar>
1147 void 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
void reportFinalPoint(const ModelEvaluatorBase::InArgs< Scalar > &finalPoint, const bool wasSolved)
Pure abstract base interface for evaluating a stateless &quot;model&quot; 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...
RCP< const Array< std::string > > get_p_names(int l) const
T & get(const std::string &name, T def_value)
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)...
T * get() 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 &paramList)
ModelEvaluatorBase::InArgs< Scalar > getNominalValues() const
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Teuchos::Ordinal Ordinal
Type for the dimension of a vector space. `*.
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
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 &lt;= l &amp;&amp; l &lt; this-&gt;Np().
Protected subclass of OutArgs that only ModelEvaluator subclasses can access to set up the selection ...
Concrete aggregate class for all input arguments computable by a ModelEvaluator subclass object...