v0.15.0
Loading...
Searching...
No Matches
TaoCtx.cpp
Go to the documentation of this file.
1/**
2 * @brief Context for Tao optimization routines
3 * @author Anonymous author(s) committing under MIT license
4 */
5
6
7namespace MoFEM {
8
22
25 loopsHessian.clear();
26 loopsObjective.clear();
27 loopsGradient.clear();
28 preHessian.clear();
29 postHessian.clear();
30 preObjective.clear();
31 postObjective.clear();
32 preGradient.clear();
33 postGradient.clear();
35}
36
37PetscErrorCode TaoSetObjective(Tao tao, Vec x, PetscReal *f, void *ctx) {
38 TaoCtx *tao_ctx = (TaoCtx *)ctx;
40 PetscLogEventBegin(tao_ctx->MOFEM_EVENT_TaoObjective, 0, 0, 0, 0);
41 CHKERR VecGhostUpdateBegin(x, INSERT_VALUES, SCATTER_FORWARD);
42 CHKERR VecGhostUpdateEnd(x, INSERT_VALUES, SCATTER_FORWARD);
43 CHKERR tao_ctx->mField.getInterface<VecManager>()->setLocalGhostVector(
44 tao_ctx->problemName, COL, x, INSERT_VALUES, SCATTER_REVERSE);
45
46 auto cache_ptr = boost::make_shared<CacheTuple>();
48 cache_ptr);
49
50 auto set = [&](auto &fe) {
51 fe.tao = tao;
52 fe.tao_x = x;
54 fe.data_ctx = PetscData::CtxSetX;
55 fe.cacheWeakPtr = cache_ptr;
56 };
57
58 auto unset = [&](auto &fe) {
59 fe.tao_ctx = TaoMethod::CTX_TAO_NONE;
60 fe.data_ctx = PetscData::CtxSetNone;
61 };
62
63 for (auto &bit : tao_ctx->preObjective) {
64 bit->vecAssembleSwitch = boost::move(tao_ctx->vecAssembleSwitch);
65 set(*bit);
67 *bit);
68 unset(*bit);
69 }
70
71 for (auto &lit : tao_ctx->loopsObjective) {
72 set(*lit.second);
73 CHKERR tao_ctx->mField.loop_finite_elements(tao_ctx->problemName, lit.first,
74 *lit.second, nullptr, MF_EXIST,
75 cache_ptr);
76 unset(*lit.second);
77 }
78
79 for (auto &bit : tao_ctx->postObjective) {
80 bit->vecAssembleSwitch = boost::move(tao_ctx->vecAssembleSwitch);
81 set(*bit);
83 tao_ctx->problemName, *bit);
84 unset(*bit);
85 tao_ctx->vecAssembleSwitch = boost::move(bit->vecAssembleSwitch);
86 }
87
88 PetscLogEventEnd(tao_ctx->MOFEM_EVENT_TaoObjective, 0, 0, 0, 0);
90}
91
92PetscErrorCode TaoSetGradient(Tao tao, Vec x, Vec f, void *ctx) {
93 TaoCtx *tao_ctx = (TaoCtx *)ctx;
95 PetscLogEventBegin(tao_ctx->MOFEM_EVENT_TaoGradient, 0, 0, 0, 0);
96 CHKERR VecGhostUpdateBegin(x, INSERT_VALUES, SCATTER_FORWARD);
97 CHKERR VecGhostUpdateEnd(x, INSERT_VALUES, SCATTER_FORWARD);
98 CHKERR tao_ctx->mField.getInterface<VecManager>()->setLocalGhostVector(
99 tao_ctx->problemName, COL, x, INSERT_VALUES, SCATTER_REVERSE);
100
101 auto zero_ghost_vec = [](Vec g) {
103 Vec l;
104 CHKERR VecGhostGetLocalForm(g, &l);
105 double *a;
106 CHKERR VecGetArray(l, &a);
107 int s;
108 CHKERR VecGetLocalSize(l, &s);
109 for (int i = 0; i != s; ++i)
110 a[i] = 0;
111 CHKERR VecRestoreArray(l, &a);
112 CHKERR VecGhostRestoreLocalForm(g, &l);
114 };
115 CHKERR zero_ghost_vec(f);
116
117 tao_ctx->vecAssembleSwitch = boost::movelib::make_unique<bool>(true);
118 auto cache_ptr = boost::make_shared<CacheTuple>();
120 cache_ptr);
121
122 auto set = [&](auto &fe) {
123 fe.tao = tao;
124 fe.tao_x = x;
125 fe.tao_f = f;
127 fe.ksp_ctx = KspMethod::CTX_SETFUNCTION;
128 fe.tao_ctx = TaoMethod::CTX_TAO_GRADIENT;
130 fe.cacheWeakPtr = cache_ptr;
131 };
132
133 auto unset = [&](auto &fe) {
134 fe.snes_ctx = SnesMethod::CTX_SNESNONE;
135 fe.ksp_ctx = KspMethod::CTX_KSPNONE;
136 fe.tao_ctx = TaoMethod::CTX_TAO_GRADIENT;
137 fe.data_ctx = PetscData::CtxSetNone;
138 };
139
140 for (auto &bit : tao_ctx->preGradient) {
141 bit->vecAssembleSwitch = boost::move(tao_ctx->vecAssembleSwitch);
142 set(*bit);
144 *bit);
145 unset(*bit);
146 tao_ctx->vecAssembleSwitch = boost::move(bit->vecAssembleSwitch);
147 }
148
149 for (auto &lit : tao_ctx->loopsGradient) {
150 lit.second->vecAssembleSwitch = boost::move(tao_ctx->vecAssembleSwitch);
151 set(*lit.second);
152 CHKERR tao_ctx->mField.loop_finite_elements(tao_ctx->problemName, lit.first,
153 *lit.second, nullptr,
154 MF_EXIST, cache_ptr);
155 unset(*lit.second);
156 tao_ctx->vecAssembleSwitch = boost::move(lit.second->vecAssembleSwitch);
157 }
158
159 for (auto &bit : tao_ctx->postGradient) {
160 bit->vecAssembleSwitch = boost::move(tao_ctx->vecAssembleSwitch);
161 set(*bit);
163 tao_ctx->problemName, *bit);
164 unset(*bit);
165 tao_ctx->vecAssembleSwitch = boost::move(bit->vecAssembleSwitch);
166 }
167
168 if (*(tao_ctx->vecAssembleSwitch)) {
169 CHKERR VecGhostUpdateBegin(f, ADD_VALUES, SCATTER_REVERSE);
170 CHKERR VecGhostUpdateEnd(f, ADD_VALUES, SCATTER_REVERSE);
171 CHKERR VecAssemblyBegin(f);
172 CHKERR VecAssemblyEnd(f);
173 }
174 PetscLogEventEnd(tao_ctx->MOFEM_EVENT_TaoGradient, 0, 0, 0, 0);
176}
177
178PetscErrorCode TaoSetObjectiveAndGradient(Tao tao, Vec x, PetscReal *f, Vec g,
179 void *ctx) {
181 CHKERR TaoSetObjective(tao, x, f, ctx);
182 CHKERR TaoSetGradient(tao, x, g, ctx);
184}
185
186PetscErrorCode TaoSetHessian(Tao tao, Vec x, Mat H, Mat Hpre, void *ctx) {
187 TaoCtx *tao_ctx = (TaoCtx *)ctx;
189 PetscLogEventBegin(tao_ctx->MOFEM_EVENT_TaoHessian, 0, 0, 0, 0);
190
191 tao_ctx->matAssembleSwitch = boost::movelib::make_unique<bool>(true);
192 auto cache_ptr = boost::make_shared<CacheTuple>();
194 cache_ptr);
195
196 auto set = [&](auto &fe) {
197 fe.tao = tao;
198 fe.tao_A = H;
199 fe.tao_B = Hpre;
200 fe.ksp_ctx = KspMethod::CTX_OPERATORS;
202 fe.tao_ctx = TaoMethod::CTX_TAO_HESSIAN;
204 fe.cacheWeakPtr = cache_ptr;
205 };
206
207 auto unset = [&](auto &fe) {
208 fe.snes_ctx = SnesMethod::CTX_SNESNONE;
209 fe.ksp_ctx = KspMethod::CTX_KSPNONE;
210 fe.tao_ctx = TaoMethod::CTX_TAO_NONE;
211 fe.data_ctx = PetscData::CtxSetNone;
212 };
213
214
215 CHKERR VecGhostUpdateBegin(x, INSERT_VALUES, SCATTER_FORWARD);
216 CHKERR VecGhostUpdateEnd(x, INSERT_VALUES, SCATTER_FORWARD);
217 CHKERR tao_ctx->mField.getInterface<VecManager>()->setLocalGhostVector(
218 tao_ctx->problemName, COL, x, INSERT_VALUES, SCATTER_REVERSE);
219
220 for (auto &bit : tao_ctx->preHessian) {
221 bit->matAssembleSwitch = boost::move(tao_ctx->matAssembleSwitch);
222 set(*bit);
224 tao_ctx->problemName, *bit);
225 unset(*bit);
226 tao_ctx->matAssembleSwitch = boost::move(bit->matAssembleSwitch);
227 }
228
229 for (auto &lit : tao_ctx->loopsHessian) {
230 lit.second->matAssembleSwitch = boost::move(tao_ctx->matAssembleSwitch);
231 set(*lit.second);
233 tao_ctx->problemName, lit.first, *(lit.second), nullptr, MF_EXIST,
234 cache_ptr);
235 unset(*lit.second);
236 tao_ctx->matAssembleSwitch = boost::move(lit.second->matAssembleSwitch);
237 }
238
239 for (auto &bit : tao_ctx->postHessian) {
240 bit->matAssembleSwitch = boost::move(tao_ctx->matAssembleSwitch);
241 set(*bit);
243 tao_ctx->problemName, *bit);
244 unset(*bit);
245 tao_ctx->matAssembleSwitch = boost::move(bit->matAssembleSwitch);
246 }
247
248 if (*tao_ctx->matAssembleSwitch) {
249 CHKERR MatAssemblyBegin(Hpre, MAT_FINAL_ASSEMBLY);
250 CHKERR MatAssemblyEnd(Hpre, MAT_FINAL_ASSEMBLY);
251 }
252 PetscLogEventEnd(tao_ctx->MOFEM_EVENT_TaoHessian, 0, 0, 0, 0);
254}
255
256} // namespace MoFEM
constexpr double a
@ COL
@ MF_EXIST
#define MoFEMFunctionReturnHot(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
#define MoFEMFunctionBeginHot
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
virtual MoFEMErrorCode problem_basic_method_postProcess(const Problem *problem_ptr, BasicMethod &method, int verb=DEFAULT_VERBOSITY)=0
Set data for BasicMethod.
virtual MoFEMErrorCode loop_finite_elements(const std::string problem_name, const std::string &fe_name, FEMethod &method, boost::shared_ptr< NumeredEntFiniteElement_multiIndex > fe_ptr=nullptr, MoFEMTypes bh=MF_EXIST, CacheTupleWeakPtr cache_ptr=CacheTupleSharedPtr(), int verb=DEFAULT_VERBOSITY)=0
Make a loop over finite elements.
auto bit
set bit
FTensor::Index< 'i', SPACE_DIM > i
FTensor::Index< 'l', 3 > l
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
implementation of Data Operators for Forces and Sources
Definition Common.hpp:10
PetscErrorCode TaoSetObjective(Tao tao, Vec x, PetscReal *f, void *ctx)
Sets the objective function value for a TAO optimization context.
Definition TaoCtx.cpp:37
PetscErrorCode TaoSetObjectiveAndGradient(Tao tao, Vec x, PetscReal *f, Vec g, void *ctx)
Sets the objective function value and gradient for a TAO optimization solver.
Definition TaoCtx.cpp:178
PetscErrorCode TaoSetGradient(Tao tao, Vec x, Vec f, void *ctx)
Sets the gradient vector for a TAO optimization context.
Definition TaoCtx.cpp:92
PetscErrorCode TaoSetHessian(Tao tao, Vec x, Mat H, Mat Hpre, void *ctx)
Sets the Hessian matrix for a TAO optimization context.
Definition TaoCtx.cpp:186
constexpr double g
virtual MoFEMErrorCode cache_problem_entities(const std::string prb_name, CacheTupleWeakPtr cache_ptr)=0
Cache variables.
virtual MoFEMErrorCode problem_basic_method_preProcess(const Problem *problem_ptr, BasicMethod &method, int verb=DEFAULT_VERBOSITY)=0
Set data for BasicMethod.
@ CTX_KSPNONE
No specific KSP context.
@ CTX_SETFUNCTION
Setting up the linear system function.
@ CTX_OPERATORS
Setting up linear operators.
static constexpr Switches CtxSetA
Jacobian matrix switch.
static constexpr Switches CtxSetX
Solution vector switch.
static constexpr Switches CtxSetNone
No data switch.
static constexpr Switches CtxSetF
Residual vector switch.
static constexpr Switches CtxSetB
Preconditioner matrix switch.
@ CTX_SNESSETJACOBIAN
Setting up Jacobian matrix computation.
@ CTX_SNESSETFUNCTION
Setting up nonlinear function evaluation.
@ CTX_SNESNONE
No specific SNES context.
Interface for TAO solvers.
Definition TaoCtx.hpp:14
MoFEMErrorCode copyLoops(const TaoCtx &tao_ctx)
Copy sequences from another TaoCtx.
Definition TaoCtx.cpp:9
boost::movelib::unique_ptr< bool > vecAssembleSwitch
Definition TaoCtx.hpp:105
MoFEM::Interface & mField
database Interface
Definition TaoCtx.hpp:16
BasicMethodsSequence postObjective
Sequence of methods run after objective is evaluated.
Definition TaoCtx.hpp:43
PetscLogEvent MOFEM_EVENT_TaoGradient
Log event for TAO Gradient.
Definition TaoCtx.hpp:110
std::string problemName
problem name
Definition TaoCtx.hpp:18
BasicMethodsSequence postGradient
Sequence of methods run after gradient is assembled.
Definition TaoCtx.hpp:48
PetscLogEvent MOFEM_EVENT_TaoHessian
Log event for TAO Hessian.
Definition TaoCtx.hpp:109
boost::movelib::unique_ptr< bool > matAssembleSwitch
Definition TaoCtx.hpp:106
BasicMethodsSequence preObjective
Sequence of methods run before objective is evaluated.
Definition TaoCtx.hpp:41
FEMethodsSequence loopsObjective
Definition TaoCtx.hpp:29
BasicMethodsSequence preGradient
Sequence of methods run before gradient is assembled.
Definition TaoCtx.hpp:46
PetscLogEvent MOFEM_EVENT_TaoObjective
Log event for TAO Objective.
Definition TaoCtx.hpp:111
MoFEMErrorCode clearLoops()
Clear loops.
Definition TaoCtx.cpp:23
BasicMethodsSequence postHessian
Sequence of methods run after Hessian is assembled.
Definition TaoCtx.hpp:38
BasicMethodsSequence preHessian
Sequence of methods run before Hessian is assembled.
Definition TaoCtx.hpp:36
FEMethodsSequence loopsGradient
Definition TaoCtx.hpp:32
FEMethodsSequence loopsHessian
Definition TaoCtx.hpp:26
@ CTX_TAO_HESSIAN
Assembling Hessian matrix.
@ CTX_TAO_NONE
No specific TAO context.
@ CTX_TAO_GRADIENT
Computing gradient vector.
@ CTX_TAO_OBJECTIVE
Evaluating objective function.
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.
Vector manager is used to create vectors \mofem_vectors.
double H
Hardening.
Definition plastic.cpp:128