19 #ifndef TAOUTIL_HH_W42GJNRO
20 #define TAOUTIL_HH_W42GJNRO
26 #include "pism/util/pism_utilities.hh"
27 #include "pism/util/TerminationReason.hh"
28 #include "pism/util/petscwrappers/Tao.hh"
29 #include "pism/util/error_handling.hh"
91 template<
class Problem>
103 ierr = TaoSetType(
m_tao,tao_type.c_str());
108 ierr = TaoSetFromOptions(
m_tao);
109 PISM_CHK(ierr,
"TaoSetFromOptions");
117 virtual std::shared_ptr<TerminationReason>
solve() {
122 auto reason =
m_problem.formInitialGuess(&x0);
123 if (reason->failed()) {
124 auto root_cause = reason;
126 reason->set_root_cause(root_cause);
129 #if PETSC_VERSION_LT(3,17,0)
130 ierr = TaoSetInitialVector(
m_tao, x0);
132 ierr = TaoSetSolution(
m_tao, x0);
134 PISM_CHK(ierr,
"TaoSetInitialVector");
136 ierr = TaoSolve(
m_tao);
139 TaoConvergedReason tao_reason;
140 ierr = TaoGetConvergedReason(
m_tao, &tao_reason);
141 PISM_CHK(ierr,
"TaoGetConvergedReason");
148 PetscErrorCode ierr = TaoSetMaximumIterations(
m_tao, max_it);
149 PISM_CHK(ierr,
"TaoSetMaximumIterations");
182 template<
class Problem>
188 ierr = TaoSetObjectiveRoutine(tao,
191 PISM_CHK(ierr,
"TaoSetObjectiveRoutine");
195 static PetscErrorCode
callback(Tao tao, Vec x,
double *value,
void *ctx) {
197 Problem *p =
reinterpret_cast<Problem *
>(ctx);
198 PetscErrorCode ierr = p->evaluateObjective(tao,x,value); CHKERRQ(ierr);
200 MPI_Comm com = MPI_COMM_SELF;
201 PetscErrorCode ierr = PetscObjectGetComm((PetscObject)tao, &com); CHKERRQ(ierr);
203 SETERRQ(com, 1,
"A PISM callback failed");
229 template<
class Problem>
233 #if PETSC_VERSION_LT(3,21,0)
234 PetscErrorCode ierr = TaoSetMonitor(tao,
236 PetscErrorCode ierr = TaoMonitorSet(tao,
243 static PetscErrorCode
callback(Tao tao,
void *ctx) {
245 Problem *p =
reinterpret_cast<Problem *
>(ctx);
248 MPI_Comm com = MPI_COMM_SELF;
249 PetscErrorCode ierr = PetscObjectGetComm((PetscObject)tao, &com); CHKERRQ(ierr);
251 SETERRQ(com, 1,
"A PISM callback failed");
276 template<
class Problem>
281 ierr = TaoSetVariableBoundsRoutine(tao,
284 PISM_CHK(ierr,
"TaoSetVariableBoundsRoutine");
288 static PetscErrorCode
callback(Tao tao, Vec lo, Vec hi,
void *ctx) {
290 Problem *p =
reinterpret_cast<Problem *
>(ctx);
291 p->getVariableBounds(tao,lo,hi);
293 MPI_Comm com = MPI_COMM_SELF;
294 PetscErrorCode ierr = PetscObjectGetComm((PetscObject)tao, &com); CHKERRQ(ierr);
296 SETERRQ(com, 1,
"A PISM callback failed");
321 template<
class Problem>
326 ierr = TaoSetGradientRoutine(tao,
329 PISM_CHK(ierr,
"TaoSetGradientRoutine");
333 static PetscErrorCode
callback(Tao tao, Vec x, Vec gradient,
void *ctx) {
335 Problem *p =
reinterpret_cast<Problem *
>(ctx);
336 p->evaluateGradient(tao,x,gradient);
338 MPI_Comm com = MPI_COMM_SELF;
339 PetscErrorCode ierr = PetscObjectGetComm((PetscObject)tao, &com); CHKERRQ(ierr);
341 SETERRQ(com, 1,
"A PISM callback failed");
366 template<
class Problem>
371 ierr = TaoSetConvergenceTest(tao,
374 PISM_CHK(ierr,
"TaoSetConvergenceTest");
377 static PetscErrorCode
callback(Tao tao,
void *ctx) {
379 Problem *p =
reinterpret_cast<Problem *
>(ctx);
380 p->convergenceTest(tao);
382 MPI_Comm com = MPI_COMM_SELF;
383 PetscErrorCode ierr = PetscObjectGetComm((PetscObject)tao, &com); CHKERRQ(ierr);
385 SETERRQ(com, 1,
"A PISM callback failed");
410 template<
class Problem,
void (Problem::*Callback)(Tao,Vec,
double*,Vec) >
415 #if PETSC_VERSION_LT(3,17,0)
416 ierr = TaoSetObjectiveAndGradientRoutine(tao,
420 ierr = TaoSetObjectiveAndGradient(tao,
425 PISM_CHK(ierr,
"TaoSetObjectiveAndGradientRoutine");
428 static PetscErrorCode
callback(Tao tao, Vec x,
double *value, Vec gradient,
void *ctx) {
430 Problem *p =
reinterpret_cast<Problem *
>(ctx);
431 (p->*Callback)(tao,x,value,gradient);
433 MPI_Comm com = MPI_COMM_SELF;
434 PetscErrorCode ierr = PetscObjectGetComm((PetscObject)tao, &com); CHKERRQ(ierr);
436 SETERRQ(com, 1,
"A PISM callback failed");
460 template<
class Problem>
463 static void connect(Tao tao, Problem &p, Vec c, Mat Jc, Mat Jd, Mat Jcpc=NULL, Mat Jcinv=NULL) {
466 ierr = TaoSetConstraintsRoutine(tao, c,
468 PISM_CHK(ierr,
"TaoSetConstraintsRoutine");
474 ierr = TaoSetJacobianStateRoutine(tao, Jc, Jcpc, Jcinv,
476 PISM_CHK(ierr,
"TaoSetJacobianStateRoutine");
478 ierr = TaoSetJacobianDesignRoutine(tao, Jd,
480 PISM_CHK(ierr,
"TaoSetJacobianDesignRoutine");
485 Problem *p =
reinterpret_cast<Problem *
>(ctx);
486 p->evaluateConstraints(tao, x, c);
488 MPI_Comm com = MPI_COMM_SELF;
489 PetscErrorCode ierr = PetscObjectGetComm((PetscObject)tao, &com); CHKERRQ(ierr);
491 SETERRQ(com, 1,
"A PISM callback failed");
497 Mat Jinv,
void*ctx) {
499 Problem *p =
reinterpret_cast<Problem *
>(ctx);
503 MatStructure structure;
504 p->evaluateConstraintsJacobianState(tao, x,
J, Jpc, Jinv, &structure);
506 MPI_Comm com = MPI_COMM_SELF;
507 PetscErrorCode ierr = PetscObjectGetComm((PetscObject)tao, &com); CHKERRQ(ierr);
509 SETERRQ(com, 1,
"A PISM callback failed");
516 Problem *p =
reinterpret_cast<Problem *
>(ctx);
517 p->evaluateConstraintsJacobianDesign(tao, x,
J);
519 MPI_Comm com = MPI_COMM_SELF;
520 PetscErrorCode ierr = PetscObjectGetComm((PetscObject)tao, &com); CHKERRQ(ierr);
522 SETERRQ(com, 1,
"A PISM callback failed");
TAOTerminationReason(TaoConvergedReason r)
virtual void get_description(std::ostream &desc, int indent_level=0)
Encapsulate TAO's TaoSolverTerminationReason codes as a PISM TerminationReason.
virtual ~TaoBasicSolver()
virtual std::shared_ptr< TerminationReason > solve()
Solve the minimization problem.
virtual Problem & problem()
TaoBasicSolver(MPI_Comm comm, const std::string &tao_type, Problem &prob)
Construct a solver to solve prob using TAO algorithm tao_type.
virtual void setMaximumIterations(int max_it)
An interface for solving an optimization problem with TAO where the problem itself is defined by a se...
static void connect(Tao tao, Problem &p)
static PetscErrorCode callback(Tao tao, void *ctx)
Adaptor to connect a TAO objective function callback to a C++ object method.
static PetscErrorCode callback(Tao tao, Vec lo, Vec hi, void *ctx)
static void connect(Tao tao, Problem &p)
Adaptor to connect a TAO objective function callback to a C++ object method.
static PetscErrorCode callback(Tao tao, Vec x, Vec gradient, void *ctx)
static void connect(Tao tao, Problem &p)
Adaptor to connect a TAO objective gradient callback to a C++ object method.
static PetscErrorCode constraints_callback(Tao tao, Vec x, Vec c, void *ctx)
static void connect(Tao tao, Problem &p, Vec c, Mat Jc, Mat Jd, Mat Jcpc=NULL, Mat Jcinv=NULL)
static PetscErrorCode jacobian_design_callback(Tao tao, Vec x, Mat J, void *ctx)
static PetscErrorCode jacobian_state_callback(Tao tao, Vec x, Mat J, Mat Jpc, Mat Jinv, void *ctx)
Adaptor to connect a TAO objective function callback to a C++ object method.
static PetscErrorCode callback(Tao tao, void *ctx)
static void connect(Tao tao, Problem &p)
Adaptor to connect a TAO monitoring callback to a C++ object method.
static PetscErrorCode callback(Tao tao, Vec x, double *value, Vec gradient, void *ctx)
static void connect(Tao tao, Problem &p)
Adaptor to connect a TAO objective and gradient function callback to a C++ object method.
static void connect(Tao tao, Problem &p)
static PetscErrorCode callback(Tao tao, Vec x, double *value, void *ctx)
Adaptor to connect a TAO objective function callback to a C++ object method.
#define PISM_CHK(errcode, name)
void handle_fatal_errors(MPI_Comm com)