38#ifdef ENABLE_PYTHON_BINDING
39#include <boost/python.hpp>
40#include <boost/python/def.hpp>
41#include <boost/python/numpy.hpp>
42namespace bp = boost::python;
43namespace np = boost::python::numpy;
46#include <ContactOps.hpp>
52 double circumcenter[3],
double *xi,
double *
eta);
57#ifdef ENABLE_PYTHON_BINDING
58struct ContactSDFPython :
public ContactOps::SDFPython {
59 using ContactOps::SDFPython::SDFPython;
66 boost::shared_ptr<ContactSDFPython> sdf_python_ptr;
68#ifdef ENABLE_PYTHON_BINDING
70 auto file_exists = [](std::string myfile) {
71 std::ifstream file(myfile.c_str());
78 char sdf_file_name[255] =
"sdf.py";
79 PetscBool has_sdf_file_option = PETSC_FALSE;
81 sdf_file_name, 255, &has_sdf_file_option);
82 std::string sdf_file = sdf_file_name;
83 if (!has_sdf_file_option) {
84 const auto contact_surface_script =
87 if (!contact_surface_script.empty()) {
88 sdf_file = contact_surface_script;
90 <<
"Using Python script 'contact_surface' from JSON config: "
95 if (file_exists(sdf_file)) {
96 MOFEM_LOG(
"EP", Sev::inform) << sdf_file <<
" file found";
97 sdf_python_ptr = boost::make_shared<ContactSDFPython>();
98 CHKERR sdf_python_ptr->sdfInit(sdf_file);
99 ContactOps::sdfPythonWeakPtr = sdf_python_ptr;
100 MOFEM_LOG(
"EP", Sev::inform) <<
"SdfPython initialized";
102 MOFEM_LOG(
"EP", Sev::warning) << sdf_file <<
" file NOT found";
107 return sdf_python_ptr;
114 using Base::refElementsMap;
117 boost::shared_ptr<moab::Core> core_mesh_ptr,
int max_order,
118 std::map<int, Range> &&body_map);
155 using MapFaceData = std::map<EntityHandle, std::vector<FaceData>>;
159 auto it = map_face_data.find(fe_ent);
160 if (it == map_face_data.end()) {
161 return (std::vector<FaceData> *)
nullptr;
163 return &(it->second);
167 std::vector<FaceData> *vec_ptr) {
169 if (it != vec_ptr->end()) {
170 if (it->gaussPtNb == gg) {
171 face_data_ptr = &(*it);
175 return face_data_ptr;
199auto checkSdf(EntityHandle fe_ent, std::map<int, Range> &sdf_map_range) {
200 for (
auto &m_sdf : sdf_map_range) {
201 if (m_sdf.second.find(fe_ent) != m_sdf.second.end())
207template <
typename OP_PTR>
211 auto nb_gauss_pts = op_ptr->getGaussPts().size2();
213 auto ts_time = op_ptr->getTStime();
214 auto ts_time_step = op_ptr->getTStimeStep();
221 op_ptr->getFTensor1CoordsAtGaussPts(),
222 getFTensor1FromMat<3>(contact_disp), nb_gauss_pts);
224 op_ptr->getFTensor1NormalsAtGaussPts(), nb_gauss_pts);
226 ts_time_step, ts_time, nb_gauss_pts, m_spatial_coords, m_normals_at_pts,
229 ts_time_step, ts_time, nb_gauss_pts, m_spatial_coords, m_normals_at_pts,
233 if (v_sdf.size() != nb_gauss_pts)
235 "Wrong number of integration pts");
236 if (m_grad_sdf.size1() != nb_gauss_pts)
238 "Wrong number of integration pts");
239 if (m_grad_sdf.size2() != 3)
245 ts_time_step, ts_time, nb_gauss_pts, m_spatial_coords, m_normals_at_pts,
247 return std::make_tuple(block_id, m_normals_at_pts, v_sdf, m_grad_sdf,
251 return std::make_tuple(block_id, m_normals_at_pts, v_sdf, m_grad_sdf,
267template <
typename T1>
270 std::array<double, 3> &unit_ray, std::array<double, 3> &point,
272 std::array<double, 9> &elem_point_nodes,
273 std::array<double, 9> &elem_traction_nodes,
278 auto t_unit_ray = getFTensor1FromPtr<3>(unit_ray.data());
279 auto t_point = getFTensor1FromPtr<3>(point.data());
281 auto get_normal = [](
auto &ele_coords) {
287 auto t_normal = get_normal(elem_point_nodes);
288 t_normal(
i) /= t_normal.l2();
290 auto sn = t_normal(
i) * t_point(
i);
291 auto nm = t_normal(
i) * t_spatial_coords(
i);
292 auto nr = t_normal(
i) * t_unit_ray(
i);
294 auto gamma = (sn - nm) / nr;
297 t_point_current(
i) = t_spatial_coords(
i) + gamma * t_unit_ray(
i);
299 auto get_local_point_shape_functions = [&](
auto &&t_elem_coords,
301 std::array<T1, 2> loc_coords;
304 &t_elem_coords(0, 0), &t_point(0), 1, loc_coords.data()),
307 N_MBTRI1(loc_coords[0], loc_coords[1]),
308 N_MBTRI2(loc_coords[0], loc_coords[1])};
311 auto eval_position = [&](
auto &&t_field,
auto &t_shape_fun) {
315 t_point_out(
i) = t_shape_fun(
j) * t_field(
j,
i);
319 auto t_shape_fun = get_local_point_shape_functions(
320 getFTensor2FromPtr<3, 3>(elem_point_nodes.data()), t_point_current);
321 auto t_slave_point_updated = eval_position(
322 getFTensor2FromPtr<3, 3>(elem_point_nodes.data()), t_shape_fun);
323 auto t_traction_updated = eval_position(
324 getFTensor2FromPtr<3, 3>(elem_traction_nodes.data()), t_shape_fun);
326 return std::make_tuple(t_slave_point_updated, t_traction_updated, t_normal);
329template <
typename T1>
342template <
typename T1>
358template <
typename T1>
362 auto [t_slave_point_current, t_slave_traction_current, t_slave_normal] =
364 auto [t_master_point_current, t_master_traction_current, t_master_normal] =
370 t_normal(
i) = t_master_normal(
i) - t_slave_normal(
i);
373 auto gap = t_normal(
i) * (t_slave_point_current(
i) - t_spatial_coords(
i));
374 auto tn_master = t_master_traction_current(
i) * t_normal(
i);
375 auto tn_slave = t_slave_traction_current(
i) * t_normal(
i);
376 auto tn = std::max(-tn_master, tn_slave);
378 return std::make_tuple(gap, tn_master, tn_slave,
380 t_master_traction_current, t_slave_traction_current);
387template <
typename T1,
typename T2,
typename T3>
400 t_u(
i) = t_spatial_coords(
i) - t_coords(
i);
407 auto [t_slave_point_current, t_slave_traction_current, t_slave_normal] =
409 auto [t_master_point_current, t_master_traction_current, t_master_normal] =
414 t_normal(
i) = t_master_normal(
i) - t_slave_normal(
i);
419 t_P(
i,
j) = t_normal(
i) * t_normal(
j);
421 t_Q(
i,
j) = kronecker_delta(
i,
j) - t_P(
i,
j);
423 constexpr double beta = 0.5;
430 auto f_min_gap = [
zeta](
auto d,
auto s) {
431 return 0.5 * (d + s - std::sqrt((d - s) * (d - s) +
zeta));
434 auto f_diff_min_gap = [
zeta](
auto d,
auto s) {
435 return 0.5 * (1 - (d - s) / std::sqrt((d - s) * (d - s) +
zeta));
439 auto f_barrier = [alpha1, alpha2, f_min_gap, f_diff_min_gap](
auto g,
443 0.5 * (tn + f_min_gap(d, tn) + f_diff_min_gap(d, tn) * (d - tn));
444 auto b2 = alpha2 * f_min_gap(
g, 0) *
g;
449 t_gap_vec(
i) = beta * t_spatial_coords(
i) +
450 (1 - beta) * t_slave_point_current(
i) - t_spatial_coords(
i);
453 -beta * t_master_traction(
i) + (beta - 1) * t_slave_traction_current(
i);
455 auto t_gap = t_normal(
i) * t_gap_vec(
i);
456 auto t_tn = t_normal(
i) * t_traction_vec(
i);
457 auto barrier = f_barrier(t_gap, t_tn);
461 t_traction_bar(
i) = t_normal(
i) * barrier;
465 t_Q(
i,
j) * t_master_traction(
j) +
467 t_P(
i,
j) * (t_master_traction(
j) - t_traction_bar(
j));
470 auto is_nan_or_inf = [](
double value) ->
bool {
471 return std::isnan(value) || std::isinf(value);
474 double v = std::complex<double>(t_rhs(
i) * t_rhs(
i)).real();
475 if (is_nan_or_inf(
v)) {
477 MOFEM_LOG(
"SELF", Sev::error) <<
"t_rhs " << t_rhs;
493 const std::string row_field_name,
494 boost::shared_ptr<ContactOps::CommonData> common_data_ptr,
495 boost::shared_ptr<ContactTree> contact_tree_ptr,
496 boost::shared_ptr<std::map<int, Range>> sdf_map_range_ptr =
nullptr);
507 const std::string row_field_name,
508 boost::shared_ptr<ContactOps::CommonData> common_data_ptr,
509 boost::shared_ptr<ContactTree> contact_tree_ptr,
510 boost::shared_ptr<std::map<int, Range>> sdf_map_range_ptr)
513 commonDataPtr(common_data_ptr), contactTreePtr(contact_tree_ptr),
514 sdfMapRangePtr(sdf_map_range_ptr) {
523 "get alpha contact failed");
525 PETSC_NULLPTR,
"",
"-alpha_contact_quadratic",
527 "get alpha contact failed");
531 "get alpha contact failed");
551 const size_t nb_gauss_pts = getGaussPts().size2();
556 "Wrong number of integration pts %ld != %ld",
564 auto t_w = getFTensor0IntegrationWeight();
565 auto t_coords = getFTensor1CoordsAtGaussPts();
566 auto t_disp = getFTensor1FromMat<3>(
commonDataPtr->contactDisp);
567 auto t_traction = getFTensor1FromMat<3>(
commonDataPtr->contactTraction);
572 auto [block_id, m_normals_at_pts, v_sdf, m_grad_sdf, m_hess_sdf] =
577 auto t_grad_sdf_v = getFTensor1FromMat<3>(m_grad_sdf);
578 auto t_normalize_normal = getFTensor1FromMat<3>(m_normals_at_pts);
585 ++t_normalize_normal;
590 auto face_data_vec_ptr =
592 auto face_gauss_pts_it = face_data_vec_ptr->begin();
594 auto nb_base_functions = data.
getN().size2();
596 for (
auto gg = 0; gg != nb_gauss_pts; ++gg) {
599 auto face_data_ptr =
contactTreePtr->getFaceDataPtr(face_gauss_pts_it, gg,
602 auto check_face_contact = [&]() {
612#ifdef ENABLE_PYTHON_BINDING
614 if (ContactOps::sdfPythonWeakPtr.lock()) {
615 auto tn = t_traction(
i) * t_grad_sdf_v(
i);
619 constexpr double c = 0;
622 if (!
c && check_face_contact()) {
624 t_spatial_coords(
i) = t_coords(
i) + t_disp(
i);
625 auto t_rhs_tmp =
multiPointRhs(face_data_ptr, t_coords, t_spatial_coords,
627 t_rhs(
i) = t_rhs_tmp(
i);
631#ifdef ENABLE_PYTHON_BINDING
634 if (ContactOps::sdfPythonWeakPtr.lock()) {
636 t_cP(
i,
j) = (
c * t_grad_sdf_v(
i)) * t_grad_sdf_v(
j);
637 t_cQ(
i,
j) = kronecker_delta(
i,
j) - t_cP(
i,
j);
638 t_rhs(
i) = t_cQ(
i,
j) * t_traction(
j) +
639 (
c * inv_cn * t_sdf_v) * t_grad_sdf_v(
i);
641 t_rhs(
i) = t_traction(
i);
644 t_rhs(
i) = t_traction(
i);
648 auto t_nf = getFTensor1FromPtr<3>(&nf[0]);
649 const double alpha = t_w * getMeasure();
652 for (; bb != nbRows / 3; ++bb) {
653 const double beta = alpha * t_base;
654 t_nf(
i) -= beta * t_rhs(
i);
658 for (; bb < nb_base_functions; ++bb)
669template <AssemblyType A>
677 boost::shared_ptr<std::vector<BrokenBaseSideData>> broken_base_side_data,
678 boost::shared_ptr<ContactOps::CommonData> common_data_ptr,
679 boost::shared_ptr<ContactTree> contact_tree_ptr);
688template <AssemblyType A>
691 boost::shared_ptr<std::vector<BrokenBaseSideData>>
692 broken_base_side_data,
693 boost::shared_ptr<ContactOps::CommonData> common_data_ptr,
694 boost::shared_ptr<ContactTree> contact_tree_ptr)
695 :
OP(broken_base_side_data), commonDataPtr(common_data_ptr),
696 contactTreePtr(contact_tree_ptr) {}
698template <AssemblyType A>
708 const size_t nb_gauss_pts = OP::getGaussPts().size2();
711 if (commonDataPtr->contactDisp.size1() != nb_gauss_pts) {
713 "Wrong number of integration pts %ld != %ld",
714 commonDataPtr->contactDisp.size1(), nb_gauss_pts);
721 auto t_w = OP::getFTensor0IntegrationWeight();
722 auto t_material_normal = OP::getFTensor1NormalsAtGaussPts();
723 auto t_coords = OP::getFTensor1CoordsAtGaussPts();
725 auto t_disp = getFTensor1FromMat<3>(commonDataPtr->contactDisp);
726 auto t_traction = getFTensor1FromMat<3>(commonDataPtr->contactTraction);
736 auto face_data_vec_ptr =
737 contactTreePtr->findFaceDataVecPtr(OP::getFEEntityHandle());
738 auto face_gauss_pts_it = face_data_vec_ptr->begin();
740 auto nb_base_functions = data.
getN().size2() / 3;
742 for (
auto gg = 0; gg != nb_gauss_pts; ++gg) {
744 auto t_nf = getFTensor1FromPtr<3>(&nf[0]);
745 const double alpha = t_w / 2.;
748 for (; bb != OP::nbRows / 3; ++bb) {
749 const double beta = alpha * t_base(
i) * t_material_normal(
i);
750 t_nf(
i) += beta * t_disp(
i);
754 for (; bb < nb_base_functions; ++bb)
766 const std::string row_field_name,
const std::string col_field_name,
767 boost::shared_ptr<ContactOps::CommonData> common_data_ptr,
768 boost::shared_ptr<ContactTree> contact_tree_ptr,
769 boost::shared_ptr<std::map<int, Range>> sdf_map_range_ptr =
nullptr);
781 const std::string row_field_name,
const std::string col_field_name,
782 boost::shared_ptr<ContactOps::CommonData> common_data_ptr,
783 boost::shared_ptr<ContactTree> contact_tree_ptr,
784 boost::shared_ptr<std::map<int, Range>> sdf_map_range_ptr)
787 commonDataPtr(common_data_ptr), contactTreePtr(contact_tree_ptr),
788 sdfMapRangePtr(sdf_map_range_ptr) {
807 auto &locMat = AssemblyBoundaryEleOp::locMat;
808 locMat.resize(nb_rows, nb_cols,
false);
811 if (nb_cols && nb_rows) {
813 auto nb_gauss_pts = getGaussPts().size2();
814 auto t_w = getFTensor0IntegrationWeight();
815 auto t_coords = getFTensor1CoordsAtGaussPts();
816 auto t_disp = getFTensor1FromMat<3>(
commonDataPtr->contactDisp);
817 auto t_traction = getFTensor1FromMat<3>(
commonDataPtr->contactTraction);
820 auto [block_id, m_normals_at_pts, v_sdf, m_grad_sdf, m_hess_sdf] =
825 auto t_grad_sdf_v = getFTensor1FromMat<3>(m_grad_sdf);
826 auto t_hess_sdf_v = getFTensor2SymmetricFromMat<3>(m_hess_sdf);
827 auto t_normalized_normal = getFTensor1FromMat<3>(m_normals_at_pts);
837 ++t_normalized_normal;
840 auto face_data_vec_ptr =
842 auto face_gauss_pts_it = face_data_vec_ptr->begin();
845 auto nb_face_functions = row_data.
getN().size2() / 3;
848 for (
size_t gg = 0; gg != nb_gauss_pts; ++gg) {
850 auto face_data_ptr =
contactTreePtr->getFaceDataPtr(face_gauss_pts_it, gg,
853 auto check_face_contact = [&]() {
865#ifdef ENABLE_PYTHON_BINDING
867 if (ContactOps::sdfPythonWeakPtr.lock()) {
868 auto tn = t_traction(
i) * t_grad_sdf_v(
i);
872 constexpr double c = 0;
875 if (!
c && check_face_contact()) {
877 t_spatial_coords(
i) = t_coords(
i) + t_disp(
i);
878 constexpr double eps = std::numeric_limits<float>::epsilon();
879 for (
auto ii = 0; ii < 3; ++ii) {
881 t_spatial_coords(0), t_spatial_coords(1), t_spatial_coords(2)};
882 t_spatial_coords_cx(ii) +=
eps * 1
i;
886 for (
int jj = 0; jj != 3; ++jj) {
887 auto v = t_rhs_tmp(jj).imag();
888 t_res_dU(jj, ii) =
v /
eps;
894#ifdef ENABLE_PYTHON_BINDING
896 if (ContactOps::sdfPythonWeakPtr.lock()) {
900 (-
c) * (t_hess_sdf_v(
i,
j) * t_grad_sdf_v(
k) * t_traction(
k) +
901 t_grad_sdf_v(
i) * t_hess_sdf_v(
k,
j) * t_traction(
k))
903 + (
c * inv_cn) * (t_sdf_v * t_hess_sdf_v(
i,
j) +
905 t_grad_sdf_v(
j) * t_grad_sdf_v(
i));
914 auto alpha = t_w * getMeasure();
917 for (; rr != nb_rows / 3; ++rr) {
919 auto t_mat = getFTensor2FromArray<3, 3, 3>(locMat, 3 * rr);
922 for (
size_t cc = 0; cc != nb_cols / 3; ++cc) {
923 auto beta = alpha * t_row_base * t_col_base;
924 t_mat(
i,
j) -= beta * t_res_dU(
i,
j);
931 for (; rr < nb_face_functions; ++rr)
943template <AssemblyType A>
951 std::string row_field_name,
952 boost::shared_ptr<std::vector<BrokenBaseSideData>> broken_base_side_data,
953 boost::shared_ptr<ContactOps::CommonData> common_data_ptr,
954 boost::shared_ptr<ContactTree> contact_tree_ptr,
955 boost::shared_ptr<std::map<int, Range>> sdf_map_range_ptr =
nullptr);
966template <AssemblyType A>
969 std::string row_field_name,
970 boost::shared_ptr<std::vector<BrokenBaseSideData>>
971 broken_base_side_data,
972 boost::shared_ptr<ContactOps::CommonData> common_data_ptr,
973 boost::shared_ptr<ContactTree> contact_tree_ptr,
974 boost::shared_ptr<std::map<int, Range>> sdf_map_range_ptr)
975 :
OP(row_field_name, broken_base_side_data, false, false),
976 commonDataPtr(common_data_ptr), contactTreePtr(contact_tree_ptr),
977 sdfMapRangePtr(sdf_map_range_ptr) {
981template <AssemblyType A>
997 auto &locMat = AssemblyBoundaryEleOp::locMat;
998 locMat.resize(nb_rows, nb_cols,
false);
1001 if (nb_cols && nb_rows) {
1003 const size_t nb_gauss_pts = OP::getGaussPts().size2();
1005 auto t_w = OP::getFTensor0IntegrationWeight();
1006 auto t_disp = getFTensor1FromMat<3>(commonDataPtr->contactDisp);
1007 auto t_traction = getFTensor1FromMat<3>(commonDataPtr->contactTraction);
1008 auto t_coords = OP::getFTensor1CoordsAtGaussPts();
1009 auto t_material_normal = OP::getFTensor1NormalsAtGaussPts();
1012 auto [block_id, m_normals_at_pts, v_sdf, m_grad_sdf, m_hess_sdf] =
1013 getSdf(
this, commonDataPtr->contactDisp,
1014 checkSdf(OP::getFEEntityHandle(), *sdfMapRangePtr),
false);
1017 auto t_grad_sdf_v = getFTensor1FromMat<3>(m_grad_sdf);
1024 ++t_material_normal;
1029 auto face_data_vec_ptr =
1030 contactTreePtr->findFaceDataVecPtr(OP::getFEEntityHandle());
1031 auto face_gauss_pts_it = face_data_vec_ptr->begin();
1034 auto nb_face_functions = row_data.
getN().size2();
1038 for (
size_t gg = 0; gg != nb_gauss_pts; ++gg) {
1040 auto face_data_ptr = contactTreePtr->getFaceDataPtr(face_gauss_pts_it, gg,
1043 auto check_face_contact = [&]() {
1044 if (
checkSdf(OP::getFEEntityHandle(), *sdfMapRangePtr) != -1)
1047 if (face_data_ptr) {
1055#ifdef ENABLE_PYTHON_BINDING
1057 if (ContactOps::sdfPythonWeakPtr.lock()) {
1058 auto tn = t_traction(
i) * t_grad_sdf_v(
i);
1062 constexpr double c = 0;
1065 if (!
c && check_face_contact()) {
1067 t_spatial_coords(
i) = t_coords(
i) + t_disp(
i);
1068 constexpr double eps = std::numeric_limits<float>::epsilon();
1069 for (
auto ii = 0; ii != 3; ++ii) {
1071 t_traction(0), t_traction(1), t_traction(2)};
1072 t_traction_cx(ii) +=
eps * 1
i;
1076 for (
int jj = 0; jj != 3; ++jj) {
1077 auto v = t_rhs_tmp(jj).imag();
1078 t_res_dP(jj, ii) =
v /
eps;
1083#ifdef ENABLE_PYTHON_BINDING
1084 if (ContactOps::sdfPythonWeakPtr.lock()) {
1086 t_cP(
i,
j) = (
c * t_grad_sdf_v(
i)) * t_grad_sdf_v(
j);
1087 t_cQ(
i,
j) = kronecker_delta(
i,
j) - t_cP(
i,
j);
1088 t_res_dP(
i,
j) = t_cQ(
i,
j);
1097 const double alpha = t_w / 2.;
1099 for (; rr != nb_rows / 3; ++rr) {
1101 auto t_mat = getFTensor2FromArray<3, 3, 3>(locMat, 3 * rr);
1104 for (
size_t cc = 0; cc != nb_cols / 3; ++cc) {
1105 auto col_base = t_col_base(
i) * t_material_normal(
i);
1106 const double beta = alpha * t_row_base * col_base;
1107 t_mat(
i,
j) -= beta * t_res_dP(
i,
j);
1114 for (; rr < nb_face_functions; ++rr)
1124template <AssemblyType A, IntegrationType I>
1127template <AssemblyType A>
1135 boost::shared_ptr<std::vector<BrokenBaseSideData>> broken_base_side_data,
1136 std::string col_field_name,
1137 boost::shared_ptr<ContactOps::CommonData> common_data_ptr,
1138 boost::shared_ptr<ContactTree> contact_tree_ptr);
1148template <AssemblyType A>
1151 boost::shared_ptr<std::vector<BrokenBaseSideData>>
1152 broken_base_side_data,
1153 std::string col_field_name,
1154 boost::shared_ptr<ContactOps::CommonData> common_data_ptr,
1155 boost::shared_ptr<ContactTree> contact_tree_ptr)
1156 :
OP(col_field_name, broken_base_side_data, true, true),
1157 commonDataPtr(common_data_ptr), contactTreePtr(contact_tree_ptr) {
1161template <AssemblyType A>
1180 auto &locMat = AssemblyBoundaryEleOp::locMat;
1181 locMat.resize(nb_rows, nb_cols,
false);
1184 if (nb_cols && nb_rows) {
1186 const size_t nb_gauss_pts = OP::getGaussPts().size2();
1188 auto t_w = OP::getFTensor0IntegrationWeight();
1189 auto t_disp = getFTensor1FromMat<3>(commonDataPtr->contactDisp);
1190 auto t_traction = getFTensor1FromMat<3>(commonDataPtr->contactTraction);
1191 auto t_coords = OP::getFTensor1CoordsAtGaussPts();
1192 auto t_material_normal = OP::getFTensor1NormalsAtGaussPts();
1199 ++t_material_normal;
1204 auto face_data_vec_ptr =
1205 contactTreePtr->findFaceDataVecPtr(OP::getFEEntityHandle());
1206 auto face_gauss_pts_it = face_data_vec_ptr->begin();
1209 auto nb_face_functions = row_data.
getN().size2() / 3;
1210 for (
size_t gg = 0; gg != nb_gauss_pts; ++gg) {
1212 const auto alpha = t_w / 2.;
1215 for (; rr != nb_rows / 3; ++rr) {
1217 auto row_base = alpha * (t_row_base(
i) * t_material_normal(
i));
1219 auto t_mat = getFTensor2FromArray<3, 3, 3>(locMat, 3 * rr);
1222 for (
size_t cc = 0; cc != nb_cols / 3; ++cc) {
1223 const auto beta = row_base * t_col_base;
1231 for (; rr < nb_face_functions; ++rr)
1238 locMat = trans(locMat);
1244 boost::shared_ptr<moab::Core> core_mesh_ptr,
1245 int max_order, std::map<int, Range> &&body_map)
1246 :
Base(m_field, core_mesh_ptr,
"contact"), maxOrder(max_order),
1249 auto ref_ele_ptr = boost::make_shared<PostProcGenerateRefMesh<MBTRI>>();
1250 ref_ele_ptr->hoNodes =
1255 "Error when generating reference element");
1257 MOFEM_LOG(
"EP", Sev::inform) <<
"Contact hoNodes " << ref_ele_ptr->hoNodes
1261 <<
"Contact maxOrder " << ref_ele_ptr->defMaxLevel;
1265 int def_ele_id = -1;
1267 MB_TAG_CREAT | MB_TAG_DENSE,
1270 thBodyId, MB_TAG_CREAT | MB_TAG_DENSE,
1290 std::array<double, 3> def_small_x{0., 0., 0.};
1292 MB_TAG_CREAT | MB_TAG_DENSE,
1293 def_small_x.data());
1295 MB_TAG_CREAT | MB_TAG_DENSE,
1296 def_small_x.data());
1298 std::array<double, 3> def_tractions{0., 0., 0.};
1300 "TRACTION", 3, MB_TYPE_DOUBLE,
thTraction, MB_TAG_CREAT | MB_TAG_DENSE,
1301 &*def_tractions.begin());
1306 CHKERR Base::preProcess();
1313 CHKERR Base::postProcess();
1316 PetscBarrier(
nullptr);
1319 if (pcomm_post_proc_mesh ==
nullptr)
1322 auto brodacts = [&](
auto &brodacts_ents) {
1326 pcomm_post_proc_mesh->broadcast_entities(
1333 Range brodacts_ents;
1335 CHKERR brodacts(brodacts_ents);
1354 treeSurfPtr = boost::shared_ptr<OrientedBoxTreeTool>(
1365 OpMoveNode(boost::shared_ptr<ContactTree> contact_tree_ptr,
1366 boost::shared_ptr<ContactOps::CommonData> common_data_ptr,
1367 boost::shared_ptr<MatrixDouble> u_h1_ptr);
1378 boost::shared_ptr<ContactTree> contact_tree_ptr,
1379 boost::shared_ptr<ContactOps::CommonData> common_data_ptr,
1380 boost::shared_ptr<MatrixDouble> u_h1_ptr)
1381 :
UOP(
NOSPACE,
UOP::OPSPACE), contactTreePtr(contact_tree_ptr),
1382 uH1Ptr(u_h1_ptr), commonDataPtr(common_data_ptr) {}
1390 auto get_body_id = [&](
auto fe_ent) {
1391 for (
auto &
m : contact_tree_ptr->bodyMap) {
1392 if (
m.second.find(fe_ent) !=
m.second.end()) {
1399 auto &moab_post_proc_mesh = contact_tree_ptr->getPostProcMesh();
1400 auto &post_proc_ents = contact_tree_ptr->getPostProcElements();
1402 auto fe_ent = getNumeredEntFiniteElementPtr()->getEnt();
1404 auto body_id = get_body_id(fe_ent);
1405 auto &map_gauss_pts = contact_tree_ptr->getMapGaussPts();
1407 CHKERR moab_post_proc_mesh.tag_clear_data(contact_tree_ptr->thEleId,
1408 post_proc_ents, &fe_id);
1409 CHKERR moab_post_proc_mesh.tag_clear_data(contact_tree_ptr->thBodyId,
1410 post_proc_ents, &body_id);
1412 auto nb_gauss_pts = getGaussPts().size2();
1413 auto t_u_h1 = getFTensor1FromMat<3>(*
uH1Ptr);
1414 auto t_u_l2 = getFTensor1FromMat<3>(
commonDataPtr->contactDisp);
1415 auto t_coords = getFTensor1CoordsAtGaussPts();
1418 auto t_x_h1 = getFTensor1FromPtr<3>(&x_h1(0, 0));
1420 auto t_x_l2 = getFTensor1FromPtr<3>(&x_l2(0, 0));
1427 for (
auto gg = 0; gg != nb_gauss_pts; ++gg) {
1428 t_x_h1(
i) = t_coords(
i) + t_u_h1(
i);
1429 t_x_l2(
i) = t_coords(
i) + t_u_l2(
i);
1438 CHKERR moab_post_proc_mesh.set_coords(
1439 &*map_gauss_pts.begin(), map_gauss_pts.size(), &*x_h1.data().begin());
1440 CHKERR moab_post_proc_mesh.tag_set_data(
1441 contact_tree_ptr->thSmallX, &*map_gauss_pts.begin(),
1442 map_gauss_pts.size(), &*x_h1.data().begin());
1443 CHKERR moab_post_proc_mesh.tag_set_data(
1444 contact_tree_ptr->thLargeX, &*map_gauss_pts.begin(),
1445 map_gauss_pts.size(), &*coords.data().begin());
1446 CHKERR moab_post_proc_mesh.tag_set_data(
1447 contact_tree_ptr->thTraction, &*map_gauss_pts.begin(),
1448 map_gauss_pts.size(), &*tractions.data().begin());
1452 "ContactTree pointer expired in OpMoveNode");
1462 OpTreeSearch(boost::shared_ptr<ContactTree> contact_tree_ptr,
1463 boost::shared_ptr<MatrixDouble> u_h1_ptr,
1464 boost::shared_ptr<MatrixDouble> traction_ptr,
Range r,
1466 moab::Interface *post_proc_mesh_ptr,
1467 std::vector<EntityHandle> *map_gauss_pts_ptr
1484 boost::shared_ptr<MatrixDouble> u_h1_ptr,
1485 boost::shared_ptr<MatrixDouble> traction_ptr,
1488 moab::Interface *post_proc_mesh_ptr,
1489 std::vector<EntityHandle> *map_gauss_pts_ptr
1492 :
UOP(
NOSPACE,
UOP::OPSPACE), contactTreePtr(contact_tree_ptr),
1493 uH1Ptr(u_h1_ptr), tractionPtr(traction_ptr),
1494 postProcMeshPtr(post_proc_mesh_ptr), mapGaussPtsPtr(map_gauss_pts_ptr),
1501 auto &m_field = getPtrFE()->mField;
1502 auto fe_ent = getNumeredEntFiniteElementPtr()->getEnt();
1511 const auto nb_gauss_pts = getGaussPts().size2();
1513 auto t_disp_h1 = getFTensor1FromMat<3>(*
uH1Ptr);
1514 auto t_coords = getFTensor1CoordsAtGaussPts();
1515 auto t_traction = getFTensor1FromMat<3>(*
tractionPtr);
1523 auto get_ele_centre = [
i](
auto t_ele_coords) {
1525 t_ele_center(
i) = 0;
1526 for (
int nn = 0; nn != 3; nn++) {
1527 t_ele_center(
i) += t_ele_coords(
i);
1530 t_ele_center(
i) /= 3;
1531 return t_ele_center;
1534 auto get_ele_radius = [
i](
auto t_ele_center,
auto t_ele_coords) {
1536 t_n0(
i) = t_ele_center(
i) - t_ele_coords(
i);
1540 auto get_face_conn = [
this](
auto face) {
1541 const EntityHandle *conn;
1544 face, conn, num_nodes,
true),
1546 if (num_nodes != 3) {
1552 auto get_face_coords = [
this](
auto conn) {
1553 std::array<double, 9> coords;
1558 auto get_closet_face = [
this](
auto *point_ptr,
auto r) {
1560 std::vector<EntityHandle> faces_out;
1564 "get closest faces");
1568 auto get_faces_out = [
this](
auto *point_ptr,
auto *unit_ray_ptr,
auto radius,
1570 std::vector<double> distances_out;
1571 std::vector<EntityHandle> faces_out;
1576 point_ptr, unit_ray_ptr, &radius),
1578 "get closest faces");
1579 return std::make_pair(faces_out, distances_out);
1582 auto get_normal = [](
auto &ele_coords) {
1588 auto make_map = [&](
auto &face_out,
auto &face_dist,
auto &t_ray_point,
1589 auto &t_unit_ray,
auto &t_master_coord) {
1592 std::map<double, EntityHandle>
m;
1593 for (
auto ii = 0; ii != face_out.size(); ++ii) {
1594 auto face_conn = get_face_conn(face_out[ii]);
1597 t_face_normal.normalize();
1599 t_x(
i) = t_ray_point(
i) + t_unit_ray(
i) * face_dist[ii];
1602 t_x(
i) * t_face_normal(
j) - t_master_coord(
i) * t_unit_ray(
j);
1603 if (t_unit_ray(
i) * t_face_normal(
i) > std::cos(M_PI / 3)) {
1604 auto dot = std::sqrt(t_chi(
i,
j) * t_chi(
i,
j));
1605 m[dot] = face_out[ii];
1611 auto get_tag_data = [
this](
auto tag,
auto face,
auto &vec) {
1615 vec.resize(tag_length);
1621 auto create_tag = [
this](
const std::string tag_name,
const int size) {
1622 double def_VAL[] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
1626 tag_name.c_str(), size, MB_TYPE_DOUBLE,
th,
1627 MB_TAG_CREAT | MB_TAG_SPARSE, def_VAL);
1634 auto set_float_precision = [](
const double x) {
1635 if (std::abs(x) < std::numeric_limits<float>::epsilon())
1642 auto save_scal_tag = [&](
auto &
th,
auto v,
const int gg) {
1645 v = set_float_precision(
v);
1652 auto get_fe_adjacencies = [
this](
auto fe_ent) {
1655 &fe_ent, 1, 2,
false, adj_faces, moab::Interface::UNION),
1657 std::set<int> adj_ids;
1658 for (
auto f : adj_faces) {
1664 auto get_face_id = [
this](
auto face) {
1673 auto get_body_id = [
this](
auto face) {
1682 auto get_face_part = [
this](
auto face) {
1683 const moab::Core *core_mesh_ptr =
1684 dynamic_cast<const moab::Core *
>(&
contactTreePtr->getPostProcMesh());
1685 auto pcomm_post_proc_mesh =
1689 pcomm_post_proc_mesh->part_tag(), &face, 1, &part) == MB_SUCCESS) {
1695 auto check_face = [&](
auto face,
auto fe_id,
auto part) {
1696 auto face_id = get_face_id(face);
1697 auto face_part = get_face_part(face);
1698 if (face_id == fe_id && face_part == part)
1706 auto save_vec_tag = [&](
auto &
th,
auto &t_d,
const int gg) {
1710 for (
auto &
a :
v.data())
1711 a = set_float_precision(
a);
1713 &*
v.data().begin());
1718 Tag th_mark = create_tag(
"contact_mark", 1);
1719 Tag th_mark_slave = create_tag(
"contact_mark_slave", 1);
1720 Tag th_body_id = create_tag(
"contact_body_id", 1);
1721 Tag th_gap = create_tag(
"contact_gap", 1);
1722 Tag th_tn_master = create_tag(
"contact_tn_master", 1);
1723 Tag th_tn_slave = create_tag(
"contact_tn_slave", 1);
1724 Tag th_contact_traction = create_tag(
"contact_traction", 3);
1725 Tag th_contact_traction_master = create_tag(
"contact_traction_master", 3);
1726 Tag th_contact_traction_slave = create_tag(
"contact_traction_slave", 3);
1727 Tag th_c = create_tag(
"contact_c", 1);
1728 Tag th_normal = create_tag(
"contact_normal", 3);
1729 Tag th_dist = create_tag(
"contact_dip", 3);
1731 auto t_ele_centre = get_ele_centre(getFTensor1Coords());
1732 auto ele_radius = get_ele_radius(t_ele_centre, getFTensor1Coords());
1738 auto adj_fe_ids = get_fe_adjacencies(fe_ent);
1740 for (
auto gg = 0; gg != nb_gauss_pts; ++gg) {
1743 t_spatial_coords(
i) = t_coords(
i) + t_disp_h1(
i);
1746 CHKERR save_vec_tag(th_contact_traction, t_traction, gg);
1749 auto faces_close = get_closet_face(&t_spatial_coords(0), ele_radius);
1750 for (
auto face_close : faces_close) {
1751 if (check_face(face_close, fe_id, m_field.get_comm_rank())) {
1753 auto body_id = get_body_id(face_close);
1755 auto master_face_conn = get_face_conn(face_close);
1756 std::array<double, 9> master_coords;
1759 master_coords.data());
1760 std::array<double, 9> master_traction;
1763 master_traction.data());
1764 auto t_normal_face_close = get_normal(master_coords);
1765 t_normal_face_close.normalize();
1769 CHKERR save_scal_tag(th_mark,
m, gg);
1770 CHKERR save_scal_tag(th_body_id,
static_cast<double>(body_id), gg);
1771 CHKERR save_vec_tag(th_normal, t_normal_face_close, gg);
1772 CHKERR save_vec_tag(th_contact_traction, t_traction, gg);
1776 t_unit_ray(
i) = -t_normal_face_close(
i);
1779 t_spatial_coords(
i) -
1782 constexpr double eps = 1e-3;
1783 auto [faces_out, faces_dist] =
1784 get_faces_out(&t_ray_point(0), &t_unit_ray(0),
1788 auto m = make_map(faces_out, faces_dist, t_ray_point, t_unit_ray,
1790 for (
auto m_it =
m.begin(); m_it !=
m.end(); ++m_it) {
1791 auto face = m_it->second;
1792 if (face != face_close) {
1796 (adj_fe_ids.find(get_face_id(face)) == adj_fe_ids.end() ||
1797 get_face_part(face) != m_field.get_comm_rank())
1802 shadow_vec.back().gaussPtNb = gg;
1804 auto slave_face_conn = get_face_conn(face);
1805 std::array<double, 9> slave_coords;
1808 slave_coords.data());
1809 auto t_normal_face = get_normal(slave_coords);
1810 std::array<double, 9> slave_tractions;
1813 slave_tractions.data());
1815 auto t_master_point =
1816 getFTensor1FromPtr<3>(shadow_vec.back().masterPoint.data());
1817 auto t_slave_point =
1818 getFTensor1FromPtr<3>(shadow_vec.back().slavePoint.data());
1819 auto t_ray_point_data =
1820 getFTensor1FromPtr<3>(shadow_vec.back().rayPoint.data());
1821 auto t_unit_ray_data =
1822 getFTensor1FromPtr<3>(shadow_vec.back().unitRay.data());
1824 t_slave_point(
i) = t_ray_point(
i) + m_it->first * t_unit_ray(
i);
1826 auto eval_position = [&](
auto &&t_elem_coords,
auto &&t_point) {
1827 std::array<double, 2> loc_coords;
1830 &t_elem_coords(0, 0), &t_point(0), 1,
1832 "get local coords");
1841 t_point_out(
i) = t_shape_fun(
j) * t_elem_coords(
j,
i);
1845 auto t_master_point_updated = eval_position(
1846 getFTensor2FromPtr<3, 3>(master_coords.data()),
1847 getFTensor1FromPtr<3>(shadow_vec.back().masterPoint.data()));
1848 t_master_point(
i) = t_master_point_updated(
i);
1850 auto t_slave_point_updated = eval_position(
1851 getFTensor2FromPtr<3, 3>(slave_coords.data()),
1852 getFTensor1FromPtr<3>(shadow_vec.back().slavePoint.data()));
1853 t_slave_point(
i) = t_slave_point_updated(
i);
1855 t_ray_point_data(
i) = t_ray_point(
i);
1856 t_unit_ray_data(
i) = t_unit_ray(
i);
1858 std::copy(master_coords.begin(), master_coords.end(),
1859 shadow_vec.back().masterPointNodes.begin());
1860 std::copy(master_traction.begin(), master_traction.end(),
1861 shadow_vec.back().masterTractionNodes.begin());
1862 std::copy(slave_coords.begin(), slave_coords.end(),
1863 shadow_vec.back().slavePointNodes.begin());
1864 std::copy(slave_tractions.begin(), slave_tractions.end(),
1865 shadow_vec.back().slaveTractionNodes.begin());
1867 shadow_vec.back().eleRadius = ele_radius;
1877 auto [gap, tn_master, tn_slave,
c, t_master_traction,
1879 multiGetGap(&(shadow_vec.back()), t_spatial_coords);
1881 t_gap_vec(
i) = t_slave_point(
i) - t_spatial_coords(
i);
1882 CHKERR save_scal_tag(th_gap, gap, gg);
1883 CHKERR save_scal_tag(th_tn_master, tn_master, gg);
1884 CHKERR save_scal_tag(th_tn_slave, tn_slave, gg);
1885 CHKERR save_scal_tag(th_c,
c, gg);
1887 CHKERR save_scal_tag(th_mark_slave,
m, gg);
1888 CHKERR save_vec_tag(th_dist, t_gap_vec, gg);
1889 CHKERR save_vec_tag(th_contact_traction_master,
1890 t_master_traction, gg);
1891 CHKERR save_vec_tag(th_contact_traction_slave, t_slave_traction,
1909 const std::string block_name,
int dim) {
1915 std::regex((boost::format(
"%s(.*)") % block_name).str())
1919 for (
auto bc : bcs) {
1923 "get meshset ents");
1930boost::shared_ptr<ForcesAndSourcesCore>
1933 auto &m_field = ep.
mField;
1935 boost::shared_ptr<ContactTree> fe_contact_tree;
1942 std::map<int, Range> map;
1948 (boost::format(
"%s(.*)") % name).str()
1955 m_field.get_moab(), dim, ents,
true),
1957 map[m_ptr->getMeshsetId()] = ents;
1958 MOFEM_LOG(
"EPSYNC", sev) <<
"Meshset: " << m_ptr->getMeshsetId() <<
" "
1959 << ents.size() <<
" entities";
1966 auto get_map_skin = [&](
auto &&map) {
1967 ParallelComm *pcomm =
1968 ParallelComm::get_pcomm(&m_field.get_moab(),
MYPCOMM_INDEX);
1970 Skinner skin(&m_field.get_moab());
1971 for (
auto &
m : map) {
1973 CHKERR skin.find_skin(0,
m.second,
false, skin_faces);
1975 skin_faces, PSTATUS_SHARED | PSTATUS_MULTISHARED,
1976 PSTATUS_NOT, -1,
nullptr),
1978 m.second.swap(skin_faces);
1988 auto contact_common_data_ptr = boost::make_shared<ContactOps::CommonData>();
1990 auto calcs_side_traction = [&](
auto &pip) {
1994 using SideEleOp = EleOnSide::UserDataOperator;
1997 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
1998 boost::make_shared<CGGUserPolynomialBase>(
nullptr,
true);
1999 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
2000 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
2002 op_loop_domain_side->getOpPtrVector().push_back(
2004 ep.
piolaStress, contact_common_data_ptr->contactTractionPtr(),
2005 boost::make_shared<double>(1.0)));
2006 pip.push_back(op_loop_domain_side);
2010 auto add_contact_three = [&]() {
2012 auto tree_moab_ptr = boost::make_shared<moab::Core>();
2013 fe_contact_tree = boost::make_shared<ContactTree>(
2016 fe_contact_tree->getOpPtrVector().push_back(
2018 ep.
contactDisp, contact_common_data_ptr->contactDispPtr()));
2019 CHKERR calcs_side_traction(fe_contact_tree->getOpPtrVector());
2020 auto u_h1_ptr = boost::make_shared<MatrixDouble>();
2021 fe_contact_tree->getOpPtrVector().push_back(
2023 fe_contact_tree->getOpPtrVector().push_back(
2024 new OpMoveNode(fe_contact_tree, contact_common_data_ptr, u_h1_ptr));
2028 CHKERR add_contact_three();
2035 struct exclude_sdf {
2036 exclude_sdf(
Range &&r) : map(r) {}
2037 bool operator()(
FEMethod *fe_method_ptr) {
2039 if (map.find(ent) != map.end()) {
2049 fe_contact_tree->exeTestHook =
2052 return fe_contact_tree;
2057 std::map<int, Range> map;
2062 (boost::format(
"%s(.*)") % name).str()
2071 map[m_ptr->getMeshsetId()] = ents;
2078 EshelbianCore &ep, boost::shared_ptr<ForcesAndSourcesCore> fe_ptr,
2079 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pip) {
2082 auto contact_tree_ptr = boost::dynamic_pointer_cast<ContactTree>(fe_ptr);
2084 auto &m_field = ep.
mField;
2090 using SideEleOp = EleOnSide::UserDataOperator;
2091 using BdyEleOp = BoundaryEle::UserDataOperator;
2098 auto rule_contact = [](int, int,
int o) {
return -1; };
2101 auto set_rule_contact = [refine](
2104 int order_col,
int order_data
2108 auto rule = 2 * order_data;
2113 op_loop_skeleton_side->getSideFEPtr()->getRuleHook = rule_contact;
2114 op_loop_skeleton_side->getSideFEPtr()->setRuleHook = set_rule_contact;
2116 EshelbianPlasticity::AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
2122 auto broken_data_ptr = boost::make_shared<std::vector<BrokenBaseSideData>>();
2125 auto contact_common_data_ptr = boost::make_shared<ContactOps::CommonData>();
2127 auto add_ops_domain_side = [&](
auto &pip) {
2132 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
2133 boost::make_shared<CGGUserPolynomialBase>(
nullptr,
true);
2135 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
2136 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
2138 op_loop_domain_side->getOpPtrVector().push_back(
2141 op_loop_domain_side->getOpPtrVector().push_back(
2143 ep.
piolaStress, contact_common_data_ptr->contactTractionPtr()));
2144 pip.push_back(op_loop_domain_side);
2148 auto add_ops_contact_rhs = [&](
auto &pip) {
2151 auto contact_sfd_map_range_ptr = boost::make_shared<std::map<int, Range>>(
2155 ep.
contactDisp, contact_common_data_ptr->contactDispPtr()));
2156 auto u_h1_ptr = boost::make_shared<MatrixDouble>();
2160 contact_tree_ptr, u_h1_ptr,
2161 contact_common_data_ptr->contactTractionPtr(),
2165 ep.
contactDisp, contact_common_data_ptr, contact_tree_ptr,
2166 contact_sfd_map_range_ptr));
2168 broken_data_ptr, contact_common_data_ptr, contact_tree_ptr));
2174 CHKERR add_ops_domain_side(op_loop_skeleton_side->getOpPtrVector());
2175 CHKERR add_ops_contact_rhs(op_loop_skeleton_side->getOpPtrVector());
2178 pip.push_back(op_loop_skeleton_side);
2184 EshelbianCore &ep, boost::shared_ptr<ForcesAndSourcesCore> fe_ptr,
2185 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pip) {
2188 auto contact_tree_ptr = boost::dynamic_pointer_cast<ContactTree>(fe_ptr);
2189 auto &m_field = ep.
mField;
2195 using SideEleOp = EleOnSide::UserDataOperator;
2196 using BdyEleOp = BoundaryEle::UserDataOperator;
2203 auto rule_contact = [](int, int,
int o) {
return -1; };
2206 auto set_rule_contact = [refine](
2209 int order_col,
int order_data
2213 auto rule = 2 * order_data;
2218 op_loop_skeleton_side->getSideFEPtr()->getRuleHook = rule_contact;
2219 op_loop_skeleton_side->getSideFEPtr()->setRuleHook = set_rule_contact;
2221 EshelbianPlasticity::AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
2227 auto broken_data_ptr = boost::make_shared<std::vector<BrokenBaseSideData>>();
2230 auto contact_common_data_ptr = boost::make_shared<ContactOps::CommonData>();
2232 auto add_ops_domain_side = [&](
auto &pip) {
2237 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
2238 boost::make_shared<CGGUserPolynomialBase>(
nullptr,
true);
2240 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
2241 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
2243 op_loop_domain_side->getOpPtrVector().push_back(
2246 op_loop_domain_side->getOpPtrVector().push_back(
2248 ep.
piolaStress, contact_common_data_ptr->contactTractionPtr()));
2249 pip.push_back(op_loop_domain_side);
2253 auto add_ops_contact_lhs = [&](
auto &pip) {
2256 ep.
contactDisp, contact_common_data_ptr->contactDispPtr()));
2257 auto u_h1_ptr = boost::make_shared<MatrixDouble>();
2261 contact_tree_ptr, u_h1_ptr,
2262 contact_common_data_ptr->contactTractionPtr(),
2267 auto contact_sfd_map_range_ptr = boost::make_shared<std::map<int, Range>>(
2272 contact_tree_ptr, contact_sfd_map_range_ptr));
2275 ep.
contactDisp, broken_data_ptr, contact_common_data_ptr,
2276 contact_tree_ptr, contact_sfd_map_range_ptr));
2279 broken_data_ptr, ep.
contactDisp, contact_common_data_ptr,
2286 CHKERR add_ops_domain_side(op_loop_skeleton_side->getOpPtrVector());
2287 CHKERR add_ops_contact_lhs(op_loop_skeleton_side->getOpPtrVector());
2290 pip.push_back(op_loop_skeleton_side);
2297 boost::shared_ptr<ForcesAndSourcesCore> fe_ptr,
2298 boost::shared_ptr<MatrixDouble> u_h1_ptr,
2299 boost::shared_ptr<MatrixDouble> contact_traction_ptr,
2300 Range r, moab::Interface *post_proc_mesh_ptr,
2301 std::vector<EntityHandle> *map_gauss_pts_ptr) {
2303 auto &m_field = ep.
mField;
2304 auto contact_tree_ptr = boost::dynamic_pointer_cast<ContactTree>(fe_ptr);
2306 contact_tree_ptr, u_h1_ptr, contact_traction_ptr,
2308 post_proc_mesh_ptr, map_gauss_pts_ptr);
Implementation of tonsorial bubble base div(v) = 0.
Eshelbian plasticity interface.
#define MOFEM_LOG_SEVERITY_SYNC(comm, severity)
Synchronise "SYNC" on curtain severity level.
#define FTENSOR_INDEX(DIM, I)
ElementsAndOps< SPACE_DIM >::BoundaryEle BoundaryEle
Tensor1< T, Tensor_Dim > normalize()
#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()
#define MYPCOMM_INDEX
default communicator number PCOMM
#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_DATA_INCONSISTENCY
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
static const double face_coords[4][9]
#define MOFEM_LOG(channel, severity)
Log.
#define MOFEM_LOG_CHANNEL(channel)
Set and reset channel.
MoFEMErrorCode getCubitMeshsetPtr(const int ms_id, const CubitBCType cubit_bc_type, const CubitMeshSets **cubit_meshset_ptr) const
get cubit meshset
FTensor::Index< 'i', SPACE_DIM > i
const double c
speed of light (cm/ns)
const double v
phase velocity of light in medium (cm/ns)
FTensor::Index< 'l', 3 > l
FTensor::Index< 'j', 3 > j
FTensor::Index< 'k', 3 > k
static auto get_range_from_block(MoFEM::Interface &m_field, const std::string block_name, int dim)
auto checkSdf(EntityHandle fe_ent, std::map< int, Range > &sdf_map_range)
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.
auto multiMasterPoint(ContactTree::FaceData *face_data_ptr, FTensor::Tensor1< T1, 3 > &t_spatial_coords)
auto multiGetGap(ContactTree::FaceData *face_data_ptr, FTensor::Tensor1< T1, 3 > &t_spatial_coords)
auto multiPointRhs(ContactTree::FaceData *face_data_ptr, FTensor::Tensor1< T1, 3 > &t_coords, FTensor::Tensor1< T2, 3 > &t_spatial_coords, FTensor::Tensor1< T3, 3 > &t_master_traction, MultiPointRhsType type, bool debug=false)
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.
auto multiSlavePoint(ContactTree::FaceData *face_data_ptr, FTensor::Tensor1< T1, 3 > &t_spatial_coords)
auto multiPoint(std::array< double, 3 > &unit_ray, std::array< double, 3 > &point, std::array< double, 9 > &elem_point_nodes, std::array< double, 9 > &elem_traction_nodes, FTensor::Tensor1< T1, 3 > &t_spatial_coords)
Calculate points data on contact surfaces.
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 auto get_body_range(MoFEM::Interface &m_field, const std::string name, int dim)
auto getSdf(OP_PTR op_ptr, MatrixDouble &contact_disp, int block_id, bool eval_hessian)
PipelineManager::ElementsAndOpsByDim< SPACE_DIM >::FaceSideEle EleOnSide
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
VectorBoundedArray< double, 3 > VectorDouble3
UBlasMatrix< double > MatrixDouble
implementation of Data Operators for Forces and Sources
auto id_from_handle(const EntityHandle h)
PetscErrorCode PetscOptionsGetScalar(PetscOptions *, const char pre[], const char name[], PetscScalar *dval, PetscBool *set)
void tricircumcenter3d_tp(double a[3], double b[3], double c[3], double circumcenter[3], double *xi, double *eta)
PetscErrorCode PetscOptionsGetString(PetscOptions *, const char pre[], const char name[], char str[], size_t size, PetscBool *set)
static auto getFTensor0FromVec(V &data)
Get tensor rank 0 (scalar) form data vector.
FTensor::Index< 'm', 3 > m
boost::shared_ptr< Range > frontAdjEdges
MoFEM::Interface & mField
const std::string materialH1Positions
const std::string elementVolumeName
const std::string spatialH1Disp
const std::string piolaStress
int contactRefinementLevels
static PetscBool physicalTimeFlg
static double currentPhysicalTime
const std::string contactDisp
const std::string contactElement
boost::shared_ptr< ContactOps::CommonData > commonDataPtr
boost::shared_ptr< ContactTree > contactTreePtr
boost::shared_ptr< ContactTree > contactTreePtr
boost::shared_ptr< ContactOps::CommonData > commonDataPtr
boost::shared_ptr< ContactOps::CommonData > commonDataPtr
boost::shared_ptr< std::map< int, Range > > sdfMapRangePtr
boost::shared_ptr< ContactTree > contactTreePtr
boost::shared_ptr< std::map< int, Range > > sdfMapRangePtr
MoFEMErrorCode iNtegrate(EntitiesFieldData::EntData &row_data, EntitiesFieldData::EntData &col_data)
OpConstrainBoundaryL2Lhs_dU(const std::string row_field_name, const std::string col_field_name, boost::shared_ptr< ContactOps::CommonData > common_data_ptr, boost::shared_ptr< ContactTree > contact_tree_ptr, boost::shared_ptr< std::map< int, Range > > sdf_map_range_ptr=nullptr)
boost::shared_ptr< ContactOps::CommonData > commonDataPtr
boost::shared_ptr< ContactTree > contactTreePtr
boost::shared_ptr< std::map< int, Range > > sdfMapRangePtr
boost::shared_ptr< ContactOps::CommonData > commonDataPtr
boost::shared_ptr< ContactTree > contactTreePtr
MoFEMErrorCode iNtegrate(EntitiesFieldData::EntData &row_data)
OpConstrainBoundaryL2Rhs(const std::string row_field_name, boost::shared_ptr< ContactOps::CommonData > common_data_ptr, boost::shared_ptr< ContactTree > contact_tree_ptr, boost::shared_ptr< std::map< int, Range > > sdf_map_range_ptr=nullptr)
boost::shared_ptr< ContactOps::CommonData > commonDataPtr
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
boost::weak_ptr< ContactTree > contactTreePtr
FaceElementForcesAndSourcesCore::UserDataOperator UOP
boost::shared_ptr< MatrixDouble > uH1Ptr
OpMoveNode(boost::shared_ptr< ContactTree > contact_tree_ptr, boost::shared_ptr< ContactOps::CommonData > common_data_ptr, boost::shared_ptr< MatrixDouble > u_h1_ptr)
moab::Interface * postProcMeshPtr
boost::shared_ptr< ContactTree > contactTreePtr
std::vector< EntityHandle > * mapGaussPtsPtr
boost::shared_ptr< MatrixDouble > uH1Ptr
OpTreeSearch(boost::shared_ptr< ContactTree > contact_tree_ptr, boost::shared_ptr< MatrixDouble > u_h1_ptr, boost::shared_ptr< MatrixDouble > traction_ptr, Range r, moab::Interface *post_proc_mesh_ptr, std::vector< EntityHandle > *map_gauss_pts_ptr)
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
boost::shared_ptr< MatrixDouble > tractionPtr
FaceElementForcesAndSourcesCore::UserDataOperator UOP
virtual int get_comm_size() const =0
virtual moab::Interface & get_moab()=0
virtual int get_comm_rank() const =0
Deprecated interface functions.
Data on single entity (This is passed as argument to DataOperator::doWork)
FTensor::Tensor0< FTensor::PackPtr< double *, 1 > > getFTensor0N(const FieldApproximationBase base)
Get base function as Tensor0.
MatrixDouble & getN(const FieldApproximationBase base)
get base functions this return matrix (nb. of rows is equal to nb. of Gauss pts, nb....
auto getFTensor1N(FieldApproximationBase base)
Get base functions for Hdiv/Hcurl spaces.
const VectorInt & getIndices() const
Get global indices of degrees of freedom on entity.
Structure for user loop methods on finite elements.
EntityHandle getFEEntityHandle() const
Get the entity handle of the current finite element.
Base face element used to integrate on skeleton.
default operator for TRI element
structure to get information from mofem into EntitiesFieldData
MatrixDouble gaussPts
Matrix of integration points.
static auto getOrCreate(moab::Core *core_mesh_ptr)
Interface for managing meshsets containing materials and boundary conditions.
Operator for broken loop side.
Calculate trace of vector (Hdiv/Hcurl) space.
Specialization for MatrixDouble vector field values calculation.
Element used to execute operators on side of the element.
Template struct for dimension-specific finite element types.
std::string optionsPrefix
Prefix for options.
MoFEMErrorCode writeFile(const std::string file_name)
wrote results in (MOAB) format, use "file_name.h5m"
auto getPostProcMeshPcommPtr()
auto & getPostProcMesh()
Get postprocessing mesh.
std::map< EntityType, PostProcGenerateRefMeshPtr > refElementsMap
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.
BoundaryEle::UserDataOperator BdyEleOp
double zeta
Viscous hardening.