15#ifdef INCLUDE_MBCOUPLER
16 #include <mbcoupler/Coupler.hpp>
23#include <boost/math/constants/constants.hpp>
26#ifdef ENABLE_PYTHON_BINDING
27 #include <boost/python.hpp>
28 #include <boost/python/def.hpp>
29 #include <boost/python/numpy.hpp>
30namespace bp = boost::python;
31namespace np = boost::python::numpy;
59 const EntityType
type) {
63 auto dim = CN::Dimension(
type);
65 std::vector<int> sendcounts(pcomm->size());
66 std::vector<int> displs(pcomm->size());
67 std::vector<int> sendbuf(r.size());
68 if (pcomm->rank() == 0) {
69 for (
auto p = 1; p != pcomm->size(); p++) {
71 ->getPartEntities(m_field.
get_moab(), p)
74 CHKERR m_field.
get_moab().get_adjacencies(part_ents, dim,
true, faces,
75 moab::Interface::UNION);
76 faces = intersect(faces, r);
77 sendcounts[p] = faces.size();
78 displs[p] = sendbuf.size();
79 for (
auto f : faces) {
81 sendbuf.push_back(
id);
87 MPI_Scatter(sendcounts.data(), 1, MPI_INT, &recv_data, 1, MPI_INT, 0,
89 std::vector<int> recvbuf(recv_data);
90 MPI_Scatterv(sendbuf.data(), sendcounts.data(), displs.data(), MPI_INT,
91 recvbuf.data(), recv_data, MPI_INT, 0, pcomm->comm());
93 if (pcomm->rank() > 0) {
95 for (
auto &f : recvbuf) {
105 const std::string block_name) {
111 std::regex((boost::format(
"%s(.*)") % block_name).str())
115 for (
auto bc : bcs) {
116 auto meshset = bc->getMeshset();
125 const std::string block_name,
int dim) {
131 std::regex((boost::format(
"%s(.*)") % block_name).str())
135 for (
auto bc : bcs) {
147 const std::string block_name,
int dim) {
148 std::map<std::string, Range> r;
153 std::regex((boost::format(
"%s(.*)") % block_name).str())
157 for (
auto bc : bcs) {
162 r[bc->getName()] = faces;
169 const unsigned int cubit_bc_type) {
172 CHKERR mesh_mng->getMeshset(ms_id, cubit_bc_type, meshset);
176static auto save_range(moab::Interface &moab,
const std::string name,
177 const Range r, std::vector<Tag> tags = {}) {
180 CHKERR moab.add_entities(*out_meshset, r);
182 CHKERR moab.write_file(name.c_str(),
"VTK",
"", out_meshset->get_ptr(), 1,
183 tags.data(), tags.size());
185 MOFEM_LOG(
"SELF", Sev::warning) <<
"Empty range for " << name;
192 ParallelComm *pcomm =
195 PSTATUS_SHARED | PSTATUS_MULTISHARED,
196 PSTATUS_NOT, -1, &boundary_ents),
198 return boundary_ents;
203 ParallelComm *pcomm =
205 CHK_MOAB_THROW(pcomm->filter_pstatus(skin, PSTATUS_NOT_OWNED, PSTATUS_NOT, -1,
214 CHK_MOAB_THROW(skin.find_skin(0, body_ents,
false, skin_ents),
"find_skin");
220 ParallelComm *pcomm =
223 Range crack_skin_without_bdy;
224 if (pcomm->rank() == 0) {
226 CHKERR moab.get_adjacencies(crack_faces, 1,
true, crack_edges,
227 moab::Interface::UNION);
228 auto crack_skin =
get_skin(m_field, crack_faces);
232 "get_entities_by_dimension");
233 auto body_skin =
get_skin(m_field, body_ents);
234 Range body_skin_edges;
235 CHK_MOAB_THROW(moab.get_adjacencies(body_skin, 1,
true, body_skin_edges,
236 moab::Interface::UNION),
238 crack_skin_without_bdy = subtract(crack_skin, body_skin_edges);
240 for (
auto &
m : front_edges_map) {
241 auto add_front = subtract(
m.second, crack_edges);
242 auto i = intersect(
m.second, crack_edges);
244 crack_skin_without_bdy.merge(add_front);
248 CHKERR moab.get_adjacencies(i_skin, 1,
true, adj_i_skin,
249 moab::Interface::UNION);
250 adj_i_skin = subtract(intersect(adj_i_skin,
m.second), crack_edges);
251 crack_skin_without_bdy.merge(adj_i_skin);
255 return send_type(m_field, crack_skin_without_bdy, MBEDGE);
261 ParallelComm *pcomm =
264 MOFEM_LOG(
"EP", Sev::noisy) <<
"get_two_sides_of_crack_surface";
266 if (!pcomm->rank()) {
268 auto impl = [&](
auto &saids) {
273 auto get_adj = [&](
auto e,
auto dim) {
276 e, dim,
true, adj, moab::Interface::UNION),
281 auto get_conn = [&](
auto e) {
288 constexpr bool debug =
false;
292 auto body_skin =
get_skin(m_field, body_ents);
293 auto body_skin_edges = get_adj(body_skin, 1);
296 subtract(
get_skin(m_field, crack_faces), body_skin_edges);
297 auto crack_skin_conn = get_conn(crack_skin);
298 auto crack_skin_conn_edges = get_adj(crack_skin_conn, 1);
299 auto crack_edges = get_adj(crack_faces, 1);
300 crack_edges = subtract(crack_edges, crack_skin);
301 auto all_tets = get_adj(crack_edges, 3);
302 crack_edges = subtract(crack_edges, crack_skin_conn_edges);
303 auto crack_conn = get_conn(crack_edges);
304 all_tets.merge(get_adj(crack_conn, 3));
313 if (crack_faces.size()) {
314 auto grow = [&](
auto r) {
315 auto crack_faces_conn = get_conn(crack_faces);
318 while (size_r != r.size() && r.size() > 0) {
320 CHKERR moab.get_connectivity(r,
v,
true);
321 v = subtract(
v, crack_faces_conn);
324 moab::Interface::UNION);
325 r = intersect(r, all_tets);
334 Range all_tets_ord = all_tets;
335 while (all_tets.size()) {
336 Range faces = get_adj(unite(saids.first, saids.second), 2);
337 faces = subtract(crack_faces, faces);
340 auto fit = faces.begin();
341 for (; fit != faces.end(); ++fit) {
342 tets = intersect(get_adj(
Range(*fit, *fit), 3), all_tets);
343 if (tets.size() == 2) {
350 saids.first.insert(tets[0]);
351 saids.first = grow(saids.first);
352 all_tets = subtract(all_tets, saids.first);
353 if (tets.size() == 2) {
354 saids.second.insert(tets[1]);
355 saids.second = grow(saids.second);
356 all_tets = subtract(all_tets, saids.second);
364 saids.first = subtract(all_tets_ord, saids.second);
365 saids.second = subtract(all_tets_ord, saids.first);
371 std::pair<Range, Range> saids;
372 if (crack_faces.size())
377 MOFEM_LOG(
"EP", Sev::noisy) <<
"get_two_sides_of_crack_surface <- done";
379 return std::pair<Range, Range>();
393 boost::shared_ptr<Range> front_nodes,
394 boost::shared_ptr<Range> front_edges,
395 boost::shared_ptr<CGGUserPolynomialBase::CachePhi> cache_phi =
nullptr)
399 boost::shared_ptr<Range> front_nodes,
400 boost::shared_ptr<Range> front_edges,
FunRule fun_rule,
401 boost::shared_ptr<CGGUserPolynomialBase::CachePhi> cache_phi =
nullptr)
406 int order_col,
int order_data) {
409 constexpr bool debug =
false;
411 constexpr int numNodes = 4;
412 constexpr int numEdges = 6;
413 constexpr int refinementLevels = 6;
415 auto &m_field = fe_raw_ptr->
mField;
416 auto fe_ptr =
static_cast<Fe *
>(fe_raw_ptr);
419 auto set_base_quadrature = [&]() {
421 int rule =
funRule(order_data);
432 auto &gauss_pts = fe_ptr->gaussPts;
433 gauss_pts.resize(4, nb_gauss_pts,
false);
434 cblas_dcopy(nb_gauss_pts, &
QUAD_3D_TABLE[rule]->points[1], 4,
435 &gauss_pts(0, 0), 1);
436 cblas_dcopy(nb_gauss_pts, &
QUAD_3D_TABLE[rule]->points[2], 4,
437 &gauss_pts(1, 0), 1);
438 cblas_dcopy(nb_gauss_pts, &
QUAD_3D_TABLE[rule]->points[3], 4,
439 &gauss_pts(2, 0), 1);
441 &gauss_pts(3, 0), 1);
442 auto &data = fe_ptr->dataOnElement[
H1];
443 data->dataOnEntities[MBVERTEX][0].getN(
NOBASE).resize(nb_gauss_pts, 4,
446 &*data->dataOnEntities[MBVERTEX][0].getN(
NOBASE).data().begin();
447 cblas_dcopy(4 * nb_gauss_pts,
QUAD_3D_TABLE[rule]->points, 1, shape_ptr,
456 CHKERR set_base_quadrature();
460 auto get_singular_nodes = [&]() {
463 CHKERR m_field.get_moab().get_connectivity(fe_handle, conn, num_nodes,
465 std::bitset<numNodes> singular_nodes;
466 for (
auto nn = 0; nn != numNodes; ++nn) {
468 singular_nodes.set(nn);
470 singular_nodes.reset(nn);
473 return singular_nodes;
476 auto get_singular_edges = [&]() {
477 std::bitset<numEdges> singular_edges;
478 for (
int ee = 0; ee != numEdges; ee++) {
480 CHKERR m_field.get_moab().side_element(fe_handle, 1, ee, edge);
482 singular_edges.set(ee);
484 singular_edges.reset(ee);
487 return singular_edges;
490 auto set_gauss_pts = [&](
auto &ref_gauss_pts) {
492 fe_ptr->gaussPts.swap(ref_gauss_pts);
493 const size_t nb_gauss_pts = fe_ptr->gaussPts.size2();
494 auto &data = fe_ptr->dataOnElement[
H1];
495 data->dataOnEntities[MBVERTEX][0].getN(
NOBASE).resize(nb_gauss_pts, 4);
497 &*data->dataOnEntities[MBVERTEX][0].getN(
NOBASE).data().begin();
499 &fe_ptr->gaussPts(1, 0), &fe_ptr->gaussPts(2, 0),
504 auto singular_nodes = get_singular_nodes();
505 if (singular_nodes.count()) {
506 auto it_map_ref_coords =
mapRefCoords.find(singular_nodes.to_ulong());
508 CHKERR set_gauss_pts(it_map_ref_coords->second);
512 auto refine_quadrature = [&]() {
515 const int max_level = refinementLevels;
519 double base_coords[] = {0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1};
521 for (
int nn = 0; nn != 4; nn++)
522 CHKERR moab_ref.create_vertex(&base_coords[3 * nn], nodes[nn]);
523 CHKERR moab_ref.create_element(MBTET, nodes, 4, tet);
527 Range tets(tet, tet);
530 tets, 1,
true, edges, moab::Interface::UNION);
535 Range nodes_at_front;
536 for (
int nn = 0; nn != numNodes; nn++) {
537 if (singular_nodes[nn]) {
539 CHKERR moab_ref.side_element(tet, 0, nn, ent);
540 nodes_at_front.insert(ent);
544 auto singular_edges = get_singular_edges();
547 CHKERR moab_ref.create_meshset(MESHSET_SET, meshset);
548 for (
int ee = 0; ee != numEdges; ee++) {
549 if (singular_edges[ee]) {
551 CHKERR moab_ref.side_element(tet, 1, ee, ent);
552 CHKERR moab_ref.add_entities(meshset, &ent, 1);
558 for (
int ll = 0; ll != max_level; ll++) {
561 ->getEntitiesByTypeAndRefLevel(
BitRefLevel().set(ll),
565 CHKERR moab_ref.get_adjacencies(
566 nodes_at_front, 1,
true, ref_edges, moab::Interface::UNION);
567 ref_edges = intersect(ref_edges, edges);
569 CHKERR moab_ref.get_entities_by_type(meshset, MBEDGE, ents,
true);
570 ref_edges = intersect(ref_edges, ents);
573 ->getEntitiesByTypeAndRefLevel(
575 CHKERR m_ref->addVerticesInTheMiddleOfEdges(
579 ->updateMeshsetByEntitiesChildren(meshset,
581 meshset, MBEDGE,
true);
587 ->getEntitiesByTypeAndRefLevel(
BitRefLevel().set(max_level),
597 for (Range::iterator tit = tets.begin(); tit != tets.end();
601 CHKERR moab_ref.get_connectivity(*tit, conn, num_nodes,
false);
602 CHKERR moab_ref.get_coords(conn, num_nodes, &ref_coords(tt, 0));
605 auto &data = fe_ptr->dataOnElement[
H1];
606 const size_t nb_gauss_pts = fe_ptr->gaussPts.size2();
607 MatrixDouble ref_gauss_pts(4, nb_gauss_pts * ref_coords.size1());
609 data->dataOnEntities[MBVERTEX][0].getN(
NOBASE);
611 for (
size_t tt = 0; tt != ref_coords.size1(); tt++) {
612 double *tet_coords = &ref_coords(tt, 0);
615 for (
size_t ggg = 0; ggg != nb_gauss_pts; ++ggg, ++gg) {
616 for (
int dd = 0; dd != 3; dd++) {
617 ref_gauss_pts(dd, gg) =
618 shape_n(ggg, 0) * tet_coords[3 * 0 + dd] +
619 shape_n(ggg, 1) * tet_coords[3 * 1 + dd] +
620 shape_n(ggg, 2) * tet_coords[3 * 2 + dd] +
621 shape_n(ggg, 3) * tet_coords[3 * 3 + dd];
623 ref_gauss_pts(3, gg) = fe_ptr->gaussPts(3, ggg) * det;
627 mapRefCoords[singular_nodes.to_ulong()].swap(ref_gauss_pts);
634 TetPolynomialBase::switchCacheBaseOff<HDIV>({fe_raw_ptr});
635 TetPolynomialBase::switchCacheBaseOn<HDIV>({fe_raw_ptr});
640 CHKERR refine_quadrature();
650 using ForcesAndSourcesCore::dataOnElement;
653 using ForcesAndSourcesCore::ForcesAndSourcesCore;
659 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 = [&]() {
694 int rule =
funRule(order_data);
704 fe_ptr->gaussPts.resize(3, nb_gauss_pts,
false);
705 cblas_dcopy(nb_gauss_pts, &
QUAD_2D_TABLE[rule]->points[1], 3,
706 &fe_ptr->gaussPts(0, 0), 1);
707 cblas_dcopy(nb_gauss_pts, &
QUAD_2D_TABLE[rule]->points[2], 3,
708 &fe_ptr->gaussPts(1, 0), 1);
710 &fe_ptr->gaussPts(2, 0), 1);
711 auto &data = fe_ptr->dataOnElement[
H1];
712 data->dataOnEntities[MBVERTEX][0].getN(
NOBASE).resize(nb_gauss_pts, 3,
715 &*data->dataOnEntities[MBVERTEX][0].getN(
NOBASE).data().begin();
716 cblas_dcopy(3 * nb_gauss_pts,
QUAD_2D_TABLE[rule]->points, 1, shape_ptr,
718 data->dataOnEntities[MBVERTEX][0].getDiffN(
NOBASE).resize(3, 2,
false);
721 data->dataOnEntities[MBVERTEX][0].getDiffN(
NOBASE).data().begin());
730 CHKERR set_base_quadrature();
734 auto get_singular_nodes = [&]() {
737 CHKERR m_field.get_moab().get_connectivity(fe_handle, conn, num_nodes,
739 std::bitset<numNodes> singular_nodes;
740 for (
auto nn = 0; nn != numNodes; ++nn) {
742 singular_nodes.set(nn);
744 singular_nodes.reset(nn);
747 return singular_nodes;
750 auto get_singular_edges = [&]() {
751 std::bitset<numEdges> singular_edges;
752 for (
int ee = 0; ee != numEdges; ee++) {
754 CHKERR m_field.get_moab().side_element(fe_handle, 1, ee, edge);
756 singular_edges.set(ee);
758 singular_edges.reset(ee);
761 return singular_edges;
764 auto set_gauss_pts = [&](
auto &ref_gauss_pts) {
766 fe_ptr->gaussPts.swap(ref_gauss_pts);
767 const size_t nb_gauss_pts = fe_ptr->gaussPts.size2();
768 auto &data = fe_ptr->dataOnElement[
H1];
769 data->dataOnEntities[MBVERTEX][0].getN(
NOBASE).resize(nb_gauss_pts, 4);
771 &*data->dataOnEntities[MBVERTEX][0].getN(
NOBASE).data().begin();
773 &fe_ptr->gaussPts(1, 0), nb_gauss_pts);
777 auto singular_nodes = get_singular_nodes();
778 if (singular_nodes.count()) {
779 auto it_map_ref_coords =
mapRefCoords.find(singular_nodes.to_ulong());
781 CHKERR set_gauss_pts(it_map_ref_coords->second);
785 auto refine_quadrature = [&]() {
788 const int max_level = refinementLevels;
791 double base_coords[] = {0, 0, 0, 1, 0, 0, 0, 1, 0};
793 for (
int nn = 0; nn != numNodes; nn++)
794 CHKERR moab_ref.create_vertex(&base_coords[3 * nn], nodes[nn]);
796 CHKERR moab_ref.create_element(MBTRI, nodes, numNodes, tri);
800 Range tris(tri, tri);
803 tris, 1,
true, edges, moab::Interface::UNION);
808 Range nodes_at_front;
809 for (
int nn = 0; nn != numNodes; nn++) {
810 if (singular_nodes[nn]) {
812 CHKERR moab_ref.side_element(tri, 0, nn, ent);
813 nodes_at_front.insert(ent);
817 auto singular_edges = get_singular_edges();
820 CHKERR moab_ref.create_meshset(MESHSET_SET, meshset);
821 for (
int ee = 0; ee != numEdges; ee++) {
822 if (singular_edges[ee]) {
824 CHKERR moab_ref.side_element(tri, 1, ee, ent);
825 CHKERR moab_ref.add_entities(meshset, &ent, 1);
831 for (
int ll = 0; ll != max_level; ll++) {
834 ->getEntitiesByTypeAndRefLevel(
BitRefLevel().set(ll),
838 CHKERR moab_ref.get_adjacencies(
839 nodes_at_front, 1,
true, ref_edges, moab::Interface::UNION);
840 ref_edges = intersect(ref_edges, edges);
842 CHKERR moab_ref.get_entities_by_type(meshset, MBEDGE, ents,
true);
843 ref_edges = intersect(ref_edges, ents);
846 ->getEntitiesByTypeAndRefLevel(
848 CHKERR m_ref->addVerticesInTheMiddleOfEdges(
852 ->updateMeshsetByEntitiesChildren(meshset,
854 meshset, MBEDGE,
true);
860 ->getEntitiesByTypeAndRefLevel(
BitRefLevel().set(max_level),
871 for (Range::iterator tit = tris.begin(); tit != tris.end();
875 CHKERR moab_ref.get_connectivity(*tit, conn, num_nodes,
false);
876 CHKERR moab_ref.get_coords(conn, num_nodes, &ref_coords(tt, 0));
879 auto &data = fe_ptr->dataOnElement[
H1];
880 const size_t nb_gauss_pts = fe_ptr->gaussPts.size2();
881 MatrixDouble ref_gauss_pts(3, nb_gauss_pts * ref_coords.size1());
883 data->dataOnEntities[MBVERTEX][0].getN(
NOBASE);
885 for (
size_t tt = 0; tt != ref_coords.size1(); tt++) {
886 double *tri_coords = &ref_coords(tt, 0);
889 auto det = t_normal.
l2();
890 for (
size_t ggg = 0; ggg != nb_gauss_pts; ++ggg, ++gg) {
891 for (
int dd = 0; dd != 2; dd++) {
892 ref_gauss_pts(dd, gg) =
893 shape_n(ggg, 0) * tri_coords[3 * 0 + dd] +
894 shape_n(ggg, 1) * tri_coords[3 * 1 + dd] +
895 shape_n(ggg, 2) * tri_coords[3 * 2 + dd];
897 ref_gauss_pts(2, gg) = fe_ptr->gaussPts(2, ggg) * det;
901 mapRefCoords[singular_nodes.to_ulong()].swap(ref_gauss_pts);
907 CHKERR refine_quadrature();
917 using ForcesAndSourcesCore::dataOnElement;
920 using ForcesAndSourcesCore::ForcesAndSourcesCore;
969 const char *list_rots[] = {
"small",
"moderate",
"large",
"no_h1"};
970 const char *list_release[] = {
"griffith_force",
"griffith_skeleton"};
971 const char *list_stretches[] = {
"linear",
"log",
"log_quadratic"};
972 const char *list_broken_hdiv_bases[] = {
"demkowicz",
"ainsworth"};
976 PetscInt choice_stretch = StretchSelector::LOG;
978 PetscInt choice_broken_hdiv_base = 0;
979 PetscBool l2_user_base_scale_set = PETSC_FALSE;
982 choice_broken_hdiv_base = 0;
985 choice_broken_hdiv_base = 1;
989 "Unsupported broken HDIV base %s",
992 char analytical_expr_file_name[255] =
"analytical_expr.py";
993 PetscBool no_stretch =
996 PetscOptionsBegin(PETSC_COMM_WORLD,
"",
"Eshelbian plasticity",
"none");
997 CHKERR PetscOptionsInt(
"-space_order",
"approximation oder for space",
"",
999 CHKERR PetscOptionsInt(
"-space_h1_order",
"approximation oder for space",
"",
1001 CHKERR PetscOptionsInt(
"-material_order",
"approximation oder for material",
1003 CHKERR PetscOptionsScalar(
"-viscosity_alpha_u",
"viscosity",
"",
alphaU,
1005 CHKERR PetscOptionsScalar(
"-viscosity_alpha_w",
"viscosity",
"",
alphaW,
1007 CHKERR PetscOptionsScalar(
"-viscosity_alpha_omega",
"rot viscosity",
"",
1009 CHKERR PetscOptionsScalar(
"-density_alpha_rho",
"density",
"",
alphaRho,
1013 CHKERR PetscOptionsEList(
"-rotations",
"rotations",
"", list_rots,
1014 LARGE_ROT + 1, list_rots[choice_rot], &choice_rot,
1016 CHKERR PetscOptionsEList(
"-grad",
"gradient of defamation approximate",
"",
1017 list_rots, NO_H1_CONFIGURATION + 1,
1018 list_rots[choice_grad], &choice_grad, PETSC_NULLPTR);
1022 CHKERR PetscOptionsEList(
"-stretches",
"stretches",
"", list_stretches,
1023 StretchSelector::STRETCH_SELECTOR_LAST,
1024 list_stretches[choice_stretch], &choice_stretch,
1027 CHKERR PetscOptionsBool(
"-no_stretch",
"do not solve for stretch",
"",
1028 no_stretch, &no_stretch, PETSC_NULLPTR);
1029 CHKERR PetscOptionsBool(
"-set_singularity",
"set singularity",
"",
1031 CHKERR PetscOptionsBool(
"-l2_user_base_scale",
"streach scale",
"",
1033 &l2_user_base_scale_set);
1034 CHKERR PetscOptionsEList(
1035 "-broken_hdiv_base",
"broken HDIV stress approximation base",
"",
1036 list_broken_hdiv_bases, 2,
1037 list_broken_hdiv_bases[choice_broken_hdiv_base],
1038 &choice_broken_hdiv_base, PETSC_NULLPTR);
1043 CHKERR PetscOptionsBool(
"-dynamic_relaxation",
"dynamic time relaxation",
"",
1045 CHKERR PetscOptionsEList(
1051 CHKERR PetscOptionsScalar(
"-physical_final_time",
"physical final time",
"",
1054 CHKERR PetscOptionsScalar(
"-physical_delta_time",
"physical delta time",
"",
1057 CHKERR PetscOptionsInt(
"-physical_max_steps",
"physical max iterations",
"",
1061 "-physical_h1_update",
"update each physicalsolver step",
"",
1066 CHKERR PetscOptionsInt(
"-contact_max_post_proc_ref_level",
"refinement level",
1070 CHKERR PetscOptionsBool(
"-cohesive_interface_on",
"cohesive interface ON",
"",
1073 "-cohesive_interface_remove_level",
"cohesive interface remove level",
"",
1079 CHKERR PetscOptionsScalar(
"-cracking_add_time",
"cracking add time",
"",
1081 CHKERR PetscOptionsScalar(
"-cracking_start_time",
"cracking start time",
"",
1084 CHKERR PetscOptionsScalar(
"-griffith_energy",
"Griffith energy",
"",
1087 CHKERR PetscOptionsScalar(
"-cracking_rtol",
"Cracking relative tolerance",
"",
1089 CHKERR PetscOptionsScalar(
"-cracking_atol",
"Cracking absolute tolerance",
"",
1091 CHKERR PetscOptionsEList(
"-energy_release_variant",
"energy release variant",
1092 "", list_release, 2, list_release[choice_release],
1093 &choice_release, PETSC_NULLPTR);
1094 CHKERR PetscOptionsInt(
"-nb_J_integral_levels",
"Number of J integarl levels",
1098 "-nb_J_integral_contours",
"Number of J integral contours",
"",
1102 char tag_name[255] =
"";
1103 CHKERR PetscOptionsString(
"-internal_stress_tag_name",
1104 "internal stress tag name",
"",
"", tag_name, 255,
1107 CHKERR PetscOptionsBool(
"-internal_stress_voigt",
"Voigt index notation",
"",
1112 char tag_heterogeneous_youngs_modulus_name[255] =
"";
1113 CHKERR PetscOptionsString(
1114 "-heterogeneous_youngs_modulus",
"heterogeneous Young's modulus tag name",
1115 "",
"", tag_heterogeneous_youngs_modulus_name, 255, PETSC_NULLPTR);
1119 "-analytical_expr_file",
1120 analytical_expr_file_name, 255, PETSC_NULLPTR);
1124 PetscOptionsBegin(PETSC_COMM_WORLD,
"mesh_transfer_",
"mesh data transfer",
1126 char tag_mesh_transfer_source_file_name[255] =
"";
1127 CHKERR PetscOptionsString(
"-source_file",
"source mesh file name",
"",
1128 "source.h5m", tag_mesh_transfer_source_file_name,
1131 CHKERR PetscOptionsInt(
"-interp_order",
"interpolation order",
"", 0,
1133 CHKERR PetscOptionsBool(
"-hybrid_interp",
"use hybrid interpolation",
"",
1140 "Unsupported mesh transfer interpolation order %d",
1157 static_cast<EnergyReleaseSelector
>(choice_release);
1158 switch (choice_broken_hdiv_base) {
1167 "Unknown broken HDIV base option");
1171 case StretchSelector::LINEAR:
1179 case StretchSelector::LOG:
1181 std::numeric_limits<float>::epsilon()) {
1197 case StretchSelector::LOG_QUADRATIC:
1203 "No logarithmic quadratic stretch for this case");
1216 <<
"-dynamic_relaxation option is deprecated, use -solver_type "
1217 "dynamic_relaxation instead.";
1221 switch (choice_solver) {
1259 MOFEM_LOG(
"EP", Sev::inform) <<
"alphaU: -viscosity_alpha_u " <<
alphaU;
1260 MOFEM_LOG(
"EP", Sev::inform) <<
"alphaW: -viscosity_alpha_w " <<
alphaW;
1262 <<
"alphaOmega: -viscosity_alpha_omega " <<
alphaOmega;
1267 MOFEM_LOG(
"EP", Sev::inform) <<
"Gradient of deformation "
1273 MOFEM_LOG(
"EP", Sev::inform) <<
"Base exponent e";
1275 <<
"Stretch: -stretches " << list_stretches[choice_stretch];
1277 <<
"No stretch: -no_stretch "
1284 MOFEM_LOG(
"EP", Sev::inform) <<
"Solver type: -solver_type "
1295 <<
"Broken HDIV base: -broken_hdiv_base "
1296 << list_broken_hdiv_bases[choice_broken_hdiv_base];
1308 <<
"Cracking relative tolerance: -cracking_rtol " <<
crackingRtol;
1310 <<
"Cracking absolute tolerance: -cracking_atol " <<
crackingAtol;
1312 <<
"Energy release variant: -energy_release_variant "
1315 <<
"Number of J integral contours: -nb_J_integral_contours "
1318 <<
"Cohesive interface on: -cohesive_interface_on "
1321 <<
"Cohesive interface remove level: -cohesive_interface_remove_level "
1324#ifdef ENABLE_PYTHON_BINDING
1325 auto file_exists = [](std::string myfile) {
1326 std::ifstream file(myfile.c_str());
1333 if (file_exists(analytical_expr_file_name)) {
1334 MOFEM_LOG(
"EP", Sev::inform) << analytical_expr_file_name <<
" file found";
1338 analytical_expr_file_name);
1342 << analytical_expr_file_name <<
" file NOT found";
1353 const bool add_bubble) {
1356 auto get_tets = [&]() {
1362 auto get_tets_skin = [&]() {
1363 Range tets_skin_part;
1365 CHKERR skin.find_skin(0, get_tets(),
false, tets_skin_part);
1366 ParallelComm *pcomm =
1369 CHKERR pcomm->filter_pstatus(tets_skin_part,
1370 PSTATUS_SHARED | PSTATUS_MULTISHARED,
1371 PSTATUS_NOT, -1, &tets_skin);
1375 auto subtract_boundary_conditions = [&](
auto &&tets_skin) {
1381 tets_skin = subtract(tets_skin,
v.faces);
1385 tets_skin = subtract(tets_skin,
v.faces);
1390 tets_skin = subtract(tets_skin,
v.faces);
1396 auto add_blockset = [&](
auto block_name,
auto &&tets_skin) {
1399 tets_skin.merge(crack_faces);
1403 auto subtract_blockset = [&](
auto block_name,
auto &&tets_skin) {
1404 auto contact_range =
1406 tets_skin = subtract(tets_skin, contact_range);
1410 auto get_stress_trace_faces = [&](
auto &&tets_skin) {
1413 faces, moab::Interface::UNION);
1414 Range trace_faces = subtract(faces, tets_skin);
1418 auto tets = get_tets();
1422 auto trace_faces = get_stress_trace_faces(
1424 subtract_blockset(
"CONTACT",
1425 subtract_boundary_conditions(get_tets_skin()))
1432 boost::make_shared<Range>(subtract(trace_faces, *
contactFaces));
1450 auto add_broken_hdiv_field = [
this, meshset, broken_hdiv_base](
1457 auto get_side_map_hdiv = [&]() {
1460 std::pair<EntityType,
1475 get_side_map_hdiv(), MB_TAG_DENSE,
MF_ZERO);
1481 auto add_l2_field = [
this, meshset](
const std::string
field_name,
1482 const int order,
const int dim) {
1491 auto add_h1_field = [
this, meshset](
const std::string
field_name,
1492 const int order,
const int dim) {
1504 auto add_l2_field_by_range = [
this](
const std::string
field_name,
1505 const int order,
const int dim,
1506 const int field_dim,
Range &&r) {
1516 auto add_bubble_field = [
this, meshset](
const std::string
field_name,
1517 const int order,
const int dim) {
1523 auto field_order_table =
1524 const_cast<Field *
>(field_ptr)->getFieldOrderTable();
1525 auto get_cgg_bubble_order_zero = [](
int p) {
return 0; };
1526 auto get_cgg_bubble_order_tet = [](
int p) {
1529 field_order_table[MBVERTEX] = get_cgg_bubble_order_zero;
1530 field_order_table[MBEDGE] = get_cgg_bubble_order_zero;
1531 field_order_table[MBTRI] = get_cgg_bubble_order_zero;
1532 field_order_table[MBTET] = get_cgg_bubble_order_tet;
1539 auto add_user_l2_field = [
this, meshset](
const std::string
field_name,
1540 const int order,
const int dim) {
1546 auto field_order_table =
1547 const_cast<Field *
>(field_ptr)->getFieldOrderTable();
1548 auto zero_dofs = [](
int p) {
return 0; };
1550 field_order_table[MBVERTEX] = zero_dofs;
1551 field_order_table[MBEDGE] = zero_dofs;
1552 field_order_table[MBTRI] = zero_dofs;
1553 field_order_table[MBTET] = dof_l2_tet;
1564 auto get_hybridised_disp = [&]() {
1566 auto skin = subtract_boundary_conditions(get_tets_skin());
1568 faces.merge(intersect(bc.faces, skin));
1589 get_hybridised_disp());
1614 auto project_ho_geometry = [&](
auto field) {
1620 auto get_adj_front_edges = [&](
auto &front_edges) {
1621 Range front_crack_nodes;
1622 Range crack_front_edges_with_both_nodes_not_at_front;
1627 moab.get_connectivity(front_edges, front_crack_nodes,
true),
1628 "get_connectivity failed");
1629 Range crack_front_edges;
1631 false, crack_front_edges,
1632 moab::Interface::UNION),
1633 "get_adjacencies failed");
1634 Range crack_front_edges_nodes;
1636 crack_front_edges_nodes,
true),
1637 "get_connectivity failed");
1639 crack_front_edges_nodes =
1640 subtract(crack_front_edges_nodes, front_crack_nodes);
1641 Range crack_front_edges_with_both_nodes_not_at_front;
1643 moab.get_adjacencies(crack_front_edges_nodes, 1,
false,
1644 crack_front_edges_with_both_nodes_not_at_front,
1645 moab::Interface::UNION),
1646 "get_adjacencies failed");
1648 crack_front_edges_with_both_nodes_not_at_front = intersect(
1649 crack_front_edges, crack_front_edges_with_both_nodes_not_at_front);
1653 crack_front_edges_with_both_nodes_not_at_front =
send_type(
1654 mField, crack_front_edges_with_both_nodes_not_at_front, MBEDGE);
1656 return std::make_pair(boost::make_shared<Range>(front_crack_nodes),
1657 boost::make_shared<Range>(
1658 crack_front_edges_with_both_nodes_not_at_front));
1661 if ((time -
crackingAddTime) > std::numeric_limits<double>::epsilon()) {
1669 auto [front_vertices, front_adj_edges] = get_adj_front_edges(*
frontEdges);
1674 <<
"Number of crack faces: " <<
crackFaces->size();
1676 <<
"Number of front edges: " <<
frontEdges->size();
1680 <<
"Number of front adjacent edges: " <<
frontAdjEdges->size();
1689 (boost::format(
"crack_faces_%d.vtk") % rank).str(),
1692 (boost::format(
"front_edges_%d.vtk") % rank).str(),
1703 auto set_singular_dofs = [&](
auto &front_adj_edges,
auto &front_vertices) {
1711 MOFEM_LOG(
"EP", Sev::inform) <<
"Singularity eps " << beta;
1716 [&](boost::shared_ptr<FieldEntity> field_entity_ptr) ->
MoFEMErrorCode {
1721 auto nb_dofs = field_entity_ptr->getEntFieldData().size();
1727 if (field_entity_ptr->getNbOfCoeffs() != 3)
1729 "Expected 3 coefficients per edge");
1730 if (nb_dofs % 3 != 0)
1732 "Expected multiple of 3 coefficients per edge");
1735 auto get_conn = [&]() {
1738 CHKERR moab.get_connectivity(field_entity_ptr->getEnt(), conn,
1740 return std::make_pair(conn, num_nodes);
1743 auto get_dir = [&](
auto &&conn_p) {
1744 auto [conn, num_nodes] = conn_p;
1746 CHKERR moab.get_coords(conn, num_nodes, coords);
1748 coords[4] - coords[1],
1749 coords[5] - coords[2]};
1753 auto get_singularity_dof = [&](
auto &&conn_p,
auto &&t_edge_dir) {
1754 auto [conn, num_nodes] = conn_p;
1756 if (front_vertices.find(conn[0]) != front_vertices.end()) {
1757 t_singularity_dof(
i) = t_edge_dir(
i) * (-
eps);
1758 }
else if (front_vertices.find(conn[1]) != front_vertices.end()) {
1759 t_singularity_dof(
i) = t_edge_dir(
i) *
eps;
1761 return t_singularity_dof;
1764 auto t_singularity_dof =
1765 get_singularity_dof(get_conn(), get_dir(get_conn()));
1767 auto field_data = field_entity_ptr->getEntFieldData();
1769 &field_data[0], &field_data[1], &field_data[2]};
1771 t_dof(
i) = t_singularity_dof(
i);
1773 for (
auto n = 1;
n < field_data.size() / 3; ++
n) {
1795 auto get_interface_from_block = [&](
auto block_name) {
1800 faces, moab::Interface::UNION);
1801 faces = subtract(faces, skin);
1803 <<
"Number of vol interface elements: " << vol_eles.size()
1804 <<
" and faces: " << faces.size();
1808 interfaceFaces->merge(get_interface_from_block(
"VOLUME_INTERFACE"));
1810 auto remove_interface_from_block = [&](
auto block_name,
auto level) {
1812 Range intreface_faces;
1815 for (
auto l = 0;
l < level; ++
l) {
1818 ents,
SPACE_DIM,
true, adj_tets, moab::Interface::UNION);
1819 Range adj_tets_faces;
1822 moab::Interface::UNION);
1823 ents.merge(adj_tets_faces);
1825 auto faces = ents.subset_by_dimension(
SPACE_DIM - 1);
1828 <<
"Removed ents " << faces.size()
1833 <<
"Interface faces after remove " << intreface_faces;
1835 auto intreface_faces_global =
send_type(
mField, intreface_faces, MBTRI);
1846#ifdef INCLUDE_MBCOUPLER
1848 double toler = 5.e-10;
1853 <<
"No source mesh specified. Skipping projection";
1860 MOFEM_LOG(
"WORLD", Sev::verbose) <<
"Interpolation Young's modulus tag name: "
1864 MOFEM_LOG(
"WORLD", Sev::verbose) <<
"Using hybrid interpolation: "
1872 auto rval_check_tag = moab.tag_get_handle(tag_name.c_str(), old_interp_tag);
1873 if (rval_check_tag == MB_SUCCESS) {
1875 <<
"Deleting existing tag on target mesh: " << tag_name;
1876 CHKERR moab.tag_delete(old_interp_tag);
1880 int world_rank = -1, world_size = -1;
1881 MPI_Comm_rank(PETSC_COMM_WORLD, &world_rank);
1882 MPI_Comm_size(PETSC_COMM_WORLD, &world_size);
1884 Range original_meshset_ents;
1885 CHKERR moab.get_entities_by_handle(0, original_meshset_ents);
1887 MPI_Comm comm_coupler;
1888 if (world_rank == 0) {
1889 MPI_Comm_split(PETSC_COMM_WORLD, 0, 0, &comm_coupler);
1891 MPI_Comm_split(PETSC_COMM_WORLD, MPI_UNDEFINED, world_rank, &comm_coupler);
1895 ParallelComm *pcomm0 =
nullptr;
1897 if (world_rank == 0) {
1898 pcomm0 =
new ParallelComm(&moab, comm_coupler, &pcomm0_id);
1901 Coupler::Method method;
1904 method = Coupler::CONSTANT;
1907 method = Coupler::LINEAR_FE;
1911 "Unsupported interpolation order");
1915 ierr = MPI_Comm_size(PETSC_COMM_WORLD, &nprocs);
1917 ierr = MPI_Comm_rank(PETSC_COMM_WORLD, &rank);
1929 CHKERR moab.create_meshset(MESHSET_SET, target_root);
1931 <<
"Creating target mesh from existing meshset";
1932 Range target_meshset_ents;
1933 CHKERR moab.get_entities_by_handle(0, target_meshset_ents);
1934 CHKERR moab.add_entities(target_root, target_meshset_ents);
1937 std::vector<Tag> interp_tags;
1938 std::vector<int> tag_length;
1939 std::vector<DataType> dtype;
1940 std::vector<TagType> storage;
1943 Range targ_verts, targ_elems;
1944 if (world_rank == 0) {
1946 CHKERR moab.create_meshset(MESHSET_SET, source_root);
1948 MOFEM_LOG(
"WORLD", Sev::inform) <<
"Loading source mesh on rank 0";
1949 auto rval_source_mesh = moab.load_file(
1951 if (rval_source_mesh != MB_SUCCESS) {
1952 MOFEM_LOG(
"WORLD", Sev::warning) <<
"Error loading source mesh file: "
1955 MOFEM_LOG(
"WORLD", Sev::inform) <<
"Source mesh loaded.";
1958 CHKERR moab.get_entities_by_dimension(source_root, 3, src_elems);
1961 CHKERR pcomm0->create_part(part_set);
1962 CHKERR moab.add_entities(part_set, src_elems);
1964 Range src_elems_part;
1965 CHKERR pcomm0->get_part_entities(src_elems_part, 3);
1968 std::string tag_to_use = iterp_tag_name;
1971 CHKERR moab.tag_get_handle(tag_to_use.c_str(), interp_tag);
1974 CHKERR moab.tag_get_length(interp_tag, interp_tag_len);
1976 if (interp_tag_len != 1 && interp_tag_len != 3 && interp_tag_len != 9) {
1978 "Unsupported interpolation tag length: %d", interp_tag_len);
1982 tag_length.push_back(interp_tag_len);
1983 dtype.push_back(DataType());
1984 storage.push_back(TagType());
1985 interp_tags.push_back(interp_tag);
1986 CHKERR moab.tag_get_data_type(interp_tag, dtype.back());
1987 CHKERR moab.tag_get_type(interp_tag, storage.back());
1990 Coupler mbc(&moab, pcomm0, src_elems_part, 0,
true);
1992 std::vector<double> vpos;
1998 CHKERR moab.get_entities_by_dimension(target_root, 3, targ_elems);
2001 targ_verts = targ_elems;
2003 CHKERR moab.get_adjacencies(targ_elems, 0,
false, targ_verts,
2004 moab::Interface::UNION);
2008 CHKERR pcomm0->get_pstatus_entities(0, PSTATUS_NOT_OWNED, tmp_verts);
2009 targ_verts = subtract(targ_verts, tmp_verts);
2012 num_pts = (int)targ_verts.size();
2013 vpos.resize(3 * targ_verts.size());
2014 CHKERR moab.get_coords(targ_verts, &vpos[0]);
2017 boost::shared_ptr<TupleList> tl_ptr;
2018 tl_ptr = boost::make_shared<TupleList>();
2019 CHKERR mbc.locate_points(&vpos[0], num_pts, 0, toler, tl_ptr.get(),
2023 auto find_missing_points = [&](
Range &targ_verts,
int &num_pts,
2024 std::vector<double> &vpos,
2025 Range &missing_verts) {
2027 int missing_pts_num = 0;
2029 auto vit = targ_verts.begin();
2030 for (; vit != targ_verts.end();
i++) {
2031 if (tl_ptr->vi_rd[3 *
i + 1] == -1) {
2032 missing_verts.insert(*vit);
2033 vit = targ_verts.erase(vit);
2040 int missing_pts_num_global = 0;
2043 if (missing_pts_num_global) {
2045 << missing_pts_num_global
2046 <<
" points in target mesh were not located in source mesh. ";
2049 if (missing_pts_num) {
2050 num_pts = (int)targ_verts.size();
2051 vpos.resize(3 * targ_verts.size());
2052 CHKERR moab.get_coords(targ_verts, &vpos[0]);
2054 CHKERR mbc.locate_points(&vpos[0], num_pts, 0, toler, tl_ptr.get(),
2060 Range missing_verts;
2061 CHKERR find_missing_points(targ_verts, num_pts, vpos, missing_verts);
2063 std::vector<double> source_data(interp_tag_len * src_elems.size(), 0.0);
2064 std::vector<double> target_data(interp_tag_len * num_pts, 0.0);
2066 CHKERR moab.tag_get_data(interp_tag, src_elems, &source_data[0]);
2068 Tag scalar_tag, adj_count_tag;
2070 string scalar_tag_name = string(tag_to_use) +
"_COMP";
2071 CHKERR moab.tag_get_handle(scalar_tag_name.c_str(), 1, MB_TYPE_DOUBLE,
2072 scalar_tag, MB_TAG_CREAT | MB_TAG_DENSE,
2075 string adj_count_tag_name =
"ADJ_COUNT";
2077 CHKERR moab.tag_get_handle(adj_count_tag_name.c_str(), 1, MB_TYPE_DOUBLE,
2078 adj_count_tag, MB_TAG_CREAT | MB_TAG_DENSE,
2083 auto create_scalar_tags = [&](
const Range &src_elems,
2084 const std::vector<double> &source_data,
2088 std::vector<double> source_data_scalar(src_elems.size());
2090 for (
int ielem = 0; ielem < src_elems.size(); ielem++) {
2091 source_data_scalar[ielem] =
2092 source_data[itag + ielem * interp_tag_len];
2096 CHKERR moab.tag_set_data(scalar_tag, src_elems, &source_data_scalar[0]);
2101 CHKERR moab.get_connectivity(src_elems, src_verts,
true);
2103 CHKERR moab.tag_clear_data(scalar_tag, src_verts, &def_scl);
2104 CHKERR moab.tag_clear_data(adj_count_tag, src_verts, &def_adj);
2106 for (
auto &tet : src_elems) {
2107 double tet_data = 0;
2108 CHKERR moab.tag_get_data(scalar_tag, &tet, 1, &tet_data);
2111 CHKERR moab.get_connectivity(&tet, 1, adj_verts,
true);
2113 std::vector<double> adj_vert_data(adj_verts.size(), 0.0);
2114 std::vector<double> adj_vert_count(adj_verts.size(), 0.0);
2116 CHKERR moab.tag_get_data(scalar_tag, adj_verts, &adj_vert_data[0]);
2117 CHKERR moab.tag_get_data(adj_count_tag, adj_verts,
2118 &adj_vert_count[0]);
2120 for (
int ivert = 0; ivert < adj_verts.size(); ivert++) {
2121 adj_vert_data[ivert] += tet_data;
2122 adj_vert_count[ivert] += 1;
2125 CHKERR moab.tag_set_data(scalar_tag, adj_verts, &adj_vert_data[0]);
2126 CHKERR moab.tag_set_data(adj_count_tag, adj_verts,
2127 &adj_vert_count[0]);
2131 std::vector<Tag> tags = {scalar_tag, adj_count_tag};
2132 pcomm0->reduce_tags(tags, tags, MPI_SUM, src_verts);
2134 std::vector<double> src_vert_data(src_verts.size(), 0.0);
2135 std::vector<double> src_vert_adj_count(src_verts.size(), 0.0);
2137 CHKERR moab.tag_get_data(scalar_tag, src_verts, &src_vert_data[0]);
2138 CHKERR moab.tag_get_data(adj_count_tag, src_verts,
2139 &src_vert_adj_count[0]);
2141 for (
int ivert = 0; ivert < src_verts.size(); ivert++) {
2142 src_vert_data[ivert] /= src_vert_adj_count[ivert];
2144 CHKERR moab.tag_set_data(scalar_tag, src_verts, &src_vert_data[0]);
2150 <<
"Performing interpolation for tag: " << tag_to_use;
2152 <<
"Number of target points to interpolate: " << num_pts;
2154 <<
"Interpolation method: "
2155 << (method == Coupler::CONSTANT ?
"constant" :
"linear FE");
2157 <<
"Number of components in tag: " << interp_tag_len;
2160 <<
"Source tag data range: ["
2161 << *std::min_element(source_data.begin(), source_data.end()) <<
", "
2162 << *std::max_element(source_data.begin(), source_data.end()) <<
"]";
2164 for (
int itag = 0; itag < interp_tag_len; itag++) {
2166 CHKERR create_scalar_tags(src_elems, source_data, itag);
2168 std::vector<double> target_data_scalar(num_pts, 0.0);
2169 CHKERR mbc.interpolate(method, scalar_tag_name, &target_data_scalar[0],
2172 for (
int ielem = 0; ielem < num_pts; ielem++) {
2173 target_data[itag + ielem * interp_tag_len] =
2174 target_data_scalar[ielem];
2179 CHKERR moab.tag_set_data(interp_tag, targ_verts, &target_data[0]);
2184 <<
"Using hybrid interpolation for "
2185 "missing points in the target mesh.";
2186 Range missing_adj_elems;
2187 CHKERR moab.get_adjacencies(missing_verts, 3,
false, missing_adj_elems,
2188 moab::Interface::UNION);
2190 int num_adj_elems = (int)missing_adj_elems.size();
2191 std::vector<double> vpos_adj_elems;
2193 vpos_adj_elems.resize(3 * missing_adj_elems.size());
2194 CHKERR moab.get_coords(missing_adj_elems, &vpos_adj_elems[0]);
2198 CHKERR mbc.locate_points(&vpos_adj_elems[0], num_adj_elems, 0, toler,
2199 tl_ptr.get(),
false);
2202 CHKERR find_missing_points(missing_adj_elems, num_adj_elems,
2203 vpos_adj_elems, missing_tets);
2204 if (missing_tets.size()) {
2206 << missing_tets.size()
2207 <<
" points in target mesh were not located in source mesh. ";
2210 std::vector<double> target_data_adj_elems(
2211 interp_tag_len * num_adj_elems, 0.0);
2213 for (
int itag = 0; itag < interp_tag_len; itag++) {
2214 CHKERR create_scalar_tags(src_elems, source_data, itag);
2216 std::vector<double> target_data_adj_elems_scalar(num_adj_elems, 0.0);
2217 CHKERR mbc.interpolate(method, scalar_tag_name,
2218 &target_data_adj_elems_scalar[0],
2221 for (
int ielem = 0; ielem < num_adj_elems; ielem++) {
2222 target_data_adj_elems[itag + ielem * interp_tag_len] =
2223 target_data_adj_elems_scalar[ielem];
2227 CHKERR moab.tag_set_data(interp_tag, missing_adj_elems,
2228 &target_data_adj_elems[0]);
2231 for (
auto &vert : missing_verts) {
2233 CHKERR moab.get_adjacencies(&vert, 1, 3,
false, adj_elems,
2234 moab::Interface::UNION);
2236 std::vector<double> adj_elems_data(adj_elems.size() * interp_tag_len,
2238 CHKERR moab.tag_get_data(interp_tag, adj_elems, &adj_elems_data[0]);
2240 std::vector<double> vert_data(interp_tag_len, 0.0);
2241 for (
int itag = 0; itag < interp_tag_len; itag++) {
2242 for (
int i = 0;
i < adj_elems.size();
i++) {
2243 vert_data[itag] += adj_elems_data[
i * interp_tag_len + itag];
2245 vert_data[itag] /= adj_elems.size();
2247 CHKERR moab.tag_set_data(interp_tag, &vert, 1, &vert_data[0]);
2251 CHKERR moab.tag_delete(scalar_tag);
2252 CHKERR moab.tag_delete(adj_count_tag);
2256 Range src_mesh_ents;
2257 CHKERR moab.get_entities_by_handle(source_root, src_mesh_ents);
2258 CHKERR moab.delete_entities(&source_root, 1);
2259 CHKERR moab.delete_entities(src_mesh_ents);
2260 CHKERR moab.delete_entities(&part_set, 1);
2264 int tag_size = tag_length.size();
2265 MPI_Bcast(&tag_size, 1, MPI_INT, 0, PETSC_COMM_WORLD);
2267 interp_tags.resize(tag_size);
2268 tag_length.resize(tag_size);
2269 dtype.resize(tag_size);
2270 storage.resize(tag_size);
2272 MPI_Bcast(interp_tags.data(), tag_size, MPI_INT, 0, PETSC_COMM_WORLD);
2273 MPI_Bcast(tag_length.data(), tag_size, MPI_INT, 0, PETSC_COMM_WORLD);
2274 MPI_Bcast(dtype.data(), tag_size, MPI_INT, 0, PETSC_COMM_WORLD);
2275 MPI_Bcast(storage.data(), tag_size, MPI_INT, 0, PETSC_COMM_WORLD);
2280 for (
size_t index = 0; index < interp_tags.size(); index++) {
2284 auto rval_check_tag =
2286 if (rval_check_tag == MB_SUCCESS) {
2288 <<
"Deleting existing tag on target mesh (post-projection): "
2290 CHKERR moab.tag_delete(old_interp_tag);
2295 MB_TAG_CREAT | storage[index];
2296 std::vector<double> def_val(tag_length[index], 0.);
2298 tag_length[index], dtype[index],
2299 interp_tag_all, flags, def_val.data());
2300 if (
rval != MB_SUCCESS && world_rank) {
2302 "Unable to create projection tag %s",
2306 MPI_Barrier(PETSC_COMM_WORLD);
2323 CHKERR moab.delete_entities(&target_root, 1);
2331 const bool add_bubble) {
2335 auto add_field_to_fe = [
this](
const std::string fe,
2375 auto set_fe_adjacency = [&](
auto fe_name) {
2378 boost::make_shared<ParentFiniteElementAdjacencyFunctionSkeleton<2>>(
2386 auto add_field_to_fe = [
this](
const std::string fe,
2400 Range natural_bc_elements;
2403 natural_bc_elements.merge(
v.faces);
2408 natural_bc_elements.merge(
v.faces);
2413 natural_bc_elements.merge(
v.faces);
2418 natural_bc_elements.merge(
v.faces);
2423 natural_bc_elements.merge(
v.faces);
2428 natural_bc_elements.merge(
v.faces);
2433 natural_bc_elements.merge(
v.faces);
2436 natural_bc_elements = intersect(natural_bc_elements, meshset_ents);
2447 auto get_skin = [&](
auto &body_ents) {
2450 CHKERR skin.find_skin(0, body_ents,
false, skin_ents);
2455 Range boundary_ents;
2456 ParallelComm *pcomm =
2458 CHKERR pcomm->filter_pstatus(skin, PSTATUS_SHARED | PSTATUS_MULTISHARED,
2459 PSTATUS_NOT, -1, &boundary_ents);
2460 return boundary_ents;
2542 auto remove_dofs_on_broken_skin = [&](
const std::string prb_name) {
2544 for (
int d : {0, 1, 2}) {
2545 std::vector<boost::weak_ptr<NumeredDofEntity>> dofs_to_remove;
2547 ->getSideDofsOnBrokenSpaceEntities(
2558 CHKERR remove_dofs_on_broken_skin(
"ESHELBY_PLASTICITY");
2602 auto set_zero_block = [&]() {
2630 auto zero_kinetic_constraints_block = [&]() {
2637 CHKERR bc_mng->removeBlockDOFsOnEntities(
"MATERIAL_PROBLEM",
"REMOVE_Y",
2639 CHKERR bc_mng->removeBlockDOFsOnEntities(
"MATERIAL_PROBLEM",
"REMOVE_Z",
2641 CHKERR bc_mng->removeBlockDOFsOnEntities(
"MATERIAL_PROBLEM",
"REMOVE_ALL",
2643 CHKERR bc_mng->removeBlockDOFsOnEntities(
"MATERIAL_PROBLEM",
"FIX_X",
2645 CHKERR bc_mng->removeBlockDOFsOnEntities(
"MATERIAL_PROBLEM",
"FIX_Y",
2647 CHKERR bc_mng->removeBlockDOFsOnEntities(
"MATERIAL_PROBLEM",
"FIX_Z",
2649 CHKERR bc_mng->removeBlockDOFsOnEntities(
"MATERIAL_PROBLEM",
"FIX_ALL",
2660 auto set_section = [&]() {
2662 PetscSection section;
2667 CHKERR PetscSectionDestroy(§ion);
2690BcDisp::BcDisp(std::string name, std::vector<double> attr,
Range faces)
2691 : blockName(name), faces(faces) {
2692 vals.resize(3,
false);
2693 flags.resize(3,
false);
2694 for (
int ii = 0; ii != 3; ++ii) {
2695 vals[ii] = attr[ii];
2696 flags[ii] =
static_cast<int>(attr[ii + 3]);
2699 MOFEM_LOG(
"EP", Sev::inform) <<
"Add BCDisp " << name;
2701 <<
"Add BCDisp vals " <<
vals[0] <<
" " <<
vals[1] <<
" " <<
vals[2];
2703 <<
"Add BCDisp flags " <<
flags[0] <<
" " <<
flags[1] <<
" " <<
flags[2];
2704 MOFEM_LOG(
"EP", Sev::inform) <<
"Add BCDisp nb. of faces " <<
faces.size();
2708 : blockName(name), faces(faces) {
2709 vals.resize(attr.size(),
false);
2710 for (
int ii = 0; ii != attr.size(); ++ii) {
2711 vals[ii] = attr[ii];
2717 : blockName(name), faces(faces) {
2718 vals.resize(3,
false);
2719 flags.resize(3,
false);
2720 for (
int ii = 0; ii != 3; ++ii) {
2721 vals[ii] = attr[ii];
2722 flags[ii] =
static_cast<int>(attr[ii + 3]);
2725 MOFEM_LOG(
"EP", Sev::inform) <<
"Add BCForce " << name;
2727 <<
"Add BCForce vals " <<
vals[0] <<
" " <<
vals[1] <<
" " <<
vals[2];
2729 <<
"Add BCForce flags " <<
flags[0] <<
" " <<
flags[1] <<
" " <<
flags[2];
2730 MOFEM_LOG(
"EP", Sev::inform) <<
"Add BCForce nb. of faces " <<
faces.size();
2734 std::vector<double> attr,
2736 : blockName(name), faces(faces) {
2739 if (attr.size() < 1) {
2741 "Wrong size of normal displacement BC");
2746 MOFEM_LOG(
"EP", Sev::inform) <<
"Add NormalDisplacementBc " << name;
2747 MOFEM_LOG(
"EP", Sev::inform) <<
"Add NormalDisplacementBc val " <<
val;
2749 <<
"Add NormalDisplacementBc nb. of faces " <<
faces.size();
2753 : blockName(name), faces(faces) {
2756 if (attr.size() < 1) {
2758 "Wrong size of normal displacement BC");
2763 MOFEM_LOG(
"EP", Sev::inform) <<
"Add PressureBc " << name;
2764 MOFEM_LOG(
"EP", Sev::inform) <<
"Add PressureBc val " <<
val;
2766 <<
"Add PressureBc nb. of faces " <<
faces.size();
2771 : blockName(name), ents(ents) {
2774 if (attr.size() < 2) {
2776 "Wrong size of external strain attribute");
2782 MOFEM_LOG(
"EP", Sev::inform) <<
"Add ExternalStrain " << name;
2783 MOFEM_LOG(
"EP", Sev::inform) <<
"Add ExternalStrain val " <<
val;
2785 <<
"Add ExternalStrain bulk modulus K " <<
bulkModulusK;
2787 <<
"Add ExternalStrain bulk modulus K " <<
bulkModulusK;
2789 <<
"Add ExternalStrain nb. of tets " <<
ents.size();
2793 std::vector<double> attr,
2795 : blockName(name), faces(faces) {
2798 if (attr.size() < 3) {
2800 "Wrong size of analytical displacement BC");
2803 flags.resize(3,
false);
2804 for (
int ii = 0; ii != 3; ++ii) {
2805 flags[ii] = attr[ii];
2808 MOFEM_LOG(
"EP", Sev::inform) <<
"Add AnalyticalDisplacementBc " << name;
2810 <<
"Add AnalyticalDisplacementBc flags " <<
flags[0] <<
" " <<
flags[1]
2813 <<
"Add AnalyticalDisplacementBc nb. of faces " <<
faces.size();
2817 std::vector<double> attr,
2819 : blockName(name), faces(faces) {
2822 if (attr.size() < 3) {
2824 "Wrong size of analytical traction BC");
2827 flags.resize(3,
false);
2828 for (
int ii = 0; ii != 3; ++ii) {
2829 flags[ii] = attr[ii];
2832 MOFEM_LOG(
"EP", Sev::inform) <<
"Add AnalyticalTractionBc " << name;
2833 MOFEM_LOG(
"EP", Sev::inform) <<
"Add AnalyticalTractionBc flags " <<
flags[0]
2836 <<
"Add AnalyticalTractionBc nb. of faces " <<
faces.size();
2841 boost::shared_ptr<TractionFreeBc> &bc_ptr,
2842 const std::string contact_set_name) {
2847 CHKERR mField.get_moab().get_entities_by_type(meshset, MBTET, tets);
2848 Range tets_skin_part;
2849 Skinner skin(&mField.get_moab());
2850 CHKERR skin.find_skin(0, tets,
false, tets_skin_part);
2851 ParallelComm *pcomm =
2854 CHKERR pcomm->filter_pstatus(tets_skin_part,
2855 PSTATUS_SHARED | PSTATUS_MULTISHARED,
2856 PSTATUS_NOT, -1, &tets_skin);
2859 for (
int dd = 0; dd != 3; ++dd)
2860 (*bc_ptr)[dd] = tets_skin;
2863 if (bcSpatialDispVecPtr)
2864 for (
auto &
v : *bcSpatialDispVecPtr) {
2866 (*bc_ptr)[0] = subtract((*bc_ptr)[0],
v.faces);
2868 (*bc_ptr)[1] = subtract((*bc_ptr)[1],
v.faces);
2870 (*bc_ptr)[2] = subtract((*bc_ptr)[2],
v.faces);
2874 if (bcSpatialRotationVecPtr)
2875 for (
auto &
v : *bcSpatialRotationVecPtr) {
2876 (*bc_ptr)[0] = subtract((*bc_ptr)[0],
v.faces);
2877 (*bc_ptr)[1] = subtract((*bc_ptr)[1],
v.faces);
2878 (*bc_ptr)[2] = subtract((*bc_ptr)[2],
v.faces);
2881 if (bcSpatialNormalDisplacementVecPtr)
2882 for (
auto &
v : *bcSpatialNormalDisplacementVecPtr) {
2883 (*bc_ptr)[0] = subtract((*bc_ptr)[0],
v.faces);
2884 (*bc_ptr)[1] = subtract((*bc_ptr)[1],
v.faces);
2885 (*bc_ptr)[2] = subtract((*bc_ptr)[2],
v.faces);
2888 if (bcSpatialAnalyticalDisplacementVecPtr)
2889 for (
auto &
v : *bcSpatialAnalyticalDisplacementVecPtr) {
2891 (*bc_ptr)[0] = subtract((*bc_ptr)[0],
v.faces);
2893 (*bc_ptr)[1] = subtract((*bc_ptr)[1],
v.faces);
2895 (*bc_ptr)[2] = subtract((*bc_ptr)[2],
v.faces);
2898 if (bcSpatialTractionVecPtr)
2899 for (
auto &
v : *bcSpatialTractionVecPtr) {
2900 (*bc_ptr)[0] = subtract((*bc_ptr)[0],
v.faces);
2901 (*bc_ptr)[1] = subtract((*bc_ptr)[1],
v.faces);
2902 (*bc_ptr)[2] = subtract((*bc_ptr)[2],
v.faces);
2905 if (bcSpatialAnalyticalTractionVecPtr)
2906 for (
auto &
v : *bcSpatialAnalyticalTractionVecPtr) {
2907 (*bc_ptr)[0] = subtract((*bc_ptr)[0],
v.faces);
2908 (*bc_ptr)[1] = subtract((*bc_ptr)[1],
v.faces);
2909 (*bc_ptr)[2] = subtract((*bc_ptr)[2],
v.faces);
2912 if (bcSpatialPressureVecPtr)
2913 for (
auto &
v : *bcSpatialPressureVecPtr) {
2914 (*bc_ptr)[0] = subtract((*bc_ptr)[0],
v.faces);
2915 (*bc_ptr)[1] = subtract((*bc_ptr)[1],
v.faces);
2916 (*bc_ptr)[2] = subtract((*bc_ptr)[2],
v.faces);
2921 std::regex((boost::format(
"%s(.*)") % contact_set_name).str()))) {
2923 CHKERR m->getMeshsetIdEntitiesByDimension(mField.get_moab(), 2, faces,
2925 (*bc_ptr)[0] = subtract((*bc_ptr)[0], faces);
2926 (*bc_ptr)[1] = subtract((*bc_ptr)[1], faces);
2927 (*bc_ptr)[2] = subtract((*bc_ptr)[2], faces);
2944 return 2 * p_data + 1;
2950 return 2 * (p_data + 1);
2955 const int tag,
const bool do_rhs,
const bool do_lhs,
const bool calc_rates,
2956 boost::shared_ptr<VolumeElementForcesAndSourcesCore> fe,
2957 const bool add_bubble) {
2961 boost::make_shared<CGGUserPolynomialBase::CachePhi>(0, 0,
MatrixDouble());
2962 fe->getUserPolynomialBase() =
2963 boost::make_shared<CGGUserPolynomialBase>(bubble_cache);
2964 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
2965 fe->getOpPtrVector(), {HDIV, H1, L2}, materialH1Positions, frontAdjEdges);
2968 fe->getRuleHook = [](int, int, int) {
return -1; };
2970 fe->setRuleHook = SetIntegrationAtFrontVolume(frontVertices, frontAdjEdges,
2977 dataAtPts->physicsPtr = physicalEquations;
2982 piolaStress, dataAtPts->getApproxPAtPts()));
2985 bubbleField, dataAtPts->getApproxPAtPts(), MBMAXTYPE));
2988 piolaStress, dataAtPts->getDivPAtPts()));
2990 if (stretchHandling == NO_STREACH) {
2991 fe->getOpPtrVector().push_back(
2992 physicalEquations->returnOpCalculateStretchFromStress(
2993 dataAtPts, physicalEquations));
2995 fe->getOpPtrVector().push_back(
2997 stretchTensor, dataAtPts->getLogStretchTensorAtPts(), MBTET));
3001 rotAxis, dataAtPts->getRotAxisAtPts(), MBTET));
3002 CHKERR VecSetDM(solTSStep, PETSC_NULLPTR);
3004 rotAxis, dataAtPts->getRotAxis0AtPts(), solTSStep, MBTET));
3006 spatialL2Disp, dataAtPts->getSmallWL2AtPts(), MBTET));
3010 spatialH1Disp, dataAtPts->getSmallWH1AtPts()));
3012 spatialH1Disp, dataAtPts->getSmallWGradH1AtPts()));
3017 spatialL2Disp, dataAtPts->getSmallWL2DotAtPts(), MBTET));
3018 if (stretchHandling == NO_STREACH) {
3020 fe->getOpPtrVector().push_back(
3022 stretchTensor, dataAtPts->getLogStretchDotTensorAtPts(), MBTET));
3023 fe->getOpPtrVector().push_back(
3025 stretchTensor, dataAtPts->getGradLogStretchDotTensorAtPts(),
3029 rotAxis, dataAtPts->getRotAxisDotAtPts(), MBTET));
3031 rotAxis, dataAtPts->getRotAxisGradDotAtPts(), MBTET));
3034 if (std::abs(alphaRho) > std::numeric_limits<double>::epsilon()) {
3036 spatialL2Disp, dataAtPts->getSmallWL2DotDotAtPts(), MBTET));
3042 dataAtPts, ((do_rhs || do_lhs) && calc_rates) ? alphaOmega : 0.));
3045 if (stretchHandling == NO_STREACH) {
3047 fe->getOpPtrVector().push_back(physicalEquations->returnOpJacobian(
3048 do_rhs, do_lhs, dataAtPts, physicalEquations));
3055 boost::shared_ptr<VolumeElementForcesAndSourcesCore> fe_lhs) {
3058 bool has_nonhomogeneous_mat_block =
3061 piolaStress, piolaStress, dataAtPts, has_nonhomogeneous_mat_block));
3063 bubbleField, piolaStress, dataAtPts, has_nonhomogeneous_mat_block));
3065 bubbleField, bubbleField, dataAtPts, has_nonhomogeneous_mat_block));
3068 spatialL2Disp, piolaStress, dataAtPts,
true));
3070 spatialL2Disp, spatialL2Disp, dataAtPts, alphaW, alphaRho));
3073 piolaStress, rotAxis, dataAtPts,
3074 symmetrySelector ==
SYMMETRIC ?
true :
false));
3076 bubbleField, rotAxis, dataAtPts,
3077 symmetrySelector ==
SYMMETRIC ?
true :
false));
3081 rotAxis, piolaStress, dataAtPts,
false));
3083 rotAxis, bubbleField, dataAtPts,
false));
3086 rotAxis, rotAxis, dataAtPts, alphaOmega));
3092 boost::shared_ptr<VolumeElementForcesAndSourcesCore> fe_lhs) {
3095 fe_lhs->getOpPtrVector().push_back(
3096 physicalEquations->returnOpSpatialPhysical_du_du(
3097 stretchTensor, stretchTensor, dataAtPts, alphaU));
3099 stretchTensor, piolaStress, dataAtPts,
true));
3101 stretchTensor, bubbleField, dataAtPts,
true));
3103 stretchTensor, rotAxis, dataAtPts,
3104 symmetrySelector ==
SYMMETRIC ?
true :
false));
3107 spatialL2Disp, piolaStress, dataAtPts,
true));
3109 spatialL2Disp, spatialL2Disp, dataAtPts, alphaW, alphaRho));
3112 piolaStress, rotAxis, dataAtPts,
3113 symmetrySelector ==
SYMMETRIC ?
true :
false));
3115 bubbleField, rotAxis, dataAtPts,
3116 symmetrySelector ==
SYMMETRIC ?
true :
false));
3120 rotAxis, stretchTensor, dataAtPts,
false));
3122 rotAxis, piolaStress, dataAtPts,
false));
3124 rotAxis, bubbleField, dataAtPts,
false));
3127 rotAxis, rotAxis, dataAtPts, alphaOmega));
3133 boost::shared_ptr<VolumeElementForcesAndSourcesCore> fe_lhs) {
3135 CHKERR pushPiolaStressGramOps(fe_lhs);
3136 fe_lhs->getOpPtrVector().push_back(
3139 bubbleField, bubbleField));
3144 boost::shared_ptr<VolumeElementForcesAndSourcesCore> fe_lhs) {
3146 fe_lhs->getOpPtrVector().push_back(
3152 const int tag,
const bool add_elastic,
const bool add_material,
3153 boost::shared_ptr<VolumeElementForcesAndSourcesCore> &fe_rhs,
3154 boost::shared_ptr<VolumeElementForcesAndSourcesCore> &fe_lhs) {
3159 std::map<int, Range> map;
3162 mField.getInterface<
MeshsetsManager>()->getCubitMeshsetPtr(std::regex(
3164 (boost::format(
"%s(.*)") % name).str()
3170 CHK_MOAB_THROW(m_ptr->getMeshsetIdEntitiesByDimension(mField.get_moab(),
3173 map[m_ptr->getMeshsetId()] = ents;
3179 auto local_tau_sacale = boost::make_shared<double>(1.0);
3182 using BdyEleOp = BoundaryEle::UserDataOperator;
3183 struct OpSetTauScale :
public BdyEleOp {
3184 OpSetTauScale(boost::shared_ptr<double> local_tau_sacale,
double alphaTau)
3186 localTauSacale(local_tau_sacale), alphaTau(alphaTau) {}
3190 auto &coords = BdyEleOp::getCoords();
3191 auto [centre, barycenter,
h] =
3193 *localTauSacale = (alphaTau /
h);
3198 boost::shared_ptr<double> localTauSacale;
3202 auto not_interface_face = [
this](
FEMethod *fe_method_ptr) {
3203 auto ent = fe_method_ptr->getFEEntityHandle();
3206 (interfaceFaces->find(ent) != interfaceFaces->end())
3208 || (crackFaces->find(ent) != crackFaces->end())
3217 fe_rhs = boost::make_shared<VolumeElementForcesAndSourcesCore>(mField);
3218 CHKERR setBaseVolumeElementOps(tag,
true,
false,
true, fe_rhs);
3223 fe_rhs->getOpPtrVector().push_back(
3225 fe_rhs->getOpPtrVector().push_back(
3227 if (stretchHandling == NO_STREACH) {
3230 if (!internalStressTagName.empty()) {
3231 switch (meshTransferInterpOrder) {
3233 fe_rhs->getOpPtrVector().push_back(
3237 fe_rhs->getOpPtrVector().push_back(
3242 "Unsupported mesh transfer interpolation order %d, for "
3244 meshTransferInterpOrder);
3248 auto ts_internal_stress =
3249 boost::make_shared<DynamicRelaxationTimeScale>(
3250 "internal_stress_history.txt",
false, def_scaling_fun);
3251 if (internalStressVoigt) {
3252 fe_rhs->getOpPtrVector().push_back(
3254 stretchTensor, dataAtPts, ts_internal_stress));
3256 fe_rhs->getOpPtrVector().push_back(
3258 stretchTensor, dataAtPts, ts_internal_stress));
3261 if (
auto op = physicalEquations->returnOpSpatialPhysicalExternalStrain(
3262 stretchTensor, dataAtPts, externalStrainVecPtr, timeScaleMap)) {
3263 fe_rhs->getOpPtrVector().push_back(op);
3264 }
else if (externalStrainVecPtr && !externalStrainVecPtr->empty()) {
3266 "OpSpatialPhysicalExternalStrain not implemented for this "
3270 fe_rhs->getOpPtrVector().push_back(
3271 physicalEquations->returnOpSpatialPhysical(stretchTensor, dataAtPts,
3274 fe_rhs->getOpPtrVector().push_back(
3276 fe_rhs->getOpPtrVector().push_back(
3278 fe_rhs->getOpPtrVector().push_back(
3281 auto set_hybridisation_rhs = [&](
auto &pip) {
3288 using SideEleOp = EleOnSide::UserDataOperator;
3289 using BdyEleOp = BoundaryEle::UserDataOperator;
3294 mField, skeletonElement,
SPACE_DIM - 1, Sev::noisy);
3296 op_loop_skeleton_side->getSideFEPtr()->getRuleHook = [](int, int, int) {
3299 op_loop_skeleton_side->getSideFEPtr()->setRuleHook =
3300 SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
3302 CHKERR EshelbianPlasticity::
3303 AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
3304 op_loop_skeleton_side->getOpPtrVector(), {L2},
3305 materialH1Positions, frontAdjEdges);
3309 auto broken_data_ptr =
3310 boost::make_shared<std::vector<BrokenBaseSideData>>();
3313 mField, elementVolumeName,
SPACE_DIM, Sev::noisy);
3314 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
3315 boost::make_shared<CGGUserPolynomialBase>(
nullptr,
true);
3317 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
3318 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
3319 materialH1Positions, frontAdjEdges);
3320 op_loop_domain_side->getOpPtrVector().push_back(
3322 auto flux_mat_ptr = boost::make_shared<MatrixDouble>();
3323 op_loop_domain_side->getOpPtrVector().push_back(
3326 op_loop_domain_side->getOpPtrVector().push_back(
3330 op_loop_skeleton_side->getOpPtrVector().push_back(op_loop_domain_side);
3332 GAUSS>::OpBrokenSpaceConstrainDHybrid<SPACE_DIM>;
3334 GAUSS>::OpBrokenSpaceConstrainDFlux<SPACE_DIM>;
3335 op_loop_skeleton_side->getOpPtrVector().push_back(
new OpC_dHybrid(
3336 hybridSpatialDisp, broken_data_ptr, boost::make_shared<double>(1.0)));
3337 auto hybrid_ptr = boost::make_shared<MatrixDouble>();
3338 op_loop_skeleton_side->getOpPtrVector().push_back(
3341 op_loop_skeleton_side->getOpPtrVector().push_back(
new OpC_dBroken(
3342 broken_data_ptr, hybrid_ptr, boost::make_shared<double>(1.0)));
3345 pip.push_back(op_loop_skeleton_side);
3350 auto set_tau_stabilsation_rhs = [&](
auto &pip,
auto side_fe_name,
3351 auto hybrid_field) {
3358 using SideEleOp = EleOnSide::UserDataOperator;
3359 using BdyEleOp = BoundaryEle::UserDataOperator;
3364 mField, side_fe_name,
SPACE_DIM - 1, Sev::noisy);
3366 op_loop_skeleton_side->getSideFEPtr()->getRuleHook = [](int, int, int) {
3369 op_loop_skeleton_side->getSideFEPtr()->setRuleHook =
3370 SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
3371 op_loop_skeleton_side->getSideFEPtr()->exeTestHook = not_interface_face;
3372 CHKERR EshelbianPlasticity::
3373 AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
3374 op_loop_skeleton_side->getOpPtrVector(), {L2},
3375 materialH1Positions, frontAdjEdges);
3378 mField, elementVolumeName,
SPACE_DIM, Sev::noisy);
3379 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
3380 boost::make_shared<CGGUserPolynomialBase>(
nullptr,
true);
3382 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
3383 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
3384 materialH1Positions, frontAdjEdges);
3387 auto broken_disp_data_ptr =
3388 boost::make_shared<std::vector<BrokenBaseSideData>>();
3389 op_loop_domain_side->getOpPtrVector().push_back(
3391 broken_disp_data_ptr));
3392 auto disp_mat_ptr = boost::make_shared<MatrixDouble>();
3393 op_loop_domain_side->getOpPtrVector().push_back(
3397 op_loop_domain_side->getOpPtrVector().push_back(
3400 op_loop_skeleton_side->getOpPtrVector().push_back(op_loop_domain_side);
3401 op_loop_skeleton_side->getOpPtrVector().push_back(
3402 new OpSetTauScale(local_tau_sacale, alphaTau));
3405 auto hybrid_ptr = boost::make_shared<MatrixDouble>();
3406 op_loop_skeleton_side->getOpPtrVector().push_back(
3411 op_loop_skeleton_side->getOpPtrVector().push_back(
3413 hybrid_field, hybrid_ptr,
3414 [local_tau_sacale, broken_disp_data_ptr](
double,
double,
double) {
3415 return broken_disp_data_ptr->size() * (*local_tau_sacale);
3418 op_loop_skeleton_side->getOpPtrVector().push_back(
3420 broken_disp_data_ptr, [local_tau_sacale](
double,
double,
double) {
3421 return (*local_tau_sacale);
3424 op_loop_skeleton_side->getOpPtrVector().push_back(
3426 hybrid_field, broken_disp_data_ptr,
3427 [local_tau_sacale](
double,
double,
double) {
3428 return -(*local_tau_sacale);
3431 op_loop_skeleton_side->getOpPtrVector().push_back(
3433 broken_disp_data_ptr, hybrid_ptr,
3434 [local_tau_sacale](
double,
double,
double) {
3435 return -(*local_tau_sacale);
3439 pip.push_back(op_loop_skeleton_side);
3444 auto set_tau_stabilsation_disp_bc_rhs = [&](
auto &pip,
auto side_fe_name) {
3451 using SideEleOp = EleOnSide::UserDataOperator;
3452 using BdyEleOp = BoundaryEle::UserDataOperator;
3457 mField, side_fe_name,
SPACE_DIM - 1, Sev::noisy);
3459 op_loop_skeleton_side->getSideFEPtr()->getRuleHook = [](int, int, int) {
3462 op_loop_skeleton_side->getSideFEPtr()->setRuleHook =
3463 SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
3464 op_loop_skeleton_side->getSideFEPtr()->exeTestHook = not_interface_face;
3465 CHKERR EshelbianPlasticity::
3466 AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
3467 op_loop_skeleton_side->getOpPtrVector(), {L2},
3468 materialH1Positions, frontAdjEdges);
3471 mField, elementVolumeName,
SPACE_DIM, Sev::noisy);
3472 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
3473 boost::make_shared<CGGUserPolynomialBase>(
nullptr,
true);
3475 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
3476 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
3477 materialH1Positions, frontAdjEdges);
3480 auto broken_disp_data_ptr =
3481 boost::make_shared<std::vector<BrokenBaseSideData>>();
3482 op_loop_domain_side->getOpPtrVector().push_back(
3484 broken_disp_data_ptr));
3485 auto disp_mat_ptr = boost::make_shared<MatrixDouble>();
3486 op_loop_domain_side->getOpPtrVector().push_back(
3490 op_loop_domain_side->getOpPtrVector().push_back(
3493 op_loop_skeleton_side->getOpPtrVector().push_back(op_loop_domain_side);
3494 op_loop_skeleton_side->getOpPtrVector().push_back(
3495 new OpSetTauScale(local_tau_sacale, alphaTau));
3498 op_loop_skeleton_side->getOpPtrVector().push_back(
3500 broken_disp_data_ptr, bcSpatialDispVecPtr, timeScaleMap,
3501 [local_tau_sacale](
double,
double,
double) {
3502 return (*local_tau_sacale);
3504 op_loop_skeleton_side->getOpPtrVector().push_back(
3506 broken_disp_data_ptr, bcSpatialAnalyticalDisplacementVecPtr,
3507 timeScaleMap, [local_tau_sacale](
double,
double,
double) {
3508 return (*local_tau_sacale);
3510 op_loop_skeleton_side->getOpPtrVector().push_back(
3512 broken_disp_data_ptr, bcSpatialRotationVecPtr, timeScaleMap,
3513 [local_tau_sacale](
double,
double,
double) {
3514 return (*local_tau_sacale);
3518 pip.push_back(op_loop_skeleton_side);
3523 auto set_contact_rhs = [&](
auto &pip) {
3527 auto set_cohesive_rhs = [&](
auto &pip) {
3529 *
this, SetIntegrationAtFrontFace(frontVertices, frontAdjEdges),
3530 interfaceFaces, pip);
3533 CHKERR set_hybridisation_rhs(fe_rhs->getOpPtrVector());
3534 CHKERR set_contact_rhs(fe_rhs->getOpPtrVector());
3535 if (alphaTau > 0.0) {
3536 CHKERR set_tau_stabilsation_rhs(fe_rhs->getOpPtrVector(), skeletonElement,
3538 CHKERR set_tau_stabilsation_disp_bc_rhs(fe_rhs->getOpPtrVector(),
3541 if (interfaceCrack == PETSC_TRUE) {
3542 CHKERR set_cohesive_rhs(fe_rhs->getOpPtrVector());
3546 using BodyNaturalBC =
3548 Assembly<PETSC>::LinearForm<
GAUSS>;
3550 BodyNaturalBC::OpFlux<NaturalMeshsetType<BLOCKSET>, 1, 3>;
3552 auto body_time_scale =
3553 boost::make_shared<DynamicRelaxationTimeScale>(
"body_force.txt");
3554 CHKERR BodyNaturalBC::AddFluxToPipeline<OpBodyForce>::add(
3555 fe_rhs->getOpPtrVector(), mField, spatialL2Disp, {body_time_scale},
3556 "BODY_FORCE", Sev::inform);
3560 fe_lhs = boost::make_shared<VolumeElementForcesAndSourcesCore>(mField);
3561 CHKERR setBaseVolumeElementOps(tag,
true,
true,
true, fe_lhs);
3566 if (stretchHandling == NO_STREACH) {
3567 CHKERR pushNoStretchVolumeA00Ops(fe_lhs);
3569 CHKERR pushStretchVolumeA00Ops(fe_lhs);
3572 auto set_hybridisation_lhs = [&](
auto &pip) {
3579 using SideEleOp = EleOnSide::UserDataOperator;
3580 using BdyEleOp = BoundaryEle::UserDataOperator;
3585 mField, skeletonElement,
SPACE_DIM - 1, Sev::noisy);
3586 op_loop_skeleton_side->getSideFEPtr()->getRuleHook = [](int, int, int) {
3589 op_loop_skeleton_side->getSideFEPtr()->setRuleHook =
3590 SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
3591 CHKERR EshelbianPlasticity::
3592 AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
3593 op_loop_skeleton_side->getOpPtrVector(), {L2},
3594 materialH1Positions, frontAdjEdges);
3598 auto broken_data_ptr =
3599 boost::make_shared<std::vector<BrokenBaseSideData>>();
3602 mField, elementVolumeName,
SPACE_DIM, Sev::noisy);
3603 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
3604 boost::make_shared<CGGUserPolynomialBase>(
nullptr,
true);
3606 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
3607 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
3608 materialH1Positions, frontAdjEdges);
3609 op_loop_domain_side->getOpPtrVector().push_back(
3612 op_loop_skeleton_side->getOpPtrVector().push_back(op_loop_domain_side);
3614 GAUSS>::OpBrokenSpaceConstrain<SPACE_DIM>;
3615 op_loop_skeleton_side->getOpPtrVector().push_back(
3616 new OpC(hybridSpatialDisp, broken_data_ptr,
3617 boost::make_shared<double>(1.0),
true,
false));
3619 pip.push_back(op_loop_skeleton_side);
3624 auto set_tau_stabilsation_lhs = [&](
auto &pip,
auto side_fe_name,
3625 auto hybrid_field) {
3632 using SideEleOp = EleOnSide::UserDataOperator;
3633 using BdyEleOp = BoundaryEle::UserDataOperator;
3638 mField, side_fe_name,
SPACE_DIM - 1, Sev::noisy);
3639 op_loop_skeleton_side->getSideFEPtr()->getRuleHook = [](int, int, int) {
3642 op_loop_skeleton_side->getSideFEPtr()->setRuleHook =
3643 SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
3644 op_loop_skeleton_side->getSideFEPtr()->exeTestHook = not_interface_face;
3645 CHKERR EshelbianPlasticity::
3646 AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
3647 op_loop_skeleton_side->getOpPtrVector(), {L2},
3648 materialH1Positions, frontAdjEdges);
3652 mField, elementVolumeName,
SPACE_DIM, Sev::noisy);
3653 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
3654 boost::make_shared<CGGUserPolynomialBase>(
nullptr,
true);
3656 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
3657 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
3658 materialH1Positions, frontAdjEdges);
3660 auto broken_disp_data_ptr =
3661 boost::make_shared<std::vector<BrokenBaseSideData>>();
3662 op_loop_domain_side->getOpPtrVector().push_back(
3664 broken_disp_data_ptr));
3665 op_loop_skeleton_side->getOpPtrVector().push_back(op_loop_domain_side);
3666 op_loop_skeleton_side->getOpPtrVector().push_back(
3667 new OpSetTauScale(local_tau_sacale, alphaTau));
3671 hybrid_field, hybrid_field,
3672 [local_tau_sacale, broken_disp_data_ptr](
double,
double,
double) {
3673 return broken_disp_data_ptr->size() * (*local_tau_sacale);
3676 op_loop_skeleton_side->getOpPtrVector().push_back(
3678 broken_disp_data_ptr, [local_tau_sacale](
double,
double,
double) {
3679 return (*local_tau_sacale);
3682 op_loop_skeleton_side->getOpPtrVector().push_back(
3684 hybrid_field, broken_disp_data_ptr,
3685 [local_tau_sacale](
double,
double,
double) {
3686 return -(*local_tau_sacale);
3690 op_loop_skeleton_side->getOpPtrVector().push_back(
3692 hybrid_field, broken_disp_data_ptr,
3693 [local_tau_sacale](
double,
double,
double) {
3694 return -(*local_tau_sacale);
3698 pip.push_back(op_loop_skeleton_side);
3703 auto set_tau_stabilsation_disp_bc_lhs = [&](
auto &pip,
auto side_fe_name) {
3710 using SideEleOp = EleOnSide::UserDataOperator;
3711 using BdyEleOp = BoundaryEle::UserDataOperator;
3716 mField, side_fe_name,
SPACE_DIM - 1, Sev::noisy);
3717 op_loop_skeleton_side->getSideFEPtr()->getRuleHook = [](int, int, int) {
3720 op_loop_skeleton_side->getSideFEPtr()->setRuleHook =
3721 SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
3722 op_loop_skeleton_side->getSideFEPtr()->exeTestHook = not_interface_face;
3723 CHKERR EshelbianPlasticity::
3724 AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
3725 op_loop_skeleton_side->getOpPtrVector(), {L2},
3726 materialH1Positions, frontAdjEdges);
3730 mField, elementVolumeName,
SPACE_DIM, Sev::noisy);
3731 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
3732 boost::make_shared<CGGUserPolynomialBase>(
nullptr,
true);
3734 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
3735 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
3736 materialH1Positions, frontAdjEdges);
3738 auto broken_disp_data_ptr =
3739 boost::make_shared<std::vector<BrokenBaseSideData>>();
3740 op_loop_domain_side->getOpPtrVector().push_back(
3742 broken_disp_data_ptr));
3743 op_loop_skeleton_side->getOpPtrVector().push_back(op_loop_domain_side);
3744 op_loop_skeleton_side->getOpPtrVector().push_back(
3745 new OpSetTauScale(local_tau_sacale, alphaTau));
3748 op_loop_skeleton_side->getOpPtrVector().push_back(
3750 broken_disp_data_ptr, bcSpatialDispVecPtr,
3751 [local_tau_sacale](
double,
double,
double) {
3752 return (*local_tau_sacale);
3754 op_loop_skeleton_side->getOpPtrVector().push_back(
3756 broken_disp_data_ptr, bcSpatialAnalyticalDisplacementVecPtr,
3757 [local_tau_sacale](
double,
double,
double) {
3758 return (*local_tau_sacale);
3760 op_loop_skeleton_side->getOpPtrVector().push_back(
3762 broken_disp_data_ptr, bcSpatialRotationVecPtr,
3763 [local_tau_sacale](
double,
double,
double) {
3764 return (*local_tau_sacale);
3767 pip.push_back(op_loop_skeleton_side);
3772 auto set_contact_lhs = [&](
auto &pip) {
3776 auto set_cohesive_lhs = [&](
auto &pip) {
3778 *
this, SetIntegrationAtFrontFace(frontVertices, frontAdjEdges),
3779 interfaceFaces, pip);
3782 CHKERR set_hybridisation_lhs(fe_lhs->getOpPtrVector());
3783 CHKERR set_contact_lhs(fe_lhs->getOpPtrVector());
3784 if (alphaTau > 0.0) {
3785 CHKERR set_tau_stabilsation_lhs(fe_lhs->getOpPtrVector(), skeletonElement,
3787 CHKERR set_tau_stabilsation_disp_bc_lhs(fe_lhs->getOpPtrVector(),
3790 if (interfaceCrack == PETSC_TRUE) {
3791 CHKERR set_cohesive_lhs(fe_lhs->getOpPtrVector());
3802 const bool add_elastic,
const bool add_material,
3803 boost::shared_ptr<FaceElementForcesAndSourcesCore> &fe_rhs,
3804 boost::shared_ptr<FaceElementForcesAndSourcesCore> &fe_lhs) {
3807 fe_rhs = boost::make_shared<FaceElementForcesAndSourcesCore>(mField);
3808 fe_lhs = boost::make_shared<FaceElementForcesAndSourcesCore>(mField);
3813 fe_rhs->getRuleHook = [](int, int, int) {
return -1; };
3814 fe_lhs->getRuleHook = [](int, int, int) {
return -1; };
3815 fe_rhs->setRuleHook = SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
3816 fe_lhs->setRuleHook = SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
3819 EshelbianPlasticity::AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
3820 fe_rhs->getOpPtrVector(), {L2}, materialH1Positions, frontAdjEdges);
3822 EshelbianPlasticity::AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
3823 fe_lhs->getOpPtrVector(), {L2}, materialH1Positions, frontAdjEdges);
3827 auto get_broken_op_side = [
this](
auto &pip) {
3830 using SideEleOp = EleOnSide::UserDataOperator;
3832 auto broken_data_ptr =
3833 boost::make_shared<std::vector<BrokenBaseSideData>>();
3836 mField, elementVolumeName,
SPACE_DIM, Sev::noisy);
3837 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
3838 boost::make_shared<CGGUserPolynomialBase>(
nullptr,
true);
3840 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
3841 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
3842 materialH1Positions, frontAdjEdges);
3843 op_loop_domain_side->getOpPtrVector().push_back(
3845 auto flux_mat_ptr = boost::make_shared<MatrixDouble>();
3846 op_loop_domain_side->getOpPtrVector().push_back(
3849 op_loop_domain_side->getOpPtrVector().push_back(
3851 pip.push_back(op_loop_domain_side);
3852 return broken_data_ptr;
3855 auto set_rhs = [&]() {
3858 auto broken_data_ptr = get_broken_op_side(fe_rhs->getOpPtrVector());
3860 fe_rhs->getOpPtrVector().push_back(
3861 new OpDispBc(broken_data_ptr, bcSpatialDispVecPtr, timeScaleMap));
3863 broken_data_ptr, bcSpatialAnalyticalDisplacementVecPtr,
3866 broken_data_ptr, bcSpatialRotationVecPtr, timeScaleMap));
3868 auto piola_scale_ptr = boost::make_shared<double>(1.0);
3869 fe_rhs->getOpPtrVector().push_back(
3871 piola_scale_ptr, timeScaleMap));
3872 auto hybrid_grad_ptr = boost::make_shared<MatrixDouble>();
3874 fe_rhs->getOpPtrVector().push_back(
3876 hybridSpatialDisp, hybrid_grad_ptr));
3878 hybridSpatialDisp, bcSpatialPressureVecPtr, piola_scale_ptr,
3879 hybrid_grad_ptr, timeScaleMap));
3881 hybridSpatialDisp, bcSpatialAnalyticalTractionVecPtr, piola_scale_ptr,
3884 auto hybrid_ptr = boost::make_shared<MatrixDouble>();
3885 fe_rhs->getOpPtrVector().push_back(
3889 hybridSpatialDisp, hybrid_ptr, broken_data_ptr,
3890 bcSpatialNormalDisplacementVecPtr, timeScaleMap));
3892 auto get_normal_disp_bc_faces = [&]() {
3895 return boost::make_shared<Range>(faces);
3900 using BdyEleOp = BoundaryEle::UserDataOperator;
3902 GAUSS>::OpBrokenSpaceConstrainDFlux<SPACE_DIM>;
3903 fe_rhs->getOpPtrVector().push_back(
new OpC_dBroken(
3904 broken_data_ptr, hybrid_ptr, boost::make_shared<double>(1.0),
3905 get_normal_disp_bc_faces()));
3910 auto set_lhs = [&]() {
3913 auto broken_data_ptr = get_broken_op_side(fe_lhs->getOpPtrVector());
3916 hybridSpatialDisp, bcSpatialNormalDisplacementVecPtr, timeScaleMap));
3918 hybridSpatialDisp, broken_data_ptr, bcSpatialNormalDisplacementVecPtr,
3921 auto hybrid_grad_ptr = boost::make_shared<MatrixDouble>();
3923 fe_lhs->getOpPtrVector().push_back(
3925 hybridSpatialDisp, hybrid_grad_ptr));
3927 hybridSpatialDisp, bcSpatialPressureVecPtr, hybrid_grad_ptr,
3930 auto get_normal_disp_bc_faces = [&]() {
3933 return boost::make_shared<Range>(faces);
3938 using BdyEleOp = BoundaryEle::UserDataOperator;
3940 GAUSS>::OpBrokenSpaceConstrain<SPACE_DIM>;
3941 fe_lhs->getOpPtrVector().push_back(
new OpC(
3942 hybridSpatialDisp, broken_data_ptr, boost::make_shared<double>(1.0),
3943 true,
true, get_normal_disp_bc_faces()));
3956 const bool add_elastic,
const bool add_material,
3957 boost::shared_ptr<FaceElementForcesAndSourcesCore> &fe_rhs,
3958 boost::shared_ptr<FaceElementForcesAndSourcesCore> &fe_lhs) {
3965 boost::shared_ptr<ForcesAndSourcesCore> &fe_contact_tree
3978 CHKERR setContactElementRhsOps(contactTreeRhs);
3980 CHKERR setVolumeElementOps(tag,
true,
false, elasticFeRhs, elasticFeLhs);
3981 CHKERR setFaceElementOps(
true,
false, elasticBcRhs, elasticBcLhs);
3984 boost::make_shared<ForcesAndSourcesCore::UserDataOperator::AdjCache>();
3986 auto get_op_contact_bc = [&]() {
3989 mField, contactElement,
SPACE_DIM - 1, Sev::noisy, adj_cache);
3990 return op_loop_side;
3998 boost::shared_ptr<FEMethod> null;
4000 if (std::abs(alphaRho) > std::numeric_limits<double>::epsilon()) {
4033 bool set_ts_monitor) {
4035#ifdef ENABLE_PYTHON_BINDING
4039 auto setup_ts_monitor = [&]() {
4040 boost::shared_ptr<TsCtx>
ts_ctx;
4043 if (set_ts_monitor) {
4047 auto monitor_ptr = boost::make_shared<EshelbianMonitor>(*ep_ptr);
4048 auto testing_monitor_ptr =
4049 boost::make_shared<EshelbianTestingMonitor>(*ep_ptr, monitor_ptr);
4053 PetscBool test_cook_flg = PETSC_FALSE;
4054 PetscBool test_cook_pts_flg = PETSC_FALSE;
4057 &test_cook_flg, PETSC_NULLPTR);
4059 &test_cook_pts_flg, PETSC_NULLPTR);
4062 if (
atom_test || test_cook_flg || test_cook_pts_flg) {
4067 MOFEM_LOG(
"EP", Sev::inform) <<
"TS monitor setup";
4068 return std::make_tuple(
ts_ctx);
4071 auto setup_snes_monitor = [&]() {
4074 CHKERR TSGetSNES(ts, &snes);
4076 CHKERR SNESMonitorSet(snes,
4079 (
void *)(snes_ctx.get()), PETSC_NULLPTR);
4080 MOFEM_LOG(
"EP", Sev::inform) <<
"SNES monitor setup";
4084 auto setup_snes_conergence_test = [&]() {
4087 auto snes_convergence_test = [](SNES snes, PetscInt it, PetscReal xnorm,
4088 PetscReal snorm, PetscReal fnorm,
4089 SNESConvergedReason *reason,
void *cctx) {
4092 CHKERR SNESConvergedDefault(snes, it, xnorm, snorm, fnorm, reason,
4096 CHKERR SNESGetSolutionUpdate(snes, &x_update);
4097 CHKERR SNESGetFunction(snes, &r, PETSC_NULLPTR, PETSC_NULLPTR);
4110 auto setup_section = [&]() {
4111 PetscSection section_raw;
4117 for (
int ff = 0; ff != num_fields; ff++) {
4120 PetscSectionGetFieldName(section_raw, ff, &
field_name),
4127 auto set_vector_on_mesh = [&]() {
4131 CHKERR VecGhostUpdateBegin(x, INSERT_VALUES, SCATTER_FORWARD);
4132 CHKERR VecGhostUpdateEnd(x, INSERT_VALUES, SCATTER_FORWARD);
4133 MOFEM_LOG(
"EP", Sev::inform) <<
"Vector set on mesh";
4137 auto setup_schur_block_solver = [&]() {
4138 MOFEM_LOG(
"EP", Sev::inform) <<
"Setting up Schur block solver";
4140 "append options prefix");
4144 boost::shared_ptr<EshelbianCore::SetUpSchur> schur_ptr;
4145 if constexpr (
A == AssemblyType::BLOCK_MAT) {
4150 MOFEM_LOG(
"EP", Sev::inform) <<
"Setting up Schur block solver done";
4157#ifdef ENABLE_PYTHON_BINDING
4158 return std::make_tuple(setup_sdf(), setup_ts_monitor(),
4159 setup_snes_monitor(), setup_snes_conergence_test(),
4160 setup_section(), set_vector_on_mesh(),
4161 setup_schur_block_solver());
4163 return std::make_tuple(setup_ts_monitor(), setup_snes_monitor(),
4164 setup_snes_conergence_test(), setup_section(),
4165 set_vector_on_mesh(), setup_schur_block_solver());
4173 PetscBool debug_model = PETSC_FALSE;
4177 <<
"Debug model flag is " << (debug_model ?
"ON" :
"OFF");
4179 if (debug_model == PETSC_TRUE) {
4181 auto post_proc = [&](TS ts, PetscReal
t, Vec u, Vec u_t, Vec u_tt, Vec
F,
4186 CHKERR TSGetSNES(ts, &snes);
4188 CHKERR SNESGetIterationNumber(snes, &it);
4189 std::string file_name =
"snes_iteration_" + std::to_string(it) +
".h5m";
4190 CHKERR postProcessResults(1, file_name,
F, u_t);
4191 std::string file_skel_name =
4192 "snes_iteration_skel_" + std::to_string(it) +
".h5m";
4194 auto get_material_force_tag = [&]() {
4195 auto &moab = mField.get_moab();
4202 CHKERR calculateFaceMaterialForce(1, ts);
4203 CHKERR postProcessSkeletonResults(1, file_skel_name,
F,
4204 {get_material_force_tag()});
4208 ts_ctx_ptr->tsDebugHook = post_proc;
4217 CHKERR addDebugModel(ts);
4221 if (std::abs(alphaRho) > std::numeric_limits<double>::epsilon()) {
4223 CHKERR VecDuplicate(x, &xx);
4224 CHKERR VecZeroEntries(xx);
4225 CHKERR TS2SetSolution(ts, x, xx);
4228 CHKERR TSSetSolution(ts, x);
4231 TetPolynomialBase::switchCacheBaseOn<HDIV>(
4232 {elasticFeLhs.get(), elasticFeRhs.get()});
4237 CHKERR TSSolve(ts, PETSC_NULLPTR);
4239 TetPolynomialBase::switchCacheBaseOff<HDIV>(
4240 {elasticFeLhs.get(), elasticFeRhs.get()});
4244 if (mField.get_comm_rank() == 0) {
4247 "solve_elastic_graph.dot");
4252 CHKERR TSGetSNES(ts, &snes);
4253 int lin_solver_iterations;
4254 CHKERR SNESGetLinearSolveIterations(snes, &lin_solver_iterations);
4256 <<
"Number of linear solver iterations " << lin_solver_iterations;
4258 PetscBool test_cook_flg = PETSC_FALSE;
4261 if (test_cook_flg) {
4262 constexpr int expected_lin_solver_iterations = 11;
4263 if (lin_solver_iterations > expected_lin_solver_iterations)
4266 "Expected number of iterations is different than expected %d > %d",
4267 lin_solver_iterations, expected_lin_solver_iterations);
4270 PetscBool test_sslv116_flag = PETSC_FALSE;
4272 &test_sslv116_flag, PETSC_NULLPTR);
4274 if (test_sslv116_flag) {
4275 double max_val = 0.0;
4276 double min_val = 0.0;
4277 auto field_min_max = [&](boost::shared_ptr<FieldEntity> ent_ptr) {
4279 auto ent_type = ent_ptr->getEntType();
4280 if (ent_type == MBVERTEX) {
4281 max_val = std::max(ent_ptr->getEntFieldData()[
SPACE_DIM - 1], max_val);
4282 min_val = std::min(ent_ptr->getEntFieldData()[
SPACE_DIM - 1], min_val);
4287 field_min_max, spatialH1Disp);
4289 double global_max_val = 0.0;
4290 double global_min_val = 0.0;
4291 MPI_Allreduce(&max_val, &global_max_val, 1, MPI_DOUBLE, MPI_MAX,
4293 MPI_Allreduce(&min_val, &global_min_val, 1, MPI_DOUBLE, MPI_MIN,
4296 <<
"Max " << spatialH1Disp <<
" value: " << global_max_val;
4298 <<
"Min " << spatialH1Disp <<
" value: " << global_min_val;
4300 double ref_max_val = 0.00767;
4301 double ref_min_val = -0.00329;
4302 if (std::abs(global_max_val - ref_max_val) > 1e-5) {
4304 "Incorrect max value of the displacement field: %f != %f",
4305 global_max_val, ref_max_val);
4307 if (std::abs(global_min_val - ref_min_val) > 4e-5) {
4309 "Incorrect min value of the displacement field: %f != %f",
4310 global_min_val, ref_min_val);
4321 double start_time) {
4327 PetscOptionsBegin(PETSC_COMM_WORLD,
"",
"Dynamic Relaxation Options",
"none");
4329 CHKERR PetscOptionsScalar(
"-dynamic_final_time",
4330 "dynamic relaxation final time",
"",
4331 finalPhysicalTime, &finalPhysicalTime, PETSC_NULLPTR);
4332 CHKERR PetscOptionsScalar(
"-dynamic_delta_time",
4333 "dynamic relaxation final time",
"", physicalDt,
4334 &physicalDt, PETSC_NULLPTR);
4335 CHKERR PetscOptionsInt(
"-dynamic_max_it",
"dynamic relaxation iterations",
"",
4336 physicalMaxSteps, &physicalMaxSteps, PETSC_NULLPTR);
4337 CHKERR PetscOptionsBool(
"-dynamic_h1_update",
"update each ts step",
"",
4338 physicalH1Update, &physicalH1Update, PETSC_NULLPTR);
4343 <<
"Following options are deprecated, use -physical prefix options "
4346 <<
"Dynamic relaxation final time -dynamic_final_time = "
4347 << finalPhysicalTime;
4349 <<
"Dynamic relaxation delta time -dynamic_delta_time = "
4352 <<
"Dynamic relaxation max iterations -dynamic_max_it = " << physicalMaxSteps;
4354 <<
"Dynamic relaxation H1 update each step -dynamic_h1_update = "
4355 << (physicalH1Update ?
"TRUE" :
"FALSE");
4357 CHKERR addDebugModel(ts);
4359 auto setup_ts_monitor = [&]() {
4360 auto monitor_ptr = boost::make_shared<EshelbianMonitor>(*
this);
4363 auto monitor_ptr = setup_ts_monitor();
4365 TetPolynomialBase::switchCacheBaseOn<HDIV>(
4366 {elasticFeLhs.get(), elasticFeRhs.get()});
4370 double ts_delta_time;
4371 CHKERR TSGetTimeStep(ts, &ts_delta_time);
4373 if (physicalH1Update) {
4381 currentPhysicalTime = start_time;
4382 physicalStepNumber = start_step;
4383 monitor_ptr->ts = PETSC_NULLPTR;
4384 monitor_ptr->ts_u = PETSC_NULLPTR;
4385 monitor_ptr->ts_t = currentPhysicalTime;
4386 monitor_ptr->ts_step = physicalStepNumber;
4389 if (physicalDt <= 0.) {
4391 "physicalDt must be positive, got %g", physicalDt);
4393 for (; currentPhysicalTime < finalPhysicalTime;) {
4395 <<
"Load step " << physicalStepNumber <<
" Time " << currentPhysicalTime
4396 <<
" delta time " << physicalDt;
4398 CHKERR TSSetStepNumber(ts, 0);
4400 CHKERR TSSetTimeStep(ts, ts_delta_time);
4401 if (!physicalH1Update) {
4404 CHKERR TSSetSolution(ts, x);
4405 CHKERR TSSolve(ts, PETSC_NULLPTR);
4406 if (!physicalH1Update) {
4412 CHKERR VecGhostUpdateBegin(x, INSERT_VALUES, SCATTER_FORWARD);
4413 CHKERR VecGhostUpdateEnd(x, INSERT_VALUES, SCATTER_FORWARD);
4415 monitor_ptr->ts = PETSC_NULLPTR;
4416 monitor_ptr->ts_u = x;
4417 monitor_ptr->ts_t = currentPhysicalTime;
4418 monitor_ptr->ts_step = physicalStepNumber;
4421 ++physicalStepNumber;
4422 if (physicalStepNumber > physicalMaxSteps)
4425 const double remainingPhysicalTime =
4426 finalPhysicalTime - currentPhysicalTime;
4427 if (physicalDt >= remainingPhysicalTime) {
4428 currentPhysicalTime = finalPhysicalTime;
4430 currentPhysicalTime += physicalDt;
4435 TetPolynomialBase::switchCacheBaseOff<HDIV>(
4436 {elasticFeLhs.get(), elasticFeRhs.get()});
4444 auto set_block = [&](
auto name,
int dim) {
4445 std::map<int, Range> map;
4446 auto set_tag_impl = [&](
auto name) {
4451 std::regex((boost::format(
"%s(.*)") % name).str())
4454 for (
auto bc : bcs) {
4456 CHKERR bc->getMeshsetIdEntitiesByDimension(mField.get_moab(), dim, r,
4458 map[bc->getMeshsetId()] = r;
4460 <<
"Block " << name <<
" id " << bc->getMeshsetId() <<
" has "
4461 << r.size() <<
" entities";
4466 CHKERR set_tag_impl(name);
4468 return std::make_pair(name, map);
4471 auto set_skin = [&](
auto &&map) {
4472 for (
auto &
m : map.second) {
4476 <<
"Skin for block " << map.first <<
" id " <<
m.first <<
" has "
4477 <<
m.second.size() <<
" entities";
4482 auto set_tag = [&](
auto &&map) {
4484 auto name = map.first;
4485 int def_val[] = {-1};
4487 mField.get_moab().tag_get_handle(name, 1, MB_TYPE_INTEGER,
th,
4488 MB_TAG_SPARSE | MB_TAG_CREAT, def_val),
4490 for (
auto &
m : map.second) {
4498 listTagsToTransfer.push_back(set_tag(set_skin(set_block(
"BODY", 3))));
4499 listTagsToTransfer.push_back(set_tag(set_skin(set_block(
"MAT_ELASTIC", 3))));
4500 listTagsToTransfer.push_back(
4501 set_tag(set_skin(set_block(
"MAT_NEOHOOKEAN", 3))));
4502 listTagsToTransfer.push_back(set_tag(set_block(
"CONTACT", 2)));
4509 std::vector<Tag> tags_to_transfer) {
4511 ParallelComm *pcomm =
4514 if (crackingOn && !pcomm->rank()) {
4517 std::vector<boost::shared_ptr<TempMeshset>> meshsets_tmp_list;
4519 std::vector<Tag> tags_list;
4523 for (
auto &
m : list) {
4526 auto meshset =
m.getMeshset();
4527 std::vector<Tag> tmp_tags_list;
4528 CHKERR mField.get_moab().tag_get_tags_on_entity(meshset, tmp_tags_list);
4530 CHKERR mField.get_moab().get_entities_by_handle(meshset, ents,
true);
4531 CHKERR mField.get_moab().add_entities(new_meshset, ents);
4532 for (
auto t : tmp_tags_list) {
4535 CHKERR mField.get_moab().tag_get_by_ptr(
4536 t, &meshset, 1, (
const void **)tag_vals, tag_size);
4537 CHKERR mField.get_moab().tag_set_by_ptr(
t, &new_meshset, 1, tag_vals,
4540 std::vector<std::string> remove_tags;
4541 remove_tags.push_back(
"AKDTree_coord_norm");
4542 remove_tags.push_back(
"__PARALLEL_");
4543 remove_tags.push_back(
"_RefBitLevel");
4545 for (
auto t : tmp_tags_list) {
4546 std::string tag_name;
4547 CHKERR mField.get_moab().tag_get_name(
t, tag_name);
4550 for (
auto &p : remove_tags) {
4551 if (tag_name.compare(0, p.size(), p) == 0) {
4558 tags_list.push_back(
t);
4562 for (
auto &m_ptr : meshsets_tmp_list) {
4564 CHKERR mField.get_moab().add_entities(*meshset_ptr, &
m, 1);
4568 std::sort(tags_list.begin(), tags_list.end());
4569 auto new_end = std::unique(tags_list.begin(), tags_list.end());
4570 tags_list.resize(std::distance(tags_list.begin(), new_end));
4573 CHKERR mField.get_moab().write_file(file.c_str(),
"MOAB",
"", &save_meshset,
4574 1, &tags_list[0], tags_list.size());
4581 Vec f_residual, Vec var_vector, Vec gradient,
4582 std::vector<Tag> tags_to_transfer, TS ts) {
4586 if (f_residual != PETSC_NULLPTR || var_vector != PETSC_NULLPTR) {
4590 auto xin = f_residual != PETSC_NULLPTR ? f_residual : var_vector;
4596 CHKERR VecScatterBegin(scatter, f_residual, f_r, INSERT_VALUES,
4598 CHKERR VecScatterEnd(scatter, f_residual, f_r, INSERT_VALUES,
4600 CHKERR VecGhostUpdateBegin(f_r, INSERT_VALUES, SCATTER_FORWARD);
4601 CHKERR VecGhostUpdateEnd(f_r, INSERT_VALUES, SCATTER_FORWARD);
4605 CHKERR VecScatterBegin(scatter, var_vector, v_v, INSERT_VALUES,
4607 CHKERR VecScatterEnd(scatter, var_vector, v_v, INSERT_VALUES,
4609 CHKERR VecGhostUpdateBegin(v_v, INSERT_VALUES, SCATTER_FORWARD);
4610 CHKERR VecGhostUpdateEnd(v_v, INSERT_VALUES, SCATTER_FORWARD);
4621 CHKERR VecScatterBegin(scatter, gradient,
g, INSERT_VALUES,
4623 CHKERR VecScatterEnd(scatter, gradient,
g, INSERT_VALUES, SCATTER_FORWARD);
4624 CHKERR VecGhostUpdateBegin(
g, INSERT_VALUES, SCATTER_FORWARD);
4625 CHKERR VecGhostUpdateEnd(
g, INSERT_VALUES, SCATTER_FORWARD);
4630 auto get_tag = [&](
auto name,
auto dim) {
4631 auto &mob = mField.get_moab();
4633 double def_val[] = {0., 0., 0.};
4634 CHK_MOAB_THROW(mob.tag_get_handle(name, dim, MB_TYPE_DOUBLE, tag,
4635 MB_TAG_CREAT | MB_TAG_SPARSE, def_val),
4639 tags_to_transfer.push_back(
get_tag(
"MaterialForce", 3));
4643 auto get_crack_tag = [&]() {
4645 rval = mField.get_moab().tag_get_handle(
"CRACK",
th);
4646 if (
rval == MB_SUCCESS) {
4649 int def_val[] = {0};
4651 "CRACK", 1, MB_TYPE_INTEGER,
th, MB_TAG_SPARSE | MB_TAG_CREAT,
4656 Tag th = get_crack_tag();
4657 tags_to_transfer.push_back(
th);
4661 mark_faces.merge(*crackFaces);
4663 mark_faces.merge(*interfaceFaces);
4664 CHKERR mField.get_moab().tag_clear_data(
th, mark_faces, mark);
4668 for (
auto t : listTagsToTransfer) {
4670 CHKERR mField.get_moab().tag_get_name(
t, name);
4672 <<
"Adding tag " << name <<
" to transfer list for post-processing";
4673 tags_to_transfer.push_back(
t);
4683 auto get_post_proc = [&](
auto &post_proc_mesh,
auto sense) {
4685 auto post_proc_ptr =
4686 boost::make_shared<PostProcBrokenMeshInMoabBaseCont<FaceEle>>(
4687 mField, post_proc_mesh);
4688 EshelbianPlasticity::AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
4689 post_proc_ptr->getOpPtrVector(), {L2}, materialH1Positions,
4692 if (ts != PETSC_NULLPTR) {
4694 CHKERR TSGetTime(ts, &(post_proc_ptr->ts_t));
4695 CHKERR TSGetTimeStep(ts, &(post_proc_ptr->ts_dt));
4698 auto domain_ops = [&](
auto &fe,
int sense) {
4701 auto bubble_cache = boost::make_shared<CGGUserPolynomialBase::CachePhi>(
4703 fe.getUserPolynomialBase() = boost::shared_ptr<BaseFunction>(
4705 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
4706 fe.getOpPtrVector(), {HDIV, H1, L2}, materialH1Positions,
4708 auto piola_scale_ptr = boost::make_shared<double>(1.0);
4710 piolaStress, dataAtPts->getApproxPAtPts(), piola_scale_ptr));
4712 bubbleField, dataAtPts->getApproxPAtPts(), piola_scale_ptr,
4714 if (stretchHandling == NO_STREACH) {
4715 fe.getOpPtrVector().push_back(
4716 physicalEquations->returnOpCalculateStretchFromStress(
4717 dataAtPts, physicalEquations));
4719 fe.getOpPtrVector().push_back(
4721 stretchTensor, dataAtPts->getLogStretchTensorAtPts(), MBTET));
4725 piolaStress, dataAtPts->getVarPiolaPts(),
4726 boost::make_shared<double>(1), v_v));
4728 bubbleField, dataAtPts->getVarPiolaPts(),
4729 boost::make_shared<double>(1), v_v, MBMAXTYPE));
4731 rotAxis, dataAtPts->getVarRotAxisPts(), v_v, MBTET));
4732 if (stretchHandling == NO_STREACH) {
4733 fe.getOpPtrVector().push_back(
4734 physicalEquations->returnOpCalculateVarStretchFromStress(
4735 dataAtPts, physicalEquations));
4737 fe.getOpPtrVector().push_back(
4739 stretchTensor, dataAtPts->getVarLogStreachPts(), v_v, MBTET));
4744 materialH1Positions, dataAtPts->getGradientAtPts(),
g));
4748 rotAxis, dataAtPts->getRotAxisAtPts(), MBTET));
4750 rotAxis, dataAtPts->getRotAxis0AtPts(), solTSStep, MBTET));
4753 spatialL2Disp, dataAtPts->getSmallWL2AtPts(), MBTET));
4755 spatialH1Disp, dataAtPts->getSmallWH1AtPts()));
4757 spatialH1Disp, dataAtPts->getSmallWGradH1AtPts()));
4759 fe.getOpPtrVector().push_back(
4763 fe.getOpPtrVector().push_back(physicalEquations->returnOpJacobian(
4764 true,
false, dataAtPts, physicalEquations));
4766 physicalEquations->returnOpCalculateEnergy(dataAtPts,
nullptr)) {
4767 fe.getOpPtrVector().push_back(op);
4776 struct OpSidePPMap :
public OpPPMap {
4777 OpSidePPMap(moab::Interface &post_proc_mesh,
4778 std::vector<EntityHandle> &map_gauss_pts,
4779 DataMapVec data_map_scalar, DataMapMat data_map_vec,
4780 DataMapMat data_map_mat, DataMapMat data_symm_map_mat,
4782 :
OpPPMap(post_proc_mesh, map_gauss_pts, data_map_scalar,
4783 data_map_vec, data_map_mat, data_symm_map_mat),
4790 if (tagSense != 0) {
4791 if (tagSense != OpPPMap::getSkeletonSense())
4804 vec_fields[
"SpatialDisplacementL2"] = dataAtPts->getSmallWL2AtPts();
4805 vec_fields[
"SpatialDisplacementH1"] = dataAtPts->getSmallWH1AtPts();
4806 vec_fields[
"Omega"] = dataAtPts->getRotAxisAtPts();
4807 vec_fields[
"AngularMomentum"] = dataAtPts->getLeviKirchhoffAtPts();
4808 vec_fields[
"X"] = dataAtPts->getLargeXH1AtPts();
4809 if (stretchHandling != NO_STREACH) {
4810 vec_fields[
"EiegnLogStreach"] = dataAtPts->getEigenVals();
4813 vec_fields[
"VarOmega"] = dataAtPts->getVarRotAxisPts();
4814 vec_fields[
"VarSpatialDisplacementL2"] =
4815 boost::make_shared<MatrixDouble>();
4817 spatialL2Disp, vec_fields[
"VarSpatialDisplacementL2"], v_v, MBTET));
4820 vec_fields[
"ResSpatialDisplacementL2"] =
4821 boost::make_shared<MatrixDouble>();
4823 spatialL2Disp, vec_fields[
"ResSpatialDisplacementL2"], f_r, MBTET));
4824 vec_fields[
"ResOmega"] = boost::make_shared<MatrixDouble>();
4826 rotAxis, vec_fields[
"ResOmega"], f_r, MBTET));
4829 vec_fields[
"Gradient"] = dataAtPts->getGradientAtPts();
4833 mat_fields[
"PiolaStress"] = dataAtPts->getApproxPAtPts();
4835 mat_fields[
"VarPiolaStress"] = dataAtPts->getVarPiolaPts();
4838 mat_fields[
"ResPiolaStress"] = boost::make_shared<MatrixDouble>();
4840 piolaStress, mat_fields[
"ResPiolaStress"],
4841 boost::make_shared<double>(1), f_r));
4843 bubbleField, mat_fields[
"ResPiolaStress"],
4844 boost::make_shared<double>(1), f_r, MBMAXTYPE));
4846 if (!internalStressTagName.empty()) {
4847 mat_fields[internalStressTagName] = dataAtPts->getInternalStressAtPts();
4848 switch (meshTransferInterpOrder) {
4850 fe.getOpPtrVector().push_back(
4854 fe.getOpPtrVector().push_back(
4859 "Unsupported mesh transfer interpolation order %d, for "
4861 meshTransferInterpOrder);
4866 mat_fields_symm[
"LogSpatialStretch"] =
4867 dataAtPts->getLogStretchTensorAtPts();
4868 mat_fields_symm[
"SpatialStretch"] = dataAtPts->getStretchTensorAtPts();
4870 mat_fields_symm[
"VarLogSpatialStretch"] =
4871 dataAtPts->getVarLogStreachPts();
4874 if (stretchHandling != NO_STREACH) {
4875 mat_fields_symm[
"ResLogSpatialStretch"] =
4876 boost::make_shared<MatrixDouble>();
4877 fe.getOpPtrVector().push_back(
4879 stretchTensor, mat_fields_symm[
"ResLogSpatialStretch"], f_r,
4884 fe.getOpPtrVector().push_back(
4888 post_proc_ptr->getPostProcMesh(), post_proc_ptr->getMapGaussPts(),
4905 post_proc_ptr->getPostProcMesh(), post_proc_ptr->getMapGaussPts(),
4911 auto X_h1_ptr = boost::make_shared<MatrixDouble>();
4913 post_proc_ptr->getOpPtrVector().push_back(
4915 dataAtPts->getLargeXH1AtPts()));
4920 domain_ops(*(op_loop_side->getSideFEPtr()), sense);
4921 post_proc_ptr->getOpPtrVector().push_back(op_loop_side);
4923 return post_proc_ptr;
4927 auto calcs_side_traction_and_displacements = [&](
auto &post_proc_ptr,
4933 using SideEleOp = EleOnSide::UserDataOperator;
4935 mField, elementVolumeName,
SPACE_DIM, Sev::noisy);
4936 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
4937 boost::shared_ptr<BaseFunction>(
4939 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
4940 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
4941 materialH1Positions, frontAdjEdges);
4942 auto traction_ptr = boost::make_shared<MatrixDouble>();
4943 op_loop_domain_side->getOpPtrVector().push_back(
4945 piolaStress, traction_ptr, boost::make_shared<double>(1.0)));
4948 contactDisp, dataAtPts->getContactL2AtPts()));
4949 pip.push_back(op_loop_domain_side);
4951 auto u_h1_ptr = boost::make_shared<MatrixDouble>();
4954 *
this, contactTreeRhs, u_h1_ptr, traction_ptr,
4956 &post_proc_ptr->getPostProcMesh(), &post_proc_ptr->getMapGaussPts()));
4962 pip.push_back(op_this);
4964 op_this->getOpPtrVector().push_back(
4968 post_proc_ptr->getPostProcMesh(), post_proc_ptr->getMapGaussPts(),
4972 {{
"ContactDisplacement", dataAtPts->getContactL2AtPts()}},
4984 auto contact_residual = boost::make_shared<MatrixDouble>();
4985 op_this->getOpPtrVector().push_back(
4987 contactDisp, contact_residual, f_r, MBTET));
4988 op_this->getOpPtrVector().push_back(
4992 post_proc_ptr->getPostProcMesh(), post_proc_ptr->getMapGaussPts(),
4996 {{
"res_contact", contact_residual}},
5010 auto post_proc_mesh = boost::make_shared<moab::Core>();
5011 auto post_proc_ptr = get_post_proc(post_proc_mesh, 1);
5012 auto post_proc_negative_sense_ptr =
5013 get_post_proc(post_proc_mesh, -1);
5014 auto skin_post_proc_ptr = get_post_proc(post_proc_mesh, 1);
5015 CHKERR calcs_side_traction_and_displacements(
5016 skin_post_proc_ptr, skin_post_proc_ptr->getOpPtrVector());
5022 CHKERR mField.get_moab().get_adjacencies(own_tets,
SPACE_DIM - 1,
true,
5023 own_faces, moab::Interface::UNION);
5025 auto get_crack_faces = [&](
auto crack_faces) {
5026 auto get_adj = [&](
auto e,
auto dim) {
5028 CHKERR mField.get_moab().get_adjacencies(e, dim,
true, adj,
5029 moab::Interface::UNION);
5033 auto tets = get_adj(crack_faces, 3);
5035 auto faces = subtract(get_adj(tets, 2), crack_faces);
5037 tets = subtract(tets, get_adj(faces, 3));
5038 return subtract(crack_faces, get_adj(tets, 2));
5041 auto side_one_faces = [&](
auto &faces) {
5042 std::pair<Range, Range> sides;
5043 for (
auto f : faces) {
5045 MOAB_THROW(mField.get_moab().get_adjacencies(&f, 1, 3,
false, adj));
5046 adj = intersect(own_tets, adj);
5047 for (
auto t : adj) {
5048 int side, sense, offset;
5049 MOAB_THROW(mField.get_moab().side_number(
t, f, side, sense, offset));
5051 sides.first.insert(f);
5053 sides.second.insert(f);
5060 auto get_interface_from_block = [&](
auto block_name) {
5064 CHKERR mField.get_moab().get_adjacencies(vol_eles,
SPACE_DIM - 1,
true,
5065 faces, moab::Interface::UNION);
5066 faces = subtract(faces, skin);
5070 auto crack_faces = unite(get_crack_faces(*crackFaces), *interfaceFaces);
5073 auto crack_side_faces = side_one_faces(crack_faces);
5074 auto side_one_crack_faces = [crack_side_faces](
FEMethod *fe_method_ptr) {
5075 auto ent = fe_method_ptr->getFEEntityHandle();
5076 if (crack_side_faces.first.find(ent) == crack_side_faces.first.end()) {
5081 auto side_minus_crack_faces = [crack_side_faces](
FEMethod *fe_method_ptr) {
5082 auto ent = fe_method_ptr->getFEEntityHandle();
5083 if (crack_side_faces.second.find(ent) == crack_side_faces.second.end()) {
5089 skin_post_proc_ptr->setTagsToTransfer(tags_to_transfer);
5090 post_proc_ptr->setTagsToTransfer(tags_to_transfer);
5091 post_proc_negative_sense_ptr->setTagsToTransfer(tags_to_transfer);
5093 auto post_proc_begin =
5097 post_proc_ptr->exeTestHook = side_one_crack_faces;
5099 dM, skeletonElement, post_proc_ptr, 0, mField.get_comm_size());
5100 post_proc_negative_sense_ptr->exeTestHook = side_minus_crack_faces;
5102 post_proc_negative_sense_ptr, 0,
5103 mField.get_comm_size());
5105 constexpr bool debug =
false;
5108 auto get_adj_front = [&]() {
5109 auto skeleton_faces = *skeletonFaces;
5111 CHKERR mField.get_moab().get_adjacencies(*frontEdges, 2,
true, adj_front,
5112 moab::Interface::UNION);
5114 adj_front = intersect(adj_front, skeleton_faces);
5115 adj_front = subtract(adj_front, *crackFaces);
5116 adj_front = intersect(own_faces, adj_front);
5121 auto only_front_faces = [adj_front](
FEMethod *fe_method_ptr) {
5122 auto ent = fe_method_ptr->getFEEntityHandle();
5123 if (adj_front.find(ent) == adj_front.end()) {
5129 post_proc_ptr->exeTestHook = only_front_faces;
5131 dM, skeletonElement, post_proc_ptr, 0, mField.get_comm_size());
5132 post_proc_negative_sense_ptr->exeTestHook = only_front_faces;
5134 post_proc_negative_sense_ptr, 0,
5135 mField.get_comm_size());
5140 CHKERR post_proc_end.writeFile(
file.c_str());
5147 std::vector<Tag> tags_to_transfer) {
5151 if (f_residual != PETSC_NULLPTR) {
5157 CHKERR VecScatterBegin(scatter, f_residual, f_r, INSERT_VALUES,
5159 CHKERR VecScatterEnd(scatter, f_residual, f_r, INSERT_VALUES,
5165 auto post_proc_mesh = boost::make_shared<moab::Core>();
5166 auto post_proc_ptr =
5167 boost::make_shared<PostProcBrokenMeshInMoabBaseCont<FaceEle>>(
5169 EshelbianPlasticity::AddHOOps<SPACE_DIM - 1, SPACE_DIM - 1, SPACE_DIM>::add(
5173 auto hybrid_disp = boost::make_shared<MatrixDouble>();
5174 post_proc_ptr->getOpPtrVector().push_back(
5176 post_proc_ptr->getOpPtrVector().push_back(
5180 auto op_loop_domain_side =
5183 post_proc_ptr->getOpPtrVector().push_back(op_loop_domain_side);
5186 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
5187 boost::make_shared<CGGUserPolynomialBase>(
nullptr,
true);
5188 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
5189 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
5191 op_loop_domain_side->getOpPtrVector().push_back(
5194 op_loop_domain_side->getOpPtrVector().push_back(
5197 op_loop_domain_side->getOpPtrVector().push_back(
5202 op_loop_domain_side->getOpPtrVector().push_back(
5206 op_loop_domain_side->getOpPtrVector().push_back(
5214 vec_fields[
"HybridDisplacement"] = hybrid_disp;
5216 vec_fields[
"spatialL2Disp"] =
dataAtPts->getSmallWL2AtPts();
5217 vec_fields[
"Omega"] =
dataAtPts->getRotAxisAtPts();
5219 mat_fields[
"PiolaStress"] =
dataAtPts->getApproxPAtPts();
5220 mat_fields[
"HybridDisplacementGradient"] =
5223 mat_fields_symm[
"LogSpatialStretch"] =
dataAtPts->getLogStretchTensorAtPts();
5225 post_proc_ptr->getOpPtrVector().push_back(
5229 post_proc_ptr->getPostProcMesh(), post_proc_ptr->getMapGaussPts(),
5244 auto hybrid_res = boost::make_shared<MatrixDouble>();
5245 post_proc_ptr->getOpPtrVector().push_back(
5249 post_proc_ptr->getOpPtrVector().push_back(
5253 post_proc_ptr->getPostProcMesh(), post_proc_ptr->getMapGaussPts(),
5257 {{
"res_hybrid", hybrid_res}},
5268 post_proc_ptr->setTagsToTransfer(tags_to_transfer);
5270 auto post_proc_begin =
5277 CHKERR post_proc_end.writeFile(file.c_str());
5286 auto post_proc_norm_fe =
5287 boost::make_shared<VolumeElementForcesAndSourcesCore>(
mField);
5290 boost::make_shared<CGGUserPolynomialBase::CachePhi>(0, 0,
MatrixDouble());
5291 post_proc_norm_fe->getUserPolynomialBase() =
5293 post_proc_norm_fe->getRuleHook = [](int, int, int) {
return -1; };
5294 post_proc_norm_fe->setRuleHook = SetIntegrationAtFrontVolume(
5296 CHKERR EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
5300 enum NORMS { U_NORM_L2 = 0, U_NORM_H1, PIOLA_NORM, U_ERROR_L2, LAST_NORM };
5303 CHKERR VecZeroEntries(norms_vec);
5305 auto u_l2_ptr = boost::make_shared<MatrixDouble>();
5306 auto u_h1_ptr = boost::make_shared<MatrixDouble>();
5307 post_proc_norm_fe->getOpPtrVector().push_back(
5309 post_proc_norm_fe->getOpPtrVector().push_back(
5311 post_proc_norm_fe->getOpPtrVector().push_back(
5313 post_proc_norm_fe->getOpPtrVector().push_back(
5315 post_proc_norm_fe->getOpPtrVector().push_back(
5319 auto piola_ptr = boost::make_shared<MatrixDouble>();
5320 post_proc_norm_fe->getOpPtrVector().push_back(
5322 post_proc_norm_fe->getOpPtrVector().push_back(
5326 post_proc_norm_fe->getOpPtrVector().push_back(
5329 TetPolynomialBase::switchCacheBaseOn<HDIV>({post_proc_norm_fe.get()});
5331 *post_proc_norm_fe);
5332 TetPolynomialBase::switchCacheBaseOff<HDIV>({post_proc_norm_fe.get()});
5334 CHKERR VecAssemblyBegin(norms_vec);
5335 CHKERR VecAssemblyEnd(norms_vec);
5336 const double *norms;
5337 CHKERR VecGetArrayRead(norms_vec, &norms);
5338 MOFEM_LOG(
"EP", Sev::inform) <<
"norm_u: " << std::sqrt(norms[U_NORM_L2]);
5339 MOFEM_LOG(
"EP", Sev::inform) <<
"norm_u_h1: " << std::sqrt(norms[U_NORM_H1]);
5341 <<
"norm_error_u_l2: " << std::sqrt(norms[U_ERROR_L2]);
5343 <<
"norm_piola: " << std::sqrt(norms[PIOLA_NORM]);
5344 CHKERR VecRestoreArrayRead(norms_vec, &norms);
5358 for (
auto bc : bc_mng->getBcMapByBlockName()) {
5359 if (
auto disp_bc = bc.second->dispBcPtr) {
5364 <<
"Field name: " <<
field_name <<
" Block name: " << block_name;
5365 MOFEM_LOG(
"EP", Sev::noisy) <<
"Displacement BC: " << *disp_bc;
5367 std::vector<double> block_attributes(6, 0.);
5368 if (disp_bc->data.flag1 == 1) {
5369 block_attributes[0] = disp_bc->data.value1;
5370 block_attributes[3] = 1;
5372 if (disp_bc->data.flag2 == 1) {
5373 block_attributes[1] = disp_bc->data.value2;
5374 block_attributes[4] = 1;
5376 if (disp_bc->data.flag3 == 1) {
5377 block_attributes[2] = disp_bc->data.value3;
5378 block_attributes[5] = 1;
5380 auto faces = bc.second->bcEnts.subset_by_dimension(2);
5388 boost::make_shared<NormalDisplacementBcVec>();
5389 for (
auto bc : bc_mng->getBcMapByBlockName()) {
5390 auto block_name =
"(.*)NORMAL_DISPLACEMENT(.*)";
5391 std::regex reg_name(block_name);
5392 if (std::regex_match(bc.first, reg_name)) {
5396 <<
"Field name: " <<
field_name <<
" Block name: " << block_name;
5398 block_name, bc.second->bcAttributes,
5399 bc.second->bcEnts.subset_by_dimension(2));
5404 boost::make_shared<AnalyticalDisplacementBcVec>();
5406 for (
auto bc : bc_mng->getBcMapByBlockName()) {
5407 auto block_name =
"(.*)ANALYTICAL_DISPLACEMENT(.*)";
5408 std::regex reg_name(block_name);
5409 if (std::regex_match(bc.first, reg_name)) {
5413 <<
"Field name: " <<
field_name <<
" Block name: " << block_name;
5415 block_name, bc.second->bcAttributes,
5416 bc.second->bcEnts.subset_by_dimension(2));
5420 auto ts_displacement =
5421 boost::make_shared<DynamicRelaxationTimeScale>(
"disp_history.txt");
5424 <<
"Add time scaling displacement BC: " << bc.blockName;
5427 ts_displacement,
"disp_history",
".txt", bc.blockName);
5430 auto ts_normal_displacement =
5431 boost::make_shared<DynamicRelaxationTimeScale>(
"normal_disp_history.txt");
5434 <<
"Add time scaling normal displacement BC: " << bc.blockName;
5437 ts_normal_displacement,
"normal_disp_history",
".txt",
5453 for (
auto bc : bc_mng->getBcMapByBlockName()) {
5454 if (
auto force_bc = bc.second->forceBcPtr) {
5459 <<
"Field name: " <<
field_name <<
" Block name: " << block_name;
5460 MOFEM_LOG(
"EP", Sev::noisy) <<
"Force BC: " << *force_bc;
5462 std::vector<double> block_attributes(6, 0.);
5463 block_attributes[0] = -force_bc->data.value3 * force_bc->data.value1;
5464 block_attributes[3] = 1;
5465 block_attributes[1] = -force_bc->data.value4 * force_bc->data.value1;
5466 block_attributes[4] = 1;
5467 block_attributes[2] = -force_bc->data.value5 * force_bc->data.value1;
5468 block_attributes[5] = 1;
5469 auto faces = bc.second->bcEnts.subset_by_dimension(2);
5477 for (
auto bc : bc_mng->getBcMapByBlockName()) {
5478 auto block_name =
"(.*)PRESSURE(.*)";
5479 std::regex reg_name(block_name);
5480 if (std::regex_match(bc.first, reg_name)) {
5485 <<
"Field name: " <<
field_name <<
" Block name: " << block_name;
5487 block_name, bc.second->bcAttributes,
5488 bc.second->bcEnts.subset_by_dimension(2));
5493 boost::make_shared<AnalyticalTractionBcVec>();
5495 for (
auto bc : bc_mng->getBcMapByBlockName()) {
5496 auto block_name =
"(.*)ANALYTICAL_TRACTION(.*)";
5497 std::regex reg_name(block_name);
5498 if (std::regex_match(bc.first, reg_name)) {
5502 <<
"Field name: " <<
field_name <<
" Block name: " << block_name;
5504 block_name, bc.second->bcAttributes,
5505 bc.second->bcEnts.subset_by_dimension(2));
5510 boost::make_shared<DynamicRelaxationTimeScale>(
"traction_history.txt");
5514 ts_traction,
"traction_history",
".txt", bc.blockName);
5518 boost::make_shared<DynamicRelaxationTimeScale>(
"pressure_history.txt");
5522 ts_pressure,
"pressure_history",
".txt", bc.blockName);
5532 &ext_strain_vec_ptr,
5533 const std::string block_name,
5534 const int nb_attributes) {
5537 std::regex((boost::format(
"(.*)%s(.*)") % block_name).str()))) {
5538 std::vector<double> block_attributes;
5539 CHKERR it->getAttributes(block_attributes);
5540 if (block_attributes.size() < nb_attributes) {
5542 "In block %s expected %d attributes, but given %ld",
5543 it->getName().c_str(), nb_attributes, block_attributes.size());
5546 auto get_block_ents = [&]() {
5552 auto Ents = get_block_ents();
5553 ext_strain_vec_ptr->emplace_back(it->getName(), block_attributes,
5563 auto ts_pre_stretch = boost::make_shared<DynamicRelaxationTimeScale>(
5564 "externalstrain_history.txt");
5567 <<
"Add time scaling external strain: " << ext_strain_block.blockName;
5570 ts_pre_stretch,
"externalstrain_history",
".txt",
5571 ext_strain_block.blockName);
5580 auto print_loc_size = [
this](
auto v,
auto str,
auto sev) {
5583 CHKERR VecGetLocalSize(
v.second, &size);
5585 CHKERR VecGetOwnershipRange(
v.second, &low, &high);
5586 MOFEM_LOG(
"EPSYNC", sev) << str <<
" local size " << size <<
" ( " << low
5587 <<
" " << high <<
" ) ";
5610 double start_time) {
5613 auto storage = solve_elastic_setup::setup(
this, ts, x,
false);
5615 auto cohesive_tao_ctx = createCohesiveTAOCtx(
5620 PetscOptionsBegin(PETSC_COMM_WORLD,
"",
"Dynamic Relaxation Options",
"none");
5622 CHKERR PetscOptionsScalar(
"-dynamic_final_time",
5623 "dynamic relaxation final time",
"",
5625 CHKERR PetscOptionsScalar(
"-dynamic_delta_time",
5626 "dynamic relaxation final time",
"",
physicalDt,
5628 CHKERR PetscOptionsInt(
"-dynamic_max_it",
"dynamic relaxation iterations",
"",
5630 CHKERR PetscOptionsBool(
"-dynamic_h1_update",
"update each ts step",
"",
5637 <<
"Dynamic relaxation final time -dynamic_final_time = "
5640 <<
"Dynamic relaxation delta time -dynamic_delta_time = "
5643 <<
"Dynamic relaxation max iterations -dynamic_max_it = " <<
physicalMaxSteps;
5645 <<
"Dynamic relaxation H1 update each step -dynamic_h1_update = "
5648 CHKERR initializeCohesiveKappaField(*
this);
5651 auto setup_ts_monitor = [&]() {
5652 auto monitor_ptr = boost::make_shared<EshelbianMonitor>(*
this);
5655 auto monitor_ptr = setup_ts_monitor();
5657 TetPolynomialBase::switchCacheBaseOn<HDIV>(
5660 CHKERR TSElasticPostStep::postStepInitialise(
this);
5662 double ts_delta_time;
5663 CHKERR TSGetTimeStep(ts, &ts_delta_time);
5666 CHKERR TSSetPreStep(ts, TSElasticPostStep::preStepFun);
5667 CHKERR TSSetPostStep(ts, TSElasticPostStep::postStepFun);
5671 CHKERR TaoSetType(tao, TAOLMVM);
5672 auto g = cohesive_tao_ctx->duplicateGradientVec();
5674 cohesiveEvaluateObjectiveAndGradient,
5675 (
void *)cohesive_tao_ctx.get());
5679 monitor_ptr->ts = PETSC_NULLPTR;
5680 monitor_ptr->ts_u = PETSC_NULLPTR;
5685 auto tao_sol0 = cohesive_tao_ctx->duplicateKappaVec();
5686 int tao_sol_size, tao_sol_loc_size;
5687 CHKERR VecGetSize(tao_sol0, &tao_sol_size);
5688 CHKERR VecGetLocalSize(tao_sol0, &tao_sol_loc_size);
5690 <<
"Cohesive crack growth initial kappa vector size " << tao_sol_size
5691 <<
" local size " << tao_sol_loc_size <<
" number of interface faces "
5694 CHKERR TaoSetFromOptions(tao);
5699 CHKERR VecSet(xu, PETSC_INFINITY);
5700 CHKERR TaoSetVariableBounds(tao, xl, xu);
5704 "physicalDt must be positive, got %g",
physicalDt);
5711 CHKERR VecZeroEntries(tao_sol0);
5712 CHKERR VecGhostUpdateBegin(tao_sol0, INSERT_VALUES, SCATTER_FORWARD);
5713 CHKERR VecGhostUpdateEnd(tao_sol0, INSERT_VALUES, SCATTER_FORWARD);
5714 CHKERR TaoSetSolution(tao, tao_sol0);
5717 CHKERR TSElasticPostStep::preStepFun(ts);
5722 CHKERR TaoGetSolution(tao, &tao_sol);
5725 auto &kappa_vec = cohesive_tao_ctx->getKappaVec();
5728 CHKERR VecAXPY(kappa_vec.second, 1.0, tao_sol);
5729 CHKERR VecGhostUpdateBegin(kappa_vec.second, INSERT_VALUES,
5731 CHKERR VecGhostUpdateEnd(kappa_vec.second, INSERT_VALUES, SCATTER_FORWARD);
5737 CHKERR VecGhostUpdateBegin(x, INSERT_VALUES, SCATTER_FORWARD);
5738 CHKERR VecGhostUpdateEnd(x, INSERT_VALUES, SCATTER_FORWARD);
5739 monitor_ptr->ts = PETSC_NULLPTR;
5740 monitor_ptr->ts_u = x;
5746 CHKERR TSElasticPostStep::postStepFun(ts);
5753 const double remainingPhysicalTime =
5762 CHKERR TSElasticPostStep::postStepDestroy();
5763 TetPolynomialBase::switchCacheBaseOff<HDIV>(
5770 double start_time) {
5775 auto storage = solve_elastic_setup::setup(
this, ts, x,
false);
5779 auto setup_ts_monitor = [&]() {
5780 auto monitor_ptr = boost::make_shared<EshelbianMonitor>(*
this);
5783 auto monitor_ptr = setup_ts_monitor();
5785 auto test_monitor_ptr =
5786 boost::make_shared<EshelbianTestingMonitor>(*
this, monitor_ptr);
5788 TetPolynomialBase::switchCacheBaseOn<HDIV>(
5791 CHKERR TSElasticPostStep::postStepInitialise(
this);
5793 double ts_delta_time;
5794 CHKERR TSGetTimeStep(ts, &ts_delta_time);
5797 CHKERR TSSetPreStep(ts, TSElasticPostStep::preStepFun);
5798 CHKERR TSSetPostStep(ts, TSElasticPostStep::postStepFun);
5801 CHKERR TSElasticPostStep::preStepFun(ts);
5802 CHKERR TSElasticPostStep::postStepFun(ts);
5804 double load_factor_change_clip = 0.1;
5806 PetscOptionsBegin(PETSC_COMM_WORLD,
"",
"Load Factor Options",
"none");
5808 CHKERR PetscOptionsScalar(
"-initial_load_factor",
"Initial load factor",
"",
5810 CHKERR PetscOptionsScalar(
"-max_crack_ext_area",
5811 "Maximum crack extension area",
"",
5814 CHKERR PetscOptionsScalar(
"-clip_load_factor_percent",
5815 "Upper bound for load factor change",
"",
5816 load_factor_change_clip,
5817 &load_factor_change_clip, PETSC_NULLPTR);
5822 monitor_ptr->ts = ts;
5823 monitor_ptr->ts_u = PETSC_NULLPTR;
5828 PetscBool test_cook_flg = PETSC_FALSE;
5835 test_monitor_ptr->ts = ts;
5836 test_monitor_ptr->ts_u = PETSC_NULLPTR;
5859 CHKERR TSSetStepNumber(ts, 0);
5861 CHKERR TSSetTimeStep(ts, ts_delta_time);
5863 CHKERR TSElasticPostStep::preStepFun(ts);
5865 CHKERR TSSetSolution(ts, x);
5866 CHKERR TSSolve(ts, PETSC_NULLPTR);
5869 CHKERR TSElasticPostStep::postStepFun(ts);
5874 CHKERR VecGhostUpdateBegin(x, INSERT_VALUES, SCATTER_FORWARD);
5875 CHKERR VecGhostUpdateEnd(x, INSERT_VALUES, SCATTER_FORWARD);
5877 monitor_ptr->ts = ts;
5878 monitor_ptr->ts_u = x;
5884 test_monitor_ptr->ts = ts;
5885 test_monitor_ptr->ts_u = x;
5894 const bool has_crack_extension = delta_area > 0.0;
5896 if (has_crack_extension) {
5899 const double updated_load_factor =
5901 loadFactor = std::max(updated_load_factor, 1.0e-6);
5906 const double initial_step_range = 5;
5907 const double min_load_factor = 1.0e-6;
5908 const double max_load_factor =
5914 <<
"Allowable range for load factor [" << min_load_factor <<
", "
5915 << max_load_factor <<
"]";
5918 const double previous_load_factor = is_first_step ? 0. :
oldLoadFactor;
5922 <<
"Setting new load factor to: " <<
loadFactor;
5925 CHKERR MPI_Bcast(load_control_data, 2, MPI_DOUBLE, 0, MPI_COMM_WORLD);
5933 const double remainingPhysicalTime =
5942 CHKERR TSElasticPostStep::postStepDestroy();
5943 TetPolynomialBase::switchCacheBaseOff<HDIV>(
5952 double start_time) {
5955 auto storage = solve_elastic_setup::setup(
this, ts, x,
false);
5957 auto topological_tao_ctx = createTopologicalTAOCtx(
5962 double final_time = 1;
5963 double delta_time = 0.1;
5965 PetscBool ts_h1_update = PETSC_FALSE;
5967 PetscOptionsBegin(PETSC_COMM_WORLD,
"",
"Dynamic Relaxation Options",
"none");
5969 CHKERR PetscOptionsScalar(
"-dynamic_final_time",
5970 "dynamic relaxation final time",
"", final_time,
5971 &final_time, PETSC_NULLPTR);
5972 CHKERR PetscOptionsScalar(
"-dynamic_delta_time",
5973 "dynamic relaxation final time",
"", delta_time,
5974 &delta_time, PETSC_NULLPTR);
5975 CHKERR PetscOptionsInt(
"-dynamic_max_it",
"dynamic relaxation iterations",
"",
5976 max_it, &max_it, PETSC_NULLPTR);
5977 CHKERR PetscOptionsBool(
"-dynamic_h1_update",
"update each ts step",
"",
5978 ts_h1_update, &ts_h1_update, PETSC_NULLPTR);
5984 <<
"Dynamic relaxation final time -dynamic_final_time = " << final_time;
5986 <<
"Dynamic relaxation delta time -dynamic_delta_time = " << delta_time;
5988 <<
"Dynamic relaxation max iterations -dynamic_max_it = " << max_it;
5990 <<
"Dynamic relaxation H1 update each step -dynamic_h1_update = "
5991 << (ts_h1_update ?
"TRUE" :
"FALSE");
5995 auto setup_ts_monitor = [&]() {
5996 auto monitor_ptr = boost::make_shared<EshelbianMonitor>(*
this);
5999 auto monitor_ptr = setup_ts_monitor();
6001 TetPolynomialBase::switchCacheBaseOn<HDIV>(
6004 CHKERR TSElasticPostStep::postStepInitialise(
this);
6006 double ts_delta_time;
6007 CHKERR TSGetTimeStep(ts, &ts_delta_time);
6010 CHKERR TSSetPreStep(ts, TSElasticPostStep::preStepFun);
6011 CHKERR TSSetPostStep(ts, TSElasticPostStep::postStepFun);
6014 CHKERR TSElasticPostStep::preStepFun(ts);
6015 CHKERR TSElasticPostStep::postStepFun(ts);
6018 CHKERR TaoSetType(tao, TAOLMVM);
6021 topologicalEvaluateObjectiveAndGradient,
6022 (
void *)topological_tao_ctx.get());
6026 monitor_ptr->ts = PETSC_NULLPTR;
6027 monitor_ptr->ts_u = PETSC_NULLPTR;
6035 CHKERR VecGhostUpdateBegin(tao_sol0, INSERT_VALUES, SCATTER_FORWARD);
6036 CHKERR VecGhostUpdateEnd(tao_sol0, INSERT_VALUES, SCATTER_FORWARD);
6038 int tao_sol_size, tao_sol_loc_size;
6039 CHKERR VecGetSize(tao_sol0, &tao_sol_size);
6040 CHKERR VecGetLocalSize(tao_sol0, &tao_sol_loc_size);
6042 <<
"Toplogical data vector size " << tao_sol_size <<
" local size "
6043 << tao_sol_loc_size <<
" number of interface faces "
6046 CHKERR TaoSetFromOptions(tao);
6048 if (delta_time <= 0.) {
6050 "delta_time must be positive, got %g", delta_time);
6055 <<
" delta time " << delta_time;
6057 CHKERR VecZeroEntries(tao_sol0);
6058 CHKERR VecGhostUpdateBegin(tao_sol0, INSERT_VALUES, SCATTER_FORWARD);
6059 CHKERR VecGhostUpdateEnd(tao_sol0, INSERT_VALUES, SCATTER_FORWARD);
6060 CHKERR TaoSetSolution(tao, tao_sol0);
6063 CHKERR TaoGetSolution(tao, &tao_sol);
6079 CHKERR VecGhostUpdateBegin(x, INSERT_VALUES, SCATTER_FORWARD);
6080 CHKERR VecGhostUpdateEnd(x, INSERT_VALUES, SCATTER_FORWARD);
6081 monitor_ptr->ts = PETSC_NULLPTR;
6082 monitor_ptr->ts_u = x;
6092 if (delta_time >= remainingPhysicalTime) {
6099 CHKERR TSElasticPostStep::postStepDestroy();
6100 TetPolynomialBase::switchCacheBaseOff<HDIV>(
6108 double start_time) {
6111 auto storage = solve_elastic_setup::setup(
this, ts, x,
false);
6113 auto topological_tao_ctx = createTopologicalTAOCtx(
6121 auto monitor_ptr = boost::make_shared<EshelbianMonitor>(*
this);
6123 TetPolynomialBase::switchCacheBaseOn<HDIV>(
6126 CHKERR TSElasticPostStep::postStepInitialise(
this);
6128 double ts_delta_time;
6129 CHKERR TSGetTimeStep(ts, &ts_delta_time);
6132 CHKERR TSSetPreStep(ts, TSElasticPostStep::preStepFun);
6133 CHKERR TSSetPostStep(ts, TSElasticPostStep::postStepFun);
6136 CHKERR TSElasticPostStep::preStepFun(ts);
6137 CHKERR TSElasticPostStep::postStepFun(ts);
6139 const bool restart_run =
6141 std::abs(start_time) > std::numeric_limits<double>::epsilon();
6144 std::abs(test_time) < std::numeric_limits<double>::epsilon()) {
6146 "Set non-zero -physical_final_time for test_topological_derivative");
6151 monitor_ptr->ts = PETSC_NULLPTR;
6152 monitor_ptr->ts_u = PETSC_NULLPTR;
6158 <<
"Solving load step before topological derivative test: "
6160 <<
" TS delta time " << ts_delta_time;
6162 CHKERR TSSetStepNumber(ts, 0);
6164 CHKERR TSSetTimeStep(ts, ts_delta_time);
6166 CHKERR TSElasticPostStep::preStepFun(ts);
6168 CHKERR TSSetSolution(ts, x);
6169 CHKERR TSSolve(ts, PETSC_NULLPTR);
6171 CHKERR TSElasticPostStep::postStepFun(ts);
6176 CHKERR VecGhostUpdateBegin(x, INSERT_VALUES, SCATTER_FORWARD);
6177 CHKERR VecGhostUpdateEnd(x, INSERT_VALUES, SCATTER_FORWARD);
6179 monitor_ptr->ts = PETSC_NULLPTR;
6180 monitor_ptr->ts_u = x;
6188 CHKERR VecGhostUpdateBegin(tao_sol0, INSERT_VALUES, SCATTER_FORWARD);
6189 CHKERR VecGhostUpdateEnd(tao_sol0, INSERT_VALUES, SCATTER_FORWARD);
6191 int tao_sol_size, tao_sol_loc_size;
6192 CHKERR VecGetSize(tao_sol0, &tao_sol_size);
6193 CHKERR VecGetLocalSize(tao_sol0, &tao_sol_loc_size);
6195 <<
"Topological data vector size " << tao_sol_size <<
" local size "
6196 << tao_sol_loc_size <<
" number of interface faces "
6199 const char *list_objective_models[ObjectiveModelType::LAST_MODEL] = {
6200 "python_model",
"hencky_model"};
6201#ifdef ENABLE_PYTHON_BINDING
6202 PetscInt choice_objective_model = ObjectiveModelType::PYTHON_MODEL;
6204 PetscInt choice_objective_model = ObjectiveModelType::HENCKY_MODEL;
6207 PETSC_NULLPTR, PETSC_NULLPTR,
"-objective_model_type",
6208 list_objective_models, ObjectiveModelType::LAST_MODEL,
6209 &choice_objective_model, PETSC_NULLPTR);
6210 const auto objective_model_type =
6211 static_cast<ObjectiveModelType
>(choice_objective_model);
6213 <<
"Objective model type: -objective_model_type "
6214 << list_objective_models[objective_model_type];
6217 PetscReal obj_value;
6218 CHKERR testTopologicalDerivative(topological_tao_ctx.get(), tao_sol0,
6219 &obj_value,
g, objective_model_type);
6221 CHKERR TSElasticPostStep::postStepDestroy();
6222 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_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 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< 'l', 3 > l
FTensor::Index< 'j', 3 > j
boost::shared_ptr< ContactSDFPython > setupContactSdf()
Read SDF file and setup contact SDF.
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)
MoFEMErrorCode pushCohesiveOpsRhs(EshelbianCore &ep, ForcesAndSourcesCore::GaussHookFun set_integration_at_front_face, boost::shared_ptr< Range > interface_range_ptr, boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pip)
static auto get_body_range(MoFEM::Interface &m_field, const std::string name, int dim)
static MoFEMErrorCodeGeneric< PetscErrorCode > ierr
static MoFEMErrorCodeGeneric< moab::ErrorCode > rval
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
UBlasMatrix< double > MatrixDouble
std::bitset< BITREFLEVEL_SIZE > BitRefLevel
Bit structure attached to each entity identifying to what mesh entity is attached.
implementation of Data Operators for Forces and Sources
PetscErrorCode TsMonitorSet(TS ts, PetscInt step, PetscReal t, Vec u, void *ctx)
Set monitor for TS solver.
auto getDMTsCtx(DM dm)
Get TS context data structure used by DM.
PetscErrorCode DMMoFEMSetDestroyProblem(DM dm, PetscBool destroy_problem)
MoFEMErrorCode MoFEMSNESMonitorEnergy(SNES snes, PetscInt its, PetscReal fgnorm, SnesCtx *ctx)
Sens monitor printing residual field by field.
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
#define QUAD_2D_TABLE_SIZE
#define QUAD_3D_TABLE_SIZE
static QUAD *const QUAD_2D_TABLE[]
static QUAD *const QUAD_3D_TABLE[]
PipelineManager::ElementsAndOpsByDim< SPACE_DIM >::FaceSideEle EleOnSide
FTensor::Index< 'm', 3 > m
CGG User Polynomial Base.
static boost::shared_ptr< SetUpSchur > createSetUpSchur(MoFEM::Interface &m_field, EshelbianCore *ep_core_ptr)
MoFEMErrorCode setElasticElementOps(const int tag)
boost::shared_ptr< ExternalStrainVec > externalStrainVecPtr
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_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 dd_f_log(const double v)
BitRefLevel bitAdjEnt
bit ref level for parent
static boost::function< double(const double)> inv_dd_f
MoFEM::Interface & mField
const std::string spatialL2Disp
static double inv_d_f_log(const double v)
std::map< std::string, boost::shared_ptr< ScalingMethod > > timeScaleMap
static enum SolverType solverType
static PetscBool l2UserBaseScale
SmartPetscObj< DM > dM
Coupled problem all fields.
MoFEMErrorCode 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 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)
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
static double d_f_log(const double v)
boost::shared_ptr< NormalDisplacementBcVec > bcSpatialNormalDisplacementVecPtr
static double crackingStartTime
MoFEMErrorCode getOptions()
const std::string piolaStress
MoFEMErrorCode setElasticElementToTs(DM dm)
static double inv_d_f_log_e(const double v)
MoFEMErrorCode setFaceInterfaceOps(const bool add_elastic, const bool add_material, boost::shared_ptr< FaceElementForcesAndSourcesCore > &fe_rhs, boost::shared_ptr< FaceElementForcesAndSourcesCore > &fe_lhs)
int contactRefinementLevels
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.
static double inv_f_log(const double v)
boost::shared_ptr< VolumeElementForcesAndSourcesCore > elasticFeLhs
boost::shared_ptr< ParentFiniteElementAdjacencyFunctionSkeleton< 2 > > parentAdjSkeletonFunctionDim2
static double crackingAddTime
static double exponentBase
static double dd_f_linear(const double v)
MoFEMErrorCode setFaceElementOps(const bool add_elastic, const bool add_material, boost::shared_ptr< FaceElementForcesAndSourcesCore > &fe_rhs, boost::shared_ptr< FaceElementForcesAndSourcesCore > &fe_lhs)
MoFEMErrorCode projectGeometry(const EntityHandle meshset=0, double time=0)
MoFEMErrorCode postProcessSkeletonResults(const int tag, const std::string file, Vec f_residual=PETSC_NULLPTR, std::vector< Tag > tags_to_transfer={})
static double currentPhysicalTime
boost::shared_ptr< AnalyticalExprPython > AnalyticalExprPythonPtr
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 double inv_d_f_linear(const double v)
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.
static double inv_dd_f_log(const double v)
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
static double inv_dd_f_linear(const double v)
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 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
boost::shared_ptr< Range > frontVertices
static enum EnergyReleaseSelector energyReleaseSelector
static boost::function< double(const double)> inv_d_f
boost::shared_ptr< PressureBcVec > bcSpatialPressureVecPtr
static double d_f_linear(const double v)
static int meshTransferInterpOrder
const std::string hybridSpatialDisp
SmartPetscObj< Vec > solTSStep
static double f_log(const double v)
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)
AnalyticalTractionBc(std::string name, std::vector< double > attr, Range faces)
BcRot(std::string name, std::vector< double > attr, Range faces)
ExternalStrain(std::string name, std::vector< double > attr, Range ents)
int operator()(int p_row, int p_col, int p_data) const
NormalDisplacementBc(std::string name, std::vector< double > attr, Range faces)
PressureBc(std::string name, std::vector< double > attr, Range faces)
boost::shared_ptr< Range > frontNodes
SetIntegrationAtFrontFace(boost::shared_ptr< Range > front_nodes, boost::shared_ptr< Range > front_edges)
boost::shared_ptr< Range > frontEdges
boost::function< int(int)> FunRule
SetIntegrationAtFrontFace(boost::shared_ptr< Range > front_nodes, boost::shared_ptr< Range > front_edges, FunRule fun_rule)
MoFEMErrorCode operator()(ForcesAndSourcesCore *fe_raw_ptr, int order_row, int order_col, int order_data)
static std::map< long int, MatrixDouble > mapRefCoords
MoFEMErrorCode operator()(ForcesAndSourcesCore *fe_raw_ptr, int order_row, int order_col, int order_data)
boost::shared_ptr< Range > frontNodes
static std::map< long int, MatrixDouble > mapRefCoords
boost::function< int(int)> FunRule
boost::shared_ptr< CGGUserPolynomialBase::CachePhi > cachePhi
SetIntegrationAtFrontVolume(boost::shared_ptr< Range > front_nodes, boost::shared_ptr< Range > front_edges, boost::shared_ptr< CGGUserPolynomialBase::CachePhi > cache_phi=nullptr)
SetIntegrationAtFrontVolume(boost::shared_ptr< Range > front_nodes, boost::shared_ptr< Range > front_edges, FunRule fun_rule, boost::shared_ptr< CGGUserPolynomialBase::CachePhi > cache_phi=nullptr)
boost::shared_ptr< Range > frontEdges
static MoFEMErrorCode preStepFun(TS ts)
static MoFEMErrorCode postStepDestroy()
static MoFEMErrorCode postStepFun(TS ts)
static MoFEMErrorCode postStepInitialise(EshelbianCore *ep_ptr)
TractionBc(std::string name, std::vector< double > attr, Range faces)
Set integration rule on element.
int operator()(int p_row, int p_col, int p_data) const
static auto setup(EshelbianCore *ep_ptr, TS ts, Vec x, bool set_ts_monitor)
multi_index_container< DofsSideMapData, indexed_by< ordered_non_unique< tag< TypeSide_mi_tag >, composite_key< DofsSideMapData, member< DofsSideMapData, EntityType, &DofsSideMapData::type >, member< DofsSideMapData, int, &DofsSideMapData::side > > >, ordered_unique< tag< EntDofIdx_mi_tag >, member< DofsSideMapData, int, &DofsSideMapData::dof > > > > DofsSideMap
Map entity stype and side to element/entity dof index.
Boundary condition manager for finite element problem setup.
static std::pair< std::string, std::string > extractStringFromBlockId(const std::string block_id, const std::string prb_name)
Extract block name and block name from block id.
static MoFEMErrorCode updateEntitiesPetscVector(moab::Interface &moab, EntitiesPetscVector &vec, Tag tag, UpdateGhosts update_gosts=defaultUpdateGhosts)
Exchange data between vector and data.
static Range getPartEntities(moab::Interface &moab, int part)
static MoFEMErrorCode setVectorFromTag(moab::Interface &moab, EntitiesPetscVector &vec, Tag tag)
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.
Definition of the displacement bc data structure.
Data on single entity (This is passed as argument to DataOperator::doWork)
Structure for user loop methods on finite elements.
EntityHandle getFEEntityHandle() const
Get the entity handle of the current finite element.
default operator for TRI element
Field data structure for finite element approximation.
Definition of the force bc data structure.
UserDataOperator(const FieldSpace space, const char type=OPSPACE, const bool symm=true)
Constructor for operators working on finite element spaces.
structure to get information from mofem into EntitiesFieldData
static boost::shared_ptr< ScalingMethod > get(boost::shared_ptr< ScalingMethod > ts, std::string file_prefix, std::string file_suffix, std::string block_name, Args &&...args)
Section manager is used to create indexes and sections.
Mesh refinement interface.
Interface for managing meshsets containing materials and boundary conditions.
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 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