void eval_model_explicit( const Thyra::ModelEvaluator<Scalar> &model, Thyra::ModelEvaluatorBase::InArgs<Scalar> &basePoint, const VectorBase<Scalar>& x_in, const typename Thyra::ModelEvaluatorBase::InArgs<Scalar>::ScalarMag &t_in, const Ptr<VectorBase<Scalar> >& f_out ) { typedef Thyra::ModelEvaluatorBase MEB; MEB::InArgs<Scalar> inArgs = model.createInArgs(); MEB::OutArgs<Scalar> outArgs = model.createOutArgs(); inArgs.setArgs(basePoint); inArgs.set_x(Teuchos::rcp(&x_in,false)); if (inArgs.supports(MEB::IN_ARG_t)) { inArgs.set_t(t_in); } // For model evaluators whose state function f(x, x_dot, t) describes // an implicit ODE, and which accept an optional x_dot input argument, // make sure the latter is set to null in order to request the evaluation // of a state function corresponding to the explicit ODE formulation // x_dot = f(x, t) if (inArgs.supports(MEB::IN_ARG_x_dot)) { inArgs.set_x_dot(Teuchos::null); } outArgs.set_f(Teuchos::rcp(&*f_out,false)); model.evalModel(inArgs,outArgs); }
Thyra::ModelEvaluatorBase::InArgs<Scalar> ExplicitModelEvaluator<Scalar>:: getNominalValues() const { typedef Thyra::ModelEvaluatorBase MEB; MEB::InArgs<Scalar> nomVals = createInArgs(); nomVals.setArgs(this->getUnderlyingModel()->getNominalValues(),true); return nomVals; }
void eval_model_explicit( const Thyra::ModelEvaluator<Scalar> &model, Thyra::ModelEvaluatorBase::InArgs<Scalar> &basePoint, const VectorBase<Scalar>& x_in, const typename Thyra::ModelEvaluatorBase::InArgs<Scalar>::ScalarMag &t_in, const Ptr<VectorBase<Scalar> >& f_out ) { typedef Thyra::ModelEvaluatorBase MEB; MEB::InArgs<Scalar> inArgs = model.createInArgs(); MEB::OutArgs<Scalar> outArgs = model.createOutArgs(); inArgs.setArgs(basePoint); inArgs.set_x(Teuchos::rcp(&x_in,false)); if (inArgs.supports(MEB::IN_ARG_t)) { inArgs.set_t(t_in); } outArgs.set_f(Teuchos::rcp(&*f_out,false)); model.evalModel(inArgs,outArgs); }
void restart( StepperBase<Scalar> *stepper ) { #ifdef RYTHMOS_DEBUG TEST_FOR_EXCEPT(0==stepper); #endif // RYTHMOS_DEBUG typedef Thyra::ModelEvaluatorBase MEB; const Rythmos::StepStatus<double> stepStatus = stepper->getStepStatus(); const RCP<const Thyra::ModelEvaluator<Scalar> > model = stepper->getModel(); // First, copy all of the model's state, including parameter values etc. MEB::InArgs<double> initialCondition = model->createInArgs(); initialCondition.setArgs(model->getNominalValues()); // Set the current values of the state and time RCP<const Thyra::VectorBase<double> > x, x_dot; Rythmos::get_x_and_x_dot(*stepper,stepStatus.time,&x,&x_dot); initialCondition.set_x(x); initialCondition.set_x_dot(x_dot); initialCondition.set_t(stepStatus.time); // Set the new initial condition back on the stepper. This will effectively // reset the stepper to think that it is starting over again (which it is). stepper->setInitialCondition(initialCondition); }
void DiagonalImplicitRKModelEvaluator<Scalar>::evalModelImpl( const Thyra::ModelEvaluatorBase::InArgs<Scalar>& inArgs_stage, const Thyra::ModelEvaluatorBase::OutArgs<Scalar>& outArgs_stage ) const { typedef ScalarTraits<Scalar> ST; typedef Thyra::ModelEvaluatorBase MEB; TEUCHOS_TEST_FOR_EXCEPTION( !isInitialized_, std::logic_error, "Error! initializeDIRKModel must be called before evalModel\n" ); TEUCHOS_TEST_FOR_EXCEPTION( !setTimeStepPointCalled_, std::logic_error, "Error! setTimeStepPoint must be called before evalModel" ); TEUCHOS_TEST_FOR_EXCEPTION( currentStage_ == -1, std::logic_error, "Error! setCurrentStage must be called before evalModel" ); THYRA_MODEL_EVALUATOR_DECORATOR_EVAL_MODEL_GEN_BEGIN( "Rythmos::DiagonalImplicitRKModelEvaluator",inArgs_stage,outArgs_stage,daeModel_ ); // // A) Unwrap the inArgs and outArgs // const RCP<const Thyra::VectorBase<Scalar> > x_in = inArgs_stage.get_x(); const RCP<Thyra::VectorBase<Scalar> > f_out = outArgs_stage.get_f(); const RCP<Thyra::LinearOpBase<Scalar> > W_op_out = outArgs_stage.get_W_op(); // // B) Assemble f_out and W_op_out for given stage // MEB::InArgs<Scalar> daeInArgs = daeModel_->createInArgs(); MEB::OutArgs<Scalar> daeOutArgs = daeModel_->createOutArgs(); const RCP<Thyra::VectorBase<Scalar> > x_i = createMember(daeModel_->get_x_space()); daeInArgs.setArgs(basePoint_); // B.1) Setup the DAE's inArgs for stage f(currentStage_) ... V_V(stage_derivatives_->getNonconstVectorBlock(currentStage_).ptr(),*x_in); assembleIRKState( currentStage_, dirkButcherTableau_->A(), delta_t_, *x_old_, *stage_derivatives_, outArg(*x_i) ); daeInArgs.set_x( x_i ); daeInArgs.set_x_dot( x_in ); daeInArgs.set_t( t_old_ + dirkButcherTableau_->c()(currentStage_) * delta_t_ ); daeInArgs.set_alpha(ST::one()); daeInArgs.set_beta( delta_t_ * dirkButcherTableau_->A()(currentStage_,currentStage_) ); // B.2) Setup the DAE's outArgs for stage f(i) ... if (!is_null(f_out)) daeOutArgs.set_f( f_out ); if (!is_null(W_op_out)) daeOutArgs.set_W_op(W_op_out); // B.3) Compute f_out(i) and/or W_op_out ... daeModel_->evalModel( daeInArgs, daeOutArgs ); daeOutArgs.set_f(Teuchos::null); daeOutArgs.set_W_op(Teuchos::null); THYRA_MODEL_EVALUATOR_DECORATOR_EVAL_MODEL_END(); }
void DefaultModelEvaluatorWithSolveFactory<Scalar>::evalModelImpl( const ModelEvaluatorBase::InArgs<Scalar> &inArgs, const ModelEvaluatorBase::OutArgs<Scalar> &outArgs ) const { typedef ModelEvaluatorBase MEB; using Teuchos::rcp; using Teuchos::rcp_const_cast; using Teuchos::rcp_dynamic_cast; using Teuchos::OSTab; THYRA_MODEL_EVALUATOR_DECORATOR_EVAL_MODEL_BEGIN( "Thyra::DefaultModelEvaluatorWithSolveFactory",inArgs,outArgs ); Teuchos::Time timer(""); typedef Teuchos::VerboseObjectTempState<LinearOpWithSolveFactoryBase<Scalar> > VOTSLOWSF; VOTSLOWSF W_factory_outputTempState(W_factory_,out,verbLevel); // InArgs MEB::InArgs<Scalar> wrappedInArgs = thyraModel->createInArgs(); wrappedInArgs.setArgs(inArgs,true); // OutArgs MEB::OutArgs<Scalar> wrappedOutArgs = thyraModel->createOutArgs(); wrappedOutArgs.setArgs(outArgs,true); RCP<LinearOpWithSolveBase<Scalar> > W; RCP<const LinearOpBase<Scalar> > fwdW; if( outArgs.supports(MEB::OUT_ARG_W) && (W = outArgs.get_W()).get() ) { Thyra::uninitializeOp<Scalar>(*W_factory_, W.ptr(), outArg(fwdW)); { // Handle this case later if we need to! const bool both_W_and_W_op_requested = nonnull(outArgs.get_W_op()); TEUCHOS_TEST_FOR_EXCEPT(both_W_and_W_op_requested); } RCP<LinearOpBase<Scalar> > nonconst_fwdW; if(fwdW.get()) { nonconst_fwdW = rcp_const_cast<LinearOpBase<Scalar> >(fwdW); } else { nonconst_fwdW = thyraModel->create_W_op(); fwdW = nonconst_fwdW; } wrappedOutArgs.set_W_op(nonconst_fwdW); } // Do the evaluation if(out.get() && includesVerbLevel(verbLevel,Teuchos::VERB_LOW)) *out << "\nEvaluating the output functions on model \'" << thyraModel->description() << "\' ...\n"; timer.start(true); thyraModel->evalModel(wrappedInArgs,wrappedOutArgs); timer.stop(); if(out.get() && includesVerbLevel(verbLevel,Teuchos::VERB_LOW)) OSTab(out).o() << "\nTime to evaluate underlying model = " << timer.totalElapsedTime()<<" sec\n"; // Postprocess arguments if(out.get() && includesVerbLevel(verbLevel,Teuchos::VERB_LOW)) *out << "\nPost processing the output objects ...\n"; timer.start(true); if( W.get() ) { Thyra::initializeOp<Scalar>(*W_factory_, fwdW, W.ptr()); W->setVerbLevel(this->getVerbLevel()); W->setOStream(this->getOStream()); } timer.stop(); if(out.get() && includesVerbLevel(verbLevel,Teuchos::VERB_LOW)) OSTab(out).o() << "\nTime to process output objects = " << timer.totalElapsedTime()<<" sec\n"; THYRA_MODEL_EVALUATOR_DECORATOR_EVAL_MODEL_END(); }
void TimeDiscretizedBackwardEulerModelEvaluator<Scalar>::evalModelImpl( const Thyra::ModelEvaluatorBase::InArgs<Scalar>& inArgs_bar, const Thyra::ModelEvaluatorBase::OutArgs<Scalar>& outArgs_bar ) const { using Teuchos::rcp_dynamic_cast; typedef ScalarTraits<Scalar> ST; typedef Thyra::ModelEvaluatorBase MEB; typedef Thyra::VectorBase<Scalar> VB; typedef Thyra::ProductVectorBase<Scalar> PVB; typedef Thyra::BlockedLinearOpBase<Scalar> BLWB; /* THYRA_MODEL_EVALUATOR_DECORATOR_EVAL_MODEL_GEN_BEGIN( "Rythmos::ImplicitRKModelEvaluator",inArgs_bar,outArgs_bar,daeModel_ ); */ TEST_FOR_EXCEPTION( delta_t_ <= 0.0, std::logic_error, "Error, you have not initialized this object correctly!" ); // // A) Unwrap the inArgs and outArgs to get at product vectors and block op // const RCP<const PVB> x_bar = rcp_dynamic_cast<const PVB>(inArgs_bar.get_x(), true); const RCP<PVB> f_bar = rcp_dynamic_cast<PVB>(outArgs_bar.get_f(), true); RCP<BLWB> W_op_bar = rcp_dynamic_cast<BLWB>(outArgs_bar.get_W_op(), true); // // B) Assemble f_bar and W_op_bar by looping over stages // MEB::InArgs<Scalar> daeInArgs = daeModel_->createInArgs(); MEB::OutArgs<Scalar> daeOutArgs = daeModel_->createOutArgs(); const RCP<VB> x_dot_i = createMember(daeModel_->get_x_space()); daeInArgs.setArgs(initCond_); Scalar t_i = initTime_; // ToDo: Define t_init! const Scalar oneOverDeltaT = 1.0/delta_t_; for ( int i = 0; i < numTimeSteps_; ++i ) { // B.1) Setup the DAE's inArgs for time step eqn f(i) ... const RCP<const Thyra::VectorBase<Scalar> > x_i = x_bar->getVectorBlock(i), x_im1 = ( i==0 ? initCond_.get_x() : x_bar->getVectorBlock(i-1) ); V_VmV( x_dot_i.ptr(), *x_i, *x_im1 ); // x_dot_i = 1/dt * ( x[i] - x[i-1] ) Vt_S( x_dot_i.ptr(), oneOverDeltaT ); // ... daeInArgs.set_x_dot( x_dot_i ); daeInArgs.set_x( x_i ); daeInArgs.set_t( t_i ); daeInArgs.set_alpha( oneOverDeltaT ); daeInArgs.set_beta( 1.0 ); // B.2) Setup the DAE's outArgs for f(i) and/or W(i,i) ... if (!is_null(f_bar)) daeOutArgs.set_f( f_bar->getNonconstVectorBlock(i) ); if (!is_null(W_op_bar)) daeOutArgs.set_W_op(W_op_bar->getNonconstBlock(i,i).assert_not_null()); // B.3) Compute f_bar(i) and/or W_op_bar(i,i) ... daeModel_->evalModel( daeInArgs, daeOutArgs ); daeOutArgs.set_f(Teuchos::null); daeOutArgs.set_W_op(Teuchos::null); // B.4) Evaluate W_op_bar(i,i-1) if ( !is_null(W_op_bar) && i > 0 ) { daeInArgs.set_alpha( -oneOverDeltaT ); daeInArgs.set_beta( 0.0 ); daeOutArgs.set_W_op(W_op_bar->getNonconstBlock(i,i-1).assert_not_null()); daeModel_->evalModel( daeInArgs, daeOutArgs ); daeOutArgs.set_W_op(Teuchos::null); } // t_i += delta_t_; } /* THYRA_MODEL_EVALUATOR_DECORATOR_EVAL_MODEL_END(); */ }
void DefaultStateEliminationModelEvaluator<Scalar>::evalModelImpl( const ModelEvaluatorBase::InArgs<Scalar> &inArgs, const ModelEvaluatorBase::OutArgs<Scalar> &outArgs ) const { typedef ModelEvaluatorBase MEB; using Teuchos::RCP; using Teuchos::rcp; using Teuchos::rcp_const_cast; using Teuchos::rcp_dynamic_cast; using Teuchos::OSTab; Teuchos::Time totalTimer(""), timer(""); totalTimer.start(true); const Teuchos::RCP<Teuchos::FancyOStream> out = this->getOStream(); const Teuchos::EVerbosityLevel verbLevel = this->getVerbLevel(); Teuchos::OSTab tab(out); if(out.get() && static_cast<int>(verbLevel) >= static_cast<int>(Teuchos::VERB_LOW)) *out << "\nEntering Thyra::DefaultStateEliminationModelEvaluator<Scalar>::evalModel(...) ...\n"; const Teuchos::RCP<const ModelEvaluator<Scalar> > thyraModel = this->getUnderlyingModel(); const int Np = outArgs.Np(), Ng = outArgs.Ng(); // Get the intial state guess if not already gotten if (is_null(x_guess_solu_)) { const ModelEvaluatorBase::InArgs<Scalar> nominalValues = thyraModel->getNominalValues(); if(nominalValues.get_x().get()) { x_guess_solu_ = nominalValues.get_x()->clone_v(); } else { x_guess_solu_ = createMember(thyraModel->get_x_space()); assign(&*x_guess_solu_,Scalar(0.0)); } } // Reset the nominal values MEB::InArgs<Scalar> wrappedNominalValues = thyraModel->getNominalValues(); wrappedNominalValues.setArgs(inArgs,true); wrappedNominalValues.set_x(x_guess_solu_); typedef Teuchos::VerboseObjectTempState<ModelEvaluatorBase> VOTSME; //VOTSME thyraModel_outputTempState(rcp(&wrappedThyraModel,false),out,verbLevel); typedef Teuchos::VerboseObjectTempState<NonlinearSolverBase<Scalar> > VOTSNSB; VOTSNSB statSolver_outputTempState( stateSolver_,out ,static_cast<int>(verbLevel) >= static_cast<int>(Teuchos::VERB_LOW) ? Teuchos::VERB_LOW : Teuchos::VERB_NONE ); if(out.get() && static_cast<int>(verbLevel) >= static_cast<int>(Teuchos::VERB_EXTREME)) *out << "\ninArgs =\n" << Teuchos::describe(inArgs,verbLevel) << "\noutArgs on input =\n" << Teuchos::describe(outArgs,Teuchos::VERB_LOW); if(out.get() && static_cast<int>(verbLevel) >= static_cast<int>(Teuchos::VERB_LOW)) *out << "\nSolving f(x,...) for x ...\n"; wrappedThyraModel_->setNominalValues( rcp(new MEB::InArgs<Scalar>(wrappedNominalValues)) ); SolveStatus<Scalar> solveStatus = stateSolver_->solve(&*x_guess_solu_,NULL); if( solveStatus.solveStatus == SOLVE_STATUS_CONVERGED ) { if(out.get() && static_cast<int>(verbLevel) >= static_cast<int>(Teuchos::VERB_LOW)) *out << "\nComputing the output functions at the solved state solution ...\n"; MEB::InArgs<Scalar> wrappedInArgs = thyraModel->createInArgs(); MEB::OutArgs<Scalar> wrappedOutArgs = thyraModel->createOutArgs(); wrappedInArgs.setArgs(inArgs,true); wrappedInArgs.set_x(x_guess_solu_); wrappedOutArgs.setArgs(outArgs,true); for( int l = 0; l < Np; ++l ) { for( int j = 0; j < Ng; ++j ) { if( outArgs.supports(MEB::OUT_ARG_DgDp,j,l).none()==false && outArgs.get_DgDp(j,l).isEmpty()==false ) { // Set DfDp(l) and DgDx(j) to be computed! //wrappedOutArgs.set_DfDp(l,...); //wrappedOutArgs.set_DgDx(j,...); TEST_FOR_EXCEPT(true); } } } thyraModel->evalModel(wrappedInArgs,wrappedOutArgs); // // Compute DgDp(j,l) using direct sensitivties // for( int l = 0; l < Np; ++l ) { if( wrappedOutArgs.supports(MEB::OUT_ARG_DfDp,l).none()==false && wrappedOutArgs.get_DfDp(l).isEmpty()==false ) { // // Compute: D(l) = -inv(DfDx)*DfDp(l) // TEST_FOR_EXCEPT(true); for( int j = 0; j < Ng; ++j ) { if( outArgs.supports(MEB::OUT_ARG_DgDp,j,l).none()==false && outArgs.get_DgDp(j,l).isEmpty()==false ) { // // Compute: DgDp(j,l) = DgDp(j,l) + DgDx(j)*D // TEST_FOR_EXCEPT(true); } } } } // ToDo: Add a mode to compute DgDp(l) using adjoint sensitivities? } else { if(out.get() && static_cast<int>(verbLevel) >= static_cast<int>(Teuchos::VERB_LOW)) *out << "\nFailed to converge, returning NaNs ...\n"; outArgs.setFailed(); } if(out.get() && static_cast<int>(verbLevel) >= static_cast<int>(Teuchos::VERB_EXTREME)) *out << "\noutArgs on output =\n" << Teuchos::describe(outArgs,verbLevel); totalTimer.stop(); if(out.get() && static_cast<int>(verbLevel) >= static_cast<int>(Teuchos::VERB_LOW)) *out << "\nTotal evaluation time = "<<totalTimer.totalElapsedTime()<<" sec\n" << "\nLeaving Thyra::DefaultStateEliminationModelEvaluator<Scalar>::evalModel(...) ...\n"; }
int main(int argc, char *argv[]) { using std::endl; typedef double Scalar; typedef double ScalarMag; using Teuchos::describe; using Teuchos::RCP; using Teuchos::rcp; using Teuchos::rcp_implicit_cast; using Teuchos::rcp_dynamic_cast; using Teuchos::as; using Teuchos::ParameterList; using Teuchos::CommandLineProcessor; typedef Teuchos::ParameterList::PrintOptions PLPrintOptions; typedef Thyra::ModelEvaluatorBase MEB; using Thyra::createMember; using Thyra::createMembers; bool success = true; Teuchos::GlobalMPISession mpiSession(&argc,&argv); RCP<Epetra_Comm> epetra_comm; #ifdef HAVE_MPI epetra_comm = rcp( new Epetra_MpiComm(MPI_COMM_WORLD) ); #else epetra_comm = rcp( new Epetra_SerialComm ); #endif // HAVE_MPI RCP<Teuchos::FancyOStream> out = Teuchos::VerboseObjectBase::getDefaultOStream(); try { // // A) Read commandline options // CommandLineProcessor clp; clp.throwExceptions(false); clp.addOutputSetupOptions(true); std::string paramsFileName = ""; clp.setOption( "params-file", ¶msFileName, "File name for XML parameters" ); std::string extraParamsString = ""; clp.setOption( "extra-params", &extraParamsString, "Extra XML parameter string" ); Teuchos::EVerbosityLevel verbLevel = Teuchos::VERB_DEFAULT; setVerbosityLevelOption( "verb-level", &verbLevel, "Top-level verbosity level. By default, this gets deincremented as you go deeper into numerical objects.", &clp ); double finalTime = 1.0; clp.setOption( "final-time", &finalTime, "Final time (the inital time)" ); int numTimeSteps = 2; clp.setOption( "num-time-steps", &numTimeSteps, "Number of time steps" ); bool dumpFinalSolutions = false; clp.setOption( "dump-final-solutions", "no-dump-final-solutions", &dumpFinalSolutions, "Determine if the final solutions are dumpped or not." ); double maxStateError = 1e-6; clp.setOption( "max-state-error", &maxStateError, "The maximum allowed error in the integrated state in relation to the exact state solution" ); // ToDo: Read in more parameters CommandLineProcessor::EParseCommandLineReturn parse_return = clp.parse(argc,argv); if( parse_return != CommandLineProcessor::PARSE_SUCCESSFUL ) return parse_return; if ( Teuchos::VERB_DEFAULT == verbLevel ) verbLevel = Teuchos::VERB_LOW; const Teuchos::EVerbosityLevel solnVerbLevel = ( dumpFinalSolutions ? Teuchos::VERB_EXTREME : verbLevel ); // // B) Get the base parameter list that all other parameter lists will be // read from. // RCP<ParameterList> paramList = Teuchos::parameterList(); if (paramsFileName.length()) updateParametersFromXmlFile( paramsFileName, &*paramList ); if (extraParamsString.length()) updateParametersFromXmlString( extraParamsString, &*paramList ); paramList->validateParameters(*getValidParameters()); // // C) Create the Stratimikos linear solver factories. // // Get the linear solve strategy that will be used to solve for the linear // system with the dae's W matrix. Stratimikos::DefaultLinearSolverBuilder daeLinearSolverBuilder; daeLinearSolverBuilder.setParameterList(sublist(paramList,DAELinearSolver_name)); RCP<Thyra::LinearOpWithSolveFactoryBase<Scalar> > daeLOWSF = createLinearSolveStrategy(daeLinearSolverBuilder); // Get the linear solve strategy that can be used to override the overall // linear system solve Stratimikos::DefaultLinearSolverBuilder overallLinearSolverBuilder; overallLinearSolverBuilder.setParameterList(sublist(paramList,OverallLinearSolver_name)); RCP<Thyra::LinearOpWithSolveFactoryBase<Scalar> > overallLOWSF = createLinearSolveStrategy(overallLinearSolverBuilder); // // D) Create the underlying EpetraExt::ModelEvaluator // RCP<EpetraExt::DiagonalTransientModel> epetraDaeModel = EpetraExt::diagonalTransientModel( epetra_comm, sublist(paramList,DiagonalTransientModel_name) ); *out <<"\nepetraDaeModel valid options:\n"; epetraDaeModel->getValidParameters()->print( *out, PLPrintOptions().indent(2).showTypes(true).showDoc(true) ); // // E) Create the Thyra-wrapped ModelEvaluator // RCP<Thyra::ModelEvaluator<double> > daeModel = epetraModelEvaluator(epetraDaeModel,daeLOWSF); // // F) Create the TimeDiscretizedBackwardEulerModelEvaluator // MEB::InArgs<Scalar> initCond = daeModel->createInArgs(); initCond.setArgs(daeModel->getNominalValues()); RCP<Thyra::ModelEvaluator<Scalar> > discretizedModel = Rythmos::timeDiscretizedBackwardEulerModelEvaluator<Scalar>( daeModel, initCond, finalTime, numTimeSteps, overallLOWSF ); *out << "\ndiscretizedModel = " << describe(*discretizedModel,verbLevel); // // F) Setup a nonlinear solver and solve the system // // F.1) Setup a nonlinear solver Thyra::DampenedNewtonNonlinearSolver<Scalar> nonlinearSolver; nonlinearSolver.setOStream(out); nonlinearSolver.setVerbLevel(verbLevel); //nonlinearSolver.setParameterList(sublist(paramList,NonlinearSolver_name)); //2007/11/27: rabartl: ToDo: Implement parameter list handling for //DampenedNonlinearSolve so that I can uncomment the above line. nonlinearSolver.setModel(discretizedModel); // F.2) Solve the system RCP<Thyra::VectorBase<Scalar> > x_bar = createMember(discretizedModel->get_x_space()); V_S( x_bar.ptr(), 0.0 ); Thyra::SolveStatus<Scalar> solveStatus = Thyra::solve( nonlinearSolver, &*x_bar ); *out << "\nsolveStatus:\n" << solveStatus; *out << "\nx_bar = " << describe(*x_bar,solnVerbLevel); // // G) Verify that the solution is correct??? // // Check against the end time exact solution. RCP<const Thyra::VectorBase<Scalar> > exact_x_final = Thyra::create_Vector( epetraDaeModel->getExactSolution(finalTime), daeModel->get_x_space() ); RCP<const Thyra::VectorBase<Scalar> > solved_x_final = rcp_dynamic_cast<Thyra::ProductVectorBase<Scalar> >(x_bar,true)->getVectorBlock(numTimeSteps-1); const bool result = Thyra::testRelNormDiffErr( "exact_x_final", *exact_x_final, "solved_x_final", *solved_x_final, "maxStateError", maxStateError, "warningTol", 1.0, // Don't warn &*out, solnVerbLevel ); if (!result) success = false; } TEUCHOS_STANDARD_CATCH_STATEMENTS(true,*out,success); if(success) *out << "\nEnd Result: TEST PASSED" << endl; else *out << "\nEnd Result: TEST FAILED" << endl; return ( success ? 0 : 1 ); } // end main() [Doxygen looks for this!]
void ImplicitRKModelEvaluator<Scalar>::evalModelImpl( const Thyra::ModelEvaluatorBase::InArgs<Scalar>& inArgs_bar, const Thyra::ModelEvaluatorBase::OutArgs<Scalar>& outArgs_bar ) const { using Teuchos::rcp_dynamic_cast; typedef ScalarTraits<Scalar> ST; typedef Thyra::ModelEvaluatorBase MEB; typedef Thyra::VectorBase<Scalar> VB; typedef Thyra::ProductVectorBase<Scalar> PVB; typedef Thyra::BlockedLinearOpBase<Scalar> BLWB; TEST_FOR_EXCEPTION( !isInitialized_, std::logic_error, "Error! initializeIRKModel must be called before evalModel\n" ); TEST_FOR_EXCEPTION( !setTimeStepPointCalled_, std::logic_error, "Error! setTimeStepPoint must be called before evalModel" ); THYRA_MODEL_EVALUATOR_DECORATOR_EVAL_MODEL_GEN_BEGIN( "Rythmos::ImplicitRKModelEvaluator",inArgs_bar,outArgs_bar,daeModel_ ); // // A) Unwrap the inArgs and outArgs to get at product vectors and block op // const RCP<const PVB> x_bar = rcp_dynamic_cast<const PVB>(inArgs_bar.get_x(), true); const RCP<PVB> f_bar = rcp_dynamic_cast<PVB>(outArgs_bar.get_f(), true); const RCP<BLWB> W_op_bar = rcp_dynamic_cast<BLWB>(outArgs_bar.get_W_op(), true); // // B) Assemble f_bar and W_op_bar by looping over stages // MEB::InArgs<Scalar> daeInArgs = daeModel_->createInArgs(); MEB::OutArgs<Scalar> daeOutArgs = daeModel_->createOutArgs(); const RCP<VB> x_i = createMember(daeModel_->get_x_space()); daeInArgs.setArgs(basePoint_); const int numStages = irkButcherTableau_->numStages(); for ( int i = 0; i < numStages; ++i ) { // B.1) Setup the DAE's inArgs for stage f(i) ... assembleIRKState( i, irkButcherTableau_->A(), delta_t_, *x_old_, *x_bar, outArg(*x_i) ); daeInArgs.set_x( x_i ); daeInArgs.set_x_dot( x_bar->getVectorBlock(i) ); daeInArgs.set_t( t_old_ + irkButcherTableau_->c()(i) * delta_t_ ); Scalar alpha = ST::zero(); if (i == 0) { alpha = ST::one(); } else { alpha = ST::zero(); } Scalar beta = delta_t_ * irkButcherTableau_->A()(i,0); daeInArgs.set_alpha( alpha ); daeInArgs.set_beta( beta ); // B.2) Setup the DAE's outArgs for stage f(i) ... if (!is_null(f_bar)) daeOutArgs.set_f( f_bar->getNonconstVectorBlock(i) ); if (!is_null(W_op_bar)) { daeOutArgs.set_W_op(W_op_bar->getNonconstBlock(i,0)); } // B.3) Compute f_bar(i) and/or W_op_bar(i,0) ... daeModel_->evalModel( daeInArgs, daeOutArgs ); daeOutArgs.set_f(Teuchos::null); daeOutArgs.set_W_op(Teuchos::null); // B.4) Evaluate the rest of the W_op_bar(i,j=1...numStages-1) ... if (!is_null(W_op_bar)) { for ( int j = 1; j < numStages; ++j ) { alpha = ST::zero(); if (i == j) { alpha = ST::one(); } else { alpha = ST::zero(); } beta = delta_t_ * irkButcherTableau_->A()(i,j); daeInArgs.set_alpha( alpha ); daeInArgs.set_beta( beta ); daeOutArgs.set_W_op(W_op_bar->getNonconstBlock(i,j)); daeModel_->evalModel( daeInArgs, daeOutArgs ); daeOutArgs.set_W_op(Teuchos::null); } } } THYRA_MODEL_EVALUATOR_DECORATOR_EVAL_MODEL_END(); }