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>(
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>(
43 ep.
rotAxis, data_at_pts_ptr->getRotAxisAtPts(),
44 data_at_pts_ptr->constantRotation, data_at_pts_ptr->higherRotation));
46 fe->getOpPtrVector().push_back(
new OpCalculateHVecTensorField<3, 3>(
55 ep.
rotAxis, boost::make_shared<MatrixDouble>(),
56 data_at_pts_ptr->previousConstantRotation,
57 data_at_pts_ptr->previousHigherRotation,
ep.
solTSStep));
58 fe->getOpPtrVector().push_back(
new OpCalculateVectorFieldValues<3>(
62 fe->getOpPtrVector().push_back(
new OpCalculateVectorFieldValues<3>(
64 fe->getOpPtrVector().push_back(
new OpCalculateVectorFieldGradient<3, 3>(
69 fe->getOpPtrVector().push_back(
73 ep, fe->getOpPtrVector(), data_at_pts_ptr,
false,
false);
76 fe->getOpPtrVector().push_back(
77 new OpCalculateHVecTensorField<SPACE_DIM, SPACE_DIM>(
80 fe->getOpPtrVector().push_back(
new OpCalculateHTensorTensorField<3, 3>(
81 ep.
bubbleField, data_at_pts_ptr->getVarPiolaPts(),
nullptr, lambda_vec,
83 fe->getOpPtrVector().push_back(
new OpCalculateHVecTensorDivergence<3, 3>(
84 ep.
piolaStress, data_at_pts_ptr->getDivVarPiolaPts(), lambda_vec));
86 fe->getOpPtrVector().push_back(
new OpCalculateVectorFieldValues<3>(
89 ep.
rotAxis, data_at_pts_ptr->getVarRotAxisPts(),
90 data_at_pts_ptr->varConstantRotation,
91 data_at_pts_ptr->varHigherRotation, lambda_vec));
92 fe->getOpPtrVector().push_back(
new OpCalculateVectorFieldGradient<3, 3>(
93 ep.
rotAxis, data_at_pts_ptr->getVarGradRotAxisPts(), lambda_vec,
97 ep, fe->getOpPtrVector(), data_at_pts_ptr, lambda_vec);
100 return data_at_pts_ptr;
105 boost::shared_ptr<VolumeElementForcesAndSourcesCore> fe,
106 ForcesAndSourcesCore::GaussHookFun boundary_integration_hook) {
113 PipelineManager::ElementsAndOpsByDim<SPACE_DIM>::BoundaryEle;
115 PipelineManager::ElementsAndOpsByDim<SPACE_DIM>::FaceSideEle;
116 using SideEleOp = EleOnSide::UserDataOperator;
117 using BdyEleOp = BoundaryEle::UserDataOperator;
121 auto op_loop_skeleton_side =
122 new OpLoopSide<BoundaryEle>(m_field, fe_name,
SPACE_DIM - 1, Sev::noisy);
123 op_loop_skeleton_side->getSideFEPtr()->getRuleHook = [](int, int, int) {
126 op_loop_skeleton_side->getSideFEPtr()->setRuleHook =
127 boundary_integration_hook;
130 EshelbianPlasticity::AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
136 auto broken_data_ptr = boost::make_shared<std::vector<BrokenBaseSideData>>();
138 auto op_loop_domain_side =
new OpBrokenLoopSide<EleOnSide>(
140 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
141 boost::make_shared<CGGUserPolynomialBase>(
nullptr,
true);
143 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
144 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
146 op_loop_domain_side->getOpPtrVector().push_back(
147 new OpGetBrokenBaseSideData<SideEleOp>(
ep.
piolaStress, broken_data_ptr));
148 auto flux_mat_ptr = boost::make_shared<MatrixDouble>();
149 op_loop_domain_side->getOpPtrVector().push_back(
150 new OpCalculateHVecTensorField<SPACE_DIM, SPACE_DIM>(
ep.
piolaStress,
152 op_loop_domain_side->getOpPtrVector().push_back(
153 new OpSetFlux<SideEleOp>(broken_data_ptr, flux_mat_ptr));
154 op_loop_skeleton_side->getOpPtrVector().push_back(op_loop_domain_side);
156 return std::make_tuple(op_loop_skeleton_side,
157 op_loop_domain_side->getSideFEPtr(), broken_data_ptr);
209 EshelbianCore &ep, boost::shared_ptr<VolumeElementForcesAndSourcesCore> fe,
210 ForcesAndSourcesCore::GaussHookFun interior_integration_hook,
211 ForcesAndSourcesCore::GaussHookFun boundary_integration_hook,
214 auto data_at_pts_ptr =
216 auto [op_skeleton_side, domain_side_fe_ptr, broken_data_ptr] =
218 boundary_integration_hook);
219 fe->getOpPtrVector().push_back(op_skeleton_side);
221 auto topo_ptr = boost::make_shared<TopologicalData>();
223 switch (eval_energy_model) {
225 char objective_function_file_name[255] =
"objective_function.py";
226 CHKERR PetscOptionsGetString(
227 PETSC_NULLPTR, PETSC_NULLPTR,
"-objective_function",
228 objective_function_file_name, 255, PETSC_NULLPTR);
230 create_python_objective_function(objective_function_file_name);
232 data_at_pts_ptr, topo_ptr, python_ptr, eval_energy_model));
236 data_at_pts_ptr, topo_ptr,
nullptr, eval_energy_model));
255 EshelbianCore &ep, boost::shared_ptr<VolumeElementForcesAndSourcesCore> fe,
256 ForcesAndSourcesCore::GaussHookFun interior_integration_hook,
257 ForcesAndSourcesCore::GaussHookFun boundary_integration_hook,
258 boost::shared_ptr<double> J_ptr, SmartPetscObj<Vec> dJ_dX_vec,
265 auto data_at_pts_ptr =
267 auto [op_skeleton_side, domain_side_fe_ptr, broken_data_ptr] =
269 boundary_integration_hook);
270 fe->getOpPtrVector().push_back(op_skeleton_side);
272 auto topo_ptr = boost::make_shared<TopologicalData>();
273 switch (eval_energy_model) {
275 char objective_function_file_name[255] =
"objective_function.py";
276 CHKERR PetscOptionsGetString(
277 PETSC_NULLPTR, PETSC_NULLPTR,
"-objective_function",
278 objective_function_file_name, 255, PETSC_NULLPTR);
280 create_python_objective_function(objective_function_file_name);
282 data_at_pts_ptr, topo_ptr, python_ptr, eval_energy_model));
286 data_at_pts_ptr, topo_ptr,
nullptr, eval_energy_model));
291 fe->getOpPtrVector().push_back(
new OpCalculateVectorFieldGradient<3, 3>(
293 topo_ptr->getJacobianAtPts(), SmartPetscObj<Vec>()));
294 fe->getOpPtrVector().push_back(
new OpInvertMatrix<3>(
295 topo_ptr->getJacobianAtPts(), topo_ptr->getDetJacobianAtPts(),
296 topo_ptr->getInvJacobianAtPts()));
298 data_at_pts_ptr, topo_ptr,
299 J_ptr, dJ_dX_vec,
Tag()));
310 EshelbianCore &ep, boost::shared_ptr<VolumeElementForcesAndSourcesCore> fe,
311 ForcesAndSourcesCore::GaussHookFun interior_integration_hook,
312 ForcesAndSourcesCore::GaussHookFun boundary_integration_hook,
313 SmartPetscObj<Vec> lambda_vec, SmartPetscObj<Vec> dJ_dX_vec,
314 const double alpha,
const double rho,
const double alpha_viscous_omega,
315 boost::shared_ptr<double> J_ptr,
316 SmartPetscObj<Vec> topo_vec = SmartPetscObj<Vec>()) {
321 ep, fe, interior_integration_hook, lambda_vec);
323 auto add_hybridised_dJ_gradient = [&](
auto fe_ptr) {
326 PipelineManager::ElementsAndOpsByDim<SPACE_DIM>::BoundaryEle;
327 using BdyEleOp = BoundaryEle::UserDataOperator;
329 auto [op_skeleton_side, domain_side_fe_ptr, broken_data_ptr] =
331 boundary_integration_hook);
334 PipelineManager::ElementsAndOpsByDim<SPACE_DIM>::FaceSideEle;
335 using SideEleOp = EleOnSide::UserDataOperator;
337 auto var_piola_mat_ptr = boost::make_shared<MatrixDouble>();
338 domain_side_fe_ptr->getOpPtrVector().push_back(
339 new OpCalculateHVecTensorField<SPACE_DIM, SPACE_DIM>(
341 domain_side_fe_ptr->getOpPtrVector().push_back(
342 new OpSetVarFlux<SideEleOp>(broken_data_ptr, var_piola_mat_ptr));
344 auto broken_disp_data_ptr =
345 boost::make_shared<std::vector<BrokenBaseSideData>>();
346 domain_side_fe_ptr->getOpPtrVector().push_back(
348 broken_disp_data_ptr));
349 auto disp_mat_ptr = boost::make_shared<MatrixDouble>();
350 domain_side_fe_ptr->getOpPtrVector().push_back(
353 domain_side_fe_ptr->getOpPtrVector().push_back(
354 new OpSetFlux<SideEleOp>(broken_disp_data_ptr, disp_mat_ptr));
355 auto var_disp_mat_ptr = boost::make_shared<MatrixDouble>();
356 domain_side_fe_ptr->getOpPtrVector().push_back(
357 new OpCalculateVectorFieldValues<SPACE_DIM>(
359 domain_side_fe_ptr->getOpPtrVector().push_back(
360 new OpSetVarFlux<SideEleOp>(broken_disp_data_ptr, var_disp_mat_ptr));
362 op_skeleton_side->getOpPtrVector().push_back(
363 new OpCalculateVectorFieldValues<SPACE_DIM>(
366 op_skeleton_side->getOpPtrVector().push_back(
367 new OpCalculateVectorFieldValues<SPACE_DIM>(
369 auto topo_ptr = boost::make_shared<TopologicalData>();
370 op_skeleton_side->getOpPtrVector().push_back(
new OpGetHONormalsOnFace(
372 topo_ptr->getTangent2AtPts(), topo_ptr->getNormalAtPts()));
377 data_at_pts_ptr->getHybridDispAtPts(),
378 data_at_pts_ptr->getVarHybridDispAtPts(), topo_ptr,
ep.
alphaTau,
382 using OpTopoC_dHybrid = FormsIntegrators<BdyEleOp>::Assembly<
A>
::LinearForm<
383 GAUSS>::OpTopoDerivativeBrokenSpaceConstrainDHybrid<SPACE_DIM>;
384 using OpTopoC_dFlux = FormsIntegrators<BdyEleOp>::Assembly<
A>
::LinearForm<
385 GAUSS>::OpTopoDerivativeBrokenSpaceConstrainDFlux<SPACE_DIM>;
386 op_skeleton_side->getOpPtrVector().push_back(
new OpTopoC_dHybrid(
388 data_at_pts_ptr->getVarHybridDispAtPts(), topo_ptr->getTangent1AtPts(),
389 topo_ptr->getTangent2AtPts(), boost::make_shared<double>(1.0),
390 dJ_dX_vec,
Tag(), J_ptr));
391 op_skeleton_side->getOpPtrVector().push_back(
new OpTopoC_dFlux(
393 data_at_pts_ptr->getHybridDispAtPts(), topo_ptr->getTangent1AtPts(),
394 topo_ptr->getTangent2AtPts(), boost::make_shared<double>(1.0),
395 dJ_dX_vec,
Tag(), J_ptr));
397 fe_ptr->getOpPtrVector().push_back(op_skeleton_side);
402 "Failed to add hybridised dJ/dx gradient operators");
404 auto topo_ptr = boost::make_shared<TopologicalData>();
406 fe->getOpPtrVector().push_back(
new OpCalculateVectorFieldGradient<3, 3>(
408 topo_ptr->getJacobianAtPts(), topo_vec));
410 fe->getOpPtrVector().push_back(
new OpCalculateVectorFieldGradient<3, 3>(
414 fe->getOpPtrVector().push_back(
new OpInvertMatrix<3>(
415 topo_ptr->getJacobianAtPts(), topo_ptr->getDetJacobianAtPts(),
416 topo_ptr->getInvJacobianAtPts()));
420 alpha_viscous_omega, J_ptr));
424 fe->getOpPtrVector().push_back(op);
427 std::string body_force_history;
430 if (body_force_history.empty()) {
431 body_force_history =
"body_force.txt";
434 <<
"Body force load history from JSON: " << body_force_history;
436 auto body_time_scale =
437 boost::make_shared<EshelbianCore::DynamicRelaxationTimeScale>(
439 auto add_body_force_opv = [&](
auto &&meshset_vec_ptr) {
440 for (
auto m : meshset_vec_ptr) {
444 std::vector<boost::shared_ptr<ScalingMethod>>{body_time_scale},
446 fe->getOpPtrVector().push_back(op);
450 const std::string body_force_block_name =
"BODY_FORCE";
456 (boost::format(
"%s(.*)") % body_force_block_name).str()
466 EshelbianCore &ep, boost::shared_ptr<FaceElementForcesAndSourcesCore> fe,
467 ForcesAndSourcesCore::GaussHookFun interior_integration_hook,
468 ForcesAndSourcesCore::GaussHookFun boundary_integration_hook,
469 SmartPetscObj<Vec> lambda_vec, SmartPetscObj<Vec> dJ_dX_vec,
470 boost::shared_ptr<double> J_ptr,
471 SmartPetscObj<Vec> topo_vec = SmartPetscObj<Vec>()) {
475 SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_ARG_NULL,
476 "Lambda vector is required for boundary dJ/dx gradient");
478 fe->getRuleHook = [](int, int, int) {
return -1; };
479 fe->setRuleHook = boundary_integration_hook;
481 EshelbianPlasticity::AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
484 auto get_broken_op_side = [&
ep, lambda_vec](
auto &pip) {
486 PipelineManager::ElementsAndOpsByDim<SPACE_DIM>::FaceSideEle;
487 using SideEleOp = EleOnSide::UserDataOperator;
489 auto broken_data_ptr =
490 boost::make_shared<std::vector<BrokenBaseSideData>>();
492 auto op_loop_domain_side =
new OpLoopSide<EleOnSide>(
494 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
495 boost::make_shared<CGGUserPolynomialBase>(
nullptr,
true);
497 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
498 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
500 op_loop_domain_side->getOpPtrVector().push_back(
503 auto flux_mat_ptr = boost::make_shared<MatrixDouble>();
504 op_loop_domain_side->getOpPtrVector().push_back(
505 new OpCalculateHVecTensorField<SPACE_DIM, SPACE_DIM>(
ep.
piolaStress,
507 op_loop_domain_side->getOpPtrVector().push_back(
508 new OpSetFlux<SideEleOp>(broken_data_ptr, flux_mat_ptr));
509 auto var_flux_mat_ptr = boost::make_shared<MatrixDouble>();
510 op_loop_domain_side->getOpPtrVector().push_back(
511 new OpCalculateHVecTensorField<SPACE_DIM, SPACE_DIM>(
513 op_loop_domain_side->getOpPtrVector().push_back(
514 new OpSetVarFlux<SideEleOp>(broken_data_ptr, var_flux_mat_ptr));
515 pip.push_back(op_loop_domain_side);
516 return broken_data_ptr;
519 auto broken_data_ptr = get_broken_op_side(fe->getOpPtrVector());
520 auto topo_ptr = boost::make_shared<TopologicalData>();
522 auto lambda_hybrid_dip_ptr = boost::make_shared<MatrixDouble>();
523 fe->getOpPtrVector().push_back(
new OpCalculateVectorFieldValues<SPACE_DIM>(
528 fe->getOpPtrVector().push_back(
537 lambda_hybrid_dip_ptr, topo_ptr,
ep.
timeScaleMap, dJ_dX_vec, J_ptr));