v0.15.5
Loading...
Searching...
No Matches
EshelbianTopologicalDerivativePush.cpp
Go to the documentation of this file.
1/**
2 * @file EshelbianTopologicalPush.cpp
3 * @author your name (you@domain.com)
4 * @brief
5 * @version 0.1
6 * @date 2026-02-25
7 *
8 * @copyright Copyright (c) 2026
9 *
10 */
11
12namespace EshelbianPlasticity {
13
15 EshelbianCore &ep, boost::shared_ptr<VolumeElementForcesAndSourcesCore> fe,
16 ForcesAndSourcesCore::GaussHookFun interior_integration_hook,
17 SmartPetscObj<Vec> lambda_vec = SmartPetscObj<Vec>()) {
18
19 auto data_at_pts_ptr = boost::make_shared<DataAtIntegrationPts>();
20
21 auto bubble_cache =
22 boost::make_shared<CGGUserPolynomialBase::CachePhi>(0, 0, MatrixDouble());
23 fe->getUserPolynomialBase() =
24 boost::make_shared<CGGUserPolynomialBase>(bubble_cache);
25 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
26 fe->getOpPtrVector(), {HDIV, H1, L2}, ep.materialH1Positions,
27 ep.frontAdjEdges);
28
29 // set integration rule
30 fe->getRuleHook = [](int, int, int) { return -1; };
31 fe->setRuleHook = interior_integration_hook;
32
33 // calculate fields values
34 fe->getOpPtrVector().push_back(new OpCalculateHVecTensorField<3, 3>(
35 ep.piolaStress, data_at_pts_ptr->getApproxPAtPts()));
36 fe->getOpPtrVector().push_back(new OpCalculateHTensorTensorField<3, 3>(
37 ep.bubbleField, data_at_pts_ptr->getApproxPAtPts(), MBMAXTYPE));
38 fe->getOpPtrVector().push_back(new OpCalculateHVecTensorDivergence<3, 3>(
39 ep.piolaStress, data_at_pts_ptr->getDivPAtPts()));
40
41 if (ep.noStretch) {
42 fe->getOpPtrVector().push_back(
43 ep.physicalEquations->returnOpCalculateStretchFromStress(
44 data_at_pts_ptr, ep.physicalEquations));
45 } else {
46 fe->getOpPtrVector().push_back(
47 new OpCalculateTensor2SymmetricFieldValues<3>(
48 ep.stretchTensor, data_at_pts_ptr->getLogStretchTensorAtPts(),
49 MBTET));
50 }
51
52 fe->getOpPtrVector().push_back(new OpCalculateVectorFieldValues<3>(
53 ep.rotAxis, data_at_pts_ptr->getRotAxisAtPts(), MBTET));
54 fe->getOpPtrVector().push_back(new OpCalculateVectorFieldValues<3>(
55 ep.spatialL2Disp, data_at_pts_ptr->getSmallWL2AtPts(), MBTET));
56
57 // H1 displacements
58 fe->getOpPtrVector().push_back(new OpCalculateVectorFieldValues<3>(
59 ep.spatialH1Disp, data_at_pts_ptr->getSmallWH1AtPts()));
60 fe->getOpPtrVector().push_back(new OpCalculateVectorFieldGradient<3, 3>(
61 ep.spatialH1Disp, data_at_pts_ptr->getSmallWGradH1AtPts()));
62
63 if (lambda_vec) {
64 fe->getOpPtrVector().push_back(
65 new OpCalculateHVecTensorField<SPACE_DIM, SPACE_DIM>(
66 ep.piolaStress, data_at_pts_ptr->getVarPiolaPts(), nullptr,
67 lambda_vec));
68 fe->getOpPtrVector().push_back(new OpCalculateHTensorTensorField<3, 3>(
69 ep.bubbleField, data_at_pts_ptr->getVarPiolaPts(), nullptr, lambda_vec,
70 MBMAXTYPE));
71 fe->getOpPtrVector().push_back(new OpCalculateHVecTensorDivergence<3, 3>(
72 ep.piolaStress, data_at_pts_ptr->getDivVarPiolaPts(), lambda_vec));
73
74 fe->getOpPtrVector().push_back(new OpCalculateVectorFieldValues<3>(
75 ep.spatialL2Disp, data_at_pts_ptr->getVarWL2Pts(), lambda_vec, MBTET));
76 fe->getOpPtrVector().push_back(new OpCalculateVectorFieldValues<3>(
77 ep.rotAxis, data_at_pts_ptr->getVarRotAxisPts(), lambda_vec, MBTET));
78 fe->getOpPtrVector().push_back(new OpCalculateVectorFieldGradient<3, 3>(
79 ep.rotAxis, data_at_pts_ptr->getVarGradRotAxisPts(), lambda_vec, MBTET));
80
81 if (ep.noStretch) {
82 fe->getOpPtrVector().push_back(
83 ep.physicalEquations->returnOpCalculateVarStretchFromStress(
84 data_at_pts_ptr, ep.physicalEquations));
85 } else {
86 fe->getOpPtrVector().push_back(
87 new OpCalculateTensor2SymmetricFieldValues<3>(
88 ep.stretchTensor, data_at_pts_ptr->getVarLogStreachPts(),
89 lambda_vec, MBTET));
90 }
91 }
92
93 return data_at_pts_ptr;
94}
95
97 EshelbianCore &ep, const std::string &fe_name,
98 boost::shared_ptr<VolumeElementForcesAndSourcesCore> fe,
99 ForcesAndSourcesCore::GaussHookFun boundary_integration_hook) {
100
101 auto &m_field = ep.mField;
102
103 using BoundaryEle =
104 PipelineManager::ElementsAndOpsByDim<SPACE_DIM>::BoundaryEle;
105 using EleOnSide =
106 PipelineManager::ElementsAndOpsByDim<SPACE_DIM>::FaceSideEle;
107 using SideEleOp = EleOnSide::UserDataOperator;
108 using BdyEleOp = BoundaryEle::UserDataOperator;
109
110 // First: Iterate over skeleton FEs adjacent to Domain FEs
111 // Note: BoundaryEle, i.e. uses skeleton interation rule
112 auto op_loop_skeleton_side =
113 new OpLoopSide<BoundaryEle>(m_field, fe_name, SPACE_DIM - 1, Sev::noisy);
114 op_loop_skeleton_side->getSideFEPtr()->getRuleHook = [](int, int, int) {
115 return -1;
116 };
117 op_loop_skeleton_side->getSideFEPtr()->setRuleHook =
118 boundary_integration_hook;
119
120 CHKERR
121 EshelbianPlasticity::AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
122 op_loop_skeleton_side->getOpPtrVector(), {L2}, ep.materialH1Positions,
123 ep.frontAdjEdges);
124
125 // Second: Iterate over domain FEs adjacent to skelton, particularly one
126 // domain element.
127 auto broken_data_ptr = boost::make_shared<std::vector<BrokenBaseSideData>>();
128 // Note: EleOnSide, i.e. uses on domain projected skeleton rule
129 auto op_loop_domain_side = new OpBrokenLoopSide<EleOnSide>(
130 m_field, ep.elementVolumeName, SPACE_DIM, Sev::noisy);
131 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
132 boost::make_shared<CGGUserPolynomialBase>();
133 CHKERR
134 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
135 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
137 op_loop_domain_side->getOpPtrVector().push_back(
138 new OpGetBrokenBaseSideData<SideEleOp>(ep.piolaStress, broken_data_ptr));
139 auto flux_mat_ptr = boost::make_shared<MatrixDouble>();
140 op_loop_domain_side->getOpPtrVector().push_back(
141 new OpCalculateHVecTensorField<SPACE_DIM, SPACE_DIM>(ep.piolaStress,
142 flux_mat_ptr));
143 op_loop_domain_side->getOpPtrVector().push_back(
144 new OpSetFlux<SideEleOp>(broken_data_ptr, flux_mat_ptr));
145 op_loop_skeleton_side->getOpPtrVector().push_back(op_loop_domain_side);
146
147 return std::make_tuple(op_loop_skeleton_side,
148 op_loop_domain_side->getSideFEPtr(), broken_data_ptr);
149}
150
152 EshelbianCore &ep, boost::shared_ptr<ForcesAndSourcesCore> fe,
153 boost::shared_ptr<DataAtIntegrationPts> data_at_pts_ptr,
154 boost::shared_ptr<TopologicalData> topo_ptr) {
155
156 auto dJ_dx_vec = createDMVector(ep.dmElastic);
157
158 fe->getOpPtrVector().push_back(
159 new OpJ_dPImpl(ep.piolaStress, data_at_pts_ptr, topo_ptr, nullptr,
160 dJ_dx_vec, Tag()));
161 fe->getOpPtrVector().push_back(new OpJ_dBubbleImpl(
162 ep.bubbleField, data_at_pts_ptr, topo_ptr, nullptr, dJ_dx_vec, Tag()));
164 fe->getOpPtrVector().push_back(new OpJ_dP_no_streachImpl(
165 ep.piolaStress, data_at_pts_ptr, topo_ptr, nullptr, dJ_dx_vec,
166 Tag()));
167 fe->getOpPtrVector().push_back(new OpJ_dBubble_no_streachImpl(
168 ep.bubbleField, data_at_pts_ptr, topo_ptr, nullptr, dJ_dx_vec,
169 Tag()));
170 } else {
171 fe->getOpPtrVector().push_back(new OpJ_dUImpl(
172 ep.stretchTensor, data_at_pts_ptr, topo_ptr, nullptr, dJ_dx_vec,
173 Tag()));
174 }
175 fe->getOpPtrVector().push_back(
176 new OpJ_dwImpl(ep.spatialL2Disp, data_at_pts_ptr, topo_ptr, nullptr,
177 dJ_dx_vec, Tag()));
178
179 return dJ_dx_vec;
180}
181
183 EshelbianCore &ep, boost::shared_ptr<ForcesAndSourcesCore> fe,
184 boost::shared_ptr<std::vector<BrokenBaseSideData>> broken_data_ptr,
185 boost::shared_ptr<DataAtIntegrationPts> data_at_pts_ptr,
186 boost::shared_ptr<TopologicalData> topo_ptr, SmartPetscObj<Vec> dJ_dx_vec) {
188 // fe->getOpPtrVector().push_back(new dJ_duGammaImpl(
189 // ep.hybridSpatialDisp, data_at_pts_ptr, topo_ptr, nullptr, dJ_dx_vec));
190 // fe->getOpPtrVector().push_back(
191 // new dJ_dTractionImpl(broken_data_ptr, topo_ptr, nullptr, dJ_dx_vec));
193}
194
195SmartPetscObj<Vec> pushTopologicalSpatialOps(
196 EshelbianCore &ep, boost::shared_ptr<VolumeElementForcesAndSourcesCore> fe,
197 ForcesAndSourcesCore::GaussHookFun interior_integration_hook,
198 ForcesAndSourcesCore::GaussHookFun boundary_integration_hook) {
199
200 auto data_at_pts_ptr =
201 pushInteriorTopologicalOpsImpl(ep, fe, interior_integration_hook);
202 auto [op_skeleton_side, domain_side_fe_ptr, broken_data_ptr] =
204 boundary_integration_hook);
205 fe->getOpPtrVector().push_back(op_skeleton_side);
206
207 auto topo_ptr = boost::make_shared<TopologicalData>();
208 char objective_function_file_name[255] = "objective_function.py";
209 CHKERR PetscOptionsGetString(
210 PETSC_NULLPTR, PETSC_NULLPTR, "-objective_function",
211 objective_function_file_name, 255, PETSC_NULLPTR);
212 auto python_ptr =
213 create_python_objective_function(objective_function_file_name);
214 fe->getOpPtrVector().push_back(new OpTopologicalObjectivePythonImpl(
215 data_at_pts_ptr, topo_ptr, python_ptr));
216
217 auto dJ_dx_vec =
218 pushInteriorTopological_dJ_dx_Impl(ep, fe, data_at_pts_ptr, topo_ptr);
219
220 // Assume for now that we do not have boundary contributions to dJ/dx. We add
221 // this once interior contributions are working and verified, and once we have
222 // a test case with non-zero boundary contribution.
223 // CHKERR pushBoundaryTopological_dJ_dx_Impl(
224 // ep, fe, broken_data_ptr, data_at_pts_ptr, topo_ptr, dJ_dx_vec);
225
226 return dJ_dx_vec;
227}
228
230 EshelbianCore &ep, boost::shared_ptr<VolumeElementForcesAndSourcesCore> fe,
231 ForcesAndSourcesCore::GaussHookFun interior_integration_hook,
232 ForcesAndSourcesCore::GaussHookFun boundary_integration_hook,
233 boost::shared_ptr<double> J_ptr, Tag th_grad_tag) {
235
236 auto data_at_pts_ptr =
237 pushInteriorTopologicalOpsImpl(ep, fe, interior_integration_hook);
238 auto [op_skeleton_side, domain_side_fe_ptr, broken_data_ptr] =
240 boundary_integration_hook);
241 fe->getOpPtrVector().push_back(op_skeleton_side);
242
243 auto topo_ptr = boost::make_shared<TopologicalData>();
244 char objective_function_file_name[255] = "objective_function.py";
245 CHKERR PetscOptionsGetString(
246 PETSC_NULLPTR, PETSC_NULLPTR, "-objective_function",
247 objective_function_file_name, 255, PETSC_NULLPTR);
248 auto python_ptr =
249 create_python_objective_function(objective_function_file_name);
250 fe->getOpPtrVector().push_back(new OpTopologicalObjectivePythonImpl(
251 data_at_pts_ptr, topo_ptr, python_ptr));
252 fe->getOpPtrVector().push_back(
253 new OpInteriorJImpl(ep.materialH1Positions, data_at_pts_ptr, topo_ptr,
254 J_ptr, SmartPetscObj<Vec>(), th_grad_tag));
256}
257
259 EshelbianCore &ep, boost::shared_ptr<VolumeElementForcesAndSourcesCore> fe,
260 ForcesAndSourcesCore::GaussHookFun interior_integration_hook,
261 ForcesAndSourcesCore::GaussHookFun boundary_integration_hook,
262 SmartPetscObj<Vec> lambda_vec, Tag th_grad_tag,
263 const double alpha, const double rho, const double alpha_omega) {
264
266
267 auto data_at_pts_ptr = pushInteriorTopologicalOpsImpl(
268 ep, fe, interior_integration_hook, lambda_vec);
269
270 auto add_hybridised_dJ_gradient = [&](auto fe_ptr) {
272 using BoundaryEle =
273 PipelineManager::ElementsAndOpsByDim<SPACE_DIM>::BoundaryEle;
274 using BdyEleOp = BoundaryEle::UserDataOperator;
275
276 auto [op_skeleton_side, domain_side_fe_ptr, broken_data_ptr] =
278 boundary_integration_hook);
279 domain_side_fe_ptr->getOpPtrVector().push_back(
280 new OpCalculateHVecTensorField<SPACE_DIM, SPACE_DIM>(
281 ep.piolaStress, data_at_pts_ptr->getVarPiolaPts(), nullptr,
282 lambda_vec));
283 op_skeleton_side->getOpPtrVector().push_back(
284 new OpCalculateVectorFieldValues<SPACE_DIM>(
285 ep.hybridSpatialDisp, data_at_pts_ptr->getVarHybridDispAtPts(),
286 lambda_vec));
287 op_skeleton_side->getOpPtrVector().push_back(
288 new OpCalculateVectorFieldValues<SPACE_DIM>(
289 ep.hybridSpatialDisp, data_at_pts_ptr->getHybridDispAtPts()));
290 auto topo_ptr = boost::make_shared<TopologicalData>();
291 op_skeleton_side->getOpPtrVector().push_back(new OpGetHONormalsOnFace(
292 ep.materialH1Positions, topo_ptr->getTangent1AtPts(),
293 topo_ptr->getTangent2AtPts(), topo_ptr->getNormalAtPts()));
294
295 using OpTopoC_dHybrid = FormsIntegrators<BdyEleOp>::Assembly<A>::LinearForm<
296 GAUSS>::OpTopoDerivativeBrokenSpaceConstrainDHybrid<SPACE_DIM>;
297 using OpTopoC_dBroken = FormsIntegrators<BdyEleOp>::Assembly<A>::LinearForm<
298 GAUSS>::OpTopoDerivativeBrokenSpaceConstrainDFlux<SPACE_DIM>;
299 op_skeleton_side->getOpPtrVector().push_back(new OpTopoC_dHybrid(
300 ep.hybridSpatialDisp, broken_data_ptr,
301 data_at_pts_ptr->getVarHybridDispAtPts(), topo_ptr->getTangent1AtPts(),
302 topo_ptr->getTangent2AtPts(), boost::make_shared<double>(1.0),
303 SmartPetscObj<Vec>(), th_grad_tag));
304 op_skeleton_side->getOpPtrVector().push_back(new OpTopoC_dBroken(
305 broken_data_ptr, data_at_pts_ptr->getHybridDispAtPts(),
306 data_at_pts_ptr->getVarHybridDispAtPts(), topo_ptr->getTangent1AtPts(),
307 topo_ptr->getTangent2AtPts(), boost::make_shared<double>(1.0),
308 SmartPetscObj<Vec>(), th_grad_tag));
309
310 fe_ptr->getOpPtrVector().push_back(op_skeleton_side);
312 };
313
314 CHK_THROW_MESSAGE(add_hybridised_dJ_gradient(fe),
315 "Failed to add hybridised dJ/dx gradient operators");
316
317 auto topo_ptr = boost::make_shared<TopologicalData>();
318 fe->getOpPtrVector().push_back(new OpCalculateVectorFieldGradient<3, 3>(
319 ep.materialH1Positions, topo_ptr->getJacobianAtPts()));
320 fe->getOpPtrVector().push_back(new OpInvertMatrix<3>(
321 topo_ptr->getJacobianAtPts(), topo_ptr->getDetJacobianAtPts(),
322 topo_ptr->getInvJacobianAtPts()));
323 fe->getOpPtrVector().push_back(new OpSensitivityInteriorGradient(
324 ep.materialH1Positions, data_at_pts_ptr, topo_ptr, th_grad_tag, alpha,
325 rho, alpha_omega));
326
328}
329
330}
constexpr int SPACE_DIM
ElementsAndOps< SPACE_DIM >::BoundaryEle BoundaryEle
#define CHK_THROW_MESSAGE(err, msg)
Check and throw MoFEM exception.
#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.
static auto pushBoundaryTopologicalOpsImpl(EshelbianCore &ep, const std::string &fe_name, boost::shared_ptr< VolumeElementForcesAndSourcesCore > fe, ForcesAndSourcesCore::GaussHookFun boundary_integration_hook)
MoFEMErrorCode pushTopologicalOps_dJ_adjont_gradient(EshelbianCore &ep, boost::shared_ptr< VolumeElementForcesAndSourcesCore > fe, ForcesAndSourcesCore::GaussHookFun interior_integration_hook, ForcesAndSourcesCore::GaussHookFun boundary_integration_hook, SmartPetscObj< Vec > lambda_vec, Tag th_grad_tag, const double alpha, const double rho, const double alpha_omega)
SmartPetscObj< Vec > pushTopologicalSpatialOps(EshelbianCore &ep, boost::shared_ptr< VolumeElementForcesAndSourcesCore > fe, ForcesAndSourcesCore::GaussHookFun interior_integration_hook, ForcesAndSourcesCore::GaussHookFun boundary_integration_hook)
static auto pushInteriorTopologicalOpsImpl(EshelbianCore &ep, boost::shared_ptr< VolumeElementForcesAndSourcesCore > fe, ForcesAndSourcesCore::GaussHookFun interior_integration_hook, SmartPetscObj< Vec > lambda_vec=SmartPetscObj< Vec >())
static auto pushBoundaryTopological_dJ_dx_Impl(EshelbianCore &ep, boost::shared_ptr< ForcesAndSourcesCore > fe, boost::shared_ptr< std::vector< BrokenBaseSideData > > broken_data_ptr, boost::shared_ptr< DataAtIntegrationPts > data_at_pts_ptr, boost::shared_ptr< TopologicalData > topo_ptr, SmartPetscObj< Vec > dJ_dx_vec)
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, Tag th_grad_tag)
PipelineManager::ElementsAndOpsByDim< SPACE_DIM >::FaceSideEle EleOnSide
static auto pushInteriorTopological_dJ_dx_Impl(EshelbianCore &ep, boost::shared_ptr< ForcesAndSourcesCore > fe, boost::shared_ptr< DataAtIntegrationPts > data_at_pts_ptr, boost::shared_ptr< TopologicalData > topo_ptr)
constexpr AssemblyType A
boost::shared_ptr< Range > frontAdjEdges
const std::string skeletonElement
MoFEM::Interface & mField
const std::string spatialL2Disp
const std::string materialH1Positions
const std::string elementVolumeName
const std::string spatialH1Disp
const std::string piolaStress
const std::string bubbleField
static PetscBool noStretch
boost::shared_ptr< PhysicalEquations > physicalEquations
const std::string rotAxis
const std::string skinElement
const std::string hybridSpatialDisp
SmartPetscObj< DM > dmElastic
Elastic problem.
const std::string stretchTensor
BoundaryEle::UserDataOperator BdyEleOp
double rho
Definition plastic.cpp:144