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>(
42 fe->getOpPtrVector().push_back(
new OpCalculateVectorFieldValues<3>(
43 ep.
rotAxis, data_at_pts_ptr->getRotAxisAtPts(), MBTET));
50 fe->getOpPtrVector().push_back(
51 new OpCalculateTensor2SymmetricFieldValues<3>(
52 ep.
stretchTensor, data_at_pts_ptr->getLogStretchTensorAtPts(),
56 fe->getOpPtrVector().push_back(
new OpCalculateHVecTensorField<3, 3>(
57 ep.
piolaStress, data_at_pts_ptr->getApproxP0AtPts(),
nullptr,
60 fe->getOpPtrVector().push_back(
new OpCalculateTensor2SymmetricFieldValues<3>(
61 ep.
stretchTensor, data_at_pts_ptr->getLogStretchTensor0AtPts(),
65 fe->getOpPtrVector().push_back(
new OpCalculateVectorFieldValues<3>(
67 fe->getOpPtrVector().push_back(
new OpCalculateVectorFieldValues<3>(
68 ep.
spatialL2Disp, data_at_pts_ptr->getSmallWL2AtPts(), MBTET));
71 fe->getOpPtrVector().push_back(
new OpCalculateVectorFieldValues<3>(
73 fe->getOpPtrVector().push_back(
new OpCalculateVectorFieldGradient<3, 3>(
75 fe->getOpPtrVector().push_back(
85 fe->getOpPtrVector().push_back(
86 new OpCalculateHVecTensorField<SPACE_DIM, SPACE_DIM>(
87 ep.
piolaStress, data_at_pts_ptr->getVarPiolaPts(),
nullptr,
89 fe->getOpPtrVector().push_back(
new OpCalculateHTensorTensorField<3, 3>(
90 ep.
bubbleField, data_at_pts_ptr->getVarPiolaPts(),
nullptr, lambda_vec,
92 fe->getOpPtrVector().push_back(
new OpCalculateHVecTensorDivergence<3, 3>(
93 ep.
piolaStress, data_at_pts_ptr->getDivVarPiolaPts(), lambda_vec));
95 fe->getOpPtrVector().push_back(
new OpCalculateVectorFieldValues<3>(
96 ep.
spatialL2Disp, data_at_pts_ptr->getVarWL2Pts(), lambda_vec, MBTET));
97 fe->getOpPtrVector().push_back(
new OpCalculateVectorFieldValues<3>(
98 ep.
rotAxis, data_at_pts_ptr->getVarRotAxisPts(), lambda_vec, MBTET));
99 fe->getOpPtrVector().push_back(
new OpCalculateVectorFieldGradient<3, 3>(
100 ep.
rotAxis, data_at_pts_ptr->getVarGradRotAxisPts(), lambda_vec, MBTET));
103 fe->getOpPtrVector().push_back(
107 fe->getOpPtrVector().push_back(
108 new OpCalculateTensor2SymmetricFieldValues<3>(
114 return data_at_pts_ptr;
119 boost::shared_ptr<VolumeElementForcesAndSourcesCore> fe,
120 ForcesAndSourcesCore::GaussHookFun boundary_integration_hook) {
124 auto &m_field = ep.
mField;
127 PipelineManager::ElementsAndOpsByDim<SPACE_DIM>::BoundaryEle;
129 PipelineManager::ElementsAndOpsByDim<SPACE_DIM>::FaceSideEle;
130 using SideEleOp = EleOnSide::UserDataOperator;
131 using BdyEleOp = BoundaryEle::UserDataOperator;
135 auto op_loop_skeleton_side =
136 new OpLoopSide<BoundaryEle>(m_field, fe_name,
SPACE_DIM - 1, Sev::noisy);
137 op_loop_skeleton_side->getSideFEPtr()->getRuleHook = [](int, int, int) {
140 op_loop_skeleton_side->getSideFEPtr()->setRuleHook =
141 boundary_integration_hook;
144 EshelbianPlasticity::AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
150 auto broken_data_ptr = boost::make_shared<std::vector<BrokenBaseSideData>>();
152 auto op_loop_domain_side =
new OpBrokenLoopSide<EleOnSide>(
154 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
155 boost::make_shared<CGGUserPolynomialBase>(
nullptr,
true);
157 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
158 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
160 op_loop_domain_side->getOpPtrVector().push_back(
161 new OpGetBrokenBaseSideData<SideEleOp>(ep.
piolaStress, broken_data_ptr));
162 auto flux_mat_ptr = boost::make_shared<MatrixDouble>();
163 op_loop_domain_side->getOpPtrVector().push_back(
164 new OpCalculateHVecTensorField<SPACE_DIM, SPACE_DIM>(ep.
piolaStress,
166 op_loop_domain_side->getOpPtrVector().push_back(
167 new OpSetFlux<SideEleOp>(broken_data_ptr, flux_mat_ptr));
168 op_loop_skeleton_side->getOpPtrVector().push_back(op_loop_domain_side);
170 return std::make_tuple(op_loop_skeleton_side,
171 op_loop_domain_side->getSideFEPtr(), broken_data_ptr);
175 EshelbianCore &ep, boost::shared_ptr<ForcesAndSourcesCore> fe,
176 boost::shared_ptr<DataAtIntegrationPts> data_at_pts_ptr,
177 boost::shared_ptr<TopologicalData> topo_ptr) {
181 auto dJ_dx_vec = createDMVector(ep.
dmElastic);
183 fe->getOpPtrVector().push_back(
187 ep.
bubbleField, data_at_pts_ptr, topo_ptr,
nullptr, dJ_dx_vec,
Tag()));
189 fe->getOpPtrVector().push_back(
new OpJ_dUImpl(
190 ep.
stretchTensor, data_at_pts_ptr, topo_ptr,
nullptr, dJ_dx_vec,
197 fe->getOpPtrVector().push_back(
201 ep.
rotAxis, data_at_pts_ptr, topo_ptr,
nullptr, dJ_dx_vec,
Tag()));
225 EshelbianCore &ep, boost::shared_ptr<VolumeElementForcesAndSourcesCore> fe,
226 ForcesAndSourcesCore::GaussHookFun interior_integration_hook,
227 ForcesAndSourcesCore::GaussHookFun boundary_integration_hook,
230 auto data_at_pts_ptr =
232 auto [op_skeleton_side, domain_side_fe_ptr, broken_data_ptr] =
234 boundary_integration_hook);
235 fe->getOpPtrVector().push_back(op_skeleton_side);
237 auto topo_ptr = boost::make_shared<TopologicalData>();
239 switch (eval_energy_model) {
241 char objective_function_file_name[255] =
"objective_function.py";
242 CHKERR PetscOptionsGetString(
243 PETSC_NULLPTR, PETSC_NULLPTR,
"-objective_function",
244 objective_function_file_name, 255, PETSC_NULLPTR);
246 create_python_objective_function(objective_function_file_name);
248 data_at_pts_ptr, topo_ptr, python_ptr, eval_energy_model));
252 data_at_pts_ptr, topo_ptr,
nullptr, eval_energy_model));
271 EshelbianCore &ep, boost::shared_ptr<VolumeElementForcesAndSourcesCore> fe,
272 ForcesAndSourcesCore::GaussHookFun interior_integration_hook,
273 ForcesAndSourcesCore::GaussHookFun boundary_integration_hook,
274 boost::shared_ptr<double> J_ptr, SmartPetscObj<Vec> dJ_dX_vec,
281 auto data_at_pts_ptr =
283 auto [op_skeleton_side, domain_side_fe_ptr, broken_data_ptr] =
285 boundary_integration_hook);
286 fe->getOpPtrVector().push_back(op_skeleton_side);
288 auto topo_ptr = boost::make_shared<TopologicalData>();
289 switch (eval_energy_model) {
291 char objective_function_file_name[255] =
"objective_function.py";
292 CHKERR PetscOptionsGetString(
293 PETSC_NULLPTR, PETSC_NULLPTR,
"-objective_function",
294 objective_function_file_name, 255, PETSC_NULLPTR);
296 create_python_objective_function(objective_function_file_name);
298 data_at_pts_ptr, topo_ptr, python_ptr, eval_energy_model));
302 data_at_pts_ptr, topo_ptr,
nullptr, eval_energy_model));
307 fe->getOpPtrVector().push_back(
new OpCalculateVectorFieldGradient<3, 3>(
309 topo_ptr->getJacobianAtPts(), SmartPetscObj<Vec>()));
310 fe->getOpPtrVector().push_back(
new OpInvertMatrix<3>(
311 topo_ptr->getJacobianAtPts(), topo_ptr->getDetJacobianAtPts(),
312 topo_ptr->getInvJacobianAtPts()));
314 data_at_pts_ptr, topo_ptr,
315 J_ptr, dJ_dX_vec,
Tag()));
326 EshelbianCore &ep, boost::shared_ptr<VolumeElementForcesAndSourcesCore> fe,
327 ForcesAndSourcesCore::GaussHookFun interior_integration_hook,
328 ForcesAndSourcesCore::GaussHookFun boundary_integration_hook,
329 SmartPetscObj<Vec> lambda_vec, SmartPetscObj<Vec> dJ_dX_vec,
330 const double alpha,
const double rho,
const double alpha_viscous_omega,
331 boost::shared_ptr<double> J_ptr,
332 SmartPetscObj<Vec> topo_vec = SmartPetscObj<Vec>()) {
337 ep, fe, interior_integration_hook, lambda_vec);
339 auto add_hybridised_dJ_gradient = [&](
auto fe_ptr) {
342 PipelineManager::ElementsAndOpsByDim<SPACE_DIM>::BoundaryEle;
343 using BdyEleOp = BoundaryEle::UserDataOperator;
345 auto [op_skeleton_side, domain_side_fe_ptr, broken_data_ptr] =
347 boundary_integration_hook);
350 PipelineManager::ElementsAndOpsByDim<SPACE_DIM>::FaceSideEle;
351 using SideEleOp = EleOnSide::UserDataOperator;
353 auto var_piola_mat_ptr = boost::make_shared<MatrixDouble>();
354 domain_side_fe_ptr->getOpPtrVector().push_back(
355 new OpCalculateHVecTensorField<SPACE_DIM, SPACE_DIM>(
356 ep.
piolaStress, var_piola_mat_ptr,
nullptr, lambda_vec));
357 domain_side_fe_ptr->getOpPtrVector().push_back(
358 new OpSetVarFlux<SideEleOp>(broken_data_ptr, var_piola_mat_ptr));
360 auto broken_disp_data_ptr =
361 boost::make_shared<std::vector<BrokenBaseSideData>>();
362 domain_side_fe_ptr->getOpPtrVector().push_back(
364 broken_disp_data_ptr));
365 auto disp_mat_ptr = boost::make_shared<MatrixDouble>();
366 domain_side_fe_ptr->getOpPtrVector().push_back(
367 new OpCalculateVectorFieldValues<SPACE_DIM>(ep.
spatialL2Disp,
369 domain_side_fe_ptr->getOpPtrVector().push_back(
370 new OpSetFlux<SideEleOp>(broken_disp_data_ptr, disp_mat_ptr));
371 auto var_disp_mat_ptr = boost::make_shared<MatrixDouble>();
372 domain_side_fe_ptr->getOpPtrVector().push_back(
373 new OpCalculateVectorFieldValues<SPACE_DIM>(
375 domain_side_fe_ptr->getOpPtrVector().push_back(
376 new OpSetVarFlux<SideEleOp>(broken_disp_data_ptr, var_disp_mat_ptr));
378 op_skeleton_side->getOpPtrVector().push_back(
379 new OpCalculateVectorFieldValues<SPACE_DIM>(
382 op_skeleton_side->getOpPtrVector().push_back(
383 new OpCalculateVectorFieldValues<SPACE_DIM>(
385 auto topo_ptr = boost::make_shared<TopologicalData>();
386 op_skeleton_side->getOpPtrVector().push_back(
new OpGetHONormalsOnFace(
388 topo_ptr->getTangent2AtPts(), topo_ptr->getNormalAtPts()));
393 data_at_pts_ptr->getHybridDispAtPts(),
394 data_at_pts_ptr->getVarHybridDispAtPts(), topo_ptr, ep.
alphaTau,
398 using OpTopoC_dHybrid =
400 GAUSS>::OpTopoDerivativeBrokenSpaceConstrainDHybrid<SPACE_DIM>;
401 using OpTopoC_dFlux =
403 GAUSS>::OpTopoDerivativeBrokenSpaceConstrainDFlux<SPACE_DIM>;
404 op_skeleton_side->getOpPtrVector().push_back(
new OpTopoC_dHybrid(
406 data_at_pts_ptr->getVarHybridDispAtPts(), topo_ptr->getTangent1AtPts(),
407 topo_ptr->getTangent2AtPts(), boost::make_shared<double>(1.0),
408 dJ_dX_vec,
Tag(), J_ptr));
409 op_skeleton_side->getOpPtrVector().push_back(
new OpTopoC_dFlux(
411 data_at_pts_ptr->getHybridDispAtPts(), topo_ptr->getTangent1AtPts(),
412 topo_ptr->getTangent2AtPts(), boost::make_shared<double>(1.0),
413 dJ_dX_vec,
Tag(), J_ptr));
415 fe_ptr->getOpPtrVector().push_back(op_skeleton_side);
420 "Failed to add hybridised dJ/dx gradient operators");
422 auto topo_ptr = boost::make_shared<TopologicalData>();
424 fe->getOpPtrVector().push_back(
new OpCalculateVectorFieldGradient<3, 3>(
426 topo_ptr->getJacobianAtPts(), topo_vec));
428 fe->getOpPtrVector().push_back(
new OpCalculateVectorFieldGradient<3, 3>(
432 fe->getOpPtrVector().push_back(
new OpInvertMatrix<3>(
433 topo_ptr->getJacobianAtPts(), topo_ptr->getDetJacobianAtPts(),
434 topo_ptr->getInvJacobianAtPts()));
438 alpha_viscous_omega, J_ptr));
442 fe->getOpPtrVector().push_back(op);
445 std::string body_force_history;
448 if (body_force_history.empty()) {
449 body_force_history =
"body_force.txt";
452 <<
"Body force load history from JSON: " << body_force_history;
454 auto body_time_scale =
455 boost::make_shared<EshelbianCore::DynamicRelaxationTimeScale>(
457 auto add_body_force_opv = [&](
auto &&meshset_vec_ptr) {
458 for (
auto m : meshset_vec_ptr) {
462 std::vector<boost::shared_ptr<ScalingMethod>>{body_time_scale},
464 fe->getOpPtrVector().push_back(op);
468 const std::string body_force_block_name =
"BODY_FORCE";
474 (boost::format(
"%s(.*)") % body_force_block_name).str()
484 EshelbianCore &ep, boost::shared_ptr<FaceElementForcesAndSourcesCore> fe,
485 ForcesAndSourcesCore::GaussHookFun interior_integration_hook,
486 ForcesAndSourcesCore::GaussHookFun boundary_integration_hook,
487 SmartPetscObj<Vec> lambda_vec, SmartPetscObj<Vec> dJ_dX_vec,
488 boost::shared_ptr<double> J_ptr,
489 SmartPetscObj<Vec> topo_vec = SmartPetscObj<Vec>()) {
493 SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_ARG_NULL,
494 "Lambda vector is required for boundary dJ/dx gradient");
496 fe->getRuleHook = [](int, int, int) {
return -1; };
497 fe->setRuleHook = boundary_integration_hook;
499 EshelbianPlasticity::AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
502 auto get_broken_op_side = [&ep, lambda_vec](
auto &pip) {
504 PipelineManager::ElementsAndOpsByDim<SPACE_DIM>::FaceSideEle;
505 using SideEleOp = EleOnSide::UserDataOperator;
507 auto broken_data_ptr =
508 boost::make_shared<std::vector<BrokenBaseSideData>>();
510 auto op_loop_domain_side =
new OpLoopSide<EleOnSide>(
512 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
513 boost::make_shared<CGGUserPolynomialBase>(
nullptr,
true);
515 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
516 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
518 op_loop_domain_side->getOpPtrVector().push_back(
519 new OpGetBrokenBaseSideData<SideEleOp>(ep.
piolaStress,
521 auto flux_mat_ptr = boost::make_shared<MatrixDouble>();
522 op_loop_domain_side->getOpPtrVector().push_back(
523 new OpCalculateHVecTensorField<SPACE_DIM, SPACE_DIM>(ep.
piolaStress,
525 op_loop_domain_side->getOpPtrVector().push_back(
526 new OpSetFlux<SideEleOp>(broken_data_ptr, flux_mat_ptr));
527 auto var_flux_mat_ptr = boost::make_shared<MatrixDouble>();
528 op_loop_domain_side->getOpPtrVector().push_back(
529 new OpCalculateHVecTensorField<SPACE_DIM, SPACE_DIM>(
530 ep.
piolaStress, var_flux_mat_ptr,
nullptr, lambda_vec));
531 op_loop_domain_side->getOpPtrVector().push_back(
532 new OpSetVarFlux<SideEleOp>(broken_data_ptr, var_flux_mat_ptr));
533 pip.push_back(op_loop_domain_side);
534 return broken_data_ptr;
537 auto broken_data_ptr = get_broken_op_side(fe->getOpPtrVector());
538 auto topo_ptr = boost::make_shared<TopologicalData>();
540 auto lambda_hybrid_dip_ptr = boost::make_shared<MatrixDouble>();
541 fe->getOpPtrVector().push_back(
new OpCalculateVectorFieldValues<SPACE_DIM>(
555 lambda_hybrid_dip_ptr, topo_ptr, ep.
timeScaleMap, dJ_dX_vec, J_ptr));