//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // // trilinosModelEvaluator.cpp - part of the Community Ice Sheet Model (CISM) // //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // // Copyright (C) 2005-2014 // CISM contributors - see AUTHORS file for list of contributors // // This file is part of CISM. // // CISM is free software: you can redistribute it and/or modify it // under the terms of the Lesser GNU General Public License as published // by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // CISM is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // Lesser GNU General Public License for more details. // // You should have received a copy of the Lesser GNU General Public License // along with CISM. If not, see . // //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ #include "trilinosModelEvaluator.hpp" #include "Teuchos_StandardCatchMacros.hpp" extern "C" { void calc_F(double* x, double* f, int N, void* bb, int ispert); void apply_precond_nox(double* x, double* y, int n, void* bb); void reset_effstrmin(const double* esm); } /*******************************************************************************/ /*******************************************************************************/ /*******************************************************************************/ trilinosModelEvaluator::trilinosModelEvaluator ( int N_, double* statevector, const Epetra_Comm& comm_, void* blackbox_res_) : N(N_), comm(comm_), blackbox_res(blackbox_res_) { bool succeeded=true; try { xMap = Teuchos::rcp(new Epetra_Map(-1, N, 0, comm)); xVec = Teuchos::rcp(new Epetra_Vector(Copy, *xMap, statevector)); precOp = Teuchos::rcp(new trilinosPreconditioner(N, xVec, xMap, blackbox_res)); pMap = Teuchos::rcp(new Epetra_LocalMap(1, 0, comm)); pVec = Teuchos::rcp(new Epetra_Vector(*pMap)); } TEUCHOS_STANDARD_CATCH_STATEMENTS(true, std::cerr, succeeded); if (!succeeded) exit(1); } /*******************************************************************************/ // Return solution vector map Teuchos::RCP trilinosModelEvaluator::get_x_map() const{ return xMap; } // Return residual vector map Teuchos::RCP trilinosModelEvaluator::get_f_map() const{ return xMap; } // Return initial solution and x_dot init Teuchos::RCP trilinosModelEvaluator::get_x_init() const{ return xVec; } Teuchos::RCP trilinosModelEvaluator::create_WPrec() const { // bool is answer to: "Prec is already inverted?" return Teuchos::rcp(new EpetraExt::ModelEvaluator::Preconditioner(precOp,true)); } Teuchos::RCP trilinosModelEvaluator::get_p_map(int l) const{ return pMap; } Teuchos::RCP trilinosModelEvaluator::get_p_init(int l) const{ return pVec; } Teuchos::RCP > trilinosModelEvaluator::get_p_names(int l) const{ RCP > p_names = rcp(new Teuchos::Array(1) ); (*p_names)[0] = "Effstrmin Factor"; return p_names; } /*******************************************************************************/ // Create InArgs EpetraExt::ModelEvaluator::InArgs trilinosModelEvaluator::createInArgs() const{ InArgsSetup inArgs; inArgs.setModelEvalDescription(this->description()); inArgs.setSupports(IN_ARG_x,true); inArgs.set_Np(1); return inArgs; } /*******************************************************************************/ // Create OutArgs EpetraExt::ModelEvaluator::OutArgs trilinosModelEvaluator::createOutArgs() const{ OutArgsSetup outArgs; outArgs.setModelEvalDescription(this->description()); outArgs.set_Np_Ng(1, 0); outArgs.setSupports(OUT_ARG_f,true); outArgs.setSupports(OUT_ARG_WPrec, true); return outArgs; } /*******************************************************************************/ // Evaluate model on InArgs void trilinosModelEvaluator::evalModel(const InArgs& inArgs, const OutArgs& outArgs) const{ // Get the solution vector x from inArgs and residual vector from outArgs RCP x = inArgs.get_x(); EpetraExt::ModelEvaluator::Evaluation f = outArgs.get_f(); if (x == Teuchos::null) throw "trilinosModelEvaluator::evalModel: x was NOT specified!"; // Check if a "Effminstr Factor" parameter is being set by LOCA Teuchos::RCP p_in = inArgs.get_p(0); if (p_in.get()) reset_effstrmin(&(*p_in)[0]); // Save the current solution, which makes it initial guess for next nonlienar solve *xVec = *x; if (f != Teuchos::null) { // Check if this is a perturbed eval. Glimmer only saves off matrices for unperturbed case. int ispert =0; if (f.getType() == EpetraExt::ModelEvaluator::EVAL_TYPE_APPROX_DERIV) ispert=1; f->PutScalar(0.0); calc_F(x->Values(), f->Values(), N, blackbox_res, ispert); } RCP WPrec = outArgs.get_WPrec(); if (WPrec != Teuchos::null) { //cout << "evalModel called for WPrec -- doing nothing " << endl; } } /*******************************************************************************/ /*******************************************************************************/ /*******************************************************************************/ trilinosPreconditioner::trilinosPreconditioner ( int N_, RCP xVec_, RCP xMap_, void* blackbox_res_) : N(N_), xVec(xVec_), xMap(xMap_), blackbox_res(blackbox_res_) { } int trilinosPreconditioner::ApplyInverse(const Epetra_MultiVector& X, Epetra_MultiVector& Y) const { bool succeeded=true; try { apply_precond_nox(Y(0)->Values(), X(0)->Values(), N, blackbox_res); } TEUCHOS_STANDARD_CATCH_STATEMENTS(true, std::cerr, succeeded); if (!succeeded) exit(1); return 0; }