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;
33 #pragma message "With ENABLE_PYTHON_BINDING"
37 #pragma message "Without ENABLE_PYTHON_BINDING"
65 const EntityType type) {
69 auto dim = CN::Dimension(type);
71 std::vector<int> sendcounts(pcomm->size());
72 std::vector<int> displs(pcomm->size());
73 std::vector<int> sendbuf(r.size());
74 if (pcomm->rank() == 0) {
75 for (
auto p = 1; p != pcomm->size(); p++) {
77 ->getPartEntities(m_field.
get_moab(), p)
80 CHKERR m_field.
get_moab().get_adjacencies(part_ents, dim,
true, faces,
81 moab::Interface::UNION);
82 faces = intersect(faces, r);
83 sendcounts[p] = faces.size();
84 displs[p] = sendbuf.size();
85 for (
auto f : faces) {
87 sendbuf.push_back(
id);
93 MPI_Scatter(sendcounts.data(), 1, MPI_INT, &recv_data, 1, MPI_INT, 0,
95 std::vector<int> recvbuf(recv_data);
96 MPI_Scatterv(sendbuf.data(), sendcounts.data(), displs.data(), MPI_INT,
97 recvbuf.data(), recv_data, MPI_INT, 0, pcomm->comm());
99 if (pcomm->rank() > 0) {
101 for (
auto &f : recvbuf) {
111 const std::string block_name,
int dim) {
117 std::regex((boost::format(
"%s(.*)") % block_name).str())
121 for (
auto bc : bcs) {
133 const std::string block_name,
int dim) {
134 std::map<std::string, Range> r;
139 std::regex((boost::format(
"%s(.*)") % block_name).str())
143 for (
auto bc : bcs) {
148 r[bc->getName()] = faces;
155 const unsigned int cubit_bc_type) {
158 CHKERR mesh_mng->getMeshset(ms_id, cubit_bc_type, meshset);
162static auto save_range(moab::Interface &moab,
const std::string name,
163 const Range r, std::vector<Tag> tags = {}) {
166 CHKERR moab.add_entities(*out_meshset, r);
168 CHKERR moab.write_file(name.c_str(),
"VTK",
"", out_meshset->get_ptr(), 1,
169 tags.data(), tags.size());
171 MOFEM_LOG(
"SELF", Sev::warning) <<
"Empty range for " << name;
178 ParallelComm *pcomm =
181 PSTATUS_SHARED | PSTATUS_MULTISHARED,
182 PSTATUS_NOT, -1, &boundary_ents),
184 return boundary_ents;
189 ParallelComm *pcomm =
191 CHK_MOAB_THROW(pcomm->filter_pstatus(skin, PSTATUS_NOT_OWNED, PSTATUS_NOT, -1,
200 CHK_MOAB_THROW(skin.find_skin(0, body_ents,
false, skin_ents),
"find_skin");
206 ParallelComm *pcomm =
209 Range crack_skin_without_bdy;
210 if (pcomm->rank() == 0) {
212 CHKERR moab.get_adjacencies(crack_faces, 1,
true, crack_edges,
213 moab::Interface::UNION);
214 auto crack_skin =
get_skin(m_field, crack_faces);
218 "get_entities_by_dimension");
219 auto body_skin =
get_skin(m_field, body_ents);
220 Range body_skin_edges;
221 CHK_MOAB_THROW(moab.get_adjacencies(body_skin, 1,
true, body_skin_edges,
222 moab::Interface::UNION),
224 crack_skin_without_bdy = subtract(crack_skin, body_skin_edges);
226 for (
auto &
m : front_edges_map) {
227 auto add_front = subtract(
m.second, crack_edges);
228 auto i = intersect(
m.second, crack_edges);
230 crack_skin_without_bdy.merge(add_front);
234 CHKERR moab.get_adjacencies(i_skin, 1,
true, adj_i_skin,
235 moab::Interface::UNION);
236 adj_i_skin = subtract(intersect(adj_i_skin,
m.second), crack_edges);
237 crack_skin_without_bdy.merge(adj_i_skin);
241 return send_type(m_field, crack_skin_without_bdy, MBEDGE);
247 ParallelComm *pcomm =
250 MOFEM_LOG(
"EP", Sev::noisy) <<
"get_two_sides_of_crack_surface";
252 if (!pcomm->rank()) {
254 auto impl = [&](
auto &saids) {
259 auto get_adj = [&](
auto e,
auto dim) {
262 e, dim,
true, adj, moab::Interface::UNION),
267 auto get_conn = [&](
auto e) {
274 constexpr bool debug =
false;
278 auto body_skin =
get_skin(m_field, body_ents);
279 auto body_skin_edges = get_adj(body_skin, 1);
282 subtract(
get_skin(m_field, crack_faces), body_skin_edges);
283 auto crack_skin_conn = get_conn(crack_skin);
284 auto crack_skin_conn_edges = get_adj(crack_skin_conn, 1);
285 auto crack_edges = get_adj(crack_faces, 1);
286 crack_edges = subtract(crack_edges, crack_skin);
287 auto all_tets = get_adj(crack_edges, 3);
288 crack_edges = subtract(crack_edges, crack_skin_conn_edges);
289 auto crack_conn = get_conn(crack_edges);
290 all_tets.merge(get_adj(crack_conn, 3));
299 if (crack_faces.size()) {
300 auto grow = [&](
auto r) {
301 auto crack_faces_conn = get_conn(crack_faces);
304 while (size_r != r.size() && r.size() > 0) {
306 CHKERR moab.get_connectivity(r,
v,
true);
307 v = subtract(
v, crack_faces_conn);
310 moab::Interface::UNION);
311 r = intersect(r, all_tets);
320 Range all_tets_ord = all_tets;
321 while (all_tets.size()) {
322 Range faces = get_adj(unite(saids.first, saids.second), 2);
323 faces = subtract(crack_faces, faces);
326 auto fit = faces.begin();
327 for (; fit != faces.end(); ++fit) {
328 tets = intersect(get_adj(
Range(*fit, *fit), 3), all_tets);
329 if (tets.size() == 2) {
336 saids.first.insert(tets[0]);
337 saids.first = grow(saids.first);
338 all_tets = subtract(all_tets, saids.first);
339 if (tets.size() == 2) {
340 saids.second.insert(tets[1]);
341 saids.second = grow(saids.second);
342 all_tets = subtract(all_tets, saids.second);
350 saids.first = subtract(all_tets_ord, saids.second);
351 saids.second = subtract(all_tets_ord, saids.first);
357 std::pair<Range, Range> saids;
358 if (crack_faces.size())
363 MOFEM_LOG(
"EP", Sev::noisy) <<
"get_two_sides_of_crack_surface <- done";
365 return std::pair<Range, Range>();
376 boost::shared_ptr<Range> front_nodes,
377 boost::shared_ptr<Range> front_edges,
378 boost::shared_ptr<CGGUserPolynomialBase::CachePhi> cache_phi =
nullptr)
382 boost::shared_ptr<Range> front_nodes,
383 boost::shared_ptr<Range> front_edges,
FunRule fun_rule,
384 boost::shared_ptr<CGGUserPolynomialBase::CachePhi> cache_phi =
nullptr)
389 int order_col,
int order_data) {
392 constexpr bool debug =
false;
394 constexpr int numNodes = 4;
395 constexpr int numEdges = 6;
396 constexpr int refinementLevels = 6;
398 auto &m_field = fe_raw_ptr->
mField;
399 auto fe_ptr =
static_cast<Fe *
>(fe_raw_ptr);
402 auto set_base_quadrature = [&]() {
404 int rule =
funRule(order_data);
415 auto &gauss_pts = fe_ptr->gaussPts;
416 gauss_pts.resize(4, nb_gauss_pts,
false);
417 cblas_dcopy(nb_gauss_pts, &
QUAD_3D_TABLE[rule]->points[1], 4,
418 &gauss_pts(0, 0), 1);
419 cblas_dcopy(nb_gauss_pts, &
QUAD_3D_TABLE[rule]->points[2], 4,
420 &gauss_pts(1, 0), 1);
421 cblas_dcopy(nb_gauss_pts, &
QUAD_3D_TABLE[rule]->points[3], 4,
422 &gauss_pts(2, 0), 1);
424 &gauss_pts(3, 0), 1);
425 auto &data = fe_ptr->dataOnElement[
H1];
426 data->dataOnEntities[MBVERTEX][0].getN(
NOBASE).resize(nb_gauss_pts, 4,
429 &*data->dataOnEntities[MBVERTEX][0].getN(
NOBASE).data().begin();
430 cblas_dcopy(4 * nb_gauss_pts,
QUAD_3D_TABLE[rule]->points, 1, shape_ptr,
439 CHKERR set_base_quadrature();
443 auto get_singular_nodes = [&]() {
446 CHKERR m_field.get_moab().get_connectivity(fe_handle, conn, num_nodes,
448 std::bitset<numNodes> singular_nodes;
449 for (
auto nn = 0; nn != numNodes; ++nn) {
451 singular_nodes.set(nn);
453 singular_nodes.reset(nn);
456 return singular_nodes;
459 auto get_singular_edges = [&]() {
460 std::bitset<numEdges> singular_edges;
461 for (
int ee = 0; ee != numEdges; ee++) {
463 CHKERR m_field.get_moab().side_element(fe_handle, 1, ee, edge);
465 singular_edges.set(ee);
467 singular_edges.reset(ee);
470 return singular_edges;
473 auto set_gauss_pts = [&](
auto &ref_gauss_pts) {
475 fe_ptr->gaussPts.swap(ref_gauss_pts);
476 const size_t nb_gauss_pts = fe_ptr->gaussPts.size2();
477 auto &data = fe_ptr->dataOnElement[
H1];
478 data->dataOnEntities[MBVERTEX][0].getN(
NOBASE).resize(nb_gauss_pts, 4);
480 &*data->dataOnEntities[MBVERTEX][0].getN(
NOBASE).data().begin();
482 &fe_ptr->gaussPts(1, 0), &fe_ptr->gaussPts(2, 0),
487 auto singular_nodes = get_singular_nodes();
488 if (singular_nodes.count()) {
489 auto it_map_ref_coords =
mapRefCoords.find(singular_nodes.to_ulong());
491 CHKERR set_gauss_pts(it_map_ref_coords->second);
495 auto refine_quadrature = [&]() {
498 const int max_level = refinementLevels;
502 double base_coords[] = {0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1};
504 for (
int nn = 0; nn != 4; nn++)
505 CHKERR moab_ref.create_vertex(&base_coords[3 * nn], nodes[nn]);
506 CHKERR moab_ref.create_element(MBTET, nodes, 4, tet);
510 Range tets(tet, tet);
513 tets, 1,
true, edges, moab::Interface::UNION);
518 Range nodes_at_front;
519 for (
int nn = 0; nn != numNodes; nn++) {
520 if (singular_nodes[nn]) {
522 CHKERR moab_ref.side_element(tet, 0, nn, ent);
523 nodes_at_front.insert(ent);
527 auto singular_edges = get_singular_edges();
530 CHKERR moab_ref.create_meshset(MESHSET_SET, meshset);
531 for (
int ee = 0; ee != numEdges; ee++) {
532 if (singular_edges[ee]) {
534 CHKERR moab_ref.side_element(tet, 1, ee, ent);
535 CHKERR moab_ref.add_entities(meshset, &ent, 1);
541 for (
int ll = 0; ll != max_level; ll++) {
544 ->getEntitiesByTypeAndRefLevel(
BitRefLevel().set(ll),
548 CHKERR moab_ref.get_adjacencies(
549 nodes_at_front, 1,
true, ref_edges, moab::Interface::UNION);
550 ref_edges = intersect(ref_edges, edges);
552 CHKERR moab_ref.get_entities_by_type(meshset, MBEDGE, ents,
true);
553 ref_edges = intersect(ref_edges, ents);
556 ->getEntitiesByTypeAndRefLevel(
558 CHKERR m_ref->addVerticesInTheMiddleOfEdges(
562 ->updateMeshsetByEntitiesChildren(meshset,
564 meshset, MBEDGE,
true);
570 ->getEntitiesByTypeAndRefLevel(
BitRefLevel().set(max_level),
580 for (Range::iterator tit = tets.begin(); tit != tets.end();
584 CHKERR moab_ref.get_connectivity(*tit, conn, num_nodes,
false);
585 CHKERR moab_ref.get_coords(conn, num_nodes, &ref_coords(tt, 0));
588 auto &data = fe_ptr->dataOnElement[
H1];
589 const size_t nb_gauss_pts = fe_ptr->gaussPts.size2();
590 MatrixDouble ref_gauss_pts(4, nb_gauss_pts * ref_coords.size1());
592 data->dataOnEntities[MBVERTEX][0].getN(
NOBASE);
594 for (
size_t tt = 0; tt != ref_coords.size1(); tt++) {
595 double *tet_coords = &ref_coords(tt, 0);
598 for (
size_t ggg = 0; ggg != nb_gauss_pts; ++ggg, ++gg) {
599 for (
int dd = 0; dd != 3; dd++) {
600 ref_gauss_pts(dd, gg) =
601 shape_n(ggg, 0) * tet_coords[3 * 0 + dd] +
602 shape_n(ggg, 1) * tet_coords[3 * 1 + dd] +
603 shape_n(ggg, 2) * tet_coords[3 * 2 + dd] +
604 shape_n(ggg, 3) * tet_coords[3 * 3 + dd];
606 ref_gauss_pts(3, gg) = fe_ptr->gaussPts(3, ggg) * det;
610 mapRefCoords[singular_nodes.to_ulong()].swap(ref_gauss_pts);
617 TetPolynomialBase::switchCacheBaseOff<HDIV>({fe_raw_ptr});
618 TetPolynomialBase::switchCacheBaseOn<HDIV>({fe_raw_ptr});
623 CHKERR refine_quadrature();
633 using ForcesAndSourcesCore::dataOnElement;
636 using ForcesAndSourcesCore::ForcesAndSourcesCore;
642 boost::shared_ptr<CGGUserPolynomialBase::CachePhi>
cachePhi;
653 boost::shared_ptr<Range> front_edges)
657 boost::shared_ptr<Range> front_edges,
662 int order_col,
int order_data) {
665 constexpr bool debug =
false;
667 constexpr int numNodes = 3;
668 constexpr int numEdges = 3;
669 constexpr int refinementLevels = 6;
671 auto &m_field = fe_raw_ptr->
mField;
672 auto fe_ptr =
static_cast<Fe *
>(fe_raw_ptr);
675 auto set_base_quadrature = [&]() {
677 int rule =
funRule(order_data);
687 fe_ptr->gaussPts.resize(3, nb_gauss_pts,
false);
688 cblas_dcopy(nb_gauss_pts, &
QUAD_2D_TABLE[rule]->points[1], 3,
689 &fe_ptr->gaussPts(0, 0), 1);
690 cblas_dcopy(nb_gauss_pts, &
QUAD_2D_TABLE[rule]->points[2], 3,
691 &fe_ptr->gaussPts(1, 0), 1);
693 &fe_ptr->gaussPts(2, 0), 1);
694 auto &data = fe_ptr->dataOnElement[
H1];
695 data->dataOnEntities[MBVERTEX][0].getN(
NOBASE).resize(nb_gauss_pts, 3,
698 &*data->dataOnEntities[MBVERTEX][0].getN(
NOBASE).data().begin();
699 cblas_dcopy(3 * nb_gauss_pts,
QUAD_2D_TABLE[rule]->points, 1, shape_ptr,
701 data->dataOnEntities[MBVERTEX][0].getDiffN(
NOBASE).resize(3, 2,
false);
704 data->dataOnEntities[MBVERTEX][0].getDiffN(
NOBASE).data().begin());
713 CHKERR set_base_quadrature();
717 auto get_singular_nodes = [&]() {
720 CHKERR m_field.get_moab().get_connectivity(fe_handle, conn, num_nodes,
722 std::bitset<numNodes> singular_nodes;
723 for (
auto nn = 0; nn != numNodes; ++nn) {
725 singular_nodes.set(nn);
727 singular_nodes.reset(nn);
730 return singular_nodes;
733 auto get_singular_edges = [&]() {
734 std::bitset<numEdges> singular_edges;
735 for (
int ee = 0; ee != numEdges; ee++) {
737 CHKERR m_field.get_moab().side_element(fe_handle, 1, ee, edge);
739 singular_edges.set(ee);
741 singular_edges.reset(ee);
744 return singular_edges;
747 auto set_gauss_pts = [&](
auto &ref_gauss_pts) {
749 fe_ptr->gaussPts.swap(ref_gauss_pts);
750 const size_t nb_gauss_pts = fe_ptr->gaussPts.size2();
751 auto &data = fe_ptr->dataOnElement[
H1];
752 data->dataOnEntities[MBVERTEX][0].getN(
NOBASE).resize(nb_gauss_pts, 4);
754 &*data->dataOnEntities[MBVERTEX][0].getN(
NOBASE).data().begin();
756 &fe_ptr->gaussPts(1, 0), nb_gauss_pts);
760 auto singular_nodes = get_singular_nodes();
761 if (singular_nodes.count()) {
762 auto it_map_ref_coords =
mapRefCoords.find(singular_nodes.to_ulong());
764 CHKERR set_gauss_pts(it_map_ref_coords->second);
768 auto refine_quadrature = [&]() {
771 const int max_level = refinementLevels;
774 double base_coords[] = {0, 0, 0, 1, 0, 0, 0, 1, 0};
776 for (
int nn = 0; nn != numNodes; nn++)
777 CHKERR moab_ref.create_vertex(&base_coords[3 * nn], nodes[nn]);
779 CHKERR moab_ref.create_element(MBTRI, nodes, numNodes, tri);
783 Range tris(tri, tri);
786 tris, 1,
true, edges, moab::Interface::UNION);
791 Range nodes_at_front;
792 for (
int nn = 0; nn != numNodes; nn++) {
793 if (singular_nodes[nn]) {
795 CHKERR moab_ref.side_element(tri, 0, nn, ent);
796 nodes_at_front.insert(ent);
800 auto singular_edges = get_singular_edges();
803 CHKERR moab_ref.create_meshset(MESHSET_SET, meshset);
804 for (
int ee = 0; ee != numEdges; ee++) {
805 if (singular_edges[ee]) {
807 CHKERR moab_ref.side_element(tri, 1, ee, ent);
808 CHKERR moab_ref.add_entities(meshset, &ent, 1);
814 for (
int ll = 0; ll != max_level; ll++) {
817 ->getEntitiesByTypeAndRefLevel(
BitRefLevel().set(ll),
821 CHKERR moab_ref.get_adjacencies(
822 nodes_at_front, 1,
true, ref_edges, moab::Interface::UNION);
823 ref_edges = intersect(ref_edges, edges);
825 CHKERR moab_ref.get_entities_by_type(meshset, MBEDGE, ents,
true);
826 ref_edges = intersect(ref_edges, ents);
829 ->getEntitiesByTypeAndRefLevel(
831 CHKERR m_ref->addVerticesInTheMiddleOfEdges(
835 ->updateMeshsetByEntitiesChildren(meshset,
837 meshset, MBEDGE,
true);
843 ->getEntitiesByTypeAndRefLevel(
BitRefLevel().set(max_level),
854 for (Range::iterator tit = tris.begin(); tit != tris.end();
858 CHKERR moab_ref.get_connectivity(*tit, conn, num_nodes,
false);
859 CHKERR moab_ref.get_coords(conn, num_nodes, &ref_coords(tt, 0));
862 auto &data = fe_ptr->dataOnElement[
H1];
863 const size_t nb_gauss_pts = fe_ptr->gaussPts.size2();
864 MatrixDouble ref_gauss_pts(3, nb_gauss_pts * ref_coords.size1());
866 data->dataOnEntities[MBVERTEX][0].getN(
NOBASE);
868 for (
size_t tt = 0; tt != ref_coords.size1(); tt++) {
869 double *tri_coords = &ref_coords(tt, 0);
872 auto det = t_normal.
l2();
873 for (
size_t ggg = 0; ggg != nb_gauss_pts; ++ggg, ++gg) {
874 for (
int dd = 0; dd != 2; dd++) {
875 ref_gauss_pts(dd, gg) =
876 shape_n(ggg, 0) * tri_coords[3 * 0 + dd] +
877 shape_n(ggg, 1) * tri_coords[3 * 1 + dd] +
878 shape_n(ggg, 2) * tri_coords[3 * 2 + dd];
880 ref_gauss_pts(2, gg) = fe_ptr->gaussPts(2, ggg) * det;
884 mapRefCoords[singular_nodes.to_ulong()].swap(ref_gauss_pts);
890 CHKERR refine_quadrature();
900 using ForcesAndSourcesCore::dataOnElement;
903 using ForcesAndSourcesCore::ForcesAndSourcesCore;
952 const char *list_rots[] = {
"small",
"moderate",
"large",
"no_h1"};
953 const char *list_symm[] = {
"symm",
"not_symm"};
954 const char *list_release[] = {
"griffith_force",
"griffith_skeleton"};
955 const char *list_stretches[] = {
"linear",
"log",
"log_quadratic"};
956 const char *list_solvers[] = {
"time_solver",
"dynamic_relaxation",
962 PetscInt choice_stretch = StretchSelector::LOG;
964 char analytical_expr_file_name[255] =
"analytical_expr.py";
966 PetscOptionsBegin(PETSC_COMM_WORLD,
"",
"Eshelbian plasticity",
"none");
967 CHKERR PetscOptionsInt(
"-space_order",
"approximation oder for space",
"",
969 CHKERR PetscOptionsInt(
"-space_h1_order",
"approximation oder for space",
"",
971 CHKERR PetscOptionsInt(
"-material_order",
"approximation oder for material",
973 CHKERR PetscOptionsScalar(
"-viscosity_alpha_u",
"viscosity",
"",
alphaU,
975 CHKERR PetscOptionsScalar(
"-viscosity_alpha_w",
"viscosity",
"",
alphaW,
977 CHKERR PetscOptionsScalar(
"-viscosity_alpha_omega",
"rot viscosity",
"",
979 CHKERR PetscOptionsScalar(
"-density_alpha_rho",
"density",
"",
alphaRho,
983 CHKERR PetscOptionsEList(
"-rotations",
"rotations",
"", list_rots,
984 LARGE_ROT + 1, list_rots[choice_rot], &choice_rot,
986 CHKERR PetscOptionsEList(
"-grad",
"gradient of defamation approximate",
"",
987 list_rots, NO_H1_CONFIGURATION + 1,
988 list_rots[choice_grad], &choice_grad, PETSC_NULLPTR);
989 CHKERR PetscOptionsEList(
"-symm",
"symmetric variant",
"", list_symm, 2,
990 list_symm[choice_symm], &choice_symm, PETSC_NULLPTR);
994 CHKERR PetscOptionsEList(
"-stretches",
"stretches",
"", list_stretches,
995 StretchSelector::STRETCH_SELECTOR_LAST,
996 list_stretches[choice_stretch], &choice_stretch,
999 CHKERR PetscOptionsBool(
"-no_stretch",
"do not solve for stretch",
"",
1001 CHKERR PetscOptionsBool(
"-set_singularity",
"set singularity",
"",
1003 CHKERR PetscOptionsBool(
"-l2_user_base_scale",
"streach scale",
"",
1009 CHKERR PetscOptionsBool(
"-dynamic_relaxation",
"dynamic time relaxation",
"",
1011 CHKERR PetscOptionsEList(
"-solver_type",
"solver type",
"", list_solvers,
1013 &choice_solver, PETSC_NULLPTR);
1016 CHKERR PetscOptionsInt(
"-contact_max_post_proc_ref_level",
"refinement level",
1020 CHKERR PetscOptionsBool(
"-cohesive_interface_on",
"cohesive interface ON",
"",
1026 CHKERR PetscOptionsScalar(
"-cracking_start_time",
"cracking start time",
"",
1029 CHKERR PetscOptionsScalar(
"-griffith_energy",
"Griffith energy",
"",
1031 CHKERR PetscOptionsEList(
"-energy_release_variant",
"energy release variant",
1032 "", list_release, 2, list_release[choice_release],
1033 &choice_release, PETSC_NULLPTR);
1034 CHKERR PetscOptionsInt(
"-nb_J_integral_levels",
"Number of J integarl levels",
1038 "-nb_J_integral_contours",
"Number of J integral contours",
"",
1042 char tag_name[255] =
"";
1043 CHKERR PetscOptionsString(
"-internal_stress_tag_name",
1044 "internal stress tag name",
"",
"", tag_name, 255,
1048 "-internal_stress_interp_order",
"internal stress interpolation order",
1050 CHKERR PetscOptionsBool(
"-internal_stress_voigt",
"Voigt index notation",
"",
1055 "-analytical_expr_file",
1056 analytical_expr_file_name, 255, PETSC_NULLPTR);
1062 "Unsupported internal stress interpolation order %d",
1075 static_cast<EnergyReleaseSelector
>(choice_release);
1078 case StretchSelector::LINEAR:
1086 case StretchSelector::LOG:
1088 std::numeric_limits<float>::epsilon()) {
1104 case StretchSelector::LOG_QUADRATIC:
1110 "No logarithmic quadratic stretch for this case");
1123 <<
"-dynamic_relaxation option is deprecated, use -solver_type "
1124 "dynamic_relaxation instead.";
1128 switch (choice_solver) {
1150 MOFEM_LOG(
"EP", Sev::inform) <<
"alphaU: -viscosity_alpha_u " <<
alphaU;
1151 MOFEM_LOG(
"EP", Sev::inform) <<
"alphaW: -viscosity_alpha_w " <<
alphaW;
1153 <<
"alphaOmega: -viscosity_alpha_omega " <<
alphaOmega;
1158 MOFEM_LOG(
"EP", Sev::inform) <<
"Gradient of deformation "
1166 MOFEM_LOG(
"EP", Sev::inform) <<
"Base exponent e";
1168 <<
"Stretch: -stretches " << list_stretches[choice_stretch];
1178 <<
"Solver type: -solver_type " << list_solvers[choice_solver];
1196 <<
"Energy release variant: -energy_release_variant "
1199 <<
"Number of J integral contours: -nb_J_integral_contours "
1202 <<
"Cohesive interface on: -cohesive_interface_on "
1207#ifdef ENABLE_PYTHON_BINDING
1208 auto file_exists = [](std::string myfile) {
1209 std::ifstream file(myfile.c_str());
1216 if (file_exists(analytical_expr_file_name)) {
1217 MOFEM_LOG(
"EP", Sev::inform) << analytical_expr_file_name <<
" file found";
1221 analytical_expr_file_name);
1225 << analytical_expr_file_name <<
" file NOT found";
1238 auto get_tets = [&]() {
1244 auto get_tets_skin = [&]() {
1245 Range tets_skin_part;
1247 CHKERR skin.find_skin(0, get_tets(),
false, tets_skin_part);
1248 ParallelComm *pcomm =
1251 CHKERR pcomm->filter_pstatus(tets_skin_part,
1252 PSTATUS_SHARED | PSTATUS_MULTISHARED,
1253 PSTATUS_NOT, -1, &tets_skin);
1257 auto subtract_boundary_conditions = [&](
auto &&tets_skin) {
1263 tets_skin = subtract(tets_skin,
v.faces);
1267 tets_skin = subtract(tets_skin,
v.faces);
1272 tets_skin = subtract(tets_skin,
v.faces);
1278 auto add_blockset = [&](
auto block_name,
auto &&tets_skin) {
1281 tets_skin.merge(crack_faces);
1285 auto subtract_blockset = [&](
auto block_name,
auto &&tets_skin) {
1286 auto contact_range =
1288 tets_skin = subtract(tets_skin, contact_range);
1292 auto get_stress_trace_faces = [&](
auto &&tets_skin) {
1295 faces, moab::Interface::UNION);
1296 Range trace_faces = subtract(faces, tets_skin);
1300 auto tets = get_tets();
1304 auto trace_faces = get_stress_trace_faces(
1306 subtract_blockset(
"CONTACT",
1307 subtract_boundary_conditions(get_tets_skin()))
1314 boost::make_shared<Range>(subtract(trace_faces, *
contactFaces));
1329 auto add_broken_hdiv_field = [
this, meshset](
const std::string
field_name,
1335 auto get_side_map_hdiv = [&]() {
1338 std::pair<EntityType,
1353 get_side_map_hdiv(), MB_TAG_DENSE,
MF_ZERO);
1359 auto add_l2_field = [
this, meshset](
const std::string
field_name,
1360 const int order,
const int dim) {
1369 auto add_h1_field = [
this, meshset](
const std::string
field_name,
1370 const int order,
const int dim) {
1382 auto add_l2_field_by_range = [
this](
const std::string
field_name,
1383 const int order,
const int dim,
1384 const int field_dim,
Range &&r) {
1394 auto add_bubble_field = [
this, meshset](
const std::string
field_name,
1395 const int order,
const int dim) {
1401 auto field_order_table =
1402 const_cast<Field *
>(field_ptr)->getFieldOrderTable();
1403 auto get_cgg_bubble_order_zero = [](
int p) {
return 0; };
1404 auto get_cgg_bubble_order_tet = [](
int p) {
1407 field_order_table[MBVERTEX] = get_cgg_bubble_order_zero;
1408 field_order_table[MBEDGE] = get_cgg_bubble_order_zero;
1409 field_order_table[MBTRI] = get_cgg_bubble_order_zero;
1410 field_order_table[MBTET] = get_cgg_bubble_order_tet;
1417 auto add_user_l2_field = [
this, meshset](
const std::string
field_name,
1418 const int order,
const int dim) {
1424 auto field_order_table =
1425 const_cast<Field *
>(field_ptr)->getFieldOrderTable();
1426 auto zero_dofs = [](
int p) {
return 0; };
1428 field_order_table[MBVERTEX] = zero_dofs;
1429 field_order_table[MBEDGE] = zero_dofs;
1430 field_order_table[MBTRI] = zero_dofs;
1431 field_order_table[MBTET] = dof_l2_tet;
1449 auto get_hybridised_disp = [&]() {
1451 auto skin = subtract_boundary_conditions(get_tets_skin());
1453 faces.merge(intersect(bc.faces, skin));
1459 get_hybridised_disp());
1485 auto project_ho_geometry = [&](
auto field) {
1491 auto get_adj_front_edges = [&](
auto &front_edges) {
1492 Range front_crack_nodes;
1493 Range crack_front_edges_with_both_nodes_not_at_front;
1498 moab.get_connectivity(front_edges, front_crack_nodes,
true),
1499 "get_connectivity failed");
1500 Range crack_front_edges;
1502 false, crack_front_edges,
1503 moab::Interface::UNION),
1504 "get_adjacencies failed");
1505 Range crack_front_edges_nodes;
1507 crack_front_edges_nodes,
true),
1508 "get_connectivity failed");
1510 crack_front_edges_nodes =
1511 subtract(crack_front_edges_nodes, front_crack_nodes);
1512 Range crack_front_edges_with_both_nodes_not_at_front;
1514 moab.get_adjacencies(crack_front_edges_nodes, 1,
false,
1515 crack_front_edges_with_both_nodes_not_at_front,
1516 moab::Interface::UNION),
1517 "get_adjacencies failed");
1519 crack_front_edges_with_both_nodes_not_at_front = intersect(
1520 crack_front_edges, crack_front_edges_with_both_nodes_not_at_front);
1524 crack_front_edges_with_both_nodes_not_at_front =
send_type(
1525 mField, crack_front_edges_with_both_nodes_not_at_front, MBEDGE);
1527 return std::make_pair(boost::make_shared<Range>(front_crack_nodes),
1528 boost::make_shared<Range>(
1529 crack_front_edges_with_both_nodes_not_at_front));
1536 auto [front_vertices, front_adj_edges] = get_adj_front_edges(*
frontEdges);
1541 <<
"Number of crack faces: " <<
crackFaces->size();
1543 <<
"Number of front edges: " <<
frontEdges->size();
1547 <<
"Number of front adjacent edges: " <<
frontAdjEdges->size();
1556 (boost::format(
"crack_faces_%d.vtk") % rank).str(),
1559 (boost::format(
"front_edges_%d.vtk") % rank).str(),
1570 auto set_singular_dofs = [&](
auto &front_adj_edges,
auto &front_vertices) {
1578 MOFEM_LOG(
"EP", Sev::inform) <<
"Singularity eps " << beta;
1583 [&](boost::shared_ptr<FieldEntity> field_entity_ptr) ->
MoFEMErrorCode {
1588 auto nb_dofs = field_entity_ptr->getEntFieldData().size();
1594 if (field_entity_ptr->getNbOfCoeffs() != 3)
1596 "Expected 3 coefficients per edge");
1597 if (nb_dofs % 3 != 0)
1599 "Expected multiple of 3 coefficients per edge");
1602 auto get_conn = [&]() {
1605 CHKERR moab.get_connectivity(field_entity_ptr->getEnt(), conn,
1607 return std::make_pair(conn, num_nodes);
1610 auto get_dir = [&](
auto &&conn_p) {
1611 auto [conn, num_nodes] = conn_p;
1613 CHKERR moab.get_coords(conn, num_nodes, coords);
1615 coords[4] - coords[1],
1616 coords[5] - coords[2]};
1620 auto get_singularity_dof = [&](
auto &&conn_p,
auto &&t_edge_dir) {
1621 auto [conn, num_nodes] = conn_p;
1623 if (front_vertices.find(conn[0]) != front_vertices.end()) {
1624 t_singularity_dof(
i) = t_edge_dir(
i) * (-
eps);
1625 }
else if (front_vertices.find(conn[1]) != front_vertices.end()) {
1626 t_singularity_dof(
i) = t_edge_dir(
i) *
eps;
1628 return t_singularity_dof;
1631 auto t_singularity_dof =
1632 get_singularity_dof(get_conn(), get_dir(get_conn()));
1634 auto field_data = field_entity_ptr->getEntFieldData();
1636 &field_data[0], &field_data[1], &field_data[2]};
1638 t_dof(
i) = t_singularity_dof(
i);
1640 for (
auto n = 1;
n < field_data.size() / 3; ++
n) {
1668#ifdef INCLUDE_MBCOUPLER
1670 char mesh_source_file[255] =
"source.h5m";
1671 char iterp_tag_name[255] =
"INTERNAL_STRESS";
1673 int interp_order = 1;
1674 PetscBool hybrid_interp = PETSC_TRUE;
1675 PetscBool project_internal_stress = PETSC_FALSE;
1677 double toler = 5.e-10;
1678 PetscOptionsBegin(PETSC_COMM_WORLD,
"mesh_transfer_",
"mesh data transfer",
1680 CHKERR PetscOptionsString(
"-source_file",
"source mesh file name",
"",
1681 "source.h5m", mesh_source_file, 255,
1682 &project_internal_stress);
1683 CHKERR PetscOptionsString(
"-interp_tag",
"interpolation tag name",
"",
1684 "INTERNAL_STRESS", iterp_tag_name, 255,
1686 CHKERR PetscOptionsInt(
"-interp_order",
"interpolation order",
"", 0,
1687 &interp_order, PETSC_NULLPTR);
1688 CHKERR PetscOptionsBool(
"-hybrid_interp",
"use hybrid interpolation",
"",
1689 hybrid_interp, &hybrid_interp, PETSC_NULLPTR);
1694 if (!project_internal_stress) {
1696 <<
"No internal stress source mesh specified. Skipping projection of "
1701 <<
"Projecting internal stress from source mesh: " << mesh_source_file;
1707 auto rval_check_tag = moab.tag_get_handle(iterp_tag_name, old_interp_tag);
1708 if (rval_check_tag == MB_SUCCESS) {
1710 <<
"Deleting existing tag on target mesh: " << iterp_tag_name;
1711 CHKERR moab.tag_delete(old_interp_tag);
1715 int world_rank = -1, world_size = -1;
1716 MPI_Comm_rank(PETSC_COMM_WORLD, &world_rank);
1717 MPI_Comm_size(PETSC_COMM_WORLD, &world_size);
1719 Range original_meshset_ents;
1720 CHKERR moab.get_entities_by_handle(0, original_meshset_ents);
1722 MPI_Comm comm_coupler;
1723 if (world_rank == 0) {
1724 MPI_Comm_split(PETSC_COMM_WORLD, 0, 0, &comm_coupler);
1726 MPI_Comm_split(PETSC_COMM_WORLD, MPI_UNDEFINED, world_rank, &comm_coupler);
1730 ParallelComm *pcomm0 =
nullptr;
1732 if (world_rank == 0) {
1733 pcomm0 =
new ParallelComm(&moab, comm_coupler, &pcomm0_id);
1736 Coupler::Method method;
1737 switch (interp_order) {
1739 method = Coupler::CONSTANT;
1742 method = Coupler::LINEAR_FE;
1746 "Unsupported interpolation order");
1750 ierr = MPI_Comm_size(PETSC_COMM_WORLD, &nprocs);
1752 ierr = MPI_Comm_rank(PETSC_COMM_WORLD, &rank);
1764 CHKERR moab.create_meshset(MESHSET_SET, target_root);
1766 <<
"Creating target mesh from existing meshset";
1767 Range target_meshset_ents;
1768 CHKERR moab.get_entities_by_handle(0, target_meshset_ents);
1769 CHKERR moab.add_entities(target_root, target_meshset_ents);
1777 Range targ_verts, targ_elems;
1778 if (world_rank == 0) {
1781 CHKERR moab.create_meshset(MESHSET_SET, source_root);
1783 MOFEM_LOG(
"WORLD", Sev::inform) <<
"Loading source mesh on rank 0";
1784 auto rval_source_mesh = moab.load_file(mesh_source_file, &source_root,
"");
1785 if (rval_source_mesh != MB_SUCCESS) {
1787 <<
"Error loading source mesh file: " << mesh_source_file;
1789 MOFEM_LOG(
"WORLD", Sev::inform) <<
"Source mesh loaded.";
1792 CHKERR moab.get_entities_by_dimension(source_root, 3, src_elems);
1795 CHKERR pcomm0->create_part(part_set);
1796 CHKERR moab.add_entities(part_set, src_elems);
1798 Range src_elems_part;
1799 CHKERR pcomm0->get_part_entities(src_elems_part, 3);
1802 CHKERR moab.tag_get_handle(iterp_tag_name, interp_tag);
1805 CHKERR moab.tag_get_length(interp_tag, interp_tag_len);
1807 if (interp_tag_len != 1 && interp_tag_len != 3 && interp_tag_len != 9) {
1809 "Unsupported interpolation tag length: %d", interp_tag_len);
1813 tag_length = interp_tag_len;
1814 CHKERR moab.tag_get_data_type(interp_tag, dtype);
1815 CHKERR moab.tag_get_type(interp_tag, storage);
1818 Coupler mbc(&moab, pcomm0, src_elems_part, 0,
true);
1820 std::vector<double> vpos;
1826 CHKERR moab.get_entities_by_dimension(target_root, 3, targ_elems);
1828 if (interp_order == 0) {
1829 targ_verts = targ_elems;
1831 CHKERR moab.get_adjacencies(targ_elems, 0,
false, targ_verts,
1832 moab::Interface::UNION);
1836 CHKERR pcomm0->get_pstatus_entities(0, PSTATUS_NOT_OWNED, tmp_verts);
1837 targ_verts = subtract(targ_verts, tmp_verts);
1840 num_pts = (int)targ_verts.size();
1841 vpos.resize(3 * targ_verts.size());
1842 CHKERR moab.get_coords(targ_verts, &vpos[0]);
1845 boost::shared_ptr<TupleList> tl_ptr;
1846 tl_ptr = boost::make_shared<TupleList>();
1847 CHKERR mbc.locate_points(&vpos[0], num_pts, 0, toler, tl_ptr.get(),
false);
1850 auto find_missing_points = [&](
Range &targ_verts,
int &num_pts,
1851 std::vector<double> &vpos,
1852 Range &missing_verts) {
1854 int missing_pts_num = 0;
1856 auto vit = targ_verts.begin();
1857 for (; vit != targ_verts.end();
i++) {
1858 if (tl_ptr->vi_rd[3 *
i + 1] == -1) {
1859 missing_verts.insert(*vit);
1860 vit = targ_verts.erase(vit);
1867 int missing_pts_num_global = 0;
1870 if (missing_pts_num_global) {
1872 << missing_pts_num_global
1873 <<
" points in target mesh were not located in source mesh. ";
1876 if (missing_pts_num) {
1877 num_pts = (int)targ_verts.size();
1878 vpos.resize(3 * targ_verts.size());
1879 CHKERR moab.get_coords(targ_verts, &vpos[0]);
1881 CHKERR mbc.locate_points(&vpos[0], num_pts, 0, toler, tl_ptr.get(),
1887 Range missing_verts;
1888 CHKERR find_missing_points(targ_verts, num_pts, vpos, missing_verts);
1890 std::vector<double> source_data(interp_tag_len * src_elems.size(), 0.0);
1891 std::vector<double> target_data(interp_tag_len * num_pts, 0.0);
1893 CHKERR moab.tag_get_data(interp_tag, src_elems, &source_data[0]);
1895 Tag scalar_tag, adj_count_tag;
1897 string scalar_tag_name = string(iterp_tag_name) +
"_COMP";
1898 CHKERR moab.tag_get_handle(scalar_tag_name.c_str(), 1, MB_TYPE_DOUBLE,
1899 scalar_tag, MB_TAG_CREAT | MB_TAG_DENSE,
1902 string adj_count_tag_name =
"ADJ_COUNT";
1904 CHKERR moab.tag_get_handle(adj_count_tag_name.c_str(), 1, MB_TYPE_DOUBLE,
1905 adj_count_tag, MB_TAG_CREAT | MB_TAG_DENSE,
1910 auto create_scalar_tags = [&](
const Range &src_elems,
1911 const std::vector<double> &source_data,
1915 std::vector<double> source_data_scalar(src_elems.size());
1917 for (
int ielem = 0; ielem < src_elems.size(); ielem++) {
1918 source_data_scalar[ielem] = source_data[itag + ielem * interp_tag_len];
1922 CHKERR moab.tag_set_data(scalar_tag, src_elems, &source_data_scalar[0]);
1924 if (interp_order == 1) {
1927 CHKERR moab.get_connectivity(src_elems, src_verts,
true);
1929 CHKERR moab.tag_clear_data(scalar_tag, src_verts, &def_scl);
1930 CHKERR moab.tag_clear_data(adj_count_tag, src_verts, &def_adj);
1932 for (
auto &tet : src_elems) {
1933 double tet_data = 0;
1934 CHKERR moab.tag_get_data(scalar_tag, &tet, 1, &tet_data);
1937 CHKERR moab.get_connectivity(&tet, 1, adj_verts,
true);
1939 std::vector<double> adj_vert_data(adj_verts.size(), 0.0);
1940 std::vector<double> adj_vert_count(adj_verts.size(), 0.0);
1942 CHKERR moab.tag_get_data(scalar_tag, adj_verts, &adj_vert_data[0]);
1943 CHKERR moab.tag_get_data(adj_count_tag, adj_verts,
1944 &adj_vert_count[0]);
1946 for (
int ivert = 0; ivert < adj_verts.size(); ivert++) {
1947 adj_vert_data[ivert] += tet_data;
1948 adj_vert_count[ivert] += 1;
1951 CHKERR moab.tag_set_data(scalar_tag, adj_verts, &adj_vert_data[0]);
1952 CHKERR moab.tag_set_data(adj_count_tag, adj_verts,
1953 &adj_vert_count[0]);
1957 std::vector<Tag> tags = {scalar_tag, adj_count_tag};
1958 pcomm0->reduce_tags(tags, tags, MPI_SUM, src_verts);
1960 std::vector<double> src_vert_data(src_verts.size(), 0.0);
1961 std::vector<double> src_vert_adj_count(src_verts.size(), 0.0);
1963 CHKERR moab.tag_get_data(scalar_tag, src_verts, &src_vert_data[0]);
1964 CHKERR moab.tag_get_data(adj_count_tag, src_verts,
1965 &src_vert_adj_count[0]);
1967 for (
int ivert = 0; ivert < src_verts.size(); ivert++) {
1968 src_vert_data[ivert] /= src_vert_adj_count[ivert];
1970 CHKERR moab.tag_set_data(scalar_tag, src_verts, &src_vert_data[0]);
1975 for (
int itag = 0; itag < interp_tag_len; itag++) {
1977 CHKERR create_scalar_tags(src_elems, source_data, itag);
1979 std::vector<double> target_data_scalar(num_pts, 0.0);
1980 CHKERR mbc.interpolate(method, scalar_tag_name, &target_data_scalar[0],
1983 for (
int ielem = 0; ielem < num_pts; ielem++) {
1984 target_data[itag + ielem * interp_tag_len] = target_data_scalar[ielem];
1989 CHKERR moab.tag_set_data(interp_tag, targ_verts, &target_data[0]);
1991 if (missing_verts.size() && (interp_order == 1) && hybrid_interp) {
1992 MOFEM_LOG(
"WORLD", Sev::warning) <<
"Using hybrid interpolation for "
1993 "missing points in the target mesh.";
1994 Range missing_adj_elems;
1995 CHKERR moab.get_adjacencies(missing_verts, 3,
false, missing_adj_elems,
1996 moab::Interface::UNION);
1998 int num_adj_elems = (int)missing_adj_elems.size();
1999 std::vector<double> vpos_adj_elems;
2001 vpos_adj_elems.resize(3 * missing_adj_elems.size());
2002 CHKERR moab.get_coords(missing_adj_elems, &vpos_adj_elems[0]);
2006 CHKERR mbc.locate_points(&vpos_adj_elems[0], num_adj_elems, 0, toler,
2007 tl_ptr.get(),
false);
2010 CHKERR find_missing_points(missing_adj_elems, num_adj_elems,
2011 vpos_adj_elems, missing_tets);
2012 if (missing_tets.size()) {
2014 << missing_tets.size()
2015 <<
"points in target mesh were not located in source mesh. ";
2018 std::vector<double> target_data_adj_elems(interp_tag_len * num_adj_elems,
2021 for (
int itag = 0; itag < interp_tag_len; itag++) {
2022 CHKERR create_scalar_tags(src_elems, source_data, itag);
2024 std::vector<double> target_data_adj_elems_scalar(num_adj_elems, 0.0);
2025 CHKERR mbc.interpolate(method, scalar_tag_name,
2026 &target_data_adj_elems_scalar[0], tl_ptr.get());
2028 for (
int ielem = 0; ielem < num_adj_elems; ielem++) {
2029 target_data_adj_elems[itag + ielem * interp_tag_len] =
2030 target_data_adj_elems_scalar[ielem];
2034 CHKERR moab.tag_set_data(interp_tag, missing_adj_elems,
2035 &target_data_adj_elems[0]);
2038 for (
auto &vert : missing_verts) {
2040 CHKERR moab.get_adjacencies(&vert, 1, 3,
false, adj_elems,
2041 moab::Interface::UNION);
2043 std::vector<double> adj_elems_data(adj_elems.size() * interp_tag_len,
2045 CHKERR moab.tag_get_data(interp_tag, adj_elems, &adj_elems_data[0]);
2047 std::vector<double> vert_data(interp_tag_len, 0.0);
2048 for (
int itag = 0; itag < interp_tag_len; itag++) {
2049 for (
int i = 0;
i < adj_elems.size();
i++) {
2050 vert_data[itag] += adj_elems_data[
i * interp_tag_len + itag];
2052 vert_data[itag] /= adj_elems.size();
2054 CHKERR moab.tag_set_data(interp_tag, &vert, 1, &vert_data[0]);
2058 CHKERR moab.tag_delete(scalar_tag);
2059 CHKERR moab.tag_delete(adj_count_tag);
2061 Range src_mesh_ents;
2062 CHKERR moab.get_entities_by_handle(source_root, src_mesh_ents);
2063 CHKERR moab.delete_entities(&source_root, 1);
2064 CHKERR moab.delete_entities(src_mesh_ents);
2065 CHKERR moab.delete_entities(&part_set, 1);
2069 MPI_Bcast(&tag_length, 1, MPI_INT, 0, PETSC_COMM_WORLD);
2070 MPI_Bcast(&dtype, 1, MPI_INT, 0, PETSC_COMM_WORLD);
2071 MPI_Bcast(&storage, 1, MPI_INT, 0, PETSC_COMM_WORLD);
2076 MB_TAG_CREAT | storage;
2077 std::vector<double> def_val(tag_length, 0.);
2078 CHKERR moab.tag_get_handle(iterp_tag_name, tag_length, dtype, interp_tag_all,
2079 flags, def_val.data());
2080 MPI_Barrier(PETSC_COMM_WORLD);
2102 CHKERR moab.delete_entities(&target_root, 1);
2113 auto add_field_to_fe = [
this](
const std::string fe,
2152 auto set_fe_adjacency = [&](
auto fe_name) {
2155 boost::make_shared<ParentFiniteElementAdjacencyFunctionSkeleton<2>>(
2163 auto add_field_to_fe = [
this](
const std::string fe,
2175 Range natural_bc_elements;
2178 natural_bc_elements.merge(
v.faces);
2183 natural_bc_elements.merge(
v.faces);
2188 natural_bc_elements.merge(
v.faces);
2193 natural_bc_elements.merge(
v.faces);
2198 natural_bc_elements.merge(
v.faces);
2203 natural_bc_elements.merge(
v.faces);
2208 natural_bc_elements.merge(
v.faces);
2211 natural_bc_elements = intersect(natural_bc_elements, meshset_ents);
2222 auto get_skin = [&](
auto &body_ents) {
2225 CHKERR skin.find_skin(0, body_ents,
false, skin_ents);
2230 Range boundary_ents;
2231 ParallelComm *pcomm =
2233 CHKERR pcomm->filter_pstatus(skin, PSTATUS_SHARED | PSTATUS_MULTISHARED,
2234 PSTATUS_NOT, -1, &boundary_ents);
2235 return boundary_ents;
2317 auto remove_dofs_on_broken_skin = [&](
const std::string prb_name) {
2319 for (
int d : {0, 1, 2}) {
2320 std::vector<boost::weak_ptr<NumeredDofEntity>> dofs_to_remove;
2322 ->getSideDofsOnBrokenSpaceEntities(
2333 CHKERR remove_dofs_on_broken_skin(
"ESHELBY_PLASTICITY");
2369 auto set_zero_block = [&]() {
2401 auto set_section = [&]() {
2403 PetscSection section;
2408 CHKERR PetscSectionDestroy(§ion);
2431BcDisp::BcDisp(std::string name, std::vector<double> attr,
Range faces)
2432 : blockName(name), faces(faces) {
2433 vals.resize(3,
false);
2434 flags.resize(3,
false);
2435 for (
int ii = 0; ii != 3; ++ii) {
2436 vals[ii] = attr[ii];
2437 flags[ii] =
static_cast<int>(attr[ii + 3]);
2440 MOFEM_LOG(
"EP", Sev::inform) <<
"Add BCDisp " << name;
2442 <<
"Add BCDisp vals " <<
vals[0] <<
" " <<
vals[1] <<
" " <<
vals[2];
2444 <<
"Add BCDisp flags " <<
flags[0] <<
" " <<
flags[1] <<
" " <<
flags[2];
2445 MOFEM_LOG(
"EP", Sev::inform) <<
"Add BCDisp nb. of faces " <<
faces.size();
2449 : blockName(name), faces(faces) {
2450 vals.resize(attr.size(),
false);
2451 for (
int ii = 0; ii != attr.size(); ++ii) {
2452 vals[ii] = attr[ii];
2458 : blockName(name), faces(faces) {
2459 vals.resize(3,
false);
2460 flags.resize(3,
false);
2461 for (
int ii = 0; ii != 3; ++ii) {
2462 vals[ii] = attr[ii];
2463 flags[ii] =
static_cast<int>(attr[ii + 3]);
2466 MOFEM_LOG(
"EP", Sev::inform) <<
"Add BCForce " << name;
2468 <<
"Add BCForce vals " <<
vals[0] <<
" " <<
vals[1] <<
" " <<
vals[2];
2470 <<
"Add BCForce flags " <<
flags[0] <<
" " <<
flags[1] <<
" " <<
flags[2];
2471 MOFEM_LOG(
"EP", Sev::inform) <<
"Add BCForce nb. of faces " <<
faces.size();
2475 std::vector<double> attr,
2477 : blockName(name), faces(faces) {
2480 if (attr.size() < 1) {
2482 "Wrong size of normal displacement BC");
2487 MOFEM_LOG(
"EP", Sev::inform) <<
"Add NormalDisplacementBc " << name;
2488 MOFEM_LOG(
"EP", Sev::inform) <<
"Add NormalDisplacementBc val " <<
val;
2490 <<
"Add NormalDisplacementBc nb. of faces " <<
faces.size();
2494 : blockName(name), faces(faces) {
2497 if (attr.size() < 1) {
2499 "Wrong size of normal displacement BC");
2504 MOFEM_LOG(
"EP", Sev::inform) <<
"Add PressureBc " << name;
2505 MOFEM_LOG(
"EP", Sev::inform) <<
"Add PressureBc val " <<
val;
2507 <<
"Add PressureBc nb. of faces " <<
faces.size();
2512 : blockName(name), ents(ents) {
2515 if (attr.size() < 2) {
2517 "Wrong size of external strain attribute");
2523 MOFEM_LOG(
"EP", Sev::inform) <<
"Add ExternalStrain " << name;
2524 MOFEM_LOG(
"EP", Sev::inform) <<
"Add ExternalStrain val " <<
val;
2526 <<
"Add ExternalStrain bulk modulus K " <<
bulkModulusK;
2528 <<
"Add ExternalStrain nb. of tets " <<
ents.size();
2532 std::vector<double> attr,
2534 : blockName(name), faces(faces) {
2537 if (attr.size() < 3) {
2539 "Wrong size of analytical displacement BC");
2542 flags.resize(3,
false);
2543 for (
int ii = 0; ii != 3; ++ii) {
2544 flags[ii] = attr[ii];
2547 MOFEM_LOG(
"EP", Sev::inform) <<
"Add AnalyticalDisplacementBc " << name;
2549 <<
"Add AnalyticalDisplacementBc flags " <<
flags[0] <<
" " <<
flags[1]
2552 <<
"Add AnalyticalDisplacementBc nb. of faces " <<
faces.size();
2556 std::vector<double> attr,
2558 : blockName(name), faces(faces) {
2561 if (attr.size() < 3) {
2563 "Wrong size of analytical traction BC");
2566 flags.resize(3,
false);
2567 for (
int ii = 0; ii != 3; ++ii) {
2568 flags[ii] = attr[ii];
2571 MOFEM_LOG(
"EP", Sev::inform) <<
"Add AnalyticalTractionBc " << name;
2572 MOFEM_LOG(
"EP", Sev::inform) <<
"Add AnalyticalTractionBc flags " <<
flags[0]
2575 <<
"Add AnalyticalTractionBc nb. of faces " <<
faces.size();
2580 boost::shared_ptr<TractionFreeBc> &bc_ptr,
2581 const std::string contact_set_name) {
2586 CHKERR mField.get_moab().get_entities_by_type(meshset, MBTET, tets);
2587 Range tets_skin_part;
2588 Skinner skin(&mField.get_moab());
2589 CHKERR skin.find_skin(0, tets,
false, tets_skin_part);
2590 ParallelComm *pcomm =
2593 CHKERR pcomm->filter_pstatus(tets_skin_part,
2594 PSTATUS_SHARED | PSTATUS_MULTISHARED,
2595 PSTATUS_NOT, -1, &tets_skin);
2598 for (
int dd = 0; dd != 3; ++dd)
2599 (*bc_ptr)[dd] = tets_skin;
2602 if (bcSpatialDispVecPtr)
2603 for (
auto &
v : *bcSpatialDispVecPtr) {
2605 (*bc_ptr)[0] = subtract((*bc_ptr)[0],
v.faces);
2607 (*bc_ptr)[1] = subtract((*bc_ptr)[1],
v.faces);
2609 (*bc_ptr)[2] = subtract((*bc_ptr)[2],
v.faces);
2613 if (bcSpatialRotationVecPtr)
2614 for (
auto &
v : *bcSpatialRotationVecPtr) {
2615 (*bc_ptr)[0] = subtract((*bc_ptr)[0],
v.faces);
2616 (*bc_ptr)[1] = subtract((*bc_ptr)[1],
v.faces);
2617 (*bc_ptr)[2] = subtract((*bc_ptr)[2],
v.faces);
2620 if (bcSpatialNormalDisplacementVecPtr)
2621 for (
auto &
v : *bcSpatialNormalDisplacementVecPtr) {
2622 (*bc_ptr)[0] = subtract((*bc_ptr)[0],
v.faces);
2623 (*bc_ptr)[1] = subtract((*bc_ptr)[1],
v.faces);
2624 (*bc_ptr)[2] = subtract((*bc_ptr)[2],
v.faces);
2627 if (bcSpatialAnalyticalDisplacementVecPtr)
2628 for (
auto &
v : *bcSpatialAnalyticalDisplacementVecPtr) {
2630 (*bc_ptr)[0] = subtract((*bc_ptr)[0],
v.faces);
2632 (*bc_ptr)[1] = subtract((*bc_ptr)[1],
v.faces);
2634 (*bc_ptr)[2] = subtract((*bc_ptr)[2],
v.faces);
2637 if (bcSpatialTractionVecPtr)
2638 for (
auto &
v : *bcSpatialTractionVecPtr) {
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 (bcSpatialAnalyticalTractionVecPtr)
2645 for (
auto &
v : *bcSpatialAnalyticalTractionVecPtr) {
2646 (*bc_ptr)[0] = subtract((*bc_ptr)[0],
v.faces);
2647 (*bc_ptr)[1] = subtract((*bc_ptr)[1],
v.faces);
2648 (*bc_ptr)[2] = subtract((*bc_ptr)[2],
v.faces);
2651 if (bcSpatialPressureVecPtr)
2652 for (
auto &
v : *bcSpatialPressureVecPtr) {
2653 (*bc_ptr)[0] = subtract((*bc_ptr)[0],
v.faces);
2654 (*bc_ptr)[1] = subtract((*bc_ptr)[1],
v.faces);
2655 (*bc_ptr)[2] = subtract((*bc_ptr)[2],
v.faces);
2660 std::regex((boost::format(
"%s(.*)") % contact_set_name).str()))) {
2662 CHKERR m->getMeshsetIdEntitiesByDimension(mField.get_moab(), 2, faces,
2664 (*bc_ptr)[0] = subtract((*bc_ptr)[0], faces);
2665 (*bc_ptr)[1] = subtract((*bc_ptr)[1], faces);
2666 (*bc_ptr)[2] = subtract((*bc_ptr)[2], faces);
2683 return 2 * p_data + 1;
2689 return 2 * (p_data + 1);
2694 const int tag,
const bool do_rhs,
const bool do_lhs,
const bool calc_rates,
2696 boost::shared_ptr<VolumeElementForcesAndSourcesCore> fe) {
2700 boost::make_shared<CGGUserPolynomialBase::CachePhi>(0, 0,
MatrixDouble());
2701 fe->getUserPolynomialBase() =
2702 boost::make_shared<CGGUserPolynomialBase>(bubble_cache);
2703 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
2704 fe->getOpPtrVector(), {HDIV, H1, L2}, materialH1Positions, frontAdjEdges);
2707 fe->getRuleHook = [](int, int, int) {
return -1; };
2708 auto vol_rule_lin = [](
int o) {
return 2 * o + 1; };
2709 auto vol_rule_no_lin = [](
int o) {
return 2 * o + (o - 1) + 1; };
2710 auto vol_rule = (
SMALL_ROT > 0) ? vol_rule_lin : vol_rule_no_lin;
2711 fe->setRuleHook = SetIntegrationAtFrontVolume(frontVertices, frontAdjEdges,
2712 vol_rule, bubble_cache);
2718 dataAtPts->physicsPtr = physicalEquations;
2723 piolaStress, dataAtPts->getApproxPAtPts()));
2725 bubbleField, dataAtPts->getApproxPAtPts(), MBMAXTYPE));
2727 piolaStress, dataAtPts->getDivPAtPts()));
2730 fe->getOpPtrVector().push_back(
2731 physicalEquations->returnOpCalculateStretchFromStress(
2732 dataAtPts, physicalEquations));
2734 fe->getOpPtrVector().push_back(
2736 stretchTensor, dataAtPts->getLogStretchTensorAtPts(), MBTET));
2740 rotAxis, dataAtPts->getRotAxisAtPts(), MBTET));
2742 rotAxis, dataAtPts->getRotAxis0AtPts(), solTSStep, MBTET));
2744 spatialL2Disp, dataAtPts->getSmallWL2AtPts(), MBTET));
2748 spatialH1Disp, dataAtPts->getSmallWH1AtPts()));
2750 spatialH1Disp, dataAtPts->getSmallWGradH1AtPts()));
2755 spatialL2Disp, dataAtPts->getSmallWL2DotAtPts(), MBTET));
2758 fe->getOpPtrVector().push_back(
2760 stretchTensor, dataAtPts->getLogStretchDotTensorAtPts(), MBTET));
2761 fe->getOpPtrVector().push_back(
2763 stretchTensor, dataAtPts->getGradLogStretchDotTensorAtPts(),
2767 rotAxis, dataAtPts->getRotAxisDotAtPts(), MBTET));
2769 rotAxis, dataAtPts->getRotAxisGradDotAtPts(), MBTET));
2772 if (std::abs(alphaRho) > std::numeric_limits<double>::epsilon()) {
2774 spatialL2Disp, dataAtPts->getSmallWL2DotDotAtPts(), MBTET));
2781 piolaStress, dataAtPts->getVarPiolaPts(), boost::make_shared<double>(1),
2784 bubbleField, dataAtPts->getVarPiolaPts(), boost::make_shared<double>(1),
2785 var_vec, MBMAXTYPE));
2787 rotAxis, dataAtPts->getVarRotAxisPts(), var_vec, MBTET));
2789 piolaStress, dataAtPts->getDivVarPiolaPts(), var_vec));
2791 spatialL2Disp, dataAtPts->getVarWL2Pts(), var_vec, MBTET));
2794 fe->getOpPtrVector().push_back(
2795 physicalEquations->returnOpCalculateVarStretchFromStress(
2796 dataAtPts, physicalEquations));
2798 fe->getOpPtrVector().push_back(
2800 stretchTensor, dataAtPts->getVarLogStreachPts(), var_vec, MBTET));
2806 dataAtPts, ((do_rhs || do_lhs) && calc_rates) ? alphaOmega : 0.));
2811 fe->getOpPtrVector().push_back(physicalEquations->returnOpJacobian(
2812 tag, do_rhs, do_lhs, dataAtPts, physicalEquations));
2819 const int tag,
const bool add_elastic,
const bool add_material,
2820 boost::shared_ptr<VolumeElementForcesAndSourcesCore> &fe_rhs,
2821 boost::shared_ptr<VolumeElementForcesAndSourcesCore> &fe_lhs) {
2826 std::map<int, Range> map;
2829 mField.getInterface<
MeshsetsManager>()->getCubitMeshsetPtr(std::regex(
2831 (boost::format(
"%s(.*)") % name).str()
2837 CHK_MOAB_THROW(m_ptr->getMeshsetIdEntitiesByDimension(mField.get_moab(),
2840 map[m_ptr->getMeshsetId()] = ents;
2846 constexpr bool stab_tau_dot_variant =
false;
2848 auto local_tau_sacale = boost::make_shared<double>(1.0);
2851 using BdyEleOp = BoundaryEle::UserDataOperator;
2853 set_scale_op->doWorkRhsHook =
2855 local_tau_sacale](
DataOperator *raw_op_ptr,
int side, EntityType type,
2858 auto op_ptr =
static_cast<BdyEleOp *
>(raw_op_ptr);
2859 auto h = std::sqrt(op_ptr->getFTensor1Normal().l2());
2860 *local_tau_sacale = (alphaTau /
h);
2864 auto not_interface_face = [
this](
FEMethod *fe_method_ptr) {
2865 auto ent = fe_method_ptr->getFEEntityHandle();
2868 (interfaceFaces->find(ent) != interfaceFaces->end())
2870 || (crackFaces->find(ent) != crackFaces->end())
2879 fe_rhs = boost::make_shared<VolumeElementForcesAndSourcesCore>(mField);
2886 fe_rhs->getOpPtrVector().push_back(
2888 fe_rhs->getOpPtrVector().push_back(
2893 if (!internalStressTagName.empty()) {
2894 switch (internalStressInterpOrder) {
2896 fe_rhs->getOpPtrVector().push_back(
2900 fe_rhs->getOpPtrVector().push_back(
2905 "Unsupported internal stress interpolation order %d",
2906 internalStressInterpOrder);
2910 auto ts_internal_stress =
2911 boost::make_shared<DynamicRelaxationTimeScale>(
2912 "internal_stress_history.txt",
false, def_scaling_fun);
2913 if (internalStressVoigt) {
2914 fe_rhs->getOpPtrVector().push_back(
2916 stretchTensor, dataAtPts, ts_internal_stress));
2918 fe_rhs->getOpPtrVector().push_back(
2920 stretchTensor, dataAtPts, ts_internal_stress));
2923 if (
auto op = physicalEquations->returnOpSpatialPhysicalExternalStrain(
2924 stretchTensor, dataAtPts, externalStrainVecPtr, timeScaleMap)) {
2925 fe_rhs->getOpPtrVector().push_back(op);
2926 }
else if (externalStrainVecPtr && !externalStrainVecPtr->empty()) {
2928 "OpSpatialPhysicalExternalStrain not implemented for this "
2932 fe_rhs->getOpPtrVector().push_back(
2933 physicalEquations->returnOpSpatialPhysical(stretchTensor, dataAtPts,
2936 fe_rhs->getOpPtrVector().push_back(
2938 fe_rhs->getOpPtrVector().push_back(
2940 fe_rhs->getOpPtrVector().push_back(
2943 auto set_hybridisation_rhs = [&](
auto &pip) {
2950 using SideEleOp = EleOnSide::UserDataOperator;
2951 using BdyEleOp = BoundaryEle::UserDataOperator;
2956 mField, skeletonElement,
SPACE_DIM - 1, Sev::noisy);
2958 op_loop_skeleton_side->getSideFEPtr()->getRuleHook = [](int, int, int) {
2961 op_loop_skeleton_side->getSideFEPtr()->setRuleHook =
2962 SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
2964 CHKERR EshelbianPlasticity::
2965 AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
2966 op_loop_skeleton_side->getOpPtrVector(), {L2},
2967 materialH1Positions, frontAdjEdges);
2971 auto broken_data_ptr =
2972 boost::make_shared<std::vector<BrokenBaseSideData>>();
2975 mField, elementVolumeName,
SPACE_DIM, Sev::noisy);
2976 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
2977 boost::make_shared<CGGUserPolynomialBase>();
2979 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
2980 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
2981 materialH1Positions, frontAdjEdges);
2982 op_loop_domain_side->getOpPtrVector().push_back(
2984 auto flux_mat_ptr = boost::make_shared<MatrixDouble>();
2985 op_loop_domain_side->getOpPtrVector().push_back(
2988 op_loop_domain_side->getOpPtrVector().push_back(
2992 op_loop_skeleton_side->getOpPtrVector().push_back(op_loop_domain_side);
2994 GAUSS>::OpBrokenSpaceConstrainDHybrid<SPACE_DIM>;
2996 GAUSS>::OpBrokenSpaceConstrainDFlux<SPACE_DIM>;
2997 op_loop_skeleton_side->getOpPtrVector().push_back(
new OpC_dHybrid(
2998 hybridSpatialDisp, broken_data_ptr, boost::make_shared<double>(1.0)));
2999 auto hybrid_ptr = boost::make_shared<MatrixDouble>();
3000 op_loop_skeleton_side->getOpPtrVector().push_back(
3003 op_loop_skeleton_side->getOpPtrVector().push_back(
new OpC_dBroken(
3004 broken_data_ptr, hybrid_ptr, boost::make_shared<double>(1.0)));
3007 pip.push_back(op_loop_skeleton_side);
3012 auto set_tau_stabilsation_rhs = [&](
auto &pip,
auto side_fe_name,
3013 auto hybrid_field) {
3020 using SideEleOp = EleOnSide::UserDataOperator;
3021 using BdyEleOp = BoundaryEle::UserDataOperator;
3026 mField, side_fe_name,
SPACE_DIM - 1, Sev::noisy);
3028 op_loop_skeleton_side->getSideFEPtr()->getRuleHook = [](int, int, int) {
3031 op_loop_skeleton_side->getSideFEPtr()->setRuleHook =
3032 SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
3033 CHKERR EshelbianPlasticity::
3034 AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
3035 op_loop_skeleton_side->getOpPtrVector(), {L2},
3036 materialH1Positions, frontAdjEdges);
3039 mField, elementVolumeName,
SPACE_DIM, Sev::noisy);
3040 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
3041 boost::make_shared<CGGUserPolynomialBase>();
3043 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
3044 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
3045 materialH1Positions, frontAdjEdges);
3048 auto broken_disp_data_ptr =
3049 boost::make_shared<std::vector<BrokenBaseSideData>>();
3050 op_loop_domain_side->getOpPtrVector().push_back(
3052 broken_disp_data_ptr));
3053 auto disp_mat_ptr = boost::make_shared<MatrixDouble>();
3054 if (stab_tau_dot_variant) {
3055 op_loop_domain_side->getOpPtrVector().push_back(
3059 op_loop_domain_side->getOpPtrVector().push_back(
3064 op_loop_domain_side->getOpPtrVector().push_back(
3067 op_loop_skeleton_side->getOpPtrVector().push_back(op_loop_domain_side);
3068 op_loop_skeleton_side->getOpPtrVector().push_back(set_scale_op);
3071 auto hybrid_ptr = boost::make_shared<MatrixDouble>();
3072 if (stab_tau_dot_variant) {
3073 op_loop_skeleton_side->getOpPtrVector().push_back(
3077 op_loop_skeleton_side->getOpPtrVector().push_back(
3083 op_loop_skeleton_side->getOpPtrVector().push_back(
3085 hybrid_field, hybrid_ptr,
3086 [local_tau_sacale, broken_disp_data_ptr](
double,
double,
double) {
3087 return broken_disp_data_ptr->size() * (*local_tau_sacale);
3090 op_loop_skeleton_side->getOpPtrVector().push_back(
3092 broken_disp_data_ptr, [local_tau_sacale](
double,
double,
double) {
3093 return (*local_tau_sacale);
3096 op_loop_skeleton_side->getOpPtrVector().push_back(
3098 hybrid_field, broken_disp_data_ptr,
3099 [local_tau_sacale](
double,
double,
double) {
3100 return -(*local_tau_sacale);
3103 op_loop_skeleton_side->getOpPtrVector().push_back(
3105 broken_disp_data_ptr, hybrid_ptr,
3106 [local_tau_sacale](
double,
double,
double) {
3107 return -(*local_tau_sacale);
3111 pip.push_back(op_loop_skeleton_side);
3116 auto set_contact_rhs = [&](
auto &pip) {
3120 auto set_cohesive_rhs = [&](
auto &pip) {
3123 SetIntegrationAtFrontFace(frontVertices, frontAdjEdges,
3124 [](
int p) {
return 2 * (p + 1) + 1; }),
3125 interfaceFaces, pip);
3128 CHKERR set_hybridisation_rhs(fe_rhs->getOpPtrVector());
3129 CHKERR set_contact_rhs(fe_rhs->getOpPtrVector());
3130 if (alphaTau > 0.0) {
3131 CHKERR set_tau_stabilsation_rhs(fe_rhs->getOpPtrVector(), skeletonElement,
3133 CHKERR set_tau_stabilsation_rhs(fe_rhs->getOpPtrVector(), contactElement,
3136 if (intefaceCrack == PETSC_TRUE) {
3137 CHKERR set_cohesive_rhs(fe_rhs->getOpPtrVector());
3141 using BodyNaturalBC =
3143 Assembly<PETSC>::LinearForm<
GAUSS>;
3145 BodyNaturalBC::OpFlux<NaturalMeshsetType<BLOCKSET>, 1, 3>;
3147 auto body_time_scale =
3148 boost::make_shared<DynamicRelaxationTimeScale>(
"body_force.txt");
3149 CHKERR BodyNaturalBC::AddFluxToPipeline<OpBodyForce>::add(
3150 fe_rhs->getOpPtrVector(), mField, spatialL2Disp, {body_time_scale},
3151 "BODY_FORCE", Sev::inform);
3155 fe_lhs = boost::make_shared<VolumeElementForcesAndSourcesCore>(mField);
3163 fe_lhs->getOpPtrVector().push_back(
3166 bubbleField, piolaStress, dataAtPts));
3167 fe_lhs->getOpPtrVector().push_back(
3171 fe_lhs->getOpPtrVector().push_back(
3172 physicalEquations->returnOpSpatialPhysical_du_du(
3173 stretchTensor, stretchTensor, dataAtPts, alphaU));
3175 stretchTensor, piolaStress, dataAtPts,
true));
3177 stretchTensor, bubbleField, dataAtPts,
true));
3179 stretchTensor, rotAxis, dataAtPts,
3180 symmetrySelector ==
SYMMETRIC ?
true :
false));
3184 spatialL2Disp, piolaStress, dataAtPts,
true));
3186 spatialL2Disp, spatialL2Disp, dataAtPts, alphaW, alphaRho));
3189 piolaStress, rotAxis, dataAtPts,
3190 symmetrySelector ==
SYMMETRIC ?
true :
false));
3192 bubbleField, rotAxis, dataAtPts,
3193 symmetrySelector ==
SYMMETRIC ?
true :
false));
3198 rotAxis, stretchTensor, dataAtPts,
false));
3201 rotAxis, piolaStress, dataAtPts,
false));
3203 rotAxis, bubbleField, dataAtPts,
false));
3206 rotAxis, rotAxis, dataAtPts, alphaOmega));
3208 auto set_hybridisation_lhs = [&](
auto &pip) {
3215 using SideEleOp = EleOnSide::UserDataOperator;
3216 using BdyEleOp = BoundaryEle::UserDataOperator;
3221 mField, skeletonElement,
SPACE_DIM - 1, Sev::noisy);
3222 op_loop_skeleton_side->getSideFEPtr()->getRuleHook = [](int, int, int) {
3225 op_loop_skeleton_side->getSideFEPtr()->setRuleHook =
3226 SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
3227 CHKERR EshelbianPlasticity::
3228 AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
3229 op_loop_skeleton_side->getOpPtrVector(), {L2},
3230 materialH1Positions, frontAdjEdges);
3234 auto broken_data_ptr =
3235 boost::make_shared<std::vector<BrokenBaseSideData>>();
3238 mField, elementVolumeName,
SPACE_DIM, Sev::noisy);
3239 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
3240 boost::make_shared<CGGUserPolynomialBase>();
3242 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
3243 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
3244 materialH1Positions, frontAdjEdges);
3245 op_loop_domain_side->getOpPtrVector().push_back(
3248 op_loop_skeleton_side->getOpPtrVector().push_back(op_loop_domain_side);
3250 GAUSS>::OpBrokenSpaceConstrain<SPACE_DIM>;
3251 op_loop_skeleton_side->getOpPtrVector().push_back(
3252 new OpC(hybridSpatialDisp, broken_data_ptr,
3253 boost::make_shared<double>(1.0),
true,
false));
3255 pip.push_back(op_loop_skeleton_side);
3260 auto set_tau_stabilsation_lhs = [&](
auto &pip,
auto side_fe_name,
3261 auto hybrid_field) {
3268 using SideEleOp = EleOnSide::UserDataOperator;
3269 using BdyEleOp = BoundaryEle::UserDataOperator;
3274 mField, side_fe_name,
SPACE_DIM - 1, Sev::noisy);
3275 op_loop_skeleton_side->getSideFEPtr()->getRuleHook = [](int, int, int) {
3278 op_loop_skeleton_side->getSideFEPtr()->setRuleHook =
3279 SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
3280 CHKERR EshelbianPlasticity::
3281 AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
3282 op_loop_skeleton_side->getOpPtrVector(), {L2},
3283 materialH1Positions, frontAdjEdges);
3287 mField, elementVolumeName,
SPACE_DIM, Sev::noisy);
3288 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
3289 boost::make_shared<CGGUserPolynomialBase>();
3291 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
3292 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
3293 materialH1Positions, frontAdjEdges);
3295 auto broken_disp_data_ptr =
3296 boost::make_shared<std::vector<BrokenBaseSideData>>();
3297 op_loop_domain_side->getOpPtrVector().push_back(
3299 broken_disp_data_ptr));
3300 op_loop_skeleton_side->getOpPtrVector().push_back(op_loop_domain_side);
3301 op_loop_skeleton_side->getOpPtrVector().push_back(set_scale_op);
3303 auto time_shift = [](
const FEMethod *fe_ptr) {
return fe_ptr->ts_a; };
3307 hybrid_field, hybrid_field,
3308 [local_tau_sacale, broken_disp_data_ptr](
double,
double,
double) {
3309 return broken_disp_data_ptr->size() * (*local_tau_sacale);
3311 if (stab_tau_dot_variant) {
3313 op_loop_skeleton_side->getOpPtrVector().back())
3314 .feScalingFun = time_shift;
3317 op_loop_skeleton_side->getOpPtrVector().push_back(
3319 broken_disp_data_ptr, [local_tau_sacale](
double,
double,
double) {
3320 return (*local_tau_sacale);
3322 if (stab_tau_dot_variant) {
3324 op_loop_skeleton_side->getOpPtrVector().back())
3325 .feScalingFun = time_shift;
3328 op_loop_skeleton_side->getOpPtrVector().push_back(
3330 hybrid_field, broken_disp_data_ptr,
3331 [local_tau_sacale](
double,
double,
double) {
3332 return -(*local_tau_sacale);
3335 if (stab_tau_dot_variant) {
3337 op_loop_skeleton_side->getOpPtrVector().back())
3338 .feScalingFun = time_shift;
3342 op_loop_skeleton_side->getOpPtrVector().push_back(
3344 hybrid_field, broken_disp_data_ptr,
3345 [local_tau_sacale](
double,
double,
double) {
3346 return -(*local_tau_sacale);
3349 if (stab_tau_dot_variant) {
3351 op_loop_skeleton_side->getOpPtrVector().back())
3352 .feScalingFun = time_shift;
3355 pip.push_back(op_loop_skeleton_side);
3360 auto set_contact_lhs = [&](
auto &pip) {
3364 auto set_cohesive_lhs = [&](
auto &pip) {
3367 SetIntegrationAtFrontFace(frontVertices, frontAdjEdges,
3368 [](
int p) {
return 2 * (p + 1) + 1; }),
3369 interfaceFaces, pip);
3372 CHKERR set_hybridisation_lhs(fe_lhs->getOpPtrVector());
3373 CHKERR set_contact_lhs(fe_lhs->getOpPtrVector());
3374 if (alphaTau > 0.0) {
3375 CHKERR set_tau_stabilsation_lhs(fe_lhs->getOpPtrVector(), skeletonElement,
3377 CHKERR set_tau_stabilsation_lhs(fe_lhs->getOpPtrVector(), contactElement,
3380 if (intefaceCrack == PETSC_TRUE) {
3381 CHKERR set_cohesive_lhs(fe_lhs->getOpPtrVector());
3392 const bool add_elastic,
const bool add_material,
3393 boost::shared_ptr<FaceElementForcesAndSourcesCore> &fe_rhs,
3394 boost::shared_ptr<FaceElementForcesAndSourcesCore> &fe_lhs) {
3397 fe_rhs = boost::make_shared<FaceElementForcesAndSourcesCore>(mField);
3398 fe_lhs = boost::make_shared<FaceElementForcesAndSourcesCore>(mField);
3403 fe_rhs->getRuleHook = [](int, int, int) {
return -1; };
3404 fe_lhs->getRuleHook = [](int, int, int) {
return -1; };
3405 fe_rhs->setRuleHook = SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
3406 fe_lhs->setRuleHook = SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
3409 EshelbianPlasticity::AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
3410 fe_rhs->getOpPtrVector(), {L2}, materialH1Positions, frontAdjEdges);
3412 EshelbianPlasticity::AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
3413 fe_lhs->getOpPtrVector(), {L2}, materialH1Positions, frontAdjEdges);
3417 auto get_broken_op_side = [
this](
auto &pip) {
3420 using SideEleOp = EleOnSide::UserDataOperator;
3422 auto broken_data_ptr =
3423 boost::make_shared<std::vector<BrokenBaseSideData>>();
3426 mField, elementVolumeName,
SPACE_DIM, Sev::noisy);
3427 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
3428 boost::make_shared<CGGUserPolynomialBase>();
3430 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
3431 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
3432 materialH1Positions, frontAdjEdges);
3433 op_loop_domain_side->getOpPtrVector().push_back(
3435 boost::shared_ptr<double> piola_scale_ptr(
new double);
3436 op_loop_domain_side->getOpPtrVector().push_back(
3437 physicalEquations->returnOpSetScale(piola_scale_ptr,
3438 physicalEquations));
3439 auto flux_mat_ptr = boost::make_shared<MatrixDouble>();
3440 op_loop_domain_side->getOpPtrVector().push_back(
3443 op_loop_domain_side->getOpPtrVector().push_back(
3445 pip.push_back(op_loop_domain_side);
3446 return std::make_tuple(broken_data_ptr, piola_scale_ptr);
3449 auto set_rhs = [&]() {
3452 auto [broken_data_ptr, piola_scale_ptr] =
3453 get_broken_op_side(fe_rhs->getOpPtrVector());
3455 fe_rhs->getOpPtrVector().push_back(
3456 new OpDispBc(broken_data_ptr, bcSpatialDispVecPtr, timeScaleMap));
3458 broken_data_ptr, bcSpatialAnalyticalDisplacementVecPtr,
3461 broken_data_ptr, bcSpatialRotationVecPtr, timeScaleMap));
3463 fe_rhs->getOpPtrVector().push_back(
3465 piola_scale_ptr, timeScaleMap));
3466 auto hybrid_grad_ptr = boost::make_shared<MatrixDouble>();
3468 fe_rhs->getOpPtrVector().push_back(
3470 hybridSpatialDisp, hybrid_grad_ptr));
3472 hybridSpatialDisp, bcSpatialPressureVecPtr, piola_scale_ptr,
3473 hybrid_grad_ptr, timeScaleMap));
3475 hybridSpatialDisp, bcSpatialAnalyticalTractionVecPtr, piola_scale_ptr,
3478 auto hybrid_ptr = boost::make_shared<MatrixDouble>();
3479 fe_rhs->getOpPtrVector().push_back(
3483 hybridSpatialDisp, hybrid_ptr, broken_data_ptr,
3484 bcSpatialNormalDisplacementVecPtr, timeScaleMap));
3486 auto get_normal_disp_bc_faces = [&]() {
3489 return boost::make_shared<Range>(faces);
3494 using BdyEleOp = BoundaryEle::UserDataOperator;
3496 GAUSS>::OpBrokenSpaceConstrainDFlux<SPACE_DIM>;
3497 fe_rhs->getOpPtrVector().push_back(
new OpC_dBroken(
3498 broken_data_ptr, hybrid_ptr, boost::make_shared<double>(1.0),
3499 get_normal_disp_bc_faces()));
3504 auto set_lhs = [&]() {
3507 auto [broken_data_ptr, piola_scale_ptr] =
3508 get_broken_op_side(fe_lhs->getOpPtrVector());
3511 hybridSpatialDisp, bcSpatialNormalDisplacementVecPtr, timeScaleMap));
3513 hybridSpatialDisp, broken_data_ptr, bcSpatialNormalDisplacementVecPtr,
3516 auto hybrid_grad_ptr = boost::make_shared<MatrixDouble>();
3518 fe_lhs->getOpPtrVector().push_back(
3520 hybridSpatialDisp, hybrid_grad_ptr));
3522 hybridSpatialDisp, bcSpatialPressureVecPtr, hybrid_grad_ptr,
3525 auto get_normal_disp_bc_faces = [&]() {
3528 return boost::make_shared<Range>(faces);
3533 using BdyEleOp = BoundaryEle::UserDataOperator;
3535 GAUSS>::OpBrokenSpaceConstrain<SPACE_DIM>;
3536 fe_lhs->getOpPtrVector().push_back(
new OpC(
3537 hybridSpatialDisp, broken_data_ptr, boost::make_shared<double>(1.0),
3538 true,
true, get_normal_disp_bc_faces()));
3551 const bool add_elastic,
const bool add_material,
3552 boost::shared_ptr<FaceElementForcesAndSourcesCore> &fe_rhs,
3553 boost::shared_ptr<FaceElementForcesAndSourcesCore> &fe_lhs) {
3560 boost::shared_ptr<ForcesAndSourcesCore> &fe_contact_tree
3573 CHKERR setContactElementRhsOps(contactTreeRhs);
3575 CHKERR setVolumeElementOps(tag,
true,
false, elasticFeRhs, elasticFeLhs);
3576 CHKERR setFaceElementOps(
true,
false, elasticBcRhs, elasticBcLhs);
3579 boost::make_shared<ForcesAndSourcesCore::UserDataOperator::AdjCache>();
3581 auto get_op_contact_bc = [&]() {
3584 mField, contactElement,
SPACE_DIM - 1, Sev::noisy, adj_cache);
3585 return op_loop_side;
3593 boost::shared_ptr<FEMethod> null;
3595 if (std::abs(alphaRho) > std::numeric_limits<double>::epsilon()) {
3627 bool set_ts_monitor) {
3629#ifdef ENABLE_PYTHON_BINDING
3633 auto setup_ts_monitor = [&]() {
3634 boost::shared_ptr<TsCtx>
ts_ctx;
3637 if (set_ts_monitor) {
3641 auto monitor_ptr = boost::make_shared<EshelbianMonitor>(*ep_ptr);
3645 MOFEM_LOG(
"EP", Sev::inform) <<
"TS monitor setup";
3646 return std::make_tuple(
ts_ctx);
3649 auto setup_snes_monitor = [&]() {
3652 CHKERR TSGetSNES(ts, &snes);
3654 CHKERR SNESMonitorSet(snes,
3657 (
void *)(snes_ctx.get()), PETSC_NULLPTR);
3658 MOFEM_LOG(
"EP", Sev::inform) <<
"SNES monitor setup";
3662 auto setup_snes_conergence_test = [&]() {
3665 auto snes_convergence_test = [](SNES snes, PetscInt it, PetscReal xnorm,
3666 PetscReal snorm, PetscReal fnorm,
3667 SNESConvergedReason *reason,
void *cctx) {
3670 CHKERR SNESConvergedDefault(snes, it, xnorm, snorm, fnorm, reason,
3674 CHKERR SNESGetSolutionUpdate(snes, &x_update);
3675 CHKERR SNESGetFunction(snes, &r, PETSC_NULLPTR, PETSC_NULLPTR);
3688 auto setup_section = [&]() {
3689 PetscSection section_raw;
3695 for (
int ff = 0; ff != num_fields; ff++) {
3698 PetscSectionGetFieldName(section_raw, ff, &
field_name),
3705 auto set_vector_on_mesh = [&]() {
3709 CHKERR VecGhostUpdateBegin(x, INSERT_VALUES, SCATTER_FORWARD);
3710 CHKERR VecGhostUpdateEnd(x, INSERT_VALUES, SCATTER_FORWARD);
3711 MOFEM_LOG(
"EP", Sev::inform) <<
"Vector set on mesh";
3715 auto setup_schur_block_solver = [&]() {
3716 MOFEM_LOG(
"EP", Sev::inform) <<
"Setting up Schur block solver";
3718 "append options prefix");
3722 boost::shared_ptr<EshelbianCore::SetUpSchur> schur_ptr;
3723 if constexpr (
A == AssemblyType::BLOCK_MAT) {
3728 MOFEM_LOG(
"EP", Sev::inform) <<
"Setting up Schur block solver done";
3735#ifdef ENABLE_PYTHON_BINDING
3736 return std::make_tuple(setup_sdf(), setup_ts_monitor(),
3737 setup_snes_monitor(), setup_snes_conergence_test(),
3738 setup_section(), set_vector_on_mesh(),
3739 setup_schur_block_solver());
3741 return std::make_tuple(setup_ts_monitor(), setup_snes_monitor(),
3742 setup_snes_conergence_test(), setup_section(),
3743 set_vector_on_mesh(), setup_schur_block_solver());
3751 PetscBool debug_model = PETSC_FALSE;
3755 <<
"Debug model flag is " << (debug_model ?
"ON" :
"OFF");
3757 if (debug_model == PETSC_TRUE) {
3759 auto post_proc = [&](TS ts, PetscReal
t, Vec u, Vec u_t, Vec u_tt, Vec
F,
3764 CHKERR TSGetSNES(ts, &snes);
3766 CHKERR SNESGetIterationNumber(snes, &it);
3767 std::string file_name =
"snes_iteration_" + std::to_string(it) +
".h5m";
3768 CHKERR postProcessResults(1, file_name,
F, u_t);
3769 std::string file_skel_name =
3770 "snes_iteration_skel_" + std::to_string(it) +
".h5m";
3772 auto get_material_force_tag = [&]() {
3773 auto &moab = mField.get_moab();
3780 CHKERR calculateFaceMaterialForce(1, ts);
3781 CHKERR postProcessSkeletonResults(1, file_skel_name,
F,
3782 {get_material_force_tag()});
3786 ts_ctx_ptr->tsDebugHook = post_proc;
3795 CHKERR addDebugModel(ts);
3799 if (std::abs(alphaRho) > std::numeric_limits<double>::epsilon()) {
3801 CHKERR VecDuplicate(x, &xx);
3802 CHKERR VecZeroEntries(xx);
3803 CHKERR TS2SetSolution(ts, x, xx);
3806 CHKERR TSSetSolution(ts, x);
3809 TetPolynomialBase::switchCacheBaseOn<HDIV>(
3810 {elasticFeLhs.get(), elasticFeRhs.get()});
3815 CHKERR TSSolve(ts, PETSC_NULLPTR);
3817 TetPolynomialBase::switchCacheBaseOff<HDIV>(
3818 {elasticFeLhs.get(), elasticFeRhs.get()});
3822 if (mField.get_comm_rank() == 0) {
3824 CHKERR PipelineGraph::writeTSGraphGraphviz(ts_ctx_ptr.get(),
3825 "solve_elastic_graph.dot");
3830 CHKERR TSGetSNES(ts, &snes);
3831 int lin_solver_iterations;
3832 CHKERR SNESGetLinearSolveIterations(snes, &lin_solver_iterations);
3834 <<
"Number of linear solver iterations " << lin_solver_iterations;
3836 PetscBool test_cook_flg = PETSC_FALSE;
3839 if (test_cook_flg) {
3840 constexpr int expected_lin_solver_iterations = 11;
3841 if (lin_solver_iterations > expected_lin_solver_iterations)
3844 "Expected number of iterations is different than expected %d > %d",
3845 lin_solver_iterations, expected_lin_solver_iterations);
3848 PetscBool test_sslv116_flag = PETSC_FALSE;
3850 &test_sslv116_flag, PETSC_NULLPTR);
3852 if (test_sslv116_flag) {
3853 double max_val = 0.0;
3854 double min_val = 0.0;
3855 auto field_min_max = [&](boost::shared_ptr<FieldEntity> ent_ptr) {
3857 auto ent_type = ent_ptr->getEntType();
3858 if (ent_type == MBVERTEX) {
3859 max_val = std::max(ent_ptr->getEntFieldData()[
SPACE_DIM - 1], max_val);
3860 min_val = std::min(ent_ptr->getEntFieldData()[
SPACE_DIM - 1], min_val);
3865 field_min_max, spatialH1Disp);
3867 double global_max_val = 0.0;
3868 double global_min_val = 0.0;
3869 MPI_Allreduce(&max_val, &global_max_val, 1, MPI_DOUBLE, MPI_MAX,
3871 MPI_Allreduce(&min_val, &global_min_val, 1, MPI_DOUBLE, MPI_MIN,
3874 <<
"Max " << spatialH1Disp <<
" value: " << global_max_val;
3876 <<
"Min " << spatialH1Disp <<
" value: " << global_min_val;
3878 double ref_max_val = 0.00767;
3879 double ref_min_val = -0.00329;
3880 if (std::abs(global_max_val - ref_max_val) > 1e-5) {
3882 "Incorrect max value of the displacement field: %f != %f",
3883 global_max_val, ref_max_val);
3885 if (std::abs(global_min_val - ref_min_val) > 4e-5) {
3887 "Incorrect min value of the displacement field: %f != %f",
3888 global_min_val, ref_min_val);
3899 double start_time) {
3904 double final_time = 1;
3905 double delta_time = 0.1;
3907 PetscBool ts_h1_update = PETSC_FALSE;
3909 PetscOptionsBegin(PETSC_COMM_WORLD,
"",
"Dynamic Relaxation Options",
"none");
3911 CHKERR PetscOptionsScalar(
"-dynamic_final_time",
3912 "dynamic relaxation final time",
"", final_time,
3913 &final_time, PETSC_NULLPTR);
3914 CHKERR PetscOptionsScalar(
"-dynamic_delta_time",
3915 "dynamic relaxation final time",
"", delta_time,
3916 &delta_time, PETSC_NULLPTR);
3917 CHKERR PetscOptionsInt(
"-dynamic_max_it",
"dynamic relaxation iterations",
"",
3918 max_it, &max_it, PETSC_NULLPTR);
3919 CHKERR PetscOptionsBool(
"-dynamic_h1_update",
"update each ts step",
"",
3920 ts_h1_update, &ts_h1_update, PETSC_NULLPTR);
3925 <<
"Dynamic relaxation final time -dynamic_final_time = " << final_time;
3927 <<
"Dynamic relaxation delta time -dynamic_delta_time = " << delta_time;
3929 <<
"Dynamic relaxation max iterations -dynamic_max_it = " << max_it;
3931 <<
"Dynamic relaxation H1 update each step -dynamic_h1_update = "
3932 << (ts_h1_update ?
"TRUE" :
"FALSE");
3934 CHKERR addDebugModel(ts);
3936 auto setup_ts_monitor = [&]() {
3937 auto monitor_ptr = boost::make_shared<EshelbianMonitor>(*
this);
3940 auto monitor_ptr = setup_ts_monitor();
3942 TetPolynomialBase::switchCacheBaseOn<HDIV>(
3943 {elasticFeLhs.get(), elasticFeRhs.get()});
3947 double ts_delta_time;
3948 CHKERR TSGetTimeStep(ts, &ts_delta_time);
3958 dynamicTime = start_time;
3959 dynamicStep = start_step;
3960 monitor_ptr->ts_u = PETSC_NULLPTR;
3961 monitor_ptr->ts_t = dynamicTime;
3962 monitor_ptr->ts_step = dynamicStep;
3965 for (; dynamicTime < final_time; dynamicTime += delta_time) {
3966 MOFEM_LOG(
"EP", Sev::inform) <<
"Load step " << dynamicStep <<
" Time "
3967 << dynamicTime <<
" delta time " << delta_time;
3969 CHKERR TSSetStepNumber(ts, 0);
3971 CHKERR TSSetTimeStep(ts, ts_delta_time);
3972 if (!ts_h1_update) {
3975 CHKERR TSSetSolution(ts, x);
3976 CHKERR TSSolve(ts, PETSC_NULLPTR);
3977 if (!ts_h1_update) {
3983 CHKERR VecGhostUpdateBegin(x, INSERT_VALUES, SCATTER_FORWARD);
3984 CHKERR VecGhostUpdateEnd(x, INSERT_VALUES, SCATTER_FORWARD);
3986 monitor_ptr->ts_u = x;
3987 monitor_ptr->ts_t = dynamicTime;
3988 monitor_ptr->ts_step = dynamicStep;
3992 if (dynamicStep > max_it)
3997 TetPolynomialBase::switchCacheBaseOff<HDIV>(
3998 {elasticFeLhs.get(), elasticFeRhs.get()});
4006 auto set_block = [&](
auto name,
int dim) {
4007 std::map<int, Range> map;
4008 auto set_tag_impl = [&](
auto name) {
4013 std::regex((boost::format(
"%s(.*)") % name).str())
4016 for (
auto bc : bcs) {
4018 CHKERR bc->getMeshsetIdEntitiesByDimension(mField.get_moab(), dim, r,
4020 map[bc->getMeshsetId()] = r;
4022 <<
"Block " << name <<
" id " << bc->getMeshsetId() <<
" has "
4023 << r.size() <<
" entities";
4028 CHKERR set_tag_impl(name);
4030 return std::make_pair(name, map);
4033 auto set_skin = [&](
auto &&map) {
4034 for (
auto &
m : map.second) {
4038 <<
"Skin for block " << map.first <<
" id " <<
m.first <<
" has "
4039 <<
m.second.size() <<
" entities";
4044 auto set_tag = [&](
auto &&map) {
4046 auto name = map.first;
4047 int def_val[] = {-1};
4049 mField.get_moab().tag_get_handle(name, 1, MB_TYPE_INTEGER,
th,
4050 MB_TAG_SPARSE | MB_TAG_CREAT, def_val),
4052 for (
auto &
m : map.second) {
4060 listTagsToTransfer.push_back(set_tag(set_skin(set_block(
"BODY", 3))));
4061 listTagsToTransfer.push_back(set_tag(set_skin(set_block(
"MAT_ELASTIC", 3))));
4062 listTagsToTransfer.push_back(
4063 set_tag(set_skin(set_block(
"MAT_NEOHOOKEAN", 3))));
4064 listTagsToTransfer.push_back(set_tag(set_block(
"CONTACT", 2)));
4071 Vec f_residual, Vec var_vector,
4072 std::vector<Tag> tags_to_transfer) {
4077 auto get_tag = [&](
auto name,
auto dim) {
4078 auto &mob = mField.get_moab();
4080 double def_val[] = {0., 0., 0.};
4081 CHK_MOAB_THROW(mob.tag_get_handle(name, dim, MB_TYPE_DOUBLE, tag,
4082 MB_TAG_CREAT | MB_TAG_SPARSE, def_val),
4086 tags_to_transfer.push_back(
get_tag(
"MaterialForce", 3));
4090 auto get_crack_tag = [&]() {
4092 rval = mField.get_moab().tag_get_handle(
"CRACK",
th);
4093 if (
rval == MB_SUCCESS) {
4096 int def_val[] = {0};
4098 "CRACK", 1, MB_TYPE_INTEGER,
th, MB_TAG_SPARSE | MB_TAG_CREAT,
4103 Tag th = get_crack_tag();
4104 tags_to_transfer.push_back(
th);
4108 mark_faces.merge(*crackFaces);
4110 mark_faces.merge(*interfaceFaces);
4111 CHKERR mField.get_moab().tag_clear_data(
th, mark_faces, mark);
4115 for (
auto t : listTagsToTransfer) {
4116 tags_to_transfer.push_back(
t);
4126 auto get_post_proc = [&](
auto &post_proc_mesh,
auto sense) {
4128 auto post_proc_ptr =
4129 boost::make_shared<PostProcBrokenMeshInMoabBaseCont<FaceEle>>(
4130 mField, post_proc_mesh);
4131 EshelbianPlasticity::AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
4132 post_proc_ptr->getOpPtrVector(), {L2}, materialH1Positions,
4135 auto domain_ops = [&](
auto &fe,
int sense) {
4137 fe.getUserPolynomialBase() =
4139 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
4140 fe.getOpPtrVector(), {HDIV, H1, L2}, materialH1Positions,
4142 auto piola_scale_ptr = boost::make_shared<double>(1.0);
4143 fe.getOpPtrVector().push_back(physicalEquations->returnOpSetScale(
4144 piola_scale_ptr, physicalEquations));
4146 piolaStress, dataAtPts->getApproxPAtPts(), piola_scale_ptr));
4148 bubbleField, dataAtPts->getApproxPAtPts(), piola_scale_ptr,
4151 fe.getOpPtrVector().push_back(
4152 physicalEquations->returnOpCalculateStretchFromStress(
4153 dataAtPts, physicalEquations));
4155 fe.getOpPtrVector().push_back(
4157 stretchTensor, dataAtPts->getLogStretchTensorAtPts(), MBTET));
4162 piolaStress, dataAtPts->getVarPiolaPts(),
4163 boost::make_shared<double>(1), vec));
4165 bubbleField, dataAtPts->getVarPiolaPts(),
4166 boost::make_shared<double>(1), vec, MBMAXTYPE));
4168 rotAxis, dataAtPts->getVarRotAxisPts(), vec, MBTET));
4170 fe.getOpPtrVector().push_back(
4171 physicalEquations->returnOpCalculateVarStretchFromStress(
4172 dataAtPts, physicalEquations));
4174 fe.getOpPtrVector().push_back(
4176 stretchTensor, dataAtPts->getVarLogStreachPts(), vec, MBTET));
4181 rotAxis, dataAtPts->getRotAxisAtPts(), MBTET));
4183 rotAxis, dataAtPts->getRotAxis0AtPts(), solTSStep, MBTET));
4186 spatialL2Disp, dataAtPts->getSmallWL2AtPts(), MBTET));
4188 spatialH1Disp, dataAtPts->getSmallWH1AtPts()));
4190 spatialH1Disp, dataAtPts->getSmallWGradH1AtPts()));
4192 fe.getOpPtrVector().push_back(
4196 fe.getOpPtrVector().push_back(physicalEquations->returnOpJacobian(
4197 tag,
true,
false, dataAtPts, physicalEquations));
4199 physicalEquations->returnOpCalculateEnergy(dataAtPts,
nullptr)) {
4200 fe.getOpPtrVector().push_back(op);
4209 struct OpSidePPMap :
public OpPPMap {
4210 OpSidePPMap(moab::Interface &post_proc_mesh,
4211 std::vector<EntityHandle> &map_gauss_pts,
4212 DataMapVec data_map_scalar, DataMapMat data_map_vec,
4213 DataMapMat data_map_mat, DataMapMat data_symm_map_mat,
4215 :
OpPPMap(post_proc_mesh, map_gauss_pts, data_map_scalar,
4216 data_map_vec, data_map_mat, data_symm_map_mat),
4223 if (tagSense != 0) {
4224 if (tagSense != OpPPMap::getSkeletonSense())
4237 vec_fields[
"SpatialDisplacementL2"] = dataAtPts->getSmallWL2AtPts();
4238 vec_fields[
"SpatialDisplacementH1"] = dataAtPts->getSmallWH1AtPts();
4239 vec_fields[
"Omega"] = dataAtPts->getRotAxisAtPts();
4240 vec_fields[
"AngularMomentum"] = dataAtPts->getLeviKirchhoffAtPts();
4241 vec_fields[
"X"] = dataAtPts->getLargeXH1AtPts();
4243 vec_fields[
"EiegnLogStreach"] = dataAtPts->getEigenValsAtPts();
4247 vec_fields[
"VarOmega"] = dataAtPts->getVarRotAxisPts();
4248 vec_fields[
"VarSpatialDisplacementL2"] =
4249 boost::make_shared<MatrixDouble>();
4251 spatialL2Disp, vec_fields[
"VarSpatialDisplacementL2"], vec, MBTET));
4255 vec_fields[
"ResSpatialDisplacementL2"] =
4256 boost::make_shared<MatrixDouble>();
4258 spatialL2Disp, vec_fields[
"ResSpatialDisplacementL2"], vec, MBTET));
4259 vec_fields[
"ResOmega"] = boost::make_shared<MatrixDouble>();
4261 rotAxis, vec_fields[
"ResOmega"], vec, MBTET));
4265 mat_fields[
"PiolaStress"] = dataAtPts->getApproxPAtPts();
4267 mat_fields[
"VarPiolaStress"] = dataAtPts->getVarPiolaPts();
4271 mat_fields[
"ResPiolaStress"] = boost::make_shared<MatrixDouble>();
4273 piolaStress, mat_fields[
"ResPiolaStress"],
4274 boost::make_shared<double>(1), vec));
4276 bubbleField, mat_fields[
"ResPiolaStress"],
4277 boost::make_shared<double>(1), vec, MBMAXTYPE));
4279 if (!internalStressTagName.empty()) {
4280 mat_fields[internalStressTagName] = dataAtPts->getInternalStressAtPts();
4281 switch (internalStressInterpOrder) {
4283 fe.getOpPtrVector().push_back(
4287 fe.getOpPtrVector().push_back(
4292 "Unsupported internal stress interpolation order %d",
4293 internalStressInterpOrder);
4298 mat_fields_symm[
"LogSpatialStretch"] =
4299 dataAtPts->getLogStretchTensorAtPts();
4300 mat_fields_symm[
"SpatialStretch"] = dataAtPts->getStretchTensorAtPts();
4302 mat_fields_symm[
"VarLogSpatialStretch"] =
4303 dataAtPts->getVarLogStreachPts();
4308 mat_fields_symm[
"ResLogSpatialStretch"] =
4309 boost::make_shared<MatrixDouble>();
4310 fe.getOpPtrVector().push_back(
4312 stretchTensor, mat_fields_symm[
"ResLogSpatialStretch"], vec,
4317 fe.getOpPtrVector().push_back(
4321 post_proc_ptr->getPostProcMesh(), post_proc_ptr->getMapGaussPts(),
4338 post_proc_ptr->getPostProcMesh(), post_proc_ptr->getMapGaussPts(),
4344 auto X_h1_ptr = boost::make_shared<MatrixDouble>();
4346 post_proc_ptr->getOpPtrVector().push_back(
4348 dataAtPts->getLargeXH1AtPts()));
4353 domain_ops(*(op_loop_side->getSideFEPtr()), sense);
4354 post_proc_ptr->getOpPtrVector().push_back(op_loop_side);
4356 return post_proc_ptr;
4360 auto calcs_side_traction_and_displacements = [&](
auto &post_proc_ptr,
4366 using SideEleOp = EleOnSide::UserDataOperator;
4368 mField, elementVolumeName,
SPACE_DIM, Sev::noisy);
4369 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
4371 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
4372 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
4373 materialH1Positions, frontAdjEdges);
4374 auto traction_ptr = boost::make_shared<MatrixDouble>();
4375 op_loop_domain_side->getOpPtrVector().push_back(
4377 piolaStress, traction_ptr, boost::make_shared<double>(1.0)));
4380 contactDisp, dataAtPts->getContactL2AtPts()));
4381 pip.push_back(op_loop_domain_side);
4383 auto u_h1_ptr = boost::make_shared<MatrixDouble>();
4386 *
this, contactTreeRhs, u_h1_ptr, traction_ptr,
4388 &post_proc_ptr->getPostProcMesh(), &post_proc_ptr->getMapGaussPts()));
4394 op_this->getOpPtrVector().push_back(
4398 post_proc_ptr->getPostProcMesh(), post_proc_ptr->getMapGaussPts(),
4402 {{
"ContactDisplacement", dataAtPts->getContactL2AtPts()}},
4414 pip.push_back(op_this);
4415 auto contact_residual = boost::make_shared<MatrixDouble>();
4416 op_this->getOpPtrVector().push_back(
4418 contactDisp, contact_residual,
4420 op_this->getOpPtrVector().push_back(
4424 post_proc_ptr->getPostProcMesh(), post_proc_ptr->getMapGaussPts(),
4428 {{
"res_contact", contact_residual}},
4442 auto post_proc_mesh = boost::make_shared<moab::Core>();
4443 auto post_proc_ptr = get_post_proc(post_proc_mesh, 1);
4444 auto post_proc_negative_sense_ptr =
4445 get_post_proc(post_proc_mesh, -1);
4446 auto skin_post_proc_ptr = get_post_proc(post_proc_mesh, 1);
4447 CHKERR calcs_side_traction_and_displacements(
4448 skin_post_proc_ptr, skin_post_proc_ptr->getOpPtrVector());
4454 CHKERR mField.get_moab().get_adjacencies(own_tets,
SPACE_DIM - 1,
true,
4455 own_faces, moab::Interface::UNION);
4457 auto get_crack_faces = [&](
auto crack_faces) {
4458 auto get_adj = [&](
auto e,
auto dim) {
4460 CHKERR mField.get_moab().get_adjacencies(e, dim,
true, adj,
4461 moab::Interface::UNION);
4465 auto tets = get_adj(crack_faces, 3);
4467 auto faces = subtract(get_adj(tets, 2), crack_faces);
4469 tets = subtract(tets, get_adj(faces, 3));
4470 return subtract(crack_faces, get_adj(tets, 2));
4473 auto side_one_faces = [&](
auto &faces) {
4474 std::pair<Range, Range> sides;
4475 for (
auto f : faces) {
4477 MOAB_THROW(mField.get_moab().get_adjacencies(&f, 1, 3,
false, adj));
4478 adj = intersect(own_tets, adj);
4479 for (
auto t : adj) {
4480 int side, sense, offset;
4481 MOAB_THROW(mField.get_moab().side_number(
t, f, side, sense, offset));
4483 sides.first.insert(f);
4485 sides.second.insert(f);
4493 unite(get_crack_faces(*crackFaces), get_crack_faces(*interfaceFaces));
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);
5145 CHKERR VecGhostUpdateBegin(x, INSERT_VALUES, SCATTER_FORWARD);
5146 CHKERR VecGhostUpdateEnd(x, INSERT_VALUES, SCATTER_FORWARD);
5147 monitor_ptr->ts_u = x;
5157 CHKERR TSElasticPostStep::postStepDestroy();
5158 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.
Add cohesive elements to Eshelbian plasticity module.
#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.
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, SmartPetscObj< Vec > ver_vec, 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
boost::shared_ptr< Range > skeletonFaces
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)
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
static PetscBool intefaceCrack
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 EntitiesPetscVector createEntitiesPetscVector(MPI_Comm comm, moab::Interface &moab, int dim, const int nb_coeffs, Sev sev=Sev::verbose, int root_rank=0)
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
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)
Operator for linear form, usually to calculate values on right hand side.
Apply rotation boundary condition.
BoundaryEle::UserDataOperator BdyEleOp
ElementsAndOps< SPACE_DIM >::SideEle SideEle