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); }
void ExplicitModelEvaluator<Scalar>:: buildInverseMassMatrix() const { typedef Thyra::ModelEvaluatorBase MEB; using Teuchos::RCP; using Thyra::createMember; RCP<const Thyra::ModelEvaluator<Scalar> > me = this->getUnderlyingModel(); // first allocate space for the mass matrix RCP<Thyra::LinearOpBase<Scalar> > mass = me->create_W_op(); // intialize a zero to get rid of the x-dot if(zero_==Teuchos::null) { zero_ = Thyra::createMember(*me->get_x_space()); Thyra::assign(zero_.ptr(),0.0); } // request only the mass matrix from the physics // Model evaluator builds: alpha*u_dot + beta*F(u) = 0 MEB::InArgs<Scalar> inArgs = me->createInArgs(); inArgs.set_x(createMember(me->get_x_space())); inArgs.set_x_dot(zero_); inArgs.set_alpha(-1.0); inArgs.set_beta(0.0); // set the one time beta to ensure dirichlet conditions // are correctly included in the mass matrix: do it for // both epetra and Tpetra. If a panzer model evaluator has // not been passed in...oh well you get what you asked for! if(panzerModel_!=Teuchos::null) panzerModel_->setOneTimeDirichletBeta(-1.0); else if(panzerEpetraModel_!=Teuchos::null) panzerEpetraModel_->setOneTimeDirichletBeta(-1.0); // set only the mass matrix MEB::OutArgs<Scalar> outArgs = me->createOutArgs(); outArgs.set_W_op(mass); // this will fill the mass matrix operator me->evalModel(inArgs,outArgs); if(!massLumping_) { invMassMatrix_ = Thyra::inverse<Scalar>(*me->get_W_factory(),mass); } else { // build lumped mass matrix (assumes all positive mass entries, does a simple sum) Teuchos::RCP<Thyra::VectorBase<Scalar> > ones = Thyra::createMember(*mass->domain()); Thyra::assign(ones.ptr(),1.0); RCP<Thyra::VectorBase<Scalar> > invLumpMass = Thyra::createMember(*mass->range()); Thyra::apply(*mass,Thyra::NOTRANS,*ones,invLumpMass.ptr()); Thyra::reciprocal(*invLumpMass,invLumpMass.ptr()); invMassMatrix_ = Thyra::diagonal(invLumpMass); } }
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 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"; }
TEUCHOS_UNIT_TEST( Rythmos_ForwardSensitivityExplicitModelEvaluator, evalModel ) { typedef Thyra::ModelEvaluatorBase MEB; RCP<ForwardSensitivityExplicitModelEvaluator<double> > model = forwardSensitivityExplicitModelEvaluator<double>(); RCP<SinCosModel> innerModel = sinCosModel(false); double a = 0.4; double f = 1.5; double L = 1.6; { RCP<ParameterList> pl = Teuchos::parameterList(); pl->set("Accept model parameters",true); pl->set("Implicit model formulation",false); pl->set("Coeff a", a ); pl->set("Coeff f", f ); pl->set("Coeff L", L ); innerModel->setParameterList(pl); } model->initializeStructure(innerModel, 0 ); RCP<VectorBase<double> > x; MEB::InArgs<double> pointInArgs; // Used to change the solution for re-evaluation RCP<StepperBase<double> > stepper; // Used for initializePointState { pointInArgs = innerModel->createInArgs(); pointInArgs.set_t(0.1); x = Thyra::createMember(innerModel->get_x_space()); { Thyra::DetachedVectorView<double> x_view( *x ); x_view[0] = 2.0; x_view[1] = 3.0; } pointInArgs.set_x(x); RCP<VectorBase<double> > p0 = Thyra::createMember(innerModel->get_p_space(0)); { Thyra::DetachedVectorView<double> p0_view( *p0 ); p0_view[0] = a; p0_view[1] = f; p0_view[2] = L; } pointInArgs.set_p(0,p0); { // Create a stepper with these initial conditions to use to call // initializePointState on this ME: stepper = forwardEulerStepper<double>(); stepper->setInitialCondition(pointInArgs); model->initializePointState(Teuchos::inOutArg(*stepper),false); } } MEB::InArgs<double> inArgs = model->createInArgs(); RCP<VectorBase<double> > x_bar = Thyra::createMember(model->get_x_space()); RCP<Thyra::DefaultMultiVectorProductVector<double> > s_bar = Teuchos::rcp_dynamic_cast<Thyra::DefaultMultiVectorProductVector<double> >( x_bar, true ); RCP<Thyra::MultiVectorBase<double> > S = s_bar->getNonconstMultiVector(); // Fill S with data { TEST_EQUALITY_CONST( S->domain()->dim(), 3 ); TEST_EQUALITY_CONST( S->range()->dim(), 2 ); RCP<VectorBase<double> > S0 = S->col(0); RCP<VectorBase<double> > S1 = S->col(1); RCP<VectorBase<double> > S2 = S->col(2); TEST_EQUALITY_CONST( S0->space()->dim(), 2 ); TEST_EQUALITY_CONST( S1->space()->dim(), 2 ); TEST_EQUALITY_CONST( S2->space()->dim(), 2 ); Thyra::DetachedVectorView<double> S0_view( *S0 ); S0_view[0] = 7.0; S0_view[1] = 8.0; Thyra::DetachedVectorView<double> S1_view( *S1 ); S1_view[0] = 9.0; S1_view[1] = 10.0; Thyra::DetachedVectorView<double> S2_view( *S2 ); S2_view[0] = 11.0; S2_view[1] = 12.0; } inArgs.set_x(x_bar); MEB::OutArgs<double> outArgs = model->createOutArgs(); RCP<VectorBase<double> > f_bar = Thyra::createMember(model->get_f_space()); RCP<Thyra::DefaultMultiVectorProductVector<double> > f_sens = Teuchos::rcp_dynamic_cast<Thyra::DefaultMultiVectorProductVector<double> >( f_bar, true ); RCP<Thyra::MultiVectorBase<double> > F_sens = f_sens->getNonconstMultiVector().assert_not_null(); V_S(Teuchos::outArg(*f_bar),0.0); outArgs.set_f(f_bar); inArgs.set_t(0.1); model->evalModel(inArgs,outArgs); // Verify F_sens = df/dx*S = df/dp // df/dx = [ 0 1 ] // [ -(f/L)*(f/L) 0 ] // S = [ 7 9 11 ] x = [ 2 ] // [ 8 10 12 ] [ 3 ] // df/dp = [ 0 0 0 ] // [ (f/L)*(f/L) 2*f/(L*L)*(a-x_0) -2*f*f/(L*L*L)*(a-x_0) ] // F_sens_0 = // [ 8 ] // [ -7*(f/L)*(f/L)+(f*f)/(L*L) ] // F_sens_1 = // [ 10 ] // [ -9*(f/L)*(f/L)+2*f/(L*L)*(a-x_0) ] // F_sens_2 = // [ 12 ] // [ -11*(f/L)*(f/L)-2*f*f/(L*L*L)*(a-x_0) ] // double tol = 1.0e-10; { TEST_EQUALITY_CONST( F_sens->domain()->dim(), 3 ); TEST_EQUALITY_CONST( F_sens->range()->dim(), 2 ); RCP<VectorBase<double> > F_sens_0 = F_sens->col(0); RCP<VectorBase<double> > F_sens_1 = F_sens->col(1); RCP<VectorBase<double> > F_sens_2 = F_sens->col(2); TEST_EQUALITY_CONST( F_sens_0->space()->dim(), 2 ); TEST_EQUALITY_CONST( F_sens_1->space()->dim(), 2 ); TEST_EQUALITY_CONST( F_sens_2->space()->dim(), 2 ); Thyra::DetachedVectorView<double> F_sens_0_view( *F_sens_0 ); TEST_FLOATING_EQUALITY( F_sens_0_view[0], 8.0, tol ); TEST_FLOATING_EQUALITY( F_sens_0_view[1], -7.0*(f/L)*(f/L)+(f*f)/(L*L), tol ); Thyra::DetachedVectorView<double> F_sens_1_view( *F_sens_1 ); TEST_FLOATING_EQUALITY( F_sens_1_view[0], 10.0, tol ); TEST_FLOATING_EQUALITY( F_sens_1_view[1], -9*(f/L)*(f/L)+2*f/(L*L)*(a-2.0), tol ); Thyra::DetachedVectorView<double> F_sens_2_view( *F_sens_2 ); TEST_FLOATING_EQUALITY( F_sens_2_view[0], 12.0, tol ); TEST_FLOATING_EQUALITY( F_sens_2_view[1], -11*(f/L)*(f/L)-2*f*f/(L*L*L)*(a-2.0), tol ); } // Now change x and evaluate again. { Thyra::DetachedVectorView<double> x_view( *x ); x_view[0] = 20.0; x_view[1] = 21.0; } // We need to call initializePointState again due to the vector // being cloned inside. stepper->setInitialCondition(pointInArgs); model->initializePointState(Teuchos::inOutArg(*stepper),false); model->evalModel(inArgs,outArgs); { TEST_EQUALITY_CONST( F_sens->domain()->dim(), 3 ); TEST_EQUALITY_CONST( F_sens->range()->dim(), 2 ); RCP<VectorBase<double> > F_sens_0 = F_sens->col(0); RCP<VectorBase<double> > F_sens_1 = F_sens->col(1); RCP<VectorBase<double> > F_sens_2 = F_sens->col(2); TEST_EQUALITY_CONST( F_sens_0->space()->dim(), 2 ); TEST_EQUALITY_CONST( F_sens_1->space()->dim(), 2 ); TEST_EQUALITY_CONST( F_sens_2->space()->dim(), 2 ); Thyra::DetachedVectorView<double> F_sens_0_view( *F_sens_0 ); TEST_FLOATING_EQUALITY( F_sens_0_view[0], 8.0, tol ); TEST_FLOATING_EQUALITY( F_sens_0_view[1], -7.0*(f/L)*(f/L)+(f*f)/(L*L), tol ); Thyra::DetachedVectorView<double> F_sens_1_view( *F_sens_1 ); TEST_FLOATING_EQUALITY( F_sens_1_view[0], 10.0, tol ); TEST_FLOATING_EQUALITY( F_sens_1_view[1], -9*(f/L)*(f/L)+2*f/(L*L)*(a-20.0), tol ); Thyra::DetachedVectorView<double> F_sens_2_view( *F_sens_2 ); TEST_FLOATING_EQUALITY( F_sens_2_view[0], 12.0, tol ); TEST_FLOATING_EQUALITY( F_sens_2_view[1], -11*(f/L)*(f/L)-2*f*f/(L*L*L)*(a-20.0), tol ); } }
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(); }