• Main Page
  • Related Pages
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

AAdapt_ThyraAdaptiveModelEvaluator.cpp

Go to the documentation of this file.
00001 //*****************************************************************//
00002 //    Albany 2.0:  Copyright 2012 Sandia Corporation               //
00003 //    This Software is released under the BSD license detailed     //
00004 //    in the file "license.txt" in the top-level Albany directory  //
00005 //*****************************************************************//
00006 
00007 #include "AAdapt_ThyraAdaptiveModelEvaluator.hpp"
00008 
00009 #include "Thyra_EpetraModelEvaluator.hpp"
00010 #include "Thyra_LinearOpWithSolveFactoryHelpers.hpp"
00011 #include "Thyra_EpetraThyraWrappers.hpp"
00012 #include "Thyra_EpetraLinearOp.hpp"
00013 #include "Thyra_DetachedMultiVectorView.hpp"
00014 #include "Thyra_ModelEvaluatorDelegatorBase.hpp" // Gives verbose macros!
00015 #include "EpetraExt_ModelEvaluatorScalingTools.h"
00016 #include "Epetra_RowMatrix.h"
00017 #include "Teuchos_Time.hpp"
00018 #include "Teuchos_implicit_cast.hpp"
00019 #include "Teuchos_Assert.hpp"
00020 #include "Teuchos_StandardParameterEntryValidators.hpp"
00021 #include "Teuchos_VerboseObjectParameterListHelpers.hpp"
00022 
00023 
00024 namespace {
00025 
00026 
00027 const std::string StateFunctionScaling_name = "State Function Scaling";
00028 Teuchos::RCP<
00029   Teuchos::StringToIntegralParameterEntryValidator<
00030     AAdapt::ThyraAdaptiveModelEvaluator::EStateFunctionScaling
00031     >
00032   >
00033 stateFunctionScalingValidator;
00034 const std::string StateFunctionScaling_default = "None";
00035 
00036 
00037 // Extract out the Epetra_RowMatrix from the set W in an Epetra OutArgs object
00038 Teuchos::RCP<Epetra_RowMatrix>
00039 get_Epetra_RowMatrix(
00040   const EpetraExt::ModelEvaluator::OutArgs &epetraOutArgs
00041   )
00042 {
00043   using Teuchos::RCP;
00044   const RCP<Epetra_Operator>
00045     eW = epetraOutArgs.get_W();
00046   const RCP<Epetra_RowMatrix>
00047     ermW = Teuchos::rcp_dynamic_cast<Epetra_RowMatrix>(eW,false);
00048   TEUCHOS_TEST_FOR_EXCEPTION(
00049     is_null(ermW), std::logic_error,
00050     "AAdapt::ThyraAdaptiveModelEvaluator::evalModel(...): Error, if\n"
00051     "scaling is turned on, the underlying Epetra_Operator created\n"
00052     "an initialized by the underlying epetra model evaluator\n"
00053     "\"" << epetraOutArgs.modelEvalDescription() << "\"\n"
00054     "must support the Epetra_RowMatrix interface through a dynamic cast.\n"
00055     "The concrete type " << Teuchos::typeName(*eW) << " does not support\n"
00056     "Epetra_RowMatrix!"
00057     );
00058   return ermW;
00059 }
00060 
00061 
00062 Teuchos::RCP<Epetra_Operator>
00063 create_and_assert_W( 
00064   const EpetraExt::ModelEvaluator &epetraModel
00065   )
00066 {
00067   using Teuchos::RCP;
00068   RCP<Epetra_Operator>
00069     eW = epetraModel.create_W();
00070   TEUCHOS_TEST_FOR_EXCEPTION(
00071     is_null(eW), std::logic_error,
00072     "Error, the call to create_W() returned null on the "
00073     "EpetraExt::ModelEvaluator object "
00074     "\"" << epetraModel.description() << "\".  This may mean that "
00075     "the underlying model does not support more than one copy of "
00076     "W at one time!" );
00077   return eW;
00078 }
00079 
00080 
00081 } // namespace
00082 
00083 
00084 namespace AAdapt {
00085 
00086 using Teuchos::RCP;
00087 using Thyra::LinearOpWithSolveFactoryBase;
00088 using Thyra::LinearOpBase;
00089 using Thyra::create_VectorSpace;
00090 using Thyra::ModelEvaluatorBase;
00091 using Thyra::VectorSpaceBase;
00092 using Thyra::VectorBase;
00093 using Thyra::PreconditionerBase;
00094 using Thyra::EpetraLinearOp;
00095 using Thyra::get_Epetra_Vector;
00096 using Thyra::convert;
00097 
00098 // Constructors/initializers/accessors.
00099 
00100 
00101 ThyraAdaptiveModelEvaluator::ThyraAdaptiveModelEvaluator()
00102   :nominalValuesAndBoundsAreUpdated_(false), stateFunctionScaling_(STATE_FUNC_SCALING_NONE),
00103    currentInArgsOutArgs_(false), finalPointWasSolved_(false)
00104 {}
00105 
00106 
00107 ThyraAdaptiveModelEvaluator::ThyraAdaptiveModelEvaluator(
00108   const RCP<const EpetraExt::ModelEvaluator> &epetraModel,
00109   const RCP<LinearOpWithSolveFactoryBase<double> > &W_factory
00110   )
00111   :nominalValuesAndBoundsAreUpdated_(false), stateFunctionScaling_(STATE_FUNC_SCALING_NONE),
00112    currentInArgsOutArgs_(false), finalPointWasSolved_(false)
00113 {
00114   initialize(epetraModel,W_factory);
00115 }
00116 
00117 
00118 void ThyraAdaptiveModelEvaluator::initialize(
00119   const RCP<const EpetraExt::ModelEvaluator> &epetraModel,
00120   const RCP<LinearOpWithSolveFactoryBase<double> > &W_factory
00121   )
00122 {
00123   using Teuchos::implicit_cast;
00124   typedef ModelEvaluatorBase MEB;
00125   //
00126   epetraModel_ = epetraModel;
00127   //
00128   W_factory_ = W_factory;
00129   //
00130   x_map_ = epetraModel_->get_x_map();
00131   f_map_ = epetraModel_->get_f_map();
00132   if (!is_null(x_map_)) {
00133     x_space_ = create_VectorSpace(x_map_);
00134     f_space_ = create_VectorSpace(f_map_);
00135   }
00136   //
00137   EpetraExt::ModelEvaluator::InArgs inArgs = epetraModel_->createInArgs();
00138   p_map_.resize(inArgs.Np()); p_space_.resize(inArgs.Np());
00139   p_map_is_local_.resize(inArgs.Np(),false);
00140   for( int l = 0; l < implicit_cast<int>(p_space_.size()); ++l ) {
00141     RCP<const Epetra_Map>
00142       p_map_l = ( p_map_[l] = epetraModel_->get_p_map(l) );
00143 #ifdef TEUCHOS_DEBUG
00144     TEUCHOS_TEST_FOR_EXCEPTION(
00145       is_null(p_map_l), std::logic_error,
00146       "Error, the the map p["<<l<<"] for the model \""
00147       <<epetraModel->description()<<"\" can not be null!");
00148 #endif
00149 
00150     p_map_is_local_[l] = !p_map_l->DistributedGlobal();
00151     p_space_[l] = create_VectorSpace(p_map_l);
00152   }
00153   //
00154   EpetraExt::ModelEvaluator::OutArgs outArgs = epetraModel_->createOutArgs();
00155   g_map_.resize(outArgs.Ng()); g_space_.resize(outArgs.Ng());
00156   g_map_is_local_.resize(outArgs.Ng(),false);
00157   for( int j = 0; j < implicit_cast<int>(g_space_.size()); ++j ) {
00158     RCP<const Epetra_Map>
00159       g_map_j = ( g_map_[j] = epetraModel_->get_g_map(j) );
00160     g_map_is_local_[j] = !g_map_j->DistributedGlobal();
00161     g_space_[j] = create_VectorSpace( g_map_j );
00162   }
00163   //
00164   epetraInArgsScaling_ = epetraModel_->createInArgs();
00165   epetraOutArgsScaling_ = epetraModel_->createOutArgs();
00166   nominalValuesAndBoundsAreUpdated_ = false;
00167   finalPointWasSolved_ = false;
00168   stateFunctionScalingVec_ = Teuchos::null; // Must set new scaling!
00169   //
00170   currentInArgsOutArgs_ = false;
00171 }
00172 
00173 
00174 RCP<const EpetraExt::ModelEvaluator>
00175 ThyraAdaptiveModelEvaluator::getEpetraModel() const
00176 {
00177   return epetraModel_;
00178 }
00179 
00180 
00181 void ThyraAdaptiveModelEvaluator::setNominalValues(
00182   const ModelEvaluatorBase::InArgs<double>& nominalValues
00183  )
00184 {
00185   nominalValues_.setArgs(nominalValues);
00186   // Note: These must be the scaled values so we don't need to scale!
00187 }
00188 
00189 
00190 void ThyraAdaptiveModelEvaluator::setStateVariableScalingVec(
00191   const RCP<const Epetra_Vector> &stateVariableScalingVec
00192   )
00193 {
00194   typedef ModelEvaluatorBase MEB;
00195 #ifdef TEUCHOS_DEBUG
00196   TEUCHOS_TEST_FOR_EXCEPT( !this->createInArgs().supports(MEB::IN_ARG_x) );
00197 #endif  
00198   stateVariableScalingVec_ = stateVariableScalingVec.assert_not_null();
00199   invStateVariableScalingVec_ = Teuchos::null;
00200   nominalValuesAndBoundsAreUpdated_ = false;
00201 }
00202 
00203 
00204 RCP<const Epetra_Vector>
00205 ThyraAdaptiveModelEvaluator::getStateVariableScalingVec() const
00206 {
00207   return stateVariableScalingVec_;
00208 }
00209 
00210 
00211 RCP<const Epetra_Vector>
00212 ThyraAdaptiveModelEvaluator::getStateVariableInvScalingVec() const
00213 {
00214   updateNominalValuesAndBounds();
00215   return invStateVariableScalingVec_;
00216 }
00217 
00218 
00219 void ThyraAdaptiveModelEvaluator::setStateFunctionScalingVec(
00220   const RCP<const Epetra_Vector> &stateFunctionScalingVec
00221   )
00222 {
00223   stateFunctionScalingVec_ = stateFunctionScalingVec;
00224 }
00225 
00226 
00227 RCP<const Epetra_Vector>
00228 ThyraAdaptiveModelEvaluator::getStateFunctionScalingVec() const
00229 {
00230   return stateFunctionScalingVec_;
00231 }
00232 
00233 
00234 void ThyraAdaptiveModelEvaluator::uninitialize(
00235   RCP<const EpetraExt::ModelEvaluator> *epetraModel,
00236   RCP<LinearOpWithSolveFactoryBase<double> > *W_factory
00237   )
00238 {
00239   if(epetraModel) *epetraModel = epetraModel_;
00240   if(W_factory) *W_factory = W_factory_;
00241   epetraModel_ = Teuchos::null;
00242   W_factory_ = Teuchos::null;
00243   stateFunctionScalingVec_ = Teuchos::null;
00244   stateVariableScalingVec_ = Teuchos::null;
00245   invStateVariableScalingVec_ = Teuchos::null;
00246   currentInArgsOutArgs_ = false;
00247 }
00248 
00249 
00250 const ModelEvaluatorBase::InArgs<double>&
00251 ThyraAdaptiveModelEvaluator::getFinalPoint() const
00252 {
00253   return finalPoint_;
00254 }
00255 
00256 
00257 bool ThyraAdaptiveModelEvaluator::finalPointWasSolved() const
00258 {
00259   return finalPointWasSolved_;
00260 }
00261 
00262 const Teuchos::RCP<Thyra::VectorBase<double> >
00263 ThyraAdaptiveModelEvaluator::resize_g_space(int index, Teuchos::RCP<const Epetra_Map> map){
00264 
00265     RCP<const Epetra_Map>
00266       g_map_j = ( g_map_[index] = map );
00267     g_map_is_local_[index] = !g_map_j->DistributedGlobal();
00268     g_space_[index] = create_VectorSpace( g_map_j );
00269     const Teuchos::RCP<Thyra::VectorBase<double> > g_j = Thyra::createMember(*g_space_[index]);
00270 
00271     RCP<Epetra_Vector> davector = get_Epetra_Vector(*g_map_[index], g_j);
00272 
00273     // replace the vector in the outArgs being used in epetraModel->evalModel
00274     evaluated_epetraUnscaledOutArgs.set_g(index, davector);
00275 
00276     return g_j;
00277 
00278 /* Ordinarily, we would update the maps, but Piro_Epetra_ME returns NULL maps.
00279     x_map_ = epetraModel_->get_x_map();
00280     f_map_ = epetraModel_->get_f_map();
00281     if (!is_null(x_map_)) {
00282       x_space_ = create_VectorSpace(x_map_);
00283       f_space_ = create_VectorSpace(f_map_);
00284     }
00285 */
00286 
00287 }
00288 
00289 
00290 // Public functions overridden from Teuchos::Describable
00291 
00292 
00293 std::string ThyraAdaptiveModelEvaluator::description() const
00294 {
00295   std::ostringstream oss;
00296   oss << "Thyra::ThyraAdaptiveModelEvaluator{";
00297   oss << "epetraModel=";
00298   if(epetraModel_.get())
00299     oss << "\'"<<epetraModel_->description()<<"\'";
00300   else
00301     oss << "NULL";
00302   oss << ",W_factory=";
00303   if(W_factory_.get())
00304     oss << "\'"<<W_factory_->description()<<"\'";
00305   else
00306     oss << "NULL";
00307   oss << "}";
00308   return oss.str();
00309 }
00310 
00311 
00312 // Overridden from Teuchos::ParameterListAcceptor
00313 
00314 
00315 void ThyraAdaptiveModelEvaluator::setParameterList(
00316   RCP<Teuchos::ParameterList> const& paramList
00317   )
00318 {
00319   TEUCHOS_TEST_FOR_EXCEPT(is_null(paramList));
00320   paramList->validateParameters(*getValidParameters(),0); // Just validate my params
00321   paramList_ = paramList;
00322   const EStateFunctionScaling stateFunctionScaling_old = stateFunctionScaling_; 
00323   stateFunctionScaling_ = stateFunctionScalingValidator->getIntegralValue(
00324     *paramList_, StateFunctionScaling_name, StateFunctionScaling_default
00325     );
00326   if( stateFunctionScaling_ != stateFunctionScaling_old )
00327     stateFunctionScalingVec_ = Teuchos::null;
00328   Teuchos::readVerboseObjectSublist(&*paramList_,this);
00329 #ifdef TEUCHOS_DEBUG
00330   paramList_->validateParameters(*getValidParameters(),0);
00331 #endif // TEUCHOS_DEBUG
00332 }
00333 
00334 
00335 RCP<Teuchos::ParameterList>
00336 ThyraAdaptiveModelEvaluator::getNonconstParameterList()
00337 {
00338   return paramList_;
00339 }
00340 
00341 
00342 RCP<Teuchos::ParameterList>
00343 ThyraAdaptiveModelEvaluator::unsetParameterList()
00344 {
00345   RCP<Teuchos::ParameterList> _paramList = paramList_;
00346   paramList_ = Teuchos::null;
00347   return _paramList;
00348 }
00349 
00350 
00351 RCP<const Teuchos::ParameterList>
00352 ThyraAdaptiveModelEvaluator::getParameterList() const
00353 {
00354   return paramList_;
00355 }
00356 
00357 
00358 RCP<const Teuchos::ParameterList>
00359 ThyraAdaptiveModelEvaluator::getValidParameters() const
00360 {
00361   using Teuchos::rcp;
00362   using Teuchos::StringToIntegralParameterEntryValidator;
00363   using Teuchos::tuple;
00364   using Teuchos::rcp_implicit_cast;
00365   typedef Teuchos::ParameterEntryValidator PEV;
00366   static RCP<const Teuchos::ParameterList> validPL;
00367   if(is_null(validPL)) {
00368     RCP<Teuchos::ParameterList>
00369       pl = Teuchos::rcp(new Teuchos::ParameterList());
00370     stateFunctionScalingValidator = rcp(
00371       new StringToIntegralParameterEntryValidator<EStateFunctionScaling>(
00372         tuple<std::string>(
00373           "None",
00374           "Row Sum"
00375           ),
00376         tuple<std::string>(
00377           "Do not scale the state function f(...) in this class.",
00378 
00379           "Scale the state function f(...) and all its derivatives\n"
00380           "using the row sum scaling from the initial Jacobian\n"
00381           "W=d(f)/d(x).  Note, this only works with Epetra_CrsMatrix\n"
00382           "currently."
00383           ),
00384         tuple<EStateFunctionScaling>(
00385           STATE_FUNC_SCALING_NONE,
00386           STATE_FUNC_SCALING_ROW_SUM
00387           ),
00388         StateFunctionScaling_name
00389         )
00390       );
00391     pl->set(StateFunctionScaling_name,StateFunctionScaling_default,
00392       "Determines if and how the state function f(...) and all of its\n"
00393       "derivatives are scaled.  The scaling is done explicitly so there should\n"
00394       "be no impact on the meaning of inner products or tolerances for\n"
00395       "linear solves.",
00396       rcp_implicit_cast<const PEV>(stateFunctionScalingValidator)
00397       );
00398     Teuchos::setupVerboseObjectSublist(&*pl);
00399     validPL = pl;
00400   }
00401   return validPL;
00402 }
00403 
00404 
00405 // Overridden from ModelEvaulator.
00406 
00407 
00408 int ThyraAdaptiveModelEvaluator::Np() const
00409 {
00410   return p_space_.size();
00411 }
00412 
00413 
00414 int ThyraAdaptiveModelEvaluator::Ng() const
00415 {
00416   return g_space_.size();
00417 }
00418 
00419 
00420 RCP<const VectorSpaceBase<double> >
00421 ThyraAdaptiveModelEvaluator::get_x_space() const
00422 {
00423   return x_space_;
00424 }
00425 
00426 
00427 RCP<const VectorSpaceBase<double> >
00428 ThyraAdaptiveModelEvaluator::get_f_space() const
00429 {
00430   return f_space_;
00431 }
00432 
00433 
00434 RCP<const VectorSpaceBase<double> >
00435 ThyraAdaptiveModelEvaluator::get_p_space(int l) const
00436 {
00437 #ifdef TEUCHOS_DEBUG
00438   TEUCHOS_ASSERT_IN_RANGE_UPPER_EXCLUSIVE( l, 0, this->Np() );
00439 #endif
00440   return p_space_[l];
00441 }
00442 
00443 
00444 RCP<const Teuchos::Array<std::string> >
00445 ThyraAdaptiveModelEvaluator::get_p_names(int l) const
00446 {
00447 #ifdef TEUCHOS_DEBUG
00448   TEUCHOS_ASSERT_IN_RANGE_UPPER_EXCLUSIVE( l, 0, this->Np() );
00449 #endif
00450   return epetraModel_->get_p_names(l);
00451 }
00452 
00453 
00454 RCP<const VectorSpaceBase<double> >
00455 ThyraAdaptiveModelEvaluator::get_g_space(int j) const
00456 {
00457   TEUCHOS_TEST_FOR_EXCEPT( ! ( 0 <= j && j < this->Ng() ) );
00458   return g_space_[j];
00459 }
00460 
00461 
00462 ModelEvaluatorBase::InArgs<double>
00463 ThyraAdaptiveModelEvaluator::getNominalValues() const
00464 {
00465   updateNominalValuesAndBounds();
00466   return nominalValues_;
00467 }
00468 
00469 
00470 ModelEvaluatorBase::InArgs<double>
00471 ThyraAdaptiveModelEvaluator::getLowerBounds() const
00472 {
00473   updateNominalValuesAndBounds();
00474   return lowerBounds_;
00475 }
00476 
00477 
00478 ModelEvaluatorBase::InArgs<double>
00479 ThyraAdaptiveModelEvaluator::getUpperBounds() const
00480 {
00481   updateNominalValuesAndBounds();
00482   return upperBounds_;
00483 }
00484 
00485 
00486 RCP<LinearOpBase<double> >
00487 ThyraAdaptiveModelEvaluator::create_W_op() const
00488 {
00489   return this->create_epetra_W_op();
00490 }
00491 
00492 
00493 RCP<PreconditionerBase<double> >
00494 ThyraAdaptiveModelEvaluator::create_W_prec() const
00495 {
00496   return Teuchos::null;
00497 }
00498 
00499 
00500 RCP<const LinearOpWithSolveFactoryBase<double> >
00501 ThyraAdaptiveModelEvaluator::get_W_factory() const
00502 {
00503   return W_factory_;
00504 }
00505 
00506 
00507 ModelEvaluatorBase::InArgs<double> ThyraAdaptiveModelEvaluator::createInArgs() const
00508 {
00509   if (!currentInArgsOutArgs_)
00510     updateInArgsOutArgs();
00511   return prototypeInArgs_;
00512 }
00513 
00514 
00515 void ThyraAdaptiveModelEvaluator::reportFinalPoint(
00516   const ModelEvaluatorBase::InArgs<double> &finalPoint,
00517   const bool wasSolved
00518   )
00519 {
00520   finalPoint_ = this->createInArgs();
00521   finalPoint_.setArgs(finalPoint);
00522   finalPointWasSolved_ = wasSolved;
00523 }
00524 
00525 
00526 // Private functions overridden from ModelEvaulatorDefaultBase
00527 
00528 
00529 RCP<LinearOpBase<double> >
00530 ThyraAdaptiveModelEvaluator::create_DfDp_op_impl(int l) const
00531 {
00532   TEUCHOS_TEST_FOR_EXCEPT(true);
00533   return Teuchos::null;
00534 }
00535 
00536 
00537 RCP<LinearOpBase<double> >
00538 ThyraAdaptiveModelEvaluator::create_DgDx_dot_op_impl(int j) const
00539 {
00540   TEUCHOS_TEST_FOR_EXCEPT(true);
00541   return Teuchos::null;
00542 }
00543 
00544 
00545 RCP<LinearOpBase<double> >
00546 ThyraAdaptiveModelEvaluator::create_DgDx_op_impl(int j) const
00547 {
00548   TEUCHOS_TEST_FOR_EXCEPT(true);
00549   return Teuchos::null;
00550 }
00551 
00552 
00553 RCP<LinearOpBase<double> >
00554 ThyraAdaptiveModelEvaluator::create_DgDp_op_impl( int j, int l ) const
00555 {
00556   TEUCHOS_TEST_FOR_EXCEPT(true);
00557   return Teuchos::null;
00558 }
00559 
00560 
00561 ModelEvaluatorBase::OutArgs<double>
00562 ThyraAdaptiveModelEvaluator::createOutArgsImpl() const
00563 {
00564   if (!currentInArgsOutArgs_)
00565     updateInArgsOutArgs();
00566   return prototypeOutArgs_;
00567 }
00568 
00569 
00570 void ThyraAdaptiveModelEvaluator::evalModelImpl(
00571   const ModelEvaluatorBase::InArgs<double>& inArgs_in,
00572   const ModelEvaluatorBase::OutArgs<double>& outArgs
00573   ) const
00574 {
00575 
00576   using Teuchos::rcp;
00577   using Teuchos::rcp_const_cast;
00578   using Teuchos::rcp_dynamic_cast;
00579   using Teuchos::OSTab;
00580   using Teuchos::includesVerbLevel;
00581   typedef EpetraExt::ModelEvaluator EME;
00582 
00583   //
00584   // A) Initial setup
00585   //
00586 
00587   // Make sure that we are fully initialized!
00588   this->updateNominalValuesAndBounds();
00589 
00590   // Make sure we grab the initial guess first!
00591   InArgs<double> inArgs = this->getNominalValues();
00592   // Now, copy the parameters from the input inArgs_in object to the inArgs
00593   // object.  Any input objects that are set in inArgs_in will overwrite those
00594   // in inArgs that will already contain the nominal values.  This will insure
00595   // that all input parameters are set and those that are not set by the
00596   // client will be at their nominal values (as defined by the underlying
00597   // EpetraExt::ModelEvaluator object).  The full set of Thyra input arguments
00598   // must be set before these can be translated into Epetra input arguments.
00599   inArgs.setArgs(inArgs_in);
00600 
00601   // This is a special exception: see evalModel() in Thyra::ME
00602   // documentation.  If inArgs() supports x_dot but the evaluate call
00603   // passes in a null value, then we need to make sure the null value
00604   // gets passed on instead of the nominal value.
00605   if (inArgs.supports(Thyra::ModelEvaluatorBase::IN_ARG_x_dot)) {
00606     if (is_null(inArgs_in.get_x_dot()))
00607       inArgs.set_x_dot(Teuchos::null);
00608   }
00609 
00610   // Print the header and the values of the inArgs and outArgs objects!
00611   typedef double Scalar; // Needed for below macro!
00612   THYRA_MODEL_EVALUATOR_DECORATOR_EVAL_MODEL_GEN_BEGIN(
00613     "Thyra::ThyraAdaptiveModelEvaluator",inArgs,outArgs,Teuchos::null
00614     );
00615 
00616   // State function Scaling
00617   const bool firstTimeStateFuncScaling
00618     = (
00619       stateFunctionScaling_ != STATE_FUNC_SCALING_NONE
00620       && is_null(stateFunctionScalingVec_)
00621       );
00622   
00623   typedef Teuchos::VerboseObjectTempState<LinearOpWithSolveFactoryBase<double> > VOTSLOWSF;
00624   VOTSLOWSF W_factory_outputTempState(W_factory_,out,verbLevel);
00625 
00626   Teuchos::Time timer("");
00627 
00628   //
00629   // B) Prepressess the InArgs and OutArgs in preparation to call
00630   // the underlying EpetraExt::ModelEvaluator
00631   //
00632 
00633   //
00634   // B.1) Translate InArgs from Thyra to Epetra objects
00635   //
00636   
00637   if (out.get() && includesVerbLevel(verbLevel,Teuchos::VERB_LOW))
00638     *out << "\nSetting-up/creating input arguments ...\n";
00639   timer.start(true);
00640 
00641   // Unwrap input Thyra objects to get Epetra objects
00642   EME::InArgs epetraScaledInArgs = epetraModel_->createInArgs();
00643   convertInArgsFromThyraToEpetra( inArgs, &epetraScaledInArgs );
00644 
00645   // Unscale the input Epetra objects which will be passed to the underlying
00646   // EpetraExt::ModelEvaluator object.
00647   EME::InArgs epetraInArgs = epetraModel_->createInArgs();
00648   EpetraExt::unscaleModelVars(
00649     epetraScaledInArgs, epetraInArgsScaling_, &epetraInArgs,
00650     out.get(), verbLevel
00651     );
00652 
00653   timer.stop();
00654   if (out.get() && includesVerbLevel(verbLevel,Teuchos::VERB_LOW))
00655     OSTab(out).o() << "\nTime to setup InArgs = "<<timer.totalElapsedTime()<<" sec\n";
00656 
00657   //
00658   // B.2) Convert from Thyra to Epetra OutArgs
00659   //
00660   
00661   if (out.get() && includesVerbLevel(verbLevel,Teuchos::VERB_LOW))
00662     *out << "\nSetting-up/creating output arguments ...\n";
00663   timer.start(true);
00664   
00665   // The unscaled Epetra OutArgs that will be passed to the
00666   // underlying EpetraExt::ModelEvaluator object
00667   // This is a private class member to allow resizing the solution data array
00668   evaluated_epetraUnscaledOutArgs = epetraModel_->createOutArgs();
00669 
00670   // Various objects that are needed later (see documentation in
00671   // the function convertOutArgsFromThyraToEpetra(...)
00672   RCP<LinearOpBase<double> > W_op;
00673   RCP<EpetraLinearOp> efwdW;
00674   RCP<Epetra_Operator> eW;
00675   
00676   // Convert from Thyra to Epetra OutArgs and grap some of the intermediate
00677   // objects accessed along the way that are needed later.
00678   convertOutArgsFromThyraToEpetra(
00679     outArgs,
00680     &evaluated_epetraUnscaledOutArgs,
00681     &W_op, &efwdW, &eW
00682     );
00683 
00684   //
00685   // B.3) Setup OutArgs to computing scaling if needed
00686   //
00687 
00688   if (firstTimeStateFuncScaling) {
00689     preEvalScalingSetup(&epetraInArgs,&evaluated_epetraUnscaledOutArgs,out,verbLevel);
00690   }
00691 
00692   timer.stop();
00693   if (out.get() && includesVerbLevel(verbLevel,Teuchos::VERB_LOW))
00694     OSTab(out).o()
00695       << "\nTime to setup OutArgs = "
00696       << timer.totalElapsedTime() <<" sec\n";
00697 
00698   //
00699   // C) Evaluate the underlying EpetraExt model to compute the Epetra outputs
00700   //
00701   
00702   if (out.get() && includesVerbLevel(verbLevel,Teuchos::VERB_LOW))
00703     *out << "\nEvaluating the Epetra output functions ...\n";
00704   timer.start(true);
00705 
00706   epetraModel_->evalModel(epetraInArgs, evaluated_epetraUnscaledOutArgs);
00707 
00708   timer.stop();
00709   if (out.get() && includesVerbLevel(verbLevel,Teuchos::VERB_LOW))
00710     OSTab(out).o()
00711       << "\nTime to evaluate Epetra output functions = "
00712       << timer.totalElapsedTime() <<" sec\n";
00713 
00714   //
00715   // D) Postprocess the output objects
00716   //
00717 
00718   //
00719   // D.1) Compute the scaling factors if needed
00720   //
00721   
00722   if (out.get() && includesVerbLevel(verbLevel,Teuchos::VERB_LOW))
00723     *out << "\nCompute scale factors if needed ...\n";
00724   timer.start(true);
00725 
00726   if (firstTimeStateFuncScaling) {
00727     postEvalScalingSetup(evaluated_epetraUnscaledOutArgs,out,verbLevel);
00728   }
00729 
00730   timer.stop();
00731   if (out.get() && includesVerbLevel(verbLevel,Teuchos::VERB_LOW))
00732     OSTab(out).o()
00733       << "\nTime to compute scale factors = "
00734       << timer.totalElapsedTime() <<" sec\n";
00735 
00736   //
00737   // D.2) Scale the output Epetra objects
00738   //
00739 
00740   if (out.get() && includesVerbLevel(verbLevel,Teuchos::VERB_LOW))
00741     *out << "\nScale the output objects ...\n";
00742   timer.start(true);
00743 
00744   EME::OutArgs epetraOutArgs = epetraModel_->createOutArgs();
00745   bool allFuncsWhereScaled = false;
00746   EpetraExt::scaleModelFuncs(
00747     evaluated_epetraUnscaledOutArgs, epetraInArgsScaling_, epetraOutArgsScaling_,
00748     &epetraOutArgs, &allFuncsWhereScaled,
00749     out.get(), verbLevel
00750     );
00751   TEUCHOS_TEST_FOR_EXCEPTION(
00752     !allFuncsWhereScaled, std::logic_error,
00753     "Error, we can not currently handle epetra output objects that could not be"
00754     " scaled.  Special code will have to be added to handle this (i.e. using"
00755     " implicit diagonal and multiplied linear operators to implicitly do"
00756     " the scaling."
00757     );
00758 
00759   timer.stop();
00760   if (out.get() && includesVerbLevel(verbLevel,Teuchos::VERB_LOW))
00761     OSTab(out).o()
00762       << "\nTime to scale the output objects = "
00763       << timer.totalElapsedTime() << " sec\n";
00764 
00765   //
00766   // D.3) Convert any Epetra objects to Thyra OutArgs objects that still need to
00767   // be converted
00768   //
00769 
00770   if (out.get() && includesVerbLevel(verbLevel,Teuchos::VERB_LOW))
00771     *out << "\nFinish processing and wrapping the output objects ...\n";
00772   timer.start(true);
00773 
00774   finishConvertingOutArgsFromEpetraToThyra(
00775     epetraOutArgs, W_op, efwdW, eW,
00776     outArgs
00777     );
00778 
00779   timer.stop();
00780   if (out.get() && includesVerbLevel(verbLevel,Teuchos::VERB_LOW))
00781     OSTab(out).o()
00782       << "\nTime to finish processing and wrapping the output objects = "
00783       << timer.totalElapsedTime() <<" sec\n";
00784 
00785   //
00786   // E) Print footer to end the function
00787   //
00788 
00789   THYRA_MODEL_EVALUATOR_DECORATOR_EVAL_MODEL_END();
00790   
00791 }
00792 
00793 
00794 // private
00795 
00796 
00797 void ThyraAdaptiveModelEvaluator::convertInArgsFromEpetraToThyra(
00798   const EpetraExt::ModelEvaluator::InArgs &epetraInArgs,
00799   ModelEvaluatorBase::InArgs<double> *inArgs
00800   ) const
00801 {
00802   
00803   using Teuchos::implicit_cast;
00804   typedef ModelEvaluatorBase MEB;
00805 
00806   TEUCHOS_TEST_FOR_EXCEPT(!inArgs);
00807 
00808   if(inArgs->supports(MEB::IN_ARG_x)) {
00809     inArgs->set_x( create_Vector( epetraInArgs.get_x(), x_space_ ) );
00810   }
00811   
00812   if(inArgs->supports(MEB::IN_ARG_x_dot)) {
00813     inArgs->set_x_dot( create_Vector( epetraInArgs.get_x_dot(), x_space_ ) );
00814   }
00815 
00816   const int l_Np = inArgs->Np();
00817   for( int l = 0; l < l_Np; ++l ) {
00818     inArgs->set_p( l, create_Vector( epetraInArgs.get_p(l), p_space_[l] ) );
00819   }
00820   
00821   if(inArgs->supports(MEB::IN_ARG_t)) {
00822     inArgs->set_t(epetraInArgs.get_t());
00823   }
00824   
00825 }
00826 
00827 
00828 void ThyraAdaptiveModelEvaluator::convertInArgsFromThyraToEpetra(
00829   const ModelEvaluatorBase::InArgs<double> &inArgs,
00830   EpetraExt::ModelEvaluator::InArgs *epetraInArgs
00831   ) const
00832 {
00833 
00834   using Teuchos::rcp;
00835   using Teuchos::rcp_const_cast;
00836 #ifdef HAVE_THYRA_ME_POLYNOMIAL
00837   using Teuchos::Polynomial;
00838 #endif // HAVE_THYRA_ME_POLYNOMIAL
00839 
00840 
00841   TEUCHOS_TEST_FOR_EXCEPT(0==epetraInArgs);
00842 
00843   RCP<const VectorBase<double> > x_dot;
00844   if( inArgs.supports(IN_ARG_x_dot) && (x_dot = inArgs.get_x_dot()).get() ) {
00845     RCP<const Epetra_Vector> e_x_dot = get_Epetra_Vector(*x_map_,x_dot);
00846     epetraInArgs->set_x_dot(e_x_dot);
00847   }
00848 
00849   RCP<const VectorBase<double> > x;
00850   if( inArgs.supports(IN_ARG_x) && (x = inArgs.get_x()).get() ) {
00851     RCP<const Epetra_Vector> e_x = get_Epetra_Vector(*x_map_,x);
00852     epetraInArgs->set_x(e_x);
00853   }
00854 
00855   RCP<const VectorBase<double> > p_l;
00856   for(int l = 0;  l < inArgs.Np(); ++l ) {
00857     p_l = inArgs.get_p(l);
00858     if(p_l.get()) epetraInArgs->set_p(l,get_Epetra_Vector(*p_map_[l],p_l));
00859   }
00860 
00861 #ifdef HAVE_THYRA_ME_POLYNOMIAL
00862 
00863   RCP<const Polynomial< VectorBase<double> > > x_dot_poly;
00864   RCP<Epetra_Vector> epetra_ptr;
00865   if(
00866     inArgs.supports(IN_ARG_x_dot_poly)
00867     && (x_dot_poly = inArgs.get_x_dot_poly()).get()
00868     )
00869   {
00870     RCP<Polynomial<Epetra_Vector> > epetra_x_dot_poly = 
00871       rcp(new Polynomial<Epetra_Vector>(x_dot_poly->degree()));
00872     for (unsigned int i=0; i<=x_dot_poly->degree(); i++) {
00873       epetra_ptr = rcp_const_cast<Epetra_Vector>(
00874         get_Epetra_Vector(*x_map_, x_dot_poly->getCoefficient(i)) );
00875       epetra_x_dot_poly->setCoefficientPtr(i,epetra_ptr);
00876     }
00877     epetraInArgs->set_x_dot_poly(epetra_x_dot_poly);
00878   }
00879   
00880   RCP<const Polynomial< VectorBase<double> > > x_poly;
00881   if(
00882     inArgs.supports(IN_ARG_x_poly)
00883     && (x_poly = inArgs.get_x_poly()).get()
00884     )
00885   {
00886     RCP<Polynomial<Epetra_Vector> > epetra_x_poly = 
00887       rcp(new Polynomial<Epetra_Vector>(x_poly->degree()));
00888     for (unsigned int i=0; i<=x_poly->degree(); i++) {
00889       epetra_ptr = rcp_const_cast<Epetra_Vector>(
00890         get_Epetra_Vector(*x_map_, x_poly->getCoefficient(i)) );
00891       epetra_x_poly->setCoefficientPtr(i,epetra_ptr);
00892     }
00893     epetraInArgs->set_x_poly(epetra_x_poly);
00894   }
00895 
00896 #endif // HAVE_THYRA_ME_POLYNOMIAL
00897 
00898   if( inArgs.supports(IN_ARG_t) )
00899     epetraInArgs->set_t(inArgs.get_t());
00900   
00901   if( inArgs.supports(IN_ARG_alpha) )
00902     epetraInArgs->set_alpha(inArgs.get_alpha());
00903   
00904   if( inArgs.supports(IN_ARG_beta) )
00905     epetraInArgs->set_beta(inArgs.get_beta());
00906 
00907 }
00908 
00909 
00910 void ThyraAdaptiveModelEvaluator::convertOutArgsFromThyraToEpetra(
00911   const ModelEvaluatorBase::OutArgs<double> &outArgs,
00912   EpetraExt::ModelEvaluator::OutArgs *epetraUnscaledOutArgs_inout,
00913   RCP<LinearOpBase<double> > *W_op_out,
00914   RCP<EpetraLinearOp> *efwdW_out,
00915   RCP<Epetra_Operator> *eW_out
00916   ) const
00917 {
00918 
00919   using Teuchos::rcp;
00920   using Teuchos::rcp_const_cast;
00921   using Teuchos::rcp_dynamic_cast;
00922   using Teuchos::OSTab;
00923   using Teuchos::implicit_cast;
00924   using Thyra::get_Epetra_Vector;
00925   typedef EpetraExt::ModelEvaluator EME;
00926 
00927   // Assert input
00928 #ifdef TEUCHOS_DEBUG
00929   TEUCHOS_ASSERT(epetraUnscaledOutArgs_inout);
00930   TEUCHOS_ASSERT(W_op_out);
00931   TEUCHOS_ASSERT(efwdW_out);
00932   TEUCHOS_ASSERT(eW_out);
00933 #endif
00934 
00935   // Create easy to use references
00936   EpetraExt::ModelEvaluator::OutArgs &epetraUnscaledOutArgs = *epetraUnscaledOutArgs_inout;
00937   RCP<LinearOpBase<double> > &W_op = *W_op_out;
00938   RCP<EpetraLinearOp> &efwdW = *efwdW_out;
00939   RCP<Epetra_Operator> &eW = *eW_out;
00940 
00941   // f
00942   { 
00943     RCP<VectorBase<double> > f;
00944     if( outArgs.supports(OUT_ARG_f) && (f = outArgs.get_f()).get() )
00945       epetraUnscaledOutArgs.set_f(get_Epetra_Vector(*f_map_,f));
00946   }
00947     
00948   // g
00949   {
00950     RCP<VectorBase<double> > g_j;
00951     for(int j = 0;  j < outArgs.Ng(); ++j ) {
00952       g_j = outArgs.get_g(j);
00953       if(g_j.get()) epetraUnscaledOutArgs.set_g(j,get_Epetra_Vector(*g_map_[j],g_j));
00954     }
00955   }
00956   
00957   // W_op
00958   {
00959 
00960     if (outArgs.supports(OUT_ARG_W_op) && nonnull(W_op = outArgs.get_W_op())) {
00961       if (nonnull(W_op) && is_null(efwdW)) {
00962         efwdW = rcp_const_cast<EpetraLinearOp>(
00963           rcp_dynamic_cast<const EpetraLinearOp>(W_op, true));
00964       }
00965     }
00966     
00967     if (nonnull(efwdW)) {
00968       // By the time we get here, if we have an object in efwdW, then it
00969       // should already be embeadded with an underlying Epetra_Operator object
00970       // that was allocated by the EpetraExt::ModelEvaluator object.
00971       // Therefore, we should just have to grab this object and be on our way.
00972       eW = efwdW->epetra_op();
00973       epetraUnscaledOutArgs.set_W(eW);
00974     }
00975     
00976     // Note: The following derivative objects update in place!
00977 
00978   }
00979 
00980   // DfDp
00981   {
00982     Derivative<double> DfDp_l;
00983     for(int l = 0;  l < outArgs.Np(); ++l ) {
00984       if( !outArgs.supports(OUT_ARG_DfDp,l).none()
00985         && !(DfDp_l = outArgs.get_DfDp(l)).isEmpty() )
00986       {
00987         epetraUnscaledOutArgs.set_DfDp(l,convert(DfDp_l,f_map_,p_map_[l]));
00988       }
00989     }
00990   }
00991 
00992   // DgDx_dot
00993   {
00994     Derivative<double> DgDx_dot_j;
00995     for(int j = 0;  j < outArgs.Ng(); ++j ) {
00996       if( !outArgs.supports(OUT_ARG_DgDx_dot,j).none()
00997         && !(DgDx_dot_j = outArgs.get_DgDx_dot(j)).isEmpty() )
00998       {
00999         epetraUnscaledOutArgs.set_DgDx_dot(j,convert(DgDx_dot_j,g_map_[j],x_map_));
01000       }
01001     }
01002   }
01003 
01004   // DgDx
01005   {
01006     Derivative<double> DgDx_j;
01007     for(int j = 0;  j < outArgs.Ng(); ++j ) {
01008       if( !outArgs.supports(OUT_ARG_DgDx,j).none()
01009         && !(DgDx_j = outArgs.get_DgDx(j)).isEmpty() )
01010       {
01011         epetraUnscaledOutArgs.set_DgDx(j,convert(DgDx_j,g_map_[j],x_map_));
01012       }
01013     }
01014   }
01015 
01016   // DgDp
01017   {
01018     DerivativeSupport DgDp_j_l_support;
01019     Derivative<double> DgDp_j_l;
01020     for (int j = 0;  j < outArgs.Ng(); ++j ) {
01021       for (int l = 0;  l < outArgs.Np(); ++l ) {
01022         if (!(DgDp_j_l_support = outArgs.supports(OUT_ARG_DgDp,j,l)).none()
01023           && !(DgDp_j_l = outArgs.get_DgDp(j,l)).isEmpty() )
01024         {
01025           epetraUnscaledOutArgs.set_DgDp(j,l,convert(DgDp_j_l,g_map_[j],p_map_[l]));
01026         }
01027       }
01028     }
01029   }
01030 
01031 #ifdef HAVE_THYRA_ME_POLYNOMIAL
01032 
01033   // f_poly
01034   RCP<const Teuchos::Polynomial< VectorBase<double> > > f_poly;
01035   if( outArgs.supports(OUT_ARG_f_poly) && (f_poly = outArgs.get_f_poly()).get() )
01036   {
01037     RCP<Teuchos::Polynomial<Epetra_Vector> > epetra_f_poly = 
01038       Teuchos::rcp(new Teuchos::Polynomial<Epetra_Vector>(f_poly->degree()));
01039     for (unsigned int i=0; i<=f_poly->degree(); i++) {
01040       RCP<Epetra_Vector> epetra_ptr
01041         = Teuchos::rcp_const_cast<Epetra_Vector>(get_Epetra_Vector(*f_map_,
01042             f_poly->getCoefficient(i)));
01043       epetra_f_poly->setCoefficientPtr(i,epetra_ptr);
01044     }
01045     epetraUnscaledOutArgs.set_f_poly(epetra_f_poly);
01046   }
01047 
01048 #endif // HAVE_THYRA_ME_POLYNOMIAL
01049 
01050 }
01051 
01052 
01053 void ThyraAdaptiveModelEvaluator::preEvalScalingSetup(
01054   EpetraExt::ModelEvaluator::InArgs *epetraInArgs_inout,
01055   EpetraExt::ModelEvaluator::OutArgs *epetraUnscaledOutArgs_inout,
01056   const RCP<Teuchos::FancyOStream> &out,
01057   const Teuchos::EVerbosityLevel verbLevel
01058   ) const
01059 {
01060   
01061   typedef EpetraExt::ModelEvaluator EME;
01062   
01063 #ifdef TEUCHOS_DEBUG
01064   TEUCHOS_ASSERT(epetraInArgs_inout);
01065   TEUCHOS_ASSERT(epetraUnscaledOutArgs_inout);
01066 #endif
01067 
01068   EpetraExt::ModelEvaluator::InArgs
01069     &epetraInArgs = *epetraInArgs_inout;
01070   EpetraExt::ModelEvaluator::OutArgs
01071     &epetraUnscaledOutArgs = *epetraUnscaledOutArgs_inout;
01072 
01073   if (
01074     ( stateFunctionScaling_ == STATE_FUNC_SCALING_ROW_SUM )
01075     &&
01076     (
01077       epetraUnscaledOutArgs.supports(EME::OUT_ARG_f) 
01078       &&
01079       epetraUnscaledOutArgs.funcOrDerivesAreSet(EME::OUT_ARG_f)
01080       )
01081     &&
01082     (
01083       epetraUnscaledOutArgs.supports(EME::OUT_ARG_W)
01084       &&
01085       is_null(epetraUnscaledOutArgs.get_W())
01086       )
01087     )
01088   {
01089     // This is the first pass through with scaling turned on and the client
01090     // turned on automatic scaling but did not ask for W.  We must compute W
01091     // in order to compute the scale factors so we must allocate a temporary W
01092     // just to compute the scale factors and then throw it away.  If the
01093     // client wants to evaluate W at the same point, then it should have
01094     // passed W in but that is not our problem here.  The ModelEvaluator
01095     // relies on the client to set up the calls to allow for efficient
01096     // evaluation.
01097 
01098     if(out.get() && verbLevel >= Teuchos::VERB_LOW)
01099       *out
01100         << "\nCreating a temporary Epetra W to compute scale factors"
01101         << " for f(...) ...\n";
01102     epetraUnscaledOutArgs.set_W(create_and_assert_W(*epetraModel_));
01103     if( epetraInArgs.supports(EME::IN_ARG_beta) )
01104       epetraInArgs.set_beta(1.0);
01105     if( epetraInArgs.supports(EME::IN_ARG_alpha) )
01106       epetraInArgs.set_alpha(0.0);
01107   }
01108   
01109 }
01110 
01111 
01112 void ThyraAdaptiveModelEvaluator::postEvalScalingSetup(
01113   const EpetraExt::ModelEvaluator::OutArgs &epetraUnscaledOutArgs,
01114   const RCP<Teuchos::FancyOStream> &out,
01115   const Teuchos::EVerbosityLevel verbLevel
01116   ) const
01117 {
01118 
01119   using Teuchos::OSTab;
01120   using Teuchos::rcp;
01121   using Teuchos::rcp_const_cast;
01122   using Teuchos::includesVerbLevel;
01123 
01124   // Compute the scale factors for the state function f(...)
01125   switch(stateFunctionScaling_) {
01126 
01127     case STATE_FUNC_SCALING_ROW_SUM: {
01128 
01129       // Compute the inverse row-sum scaling from W
01130 
01131       const RCP<Epetra_RowMatrix>
01132         ermW = get_Epetra_RowMatrix(epetraUnscaledOutArgs);
01133       // Note: Above, we get the Epetra W object directly from the Epetra
01134       // OutArgs object since this might be a temporary matrix just to
01135       // compute scaling factors.  In this case, the stack funtion variable
01136       // eW might be empty!
01137 
01138       RCP<Epetra_Vector>
01139         invRowSums = rcp(new Epetra_Vector(ermW->OperatorRangeMap()));
01140       // Above: From the documentation is seems that the RangeMap should be
01141       // okay but who knows for sure!
01142 
01143       ermW->InvRowSums(*invRowSums);
01144 
01145       if (out.get() && includesVerbLevel(verbLevel,Teuchos::VERB_LOW)) {
01146         *out
01147           << "\nComputed inverse row sum scaling from W that"
01148           " will be used to scale f(...) and its derivatives:\n";
01149         double minVal = 0, maxVal = 0, avgVal = 0;
01150         invRowSums->MinValue(&minVal);
01151         invRowSums->MaxValue(&maxVal);
01152         invRowSums->MeanValue(&avgVal);
01153         OSTab tab(out);
01154         *out
01155           << "min(invRowSums) = " << minVal << "\n"
01156           << "max(invRowSums) = " << maxVal << "\n"
01157           << "avg(invRowSums) = " << avgVal << "\n";
01158       }
01159 
01160       stateFunctionScalingVec_ = invRowSums;
01161 
01162       break;
01163 
01164     }
01165 
01166     default:
01167       TEUCHOS_TEST_FOR_EXCEPT("Should never get here!");
01168 
01169   }
01170 
01171   epetraOutArgsScaling_ = epetraModel_->createOutArgs();
01172 
01173   epetraOutArgsScaling_.set_f(
01174     rcp_const_cast<Epetra_Vector>(stateFunctionScalingVec_) );
01175 
01176 }
01177 
01178 
01179 void ThyraAdaptiveModelEvaluator::finishConvertingOutArgsFromEpetraToThyra(
01180   const EpetraExt::ModelEvaluator::OutArgs &epetraOutArgs,
01181   RCP<LinearOpBase<double> > &W_op,
01182   RCP<EpetraLinearOp> &efwdW,
01183   RCP<Epetra_Operator> &eW,
01184   const ModelEvaluatorBase::OutArgs<double> &outArgs
01185   ) const
01186 {
01187 
01188   using Teuchos::rcp_dynamic_cast;
01189   typedef EpetraExt::ModelEvaluator EME;
01190 
01191   if (nonnull(efwdW)) {
01192     efwdW->setFullyInitialized(true); 
01193     // NOTE: Above will directly update W_op also if W.get()==NULL!
01194   }
01195 
01196   if (nonnull(W_op)) {
01197     if (W_op.shares_resource(efwdW)) {
01198       // W_op was already updated above since *efwdW is the same object as *W_op
01199     }
01200     else {
01201       rcp_dynamic_cast<EpetraLinearOp>(W_op, true)->setFullyInitialized(true);
01202     }
01203   }
01204   
01205 }
01206 
01207 
01208 void ThyraAdaptiveModelEvaluator::updateNominalValuesAndBounds() const
01209 {
01210 
01211   using Teuchos::rcp;
01212   using Teuchos::implicit_cast;
01213   typedef ModelEvaluatorBase MEB;
01214   typedef EpetraExt::ModelEvaluator EME;
01215 
01216   if( !nominalValuesAndBoundsAreUpdated_ ) {
01217 
01218     // Gather the nominal values and bounds into Epetra InArgs objects
01219 
01220     EME::InArgs epetraOrigNominalValues;
01221     EpetraExt::gatherModelNominalValues(
01222       *epetraModel_, &epetraOrigNominalValues );
01223 
01224     EME::InArgs epetraOrigLowerBounds;
01225     EME::InArgs epetraOrigUpperBounds;
01226     EpetraExt::gatherModelBounds(
01227       *epetraModel_, &epetraOrigLowerBounds, &epetraOrigUpperBounds );
01228 
01229     // Set up Epetra InArgs scaling object
01230 
01231     epetraInArgsScaling_ = epetraModel_->createInArgs();
01232 
01233     if( !is_null(stateVariableScalingVec_) ) {
01234       invStateVariableScalingVec_
01235         = EpetraExt::createInverseModelScalingVector(stateVariableScalingVec_);
01236       if( epetraOrigNominalValues.supports(EME::IN_ARG_x_dot) ) {
01237         epetraInArgsScaling_.set_x_dot(invStateVariableScalingVec_);
01238       }
01239       if( epetraOrigNominalValues.supports(EME::IN_ARG_x) ) {
01240         epetraInArgsScaling_.set_x(invStateVariableScalingVec_);
01241       }
01242     }
01243     
01244     // Scale the original variables and bounds
01245 
01246     EME::InArgs epetraScaledNominalValues = epetraModel_->createInArgs();
01247     EpetraExt::scaleModelVars(
01248       epetraOrigNominalValues, epetraInArgsScaling_, &epetraScaledNominalValues
01249       );
01250 
01251     EME::InArgs epetraScaledLowerBounds = epetraModel_->createInArgs();
01252     EME::InArgs epetraScaledUpperBounds = epetraModel_->createInArgs();
01253     EpetraExt::scaleModelBounds(
01254       epetraOrigLowerBounds, epetraOrigUpperBounds, epetraModel_->getInfBound(),
01255       epetraInArgsScaling_,
01256       &epetraScaledLowerBounds, &epetraScaledUpperBounds
01257       );
01258 
01259     // Wrap the scaled epetra InArgs objects as Thyra InArgs objects!
01260 
01261     nominalValues_ = this->createInArgs();
01262     lowerBounds_ = this->createInArgs();
01263     upperBounds_ = this->createInArgs();
01264     convertInArgsFromEpetraToThyra(epetraScaledNominalValues, &nominalValues_);
01265     convertInArgsFromEpetraToThyra(epetraScaledLowerBounds, &lowerBounds_);
01266     convertInArgsFromEpetraToThyra(epetraScaledUpperBounds, &upperBounds_);
01267 
01268     nominalValuesAndBoundsAreUpdated_ = true;
01269 
01270   }
01271   else {
01272 
01273     // The nominal values and bounds should already be updated an should have
01274     // the currect scaling!
01275 
01276   }
01277 
01278 }
01279 
01280 
01281 void ThyraAdaptiveModelEvaluator::updateInArgsOutArgs() const
01282 {
01283 
01284   typedef EpetraExt::ModelEvaluator EME;
01285 
01286   const EpetraExt::ModelEvaluator &epetraModel = *epetraModel_;
01287   EME::InArgs  epetraInArgs  = epetraModel.createInArgs();
01288   EME::OutArgs epetraOutArgs = epetraModel.createOutArgs();
01289   const int l_Np = epetraOutArgs.Np();
01290   const int l_Ng = epetraOutArgs.Ng();
01291 
01292   //
01293   // InArgs
01294   //
01295 
01296   InArgsSetup<double> inArgs;
01297   inArgs.setModelEvalDescription(this->description());
01298   inArgs.set_Np(epetraInArgs.Np());
01299   inArgs.setSupports(IN_ARG_x_dot, epetraInArgs.supports(EME::IN_ARG_x_dot));
01300   inArgs.setSupports(IN_ARG_x, epetraInArgs.supports(EME::IN_ARG_x));
01301 #ifdef HAVE_THYRA_ME_POLYNOMIAL
01302   inArgs.setSupports(IN_ARG_x_dot_poly,
01303     epetraInArgs.supports(EME::IN_ARG_x_dot_poly));
01304   inArgs.setSupports(IN_ARG_x_poly, epetraInArgs.supports(EME::IN_ARG_x_poly));
01305 #endif // HAVE_THYRA_ME_POLYNOMIAL
01306   inArgs.setSupports(IN_ARG_t, epetraInArgs.supports(EME::IN_ARG_t));
01307   inArgs.setSupports(IN_ARG_alpha, epetraInArgs.supports(EME::IN_ARG_alpha));
01308   inArgs.setSupports(IN_ARG_beta, epetraInArgs.supports(EME::IN_ARG_beta));
01309   prototypeInArgs_ = inArgs;
01310 
01311   //
01312   // OutArgs
01313   //
01314 
01315   OutArgsSetup<double> outArgs;
01316   outArgs.setModelEvalDescription(this->description());
01317   outArgs.set_Np_Ng(l_Np, l_Ng);
01318   // f
01319   outArgs.setSupports(OUT_ARG_f, epetraOutArgs.supports(EME::OUT_ARG_f));
01320   if (outArgs.supports(OUT_ARG_f)) {
01321     // W_op
01322     outArgs.setSupports(OUT_ARG_W_op,  epetraOutArgs.supports(EME::OUT_ARG_W));
01323     outArgs.set_W_properties(convert(epetraOutArgs.get_W_properties()));
01324     // DfDp
01325     for(int l=0; l<l_Np; ++l) {
01326       outArgs.setSupports(OUT_ARG_DfDp, l,
01327         convert(epetraOutArgs.supports(EME::OUT_ARG_DfDp, l)));
01328       if(!outArgs.supports(OUT_ARG_DfDp, l).none())
01329         outArgs.set_DfDp_properties(l,
01330           convert(epetraOutArgs.get_DfDp_properties(l)));
01331     }
01332   }
01333   // DgDx_dot and DgDx
01334   for(int j=0; j<l_Ng; ++j) {
01335     if (inArgs.supports(IN_ARG_x_dot))
01336       outArgs.setSupports(OUT_ARG_DgDx_dot, j,
01337         convert(epetraOutArgs.supports(EME::OUT_ARG_DgDx_dot, j)));
01338     if(!outArgs.supports(OUT_ARG_DgDx_dot, j).none())
01339       outArgs.set_DgDx_dot_properties(j,
01340         convert(epetraOutArgs.get_DgDx_dot_properties(j)));
01341     if (inArgs.supports(IN_ARG_x))
01342       outArgs.setSupports(OUT_ARG_DgDx, j,
01343         convert(epetraOutArgs.supports(EME::OUT_ARG_DgDx, j)));
01344     if(!outArgs.supports(OUT_ARG_DgDx, j).none())
01345       outArgs.set_DgDx_properties(j,
01346         convert(epetraOutArgs.get_DgDx_properties(j)));
01347   }
01348   // DgDp
01349   for(int j=0; j < l_Ng; ++j) for(int l=0; l < l_Np; ++l) {
01350     const EME::DerivativeSupport epetra_DgDp_j_l_support =
01351       epetraOutArgs.supports(EME::OUT_ARG_DgDp, j, l);
01352     outArgs.setSupports(OUT_ARG_DgDp, j, l,
01353       convert(epetra_DgDp_j_l_support));
01354     if(!outArgs.supports(OUT_ARG_DgDp, j, l).none())
01355       outArgs.set_DgDp_properties(j, l,
01356         convert(epetraOutArgs.get_DgDp_properties(j, l)));
01357   }
01358 #ifdef HAVE_THYRA_ME_POLYNOMIAL
01359   outArgs.setSupports(OUT_ARG_f_poly,
01360     epetraOutArgs.supports(EME::OUT_ARG_f_poly));
01361 #endif // HAVE_THYRA_ME_POLYNOMIAL
01362   prototypeOutArgs_ = outArgs;
01363 
01364   // We are current!
01365   currentInArgsOutArgs_ = true;
01366 
01367 }
01368 
01369 
01370 RCP<EpetraLinearOp>
01371 ThyraAdaptiveModelEvaluator::create_epetra_W_op() const
01372 {
01373   return Thyra::partialNonconstEpetraLinearOp(
01374     this->get_f_space(), this->get_x_space(),
01375     create_and_assert_W(*epetraModel_)
01376     );
01377 }
01378 
01379 
01380 } // namespace AAdapt
01381 

Generated on Wed Mar 26 2014 18:36:35 for Albany: a Trilinos-based PDE code by  doxygen 1.7.1