Thyra  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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 
25 namespace {
26 
27 
28 const std::string StateFunctionScaling_name = "State Function Scaling";
31  Thyra::EpetraModelEvaluator::EStateFunctionScaling
32  >
33  >
34 stateFunctionScalingValidator;
35 const std::string StateFunctionScaling_default = "None";
36 
37 
38 // Extract out the Epetra_RowMatrix from the set W in an Epetra OutArgs object
40 get_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>
48  ermW = Teuchos::rcp_dynamic_cast<Epetra_RowMatrix>(eW,false);
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 
64 create_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 
85 namespace 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,
99  const RCP<LinearOpWithSolveFactoryBase<double> > &W_factory
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,
110  const RCP<LinearOpWithSolveFactoryBase<double> > &W_factory
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;
329  static RCP<const Teuchos::ParameterList> validPL;
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 
468 {
469  return Teuchos::null;
470 }
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 
503 EpetraModelEvaluator::create_DfDp_op_impl(int /* l */) const
504 {
506  TEUCHOS_UNREACHABLE_RETURN(Teuchos::null);
507 }
508 
509 
510 RCP<LinearOpBase<double> >
511 EpetraModelEvaluator::create_DgDx_dot_op_impl(int /* j */) const
512 {
514  TEUCHOS_UNREACHABLE_RETURN(Teuchos::null);
515 }
516 
517 
518 RCP<LinearOpBase<double> >
519 EpetraModelEvaluator::create_DgDx_op_impl(int /* j */) const
520 {
522  TEUCHOS_UNREACHABLE_RETURN(Teuchos::null);
523 }
524 
525 
526 RCP<LinearOpBase<double> >
527 EpetraModelEvaluator::create_DgDp_op_impl( int /* j */, int /* l */ ) const
528 {
530  TEUCHOS_UNREACHABLE_RETURN(Teuchos::null);
531 }
532 
533 
534 ModelEvaluatorBase::OutArgs<double>
535 EpetraModelEvaluator::createOutArgsImpl() const
536 {
537  if (!currentInArgsOutArgs_) {
538  updateInArgsOutArgs();
539  }
540  return prototypeOutArgs_;
541 }
542 
543 
544 void 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 
772 void EpetraModelEvaluator::convertInArgsFromEpetraToThyra(
773  const EpetraExt::ModelEvaluator::InArgs &epetraInArgs,
774  ModelEvaluatorBase::InArgs<double> *inArgs
775  ) const
776 {
777 
779  typedef ModelEvaluatorBase MEB;
780 
781  TEUCHOS_TEST_FOR_EXCEPT(!inArgs);
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 
815 void 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
824  using Teuchos::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 
917 void 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
1100  = Teuchos::rcp_const_cast<Epetra_Vector>(get_Epetra_Vector(*f_map_,
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 
1112 void 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 
1175 void 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 
1242 void 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 
1271 void EpetraModelEvaluator::updateNominalValuesAndBounds() const
1272 {
1273 
1274  using Teuchos::rcp;
1275  using Teuchos::implicit_cast;
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 
1344 void 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 
1471 RCP<EpetraLinearOp>
1472 EpetraModelEvaluator::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 
1490 Thyra::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 
1500 Thyra::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 
1516 EpetraExt::ModelEvaluator::EDerivativeMultiVectorOrientation
1517 Thyra::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 
1534 Thyra::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 
1572 Thyra::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 
1587 EpetraExt::ModelEvaluator::Derivative
1588 Thyra::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(
1597  Teuchos::rcp_const_cast<Epetra_Operator>(
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 }
1618 EpetraExt::ModelEvaluator::MPDerivative
1619 Thyra::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 }
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...
const ModelEvaluatorBase::InArgs< double > & getFinalPoint() const
ModelEvaluatorBase::InArgs< double > getLowerBounds() const
void setNominalValues(const ModelEvaluatorBase::InArgs< double > &nominalValues)
Set the nominal values.
bool DistributedGlobal() const
RCP< const EpetraExt::ModelEvaluator > getEpetraModel() const
void reportFinalPoint(const ModelEvaluatorBase::InArgs< double > &finalPoint, const bool wasSolved)
bool is_null(const boost::shared_ptr< T > &p)
basic_OSTab< char > OSTab
RCP< const Teuchos::ParameterList > getValidParameters() const
RCP< LinearOpBase< double > > create_W_op() const
ModelEvaluatorBase::InArgs< double > getNominalValues() const
RCP< Teuchos::ParameterList > getNonconstParameterList()
RCP< const VectorSpaceBase< double > > create_VectorSpace(const RCP< const Epetra_Map > &epetra_map)
Create an VectorSpaceBase object given an Epetra_Map object.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
RCP< PreconditionerBase< double > > create_W_prec() const
Returns null currently.
void setStateVariableScalingVec(const RCP< const Epetra_Vector > &stateVariableScalingVec)
Set the state variable scaling vector s_x (see above).
ParameterList & set(std::string const &name, T &&value, std::string const &docString="", RCP< const ParameterEntryValidator > const &validator=null)
ModelEvaluatorBase::InArgs< double > createInArgs() const
RCP< const Epetra_Vector > getStateVariableScalingVec() const
Get the inverse state variable scaling vector inv_s_x (see above).
#define TEUCHOS_ASSERT_IN_RANGE_UPPER_EXCLUSIVE(index, lower_inclusive, upper_exclusive)
RCP< const Teuchos::ParameterList > getParameterList() const
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
RCP< const LinearOpWithSolveFactoryBase< double > > get_W_factory() const
RCP< const Epetra_Vector > getStateVariableInvScalingVec() const
Get the state variable scaling vector s_x (see above).
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.
void setArgs(const InArgs< Scalar > &inArgs, bool ignoreUnsupported=false, bool cloneObjects=false)
Set non-null arguments (does not overwrite non-NULLs with NULLs) .
ModelEvaluatorBase::InArgs< double > getUpperBounds() const
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).
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.
void initialize(const RCP< const EpetraExt::ModelEvaluator > &epetraModel, const RCP< LinearOpWithSolveFactoryBase< double > > &W_factory)
RCP< const VectorSpaceBase< double > > get_f_space() const
TypeTo implicit_cast(const TypeFrom &t)
RCP< const VectorSpaceBase< double > > get_x_space() const
RCP< const VectorSpaceBase< double > > get_g_space(int j) const
Simple public strict containing properties of a derivative object.
RCP< const VectorSpaceBase< double > > get_p_space(int l) const
void resize(size_type new_size, const value_type &x=value_type())
RCP< const Teuchos::Array< std::string > > get_p_names(int l) const
void setParameterList(RCP< Teuchos::ParameterList > const &paramList)
TEUCHOSCORE_LIB_DLL_EXPORT bool includesVerbLevel(const EVerbosityLevel verbLevel, const EVerbosityLevel requestedVerbLevel, const bool isDefaultLevel=false)
const RCP< T > & assert_not_null() const
void validateParameters(ParameterList const &validParamList, int const depth=1000, EValidateUsed const validateUsed=VALIDATE_USED_ENABLED, EValidateDefaults const validateDefaults=VALIDATE_DEFAULTS_ENABLED) const
Base subclass for ModelEvaluator that defines some basic types.
ModelEvaluatorBase::EDerivativeMultiVectorOrientation convert(const EpetraExt::ModelEvaluator::EDerivativeMultiVectorOrientation &mvOrientation)
void uninitialize(RCP< const EpetraExt::ModelEvaluator > *epetraModel=NULL, RCP< LinearOpWithSolveFactoryBase< double > > *W_factory=NULL)
bool nonnull(const boost::shared_ptr< T > &p)
Teuchos::ArrayView< const std::string > get_g_names(int j) const
#define TEUCHOS_UNREACHABLE_RETURN(dummyReturnVal)
size_type size() const
Determines the forms of a general derivative that are supported.
#define TEUCHOS_ASSERT(assertion_test)
bool supports(EInArgsMembers arg) const
Determines if an input argument is supported or not.
RCP< Teuchos::ParameterList > unsetParameterList()
#define TEUCHOS_TEST_FOR_EXCEPT(throw_exception_test)
std::string typeName(const T &t)