11 {
13
14 try {
15 moab::Core moab_core;
18
20
27
33
34 Tao tao;
35 CHKERR TaoCreate(PETSC_COMM_WORLD, &tao);
36 CHKERR TaoSetType(tao, TAOALMM);
37 CHKERR TaoSetSolution(tao, x);
38
40
41 auto check_vector_pipeline = [&](auto context, const double value,
42 auto &pre_process, auto &post_process) {
43 auto pre = boost::make_shared<BasicMethod>();
44 auto post = boost::make_shared<BasicMethod>();
45 auto *pre_ptr = pre.get();
46 auto *post_ptr = post.get();
47
48 pre->preProcessHook = [pre_ptr, context, value,
c]() {
50 if (pre_ptr->tao_ctx != context || pre_ptr->tao_c !=
c)
52 "Incorrect TAO constraint context");
53 CHKERR VecSet(pre_ptr->tao_c, value);
55 };
56 post->postProcessHook = [post_ptr, context,
c]() {
58 if (post_ptr->tao_ctx != context || post_ptr->tao_c !=
c)
60 "Incorrect TAO constraint context");
62 };
63
64 pre_process.push_back(pre);
65 post_process.push_back(post);
66 };
67
68 auto check_jacobian_pipeline = [&](auto context, const double value,
69 auto &pre_process, auto &post_process) {
70 auto pre = boost::make_shared<BasicMethod>();
71 auto post = boost::make_shared<BasicMethod>();
72 auto *pre_ptr = pre.get();
73 auto *post_ptr = post.get();
74
75 pre->preProcessHook = [pre_ptr, context, value,
J]() {
77 if (pre_ptr->tao_ctx != context || pre_ptr->tao_J !=
J ||
78 pre_ptr->tao_Jpre !=
J)
80 "Incorrect TAO constraint Jacobian context");
81 CHKERR MatShift(pre_ptr->tao_Jpre, value);
83 };
84 post->postProcessHook = [post_ptr, context,
J]() {
86 if (post_ptr->tao_ctx != context || post_ptr->tao_J !=
J ||
87 post_ptr->tao_Jpre !=
J)
89 "Incorrect TAO constraint Jacobian context");
91 };
92
93 pre_process.push_back(pre);
94 post_process.push_back(post);
95 };
96
98 tao_ctx.getPreProcEqualityConstraint(),
99 tao_ctx.getPostProcEqualityConstraint());
101 tao_ctx.getPreProcInequalityConstraint(),
102 tao_ctx.getPostProcInequalityConstraint());
104 tao_ctx.getPreProcEqualityJacobian(),
105 tao_ctx.getPostProcEqualityJacobian());
107 tao_ctx.getPreProcInequalityJacobian(),
108 tao_ctx.getPostProcInequalityJacobian());
109
110 CHKERR TaoSetEqualityConstraintsRoutine(
112 CHKERR TaoSetInequalityConstraintsRoutine(
114 CHKERR TaoSetJacobianEqualityRoutine(
116 CHKERR TaoSetJacobianInequalityRoutine(
118
119 auto check_vector = [&](const double expected) {
122 PetscReal norm;
123 CHKERR VecNorm(
c, NORM_INFINITY, &norm);
124 if (norm > 10 * PETSC_MACHINE_EPSILON)
126 "Incorrect TAO constraint vector");
128 };
129
130 auto check_jacobian = [&](const double expected) {
134 PetscReal norm;
136 if (norm > 10 * PETSC_MACHINE_EPSILON)
138 "Incorrect TAO constraint Jacobian");
140 };
141
142 CHKERR TaoComputeEqualityConstraints(tao, x,
c);
144 CHKERR TaoComputeInequalityConstraints(tao, x,
c);
146 CHKERR TaoComputeJacobianEquality(tao, x,
J,
J);
147 CHKERR check_jacobian(4.0);
148 CHKERR TaoComputeJacobianInequality(tao, x,
J,
J);
149 CHKERR check_jacobian(5.0);
150
152 CHKERR copied_ctx.copyLoops(tao_ctx);
153 if (copied_ctx.getPreProcEqualityConstraint().empty() ||
154 copied_ctx.getPreProcInequalityConstraint().empty() ||
155 copied_ctx.getPreProcEqualityJacobian().empty() ||
156 copied_ctx.getPreProcInequalityJacobian().empty())
158 "TAO constraint pipelines were not copied");
159 CHKERR copied_ctx.clearLoops();
160 if (!copied_ctx.getPreProcEqualityConstraint().empty() ||
161 !copied_ctx.getPreProcInequalityConstraint().empty() ||
162 !copied_ctx.getPreProcEqualityJacobian().empty() ||
163 !copied_ctx.getPreProcInequalityJacobian().empty())
165 "TAO constraint pipelines were not cleared");
166
167
168
171 simple->getProblemName(),
COL, x, INSERT_VALUES, SCATTER_REVERSE);
177 PetscInt objective_calls = 0, gradient_calls = 0;
178 tao_ctx.getObjectiveHook() = [&](Tao,
Vec trial, PetscReal *objective) {
180 if (trial != x)
182 "Incorrect TAO objective-hook controls");
183 ++objective_calls;
184 *objective = 3.0;
186 };
187 tao_ctx.getGradientHook() = [&](Tao,
Vec trial,
Vec g) {
189 PetscBool equal;
190 CHKERR VecEqual(
g, expected_gradient, &equal);
191 if (trial != x || !equal)
193 "TAO gradient hook did not receive the cached gradient");
194 ++gradient_calls;
196 };
199 CHKERR ::TaoSetObjectiveAndGradient(
201 PetscReal objective;
202 CHKERR TaoComputeObjective(tao, x, &objective);
203 if (objective != 3.0 || objective_calls != 1 || gradient_calls != 0)
205 "Objective-only wrapper did not dispatch exclusively to its hook");
207 if (objective_calls != 1 || gradient_calls != 1)
209 "Gradient-only wrapper did not dispatch exclusively to its hook");
210 CHKERR TaoComputeObjectiveAndGradient(tao, x, &objective,
gradient);
211 PetscBool equal;
213 if (objective != 3.0 || objective_calls != 2 || gradient_calls != 2 ||
214 !equal)
216 "Combined wrapper did not fall back to the separate hooks");
219 simple->getProblemName(),
COL, mesh_controls, INSERT_VALUES,
220 SCATTER_FORWARD);
221 PetscReal mesh_norm;
222 CHKERR VecNorm(mesh_controls, NORM_INFINITY, &mesh_norm);
223 if (mesh_norm != 0)
225 "TAO evaluation hooks implicitly scattered trial controls");
226
228 }
230
232 return 0;
233}
SmartPetscObj< Vec > diagonal
SmartPetscObj< Vec > gradient
void simple(double P1[], double P2[], double P3[], double c[], const int N)
#define CATCH_ERRORS
Catch errors.
@ AINSWORTH_LEGENDRE_BASE
Ainsworth Cole (Legendre) approx. base .
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
@ MOFEM_DATA_INCONSISTENCY
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
PetscErrorCode DMRegister_MoFEM(const char sname[])
Register MoFEM problem.
auto createDMVector(DM dm, RowColData rc=RowColData::COL)
Get smart vector from DM.
auto createDMMatrix(DM dm)
Get smart matrix from DM.
const double c
speed of light (cm/ns)
FTensor::Index< 'J', DIM1 > J
const FTensor::Tensor2< T, Dim, Dim > Vec
PetscErrorCode TaoSetObjective(Tao tao, Vec x, PetscReal *f, void *ctx)
Sets the objective function value for a TAO optimization context.
PetscErrorCode TaoSetJacobianInequality(Tao tao, Vec x, Mat J, Mat Jpre, void *ctx)
Assemble the inequality constraint Jacobian.
PetscErrorCode TaoSetEqualityConstraints(Tao tao, Vec x, Vec c, void *ctx)
Evaluate equality constraints for a TAO optimization context.
SmartPetscObj< Vec > vectorDuplicate(Vec vec)
Create duplicate vector of smart vector.
PetscErrorCode TaoSetInequalityConstraints(Tao tao, Vec x, Vec c, void *ctx)
Evaluate inequality constraints for a TAO optimization context.
PetscErrorCode TaoSetJacobianEquality(Tao tao, Vec x, Mat J, Mat Jpre, void *ctx)
Assemble the equality constraint Jacobian.
PetscErrorCode TaoSetObjectiveAndGradient(Tao tao, Vec x, PetscReal *f, Vec g, void *ctx)
Sets the objective function value and gradient for a TAO optimization solver.
PetscErrorCode TaoSetGradient(Tao tao, Vec x, Vec f, void *ctx)
Sets the gradient vector for a TAO optimization context.
static MoFEMErrorCode Initialize(int *argc, char ***args, const char file[], const char help[])
Initializes the MoFEM database PETSc, MOAB and MPI.
static MoFEMErrorCode Finalize()
Checks for options to be called at the conclusion of the program.
Deprecated interface functions.
Simple interface for fast problem set-up.
MoFEMErrorCode getOptions()
get options
Interface for TAO solvers.
@ CTX_TAO_EQUALITY_CONSTRAINT
Evaluating equality constraints.
@ CTX_TAO_EQUALITY_JACOBIAN
Assembling equality Jacobian.
@ CTX_TAO_INEQUALITY_JACOBIAN
Assembling inequality Jacobian.
@ CTX_TAO_INEQUALITY_CONSTRAINT
Evaluating inequality constraints.
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.
Vector manager is used to create vectors \mofem_vectors.