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 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 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(); }