Thyra Version of the Day
Loading...
Searching...
No Matches
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
25namespace Thyra {
26
27
98template<class Scalar>
100 : virtual public ModelEvaluatorDefaultBase<Scalar>
101{
102public:
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,
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,
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
249private:
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
273private:
274
275 // //////////////////////////
276 // Private types
277
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_;
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
335template<class Scalar>
339
340
341template<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{
356 N, periodModels, z_indexes, z, g_index, g_weights,
357 x_bar_space, f_bar_space, W_bar_factory
358 );
359}
360
361
362template<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
449template<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
478template<class Scalar>
480{
481 return Np_;
482}
483
484
485template<class Scalar>
487{
488 return Ng_;
489}
490
491
492template<class Scalar>
495{
496 return x_bar_space_;
497}
498
499
500template<class Scalar>
503{
504 return f_bar_space_;
505}
506
507
508template<class Scalar>
511{
512 return periodModel_->get_p_space(period_l(l));
513}
514
515
516template<class Scalar>
519{
520 return periodModel_->get_p_names(period_l(l));
521}
522
523
524template<class Scalar>
527{
529 return periodModel_->get_g_space(g_index_);
530}
531
532
533template<class Scalar>
536{
537 return periodModel_->get_g_names(j);
538}
539
540
541template<class Scalar>
544{
545 return nominalValues_;
546}
547
548
549template<class Scalar>
552{
553 return lowerBounds_;
554}
555
556
557template<class Scalar>
560{
561 return upperBounds_;
562}
563
564
565template<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
582template<class Scalar>
588
589
590template<class Scalar>
593{
594 return W_bar_factory_;
595}
596
597
598template<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
612template<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
630template<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
639template<class Scalar>
640RCP<LinearOpBase<Scalar> >
641DefaultMultiPeriodModelEvaluator<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
648template<class Scalar>
649RCP<LinearOpBase<Scalar> >
650DefaultMultiPeriodModelEvaluator<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
657template<class Scalar>
658RCP<LinearOpBase<Scalar> >
659DefaultMultiPeriodModelEvaluator<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
666template<class Scalar>
667ModelEvaluatorBase::OutArgs<Scalar>
668DefaultMultiPeriodModelEvaluator<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
740template<class Scalar>
741void 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
1024template<class Scalar>
1025void 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();
1035 Array<int>::const_iterator
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
1069template<class Scalar>
1070void 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
1146template<class Scalar>
1147RCP<ProductVectorBase<Scalar> >
1148DefaultMultiPeriodModelEvaluator<Scalar>::createProductVector(
1149 const RCP<const ProductVectorSpaceBase<Scalar> > &prodVecSpc
1150 )
1151{
1153 Thyra::createMember<Scalar>(prodVecSpc), true );
1154}
1155
1156
1157} // namespace Thyra
1158
1159
1160#endif // THYRA_DEFAULT_MULTI_PERIOD_MODEL_EVALUATOR_HPP
size_type size() const
Composite subclass that takes a single ModelEvaluator object and represents it as a single aggregate ...
ArrayView< const std::string > get_g_names(int j) const
RCP< const VectorSpaceBase< Scalar > > get_x_space() const
ModelEvaluatorBase::InArgs< Scalar > getUpperBounds() const
RCP< const VectorSpaceBase< Scalar > > get_g_space(int j) const
RCP< PreconditionerBase< Scalar > > create_W_prec() const
ModelEvaluatorBase::InArgs< Scalar > getLowerBounds() const
RCP< const VectorSpaceBase< Scalar > > get_p_space(int l) const
RCP< const LinearOpWithSolveFactoryBase< Scalar > > get_W_factory() const
ModelEvaluatorBase::InArgs< Scalar > createInArgs() const
RCP< const Array< std::string > > get_p_names(int l) const
void reset_z(const Array< Array< RCP< const VectorBase< Scalar > > > > &z)
Reset z.
RCP< const VectorSpaceBase< Scalar > > get_f_space() const
void reportFinalPoint(const ModelEvaluatorBase::InArgs< Scalar > &finalPoint, const bool wasSolved)
Ignores the final point.
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 > getNominalValues() const
Factory interface for creating LinearOpWithSolveBase objects from compatible LinearOpBase objects.
Concrete aggregate class for all input arguments computable by a ModelEvaluator subclass object.
Concrete aggregate class for all output arguments computable by a ModelEvaluator subclass object.
Base subclass for ModelEvaluator that defines some basic types.
Default base class for concrete model evaluators.
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_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)
const char * toString(EConj conj)
Return a string name for a EOpTransp value. `*.
TypeTo implicit_cast(const TypeFrom &t)
T_To & dyn_cast(T_From &from)