Thyra  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Thyra_DefaultMultiPeriodModelEvaluator.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_DEFAULT_MULTI_PERIOD_MODEL_EVALUATOR_HPP
11 #define THYRA_DEFAULT_MULTI_PERIOD_MODEL_EVALUATOR_HPP
12 
13 
14 #include "Thyra_ModelEvaluatorDefaultBase.hpp"
15 #include "Thyra_DefaultProductVectorSpace.hpp"
16 #include "Thyra_DefaultBlockedTriangularLinearOpWithSolveFactory.hpp" // Default implementation
17 #include "Thyra_DefaultBlockedLinearOp.hpp"
18 #include "Thyra_ModelEvaluatorDelegatorBase.hpp"
19 #include "Thyra_ProductVectorBase.hpp"
20 #include "Teuchos_implicit_cast.hpp"
21 #include "Teuchos_AbstractFactory.hpp" // Interface
22 #include "Teuchos_AbstractFactoryStd.hpp" // Implementation
23 
24 
25 namespace Thyra {
26 
27 
98 template<class Scalar>
100  : virtual public ModelEvaluatorDefaultBase<Scalar>
101 {
102 public:
103 
106 
109 
112  const int N,
113  const Array<RCP<ModelEvaluator<Scalar> > > &periodModels,
114  const Array<int> &z_indexes,
115  const Array<Array<RCP<const VectorBase<Scalar> > > > &z,
116  const int g_index,
117  const Array<Scalar> g_weights,
118  const RCP<const ProductVectorSpaceBase<Scalar> > &x_bar_space = Teuchos::null,
119  const RCP<const ProductVectorSpaceBase<Scalar> > &f_bar_space = Teuchos::null,
120  const RCP<LinearOpWithSolveFactoryBase<Scalar> > &W_bar_factory = Teuchos::null
121  );
122 
181  void initialize(
182  const int N,
183  const Array<RCP<ModelEvaluator<Scalar> > > &periodModels,
184  const Array<int> &z_indexes,
185  const Array<Array<RCP<const VectorBase<Scalar> > > > &z,
186  const int g_index,
187  const Array<Scalar> g_weights,
188  const RCP<const ProductVectorSpaceBase<Scalar> > &x_bar_space = Teuchos::null,
189  const RCP<const ProductVectorSpaceBase<Scalar> > &f_bar_space = Teuchos::null,
190  const RCP<LinearOpWithSolveFactoryBase<Scalar> > &W_bar_factory = Teuchos::null
191  );
192 
202  void reset_z(
203  const Array<Array<RCP<const VectorBase<Scalar> > > > &z
204  );
205 
207 
210 
212  int Np() const;
214  int Ng() const;
242  void reportFinalPoint(
243  const ModelEvaluatorBase::InArgs<Scalar> &finalPoint,
244  const bool wasSolved
245  );
246 
248 
249 private:
250 
251 
254 
256  RCP<LinearOpBase<Scalar> > create_DfDp_op_impl(int l) const;
258  RCP<LinearOpBase<Scalar> > create_DgDx_dot_op_impl(int j) const;
260  RCP<LinearOpBase<Scalar> > create_DgDx_op_impl(int j) const;
262  RCP<LinearOpBase<Scalar> > create_DgDp_op_impl(int j, int l) const;
264  ModelEvaluatorBase::OutArgs<Scalar> createOutArgsImpl() const;
266  void evalModelImpl(
269  ) const;
270 
272 
273 private:
274 
275  // //////////////////////////
276  // Private types
277 
278  typedef Array<Scalar> g_weights_t;
280 
281  // /////////////////////////
282  // Private data members
283 
284  RCP<ModelEvaluator<Scalar> > periodModel_;
285  Array<RCP<ModelEvaluator<Scalar> > > periodModels_;
286  Array<int> z_indexes_;
287  Array<int> period_l_map_;
288  z_t z_; // size == N
289  int g_index_;
290  g_weights_t g_weights_; // size == N
294  int Np_;
295  int Ng_;
296  ModelEvaluatorBase::InArgs<Scalar> nominalValues_;
299 
300  // /////////////////////////
301  // Private member functions
302 
303  void set_z_indexes_and_create_period_l_map( const Array<int> &z_indexes );
304 
305  void wrapNominalValuesAndBounds();
306 
307  static
309  createProductVector(
310  const RCP<const ProductVectorSpaceBase<Scalar> > &prodVecSpc
311  );
312 
313  // Return the index of a "free" parameter in the period model given its
314  // index in this mulit-period model.
315  int period_l(const int l) const
316  {
317  TEUCHOS_TEST_FOR_EXCEPT( !( 0 <= l && l < Np_) );
318  return period_l_map_[l];
319  }
320 
321  int numPeriodZs() const { return z_indexes_.size(); }
322 
323  int N() const { return x_bar_space_->numBlocks(); }
324 
325 };
326 
327 
328 // /////////////////////////////////
329 // Implementations
330 
331 
332 // Constructors/Intializers/Accessors
333 
334 
335 template<class Scalar>
337  :g_index_(-1), Np_(-1), Ng_(-1)
338 {}
339 
340 
341 template<class Scalar>
343  const int N,
344  const Array<RCP<ModelEvaluator<Scalar> > > &periodModels,
345  const Array<int> &z_indexes,
346  const Array<Array<RCP<const VectorBase<Scalar> > > > &z,
347  const int g_index,
348  const Array<Scalar> g_weights,
349  const RCP<const ProductVectorSpaceBase<Scalar> > &x_bar_space,
350  const RCP<const ProductVectorSpaceBase<Scalar> > &f_bar_space,
351  const RCP<LinearOpWithSolveFactoryBase<Scalar> > &W_bar_factory
352  )
353  :g_index_(-1), Np_(-1), Ng_(-1)
354 {
355  initialize(
356  N, periodModels, z_indexes, z, g_index, g_weights,
357  x_bar_space, f_bar_space, W_bar_factory
358  );
359 }
360 
361 
362 template<class Scalar>
364  const int N,
365  const Array<RCP<ModelEvaluator<Scalar> > > &periodModels,
366  const Array<int> &z_indexes,
367  const Array<Array<RCP<const VectorBase<Scalar> > > > &z,
368  const int g_index,
369  const Array<Scalar> g_weights,
370  const RCP<const ProductVectorSpaceBase<Scalar> > &x_bar_space,
371  const RCP<const ProductVectorSpaceBase<Scalar> > &f_bar_space,
372  const RCP<LinearOpWithSolveFactoryBase<Scalar> > &W_bar_factory
373  )
374 {
375 
378  typedef ModelEvaluatorBase MEB;
379 
380  TEUCHOS_TEST_FOR_EXCEPT( N <= 0 );
381  TEUCHOS_TEST_FOR_EXCEPT( implicit_cast<int>(periodModels.size()) != N );
382  MEB::InArgs<Scalar> periodInArgs = periodModels[0]->createInArgs();
383  MEB::OutArgs<Scalar> periodOutArgs = periodModels[0]->createOutArgs();
384  for ( int k = 0; k < implicit_cast<int>(z_indexes.size()); ++k ) {
385  TEUCHOS_TEST_FOR_EXCEPT( !( 0 <= z_indexes[k] && z_indexes[k] < periodInArgs.Np() ) );
386  }
387  TEUCHOS_TEST_FOR_EXCEPT( implicit_cast<int>(z.size())!=N );
388  TEUCHOS_TEST_FOR_EXCEPT( !( 0 <= g_index && g_index < periodOutArgs.Ng() ) );
389  TEUCHOS_TEST_FOR_EXCEPT( implicit_cast<int>(g_weights.size())!=N );
390  // ToDo: Assert that the different period models are compatible!
391 
392  Np_ = periodInArgs.Np() - z_indexes.size();
393 
394  Ng_ = 1;
395 
396  set_z_indexes_and_create_period_l_map(z_indexes);
397 
398  periodModel_ = periodModels[0]; // Assume basic structure!
399 
400  periodModels_ = periodModels;
401 
402  z_.resize(N);
403  reset_z(z);
404 
405  g_index_ = g_index;
406  g_weights_ = g_weights;
407 
408  if ( periodInArgs.supports(MEB::IN_ARG_x) ) {
409  if( !is_null(x_bar_space) ) {
410  TEUCHOS_TEST_FOR_EXCEPT(!(x_bar_space->numBlocks()==N));
411  // ToDo: Check the constituent spaces more carefully against models[]->get_x_space().
412  x_bar_space_ = x_bar_space;
413  }
414  else {
415  x_bar_space_ = productVectorSpace(periodModel_->get_x_space(),N);
416  // ToDo: Update to build from different models for different x spaces!
417  }
418  }
419 
420  if ( periodOutArgs.supports(MEB::OUT_ARG_f) ) {
421  if( !is_null(f_bar_space) ) {
422  TEUCHOS_TEST_FOR_EXCEPT(!(f_bar_space->numBlocks()==N));
423  // ToDo: Check the constituent spaces more carefully against models[]->get_f_space().
424  f_bar_space_ = f_bar_space;
425  }
426  else {
427  f_bar_space_ = productVectorSpace(periodModel_->get_f_space(),N);
428  // ToDo: Update to build from different models for different f spaces!
429  }
430  }
431 
432  if ( periodOutArgs.supports(MEB::OUT_ARG_W) ) {
433  if ( !is_null(W_bar_factory) ) {
434  // ToDo: Check the compatability of the W_bar objects created using this object!
435  W_bar_factory_ = W_bar_factory;
436  }
437  else {
438  W_bar_factory_ =
439  defaultBlockedTriangularLinearOpWithSolveFactory<Scalar>(
440  periodModel_->get_W_factory() );
441  }
442  }
443 
444  wrapNominalValuesAndBounds();
445 
446 }
447 
448 
449 template<class Scalar>
451  const Array<Array<RCP<const VectorBase<Scalar> > > > &z
452  )
453 {
454 
456 
457  const int N = z_.size();
458 
459 #ifdef TEUCHOS_DEBUG
460  TEUCHOS_TEST_FOR_EXCEPT( N == 0 && "Error, must have called initialize() first!" );
461  TEUCHOS_TEST_FOR_EXCEPT( implicit_cast<int>(z.size()) != N );
462 #endif
463 
464  for( int i = 0; i < N; ++i ) {
465  const Array<RCP<const VectorBase<Scalar> > > &z_i = z[i];
466 #ifdef TEUCHOS_DEBUG
467  TEUCHOS_TEST_FOR_EXCEPT( z_i.size() != z_indexes_.size() );
468 #endif
469  z_[i] = z_i;
470  }
471 
472 }
473 
474 
475 // Public functions overridden from ModelEvaulator
476 
477 
478 template<class Scalar>
480 {
481  return Np_;
482 }
483 
484 
485 template<class Scalar>
487 {
488  return Ng_;
489 }
490 
491 
492 template<class Scalar>
495 {
496  return x_bar_space_;
497 }
498 
499 
500 template<class Scalar>
503 {
504  return f_bar_space_;
505 }
506 
507 
508 template<class Scalar>
511 {
512  return periodModel_->get_p_space(period_l(l));
513 }
514 
515 
516 template<class Scalar>
519 {
520  return periodModel_->get_p_names(period_l(l));
521 }
522 
523 
524 template<class Scalar>
527 {
529  return periodModel_->get_g_space(g_index_);
530 }
531 
532 
533 template<class Scalar>
536 {
537  return periodModel_->get_g_names(j);
538 }
539 
540 
541 template<class Scalar>
544 {
545  return nominalValues_;
546 }
547 
548 
549 template<class Scalar>
552 {
553  return lowerBounds_;
554 }
555 
556 
557 template<class Scalar>
560 {
561  return upperBounds_;
562 }
563 
564 
565 template<class Scalar>
568 {
569  // Set up the block structure ready to have the blocks filled!
571  W_op_bar = defaultBlockedLinearOp<Scalar>();
572  W_op_bar->beginBlockFill(f_bar_space_,x_bar_space_);
573  const int N = x_bar_space_->numBlocks();
574  for ( int i = 0; i < N; ++i ) {
575  W_op_bar->setNonconstBlock( i, i, periodModel_->create_W_op() );
576  }
577  W_op_bar->endBlockFill();
578  return W_op_bar;
579 }
580 
581 
582 template<class Scalar>
585 {
586  return Teuchos::null;
587 }
588 
589 
590 template<class Scalar>
593 {
594  return W_bar_factory_;
595 }
596 
597 
598 template<class Scalar>
601 {
602  typedef ModelEvaluatorBase MEB;
603  MEB::InArgs<Scalar> periodInArgs = periodModel_->createInArgs();
604  MEB::InArgsSetup<Scalar> inArgs;
605  inArgs.setModelEvalDescription(this->description());
606  inArgs.set_Np(Np_);
607  inArgs.setSupports( MEB::IN_ARG_x, periodInArgs.supports(MEB::IN_ARG_x) );
608  return inArgs;
609 }
610 
611 
612 template<class Scalar>
614  const ModelEvaluatorBase::InArgs<Scalar> &finalPoint
615  ,const bool wasSolved
616  )
617 {
618  // We are just going to ignore the final point here. It is not clear how to
619  // report a "final" point back to the underlying *periodModel_ object since
620  // we have so many different "points" that we could return (i.e. one for
621  // each period). I guess we could report back the final parameter values
622  // (other than the z parameter) but there are multiple states x[i] and
623  // period parameters z[i] that we can report back.
624 }
625 
626 
627 // Public functions overridden from ModelEvaulatorDefaultBase
628 
629 
630 template<class Scalar>
633 {
634  TEUCHOS_TEST_FOR_EXCEPT("This class does not support DfDp(l) as a linear operator yet.");
635  return Teuchos::null;
636 }
637 
638 
639 template<class Scalar>
640 RCP<LinearOpBase<Scalar> >
641 DefaultMultiPeriodModelEvaluator<Scalar>::create_DgDx_dot_op_impl(int j) const
642 {
643  TEUCHOS_TEST_FOR_EXCEPT("This class does not support DgDx_dot(j) as a linear operator yet.");
644  return Teuchos::null;
645 }
646 
647 
648 template<class Scalar>
649 RCP<LinearOpBase<Scalar> >
650 DefaultMultiPeriodModelEvaluator<Scalar>::create_DgDx_op_impl(int j) const
651 {
652  TEUCHOS_TEST_FOR_EXCEPT("This class does not support DgDx(j) as a linear operator yet.");
653  return Teuchos::null;
654 }
655 
656 
657 template<class Scalar>
658 RCP<LinearOpBase<Scalar> >
659 DefaultMultiPeriodModelEvaluator<Scalar>::create_DgDp_op_impl(int j, int l) const
660 {
661  TEUCHOS_TEST_FOR_EXCEPT("This class does not support DgDp(j,l) as a linear operator yet.");
662  return Teuchos::null;
663 }
664 
665 
666 template<class Scalar>
667 ModelEvaluatorBase::OutArgs<Scalar>
668 DefaultMultiPeriodModelEvaluator<Scalar>::createOutArgsImpl() const
669 {
670 
671  typedef ModelEvaluatorBase MEB;
672 
673  MEB::OutArgs<Scalar> periodOutArgs = periodModel_->createOutArgs();
674  MEB::OutArgsSetup<Scalar> outArgs;
675 
676  outArgs.setModelEvalDescription(this->description());
677 
678  outArgs.set_Np_Ng(Np_,Ng_);
679 
680  // f
681  if (periodOutArgs.supports(MEB::OUT_ARG_f) ) {
682  outArgs.setSupports(MEB::OUT_ARG_f);
683  }
684 
685  // W_op
686  if (periodOutArgs.supports(MEB::OUT_ARG_W_op) ) {
687  outArgs.setSupports(MEB::OUT_ARG_W_op);
688  outArgs.set_W_properties(periodOutArgs.get_W_properties());
689  }
690  // Note: We will not directly support the LOWSB form W as we will let the
691  // default base class handle this given our W_factory!
692 
693  // DfDp(l)
694  for ( int l = 0; l < Np_; ++l ) {
695  const int period_l = this->period_l(l);
696  const MEB::DerivativeSupport period_DfDp_l_support
697  = periodOutArgs.supports(MEB::OUT_ARG_DfDp,period_l);
698  if (!period_DfDp_l_support.none()) {
699  outArgs.setSupports( MEB::OUT_ARG_DfDp, l, period_DfDp_l_support );
700  outArgs.set_DfDp_properties(
701  l, periodOutArgs.get_DfDp_properties(period_l) );
702  }
703  }
704 
705  // DgDx_dot
706  const MEB::DerivativeSupport
707  period_DgDx_dot_support = periodOutArgs.supports(MEB::OUT_ARG_DgDx_dot,g_index_);
708  if (!period_DgDx_dot_support.none()) {
709  outArgs.setSupports( MEB::OUT_ARG_DgDx_dot, 0, period_DgDx_dot_support );
710  outArgs.set_DgDx_dot_properties(
711  0, periodOutArgs.get_DgDx_dot_properties(g_index_) );
712  }
713 
714  // DgDx
715  const MEB::DerivativeSupport
716  period_DgDx_support = periodOutArgs.supports(MEB::OUT_ARG_DgDx,g_index_);
717  if (!period_DgDx_support.none()) {
718  outArgs.setSupports( MEB::OUT_ARG_DgDx, 0, period_DgDx_support );
719  outArgs.set_DgDx_properties(
720  0, periodOutArgs.get_DgDx_properties(g_index_) );
721  }
722 
723  // DgDp(l)
724  for ( int l = 0; l < Np_; ++l ) {
725  const int period_l = this->period_l(l);
726  const MEB::DerivativeSupport period_DgDp_l_support
727  = periodOutArgs.supports(MEB::OUT_ARG_DgDp, g_index_, period_l);
728  if (!period_DgDp_l_support.none()) {
729  outArgs.setSupports( MEB::OUT_ARG_DgDp, 0, l, period_DgDp_l_support );
730  outArgs.set_DgDp_properties(
731  0, l, periodOutArgs.get_DgDp_properties(g_index_,period_l) );
732  }
733  }
734 
735  return outArgs;
736 
737 }
738 
739 
740 template<class Scalar>
741 void DefaultMultiPeriodModelEvaluator<Scalar>::evalModelImpl(
742  const ModelEvaluatorBase::InArgs<Scalar> &inArgs,
743  const ModelEvaluatorBase::OutArgs<Scalar> &outArgs
744  ) const
745 {
746 
747  using Teuchos::rcp_dynamic_cast;
749  typedef ModelEvaluatorBase MEB;
751 
752  THYRA_MODEL_EVALUATOR_DECORATOR_EVAL_MODEL_GEN_BEGIN(
753  "DefaultMultiPeriodModelEvaluator",inArgs,outArgs,periodModel_ );
754  // ToDo: You will have to set the verbosity level for each of the
755  // periodModels_[i] individually below!
756 
757  const int N = x_bar_space_->numBlocks();
758  const int Np = this->Np_;
759  //const int Ng = this->Ng_;
760 
761  //
762  // A) Setup InArgs
763  //
764 
765  RCP<const ProductVectorBase<Scalar> > x_bar;
766  if (inArgs.supports(MEB::IN_ARG_x)) {
767  x_bar = rcp_dynamic_cast<const ProductVectorBase<Scalar> >(
768  inArgs.get_x(), true );
770  is_null(x_bar), std::logic_error,
771  "Error, if x is supported, it must be set!"
772  );
773  }
774 
775  //
776  // B) Setup OutArgs
777  //
778 
779  RCP<ProductVectorBase<Scalar> > f_bar;
780  if (outArgs.supports(MEB::OUT_ARG_f)) {
781  f_bar = rcp_dynamic_cast<ProductVectorBase<Scalar> >(
782  outArgs.get_f(), true );
783  }
784 
785  Array<MEB::Derivative<Scalar> > DfDp_bar(Np);
786  Array<RCP<ProductMultiVectorBase<Scalar> > > DfDp_bar_mv(Np);
787  for ( int l = 0; l < Np; ++l ) {
788  if (!outArgs.supports(MEB::OUT_ARG_DfDp,l).none()) {
789  MEB::Derivative<Scalar>
790  DfDp_bar_l = outArgs.get_DfDp(l);
791  DfDp_bar[l] = DfDp_bar_l;
792  DfDp_bar_mv[l] = rcp_dynamic_cast<ProductMultiVectorBase<Scalar> >(
793  DfDp_bar_l.getMultiVector(), true );
795  (
796  !DfDp_bar_l.isEmpty()
797  &&
798  (
799  is_null(DfDp_bar_mv[l])
800  ||
801  DfDp_bar_l.getMultiVectorOrientation() != MEB::DERIV_MV_BY_COL
802  )
803  ),
804  std::logic_error,
805  "Error, we currently can only handle DfDp as an column-based multi-vector!"
806  );
807  }
808  }
809 
810  RCP<BlockedLinearOpBase<Scalar> > W_op_bar;
811  if (outArgs.supports(MEB::OUT_ARG_W_op)) {
812  W_op_bar = rcp_dynamic_cast<BlockedLinearOpBase<Scalar> >(
813  outArgs.get_W_op(), true
814  );
815  }
816 
817  RCP<VectorBase<Scalar> >
818  g_bar = outArgs.get_g(0);
819 
820  MEB::Derivative<Scalar> DgDx_dot_bar;
821  RCP<ProductMultiVectorBase<Scalar> > DgDx_dot_bar_mv;
822  if (!outArgs.supports(MEB::OUT_ARG_DgDx_dot,0).none()) {
823  DgDx_dot_bar = outArgs.get_DgDx_dot(0);
824  DgDx_dot_bar_mv = rcp_dynamic_cast<ProductMultiVectorBase<Scalar> >(
825  DgDx_dot_bar.getMultiVector(), true );
827  (
828  !DgDx_dot_bar.isEmpty()
829  &&
830  (
831  is_null(DgDx_dot_bar_mv)
832  ||
833  DgDx_dot_bar.getMultiVectorOrientation() != MEB::DERIV_TRANS_MV_BY_ROW
834  )
835  ),
836  std::logic_error,
837  "Error, we currently can only handle DgDx_dot as an row-based multi-vector!"
838  );
839  }
840 
841  MEB::Derivative<Scalar> DgDx_bar;
842  RCP<ProductMultiVectorBase<Scalar> > DgDx_bar_mv;
843  if (!outArgs.supports(MEB::OUT_ARG_DgDx,0).none()) {
844  DgDx_bar = outArgs.get_DgDx(0);
845  DgDx_bar_mv = rcp_dynamic_cast<ProductMultiVectorBase<Scalar> >(
846  DgDx_bar.getMultiVector(), true );
848  (
849  !DgDx_bar.isEmpty()
850  &&
851  (
852  is_null(DgDx_bar_mv)
853  ||
854  DgDx_bar.getMultiVectorOrientation() != MEB::DERIV_TRANS_MV_BY_ROW
855  )
856  ),
857  std::logic_error,
858  "Error, we currently can only handle DgDx as an row-based multi-vector!"
859  );
860  }
861 
862  Array<MEB::Derivative<Scalar> > DgDp_bar(Np);
863  Array<RCP<MultiVectorBase<Scalar> > > DgDp_bar_mv(Np);
864  for ( int l = 0; l < Np; ++l ) {
865  if (!outArgs.supports(MEB::OUT_ARG_DgDp,0,l).none()) {
866  MEB::Derivative<Scalar>
867  DgDp_bar_l = outArgs.get_DgDp(0,l);
868  DgDp_bar[l] = DgDp_bar_l;
869  DgDp_bar_mv[l] = DgDp_bar_l.getMultiVector();
871  !DgDp_bar_l.isEmpty() && is_null(DgDp_bar_mv[l]),
872  std::logic_error,
873  "Error, we currently can only handle DgDp as some type of multi-vector!"
874  );
875  }
876  }
877 
878  //
879  // C) Evaluate the model
880  //
881 
882  // C.1) Set up storage and do some initializations
883 
884  MEB::InArgs<Scalar>
885  periodInArgs = periodModel_->createInArgs();
886  // ToDo: The above will have to change if you allow different structures for
887  // each period model!
888 
889  // Set all of the parameters that will just be passed through
890  for ( int l = 0; l < Np; ++l )
891  periodInArgs.set_p( period_l(l), inArgs.get_p(l) ); // Can be null just fine
892 
893  MEB::OutArgs<Scalar>
894  periodOutArgs = periodModel_->createOutArgs();
895  // ToDo: The above will have to change if you allow different structures for
896  // each period model!
897 
898  // Create storage for period g's that will be summed into global g_bar
899  periodOutArgs.set_g(
900  g_index_, createMember<Scalar>( periodModel_->get_g_space(g_index_) ) );
901 
902  // Zero out global g_bar that will be summed into below
903  if (!is_null(g_bar) )
904  assign( g_bar.ptr(), ST::zero() );
905 
906  // Set up storage for peroid DgDp[l] objects that will be summed into global
907  // DgDp_bar[l] and zero out DgDp_bar[l] that will be summed into.
908  for ( int l = 0; l < Np; ++l ) {
909  if ( !is_null(DgDp_bar_mv[l]) ) {
910  assign(DgDp_bar_mv[l].ptr(), ST::zero());
911  periodOutArgs.set_DgDp(
912  g_index_, period_l(l),
913  create_DgDp_mv(
914  *periodModel_, g_index_, period_l(l),
915  DgDp_bar[l].getMultiVectorOrientation()
916  )
917  );
918  }
919  }
920 
921  // C.2) Loop over periods and assemble the model
922 
923  for ( int i = 0; i < N; ++i ) {
924 
925  VOTSME thyraModel_outputTempState(periodModels_[i],out,verbLevel);
926 
927  // C.2.a) Set period-speicific InArgs and OutArgs
928 
929  for ( int k = 0; k < numPeriodZs(); ++k )
930  periodInArgs.set_p( z_indexes_[k], z_[i][k] );
931 
932  if (!is_null(x_bar))
933  periodInArgs.set_x(x_bar->getVectorBlock(i));
934 
935  if (!is_null(f_bar))
936  periodOutArgs.set_f(f_bar->getNonconstVectorBlock(i)); // Updated in place!
937 
938  if ( !is_null(W_op_bar) )
939  periodOutArgs.set_W_op(W_op_bar->getNonconstBlock(i,i));
940 
941  for ( int l = 0; l < Np; ++l ) {
942  if ( !is_null(DfDp_bar_mv[l]) ) {
943  periodOutArgs.set_DfDp(
944  period_l(l),
945  MEB::Derivative<Scalar>(
946  DfDp_bar_mv[l]->getNonconstMultiVectorBlock(i),
947  MEB::DERIV_MV_BY_COL
948  )
949  );
950  }
951  }
952 
953  if ( !is_null(DgDx_dot_bar_mv) ) {
954  periodOutArgs.set_DgDx_dot(
955  g_index_,
956  MEB::Derivative<Scalar>(
957  DgDx_dot_bar_mv->getNonconstMultiVectorBlock(i),
958  MEB::DERIV_TRANS_MV_BY_ROW
959  )
960  );
961  }
962 
963  if ( !is_null(DgDx_bar_mv) ) {
964  periodOutArgs.set_DgDx(
965  g_index_,
966  MEB::Derivative<Scalar>(
967  DgDx_bar_mv->getNonconstMultiVectorBlock(i),
968  MEB::DERIV_TRANS_MV_BY_ROW
969  )
970  );
971  }
972 
973  // C.2.b) Evaluate the period model
974 
975  periodModels_[i]->evalModel( periodInArgs, periodOutArgs );
976 
977  // C.2.c) Process output arguments that need processed
978 
979  // Sum into global g_bar
980  if (!is_null(g_bar)) {
981  Vp_StV( g_bar.ptr(), g_weights_[i], *periodOutArgs.get_g(g_index_) );
982  }
983 
984  // Sum into global DgDp_bar
985  for ( int l = 0; l < Np; ++l ) {
986  if ( !is_null(DgDp_bar_mv[l]) ) {
987  update(
988  g_weights_[i],
989  *periodOutArgs.get_DgDp(g_index_,period_l(l)).getMultiVector(),
990  DgDp_bar_mv[l].ptr()
991  );
992  }
993  }
994 
995  // Scale DgDx_dot_bar_mv[i]
996  if ( !is_null(DgDx_dot_bar_mv) ) {
997  scale( g_weights_[i],
998  DgDx_dot_bar_mv->getNonconstMultiVectorBlock(i).ptr() );
999  }
1000 
1001  // Scale DgDx_bar_mv[i]
1002  if ( !is_null(DgDx_bar_mv) ) {
1003  scale( g_weights_[i],
1004  DgDx_bar_mv->getNonconstMultiVectorBlock(i).ptr() );
1005  }
1006 
1007  }
1008 
1009  // ToDo: We need to do some type of global sum of g_bar and DgDp_bar to
1010  // account for other clusters of processes. I might do this with a separate
1011  // non-ANA class.
1012 
1013  // Once we get here, all of the quantities should be updated and we should
1014  // be all done!
1015 
1016  THYRA_MODEL_EVALUATOR_DECORATOR_EVAL_MODEL_END();
1017 
1018 }
1019 
1020 
1021 // private
1022 
1023 
1024 template<class Scalar>
1025 void DefaultMultiPeriodModelEvaluator<Scalar>::set_z_indexes_and_create_period_l_map(
1026  const Array<int> &z_indexes
1027  )
1028 {
1029 #ifdef TEUCHOS_DEBUG
1030  TEUCHOS_TEST_FOR_EXCEPT( Np_ <= 0 && "Error, Np must be set!" );
1031 #endif
1032  z_indexes_ = z_indexes;
1033  period_l_map_.resize(0);
1034  const int numTotalParams = Np_ + z_indexes_.size();
1036  z_indexes_itr = z_indexes_.begin(),
1037  z_indexes_end = z_indexes_.end();
1038  int last_z_index = -1;
1039  for ( int k = 0; k < numTotalParams; ++k ) {
1040  if ( z_indexes_itr == z_indexes_end || k < *z_indexes_itr ) {
1041  // This is a "free" parameter subvector
1042  period_l_map_.push_back(k);
1043  }
1044  else {
1045  // This is a "fixed" period parameter subvector so increment
1046  // z_indexes iterator.
1047 #ifdef TEUCHOS_DEBUG
1048  TEUCHOS_TEST_FOR_EXCEPT( k != *z_indexes_itr && "This should never happen!" );
1049 #endif
1050  const int tmp_last_z_index = *z_indexes_itr;
1051  ++z_indexes_itr;
1052  if ( z_indexes_itr != z_indexes_end ) {
1053 #ifdef TEUCHOS_DEBUG
1054  if ( last_z_index >= 0 ) {
1056  *z_indexes_itr <= last_z_index, std::logic_error,
1057  "Error, the z_indexes array = " << toString(z_indexes_)
1058  << " is not sorted or contains duplicate entries!"
1059  );
1060  }
1061 #endif
1062  last_z_index = tmp_last_z_index;
1063  }
1064  }
1065  }
1066 }
1067 
1068 
1069 template<class Scalar>
1070 void DefaultMultiPeriodModelEvaluator<Scalar>::wrapNominalValuesAndBounds()
1071 {
1072 
1073  using Teuchos::rcp_dynamic_cast;
1074  typedef ModelEvaluatorBase MEB;
1075 
1076  nominalValues_ = this->createInArgs();
1077  lowerBounds_ = this->createInArgs();
1078  upperBounds_ = this->createInArgs();
1079 
1080  const MEB::InArgs<Scalar>
1081  periodNominalValues = periodModel_->getNominalValues(),
1082  periodLowerBounds = periodModel_->getLowerBounds(),
1083  periodUpperBounds = periodModel_->getUpperBounds();
1084 
1085  if (periodNominalValues.supports(MEB::IN_ARG_x)) {
1086 
1087  if( !is_null(periodNominalValues.get_x()) ) {
1088  // If the first peroid model has nominal values for x, then all of them
1089  // must also!
1090  RCP<Thyra::ProductVectorBase<Scalar> >
1091  x_bar_init = createProductVector(x_bar_space_);
1092  const int N = this->N();
1093  for ( int i = 0; i < N; ++i ) {
1094  assign(
1095  x_bar_init->getNonconstVectorBlock(i).ptr(),
1096  *periodModels_[i]->getNominalValues().get_x()
1097  );
1098  }
1099  nominalValues_.set_x(x_bar_init);
1100  }
1101 
1102  if( !is_null(periodLowerBounds.get_x()) ) {
1103  // If the first peroid model has lower bounds for for x, then all of
1104  // them must also!
1105  RCP<Thyra::ProductVectorBase<Scalar> >
1106  x_bar_l = createProductVector(x_bar_space_);
1107  const int N = this->N();
1108  for ( int i = 0; i < N; ++i ) {
1109  assign(
1110  x_bar_l->getNonconstVectorBlock(i).ptr(),
1111  *periodModels_[i]->getLowerBounds().get_x()
1112  );
1113  }
1114  lowerBounds_.set_x(x_bar_l);
1115  }
1116 
1117  if( !is_null(periodUpperBounds.get_x()) ) {
1118  // If the first peroid model has upper bounds for for x, then all of
1119  // them must also!
1120  RCP<Thyra::ProductVectorBase<Scalar> >
1121  x_bar_u = createProductVector(x_bar_space_);
1122  const int N = this->N();
1123  for ( int i = 0; i < N; ++i ) {
1124  assign(
1125  x_bar_u->getNonconstVectorBlock(i).ptr(),
1126  *periodModels_[i]->getUpperBounds().get_x()
1127  );
1128  }
1129  upperBounds_.set_x(x_bar_u);
1130  }
1131 
1132  }
1133 
1134  // There can only be one set of nominal values for the non-period parameters
1135  // so just take them from the first period!
1136  for ( int l = 0; l < Np_; ++l ) {
1137  const int period_l = this->period_l(l);
1138  nominalValues_.set_p(l,periodNominalValues.get_p(period_l));
1139  lowerBounds_.set_p(l,periodLowerBounds.get_p(period_l));
1140  upperBounds_.set_p(l,periodUpperBounds.get_p(period_l));
1141  }
1142 
1143 }
1144 
1145 
1146 template<class Scalar>
1147 RCP<ProductVectorBase<Scalar> >
1148 DefaultMultiPeriodModelEvaluator<Scalar>::createProductVector(
1149  const RCP<const ProductVectorSpaceBase<Scalar> > &prodVecSpc
1150  )
1151 {
1152  return Teuchos::rcp_dynamic_cast<ProductVectorBase<Scalar> >(
1153  Thyra::createMember<Scalar>(prodVecSpc), true );
1154 }
1155 
1156 
1157 } // namespace Thyra
1158 
1159 
1160 #endif // THYRA_DEFAULT_MULTI_PERIOD_MODEL_EVALUATOR_HPP
Pure abstract base interface for evaluating a stateless &quot;model&quot; that can be mapped into a number of d...
Default base class for concrete model evaluators.
bool is_null(const boost::shared_ptr< T > &p)
Concrete aggregate class for all output arguments computable by a ModelEvaluator subclass object...
ModelEvaluatorBase::InArgs< Scalar > getLowerBounds() const
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
RCP< const Array< std::string > > get_p_names(int l) const
ArrayView< const std::string > get_g_names(int j) const
void reset_z(const Array< Array< RCP< const VectorBase< Scalar > > > > &z)
Reset z.
RCP< const VectorSpaceBase< Scalar > > get_p_space(int l) const
Composite subclass that takes a single ModelEvaluator object and represents it as a single aggregate ...
void initialize(const int N, const Array< RCP< ModelEvaluator< Scalar > > > &periodModels, const Array< int > &z_indexes, const Array< Array< RCP< const VectorBase< Scalar > > > > &z, const int g_index, const Array< Scalar > g_weights, const RCP< const ProductVectorSpaceBase< Scalar > > &x_bar_space=Teuchos::null, const RCP< const ProductVectorSpaceBase< Scalar > > &f_bar_space=Teuchos::null, const RCP< LinearOpWithSolveFactoryBase< Scalar > > &W_bar_factory=Teuchos::null)
Initialize.
ModelEvaluatorBase::InArgs< Scalar > createInArgs() const
Factory interface for creating LinearOpWithSolveBase objects from compatible LinearOpBase objects...
ModelEvaluatorBase::InArgs< Scalar > getUpperBounds() const
ModelEvaluatorBase::InArgs< Scalar > getNominalValues() const
RCP< const LinearOpWithSolveFactoryBase< Scalar > > get_W_factory() const
TypeTo implicit_cast(const TypeFrom &t)
Abstract interface for finite-dimensional dense vectors.
TEUCHOSCORE_LIB_DLL_EXPORT std::string toString(const EVerbosityLevel verbLevel)
RCP< const VectorSpaceBase< Scalar > > get_g_space(int j) const
void reportFinalPoint(const ModelEvaluatorBase::InArgs< Scalar > &finalPoint, const bool wasSolved)
Ignores the final point.
RCP< const VectorSpaceBase< Scalar > > get_f_space() const
std::vector< int >::const_iterator const_iterator
Base subclass for ModelEvaluator that defines some basic types.
RCP< const VectorSpaceBase< Scalar > > get_x_space() const
size_type size() const
RCP< PreconditionerBase< Scalar > > create_W_prec() const
#define TEUCHOS_TEST_FOR_EXCEPT(throw_exception_test)
Concrete aggregate class for all input arguments computable by a ModelEvaluator subclass object...