10 using namespace MoFEM;
15 #include <boost/math/constants/constants.hpp>
19 #include <boost/python.hpp>
20 #include <boost/python/def.hpp>
21 #include <boost/python/numpy.hpp>
22 namespace bp = boost::python;
23 namespace np = boost::python::numpy;
25 #pragma message "With PYTHON_SDF"
29 #pragma message "Without PYTHON_SDF"
53 const std::string block_name,
int dim) {
59 std::regex((boost::format(
"%s(.*)") % block_name).str())
78 CHKERR moab.add_entities(*out_meshset,
r);
80 CHKERR moab.write_file(name.c_str(),
"VTK",
"", out_meshset->get_ptr(), 1);
82 MOFEM_LOG(
"SELF", Sev::warning) <<
"Empty range for " << name;
97 return MatSetValues<AssemblyTypeSelector<SCHUR>>(
98 op_ptr->
getKSPB(), row_data, col_data,
m, ADD_VALUES);
108 int order_col,
int order_data) {
111 auto &m_field = fe_raw_ptr->
mField;
112 auto vol_fe_ptr =
dynamic_cast<VolFe *
>(fe_raw_ptr);
115 auto set_base_quadrature = [&]() {
117 int rule = 2 * order_data + 1;
128 auto &gauss_pts = vol_fe_ptr->gaussPts;
129 gauss_pts.resize(4, nb_gauss_pts,
false);
130 cblas_dcopy(nb_gauss_pts, &
QUAD_3D_TABLE[rule]->points[1], 4,
131 &gauss_pts(0, 0), 1);
132 cblas_dcopy(nb_gauss_pts, &
QUAD_3D_TABLE[rule]->points[2], 4,
133 &gauss_pts(1, 0), 1);
134 cblas_dcopy(nb_gauss_pts, &
QUAD_3D_TABLE[rule]->points[3], 4,
135 &gauss_pts(2, 0), 1);
137 &gauss_pts(3, 0), 1);
138 auto &data = vol_fe_ptr->dataOnElement[
H1];
139 data->dataOnEntities[MBVERTEX][0].getN(
NOBASE).resize(nb_gauss_pts, 4,
142 &*data->dataOnEntities[MBVERTEX][0].getN(
NOBASE).data().begin();
143 cblas_dcopy(4 * nb_gauss_pts,
QUAD_3D_TABLE[rule]->points, 1,
147 "rule > quadrature order %d < %d", rule,
153 CHKERR set_base_quadrature();
155 if (frontNodes->size() && EshelbianCore::setSingularity) {
157 auto get_singular_nodes = [&]() {
160 CHKERR m_field.get_moab().get_connectivity(fe_handle, conn, num_nodes,
162 std::bitset<numNodes> singular_nodes;
163 for (
auto nn = 0; nn != numNodes; ++nn) {
164 if (frontNodes->find(conn[nn]) != frontNodes->end()) {
165 singular_nodes.set(nn);
167 singular_nodes.reset(nn);
170 return singular_nodes;
173 auto get_singular_edges = [&]() {
174 std::bitset<numEdges> singular_edges;
175 for (
int ee = 0; ee != numEdges; ee++) {
177 CHKERR m_field.get_moab().side_element(fe_handle, 1, ee, edge);
178 if (frontEdges->find(edge) != frontEdges->end()) {
179 singular_edges.set(ee);
181 singular_edges.reset(ee);
184 return singular_edges;
187 auto set_gauss_pts = [&](
auto &ref_gauss_pts) {
189 vol_fe_ptr->gaussPts.swap(ref_gauss_pts);
190 const size_t nb_gauss_pts = vol_fe_ptr->gaussPts.size2();
201 auto singular_nodes = get_singular_nodes();
202 if (singular_nodes.count()) {
203 auto it_map_ref_coords =
mapRefCoords.find(singular_nodes.to_ulong());
205 CHKERR set_gauss_pts(it_map_ref_coords->second);
209 auto refine_quadrature = [&]() {
212 const int max_level = refinementLevels;
216 double base_coords[] = {0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1};
218 for (
int nn = 0; nn != 4; nn++)
219 CHKERR moab_ref.create_vertex(&base_coords[3 * nn], nodes[nn]);
220 CHKERR moab_ref.create_element(MBTET, nodes, 4, tet);
226 Range nodes_at_front;
227 for (
int nn = 0; nn != numNodes; nn++) {
228 if (singular_nodes[nn]) {
230 CHKERR moab_ref.side_element(tet, 0, nn, ent);
231 nodes_at_front.insert(ent);
235 auto singular_edges = get_singular_edges();
238 CHKERR moab_ref.create_meshset(MESHSET_SET, meshset);
239 for (
int ee = 0; ee != 6; ee++) {
240 if (singular_edges[ee]) {
242 CHKERR moab_ref.side_element(tet, 1, ee, ent);
243 CHKERR moab_ref.add_entities(meshset, &ent, 1);
249 for (
int ll = 0; ll != max_level; ll++) {
252 ->getEntitiesByTypeAndRefLevel(
BitRefLevel().set(ll),
256 CHKERR moab_ref.get_adjacencies(
257 nodes_at_front, 1,
true, ref_edges, moab::Interface::UNION);
258 ref_edges = intersect(ref_edges, edges);
260 CHKERR moab_ref.get_entities_by_type(meshset, MBEDGE, ents,
true);
261 ref_edges = intersect(ref_edges, ents);
264 ->getEntitiesByTypeAndRefLevel(
266 CHKERR m_ref->addVerticesInTheMiddleOfEdges(
270 ->updateMeshsetByEntitiesChildren(meshset,
272 meshset, MBEDGE,
true);
278 ->getEntitiesByTypeAndRefLevel(
BitRefLevel().set(max_level),
283 for (Range::iterator tit = tets.begin(); tit != tets.end();
287 CHKERR moab_ref.get_connectivity(*tit, conn, num_nodes,
false);
288 CHKERR moab_ref.get_coords(conn, num_nodes, &ref_coords(tt, 0));
291 auto &data = vol_fe_ptr->dataOnElement[
H1];
292 const size_t nb_gauss_pts = vol_fe_ptr->gaussPts.size2();
293 MatrixDouble ref_gauss_pts(4, nb_gauss_pts * ref_coords.size1());
295 data->dataOnEntities[MBVERTEX][0].getN(
NOBASE);
297 for (
size_t tt = 0; tt != ref_coords.size1(); tt++) {
298 double *tet_coords = &ref_coords(tt, 0);
301 for (
size_t ggg = 0; ggg != nb_gauss_pts; ++ggg, ++gg) {
302 for (
int dd = 0;
dd != 3;
dd++) {
303 ref_gauss_pts(
dd, gg) =
304 shape_n(ggg, 0) * tet_coords[3 * 0 +
dd] +
305 shape_n(ggg, 1) * tet_coords[3 * 1 +
dd] +
306 shape_n(ggg, 2) * tet_coords[3 * 2 +
dd] +
307 shape_n(ggg, 3) * tet_coords[3 * 3 +
dd];
309 ref_gauss_pts(3, gg) = vol_fe_ptr->gaussPts(3, ggg) * det;
313 mapRefCoords[singular_nodes.to_ulong()].swap(ref_gauss_pts);
330 static inline constexpr
int numNodes = 4;
331 static inline constexpr
int numEdges = 6;
332 static inline constexpr
int refinementLevels = 3;
339 double EshelbianCore::exponentBase = exp(1);
342 EshelbianCore::d_f_log_e;
344 EshelbianCore::dd_f_log_e;
345 boost::function<
double(
const double)> EshelbianCore::inv_f =
346 EshelbianCore::inv_f_log;
347 boost::function<
double(
const double)> EshelbianCore::inv_d_f =
348 EshelbianCore::inv_d_f_log;
349 boost::function<
double(
const double)> EshelbianCore::inv_dd_f =
350 EshelbianCore::inv_dd_f_log;
353 EshelbianCore::query_interface(boost::typeindex::type_index type_index,
379 const char *list_rots[] = {
"small",
"moderate",
"large",
"no_h1"};
383 const char *list_stretches[] = {
"linear",
"log"};
386 CHKERR PetscOptionsBegin(PETSC_COMM_WORLD,
"",
"Eshelbian plasticity",
388 CHKERR PetscOptionsInt(
"-space_order",
"approximation oder for space",
"",
390 CHKERR PetscOptionsInt(
"-space_h1_order",
"approximation oder for space",
"",
392 CHKERR PetscOptionsInt(
"-material_order",
"approximation oder for material",
394 CHKERR PetscOptionsScalar(
"-viscosity_alpha_u",
"viscosity",
"",
alphaU,
396 CHKERR PetscOptionsScalar(
"-viscosity_alpha_w",
"viscosity",
"",
alphaW,
398 CHKERR PetscOptionsScalar(
"-density_alpha_rho",
"density",
"",
alphaRho,
400 CHKERR PetscOptionsEList(
"-rotations",
"rotations",
"", list_rots,
401 LARGE_ROT + 1, list_rots[choice_rot], &choice_rot,
403 CHKERR PetscOptionsEList(
"-grad",
"gradient of defamation approximate",
"",
405 list_rots[choice_grad], &choice_grad, PETSC_NULL);
410 list_stretches[choice_stretch], &choice_stretch, PETSC_NULL);
412 CHKERR PetscOptionsBool(
"-no_stretch",
"do not solve for stretch",
"",
414 CHKERR PetscOptionsBool(
"-set_singularity",
"set singularity",
"",
418 CHKERR PetscOptionsInt(
"-contact_max_post_proc_ref_level",
"refinement level",
422 ierr = PetscOptionsEnd();
468 MOFEM_LOG(
"EP", Sev::inform) <<
"Gradient of deformation "
474 MOFEM_LOG(
"EP", Sev::inform) <<
"Base exponent e";
475 MOFEM_LOG(
"EP", Sev::inform) <<
"Stretch " << list_stretches[choice_stretch];
486 auto get_tets = [&]() {
492 auto get_tets_skin = [&]() {
493 Range tets_skin_part;
495 CHKERR skin.find_skin(0, get_tets(),
false, tets_skin_part);
496 ParallelComm *pcomm =
499 CHKERR pcomm->filter_pstatus(tets_skin_part,
500 PSTATUS_SHARED | PSTATUS_MULTISHARED,
501 PSTATUS_NOT, -1, &tets_skin);
505 auto subtract_boundary_conditions = [&](
auto &&tets_skin) {
511 tets_skin = subtract(tets_skin,
v.faces);
516 auto add_blockset = [&](
auto block_name,
auto &&tets_skin) {
519 tets_skin.merge(crack_faces);
523 auto subtract_blockset = [&](
auto block_name,
auto &&tets_skin) {
526 tets_skin = subtract(tets_skin, contact_range);
530 auto get_stress_trace_faces = [&](
auto &&tets_skin) {
533 faces, moab::Interface::UNION);
534 Range trace_faces = subtract(faces, tets_skin);
538 auto tets = get_tets();
542 auto trace_faces = get_stress_trace_faces(
544 subtract_blockset(
"CONTACT",
545 subtract_boundary_conditions(get_tets_skin()))
552 boost::make_shared<Range>(subtract(trace_faces, *
contactFaces));
554 boost::make_shared<Range>(get_stress_trace_faces(
Range()));
566 auto add_broken_hdiv_field = [
this, meshset](
const std::string
field_name,
572 auto get_side_map_hdiv = [&]() {
575 std::pair<EntityType,
590 get_side_map_hdiv(), MB_TAG_DENSE,
MF_ZERO);
596 auto add_l2_field = [
this, meshset](
const std::string
field_name,
597 const int order,
const int dim) {
606 auto add_h1_field = [
this, meshset](
const std::string
field_name,
607 const int order,
const int dim) {
619 auto add_l2_field_by_range = [
this](
const std::string
field_name,
620 const int order,
const int dim,
621 const int field_dim,
Range &&
r) {
631 auto add_bubble_field = [
this, meshset](
const std::string
field_name,
632 const int order,
const int dim) {
638 auto field_order_table =
639 const_cast<Field *
>(field_ptr)->getFieldOrderTable();
640 auto get_cgg_bubble_order_zero = [](
int p) {
return 0; };
641 auto get_cgg_bubble_order_tet = [](
int p) {
644 field_order_table[MBVERTEX] = get_cgg_bubble_order_zero;
645 field_order_table[MBEDGE] = get_cgg_bubble_order_zero;
646 field_order_table[MBTRI] = get_cgg_bubble_order_zero;
647 field_order_table[MBTET] = get_cgg_bubble_order_tet;
654 auto add_user_l2_field = [
this, meshset](
const std::string
field_name,
655 const int order,
const int dim) {
661 auto field_order_table =
662 const_cast<Field *
>(field_ptr)->getFieldOrderTable();
663 auto zero_dofs = [](
int p) {
return 0; };
665 field_order_table[MBVERTEX] = zero_dofs;
666 field_order_table[MBEDGE] = zero_dofs;
667 field_order_table[MBTRI] = zero_dofs;
668 field_order_table[MBTET] = dof_l2_tet;
710 auto project_ho_geometry = [&]() {
714 CHKERR project_ho_geometry();
716 auto get_skin = [&](
auto &body_ents) {
719 CHKERR skin.find_skin(0, body_ents,
false, skin_ents);
723 auto filter_true_skin = [&](
auto &&skin) {
725 ParallelComm *pcomm =
727 CHKERR pcomm->filter_pstatus(skin, PSTATUS_SHARED | PSTATUS_MULTISHARED,
728 PSTATUS_NOT, -1, &boundary_ents);
729 return boundary_ents;
732 auto get_crack_front_edges = [&]() {
737 auto body_skin = filter_true_skin(get_skin(body_ents));
738 Range body_skin_edges;
739 CHKERR moab.get_adjacencies(body_skin,
SPACE_DIM - 2,
true, body_skin_edges,
740 moab::Interface::UNION);
742 crack_skin = subtract(crack_skin, body_skin_edges);
743 std::map<int, Range> received_ents;
745 crack_skin, &received_ents);
748 for (
auto &
m : received_ents) {
752 to_remove.merge(intersect(crack_skin,
m.second));
756 crack_skin = subtract(crack_skin, to_remove);
760 return boost::make_shared<Range>(crack_skin);
763 auto get_adj_front_edges = [&](
auto &front_edges) {
765 Range front_crack_nodes;
766 CHKERR moab.get_connectivity(front_edges, front_crack_nodes,
true);
769 Range crack_front_edges;
771 crack_front_edges, moab::Interface::UNION);
772 crack_front_edges = subtract(crack_front_edges, front_edges);
776 Range crack_front_edges_nodes;
777 CHKERR moab.get_connectivity(crack_front_edges, crack_front_edges_nodes,
779 crack_front_edges_nodes =
780 subtract(crack_front_edges_nodes, front_crack_nodes);
781 Range crack_front_edges_with_both_nodes_not_at_front;
782 CHKERR moab.get_adjacencies(crack_front_edges_nodes,
SPACE_DIM - 2,
false,
783 crack_front_edges_with_both_nodes_not_at_front,
784 moab::Interface::UNION);
785 crack_front_edges_with_both_nodes_not_at_front = intersect(
786 crack_front_edges_with_both_nodes_not_at_front, crack_front_edges);
788 return std::make_pair(boost::make_shared<Range>(front_crack_nodes),
789 boost::make_shared<Range>(
790 crack_front_edges_with_both_nodes_not_at_front));
796 auto [front_vertices, front_adj_edges] = get_adj_front_edges(*
frontEdges);
800 auto set_singular_dofs = [&](
auto &front_adj_edges,
auto &front_vertices) {
808 MOFEM_LOG(
"EP", Sev::inform) <<
"Singularity eps " << beta;
811 for (
auto edge : front_adj_edges) {
814 CHKERR moab.get_connectivity(edge, conn, num_nodes,
false);
816 CHKERR moab.get_coords(conn, num_nodes, coords);
817 const double dir[3] = {coords[3] - coords[0], coords[4] - coords[1],
818 coords[5] - coords[2]};
819 double dof[3] = {0, 0, 0};
820 if (front_vertices.find(conn[0]) != front_vertices.end()) {
821 for (
int dd = 0;
dd != 3;
dd++) {
824 }
else if (front_vertices.find(conn[1]) != front_vertices.end()) {
825 for (
int dd = 0;
dd != 3;
dd++) {
831 const int idx = dit->get()->getEntDofIdx();
833 dit->get()->getFieldData() = 0;
835 dit->get()->getFieldData() = dof[idx];
854 auto add_field_to_fe = [
this](
const std::string fe,
887 Range front_elements;
889 Range front_elements_layer;
891 front_elements_layer,
892 moab::Interface::UNION);
893 front_elements.merge(front_elements_layer);
897 moab::Interface::UNION);
915 auto set_fe_adjacency = [&](
auto fe_name) {
918 boost::make_shared<ParentFiniteElementAdjacencyFunctionSkeleton<2>>(
926 auto add_field_to_fe = [
this](
const std::string fe,
938 Range natural_bc_elements;
941 natural_bc_elements.merge(
v.faces);
946 natural_bc_elements.merge(
v.faces);
951 natural_bc_elements.merge(
v.faces);
962 auto get_skin = [&](
auto &body_ents) {
965 CHKERR skin.find_skin(0, body_ents,
false, skin_ents);
969 auto filter_true_skin = [&](
auto &&skin) {
971 ParallelComm *pcomm =
973 CHKERR pcomm->filter_pstatus(skin, PSTATUS_SHARED | PSTATUS_MULTISHARED,
974 PSTATUS_NOT, -1, &boundary_ents);
975 return boundary_ents;
982 auto skin = filter_true_skin(get_skin(body_ents));
1034 Range front_elements;
1036 Range front_elements_layer;
1038 front_elements_layer,
1039 moab::Interface::UNION);
1040 front_elements.merge(front_elements_layer);
1041 front_edges.clear();
1044 moab::Interface::UNION);
1048 Range front_elements_faces;
1050 true, front_elements_faces,
1051 moab::Interface::UNION);
1052 auto body_skin = filter_true_skin(get_skin(body_ents));
1053 auto front_elements_skin = filter_true_skin(get_skin(front_elements));
1054 Range material_skeleton_faces =
1055 subtract(front_elements_faces, front_elements_skin);
1056 material_skeleton_faces.merge(intersect(front_elements_skin, body_skin));
1061 front_elements_skin);
1063 material_skeleton_faces);
1125 auto remove_dofs_on_broken_skin = [&](
const std::string prb_name) {
1127 for (
int d : {0, 1, 2}) {
1128 std::vector<boost::weak_ptr<NumeredDofEntity>> dofs_to_remove;
1130 ->getSideDofsOnBrokenSpaceEntities(
1141 CHKERR remove_dofs_on_broken_skin(
"ESHELBY_PLASTICITY");
1177 auto set_zero_block = [&]() {
1207 auto set_section = [&]() {
1209 PetscSection section;
1214 CHKERR PetscSectionDestroy(§ion);
1231 ->pushMarkDOFsOnEntities<DisplacementCubitBcData>(
1238 : blockName(name), faces(faces) {
1239 vals.resize(3,
false);
1240 flags.resize(3,
false);
1241 for (
int ii = 0; ii != 3; ++ii) {
1242 vals[ii] = attr[ii];
1243 flags[ii] =
static_cast<int>(attr[ii + 3]);
1246 MOFEM_LOG(
"EP", Sev::inform) <<
"Add BCDisp " << name;
1248 <<
"Add BCDisp vals " <<
vals[0] <<
" " <<
vals[1] <<
" " <<
vals[2];
1250 <<
"Add BCDisp flags " <<
flags[0] <<
" " <<
flags[1] <<
" " <<
flags[2];
1251 MOFEM_LOG(
"EP", Sev::inform) <<
"Add BCDisp nb. of faces " <<
faces.size();
1255 : blockName(name), faces(faces) {
1256 vals.resize(3,
false);
1257 for (
int ii = 0; ii != 3; ++ii) {
1258 vals[ii] = attr[ii];
1265 : blockName(name), faces(faces) {
1266 vals.resize(3,
false);
1267 flags.resize(3,
false);
1268 for (
int ii = 0; ii != 3; ++ii) {
1269 vals[ii] = attr[ii];
1270 flags[ii] =
static_cast<int>(attr[ii + 3]);
1273 MOFEM_LOG(
"EP", Sev::inform) <<
"Add BCForce " << name;
1275 <<
"Add BCForce vals " <<
vals[0] <<
" " <<
vals[1] <<
" " <<
vals[2];
1277 <<
"Add BCForce flags " <<
flags[0] <<
" " <<
flags[1] <<
" " <<
flags[2];
1278 MOFEM_LOG(
"EP", Sev::inform) <<
"Add BCForce nb. of faces " <<
faces.size();
1283 boost::shared_ptr<TractionFreeBc> &bc_ptr,
1284 const std::string contact_set_name) {
1290 Range tets_skin_part;
1292 CHKERR skin.find_skin(0, tets,
false, tets_skin_part);
1293 ParallelComm *pcomm =
1296 CHKERR pcomm->filter_pstatus(tets_skin_part,
1297 PSTATUS_SHARED | PSTATUS_MULTISHARED,
1298 PSTATUS_NOT, -1, &tets_skin);
1301 for (
int dd = 0;
dd != 3; ++
dd)
1302 (*bc_ptr)[
dd] = tets_skin;
1308 (*bc_ptr)[0] = subtract((*bc_ptr)[0],
v.faces);
1310 (*bc_ptr)[1] = subtract((*bc_ptr)[1],
v.faces);
1312 (*bc_ptr)[2] = subtract((*bc_ptr)[2],
v.faces);
1318 (*bc_ptr)[0] = subtract((*bc_ptr)[0],
v.faces);
1319 (*bc_ptr)[1] = subtract((*bc_ptr)[1],
v.faces);
1320 (*bc_ptr)[2] = subtract((*bc_ptr)[2],
v.faces);
1325 (*bc_ptr)[0] = subtract((*bc_ptr)[0],
v.faces);
1326 (*bc_ptr)[1] = subtract((*bc_ptr)[1],
v.faces);
1327 (*bc_ptr)[2] = subtract((*bc_ptr)[2],
v.faces);
1332 std::regex((boost::format(
"%s(.*)") % contact_set_name).str()))) {
1336 (*bc_ptr)[0] = subtract((*bc_ptr)[0], faces);
1337 (*bc_ptr)[1] = subtract((*bc_ptr)[1], faces);
1338 (*bc_ptr)[2] = subtract((*bc_ptr)[2], faces);
1358 return 2 * p_data + 1;
1364 return 2 * (p_data + 1);
1369 boost::shared_ptr<CachePhi> cache_phi_otr)
1373 boost::typeindex::type_index type_index,
1381 boost::shared_ptr<BaseFunctionCtx> ctx_ptr) {
1386 int nb_gauss_pts = pts.size2();
1387 if (!nb_gauss_pts) {
1391 if (pts.size1() < 3) {
1393 "Wrong dimension of pts, should be at least 3 rows with "
1397 const auto base = this->cTx->bAse;
1400 switch (this->cTx->sPace) {
1405 data.
dataOnEntities[MBVERTEX][0].getN(base).resize(nb_gauss_pts, 4,
false);
1406 CHKERR Tools::shapeFunMBTET(
1408 &pts(0, 0), &pts(1, 0), &pts(2, 0), nb_gauss_pts);
1409 data.
dataOnEntities[MBVERTEX][0].getDiffN(base).resize(4, 3,
false);
1410 std::copy(Tools::diffShapeFunMBTET.begin(), Tools::diffShapeFunMBTET.end(),
1413 CHKERR getValueL2AinsworthBase(pts);
1429 "Wrong base, should be USER_BASE");
1437 const int nb_gauss_pts = pts.size2();
1439 auto check_cache = [
this](
int order,
int nb_gauss_pts) ->
bool {
1448 if (check_cache(
order, nb_gauss_pts)) {
1451 phi.resize(mat.size1(), mat.size2(),
false);
1456 shapeFun.resize(nb_gauss_pts, 4,
false);
1458 &pts(2, 0), nb_gauss_pts);
1460 double diff_shape_fun[12];
1466 phi.resize(nb_gauss_pts, 9 * nb_base_functions,
false);
1489 const int tag,
const bool do_rhs,
const bool do_lhs,
1490 boost::shared_ptr<VolumeElementForcesAndSourcesCore> &fe) {
1492 fe = boost::make_shared<VolumeElementForcesAndSourcesCore>(
mField);
1495 boost::make_shared<CGGUserPolynomialBase::CachePhi>(0, 0,
MatrixDouble());
1496 fe->getUserPolynomialBase() =
1497 boost::make_shared<CGGUserPolynomialBase>(bubble_cache);
1519 fe->getOpPtrVector().push_back(
1523 fe->getOpPtrVector().push_back(
1538 fe->getOpPtrVector().push_back(
1546 if (std::abs(
alphaRho) > std::numeric_limits<double>::epsilon()) {
1558 fe->getOpPtrVector().push_back(
1572 const int tag,
const bool add_elastic,
const bool add_material,
1573 boost::shared_ptr<VolumeElementForcesAndSourcesCore> &fe_rhs,
1574 boost::shared_ptr<VolumeElementForcesAndSourcesCore> &fe_lhs) {
1578 auto get_body_range = [
this](
auto name,
int dim) {
1579 std::map<int, Range> map;
1584 (boost::format(
"%s(.*)") % name).str()
1593 map[m_ptr->getMeshsetId()] = ents;
1599 auto rule_contact = [](
int,
int,
int o) {
return -1; };
1602 auto set_rule_contact = [refine](
1605 int order_col,
int order_data
1609 auto rule = 2 * order_data;
1610 fe_raw_ptr->
gaussPts = Tools::refineTriangleIntegrationPts(rule, refine);
1614 auto time_scale = boost::make_shared<TimeScale>();
1621 fe_rhs->getOpPtrVector().push_back(
1623 fe_rhs->getOpPtrVector().push_back(
1628 fe_rhs->getOpPtrVector().push_back(
1632 fe_rhs->getOpPtrVector().push_back(
1634 fe_rhs->getOpPtrVector().push_back(
1636 fe_rhs->getOpPtrVector().push_back(
1639 auto set_hybridisation = [&](
auto &pip) {
1653 op_loop_skeleton_side->getSideFEPtr()->getRuleHook =
FaceRule();
1654 CHKERR EshelbianPlasticity::
1655 AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
1656 op_loop_skeleton_side->getOpPtrVector(), {L2},
1661 auto broken_data_ptr =
1662 boost::make_shared<std::vector<BrokenBaseSideData>>();
1666 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
1667 boost::make_shared<CGGUserPolynomialBase>();
1670 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
1672 op_loop_domain_side->getOpPtrVector().push_back(
1674 auto flux_mat_ptr = boost::make_shared<MatrixDouble>();
1675 op_loop_domain_side->getOpPtrVector().push_back(
1678 op_loop_domain_side->getOpPtrVector().push_back(
1682 op_loop_skeleton_side->getOpPtrVector().push_back(op_loop_domain_side);
1684 GAUSS>::OpBrokenSpaceConstrainDHybrid<SPACE_DIM>;
1686 GAUSS>::OpBrokenSpaceConstrainDFlux<SPACE_DIM>;
1687 op_loop_skeleton_side->getOpPtrVector().push_back(
1689 auto hybrid_ptr = boost::make_shared<MatrixDouble>();
1690 op_loop_skeleton_side->getOpPtrVector().push_back(
1693 op_loop_skeleton_side->getOpPtrVector().push_back(
1694 new OpC_dBroken(broken_data_ptr, hybrid_ptr, 1.));
1697 pip.push_back(op_loop_skeleton_side);
1702 auto set_contact = [&](
auto &pip) {
1717 op_loop_skeleton_side->getSideFEPtr()->getRuleHook = rule_contact;
1718 op_loop_skeleton_side->getSideFEPtr()->setRuleHook = set_rule_contact;
1719 CHKERR EshelbianPlasticity::
1720 AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
1721 op_loop_skeleton_side->getOpPtrVector(), {L2},
1726 auto broken_data_ptr =
1727 boost::make_shared<std::vector<BrokenBaseSideData>>();
1730 auto contact_common_data_ptr =
1731 boost::make_shared<ContactOps::CommonData>();
1733 auto add_ops_domain_side = [&](
auto &pip) {
1738 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
1739 boost::make_shared<CGGUserPolynomialBase>();
1742 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
1744 op_loop_domain_side->getOpPtrVector().push_back(
1747 op_loop_domain_side->getOpPtrVector().push_back(
1749 piolaStress, contact_common_data_ptr->contactTractionPtr()));
1750 pip.push_back(op_loop_domain_side);
1754 auto add_ops_contact_rhs = [&](
auto &pip) {
1757 auto contact_sfd_map_range_ptr =
1758 boost::make_shared<std::map<int, Range>>(
1759 get_body_range(
"CONTACT_SDF",
SPACE_DIM - 1));
1762 contactDisp, contact_common_data_ptr->contactDispPtr()));
1763 auto u_h1_ptr = boost::make_shared<MatrixDouble>();
1772 contact_sfd_map_range_ptr));
1781 CHKERR add_ops_domain_side(op_loop_skeleton_side->getOpPtrVector());
1782 CHKERR add_ops_contact_rhs(op_loop_skeleton_side->getOpPtrVector());
1785 pip.push_back(op_loop_skeleton_side);
1790 CHKERR set_hybridisation(fe_rhs->getOpPtrVector());
1791 CHKERR set_contact(fe_rhs->getOpPtrVector());
1794 using BodyNaturalBC =
1796 Assembly<PETSC>::LinearForm<
GAUSS>;
1798 BodyNaturalBC::OpFlux<NaturalMeshsetType<BLOCKSET>, 1, 3>;
1799 CHKERR BodyNaturalBC::AddFluxToPipeline<OpBodyForce>::add(
1801 "BODY_FORCE", Sev::inform);
1810 const bool symmetric_system =
1814 fe_lhs->getOpPtrVector().push_back(
1818 fe_lhs->getOpPtrVector().push_back(
1822 fe_lhs->getOpPtrVector().push_back(
1829 if (!symmetric_system) {
1845 if (!symmetric_system) {
1850 fe_lhs->getOpPtrVector().push_back(
1854 auto set_hybridisation = [&](
auto &pip) {
1868 op_loop_skeleton_side->getSideFEPtr()->getRuleHook =
FaceRule();
1869 CHKERR EshelbianPlasticity::
1870 AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
1871 op_loop_skeleton_side->getOpPtrVector(), {L2},
1876 auto broken_data_ptr =
1877 boost::make_shared<std::vector<BrokenBaseSideData>>();
1881 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
1882 boost::make_shared<CGGUserPolynomialBase>();
1885 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
1887 op_loop_domain_side->getOpPtrVector().push_back(
1890 op_loop_skeleton_side->getOpPtrVector().push_back(op_loop_domain_side);
1892 GAUSS>::OpBrokenSpaceConstrain<SPACE_DIM>;
1893 op_loop_skeleton_side->getOpPtrVector().push_back(
1896 pip.push_back(op_loop_skeleton_side);
1901 auto set_contact = [&](
auto &pip) {
1916 op_loop_skeleton_side->getSideFEPtr()->getRuleHook = rule_contact;
1917 op_loop_skeleton_side->getSideFEPtr()->setRuleHook = set_rule_contact;
1918 CHKERR EshelbianPlasticity::
1919 AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
1920 op_loop_skeleton_side->getOpPtrVector(), {L2},
1925 auto broken_data_ptr =
1926 boost::make_shared<std::vector<BrokenBaseSideData>>();
1929 auto contact_common_data_ptr =
1930 boost::make_shared<ContactOps::CommonData>();
1932 auto add_ops_domain_side = [&](
auto &pip) {
1937 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
1938 boost::make_shared<CGGUserPolynomialBase>();
1941 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
1943 op_loop_domain_side->getOpPtrVector().push_back(
1946 op_loop_domain_side->getOpPtrVector().push_back(
1948 piolaStress, contact_common_data_ptr->contactTractionPtr()));
1949 pip.push_back(op_loop_domain_side);
1953 auto add_ops_contact_lhs = [&](
auto &pip) {
1956 contactDisp, contact_common_data_ptr->contactDispPtr()));
1957 auto u_h1_ptr = boost::make_shared<MatrixDouble>();
1966 auto contact_sfd_map_range_ptr =
1967 boost::make_shared<std::map<int, Range>>(
1968 get_body_range(
"CONTACT_SDF",
SPACE_DIM - 1));
1972 contact_sfd_map_range_ptr));
1975 contactDisp, broken_data_ptr, contact_common_data_ptr,
1979 broken_data_ptr,
contactDisp, contact_common_data_ptr,
1986 CHKERR add_ops_domain_side(op_loop_skeleton_side->getOpPtrVector());
1987 CHKERR add_ops_contact_lhs(op_loop_skeleton_side->getOpPtrVector());
1990 pip.push_back(op_loop_skeleton_side);
1995 CHKERR set_hybridisation(fe_lhs->getOpPtrVector());
1996 CHKERR set_contact(fe_lhs->getOpPtrVector());
2006 const bool add_elastic,
const bool add_material,
2007 boost::shared_ptr<FaceElementForcesAndSourcesCore> &fe_rhs,
2008 boost::shared_ptr<FaceElementForcesAndSourcesCore> &fe_lhs) {
2011 fe_rhs = boost::make_shared<FaceElementForcesAndSourcesCore>(
mField);
2012 fe_lhs = boost::make_shared<FaceElementForcesAndSourcesCore>(
mField);
2015 fe_rhs->getRuleHook = [](
int,
int,
int p) {
return 2 * (p + 1); };
2016 fe_lhs->getRuleHook = [](
int,
int,
int p) {
return 2 * (p + 1); };
2027 auto get_broken_op_side = [
this](
auto &pip) {
2032 auto broken_data_ptr =
2033 boost::make_shared<std::vector<BrokenBaseSideData>>();
2037 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
2038 boost::make_shared<CGGUserPolynomialBase>();
2041 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
2043 op_loop_domain_side->getOpPtrVector().push_back(
2045 pip.push_back(op_loop_domain_side);
2046 return broken_data_ptr;
2049 auto broken_data_ptr = get_broken_op_side(fe_rhs->getOpPtrVector());
2051 fe_rhs->getOpPtrVector().push_back(
2055 boost::make_shared<TimeScale>(
"disp_history.txt")
2063 boost::make_shared<TimeScale>(
"rotation_history.txt")
2067 fe_rhs->getOpPtrVector().push_back(
2076 boost::shared_ptr<ContactTree> &fe_contact_tree
2082 auto get_body_range = [
this](
auto name,
int dim) {
2083 std::map<int, Range> map;
2088 (boost::format(
"%s(.*)") % name).str()
2097 map[m_ptr->getMeshsetId()] = ents;
2103 auto get_map_skin = [
this](
auto &&map) {
2104 ParallelComm *pcomm =
2108 for (
auto &
m : map) {
2110 CHKERR skin.find_skin(0,
m.second,
false, skin_faces);
2112 PSTATUS_SHARED | PSTATUS_MULTISHARED,
2113 PSTATUS_NOT, -1,
nullptr),
2115 m.second.swap(skin_faces);
2125 auto contact_common_data_ptr = boost::make_shared<ContactOps::CommonData>();
2127 auto calcs_side_traction = [&](
auto &pip) {
2134 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
2135 boost::make_shared<CGGUserPolynomialBase>();
2137 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
2139 op_loop_domain_side->getOpPtrVector().push_back(
2141 piolaStress, contact_common_data_ptr->contactTractionPtr()));
2142 pip.push_back(op_loop_domain_side);
2146 auto add_contact_three = [&]() {
2148 auto tree_moab_ptr = boost::make_shared<moab::Core>();
2149 fe_contact_tree = boost::make_shared<ContactTree>(
2151 get_map_skin(get_body_range(
"BODY", 3)));
2152 fe_contact_tree->getOpPtrVector().push_back(
2154 contactDisp, contact_common_data_ptr->contactDispPtr()));
2155 CHKERR calcs_side_traction(fe_contact_tree->getOpPtrVector());
2156 auto u_h1_ptr = boost::make_shared<MatrixDouble>();
2157 fe_contact_tree->getOpPtrVector().push_back(
2159 fe_contact_tree->getOpPtrVector().push_back(
2160 new OpMoveNode(fe_contact_tree, contact_common_data_ptr, u_h1_ptr));
2164 CHKERR add_contact_three();
2180 boost::make_shared<ForcesAndSourcesCore::UserDataOperator::AdjCache>();
2182 auto get_op_contact_bc = [&]() {
2186 return op_loop_side;
2194 boost::shared_ptr<FEMethod>
null;
2196 if (std::abs(
alphaRho) > std::numeric_limits<double>::epsilon()) {
2230 boost::shared_ptr<ContactOps::SDFPython> sdf_python_ptr;
2232 auto file_exists = [](std::string myfile) {
2233 std::ifstream file(myfile.c_str());
2240 char sdf_file_name[255] =
"sdf.py";
2242 sdf_file_name, 255, PETSC_NULL);
2244 if (file_exists(sdf_file_name)) {
2245 MOFEM_LOG(
"EP", Sev::inform) << sdf_file_name <<
" file found";
2246 sdf_python_ptr = boost::make_shared<ContactOps::SDFPython>();
2247 CHKERR sdf_python_ptr->sdfInit(sdf_file_name);
2248 ContactOps::sdfPythonWeakPtr = sdf_python_ptr;
2250 MOFEM_LOG(
"EP", Sev::warning) << sdf_file_name <<
" file NOT found";
2255 boost::shared_ptr<TsCtx>
ts_ctx;
2263 CHKERR TSAppendOptionsPrefix(ts,
"elastic_");
2264 CHKERR TSSetFromOptions(ts);
2269 CHKERR TSGetSNES(ts, &snes);
2271 PetscViewerAndFormat *vf;
2272 CHKERR PetscViewerAndFormatCreate(PETSC_VIEWER_STDOUT_WORLD,
2273 PETSC_VIEWER_DEFAULT, &vf);
2276 (
MoFEMErrorCode(*)(SNES, PetscInt, PetscReal,
void *))SNESMonitorFields,
2279 PetscSection section;
2282 CHKERR PetscSectionGetNumFields(section, &num_fields);
2283 for (
int ff = 0; ff != num_fields; ff++) {
2290 CHKERR VecGhostUpdateBegin(x, INSERT_VALUES, SCATTER_FORWARD);
2291 CHKERR VecGhostUpdateEnd(x, INSERT_VALUES, SCATTER_FORWARD);
2294 boost::shared_ptr<SetUpSchur> schur_ptr;
2297 CHKERR schur_ptr->setUp(ts);
2300 if (std::abs(
alphaRho) > std::numeric_limits<double>::epsilon()) {
2302 CHKERR VecDuplicate(x, &xx);
2303 CHKERR VecZeroEntries(xx);
2304 CHKERR TS2SetSolution(ts, x, xx);
2307 CHKERR TSSetSolution(ts, x);
2310 TetPolynomialBase::switchCacheBaseOn<HDIV>(
2316 CHKERR TSSolve(ts, PETSC_NULL);
2318 TetPolynomialBase::switchCacheBaseOff<HDIV>(
2322 int lin_solver_iterations;
2323 CHKERR SNESGetLinearSolveIterations(snes, &lin_solver_iterations);
2325 <<
"Number of linear solver iterations " << lin_solver_iterations;
2327 PetscBool test_cook_flg = PETSC_FALSE;
2330 if (test_cook_flg) {
2331 constexpr
int expected_lin_solver_iterations = 11;
2332 if (lin_solver_iterations > expected_lin_solver_iterations)
2335 "Expected number of iterations is different than expected %d > %d",
2336 lin_solver_iterations, expected_lin_solver_iterations);
2345 const std::string file) {
2353 auto post_proc_mesh = boost::make_shared<moab::Core>();
2354 auto post_proc_begin =
2358 auto contact_common_data_ptr = boost::make_shared<ContactOps::CommonData>();
2360 auto get_post_proc = [&](
auto sense) {
2363 auto post_proc_ptr =
2364 boost::make_shared<PostProcBrokenMeshInMoabBaseCont<FaceEle>>(
2371 auto domain_ops = [&](
auto &fe,
int sense) {
2373 fe.getUserPolynomialBase() =
2383 fe.getOpPtrVector().push_back(
2387 fe.getOpPtrVector().push_back(
2401 fe.getOpPtrVector().push_back(
2409 fe.getOpPtrVector().push_back(op);
2419 post_proc_ptr->getPostProcMesh(), post_proc_ptr->getMapGaussPts(),
2425 post_proc_ptr->getOpPtrVector().push_back(
2428 auto X_h1_ptr = boost::make_shared<MatrixDouble>();
2430 post_proc_ptr->getOpPtrVector().push_back(
2437 domain_ops(*(op_loop_side->getSideFEPtr()), sense);
2438 post_proc_ptr->getOpPtrVector().push_back(op_loop_side);
2440 return post_proc_ptr;
2443 auto post_proc_ptr = get_post_proc(1);
2444 auto post_proc_negative_sense_ptr = get_post_proc(-1);
2447 auto u_h1_ptr = boost::make_shared<MatrixDouble>();
2448 auto lambda_h1_ptr = boost::make_shared<MatrixDouble>();
2449 post_proc_ptr->getOpPtrVector().push_back(
2455 auto calcs_side_traction = [&](
auto &pip) {
2462 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
2465 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
2467 op_loop_domain_side->getOpPtrVector().push_back(
2469 piolaStress, contact_common_data_ptr->contactTractionPtr()));
2470 pip.push_back(op_loop_domain_side);
2474 CHKERR calcs_side_traction(post_proc_ptr->getOpPtrVector());
2476 post_proc_ptr->getOpPtrVector().push_back(
new OpTreeSearch(
2479 &post_proc_ptr->getPostProcMesh(), &post_proc_ptr->getMapGaussPts()));
2488 post_proc_negative_sense_ptr, 0,
2492 CHKERR post_proc_end.writeFile(file.c_str());
2500 auto post_proc_norm_fe =
2501 boost::make_shared<VolumeElementForcesAndSourcesCore>(
mField);
2503 auto post_proc_norm_rule_hook = [](
int,
int,
int p) ->
int {
2506 post_proc_norm_fe->getRuleHook = post_proc_norm_rule_hook;
2508 post_proc_norm_fe->getUserPolynomialBase() =
2515 enum NORMS { U_NORM_L2 = 0, U_NORM_H1, PIOLA_NORM, U_ERROR_L2, LAST_NORM };
2518 CHKERR VecZeroEntries(norms_vec);
2520 auto u_l2_ptr = boost::make_shared<MatrixDouble>();
2521 auto u_h1_ptr = boost::make_shared<MatrixDouble>();
2522 post_proc_norm_fe->getOpPtrVector().push_back(
2524 post_proc_norm_fe->getOpPtrVector().push_back(
2526 post_proc_norm_fe->getOpPtrVector().push_back(
2528 post_proc_norm_fe->getOpPtrVector().push_back(
2530 post_proc_norm_fe->getOpPtrVector().push_back(
2534 auto piola_ptr = boost::make_shared<MatrixDouble>();
2535 post_proc_norm_fe->getOpPtrVector().push_back(
2537 post_proc_norm_fe->getOpPtrVector().push_back(
2540 TetPolynomialBase::switchCacheBaseOn<HDIV>({post_proc_norm_fe.get()});
2542 *post_proc_norm_fe);
2543 TetPolynomialBase::switchCacheBaseOff<HDIV>({post_proc_norm_fe.get()});
2545 CHKERR VecAssemblyBegin(norms_vec);
2546 CHKERR VecAssemblyEnd(norms_vec);
2547 const double *norms;
2548 CHKERR VecGetArrayRead(norms_vec, &norms);
2549 MOFEM_LOG(
"EP", Sev::inform) <<
"norm_u: " << std::sqrt(norms[U_NORM_L2]);
2550 MOFEM_LOG(
"EP", Sev::inform) <<
"norm_u_h1: " << std::sqrt(norms[U_NORM_H1]);
2552 <<
"norm_error_u_l2: " << std::sqrt(norms[U_ERROR_L2]);
2554 <<
"norm_piola: " << std::sqrt(norms[PIOLA_NORM]);
2555 CHKERR VecRestoreArrayRead(norms_vec, &norms);
2570 for (
auto bc : bc_mng->getBcMapByBlockName()) {
2571 if (
auto disp_bc = bc.second->dispBcPtr) {
2573 MOFEM_LOG(
"EP", Sev::noisy) << *disp_bc;
2575 std::vector<double> block_attributes(6, 0.);
2576 if (disp_bc->data.flag1 == 1) {
2577 block_attributes[0] = disp_bc->data.value1;
2578 block_attributes[3] = 1;
2580 if (disp_bc->data.flag2 == 1) {
2581 block_attributes[1] = disp_bc->data.value2;
2582 block_attributes[4] = 1;
2584 if (disp_bc->data.flag3 == 1) {
2585 block_attributes[2] = disp_bc->data.value3;
2586 block_attributes[5] = 1;
2588 auto faces = bc.second->bcEnts.subset_by_dimension(2);
2608 for (
auto bc : bc_mng->getBcMapByBlockName()) {
2609 if (
auto force_bc = bc.second->forceBcPtr) {
2610 std::vector<double> block_attributes(6, 0.);
2611 block_attributes[0] = -force_bc->data.value3 * force_bc->data.value1;
2612 block_attributes[3] = 1;
2613 block_attributes[1] = -force_bc->data.value4 * force_bc->data.value1;
2614 block_attributes[4] = 1;
2615 block_attributes[2] = -force_bc->data.value5 * force_bc->data.value1;
2616 block_attributes[5] = 1;
2617 auto faces = bc.second->bcEnts.subset_by_dimension(2);