16#ifdef INCLUDE_MBCOUPLER
17 #include <mbcoupler/Coupler.hpp>
24#include <boost/math/constants/constants.hpp>
27#ifdef ENABLE_PYTHON_BINDING
28 #include <boost/python.hpp>
29 #include <boost/python/def.hpp>
30 #include <boost/python/numpy.hpp>
31namespace bp = boost::python;
32namespace np = boost::python::numpy;
60 const EntityType
type) {
64 auto dim = CN::Dimension(
type);
66 std::vector<int> sendcounts(pcomm->size());
67 std::vector<int> displs(pcomm->size());
68 std::vector<int> sendbuf(r.size());
69 if (pcomm->rank() == 0) {
70 for (
auto p = 1; p != pcomm->size(); p++) {
72 ->getPartEntities(m_field.
get_moab(), p)
75 CHKERR m_field.
get_moab().get_adjacencies(part_ents, dim,
true, faces,
76 moab::Interface::UNION);
77 faces = intersect(faces, r);
78 sendcounts[p] = faces.size();
79 displs[p] = sendbuf.size();
80 for (
auto f : faces) {
82 sendbuf.push_back(
id);
88 MPI_Scatter(sendcounts.data(), 1, MPI_INT, &recv_data, 1, MPI_INT, 0,
90 std::vector<int> recvbuf(recv_data);
91 MPI_Scatterv(sendbuf.data(), sendcounts.data(), displs.data(), MPI_INT,
92 recvbuf.data(), recv_data, MPI_INT, 0, pcomm->comm());
94 if (pcomm->rank() > 0) {
96 for (
auto &f : recvbuf) {
106 const std::string block_name) {
112 std::regex((boost::format(
"%s(.*)") % block_name).str())
116 for (
auto bc : bcs) {
117 auto meshset = bc->getMeshset();
126 const std::string block_name,
int dim) {
132 std::regex((boost::format(
"%s(.*)") % block_name).str())
136 for (
auto bc : bcs) {
148 const std::string block_name,
int dim) {
149 std::map<std::string, Range> r;
154 std::regex((boost::format(
"%s(.*)") % block_name).str())
158 for (
auto bc : bcs) {
163 r[bc->getName()] = faces;
170 const unsigned int cubit_bc_type) {
172 EntityHandle meshset;
177static auto save_range(moab::Interface &moab,
const std::string name,
178 const Range r, std::vector<Tag> tags = {}) {
181 CHKERR moab.add_entities(*out_meshset, r);
183 CHKERR moab.write_file(name.c_str(),
"VTK",
"", out_meshset->get_ptr(), 1,
184 tags.data(), tags.size());
186 MOFEM_LOG(
"SELF", Sev::warning) <<
"Empty range for " << name;
193 ParallelComm *pcomm =
196 PSTATUS_SHARED | PSTATUS_MULTISHARED,
197 PSTATUS_NOT, -1, &boundary_ents),
199 return boundary_ents;
204 ParallelComm *pcomm =
206 CHK_MOAB_THROW(pcomm->filter_pstatus(skin, PSTATUS_NOT_OWNED, PSTATUS_NOT, -1,
215 CHK_MOAB_THROW(skin.find_skin(0, body_ents,
false, skin_ents),
"find_skin");
221 ParallelComm *pcomm =
224 Range crack_skin_without_bdy;
225 if (pcomm->rank() == 0) {
227 CHKERR moab.get_adjacencies(crack_faces, 1,
true, crack_edges,
228 moab::Interface::UNION);
229 auto crack_skin =
get_skin(m_field, crack_faces);
233 "get_entities_by_dimension");
234 auto body_skin =
get_skin(m_field, body_ents);
235 Range body_skin_edges;
236 CHK_MOAB_THROW(moab.get_adjacencies(body_skin, 1,
true, body_skin_edges,
237 moab::Interface::UNION),
239 crack_skin_without_bdy = subtract(crack_skin, body_skin_edges);
241 for (
auto &
m : front_edges_map) {
242 auto add_front = subtract(
m.second, crack_edges);
243 auto i = intersect(
m.second, crack_edges);
245 crack_skin_without_bdy.merge(add_front);
249 CHKERR moab.get_adjacencies(i_skin, 1,
true, adj_i_skin,
250 moab::Interface::UNION);
251 adj_i_skin = subtract(intersect(adj_i_skin,
m.second), crack_edges);
252 crack_skin_without_bdy.merge(adj_i_skin);
256 return send_type(m_field, crack_skin_without_bdy, MBEDGE);
262 ParallelComm *pcomm =
265 MOFEM_LOG(
"EP", Sev::noisy) <<
"get_two_sides_of_crack_surface";
267 if (!pcomm->rank()) {
269 auto impl = [&](
auto &saids) {
274 auto get_adj = [&](
auto e,
auto dim) {
277 e, dim,
true, adj, moab::Interface::UNION),
282 auto get_conn = [&](
auto e) {
289 constexpr bool debug =
false;
293 auto body_skin =
get_skin(m_field, body_ents);
294 auto body_skin_edges = get_adj(body_skin, 1);
297 subtract(
get_skin(m_field, crack_faces), body_skin_edges);
298 auto crack_skin_conn = get_conn(crack_skin);
299 auto crack_skin_conn_edges = get_adj(crack_skin_conn, 1);
300 auto crack_edges = get_adj(crack_faces, 1);
301 crack_edges = subtract(crack_edges, crack_skin);
302 auto all_tets = get_adj(crack_edges, 3);
303 crack_edges = subtract(crack_edges, crack_skin_conn_edges);
304 auto crack_conn = get_conn(crack_edges);
305 all_tets.merge(get_adj(crack_conn, 3));
314 if (crack_faces.size()) {
315 auto grow = [&](
auto r) {
316 auto crack_faces_conn = get_conn(crack_faces);
319 while (size_r != r.size() && r.size() > 0) {
321 CHKERR moab.get_connectivity(r,
v,
true);
322 v = subtract(
v, crack_faces_conn);
325 moab::Interface::UNION);
326 r = intersect(r, all_tets);
335 Range all_tets_ord = all_tets;
336 while (all_tets.size()) {
337 Range faces = get_adj(unite(saids.first, saids.second), 2);
338 faces = subtract(crack_faces, faces);
341 auto fit = faces.begin();
342 for (; fit != faces.end(); ++fit) {
343 tets = intersect(get_adj(
Range(*fit, *fit), 3), all_tets);
344 if (tets.size() == 2) {
351 saids.first.insert(tets[0]);
352 saids.first = grow(saids.first);
353 all_tets = subtract(all_tets, saids.first);
354 if (tets.size() == 2) {
355 saids.second.insert(tets[1]);
356 saids.second = grow(saids.second);
357 all_tets = subtract(all_tets, saids.second);
365 saids.first = subtract(all_tets_ord, saids.second);
366 saids.second = subtract(all_tets_ord, saids.first);
372 std::pair<Range, Range> saids;
373 if (crack_faces.size())
378 MOFEM_LOG(
"EP", Sev::noisy) <<
"get_two_sides_of_crack_surface <- done";
380 return std::pair<Range, Range>();
394 boost::shared_ptr<Range> front_nodes,
395 boost::shared_ptr<Range> front_edges,
396 boost::shared_ptr<CGGUserPolynomialBase::CachePhi> cache_phi =
nullptr)
401 boost::shared_ptr<Range> front_nodes,
402 boost::shared_ptr<Range> front_edges,
FunRule fun_rule,
403 boost::shared_ptr<CGGUserPolynomialBase::CachePhi> cache_phi =
nullptr)
408 int order_col,
int order_data) {
411 constexpr bool debug =
false;
413 constexpr int numNodes = 4;
414 constexpr int numEdges = 6;
415 constexpr int refinementLevels = 6;
417 auto &m_field = fe_raw_ptr->
mField;
418 auto fe_ptr =
static_cast<Fe *
>(fe_raw_ptr);
421 auto set_base_quadrature = [&]() {
426 const int rule =
funRule(order_data);
427 const auto xiao_rule =
431 "Xiao--Gimbutas tetrahedron rule is available for polynomial "
432 "orders 0 to %d; requested %d",
435 if (xiao_rule->numBarycentricCoordinates != 4) {
437 "wrong number of tetrahedron barycentric coordinates");
440 const size_t nb_gauss_pts = xiao_rule->numPoints;
441 auto &gauss_pts = fe_ptr->gaussPts;
442 gauss_pts.resize(4, nb_gauss_pts,
false);
443 cblas_dcopy(nb_gauss_pts, &xiao_rule->points[1], 4, &gauss_pts(0, 0),
445 cblas_dcopy(nb_gauss_pts, &xiao_rule->points[2], 4, &gauss_pts(1, 0),
447 cblas_dcopy(nb_gauss_pts, &xiao_rule->points[3], 4, &gauss_pts(2, 0),
449 cblas_dcopy(nb_gauss_pts, xiao_rule->weights, 1, &gauss_pts(3, 0), 1);
450 auto &data = fe_ptr->dataOnElement[
H1];
451 data->dataOnEntities[MBVERTEX][0].getN(
NOBASE).resize(nb_gauss_pts, 4,
454 &*data->dataOnEntities[MBVERTEX][0].getN(
NOBASE).data().begin();
455 cblas_dcopy(4 * nb_gauss_pts, xiao_rule->points, 1, shape_ptr, 1);
459 CHKERR set_base_quadrature();
463 auto get_singular_nodes = [&]() {
465 const EntityHandle *conn;
466 CHKERR m_field.get_moab().get_connectivity(fe_handle, conn, num_nodes,
468 std::bitset<numNodes> singular_nodes;
469 for (
auto nn = 0; nn != numNodes; ++nn) {
471 singular_nodes.set(nn);
473 singular_nodes.reset(nn);
476 return singular_nodes;
479 auto get_singular_edges = [&]() {
480 std::bitset<numEdges> singular_edges;
481 for (
int ee = 0; ee != numEdges; ee++) {
483 CHKERR m_field.get_moab().side_element(fe_handle, 1, ee, edge);
485 singular_edges.set(ee);
487 singular_edges.reset(ee);
490 return singular_edges;
493 auto set_gauss_pts = [&](
auto &ref_gauss_pts) {
495 fe_ptr->gaussPts.swap(ref_gauss_pts);
496 const size_t nb_gauss_pts = fe_ptr->gaussPts.size2();
497 auto &data = fe_ptr->dataOnElement[
H1];
498 data->dataOnEntities[MBVERTEX][0].getN(
NOBASE).resize(nb_gauss_pts, 4);
500 &*data->dataOnEntities[MBVERTEX][0].getN(
NOBASE).data().begin();
502 &fe_ptr->gaussPts(1, 0), &fe_ptr->gaussPts(2, 0),
507 auto singular_nodes = get_singular_nodes();
508 if (singular_nodes.count()) {
509 auto it_map_ref_coords =
mapRefCoords.find(singular_nodes.to_ulong());
511 CHKERR set_gauss_pts(it_map_ref_coords->second);
515 auto refine_quadrature = [&]() {
518 const int max_level = refinementLevels;
522 double base_coords[] = {0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1};
523 EntityHandle nodes[4];
524 for (
int nn = 0; nn != 4; nn++)
525 CHKERR moab_ref.create_vertex(&base_coords[3 * nn], nodes[nn]);
526 CHKERR moab_ref.create_element(MBTET, nodes, 4, tet);
530 Range tets(tet, tet);
533 tets, 1,
true, edges, moab::Interface::UNION);
538 Range nodes_at_front;
539 for (
int nn = 0; nn != numNodes; nn++) {
540 if (singular_nodes[nn]) {
542 CHKERR moab_ref.side_element(tet, 0, nn, ent);
543 nodes_at_front.insert(ent);
547 auto singular_edges = get_singular_edges();
549 EntityHandle meshset;
550 CHKERR moab_ref.create_meshset(MESHSET_SET, meshset);
551 for (
int ee = 0; ee != numEdges; ee++) {
552 if (singular_edges[ee]) {
554 CHKERR moab_ref.side_element(tet, 1, ee, ent);
555 CHKERR moab_ref.add_entities(meshset, &ent, 1);
561 for (
int ll = 0; ll != max_level; ll++) {
564 ->getEntitiesByTypeAndRefLevel(
BitRefLevel().set(ll),
568 CHKERR moab_ref.get_adjacencies(
569 nodes_at_front, 1,
true, ref_edges, moab::Interface::UNION);
570 ref_edges = intersect(ref_edges, edges);
572 CHKERR moab_ref.get_entities_by_type(meshset, MBEDGE, ents,
true);
573 ref_edges = intersect(ref_edges, ents);
576 ->getEntitiesByTypeAndRefLevel(
578 CHKERR m_ref->addVerticesInTheMiddleOfEdges(
582 ->updateMeshsetByEntitiesChildren(meshset,
584 meshset, MBEDGE,
true);
590 ->getEntitiesByTypeAndRefLevel(
BitRefLevel().set(max_level),
600 for (Range::iterator tit = tets.begin(); tit != tets.end();
603 const EntityHandle *conn;
604 CHKERR moab_ref.get_connectivity(*tit, conn, num_nodes,
false);
605 CHKERR moab_ref.get_coords(conn, num_nodes, &ref_coords(tt, 0));
608 auto &data = fe_ptr->dataOnElement[
H1];
609 const size_t nb_gauss_pts = fe_ptr->gaussPts.size2();
610 MatrixDouble ref_gauss_pts(4, nb_gauss_pts * ref_coords.size1());
612 data->dataOnEntities[MBVERTEX][0].getN(
NOBASE);
614 for (
size_t tt = 0; tt != ref_coords.size1(); tt++) {
615 double *tet_coords = &ref_coords(tt, 0);
618 for (
size_t ggg = 0; ggg != nb_gauss_pts; ++ggg, ++gg) {
619 for (
int dd = 0; dd != 3; dd++) {
620 ref_gauss_pts(dd, gg) =
621 shape_n(ggg, 0) * tet_coords[3 * 0 + dd] +
622 shape_n(ggg, 1) * tet_coords[3 * 1 + dd] +
623 shape_n(ggg, 2) * tet_coords[3 * 2 + dd] +
624 shape_n(ggg, 3) * tet_coords[3 * 3 + dd];
626 ref_gauss_pts(3, gg) = fe_ptr->gaussPts(3, ggg) * det;
630 mapRefCoords[singular_nodes.to_ulong()].swap(ref_gauss_pts);
637 TetPolynomialBase::switchCacheBaseOff<HDIV>({fe_raw_ptr});
638 TetPolynomialBase::switchCacheBaseOn<HDIV>({fe_raw_ptr});
643 CHKERR refine_quadrature();
653 using ForcesAndSourcesCore::dataOnElement;
656 using ForcesAndSourcesCore::ForcesAndSourcesCore;
662 boost::shared_ptr<CGGUserPolynomialBase::CachePhi>
cachePhi;
670 boost::shared_ptr<Range> front_edges)
674 boost::shared_ptr<Range> front_edges,
679 int order_col,
int order_data) {
682 constexpr bool debug =
false;
684 constexpr int numNodes = 3;
685 constexpr int numEdges = 3;
686 constexpr int refinementLevels = 6;
688 auto &m_field = fe_raw_ptr->
mField;
689 auto fe_ptr =
static_cast<Fe *
>(fe_raw_ptr);
692 auto set_base_quadrature = [&]() {
698 "Xiao--Gimbutas triangle rule is available for polynomial "
699 "orders 0 to %d; requested %d",
702 if (xiao_rule->numBarycentricCoordinates != 3) {
704 "wrong number of triangle barycentric coordinates");
707 const size_t nb_gauss_pts = xiao_rule->numPoints;
708 auto &gauss_pts = fe_ptr->gaussPts;
709 gauss_pts.resize(3, nb_gauss_pts,
false);
710 cblas_dcopy(nb_gauss_pts, &xiao_rule->points[1], 3, &gauss_pts(0, 0),
712 cblas_dcopy(nb_gauss_pts, &xiao_rule->points[2], 3, &gauss_pts(1, 0),
714 cblas_dcopy(nb_gauss_pts, xiao_rule->weights, 1, &gauss_pts(2, 0), 1);
718 CHKERR set_base_quadrature();
722 auto get_singular_nodes = [&]() {
724 const EntityHandle *conn;
725 CHKERR m_field.get_moab().get_connectivity(fe_handle, conn, num_nodes,
727 std::bitset<numNodes> singular_nodes;
728 for (
auto nn = 0; nn != numNodes; ++nn) {
730 singular_nodes.set(nn);
732 singular_nodes.reset(nn);
735 return singular_nodes;
738 auto get_singular_edges = [&]() {
739 std::bitset<numEdges> singular_edges;
740 for (
int ee = 0; ee != numEdges; ee++) {
742 CHKERR m_field.get_moab().side_element(fe_handle, 1, ee, edge);
744 singular_edges.set(ee);
746 singular_edges.reset(ee);
749 return singular_edges;
752 auto set_gauss_pts = [&](
auto &ref_gauss_pts) {
754 fe_ptr->gaussPts.swap(ref_gauss_pts);
758 auto singular_nodes = get_singular_nodes();
759 if (singular_nodes.count()) {
760 auto it_map_ref_coords =
mapRefCoords.find(singular_nodes.to_ulong());
762 CHKERR set_gauss_pts(it_map_ref_coords->second);
766 auto refine_quadrature = [&]() {
769 const int max_level = refinementLevels;
772 double base_coords[] = {0, 0, 0, 1, 0, 0, 0, 1, 0};
773 EntityHandle nodes[numNodes];
774 for (
int nn = 0; nn != numNodes; nn++)
775 CHKERR moab_ref.create_vertex(&base_coords[3 * nn], nodes[nn]);
777 CHKERR moab_ref.create_element(MBTRI, nodes, numNodes, tri);
781 Range tris(tri, tri);
784 tris, 1,
true, edges, moab::Interface::UNION);
789 Range nodes_at_front;
790 for (
int nn = 0; nn != numNodes; nn++) {
791 if (singular_nodes[nn]) {
793 CHKERR moab_ref.side_element(tri, 0, nn, ent);
794 nodes_at_front.insert(ent);
798 auto singular_edges = get_singular_edges();
800 EntityHandle meshset;
801 CHKERR moab_ref.create_meshset(MESHSET_SET, meshset);
802 for (
int ee = 0; ee != numEdges; ee++) {
803 if (singular_edges[ee]) {
805 CHKERR moab_ref.side_element(tri, 1, ee, ent);
806 CHKERR moab_ref.add_entities(meshset, &ent, 1);
812 for (
int ll = 0; ll != max_level; ll++) {
815 ->getEntitiesByTypeAndRefLevel(
BitRefLevel().set(ll),
819 CHKERR moab_ref.get_adjacencies(
820 nodes_at_front, 1,
true, ref_edges, moab::Interface::UNION);
821 ref_edges = intersect(ref_edges, edges);
823 CHKERR moab_ref.get_entities_by_type(meshset, MBEDGE, ents,
true);
824 ref_edges = intersect(ref_edges, ents);
827 ->getEntitiesByTypeAndRefLevel(
829 CHKERR m_ref->addVerticesInTheMiddleOfEdges(
833 ->updateMeshsetByEntitiesChildren(meshset,
835 meshset, MBEDGE,
true);
841 ->getEntitiesByTypeAndRefLevel(
BitRefLevel().set(max_level),
852 for (Range::iterator tit = tris.begin(); tit != tris.end();
855 const EntityHandle *conn;
856 CHKERR moab_ref.get_connectivity(*tit, conn, num_nodes,
false);
857 CHKERR moab_ref.get_coords(conn, num_nodes, &ref_coords(tt, 0));
860 const size_t nb_gauss_pts = fe_ptr->gaussPts.size2();
861 MatrixDouble ref_gauss_pts(3, nb_gauss_pts * ref_coords.size1());
864 &fe_ptr->gaussPts(1, 0), nb_gauss_pts);
866 for (
size_t tt = 0; tt != ref_coords.size1(); tt++) {
867 double *tri_coords = &ref_coords(tt, 0);
870 auto det = t_normal.
l2();
871 for (
size_t ggg = 0; ggg != nb_gauss_pts; ++ggg, ++gg) {
872 for (
int dd = 0; dd != 2; dd++) {
873 ref_gauss_pts(dd, gg) =
874 shape_n(ggg, 0) * tri_coords[3 * 0 + dd] +
875 shape_n(ggg, 1) * tri_coords[3 * 1 + dd] +
876 shape_n(ggg, 2) * tri_coords[3 * 2 + dd];
878 ref_gauss_pts(2, gg) = fe_ptr->gaussPts(2, ggg) * det;
882 mapRefCoords[singular_nodes.to_ulong()].swap(ref_gauss_pts);
888 CHKERR refine_quadrature();
898 using ForcesAndSourcesCore::dataOnElement;
901 using ForcesAndSourcesCore::ForcesAndSourcesCore;
949 const char *list_rots[] = {
"small",
"moderate",
"large",
"no_h1"};
950 const char *list_release[] = {
"griffith_force",
"griffith_skeleton"};
951 const char *list_stretches[] = {
"linear",
"log",
"log_quadratic"};
952 const char *list_broken_hdiv_bases[] = {
"demkowicz",
"ainsworth"};
956 PetscInt choice_stretch = StretchSelector::LOG;
958 PetscInt choice_broken_hdiv_base = 0;
959 PetscBool l2_user_base_scale_set = PETSC_FALSE;
962 choice_broken_hdiv_base = 0;
965 choice_broken_hdiv_base = 1;
969 "Unsupported broken HDIV base %s",
972 char analytical_expr_file_name[255] =
"analytical_expr.py";
973 PetscBool no_stretch =
isNoStretch() ? PETSC_TRUE : PETSC_FALSE;
975 PetscOptionsBegin(PETSC_COMM_WORLD,
"",
"Eshelbian plasticity",
"none");
976 CHKERR PetscOptionsInt(
"-space_order",
"approximation oder for space",
"",
978 CHKERR PetscOptionsInt(
"-space_h1_order",
"approximation oder for space",
"",
980 CHKERR PetscOptionsInt(
"-material_order",
"approximation oder for material",
982 CHKERR PetscOptionsScalar(
"-viscosity_alpha_u",
"viscosity",
"",
alphaU,
984 CHKERR PetscOptionsScalar(
"-viscosity_alpha_w",
"viscosity",
"",
alphaW,
988 CHKERR PetscOptionsScalar(
"-alpha_omega0",
"rot H1 penalty scaled by |M0|",
992 CHKERR PetscOptionsScalar(
"-alpha_r0",
"rot L2 penalty scaled by |M0|",
"",
994 CHKERR PetscOptionsScalar(
"-viscosity_alpha_omega",
"rot viscosity",
"",
997 CHKERR PetscOptionsScalar(
"-viscosity_alpha_omega0",
998 "rot viscosity scaled by |M0|",
"",
1001 CHKERR PetscOptionsScalar(
"-viscosity_alpha_r",
"rot L2 viscosity",
"",
1003 CHKERR PetscOptionsScalar(
"-viscosity_alpha_r0",
1004 "rot L2 viscosity scaled by |M0|",
"",
1006 CHKERR PetscOptionsScalar(
"-density_alpha_rho",
"density",
"",
alphaRho,
1012 CHKERR PetscOptionsScalar(
"-alpha_tau_bc_disp",
"tau for displacement BC",
"",
1014 CHKERR PetscOptionsScalar(
"-alpha_tau0_bc_disp",
1017 CHKERR PetscOptionsEList(
"-rotations",
"rotations",
"", list_rots,
1018 LARGE_ROT + 1, list_rots[choice_rot], &choice_rot,
1020 CHKERR PetscOptionsEList(
"-grad",
"gradient of defamation approximate",
"",
1021 list_rots, NO_H1_CONFIGURATION + 1,
1022 list_rots[choice_grad], &choice_grad, PETSC_NULLPTR);
1024 CHKERR PetscOptionsEList(
"-stretches",
"stretches",
"", list_stretches,
1025 StretchSelector::STRETCH_SELECTOR_LAST,
1026 list_stretches[choice_stretch], &choice_stretch,
1029 CHKERR PetscOptionsBool(
"-no_stretch",
"do not solve for stretch",
"",
1030 no_stretch, &no_stretch, PETSC_NULLPTR);
1031 CHKERR PetscOptionsBool(
"-set_singularity",
"set singularity",
"",
1033 CHKERR PetscOptionsBool(
"-l2_user_base_scale",
"streach scale",
"",
1035 &l2_user_base_scale_set);
1036 CHKERR PetscOptionsEList(
1037 "-broken_hdiv_base",
"broken HDIV stress approximation base",
"",
1038 list_broken_hdiv_bases, 2,
1039 list_broken_hdiv_bases[choice_broken_hdiv_base],
1040 &choice_broken_hdiv_base, PETSC_NULLPTR);
1045 CHKERR PetscOptionsBool(
"-dynamic_relaxation",
"dynamic time relaxation",
"",
1047 CHKERR PetscOptionsEList(
1053 CHKERR PetscOptionsScalar(
"-physical_final_time",
"physical final time",
"",
1056 CHKERR PetscOptionsScalar(
"-physical_delta_time",
"physical delta time",
"",
1059 CHKERR PetscOptionsInt(
"-physical_max_steps",
"physical max iterations",
"",
1063 "-physical_h1_update",
"update each physicalsolver step",
"",
1068 CHKERR PetscOptionsInt(
"-contact_max_post_proc_ref_level",
"refinement level",
1072 CHKERR PetscOptionsBool(
"-cohesive_interface_on",
"cohesive interface ON",
"",
1075 "-cohesive_interface_remove_level",
"cohesive interface remove level",
"",
1081 CHKERR PetscOptionsScalar(
"-cracking_add_time",
"cracking add time",
"",
1083 CHKERR PetscOptionsScalar(
"-cracking_start_time",
"cracking start time",
"",
1086 CHKERR PetscOptionsScalar(
"-griffith_energy",
"Griffith energy",
"",
1089 CHKERR PetscOptionsScalar(
"-cracking_rtol",
"Cracking relative tolerance",
"",
1091 CHKERR PetscOptionsScalar(
"-cracking_atol",
"Cracking absolute tolerance",
"",
1093 CHKERR PetscOptionsEList(
"-energy_release_variant",
"energy release variant",
1094 "", list_release, 2, list_release[choice_release],
1095 &choice_release, PETSC_NULLPTR);
1096 CHKERR PetscOptionsInt(
"-nb_J_integral_levels",
"Number of J integarl levels",
1100 "-nb_J_integral_contours",
"Number of J integral contours",
"",
1104 char tag_name[255] =
"";
1105 CHKERR PetscOptionsString(
"-internal_stress_tag_name",
1106 "internal stress tag name",
"",
"", tag_name, 255,
1109 CHKERR PetscOptionsBool(
"-internal_stress_voigt",
"Voigt index notation",
"",
1114 char tag_heterogeneous_youngs_modulus_name[255] =
"";
1115 CHKERR PetscOptionsString(
1116 "-heterogeneous_youngs_modulus",
"heterogeneous Young's modulus tag name",
1117 "",
"", tag_heterogeneous_youngs_modulus_name, 255, PETSC_NULLPTR);
1120 PetscBool has_analytical_expr_file_option = PETSC_FALSE;
1122 PETSC_NULLPTR, PETSC_NULLPTR,
"-analytical_expr_file",
1123 analytical_expr_file_name, 255, &has_analytical_expr_file_option);
1124 if (!has_analytical_expr_file_option) {
1125 const auto analytical_expr_script =
1128 if (!analytical_expr_script.empty()) {
1129 CHKERR PetscStrncpy(analytical_expr_file_name,
1130 analytical_expr_script.c_str(),
1131 sizeof(analytical_expr_file_name));
1133 <<
"Using Python script 'analytical_expr' from JSON config: "
1134 << analytical_expr_file_name;
1143 PetscOptionsBegin(PETSC_COMM_WORLD,
"mesh_transfer_",
"mesh data transfer",
1145 char tag_mesh_transfer_source_file_name[255] =
"";
1146 CHKERR PetscOptionsString(
"-source_file",
"source mesh file name",
"",
1147 "source.h5m", tag_mesh_transfer_source_file_name,
1150 CHKERR PetscOptionsInt(
"-interp_order",
"interpolation order",
"", 0,
1152 CHKERR PetscOptionsBool(
"-hybrid_interp",
"use hybrid interpolation",
"",
1159 "Unsupported mesh transfer interpolation order %d",
1178 static_cast<EnergyReleaseSelector
>(choice_release);
1179 switch (choice_broken_hdiv_base) {
1188 "Unknown broken HDIV base option");
1192 case StretchSelector::LINEAR:
1200 case StretchSelector::LOG:
1208 case StretchSelector::LOG_QUADRATIC:
1224 <<
"-dynamic_relaxation option is deprecated, use -solver_type "
1225 "dynamic_relaxation instead.";
1229 switch (choice_solver) {
1262 const auto yes_no = [](
auto flag) {
return flag ?
"yes" :
"no"; };
1269 MOFEM_LOG(
"EP", Sev::inform) <<
"alphaU: -viscosity_alpha_u " <<
alphaU;
1270 MOFEM_LOG(
"EP", Sev::inform) <<
"alphaW: -viscosity_alpha_w " <<
alphaW;
1277 <<
"alphaViscousOmega: -viscosity_alpha_omega "
1280 <<
"alphaViscousOmega0: -viscosity_alpha_omega0 "
1295 MOFEM_LOG(
"EP", Sev::inform) <<
"Gradient of deformation: -grad "
1298 <<
"Stretch: -stretches " << list_stretches[choice_stretch];
1300 <<
"No stretch: -no_stretch "
1304 <<
"Dynamic relaxation: -dynamic_relaxation "
1305 << yes_no(dynamic_relaxation_option);
1306 MOFEM_LOG(
"EP", Sev::inform) <<
"Solver type: -solver_type "
1312 <<
"Physical delta time: -physical_delta_time " <<
physicalDt;
1316 <<
"Physical H1 update: -physical_h1_update "
1322 <<
"L2 user base scale: -l2_user_base_scale "
1323 << yes_no(l2_user_base_scale_option);
1326 <<
"Effective L2 user base scale after option processing "
1330 <<
"Broken HDIV base: -broken_hdiv_base "
1331 << list_broken_hdiv_bases[choice_broken_hdiv_base];
1333 <<
"Contact max post-proc ref level: -contact_max_post_proc_ref_level "
1337 <<
"Cracking on: -cracking_on " << yes_no(
crackingOn);
1345 <<
"Cracking relative tolerance: -cracking_rtol " <<
crackingRtol;
1347 <<
"Cracking absolute tolerance: -cracking_atol " <<
crackingAtol;
1349 <<
"Energy release variant: -energy_release_variant "
1352 <<
"Number of J integral contours: -nb_J_integral_contours / "
1353 "-nb_J_integral_levels "
1356 <<
"Cohesive interface on: -cohesive_interface_on "
1359 <<
"Cohesive interface remove level: -cohesive_interface_remove_level "
1362 <<
"Internal stress tag name: -internal_stress_tag_name "
1365 <<
"Internal stress Voigt notation: -internal_stress_voigt "
1368 <<
"Heterogeneous Young's modulus: -heterogeneous_youngs_modulus "
1371 <<
"Analytical expression file: -analytical_expr_file "
1372 << analytical_expr_file_name;
1375 <<
"Mesh transfer source file: -mesh_transfer_source_file "
1379 <<
"Mesh transfer source file: -mesh_transfer_source_file <not set>";
1382 <<
"Mesh transfer interpolation order: -mesh_transfer_interp_order "
1385 <<
"Mesh transfer hybrid interpolation: -mesh_transfer_hybrid_interp "
1388#ifdef ENABLE_PYTHON_BINDING
1389 auto file_exists = [](std::string myfile) {
1390 std::ifstream file(myfile.c_str());
1397 if (file_exists(analytical_expr_file_name)) {
1398 MOFEM_LOG(
"EP", Sev::inform) << analytical_expr_file_name <<
" file found";
1402 analytical_expr_file_name);
1406 << analytical_expr_file_name <<
" file NOT found";
1417 const bool add_bubble) {
1420 auto get_tets = [&]() {
1426 auto get_tets_skin = [&]() {
1427 Range tets_skin_part;
1429 CHKERR skin.find_skin(0, get_tets(),
false, tets_skin_part);
1430 ParallelComm *pcomm =
1433 CHKERR pcomm->filter_pstatus(tets_skin_part,
1434 PSTATUS_SHARED | PSTATUS_MULTISHARED,
1435 PSTATUS_NOT, -1, &tets_skin);
1439 auto subtract_boundary_conditions = [&](
auto &&tets_skin) {
1445 tets_skin = subtract(tets_skin,
v.faces);
1450 tets_skin = subtract(tets_skin,
v.faces);
1455 tets_skin = subtract(tets_skin,
v.faces);
1460 tets_skin = subtract(tets_skin,
v.faces);
1466 auto add_blockset = [&](
auto block_name,
auto &&tets_skin) {
1469 tets_skin.merge(crack_faces);
1473 auto subtract_blockset = [&](
auto block_name,
auto &&tets_skin) {
1474 auto contact_range =
1476 tets_skin = subtract(tets_skin, contact_range);
1480 auto get_stress_trace_faces = [&](
auto &&tets_skin) {
1483 faces, moab::Interface::UNION);
1484 Range trace_faces = subtract(faces, tets_skin);
1488 auto tets = get_tets();
1492 auto trace_faces = get_stress_trace_faces(
1494 subtract_blockset(
"CONTACT",
1495 subtract_boundary_conditions(get_tets_skin()))
1502 boost::make_shared<Range>(subtract(trace_faces, *
contactFaces));
1520 auto add_broken_hdiv_field = [
this, meshset, broken_hdiv_base](
1527 auto get_side_map_hdiv = [&]() {
1530 std::pair<EntityType,
1545 get_side_map_hdiv(), MB_TAG_DENSE,
MF_ZERO);
1551 auto add_l2_field = [
this, meshset](
const std::string
field_name,
1552 const int order,
const int dim) {
1561 auto add_h1_field = [
this, meshset](
const std::string
field_name,
1562 const int order,
const int dim) {
1574 auto add_l2_field_by_range = [
this](
const std::string
field_name,
1575 const int order,
const int dim,
1576 const int field_dim,
Range &&r) {
1586 auto add_bubble_field = [
this, meshset](
const std::string
field_name,
1587 const int order,
const int dim) {
1593 auto field_order_table =
1594 const_cast<Field *
>(field_ptr)->getFieldOrderTable();
1595 auto get_cgg_bubble_order_zero = [](
int p) {
return 0; };
1596 auto get_cgg_bubble_order_tet = [](
int p) {
1599 field_order_table[MBVERTEX] = get_cgg_bubble_order_zero;
1600 field_order_table[MBEDGE] = get_cgg_bubble_order_zero;
1601 field_order_table[MBTRI] = get_cgg_bubble_order_zero;
1602 field_order_table[MBTET] = get_cgg_bubble_order_tet;
1609 auto add_user_l2_field = [
this, meshset](
const std::string
field_name,
1610 const int order,
const int dim) {
1616 auto field_order_table =
1617 const_cast<Field *
>(field_ptr)->getFieldOrderTable();
1618 auto zero_dofs = [](
int p) {
return 0; };
1620 field_order_table[MBVERTEX] = zero_dofs;
1621 field_order_table[MBEDGE] = zero_dofs;
1622 field_order_table[MBTRI] = zero_dofs;
1623 field_order_table[MBTET] = dof_l2_tet;
1634 auto get_hybridised_disp = [&]() {
1636 auto skin = subtract_boundary_conditions(get_tets_skin());
1638 faces.merge(intersect(bc.faces, skin));
1642 faces.merge(intersect(bc.faces, skin));
1663 get_hybridised_disp());
1688 auto project_ho_geometry = [&](
auto field) {
1694 auto get_adj_front_edges = [&](
auto &front_edges) {
1695 Range front_crack_nodes;
1696 Range crack_front_edges_with_both_nodes_not_at_front;
1701 moab.get_connectivity(front_edges, front_crack_nodes,
true),
1702 "get_connectivity failed");
1703 Range crack_front_edges;
1705 false, crack_front_edges,
1706 moab::Interface::UNION),
1707 "get_adjacencies failed");
1708 Range crack_front_edges_nodes;
1710 crack_front_edges_nodes,
true),
1711 "get_connectivity failed");
1713 crack_front_edges_nodes =
1714 subtract(crack_front_edges_nodes, front_crack_nodes);
1715 Range crack_front_edges_with_both_nodes_not_at_front;
1717 moab.get_adjacencies(crack_front_edges_nodes, 1,
false,
1718 crack_front_edges_with_both_nodes_not_at_front,
1719 moab::Interface::UNION),
1720 "get_adjacencies failed");
1722 crack_front_edges_with_both_nodes_not_at_front = intersect(
1723 crack_front_edges, crack_front_edges_with_both_nodes_not_at_front);
1727 crack_front_edges_with_both_nodes_not_at_front =
send_type(
1728 mField, crack_front_edges_with_both_nodes_not_at_front, MBEDGE);
1730 return std::make_pair(boost::make_shared<Range>(front_crack_nodes),
1731 boost::make_shared<Range>(
1732 crack_front_edges_with_both_nodes_not_at_front));
1735 if ((time -
crackingAddTime) > std::numeric_limits<double>::epsilon()) {
1743 auto [front_vertices, front_adj_edges] = get_adj_front_edges(*
frontEdges);
1748 <<
"Number of crack faces: " <<
crackFaces->size();
1750 <<
"Number of front edges: " <<
frontEdges->size();
1754 <<
"Number of front adjacent edges: " <<
frontAdjEdges->size();
1763 (boost::format(
"crack_faces_%d.vtk") % rank).str(),
1766 (boost::format(
"front_edges_%d.vtk") % rank).str(),
1777 auto set_singular_dofs = [&](
auto &front_adj_edges,
auto &front_vertices) {
1785 MOFEM_LOG(
"EP", Sev::inform) <<
"Singularity eps " << beta;
1790 [&](boost::shared_ptr<FieldEntity> field_entity_ptr) ->
MoFEMErrorCode {
1795 auto nb_dofs = field_entity_ptr->getEntFieldData().size();
1801 if (field_entity_ptr->getNbOfCoeffs() != 3)
1803 "Expected 3 coefficients per edge");
1804 if (nb_dofs % 3 != 0)
1806 "Expected multiple of 3 coefficients per edge");
1809 auto get_conn = [&]() {
1811 const EntityHandle *conn;
1812 CHKERR moab.get_connectivity(field_entity_ptr->getEnt(), conn,
1814 return std::make_pair(conn, num_nodes);
1817 auto get_dir = [&](
auto &&conn_p) {
1818 auto [conn, num_nodes] = conn_p;
1820 CHKERR moab.get_coords(conn, num_nodes, coords);
1822 coords[4] - coords[1],
1823 coords[5] - coords[2]};
1827 auto get_singularity_dof = [&](
auto &&conn_p,
auto &&t_edge_dir) {
1828 auto [conn, num_nodes] = conn_p;
1830 if (front_vertices.find(conn[0]) != front_vertices.end()) {
1831 t_singularity_dof(
i) = t_edge_dir(
i) * (-
eps);
1832 }
else if (front_vertices.find(conn[1]) != front_vertices.end()) {
1833 t_singularity_dof(
i) = t_edge_dir(
i) *
eps;
1835 return t_singularity_dof;
1838 auto t_singularity_dof =
1839 get_singularity_dof(get_conn(), get_dir(get_conn()));
1841 auto field_data = field_entity_ptr->getEntFieldData();
1843 &field_data[0], &field_data[1], &field_data[2]};
1845 t_dof(
i) = t_singularity_dof(
i);
1847 for (
auto n = 1;
n < field_data.size() / 3; ++
n) {
1869 auto get_interface_from_block = [&](
auto block_name) {
1874 faces, moab::Interface::UNION);
1875 faces = subtract(faces, skin);
1877 <<
"Number of vol interface elements: " << vol_eles.size()
1878 <<
" and faces: " << faces.size();
1882 interfaceFaces->merge(get_interface_from_block(
"VOLUME_INTERFACE"));
1884 auto remove_interface_from_block = [&](
auto block_name,
auto level) {
1886 Range intreface_faces;
1889 for (
auto l = 0;
l < level; ++
l) {
1892 ents,
SPACE_DIM,
true, adj_tets, moab::Interface::UNION);
1893 Range adj_tets_faces;
1896 moab::Interface::UNION);
1897 ents.merge(adj_tets_faces);
1899 auto faces = ents.subset_by_dimension(
SPACE_DIM - 1);
1902 <<
"Removed ents " << faces.size()
1907 <<
"Interface faces after remove " << intreface_faces;
1909 auto intreface_faces_global =
send_type(
mField, intreface_faces, MBTRI);
1920#ifdef INCLUDE_MBCOUPLER
1922 double toler = 5.e-10;
1927 <<
"No source mesh specified. Skipping projection";
1934 MOFEM_LOG(
"WORLD", Sev::verbose) <<
"Interpolation Young's modulus tag name: "
1938 MOFEM_LOG(
"WORLD", Sev::verbose) <<
"Using hybrid interpolation: "
1946 auto rval_check_tag = moab.tag_get_handle(tag_name.c_str(), old_interp_tag);
1947 if (rval_check_tag == MB_SUCCESS) {
1949 <<
"Deleting existing tag on target mesh: " << tag_name;
1950 CHKERR moab.tag_delete(old_interp_tag);
1954 int world_rank = -1, world_size = -1;
1955 MPI_Comm_rank(PETSC_COMM_WORLD, &world_rank);
1956 MPI_Comm_size(PETSC_COMM_WORLD, &world_size);
1958 Range original_meshset_ents;
1959 CHKERR moab.get_entities_by_handle(0, original_meshset_ents);
1961 MPI_Comm comm_coupler;
1962 if (world_rank == 0) {
1963 MPI_Comm_split(PETSC_COMM_WORLD, 0, 0, &comm_coupler);
1965 MPI_Comm_split(PETSC_COMM_WORLD, MPI_UNDEFINED, world_rank, &comm_coupler);
1969 ParallelComm *pcomm0 =
nullptr;
1971 if (world_rank == 0) {
1972 pcomm0 =
new ParallelComm(&moab, comm_coupler, &pcomm0_id);
1975 Coupler::Method method;
1978 method = Coupler::CONSTANT;
1981 method = Coupler::LINEAR_FE;
1985 "Unsupported interpolation order");
1989 ierr = MPI_Comm_size(PETSC_COMM_WORLD, &nprocs);
1991 ierr = MPI_Comm_rank(PETSC_COMM_WORLD, &rank);
2002 EntityHandle target_root;
2003 CHKERR moab.create_meshset(MESHSET_SET, target_root);
2005 <<
"Creating target mesh from existing meshset";
2006 Range target_meshset_ents;
2007 CHKERR moab.get_entities_by_handle(0, target_meshset_ents);
2008 CHKERR moab.add_entities(target_root, target_meshset_ents);
2011 std::vector<Tag> interp_tags;
2012 std::vector<int> tag_length;
2013 std::vector<DataType> dtype;
2014 std::vector<TagType> storage;
2017 Range targ_verts, targ_elems;
2018 if (world_rank == 0) {
2019 EntityHandle source_root;
2020 CHKERR moab.create_meshset(MESHSET_SET, source_root);
2022 MOFEM_LOG(
"WORLD", Sev::inform) <<
"Loading source mesh on rank 0";
2023 auto rval_source_mesh = moab.load_file(
2025 if (rval_source_mesh != MB_SUCCESS) {
2026 MOFEM_LOG(
"WORLD", Sev::warning) <<
"Error loading source mesh file: "
2029 MOFEM_LOG(
"WORLD", Sev::inform) <<
"Source mesh loaded.";
2032 CHKERR moab.get_entities_by_dimension(source_root, 3, src_elems);
2034 EntityHandle part_set;
2035 CHKERR pcomm0->create_part(part_set);
2036 CHKERR moab.add_entities(part_set, src_elems);
2038 Range src_elems_part;
2039 CHKERR pcomm0->get_part_entities(src_elems_part, 3);
2042 std::string tag_to_use = iterp_tag_name;
2045 CHKERR moab.tag_get_handle(tag_to_use.c_str(), interp_tag);
2048 CHKERR moab.tag_get_length(interp_tag, interp_tag_len);
2050 if (interp_tag_len != 1 && interp_tag_len != 3 && interp_tag_len != 9) {
2052 "Unsupported interpolation tag length: %d", interp_tag_len);
2056 tag_length.push_back(interp_tag_len);
2057 dtype.push_back(DataType());
2058 storage.push_back(TagType());
2059 interp_tags.push_back(interp_tag);
2060 CHKERR moab.tag_get_data_type(interp_tag, dtype.back());
2061 CHKERR moab.tag_get_type(interp_tag, storage.back());
2064 Coupler mbc(&moab, pcomm0, src_elems_part, 0,
true);
2066 std::vector<double> vpos;
2072 CHKERR moab.get_entities_by_dimension(target_root, 3, targ_elems);
2075 targ_verts = targ_elems;
2077 CHKERR moab.get_adjacencies(targ_elems, 0,
false, targ_verts,
2078 moab::Interface::UNION);
2082 CHKERR pcomm0->get_pstatus_entities(0, PSTATUS_NOT_OWNED, tmp_verts);
2083 targ_verts = subtract(targ_verts, tmp_verts);
2086 num_pts = (int)targ_verts.size();
2087 vpos.resize(3 * targ_verts.size());
2088 CHKERR moab.get_coords(targ_verts, &vpos[0]);
2091 boost::shared_ptr<TupleList> tl_ptr;
2092 tl_ptr = boost::make_shared<TupleList>();
2093 CHKERR mbc.locate_points(&vpos[0], num_pts, 0, toler, tl_ptr.get(),
2097 auto find_missing_points = [&](
Range &targ_verts,
int &num_pts,
2098 std::vector<double> &vpos,
2099 Range &missing_verts) {
2101 int missing_pts_num = 0;
2103 auto vit = targ_verts.begin();
2104 for (; vit != targ_verts.end();
i++) {
2105 if (tl_ptr->vi_rd[3 *
i + 1] == -1) {
2106 missing_verts.insert(*vit);
2107 vit = targ_verts.erase(vit);
2114 int missing_pts_num_global = 0;
2117 if (missing_pts_num_global) {
2119 << missing_pts_num_global
2120 <<
" points in target mesh were not located in source mesh. ";
2123 if (missing_pts_num) {
2124 num_pts = (int)targ_verts.size();
2125 vpos.resize(3 * targ_verts.size());
2126 CHKERR moab.get_coords(targ_verts, &vpos[0]);
2128 CHKERR mbc.locate_points(&vpos[0], num_pts, 0, toler, tl_ptr.get(),
2134 Range missing_verts;
2135 CHKERR find_missing_points(targ_verts, num_pts, vpos, missing_verts);
2137 std::vector<double> source_data(interp_tag_len * src_elems.size(), 0.0);
2138 std::vector<double> target_data(interp_tag_len * num_pts, 0.0);
2140 CHKERR moab.tag_get_data(interp_tag, src_elems, &source_data[0]);
2142 Tag scalar_tag, adj_count_tag;
2144 string scalar_tag_name = string(tag_to_use) +
"_COMP";
2145 CHKERR moab.tag_get_handle(scalar_tag_name.c_str(), 1, MB_TYPE_DOUBLE,
2146 scalar_tag, MB_TAG_CREAT | MB_TAG_DENSE,
2149 string adj_count_tag_name =
"ADJ_COUNT";
2151 CHKERR moab.tag_get_handle(adj_count_tag_name.c_str(), 1, MB_TYPE_DOUBLE,
2152 adj_count_tag, MB_TAG_CREAT | MB_TAG_DENSE,
2157 auto create_scalar_tags = [&](
const Range &src_elems,
2158 const std::vector<double> &source_data,
2162 std::vector<double> source_data_scalar(src_elems.size());
2164 for (
int ielem = 0; ielem < src_elems.size(); ielem++) {
2165 source_data_scalar[ielem] =
2166 source_data[itag + ielem * interp_tag_len];
2170 CHKERR moab.tag_set_data(scalar_tag, src_elems, &source_data_scalar[0]);
2175 CHKERR moab.get_connectivity(src_elems, src_verts,
true);
2177 CHKERR moab.tag_clear_data(scalar_tag, src_verts, &def_scl);
2178 CHKERR moab.tag_clear_data(adj_count_tag, src_verts, &def_adj);
2180 for (
auto &tet : src_elems) {
2181 double tet_data = 0;
2182 CHKERR moab.tag_get_data(scalar_tag, &tet, 1, &tet_data);
2185 CHKERR moab.get_connectivity(&tet, 1, adj_verts,
true);
2187 std::vector<double> adj_vert_data(adj_verts.size(), 0.0);
2188 std::vector<double> adj_vert_count(adj_verts.size(), 0.0);
2190 CHKERR moab.tag_get_data(scalar_tag, adj_verts, &adj_vert_data[0]);
2191 CHKERR moab.tag_get_data(adj_count_tag, adj_verts,
2192 &adj_vert_count[0]);
2194 for (
int ivert = 0; ivert < adj_verts.size(); ivert++) {
2195 adj_vert_data[ivert] += tet_data;
2196 adj_vert_count[ivert] += 1;
2199 CHKERR moab.tag_set_data(scalar_tag, adj_verts, &adj_vert_data[0]);
2200 CHKERR moab.tag_set_data(adj_count_tag, adj_verts,
2201 &adj_vert_count[0]);
2205 std::vector<Tag> tags = {scalar_tag, adj_count_tag};
2206 pcomm0->reduce_tags(tags, tags, MPI_SUM, src_verts);
2208 std::vector<double> src_vert_data(src_verts.size(), 0.0);
2209 std::vector<double> src_vert_adj_count(src_verts.size(), 0.0);
2211 CHKERR moab.tag_get_data(scalar_tag, src_verts, &src_vert_data[0]);
2212 CHKERR moab.tag_get_data(adj_count_tag, src_verts,
2213 &src_vert_adj_count[0]);
2215 for (
int ivert = 0; ivert < src_verts.size(); ivert++) {
2216 src_vert_data[ivert] /= src_vert_adj_count[ivert];
2218 CHKERR moab.tag_set_data(scalar_tag, src_verts, &src_vert_data[0]);
2224 <<
"Performing interpolation for tag: " << tag_to_use;
2226 <<
"Number of target points to interpolate: " << num_pts;
2228 <<
"Interpolation method: "
2229 << (method == Coupler::CONSTANT ?
"constant" :
"linear FE");
2231 <<
"Number of components in tag: " << interp_tag_len;
2234 <<
"Source tag data range: ["
2235 << *std::min_element(source_data.begin(), source_data.end()) <<
", "
2236 << *std::max_element(source_data.begin(), source_data.end()) <<
"]";
2238 for (
int itag = 0; itag < interp_tag_len; itag++) {
2240 CHKERR create_scalar_tags(src_elems, source_data, itag);
2242 std::vector<double> target_data_scalar(num_pts, 0.0);
2243 CHKERR mbc.interpolate(method, scalar_tag_name, &target_data_scalar[0],
2246 for (
int ielem = 0; ielem < num_pts; ielem++) {
2247 target_data[itag + ielem * interp_tag_len] =
2248 target_data_scalar[ielem];
2253 CHKERR moab.tag_set_data(interp_tag, targ_verts, &target_data[0]);
2258 <<
"Using hybrid interpolation for "
2259 "missing points in the target mesh.";
2260 Range missing_adj_elems;
2261 CHKERR moab.get_adjacencies(missing_verts, 3,
false, missing_adj_elems,
2262 moab::Interface::UNION);
2264 int num_adj_elems = (int)missing_adj_elems.size();
2265 std::vector<double> vpos_adj_elems;
2267 vpos_adj_elems.resize(3 * missing_adj_elems.size());
2268 CHKERR moab.get_coords(missing_adj_elems, &vpos_adj_elems[0]);
2272 CHKERR mbc.locate_points(&vpos_adj_elems[0], num_adj_elems, 0, toler,
2273 tl_ptr.get(),
false);
2276 CHKERR find_missing_points(missing_adj_elems, num_adj_elems,
2277 vpos_adj_elems, missing_tets);
2278 if (missing_tets.size()) {
2280 << missing_tets.size()
2281 <<
" points in target mesh were not located in source mesh. ";
2284 std::vector<double> target_data_adj_elems(
2285 interp_tag_len * num_adj_elems, 0.0);
2287 for (
int itag = 0; itag < interp_tag_len; itag++) {
2288 CHKERR create_scalar_tags(src_elems, source_data, itag);
2290 std::vector<double> target_data_adj_elems_scalar(num_adj_elems, 0.0);
2291 CHKERR mbc.interpolate(method, scalar_tag_name,
2292 &target_data_adj_elems_scalar[0],
2295 for (
int ielem = 0; ielem < num_adj_elems; ielem++) {
2296 target_data_adj_elems[itag + ielem * interp_tag_len] =
2297 target_data_adj_elems_scalar[ielem];
2301 CHKERR moab.tag_set_data(interp_tag, missing_adj_elems,
2302 &target_data_adj_elems[0]);
2305 for (
auto &vert : missing_verts) {
2307 CHKERR moab.get_adjacencies(&vert, 1, 3,
false, adj_elems,
2308 moab::Interface::UNION);
2310 std::vector<double> adj_elems_data(adj_elems.size() * interp_tag_len,
2312 CHKERR moab.tag_get_data(interp_tag, adj_elems, &adj_elems_data[0]);
2314 std::vector<double> vert_data(interp_tag_len, 0.0);
2315 for (
int itag = 0; itag < interp_tag_len; itag++) {
2316 for (
int i = 0;
i < adj_elems.size();
i++) {
2317 vert_data[itag] += adj_elems_data[
i * interp_tag_len + itag];
2319 vert_data[itag] /= adj_elems.size();
2321 CHKERR moab.tag_set_data(interp_tag, &vert, 1, &vert_data[0]);
2325 CHKERR moab.tag_delete(scalar_tag);
2326 CHKERR moab.tag_delete(adj_count_tag);
2330 Range src_mesh_ents;
2331 CHKERR moab.get_entities_by_handle(source_root, src_mesh_ents);
2332 CHKERR moab.delete_entities(&source_root, 1);
2333 CHKERR moab.delete_entities(src_mesh_ents);
2334 CHKERR moab.delete_entities(&part_set, 1);
2338 int tag_size = tag_length.size();
2339 MPI_Bcast(&tag_size, 1, MPI_INT, 0, PETSC_COMM_WORLD);
2341 interp_tags.resize(tag_size);
2342 tag_length.resize(tag_size);
2343 dtype.resize(tag_size);
2344 storage.resize(tag_size);
2346 MPI_Bcast(interp_tags.data(), tag_size, MPI_INT, 0, PETSC_COMM_WORLD);
2347 MPI_Bcast(tag_length.data(), tag_size, MPI_INT, 0, PETSC_COMM_WORLD);
2348 MPI_Bcast(dtype.data(), tag_size, MPI_INT, 0, PETSC_COMM_WORLD);
2349 MPI_Bcast(storage.data(), tag_size, MPI_INT, 0, PETSC_COMM_WORLD);
2354 for (
size_t index = 0; index < interp_tags.size(); index++) {
2358 auto rval_check_tag =
2360 if (rval_check_tag == MB_SUCCESS) {
2362 <<
"Deleting existing tag on target mesh (post-projection): "
2364 CHKERR moab.tag_delete(old_interp_tag);
2369 MB_TAG_CREAT | storage[index];
2370 std::vector<double> def_val(tag_length[index], 0.);
2372 tag_length[index], dtype[index],
2373 interp_tag_all, flags, def_val.data());
2374 if (
rval != MB_SUCCESS && world_rank) {
2376 "Unable to create projection tag %s",
2380 MPI_Barrier(PETSC_COMM_WORLD);
2397 CHKERR moab.delete_entities(&target_root, 1);
2405 const bool add_bubble) {
2409 auto add_field_to_fe = [
this](
const std::string fe,
2449 auto set_fe_adjacency = [&](
auto fe_name) {
2452 boost::make_shared<ParentFiniteElementAdjacencyFunctionSkeleton<2>>(
2460 auto add_field_to_fe = [
this](
const std::string fe,
2474 Range natural_bc_elements;
2477 natural_bc_elements.merge(
v.faces);
2482 natural_bc_elements.merge(
v.faces);
2487 natural_bc_elements.merge(
v.faces);
2492 natural_bc_elements.merge(
v.faces);
2497 natural_bc_elements.merge(
v.faces);
2502 natural_bc_elements.merge(
v.faces);
2507 natural_bc_elements.merge(
v.faces);
2512 natural_bc_elements.merge(
v.faces);
2515 natural_bc_elements = intersect(natural_bc_elements, meshset_ents);
2526 auto get_skin = [&](
auto &body_ents) {
2529 CHKERR skin.find_skin(0, body_ents,
false, skin_ents);
2534 Range boundary_ents;
2535 ParallelComm *pcomm =
2537 CHKERR pcomm->filter_pstatus(skin, PSTATUS_SHARED | PSTATUS_MULTISHARED,
2538 PSTATUS_NOT, -1, &boundary_ents);
2539 return boundary_ents;
2599 const EntityHandle meshset) {
2621 auto remove_dofs_on_broken_skin = [&](
const std::string prb_name) {
2623 for (
int d : {0, 1, 2}) {
2624 std::vector<boost::weak_ptr<NumeredDofEntity>> dofs_to_remove;
2626 ->getSideDofsOnBrokenSpaceEntities(
2637 CHKERR remove_dofs_on_broken_skin(
"ESHELBY_PLASTICITY");
2681 auto set_zero_block = [&]() {
2709 auto zero_kinetic_constraints_block = [&]() {
2716 CHKERR bc_mng->removeBlockDOFsOnEntities(
"MATERIAL_PROBLEM",
"REMOVE_Y",
2718 CHKERR bc_mng->removeBlockDOFsOnEntities(
"MATERIAL_PROBLEM",
"REMOVE_Z",
2720 CHKERR bc_mng->removeBlockDOFsOnEntities(
"MATERIAL_PROBLEM",
"REMOVE_ALL",
2722 CHKERR bc_mng->removeBlockDOFsOnEntities(
"MATERIAL_PROBLEM",
"FIX_X",
2724 CHKERR bc_mng->removeBlockDOFsOnEntities(
"MATERIAL_PROBLEM",
"FIX_Y",
2726 CHKERR bc_mng->removeBlockDOFsOnEntities(
"MATERIAL_PROBLEM",
"FIX_Z",
2728 CHKERR bc_mng->removeBlockDOFsOnEntities(
"MATERIAL_PROBLEM",
"FIX_ALL",
2739 auto set_section = [&]() {
2741 PetscSection section;
2746 CHKERR PetscSectionDestroy(§ion);
2769BcDisp::BcDisp(std::string name, std::vector<double> attr,
Range faces,
2770 std::string load_history_file)
2771 : blockName(name), loadHistoryFile(load_history_file), faces(faces) {
2772 vals.resize(3,
false);
2773 flags.resize(3,
false);
2774 for (
int ii = 0; ii != 3; ++ii) {
2775 vals[ii] = attr[ii];
2776 flags[ii] =
static_cast<int>(attr[ii + 3]);
2779 MOFEM_LOG(
"EP", Sev::inform) <<
"Add BCDisp " << name;
2781 <<
"Add BCDisp vals " <<
vals[0] <<
" " <<
vals[1] <<
" " <<
vals[2];
2783 <<
"Add BCDisp flags " <<
flags[0] <<
" " <<
flags[1] <<
" " <<
flags[2];
2784 MOFEM_LOG(
"EP", Sev::inform) <<
"Add BCDisp nb. of faces " <<
faces.size();
2788 std::string load_history_file)
2789 : blockName(name), loadHistoryFile(load_history_file), faces(faces) {
2790 vals.resize(attr.size(),
false);
2791 for (
int ii = 0; ii != attr.size(); ++ii) {
2792 vals[ii] = attr[ii];
2798 std::string load_history_file)
2799 : blockName(name), loadHistoryFile(load_history_file), faces(faces) {
2800 vals.resize(3,
false);
2801 flags.resize(3,
false);
2802 for (
int ii = 0; ii != 3; ++ii) {
2803 vals[ii] = attr[ii];
2804 flags[ii] =
static_cast<int>(attr[ii + 3]);
2807 MOFEM_LOG(
"EP", Sev::inform) <<
"Add BCForce " << name;
2809 <<
"Add BCForce vals " <<
vals[0] <<
" " <<
vals[1] <<
" " <<
vals[2];
2811 <<
"Add BCForce flags " <<
flags[0] <<
" " <<
flags[1] <<
" " <<
flags[2];
2812 MOFEM_LOG(
"EP", Sev::inform) <<
"Add BCForce nb. of faces " <<
faces.size();
2816 std::vector<double> attr,
2818 std::string load_history_file)
2819 : blockName(name), loadHistoryFile(load_history_file), faces(faces) {
2822 if (attr.size() < 1) {
2824 "Wrong size of normal displacement BC");
2829 MOFEM_LOG(
"EP", Sev::inform) <<
"Add NormalDisplacementBc " << name;
2830 MOFEM_LOG(
"EP", Sev::inform) <<
"Add NormalDisplacementBc val " <<
val;
2832 <<
"Add NormalDisplacementBc nb. of faces " <<
faces.size();
2836 : blockName(name), faces(faces) {
2839 if (attr.size() < 2) {
2841 "Wrong size of spring BC attributes");
2847 MOFEM_LOG(
"EP", Sev::inform) <<
"Add SpringBc " << name;
2850 MOFEM_LOG(
"EP", Sev::inform) <<
"Add SpringBc nb. of faces " <<
faces.size();
2854 std::string load_history_file)
2855 : blockName(name), loadHistoryFile(load_history_file), faces(faces) {
2858 if (attr.size() < 1) {
2860 "Wrong size of normal displacement BC");
2865 MOFEM_LOG(
"EP", Sev::inform) <<
"Add PressureBc " << name;
2866 MOFEM_LOG(
"EP", Sev::inform) <<
"Add PressureBc val " <<
val;
2868 <<
"Add PressureBc nb. of faces " <<
faces.size();
2872 Range ents, std::string load_history_file)
2873 : blockName(name), loadHistoryFile(load_history_file), ents(ents) {
2876 if (attr.size() < 2) {
2878 "Wrong size of external strain attribute");
2884 MOFEM_LOG(
"EP", Sev::inform) <<
"Add ExternalStrain " << name;
2885 MOFEM_LOG(
"EP", Sev::inform) <<
"Add ExternalStrain val " <<
val;
2887 <<
"Add ExternalStrain bulk modulus K " <<
bulkModulusK;
2889 <<
"Add ExternalStrain bulk modulus K " <<
bulkModulusK;
2891 <<
"Add ExternalStrain nb. of tets " <<
ents.size();
2895 std::string name, std::vector<double> attr,
Range faces,
2896 std::string load_history_file)
2897 : blockName(name), faces(faces) {
2898 (void)load_history_file;
2899 if (attr.size() < 3) {
2901 "Wrong size of analytical displacement BC");
2904 flags.resize(3,
false);
2905 for (
int ii = 0; ii != 3; ++ii) {
2906 flags[ii] = attr[ii];
2909 MOFEM_LOG(
"EP", Sev::inform) <<
"Add AnalyticalDisplacementBc " << name;
2911 <<
"Add AnalyticalDisplacementBc flags " <<
flags[0] <<
" " <<
flags[1]
2914 <<
"Add AnalyticalDisplacementBc nb. of faces " <<
faces.size();
2918 std::vector<double> attr,
2920 std::string load_history_file)
2921 : blockName(name), faces(faces) {
2922 (void)load_history_file;
2923 flags.resize(3,
false);
2924 for (
int ii = 0; ii != 3; ++ii) {
2925 flags[ii] = attr.size() < 3 ? 1 : attr[ii];
2928 MOFEM_LOG(
"EP", Sev::inform) <<
"Add AnalyticalTractionBc " << name;
2929 MOFEM_LOG(
"EP", Sev::inform) <<
"Add AnalyticalTractionBc flags " <<
flags[0]
2932 <<
"Add AnalyticalTractionBc nb. of faces " <<
faces.size();
2937 boost::shared_ptr<TractionFreeBc> &bc_ptr,
2938 const std::string contact_set_name) {
2943 CHKERR mField.get_moab().get_entities_by_type(meshset, MBTET, tets);
2944 Range tets_skin_part;
2945 Skinner skin(&mField.get_moab());
2946 CHKERR skin.find_skin(0, tets,
false, tets_skin_part);
2947 ParallelComm *pcomm =
2950 CHKERR pcomm->filter_pstatus(tets_skin_part,
2951 PSTATUS_SHARED | PSTATUS_MULTISHARED,
2952 PSTATUS_NOT, -1, &tets_skin);
2955 for (
int dd = 0; dd != 3; ++dd)
2956 (*bc_ptr)[dd] = tets_skin;
2959 if (bcSpatialDispVecPtr)
2960 for (
auto &
v : *bcSpatialDispVecPtr) {
2962 (*bc_ptr)[0] = subtract((*bc_ptr)[0],
v.faces);
2964 (*bc_ptr)[1] = subtract((*bc_ptr)[1],
v.faces);
2966 (*bc_ptr)[2] = subtract((*bc_ptr)[2],
v.faces);
2970 if (bcSpatialRotationVecPtr)
2971 for (
auto &
v : *bcSpatialRotationVecPtr) {
2972 (*bc_ptr)[0] = subtract((*bc_ptr)[0],
v.faces);
2973 (*bc_ptr)[1] = subtract((*bc_ptr)[1],
v.faces);
2974 (*bc_ptr)[2] = subtract((*bc_ptr)[2],
v.faces);
2977 if (bcSpatialNormalDisplacementVecPtr)
2978 for (
auto &
v : *bcSpatialNormalDisplacementVecPtr) {
2979 (*bc_ptr)[0] = subtract((*bc_ptr)[0],
v.faces);
2980 (*bc_ptr)[1] = subtract((*bc_ptr)[1],
v.faces);
2981 (*bc_ptr)[2] = subtract((*bc_ptr)[2],
v.faces);
2984 if (bcSpatialAnalyticalDisplacementVecPtr)
2985 for (
auto &
v : *bcSpatialAnalyticalDisplacementVecPtr) {
2987 (*bc_ptr)[0] = subtract((*bc_ptr)[0],
v.faces);
2989 (*bc_ptr)[1] = subtract((*bc_ptr)[1],
v.faces);
2991 (*bc_ptr)[2] = subtract((*bc_ptr)[2],
v.faces);
2994 if (bcSpatialTractionVecPtr)
2995 for (
auto &
v : *bcSpatialTractionVecPtr) {
2996 (*bc_ptr)[0] = subtract((*bc_ptr)[0],
v.faces);
2997 (*bc_ptr)[1] = subtract((*bc_ptr)[1],
v.faces);
2998 (*bc_ptr)[2] = subtract((*bc_ptr)[2],
v.faces);
3001 if (bcSpatialSpringVecPtr)
3002 for (
auto &
v : *bcSpatialSpringVecPtr) {
3003 (*bc_ptr)[0] = subtract((*bc_ptr)[0],
v.faces);
3004 (*bc_ptr)[1] = subtract((*bc_ptr)[1],
v.faces);
3005 (*bc_ptr)[2] = subtract((*bc_ptr)[2],
v.faces);
3008 if (bcSpatialAnalyticalTractionVecPtr)
3009 for (
auto &
v : *bcSpatialAnalyticalTractionVecPtr) {
3010 (*bc_ptr)[0] = subtract((*bc_ptr)[0],
v.faces);
3011 (*bc_ptr)[1] = subtract((*bc_ptr)[1],
v.faces);
3012 (*bc_ptr)[2] = subtract((*bc_ptr)[2],
v.faces);
3015 if (bcSpatialPressureVecPtr)
3016 for (
auto &
v : *bcSpatialPressureVecPtr) {
3017 (*bc_ptr)[0] = subtract((*bc_ptr)[0],
v.faces);
3018 (*bc_ptr)[1] = subtract((*bc_ptr)[1],
v.faces);
3019 (*bc_ptr)[2] = subtract((*bc_ptr)[2],
v.faces);
3024 std::regex((boost::format(
"%s(.*)") % contact_set_name).str()))) {
3026 CHKERR m->getMeshsetIdEntitiesByDimension(mField.get_moab(), 2, faces,
3028 (*bc_ptr)[0] = subtract((*bc_ptr)[0], faces);
3029 (*bc_ptr)[1] = subtract((*bc_ptr)[1], faces);
3030 (*bc_ptr)[2] = subtract((*bc_ptr)[2], faces);
3047 return 2 * p_data + 1;
3053 return 2 * (p_data + 1);
3058 const int tag,
const bool do_rhs,
const bool do_lhs,
const bool calc_rates,
3059 boost::shared_ptr<VolumeElementForcesAndSourcesCore> fe,
3060 const bool add_bubble) {
3064 boost::make_shared<CGGUserPolynomialBase::CachePhi>(0, 0,
MatrixDouble());
3065 fe->getUserPolynomialBase() =
3066 boost::make_shared<CGGUserPolynomialBase>(bubble_cache);
3067 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
3068 fe->getOpPtrVector(), {HDIV, H1, L2}, materialH1Positions, frontAdjEdges);
3071 fe->getRuleHook = [](int, int, int) {
return -1; };
3073 fe->setRuleHook = SetIntegrationAtFrontVolume(frontVertices, frontAdjEdges,
3080 dataAtPts->physicsPtr = physicalEquations;
3085 piolaStress, dataAtPts->getApproxPAtPts()));
3088 bubbleField, dataAtPts->getApproxPAtPts(), MBMAXTYPE));
3091 piolaStress, dataAtPts->getDivPAtPts()));
3093 rotAxis, dataAtPts->getRotAxisAtPts(), MBTET));
3095 if (isNoStretch()) {
3097 fe->getOpPtrVector(), physicalEquations, dataAtPts,
3098 externalStrainVecPtr, timeScaleMap);
3100 fe->getOpPtrVector().push_back(
3102 stretchTensor, dataAtPts->getLogStretchTensorAtPts(), MBTET));
3105 CHKERR VecSetDM(solTSStep, PETSC_NULLPTR);
3107 piolaStress, dataAtPts->getApproxP0AtPts(),
nullptr, solTSStep));
3108 if (!isNoStretch()) {
3110 stretchTensor, dataAtPts->getLogStretchTensor0AtPts(), solTSStep,
3115 rotAxis, dataAtPts->getRotAxis0AtPts(), solTSStep, MBTET));
3117 rotAxis, dataAtPts->getRotAxisGradAtPts(), MBTET));
3119 spatialL2Disp, dataAtPts->getSmallWL2AtPts(), MBTET));
3123 spatialH1Disp, dataAtPts->getSmallWH1AtPts()));
3125 spatialH1Disp, dataAtPts->getSmallWGradH1AtPts()));
3130 spatialL2Disp, dataAtPts->getSmallWL2DotAtPts(), MBTET));
3131 if (isNoStretch()) {
3133 fe->getOpPtrVector().push_back(
3135 stretchTensor, dataAtPts->getLogStretchDotTensorAtPts(), MBTET));
3136 fe->getOpPtrVector().push_back(
3138 stretchTensor, dataAtPts->getGradLogStretchDotTensorAtPts(),
3142 rotAxis, dataAtPts->getRotAxisDotAtPts(), MBTET));
3144 rotAxis, dataAtPts->getRotAxisGradDotAtPts(), MBTET));
3147 if (std::abs(alphaRho) > std::numeric_limits<double>::epsilon()) {
3149 spatialL2Disp, dataAtPts->getSmallWL2DotDotAtPts(), MBTET));
3154 fe->getOpPtrVector().push_back(
3158 if (isNoStretch()) {
3160 fe->getOpPtrVector().push_back(physicalEquations->returnOpJacobian(
3161 do_rhs, do_lhs, dataAtPts, physicalEquations));
3168 boost::shared_ptr<VolumeElementForcesAndSourcesCore> fe_lhs) {
3171 bool has_nonhomogeneous_mat_block =
3174 piolaStress, piolaStress, dataAtPts, has_nonhomogeneous_mat_block));
3176 bubbleField, piolaStress, dataAtPts, has_nonhomogeneous_mat_block));
3178 bubbleField, bubbleField, dataAtPts, has_nonhomogeneous_mat_block));
3181 spatialL2Disp, piolaStress, dataAtPts,
true));
3183 spatialL2Disp, spatialL2Disp, dataAtPts, alphaW, alphaRho));
3186 piolaStress, rotAxis, dataAtPts,
3187 symmetrySelector ==
SYMMETRIC ?
true :
false));
3189 bubbleField, rotAxis, dataAtPts,
3190 symmetrySelector ==
SYMMETRIC ?
true :
false));
3194 rotAxis, piolaStress, dataAtPts,
false));
3196 rotAxis, bubbleField, dataAtPts,
false));
3199 rotAxis, rotAxis, dataAtPts, alphaR, alphaR0, alphaOmega, alphaOmega0,
3200 alphaViscousR, alphaViscousR0, alphaViscousOmega,
3201 alphaViscousOmega0));
3207 boost::shared_ptr<VolumeElementForcesAndSourcesCore> fe_lhs) {
3210 fe_lhs->getOpPtrVector().push_back(
3211 physicalEquations->returnOpSpatialPhysical_du_du(
3212 stretchTensor, stretchTensor, dataAtPts, alphaU));
3214 stretchTensor, piolaStress, dataAtPts,
true));
3216 stretchTensor, bubbleField, dataAtPts,
true));
3218 stretchTensor, rotAxis, dataAtPts,
3219 symmetrySelector ==
SYMMETRIC ?
true :
false));
3222 spatialL2Disp, piolaStress, dataAtPts,
true));
3224 spatialL2Disp, spatialL2Disp, dataAtPts, alphaW, alphaRho));
3227 piolaStress, rotAxis, dataAtPts,
3228 symmetrySelector ==
SYMMETRIC ?
true :
false));
3230 bubbleField, rotAxis, dataAtPts,
3231 symmetrySelector ==
SYMMETRIC ?
true :
false));
3235 rotAxis, stretchTensor, dataAtPts,
false));
3237 rotAxis, piolaStress, dataAtPts,
false));
3239 rotAxis, bubbleField, dataAtPts,
false));
3242 rotAxis, rotAxis, dataAtPts, alphaR, alphaR0, alphaOmega, alphaOmega0,
3243 alphaViscousR, alphaViscousR0, alphaViscousOmega,
3244 alphaViscousOmega0));
3250 boost::shared_ptr<VolumeElementForcesAndSourcesCore> fe_lhs) {
3252 CHKERR pushPiolaStressGramOps(fe_lhs);
3253 fe_lhs->getOpPtrVector().push_back(
3256 bubbleField, bubbleField));
3261 boost::shared_ptr<VolumeElementForcesAndSourcesCore> fe_lhs) {
3263 fe_lhs->getOpPtrVector().push_back(
3269 const int tag,
const bool add_elastic,
const bool add_material,
3270 boost::shared_ptr<VolumeElementForcesAndSourcesCore> &fe_rhs,
3271 boost::shared_ptr<VolumeElementForcesAndSourcesCore> &fe_lhs) {
3276 std::map<int, Range> map;
3279 mField.getInterface<
MeshsetsManager>()->getCubitMeshsetPtr(std::regex(
3281 (boost::format(
"%s(.*)") % name).str()
3287 CHK_MOAB_THROW(m_ptr->getMeshsetIdEntitiesByDimension(mField.get_moab(),
3290 map[m_ptr->getMeshsetId()] = ents;
3296 auto local_tau_sacale = boost::make_shared<double>(1.0);
3299 using BdyEleOp = BoundaryEle::UserDataOperator;
3300 struct OpSetTauScale :
public BdyEleOp {
3301 OpSetTauScale(boost::shared_ptr<double> local_tau_sacale,
double alphaTau,
3303 boost::shared_ptr<MatrixDouble> flux_mat_ptr)
3305 localTauSacale(local_tau_sacale), alphaTau(alphaTau),
3306 alphaTau0(alphaTau0), fluxMatPtr(flux_mat_ptr) {}
3310 auto &coords = BdyEleOp::getCoords();
3311 auto [centre, barycenter,
h] =
3315 auto t_P = getFTensor2FromMat<3, 3>(fluxMatPtr);
3316 auto t_normal = getFTensor1NormalsAtGaussPts();
3317 auto t_w = getFTensor0IntegrationWeight();
3318 auto nb_gauss_pts = getGaussPts().size2();
3320 for (
auto gg = 0; gg != nb_gauss_pts; ++gg) {
3322 t_t(
i) = t_P(
i,
J) * t_normal(
J);
3323 norm += t_w * sqrt(t_t(
i) * t_t(
i));
3329 *localTauSacale = (alphaTau /
h) + alphaTau0 * norm;
3335 boost::shared_ptr<double> localTauSacale;
3336 boost::shared_ptr<MatrixDouble> fluxMatPtr;
3341 auto not_interface_face = [
this](
FEMethod *fe_method_ptr) {
3342 auto ent = fe_method_ptr->getFEEntityHandle();
3345 (interfaceFaces->find(ent) != interfaceFaces->end())
3347 || (crackFaces->find(ent) != crackFaces->end())
3356 fe_rhs = boost::make_shared<VolumeElementForcesAndSourcesCore>(mField);
3357 CHKERR setBaseVolumeElementOps(tag,
true,
false,
true, fe_rhs);
3362 fe_rhs->getOpPtrVector().push_back(
3364 fe_rhs->getOpPtrVector().push_back(
3366 alphaOmega0, alphaViscousR, alphaViscousR0,
3367 alphaViscousOmega, alphaViscousOmega0));
3368 if (isNoStretch()) {
3371 if (!internalStressTagName.empty()) {
3372 switch (meshTransferInterpOrder) {
3374 fe_rhs->getOpPtrVector().push_back(
3378 fe_rhs->getOpPtrVector().push_back(
3383 "Unsupported mesh transfer interpolation order %d, for "
3385 meshTransferInterpOrder);
3389 auto ts_internal_stress =
3390 boost::make_shared<DynamicRelaxationTimeScale>(
3391 "internal_stress_history.txt",
false, def_scaling_fun);
3392 if (internalStressVoigt) {
3393 fe_rhs->getOpPtrVector().push_back(
3395 stretchTensor, dataAtPts, ts_internal_stress));
3397 fe_rhs->getOpPtrVector().push_back(
3399 stretchTensor, dataAtPts, ts_internal_stress));
3402 if (
auto op = physicalEquations->returnOpSpatialPhysicalExternalStrain(
3403 stretchTensor, dataAtPts, externalStrainVecPtr, timeScaleMap)) {
3404 fe_rhs->getOpPtrVector().push_back(op);
3405 }
else if (externalStrainVecPtr && !externalStrainVecPtr->empty()) {
3407 "OpSpatialPhysicalExternalStrain not implemented for this "
3411 fe_rhs->getOpPtrVector().push_back(
3412 physicalEquations->returnOpSpatialPhysical(stretchTensor, dataAtPts,
3415 fe_rhs->getOpPtrVector().push_back(
3417 fe_rhs->getOpPtrVector().push_back(
3419 fe_rhs->getOpPtrVector().push_back(
3422 auto set_hybridisation_rhs = [&](
auto &pip) {
3429 using SideEleOp = EleOnSide::UserDataOperator;
3430 using BdyEleOp = BoundaryEle::UserDataOperator;
3435 mField, skeletonElement,
SPACE_DIM - 1, Sev::noisy);
3437 op_loop_skeleton_side->getSideFEPtr()->getRuleHook = [](int, int, int) {
3440 op_loop_skeleton_side->getSideFEPtr()->setRuleHook =
3441 SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
3443 CHKERR EshelbianPlasticity::
3444 AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
3445 op_loop_skeleton_side->getOpPtrVector(), {L2},
3446 materialH1Positions, frontAdjEdges);
3450 auto broken_data_ptr =
3451 boost::make_shared<std::vector<BrokenBaseSideData>>();
3454 mField, elementVolumeName,
SPACE_DIM, Sev::noisy);
3455 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
3456 boost::make_shared<CGGUserPolynomialBase>(
nullptr,
true);
3458 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
3459 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
3460 materialH1Positions, frontAdjEdges);
3461 op_loop_domain_side->getOpPtrVector().push_back(
3463 auto flux_mat_ptr = boost::make_shared<MatrixDouble>();
3464 op_loop_domain_side->getOpPtrVector().push_back(
3467 op_loop_domain_side->getOpPtrVector().push_back(
3471 op_loop_skeleton_side->getOpPtrVector().push_back(op_loop_domain_side);
3473 GAUSS>::OpBrokenSpaceConstrainDHybrid<SPACE_DIM>;
3475 GAUSS>::OpBrokenSpaceConstrainDFlux<SPACE_DIM>;
3476 op_loop_skeleton_side->getOpPtrVector().push_back(
new OpC_dHybrid(
3477 hybridSpatialDisp, broken_data_ptr, boost::make_shared<double>(1.0)));
3478 auto hybrid_ptr = boost::make_shared<MatrixDouble>();
3479 op_loop_skeleton_side->getOpPtrVector().push_back(
3482 op_loop_skeleton_side->getOpPtrVector().push_back(
new OpC_dBroken(
3483 broken_data_ptr, hybrid_ptr, boost::make_shared<double>(1.0)));
3486 pip.push_back(op_loop_skeleton_side);
3491 auto set_tau_stabilsation_rhs = [&](
auto &pip,
auto side_fe_name,
3492 auto hybrid_field) {
3499 using SideEleOp = EleOnSide::UserDataOperator;
3500 using BdyEleOp = BoundaryEle::UserDataOperator;
3505 mField, side_fe_name,
SPACE_DIM - 1, Sev::noisy);
3507 op_loop_skeleton_side->getSideFEPtr()->getRuleHook = [](int, int, int) {
3510 op_loop_skeleton_side->getSideFEPtr()->setRuleHook =
3511 SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
3512 op_loop_skeleton_side->getSideFEPtr()->exeTestHook = not_interface_face;
3513 CHKERR EshelbianPlasticity::
3514 AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
3515 op_loop_skeleton_side->getOpPtrVector(), {L2},
3516 materialH1Positions, frontAdjEdges);
3519 mField, elementVolumeName,
SPACE_DIM, Sev::noisy);
3520 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
3521 boost::make_shared<CGGUserPolynomialBase>(
nullptr,
true);
3523 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
3524 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
3525 materialH1Positions, frontAdjEdges);
3528 auto broken_disp_data_ptr =
3529 boost::make_shared<std::vector<BrokenBaseSideData>>();
3530 op_loop_domain_side->getOpPtrVector().push_back(
3532 broken_disp_data_ptr));
3533 auto disp_mat_ptr = boost::make_shared<MatrixDouble>();
3534 op_loop_domain_side->getOpPtrVector().push_back(
3538 op_loop_domain_side->getOpPtrVector().push_back(
3540 auto flux_mat_ptr = boost::make_shared<MatrixDouble>();
3541 op_loop_domain_side->getOpPtrVector().push_back(
3543 piolaStress, flux_mat_ptr, boost::make_shared<double>(1.0),
3545 op_loop_skeleton_side->getOpPtrVector().push_back(op_loop_domain_side);
3546 op_loop_skeleton_side->getOpPtrVector().push_back(
3547 new OpSetTauScale(local_tau_sacale, alphaTau, alphaTau0,
3551 auto hybrid_ptr = boost::make_shared<MatrixDouble>();
3552 op_loop_skeleton_side->getOpPtrVector().push_back(
3557 op_loop_skeleton_side->getOpPtrVector().push_back(
3559 hybrid_field, hybrid_ptr,
3560 [local_tau_sacale, broken_disp_data_ptr](
double,
double,
double) {
3561 return broken_disp_data_ptr->size() * (*local_tau_sacale);
3564 op_loop_skeleton_side->getOpPtrVector().push_back(
3566 broken_disp_data_ptr, [local_tau_sacale](
double,
double,
double) {
3567 return (*local_tau_sacale);
3570 op_loop_skeleton_side->getOpPtrVector().push_back(
3572 hybrid_field, broken_disp_data_ptr,
3573 [local_tau_sacale](
double,
double,
double) {
3574 return -(*local_tau_sacale);
3577 op_loop_skeleton_side->getOpPtrVector().push_back(
3579 broken_disp_data_ptr, hybrid_ptr,
3580 [local_tau_sacale](
double,
double,
double) {
3581 return -(*local_tau_sacale);
3585 pip.push_back(op_loop_skeleton_side);
3590 auto set_tau_stabilsation_disp_bc_rhs = [&](
auto &pip,
auto side_fe_name) {
3597 using SideEleOp = EleOnSide::UserDataOperator;
3598 using BdyEleOp = BoundaryEle::UserDataOperator;
3603 mField, side_fe_name,
SPACE_DIM - 1, Sev::noisy);
3605 op_loop_skeleton_side->getSideFEPtr()->getRuleHook = [](int, int, int) {
3608 op_loop_skeleton_side->getSideFEPtr()->setRuleHook =
3609 SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
3610 op_loop_skeleton_side->getSideFEPtr()->exeTestHook = not_interface_face;
3611 CHKERR EshelbianPlasticity::
3612 AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
3613 op_loop_skeleton_side->getOpPtrVector(), {L2},
3614 materialH1Positions, frontAdjEdges);
3617 mField, elementVolumeName,
SPACE_DIM, Sev::noisy);
3618 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
3619 boost::make_shared<CGGUserPolynomialBase>(
nullptr,
true);
3621 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
3622 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
3623 materialH1Positions, frontAdjEdges);
3626 auto broken_disp_data_ptr =
3627 boost::make_shared<std::vector<BrokenBaseSideData>>();
3628 op_loop_domain_side->getOpPtrVector().push_back(
3630 broken_disp_data_ptr));
3631 auto disp_mat_ptr = boost::make_shared<MatrixDouble>();
3632 op_loop_domain_side->getOpPtrVector().push_back(
3636 op_loop_domain_side->getOpPtrVector().push_back(
3639 op_loop_skeleton_side->getOpPtrVector().push_back(op_loop_domain_side);
3640 auto flux_mat_ptr = boost::make_shared<MatrixDouble>();
3641 op_loop_domain_side->getOpPtrVector().push_back(
3643 piolaStress, flux_mat_ptr, boost::make_shared<double>(1.0),
3645 op_loop_skeleton_side->getOpPtrVector().push_back(
new OpSetTauScale(
3646 local_tau_sacale, alphaTauBcDisp, alphaTauBcDisp0, flux_mat_ptr));
3649 op_loop_skeleton_side->getOpPtrVector().push_back(
3651 broken_disp_data_ptr, bcSpatialDispVecPtr, timeScaleMap,
3652 [local_tau_sacale](
double,
double,
double) {
3653 return (*local_tau_sacale);
3655 op_loop_skeleton_side->getOpPtrVector().push_back(
3657 broken_disp_data_ptr, bcSpatialAnalyticalDisplacementVecPtr,
3658 timeScaleMap, [local_tau_sacale](
double,
double,
double) {
3659 return (*local_tau_sacale);
3661 op_loop_skeleton_side->getOpPtrVector().push_back(
3663 broken_disp_data_ptr, bcSpatialRotationVecPtr, timeScaleMap,
3664 [local_tau_sacale](
double,
double,
double) {
3665 return (*local_tau_sacale);
3669 pip.push_back(op_loop_skeleton_side);
3674 auto set_contact_rhs = [&](
auto &pip) {
3678 auto set_cohesive_rhs = [&](
auto &pip) {
3680 *
this, SetIntegrationAtFrontFace(frontVertices, frontAdjEdges),
3681 interfaceFaces, pip);
3684 CHKERR set_hybridisation_rhs(fe_rhs->getOpPtrVector());
3685 CHKERR set_contact_rhs(fe_rhs->getOpPtrVector());
3686 if (alphaTau > 0.0 || alphaTau0 > 0.0) {
3687 CHKERR set_tau_stabilsation_rhs(fe_rhs->getOpPtrVector(), skeletonElement,
3690 if (alphaTauBcDisp > 0.0 || alphaTauBcDisp0 > 0.0) {
3691 CHKERR set_tau_stabilsation_disp_bc_rhs(fe_rhs->getOpPtrVector(),
3694 if (interfaceCrack == PETSC_TRUE) {
3695 CHKERR set_cohesive_rhs(fe_rhs->getOpPtrVector());
3699 using BodyNaturalBC =
3701 Assembly<PETSC>::LinearForm<
GAUSS>;
3703 BodyNaturalBC::OpFlux<NaturalMeshsetType<BLOCKSET>, 1, 3>;
3705 std::string body_force_history;
3706 CHKERR getStringArgumentFromJsonBlocksets(
"BODY_FORCE",
"load_history",
3707 body_force_history);
3708 if (body_force_history.empty()) {
3709 body_force_history =
"body_force.txt";
3712 <<
"Body force load history from JSON: " << body_force_history;
3714 auto body_time_scale =
3715 boost::make_shared<DynamicRelaxationTimeScale>(body_force_history);
3716 CHKERR BodyNaturalBC::AddFluxToPipeline<OpBodyForce>::add(
3717 fe_rhs->getOpPtrVector(), mField, spatialL2Disp, {body_time_scale},
3718 "BODY_FORCE", Sev::inform);
3722 fe_lhs = boost::make_shared<VolumeElementForcesAndSourcesCore>(mField);
3723 CHKERR setBaseVolumeElementOps(tag,
true,
true,
true, fe_lhs);
3728 if (isNoStretch()) {
3729 CHKERR pushNoStretchVolumeA00Ops(fe_lhs);
3731 CHKERR pushStretchVolumeA00Ops(fe_lhs);
3734 auto set_hybridisation_lhs = [&](
auto &pip) {
3741 using SideEleOp = EleOnSide::UserDataOperator;
3742 using BdyEleOp = BoundaryEle::UserDataOperator;
3747 mField, skeletonElement,
SPACE_DIM - 1, Sev::noisy);
3748 op_loop_skeleton_side->getSideFEPtr()->getRuleHook = [](int, int, int) {
3751 op_loop_skeleton_side->getSideFEPtr()->setRuleHook =
3752 SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
3753 CHKERR EshelbianPlasticity::
3754 AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
3755 op_loop_skeleton_side->getOpPtrVector(), {L2},
3756 materialH1Positions, frontAdjEdges);
3760 auto broken_data_ptr =
3761 boost::make_shared<std::vector<BrokenBaseSideData>>();
3764 mField, elementVolumeName,
SPACE_DIM, Sev::noisy);
3765 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
3766 boost::make_shared<CGGUserPolynomialBase>(
nullptr,
true);
3768 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
3769 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
3770 materialH1Positions, frontAdjEdges);
3771 op_loop_domain_side->getOpPtrVector().push_back(
3774 op_loop_skeleton_side->getOpPtrVector().push_back(op_loop_domain_side);
3776 GAUSS>::OpBrokenSpaceConstrain<SPACE_DIM>;
3777 op_loop_skeleton_side->getOpPtrVector().push_back(
3778 new OpC(hybridSpatialDisp, broken_data_ptr,
3779 boost::make_shared<double>(1.0),
true,
false));
3781 pip.push_back(op_loop_skeleton_side);
3786 auto set_tau_stabilsation_lhs = [&](
auto &pip,
auto side_fe_name,
3787 auto hybrid_field) {
3794 using SideEleOp = EleOnSide::UserDataOperator;
3795 using BdyEleOp = BoundaryEle::UserDataOperator;
3800 mField, side_fe_name,
SPACE_DIM - 1, Sev::noisy);
3801 op_loop_skeleton_side->getSideFEPtr()->getRuleHook = [](int, int, int) {
3804 op_loop_skeleton_side->getSideFEPtr()->setRuleHook =
3805 SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
3806 op_loop_skeleton_side->getSideFEPtr()->exeTestHook = not_interface_face;
3807 CHKERR EshelbianPlasticity::
3808 AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
3809 op_loop_skeleton_side->getOpPtrVector(), {L2},
3810 materialH1Positions, frontAdjEdges);
3814 mField, elementVolumeName,
SPACE_DIM, Sev::noisy);
3815 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
3816 boost::make_shared<CGGUserPolynomialBase>(
nullptr,
true);
3818 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
3819 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
3820 materialH1Positions, frontAdjEdges);
3822 auto broken_disp_data_ptr =
3823 boost::make_shared<std::vector<BrokenBaseSideData>>();
3824 op_loop_domain_side->getOpPtrVector().push_back(
3826 broken_disp_data_ptr));
3827 auto flux_mat_ptr = boost::make_shared<MatrixDouble>();
3828 op_loop_domain_side->getOpPtrVector().push_back(
3830 piolaStress, flux_mat_ptr, boost::make_shared<double>(1.0),
3832 op_loop_skeleton_side->getOpPtrVector().push_back(op_loop_domain_side);
3833 op_loop_skeleton_side->getOpPtrVector().push_back(
3834 new OpSetTauScale(local_tau_sacale, alphaTau, alphaTau0,
3839 hybrid_field, hybrid_field,
3840 [local_tau_sacale, broken_disp_data_ptr](
double,
double,
double) {
3841 return broken_disp_data_ptr->size() * (*local_tau_sacale);
3844 op_loop_skeleton_side->getOpPtrVector().push_back(
3846 broken_disp_data_ptr, [local_tau_sacale](
double,
double,
double) {
3847 return (*local_tau_sacale);
3850 op_loop_skeleton_side->getOpPtrVector().push_back(
3852 hybrid_field, broken_disp_data_ptr,
3853 [local_tau_sacale](
double,
double,
double) {
3854 return -(*local_tau_sacale);
3858 op_loop_skeleton_side->getOpPtrVector().push_back(
3860 hybrid_field, broken_disp_data_ptr,
3861 [local_tau_sacale](
double,
double,
double) {
3862 return -(*local_tau_sacale);
3866 pip.push_back(op_loop_skeleton_side);
3871 auto set_tau_stabilsation_disp_bc_lhs = [&](
auto &pip,
auto side_fe_name) {
3878 using SideEleOp = EleOnSide::UserDataOperator;
3879 using BdyEleOp = BoundaryEle::UserDataOperator;
3884 mField, side_fe_name,
SPACE_DIM - 1, Sev::noisy);
3885 op_loop_skeleton_side->getSideFEPtr()->getRuleHook = [](int, int, int) {
3888 op_loop_skeleton_side->getSideFEPtr()->setRuleHook =
3889 SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
3890 op_loop_skeleton_side->getSideFEPtr()->exeTestHook = not_interface_face;
3891 CHKERR EshelbianPlasticity::
3892 AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
3893 op_loop_skeleton_side->getOpPtrVector(), {L2},
3894 materialH1Positions, frontAdjEdges);
3898 mField, elementVolumeName,
SPACE_DIM, Sev::noisy);
3899 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
3900 boost::make_shared<CGGUserPolynomialBase>(
nullptr,
true);
3902 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
3903 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
3904 materialH1Positions, frontAdjEdges);
3906 auto broken_disp_data_ptr =
3907 boost::make_shared<std::vector<BrokenBaseSideData>>();
3908 op_loop_domain_side->getOpPtrVector().push_back(
3910 broken_disp_data_ptr));
3911 auto flux_mat_ptr = boost::make_shared<MatrixDouble>();
3912 op_loop_domain_side->getOpPtrVector().push_back(
3914 piolaStress, flux_mat_ptr, boost::make_shared<double>(1.0),
3916 op_loop_skeleton_side->getOpPtrVector().push_back(op_loop_domain_side);
3917 op_loop_skeleton_side->getOpPtrVector().push_back(
new OpSetTauScale(
3918 local_tau_sacale, alphaTauBcDisp, alphaTauBcDisp0, flux_mat_ptr));
3921 op_loop_skeleton_side->getOpPtrVector().push_back(
3923 broken_disp_data_ptr, bcSpatialDispVecPtr,
3924 [local_tau_sacale](
double,
double,
double) {
3925 return (*local_tau_sacale);
3927 op_loop_skeleton_side->getOpPtrVector().push_back(
3929 broken_disp_data_ptr, bcSpatialAnalyticalDisplacementVecPtr,
3930 [local_tau_sacale](
double,
double,
double) {
3931 return (*local_tau_sacale);
3933 op_loop_skeleton_side->getOpPtrVector().push_back(
3935 broken_disp_data_ptr, bcSpatialRotationVecPtr,
3936 [local_tau_sacale](
double,
double,
double) {
3937 return (*local_tau_sacale);
3940 pip.push_back(op_loop_skeleton_side);
3945 auto set_contact_lhs = [&](
auto &pip) {
3949 auto set_cohesive_lhs = [&](
auto &pip) {
3951 *
this, SetIntegrationAtFrontFace(frontVertices, frontAdjEdges),
3952 interfaceFaces, pip);
3955 CHKERR set_hybridisation_lhs(fe_lhs->getOpPtrVector());
3956 CHKERR set_contact_lhs(fe_lhs->getOpPtrVector());
3957 if (alphaTau > 0.0 || alphaTau0 > 0.0) {
3958 CHKERR set_tau_stabilsation_lhs(fe_lhs->getOpPtrVector(), skeletonElement,
3961 if (alphaTauBcDisp > 0.0 || alphaTauBcDisp0 > 0.0) {
3962 CHKERR set_tau_stabilsation_disp_bc_lhs(fe_lhs->getOpPtrVector(),
3965 if (interfaceCrack == PETSC_TRUE) {
3966 CHKERR set_cohesive_lhs(fe_lhs->getOpPtrVector());
3977 const bool add_elastic,
const bool add_material,
3978 boost::shared_ptr<FaceElementForcesAndSourcesCore> &fe_rhs,
3979 boost::shared_ptr<FaceElementForcesAndSourcesCore> &fe_lhs) {
3982 fe_rhs = boost::make_shared<FaceElementForcesAndSourcesCore>(mField);
3983 fe_lhs = boost::make_shared<FaceElementForcesAndSourcesCore>(mField);
3988 fe_rhs->getRuleHook = [](int, int, int) {
return -1; };
3989 fe_lhs->getRuleHook = [](int, int, int) {
return -1; };
3990 fe_rhs->setRuleHook = SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
3991 fe_lhs->setRuleHook = SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
3994 EshelbianPlasticity::AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
3995 fe_rhs->getOpPtrVector(), {L2}, materialH1Positions, frontAdjEdges);
3997 EshelbianPlasticity::AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
3998 fe_lhs->getOpPtrVector(), {L2}, materialH1Positions, frontAdjEdges);
4002 auto get_broken_op_side = [
this](
auto &pip) {
4005 using SideEleOp = EleOnSide::UserDataOperator;
4007 auto broken_data_ptr =
4008 boost::make_shared<std::vector<BrokenBaseSideData>>();
4011 mField, elementVolumeName,
SPACE_DIM, Sev::noisy);
4012 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
4013 boost::make_shared<CGGUserPolynomialBase>(
nullptr,
true);
4015 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
4016 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
4017 materialH1Positions, frontAdjEdges);
4018 op_loop_domain_side->getOpPtrVector().push_back(
4020 auto flux_mat_ptr = boost::make_shared<MatrixDouble>();
4021 op_loop_domain_side->getOpPtrVector().push_back(
4024 op_loop_domain_side->getOpPtrVector().push_back(
4026 pip.push_back(op_loop_domain_side);
4027 return broken_data_ptr;
4030 auto set_rhs = [&]() {
4033 auto broken_data_ptr = get_broken_op_side(fe_rhs->getOpPtrVector());
4035 fe_rhs->getOpPtrVector().push_back(
4036 new OpDispBc(broken_data_ptr, bcSpatialDispVecPtr, timeScaleMap));
4038 broken_data_ptr, bcSpatialAnalyticalDisplacementVecPtr,
4041 broken_data_ptr, bcSpatialRotationVecPtr, timeScaleMap));
4043 auto piola_scale_ptr = boost::make_shared<double>(1.0);
4044 fe_rhs->getOpPtrVector().push_back(
4046 piola_scale_ptr, timeScaleMap));
4047 auto hybrid_grad_ptr = boost::make_shared<MatrixDouble>();
4049 fe_rhs->getOpPtrVector().push_back(
4051 hybridSpatialDisp, hybrid_grad_ptr));
4053 hybridSpatialDisp, bcSpatialPressureVecPtr, piola_scale_ptr,
4054 hybrid_grad_ptr, timeScaleMap));
4056 hybridSpatialDisp, bcSpatialAnalyticalTractionVecPtr, piola_scale_ptr,
4059 auto hybrid_ptr = boost::make_shared<MatrixDouble>();
4060 fe_rhs->getOpPtrVector().push_back(
4064 hybridSpatialDisp, hybrid_ptr, broken_data_ptr,
4065 bcSpatialNormalDisplacementVecPtr, timeScaleMap));
4066 fe_rhs->getOpPtrVector().push_back(
4067 new OpSpringRhsBc(hybridSpatialDisp, hybrid_ptr, broken_data_ptr,
4068 bcSpatialSpringVecPtr));
4070 auto get_normal_disp_bc_faces = [&]() {
4073 return boost::make_shared<Range>(faces);
4076 auto get_spring_bc_faces = [&]() {
4078 return boost::make_shared<Range>(faces);
4083 using BdyEleOp = BoundaryEle::UserDataOperator;
4085 GAUSS>::OpBrokenSpaceConstrainDFlux<SPACE_DIM>;
4086 fe_rhs->getOpPtrVector().push_back(
new OpC_dBroken(
4087 broken_data_ptr, hybrid_ptr, boost::make_shared<double>(1.0),
4088 get_normal_disp_bc_faces()));
4089 fe_rhs->getOpPtrVector().push_back(
new OpC_dBroken(
4090 broken_data_ptr, hybrid_ptr, boost::make_shared<double>(1.0),
4091 get_spring_bc_faces()));
4096 auto set_lhs = [&]() {
4099 auto broken_data_ptr = get_broken_op_side(fe_lhs->getOpPtrVector());
4102 hybridSpatialDisp, bcSpatialNormalDisplacementVecPtr, timeScaleMap));
4104 hybridSpatialDisp, broken_data_ptr, bcSpatialNormalDisplacementVecPtr,
4106 fe_lhs->getOpPtrVector().push_back(
4109 hybridSpatialDisp, broken_data_ptr, bcSpatialSpringVecPtr));
4111 auto hybrid_grad_ptr = boost::make_shared<MatrixDouble>();
4113 fe_lhs->getOpPtrVector().push_back(
4115 hybridSpatialDisp, hybrid_grad_ptr));
4117 hybridSpatialDisp, bcSpatialPressureVecPtr, hybrid_grad_ptr,
4120 auto get_normal_disp_bc_faces = [&]() {
4123 return boost::make_shared<Range>(faces);
4126 auto get_spring_bc_faces = [&]() {
4128 return boost::make_shared<Range>(faces);
4133 using BdyEleOp = BoundaryEle::UserDataOperator;
4135 GAUSS>::OpBrokenSpaceConstrain<SPACE_DIM>;
4136 fe_lhs->getOpPtrVector().push_back(
new OpC(
4137 hybridSpatialDisp, broken_data_ptr, boost::make_shared<double>(1.0),
4138 true,
true, get_normal_disp_bc_faces()));
4139 fe_lhs->getOpPtrVector().push_back(
new OpC(
4140 hybridSpatialDisp, broken_data_ptr, boost::make_shared<double>(1.0),
4141 true,
true, get_spring_bc_faces()));
4154 const bool add_elastic,
const bool add_material,
4155 boost::shared_ptr<FaceElementForcesAndSourcesCore> &fe_rhs,
4156 boost::shared_ptr<FaceElementForcesAndSourcesCore> &fe_lhs) {
4163 boost::shared_ptr<ForcesAndSourcesCore> &fe_contact_tree
4176 CHKERR setContactElementRhsOps(contactTreeRhs);
4178 CHKERR setVolumeElementOps(tag,
true,
false, elasticFeRhs, elasticFeLhs);
4179 CHKERR setFaceElementOps(
true,
false, elasticBcRhs, elasticBcLhs);
4182 boost::make_shared<ForcesAndSourcesCore::UserDataOperator::AdjCache>();
4184 auto get_op_contact_bc = [&]() {
4187 mField, contactElement,
SPACE_DIM - 1, Sev::noisy, adj_cache);
4188 return op_loop_side;
4196 boost::shared_ptr<FEMethod> null;
4198 if (std::abs(alphaRho) > std::numeric_limits<double>::epsilon()) {
4231 bool set_ts_monitor) {
4233#ifdef ENABLE_PYTHON_BINDING
4237 auto setup_ts_monitor = [&]() {
4238 boost::shared_ptr<TsCtx>
ts_ctx;
4241 if (set_ts_monitor) {
4245 auto monitor_ptr = boost::make_shared<EshelbianMonitor>(*ep_ptr);
4246 auto testing_monitor_ptr =
4247 boost::make_shared<EshelbianTestingMonitor>(*ep_ptr, monitor_ptr);
4251 PetscBool test_cook_flg = PETSC_FALSE;
4252 PetscBool test_cook_pts_flg = PETSC_FALSE;
4255 &test_cook_flg, PETSC_NULLPTR);
4257 &test_cook_pts_flg, PETSC_NULLPTR);
4260 if (
atom_test || test_cook_flg || test_cook_pts_flg) {
4265 MOFEM_LOG(
"EP", Sev::inform) <<
"TS monitor setup";
4266 return std::make_tuple(
ts_ctx);
4269 auto setup_snes_monitor = [&]() {
4272 CHKERR TSGetSNES(ts, &snes);
4274 CHKERR SNESMonitorSet(snes,
4277 (
void *)(snes_ctx.get()), PETSC_NULLPTR);
4278 MOFEM_LOG(
"EP", Sev::inform) <<
"SNES monitor setup";
4282 auto setup_snes_conergence_test = [&]() {
4285 auto snes_convergence_test = [](SNES snes, PetscInt it, PetscReal xnorm,
4286 PetscReal snorm, PetscReal fnorm,
4287 SNESConvergedReason *reason,
void *cctx) {
4290 CHKERR SNESConvergedDefault(snes, it, xnorm, snorm, fnorm, reason,
4294 CHKERR SNESGetSolutionUpdate(snes, &x_update);
4295 CHKERR SNESGetFunction(snes, &r, PETSC_NULLPTR, PETSC_NULLPTR);
4308 auto setup_section = [&]() {
4309 PetscSection section_raw;
4315 for (
int ff = 0; ff != num_fields; ff++) {
4318 PetscSectionGetFieldName(section_raw, ff, &
field_name),
4325 auto set_vector_on_mesh = [&]() {
4329 CHKERR VecGhostUpdateBegin(x, INSERT_VALUES, SCATTER_FORWARD);
4330 CHKERR VecGhostUpdateEnd(x, INSERT_VALUES, SCATTER_FORWARD);
4331 MOFEM_LOG(
"EP", Sev::inform) <<
"Vector set on mesh";
4335 auto setup_schur_block_solver = [&]() {
4336 MOFEM_LOG(
"EP", Sev::inform) <<
"Setting up Schur block solver";
4338 "append options prefix");
4342 boost::shared_ptr<EshelbianCore::SetUpSchur> schur_ptr;
4343 if constexpr (
A == AssemblyType::BLOCK_MAT) {
4348 MOFEM_LOG(
"EP", Sev::inform) <<
"Setting up Schur block solver done";
4355#ifdef ENABLE_PYTHON_BINDING
4356 return std::make_tuple(setup_sdf(), setup_ts_monitor(),
4357 setup_snes_monitor(), setup_snes_conergence_test(),
4358 setup_section(), set_vector_on_mesh(),
4359 setup_schur_block_solver());
4361 return std::make_tuple(setup_ts_monitor(), setup_snes_monitor(),
4362 setup_snes_conergence_test(), setup_section(),
4363 set_vector_on_mesh(), setup_schur_block_solver());
4371 PetscBool debug_model = PETSC_FALSE;
4375 <<
"Debug model flag is " << (debug_model ?
"ON" :
"OFF");
4377 if (debug_model == PETSC_TRUE) {
4379 auto post_proc = [&](TS ts, PetscReal
t, Vec u, Vec u_t, Vec u_tt, Vec
F,
4384 CHKERR TSGetSNES(ts, &snes);
4386 CHKERR SNESGetIterationNumber(snes, &it);
4387 std::string file_name =
"snes_iteration_" + std::to_string(it) +
".h5m";
4388 CHKERR postProcessResults(1, file_name,
F, u_t, PETSC_NULLPTR, {}, ts);
4389 std::string file_skel_name =
4390 "snes_iteration_skel_" + std::to_string(it) +
".h5m";
4392 auto get_material_force_tag = [&]() {
4393 auto &moab = mField.get_moab();
4400 CHKERR calculateFaceMaterialForce(1, ts);
4401 CHKERR postProcessSkeletonResults(1, file_skel_name,
F,
4402 {get_material_force_tag()}, ts);
4406 ts_ctx_ptr->tsDebugHook = post_proc;
4415 CHKERR addDebugModel(ts);
4419 if (std::abs(alphaRho) > std::numeric_limits<double>::epsilon()) {
4421 CHKERR VecDuplicate(x, &xx);
4422 CHKERR VecZeroEntries(xx);
4423 CHKERR TS2SetSolution(ts, x, xx);
4426 CHKERR TSSetSolution(ts, x);
4429 TetPolynomialBase::switchCacheBaseOn<HDIV>(
4430 {elasticFeLhs.get(), elasticFeRhs.get()});
4435 CHKERR TSSolve(ts, PETSC_NULLPTR);
4437 TetPolynomialBase::switchCacheBaseOff<HDIV>(
4438 {elasticFeLhs.get(), elasticFeRhs.get()});
4442 if (mField.get_comm_rank() == 0) {
4445 "solve_elastic_graph.dot");
4450 CHKERR TSGetSNES(ts, &snes);
4451 int lin_solver_iterations;
4452 CHKERR SNESGetLinearSolveIterations(snes, &lin_solver_iterations);
4454 <<
"Number of linear solver iterations " << lin_solver_iterations;
4456 PetscBool test_cook_flg = PETSC_FALSE;
4459 if (test_cook_flg) {
4460 PetscInt expected_lin_solver_iterations = 11;
4462 "-test_cook_max_linear_iterations",
4463 &expected_lin_solver_iterations, PETSC_NULLPTR);
4464 if (lin_solver_iterations > expected_lin_solver_iterations)
4467 "Expected number of iterations is different than expected %d > %d",
4468 lin_solver_iterations, expected_lin_solver_iterations);
4471 PetscBool test_sslv116_flag = PETSC_FALSE;
4473 &test_sslv116_flag, PETSC_NULLPTR);
4475 if (test_sslv116_flag) {
4476 double max_val = 0.0;
4477 double min_val = 0.0;
4478 auto field_min_max = [&](boost::shared_ptr<FieldEntity> ent_ptr) {
4480 auto ent_type = ent_ptr->getEntType();
4481 if (ent_type == MBVERTEX) {
4482 max_val = std::max(ent_ptr->getEntFieldData()[
SPACE_DIM - 1], max_val);
4483 min_val = std::min(ent_ptr->getEntFieldData()[
SPACE_DIM - 1], min_val);
4488 field_min_max, spatialH1Disp);
4490 double global_max_val = 0.0;
4491 double global_min_val = 0.0;
4492 MPI_Allreduce(&max_val, &global_max_val, 1, MPI_DOUBLE, MPI_MAX,
4494 MPI_Allreduce(&min_val, &global_min_val, 1, MPI_DOUBLE, MPI_MIN,
4497 <<
"Max " << spatialH1Disp <<
" value: " << global_max_val;
4499 <<
"Min " << spatialH1Disp <<
" value: " << global_min_val;
4501 double ref_max_val = 0.00767;
4502 double ref_min_val = -0.00329;
4503 if (std::abs(global_max_val - ref_max_val) > 1e-5) {
4505 "Incorrect max value of the displacement field: %f != %f",
4506 global_max_val, ref_max_val);
4508 if (std::abs(global_min_val - ref_min_val) > 4e-5) {
4510 "Incorrect min value of the displacement field: %f != %f",
4511 global_min_val, ref_min_val);
4522 double start_time) {
4528 PetscOptionsBegin(PETSC_COMM_WORLD,
"",
"Dynamic Relaxation Options",
"none");
4530 CHKERR PetscOptionsScalar(
4531 "-dynamic_final_time",
"dynamic relaxation final time",
"",
4532 finalPhysicalTime, &finalPhysicalTime, PETSC_NULLPTR);
4533 CHKERR PetscOptionsScalar(
"-dynamic_delta_time",
4534 "dynamic relaxation final time",
"", physicalDt,
4535 &physicalDt, PETSC_NULLPTR);
4536 CHKERR PetscOptionsInt(
"-dynamic_max_it",
"dynamic relaxation iterations",
"",
4537 physicalMaxSteps, &physicalMaxSteps, PETSC_NULLPTR);
4538 CHKERR PetscOptionsBool(
"-dynamic_h1_update",
"update each ts step",
"",
4539 physicalH1Update, &physicalH1Update, PETSC_NULLPTR);
4544 <<
"Following options are deprecated, use -physical prefix options "
4547 <<
"Dynamic relaxation final time -dynamic_final_time = "
4548 << finalPhysicalTime;
4550 <<
"Dynamic relaxation delta time -dynamic_delta_time = " << physicalDt;
4552 <<
"Dynamic relaxation max iterations -dynamic_max_it = "
4553 << physicalMaxSteps;
4555 <<
"Dynamic relaxation H1 update each step -dynamic_h1_update = "
4556 << (physicalH1Update ?
"TRUE" :
"FALSE");
4558 CHKERR addDebugModel(ts);
4560 auto setup_ts_monitor = [&]() {
4561 auto monitor_ptr = boost::make_shared<EshelbianMonitor>(*
this);
4564 auto monitor_ptr = setup_ts_monitor();
4566 TetPolynomialBase::switchCacheBaseOn<HDIV>(
4567 {elasticFeLhs.get(), elasticFeRhs.get()});
4571 double ts_delta_time;
4572 CHKERR TSGetTimeStep(ts, &ts_delta_time);
4573 CHKERR TSSetSolution(ts, x);
4575 if (physicalH1Update) {
4579 CHKERR TSSetPreStep(ts, PETSC_NULLPTR);
4580 CHKERR TSSetPostStep(ts, PETSC_NULLPTR);
4586 currentPhysicalTime = start_time;
4587 physicalStepNumber = start_step;
4588 monitor_ptr->ts = PETSC_NULLPTR;
4589 monitor_ptr->ts_u = PETSC_NULLPTR;
4590 monitor_ptr->ts_t = currentPhysicalTime;
4591 monitor_ptr->ts_step = physicalStepNumber;
4594 if (physicalDt <= 0.) {
4596 "physicalDt must be positive, got %g", physicalDt);
4598 for (; currentPhysicalTime < finalPhysicalTime;) {
4600 <<
"Load step " << physicalStepNumber <<
" Time " << currentPhysicalTime
4601 <<
" delta time " << physicalDt;
4603 CHKERR TSSetStepNumber(ts, 0);
4605 CHKERR TSSetTimeStep(ts, ts_delta_time);
4606 CHKERR TSSetSolution(ts, x);
4607 if (!physicalH1Update) {
4610 CHKERR TSSolve(ts, PETSC_NULLPTR);
4611 if (!physicalH1Update) {
4617 CHKERR VecGhostUpdateBegin(x, INSERT_VALUES, SCATTER_FORWARD);
4618 CHKERR VecGhostUpdateEnd(x, INSERT_VALUES, SCATTER_FORWARD);
4620 monitor_ptr->ts = PETSC_NULLPTR;
4621 monitor_ptr->ts_u = x;
4622 monitor_ptr->ts_t = currentPhysicalTime;
4623 monitor_ptr->ts_step = physicalStepNumber;
4626 ++physicalStepNumber;
4627 if (physicalStepNumber > physicalMaxSteps)
4630 const double remainingPhysicalTime =
4631 finalPhysicalTime - currentPhysicalTime;
4632 if (physicalDt >= remainingPhysicalTime) {
4633 currentPhysicalTime = finalPhysicalTime;
4635 currentPhysicalTime += physicalDt;
4640 TetPolynomialBase::switchCacheBaseOff<HDIV>(
4641 {elasticFeLhs.get(), elasticFeRhs.get()});
4649 auto set_block = [&](
auto name,
int dim) {
4650 std::map<int, Range> map;
4651 auto set_tag_impl = [&](
auto name) {
4656 std::regex((boost::format(
"%s(.*)") % name).str())
4659 for (
auto bc : bcs) {
4661 CHKERR bc->getMeshsetIdEntitiesByDimension(mField.get_moab(), dim, r,
4663 map[bc->getMeshsetId()] = r;
4665 <<
"Block " << name <<
" id " << bc->getMeshsetId() <<
" has "
4666 << r.size() <<
" entities";
4671 CHKERR set_tag_impl(name);
4673 return std::make_pair(name, map);
4676 auto set_skin = [&](
auto &&map) {
4677 for (
auto &
m : map.second) {
4681 <<
"Skin for block " << map.first <<
" id " <<
m.first <<
" has "
4682 <<
m.second.size() <<
" entities";
4687 auto set_tag = [&](
auto &&map) {
4689 auto name = map.first;
4690 int def_val[] = {-1};
4692 mField.get_moab().tag_get_handle(name, 1, MB_TYPE_INTEGER,
th,
4693 MB_TAG_SPARSE | MB_TAG_CREAT, def_val),
4695 for (
auto &
m : map.second) {
4703 listTagsToTransfer.push_back(set_tag(set_skin(set_block(
"BODY", 3))));
4704 listTagsToTransfer.push_back(set_tag(set_skin(set_block(
"MAT_ELASTIC", 3))));
4705 listTagsToTransfer.push_back(
4706 set_tag(set_skin(set_block(
"MAT_NEOHOOKEAN", 3))));
4707 listTagsToTransfer.push_back(set_tag(set_block(
"CONTACT", 2)));
4714 std::vector<Tag> tags_to_transfer) {
4716 ParallelComm *pcomm =
4719 if (crackingOn && !pcomm->rank()) {
4722 std::vector<boost::shared_ptr<TempMeshset>> meshsets_tmp_list;
4724 std::vector<Tag> tags_list;
4728 for (
auto &
m : list) {
4730 EntityHandle new_meshset = *meshsets_tmp_list.back();
4731 auto meshset =
m.getMeshset();
4732 std::vector<Tag> tmp_tags_list;
4733 CHKERR mField.get_moab().tag_get_tags_on_entity(meshset, tmp_tags_list);
4735 CHKERR mField.get_moab().get_entities_by_handle(meshset, ents,
true);
4736 CHKERR mField.get_moab().add_entities(new_meshset, ents);
4737 for (
auto t : tmp_tags_list) {
4740 CHKERR mField.get_moab().tag_get_by_ptr(
4741 t, &meshset, 1, (
const void **)tag_vals, tag_size);
4742 CHKERR mField.get_moab().tag_set_by_ptr(
t, &new_meshset, 1, tag_vals,
4745 std::vector<std::string> remove_tags;
4746 remove_tags.push_back(
"AKDTree_coord_norm");
4747 remove_tags.push_back(
"__PARALLEL_");
4748 remove_tags.push_back(
"_RefBitLevel");
4750 for (
auto t : tmp_tags_list) {
4751 std::string tag_name;
4752 CHKERR mField.get_moab().tag_get_name(
t, tag_name);
4755 for (
auto &p : remove_tags) {
4756 if (tag_name.compare(0, p.size(), p) == 0) {
4763 tags_list.push_back(
t);
4767 for (
auto &m_ptr : meshsets_tmp_list) {
4768 EntityHandle
m = *m_ptr;
4769 CHKERR mField.get_moab().add_entities(*meshset_ptr, &
m, 1);
4773 std::sort(tags_list.begin(), tags_list.end());
4774 auto new_end = std::unique(tags_list.begin(), tags_list.end());
4775 tags_list.resize(std::distance(tags_list.begin(), new_end));
4777 EntityHandle save_meshset = *meshset_ptr;
4778 CHKERR mField.get_moab().write_file(file.c_str(),
"MOAB",
"", &save_meshset,
4779 1, &tags_list[0], tags_list.size());
4786 Vec f_residual, Vec var_vector, Vec gradient,
4787 std::vector<Tag> tags_to_transfer, TS ts) {
4791 if (f_residual != PETSC_NULLPTR || var_vector != PETSC_NULLPTR) {
4795 auto xin = f_residual != PETSC_NULLPTR ? f_residual : var_vector;
4801 CHKERR VecScatterBegin(scatter, f_residual, f_r, INSERT_VALUES,
4803 CHKERR VecScatterEnd(scatter, f_residual, f_r, INSERT_VALUES,
4805 CHKERR VecGhostUpdateBegin(f_r, INSERT_VALUES, SCATTER_FORWARD);
4806 CHKERR VecGhostUpdateEnd(f_r, INSERT_VALUES, SCATTER_FORWARD);
4810 CHKERR VecScatterBegin(scatter, var_vector, v_v, INSERT_VALUES,
4812 CHKERR VecScatterEnd(scatter, var_vector, v_v, INSERT_VALUES,
4814 CHKERR VecGhostUpdateBegin(v_v, INSERT_VALUES, SCATTER_FORWARD);
4815 CHKERR VecGhostUpdateEnd(v_v, INSERT_VALUES, SCATTER_FORWARD);
4826 CHKERR VecScatterBegin(scatter, gradient,
g, INSERT_VALUES,
4828 CHKERR VecScatterEnd(scatter, gradient,
g, INSERT_VALUES, SCATTER_FORWARD);
4829 CHKERR VecGhostUpdateBegin(
g, INSERT_VALUES, SCATTER_FORWARD);
4830 CHKERR VecGhostUpdateEnd(
g, INSERT_VALUES, SCATTER_FORWARD);
4835 auto get_tag = [&](
auto name,
auto dim) {
4836 auto &mob = mField.get_moab();
4838 double def_val[] = {0., 0., 0.};
4839 CHK_MOAB_THROW(mob.tag_get_handle(name, dim, MB_TYPE_DOUBLE, tag,
4840 MB_TAG_CREAT | MB_TAG_SPARSE, def_val),
4844 tags_to_transfer.push_back(
get_tag(
"MaterialForce", 3));
4848 auto get_crack_tag = [&]() {
4850 rval = mField.get_moab().tag_get_handle(
"CRACK",
th);
4851 if (
rval == MB_SUCCESS) {
4854 int def_val[] = {0};
4856 "CRACK", 1, MB_TYPE_INTEGER,
th, MB_TAG_SPARSE | MB_TAG_CREAT,
4861 Tag th = get_crack_tag();
4862 tags_to_transfer.push_back(
th);
4866 mark_faces.merge(*crackFaces);
4868 mark_faces.merge(*interfaceFaces);
4869 CHKERR mField.get_moab().tag_clear_data(
th, mark_faces, mark);
4873 for (
auto t : listTagsToTransfer) {
4875 CHKERR mField.get_moab().tag_get_name(
t, name);
4877 <<
"Adding tag " << name <<
" to transfer list for post-processing";
4878 tags_to_transfer.push_back(
t);
4888 auto get_post_proc = [&](
auto &post_proc_mesh,
auto sense) {
4890 auto post_proc_ptr =
4891 boost::make_shared<PostProcBrokenMeshInMoabBaseCont<FaceEle>>(
4892 mField, post_proc_mesh);
4893 EshelbianPlasticity::AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
4894 post_proc_ptr->getOpPtrVector(), {L2}, materialH1Positions,
4897 if (ts != PETSC_NULLPTR) {
4899 CHKERR TSGetTime(ts, &(post_proc_ptr->ts_t));
4900 CHKERR TSGetTimeStep(ts, &(post_proc_ptr->ts_dt));
4903 auto domain_ops = [&](
auto &fe,
int sense) {
4906 auto bubble_cache = boost::make_shared<CGGUserPolynomialBase::CachePhi>(
4908 fe.getUserPolynomialBase() = boost::shared_ptr<BaseFunction>(
4910 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
4911 fe.getOpPtrVector(), {HDIV, H1, L2}, materialH1Positions,
4913 auto piola_scale_ptr = boost::make_shared<double>(1.0);
4915 piolaStress, dataAtPts->getApproxPAtPts(), piola_scale_ptr));
4916 constexpr bool add_bubble =
true;
4919 bubbleField, dataAtPts->getApproxPAtPts(), piola_scale_ptr,
4923 rotAxis, dataAtPts->getRotAxisAtPts(), MBTET));
4924 if (isNoStretch()) {
4926 fe.getOpPtrVector(), physicalEquations, dataAtPts,
4927 externalStrainVecPtr, timeScaleMap);
4929 fe.getOpPtrVector().push_back(
4931 stretchTensor, dataAtPts->getLogStretchTensorAtPts(), MBTET));
4933 CHKERR VecSetDM(solTSStep, PETSC_NULLPTR);
4935 piolaStress, dataAtPts->getApproxP0AtPts(),
nullptr, solTSStep));
4938 bubbleField, dataAtPts->getApproxP0AtPts(),
nullptr, solTSStep,
4941 if (!isNoStretch()) {
4942 fe.getOpPtrVector().push_back(
4944 stretchTensor, dataAtPts->getLogStretchTensor0AtPts(),
4949 piolaStress, dataAtPts->getVarPiolaPts(),
4950 boost::make_shared<double>(1), v_v));
4952 bubbleField, dataAtPts->getVarPiolaPts(),
4953 boost::make_shared<double>(1), v_v, MBMAXTYPE));
4955 rotAxis, dataAtPts->getVarRotAxisPts(), v_v, MBTET));
4956 if (isNoStretch()) {
4957 fe.getOpPtrVector().push_back(
4958 physicalEquations->returnOpCalculateVarStretchFromStress(
4959 dataAtPts, physicalEquations));
4961 fe.getOpPtrVector().push_back(
4963 stretchTensor, dataAtPts->getVarLogStreachPts(), v_v, MBTET));
4968 materialH1Positions, dataAtPts->getGradientAtPts(),
g));
4972 rotAxis, dataAtPts->getRotAxis0AtPts(), solTSStep, MBTET));
4975 spatialL2Disp, dataAtPts->getSmallWL2AtPts(), MBTET));
4977 spatialH1Disp, dataAtPts->getSmallWH1AtPts()));
4979 spatialH1Disp, dataAtPts->getSmallWGradH1AtPts()));
4981 fe.getOpPtrVector().push_back(
4985 fe.getOpPtrVector().push_back(physicalEquations->returnOpJacobian(
4986 true,
false, dataAtPts, physicalEquations));
4988 physicalEquations->returnOpCalculateEnergy(dataAtPts,
nullptr)) {
4989 fe.getOpPtrVector().push_back(op);
4998 struct OpSidePPMap :
public OpPPMap {
4999 OpSidePPMap(moab::Interface &post_proc_mesh,
5000 std::vector<EntityHandle> &map_gauss_pts,
5001 DataMapVec data_map_scalar, DataMapMat data_map_vec,
5002 DataMapMat data_map_mat, DataMapMat data_symm_map_mat,
5004 :
OpPPMap(post_proc_mesh, map_gauss_pts, data_map_scalar,
5005 data_map_vec, data_map_mat, data_symm_map_mat),
5012 if (tagSense != 0) {
5013 if (tagSense != OpPPMap::getSkeletonSense())
5026 vec_fields[
"SpatialDisplacementL2"] = dataAtPts->getSmallWL2AtPts();
5027 vec_fields[
"SpatialDisplacementH1"] = dataAtPts->getSmallWH1AtPts();
5028 vec_fields[
"Omega"] = dataAtPts->getRotAxisAtPts();
5029 vec_fields[
"AngularMomentum"] = dataAtPts->getLeviKirchhoffAtPts();
5030 vec_fields[
"X"] = dataAtPts->getLargeXH1AtPts();
5031 if (!isNoStretch()) {
5032 vec_fields[
"EiegnLogStreach"] = dataAtPts->getEigenVals();
5035 vec_fields[
"VarOmega"] = dataAtPts->getVarRotAxisPts();
5036 vec_fields[
"VarSpatialDisplacementL2"] =
5037 boost::make_shared<MatrixDouble>();
5039 spatialL2Disp, vec_fields[
"VarSpatialDisplacementL2"], v_v, MBTET));
5042 vec_fields[
"ResSpatialDisplacementL2"] =
5043 boost::make_shared<MatrixDouble>();
5045 spatialL2Disp, vec_fields[
"ResSpatialDisplacementL2"], f_r, MBTET));
5046 vec_fields[
"ResOmega"] = boost::make_shared<MatrixDouble>();
5048 rotAxis, vec_fields[
"ResOmega"], f_r, MBTET));
5051 vec_fields[
"Gradient"] = dataAtPts->getGradientAtPts();
5055 mat_fields[
"PiolaStress"] = dataAtPts->getApproxPAtPts();
5057 mat_fields[
"VarPiolaStress"] = dataAtPts->getVarPiolaPts();
5060 mat_fields[
"ResPiolaStress"] = boost::make_shared<MatrixDouble>();
5062 piolaStress, mat_fields[
"ResPiolaStress"],
5063 boost::make_shared<double>(1), f_r));
5065 bubbleField, mat_fields[
"ResPiolaStress"],
5066 boost::make_shared<double>(1), f_r, MBMAXTYPE));
5068 if (!internalStressTagName.empty()) {
5069 mat_fields[internalStressTagName] = dataAtPts->getInternalStressAtPts();
5070 switch (meshTransferInterpOrder) {
5072 fe.getOpPtrVector().push_back(
5076 fe.getOpPtrVector().push_back(
5081 "Unsupported mesh transfer interpolation order %d, for "
5083 meshTransferInterpOrder);
5088 mat_fields_symm[
"LogSpatialStretch"] =
5089 dataAtPts->getLogStretchTensorAtPts();
5090 mat_fields_symm[
"SpatialStretch"] = dataAtPts->getStretchTensorAtPts();
5092 mat_fields_symm[
"VarLogSpatialStretch"] =
5093 dataAtPts->getVarLogStreachPts();
5096 if (!isNoStretch()) {
5097 mat_fields_symm[
"ResLogSpatialStretch"] =
5098 boost::make_shared<MatrixDouble>();
5099 fe.getOpPtrVector().push_back(
5101 stretchTensor, mat_fields_symm[
"ResLogSpatialStretch"], f_r,
5106 fe.getOpPtrVector().push_back(
5110 post_proc_ptr->getPostProcMesh(), post_proc_ptr->getMapGaussPts(),
5127 post_proc_ptr->getPostProcMesh(), post_proc_ptr->getMapGaussPts(),
5133 auto X_h1_ptr = boost::make_shared<MatrixDouble>();
5135 post_proc_ptr->getOpPtrVector().push_back(
5137 dataAtPts->getLargeXH1AtPts()));
5142 domain_ops(*(op_loop_side->getSideFEPtr()), sense);
5143 post_proc_ptr->getOpPtrVector().push_back(op_loop_side);
5145 return post_proc_ptr;
5149 auto calcs_side_traction_and_displacements = [&](
auto &post_proc_ptr,
5155 using SideEleOp = EleOnSide::UserDataOperator;
5157 mField, elementVolumeName,
SPACE_DIM, Sev::noisy);
5158 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
5159 boost::shared_ptr<BaseFunction>(
5161 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
5162 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
5163 materialH1Positions, frontAdjEdges);
5164 auto traction_ptr = boost::make_shared<MatrixDouble>();
5165 op_loop_domain_side->getOpPtrVector().push_back(
5167 piolaStress, traction_ptr, boost::make_shared<double>(1.0)));
5170 contactDisp, dataAtPts->getContactL2AtPts()));
5171 pip.push_back(op_loop_domain_side);
5173 auto u_h1_ptr = boost::make_shared<MatrixDouble>();
5176 *
this, contactTreeRhs, u_h1_ptr, traction_ptr,
5178 &post_proc_ptr->getPostProcMesh(), &post_proc_ptr->getMapGaussPts()));
5184 pip.push_back(op_this);
5186 op_this->getOpPtrVector().push_back(
5190 post_proc_ptr->getPostProcMesh(), post_proc_ptr->getMapGaussPts(),
5194 {{
"ContactDisplacement", dataAtPts->getContactL2AtPts()}},
5206 auto contact_residual = boost::make_shared<MatrixDouble>();
5207 op_this->getOpPtrVector().push_back(
5209 contactDisp, contact_residual, f_r, MBTET));
5210 op_this->getOpPtrVector().push_back(
5214 post_proc_ptr->getPostProcMesh(), post_proc_ptr->getMapGaussPts(),
5218 {{
"res_contact", contact_residual}},
5232 auto post_proc_mesh = boost::make_shared<moab::Core>();
5233 auto post_proc_ptr = get_post_proc(post_proc_mesh, 1);
5234 auto post_proc_negative_sense_ptr =
5235 get_post_proc(post_proc_mesh, -1);
5236 auto skin_post_proc_ptr = get_post_proc(post_proc_mesh, 1);
5237 CHKERR calcs_side_traction_and_displacements(
5238 skin_post_proc_ptr, skin_post_proc_ptr->getOpPtrVector());
5244 CHKERR mField.get_moab().get_adjacencies(own_tets,
SPACE_DIM - 1,
true,
5245 own_faces, moab::Interface::UNION);
5247 auto get_crack_faces = [&](
auto crack_faces) {
5248 auto get_adj = [&](
auto e,
auto dim) {
5250 CHKERR mField.get_moab().get_adjacencies(e, dim,
true, adj,
5251 moab::Interface::UNION);
5255 auto tets = get_adj(crack_faces, 3);
5257 auto faces = subtract(get_adj(tets, 2), crack_faces);
5259 tets = subtract(tets, get_adj(faces, 3));
5260 return subtract(crack_faces, get_adj(tets, 2));
5263 auto side_one_faces = [&](
auto &faces) {
5264 std::pair<Range, Range> sides;
5265 for (
auto f : faces) {
5267 MOAB_THROW(mField.get_moab().get_adjacencies(&f, 1, 3,
false, adj));
5268 adj = intersect(own_tets, adj);
5269 for (
auto t : adj) {
5270 int side, sense, offset;
5271 MOAB_THROW(mField.get_moab().side_number(
t, f, side, sense, offset));
5273 sides.first.insert(f);
5275 sides.second.insert(f);
5282 auto get_interface_from_block = [&](
auto block_name) {
5286 CHKERR mField.get_moab().get_adjacencies(vol_eles,
SPACE_DIM - 1,
true,
5287 faces, moab::Interface::UNION);
5288 faces = subtract(faces, skin);
5292 auto crack_faces = unite(get_crack_faces(*crackFaces), *interfaceFaces);
5295 auto crack_side_faces = side_one_faces(crack_faces);
5296 auto side_one_crack_faces = [crack_side_faces](
FEMethod *fe_method_ptr) {
5297 auto ent = fe_method_ptr->getFEEntityHandle();
5298 if (crack_side_faces.first.find(ent) == crack_side_faces.first.end()) {
5303 auto side_minus_crack_faces = [crack_side_faces](
FEMethod *fe_method_ptr) {
5304 auto ent = fe_method_ptr->getFEEntityHandle();
5305 if (crack_side_faces.second.find(ent) == crack_side_faces.second.end()) {
5311 skin_post_proc_ptr->setTagsToTransfer(tags_to_transfer);
5312 post_proc_ptr->setTagsToTransfer(tags_to_transfer);
5313 post_proc_negative_sense_ptr->setTagsToTransfer(tags_to_transfer);
5315 auto post_proc_begin =
5319 post_proc_ptr->exeTestHook = side_one_crack_faces;
5321 dM, skeletonElement, post_proc_ptr, 0, mField.get_comm_size());
5322 post_proc_negative_sense_ptr->exeTestHook = side_minus_crack_faces;
5324 post_proc_negative_sense_ptr, 0,
5325 mField.get_comm_size());
5327 constexpr bool debug =
false;
5330 auto get_adj_front = [&]() {
5331 auto skeleton_faces = *skeletonFaces;
5333 CHKERR mField.get_moab().get_adjacencies(*frontEdges, 2,
true, adj_front,
5334 moab::Interface::UNION);
5336 adj_front = intersect(adj_front, skeleton_faces);
5337 adj_front = subtract(adj_front, *crackFaces);
5338 adj_front = intersect(own_faces, adj_front);
5343 auto only_front_faces = [adj_front](
FEMethod *fe_method_ptr) {
5344 auto ent = fe_method_ptr->getFEEntityHandle();
5345 if (adj_front.find(ent) == adj_front.end()) {
5351 post_proc_ptr->exeTestHook = only_front_faces;
5353 dM, skeletonElement, post_proc_ptr, 0, mField.get_comm_size());
5354 post_proc_negative_sense_ptr->exeTestHook = only_front_faces;
5356 post_proc_negative_sense_ptr, 0,
5357 mField.get_comm_size());
5362 CHKERR post_proc_end.writeFile(
file.c_str());
5369 std::vector<Tag> tags_to_transfer,
5374 if (f_residual != PETSC_NULLPTR) {
5380 CHKERR VecScatterBegin(scatter, f_residual, f_r, INSERT_VALUES,
5382 CHKERR VecScatterEnd(scatter, f_residual, f_r, INSERT_VALUES,
5388 auto post_proc_mesh = boost::make_shared<moab::Core>();
5389 auto post_proc_ptr =
5390 boost::make_shared<PostProcBrokenMeshInMoabBaseCont<FaceEle>>(
5392 if (ts != PETSC_NULLPTR) {
5394 CHKERR TSGetTime(ts, &post_proc_ptr->ts_t);
5395 CHKERR TSGetTimeStep(ts, &post_proc_ptr->ts_dt);
5397 EshelbianPlasticity::AddHOOps<SPACE_DIM - 1, SPACE_DIM - 1, SPACE_DIM>::add(
5401 auto hybrid_disp = boost::make_shared<MatrixDouble>();
5402 post_proc_ptr->getOpPtrVector().push_back(
5404 post_proc_ptr->getOpPtrVector().push_back(
5408 auto op_loop_domain_side =
5411 post_proc_ptr->getOpPtrVector().push_back(op_loop_domain_side);
5414 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
5415 boost::make_shared<CGGUserPolynomialBase>(
nullptr,
true);
5416 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
5417 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
5419 op_loop_domain_side->getOpPtrVector().push_back(
5422 op_loop_domain_side->getOpPtrVector().push_back(
5425 op_loop_domain_side->getOpPtrVector().push_back(
5430 pushOpCalculateStretchFromStress(
5434 op_loop_domain_side->getOpPtrVector().push_back(
5442 vec_fields[
"HybridDisplacement"] = hybrid_disp;
5444 vec_fields[
"spatialL2Disp"] =
dataAtPts->getSmallWL2AtPts();
5445 vec_fields[
"Omega"] =
dataAtPts->getRotAxisAtPts();
5447 mat_fields[
"PiolaStress"] =
dataAtPts->getApproxPAtPts();
5448 mat_fields[
"HybridDisplacementGradient"] =
5451 mat_fields_symm[
"LogSpatialStretch"] =
dataAtPts->getLogStretchTensorAtPts();
5453 post_proc_ptr->getOpPtrVector().push_back(
5457 post_proc_ptr->getPostProcMesh(), post_proc_ptr->getMapGaussPts(),
5472 auto hybrid_res = boost::make_shared<MatrixDouble>();
5473 post_proc_ptr->getOpPtrVector().push_back(
5477 post_proc_ptr->getOpPtrVector().push_back(
5481 post_proc_ptr->getPostProcMesh(), post_proc_ptr->getMapGaussPts(),
5485 {{
"res_hybrid", hybrid_res}},
5496 post_proc_ptr->setTagsToTransfer(tags_to_transfer);
5498 auto post_proc_begin =
5505 CHKERR post_proc_end.writeFile(file.c_str());
5514 auto post_proc_norm_fe =
5515 boost::make_shared<VolumeElementForcesAndSourcesCore>(
mField);
5518 boost::make_shared<CGGUserPolynomialBase::CachePhi>(0, 0,
MatrixDouble());
5519 post_proc_norm_fe->getUserPolynomialBase() =
5521 post_proc_norm_fe->getRuleHook = [](int, int, int) {
return -1; };
5522 post_proc_norm_fe->setRuleHook = SetIntegrationAtFrontVolume(
5524 CHKERR EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
5528 enum NORMS { U_NORM_L2 = 0, U_NORM_H1, PIOLA_NORM, U_ERROR_L2, LAST_NORM };
5531 CHKERR VecZeroEntries(norms_vec);
5533 auto u_l2_ptr = boost::make_shared<MatrixDouble>();
5534 auto u_h1_ptr = boost::make_shared<MatrixDouble>();
5535 post_proc_norm_fe->getOpPtrVector().push_back(
5537 post_proc_norm_fe->getOpPtrVector().push_back(
5539 post_proc_norm_fe->getOpPtrVector().push_back(
5541 post_proc_norm_fe->getOpPtrVector().push_back(
5543 post_proc_norm_fe->getOpPtrVector().push_back(
5547 auto piola_ptr = boost::make_shared<MatrixDouble>();
5548 post_proc_norm_fe->getOpPtrVector().push_back(
5550 post_proc_norm_fe->getOpPtrVector().push_back(
5554 post_proc_norm_fe->getOpPtrVector().push_back(
5557 TetPolynomialBase::switchCacheBaseOn<HDIV>({post_proc_norm_fe.get()});
5559 *post_proc_norm_fe);
5560 TetPolynomialBase::switchCacheBaseOff<HDIV>({post_proc_norm_fe.get()});
5562 CHKERR VecAssemblyBegin(norms_vec);
5563 CHKERR VecAssemblyEnd(norms_vec);
5564 const double *norms;
5565 CHKERR VecGetArrayRead(norms_vec, &norms);
5566 MOFEM_LOG(
"EP", Sev::inform) <<
"norm_u: " << std::sqrt(norms[U_NORM_L2]);
5567 MOFEM_LOG(
"EP", Sev::inform) <<
"norm_u_h1: " << std::sqrt(norms[U_NORM_H1]);
5569 <<
"norm_error_u_l2: " << std::sqrt(norms[U_ERROR_L2]);
5571 <<
"norm_piola: " << std::sqrt(norms[PIOLA_NORM]);
5572 CHKERR VecRestoreArrayRead(norms_vec, &norms);
5588 auto get_fix_load_history = [&](
const std::string &block_name) {
5589 for (
const auto type_name : {
"FIX_X",
"FIX_Y",
"FIX_Z",
"FIX_ALL"}) {
5593 (boost::format(
"%s(.*)") % type_name).str()
5598 if (it->getName() == block_name) {
5600 type_name, it->getMeshsetId(),
"load_history");
5604 return std::string();
5607 for (
auto bc : bc_mng->getBcMapByBlockName()) {
5608 if (
auto disp_bc = bc.second->dispBcPtr) {
5613 <<
"Field name: " <<
field_name <<
" Block name: " << block_name;
5614 MOFEM_LOG(
"EP", Sev::noisy) <<
"Displacement BC: " << *disp_bc;
5616 std::vector<double> block_attributes(6, 0.);
5617 if (disp_bc->data.flag1 == 1) {
5618 block_attributes[0] = disp_bc->data.value1;
5619 block_attributes[3] = 1;
5621 if (disp_bc->data.flag2 == 1) {
5622 block_attributes[1] = disp_bc->data.value2;
5623 block_attributes[4] = 1;
5625 if (disp_bc->data.flag3 == 1) {
5626 block_attributes[2] = disp_bc->data.value3;
5627 block_attributes[5] = 1;
5629 auto faces = bc.second->bcEnts.subset_by_dimension(2);
5631 get_fix_load_history(block_name));
5638 boost::make_shared<NormalDisplacementBcVec>();
5643 for (
auto it : mesh_mng->getCubitMeshsetPtr(
5644 std::regex((boost::format(
"(.*)%s(.*)") %
"SPRING_BC").str()))) {
5645 std::vector<double> block_attributes;
5646 CHKERR it->getAttributes(block_attributes);
5647 if (block_attributes.size() < 2) {
5649 "In block %s expected 2 attributes, but given %ld",
5650 it->getName().c_str(), block_attributes.size());
5656 <<
"Found spring BC on block " << it->getName();
5658 <<
" kn = " << block_attributes[0] <<
", kt = " << block_attributes[1];
5659 MOFEM_LOG(
"EP", Sev::inform) <<
" nb. of faces " << faces.size();
5664 boost::make_shared<AnalyticalDisplacementBcVec>();
5668 auto ts_displacement =
5669 boost::make_shared<DynamicRelaxationTimeScale>(
"disp_history.txt");
5672 <<
"Add time scaling displacement BC: " << bc.blockName;
5673 if (!bc.loadHistoryFile.empty()) {
5675 <<
"Displacement load history from JSON for " << bc.blockName <<
": "
5676 << bc.loadHistoryFile;
5678 boost::make_shared<DynamicRelaxationTimeScale>(bc.loadHistoryFile);
5682 ts_displacement,
"disp_history",
".txt", bc.blockName);
5686 auto ts_normal_displacement =
5687 boost::make_shared<DynamicRelaxationTimeScale>(
"normal_disp_history.txt");
5690 <<
"Add time scaling normal displacement BC: " << bc.blockName;
5691 if (!bc.loadHistoryFile.empty()) {
5693 <<
"Normal displacement load history from JSON for " << bc.blockName
5694 <<
": " << bc.loadHistoryFile;
5696 boost::make_shared<DynamicRelaxationTimeScale>(bc.loadHistoryFile);
5700 ts_normal_displacement,
"normal_disp_history",
".txt",
5717 for (
auto bc : bc_mng->getBcMapByBlockName()) {
5718 if (
auto force_bc = bc.second->forceBcPtr) {
5723 <<
"Field name: " <<
field_name <<
" Block name: " << block_name;
5724 MOFEM_LOG(
"EP", Sev::noisy) <<
"Force BC: " << *force_bc;
5726 std::vector<double> block_attributes(6, 0.);
5727 block_attributes[0] = -force_bc->data.value3 * force_bc->data.value1;
5728 block_attributes[3] = 1;
5729 block_attributes[1] = -force_bc->data.value4 * force_bc->data.value1;
5730 block_attributes[4] = 1;
5731 block_attributes[2] = -force_bc->data.value5 * force_bc->data.value1;
5732 block_attributes[5] = 1;
5733 auto faces = bc.second->bcEnts.subset_by_dimension(2);
5744 boost::make_shared<AnalyticalTractionBcVec>();
5748 boost::make_shared<DynamicRelaxationTimeScale>(
"traction_history.txt");
5750 if (!bc.loadHistoryFile.empty()) {
5752 <<
"Traction load history from JSON for " << bc.blockName <<
": "
5753 << bc.loadHistoryFile;
5755 boost::make_shared<DynamicRelaxationTimeScale>(bc.loadHistoryFile);
5759 ts_traction,
"traction_history",
".txt", bc.blockName);
5764 boost::make_shared<DynamicRelaxationTimeScale>(
"pressure_history.txt");
5766 if (!bc.loadHistoryFile.empty()) {
5768 <<
"Pressure load history from JSON for " << bc.blockName <<
": "
5769 << bc.loadHistoryFile;
5771 boost::make_shared<DynamicRelaxationTimeScale>(bc.loadHistoryFile);
5775 ts_pressure,
"pressure_history",
".txt", bc.blockName);
5786 &ext_strain_vec_ptr,
5787 const std::string block_name,
5788 const int nb_attributes) {
5791 std::regex((boost::format(
"(.*)%s(.*)") % block_name).str()))) {
5792 std::vector<double> block_attributes;
5793 const bool analytical_external_strain = std::regex_match(
5794 it->getName(), std::regex(
"(.*)ANALYTICAL_EXTERNALSTRAIN(.*)"));
5795 const std::string json_block_name =
5796 analytical_external_strain ?
"ANALYTICAL_EXTERNALSTRAIN" : block_name;
5798 CHKERR it->getAttributes(block_attributes);
5800 if (block_attributes.size() < nb_attributes) {
5802 "In block %s expected %d attributes, but given %ld",
5803 it->getName().c_str(), nb_attributes, block_attributes.size());
5806 auto get_block_ents = [&]() {
5813 std::string load_history;
5814 if (!analytical_external_strain) {
5816 json_block_name, it->getMeshsetId(),
"load_history");
5818 ext_strain_vec_ptr->emplace_back(it->getName(), block_attributes,
5819 get_block_ents(), load_history);
5828 auto ts_pre_stretch = boost::make_shared<DynamicRelaxationTimeScale>(
5829 "externalstrain_history.txt");
5832 <<
"Add time scaling external strain: " << ext_strain_block.blockName;
5833 if (!ext_strain_block.loadHistoryFile.empty()) {
5835 <<
"External strain load history from JSON for "
5836 << ext_strain_block.blockName <<
": "
5837 << ext_strain_block.loadHistoryFile;
5839 boost::make_shared<DynamicRelaxationTimeScale>(
5840 ext_strain_block.loadHistoryFile);
5844 ts_pre_stretch,
"externalstrain_history",
".txt",
5845 ext_strain_block.blockName);
5855 auto print_loc_size = [
this](
auto v,
auto str,
auto sev) {
5858 CHKERR VecGetLocalSize(
v.second, &size);
5860 CHKERR VecGetOwnershipRange(
v.second, &low, &high);
5861 MOFEM_LOG(
"EPSYNC", sev) << str <<
" local size " << size <<
" ( " << low
5862 <<
" " << high <<
" ) ";
5885 double start_time) {
5888 auto storage = solve_elastic_setup::setup(
this, ts, x,
false);
5890 auto cohesive_tao_ctx = createCohesiveTAOCtx(
5895 PetscOptionsBegin(PETSC_COMM_WORLD,
"",
"Dynamic Relaxation Options",
"none");
5897 CHKERR PetscOptionsScalar(
5898 "-dynamic_final_time",
"dynamic relaxation final time",
"",
5900 CHKERR PetscOptionsScalar(
"-dynamic_delta_time",
5901 "dynamic relaxation final time",
"",
physicalDt,
5903 CHKERR PetscOptionsInt(
"-dynamic_max_it",
"dynamic relaxation iterations",
"",
5905 CHKERR PetscOptionsBool(
"-dynamic_h1_update",
"update each ts step",
"",
5912 <<
"Dynamic relaxation final time -dynamic_final_time = "
5915 <<
"Dynamic relaxation delta time -dynamic_delta_time = " <<
physicalDt;
5917 <<
"Dynamic relaxation max iterations -dynamic_max_it = "
5920 <<
"Dynamic relaxation H1 update each step -dynamic_h1_update = "
5923 CHKERR initializeCohesiveKappaField(*
this);
5926 auto setup_ts_monitor = [&]() {
5927 auto monitor_ptr = boost::make_shared<EshelbianMonitor>(*
this);
5930 auto monitor_ptr = setup_ts_monitor();
5932 TetPolynomialBase::switchCacheBaseOn<HDIV>(
5935 CHKERR TSElasticPostStep::postStepInitialise(
this);
5937 double ts_delta_time;
5938 CHKERR TSGetTimeStep(ts, &ts_delta_time);
5941 CHKERR TSSetPreStep(ts, TSElasticPostStep::preStepFun);
5942 CHKERR TSSetPostStep(ts, TSElasticPostStep::postStepFun);
5946 CHKERR TaoSetType(tao, TAOLMVM);
5947 auto g = cohesive_tao_ctx->duplicateGradientVec();
5949 cohesiveEvaluateObjectiveAndGradient,
5950 (
void *)cohesive_tao_ctx.get());
5954 monitor_ptr->ts = PETSC_NULLPTR;
5955 monitor_ptr->ts_u = PETSC_NULLPTR;
5960 auto tao_sol0 = cohesive_tao_ctx->duplicateKappaVec();
5961 int tao_sol_size, tao_sol_loc_size;
5962 CHKERR VecGetSize(tao_sol0, &tao_sol_size);
5963 CHKERR VecGetLocalSize(tao_sol0, &tao_sol_loc_size);
5965 <<
"Cohesive crack growth initial kappa vector size " << tao_sol_size
5966 <<
" local size " << tao_sol_loc_size <<
" number of interface faces "
5969 CHKERR TaoSetFromOptions(tao);
5974 CHKERR VecSet(xu, PETSC_INFINITY);
5975 CHKERR TaoSetVariableBounds(tao, xl, xu);
5979 "physicalDt must be positive, got %g",
physicalDt);
5986 CHKERR VecZeroEntries(tao_sol0);
5987 CHKERR VecGhostUpdateBegin(tao_sol0, INSERT_VALUES, SCATTER_FORWARD);
5988 CHKERR VecGhostUpdateEnd(tao_sol0, INSERT_VALUES, SCATTER_FORWARD);
5989 CHKERR TaoSetSolution(tao, tao_sol0);
5992 CHKERR TSElasticPostStep::preStepFun(ts);
5997 CHKERR TaoGetSolution(tao, &tao_sol);
6000 auto &kappa_vec = cohesive_tao_ctx->getKappaVec();
6003 CHKERR VecAXPY(kappa_vec.second, 1.0, tao_sol);
6004 CHKERR VecGhostUpdateBegin(kappa_vec.second, INSERT_VALUES,
6006 CHKERR VecGhostUpdateEnd(kappa_vec.second, INSERT_VALUES, SCATTER_FORWARD);
6012 CHKERR VecGhostUpdateBegin(x, INSERT_VALUES, SCATTER_FORWARD);
6013 CHKERR VecGhostUpdateEnd(x, INSERT_VALUES, SCATTER_FORWARD);
6014 monitor_ptr->ts = PETSC_NULLPTR;
6015 monitor_ptr->ts_u = x;
6021 CHKERR TSElasticPostStep::postStepFun(ts);
6028 const double remainingPhysicalTime =
6037 CHKERR TSElasticPostStep::postStepDestroy();
6038 TetPolynomialBase::switchCacheBaseOff<HDIV>(
6045 double start_time) {
6050 auto storage = solve_elastic_setup::setup(
this, ts, x,
false);
6054 auto setup_ts_monitor = [&]() {
6055 auto monitor_ptr = boost::make_shared<EshelbianMonitor>(*
this);
6058 auto monitor_ptr = setup_ts_monitor();
6060 auto test_monitor_ptr =
6061 boost::make_shared<EshelbianTestingMonitor>(*
this, monitor_ptr);
6063 TetPolynomialBase::switchCacheBaseOn<HDIV>(
6066 CHKERR TSElasticPostStep::postStepInitialise(
this);
6068 double ts_delta_time;
6069 CHKERR TSGetTimeStep(ts, &ts_delta_time);
6072 CHKERR TSSetPreStep(ts, TSElasticPostStep::preStepFun);
6073 CHKERR TSSetPostStep(ts, TSElasticPostStep::postStepFun);
6076 CHKERR TSElasticPostStep::preStepFun(ts);
6077 CHKERR TSElasticPostStep::postStepFun(ts);
6079 double load_factor_change_clip = 0.1;
6081 PetscOptionsBegin(PETSC_COMM_WORLD,
"",
"Load Factor Options",
"none");
6083 CHKERR PetscOptionsScalar(
"-initial_load_factor",
"Initial load factor",
"",
6085 CHKERR PetscOptionsScalar(
6086 "-max_crack_ext_area",
"Maximum crack extension area",
"",
6088 CHKERR PetscOptionsScalar(
6089 "-clip_load_factor_percent",
"Upper bound for load factor change",
"",
6090 load_factor_change_clip, &load_factor_change_clip, PETSC_NULLPTR);
6095 monitor_ptr->ts = ts;
6096 monitor_ptr->ts_u = PETSC_NULLPTR;
6101 PetscBool test_cook_flg = PETSC_FALSE;
6108 test_monitor_ptr->ts = ts;
6109 test_monitor_ptr->ts_u = PETSC_NULLPTR;
6132 CHKERR TSSetStepNumber(ts, 0);
6134 CHKERR TSSetTimeStep(ts, ts_delta_time);
6136 CHKERR TSElasticPostStep::preStepFun(ts);
6138 CHKERR TSSetSolution(ts, x);
6139 CHKERR TSSolve(ts, PETSC_NULLPTR);
6142 CHKERR TSElasticPostStep::postStepFun(ts);
6147 CHKERR VecGhostUpdateBegin(x, INSERT_VALUES, SCATTER_FORWARD);
6148 CHKERR VecGhostUpdateEnd(x, INSERT_VALUES, SCATTER_FORWARD);
6150 monitor_ptr->ts = ts;
6151 monitor_ptr->ts_u = x;
6157 test_monitor_ptr->ts = ts;
6158 test_monitor_ptr->ts_u = x;
6167 const bool has_crack_extension = delta_area > 0.0;
6169 if (has_crack_extension) {
6172 const double updated_load_factor =
6174 loadFactor = std::max(updated_load_factor, 1.0e-6);
6179 const double initial_step_range = 5;
6180 const double min_load_factor = 1.0e-6;
6181 const double max_load_factor =
6187 <<
"Allowable range for load factor [" << min_load_factor <<
", "
6188 << max_load_factor <<
"]";
6191 const double previous_load_factor = is_first_step ? 0. :
oldLoadFactor;
6195 <<
"Setting new load factor to: " <<
loadFactor;
6198 CHKERR MPI_Bcast(load_control_data, 2, MPI_DOUBLE, 0, MPI_COMM_WORLD);
6206 const double remainingPhysicalTime =
6215 CHKERR TSElasticPostStep::postStepDestroy();
6216 TetPolynomialBase::switchCacheBaseOff<HDIV>(
6225 double start_time) {
6228 auto storage = solve_elastic_setup::setup(
this, ts, x,
false);
6230 auto topological_tao_ctx = createTopologicalTAOCtx(
6235 double final_time = 1;
6236 double delta_time = 0.1;
6238 PetscBool ts_h1_update = PETSC_FALSE;
6240 PetscOptionsBegin(PETSC_COMM_WORLD,
"",
"Dynamic Relaxation Options",
"none");
6242 CHKERR PetscOptionsScalar(
"-dynamic_final_time",
6243 "dynamic relaxation final time",
"", final_time,
6244 &final_time, PETSC_NULLPTR);
6245 CHKERR PetscOptionsScalar(
"-dynamic_delta_time",
6246 "dynamic relaxation final time",
"", delta_time,
6247 &delta_time, PETSC_NULLPTR);
6248 CHKERR PetscOptionsInt(
"-dynamic_max_it",
"dynamic relaxation iterations",
"",
6249 max_it, &max_it, PETSC_NULLPTR);
6250 CHKERR PetscOptionsBool(
"-dynamic_h1_update",
"update each ts step",
"",
6251 ts_h1_update, &ts_h1_update, PETSC_NULLPTR);
6257 <<
"Dynamic relaxation final time -dynamic_final_time = " << final_time;
6259 <<
"Dynamic relaxation delta time -dynamic_delta_time = " << delta_time;
6261 <<
"Dynamic relaxation max iterations -dynamic_max_it = " << max_it;
6263 <<
"Dynamic relaxation H1 update each step -dynamic_h1_update = "
6264 << (ts_h1_update ?
"TRUE" :
"FALSE");
6268 auto setup_ts_monitor = [&]() {
6269 auto monitor_ptr = boost::make_shared<EshelbianMonitor>(*
this);
6272 auto monitor_ptr = setup_ts_monitor();
6274 TetPolynomialBase::switchCacheBaseOn<HDIV>(
6277 CHKERR TSElasticPostStep::postStepInitialise(
this);
6279 double ts_delta_time;
6280 CHKERR TSGetTimeStep(ts, &ts_delta_time);
6283 CHKERR TSSetPreStep(ts, TSElasticPostStep::preStepFun);
6284 CHKERR TSSetPostStep(ts, TSElasticPostStep::postStepFun);
6287 CHKERR TSElasticPostStep::preStepFun(ts);
6288 CHKERR TSElasticPostStep::postStepFun(ts);
6291 CHKERR TaoSetType(tao, TAOLMVM);
6294 topologicalEvaluateObjectiveAndGradient,
6295 (
void *)topological_tao_ctx.get());
6299 monitor_ptr->ts = PETSC_NULLPTR;
6300 monitor_ptr->ts_u = PETSC_NULLPTR;
6308 CHKERR VecGhostUpdateBegin(tao_sol0, INSERT_VALUES, SCATTER_FORWARD);
6309 CHKERR VecGhostUpdateEnd(tao_sol0, INSERT_VALUES, SCATTER_FORWARD);
6311 int tao_sol_size, tao_sol_loc_size;
6312 CHKERR VecGetSize(tao_sol0, &tao_sol_size);
6313 CHKERR VecGetLocalSize(tao_sol0, &tao_sol_loc_size);
6315 <<
"Toplogical data vector size " << tao_sol_size <<
" local size "
6316 << tao_sol_loc_size <<
" number of interface faces "
6319 CHKERR TaoSetFromOptions(tao);
6321 if (delta_time <= 0.) {
6323 "delta_time must be positive, got %g", delta_time);
6328 <<
" delta time " << delta_time;
6330 CHKERR VecZeroEntries(tao_sol0);
6331 CHKERR VecGhostUpdateBegin(tao_sol0, INSERT_VALUES, SCATTER_FORWARD);
6332 CHKERR VecGhostUpdateEnd(tao_sol0, INSERT_VALUES, SCATTER_FORWARD);
6333 CHKERR TaoSetSolution(tao, tao_sol0);
6336 CHKERR TaoGetSolution(tao, &tao_sol);
6352 CHKERR VecGhostUpdateBegin(x, INSERT_VALUES, SCATTER_FORWARD);
6353 CHKERR VecGhostUpdateEnd(x, INSERT_VALUES, SCATTER_FORWARD);
6354 monitor_ptr->ts = PETSC_NULLPTR;
6355 monitor_ptr->ts_u = x;
6365 if (delta_time >= remainingPhysicalTime) {
6372 CHKERR TSElasticPostStep::postStepDestroy();
6373 TetPolynomialBase::switchCacheBaseOff<HDIV>(
6381 double start_time) {
6384 auto storage = solve_elastic_setup::setup(
this, ts, x,
false);
6386 auto topological_tao_ctx = createTopologicalTAOCtx(
6394 auto monitor_ptr = boost::make_shared<EshelbianMonitor>(*
this);
6396 TetPolynomialBase::switchCacheBaseOn<HDIV>(
6399 CHKERR TSElasticPostStep::postStepInitialise(
this);
6401 double ts_delta_time;
6402 CHKERR TSGetTimeStep(ts, &ts_delta_time);
6405 CHKERR TSSetPreStep(ts, TSElasticPostStep::preStepFun);
6406 CHKERR TSSetPostStep(ts, TSElasticPostStep::postStepFun);
6409 CHKERR TSElasticPostStep::preStepFun(ts);
6410 CHKERR TSElasticPostStep::postStepFun(ts);
6412 const bool restart_run =
6414 std::abs(start_time) > std::numeric_limits<double>::epsilon();
6417 std::abs(test_time) < std::numeric_limits<double>::epsilon()) {
6419 "Set non-zero -physical_final_time for test_topological_derivative");
6424 monitor_ptr->ts = PETSC_NULLPTR;
6425 monitor_ptr->ts_u = PETSC_NULLPTR;
6431 <<
"Solving load step before topological derivative test: "
6433 <<
" TS delta time " << ts_delta_time;
6435 CHKERR TSSetStepNumber(ts, 0);
6437 CHKERR TSSetTimeStep(ts, ts_delta_time);
6439 CHKERR TSElasticPostStep::preStepFun(ts);
6441 CHKERR TSSetSolution(ts, x);
6442 CHKERR TSSolve(ts, PETSC_NULLPTR);
6444 CHKERR TSElasticPostStep::postStepFun(ts);
6449 CHKERR VecGhostUpdateBegin(x, INSERT_VALUES, SCATTER_FORWARD);
6450 CHKERR VecGhostUpdateEnd(x, INSERT_VALUES, SCATTER_FORWARD);
6452 monitor_ptr->ts = PETSC_NULLPTR;
6453 monitor_ptr->ts_u = x;
6461 CHKERR VecGhostUpdateBegin(tao_sol0, INSERT_VALUES, SCATTER_FORWARD);
6462 CHKERR VecGhostUpdateEnd(tao_sol0, INSERT_VALUES, SCATTER_FORWARD);
6464 int tao_sol_size, tao_sol_loc_size;
6465 CHKERR VecGetSize(tao_sol0, &tao_sol_size);
6466 CHKERR VecGetLocalSize(tao_sol0, &tao_sol_loc_size);
6468 <<
"Topological data vector size " << tao_sol_size <<
" local size "
6469 << tao_sol_loc_size <<
" number of interface faces "
6472 const char *list_objective_models[ObjectiveModelType::LAST_MODEL] = {
6473 "python_model",
"hencky_model"};
6474#ifdef ENABLE_PYTHON_BINDING
6475 PetscInt choice_objective_model = ObjectiveModelType::PYTHON_MODEL;
6477 PetscInt choice_objective_model = ObjectiveModelType::HENCKY_MODEL;
6480 PETSC_NULLPTR, PETSC_NULLPTR,
"-objective_model_type",
6481 list_objective_models, ObjectiveModelType::LAST_MODEL,
6482 &choice_objective_model, PETSC_NULLPTR);
6483 const auto objective_model_type =
6484 static_cast<ObjectiveModelType
>(choice_objective_model);
6486 <<
"Objective model type: -objective_model_type "
6487 << list_objective_models[objective_model_type];
6490 PetscReal obj_value;
6491 CHKERR testTopologicalDerivative(topological_tao_ctx.get(), tao_sol0,
6492 &obj_value,
g, objective_model_type);
6494 CHKERR TSElasticPostStep::postStepDestroy();
6495 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
FormsIntegrators< VolUserDataOperator >::Assembly< A >::BiLinearForm< GAUSS >::OpMass< 9, 9 > OpStressGram_dBubble_dBubble
FormsIntegrators< VolUserDataOperator >::Assembly< A >::BiLinearForm< GAUSS >::OpMass< 3, 9 > OpStressGram_dP_dP
static auto send_type(MoFEM::Interface &m_field, Range r, const EntityType type)
static auto get_block_meshset(MoFEM::Interface &m_field, const int ms_id, const unsigned int cubit_bc_type)
static auto get_range_from_block(MoFEM::Interface &m_field, const std::string block_name, int dim)
static auto get_two_sides_of_crack_surface(MoFEM::Interface &m_field, Range crack_faces)
static auto get_range_from_block_map(MoFEM::Interface &m_field, const std::string block_name, int dim)
static auto filter_owners(MoFEM::Interface &m_field, Range skin)
static auto filter_true_skin(MoFEM::Interface &m_field, Range &&skin)
static auto get_skin(MoFEM::Interface &m_field, Range body_ents)
static auto get_entities_by_handle(MoFEM::Interface &m_field, const std::string block_name)
static auto get_crack_front_edges(MoFEM::Interface &m_field, Range crack_faces)
Eshelbian plasticity interface.
Contains definition of EshelbianTestingMonitor class.
#define MOFEM_LOG_SEVERITY_SYNC(comm, severity)
Synchronise "SYNC" on curtain severity level.
#define MOFEM_LOG_C(channel, severity, format,...)
#define FTENSOR_INDEXES(DIM,...)
#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
static const char *const ApproximationBaseNames[]
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
#define MoFEMFunctionBeginHot
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
PetscErrorCode DMMoFEMSetIsPartitioned(DM dm, PetscBool is_partitioned)
PetscErrorCode DMMoFEMCreateSubDM(DM subdm, DM dm, const char problem_name[])
Must be called by user to set Sub DM MoFEM data structures.
PetscErrorCode DMMoFEMAddElement(DM dm, std::string fe_name)
add element to dm
PetscErrorCode DMMoFEMSetSquareProblem(DM dm, PetscBool square_problem)
set squared problem
PetscErrorCode DMMoFEMTSSetIFunction(DM dm, const char fe_name[], MoFEM::FEMethod *method, MoFEM::BasicMethod *pre_only, MoFEM::BasicMethod *post_only)
set TS implicit function evaluation function
PetscErrorCode DMMoFEMCreateMoFEM(DM dm, MoFEM::Interface *m_field_ptr, const char problem_name[], const MoFEM::BitRefLevel bit_level, const MoFEM::BitRefLevel bit_mask=MoFEM::BitRefLevel().set())
Must be called by user to set MoFEM data structures.
PetscErrorCode DMoFEMPostProcessFiniteElements(DM dm, MoFEM::FEMethod *method)
execute finite element method for each element in dm (problem)
PetscErrorCode DMMoFEMAddSubFieldRow(DM dm, const char field_name[])
PetscErrorCode DMMoFEMGetTsCtx(DM dm, MoFEM::TsCtx **ts_ctx)
get MoFEM::TsCtx data structure
PetscErrorCode DMoFEMMeshToLocalVector(DM dm, Vec l, InsertMode mode, ScatterMode scatter_mode, RowColData rc=RowColData::COL)
set local (or ghosted) vector values on mesh for partition only
PetscErrorCode DMoFEMLoopFiniteElements(DM dm, const char fe_name[], MoFEM::FEMethod *method, CacheTupleWeakPtr cache_ptr=CacheTupleSharedPtr())
Executes FEMethod for finite elements in DM.
auto createDMVector(DM dm, RowColData rc=RowColData::COL)
Get smart vector from DM.
PetscErrorCode DMMoFEMTSSetIJacobian(DM dm, const std::string fe_name, boost::shared_ptr< MoFEM::FEMethod > method, boost::shared_ptr< MoFEM::BasicMethod > pre_only, boost::shared_ptr< MoFEM::BasicMethod > post_only)
set TS Jacobian evaluation function
PetscErrorCode DMMoFEMAddSubFieldCol(DM dm, const char field_name[])
PetscErrorCode DMMoFEMTSSetI2Jacobian(DM dm, const std::string fe_name, boost::shared_ptr< MoFEM::FEMethod > method, boost::shared_ptr< MoFEM::BasicMethod > pre_only, boost::shared_ptr< MoFEM::BasicMethod > post_only)
set TS Jacobian evaluation function
PetscErrorCode DMMoFEMTSSetI2Function(DM dm, const std::string fe_name, boost::shared_ptr< MoFEM::FEMethod > method, boost::shared_ptr< MoFEM::BasicMethod > pre_only, boost::shared_ptr< MoFEM::BasicMethod > post_only)
set TS implicit function evaluation function
PetscErrorCode DMoFEMLoopFiniteElementsUpAndLowRank(DM dm, const char fe_name[], MoFEM::FEMethod *method, int low_rank, int up_rank, CacheTupleWeakPtr cache_ptr=CacheTupleSharedPtr())
Executes FEMethod for finite elements in DM.
PetscErrorCode DMoFEMPreProcessFiniteElements(DM dm, MoFEM::FEMethod *method)
execute finite element method for each element in dm (problem)
virtual MoFEMErrorCode add_finite_element(const std::string &fe_name, enum MoFEMTypes bh=MF_EXCL, int verb=DEFAULT_VERBOSITY)=0
add finite element
virtual MoFEMErrorCode build_finite_elements(int verb=DEFAULT_VERBOSITY)=0
Build finite elements.
virtual MoFEMErrorCode modify_finite_element_add_field_col(const std::string &fe_name, const std::string name_row)=0
set field col which finite element use
virtual MoFEMErrorCode modify_finite_element_adjacency_table(const std::string &fe_name, const EntityType type, ElementAdjacencyFunct function)=0
modify finite element table, only for advanced user
virtual MoFEMErrorCode add_ents_to_finite_element_by_type(const EntityHandle entities, const EntityType type, const std::string name, const bool recursive=true)=0
add entities to finite element
virtual MoFEMErrorCode modify_finite_element_add_field_row(const std::string &fe_name, const std::string name_row)=0
set field row which finite element use
virtual MoFEMErrorCode modify_finite_element_add_field_data(const std::string &fe_name, const std::string name_field)=0
set finite element field data
virtual const Field * get_field_structure(const std::string &name, enum MoFEMTypes bh=MF_EXIST) const =0
get field structure
virtual MoFEMErrorCode build_fields(int verb=DEFAULT_VERBOSITY)=0
virtual MoFEMErrorCode add_ents_to_field_by_dim(const Range &ents, const int dim, const std::string &name, int verb=DEFAULT_VERBOSITY)=0
Add entities to field meshset.
virtual MoFEMErrorCode set_field_order(const EntityHandle meshset, const EntityType type, const std::string &name, const ApproximationOrder order, int verb=DEFAULT_VERBOSITY)=0
Set order approximation of the entities in the field.
virtual MoFEMErrorCode add_ents_to_field_by_type(const Range &ents, const EntityType type, const std::string &name, int verb=DEFAULT_VERBOSITY)=0
Add entities to field meshset.
#define MOFEM_LOG(channel, severity)
Log.
SeverityLevel
Severity levels.
#define MOFEM_LOG_TAG(channel, tag)
Tag channel.
#define MOFEM_LOG_CHANNEL(channel)
Set and reset channel.
virtual MoFEMErrorCode loop_dofs(const Problem *problem_ptr, const std::string &field_name, RowColData rc, DofMethod &method, int lower_rank, int upper_rank, int verb=DEFAULT_VERBOSITY)=0
Make a loop over dofs.
virtual MoFEMErrorCode loop_finite_elements(const std::string problem_name, const std::string &fe_name, FEMethod &method, boost::shared_ptr< NumeredEntFiniteElement_multiIndex > fe_ptr=nullptr, MoFEMTypes bh=MF_EXIST, CacheTupleWeakPtr cache_ptr=CacheTupleSharedPtr(), int verb=DEFAULT_VERBOSITY)=0
Make a loop over finite elements.
MoFEMErrorCode getMeshset(const int ms_id, const unsigned int cubit_bc_type, EntityHandle &meshset) const
get meshset from CUBIT Id and CUBIT type
MoFEMErrorCode getCubitMeshsetPtr(const int ms_id, const CubitBCType cubit_bc_type, const CubitMeshSets **cubit_meshset_ptr) const
get cubit meshset
MoFEMErrorCode removeBlockDOFsOnEntities(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, bool is_distributed_mesh=true)
Remove DOFs from problem based on block entities.
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', DIM1 > J
FTensor::Index< 'l', 3 > l
FTensor::Index< 'j', 3 > j
static auto filter_true_skin(MoFEM::Interface &m_field, Range &&skin)
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)
boost::shared_ptr< ContactSDFPython > setupContactSdf(MoFEM::Interface &m_field)
Read SDF file and setup contact SDF.
MoFEMErrorCode pushCohesiveOpsRhs(EshelbianCore &ep, ForcesAndSourcesCore::GaussHookFun set_integration_at_front_face, boost::shared_ptr< Range > interface_range_ptr, boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pip)
void pushOpCalculateStretchFromStress(OpVector &op_vector, boost::shared_ptr< PhysicalEquations > physics_ptr, boost::shared_ptr< DataAtIntegrationPts > data_ptr, boost::shared_ptr< ExternalStrainVec > external_strain_vec_ptr, const std::map< std::string, boost::shared_ptr< ScalingMethod > > &smv, boost::shared_ptr< MatrixDouble > strain_ptr=nullptr)
Push pointwise external-pressure evaluation before stress recovery.
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.
const Rule * getTriangleRule(const int order)
const Rule * getTetrahedronRule(const int order)
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.
PetscErrorCode PetscOptionsGetInt(PetscOptions *, const char pre[], const char name[], PetscInt *ivalue, PetscBool *set)
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 PetscOptionsGetEList(PetscOptions *, const char pre[], const char name[], const char *const *list, PetscInt next, PetscInt *value, PetscBool *set)
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
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
static PetscBool physicalH1Update
static enum StretchSelector stretchSelector
boost::shared_ptr< Range > frontAdjEdges
static int interfaceRemoveLevel
MoFEMErrorCode addBoundaryFiniteElement(const EntityHandle meshset=0)
const std::string skeletonElement
static double inv_dd_f_linear(const double)
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 inv_d_f_linear(const double)
static double dd_f_linear(const double)
BitRefLevel bitAdjEnt
bit ref level for parent
static boost::function< double(const double)> inv_dd_f
MoFEM::Interface & mField
const std::string spatialL2Disp
std::map< std::string, boost::shared_ptr< ScalingMethod > > timeScaleMap
static enum SolverType solverType
MoFEMErrorCode postProcessSkeletonResults(const int tag, const std::string file, Vec f_residual=PETSC_NULLPTR, std::vector< Tag > tags_to_transfer={}, TS ts=PETSC_NULLPTR)
static PetscBool l2UserBaseScale
SmartPetscObj< DM > dM
Coupled problem all fields.
MoFEMErrorCode solveSchapeOptimisation(TS ts, Vec x, int start_step, double start_time)
Solve shape optimisation problem.
static enum StretchHandling stretchHandling
boost::shared_ptr< TractionFreeBc > bcSpatialFreeTractionVecPtr
static const char * listSolvers[]
const std::string materialH1Positions
static int nbJIntegralContours
MoFEMErrorCode setBlockTagsOnSkin()
static PetscBool crackingOn
MoFEMErrorCode getTractionFreeBc(const EntityHandle meshset, boost::shared_ptr< TractionFreeBc > &bc_ptr, const std::string contact_set_name)
Remove all, but entities where kinematic constrains are applied.
static double griffithEnergy
Griffith energy.
boost::shared_ptr< VolumeElementForcesAndSourcesCore > elasticFeRhs
MoFEMErrorCode postProcessRestartMesh(const int tag, const std::string file, std::vector< Tag > tags_to_transfer={})
const std::string elementVolumeName
static double dd_f_log_e(const double v)
static double d_f_linear(const double)
static enum RotSelector rotSelector
MoFEMErrorCode addDebugModel(TS ts)
Add debug to model.
static enum RotSelector gradApproximator
PetscBool loadFactorTSSolveExecuted
MoFEMErrorCode postProcessResults(const int tag, const std::string file, Vec f_residual=PETSC_NULLPTR, Vec var_vec=PETSC_NULLPTR, Vec gradient=PETSC_NULLPTR, std::vector< Tag > tags_to_transfer={}, TS ts=PETSC_NULLPTR)
MoFEMErrorCode getBc(boost::shared_ptr< BC > &bc_vec_ptr, const std::string block_name, const int nb_attributes)
static double inv_dd_f_log_e_quadratic(const double stretch)
CommInterface::EntitiesPetscVector vertexExchange
static std::vector< std::string > listTagsToProject
boost::shared_ptr< BcRotVec > bcSpatialRotationVecPtr
static std::string heterogeneousYoungModTagName
const std::string spatialH1Disp
static FieldApproximationBase brokenHdivBase
static double maxCrackExtension
static int physicalMaxSteps
MoFEMErrorCode solveElastic(TS ts, Vec x)
@ TestTopologicalDerivative
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)
std::string getStringArgumentFromJsonBlockset(const std::string &type_name, const int meshset_id, const std::string ¶m_name)
int contactRefinementLevels
static int physicalStepNumber
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)
static PetscBool physicalTimeFlg
MoFEMErrorCode query_interface(boost::typeindex::type_index type_index, UnknownInterface **iface) const
Getting interface of core database.
const std::string bubbleField
boost::shared_ptr< AnalyticalDisplacementBcVec > bcSpatialAnalyticalDisplacementVecPtr
SmartPetscObj< DM > dmMaterial
Material problem.
boost::shared_ptr< VolumeElementForcesAndSourcesCore > elasticFeLhs
boost::shared_ptr< ParentFiniteElementAdjacencyFunctionSkeleton< 2 > > parentAdjSkeletonFunctionDim2
static double crackingAddTime
double alphaViscousOmega0
MoFEMErrorCode setFaceElementOps(const bool add_elastic, const bool add_material, boost::shared_ptr< FaceElementForcesAndSourcesCore > &fe_rhs, boost::shared_ptr< FaceElementForcesAndSourcesCore > &fe_lhs)
MoFEMErrorCode projectGeometry(const EntityHandle meshset=0, double time=0)
static double currentPhysicalTime
boost::shared_ptr< AnalyticalExprPython > AnalyticalExprPythonPtr
boost::shared_ptr< SpringBcVec > bcSpatialSpringVecPtr
static double crackingAtol
Cracking absolute tolerance.
MoFEMErrorCode projectMaterialTags(const EntityHandle meshset=0)
boost::shared_ptr< Range > skeletonFaces
static double crackingRtol
Cracking relative tolerance.
boost::shared_ptr< PhysicalEquations > physicalEquations
const std::string rotAxis
static PetscBool meshTransferHybridInterp
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.
const std::string contactDisp
static std::string internalStressTagName
CommInterface::EntitiesPetscVector edgeExchange
SmartPetscObj< DM > dmPrjSpatial
Projection spatial displacement.
static boost::function< double(const double)> f
MoFEMErrorCode solveTestTopologicalDerivative(TS ts, Vec x, int start_step, double start_time)
boost::shared_ptr< BcDispVec > bcSpatialDispVecPtr
static double finalPhysicalTime
const std::string skinElement
static PetscBool internalStressVoigt
MoFEMErrorCode addVolumeFiniteElement(const EntityHandle meshset=0, const bool add_bubble=true)
static double inv_dd_f_log_e(const double v)
MoFEMErrorCode getExternalStrain()
MoFEMErrorCode getSpatialTractionBc()
MoFEMErrorCode pushNoStretchVolumeA00Ops(boost::shared_ptr< VolumeElementForcesAndSourcesCore > fe_lhs)
static PetscBool setSingularity
MoFEMErrorCode setBaseVolumeElementOps(const int tag, const bool do_rhs, const bool do_lhs, const bool calc_rates, boost::shared_ptr< VolumeElementForcesAndSourcesCore > fe, const bool add_bubble=true)
static double d_f_log_e(const double v)
boost::shared_ptr< AnalyticalTractionBcVec > bcSpatialAnalyticalTractionVecPtr
boost::shared_ptr< double > currentCrackAreaPtr
static PetscBool meshTransferSourceMeshFileSpecified
static double f_log_e_quadratic(const double v)
double avgGriffithsEnergy
static double inv_f_log_e_quadratic(const double stretch)
static bool hasNonHomogeneousMaterialBlock
MoFEMErrorCode addDMs(const BitRefLevel bit=BitRefLevel().set(0), const EntityHandle meshset=0)
MoFEMErrorCode solveCohesiveCrackGrowth(TS ts, Vec x, int start_step, double start_time)
Solve cohesive crack growth problem.
MoFEMErrorCode getSpatialDispBc()
[Getting norms]
BitRefLevel bitAdjParent
bit ref level for parent
MoFEMErrorCode setContactElementRhsOps(boost::shared_ptr< ForcesAndSourcesCore > &fe_contact_tree)
static PetscBool interfaceCrack
MoFEMErrorCode solveLoadFactor(TS ts, Vec x, int start_step, double start_time)
Solve load factor crack growth problem.
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)
MoFEMErrorCode pushStretchVolumeA00Ops(boost::shared_ptr< VolumeElementForcesAndSourcesCore > fe_lhs)
boost::shared_ptr< DataAtIntegrationPts > dataAtPts
boost::shared_ptr< Range > crackFaces
static boost::function< double(const double)> d_f
static bool isNoStretch()
boost::shared_ptr< Range > frontVertices
static enum EnergyReleaseSelector energyReleaseSelector
static boost::function< double(const double)> inv_d_f
boost::shared_ptr< PressureBcVec > bcSpatialPressureVecPtr
static int meshTransferInterpOrder
const std::string hybridSpatialDisp
SmartPetscObj< Vec > solTSStep
static double inv_d_f_log_e_quadratic(const double stretch)
CommInterface::EntitiesPetscVector faceExchange
SmartPetscObj< DM > dmElastic
Elastic problem.
static std::string meshTransferSourceMeshFileName
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)
MoFEMErrorCode addFields(const EntityHandle meshset=0, const bool add_bubble=true)
MoFEMErrorCode withFieldOrders(Op &&op) const
MoFEMErrorCode pushStressGramOps(boost::shared_ptr< VolumeElementForcesAndSourcesCore > fe_lhs)
const std::string contactElement
MoFEMErrorCode pushPiolaStressGramOps(boost::shared_ptr< VolumeElementForcesAndSourcesCore > fe_lhs)
AnalyticalDisplacementBc(std::string name, std::vector< double > attr, Range faces, std::string load_history_file="")
AnalyticalTractionBc(std::string name, std::vector< double > attr, Range faces, std::string load_history_file="")
BcRot(std::string name, std::vector< double > attr, Range faces, std::string load_history_file="")
ExternalStrain(std::string name, std::vector< double > attr, Range ents, std::string load_history_file="")
int operator()(int p_row, int p_col, int p_data) const
NormalDisplacementBc(std::string name, std::vector< double > attr, Range faces, std::string load_history_file="")
PressureBc(std::string name, std::vector< double > attr, Range faces, std::string load_history_file="")
boost::shared_ptr< Range > frontNodes
SetIntegrationAtFrontFace(boost::shared_ptr< Range > front_nodes, boost::shared_ptr< Range > front_edges, int(*)(int))
SetIntegrationAtFrontFace(boost::shared_ptr< Range > front_nodes, boost::shared_ptr< Range > front_edges)
boost::shared_ptr< Range > frontEdges
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
SpringBc(std::string name, std::vector< double > attr, Range faces)
double tangentialStiffness
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, std::string load_history_file="")
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.
Template specialization for displacement boundary conditions.
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.
Template specialization system for type-safe boundary condition handling.
static MoFEMErrorCode updateEntitiesPetscVector(moab::Interface &moab, EntitiesPetscVector &vec, Tag tag, UpdateGhosts update_gosts=defaultUpdateGhosts)
Exchange data between vector and data.
static Range getPartEntities(moab::Interface &moab, int part)
static MoFEMErrorCode setVectorFromTag(moab::Interface &moab, EntitiesPetscVector &vec, Tag tag)
Set the Vector From Tag object.
static MoFEMErrorCode setTagFromVector(moab::Interface &moab, EntitiesPetscVector &vec, Tag tag)
Set the Tag From Vector object.
static EntitiesPetscVector createEntitiesPetscVector(MPI_Comm comm, moab::Interface &moab, std::function< Range(Range)> get_entities_fun, const int nb_coeffs, Sev sev=Sev::verbose, int root_rank=0, bool get_vertices=true)
Create a ghost vector for exchanging data.
virtual moab::Interface & get_moab()=0
virtual MoFEMErrorCode add_broken_field(const std::string name, const FieldSpace space, const FieldApproximationBase base, const FieldCoefficientsNumber nb_of_coefficients, const std::vector< std::pair< EntityType, std::function< MoFEMErrorCode(BaseFunction::DofsSideMap &)> > > list_dof_side_map, const TagType tag_type=MB_TAG_SPARSE, const enum MoFEMTypes bh=MF_EXCL, int verb=DEFAULT_VERBOSITY)=0
Add field.
virtual bool check_finite_element(const std::string &name) const =0
Check if finite element is in database.
virtual MoFEMErrorCode build_adjacencies(const Range &ents, int verb=DEFAULT_VERBOSITY)=0
build adjacencies
virtual MoFEMErrorCode add_field(const std::string name, const FieldSpace space, const FieldApproximationBase base, const FieldCoefficientsNumber nb_of_coefficients, const TagType tag_type=MB_TAG_SPARSE, const enum MoFEMTypes bh=MF_EXCL, int verb=DEFAULT_VERBOSITY)=0
Add field.
virtual MPI_Comm & get_comm() const =0
virtual int get_comm_rank() const =0
Deprecated interface functions.
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.
CubitMeshSet_multiIndex & getMeshsetsMultindex()
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 MatrixDouble vector field values calculation.
Element used to execute operators on side of the element.
Execute "this" element in the operator.
Post post-proc data at points from hash maps.
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
Operator for linear form, usually to calculate values on right hand side.
std::map< std::string, boost::shared_ptr< MatrixDouble > > DataMapMat
@ CTX_SET_TIME
Time value is set.
static constexpr Switches CtxSetTime
Time value switch.
static MoFEMErrorCode writeTSGraphGraphviz(TsCtx *ts_ctx, std::string file_name)
TS graph to Graphviz file.
Template struct for dimension-specific finite element types.
Problem manager is used to build and partition problems.
Projection of edge entities with one mid-node on hierarchical basis.
intrusive_ptr for managing petsc objects
std::function< double(double)> ScalingFun
FEMethodsSequence & getLoopsMonitor()
Get the loops to do Monitor object.
base class for all interface classes
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.
Vector manager is used to create vectors \mofem_vectors.
default operator for TET element
MoFEMErrorCode doWork(int side, EntityType type, EntData &data)
Apply rotation boundary condition.
BoundaryEle::UserDataOperator BdyEleOp
ElementsAndOps< SPACE_DIM >::SideEle SideEle