void Piro::LOCASolver<Scalar>::evalModelImpl( const Thyra::ModelEvaluatorBase::InArgs<Scalar>& inArgs, const Thyra::ModelEvaluatorBase::OutArgs<Scalar>& outArgs) const { const int l = 0; // TODO: Allow user to select parameter index const Teuchos::RCP<const Thyra::VectorBase<Scalar> > p_inargs = inArgs.get_p(l); // Forward parameter values to the LOCA stepper { const Teuchos::RCP<const Thyra::VectorBase<Scalar> > p_inargs_or_nominal = Teuchos::nonnull(p_inargs) ? p_inargs : this->getNominalValues().get_p(l); const Thyra::ConstDetachedVectorView<Scalar> p_init_values(p_inargs_or_nominal); const Teuchos_Ordinal p_entry_count = p_init_values.subDim(); TEUCHOS_ASSERT(p_entry_count == Teuchos::as<Teuchos_Ordinal>(paramVector_.length())); for (Teuchos_Ordinal k = 0; k < p_entry_count; ++k) { paramVector_[k] = p_init_values[k]; } group_->setParams(paramVector_); } stepper_->reset(globalData_, group_, locaStatusTests_, noxStatusTests_, piroParams_); const LOCA::Abstract::Iterator::IteratorStatus status = stepper_->run(); if (status == LOCA::Abstract::Iterator::Finished) { std::cerr << "Continuation Stepper Finished.\n"; } else if (status == LOCA::Abstract::Iterator::NotFinished) { std::cerr << "Continuation Stepper did not reach final value.\n"; } else { std::cerr << "Nonlinear solver failed to converge.\n"; outArgs.setFailed(); } const Teuchos::RCP<Thyra::VectorBase<Scalar> > x_outargs = outArgs.get_g(this->num_g()); const Teuchos::RCP<Thyra::VectorBase<Scalar> > x_final = Teuchos::nonnull(x_outargs) ? x_outargs : Thyra::createMember(this->get_g_space(this->num_g())); { // Deep copy final solution from LOCA group NOX::Thyra::Vector finalSolution(x_final); finalSolution = group_->getX(); } // Compute responses for the final solution { Thyra::ModelEvaluatorBase::InArgs<Scalar> modelInArgs = this->getModel().createInArgs(); { modelInArgs.set_x(x_final); modelInArgs.set_p(l, p_inargs); } this->evalConvergedModel(modelInArgs, outArgs); } }
Thyra::ModelEvaluatorBase::InArgs<Scalar> Piro::VelocityVerletSolver<Scalar>::getNominalValues() const { Thyra::ModelEvaluatorBase::InArgs<Scalar> result = this->createInArgs(); const Thyra::ModelEvaluatorBase::InArgs<Scalar> modelNominalValues = model->getNominalValues(); for (int l = 0; l < num_p; ++l) { result.set_p(l, modelNominalValues.get_p(l)); } return result; }
void DiagonalROME<Scalar>::evalModelImpl( const Thyra::ModelEvaluatorBase::InArgs<Scalar>& inArgs, const Thyra::ModelEvaluatorBase::OutArgs<Scalar>& outArgs ) const { using Teuchos::as; using Teuchos::outArg; typedef Teuchos::ScalarTraits<Scalar> ST; using Thyra::get_mv; using Thyra::ConstDetachedSpmdVectorView; using Thyra::DetachedSpmdVectorView; typedef Thyra::Ordinal Ordinal; typedef Thyra::ModelEvaluatorBase MEB; typedef MEB::DerivativeMultiVector<Scalar> DMV; const ConstDetachedSpmdVectorView<Scalar> p(inArgs.get_p(0)); const ConstDetachedSpmdVectorView<Scalar> ps(ps_); const ConstDetachedSpmdVectorView<Scalar> diag(diag_); const ConstDetachedSpmdVectorView<Scalar> s_bar(s_bar_); // g(p) if (!is_null(outArgs.get_g(0))) { Scalar g_val = ST::zero(); for (Ordinal i = 0; i < p.subDim(); ++i) { const Scalar p_ps = p[i] - ps[i]; g_val += diag[i] * p_ps*p_ps; if (nonlinearTermFactor_ != ST::zero()) { g_val += nonlinearTermFactor_ * p_ps * p_ps * p_ps; } } Scalar global_g_val; Teuchos::reduceAll<Ordinal, Scalar>(*comm_, Teuchos::REDUCE_SUM, g_val, outArg(global_g_val) ); DetachedSpmdVectorView<Scalar>(outArgs.get_g(0))[0] = as<Scalar>(0.5) * global_g_val + g_offset_; } // DgDp[i] if (!outArgs.get_DgDp(0,0).isEmpty()) { const RCP<Thyra::MultiVectorBase<Scalar> > DgDp_trans_mv = get_mv<Scalar>(outArgs.get_DgDp(0,0), "DgDp^T", MEB::DERIV_TRANS_MV_BY_ROW); const DetachedSpmdVectorView<Scalar> DgDp_grad(DgDp_trans_mv->col(0)); for (Thyra::Ordinal i = 0; i < p.subDim(); ++i) { const Scalar p_ps = p[i] - ps[i]; Scalar DgDp_grad_i = diag[i] * p_ps; if (nonlinearTermFactor_ != ST::zero()) { DgDp_grad_i += as<Scalar>(1.5) * nonlinearTermFactor_ * p_ps * p_ps; } DgDp_grad[i] = DgDp_grad_i / s_bar[i]; } } }
int main(int argc, char *argv[]) { int status=0; // 0 = pass, failures are incremented bool success = true; Teuchos::GlobalMPISession mpiSession(&argc,&argv); #ifdef ENABLE_CHECK_FPE // Catch FPEs _mm_setcsr(_MM_MASK_MASK &~ (_MM_MASK_OVERFLOW | _MM_MASK_INVALID | _MM_MASK_DIV_ZERO) ); #endif using Teuchos::RCP; using Teuchos::rcp; RCP<Teuchos::FancyOStream> out(Teuchos::VerboseObjectBase::getDefaultOStream()); // Command-line argument for input file std::string xmlfilename; if(argc > 1){ if(!strcmp(argv[1],"--help")){ printf("albany [inputfile.xml]\n"); exit(1); } else xmlfilename = argv[1]; } else xmlfilename = "input.xml"; try { RCP<Teuchos::Time> totalTime = Teuchos::TimeMonitor::getNewTimer("Albany: ***Total Time***"); RCP<Teuchos::Time> setupTime = Teuchos::TimeMonitor::getNewTimer("Albany: Setup Time"); Teuchos::TimeMonitor totalTimer(*totalTime); //start timer Teuchos::TimeMonitor setupTimer(*setupTime); //start timer Albany::SolverFactory slvrfctry(xmlfilename, Albany_MPI_COMM_WORLD); RCP<Epetra_Comm> appComm = Albany::createEpetraCommFromMpiComm(Albany_MPI_COMM_WORLD); RCP<Albany::Application> app; const RCP<Thyra::ModelEvaluator<double> > solver = slvrfctry.createThyraSolverAndGetAlbanyApp(app, appComm, appComm); setupTimer.~TimeMonitor(); Teuchos::ParameterList &solveParams = slvrfctry.getAnalysisParameters().sublist("Solve", /*mustAlreadyExist =*/ false); // By default, request the sensitivities if not explicitly disabled solveParams.get("Compute Sensitivities", true); Teuchos::Array<Teuchos::RCP<const Thyra::VectorBase<double> > > thyraResponses; Teuchos::Array<Teuchos::Array<Teuchos::RCP<const Thyra::MultiVectorBase<double> > > > thyraSensitivities; // The PoissonSchrodinger_SchroPo and PoissonSchroMosCap1D tests seg fault as albanyApp is null - // For now, do not resize the response vectors. FIXME sort out this issue. if(Teuchos::nonnull(app)) Piro::PerformSolveBase(*solver, solveParams, thyraResponses, thyraSensitivities, app->getAdaptSolMgr()->getSolObserver()); else Piro::PerformSolveBase(*solver, solveParams, thyraResponses, thyraSensitivities); *out << "After main solve" << std::endl; Teuchos::Array<Teuchos::RCP<const Epetra_Vector> > responses; Teuchos::Array<Teuchos::Array<Teuchos::RCP<const Epetra_MultiVector> > > sensitivities; epetraFromThyra(appComm, thyraResponses, thyraSensitivities, responses, sensitivities); const int num_p = solver->Np(); // Number of *vectors* of parameters const int num_g = solver->Ng(); // Number of *vectors* of responses *out << "Finished eval of first model: Params, Responses " << std::setprecision(12) << std::endl; const Thyra::ModelEvaluatorBase::InArgs<double> nominal = solver->getNominalValues(); for (int i=0; i<num_p; i++) { const Teuchos::RCP<const Epetra_Vector> p_init = epetraVectorFromThyra(appComm, nominal.get_p(i)); p_init->Print(*out << "\nParameter vector " << i << ":\n"); } for (int i=0; i<num_g-1; i++) { const RCP<const Epetra_Vector> g = responses[i]; bool is_scalar = true; if (app != Teuchos::null) is_scalar = app->getResponse(i)->isScalarResponse(); if (is_scalar) { g->Print(*out << "\nResponse vector " << i << ":\n"); if (num_p == 0) { // Just calculate regression data status += slvrfctry.checkSolveTestResults(i, 0, g.get(), NULL); } else { for (int j=0; j<num_p; j++) { const RCP<const Epetra_MultiVector> dgdp = sensitivities[i][j]; if (Teuchos::nonnull(dgdp)) { dgdp->Print(*out << "\nSensitivities (" << i << "," << j << "):!\n"); } status += slvrfctry.checkSolveTestResults(i, j, g.get(), dgdp.get()); } } } } const RCP<const Epetra_Vector> xfinal = responses.back(); double mnv; xfinal->MeanValue(&mnv); *out << "Main_Solve: MeanValue of final solution " << mnv << std::endl; *out << "\nNumber of Failed Comparisons: " << status << std::endl; } TEUCHOS_STANDARD_CATCH_STATEMENTS(true, std::cerr, success); if (!success) status+=10000; Teuchos::TimeMonitor::summarize(*out,false,true,false/*zero timers*/); return status; }
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); } } }
// The solve is done in the felix_driver_run function, and the solution is passed back to Glimmer-CISM // IK, 12/3/13: time_inc_yr and cur_time_yr are not used here... void felix_driver_run(FelixToGlimmer * ftg_ptr, double& cur_time_yr, double time_inc_yr) { //IK, 12/9/13: how come FancyOStream prints an all processors?? Teuchos::RCP<Teuchos::FancyOStream> out(Teuchos::VerboseObjectBase::getDefaultOStream()); if (debug_output_verbosity != 0 & mpiCommT->getRank() == 0) { std::cout << "In felix_driver_run, cur_time, time_inc = " << cur_time_yr << " " << time_inc_yr << std::endl; } // --------------------------------------------- // get u and v velocity solution from Glimmer-CISM // IK, 11/26/13: need to concatenate these into a single solve for initial condition for Albany/FELIX solve // IK, 3/14/14: moved this step to felix_driver_run from felix_driver init, since we still want to grab and u and v velocities for CISM if the mesh hasn't changed, // in which case only felix_driver_run will be called, not felix_driver_init. // --------------------------------------------- if (debug_output_verbosity != 0 & mpiCommT->getRank() == 0) std::cout << "In felix_driver_run: grabbing pointers to u and v velocities in CISM..." << std::endl; uVel_ptr = ftg_ptr ->getDoubleVar("uvel", "velocity"); vVel_ptr = ftg_ptr ->getDoubleVar("vvel", "velocity"); // --------------------------------------------- // Set restart solution to the one passed from CISM // IK, 3/14/14: moved this from felix_driver_init to felix_driver_run. // --------------------------------------------- if (debug_output_verbosity != 0 & mpiCommT->getRank() == 0) std::cout << "In felix_driver_run: setting initial condition from CISM..." << std::endl; //Check what kind of ordering you have in the solution & create solutionField object. interleavedOrdering = meshStruct->getInterleavedOrdering(); Albany::AbstractSTKFieldContainer::VectorFieldType* solutionField; if(interleavedOrdering) solutionField = Teuchos::rcp_dynamic_cast<Albany::OrdinarySTKFieldContainer<true> >(meshStruct->getFieldContainer())->getSolutionField(); else solutionField = Teuchos::rcp_dynamic_cast<Albany::OrdinarySTKFieldContainer<false> >(meshStruct->getFieldContainer())->getSolutionField(); //Create vector used to renumber nodes on each processor from the Albany convention (horizontal levels first) to the CISM convention (vertical layers first) nNodes2D = (global_ewn + 1)*(global_nsn+1); //number global nodes in the domain in 2D nNodesProc2D = (nsn-2*nhalo+1)*(ewn-2*nhalo+1); //number of nodes on each processor in 2D cismToAlbanyNodeNumberMap.resize(upn*nNodesProc2D); for (int j=0; j<nsn-2*nhalo+1;j++) { for (int i=0; i<ewn-2*nhalo+1; i++) { for (int k=0; k<upn; k++) { int index = k+upn*i + j*(ewn-2*nhalo+1)*upn; cismToAlbanyNodeNumberMap[index] = k*nNodes2D + global_node_id_owned_map_Ptr[i+j*(ewn-2*nhalo+1)]; //if (mpiComm->MyPID() == 0) // std::cout << "index: " << index << ", cismToAlbanyNodeNumberMap: " << cismToAlbanyNodeNumberMap[index] << std::endl; } } } //The way it worked out, uVel_ptr and vVel_ptr have more nodes than the nodes in the mesh passed to Albany/CISM for the solve. In particular, //there is 1 row of halo elements in uVel_ptr and vVel_ptr. To account for this, we copy uVel_ptr and vVel_ptr into std::vectors, which do not have the halo elements. std::vector<double> uvel_vec(upn*nNodesProc2D); std::vector<double> vvel_vec(upn*nNodesProc2D); int counter1 = 0; int counter2 = 0; int local_nodeID; for (int j=0; j<nsn-1; j++) { for (int i=0; i<ewn-1; i++) { for (int k=0; k<upn; k++) { if (j >= nhalo-1 & j < nsn-nhalo) { if (i >= nhalo-1 & i < ewn-nhalo) { #ifdef CISM_USE_EPETRA local_nodeID = node_map->LID(cismToAlbanyNodeNumberMap[counter1]); #else local_nodeID = node_map->getLocalElement(cismToAlbanyNodeNumberMap[counter1]); #endif uvel_vec[counter1] = uVel_ptr[counter2]; vvel_vec[counter1] = vVel_ptr[counter2]; counter1++; } } counter2++; } } } //Loop over all the elements to find which nodes are active. For the active nodes, copy uvel and vvel from CISM into Albany solution array to //use as initial condition. //NOTE: there is some inefficiency here by looping over all the elements. TO DO? pass only active nodes from Albany-CISM to improve this? double velScale = seconds_per_year*vel_scaling_param; for (int i=0; i<nElementsActive; i++) { for (int j=0; j<8; j++) { int node_GID = global_element_conn_active_Ptr[i + nElementsActive*j]; //node_GID is 1-based #ifdef CISM_USE_EPETRA int node_LID = node_map->LID(node_GID); //node_LID is 0-based #else int node_LID = node_map->getLocalElement(node_GID); //node_LID is 0-based #endif stk::mesh::Entity node = meshStruct->bulkData->get_entity(stk::topology::NODE_RANK, node_GID); double* sol = stk::mesh::field_data(*solutionField, node); //IK, 3/18/14: added division by velScale to convert uvel and vvel from dimensionless to having units of m/year (the Albany units) sol[0] = uvel_vec[node_LID]/velScale; sol[1] = vvel_vec[node_LID]/velScale; } } // --------------------------------------------------------------------------------------------------- // Solve // --------------------------------------------------------------------------------------------------- if (debug_output_verbosity != 0 & mpiCommT->getRank() == 0) std::cout << "In felix_driver_run: starting the solve... " << std::endl; //Need to set HasRestart solution such that uvel_Ptr and vvel_Ptr (u and v from Glimmer/CISM) are always set as initial condition? meshStruct->setHasRestartSolution(!first_time_step); //Turn off homotopy if we're not in the first time-step. //NOTE - IMPORTANT: Glen's Law Homotopy parameter should be set to 1.0 in the parameter list for this logic to work!!! if (!first_time_step) { meshStruct->setRestartDataTime(parameterList->sublist("Problem").get("Homotopy Restart Step", 1.)); double homotopy = parameterList->sublist("Problem").sublist("FELIX Viscosity").get("Glen's Law Homotopy Parameter", 1.0); if(meshStruct->restartDataTime()== homotopy) { parameterList->sublist("Problem").set("Solution Method", "Steady"); parameterList->sublist("Piro").set("Solver Type", "NOX"); } } albanyApp->createDiscretization(); //IK, 10/30/14: Check that # of elements from previous time step hasn't changed. //If it has not, use previous solution as initial guess for current time step. //Otherwise do not set initial solution. It's possible this can be improved so some part of the previous solution is used //defined on the current mesh (if it receded, which likely it will in dynamic ice sheet simulations...). if (nElementsActivePrevious != nElementsActive) previousSolution = Teuchos::null; albanyApp->finalSetUp(parameterList, previousSolution); //if (!first_time_step) // std::cout << "previousSolution: " << *previousSolution << std::endl; #ifdef CISM_USE_EPETRA solver = slvrfctry->createThyraSolverAndGetAlbanyApp(albanyApp, mpiComm, mpiComm, Teuchos::null, false); #else solver = slvrfctry->createAndGetAlbanyAppT(albanyApp, mpiCommT, mpiCommT, Teuchos::null, false); #endif Teuchos::ParameterList solveParams; solveParams.set("Compute Sensitivities", true); Teuchos::Array<Teuchos::RCP<const Thyra::VectorBase<double> > > thyraResponses; Teuchos::Array<Teuchos::Array<Teuchos::RCP<const Thyra::MultiVectorBase<double> > > > thyraSensitivities; Piro::PerformSolveBase(*solver, solveParams, thyraResponses, thyraSensitivities); #ifdef CISM_USE_EPETRA const Epetra_Map& ownedMap(*albanyApp->getDiscretization()->getMap()); //owned map const Epetra_Map& overlapMap(*albanyApp->getDiscretization()->getOverlapMap()); //overlap map Epetra_Import import(overlapMap, ownedMap); //importer from ownedMap to overlapMap Epetra_Vector solutionOverlap(overlapMap); //overlapped solution solutionOverlap.Import(*albanyApp->getDiscretization()->getSolutionField(), import, Insert); #else Teuchos::RCP<const Tpetra_Map> ownedMap = albanyApp->getDiscretization()->getMapT(); //owned map Teuchos::RCP<const Tpetra_Map> overlapMap = albanyApp->getDiscretization()->getOverlapMapT(); //overlap map Teuchos::RCP<Tpetra_Import> import = Teuchos::rcp(new Tpetra_Import(ownedMap, overlapMap)); Teuchos::RCP<Tpetra_Vector> solutionOverlap = Teuchos::rcp(new Tpetra_Vector(overlapMap)); solutionOverlap->doImport(*albanyApp->getDiscretization()->getSolutionFieldT(), *import, Tpetra::INSERT); Teuchos::ArrayRCP<const ST> solutionOverlap_constView = solutionOverlap->get1dView(); #endif #ifdef WRITE_TO_MATRIX_MARKET #ifdef CISM_USE_EPETRA //For debug: write solution and maps to matrix market file EpetraExt::BlockMapToMatrixMarketFile("node_map.mm", *node_map); EpetraExt::BlockMapToMatrixMarketFile("map.mm", ownedMap); EpetraExt::BlockMapToMatrixMarketFile("overlap_map.mm", overlapMap); EpetraExt::MultiVectorToMatrixMarketFile("solution.mm", *albanyApp->getDiscretization()->getSolutionField()); #else Tpetra_MatrixMarket_Writer::writeMapFile("node_map.mm", *node_map); Tpetra_MatrixMarket_Writer::writeMapFile("map.mm", *ownedMap); Tpetra_MatrixMarket_Writer::writeMapFile("overlap_map.mm", *overlapMap); Tpetra_MatrixMarket_Writer::writeDenseFile("solution.mm", app->getDiscretization()->getSolutionFieldT()); #endif #endif //set previousSolution (used as initial guess for next time step) to final Albany solution. previousSolution = Teuchos::rcp(new Tpetra_Vector(*albanyApp->getDiscretization()->getSolutionFieldT())); nElementsActivePrevious = nElementsActive; //std::cout << "Final solution: " << *albanyApp->getDiscretization()->getSolutionField() << std::endl; // --------------------------------------------------------------------------------------------------- // Compute sensitivies / responses and perform regression tests // IK, 12/9/13: how come this is turned off in mpas branch? // --------------------------------------------------------------------------------------------------- if (debug_output_verbosity != 0 & mpiCommT->getRank() == 0) std::cout << "Computing responses and sensitivities..." << std::endl; int status=0; // 0 = pass, failures are incremented #ifdef CISM_USE_EPETRA Teuchos::Array<Teuchos::RCP<const Epetra_Vector> > responses; Teuchos::Array<Teuchos::Array<Teuchos::RCP<const Epetra_MultiVector> > > sensitivities; epetraFromThyra(mpiComm, thyraResponses, thyraSensitivities, responses, sensitivities); #else Teuchos::Array<Teuchos::RCP<const Tpetra_Vector> > responses; Teuchos::Array<Teuchos::Array<Teuchos::RCP<const Tpetra_MultiVector> > > sensitivities; tpetraFromThyra(thyraResponses, thyraSensitivities, responses, sensitivities); #endif const int num_p = solver->Np(); // Number of *vectors* of parameters const int num_g = solver->Ng(); // Number of *vectors* of responses if (debug_output_verbosity != 0) { *out << "Finished eval of first model: Params, Responses " << std::setprecision(12) << std::endl; } const Thyra::ModelEvaluatorBase::InArgs<double> nominal = solver->getNominalValues(); if (debug_output_verbosity != 0) { for (int i=0; i<num_p; i++) { #ifdef CISM_USE_EPETRA const Teuchos::RCP<const Epetra_Vector> p_init = epetraVectorFromThyra(mpiComm, nominal.get_p(i)); p_init->Print(*out << "\nParameter vector " << i << ":\n"); #else Albany::printTpetraVector(*out << "\nParameter vector " << i << ":\n", ConverterT::getConstTpetraVector(nominal.get_p(i))); #endif } } for (int i=0; i<num_g-1; i++) { #ifdef CISM_USE_EPETRA const Teuchos::RCP<const Epetra_Vector> g = responses[i]; #else const Teuchos::RCP<const Tpetra_Vector> g = responses[i]; #endif bool is_scalar = true; if (albanyApp != Teuchos::null) is_scalar = albanyApp->getResponse(i)->isScalarResponse(); if (is_scalar) { if (debug_output_verbosity != 0) { #ifdef CISM_USE_EPETRA g->Print(*out << "\nResponse vector " << i << ":\n"); #else Albany::printTpetraVector(*out << "\nResponse vector " << i << ":\n", g); #endif } if (num_p == 0 && cur_time_yr == final_time) { // Just calculate regression data -- only if in final time step #ifdef CISM_USE_EPETRA status += slvrfctry->checkSolveTestResults(i, 0, g.get(), NULL); #else status += slvrfctry->checkSolveTestResultsT(i, 0, g.get(), NULL); #endif } else { for (int j=0; j<num_p; j++) { #ifdef CISM_USE_EPETRA const Teuchos::RCP<const Epetra_MultiVector> dgdp = sensitivities[i][j]; #else const Teuchos::RCP<const Tpetra_MultiVector> dgdp = sensitivities[i][j]; #endif if (debug_output_verbosity != 0) { if (Teuchos::nonnull(dgdp)) { #ifdef CISM_USE_EPETRA dgdp->Print(*out << "\nSensitivities (" << i << "," << j << "):!\n"); #else Albany::printTpetraVector(*out << "\nSensitivities (" << i << "," << j << "):!\n", dgdp); #endif } } if (cur_time_yr == final_time) { #ifdef CISM_USE_EPETRA status += slvrfctry->checkSolveTestResults(i, j, g.get(), dgdp.get()); #else status += slvrfctry->checkSolveTestResultsT(i, j, g.get(), dgdp.get()); #endif } } } } } if (debug_output_verbosity != 0 && cur_time_yr == final_time) //only print regression test result if you're in the final time step *out << "\nNumber of Failed Comparisons: " << status << std::endl; //IK, 10/30/14: added the following line so that when you run ctest from CISM the test fails if there are some failed comparisons. if (status > 0) TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "All regression comparisons did not pass!" << std::endl); // --------------------------------------------------------------------------------------------------- // Copy solution back to glimmer uvel and vvel arrays to be passed back // --------------------------------------------------------------------------------------------------- //std::cout << "overlapMap # global elements: " << overlapMap.NumGlobalElements() << std::endl; //std::cout << "overlapMap # my elements: " << overlapMap.NumMyElements() << std::endl; //std::cout << "overlapMap: " << overlapMap << std::endl; //std::cout << "map # global elements: " << ownedMap.NumGlobalElements() << std::endl; //std::cout << "map # my elements: " << ownedMap.NumMyElements() << std::endl; //std::cout << "node_map # global elements: " << node_map->NumGlobalElements() << std::endl; //std::cout << "node_map # my elements: " << node_map->NumMyElements() << std::endl; //std::cout << "node_map: " << *node_map << std::endl; if (debug_output_verbosity != 0 & mpiCommT->getRank() == 0) std::cout << "In felix_driver_run: copying Albany solution to uvel and vvel to send back to CISM... " << std::endl; #ifdef CISM_USE_EPETRA //Epetra_Vectors to hold uvel and vvel to be passed to Glimmer/CISM Epetra_Vector uvel(*node_map, true); Epetra_Vector vvel(*node_map, true); #else //Tpetra_Vectors to hold uvel and vvel to be passed to Glimmer/CISM Teuchos::RCP<Tpetra_Vector> uvel = Teuchos::rcp(new Tpetra_Vector(node_map, true)); Teuchos::RCP<Tpetra_Vector> vvel = Teuchos::rcp(new Tpetra_Vector(node_map, true)); #endif #ifdef CISM_USE_EPETRA if (interleavedOrdering == true) { for (int i=0; i<overlapMap.NumMyElements(); i++) { int global_dof = overlapMap.GID(i); double sol_value = solutionOverlap[i]; int modulo = (global_dof % 2); //check if dof is for u or for v int vel_global_dof, vel_local_dof; if (modulo == 0) { //u dof vel_global_dof = global_dof/2+1; //add 1 because node_map is 1-based vel_local_dof = node_map->LID(vel_global_dof); //look up local id corresponding to global id in node_map //std::cout << "uvel: global_dof = " << global_dof << ", uvel_global_dof = " << vel_global_dof << ", uvel_local_dof = " << vel_local_dof << std::endl; uvel.ReplaceMyValues(1, &sol_value, &vel_local_dof); } else { // v dof vel_global_dof = (global_dof-1)/2+1; //add 1 because node_map is 1-based vel_local_dof = node_map->LID(vel_global_dof); //look up local id corresponding to global id in node_map vvel.ReplaceMyValues(1, &sol_value, & vel_local_dof); } } } else { //note: the case with non-interleaved ordering has not been tested... int numDofs = overlapMap.NumGlobalElements(); for (int i=0; i<overlapMap.NumMyElements(); i++) { int global_dof = overlapMap.GID(i); double sol_value = solutionOverlap[i]; int vel_global_dof, vel_local_dof; if (global_dof < numDofs/2) { //u dof vel_global_dof = global_dof+1; //add 1 because node_map is 1-based vel_local_dof = node_map->LID(vel_global_dof); //look up local id corresponding to global id in node_map uvel.ReplaceMyValues(1, &sol_value, &vel_local_dof); } else { //v dofs vel_global_dof = global_dof-numDofs/2+1; //add 1 because node_map is 1-based vel_local_dof = node_map->LID(vel_global_dof); //look up local id corresponding to global id in node_map vvel.ReplaceMyValues(1, &sol_value, & vel_local_dof); } } } #else if (interleavedOrdering == true) { for (int i=0; i<overlapMap->getNodeNumElements(); i++) { int global_dof = overlapMap->getGlobalElement(i); double sol_value = solutionOverlap_constView[i]; int modulo = (global_dof % 2); //check if dof is for u or for v int vel_global_dof, vel_local_dof; if (modulo == 0) { //u dof vel_global_dof = global_dof/2+1; //add 1 because node_map is 1-based vel_local_dof = node_map->getLocalElement(vel_global_dof); //look up local id corresponding to global id in node_map //std::cout << "uvel: global_dof = " << global_dof << ", uvel_global_dof = " << vel_global_dof << ", uvel_local_dof = " << vel_local_dof << std::endl; uvel->replaceLocalValue(vel_local_dof, sol_value); } else { // v dof vel_global_dof = (global_dof-1)/2+1; //add 1 because node_map is 1-based vel_local_dof = node_map->getLocalElement(vel_global_dof); //look up local id corresponding to global id in node_map vvel->replaceLocalValue(vel_local_dof, sol_value); } } } else { //note: the case with non-interleaved ordering has not been tested... int numDofs = overlapMap->getGlobalNumElements(); for (int i=0; i<overlapMap->getNodeNumElements(); i++) { int global_dof = overlapMap->getGlobalElement(i); double sol_value = solutionOverlap_constView[i]; int vel_global_dof, vel_local_dof; if (global_dof < numDofs/2) { //u dof vel_global_dof = global_dof+1; //add 1 because node_map is 1-based vel_local_dof = node_map->getLocalElement(vel_global_dof); //look up local id corresponding to global id in node_map uvel->replaceLocalValue(vel_local_dof, sol_value); } else { //v dofs vel_global_dof = global_dof-numDofs/2+1; //add 1 because node_map is 1-based vel_local_dof = node_map->getLocalElement(vel_global_dof); //look up local id corresponding to global id in node_map vvel->replaceLocalValue(vel_local_dof, sol_value); } } } #endif #ifdef WRITE_TO_MATRIX_MARKET //For debug: write solution to matrix market file #ifdef CISM_USE_EPETRA EpetraExt::MultiVectorToMatrixMarketFile("uvel.mm", uvel); EpetraExt::MultiVectorToMatrixMarketFile("vvel.mm", vvel); #else Tpetra_MatrixMarket_Writer::writeDenseFile("uvel.mm", uvel); Tpetra_MatrixMarket_Writer::writeDenseFile("vvel.mm", vvel); #endif #endif //Copy uvel and vvel into uVel_ptr and vVel_ptr respectively (the arrays passed back to CISM) according to the numbering consistent w/ CISM. counter1 = 0; counter2 = 0; #ifdef CISM_USE_EPETRA #else Teuchos::ArrayRCP<const ST> uvel_constView = uvel->get1dView(); Teuchos::ArrayRCP<const ST> vvel_constView = vvel->get1dView(); #endif local_nodeID = 0; for (int j=0; j<nsn-1; j++) { for (int i=0; i<ewn-1; i++) { for (int k=0; k<upn; k++) { if (j >= nhalo-1 & j < nsn-nhalo) { if (i >= nhalo-1 & i < ewn-nhalo) { #ifdef CISM_USE_EPETRA local_nodeID = node_map->LID(cismToAlbanyNodeNumberMap[counter1]); //if (mpiComm->MyPID() == 0) //std::cout << "counter1:" << counter1 << ", cismToAlbanyNodeNumberMap[counter1]: " << cismToAlbanyNodeNumberMap[counter1] << ", local_nodeID: " //<< local_nodeID << ", uvel: " << uvel[local_nodeID] << std::endl; //uvel[local_nodeID] << std::endl; uVel_ptr[counter2] = uvel[local_nodeID]; vVel_ptr[counter2] = vvel[local_nodeID]; #else local_nodeID = node_map->getLocalElement(cismToAlbanyNodeNumberMap[counter1]); uVel_ptr[counter2] = uvel_constView[local_nodeID]; vVel_ptr[counter2] = vvel_constView[local_nodeID]; #endif counter1++; } } else { uVel_ptr[counter2] = 0.0; vVel_ptr[counter2] = 0.0; } counter2++; } } } first_time_step = false; }
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()); } }
// 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 Piro::RythmosSolver<Scalar>::evalModelImpl( #endif 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); } RCP<const Thyra::VectorBase<Scalar> > p_in2; //JF add for multipoint if (num_p > 1) { p_in2 = inArgs.get_p(l+1); } // 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); Thyra::ModelEvaluatorBase::InArgs<Scalar> state_ic = model->getNominalValues(); // Set initial time in ME if needed if(t_initial > 0.0 && state_ic.supports(Thyra::ModelEvaluatorBase::IN_ARG_t)) state_ic.set_t(t_initial); if (Teuchos::nonnull(initialConditionModel)) { // The initial condition depends on the parameter // It is found by querying the auxiliary model evaluator as the last response const RCP<Thyra::VectorBase<Scalar> > initialState = Thyra::createMember(model->get_x_space()); { Thyra::ModelEvaluatorBase::InArgs<Scalar> initCondInArgs = initialConditionModel->createInArgs(); if (num_p > 0) { initCondInArgs.set_p(l, inArgs.get_p(l)); } Thyra::ModelEvaluatorBase::OutArgs<Scalar> initCondOutArgs = initialConditionModel->createOutArgs(); initCondOutArgs.set_g(initCondOutArgs.Ng() - 1, initialState); initialConditionModel->evalModel(initCondInArgs, initCondOutArgs); } state_ic.set_x(initialState); } // Set paramters p_in as part of initial conditions if (num_p > 0) { if (Teuchos::nonnull(p_in)) { state_ic.set_p(l, p_in); } } if (num_p > 1) { //JF added for multipoint if (Teuchos::nonnull(p_in2)) { state_ic.set_p(l+1, p_in2); } } *out << "\nstate_ic:\n" << Teuchos::describe(state_ic, solnVerbLevel); //JF may need a version of the following for multipoint, i.e. num_p>1, l+1, if we want sensitivities RCP<Thyra::MultiVectorBase<Scalar> > dgxdp_out; Thyra::ModelEvaluatorBase::Derivative<Scalar> dgdp_deriv_out; if (num_p > 0) { const Thyra::ModelEvaluatorBase::DerivativeSupport dgxdp_support = outArgs.supports(Thyra::ModelEvaluatorBase::OUT_ARG_DgDp, num_g, l); if (dgxdp_support.supports(Thyra::ModelEvaluatorBase::DERIV_MV_JACOBIAN_FORM)) { const Thyra::ModelEvaluatorBase::Derivative<Scalar> dgxdp_deriv = outArgs.get_DgDp(num_g, l); dgxdp_out = dgxdp_deriv.getMultiVector(); } if (num_g > 0) { const Thyra::ModelEvaluatorBase::DerivativeSupport dgdp_support = outArgs.supports(Thyra::ModelEvaluatorBase::OUT_ARG_DgDp, j, l); if (!dgdp_support.none()) { dgdp_deriv_out = outArgs.get_DgDp(j, l); } } } const bool requestedSensitivities = Teuchos::nonnull(dgxdp_out) || !dgdp_deriv_out.isEmpty(); RCP<const Thyra::VectorBase<Scalar> > finalSolution; if (!requestedSensitivities) { // *out << "\nE) Solve the forward problem ...\n"; // fwdStateStepper->setInitialCondition(state_ic); fwdStateIntegrator->setStepper(fwdStateStepper, t_final, true); *out << "T final : " << t_final << " \n"; Teuchos::Array<RCP<const Thyra::VectorBase<Scalar> > > x_final_array; fwdStateIntegrator->getFwdPoints( Teuchos::tuple<Scalar>(t_final), &x_final_array, NULL, NULL); finalSolution = x_final_array[0]; if (Teuchos::VERB_MEDIUM <= solnVerbLevel) { std::cout << "Final Solution\n" << *finalSolution << std::endl; } } else { // Computing sensitivities // *out << "\nE) Solve the forward problem with Sensitivities...\n"; // RCP<Rythmos::ForwardSensitivityStepper<Scalar> > stateAndSensStepper = Rythmos::forwardSensitivityStepper<Scalar>(); stateAndSensStepper->initializeSyncedSteppers( model, l, model->getNominalValues(), fwdStateStepper, fwdTimeStepSolver); // // Set the initial condition for the state and forward sensitivities // const RCP<Thyra::VectorBase<Scalar> > s_bar_init = Thyra::createMember(stateAndSensStepper->getFwdSensModel()->get_x_space()); const RCP<Thyra::VectorBase<Scalar> > s_bar_dot_init = Thyra::createMember(stateAndSensStepper->getFwdSensModel()->get_x_space()); if (Teuchos::is_null(initialConditionModel)) { // The initial condition is assumed to be independent from the parameters // Therefore, the initial condition for the sensitivity is zero Thyra::assign(s_bar_init.ptr(), Teuchos::ScalarTraits<Scalar>::zero()); } else { // Use initialConditionModel to compute initial condition for sensitivity Thyra::ModelEvaluatorBase::InArgs<Scalar> initCondInArgs = initialConditionModel->createInArgs(); initCondInArgs.set_p(l, inArgs.get_p(l)); Thyra::ModelEvaluatorBase::OutArgs<Scalar> initCondOutArgs = initialConditionModel->createOutArgs(); typedef Thyra::DefaultMultiVectorProductVector<Scalar> DMVPV; const RCP<DMVPV> s_bar_init_downcasted = Teuchos::rcp_dynamic_cast<DMVPV>(s_bar_init); const Thyra::ModelEvaluatorBase::Derivative<Scalar> initCond_deriv( s_bar_init_downcasted->getNonconstMultiVector(), Thyra::ModelEvaluatorBase::DERIV_MV_JACOBIAN_FORM); initCondOutArgs.set_DgDp(initCondOutArgs.Ng() - 1, l, initCond_deriv); initialConditionModel->evalModel(initCondInArgs, initCondOutArgs); } Thyra::assign(s_bar_dot_init.ptr(), Teuchos::ScalarTraits<Scalar>::zero()); RCP<const Rythmos::StateAndForwardSensitivityModelEvaluator<Scalar> > stateAndSensModel = stateAndSensStepper->getStateAndFwdSensModel(); Thyra::ModelEvaluatorBase::InArgs<Scalar> state_and_sens_ic = stateAndSensStepper->getModel()->createInArgs(); // Copy time, parameters etc. state_and_sens_ic.setArgs(state_ic); // Set initial condition for x_bar = [ x; s_bar ] state_and_sens_ic.set_x(stateAndSensModel->create_x_bar_vec(state_ic.get_x(), s_bar_init)); // Set initial condition for x_bar_dot = [ x_dot; s_bar_dot ] state_and_sens_ic.set_x_dot(stateAndSensModel->create_x_bar_vec(state_ic.get_x_dot(), s_bar_dot_init)); stateAndSensStepper->setInitialCondition(state_and_sens_ic); // // Use a StepperAsModelEvaluator to integrate the state+sens // const RCP<Rythmos::StepperAsModelEvaluator<Scalar> > stateAndSensIntegratorAsModel = Rythmos::stepperAsModelEvaluator( Teuchos::rcp_implicit_cast<Rythmos::StepperBase<Scalar> >(stateAndSensStepper), Teuchos::rcp_implicit_cast<Rythmos::IntegratorBase<Scalar> >(fwdStateIntegrator), state_and_sens_ic); // StepperAsModelEvaluator outputs the solution as its last response const int stateAndSensModelStateResponseIndex = stateAndSensIntegratorAsModel->Ng() - 1; *out << "\nUse the StepperAsModelEvaluator to integrate state + sens x_bar(p,t_final) ... \n"; Teuchos::OSTab tab(out); // Solution sensitivity in column-oriented (Jacobian) MultiVector form RCP<const Thyra::MultiVectorBase<Scalar> > dxdp; const RCP<Thyra::VectorBase<Scalar> > x_bar_final = Thyra::createMember(stateAndSensIntegratorAsModel->get_g_space(stateAndSensModelStateResponseIndex)); // Extract pieces of x_bar_final to prepare output { const RCP<const Thyra::ProductVectorBase<Scalar> > x_bar_final_downcasted = Thyra::productVectorBase<Scalar>(x_bar_final); // Solution const int solutionBlockIndex = 0; finalSolution = x_bar_final_downcasted->getVectorBlock(solutionBlockIndex); // Sensitivity const int sensitivityBlockIndex = 1; const RCP<const Thyra::VectorBase<Scalar> > s_bar_final = x_bar_final_downcasted->getVectorBlock(sensitivityBlockIndex); { typedef Thyra::DefaultMultiVectorProductVector<Scalar> DMVPV; const RCP<const DMVPV> s_bar_final_downcasted = Teuchos::rcp_dynamic_cast<const DMVPV>(s_bar_final); dxdp = s_bar_final_downcasted->getMultiVector(); } } Thyra::eval_g( *stateAndSensIntegratorAsModel, l, *state_ic.get_p(l), t_final, stateAndSensModelStateResponseIndex, x_bar_final.get() ); *out << "\nx_bar_final = x_bar(p,t_final) evaluated using " << "stateAndSensIntegratorAsModel:\n" << Teuchos::describe(*x_bar_final,solnVerbLevel); if (Teuchos::nonnull(dgxdp_out)) { Thyra::assign(dgxdp_out.ptr(), *dxdp); } if (!dgdp_deriv_out.isEmpty()) { RCP<Thyra::DefaultAddedLinearOp<Scalar> > dgdp_op_out; { const RCP<Thyra::LinearOpBase<Scalar> > dgdp_op = dgdp_deriv_out.getLinearOp(); if (Teuchos::nonnull(dgdp_op)) { dgdp_op_out = Teuchos::rcp_dynamic_cast<Thyra::DefaultAddedLinearOp<Scalar> >(dgdp_op); dgdp_op_out.assert_not_null(); } } Thyra::ModelEvaluatorBase::InArgs<Scalar> modelInArgs = model->createInArgs(); { modelInArgs.set_x(finalSolution); if (num_p > 0) { modelInArgs.set_p(l, p_in); } } // require dgdx, dgdp from model Thyra::ModelEvaluatorBase::OutArgs<Scalar> modelOutArgs = model->createOutArgs(); { const Thyra::ModelEvaluatorBase::Derivative<Scalar> dgdx_deriv(model->create_DgDx_op(j)); modelOutArgs.set_DgDx(j, dgdx_deriv); Thyra::ModelEvaluatorBase::Derivative<Scalar> dgdp_deriv; if (Teuchos::nonnull(dgdp_op_out)) { dgdp_deriv = model->create_DgDp_op(j, l); } else { dgdp_deriv = dgdp_deriv_out; } modelOutArgs.set_DgDp(j, l, dgdp_deriv); } model->evalModel(modelInArgs, modelOutArgs); const RCP<const Thyra::LinearOpBase<Scalar> > dgdx = modelOutArgs.get_DgDx(j).getLinearOp(); // dgdp_out = dgdp + <dgdx, dxdp> if (Teuchos::nonnull(dgdp_op_out)) { Teuchos::Array<RCP<const Thyra::LinearOpBase<Scalar> > > op_args(2); { op_args[0] = modelOutArgs.get_DgDp(j, l).getLinearOp(); op_args[1] = Thyra::multiply<Scalar>(dgdx, dxdp); } dgdp_op_out->initialize(op_args); } else { const RCP<Thyra::MultiVectorBase<Scalar> > dgdp_mv_out = dgdp_deriv_out.getMultiVector(); Thyra::apply( *dgdx, Thyra::NOTRANS, *dxdp, dgdp_mv_out.ptr(), Teuchos::ScalarTraits<Scalar>::one(), Teuchos::ScalarTraits<Scalar>::one()); } } } *out << "\nF) Check the solution to the forward problem ...\n"; // As post-processing step, calculate responses at final solution { Thyra::ModelEvaluatorBase::InArgs<Scalar> modelInArgs = model->createInArgs(); { modelInArgs.set_x(finalSolution); if (num_p > 0) { modelInArgs.set_p(l, p_in); } if (num_p > 1) { //JF added for multipoint modelInArgs.set_p(l+1, p_in2); } //Set time to be final time at which the solve occurs (< t_final in the case we don't make it to t_final). modelInArgs.set_t(fwdStateStepper->getTimeRange().lower()); } Thyra::ModelEvaluatorBase::OutArgs<Scalar> modelOutArgs = model->createOutArgs(); if (Teuchos::nonnull(g_out)) { Thyra::put_scalar(Teuchos::ScalarTraits<Scalar>::zero(), g_out.ptr()); modelOutArgs.set_g(j, g_out); } model->evalModel(modelInArgs, modelOutArgs); } // Return the final solution as an additional g-vector, if requested if (Teuchos::nonnull(gx_out)) { Thyra::copy(*finalSolution, gx_out.ptr()); } }
void Piro::VelocityVerletSolver<Scalar, LocalOrdinal, GlobalOrdinal, Node>::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); // create a new vector and fill it with the contents of model->get_x() // Build a multivector holding x (0th vector), v (1st vector), and a (2nd vector) // Teuchos::RCP<Thyra::MultiVectorBase<Scalar> > soln = createMembers(model->get_x_space(), 3); // create a new vector and fill it with the contents of model->get_x() /* Teuchos::RCP<Thyra::VectorBase<Scalar> > x = soln->col(0); assign(x.ptr(), *model->getNominalValues().get_x()); Teuchos::RCP<Thyra::VectorBase<Scalar> > v = soln->col(1); assign(v.ptr(), *model->getNominalValues().get_x_dot()); Teuchos::RCP<Thyra::VectorBase<Scalar> > a = soln->col(2); assign(a.ptr(), *model->get_x_dotdot()); */ Teuchos::RCP<Thyra::VectorBase<Scalar> > x = model->getNominalValues().get_x()->clone_v(); Teuchos::RCP<Thyra::VectorBase<Scalar> > v = model->getNominalValues().get_x_dot()->clone_v(); // Note that Thyra doesn't have x_dotdot - go get it from the transient decorator around the Albany model // Teuchos::RCP<Thyra::VectorBase<Scalar> > a = model->get_x_dotdot()->clone_v(); Teuchos::RCP<Thyra::DefaultModelEvaluatorWithSolveFactory<Scalar> > DMEWSF(Teuchos::rcp_dynamic_cast<Thyra::DefaultModelEvaluatorWithSolveFactory<Scalar> >(model)); Teuchos::RCP<const Piro::TransientDecorator<Scalar, LocalOrdinal, GlobalOrdinal, Node> > dec = Teuchos::rcp_dynamic_cast<const Piro::TransientDecorator<Scalar, LocalOrdinal, GlobalOrdinal, Node> > (DMEWSF->getUnderlyingModel()); TEUCHOS_TEST_FOR_EXCEPTION(Teuchos::is_null(dec), std::logic_error, "Underlying model in VelovityVerletSolver does not cast to a Piro::TransientDecorator<Scalar, LocalOrdinal, GlobalOrdinal, Node>" << std::endl); Teuchos::RCP<Thyra::VectorBase<Scalar> > a = dec->get_x_dotdot()->clone_v(); 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(*soln, 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); Vp_StV(x.ptr(), delta_t, *v); Vp_StV(x.ptr(), ddt, *a); t += delta_t; model_inargs.set_t(t); // v->Update(0.5*delta_t, *a, 1.0); Vp_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); Vp_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::LOCAAdaptiveSolver<Scalar>::evalModelImpl( const Thyra::ModelEvaluatorBase::InArgs<Scalar>& inArgs, const Thyra::ModelEvaluatorBase::OutArgs<Scalar>& outArgs) const { const int l = 0; // TODO: Allow user to select parameter index const Teuchos::RCP<const Thyra::VectorBase<Scalar> > p_inargs = inArgs.get_p(l); // Forward parameter values to the LOCAAdaptive stepper { const Teuchos::RCP<const Thyra::VectorBase<Scalar> > p_inargs_or_nominal = Teuchos::nonnull(p_inargs) ? p_inargs : this->getNominalValues().get_p(l); const Thyra::ConstDetachedVectorView<Scalar> p_init_values(p_inargs_or_nominal); const Teuchos_Ordinal p_entry_count = p_init_values.subDim(); TEUCHOS_ASSERT(p_entry_count == Teuchos::as<Teuchos_Ordinal>(paramVector_.length())); for (Teuchos_Ordinal k = 0; k < p_entry_count; ++k) { paramVector_[k] = p_init_values[k]; } // solMgr_->getSolutionGroup()->setParams(paramVector_); Teuchos::rcp_dynamic_cast< ::Thyra::LOCAAdaptiveState >(solMgr_->getState()) ->getSolutionGroup()->setParams(paramVector_); } LOCA::Abstract::Iterator::IteratorStatus status; status = stepper_->run(); if (status == LOCA::Abstract::Iterator::Finished) { utils_.out() << "Continuation Stepper Finished.\n"; } else if (status == LOCA::Abstract::Iterator::NotFinished) { utils_.out() << "Continuation Stepper did not reach final value.\n"; } else { utils_.out() << "Nonlinear solver failed to converge.\n"; outArgs.setFailed(); } // The time spent globalData_->locaUtils->out() << std::endl << "#### Statistics ########" << std::endl; // Check number of steps int numSteps = stepper_->getStepNumber(); globalData_->locaUtils->out() << std::endl << " Number of continuation Steps = " << numSteps << std::endl; // Check number of failed steps int numFailedSteps = stepper_->getNumFailedSteps(); globalData_->locaUtils->out() << std::endl << " Number of failed continuation Steps = " << numFailedSteps << std::endl; globalData_->locaUtils->out() << std::endl; // Note: the last g is used to store the final solution. It can be null - if it is just // skip the store. If adaptation has occurred, g is not the correct size. const Teuchos::RCP<Thyra::VectorBase<Scalar> > x_outargs = outArgs.get_g(this->num_g()); Teuchos::RCP<Thyra::VectorBase<Scalar> > x_final; int x_args_dim = 0; int f_sol_dim = 0; // Pardon the nasty cast to resize the last g in outArgs - need to fit the solution Thyra::ModelEvaluatorBase::OutArgs<Scalar>* mutable_outArgsPtr = const_cast<Thyra::ModelEvaluatorBase::OutArgs<Scalar>* >(&outArgs); if(Teuchos::nonnull(x_outargs)){ // g has been allocated, calculate the sizes of g and the solution x_args_dim = x_outargs->space()->dim(); // f_sol_dim = solMgr_->getSolutionGroup()->getX().length(); f_sol_dim = Teuchos::rcp_dynamic_cast< ::Thyra::LOCAAdaptiveState >(solMgr_->getState()) ->getSolutionGroup()->getX().length(); } if(Teuchos::is_null(x_outargs) || (x_args_dim != f_sol_dim)){ // g is not the right size x_final = Thyra::createMember(this->get_g_space(this->num_g())); mutable_outArgsPtr->set_g(this->num_g(), x_final); } else { // g is OK, use it x_final = x_outargs; } { // Deep copy final solution from LOCA group NOX::Thyra::Vector finalSolution(x_final); // finalSolution = solMgr_->getSolutionGroup()->getX(); finalSolution = Teuchos::rcp_dynamic_cast< ::Thyra::LOCAAdaptiveState >(solMgr_->getState()) ->getSolutionGroup()->getX(); } // If the arrays need resizing if(x_args_dim != f_sol_dim){ const int parameterCount = this->Np(); for (int pc = 0; pc < parameterCount; ++pc) { const Thyra::ModelEvaluatorBase::DerivativeSupport dgdp_support = outArgs.supports(Thyra::ModelEvaluatorBase::OUT_ARG_DgDp, this->num_g(), pc); const Thyra::ModelEvaluatorBase::EDerivativeMultiVectorOrientation dgdp_orient = Thyra::ModelEvaluatorBase::DERIV_MV_JACOBIAN_FORM; if (dgdp_support.supports(dgdp_orient)) { const Thyra::ModelEvaluatorBase::DerivativeMultiVector<Scalar> dgdp = Thyra::create_DgDp_mv(*this, this->num_g(), pc, dgdp_orient); mutable_outArgsPtr->set_DgDp(this->num_g(), pc, dgdp); } } } // Compute responses for the final solution { Thyra::ModelEvaluatorBase::InArgs<Scalar> modelInArgs = this->getModel().createInArgs(); { modelInArgs.set_x(x_final); modelInArgs.set_p(l, p_inargs); } this->evalConvergedModel(modelInArgs, outArgs); // Save the final solution TODO: this needs to be redone Teuchos::RCP<Thyra::ModelEvaluatorBase::InArgs<Scalar> > fp = Teuchos::rcp_const_cast<Thyra::ModelEvaluatorBase::InArgs<Scalar> >(finalPoint_); Thyra::ModelEvaluatorBase::InArgsSetup<Scalar> ia; ia.setSupports(Thyra::ModelEvaluatorBase::IN_ARG_x, true); *fp = ia; fp->set_x(x_final); } }
int main(int argc, char *argv[]) { int status=0; // 0 = pass, failures are incremented bool success = true; #ifdef ALBANY_DEBUG Teuchos::GlobalMPISession mpiSession(&argc, &argv); #else // bypass printing process startup info Teuchos::GlobalMPISession mpiSession(&argc, &argv, NULL); #endif Kokkos::initialize(argc, argv); #ifdef ALBANY_FLUSH_DENORMALS _MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON); _MM_SET_DENORMALS_ZERO_MODE(_MM_DENORMALS_ZERO_ON); #endif #ifdef ALBANY_CHECK_FPE // Catch FPEs. Follow Main_SolveT.cpp's approach to checking for floating // point exceptions. //_mm_setcsr(_MM_MASK_MASK &~ (_MM_MASK_OVERFLOW | _MM_MASK_INVALID | _MM_MASK_DIV_ZERO) ); _MM_SET_EXCEPTION_MASK(_MM_GET_EXCEPTION_MASK() & ~_MM_MASK_INVALID); #endif using Teuchos::RCP; using Teuchos::rcp; RCP<Teuchos::FancyOStream> out(Teuchos::VerboseObjectBase::getDefaultOStream()); // Command-line argument for input file Albany::CmdLineArgs cmd; cmd.parse_cmdline(argc, argv, *out); try { RCP<Teuchos::Time> totalTime = Teuchos::TimeMonitor::getNewTimer("Albany: ***Total Time***"); RCP<Teuchos::Time> setupTime = Teuchos::TimeMonitor::getNewTimer("Albany: Setup Time"); Teuchos::TimeMonitor totalTimer(*totalTime); //start timer Teuchos::TimeMonitor setupTimer(*setupTime); //start timer RCP<const Teuchos_Comm> comm = Tpetra::DefaultPlatform::getDefaultPlatform().getComm(); // Connect vtune for performance profiling if (cmd.vtune) { Albany::connect_vtune(comm->getRank()); } Albany::SolverFactory slvrfctry(cmd.xml_filename, comm); RCP<Epetra_Comm> appComm = Albany::createEpetraCommFromTeuchosComm(comm); RCP<Albany::Application> app; const RCP<Thyra::ModelEvaluator<double> > solver = slvrfctry.createThyraSolverAndGetAlbanyApp(app, appComm, appComm); setupTimer.~TimeMonitor(); // PHX::InitializeKokkosDevice(); Teuchos::ParameterList &solveParams = slvrfctry.getAnalysisParameters().sublist("Solve", /*mustAlreadyExist =*/ false); // By default, request the sensitivities if not explicitly disabled solveParams.get("Compute Sensitivities", true); Teuchos::Array<Teuchos::RCP<const Thyra::VectorBase<double> > > thyraResponses; Teuchos::Array<Teuchos::Array<Teuchos::RCP<const Thyra::MultiVectorBase<double> > > > thyraSensitivities; // The PoissonSchrodinger_SchroPo and PoissonSchroMosCap1D tests seg fault as albanyApp is null - // For now, do not resize the response vectors. FIXME sort out this issue. if(Teuchos::nonnull(app)) Piro::PerformSolveBase(*solver, solveParams, thyraResponses, thyraSensitivities, app->getAdaptSolMgr()->getSolObserver()); else Piro::PerformSolveBase(*solver, solveParams, thyraResponses, thyraSensitivities); Teuchos::Array<Teuchos::RCP<const Epetra_Vector> > responses; Teuchos::Array<Teuchos::Array<Teuchos::RCP<const Epetra_MultiVector> > > sensitivities; epetraFromThyra(appComm, thyraResponses, thyraSensitivities, responses, sensitivities); const int num_p = solver->Np(); // Number of *vectors* of parameters const int num_g = solver->Ng(); // Number of *vectors* of responses *out << "Finished eval of first model: Params, Responses " << std::setprecision(12) << std::endl; Teuchos::ParameterList& parameterParams = slvrfctry.getParameters().sublist("Problem").sublist("Parameters"); int num_param_vecs = (parameterParams.isType<int>("Number")) ? int(parameterParams.get("Number", 0) > 0) : parameterParams.get("Number of Parameter Vectors", 0); const Thyra::ModelEvaluatorBase::InArgs<double> nominal = solver->getNominalValues(); double norm2; for (int i=0; i<num_p; i++) { const Teuchos::RCP<const Epetra_Vector> p_init = epetraVectorFromThyra(appComm, nominal.get_p(i)); if(i < num_param_vecs) p_init->Print(*out << "\nParameter vector " << i << ":\n"); else { //distributed parameters, we print only 2-norm p_init->Norm2(&norm2); *out << "\nDistributed Parameter " << i << ": " << norm2 << " (two-norm)\n" << std::endl; } } for (int i=0; i<num_g-1; i++) { const RCP<const Epetra_Vector> g = responses[i]; bool is_scalar = true; if (app != Teuchos::null) is_scalar = app->getResponse(i)->isScalarResponse(); if (is_scalar) { g->Print(*out << "\nResponse vector " << i << ":\n"); if (num_p == 0) { // Just calculate regression data status += slvrfctry.checkSolveTestResults(i, 0, g.get(), NULL); } else { for (int j=0; j<num_p; j++) { const RCP<const Epetra_MultiVector> dgdp = sensitivities[i][j]; if (Teuchos::nonnull(dgdp)) { if(j < num_param_vecs) { dgdp->Print(*out << "\nSensitivities (" << i << "," << j << "): \n"); status += slvrfctry.checkSolveTestResults(i, j, g.get(), dgdp.get()); } else { const Epetra_Map serial_map(-1, 1, 0, dgdp.get()->Comm()); Epetra_MultiVector norms(serial_map,dgdp->NumVectors()); // RCP<Albany::ScalarResponseFunction> response = rcp_dynamic_cast<Albany::ScalarResponseFunction>(app->getResponse(i)); // int numResponses = response->numResponses(); *out << "\nSensitivities (" << i << "," << j << ") for Distributed Parameters: (two-norm)\n"; *out << " "; for(int ir=0; ir<dgdp->NumVectors(); ++ir) { (*dgdp)(ir)->Norm2(&norm2); (*norms(ir))[0] = norm2; *out << " " << norm2; } *out << "\n" << std::endl; status += slvrfctry.checkSolveTestResults(i, j, g.get(), &norms); } } } } } } // Create debug output object Teuchos::ParameterList &debugParams = slvrfctry.getParameters().sublist("Debug Output", true); bool writeToMatrixMarketSoln = debugParams.get("Write Solution to MatrixMarket", false); bool writeToMatrixMarketDistrSolnMap = debugParams.get("Write Distributed Solution and Map to MatrixMarket", false); bool writeToCoutSoln = debugParams.get("Write Solution to Standard Output", false); const RCP<const Epetra_Vector> xfinal = responses.back(); double mnv; xfinal->MeanValue(&mnv); *out << "Main_Solve: MeanValue of final solution " << mnv << std::endl; *out << "\nNumber of Failed Comparisons: " << status << std::endl; if (writeToCoutSoln == true) std::cout << "xfinal: " << *xfinal << std::endl; #ifdef ALBANY_PERIDIGM #if defined(ALBANY_EPETRA) if (Teuchos::nonnull(LCM::PeridigmManager::self())) { *out << setprecision(12) << "\nPERIDIGM-ALBANY OPTIMIZATION-BASED COUPLING FINAL FUNCTIONAL VALUE = " << LCM::PeridigmManager::self()->obcEvaluateFunctional() << "\n" << std::endl; } #endif #endif if (debugParams.get<bool>("Analyze Memory", false)) Albany::printMemoryAnalysis(std::cout, comm); if (writeToMatrixMarketSoln == true) { //create serial map that puts the whole solution on processor 0 int numMyElements = (xfinal->Comm().MyPID() == 0) ? app->getDiscretization()->getMap()->NumGlobalElements() : 0; const Epetra_Map serial_map(-1, numMyElements, 0, xfinal->Comm()); //create importer from parallel map to serial map and populate serial solution xfinal_serial Epetra_Import importOperator(serial_map, *app->getDiscretization()->getMap()); Epetra_Vector xfinal_serial(serial_map); xfinal_serial.Import(*app->getDiscretization()->getSolutionField(), importOperator, Insert); //writing to MatrixMarket file EpetraExt::MultiVectorToMatrixMarketFile("xfinal.mm", xfinal_serial); } if (writeToMatrixMarketDistrSolnMap == true) { //writing to MatrixMarket file EpetraExt::MultiVectorToMatrixMarketFile("xfinal_distributed.mm", *xfinal); EpetraExt::BlockMapToMatrixMarketFile("xfinal_distributed_map.mm", *app->getDiscretization()->getMap()); } } TEUCHOS_STANDARD_CATCH_STATEMENTS(true, std::cerr, success); if (!success) status+=10000; Teuchos::TimeMonitor::summarize(*out,false,true,false/*zero timers*/); Kokkos::finalize_all(); return status; }
void Piro::NOXSolver<Scalar>::evalModelImpl( const Thyra::ModelEvaluatorBase::InArgs<Scalar>& inArgs, const Thyra::ModelEvaluatorBase::OutArgs<Scalar>& outArgs ) const { using Teuchos::RCP; using Teuchos::rcp; //*out << "In eval Modle " << endl; // Parse InArgs RCP<const Thyra::VectorBase<Scalar> > p_in; if (num_p > 0) p_in = inArgs.get_p(0); // Parse OutArgs: always 1 extra RCP< Thyra::VectorBase<Scalar> > g_out; if (num_g > 0) g_out = outArgs.get_g(0); RCP< Thyra::VectorBase<Scalar> > gx_out = outArgs.get_g(num_g); // Parse out-args for sensitivity calculation ::Thyra::SolveCriteria<double> solve_criteria; ::Thyra::SolveStatus<double> solve_status; RCP< ::Thyra::VectorBase<double> > initial_guess = model->getNominalValues().get_x()->clone_v(); solve_status = solver->solve(initial_guess.get(), &solve_criteria, NULL); // if (solve_status.solveStatus == ::Thyra::SOLVE_STATUS_CONVERGED) // std::cout << "Test passed!" << std::endl; // return the final solution as an additional g-vector, if requested RCP<const Thyra::VectorBase<Scalar> > finalSolution = solver->get_current_x(); if (gx_out != Teuchos::null) Thyra::copy(*finalSolution, gx_out.ptr()); if (g_out != Teuchos::null) { // As post-processing step, calc responses at final solution Thyra::ModelEvaluatorBase::InArgs<Scalar> model_inargs = model->createInArgs(); Thyra::ModelEvaluatorBase::OutArgs<Scalar> model_outargs = model->createOutArgs(); model_inargs.set_x(finalSolution); if (num_p > 0) model_inargs.set_p(0, p_in); if (g_out != Teuchos::null) { Thyra::put_scalar(0.0,g_out.ptr()); model_outargs.set_g(0, g_out); } model->evalModel(model_inargs, model_outargs); } /********************* NEED TO CONVERT TO THYRA ******************* RCP< Thyra::MultiVectorBase<Scalar> > dgdp_out; if (num_p>0 && num_g>0) dgdp_out = outArgs.get_DgDp(0,0).getMultiVector(); if (dgdp_out == Teuchos::null) { Teuchos::RCP<Epetra_MultiVector> dgdx = Teuchos::rcp(new Epetra_MultiVector(finalSolution->Map(), dgdp_out->GlobalLength())); Teuchos::Array<int> p_indexes = outArgs.get_DgDp(0,0).getDerivativeMultiVector().getParamIndexes(); EpetraExt::ModelEvaluator::DerivativeMultiVector dmv_dgdp(dgdp_out, DERIV_MV_BY_COL, p_indexes); EpetraExt::ModelEvaluator::InArgs model_inargs = model->createInArgs(); EpetraExt::ModelEvaluator::OutArgs model_outargs = model->createOutArgs(); model_inargs.set_x(finalSolution); model_inargs.set_p(0, p_in); if (g_out != Teuchos::null) { g_out->PutScalar(0.0); model_outargs.set_g(0, g_out); } model_outargs.set_DgDp(0,0,dmv_dgdp); model_outargs.set_DgDx(0,dgdx); model->evalModel(model_inargs, model_outargs); // (3) Calculate dg/dp = dg/dx*dx/dp + dg/dp // This may be the transpose of what we want since we specified // we want dg/dp by column in createOutArgs(). // In this case just interchange the order of dgdx and dxdp // We should really probably check what the underlying ME does if (Teuchos::VERB_MEDIUM <= solnVerbLevel) cout << " dgdx \n" << *dgdx << endl; if (Teuchos::VERB_MEDIUM <= solnVerbLevel) cout << " dxdp \n" << *dxdp << endl; dgdp_out->Multiply('T', 'N', 1.0, *dgdx, *dxdp, 1.0); } *********************/ }
void Piro::RythmosSolver<Scalar>::evalModelImpl( const Thyra::ModelEvaluatorBase::InArgs<Scalar>& inArgs, const Thyra::ModelEvaluatorBase::OutArgs<Scalar>& outArgs ) const { using Teuchos::RCP; using Teuchos::rcp; // Parse InArgs RCP<const Thyra::VectorBase<Scalar> > p_in; if (num_p > 0) p_in = inArgs.get_p(0); // Parse OutArgs: always 1 extra RCP< Thyra::VectorBase<Scalar> > g_out; if (num_g > 0) g_out = outArgs.get_g(0); RCP< Thyra::VectorBase<Scalar> > gx_out = outArgs.get_g(num_g); // Parse out-args for sensitivity calculation RCP< Thyra::MultiVectorBase<Scalar> > dgdp_out; if (num_p>0 && num_g>0) dgdp_out = outArgs.get_DgDp(0,0).getMultiVector(); RCP<const Thyra::VectorBase<Scalar> > finalSolution; Thyra::ModelEvaluatorBase::InArgs<Scalar> state_ic = model->getNominalValues(); // Set paramters p_in as part of initial conditions if (num_p > 0) state_ic.set_p(0,p_in); //*out << "\nstate_ic:\n" << Teuchos::describe(state_ic,Teuchos::VERB_NONE); *out << "\nstate_ic:\n" << Teuchos::describe(state_ic,solnVerbLevel); if (dgdp_out == Teuchos::null) { // *out << "\nE) Solve the forward problem ...\n"; // fwdStateStepper->setInitialCondition(state_ic); fwdStateIntegrator->setStepper(fwdStateStepper, t_final, true); Teuchos::Array<RCP<const Thyra::VectorBase<Scalar> > > x_final_array; fwdStateIntegrator->getFwdPoints( Teuchos::tuple<Scalar>(t_final), &x_final_array, NULL, NULL ); finalSolution = x_final_array[0]; if (Teuchos::VERB_MEDIUM <= solnVerbLevel) std::cout << "Final Solution\n" << *finalSolution << std::endl; // As post-processing step, calc responses at final solution Thyra::ModelEvaluatorBase::InArgs<Scalar> model_inargs = model->createInArgs(); Thyra::ModelEvaluatorBase::OutArgs<Scalar> model_outargs = model->createOutArgs(); model_inargs.set_x(finalSolution); if (num_p > 0) model_inargs.set_p(0, p_in); if (g_out != Teuchos::null) { Thyra::put_scalar(0.0,g_out.ptr()); model_outargs.set_g(0, g_out); } model->evalModel(model_inargs, model_outargs); } else {//Doing sensitivities // *out << "\nE) Solve the forward problem with Sensitivities...\n"; // RCP<Rythmos::ForwardSensitivityStepper<Scalar> > stateAndSensStepper = Rythmos::forwardSensitivityStepper<Scalar>(); stateAndSensStepper->initializeSyncedSteppers( model, 0, model->getNominalValues(), fwdStateStepper, fwdTimeStepSolver); // // Set the initial condition for the state and forward sensitivities // RCP< Thyra::VectorBase<Scalar> > s_bar_init = createMember(stateAndSensStepper->getFwdSensModel()->get_x_space()); assign( s_bar_init.ptr(), 0.0 ); RCP< Thyra::VectorBase<Scalar> > s_bar_dot_init = createMember(stateAndSensStepper->getFwdSensModel()->get_x_space()); assign( s_bar_dot_init.ptr(), 0.0 ); // Above, I believe that these are the correct initial conditions for // s_bar and s_bar_dot given how the EpetraExt::DiagonalTransientModel // is currently implemented! RCP<const Rythmos::StateAndForwardSensitivityModelEvaluator<Scalar> > stateAndSensModel = stateAndSensStepper->getStateAndFwdSensModel(); Thyra::ModelEvaluatorBase::InArgs<Scalar> state_and_sens_ic = stateAndSensStepper->getModel()->createInArgs(); // Copy time, parameters etc. state_and_sens_ic.setArgs(state_ic); // Set initial condition for x_bar = [ x; s_bar ] state_and_sens_ic.set_x( stateAndSensModel->create_x_bar_vec(state_ic.get_x(),s_bar_init) ); // Set initial condition for x_bar_dot = [ x_dot; s_bar_dot ] state_and_sens_ic.set_x_dot( stateAndSensModel->create_x_bar_vec(state_ic.get_x_dot(),s_bar_dot_init) ); // *out << "\nstate_and_sens_ic:\n" << Teuchos::describe(state_and_sens_ic,Teuchos::VERB_DEFAULT); stateAndSensStepper->setInitialCondition(state_and_sens_ic); // // Use a StepperAsModelEvaluator to integrate the state+sens // RCP<Rythmos::StepperAsModelEvaluator<Scalar> > stateAndSensIntegratorAsModel = Rythmos::stepperAsModelEvaluator( Teuchos::rcp_implicit_cast<Rythmos::StepperBase<Scalar> >(stateAndSensStepper), Teuchos::rcp_implicit_cast<Rythmos::IntegratorBase<Scalar> >(fwdStateIntegrator), state_and_sens_ic ); *out << "\nUse the StepperAsModelEvaluator to integrate state + sens x_bar(p,t_final) ... \n"; RCP< Thyra::VectorBase<Scalar> > x_bar_final; Teuchos::OSTab tab(out); x_bar_final = createMember(stateAndSensIntegratorAsModel->get_g_space(0)); eval_g( *stateAndSensIntegratorAsModel, 0, *state_ic.get_p(0), t_final, 0, &*x_bar_final ); *out << "\nx_bar_final = x_bar(p,t_final) evaluated using " << "stateAndSensIntegratorAsModel:\n" << Teuchos::describe(*x_bar_final,solnVerbLevel); // As post-processing step, calc responses and gradient at final solution finalSolution = Thyra::productVectorBase<Scalar>(x_bar_final)->getVectorBlock(0); *out << "\nF) Check the solution to the forward problem ...\n"; // Extract sensitivity vectors into Epetra_MultiVector Teuchos::RCP<const Thyra::MultiVectorBase<Scalar> > dxdp = Teuchos::rcp_dynamic_cast<const Thyra::DefaultMultiVectorProductVector<Scalar> > (Thyra::productVectorBase<Scalar>(x_bar_final)->getVectorBlock(1)) ->getMultiVector();; Thyra::assign(dgdp_out.ptr(), 0.0); /********************* NEED TO CONVERT TO THYRA ******************* Teuchos::RCP<Epetra_MultiVector> dgdx = Teuchos::rcp(new Epetra_MultiVector(finalSolution->Map(), dgdp_out->GlobalLength())); Teuchos::Array<int> p_indexes = outArgs.get_DgDp(0,0).getDerivativeMultiVector().getParamIndexes(); EpetraExt::ModelEvaluator::DerivativeMultiVector dmv_dgdp(dgdp_out, DERIV_MV_BY_COL, p_indexes); EpetraExt::ModelEvaluator::InArgs model_inargs = model->createInArgs(); EpetraExt::ModelEvaluator::OutArgs model_outargs = model->createOutArgs(); model_inargs.set_x(finalSolution); model_inargs.set_p(0, p_in); if (g_out != Teuchos::null) { g_out->PutScalar(0.0); model_outargs.set_g(0, g_out); } model_outargs.set_DgDp(0,0,dmv_dgdp); model_outargs.set_DgDx(0,dgdx); model->evalModel(model_inargs, model_outargs); // (3) Calculate dg/dp = dg/dx*dx/dp + dg/dp // This may be the transpose of what we want since we specified // we want dg/dp by column in createOutArgs(). // In this case just interchange the order of dgdx and dxdp // We should really probably check what the underlying ME does if (Teuchos::VERB_MEDIUM <= solnVerbLevel) cout << " dgdx \n" << *dgdx << endl; if (Teuchos::VERB_MEDIUM <= solnVerbLevel) cout << " dxdp \n" << *dxdp << endl; dgdp_out->Multiply('T', 'N', 1.0, *dgdx, *dxdp, 1.0); *********************/ } // return the final solution as an additional g-vector, if requested if (gx_out != Teuchos::null) Thyra::copy(*finalSolution, gx_out.ptr()); }
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; }