15 EshelbianCore &ep, boost::shared_ptr<VolumeElementForcesAndSourcesCore> fe,
16 ForcesAndSourcesCore::GaussHookFun interior_integration_hook,
17 SmartPetscObj<Vec> lambda_vec = SmartPetscObj<Vec>()) {
21 auto data_at_pts_ptr = boost::make_shared<DataAtIntegrationPts>();
24 boost::make_shared<CGGUserPolynomialBase::CachePhi>(0, 0, MatrixDouble());
25 fe->getUserPolynomialBase() =
26 boost::make_shared<CGGUserPolynomialBase>(bubble_cache);
27 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
32 fe->getRuleHook = [](int, int, int) {
return -1; };
33 fe->setRuleHook = interior_integration_hook;
36 fe->getOpPtrVector().push_back(
new OpCalculateHVecTensorField<3, 3>(
37 ep.
piolaStress, data_at_pts_ptr->getApproxPAtPts()));
38 fe->getOpPtrVector().push_back(
new OpCalculateHTensorTensorField<3, 3>(
39 ep.
bubbleField, data_at_pts_ptr->getApproxPAtPts(), MBMAXTYPE));
40 fe->getOpPtrVector().push_back(
new OpCalculateHVecTensorDivergence<3, 3>(
44 fe->getOpPtrVector().push_back(
48 fe->getOpPtrVector().push_back(
49 new OpCalculateTensor2SymmetricFieldValues<3>(
50 ep.
stretchTensor, data_at_pts_ptr->getLogStretchTensorAtPts(),
54 fe->getOpPtrVector().push_back(
new OpCalculateVectorFieldValues<3>(
55 ep.
rotAxis, data_at_pts_ptr->getRotAxisAtPts(), MBTET));
56 fe->getOpPtrVector().push_back(
new OpCalculateVectorFieldValues<3>(
57 ep.
spatialL2Disp, data_at_pts_ptr->getSmallWL2AtPts(), MBTET));
60 fe->getOpPtrVector().push_back(
new OpCalculateVectorFieldValues<3>(
62 fe->getOpPtrVector().push_back(
new OpCalculateVectorFieldGradient<3, 3>(
64 fe->getOpPtrVector().push_back(
74 fe->getOpPtrVector().push_back(
75 new OpCalculateHVecTensorField<SPACE_DIM, SPACE_DIM>(
76 ep.
piolaStress, data_at_pts_ptr->getVarPiolaPts(),
nullptr,
78 fe->getOpPtrVector().push_back(
new OpCalculateHTensorTensorField<3, 3>(
79 ep.
bubbleField, data_at_pts_ptr->getVarPiolaPts(),
nullptr, lambda_vec,
81 fe->getOpPtrVector().push_back(
new OpCalculateHVecTensorDivergence<3, 3>(
82 ep.
piolaStress, data_at_pts_ptr->getDivVarPiolaPts(), lambda_vec));
84 fe->getOpPtrVector().push_back(
new OpCalculateVectorFieldValues<3>(
85 ep.
spatialL2Disp, data_at_pts_ptr->getVarWL2Pts(), lambda_vec, MBTET));
86 fe->getOpPtrVector().push_back(
new OpCalculateVectorFieldValues<3>(
87 ep.
rotAxis, data_at_pts_ptr->getVarRotAxisPts(), lambda_vec, MBTET));
88 fe->getOpPtrVector().push_back(
new OpCalculateVectorFieldGradient<3, 3>(
89 ep.
rotAxis, data_at_pts_ptr->getVarGradRotAxisPts(), lambda_vec, MBTET));
92 fe->getOpPtrVector().push_back(
96 fe->getOpPtrVector().push_back(
97 new OpCalculateTensor2SymmetricFieldValues<3>(
103 return data_at_pts_ptr;
108 boost::shared_ptr<VolumeElementForcesAndSourcesCore> fe,
109 ForcesAndSourcesCore::GaussHookFun boundary_integration_hook) {
113 auto &m_field = ep.
mField;
116 PipelineManager::ElementsAndOpsByDim<SPACE_DIM>::BoundaryEle;
118 PipelineManager::ElementsAndOpsByDim<SPACE_DIM>::FaceSideEle;
119 using SideEleOp = EleOnSide::UserDataOperator;
120 using BdyEleOp = BoundaryEle::UserDataOperator;
124 auto op_loop_skeleton_side =
125 new OpLoopSide<BoundaryEle>(m_field, fe_name,
SPACE_DIM - 1, Sev::noisy);
126 op_loop_skeleton_side->getSideFEPtr()->getRuleHook = [](int, int, int) {
129 op_loop_skeleton_side->getSideFEPtr()->setRuleHook =
130 boundary_integration_hook;
133 EshelbianPlasticity::AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
139 auto broken_data_ptr = boost::make_shared<std::vector<BrokenBaseSideData>>();
141 auto op_loop_domain_side =
new OpBrokenLoopSide<EleOnSide>(
143 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
144 boost::make_shared<CGGUserPolynomialBase>(
nullptr,
true);
146 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
147 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
149 op_loop_domain_side->getOpPtrVector().push_back(
150 new OpGetBrokenBaseSideData<SideEleOp>(ep.
piolaStress, broken_data_ptr));
151 auto flux_mat_ptr = boost::make_shared<MatrixDouble>();
152 op_loop_domain_side->getOpPtrVector().push_back(
153 new OpCalculateHVecTensorField<SPACE_DIM, SPACE_DIM>(ep.
piolaStress,
155 op_loop_domain_side->getOpPtrVector().push_back(
156 new OpSetFlux<SideEleOp>(broken_data_ptr, flux_mat_ptr));
157 op_loop_skeleton_side->getOpPtrVector().push_back(op_loop_domain_side);
159 return std::make_tuple(op_loop_skeleton_side,
160 op_loop_domain_side->getSideFEPtr(), broken_data_ptr);
164 EshelbianCore &ep, boost::shared_ptr<ForcesAndSourcesCore> fe,
165 boost::shared_ptr<DataAtIntegrationPts> data_at_pts_ptr,
166 boost::shared_ptr<TopologicalData> topo_ptr) {
170 auto dJ_dx_vec = createDMVector(ep.
dmElastic);
172 fe->getOpPtrVector().push_back(
176 ep.
bubbleField, data_at_pts_ptr, topo_ptr,
nullptr, dJ_dx_vec,
Tag()));
178 fe->getOpPtrVector().push_back(
new OpJ_dUImpl(
179 ep.
stretchTensor, data_at_pts_ptr, topo_ptr,
nullptr, dJ_dx_vec,
186 fe->getOpPtrVector().push_back(
190 ep.
rotAxis, data_at_pts_ptr, topo_ptr,
nullptr, dJ_dx_vec,
Tag()));
214 EshelbianCore &ep, boost::shared_ptr<VolumeElementForcesAndSourcesCore> fe,
215 ForcesAndSourcesCore::GaussHookFun interior_integration_hook,
216 ForcesAndSourcesCore::GaussHookFun boundary_integration_hook,
219 auto data_at_pts_ptr =
221 auto [op_skeleton_side, domain_side_fe_ptr, broken_data_ptr] =
223 boundary_integration_hook);
224 fe->getOpPtrVector().push_back(op_skeleton_side);
226 auto topo_ptr = boost::make_shared<TopologicalData>();
228 switch (eval_energy_model) {
230 char objective_function_file_name[255] =
"objective_function.py";
231 CHKERR PetscOptionsGetString(
232 PETSC_NULLPTR, PETSC_NULLPTR,
"-objective_function",
233 objective_function_file_name, 255, PETSC_NULLPTR);
235 create_python_objective_function(objective_function_file_name);
237 data_at_pts_ptr, topo_ptr, python_ptr, eval_energy_model));
241 data_at_pts_ptr, topo_ptr,
nullptr, eval_energy_model));
260 EshelbianCore &ep, boost::shared_ptr<VolumeElementForcesAndSourcesCore> fe,
261 ForcesAndSourcesCore::GaussHookFun interior_integration_hook,
262 ForcesAndSourcesCore::GaussHookFun boundary_integration_hook,
263 boost::shared_ptr<double> J_ptr, SmartPetscObj<Vec> dJ_dX_vec,
270 auto data_at_pts_ptr =
272 auto [op_skeleton_side, domain_side_fe_ptr, broken_data_ptr] =
274 boundary_integration_hook);
275 fe->getOpPtrVector().push_back(op_skeleton_side);
277 auto topo_ptr = boost::make_shared<TopologicalData>();
278 switch (eval_energy_model) {
280 char objective_function_file_name[255] =
"objective_function.py";
281 CHKERR PetscOptionsGetString(
282 PETSC_NULLPTR, PETSC_NULLPTR,
"-objective_function",
283 objective_function_file_name, 255, PETSC_NULLPTR);
285 create_python_objective_function(objective_function_file_name);
287 data_at_pts_ptr, topo_ptr, python_ptr, eval_energy_model));
291 data_at_pts_ptr, topo_ptr,
nullptr, eval_energy_model));
296 fe->getOpPtrVector().push_back(
new OpCalculateVectorFieldGradient<3, 3>(
298 topo_ptr->getJacobianAtPts(), SmartPetscObj<Vec>()));
299 fe->getOpPtrVector().push_back(
new OpInvertMatrix<3>(
300 topo_ptr->getJacobianAtPts(), topo_ptr->getDetJacobianAtPts(),
301 topo_ptr->getInvJacobianAtPts()));
303 data_at_pts_ptr, topo_ptr,
304 J_ptr, dJ_dX_vec,
Tag()));
315 EshelbianCore &ep, boost::shared_ptr<VolumeElementForcesAndSourcesCore> fe,
316 ForcesAndSourcesCore::GaussHookFun interior_integration_hook,
317 ForcesAndSourcesCore::GaussHookFun boundary_integration_hook,
318 SmartPetscObj<Vec> lambda_vec, SmartPetscObj<Vec> dJ_dX_vec,
319 const double alpha,
const double rho,
const double alpha_omega,
320 boost::shared_ptr<double> J_ptr,
321 SmartPetscObj<Vec> topo_vec = SmartPetscObj<Vec>()) {
326 ep, fe, interior_integration_hook, lambda_vec);
328 auto add_hybridised_dJ_gradient = [&](
auto fe_ptr) {
331 PipelineManager::ElementsAndOpsByDim<SPACE_DIM>::BoundaryEle;
332 using BdyEleOp = BoundaryEle::UserDataOperator;
334 auto [op_skeleton_side, domain_side_fe_ptr, broken_data_ptr] =
336 boundary_integration_hook);
339 PipelineManager::ElementsAndOpsByDim<SPACE_DIM>::FaceSideEle;
340 using SideEleOp = EleOnSide::UserDataOperator;
342 auto var_piola_mat_ptr = boost::make_shared<MatrixDouble>();
343 domain_side_fe_ptr->getOpPtrVector().push_back(
344 new OpCalculateHVecTensorField<SPACE_DIM, SPACE_DIM>(
345 ep.
piolaStress, var_piola_mat_ptr,
nullptr, lambda_vec));
346 domain_side_fe_ptr->getOpPtrVector().push_back(
347 new OpSetVarFlux<SideEleOp>(broken_data_ptr, var_piola_mat_ptr));
349 auto broken_disp_data_ptr =
350 boost::make_shared<std::vector<BrokenBaseSideData>>();
351 domain_side_fe_ptr->getOpPtrVector().push_back(
353 broken_disp_data_ptr));
354 auto disp_mat_ptr = boost::make_shared<MatrixDouble>();
355 domain_side_fe_ptr->getOpPtrVector().push_back(
356 new OpCalculateVectorFieldValues<SPACE_DIM>(ep.
spatialL2Disp,
358 domain_side_fe_ptr->getOpPtrVector().push_back(
359 new OpSetFlux<SideEleOp>(broken_disp_data_ptr, disp_mat_ptr));
360 auto var_disp_mat_ptr = boost::make_shared<MatrixDouble>();
361 domain_side_fe_ptr->getOpPtrVector().push_back(
362 new OpCalculateVectorFieldValues<SPACE_DIM>(
364 domain_side_fe_ptr->getOpPtrVector().push_back(
365 new OpSetVarFlux<SideEleOp>(broken_disp_data_ptr, var_disp_mat_ptr));
367 op_skeleton_side->getOpPtrVector().push_back(
368 new OpCalculateVectorFieldValues<SPACE_DIM>(
371 op_skeleton_side->getOpPtrVector().push_back(
372 new OpCalculateVectorFieldValues<SPACE_DIM>(
374 auto topo_ptr = boost::make_shared<TopologicalData>();
375 op_skeleton_side->getOpPtrVector().push_back(
new OpGetHONormalsOnFace(
377 topo_ptr->getTangent2AtPts(), topo_ptr->getNormalAtPts()));
382 data_at_pts_ptr->getHybridDispAtPts(),
383 data_at_pts_ptr->getVarHybridDispAtPts(), topo_ptr, ep.
alphaTau,
387 using OpTopoC_dHybrid =
389 GAUSS>::OpTopoDerivativeBrokenSpaceConstrainDHybrid<SPACE_DIM>;
390 using OpTopoC_dFlux =
392 GAUSS>::OpTopoDerivativeBrokenSpaceConstrainDFlux<SPACE_DIM>;
393 op_skeleton_side->getOpPtrVector().push_back(
new OpTopoC_dHybrid(
395 data_at_pts_ptr->getVarHybridDispAtPts(), topo_ptr->getTangent1AtPts(),
396 topo_ptr->getTangent2AtPts(), boost::make_shared<double>(1.0),
397 dJ_dX_vec,
Tag(), J_ptr));
398 op_skeleton_side->getOpPtrVector().push_back(
new OpTopoC_dFlux(
400 data_at_pts_ptr->getHybridDispAtPts(), topo_ptr->getTangent1AtPts(),
401 topo_ptr->getTangent2AtPts(), boost::make_shared<double>(1.0),
402 dJ_dX_vec,
Tag(), J_ptr));
404 fe_ptr->getOpPtrVector().push_back(op_skeleton_side);
409 "Failed to add hybridised dJ/dx gradient operators");
411 auto topo_ptr = boost::make_shared<TopologicalData>();
413 fe->getOpPtrVector().push_back(
new OpCalculateVectorFieldGradient<3, 3>(
415 topo_ptr->getJacobianAtPts(), topo_vec));
417 fe->getOpPtrVector().push_back(
new OpCalculateVectorFieldGradient<3, 3>(
421 fe->getOpPtrVector().push_back(
new OpInvertMatrix<3>(
422 topo_ptr->getJacobianAtPts(), topo_ptr->getDetJacobianAtPts(),
423 topo_ptr->getInvJacobianAtPts()));
427 alpha_omega, J_ptr));
431 fe->getOpPtrVector().push_back(op);
434 auto body_time_scale =
435 boost::make_shared<EshelbianCore::DynamicRelaxationTimeScale>(
437 auto add_body_force_opv = [&](
auto &&meshset_vec_ptr) {
438 for (
auto m : meshset_vec_ptr) {
442 std::vector<boost::shared_ptr<ScalingMethod>>{body_time_scale},
444 fe->getOpPtrVector().push_back(op);
448 const std::string body_force_block_name =
"BODY_FORCE";
454 (boost::format(
"%s(.*)") % body_force_block_name).str()
464 EshelbianCore &ep, boost::shared_ptr<FaceElementForcesAndSourcesCore> fe,
465 ForcesAndSourcesCore::GaussHookFun interior_integration_hook,
466 ForcesAndSourcesCore::GaussHookFun boundary_integration_hook,
467 SmartPetscObj<Vec> lambda_vec, SmartPetscObj<Vec> dJ_dX_vec,
468 boost::shared_ptr<double> J_ptr,
469 SmartPetscObj<Vec> topo_vec = SmartPetscObj<Vec>()) {
473 SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_ARG_NULL,
474 "Lambda vector is required for boundary dJ/dx gradient");
476 fe->getRuleHook = [](int, int, int) {
return -1; };
477 fe->setRuleHook = boundary_integration_hook;
479 EshelbianPlasticity::AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
482 auto get_broken_op_side = [&ep, lambda_vec](
auto &pip) {
484 PipelineManager::ElementsAndOpsByDim<SPACE_DIM>::FaceSideEle;
485 using SideEleOp = EleOnSide::UserDataOperator;
487 auto broken_data_ptr =
488 boost::make_shared<std::vector<BrokenBaseSideData>>();
490 auto op_loop_domain_side =
new OpLoopSide<EleOnSide>(
492 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
493 boost::make_shared<CGGUserPolynomialBase>(
nullptr,
true);
495 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
496 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
498 op_loop_domain_side->getOpPtrVector().push_back(
499 new OpGetBrokenBaseSideData<SideEleOp>(ep.
piolaStress,
501 auto flux_mat_ptr = boost::make_shared<MatrixDouble>();
502 op_loop_domain_side->getOpPtrVector().push_back(
503 new OpCalculateHVecTensorField<SPACE_DIM, SPACE_DIM>(ep.
piolaStress,
505 op_loop_domain_side->getOpPtrVector().push_back(
506 new OpSetFlux<SideEleOp>(broken_data_ptr, flux_mat_ptr));
507 auto var_flux_mat_ptr = boost::make_shared<MatrixDouble>();
508 op_loop_domain_side->getOpPtrVector().push_back(
509 new OpCalculateHVecTensorField<SPACE_DIM, SPACE_DIM>(
510 ep.
piolaStress, var_flux_mat_ptr,
nullptr, lambda_vec));
511 op_loop_domain_side->getOpPtrVector().push_back(
512 new OpSetVarFlux<SideEleOp>(broken_data_ptr, var_flux_mat_ptr));
513 pip.push_back(op_loop_domain_side);
514 return broken_data_ptr;
517 auto broken_data_ptr = get_broken_op_side(fe->getOpPtrVector());
518 auto topo_ptr = boost::make_shared<TopologicalData>();
520 auto lambda_hybrid_dip_ptr = boost::make_shared<MatrixDouble>();
521 fe->getOpPtrVector().push_back(
new OpCalculateVectorFieldValues<SPACE_DIM>(
535 lambda_hybrid_dip_ptr, topo_ptr, ep.
timeScaleMap, dJ_dX_vec, J_ptr));