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;
58 const EntityType type) {
62 auto dim = CN::Dimension(type);
64 std::vector<int> sendcounts(pcomm->size());
65 std::vector<int> displs(pcomm->size());
66 std::vector<int> sendbuf(r.size());
67 if (pcomm->rank() == 0) {
68 for (
auto p = 1; p != pcomm->size(); p++) {
70 ->getPartEntities(m_field.
get_moab(), p)
73 CHKERR m_field.
get_moab().get_adjacencies(part_ents, dim,
true, faces,
74 moab::Interface::UNION);
75 faces = intersect(faces, r);
76 sendcounts[p] = faces.size();
77 displs[p] = sendbuf.size();
78 for (
auto f : faces) {
80 sendbuf.push_back(
id);
86 MPI_Scatter(sendcounts.data(), 1, MPI_INT, &recv_data, 1, MPI_INT, 0,
88 std::vector<int> recvbuf(recv_data);
89 MPI_Scatterv(sendbuf.data(), sendcounts.data(), displs.data(), MPI_INT,
90 recvbuf.data(), recv_data, MPI_INT, 0, pcomm->comm());
92 if (pcomm->rank() > 0) {
94 for (
auto &f : recvbuf) {
104 const std::string block_name,
int dim) {
110 std::regex((boost::format(
"%s(.*)") % block_name).str())
114 for (
auto bc : bcs) {
126 const std::string block_name,
int dim) {
127 std::map<std::string, Range> r;
132 std::regex((boost::format(
"%s(.*)") % block_name).str())
136 for (
auto bc : bcs) {
141 r[bc->getName()] = faces;
148 const unsigned int cubit_bc_type) {
151 CHKERR mesh_mng->getMeshset(ms_id, cubit_bc_type, meshset);
155static auto save_range(moab::Interface &moab,
const std::string name,
156 const Range r, std::vector<Tag> tags = {}) {
159 CHKERR moab.add_entities(*out_meshset, r);
161 CHKERR moab.write_file(name.c_str(),
"VTK",
"", out_meshset->get_ptr(), 1,
162 tags.data(), tags.size());
164 MOFEM_LOG(
"SELF", Sev::warning) <<
"Empty range for " << name;
171 ParallelComm *pcomm =
174 PSTATUS_SHARED | PSTATUS_MULTISHARED,
175 PSTATUS_NOT, -1, &boundary_ents),
177 return boundary_ents;
182 ParallelComm *pcomm =
184 CHK_MOAB_THROW(pcomm->filter_pstatus(skin, PSTATUS_NOT_OWNED, PSTATUS_NOT, -1,
193 CHK_MOAB_THROW(skin.find_skin(0, body_ents,
false, skin_ents),
"find_skin");
199 ParallelComm *pcomm =
202 Range crack_skin_without_bdy;
203 if (pcomm->rank() == 0) {
205 CHKERR moab.get_adjacencies(crack_faces, 1,
true, crack_edges,
206 moab::Interface::UNION);
207 auto crack_skin =
get_skin(m_field, crack_faces);
211 "get_entities_by_dimension");
212 auto body_skin =
get_skin(m_field, body_ents);
213 Range body_skin_edges;
214 CHK_MOAB_THROW(moab.get_adjacencies(body_skin, 1,
true, body_skin_edges,
215 moab::Interface::UNION),
217 crack_skin_without_bdy = subtract(crack_skin, body_skin_edges);
219 for (
auto &
m : front_edges_map) {
220 auto add_front = subtract(
m.second, crack_edges);
221 auto i = intersect(
m.second, crack_edges);
223 crack_skin_without_bdy.merge(add_front);
227 CHKERR moab.get_adjacencies(i_skin, 1,
true, adj_i_skin,
228 moab::Interface::UNION);
229 adj_i_skin = subtract(intersect(adj_i_skin,
m.second), crack_edges);
230 crack_skin_without_bdy.merge(adj_i_skin);
234 return send_type(m_field, crack_skin_without_bdy, MBEDGE);
240 ParallelComm *pcomm =
243 MOFEM_LOG(
"EP", Sev::noisy) <<
"get_two_sides_of_crack_surface";
245 if (!pcomm->rank()) {
247 auto impl = [&](
auto &saids) {
252 auto get_adj = [&](
auto e,
auto dim) {
255 e, dim,
true, adj, moab::Interface::UNION),
260 auto get_conn = [&](
auto e) {
267 constexpr bool debug =
false;
271 auto body_skin =
get_skin(m_field, body_ents);
272 auto body_skin_edges = get_adj(body_skin, 1);
275 subtract(
get_skin(m_field, crack_faces), body_skin_edges);
276 auto crack_skin_conn = get_conn(crack_skin);
277 auto crack_skin_conn_edges = get_adj(crack_skin_conn, 1);
278 auto crack_edges = get_adj(crack_faces, 1);
279 crack_edges = subtract(crack_edges, crack_skin);
280 auto all_tets = get_adj(crack_edges, 3);
281 crack_edges = subtract(crack_edges, crack_skin_conn_edges);
282 auto crack_conn = get_conn(crack_edges);
283 all_tets.merge(get_adj(crack_conn, 3));
292 if (crack_faces.size()) {
293 auto grow = [&](
auto r) {
294 auto crack_faces_conn = get_conn(crack_faces);
297 while (size_r != r.size() && r.size() > 0) {
299 CHKERR moab.get_connectivity(r,
v,
true);
300 v = subtract(
v, crack_faces_conn);
303 moab::Interface::UNION);
304 r = intersect(r, all_tets);
313 Range all_tets_ord = all_tets;
314 while (all_tets.size()) {
315 Range faces = get_adj(unite(saids.first, saids.second), 2);
316 faces = subtract(crack_faces, faces);
319 auto fit = faces.begin();
320 for (; fit != faces.end(); ++fit) {
321 tets = intersect(get_adj(
Range(*fit, *fit), 3), all_tets);
322 if (tets.size() == 2) {
329 saids.first.insert(tets[0]);
330 saids.first = grow(saids.first);
331 all_tets = subtract(all_tets, saids.first);
332 if (tets.size() == 2) {
333 saids.second.insert(tets[1]);
334 saids.second = grow(saids.second);
335 all_tets = subtract(all_tets, saids.second);
343 saids.first = subtract(all_tets_ord, saids.second);
344 saids.second = subtract(all_tets_ord, saids.first);
350 std::pair<Range, Range> saids;
351 if (crack_faces.size())
356 MOFEM_LOG(
"EP", Sev::noisy) <<
"get_two_sides_of_crack_surface <- done";
358 return std::pair<Range, Range>();
369 boost::shared_ptr<Range> front_nodes,
370 boost::shared_ptr<Range> front_edges,
371 boost::shared_ptr<CGGUserPolynomialBase::CachePhi> cache_phi =
nullptr)
375 boost::shared_ptr<Range> front_nodes,
376 boost::shared_ptr<Range> front_edges,
FunRule fun_rule,
377 boost::shared_ptr<CGGUserPolynomialBase::CachePhi> cache_phi =
nullptr)
382 int order_col,
int order_data) {
385 constexpr bool debug =
false;
387 constexpr int numNodes = 4;
388 constexpr int numEdges = 6;
389 constexpr int refinementLevels = 6;
391 auto &m_field = fe_raw_ptr->
mField;
392 auto fe_ptr =
static_cast<Fe *
>(fe_raw_ptr);
395 auto set_base_quadrature = [&]() {
397 int rule =
funRule(order_data);
408 auto &gauss_pts = fe_ptr->gaussPts;
409 gauss_pts.resize(4, nb_gauss_pts,
false);
410 cblas_dcopy(nb_gauss_pts, &
QUAD_3D_TABLE[rule]->points[1], 4,
411 &gauss_pts(0, 0), 1);
412 cblas_dcopy(nb_gauss_pts, &
QUAD_3D_TABLE[rule]->points[2], 4,
413 &gauss_pts(1, 0), 1);
414 cblas_dcopy(nb_gauss_pts, &
QUAD_3D_TABLE[rule]->points[3], 4,
415 &gauss_pts(2, 0), 1);
417 &gauss_pts(3, 0), 1);
418 auto &data = fe_ptr->dataOnElement[
H1];
419 data->dataOnEntities[MBVERTEX][0].getN(
NOBASE).resize(nb_gauss_pts, 4,
422 &*data->dataOnEntities[MBVERTEX][0].getN(
NOBASE).data().begin();
423 cblas_dcopy(4 * nb_gauss_pts,
QUAD_3D_TABLE[rule]->points, 1, shape_ptr,
432 CHKERR set_base_quadrature();
436 auto get_singular_nodes = [&]() {
439 CHKERR m_field.get_moab().get_connectivity(fe_handle, conn, num_nodes,
441 std::bitset<numNodes> singular_nodes;
442 for (
auto nn = 0; nn != numNodes; ++nn) {
444 singular_nodes.set(nn);
446 singular_nodes.reset(nn);
449 return singular_nodes;
452 auto get_singular_edges = [&]() {
453 std::bitset<numEdges> singular_edges;
454 for (
int ee = 0; ee != numEdges; ee++) {
456 CHKERR m_field.get_moab().side_element(fe_handle, 1, ee, edge);
458 singular_edges.set(ee);
460 singular_edges.reset(ee);
463 return singular_edges;
466 auto set_gauss_pts = [&](
auto &ref_gauss_pts) {
468 fe_ptr->gaussPts.swap(ref_gauss_pts);
469 const size_t nb_gauss_pts = fe_ptr->gaussPts.size2();
470 auto &data = fe_ptr->dataOnElement[
H1];
471 data->dataOnEntities[MBVERTEX][0].getN(
NOBASE).resize(nb_gauss_pts, 4);
473 &*data->dataOnEntities[MBVERTEX][0].getN(
NOBASE).data().begin();
475 &fe_ptr->gaussPts(1, 0), &fe_ptr->gaussPts(2, 0),
480 auto singular_nodes = get_singular_nodes();
481 if (singular_nodes.count()) {
482 auto it_map_ref_coords =
mapRefCoords.find(singular_nodes.to_ulong());
484 CHKERR set_gauss_pts(it_map_ref_coords->second);
488 auto refine_quadrature = [&]() {
491 const int max_level = refinementLevels;
495 double base_coords[] = {0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1};
497 for (
int nn = 0; nn != 4; nn++)
498 CHKERR moab_ref.create_vertex(&base_coords[3 * nn], nodes[nn]);
499 CHKERR moab_ref.create_element(MBTET, nodes, 4, tet);
503 Range tets(tet, tet);
506 tets, 1,
true, edges, moab::Interface::UNION);
511 Range nodes_at_front;
512 for (
int nn = 0; nn != numNodes; nn++) {
513 if (singular_nodes[nn]) {
515 CHKERR moab_ref.side_element(tet, 0, nn, ent);
516 nodes_at_front.insert(ent);
520 auto singular_edges = get_singular_edges();
523 CHKERR moab_ref.create_meshset(MESHSET_SET, meshset);
524 for (
int ee = 0; ee != numEdges; ee++) {
525 if (singular_edges[ee]) {
527 CHKERR moab_ref.side_element(tet, 1, ee, ent);
528 CHKERR moab_ref.add_entities(meshset, &ent, 1);
534 for (
int ll = 0; ll != max_level; ll++) {
537 ->getEntitiesByTypeAndRefLevel(
BitRefLevel().set(ll),
541 CHKERR moab_ref.get_adjacencies(
542 nodes_at_front, 1,
true, ref_edges, moab::Interface::UNION);
543 ref_edges = intersect(ref_edges, edges);
545 CHKERR moab_ref.get_entities_by_type(meshset, MBEDGE, ents,
true);
546 ref_edges = intersect(ref_edges, ents);
549 ->getEntitiesByTypeAndRefLevel(
551 CHKERR m_ref->addVerticesInTheMiddleOfEdges(
555 ->updateMeshsetByEntitiesChildren(meshset,
557 meshset, MBEDGE,
true);
563 ->getEntitiesByTypeAndRefLevel(
BitRefLevel().set(max_level),
573 for (Range::iterator tit = tets.begin(); tit != tets.end();
577 CHKERR moab_ref.get_connectivity(*tit, conn, num_nodes,
false);
578 CHKERR moab_ref.get_coords(conn, num_nodes, &ref_coords(tt, 0));
581 auto &data = fe_ptr->dataOnElement[
H1];
582 const size_t nb_gauss_pts = fe_ptr->gaussPts.size2();
583 MatrixDouble ref_gauss_pts(4, nb_gauss_pts * ref_coords.size1());
585 data->dataOnEntities[MBVERTEX][0].getN(
NOBASE);
587 for (
size_t tt = 0; tt != ref_coords.size1(); tt++) {
588 double *tet_coords = &ref_coords(tt, 0);
591 for (
size_t ggg = 0; ggg != nb_gauss_pts; ++ggg, ++gg) {
592 for (
int dd = 0; dd != 3; dd++) {
593 ref_gauss_pts(dd, gg) =
594 shape_n(ggg, 0) * tet_coords[3 * 0 + dd] +
595 shape_n(ggg, 1) * tet_coords[3 * 1 + dd] +
596 shape_n(ggg, 2) * tet_coords[3 * 2 + dd] +
597 shape_n(ggg, 3) * tet_coords[3 * 3 + dd];
599 ref_gauss_pts(3, gg) = fe_ptr->gaussPts(3, ggg) * det;
603 mapRefCoords[singular_nodes.to_ulong()].swap(ref_gauss_pts);
610 TetPolynomialBase::switchCacheBaseOff<HDIV>({fe_raw_ptr});
611 TetPolynomialBase::switchCacheBaseOn<HDIV>({fe_raw_ptr});
616 CHKERR refine_quadrature();
626 using ForcesAndSourcesCore::dataOnElement;
629 using ForcesAndSourcesCore::ForcesAndSourcesCore;
635 boost::shared_ptr<CGGUserPolynomialBase::CachePhi>
cachePhi;
646 boost::shared_ptr<Range> front_edges)
650 boost::shared_ptr<Range> front_edges,
655 int order_col,
int order_data) {
658 constexpr bool debug =
false;
660 constexpr int numNodes = 3;
661 constexpr int numEdges = 3;
662 constexpr int refinementLevels = 6;
664 auto &m_field = fe_raw_ptr->
mField;
665 auto fe_ptr =
static_cast<Fe *
>(fe_raw_ptr);
668 auto set_base_quadrature = [&]() {
670 int rule =
funRule(order_data);
680 fe_ptr->gaussPts.resize(3, nb_gauss_pts,
false);
681 cblas_dcopy(nb_gauss_pts, &
QUAD_2D_TABLE[rule]->points[1], 3,
682 &fe_ptr->gaussPts(0, 0), 1);
683 cblas_dcopy(nb_gauss_pts, &
QUAD_2D_TABLE[rule]->points[2], 3,
684 &fe_ptr->gaussPts(1, 0), 1);
686 &fe_ptr->gaussPts(2, 0), 1);
687 auto &data = fe_ptr->dataOnElement[
H1];
688 data->dataOnEntities[MBVERTEX][0].getN(
NOBASE).resize(nb_gauss_pts, 3,
691 &*data->dataOnEntities[MBVERTEX][0].getN(
NOBASE).data().begin();
692 cblas_dcopy(3 * nb_gauss_pts,
QUAD_2D_TABLE[rule]->points, 1, shape_ptr,
694 data->dataOnEntities[MBVERTEX][0].getDiffN(
NOBASE).resize(3, 2,
false);
697 data->dataOnEntities[MBVERTEX][0].getDiffN(
NOBASE).data().begin());
706 CHKERR set_base_quadrature();
710 auto get_singular_nodes = [&]() {
713 CHKERR m_field.get_moab().get_connectivity(fe_handle, conn, num_nodes,
715 std::bitset<numNodes> singular_nodes;
716 for (
auto nn = 0; nn != numNodes; ++nn) {
718 singular_nodes.set(nn);
720 singular_nodes.reset(nn);
723 return singular_nodes;
726 auto get_singular_edges = [&]() {
727 std::bitset<numEdges> singular_edges;
728 for (
int ee = 0; ee != numEdges; ee++) {
730 CHKERR m_field.get_moab().side_element(fe_handle, 1, ee, edge);
732 singular_edges.set(ee);
734 singular_edges.reset(ee);
737 return singular_edges;
740 auto set_gauss_pts = [&](
auto &ref_gauss_pts) {
742 fe_ptr->gaussPts.swap(ref_gauss_pts);
743 const size_t nb_gauss_pts = fe_ptr->gaussPts.size2();
744 auto &data = fe_ptr->dataOnElement[
H1];
745 data->dataOnEntities[MBVERTEX][0].getN(
NOBASE).resize(nb_gauss_pts, 4);
747 &*data->dataOnEntities[MBVERTEX][0].getN(
NOBASE).data().begin();
749 &fe_ptr->gaussPts(1, 0), nb_gauss_pts);
753 auto singular_nodes = get_singular_nodes();
754 if (singular_nodes.count()) {
755 auto it_map_ref_coords =
mapRefCoords.find(singular_nodes.to_ulong());
757 CHKERR set_gauss_pts(it_map_ref_coords->second);
761 auto refine_quadrature = [&]() {
764 const int max_level = refinementLevels;
767 double base_coords[] = {0, 0, 0, 1, 0, 0, 0, 1, 0};
769 for (
int nn = 0; nn != numNodes; nn++)
770 CHKERR moab_ref.create_vertex(&base_coords[3 * nn], nodes[nn]);
772 CHKERR moab_ref.create_element(MBTRI, nodes, numNodes, tri);
776 Range tris(tri, tri);
779 tris, 1,
true, edges, moab::Interface::UNION);
784 Range nodes_at_front;
785 for (
int nn = 0; nn != numNodes; nn++) {
786 if (singular_nodes[nn]) {
788 CHKERR moab_ref.side_element(tri, 0, nn, ent);
789 nodes_at_front.insert(ent);
793 auto singular_edges = get_singular_edges();
796 CHKERR moab_ref.create_meshset(MESHSET_SET, meshset);
797 for (
int ee = 0; ee != numEdges; ee++) {
798 if (singular_edges[ee]) {
800 CHKERR moab_ref.side_element(tri, 1, ee, ent);
801 CHKERR moab_ref.add_entities(meshset, &ent, 1);
807 for (
int ll = 0; ll != max_level; ll++) {
810 ->getEntitiesByTypeAndRefLevel(
BitRefLevel().set(ll),
814 CHKERR moab_ref.get_adjacencies(
815 nodes_at_front, 1,
true, ref_edges, moab::Interface::UNION);
816 ref_edges = intersect(ref_edges, edges);
818 CHKERR moab_ref.get_entities_by_type(meshset, MBEDGE, ents,
true);
819 ref_edges = intersect(ref_edges, ents);
822 ->getEntitiesByTypeAndRefLevel(
824 CHKERR m_ref->addVerticesInTheMiddleOfEdges(
828 ->updateMeshsetByEntitiesChildren(meshset,
830 meshset, MBEDGE,
true);
836 ->getEntitiesByTypeAndRefLevel(
BitRefLevel().set(max_level),
847 for (Range::iterator tit = tris.begin(); tit != tris.end();
851 CHKERR moab_ref.get_connectivity(*tit, conn, num_nodes,
false);
852 CHKERR moab_ref.get_coords(conn, num_nodes, &ref_coords(tt, 0));
855 auto &data = fe_ptr->dataOnElement[
H1];
856 const size_t nb_gauss_pts = fe_ptr->gaussPts.size2();
857 MatrixDouble ref_gauss_pts(3, nb_gauss_pts * ref_coords.size1());
859 data->dataOnEntities[MBVERTEX][0].getN(
NOBASE);
861 for (
size_t tt = 0; tt != ref_coords.size1(); tt++) {
862 double *tri_coords = &ref_coords(tt, 0);
865 auto det = t_normal.
l2();
866 for (
size_t ggg = 0; ggg != nb_gauss_pts; ++ggg, ++gg) {
867 for (
int dd = 0; dd != 2; dd++) {
868 ref_gauss_pts(dd, gg) =
869 shape_n(ggg, 0) * tri_coords[3 * 0 + dd] +
870 shape_n(ggg, 1) * tri_coords[3 * 1 + dd] +
871 shape_n(ggg, 2) * tri_coords[3 * 2 + dd];
873 ref_gauss_pts(2, gg) = fe_ptr->gaussPts(2, ggg) * det;
877 mapRefCoords[singular_nodes.to_ulong()].swap(ref_gauss_pts);
883 CHKERR refine_quadrature();
893 using ForcesAndSourcesCore::dataOnElement;
896 using ForcesAndSourcesCore::ForcesAndSourcesCore;
945 const char *list_rots[] = {
"small",
"moderate",
"large",
"no_h1"};
946 const char *list_symm[] = {
"symm",
"not_symm"};
947 const char *list_release[] = {
"griffith_force",
"griffith_skeleton"};
948 const char *list_stretches[] = {
"linear",
"log",
"log_quadratic"};
949 const char *list_solvers[] = {
"time_solver",
"dynamic_relaxation",
955 PetscInt choice_stretch = StretchSelector::LOG;
957 char analytical_expr_file_name[255] =
"analytical_expr.py";
959 PetscOptionsBegin(PETSC_COMM_WORLD,
"",
"Eshelbian plasticity",
"none");
960 CHKERR PetscOptionsInt(
"-space_order",
"approximation oder for space",
"",
962 CHKERR PetscOptionsInt(
"-space_h1_order",
"approximation oder for space",
"",
964 CHKERR PetscOptionsInt(
"-material_order",
"approximation oder for material",
966 CHKERR PetscOptionsScalar(
"-viscosity_alpha_u",
"viscosity",
"",
alphaU,
968 CHKERR PetscOptionsScalar(
"-viscosity_alpha_w",
"viscosity",
"",
alphaW,
970 CHKERR PetscOptionsScalar(
"-viscosity_alpha_omega",
"rot viscosity",
"",
972 CHKERR PetscOptionsScalar(
"-density_alpha_rho",
"density",
"",
alphaRho,
976 CHKERR PetscOptionsEList(
"-rotations",
"rotations",
"", list_rots,
977 LARGE_ROT + 1, list_rots[choice_rot], &choice_rot,
979 CHKERR PetscOptionsEList(
"-grad",
"gradient of defamation approximate",
"",
980 list_rots, NO_H1_CONFIGURATION + 1,
981 list_rots[choice_grad], &choice_grad, PETSC_NULLPTR);
982 CHKERR PetscOptionsEList(
"-symm",
"symmetric variant",
"", list_symm, 2,
983 list_symm[choice_symm], &choice_symm, PETSC_NULLPTR);
987 CHKERR PetscOptionsEList(
"-stretches",
"stretches",
"", list_stretches,
988 StretchSelector::STRETCH_SELECTOR_LAST,
989 list_stretches[choice_stretch], &choice_stretch,
992 CHKERR PetscOptionsBool(
"-no_stretch",
"do not solve for stretch",
"",
994 CHKERR PetscOptionsBool(
"-set_singularity",
"set singularity",
"",
996 CHKERR PetscOptionsBool(
"-l2_user_base_scale",
"streach scale",
"",
1002 CHKERR PetscOptionsBool(
"-dynamic_relaxation",
"dynamic time relaxation",
"",
1004 CHKERR PetscOptionsEList(
"-solver_type",
"solver type",
"", list_solvers,
1006 &choice_solver, PETSC_NULLPTR);
1009 CHKERR PetscOptionsInt(
"-contact_max_post_proc_ref_level",
"refinement level",
1013 CHKERR PetscOptionsBool(
"-cohesive_interface_on",
"cohesive interface ON",
"",
1019 CHKERR PetscOptionsScalar(
"-cracking_start_time",
"cracking start time",
"",
1022 CHKERR PetscOptionsScalar(
"-griffith_energy",
"Griffith energy",
"",
1025 CHKERR PetscOptionsScalar(
"-cracking_rtol",
"Cracking relative tolerance",
"",
1027 CHKERR PetscOptionsScalar(
"-cracking_atol",
"Cracking absolute tolerance",
"",
1029 CHKERR PetscOptionsEList(
"-energy_release_variant",
"energy release variant",
1030 "", list_release, 2, list_release[choice_release],
1031 &choice_release, PETSC_NULLPTR);
1032 CHKERR PetscOptionsInt(
"-nb_J_integral_levels",
"Number of J integarl levels",
1036 "-nb_J_integral_contours",
"Number of J integral contours",
"",
1040 char tag_name[255] =
"";
1041 CHKERR PetscOptionsString(
"-internal_stress_tag_name",
1042 "internal stress tag name",
"",
"", tag_name, 255,
1046 "-internal_stress_interp_order",
"internal stress interpolation order",
1048 CHKERR PetscOptionsBool(
"-internal_stress_voigt",
"Voigt index notation",
"",
1053 "-analytical_expr_file",
1054 analytical_expr_file_name, 255, PETSC_NULLPTR);
1060 "Unsupported internal stress interpolation order %d",
1073 static_cast<EnergyReleaseSelector
>(choice_release);
1076 case StretchSelector::LINEAR:
1084 case StretchSelector::LOG:
1086 std::numeric_limits<float>::epsilon()) {
1102 case StretchSelector::LOG_QUADRATIC:
1108 "No logarithmic quadratic stretch for this case");
1121 <<
"-dynamic_relaxation option is deprecated, use -solver_type "
1122 "dynamic_relaxation instead.";
1126 switch (choice_solver) {
1148 MOFEM_LOG(
"EP", Sev::inform) <<
"alphaU: -viscosity_alpha_u " <<
alphaU;
1149 MOFEM_LOG(
"EP", Sev::inform) <<
"alphaW: -viscosity_alpha_w " <<
alphaW;
1151 <<
"alphaOmega: -viscosity_alpha_omega " <<
alphaOmega;
1156 MOFEM_LOG(
"EP", Sev::inform) <<
"Gradient of deformation "
1164 MOFEM_LOG(
"EP", Sev::inform) <<
"Base exponent e";
1166 <<
"Stretch: -stretches " << list_stretches[choice_stretch];
1176 <<
"Solver type: -solver_type " << list_solvers[choice_solver];
1194 <<
"Cracking relative tolerance: -cracking_rtol " <<
crackingRtol;
1196 <<
"Cracking absolute tolerance: -cracking_atol " <<
crackingAtol;
1198 <<
"Energy release variant: -energy_release_variant "
1201 <<
"Number of J integral contours: -nb_J_integral_contours "
1204 <<
"Cohesive interface on: -cohesive_interface_on "
1209#ifdef ENABLE_PYTHON_BINDING
1210 auto file_exists = [](std::string myfile) {
1211 std::ifstream file(myfile.c_str());
1218 if (file_exists(analytical_expr_file_name)) {
1219 MOFEM_LOG(
"EP", Sev::inform) << analytical_expr_file_name <<
" file found";
1223 analytical_expr_file_name);
1227 << analytical_expr_file_name <<
" file NOT found";
1240 auto get_tets = [&]() {
1246 auto get_tets_skin = [&]() {
1247 Range tets_skin_part;
1249 CHKERR skin.find_skin(0, get_tets(),
false, tets_skin_part);
1250 ParallelComm *pcomm =
1253 CHKERR pcomm->filter_pstatus(tets_skin_part,
1254 PSTATUS_SHARED | PSTATUS_MULTISHARED,
1255 PSTATUS_NOT, -1, &tets_skin);
1259 auto subtract_boundary_conditions = [&](
auto &&tets_skin) {
1265 tets_skin = subtract(tets_skin,
v.faces);
1269 tets_skin = subtract(tets_skin,
v.faces);
1274 tets_skin = subtract(tets_skin,
v.faces);
1280 auto add_blockset = [&](
auto block_name,
auto &&tets_skin) {
1283 tets_skin.merge(crack_faces);
1287 auto subtract_blockset = [&](
auto block_name,
auto &&tets_skin) {
1288 auto contact_range =
1290 tets_skin = subtract(tets_skin, contact_range);
1294 auto get_stress_trace_faces = [&](
auto &&tets_skin) {
1297 faces, moab::Interface::UNION);
1298 Range trace_faces = subtract(faces, tets_skin);
1302 auto tets = get_tets();
1306 auto trace_faces = get_stress_trace_faces(
1308 subtract_blockset(
"CONTACT",
1309 subtract_boundary_conditions(get_tets_skin()))
1316 boost::make_shared<Range>(subtract(trace_faces, *
contactFaces));
1331 auto add_broken_hdiv_field = [
this, meshset](
const std::string
field_name,
1337 auto get_side_map_hdiv = [&]() {
1340 std::pair<EntityType,
1355 get_side_map_hdiv(), MB_TAG_DENSE,
MF_ZERO);
1361 auto add_l2_field = [
this, meshset](
const std::string
field_name,
1362 const int order,
const int dim) {
1371 auto add_h1_field = [
this, meshset](
const std::string
field_name,
1372 const int order,
const int dim) {
1384 auto add_l2_field_by_range = [
this](
const std::string
field_name,
1385 const int order,
const int dim,
1386 const int field_dim,
Range &&r) {
1396 auto add_bubble_field = [
this, meshset](
const std::string
field_name,
1397 const int order,
const int dim) {
1403 auto field_order_table =
1404 const_cast<Field *
>(field_ptr)->getFieldOrderTable();
1405 auto get_cgg_bubble_order_zero = [](
int p) {
return 0; };
1406 auto get_cgg_bubble_order_tet = [](
int p) {
1409 field_order_table[MBVERTEX] = get_cgg_bubble_order_zero;
1410 field_order_table[MBEDGE] = get_cgg_bubble_order_zero;
1411 field_order_table[MBTRI] = get_cgg_bubble_order_zero;
1412 field_order_table[MBTET] = get_cgg_bubble_order_tet;
1419 auto add_user_l2_field = [
this, meshset](
const std::string
field_name,
1420 const int order,
const int dim) {
1426 auto field_order_table =
1427 const_cast<Field *
>(field_ptr)->getFieldOrderTable();
1428 auto zero_dofs = [](
int p) {
return 0; };
1430 field_order_table[MBVERTEX] = zero_dofs;
1431 field_order_table[MBEDGE] = zero_dofs;
1432 field_order_table[MBTRI] = zero_dofs;
1433 field_order_table[MBTET] = dof_l2_tet;
1451 auto get_hybridised_disp = [&]() {
1453 auto skin = subtract_boundary_conditions(get_tets_skin());
1455 faces.merge(intersect(bc.faces, skin));
1461 get_hybridised_disp());
1487 auto project_ho_geometry = [&](
auto field) {
1493 auto get_adj_front_edges = [&](
auto &front_edges) {
1494 Range front_crack_nodes;
1495 Range crack_front_edges_with_both_nodes_not_at_front;
1500 moab.get_connectivity(front_edges, front_crack_nodes,
true),
1501 "get_connectivity failed");
1502 Range crack_front_edges;
1504 false, crack_front_edges,
1505 moab::Interface::UNION),
1506 "get_adjacencies failed");
1507 Range crack_front_edges_nodes;
1509 crack_front_edges_nodes,
true),
1510 "get_connectivity failed");
1512 crack_front_edges_nodes =
1513 subtract(crack_front_edges_nodes, front_crack_nodes);
1514 Range crack_front_edges_with_both_nodes_not_at_front;
1516 moab.get_adjacencies(crack_front_edges_nodes, 1,
false,
1517 crack_front_edges_with_both_nodes_not_at_front,
1518 moab::Interface::UNION),
1519 "get_adjacencies failed");
1521 crack_front_edges_with_both_nodes_not_at_front = intersect(
1522 crack_front_edges, crack_front_edges_with_both_nodes_not_at_front);
1526 crack_front_edges_with_both_nodes_not_at_front =
send_type(
1527 mField, crack_front_edges_with_both_nodes_not_at_front, MBEDGE);
1529 return std::make_pair(boost::make_shared<Range>(front_crack_nodes),
1530 boost::make_shared<Range>(
1531 crack_front_edges_with_both_nodes_not_at_front));
1538 auto [front_vertices, front_adj_edges] = get_adj_front_edges(*
frontEdges);
1543 <<
"Number of crack faces: " <<
crackFaces->size();
1545 <<
"Number of front edges: " <<
frontEdges->size();
1549 <<
"Number of front adjacent edges: " <<
frontAdjEdges->size();
1558 (boost::format(
"crack_faces_%d.vtk") % rank).str(),
1561 (boost::format(
"front_edges_%d.vtk") % rank).str(),
1572 auto set_singular_dofs = [&](
auto &front_adj_edges,
auto &front_vertices) {
1580 MOFEM_LOG(
"EP", Sev::inform) <<
"Singularity eps " << beta;
1585 [&](boost::shared_ptr<FieldEntity> field_entity_ptr) ->
MoFEMErrorCode {
1590 auto nb_dofs = field_entity_ptr->getEntFieldData().size();
1596 if (field_entity_ptr->getNbOfCoeffs() != 3)
1598 "Expected 3 coefficients per edge");
1599 if (nb_dofs % 3 != 0)
1601 "Expected multiple of 3 coefficients per edge");
1604 auto get_conn = [&]() {
1607 CHKERR moab.get_connectivity(field_entity_ptr->getEnt(), conn,
1609 return std::make_pair(conn, num_nodes);
1612 auto get_dir = [&](
auto &&conn_p) {
1613 auto [conn, num_nodes] = conn_p;
1615 CHKERR moab.get_coords(conn, num_nodes, coords);
1617 coords[4] - coords[1],
1618 coords[5] - coords[2]};
1622 auto get_singularity_dof = [&](
auto &&conn_p,
auto &&t_edge_dir) {
1623 auto [conn, num_nodes] = conn_p;
1625 if (front_vertices.find(conn[0]) != front_vertices.end()) {
1626 t_singularity_dof(
i) = t_edge_dir(
i) * (-
eps);
1627 }
else if (front_vertices.find(conn[1]) != front_vertices.end()) {
1628 t_singularity_dof(
i) = t_edge_dir(
i) *
eps;
1630 return t_singularity_dof;
1633 auto t_singularity_dof =
1634 get_singularity_dof(get_conn(), get_dir(get_conn()));
1636 auto field_data = field_entity_ptr->getEntFieldData();
1638 &field_data[0], &field_data[1], &field_data[2]};
1640 t_dof(
i) = t_singularity_dof(
i);
1642 for (
auto n = 1;
n < field_data.size() / 3; ++
n) {
1664 auto get_interface_from_block = [&](
auto block_name) {
1669 faces, moab::Interface::UNION);
1670 faces = subtract(faces, skin);
1672 <<
"Number of vol interface elements: " << vol_eles.size()
1673 <<
" and faces: " << faces.size();
1677 interfaceFaces->merge(get_interface_from_block(
"VOLUME_INTERFACE"));
1685#ifdef INCLUDE_MBCOUPLER
1687 char mesh_source_file[255] =
"source.h5m";
1688 char iterp_tag_name[255] =
"INTERNAL_STRESS";
1690 int interp_order = 1;
1691 PetscBool hybrid_interp = PETSC_TRUE;
1692 PetscBool project_internal_stress = PETSC_FALSE;
1694 double toler = 5.e-10;
1695 PetscOptionsBegin(PETSC_COMM_WORLD,
"mesh_transfer_",
"mesh data transfer",
1697 CHKERR PetscOptionsString(
"-source_file",
"source mesh file name",
"",
1698 "source.h5m", mesh_source_file, 255,
1699 &project_internal_stress);
1700 CHKERR PetscOptionsString(
"-interp_tag",
"interpolation tag name",
"",
1701 "INTERNAL_STRESS", iterp_tag_name, 255,
1703 CHKERR PetscOptionsInt(
"-interp_order",
"interpolation order",
"", 0,
1704 &interp_order, PETSC_NULLPTR);
1705 CHKERR PetscOptionsBool(
"-hybrid_interp",
"use hybrid interpolation",
"",
1706 hybrid_interp, &hybrid_interp, PETSC_NULLPTR);
1711 if (!project_internal_stress) {
1713 <<
"No internal stress source mesh specified. Skipping projection of "
1718 <<
"Projecting internal stress from source mesh: " << mesh_source_file;
1724 auto rval_check_tag = moab.tag_get_handle(iterp_tag_name, old_interp_tag);
1725 if (rval_check_tag == MB_SUCCESS) {
1727 <<
"Deleting existing tag on target mesh: " << iterp_tag_name;
1728 CHKERR moab.tag_delete(old_interp_tag);
1732 int world_rank = -1, world_size = -1;
1733 MPI_Comm_rank(PETSC_COMM_WORLD, &world_rank);
1734 MPI_Comm_size(PETSC_COMM_WORLD, &world_size);
1736 Range original_meshset_ents;
1737 CHKERR moab.get_entities_by_handle(0, original_meshset_ents);
1739 MPI_Comm comm_coupler;
1740 if (world_rank == 0) {
1741 MPI_Comm_split(PETSC_COMM_WORLD, 0, 0, &comm_coupler);
1743 MPI_Comm_split(PETSC_COMM_WORLD, MPI_UNDEFINED, world_rank, &comm_coupler);
1747 ParallelComm *pcomm0 =
nullptr;
1749 if (world_rank == 0) {
1750 pcomm0 =
new ParallelComm(&moab, comm_coupler, &pcomm0_id);
1753 Coupler::Method method;
1754 switch (interp_order) {
1756 method = Coupler::CONSTANT;
1759 method = Coupler::LINEAR_FE;
1763 "Unsupported interpolation order");
1767 ierr = MPI_Comm_size(PETSC_COMM_WORLD, &nprocs);
1769 ierr = MPI_Comm_rank(PETSC_COMM_WORLD, &rank);
1781 CHKERR moab.create_meshset(MESHSET_SET, target_root);
1783 <<
"Creating target mesh from existing meshset";
1784 Range target_meshset_ents;
1785 CHKERR moab.get_entities_by_handle(0, target_meshset_ents);
1786 CHKERR moab.add_entities(target_root, target_meshset_ents);
1794 Range targ_verts, targ_elems;
1795 if (world_rank == 0) {
1798 CHKERR moab.create_meshset(MESHSET_SET, source_root);
1800 MOFEM_LOG(
"WORLD", Sev::inform) <<
"Loading source mesh on rank 0";
1801 auto rval_source_mesh = moab.load_file(mesh_source_file, &source_root,
"");
1802 if (rval_source_mesh != MB_SUCCESS) {
1804 <<
"Error loading source mesh file: " << mesh_source_file;
1806 MOFEM_LOG(
"WORLD", Sev::inform) <<
"Source mesh loaded.";
1809 CHKERR moab.get_entities_by_dimension(source_root, 3, src_elems);
1812 CHKERR pcomm0->create_part(part_set);
1813 CHKERR moab.add_entities(part_set, src_elems);
1815 Range src_elems_part;
1816 CHKERR pcomm0->get_part_entities(src_elems_part, 3);
1819 CHKERR moab.tag_get_handle(iterp_tag_name, interp_tag);
1822 CHKERR moab.tag_get_length(interp_tag, interp_tag_len);
1824 if (interp_tag_len != 1 && interp_tag_len != 3 && interp_tag_len != 9) {
1826 "Unsupported interpolation tag length: %d", interp_tag_len);
1830 tag_length = interp_tag_len;
1831 CHKERR moab.tag_get_data_type(interp_tag, dtype);
1832 CHKERR moab.tag_get_type(interp_tag, storage);
1835 Coupler mbc(&moab, pcomm0, src_elems_part, 0,
true);
1837 std::vector<double> vpos;
1843 CHKERR moab.get_entities_by_dimension(target_root, 3, targ_elems);
1845 if (interp_order == 0) {
1846 targ_verts = targ_elems;
1848 CHKERR moab.get_adjacencies(targ_elems, 0,
false, targ_verts,
1849 moab::Interface::UNION);
1853 CHKERR pcomm0->get_pstatus_entities(0, PSTATUS_NOT_OWNED, tmp_verts);
1854 targ_verts = subtract(targ_verts, tmp_verts);
1857 num_pts = (int)targ_verts.size();
1858 vpos.resize(3 * targ_verts.size());
1859 CHKERR moab.get_coords(targ_verts, &vpos[0]);
1862 boost::shared_ptr<TupleList> tl_ptr;
1863 tl_ptr = boost::make_shared<TupleList>();
1864 CHKERR mbc.locate_points(&vpos[0], num_pts, 0, toler, tl_ptr.get(),
false);
1867 auto find_missing_points = [&](
Range &targ_verts,
int &num_pts,
1868 std::vector<double> &vpos,
1869 Range &missing_verts) {
1871 int missing_pts_num = 0;
1873 auto vit = targ_verts.begin();
1874 for (; vit != targ_verts.end();
i++) {
1875 if (tl_ptr->vi_rd[3 *
i + 1] == -1) {
1876 missing_verts.insert(*vit);
1877 vit = targ_verts.erase(vit);
1884 int missing_pts_num_global = 0;
1887 if (missing_pts_num_global) {
1889 << missing_pts_num_global
1890 <<
" points in target mesh were not located in source mesh. ";
1893 if (missing_pts_num) {
1894 num_pts = (int)targ_verts.size();
1895 vpos.resize(3 * targ_verts.size());
1896 CHKERR moab.get_coords(targ_verts, &vpos[0]);
1898 CHKERR mbc.locate_points(&vpos[0], num_pts, 0, toler, tl_ptr.get(),
1904 Range missing_verts;
1905 CHKERR find_missing_points(targ_verts, num_pts, vpos, missing_verts);
1907 std::vector<double> source_data(interp_tag_len * src_elems.size(), 0.0);
1908 std::vector<double> target_data(interp_tag_len * num_pts, 0.0);
1910 CHKERR moab.tag_get_data(interp_tag, src_elems, &source_data[0]);
1912 Tag scalar_tag, adj_count_tag;
1914 string scalar_tag_name = string(iterp_tag_name) +
"_COMP";
1915 CHKERR moab.tag_get_handle(scalar_tag_name.c_str(), 1, MB_TYPE_DOUBLE,
1916 scalar_tag, MB_TAG_CREAT | MB_TAG_DENSE,
1919 string adj_count_tag_name =
"ADJ_COUNT";
1921 CHKERR moab.tag_get_handle(adj_count_tag_name.c_str(), 1, MB_TYPE_DOUBLE,
1922 adj_count_tag, MB_TAG_CREAT | MB_TAG_DENSE,
1927 auto create_scalar_tags = [&](
const Range &src_elems,
1928 const std::vector<double> &source_data,
1932 std::vector<double> source_data_scalar(src_elems.size());
1934 for (
int ielem = 0; ielem < src_elems.size(); ielem++) {
1935 source_data_scalar[ielem] = source_data[itag + ielem * interp_tag_len];
1939 CHKERR moab.tag_set_data(scalar_tag, src_elems, &source_data_scalar[0]);
1941 if (interp_order == 1) {
1944 CHKERR moab.get_connectivity(src_elems, src_verts,
true);
1946 CHKERR moab.tag_clear_data(scalar_tag, src_verts, &def_scl);
1947 CHKERR moab.tag_clear_data(adj_count_tag, src_verts, &def_adj);
1949 for (
auto &tet : src_elems) {
1950 double tet_data = 0;
1951 CHKERR moab.tag_get_data(scalar_tag, &tet, 1, &tet_data);
1954 CHKERR moab.get_connectivity(&tet, 1, adj_verts,
true);
1956 std::vector<double> adj_vert_data(adj_verts.size(), 0.0);
1957 std::vector<double> adj_vert_count(adj_verts.size(), 0.0);
1959 CHKERR moab.tag_get_data(scalar_tag, adj_verts, &adj_vert_data[0]);
1960 CHKERR moab.tag_get_data(adj_count_tag, adj_verts,
1961 &adj_vert_count[0]);
1963 for (
int ivert = 0; ivert < adj_verts.size(); ivert++) {
1964 adj_vert_data[ivert] += tet_data;
1965 adj_vert_count[ivert] += 1;
1968 CHKERR moab.tag_set_data(scalar_tag, adj_verts, &adj_vert_data[0]);
1969 CHKERR moab.tag_set_data(adj_count_tag, adj_verts,
1970 &adj_vert_count[0]);
1974 std::vector<Tag> tags = {scalar_tag, adj_count_tag};
1975 pcomm0->reduce_tags(tags, tags, MPI_SUM, src_verts);
1977 std::vector<double> src_vert_data(src_verts.size(), 0.0);
1978 std::vector<double> src_vert_adj_count(src_verts.size(), 0.0);
1980 CHKERR moab.tag_get_data(scalar_tag, src_verts, &src_vert_data[0]);
1981 CHKERR moab.tag_get_data(adj_count_tag, src_verts,
1982 &src_vert_adj_count[0]);
1984 for (
int ivert = 0; ivert < src_verts.size(); ivert++) {
1985 src_vert_data[ivert] /= src_vert_adj_count[ivert];
1987 CHKERR moab.tag_set_data(scalar_tag, src_verts, &src_vert_data[0]);
1992 for (
int itag = 0; itag < interp_tag_len; itag++) {
1994 CHKERR create_scalar_tags(src_elems, source_data, itag);
1996 std::vector<double> target_data_scalar(num_pts, 0.0);
1997 CHKERR mbc.interpolate(method, scalar_tag_name, &target_data_scalar[0],
2000 for (
int ielem = 0; ielem < num_pts; ielem++) {
2001 target_data[itag + ielem * interp_tag_len] = target_data_scalar[ielem];
2006 CHKERR moab.tag_set_data(interp_tag, targ_verts, &target_data[0]);
2008 if (missing_verts.size() && (interp_order == 1) && hybrid_interp) {
2009 MOFEM_LOG(
"WORLD", Sev::warning) <<
"Using hybrid interpolation for "
2010 "missing points in the target mesh.";
2011 Range missing_adj_elems;
2012 CHKERR moab.get_adjacencies(missing_verts, 3,
false, missing_adj_elems,
2013 moab::Interface::UNION);
2015 int num_adj_elems = (int)missing_adj_elems.size();
2016 std::vector<double> vpos_adj_elems;
2018 vpos_adj_elems.resize(3 * missing_adj_elems.size());
2019 CHKERR moab.get_coords(missing_adj_elems, &vpos_adj_elems[0]);
2023 CHKERR mbc.locate_points(&vpos_adj_elems[0], num_adj_elems, 0, toler,
2024 tl_ptr.get(),
false);
2027 CHKERR find_missing_points(missing_adj_elems, num_adj_elems,
2028 vpos_adj_elems, missing_tets);
2029 if (missing_tets.size()) {
2031 << missing_tets.size()
2032 <<
"points in target mesh were not located in source mesh. ";
2035 std::vector<double> target_data_adj_elems(interp_tag_len * num_adj_elems,
2038 for (
int itag = 0; itag < interp_tag_len; itag++) {
2039 CHKERR create_scalar_tags(src_elems, source_data, itag);
2041 std::vector<double> target_data_adj_elems_scalar(num_adj_elems, 0.0);
2042 CHKERR mbc.interpolate(method, scalar_tag_name,
2043 &target_data_adj_elems_scalar[0], tl_ptr.get());
2045 for (
int ielem = 0; ielem < num_adj_elems; ielem++) {
2046 target_data_adj_elems[itag + ielem * interp_tag_len] =
2047 target_data_adj_elems_scalar[ielem];
2051 CHKERR moab.tag_set_data(interp_tag, missing_adj_elems,
2052 &target_data_adj_elems[0]);
2055 for (
auto &vert : missing_verts) {
2057 CHKERR moab.get_adjacencies(&vert, 1, 3,
false, adj_elems,
2058 moab::Interface::UNION);
2060 std::vector<double> adj_elems_data(adj_elems.size() * interp_tag_len,
2062 CHKERR moab.tag_get_data(interp_tag, adj_elems, &adj_elems_data[0]);
2064 std::vector<double> vert_data(interp_tag_len, 0.0);
2065 for (
int itag = 0; itag < interp_tag_len; itag++) {
2066 for (
int i = 0;
i < adj_elems.size();
i++) {
2067 vert_data[itag] += adj_elems_data[
i * interp_tag_len + itag];
2069 vert_data[itag] /= adj_elems.size();
2071 CHKERR moab.tag_set_data(interp_tag, &vert, 1, &vert_data[0]);
2075 CHKERR moab.tag_delete(scalar_tag);
2076 CHKERR moab.tag_delete(adj_count_tag);
2078 Range src_mesh_ents;
2079 CHKERR moab.get_entities_by_handle(source_root, src_mesh_ents);
2080 CHKERR moab.delete_entities(&source_root, 1);
2081 CHKERR moab.delete_entities(src_mesh_ents);
2082 CHKERR moab.delete_entities(&part_set, 1);
2086 MPI_Bcast(&tag_length, 1, MPI_INT, 0, PETSC_COMM_WORLD);
2087 MPI_Bcast(&dtype, 1, MPI_INT, 0, PETSC_COMM_WORLD);
2088 MPI_Bcast(&storage, 1, MPI_INT, 0, PETSC_COMM_WORLD);
2093 MB_TAG_CREAT | storage;
2094 std::vector<double> def_val(tag_length, 0.);
2095 CHKERR moab.tag_get_handle(iterp_tag_name, tag_length, dtype, interp_tag_all,
2096 flags, def_val.data());
2097 MPI_Barrier(PETSC_COMM_WORLD);
2119 CHKERR moab.delete_entities(&target_root, 1);
2130 auto add_field_to_fe = [
this](
const std::string fe,
2169 auto set_fe_adjacency = [&](
auto fe_name) {
2172 boost::make_shared<ParentFiniteElementAdjacencyFunctionSkeleton<2>>(
2180 auto add_field_to_fe = [
this](
const std::string fe,
2192 Range natural_bc_elements;
2195 natural_bc_elements.merge(
v.faces);
2200 natural_bc_elements.merge(
v.faces);
2205 natural_bc_elements.merge(
v.faces);
2210 natural_bc_elements.merge(
v.faces);
2215 natural_bc_elements.merge(
v.faces);
2220 natural_bc_elements.merge(
v.faces);
2225 natural_bc_elements.merge(
v.faces);
2228 natural_bc_elements = intersect(natural_bc_elements, meshset_ents);
2239 auto get_skin = [&](
auto &body_ents) {
2242 CHKERR skin.find_skin(0, body_ents,
false, skin_ents);
2247 Range boundary_ents;
2248 ParallelComm *pcomm =
2250 CHKERR pcomm->filter_pstatus(skin, PSTATUS_SHARED | PSTATUS_MULTISHARED,
2251 PSTATUS_NOT, -1, &boundary_ents);
2252 return boundary_ents;
2334 auto remove_dofs_on_broken_skin = [&](
const std::string prb_name) {
2336 for (
int d : {0, 1, 2}) {
2337 std::vector<boost::weak_ptr<NumeredDofEntity>> dofs_to_remove;
2339 ->getSideDofsOnBrokenSpaceEntities(
2350 CHKERR remove_dofs_on_broken_skin(
"ESHELBY_PLASTICITY");
2386 auto set_zero_block = [&]() {
2418 auto set_section = [&]() {
2420 PetscSection section;
2425 CHKERR PetscSectionDestroy(§ion);
2448BcDisp::BcDisp(std::string name, std::vector<double> attr,
Range faces)
2449 : blockName(name), faces(faces) {
2450 vals.resize(3,
false);
2451 flags.resize(3,
false);
2452 for (
int ii = 0; ii != 3; ++ii) {
2453 vals[ii] = attr[ii];
2454 flags[ii] =
static_cast<int>(attr[ii + 3]);
2457 MOFEM_LOG(
"EP", Sev::inform) <<
"Add BCDisp " << name;
2459 <<
"Add BCDisp vals " <<
vals[0] <<
" " <<
vals[1] <<
" " <<
vals[2];
2461 <<
"Add BCDisp flags " <<
flags[0] <<
" " <<
flags[1] <<
" " <<
flags[2];
2462 MOFEM_LOG(
"EP", Sev::inform) <<
"Add BCDisp nb. of faces " <<
faces.size();
2466 : blockName(name), faces(faces) {
2467 vals.resize(attr.size(),
false);
2468 for (
int ii = 0; ii != attr.size(); ++ii) {
2469 vals[ii] = attr[ii];
2475 : blockName(name), faces(faces) {
2476 vals.resize(3,
false);
2477 flags.resize(3,
false);
2478 for (
int ii = 0; ii != 3; ++ii) {
2479 vals[ii] = attr[ii];
2480 flags[ii] =
static_cast<int>(attr[ii + 3]);
2483 MOFEM_LOG(
"EP", Sev::inform) <<
"Add BCForce " << name;
2485 <<
"Add BCForce vals " <<
vals[0] <<
" " <<
vals[1] <<
" " <<
vals[2];
2487 <<
"Add BCForce flags " <<
flags[0] <<
" " <<
flags[1] <<
" " <<
flags[2];
2488 MOFEM_LOG(
"EP", Sev::inform) <<
"Add BCForce nb. of faces " <<
faces.size();
2492 std::vector<double> attr,
2494 : blockName(name), faces(faces) {
2497 if (attr.size() < 1) {
2499 "Wrong size of normal displacement BC");
2504 MOFEM_LOG(
"EP", Sev::inform) <<
"Add NormalDisplacementBc " << name;
2505 MOFEM_LOG(
"EP", Sev::inform) <<
"Add NormalDisplacementBc val " <<
val;
2507 <<
"Add NormalDisplacementBc nb. of faces " <<
faces.size();
2511 : blockName(name), faces(faces) {
2514 if (attr.size() < 1) {
2516 "Wrong size of normal displacement BC");
2521 MOFEM_LOG(
"EP", Sev::inform) <<
"Add PressureBc " << name;
2522 MOFEM_LOG(
"EP", Sev::inform) <<
"Add PressureBc val " <<
val;
2524 <<
"Add PressureBc nb. of faces " <<
faces.size();
2529 : blockName(name), ents(ents) {
2532 if (attr.size() < 2) {
2534 "Wrong size of external strain attribute");
2540 MOFEM_LOG(
"EP", Sev::inform) <<
"Add ExternalStrain " << name;
2541 MOFEM_LOG(
"EP", Sev::inform) <<
"Add ExternalStrain val " <<
val;
2543 <<
"Add ExternalStrain bulk modulus K " <<
bulkModulusK;
2545 <<
"Add ExternalStrain nb. of tets " <<
ents.size();
2549 std::vector<double> attr,
2551 : blockName(name), faces(faces) {
2554 if (attr.size() < 3) {
2556 "Wrong size of analytical displacement BC");
2559 flags.resize(3,
false);
2560 for (
int ii = 0; ii != 3; ++ii) {
2561 flags[ii] = attr[ii];
2564 MOFEM_LOG(
"EP", Sev::inform) <<
"Add AnalyticalDisplacementBc " << name;
2566 <<
"Add AnalyticalDisplacementBc flags " <<
flags[0] <<
" " <<
flags[1]
2569 <<
"Add AnalyticalDisplacementBc nb. of faces " <<
faces.size();
2573 std::vector<double> attr,
2575 : blockName(name), faces(faces) {
2578 if (attr.size() < 3) {
2580 "Wrong size of analytical traction BC");
2583 flags.resize(3,
false);
2584 for (
int ii = 0; ii != 3; ++ii) {
2585 flags[ii] = attr[ii];
2588 MOFEM_LOG(
"EP", Sev::inform) <<
"Add AnalyticalTractionBc " << name;
2589 MOFEM_LOG(
"EP", Sev::inform) <<
"Add AnalyticalTractionBc flags " <<
flags[0]
2592 <<
"Add AnalyticalTractionBc nb. of faces " <<
faces.size();
2597 boost::shared_ptr<TractionFreeBc> &bc_ptr,
2598 const std::string contact_set_name) {
2603 CHKERR mField.get_moab().get_entities_by_type(meshset, MBTET, tets);
2604 Range tets_skin_part;
2605 Skinner skin(&mField.get_moab());
2606 CHKERR skin.find_skin(0, tets,
false, tets_skin_part);
2607 ParallelComm *pcomm =
2610 CHKERR pcomm->filter_pstatus(tets_skin_part,
2611 PSTATUS_SHARED | PSTATUS_MULTISHARED,
2612 PSTATUS_NOT, -1, &tets_skin);
2615 for (
int dd = 0; dd != 3; ++dd)
2616 (*bc_ptr)[dd] = tets_skin;
2619 if (bcSpatialDispVecPtr)
2620 for (
auto &
v : *bcSpatialDispVecPtr) {
2622 (*bc_ptr)[0] = subtract((*bc_ptr)[0],
v.faces);
2624 (*bc_ptr)[1] = subtract((*bc_ptr)[1],
v.faces);
2626 (*bc_ptr)[2] = subtract((*bc_ptr)[2],
v.faces);
2630 if (bcSpatialRotationVecPtr)
2631 for (
auto &
v : *bcSpatialRotationVecPtr) {
2632 (*bc_ptr)[0] = subtract((*bc_ptr)[0],
v.faces);
2633 (*bc_ptr)[1] = subtract((*bc_ptr)[1],
v.faces);
2634 (*bc_ptr)[2] = subtract((*bc_ptr)[2],
v.faces);
2637 if (bcSpatialNormalDisplacementVecPtr)
2638 for (
auto &
v : *bcSpatialNormalDisplacementVecPtr) {
2639 (*bc_ptr)[0] = subtract((*bc_ptr)[0],
v.faces);
2640 (*bc_ptr)[1] = subtract((*bc_ptr)[1],
v.faces);
2641 (*bc_ptr)[2] = subtract((*bc_ptr)[2],
v.faces);
2644 if (bcSpatialAnalyticalDisplacementVecPtr)
2645 for (
auto &
v : *bcSpatialAnalyticalDisplacementVecPtr) {
2647 (*bc_ptr)[0] = subtract((*bc_ptr)[0],
v.faces);
2649 (*bc_ptr)[1] = subtract((*bc_ptr)[1],
v.faces);
2651 (*bc_ptr)[2] = subtract((*bc_ptr)[2],
v.faces);
2654 if (bcSpatialTractionVecPtr)
2655 for (
auto &
v : *bcSpatialTractionVecPtr) {
2656 (*bc_ptr)[0] = subtract((*bc_ptr)[0],
v.faces);
2657 (*bc_ptr)[1] = subtract((*bc_ptr)[1],
v.faces);
2658 (*bc_ptr)[2] = subtract((*bc_ptr)[2],
v.faces);
2661 if (bcSpatialAnalyticalTractionVecPtr)
2662 for (
auto &
v : *bcSpatialAnalyticalTractionVecPtr) {
2663 (*bc_ptr)[0] = subtract((*bc_ptr)[0],
v.faces);
2664 (*bc_ptr)[1] = subtract((*bc_ptr)[1],
v.faces);
2665 (*bc_ptr)[2] = subtract((*bc_ptr)[2],
v.faces);
2668 if (bcSpatialPressureVecPtr)
2669 for (
auto &
v : *bcSpatialPressureVecPtr) {
2670 (*bc_ptr)[0] = subtract((*bc_ptr)[0],
v.faces);
2671 (*bc_ptr)[1] = subtract((*bc_ptr)[1],
v.faces);
2672 (*bc_ptr)[2] = subtract((*bc_ptr)[2],
v.faces);
2677 std::regex((boost::format(
"%s(.*)") % contact_set_name).str()))) {
2679 CHKERR m->getMeshsetIdEntitiesByDimension(mField.get_moab(), 2, faces,
2681 (*bc_ptr)[0] = subtract((*bc_ptr)[0], faces);
2682 (*bc_ptr)[1] = subtract((*bc_ptr)[1], faces);
2683 (*bc_ptr)[2] = subtract((*bc_ptr)[2], faces);
2700 return 2 * p_data + 1;
2706 return 2 * (p_data + 1);
2711 const int tag,
const bool do_rhs,
const bool do_lhs,
const bool calc_rates,
2712 boost::shared_ptr<VolumeElementForcesAndSourcesCore> fe) {
2716 boost::make_shared<CGGUserPolynomialBase::CachePhi>(0, 0,
MatrixDouble());
2717 fe->getUserPolynomialBase() =
2718 boost::make_shared<CGGUserPolynomialBase>(bubble_cache);
2719 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
2720 fe->getOpPtrVector(), {HDIV, H1, L2}, materialH1Positions, frontAdjEdges);
2723 fe->getRuleHook = [](int, int, int) {
return -1; };
2724 auto vol_rule_lin = [](
int o) {
return 2 * o + 1; };
2725 auto vol_rule_no_lin = [](
int o) {
return 2 * o + (o - 1) + 1; };
2726 auto vol_rule = (
SMALL_ROT > 0) ? vol_rule_lin : vol_rule_no_lin;
2727 fe->setRuleHook = SetIntegrationAtFrontVolume(frontVertices, frontAdjEdges,
2728 vol_rule, bubble_cache);
2734 dataAtPts->physicsPtr = physicalEquations;
2739 piolaStress, dataAtPts->getApproxPAtPts()));
2741 bubbleField, dataAtPts->getApproxPAtPts(), MBMAXTYPE));
2743 piolaStress, dataAtPts->getDivPAtPts()));
2746 fe->getOpPtrVector().push_back(
2747 physicalEquations->returnOpCalculateStretchFromStress(
2748 dataAtPts, physicalEquations));
2750 fe->getOpPtrVector().push_back(
2752 stretchTensor, dataAtPts->getLogStretchTensorAtPts(), MBTET));
2756 rotAxis, dataAtPts->getRotAxisAtPts(), MBTET));
2758 rotAxis, dataAtPts->getRotAxis0AtPts(), solTSStep, MBTET));
2760 spatialL2Disp, dataAtPts->getSmallWL2AtPts(), MBTET));
2764 spatialH1Disp, dataAtPts->getSmallWH1AtPts()));
2766 spatialH1Disp, dataAtPts->getSmallWGradH1AtPts()));
2771 spatialL2Disp, dataAtPts->getSmallWL2DotAtPts(), MBTET));
2774 fe->getOpPtrVector().push_back(
2776 stretchTensor, dataAtPts->getLogStretchDotTensorAtPts(), MBTET));
2777 fe->getOpPtrVector().push_back(
2779 stretchTensor, dataAtPts->getGradLogStretchDotTensorAtPts(),
2783 rotAxis, dataAtPts->getRotAxisDotAtPts(), MBTET));
2785 rotAxis, dataAtPts->getRotAxisGradDotAtPts(), MBTET));
2788 if (std::abs(alphaRho) > std::numeric_limits<double>::epsilon()) {
2790 spatialL2Disp, dataAtPts->getSmallWL2DotDotAtPts(), MBTET));
2796 dataAtPts, ((do_rhs || do_lhs) && calc_rates) ? alphaOmega : 0.));
2801 fe->getOpPtrVector().push_back(physicalEquations->returnOpJacobian(
2802 tag, do_rhs, do_lhs, dataAtPts, physicalEquations));
2809 const int tag,
const bool add_elastic,
const bool add_material,
2810 boost::shared_ptr<VolumeElementForcesAndSourcesCore> &fe_rhs,
2811 boost::shared_ptr<VolumeElementForcesAndSourcesCore> &fe_lhs) {
2816 std::map<int, Range> map;
2819 mField.getInterface<
MeshsetsManager>()->getCubitMeshsetPtr(std::regex(
2821 (boost::format(
"%s(.*)") % name).str()
2827 CHK_MOAB_THROW(m_ptr->getMeshsetIdEntitiesByDimension(mField.get_moab(),
2830 map[m_ptr->getMeshsetId()] = ents;
2836 constexpr bool stab_tau_dot_variant =
false;
2838 auto local_tau_sacale = boost::make_shared<double>(1.0);
2841 using BdyEleOp = BoundaryEle::UserDataOperator;
2843 set_scale_op->doWorkRhsHook =
2845 local_tau_sacale](
DataOperator *raw_op_ptr,
int side, EntityType type,
2848 auto op_ptr =
static_cast<BdyEleOp *
>(raw_op_ptr);
2849 auto h = std::sqrt(op_ptr->getFTensor1Normal().l2());
2850 *local_tau_sacale = (alphaTau /
h);
2854 auto not_interface_face = [
this](
FEMethod *fe_method_ptr) {
2855 auto ent = fe_method_ptr->getFEEntityHandle();
2858 (interfaceFaces->find(ent) != interfaceFaces->end())
2860 || (crackFaces->find(ent) != crackFaces->end())
2869 fe_rhs = boost::make_shared<VolumeElementForcesAndSourcesCore>(mField);
2870 CHKERR setBaseVolumeElementOps(tag,
true,
false,
true, fe_rhs);
2875 fe_rhs->getOpPtrVector().push_back(
2877 fe_rhs->getOpPtrVector().push_back(
2882 if (!internalStressTagName.empty()) {
2883 switch (internalStressInterpOrder) {
2885 fe_rhs->getOpPtrVector().push_back(
2889 fe_rhs->getOpPtrVector().push_back(
2894 "Unsupported internal stress interpolation order %d",
2895 internalStressInterpOrder);
2899 auto ts_internal_stress =
2900 boost::make_shared<DynamicRelaxationTimeScale>(
2901 "internal_stress_history.txt",
false, def_scaling_fun);
2902 if (internalStressVoigt) {
2903 fe_rhs->getOpPtrVector().push_back(
2905 stretchTensor, dataAtPts, ts_internal_stress));
2907 fe_rhs->getOpPtrVector().push_back(
2909 stretchTensor, dataAtPts, ts_internal_stress));
2912 if (
auto op = physicalEquations->returnOpSpatialPhysicalExternalStrain(
2913 stretchTensor, dataAtPts, externalStrainVecPtr, timeScaleMap)) {
2914 fe_rhs->getOpPtrVector().push_back(op);
2915 }
else if (externalStrainVecPtr && !externalStrainVecPtr->empty()) {
2917 "OpSpatialPhysicalExternalStrain not implemented for this "
2921 fe_rhs->getOpPtrVector().push_back(
2922 physicalEquations->returnOpSpatialPhysical(stretchTensor, dataAtPts,
2925 fe_rhs->getOpPtrVector().push_back(
2927 fe_rhs->getOpPtrVector().push_back(
2929 fe_rhs->getOpPtrVector().push_back(
2932 auto set_hybridisation_rhs = [&](
auto &pip) {
2939 using SideEleOp = EleOnSide::UserDataOperator;
2940 using BdyEleOp = BoundaryEle::UserDataOperator;
2945 mField, skeletonElement,
SPACE_DIM - 1, Sev::noisy);
2947 op_loop_skeleton_side->getSideFEPtr()->getRuleHook = [](int, int, int) {
2950 op_loop_skeleton_side->getSideFEPtr()->setRuleHook =
2951 SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
2953 CHKERR EshelbianPlasticity::
2954 AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
2955 op_loop_skeleton_side->getOpPtrVector(), {L2},
2956 materialH1Positions, frontAdjEdges);
2960 auto broken_data_ptr =
2961 boost::make_shared<std::vector<BrokenBaseSideData>>();
2964 mField, elementVolumeName,
SPACE_DIM, Sev::noisy);
2965 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
2966 boost::make_shared<CGGUserPolynomialBase>();
2968 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
2969 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
2970 materialH1Positions, frontAdjEdges);
2971 op_loop_domain_side->getOpPtrVector().push_back(
2973 auto flux_mat_ptr = boost::make_shared<MatrixDouble>();
2974 op_loop_domain_side->getOpPtrVector().push_back(
2977 op_loop_domain_side->getOpPtrVector().push_back(
2981 op_loop_skeleton_side->getOpPtrVector().push_back(op_loop_domain_side);
2983 GAUSS>::OpBrokenSpaceConstrainDHybrid<SPACE_DIM>;
2985 GAUSS>::OpBrokenSpaceConstrainDFlux<SPACE_DIM>;
2986 op_loop_skeleton_side->getOpPtrVector().push_back(
new OpC_dHybrid(
2987 hybridSpatialDisp, broken_data_ptr, boost::make_shared<double>(1.0)));
2988 auto hybrid_ptr = boost::make_shared<MatrixDouble>();
2989 op_loop_skeleton_side->getOpPtrVector().push_back(
2992 op_loop_skeleton_side->getOpPtrVector().push_back(
new OpC_dBroken(
2993 broken_data_ptr, hybrid_ptr, boost::make_shared<double>(1.0)));
2996 pip.push_back(op_loop_skeleton_side);
3001 auto set_tau_stabilsation_rhs = [&](
auto &pip,
auto side_fe_name,
3002 auto hybrid_field) {
3009 using SideEleOp = EleOnSide::UserDataOperator;
3010 using BdyEleOp = BoundaryEle::UserDataOperator;
3015 mField, side_fe_name,
SPACE_DIM - 1, Sev::noisy);
3017 op_loop_skeleton_side->getSideFEPtr()->getRuleHook = [](int, int, int) {
3020 op_loop_skeleton_side->getSideFEPtr()->setRuleHook =
3021 SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
3022 CHKERR EshelbianPlasticity::
3023 AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
3024 op_loop_skeleton_side->getOpPtrVector(), {L2},
3025 materialH1Positions, frontAdjEdges);
3028 mField, elementVolumeName,
SPACE_DIM, Sev::noisy);
3029 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
3030 boost::make_shared<CGGUserPolynomialBase>();
3032 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
3033 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
3034 materialH1Positions, frontAdjEdges);
3037 auto broken_disp_data_ptr =
3038 boost::make_shared<std::vector<BrokenBaseSideData>>();
3039 op_loop_domain_side->getOpPtrVector().push_back(
3041 broken_disp_data_ptr));
3042 auto disp_mat_ptr = boost::make_shared<MatrixDouble>();
3043 if (stab_tau_dot_variant) {
3044 op_loop_domain_side->getOpPtrVector().push_back(
3048 op_loop_domain_side->getOpPtrVector().push_back(
3053 op_loop_domain_side->getOpPtrVector().push_back(
3056 op_loop_skeleton_side->getOpPtrVector().push_back(op_loop_domain_side);
3057 op_loop_skeleton_side->getOpPtrVector().push_back(set_scale_op);
3060 auto hybrid_ptr = boost::make_shared<MatrixDouble>();
3061 if (stab_tau_dot_variant) {
3062 op_loop_skeleton_side->getOpPtrVector().push_back(
3066 op_loop_skeleton_side->getOpPtrVector().push_back(
3072 op_loop_skeleton_side->getOpPtrVector().push_back(
3074 hybrid_field, hybrid_ptr,
3075 [local_tau_sacale, broken_disp_data_ptr](
double,
double,
double) {
3076 return broken_disp_data_ptr->size() * (*local_tau_sacale);
3079 op_loop_skeleton_side->getOpPtrVector().push_back(
3081 broken_disp_data_ptr, [local_tau_sacale](
double,
double,
double) {
3082 return (*local_tau_sacale);
3085 op_loop_skeleton_side->getOpPtrVector().push_back(
3087 hybrid_field, broken_disp_data_ptr,
3088 [local_tau_sacale](
double,
double,
double) {
3089 return -(*local_tau_sacale);
3092 op_loop_skeleton_side->getOpPtrVector().push_back(
3094 broken_disp_data_ptr, hybrid_ptr,
3095 [local_tau_sacale](
double,
double,
double) {
3096 return -(*local_tau_sacale);
3100 pip.push_back(op_loop_skeleton_side);
3105 auto set_contact_rhs = [&](
auto &pip) {
3109 auto set_cohesive_rhs = [&](
auto &pip) {
3112 SetIntegrationAtFrontFace(frontVertices, frontAdjEdges,
3113 [](
int p) {
return 2 * (p + 1) + 1; }),
3114 interfaceFaces, pip);
3117 CHKERR set_hybridisation_rhs(fe_rhs->getOpPtrVector());
3118 CHKERR set_contact_rhs(fe_rhs->getOpPtrVector());
3119 if (alphaTau > 0.0) {
3120 CHKERR set_tau_stabilsation_rhs(fe_rhs->getOpPtrVector(), skeletonElement,
3122 CHKERR set_tau_stabilsation_rhs(fe_rhs->getOpPtrVector(), contactElement,
3125 if (interfaceCrack == PETSC_TRUE) {
3126 CHKERR set_cohesive_rhs(fe_rhs->getOpPtrVector());
3130 using BodyNaturalBC =
3132 Assembly<PETSC>::LinearForm<
GAUSS>;
3134 BodyNaturalBC::OpFlux<NaturalMeshsetType<BLOCKSET>, 1, 3>;
3136 auto body_time_scale =
3137 boost::make_shared<DynamicRelaxationTimeScale>(
"body_force.txt");
3138 CHKERR BodyNaturalBC::AddFluxToPipeline<OpBodyForce>::add(
3139 fe_rhs->getOpPtrVector(), mField, spatialL2Disp, {body_time_scale},
3140 "BODY_FORCE", Sev::inform);
3144 fe_lhs = boost::make_shared<VolumeElementForcesAndSourcesCore>(mField);
3145 CHKERR setBaseVolumeElementOps(tag,
true,
true,
true, fe_lhs);
3151 fe_lhs->getOpPtrVector().push_back(
3154 bubbleField, piolaStress, dataAtPts));
3155 fe_lhs->getOpPtrVector().push_back(
3159 fe_lhs->getOpPtrVector().push_back(
3160 physicalEquations->returnOpSpatialPhysical_du_du(
3161 stretchTensor, stretchTensor, dataAtPts, alphaU));
3163 stretchTensor, piolaStress, dataAtPts,
true));
3165 stretchTensor, bubbleField, dataAtPts,
true));
3167 stretchTensor, rotAxis, dataAtPts,
3168 symmetrySelector ==
SYMMETRIC ?
true :
false));
3172 spatialL2Disp, piolaStress, dataAtPts,
true));
3174 spatialL2Disp, spatialL2Disp, dataAtPts, alphaW, alphaRho));
3177 piolaStress, rotAxis, dataAtPts,
3178 symmetrySelector ==
SYMMETRIC ?
true :
false));
3180 bubbleField, rotAxis, dataAtPts,
3181 symmetrySelector ==
SYMMETRIC ?
true :
false));
3186 rotAxis, stretchTensor, dataAtPts,
false));
3189 rotAxis, piolaStress, dataAtPts,
false));
3191 rotAxis, bubbleField, dataAtPts,
false));
3194 rotAxis, rotAxis, dataAtPts, alphaOmega));
3196 auto set_hybridisation_lhs = [&](
auto &pip) {
3203 using SideEleOp = EleOnSide::UserDataOperator;
3204 using BdyEleOp = BoundaryEle::UserDataOperator;
3209 mField, skeletonElement,
SPACE_DIM - 1, Sev::noisy);
3210 op_loop_skeleton_side->getSideFEPtr()->getRuleHook = [](int, int, int) {
3213 op_loop_skeleton_side->getSideFEPtr()->setRuleHook =
3214 SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
3215 CHKERR EshelbianPlasticity::
3216 AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
3217 op_loop_skeleton_side->getOpPtrVector(), {L2},
3218 materialH1Positions, frontAdjEdges);
3222 auto broken_data_ptr =
3223 boost::make_shared<std::vector<BrokenBaseSideData>>();
3226 mField, elementVolumeName,
SPACE_DIM, Sev::noisy);
3227 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
3228 boost::make_shared<CGGUserPolynomialBase>();
3230 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
3231 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
3232 materialH1Positions, frontAdjEdges);
3233 op_loop_domain_side->getOpPtrVector().push_back(
3236 op_loop_skeleton_side->getOpPtrVector().push_back(op_loop_domain_side);
3238 GAUSS>::OpBrokenSpaceConstrain<SPACE_DIM>;
3239 op_loop_skeleton_side->getOpPtrVector().push_back(
3240 new OpC(hybridSpatialDisp, broken_data_ptr,
3241 boost::make_shared<double>(1.0),
true,
false));
3243 pip.push_back(op_loop_skeleton_side);
3248 auto set_tau_stabilsation_lhs = [&](
auto &pip,
auto side_fe_name,
3249 auto hybrid_field) {
3256 using SideEleOp = EleOnSide::UserDataOperator;
3257 using BdyEleOp = BoundaryEle::UserDataOperator;
3262 mField, side_fe_name,
SPACE_DIM - 1, Sev::noisy);
3263 op_loop_skeleton_side->getSideFEPtr()->getRuleHook = [](int, int, int) {
3266 op_loop_skeleton_side->getSideFEPtr()->setRuleHook =
3267 SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
3268 CHKERR EshelbianPlasticity::
3269 AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
3270 op_loop_skeleton_side->getOpPtrVector(), {L2},
3271 materialH1Positions, frontAdjEdges);
3275 mField, elementVolumeName,
SPACE_DIM, Sev::noisy);
3276 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
3277 boost::make_shared<CGGUserPolynomialBase>();
3279 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
3280 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
3281 materialH1Positions, frontAdjEdges);
3283 auto broken_disp_data_ptr =
3284 boost::make_shared<std::vector<BrokenBaseSideData>>();
3285 op_loop_domain_side->getOpPtrVector().push_back(
3287 broken_disp_data_ptr));
3288 op_loop_skeleton_side->getOpPtrVector().push_back(op_loop_domain_side);
3289 op_loop_skeleton_side->getOpPtrVector().push_back(set_scale_op);
3291 auto time_shift = [](
const FEMethod *fe_ptr) {
return fe_ptr->ts_a; };
3295 hybrid_field, hybrid_field,
3296 [local_tau_sacale, broken_disp_data_ptr](
double,
double,
double) {
3297 return broken_disp_data_ptr->size() * (*local_tau_sacale);
3299 if (stab_tau_dot_variant) {
3301 op_loop_skeleton_side->getOpPtrVector().back())
3302 .feScalingFun = time_shift;
3305 op_loop_skeleton_side->getOpPtrVector().push_back(
3307 broken_disp_data_ptr, [local_tau_sacale](
double,
double,
double) {
3308 return (*local_tau_sacale);
3310 if (stab_tau_dot_variant) {
3312 op_loop_skeleton_side->getOpPtrVector().back())
3313 .feScalingFun = time_shift;
3316 op_loop_skeleton_side->getOpPtrVector().push_back(
3318 hybrid_field, broken_disp_data_ptr,
3319 [local_tau_sacale](
double,
double,
double) {
3320 return -(*local_tau_sacale);
3323 if (stab_tau_dot_variant) {
3325 op_loop_skeleton_side->getOpPtrVector().back())
3326 .feScalingFun = time_shift;
3330 op_loop_skeleton_side->getOpPtrVector().push_back(
3332 hybrid_field, broken_disp_data_ptr,
3333 [local_tau_sacale](
double,
double,
double) {
3334 return -(*local_tau_sacale);
3337 if (stab_tau_dot_variant) {
3339 op_loop_skeleton_side->getOpPtrVector().back())
3340 .feScalingFun = time_shift;
3343 pip.push_back(op_loop_skeleton_side);
3348 auto set_contact_lhs = [&](
auto &pip) {
3352 auto set_cohesive_lhs = [&](
auto &pip) {
3355 SetIntegrationAtFrontFace(frontVertices, frontAdjEdges,
3356 [](
int p) {
return 2 * (p + 1) + 1; }),
3357 interfaceFaces, pip);
3360 CHKERR set_hybridisation_lhs(fe_lhs->getOpPtrVector());
3361 CHKERR set_contact_lhs(fe_lhs->getOpPtrVector());
3362 if (alphaTau > 0.0) {
3363 CHKERR set_tau_stabilsation_lhs(fe_lhs->getOpPtrVector(), skeletonElement,
3365 CHKERR set_tau_stabilsation_lhs(fe_lhs->getOpPtrVector(), contactElement,
3368 if (interfaceCrack == PETSC_TRUE) {
3369 CHKERR set_cohesive_lhs(fe_lhs->getOpPtrVector());
3380 const bool add_elastic,
const bool add_material,
3381 boost::shared_ptr<FaceElementForcesAndSourcesCore> &fe_rhs,
3382 boost::shared_ptr<FaceElementForcesAndSourcesCore> &fe_lhs) {
3385 fe_rhs = boost::make_shared<FaceElementForcesAndSourcesCore>(mField);
3386 fe_lhs = boost::make_shared<FaceElementForcesAndSourcesCore>(mField);
3391 fe_rhs->getRuleHook = [](int, int, int) {
return -1; };
3392 fe_lhs->getRuleHook = [](int, int, int) {
return -1; };
3393 fe_rhs->setRuleHook = SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
3394 fe_lhs->setRuleHook = SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
3397 EshelbianPlasticity::AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
3398 fe_rhs->getOpPtrVector(), {L2}, materialH1Positions, frontAdjEdges);
3400 EshelbianPlasticity::AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
3401 fe_lhs->getOpPtrVector(), {L2}, materialH1Positions, frontAdjEdges);
3405 auto get_broken_op_side = [
this](
auto &pip) {
3408 using SideEleOp = EleOnSide::UserDataOperator;
3410 auto broken_data_ptr =
3411 boost::make_shared<std::vector<BrokenBaseSideData>>();
3414 mField, elementVolumeName,
SPACE_DIM, Sev::noisy);
3415 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
3416 boost::make_shared<CGGUserPolynomialBase>();
3418 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
3419 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
3420 materialH1Positions, frontAdjEdges);
3421 op_loop_domain_side->getOpPtrVector().push_back(
3423 boost::shared_ptr<double> piola_scale_ptr(
new double);
3424 op_loop_domain_side->getOpPtrVector().push_back(
3425 physicalEquations->returnOpSetScale(piola_scale_ptr,
3426 physicalEquations));
3427 auto flux_mat_ptr = boost::make_shared<MatrixDouble>();
3428 op_loop_domain_side->getOpPtrVector().push_back(
3431 op_loop_domain_side->getOpPtrVector().push_back(
3433 pip.push_back(op_loop_domain_side);
3434 return std::make_tuple(broken_data_ptr, piola_scale_ptr);
3437 auto set_rhs = [&]() {
3440 auto [broken_data_ptr, piola_scale_ptr] =
3441 get_broken_op_side(fe_rhs->getOpPtrVector());
3443 fe_rhs->getOpPtrVector().push_back(
3444 new OpDispBc(broken_data_ptr, bcSpatialDispVecPtr, timeScaleMap));
3446 broken_data_ptr, bcSpatialAnalyticalDisplacementVecPtr,
3449 broken_data_ptr, bcSpatialRotationVecPtr, timeScaleMap));
3451 fe_rhs->getOpPtrVector().push_back(
3453 piola_scale_ptr, timeScaleMap));
3454 auto hybrid_grad_ptr = boost::make_shared<MatrixDouble>();
3456 fe_rhs->getOpPtrVector().push_back(
3458 hybridSpatialDisp, hybrid_grad_ptr));
3460 hybridSpatialDisp, bcSpatialPressureVecPtr, piola_scale_ptr,
3461 hybrid_grad_ptr, timeScaleMap));
3463 hybridSpatialDisp, bcSpatialAnalyticalTractionVecPtr, piola_scale_ptr,
3466 auto hybrid_ptr = boost::make_shared<MatrixDouble>();
3467 fe_rhs->getOpPtrVector().push_back(
3471 hybridSpatialDisp, hybrid_ptr, broken_data_ptr,
3472 bcSpatialNormalDisplacementVecPtr, timeScaleMap));
3474 auto get_normal_disp_bc_faces = [&]() {
3477 return boost::make_shared<Range>(faces);
3482 using BdyEleOp = BoundaryEle::UserDataOperator;
3484 GAUSS>::OpBrokenSpaceConstrainDFlux<SPACE_DIM>;
3485 fe_rhs->getOpPtrVector().push_back(
new OpC_dBroken(
3486 broken_data_ptr, hybrid_ptr, boost::make_shared<double>(1.0),
3487 get_normal_disp_bc_faces()));
3492 auto set_lhs = [&]() {
3495 auto [broken_data_ptr, piola_scale_ptr] =
3496 get_broken_op_side(fe_lhs->getOpPtrVector());
3499 hybridSpatialDisp, bcSpatialNormalDisplacementVecPtr, timeScaleMap));
3501 hybridSpatialDisp, broken_data_ptr, bcSpatialNormalDisplacementVecPtr,
3504 auto hybrid_grad_ptr = boost::make_shared<MatrixDouble>();
3506 fe_lhs->getOpPtrVector().push_back(
3508 hybridSpatialDisp, hybrid_grad_ptr));
3510 hybridSpatialDisp, bcSpatialPressureVecPtr, hybrid_grad_ptr,
3513 auto get_normal_disp_bc_faces = [&]() {
3516 return boost::make_shared<Range>(faces);
3521 using BdyEleOp = BoundaryEle::UserDataOperator;
3523 GAUSS>::OpBrokenSpaceConstrain<SPACE_DIM>;
3524 fe_lhs->getOpPtrVector().push_back(
new OpC(
3525 hybridSpatialDisp, broken_data_ptr, boost::make_shared<double>(1.0),
3526 true,
true, get_normal_disp_bc_faces()));
3539 const bool add_elastic,
const bool add_material,
3540 boost::shared_ptr<FaceElementForcesAndSourcesCore> &fe_rhs,
3541 boost::shared_ptr<FaceElementForcesAndSourcesCore> &fe_lhs) {
3548 boost::shared_ptr<ForcesAndSourcesCore> &fe_contact_tree
3561 CHKERR setContactElementRhsOps(contactTreeRhs);
3563 CHKERR setVolumeElementOps(tag,
true,
false, elasticFeRhs, elasticFeLhs);
3564 CHKERR setFaceElementOps(
true,
false, elasticBcRhs, elasticBcLhs);
3567 boost::make_shared<ForcesAndSourcesCore::UserDataOperator::AdjCache>();
3569 auto get_op_contact_bc = [&]() {
3572 mField, contactElement,
SPACE_DIM - 1, Sev::noisy, adj_cache);
3573 return op_loop_side;
3581 boost::shared_ptr<FEMethod> null;
3583 if (std::abs(alphaRho) > std::numeric_limits<double>::epsilon()) {
3615 bool set_ts_monitor) {
3617#ifdef ENABLE_PYTHON_BINDING
3621 auto setup_ts_monitor = [&]() {
3622 boost::shared_ptr<TsCtx>
ts_ctx;
3625 if (set_ts_monitor) {
3629 auto monitor_ptr = boost::make_shared<EshelbianMonitor>(*ep_ptr);
3633 MOFEM_LOG(
"EP", Sev::inform) <<
"TS monitor setup";
3634 return std::make_tuple(
ts_ctx);
3637 auto setup_snes_monitor = [&]() {
3640 CHKERR TSGetSNES(ts, &snes);
3642 CHKERR SNESMonitorSet(snes,
3645 (
void *)(snes_ctx.get()), PETSC_NULLPTR);
3646 MOFEM_LOG(
"EP", Sev::inform) <<
"SNES monitor setup";
3650 auto setup_snes_conergence_test = [&]() {
3653 auto snes_convergence_test = [](SNES snes, PetscInt it, PetscReal xnorm,
3654 PetscReal snorm, PetscReal fnorm,
3655 SNESConvergedReason *reason,
void *cctx) {
3658 CHKERR SNESConvergedDefault(snes, it, xnorm, snorm, fnorm, reason,
3662 CHKERR SNESGetSolutionUpdate(snes, &x_update);
3663 CHKERR SNESGetFunction(snes, &r, PETSC_NULLPTR, PETSC_NULLPTR);
3676 auto setup_section = [&]() {
3677 PetscSection section_raw;
3683 for (
int ff = 0; ff != num_fields; ff++) {
3686 PetscSectionGetFieldName(section_raw, ff, &
field_name),
3693 auto set_vector_on_mesh = [&]() {
3697 CHKERR VecGhostUpdateBegin(x, INSERT_VALUES, SCATTER_FORWARD);
3698 CHKERR VecGhostUpdateEnd(x, INSERT_VALUES, SCATTER_FORWARD);
3699 MOFEM_LOG(
"EP", Sev::inform) <<
"Vector set on mesh";
3703 auto setup_schur_block_solver = [&]() {
3704 MOFEM_LOG(
"EP", Sev::inform) <<
"Setting up Schur block solver";
3706 "append options prefix");
3710 boost::shared_ptr<EshelbianCore::SetUpSchur> schur_ptr;
3711 if constexpr (
A == AssemblyType::BLOCK_MAT) {
3716 MOFEM_LOG(
"EP", Sev::inform) <<
"Setting up Schur block solver done";
3723#ifdef ENABLE_PYTHON_BINDING
3724 return std::make_tuple(setup_sdf(), setup_ts_monitor(),
3725 setup_snes_monitor(), setup_snes_conergence_test(),
3726 setup_section(), set_vector_on_mesh(),
3727 setup_schur_block_solver());
3729 return std::make_tuple(setup_ts_monitor(), setup_snes_monitor(),
3730 setup_snes_conergence_test(), setup_section(),
3731 set_vector_on_mesh(), setup_schur_block_solver());
3739 PetscBool debug_model = PETSC_FALSE;
3743 <<
"Debug model flag is " << (debug_model ?
"ON" :
"OFF");
3745 if (debug_model == PETSC_TRUE) {
3747 auto post_proc = [&](TS ts, PetscReal
t, Vec u, Vec u_t, Vec u_tt, Vec
F,
3752 CHKERR TSGetSNES(ts, &snes);
3754 CHKERR SNESGetIterationNumber(snes, &it);
3755 std::string file_name =
"snes_iteration_" + std::to_string(it) +
".h5m";
3756 CHKERR postProcessResults(1, file_name,
F, u_t);
3757 std::string file_skel_name =
3758 "snes_iteration_skel_" + std::to_string(it) +
".h5m";
3760 auto get_material_force_tag = [&]() {
3761 auto &moab = mField.get_moab();
3768 CHKERR calculateFaceMaterialForce(1, ts);
3769 CHKERR postProcessSkeletonResults(1, file_skel_name,
F,
3770 {get_material_force_tag()});
3774 ts_ctx_ptr->tsDebugHook = post_proc;
3783 CHKERR addDebugModel(ts);
3787 if (std::abs(alphaRho) > std::numeric_limits<double>::epsilon()) {
3789 CHKERR VecDuplicate(x, &xx);
3790 CHKERR VecZeroEntries(xx);
3791 CHKERR TS2SetSolution(ts, x, xx);
3794 CHKERR TSSetSolution(ts, x);
3797 TetPolynomialBase::switchCacheBaseOn<HDIV>(
3798 {elasticFeLhs.get(), elasticFeRhs.get()});
3803 CHKERR TSSolve(ts, PETSC_NULLPTR);
3805 TetPolynomialBase::switchCacheBaseOff<HDIV>(
3806 {elasticFeLhs.get(), elasticFeRhs.get()});
3810 if (mField.get_comm_rank() == 0) {
3813 "solve_elastic_graph.dot");
3818 CHKERR TSGetSNES(ts, &snes);
3819 int lin_solver_iterations;
3820 CHKERR SNESGetLinearSolveIterations(snes, &lin_solver_iterations);
3822 <<
"Number of linear solver iterations " << lin_solver_iterations;
3824 PetscBool test_cook_flg = PETSC_FALSE;
3827 if (test_cook_flg) {
3828 constexpr int expected_lin_solver_iterations = 11;
3829 if (lin_solver_iterations > expected_lin_solver_iterations)
3832 "Expected number of iterations is different than expected %d > %d",
3833 lin_solver_iterations, expected_lin_solver_iterations);
3836 PetscBool test_sslv116_flag = PETSC_FALSE;
3838 &test_sslv116_flag, PETSC_NULLPTR);
3840 if (test_sslv116_flag) {
3841 double max_val = 0.0;
3842 double min_val = 0.0;
3843 auto field_min_max = [&](boost::shared_ptr<FieldEntity> ent_ptr) {
3845 auto ent_type = ent_ptr->getEntType();
3846 if (ent_type == MBVERTEX) {
3847 max_val = std::max(ent_ptr->getEntFieldData()[
SPACE_DIM - 1], max_val);
3848 min_val = std::min(ent_ptr->getEntFieldData()[
SPACE_DIM - 1], min_val);
3853 field_min_max, spatialH1Disp);
3855 double global_max_val = 0.0;
3856 double global_min_val = 0.0;
3857 MPI_Allreduce(&max_val, &global_max_val, 1, MPI_DOUBLE, MPI_MAX,
3859 MPI_Allreduce(&min_val, &global_min_val, 1, MPI_DOUBLE, MPI_MIN,
3862 <<
"Max " << spatialH1Disp <<
" value: " << global_max_val;
3864 <<
"Min " << spatialH1Disp <<
" value: " << global_min_val;
3866 double ref_max_val = 0.00767;
3867 double ref_min_val = -0.00329;
3868 if (std::abs(global_max_val - ref_max_val) > 1e-5) {
3870 "Incorrect max value of the displacement field: %f != %f",
3871 global_max_val, ref_max_val);
3873 if (std::abs(global_min_val - ref_min_val) > 4e-5) {
3875 "Incorrect min value of the displacement field: %f != %f",
3876 global_min_val, ref_min_val);
3887 double start_time) {
3892 double final_time = 1;
3893 double delta_time = 0.1;
3895 PetscBool ts_h1_update = PETSC_FALSE;
3897 PetscOptionsBegin(PETSC_COMM_WORLD,
"",
"Dynamic Relaxation Options",
"none");
3899 CHKERR PetscOptionsScalar(
"-dynamic_final_time",
3900 "dynamic relaxation final time",
"", final_time,
3901 &final_time, PETSC_NULLPTR);
3902 CHKERR PetscOptionsScalar(
"-dynamic_delta_time",
3903 "dynamic relaxation final time",
"", delta_time,
3904 &delta_time, PETSC_NULLPTR);
3905 CHKERR PetscOptionsInt(
"-dynamic_max_it",
"dynamic relaxation iterations",
"",
3906 max_it, &max_it, PETSC_NULLPTR);
3907 CHKERR PetscOptionsBool(
"-dynamic_h1_update",
"update each ts step",
"",
3908 ts_h1_update, &ts_h1_update, PETSC_NULLPTR);
3913 <<
"Dynamic relaxation final time -dynamic_final_time = " << final_time;
3915 <<
"Dynamic relaxation delta time -dynamic_delta_time = " << delta_time;
3917 <<
"Dynamic relaxation max iterations -dynamic_max_it = " << max_it;
3919 <<
"Dynamic relaxation H1 update each step -dynamic_h1_update = "
3920 << (ts_h1_update ?
"TRUE" :
"FALSE");
3922 CHKERR addDebugModel(ts);
3924 auto setup_ts_monitor = [&]() {
3925 auto monitor_ptr = boost::make_shared<EshelbianMonitor>(*
this);
3928 auto monitor_ptr = setup_ts_monitor();
3930 TetPolynomialBase::switchCacheBaseOn<HDIV>(
3931 {elasticFeLhs.get(), elasticFeRhs.get()});
3935 double ts_delta_time;
3936 CHKERR TSGetTimeStep(ts, &ts_delta_time);
3946 dynamicTime = start_time;
3947 dynamicStep = start_step;
3948 monitor_ptr->ts_u = PETSC_NULLPTR;
3949 monitor_ptr->ts_t = dynamicTime;
3950 monitor_ptr->ts_step = dynamicStep;
3953 for (; dynamicTime < final_time; dynamicTime += delta_time) {
3954 MOFEM_LOG(
"EP", Sev::inform) <<
"Load step " << dynamicStep <<
" Time "
3955 << dynamicTime <<
" delta time " << delta_time;
3957 CHKERR TSSetStepNumber(ts, 0);
3959 CHKERR TSSetTimeStep(ts, ts_delta_time);
3960 if (!ts_h1_update) {
3963 CHKERR TSSetSolution(ts, x);
3964 CHKERR TSSolve(ts, PETSC_NULLPTR);
3965 if (!ts_h1_update) {
3971 CHKERR VecGhostUpdateBegin(x, INSERT_VALUES, SCATTER_FORWARD);
3972 CHKERR VecGhostUpdateEnd(x, INSERT_VALUES, SCATTER_FORWARD);
3974 monitor_ptr->ts_u = x;
3975 monitor_ptr->ts_t = dynamicTime;
3976 monitor_ptr->ts_step = dynamicStep;
3980 if (dynamicStep > max_it)
3985 TetPolynomialBase::switchCacheBaseOff<HDIV>(
3986 {elasticFeLhs.get(), elasticFeRhs.get()});
3994 auto set_block = [&](
auto name,
int dim) {
3995 std::map<int, Range> map;
3996 auto set_tag_impl = [&](
auto name) {
4001 std::regex((boost::format(
"%s(.*)") % name).str())
4004 for (
auto bc : bcs) {
4006 CHKERR bc->getMeshsetIdEntitiesByDimension(mField.get_moab(), dim, r,
4008 map[bc->getMeshsetId()] = r;
4010 <<
"Block " << name <<
" id " << bc->getMeshsetId() <<
" has "
4011 << r.size() <<
" entities";
4016 CHKERR set_tag_impl(name);
4018 return std::make_pair(name, map);
4021 auto set_skin = [&](
auto &&map) {
4022 for (
auto &
m : map.second) {
4026 <<
"Skin for block " << map.first <<
" id " <<
m.first <<
" has "
4027 <<
m.second.size() <<
" entities";
4032 auto set_tag = [&](
auto &&map) {
4034 auto name = map.first;
4035 int def_val[] = {-1};
4037 mField.get_moab().tag_get_handle(name, 1, MB_TYPE_INTEGER,
th,
4038 MB_TAG_SPARSE | MB_TAG_CREAT, def_val),
4040 for (
auto &
m : map.second) {
4048 listTagsToTransfer.push_back(set_tag(set_skin(set_block(
"BODY", 3))));
4049 listTagsToTransfer.push_back(set_tag(set_skin(set_block(
"MAT_ELASTIC", 3))));
4050 listTagsToTransfer.push_back(
4051 set_tag(set_skin(set_block(
"MAT_NEOHOOKEAN", 3))));
4052 listTagsToTransfer.push_back(set_tag(set_block(
"CONTACT", 2)));
4059 Vec f_residual, Vec var_vector,
4060 std::vector<Tag> tags_to_transfer) {
4065 auto get_tag = [&](
auto name,
auto dim) {
4066 auto &mob = mField.get_moab();
4068 double def_val[] = {0., 0., 0.};
4069 CHK_MOAB_THROW(mob.tag_get_handle(name, dim, MB_TYPE_DOUBLE, tag,
4070 MB_TAG_CREAT | MB_TAG_SPARSE, def_val),
4074 tags_to_transfer.push_back(
get_tag(
"MaterialForce", 3));
4078 auto get_crack_tag = [&]() {
4080 rval = mField.get_moab().tag_get_handle(
"CRACK",
th);
4081 if (
rval == MB_SUCCESS) {
4084 int def_val[] = {0};
4086 "CRACK", 1, MB_TYPE_INTEGER,
th, MB_TAG_SPARSE | MB_TAG_CREAT,
4091 Tag th = get_crack_tag();
4092 tags_to_transfer.push_back(
th);
4096 mark_faces.merge(*crackFaces);
4098 mark_faces.merge(*interfaceFaces);
4099 CHKERR mField.get_moab().tag_clear_data(
th, mark_faces, mark);
4103 for (
auto t : listTagsToTransfer) {
4104 tags_to_transfer.push_back(
t);
4114 auto get_post_proc = [&](
auto &post_proc_mesh,
auto sense) {
4116 auto post_proc_ptr =
4117 boost::make_shared<PostProcBrokenMeshInMoabBaseCont<FaceEle>>(
4118 mField, post_proc_mesh);
4119 EshelbianPlasticity::AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
4120 post_proc_ptr->getOpPtrVector(), {L2}, materialH1Positions,
4123 auto domain_ops = [&](
auto &fe,
int sense) {
4125 fe.getUserPolynomialBase() =
4127 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
4128 fe.getOpPtrVector(), {HDIV, H1, L2}, materialH1Positions,
4130 auto piola_scale_ptr = boost::make_shared<double>(1.0);
4131 fe.getOpPtrVector().push_back(physicalEquations->returnOpSetScale(
4132 piola_scale_ptr, physicalEquations));
4134 piolaStress, dataAtPts->getApproxPAtPts(), piola_scale_ptr));
4136 bubbleField, dataAtPts->getApproxPAtPts(), piola_scale_ptr,
4139 fe.getOpPtrVector().push_back(
4140 physicalEquations->returnOpCalculateStretchFromStress(
4141 dataAtPts, physicalEquations));
4143 fe.getOpPtrVector().push_back(
4145 stretchTensor, dataAtPts->getLogStretchTensorAtPts(), MBTET));
4150 piolaStress, dataAtPts->getVarPiolaPts(),
4151 boost::make_shared<double>(1), vec));
4153 bubbleField, dataAtPts->getVarPiolaPts(),
4154 boost::make_shared<double>(1), vec, MBMAXTYPE));
4156 rotAxis, dataAtPts->getVarRotAxisPts(), vec, MBTET));
4158 fe.getOpPtrVector().push_back(
4159 physicalEquations->returnOpCalculateVarStretchFromStress(
4160 dataAtPts, physicalEquations));
4162 fe.getOpPtrVector().push_back(
4164 stretchTensor, dataAtPts->getVarLogStreachPts(), vec, MBTET));
4169 rotAxis, dataAtPts->getRotAxisAtPts(), MBTET));
4171 rotAxis, dataAtPts->getRotAxis0AtPts(), solTSStep, MBTET));
4174 spatialL2Disp, dataAtPts->getSmallWL2AtPts(), MBTET));
4176 spatialH1Disp, dataAtPts->getSmallWH1AtPts()));
4178 spatialH1Disp, dataAtPts->getSmallWGradH1AtPts()));
4180 fe.getOpPtrVector().push_back(
4184 fe.getOpPtrVector().push_back(physicalEquations->returnOpJacobian(
4185 tag,
true,
false, dataAtPts, physicalEquations));
4187 physicalEquations->returnOpCalculateEnergy(dataAtPts,
nullptr)) {
4188 fe.getOpPtrVector().push_back(op);
4197 struct OpSidePPMap :
public OpPPMap {
4198 OpSidePPMap(moab::Interface &post_proc_mesh,
4199 std::vector<EntityHandle> &map_gauss_pts,
4200 DataMapVec data_map_scalar, DataMapMat data_map_vec,
4201 DataMapMat data_map_mat, DataMapMat data_symm_map_mat,
4203 :
OpPPMap(post_proc_mesh, map_gauss_pts, data_map_scalar,
4204 data_map_vec, data_map_mat, data_symm_map_mat),
4211 if (tagSense != 0) {
4212 if (tagSense != OpPPMap::getSkeletonSense())
4225 vec_fields[
"SpatialDisplacementL2"] = dataAtPts->getSmallWL2AtPts();
4226 vec_fields[
"SpatialDisplacementH1"] = dataAtPts->getSmallWH1AtPts();
4227 vec_fields[
"Omega"] = dataAtPts->getRotAxisAtPts();
4228 vec_fields[
"AngularMomentum"] = dataAtPts->getLeviKirchhoffAtPts();
4229 vec_fields[
"X"] = dataAtPts->getLargeXH1AtPts();
4231 vec_fields[
"EiegnLogStreach"] = dataAtPts->getEigenValsAtPts();
4235 vec_fields[
"VarOmega"] = dataAtPts->getVarRotAxisPts();
4236 vec_fields[
"VarSpatialDisplacementL2"] =
4237 boost::make_shared<MatrixDouble>();
4239 spatialL2Disp, vec_fields[
"VarSpatialDisplacementL2"], vec, MBTET));
4243 vec_fields[
"ResSpatialDisplacementL2"] =
4244 boost::make_shared<MatrixDouble>();
4246 spatialL2Disp, vec_fields[
"ResSpatialDisplacementL2"], vec, MBTET));
4247 vec_fields[
"ResOmega"] = boost::make_shared<MatrixDouble>();
4249 rotAxis, vec_fields[
"ResOmega"], vec, MBTET));
4253 mat_fields[
"PiolaStress"] = dataAtPts->getApproxPAtPts();
4255 mat_fields[
"VarPiolaStress"] = dataAtPts->getVarPiolaPts();
4259 mat_fields[
"ResPiolaStress"] = boost::make_shared<MatrixDouble>();
4261 piolaStress, mat_fields[
"ResPiolaStress"],
4262 boost::make_shared<double>(1), vec));
4264 bubbleField, mat_fields[
"ResPiolaStress"],
4265 boost::make_shared<double>(1), vec, MBMAXTYPE));
4267 if (!internalStressTagName.empty()) {
4268 mat_fields[internalStressTagName] = dataAtPts->getInternalStressAtPts();
4269 switch (internalStressInterpOrder) {
4271 fe.getOpPtrVector().push_back(
4275 fe.getOpPtrVector().push_back(
4280 "Unsupported internal stress interpolation order %d",
4281 internalStressInterpOrder);
4286 mat_fields_symm[
"LogSpatialStretch"] =
4287 dataAtPts->getLogStretchTensorAtPts();
4288 mat_fields_symm[
"SpatialStretch"] = dataAtPts->getStretchTensorAtPts();
4290 mat_fields_symm[
"VarLogSpatialStretch"] =
4291 dataAtPts->getVarLogStreachPts();
4296 mat_fields_symm[
"ResLogSpatialStretch"] =
4297 boost::make_shared<MatrixDouble>();
4298 fe.getOpPtrVector().push_back(
4300 stretchTensor, mat_fields_symm[
"ResLogSpatialStretch"], vec,
4305 fe.getOpPtrVector().push_back(
4309 post_proc_ptr->getPostProcMesh(), post_proc_ptr->getMapGaussPts(),
4326 post_proc_ptr->getPostProcMesh(), post_proc_ptr->getMapGaussPts(),
4332 auto X_h1_ptr = boost::make_shared<MatrixDouble>();
4334 post_proc_ptr->getOpPtrVector().push_back(
4336 dataAtPts->getLargeXH1AtPts()));
4341 domain_ops(*(op_loop_side->getSideFEPtr()), sense);
4342 post_proc_ptr->getOpPtrVector().push_back(op_loop_side);
4344 return post_proc_ptr;
4348 auto calcs_side_traction_and_displacements = [&](
auto &post_proc_ptr,
4354 using SideEleOp = EleOnSide::UserDataOperator;
4356 mField, elementVolumeName,
SPACE_DIM, Sev::noisy);
4357 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
4359 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
4360 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
4361 materialH1Positions, frontAdjEdges);
4362 auto traction_ptr = boost::make_shared<MatrixDouble>();
4363 op_loop_domain_side->getOpPtrVector().push_back(
4365 piolaStress, traction_ptr, boost::make_shared<double>(1.0)));
4368 contactDisp, dataAtPts->getContactL2AtPts()));
4369 pip.push_back(op_loop_domain_side);
4371 auto u_h1_ptr = boost::make_shared<MatrixDouble>();
4374 *
this, contactTreeRhs, u_h1_ptr, traction_ptr,
4376 &post_proc_ptr->getPostProcMesh(), &post_proc_ptr->getMapGaussPts()));
4382 pip.push_back(op_this);
4384 op_this->getOpPtrVector().push_back(
4388 post_proc_ptr->getPostProcMesh(), post_proc_ptr->getMapGaussPts(),
4392 {{
"ContactDisplacement", dataAtPts->getContactL2AtPts()}},
4405 auto contact_residual = boost::make_shared<MatrixDouble>();
4406 op_this->getOpPtrVector().push_back(
4408 contactDisp, contact_residual,
4410 op_this->getOpPtrVector().push_back(
4414 post_proc_ptr->getPostProcMesh(), post_proc_ptr->getMapGaussPts(),
4418 {{
"res_contact", contact_residual}},
4432 auto post_proc_mesh = boost::make_shared<moab::Core>();
4433 auto post_proc_ptr = get_post_proc(post_proc_mesh, 1);
4434 auto post_proc_negative_sense_ptr =
4435 get_post_proc(post_proc_mesh, -1);
4436 auto skin_post_proc_ptr = get_post_proc(post_proc_mesh, 1);
4437 CHKERR calcs_side_traction_and_displacements(
4438 skin_post_proc_ptr, skin_post_proc_ptr->getOpPtrVector());
4444 CHKERR mField.get_moab().get_adjacencies(own_tets,
SPACE_DIM - 1,
true,
4445 own_faces, moab::Interface::UNION);
4447 auto get_crack_faces = [&](
auto crack_faces) {
4448 auto get_adj = [&](
auto e,
auto dim) {
4450 CHKERR mField.get_moab().get_adjacencies(e, dim,
true, adj,
4451 moab::Interface::UNION);
4455 auto tets = get_adj(crack_faces, 3);
4457 auto faces = subtract(get_adj(tets, 2), crack_faces);
4459 tets = subtract(tets, get_adj(faces, 3));
4460 return subtract(crack_faces, get_adj(tets, 2));
4463 auto side_one_faces = [&](
auto &faces) {
4464 std::pair<Range, Range> sides;
4465 for (
auto f : faces) {
4467 MOAB_THROW(mField.get_moab().get_adjacencies(&f, 1, 3,
false, adj));
4468 adj = intersect(own_tets, adj);
4469 for (
auto t : adj) {
4470 int side, sense, offset;
4471 MOAB_THROW(mField.get_moab().side_number(
t, f, side, sense, offset));
4473 sides.first.insert(f);
4475 sides.second.insert(f);
4482 auto get_interface_from_block = [&](
auto block_name) {
4486 CHKERR mField.get_moab().get_adjacencies(vol_eles,
SPACE_DIM - 1,
true,
4487 faces, moab::Interface::UNION);
4488 faces = subtract(faces, skin);
4492 auto crack_faces = unite(get_crack_faces(*crackFaces), *interfaceFaces);
4493 crack_faces.merge(get_interface_from_block(
"VOLUME_INTERFACE"));
4494 auto crack_side_faces = side_one_faces(crack_faces);
4495 auto side_one_crack_faces = [crack_side_faces](
FEMethod *fe_method_ptr) {
4496 auto ent = fe_method_ptr->getFEEntityHandle();
4497 if (crack_side_faces.first.find(ent) == crack_side_faces.first.end()) {
4502 auto side_minus_crack_faces = [crack_side_faces](
FEMethod *fe_method_ptr) {
4503 auto ent = fe_method_ptr->getFEEntityHandle();
4504 if (crack_side_faces.second.find(ent) == crack_side_faces.second.end()) {
4510 skin_post_proc_ptr->setTagsToTransfer(tags_to_transfer);
4511 post_proc_ptr->setTagsToTransfer(tags_to_transfer);
4512 post_proc_negative_sense_ptr->setTagsToTransfer(tags_to_transfer);
4514 auto post_proc_begin =
4518 post_proc_ptr->exeTestHook = side_one_crack_faces;
4520 dM, skeletonElement, post_proc_ptr, 0, mField.get_comm_size());
4521 post_proc_negative_sense_ptr->exeTestHook = side_minus_crack_faces;
4523 post_proc_negative_sense_ptr, 0,
4524 mField.get_comm_size());
4526 constexpr bool debug =
false;
4529 auto get_adj_front = [&]() {
4530 auto skeleton_faces = *skeletonFaces;
4532 CHKERR mField.get_moab().get_adjacencies(*frontEdges, 2,
true, adj_front,
4533 moab::Interface::UNION);
4535 adj_front = intersect(adj_front, skeleton_faces);
4536 adj_front = subtract(adj_front, *crackFaces);
4537 adj_front = intersect(own_faces, adj_front);
4542 auto only_front_faces = [adj_front](
FEMethod *fe_method_ptr) {
4543 auto ent = fe_method_ptr->getFEEntityHandle();
4544 if (adj_front.find(ent) == adj_front.end()) {
4550 post_proc_ptr->exeTestHook = only_front_faces;
4552 dM, skeletonElement, post_proc_ptr, 0, mField.get_comm_size());
4553 post_proc_negative_sense_ptr->exeTestHook = only_front_faces;
4555 post_proc_negative_sense_ptr, 0,
4556 mField.get_comm_size());
4561 CHKERR post_proc_end.writeFile(file.c_str());
4568 std::vector<Tag> tags_to_transfer) {
4573 auto post_proc_mesh = boost::make_shared<moab::Core>();
4574 auto post_proc_ptr =
4575 boost::make_shared<PostProcBrokenMeshInMoabBaseCont<FaceEle>>(
4577 EshelbianPlasticity::AddHOOps<SPACE_DIM - 1, SPACE_DIM - 1, SPACE_DIM>::add(
4581 auto hybrid_disp = boost::make_shared<MatrixDouble>();
4582 post_proc_ptr->getOpPtrVector().push_back(
4584 post_proc_ptr->getOpPtrVector().push_back(
4588 auto op_loop_domain_side =
4591 post_proc_ptr->getOpPtrVector().push_back(op_loop_domain_side);
4594 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
4595 boost::make_shared<CGGUserPolynomialBase>();
4596 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
4597 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
4599 op_loop_domain_side->getOpPtrVector().push_back(
4602 op_loop_domain_side->getOpPtrVector().push_back(
4605 op_loop_domain_side->getOpPtrVector().push_back(
4608 op_loop_domain_side->getOpPtrVector().push_back(
4613 op_loop_domain_side->getOpPtrVector().push_back(
4617 op_loop_domain_side->getOpPtrVector().push_back(
4625 vec_fields[
"HybridDisplacement"] = hybrid_disp;
4627 vec_fields[
"spatialL2Disp"] =
dataAtPts->getSmallWL2AtPts();
4628 vec_fields[
"Omega"] =
dataAtPts->getRotAxisAtPts();
4630 mat_fields[
"PiolaStress"] =
dataAtPts->getApproxPAtPts();
4631 mat_fields[
"HybridDisplacementGradient"] =
4634 mat_fields_symm[
"LogSpatialStretch"] =
dataAtPts->getLogStretchTensorAtPts();
4636 post_proc_ptr->getOpPtrVector().push_back(
4640 post_proc_ptr->getPostProcMesh(), post_proc_ptr->getMapGaussPts(),
4655 auto hybrid_res = boost::make_shared<MatrixDouble>();
4656 post_proc_ptr->getOpPtrVector().push_back(
4661 post_proc_ptr->getOpPtrVector().push_back(
4665 post_proc_ptr->getPostProcMesh(), post_proc_ptr->getMapGaussPts(),
4669 {{
"res_hybrid", hybrid_res}},
4680 post_proc_ptr->setTagsToTransfer(tags_to_transfer);
4682 auto post_proc_begin =
4689 CHKERR post_proc_end.writeFile(file.c_str());
4698 auto post_proc_norm_fe =
4699 boost::make_shared<VolumeElementForcesAndSourcesCore>(
mField);
4701 auto post_proc_norm_rule_hook = [](int, int,
int p) ->
int {
4704 post_proc_norm_fe->getRuleHook = post_proc_norm_rule_hook;
4706 post_proc_norm_fe->getUserPolynomialBase() =
4709 CHKERR EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
4713 enum NORMS { U_NORM_L2 = 0, U_NORM_H1, PIOLA_NORM, U_ERROR_L2, LAST_NORM };
4716 CHKERR VecZeroEntries(norms_vec);
4718 auto u_l2_ptr = boost::make_shared<MatrixDouble>();
4719 auto u_h1_ptr = boost::make_shared<MatrixDouble>();
4720 post_proc_norm_fe->getOpPtrVector().push_back(
4722 post_proc_norm_fe->getOpPtrVector().push_back(
4724 post_proc_norm_fe->getOpPtrVector().push_back(
4726 post_proc_norm_fe->getOpPtrVector().push_back(
4728 post_proc_norm_fe->getOpPtrVector().push_back(
4732 auto piola_ptr = boost::make_shared<MatrixDouble>();
4733 post_proc_norm_fe->getOpPtrVector().push_back(
4735 post_proc_norm_fe->getOpPtrVector().push_back(
4739 post_proc_norm_fe->getOpPtrVector().push_back(
4742 TetPolynomialBase::switchCacheBaseOn<HDIV>({post_proc_norm_fe.get()});
4744 *post_proc_norm_fe);
4745 TetPolynomialBase::switchCacheBaseOff<HDIV>({post_proc_norm_fe.get()});
4747 CHKERR VecAssemblyBegin(norms_vec);
4748 CHKERR VecAssemblyEnd(norms_vec);
4749 const double *norms;
4750 CHKERR VecGetArrayRead(norms_vec, &norms);
4751 MOFEM_LOG(
"EP", Sev::inform) <<
"norm_u: " << std::sqrt(norms[U_NORM_L2]);
4752 MOFEM_LOG(
"EP", Sev::inform) <<
"norm_u_h1: " << std::sqrt(norms[U_NORM_H1]);
4754 <<
"norm_error_u_l2: " << std::sqrt(norms[U_ERROR_L2]);
4756 <<
"norm_piola: " << std::sqrt(norms[PIOLA_NORM]);
4757 CHKERR VecRestoreArrayRead(norms_vec, &norms);
4771 for (
auto bc : bc_mng->getBcMapByBlockName()) {
4772 if (
auto disp_bc = bc.second->dispBcPtr) {
4777 <<
"Field name: " <<
field_name <<
" Block name: " << block_name;
4778 MOFEM_LOG(
"EP", Sev::noisy) <<
"Displacement BC: " << *disp_bc;
4780 std::vector<double> block_attributes(6, 0.);
4781 if (disp_bc->data.flag1 == 1) {
4782 block_attributes[0] = disp_bc->data.value1;
4783 block_attributes[3] = 1;
4785 if (disp_bc->data.flag2 == 1) {
4786 block_attributes[1] = disp_bc->data.value2;
4787 block_attributes[4] = 1;
4789 if (disp_bc->data.flag3 == 1) {
4790 block_attributes[2] = disp_bc->data.value3;
4791 block_attributes[5] = 1;
4793 auto faces = bc.second->bcEnts.subset_by_dimension(2);
4801 boost::make_shared<NormalDisplacementBcVec>();
4802 for (
auto bc : bc_mng->getBcMapByBlockName()) {
4803 auto block_name =
"(.*)NORMAL_DISPLACEMENT(.*)";
4804 std::regex reg_name(block_name);
4805 if (std::regex_match(bc.first, reg_name)) {
4809 <<
"Field name: " <<
field_name <<
" Block name: " << block_name;
4811 block_name, bc.second->bcAttributes,
4812 bc.second->bcEnts.subset_by_dimension(2));
4817 boost::make_shared<AnalyticalDisplacementBcVec>();
4819 for (
auto bc : bc_mng->getBcMapByBlockName()) {
4820 auto block_name =
"(.*)ANALYTICAL_DISPLACEMENT(.*)";
4821 std::regex reg_name(block_name);
4822 if (std::regex_match(bc.first, reg_name)) {
4826 <<
"Field name: " <<
field_name <<
" Block name: " << block_name;
4828 block_name, bc.second->bcAttributes,
4829 bc.second->bcEnts.subset_by_dimension(2));
4833 auto ts_displacement =
4834 boost::make_shared<DynamicRelaxationTimeScale>(
"disp_history.txt");
4837 <<
"Add time scaling displacement BC: " << bc.blockName;
4840 ts_displacement,
"disp_history",
".txt", bc.blockName);
4843 auto ts_normal_displacement =
4844 boost::make_shared<DynamicRelaxationTimeScale>(
"normal_disp_history.txt");
4847 <<
"Add time scaling normal displacement BC: " << bc.blockName;
4850 ts_normal_displacement,
"normal_disp_history",
".txt",
4866 for (
auto bc : bc_mng->getBcMapByBlockName()) {
4867 if (
auto force_bc = bc.second->forceBcPtr) {
4872 <<
"Field name: " <<
field_name <<
" Block name: " << block_name;
4873 MOFEM_LOG(
"EP", Sev::noisy) <<
"Force BC: " << *force_bc;
4875 std::vector<double> block_attributes(6, 0.);
4876 block_attributes[0] = -force_bc->data.value3 * force_bc->data.value1;
4877 block_attributes[3] = 1;
4878 block_attributes[1] = -force_bc->data.value4 * force_bc->data.value1;
4879 block_attributes[4] = 1;
4880 block_attributes[2] = -force_bc->data.value5 * force_bc->data.value1;
4881 block_attributes[5] = 1;
4882 auto faces = bc.second->bcEnts.subset_by_dimension(2);
4890 for (
auto bc : bc_mng->getBcMapByBlockName()) {
4891 auto block_name =
"(.*)PRESSURE(.*)";
4892 std::regex reg_name(block_name);
4893 if (std::regex_match(bc.first, reg_name)) {
4898 <<
"Field name: " <<
field_name <<
" Block name: " << block_name;
4900 block_name, bc.second->bcAttributes,
4901 bc.second->bcEnts.subset_by_dimension(2));
4906 boost::make_shared<AnalyticalTractionBcVec>();
4908 for (
auto bc : bc_mng->getBcMapByBlockName()) {
4909 auto block_name =
"(.*)ANALYTICAL_TRACTION(.*)";
4910 std::regex reg_name(block_name);
4911 if (std::regex_match(bc.first, reg_name)) {
4915 <<
"Field name: " <<
field_name <<
" Block name: " << block_name;
4917 block_name, bc.second->bcAttributes,
4918 bc.second->bcEnts.subset_by_dimension(2));
4923 boost::make_shared<DynamicRelaxationTimeScale>(
"traction_history.txt");
4927 ts_traction,
"traction_history",
".txt", bc.blockName);
4931 boost::make_shared<DynamicRelaxationTimeScale>(
"pressure_history.txt");
4935 ts_pressure,
"pressure_history",
".txt", bc.blockName);
4945 &ext_strain_vec_ptr,
4946 const std::string block_name,
4947 const int nb_attributes) {
4950 std::regex((boost::format(
"(.*)%s(.*)") % block_name).str()))) {
4951 std::vector<double> block_attributes;
4952 CHKERR it->getAttributes(block_attributes);
4953 if (block_attributes.size() < nb_attributes) {
4955 "In block %s expected %d attributes, but given %ld",
4956 it->getName().c_str(), nb_attributes, block_attributes.size());
4959 auto get_block_ents = [&]() {
4965 auto Ents = get_block_ents();
4966 ext_strain_vec_ptr->emplace_back(it->getName(), block_attributes,
4976 auto ts_pre_stretch = boost::make_shared<DynamicRelaxationTimeScale>(
4977 "externalstrain_history.txt");
4980 <<
"Add time scaling external strain: " << ext_strain_block.blockName;
4983 ts_pre_stretch,
"externalstrain_history",
".txt",
4984 ext_strain_block.blockName);
4993 auto print_loc_size = [
this](
auto v,
auto str,
auto sev) {
4996 CHKERR VecGetLocalSize(
v.second, &size);
4998 CHKERR VecGetOwnershipRange(
v.second, &low, &high);
4999 MOFEM_LOG(
"EPSYNC", sev) << str <<
" local size " << size <<
" ( " << low
5000 <<
" " << high <<
" ) ";
5023 double start_time) {
5026 auto storage = solve_elastic_setup::setup(
this, ts, x,
false);
5028 auto cohesive_tao_ctx = createCohesiveTAOCtx(
5031 [](
int p) {
return 2 * (p + 1) + 1; }),
5034 double final_time = 1;
5035 double delta_time = 0.1;
5037 PetscBool ts_h1_update = PETSC_FALSE;
5039 PetscOptionsBegin(PETSC_COMM_WORLD,
"",
"Dynamic Relaxation Options",
"none");
5041 CHKERR PetscOptionsScalar(
"-dynamic_final_time",
5042 "dynamic relaxation final time",
"", final_time,
5043 &final_time, PETSC_NULLPTR);
5044 CHKERR PetscOptionsScalar(
"-dynamic_delta_time",
5045 "dynamic relaxation final time",
"", delta_time,
5046 &delta_time, PETSC_NULLPTR);
5047 CHKERR PetscOptionsInt(
"-dynamic_max_it",
"dynamic relaxation iterations",
"",
5048 max_it, &max_it, PETSC_NULLPTR);
5049 CHKERR PetscOptionsBool(
"-dynamic_h1_update",
"update each ts step",
"",
5050 ts_h1_update, &ts_h1_update, PETSC_NULLPTR);
5055 <<
"Dynamic relaxation final time -dynamic_final_time = " << final_time;
5057 <<
"Dynamic relaxation delta time -dynamic_delta_time = " << delta_time;
5059 <<
"Dynamic relaxation max iterations -dynamic_max_it = " << max_it;
5061 <<
"Dynamic relaxation H1 update each step -dynamic_h1_update = "
5062 << (ts_h1_update ?
"TRUE" :
"FALSE");
5064 CHKERR initializeCohesiveKappaField(*
this);
5067 auto setup_ts_monitor = [&]() {
5068 auto monitor_ptr = boost::make_shared<EshelbianMonitor>(*
this);
5071 auto monitor_ptr = setup_ts_monitor();
5073 TetPolynomialBase::switchCacheBaseOn<HDIV>(
5076 CHKERR TSElasticPostStep::postStepInitialise(
this);
5078 double ts_delta_time;
5079 CHKERR TSGetTimeStep(ts, &ts_delta_time);
5082 CHKERR TSSetPreStep(ts, TSElasticPostStep::preStepFun);
5083 CHKERR TSSetPostStep(ts, TSElasticPostStep::postStepFun);
5086 CHKERR TSElasticPostStep::preStepFun(ts);
5087 CHKERR TSElasticPostStep::postStepFun(ts);
5090 CHKERR TaoSetType(tao, TAOLMVM);
5091 auto g = cohesive_tao_ctx->duplicateGradientVec();
5093 cohesiveEvaluateObjectiveAndGradient,
5094 (
void *)cohesive_tao_ctx.get());
5098 monitor_ptr->ts_u = PETSC_NULLPTR;
5103 auto tao_sol0 = cohesive_tao_ctx->duplicateKappaVec();
5104 int tao_sol_size, tao_sol_loc_size;
5105 CHKERR VecGetSize(tao_sol0, &tao_sol_size);
5106 CHKERR VecGetLocalSize(tao_sol0, &tao_sol_loc_size);
5108 <<
"Cohesive crack growth initial kappa vector size " << tao_sol_size
5109 <<
" local size " << tao_sol_loc_size <<
" number of interface faces "
5112 CHKERR TaoSetFromOptions(tao);
5117 CHKERR VecSet(xu, PETSC_INFINITY);
5118 CHKERR TaoSetVariableBounds(tao, xl, xu);
5124 CHKERR VecZeroEntries(tao_sol0);
5125 CHKERR VecGhostUpdateBegin(tao_sol0, INSERT_VALUES, SCATTER_FORWARD);
5126 CHKERR VecGhostUpdateEnd(tao_sol0, INSERT_VALUES, SCATTER_FORWARD);
5127 CHKERR TaoSetSolution(tao, tao_sol0);
5130 CHKERR TaoGetSolution(tao, &tao_sol);
5133 auto &kappa_vec = cohesive_tao_ctx->getKappaVec();
5136 CHKERR VecAXPY(kappa_vec.second, 1.0, tao_sol);
5137 CHKERR VecGhostUpdateBegin(kappa_vec.second, INSERT_VALUES,
5139 CHKERR VecGhostUpdateEnd(kappa_vec.second, INSERT_VALUES, SCATTER_FORWARD);
5146 CHKERR VecGhostUpdateBegin(x, INSERT_VALUES, SCATTER_FORWARD);
5147 CHKERR VecGhostUpdateEnd(x, INSERT_VALUES, SCATTER_FORWARD);
5148 monitor_ptr->ts_u = x;
5158 CHKERR TSElasticPostStep::postStepDestroy();
5159 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_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 DMoFEMMeshToLocalVector(DM dm, Vec l, InsertMode mode, ScatterMode scatter_mode)
set local (or ghosted) vector values on mesh for partition only
PetscErrorCode DMMoFEMAddSubFieldRow(DM dm, const char field_name[])
PetscErrorCode DMMoFEMGetTsCtx(DM dm, MoFEM::TsCtx **ts_ctx)
get MoFEM::TsCtx data structure
PetscErrorCode DMoFEMLoopFiniteElements(DM dm, const char fe_name[], MoFEM::FEMethod *method, CacheTupleWeakPtr cache_ptr=CacheTupleSharedPtr())
Executes FEMethod for finite elements in 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
auto createDMVector(DM dm)
Get smart vector from DM.
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< '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.
MoFEM::OpBrokenTopoBase GAUSS
Gaussian quadrature integration.
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
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
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)
static int internalStressInterpOrder
MoFEMErrorCode projectGeometry(const EntityHandle meshset=0)
boost::shared_ptr< TractionFreeBc > bcSpatialFreeTractionVecPtr
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
static double inv_f_log(const double v)
boost::shared_ptr< VolumeElementForcesAndSourcesCore > elasticFeLhs
static PetscBool noStretch
boost::shared_ptr< ParentFiniteElementAdjacencyFunctionSkeleton< 2 > > parentAdjSkeletonFunctionDim2
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 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
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={})
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
base operator to do operations at Gauss Pt. level
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
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