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 PetscErrorCode ierr = TaoSetMonitor(tao,
239 static PetscErrorCode
callback(Tao tao,
void *ctx) {
241 Problem *p =
reinterpret_cast<Problem *
>(ctx);
244 MPI_Comm com = MPI_COMM_SELF;
245 PetscErrorCode ierr = PetscObjectGetComm((PetscObject)tao, &com); CHKERRQ(ierr);
247 SETERRQ(com, 1,
"A PISM callback failed");
272 template<
class Problem>
277 ierr = TaoSetVariableBoundsRoutine(tao,
280 PISM_CHK(ierr,
"TaoSetVariableBoundsRoutine");
284 static PetscErrorCode
callback(Tao tao, Vec lo, Vec hi,
void *ctx) {
286 Problem *p =
reinterpret_cast<Problem *
>(ctx);
287 p->getVariableBounds(tao,lo,hi);
289 MPI_Comm com = MPI_COMM_SELF;
290 PetscErrorCode ierr = PetscObjectGetComm((PetscObject)tao, &com); CHKERRQ(ierr);
292 SETERRQ(com, 1,
"A PISM callback failed");
317 template<
class Problem>
322 ierr = TaoSetGradientRoutine(tao,
325 PISM_CHK(ierr,
"TaoSetGradientRoutine");
329 static PetscErrorCode
callback(Tao tao, Vec x, Vec gradient,
void *ctx) {
331 Problem *p =
reinterpret_cast<Problem *
>(ctx);
332 p->evaluateGradient(tao,x,gradient);
334 MPI_Comm com = MPI_COMM_SELF;
335 PetscErrorCode ierr = PetscObjectGetComm((PetscObject)tao, &com); CHKERRQ(ierr);
337 SETERRQ(com, 1,
"A PISM callback failed");
362 template<
class Problem>
367 ierr = TaoSetConvergenceTest(tao,
370 PISM_CHK(ierr,
"TaoSetConvergenceTest");
373 static PetscErrorCode
callback(Tao tao,
void *ctx) {
375 Problem *p =
reinterpret_cast<Problem *
>(ctx);
376 p->convergenceTest(tao);
378 MPI_Comm com = MPI_COMM_SELF;
379 PetscErrorCode ierr = PetscObjectGetComm((PetscObject)tao, &com); CHKERRQ(ierr);
381 SETERRQ(com, 1,
"A PISM callback failed");
406 template<
class Problem,
void (Problem::*Callback)(Tao,Vec,
double*,Vec) >
411 #if PETSC_VERSION_LT(3,17,0)
412 ierr = TaoSetObjectiveAndGradientRoutine(tao,
416 ierr = TaoSetObjectiveAndGradient(tao,
421 PISM_CHK(ierr,
"TaoSetObjectiveAndGradientRoutine");
424 static PetscErrorCode
callback(Tao tao, Vec x,
double *value, Vec gradient,
void *ctx) {
426 Problem *p =
reinterpret_cast<Problem *
>(ctx);
427 (p->*Callback)(tao,x,value,gradient);
429 MPI_Comm com = MPI_COMM_SELF;
430 PetscErrorCode ierr = PetscObjectGetComm((PetscObject)tao, &com); CHKERRQ(ierr);
432 SETERRQ(com, 1,
"A PISM callback failed");
456 template<
class Problem>
459 static void connect(Tao tao, Problem &p, Vec c, Mat Jc, Mat Jd, Mat Jcpc=NULL, Mat Jcinv=NULL) {
462 ierr = TaoSetConstraintsRoutine(tao, c,
464 PISM_CHK(ierr,
"TaoSetConstraintsRoutine");
470 ierr = TaoSetJacobianStateRoutine(tao, Jc, Jcpc, Jcinv,
472 PISM_CHK(ierr,
"TaoSetJacobianStateRoutine");
474 ierr = TaoSetJacobianDesignRoutine(tao, Jd,
476 PISM_CHK(ierr,
"TaoSetJacobianDesignRoutine");
481 Problem *p =
reinterpret_cast<Problem *
>(ctx);
482 p->evaluateConstraints(tao, x, c);
484 MPI_Comm com = MPI_COMM_SELF;
485 PetscErrorCode ierr = PetscObjectGetComm((PetscObject)tao, &com); CHKERRQ(ierr);
487 SETERRQ(com, 1,
"A PISM callback failed");
493 Mat Jinv,
void*ctx) {
495 Problem *p =
reinterpret_cast<Problem *
>(ctx);
499 MatStructure structure;
500 p->evaluateConstraintsJacobianState(tao, x,
J, Jpc, Jinv, &structure);
502 MPI_Comm com = MPI_COMM_SELF;
503 PetscErrorCode ierr = PetscObjectGetComm((PetscObject)tao, &com); CHKERRQ(ierr);
505 SETERRQ(com, 1,
"A PISM callback failed");
512 Problem *p =
reinterpret_cast<Problem *
>(ctx);
513 p->evaluateConstraintsJacobianDesign(tao, x,
J);
515 MPI_Comm com = MPI_COMM_SELF;
516 PetscErrorCode ierr = PetscObjectGetComm((PetscObject)tao, &com); CHKERRQ(ierr);
518 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)