void ImplicitRKStepper<Scalar>::setInitialCondition( const Thyra::ModelEvaluatorBase::InArgs<Scalar> &initialCondition ) { typedef ScalarTraits<Scalar> ST; typedef Thyra::ModelEvaluatorBase MEB; basePoint_ = initialCondition; // x RCP<const Thyra::VectorBase<Scalar> > x_init = initialCondition.get_x(); #ifdef HAVE_RYTHMOS_DEBUG TEUCHOS_TEST_FOR_EXCEPTION( is_null(x_init), std::logic_error, "Error, if the client passes in an intial condition to setInitialCondition(...),\n" "then x can not be null!" ); #endif x_ = x_init->clone_v(); // x_dot x_dot_ = createMember(x_->space()); RCP<const Thyra::VectorBase<Scalar> > x_dot_init = initialCondition.get_x_dot(); if (!is_null(x_dot_init)) assign(x_dot_.ptr(),*x_dot_init); else assign(x_dot_.ptr(),ST::zero()); // t const Scalar t = ( initialCondition.supports(MEB::IN_ARG_t) ? initialCondition.get_t() : ST::zero() ); timeRange_ = timeRange(t,t); // x_old x_old_ = x_->clone_v(); haveInitialCondition_ = true; }
void Simple2DModelEvaluator<Scalar>::evalModelImpl( const Thyra::ModelEvaluatorBase::InArgs<Scalar> &inArgs, const Thyra::ModelEvaluatorBase::OutArgs<Scalar> &outArgs ) const { using Teuchos::rcp_dynamic_cast; const Scalar one = 1.0, two = 2.0, zero = 0.0; const ConstDetachedVectorView<Scalar> x(inArgs.get_x()); const RCP<Thyra::VectorBase<Scalar> > f_out = outArgs.get_f(); const RCP<Thyra::LinearOpBase< Scalar > > W_op_out = outArgs.get_W_op(); const RCP<Thyra::PreconditionerBase< Scalar > > W_prec_out = outArgs.get_W_prec(); if (nonnull(f_out)) { const DetachedVectorView<Scalar> f(f_out); f[0] = x[0] + x[1] * x[1] - p_[0]; f[1] = d_ * (x[0] * x[0] - x[1] - p_[1]); } if (nonnull(W_op_out)) { const RCP<SimpleDenseLinearOp<Scalar> > W = rcp_dynamic_cast<SimpleDenseLinearOp<Scalar> >(W_op_out, true); const RCP<MultiVectorBase<Scalar> > W_mv = W->getNonconstMultiVector(); Thyra::DetachedMultiVectorView<Scalar> W_dmvv(W_mv); W_dmvv(0, 0) = one; W_dmvv(0, 1) = two * x[1]; W_dmvv(1, 0) = d_ * two * x[0]; W_dmvv(1, 1) = -d_; } if (nonnull(W_prec_out)) { const RCP<SimpleDenseLinearOp<Scalar> > W_prec_op = rcp_dynamic_cast<SimpleDenseLinearOp<Scalar> >( W_prec_out->getNonconstUnspecifiedPrecOp(), true); const RCP<MultiVectorBase<Scalar> > W_prec_mv = W_prec_op->getNonconstMultiVector(); Thyra::DetachedMultiVectorView<Scalar> W_prec_dmvv(W_prec_mv); // Diagonal inverse of W (see W above) W_prec_dmvv(0, 0) = one; W_prec_dmvv(0, 1) = zero; W_prec_dmvv(1, 0) = zero; W_prec_dmvv(1, 1) = -one/d_; } }
void TimeDiscretizedBackwardEulerModelEvaluator<Scalar>::initialize( const RCP<const Thyra::ModelEvaluator<Scalar> > &daeModel, const Thyra::ModelEvaluatorBase::InArgs<Scalar> &initCond, const Scalar finalTime, const int numTimeSteps, const RCP<Thyra::LinearOpWithSolveFactoryBase<Scalar> > &W_bar_factory ) { TEST_FOR_EXCEPT(is_null(daeModel)); TEST_FOR_EXCEPT(is_null(initCond.get_x())); TEST_FOR_EXCEPT(is_null(initCond.get_x_dot())); TEST_FOR_EXCEPT(finalTime <= initCond.get_t()); TEST_FOR_EXCEPT(numTimeSteps <= 0); // ToDo: Validate that daeModel is of the right form! daeModel_ = daeModel; initCond_ = initCond; finalTime_ = finalTime; numTimeSteps_ = numTimeSteps; initTime_ = initCond.get_t(); delta_t_ = (finalTime_ - initTime_) / numTimeSteps_; x_bar_space_ = productVectorSpace(daeModel_->get_x_space(),numTimeSteps_); f_bar_space_ = productVectorSpace(daeModel_->get_f_space(),numTimeSteps_); if (!is_null(W_bar_factory)) { W_bar_factory_ = W_bar_factory; } else { W_bar_factory_ = Thyra::defaultBlockedTriangularLinearOpWithSolveFactory<Scalar>( daeModel_->get_W_factory() ); } }
void DiagonalImplicitRKModelEvaluator<Scalar>::initializeDIRKModel( const RCP<const Thyra::ModelEvaluator<Scalar> >& daeModel, const Thyra::ModelEvaluatorBase::InArgs<Scalar>& basePoint, const RCP<Thyra::LinearOpWithSolveFactoryBase<Scalar> >& dirk_W_factory, const RCP<const RKButcherTableauBase<Scalar> >& irkButcherTableau ) { typedef ScalarTraits<Scalar> ST; // ToDo: Assert input arguments! // How do I verify the basePoint is an authentic InArgs from daeModel? TEUCHOS_TEST_FOR_EXCEPTION( is_null(basePoint.get_x()), std::logic_error, "Error! The basepoint x vector is null!" ); TEUCHOS_TEST_FOR_EXCEPTION( is_null(daeModel), std::logic_error, "Error! The model evaluator pointer is null!" ); TEUCHOS_TEST_FOR_EXCEPTION( !daeModel->get_x_space()->isCompatible(*(basePoint.get_x()->space())), std::logic_error, "Error! The basepoint input arguments are incompatible with the model evaluator vector space!" ); //TEUCHOS_TEST_FOR_EXCEPT(is_null(dirk_W_factory)); daeModel_ = daeModel; basePoint_ = basePoint; dirk_W_factory_ = dirk_W_factory; dirkButcherTableau_ = irkButcherTableau; const int numStages = dirkButcherTableau_->numStages(); using Teuchos::rcp_dynamic_cast; stage_space_ = productVectorSpace(daeModel_->get_x_space(),numStages); RCP<const Thyra::VectorSpaceBase<Scalar> > vs = rcp_dynamic_cast<const Thyra::VectorSpaceBase<Scalar> >(stage_space_,true); stage_derivatives_ = rcp_dynamic_cast<Thyra::ProductVectorBase<Scalar> >(createMember(vs),true); Thyra::V_S( rcp_dynamic_cast<Thyra::VectorBase<Scalar> >(stage_derivatives_).ptr(),ST::zero()); // Set up prototypical InArgs { typedef Thyra::ModelEvaluatorBase MEB; MEB::InArgsSetup<Scalar> inArgs; inArgs.setModelEvalDescription(this->description()); inArgs.setSupports(MEB::IN_ARG_x); inArgs_ = inArgs; } // Set up prototypical OutArgs { typedef Thyra::ModelEvaluatorBase MEB; MEB::OutArgsSetup<Scalar> outArgs; outArgs.setModelEvalDescription(this->description()); outArgs.setSupports(MEB::OUT_ARG_f); outArgs.setSupports(MEB::OUT_ARG_W_op); outArgs_ = outArgs; } // Set up nominal values nominalValues_ = inArgs_; isInitialized_ = true; }
TEUCHOS_UNIT_TEST( Rythmos_ImplicitBDFStepper, exactNumericalAnswer_BE_nonlinear ) { double epsilon = 0.5; RCP<ParameterList> modelPL = Teuchos::parameterList(); { modelPL->set("Implicit model formulation",true); modelPL->set("Coeff epsilon",epsilon); } RCP<VanderPolModel> model = vanderPolModel(); model->setParameterList(modelPL); Thyra::ModelEvaluatorBase::InArgs<double> model_ic = model->getNominalValues(); RCP<TimeStepNonlinearSolver<double> > nlSolver = timeStepNonlinearSolver<double>(); { RCP<ParameterList> nlPL = Teuchos::parameterList(); nlPL->set("Default Tol",1.0e-10); nlPL->set("Default Max Iters",20); nlSolver->setParameterList(nlPL); } RCP<ParameterList> stepperPL = Teuchos::parameterList(); { ParameterList& pl = stepperPL->sublist("Step Control Settings"); pl.set("minOrder",1); pl.set("maxOrder",1); ParameterList& vopl = pl.sublist("VerboseObject"); vopl.set("Verbosity Level","none"); } RCP<ImplicitBDFStepper<double> > stepper = implicitBDFStepper<double>(model,nlSolver,stepperPL); stepper->setInitialCondition(model_ic); double h = 0.1; std::vector<double> x_0_exact; std::vector<double> x_1_exact; std::vector<double> x_0_dot_exact; std::vector<double> x_1_dot_exact; { x_0_exact.push_back(2.0); // IC x_1_exact.push_back(0.0); x_0_exact.push_back(1.982896621392518e+00); // matlab x_1_exact.push_back(-1.710337860748234e-01); x_0_exact.push_back(1.951487185706842e+00); // matlab x_1_exact.push_back(-3.140943568567556e-01); x_0_exact.push_back(1.908249109758246e+00); // matlab x_1_exact.push_back(-4.323807594859574e-01); x_0_dot_exact.push_back(0.0); x_1_dot_exact.push_back(0.0); for ( int i=1 ; i< Teuchos::as<int>(x_0_exact.size()) ; ++i ) { x_0_dot_exact.push_back( (x_0_exact[i]-x_0_exact[i-1])/h ); x_1_dot_exact.push_back( (x_1_exact[i]-x_1_exact[i-1])/h ); //std::cout << "x_0_dot_exact["<<i<<"] = "<<x_0_dot_exact[i] << std::endl; //std::cout << "x_1_dot_exact["<<i<<"] = "<<x_1_dot_exact[i] << std::endl; } } double tol_discrete = 1.0e-12; double tol_continuous = 1.0e-2; { // Get IC out double t = 0.0; RCP<const VectorBase<double> > x; RCP<const VectorBase<double> > xdot; { // Get x out of stepper. Array<double> t_vec; Array<RCP<const VectorBase<double> > > x_vec; Array<RCP<const VectorBase<double> > > xdot_vec; t_vec.resize(1); t_vec[0] = t; stepper->getPoints(t_vec,&x_vec,&xdot_vec,NULL); x = x_vec[0]; xdot = xdot_vec[0]; } { Thyra::ConstDetachedVectorView<double> x_view( *x ); TEST_FLOATING_EQUALITY( x_view[0], x_0_exact[0], tol_discrete ); TEST_FLOATING_EQUALITY( x_view[1], x_1_exact[0], tol_discrete ); Thyra::ConstDetachedVectorView<double> xdot_view( *xdot ); TEST_FLOATING_EQUALITY( xdot_view[0], x_0_dot_exact[0], tol_discrete ); TEST_FLOATING_EQUALITY( xdot_view[1], x_1_dot_exact[0], tol_discrete ); } } for (int i=1 ; i < Teuchos::as<int>(x_0_exact.size()); ++i) { // Each time step double t = 0.0+i*h; double h_taken = stepper->takeStep(h,STEP_TYPE_FIXED); TEST_ASSERT( h_taken == h ); RCP<const VectorBase<double> > x; RCP<const VectorBase<double> > xdot; { // Get x out of stepper. Array<double> t_vec; Array<RCP<const VectorBase<double> > > x_vec; Array<RCP<const VectorBase<double> > > xdot_vec; t_vec.resize(1); t_vec[0] = t; stepper->getPoints(t_vec,&x_vec,&xdot_vec,NULL); x = x_vec[0]; xdot = xdot_vec[0]; } { Thyra::ConstDetachedVectorView<double> x_view( *x ); TEST_FLOATING_EQUALITY( x_view[0], x_0_exact[i], tol_discrete ); TEST_FLOATING_EQUALITY( x_view[1], x_1_exact[i], tol_discrete ); Thyra::ConstDetachedVectorView<double> xdot_view( *xdot ); TEST_FLOATING_EQUALITY( xdot_view[0], x_0_dot_exact[i], tol_discrete ); TEST_FLOATING_EQUALITY( xdot_view[1], x_1_dot_exact[i], tol_discrete ); } // Now compare this to the continuous exact solution: { Thyra::ModelEvaluatorBase::InArgs<double> inArgs = model->getExactSolution(t); RCP<const VectorBase<double> > x_continuous_exact = inArgs.get_x(); RCP<const VectorBase<double> > xdot_continuous_exact = inArgs.get_x_dot(); { Thyra::ConstDetachedVectorView<double> x_view( *x ); Thyra::ConstDetachedVectorView<double> xce_view( *x_continuous_exact ); TEST_FLOATING_EQUALITY( x_view[0], xce_view[0], tol_continuous ); TEST_FLOATING_EQUALITY( x_view[1], xce_view[1], tol_continuous*10 ); Thyra::ConstDetachedVectorView<double> xdot_view( *xdot ); Thyra::ConstDetachedVectorView<double> xdotce_view( *xdot_continuous_exact ); TEST_FLOATING_EQUALITY( xdot_view[0], xdotce_view[0], tol_continuous*10 ); TEST_FLOATING_EQUALITY( xdot_view[1], xdotce_view[1], tol_continuous*10 ); } } } }
void Albany::ModelEvaluatorT::evalModelImpl( const Thyra::ModelEvaluatorBase::InArgs<ST>& inArgsT, const Thyra::ModelEvaluatorBase::OutArgs<ST>& outArgsT) const { #ifdef OUTPUT_TO_SCREEN std::cout << "DEBUG: " << __PRETTY_FUNCTION__ << "\n"; #endif Teuchos::TimeMonitor Timer(*timer); //start timer // // Get the input arguments // const Teuchos::RCP<const Tpetra_Vector> xT = ConverterT::getConstTpetraVector(inArgsT.get_x()); const Teuchos::RCP<const Tpetra_Vector> x_dotT = (supports_xdot && Teuchos::nonnull(inArgsT.get_x_dot())) ? ConverterT::getConstTpetraVector(inArgsT.get_x_dot()) : Teuchos::null; const Teuchos::RCP<const Tpetra_Vector> x_dotdotT = (supports_xdotdot && Teuchos::nonnull(this->get_x_dotdot())) ? ConverterT::getConstTpetraVector(this->get_x_dotdot()) : Teuchos::null; const double alpha = (Teuchos::nonnull(x_dotT) || Teuchos::nonnull(x_dotdotT)) ? inArgsT.get_alpha() : 0.0; const double omega = Teuchos::nonnull(x_dotdotT) ? this->get_omega() : 0.0; const double beta = (Teuchos::nonnull(x_dotT) || Teuchos::nonnull(x_dotdotT)) ? inArgsT.get_beta() : 1.0; const double curr_time = (Teuchos::nonnull(x_dotT) || Teuchos::nonnull(x_dotdotT)) ? inArgsT.get_t() : 0.0; for (int l = 0; l < inArgsT.Np(); ++l) { const Teuchos::RCP<const Thyra::VectorBase<ST> > p = inArgsT.get_p(l); if (Teuchos::nonnull(p)) { const Teuchos::RCP<const Tpetra_Vector> pT = ConverterT::getConstTpetraVector(p); const Teuchos::ArrayRCP<const ST> pT_constView = pT->get1dView(); ParamVec &sacado_param_vector = sacado_param_vec[l]; for (unsigned int k = 0; k < sacado_param_vector.size(); ++k) { sacado_param_vector[k].baseValue = pT_constView[k]; } } } // // Get the output arguments // const Teuchos::RCP<Tpetra_Vector> fT_out = Teuchos::nonnull(outArgsT.get_f()) ? ConverterT::getTpetraVector(outArgsT.get_f()) : Teuchos::null; const Teuchos::RCP<Tpetra_Operator> W_op_outT = Teuchos::nonnull(outArgsT.get_W_op()) ? ConverterT::getTpetraOperator(outArgsT.get_W_op()) : Teuchos::null; #ifdef WRITE_MASS_MATRIX_TO_MM_FILE //IK, 4/24/15: adding object to hold mass matrix to be written to matrix market file const Teuchos::RCP<Tpetra_Operator> Mass = Teuchos::nonnull(outArgsT.get_W_op()) ? ConverterT::getTpetraOperator(outArgsT.get_W_op()) : Teuchos::null; //IK, 4/24/15: needed for writing mass matrix out to matrix market file const Teuchos::RCP<Tpetra_Vector> ftmp = Teuchos::nonnull(outArgsT.get_f()) ? ConverterT::getTpetraVector(outArgsT.get_f()) : Teuchos::null; #endif // Cast W to a CrsMatrix, throw an exception if this fails const Teuchos::RCP<Tpetra_CrsMatrix> W_op_out_crsT = Teuchos::nonnull(W_op_outT) ? Teuchos::rcp_dynamic_cast<Tpetra_CrsMatrix>(W_op_outT, true) : Teuchos::null; #ifdef WRITE_MASS_MATRIX_TO_MM_FILE //IK, 4/24/15: adding object to hold mass matrix to be written to matrix market file const Teuchos::RCP<Tpetra_CrsMatrix> Mass_crs = Teuchos::nonnull(Mass) ? Teuchos::rcp_dynamic_cast<Tpetra_CrsMatrix>(Mass, true) : Teuchos::null; #endif // // Compute the functions // bool f_already_computed = false; // W matrix if (Teuchos::nonnull(W_op_out_crsT)) { app->computeGlobalJacobianT( alpha, beta, omega, curr_time, x_dotT.get(), x_dotdotT.get(), *xT, sacado_param_vec, fT_out.get(), *W_op_out_crsT); f_already_computed = true; #ifdef WRITE_MASS_MATRIX_TO_MM_FILE //IK, 4/24/15: write mass matrix to matrix market file //Warning: to read this in to MATLAB correctly, code must be run in serial. //Otherwise Mass will have a distributed Map which would also need to be read in to MATLAB for proper //reading in of Mass. app->computeGlobalJacobianT(1.0, 0.0, 0.0, curr_time, x_dotT.get(), x_dotdotT.get(), *xT, sacado_param_vec, ftmp.get(), *Mass_crs); Tpetra_MatrixMarket_Writer::writeSparseFile("mass.mm", Mass_crs); Tpetra_MatrixMarket_Writer::writeMapFile("rowmap.mm", *Mass_crs->getRowMap()); Tpetra_MatrixMarket_Writer::writeMapFile("colmap.mm", *Mass_crs->getColMap()); #endif } // df/dp for (int l = 0; l < outArgsT.Np(); ++l) { const Teuchos::RCP<Thyra::MultiVectorBase<ST> > dfdp_out = outArgsT.get_DfDp(l).getMultiVector(); const Teuchos::RCP<Tpetra_MultiVector> dfdp_outT = Teuchos::nonnull(dfdp_out) ? ConverterT::getTpetraMultiVector(dfdp_out) : Teuchos::null; if (Teuchos::nonnull(dfdp_outT)) { const Teuchos::RCP<ParamVec> p_vec = Teuchos::rcpFromRef(sacado_param_vec[l]); app->computeGlobalTangentT( 0.0, 0.0, 0.0, curr_time, false, x_dotT.get(), x_dotdotT.get(), *xT, sacado_param_vec, p_vec.get(), NULL, NULL, NULL, NULL, fT_out.get(), NULL, dfdp_outT.get()); f_already_computed = true; } } // f if (app->is_adjoint) { const Thyra::ModelEvaluatorBase::Derivative<ST> f_derivT( outArgsT.get_f(), Thyra::ModelEvaluatorBase::DERIV_TRANS_MV_BY_ROW); const Thyra::ModelEvaluatorBase::Derivative<ST> dummy_derivT; const int response_index = 0; // need to add capability for sending this in app->evaluateResponseDerivativeT( response_index, curr_time, x_dotT.get(), x_dotdotT.get(), *xT, sacado_param_vec, NULL, NULL, f_derivT, dummy_derivT, dummy_derivT, dummy_derivT); } else { if (Teuchos::nonnull(fT_out) && !f_already_computed) { app->computeGlobalResidualT( curr_time, x_dotT.get(), x_dotdotT.get(), *xT, sacado_param_vec, *fT_out); } } // Response functions for (int j = 0; j < outArgsT.Ng(); ++j) { const Teuchos::RCP<Thyra::VectorBase<ST> > g_out = outArgsT.get_g(j); Teuchos::RCP<Tpetra_Vector> gT_out = Teuchos::nonnull(g_out) ? ConverterT::getTpetraVector(g_out) : Teuchos::null; const Thyra::ModelEvaluatorBase::Derivative<ST> dgdxT_out = outArgsT.get_DgDx(j); Thyra::ModelEvaluatorBase::Derivative<ST> dgdxdotT_out; if(supports_xdot) dgdxdotT_out = outArgsT.get_DgDx_dot(j); // const Thyra::ModelEvaluatorBase::Derivative<ST> dgdxdotdotT_out = this->get_DgDx_dotdot(j); const Thyra::ModelEvaluatorBase::Derivative<ST> dgdxdotdotT_out; sanitize_nans(dgdxT_out); sanitize_nans(dgdxdotT_out); sanitize_nans(dgdxdotdotT_out); // dg/dx, dg/dxdot if (!dgdxT_out.isEmpty() || !dgdxdotT_out.isEmpty()) { const Thyra::ModelEvaluatorBase::Derivative<ST> dummy_derivT; app->evaluateResponseDerivativeT( j, curr_time, x_dotT.get(), x_dotdotT.get(), *xT, sacado_param_vec, NULL, gT_out.get(), dgdxT_out, dgdxdotT_out, dgdxdotdotT_out, dummy_derivT); // Set gT_out to null to indicate that g_out was evaluated. gT_out = Teuchos::null; } // dg/dp for (int l = 0; l < outArgsT.Np(); ++l) { const Teuchos::RCP<Thyra::MultiVectorBase<ST> > dgdp_out = outArgsT.get_DgDp(j, l).getMultiVector(); const Teuchos::RCP<Tpetra_MultiVector> dgdpT_out = Teuchos::nonnull(dgdp_out) ? ConverterT::getTpetraMultiVector(dgdp_out) : Teuchos::null; if (Teuchos::nonnull(dgdpT_out)) { const Teuchos::RCP<ParamVec> p_vec = Teuchos::rcpFromRef(sacado_param_vec[l]); app->evaluateResponseTangentT( j, alpha, beta, omega, curr_time, false, x_dotT.get(), x_dotdotT.get(), *xT, sacado_param_vec, p_vec.get(), NULL, NULL, NULL, NULL, gT_out.get(), NULL, dgdpT_out.get()); gT_out = Teuchos::null; } } if (Teuchos::nonnull(gT_out)) { app->evaluateResponseT( j, curr_time, x_dotT.get(), x_dotdotT.get(), *xT, sacado_param_vec, *gT_out); } } }
void Albany::ModelEvaluatorT::evalModelImpl( const Thyra::ModelEvaluatorBase::InArgs<ST>& inArgsT, const Thyra::ModelEvaluatorBase::OutArgs<ST>& outArgsT) const { Teuchos::TimeMonitor Timer(*timer); //start timer // // Get the input arguments // const Teuchos::RCP<const Tpetra_Vector> xT = ConverterT::getConstTpetraVector(inArgsT.get_x()); const Teuchos::RCP<const Tpetra_Vector> x_dotT = Teuchos::nonnull(inArgsT.get_x_dot()) ? ConverterT::getConstTpetraVector(inArgsT.get_x_dot()) : Teuchos::null; // AGS: x_dotdot time integrators not imlemented in Thyra ME yet //const Teuchos::RCP<const Tpetra_Vector> x_dotdotT = // Teuchos::nonnull(inArgsT.get_x_dotdot()) ? // ConverterT::getConstTpetraVector(inArgsT.get_x_dotdot()) : // Teuchos::null; const Teuchos::RCP<const Tpetra_Vector> x_dotdotT = Teuchos::null; const double alpha = (Teuchos::nonnull(x_dotT) || Teuchos::nonnull(x_dotdotT)) ? inArgsT.get_alpha() : 0.0; // AGS: x_dotdot time integrators not imlemented in Thyra ME yet // const double omega = (Teuchos::nonnull(x_dotT) || Teuchos::nonnull(x_dotdotT)) ? inArgsT.get_omega() : 0.0; const double omega = 0.0; const double beta = (Teuchos::nonnull(x_dotT) || Teuchos::nonnull(x_dotdotT)) ? inArgsT.get_beta() : 1.0; const double curr_time = (Teuchos::nonnull(x_dotT) || Teuchos::nonnull(x_dotdotT)) ? inArgsT.get_t() : 0.0; for (int l = 0; l < inArgsT.Np(); ++l) { const Teuchos::RCP<const Thyra::VectorBase<ST> > p = inArgsT.get_p(l); if (Teuchos::nonnull(p)) { const Teuchos::RCP<const Tpetra_Vector> pT = ConverterT::getConstTpetraVector(p); const Teuchos::ArrayRCP<const ST> pT_constView = pT->get1dView(); ParamVec &sacado_param_vector = sacado_param_vec[l]; for (unsigned int k = 0; k < sacado_param_vector.size(); ++k) { sacado_param_vector[k].baseValue = pT_constView[k]; } } } // // Get the output arguments // const Teuchos::RCP<Tpetra_Vector> fT_out = Teuchos::nonnull(outArgsT.get_f()) ? ConverterT::getTpetraVector(outArgsT.get_f()) : Teuchos::null; const Teuchos::RCP<Tpetra_Operator> W_op_outT = Teuchos::nonnull(outArgsT.get_W_op()) ? ConverterT::getTpetraOperator(outArgsT.get_W_op()) : Teuchos::null; // Cast W to a CrsMatrix, throw an exception if this fails const Teuchos::RCP<Tpetra_CrsMatrix> W_op_out_crsT = Teuchos::nonnull(W_op_outT) ? Teuchos::rcp_dynamic_cast<Tpetra_CrsMatrix>(W_op_outT, true) : Teuchos::null; // // Compute the functions // bool f_already_computed = false; // W matrix if (Teuchos::nonnull(W_op_out_crsT)) { app->computeGlobalJacobianT( alpha, beta, omega, curr_time, x_dotT.get(), x_dotdotT.get(), *xT, sacado_param_vec, fT_out.get(), *W_op_out_crsT); f_already_computed = true; } // df/dp for (int l = 0; l < outArgsT.Np(); ++l) { const Teuchos::RCP<Thyra::MultiVectorBase<ST> > dfdp_out = outArgsT.get_DfDp(l).getMultiVector(); const Teuchos::RCP<Tpetra_MultiVector> dfdp_outT = Teuchos::nonnull(dfdp_out) ? ConverterT::getTpetraMultiVector(dfdp_out) : Teuchos::null; if (Teuchos::nonnull(dfdp_outT)) { const Teuchos::RCP<ParamVec> p_vec = Teuchos::rcpFromRef(sacado_param_vec[l]); app->computeGlobalTangentT( 0.0, 0.0, 0.0, curr_time, false, x_dotT.get(), x_dotdotT.get(), *xT, sacado_param_vec, p_vec.get(), NULL, NULL, NULL, NULL, fT_out.get(), NULL, dfdp_outT.get()); f_already_computed = true; } } // f if (app->is_adjoint) { const Thyra::ModelEvaluatorBase::Derivative<ST> f_derivT( outArgsT.get_f(), Thyra::ModelEvaluatorBase::DERIV_TRANS_MV_BY_ROW); const Thyra::ModelEvaluatorBase::Derivative<ST> dummy_derivT; const int response_index = 0; // need to add capability for sending this in app->evaluateResponseDerivativeT( response_index, curr_time, x_dotT.get(), x_dotdotT.get(), *xT, sacado_param_vec, NULL, NULL, f_derivT, dummy_derivT, dummy_derivT, dummy_derivT); } else { if (Teuchos::nonnull(fT_out) && !f_already_computed) { app->computeGlobalResidualT( curr_time, x_dotT.get(), x_dotdotT.get(), *xT, sacado_param_vec, *fT_out); } } // Response functions for (int j = 0; j < outArgsT.Ng(); ++j) { const Teuchos::RCP<Thyra::VectorBase<ST> > g_out = outArgsT.get_g(j); Teuchos::RCP<Tpetra_Vector> gT_out = Teuchos::nonnull(g_out) ? ConverterT::getTpetraVector(g_out) : Teuchos::null; const Thyra::ModelEvaluatorBase::Derivative<ST> dgdxT_out = outArgsT.get_DgDx(j); const Thyra::ModelEvaluatorBase::Derivative<ST> dgdxdotT_out = outArgsT.get_DgDx_dot(j); // AGS: x_dotdot time integrators not imlemented in Thyra ME yet const Thyra::ModelEvaluatorBase::Derivative<ST> dgdxdotdotT_out; // dg/dx, dg/dxdot if (!dgdxT_out.isEmpty() || !dgdxdotT_out.isEmpty()) { const Thyra::ModelEvaluatorBase::Derivative<ST> dummy_derivT; app->evaluateResponseDerivativeT( j, curr_time, x_dotT.get(), x_dotdotT.get(), *xT, sacado_param_vec, NULL, gT_out.get(), dgdxT_out, dgdxdotT_out, dgdxdotdotT_out, dummy_derivT); // Set gT_out to null to indicate that g_out was evaluated. gT_out = Teuchos::null; } // dg/dp for (int l = 0; l < outArgsT.Np(); ++l) { const Teuchos::RCP<Thyra::MultiVectorBase<ST> > dgdp_out = outArgsT.get_DgDp(j, l).getMultiVector(); const Teuchos::RCP<Tpetra_MultiVector> dgdpT_out = Teuchos::nonnull(dgdp_out) ? ConverterT::getTpetraMultiVector(dgdp_out) : Teuchos::null; if (Teuchos::nonnull(dgdpT_out)) { const Teuchos::RCP<ParamVec> p_vec = Teuchos::rcpFromRef(sacado_param_vec[l]); app->evaluateResponseTangentT( j, alpha, beta, omega, curr_time, false, x_dotT.get(), x_dotdotT.get(), *xT, sacado_param_vec, p_vec.get(), NULL, NULL, NULL, NULL, gT_out.get(), NULL, dgdpT_out.get()); gT_out = Teuchos::null; } } if (Teuchos::nonnull(gT_out)) { app->evaluateResponseT( j, curr_time, x_dotT.get(), x_dotdotT.get(), *xT, sacado_param_vec, *gT_out); } } }
// hide the original parental method AMET->evalModelImpl(): void Aeras::HVDecorator::evalModelImpl( const Thyra::ModelEvaluatorBase::InArgs<ST>& inArgsT, const Thyra::ModelEvaluatorBase::OutArgs<ST>& outArgsT) const { #ifdef OUTPUT_TO_SCREEN std::cout << "DEBUG WHICH HVDecorator: " << __PRETTY_FUNCTION__ << "\n"; #endif Teuchos::TimeMonitor Timer(*timer); //start timer // // Get the input arguments // // Thyra vectors const Teuchos::RCP<const Thyra_Vector> x = inArgsT.get_x(); const Teuchos::RCP<const Thyra_Vector> x_dot = (supports_xdot ? inArgsT.get_x_dot() : Teuchos::null); const Teuchos::RCP<const Thyra_Vector> x_dotdot = (supports_xdotdot ? inArgsT.get_x_dot_dot() : Teuchos::null); const double alpha = (Teuchos::nonnull(x_dot) || Teuchos::nonnull(x_dotdot)) ? inArgsT.get_alpha() : 0.0; // AGS: x_dotdot time integrators not imlemented in Thyra ME yet // const double omega = (Teuchos::nonnull(x_dot) || Teuchos::nonnull(x_dotdot)) ? inArgsT.get_omega() : 0.0; const double omega = 0.0; const double beta = (Teuchos::nonnull(x_dot) || Teuchos::nonnull(x_dotdot)) ? inArgsT.get_beta() : 1.0; const double curr_time = (Teuchos::nonnull(x_dot) || Teuchos::nonnull(x_dotdot)) ? inArgsT.get_t() : 0.0; for (int l = 0; l < inArgsT.Np(); ++l) { const Teuchos::RCP<const Thyra_Vector> p = inArgsT.get_p(l); if (Teuchos::nonnull(p)) { const Teuchos::RCP<const Tpetra_Vector> pT = Albany::getConstTpetraVector(p); const Teuchos::ArrayRCP<const ST> pT_constView = pT->get1dView(); ParamVec &sacado_param_vector = sacado_param_vec[l]; for (unsigned int k = 0; k < sacado_param_vector.size(); ++k) { sacado_param_vector[k].baseValue = pT_constView[k]; } } } // // Get the output arguments // auto f = outArgsT.get_f(); auto W_op = outArgsT.get_W_op(); // // Compute the functions // bool f_already_computed = false; // W matrix if (Teuchos::nonnull(W_op)) { app->computeGlobalJacobian( alpha, beta, omega, curr_time, x, x_dot, x_dotdot, sacado_param_vec, f, W_op); f_already_computed = true; } // df/dp for (int l = 0; l < outArgsT.Np(); ++l) { const Teuchos::RCP<Thyra_MultiVector> df_dp = outArgsT.get_DfDp(l).getMultiVector(); if (Teuchos::nonnull(df_dp)) { const Teuchos::RCP<ParamVec> p_vec = Teuchos::rcpFromRef(sacado_param_vec[l]); app->computeGlobalTangent( 0.0, 0.0, 0.0, curr_time, false, x, x_dot, x_dotdot, sacado_param_vec, p_vec.get(), Teuchos::null, Teuchos::null, Teuchos::null, Teuchos::null, f, Teuchos::null, df_dp); f_already_computed = true; } } // f if (app->is_adjoint) { const Thyra_Derivative f_deriv(f, Thyra::ModelEvaluatorBase::DERIV_TRANS_MV_BY_ROW); const Thyra_Derivative dummy_deriv; const int response_index = 0; // need to add capability for sending this in app->evaluateResponseDerivative( response_index, curr_time, x, x_dot, x_dotdot, sacado_param_vec, NULL, Teuchos::null, f_deriv, dummy_deriv, dummy_deriv, dummy_deriv); } else { if (Teuchos::nonnull(f) && !f_already_computed) { app->computeGlobalResidual( curr_time, x, x_dot, x_dotdot, sacado_param_vec, f); } } //compute xtilde applyLinvML(x, xtilde); #ifdef WRITE_TO_MATRIX_MARKET_TO_MM_FILE //writing to MatrixMarket for debug char name[100]; //create string for file name sprintf(name, "xT_%i.mm", mm_counter); const Teuchos::RCP<const Tpetra_Vector> xT = Albany::getConstTpetraVector(x); Tpetra::MatrixMarket::Writer<Tpetra_CrsMatrix>::writeDenseFile(name, xT); sprintf(name, "xtildeT_%i.mm", mm_counter); const Teuchos::RCP<const Tpetra_Vector> xtildeT = Albany::getConstTpetraVector(xtilde); Tpetra::MatrixMarket::Writer<Tpetra_CrsMatrix>::writeDenseFile(name, xtildeT); mm_counter++; #endif if (supports_xdot && Teuchos::nonnull(inArgsT.get_x_dot()) && Teuchos::nonnull(f)){ #ifdef OUTPUT_TO_SCREEN std::cout <<"in the if-statement for the update" <<std::endl; #endif f->update(1.0,*xtilde); } // Response functions for (int j = 0; j < outArgsT.Ng(); ++j) { Teuchos::RCP<Thyra_Vector> g = outArgsT.get_g(j); const Thyra_Derivative dg_dx = outArgsT.get_DgDx(j); const Thyra_Derivative dg_dxdot = outArgsT.get_DgDx_dot(j); // AGS: x_dotdot time integrators not imlemented in Thyra ME yet const Thyra_Derivative dg_dxdotdot; sanitize_nans(dg_dx); sanitize_nans(dg_dxdot); sanitize_nans(dg_dxdotdot); // dg/dx, dg/dxdot if (!dg_dx.isEmpty() || !dg_dxdot.isEmpty()) { const Thyra_Derivative dummy_deriv; app->evaluateResponseDerivative( j, curr_time, x, x_dot, x_dotdot, sacado_param_vec, NULL, g, dg_dx, dg_dxdot, dg_dxdotdot, dummy_deriv); // Set g to null to indicate the response was evaluated. g= Teuchos::null; } // dg/dp for (int l = 0; l < outArgsT.Np(); ++l) { const Teuchos::RCP<Thyra_MultiVector> dg_dp = outArgsT.get_DgDp(j, l).getMultiVector(); if (Teuchos::nonnull(dg_dp)) { const Teuchos::RCP<ParamVec> p_vec = Teuchos::rcpFromRef(sacado_param_vec[l]); app->evaluateResponseTangent( j, alpha, beta, omega, curr_time, false, x, x_dot, x_dotdot, sacado_param_vec, p_vec.get(), Teuchos::null, Teuchos::null, Teuchos::null, Teuchos::null, g, Teuchos::null, dg_dp); g = Teuchos::null; } } // If response was not yet evaluated, do it now. if (Teuchos::nonnull(g)) { app->evaluateResponse( j, curr_time, x, x_dot, x_dotdot, sacado_param_vec, g); } } }
// hide the original parental method AMET->evalModelImpl(): void Aeras::HVDecorator::evalModelImpl( const Thyra::ModelEvaluatorBase::InArgs<ST>& inArgsT, const Thyra::ModelEvaluatorBase::OutArgs<ST>& outArgsT) const { std::cout << "DEBUG WHICH HVDecorator: " << __PRETTY_FUNCTION__ << "\n"; Teuchos::TimeMonitor Timer(*timer); //start timer // // Get the input arguments // const Teuchos::RCP<const Tpetra_Vector> xT = ConverterT::getConstTpetraVector(inArgsT.get_x()); const Teuchos::RCP<const Tpetra_Vector> x_dotT = Teuchos::nonnull(inArgsT.get_x_dot()) ? ConverterT::getConstTpetraVector(inArgsT.get_x_dot()) : Teuchos::null; // AGS: x_dotdot time integrators not imlemented in Thyra ME yet //const Teuchos::RCP<const Tpetra_Vector> x_dotdotT = // Teuchos::nonnull(inArgsT.get_x_dotdot()) ? // ConverterT::getConstTpetraVector(inArgsT.get_x_dotdot()) : // Teuchos::null; const Teuchos::RCP<const Tpetra_Vector> x_dotdotT = Teuchos::null; const double alpha = (Teuchos::nonnull(x_dotT) || Teuchos::nonnull(x_dotdotT)) ? inArgsT.get_alpha() : 0.0; // AGS: x_dotdot time integrators not imlemented in Thyra ME yet // const double omega = (Teuchos::nonnull(x_dotT) || Teuchos::nonnull(x_dotdotT)) ? inArgsT.get_omega() : 0.0; const double omega = 0.0; const double beta = (Teuchos::nonnull(x_dotT) || Teuchos::nonnull(x_dotdotT)) ? inArgsT.get_beta() : 1.0; const double curr_time = (Teuchos::nonnull(x_dotT) || Teuchos::nonnull(x_dotdotT)) ? inArgsT.get_t() : 0.0; for (int l = 0; l < inArgsT.Np(); ++l) { const Teuchos::RCP<const Thyra::VectorBase<ST> > p = inArgsT.get_p(l); if (Teuchos::nonnull(p)) { const Teuchos::RCP<const Tpetra_Vector> pT = ConverterT::getConstTpetraVector(p); const Teuchos::ArrayRCP<const ST> pT_constView = pT->get1dView(); ParamVec &sacado_param_vector = sacado_param_vec[l]; for (unsigned int k = 0; k < sacado_param_vector.size(); ++k) { sacado_param_vector[k].baseValue = pT_constView[k]; } } } // // Get the output arguments // const Teuchos::RCP<Tpetra_Vector> fT_out = Teuchos::nonnull(outArgsT.get_f()) ? ConverterT::getTpetraVector(outArgsT.get_f()) : Teuchos::null; const Teuchos::RCP<Tpetra_Operator> W_op_outT = Teuchos::nonnull(outArgsT.get_W_op()) ? ConverterT::getTpetraOperator(outArgsT.get_W_op()) : Teuchos::null; #ifdef WRITE_MASS_MATRIX_TO_MM_FILE //IK, 4/24/15: adding object to hold mass matrix to be written to matrix market file const Teuchos::RCP<Tpetra_Operator> Mass = Teuchos::nonnull(outArgsT.get_W_op()) ? ConverterT::getTpetraOperator(outArgsT.get_W_op()) : Teuchos::null; //IK, 4/24/15: needed for writing mass matrix out to matrix market file const Teuchos::RCP<Tpetra_Vector> ftmp = Teuchos::nonnull(outArgsT.get_f()) ? ConverterT::getTpetraVector(outArgsT.get_f()) : Teuchos::null; #endif // Cast W to a CrsMatrix, throw an exception if this fails const Teuchos::RCP<Tpetra_CrsMatrix> W_op_out_crsT = Teuchos::nonnull(W_op_outT) ? Teuchos::rcp_dynamic_cast<Tpetra_CrsMatrix>(W_op_outT, true) : Teuchos::null; #ifdef WRITE_MASS_MATRIX_TO_MM_FILE //IK, 4/24/15: adding object to hold mass matrix to be written to matrix market file const Teuchos::RCP<Tpetra_CrsMatrix> Mass_crs = Teuchos::nonnull(Mass) ? Teuchos::rcp_dynamic_cast<Tpetra_CrsMatrix>(Mass, true) : Teuchos::null; #endif // // Compute the functions // bool f_already_computed = false; // W matrix if (Teuchos::nonnull(W_op_out_crsT)) { app->computeGlobalJacobianT( alpha, beta, omega, curr_time, x_dotT.get(), x_dotdotT.get(), *xT, sacado_param_vec, fT_out.get(), *W_op_out_crsT); f_already_computed = true; } // df/dp for (int l = 0; l < outArgsT.Np(); ++l) { const Teuchos::RCP<Thyra::MultiVectorBase<ST> > dfdp_out = outArgsT.get_DfDp(l).getMultiVector(); const Teuchos::RCP<Tpetra_MultiVector> dfdp_outT = Teuchos::nonnull(dfdp_out) ? ConverterT::getTpetraMultiVector(dfdp_out) : Teuchos::null; if (Teuchos::nonnull(dfdp_outT)) { const Teuchos::RCP<ParamVec> p_vec = Teuchos::rcpFromRef(sacado_param_vec[l]); app->computeGlobalTangentT( 0.0, 0.0, 0.0, curr_time, false, x_dotT.get(), x_dotdotT.get(), *xT, sacado_param_vec, p_vec.get(), NULL, NULL, NULL, NULL, fT_out.get(), NULL, dfdp_outT.get()); f_already_computed = true; } } // f if (app->is_adjoint) { const Thyra::ModelEvaluatorBase::Derivative<ST> f_derivT( outArgsT.get_f(), Thyra::ModelEvaluatorBase::DERIV_TRANS_MV_BY_ROW); const Thyra::ModelEvaluatorBase::Derivative<ST> dummy_derivT; const int response_index = 0; // need to add capability for sending this in app->evaluateResponseDerivativeT( response_index, curr_time, x_dotT.get(), x_dotdotT.get(), *xT, sacado_param_vec, NULL, NULL, f_derivT, dummy_derivT, dummy_derivT, dummy_derivT); } else { if (Teuchos::nonnull(fT_out) && !f_already_computed) { app->computeGlobalResidualT( curr_time, x_dotT.get(), x_dotdotT.get(), *xT, sacado_param_vec, *fT_out); } } Teuchos::RCP<Tpetra_Vector> xtildeT = Teuchos::rcp(new Tpetra_Vector(xT->getMap())); //compute xtildeT applyLinvML(xT, xtildeT); #ifdef WRITE_TO_MATRIX_MARKET //writing to MatrixMarket for debug char name[100]; //create string for file name sprintf(name, "xT_%i.mm", mm_counter); Tpetra_MatrixMarket_Writer::writeDenseFile(name, xT); sprintf(name, "xtildeT_%i.mm", mm_counter); Tpetra_MatrixMarket_Writer::writeDenseFile(name, xtildeT); mm_counter++; #endif //std::cout <<"in HVDec evalModelImpl a, b= " << alpha << " "<< beta <<std::endl; if(Teuchos::nonnull(inArgsT.get_x_dot())){ std::cout <<"in the if-statement for the update" <<std::endl; fT_out->update(1.0, *xtildeT, 1.0); } // Response functions for (int j = 0; j < outArgsT.Ng(); ++j) { const Teuchos::RCP<Thyra::VectorBase<ST> > g_out = outArgsT.get_g(j); Teuchos::RCP<Tpetra_Vector> gT_out = Teuchos::nonnull(g_out) ? ConverterT::getTpetraVector(g_out) : Teuchos::null; const Thyra::ModelEvaluatorBase::Derivative<ST> dgdxT_out = outArgsT.get_DgDx(j); const Thyra::ModelEvaluatorBase::Derivative<ST> dgdxdotT_out = outArgsT.get_DgDx_dot(j); // AGS: x_dotdot time integrators not imlemented in Thyra ME yet const Thyra::ModelEvaluatorBase::Derivative<ST> dgdxdotdotT_out; sanitize_nans(dgdxT_out); sanitize_nans(dgdxdotT_out); sanitize_nans(dgdxdotdotT_out); // dg/dx, dg/dxdot if (!dgdxT_out.isEmpty() || !dgdxdotT_out.isEmpty()) { const Thyra::ModelEvaluatorBase::Derivative<ST> dummy_derivT; app->evaluateResponseDerivativeT( j, curr_time, x_dotT.get(), x_dotdotT.get(), *xT, sacado_param_vec, NULL, gT_out.get(), dgdxT_out, dgdxdotT_out, dgdxdotdotT_out, dummy_derivT); // Set gT_out to null to indicate that g_out was evaluated. gT_out = Teuchos::null; } // dg/dp for (int l = 0; l < outArgsT.Np(); ++l) { const Teuchos::RCP<Thyra::MultiVectorBase<ST> > dgdp_out = outArgsT.get_DgDp(j, l).getMultiVector(); const Teuchos::RCP<Tpetra_MultiVector> dgdpT_out = Teuchos::nonnull(dgdp_out) ? ConverterT::getTpetraMultiVector(dgdp_out) : Teuchos::null; if (Teuchos::nonnull(dgdpT_out)) { const Teuchos::RCP<ParamVec> p_vec = Teuchos::rcpFromRef(sacado_param_vec[l]); app->evaluateResponseTangentT( j, alpha, beta, omega, curr_time, false, x_dotT.get(), x_dotdotT.get(), *xT, sacado_param_vec, p_vec.get(), NULL, NULL, NULL, NULL, gT_out.get(), NULL, dgdpT_out.get()); gT_out = Teuchos::null; } } if (Teuchos::nonnull(gT_out)) { app->evaluateResponseT( j, curr_time, x_dotT.get(), x_dotdotT.get(), *xT, sacado_param_vec, *gT_out); } } }
virtual void evalModelImpl( const Thyra::ModelEvaluatorBase::InArgs<double> &in_args, const Thyra::ModelEvaluatorBase::OutArgs<double> &out_args ) const { const auto & x_in = in_args.get_x(); #ifndef NDEBUG TEUCHOS_ASSERT(!x_in.is_null()); #endif // create corresponding tpetra vector auto x_in_tpetra = Thyra::TpetraOperatorVectorExtraction<double,int,int>::getConstTpetraVector( x_in ); // compute F const auto & f_out = out_args.get_f(); if (!f_out.is_null()) { // Dissect in_args.get_p(0) into parameter sublists. const auto & p_in = in_args.get_p(0); #ifndef NDEBUG TEUCHOS_ASSERT(!p_in.is_null()); // Make sure the parameters aren't NaNs. for (int k = 0; k < p_in->space()->dim(); k++) { TEUCHOS_ASSERT(!std::isnan(Thyra::get_ele(*p_in, k))); } #endif // Fill the parameters into a std::map. const auto param_names = this->get_p_names(0); const double alph = Thyra::get_ele(*p_in, 0); auto f_out_tpetra = Thyra::TpetraOperatorVectorExtraction<double,int,int>::getTpetraVector( f_out ); const auto x_data = x_in_tpetra->getData(); auto f_data = f_out_tpetra->getDataNonConst(); for (size_t i = 0; i < f_data.size(); i++) { f_data[i] = x_data[i] * x_data[i] - alph; } } // Compute df/dp. const auto & derivMv = out_args.get_DfDp(0).getDerivativeMultiVector(); const auto & dfdp_out = derivMv.getMultiVector(); if (!dfdp_out.is_null()) { auto dfdp_out_tpetra = Thyra::TpetraOperatorVectorExtraction<double,int,int>::getTpetraMultiVector( dfdp_out ); TEUCHOS_ASSERT_EQUALITY(dfdp_out_tpetra->getNumVectors(), 1); auto out = dfdp_out_tpetra->getVectorNonConst(0); auto out_data = out->getDataNonConst(); for (size_t k = 0; k < out_data.size(); k++) { out_data[k] = -1.0; } } // Fill Jacobian. const auto & W_out = out_args.get_W_op(); if(!W_out.is_null()) { auto W_outT = Thyra::TpetraOperatorVectorExtraction<double,int,int>::getTpetraOperator( W_out ); const auto & jac = Teuchos::rcp_dynamic_cast<jac_sqrt_alpha>(W_outT, true); jac->set_x0(*x_in_tpetra); } return; }
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 ForwardSensitivityExplicitModelEvaluator<Scalar>::evalModelImpl( const Thyra::ModelEvaluatorBase::InArgs<Scalar> &inArgs, const Thyra::ModelEvaluatorBase::OutArgs<Scalar> &outArgs ) const { using Teuchos::rcp_dynamic_cast; typedef Teuchos::ScalarTraits<Scalar> ST; typedef Thyra::ModelEvaluatorBase MEB; typedef Teuchos::VerboseObjectTempState<Thyra::ModelEvaluatorBase> VOTSME; THYRA_MODEL_EVALUATOR_DECORATOR_EVAL_MODEL_GEN_BEGIN( "ForwardSensitivityExplicitModelEvaluator", inArgs, outArgs, Teuchos::null ); // // Update the derivative matrices if they are not already updated for the // given time!. // { RYTHMOS_FUNC_TIME_MONITOR_DIFF( "Rythmos:ForwardSensitivityExplicitModelEvaluator::evalModel: computeMatrices", Rythmos_FSEME ); computeDerivativeMatrices(inArgs); } // // InArgs // RCP<const Thyra::DefaultMultiVectorProductVector<Scalar> > s_bar = rcp_dynamic_cast<const Thyra::DefaultMultiVectorProductVector<Scalar> >( inArgs.get_x().assert_not_null(), true ); RCP<const Thyra::MultiVectorBase<Scalar> > S = s_bar->getMultiVector(); // // OutArgs // RCP<Thyra::DefaultMultiVectorProductVector<Scalar> > f_sens = rcp_dynamic_cast<Thyra::DefaultMultiVectorProductVector<Scalar> >( outArgs.get_f(), true ); RCP<Thyra::MultiVectorBase<Scalar> > F_sens = f_sens->getNonconstMultiVector().assert_not_null(); // // Compute the requested functions // if(!is_null(F_sens)) { RYTHMOS_FUNC_TIME_MONITOR_DIFF( "Rythmos:ForwardSensitivityExplicitModelEvaluator::evalModel: computeSens", Rythmos_FSEME ); // Form the residual: df/dx * S + df/dp // F_sens = df/dx * S Thyra::apply( *DfDx_, Thyra::NOTRANS, *S, F_sens.ptr(), ST::one(), ST::zero() ); // F_sens += d(f)/d(p) Vp_V( F_sens.ptr(), *DfDp_ ); } 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(); }
void ImplicitRKModelEvaluator<Scalar>::initializeIRKModel( const RCP<const Thyra::ModelEvaluator<Scalar> >& daeModel, const Thyra::ModelEvaluatorBase::InArgs<Scalar>& basePoint, const RCP<Thyra::LinearOpWithSolveFactoryBase<Scalar> >& irk_W_factory, const RCP<const RKButcherTableauBase<Scalar> >& irkButcherTableau ) { // ToDo: Assert input arguments! // How do I verify the basePoint is an authentic InArgs from daeModel? TEST_FOR_EXCEPTION( is_null(basePoint.get_x()), std::logic_error, "Error! The basepoint x vector is null!" ); TEST_FOR_EXCEPTION( is_null(daeModel), std::logic_error, "Error! The model evaluator pointer is null!" ); TEST_FOR_EXCEPTION( !daeModel->get_x_space()->isCompatible(*(basePoint.get_x()->space())), std::logic_error, "Error! The basepoint input arguments are incompatible with the model evaluator vector space!" ); TEST_FOR_EXCEPT(is_null(irk_W_factory)); daeModel_ = daeModel; basePoint_ = basePoint; irk_W_factory_ = irk_W_factory; irkButcherTableau_ = irkButcherTableau; const int numStages = irkButcherTableau_->numStages(); x_bar_space_ = productVectorSpace(daeModel_->get_x_space(),numStages); f_bar_space_ = productVectorSpace(daeModel_->get_f_space(),numStages); // HACK! Remove the preconditioner factory for now! if (irk_W_factory_->acceptsPreconditionerFactory()) irk_W_factory_->unsetPreconditionerFactory(); // ToDo: create the block diagonal preconditioner factory and set this on // irk_W_factory_! // Set up prototypical InArgs { typedef Thyra::ModelEvaluatorBase MEB; MEB::InArgsSetup<Scalar> inArgs; inArgs.setModelEvalDescription(this->description()); inArgs.setSupports(MEB::IN_ARG_x); inArgs_ = inArgs; } // Set up prototypical OutArgs { typedef Thyra::ModelEvaluatorBase MEB; MEB::OutArgsSetup<Scalar> outArgs; outArgs.setModelEvalDescription(this->description()); outArgs.setSupports(MEB::OUT_ARG_f); outArgs.setSupports(MEB::OUT_ARG_W_op); outArgs_ = outArgs; } // Set up nominal values nominalValues_ = inArgs_; isInitialized_ = true; }
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 Piro::VelocityVerletSolver<Scalar>::evalModelImpl( const Thyra::ModelEvaluatorBase::InArgs<Scalar>& inArgs, const Thyra::ModelEvaluatorBase::OutArgs<Scalar>& outArgs) const { using Teuchos::RCP; using Teuchos::rcp; // TODO: Support more than 1 parameter and 1 response const int j = 0; const int l = 0; // Parse InArgs RCP<const Thyra::VectorBase<Scalar> > p_in; if (num_p > 0) { p_in = inArgs.get_p(l); } // Parse OutArgs RCP<Thyra::VectorBase<Scalar> > g_out; if (num_g > 0) { g_out = outArgs.get_g(j); } const RCP<Thyra::VectorBase<Scalar> > gx_out = outArgs.get_g(num_g); Teuchos::RCP<Thyra::VectorBase<Scalar> > x = inArgs.get_x()->clone_v(); Teuchos::RCP<Thyra::VectorBase<Scalar> > v = inArgs.get_x_dot()->clone_v(); Teuchos::RCP<Thyra::VectorBase<Scalar> > a = Thyra::createMember<Scalar>(model->get_f_space()); RCP<Thyra::VectorBase<Scalar> > finalSolution; // Zero out the acceleration vector put_scalar(0.0, a.ptr()); TEUCHOS_TEST_FOR_EXCEPTION(v == Teuchos::null || x == Teuchos::null, Teuchos::Exceptions::InvalidParameter, std::endl << "Error in Piro::VelocityVerletSolver " << "Requires initial x and x_dot: " << std::endl); Scalar t = t_init; // Observe initial condition if (observer != Teuchos::null) observer->observeSolution(*x, t); Scalar vo = norm_2(*v); *out << "Initial Velocity = " << vo << std::endl; if (Teuchos::VERB_MEDIUM <= solnVerbLevel) *out << std::endl; Thyra::ModelEvaluatorBase::InArgs<Scalar> model_inargs = model->createInArgs(); Thyra::ModelEvaluatorBase::OutArgs<Scalar> model_outargs = model->createOutArgs(); model_inargs.set_x(x); if (num_p > 0) model_inargs.set_p(0, p_in); model_outargs.set_f(a); if (g_out != Teuchos::null) model_outargs.set_g(0, g_out); Scalar ddt = 0.5 * delta_t * delta_t; // Calculate acceleration at time 0 model->evalModel(model_inargs, model_outargs); for (int timeStep = 1; timeStep <= numTimeSteps; timeStep++) { // x->Update(delta_t, *v, ddt, *a, 1.0); V_StVpStV(x.ptr(), delta_t, *v, ddt, *a); t += delta_t; model_inargs.set_t(t); // v->Update(0.5*delta_t, *a, 1.0); V_StV(v.ptr(), 0.5 * delta_t, *a); //calc a(x,t,p); model->evalModel(model_inargs, model_outargs); // v->Update(0.5*delta_t, *a, 1.0); V_StV(v.ptr(), 0.5 * delta_t, *a); // Observe completed time step if (observer != Teuchos::null) observer->observeSolution(*x, t); } // return the final solution as an additional g-vector, if requested if (finalSolution != Teuchos::null) finalSolution = x->clone_v(); // Return the final solution as an additional g-vector, if requested if (Teuchos::nonnull(gx_out)) { Thyra::copy(*finalSolution, gx_out.ptr()); } }
void Piro::SteadyStateSolver<Scalar>::evalConvergedModel( const Thyra::ModelEvaluatorBase::InArgs<Scalar>& modelInArgs, const Thyra::ModelEvaluatorBase::OutArgs<Scalar>& outArgs) const { using Teuchos::RCP; using Teuchos::rcp; // Solution at convergence is the response at index num_g_ { const RCP<Thyra::VectorBase<Scalar> > gx_out = outArgs.get_g(num_g_); if (Teuchos::nonnull(gx_out)) { Thyra::copy(*modelInArgs.get_x(), gx_out.ptr()); } } // Setup output for final evalution of underlying model Thyra::ModelEvaluatorBase::OutArgs<Scalar> modelOutArgs = model_->createOutArgs(); { // Responses for (int j = 0; j < num_g_; ++j) { const RCP<Thyra::VectorBase<Scalar> > g_out = outArgs.get_g(j); // Forward to underlying model modelOutArgs.set_g(j, g_out); } // Jacobian { bool jacobianRequired = false; for (int j = 0; j <= num_g_; ++j) { for (int l = 0; l < num_p_; ++l) { const Thyra::ModelEvaluatorBase::DerivativeSupport dgdp_support = outArgs.supports(Thyra::ModelEvaluatorBase::OUT_ARG_DgDp, j, l); if (!dgdp_support.none()) { const Thyra::ModelEvaluatorBase::Derivative<Scalar> dgdp_deriv = outArgs.get_DgDp(j, l); if (!dgdp_deriv.isEmpty()) { jacobianRequired = true; } } } } if (jacobianRequired) { const RCP<Thyra::LinearOpWithSolveBase<Scalar> > jacobian = model_->create_W(); modelOutArgs.set_W(jacobian); } } // DfDp derivatives for (int l = 0; l < num_p_; ++l) { Thyra::ModelEvaluatorBase::DerivativeSupport dfdp_request; for (int j = 0; j <= num_g_; ++j) { const Thyra::ModelEvaluatorBase::DerivativeSupport dgdp_support = outArgs.supports(Thyra::ModelEvaluatorBase::OUT_ARG_DgDp, j, l); if (!dgdp_support.none()) { const Thyra::ModelEvaluatorBase::Derivative<Scalar> dgdp_deriv = outArgs.get_DgDp(j, l); if (Teuchos::nonnull(dgdp_deriv.getLinearOp())) { dfdp_request.plus(Thyra::ModelEvaluatorBase::DERIV_LINEAR_OP); } else if (Teuchos::nonnull(dgdp_deriv.getMultiVector())) { dfdp_request.plus(Thyra::ModelEvaluatorBase::DERIV_MV_JACOBIAN_FORM); } } } if (!dfdp_request.none()) { Thyra::ModelEvaluatorBase::Derivative<Scalar> dfdp_deriv; if (dfdp_request.supports(Thyra::ModelEvaluatorBase::DERIV_MV_JACOBIAN_FORM)) { dfdp_deriv = Thyra::create_DfDp_mv(*model_, l, Thyra::ModelEvaluatorBase::DERIV_MV_JACOBIAN_FORM); } else if (dfdp_request.supports(Thyra::ModelEvaluatorBase::DERIV_LINEAR_OP)) { dfdp_deriv = model_->create_DfDp_op(l); } modelOutArgs.set_DfDp(l, dfdp_deriv); } } // DgDx derivatives for (int j = 0; j < num_g_; ++j) { Thyra::ModelEvaluatorBase::DerivativeSupport dgdx_request; for (int l = 0; l < num_p_; ++l) { const Thyra::ModelEvaluatorBase::DerivativeSupport dgdp_support = outArgs.supports(Thyra::ModelEvaluatorBase::OUT_ARG_DgDp, j, l); if (!dgdp_support.none()) { const Thyra::ModelEvaluatorBase::Derivative<Scalar> dgdp_deriv = outArgs.get_DgDp(j, l); if (!dgdp_deriv.isEmpty()) { const bool dgdp_mvGrad_required = Teuchos::nonnull(dgdp_deriv.getMultiVector()) && dgdp_deriv.getMultiVectorOrientation() == Thyra::ModelEvaluatorBase::DERIV_MV_GRADIENT_FORM; if (dgdp_mvGrad_required) { dgdx_request.plus(Thyra::ModelEvaluatorBase::DERIV_MV_GRADIENT_FORM); } else { dgdx_request.plus(Thyra::ModelEvaluatorBase::DERIV_LINEAR_OP); } } } } if (!dgdx_request.none()) { Thyra::ModelEvaluatorBase::Derivative<Scalar> dgdx_deriv; if (dgdx_request.supports(Thyra::ModelEvaluatorBase::DERIV_MV_GRADIENT_FORM)) { dgdx_deriv = Thyra::create_DgDx_mv(*model_, j, Thyra::ModelEvaluatorBase::DERIV_MV_GRADIENT_FORM); } else if (dgdx_request.supports(Thyra::ModelEvaluatorBase::DERIV_LINEAR_OP)) { dgdx_deriv = model_->create_DgDx_op(j); } modelOutArgs.set_DgDx(j, dgdx_deriv); } } // DgDp derivatives for (int l = 0; l < num_p_; ++l) { for (int j = 0; j < num_g_; ++j) { const Thyra::ModelEvaluatorBase::DerivativeSupport dgdp_support = outArgs.supports(Thyra::ModelEvaluatorBase::OUT_ARG_DgDp, j, l); if (!dgdp_support.none()) { const Thyra::ModelEvaluatorBase::Derivative<Scalar> dgdp_deriv = outArgs.get_DgDp(j, l); Thyra::ModelEvaluatorBase::Derivative<Scalar> model_dgdp_deriv; const RCP<Thyra::LinearOpBase<Scalar> > dgdp_op = dgdp_deriv.getLinearOp(); if (Teuchos::nonnull(dgdp_op)) { model_dgdp_deriv = model_->create_DgDp_op(j, l); } else { model_dgdp_deriv = dgdp_deriv; } if (!model_dgdp_deriv.isEmpty()) { modelOutArgs.set_DgDp(j, l, model_dgdp_deriv); } } } } } // Evaluate underlying model model_->evalModel(modelInArgs, modelOutArgs); // Assemble user-requested sensitivities if (modelOutArgs.supports(Thyra::ModelEvaluatorBase::OUT_ARG_W)) { const RCP<Thyra::LinearOpWithSolveBase<Scalar> > jacobian = modelOutArgs.get_W(); if (Teuchos::nonnull(jacobian)) { for (int l = 0; l < num_p_; ++l) { const Thyra::ModelEvaluatorBase::DerivativeSupport dfdp_support = modelOutArgs.supports(Thyra::ModelEvaluatorBase::OUT_ARG_DfDp, l); if (!dfdp_support.none()) { const Thyra::ModelEvaluatorBase::Derivative<Scalar> dfdp_deriv = modelOutArgs.get_DfDp(l); const RCP<Thyra::MultiVectorBase<Scalar> > dfdp_mv = dfdp_deriv.getMultiVector(); RCP<Thyra::LinearOpBase<Scalar> > dfdp_op = dfdp_deriv.getLinearOp(); if (Teuchos::is_null(dfdp_op)) { dfdp_op = dfdp_mv; } const Thyra::ModelEvaluatorBase::Derivative<Scalar> dxdp_deriv = outArgs.get_DgDp(num_g_, l); const RCP<Thyra::LinearOpBase<Scalar> > dxdp_op = dxdp_deriv.getLinearOp(); const RCP<Thyra::MultiVectorBase<Scalar> > dxdp_mv = dxdp_deriv.getMultiVector(); RCP<const Thyra::LinearOpBase<Scalar> > minus_dxdp_op; RCP<Thyra::MultiVectorBase<Scalar> > minus_dxdp_mv; if (Teuchos::nonnull(dfdp_mv)) { if (Teuchos::nonnull(dxdp_mv)) { minus_dxdp_mv = dxdp_mv; // Use user-provided object as temporary } else { minus_dxdp_mv = Thyra::createMembers(model_->get_x_space(), model_->get_p_space(l)); minus_dxdp_op = minus_dxdp_mv; } } if (Teuchos::is_null(minus_dxdp_op)) { const RCP<const Thyra::LinearOpBase<Scalar> > dfdx_inv_op = Thyra::inverse<Scalar>(jacobian); minus_dxdp_op = Thyra::multiply<Scalar>(dfdx_inv_op, dfdp_op); } if (Teuchos::nonnull(minus_dxdp_mv)) { Thyra::assign(minus_dxdp_mv.ptr(), Teuchos::ScalarTraits<Scalar>::zero()); const Thyra::SolveCriteria<Scalar> defaultSolveCriteria; const Thyra::SolveStatus<Scalar> solveStatus = Thyra::solve( *jacobian, Thyra::NOTRANS, *dfdp_mv, minus_dxdp_mv.ptr(), Teuchos::ptr(&defaultSolveCriteria)); TEUCHOS_TEST_FOR_EXCEPTION( solveStatus.solveStatus == Thyra::SOLVE_STATUS_UNCONVERGED, std::runtime_error, "Jacobian solver failed to converge"); } // Solution sensitivities if (Teuchos::nonnull(dxdp_mv)) { minus_dxdp_mv = Teuchos::null; // Invalidates temporary Thyra::scale(-Teuchos::ScalarTraits<Scalar>::one(), dxdp_mv.ptr()); } else if (Teuchos::nonnull(dxdp_op)) { const RCP<Thyra::DefaultMultipliedLinearOp<Scalar> > dxdp_op_downcasted = Teuchos::rcp_dynamic_cast<Thyra::DefaultMultipliedLinearOp<Scalar> >(dxdp_op); TEUCHOS_TEST_FOR_EXCEPTION( Teuchos::is_null(dxdp_op_downcasted), std::invalid_argument, "Illegal operator for DgDp(" << "j = " << num_g_ << ", " << "index l = " << l << ")\n"); const RCP<const Thyra::LinearOpBase<Scalar> > minus_id_op = Thyra::scale<Scalar>(-Teuchos::ScalarTraits<Scalar>::one(), Thyra::identity(dfdp_op->domain())); dxdp_op_downcasted->initialize(Teuchos::tuple(minus_dxdp_op, minus_id_op)); } // Response sensitivities for (int j = 0; j < num_g_; ++j) { const Thyra::ModelEvaluatorBase::DerivativeSupport dgdp_support = outArgs.supports(Thyra::ModelEvaluatorBase::OUT_ARG_DgDp, j, l); if (!dgdp_support.none()) { const Thyra::ModelEvaluatorBase::Derivative<Scalar> dgdp_deriv = outArgs.get_DgDp(j, l); if (!dgdp_deriv.isEmpty()) { const Thyra::ModelEvaluatorBase::Derivative<Scalar> dgdx_deriv = modelOutArgs.get_DgDx(j); const RCP<const Thyra::MultiVectorBase<Scalar> > dgdx_mv = dgdx_deriv.getMultiVector(); RCP<const Thyra::LinearOpBase<Scalar> > dgdx_op = dgdx_deriv.getLinearOp(); if (Teuchos::is_null(dgdx_op)) { dgdx_op = Thyra::adjoint<Scalar>(dgdx_mv); } const RCP<Thyra::LinearOpBase<Scalar> > dgdp_op = dgdp_deriv.getLinearOp(); if (Teuchos::nonnull(dgdp_op)) { const RCP<Thyra::DefaultAddedLinearOp<Scalar> > dgdp_op_downcasted = Teuchos::rcp_dynamic_cast<Thyra::DefaultAddedLinearOp<Scalar> >(dgdp_op); TEUCHOS_TEST_FOR_EXCEPTION( Teuchos::is_null(dgdp_op_downcasted), std::invalid_argument, "Illegal operator for DgDp(" << "j = " << j << ", " << "index l = " << l << ")\n"); dgdp_op_downcasted->uninitialize(); const RCP<const Thyra::LinearOpBase<Scalar> > implicit_dgdp_op = Thyra::multiply<Scalar>( Thyra::scale<Scalar>(-Teuchos::ScalarTraits<Scalar>::one(), dgdx_op), minus_dxdp_op); const RCP<const Thyra::LinearOpBase<Scalar> > model_dgdp_op = modelOutArgs.get_DgDp(j, l).getLinearOp(); Teuchos::Array<RCP<const Thyra::LinearOpBase<Scalar> > > op_args(2); op_args[0] = model_dgdp_op; op_args[1] = implicit_dgdp_op; dgdp_op_downcasted->initialize(op_args); } const RCP<Thyra::MultiVectorBase<Scalar> > dgdp_mv = dgdp_deriv.getMultiVector(); if (Teuchos::nonnull(dgdp_mv)) { if (dgdp_deriv.getMultiVectorOrientation() == Thyra::ModelEvaluatorBase::DERIV_MV_GRADIENT_FORM) { if (Teuchos::nonnull(dxdp_mv)) { Thyra::apply( *dxdp_mv, Thyra::TRANS, *dgdx_mv, dgdp_mv.ptr(), Teuchos::ScalarTraits<Scalar>::one(), Teuchos::ScalarTraits<Scalar>::one()); } else { Thyra::apply( *minus_dxdp_mv, Thyra::TRANS, *dgdx_mv, dgdp_mv.ptr(), -Teuchos::ScalarTraits<Scalar>::one(), Teuchos::ScalarTraits<Scalar>::one()); } } else { if (Teuchos::nonnull(dxdp_mv)) { Thyra::apply( *dgdx_op, Thyra::NOTRANS, *dxdp_mv, dgdp_mv.ptr(), Teuchos::ScalarTraits<Scalar>::one(), Teuchos::ScalarTraits<Scalar>::one()); } else { Thyra::apply( *dgdx_op, Thyra::NOTRANS, *minus_dxdp_mv, dgdp_mv.ptr(), -Teuchos::ScalarTraits<Scalar>::one(), Teuchos::ScalarTraits<Scalar>::one()); } } } } } } } } } } }
virtual void evalModelImpl( const Thyra::ModelEvaluatorBase::InArgs<double> &in_args, const Thyra::ModelEvaluatorBase::OutArgs<double> &out_args ) const { const double alpha = in_args.get_alpha(); double beta = in_args.get_beta(); // From packages/piro/test/MockModelEval_A.cpp if (alpha == 0.0 && beta == 0.0) { // beta = 1.0; } #ifndef NDEBUG TEUCHOS_ASSERT_EQUALITY(alpha, 0.0); TEUCHOS_ASSERT_EQUALITY(beta, 1.0); #endif const auto & x_in = in_args.get_x(); #ifndef NDEBUG TEUCHOS_ASSERT(!x_in.is_null()); #endif // create corresponding tpetra vector auto x_in_tpetra = Thyra::TpetraOperatorVectorExtraction<double,int,int>::getConstTpetraVector( x_in ); // Dissect in_args.get_p(0) into parameter sublists. const auto & p_in = in_args.get_p(0); #ifndef NDEBUG TEUCHOS_ASSERT(!p_in.is_null()); #endif #ifndef NDEBUG // Make sure the parameters aren't NaNs. for (int k = 0; k < p_in->space()->dim(); k++) { TEUCHOS_ASSERT(!std::isnan(Thyra::get_ele(*p_in, k))); } #endif // Fill the parameters into a std::map. const auto param_names = this->get_p_names(0); std::map<std::string, double> params; for (int k = 0; k < p_in->space()->dim(); k++) { params[(*param_names)[k]] = Thyra::get_ele(*p_in, k); } // compute F const auto & f_out = out_args.get_f(); if (!f_out.is_null()) { auto f_out_tpetra = Thyra::TpetraOperatorVectorExtraction<double,int,int>::getTpetraVector( f_out ); this->f_->set_parameters(params, {}); this->f_->apply( *x_in_tpetra, *f_out_tpetra ); } // Compute df/dp. const auto & derivMv = out_args.get_DfDp(0).getDerivativeMultiVector(); const auto & dfdp_out = derivMv.getMultiVector(); if (!dfdp_out.is_null()) { auto dfdp_out_tpetra = Thyra::TpetraOperatorVectorExtraction<double,int,int>::getTpetraMultiVector( dfdp_out ); const int numAllParams = this->get_p_space(0)->dim(); TEUCHOS_ASSERT_EQUALITY( numAllParams, dfdp_out_tpetra->getNumVectors() ); // Compute all derivatives. this->dfdp_->set_parameters(params, {}); for (int k = 0; k < numAllParams; k++) { this->dfdp_->apply( *x_in_tpetra, *dfdp_out_tpetra->getVectorNonConst(k) ); } } // Fill Jacobian. const auto & W_out = out_args.get_W_op(); if(!W_out.is_null()) { auto W_outT = Thyra::TpetraOperatorVectorExtraction<double,int,int>::getTpetraOperator( W_out ); const auto & jac = Teuchos::rcp_dynamic_cast<nosh::fvm_operator>(W_outT, true); std::shared_ptr<const Tpetra::Vector<double,int,int>> x_std = Teuchos::get_shared_ptr(x_in_tpetra); jac->set_parameters(params, {{"u0", x_std}}); } // // Fill preconditioner. // const auto & WPrec_out = out_args.get_W_prec(); // if(!WPrec_out.is_null()) { // auto WPrec_outT = // Thyra::TpetraOperatorVectorExtraction<double,int,int>::getTpetraOperator( // WPrec_out->getNonconstUnspecifiedPrecOp() // ); // const auto & keoPrec = // Teuchos::rcp_dynamic_cast<nosh::keo_regularized>(WPrec_outT, true); // keoPrec->rebuild( // params, // *x_in_tpetra // ); // } return; }