15#ifdef INCLUDE_MBCOUPLER
16 #include <mbcoupler/Coupler.hpp>
23#include <boost/math/constants/constants.hpp>
26#ifdef ENABLE_PYTHON_BINDING
27#include <boost/python.hpp>
28#include <boost/python/def.hpp>
29#include <boost/python/numpy.hpp>
30namespace bp = boost::python;
31namespace np = boost::python::numpy;
59 const EntityType type) {
63 auto dim = CN::Dimension(type);
65 std::vector<int> sendcounts(pcomm->size());
66 std::vector<int> displs(pcomm->size());
67 std::vector<int> sendbuf(r.size());
68 if (pcomm->rank() == 0) {
69 for (
auto p = 1; p != pcomm->size(); p++) {
71 ->getPartEntities(m_field.
get_moab(), p)
74 CHKERR m_field.
get_moab().get_adjacencies(part_ents, dim,
true, faces,
75 moab::Interface::UNION);
76 faces = intersect(faces, r);
77 sendcounts[p] = faces.size();
78 displs[p] = sendbuf.size();
79 for (
auto f : faces) {
81 sendbuf.push_back(
id);
87 MPI_Scatter(sendcounts.data(), 1, MPI_INT, &recv_data, 1, MPI_INT, 0,
89 std::vector<int> recvbuf(recv_data);
90 MPI_Scatterv(sendbuf.data(), sendcounts.data(), displs.data(), MPI_INT,
91 recvbuf.data(), recv_data, MPI_INT, 0, pcomm->comm());
93 if (pcomm->rank() > 0) {
95 for (
auto &f : recvbuf) {
105 const std::string block_name) {
111 std::regex((boost::format(
"%s(.*)") % block_name).str())
115 for (
auto bc : bcs) {
116 auto meshset = bc->getMeshset();
125 const std::string block_name,
int dim) {
131 std::regex((boost::format(
"%s(.*)") % block_name).str())
135 for (
auto bc : bcs) {
147 const std::string block_name,
int dim) {
148 std::map<std::string, Range> r;
153 std::regex((boost::format(
"%s(.*)") % block_name).str())
157 for (
auto bc : bcs) {
162 r[bc->getName()] = faces;
169 const unsigned int cubit_bc_type) {
172 CHKERR mesh_mng->getMeshset(ms_id, cubit_bc_type, meshset);
176static auto save_range(moab::Interface &moab,
const std::string name,
177 const Range r, std::vector<Tag> tags = {}) {
180 CHKERR moab.add_entities(*out_meshset, r);
182 CHKERR moab.write_file(name.c_str(),
"VTK",
"", out_meshset->get_ptr(), 1,
183 tags.data(), tags.size());
185 MOFEM_LOG(
"SELF", Sev::warning) <<
"Empty range for " << name;
192 ParallelComm *pcomm =
195 PSTATUS_SHARED | PSTATUS_MULTISHARED,
196 PSTATUS_NOT, -1, &boundary_ents),
198 return boundary_ents;
203 ParallelComm *pcomm =
205 CHK_MOAB_THROW(pcomm->filter_pstatus(skin, PSTATUS_NOT_OWNED, PSTATUS_NOT, -1,
214 CHK_MOAB_THROW(skin.find_skin(0, body_ents,
false, skin_ents),
"find_skin");
220 ParallelComm *pcomm =
223 Range crack_skin_without_bdy;
224 if (pcomm->rank() == 0) {
226 CHKERR moab.get_adjacencies(crack_faces, 1,
true, crack_edges,
227 moab::Interface::UNION);
228 auto crack_skin =
get_skin(m_field, crack_faces);
232 "get_entities_by_dimension");
233 auto body_skin =
get_skin(m_field, body_ents);
234 Range body_skin_edges;
235 CHK_MOAB_THROW(moab.get_adjacencies(body_skin, 1,
true, body_skin_edges,
236 moab::Interface::UNION),
238 crack_skin_without_bdy = subtract(crack_skin, body_skin_edges);
240 for (
auto &
m : front_edges_map) {
241 auto add_front = subtract(
m.second, crack_edges);
242 auto i = intersect(
m.second, crack_edges);
244 crack_skin_without_bdy.merge(add_front);
248 CHKERR moab.get_adjacencies(i_skin, 1,
true, adj_i_skin,
249 moab::Interface::UNION);
250 adj_i_skin = subtract(intersect(adj_i_skin,
m.second), crack_edges);
251 crack_skin_without_bdy.merge(adj_i_skin);
255 return send_type(m_field, crack_skin_without_bdy, MBEDGE);
261 ParallelComm *pcomm =
264 MOFEM_LOG(
"EP", Sev::noisy) <<
"get_two_sides_of_crack_surface";
266 if (!pcomm->rank()) {
268 auto impl = [&](
auto &saids) {
273 auto get_adj = [&](
auto e,
auto dim) {
276 e, dim,
true, adj, moab::Interface::UNION),
281 auto get_conn = [&](
auto e) {
288 constexpr bool debug =
false;
292 auto body_skin =
get_skin(m_field, body_ents);
293 auto body_skin_edges = get_adj(body_skin, 1);
296 subtract(
get_skin(m_field, crack_faces), body_skin_edges);
297 auto crack_skin_conn = get_conn(crack_skin);
298 auto crack_skin_conn_edges = get_adj(crack_skin_conn, 1);
299 auto crack_edges = get_adj(crack_faces, 1);
300 crack_edges = subtract(crack_edges, crack_skin);
301 auto all_tets = get_adj(crack_edges, 3);
302 crack_edges = subtract(crack_edges, crack_skin_conn_edges);
303 auto crack_conn = get_conn(crack_edges);
304 all_tets.merge(get_adj(crack_conn, 3));
313 if (crack_faces.size()) {
314 auto grow = [&](
auto r) {
315 auto crack_faces_conn = get_conn(crack_faces);
318 while (size_r != r.size() && r.size() > 0) {
320 CHKERR moab.get_connectivity(r,
v,
true);
321 v = subtract(
v, crack_faces_conn);
324 moab::Interface::UNION);
325 r = intersect(r, all_tets);
334 Range all_tets_ord = all_tets;
335 while (all_tets.size()) {
336 Range faces = get_adj(unite(saids.first, saids.second), 2);
337 faces = subtract(crack_faces, faces);
340 auto fit = faces.begin();
341 for (; fit != faces.end(); ++fit) {
342 tets = intersect(get_adj(
Range(*fit, *fit), 3), all_tets);
343 if (tets.size() == 2) {
350 saids.first.insert(tets[0]);
351 saids.first = grow(saids.first);
352 all_tets = subtract(all_tets, saids.first);
353 if (tets.size() == 2) {
354 saids.second.insert(tets[1]);
355 saids.second = grow(saids.second);
356 all_tets = subtract(all_tets, saids.second);
364 saids.first = subtract(all_tets_ord, saids.second);
365 saids.second = subtract(all_tets_ord, saids.first);
371 std::pair<Range, Range> saids;
372 if (crack_faces.size())
377 MOFEM_LOG(
"EP", Sev::noisy) <<
"get_two_sides_of_crack_surface <- done";
379 return std::pair<Range, Range>();
390 boost::shared_ptr<Range> front_nodes,
391 boost::shared_ptr<Range> front_edges,
392 boost::shared_ptr<CGGUserPolynomialBase::CachePhi> cache_phi =
nullptr)
396 boost::shared_ptr<Range> front_nodes,
397 boost::shared_ptr<Range> front_edges,
FunRule fun_rule,
398 boost::shared_ptr<CGGUserPolynomialBase::CachePhi> cache_phi =
nullptr)
403 int order_col,
int order_data) {
406 constexpr bool debug =
false;
408 constexpr int numNodes = 4;
409 constexpr int numEdges = 6;
410 constexpr int refinementLevels = 6;
412 auto &m_field = fe_raw_ptr->
mField;
413 auto fe_ptr =
static_cast<Fe *
>(fe_raw_ptr);
416 auto set_base_quadrature = [&]() {
418 int rule =
funRule(order_data);
429 auto &gauss_pts = fe_ptr->gaussPts;
430 gauss_pts.resize(4, nb_gauss_pts,
false);
431 cblas_dcopy(nb_gauss_pts, &
QUAD_3D_TABLE[rule]->points[1], 4,
432 &gauss_pts(0, 0), 1);
433 cblas_dcopy(nb_gauss_pts, &
QUAD_3D_TABLE[rule]->points[2], 4,
434 &gauss_pts(1, 0), 1);
435 cblas_dcopy(nb_gauss_pts, &
QUAD_3D_TABLE[rule]->points[3], 4,
436 &gauss_pts(2, 0), 1);
438 &gauss_pts(3, 0), 1);
439 auto &data = fe_ptr->dataOnElement[
H1];
440 data->dataOnEntities[MBVERTEX][0].getN(
NOBASE).resize(nb_gauss_pts, 4,
443 &*data->dataOnEntities[MBVERTEX][0].getN(
NOBASE).data().begin();
444 cblas_dcopy(4 * nb_gauss_pts,
QUAD_3D_TABLE[rule]->points, 1, shape_ptr,
453 CHKERR set_base_quadrature();
457 auto get_singular_nodes = [&]() {
460 CHKERR m_field.get_moab().get_connectivity(fe_handle, conn, num_nodes,
462 std::bitset<numNodes> singular_nodes;
463 for (
auto nn = 0; nn != numNodes; ++nn) {
465 singular_nodes.set(nn);
467 singular_nodes.reset(nn);
470 return singular_nodes;
473 auto get_singular_edges = [&]() {
474 std::bitset<numEdges> singular_edges;
475 for (
int ee = 0; ee != numEdges; ee++) {
477 CHKERR m_field.get_moab().side_element(fe_handle, 1, ee, edge);
479 singular_edges.set(ee);
481 singular_edges.reset(ee);
484 return singular_edges;
487 auto set_gauss_pts = [&](
auto &ref_gauss_pts) {
489 fe_ptr->gaussPts.swap(ref_gauss_pts);
490 const size_t nb_gauss_pts = fe_ptr->gaussPts.size2();
491 auto &data = fe_ptr->dataOnElement[
H1];
492 data->dataOnEntities[MBVERTEX][0].getN(
NOBASE).resize(nb_gauss_pts, 4);
494 &*data->dataOnEntities[MBVERTEX][0].getN(
NOBASE).data().begin();
496 &fe_ptr->gaussPts(1, 0), &fe_ptr->gaussPts(2, 0),
501 auto singular_nodes = get_singular_nodes();
502 if (singular_nodes.count()) {
503 auto it_map_ref_coords =
mapRefCoords.find(singular_nodes.to_ulong());
505 CHKERR set_gauss_pts(it_map_ref_coords->second);
509 auto refine_quadrature = [&]() {
512 const int max_level = refinementLevels;
516 double base_coords[] = {0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1};
518 for (
int nn = 0; nn != 4; nn++)
519 CHKERR moab_ref.create_vertex(&base_coords[3 * nn], nodes[nn]);
520 CHKERR moab_ref.create_element(MBTET, nodes, 4, tet);
524 Range tets(tet, tet);
527 tets, 1,
true, edges, moab::Interface::UNION);
532 Range nodes_at_front;
533 for (
int nn = 0; nn != numNodes; nn++) {
534 if (singular_nodes[nn]) {
536 CHKERR moab_ref.side_element(tet, 0, nn, ent);
537 nodes_at_front.insert(ent);
541 auto singular_edges = get_singular_edges();
544 CHKERR moab_ref.create_meshset(MESHSET_SET, meshset);
545 for (
int ee = 0; ee != numEdges; ee++) {
546 if (singular_edges[ee]) {
548 CHKERR moab_ref.side_element(tet, 1, ee, ent);
549 CHKERR moab_ref.add_entities(meshset, &ent, 1);
555 for (
int ll = 0; ll != max_level; ll++) {
558 ->getEntitiesByTypeAndRefLevel(
BitRefLevel().set(ll),
562 CHKERR moab_ref.get_adjacencies(
563 nodes_at_front, 1,
true, ref_edges, moab::Interface::UNION);
564 ref_edges = intersect(ref_edges, edges);
566 CHKERR moab_ref.get_entities_by_type(meshset, MBEDGE, ents,
true);
567 ref_edges = intersect(ref_edges, ents);
570 ->getEntitiesByTypeAndRefLevel(
572 CHKERR m_ref->addVerticesInTheMiddleOfEdges(
576 ->updateMeshsetByEntitiesChildren(meshset,
578 meshset, MBEDGE,
true);
584 ->getEntitiesByTypeAndRefLevel(
BitRefLevel().set(max_level),
594 for (Range::iterator tit = tets.begin(); tit != tets.end();
598 CHKERR moab_ref.get_connectivity(*tit, conn, num_nodes,
false);
599 CHKERR moab_ref.get_coords(conn, num_nodes, &ref_coords(tt, 0));
602 auto &data = fe_ptr->dataOnElement[
H1];
603 const size_t nb_gauss_pts = fe_ptr->gaussPts.size2();
604 MatrixDouble ref_gauss_pts(4, nb_gauss_pts * ref_coords.size1());
606 data->dataOnEntities[MBVERTEX][0].getN(
NOBASE);
608 for (
size_t tt = 0; tt != ref_coords.size1(); tt++) {
609 double *tet_coords = &ref_coords(tt, 0);
612 for (
size_t ggg = 0; ggg != nb_gauss_pts; ++ggg, ++gg) {
613 for (
int dd = 0; dd != 3; dd++) {
614 ref_gauss_pts(dd, gg) =
615 shape_n(ggg, 0) * tet_coords[3 * 0 + dd] +
616 shape_n(ggg, 1) * tet_coords[3 * 1 + dd] +
617 shape_n(ggg, 2) * tet_coords[3 * 2 + dd] +
618 shape_n(ggg, 3) * tet_coords[3 * 3 + dd];
620 ref_gauss_pts(3, gg) = fe_ptr->gaussPts(3, ggg) * det;
624 mapRefCoords[singular_nodes.to_ulong()].swap(ref_gauss_pts);
631 TetPolynomialBase::switchCacheBaseOff<HDIV>({fe_raw_ptr});
632 TetPolynomialBase::switchCacheBaseOn<HDIV>({fe_raw_ptr});
637 CHKERR refine_quadrature();
647 using ForcesAndSourcesCore::dataOnElement;
650 using ForcesAndSourcesCore::ForcesAndSourcesCore;
656 boost::shared_ptr<CGGUserPolynomialBase::CachePhi>
cachePhi;
667 boost::shared_ptr<Range> front_edges)
671 boost::shared_ptr<Range> front_edges,
676 int order_col,
int order_data) {
679 constexpr bool debug =
false;
681 constexpr int numNodes = 3;
682 constexpr int numEdges = 3;
683 constexpr int refinementLevels = 6;
685 auto &m_field = fe_raw_ptr->
mField;
686 auto fe_ptr =
static_cast<Fe *
>(fe_raw_ptr);
689 auto set_base_quadrature = [&]() {
691 int rule =
funRule(order_data);
701 fe_ptr->gaussPts.resize(3, nb_gauss_pts,
false);
702 cblas_dcopy(nb_gauss_pts, &
QUAD_2D_TABLE[rule]->points[1], 3,
703 &fe_ptr->gaussPts(0, 0), 1);
704 cblas_dcopy(nb_gauss_pts, &
QUAD_2D_TABLE[rule]->points[2], 3,
705 &fe_ptr->gaussPts(1, 0), 1);
707 &fe_ptr->gaussPts(2, 0), 1);
708 auto &data = fe_ptr->dataOnElement[
H1];
709 data->dataOnEntities[MBVERTEX][0].getN(
NOBASE).resize(nb_gauss_pts, 3,
712 &*data->dataOnEntities[MBVERTEX][0].getN(
NOBASE).data().begin();
713 cblas_dcopy(3 * nb_gauss_pts,
QUAD_2D_TABLE[rule]->points, 1, shape_ptr,
715 data->dataOnEntities[MBVERTEX][0].getDiffN(
NOBASE).resize(3, 2,
false);
718 data->dataOnEntities[MBVERTEX][0].getDiffN(
NOBASE).data().begin());
727 CHKERR set_base_quadrature();
731 auto get_singular_nodes = [&]() {
734 CHKERR m_field.get_moab().get_connectivity(fe_handle, conn, num_nodes,
736 std::bitset<numNodes> singular_nodes;
737 for (
auto nn = 0; nn != numNodes; ++nn) {
739 singular_nodes.set(nn);
741 singular_nodes.reset(nn);
744 return singular_nodes;
747 auto get_singular_edges = [&]() {
748 std::bitset<numEdges> singular_edges;
749 for (
int ee = 0; ee != numEdges; ee++) {
751 CHKERR m_field.get_moab().side_element(fe_handle, 1, ee, edge);
753 singular_edges.set(ee);
755 singular_edges.reset(ee);
758 return singular_edges;
761 auto set_gauss_pts = [&](
auto &ref_gauss_pts) {
763 fe_ptr->gaussPts.swap(ref_gauss_pts);
764 const size_t nb_gauss_pts = fe_ptr->gaussPts.size2();
765 auto &data = fe_ptr->dataOnElement[
H1];
766 data->dataOnEntities[MBVERTEX][0].getN(
NOBASE).resize(nb_gauss_pts, 4);
768 &*data->dataOnEntities[MBVERTEX][0].getN(
NOBASE).data().begin();
770 &fe_ptr->gaussPts(1, 0), nb_gauss_pts);
774 auto singular_nodes = get_singular_nodes();
775 if (singular_nodes.count()) {
776 auto it_map_ref_coords =
mapRefCoords.find(singular_nodes.to_ulong());
778 CHKERR set_gauss_pts(it_map_ref_coords->second);
782 auto refine_quadrature = [&]() {
785 const int max_level = refinementLevels;
788 double base_coords[] = {0, 0, 0, 1, 0, 0, 0, 1, 0};
790 for (
int nn = 0; nn != numNodes; nn++)
791 CHKERR moab_ref.create_vertex(&base_coords[3 * nn], nodes[nn]);
793 CHKERR moab_ref.create_element(MBTRI, nodes, numNodes, tri);
797 Range tris(tri, tri);
800 tris, 1,
true, edges, moab::Interface::UNION);
805 Range nodes_at_front;
806 for (
int nn = 0; nn != numNodes; nn++) {
807 if (singular_nodes[nn]) {
809 CHKERR moab_ref.side_element(tri, 0, nn, ent);
810 nodes_at_front.insert(ent);
814 auto singular_edges = get_singular_edges();
817 CHKERR moab_ref.create_meshset(MESHSET_SET, meshset);
818 for (
int ee = 0; ee != numEdges; ee++) {
819 if (singular_edges[ee]) {
821 CHKERR moab_ref.side_element(tri, 1, ee, ent);
822 CHKERR moab_ref.add_entities(meshset, &ent, 1);
828 for (
int ll = 0; ll != max_level; ll++) {
831 ->getEntitiesByTypeAndRefLevel(
BitRefLevel().set(ll),
835 CHKERR moab_ref.get_adjacencies(
836 nodes_at_front, 1,
true, ref_edges, moab::Interface::UNION);
837 ref_edges = intersect(ref_edges, edges);
839 CHKERR moab_ref.get_entities_by_type(meshset, MBEDGE, ents,
true);
840 ref_edges = intersect(ref_edges, ents);
843 ->getEntitiesByTypeAndRefLevel(
845 CHKERR m_ref->addVerticesInTheMiddleOfEdges(
849 ->updateMeshsetByEntitiesChildren(meshset,
851 meshset, MBEDGE,
true);
857 ->getEntitiesByTypeAndRefLevel(
BitRefLevel().set(max_level),
868 for (Range::iterator tit = tris.begin(); tit != tris.end();
872 CHKERR moab_ref.get_connectivity(*tit, conn, num_nodes,
false);
873 CHKERR moab_ref.get_coords(conn, num_nodes, &ref_coords(tt, 0));
876 auto &data = fe_ptr->dataOnElement[
H1];
877 const size_t nb_gauss_pts = fe_ptr->gaussPts.size2();
878 MatrixDouble ref_gauss_pts(3, nb_gauss_pts * ref_coords.size1());
880 data->dataOnEntities[MBVERTEX][0].getN(
NOBASE);
882 for (
size_t tt = 0; tt != ref_coords.size1(); tt++) {
883 double *tri_coords = &ref_coords(tt, 0);
886 auto det = t_normal.
l2();
887 for (
size_t ggg = 0; ggg != nb_gauss_pts; ++ggg, ++gg) {
888 for (
int dd = 0; dd != 2; dd++) {
889 ref_gauss_pts(dd, gg) =
890 shape_n(ggg, 0) * tri_coords[3 * 0 + dd] +
891 shape_n(ggg, 1) * tri_coords[3 * 1 + dd] +
892 shape_n(ggg, 2) * tri_coords[3 * 2 + dd];
894 ref_gauss_pts(2, gg) = fe_ptr->gaussPts(2, ggg) * det;
898 mapRefCoords[singular_nodes.to_ulong()].swap(ref_gauss_pts);
904 CHKERR refine_quadrature();
914 using ForcesAndSourcesCore::dataOnElement;
917 using ForcesAndSourcesCore::ForcesAndSourcesCore;
966 const char *list_rots[] = {
"small",
"moderate",
"large",
"no_h1"};
967 const char *list_symm[] = {
"symm",
"not_symm"};
968 const char *list_release[] = {
"griffith_force",
"griffith_skeleton"};
969 const char *list_stretches[] = {
"linear",
"log",
"log_quadratic"};
974 PetscInt choice_stretch = StretchSelector::LOG;
976 char analytical_expr_file_name[255] =
"analytical_expr.py";
978 PetscOptionsBegin(PETSC_COMM_WORLD,
"",
"Eshelbian plasticity",
"none");
979 CHKERR PetscOptionsInt(
"-space_order",
"approximation oder for space",
"",
981 CHKERR PetscOptionsInt(
"-space_h1_order",
"approximation oder for space",
"",
983 CHKERR PetscOptionsInt(
"-material_order",
"approximation oder for material",
985 CHKERR PetscOptionsScalar(
"-viscosity_alpha_u",
"viscosity",
"",
alphaU,
987 CHKERR PetscOptionsScalar(
"-viscosity_alpha_w",
"viscosity",
"",
alphaW,
989 CHKERR PetscOptionsScalar(
"-viscosity_alpha_omega",
"rot viscosity",
"",
991 CHKERR PetscOptionsScalar(
"-density_alpha_rho",
"density",
"",
alphaRho,
995 CHKERR PetscOptionsEList(
"-rotations",
"rotations",
"", list_rots,
996 LARGE_ROT + 1, list_rots[choice_rot], &choice_rot,
998 CHKERR PetscOptionsEList(
"-grad",
"gradient of defamation approximate",
"",
999 list_rots, NO_H1_CONFIGURATION + 1,
1000 list_rots[choice_grad], &choice_grad, PETSC_NULLPTR);
1001 CHKERR PetscOptionsEList(
"-symm",
"symmetric variant",
"", list_symm, 2,
1002 list_symm[choice_symm], &choice_symm, PETSC_NULLPTR);
1006 CHKERR PetscOptionsEList(
"-stretches",
"stretches",
"", list_stretches,
1007 StretchSelector::STRETCH_SELECTOR_LAST,
1008 list_stretches[choice_stretch], &choice_stretch,
1011 CHKERR PetscOptionsBool(
"-no_stretch",
"do not solve for stretch",
"",
1013 CHKERR PetscOptionsBool(
"-set_singularity",
"set singularity",
"",
1015 CHKERR PetscOptionsBool(
"-l2_user_base_scale",
"streach scale",
"",
1021 CHKERR PetscOptionsBool(
"-dynamic_relaxation",
"dynamic time relaxation",
"",
1023 CHKERR PetscOptionsEList(
1029 CHKERR PetscOptionsInt(
"-contact_max_post_proc_ref_level",
"refinement level",
1033 CHKERR PetscOptionsBool(
"-cohesive_interface_on",
"cohesive interface ON",
"",
1036 "-cohesive_interface_remove_level",
"cohesive interface remove level",
"",
1042 CHKERR PetscOptionsScalar(
"-cracking_add_time",
"cracking add time",
"",
1044 CHKERR PetscOptionsScalar(
"-cracking_start_time",
"cracking start time",
"",
1047 CHKERR PetscOptionsScalar(
"-griffith_energy",
"Griffith energy",
"",
1050 CHKERR PetscOptionsScalar(
"-cracking_rtol",
"Cracking relative tolerance",
"",
1052 CHKERR PetscOptionsScalar(
"-cracking_atol",
"Cracking absolute tolerance",
"",
1054 CHKERR PetscOptionsEList(
"-energy_release_variant",
"energy release variant",
1055 "", list_release, 2, list_release[choice_release],
1056 &choice_release, PETSC_NULLPTR);
1057 CHKERR PetscOptionsInt(
"-nb_J_integral_levels",
"Number of J integarl levels",
1061 "-nb_J_integral_contours",
"Number of J integral contours",
"",
1065 char tag_name[255] =
"";
1066 CHKERR PetscOptionsString(
"-internal_stress_tag_name",
1067 "internal stress tag name",
"",
"", tag_name, 255,
1071 "-internal_stress_interp_order",
"internal stress interpolation order",
1073 CHKERR PetscOptionsBool(
"-internal_stress_voigt",
"Voigt index notation",
"",
1078 "-analytical_expr_file",
1079 analytical_expr_file_name, 255, PETSC_NULLPTR);
1085 "Unsupported internal stress interpolation order %d",
1098 static_cast<EnergyReleaseSelector
>(choice_release);
1101 case StretchSelector::LINEAR:
1109 case StretchSelector::LOG:
1111 std::numeric_limits<float>::epsilon()) {
1127 case StretchSelector::LOG_QUADRATIC:
1133 "No logarithmic quadratic stretch for this case");
1146 <<
"-dynamic_relaxation option is deprecated, use -solver_type "
1147 "dynamic_relaxation instead.";
1151 switch (choice_solver) {
1180 MOFEM_LOG(
"EP", Sev::inform) <<
"alphaU: -viscosity_alpha_u " <<
alphaU;
1181 MOFEM_LOG(
"EP", Sev::inform) <<
"alphaW: -viscosity_alpha_w " <<
alphaW;
1183 <<
"alphaOmega: -viscosity_alpha_omega " <<
alphaOmega;
1188 MOFEM_LOG(
"EP", Sev::inform) <<
"Gradient of deformation "
1196 MOFEM_LOG(
"EP", Sev::inform) <<
"Base exponent e";
1198 <<
"Stretch: -stretches " << list_stretches[choice_stretch];
1207 MOFEM_LOG(
"EP", Sev::inform) <<
"Solver type: -solver_type "
1228 <<
"Cracking relative tolerance: -cracking_rtol " <<
crackingRtol;
1230 <<
"Cracking absolute tolerance: -cracking_atol " <<
crackingAtol;
1232 <<
"Energy release variant: -energy_release_variant "
1235 <<
"Number of J integral contours: -nb_J_integral_contours "
1238 <<
"Cohesive interface on: -cohesive_interface_on "
1243 <<
"Cohesive interface remove level: -cohesive_interface_remove_level "
1246#ifdef ENABLE_PYTHON_BINDING
1247 auto file_exists = [](std::string myfile) {
1248 std::ifstream file(myfile.c_str());
1255 if (file_exists(analytical_expr_file_name)) {
1256 MOFEM_LOG(
"EP", Sev::inform) << analytical_expr_file_name <<
" file found";
1260 analytical_expr_file_name);
1264 << analytical_expr_file_name <<
" file NOT found";
1277 auto get_tets = [&]() {
1283 auto get_tets_skin = [&]() {
1284 Range tets_skin_part;
1286 CHKERR skin.find_skin(0, get_tets(),
false, tets_skin_part);
1287 ParallelComm *pcomm =
1290 CHKERR pcomm->filter_pstatus(tets_skin_part,
1291 PSTATUS_SHARED | PSTATUS_MULTISHARED,
1292 PSTATUS_NOT, -1, &tets_skin);
1296 auto subtract_boundary_conditions = [&](
auto &&tets_skin) {
1302 tets_skin = subtract(tets_skin,
v.faces);
1306 tets_skin = subtract(tets_skin,
v.faces);
1311 tets_skin = subtract(tets_skin,
v.faces);
1317 auto add_blockset = [&](
auto block_name,
auto &&tets_skin) {
1320 tets_skin.merge(crack_faces);
1324 auto subtract_blockset = [&](
auto block_name,
auto &&tets_skin) {
1325 auto contact_range =
1327 tets_skin = subtract(tets_skin, contact_range);
1331 auto get_stress_trace_faces = [&](
auto &&tets_skin) {
1334 faces, moab::Interface::UNION);
1335 Range trace_faces = subtract(faces, tets_skin);
1339 auto tets = get_tets();
1343 auto trace_faces = get_stress_trace_faces(
1345 subtract_blockset(
"CONTACT",
1346 subtract_boundary_conditions(get_tets_skin()))
1353 boost::make_shared<Range>(subtract(trace_faces, *
contactFaces));
1368 auto add_broken_hdiv_field = [
this, meshset](
const std::string
field_name,
1374 auto get_side_map_hdiv = [&]() {
1377 std::pair<EntityType,
1392 get_side_map_hdiv(), MB_TAG_DENSE,
MF_ZERO);
1398 auto add_l2_field = [
this, meshset](
const std::string
field_name,
1399 const int order,
const int dim) {
1408 auto add_h1_field = [
this, meshset](
const std::string
field_name,
1409 const int order,
const int dim) {
1421 auto add_l2_field_by_range = [
this](
const std::string
field_name,
1422 const int order,
const int dim,
1423 const int field_dim,
Range &&r) {
1433 auto add_bubble_field = [
this, meshset](
const std::string
field_name,
1434 const int order,
const int dim) {
1440 auto field_order_table =
1441 const_cast<Field *
>(field_ptr)->getFieldOrderTable();
1442 auto get_cgg_bubble_order_zero = [](
int p) {
return 0; };
1443 auto get_cgg_bubble_order_tet = [](
int p) {
1446 field_order_table[MBVERTEX] = get_cgg_bubble_order_zero;
1447 field_order_table[MBEDGE] = get_cgg_bubble_order_zero;
1448 field_order_table[MBTRI] = get_cgg_bubble_order_zero;
1449 field_order_table[MBTET] = get_cgg_bubble_order_tet;
1456 auto add_user_l2_field = [
this, meshset](
const std::string
field_name,
1457 const int order,
const int dim) {
1463 auto field_order_table =
1464 const_cast<Field *
>(field_ptr)->getFieldOrderTable();
1465 auto zero_dofs = [](
int p) {
return 0; };
1467 field_order_table[MBVERTEX] = zero_dofs;
1468 field_order_table[MBEDGE] = zero_dofs;
1469 field_order_table[MBTRI] = zero_dofs;
1470 field_order_table[MBTET] = dof_l2_tet;
1488 auto get_hybridised_disp = [&]() {
1490 auto skin = subtract_boundary_conditions(get_tets_skin());
1492 faces.merge(intersect(bc.faces, skin));
1498 get_hybridised_disp());
1525 auto project_ho_geometry = [&](
auto field) {
1531 auto get_adj_front_edges = [&](
auto &front_edges) {
1532 Range front_crack_nodes;
1533 Range crack_front_edges_with_both_nodes_not_at_front;
1538 moab.get_connectivity(front_edges, front_crack_nodes,
true),
1539 "get_connectivity failed");
1540 Range crack_front_edges;
1542 false, crack_front_edges,
1543 moab::Interface::UNION),
1544 "get_adjacencies failed");
1545 Range crack_front_edges_nodes;
1547 crack_front_edges_nodes,
true),
1548 "get_connectivity failed");
1550 crack_front_edges_nodes =
1551 subtract(crack_front_edges_nodes, front_crack_nodes);
1552 Range crack_front_edges_with_both_nodes_not_at_front;
1554 moab.get_adjacencies(crack_front_edges_nodes, 1,
false,
1555 crack_front_edges_with_both_nodes_not_at_front,
1556 moab::Interface::UNION),
1557 "get_adjacencies failed");
1559 crack_front_edges_with_both_nodes_not_at_front = intersect(
1560 crack_front_edges, crack_front_edges_with_both_nodes_not_at_front);
1564 crack_front_edges_with_both_nodes_not_at_front =
send_type(
1565 mField, crack_front_edges_with_both_nodes_not_at_front, MBEDGE);
1567 return std::make_pair(boost::make_shared<Range>(front_crack_nodes),
1568 boost::make_shared<Range>(
1569 crack_front_edges_with_both_nodes_not_at_front));
1572 if ((time -
crackingAddTime) > std::numeric_limits<double>::epsilon()) {
1580 auto [front_vertices, front_adj_edges] = get_adj_front_edges(*
frontEdges);
1585 <<
"Number of crack faces: " <<
crackFaces->size();
1587 <<
"Number of front edges: " <<
frontEdges->size();
1591 <<
"Number of front adjacent edges: " <<
frontAdjEdges->size();
1600 (boost::format(
"crack_faces_%d.vtk") % rank).str(),
1603 (boost::format(
"front_edges_%d.vtk") % rank).str(),
1614 auto set_singular_dofs = [&](
auto &front_adj_edges,
auto &front_vertices) {
1622 MOFEM_LOG(
"EP", Sev::inform) <<
"Singularity eps " << beta;
1627 [&](boost::shared_ptr<FieldEntity> field_entity_ptr) ->
MoFEMErrorCode {
1632 auto nb_dofs = field_entity_ptr->getEntFieldData().size();
1638 if (field_entity_ptr->getNbOfCoeffs() != 3)
1640 "Expected 3 coefficients per edge");
1641 if (nb_dofs % 3 != 0)
1643 "Expected multiple of 3 coefficients per edge");
1646 auto get_conn = [&]() {
1649 CHKERR moab.get_connectivity(field_entity_ptr->getEnt(), conn,
1651 return std::make_pair(conn, num_nodes);
1654 auto get_dir = [&](
auto &&conn_p) {
1655 auto [conn, num_nodes] = conn_p;
1657 CHKERR moab.get_coords(conn, num_nodes, coords);
1659 coords[4] - coords[1],
1660 coords[5] - coords[2]};
1664 auto get_singularity_dof = [&](
auto &&conn_p,
auto &&t_edge_dir) {
1665 auto [conn, num_nodes] = conn_p;
1667 if (front_vertices.find(conn[0]) != front_vertices.end()) {
1668 t_singularity_dof(
i) = t_edge_dir(
i) * (-
eps);
1669 }
else if (front_vertices.find(conn[1]) != front_vertices.end()) {
1670 t_singularity_dof(
i) = t_edge_dir(
i) *
eps;
1672 return t_singularity_dof;
1675 auto t_singularity_dof =
1676 get_singularity_dof(get_conn(), get_dir(get_conn()));
1678 auto field_data = field_entity_ptr->getEntFieldData();
1680 &field_data[0], &field_data[1], &field_data[2]};
1682 t_dof(
i) = t_singularity_dof(
i);
1684 for (
auto n = 1;
n < field_data.size() / 3; ++
n) {
1706 auto get_interface_from_block = [&](
auto block_name) {
1711 faces, moab::Interface::UNION);
1712 faces = subtract(faces, skin);
1714 <<
"Number of vol interface elements: " << vol_eles.size()
1715 <<
" and faces: " << faces.size();
1719 interfaceFaces->merge(get_interface_from_block(
"VOLUME_INTERFACE"));
1721 auto remove_interface_from_block = [&](
auto block_name,
auto level) {
1723 Range intreface_faces;
1726 for (
auto l = 0;
l < level; ++
l) {
1729 ents,
SPACE_DIM,
true, adj_tets, moab::Interface::UNION);
1730 Range adj_tets_faces;
1733 moab::Interface::UNION);
1734 ents.merge(adj_tets_faces);
1736 auto faces = ents.subset_by_dimension(
SPACE_DIM - 1);
1739 <<
"Removed ents " << faces.size()
1744 <<
"Interface faces after remove " << intreface_faces;
1746 auto intreface_faces_global =
send_type(
mField, intreface_faces, MBTRI);
1758#ifdef INCLUDE_MBCOUPLER
1760 char mesh_source_file[255] =
"source.h5m";
1761 char iterp_tag_name[255] =
"INTERNAL_STRESS";
1763 int interp_order = 1;
1764 PetscBool hybrid_interp = PETSC_TRUE;
1765 PetscBool project_internal_stress = PETSC_FALSE;
1767 double toler = 5.e-10;
1768 PetscOptionsBegin(PETSC_COMM_WORLD,
"mesh_transfer_",
"mesh data transfer",
1770 CHKERR PetscOptionsString(
"-source_file",
"source mesh file name",
"",
1771 "source.h5m", mesh_source_file, 255,
1772 &project_internal_stress);
1773 CHKERR PetscOptionsString(
"-interp_tag",
"interpolation tag name",
"",
1774 "INTERNAL_STRESS", iterp_tag_name, 255,
1776 CHKERR PetscOptionsInt(
"-interp_order",
"interpolation order",
"", 0,
1777 &interp_order, PETSC_NULLPTR);
1778 CHKERR PetscOptionsBool(
"-hybrid_interp",
"use hybrid interpolation",
"",
1779 hybrid_interp, &hybrid_interp, PETSC_NULLPTR);
1784 if (!project_internal_stress) {
1786 <<
"No internal stress source mesh specified. Skipping projection of "
1791 <<
"Projecting internal stress from source mesh: " << mesh_source_file;
1797 auto rval_check_tag = moab.tag_get_handle(iterp_tag_name, old_interp_tag);
1798 if (rval_check_tag == MB_SUCCESS) {
1800 <<
"Deleting existing tag on target mesh: " << iterp_tag_name;
1801 CHKERR moab.tag_delete(old_interp_tag);
1805 int world_rank = -1, world_size = -1;
1806 MPI_Comm_rank(PETSC_COMM_WORLD, &world_rank);
1807 MPI_Comm_size(PETSC_COMM_WORLD, &world_size);
1809 Range original_meshset_ents;
1810 CHKERR moab.get_entities_by_handle(0, original_meshset_ents);
1812 MPI_Comm comm_coupler;
1813 if (world_rank == 0) {
1814 MPI_Comm_split(PETSC_COMM_WORLD, 0, 0, &comm_coupler);
1816 MPI_Comm_split(PETSC_COMM_WORLD, MPI_UNDEFINED, world_rank, &comm_coupler);
1820 ParallelComm *pcomm0 =
nullptr;
1822 if (world_rank == 0) {
1823 pcomm0 =
new ParallelComm(&moab, comm_coupler, &pcomm0_id);
1826 Coupler::Method method;
1827 switch (interp_order) {
1829 method = Coupler::CONSTANT;
1832 method = Coupler::LINEAR_FE;
1836 "Unsupported interpolation order");
1840 ierr = MPI_Comm_size(PETSC_COMM_WORLD, &nprocs);
1842 ierr = MPI_Comm_rank(PETSC_COMM_WORLD, &rank);
1854 CHKERR moab.create_meshset(MESHSET_SET, target_root);
1856 <<
"Creating target mesh from existing meshset";
1857 Range target_meshset_ents;
1858 CHKERR moab.get_entities_by_handle(0, target_meshset_ents);
1859 CHKERR moab.add_entities(target_root, target_meshset_ents);
1867 Range targ_verts, targ_elems;
1868 if (world_rank == 0) {
1871 CHKERR moab.create_meshset(MESHSET_SET, source_root);
1873 MOFEM_LOG(
"WORLD", Sev::inform) <<
"Loading source mesh on rank 0";
1874 auto rval_source_mesh = moab.load_file(mesh_source_file, &source_root,
"");
1875 if (rval_source_mesh != MB_SUCCESS) {
1877 <<
"Error loading source mesh file: " << mesh_source_file;
1879 MOFEM_LOG(
"WORLD", Sev::inform) <<
"Source mesh loaded.";
1882 CHKERR moab.get_entities_by_dimension(source_root, 3, src_elems);
1885 CHKERR pcomm0->create_part(part_set);
1886 CHKERR moab.add_entities(part_set, src_elems);
1888 Range src_elems_part;
1889 CHKERR pcomm0->get_part_entities(src_elems_part, 3);
1892 CHKERR moab.tag_get_handle(iterp_tag_name, interp_tag);
1895 CHKERR moab.tag_get_length(interp_tag, interp_tag_len);
1897 if (interp_tag_len != 1 && interp_tag_len != 3 && interp_tag_len != 9) {
1899 "Unsupported interpolation tag length: %d", interp_tag_len);
1903 tag_length = interp_tag_len;
1904 CHKERR moab.tag_get_data_type(interp_tag, dtype);
1905 CHKERR moab.tag_get_type(interp_tag, storage);
1908 Coupler mbc(&moab, pcomm0, src_elems_part, 0,
true);
1910 std::vector<double> vpos;
1916 CHKERR moab.get_entities_by_dimension(target_root, 3, targ_elems);
1918 if (interp_order == 0) {
1919 targ_verts = targ_elems;
1921 CHKERR moab.get_adjacencies(targ_elems, 0,
false, targ_verts,
1922 moab::Interface::UNION);
1926 CHKERR pcomm0->get_pstatus_entities(0, PSTATUS_NOT_OWNED, tmp_verts);
1927 targ_verts = subtract(targ_verts, tmp_verts);
1930 num_pts = (int)targ_verts.size();
1931 vpos.resize(3 * targ_verts.size());
1932 CHKERR moab.get_coords(targ_verts, &vpos[0]);
1935 boost::shared_ptr<TupleList> tl_ptr;
1936 tl_ptr = boost::make_shared<TupleList>();
1937 CHKERR mbc.locate_points(&vpos[0], num_pts, 0, toler, tl_ptr.get(),
false);
1940 auto find_missing_points = [&](
Range &targ_verts,
int &num_pts,
1941 std::vector<double> &vpos,
1942 Range &missing_verts) {
1944 int missing_pts_num = 0;
1946 auto vit = targ_verts.begin();
1947 for (; vit != targ_verts.end();
i++) {
1948 if (tl_ptr->vi_rd[3 *
i + 1] == -1) {
1949 missing_verts.insert(*vit);
1950 vit = targ_verts.erase(vit);
1957 int missing_pts_num_global = 0;
1960 if (missing_pts_num_global) {
1962 << missing_pts_num_global
1963 <<
" points in target mesh were not located in source mesh. ";
1966 if (missing_pts_num) {
1967 num_pts = (int)targ_verts.size();
1968 vpos.resize(3 * targ_verts.size());
1969 CHKERR moab.get_coords(targ_verts, &vpos[0]);
1971 CHKERR mbc.locate_points(&vpos[0], num_pts, 0, toler, tl_ptr.get(),
1977 Range missing_verts;
1978 CHKERR find_missing_points(targ_verts, num_pts, vpos, missing_verts);
1980 std::vector<double> source_data(interp_tag_len * src_elems.size(), 0.0);
1981 std::vector<double> target_data(interp_tag_len * num_pts, 0.0);
1983 CHKERR moab.tag_get_data(interp_tag, src_elems, &source_data[0]);
1985 Tag scalar_tag, adj_count_tag;
1987 string scalar_tag_name = string(iterp_tag_name) +
"_COMP";
1988 CHKERR moab.tag_get_handle(scalar_tag_name.c_str(), 1, MB_TYPE_DOUBLE,
1989 scalar_tag, MB_TAG_CREAT | MB_TAG_DENSE,
1992 string adj_count_tag_name =
"ADJ_COUNT";
1994 CHKERR moab.tag_get_handle(adj_count_tag_name.c_str(), 1, MB_TYPE_DOUBLE,
1995 adj_count_tag, MB_TAG_CREAT | MB_TAG_DENSE,
2000 auto create_scalar_tags = [&](
const Range &src_elems,
2001 const std::vector<double> &source_data,
2005 std::vector<double> source_data_scalar(src_elems.size());
2007 for (
int ielem = 0; ielem < src_elems.size(); ielem++) {
2008 source_data_scalar[ielem] = source_data[itag + ielem * interp_tag_len];
2012 CHKERR moab.tag_set_data(scalar_tag, src_elems, &source_data_scalar[0]);
2014 if (interp_order == 1) {
2017 CHKERR moab.get_connectivity(src_elems, src_verts,
true);
2019 CHKERR moab.tag_clear_data(scalar_tag, src_verts, &def_scl);
2020 CHKERR moab.tag_clear_data(adj_count_tag, src_verts, &def_adj);
2022 for (
auto &tet : src_elems) {
2023 double tet_data = 0;
2024 CHKERR moab.tag_get_data(scalar_tag, &tet, 1, &tet_data);
2027 CHKERR moab.get_connectivity(&tet, 1, adj_verts,
true);
2029 std::vector<double> adj_vert_data(adj_verts.size(), 0.0);
2030 std::vector<double> adj_vert_count(adj_verts.size(), 0.0);
2032 CHKERR moab.tag_get_data(scalar_tag, adj_verts, &adj_vert_data[0]);
2033 CHKERR moab.tag_get_data(adj_count_tag, adj_verts,
2034 &adj_vert_count[0]);
2036 for (
int ivert = 0; ivert < adj_verts.size(); ivert++) {
2037 adj_vert_data[ivert] += tet_data;
2038 adj_vert_count[ivert] += 1;
2041 CHKERR moab.tag_set_data(scalar_tag, adj_verts, &adj_vert_data[0]);
2042 CHKERR moab.tag_set_data(adj_count_tag, adj_verts,
2043 &adj_vert_count[0]);
2047 std::vector<Tag> tags = {scalar_tag, adj_count_tag};
2048 pcomm0->reduce_tags(tags, tags, MPI_SUM, src_verts);
2050 std::vector<double> src_vert_data(src_verts.size(), 0.0);
2051 std::vector<double> src_vert_adj_count(src_verts.size(), 0.0);
2053 CHKERR moab.tag_get_data(scalar_tag, src_verts, &src_vert_data[0]);
2054 CHKERR moab.tag_get_data(adj_count_tag, src_verts,
2055 &src_vert_adj_count[0]);
2057 for (
int ivert = 0; ivert < src_verts.size(); ivert++) {
2058 src_vert_data[ivert] /= src_vert_adj_count[ivert];
2060 CHKERR moab.tag_set_data(scalar_tag, src_verts, &src_vert_data[0]);
2065 for (
int itag = 0; itag < interp_tag_len; itag++) {
2067 CHKERR create_scalar_tags(src_elems, source_data, itag);
2069 std::vector<double> target_data_scalar(num_pts, 0.0);
2070 CHKERR mbc.interpolate(method, scalar_tag_name, &target_data_scalar[0],
2073 for (
int ielem = 0; ielem < num_pts; ielem++) {
2074 target_data[itag + ielem * interp_tag_len] = target_data_scalar[ielem];
2079 CHKERR moab.tag_set_data(interp_tag, targ_verts, &target_data[0]);
2081 if (missing_verts.size() && (interp_order == 1) && hybrid_interp) {
2082 MOFEM_LOG(
"WORLD", Sev::warning) <<
"Using hybrid interpolation for "
2083 "missing points in the target mesh.";
2084 Range missing_adj_elems;
2085 CHKERR moab.get_adjacencies(missing_verts, 3,
false, missing_adj_elems,
2086 moab::Interface::UNION);
2088 int num_adj_elems = (int)missing_adj_elems.size();
2089 std::vector<double> vpos_adj_elems;
2091 vpos_adj_elems.resize(3 * missing_adj_elems.size());
2092 CHKERR moab.get_coords(missing_adj_elems, &vpos_adj_elems[0]);
2096 CHKERR mbc.locate_points(&vpos_adj_elems[0], num_adj_elems, 0, toler,
2097 tl_ptr.get(),
false);
2100 CHKERR find_missing_points(missing_adj_elems, num_adj_elems,
2101 vpos_adj_elems, missing_tets);
2102 if (missing_tets.size()) {
2104 << missing_tets.size()
2105 <<
"points in target mesh were not located in source mesh. ";
2108 std::vector<double> target_data_adj_elems(interp_tag_len * num_adj_elems,
2111 for (
int itag = 0; itag < interp_tag_len; itag++) {
2112 CHKERR create_scalar_tags(src_elems, source_data, itag);
2114 std::vector<double> target_data_adj_elems_scalar(num_adj_elems, 0.0);
2115 CHKERR mbc.interpolate(method, scalar_tag_name,
2116 &target_data_adj_elems_scalar[0], tl_ptr.get());
2118 for (
int ielem = 0; ielem < num_adj_elems; ielem++) {
2119 target_data_adj_elems[itag + ielem * interp_tag_len] =
2120 target_data_adj_elems_scalar[ielem];
2124 CHKERR moab.tag_set_data(interp_tag, missing_adj_elems,
2125 &target_data_adj_elems[0]);
2128 for (
auto &vert : missing_verts) {
2130 CHKERR moab.get_adjacencies(&vert, 1, 3,
false, adj_elems,
2131 moab::Interface::UNION);
2133 std::vector<double> adj_elems_data(adj_elems.size() * interp_tag_len,
2135 CHKERR moab.tag_get_data(interp_tag, adj_elems, &adj_elems_data[0]);
2137 std::vector<double> vert_data(interp_tag_len, 0.0);
2138 for (
int itag = 0; itag < interp_tag_len; itag++) {
2139 for (
int i = 0;
i < adj_elems.size();
i++) {
2140 vert_data[itag] += adj_elems_data[
i * interp_tag_len + itag];
2142 vert_data[itag] /= adj_elems.size();
2144 CHKERR moab.tag_set_data(interp_tag, &vert, 1, &vert_data[0]);
2148 CHKERR moab.tag_delete(scalar_tag);
2149 CHKERR moab.tag_delete(adj_count_tag);
2151 Range src_mesh_ents;
2152 CHKERR moab.get_entities_by_handle(source_root, src_mesh_ents);
2153 CHKERR moab.delete_entities(&source_root, 1);
2154 CHKERR moab.delete_entities(src_mesh_ents);
2155 CHKERR moab.delete_entities(&part_set, 1);
2159 MPI_Bcast(&tag_length, 1, MPI_INT, 0, PETSC_COMM_WORLD);
2160 MPI_Bcast(&dtype, 1, MPI_INT, 0, PETSC_COMM_WORLD);
2161 MPI_Bcast(&storage, 1, MPI_INT, 0, PETSC_COMM_WORLD);
2166 MB_TAG_CREAT | storage;
2167 std::vector<double> def_val(tag_length, 0.);
2168 CHKERR moab.tag_get_handle(iterp_tag_name, tag_length, dtype, interp_tag_all,
2169 flags, def_val.data());
2170 MPI_Barrier(PETSC_COMM_WORLD);
2192 CHKERR moab.delete_entities(&target_root, 1);
2203 auto add_field_to_fe = [
this](
const std::string fe,
2241 auto set_fe_adjacency = [&](
auto fe_name) {
2244 boost::make_shared<ParentFiniteElementAdjacencyFunctionSkeleton<2>>(
2252 auto add_field_to_fe = [
this](
const std::string fe,
2266 Range natural_bc_elements;
2269 natural_bc_elements.merge(
v.faces);
2274 natural_bc_elements.merge(
v.faces);
2279 natural_bc_elements.merge(
v.faces);
2284 natural_bc_elements.merge(
v.faces);
2289 natural_bc_elements.merge(
v.faces);
2294 natural_bc_elements.merge(
v.faces);
2299 natural_bc_elements.merge(
v.faces);
2302 natural_bc_elements = intersect(natural_bc_elements, meshset_ents);
2313 auto get_skin = [&](
auto &body_ents) {
2316 CHKERR skin.find_skin(0, body_ents,
false, skin_ents);
2321 Range boundary_ents;
2322 ParallelComm *pcomm =
2324 CHKERR pcomm->filter_pstatus(skin, PSTATUS_SHARED | PSTATUS_MULTISHARED,
2325 PSTATUS_NOT, -1, &boundary_ents);
2326 return boundary_ents;
2408 auto remove_dofs_on_broken_skin = [&](
const std::string prb_name) {
2410 for (
int d : {0, 1, 2}) {
2411 std::vector<boost::weak_ptr<NumeredDofEntity>> dofs_to_remove;
2413 ->getSideDofsOnBrokenSpaceEntities(
2424 CHKERR remove_dofs_on_broken_skin(
"ESHELBY_PLASTICITY");
2467 auto set_zero_block = [&]() {
2499 auto set_section = [&]() {
2501 PetscSection section;
2506 CHKERR PetscSectionDestroy(§ion);
2529BcDisp::BcDisp(std::string name, std::vector<double> attr,
Range faces)
2530 : blockName(name), faces(faces) {
2531 vals.resize(3,
false);
2532 flags.resize(3,
false);
2533 for (
int ii = 0; ii != 3; ++ii) {
2534 vals[ii] = attr[ii];
2535 flags[ii] =
static_cast<int>(attr[ii + 3]);
2538 MOFEM_LOG(
"EP", Sev::inform) <<
"Add BCDisp " << name;
2540 <<
"Add BCDisp vals " <<
vals[0] <<
" " <<
vals[1] <<
" " <<
vals[2];
2542 <<
"Add BCDisp flags " <<
flags[0] <<
" " <<
flags[1] <<
" " <<
flags[2];
2543 MOFEM_LOG(
"EP", Sev::inform) <<
"Add BCDisp nb. of faces " <<
faces.size();
2547 : blockName(name), faces(faces) {
2548 vals.resize(attr.size(),
false);
2549 for (
int ii = 0; ii != attr.size(); ++ii) {
2550 vals[ii] = attr[ii];
2556 : blockName(name), faces(faces) {
2557 vals.resize(3,
false);
2558 flags.resize(3,
false);
2559 for (
int ii = 0; ii != 3; ++ii) {
2560 vals[ii] = attr[ii];
2561 flags[ii] =
static_cast<int>(attr[ii + 3]);
2564 MOFEM_LOG(
"EP", Sev::inform) <<
"Add BCForce " << name;
2566 <<
"Add BCForce vals " <<
vals[0] <<
" " <<
vals[1] <<
" " <<
vals[2];
2568 <<
"Add BCForce flags " <<
flags[0] <<
" " <<
flags[1] <<
" " <<
flags[2];
2569 MOFEM_LOG(
"EP", Sev::inform) <<
"Add BCForce nb. of faces " <<
faces.size();
2573 std::vector<double> attr,
2575 : blockName(name), faces(faces) {
2578 if (attr.size() < 1) {
2580 "Wrong size of normal displacement BC");
2585 MOFEM_LOG(
"EP", Sev::inform) <<
"Add NormalDisplacementBc " << name;
2586 MOFEM_LOG(
"EP", Sev::inform) <<
"Add NormalDisplacementBc val " <<
val;
2588 <<
"Add NormalDisplacementBc nb. of faces " <<
faces.size();
2592 : blockName(name), faces(faces) {
2595 if (attr.size() < 1) {
2597 "Wrong size of normal displacement BC");
2602 MOFEM_LOG(
"EP", Sev::inform) <<
"Add PressureBc " << name;
2603 MOFEM_LOG(
"EP", Sev::inform) <<
"Add PressureBc val " <<
val;
2605 <<
"Add PressureBc nb. of faces " <<
faces.size();
2610 : blockName(name), ents(ents) {
2613 if (attr.size() < 2) {
2615 "Wrong size of external strain attribute");
2621 MOFEM_LOG(
"EP", Sev::inform) <<
"Add ExternalStrain " << name;
2622 MOFEM_LOG(
"EP", Sev::inform) <<
"Add ExternalStrain val " <<
val;
2623 MOFEM_LOG(
"EP", Sev::inform) <<
"Add ExternalStrain bulk modulus K "
2626 <<
"Add ExternalStrain bulk modulus K " <<
bulkModulusK;
2628 <<
"Add ExternalStrain nb. of tets " <<
ents.size();
2632 std::vector<double> attr,
2634 : blockName(name), faces(faces) {
2637 if (attr.size() < 3) {
2639 "Wrong size of analytical displacement BC");
2642 flags.resize(3,
false);
2643 for (
int ii = 0; ii != 3; ++ii) {
2644 flags[ii] = attr[ii];
2647 MOFEM_LOG(
"EP", Sev::inform) <<
"Add AnalyticalDisplacementBc " << name;
2649 <<
"Add AnalyticalDisplacementBc flags " <<
flags[0] <<
" " <<
flags[1]
2652 <<
"Add AnalyticalDisplacementBc nb. of faces " <<
faces.size();
2656 std::vector<double> attr,
2658 : blockName(name), faces(faces) {
2661 if (attr.size() < 3) {
2663 "Wrong size of analytical traction BC");
2666 flags.resize(3,
false);
2667 for (
int ii = 0; ii != 3; ++ii) {
2668 flags[ii] = attr[ii];
2671 MOFEM_LOG(
"EP", Sev::inform) <<
"Add AnalyticalTractionBc " << name;
2672 MOFEM_LOG(
"EP", Sev::inform) <<
"Add AnalyticalTractionBc flags " <<
flags[0]
2675 <<
"Add AnalyticalTractionBc nb. of faces " <<
faces.size();
2680 boost::shared_ptr<TractionFreeBc> &bc_ptr,
2681 const std::string contact_set_name) {
2686 CHKERR mField.get_moab().get_entities_by_type(meshset, MBTET, tets);
2687 Range tets_skin_part;
2688 Skinner skin(&mField.get_moab());
2689 CHKERR skin.find_skin(0, tets,
false, tets_skin_part);
2690 ParallelComm *pcomm =
2693 CHKERR pcomm->filter_pstatus(tets_skin_part,
2694 PSTATUS_SHARED | PSTATUS_MULTISHARED,
2695 PSTATUS_NOT, -1, &tets_skin);
2698 for (
int dd = 0; dd != 3; ++dd)
2699 (*bc_ptr)[dd] = tets_skin;
2702 if (bcSpatialDispVecPtr)
2703 for (
auto &
v : *bcSpatialDispVecPtr) {
2705 (*bc_ptr)[0] = subtract((*bc_ptr)[0],
v.faces);
2707 (*bc_ptr)[1] = subtract((*bc_ptr)[1],
v.faces);
2709 (*bc_ptr)[2] = subtract((*bc_ptr)[2],
v.faces);
2713 if (bcSpatialRotationVecPtr)
2714 for (
auto &
v : *bcSpatialRotationVecPtr) {
2715 (*bc_ptr)[0] = subtract((*bc_ptr)[0],
v.faces);
2716 (*bc_ptr)[1] = subtract((*bc_ptr)[1],
v.faces);
2717 (*bc_ptr)[2] = subtract((*bc_ptr)[2],
v.faces);
2720 if (bcSpatialNormalDisplacementVecPtr)
2721 for (
auto &
v : *bcSpatialNormalDisplacementVecPtr) {
2722 (*bc_ptr)[0] = subtract((*bc_ptr)[0],
v.faces);
2723 (*bc_ptr)[1] = subtract((*bc_ptr)[1],
v.faces);
2724 (*bc_ptr)[2] = subtract((*bc_ptr)[2],
v.faces);
2727 if (bcSpatialAnalyticalDisplacementVecPtr)
2728 for (
auto &
v : *bcSpatialAnalyticalDisplacementVecPtr) {
2730 (*bc_ptr)[0] = subtract((*bc_ptr)[0],
v.faces);
2732 (*bc_ptr)[1] = subtract((*bc_ptr)[1],
v.faces);
2734 (*bc_ptr)[2] = subtract((*bc_ptr)[2],
v.faces);
2737 if (bcSpatialTractionVecPtr)
2738 for (
auto &
v : *bcSpatialTractionVecPtr) {
2739 (*bc_ptr)[0] = subtract((*bc_ptr)[0],
v.faces);
2740 (*bc_ptr)[1] = subtract((*bc_ptr)[1],
v.faces);
2741 (*bc_ptr)[2] = subtract((*bc_ptr)[2],
v.faces);
2744 if (bcSpatialAnalyticalTractionVecPtr)
2745 for (
auto &
v : *bcSpatialAnalyticalTractionVecPtr) {
2746 (*bc_ptr)[0] = subtract((*bc_ptr)[0],
v.faces);
2747 (*bc_ptr)[1] = subtract((*bc_ptr)[1],
v.faces);
2748 (*bc_ptr)[2] = subtract((*bc_ptr)[2],
v.faces);
2751 if (bcSpatialPressureVecPtr)
2752 for (
auto &
v : *bcSpatialPressureVecPtr) {
2753 (*bc_ptr)[0] = subtract((*bc_ptr)[0],
v.faces);
2754 (*bc_ptr)[1] = subtract((*bc_ptr)[1],
v.faces);
2755 (*bc_ptr)[2] = subtract((*bc_ptr)[2],
v.faces);
2760 std::regex((boost::format(
"%s(.*)") % contact_set_name).str()))) {
2762 CHKERR m->getMeshsetIdEntitiesByDimension(mField.get_moab(), 2, faces,
2764 (*bc_ptr)[0] = subtract((*bc_ptr)[0], faces);
2765 (*bc_ptr)[1] = subtract((*bc_ptr)[1], faces);
2766 (*bc_ptr)[2] = subtract((*bc_ptr)[2], faces);
2783 return 2 * p_data + 1;
2789 return 2 * (p_data + 1);
2794 const int tag,
const bool do_rhs,
const bool do_lhs,
const bool calc_rates,
2795 boost::shared_ptr<VolumeElementForcesAndSourcesCore> fe) {
2799 boost::make_shared<CGGUserPolynomialBase::CachePhi>(0, 0,
MatrixDouble());
2800 fe->getUserPolynomialBase() =
2801 boost::make_shared<CGGUserPolynomialBase>(bubble_cache);
2802 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
2803 fe->getOpPtrVector(), {HDIV, H1, L2}, materialH1Positions, frontAdjEdges);
2806 fe->getRuleHook = [](int, int, int) {
return -1; };
2807 auto vol_rule_lin = [](
int o) {
return 2 * o + 1; };
2808 auto vol_rule_no_lin = [](
int o) {
return 2 * o + (o - 1) + 1; };
2809 auto vol_rule = (
SMALL_ROT > 0) ? vol_rule_lin : vol_rule_no_lin;
2810 fe->setRuleHook = SetIntegrationAtFrontVolume(frontVertices, frontAdjEdges,
2811 vol_rule, bubble_cache);
2817 dataAtPts->physicsPtr = physicalEquations;
2822 piolaStress, dataAtPts->getApproxPAtPts()));
2824 bubbleField, dataAtPts->getApproxPAtPts(), MBMAXTYPE));
2826 piolaStress, dataAtPts->getDivPAtPts()));
2829 fe->getOpPtrVector().push_back(
2830 physicalEquations->returnOpCalculateStretchFromStress(
2831 dataAtPts, physicalEquations));
2833 fe->getOpPtrVector().push_back(
2835 stretchTensor, dataAtPts->getLogStretchTensorAtPts(), MBTET));
2839 rotAxis, dataAtPts->getRotAxisAtPts(), MBTET));
2840 CHKERR VecSetDM(solTSStep, PETSC_NULLPTR);
2842 rotAxis, dataAtPts->getRotAxis0AtPts(), solTSStep, MBTET));
2844 spatialL2Disp, dataAtPts->getSmallWL2AtPts(), MBTET));
2848 spatialH1Disp, dataAtPts->getSmallWH1AtPts()));
2850 spatialH1Disp, dataAtPts->getSmallWGradH1AtPts()));
2855 spatialL2Disp, dataAtPts->getSmallWL2DotAtPts(), MBTET));
2858 fe->getOpPtrVector().push_back(
2860 stretchTensor, dataAtPts->getLogStretchDotTensorAtPts(), MBTET));
2861 fe->getOpPtrVector().push_back(
2863 stretchTensor, dataAtPts->getGradLogStretchDotTensorAtPts(),
2867 rotAxis, dataAtPts->getRotAxisDotAtPts(), MBTET));
2869 rotAxis, dataAtPts->getRotAxisGradDotAtPts(), MBTET));
2872 if (std::abs(alphaRho) > std::numeric_limits<double>::epsilon()) {
2874 spatialL2Disp, dataAtPts->getSmallWL2DotDotAtPts(), MBTET));
2880 dataAtPts, ((do_rhs || do_lhs) && calc_rates) ? alphaOmega : 0.));
2885 fe->getOpPtrVector().push_back(physicalEquations->returnOpJacobian(
2886 tag, do_rhs, do_lhs, dataAtPts, physicalEquations));
2893 const int tag,
const bool add_elastic,
const bool add_material,
2894 boost::shared_ptr<VolumeElementForcesAndSourcesCore> &fe_rhs,
2895 boost::shared_ptr<VolumeElementForcesAndSourcesCore> &fe_lhs) {
2900 std::map<int, Range> map;
2903 mField.getInterface<
MeshsetsManager>()->getCubitMeshsetPtr(std::regex(
2905 (boost::format(
"%s(.*)") % name).str()
2911 CHK_MOAB_THROW(m_ptr->getMeshsetIdEntitiesByDimension(mField.get_moab(),
2914 map[m_ptr->getMeshsetId()] = ents;
2920 constexpr bool stab_tau_dot_variant =
false;
2922 auto local_tau_sacale = boost::make_shared<double>(1.0);
2925 using BdyEleOp = BoundaryEle::UserDataOperator;
2926 struct OpSetTauScale :
public BdyEleOp {
2927 OpSetTauScale(boost::shared_ptr<double> local_tau_sacale,
double alphaTau)
2929 localTauSacale(local_tau_sacale), alphaTau(alphaTau) {}
2933 auto h = std::sqrt(getFTensor1Normal().l2());
2934 *localTauSacale = (alphaTau /
h);
2939 boost::shared_ptr<double> localTauSacale;
2943 auto not_interface_face = [
this](
FEMethod *fe_method_ptr) {
2944 auto ent = fe_method_ptr->getFEEntityHandle();
2947 (interfaceFaces->find(ent) != interfaceFaces->end())
2949 || (crackFaces->find(ent) != crackFaces->end())
2958 fe_rhs = boost::make_shared<VolumeElementForcesAndSourcesCore>(mField);
2959 CHKERR setBaseVolumeElementOps(tag,
true,
false,
true, fe_rhs);
2964 fe_rhs->getOpPtrVector().push_back(
2966 fe_rhs->getOpPtrVector().push_back(
2971 if (!internalStressTagName.empty()) {
2972 switch (internalStressInterpOrder) {
2974 fe_rhs->getOpPtrVector().push_back(
2978 fe_rhs->getOpPtrVector().push_back(
2983 "Unsupported internal stress interpolation order %d",
2984 internalStressInterpOrder);
2988 auto ts_internal_stress =
2989 boost::make_shared<DynamicRelaxationTimeScale>(
2990 "internal_stress_history.txt",
false, def_scaling_fun);
2991 if (internalStressVoigt) {
2992 fe_rhs->getOpPtrVector().push_back(
2994 stretchTensor, dataAtPts, ts_internal_stress));
2996 fe_rhs->getOpPtrVector().push_back(
2998 stretchTensor, dataAtPts, ts_internal_stress));
3001 if (
auto op = physicalEquations->returnOpSpatialPhysicalExternalStrain(
3002 stretchTensor, dataAtPts, externalStrainVecPtr, timeScaleMap)) {
3003 fe_rhs->getOpPtrVector().push_back(op);
3004 }
else if (externalStrainVecPtr && !externalStrainVecPtr->empty()) {
3006 "OpSpatialPhysicalExternalStrain not implemented for this "
3010 fe_rhs->getOpPtrVector().push_back(
3011 physicalEquations->returnOpSpatialPhysical(stretchTensor, dataAtPts,
3014 fe_rhs->getOpPtrVector().push_back(
3016 fe_rhs->getOpPtrVector().push_back(
3018 fe_rhs->getOpPtrVector().push_back(
3021 auto set_hybridisation_rhs = [&](
auto &pip) {
3028 using SideEleOp = EleOnSide::UserDataOperator;
3029 using BdyEleOp = BoundaryEle::UserDataOperator;
3034 mField, skeletonElement,
SPACE_DIM - 1, Sev::noisy);
3036 op_loop_skeleton_side->getSideFEPtr()->getRuleHook = [](int, int, int) {
3039 op_loop_skeleton_side->getSideFEPtr()->setRuleHook =
3040 SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
3042 CHKERR EshelbianPlasticity::
3043 AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
3044 op_loop_skeleton_side->getOpPtrVector(), {L2},
3045 materialH1Positions, frontAdjEdges);
3049 auto broken_data_ptr =
3050 boost::make_shared<std::vector<BrokenBaseSideData>>();
3053 mField, elementVolumeName,
SPACE_DIM, Sev::noisy);
3054 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
3055 boost::make_shared<CGGUserPolynomialBase>(
nullptr,
true);
3057 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
3058 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
3059 materialH1Positions, frontAdjEdges);
3060 op_loop_domain_side->getOpPtrVector().push_back(
3062 auto flux_mat_ptr = boost::make_shared<MatrixDouble>();
3063 op_loop_domain_side->getOpPtrVector().push_back(
3066 op_loop_domain_side->getOpPtrVector().push_back(
3070 op_loop_skeleton_side->getOpPtrVector().push_back(op_loop_domain_side);
3072 GAUSS>::OpBrokenSpaceConstrainDHybrid<SPACE_DIM>;
3074 GAUSS>::OpBrokenSpaceConstrainDFlux<SPACE_DIM>;
3075 op_loop_skeleton_side->getOpPtrVector().push_back(
new OpC_dHybrid(
3076 hybridSpatialDisp, broken_data_ptr, boost::make_shared<double>(1.0)));
3077 auto hybrid_ptr = boost::make_shared<MatrixDouble>();
3078 op_loop_skeleton_side->getOpPtrVector().push_back(
3081 op_loop_skeleton_side->getOpPtrVector().push_back(
new OpC_dBroken(
3082 broken_data_ptr, hybrid_ptr, boost::make_shared<double>(1.0)));
3085 pip.push_back(op_loop_skeleton_side);
3090 auto set_tau_stabilsation_rhs = [&](
auto &pip,
auto side_fe_name,
3091 auto hybrid_field) {
3098 using SideEleOp = EleOnSide::UserDataOperator;
3099 using BdyEleOp = BoundaryEle::UserDataOperator;
3104 mField, side_fe_name,
SPACE_DIM - 1, Sev::noisy);
3106 op_loop_skeleton_side->getSideFEPtr()->getRuleHook = [](int, int, int) {
3109 op_loop_skeleton_side->getSideFEPtr()->setRuleHook =
3110 SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
3111 CHKERR EshelbianPlasticity::
3112 AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
3113 op_loop_skeleton_side->getOpPtrVector(), {L2},
3114 materialH1Positions, frontAdjEdges);
3117 mField, elementVolumeName,
SPACE_DIM, Sev::noisy);
3118 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
3119 boost::make_shared<CGGUserPolynomialBase>(
nullptr,
true);
3121 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
3122 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
3123 materialH1Positions, frontAdjEdges);
3126 auto broken_disp_data_ptr =
3127 boost::make_shared<std::vector<BrokenBaseSideData>>();
3128 op_loop_domain_side->getOpPtrVector().push_back(
3130 broken_disp_data_ptr));
3131 auto disp_mat_ptr = boost::make_shared<MatrixDouble>();
3132 if (stab_tau_dot_variant) {
3133 op_loop_domain_side->getOpPtrVector().push_back(
3137 op_loop_domain_side->getOpPtrVector().push_back(
3142 op_loop_domain_side->getOpPtrVector().push_back(
3145 op_loop_skeleton_side->getOpPtrVector().push_back(op_loop_domain_side);
3146 op_loop_skeleton_side->getOpPtrVector().push_back(
3147 new OpSetTauScale(local_tau_sacale, alphaTau));
3150 auto hybrid_ptr = boost::make_shared<MatrixDouble>();
3151 if (stab_tau_dot_variant) {
3152 op_loop_skeleton_side->getOpPtrVector().push_back(
3156 op_loop_skeleton_side->getOpPtrVector().push_back(
3162 op_loop_skeleton_side->getOpPtrVector().push_back(
3164 hybrid_field, hybrid_ptr,
3165 [local_tau_sacale, broken_disp_data_ptr](
double,
double,
double) {
3166 return broken_disp_data_ptr->size() * (*local_tau_sacale);
3169 op_loop_skeleton_side->getOpPtrVector().push_back(
3171 broken_disp_data_ptr, [local_tau_sacale](
double,
double,
double) {
3172 return (*local_tau_sacale);
3175 op_loop_skeleton_side->getOpPtrVector().push_back(
3177 hybrid_field, broken_disp_data_ptr,
3178 [local_tau_sacale](
double,
double,
double) {
3179 return -(*local_tau_sacale);
3182 op_loop_skeleton_side->getOpPtrVector().push_back(
3184 broken_disp_data_ptr, hybrid_ptr,
3185 [local_tau_sacale](
double,
double,
double) {
3186 return -(*local_tau_sacale);
3190 pip.push_back(op_loop_skeleton_side);
3195 auto set_contact_rhs = [&](
auto &pip) {
3199 auto set_cohesive_rhs = [&](
auto &pip) {
3202 SetIntegrationAtFrontFace(frontVertices, frontAdjEdges,
3203 [](
int p) {
return 2 * (p + 1) + 1; }),
3204 interfaceFaces, pip);
3207 CHKERR set_hybridisation_rhs(fe_rhs->getOpPtrVector());
3208 CHKERR set_contact_rhs(fe_rhs->getOpPtrVector());
3209 if (alphaTau > 0.0) {
3210 CHKERR set_tau_stabilsation_rhs(fe_rhs->getOpPtrVector(), skeletonElement,
3212 CHKERR set_tau_stabilsation_rhs(fe_rhs->getOpPtrVector(), contactElement,
3215 if (interfaceCrack == PETSC_TRUE) {
3216 CHKERR set_cohesive_rhs(fe_rhs->getOpPtrVector());
3220 using BodyNaturalBC =
3222 Assembly<PETSC>::LinearForm<
GAUSS>;
3224 BodyNaturalBC::OpFlux<NaturalMeshsetType<BLOCKSET>, 1, 3>;
3226 auto body_time_scale =
3227 boost::make_shared<DynamicRelaxationTimeScale>(
"body_force.txt");
3228 CHKERR BodyNaturalBC::AddFluxToPipeline<OpBodyForce>::add(
3229 fe_rhs->getOpPtrVector(), mField, spatialL2Disp, {body_time_scale},
3230 "BODY_FORCE", Sev::inform);
3234 fe_lhs = boost::make_shared<VolumeElementForcesAndSourcesCore>(mField);
3235 CHKERR setBaseVolumeElementOps(tag,
true,
true,
true, fe_lhs);
3241 fe_lhs->getOpPtrVector().push_back(
3244 bubbleField, piolaStress, dataAtPts));
3245 fe_lhs->getOpPtrVector().push_back(
3249 fe_lhs->getOpPtrVector().push_back(
3250 physicalEquations->returnOpSpatialPhysical_du_du(
3251 stretchTensor, stretchTensor, dataAtPts, alphaU));
3253 stretchTensor, piolaStress, dataAtPts,
true));
3255 stretchTensor, bubbleField, dataAtPts,
true));
3257 stretchTensor, rotAxis, dataAtPts,
3258 symmetrySelector ==
SYMMETRIC ?
true :
false));
3262 spatialL2Disp, piolaStress, dataAtPts,
true));
3264 spatialL2Disp, spatialL2Disp, dataAtPts, alphaW, alphaRho));
3267 piolaStress, rotAxis, dataAtPts,
3268 symmetrySelector ==
SYMMETRIC ?
true :
false));
3270 bubbleField, rotAxis, dataAtPts,
3271 symmetrySelector ==
SYMMETRIC ?
true :
false));
3276 rotAxis, stretchTensor, dataAtPts,
false));
3279 rotAxis, piolaStress, dataAtPts,
false));
3281 rotAxis, bubbleField, dataAtPts,
false));
3284 rotAxis, rotAxis, dataAtPts, alphaOmega));
3286 auto set_hybridisation_lhs = [&](
auto &pip) {
3293 using SideEleOp = EleOnSide::UserDataOperator;
3294 using BdyEleOp = BoundaryEle::UserDataOperator;
3299 mField, skeletonElement,
SPACE_DIM - 1, Sev::noisy);
3300 op_loop_skeleton_side->getSideFEPtr()->getRuleHook = [](int, int, int) {
3303 op_loop_skeleton_side->getSideFEPtr()->setRuleHook =
3304 SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
3305 CHKERR EshelbianPlasticity::
3306 AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
3307 op_loop_skeleton_side->getOpPtrVector(), {L2},
3308 materialH1Positions, frontAdjEdges);
3312 auto broken_data_ptr =
3313 boost::make_shared<std::vector<BrokenBaseSideData>>();
3316 mField, elementVolumeName,
SPACE_DIM, Sev::noisy);
3317 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
3318 boost::make_shared<CGGUserPolynomialBase>(
nullptr,
true);
3320 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
3321 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
3322 materialH1Positions, frontAdjEdges);
3323 op_loop_domain_side->getOpPtrVector().push_back(
3326 op_loop_skeleton_side->getOpPtrVector().push_back(op_loop_domain_side);
3328 GAUSS>::OpBrokenSpaceConstrain<SPACE_DIM>;
3329 op_loop_skeleton_side->getOpPtrVector().push_back(
3330 new OpC(hybridSpatialDisp, broken_data_ptr,
3331 boost::make_shared<double>(1.0),
true,
false));
3333 pip.push_back(op_loop_skeleton_side);
3338 auto set_tau_stabilsation_lhs = [&](
auto &pip,
auto side_fe_name,
3339 auto hybrid_field) {
3346 using SideEleOp = EleOnSide::UserDataOperator;
3347 using BdyEleOp = BoundaryEle::UserDataOperator;
3352 mField, side_fe_name,
SPACE_DIM - 1, Sev::noisy);
3353 op_loop_skeleton_side->getSideFEPtr()->getRuleHook = [](int, int, int) {
3356 op_loop_skeleton_side->getSideFEPtr()->setRuleHook =
3357 SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
3358 CHKERR EshelbianPlasticity::
3359 AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
3360 op_loop_skeleton_side->getOpPtrVector(), {L2},
3361 materialH1Positions, frontAdjEdges);
3365 mField, elementVolumeName,
SPACE_DIM, Sev::noisy);
3366 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
3367 boost::make_shared<CGGUserPolynomialBase>(
nullptr,
true);
3369 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
3370 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
3371 materialH1Positions, frontAdjEdges);
3373 auto broken_disp_data_ptr =
3374 boost::make_shared<std::vector<BrokenBaseSideData>>();
3375 op_loop_domain_side->getOpPtrVector().push_back(
3377 broken_disp_data_ptr));
3378 op_loop_skeleton_side->getOpPtrVector().push_back(op_loop_domain_side);
3379 op_loop_skeleton_side->getOpPtrVector().push_back(
3380 new OpSetTauScale(local_tau_sacale, alphaTau));
3382 auto time_shift = [](
const FEMethod *fe_ptr) {
return fe_ptr->ts_a; };
3386 hybrid_field, hybrid_field,
3387 [local_tau_sacale, broken_disp_data_ptr](
double,
double,
double) {
3388 return broken_disp_data_ptr->size() * (*local_tau_sacale);
3390 if (stab_tau_dot_variant) {
3392 op_loop_skeleton_side->getOpPtrVector().back())
3393 .feScalingFun = time_shift;
3396 op_loop_skeleton_side->getOpPtrVector().push_back(
3398 broken_disp_data_ptr, [local_tau_sacale](
double,
double,
double) {
3399 return (*local_tau_sacale);
3401 if (stab_tau_dot_variant) {
3403 op_loop_skeleton_side->getOpPtrVector().back())
3404 .feScalingFun = time_shift;
3407 op_loop_skeleton_side->getOpPtrVector().push_back(
3409 hybrid_field, broken_disp_data_ptr,
3410 [local_tau_sacale](
double,
double,
double) {
3411 return -(*local_tau_sacale);
3414 if (stab_tau_dot_variant) {
3416 op_loop_skeleton_side->getOpPtrVector().back())
3417 .feScalingFun = time_shift;
3421 op_loop_skeleton_side->getOpPtrVector().push_back(
3423 hybrid_field, broken_disp_data_ptr,
3424 [local_tau_sacale](
double,
double,
double) {
3425 return -(*local_tau_sacale);
3428 if (stab_tau_dot_variant) {
3430 op_loop_skeleton_side->getOpPtrVector().back())
3431 .feScalingFun = time_shift;
3434 pip.push_back(op_loop_skeleton_side);
3439 auto set_contact_lhs = [&](
auto &pip) {
3443 auto set_cohesive_lhs = [&](
auto &pip) {
3446 SetIntegrationAtFrontFace(frontVertices, frontAdjEdges,
3447 [](
int p) {
return 2 * (p + 1) + 1; }),
3448 interfaceFaces, pip);
3451 CHKERR set_hybridisation_lhs(fe_lhs->getOpPtrVector());
3452 CHKERR set_contact_lhs(fe_lhs->getOpPtrVector());
3453 if (alphaTau > 0.0) {
3454 CHKERR set_tau_stabilsation_lhs(fe_lhs->getOpPtrVector(), skeletonElement,
3456 CHKERR set_tau_stabilsation_lhs(fe_lhs->getOpPtrVector(), contactElement,
3459 if (interfaceCrack == PETSC_TRUE) {
3460 CHKERR set_cohesive_lhs(fe_lhs->getOpPtrVector());
3471 const bool add_elastic,
const bool add_material,
3472 boost::shared_ptr<FaceElementForcesAndSourcesCore> &fe_rhs,
3473 boost::shared_ptr<FaceElementForcesAndSourcesCore> &fe_lhs) {
3476 fe_rhs = boost::make_shared<FaceElementForcesAndSourcesCore>(mField);
3477 fe_lhs = boost::make_shared<FaceElementForcesAndSourcesCore>(mField);
3482 fe_rhs->getRuleHook = [](int, int, int) {
return -1; };
3483 fe_lhs->getRuleHook = [](int, int, int) {
return -1; };
3484 fe_rhs->setRuleHook = SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
3485 fe_lhs->setRuleHook = SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
3488 EshelbianPlasticity::AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
3489 fe_rhs->getOpPtrVector(), {L2}, materialH1Positions, frontAdjEdges);
3491 EshelbianPlasticity::AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
3492 fe_lhs->getOpPtrVector(), {L2}, materialH1Positions, frontAdjEdges);
3496 auto get_broken_op_side = [
this](
auto &pip) {
3499 using SideEleOp = EleOnSide::UserDataOperator;
3501 auto broken_data_ptr =
3502 boost::make_shared<std::vector<BrokenBaseSideData>>();
3505 mField, elementVolumeName,
SPACE_DIM, Sev::noisy);
3506 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
3507 boost::make_shared<CGGUserPolynomialBase>(
nullptr,
true);
3509 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
3510 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
3511 materialH1Positions, frontAdjEdges);
3512 op_loop_domain_side->getOpPtrVector().push_back(
3514 boost::shared_ptr<double> piola_scale_ptr(
new double);
3515 op_loop_domain_side->getOpPtrVector().push_back(
3516 physicalEquations->returnOpSetScale(piola_scale_ptr,
3517 physicalEquations));
3518 auto flux_mat_ptr = boost::make_shared<MatrixDouble>();
3519 op_loop_domain_side->getOpPtrVector().push_back(
3522 op_loop_domain_side->getOpPtrVector().push_back(
3524 pip.push_back(op_loop_domain_side);
3525 return std::make_tuple(broken_data_ptr, piola_scale_ptr);
3528 auto set_rhs = [&]() {
3531 auto [broken_data_ptr, piola_scale_ptr] =
3532 get_broken_op_side(fe_rhs->getOpPtrVector());
3534 fe_rhs->getOpPtrVector().push_back(
3535 new OpDispBc(broken_data_ptr, bcSpatialDispVecPtr, timeScaleMap));
3537 broken_data_ptr, bcSpatialAnalyticalDisplacementVecPtr,
3540 broken_data_ptr, bcSpatialRotationVecPtr, timeScaleMap));
3542 fe_rhs->getOpPtrVector().push_back(
3544 piola_scale_ptr, timeScaleMap));
3545 auto hybrid_grad_ptr = boost::make_shared<MatrixDouble>();
3547 fe_rhs->getOpPtrVector().push_back(
3549 hybridSpatialDisp, hybrid_grad_ptr));
3551 hybridSpatialDisp, bcSpatialPressureVecPtr, piola_scale_ptr,
3552 hybrid_grad_ptr, timeScaleMap));
3554 hybridSpatialDisp, bcSpatialAnalyticalTractionVecPtr, piola_scale_ptr,
3557 auto hybrid_ptr = boost::make_shared<MatrixDouble>();
3558 fe_rhs->getOpPtrVector().push_back(
3562 hybridSpatialDisp, hybrid_ptr, broken_data_ptr,
3563 bcSpatialNormalDisplacementVecPtr, timeScaleMap));
3565 auto get_normal_disp_bc_faces = [&]() {
3568 return boost::make_shared<Range>(faces);
3573 using BdyEleOp = BoundaryEle::UserDataOperator;
3575 GAUSS>::OpBrokenSpaceConstrainDFlux<SPACE_DIM>;
3576 fe_rhs->getOpPtrVector().push_back(
new OpC_dBroken(
3577 broken_data_ptr, hybrid_ptr, boost::make_shared<double>(1.0),
3578 get_normal_disp_bc_faces()));
3583 auto set_lhs = [&]() {
3586 auto [broken_data_ptr, piola_scale_ptr] =
3587 get_broken_op_side(fe_lhs->getOpPtrVector());
3590 hybridSpatialDisp, bcSpatialNormalDisplacementVecPtr, timeScaleMap));
3592 hybridSpatialDisp, broken_data_ptr, bcSpatialNormalDisplacementVecPtr,
3595 auto hybrid_grad_ptr = boost::make_shared<MatrixDouble>();
3597 fe_lhs->getOpPtrVector().push_back(
3599 hybridSpatialDisp, hybrid_grad_ptr));
3601 hybridSpatialDisp, bcSpatialPressureVecPtr, hybrid_grad_ptr,
3604 auto get_normal_disp_bc_faces = [&]() {
3607 return boost::make_shared<Range>(faces);
3612 using BdyEleOp = BoundaryEle::UserDataOperator;
3614 GAUSS>::OpBrokenSpaceConstrain<SPACE_DIM>;
3615 fe_lhs->getOpPtrVector().push_back(
new OpC(
3616 hybridSpatialDisp, broken_data_ptr, boost::make_shared<double>(1.0),
3617 true,
true, get_normal_disp_bc_faces()));
3630 const bool add_elastic,
const bool add_material,
3631 boost::shared_ptr<FaceElementForcesAndSourcesCore> &fe_rhs,
3632 boost::shared_ptr<FaceElementForcesAndSourcesCore> &fe_lhs) {
3639 boost::shared_ptr<ForcesAndSourcesCore> &fe_contact_tree
3652 CHKERR setContactElementRhsOps(contactTreeRhs);
3654 CHKERR setVolumeElementOps(tag,
true,
false, elasticFeRhs, elasticFeLhs);
3655 CHKERR setFaceElementOps(
true,
false, elasticBcRhs, elasticBcLhs);
3658 boost::make_shared<ForcesAndSourcesCore::UserDataOperator::AdjCache>();
3660 auto get_op_contact_bc = [&]() {
3663 mField, contactElement,
SPACE_DIM - 1, Sev::noisy, adj_cache);
3664 return op_loop_side;
3672 boost::shared_ptr<FEMethod> null;
3674 if (std::abs(alphaRho) > std::numeric_limits<double>::epsilon()) {
3706 bool set_ts_monitor) {
3708#ifdef ENABLE_PYTHON_BINDING
3712 auto setup_ts_monitor = [&]() {
3713 boost::shared_ptr<TsCtx>
ts_ctx;
3716 if (set_ts_monitor) {
3720 auto monitor_ptr = boost::make_shared<EshelbianMonitor>(*ep_ptr);
3724 MOFEM_LOG(
"EP", Sev::inform) <<
"TS monitor setup";
3725 return std::make_tuple(
ts_ctx);
3728 auto setup_snes_monitor = [&]() {
3731 CHKERR TSGetSNES(ts, &snes);
3733 CHKERR SNESMonitorSet(snes,
3736 (
void *)(snes_ctx.get()), PETSC_NULLPTR);
3737 MOFEM_LOG(
"EP", Sev::inform) <<
"SNES monitor setup";
3741 auto setup_snes_conergence_test = [&]() {
3744 auto snes_convergence_test = [](SNES snes, PetscInt it, PetscReal xnorm,
3745 PetscReal snorm, PetscReal fnorm,
3746 SNESConvergedReason *reason,
void *cctx) {
3749 CHKERR SNESConvergedDefault(snes, it, xnorm, snorm, fnorm, reason,
3753 CHKERR SNESGetSolutionUpdate(snes, &x_update);
3754 CHKERR SNESGetFunction(snes, &r, PETSC_NULLPTR, PETSC_NULLPTR);
3767 auto setup_section = [&]() {
3768 PetscSection section_raw;
3774 for (
int ff = 0; ff != num_fields; ff++) {
3777 PetscSectionGetFieldName(section_raw, ff, &
field_name),
3784 auto set_vector_on_mesh = [&]() {
3788 CHKERR VecGhostUpdateBegin(x, INSERT_VALUES, SCATTER_FORWARD);
3789 CHKERR VecGhostUpdateEnd(x, INSERT_VALUES, SCATTER_FORWARD);
3790 MOFEM_LOG(
"EP", Sev::inform) <<
"Vector set on mesh";
3794 auto setup_schur_block_solver = [&]() {
3795 MOFEM_LOG(
"EP", Sev::inform) <<
"Setting up Schur block solver";
3797 "append options prefix");
3801 boost::shared_ptr<EshelbianCore::SetUpSchur> schur_ptr;
3802 if constexpr (
A == AssemblyType::BLOCK_MAT) {
3807 MOFEM_LOG(
"EP", Sev::inform) <<
"Setting up Schur block solver done";
3814#ifdef ENABLE_PYTHON_BINDING
3815 return std::make_tuple(setup_sdf(), setup_ts_monitor(),
3816 setup_snes_monitor(), setup_snes_conergence_test(),
3817 setup_section(), set_vector_on_mesh(),
3818 setup_schur_block_solver());
3820 return std::make_tuple(setup_ts_monitor(), setup_snes_monitor(),
3821 setup_snes_conergence_test(), setup_section(),
3822 set_vector_on_mesh(), setup_schur_block_solver());
3830 PetscBool debug_model = PETSC_FALSE;
3834 <<
"Debug model flag is " << (debug_model ?
"ON" :
"OFF");
3836 if (debug_model == PETSC_TRUE) {
3838 auto post_proc = [&](TS ts, PetscReal
t, Vec u, Vec u_t, Vec u_tt, Vec
F,
3843 CHKERR TSGetSNES(ts, &snes);
3845 CHKERR SNESGetIterationNumber(snes, &it);
3846 std::string file_name =
"snes_iteration_" + std::to_string(it) +
".h5m";
3847 CHKERR postProcessResults(1, file_name,
F, u_t);
3848 std::string file_skel_name =
3849 "snes_iteration_skel_" + std::to_string(it) +
".h5m";
3851 auto get_material_force_tag = [&]() {
3852 auto &moab = mField.get_moab();
3859 CHKERR calculateFaceMaterialForce(1, ts);
3860 CHKERR postProcessSkeletonResults(1, file_skel_name,
F,
3861 {get_material_force_tag()});
3865 ts_ctx_ptr->tsDebugHook = post_proc;
3874 CHKERR addDebugModel(ts);
3878 if (std::abs(alphaRho) > std::numeric_limits<double>::epsilon()) {
3880 CHKERR VecDuplicate(x, &xx);
3881 CHKERR VecZeroEntries(xx);
3882 CHKERR TS2SetSolution(ts, x, xx);
3885 CHKERR TSSetSolution(ts, x);
3888 TetPolynomialBase::switchCacheBaseOn<HDIV>(
3889 {elasticFeLhs.get(), elasticFeRhs.get()});
3894 CHKERR TSSolve(ts, PETSC_NULLPTR);
3896 TetPolynomialBase::switchCacheBaseOff<HDIV>(
3897 {elasticFeLhs.get(), elasticFeRhs.get()});
3901 if (mField.get_comm_rank() == 0) {
3904 "solve_elastic_graph.dot");
3909 CHKERR TSGetSNES(ts, &snes);
3910 int lin_solver_iterations;
3911 CHKERR SNESGetLinearSolveIterations(snes, &lin_solver_iterations);
3913 <<
"Number of linear solver iterations " << lin_solver_iterations;
3915 PetscBool test_cook_flg = PETSC_FALSE;
3918 if (test_cook_flg) {
3919 constexpr int expected_lin_solver_iterations = 11;
3920 if (lin_solver_iterations > expected_lin_solver_iterations)
3923 "Expected number of iterations is different than expected %d > %d",
3924 lin_solver_iterations, expected_lin_solver_iterations);
3927 PetscBool test_sslv116_flag = PETSC_FALSE;
3929 &test_sslv116_flag, PETSC_NULLPTR);
3931 if (test_sslv116_flag) {
3932 double max_val = 0.0;
3933 double min_val = 0.0;
3934 auto field_min_max = [&](boost::shared_ptr<FieldEntity> ent_ptr) {
3936 auto ent_type = ent_ptr->getEntType();
3937 if (ent_type == MBVERTEX) {
3938 max_val = std::max(ent_ptr->getEntFieldData()[
SPACE_DIM - 1], max_val);
3939 min_val = std::min(ent_ptr->getEntFieldData()[
SPACE_DIM - 1], min_val);
3944 field_min_max, spatialH1Disp);
3946 double global_max_val = 0.0;
3947 double global_min_val = 0.0;
3948 MPI_Allreduce(&max_val, &global_max_val, 1, MPI_DOUBLE, MPI_MAX,
3950 MPI_Allreduce(&min_val, &global_min_val, 1, MPI_DOUBLE, MPI_MIN,
3953 <<
"Max " << spatialH1Disp <<
" value: " << global_max_val;
3955 <<
"Min " << spatialH1Disp <<
" value: " << global_min_val;
3957 double ref_max_val = 0.00767;
3958 double ref_min_val = -0.00329;
3959 if (std::abs(global_max_val - ref_max_val) > 1e-5) {
3961 "Incorrect max value of the displacement field: %f != %f",
3962 global_max_val, ref_max_val);
3964 if (std::abs(global_min_val - ref_min_val) > 4e-5) {
3966 "Incorrect min value of the displacement field: %f != %f",
3967 global_min_val, ref_min_val);
3978 double start_time) {
3983 double final_time = 1;
3984 double delta_time = 0.1;
3986 PetscBool ts_h1_update = PETSC_FALSE;
3988 PetscOptionsBegin(PETSC_COMM_WORLD,
"",
"Dynamic Relaxation Options",
"none");
3990 CHKERR PetscOptionsScalar(
"-dynamic_final_time",
3991 "dynamic relaxation final time",
"", final_time,
3992 &final_time, PETSC_NULLPTR);
3993 CHKERR PetscOptionsScalar(
"-dynamic_delta_time",
3994 "dynamic relaxation final time",
"", delta_time,
3995 &delta_time, PETSC_NULLPTR);
3996 CHKERR PetscOptionsInt(
"-dynamic_max_it",
"dynamic relaxation iterations",
"",
3997 max_it, &max_it, PETSC_NULLPTR);
3998 CHKERR PetscOptionsBool(
"-dynamic_h1_update",
"update each ts step",
"",
3999 ts_h1_update, &ts_h1_update, PETSC_NULLPTR);
4004 <<
"Dynamic relaxation final time -dynamic_final_time = " << final_time;
4006 <<
"Dynamic relaxation delta time -dynamic_delta_time = " << delta_time;
4008 <<
"Dynamic relaxation max iterations -dynamic_max_it = " << max_it;
4010 <<
"Dynamic relaxation H1 update each step -dynamic_h1_update = "
4011 << (ts_h1_update ?
"TRUE" :
"FALSE");
4013 CHKERR addDebugModel(ts);
4015 auto setup_ts_monitor = [&]() {
4016 auto monitor_ptr = boost::make_shared<EshelbianMonitor>(*
this);
4019 auto monitor_ptr = setup_ts_monitor();
4021 TetPolynomialBase::switchCacheBaseOn<HDIV>(
4022 {elasticFeLhs.get(), elasticFeRhs.get()});
4026 double ts_delta_time;
4027 CHKERR TSGetTimeStep(ts, &ts_delta_time);
4037 dynamicTime = start_time;
4038 dynamicStep = start_step;
4039 monitor_ptr->ts = PETSC_NULLPTR;
4040 monitor_ptr->ts_u = PETSC_NULLPTR;
4041 monitor_ptr->ts_t = dynamicTime;
4042 monitor_ptr->ts_step = dynamicStep;
4045 for (; dynamicTime < final_time; dynamicTime += delta_time) {
4046 MOFEM_LOG(
"EP", Sev::inform) <<
"Load step " << dynamicStep <<
" Time "
4047 << dynamicTime <<
" delta time " << delta_time;
4049 CHKERR TSSetStepNumber(ts, 0);
4051 CHKERR TSSetTimeStep(ts, ts_delta_time);
4052 if (!ts_h1_update) {
4055 CHKERR TSSetSolution(ts, x);
4056 CHKERR TSSolve(ts, PETSC_NULLPTR);
4057 if (!ts_h1_update) {
4063 CHKERR VecGhostUpdateBegin(x, INSERT_VALUES, SCATTER_FORWARD);
4064 CHKERR VecGhostUpdateEnd(x, INSERT_VALUES, SCATTER_FORWARD);
4066 monitor_ptr->ts = PETSC_NULLPTR;
4067 monitor_ptr->ts_u = x;
4068 monitor_ptr->ts_t = dynamicTime;
4069 monitor_ptr->ts_step = dynamicStep;
4073 if (dynamicStep > max_it)
4078 TetPolynomialBase::switchCacheBaseOff<HDIV>(
4079 {elasticFeLhs.get(), elasticFeRhs.get()});
4087 auto set_block = [&](
auto name,
int dim) {
4088 std::map<int, Range> map;
4089 auto set_tag_impl = [&](
auto name) {
4094 std::regex((boost::format(
"%s(.*)") % name).str())
4097 for (
auto bc : bcs) {
4099 CHKERR bc->getMeshsetIdEntitiesByDimension(mField.get_moab(), dim, r,
4101 map[bc->getMeshsetId()] = r;
4103 <<
"Block " << name <<
" id " << bc->getMeshsetId() <<
" has "
4104 << r.size() <<
" entities";
4109 CHKERR set_tag_impl(name);
4111 return std::make_pair(name, map);
4114 auto set_skin = [&](
auto &&map) {
4115 for (
auto &
m : map.second) {
4119 <<
"Skin for block " << map.first <<
" id " <<
m.first <<
" has "
4120 <<
m.second.size() <<
" entities";
4125 auto set_tag = [&](
auto &&map) {
4127 auto name = map.first;
4128 int def_val[] = {-1};
4130 mField.get_moab().tag_get_handle(name, 1, MB_TYPE_INTEGER,
th,
4131 MB_TAG_SPARSE | MB_TAG_CREAT, def_val),
4133 for (
auto &
m : map.second) {
4141 listTagsToTransfer.push_back(set_tag(set_skin(set_block(
"BODY", 3))));
4142 listTagsToTransfer.push_back(set_tag(set_skin(set_block(
"MAT_ELASTIC", 3))));
4143 listTagsToTransfer.push_back(
4144 set_tag(set_skin(set_block(
"MAT_NEOHOOKEAN", 3))));
4145 listTagsToTransfer.push_back(set_tag(set_block(
"CONTACT", 2)));
4152 Vec f_residual, Vec var_vector,
4153 std::vector<Tag> tags_to_transfer, TS ts) {
4158 auto get_tag = [&](
auto name,
auto dim) {
4159 auto &mob = mField.get_moab();
4161 double def_val[] = {0., 0., 0.};
4162 CHK_MOAB_THROW(mob.tag_get_handle(name, dim, MB_TYPE_DOUBLE, tag,
4163 MB_TAG_CREAT | MB_TAG_SPARSE, def_val),
4167 tags_to_transfer.push_back(
get_tag(
"MaterialForce", 3));
4171 auto get_crack_tag = [&]() {
4173 rval = mField.get_moab().tag_get_handle(
"CRACK",
th);
4174 if (
rval == MB_SUCCESS) {
4177 int def_val[] = {0};
4179 "CRACK", 1, MB_TYPE_INTEGER,
th, MB_TAG_SPARSE | MB_TAG_CREAT,
4184 Tag th = get_crack_tag();
4185 tags_to_transfer.push_back(
th);
4189 mark_faces.merge(*crackFaces);
4191 mark_faces.merge(*interfaceFaces);
4192 CHKERR mField.get_moab().tag_clear_data(
th, mark_faces, mark);
4196 for (
auto t : listTagsToTransfer) {
4198 CHKERR mField.get_moab().tag_get_name(
t, name);
4199 MOFEM_LOG(
"EP", Sev::verbose) <<
"Adding tag " << name
4200 <<
" to transfer list for post-processing";
4201 tags_to_transfer.push_back(
t);
4211 auto get_post_proc = [&](
auto &post_proc_mesh,
auto sense) {
4213 auto post_proc_ptr =
4214 boost::make_shared<PostProcBrokenMeshInMoabBaseCont<FaceEle>>(
4215 mField, post_proc_mesh);
4216 EshelbianPlasticity::AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
4217 post_proc_ptr->getOpPtrVector(), {L2}, materialH1Positions,
4220 if (ts != PETSC_NULLPTR) {
4222 CHKERR TSGetTime(ts, &(post_proc_ptr->ts_t));
4225 auto domain_ops = [&](
auto &fe,
int sense) {
4228 auto bubble_cache = boost::make_shared<CGGUserPolynomialBase::CachePhi>(
4230 fe.getUserPolynomialBase() = boost::shared_ptr<BaseFunction>(
4232 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
4233 fe.getOpPtrVector(), {HDIV, H1, L2}, materialH1Positions,
4235 auto piola_scale_ptr = boost::make_shared<double>(1.0);
4236 fe.getOpPtrVector().push_back(physicalEquations->returnOpSetScale(
4237 piola_scale_ptr, physicalEquations));
4239 piolaStress, dataAtPts->getApproxPAtPts(), piola_scale_ptr));
4241 bubbleField, dataAtPts->getApproxPAtPts(), piola_scale_ptr,
4244 fe.getOpPtrVector().push_back(
4245 physicalEquations->returnOpCalculateStretchFromStress(
4246 dataAtPts, physicalEquations));
4248 fe.getOpPtrVector().push_back(
4250 stretchTensor, dataAtPts->getLogStretchTensorAtPts(), MBTET));
4255 piolaStress, dataAtPts->getVarPiolaPts(),
4256 boost::make_shared<double>(1), vec));
4258 bubbleField, dataAtPts->getVarPiolaPts(),
4259 boost::make_shared<double>(1), vec, MBMAXTYPE));
4261 rotAxis, dataAtPts->getVarRotAxisPts(), vec, MBTET));
4263 fe.getOpPtrVector().push_back(
4264 physicalEquations->returnOpCalculateVarStretchFromStress(
4265 dataAtPts, physicalEquations));
4267 fe.getOpPtrVector().push_back(
4269 stretchTensor, dataAtPts->getVarLogStreachPts(), vec, MBTET));
4274 rotAxis, dataAtPts->getRotAxisAtPts(), MBTET));
4276 rotAxis, dataAtPts->getRotAxis0AtPts(), solTSStep, MBTET));
4279 spatialL2Disp, dataAtPts->getSmallWL2AtPts(), MBTET));
4281 spatialH1Disp, dataAtPts->getSmallWH1AtPts()));
4283 spatialH1Disp, dataAtPts->getSmallWGradH1AtPts()));
4285 fe.getOpPtrVector().push_back(
4289 fe.getOpPtrVector().push_back(physicalEquations->returnOpJacobian(
4290 tag,
true,
false, dataAtPts, physicalEquations));
4292 physicalEquations->returnOpCalculateEnergy(dataAtPts,
nullptr)) {
4293 fe.getOpPtrVector().push_back(op);
4302 struct OpSidePPMap :
public OpPPMap {
4303 OpSidePPMap(moab::Interface &post_proc_mesh,
4304 std::vector<EntityHandle> &map_gauss_pts,
4305 DataMapVec data_map_scalar, DataMapMat data_map_vec,
4306 DataMapMat data_map_mat, DataMapMat data_symm_map_mat,
4308 :
OpPPMap(post_proc_mesh, map_gauss_pts, data_map_scalar,
4309 data_map_vec, data_map_mat, data_symm_map_mat),
4316 if (tagSense != 0) {
4317 if (tagSense != OpPPMap::getSkeletonSense())
4330 vec_fields[
"SpatialDisplacementL2"] = dataAtPts->getSmallWL2AtPts();
4331 vec_fields[
"SpatialDisplacementH1"] = dataAtPts->getSmallWH1AtPts();
4332 vec_fields[
"Omega"] = dataAtPts->getRotAxisAtPts();
4333 vec_fields[
"AngularMomentum"] = dataAtPts->getLeviKirchhoffAtPts();
4334 vec_fields[
"X"] = dataAtPts->getLargeXH1AtPts();
4336 vec_fields[
"EiegnLogStreach"] = dataAtPts->getEigenValsAtPts();
4340 vec_fields[
"VarOmega"] = dataAtPts->getVarRotAxisPts();
4341 vec_fields[
"VarSpatialDisplacementL2"] =
4342 boost::make_shared<MatrixDouble>();
4344 spatialL2Disp, vec_fields[
"VarSpatialDisplacementL2"], vec, MBTET));
4348 vec_fields[
"ResSpatialDisplacementL2"] =
4349 boost::make_shared<MatrixDouble>();
4351 spatialL2Disp, vec_fields[
"ResSpatialDisplacementL2"], vec, MBTET));
4352 vec_fields[
"ResOmega"] = boost::make_shared<MatrixDouble>();
4354 rotAxis, vec_fields[
"ResOmega"], vec, MBTET));
4358 mat_fields[
"PiolaStress"] = dataAtPts->getApproxPAtPts();
4360 mat_fields[
"VarPiolaStress"] = dataAtPts->getVarPiolaPts();
4364 mat_fields[
"ResPiolaStress"] = boost::make_shared<MatrixDouble>();
4366 piolaStress, mat_fields[
"ResPiolaStress"],
4367 boost::make_shared<double>(1), vec));
4369 bubbleField, mat_fields[
"ResPiolaStress"],
4370 boost::make_shared<double>(1), vec, MBMAXTYPE));
4372 if (!internalStressTagName.empty()) {
4373 mat_fields[internalStressTagName] = dataAtPts->getInternalStressAtPts();
4374 switch (internalStressInterpOrder) {
4376 fe.getOpPtrVector().push_back(
4380 fe.getOpPtrVector().push_back(
4385 "Unsupported internal stress interpolation order %d",
4386 internalStressInterpOrder);
4391 mat_fields_symm[
"LogSpatialStretch"] =
4392 dataAtPts->getLogStretchTensorAtPts();
4393 mat_fields_symm[
"SpatialStretch"] = dataAtPts->getStretchTensorAtPts();
4395 mat_fields_symm[
"VarLogSpatialStretch"] =
4396 dataAtPts->getVarLogStreachPts();
4401 mat_fields_symm[
"ResLogSpatialStretch"] =
4402 boost::make_shared<MatrixDouble>();
4403 fe.getOpPtrVector().push_back(
4405 stretchTensor, mat_fields_symm[
"ResLogSpatialStretch"], vec,
4410 fe.getOpPtrVector().push_back(
4414 post_proc_ptr->getPostProcMesh(), post_proc_ptr->getMapGaussPts(),
4431 post_proc_ptr->getPostProcMesh(), post_proc_ptr->getMapGaussPts(),
4437 auto X_h1_ptr = boost::make_shared<MatrixDouble>();
4439 post_proc_ptr->getOpPtrVector().push_back(
4441 dataAtPts->getLargeXH1AtPts()));
4446 domain_ops(*(op_loop_side->getSideFEPtr()), sense);
4447 post_proc_ptr->getOpPtrVector().push_back(op_loop_side);
4449 return post_proc_ptr;
4453 auto calcs_side_traction_and_displacements = [&](
auto &post_proc_ptr,
4459 using SideEleOp = EleOnSide::UserDataOperator;
4461 mField, elementVolumeName,
SPACE_DIM, Sev::noisy);
4462 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
4463 boost::shared_ptr<BaseFunction>(
4465 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
4466 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
4467 materialH1Positions, frontAdjEdges);
4468 auto traction_ptr = boost::make_shared<MatrixDouble>();
4469 op_loop_domain_side->getOpPtrVector().push_back(
4471 piolaStress, traction_ptr, boost::make_shared<double>(1.0)));
4474 contactDisp, dataAtPts->getContactL2AtPts()));
4475 pip.push_back(op_loop_domain_side);
4477 auto u_h1_ptr = boost::make_shared<MatrixDouble>();
4480 *
this, contactTreeRhs, u_h1_ptr, traction_ptr,
4482 &post_proc_ptr->getPostProcMesh(), &post_proc_ptr->getMapGaussPts()));
4488 pip.push_back(op_this);
4490 op_this->getOpPtrVector().push_back(
4494 post_proc_ptr->getPostProcMesh(), post_proc_ptr->getMapGaussPts(),
4498 {{
"ContactDisplacement", dataAtPts->getContactL2AtPts()}},
4511 auto contact_residual = boost::make_shared<MatrixDouble>();
4512 op_this->getOpPtrVector().push_back(
4514 contactDisp, contact_residual,
4516 op_this->getOpPtrVector().push_back(
4520 post_proc_ptr->getPostProcMesh(), post_proc_ptr->getMapGaussPts(),
4524 {{
"res_contact", contact_residual}},
4538 auto post_proc_mesh = boost::make_shared<moab::Core>();
4539 auto post_proc_ptr = get_post_proc(post_proc_mesh, 1);
4540 auto post_proc_negative_sense_ptr =
4541 get_post_proc(post_proc_mesh, -1);
4542 auto skin_post_proc_ptr = get_post_proc(post_proc_mesh, 1);
4543 CHKERR calcs_side_traction_and_displacements(
4544 skin_post_proc_ptr, skin_post_proc_ptr->getOpPtrVector());
4550 CHKERR mField.get_moab().get_adjacencies(own_tets,
SPACE_DIM - 1,
true,
4551 own_faces, moab::Interface::UNION);
4553 auto get_crack_faces = [&](
auto crack_faces) {
4554 auto get_adj = [&](
auto e,
auto dim) {
4556 CHKERR mField.get_moab().get_adjacencies(e, dim,
true, adj,
4557 moab::Interface::UNION);
4561 auto tets = get_adj(crack_faces, 3);
4563 auto faces = subtract(get_adj(tets, 2), crack_faces);
4565 tets = subtract(tets, get_adj(faces, 3));
4566 return subtract(crack_faces, get_adj(tets, 2));
4569 auto side_one_faces = [&](
auto &faces) {
4570 std::pair<Range, Range> sides;
4571 for (
auto f : faces) {
4573 MOAB_THROW(mField.get_moab().get_adjacencies(&f, 1, 3,
false, adj));
4574 adj = intersect(own_tets, adj);
4575 for (
auto t : adj) {
4576 int side, sense, offset;
4577 MOAB_THROW(mField.get_moab().side_number(
t, f, side, sense, offset));
4579 sides.first.insert(f);
4581 sides.second.insert(f);
4588 auto get_interface_from_block = [&](
auto block_name) {
4592 CHKERR mField.get_moab().get_adjacencies(vol_eles,
SPACE_DIM - 1,
true,
4593 faces, moab::Interface::UNION);
4594 faces = subtract(faces, skin);
4598 auto crack_faces = unite(get_crack_faces(*crackFaces), *interfaceFaces);
4600 auto crack_side_faces = side_one_faces(crack_faces);
4601 auto side_one_crack_faces = [crack_side_faces](
FEMethod *fe_method_ptr) {
4602 auto ent = fe_method_ptr->getFEEntityHandle();
4603 if (crack_side_faces.first.find(ent) == crack_side_faces.first.end()) {
4608 auto side_minus_crack_faces = [crack_side_faces](
FEMethod *fe_method_ptr) {
4609 auto ent = fe_method_ptr->getFEEntityHandle();
4610 if (crack_side_faces.second.find(ent) == crack_side_faces.second.end()) {
4616 skin_post_proc_ptr->setTagsToTransfer(tags_to_transfer);
4617 post_proc_ptr->setTagsToTransfer(tags_to_transfer);
4618 post_proc_negative_sense_ptr->setTagsToTransfer(tags_to_transfer);
4620 auto post_proc_begin =
4624 post_proc_ptr->exeTestHook = side_one_crack_faces;
4626 dM, skeletonElement, post_proc_ptr, 0, mField.get_comm_size());
4627 post_proc_negative_sense_ptr->exeTestHook = side_minus_crack_faces;
4629 post_proc_negative_sense_ptr, 0,
4630 mField.get_comm_size());
4632 constexpr bool debug =
false;
4635 auto get_adj_front = [&]() {
4636 auto skeleton_faces = *skeletonFaces;
4638 CHKERR mField.get_moab().get_adjacencies(*frontEdges, 2,
true, adj_front,
4639 moab::Interface::UNION);
4641 adj_front = intersect(adj_front, skeleton_faces);
4642 adj_front = subtract(adj_front, *crackFaces);
4643 adj_front = intersect(own_faces, adj_front);
4648 auto only_front_faces = [adj_front](
FEMethod *fe_method_ptr) {
4649 auto ent = fe_method_ptr->getFEEntityHandle();
4650 if (adj_front.find(ent) == adj_front.end()) {
4656 post_proc_ptr->exeTestHook = only_front_faces;
4658 dM, skeletonElement, post_proc_ptr, 0, mField.get_comm_size());
4659 post_proc_negative_sense_ptr->exeTestHook = only_front_faces;
4661 post_proc_negative_sense_ptr, 0,
4662 mField.get_comm_size());
4667 CHKERR post_proc_end.writeFile(file.c_str());
4674 std::vector<Tag> tags_to_transfer) {
4679 auto post_proc_mesh = boost::make_shared<moab::Core>();
4680 auto post_proc_ptr =
4681 boost::make_shared<PostProcBrokenMeshInMoabBaseCont<FaceEle>>(
4683 EshelbianPlasticity::AddHOOps<SPACE_DIM - 1, SPACE_DIM - 1, SPACE_DIM>::add(
4687 auto hybrid_disp = boost::make_shared<MatrixDouble>();
4688 post_proc_ptr->getOpPtrVector().push_back(
4690 post_proc_ptr->getOpPtrVector().push_back(
4694 auto op_loop_domain_side =
4697 post_proc_ptr->getOpPtrVector().push_back(op_loop_domain_side);
4700 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
4701 boost::make_shared<CGGUserPolynomialBase>(
nullptr,
true);
4702 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
4703 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
4705 op_loop_domain_side->getOpPtrVector().push_back(
4708 op_loop_domain_side->getOpPtrVector().push_back(
4711 op_loop_domain_side->getOpPtrVector().push_back(
4716 op_loop_domain_side->getOpPtrVector().push_back(
4720 op_loop_domain_side->getOpPtrVector().push_back(
4728 vec_fields[
"HybridDisplacement"] = hybrid_disp;
4730 vec_fields[
"spatialL2Disp"] =
dataAtPts->getSmallWL2AtPts();
4731 vec_fields[
"Omega"] =
dataAtPts->getRotAxisAtPts();
4733 mat_fields[
"PiolaStress"] =
dataAtPts->getApproxPAtPts();
4734 mat_fields[
"HybridDisplacementGradient"] =
4737 mat_fields_symm[
"LogSpatialStretch"] =
dataAtPts->getLogStretchTensorAtPts();
4739 post_proc_ptr->getOpPtrVector().push_back(
4743 post_proc_ptr->getPostProcMesh(), post_proc_ptr->getMapGaussPts(),
4758 auto hybrid_res = boost::make_shared<MatrixDouble>();
4759 post_proc_ptr->getOpPtrVector().push_back(
4764 post_proc_ptr->getOpPtrVector().push_back(
4768 post_proc_ptr->getPostProcMesh(), post_proc_ptr->getMapGaussPts(),
4772 {{
"res_hybrid", hybrid_res}},
4783 post_proc_ptr->setTagsToTransfer(tags_to_transfer);
4785 auto post_proc_begin =
4792 CHKERR post_proc_end.writeFile(file.c_str());
4801 auto post_proc_norm_fe =
4802 boost::make_shared<VolumeElementForcesAndSourcesCore>(
mField);
4805 boost::make_shared<CGGUserPolynomialBase::CachePhi>(0, 0,
MatrixDouble());
4806 post_proc_norm_fe->getUserPolynomialBase() =
4808 post_proc_norm_fe->getRuleHook = [](int, int, int) {
return -1; };
4809 auto vol_rule_lin = [](
int o) {
return 2 * o + 1; };
4810 auto vol_rule_no_lin = [](
int o) {
return 2 * o + (o - 1) + 1; };
4811 auto vol_rule = (SMALL_ROT > 0) ? vol_rule_lin : vol_rule_no_lin;
4812 post_proc_norm_fe->setRuleHook = SetIntegrationAtFrontVolume(
4814 CHKERR EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
4818 enum NORMS { U_NORM_L2 = 0, U_NORM_H1, PIOLA_NORM, U_ERROR_L2, LAST_NORM };
4821 CHKERR VecZeroEntries(norms_vec);
4823 auto u_l2_ptr = boost::make_shared<MatrixDouble>();
4824 auto u_h1_ptr = boost::make_shared<MatrixDouble>();
4825 post_proc_norm_fe->getOpPtrVector().push_back(
4827 post_proc_norm_fe->getOpPtrVector().push_back(
4829 post_proc_norm_fe->getOpPtrVector().push_back(
4831 post_proc_norm_fe->getOpPtrVector().push_back(
4833 post_proc_norm_fe->getOpPtrVector().push_back(
4837 auto piola_ptr = boost::make_shared<MatrixDouble>();
4838 post_proc_norm_fe->getOpPtrVector().push_back(
4840 post_proc_norm_fe->getOpPtrVector().push_back(
4844 post_proc_norm_fe->getOpPtrVector().push_back(
4847 TetPolynomialBase::switchCacheBaseOn<HDIV>({post_proc_norm_fe.get()});
4849 *post_proc_norm_fe);
4850 TetPolynomialBase::switchCacheBaseOff<HDIV>({post_proc_norm_fe.get()});
4852 CHKERR VecAssemblyBegin(norms_vec);
4853 CHKERR VecAssemblyEnd(norms_vec);
4854 const double *norms;
4855 CHKERR VecGetArrayRead(norms_vec, &norms);
4856 MOFEM_LOG(
"EP", Sev::inform) <<
"norm_u: " << std::sqrt(norms[U_NORM_L2]);
4857 MOFEM_LOG(
"EP", Sev::inform) <<
"norm_u_h1: " << std::sqrt(norms[U_NORM_H1]);
4859 <<
"norm_error_u_l2: " << std::sqrt(norms[U_ERROR_L2]);
4861 <<
"norm_piola: " << std::sqrt(norms[PIOLA_NORM]);
4862 CHKERR VecRestoreArrayRead(norms_vec, &norms);
4876 for (
auto bc : bc_mng->getBcMapByBlockName()) {
4877 if (
auto disp_bc = bc.second->dispBcPtr) {
4882 <<
"Field name: " <<
field_name <<
" Block name: " << block_name;
4883 MOFEM_LOG(
"EP", Sev::noisy) <<
"Displacement BC: " << *disp_bc;
4885 std::vector<double> block_attributes(6, 0.);
4886 if (disp_bc->data.flag1 == 1) {
4887 block_attributes[0] = disp_bc->data.value1;
4888 block_attributes[3] = 1;
4890 if (disp_bc->data.flag2 == 1) {
4891 block_attributes[1] = disp_bc->data.value2;
4892 block_attributes[4] = 1;
4894 if (disp_bc->data.flag3 == 1) {
4895 block_attributes[2] = disp_bc->data.value3;
4896 block_attributes[5] = 1;
4898 auto faces = bc.second->bcEnts.subset_by_dimension(2);
4906 boost::make_shared<NormalDisplacementBcVec>();
4907 for (
auto bc : bc_mng->getBcMapByBlockName()) {
4908 auto block_name =
"(.*)NORMAL_DISPLACEMENT(.*)";
4909 std::regex reg_name(block_name);
4910 if (std::regex_match(bc.first, reg_name)) {
4914 <<
"Field name: " <<
field_name <<
" Block name: " << block_name;
4916 block_name, bc.second->bcAttributes,
4917 bc.second->bcEnts.subset_by_dimension(2));
4922 boost::make_shared<AnalyticalDisplacementBcVec>();
4924 for (
auto bc : bc_mng->getBcMapByBlockName()) {
4925 auto block_name =
"(.*)ANALYTICAL_DISPLACEMENT(.*)";
4926 std::regex reg_name(block_name);
4927 if (std::regex_match(bc.first, reg_name)) {
4931 <<
"Field name: " <<
field_name <<
" Block name: " << block_name;
4933 block_name, bc.second->bcAttributes,
4934 bc.second->bcEnts.subset_by_dimension(2));
4938 auto ts_displacement =
4939 boost::make_shared<DynamicRelaxationTimeScale>(
"disp_history.txt");
4942 <<
"Add time scaling displacement BC: " << bc.blockName;
4945 ts_displacement,
"disp_history",
".txt", bc.blockName);
4948 auto ts_normal_displacement =
4949 boost::make_shared<DynamicRelaxationTimeScale>(
"normal_disp_history.txt");
4952 <<
"Add time scaling normal displacement BC: " << bc.blockName;
4955 ts_normal_displacement,
"normal_disp_history",
".txt",
4971 for (
auto bc : bc_mng->getBcMapByBlockName()) {
4972 if (
auto force_bc = bc.second->forceBcPtr) {
4977 <<
"Field name: " <<
field_name <<
" Block name: " << block_name;
4978 MOFEM_LOG(
"EP", Sev::noisy) <<
"Force BC: " << *force_bc;
4980 std::vector<double> block_attributes(6, 0.);
4981 block_attributes[0] = -force_bc->data.value3 * force_bc->data.value1;
4982 block_attributes[3] = 1;
4983 block_attributes[1] = -force_bc->data.value4 * force_bc->data.value1;
4984 block_attributes[4] = 1;
4985 block_attributes[2] = -force_bc->data.value5 * force_bc->data.value1;
4986 block_attributes[5] = 1;
4987 auto faces = bc.second->bcEnts.subset_by_dimension(2);
4995 for (
auto bc : bc_mng->getBcMapByBlockName()) {
4996 auto block_name =
"(.*)PRESSURE(.*)";
4997 std::regex reg_name(block_name);
4998 if (std::regex_match(bc.first, reg_name)) {
5003 <<
"Field name: " <<
field_name <<
" Block name: " << block_name;
5005 block_name, bc.second->bcAttributes,
5006 bc.second->bcEnts.subset_by_dimension(2));
5011 boost::make_shared<AnalyticalTractionBcVec>();
5013 for (
auto bc : bc_mng->getBcMapByBlockName()) {
5014 auto block_name =
"(.*)ANALYTICAL_TRACTION(.*)";
5015 std::regex reg_name(block_name);
5016 if (std::regex_match(bc.first, reg_name)) {
5020 <<
"Field name: " <<
field_name <<
" Block name: " << block_name;
5022 block_name, bc.second->bcAttributes,
5023 bc.second->bcEnts.subset_by_dimension(2));
5028 boost::make_shared<DynamicRelaxationTimeScale>(
"traction_history.txt");
5032 ts_traction,
"traction_history",
".txt", bc.blockName);
5036 boost::make_shared<DynamicRelaxationTimeScale>(
"pressure_history.txt");
5040 ts_pressure,
"pressure_history",
".txt", bc.blockName);
5050 &ext_strain_vec_ptr,
5051 const std::string block_name,
5052 const int nb_attributes) {
5055 std::regex((boost::format(
"(.*)%s(.*)") % block_name).str()))) {
5056 std::vector<double> block_attributes;
5057 CHKERR it->getAttributes(block_attributes);
5058 if (block_attributes.size() < nb_attributes) {
5060 "In block %s expected %d attributes, but given %ld",
5061 it->getName().c_str(), nb_attributes, block_attributes.size());
5064 auto get_block_ents = [&]() {
5070 auto Ents = get_block_ents();
5071 ext_strain_vec_ptr->emplace_back(it->getName(), block_attributes,
5081 auto ts_pre_stretch = boost::make_shared<DynamicRelaxationTimeScale>(
5082 "externalstrain_history.txt");
5085 <<
"Add time scaling external strain: " << ext_strain_block.blockName;
5088 ts_pre_stretch,
"externalstrain_history",
".txt",
5089 ext_strain_block.blockName);
5098 auto print_loc_size = [
this](
auto v,
auto str,
auto sev) {
5101 CHKERR VecGetLocalSize(
v.second, &size);
5103 CHKERR VecGetOwnershipRange(
v.second, &low, &high);
5104 MOFEM_LOG(
"EPSYNC", sev) << str <<
" local size " << size <<
" ( " << low
5105 <<
" " << high <<
" ) ";
5128 double start_time) {
5131 auto storage = solve_elastic_setup::setup(
this, ts, x,
false);
5133 auto cohesive_tao_ctx = createCohesiveTAOCtx(
5136 [](
int p) {
return 2 * (p + 1) + 1; }),
5139 double final_time = 1;
5140 double delta_time = 0.1;
5142 PetscBool ts_h1_update = PETSC_FALSE;
5144 PetscOptionsBegin(PETSC_COMM_WORLD,
"",
"Dynamic Relaxation Options",
"none");
5146 CHKERR PetscOptionsScalar(
"-dynamic_final_time",
5147 "dynamic relaxation final time",
"", final_time,
5148 &final_time, PETSC_NULLPTR);
5149 CHKERR PetscOptionsScalar(
"-dynamic_delta_time",
5150 "dynamic relaxation final time",
"", delta_time,
5151 &delta_time, PETSC_NULLPTR);
5152 CHKERR PetscOptionsInt(
"-dynamic_max_it",
"dynamic relaxation iterations",
"",
5153 max_it, &max_it, PETSC_NULLPTR);
5154 CHKERR PetscOptionsBool(
"-dynamic_h1_update",
"update each ts step",
"",
5155 ts_h1_update, &ts_h1_update, PETSC_NULLPTR);
5161 <<
"Dynamic relaxation final time -dynamic_final_time = " << final_time;
5163 <<
"Dynamic relaxation delta time -dynamic_delta_time = " << delta_time;
5165 <<
"Dynamic relaxation max iterations -dynamic_max_it = " << max_it;
5167 <<
"Dynamic relaxation H1 update each step -dynamic_h1_update = "
5168 << (ts_h1_update ?
"TRUE" :
"FALSE");
5170 CHKERR initializeCohesiveKappaField(*
this);
5173 auto setup_ts_monitor = [&]() {
5174 auto monitor_ptr = boost::make_shared<EshelbianMonitor>(*
this);
5177 auto monitor_ptr = setup_ts_monitor();
5179 TetPolynomialBase::switchCacheBaseOn<HDIV>(
5182 CHKERR TSElasticPostStep::postStepInitialise(
this);
5184 double ts_delta_time;
5185 CHKERR TSGetTimeStep(ts, &ts_delta_time);
5188 CHKERR TSSetPreStep(ts, TSElasticPostStep::preStepFun);
5189 CHKERR TSSetPostStep(ts, TSElasticPostStep::postStepFun);
5193 CHKERR TaoSetType(tao, TAOLMVM);
5194 auto g = cohesive_tao_ctx->duplicateGradientVec();
5196 cohesiveEvaluateObjectiveAndGradient,
5197 (
void *)cohesive_tao_ctx.get());
5201 monitor_ptr->ts = PETSC_NULLPTR;
5202 monitor_ptr->ts_u = PETSC_NULLPTR;
5207 auto tao_sol0 = cohesive_tao_ctx->duplicateKappaVec();
5208 int tao_sol_size, tao_sol_loc_size;
5209 CHKERR VecGetSize(tao_sol0, &tao_sol_size);
5210 CHKERR VecGetLocalSize(tao_sol0, &tao_sol_loc_size);
5212 <<
"Cohesive crack growth initial kappa vector size " << tao_sol_size
5213 <<
" local size " << tao_sol_loc_size <<
" number of interface faces "
5216 CHKERR TaoSetFromOptions(tao);
5221 CHKERR VecSet(xu, PETSC_INFINITY);
5222 CHKERR TaoSetVariableBounds(tao, xl, xu);
5228 CHKERR VecZeroEntries(tao_sol0);
5229 CHKERR VecGhostUpdateBegin(tao_sol0, INSERT_VALUES, SCATTER_FORWARD);
5230 CHKERR VecGhostUpdateEnd(tao_sol0, INSERT_VALUES, SCATTER_FORWARD);
5231 CHKERR TaoSetSolution(tao, tao_sol0);
5234 CHKERR TaoGetSolution(tao, &tao_sol);
5237 auto &kappa_vec = cohesive_tao_ctx->getKappaVec();
5240 CHKERR VecAXPY(kappa_vec.second, 1.0, tao_sol);
5241 CHKERR VecGhostUpdateBegin(kappa_vec.second, INSERT_VALUES,
5243 CHKERR VecGhostUpdateEnd(kappa_vec.second, INSERT_VALUES, SCATTER_FORWARD);
5250 CHKERR VecGhostUpdateBegin(x, INSERT_VALUES, SCATTER_FORWARD);
5251 CHKERR VecGhostUpdateEnd(x, INSERT_VALUES, SCATTER_FORWARD);
5252 monitor_ptr->ts = PETSC_NULLPTR;
5253 monitor_ptr->ts_u = x;
5263 CHKERR TSElasticPostStep::postStepDestroy();
5264 TetPolynomialBase::switchCacheBaseOff<HDIV>(
5272 double start_time) {
5275 constexpr bool debug =
true;
5278 auto storage = solve_elastic_setup::setup(
this, ts, x,
false);
5280 auto topological_tao_ctx = createTopologicalTAOCtx(
5283 [](
int p) {
return 2 * (p + 1) + 1; }),
5285 [](
int p) {
return 2 * (p + 1) + 1; }),
5288 double final_time = 1;
5289 double delta_time = 0.1;
5291 PetscBool ts_h1_update = PETSC_FALSE;
5293 PetscOptionsBegin(PETSC_COMM_WORLD,
"",
"Dynamic Relaxation Options",
"none");
5295 CHKERR PetscOptionsScalar(
"-dynamic_final_time",
5296 "dynamic relaxation final time",
"", final_time,
5297 &final_time, PETSC_NULLPTR);
5298 CHKERR PetscOptionsScalar(
"-dynamic_delta_time",
5299 "dynamic relaxation final time",
"", delta_time,
5300 &delta_time, PETSC_NULLPTR);
5301 CHKERR PetscOptionsInt(
"-dynamic_max_it",
"dynamic relaxation iterations",
"",
5302 max_it, &max_it, PETSC_NULLPTR);
5303 CHKERR PetscOptionsBool(
"-dynamic_h1_update",
"update each ts step",
"",
5304 ts_h1_update, &ts_h1_update, PETSC_NULLPTR);
5310 <<
"Dynamic relaxation final time -dynamic_final_time = " << final_time;
5312 <<
"Dynamic relaxation delta time -dynamic_delta_time = " << delta_time;
5314 <<
"Dynamic relaxation max iterations -dynamic_max_it = " << max_it;
5316 <<
"Dynamic relaxation H1 update each step -dynamic_h1_update = "
5317 << (ts_h1_update ?
"TRUE" :
"FALSE");
5321 auto setup_ts_monitor = [&]() {
5322 auto monitor_ptr = boost::make_shared<EshelbianMonitor>(*
this);
5325 auto monitor_ptr = setup_ts_monitor();
5327 TetPolynomialBase::switchCacheBaseOn<HDIV>(
5330 CHKERR TSElasticPostStep::postStepInitialise(
this);
5332 double ts_delta_time;
5333 CHKERR TSGetTimeStep(ts, &ts_delta_time);
5336 CHKERR TSSetPreStep(ts, TSElasticPostStep::preStepFun);
5337 CHKERR TSSetPostStep(ts, TSElasticPostStep::postStepFun);
5340 CHKERR TSElasticPostStep::preStepFun(ts);
5341 CHKERR TSElasticPostStep::postStepFun(ts);
5344 CHKERR TaoSetType(tao, TAOLMVM);
5347 topologicalEvaluateObjectiveAndGradient,
5348 (
void *)topological_tao_ctx.get());
5352 monitor_ptr->ts = PETSC_NULLPTR;
5353 monitor_ptr->ts_u = PETSC_NULLPTR;
5361 CHKERR VecGhostUpdateBegin(tao_sol0, INSERT_VALUES, SCATTER_FORWARD);
5362 CHKERR VecGhostUpdateEnd(tao_sol0, INSERT_VALUES, SCATTER_FORWARD);
5364 int tao_sol_size, tao_sol_loc_size;
5365 CHKERR VecGetSize(tao_sol0, &tao_sol_size);
5366 CHKERR VecGetLocalSize(tao_sol0, &tao_sol_loc_size);
5368 <<
"Cohesive crack growth initial kappa vector size " << tao_sol_size
5369 <<
" local size " << tao_sol_loc_size <<
" number of interface faces "
5372 CHKERR TaoSetFromOptions(tao);
5380 CHKERR testTopologicalDerivative(topological_tao_ctx.get(), tao_sol0,
5384 CHKERR VecZeroEntries(tao_sol0);
5385 CHKERR VecGhostUpdateBegin(tao_sol0, INSERT_VALUES, SCATTER_FORWARD);
5386 CHKERR VecGhostUpdateEnd(tao_sol0, INSERT_VALUES, SCATTER_FORWARD);
5387 CHKERR TaoSetSolution(tao, tao_sol0);
5390 CHKERR TaoGetSolution(tao, &tao_sol);
5407 CHKERR VecGhostUpdateBegin(x, INSERT_VALUES, SCATTER_FORWARD);
5408 CHKERR VecGhostUpdateEnd(x, INSERT_VALUES, SCATTER_FORWARD);
5409 monitor_ptr->ts = PETSC_NULLPTR;
5410 monitor_ptr->ts_u = x;
5420 CHKERR TSElasticPostStep::postStepDestroy();
5421 TetPolynomialBase::switchCacheBaseOff<HDIV>(
Implementation of tonsorial bubble base div(v) = 0.
#define NBVOLUMETET_CCG_BUBBLE(P)
Bubble function for CGG H div space.
Implementation of CGGUserPolynomialBase class.
Auxilary functions for Eshelbian plasticity.
Contains definition of EshelbianMonitor class.
FormsIntegrators< FaceElementForcesAndSourcesCore::UserDataOperator >::Assembly< A >::BiLinearForm< GAUSS >::OpMass< 1, SPACE_DIM > OpMassVectorFace
static auto send_type(MoFEM::Interface &m_field, Range r, const EntityType type)
static auto get_block_meshset(MoFEM::Interface &m_field, const int ms_id, const unsigned int cubit_bc_type)
static auto get_range_from_block(MoFEM::Interface &m_field, const std::string block_name, int dim)
static auto get_two_sides_of_crack_surface(MoFEM::Interface &m_field, Range crack_faces)
static auto get_range_from_block_map(MoFEM::Interface &m_field, const std::string block_name, int dim)
static auto filter_owners(MoFEM::Interface &m_field, Range skin)
static auto filter_true_skin(MoFEM::Interface &m_field, Range &&skin)
static auto get_skin(MoFEM::Interface &m_field, Range body_ents)
static auto get_entities_by_handle(MoFEM::Interface &m_field, const std::string block_name)
static auto get_crack_front_edges(MoFEM::Interface &m_field, Range crack_faces)
Eshelbian plasticity interface.
#define MOFEM_LOG_SEVERITY_SYNC(comm, severity)
Synchronise "SYNC" on curtain severity level.
#define MOFEM_LOG_C(channel, severity, format,...)
#define FTENSOR_INDEX(DIM, I)
Range get_range_from_block(MoFEM::Interface &m_field, const std::string block_name, int dim)
ElementsAndOps< SPACE_DIM >::BoundaryEle BoundaryEle
FieldApproximationBase
approximation base
@ AINSWORTH_LEGENDRE_BASE
Ainsworth Cole (Legendre) approx. base .
@ USER_BASE
user implemented approximation base
#define MOAB_THROW(err)
Check error code of MoAB function and throw MoFEM exception.
#define CHK_THROW_MESSAGE(err, msg)
Check and throw MoFEM exception.
#define MoFEMFunctionReturnHot(a)
Last executable line of each PETSc function used for error handling. Replaces return()
@ L2
field with C-1 continuity
@ HDIV
field with continuous normal traction
#define MYPCOMM_INDEX
default communicator number PCOMM
@ DISCONTINUOUS
Broken continuity (No effect on L2 space)
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
#define CHK_MOAB_THROW(err, msg)
Check error code of MoAB function and throw MoFEM exception.
@ MOFEM_ATOM_TEST_INVALID
@ MOFEM_DATA_INCONSISTENCY
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
#define MoFEMFunctionBeginHot
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
PetscErrorCode DMMoFEMSetIsPartitioned(DM dm, PetscBool is_partitioned)
PetscErrorCode DMMoFEMCreateSubDM(DM subdm, DM dm, const char problem_name[])
Must be called by user to set Sub DM MoFEM data structures.
PetscErrorCode DMMoFEMAddElement(DM dm, std::string fe_name)
add element to dm
PetscErrorCode DMMoFEMSetSquareProblem(DM dm, PetscBool square_problem)
set squared problem
PetscErrorCode DMMoFEMTSSetIFunction(DM dm, const char fe_name[], MoFEM::FEMethod *method, MoFEM::BasicMethod *pre_only, MoFEM::BasicMethod *post_only)
set TS implicit function evaluation function
PetscErrorCode DMMoFEMCreateMoFEM(DM dm, MoFEM::Interface *m_field_ptr, const char problem_name[], const MoFEM::BitRefLevel bit_level, const MoFEM::BitRefLevel bit_mask=MoFEM::BitRefLevel().set())
Must be called by user to set MoFEM data structures.
PetscErrorCode DMoFEMPostProcessFiniteElements(DM dm, MoFEM::FEMethod *method)
execute finite element method for each element in dm (problem)
PetscErrorCode DMMoFEMAddSubFieldRow(DM dm, const char field_name[])
PetscErrorCode DMMoFEMGetTsCtx(DM dm, MoFEM::TsCtx **ts_ctx)
get MoFEM::TsCtx data structure
PetscErrorCode DMoFEMMeshToLocalVector(DM dm, Vec l, InsertMode mode, ScatterMode scatter_mode, RowColData rc=RowColData::COL)
set local (or ghosted) vector values on mesh for partition only
PetscErrorCode DMoFEMLoopFiniteElements(DM dm, const char fe_name[], MoFEM::FEMethod *method, CacheTupleWeakPtr cache_ptr=CacheTupleSharedPtr())
Executes FEMethod for finite elements in DM.
auto createDMVector(DM dm, RowColData rc=RowColData::COL)
Get smart vector from DM.
PetscErrorCode DMMoFEMTSSetIJacobian(DM dm, const std::string fe_name, boost::shared_ptr< MoFEM::FEMethod > method, boost::shared_ptr< MoFEM::BasicMethod > pre_only, boost::shared_ptr< MoFEM::BasicMethod > post_only)
set TS Jacobian evaluation function
PetscErrorCode DMMoFEMAddSubFieldCol(DM dm, const char field_name[])
PetscErrorCode DMMoFEMTSSetI2Jacobian(DM dm, const std::string fe_name, boost::shared_ptr< MoFEM::FEMethod > method, boost::shared_ptr< MoFEM::BasicMethod > pre_only, boost::shared_ptr< MoFEM::BasicMethod > post_only)
set TS Jacobian evaluation function
PetscErrorCode DMMoFEMTSSetI2Function(DM dm, const std::string fe_name, boost::shared_ptr< MoFEM::FEMethod > method, boost::shared_ptr< MoFEM::BasicMethod > pre_only, boost::shared_ptr< MoFEM::BasicMethod > post_only)
set TS implicit function evaluation function
PetscErrorCode DMoFEMLoopFiniteElementsUpAndLowRank(DM dm, const char fe_name[], MoFEM::FEMethod *method, int low_rank, int up_rank, CacheTupleWeakPtr cache_ptr=CacheTupleSharedPtr())
Executes FEMethod for finite elements in DM.
PetscErrorCode DMoFEMPreProcessFiniteElements(DM dm, MoFEM::FEMethod *method)
execute finite element method for each element in dm (problem)
virtual MoFEMErrorCode add_finite_element(const std::string &fe_name, enum MoFEMTypes bh=MF_EXCL, int verb=DEFAULT_VERBOSITY)=0
add finite element
virtual MoFEMErrorCode build_finite_elements(int verb=DEFAULT_VERBOSITY)=0
Build finite elements.
virtual MoFEMErrorCode modify_finite_element_add_field_col(const std::string &fe_name, const std::string name_row)=0
set field col which finite element use
virtual MoFEMErrorCode modify_finite_element_adjacency_table(const std::string &fe_name, const EntityType type, ElementAdjacencyFunct function)=0
modify finite element table, only for advanced user
virtual MoFEMErrorCode add_ents_to_finite_element_by_type(const EntityHandle entities, const EntityType type, const std::string name, const bool recursive=true)=0
add entities to finite element
virtual MoFEMErrorCode modify_finite_element_add_field_row(const std::string &fe_name, const std::string name_row)=0
set field row which finite element use
virtual MoFEMErrorCode modify_finite_element_add_field_data(const std::string &fe_name, const std::string name_field)=0
set finite element field data
virtual const Field * get_field_structure(const std::string &name, enum MoFEMTypes bh=MF_EXIST) const =0
get field structure
virtual MoFEMErrorCode build_fields(int verb=DEFAULT_VERBOSITY)=0
virtual MoFEMErrorCode add_ents_to_field_by_dim(const Range &ents, const int dim, const std::string &name, int verb=DEFAULT_VERBOSITY)=0
Add entities to field meshset.
virtual MoFEMErrorCode set_field_order(const EntityHandle meshset, const EntityType type, const std::string &name, const ApproximationOrder order, int verb=DEFAULT_VERBOSITY)=0
Set order approximation of the entities in the field.
virtual MoFEMErrorCode add_ents_to_field_by_type(const Range &ents, const EntityType type, const std::string &name, int verb=DEFAULT_VERBOSITY)=0
Add entities to field meshset.
#define MOFEM_LOG(channel, severity)
Log.
SeverityLevel
Severity levels.
#define MOFEM_LOG_TAG(channel, tag)
Tag channel.
#define MOFEM_LOG_CHANNEL(channel)
Set and reset channel.
virtual MoFEMErrorCode loop_dofs(const Problem *problem_ptr, const std::string &field_name, RowColData rc, DofMethod &method, int lower_rank, int upper_rank, int verb=DEFAULT_VERBOSITY)=0
Make a loop over dofs.
virtual MoFEMErrorCode loop_finite_elements(const std::string problem_name, const std::string &fe_name, FEMethod &method, boost::shared_ptr< NumeredEntFiniteElement_multiIndex > fe_ptr=nullptr, MoFEMTypes bh=MF_EXIST, CacheTupleWeakPtr cache_ptr=CacheTupleSharedPtr(), int verb=DEFAULT_VERBOSITY)=0
Make a loop over finite elements.
MoFEMErrorCode getCubitMeshsetPtr(const int ms_id, const CubitBCType cubit_bc_type, const CubitMeshSets **cubit_meshset_ptr) const
get cubit meshset
MoFEMErrorCode pushMarkDOFsOnEntities(const std::string problem_name, const std::string block_name, const std::string field_name, int lo, int hi, bool get_low_dim_ents=true)
Mark DOFs on block entities for boundary conditions.
#define NBVOLUMETET_L2(P)
Number of base functions on tetrahedron for L2 space.
FTensor::Index< 'i', SPACE_DIM > i
const double v
phase velocity of light in medium (cm/ns)
const double n
refractive index of diffusive medium
FTensor::Index< 'l', 3 > l
FTensor::Index< 'j', 3 > j
boost::shared_ptr< ContactSDFPython > setupContactSdf()
Read SDF file and setup contact SDF.
static auto get_range_from_block(MoFEM::Interface &m_field, const std::string block_name, int dim)
static Tag get_tag(moab::Interface &moab, std::string tag_name, int size)
ForcesAndSourcesCore::UserDataOperator * getOpContactDetection(EshelbianCore &ep, boost::shared_ptr< ForcesAndSourcesCore > contact_tree_ptr, boost::shared_ptr< MatrixDouble > u_h1_ptr, boost::shared_ptr< MatrixDouble > contact_traction_ptr, Range r, moab::Interface *post_proc_mesh_ptr, std::vector< EntityHandle > *map_gauss_pts_ptr)
Push operator for contact detection.
boost::shared_ptr< ForcesAndSourcesCore > createContactDetectionFiniteElement(EshelbianCore &ep)
Create a Contact Tree finite element.
MoFEMErrorCode pushContactOpsRhs(EshelbianCore &ep, boost::shared_ptr< ForcesAndSourcesCore > contact_tree_ptr, boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pip)
Push contact operations to the right-hand side.
MoFEMErrorCode pushContactOpsLhs(EshelbianCore &ep, boost::shared_ptr< ForcesAndSourcesCore > contact_tree_ptr, boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pip)
Push contact operations to the left-hand side.
MoFEMErrorCode pushCohesiveOpsLhs(EshelbianCore &ep, ForcesAndSourcesCore::GaussHookFun set_integration_at_front_face, boost::shared_ptr< Range > interface_range_ptr, boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pip)
MoFEMErrorCode pushCohesiveOpsRhs(EshelbianCore &ep, ForcesAndSourcesCore::GaussHookFun set_integration_at_front_face, boost::shared_ptr< Range > interface_range_ptr, boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pip)
static auto get_body_range(MoFEM::Interface &m_field, const std::string name, int dim)
static MoFEMErrorCodeGeneric< PetscErrorCode > ierr
static MoFEMErrorCodeGeneric< moab::ErrorCode > rval
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
UBlasMatrix< double > MatrixDouble
std::bitset< BITREFLEVEL_SIZE > BitRefLevel
Bit structure attached to each entity identifying to what mesh entity is attached.
implementation of Data Operators for Forces and Sources
PetscErrorCode TsMonitorSet(TS ts, PetscInt step, PetscReal t, Vec u, void *ctx)
Set monitor for TS solver.
auto getDMTsCtx(DM dm)
Get TS context data structure used by DM.
PetscErrorCode DMMoFEMSetDestroyProblem(DM dm, PetscBool destroy_problem)
MoFEMErrorCode MoFEMSNESMonitorEnergy(SNES snes, PetscInt its, PetscReal fgnorm, SnesCtx *ctx)
Sens monitor printing residual field by field.
auto id_from_handle(const EntityHandle h)
PetscErrorCode PetscOptionsGetBool(PetscOptions *, const char pre[], const char name[], PetscBool *bval, PetscBool *set)
PetscErrorCode PetscOptionsGetScalar(PetscOptions *, const char pre[], const char name[], PetscScalar *dval, PetscBool *set)
SmartPetscObj< Vec > vectorDuplicate(Vec vec)
Create duplicate vector of smart vector.
auto createVectorMPI(MPI_Comm comm, PetscInt n, PetscInt N)
Create MPI Vector.
PostProcBrokenMeshInMoabBaseEndImpl< PostProcBrokenMeshInMoabBase< ForcesAndSourcesCore > > PostProcBrokenMeshInMoabBaseEnd
Enable to run stack of post-processing elements. Use this to end stack.
PostProcBrokenMeshInMoabBaseBeginImpl< PostProcBrokenMeshInMoabBase< ForcesAndSourcesCore > > PostProcBrokenMeshInMoabBaseBegin
Enable to run stack of post-processing elements. Use this to begin stack.
PetscErrorCode PetscOptionsGetString(PetscOptions *, const char pre[], const char name[], char str[], size_t size, PetscBool *set)
auto get_temp_meshset_ptr(moab::Interface &moab)
Create smart pointer to temporary meshset.
PetscErrorCode TaoSetObjectiveAndGradient(Tao tao, Vec x, PetscReal *f, Vec g, void *ctx)
Sets the objective function value and gradient for a TAO optimization solver.
auto getDMSnesCtx(DM dm)
Get SNES context data structure used by DM.
auto createDM(MPI_Comm comm, const std::string dm_type_name)
Creates smart DM object.
auto createTao(MPI_Comm comm)
auto ent_form_type_and_id(const EntityType type, const EntityID id)
get entity handle from type and id
OpPostProcMapInMoab< SPACE_DIM, SPACE_DIM > OpPPMap
constexpr double t
plate stiffness
constexpr auto field_name
#define QUAD_2D_TABLE_SIZE
#define QUAD_3D_TABLE_SIZE
static QUAD *const QUAD_2D_TABLE[]
static QUAD *const QUAD_3D_TABLE[]
PipelineManager::ElementsAndOpsByDim< SPACE_DIM >::FaceSideEle EleOnSide
FTensor::Index< 'm', 3 > m
CGG User Polynomial Base.
static boost::shared_ptr< SetUpSchur > createSetUpSchur(MoFEM::Interface &m_field, EshelbianCore *ep_core_ptr)
MoFEMErrorCode setElasticElementOps(const int tag)
boost::shared_ptr< ExternalStrainVec > externalStrainVecPtr
MoFEMErrorCode addVolumeFiniteElement(const EntityHandle meshset=0)
MoFEMErrorCode addFields(const EntityHandle meshset=0)
static enum StretchSelector stretchSelector
boost::shared_ptr< Range > frontAdjEdges
static int interfaceRemoveLevel
MoFEMErrorCode addBoundaryFiniteElement(const EntityHandle meshset=0)
const std::string skeletonElement
static double inv_f_linear(const double v)
boost::shared_ptr< TractionBcVec > bcSpatialTractionVecPtr
boost::shared_ptr< Range > contactFaces
static double dd_f_log_e_quadratic(const double v)
static double dynamicTime
static double dd_f_log(const double v)
BitRefLevel bitAdjEnt
bit ref level for parent
MoFEMErrorCode postProcessResults(const int tag, const std::string file, Vec f_residual=PETSC_NULLPTR, Vec var_vec=PETSC_NULLPTR, std::vector< Tag > tags_to_transfer={}, TS ts=PETSC_NULLPTR)
static boost::function< double(const double)> inv_dd_f
MoFEM::Interface & mField
const std::string spatialL2Disp
static double inv_d_f_log(const double v)
std::map< std::string, boost::shared_ptr< ScalingMethod > > timeScaleMap
static enum SolverType solverType
static PetscBool l2UserBaseScale
SmartPetscObj< DM > dM
Coupled problem all fields.
MoFEMErrorCode projectInternalStress(const EntityHandle meshset=0)
MoFEMErrorCode solveSchapeOptimisation(TS ts, Vec x, int start_step, double start_time)
Solve cohesive crack growth problem.
static int internalStressInterpOrder
boost::shared_ptr< TractionFreeBc > bcSpatialFreeTractionVecPtr
static const char * listSolvers[]
const std::string materialH1Positions
static int nbJIntegralContours
MoFEMErrorCode setBlockTagsOnSkin()
static PetscBool crackingOn
MoFEMErrorCode getTractionFreeBc(const EntityHandle meshset, boost::shared_ptr< TractionFreeBc > &bc_ptr, const std::string contact_set_name)
Remove all, but entities where kinematic constrains are applied.
MoFEMErrorCode setBaseVolumeElementOps(const int tag, const bool do_rhs, const bool do_lhs, const bool calc_rates, boost::shared_ptr< VolumeElementForcesAndSourcesCore > fe)
static double griffithEnergy
Griffith energy.
boost::shared_ptr< VolumeElementForcesAndSourcesCore > elasticFeRhs
const std::string elementVolumeName
static double dd_f_log_e(const double v)
static enum RotSelector rotSelector
MoFEMErrorCode addDebugModel(TS ts)
Add debug to model.
static enum RotSelector gradApproximator
MoFEMErrorCode getBc(boost::shared_ptr< BC > &bc_vec_ptr, const std::string block_name, const int nb_attributes)
CommInterface::EntitiesPetscVector vertexExchange
boost::shared_ptr< BcRotVec > bcSpatialRotationVecPtr
static PetscBool dynamicRelaxation
const std::string spatialH1Disp
MoFEMErrorCode solveElastic(TS ts, Vec x)
static double d_f_log(const double v)
boost::shared_ptr< NormalDisplacementBcVec > bcSpatialNormalDisplacementVecPtr
static double crackingStartTime
MoFEMErrorCode getOptions()
const std::string piolaStress
MoFEMErrorCode setElasticElementToTs(DM dm)
static double inv_d_f_log_e(const double v)
MoFEMErrorCode setFaceInterfaceOps(const bool add_elastic, const bool add_material, boost::shared_ptr< FaceElementForcesAndSourcesCore > &fe_rhs, boost::shared_ptr< FaceElementForcesAndSourcesCore > &fe_lhs)
int contactRefinementLevels
MoFEMErrorCode gettingNorms()
[Getting norms]
boost::shared_ptr< Range > interfaceFaces
MoFEMErrorCode setVolumeElementOps(const int tag, const bool add_elastic, const bool add_material, boost::shared_ptr< VolumeElementForcesAndSourcesCore > &fe_rhs, boost::shared_ptr< VolumeElementForcesAndSourcesCore > &fe_lhs)
MoFEMErrorCode query_interface(boost::typeindex::type_index type_index, UnknownInterface **iface) const
Getting interface of core database.
const std::string bubbleField
boost::shared_ptr< AnalyticalDisplacementBcVec > bcSpatialAnalyticalDisplacementVecPtr
SmartPetscObj< DM > dmMaterial
Material problem.
static double inv_f_log(const double v)
boost::shared_ptr< VolumeElementForcesAndSourcesCore > elasticFeLhs
static PetscBool noStretch
boost::shared_ptr< ParentFiniteElementAdjacencyFunctionSkeleton< 2 > > parentAdjSkeletonFunctionDim2
static double crackingAddTime
static double exponentBase
static double dd_f_linear(const double v)
MoFEMErrorCode setFaceElementOps(const bool add_elastic, const bool add_material, boost::shared_ptr< FaceElementForcesAndSourcesCore > &fe_rhs, boost::shared_ptr< FaceElementForcesAndSourcesCore > &fe_lhs)
MoFEMErrorCode projectGeometry(const EntityHandle meshset=0, double time=0)
MoFEMErrorCode postProcessSkeletonResults(const int tag, const std::string file, Vec f_residual=PETSC_NULLPTR, std::vector< Tag > tags_to_transfer={})
boost::shared_ptr< AnalyticalExprPython > AnalyticalExprPythonPtr
static double crackingAtol
Cracking absolute tolerance.
boost::shared_ptr< Range > skeletonFaces
static double crackingRtol
Cracking relative tolerance.
boost::shared_ptr< PhysicalEquations > physicalEquations
const std::string rotAxis
static double inv_d_f_linear(const double v)
BitRefLevel bitAdjParentMask
bit ref level for parent parent
MoFEMErrorCode solveDynamicRelaxation(TS ts, Vec x, int start_step, double start_time)
Solve problem using dynamic relaxation method.
static double inv_dd_f_log(const double v)
const std::string contactDisp
static std::string internalStressTagName
static enum SymmetrySelector symmetrySelector
CommInterface::EntitiesPetscVector edgeExchange
SmartPetscObj< DM > dmPrjSpatial
Projection spatial displacement.
static boost::function< double(const double)> f
boost::shared_ptr< BcDispVec > bcSpatialDispVecPtr
const std::string skinElement
static PetscBool internalStressVoigt
static double inv_dd_f_linear(const double v)
static double inv_dd_f_log_e(const double v)
MoFEMErrorCode getExternalStrain()
MoFEMErrorCode getSpatialTractionBc()
static PetscBool setSingularity
static double d_f_log_e(const double v)
boost::shared_ptr< AnalyticalTractionBcVec > bcSpatialAnalyticalTractionVecPtr
static double f_log_e_quadratic(const double v)
MoFEMErrorCode addDMs(const BitRefLevel bit=BitRefLevel().set(0), const EntityHandle meshset=0)
MoFEMErrorCode solveCohesiveCrackGrowth(TS ts, Vec x, int start_step, double start_time)
Solve cohesive crack growth problem.
MoFEMErrorCode getSpatialDispBc()
[Getting norms]
BitRefLevel bitAdjParent
bit ref level for parent
MoFEMErrorCode setContactElementRhsOps(boost::shared_ptr< ForcesAndSourcesCore > &fe_contact_tree)
static PetscBool interfaceCrack
static double d_f_log_e_quadratic(const double v)
CommInterface::EntitiesPetscVector volumeExchange
const std::string naturalBcElement
static boost::function< double(const double)> dd_f
static double f_log_e(const double v)
static double inv_f_log_e(const double v)
MoFEMErrorCode createExchangeVectors(Sev sev)
boost::shared_ptr< DataAtIntegrationPts > dataAtPts
boost::shared_ptr< Range > crackFaces
static boost::function< double(const double)> d_f
boost::shared_ptr< Range > frontVertices
static enum EnergyReleaseSelector energyReleaseSelector
static boost::function< double(const double)> inv_d_f
boost::shared_ptr< PressureBcVec > bcSpatialPressureVecPtr
static double d_f_linear(const double v)
const std::string hybridSpatialDisp
SmartPetscObj< Vec > solTSStep
static double f_log(const double v)
CommInterface::EntitiesPetscVector faceExchange
SmartPetscObj< DM > dmElastic
Elastic problem.
EshelbianCore(MoFEM::Interface &m_field)
boost::shared_ptr< Range > frontEdges
static boost::function< double(const double)> inv_f
const std::string stretchTensor
BitRefLevel bitAdjEntMask
bit ref level for parent parent
static double f_linear(const double v)
const std::string contactElement
AnalyticalDisplacementBc(std::string name, std::vector< double > attr, Range faces)
AnalyticalTractionBc(std::string name, std::vector< double > attr, Range faces)
BcRot(std::string name, std::vector< double > attr, Range faces)
ExternalStrain(std::string name, std::vector< double > attr, Range ents)
int operator()(int p_row, int p_col, int p_data) const
NormalDisplacementBc(std::string name, std::vector< double > attr, Range faces)
PressureBc(std::string name, std::vector< double > attr, Range faces)
boost::shared_ptr< Range > frontNodes
SetIntegrationAtFrontFace(boost::shared_ptr< Range > front_nodes, boost::shared_ptr< Range > front_edges)
boost::shared_ptr< Range > frontEdges
boost::function< int(int)> FunRule
SetIntegrationAtFrontFace(boost::shared_ptr< Range > front_nodes, boost::shared_ptr< Range > front_edges, FunRule fun_rule)
MoFEMErrorCode operator()(ForcesAndSourcesCore *fe_raw_ptr, int order_row, int order_col, int order_data)
static std::map< long int, MatrixDouble > mapRefCoords
MoFEMErrorCode operator()(ForcesAndSourcesCore *fe_raw_ptr, int order_row, int order_col, int order_data)
boost::shared_ptr< Range > frontNodes
static std::map< long int, MatrixDouble > mapRefCoords
boost::function< int(int)> FunRule
boost::shared_ptr< CGGUserPolynomialBase::CachePhi > cachePhi
SetIntegrationAtFrontVolume(boost::shared_ptr< Range > front_nodes, boost::shared_ptr< Range > front_edges, boost::shared_ptr< CGGUserPolynomialBase::CachePhi > cache_phi=nullptr)
SetIntegrationAtFrontVolume(boost::shared_ptr< Range > front_nodes, boost::shared_ptr< Range > front_edges, FunRule fun_rule, boost::shared_ptr< CGGUserPolynomialBase::CachePhi > cache_phi=nullptr)
boost::shared_ptr< Range > frontEdges
static MoFEMErrorCode preStepFun(TS ts)
static MoFEMErrorCode postStepDestroy()
static MoFEMErrorCode postStepFun(TS ts)
static MoFEMErrorCode postStepInitialise(EshelbianCore *ep_ptr)
TractionBc(std::string name, std::vector< double > attr, Range faces)
Set integration rule on element.
int operator()(int p_row, int p_col, int p_data) const
static auto setup(EshelbianCore *ep_ptr, TS ts, Vec x, bool set_ts_monitor)
multi_index_container< DofsSideMapData, indexed_by< ordered_non_unique< tag< TypeSide_mi_tag >, composite_key< DofsSideMapData, member< DofsSideMapData, EntityType, &DofsSideMapData::type >, member< DofsSideMapData, int, &DofsSideMapData::side > > >, ordered_unique< tag< EntDofIdx_mi_tag >, member< DofsSideMapData, int, &DofsSideMapData::dof > > > > DofsSideMap
Map entity stype and side to element/entity dof index.
Boundary condition manager for finite element problem setup.
static std::pair< std::string, std::string > extractStringFromBlockId(const std::string block_id, const std::string prb_name)
Extract block name and block name from block id.
static MoFEMErrorCode updateEntitiesPetscVector(moab::Interface &moab, EntitiesPetscVector &vec, Tag tag, UpdateGhosts update_gosts=defaultUpdateGhosts)
Exchange data between vector and data.
static Range getPartEntities(moab::Interface &moab, int part)
static MoFEMErrorCode setVectorFromTag(moab::Interface &moab, EntitiesPetscVector &vec, Tag tag)
static MoFEMErrorCode setTagFromVector(moab::Interface &moab, EntitiesPetscVector &vec, Tag tag)
static EntitiesPetscVector createEntitiesPetscVector(MPI_Comm comm, moab::Interface &moab, std::function< Range(Range)> get_entities_fun, const int nb_coeffs, Sev sev=Sev::verbose, int root_rank=0, bool get_vertices=true)
Create a ghost vector for exchanging data.
virtual moab::Interface & get_moab()=0
virtual MoFEMErrorCode add_broken_field(const std::string name, const FieldSpace space, const FieldApproximationBase base, const FieldCoefficientsNumber nb_of_coefficients, const std::vector< std::pair< EntityType, std::function< MoFEMErrorCode(BaseFunction::DofsSideMap &)> > > list_dof_side_map, const TagType tag_type=MB_TAG_SPARSE, const enum MoFEMTypes bh=MF_EXCL, int verb=DEFAULT_VERBOSITY)=0
Add field.
virtual bool check_finite_element(const std::string &name) const =0
Check if finite element is in database.
virtual MoFEMErrorCode build_adjacencies(const Range &ents, int verb=DEFAULT_VERBOSITY)=0
build adjacencies
virtual MoFEMErrorCode add_field(const std::string name, const FieldSpace space, const FieldApproximationBase base, const FieldCoefficientsNumber nb_of_coefficients, const TagType tag_type=MB_TAG_SPARSE, const enum MoFEMTypes bh=MF_EXCL, int verb=DEFAULT_VERBOSITY)=0
Add field.
virtual MPI_Comm & get_comm() const =0
virtual int get_comm_rank() const =0
Deprecated interface functions.
Definition of the displacement bc data structure.
Data on single entity (This is passed as argument to DataOperator::doWork)
Structure for user loop methods on finite elements.
EntityHandle getFEEntityHandle() const
Get the entity handle of the current finite element.
default operator for TRI element
Field data structure for finite element approximation.
Definition of the force bc data structure.
UserDataOperator(const FieldSpace space, const char type=OPSPACE, const bool symm=true)
Constructor for operators working on finite element spaces.
structure to get information from mofem into EntitiesFieldData
static boost::shared_ptr< ScalingMethod > get(boost::shared_ptr< ScalingMethod > ts, std::string file_prefix, std::string file_suffix, std::string block_name, Args &&...args)
Section manager is used to create indexes and sections.
Mesh refinement interface.
Interface for managing meshsets containing materials and boundary conditions.
Natural boundary conditions.
Operator for broken loop side.
Get norm of input MatrixDouble for Tensor1.
Get norm of input MatrixDouble for Tensor2.
Calculate tenor field using tensor base, i.e. Hdiv/Hcurl.
Calculate divergence of tonsorial field using vectorial base.
Calculate tenor field using vectorial base, i.e. Hdiv/Hcurl.
Calculate trace of vector (Hdiv/Hcurl) space.
Calculate symmetric tensor field rates ant integratio pts.
Calculate symmetric tensor field values at integration pts.
Get field gradients time derivative at integration pts for scalar field rank 0, i....
Get field gradients at integration pts for scalar field rank 0, i.e. vector field.
Approximate field values for given petsc vector.
Specialization for double precision vector field values calculation.
Element used to execute operators on side of the element.
Execute "this" element in the operator.
Post post-proc data at points from hash maps.
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
Operator for linear form, usually to calculate values on right hand side.
std::map< std::string, boost::shared_ptr< MatrixDouble > > DataMapMat
@ CTX_SET_TIME
Time value is set.
static MoFEMErrorCode writeTSGraphGraphviz(TsCtx *ts_ctx, std::string file_name)
TS graph to Graphviz file.
Template struct for dimension-specific finite element types.
Problem manager is used to build and partition problems.
Projection of edge entities with one mid-node on hierarchical basis.
intrusive_ptr for managing petsc objects
std::function< double(double)> ScalingFun
FEMethodsSequence & getLoopsMonitor()
Get the loops to do Monitor object.
base class for all interface classes
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.
default operator for TET element
MoFEMErrorCode doWork(int side, EntityType type, EntData &data)
Apply rotation boundary condition.
BoundaryEle::UserDataOperator BdyEleOp
ElementsAndOps< SPACE_DIM >::SideEle SideEle