16#ifdef INCLUDE_MBCOUPLER
17 #include <mbcoupler/Coupler.hpp>
25#include <boost/math/constants/constants.hpp>
28#ifdef ENABLE_PYTHON_BINDING
29 #include <boost/python.hpp>
30 #include <boost/python/def.hpp>
31 #include <boost/python/numpy.hpp>
32namespace bp = boost::python;
33namespace np = boost::python::numpy;
50 const EntityType
type) {
54 auto dim = CN::Dimension(
type);
56 std::vector<int> sendcounts(pcomm->size());
57 std::vector<int> displs(pcomm->size());
58 std::vector<int> sendbuf(r.size());
59 if (pcomm->rank() == 0) {
60 for (
auto p = 1; p != pcomm->size(); p++) {
62 ->getPartEntities(m_field.
get_moab(), p)
65 CHKERR m_field.
get_moab().get_adjacencies(part_ents, dim,
true, faces,
66 moab::Interface::UNION);
67 faces = intersect(faces, r);
68 sendcounts[p] = faces.size();
69 displs[p] = sendbuf.size();
70 for (
auto f : faces) {
72 sendbuf.push_back(
id);
78 MPI_Scatter(sendcounts.data(), 1, MPI_INT, &recv_data, 1, MPI_INT, 0,
80 std::vector<int> recvbuf(recv_data);
81 MPI_Scatterv(sendbuf.data(), sendcounts.data(), displs.data(), MPI_INT,
82 recvbuf.data(), recv_data, MPI_INT, 0, pcomm->comm());
84 if (pcomm->rank() > 0) {
86 for (
auto &f : recvbuf) {
96 const std::string block_name) {
102 std::regex((boost::format(
"%s(.*)") % block_name).str())
106 for (
auto bc : bcs) {
107 auto meshset = bc->getMeshset();
116 const std::string block_name,
int dim) {
122 std::regex((boost::format(
"%s(.*)") % block_name).str())
126 for (
auto bc : bcs) {
138 const std::string block_name,
int dim) {
139 std::map<std::string, Range> r;
144 std::regex((boost::format(
"%s(.*)") % block_name).str())
148 for (
auto bc : bcs) {
153 r[bc->getName()] = faces;
159static auto save_range(moab::Interface &moab,
const std::string name,
160 const Range r, std::vector<Tag> tags = {}) {
163 CHKERR moab.add_entities(*out_meshset, r);
165 CHKERR moab.write_file(name.c_str(),
"VTK",
"", out_meshset->get_ptr(), 1,
166 tags.data(), tags.size());
168 MOFEM_LOG(
"SELF", Sev::warning) <<
"Empty range for " << name;
175 ParallelComm *pcomm =
178 PSTATUS_SHARED | PSTATUS_MULTISHARED,
179 PSTATUS_NOT, -1, &boundary_ents),
181 return boundary_ents;
186 ParallelComm *pcomm =
188 CHK_MOAB_THROW(pcomm->filter_pstatus(skin, PSTATUS_NOT_OWNED, PSTATUS_NOT, -1,
197 CHK_MOAB_THROW(skin.find_skin(0, body_ents,
false, skin_ents),
"find_skin");
203 ParallelComm *pcomm =
206 Range crack_skin_without_bdy;
207 if (pcomm->rank() == 0) {
209 CHKERR moab.get_adjacencies(crack_faces, 1,
true, crack_edges,
210 moab::Interface::UNION);
211 auto crack_skin =
get_skin(m_field, crack_faces);
215 "get_entities_by_dimension");
216 auto body_skin =
get_skin(m_field, body_ents);
217 Range body_skin_edges;
218 CHK_MOAB_THROW(moab.get_adjacencies(body_skin, 1,
true, body_skin_edges,
219 moab::Interface::UNION),
221 crack_skin_without_bdy = subtract(crack_skin, body_skin_edges);
223 for (
auto &
m : front_edges_map) {
224 auto add_front = subtract(
m.second, crack_edges);
225 auto i = intersect(
m.second, crack_edges);
227 crack_skin_without_bdy.merge(add_front);
231 CHKERR moab.get_adjacencies(i_skin, 1,
true, adj_i_skin,
232 moab::Interface::UNION);
233 adj_i_skin = subtract(intersect(adj_i_skin,
m.second), crack_edges);
234 crack_skin_without_bdy.merge(adj_i_skin);
238 return send_type(m_field, crack_skin_without_bdy, MBEDGE);
244 ParallelComm *pcomm =
247 MOFEM_LOG(
"EP", Sev::noisy) <<
"get_two_sides_of_crack_surface";
249 if (!pcomm->rank()) {
251 auto impl = [&](
auto &saids) {
256 auto get_adj = [&](
auto e,
auto dim) {
259 e, dim,
true, adj, moab::Interface::UNION),
264 auto get_conn = [&](
auto e) {
271 constexpr bool debug =
false;
275 auto body_skin =
get_skin(m_field, body_ents);
276 auto body_skin_edges = get_adj(body_skin, 1);
279 subtract(
get_skin(m_field, crack_faces), body_skin_edges);
280 auto crack_skin_conn = get_conn(crack_skin);
281 auto crack_skin_conn_edges = get_adj(crack_skin_conn, 1);
282 auto crack_edges = get_adj(crack_faces, 1);
283 crack_edges = subtract(crack_edges, crack_skin);
284 auto all_tets = get_adj(crack_edges, 3);
285 crack_edges = subtract(crack_edges, crack_skin_conn_edges);
286 auto crack_conn = get_conn(crack_edges);
287 all_tets.merge(get_adj(crack_conn, 3));
296 if (crack_faces.size()) {
297 auto grow = [&](
auto r) {
298 auto crack_faces_conn = get_conn(crack_faces);
301 while (size_r != r.size() && r.size() > 0) {
303 CHKERR moab.get_connectivity(r,
v,
true);
304 v = subtract(
v, crack_faces_conn);
307 moab::Interface::UNION);
308 r = intersect(r, all_tets);
317 Range all_tets_ord = all_tets;
318 while (all_tets.size()) {
319 Range faces = get_adj(unite(saids.first, saids.second), 2);
320 faces = subtract(crack_faces, faces);
323 auto fit = faces.begin();
324 for (; fit != faces.end(); ++fit) {
325 tets = intersect(get_adj(
Range(*fit, *fit), 3), all_tets);
326 if (tets.size() == 2) {
333 saids.first.insert(tets[0]);
334 saids.first = grow(saids.first);
335 all_tets = subtract(all_tets, saids.first);
336 if (tets.size() == 2) {
337 saids.second.insert(tets[1]);
338 saids.second = grow(saids.second);
339 all_tets = subtract(all_tets, saids.second);
347 saids.first = subtract(all_tets_ord, saids.second);
348 saids.second = subtract(all_tets_ord, saids.first);
354 std::pair<Range, Range> saids;
355 if (crack_faces.size())
360 MOFEM_LOG(
"EP", Sev::noisy) <<
"get_two_sides_of_crack_surface <- done";
362 return std::pair<Range, Range>();
376 boost::shared_ptr<Range> front_nodes,
377 boost::shared_ptr<Range> front_edges,
378 boost::shared_ptr<CGGUserPolynomialBase::CachePhi> cache_phi =
nullptr)
383 boost::shared_ptr<Range> front_nodes,
384 boost::shared_ptr<Range> front_edges,
FunRule fun_rule,
385 boost::shared_ptr<CGGUserPolynomialBase::CachePhi> cache_phi =
nullptr)
390 int order_col,
int order_data) {
393 constexpr bool debug =
false;
395 constexpr int numNodes = 4;
396 constexpr int numEdges = 6;
397 constexpr int refinementLevels = 6;
399 auto &m_field = fe_raw_ptr->
mField;
400 auto fe_ptr =
static_cast<Fe *
>(fe_raw_ptr);
403 auto set_base_quadrature = [&]() {
408 const int rule =
funRule(order_data);
409 const auto xiao_rule = IntRules::XiaoGimbutas::getTetrahedronRule(rule);
412 "Xiao--Gimbutas tetrahedron rule is available for polynomial "
413 "orders 0 to %d; requested %d",
414 IntRules::XiaoGimbutas::tetrahedronRuleCount, rule);
416 if (xiao_rule->numBarycentricCoordinates != 4) {
418 "wrong number of tetrahedron barycentric coordinates");
421 const size_t nb_gauss_pts = xiao_rule->numPoints;
422 auto &gauss_pts = fe_ptr->gaussPts;
423 gauss_pts.resize(4, nb_gauss_pts,
false);
424 cblas_dcopy(nb_gauss_pts, &xiao_rule->points[1], 4, &gauss_pts(0, 0), 1);
425 cblas_dcopy(nb_gauss_pts, &xiao_rule->points[2], 4, &gauss_pts(1, 0), 1);
426 cblas_dcopy(nb_gauss_pts, &xiao_rule->points[3], 4, &gauss_pts(2, 0), 1);
427 cblas_dcopy(nb_gauss_pts, xiao_rule->weights, 1, &gauss_pts(3, 0), 1);
428 auto &data = fe_ptr->dataOnElement[
H1];
429 data->dataOnEntities[MBVERTEX][0].getN(
NOBASE).resize(nb_gauss_pts, 4,
432 &*data->dataOnEntities[MBVERTEX][0].getN(
NOBASE).data().begin();
433 cblas_dcopy(4 * nb_gauss_pts, xiao_rule->points, 1, shape_ptr, 1);
437 CHKERR set_base_quadrature();
441 auto get_singular_nodes = [&]() {
443 const EntityHandle *conn;
444 CHKERR m_field.get_moab().get_connectivity(fe_handle, conn, num_nodes,
446 std::bitset<numNodes> singular_nodes;
447 for (
auto nn = 0; nn != numNodes; ++nn) {
449 singular_nodes.set(nn);
451 singular_nodes.reset(nn);
454 return singular_nodes;
457 auto get_singular_edges = [&]() {
458 std::bitset<numEdges> singular_edges;
459 for (
int ee = 0; ee != numEdges; ee++) {
461 CHKERR m_field.get_moab().side_element(fe_handle, 1, ee, edge);
463 singular_edges.set(ee);
465 singular_edges.reset(ee);
468 return singular_edges;
471 auto set_gauss_pts = [&](
auto &ref_gauss_pts) {
473 fe_ptr->gaussPts.swap(ref_gauss_pts);
474 const size_t nb_gauss_pts = fe_ptr->gaussPts.size2();
475 auto &data = fe_ptr->dataOnElement[
H1];
476 data->dataOnEntities[MBVERTEX][0].getN(
NOBASE).resize(nb_gauss_pts, 4);
478 &*data->dataOnEntities[MBVERTEX][0].getN(
NOBASE).data().begin();
480 &fe_ptr->gaussPts(1, 0), &fe_ptr->gaussPts(2, 0),
485 auto singular_nodes = get_singular_nodes();
486 if (singular_nodes.count()) {
487 auto it_map_ref_coords =
mapRefCoords.find(singular_nodes.to_ulong());
489 CHKERR set_gauss_pts(it_map_ref_coords->second);
493 auto refine_quadrature = [&]() {
496 const int max_level = refinementLevels;
500 double base_coords[] = {0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1};
501 EntityHandle nodes[4];
502 for (
int nn = 0; nn != 4; nn++)
503 CHKERR moab_ref.create_vertex(&base_coords[3 * nn], nodes[nn]);
504 CHKERR moab_ref.create_element(MBTET, nodes, 4, tet);
508 Range tets(tet, tet);
511 tets, 1,
true, edges, moab::Interface::UNION);
516 Range nodes_at_front;
517 for (
int nn = 0; nn != numNodes; nn++) {
518 if (singular_nodes[nn]) {
520 CHKERR moab_ref.side_element(tet, 0, nn, ent);
521 nodes_at_front.insert(ent);
525 auto singular_edges = get_singular_edges();
527 EntityHandle meshset;
528 CHKERR moab_ref.create_meshset(MESHSET_SET, meshset);
529 for (
int ee = 0; ee != numEdges; ee++) {
530 if (singular_edges[ee]) {
532 CHKERR moab_ref.side_element(tet, 1, ee, ent);
533 CHKERR moab_ref.add_entities(meshset, &ent, 1);
539 for (
int ll = 0; ll != max_level; ll++) {
542 ->getEntitiesByTypeAndRefLevel(
BitRefLevel().set(ll),
546 CHKERR moab_ref.get_adjacencies(
547 nodes_at_front, 1,
true, ref_edges, moab::Interface::UNION);
548 ref_edges = intersect(ref_edges, edges);
550 CHKERR moab_ref.get_entities_by_type(meshset, MBEDGE, ents,
true);
551 ref_edges = intersect(ref_edges, ents);
554 ->getEntitiesByTypeAndRefLevel(
556 CHKERR m_ref->addVerticesInTheMiddleOfEdges(
560 ->updateMeshsetByEntitiesChildren(meshset,
562 meshset, MBEDGE,
true);
568 ->getEntitiesByTypeAndRefLevel(
BitRefLevel().set(max_level),
578 for (Range::iterator tit = tets.begin(); tit != tets.end();
581 const EntityHandle *conn;
582 CHKERR moab_ref.get_connectivity(*tit, conn, num_nodes,
false);
583 CHKERR moab_ref.get_coords(conn, num_nodes, &ref_coords(tt, 0));
586 auto &data = fe_ptr->dataOnElement[
H1];
587 const size_t nb_gauss_pts = fe_ptr->gaussPts.size2();
588 MatrixDouble ref_gauss_pts(4, nb_gauss_pts * ref_coords.size1());
590 data->dataOnEntities[MBVERTEX][0].getN(
NOBASE);
592 for (
size_t tt = 0; tt != ref_coords.size1(); tt++) {
593 double *tet_coords = &ref_coords(tt, 0);
596 for (
size_t ggg = 0; ggg != nb_gauss_pts; ++ggg, ++gg) {
597 for (
int dd = 0; dd != 3; dd++) {
598 ref_gauss_pts(dd, gg) =
599 shape_n(ggg, 0) * tet_coords[3 * 0 + dd] +
600 shape_n(ggg, 1) * tet_coords[3 * 1 + dd] +
601 shape_n(ggg, 2) * tet_coords[3 * 2 + dd] +
602 shape_n(ggg, 3) * tet_coords[3 * 3 + dd];
604 ref_gauss_pts(3, gg) = fe_ptr->gaussPts(3, ggg) * det;
608 mapRefCoords[singular_nodes.to_ulong()].swap(ref_gauss_pts);
615 TetPolynomialBase::switchCacheBaseOff<HDIV>({fe_raw_ptr});
616 TetPolynomialBase::switchCacheBaseOn<HDIV>({fe_raw_ptr});
621 CHKERR refine_quadrature();
631 using ForcesAndSourcesCore::dataOnElement;
634 using ForcesAndSourcesCore::ForcesAndSourcesCore;
640 boost::shared_ptr<CGGUserPolynomialBase::CachePhi>
cachePhi;
648 boost::shared_ptr<Range> front_edges)
652 boost::shared_ptr<Range> front_edges,
int (*)(
int))
656 int order_col,
int order_data) {
659 constexpr bool debug =
false;
661 constexpr int numNodes = 3;
662 constexpr int numEdges = 3;
663 constexpr int refinementLevels = 6;
665 auto &m_field = fe_raw_ptr->
mField;
666 auto fe_ptr =
static_cast<Fe *
>(fe_raw_ptr);
669 auto set_base_quadrature = [&]() {
672 const auto xiao_rule = IntRules::XiaoGimbutas::getTriangleRule(rule);
675 "Xiao--Gimbutas triangle rule is available for polynomial "
676 "orders 0 to %d; requested %d",
677 IntRules::XiaoGimbutas::triangleRuleCount, rule);
679 if (xiao_rule->numBarycentricCoordinates != 3) {
681 "wrong number of triangle barycentric coordinates");
684 const size_t nb_gauss_pts = xiao_rule->numPoints;
685 auto &gauss_pts = fe_ptr->gaussPts;
686 gauss_pts.resize(3, nb_gauss_pts,
false);
687 cblas_dcopy(nb_gauss_pts, &xiao_rule->points[1], 3, &gauss_pts(0, 0), 1);
688 cblas_dcopy(nb_gauss_pts, &xiao_rule->points[2], 3, &gauss_pts(1, 0), 1);
689 cblas_dcopy(nb_gauss_pts, xiao_rule->weights, 1, &gauss_pts(2, 0), 1);
693 CHKERR set_base_quadrature();
697 auto get_singular_nodes = [&]() {
699 const EntityHandle *conn;
700 CHKERR m_field.get_moab().get_connectivity(fe_handle, conn, num_nodes,
702 std::bitset<numNodes> singular_nodes;
703 for (
auto nn = 0; nn != numNodes; ++nn) {
705 singular_nodes.set(nn);
707 singular_nodes.reset(nn);
710 return singular_nodes;
713 auto get_singular_edges = [&]() {
714 std::bitset<numEdges> singular_edges;
715 for (
int ee = 0; ee != numEdges; ee++) {
717 CHKERR m_field.get_moab().side_element(fe_handle, 1, ee, edge);
719 singular_edges.set(ee);
721 singular_edges.reset(ee);
724 return singular_edges;
727 auto set_gauss_pts = [&](
auto &ref_gauss_pts) {
729 fe_ptr->gaussPts.swap(ref_gauss_pts);
733 auto singular_nodes = get_singular_nodes();
734 if (singular_nodes.count()) {
735 auto it_map_ref_coords =
mapRefCoords.find(singular_nodes.to_ulong());
737 CHKERR set_gauss_pts(it_map_ref_coords->second);
741 auto refine_quadrature = [&]() {
744 const int max_level = refinementLevels;
747 double base_coords[] = {0, 0, 0, 1, 0, 0, 0, 1, 0};
748 EntityHandle nodes[numNodes];
749 for (
int nn = 0; nn != numNodes; nn++)
750 CHKERR moab_ref.create_vertex(&base_coords[3 * nn], nodes[nn]);
752 CHKERR moab_ref.create_element(MBTRI, nodes, numNodes, tri);
756 Range tris(tri, tri);
759 tris, 1,
true, edges, moab::Interface::UNION);
764 Range nodes_at_front;
765 for (
int nn = 0; nn != numNodes; nn++) {
766 if (singular_nodes[nn]) {
768 CHKERR moab_ref.side_element(tri, 0, nn, ent);
769 nodes_at_front.insert(ent);
773 auto singular_edges = get_singular_edges();
775 EntityHandle meshset;
776 CHKERR moab_ref.create_meshset(MESHSET_SET, meshset);
777 for (
int ee = 0; ee != numEdges; ee++) {
778 if (singular_edges[ee]) {
780 CHKERR moab_ref.side_element(tri, 1, ee, ent);
781 CHKERR moab_ref.add_entities(meshset, &ent, 1);
787 for (
int ll = 0; ll != max_level; ll++) {
790 ->getEntitiesByTypeAndRefLevel(
BitRefLevel().set(ll),
794 CHKERR moab_ref.get_adjacencies(
795 nodes_at_front, 1,
true, ref_edges, moab::Interface::UNION);
796 ref_edges = intersect(ref_edges, edges);
798 CHKERR moab_ref.get_entities_by_type(meshset, MBEDGE, ents,
true);
799 ref_edges = intersect(ref_edges, ents);
802 ->getEntitiesByTypeAndRefLevel(
804 CHKERR m_ref->addVerticesInTheMiddleOfEdges(
808 ->updateMeshsetByEntitiesChildren(meshset,
810 meshset, MBEDGE,
true);
816 ->getEntitiesByTypeAndRefLevel(
BitRefLevel().set(max_level),
827 for (Range::iterator tit = tris.begin(); tit != tris.end();
830 const EntityHandle *conn;
831 CHKERR moab_ref.get_connectivity(*tit, conn, num_nodes,
false);
832 CHKERR moab_ref.get_coords(conn, num_nodes, &ref_coords(tt, 0));
835 const size_t nb_gauss_pts = fe_ptr->gaussPts.size2();
836 MatrixDouble ref_gauss_pts(3, nb_gauss_pts * ref_coords.size1());
839 &fe_ptr->gaussPts(1, 0), nb_gauss_pts);
841 for (
size_t tt = 0; tt != ref_coords.size1(); tt++) {
842 double *tri_coords = &ref_coords(tt, 0);
845 auto det = t_normal.
l2();
846 for (
size_t ggg = 0; ggg != nb_gauss_pts; ++ggg, ++gg) {
847 for (
int dd = 0; dd != 2; dd++) {
848 ref_gauss_pts(dd, gg) =
849 shape_n(ggg, 0) * tri_coords[3 * 0 + dd] +
850 shape_n(ggg, 1) * tri_coords[3 * 1 + dd] +
851 shape_n(ggg, 2) * tri_coords[3 * 2 + dd];
853 ref_gauss_pts(2, gg) = fe_ptr->gaussPts(2, ggg) * det;
857 mapRefCoords[singular_nodes.to_ulong()].swap(ref_gauss_pts);
863 CHKERR refine_quadrature();
873 using ForcesAndSourcesCore::dataOnElement;
876 using ForcesAndSourcesCore::ForcesAndSourcesCore;
925 auto comm = PetscObjectComm(
reinterpret_cast<PetscObject
>(dm.get()));
926 CHKERRABORT(comm, DMMoFEMClearDMCtx(dm));
944 const char *ts_prefix =
nullptr;
945 CHKERR TSGetOptionsPrefix(ts, &ts_prefix);
946 const std::string prefix = ts_prefix ? ts_prefix :
"";
947 const auto make_ts_option = [&prefix](
const char *name) {
948 return std::string(
"-") + prefix + name;
950 const auto has_ts_option = [&make_ts_option](
const char *name,
952 const auto option = make_ts_option(name);
953 return PetscOptionsHasName(PETSC_NULLPTR, PETSC_NULLPTR, option.c_str(),
956 const auto clear_ts_option = [&make_ts_option](
const char *name) {
957 const auto option = make_ts_option(name);
958 return PetscOptionsClearValue(PETSC_NULLPTR, option.c_str());
961 PetscBool cancel_snes_monitor = PETSC_FALSE;
962 PetscBool cancel_ksp_monitor = PETSC_FALSE;
963 CHKERR has_ts_option(
"snes_monitor_cancel", &cancel_snes_monitor);
964 CHKERR has_ts_option(
"ksp_monitor_cancel", &cancel_ksp_monitor);
967 CHKERR TSGetSNES(ts, &snes);
969 if (cancel_snes_monitor) {
970 CHKERR clear_ts_option(
"snes_monitor");
971 CHKERR clear_ts_option(
"snes_linesearch_monitor");
972 CHKERR SNESMonitorCancel(snes);
973 SNESLineSearch line_search;
974 CHKERR SNESGetLineSearch(snes, &line_search);
975 CHKERR SNESLineSearchMonitorCancel(line_search);
978 if (cancel_ksp_monitor) {
979 CHKERR clear_ts_option(
"ksp_monitor");
980 CHKERR clear_ts_option(
"ksp_monitor_short");
981 CHKERR clear_ts_option(
"ksp_monitor_true_residual");
983 CHKERR SNESGetKSP(snes, &ksp);
984 CHKERR KSPMonitorCancel(ksp);
993 PetscBool cancel_projection_ksp_monitor = PETSC_FALSE;
994 CHKERR PetscOptionsHasName(PETSC_NULLPTR, PETSC_NULLPTR,
995 "-prjspatial_ksp_monitor_cancel",
996 &cancel_projection_ksp_monitor);
998 if (cancel_projection_ksp_monitor) {
999 CHKERR PetscOptionsClearValue(PETSC_NULLPTR,
"-prjspatial_ksp_monitor");
1000 CHKERR PetscOptionsClearValue(PETSC_NULLPTR,
1001 "-prjspatial_ksp_monitor_short");
1002 CHKERR PetscOptionsClearValue(PETSC_NULLPTR,
1003 "-prjspatial_ksp_monitor_true_residual");
1013 const char *list_rots[] = {
"small",
"moderate",
"large",
"no_h1"};
1014 const char *list_release[] = {
"griffith_force",
"griffith_skeleton"};
1015 const char *list_stretches[] = {
"linear",
"log",
"log_quadratic"};
1016 const char *list_broken_hdiv_bases[] = {
"demkowicz",
"ainsworth"};
1020 PetscInt choice_stretch = StretchSelector::LOG;
1022 PetscInt choice_broken_hdiv_base = 0;
1023 PetscBool l2_user_base_scale_set = PETSC_FALSE;
1026 choice_broken_hdiv_base = 0;
1029 choice_broken_hdiv_base = 1;
1033 "Unsupported broken HDIV base %s",
1036 char analytical_expr_file_name[255] =
"analytical_expr.py";
1038 PetscOptionsBegin(PETSC_COMM_WORLD,
"",
"Eshelbian plasticity",
"none");
1039 CHKERR PetscOptionsInt(
"-space_order",
"approximation oder for space",
"",
1041 CHKERR PetscOptionsInt(
"-space_h1_order",
"approximation oder for space",
"",
1043 CHKERR PetscOptionsInt(
"-material_order",
"approximation oder for material",
1045 CHKERR PetscOptionsScalar(
"-viscosity_alpha_u",
1046 "Logarithmic-stretch rate viscosity",
"",
alphaU,
1048 CHKERR PetscOptionsScalar(
"-viscosity_alpha_w",
1049 "Spatial-displacement rate viscosity",
"",
alphaW,
1051 CHKERR PetscOptionsScalar(
"-alpha_omega",
"H1 rotation penalty coefficient",
1053 CHKERR PetscOptionsScalar(
"-alpha_r",
"L2 rotation penalty coefficient",
"",
1055 CHKERR PetscOptionsScalar(
"-viscosity_alpha_omega",
1056 "H1 rotation-rate viscosity",
"",
1059 CHKERR PetscOptionsScalar(
"-viscosity_alpha_r",
"L2 rotation-rate viscosity",
"",
1061 CHKERR PetscOptionsScalar(
"-density_alpha_rho",
1062 "Spatial-displacement inertia density",
"",
1064 CHKERR PetscOptionsScalar(
"-alpha_tau",
1065 "Interior displacement-stabilisation coefficient",
1067 CHKERR PetscOptionsScalar(
1069 "Coefficient multiplying the face-averaged normal-traction contribution "
1070 "to displacement stabilisation",
1072 CHKERR PetscOptionsScalar(
"-alpha_tau_bc_disp",
1073 "Displacement-BC stabilisation coefficient",
"",
1075 CHKERR PetscOptionsEList(
"-rotations",
"rotations",
"", list_rots,
1076 LARGE_ROT + 1, list_rots[choice_rot], &choice_rot,
1078 CHKERR PetscOptionsEList(
"-grad",
"gradient of defamation approximate",
"",
1079 list_rots, NO_H1_CONFIGURATION + 1,
1080 list_rots[choice_grad], &choice_grad, PETSC_NULLPTR);
1082 CHKERR PetscOptionsEList(
"-stretches",
"stretches",
"", list_stretches,
1083 StretchSelector::STRETCH_SELECTOR_LAST,
1084 list_stretches[choice_stretch], &choice_stretch,
1087 CHKERR PetscOptionsBool(
"-set_singularity",
"set singularity",
"",
1089 CHKERR PetscOptionsBool(
"-l2_user_base_scale",
"streach scale",
"",
1091 &l2_user_base_scale_set);
1092 CHKERR PetscOptionsEList(
"-broken_hdiv_base",
1093 "broken HDIV stress approximation base",
"",
1094 list_broken_hdiv_bases, 2,
1095 list_broken_hdiv_bases[choice_broken_hdiv_base],
1096 &choice_broken_hdiv_base, PETSC_NULLPTR);
1101 CHKERR PetscOptionsBool(
"-dynamic_relaxation",
"dynamic time relaxation",
"",
1103 CHKERR PetscOptionsEList(
1109 CHKERR PetscOptionsScalar(
"-physical_final_time",
"physical final time",
"",
1112 CHKERR PetscOptionsScalar(
"-physical_delta_time",
"physical delta time",
"",
1115 CHKERR PetscOptionsInt(
"-physical_max_steps",
"physical max iterations",
"",
1119 "-physical_h1_update",
"update each physicalsolver step",
"",
1124 CHKERR PetscOptionsInt(
"-contact_max_post_proc_ref_level",
"refinement level",
1128 CHKERR PetscOptionsBool(
"-cohesive_interface_on",
"cohesive interface ON",
"",
1131 "-cohesive_interface_remove_level",
"cohesive interface remove level",
"",
1133 CHKERR PetscOptionsBool(
"-plastic_volume",
1134 "restrict plasticity to the PLATIC_VOLUME block",
"",
1140 CHKERR PetscOptionsBool(
"-propagate_under_compression",
1141 "propagate crack under compression",
"",
1144 CHKERR PetscOptionsScalar(
"-cracking_add_time",
"cracking add time",
"",
1146 CHKERR PetscOptionsScalar(
"-cracking_start_time",
"cracking start time",
"",
1149 CHKERR PetscOptionsScalar(
"-griffith_energy",
"Griffith energy",
"",
1152 CHKERR PetscOptionsScalar(
"-cracking_rtol",
"Cracking relative tolerance",
"",
1154 CHKERR PetscOptionsScalar(
"-cracking_atol",
"Cracking absolute tolerance",
"",
1156 CHKERR PetscOptionsEList(
"-energy_release_variant",
"energy release variant",
1157 "", list_release, 2, list_release[choice_release],
1158 &choice_release, PETSC_NULLPTR);
1159 CHKERR PetscOptionsInt(
"-nb_J_integral_levels",
"Number of J integarl levels",
1163 "-nb_J_integral_contours",
"Number of J integral contours",
"",
1167 char tag_name[255] =
"";
1168 CHKERR PetscOptionsString(
"-internal_stress_tag_name",
1169 "internal stress tag name",
"",
"", tag_name, 255,
1172 CHKERR PetscOptionsBool(
"-internal_stress_voigt",
"Voigt index notation",
"",
1177 char tag_heterogeneous_youngs_modulus_name[255] =
"";
1178 CHKERR PetscOptionsString(
1179 "-heterogeneous_youngs_modulus",
"heterogeneous Young's modulus tag name",
1180 "",
"", tag_heterogeneous_youngs_modulus_name, 255, PETSC_NULLPTR);
1183 PetscBool has_analytical_expr_file_option = PETSC_FALSE;
1185 PETSC_NULLPTR, PETSC_NULLPTR,
"-analytical_expr_file",
1186 analytical_expr_file_name, 255, &has_analytical_expr_file_option);
1187 if (!has_analytical_expr_file_option) {
1188 const auto analytical_expr_script =
1191 if (!analytical_expr_script.empty()) {
1192 CHKERR PetscStrncpy(analytical_expr_file_name,
1193 analytical_expr_script.c_str(),
1194 sizeof(analytical_expr_file_name));
1196 <<
"Using Python script 'analytical_expr' from JSON config: "
1197 << analytical_expr_file_name;
1205 PetscOptionsBegin(PETSC_COMM_WORLD,
"mesh_transfer_",
"mesh data transfer",
1207 char tag_mesh_transfer_source_file_name[255] =
"";
1208 CHKERR PetscOptionsString(
"-source_file",
"source mesh file name",
"",
1209 "source.h5m", tag_mesh_transfer_source_file_name,
1212 CHKERR PetscOptionsInt(
"-interp_order",
"interpolation order",
"", 0,
1214 CHKERR PetscOptionsBool(
"-hybrid_interp",
"use hybrid interpolation",
"",
1221 "Unsupported mesh transfer interpolation order %d",
1238 static_cast<EnergyReleaseSelector
>(choice_release);
1239 switch (choice_broken_hdiv_base) {
1248 "Unknown broken HDIV base option");
1252 case StretchSelector::LINEAR:
1260 case StretchSelector::LOG:
1268 case StretchSelector::LOG_QUADRATIC:
1284 <<
"-dynamic_relaxation option is deprecated, use -solver_type "
1285 "dynamic_relaxation instead.";
1289 switch (choice_solver) {
1352 <<
"Cracking start/add time does not apply for load factor solver.";
1357 const auto yes_no = [](
auto flag) {
return flag ?
"yes" :
"no"; };
1365 <<
"alphaU (-viscosity_alpha_u), logarithmic-stretch rate viscosity: "
1368 <<
"alphaW (-viscosity_alpha_w), spatial-displacement rate viscosity: "
1371 <<
"alphaOmega (-alpha_omega), H1 rotation penalty coefficient: "
1374 <<
"alphaR (-alpha_r), L2 rotation penalty coefficient: " <<
alphaR;
1376 <<
"alphaViscousOmega (-viscosity_alpha_omega), H1 rotation-rate "
1380 <<
"alphaViscousR (-viscosity_alpha_r), L2 rotation-rate viscosity: "
1383 <<
"alphaRho (-density_alpha_rho), spatial-displacement inertia "
1387 <<
"alphaTau (-alpha_tau), interior displacement-stabilisation "
1391 <<
"alphaTauLin (-alpha_tau_lin), face-averaged normal-traction "
1392 "stabilisation coefficient: "
1395 <<
"alphaTauBcDisp (-alpha_tau_bc_disp), displacement-BC "
1396 "stabilisation coefficient: "
1400 MOFEM_LOG(
"EP", Sev::inform) <<
"Gradient of deformation: -grad "
1403 <<
"Stretch: -stretches " << list_stretches[choice_stretch];
1405 MOFEM_LOG(
"EP", Sev::inform) <<
"Dynamic relaxation: -dynamic_relaxation "
1406 << yes_no(dynamic_relaxation_option);
1407 MOFEM_LOG(
"EP", Sev::inform) <<
"Solver type: -solver_type "
1413 <<
"Physical delta time: -physical_delta_time " <<
physicalDt;
1416 MOFEM_LOG(
"EP", Sev::inform) <<
"Physical H1 update: -physical_h1_update "
1421 MOFEM_LOG(
"EP", Sev::inform) <<
"L2 user base scale: -l2_user_base_scale "
1422 << yes_no(l2_user_base_scale_option);
1425 <<
"Effective L2 user base scale after option processing "
1429 <<
"Broken HDIV base: -broken_hdiv_base "
1430 << list_broken_hdiv_bases[choice_broken_hdiv_base];
1432 <<
"Contact max post-proc ref level: -contact_max_post_proc_ref_level "
1436 <<
"Cracking on: -cracking_on " << yes_no(
crackingOn);
1444 <<
"Cracking relative tolerance: -cracking_rtol " <<
crackingRtol;
1446 <<
"Cracking absolute tolerance: -cracking_atol " <<
crackingAtol;
1448 <<
"Energy release variant: -energy_release_variant "
1451 <<
"Number of J integral contours: -nb_J_integral_contours / "
1452 "-nb_J_integral_levels "
1455 <<
"Cohesive interface on: -cohesive_interface_on "
1458 <<
"Cohesive interface remove level: -cohesive_interface_remove_level "
1461 <<
"Plastic volume: -plastic_volume " << yes_no(
plasticVolume);
1463 <<
"Internal stress tag name: -internal_stress_tag_name "
1466 <<
"Internal stress Voigt notation: -internal_stress_voigt "
1469 <<
"Heterogeneous Young's modulus: -heterogeneous_youngs_modulus "
1472 <<
"Analytical expression file: -analytical_expr_file "
1473 << analytical_expr_file_name;
1476 <<
"Mesh transfer source file: -mesh_transfer_source_file "
1480 <<
"Mesh transfer source file: -mesh_transfer_source_file <not set>";
1483 <<
"Mesh transfer interpolation order: -mesh_transfer_interp_order "
1486 <<
"Mesh transfer hybrid interpolation: -mesh_transfer_hybrid_interp "
1489#ifdef ENABLE_PYTHON_BINDING
1490 auto file_exists = [](std::string myfile) {
1491 std::ifstream file(myfile.c_str());
1498 if (file_exists(analytical_expr_file_name)) {
1499 MOFEM_LOG(
"EP", Sev::inform) << analytical_expr_file_name <<
" file found";
1503 analytical_expr_file_name);
1507 << analytical_expr_file_name <<
" file NOT found";
1530 <<
"Number of plastic volume elements: " <<
plasticVolumes->size();
1535 auto get_internal_interface_faces = [&](
const auto block_name) {
1540 volume_elements,
SPACE_DIM - 1,
true, faces, moab::Interface::UNION);
1541 faces = subtract(faces, skin);
1543 <<
"Number of volume interface elements: " << volume_elements.size()
1544 <<
" and internal faces: " << faces.size();
1549 get_internal_interface_faces(
"(VOLUME_INTERFACE|MAT_COHESIVE)"));
1551 auto remove_interface_faces = [&](
const auto block_name,
const auto level) {
1553 Range retained_faces;
1556 for (
auto l = 0;
l < level; ++
l) {
1557 Range adjacent_tets;
1559 entities,
SPACE_DIM,
true, adjacent_tets, moab::Interface::UNION);
1560 Range adjacent_tet_faces;
1562 true, adjacent_tet_faces,
1563 moab::Interface::UNION);
1564 entities.merge(adjacent_tet_faces);
1566 const auto faces = entities.subset_by_dimension(
SPACE_DIM - 1);
1567 if (!faces.empty()) {
1569 <<
"Removing " << faces.size() <<
" of " <<
interfaceFaces->size()
1570 <<
" interface faces";
1574 <<
"Interface faces after removal " << retained_faces;
1576 auto global_retained_faces =
send_type(
mField, retained_faces, MBTRI);
1589 const bool add_bubble) {
1592 auto get_tets = [&]() {
1598 auto get_tets_skin = [&]() {
1599 Range tets_skin_part;
1601 CHKERR skin.find_skin(0, get_tets(),
false, tets_skin_part);
1602 ParallelComm *pcomm =
1605 CHKERR pcomm->filter_pstatus(tets_skin_part,
1606 PSTATUS_SHARED | PSTATUS_MULTISHARED,
1607 PSTATUS_NOT, -1, &tets_skin);
1611 auto subtract_boundary_conditions = [&](
auto &&tets_skin) {
1617 tets_skin = subtract(tets_skin,
v.faces);
1622 tets_skin = subtract(tets_skin,
v.faces);
1627 tets_skin = subtract(tets_skin,
v.faces);
1632 tets_skin = subtract(tets_skin,
v.faces);
1638 auto subtract_blockset = [&](
auto block_name,
auto &&tets_skin) {
1639 auto contact_range =
1641 tets_skin = subtract(tets_skin, contact_range);
1645 auto get_stress_trace_faces = [&](
auto &&tets_skin) {
1648 faces, moab::Interface::UNION);
1649 Range trace_faces = subtract(faces, tets_skin);
1653 auto tets = get_tets();
1657 auto trace_faces = get_stress_trace_faces(
1659 subtract_blockset(
"CONTACT",
1660 subtract_boundary_conditions(get_tets_skin()))
1667 boost::make_shared<Range>(subtract(trace_faces, *
contactFaces));
1684 auto add_broken_hdiv_field = [
this, meshset,
1685 broken_hdiv_base](
const std::string
field_name,
1691 auto get_side_map_hdiv = [&]() {
1694 std::pair<EntityType,
1709 get_side_map_hdiv(), MB_TAG_DENSE,
MF_ZERO);
1715 auto add_l2_field = [
this, meshset](
const std::string
field_name,
1716 const int order,
const int dim) {
1725 auto add_h1_field = [
this, meshset](
const std::string
field_name,
1726 const int order,
const int dim) {
1738 auto add_l2_field_by_range = [
this](
const std::string
field_name,
1739 const int order,
const int dim,
1740 const int field_dim,
Range &&r) {
1750 auto add_bubble_field = [
this, meshset](
const std::string
field_name,
1751 const int order,
const int dim) {
1757 auto field_order_table =
1758 const_cast<Field *
>(field_ptr)->getFieldOrderTable();
1759 auto get_cgg_bubble_order_zero = [](
int p) {
return 0; };
1760 auto get_cgg_bubble_order_tet = [](
int p) {
1763 field_order_table[MBVERTEX] = get_cgg_bubble_order_zero;
1764 field_order_table[MBEDGE] = get_cgg_bubble_order_zero;
1765 field_order_table[MBTRI] = get_cgg_bubble_order_zero;
1766 field_order_table[MBTET] = get_cgg_bubble_order_tet;
1773 auto add_user_l2_field = [
this, meshset](
const std::string
field_name,
1774 const int order,
const int dim) {
1780 auto field_order_table =
1781 const_cast<Field *
>(field_ptr)->getFieldOrderTable();
1782 auto zero_dofs = [](
int p) {
return 0; };
1784 field_order_table[MBVERTEX] = zero_dofs;
1785 field_order_table[MBEDGE] = zero_dofs;
1786 field_order_table[MBTRI] = zero_dofs;
1787 field_order_table[MBTET] = dof_l2_tet;
1798 auto get_hybridised_disp = [&]() {
1800 auto skin = subtract_boundary_conditions(get_tets_skin());
1802 faces.merge(intersect(bc.faces, skin));
1806 faces.merge(intersect(bc.faces, skin));
1820 for (
const auto &field :
1822 CHKERR add_user_l2_field(field.name, field.order, field.coefficients);
1824 2, 3, get_hybridised_disp());
1839 plasticLogarithmicStretchCoordinateSize);
1844 "Plastic volumes have not been resolved by "
1845 "resolveDissipationEntities");
1848 CHKERR add_l2_field_by_range(
1870 auto project_ho_geometry = [&](
auto field) {
1876 auto get_adj_front_edges = [&](
auto &front_edges) {
1877 Range front_crack_nodes;
1878 Range crack_front_edges_with_both_nodes_not_at_front;
1883 moab.get_connectivity(front_edges, front_crack_nodes,
true),
1884 "get_connectivity failed");
1885 Range crack_front_edges;
1887 false, crack_front_edges,
1888 moab::Interface::UNION),
1889 "get_adjacencies failed");
1890 Range crack_front_edges_nodes;
1892 crack_front_edges_nodes,
true),
1893 "get_connectivity failed");
1895 crack_front_edges_nodes =
1896 subtract(crack_front_edges_nodes, front_crack_nodes);
1897 Range crack_front_edges_with_both_nodes_not_at_front;
1899 moab.get_adjacencies(crack_front_edges_nodes, 1,
false,
1900 crack_front_edges_with_both_nodes_not_at_front,
1901 moab::Interface::UNION),
1902 "get_adjacencies failed");
1904 crack_front_edges_with_both_nodes_not_at_front = intersect(
1905 crack_front_edges, crack_front_edges_with_both_nodes_not_at_front);
1909 crack_front_edges_with_both_nodes_not_at_front =
send_type(
1910 mField, crack_front_edges_with_both_nodes_not_at_front, MBEDGE);
1912 return std::make_pair(boost::make_shared<Range>(front_crack_nodes),
1913 boost::make_shared<Range>(
1914 crack_front_edges_with_both_nodes_not_at_front));
1917 if ((time -
crackingAddTime) > std::numeric_limits<double>::epsilon()) {
1925 auto [front_vertices, front_adj_edges] = get_adj_front_edges(*
frontEdges);
1930 <<
"Number of crack faces: " <<
crackFaces->size();
1932 <<
"Number of front edges: " <<
frontEdges->size();
1936 <<
"Number of front adjacent edges: " <<
frontAdjEdges->size();
1945 (boost::format(
"crack_faces_%d.vtk") % rank).str(),
1948 (boost::format(
"front_edges_%d.vtk") % rank).str(),
1959 auto set_singular_dofs = [&](
auto &front_adj_edges,
auto &front_vertices) {
1967 MOFEM_LOG(
"EP", Sev::inform) <<
"Singularity eps " << beta;
1972 [&](boost::shared_ptr<FieldEntity> field_entity_ptr) ->
MoFEMErrorCode {
1977 auto nb_dofs = field_entity_ptr->getEntFieldData().size();
1983 if (field_entity_ptr->getNbOfCoeffs() != 3)
1985 "Expected 3 coefficients per edge");
1986 if (nb_dofs % 3 != 0)
1988 "Expected multiple of 3 coefficients per edge");
1991 auto get_conn = [&]() {
1993 const EntityHandle *conn;
1994 CHKERR moab.get_connectivity(field_entity_ptr->getEnt(), conn,
1996 return std::make_pair(conn, num_nodes);
1999 auto get_dir = [&](
auto &&conn_p) {
2000 auto [conn, num_nodes] = conn_p;
2002 CHKERR moab.get_coords(conn, num_nodes, coords);
2004 coords[4] - coords[1],
2005 coords[5] - coords[2]};
2009 auto get_singularity_dof = [&](
auto &&conn_p,
auto &&t_edge_dir) {
2010 auto [conn, num_nodes] = conn_p;
2012 if (front_vertices.find(conn[0]) != front_vertices.end()) {
2013 t_singularity_dof(
i) = t_edge_dir(
i) * (-
eps);
2014 }
else if (front_vertices.find(conn[1]) != front_vertices.end()) {
2015 t_singularity_dof(
i) = t_edge_dir(
i) *
eps;
2017 return t_singularity_dof;
2020 auto t_singularity_dof =
2021 get_singularity_dof(get_conn(), get_dir(get_conn()));
2023 auto field_data = field_entity_ptr->getEntFieldData();
2025 &field_data[0], &field_data[1], &field_data[2]};
2027 t_dof(
i) = t_singularity_dof(
i);
2029 for (
auto n = 1;
n < field_data.size() / 3; ++
n) {
2051#ifdef INCLUDE_MBCOUPLER
2053 double toler = 5.e-10;
2058 <<
"No source mesh specified. Skipping projection";
2065 MOFEM_LOG(
"WORLD", Sev::verbose) <<
"Interpolation Young's modulus tag name: "
2069 MOFEM_LOG(
"WORLD", Sev::verbose) <<
"Using hybrid interpolation: "
2077 auto rval_check_tag = moab.tag_get_handle(tag_name.c_str(), old_interp_tag);
2078 if (rval_check_tag == MB_SUCCESS) {
2080 <<
"Deleting existing tag on target mesh: " << tag_name;
2081 CHKERR moab.tag_delete(old_interp_tag);
2085 int world_rank = -1, world_size = -1;
2086 MPI_Comm_rank(PETSC_COMM_WORLD, &world_rank);
2087 MPI_Comm_size(PETSC_COMM_WORLD, &world_size);
2089 Range original_meshset_ents;
2090 CHKERR moab.get_entities_by_handle(0, original_meshset_ents);
2092 MPI_Comm comm_coupler;
2093 if (world_rank == 0) {
2094 MPI_Comm_split(PETSC_COMM_WORLD, 0, 0, &comm_coupler);
2096 MPI_Comm_split(PETSC_COMM_WORLD, MPI_UNDEFINED, world_rank, &comm_coupler);
2100 ParallelComm *pcomm0 =
nullptr;
2102 if (world_rank == 0) {
2103 pcomm0 =
new ParallelComm(&moab, comm_coupler, &pcomm0_id);
2106 Coupler::Method method;
2109 method = Coupler::CONSTANT;
2112 method = Coupler::LINEAR_FE;
2116 "Unsupported interpolation order");
2120 ierr = MPI_Comm_size(PETSC_COMM_WORLD, &nprocs);
2122 ierr = MPI_Comm_rank(PETSC_COMM_WORLD, &rank);
2133 EntityHandle target_root;
2134 CHKERR moab.create_meshset(MESHSET_SET, target_root);
2136 <<
"Creating target mesh from existing meshset";
2137 Range target_meshset_ents;
2138 CHKERR moab.get_entities_by_handle(0, target_meshset_ents);
2139 CHKERR moab.add_entities(target_root, target_meshset_ents);
2142 std::vector<Tag> interp_tags;
2143 std::vector<int> tag_length;
2144 std::vector<DataType> dtype;
2145 std::vector<TagType> storage;
2148 Range targ_verts, targ_elems;
2149 if (world_rank == 0) {
2150 EntityHandle source_root;
2151 CHKERR moab.create_meshset(MESHSET_SET, source_root);
2153 MOFEM_LOG(
"WORLD", Sev::inform) <<
"Loading source mesh on rank 0";
2154 auto rval_source_mesh = moab.load_file(
2156 if (rval_source_mesh != MB_SUCCESS) {
2157 MOFEM_LOG(
"WORLD", Sev::warning) <<
"Error loading source mesh file: "
2160 MOFEM_LOG(
"WORLD", Sev::inform) <<
"Source mesh loaded.";
2163 CHKERR moab.get_entities_by_dimension(source_root, 3, src_elems);
2165 EntityHandle part_set;
2166 CHKERR pcomm0->create_part(part_set);
2167 CHKERR moab.add_entities(part_set, src_elems);
2169 Range src_elems_part;
2170 CHKERR pcomm0->get_part_entities(src_elems_part, 3);
2173 std::string tag_to_use = iterp_tag_name;
2176 CHKERR moab.tag_get_handle(tag_to_use.c_str(), interp_tag);
2179 CHKERR moab.tag_get_length(interp_tag, interp_tag_len);
2181 if (interp_tag_len != 1 && interp_tag_len != 3 && interp_tag_len != 9) {
2183 "Unsupported interpolation tag length: %d", interp_tag_len);
2187 tag_length.push_back(interp_tag_len);
2188 dtype.push_back(DataType());
2189 storage.push_back(TagType());
2190 interp_tags.push_back(interp_tag);
2191 CHKERR moab.tag_get_data_type(interp_tag, dtype.back());
2192 CHKERR moab.tag_get_type(interp_tag, storage.back());
2195 Coupler mbc(&moab, pcomm0, src_elems_part, 0,
true);
2197 std::vector<double> vpos;
2203 CHKERR moab.get_entities_by_dimension(target_root, 3, targ_elems);
2206 targ_verts = targ_elems;
2208 CHKERR moab.get_adjacencies(targ_elems, 0,
false, targ_verts,
2209 moab::Interface::UNION);
2213 CHKERR pcomm0->get_pstatus_entities(0, PSTATUS_NOT_OWNED, tmp_verts);
2214 targ_verts = subtract(targ_verts, tmp_verts);
2217 num_pts = (int)targ_verts.size();
2218 vpos.resize(3 * targ_verts.size());
2219 CHKERR moab.get_coords(targ_verts, &vpos[0]);
2222 boost::shared_ptr<TupleList> tl_ptr;
2223 tl_ptr = boost::make_shared<TupleList>();
2224 CHKERR mbc.locate_points(&vpos[0], num_pts, 0, toler, tl_ptr.get(),
2228 auto find_missing_points = [&](
Range &targ_verts,
int &num_pts,
2229 std::vector<double> &vpos,
2230 Range &missing_verts) {
2232 int missing_pts_num = 0;
2234 auto vit = targ_verts.begin();
2235 for (; vit != targ_verts.end();
i++) {
2236 if (tl_ptr->vi_rd[3 *
i + 1] == -1) {
2237 missing_verts.insert(*vit);
2238 vit = targ_verts.erase(vit);
2245 int missing_pts_num_global = 0;
2248 if (missing_pts_num_global) {
2250 << missing_pts_num_global
2251 <<
" points in target mesh were not located in source mesh. ";
2254 if (missing_pts_num) {
2255 num_pts = (int)targ_verts.size();
2256 vpos.resize(3 * targ_verts.size());
2257 CHKERR moab.get_coords(targ_verts, &vpos[0]);
2259 CHKERR mbc.locate_points(&vpos[0], num_pts, 0, toler, tl_ptr.get(),
2265 Range missing_verts;
2266 CHKERR find_missing_points(targ_verts, num_pts, vpos, missing_verts);
2268 std::vector<double> source_data(interp_tag_len * src_elems.size(), 0.0);
2269 std::vector<double> target_data(interp_tag_len * num_pts, 0.0);
2271 CHKERR moab.tag_get_data(interp_tag, src_elems, &source_data[0]);
2273 Tag scalar_tag, adj_count_tag;
2275 string scalar_tag_name = string(tag_to_use) +
"_COMP";
2276 CHKERR moab.tag_get_handle(scalar_tag_name.c_str(), 1, MB_TYPE_DOUBLE,
2277 scalar_tag, MB_TAG_CREAT | MB_TAG_DENSE,
2280 string adj_count_tag_name =
"ADJ_COUNT";
2282 CHKERR moab.tag_get_handle(adj_count_tag_name.c_str(), 1, MB_TYPE_DOUBLE,
2283 adj_count_tag, MB_TAG_CREAT | MB_TAG_DENSE,
2288 auto create_scalar_tags = [&](
const Range &src_elems,
2289 const std::vector<double> &source_data,
2293 std::vector<double> source_data_scalar(src_elems.size());
2295 for (
int ielem = 0; ielem < src_elems.size(); ielem++) {
2296 source_data_scalar[ielem] =
2297 source_data[itag + ielem * interp_tag_len];
2301 CHKERR moab.tag_set_data(scalar_tag, src_elems, &source_data_scalar[0]);
2306 CHKERR moab.get_connectivity(src_elems, src_verts,
true);
2308 CHKERR moab.tag_clear_data(scalar_tag, src_verts, &def_scl);
2309 CHKERR moab.tag_clear_data(adj_count_tag, src_verts, &def_adj);
2311 for (
auto &tet : src_elems) {
2312 double tet_data = 0;
2313 CHKERR moab.tag_get_data(scalar_tag, &tet, 1, &tet_data);
2316 CHKERR moab.get_connectivity(&tet, 1, adj_verts,
true);
2318 std::vector<double> adj_vert_data(adj_verts.size(), 0.0);
2319 std::vector<double> adj_vert_count(adj_verts.size(), 0.0);
2321 CHKERR moab.tag_get_data(scalar_tag, adj_verts, &adj_vert_data[0]);
2322 CHKERR moab.tag_get_data(adj_count_tag, adj_verts,
2323 &adj_vert_count[0]);
2325 for (
int ivert = 0; ivert < adj_verts.size(); ivert++) {
2326 adj_vert_data[ivert] += tet_data;
2327 adj_vert_count[ivert] += 1;
2330 CHKERR moab.tag_set_data(scalar_tag, adj_verts, &adj_vert_data[0]);
2331 CHKERR moab.tag_set_data(adj_count_tag, adj_verts,
2332 &adj_vert_count[0]);
2336 std::vector<Tag> tags = {scalar_tag, adj_count_tag};
2337 pcomm0->reduce_tags(tags, tags, MPI_SUM, src_verts);
2339 std::vector<double> src_vert_data(src_verts.size(), 0.0);
2340 std::vector<double> src_vert_adj_count(src_verts.size(), 0.0);
2342 CHKERR moab.tag_get_data(scalar_tag, src_verts, &src_vert_data[0]);
2343 CHKERR moab.tag_get_data(adj_count_tag, src_verts,
2344 &src_vert_adj_count[0]);
2346 for (
int ivert = 0; ivert < src_verts.size(); ivert++) {
2347 src_vert_data[ivert] /= src_vert_adj_count[ivert];
2349 CHKERR moab.tag_set_data(scalar_tag, src_verts, &src_vert_data[0]);
2355 <<
"Performing interpolation for tag: " << tag_to_use;
2357 <<
"Number of target points to interpolate: " << num_pts;
2359 <<
"Interpolation method: "
2360 << (method == Coupler::CONSTANT ?
"constant" :
"linear FE");
2362 <<
"Number of components in tag: " << interp_tag_len;
2365 <<
"Source tag data range: ["
2366 << *std::min_element(source_data.begin(), source_data.end()) <<
", "
2367 << *std::max_element(source_data.begin(), source_data.end()) <<
"]";
2369 for (
int itag = 0; itag < interp_tag_len; itag++) {
2371 CHKERR create_scalar_tags(src_elems, source_data, itag);
2373 std::vector<double> target_data_scalar(num_pts, 0.0);
2374 CHKERR mbc.interpolate(method, scalar_tag_name, &target_data_scalar[0],
2377 for (
int ielem = 0; ielem < num_pts; ielem++) {
2378 target_data[itag + ielem * interp_tag_len] =
2379 target_data_scalar[ielem];
2384 CHKERR moab.tag_set_data(interp_tag, targ_verts, &target_data[0]);
2389 <<
"Using hybrid interpolation for "
2390 "missing points in the target mesh.";
2391 Range missing_adj_elems;
2392 CHKERR moab.get_adjacencies(missing_verts, 3,
false, missing_adj_elems,
2393 moab::Interface::UNION);
2395 int num_adj_elems = (int)missing_adj_elems.size();
2396 std::vector<double> vpos_adj_elems;
2398 vpos_adj_elems.resize(3 * missing_adj_elems.size());
2399 CHKERR moab.get_coords(missing_adj_elems, &vpos_adj_elems[0]);
2403 CHKERR mbc.locate_points(&vpos_adj_elems[0], num_adj_elems, 0, toler,
2404 tl_ptr.get(),
false);
2407 CHKERR find_missing_points(missing_adj_elems, num_adj_elems,
2408 vpos_adj_elems, missing_tets);
2409 if (missing_tets.size()) {
2411 << missing_tets.size()
2412 <<
" points in target mesh were not located in source mesh. ";
2415 std::vector<double> target_data_adj_elems(
2416 interp_tag_len * num_adj_elems, 0.0);
2418 for (
int itag = 0; itag < interp_tag_len; itag++) {
2419 CHKERR create_scalar_tags(src_elems, source_data, itag);
2421 std::vector<double> target_data_adj_elems_scalar(num_adj_elems, 0.0);
2422 CHKERR mbc.interpolate(method, scalar_tag_name,
2423 &target_data_adj_elems_scalar[0],
2426 for (
int ielem = 0; ielem < num_adj_elems; ielem++) {
2427 target_data_adj_elems[itag + ielem * interp_tag_len] =
2428 target_data_adj_elems_scalar[ielem];
2432 CHKERR moab.tag_set_data(interp_tag, missing_adj_elems,
2433 &target_data_adj_elems[0]);
2436 for (
auto &vert : missing_verts) {
2438 CHKERR moab.get_adjacencies(&vert, 1, 3,
false, adj_elems,
2439 moab::Interface::UNION);
2441 std::vector<double> adj_elems_data(adj_elems.size() * interp_tag_len,
2443 CHKERR moab.tag_get_data(interp_tag, adj_elems, &adj_elems_data[0]);
2445 std::vector<double> vert_data(interp_tag_len, 0.0);
2446 for (
int itag = 0; itag < interp_tag_len; itag++) {
2447 for (
int i = 0;
i < adj_elems.size();
i++) {
2448 vert_data[itag] += adj_elems_data[
i * interp_tag_len + itag];
2450 vert_data[itag] /= adj_elems.size();
2452 CHKERR moab.tag_set_data(interp_tag, &vert, 1, &vert_data[0]);
2456 CHKERR moab.tag_delete(scalar_tag);
2457 CHKERR moab.tag_delete(adj_count_tag);
2461 Range src_mesh_ents;
2462 CHKERR moab.get_entities_by_handle(source_root, src_mesh_ents);
2463 CHKERR moab.delete_entities(&source_root, 1);
2464 CHKERR moab.delete_entities(src_mesh_ents);
2465 CHKERR moab.delete_entities(&part_set, 1);
2469 int tag_size = tag_length.size();
2470 MPI_Bcast(&tag_size, 1, MPI_INT, 0, PETSC_COMM_WORLD);
2472 interp_tags.resize(tag_size);
2473 tag_length.resize(tag_size);
2474 dtype.resize(tag_size);
2475 storage.resize(tag_size);
2477 MPI_Bcast(interp_tags.data(), tag_size, MPI_INT, 0, PETSC_COMM_WORLD);
2478 MPI_Bcast(tag_length.data(), tag_size, MPI_INT, 0, PETSC_COMM_WORLD);
2479 MPI_Bcast(dtype.data(), tag_size, MPI_INT, 0, PETSC_COMM_WORLD);
2480 MPI_Bcast(storage.data(), tag_size, MPI_INT, 0, PETSC_COMM_WORLD);
2485 for (
size_t index = 0; index < interp_tags.size(); index++) {
2489 auto rval_check_tag =
2491 if (rval_check_tag == MB_SUCCESS) {
2493 <<
"Deleting existing tag on target mesh (post-projection): "
2495 CHKERR moab.tag_delete(old_interp_tag);
2500 MB_TAG_CREAT | storage[index];
2501 std::vector<double> def_val(tag_length[index], 0.);
2503 tag_length[index], dtype[index],
2504 interp_tag_all, flags, def_val.data());
2505 if (
rval != MB_SUCCESS && world_rank) {
2507 "Unable to create projection tag %s",
2511 MPI_Barrier(PETSC_COMM_WORLD);
2528 CHKERR moab.delete_entities(&target_root, 1);
2535 const bool add_bubble) {
2539 auto add_field_to_fe = [
this](
const std::string fe,
2586 auto set_fe_adjacency = [&](
auto fe_name) {
2589 boost::make_shared<ParentFiniteElementAdjacencyFunctionSkeleton<2>>(
2597 auto add_field_to_fe = [
this](
const std::string fe,
2611 Range natural_bc_elements;
2614 natural_bc_elements.merge(
v.faces);
2619 natural_bc_elements.merge(
v.faces);
2624 natural_bc_elements.merge(
v.faces);
2629 natural_bc_elements.merge(
v.faces);
2634 natural_bc_elements.merge(
v.faces);
2639 natural_bc_elements.merge(
v.faces);
2644 natural_bc_elements.merge(
v.faces);
2649 natural_bc_elements.merge(
v.faces);
2652 natural_bc_elements = intersect(natural_bc_elements, meshset_ents);
2663 auto get_skin = [&](
auto &body_ents) {
2666 CHKERR skin.find_skin(0, body_ents,
false, skin_ents);
2671 Range boundary_ents;
2672 ParallelComm *pcomm =
2674 CHKERR pcomm->filter_pstatus(skin, PSTATUS_SHARED | PSTATUS_MULTISHARED,
2675 PSTATUS_NOT, -1, &boundary_ents);
2676 return boundary_ents;
2735 const EntityHandle meshset) {
2757 auto remove_dofs_on_broken_skin = [&](
const std::string prb_name) {
2759 for (
int d : {0, 1, 2}) {
2760 std::vector<boost::weak_ptr<NumeredDofEntity>> dofs_to_remove;
2762 ->getSideDofsOnBrokenSpaceEntities(
2773 CHKERR remove_dofs_on_broken_skin(
"ESHELBY_PLASTICITY");
2838 auto set_zero_block = [&]() {
2841 auto add_empty_pair = [&](
const std::string &row,
2842 const std::string &col) {
2848 CHKERR problems_manager->addFieldToEmptyFieldBlocks(
2849 "ELASTIC_PROBLEM", col, row);
2853 for (
const auto &[row, col] :
2855 CHKERR add_empty_pair(row, col);
2863 auto set_section = [&]() {
2865 PetscSection section;
2870 CHKERR PetscSectionDestroy(§ion);
2893BcDisp::BcDisp(std::string name, std::vector<double> attr,
Range faces,
2894 std::string load_history_file)
2895 : blockName(name), loadHistoryFile(load_history_file), faces(faces) {
2896 vals.resize(3,
false);
2897 flags.resize(3,
false);
2898 for (
int ii = 0; ii != 3; ++ii) {
2899 vals[ii] = attr[ii];
2900 flags[ii] =
static_cast<int>(attr[ii + 3]);
2903 MOFEM_LOG(
"EP", Sev::inform) <<
"Add BCDisp " << name;
2905 <<
"Add BCDisp vals " <<
vals[0] <<
" " <<
vals[1] <<
" " <<
vals[2];
2907 <<
"Add BCDisp flags " <<
flags[0] <<
" " <<
flags[1] <<
" " <<
flags[2];
2908 MOFEM_LOG(
"EP", Sev::inform) <<
"Add BCDisp nb. of faces " <<
faces.size();
2912 std::string load_history_file)
2913 : blockName(name), loadHistoryFile(load_history_file), faces(faces) {
2914 vals.resize(attr.size(),
false);
2915 for (
int ii = 0; ii != attr.size(); ++ii) {
2916 vals[ii] = attr[ii];
2922 std::string load_history_file)
2923 : blockName(name), loadHistoryFile(load_history_file), faces(faces) {
2924 vals.resize(3,
false);
2925 flags.resize(3,
false);
2926 for (
int ii = 0; ii != 3; ++ii) {
2927 vals[ii] = attr[ii];
2928 flags[ii] =
static_cast<int>(attr[ii + 3]);
2931 MOFEM_LOG(
"EP", Sev::inform) <<
"Add BCForce " << name;
2933 <<
"Add BCForce vals " <<
vals[0] <<
" " <<
vals[1] <<
" " <<
vals[2];
2935 <<
"Add BCForce flags " <<
flags[0] <<
" " <<
flags[1] <<
" " <<
flags[2];
2936 MOFEM_LOG(
"EP", Sev::inform) <<
"Add BCForce nb. of faces " <<
faces.size();
2940 std::vector<double> attr,
2942 std::string load_history_file)
2943 : blockName(name), loadHistoryFile(load_history_file), faces(faces) {
2946 if (attr.size() < 1) {
2948 "Wrong size of normal displacement BC");
2953 MOFEM_LOG(
"EP", Sev::inform) <<
"Add NormalDisplacementBc " << name;
2954 MOFEM_LOG(
"EP", Sev::inform) <<
"Add NormalDisplacementBc val " <<
val;
2956 <<
"Add NormalDisplacementBc nb. of faces " <<
faces.size();
2960 : blockName(name), faces(faces) {
2963 if (attr.size() < 2) {
2965 "Wrong size of spring BC attributes");
2971 MOFEM_LOG(
"EP", Sev::inform) <<
"Add SpringBc " << name;
2974 MOFEM_LOG(
"EP", Sev::inform) <<
"Add SpringBc nb. of faces " <<
faces.size();
2978 std::string load_history_file)
2979 : blockName(name), loadHistoryFile(load_history_file), faces(faces) {
2982 if (attr.size() < 1) {
2984 "Wrong size of normal displacement BC");
2989 MOFEM_LOG(
"EP", Sev::inform) <<
"Add PressureBc " << name;
2990 MOFEM_LOG(
"EP", Sev::inform) <<
"Add PressureBc val " <<
val;
2992 <<
"Add PressureBc nb. of faces " <<
faces.size();
2996 Range ents, std::string load_history_file)
2997 : blockName(name), loadHistoryFile(load_history_file), ents(ents) {
3000 if (attr.size() < 2) {
3002 "Wrong size of external strain attribute");
3008 MOFEM_LOG(
"EP", Sev::inform) <<
"Add ExternalStrain " << name;
3009 MOFEM_LOG(
"EP", Sev::inform) <<
"Add ExternalStrain val " <<
val;
3011 <<
"Add ExternalStrain bulk modulus K " <<
bulkModulusK;
3013 <<
"Add ExternalStrain bulk modulus K " <<
bulkModulusK;
3015 <<
"Add ExternalStrain nb. of tets " <<
ents.size();
3019 std::string name, std::vector<double> attr,
Range faces,
3020 std::string load_history_file)
3021 : blockName(name), faces(faces) {
3022 (void)load_history_file;
3023 if (attr.size() < 3) {
3025 "Wrong size of analytical displacement BC");
3028 flags.resize(3,
false);
3029 for (
int ii = 0; ii != 3; ++ii) {
3030 flags[ii] = attr[ii];
3033 MOFEM_LOG(
"EP", Sev::inform) <<
"Add AnalyticalDisplacementBc " << name;
3035 <<
"Add AnalyticalDisplacementBc flags " <<
flags[0] <<
" " <<
flags[1]
3038 <<
"Add AnalyticalDisplacementBc nb. of faces " <<
faces.size();
3042 std::vector<double> attr,
3044 std::string load_history_file)
3045 : blockName(name), faces(faces) {
3046 (void)load_history_file;
3047 flags.resize(3,
false);
3048 for (
int ii = 0; ii != 3; ++ii) {
3049 flags[ii] = attr.size() < 3 ? 1 : attr[ii];
3052 MOFEM_LOG(
"EP", Sev::inform) <<
"Add AnalyticalTractionBc " << name;
3053 MOFEM_LOG(
"EP", Sev::inform) <<
"Add AnalyticalTractionBc flags " <<
flags[0]
3056 <<
"Add AnalyticalTractionBc nb. of faces " <<
faces.size();
3061 boost::shared_ptr<TractionFreeBc> &bc_ptr,
3062 const std::string contact_set_name) {
3067 CHKERR mField.get_moab().get_entities_by_type(meshset, MBTET, tets);
3068 Range tets_skin_part;
3069 Skinner skin(&mField.get_moab());
3070 CHKERR skin.find_skin(0, tets,
false, tets_skin_part);
3071 ParallelComm *pcomm =
3074 CHKERR pcomm->filter_pstatus(tets_skin_part,
3075 PSTATUS_SHARED | PSTATUS_MULTISHARED,
3076 PSTATUS_NOT, -1, &tets_skin);
3079 for (
int dd = 0; dd != 3; ++dd)
3080 (*bc_ptr)[dd] = tets_skin;
3083 if (bcSpatialDispVecPtr)
3084 for (
auto &
v : *bcSpatialDispVecPtr) {
3086 (*bc_ptr)[0] = subtract((*bc_ptr)[0],
v.faces);
3088 (*bc_ptr)[1] = subtract((*bc_ptr)[1],
v.faces);
3090 (*bc_ptr)[2] = subtract((*bc_ptr)[2],
v.faces);
3094 if (bcSpatialRotationVecPtr)
3095 for (
auto &
v : *bcSpatialRotationVecPtr) {
3096 (*bc_ptr)[0] = subtract((*bc_ptr)[0],
v.faces);
3097 (*bc_ptr)[1] = subtract((*bc_ptr)[1],
v.faces);
3098 (*bc_ptr)[2] = subtract((*bc_ptr)[2],
v.faces);
3101 if (bcSpatialNormalDisplacementVecPtr)
3102 for (
auto &
v : *bcSpatialNormalDisplacementVecPtr) {
3103 (*bc_ptr)[0] = subtract((*bc_ptr)[0],
v.faces);
3104 (*bc_ptr)[1] = subtract((*bc_ptr)[1],
v.faces);
3105 (*bc_ptr)[2] = subtract((*bc_ptr)[2],
v.faces);
3108 if (bcSpatialAnalyticalDisplacementVecPtr)
3109 for (
auto &
v : *bcSpatialAnalyticalDisplacementVecPtr) {
3111 (*bc_ptr)[0] = subtract((*bc_ptr)[0],
v.faces);
3113 (*bc_ptr)[1] = subtract((*bc_ptr)[1],
v.faces);
3115 (*bc_ptr)[2] = subtract((*bc_ptr)[2],
v.faces);
3118 if (bcSpatialTractionVecPtr)
3119 for (
auto &
v : *bcSpatialTractionVecPtr) {
3120 (*bc_ptr)[0] = subtract((*bc_ptr)[0],
v.faces);
3121 (*bc_ptr)[1] = subtract((*bc_ptr)[1],
v.faces);
3122 (*bc_ptr)[2] = subtract((*bc_ptr)[2],
v.faces);
3125 if (bcSpatialSpringVecPtr)
3126 for (
auto &
v : *bcSpatialSpringVecPtr) {
3127 (*bc_ptr)[0] = subtract((*bc_ptr)[0],
v.faces);
3128 (*bc_ptr)[1] = subtract((*bc_ptr)[1],
v.faces);
3129 (*bc_ptr)[2] = subtract((*bc_ptr)[2],
v.faces);
3132 if (bcSpatialAnalyticalTractionVecPtr)
3133 for (
auto &
v : *bcSpatialAnalyticalTractionVecPtr) {
3134 (*bc_ptr)[0] = subtract((*bc_ptr)[0],
v.faces);
3135 (*bc_ptr)[1] = subtract((*bc_ptr)[1],
v.faces);
3136 (*bc_ptr)[2] = subtract((*bc_ptr)[2],
v.faces);
3139 if (bcSpatialPressureVecPtr)
3140 for (
auto &
v : *bcSpatialPressureVecPtr) {
3141 (*bc_ptr)[0] = subtract((*bc_ptr)[0],
v.faces);
3142 (*bc_ptr)[1] = subtract((*bc_ptr)[1],
v.faces);
3143 (*bc_ptr)[2] = subtract((*bc_ptr)[2],
v.faces);
3148 std::regex((boost::format(
"%s(.*)") % contact_set_name).str()))) {
3150 CHKERR m->getMeshsetIdEntitiesByDimension(mField.get_moab(), 2, faces,
3152 (*bc_ptr)[0] = subtract((*bc_ptr)[0], faces);
3153 (*bc_ptr)[1] = subtract((*bc_ptr)[1], faces);
3154 (*bc_ptr)[2] = subtract((*bc_ptr)[2], faces);
3167 "Plastic-flow increment operator has a null integration-point "
3173 const int nb_integration_pts =
getGaussPts().size2();
3174 auto t_h_p =
dataAtPts->getFTensorPlasticH(nb_integration_pts);
3178 *
dataAtPts->getPlasticFlow(), nb_integration_pts);
3179 auto t_flow = get_flow();
3181 for (
int gg = 0; gg != nb_integration_pts; ++gg) {
3182 t_h_p(
i,
j) += t_flow(
i,
j);
3194 const int tag,
const bool do_rhs,
const bool do_lhs,
const bool calc_rates,
3195 boost::shared_ptr<VolumeElementForcesAndSourcesCore> fe,
3196 const bool add_bubble) {
3200 boost::make_shared<CGGUserPolynomialBase::CachePhi>(0, 0,
MatrixDouble());
3201 fe->getUserPolynomialBase() =
3202 boost::make_shared<CGGUserPolynomialBase>(bubble_cache);
3203 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
3204 fe->getOpPtrVector(), {HDIV, H1, L2}, materialH1Positions, frontAdjEdges);
3207 fe->getRuleHook = [](int, int, int) {
return -1; };
3208 fe->setRuleHook = SetIntegrationAtFrontVolume(frontVertices, frontAdjEdges,
3215 dataAtPts->physicsPtr = physicalEquations;
3219 piolaStress,
dataAtPts->getApproxPAtPts()));
3222 bubbleField,
dataAtPts->getApproxPAtPts(), MBMAXTYPE));
3225 piolaStress,
dataAtPts->getDivPAtPts()));
3227 rotAxis,
dataAtPts->getRotAxisAtPts(), MBTET));
3229 CHKERR VecSetDM(solTSStep, PETSC_NULLPTR);
3231 piolaStress,
dataAtPts->getApproxP0AtPts(),
nullptr, solTSStep));
3232 CHKERR physicalEquations->pushMaterialFields(
3238 CHKERR physicalEquations->pushMaterialFields(*
this, fe->getOpPtrVector(),
3242 rotAxis,
dataAtPts->getRotAxis0AtPts(), solTSStep, MBTET));
3244 rotAxis,
dataAtPts->getRotAxisGradAtPts(), MBTET));
3246 spatialL2Disp,
dataAtPts->getSmallWL2AtPts(), MBTET));
3250 spatialH1Disp,
dataAtPts->getSmallWH1AtPts()));
3252 spatialH1Disp,
dataAtPts->getSmallWGradH1AtPts()));
3257 spatialL2Disp,
dataAtPts->getSmallWL2DotAtPts(), MBTET));
3258 CHKERR physicalEquations->pushMaterialRates(*
this, fe->getOpPtrVector(),
3261 rotAxis,
dataAtPts->getRotAxisDotAtPts(), MBTET));
3263 rotAxis,
dataAtPts->getRotAxisGradDotAtPts(), MBTET));
3266 if (std::abs(alphaRho) > std::numeric_limits<double>::epsilon()) {
3268 spatialL2Disp,
dataAtPts->getSmallWL2DotDotAtPts(), MBTET));
3274 fe->getOpPtrVector(), plasticHField,
dataAtPts->getPlasticH(), MBTET);
3275 if (plasticVolume && dmIncrementalOptimization && incrementalTrialControl) {
3277 fe->getOpPtrVector(), plasticFlowField,
dataAtPts->getPlasticFlow(),
3278 MBTET, dmIncrementalOptimization, incrementalTrialControl);
3279 fe->getOpPtrVector().push_back(
new OpApplyPlasticFlowIncrement(
dataAtPts));
3281 fe->getOpPtrVector().push_back(
3285 CHKERR physicalEquations->pushMaterialEvaluation(*
this, fe->getOpPtrVector(),
3292 boost::shared_ptr<VolumeElementForcesAndSourcesCore> fe_lhs) {
3295 CHKERR physicalEquations->pushMaterialTangent(*
this, fe_lhs->getOpPtrVector(),
3299 spatialL2Disp, piolaStress,
dataAtPts,
true));
3301 spatialL2Disp, spatialL2Disp,
dataAtPts, alphaW, alphaRho));
3305 symmetrySelector ==
SYMMETRIC ?
true :
false));
3308 symmetrySelector ==
SYMMETRIC ?
true :
false));
3312 rotAxis, piolaStress,
dataAtPts,
false));
3314 rotAxis, bubbleField,
dataAtPts,
false));
3317 rotAxis, rotAxis,
dataAtPts, alphaR, alphaOmega, alphaViscousR,
3318 alphaViscousOmega));
3324 boost::shared_ptr<VolumeElementForcesAndSourcesCore> fe_lhs) {
3326 CHKERR pushPiolaStressGramOps(fe_lhs);
3327 fe_lhs->getOpPtrVector().push_back(
3329 fe_lhs->getOpPtrVector().push_back(
3335 boost::shared_ptr<VolumeElementForcesAndSourcesCore> fe_lhs) {
3337 fe_lhs->getOpPtrVector().push_back(
3343 const int tag,
const bool add_elastic,
const bool add_material,
3344 boost::shared_ptr<VolumeElementForcesAndSourcesCore> &fe_rhs,
3345 boost::shared_ptr<VolumeElementForcesAndSourcesCore> &fe_lhs) {
3348 CHKERR physicalEquations->checkSetup(*
this);
3350 auto local_tau_sacale = boost::make_shared<double>(1.0);
3353 using BdyEleOp = BoundaryEle::UserDataOperator;
3354 struct OpSetTauScale :
public BdyEleOp {
3355 OpSetTauScale(boost::shared_ptr<double> local_tau_sacale,
3356 boost::shared_ptr<MatrixDouble> piola_stress_at_pts,
3357 double alpha_tau,
double alpha_tau_lin)
3359 localTauSacale(local_tau_sacale),
3360 piolaStressAtPts(piola_stress_at_pts), alphaTau(alpha_tau),
3361 alphaTauLin(alpha_tau_lin) {}
3365 auto &coords = BdyEleOp::getCoords();
3366 auto [centre, barycenter,
h] =
3369 if (PetscUnlikely(
h <= 0))
3371 "Non-positive characteristic face size");
3373 double mean_normal_traction = 0;
3374 if (alphaTauLin > 0) {
3375 if (PetscUnlikely(!piolaStressAtPts))
3377 "Piola stress is not available for tau scaling");
3379 const auto nb_gauss_pts = BdyEleOp::getGaussPts().size2();
3384 *piolaStressAtPts, nb_gauss_pts);
3385 auto t_piola = get_piola();
3386 auto t_normal = BdyEleOp::getFTensor1NormalsAtGaussPts();
3387 auto t_w = BdyEleOp::getFTensor0IntegrationWeight();
3390 double face_measure = 0;
3391 double integrated_normal_traction = 0;
3392 for (
int gg = 0; gg != nb_gauss_pts; ++gg) {
3393 const double normal_norm = t_normal.l2();
3394 if (PetscUnlikely(normal_norm <= 0))
3396 "Face normal has non-positive length");
3399 t_unit_normal(
i) = t_normal(
i) / normal_norm;
3400 const double dA = t_w * BdyEleOp::getMeasure();
3402 integrated_normal_traction +=
3403 dA * std::abs(t_unit_normal(
i) * t_piola(
i,
J) *
3411 if (PetscUnlikely(face_measure <= 0))
3413 "Face has non-positive measure");
3414 mean_normal_traction = integrated_normal_traction / face_measure;
3417 *localTauSacale = (alphaTau + alphaTauLin * mean_normal_traction) /
h;
3423 boost::shared_ptr<double> localTauSacale;
3424 boost::shared_ptr<MatrixDouble> piolaStressAtPts;
3429 auto add_tau_stress_producer = [&](
auto &pip) {
3431 auto piola_stress_at_pts =
dataAtPts->getApproxP0AtPts();
3432 if (alphaTauLin > 0)
3434 piolaStress, piola_stress_at_pts,
nullptr, solTSStep));
3435 return piola_stress_at_pts;
3438 auto not_interface_face = [
this](
FEMethod *fe_method_ptr) {
3439 auto ent = fe_method_ptr->getFEEntityHandle();
3442 (interfaceFaces->find(ent) != interfaceFaces->end())
3444 || (crackFaces->find(ent) != crackFaces->end())
3453 fe_rhs = boost::make_shared<VolumeElementForcesAndSourcesCore>(mField);
3454 CHKERR setBaseVolumeElementOps(tag,
true,
false,
true, fe_rhs);
3459 fe_rhs->getOpPtrVector().push_back(
3462 rotAxis,
dataAtPts, alphaR, alphaOmega, alphaViscousR,
3463 alphaViscousOmega));
3464 CHKERR physicalEquations->pushMaterialResidual(
3465 *
this, fe_rhs->getOpPtrVector(),
dataAtPts);
3466 fe_rhs->getOpPtrVector().push_back(
3468 fe_rhs->getOpPtrVector().push_back(
3470 fe_rhs->getOpPtrVector().push_back(
3473 auto set_hybridisation_rhs = [&](
auto &pip) {
3480 using SideEleOp = EleOnSide::UserDataOperator;
3481 using BdyEleOp = BoundaryEle::UserDataOperator;
3486 mField, skeletonElement,
SPACE_DIM - 1, Sev::noisy);
3487 op_loop_skeleton_side->getSideFEPtr()->getRuleHook = [](int, int, int) {
3490 op_loop_skeleton_side->getSideFEPtr()->setRuleHook =
3491 SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
3493 CHKERR EshelbianPlasticity::
3494 AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
3495 op_loop_skeleton_side->getOpPtrVector(), {L2},
3496 materialH1Positions, frontAdjEdges);
3500 auto broken_data_ptr =
3501 boost::make_shared<std::vector<BrokenBaseSideData>>();
3504 mField, elementVolumeName,
SPACE_DIM, Sev::noisy);
3505 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
3506 boost::make_shared<CGGUserPolynomialBase>(
nullptr,
true);
3508 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
3509 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
3510 materialH1Positions, frontAdjEdges);
3511 op_loop_domain_side->getOpPtrVector().push_back(
3513 auto flux_mat_ptr = boost::make_shared<MatrixDouble>();
3514 op_loop_domain_side->getOpPtrVector().push_back(
3517 op_loop_domain_side->getOpPtrVector().push_back(
3521 op_loop_skeleton_side->getOpPtrVector().push_back(op_loop_domain_side);
3523 GAUSS>::OpBrokenSpaceConstrainDHybrid<SPACE_DIM>;
3525 GAUSS>::OpBrokenSpaceConstrainDFlux<SPACE_DIM>;
3526 op_loop_skeleton_side->getOpPtrVector().push_back(
new OpC_dHybrid(
3527 hybridSpatialDisp, broken_data_ptr, boost::make_shared<double>(1.0)));
3528 auto hybrid_ptr = boost::make_shared<MatrixDouble>();
3529 op_loop_skeleton_side->getOpPtrVector().push_back(
3532 op_loop_skeleton_side->getOpPtrVector().push_back(
new OpC_dBroken(
3533 broken_data_ptr, hybrid_ptr, boost::make_shared<double>(1.0)));
3536 pip.push_back(op_loop_skeleton_side);
3541 auto set_tau_stabilsation_rhs = [&](
auto &pip,
auto side_fe_name,
3542 auto hybrid_field) {
3549 using SideEleOp = EleOnSide::UserDataOperator;
3550 using BdyEleOp = BoundaryEle::UserDataOperator;
3555 mField, side_fe_name,
SPACE_DIM - 1, Sev::noisy);
3556 op_loop_skeleton_side->getSideFEPtr()->getRuleHook = [](int, int, int) {
3559 op_loop_skeleton_side->getSideFEPtr()->setRuleHook =
3560 SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
3561 op_loop_skeleton_side->getSideFEPtr()->exeTestHook = not_interface_face;
3562 CHKERR EshelbianPlasticity::
3563 AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
3564 op_loop_skeleton_side->getOpPtrVector(), {L2},
3565 materialH1Positions, frontAdjEdges);
3568 mField, elementVolumeName,
SPACE_DIM, Sev::noisy);
3569 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
3570 boost::make_shared<CGGUserPolynomialBase>(
nullptr,
true);
3572 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
3573 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
3574 materialH1Positions, frontAdjEdges);
3577 auto broken_disp_data_ptr =
3578 boost::make_shared<std::vector<BrokenBaseSideData>>();
3579 op_loop_domain_side->getOpPtrVector().push_back(
3581 broken_disp_data_ptr));
3582 auto disp_mat_ptr = boost::make_shared<MatrixDouble>();
3583 op_loop_domain_side->getOpPtrVector().push_back(
3587 op_loop_domain_side->getOpPtrVector().push_back(
3589 auto piola_stress_at_pts =
3590 add_tau_stress_producer(op_loop_domain_side->getOpPtrVector());
3591 op_loop_skeleton_side->getOpPtrVector().push_back(op_loop_domain_side);
3592 op_loop_skeleton_side->getOpPtrVector().push_back(
3593 new OpSetTauScale(local_tau_sacale, piola_stress_at_pts, alphaTau,
3597 auto hybrid_ptr = boost::make_shared<MatrixDouble>();
3598 op_loop_skeleton_side->getOpPtrVector().push_back(
3603 op_loop_skeleton_side->getOpPtrVector().push_back(
3605 hybrid_field, hybrid_ptr,
3606 [local_tau_sacale, broken_disp_data_ptr](
double,
double,
double) {
3607 return broken_disp_data_ptr->size() * (*local_tau_sacale);
3610 op_loop_skeleton_side->getOpPtrVector().push_back(
3612 broken_disp_data_ptr, [local_tau_sacale](
double,
double,
double) {
3613 return (*local_tau_sacale);
3616 op_loop_skeleton_side->getOpPtrVector().push_back(
3618 hybrid_field, broken_disp_data_ptr,
3619 [local_tau_sacale](
double,
double,
double) {
3620 return -(*local_tau_sacale);
3623 op_loop_skeleton_side->getOpPtrVector().push_back(
3625 broken_disp_data_ptr, hybrid_ptr,
3626 [local_tau_sacale](
double,
double,
double) {
3627 return -(*local_tau_sacale);
3631 pip.push_back(op_loop_skeleton_side);
3636 auto set_tau_stabilsation_disp_bc_rhs = [&](
auto &pip,
auto side_fe_name) {
3643 using SideEleOp = EleOnSide::UserDataOperator;
3644 using BdyEleOp = BoundaryEle::UserDataOperator;
3649 mField, side_fe_name,
SPACE_DIM - 1, Sev::noisy);
3650 op_loop_skeleton_side->getSideFEPtr()->getRuleHook = [](int, int, int) {
3653 op_loop_skeleton_side->getSideFEPtr()->setRuleHook =
3654 SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
3655 op_loop_skeleton_side->getSideFEPtr()->exeTestHook = not_interface_face;
3656 CHKERR EshelbianPlasticity::
3657 AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
3658 op_loop_skeleton_side->getOpPtrVector(), {L2},
3659 materialH1Positions, frontAdjEdges);
3662 mField, elementVolumeName,
SPACE_DIM, Sev::noisy);
3663 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
3664 boost::make_shared<CGGUserPolynomialBase>(
nullptr,
true);
3666 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
3667 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
3668 materialH1Positions, frontAdjEdges);
3671 auto broken_disp_data_ptr =
3672 boost::make_shared<std::vector<BrokenBaseSideData>>();
3673 op_loop_domain_side->getOpPtrVector().push_back(
3675 broken_disp_data_ptr));
3676 auto disp_mat_ptr = boost::make_shared<MatrixDouble>();
3677 op_loop_domain_side->getOpPtrVector().push_back(
3681 op_loop_domain_side->getOpPtrVector().push_back(
3684 auto piola_stress_at_pts =
3685 add_tau_stress_producer(op_loop_domain_side->getOpPtrVector());
3687 op_loop_skeleton_side->getOpPtrVector().push_back(op_loop_domain_side);
3688 op_loop_skeleton_side->getOpPtrVector().push_back(
3689 new OpSetTauScale(local_tau_sacale, piola_stress_at_pts,
3690 alphaTauBcDisp, alphaTauLin));
3693 op_loop_skeleton_side->getOpPtrVector().push_back(
3695 broken_disp_data_ptr, bcSpatialDispVecPtr, timeScaleMap,
3696 [local_tau_sacale](
double,
double,
double) {
3697 return (*local_tau_sacale);
3699 op_loop_skeleton_side->getOpPtrVector().push_back(
3701 broken_disp_data_ptr, bcSpatialAnalyticalDisplacementVecPtr,
3702 timeScaleMap, [local_tau_sacale](
double,
double,
double) {
3703 return (*local_tau_sacale);
3705 op_loop_skeleton_side->getOpPtrVector().push_back(
3707 broken_disp_data_ptr, bcSpatialRotationVecPtr, timeScaleMap,
3708 [local_tau_sacale](
double,
double,
double) {
3709 return (*local_tau_sacale);
3713 pip.push_back(op_loop_skeleton_side);
3718 auto set_contact_rhs = [&](
auto &pip) {
3722 CHKERR set_hybridisation_rhs(fe_rhs->getOpPtrVector());
3723 CHKERR set_contact_rhs(fe_rhs->getOpPtrVector());
3724 if (alphaTau > 0.0 || alphaTauLin > 0.0) {
3725 CHKERR set_tau_stabilsation_rhs(fe_rhs->getOpPtrVector(), skeletonElement,
3728 if (alphaTauBcDisp > 0.0 || alphaTauLin > 0.0) {
3729 CHKERR set_tau_stabilsation_disp_bc_rhs(fe_rhs->getOpPtrVector(),
3733 using BodyNaturalBC =
3735 Assembly<PETSC>::LinearForm<
GAUSS>;
3737 BodyNaturalBC::OpFlux<NaturalMeshsetType<BLOCKSET>, 1, 3>;
3739 std::string body_force_history;
3740 CHKERR getStringArgumentFromJsonBlocksets(
"BODY_FORCE",
"load_history",
3741 body_force_history);
3742 if (body_force_history.empty()) {
3743 body_force_history =
"body_force.txt";
3746 <<
"Body force load history from JSON: " << body_force_history;
3748 auto body_time_scale =
3749 boost::make_shared<DynamicRelaxationTimeScale>(body_force_history);
3750 CHKERR BodyNaturalBC::AddFluxToPipeline<OpBodyForce>::add(
3751 fe_rhs->getOpPtrVector(), mField, spatialL2Disp, {body_time_scale},
3752 "BODY_FORCE", Sev::inform);
3756 fe_lhs = boost::make_shared<VolumeElementForcesAndSourcesCore>(mField);
3757 CHKERR setBaseVolumeElementOps(tag,
true,
true,
true, fe_lhs);
3762 CHKERR pushVolumeA00Ops(fe_lhs);
3764 auto set_hybridisation_lhs = [&](
auto &pip) {
3771 using SideEleOp = EleOnSide::UserDataOperator;
3772 using BdyEleOp = BoundaryEle::UserDataOperator;
3777 mField, skeletonElement,
SPACE_DIM - 1, Sev::noisy);
3778 op_loop_skeleton_side->getSideFEPtr()->getRuleHook = [](int, int, int) {
3781 op_loop_skeleton_side->getSideFEPtr()->setRuleHook =
3782 SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
3783 CHKERR EshelbianPlasticity::
3784 AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
3785 op_loop_skeleton_side->getOpPtrVector(), {L2},
3786 materialH1Positions, frontAdjEdges);
3790 auto broken_data_ptr =
3791 boost::make_shared<std::vector<BrokenBaseSideData>>();
3794 mField, elementVolumeName,
SPACE_DIM, Sev::noisy);
3795 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
3796 boost::make_shared<CGGUserPolynomialBase>(
nullptr,
true);
3798 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
3799 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
3800 materialH1Positions, frontAdjEdges);
3801 op_loop_domain_side->getOpPtrVector().push_back(
3804 op_loop_skeleton_side->getOpPtrVector().push_back(op_loop_domain_side);
3806 GAUSS>::OpBrokenSpaceConstrain<SPACE_DIM>;
3807 op_loop_skeleton_side->getOpPtrVector().push_back(
3808 new OpC(hybridSpatialDisp, broken_data_ptr,
3809 boost::make_shared<double>(1.0),
true,
false));
3811 pip.push_back(op_loop_skeleton_side);
3816 auto set_tau_stabilsation_lhs = [&](
auto &pip,
auto side_fe_name,
3817 auto hybrid_field) {
3824 using SideEleOp = EleOnSide::UserDataOperator;
3825 using BdyEleOp = BoundaryEle::UserDataOperator;
3830 mField, side_fe_name,
SPACE_DIM - 1, Sev::noisy);
3831 op_loop_skeleton_side->getSideFEPtr()->getRuleHook = [](int, int, int) {
3834 op_loop_skeleton_side->getSideFEPtr()->setRuleHook =
3835 SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
3836 op_loop_skeleton_side->getSideFEPtr()->exeTestHook = not_interface_face;
3837 CHKERR EshelbianPlasticity::
3838 AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
3839 op_loop_skeleton_side->getOpPtrVector(), {L2},
3840 materialH1Positions, frontAdjEdges);
3844 mField, elementVolumeName,
SPACE_DIM, Sev::noisy);
3845 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
3846 boost::make_shared<CGGUserPolynomialBase>(
nullptr,
true);
3848 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
3849 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
3850 materialH1Positions, frontAdjEdges);
3852 auto broken_disp_data_ptr =
3853 boost::make_shared<std::vector<BrokenBaseSideData>>();
3854 op_loop_domain_side->getOpPtrVector().push_back(
3856 broken_disp_data_ptr));
3857 auto piola_stress_at_pts =
3858 add_tau_stress_producer(op_loop_domain_side->getOpPtrVector());
3859 op_loop_skeleton_side->getOpPtrVector().push_back(op_loop_domain_side);
3860 op_loop_skeleton_side->getOpPtrVector().push_back(
3861 new OpSetTauScale(local_tau_sacale, piola_stress_at_pts, alphaTau,
3866 hybrid_field, hybrid_field,
3867 [local_tau_sacale, broken_disp_data_ptr](
double,
double,
double) {
3868 return broken_disp_data_ptr->size() * (*local_tau_sacale);
3871 op_loop_skeleton_side->getOpPtrVector().push_back(
3873 broken_disp_data_ptr, [local_tau_sacale](
double,
double,
double) {
3874 return (*local_tau_sacale);
3877 op_loop_skeleton_side->getOpPtrVector().push_back(
3879 hybrid_field, broken_disp_data_ptr,
3880 [local_tau_sacale](
double,
double,
double) {
3881 return -(*local_tau_sacale);
3885 op_loop_skeleton_side->getOpPtrVector().push_back(
3887 hybrid_field, broken_disp_data_ptr,
3888 [local_tau_sacale](
double,
double,
double) {
3889 return -(*local_tau_sacale);
3893 pip.push_back(op_loop_skeleton_side);
3898 auto set_tau_stabilsation_disp_bc_lhs = [&](
auto &pip,
auto side_fe_name) {
3905 using SideEleOp = EleOnSide::UserDataOperator;
3906 using BdyEleOp = BoundaryEle::UserDataOperator;
3911 mField, side_fe_name,
SPACE_DIM - 1, Sev::noisy);
3912 op_loop_skeleton_side->getSideFEPtr()->getRuleHook = [](int, int, int) {
3915 op_loop_skeleton_side->getSideFEPtr()->setRuleHook =
3916 SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
3917 op_loop_skeleton_side->getSideFEPtr()->exeTestHook = not_interface_face;
3918 CHKERR EshelbianPlasticity::
3919 AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
3920 op_loop_skeleton_side->getOpPtrVector(), {L2},
3921 materialH1Positions, frontAdjEdges);
3925 mField, elementVolumeName,
SPACE_DIM, Sev::noisy);
3926 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
3927 boost::make_shared<CGGUserPolynomialBase>(
nullptr,
true);
3929 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
3930 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
3931 materialH1Positions, frontAdjEdges);
3933 auto broken_disp_data_ptr =
3934 boost::make_shared<std::vector<BrokenBaseSideData>>();
3935 op_loop_domain_side->getOpPtrVector().push_back(
3937 broken_disp_data_ptr));
3938 auto piola_stress_at_pts =
3939 add_tau_stress_producer(op_loop_domain_side->getOpPtrVector());
3940 op_loop_skeleton_side->getOpPtrVector().push_back(op_loop_domain_side);
3941 op_loop_skeleton_side->getOpPtrVector().push_back(
3942 new OpSetTauScale(local_tau_sacale, piola_stress_at_pts,
3943 alphaTauBcDisp, alphaTauLin));
3946 op_loop_skeleton_side->getOpPtrVector().push_back(
3948 broken_disp_data_ptr, bcSpatialDispVecPtr,
3949 [local_tau_sacale](
double,
double,
double) {
3950 return (*local_tau_sacale);
3952 op_loop_skeleton_side->getOpPtrVector().push_back(
3954 broken_disp_data_ptr, bcSpatialAnalyticalDisplacementVecPtr,
3955 [local_tau_sacale](
double,
double,
double) {
3956 return (*local_tau_sacale);
3958 op_loop_skeleton_side->getOpPtrVector().push_back(
3960 broken_disp_data_ptr, bcSpatialRotationVecPtr,
3961 [local_tau_sacale](
double,
double,
double) {
3962 return (*local_tau_sacale);
3965 pip.push_back(op_loop_skeleton_side);
3970 auto set_contact_lhs = [&](
auto &pip) {
3974 CHKERR set_hybridisation_lhs(fe_lhs->getOpPtrVector());
3975 CHKERR set_contact_lhs(fe_lhs->getOpPtrVector());
3976 if (alphaTau > 0.0 || alphaTauLin > 0.0) {
3977 CHKERR set_tau_stabilsation_lhs(fe_lhs->getOpPtrVector(), skeletonElement,
3980 if (alphaTauBcDisp > 0.0 || alphaTauLin > 0.0) {
3981 CHKERR set_tau_stabilsation_disp_bc_lhs(fe_lhs->getOpPtrVector(),
3993 const bool add_elastic,
const bool add_material,
3994 boost::shared_ptr<FaceElementForcesAndSourcesCore> &fe_rhs,
3995 boost::shared_ptr<FaceElementForcesAndSourcesCore> &fe_lhs) {
3998 fe_rhs = boost::make_shared<FaceElementForcesAndSourcesCore>(mField);
3999 fe_lhs = boost::make_shared<FaceElementForcesAndSourcesCore>(mField);
4004 fe_rhs->getRuleHook = [](int, int, int) {
return -1; };
4005 fe_lhs->getRuleHook = [](int, int, int) {
return -1; };
4006 fe_rhs->setRuleHook = SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
4007 fe_lhs->setRuleHook = SetIntegrationAtFrontFace(frontVertices, frontAdjEdges);
4010 EshelbianPlasticity::AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
4011 fe_rhs->getOpPtrVector(), {L2}, materialH1Positions, frontAdjEdges);
4013 EshelbianPlasticity::AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
4014 fe_lhs->getOpPtrVector(), {L2}, materialH1Positions, frontAdjEdges);
4018 auto get_broken_op_side = [
this](
auto &pip) {
4021 using SideEleOp = EleOnSide::UserDataOperator;
4023 auto broken_data_ptr =
4024 boost::make_shared<std::vector<BrokenBaseSideData>>();
4027 mField, elementVolumeName,
SPACE_DIM, Sev::noisy);
4028 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
4029 boost::make_shared<CGGUserPolynomialBase>(
nullptr,
true);
4031 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
4032 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
4033 materialH1Positions, frontAdjEdges);
4034 op_loop_domain_side->getOpPtrVector().push_back(
4036 auto flux_mat_ptr = boost::make_shared<MatrixDouble>();
4037 op_loop_domain_side->getOpPtrVector().push_back(
4040 op_loop_domain_side->getOpPtrVector().push_back(
4042 pip.push_back(op_loop_domain_side);
4043 return broken_data_ptr;
4046 auto set_rhs = [&]() {
4049 auto broken_data_ptr = get_broken_op_side(fe_rhs->getOpPtrVector());
4051 fe_rhs->getOpPtrVector().push_back(
4052 new OpDispBc(broken_data_ptr, bcSpatialDispVecPtr, timeScaleMap));
4054 broken_data_ptr, bcSpatialAnalyticalDisplacementVecPtr,
4057 broken_data_ptr, bcSpatialRotationVecPtr, timeScaleMap));
4059 auto piola_scale_ptr = boost::make_shared<double>(1.0);
4060 fe_rhs->getOpPtrVector().push_back(
4062 piola_scale_ptr, timeScaleMap));
4063 auto hybrid_grad_ptr = boost::make_shared<MatrixDouble>();
4065 fe_rhs->getOpPtrVector().push_back(
4067 hybridSpatialDisp, hybrid_grad_ptr));
4069 hybridSpatialDisp, bcSpatialPressureVecPtr, piola_scale_ptr,
4070 hybrid_grad_ptr, timeScaleMap));
4072 hybridSpatialDisp, bcSpatialAnalyticalTractionVecPtr, piola_scale_ptr,
4075 auto hybrid_ptr = boost::make_shared<MatrixDouble>();
4076 fe_rhs->getOpPtrVector().push_back(
4080 hybridSpatialDisp, hybrid_ptr, broken_data_ptr,
4081 bcSpatialNormalDisplacementVecPtr, timeScaleMap));
4082 fe_rhs->getOpPtrVector().push_back(
4083 new OpSpringRhsBc(hybridSpatialDisp, hybrid_ptr, broken_data_ptr,
4084 bcSpatialSpringVecPtr));
4086 auto get_normal_disp_bc_faces = [&]() {
4089 return boost::make_shared<Range>(faces);
4092 auto get_spring_bc_faces = [&]() {
4094 return boost::make_shared<Range>(faces);
4099 using BdyEleOp = BoundaryEle::UserDataOperator;
4101 GAUSS>::OpBrokenSpaceConstrainDFlux<SPACE_DIM>;
4102 fe_rhs->getOpPtrVector().push_back(
new OpC_dBroken(
4103 broken_data_ptr, hybrid_ptr, boost::make_shared<double>(1.0),
4104 get_normal_disp_bc_faces()));
4105 fe_rhs->getOpPtrVector().push_back(
new OpC_dBroken(
4106 broken_data_ptr, hybrid_ptr, boost::make_shared<double>(1.0),
4107 get_spring_bc_faces()));
4112 auto set_lhs = [&]() {
4115 auto broken_data_ptr = get_broken_op_side(fe_lhs->getOpPtrVector());
4118 hybridSpatialDisp, bcSpatialNormalDisplacementVecPtr, timeScaleMap));
4120 hybridSpatialDisp, broken_data_ptr, bcSpatialNormalDisplacementVecPtr,
4122 fe_lhs->getOpPtrVector().push_back(
4125 hybridSpatialDisp, broken_data_ptr, bcSpatialSpringVecPtr));
4127 auto hybrid_grad_ptr = boost::make_shared<MatrixDouble>();
4129 fe_lhs->getOpPtrVector().push_back(
4131 hybridSpatialDisp, hybrid_grad_ptr));
4133 hybridSpatialDisp, bcSpatialPressureVecPtr, hybrid_grad_ptr,
4136 auto get_normal_disp_bc_faces = [&]() {
4139 return boost::make_shared<Range>(faces);
4142 auto get_spring_bc_faces = [&]() {
4144 return boost::make_shared<Range>(faces);
4149 using BdyEleOp = BoundaryEle::UserDataOperator;
4151 GAUSS>::OpBrokenSpaceConstrain<SPACE_DIM>;
4152 fe_lhs->getOpPtrVector().push_back(
new OpC(
4153 hybridSpatialDisp, broken_data_ptr, boost::make_shared<double>(1.0),
4154 true,
true, get_normal_disp_bc_faces()));
4155 fe_lhs->getOpPtrVector().push_back(
new OpC(
4156 hybridSpatialDisp, broken_data_ptr, boost::make_shared<double>(1.0),
4157 true,
true, get_spring_bc_faces()));
4171 boost::shared_ptr<ForcesAndSourcesCore> &fe_contact_tree
4184 CHKERR setContactElementRhsOps(contactTreeRhs);
4186 CHKERR setVolumeElementOps(tag,
true,
false, elasticFeRhs, elasticFeLhs);
4187 CHKERR setFaceElementOps(
true,
false, elasticBcRhs, elasticBcLhs);
4194 boost::shared_ptr<FEMethod> null;
4196 if (std::abs(alphaRho) > std::numeric_limits<double>::epsilon()) {
4229 bool set_ts_monitor) {
4231#ifdef ENABLE_PYTHON_BINDING
4235 auto setup_ts_monitor = [&]() {
4236 boost::shared_ptr<TsCtx>
ts_ctx;
4239 if (set_ts_monitor) {
4243 auto monitor_ptr = boost::make_shared<EshelbianMonitor>(*ep_ptr);
4244 auto testing_monitor_ptr =
4245 boost::make_shared<EshelbianTestingMonitor>(*ep_ptr, monitor_ptr);
4249 PetscBool test_cook_flg = PETSC_FALSE;
4250 PetscBool test_cook_pts_flg = PETSC_FALSE;
4253 &test_cook_flg, PETSC_NULLPTR);
4255 &test_cook_pts_flg, PETSC_NULLPTR);
4258 if (
atom_test || test_cook_flg || test_cook_pts_flg) {
4263 MOFEM_LOG(
"EP", Sev::inform) <<
"TS monitor setup";
4264 return std::make_tuple(
ts_ctx);
4267 auto setup_snes_monitor = [&]() {
4270 CHKERR TSGetSNES(ts, &snes);
4272 CHKERR SNESMonitorSet(snes,
4275 (
void *)(snes_ctx.get()), PETSC_NULLPTR);
4276 MOFEM_LOG(
"EP", Sev::inform) <<
"SNES monitor setup";
4280 auto setup_snes_convergence_test = [&]() {
4285 auto snes_convergence_test =
4286 [](SNES snes, PetscInt it, PetscReal xnorm, PetscReal snorm,
4287 PetscReal fnorm, SNESConvergedReason *reason,
void *cctx) {
4290 CHKERR SNESConvergedDefault(snes, it, xnorm, snorm, fnorm, reason,
4297 if (ep_ptr->
dynamicAtol > 0 && fnorm < ep_ptr->dynamicAtol) {
4298 *reason = SNES_BREAKOUT_INNER_ITER;
4301 "Stopping dynamic relaxation: SNES iteration 0 residual "
4303 static_cast<double>(fnorm),
4306 fnorm < ep_ptr->dynamicRtol *
4308 *reason = SNES_BREAKOUT_INNER_ITER;
4311 "Stopping dynamic relaxation: SNES iteration 0 residual "
4312 "%3.4e < %3.4e * initial residual %3.4e",
4313 static_cast<double>(fnorm),
4318 if (*reason == SNES_BREAKOUT_INNER_ITER) {
4319 PetscObject ts_obj = PETSC_NULLPTR;
4320 CHKERR PetscObjectQuery((PetscObject)snes,
4321 "dynamic_relaxation_ts", &ts_obj);
4322 CHKERR TSSetConvergedReason((TS)ts_obj, TS_CONVERGED_USER);
4330 CHKERR TSGetSNES(ts, &snes);
4331 CHKERR PetscObjectCompose((PetscObject)snes,
"dynamic_relaxation_ts",
4333 CHKERR SNESSetConvergenceTest(snes, snes_convergence_test, ep_ptr,
4335 MOFEM_LOG(
"EP", Sev::inform) <<
"SNES convergence test setup";
4340 auto setup_section = [&]() {
4341 PetscSection section_raw;
4347 for (
int ff = 0; ff != num_fields; ff++) {
4350 PetscSectionGetFieldName(section_raw, ff, &
field_name),
4357 auto set_vector_on_mesh = [&]() {
4361 CHKERR VecGhostUpdateBegin(x, INSERT_VALUES, SCATTER_FORWARD);
4362 CHKERR VecGhostUpdateEnd(x, INSERT_VALUES, SCATTER_FORWARD);
4363 MOFEM_LOG(
"EP", Sev::inform) <<
"Vector set on mesh";
4367 auto setup_schur_block_solver = [&]() {
4368 MOFEM_LOG(
"EP", Sev::inform) <<
"Setting up Schur block solver";
4370 "append options prefix");
4374 boost::shared_ptr<EshelbianCore::SetUpSchur> schur_ptr;
4375 if constexpr (
A == AssemblyType::BLOCK_MAT) {
4380 MOFEM_LOG(
"EP", Sev::inform) <<
"Setting up Schur block solver done";
4387#ifdef ENABLE_PYTHON_BINDING
4388 return std::make_tuple(setup_sdf(), setup_ts_monitor(),
4389 setup_snes_monitor(), setup_snes_convergence_test(),
4390 setup_section(), set_vector_on_mesh(),
4391 setup_schur_block_solver());
4393 return std::make_tuple(setup_ts_monitor(), setup_snes_monitor(),
4394 setup_snes_convergence_test(), setup_section(),
4395 set_vector_on_mesh(), setup_schur_block_solver());
4403 PetscBool debug_model = PETSC_FALSE;
4407 <<
"Debug model flag is " << (debug_model ?
"ON" :
"OFF");
4409 if (debug_model == PETSC_TRUE) {
4411 auto post_proc = [&](TS ts, PetscReal
t, Vec u, Vec u_t, Vec u_tt, Vec
F,
4416 CHKERR TSGetSNES(ts, &snes);
4418 CHKERR SNESGetIterationNumber(snes, &it);
4419 std::string file_name =
"snes_iteration_" + std::to_string(it) +
".h5m";
4420 CHKERR postProcessResults(1, file_name,
F, u_t, PETSC_NULLPTR, {}, ts);
4426 std::string file_skel_name =
4427 "snes_iteration_skel_" + std::to_string(it) +
".h5m";
4429 auto get_material_force_tag = [&]() {
4430 auto &moab = mField.get_moab();
4437 CHKERR calculateFaceMaterialForce(1, ts);
4438 CHKERR postProcessSkeletonResults(1, file_skel_name,
F,
4439 {get_material_force_tag()}, ts);
4444 ts_ctx_ptr->tsDebugHook = post_proc;
4453 CHKERR addDebugModel(ts);
4457 if (std::abs(alphaRho) > std::numeric_limits<double>::epsilon()) {
4459 CHKERR VecDuplicate(x, &xx);
4460 CHKERR VecZeroEntries(xx);
4461 CHKERR TS2SetSolution(ts, x, xx);
4464 CHKERR TSSetSolution(ts, x);
4467 TetPolynomialBase::switchCacheBaseOn<HDIV>(
4468 {elasticFeLhs.get(), elasticFeRhs.get()});
4473 CHKERR TSSolve(ts, PETSC_NULLPTR);
4475 TetPolynomialBase::switchCacheBaseOff<HDIV>(
4476 {elasticFeLhs.get(), elasticFeRhs.get()});
4480 if (mField.get_comm_rank() == 0) {
4483 "solve_elastic_graph.dot");
4488 CHKERR TSGetSNES(ts, &snes);
4489 int lin_solver_iterations;
4490 CHKERR SNESGetLinearSolveIterations(snes, &lin_solver_iterations);
4492 <<
"Number of linear solver iterations " << lin_solver_iterations;
4494 PetscBool test_cook_flg = PETSC_FALSE;
4497 if (test_cook_flg) {
4498 PetscInt expected_lin_solver_iterations = 11;
4500 "-test_cook_max_linear_iterations",
4501 &expected_lin_solver_iterations, PETSC_NULLPTR);
4502 if (lin_solver_iterations > expected_lin_solver_iterations)
4505 "Expected number of iterations is different than expected %d > %d",
4506 lin_solver_iterations, expected_lin_solver_iterations);
4509 PetscBool test_sslv116_flag = PETSC_FALSE;
4511 &test_sslv116_flag, PETSC_NULLPTR);
4513 if (test_sslv116_flag) {
4514 double max_val = 0.0;
4515 double min_val = 0.0;
4516 auto field_min_max = [&](boost::shared_ptr<FieldEntity> ent_ptr) {
4518 auto ent_type = ent_ptr->getEntType();
4519 if (ent_type == MBVERTEX) {
4520 max_val = std::max(ent_ptr->getEntFieldData()[
SPACE_DIM - 1], max_val);
4521 min_val = std::min(ent_ptr->getEntFieldData()[
SPACE_DIM - 1], min_val);
4526 field_min_max, spatialH1Disp);
4528 double global_max_val = 0.0;
4529 double global_min_val = 0.0;
4530 MPI_Allreduce(&max_val, &global_max_val, 1, MPI_DOUBLE, MPI_MAX,
4532 MPI_Allreduce(&min_val, &global_min_val, 1, MPI_DOUBLE, MPI_MIN,
4535 <<
"Max " << spatialH1Disp <<
" value: " << global_max_val;
4537 <<
"Min " << spatialH1Disp <<
" value: " << global_min_val;
4539 double ref_max_val = 0.00767;
4540 double ref_min_val = -0.00329;
4541 if (std::abs(global_max_val - ref_max_val) > 1e-5) {
4543 "Incorrect max value of the displacement field: %f != %f",
4544 global_max_val, ref_max_val);
4546 if (std::abs(global_min_val - ref_min_val) > 4e-5) {
4548 "Incorrect min value of the displacement field: %f != %f",
4549 global_min_val, ref_min_val);
4563 CHKERR TSGetSNES(ts, &snes);
4564 SNESConvergedReason snes_reason;
4565 CHKERR SNESGetConvergedReason(snes, &snes_reason);
4566 if (snes_reason == SNES_BREAKOUT_INNER_ITER) {
4568 <<
"Dynamic relaxation stopped due to SNES_BREAKOUT_INNER_ITER";
4569 CHKERR SNESSetConvergedReason(snes, SNES_CONVERGED_ITERATING);
4578 PetscBool is_beuler = PETSC_FALSE;
4579 PetscBool is_theta = PETSC_FALSE;
4580 CHKERR PetscObjectTypeCompare((PetscObject)ts, TSBEULER, &is_beuler);
4581 CHKERR PetscObjectTypeCompare((PetscObject)ts, TSTHETA, &is_theta);
4583 PetscBool theta_extrapolate = PETSC_FALSE;
4584 PetscBool theta_extrapolate_set = PETSC_FALSE;
4586 "-elastic_ts_theta_initial_guess_extrapolate",
4587 &theta_extrapolate, &theta_extrapolate_set);
4588 if (theta_extrapolate_set && theta_extrapolate) {
4590 "-dynamic_atol and -dynamic_rtol assume the SNES iteration 0 "
4591 "residual is evaluated with zero rates. Disable "
4592 "-elastic_ts_theta_initial_guess_extrapolate.");
4595 PetscBool is_backward_euler_equivalent = is_beuler;
4597 PetscReal theta = 0;
4598 CHKERR TSThetaGetTheta(ts, &theta);
4599 is_backward_euler_equivalent =
4600 (std::abs(theta - 1.) <= 10. * std::numeric_limits<double>::epsilon())
4605 if (!is_backward_euler_equivalent) {
4607 "-dynamic_atol and -dynamic_rtol require a "
4608 "backward-Euler-equivalent TS "
4609 "so that SNES iteration 0 has zero rates. Use "
4610 "-elastic_ts_type beuler or "
4611 "-elastic_ts_type theta -elastic_ts_theta_theta 1.");
4619 double start_time) {
4623 PetscOptionsBegin(PETSC_COMM_WORLD,
"",
"Dynamic Relaxation Options",
"none");
4625 CHKERR PetscOptionsScalar(
4626 "-dynamic_final_time",
"dynamic relaxation final time",
"",
4627 finalPhysicalTime, &finalPhysicalTime, PETSC_NULLPTR);
4628 CHKERR PetscOptionsScalar(
"-dynamic_delta_time",
4629 "dynamic relaxation final time",
"", physicalDt,
4630 &physicalDt, PETSC_NULLPTR);
4631 CHKERR PetscOptionsInt(
"-dynamic_max_it",
"dynamic relaxation iterations",
"",
4632 physicalMaxSteps, &physicalMaxSteps, PETSC_NULLPTR);
4633 CHKERR PetscOptionsBool(
"-dynamic_h1_update",
"update each ts step",
"",
4634 physicalH1Update, &physicalH1Update, PETSC_NULLPTR);
4635 CHKERR PetscOptionsScalar(
"-dynamic_atol",
4636 "stop relaxation when the zero-rate residual is "
4637 "below this value; disabled for <= 0",
4638 "", dynamicAtol, &dynamicAtol, PETSC_NULLPTR);
4639 CHKERR PetscOptionsScalar(
"-dynamic_rtol",
4640 "stop relaxation when the zero-rate residual is "
4641 "below this fraction of its initial value; "
4642 "disabled for <= 0",
4643 "", dynamicRtol, &dynamicRtol, PETSC_NULLPTR);
4649 if (dynamicAtol > 0 || dynamicRtol > 0) {
4654 <<
"Following options are deprecated, use -physical prefix options "
4657 <<
"Dynamic relaxation final time -dynamic_final_time = "
4658 << finalPhysicalTime;
4660 <<
"Dynamic relaxation delta time -dynamic_delta_time = " << physicalDt;
4662 <<
"Dynamic relaxation max iterations -dynamic_max_it = "
4663 << physicalMaxSteps;
4665 <<
"Dynamic relaxation H1 update each step -dynamic_h1_update = "
4666 << (physicalH1Update ?
"TRUE" :
"FALSE");
4668 <<
"Dynamic relaxation absolute tolerance -dynamic_atol = "
4671 <<
"Dynamic relaxation relative tolerance -dynamic_rtol = "
4674 CHKERR addDebugModel(ts);
4676 auto setup_ts_monitor = [&]() {
4677 auto monitor_ptr = boost::make_shared<EshelbianMonitor>(*
this);
4680 auto monitor_ptr = setup_ts_monitor();
4682 TetPolynomialBase::switchCacheBaseOn<HDIV>(
4683 {elasticFeLhs.get(), elasticFeRhs.get()});
4687 double ts_delta_time;
4688 CHKERR TSGetTimeStep(ts, &ts_delta_time);
4689 CHKERR TSSetSolution(ts, x);
4691 if (physicalH1Update) {
4695 CHKERR TSSetPreStep(ts, PETSC_NULLPTR);
4696 CHKERR TSSetPostStep(ts, PETSC_NULLPTR);
4698 if (dynamicAtol > 0 || dynamicRtol > 0) {
4706 currentPhysicalTime = start_time;
4707 physicalStepNumber = start_step;
4708 monitor_ptr->ts = PETSC_NULLPTR;
4709 monitor_ptr->ts_u = PETSC_NULLPTR;
4710 monitor_ptr->ts_t = currentPhysicalTime;
4711 monitor_ptr->ts_step = physicalStepNumber;
4714 if (physicalDt <= 0.) {
4716 "physicalDt must be positive, got %g", physicalDt);
4718 for (; currentPhysicalTime <= finalPhysicalTime;) {
4720 <<
"Load step " << physicalStepNumber <<
" Time " << currentPhysicalTime
4721 <<
" delta time " << physicalDt;
4723 CHKERR TSSetStepNumber(ts, 0);
4725 CHKERR TSSetTimeStep(ts, ts_delta_time);
4726 CHKERR TSSetSolution(ts, x);
4727 if (!physicalH1Update) {
4730 dynamicInitialResidual = -1;
4731 CHKERR TSSolve(ts, PETSC_NULLPTR);
4732 if (!physicalH1Update) {
4738 CHKERR VecGhostUpdateBegin(x, INSERT_VALUES, SCATTER_FORWARD);
4739 CHKERR VecGhostUpdateEnd(x, INSERT_VALUES, SCATTER_FORWARD);
4741 monitor_ptr->ts = PETSC_NULLPTR;
4742 monitor_ptr->ts_u = x;
4743 monitor_ptr->ts_t = currentPhysicalTime;
4744 monitor_ptr->ts_step = physicalStepNumber;
4747 ++physicalStepNumber;
4748 if (physicalStepNumber > physicalMaxSteps)
4750 if (currentPhysicalTime >= finalPhysicalTime)
4753 const double remainingPhysicalTime =
4754 finalPhysicalTime - currentPhysicalTime;
4755 if (physicalDt >= remainingPhysicalTime) {
4756 currentPhysicalTime = finalPhysicalTime;
4758 currentPhysicalTime += physicalDt;
4763 TetPolynomialBase::switchCacheBaseOff<HDIV>(
4764 {elasticFeLhs.get(), elasticFeRhs.get()});
4772 auto set_block = [&](
auto name,
int dim) {
4773 std::map<int, Range> map;
4774 auto set_tag_impl = [&](
auto name) {
4779 std::regex((boost::format(
"%s(.*)") % name).str())
4782 for (
auto bc : bcs) {
4784 CHKERR bc->getMeshsetIdEntitiesByDimension(mField.get_moab(), dim, r,
4786 map[bc->getMeshsetId()] = r;
4788 <<
"Block " << name <<
" id " << bc->getMeshsetId() <<
" has "
4789 << r.size() <<
" entities";
4794 CHKERR set_tag_impl(name);
4796 return std::make_pair(name, map);
4799 auto set_skin = [&](
auto &&map) {
4800 for (
auto &
m : map.second) {
4804 <<
"Skin for block " << map.first <<
" id " <<
m.first <<
" has "
4805 <<
m.second.size() <<
" entities";
4810 auto set_tag = [&](
auto &&map) {
4812 auto name = map.first;
4813 int def_val[] = {-1};
4815 mField.get_moab().tag_get_handle(name, 1, MB_TYPE_INTEGER,
th,
4816 MB_TAG_SPARSE | MB_TAG_CREAT, def_val),
4818 for (
auto &
m : map.second) {
4826 listTagsToTransfer.push_back(set_tag(set_skin(set_block(
"BODY", 3))));
4827 listTagsToTransfer.push_back(set_tag(set_skin(set_block(
"MAT_ELASTIC", 3))));
4828 listTagsToTransfer.push_back(
4829 set_tag(set_skin(set_block(
"MAT_NEOHOOKEAN", 3))));
4830 listTagsToTransfer.push_back(set_tag(set_block(
"CONTACT", 2)));
4837 std::vector<Tag> tags_to_transfer) {
4839 ParallelComm *pcomm =
4842 if (crackingOn && !pcomm->rank()) {
4845 std::vector<boost::shared_ptr<TempMeshset>> meshsets_tmp_list;
4847 std::vector<Tag> tags_list;
4851 for (
auto &
m : list) {
4853 EntityHandle new_meshset = *meshsets_tmp_list.back();
4854 auto meshset =
m.getMeshset();
4855 std::vector<Tag> tmp_tags_list;
4856 CHKERR mField.get_moab().tag_get_tags_on_entity(meshset, tmp_tags_list);
4858 CHKERR mField.get_moab().get_entities_by_handle(meshset, ents,
true);
4859 CHKERR mField.get_moab().add_entities(new_meshset, ents);
4860 for (
auto t : tmp_tags_list) {
4863 CHKERR mField.get_moab().tag_get_by_ptr(
4864 t, &meshset, 1, (
const void **)tag_vals, tag_size);
4865 CHKERR mField.get_moab().tag_set_by_ptr(
t, &new_meshset, 1, tag_vals,
4868 std::vector<std::string> remove_tags;
4869 remove_tags.push_back(
"AKDTree_coord_norm");
4870 remove_tags.push_back(
"__PARALLEL_");
4871 remove_tags.push_back(
"_RefBitLevel");
4873 for (
auto t : tmp_tags_list) {
4874 std::string tag_name;
4875 CHKERR mField.get_moab().tag_get_name(
t, tag_name);
4878 for (
auto &p : remove_tags) {
4879 if (tag_name.compare(0, p.size(), p) == 0) {
4886 tags_list.push_back(
t);
4890 for (
auto &m_ptr : meshsets_tmp_list) {
4891 EntityHandle
m = *m_ptr;
4892 CHKERR mField.get_moab().add_entities(*meshset_ptr, &
m, 1);
4896 std::sort(tags_list.begin(), tags_list.end());
4897 auto new_end = std::unique(tags_list.begin(), tags_list.end());
4898 tags_list.resize(std::distance(tags_list.begin(), new_end));
4900 EntityHandle save_meshset = *meshset_ptr;
4901 CHKERR mField.get_moab().write_file(file.c_str(),
"MOAB",
"", &save_meshset,
4902 1, &tags_list[0], tags_list.size());
4909 Vec f_residual, Vec var_vector, Vec gradient,
4910 std::vector<Tag> tags_to_transfer, TS ts) {
4914 if (f_residual != PETSC_NULLPTR || var_vector != PETSC_NULLPTR) {
4918 auto xin = f_residual != PETSC_NULLPTR ? f_residual : var_vector;
4924 CHKERR VecScatterBegin(scatter, f_residual, f_r, INSERT_VALUES,
4926 CHKERR VecScatterEnd(scatter, f_residual, f_r, INSERT_VALUES,
4928 CHKERR VecGhostUpdateBegin(f_r, INSERT_VALUES, SCATTER_FORWARD);
4929 CHKERR VecGhostUpdateEnd(f_r, INSERT_VALUES, SCATTER_FORWARD);
4933 CHKERR VecScatterBegin(scatter, var_vector, v_v, INSERT_VALUES,
4935 CHKERR VecScatterEnd(scatter, var_vector, v_v, INSERT_VALUES,
4937 CHKERR VecGhostUpdateBegin(v_v, INSERT_VALUES, SCATTER_FORWARD);
4938 CHKERR VecGhostUpdateEnd(v_v, INSERT_VALUES, SCATTER_FORWARD);
4949 CHKERR VecScatterBegin(scatter, gradient,
g, INSERT_VALUES,
4951 CHKERR VecScatterEnd(scatter, gradient,
g, INSERT_VALUES, SCATTER_FORWARD);
4952 CHKERR VecGhostUpdateBegin(
g, INSERT_VALUES, SCATTER_FORWARD);
4953 CHKERR VecGhostUpdateEnd(
g, INSERT_VALUES, SCATTER_FORWARD);
4958 auto get_tag = [&](
auto name,
auto dim) {
4959 auto &mob = mField.get_moab();
4961 double def_val[] = {0., 0., 0.};
4962 CHK_MOAB_THROW(mob.tag_get_handle(name, dim, MB_TYPE_DOUBLE, tag,
4963 MB_TAG_CREAT | MB_TAG_SPARSE, def_val),
4967 tags_to_transfer.push_back(get_tag(
"MaterialForce", 3));
4971 auto get_crack_tag = [&]() {
4973 rval = mField.get_moab().tag_get_handle(
"CRACK",
th);
4974 if (
rval == MB_SUCCESS) {
4977 int def_val[] = {0};
4979 "CRACK", 1, MB_TYPE_INTEGER,
th, MB_TAG_SPARSE | MB_TAG_CREAT,
4984 Tag th = get_crack_tag();
4985 tags_to_transfer.push_back(
th);
4989 mark_faces.merge(*crackFaces);
4991 mark_faces.merge(*interfaceFaces);
4992 CHKERR mField.get_moab().tag_clear_data(
th, mark_faces, mark);
4996 for (
auto t : listTagsToTransfer) {
4998 CHKERR mField.get_moab().tag_get_name(
t, name);
5000 <<
"Adding tag " << name <<
" to transfer list for post-processing";
5001 tags_to_transfer.push_back(
t);
5011 auto get_post_proc = [&](
auto &post_proc_mesh,
auto sense) {
5013 auto post_proc_ptr =
5014 boost::make_shared<PostProcBrokenMeshInMoabBaseCont<FaceEle>>(
5015 mField, post_proc_mesh);
5016 EshelbianPlasticity::AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
5017 post_proc_ptr->getOpPtrVector(), {L2}, materialH1Positions,
5020 if (ts != PETSC_NULLPTR) {
5022 CHKERR TSGetTime(ts, &(post_proc_ptr->ts_t));
5023 CHKERR TSGetTimeStep(ts, &(post_proc_ptr->ts_dt));
5026 auto domain_ops = [&](
auto &fe,
int sense) {
5028 MaterialPostProcData material_output;
5030 auto bubble_cache = boost::make_shared<CGGUserPolynomialBase::CachePhi>(
5032 fe.getUserPolynomialBase() = boost::shared_ptr<BaseFunction>(
5034 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
5035 fe.getOpPtrVector(), {HDIV, H1, L2}, materialH1Positions,
5037 auto piola_scale_ptr = boost::make_shared<double>(1.0);
5039 piolaStress,
dataAtPts->getApproxPAtPts(), piola_scale_ptr));
5040 const bool add_bubble = mField.check_field(bubbleField);
5043 bubbleField,
dataAtPts->getApproxPAtPts(), piola_scale_ptr,
5047 rotAxis,
dataAtPts->getRotAxisAtPts(), MBTET));
5048 CHKERR VecSetDM(solTSStep, PETSC_NULLPTR);
5050 piolaStress,
dataAtPts->getApproxP0AtPts(),
nullptr, solTSStep));
5053 bubbleField,
dataAtPts->getApproxP0AtPts(),
nullptr, solTSStep,
5056 CHKERR physicalEquations->pushMaterialFields(
5058 CHKERR physicalEquations->pushMaterialFields(
5062 piolaStress,
dataAtPts->getVarPiolaPts(),
5063 boost::make_shared<double>(1), v_v));
5066 bubbleField,
dataAtPts->getVarPiolaPts(),
5067 boost::make_shared<double>(1), v_v, MBMAXTYPE));
5069 rotAxis,
dataAtPts->getVarRotAxisPts(), v_v, MBTET));
5070 CHKERR physicalEquations->pushMaterialVariation(
5071 *
this, fe.getOpPtrVector(),
dataAtPts, v_v, &material_output);
5075 materialH1Positions,
dataAtPts->getGradientAtPts(),
g));
5079 rotAxis,
dataAtPts->getRotAxis0AtPts(), solTSStep, MBTET));
5082 spatialL2Disp,
dataAtPts->getSmallWL2AtPts(), MBTET));
5084 spatialH1Disp,
dataAtPts->getSmallWH1AtPts()));
5086 spatialH1Disp,
dataAtPts->getSmallWGradH1AtPts()));
5089 fe.getOpPtrVector(), plasticHField,
dataAtPts->getPlasticH(),
5091 auto plastic_flow_ptr = boost::shared_ptr<MatrixDouble>();
5092 auto plastic_kappa_ptr = boost::shared_ptr<VectorDouble>();
5093 if (plasticVolume) {
5094 plastic_flow_ptr = boost::make_shared<MatrixDouble>();
5096 fe.getOpPtrVector(), plasticFlowField, plastic_flow_ptr, MBTET);
5097 plastic_kappa_ptr = boost::make_shared<VectorDouble>();
5099 plasticKappaField, plastic_kappa_ptr, MBTET));
5101 fe.getOpPtrVector().push_back(
5104 CHKERR physicalEquations->pushPostProc(*
this, fe.getOpPtrVector(),
5114 scalar_fields[
"PlasticKappa"] = plastic_kappa_ptr;
5116 struct OpSidePPMap :
public OpPPMap {
5117 OpSidePPMap(moab::Interface &post_proc_mesh,
5118 std::vector<EntityHandle> &map_gauss_pts,
5119 DataMapVec data_map_scalar, DataMapMat data_map_vec,
5120 DataMapMat data_map_mat, DataMapMat data_symm_map_mat,
5122 :
OpPPMap(post_proc_mesh, map_gauss_pts, data_map_scalar,
5123 data_map_vec, data_map_mat, data_symm_map_mat),
5130 if (tagSense != 0) {
5131 if (tagSense != OpPPMap::getSkeletonSense())
5144 vec_fields[
"SpatialDisplacementL2"] =
dataAtPts->getSmallWL2AtPts();
5145 vec_fields[
"SpatialDisplacementH1"] =
dataAtPts->getSmallWH1AtPts();
5146 vec_fields[
"Omega"] =
dataAtPts->getRotAxisAtPts();
5147 vec_fields[
"AngularMomentum"] =
dataAtPts->getLeviKirchhoffAtPts();
5148 vec_fields[
"X"] =
dataAtPts->getLargeXH1AtPts();
5150 vec_fields[
"VarOmega"] =
dataAtPts->getVarRotAxisPts();
5151 vec_fields[
"VarSpatialDisplacementL2"] =
5152 boost::make_shared<MatrixDouble>();
5154 spatialL2Disp, vec_fields[
"VarSpatialDisplacementL2"], v_v, MBTET));
5157 vec_fields[
"ResSpatialDisplacementL2"] =
5158 boost::make_shared<MatrixDouble>();
5160 spatialL2Disp, vec_fields[
"ResSpatialDisplacementL2"], f_r, MBTET));
5161 vec_fields[
"ResOmega"] = boost::make_shared<MatrixDouble>();
5163 rotAxis, vec_fields[
"ResOmega"], f_r, MBTET));
5166 vec_fields[
"Gradient"] =
dataAtPts->getGradientAtPts();
5170 mat_fields[
"PiolaStress"] =
dataAtPts->getApproxPAtPts();
5172 mat_fields[
"VarPiolaStress"] =
dataAtPts->getVarPiolaPts();
5175 mat_fields[
"ResPiolaStress"] = boost::make_shared<MatrixDouble>();
5177 piolaStress, mat_fields[
"ResPiolaStress"],
5178 boost::make_shared<double>(1), f_r));
5181 bubbleField, mat_fields[
"ResPiolaStress"],
5182 boost::make_shared<double>(1), f_r, MBMAXTYPE));
5184 if (!internalStressTagName.empty()) {
5185 mat_fields[internalStressTagName] =
dataAtPts->getInternalStressAtPts();
5186 switch (meshTransferInterpOrder) {
5188 fe.getOpPtrVector().push_back(
5192 fe.getOpPtrVector().push_back(
5197 "Unsupported mesh transfer interpolation order %d, for "
5199 meshTransferInterpOrder);
5205 CHKERR physicalEquations->pushPostProcResidual(
5206 *
this, fe.getOpPtrVector(),
dataAtPts, f_r, material_output);
5209 mat_fields_symm[
"PlasticHp"] =
dataAtPts->getPlasticH();
5211 mat_fields_symm[
"PlasticFlow"] = plastic_flow_ptr;
5212 scalar_fields.insert(material_output.scalarFields.begin(),
5213 material_output.scalarFields.end());
5214 vec_fields.insert(material_output.vectorFields.begin(),
5215 material_output.vectorFields.end());
5216 mat_fields_symm.insert(material_output.symmetricFields.begin(),
5217 material_output.symmetricFields.end());
5219 fe.getOpPtrVector().push_back(
5223 post_proc_ptr->getPostProcMesh(), post_proc_ptr->getMapGaussPts(),
5240 post_proc_ptr->getPostProcMesh(), post_proc_ptr->getMapGaussPts(),
5246 auto X_h1_ptr = boost::make_shared<MatrixDouble>();
5248 post_proc_ptr->getOpPtrVector().push_back(
5256 "Cannot construct material postprocessing pipeline");
5257 post_proc_ptr->getOpPtrVector().push_back(op_loop_side);
5259 return post_proc_ptr;
5263 auto calcs_side_traction_and_displacements = [&](
auto &post_proc_ptr,
5269 using SideEleOp = EleOnSide::UserDataOperator;
5271 mField, elementVolumeName,
SPACE_DIM, Sev::noisy);
5272 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
5273 boost::shared_ptr<BaseFunction>(
5275 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
5276 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
5277 materialH1Positions, frontAdjEdges);
5278 auto traction_ptr = boost::make_shared<MatrixDouble>();
5279 op_loop_domain_side->getOpPtrVector().push_back(
5281 piolaStress, traction_ptr, boost::make_shared<double>(1.0)));
5284 contactDisp,
dataAtPts->getContactL2AtPts()));
5285 pip.push_back(op_loop_domain_side);
5287 auto u_h1_ptr = boost::make_shared<MatrixDouble>();
5290 *
this, contactTreeRhs, u_h1_ptr, traction_ptr,
5292 &post_proc_ptr->getPostProcMesh(), &post_proc_ptr->getMapGaussPts()));
5298 pip.push_back(op_this);
5301 vec_fields[
"ContactDisplacement"] =
dataAtPts->getContactL2AtPts();
5303 op_this->getOpPtrVector().push_back(
5307 post_proc_ptr->getPostProcMesh(), post_proc_ptr->getMapGaussPts(),
5323 auto contact_residual = boost::make_shared<MatrixDouble>();
5324 op_this->getOpPtrVector().push_back(
5326 contactDisp, contact_residual, f_r, MBTET));
5327 op_this->getOpPtrVector().push_back(
5331 post_proc_ptr->getPostProcMesh(), post_proc_ptr->getMapGaussPts(),
5335 {{
"res_contact", contact_residual}},
5349 auto post_proc_mesh = boost::make_shared<moab::Core>();
5350 auto post_proc_ptr = get_post_proc(post_proc_mesh, 1);
5351 auto post_proc_negative_sense_ptr =
5352 get_post_proc(post_proc_mesh, -1);
5353 auto skin_post_proc_ptr = get_post_proc(post_proc_mesh, 1);
5354 CHKERR calcs_side_traction_and_displacements(
5355 skin_post_proc_ptr, skin_post_proc_ptr->getOpPtrVector());
5361 CHKERR mField.get_moab().get_adjacencies(own_tets,
SPACE_DIM - 1,
true,
5362 own_faces, moab::Interface::UNION);
5364 auto get_crack_faces = [&](
auto crack_faces) {
5365 auto get_adj = [&](
auto e,
auto dim) {
5367 CHKERR mField.get_moab().get_adjacencies(e, dim,
true, adj,
5368 moab::Interface::UNION);
5372 auto tets = get_adj(crack_faces, 3);
5374 auto faces = subtract(get_adj(tets, 2), crack_faces);
5376 tets = subtract(tets, get_adj(faces, 3));
5377 return subtract(crack_faces, get_adj(tets, 2));
5380 auto side_one_faces = [&](
auto &faces) {
5381 std::pair<Range, Range> sides;
5382 for (
auto f : faces) {
5384 MOAB_THROW(mField.get_moab().get_adjacencies(&f, 1, 3,
false, adj));
5385 adj = intersect(own_tets, adj);
5386 for (
auto t : adj) {
5387 int side, sense, offset;
5388 MOAB_THROW(mField.get_moab().side_number(
t, f, side, sense, offset));
5390 sides.first.insert(f);
5392 sides.second.insert(f);
5399 auto crack_faces = unite(get_crack_faces(*crackFaces), *interfaceFaces);
5402 auto crack_side_faces = side_one_faces(crack_faces);
5403 auto side_one_crack_faces = [crack_side_faces](
FEMethod *fe_method_ptr) {
5404 auto ent = fe_method_ptr->getFEEntityHandle();
5405 if (crack_side_faces.first.find(ent) == crack_side_faces.first.end()) {
5410 auto side_minus_crack_faces = [crack_side_faces](
FEMethod *fe_method_ptr) {
5411 auto ent = fe_method_ptr->getFEEntityHandle();
5412 if (crack_side_faces.second.find(ent) == crack_side_faces.second.end()) {
5418 skin_post_proc_ptr->setTagsToTransfer(tags_to_transfer);
5419 post_proc_ptr->setTagsToTransfer(tags_to_transfer);
5420 post_proc_negative_sense_ptr->setTagsToTransfer(tags_to_transfer);
5422 auto post_proc_begin =
5426 post_proc_ptr->exeTestHook = side_one_crack_faces;
5428 dM, skeletonElement, post_proc_ptr, 0, mField.get_comm_size());
5429 post_proc_negative_sense_ptr->exeTestHook = side_minus_crack_faces;
5431 post_proc_negative_sense_ptr, 0,
5432 mField.get_comm_size());
5434 constexpr bool debug =
false;
5437 auto get_adj_front = [&]() {
5438 auto skeleton_faces = *skeletonFaces;
5440 CHKERR mField.get_moab().get_adjacencies(*frontEdges, 2,
true, adj_front,
5441 moab::Interface::UNION);
5443 adj_front = intersect(adj_front, skeleton_faces);
5444 adj_front = subtract(adj_front, *crackFaces);
5445 adj_front = intersect(own_faces, adj_front);
5450 auto only_front_faces = [adj_front](
FEMethod *fe_method_ptr) {
5451 auto ent = fe_method_ptr->getFEEntityHandle();
5452 if (adj_front.find(ent) == adj_front.end()) {
5458 post_proc_ptr->exeTestHook = only_front_faces;
5460 dM, skeletonElement, post_proc_ptr, 0, mField.get_comm_size());
5461 post_proc_negative_sense_ptr->exeTestHook = only_front_faces;
5463 post_proc_negative_sense_ptr, 0,
5464 mField.get_comm_size());
5469 CHKERR post_proc_end.writeFile(
file.c_str());
5474 const int tag,
const std::string file, Vec f_residual,
5475 std::vector<Tag> tags_to_transfer, TS ts) {
5479 if (f_residual != PETSC_NULLPTR) {
5485 CHKERR VecScatterBegin(scatter, f_residual, f_r, INSERT_VALUES,
5487 CHKERR VecScatterEnd(scatter, f_residual, f_r, INSERT_VALUES,
5489 CHKERR VecGhostUpdateBegin(f_r, INSERT_VALUES, SCATTER_FORWARD);
5490 CHKERR VecGhostUpdateEnd(f_r, INSERT_VALUES, SCATTER_FORWARD);
5495 auto post_proc_mesh = boost::make_shared<moab::Core>();
5496 auto post_proc_ptr =
5497 boost::make_shared<PostProcBrokenMeshInMoabBaseCont<FaceEle>>(
5499 if (ts != PETSC_NULLPTR) {
5501 CHKERR TSGetTime(ts, &post_proc_ptr->ts_t);
5502 CHKERR TSGetTimeStep(ts, &post_proc_ptr->ts_dt);
5504 EshelbianPlasticity::AddHOOps<SPACE_DIM - 1, SPACE_DIM - 1, SPACE_DIM>::add(
5508 auto hybrid_disp = boost::make_shared<MatrixDouble>();
5509 post_proc_ptr->getOpPtrVector().push_back(
5511 post_proc_ptr->getOpPtrVector().push_back(
5515 auto op_loop_domain_side =
5518 post_proc_ptr->getOpPtrVector().push_back(op_loop_domain_side);
5520 MaterialPostProcData material_output;
5522 *
this, *op_loop_domain_side->getSideFEPtr(),
dataAtPts, f_r,
5528 vec_fields[
"HybridDisplacement"] = hybrid_disp;
5530 vec_fields[
"spatialL2Disp"] =
dataAtPts->getSmallWL2AtPts();
5531 vec_fields[
"Omega"] =
dataAtPts->getRotAxisAtPts();
5533 mat_fields[
"PiolaStress"] =
dataAtPts->getApproxPAtPts();
5534 mat_fields[
"HybridDisplacementGradient"] =
5538 post_proc_ptr->getOpPtrVector().push_back(
5542 post_proc_ptr->getPostProcMesh(), post_proc_ptr->getMapGaussPts(),
5544 material_output.scalarFields,
5557 auto hybrid_res = boost::make_shared<MatrixDouble>();
5558 post_proc_ptr->getOpPtrVector().push_back(
5562 post_proc_ptr->getOpPtrVector().push_back(
5566 post_proc_ptr->getPostProcMesh(), post_proc_ptr->getMapGaussPts(),
5570 {{
"res_hybrid", hybrid_res}},
5581 post_proc_ptr->setTagsToTransfer(tags_to_transfer);
5583 auto post_proc_begin =
5590 CHKERR post_proc_end.writeFile(file.c_str());
5599 auto post_proc_norm_fe =
5600 boost::make_shared<VolumeElementForcesAndSourcesCore>(
mField);
5603 boost::make_shared<CGGUserPolynomialBase::CachePhi>(0, 0,
MatrixDouble());
5604 post_proc_norm_fe->getUserPolynomialBase() =
5606 post_proc_norm_fe->getRuleHook = [](int, int, int) {
return -1; };
5607 post_proc_norm_fe->setRuleHook = SetIntegrationAtFrontVolume(
5609 CHKERR EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
5613 enum NORMS { U_NORM_L2 = 0, U_NORM_H1, PIOLA_NORM, U_ERROR_L2, LAST_NORM };
5616 CHKERR VecZeroEntries(norms_vec);
5618 auto u_l2_ptr = boost::make_shared<MatrixDouble>();
5619 auto u_h1_ptr = boost::make_shared<MatrixDouble>();
5620 post_proc_norm_fe->getOpPtrVector().push_back(
5622 post_proc_norm_fe->getOpPtrVector().push_back(
5624 post_proc_norm_fe->getOpPtrVector().push_back(
5626 post_proc_norm_fe->getOpPtrVector().push_back(
5628 post_proc_norm_fe->getOpPtrVector().push_back(
5632 auto piola_ptr = boost::make_shared<MatrixDouble>();
5633 post_proc_norm_fe->getOpPtrVector().push_back(
5635 post_proc_norm_fe->getOpPtrVector().push_back(
5639 post_proc_norm_fe->getOpPtrVector().push_back(
5642 TetPolynomialBase::switchCacheBaseOn<HDIV>({post_proc_norm_fe.get()});
5644 *post_proc_norm_fe);
5645 TetPolynomialBase::switchCacheBaseOff<HDIV>({post_proc_norm_fe.get()});
5647 CHKERR VecAssemblyBegin(norms_vec);
5648 CHKERR VecAssemblyEnd(norms_vec);
5649 const double *norms;
5650 CHKERR VecGetArrayRead(norms_vec, &norms);
5651 MOFEM_LOG(
"EP", Sev::inform) <<
"norm_u: " << std::sqrt(norms[U_NORM_L2]);
5652 MOFEM_LOG(
"EP", Sev::inform) <<
"norm_u_h1: " << std::sqrt(norms[U_NORM_H1]);
5654 <<
"norm_error_u_l2: " << std::sqrt(norms[U_ERROR_L2]);
5656 <<
"norm_piola: " << std::sqrt(norms[PIOLA_NORM]);
5657 CHKERR VecRestoreArrayRead(norms_vec, &norms);
5673 auto get_fix_load_history = [&](
const std::string &block_name) {
5674 for (
const auto type_name : {
"FIX_X",
"FIX_Y",
"FIX_Z",
"FIX_ALL"}) {
5678 (boost::format(
"%s(.*)") % type_name).str()
5683 if (it->getName() == block_name) {
5685 type_name, it->getMeshsetId(),
"load_history");
5689 return std::string();
5692 for (
auto bc : bc_mng->getBcMapByBlockName()) {
5693 if (
auto disp_bc = bc.second->dispBcPtr) {
5698 <<
"Field name: " <<
field_name <<
" Block name: " << block_name;
5699 MOFEM_LOG(
"EP", Sev::noisy) <<
"Displacement BC: " << *disp_bc;
5701 std::vector<double> block_attributes(6, 0.);
5702 if (disp_bc->data.flag1 == 1) {
5703 block_attributes[0] = disp_bc->data.value1;
5704 block_attributes[3] = 1;
5706 if (disp_bc->data.flag2 == 1) {
5707 block_attributes[1] = disp_bc->data.value2;
5708 block_attributes[4] = 1;
5710 if (disp_bc->data.flag3 == 1) {
5711 block_attributes[2] = disp_bc->data.value3;
5712 block_attributes[5] = 1;
5714 auto faces = bc.second->bcEnts.subset_by_dimension(2);
5716 get_fix_load_history(block_name));
5723 boost::make_shared<NormalDisplacementBcVec>();
5728 for (
auto it : mesh_mng->getCubitMeshsetPtr(
5729 std::regex((boost::format(
"(.*)%s(.*)") %
"SPRING_BC").str()))) {
5730 std::vector<double> block_attributes;
5731 CHKERR it->getAttributes(block_attributes);
5732 if (block_attributes.size() < 2) {
5734 "In block %s expected 2 attributes, but given %ld",
5735 it->getName().c_str(), block_attributes.size());
5741 <<
"Found spring BC on block " << it->getName();
5743 <<
" kn = " << block_attributes[0] <<
", kt = " << block_attributes[1];
5744 MOFEM_LOG(
"EP", Sev::inform) <<
" nb. of faces " << faces.size();
5749 boost::make_shared<AnalyticalDisplacementBcVec>();
5753 auto ts_displacement =
5754 boost::make_shared<DynamicRelaxationTimeScale>(
"disp_history.txt");
5757 <<
"Add time scaling displacement BC: " << bc.blockName;
5758 if (!bc.loadHistoryFile.empty()) {
5760 <<
"Displacement load history from JSON for " << bc.blockName <<
": "
5761 << bc.loadHistoryFile;
5763 boost::make_shared<DynamicRelaxationTimeScale>(bc.loadHistoryFile);
5767 ts_displacement,
"disp_history",
".txt", bc.blockName);
5771 auto ts_normal_displacement =
5772 boost::make_shared<DynamicRelaxationTimeScale>(
"normal_disp_history.txt");
5775 <<
"Add time scaling normal displacement BC: " << bc.blockName;
5776 if (!bc.loadHistoryFile.empty()) {
5778 <<
"Normal displacement load history from JSON for " << bc.blockName
5779 <<
": " << bc.loadHistoryFile;
5781 boost::make_shared<DynamicRelaxationTimeScale>(bc.loadHistoryFile);
5785 ts_normal_displacement,
"normal_disp_history",
".txt",
5802 for (
auto bc : bc_mng->getBcMapByBlockName()) {
5803 if (
auto force_bc = bc.second->forceBcPtr) {
5808 <<
"Field name: " <<
field_name <<
" Block name: " << block_name;
5809 MOFEM_LOG(
"EP", Sev::noisy) <<
"Force BC: " << *force_bc;
5811 std::vector<double> block_attributes(6, 0.);
5812 block_attributes[0] = -force_bc->data.value3 * force_bc->data.value1;
5813 block_attributes[3] = 1;
5814 block_attributes[1] = -force_bc->data.value4 * force_bc->data.value1;
5815 block_attributes[4] = 1;
5816 block_attributes[2] = -force_bc->data.value5 * force_bc->data.value1;
5817 block_attributes[5] = 1;
5818 auto faces = bc.second->bcEnts.subset_by_dimension(2);
5829 boost::make_shared<AnalyticalTractionBcVec>();
5833 boost::make_shared<DynamicRelaxationTimeScale>(
"traction_history.txt");
5835 if (!bc.loadHistoryFile.empty()) {
5837 <<
"Traction load history from JSON for " << bc.blockName <<
": "
5838 << bc.loadHistoryFile;
5840 boost::make_shared<DynamicRelaxationTimeScale>(bc.loadHistoryFile);
5844 ts_traction,
"traction_history",
".txt", bc.blockName);
5849 boost::make_shared<DynamicRelaxationTimeScale>(
"pressure_history.txt");
5851 if (!bc.loadHistoryFile.empty()) {
5853 <<
"Pressure load history from JSON for " << bc.blockName <<
": "
5854 << bc.loadHistoryFile;
5856 boost::make_shared<DynamicRelaxationTimeScale>(bc.loadHistoryFile);
5860 ts_pressure,
"pressure_history",
".txt", bc.blockName);
5871 &ext_strain_vec_ptr,
5872 const std::string block_name,
5873 const int nb_attributes) {
5876 std::regex((boost::format(
"(.*)%s(.*)") % block_name).str()))) {
5877 std::vector<double> block_attributes;
5878 const bool analytical_external_strain = std::regex_match(
5879 it->getName(), std::regex(
"(.*)ANALYTICAL_EXTERNALSTRAIN(.*)"));
5880 const std::string json_block_name =
5881 analytical_external_strain ?
"ANALYTICAL_EXTERNALSTRAIN" : block_name;
5883 CHKERR it->getAttributes(block_attributes);
5885 if (block_attributes.size() < nb_attributes) {
5887 "In block %s expected %d attributes, but given %ld",
5888 it->getName().c_str(), nb_attributes, block_attributes.size());
5891 auto get_block_ents = [&]() {
5898 std::string load_history;
5899 if (!analytical_external_strain) {
5901 json_block_name, it->getMeshsetId(),
"load_history");
5903 ext_strain_vec_ptr->emplace_back(it->getName(), block_attributes,
5904 get_block_ents(), load_history);
5913 auto ts_pre_stretch = boost::make_shared<DynamicRelaxationTimeScale>(
5914 "externalstrain_history.txt");
5917 <<
"Add time scaling external strain: " << ext_strain_block.blockName;
5918 if (!ext_strain_block.loadHistoryFile.empty()) {
5920 <<
"External strain load history from JSON for "
5921 << ext_strain_block.blockName <<
": "
5922 << ext_strain_block.loadHistoryFile;
5924 boost::make_shared<DynamicRelaxationTimeScale>(
5925 ext_strain_block.loadHistoryFile);
5929 ts_pre_stretch,
"externalstrain_history",
".txt",
5930 ext_strain_block.blockName);
5940 auto print_loc_size = [
this](
auto v,
auto str,
auto sev) {
5943 CHKERR VecGetLocalSize(
v.second, &size);
5945 CHKERR VecGetOwnershipRange(
v.second, &low, &high);
5946 MOFEM_LOG(
"EPSYNC", sev) << str <<
" local size " << size <<
" ( " << low
5947 <<
" " << high <<
" ) ";
5969 double start_time) {
5974 auto storage = solve_elastic_setup::setup(
this, ts, x,
false);
5978 auto setup_ts_monitor = [&]() {
5979 auto monitor_ptr = boost::make_shared<EshelbianMonitor>(*
this);
5982 auto monitor_ptr = setup_ts_monitor();
5984 auto test_monitor_ptr =
5985 boost::make_shared<EshelbianTestingMonitor>(*
this, monitor_ptr);
5987 TetPolynomialBase::switchCacheBaseOn<HDIV>(
5990 CHKERR TSElasticPostStep::postStepInitialise(
this);
5992 double ts_delta_time;
5993 CHKERR TSGetTimeStep(ts, &ts_delta_time);
5996 CHKERR TSSetPreStep(ts, TSElasticPostStep::preStepFun);
5997 CHKERR TSSetPostStep(ts, TSElasticPostStep::postStepFun);
6000 CHKERR TSElasticPostStep::preStepFun(ts);
6001 CHKERR TSElasticPostStep::postStepFun(ts);
6003 double load_factor_change_clip = 0.1;
6005 PetscOptionsBegin(PETSC_COMM_WORLD,
"",
"Load Factor Options",
"none");
6007 CHKERR PetscOptionsScalar(
"-initial_load_factor",
"Initial load factor",
"",
6009 CHKERR PetscOptionsScalar(
6010 "-max_crack_ext_area",
"Maximum crack extension area",
"",
6012 CHKERR PetscOptionsScalar(
6013 "-clip_load_factor_percent",
"Upper bound for load factor change",
"",
6014 load_factor_change_clip, &load_factor_change_clip, PETSC_NULLPTR);
6020 monitor_ptr->ts = ts;
6021 monitor_ptr->ts_u = PETSC_NULLPTR;
6026 PetscBool test_cook_flg = PETSC_FALSE;
6033 test_monitor_ptr->ts = ts;
6034 test_monitor_ptr->ts_u = PETSC_NULLPTR;
6048 double load_factor_modifier = 1.0;
6059 CHKERR TSSetStepNumber(ts, 0);
6061 CHKERR TSSetTimeStep(ts, ts_delta_time);
6063 CHKERR TSElasticPostStep::preStepFun(ts);
6065 CHKERR TSSetSolution(ts, x);
6066 CHKERR TSSolve(ts, PETSC_NULLPTR);
6069 CHKERR TSElasticPostStep::postStepFun(ts);
6074 CHKERR VecGhostUpdateBegin(x, INSERT_VALUES, SCATTER_FORWARD);
6075 CHKERR VecGhostUpdateEnd(x, INSERT_VALUES, SCATTER_FORWARD);
6077 monitor_ptr->ts = ts;
6078 monitor_ptr->ts_u = x;
6084 test_monitor_ptr->ts = ts;
6085 test_monitor_ptr->ts_u = x;
6094 auto update_load_factor_modifier = [&](
auto reason) {
6098 <<
" consecutive steps. Increasing load factor range to allow "
6099 "for larger increments.";
6100 load_factor_modifier += 1.0;
6102 load_factor_modifier = 1.0;
6106 const bool crack_arrest_stops =
6108 update_load_factor_modifier(crack_arrest_stops
6109 ?
"Potential crack arrest"
6110 :
"No cracking occured");
6112 if (crack_arrest_stops) {
6113 physicalDt = initial_dt * load_factor_modifier;
6116 <<
"Potential crack arrest detected. Increasing load factor by "
6121 const double updated_load_factor =
6123 loadFactor = std::max(updated_load_factor, 1.0e-6);
6126 <<
"Griffith energy is zero, cannot update load factor.";
6131 const double initial_step_range = 0;
6132 const double min_load_factor = 1.0e-6;
6133 const double max_load_factor =
6135 (1.0 + load_factor_change_clip * load_factor_modifier);
6140 <<
"Allowable range for load factor [" << min_load_factor <<
", "
6141 << max_load_factor <<
"]";
6149 <<
"Setting new load factor to: " <<
loadFactor;
6152 CHKERR MPI_Bcast(load_control_data, 2, MPI_DOUBLE, 0, MPI_COMM_WORLD);
6160 const double remainingPhysicalTime =
6169 CHKERR TSElasticPostStep::postStepDestroy();
6170 TetPolynomialBase::switchCacheBaseOff<HDIV>(
6179 double start_time) {
6182 auto storage = solve_elastic_setup::setup(
this, ts, x,
false);
6184 auto topological_tao_ctx = createTopologicalTAOCtx(
6189 double final_time = 1;
6190 double delta_time = 0.1;
6192 PetscBool ts_h1_update = PETSC_FALSE;
6194 PetscOptionsBegin(PETSC_COMM_WORLD,
"",
"Dynamic Relaxation Options",
"none");
6196 CHKERR PetscOptionsScalar(
"-dynamic_final_time",
6197 "dynamic relaxation final time",
"", final_time,
6198 &final_time, PETSC_NULLPTR);
6199 CHKERR PetscOptionsScalar(
"-dynamic_delta_time",
6200 "dynamic relaxation final time",
"", delta_time,
6201 &delta_time, PETSC_NULLPTR);
6202 CHKERR PetscOptionsInt(
"-dynamic_max_it",
"dynamic relaxation iterations",
"",
6203 max_it, &max_it, PETSC_NULLPTR);
6204 CHKERR PetscOptionsBool(
"-dynamic_h1_update",
"update each ts step",
"",
6205 ts_h1_update, &ts_h1_update, PETSC_NULLPTR);
6211 <<
"Dynamic relaxation final time -dynamic_final_time = " << final_time;
6213 <<
"Dynamic relaxation delta time -dynamic_delta_time = " << delta_time;
6215 <<
"Dynamic relaxation max iterations -dynamic_max_it = " << max_it;
6217 <<
"Dynamic relaxation H1 update each step -dynamic_h1_update = "
6218 << (ts_h1_update ?
"TRUE" :
"FALSE");
6222 auto setup_ts_monitor = [&]() {
6223 auto monitor_ptr = boost::make_shared<EshelbianMonitor>(*
this);
6226 auto monitor_ptr = setup_ts_monitor();
6228 TetPolynomialBase::switchCacheBaseOn<HDIV>(
6231 CHKERR TSElasticPostStep::postStepInitialise(
this);
6233 double ts_delta_time;
6234 CHKERR TSGetTimeStep(ts, &ts_delta_time);
6237 CHKERR TSSetPreStep(ts, TSElasticPostStep::preStepFun);
6238 CHKERR TSSetPostStep(ts, TSElasticPostStep::postStepFun);
6241 CHKERR TSElasticPostStep::preStepFun(ts);
6242 CHKERR TSElasticPostStep::postStepFun(ts);
6245 CHKERR TaoSetType(tao, TAOLMVM);
6248 topologicalEvaluateObjectiveAndGradient,
6249 (
void *)topological_tao_ctx.get());
6253 monitor_ptr->ts = PETSC_NULLPTR;
6254 monitor_ptr->ts_u = PETSC_NULLPTR;
6262 CHKERR VecGhostUpdateBegin(tao_sol0, INSERT_VALUES, SCATTER_FORWARD);
6263 CHKERR VecGhostUpdateEnd(tao_sol0, INSERT_VALUES, SCATTER_FORWARD);
6265 int tao_sol_size, tao_sol_loc_size;
6266 CHKERR VecGetSize(tao_sol0, &tao_sol_size);
6267 CHKERR VecGetLocalSize(tao_sol0, &tao_sol_loc_size);
6269 <<
"Toplogical data vector size " << tao_sol_size <<
" local size "
6270 << tao_sol_loc_size <<
" number of interface faces "
6273 CHKERR TaoSetFromOptions(tao);
6275 if (delta_time <= 0.) {
6277 "delta_time must be positive, got %g", delta_time);
6282 <<
" delta time " << delta_time;
6284 CHKERR VecZeroEntries(tao_sol0);
6285 CHKERR VecGhostUpdateBegin(tao_sol0, INSERT_VALUES, SCATTER_FORWARD);
6286 CHKERR VecGhostUpdateEnd(tao_sol0, INSERT_VALUES, SCATTER_FORWARD);
6287 CHKERR TaoSetSolution(tao, tao_sol0);
6290 CHKERR TaoGetSolution(tao, &tao_sol);
6294 CHKERR VecGhostUpdateBegin(x, INSERT_VALUES, SCATTER_FORWARD);
6295 CHKERR VecGhostUpdateEnd(x, INSERT_VALUES, SCATTER_FORWARD);
6296 monitor_ptr->ts = PETSC_NULLPTR;
6297 monitor_ptr->ts_u = x;
6307 if (delta_time >= remainingPhysicalTime) {
6314 CHKERR TSElasticPostStep::postStepDestroy();
6315 TetPolynomialBase::switchCacheBaseOff<HDIV>(
6323 double start_time) {
6326 auto storage = solve_elastic_setup::setup(
this, ts, x,
false);
6330 auto topological_tao_ctx = createTopologicalTAOCtx(
6338 auto monitor_ptr = boost::make_shared<EshelbianMonitor>(*
this);
6340 TetPolynomialBase::switchCacheBaseOn<HDIV>(
6343 CHKERR TSElasticPostStep::postStepInitialise(
this);
6345 double ts_delta_time;
6346 CHKERR TSGetTimeStep(ts, &ts_delta_time);
6349 CHKERR TSSetPreStep(ts, TSElasticPostStep::preStepFun);
6350 CHKERR TSSetPostStep(ts, TSElasticPostStep::postStepFun);
6353 CHKERR TSElasticPostStep::preStepFun(ts);
6354 CHKERR TSElasticPostStep::postStepFun(ts);
6356 const bool restart_run =
6358 std::abs(start_time) > std::numeric_limits<double>::epsilon();
6361 std::abs(test_time) < std::numeric_limits<double>::epsilon()) {
6364 "Set non-zero -physical_final_time for test_topological_derivative");
6369 monitor_ptr->ts = PETSC_NULLPTR;
6370 monitor_ptr->ts_u = PETSC_NULLPTR;
6376 <<
"Solving load step before topological derivative test: "
6378 <<
" TS delta time " << ts_delta_time;
6380 CHKERR TSSetStepNumber(ts, 0);
6382 CHKERR TSSetTimeStep(ts, ts_delta_time);
6384 CHKERR TSElasticPostStep::preStepFun(ts);
6386 CHKERR TSSetSolution(ts, x);
6387 CHKERR TSSolve(ts, PETSC_NULLPTR);
6389 CHKERR TSElasticPostStep::postStepFun(ts);
6393 CHKERR VecGhostUpdateBegin(x, INSERT_VALUES, SCATTER_FORWARD);
6394 CHKERR VecGhostUpdateEnd(x, INSERT_VALUES, SCATTER_FORWARD);
6396 monitor_ptr->ts = PETSC_NULLPTR;
6397 monitor_ptr->ts_u = x;
6405 CHKERR VecGhostUpdateBegin(tao_sol0, INSERT_VALUES, SCATTER_FORWARD);
6406 CHKERR VecGhostUpdateEnd(tao_sol0, INSERT_VALUES, SCATTER_FORWARD);
6408 int tao_sol_size, tao_sol_loc_size;
6409 CHKERR VecGetSize(tao_sol0, &tao_sol_size);
6410 CHKERR VecGetLocalSize(tao_sol0, &tao_sol_loc_size);
6412 <<
"Topological data vector size " << tao_sol_size <<
" local size "
6413 << tao_sol_loc_size <<
" number of interface faces "
6416 const char *list_objective_models[ObjectiveModelType::LAST_MODEL] = {
6417 "python_model",
"hencky_model"};
6418#ifdef ENABLE_PYTHON_BINDING
6419 PetscInt choice_objective_model = ObjectiveModelType::PYTHON_MODEL;
6421 PetscInt choice_objective_model = ObjectiveModelType::HENCKY_MODEL;
6424 "-objective_model_type", list_objective_models,
6425 ObjectiveModelType::LAST_MODEL,
6426 &choice_objective_model, PETSC_NULLPTR);
6427 const auto objective_model_type =
6428 static_cast<ObjectiveModelType
>(choice_objective_model);
6429 MOFEM_LOG(
"EP", Sev::inform) <<
"Objective model type: -objective_model_type "
6430 << list_objective_models[objective_model_type];
6433 PetscReal obj_value;
6434 CHKERR testTopologicalDerivative(topological_tao_ctx.get(), tao_sol0,
6435 &obj_value,
g, objective_model_type);
6437 CHKERR TSElasticPostStep::postStepDestroy();
6438 TetPolynomialBase::switchCacheBaseOff<HDIV>(
6446 double start_time) {
6451 "The equilibrated mechanical value test requires "
6452 "-plastic_volume 1 and -cohesive_interface_on 0");
6453 CHKERR validateEquilibratedMechanicalValueScope(*
this);
6455 auto storage = solve_elastic_setup::setup(
this, ts, x,
false);
6460 TetPolynomialBase::switchCacheBaseOn<HDIV>(
6462 CHKERR TSSetSolution(ts, x);
6464 CHKERR TSElasticPostStep::postStepInitialise(
this);
6466 const bool restart_run =
6468 std::abs(start_time) > std::numeric_limits<double>::epsilon();
6472 "Set non-zero -physical_final_time for "
6473 "test_equilibrated_mechanical_value");
6476 CHKERR testEquilibratedMechanicalValue(*
this, ts, x);
6478 CHKERR TSElasticPostStep::postStepDestroy();
6479 TetPolynomialBase::switchCacheBaseOff<HDIV>(
6487 double start_time) {
6492 "The incremental-optimization transaction test currently requires "
6493 "-plastic_volume 1 and -cohesive_interface_on 0");
6494 CHKERR validateEquilibratedMechanicalValueScope(*
this);
6496 auto storage = solve_elastic_setup::setup(
this, ts, x,
false);
6501 TetPolynomialBase::switchCacheBaseOn<HDIV>(
6503 CHKERR TSSetSolution(ts, x);
6505 CHKERR TSElasticPostStep::postStepInitialise(
this);
6507 const bool restart_run =
6509 std::abs(start_time) > std::numeric_limits<double>::epsilon();
6513 "Set non-zero -physical_final_time for "
6514 "test_incremental_optimization_transaction");
6517 CHKERR testIncrementalOptimizationTransaction(*
this, ts, x);
6519 CHKERR TSElasticPostStep::postStepDestroy();
6520 TetPolynomialBase::switchCacheBaseOff<HDIV>(
6527 TS ts, Vec x,
int start_step,
double start_time) {
6532 "The incremental-optimization derivative test currently requires "
6533 "-plastic_volume 1 and -cohesive_interface_on 0");
6534 CHKERR validateEquilibratedMechanicalValueScope(*
this);
6536 auto storage = solve_elastic_setup::setup(
this, ts, x,
false);
6541 TetPolynomialBase::switchCacheBaseOn<HDIV>(
6543 CHKERR TSSetSolution(ts, x);
6545 CHKERR TSElasticPostStep::postStepInitialise(
this);
6547 const bool restart_run =
6549 std::abs(start_time) > std::numeric_limits<double>::epsilon();
6552 std::numeric_limits<double>::epsilon())
6554 "Set non-zero -physical_final_time for "
6555 "test_incremental_optimization_objective_derivative");
6558 CHKERR testIncrementalOptimizationObjectiveDerivative(*
this, ts, x);
6560 CHKERR TSElasticPostStep::postStepDestroy();
6561 TetPolynomialBase::switchCacheBaseOff<HDIV>(
6568 TS ts, Vec x,
int start_step,
double start_time) {
6573 "The incremental-optimization constraint derivative test "
6574 "requires -plastic_volume 1 and -cohesive_interface_on 0");
6575 CHKERR validateEquilibratedMechanicalValueScope(*
this);
6577 auto storage = solve_elastic_setup::setup(
this, ts, x,
false);
6582 TetPolynomialBase::switchCacheBaseOn<HDIV>(
6584 CHKERR TSSetSolution(ts, x);
6586 CHKERR TSElasticPostStep::postStepInitialise(
this);
6588 const bool restart_run =
6590 std::abs(start_time) > std::numeric_limits<double>::epsilon();
6593 std::numeric_limits<double>::epsilon())
6595 "Set non-zero -physical_final_time for "
6596 "test_incremental_optimization_constraint_derivative");
6599 CHKERR testIncrementalOptimizationConstraintDerivative(*
this, ts, x);
6601 CHKERR TSElasticPostStep::postStepDestroy();
6602 TetPolynomialBase::switchCacheBaseOff<HDIV>(
6608 TS ts, Vec x,
int start_step,
double start_time) {
6613 "-solver_type incremental_optimization currently supports "
6614 "-plastic_volume 1 and -cohesive_interface_on 0 only");
6615 CHKERR validateEquilibratedMechanicalValueScope(*
this);
6616 auto storage = solve_elastic_setup::setup(
this, ts, x,
false);
6621 TetPolynomialBase::switchCacheBaseOn<HDIV>(
6623 CHKERR TSSetSolution(ts, x);
6625 CHKERR TSElasticPostStep::postStepInitialise(
this);
6629 "Incremental-optimization final physical time %g must exceed "
6630 "the start time %g",
6634 "Incremental-optimization physical time step must be positive, "
6639 "Incremental-optimization physical maximum steps must be "
6643 PetscBool monitor_physical_steps = PETSC_TRUE;
6645 "-incremental_optimization_step_monitor",
6646 &monitor_physical_steps, PETSC_NULLPTR);
6647 boost::shared_ptr<EshelbianMonitor> monitor_ptr;
6648 if (monitor_physical_steps)
6649 monitor_ptr = boost::make_shared<EshelbianMonitor>(*
this);
6650 auto monitor_committed_step = [&]() {
6656 CHKERR VecGhostUpdateBegin(x, INSERT_VALUES, SCATTER_FORWARD);
6657 CHKERR VecGhostUpdateEnd(x, INSERT_VALUES, SCATTER_FORWARD);
6658 monitor_ptr->ts = PETSC_NULLPTR;
6659 monitor_ptr->ts_u = x;
6665 auto clear_incremental_control_fields = [&]() {
6669 CHKERR PlasticIncrementalOptimizationInternal::clearPlasticIncrementFields(
6679 CHKERR clear_incremental_control_fields();
6680 CHKERR monitor_committed_step();
6682 const double time_tolerance =
6683 10 * std::numeric_limits<double>::epsilon() *
6685 int completed_steps = 0;
6699 CHKERR TSSetSolution(ts, x);
6701 CHKERR TSElasticPostStep::preStepFun(ts);
6707 CHKERR TSSetSolution(ts, x);
6709 CHKERR TSElasticPostStep::postStepFun(ts);
6714 clear_incremental_control_fields();
6716 CHKERR clear_control_error;
6720 const bool reached_final_time =
6723 CHKERR TSElasticPostStep::postStepDestroy();
6724 TetPolynomialBase::switchCacheBaseOff<HDIV>(
6727 if (!reached_final_time)
6729 "Incremental optimization stopped at time %g after %d steps "
6730 "before final time %g; increase -physical_max_steps",
6734 <<
"Incremental optimization completed " << completed_steps
boost::shared_ptr< DataAtIntegrationPts > dataAtPts
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_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.
Native restart vector layout validation.
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,...)
Shared implementation details for plastic incremental optimization.
Plasticity implementation of incremental optimization.
#define FTENSOR_INDEXES(DIM,...)
#define FTENSOR_INDEX(DIM, I)
Range get_range_from_block(MoFEM::Interface &m_field, const std::string block_name, int dim)
ElementsAndOps< SPACE_DIM >::BoundaryEle BoundaryEle
FieldApproximationBase
approximation base
@ AINSWORTH_LEGENDRE_BASE
Ainsworth Cole (Legendre) approx. base .
@ USER_BASE
user implemented approximation base
#define MOAB_THROW(err)
Check error code of MoAB function and throw MoFEM exception.
#define CHK_THROW_MESSAGE(err, msg)
Check and throw MoFEM exception.
#define MoFEMFunctionReturnHot(a)
Last executable line of each PETSc function used for error handling. Replaces return()
@ L2
field with C-1 continuity
@ HDIV
field with continuous normal traction
#define MYPCOMM_INDEX
default communicator number PCOMM
@ DISCONTINUOUS
Broken continuity (No effect on L2 space)
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
#define CHK_MOAB_THROW(err, msg)
Check error code of MoAB function and throw MoFEM exception.
@ MOFEM_OPERATION_UNSUCCESSFUL
@ 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.
virtual bool check_field(const std::string &name) const =0
check if field is in database
#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 addFieldToEmptyFieldBlocks(const std::string problem_name, const std::string row_field, const std::string col_field) const
Add empty field blocks to optimize matrix storage.
MoFEMErrorCode pushMarkDOFsOnEntities(const std::string problem_name, const std::string block_name, const std::string field_name, int lo, int hi, bool get_low_dim_ents=true)
Mark DOFs on block entities for boundary conditions.
#define NBVOLUMETET_L2(P)
Number of base functions on tetrahedron for L2 space.
FTensor::Index< 'i', SPACE_DIM > i
const double v
phase velocity of light in medium (cm/ns)
const double n
refractive index of diffusive medium
FTensor::Index< 'J', DIM1 > J
FTensor::Index< 'l', 3 > l
FTensor::Index< 'j', 3 > j
static auto filter_true_skin(MoFEM::Interface &m_field, Range &&skin)
static MoFEMErrorCode checkDynamicToleranceCompatibility(TS ts)
static auto get_range_from_block(MoFEM::Interface &m_field, const std::string block_name, int dim)
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.
boost::shared_ptr< ContactSDFPython > setupContactSdf(MoFEM::Interface &m_field)
Read SDF file and setup contact SDF.
static MoFEMErrorCode RelaxationResidualMonitor(TS ts, PetscInt, PetscReal, Vec, void *)
MoFEMErrorCode addCalculatePlasticLogarithmicStretchFieldValues(boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pipeline, const std::string &field_name, boost::shared_ptr< MatrixDouble > tensor_values, const EntityType zero_type, SmartPetscObj< DM > data_dm, SmartPetscObj< Vec > data_vector)
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
decltype(GetFTensor2SymmetricFromMatImpl< Tensor_Dim, S, DL, M >::get(std::declval< M & >(), 0, 0)) GetFTensor2SymmetricFromMatType
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.
decltype(GetFTensor2FromMatImpl< Tensor_Dim0, Tensor_Dim1, S, DL, M >::get(std::declval< M & >(), 0, 0)) GetFTensor2FromMatType
auto createTao(MPI_Comm comm)
auto ent_form_type_and_id(const EntityType type, const EntityID id)
get entity handle from type and id
OpPostProcMapInMoab< SPACE_DIM, SPACE_DIM > OpPPMap
constexpr double t
plate stiffness
constexpr auto field_name
PipelineManager::ElementsAndOpsByDim< SPACE_DIM >::FaceSideEle EleOnSide
FTensor::Index< 'm', 3 > m
CGG User Polynomial Base.
static boost::shared_ptr< SetUpSchur > createSetUpSchur(MoFEM::Interface &m_field, EshelbianCore *ep_core_ptr)
SmartPetscObj< Vec > incrementalTrialControl
MoFEMErrorCode setElasticElementOps(const int tag)
boost::shared_ptr< ExternalStrainVec > externalStrainVecPtr
static PetscBool physicalH1Update
static enum StretchSelector stretchSelector
boost::shared_ptr< Range > frontAdjEdges
static int interfaceRemoveLevel
MoFEMErrorCode addBoundaryFiniteElement(const EntityHandle meshset=0)
const std::string skeletonElement
static double inv_dd_f_linear(const double)
static double inv_f_linear(const double v)
boost::shared_ptr< TractionBcVec > bcSpatialTractionVecPtr
boost::shared_ptr< Range > contactFaces
static double dd_f_log_e_quadratic(const double v)
static double inv_d_f_linear(const double)
double dynamicInitialResidual
static double dd_f_linear(const double)
BitRefLevel bitAdjEnt
bit ref level for parent
static boost::function< double(const double)> inv_dd_f
MoFEM::Interface & mField
const std::string spatialL2Disp
std::map< std::string, boost::shared_ptr< ScalingMethod > > timeScaleMap
static enum SolverType solverType
MoFEMErrorCode postProcessSkeletonResults(const int tag, const std::string file, Vec f_residual=PETSC_NULLPTR, std::vector< Tag > tags_to_transfer={}, TS ts=PETSC_NULLPTR)
static PetscBool l2UserBaseScale
SmartPetscObj< DM > dM
Coupled problem all fields.
MoFEMErrorCode solveSchapeOptimisation(TS ts, Vec x, int start_step, double start_time)
Solve shape optimisation problem.
boost::shared_ptr< Range > plasticVolumes
boost::shared_ptr< TractionFreeBc > bcSpatialFreeTractionVecPtr
static const char * listSolvers[]
const std::string materialH1Positions
static int nbJIntegralContours
MoFEMErrorCode applyTestSolverMonitorOptions(TS ts)
MoFEMErrorCode setBlockTagsOnSkin()
static PetscBool crackingOn
MoFEMErrorCode getTractionFreeBc(const EntityHandle meshset, boost::shared_ptr< TractionFreeBc > &bc_ptr, const std::string contact_set_name)
Remove all, but entities where kinematic constrains are applied.
MoFEMErrorCode applyProjectionSolverMonitorOptions()
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={})
MoFEMErrorCode pushVolumeA00Ops(boost::shared_ptr< VolumeElementForcesAndSourcesCore > fe_lhs)
const std::string elementVolumeName
static double dd_f_log_e(const double v)
static double d_f_linear(const double)
static enum RotSelector rotSelector
MoFEMErrorCode addDebugModel(TS ts)
Add debug to model.
static enum RotSelector gradApproximator
PetscBool loadFactorTSSolveExecuted
MoFEMErrorCode postProcessResults(const int tag, const std::string file, Vec f_residual=PETSC_NULLPTR, Vec var_vec=PETSC_NULLPTR, Vec gradient=PETSC_NULLPTR, std::vector< Tag > tags_to_transfer={}, TS ts=PETSC_NULLPTR)
MoFEMErrorCode getBc(boost::shared_ptr< BC > &bc_vec_ptr, const std::string block_name, const int nb_attributes)
static double inv_dd_f_log_e_quadratic(const double stretch)
CommInterface::EntitiesPetscVector vertexExchange
static std::vector< std::string > listTagsToProject
boost::shared_ptr< BcRotVec > bcSpatialRotationVecPtr
static std::string heterogeneousYoungModTagName
const std::string spatialH1Disp
static FieldApproximationBase brokenHdivBase
static double maxCrackExtension
static int physicalMaxSteps
MoFEMErrorCode solveElastic(TS ts, Vec x)
@ TestIncrementalOptimizationConstraintDerivative
@ TestIncrementalOptimizationLayout
@ TestIncrementalOptimizationTransaction
@ TestIncrementalOptimizationObjectiveDerivative
@ IncrementalOptimization
@ TestTopologicalDerivative
@ TestEquilibratedMechanicalValue
boost::shared_ptr< NormalDisplacementBcVec > bcSpatialNormalDisplacementVecPtr
MoFEMErrorCode solveTestIncrementalOptimizationTransaction(TS ts, Vec x, int start_step, double start_time)
static double crackingStartTime
MoFEMErrorCode getOptions()
const std::string plasticHField
const std::string piolaStress
MoFEMErrorCode setElasticElementToTs(DM dm)
static double inv_d_f_log_e(const double v)
std::string getStringArgumentFromJsonBlockset(const std::string &type_name, const int meshset_id, const std::string ¶m_name)
int contactRefinementLevels
static int physicalStepNumber
MoFEMErrorCode gettingNorms()
[Getting norms]
MoFEMErrorCode solveTestEquilibratedMechanicalValue(TS ts, Vec x, int start_step, double start_time)
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
MoFEMErrorCode solveIncrementalOptimizationTAO(TS ts, Vec x, int start_step, double start_time)
Solve the incremental constitutive optimization with TAO.
boost::shared_ptr< AnalyticalDisplacementBcVec > bcSpatialAnalyticalDisplacementVecPtr
const std::string plasticFlowField
SmartPetscObj< DM > dmMaterial
Material problem.
MoFEMErrorCode runIncrementalOptimizationTAO(TS ts, Vec x)
boost::shared_ptr< VolumeElementForcesAndSourcesCore > elasticFeLhs
MoFEMErrorCode solveTestIncrementalOptimizationObjectiveDerivative(TS ts, Vec x, int start_step, double start_time)
MoFEMErrorCode resolveDissipationEntities(const EntityHandle meshset=0)
boost::shared_ptr< ParentFiniteElementAdjacencyFunctionSkeleton< 2 > > parentAdjSkeletonFunctionDim2
static double crackingAddTime
MoFEMErrorCode setFaceElementOps(const bool add_elastic, const bool add_material, boost::shared_ptr< FaceElementForcesAndSourcesCore > &fe_rhs, boost::shared_ptr< FaceElementForcesAndSourcesCore > &fe_lhs)
MoFEMErrorCode projectGeometry(const EntityHandle meshset=0, double time=0)
static double currentPhysicalTime
boost::shared_ptr< AnalyticalExprPython > AnalyticalExprPythonPtr
boost::shared_ptr< SpringBcVec > bcSpatialSpringVecPtr
static double crackingAtol
Cracking absolute tolerance.
MoFEMErrorCode projectMaterialTags(const EntityHandle meshset=0)
boost::shared_ptr< Range > skeletonFaces
static double crackingRtol
Cracking relative tolerance.
boost::shared_ptr< PhysicalEquations > physicalEquations
const std::string rotAxis
static PetscBool meshTransferHybridInterp
BitRefLevel bitAdjParentMask
bit ref level for parent parent
MoFEMErrorCode solveDynamicRelaxation(TS ts, Vec x, int start_step, double start_time)
Solve problem using dynamic relaxation method.
const std::string contactDisp
static std::string internalStressTagName
CommInterface::EntitiesPetscVector edgeExchange
SmartPetscObj< DM > dmPrjSpatial
Projection spatial displacement.
static boost::function< double(const double)> f
MoFEMErrorCode solveTestTopologicalDerivative(TS ts, Vec x, int start_step, double start_time)
static int nbStepsNoCrackExtension
boost::shared_ptr< BcDispVec > bcSpatialDispVecPtr
static double finalPhysicalTime
const std::string skinElement
static PetscBool internalStressVoigt
MoFEMErrorCode addVolumeFiniteElement(const EntityHandle meshset=0, const bool add_bubble=true)
MoFEMErrorCode solveTestIncrementalOptimizationConstraintDerivative(TS ts, Vec x, int start_step, double start_time)
static double inv_dd_f_log_e(const double v)
MoFEMErrorCode getExternalStrain()
MoFEMErrorCode getSpatialTractionBc()
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
static PetscBool plasticVolume
boost::shared_ptr< double > currentCrackAreaPtr
static PetscBool meshTransferSourceMeshFileSpecified
static double f_log_e_quadratic(const double v)
double avgGriffithsEnergy
static double inv_f_log_e_quadratic(const double stretch)
MoFEMErrorCode addDMs(const BitRefLevel bit=BitRefLevel().set(0), const EntityHandle meshset=0)
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 bool potentialCrackArrest
static PetscBool propagateUnderCompression
static double inv_f_log_e(const double v)
MoFEMErrorCode createExchangeVectors(Sev sev)
boost::shared_ptr< DataAtIntegrationPts > dataAtPts
boost::shared_ptr< Range > crackFaces
static boost::function< double(const double)> d_f
boost::shared_ptr< Range > frontVertices
static enum EnergyReleaseSelector energyReleaseSelector
static boost::function< double(const double)> inv_d_f
boost::shared_ptr< PressureBcVec > bcSpatialPressureVecPtr
static int meshTransferInterpOrder
const std::string hybridSpatialDisp
SmartPetscObj< Vec > solTSStep
static double inv_d_f_log_e_quadratic(const double stretch)
CommInterface::EntitiesPetscVector faceExchange
SmartPetscObj< DM > dmElastic
Elastic problem.
static std::string meshTransferSourceMeshFileName
EshelbianCore(MoFEM::Interface &m_field)
const std::string plasticKappaField
boost::shared_ptr< Range > frontEdges
static boost::function< double(const double)> inv_f
BitRefLevel bitAdjEntMask
bit ref level for parent parent
static double f_linear(const double v)
SmartPetscObj< DM > dmIncrementalOptimization
Incremental-optimization control problem.
MoFEMErrorCode addFields(const EntityHandle meshset=0, const bool add_bubble=true)
MoFEMErrorCode withFieldOrders(Op &&op) const
MoFEMErrorCode pushStressGramOps(boost::shared_ptr< VolumeElementForcesAndSourcesCore > fe_lhs)
const std::string contactElement
MoFEMErrorCode pushPiolaStressGramOps(boost::shared_ptr< VolumeElementForcesAndSourcesCore > fe_lhs)
AnalyticalDisplacementBc(std::string name, std::vector< double > attr, Range faces, std::string load_history_file="")
AnalyticalTractionBc(std::string name, std::vector< double > attr, Range faces, std::string load_history_file="")
BcRot(std::string name, std::vector< double > attr, Range faces, std::string load_history_file="")
ExternalStrain(std::string name, std::vector< double > attr, Range ents, std::string load_history_file="")
NormalDisplacementBc(std::string name, std::vector< double > attr, Range faces, std::string load_history_file="")
OpApplyPlasticFlowIncrement(boost::shared_ptr< DataAtIntegrationPts > data_ptr)
boost::shared_ptr< DataAtIntegrationPts > dataAtPts
MoFEMErrorCode doWork(int, EntityType, EntData &) override
Operator for linear form, usually to calculate values on right hand side.
@ CURRENT
Current state of the field.
@ PREVIOUS
Previous state of the field.
PressureBc(std::string name, std::vector< double > attr, Range faces, std::string load_history_file="")
boost::shared_ptr< Range > frontNodes
SetIntegrationAtFrontFace(boost::shared_ptr< Range > front_nodes, boost::shared_ptr< Range > front_edges, int(*)(int))
SetIntegrationAtFrontFace(boost::shared_ptr< Range > front_nodes, boost::shared_ptr< Range > front_edges)
boost::shared_ptr< Range > frontEdges
MoFEMErrorCode operator()(ForcesAndSourcesCore *fe_raw_ptr, int order_row, int order_col, int order_data)
static std::map< long int, MatrixDouble > mapRefCoords
MoFEMErrorCode operator()(ForcesAndSourcesCore *fe_raw_ptr, int order_row, int order_col, int order_data)
boost::shared_ptr< Range > frontNodes
static std::map< long int, MatrixDouble > mapRefCoords
boost::function< int(int)> FunRule
boost::shared_ptr< CGGUserPolynomialBase::CachePhi > cachePhi
SetIntegrationAtFrontVolume(boost::shared_ptr< Range > front_nodes, boost::shared_ptr< Range > front_edges, boost::shared_ptr< CGGUserPolynomialBase::CachePhi > cache_phi=nullptr)
SetIntegrationAtFrontVolume(boost::shared_ptr< Range > front_nodes, boost::shared_ptr< Range > front_edges, FunRule fun_rule, boost::shared_ptr< CGGUserPolynomialBase::CachePhi > cache_phi=nullptr)
boost::shared_ptr< Range > frontEdges
SpringBc(std::string name, std::vector< double > attr, Range faces)
double tangentialStiffness
static MoFEMErrorCode preStepFun(TS ts)
static MoFEMErrorCode postStepDestroy()
static MoFEMErrorCode postStepFun(TS ts)
static MoFEMErrorCode postStepInitialise(EshelbianCore *ep_ptr)
TractionBc(std::string name, std::vector< double > attr, Range faces, std::string load_history_file="")
static auto setup(EshelbianCore *ep_ptr, TS ts, Vec x, bool set_ts_monitor)
multi_index_container< DofsSideMapData, indexed_by< ordered_non_unique< tag< TypeSide_mi_tag >, composite_key< DofsSideMapData, member< DofsSideMapData, EntityType, &DofsSideMapData::type >, member< DofsSideMapData, int, &DofsSideMapData::side > > >, ordered_unique< tag< EntDofIdx_mi_tag >, member< DofsSideMapData, int, &DofsSideMapData::dof > > > > DofsSideMap
Map entity stype and side to element/entity dof index.
Template specialization for displacement boundary conditions.
Boundary condition manager for finite element problem setup.
static std::pair< std::string, std::string > extractStringFromBlockId(const std::string block_id, const std::string prb_name)
Extract block name and block name from block id.
Template specialization system for type-safe boundary condition handling.
static MoFEMErrorCode updateEntitiesPetscVector(moab::Interface &moab, EntitiesPetscVector &vec, Tag tag, UpdateGhosts update_gosts=defaultUpdateGhosts)
Exchange data between vector and data.
static Range getPartEntities(moab::Interface &moab, int part)
static EntitiesPetscVector createEntitiesPetscVector(MPI_Comm comm, moab::Interface &moab, std::function< Range(Range)> get_entities_fun, const int nb_coeffs, Sev sev=Sev::verbose, int root_rank=0, bool get_vertices=true)
Create a ghost vector for exchanging data.
virtual moab::Interface & get_moab()=0
virtual MoFEMErrorCode add_broken_field(const std::string name, const FieldSpace space, const FieldApproximationBase base, const FieldCoefficientsNumber nb_of_coefficients, const std::vector< std::pair< EntityType, std::function< MoFEMErrorCode(BaseFunction::DofsSideMap &)> > > list_dof_side_map, const TagType tag_type=MB_TAG_SPARSE, const enum MoFEMTypes bh=MF_EXCL, int verb=DEFAULT_VERBOSITY)=0
Add field.
virtual bool check_finite_element(const std::string &name) const =0
Check if finite element is in database.
virtual MoFEMErrorCode build_adjacencies(const Range &ents, int verb=DEFAULT_VERBOSITY)=0
build adjacencies
virtual MoFEMErrorCode add_field(const std::string name, const FieldSpace space, const FieldApproximationBase base, const FieldCoefficientsNumber nb_of_coefficients, const TagType tag_type=MB_TAG_SPARSE, const enum MoFEMTypes bh=MF_EXCL, int verb=DEFAULT_VERBOSITY)=0
Add field.
virtual MPI_Comm & get_comm() const =0
virtual int get_comm_rank() const =0
Deprecated interface functions.
Data on single entity (This is passed as argument to DataOperator::doWork)
Structure for user loop methods on finite elements.
EntityHandle getFEEntityHandle() const
Get the entity handle of the current finite element.
Field data structure for finite element approximation.
Definition of the force bc data structure.
@ OPSPACE
operator do Work is execute on space data
MatrixDouble & getGaussPts()
matrix of integration (Gauss) points for Volume Element
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.
Specialization for double precision scalar field values calculation.
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, ScalarDataPtr > DataMapVec
std::map< std::string, boost::shared_ptr< MatrixDouble > > DataMapMat
@ CTX_SET_TIME
Time value is set.
static constexpr Switches CtxSetTime
Time value switch.
static MoFEMErrorCode writeTSGraphGraphviz(TsCtx *ts_ctx, std::string file_name)
TS graph to Graphviz file.
Template struct for dimension-specific finite element types.
Problem manager is used to build and partition problems.
Projection of edge entities with one mid-node on hierarchical basis.
intrusive_ptr for managing petsc objects
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