Thyra Version of the Day
Loading...
Searching...
No Matches
Thyra_EpetraModelEvaluator.cpp
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#include "Thyra_EpetraModelEvaluator.hpp"
11#include "Thyra_LinearOpWithSolveFactoryHelpers.hpp"
13#include "Thyra_EpetraLinearOp.hpp"
14#include "Thyra_DetachedMultiVectorView.hpp"
15#include "Thyra_ModelEvaluatorDelegatorBase.hpp" // Gives verbose macros!
16#include "EpetraExt_ModelEvaluatorScalingTools.h"
17#include "Epetra_RowMatrix.h"
18#include "Teuchos_Time.hpp"
19#include "Teuchos_implicit_cast.hpp"
20#include "Teuchos_Assert.hpp"
21#include "Teuchos_StandardParameterEntryValidators.hpp"
22#include "Teuchos_VerboseObjectParameterListHelpers.hpp"
23
24
25namespace {
26
27
28const std::string StateFunctionScaling_name = "State Function Scaling";
31 Thyra::EpetraModelEvaluator::EStateFunctionScaling
32 >
33 >
34stateFunctionScalingValidator;
35const std::string StateFunctionScaling_default = "None";
36
37
38// Extract out the Epetra_RowMatrix from the set W in an Epetra OutArgs object
40get_Epetra_RowMatrix(
41 const EpetraExt::ModelEvaluator::OutArgs &epetraOutArgs
42 )
43{
44 using Teuchos::RCP;
45 const RCP<Epetra_Operator>
46 eW = epetraOutArgs.get_W();
47 const RCP<Epetra_RowMatrix>
50 is_null(ermW), std::logic_error,
51 "Thyra::EpetraModelEvaluator::evalModel(...): Error, if\n"
52 "scaling is turned on, the underlying Epetra_Operator created\n"
53 "an initialized by the underlying epetra model evaluator\n"
54 "\"" << epetraOutArgs.modelEvalDescription() << "\"\n"
55 "must support the Epetra_RowMatrix interface through a dynamic cast.\n"
56 "The concrete type " << Teuchos::typeName(*eW) << " does not support\n"
57 "Epetra_RowMatrix!"
58 );
59 return ermW;
60}
61
62
64create_and_assert_W(
65 const EpetraExt::ModelEvaluator &epetraModel
66 )
67{
68 using Teuchos::RCP;
69 RCP<Epetra_Operator>
70 eW = epetraModel.create_W();
72 is_null(eW), std::logic_error,
73 "Error, the call to create_W() returned null on the "
74 "EpetraExt::ModelEvaluator object "
75 "\"" << epetraModel.description() << "\". This may mean that "
76 "the underlying model does not support more than one copy of "
77 "W at one time!" );
78 return eW;
79}
80
81
82} // namespace
83
84
85namespace Thyra {
86
87
88// Constructors/initializers/accessors.
89
90
92 :nominalValuesAndBoundsAreUpdated_(false), stateFunctionScaling_(STATE_FUNC_SCALING_NONE),
93 currentInArgsOutArgs_(false), finalPointWasSolved_(false)
94{}
95
96
98 const RCP<const EpetraExt::ModelEvaluator> &epetraModel,
100 )
101 :nominalValuesAndBoundsAreUpdated_(false), stateFunctionScaling_(STATE_FUNC_SCALING_NONE),
102 currentInArgsOutArgs_(false), finalPointWasSolved_(false)
103{
104 initialize(epetraModel,W_factory);
105}
106
107
109 const RCP<const EpetraExt::ModelEvaluator> &epetraModel,
111 )
112{
114 //typedef ModelEvaluatorBase MEB; // unused
115 //
116 epetraModel_ = epetraModel;
117 //
118 W_factory_ = W_factory;
119 //
120 x_map_ = epetraModel_->get_x_map();
121 f_map_ = epetraModel_->get_f_map();
122 if (!is_null(x_map_)) {
123 x_space_ = create_VectorSpace(x_map_);
124 f_space_ = create_VectorSpace(f_map_);
125 }
126 //
127 EpetraExt::ModelEvaluator::InArgs inArgs = epetraModel_->createInArgs();
128 p_map_.resize(inArgs.Np()); p_space_.resize(inArgs.Np());
129 p_map_is_local_.resize(inArgs.Np(),false);
130 for( int l = 0; l < implicit_cast<int>(p_space_.size()); ++l ) {
132 p_map_l = ( p_map_[l] = epetraModel_->get_p_map(l) );
133#ifdef TEUCHOS_DEBUG
135 is_null(p_map_l), std::logic_error,
136 "Error, the the map p["<<l<<"] for the model \""
137 <<epetraModel->description()<<"\" can not be null!");
138#endif
139
140 p_map_is_local_[l] = !p_map_l->DistributedGlobal();
141 p_space_[l] = create_VectorSpace(p_map_l);
142 }
143 //
144 EpetraExt::ModelEvaluator::OutArgs outArgs = epetraModel_->createOutArgs();
145 g_map_.resize(outArgs.Ng()); g_space_.resize(outArgs.Ng());
146 g_map_is_local_.resize(outArgs.Ng(),false);
147 for( int j = 0; j < implicit_cast<int>(g_space_.size()); ++j ) {
149 g_map_j = ( g_map_[j] = epetraModel_->get_g_map(j) );
150 g_map_is_local_[j] = !g_map_j->DistributedGlobal();
151 g_space_[j] = create_VectorSpace( g_map_j );
152 }
153 //
154 epetraInArgsScaling_ = epetraModel_->createInArgs();
155 epetraOutArgsScaling_ = epetraModel_->createOutArgs();
156 nominalValuesAndBoundsAreUpdated_ = false;
157 finalPointWasSolved_ = false;
158 stateFunctionScalingVec_ = Teuchos::null; // Must set new scaling!
159 //
160 currentInArgsOutArgs_ = false;
161}
162
163
166{
167 return epetraModel_;
168}
169
170
172 const ModelEvaluatorBase::InArgs<double>& nominalValues
173 )
174{
175 nominalValues_.setArgs(nominalValues);
176 // Note: These must be the scaled values so we don't need to scale!
177}
178
179
181 const RCP<const Epetra_Vector> &stateVariableScalingVec
182 )
183{
184#ifdef TEUCHOS_DEBUG
185 typedef ModelEvaluatorBase MEB;
186 TEUCHOS_TEST_FOR_EXCEPT( !this->createInArgs().supports(MEB::IN_ARG_x) );
187#endif
188 stateVariableScalingVec_ = stateVariableScalingVec.assert_not_null();
189 invStateVariableScalingVec_ = Teuchos::null;
190 nominalValuesAndBoundsAreUpdated_ = false;
191}
192
193
196{
197 return stateVariableScalingVec_;
198}
199
200
203{
204 updateNominalValuesAndBounds();
205 return invStateVariableScalingVec_;
206}
207
208
210 const RCP<const Epetra_Vector> &stateFunctionScalingVec
211 )
212{
213 stateFunctionScalingVec_ = stateFunctionScalingVec;
214}
215
216
219{
220 return stateFunctionScalingVec_;
221}
222
223
227 )
228{
229 if(epetraModel) *epetraModel = epetraModel_;
230 if(W_factory) *W_factory = W_factory_;
231 epetraModel_ = Teuchos::null;
232 W_factory_ = Teuchos::null;
233 stateFunctionScalingVec_ = Teuchos::null;
234 stateVariableScalingVec_ = Teuchos::null;
235 invStateVariableScalingVec_ = Teuchos::null;
236 currentInArgsOutArgs_ = false;
237}
238
239
242{
243 return finalPoint_;
244}
245
246
248{
249 return finalPointWasSolved_;
250}
251
252
253// Public functions overridden from Teuchos::Describable
254
255
257{
258 std::ostringstream oss;
259 oss << "Thyra::EpetraModelEvaluator{";
260 oss << "epetraModel=";
261 if(epetraModel_.get())
262 oss << "\'"<<epetraModel_->description()<<"\'";
263 else
264 oss << "NULL";
265 oss << ",W_factory=";
266 if(W_factory_.get())
267 oss << "\'"<<W_factory_->description()<<"\'";
268 else
269 oss << "NULL";
270 oss << "}";
271 return oss.str();
272}
273
274
275// Overridden from Teuchos::ParameterListAcceptor
276
277
279 RCP<Teuchos::ParameterList> const& paramList
280 )
281{
282 TEUCHOS_TEST_FOR_EXCEPT(is_null(paramList));
283 paramList->validateParameters(*getValidParameters(),0); // Just validate my params
284 paramList_ = paramList;
285 const EStateFunctionScaling stateFunctionScaling_old = stateFunctionScaling_;
286 stateFunctionScaling_ = stateFunctionScalingValidator->getIntegralValue(
287 *paramList_, StateFunctionScaling_name, StateFunctionScaling_default
288 );
289 if( stateFunctionScaling_ != stateFunctionScaling_old )
290 stateFunctionScalingVec_ = Teuchos::null;
291 Teuchos::readVerboseObjectSublist(&*paramList_,this);
292#ifdef TEUCHOS_DEBUG
293 paramList_->validateParameters(*getValidParameters(),0);
294#endif // TEUCHOS_DEBUG
295}
296
297
300{
301 return paramList_;
302}
303
304
307{
308 RCP<Teuchos::ParameterList> _paramList = paramList_;
309 paramList_ = Teuchos::null;
310 return _paramList;
311}
312
313
316{
317 return paramList_;
318}
319
320
323{
324 using Teuchos::rcp;
326 using Teuchos::tuple;
327 using Teuchos::rcp_implicit_cast;
330 if(is_null(validPL)) {
333 stateFunctionScalingValidator = rcp(
334 new StringToIntegralParameterEntryValidator<EStateFunctionScaling>(
335 tuple<std::string>(
336 "None",
337 "Row Sum"
338 ),
339 tuple<std::string>(
340 "Do not scale the state function f(...) in this class.",
341
342 "Scale the state function f(...) and all its derivatives\n"
343 "using the row sum scaling from the initial Jacobian\n"
344 "W=d(f)/d(x). Note, this only works with Epetra_CrsMatrix\n"
345 "currently."
346 ),
347 tuple<EStateFunctionScaling>(
348 STATE_FUNC_SCALING_NONE,
349 STATE_FUNC_SCALING_ROW_SUM
350 ),
351 StateFunctionScaling_name
352 )
353 );
354 pl->set(StateFunctionScaling_name,StateFunctionScaling_default,
355 "Determines if and how the state function f(...) and all of its\n"
356 "derivatives are scaled. The scaling is done explicitly so there should\n"
357 "be no impact on the meaning of inner products or tolerances for\n"
358 "linear solves.",
359 rcp_implicit_cast<const PEV>(stateFunctionScalingValidator)
360 );
361 Teuchos::setupVerboseObjectSublist(&*pl);
362 validPL = pl;
363 }
364 return validPL;
365}
366
367
368// Overridden from ModelEvaulator.
369
370
372{
373 return p_space_.size();
374}
375
376
378{
379 return g_space_.size();
380}
381
382
385{
386 return x_space_;
387}
388
389
392{
393 return f_space_;
394}
395
396
399{
400#ifdef TEUCHOS_DEBUG
402#endif
403 return p_space_[l];
404}
405
406
409{
410#ifdef TEUCHOS_DEBUG
412#endif
413 return epetraModel_->get_p_names(l);
414}
415
416
419{
420 TEUCHOS_TEST_FOR_EXCEPT( ! ( 0 <= j && j < this->Ng() ) );
421 return g_space_[j];
422}
423
424
427{
428#ifdef TEUCHOS_DEBUG
430#endif
431 return epetraModel_->get_g_names(j);
432}
433
434
437{
438 updateNominalValuesAndBounds();
439 return nominalValues_;
440}
441
442
445{
446 updateNominalValuesAndBounds();
447 return lowerBounds_;
448}
449
450
453{
454 updateNominalValuesAndBounds();
455 return upperBounds_;
456}
457
458
461{
462 return this->create_epetra_W_op();
463}
464
465
471
472
475{
476 return W_factory_;
477}
478
479
481{
482 if (!currentInArgsOutArgs_)
483 updateInArgsOutArgs();
484 return prototypeInArgs_;
485}
486
487
489 const ModelEvaluatorBase::InArgs<double> &finalPoint,
490 const bool wasSolved
491 )
492{
493 finalPoint_ = this->createInArgs();
494 finalPoint_.setArgs(finalPoint);
495 finalPointWasSolved_ = wasSolved;
496}
497
498
499// Private functions overridden from ModelEvaulatorDefaultBase
500
501
503EpetraModelEvaluator::create_DfDp_op_impl(int /* l */) const
504{
507}
508
509
510RCP<LinearOpBase<double> >
511EpetraModelEvaluator::create_DgDx_dot_op_impl(int /* j */) const
512{
515}
516
517
518RCP<LinearOpBase<double> >
519EpetraModelEvaluator::create_DgDx_op_impl(int /* j */) const
520{
523}
524
525
526RCP<LinearOpBase<double> >
527EpetraModelEvaluator::create_DgDp_op_impl( int /* j */, int /* l */ ) const
528{
531}
532
533
534ModelEvaluatorBase::OutArgs<double>
535EpetraModelEvaluator::createOutArgsImpl() const
536{
537 if (!currentInArgsOutArgs_) {
538 updateInArgsOutArgs();
539 }
540 return prototypeOutArgs_;
541}
542
543
544void EpetraModelEvaluator::evalModelImpl(
545 const ModelEvaluatorBase::InArgs<double>& inArgs_in,
546 const ModelEvaluatorBase::OutArgs<double>& outArgs
547 ) const
548{
549
550 using Teuchos::rcp;
551 using Teuchos::rcp_const_cast;
552 using Teuchos::rcp_dynamic_cast;
553 using Teuchos::OSTab;
555 typedef EpetraExt::ModelEvaluator EME;
556
557 //
558 // A) Initial setup
559 //
560
561 // Make sure that we are fully initialized!
562 this->updateNominalValuesAndBounds();
563
564 // Make sure we grab the initial guess first!
565 InArgs<double> inArgs = this->getNominalValues();
566 // Now, copy the parameters from the input inArgs_in object to the inArgs
567 // object. Any input objects that are set in inArgs_in will overwrite those
568 // in inArgs that will already contain the nominal values. This will insure
569 // that all input parameters are set and those that are not set by the
570 // client will be at their nominal values (as defined by the underlying
571 // EpetraExt::ModelEvaluator object). The full set of Thyra input arguments
572 // must be set before these can be translated into Epetra input arguments.
573 inArgs.setArgs(inArgs_in);
574
575 // This is a special exception: see evalModel() in Thyra::ME
576 // documentation. If inArgs() supports x_dot but the evaluate call
577 // passes in a null value, then we need to make sure the null value
578 // gets passed on instead of the nominal value.
579 if (inArgs.supports(Thyra::ModelEvaluatorBase::IN_ARG_x_dot)) {
580 if (is_null(inArgs_in.get_x_dot()))
581 inArgs.set_x_dot(Teuchos::null);
582 }
583
584 // Print the header and the values of the inArgs and outArgs objects!
585 typedef double Scalar; // Needed for below macro!
586 THYRA_MODEL_EVALUATOR_DECORATOR_EVAL_MODEL_GEN_BEGIN(
587 "Thyra::EpetraModelEvaluator",inArgs,outArgs,Teuchos::null
588 );
589
590 // State function Scaling
591 const bool firstTimeStateFuncScaling
592 = (
593 stateFunctionScaling_ != STATE_FUNC_SCALING_NONE
594 && is_null(stateFunctionScalingVec_)
595 );
596
598 VOTSLOWSF W_factory_outputTempState(W_factory_,out,verbLevel);
599
600 Teuchos::Time timer("");
601
602 //
603 // B) Prepressess the InArgs and OutArgs in preparation to call
604 // the underlying EpetraExt::ModelEvaluator
605 //
606
607 //
608 // B.1) Translate InArgs from Thyra to Epetra objects
609 //
610
611 if (out.get() && includesVerbLevel(verbLevel,Teuchos::VERB_LOW))
612 *out << "\nSetting-up/creating input arguments ...\n";
613 timer.start(true);
614
615 // Unwrap input Thyra objects to get Epetra objects
616 EME::InArgs epetraScaledInArgs = epetraModel_->createInArgs();
617 convertInArgsFromThyraToEpetra( inArgs, &epetraScaledInArgs );
618
619 // Unscale the input Epetra objects which will be passed to the underlying
620 // EpetraExt::ModelEvaluator object.
621 EME::InArgs epetraInArgs = epetraModel_->createInArgs();
622 EpetraExt::unscaleModelVars(
623 epetraScaledInArgs, epetraInArgsScaling_, &epetraInArgs,
624 out.get(), verbLevel
625 );
626
627 timer.stop();
628 if (out.get() && includesVerbLevel(verbLevel,Teuchos::VERB_LOW))
629 OSTab(out).o() << "\nTime to setup InArgs = "<<timer.totalElapsedTime()<<" sec\n";
630
631 //
632 // B.2) Convert from Thyra to Epetra OutArgs
633 //
634
635 if (out.get() && includesVerbLevel(verbLevel,Teuchos::VERB_LOW))
636 *out << "\nSetting-up/creating output arguments ...\n";
637 timer.start(true);
638
639 // The unscaled Epetra OutArgs that will be passed to the
640 // underlying EpetraExt::ModelEvaluator object
641 EME::OutArgs epetraUnscaledOutArgs = epetraModel_->createOutArgs();
642
643 // Various objects that are needed later (see documentation in
644 // the function convertOutArgsFromThyraToEpetra(...)
645 RCP<LinearOpBase<double> > W_op;
646 RCP<EpetraLinearOp> efwdW;
647 RCP<Epetra_Operator> eW;
648
649 // Convert from Thyra to Epetra OutArgs and grap some of the intermediate
650 // objects accessed along the way that are needed later.
651 convertOutArgsFromThyraToEpetra(
652 outArgs,
653 &epetraUnscaledOutArgs,
654 &W_op, &efwdW, &eW
655 );
656
657 //
658 // B.3) Setup OutArgs to computing scaling if needed
659 //
660
661 if (firstTimeStateFuncScaling) {
662 preEvalScalingSetup(&epetraInArgs,&epetraUnscaledOutArgs,out,verbLevel);
663 }
664
665 timer.stop();
666 if (out.get() && includesVerbLevel(verbLevel,Teuchos::VERB_LOW))
667 OSTab(out).o()
668 << "\nTime to setup OutArgs = "
669 << timer.totalElapsedTime() <<" sec\n";
670
671 //
672 // C) Evaluate the underlying EpetraExt model to compute the Epetra outputs
673 //
674
675 if (out.get() && includesVerbLevel(verbLevel,Teuchos::VERB_LOW))
676 *out << "\nEvaluating the Epetra output functions ...\n";
677 timer.start(true);
678
679 epetraModel_->evalModel(epetraInArgs,epetraUnscaledOutArgs);
680
681 timer.stop();
682 if (out.get() && includesVerbLevel(verbLevel,Teuchos::VERB_LOW))
683 OSTab(out).o()
684 << "\nTime to evaluate Epetra output functions = "
685 << timer.totalElapsedTime() <<" sec\n";
686
687 //
688 // D) Postprocess the output objects
689 //
690
691 //
692 // D.1) Compute the scaling factors if needed
693 //
694
695 if (out.get() && includesVerbLevel(verbLevel,Teuchos::VERB_LOW))
696 *out << "\nCompute scale factors if needed ...\n";
697 timer.start(true);
698
699 if (firstTimeStateFuncScaling) {
700 postEvalScalingSetup(epetraUnscaledOutArgs,out,verbLevel);
701 }
702
703 timer.stop();
704 if (out.get() && includesVerbLevel(verbLevel,Teuchos::VERB_LOW))
705 OSTab(out).o()
706 << "\nTime to compute scale factors = "
707 << timer.totalElapsedTime() <<" sec\n";
708
709 //
710 // D.2) Scale the output Epetra objects
711 //
712
713 if (out.get() && includesVerbLevel(verbLevel,Teuchos::VERB_LOW))
714 *out << "\nScale the output objects ...\n";
715 timer.start(true);
716
717 EME::OutArgs epetraOutArgs = epetraModel_->createOutArgs();
718 bool allFuncsWhereScaled = false;
719 EpetraExt::scaleModelFuncs(
720 epetraUnscaledOutArgs, epetraInArgsScaling_, epetraOutArgsScaling_,
721 &epetraOutArgs, &allFuncsWhereScaled,
722 out.get(), verbLevel
723 );
724 // AGS: This test precluded use of matrix-free Operators (vs. RowMatrix)
725 if (stateFunctionScaling_ != STATE_FUNC_SCALING_NONE)
727 !allFuncsWhereScaled, std::logic_error,
728 "Error, we can not currently handle epetra output objects that could not be"
729 " scaled. Special code will have to be added to handle this (i.e. using"
730 " implicit diagonal and multiplied linear operators to implicitly do"
731 " the scaling."
732 );
733
734 timer.stop();
735 if (out.get() && includesVerbLevel(verbLevel,Teuchos::VERB_LOW))
736 OSTab(out).o()
737 << "\nTime to scale the output objects = "
738 << timer.totalElapsedTime() << " sec\n";
739
740 //
741 // D.3) Convert any Epetra objects to Thyra OutArgs objects that still need to
742 // be converted
743 //
744
745 if (out.get() && includesVerbLevel(verbLevel,Teuchos::VERB_LOW))
746 *out << "\nFinish processing and wrapping the output objects ...\n";
747 timer.start(true);
748
749 finishConvertingOutArgsFromEpetraToThyra(
750 epetraOutArgs, W_op, efwdW, eW,
751 outArgs
752 );
753
754 timer.stop();
755 if (out.get() && includesVerbLevel(verbLevel,Teuchos::VERB_LOW))
756 OSTab(out).o()
757 << "\nTime to finish processing and wrapping the output objects = "
758 << timer.totalElapsedTime() <<" sec\n";
759
760 //
761 // E) Print footer to end the function
762 //
763
764 THYRA_MODEL_EVALUATOR_DECORATOR_EVAL_MODEL_END();
765
766}
767
768
769// private
770
771
772void EpetraModelEvaluator::convertInArgsFromEpetraToThyra(
773 const EpetraExt::ModelEvaluator::InArgs &epetraInArgs,
774 ModelEvaluatorBase::InArgs<double> *inArgs
775 ) const
776{
777
779 typedef ModelEvaluatorBase MEB;
780
782
783 if(inArgs->supports(MEB::IN_ARG_x)) {
784 inArgs->set_x( create_Vector( epetraInArgs.get_x(), x_space_ ) );
785 }
786
787 if(inArgs->supports(MEB::IN_ARG_x_dot)) {
788 inArgs->set_x_dot( create_Vector( epetraInArgs.get_x_dot(), x_space_ ) );
789 }
790
791 if(inArgs->supports(MEB::IN_ARG_x_mp)) {
792 inArgs->set_x_mp( epetraInArgs.get_x_mp() );
793 }
794
795 if(inArgs->supports(MEB::IN_ARG_x_dot_mp)) {
796 inArgs->set_x_dot_mp( epetraInArgs.get_x_dot_mp() );
797 }
798
799 const int l_Np = inArgs->Np();
800 for( int l = 0; l < l_Np; ++l ) {
801 inArgs->set_p( l, create_Vector( epetraInArgs.get_p(l), p_space_[l] ) );
802 }
803 for( int l = 0; l < l_Np; ++l ) {
804 if(inArgs->supports(MEB::IN_ARG_p_mp, l))
805 inArgs->set_p_mp( l, epetraInArgs.get_p_mp(l) );
806 }
807
808 if(inArgs->supports(MEB::IN_ARG_t)) {
809 inArgs->set_t(epetraInArgs.get_t());
810 }
811
812}
813
814
815void EpetraModelEvaluator::convertInArgsFromThyraToEpetra(
816 const ModelEvaluatorBase::InArgs<double> &inArgs,
817 EpetraExt::ModelEvaluator::InArgs *epetraInArgs
818 ) const
819{
820
821 using Teuchos::rcp;
822 using Teuchos::rcp_const_cast;
823#ifdef HAVE_THYRA_ME_POLYNOMIAL
825#endif // HAVE_THYRA_ME_POLYNOMIAL
826
827
828 TEUCHOS_TEST_FOR_EXCEPT(0==epetraInArgs);
829
830 RCP<const VectorBase<double> > x_dot;
831 if( inArgs.supports(IN_ARG_x_dot) && (x_dot = inArgs.get_x_dot()).get() ) {
832 RCP<const Epetra_Vector> e_x_dot = get_Epetra_Vector(*x_map_,x_dot);
833 epetraInArgs->set_x_dot(e_x_dot);
834 }
835 RCP<const Stokhos::ProductEpetraVector > x_dot_mp;
836 if( inArgs.supports(IN_ARG_x_dot_mp) && (x_dot_mp = inArgs.get_x_dot_mp()).get() ) {
837 epetraInArgs->set_x_dot_mp(x_dot_mp);
838 }
839
840 RCP<const VectorBase<double> > x;
841 if( inArgs.supports(IN_ARG_x) && (x = inArgs.get_x()).get() ) {
842 RCP<const Epetra_Vector> e_x = get_Epetra_Vector(*x_map_,x);
843 epetraInArgs->set_x(e_x);
844 }
845 RCP<const Stokhos::ProductEpetraVector > x_mp;
846 if( inArgs.supports(IN_ARG_x_mp) && (x_mp = inArgs.get_x_mp()).get() ) {
847 epetraInArgs->set_x_mp(x_mp);
848 }
849
850 RCP<const VectorBase<double> > p_l;
851 for(int l = 0; l < inArgs.Np(); ++l ) {
852 p_l = inArgs.get_p(l);
853 if(p_l.get()) epetraInArgs->set_p(l,get_Epetra_Vector(*p_map_[l],p_l));
854 }
855 RCP<const Stokhos::ProductEpetraVector > p_mp_l;
856 for(int l = 0; l < inArgs.Np(); ++l ) {
857 if (inArgs.supports(IN_ARG_p_mp,l)) {
858 p_mp_l = inArgs.get_p_mp(l);
859 if(p_mp_l.get()) epetraInArgs->set_p_mp(l,p_mp_l);
860 }
861 }
862
863#ifdef HAVE_THYRA_ME_POLYNOMIAL
864
865 RCP<const Polynomial< VectorBase<double> > > x_dot_poly;
866 RCP<Epetra_Vector> epetra_ptr;
867 if(
868 inArgs.supports(IN_ARG_x_dot_poly)
869 && (x_dot_poly = inArgs.get_x_dot_poly()).get()
870 )
871 {
872 RCP<Polynomial<Epetra_Vector> > epetra_x_dot_poly =
873 rcp(new Polynomial<Epetra_Vector>(x_dot_poly->degree()));
874 for (unsigned int i=0; i<=x_dot_poly->degree(); i++) {
875 epetra_ptr = rcp_const_cast<Epetra_Vector>(
876 get_Epetra_Vector(*x_map_, x_dot_poly->getCoefficient(i)) );
877 epetra_x_dot_poly->setCoefficientPtr(i,epetra_ptr);
878 }
879 epetraInArgs->set_x_dot_poly(epetra_x_dot_poly);
880 }
881
882 RCP<const Polynomial< VectorBase<double> > > x_poly;
883 if(
884 inArgs.supports(IN_ARG_x_poly)
885 && (x_poly = inArgs.get_x_poly()).get()
886 )
887 {
888 RCP<Polynomial<Epetra_Vector> > epetra_x_poly =
889 rcp(new Polynomial<Epetra_Vector>(x_poly->degree()));
890 for (unsigned int i=0; i<=x_poly->degree(); i++) {
891 epetra_ptr = rcp_const_cast<Epetra_Vector>(
892 get_Epetra_Vector(*x_map_, x_poly->getCoefficient(i)) );
893 epetra_x_poly->setCoefficientPtr(i,epetra_ptr);
894 }
895 epetraInArgs->set_x_poly(epetra_x_poly);
896 }
897
898#endif // HAVE_THYRA_ME_POLYNOMIAL
899
900 if( inArgs.supports(IN_ARG_t) )
901 epetraInArgs->set_t(inArgs.get_t());
902
903 if( inArgs.supports(IN_ARG_alpha) )
904 epetraInArgs->set_alpha(inArgs.get_alpha());
905
906 if( inArgs.supports(IN_ARG_beta) )
907 epetraInArgs->set_beta(inArgs.get_beta());
908
909 if( inArgs.supports(IN_ARG_step_size) )
910 epetraInArgs->set_step_size(inArgs.get_step_size());
911
912 if( inArgs.supports(IN_ARG_stage_number) )
913 epetraInArgs->set_stage_number(inArgs.get_stage_number());
914}
915
916
917void EpetraModelEvaluator::convertOutArgsFromThyraToEpetra(
918 const ModelEvaluatorBase::OutArgs<double> &outArgs,
919 EpetraExt::ModelEvaluator::OutArgs *epetraUnscaledOutArgs_inout,
920 RCP<LinearOpBase<double> > *W_op_out,
921 RCP<EpetraLinearOp> *efwdW_out,
922 RCP<Epetra_Operator> *eW_out
923 ) const
924{
925
926 using Teuchos::rcp;
927 using Teuchos::rcp_const_cast;
928 using Teuchos::rcp_dynamic_cast;
929 using Teuchos::OSTab;
932 //typedef EpetraExt::ModelEvaluator EME; // unused
933
934 // Assert input
935#ifdef TEUCHOS_DEBUG
936 TEUCHOS_ASSERT(epetraUnscaledOutArgs_inout);
937 TEUCHOS_ASSERT(W_op_out);
938 TEUCHOS_ASSERT(efwdW_out);
939 TEUCHOS_ASSERT(eW_out);
940#endif
941
942 // Create easy to use references
943 EpetraExt::ModelEvaluator::OutArgs &epetraUnscaledOutArgs = *epetraUnscaledOutArgs_inout;
944 RCP<LinearOpBase<double> > &W_op = *W_op_out;
945 RCP<EpetraLinearOp> &efwdW = *efwdW_out;
946 RCP<Epetra_Operator> &eW = *eW_out;
947
948 // f
949 {
950 RCP<VectorBase<double> > f;
951 if( outArgs.supports(OUT_ARG_f) && (f = outArgs.get_f()).get() )
952 epetraUnscaledOutArgs.set_f(get_Epetra_Vector(*f_map_,f));
953 RCP<Stokhos::ProductEpetraVector > f_mp;
954 if( outArgs.supports(OUT_ARG_f_mp) && (f_mp = outArgs.get_f_mp()).get() )
955 epetraUnscaledOutArgs.set_f_mp(f_mp);
956 }
957
958 // g
959 {
960 RCP<VectorBase<double> > g_j;
961 for(int j = 0; j < outArgs.Ng(); ++j ) {
962 g_j = outArgs.get_g(j);
963 if(g_j.get()) epetraUnscaledOutArgs.set_g(j,get_Epetra_Vector(*g_map_[j],g_j));
964 }
965 RCP<Stokhos::ProductEpetraVector > g_mp_j;
966 for(int j = 0; j < outArgs.Ng(); ++j ) {
967 if (outArgs.supports(OUT_ARG_g_mp,j)) {
968 g_mp_j = outArgs.get_g_mp(j);
969 if(g_mp_j.get()) epetraUnscaledOutArgs.set_g_mp(j,g_mp_j);
970 }
971 }
972 }
973
974 // W_op
975 {
976 RCP<Stokhos::ProductEpetraOperator > W_mp;
977 if( outArgs.supports(OUT_ARG_W_mp) && (W_mp = outArgs.get_W_mp()).get() )
978 epetraUnscaledOutArgs.set_W_mp(W_mp);
979 }
980
981 // W_op
982 {
983
984 if (outArgs.supports(OUT_ARG_W_op) && nonnull(W_op = outArgs.get_W_op())) {
985 if (nonnull(W_op) && is_null(efwdW)) {
986 efwdW = rcp_const_cast<EpetraLinearOp>(
987 rcp_dynamic_cast<const EpetraLinearOp>(W_op, true));
988 }
989 }
990
991 if (nonnull(efwdW)) {
992 // By the time we get here, if we have an object in efwdW, then it
993 // should already be embeadded with an underlying Epetra_Operator object
994 // that was allocated by the EpetraExt::ModelEvaluator object.
995 // Therefore, we should just have to grab this object and be on our way.
996 eW = efwdW->epetra_op();
997 epetraUnscaledOutArgs.set_W(eW);
998 }
999
1000 // Note: The following derivative objects update in place!
1001
1002 }
1003
1004 // DfDp
1005 {
1006 Derivative<double> DfDp_l;
1007 for(int l = 0; l < outArgs.Np(); ++l ) {
1008 if( !outArgs.supports(OUT_ARG_DfDp,l).none()
1009 && !(DfDp_l = outArgs.get_DfDp(l)).isEmpty() )
1010 {
1011 epetraUnscaledOutArgs.set_DfDp(l,convert(DfDp_l,f_map_,p_map_[l]));
1012 }
1013 }
1014 MPDerivative DfDp_mp_l;
1015 for(int l = 0; l < outArgs.Np(); ++l ) {
1016 if( !outArgs.supports(OUT_ARG_DfDp_mp,l).none()
1017 && !(DfDp_mp_l = outArgs.get_DfDp_mp(l)).isEmpty() )
1018 {
1019 epetraUnscaledOutArgs.set_DfDp_mp(l,convert(DfDp_mp_l,f_map_,p_map_[l]));
1020 }
1021 }
1022 }
1023
1024 // DgDx_dot
1025 {
1026 Derivative<double> DgDx_dot_j;
1027 for(int j = 0; j < outArgs.Ng(); ++j ) {
1028 if( !outArgs.supports(OUT_ARG_DgDx_dot,j).none()
1029 && !(DgDx_dot_j = outArgs.get_DgDx_dot(j)).isEmpty() )
1030 {
1031 epetraUnscaledOutArgs.set_DgDx_dot(j,convert(DgDx_dot_j,g_map_[j],x_map_));
1032 }
1033 }
1034 MPDerivative DgDx_dot_mp_j;
1035 for(int j = 0; j < outArgs.Ng(); ++j ) {
1036 if( !outArgs.supports(OUT_ARG_DgDx_dot_mp,j).none()
1037 && !(DgDx_dot_mp_j = outArgs.get_DgDx_dot_mp(j)).isEmpty() )
1038 {
1039 epetraUnscaledOutArgs.set_DgDx_dot_mp(j,convert(DgDx_dot_mp_j,g_map_[j],x_map_));
1040 }
1041 }
1042 }
1043
1044 // DgDx
1045 {
1046 Derivative<double> DgDx_j;
1047 for(int j = 0; j < outArgs.Ng(); ++j ) {
1048 if( !outArgs.supports(OUT_ARG_DgDx,j).none()
1049 && !(DgDx_j = outArgs.get_DgDx(j)).isEmpty() )
1050 {
1051 epetraUnscaledOutArgs.set_DgDx(j,convert(DgDx_j,g_map_[j],x_map_));
1052 }
1053 }
1054 MPDerivative DgDx_mp_j;
1055 for(int j = 0; j < outArgs.Ng(); ++j ) {
1056 if( !outArgs.supports(OUT_ARG_DgDx_mp,j).none()
1057 && !(DgDx_mp_j = outArgs.get_DgDx_mp(j)).isEmpty() )
1058 {
1059 epetraUnscaledOutArgs.set_DgDx_mp(j,convert(DgDx_mp_j,g_map_[j],x_map_));
1060 }
1061 }
1062 }
1063
1064 // DgDp
1065 {
1066 DerivativeSupport DgDp_j_l_support;
1067 Derivative<double> DgDp_j_l;
1068 for (int j = 0; j < outArgs.Ng(); ++j ) {
1069 for (int l = 0; l < outArgs.Np(); ++l ) {
1070 if (!(DgDp_j_l_support = outArgs.supports(OUT_ARG_DgDp,j,l)).none()
1071 && !(DgDp_j_l = outArgs.get_DgDp(j,l)).isEmpty() )
1072 {
1073 epetraUnscaledOutArgs.set_DgDp(j,l,convert(DgDp_j_l,g_map_[j],p_map_[l]));
1074 }
1075 }
1076 }
1077 DerivativeSupport DgDp_mp_j_l_support;
1078 MPDerivative DgDp_mp_j_l;
1079 for (int j = 0; j < outArgs.Ng(); ++j ) {
1080 for (int l = 0; l < outArgs.Np(); ++l ) {
1081 if (!(DgDp_mp_j_l_support = outArgs.supports(OUT_ARG_DgDp_mp,j,l)).none()
1082 && !(DgDp_mp_j_l = outArgs.get_DgDp_mp(j,l)).isEmpty() )
1083 {
1084 epetraUnscaledOutArgs.set_DgDp_mp(j,l,convert(DgDp_mp_j_l,g_map_[j],p_map_[l]));
1085 }
1086 }
1087 }
1088 }
1089
1090#ifdef HAVE_THYRA_ME_POLYNOMIAL
1091
1092 // f_poly
1093 RCP<const Teuchos::Polynomial< VectorBase<double> > > f_poly;
1094 if( outArgs.supports(OUT_ARG_f_poly) && (f_poly = outArgs.get_f_poly()).get() )
1095 {
1096 RCP<Teuchos::Polynomial<Epetra_Vector> > epetra_f_poly =
1097 Teuchos::rcp(new Teuchos::Polynomial<Epetra_Vector>(f_poly->degree()));
1098 for (unsigned int i=0; i<=f_poly->degree(); i++) {
1099 RCP<Epetra_Vector> epetra_ptr
1101 f_poly->getCoefficient(i)));
1102 epetra_f_poly->setCoefficientPtr(i,epetra_ptr);
1103 }
1104 epetraUnscaledOutArgs.set_f_poly(epetra_f_poly);
1105 }
1106
1107#endif // HAVE_THYRA_ME_POLYNOMIAL
1108
1109}
1110
1111
1112void EpetraModelEvaluator::preEvalScalingSetup(
1113 EpetraExt::ModelEvaluator::InArgs *epetraInArgs_inout,
1114 EpetraExt::ModelEvaluator::OutArgs *epetraUnscaledOutArgs_inout,
1115 const RCP<Teuchos::FancyOStream> &out,
1116 const Teuchos::EVerbosityLevel verbLevel
1117 ) const
1118{
1119
1120 typedef EpetraExt::ModelEvaluator EME;
1121
1122#ifdef TEUCHOS_DEBUG
1123 TEUCHOS_ASSERT(epetraInArgs_inout);
1124 TEUCHOS_ASSERT(epetraUnscaledOutArgs_inout);
1125#endif
1126
1127 EpetraExt::ModelEvaluator::InArgs
1128 &epetraInArgs = *epetraInArgs_inout;
1129 EpetraExt::ModelEvaluator::OutArgs
1130 &epetraUnscaledOutArgs = *epetraUnscaledOutArgs_inout;
1131
1132 if (
1133 ( stateFunctionScaling_ == STATE_FUNC_SCALING_ROW_SUM )
1134 &&
1135 (
1136 epetraUnscaledOutArgs.supports(EME::OUT_ARG_f)
1137 &&
1138 epetraUnscaledOutArgs.funcOrDerivesAreSet(EME::OUT_ARG_f)
1139 )
1140 &&
1141 (
1142 epetraUnscaledOutArgs.supports(EME::OUT_ARG_W)
1143 &&
1144 is_null(epetraUnscaledOutArgs.get_W())
1145 )
1146 )
1147 {
1148 // This is the first pass through with scaling turned on and the client
1149 // turned on automatic scaling but did not ask for W. We must compute W
1150 // in order to compute the scale factors so we must allocate a temporary W
1151 // just to compute the scale factors and then throw it away. If the
1152 // client wants to evaluate W at the same point, then it should have
1153 // passed W in but that is not our problem here. The ModelEvaluator
1154 // relies on the client to set up the calls to allow for efficient
1155 // evaluation.
1156
1157 if(out.get() && verbLevel >= Teuchos::VERB_LOW)
1158 *out
1159 << "\nCreating a temporary Epetra W to compute scale factors"
1160 << " for f(...) ...\n";
1161 epetraUnscaledOutArgs.set_W(create_and_assert_W(*epetraModel_));
1162 if( epetraInArgs.supports(EME::IN_ARG_beta) )
1163 epetraInArgs.set_beta(1.0);
1164 if( epetraInArgs.supports(EME::IN_ARG_alpha) )
1165 epetraInArgs.set_alpha(0.0);
1166 if( epetraInArgs.supports(EME::IN_ARG_step_size) )
1167 epetraInArgs.set_step_size(0.0);
1168 if( epetraInArgs.supports(EME::IN_ARG_stage_number) )
1169 epetraInArgs.set_stage_number(1.0);
1170 }
1171
1172}
1173
1174
1175void EpetraModelEvaluator::postEvalScalingSetup(
1176 const EpetraExt::ModelEvaluator::OutArgs &epetraUnscaledOutArgs,
1177 const RCP<Teuchos::FancyOStream> &out,
1178 const Teuchos::EVerbosityLevel verbLevel
1179 ) const
1180{
1181
1182 using Teuchos::OSTab;
1183 using Teuchos::rcp;
1184 using Teuchos::rcp_const_cast;
1186
1187 // Compute the scale factors for the state function f(...)
1188 switch(stateFunctionScaling_) {
1189
1190 case STATE_FUNC_SCALING_ROW_SUM: {
1191
1192 // Compute the inverse row-sum scaling from W
1193
1194 const RCP<Epetra_RowMatrix>
1195 ermW = get_Epetra_RowMatrix(epetraUnscaledOutArgs);
1196 // Note: Above, we get the Epetra W object directly from the Epetra
1197 // OutArgs object since this might be a temporary matrix just to
1198 // compute scaling factors. In this case, the stack funtion variable
1199 // eW might be empty!
1200
1201 RCP<Epetra_Vector>
1202 invRowSums = rcp(new Epetra_Vector(ermW->OperatorRangeMap()));
1203 // Above: From the documentation is seems that the RangeMap should be
1204 // okay but who knows for sure!
1205
1206 ermW->InvRowSums(*invRowSums);
1207
1208 if (out.get() && includesVerbLevel(verbLevel,Teuchos::VERB_LOW)) {
1209 *out
1210 << "\nComputed inverse row sum scaling from W that"
1211 " will be used to scale f(...) and its derivatives:\n";
1212 double minVal = 0, maxVal = 0, avgVal = 0;
1213 invRowSums->MinValue(&minVal);
1214 invRowSums->MaxValue(&maxVal);
1215 invRowSums->MeanValue(&avgVal);
1216 OSTab tab(out);
1217 *out
1218 << "min(invRowSums) = " << minVal << "\n"
1219 << "max(invRowSums) = " << maxVal << "\n"
1220 << "avg(invRowSums) = " << avgVal << "\n";
1221 }
1222
1223 stateFunctionScalingVec_ = invRowSums;
1224
1225 break;
1226
1227 }
1228
1229 default:
1230 TEUCHOS_TEST_FOR_EXCEPT("Should never get here!");
1231
1232 }
1233
1234 epetraOutArgsScaling_ = epetraModel_->createOutArgs();
1235
1236 epetraOutArgsScaling_.set_f(
1237 rcp_const_cast<Epetra_Vector>(stateFunctionScalingVec_) );
1238
1239}
1240
1241
1242void EpetraModelEvaluator::finishConvertingOutArgsFromEpetraToThyra(
1243 const EpetraExt::ModelEvaluator::OutArgs &/* epetraOutArgs */,
1244 RCP<LinearOpBase<double> > &W_op,
1245 RCP<EpetraLinearOp> &efwdW,
1246 RCP<Epetra_Operator> &/* eW */,
1247 const ModelEvaluatorBase::OutArgs<double> &/* outArgs */
1248 ) const
1249{
1250
1251 using Teuchos::rcp_dynamic_cast;
1252 //typedef EpetraExt::ModelEvaluator EME; // unused
1253
1254 if (nonnull(efwdW)) {
1255 efwdW->setFullyInitialized(true);
1256 // NOTE: Above will directly update W_op also if W.get()==NULL!
1257 }
1258
1259 if (nonnull(W_op)) {
1260 if (W_op.shares_resource(efwdW)) {
1261 // W_op was already updated above since *efwdW is the same object as *W_op
1262 }
1263 else {
1264 rcp_dynamic_cast<EpetraLinearOp>(W_op, true)->setFullyInitialized(true);
1265 }
1266 }
1267
1268}
1269
1270
1271void EpetraModelEvaluator::updateNominalValuesAndBounds() const
1272{
1273
1274 using Teuchos::rcp;
1276 //typedef ModelEvaluatorBase MEB; // unused
1277 typedef EpetraExt::ModelEvaluator EME;
1278
1279 if( !nominalValuesAndBoundsAreUpdated_ ) {
1280
1281 // Gather the nominal values and bounds into Epetra InArgs objects
1282
1283 EME::InArgs epetraOrigNominalValues;
1284 EpetraExt::gatherModelNominalValues(
1285 *epetraModel_, &epetraOrigNominalValues );
1286
1287 EME::InArgs epetraOrigLowerBounds;
1288 EME::InArgs epetraOrigUpperBounds;
1289 EpetraExt::gatherModelBounds(
1290 *epetraModel_, &epetraOrigLowerBounds, &epetraOrigUpperBounds );
1291
1292 // Set up Epetra InArgs scaling object
1293
1294 epetraInArgsScaling_ = epetraModel_->createInArgs();
1295
1296 if( !is_null(stateVariableScalingVec_) ) {
1297 invStateVariableScalingVec_
1298 = EpetraExt::createInverseModelScalingVector(stateVariableScalingVec_);
1299 if( epetraOrigNominalValues.supports(EME::IN_ARG_x_dot) ) {
1300 epetraInArgsScaling_.set_x_dot(invStateVariableScalingVec_);
1301 }
1302 if( epetraOrigNominalValues.supports(EME::IN_ARG_x) ) {
1303 epetraInArgsScaling_.set_x(invStateVariableScalingVec_);
1304 }
1305 }
1306
1307 // Scale the original variables and bounds
1308
1309 EME::InArgs epetraScaledNominalValues = epetraModel_->createInArgs();
1310 EpetraExt::scaleModelVars(
1311 epetraOrigNominalValues, epetraInArgsScaling_, &epetraScaledNominalValues
1312 );
1313
1314 EME::InArgs epetraScaledLowerBounds = epetraModel_->createInArgs();
1315 EME::InArgs epetraScaledUpperBounds = epetraModel_->createInArgs();
1316 EpetraExt::scaleModelBounds(
1317 epetraOrigLowerBounds, epetraOrigUpperBounds, epetraModel_->getInfBound(),
1318 epetraInArgsScaling_,
1319 &epetraScaledLowerBounds, &epetraScaledUpperBounds
1320 );
1321
1322 // Wrap the scaled epetra InArgs objects as Thyra InArgs objects!
1323
1324 nominalValues_ = this->createInArgs();
1325 lowerBounds_ = this->createInArgs();
1326 upperBounds_ = this->createInArgs();
1327 convertInArgsFromEpetraToThyra(epetraScaledNominalValues, &nominalValues_);
1328 convertInArgsFromEpetraToThyra(epetraScaledLowerBounds, &lowerBounds_);
1329 convertInArgsFromEpetraToThyra(epetraScaledUpperBounds, &upperBounds_);
1330
1331 nominalValuesAndBoundsAreUpdated_ = true;
1332
1333 }
1334 else {
1335
1336 // The nominal values and bounds should already be updated an should have
1337 // the currect scaling!
1338
1339 }
1340
1341}
1342
1343
1344void EpetraModelEvaluator::updateInArgsOutArgs() const
1345{
1346
1347 typedef EpetraExt::ModelEvaluator EME;
1348
1349 const EpetraExt::ModelEvaluator &epetraModel = *epetraModel_;
1350 EME::InArgs epetraInArgs = epetraModel.createInArgs();
1351 EME::OutArgs epetraOutArgs = epetraModel.createOutArgs();
1352 const int l_Np = epetraOutArgs.Np();
1353 const int l_Ng = epetraOutArgs.Ng();
1354
1355 //
1356 // InArgs
1357 //
1358
1359 InArgsSetup<double> inArgs;
1360 inArgs.setModelEvalDescription(this->description());
1361 inArgs.set_Np(epetraInArgs.Np());
1362 inArgs.setSupports(IN_ARG_x_dot, epetraInArgs.supports(EME::IN_ARG_x_dot));
1363 inArgs.setSupports(IN_ARG_x, epetraInArgs.supports(EME::IN_ARG_x));
1364 inArgs.setSupports(IN_ARG_x_dot_mp, epetraInArgs.supports(EME::IN_ARG_x_dot_mp));
1365 inArgs.setSupports(IN_ARG_x_mp, epetraInArgs.supports(EME::IN_ARG_x_mp));
1366#ifdef HAVE_THYRA_ME_POLYNOMIAL
1367 inArgs.setSupports(IN_ARG_x_dot_poly,
1368 epetraInArgs.supports(EME::IN_ARG_x_dot_poly));
1369 inArgs.setSupports(IN_ARG_x_poly, epetraInArgs.supports(EME::IN_ARG_x_poly));
1370#endif // HAVE_THYRA_ME_POLYNOMIAL
1371 inArgs.setSupports(IN_ARG_t, epetraInArgs.supports(EME::IN_ARG_t));
1372 inArgs.setSupports(IN_ARG_alpha, epetraInArgs.supports(EME::IN_ARG_alpha));
1373 inArgs.setSupports(IN_ARG_beta, epetraInArgs.supports(EME::IN_ARG_beta));
1374 inArgs.setSupports(IN_ARG_step_size, epetraInArgs.supports(EME::IN_ARG_step_size));
1375 inArgs.setSupports(IN_ARG_stage_number, epetraInArgs.supports(EME::IN_ARG_stage_number));
1376 for(int l=0; l<l_Np; ++l) {
1377 inArgs.setSupports(IN_ARG_p_mp, l, epetraInArgs.supports(EME::IN_ARG_p_mp, l));
1378 }
1379 prototypeInArgs_ = inArgs;
1380
1381 //
1382 // OutArgs
1383 //
1384
1385 OutArgsSetup<double> outArgs;
1386 outArgs.setModelEvalDescription(this->description());
1387 outArgs.set_Np_Ng(l_Np, l_Ng);
1388 // f
1389 outArgs.setSupports(OUT_ARG_f, epetraOutArgs.supports(EME::OUT_ARG_f));
1390 outArgs.setSupports(OUT_ARG_f_mp, epetraOutArgs.supports(EME::OUT_ARG_f_mp));
1391 if (outArgs.supports(OUT_ARG_f)) {
1392 // W_op
1393 outArgs.setSupports(OUT_ARG_W_op, epetraOutArgs.supports(EME::OUT_ARG_W));
1394 outArgs.set_W_properties(convert(epetraOutArgs.get_W_properties()));
1395 // DfDp
1396 for(int l=0; l<l_Np; ++l) {
1397 outArgs.setSupports(OUT_ARG_DfDp, l,
1398 convert(epetraOutArgs.supports(EME::OUT_ARG_DfDp, l)));
1399 if(!outArgs.supports(OUT_ARG_DfDp, l).none())
1400 outArgs.set_DfDp_properties(l,
1401 convert(epetraOutArgs.get_DfDp_properties(l)));
1402 if (outArgs.supports(OUT_ARG_f_mp))
1403 {
1404 outArgs.setSupports(OUT_ARG_DfDp_mp, l,
1405 convert(epetraOutArgs.supports(EME::OUT_ARG_DfDp_mp, l)));
1406 if(!outArgs.supports(OUT_ARG_DfDp_mp, l).none())
1407 outArgs.set_DfDp_mp_properties(l,
1408 convert(epetraOutArgs.get_DfDp_mp_properties(l)));
1409 }
1410 }
1411 }
1412 // DgDx_dot and DgDx
1413 for(int j=0; j<l_Ng; ++j) {
1414 if (inArgs.supports(IN_ARG_x_dot))
1415 outArgs.setSupports(OUT_ARG_DgDx_dot, j,
1416 convert(epetraOutArgs.supports(EME::OUT_ARG_DgDx_dot, j)));
1417 if(!outArgs.supports(OUT_ARG_DgDx_dot, j).none())
1418 outArgs.set_DgDx_dot_properties(j,
1419 convert(epetraOutArgs.get_DgDx_dot_properties(j)));
1420 if (inArgs.supports(IN_ARG_x))
1421 outArgs.setSupports(OUT_ARG_DgDx, j,
1422 convert(epetraOutArgs.supports(EME::OUT_ARG_DgDx, j)));
1423 if(!outArgs.supports(OUT_ARG_DgDx, j).none())
1424 outArgs.set_DgDx_properties(j,
1425 convert(epetraOutArgs.get_DgDx_properties(j)));
1426 if (inArgs.supports(IN_ARG_x_dot_mp))
1427 outArgs.setSupports(OUT_ARG_DgDx_dot_mp, j,
1428 convert(epetraOutArgs.supports(EME::OUT_ARG_DgDx_dot_mp, j)));
1429 if(!outArgs.supports(OUT_ARG_DgDx_dot_mp, j).none())
1430 outArgs.set_DgDx_dot_mp_properties(j,
1431 convert(epetraOutArgs.get_DgDx_dot_mp_properties(j)));
1432 if (inArgs.supports(IN_ARG_x_mp))
1433 outArgs.setSupports(OUT_ARG_DgDx_mp, j,
1434 convert(epetraOutArgs.supports(EME::OUT_ARG_DgDx_mp, j)));
1435 if(!outArgs.supports(OUT_ARG_DgDx_mp, j).none())
1436 outArgs.set_DgDx_mp_properties(j,
1437 convert(epetraOutArgs.get_DgDx_mp_properties(j)));
1438 }
1439 // DgDp
1440 for(int j=0; j < l_Ng; ++j) for(int l=0; l < l_Np; ++l) {
1441 const EME::DerivativeSupport epetra_DgDp_j_l_support =
1442 epetraOutArgs.supports(EME::OUT_ARG_DgDp, j, l);
1443 outArgs.setSupports(OUT_ARG_DgDp, j, l,
1444 convert(epetra_DgDp_j_l_support));
1445 if(!outArgs.supports(OUT_ARG_DgDp, j, l).none())
1446 outArgs.set_DgDp_properties(j, l,
1447 convert(epetraOutArgs.get_DgDp_properties(j, l)));
1448 const EME::DerivativeSupport epetra_DgDp_mp_j_l_support =
1449 epetraOutArgs.supports(EME::OUT_ARG_DgDp_mp, j, l);
1450 outArgs.setSupports(OUT_ARG_DgDp_mp, j, l,
1451 convert(epetra_DgDp_mp_j_l_support));
1452 if(!outArgs.supports(OUT_ARG_DgDp_mp, j, l).none())
1453 outArgs.set_DgDp_mp_properties(j, l,
1454 convert(epetraOutArgs.get_DgDp_mp_properties(j, l)));
1455 }
1456 for(int j=0; j<l_Ng; ++j) {
1457 outArgs.setSupports(OUT_ARG_g_mp, j, epetraOutArgs.supports(EME::OUT_ARG_g_mp, j));
1458 }
1459#ifdef HAVE_THYRA_ME_POLYNOMIAL
1460 outArgs.setSupports(OUT_ARG_f_poly,
1461 epetraOutArgs.supports(EME::OUT_ARG_f_poly));
1462#endif // HAVE_THYRA_ME_POLYNOMIAL
1463 prototypeOutArgs_ = outArgs;
1464
1465 // We are current!
1466 currentInArgsOutArgs_ = true;
1467
1468}
1469
1470
1471RCP<EpetraLinearOp>
1472EpetraModelEvaluator::create_epetra_W_op() const
1473{
1474 return Thyra::partialNonconstEpetraLinearOp(
1475 this->get_f_space(), this->get_x_space(),
1476 create_and_assert_W(*epetraModel_)
1477 );
1478}
1479
1480
1481} // namespace Thyra
1482
1483
1484//
1485// Non-member utility functions
1486//
1487
1488
1490Thyra::epetraModelEvaluator(
1491 const RCP<const EpetraExt::ModelEvaluator> &epetraModel,
1492 const RCP<LinearOpWithSolveFactoryBase<double> > &W_factory
1493 )
1494{
1495 return Teuchos::rcp(new EpetraModelEvaluator(epetraModel,W_factory));
1496}
1497
1498
1500Thyra::convert(
1501 const EpetraExt::ModelEvaluator::EDerivativeMultiVectorOrientation &mvOrientation
1502 )
1503{
1504 switch(mvOrientation) {
1505 case EpetraExt::ModelEvaluator::DERIV_MV_BY_COL :
1506 return ModelEvaluatorBase::DERIV_MV_BY_COL;
1507 case EpetraExt::ModelEvaluator::DERIV_TRANS_MV_BY_ROW :
1508 return ModelEvaluatorBase::DERIV_TRANS_MV_BY_ROW;
1509 default:
1511 }
1512 TEUCHOS_UNREACHABLE_RETURN(ModelEvaluatorBase::DERIV_MV_BY_COL);
1513}
1514
1515
1516EpetraExt::ModelEvaluator::EDerivativeMultiVectorOrientation
1517Thyra::convert(
1518 const ModelEvaluatorBase::EDerivativeMultiVectorOrientation &mvOrientation
1519 )
1520{
1521 switch(mvOrientation) {
1522 case ModelEvaluatorBase::DERIV_MV_BY_COL :
1523 return EpetraExt::ModelEvaluator::DERIV_MV_BY_COL;
1524 case ModelEvaluatorBase::DERIV_TRANS_MV_BY_ROW :
1525 return EpetraExt::ModelEvaluator::DERIV_TRANS_MV_BY_ROW;
1526 default:
1528 }
1529 TEUCHOS_UNREACHABLE_RETURN(EpetraExt::ModelEvaluator::DERIV_MV_BY_COL);
1530}
1531
1532
1534Thyra::convert(
1535 const EpetraExt::ModelEvaluator::DerivativeProperties &derivativeProperties
1536 )
1537{
1538 ModelEvaluatorBase::EDerivativeLinearity linearity;
1539 switch(derivativeProperties.linearity) {
1540 case EpetraExt::ModelEvaluator::DERIV_LINEARITY_UNKNOWN:
1541 linearity = ModelEvaluatorBase::DERIV_LINEARITY_UNKNOWN;
1542 break;
1543 case EpetraExt::ModelEvaluator::DERIV_LINEARITY_CONST:
1544 linearity = ModelEvaluatorBase::DERIV_LINEARITY_CONST;
1545 break;
1546 case EpetraExt::ModelEvaluator::DERIV_LINEARITY_NONCONST:
1547 linearity = ModelEvaluatorBase::DERIV_LINEARITY_NONCONST;
1548 break;
1549 default:
1551 }
1552 ModelEvaluatorBase::ERankStatus rank;
1553 switch(derivativeProperties.rank) {
1554 case EpetraExt::ModelEvaluator::DERIV_RANK_UNKNOWN:
1555 rank = ModelEvaluatorBase::DERIV_RANK_UNKNOWN;
1556 break;
1557 case EpetraExt::ModelEvaluator::DERIV_RANK_FULL:
1558 rank = ModelEvaluatorBase::DERIV_RANK_FULL;
1559 break;
1560 case EpetraExt::ModelEvaluator::DERIV_RANK_DEFICIENT:
1561 rank = ModelEvaluatorBase::DERIV_RANK_DEFICIENT;
1562 break;
1563 default:
1565 }
1566 return ModelEvaluatorBase::DerivativeProperties(
1567 linearity,rank,derivativeProperties.supportsAdjoint);
1568}
1569
1570
1572Thyra::convert(
1573 const EpetraExt::ModelEvaluator::DerivativeSupport &derivativeSupport
1574 )
1575{
1576 ModelEvaluatorBase::DerivativeSupport ds;
1577 if(derivativeSupport.supports(EpetraExt::ModelEvaluator::DERIV_LINEAR_OP))
1578 ds.plus(ModelEvaluatorBase::DERIV_LINEAR_OP);
1579 if(derivativeSupport.supports(EpetraExt::ModelEvaluator::DERIV_MV_BY_COL))
1580 ds.plus(ModelEvaluatorBase::DERIV_MV_BY_COL);
1581 if(derivativeSupport.supports(EpetraExt::ModelEvaluator::DERIV_TRANS_MV_BY_ROW))
1582 ds.plus(ModelEvaluatorBase::DERIV_TRANS_MV_BY_ROW);
1583 return ds;
1584}
1585
1586
1587EpetraExt::ModelEvaluator::Derivative
1588Thyra::convert(
1589 const ModelEvaluatorBase::Derivative<double> &derivative,
1590 const RCP<const Epetra_Map> &fnc_map,
1591 const RCP<const Epetra_Map> &var_map
1592 )
1593{
1594 typedef ModelEvaluatorBase MEB;
1595 if(derivative.getLinearOp().get()) {
1596 return EpetraExt::ModelEvaluator::Derivative(
1598 Teuchos::dyn_cast<const EpetraLinearOp>(*derivative.getLinearOp()).epetra_op()
1599 )
1600 );
1601 }
1602 else if(derivative.getDerivativeMultiVector().getMultiVector().get()) {
1603 return EpetraExt::ModelEvaluator::Derivative(
1604 EpetraExt::ModelEvaluator::DerivativeMultiVector(
1606 ( derivative.getDerivativeMultiVector().getOrientation() == MEB::DERIV_MV_BY_COL
1607 ? *fnc_map
1608 : *var_map
1609 )
1610 ,derivative.getDerivativeMultiVector().getMultiVector()
1611 )
1612 ,convert(derivative.getDerivativeMultiVector().getOrientation())
1613 )
1614 );
1615 }
1616 return EpetraExt::ModelEvaluator::Derivative();
1617}
1618EpetraExt::ModelEvaluator::MPDerivative
1619Thyra::convert(
1620 const ModelEvaluatorBase::MPDerivative &derivative,
1621 const RCP<const Epetra_Map> &/* fnc_map */,
1622 const RCP<const Epetra_Map> &/* var_map */
1623 )
1624{
1625 //typedef ModelEvaluatorBase MEB; // unused
1626 if(derivative.getLinearOp().get()) {
1627 return EpetraExt::ModelEvaluator::MPDerivative(
1628 derivative.getLinearOp()
1629 );
1630 }
1631 else if(derivative.getDerivativeMultiVector().getMultiVector().get()) {
1632 return EpetraExt::ModelEvaluator::MPDerivative(
1633 EpetraExt::ModelEvaluator::MPDerivativeMultiVector(
1634 derivative.getDerivativeMultiVector().getMultiVector()
1635 ,convert(derivative.getDerivativeMultiVector().getOrientation())
1636 )
1637 );
1638 }
1639 return EpetraExt::ModelEvaluator::MPDerivative();
1640}
size_type size() const
void resize(size_type new_size, const value_type &x=value_type())
const RCP< T > & assert_not_null() const
T * get() const
RCP< Teuchos::ParameterList > unsetParameterList()
RCP< Teuchos::ParameterList > getNonconstParameterList()
void setStateFunctionScalingVec(const RCP< const Epetra_Vector > &stateFunctionScalingVec)
Set the state function scaling vector s_f (see above).
RCP< const Epetra_Vector > getStateFunctionScalingVec() const
Get the state function scaling vector s_f (see above).
void initialize(const RCP< const EpetraExt::ModelEvaluator > &epetraModel, const RCP< LinearOpWithSolveFactoryBase< double > > &W_factory)
RCP< const VectorSpaceBase< double > > get_f_space() const
void setStateVariableScalingVec(const RCP< const Epetra_Vector > &stateVariableScalingVec)
Set the state variable scaling vector s_x (see above).
RCP< LinearOpBase< double > > create_W_op() const
ModelEvaluatorBase::InArgs< double > getUpperBounds() const
void setNominalValues(const ModelEvaluatorBase::InArgs< double > &nominalValues)
Set the nominal values.
RCP< PreconditionerBase< double > > create_W_prec() const
Returns null currently.
RCP< const LinearOpWithSolveFactoryBase< double > > get_W_factory() const
ModelEvaluatorBase::InArgs< double > getNominalValues() const
RCP< const Teuchos::ParameterList > getParameterList() const
void reportFinalPoint(const ModelEvaluatorBase::InArgs< double > &finalPoint, const bool wasSolved)
ModelEvaluatorBase::InArgs< double > createInArgs() const
void setParameterList(RCP< Teuchos::ParameterList > const &paramList)
RCP< const VectorSpaceBase< double > > get_g_space(int j) const
RCP< const EpetraExt::ModelEvaluator > getEpetraModel() const
void uninitialize(RCP< const EpetraExt::ModelEvaluator > *epetraModel=NULL, RCP< LinearOpWithSolveFactoryBase< double > > *W_factory=NULL)
RCP< const VectorSpaceBase< double > > get_x_space() const
RCP< const Epetra_Vector > getStateVariableInvScalingVec() const
Get the state variable scaling vector s_x (see above).
ModelEvaluatorBase::InArgs< double > getLowerBounds() const
RCP< const Epetra_Vector > getStateVariableScalingVec() const
Get the inverse state variable scaling vector inv_s_x (see above).
RCP< const Teuchos::ParameterList > getValidParameters() const
Teuchos::ArrayView< const std::string > get_g_names(int j) const
RCP< const Teuchos::Array< std::string > > get_p_names(int l) const
RCP< const VectorSpaceBase< double > > get_p_space(int l) const
const ModelEvaluatorBase::InArgs< double > & getFinalPoint() const
ModelEvaluatorBase::EDerivativeMultiVectorOrientation convert(const EpetraExt::ModelEvaluator::EDerivativeMultiVectorOrientation &mvOrientation)
Factory interface for creating LinearOpWithSolveBase objects from compatible LinearOpBase objects.
Determines the forms of a general derivative that are supported.
Concrete aggregate class for all input arguments computable by a ModelEvaluator subclass object.
void setArgs(const InArgs< Scalar > &inArgs, bool ignoreUnsupported=false, bool cloneObjects=false)
Set non-null arguments (does not overwrite non-NULLs with NULLs) .
bool supports(EInArgsMembers arg) const
Determines if an input argument is supported or not.
Base subclass for ModelEvaluator that defines some basic types.
RCP< VectorBase< double > > create_Vector(const RCP< Epetra_Vector > &epetra_v, const RCP< const VectorSpaceBase< double > > &space=Teuchos::null)
Create a non-const VectorBase object from a non-const Epetra_Vector object.
RCP< const VectorSpaceBase< double > > create_VectorSpace(const RCP< const Epetra_Map > &epetra_map)
Create an VectorSpaceBase object given an Epetra_Map object.
RCP< Epetra_Vector > get_Epetra_Vector(const Epetra_Map &map, const RCP< VectorBase< double > > &v)
Get a non-const Epetra_Vector view from a non-const VectorBase object if possible.
RCP< Epetra_MultiVector > get_Epetra_MultiVector(const Epetra_Map &map, const RCP< MultiVectorBase< double > > &mv)
Get a non-const Epetra_MultiVector view from a non-const MultiVectorBase object if possible.
#define TEUCHOS_ASSERT(assertion_test)
#define TEUCHOS_ASSERT_IN_RANGE_UPPER_EXCLUSIVE(index, lower_inclusive, upper_exclusive)
#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)
bool nonnull(const std::shared_ptr< T > &p)
#define TEUCHOS_UNREACHABLE_RETURN(dummyReturnVal)
TypeTo implicit_cast(const TypeFrom &t)
std::string typeName(const T &t)
T_To & dyn_cast(T_From &from)
basic_OSTab< char > OSTab
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)
Simple public strict containing properties of a derivative object.