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
double H
Hardening.
Definition plastic.cpp:128
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.
static constexpr Switches CtxSetA
static constexpr Switches CtxSetX
static constexpr Switches CtxSetNone
static constexpr Switches CtxSetF
static constexpr Switches CtxSetB
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
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.
Vector manager is used to create vectors \mofem_vectors.