v0.15.5
Loading...
Searching...
No Matches
EshelbianTopologicalDerivative.cpp
Go to the documentation of this file.
1/**
2 * @file EshelbianTopologicalDerivative.cpp
3 * @author your name (you@domain.com)
4 * @brief
5 * @version 0.1
6 * @date 2026-02-21
7 *
8 * @copyright Copyright (c) 2026
9 *
10 */
11
12#define SINGULARITY
13#include <MoFEM.hpp>
14using namespace MoFEM;
15
17#include <EshelbianAux.hpp>
18#include <TSElasticPostStep.hpp>
19
20#include <boost/math/constants/constants.hpp>
22
25
26using namespace EshelbianPlasticity;
27using namespace ShapeOptimization;
28
29namespace EshelbianPlasticity {
30
33 EshelbianCore *ep,
34 ForcesAndSourcesCore::GaussHookFun set_integration_at_interior,
35 ForcesAndSourcesCore::GaussHookFun set_integration_at_face,
36 SmartPetscObj<TS> time_solver)
37 : ep_ptr(ep), integrationAtInterior(set_integration_at_interior),
38 integrationAtFace(set_integration_at_face), timeSolver(time_solver) {
39
42 }
43
44private:
49
50 friend MoFEMErrorCode
52
53 friend MoFEMErrorCode
55
56 friend MoFEMErrorCode
57 evaluateGradientImpl(TopologicalTAOCtxImpl *ctx_impl_ptr, double *f, Vec g);
58
59 friend MoFEMErrorCode
61 double *f, Vec g, double epsilon);
62
63 friend MoFEMErrorCode
64 topologicalEvaluateObjectiveAndGradient(Tao tao, Vec sol, PetscReal *f, Vec g,
65 void *ctx);
66
68 Vec sol, PetscReal *f,
69 Vec g);
70
73};
74
75boost::shared_ptr<TopologicalTAOCtx> createTopologicalTAOCtx(
76 EshelbianCore *ep,
77 ForcesAndSourcesCore::GaussHookFun set_integration_at_interior,
78 ForcesAndSourcesCore::GaussHookFun set_integration_at_face,
79 SmartPetscObj<TS> time_solver) {
80 return boost::make_shared<TopologicalTAOCtxImpl>(
81 ep, set_integration_at_interior, set_integration_at_face, time_solver);
82}
83}
84
87
88namespace EshelbianPlasticity {
89
93 auto &ep = *ctx_impl_ptr->ep_ptr;
94 auto ts = ctx_impl_ptr->timeSolver;
95
96 CHKERR VecGhostUpdateBegin(ctx_impl_ptr->primalProblemVec, INSERT_VALUES,
97 SCATTER_FORWARD);
98 CHKERR VecGhostUpdateEnd(ctx_impl_ptr->primalProblemVec, INSERT_VALUES,
99 SCATTER_FORWARD);
100 CHKERR DMoFEMMeshToLocalVector(ep.dmElastic, ctx_impl_ptr->primalProblemVec,
101 INSERT_VALUES, SCATTER_FORWARD,
103
104 CHKERR TSSetFromOptions(ts);
105 CHKERR TSSetStepNumber(ts, 0);
106 CHKERR TSSetTime(ts, 0);
107 CHKERR TSSetSolution(ts, ctx_impl_ptr->primalProblemVec);
108 double dt;
109 CHKERR TSGetTimeStep(ts, &dt);
110 MOFEM_LOG("EP", Sev::inform)
111 << "evaluatePrimalProblemTopologicalImpl: Time step dt: " << dt;
112 CHKERR TSSolve(ts, PETSC_NULLPTR);
113 CHKERR TSSetTimeStep(ts, dt);
114
115
117}
118
121 auto &ep = *ctx_impl_ptr->ep_ptr;
122 auto &m_field = ep.mField;
123 auto interior_integration_hook = ctx_impl_ptr->integrationAtInterior;
124 auto boundary_integration_hook = ctx_impl_ptr->integrationAtFace;
125
126 auto fe_spatial =
127 boost::make_shared<VolumeElementForcesAndSourcesCore>(m_field);
128 auto dJ_dx_vec = pushTopologicalSpatialOps(
129 ep, fe_spatial, interior_integration_hook, boundary_integration_hook);
130 CHKERR DMoFEMLoopFiniteElements(ep.dmElastic, ep.elementVolumeName,
131 fe_spatial);
132 CHKERR VecAssemblyBegin(dJ_dx_vec);
133 CHKERR VecAssemblyEnd(dJ_dx_vec);
134 CHKERR VecGhostUpdateBegin(dJ_dx_vec, ADD_VALUES, SCATTER_REVERSE);
135 CHKERR VecGhostUpdateEnd(dJ_dx_vec, ADD_VALUES, SCATTER_REVERSE);
136 CHKERR VecGhostUpdateBegin(dJ_dx_vec, INSERT_VALUES, SCATTER_FORWARD);
137 CHKERR VecGhostUpdateEnd(dJ_dx_vec, INSERT_VALUES, SCATTER_FORWARD);
138
139 auto ksp = snesGetKSP(tsGetSNES(ctx_impl_ptr->timeSolver));
140 CHKERR KSPSolveTranspose(ksp, dJ_dx_vec, ctx_impl_ptr->adjointProblemVec);
141 CHKERR VecGhostUpdateBegin(ctx_impl_ptr->adjointProblemVec, INSERT_VALUES,
142 SCATTER_FORWARD);
143 CHKERR VecGhostUpdateEnd(ctx_impl_ptr->adjointProblemVec, INSERT_VALUES,
144 SCATTER_FORWARD);
145
147}
148
150 double *f, Vec g) {
152 auto &ep = *ctx_impl_ptr->ep_ptr;
153 auto &m_field = ep.mField;
154 auto interior_integration_hook = ctx_impl_ptr->integrationAtInterior;
155 auto boundary_integration_hook = ctx_impl_ptr->integrationAtFace;
156
157 auto fe_material =
158 boost::make_shared<VolumeElementForcesAndSourcesCore>(m_field);
159 auto fe_adjoint =
160 boost::make_shared<VolumeElementForcesAndSourcesCore>(m_field);
161
162 boost::shared_ptr<double> J_ptr(fe_material, f);
163 auto dJ_dX_vec = SmartPetscObj<Vec>(g, true);
164 CHKERR VecZeroEntries(dJ_dX_vec);
165 CHKERR VecGhostUpdateBegin(dJ_dX_vec, INSERT_VALUES, SCATTER_FORWARD);
166 CHKERR VecGhostUpdateEnd(dJ_dX_vec, INSERT_VALUES, SCATTER_FORWARD);
167
168 CHKERR pushTopologicalMaterialOps(ep, fe_material, interior_integration_hook,
169 boundary_integration_hook, J_ptr,
170 dJ_dX_vec);
171 auto alpha = ep.alphaW;
172 auto rho = ep.alphaRho;
173 auto alpha_omega = ep.alphaOmega;
175 ep, fe_adjoint, interior_integration_hook, boundary_integration_hook,
176 ctx_impl_ptr->adjointProblemVec, dJ_dX_vec, alpha, rho, alpha_omega);
177
178 CHKERR DMoFEMLoopFiniteElements(ep.dmMaterial, ep.elementVolumeName,
179 fe_material);
180 CHKERR DMoFEMLoopFiniteElements(ep.dmMaterial, ep.elementVolumeName,
181 fe_adjoint);
182 CHKERR VecAssemblyBegin(dJ_dX_vec);
183 CHKERR VecAssemblyEnd(dJ_dX_vec);
184 CHKERR VecGhostUpdateBegin(dJ_dX_vec, ADD_VALUES, SCATTER_REVERSE);
185 CHKERR VecGhostUpdateEnd(dJ_dX_vec, ADD_VALUES, SCATTER_REVERSE);
186 CHKERR VecGhostUpdateBegin(dJ_dX_vec, INSERT_VALUES, SCATTER_FORWARD);
187 CHKERR VecGhostUpdateEnd(dJ_dX_vec, INSERT_VALUES, SCATTER_FORWARD);
188
190}
191
193 Vec sol, double *f, Vec g,
194 double epsilon) {
196
197 auto &ep = *ctx_impl_ptr->ep_ptr;
198 auto &m_field = ep.mField;
199 auto interior_integration_hook = ctx_impl_ptr->integrationAtInterior;
200 auto boundary_integration_hook = ctx_impl_ptr->integrationAtFace;
201
202 auto fe_material =
203 boost::make_shared<VolumeElementForcesAndSourcesCore>(m_field);
204 auto J_ptr = boost::make_shared<double>(0);
205 CHKERR pushTopologicalMaterialOps(ep, fe_material, interior_integration_hook,
206 boundary_integration_hook, J_ptr,
208
209 auto opt = ep.mField.getInterface<OperatorsTester>();
210 constexpr double eps = 1e-6;
211 auto random_vec = opt->setRandomFields(
212 ep.dmMaterial, {{ep.materialH1Positions, {-eps, eps}}}, nullptr,
214 auto a_vec = vectorDuplicate(random_vec);
215 CHKERR VecCopy(sol, a_vec);
216 CHKERR VecAXPY(a_vec, 1, random_vec);
217 auto b_vec = vectorDuplicate(random_vec);
218 CHKERR VecCopy(sol, b_vec);
219 CHKERR VecAXPY(b_vec, -1, random_vec);
220
221 *J_ptr = 0;
222 CHKERR VecGhostUpdateBegin(a_vec, INSERT_VALUES, SCATTER_FORWARD);
223 CHKERR VecGhostUpdateEnd(a_vec, INSERT_VALUES, SCATTER_FORWARD);
224 CHKERR DMoFEMMeshToLocalVector(ep.dmMaterial, a_vec, INSERT_VALUES,
225 SCATTER_REVERSE, RowColData::ROW);
226 CHKERR DMoFEMLoopFiniteElements(ep.dmMaterial, ep.elementVolumeName,
227 fe_material);
228 double J_plus = *J_ptr;
229 *J_ptr = 0;
230 CHKERR VecGhostUpdateBegin(b_vec, INSERT_VALUES, SCATTER_FORWARD);
231 CHKERR VecGhostUpdateEnd(b_vec, INSERT_VALUES, SCATTER_FORWARD);
232 CHKERR DMoFEMMeshToLocalVector(ep.dmMaterial, b_vec, INSERT_VALUES,
233 SCATTER_REVERSE, RowColData::ROW);
234 CHKERR DMoFEMLoopFiniteElements(ep.dmMaterial, ep.elementVolumeName,
235 fe_material);
236 double J_minus = *J_ptr;
237 double dJ_da = (J_plus - J_minus) / (2 * eps);
238
239 double exact_dJ;
240 CHKERR VecDot(g, random_vec, &exact_dJ);
241 double error = std::abs(dJ_da - exact_dJ);
242
243 MOFEM_LOG("EP", Sev::inform)
244 << "J = " << *f << ", dJ/da = " << dJ_da << ", exact dJ/da = " << exact_dJ
245 << ", error = " << error;
246
247 CHKERR VecGhostUpdateBegin(sol, INSERT_VALUES, SCATTER_FORWARD);
248 CHKERR VecGhostUpdateEnd(sol, INSERT_VALUES, SCATTER_FORWARD);
249 CHKERR DMoFEMMeshToLocalVector(ep.dmMaterial, sol, INSERT_VALUES,
250 SCATTER_REVERSE, RowColData::ROW);
251
253}
254
256 PetscReal *f, Vec g) {
257
259 auto *ctx_impl_ptr = dynamic_cast<TopologicalTAOCtxImpl *>(ctx_ptr);
260 if (!ctx_impl_ptr)
261 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
262 "Invalid context pointer type");
263 auto &ep = *ctx_impl_ptr->ep_ptr;
264
265 CHKERR VecGhostUpdateBegin(sol, INSERT_VALUES, SCATTER_FORWARD);
266 CHKERR VecGhostUpdateEnd(sol, INSERT_VALUES, SCATTER_FORWARD);
267 CHKERR DMoFEMMeshToLocalVector(ep.dmMaterial, sol, INSERT_VALUES,
268 SCATTER_REVERSE, RowColData::ROW);
269
270 CHKERR VecZeroEntries(g);
271 *f = 0;
272
274 double norm2_x;
275 CHKERR VecNorm(ctx_impl_ptr->primalProblemVec, NORM_2, &norm2_x);
276 MOFEM_LOG("EP", Sev::inform)
277 << "evaluatePrimalProblemTopologicalImpl: Norm of displacement vector: "
278 << norm2_x;
279 if (norm2_x < 1e-12) {
281 }
282
284 CHKERR evaluateGradientImpl(ctx_impl_ptr, f, g);
285
286 CHKERR finiteDifferenceGradientTest(ctx_impl_ptr, sol, f, g, 1e-6);
287
289}
290
292 PetscReal *f, Vec g,
293 void *ctx) {
294
296// auto *ctx_impl_ptr = static_cast<TopologicalTAOCtxImpl *>(ctx);
297// if (!ctx_impl_ptr)
298// SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
299// "Invalid context pointer type");
300// auto &ep = *ctx_impl_ptr->ep_ptr;
301// auto &m_field = ep.mField;
302// auto interior_integration_hook = ctx_impl_ptr->integrationAtInterior;
303// auto boundary_integration_hook = ctx_impl_ptr->integrationAtFace;
304// auto alpha = ep.alphaW;
305// auto rho = ep.alphaRho;
306// auto alpha_omega = ep.alphaOmega;
307
308
310}
311}
Auxilary functions for Eshelbian plasticity.
Eshelbian plasticity interface.
Interface for Python-based objective function evaluation in topology optimization.
static const double eps
@ COL
@ ROW
#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 ...
@ MOFEM_DATA_INCONSISTENCY
Definition definitions.h:31
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
PetscErrorCode DMoFEMMeshToLocalVector(DM dm, Vec l, InsertMode mode, ScatterMode scatter_mode, RowColData rc=RowColData::COL)
set local (or ghosted) vector values on mesh for partition only
Definition DMMoFEM.cpp:514
PetscErrorCode DMoFEMLoopFiniteElements(DM dm, const char fe_name[], MoFEM::FEMethod *method, CacheTupleWeakPtr cache_ptr=CacheTupleSharedPtr())
Executes FEMethod for finite elements in DM.
Definition DMMoFEM.cpp:576
auto createDMVector(DM dm, RowColData rc=RowColData::COL)
Get smart vector from DM.
Definition DMMoFEM.hpp:1237
#define MOFEM_LOG(channel, severity)
Log.
double dt
MoFEMErrorCode evaluateGradientImpl(TopologicalTAOCtxImpl *ctx_impl_ptr, double *f, Vec g)
boost::shared_ptr< TopologicalTAOCtx > createTopologicalTAOCtx(EshelbianCore *ep, ForcesAndSourcesCore::GaussHookFun set_integration_at_interior, ForcesAndSourcesCore::GaussHookFun set_integration_at_face, SmartPetscObj< TS > time_solver)
MoFEMErrorCode pushTopologicalOps_dJ_adjoint_gradient(EshelbianCore &ep, boost::shared_ptr< VolumeElementForcesAndSourcesCore > fe, ForcesAndSourcesCore::GaussHookFun interior_integration_hook, ForcesAndSourcesCore::GaussHookFun boundary_integration_hook, SmartPetscObj< Vec > lambda_vec, SmartPetscObj< Vec > dJ_dX_vec, const double alpha, const double rho, const double alpha_omega)
MoFEMErrorCode evaluatePrimalProblemTopologicalImpl(TopologicalTAOCtxImpl *ctx_impl_ptr)
MoFEMErrorCode pushTopologicalMaterialOps(EshelbianCore &ep, boost::shared_ptr< VolumeElementForcesAndSourcesCore > fe, ForcesAndSourcesCore::GaussHookFun interior_integration_hook, ForcesAndSourcesCore::GaussHookFun boundary_integration_hook, boost::shared_ptr< double > J_ptr, SmartPetscObj< Vec > dJ_dX_vec)
MoFEMErrorCode finiteDifferenceGradientTest(TopologicalTAOCtxImpl *ctx_impl_ptr, Vec sol, double *f, Vec g, double epsilon)
SmartPetscObj< Vec > pushTopologicalSpatialOps(EshelbianCore &ep, boost::shared_ptr< VolumeElementForcesAndSourcesCore > fe, ForcesAndSourcesCore::GaussHookFun interior_integration_hook, ForcesAndSourcesCore::GaussHookFun boundary_integration_hook)
MoFEMErrorCode testTopologicalDerivative(TopologicalTAOCtx *ctx_ptr, Vec sol, PetscReal *f, Vec g)
MoFEMErrorCode topologicalEvaluateObjectiveAndGradient(Tao tao, Vec sol, PetscReal *f, Vec g, void *ctx)
MoFEMErrorCode evaluateAdjointProblemImpl(TopologicalTAOCtxImpl *ctx_impl_ptr)
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
implementation of Data Operators for Forces and Sources
Definition Common.hpp:10
auto snesGetKSP(SNES snes)
auto tsGetSNES(TS ts)
SmartPetscObj< Vec > vectorDuplicate(Vec vec)
Create duplicate vector of smart vector.
constexpr double g
MoFEM::Interface & mField
SmartPetscObj< DM > dmElastic
Elastic problem.
friend MoFEMErrorCode topologicalEvaluateObjectiveAndGradient(Tao tao, Vec sol, PetscReal *f, Vec g, void *ctx)
friend MoFEMErrorCode testTopologicalDerivative(TopologicalTAOCtx *ctx_ptr, Vec sol, PetscReal *f, Vec g)
friend MoFEMErrorCode evaluatePrimalProblemTopologicalImpl(TopologicalTAOCtxImpl *ctx_impl_ptr)
friend MoFEMErrorCode evaluateGradientImpl(TopologicalTAOCtxImpl *ctx_impl_ptr, double *f, Vec g)
friend MoFEMErrorCode finiteDifferenceGradientTest(TopologicalTAOCtxImpl *ctx_impl_ptr, Vec sol, double *f, Vec g, double epsilon)
TopologicalTAOCtxImpl(EshelbianCore *ep, ForcesAndSourcesCore::GaussHookFun set_integration_at_interior, ForcesAndSourcesCore::GaussHookFun set_integration_at_face, SmartPetscObj< TS > time_solver)
friend MoFEMErrorCode evaluateAdjointProblemImpl(TopologicalTAOCtxImpl *ctx_impl_ptr)
boost::function< MoFEMErrorCode(ForcesAndSourcesCore *fe_raw_ptr, int order_row, int order_col, int order_data)> GaussHookFun
Calculate directional derivative of the right hand side and compare it with tangent matrix derivative...
intrusive_ptr for managing petsc objects
double rho
Definition plastic.cpp:144