10 using namespace MoFEM;
15 #include <boost/math/constants/constants.hpp>
19 #include <boost/python.hpp>
20 #include <boost/python/def.hpp>
21 #include <boost/python/numpy.hpp>
22 namespace bp = boost::python;
23 namespace np = boost::python::numpy;
25 #pragma message "With PYTHON_SDF"
29 #pragma message "Without PYTHON_SDF"
53 const EntityType
type) {
57 auto dim = CN::Dimension(
type);
59 std::vector<int> sendcounts(pcomm->size());
60 std::vector<int> displs(pcomm->size());
61 std::vector<int> sendbuf(
r.size());
62 if (pcomm->rank() == 0) {
63 for (
auto p = 1; p != pcomm->size(); p++) {
65 ->getPartEntities(m_field.
get_moab(), p)
68 CHKERR m_field.
get_moab().get_adjacencies(part_ents, dim,
true, faces,
69 moab::Interface::UNION);
70 faces = intersect(faces,
r);
71 sendcounts[p] = faces.size();
72 displs[p] = sendbuf.size();
73 for (
auto f : faces) {
75 sendbuf.push_back(
id);
81 MPI_Scatter(sendcounts.data(), 1, MPI_INT, &recv_data, 1, MPI_INT, 0,
83 std::vector<int> recvbuf(recv_data);
84 MPI_Scatterv(sendbuf.data(), sendcounts.data(), displs.data(), MPI_INT,
85 recvbuf.data(), recv_data, MPI_INT, 0, pcomm->comm());
87 if (pcomm->rank() > 0) {
89 for (
auto &
f : recvbuf) {
99 const std::string block_name,
int dim) {
105 std::regex((boost::format(
"%s(.*)") % block_name).str())
109 for (
auto bc : bcs) {
121 const unsigned int cubit_bc_type) {
124 CHKERR mesh_mng->getMeshset(ms_id, cubit_bc_type, meshset);
129 const Range r, std::vector<Tag> tags = {}) {
132 CHKERR moab.add_entities(*out_meshset,
r);
134 CHKERR moab.write_file(name.c_str(),
"VTK",
"", out_meshset->get_ptr(), 1,
135 tags.data(), tags.size());
137 MOFEM_LOG(
"SELF", Sev::warning) <<
"Empty range for " << name;
144 ParallelComm *pcomm =
147 PSTATUS_SHARED | PSTATUS_MULTISHARED,
148 PSTATUS_NOT, -1, &boundary_ents),
150 return boundary_ents;
155 ParallelComm *pcomm =
157 CHK_MOAB_THROW(pcomm->filter_pstatus(skin, PSTATUS_NOT_OWNED, PSTATUS_NOT, -1,
166 CHK_MOAB_THROW(skin.find_skin(0, body_ents,
false, skin_ents),
"find_skin");
172 ParallelComm *pcomm =
176 if (pcomm->rank() == 0) {
177 crack_skin =
get_skin(m_field, crack_faces);
181 "get_entities_by_dimension");
182 auto body_skin =
get_skin(m_field, body_ents);
183 Range body_skin_edges;
184 CHK_MOAB_THROW(moab.get_adjacencies(body_skin, 1,
true, body_skin_edges,
185 moab::Interface::UNION),
187 crack_skin = subtract(crack_skin, body_skin_edges);
189 return send_type(m_field, crack_skin, MBEDGE);
195 ParallelComm *pcomm =
198 MOFEM_LOG(
"EP", Sev::inform) <<
"get_two_sides_of_crack_surface";
200 if (!pcomm->rank()) {
202 auto impl = [&](
auto &saids) {
207 auto get_adj = [&](
auto e,
auto dim) {
210 e, dim,
true, adj, moab::Interface::UNION),
215 auto get_conn = [&](
auto e) {
222 constexpr
bool debug =
false;
226 auto body_skin =
get_skin(m_field, body_ents);
227 auto body_skin_edges = get_adj(body_skin, 1);
230 subtract(
get_skin(m_field, crack_faces), body_skin_edges);
231 auto crack_skin_conn = get_conn(crack_skin);
232 auto crack_skin_conn_edges = get_adj(crack_skin_conn, 1);
233 auto crack_edges = get_adj(crack_faces, 1);
234 crack_edges = subtract(crack_edges, crack_skin);
235 auto all_tets = get_adj(crack_edges, 3);
236 crack_edges = subtract(crack_edges, crack_skin_conn_edges);
237 auto crack_conn = get_conn(crack_edges);
238 all_tets.merge(get_adj(crack_conn, 3));
247 if (crack_faces.size()) {
248 auto grow = [&](
auto r) {
249 auto crack_faces_conn = get_conn(crack_faces);
252 while (size_r !=
r.size() &&
r.size() > 0) {
254 CHKERR moab.get_connectivity(
r,
v,
true);
255 v = subtract(
v, crack_faces_conn);
258 moab::Interface::UNION);
259 r = intersect(
r, all_tets);
268 Range all_tets_ord = all_tets;
269 while (all_tets.size()) {
270 Range faces = get_adj(unite(saids.first, saids.second), 2);
271 faces = subtract(crack_faces, faces);
274 auto fit = faces.begin();
275 for (;fit != faces.end(); ++fit) {
276 tets = intersect(get_adj(
Range(*fit, *fit), 3), all_tets);
277 if (tets.size() == 2) {
284 saids.first.insert(tets[0]);
285 saids.first = grow(saids.first);
286 all_tets = subtract(all_tets, saids.first);
287 if (tets.size() == 2) {
288 saids.second.insert(tets[1]);
289 saids.second = grow(saids.second);
290 all_tets = subtract(all_tets, saids.second);
298 saids.first = subtract(all_tets_ord, saids.second);
299 saids.second = subtract(all_tets_ord, saids.first);
306 std::pair<Range, Range> saids;
307 if (crack_faces.size())
312 MOFEM_LOG(
"EP", Sev::inform) <<
"get_two_sides_of_crack_surface <- done";
314 return std::pair<Range, Range>();
335 boost::shared_ptr<Range> front_edges)
336 : frontNodes(front_nodes), frontEdges(front_edges) {};
339 int order_col,
int order_data) {
342 constexpr
bool debug =
false;
344 constexpr
int numNodes = 4;
345 constexpr
int numEdges = 6;
346 constexpr
int refinementLevels = 4;
348 auto &m_field = fe_raw_ptr->
mField;
349 auto fe_ptr =
static_cast<Fe *
>(fe_raw_ptr);
352 auto set_base_quadrature = [&]() {
354 int rule = 2 * order_data + 1;
365 auto &gauss_pts = fe_ptr->gaussPts;
366 gauss_pts.resize(4, nb_gauss_pts,
false);
367 cblas_dcopy(nb_gauss_pts, &
QUAD_3D_TABLE[rule]->points[1], 4,
368 &gauss_pts(0, 0), 1);
369 cblas_dcopy(nb_gauss_pts, &
QUAD_3D_TABLE[rule]->points[2], 4,
370 &gauss_pts(1, 0), 1);
371 cblas_dcopy(nb_gauss_pts, &
QUAD_3D_TABLE[rule]->points[3], 4,
372 &gauss_pts(2, 0), 1);
374 &gauss_pts(3, 0), 1);
375 auto &data = fe_ptr->dataOnElement[
H1];
376 data->dataOnEntities[MBVERTEX][0].getN(
NOBASE).resize(nb_gauss_pts, 4,
379 &*data->dataOnEntities[MBVERTEX][0].getN(
NOBASE).data().begin();
380 cblas_dcopy(4 * nb_gauss_pts,
QUAD_3D_TABLE[rule]->points, 1, shape_ptr,
389 CHKERR set_base_quadrature();
393 auto get_singular_nodes = [&]() {
396 CHKERR m_field.get_moab().get_connectivity(fe_handle, conn, num_nodes,
398 std::bitset<numNodes> singular_nodes;
399 for (
auto nn = 0; nn != numNodes; ++nn) {
400 if (frontNodes->find(conn[nn]) != frontNodes->end()) {
401 singular_nodes.set(nn);
403 singular_nodes.reset(nn);
406 return singular_nodes;
409 auto get_singular_edges = [&]() {
410 std::bitset<numEdges> singular_edges;
411 for (
int ee = 0; ee != numEdges; ee++) {
413 CHKERR m_field.get_moab().side_element(fe_handle, 1, ee, edge);
414 if (frontEdges->find(edge) != frontEdges->end()) {
415 singular_edges.set(ee);
417 singular_edges.reset(ee);
420 return singular_edges;
423 auto set_gauss_pts = [&](
auto &ref_gauss_pts) {
425 fe_ptr->gaussPts.swap(ref_gauss_pts);
426 const size_t nb_gauss_pts = fe_ptr->gaussPts.size2();
427 auto &data = fe_ptr->dataOnElement[
H1];
428 data->dataOnEntities[MBVERTEX][0].getN(
NOBASE).resize(nb_gauss_pts, 4);
430 &*data->dataOnEntities[MBVERTEX][0].getN(
NOBASE).data().begin();
432 &fe_ptr->gaussPts(1, 0), &fe_ptr->gaussPts(2, 0),
437 auto singular_nodes = get_singular_nodes();
438 if (singular_nodes.count()) {
439 auto it_map_ref_coords =
mapRefCoords.find(singular_nodes.to_ulong());
441 CHKERR set_gauss_pts(it_map_ref_coords->second);
445 auto refine_quadrature = [&]() {
448 const int max_level = refinementLevels;
452 double base_coords[] = {0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1};
454 for (
int nn = 0; nn != 4; nn++)
455 CHKERR moab_ref.create_vertex(&base_coords[3 * nn], nodes[nn]);
456 CHKERR moab_ref.create_element(MBTET, nodes, 4, tet);
460 Range tets(tet, tet);
463 tets, 1,
true, edges, moab::Interface::UNION);
468 Range nodes_at_front;
469 for (
int nn = 0; nn != numNodes; nn++) {
470 if (singular_nodes[nn]) {
472 CHKERR moab_ref.side_element(tet, 0, nn, ent);
473 nodes_at_front.insert(ent);
477 auto singular_edges = get_singular_edges();
480 CHKERR moab_ref.create_meshset(MESHSET_SET, meshset);
481 for (
int ee = 0; ee != numEdges; ee++) {
482 if (singular_edges[ee]) {
484 CHKERR moab_ref.side_element(tet, 1, ee, ent);
485 CHKERR moab_ref.add_entities(meshset, &ent, 1);
491 for (
int ll = 0; ll != max_level; ll++) {
494 ->getEntitiesByTypeAndRefLevel(
BitRefLevel().set(ll),
498 CHKERR moab_ref.get_adjacencies(
499 nodes_at_front, 1,
true, ref_edges, moab::Interface::UNION);
500 ref_edges = intersect(ref_edges, edges);
502 CHKERR moab_ref.get_entities_by_type(meshset, MBEDGE, ents,
true);
503 ref_edges = intersect(ref_edges, ents);
506 ->getEntitiesByTypeAndRefLevel(
508 CHKERR m_ref->addVerticesInTheMiddleOfEdges(
512 ->updateMeshsetByEntitiesChildren(meshset,
514 meshset, MBEDGE,
true);
520 ->getEntitiesByTypeAndRefLevel(
BitRefLevel().set(max_level),
530 for (Range::iterator tit = tets.begin(); tit != tets.end();
534 CHKERR moab_ref.get_connectivity(*tit, conn, num_nodes,
false);
535 CHKERR moab_ref.get_coords(conn, num_nodes, &ref_coords(tt, 0));
538 auto &data = fe_ptr->dataOnElement[
H1];
539 const size_t nb_gauss_pts = fe_ptr->gaussPts.size2();
540 MatrixDouble ref_gauss_pts(4, nb_gauss_pts * ref_coords.size1());
542 data->dataOnEntities[MBVERTEX][0].getN(
NOBASE);
544 for (
size_t tt = 0; tt != ref_coords.size1(); tt++) {
545 double *tet_coords = &ref_coords(tt, 0);
548 for (
size_t ggg = 0; ggg != nb_gauss_pts; ++ggg, ++gg) {
549 for (
int dd = 0;
dd != 3;
dd++) {
550 ref_gauss_pts(
dd, gg) =
551 shape_n(ggg, 0) * tet_coords[3 * 0 +
dd] +
552 shape_n(ggg, 1) * tet_coords[3 * 1 +
dd] +
553 shape_n(ggg, 2) * tet_coords[3 * 2 +
dd] +
554 shape_n(ggg, 3) * tet_coords[3 * 3 +
dd];
556 ref_gauss_pts(3, gg) = fe_ptr->gaussPts(3, ggg) * det;
560 mapRefCoords[singular_nodes.to_ulong()].swap(ref_gauss_pts);
566 CHKERR refine_quadrature();
591 boost::shared_ptr<Range> front_edges)
592 : frontNodes(front_nodes), frontEdges(front_edges) {};
595 int order_col,
int order_data) {
598 constexpr
bool debug =
false;
600 constexpr
int numNodes = 3;
601 constexpr
int numEdges = 3;
602 constexpr
int refinementLevels = 4;
604 auto &m_field = fe_raw_ptr->
mField;
605 auto fe_ptr =
static_cast<Fe *
>(fe_raw_ptr);
608 auto set_base_quadrature = [&]() {
610 int rule = 2 * (order_data + 1);
620 fe_ptr->gaussPts.resize(3, nb_gauss_pts,
false);
621 cblas_dcopy(nb_gauss_pts, &
QUAD_2D_TABLE[rule]->points[1], 3,
622 &fe_ptr->gaussPts(0, 0), 1);
623 cblas_dcopy(nb_gauss_pts, &
QUAD_2D_TABLE[rule]->points[2], 3,
624 &fe_ptr->gaussPts(1, 0), 1);
626 &fe_ptr->gaussPts(2, 0), 1);
627 auto &data = fe_ptr->dataOnElement[
H1];
628 data->dataOnEntities[MBVERTEX][0].getN(
NOBASE).resize(nb_gauss_pts, 3,
631 &*data->dataOnEntities[MBVERTEX][0].getN(
NOBASE).data().begin();
632 cblas_dcopy(3 * nb_gauss_pts,
QUAD_2D_TABLE[rule]->points, 1, shape_ptr,
634 data->dataOnEntities[MBVERTEX][0].getDiffN(
NOBASE).resize(3, 2,
false);
637 data->dataOnEntities[MBVERTEX][0].getDiffN(
NOBASE).data().begin());
646 CHKERR set_base_quadrature();
650 auto get_singular_nodes = [&]() {
653 CHKERR m_field.get_moab().get_connectivity(fe_handle, conn, num_nodes,
655 std::bitset<numNodes> singular_nodes;
656 for (
auto nn = 0; nn != numNodes; ++nn) {
657 if (frontNodes->find(conn[nn]) != frontNodes->end()) {
658 singular_nodes.set(nn);
660 singular_nodes.reset(nn);
663 return singular_nodes;
666 auto get_singular_edges = [&]() {
667 std::bitset<numEdges> singular_edges;
668 for (
int ee = 0; ee != numEdges; ee++) {
670 CHKERR m_field.get_moab().side_element(fe_handle, 1, ee, edge);
671 if (frontEdges->find(edge) != frontEdges->end()) {
672 singular_edges.set(ee);
674 singular_edges.reset(ee);
677 return singular_edges;
680 auto set_gauss_pts = [&](
auto &ref_gauss_pts) {
682 fe_ptr->gaussPts.swap(ref_gauss_pts);
683 const size_t nb_gauss_pts = fe_ptr->gaussPts.size2();
684 auto &data = fe_ptr->dataOnElement[
H1];
685 data->dataOnEntities[MBVERTEX][0].getN(
NOBASE).resize(nb_gauss_pts, 4);
687 &*data->dataOnEntities[MBVERTEX][0].getN(
NOBASE).data().begin();
689 &fe_ptr->gaussPts(1, 0), nb_gauss_pts);
693 auto singular_nodes = get_singular_nodes();
694 if (singular_nodes.count()) {
695 auto it_map_ref_coords =
mapRefCoords.find(singular_nodes.to_ulong());
697 CHKERR set_gauss_pts(it_map_ref_coords->second);
701 auto refine_quadrature = [&]() {
704 const int max_level = refinementLevels;
707 double base_coords[] = {0, 0, 0, 1, 0, 0, 0, 1, 0};
709 for (
int nn = 0; nn != numNodes; nn++)
710 CHKERR moab_ref.create_vertex(&base_coords[3 * nn], nodes[nn]);
712 CHKERR moab_ref.create_element(MBTRI, nodes, numNodes, tri);
716 Range tris(tri, tri);
719 tris, 1,
true, edges, moab::Interface::UNION);
724 Range nodes_at_front;
725 for (
int nn = 0; nn != numNodes; nn++) {
726 if (singular_nodes[nn]) {
728 CHKERR moab_ref.side_element(tri, 0, nn, ent);
729 nodes_at_front.insert(ent);
733 auto singular_edges = get_singular_edges();
736 CHKERR moab_ref.create_meshset(MESHSET_SET, meshset);
737 for (
int ee = 0; ee != numEdges; ee++) {
738 if (singular_edges[ee]) {
740 CHKERR moab_ref.side_element(tri, 1, ee, ent);
741 CHKERR moab_ref.add_entities(meshset, &ent, 1);
747 for (
int ll = 0; ll != max_level; ll++) {
750 ->getEntitiesByTypeAndRefLevel(
BitRefLevel().set(ll),
754 CHKERR moab_ref.get_adjacencies(
755 nodes_at_front, 1,
true, ref_edges, moab::Interface::UNION);
756 ref_edges = intersect(ref_edges, edges);
758 CHKERR moab_ref.get_entities_by_type(meshset, MBEDGE, ents,
true);
759 ref_edges = intersect(ref_edges, ents);
762 ->getEntitiesByTypeAndRefLevel(
764 CHKERR m_ref->addVerticesInTheMiddleOfEdges(
768 ->updateMeshsetByEntitiesChildren(meshset,
770 meshset, MBEDGE,
true);
776 ->getEntitiesByTypeAndRefLevel(
BitRefLevel().set(max_level),
787 for (Range::iterator tit = tris.begin(); tit != tris.end();
791 CHKERR moab_ref.get_connectivity(*tit, conn, num_nodes,
false);
792 CHKERR moab_ref.get_coords(conn, num_nodes, &ref_coords(tt, 0));
795 auto &data = fe_ptr->dataOnElement[
H1];
796 const size_t nb_gauss_pts = fe_ptr->gaussPts.size2();
797 MatrixDouble ref_gauss_pts(3, nb_gauss_pts * ref_coords.size1());
799 data->dataOnEntities[MBVERTEX][0].getN(
NOBASE);
801 for (
size_t tt = 0; tt != ref_coords.size1(); tt++) {
802 double *tri_coords = &ref_coords(tt, 0);
805 auto det = t_normal.
l2();
806 for (
size_t ggg = 0; ggg != nb_gauss_pts; ++ggg, ++gg) {
807 for (
int dd = 0;
dd != 2;
dd++) {
808 ref_gauss_pts(
dd, gg) =
809 shape_n(ggg, 0) * tri_coords[3 * 0 +
dd] +
810 shape_n(ggg, 1) * tri_coords[3 * 1 +
dd] +
811 shape_n(ggg, 2) * tri_coords[3 * 2 +
dd];
813 ref_gauss_pts(2, gg) = fe_ptr->gaussPts(2, ggg) * det;
817 mapRefCoords[singular_nodes.to_ulong()].swap(ref_gauss_pts);
823 CHKERR refine_quadrature();
885 const char *list_rots[] = {
"small",
"moderate",
"large",
"no_h1"};
886 const char *list_symm[] = {
"symm",
"not_symm"};
891 const char *list_stretches[] = {
"linear",
"log"};
894 CHKERR PetscOptionsBegin(PETSC_COMM_WORLD,
"",
"Eshelbian plasticity",
896 CHKERR PetscOptionsInt(
"-space_order",
"approximation oder for space",
"",
898 CHKERR PetscOptionsInt(
"-space_h1_order",
"approximation oder for space",
"",
900 CHKERR PetscOptionsInt(
"-material_order",
"approximation oder for material",
902 CHKERR PetscOptionsScalar(
"-viscosity_alpha_u",
"viscosity",
"",
alphaU,
904 CHKERR PetscOptionsScalar(
"-viscosity_alpha_w",
"viscosity",
"",
alphaW,
906 CHKERR PetscOptionsScalar(
"-viscosity_alpha_omega",
"rot viscosity",
"",
908 CHKERR PetscOptionsScalar(
"-density_alpha_rho",
"density",
"",
alphaRho,
910 CHKERR PetscOptionsEList(
"-rotations",
"rotations",
"", list_rots,
911 LARGE_ROT + 1, list_rots[choice_rot], &choice_rot,
913 CHKERR PetscOptionsEList(
"-grad",
"gradient of defamation approximate",
"",
915 list_rots[choice_grad], &choice_grad, PETSC_NULL);
916 CHKERR PetscOptionsEList(
"-symm",
"symmetric variant",
"", list_symm, 2,
917 list_symm[choice_symm], &choice_symm, PETSC_NULL);
923 list_stretches[choice_stretch], &choice_stretch, PETSC_NULL);
925 CHKERR PetscOptionsBool(
"-no_stretch",
"do not solve for stretch",
"",
927 CHKERR PetscOptionsBool(
"-set_singularity",
"set singularity",
"",
929 CHKERR PetscOptionsBool(
"-l2_user_base_scale",
"streach scale",
"",
933 CHKERR PetscOptionsBool(
"-dynamic_relaxation",
"dynamic time relaxation",
"",
937 CHKERR PetscOptionsInt(
"-contact_max_post_proc_ref_level",
"refinement level",
944 CHKERR PetscOptionsScalar(
"-griffith_energy",
"Griffith energy",
"",
947 ierr = PetscOptionsEnd();
999 MOFEM_LOG(
"EP", Sev::inform) <<
"Gradient of deformation "
1007 MOFEM_LOG(
"EP", Sev::inform) <<
"Base exponent e";
1008 MOFEM_LOG(
"EP", Sev::inform) <<
"Stretch " << list_stretches[choice_stretch];
1030 auto get_tets = [&]() {
1036 auto get_tets_skin = [&]() {
1037 Range tets_skin_part;
1039 CHKERR skin.find_skin(0, get_tets(),
false, tets_skin_part);
1040 ParallelComm *pcomm =
1043 CHKERR pcomm->filter_pstatus(tets_skin_part,
1044 PSTATUS_SHARED | PSTATUS_MULTISHARED,
1045 PSTATUS_NOT, -1, &tets_skin);
1049 auto subtract_boundary_conditions = [&](
auto &&tets_skin) {
1055 tets_skin = subtract(tets_skin,
v.faces);
1060 auto add_blockset = [&](
auto block_name,
auto &&tets_skin) {
1063 tets_skin.merge(crack_faces);
1067 auto subtract_blockset = [&](
auto block_name,
auto &&tets_skin) {
1068 auto contact_range =
1070 tets_skin = subtract(tets_skin, contact_range);
1074 auto get_stress_trace_faces = [&](
auto &&tets_skin) {
1077 faces, moab::Interface::UNION);
1078 Range trace_faces = subtract(faces, tets_skin);
1082 auto tets = get_tets();
1086 auto trace_faces = get_stress_trace_faces(
1088 subtract_blockset(
"CONTACT",
1089 subtract_boundary_conditions(get_tets_skin()))
1096 boost::make_shared<Range>(subtract(trace_faces, *
contactFaces));
1098 boost::make_shared<Range>(get_stress_trace_faces(
Range()));
1110 auto add_broken_hdiv_field = [
this, meshset](
const std::string
field_name,
1116 auto get_side_map_hdiv = [&]() {
1119 std::pair<EntityType,
1134 get_side_map_hdiv(), MB_TAG_DENSE,
MF_ZERO);
1140 auto add_l2_field = [
this, meshset](
const std::string
field_name,
1141 const int order,
const int dim) {
1150 auto add_h1_field = [
this, meshset](
const std::string
field_name,
1151 const int order,
const int dim) {
1163 auto add_l2_field_by_range = [
this](
const std::string
field_name,
1164 const int order,
const int dim,
1165 const int field_dim,
Range &&
r) {
1175 auto add_bubble_field = [
this, meshset](
const std::string
field_name,
1176 const int order,
const int dim) {
1182 auto field_order_table =
1183 const_cast<Field *
>(field_ptr)->getFieldOrderTable();
1184 auto get_cgg_bubble_order_zero = [](
int p) {
return 0; };
1185 auto get_cgg_bubble_order_tet = [](
int p) {
1188 field_order_table[MBVERTEX] = get_cgg_bubble_order_zero;
1189 field_order_table[MBEDGE] = get_cgg_bubble_order_zero;
1190 field_order_table[MBTRI] = get_cgg_bubble_order_zero;
1191 field_order_table[MBTET] = get_cgg_bubble_order_tet;
1198 auto add_user_l2_field = [
this, meshset](
const std::string
field_name,
1199 const int order,
const int dim) {
1205 auto field_order_table =
1206 const_cast<Field *
>(field_ptr)->getFieldOrderTable();
1207 auto zero_dofs = [](
int p) {
return 0; };
1209 field_order_table[MBVERTEX] = zero_dofs;
1210 field_order_table[MBEDGE] = zero_dofs;
1211 field_order_table[MBTRI] = zero_dofs;
1212 field_order_table[MBTET] = dof_l2_tet;
1257 auto project_ho_geometry = [&](
auto field) {
1263 auto get_adj_front_edges = [&](
auto &front_edges) {
1265 Range front_crack_nodes;
1266 CHKERR moab.get_connectivity(front_edges, front_crack_nodes,
true);
1269 Range crack_front_edges;
1271 crack_front_edges, moab::Interface::UNION);
1273 intersect(subtract(crack_front_edges, front_edges), meshset_ents);
1277 Range crack_front_edges_nodes;
1278 CHKERR moab.get_connectivity(crack_front_edges, crack_front_edges_nodes,
1281 crack_front_edges_nodes);
1282 crack_front_edges_nodes =
1283 subtract(crack_front_edges_nodes, front_crack_nodes);
1284 Range crack_front_edges_with_both_nodes_not_at_front;
1285 CHKERR moab.get_adjacencies(crack_front_edges_nodes,
SPACE_DIM - 2,
false,
1286 crack_front_edges_with_both_nodes_not_at_front,
1287 moab::Interface::UNION);
1288 crack_front_edges_with_both_nodes_not_at_front =
1289 intersect(crack_front_edges_with_both_nodes_not_at_front, meshset_ents);
1291 crack_front_edges_with_both_nodes_not_at_front);
1292 crack_front_edges_with_both_nodes_not_at_front = intersect(
1293 crack_front_edges_with_both_nodes_not_at_front, crack_front_edges);
1295 return std::make_pair(boost::make_shared<Range>(front_crack_nodes),
1296 boost::make_shared<Range>(
1297 crack_front_edges_with_both_nodes_not_at_front));
1305 auto [front_vertices, front_adj_edges] = get_adj_front_edges(*
frontEdges);
1316 (boost::format(
"crack_faces_%d.vtk") % rank).str(),
1330 auto set_singular_dofs = [&](
auto &front_adj_edges,
auto &front_vertices) {
1338 MOFEM_LOG(
"EP", Sev::inform) <<
"Singularity eps " << beta;
1341 for (
auto edge : front_adj_edges) {
1344 CHKERR moab.get_connectivity(edge, conn, num_nodes,
false);
1346 CHKERR moab.get_coords(conn, num_nodes, coords);
1347 const double dir[3] = {coords[3] - coords[0], coords[4] - coords[1],
1348 coords[5] - coords[2]};
1349 double dof[3] = {0, 0, 0};
1350 if (front_vertices.find(conn[0]) != front_vertices.end()) {
1351 for (
int dd = 0;
dd != 3;
dd++) {
1354 }
else if (front_vertices.find(conn[1]) != front_vertices.end()) {
1355 for (
int dd = 0;
dd != 3;
dd++) {
1361 const int idx = dit->get()->getEntDofIdx();
1363 dit->get()->getFieldData() = 0;
1365 dit->get()->getFieldData() = dof[idx];
1384 auto add_field_to_fe = [
this](
const std::string fe,
1417 Range front_elements;
1419 Range front_elements_layer;
1421 front_elements_layer,
1422 moab::Interface::UNION);
1423 front_elements.merge(front_elements_layer);
1424 front_edges.clear();
1427 moab::Interface::UNION);
1448 auto set_fe_adjacency = [&](
auto fe_name) {
1451 boost::make_shared<ParentFiniteElementAdjacencyFunctionSkeleton<2>>(
1459 auto add_field_to_fe = [
this](
const std::string fe,
1471 Range natural_bc_elements;
1474 natural_bc_elements.merge(
v.faces);
1479 natural_bc_elements.merge(
v.faces);
1484 natural_bc_elements.merge(
v.faces);
1487 natural_bc_elements = intersect(natural_bc_elements, meshset_ents);
1496 auto get_skin = [&](
auto &body_ents) {
1499 CHKERR skin.find_skin(0, body_ents,
false, skin_ents);
1504 Range boundary_ents;
1505 ParallelComm *pcomm =
1507 CHKERR pcomm->filter_pstatus(skin, PSTATUS_SHARED | PSTATUS_MULTISHARED,
1508 PSTATUS_NOT, -1, &boundary_ents);
1509 return boundary_ents;
1570 Range front_elements;
1572 Range front_elements_layer;
1574 front_elements_layer,
1575 moab::Interface::UNION);
1576 front_elements.merge(front_elements_layer);
1577 front_edges.clear();
1580 moab::Interface::UNION);
1584 Range front_elements_faces;
1586 true, front_elements_faces,
1587 moab::Interface::UNION);
1590 Range material_skeleton_faces =
1591 subtract(front_elements_faces, front_elements_skin);
1592 material_skeleton_faces.merge(intersect(front_elements_skin, body_skin));
1597 front_elements_skin);
1599 material_skeleton_faces);
1637 auto remove_dofs_on_broken_skin = [&](
const std::string prb_name) {
1639 for (
int d : {0, 1, 2}) {
1640 std::vector<boost::weak_ptr<NumeredDofEntity>> dofs_to_remove;
1642 ->getSideDofsOnBrokenSpaceEntities(
1653 CHKERR remove_dofs_on_broken_skin(
"ESHELBY_PLASTICITY");
1689 auto set_zero_block = [&]() {
1721 auto set_section = [&]() {
1723 PetscSection section;
1728 CHKERR PetscSectionDestroy(§ion);
1745 ->pushMarkDOFsOnEntities<DisplacementCubitBcData>(
1751 BcDisp::BcDisp(std::string name, std::vector<double> &attr,
Range &faces)
1752 : blockName(name), faces(faces) {
1753 vals.resize(3,
false);
1754 flags.resize(3,
false);
1755 for (
int ii = 0; ii != 3; ++ii) {
1756 vals[ii] = attr[ii];
1757 flags[ii] =
static_cast<int>(attr[ii + 3]);
1760 MOFEM_LOG(
"EP", Sev::inform) <<
"Add BCDisp " << name;
1762 <<
"Add BCDisp vals " <<
vals[0] <<
" " <<
vals[1] <<
" " <<
vals[2];
1764 <<
"Add BCDisp flags " <<
flags[0] <<
" " <<
flags[1] <<
" " <<
flags[2];
1765 MOFEM_LOG(
"EP", Sev::inform) <<
"Add BCDisp nb. of faces " <<
faces.size();
1769 : blockName(name), faces(faces) {
1770 vals.resize(3,
false);
1771 for (
int ii = 0; ii != 3; ++ii) {
1772 vals[ii] = attr[ii];
1779 : blockName(name), faces(faces) {
1780 vals.resize(3,
false);
1781 flags.resize(3,
false);
1782 for (
int ii = 0; ii != 3; ++ii) {
1783 vals[ii] = attr[ii];
1784 flags[ii] =
static_cast<int>(attr[ii + 3]);
1787 MOFEM_LOG(
"EP", Sev::inform) <<
"Add BCForce " << name;
1789 <<
"Add BCForce vals " <<
vals[0] <<
" " <<
vals[1] <<
" " <<
vals[2];
1791 <<
"Add BCForce flags " <<
flags[0] <<
" " <<
flags[1] <<
" " <<
flags[2];
1792 MOFEM_LOG(
"EP", Sev::inform) <<
"Add BCForce nb. of faces " <<
faces.size();
1797 boost::shared_ptr<TractionFreeBc> &bc_ptr,
1798 const std::string contact_set_name) {
1803 CHKERR mField.get_moab().get_entities_by_type(meshset, MBTET, tets);
1804 Range tets_skin_part;
1805 Skinner skin(&mField.get_moab());
1806 CHKERR skin.find_skin(0, tets,
false, tets_skin_part);
1807 ParallelComm *pcomm =
1810 CHKERR pcomm->filter_pstatus(tets_skin_part,
1811 PSTATUS_SHARED | PSTATUS_MULTISHARED,
1812 PSTATUS_NOT, -1, &tets_skin);
1815 for (
int dd = 0;
dd != 3; ++
dd)
1816 (*bc_ptr)[
dd] = tets_skin;
1819 if (bcSpatialDispVecPtr)
1820 for (
auto &
v : *bcSpatialDispVecPtr) {
1822 (*bc_ptr)[0] = subtract((*bc_ptr)[0],
v.faces);
1824 (*bc_ptr)[1] = subtract((*bc_ptr)[1],
v.faces);
1826 (*bc_ptr)[2] = subtract((*bc_ptr)[2],
v.faces);
1830 if (bcSpatialRotationVecPtr)
1831 for (
auto &
v : *bcSpatialRotationVecPtr) {
1832 (*bc_ptr)[0] = subtract((*bc_ptr)[0],
v.faces);
1833 (*bc_ptr)[1] = subtract((*bc_ptr)[1],
v.faces);
1834 (*bc_ptr)[2] = subtract((*bc_ptr)[2],
v.faces);
1837 if (bcSpatialTraction)
1838 for (
auto &
v : *bcSpatialTraction) {
1839 (*bc_ptr)[0] = subtract((*bc_ptr)[0],
v.faces);
1840 (*bc_ptr)[1] = subtract((*bc_ptr)[1],
v.faces);
1841 (*bc_ptr)[2] = subtract((*bc_ptr)[2],
v.faces);
1846 std::regex((boost::format(
"%s(.*)") % contact_set_name).str()))) {
1848 CHKERR m->getMeshsetIdEntitiesByDimension(mField.get_moab(), 2, faces,
1850 (*bc_ptr)[0] = subtract((*bc_ptr)[0], faces);
1851 (*bc_ptr)[1] = subtract((*bc_ptr)[1], faces);
1852 (*bc_ptr)[2] = subtract((*bc_ptr)[2], faces);
1869 return 2 * p_data + 1;
1875 return 2 * (p_data + 1);
1880 boost::shared_ptr<CachePhi> cache_phi_otr)
1884 boost::typeindex::type_index type_index,
1892 boost::shared_ptr<BaseFunctionCtx> ctx_ptr) {
1897 int nb_gauss_pts = pts.size2();
1898 if (!nb_gauss_pts) {
1902 if (pts.size1() < 3) {
1904 "Wrong dimension of pts, should be at least 3 rows with "
1908 const auto base = this->cTx->bAse;
1911 switch (this->cTx->sPace) {
1916 data.
dataOnEntities[MBVERTEX][0].getN(base).resize(nb_gauss_pts, 4,
false);
1917 CHKERR Tools::shapeFunMBTET(
1919 &pts(0, 0), &pts(1, 0), &pts(2, 0), nb_gauss_pts);
1920 data.
dataOnEntities[MBVERTEX][0].getDiffN(base).resize(4, 3,
false);
1921 std::copy(Tools::diffShapeFunMBTET.begin(), Tools::diffShapeFunMBTET.end(),
1924 CHKERR getValueL2AinsworthBase(pts);
1940 "Wrong base, should be USER_BASE");
1948 const int nb_gauss_pts = pts.size2();
1950 auto check_cache = [
this](
int order,
int nb_gauss_pts) ->
bool {
1959 if (check_cache(
order, nb_gauss_pts)) {
1962 phi.resize(mat.size1(), mat.size2(),
false);
1967 shapeFun.resize(nb_gauss_pts, 4,
false);
1969 &pts(2, 0), nb_gauss_pts);
1971 double diff_shape_fun[12];
1977 phi.resize(nb_gauss_pts, 9 * nb_base_functions,
false);
2000 const int tag,
const bool do_rhs,
const bool do_lhs,
const bool calc_rates,
2002 boost::shared_ptr<VolumeElementForcesAndSourcesCore> fe) {
2006 boost::make_shared<CGGUserPolynomialBase::CachePhi>(0, 0,
MatrixDouble());
2007 fe->getUserPolynomialBase() =
2008 boost::make_shared<CGGUserPolynomialBase>(bubble_cache);
2009 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
2010 fe->getOpPtrVector(), {HDIV, H1, L2}, materialH1Positions, frontAdjEdges);
2013 fe->getRuleHook = [](
int,
int,
int) {
return -1; };
2014 fe->setRuleHook = SetIntegrationAtFrontVolume(frontVertices, frontAdjEdges);
2019 boost::shared_ptr<DataAtIntegrationPts>(
new DataAtIntegrationPts());
2020 dataAtPts->physicsPtr = physicalEquations;
2025 piolaStress, dataAtPts->getApproxPAtPts()));
2027 bubbleField, dataAtPts->getApproxPAtPts(), MBMAXTYPE));
2029 piolaStress, dataAtPts->getDivPAtPts()));
2032 fe->getOpPtrVector().push_back(
2033 physicalEquations->returnOpCalculateStretchFromStress(
2034 dataAtPts, physicalEquations));
2036 fe->getOpPtrVector().push_back(
2038 stretchTensor, dataAtPts->getLogStretchTensorAtPts(), MBTET));
2042 rotAxis, dataAtPts->getRotAxisAtPts(), MBTET));
2044 rotAxis, dataAtPts->getRotAxis0AtPts(), solTSStep, MBTET));
2046 spatialL2Disp, dataAtPts->getSmallWL2AtPts(), MBTET));
2050 spatialH1Disp, dataAtPts->getSmallWH1AtPts()));
2052 spatialH1Disp, dataAtPts->getSmallWGradH1AtPts()));
2057 spatialL2Disp, dataAtPts->getSmallWL2DotAtPts(), MBTET));
2060 fe->getOpPtrVector().push_back(
2062 stretchTensor, dataAtPts->getLogStretchDotTensorAtPts(), MBTET));
2065 rotAxis, dataAtPts->getRotAxisDotAtPts(), MBTET));
2067 rotAxis, dataAtPts->getRotAxisGradDotAtPts(), MBTET));
2070 stretchTensor, dataAtPts->getGradLogStretchDotTensorAtPts(), MBTET));
2073 if (std::abs(alphaRho) > std::numeric_limits<double>::epsilon()) {
2075 spatialL2Disp, dataAtPts->getSmallWL2DotDotAtPts(), MBTET));
2082 piolaStress, dataAtPts->getVarPiolaPts(), boost::make_shared<double>(1),
2085 bubbleField, dataAtPts->getVarPiolaPts(), boost::make_shared<double>(1),
2086 var_vec, MBMAXTYPE));
2088 rotAxis, dataAtPts->getVarRotAxisPts(), var_vec, MBTET));
2090 piolaStress, dataAtPts->getDivVarPiolaPts(), var_vec));
2092 spatialL2Disp, dataAtPts->getVarWL2Pts(), var_vec, MBTET));
2095 fe->getOpPtrVector().push_back(
2096 physicalEquations->returnOpCalculateVarStretchFromStress(
2097 dataAtPts, physicalEquations));
2099 fe->getOpPtrVector().push_back(
2101 stretchTensor, dataAtPts->getVarLogStreachPts(), var_vec, MBTET));
2107 dataAtPts, ((do_rhs || do_lhs) && calc_rates) ? alphaOmega : 0.));
2112 fe->getOpPtrVector().push_back(physicalEquations->returnOpJacobian(
2113 tag, do_rhs, do_lhs, dataAtPts, physicalEquations));
2120 const int tag,
const bool add_elastic,
const bool add_material,
2121 boost::shared_ptr<VolumeElementForcesAndSourcesCore> &fe_rhs,
2122 boost::shared_ptr<VolumeElementForcesAndSourcesCore> &fe_lhs) {
2126 auto get_body_range = [
this](
auto name,
int dim) {
2127 std::map<int, Range> map;
2132 (boost::format(
"%s(.*)") % name).str()
2138 CHK_MOAB_THROW(m_ptr->getMeshsetIdEntitiesByDimension(mField.get_moab(),
2141 map[m_ptr->getMeshsetId()] = ents;
2147 auto rule_contact = [](
int,
int,
int o) {
return -1; };
2148 auto refine = Tools::refineTriangle(contactRefinementLevels);
2150 auto set_rule_contact = [refine](
2153 int order_col,
int order_data
2157 auto rule = 2 * order_data;
2158 fe_raw_ptr->
gaussPts = Tools::refineTriangleIntegrationPts(rule, refine);
2162 auto time_scale = boost::make_shared<DynamicRelaxationTimeScale>();
2165 fe_rhs = boost::make_shared<VolumeElementForcesAndSourcesCore>(mField);
2172 fe_rhs->getOpPtrVector().push_back(
2174 fe_rhs->getOpPtrVector().push_back(
2179 fe_rhs->getOpPtrVector().push_back(
2180 physicalEquations->returnOpSpatialPhysical(stretchTensor, dataAtPts,
2183 fe_rhs->getOpPtrVector().push_back(
2185 fe_rhs->getOpPtrVector().push_back(
2187 fe_rhs->getOpPtrVector().push_back(
2190 auto set_hybridisation = [&](
auto &pip) {
2203 mField, skeletonElement,
SPACE_DIM - 1, Sev::noisy);
2205 op_loop_skeleton_side->getSideFEPtr()->getRuleHook = [](
int,
int,
int) {
2208 op_loop_skeleton_side->getSideFEPtr()->setRuleHook =
2209 SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
2211 CHKERR EshelbianPlasticity::
2212 AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
2213 op_loop_skeleton_side->getOpPtrVector(), {L2},
2214 materialH1Positions, frontAdjEdges);
2218 auto broken_data_ptr =
2219 boost::make_shared<std::vector<BrokenBaseSideData>>();
2222 mField, elementVolumeName,
SPACE_DIM, Sev::noisy);
2223 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
2224 boost::make_shared<CGGUserPolynomialBase>();
2226 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
2227 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
2228 materialH1Positions, frontAdjEdges);
2229 op_loop_domain_side->getOpPtrVector().push_back(
2231 auto flux_mat_ptr = boost::make_shared<MatrixDouble>();
2232 op_loop_domain_side->getOpPtrVector().push_back(
2235 op_loop_domain_side->getOpPtrVector().push_back(
2239 op_loop_skeleton_side->getOpPtrVector().push_back(op_loop_domain_side);
2241 GAUSS>::OpBrokenSpaceConstrainDHybrid<SPACE_DIM>;
2243 GAUSS>::OpBrokenSpaceConstrainDFlux<SPACE_DIM>;
2244 op_loop_skeleton_side->getOpPtrVector().push_back(
new OpC_dHybrid(
2245 hybridSpatialDisp, broken_data_ptr, boost::make_shared<double>(1.0)));
2246 auto hybrid_ptr = boost::make_shared<MatrixDouble>();
2247 op_loop_skeleton_side->getOpPtrVector().push_back(
2250 op_loop_skeleton_side->getOpPtrVector().push_back(
new OpC_dBroken(
2251 broken_data_ptr, hybrid_ptr, boost::make_shared<double>(1.0)));
2254 pip.push_back(op_loop_skeleton_side);
2259 auto set_contact = [&](
auto &pip) {
2272 mField, contactElement,
SPACE_DIM - 1, Sev::noisy);
2274 op_loop_skeleton_side->getSideFEPtr()->getRuleHook = rule_contact;
2275 op_loop_skeleton_side->getSideFEPtr()->setRuleHook = set_rule_contact;
2276 CHKERR EshelbianPlasticity::
2277 AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
2278 op_loop_skeleton_side->getOpPtrVector(), {L2},
2279 materialH1Positions, frontAdjEdges);
2283 auto broken_data_ptr =
2284 boost::make_shared<std::vector<BrokenBaseSideData>>();
2287 auto contact_common_data_ptr =
2288 boost::make_shared<ContactOps::CommonData>();
2290 auto add_ops_domain_side = [&](
auto &pip) {
2294 mField, elementVolumeName,
SPACE_DIM, Sev::noisy);
2295 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
2296 boost::make_shared<CGGUserPolynomialBase>();
2298 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
2299 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
2300 materialH1Positions, frontAdjEdges);
2301 op_loop_domain_side->getOpPtrVector().push_back(
2304 op_loop_domain_side->getOpPtrVector().push_back(
2306 piolaStress, contact_common_data_ptr->contactTractionPtr()));
2307 pip.push_back(op_loop_domain_side);
2311 auto add_ops_contact_rhs = [&](
auto &pip) {
2314 auto contact_sfd_map_range_ptr =
2315 boost::make_shared<std::map<int, Range>>(
2316 get_body_range(
"CONTACT_SDF",
SPACE_DIM - 1));
2319 contactDisp, contact_common_data_ptr->contactDispPtr()));
2320 auto u_h1_ptr = boost::make_shared<MatrixDouble>();
2323 pip.push_back(
new OpTreeSearch(
2324 contactTreeRhs, contact_common_data_ptr, u_h1_ptr,
2328 contactDisp, contact_common_data_ptr, contactTreeRhs,
2329 contact_sfd_map_range_ptr));
2332 broken_data_ptr, contact_common_data_ptr, contactTreeRhs));
2338 CHKERR add_ops_domain_side(op_loop_skeleton_side->getOpPtrVector());
2339 CHKERR add_ops_contact_rhs(op_loop_skeleton_side->getOpPtrVector());
2342 pip.push_back(op_loop_skeleton_side);
2347 CHKERR set_hybridisation(fe_rhs->getOpPtrVector());
2348 CHKERR set_contact(fe_rhs->getOpPtrVector());
2351 using BodyNaturalBC =
2353 Assembly<PETSC>::LinearForm<
GAUSS>;
2355 BodyNaturalBC::OpFlux<NaturalMeshsetType<BLOCKSET>, 1, 3>;
2356 CHKERR BodyNaturalBC::AddFluxToPipeline<OpBodyForce>::add(
2357 fe_rhs->getOpPtrVector(), mField, spatialL2Disp, {time_scale},
2358 "BODY_FORCE", Sev::inform);
2362 fe_lhs = boost::make_shared<VolumeElementForcesAndSourcesCore>(mField);
2370 fe_lhs->getOpPtrVector().push_back(
2373 bubbleField, piolaStress, dataAtPts));
2374 fe_lhs->getOpPtrVector().push_back(
2378 fe_lhs->getOpPtrVector().push_back(
2379 physicalEquations->returnOpSpatialPhysical_du_du(
2380 stretchTensor, stretchTensor, dataAtPts, alphaU));
2382 stretchTensor, piolaStress, dataAtPts,
true));
2384 stretchTensor, bubbleField, dataAtPts,
true));
2386 stretchTensor, rotAxis, dataAtPts,
2387 symmetrySelector ==
SYMMETRIC ?
true :
false));
2391 spatialL2Disp, piolaStress, dataAtPts,
true));
2393 spatialL2Disp, spatialL2Disp, dataAtPts, alphaW, alphaRho));
2396 piolaStress, rotAxis, dataAtPts,
2397 symmetrySelector ==
SYMMETRIC ?
true :
false));
2399 bubbleField, rotAxis, dataAtPts,
2400 symmetrySelector ==
SYMMETRIC ?
true :
false));
2402 if (symmetrySelector ==
SYMMETRIC ?
false :
true) {
2404 rotAxis, stretchTensor, dataAtPts,
false));
2406 rotAxis, piolaStress, dataAtPts,
false));
2408 rotAxis, bubbleField, dataAtPts,
false));
2411 rotAxis, rotAxis, dataAtPts, alphaOmega));
2413 auto set_hybridisation = [&](
auto &pip) {
2426 mField, skeletonElement,
SPACE_DIM - 1, Sev::noisy);
2428 op_loop_skeleton_side->getSideFEPtr()->getRuleHook = [](
int,
int,
int) {
2431 op_loop_skeleton_side->getSideFEPtr()->setRuleHook =
2432 SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
2433 CHKERR EshelbianPlasticity::
2434 AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
2435 op_loop_skeleton_side->getOpPtrVector(), {L2},
2436 materialH1Positions, frontAdjEdges);
2440 auto broken_data_ptr =
2441 boost::make_shared<std::vector<BrokenBaseSideData>>();
2444 mField, elementVolumeName,
SPACE_DIM, Sev::noisy);
2445 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
2446 boost::make_shared<CGGUserPolynomialBase>();
2448 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
2449 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
2450 materialH1Positions, frontAdjEdges);
2451 op_loop_domain_side->getOpPtrVector().push_back(
2454 op_loop_skeleton_side->getOpPtrVector().push_back(op_loop_domain_side);
2456 GAUSS>::OpBrokenSpaceConstrain<SPACE_DIM>;
2457 op_loop_skeleton_side->getOpPtrVector().push_back(
2458 new OpC(hybridSpatialDisp, broken_data_ptr,
2459 boost::make_shared<double>(1.0),
true,
false));
2461 pip.push_back(op_loop_skeleton_side);
2466 auto set_contact = [&](
auto &pip) {
2479 mField, contactElement,
SPACE_DIM - 1, Sev::noisy);
2481 op_loop_skeleton_side->getSideFEPtr()->getRuleHook = rule_contact;
2482 op_loop_skeleton_side->getSideFEPtr()->setRuleHook = set_rule_contact;
2483 CHKERR EshelbianPlasticity::
2484 AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
2485 op_loop_skeleton_side->getOpPtrVector(), {L2},
2486 materialH1Positions, frontAdjEdges);
2490 auto broken_data_ptr =
2491 boost::make_shared<std::vector<BrokenBaseSideData>>();
2494 auto contact_common_data_ptr =
2495 boost::make_shared<ContactOps::CommonData>();
2497 auto add_ops_domain_side = [&](
auto &pip) {
2501 mField, elementVolumeName,
SPACE_DIM, Sev::noisy);
2502 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
2503 boost::make_shared<CGGUserPolynomialBase>();
2505 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
2506 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
2507 materialH1Positions, frontAdjEdges);
2508 op_loop_domain_side->getOpPtrVector().push_back(
2511 op_loop_domain_side->getOpPtrVector().push_back(
2513 piolaStress, contact_common_data_ptr->contactTractionPtr()));
2514 pip.push_back(op_loop_domain_side);
2518 auto add_ops_contact_lhs = [&](
auto &pip) {
2521 contactDisp, contact_common_data_ptr->contactDispPtr()));
2522 auto u_h1_ptr = boost::make_shared<MatrixDouble>();
2525 pip.push_back(
new OpTreeSearch(
2526 contactTreeRhs, contact_common_data_ptr, u_h1_ptr,
2531 auto contact_sfd_map_range_ptr =
2532 boost::make_shared<std::map<int, Range>>(
2533 get_body_range(
"CONTACT_SDF",
SPACE_DIM - 1));
2536 contactDisp, contactDisp, contact_common_data_ptr, contactTreeRhs,
2537 contact_sfd_map_range_ptr));
2540 contactDisp, broken_data_ptr, contact_common_data_ptr,
2541 contactTreeRhs, contact_sfd_map_range_ptr));
2544 broken_data_ptr, contactDisp, contact_common_data_ptr,
2551 CHKERR add_ops_domain_side(op_loop_skeleton_side->getOpPtrVector());
2552 CHKERR add_ops_contact_lhs(op_loop_skeleton_side->getOpPtrVector());
2555 pip.push_back(op_loop_skeleton_side);
2560 CHKERR set_hybridisation(fe_lhs->getOpPtrVector());
2561 CHKERR set_contact(fe_lhs->getOpPtrVector());
2571 const bool add_elastic,
const bool add_material,
2572 boost::shared_ptr<FaceElementForcesAndSourcesCore> &fe_rhs,
2573 boost::shared_ptr<FaceElementForcesAndSourcesCore> &fe_lhs) {
2576 fe_rhs = boost::make_shared<FaceElementForcesAndSourcesCore>(mField);
2577 fe_lhs = boost::make_shared<FaceElementForcesAndSourcesCore>(mField);
2582 fe_rhs->getRuleHook = [](
int,
int,
int) {
return -1; };
2583 fe_lhs->getRuleHook = [](
int,
int,
int) {
return -1; };
2584 fe_rhs->setRuleHook = SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
2585 fe_lhs->setRuleHook = SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
2588 EshelbianPlasticity::AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
2589 fe_rhs->getOpPtrVector(), {L2}, materialH1Positions, frontAdjEdges);
2591 EshelbianPlasticity::AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
2592 fe_lhs->getOpPtrVector(), {L2}, materialH1Positions, frontAdjEdges);
2596 auto get_broken_op_side = [
this](
auto &pip) {
2601 auto broken_data_ptr =
2602 boost::make_shared<std::vector<BrokenBaseSideData>>();
2605 mField, elementVolumeName,
SPACE_DIM, Sev::noisy);
2606 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
2607 boost::make_shared<CGGUserPolynomialBase>();
2609 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
2610 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
2611 materialH1Positions, frontAdjEdges);
2612 op_loop_domain_side->getOpPtrVector().push_back(
2614 boost::shared_ptr<double> piola_scale_ptr(
new double);
2615 op_loop_domain_side->getOpPtrVector().push_back(
2616 physicalEquations->returnOpSetScale(piola_scale_ptr,
2617 physicalEquations));
2618 pip.push_back(op_loop_domain_side);
2619 return std::make_pair(broken_data_ptr, piola_scale_ptr);
2622 auto [broken_data_ptr, piola_scale_ptr] =
2623 get_broken_op_side(fe_rhs->getOpPtrVector());
2625 fe_rhs->getOpPtrVector().push_back(
new OpDispBc(
2626 broken_data_ptr, bcSpatialDispVecPtr,
2629 boost::make_shared<DynamicRelaxationTimeScale>(
"disp_history.txt")
2632 fe_rhs->getOpPtrVector().push_back(
2633 new OpRotationBc(broken_data_ptr, bcSpatialRotationVecPtr,
2637 boost::make_shared<DynamicRelaxationTimeScale>(
2638 "rotation_history.txt")
2643 hybridSpatialDisp, bcSpatialTraction, piola_scale_ptr,
2645 {boost::make_shared<DynamicRelaxationTimeScale>(
"traction_history.txt")}
2655 boost::shared_ptr<ContactTree> &fe_contact_tree
2661 auto get_body_range = [
this](
auto name,
int dim,
auto sev) {
2662 std::map<int, Range> map;
2667 (boost::format(
"%s(.*)") % name).str()
2673 CHK_MOAB_THROW(m_ptr->getMeshsetIdEntitiesByDimension(mField.get_moab(),
2676 map[m_ptr->getMeshsetId()] = ents;
2677 MOFEM_LOG(
"EPSYNC", sev) <<
"Meshset: " << m_ptr->getMeshsetId() <<
" "
2678 << ents.size() <<
" entities";
2685 auto get_map_skin = [
this](
auto &&map) {
2686 ParallelComm *pcomm =
2689 Skinner skin(&mField.get_moab());
2690 for (
auto &
m : map) {
2692 CHKERR skin.find_skin(0,
m.second,
false, skin_faces);
2694 PSTATUS_SHARED | PSTATUS_MULTISHARED,
2695 PSTATUS_NOT, -1,
nullptr),
2697 m.second.swap(skin_faces);
2707 auto contact_common_data_ptr = boost::make_shared<ContactOps::CommonData>();
2709 auto calcs_side_traction = [&](
auto &pip) {
2715 mField, elementVolumeName,
SPACE_DIM, Sev::noisy);
2716 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
2717 boost::make_shared<CGGUserPolynomialBase>();
2718 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
2719 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
2720 materialH1Positions, frontAdjEdges);
2721 op_loop_domain_side->getOpPtrVector().push_back(
2723 piolaStress, contact_common_data_ptr->contactTractionPtr(),
2724 boost::make_shared<double>(1.0)));
2725 pip.push_back(op_loop_domain_side);
2729 auto add_contact_three = [&]() {
2731 auto tree_moab_ptr = boost::make_shared<moab::Core>();
2732 fe_contact_tree = boost::make_shared<ContactTree>(
2733 mField, tree_moab_ptr, spaceOrder,
2734 get_body_range(
"CONTACT",
SPACE_DIM - 1, Sev::inform));
2735 fe_contact_tree->getOpPtrVector().push_back(
2737 contactDisp, contact_common_data_ptr->contactDispPtr()));
2738 CHKERR calcs_side_traction(fe_contact_tree->getOpPtrVector());
2739 auto u_h1_ptr = boost::make_shared<MatrixDouble>();
2740 fe_contact_tree->getOpPtrVector().push_back(
2742 fe_contact_tree->getOpPtrVector().push_back(
2743 new OpMoveNode(fe_contact_tree, contact_common_data_ptr, u_h1_ptr));
2747 CHKERR add_contact_three();
2757 CHKERR setContactElementRhsOps(contactTreeRhs);
2759 CHKERR setVolumeElementOps(tag,
true,
false, elasticFeRhs, elasticFeLhs);
2760 CHKERR setFaceElementOps(
true,
false, elasticBcRhs, elasticBcLhs);
2763 boost::make_shared<ForcesAndSourcesCore::UserDataOperator::AdjCache>();
2765 auto get_op_contact_bc = [&]() {
2768 mField, contactElement,
SPACE_DIM - 1, Sev::noisy, adj_cache);
2769 return op_loop_side;
2777 boost::shared_ptr<FEMethod>
null;
2779 if (std::abs(alphaRho) > std::numeric_limits<double>::epsilon()) {
2811 bool set_ts_monitor) {
2814 auto setup_sdf = [&]() {
2815 boost::shared_ptr<ContactOps::SDFPython> sdf_python_ptr;
2817 auto file_exists = [](std::string myfile) {
2818 std::ifstream file(myfile.c_str());
2825 char sdf_file_name[255] =
"sdf.py";
2827 sdf_file_name, 255, PETSC_NULL);
2829 if (file_exists(sdf_file_name)) {
2830 MOFEM_LOG(
"EP", Sev::inform) << sdf_file_name <<
" file found";
2831 sdf_python_ptr = boost::make_shared<ContactOps::SDFPython>();
2832 CHKERR sdf_python_ptr->sdfInit(sdf_file_name);
2833 ContactOps::sdfPythonWeakPtr = sdf_python_ptr;
2835 MOFEM_LOG(
"EP", Sev::warning) << sdf_file_name <<
" file NOT found";
2837 return sdf_python_ptr;
2839 auto sdf_python_ptr = setup_sdf();
2842 auto setup_ts_monitor = [&]() {
2843 boost::shared_ptr<TsCtx>
ts_ctx;
2845 if (set_ts_monitor) {
2847 auto monitor_ptr = boost::make_shared<EshelbianMonitor>(*ep_ptr);
2851 return std::make_tuple(
ts_ctx);
2854 auto setup_snes_monitor = [&]() {
2857 CHKERR TSGetSNES(ts, &snes);
2858 PetscViewerAndFormat *vf;
2859 CHKERR PetscViewerAndFormatCreate(PETSC_VIEWER_STDOUT_WORLD,
2860 PETSC_VIEWER_DEFAULT, &vf);
2864 void *))SNESMonitorFields,
2869 auto setup_section = [&]() {
2870 PetscSection section_raw;
2873 CHKERR PetscSectionGetNumFields(section_raw, &num_fields);
2874 for (
int ff = 0; ff != num_fields; ff++) {
2882 auto set_vector_on_mesh = [&]() {
2886 CHKERR VecGhostUpdateBegin(x, INSERT_VALUES, SCATTER_FORWARD);
2887 CHKERR VecGhostUpdateEnd(x, INSERT_VALUES, SCATTER_FORWARD);
2891 auto setup_schur_block_solver = [&]() {
2892 CHKERR TSAppendOptionsPrefix(ts,
"elastic_");
2893 CHKERR TSSetFromOptions(ts);
2896 boost::shared_ptr<EshelbianCore::SetUpSchur> schur_ptr;
2909 return std::make_tuple(setup_sdf(), setup_ts_monitor(),
2910 setup_snes_monitor(), setup_section(),
2911 set_vector_on_mesh(), setup_schur_block_solver());
2913 return std::make_tuple(setup_ts_monitor(), setup_snes_monitor(),
2914 setup_section(), set_vector_on_mesh(),
2915 setup_schur_block_solver());
2923 PetscBool debug_model = PETSC_FALSE;
2927 if (debug_model == PETSC_TRUE) {
2929 auto post_proc = [&](TS ts, PetscReal
t,
Vec u,
Vec u_t,
Vec u_tt,
Vec F,
2934 CHKERR TSGetSNES(ts, &snes);
2936 CHKERR SNESGetIterationNumber(snes, &it);
2937 std::string file_name =
"snes_iteration_" + std::to_string(it) +
".h5m";
2938 CHKERR postProcessResults(1, file_name,
F);
2939 std::string file_skel_name =
2940 "snes_iteration_skel_" + std::to_string(it) +
".h5m";
2941 CHKERR postProcessSkeletonResults(1, file_skel_name,
F);
2945 ts_ctx_ptr->tsDebugHook = post_proc;
2950 if (std::abs(alphaRho) > std::numeric_limits<double>::epsilon()) {
2952 CHKERR VecDuplicate(x, &xx);
2953 CHKERR VecZeroEntries(xx);
2954 CHKERR TS2SetSolution(ts, x, xx);
2957 CHKERR TSSetSolution(ts, x);
2960 TetPolynomialBase::switchCacheBaseOn<HDIV>(
2961 {elasticFeLhs.get(), elasticFeRhs.get()});
2966 CHKERR TSSolve(ts, PETSC_NULL);
2968 TetPolynomialBase::switchCacheBaseOff<HDIV>(
2969 {elasticFeLhs.get(), elasticFeRhs.get()});
2972 CHKERR TSGetSNES(ts, &snes);
2973 int lin_solver_iterations;
2974 CHKERR SNESGetLinearSolveIterations(snes, &lin_solver_iterations);
2976 <<
"Number of linear solver iterations " << lin_solver_iterations;
2978 PetscBool test_cook_flg = PETSC_FALSE;
2981 if (test_cook_flg) {
2982 constexpr
int expected_lin_solver_iterations = 11;
2983 if (lin_solver_iterations > expected_lin_solver_iterations)
2986 "Expected number of iterations is different than expected %d > %d",
2987 lin_solver_iterations, expected_lin_solver_iterations);
3000 double final_time = 1;
3001 double delta_time = 0.1;
3003 PetscBool ts_h1_update = PETSC_FALSE;
3005 CHKERR PetscOptionsBegin(PETSC_COMM_WORLD,
"",
"Dynamic Relaxation Options",
3008 CHKERR PetscOptionsScalar(
"-dynamic_final_time",
3009 "dynamic relaxation final time",
"", final_time,
3010 &final_time, PETSC_NULL);
3011 CHKERR PetscOptionsScalar(
"-dynamic_delta_time",
3012 "dynamic relaxation final time",
"", delta_time,
3013 &delta_time, PETSC_NULL);
3014 CHKERR PetscOptionsInt(
"-dynamic_max_it",
"dynamic relaxation iterations",
"",
3015 max_it, &max_it, PETSC_NULL);
3016 CHKERR PetscOptionsBool(
"-dynamic_h1_update",
"update each ts step",
"",
3017 ts_h1_update, &ts_h1_update, PETSC_NULL);
3019 ierr = PetscOptionsEnd();
3022 auto setup_ts_monitor = [&]() {
3023 auto monitor_ptr = boost::make_shared<EshelbianMonitor>(*
this);
3026 auto monitor_ptr = setup_ts_monitor();
3028 TetPolynomialBase::switchCacheBaseOn<HDIV>(
3029 {elasticFeLhs.get(), elasticFeRhs.get()});
3033 double ts_delta_time;
3034 CHKERR TSGetTimeStep(ts, &ts_delta_time);
3046 monitor_ptr->ts_u = PETSC_NULL;
3047 monitor_ptr->ts_t = dynamicTime;
3048 monitor_ptr->ts_step = dynamicStep;
3050 MOFEM_LOG(
"EP", Sev::inform) <<
"IT " << dynamicStep <<
" Time "
3051 << dynamicTime <<
" delta time " << delta_time;
3052 dynamicTime += delta_time;
3055 for (; dynamicTime < final_time; dynamicTime += delta_time) {
3056 MOFEM_LOG(
"EP", Sev::inform) <<
"IT " << dynamicStep <<
" Time "
3057 << dynamicTime <<
" delta time " << delta_time;
3059 CHKERR TSSetStepNumber(ts, 0);
3061 CHKERR TSSetTimeStep(ts, ts_delta_time);
3062 if (!ts_h1_update) {
3065 CHKERR TSSolve(ts, PETSC_NULL);
3066 if (!ts_h1_update) {
3070 monitor_ptr->ts_u = PETSC_NULL;
3071 monitor_ptr->ts_t = dynamicTime;
3072 monitor_ptr->ts_step = dynamicStep;
3076 if (dynamicStep > max_it)
3081 TetPolynomialBase::switchCacheBaseOff<HDIV>(
3082 {elasticFeLhs.get(), elasticFeRhs.get()});
3090 auto set_block = [&](
auto name,
int dim) {
3091 std::map<int, Range> map;
3092 auto set_tag_impl = [&](
auto name) {
3097 std::regex((boost::format(
"%s(.*)") % name).str())
3100 for (
auto bc : bcs) {
3102 CHKERR bc->getMeshsetIdEntitiesByDimension(mField.get_moab(), dim,
r,
3104 map[bc->getMeshsetId()] =
r;
3109 CHKERR set_tag_impl(name);
3111 return std::make_pair(name, map);
3114 auto set_skin = [&](
auto &&map) {
3115 for (
auto &
m : map.second) {
3122 auto set_tag = [&](
auto &&map) {
3124 auto name = map.first;
3125 int def_val[] = {-1};
3127 mField.get_moab().tag_get_handle(name, 1, MB_TYPE_INTEGER,
th,
3128 MB_TAG_SPARSE | MB_TAG_CREAT, def_val),
3130 for (
auto &
m : map.second) {
3138 listTagsToTransfer.push_back(set_tag(set_skin(set_block(
"BODY", 3))));
3139 listTagsToTransfer.push_back(set_tag(set_skin(set_block(
"MAT_ELASTIC", 3))));
3140 listTagsToTransfer.push_back(
3141 set_tag(set_skin(set_block(
"MAT_NEOHOOKEAN", 3))));
3142 listTagsToTransfer.push_back(set_tag(set_block(
"CONTACT", 2)));
3149 Vec f_residual,
Vec var_vector,
3150 std::vector<Tag> tags_to_transfer) {
3156 rval = mField.get_moab().tag_get_handle(
"CRACK",
th);
3157 if (
rval == MB_SUCCESS) {
3158 CHKERR mField.get_moab().tag_delete(
th);
3160 int def_val[] = {0};
3161 CHKERR mField.get_moab().tag_get_handle(
3162 "CRACK", 1, MB_TYPE_INTEGER,
th, MB_TAG_SPARSE | MB_TAG_CREAT, def_val);
3164 CHKERR mField.get_moab().tag_clear_data(
th, *crackFaces, mark);
3165 tags_to_transfer.push_back(
th);
3169 for (
auto t : listTagsToTransfer) {
3170 tags_to_transfer.push_back(
t);
3175 boost::shared_ptr<DataAtIntegrationPts>(
new DataAtIntegrationPts());
3180 auto get_post_proc = [&](
auto &post_proc_mesh,
auto sense) {
3182 auto post_proc_ptr =
3183 boost::make_shared<PostProcBrokenMeshInMoabBaseCont<FaceEle>>(
3184 mField, post_proc_mesh);
3185 EshelbianPlasticity::AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
3186 post_proc_ptr->getOpPtrVector(), {L2}, materialH1Positions,
3189 auto domain_ops = [&](
auto &fe,
int sense) {
3191 fe.getUserPolynomialBase() =
3192 boost::shared_ptr<BaseFunction>(
new CGGUserPolynomialBase());
3193 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
3194 fe.getOpPtrVector(), {HDIV, H1, L2}, materialH1Positions,
3196 auto piola_scale_ptr = boost::make_shared<double>(1.0);
3197 fe.getOpPtrVector().push_back(physicalEquations->returnOpSetScale(
3198 piola_scale_ptr, physicalEquations));
3200 piolaStress, dataAtPts->getApproxPAtPts(), piola_scale_ptr));
3202 bubbleField, dataAtPts->getApproxPAtPts(), piola_scale_ptr,
3205 fe.getOpPtrVector().push_back(
3206 physicalEquations->returnOpCalculateStretchFromStress(
3207 dataAtPts, physicalEquations));
3209 fe.getOpPtrVector().push_back(
3211 stretchTensor, dataAtPts->getLogStretchTensorAtPts(), MBTET));
3216 piolaStress, dataAtPts->getVarPiolaPts(),
3217 boost::make_shared<double>(1), vec));
3219 bubbleField, dataAtPts->getVarPiolaPts(),
3220 boost::make_shared<double>(1), vec, MBMAXTYPE));
3222 rotAxis, dataAtPts->getVarRotAxisPts(), vec, MBTET));
3224 fe.getOpPtrVector().push_back(
3225 physicalEquations->returnOpCalculateVarStretchFromStress(
3226 dataAtPts, physicalEquations));
3228 fe.getOpPtrVector().push_back(
3230 stretchTensor, dataAtPts->getVarLogStreachPts(), vec, MBTET));
3235 rotAxis, dataAtPts->getRotAxisAtPts(), MBTET));
3237 rotAxis, dataAtPts->getRotAxis0AtPts(), solTSStep, MBTET));
3240 spatialL2Disp, dataAtPts->getSmallWL2AtPts(), MBTET));
3242 spatialH1Disp, dataAtPts->getSmallWH1AtPts()));
3244 spatialH1Disp, dataAtPts->getSmallWGradH1AtPts()));
3246 fe.getOpPtrVector().push_back(
3250 fe.getOpPtrVector().push_back(physicalEquations->returnOpJacobian(
3251 tag,
true,
false, dataAtPts, physicalEquations));
3253 physicalEquations->returnOpCalculateEnergy(dataAtPts,
nullptr)) {
3254 fe.getOpPtrVector().push_back(op);
3263 struct OpSidePPMap :
public OpPPMap {
3265 std::vector<EntityHandle> &map_gauss_pts,
3266 DataMapVec data_map_scalar, DataMapMat data_map_vec,
3267 DataMapMat data_map_mat, DataMapMat data_symm_map_mat,
3269 :
OpPPMap(post_proc_mesh, map_gauss_pts, data_map_scalar,
3270 data_map_vec, data_map_mat, data_symm_map_mat),
3277 if (tagSense != OpPPMap::getSkeletonSense())
3289 vec_fields[
"SpatialDisplacementL2"] = dataAtPts->getSmallWL2AtPts();
3290 vec_fields[
"SpatialDisplacementH1"] = dataAtPts->getSmallWH1AtPts();
3291 vec_fields[
"Omega"] = dataAtPts->getRotAxisAtPts();
3292 vec_fields[
"ContactDisplacement"] = dataAtPts->getContactL2AtPts();
3293 vec_fields[
"AngularMomentum"] = dataAtPts->getLeviKirchhoffAtPts();
3294 vec_fields[
"X"] = dataAtPts->getLargeXH1AtPts();
3297 vec_fields[
"VarOmega"] = dataAtPts->getVarRotAxisPts();
3298 vec_fields[
"VarSpatialDisplacementL2"] =
3299 boost::make_shared<MatrixDouble>();
3301 spatialL2Disp, vec_fields[
"VarSpatialDisplacementL2"], vec, MBTET));
3305 vec_fields[
"ResSpatialDisplacementL2"] =
3306 boost::make_shared<MatrixDouble>();
3308 spatialL2Disp, vec_fields[
"ResSpatialDisplacementL2"], vec, MBTET));
3309 vec_fields[
"ResOmega"] = boost::make_shared<MatrixDouble>();
3311 rotAxis, vec_fields[
"ResOmega"], vec, MBTET));
3315 mat_fields[
"PiolaStress"] = dataAtPts->getApproxPAtPts();
3317 mat_fields[
"VarPiolaStress"] = dataAtPts->getVarPiolaPts();
3321 mat_fields[
"ResPiolaStress"] = boost::make_shared<MatrixDouble>();
3323 piolaStress, mat_fields[
"ResPiolaStress"],
3324 boost::make_shared<double>(1), vec));
3326 bubbleField, mat_fields[
"ResPiolaStress"],
3327 boost::make_shared<double>(1), vec, MBMAXTYPE));
3331 mat_fields_symm[
"LogSpatialStretch"] =
3332 dataAtPts->getLogStretchTensorAtPts();
3333 mat_fields_symm[
"SpatialStretch"] = dataAtPts->getStretchTensorAtPts();
3335 mat_fields_symm[
"VarLogSpatialStretch"] =
3336 dataAtPts->getVarLogStreachPts();
3341 mat_fields_symm[
"ResLogSpatialStretch"] =
3342 boost::make_shared<MatrixDouble>();
3343 fe.getOpPtrVector().push_back(
3345 stretchTensor, mat_fields_symm[
"ResLogSpatialStretch"], vec,
3350 fe.getOpPtrVector().push_back(
3354 post_proc_ptr->getPostProcMesh(), post_proc_ptr->getMapGaussPts(),
3371 post_proc_ptr->getPostProcMesh(), post_proc_ptr->getMapGaussPts(),
3377 post_proc_ptr->getOpPtrVector().push_back(
3379 dataAtPts->getContactL2AtPts()));
3380 auto X_h1_ptr = boost::make_shared<MatrixDouble>();
3382 post_proc_ptr->getOpPtrVector().push_back(
3384 dataAtPts->getLargeXH1AtPts()));
3389 domain_ops(*(op_loop_side->getSideFEPtr()), sense);
3390 post_proc_ptr->getOpPtrVector().push_back(op_loop_side);
3392 return post_proc_ptr;
3396 auto calcs_side_traction_and_displacements = [&](
auto &post_proc_ptr,
3399 auto contact_common_data_ptr = boost::make_shared<ContactOps::CommonData>();
3405 mField, elementVolumeName,
SPACE_DIM, Sev::noisy);
3406 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
3407 boost::shared_ptr<BaseFunction>(
new CGGUserPolynomialBase());
3408 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
3409 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
3410 materialH1Positions, frontAdjEdges);
3411 op_loop_domain_side->getOpPtrVector().push_back(
3413 piolaStress, contact_common_data_ptr->contactTractionPtr(),
3414 boost::make_shared<double>(1.0)));
3415 pip.push_back(op_loop_domain_side);
3417 auto u_h1_ptr = boost::make_shared<MatrixDouble>();
3420 contactDisp, contact_common_data_ptr->contactDispPtr()));
3421 pip.push_back(
new OpTreeSearch(
3422 contactTreeRhs, contact_common_data_ptr, u_h1_ptr,
3424 &post_proc_ptr->getPostProcMesh(), &post_proc_ptr->getMapGaussPts()));
3428 auto post_proc_mesh = boost::make_shared<moab::Core>();
3429 auto post_proc_ptr = get_post_proc(post_proc_mesh, 1);
3430 auto post_proc_negative_sense_ptr = get_post_proc(post_proc_mesh, -1);
3431 CHKERR calcs_side_traction_and_displacements(post_proc_ptr,
3432 post_proc_ptr->getOpPtrVector());
3435 CommInterface::getPartEntities(mField.get_moab(), mField.get_comm_rank())
3438 CHKERR mField.get_moab().get_adjacencies(own_tets,
SPACE_DIM - 1,
true,
3439 own_faces, moab::Interface::UNION);
3441 auto get_post_negative = [&](
auto &&ents) {
3442 auto crack_faces_pos = ents;
3443 auto crack_faces_neg = crack_faces_pos;
3444 auto skin =
get_skin(mField, own_tets);
3445 auto crack_on_proc_skin = intersect(crack_faces_pos, skin);
3446 for (
auto f : crack_on_proc_skin) {
3449 tet = intersect(tet, own_tets);
3450 int side_number, sense, offset;
3451 CHKERR mField.get_moab().side_number(tet[0],
f, side_number, sense,
3454 crack_faces_neg.erase(
f);
3456 crack_faces_pos.erase(
f);
3459 return std::make_pair(crack_faces_pos, crack_faces_neg);
3462 auto get_crack_faces = [&](
auto crack_faces) {
3463 auto get_adj = [&](
auto e,
auto dim) {
3465 CHKERR mField.get_moab().get_adjacencies(e, dim,
true, adj,
3466 moab::Interface::UNION);
3469 auto tets = get_adj(crack_faces, 3);
3470 auto faces = subtract(get_adj(tets, 2), crack_faces);
3471 tets = subtract(tets, get_adj(faces, 3));
3472 return subtract(crack_faces, get_adj(tets, 2));
3475 auto [crack_faces_pos, crack_faces_neg] =
3476 get_post_negative(intersect(own_faces, get_crack_faces(*crackFaces)));
3478 auto only_crack_faces = [&](
FEMethod *fe_method_ptr) {
3479 auto ent = fe_method_ptr->getFEEntityHandle();
3480 if (crack_faces_pos.find(ent) == crack_faces_pos.end()) {
3486 auto only_negative_crack_faces = [&](
FEMethod *fe_method_ptr) {
3487 auto ent = fe_method_ptr->getFEEntityHandle();
3488 if (crack_faces_neg.find(ent) == crack_faces_neg.end()) {
3494 auto get_adj_front = [&]() {
3495 auto skeleton_faces = *skeletonFaces;
3497 CHKERR mField.get_moab().get_adjacencies(*frontEdges, 2,
true, adj_front,
3498 moab::Interface::UNION);
3500 adj_front = intersect(adj_front, skeleton_faces);
3501 adj_front = subtract(adj_front, *crackFaces);
3502 adj_front = intersect(own_faces, adj_front);
3506 post_proc_ptr->setTagsToTransfer(tags_to_transfer);
3507 post_proc_negative_sense_ptr->setTagsToTransfer(tags_to_transfer);
3509 auto post_proc_begin =
3513 post_proc_ptr->exeTestHook = only_crack_faces;
3514 post_proc_negative_sense_ptr->exeTestHook = only_negative_crack_faces;
3516 dM, skeletonElement, post_proc_ptr, 0, mField.get_comm_size());
3518 post_proc_negative_sense_ptr, 0,
3519 mField.get_comm_size());
3521 constexpr
bool debug =
false;
3524 auto [adj_front_pos, adj_front_neg] =
3527 auto only_front_faces_pos = [adj_front_pos](
FEMethod *fe_method_ptr) {
3528 auto ent = fe_method_ptr->getFEEntityHandle();
3529 if (adj_front_pos.find(ent) == adj_front_pos.end()) {
3535 auto only_front_faces_neg = [adj_front_neg](
FEMethod *fe_method_ptr) {
3536 auto ent = fe_method_ptr->getFEEntityHandle();
3537 if (adj_front_neg.find(ent) == adj_front_neg.end()) {
3543 post_proc_ptr->exeTestHook = only_front_faces_pos;
3545 dM, skeletonElement, post_proc_ptr, 0, mField.get_comm_size());
3546 post_proc_negative_sense_ptr->exeTestHook = only_front_faces_neg;
3548 post_proc_negative_sense_ptr, 0,
3549 mField.get_comm_size());
3554 CHKERR post_proc_end.writeFile(file.c_str());
3559 const std::string file,
3565 auto post_proc_mesh = boost::make_shared<moab::Core>();
3566 auto post_proc_ptr =
3567 boost::make_shared<PostProcBrokenMeshInMoabBaseCont<FaceEle>>(
3568 mField, post_proc_mesh);
3569 EshelbianPlasticity::AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
3570 post_proc_ptr->getOpPtrVector(), {L2}, materialH1Positions,
3573 auto hybrid_disp = boost::make_shared<MatrixDouble>();
3574 post_proc_ptr->getOpPtrVector().push_back(
3577 auto hybrid_res = boost::make_shared<MatrixDouble>();
3578 post_proc_ptr->getOpPtrVector().push_back(
3582 post_proc_ptr->getOpPtrVector().push_back(
3586 post_proc_ptr->getPostProcMesh(), post_proc_ptr->getMapGaussPts(),
3590 {{
"hybrid_disp", hybrid_disp}},
3601 auto hybrid_res = boost::make_shared<MatrixDouble>();
3602 post_proc_ptr->getOpPtrVector().push_back(
3604 hybridSpatialDisp, hybrid_res,
3607 post_proc_ptr->getOpPtrVector().push_back(
3611 post_proc_ptr->getPostProcMesh(), post_proc_ptr->getMapGaussPts(),
3615 {{
"res_hybrid", hybrid_res}},
3626 auto post_proc_begin =
3633 CHKERR post_proc_end.writeFile(file.c_str());
3642 constexpr
bool debug =
true;
3663 auto get_tags_vec = [&]() {
3664 std::vector<Tag> tags(1);
3666 auto create_and_clean = [&]() {
3669 auto rval = moab.tag_get_handle(
"ReleaseEnergy", tags[0]);
3670 if (
rval == MB_SUCCESS) {
3671 moab.tag_delete(tags[0]);
3673 double def_val[] = {0};
3674 CHKERR moab.tag_get_handle(
"ReleaseEnergy", 1, MB_TYPE_DOUBLE, tags[0],
3675 MB_TAG_CREAT | MB_TAG_SPARSE, def_val);
3684 auto tags = get_tags_vec();
3686 auto get_adj_front = [&]() {
3690 moab::Interface::UNION);
3692 adj_front = intersect(adj_front, skeleton_faces);
3693 adj_front = subtract(adj_front, *
crackFaces);
3697 auto get_nb_front_faces_on_proc = [&](
auto &&adj_front) {
3698 int send_size = adj_front.size();
3700 MPI_Allgather(&send_size, 1, MPI_INT, recv_data.data(), 1, MPI_INT,
3703 return std::pair(recv_data, adj_front);
3706 auto get_snes = [&](TS ts) {
3708 CHKERR TSGetSNES(ts, &snes);
3712 auto get_ksp = [&](SNES snes) {
3714 CHKERR SNESGetKSP(snes, &ksp);
3715 CHKERR KSPSetFromOptions(ksp);
3719 auto integrate_energy = [&](
auto x,
auto release_energy_ptr) {
3721 auto set_volume = [&]() {
3723 boost::make_shared<VolumeElementForcesAndSourcesCore>(
mField);
3724 fe_ptr->ts_ctx = TSMethod::CTX_TSSETIJACOBIAN;
3726 fe_ptr->getOpPtrVector().push_back(
3734 auto calc_release_energy = [&](
auto t,
auto &&tuple_of_vectors,
3735 auto adj_front,
double &energy,
double &area) {
3737 MOFEM_LOG(
"EP", Sev::inform) <<
"Calculate face release energy";
3740 auto copy_is = [&](
auto is,
auto a,
auto b) {
3742 const PetscInt *is_array;
3744 CHKERR ISGetLocalSize(is, &is_size);
3745 CHKERR ISGetIndices(is, &is_array);
3749 CHKERR VecGetArrayRead(b, &pb);
3750 for (
int i = 0;
i != is_size; ++
i) {
3751 pa[is_array[
i]] = pb[is_array[
i]];
3753 CHKERR VecRestoreArrayRead(b, &pb);
3754 CHKERR VecRestoreArray(
a, &pa);
3755 CHKERR ISRestoreIndices(is, &is_array);
3759 auto axpy_is = [&](
auto is,
double alpha,
auto a,
auto b) {
3761 const PetscInt *is_array;
3763 CHKERR ISGetLocalSize(is, &is_size);
3764 CHKERR ISGetIndices(is, &is_array);
3768 CHKERR VecGetArrayRead(b, &pb);
3769 for (
int i = 0;
i != is_size; ++
i) {
3770 pa[is_array[
i]] += alpha * pb[is_array[
i]];
3772 CHKERR VecRestoreArrayRead(b, &pb);
3773 CHKERR VecRestoreArray(
a, &pa);
3774 CHKERR ISRestoreIndices(is, &is_array);
3778 auto zero_is = [&](
auto is,
auto a) {
3780 const PetscInt *is_array;
3782 CHKERR ISGetLocalSize(is, &is_size);
3783 CHKERR ISGetIndices(is, &is_array);
3786 for (
int i = 0;
i != is_size; ++
i) {
3787 pa[is_array[
i]] = 0;
3789 CHKERR VecRestoreArray(
a, &pa);
3790 CHKERR ISRestoreIndices(is, &is_array);
3794 auto estimate_energy = [&](
auto x) {
3795 auto release_energy_ptr = boost::make_shared<double>(0);
3797 "integrate_energy");
3803 area += t_normal.
l2() / 2;
3806 std::array<double, 2> send_data{area, *release_energy_ptr};
3807 std::array<double, 2> recv_data{0, 0};
3809 MPI_Allreduce(send_data.data(), recv_data.data(), 2, MPI_DOUBLE, MPI_SUM,
3811 return std::pair(recv_data[1], recv_data[0]);
3814 auto set_tag = [&](
auto &&release_energy,
auto adj_front) {
3817 MOFEM_LOG(
"EP", Sev::inform) <<
"Energy release " << release_energy;
3819 CHKERR moab.tag_clear_data(tags[0], own, &release_energy);
3823 auto solve = [&]() {
3826 auto [x,
f] = tuple_of_vectors;
3829 auto ksp = get_ksp(get_snes(ts));
3830 CHKERR KSPGetOperators(ksp, &mA, PETSC_NULL);
3835 std::vector<boost::weak_ptr<NumeredDofEntity>> piola_skelton_dofs_vec;
3837 ->getSideDofsOnBrokenSpaceEntities(
3842 ->isCreateProblemBrokenFieldAndRankLocal(piola_skelton_dofs_vec,
3843 skeleton_piola_is_local);
3846 ->isCreateProblemBrokenFieldAndRank(piola_skelton_dofs_vec,
3847 skeleton_piola_is_global);
3852 skeleton_hybrid_is_local, &faces);
3856 skeleton_hybrid_is_global, &faces);
3858 CHKERR VecZeroEntries(x);
3859 CHKERR copy_is(skeleton_piola_is_local, x,
t);
3861 CHKERR zero_is(skeleton_piola_is_local,
f);
3862 CHKERR zero_is(skeleton_hybrid_is_local,
f);
3866 std::vector<double> save_mat_storage(*mat_storage);
3867 std::vector<double> save_mat_precon_storage(*mat_precon_storage);
3869 CHKERR MatZeroRowsColumnsIS(mA, skeleton_piola_is_global, 1, PETSC_NULL,
3871 CHKERR MatZeroRowsColumnsIS(mA, skeleton_hybrid_is_global, 1, PETSC_NULL,
3874 PetscBool factor_schur = PETSC_FALSE;
3876 &factor_schur, PETSC_NULL);
3877 if (factor_schur == PETSC_TRUE) {
3881 schur_skeleton_hybrid_is, &faces);
3886 CHKERR MatAssemblyBegin(
S, MAT_FINAL_ASSEMBLY);
3887 CHKERR MatAssemblyEnd(
S, MAT_FINAL_ASSEMBLY);
3888 CHKERR MatZeroRowsColumnsIS(
S, schur_skeleton_hybrid_is, 1, PETSC_NULL,
3892 CHKERR copy_is(skeleton_piola_is_local,
f,
t);
3896 CHKERR VecGhostUpdateBegin(x, INSERT_VALUES, SCATTER_FORWARD);
3897 CHKERR VecGhostUpdateEnd(x, INSERT_VALUES, SCATTER_FORWARD);
3899 std::copy(save_mat_storage.begin(), save_mat_storage.end(),
3900 mat_storage->begin());
3901 std::copy(save_mat_precon_storage.begin(), save_mat_precon_storage.end(),
3902 mat_precon_storage->begin());
3908 auto [x,
f] = tuple_of_vectors;
3909 std::tie(energy, area) = estimate_energy(x);
3910 CHKERR set_tag(energy, adj_front);
3915 auto run_faces = [&](
auto &&p) {
3916 auto [recv_data, adj_front] = p;
3922 std::map<int, std::tuple<double, double, Range, SmartPetscObj<Vec>>>
3925 auto solve_and_add = [&](
auto &&face,
auto id) {
3930 double energy, area;
3932 std::make_tuple(face_x, face_f),
3933 face, energy, area);
3935 if (release_by_energy.find(
id) == release_by_energy.end()) {
3937 CHKERR VecCopy(face_x, vec);
3938 release_by_energy[id] = std::make_tuple(energy, area, face, vec);
3940 auto [e,
a, faces, vec] = release_by_energy.at(
id);
3942 CHKERR VecCopy(face_x, vec);
3944 release_by_energy[id] = std::make_tuple(energy, area, faces, vec);
3951 ParallelComm *pcomm =
3955 for (
auto f = 0;
f < recv_data[p]; ++
f) {
3959 MOFEM_LOG(
"SYNC", Sev::noisy) <<
"edge id " << id;
3960 solve_and_add(
Range(),
id);
3964 auto face =
Range(adj_front[
f], adj_front[
f]);
3967 moab::Interface::UNION),
3972 CHK_MOAB_THROW(pcomm->get_owner_handle(edges[0], owner, owner_handle),
3977 MOFEM_LOG(
"SYNC", Sev::noisy) <<
"owner " << owner <<
"edge id " << id;
3978 solve_and_add(face,
id);
3981 for (
auto f = 0;
f < recv_data[p]; ++
f) {
3985 MOFEM_LOG(
"SYNC", Sev::noisy) <<
"edge id " << id;
3986 solve_and_add(
Range(),
id);
3991 return release_by_energy;
3994 auto release_by_energy = run_faces(
4000 std::map<double, std::tuple<double, EntityHandle, Range, SmartPetscObj<Vec>>>
4001 sorted_release_by_energy;
4003 for (
auto &
m : release_by_energy) {
4004 auto [energy, area, faces, vec] =
m.second;
4005 sorted_release_by_energy[energy] =
4006 std::make_tuple(area,
m.first, faces, vec);
4009 double total_area = 0;
4010 double total_energy_sum = 0;
4014 CHKERR VecZeroEntries(x);
4015 for (
auto m = sorted_release_by_energy.rbegin();
4016 m != sorted_release_by_energy.rend(); ++
m) {
4017 auto [area, id, faces, vec] =
m->second;
4019 CHKERR VecAXPY(x, 1., vec);
4020 CHKERR VecGhostUpdateBegin(x, INSERT_VALUES, SCATTER_FORWARD);
4021 CHKERR VecGhostUpdateEnd(x, INSERT_VALUES, SCATTER_FORWARD);
4022 auto release_energy_ptr = boost::make_shared<double>(0);
4023 CHKERR integrate_energy(x, release_energy_ptr);
4024 std::array<double, 2> send_data{area, *release_energy_ptr};
4025 std::array<double, 2> recv_data{0, 0};
4026 MPI_Allreduce(send_data.data(), recv_data.data(), 2, MPI_DOUBLE, MPI_SUM,
4028 if (recv_data[1] < total_energy_sum) {
4029 CHKERR VecAXPY(x, -1., vec);
4030 double release_energy = 0;
4033 total_energy_sum = recv_data[1];
4034 total_area += recv_data[0];
4037 <<
"Aggregated energy release " << total_area <<
" " << recv_data[1];
4049 for (
auto f : skin) {
4052 if (tet.size() != 1) {
4053 MOFEM_LOG(
"EP", Sev::error) <<
"tet.size()!=1";
4056 double release_energy;
4058 release_energy /= total_energy_sum;
4069 bool set_orientation) {
4072 constexpr
bool debug =
true;
4073 constexpr
auto sev = Sev::inform;
4076 Range geometry_edges_verts;
4078 geometry_edges_verts,
true);
4079 Range crack_faces_verts;
4082 Range crack_faces_edges;
4084 *
crackFaces, 1,
true, crack_faces_edges, moab::Interface::UNION);
4086 auto get_tags_vec = [&](
auto tag_name,
int dim) {
4087 std::vector<Tag> tags(1);
4092 auto create_and_clean = [&]() {
4095 auto rval = moab.tag_get_handle(tag_name, tags[0]);
4096 if (
rval == MB_SUCCESS) {
4097 moab.tag_delete(tags[0]);
4099 double def_val[] = {0., 0., 0.};
4100 CHKERR moab.tag_get_handle(tag_name, dim, MB_TYPE_DOUBLE, tags[0],
4101 MB_TAG_CREAT | MB_TAG_SPARSE, def_val);
4110 auto get_adj_front = [&](
bool subtract_crack) {
4113 adj_front, moab::Interface::UNION);
4115 adj_front = subtract(adj_front, *
crackFaces);
4121 auto th_front_position = get_tags_vec(
"FrontPosition", 3);
4122 auto th_max_face_energy = get_tags_vec(
"MaxFaceEnergy", 1);
4126 auto get_crack_adj_tets = [&](
auto r) {
4127 Range crack_faces_conn;
4129 Range crack_faces_conn_tets;
4131 true, crack_faces_conn_tets,
4132 moab::Interface::UNION);
4133 return crack_faces_conn_tets;
4136 auto get_layers_for_sides = [&](
auto &side) {
4137 std::vector<Range> layers;
4141 auto get_adj = [&](
auto &
r,
int dim) {
4144 moab::Interface::UNION);
4148 auto get_tets = [&](
auto r) {
return get_adj(
r,
SPACE_DIM); };
4153 Range front_faces = get_adj(front_nodes, 2);
4154 front_faces = subtract(front_faces, *
crackFaces);
4155 auto front_tets = get_tets(front_nodes);
4156 auto front_side = intersect(side, front_tets);
4157 layers.push_back(front_side);
4160 adj_faces = intersect(adj_faces, front_faces);
4161 auto adj_faces_tets = get_tets(adj_faces);
4162 adj_faces_tets = intersect(adj_faces_tets, front_tets);
4163 layers.push_back(unite(layers.back(), adj_faces_tets));
4164 if (layers.back().size() == layers[layers.size() - 2].size()) {
4175 auto layers_top = get_layers_for_sides(sides_pair.first);
4176 auto layers_bottom = get_layers_for_sides(sides_pair.second);
4188 MOFEM_LOG(
"SELF", sev) <<
"Nb. layers " << layers_top.size();
4190 for (
auto &
r : layers_top) {
4191 MOFEM_LOG(
"SELF", sev) <<
"Layer " <<
l <<
" size " <<
r.size();
4194 "layers_top_" + boost::lexical_cast<std::string>(
l) +
".vtk",
r);
4199 for (
auto &
r : layers_bottom) {
4200 MOFEM_LOG(
"SELF", sev) <<
"Layer " <<
l <<
" size " <<
r.size();
4203 "layers_bottom_" + boost::lexical_cast<std::string>(
l) +
".vtk",
r);
4209 auto get_cross = [&](
auto t_dir,
auto f) {
4221 auto get_sense = [&](
auto f,
auto e) {
4222 int side, sense, offset;
4225 return std::make_tuple(side, sense, offset);
4228 auto calculate_edge_direction = [&](
auto e) {
4232 std::array<double, 6> coords;
4235 &coords[0], &coords[1], &coords[2]};
4237 &coords[3], &coords[4], &coords[5]};
4240 t_dir(
i) = t_p1(
i) - t_p0(
i);
4241 auto l = t_dir.
l2();
4246 auto evaluate_face_energy_and_set_orientation = [&](
auto front_edges,
4261 auto find_maximal_face_energy = [&](
auto front_edges,
auto front_faces,
4262 auto &edge_face_max_energy_map) {
4264 for (
auto e : front_edges) {
4267 faces = intersect(faces, front_faces);
4269 std::vector<double> face_energy(faces.size());
4271 face_energy.data());
4272 auto max_energy_it =
4273 std::max_element(face_energy.begin(), face_energy.end());
4275 max_energy_it != face_energy.end() ? *max_energy_it : 0;
4278 edge_face_max_energy_map[e] =
4279 std::make_tuple(faces[max_energy_it - face_energy.begin()],
4280 max_energy,
static_cast<double>(0));
4282 <<
"Edge " << e <<
" max energy " << max_energy;
4292 auto calculate_face_orientation = [&](
auto &edge_face_max_energy_map) {
4295 auto up_down_face = [&](
4297 auto &face_angle_map_up,
4298 auto &face_angle_map_down
4303 for (
auto &
m : edge_face_max_energy_map) {
4305 auto [max_face, energy, opt_angle] =
m.second;
4309 faces = intersect(faces, front_faces);
4313 moab::Interface::UNION);
4314 if (adj_tets.size()) {
4319 moab::Interface::UNION);
4320 if (adj_tets.size()) {
4322 Range adj_tets_faces;
4325 adj_tets,
SPACE_DIM - 1,
false, adj_tets_faces,
4326 moab::Interface::UNION);
4327 adj_tets_faces = intersect(adj_tets_faces, faces);
4328 if (adj_tets_faces.size() != 3 && adj_tets_faces.size() != 2) {
4330 <<
"Wrong number of crack faces " << adj_tets_faces.size()
4331 <<
" " << adj_tets.size();
4333 "Wrong number of crack faces");
4340 get_cross(calculate_edge_direction(e), max_face);
4341 auto [side_max, sense_max, offset_max] = get_sense(max_face, e);
4342 t_cross_max(
i) *= sense_max;
4344 for (
auto t : adj_tets) {
4345 Range adj_tets_faces;
4347 &
t, 1,
SPACE_DIM - 1,
false, adj_tets_faces);
4348 adj_tets_faces = intersect(adj_tets_faces, faces);
4350 subtract(adj_tets_faces,
Range(max_face, max_face));
4352 if (adj_tets_faces.size() == 1) {
4356 auto t_cross = get_cross(calculate_edge_direction(e),
4358 auto [side, sense, offset] =
4359 get_sense(adj_tets_faces[0], e);
4360 t_cross(
i) *= sense;
4361 double dot = t_cross(
i) * t_cross_max(
i);
4362 auto angle = std::acos(dot);
4366 th_face_energy, adj_tets_faces, &energy);
4368 auto [side_face, sense_face, offset_face] =
4369 get_sense(
t, max_face);
4371 if (sense_face > 0) {
4372 face_angle_map_up[e] =
4373 std::make_tuple(energy, angle, adj_tets_faces[0]);
4376 face_angle_map_down[e] =
4377 std::make_tuple(energy, -angle, adj_tets_faces[0]);
4391 auto calc_optimal_angle_impl = [&](
double a0,
double e0,
double a1,
4392 double e1,
double a2,
double e2) {
4409 if (b[0] > -std::numeric_limits<float>::epsilon()) {
4410 return std::make_pair(e0, 0.);
4414 auto optimal_angle = -b[1] / (2 * b[0]);
4415 auto optimal_energy = b[0] * optimal_angle * optimal_angle +
4416 b[1] * optimal_angle + b[2];
4421 <<
"Optimal_energy " << optimal_energy <<
" ( " << e0 <<
" "
4422 << (optimal_energy - e0) / e0 <<
"% ) " << optimal_angle
4423 <<
" e1 : a1 " << e1 <<
" : " <<
a1 <<
" e2 : a2 " << e2
4426 double angle = -M_PI;
4427 for (
double a = -M_PI;
a < M_PI;
a += M_PI / 20.) {
4428 double energy = b[0] *
a *
a + b[1] *
a + b[2];
4429 MOFEM_LOG(
"SELF", sev) <<
"PlotAngles " <<
a <<
" " << energy;
4431 MOFEM_LOG(
"SELF", sev) <<
"PlotAngles " << endl;
4433 MOFEM_LOG(
"SELF", sev) <<
"AnglePts " <<
a1 <<
" " << e1;
4434 MOFEM_LOG(
"SELF", sev) <<
"AnglePts " <<
a0 <<
" " << e0;
4435 MOFEM_LOG(
"SELF", sev) <<
"AnglePts " <<
a2 <<
" " << e2;
4436 MOFEM_LOG(
"SELF", sev) <<
"AnglePts " << endl;
4440 return std::make_pair(optimal_energy, optimal_angle);
4446 auto [opt_e0, opt_a0] = calc_optimal_angle_impl(1, 1, 0, 0, 3, -3);
4447 if (std::abs(opt_e0 - 1) > std::numeric_limits<double>::epsilon()) {
4450 if (std::abs(opt_a0 - 1) > std::numeric_limits<double>::epsilon()) {
4457 auto calc_optimal_angle = [&](
4459 auto &face_angle_map_up,
4460 auto &face_angle_map_down
4465 for (
auto &
m : edge_face_max_energy_map) {
4467 auto &[max_face, e0,
a0] =
m.second;
4469 if (std::abs(e0) > std::numeric_limits<double>::epsilon()) {
4471 if (face_angle_map_up.find(e) == face_angle_map_up.end() ||
4472 face_angle_map_down.find(e) == face_angle_map_down.end()) {
4475 auto [e1,
a1, face_up] = face_angle_map_up.at(e);
4476 auto [e2,
a2, face_down] = face_angle_map_down.at(e);
4479 auto [optimal_energy, optimal_angle] =
4480 calc_optimal_angle_impl(
a0, e0,
a1, e1,
a2, e2);
4482 e0 = optimal_energy;
4491 std::map<EntityHandle, std::tuple<double, double, EntityHandle>>
4493 std::map<EntityHandle, std::tuple<double, double, EntityHandle>>
4494 face_angle_map_down;
4495 CHKERR up_down_face(face_angle_map_up, face_angle_map_down);
4496 CHKERR calc_optimal_angle(face_angle_map_up, face_angle_map_down);
4499 auto th_angle = get_tags_vec(
"Angle", 1);
4501 for (
auto &
m : face_angle_map_up) {
4502 auto [e,
a, face] =
m.second;
4507 for (
auto &
m : face_angle_map_down) {
4508 auto [e,
a, face] =
m.second;
4513 Range max_energy_faces;
4514 for (
auto &
m : edge_face_max_energy_map) {
4515 auto [face, e, angle] =
m.second;
4516 max_energy_faces.insert(face);
4531 auto sort_by_energy = [&](
auto &edge_face_max_energy_map) {
4532 std::map<double, std::tuple<EntityHandle, EntityHandle, double>>
4534 for (
auto m : edge_face_max_energy_map) {
4536 auto [max_face, energy, opt_angle] =
m.second;
4537 sort_by_energy[energy] = std::make_tuple(e, max_face, opt_angle);
4539 return sort_by_energy;
4542 auto set_face_orientation = [&](
auto &sort_by_energy,
auto &layers,
4543 auto &set_vertices,
double &all_quality) {
4549 Range body_skin_edges;
4551 body_skin, 1,
false, body_skin_edges, moab::Interface::UNION);
4552 Range boundary_skin_verts;
4554 boundary_skin_verts,
true);
4556 auto get_rotated_normal = [&](
auto e,
auto f,
auto angle) {
4559 auto t_edge_dir = calculate_edge_direction(e);
4560 auto [side, sense, offset] = get_sense(
f, e);
4561 t_edge_dir(
i) *= sense;
4562 t_edge_dir.normalize();
4563 t_edge_dir(
i) *= angle;
4568 t_rotated_normal(
i) = t_R(
i,
j) * t_normal(
j);
4569 return std::make_tuple(t_normal, t_rotated_normal);
4572 Range rotated_normals;
4575 for (
auto it = sort_by_energy.rbegin(); it != sort_by_energy.rend();
4577 auto energy = it->first;
4578 auto [e, max_face, opt_angle] = it->second;
4581 auto [t_normal, t_rotated_normal] =
4582 get_rotated_normal(e, max_face, opt_angle);
4583 rotated_normals.insert(max_face);
4592 if (adj_tets.size() != 2) {
4594 <<
"Wrong number of tets adjacent to max face "
4597 "Wrong number of crack faces");
4600 Range adj_front_faces;
4603 adj_front_faces = subtract(adj_front_faces, *
crackFaces);
4604 Range adj_tet_faces;
4606 adj_tets, 2,
false, adj_tet_faces, moab::Interface::UNION);
4608 intersect(adj_tet_faces, adj_front_faces);
4610 if (adj_tet_faces.size() != 3) {
4611 MOFEM_LOG(
"SELF", sev) <<
"Wrong number of faces adj. to test "
4612 << adj_tet_faces.size();
4614 "Wrong number of crack faces");
4618 Range adj_front_faces_edges;
4620 adj_front_faces_edges,
4621 moab::Interface::UNION);
4624 std::array<EntityHandle, 3> processed_faces{0, max_face, 0};
4626 for (
auto &
l : layers) {
4627 auto adj_tets_layer = intersect(adj_tets,
l);
4628 if (adj_tets_layer.empty()) {
4633 adj_tets_layer, 2,
false, faces_layer, moab::Interface::UNION);
4634 faces_layer = intersect(faces_layer, adj_front_faces);
4635 faces_layer = subtract(faces_layer,
Range(max_face, max_face));
4636 if (set_index > 0) {
4637 faces_layer = subtract(
4638 faces_layer,
Range(processed_faces[0], processed_faces[0]));
4641 if (faces_layer.size() != 1) {
4643 <<
"Wrong number of faces to move " << faces_layer.size();
4645 "Wrong number of crack faces");
4648 processed_faces[set_index] = faces_layer[0];
4653 for (
auto f : {0, 1, 2}) {
4655 if (processed_faces[
f] == 0)
4661 if (
rval != MB_SUCCESS) {
4663 <<
"get_connectivity failed " <<
f <<
" "
4666 "can noy get connectivity");
4668 vertex = subtract(vertex, front_vertex);
4669 if (set_vertices.find(vertex[0]) != set_vertices.end()) {
4671 processed_faces[1] = 0;
4672 processed_faces[2] = 0;
4673 }
else if (
f == 1) {
4674 processed_faces[0] = 0;
4675 processed_faces[2] = 0;
4677 processed_faces[0] = 0;
4678 processed_faces[1] = 0;
4689 for (
auto f : processed_faces) {
4696 if (
rval != MB_SUCCESS) {
4698 <<
"get_connectivity failed " <<
f <<
" "
4701 "can noy get connectivity");
4703 vertex = subtract(vertex, front_vertex);
4705 if (vertex.size() != 1) {
4707 <<
"Wrong number of vertex to move " << vertex.size();
4717 vertex_edges = subtract(vertex_edges, adj_front_faces_edges);
4718 if (boundary_skin_verts.size() &&
4719 boundary_skin_verts.find(vertex[0]) !=
4720 boundary_skin_verts.end()) {
4721 MOFEM_LOG(
"SELF", sev) <<
"Boundary vertex";
4722 vertex_edges = intersect(vertex_edges, body_skin_edges);
4724 if (geometry_edges_verts.size() &&
4725 geometry_edges_verts.find(vertex[0]) !=
4726 geometry_edges_verts.end()) {
4727 MOFEM_LOG(
"SELF", sev) <<
"Geometry edge vertex";
4728 vertex_edges = intersect(vertex_edges, geometry_edges);
4730 if (crack_faces_verts.size() &&
4731 crack_faces_verts.find(vertex_edges[0]) !=
4732 crack_faces_verts.end()) {
4733 MOFEM_LOG(
"SELF", sev) <<
"Crack face vertex";
4734 vertex_edges = intersect(vertex_edges, crack_faces_edges);
4744 std::map<EntityHandle, FTensor::Tensor1<double, SPACE_DIM>>
4746 for (
auto e : vertex_edges) {
4749 edge_conn = subtract(edge_conn, vertex);
4751 if (edge_conn.size() != 1) {
4753 <<
"Wrong number of edge conn " << edge_conn.size();
4756 auto it = set_vertices.find(vertex[0]);
4757 if (it != set_vertices.end()) {
4758 node_positions_map[e](
i) = std::get<2>(it->second)(
i);
4761 t_v0(
i) = (t_v_e0(
i) + t_v_e1(
i)) / 2;
4764 auto a = (t_v0(
i) - t_vertex_coords(
i)) * t_rotated_normal(
i);
4765 auto b = (t_v3(
i) - t_vertex_coords(
i)) * t_rotated_normal(
i);
4768 << face_idx <<
" edge: " << e <<
" gamma: " << gamma;
4769 if (std::isnormal(gamma) &&
4770 gamma > -std::numeric_limits<double>::epsilon() &&
4771 gamma < 1 - std::numeric_limits<double>::epsilon()) {
4772 for (
auto i : {0, 1, 2}) {
4773 node_positions_map[e](
i) =
4774 gamma * (t_v3(
i) - t_vertex_coords(
i));
4779 if (vertex_edges.size() == 0) {
4780 node_positions_map[0](
i) = 0;
4783 Range adj_vertex_tets;
4786 for (
auto &p : node_positions_map) {
4787 double min_quality = 1;
4788 for (
auto t : adj_vertex_tets) {
4793 std::array<double, 12> coords;
4797 for (; idx < num_nodes; ++idx) {
4798 if (conn[idx] == vertex[0]) {
4803 if (set_vertices.find(vertex[0]) == set_vertices.end()) {
4804 for (
auto ii : {0, 1, 2}) {
4805 coords[3 * idx + ii] += p.second(ii);
4808 for (
auto vv : {0, 1, 2, 3}) {
4809 auto it = set_vertices.find(conn[vv]);
4810 if (it != set_vertices.end()) {
4811 auto &[
f, energy, t_position] = it->second;
4812 for (
auto ii : {0, 1, 2})
4813 coords[3 * vv + ii] += t_position(ii);
4817 double q = Tools::volumeLengthQuality(coords.data());
4818 if (!std::isnormal(q))
4820 min_quality = std::min(min_quality, q);
4822 sort_by_quality[min_quality] =
4823 std::make_tuple(vertex[0],
f,
4825 p.second(0), p.second(1), p.second(2)});
4832 for (
auto s : sort_by_quality) {
4833 auto &[vertex, face, t_position] = s.second;
4835 <<
"Quality: " << s.first <<
" vertex " << vertex <<
" face "
4836 << face <<
" point: " << t_position;
4839 for (
auto it = sort_by_quality.rbegin(); it != sort_by_quality.rend();
4841 auto &[vertex, face, t_position] = it->second;
4842 all_quality = std::min(all_quality, it->first);
4844 <<
"Set quality: " << it->first <<
" vertex " << vertex
4845 <<
" face " << face <<
" point: " << t_position;
4846 set_vertices[vertex] = std::make_tuple(face, energy, t_position);
4855 std::map<EntityHandle, std::tuple<EntityHandle, double, double>>
4856 edge_face_max_energy_map;
4857 CHKERR find_maximal_face_energy(front_edges, front_faces,
4858 edge_face_max_energy_map);
4859 CHKERR calculate_face_orientation(edge_face_max_energy_map);
4861 auto edge_map_sort_by_energy = sort_by_energy(edge_face_max_energy_map);
4864 double top_quality = 1;
4868 CHKERR set_face_orientation(edge_map_sort_by_energy, layers_top,
4869 set_vertices_top, top_quality);
4871 double bottom_quality = 1;
4874 set_vertices_bottom;
4875 CHKERR set_face_orientation(edge_map_sort_by_energy, layers_bottom,
4876 set_vertices_bottom, bottom_quality);
4878 MOFEM_LOG(
"SELF", sev) <<
"Top quality " << top_quality;
4879 MOFEM_LOG(
"SELF", sev) <<
"Bottom quality " << bottom_quality;
4881 auto set_tag = [&](
auto &set_vertices,
auto th_position) {
4883 for (
auto m : set_vertices) {
4885 auto &[
f, energy, t_p] =
m.second;
4893 if (top_quality > bottom_quality) {
4894 CHKERR set_tag(set_vertices_top, th_position);
4896 CHKERR set_tag(set_vertices_bottom, th_position);
4900 auto th_front_top = get_tags_vec(
"FrontPositionTop", 3);
4901 auto th_front_bottom = get_tags_vec(
"FrontPositionBottom", 3);
4903 Range top_moved_faces;
4904 for (
auto m : set_vertices_top) {
4906 auto &[
f, energy, t_p] =
m.second;
4907 top_moved_faces.insert(
f);
4911 Range bottom_moved_faces;
4912 for (
auto m : set_vertices_bottom) {
4914 auto &[
f, energy, t_p] =
m.second;
4915 bottom_moved_faces.insert(
f);
4920 for (
auto m : set_vertices_bottom) {
4921 auto &[
f, energy, t_p] =
m.second;
4922 bottom_moved_faces.insert(
f);
4928 bottom_moved_faces);
4929 auto front_faces = get_adj_front(
false);
4937 CHKERR evaluate_face_energy_and_set_orientation(
4938 *
frontEdges, get_adj_front(
false), sides_pair, th_front_position);
4955 auto get_max_moved_faces = [&]() {
4956 Range max_moved_faces;
4957 auto adj_front = get_adj_front(
false);
4958 std::vector<double> face_energy(adj_front.size());
4960 face_energy.data());
4961 for (
int i = 0;
i != adj_front.size(); ++
i) {
4962 if (face_energy[
i] > std::numeric_limits<double>::epsilon()) {
4963 max_moved_faces.insert(adj_front[
i]);
4967 return boost::make_shared<Range>(max_moved_faces);
4982 "max_moved_faces_" +
4996 Tag th_front_position;
4998 mField.
get_moab().tag_get_handle(
"FrontPosition", th_front_position);
5003 std::vector<double> coords(3 * verts.size());
5005 std::vector<double> pos(3 * verts.size());
5007 for (
int i = 0;
i != 3 * verts.size(); ++
i) {
5008 coords[
i] += pos[
i];
5011 double zero[] = {0., 0., 0.};
5015 constexpr
bool debug =
true;
5020 "set_coords_faces_" +
5031 constexpr
bool potential_crack_debug =
false;
5032 if constexpr (potential_crack_debug) {
5035 Range crack_front_verts;
5040 Range crack_front_faces;
5042 true, crack_front_faces,
5043 moab::Interface::UNION);
5044 crack_front_faces = intersect(crack_front_faces, add_ents);
5051 auto get_crack_faces = [&]() {
5059 auto get_extended_crack_faces = [&]() {
5060 auto get_faces_of_crack_front_verts = [&](
auto crack_faces_org) {
5061 ParallelComm *pcomm =
5066 if (!pcomm->rank()) {
5068 auto get_nodes = [&](
auto &&e) {
5071 "get connectivity");
5075 auto get_adj = [&](
auto &&e,
auto dim,
5076 auto t = moab::Interface::UNION) {
5088 auto body_skin_edges = get_adj(body_skin, 1, moab::Interface::UNION);
5092 s = crack_faces.size();
5094 auto crack_face_nodes = get_nodes(crack_faces_org);
5095 auto crack_faces_edges =
5096 get_adj(crack_faces_org, 1, moab::Interface::UNION);
5100 auto crack_skin_nodes = get_nodes(crack_skin);
5102 auto crack_skin_faces =
5103 get_adj(crack_skin, 2, moab::Interface::UNION);
5104 crack_skin_faces = subtract(crack_skin_faces, crack_faces_org);
5106 crack_faces = crack_faces_org;
5107 for (
auto f : crack_skin_faces) {
5108 auto edges = intersect(
5109 get_adj(
Range(
f,
f), 1, moab::Interface::UNION), crack_skin);
5110 auto edge_conn = get_nodes(
Range(edges));
5111 if (edges.size() == 2) {
5112 auto faces = intersect(get_adj(edges, 2, moab::Interface::UNION),
5114 if (faces.size() == 2) {
5115 auto edge0_conn = get_nodes(
Range(edges[0], edges[0]));
5116 auto edge1_conn = get_nodes(
Range(edges[1], edges[1]));
5117 auto edges_conn = intersect(intersect(edge0_conn, edge1_conn),
5121 auto node_edges = subtract(intersect(
5122 get_adj(
edges_conn, 1, moab::Interface::INTERSECT),
5123 crack_faces_edges), crack_skin);
5125 if (node_edges.size()) {
5130 auto get_t_dir = [&](
auto e_conn) {
5131 auto other_node = subtract(e_conn,
edges_conn);
5135 t_dir(
i) -= t_v0(
i);
5141 get_t_dir(edge0_conn)(
i) + get_t_dir(edge1_conn)(
i);
5144 t_crack_surface_ave_dir(
i) = 0;
5145 for (
auto e : node_edges) {
5146 auto e_conn = get_nodes(
Range(e, e));
5147 auto t_dir = get_t_dir(e_conn);
5148 t_crack_surface_ave_dir(
i) += t_dir(
i);
5151 auto dot = t_ave_dir(
i) * t_crack_surface_ave_dir(
i);
5154 if (dot < -std::numeric_limits<double>::epsilon()) {
5155 crack_faces.insert(
f);
5160 }
else if (edges.size() == 3) {
5161 crack_faces.insert(
f);
5165 crack_faces_org = crack_faces;
5167 }
while (s != crack_faces.size());
5173 return get_faces_of_crack_front_verts(get_crack_faces());
5177 constexpr
bool debug =
false;
5181 "new_crack_surface_" +
5183 get_extended_crack_faces());
5187 auto new_crack_faces = subtract(get_extended_crack_faces(), *
crackFaces);
5202 verts = subtract(verts, conn);
5203 std::vector<double> coords(3 * verts.size());
5205 double def_coords[] = {0., 0., 0.};
5208 "ORG_COORDS", 3, MB_TYPE_DOUBLE, th_org_coords,
5209 MB_TAG_CREAT | MB_TAG_DENSE, def_coords);
5229 auto post_proc_norm_fe =
5230 boost::make_shared<VolumeElementForcesAndSourcesCore>(
mField);
5232 auto post_proc_norm_rule_hook = [](
int,
int,
int p) ->
int {
5235 post_proc_norm_fe->getRuleHook = post_proc_norm_rule_hook;
5237 post_proc_norm_fe->getUserPolynomialBase() =
5238 boost::shared_ptr<BaseFunction>(
new CGGUserPolynomialBase());
5240 CHKERR EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
5244 enum NORMS { U_NORM_L2 = 0, U_NORM_H1, PIOLA_NORM, U_ERROR_L2, LAST_NORM };
5247 CHKERR VecZeroEntries(norms_vec);
5249 auto u_l2_ptr = boost::make_shared<MatrixDouble>();
5250 auto u_h1_ptr = boost::make_shared<MatrixDouble>();
5251 post_proc_norm_fe->getOpPtrVector().push_back(
5253 post_proc_norm_fe->getOpPtrVector().push_back(
5255 post_proc_norm_fe->getOpPtrVector().push_back(
5257 post_proc_norm_fe->getOpPtrVector().push_back(
5259 post_proc_norm_fe->getOpPtrVector().push_back(
5263 auto piola_ptr = boost::make_shared<MatrixDouble>();
5264 post_proc_norm_fe->getOpPtrVector().push_back(
5266 post_proc_norm_fe->getOpPtrVector().push_back(
5269 TetPolynomialBase::switchCacheBaseOn<HDIV>({post_proc_norm_fe.get()});
5271 *post_proc_norm_fe);
5272 TetPolynomialBase::switchCacheBaseOff<HDIV>({post_proc_norm_fe.get()});
5274 CHKERR VecAssemblyBegin(norms_vec);
5275 CHKERR VecAssemblyEnd(norms_vec);
5276 const double *norms;
5277 CHKERR VecGetArrayRead(norms_vec, &norms);
5278 MOFEM_LOG(
"EP", Sev::inform) <<
"norm_u: " << std::sqrt(norms[U_NORM_L2]);
5279 MOFEM_LOG(
"EP", Sev::inform) <<
"norm_u_h1: " << std::sqrt(norms[U_NORM_H1]);
5281 <<
"norm_error_u_l2: " << std::sqrt(norms[U_ERROR_L2]);
5283 <<
"norm_piola: " << std::sqrt(norms[PIOLA_NORM]);
5284 CHKERR VecRestoreArrayRead(norms_vec, &norms);
5299 for (
auto bc : bc_mng->getBcMapByBlockName()) {
5300 if (
auto disp_bc = bc.second->dispBcPtr) {
5302 MOFEM_LOG(
"EP", Sev::noisy) << *disp_bc;
5304 std::vector<double> block_attributes(6, 0.);
5305 if (disp_bc->data.flag1 == 1) {
5306 block_attributes[0] = disp_bc->data.value1;
5307 block_attributes[3] = 1;
5309 if (disp_bc->data.flag2 == 1) {
5310 block_attributes[1] = disp_bc->data.value2;
5311 block_attributes[4] = 1;
5313 if (disp_bc->data.flag3 == 1) {
5314 block_attributes[2] = disp_bc->data.value3;
5315 block_attributes[5] = 1;
5317 auto faces = bc.second->bcEnts.subset_by_dimension(2);
5337 for (
auto bc : bc_mng->getBcMapByBlockName()) {
5338 if (
auto force_bc = bc.second->forceBcPtr) {
5339 std::vector<double> block_attributes(6, 0.);
5340 block_attributes[0] = -force_bc->data.value3 * force_bc->data.value1;
5341 block_attributes[3] = 1;
5342 block_attributes[1] = -force_bc->data.value4 * force_bc->data.value1;
5343 block_attributes[4] = 1;
5344 block_attributes[2] = -force_bc->data.value5 * force_bc->data.value1;
5345 block_attributes[5] = 1;
5346 auto faces = bc.second->bcEnts.subset_by_dimension(2);
5361 faceExchange = CommInterface::createEntitiesPetscVector(
5363 edgeExchange = CommInterface::createEntitiesPetscVector(
5368 auto print_loc_size = [
this](
auto v,
auto str,
auto sev) {
5371 CHKERR VecGetLocalSize(
v.second, &size);
5373 CHKERR VecGetOwnershipRange(
v.second, &low, &high);
5374 MOFEM_LOG(
"EPSYNC", sev) << str <<
" local size " << size <<
" ( " << low
5375 <<
" " << high <<
" ) ";