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;
45 #pragma message "With ENABLE_PYTHON_BINDING"
49 #pragma message "Without ENABLE_PYTHON_BINDING"
53#include <ContactOps.hpp>
59 double circumcenter[3],
double *xi,
double *
eta);
65 using ContactOps::SDFPython::SDFPython;
69 boost::shared_ptr<ContactSDFPython> sdf_python_ptr;
71#ifdef ENABLE_PYTHON_BINDING
73 auto file_exists = [](std::string myfile) {
74 std::ifstream file(myfile.c_str());
81 char sdf_file_name[255] =
"sdf.py";
83 sdf_file_name, 255, PETSC_NULLPTR);
85 if (file_exists(sdf_file_name)) {
86 MOFEM_LOG(
"EP", Sev::inform) << sdf_file_name <<
" file found";
87 sdf_python_ptr = boost::make_shared<ContactSDFPython>();
88 CHKERR sdf_python_ptr->sdfInit(sdf_file_name);
89 ContactOps::sdfPythonWeakPtr = sdf_python_ptr;
90 MOFEM_LOG(
"EP", Sev::inform) <<
"SdfPython initialized";
92 MOFEM_LOG(
"EP", Sev::warning) << sdf_file_name <<
" file NOT found";
97 return sdf_python_ptr;
107 boost::shared_ptr<moab::Core> core_mesh_ptr,
int max_order,
108 std::map<int, Range> &&body_map);
140 using MapFaceData = std::map<EntityHandle, std::vector<FaceData>>;
144 auto it = map_face_data.find(fe_ent);
145 if (it == map_face_data.end()) {
146 return (std::vector<FaceData> *)
nullptr;
148 return &(it->second);
152 std::vector<FaceData> *vec_ptr) {
154 if (it != vec_ptr->end()) {
155 if (it->gaussPtNb == gg) {
156 face_data_ptr = &(*it);
160 return face_data_ptr;
185 for (
auto &m_sdf : sdf_map_range) {
186 if (m_sdf.second.find(fe_ent) != m_sdf.second.end())
192template <
typename OP_PTR>
196 auto nb_gauss_pts = op_ptr->getGaussPts().size2();
198 auto ts_time = op_ptr->getTStime();
199 auto ts_time_step = op_ptr->getTStimeStep();
206 op_ptr->getFTensor1CoordsAtGaussPts(),
207 getFTensor1FromMat<3>(contact_disp), nb_gauss_pts);
209 op_ptr->getFTensor1NormalsAtGaussPts(), nb_gauss_pts);
211 ts_time_step, ts_time, nb_gauss_pts, m_spatial_coords, m_normals_at_pts,
214 ts_time_step, ts_time, nb_gauss_pts, m_spatial_coords, m_normals_at_pts,
218 if (v_sdf.size() != nb_gauss_pts)
220 "Wrong number of integration pts");
221 if (m_grad_sdf.size2() != nb_gauss_pts)
223 "Wrong number of integration pts");
224 if (m_grad_sdf.size1() != 3)
230 ts_time_step, ts_time, nb_gauss_pts, m_spatial_coords, m_normals_at_pts,
232 return std::make_tuple(block_id, m_normals_at_pts, v_sdf, m_grad_sdf,
236 return std::make_tuple(block_id, m_normals_at_pts, v_sdf, m_grad_sdf,
252template <
typename T1>
255 std::array<double, 3> &unit_ray, std::array<double, 3> &point,
257 std::array<double, 9> &elem_point_nodes,
258 std::array<double, 9> &elem_traction_nodes,
263 auto t_unit_ray = getFTensor1FromPtr<3>(unit_ray.data());
264 auto t_point = getFTensor1FromPtr<3>(point.data());
266 auto get_normal = [](
auto &ele_coords) {
272 auto t_normal = get_normal(elem_point_nodes);
273 t_normal(
i) /= t_normal.l2();
275 auto sn = t_normal(
i) * t_point(
i);
276 auto nm = t_normal(
i) * t_spatial_coords(
i);
277 auto nr = t_normal(
i) * t_unit_ray(
i);
279 auto gamma = (sn - nm) / nr;
282 t_point_current(
i) = t_spatial_coords(
i) + gamma * t_unit_ray(
i);
284 auto get_local_point_shape_functions = [&](
auto &&t_elem_coords,
286 std::array<T1, 2> loc_coords;
289 &t_elem_coords(0, 0), &t_point(0), 1, loc_coords.data()),
292 N_MBTRI1(loc_coords[0], loc_coords[1]),
293 N_MBTRI2(loc_coords[0], loc_coords[1])};
296 auto eval_position = [&](
auto &&t_field,
auto &t_shape_fun) {
300 t_point_out(
i) = t_shape_fun(
j) * t_field(
j,
i);
304 auto t_shape_fun = get_local_point_shape_functions(
305 getFTensor2FromPtr<3, 3>(elem_point_nodes.data()), t_point_current);
306 auto t_slave_point_updated = eval_position(
307 getFTensor2FromPtr<3, 3>(elem_point_nodes.data()), t_shape_fun);
308 auto t_traction_updated = eval_position(
309 getFTensor2FromPtr<3, 3>(elem_traction_nodes.data()), t_shape_fun);
311 return std::make_tuple(t_slave_point_updated, t_traction_updated, t_normal);
314template <
typename T1>
327template <
typename T1>
343template <
typename T1>
347 auto [t_slave_point_current, t_slave_traction_current, t_slave_normal] =
349 auto [t_master_point_current, t_master_traction_current, t_master_normal] =
355 t_normal(
i) = t_master_normal(
i) - t_slave_normal(
i);
358 auto gap = t_normal(
i) * (t_slave_point_current(
i) - t_spatial_coords(
i));
359 auto tn_master = t_master_traction_current(
i) * t_normal(
i);
360 auto tn_slave = t_slave_traction_current(
i) * t_normal(
i);
361 auto tn = std::max(-tn_master, tn_slave);
363 return std::make_tuple(gap, tn_master, tn_slave,
365 t_master_traction_current, t_slave_traction_current);
372template <
typename T1,
typename T2,
typename T3>
385 t_u(
i) = t_spatial_coords(
i) - t_coords(
i);
392 auto [t_slave_point_current, t_slave_traction_current, t_slave_normal] =
394 auto [t_master_point_current, t_master_traction_current, t_master_normal] =
399 t_normal(
i) = t_master_normal(
i) - t_slave_normal(
i);
404 t_P(
i,
j) = t_normal(
i) * t_normal(
j);
406 t_Q(
i,
j) = kronecker_delta(
i,
j) - t_P(
i,
j);
408 constexpr double beta = 0.5;
415 auto f_min_gap = [
zeta](
auto d,
auto s) {
416 return 0.5 * (d + s - std::sqrt((d - s) * (d - s) +
zeta));
419 auto f_diff_min_gap = [
zeta](
auto d,
auto s) {
420 return 0.5 * (1 - (d - s) / std::sqrt((d - s) * (d - s) +
zeta));
424 auto f_barrier = [alpha1, alpha2, f_min_gap, f_diff_min_gap](
auto g,
428 0.5 * (tn + f_min_gap(d, tn) + f_diff_min_gap(d, tn) * (d - tn));
429 auto b2 = alpha2 * f_min_gap(
g, 0) *
g;
434 t_gap_vec(
i) = beta * t_spatial_coords(
i) +
435 (1 - beta) * t_slave_point_current(
i) - t_spatial_coords(
i);
438 -beta * t_master_traction(
i) + (beta - 1) * t_slave_traction_current(
i);
440 auto t_gap = t_normal(
i) * t_gap_vec(
i);
441 auto t_tn = t_normal(
i) * t_traction_vec(
i);
442 auto barrier = f_barrier(t_gap, t_tn);
446 t_traction_bar(
i) = t_normal(
i) * barrier;
450 t_Q(
i,
j) * t_master_traction(
j) +
452 t_P(
i,
j) * (t_master_traction(
j) - t_traction_bar(
j));
455 auto is_nan_or_inf = [](
double value) ->
bool {
456 return std::isnan(value) || std::isinf(value);
459 double v = std::complex<double>(t_rhs(
i) * t_rhs(
i)).real();
460 if (is_nan_or_inf(
v)) {
462 MOFEM_LOG(
"SELF", Sev::error) <<
"t_rhs " << t_rhs;
478 const std::string row_field_name,
479 boost::shared_ptr<ContactOps::CommonData> common_data_ptr,
480 boost::shared_ptr<ContactTree> contact_tree_ptr,
481 boost::shared_ptr<std::map<int, Range>> sdf_map_range_ptr =
nullptr);
492 const std::string row_field_name,
493 boost::shared_ptr<ContactOps::CommonData> common_data_ptr,
494 boost::shared_ptr<ContactTree> contact_tree_ptr,
495 boost::shared_ptr<std::map<int, Range>> sdf_map_range_ptr)
498 commonDataPtr(common_data_ptr), contactTreePtr(contact_tree_ptr),
499 sdfMapRangePtr(sdf_map_range_ptr) {
508 "get alpha contact failed");
510 PETSC_NULLPTR,
"",
"-alpha_contact_quadratic",
512 "get alpha contact failed");
516 "get alpha contact failed");
536 const size_t nb_gauss_pts = getGaussPts().size2();
541 "Wrong number of integration pts %ld != %ld",
549 auto t_w = getFTensor0IntegrationWeight();
550 auto t_coords = getFTensor1CoordsAtGaussPts();
551 auto t_disp = getFTensor1FromMat<3>(
commonDataPtr->contactDisp);
552 auto t_traction = getFTensor1FromMat<3>(
commonDataPtr->contactTraction);
557 auto [block_id, m_normals_at_pts, v_sdf, m_grad_sdf, m_hess_sdf] =
562 auto t_grad_sdf_v = getFTensor1FromMat<3>(m_grad_sdf);
563 auto t_normalize_normal = getFTensor1FromMat<3>(m_normals_at_pts);
570 ++t_normalize_normal;
575 auto face_data_vec_ptr =
577 auto face_gauss_pts_it = face_data_vec_ptr->begin();
579 auto nb_base_functions = data.
getN().size2();
581 for (
auto gg = 0; gg != nb_gauss_pts; ++gg) {
584 auto face_data_ptr =
contactTreePtr->getFaceDataPtr(face_gauss_pts_it, gg,
587 auto check_face_contact = [&]() {
597#ifdef ENABLE_PYTHON_BINDING
599 if (ContactOps::sdfPythonWeakPtr.lock()) {
600 auto tn = t_traction(
i) * t_grad_sdf_v(
i);
604 constexpr double c = 0;
607 if (!
c && check_face_contact()) {
609 t_spatial_coords(
i) = t_coords(
i) + t_disp(
i);
610 auto t_rhs_tmp =
multiPointRhs(face_data_ptr, t_coords, t_spatial_coords,
612 t_rhs(
i) = t_rhs_tmp(
i);
616#ifdef ENABLE_PYTHON_BINDING
619 if (ContactOps::sdfPythonWeakPtr.lock()) {
621 t_cP(
i,
j) = (
c * t_grad_sdf_v(
i)) * t_grad_sdf_v(
j);
622 t_cQ(
i,
j) = kronecker_delta(
i,
j) - t_cP(
i,
j);
623 t_rhs(
i) = t_cQ(
i,
j) * t_traction(
j) +
624 (
c * inv_cn * t_sdf_v) * t_grad_sdf_v(
i);
626 t_rhs(
i) = t_traction(
i);
629 t_rhs(
i) = t_traction(
i);
633 auto t_nf = getFTensor1FromPtr<3>(&nf[0]);
634 const double alpha = t_w * getMeasure();
637 for (; bb !=
nbRows / 3; ++bb) {
638 const double beta = alpha * t_base;
639 t_nf(
i) -= beta * t_rhs(
i);
643 for (; bb < nb_base_functions; ++bb)
654template <AssemblyType A>
662 boost::shared_ptr<std::vector<BrokenBaseSideData>> broken_base_side_data,
663 boost::shared_ptr<ContactOps::CommonData> common_data_ptr,
664 boost::shared_ptr<ContactTree> contact_tree_ptr);
673template <AssemblyType A>
676 boost::shared_ptr<std::vector<BrokenBaseSideData>>
677 broken_base_side_data,
678 boost::shared_ptr<ContactOps::CommonData> common_data_ptr,
679 boost::shared_ptr<ContactTree> contact_tree_ptr)
680 :
OP(broken_base_side_data), commonDataPtr(common_data_ptr),
681 contactTreePtr(contact_tree_ptr) {}
683template <AssemblyType A>
693 const size_t nb_gauss_pts = OP::getGaussPts().size2();
696 if (commonDataPtr->contactDisp.size2() != nb_gauss_pts) {
698 "Wrong number of integration pts %ld != %ld",
699 commonDataPtr->contactDisp.size2(), nb_gauss_pts);
706 auto t_w = OP::getFTensor0IntegrationWeight();
707 auto t_material_normal = OP::getFTensor1NormalsAtGaussPts();
708 auto t_coords = OP::getFTensor1CoordsAtGaussPts();
710 auto t_disp = getFTensor1FromMat<3>(commonDataPtr->contactDisp);
711 auto t_traction = getFTensor1FromMat<3>(commonDataPtr->contactTraction);
721 auto face_data_vec_ptr =
722 contactTreePtr->findFaceDataVecPtr(OP::getFEEntityHandle());
723 auto face_gauss_pts_it = face_data_vec_ptr->begin();
725 auto nb_base_functions = data.
getN().size2() / 3;
727 for (
auto gg = 0; gg != nb_gauss_pts; ++gg) {
729 auto t_nf = getFTensor1FromPtr<3>(&nf[0]);
730 const double alpha = t_w / 2.;
733 for (; bb != OP::nbRows / 3; ++bb) {
734 const double beta = alpha * t_base(
i) * t_material_normal(
i);
735 t_nf(
i) += beta * t_disp(
i);
739 for (; bb < nb_base_functions; ++bb)
751 const std::string row_field_name,
const std::string col_field_name,
752 boost::shared_ptr<ContactOps::CommonData> common_data_ptr,
753 boost::shared_ptr<ContactTree> contact_tree_ptr,
754 boost::shared_ptr<std::map<int, Range>> sdf_map_range_ptr =
nullptr);
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)
772 commonDataPtr(common_data_ptr), contactTreePtr(contact_tree_ptr),
773 sdfMapRangePtr(sdf_map_range_ptr) {
792 auto &
locMat = AssemblyBoundaryEleOp::locMat;
793 locMat.resize(nb_rows, nb_cols,
false);
796 if (nb_cols && nb_rows) {
798 auto nb_gauss_pts = getGaussPts().size2();
799 auto t_w = getFTensor0IntegrationWeight();
800 auto t_coords = getFTensor1CoordsAtGaussPts();
801 auto t_disp = getFTensor1FromMat<3>(
commonDataPtr->contactDisp);
802 auto t_traction = getFTensor1FromMat<3>(
commonDataPtr->contactTraction);
805 auto [block_id, m_normals_at_pts, v_sdf, m_grad_sdf, m_hess_sdf] =
810 auto t_grad_sdf_v = getFTensor1FromMat<3>(m_grad_sdf);
811 auto t_hess_sdf_v = getFTensor2SymmetricFromMat<3>(m_hess_sdf);
812 auto t_normalized_normal = getFTensor1FromMat<3>(m_normals_at_pts);
822 ++t_normalized_normal;
825 auto face_data_vec_ptr =
827 auto face_gauss_pts_it = face_data_vec_ptr->begin();
830 auto nb_face_functions = row_data.
getN().size2() / 3;
833 for (
size_t gg = 0; gg != nb_gauss_pts; ++gg) {
835 auto face_data_ptr =
contactTreePtr->getFaceDataPtr(face_gauss_pts_it, gg,
838 auto check_face_contact = [&]() {
850#ifdef ENABLE_PYTHON_BINDING
852 if (ContactOps::sdfPythonWeakPtr.lock()) {
853 auto tn = t_traction(
i) * t_grad_sdf_v(
i);
857 constexpr double c = 0;
860 if (!
c && check_face_contact()) {
862 t_spatial_coords(
i) = t_coords(
i) + t_disp(
i);
863 constexpr double eps = std::numeric_limits<float>::epsilon();
864 for (
auto ii = 0; ii < 3; ++ii) {
866 t_spatial_coords(0), t_spatial_coords(1), t_spatial_coords(2)};
867 t_spatial_coords_cx(ii) +=
eps * 1
i;
871 for (
int jj = 0; jj != 3; ++jj) {
872 auto v = t_rhs_tmp(jj).imag();
873 t_res_dU(jj, ii) =
v /
eps;
879#ifdef ENABLE_PYTHON_BINDING
881 if (ContactOps::sdfPythonWeakPtr.lock()) {
885 (-
c) * (t_hess_sdf_v(
i,
j) * t_grad_sdf_v(
k) * t_traction(
k) +
886 t_grad_sdf_v(
i) * t_hess_sdf_v(
k,
j) * t_traction(
k))
888 + (
c * inv_cn) * (t_sdf_v * t_hess_sdf_v(
i,
j) +
890 t_grad_sdf_v(
j) * t_grad_sdf_v(
i));
899 auto alpha = t_w * getMeasure();
902 for (; rr != nb_rows / 3; ++rr) {
904 auto t_mat = getFTensor2FromArray<3, 3, 3>(
locMat, 3 * rr);
907 for (
size_t cc = 0; cc != nb_cols / 3; ++cc) {
908 auto beta = alpha * t_row_base * t_col_base;
909 t_mat(
i,
j) -= beta * t_res_dU(
i,
j);
916 for (; rr < nb_face_functions; ++rr)
928template <AssemblyType A>
936 std::string row_field_name,
937 boost::shared_ptr<std::vector<BrokenBaseSideData>> broken_base_side_data,
938 boost::shared_ptr<ContactOps::CommonData> common_data_ptr,
939 boost::shared_ptr<ContactTree> contact_tree_ptr,
940 boost::shared_ptr<std::map<int, Range>> sdf_map_range_ptr =
nullptr);
951template <AssemblyType A>
954 std::string row_field_name,
955 boost::shared_ptr<std::vector<BrokenBaseSideData>>
956 broken_base_side_data,
957 boost::shared_ptr<ContactOps::CommonData> common_data_ptr,
958 boost::shared_ptr<ContactTree> contact_tree_ptr,
959 boost::shared_ptr<std::map<int, Range>> sdf_map_range_ptr)
960 :
OP(row_field_name, broken_base_side_data, false, false),
961 commonDataPtr(common_data_ptr), contactTreePtr(contact_tree_ptr),
962 sdfMapRangePtr(sdf_map_range_ptr) {
966template <AssemblyType A>
982 auto &locMat = AssemblyBoundaryEleOp::locMat;
983 locMat.resize(nb_rows, nb_cols,
false);
986 if (nb_cols && nb_rows) {
988 const size_t nb_gauss_pts = OP::getGaussPts().size2();
990 auto t_w = OP::getFTensor0IntegrationWeight();
991 auto t_disp = getFTensor1FromMat<3>(commonDataPtr->contactDisp);
992 auto t_traction = getFTensor1FromMat<3>(commonDataPtr->contactTraction);
993 auto t_coords = OP::getFTensor1CoordsAtGaussPts();
994 auto t_material_normal = OP::getFTensor1NormalsAtGaussPts();
997 auto [block_id, m_normals_at_pts, v_sdf, m_grad_sdf, m_hess_sdf] =
998 getSdf(
this, commonDataPtr->contactDisp,
999 checkSdf(OP::getFEEntityHandle(), *sdfMapRangePtr),
false);
1002 auto t_grad_sdf_v = getFTensor1FromMat<3>(m_grad_sdf);
1009 ++t_material_normal;
1014 auto face_data_vec_ptr =
1015 contactTreePtr->findFaceDataVecPtr(OP::getFEEntityHandle());
1016 auto face_gauss_pts_it = face_data_vec_ptr->begin();
1019 auto nb_face_functions = row_data.
getN().size2();
1023 for (
size_t gg = 0; gg != nb_gauss_pts; ++gg) {
1025 auto face_data_ptr = contactTreePtr->getFaceDataPtr(face_gauss_pts_it, gg,
1028 auto check_face_contact = [&]() {
1029 if (
checkSdf(OP::getFEEntityHandle(), *sdfMapRangePtr) != -1)
1032 if (face_data_ptr) {
1040#ifdef ENABLE_PYTHON_BINDING
1042 if (ContactOps::sdfPythonWeakPtr.lock()) {
1043 auto tn = t_traction(
i) * t_grad_sdf_v(
i);
1047 constexpr double c = 0;
1050 if (!
c && check_face_contact()) {
1052 t_spatial_coords(
i) = t_coords(
i) + t_disp(
i);
1053 constexpr double eps = std::numeric_limits<float>::epsilon();
1054 for (
auto ii = 0; ii != 3; ++ii) {
1056 t_traction(0), t_traction(1), t_traction(2)};
1057 t_traction_cx(ii) +=
eps * 1
i;
1061 for (
int jj = 0; jj != 3; ++jj) {
1062 auto v = t_rhs_tmp(jj).imag();
1063 t_res_dP(jj, ii) =
v /
eps;
1068#ifdef ENABLE_PYTHON_BINDING
1069 if (ContactOps::sdfPythonWeakPtr.lock()) {
1071 t_cP(
i,
j) = (
c * t_grad_sdf_v(
i)) * t_grad_sdf_v(
j);
1072 t_cQ(
i,
j) = kronecker_delta(
i,
j) - t_cP(
i,
j);
1073 t_res_dP(
i,
j) = t_cQ(
i,
j);
1082 const double alpha = t_w / 2.;
1084 for (; rr != nb_rows / 3; ++rr) {
1086 auto t_mat = getFTensor2FromArray<3, 3, 3>(locMat, 3 * rr);
1089 for (
size_t cc = 0; cc != nb_cols / 3; ++cc) {
1090 auto col_base = t_col_base(
i) * t_material_normal(
i);
1091 const double beta = alpha * t_row_base * col_base;
1092 t_mat(
i,
j) -= beta * t_res_dP(
i,
j);
1099 for (; rr < nb_face_functions; ++rr)
1109template <AssemblyType A, IntegrationType I>
1112template <AssemblyType A>
1120 boost::shared_ptr<std::vector<BrokenBaseSideData>> broken_base_side_data,
1121 std::string col_field_name,
1122 boost::shared_ptr<ContactOps::CommonData> common_data_ptr,
1123 boost::shared_ptr<ContactTree> contact_tree_ptr);
1133template <AssemblyType A>
1136 boost::shared_ptr<std::vector<BrokenBaseSideData>>
1137 broken_base_side_data,
1138 std::string col_field_name,
1139 boost::shared_ptr<ContactOps::CommonData> common_data_ptr,
1140 boost::shared_ptr<ContactTree> contact_tree_ptr)
1141 :
OP(col_field_name, broken_base_side_data, true, true),
1142 commonDataPtr(common_data_ptr), contactTreePtr(contact_tree_ptr) {
1146template <AssemblyType A>
1165 auto &locMat = AssemblyBoundaryEleOp::locMat;
1166 locMat.resize(nb_rows, nb_cols,
false);
1169 if (nb_cols && nb_rows) {
1171 const size_t nb_gauss_pts = OP::getGaussPts().size2();
1173 auto t_w = OP::getFTensor0IntegrationWeight();
1174 auto t_disp = getFTensor1FromMat<3>(commonDataPtr->contactDisp);
1175 auto t_traction = getFTensor1FromMat<3>(commonDataPtr->contactTraction);
1176 auto t_coords = OP::getFTensor1CoordsAtGaussPts();
1177 auto t_material_normal = OP::getFTensor1NormalsAtGaussPts();
1184 ++t_material_normal;
1189 auto face_data_vec_ptr =
1190 contactTreePtr->findFaceDataVecPtr(OP::getFEEntityHandle());
1191 auto face_gauss_pts_it = face_data_vec_ptr->begin();
1194 auto nb_face_functions = row_data.
getN().size2() / 3;
1195 for (
size_t gg = 0; gg != nb_gauss_pts; ++gg) {
1197 const auto alpha = t_w / 2.;
1200 for (; rr != nb_rows / 3; ++rr) {
1202 auto row_base = alpha * (t_row_base(
i) * t_material_normal(
i));
1204 auto t_mat = getFTensor2FromArray<3, 3, 3>(locMat, 3 * rr);
1207 for (
size_t cc = 0; cc != nb_cols / 3; ++cc) {
1208 const auto beta = row_base * t_col_base;
1216 for (; rr < nb_face_functions; ++rr)
1223 locMat = trans(locMat);
1229 boost::shared_ptr<moab::Core> core_mesh_ptr,
1230 int max_order, std::map<int, Range> &&body_map)
1231 :
Base(m_field, core_mesh_ptr,
"contact"), maxOrder(max_order),
1234 auto ref_ele_ptr = boost::make_shared<PostProcGenerateRefMesh<MBTRI>>();
1235 ref_ele_ptr->hoNodes =
1240 "Error when generating reference element");
1242 MOFEM_LOG(
"EP", Sev::inform) <<
"Contact hoNodes " << ref_ele_ptr->hoNodes
1246 <<
"Contact maxOrder " << ref_ele_ptr->defMaxLevel;
1250 int def_ele_id = -1;
1252 MB_TAG_CREAT | MB_TAG_DENSE,
1255 thBodyId, MB_TAG_CREAT | MB_TAG_DENSE,
1275 std::array<double, 3> def_small_x{0., 0., 0.};
1277 MB_TAG_CREAT | MB_TAG_DENSE,
1278 def_small_x.data());
1280 MB_TAG_CREAT | MB_TAG_DENSE,
1281 def_small_x.data());
1283 std::array<double, 3> def_tractions{0., 0., 0.};
1285 "TRACTION", 3, MB_TYPE_DOUBLE,
thTraction, MB_TAG_CREAT | MB_TAG_DENSE,
1286 &*def_tractions.begin());
1301 PetscBarrier(
nullptr);
1303 ParallelComm *pcomm_post_proc_mesh =
1305 if (pcomm_post_proc_mesh ==
nullptr)
1310 auto brodacts = [&](
auto &brodacts_ents) {
1314 pcomm_post_proc_mesh->broadcast_entities(
1321 Range brodacts_ents;
1323 CHKERR brodacts(brodacts_ents);
1342 treeSurfPtr = boost::shared_ptr<OrientedBoxTreeTool>(
1355 OpMoveNode(boost::shared_ptr<ContactTree> contact_tree_ptr,
1356 boost::shared_ptr<ContactOps::CommonData> common_data_ptr,
1357 boost::shared_ptr<MatrixDouble> u_h1_ptr);
1368 boost::shared_ptr<ContactTree> contact_tree_ptr,
1369 boost::shared_ptr<ContactOps::CommonData> common_data_ptr,
1370 boost::shared_ptr<MatrixDouble> u_h1_ptr)
1371 :
UOP(
NOSPACE,
UOP::OPSPACE), contactTreePtr(contact_tree_ptr),
1372 uH1Ptr(u_h1_ptr), commonDataPtr(common_data_ptr) {}
1378 auto get_body_id = [&](
auto fe_ent) {
1380 if (
m.second.find(fe_ent) !=
m.second.end()) {
1390 auto fe_ent = getNumeredEntFiniteElementPtr()->getEnt();
1392 auto body_id = get_body_id(fe_ent);
1396 post_proc_ents, &fe_id);
1398 post_proc_ents, &body_id);
1400 auto nb_gauss_pts = getGaussPts().size2();
1401 auto t_u_h1 = getFTensor1FromMat<3>(*
uH1Ptr);
1402 auto t_u_l2 = getFTensor1FromMat<3>(
commonDataPtr->contactDisp);
1403 auto t_coords = getFTensor1CoordsAtGaussPts();
1406 auto t_x_h1 = getFTensor1FromPtr<3>(&x_h1(0, 0));
1408 auto t_x_l2 = getFTensor1FromPtr<3>(&x_l2(0, 0));
1415 for (
auto gg = 0; gg != nb_gauss_pts; ++gg) {
1416 t_x_h1(
i) = t_coords(
i) + t_u_h1(
i);
1417 t_x_l2(
i) = t_coords(
i) + t_u_l2(
i);
1426 CHKERR moab_post_proc_mesh.set_coords(
1427 &*map_gauss_pts.begin(), map_gauss_pts.size(), &*x_h1.data().begin());
1428 CHKERR moab_post_proc_mesh.tag_set_data(
1429 contactTreePtr->thSmallX, &*map_gauss_pts.begin(), map_gauss_pts.size(),
1430 &*x_h1.data().begin());
1431 CHKERR moab_post_proc_mesh.tag_set_data(
1432 contactTreePtr->thLargeX, &*map_gauss_pts.begin(), map_gauss_pts.size(),
1433 &*coords.data().begin());
1434 CHKERR moab_post_proc_mesh.tag_set_data(
1435 contactTreePtr->thTraction, &*map_gauss_pts.begin(), map_gauss_pts.size(),
1436 &*tractions.data().begin());
1445 OpTreeSearch(boost::shared_ptr<ContactTree> contact_tree_ptr,
1446 boost::shared_ptr<MatrixDouble> u_h1_ptr,
1447 boost::shared_ptr<MatrixDouble> traction_ptr,
Range r,
1449 moab::Interface *post_proc_mesh_ptr,
1450 std::vector<EntityHandle> *map_gauss_pts_ptr
1467 boost::shared_ptr<MatrixDouble> u_h1_ptr,
1468 boost::shared_ptr<MatrixDouble> traction_ptr,
1471 moab::Interface *post_proc_mesh_ptr,
1472 std::vector<EntityHandle> *map_gauss_pts_ptr
1475 :
UOP(
NOSPACE,
UOP::OPSPACE), contactTreePtr(contact_tree_ptr),
1476 uH1Ptr(u_h1_ptr), tractionPtr(traction_ptr),
1477 postProcMeshPtr(post_proc_mesh_ptr), mapGaussPtsPtr(map_gauss_pts_ptr),
1484 auto &m_field = getPtrFE()->mField;
1485 auto fe_ent = getNumeredEntFiniteElementPtr()->getEnt();
1494 const auto nb_gauss_pts = getGaussPts().size2();
1496 auto t_disp_h1 = getFTensor1FromMat<3>(*
uH1Ptr);
1497 auto t_coords = getFTensor1CoordsAtGaussPts();
1498 auto t_traction = getFTensor1FromMat<3>(*
tractionPtr);
1506 auto get_ele_centre = [
i](
auto t_ele_coords) {
1508 t_ele_center(
i) = 0;
1509 for (
int nn = 0; nn != 3; nn++) {
1510 t_ele_center(
i) += t_ele_coords(
i);
1513 t_ele_center(
i) /= 3;
1514 return t_ele_center;
1517 auto get_ele_radius = [
i](
auto t_ele_center,
auto t_ele_coords) {
1519 t_n0(
i) = t_ele_center(
i) - t_ele_coords(
i);
1523 auto get_face_conn = [
this](
auto face) {
1527 face, conn, num_nodes,
true),
1529 if (num_nodes != 3) {
1535 auto get_face_coords = [
this](
auto conn) {
1536 std::array<double, 9> coords;
1541 auto get_closet_face = [
this](
auto *point_ptr,
auto r) {
1543 std::vector<EntityHandle> faces_out;
1547 "get closest faces");
1551 auto get_faces_out = [
this](
auto *point_ptr,
auto *unit_ray_ptr,
auto radius,
1553 std::vector<double> distances_out;
1554 std::vector<EntityHandle> faces_out;
1559 point_ptr, unit_ray_ptr, &radius),
1561 "get closest faces");
1562 return std::make_pair(faces_out, distances_out);
1565 auto get_normal = [](
auto &ele_coords) {
1571 auto make_map = [&](
auto &face_out,
auto &face_dist,
auto &t_ray_point,
1572 auto &t_unit_ray,
auto &t_master_coord) {
1575 std::map<double, EntityHandle>
m;
1576 for (
auto ii = 0; ii != face_out.size(); ++ii) {
1577 auto face_conn = get_face_conn(face_out[ii]);
1580 t_face_normal.normalize();
1582 t_x(
i) = t_ray_point(
i) + t_unit_ray(
i) * face_dist[ii];
1585 t_x(
i) * t_face_normal(
j) - t_master_coord(
i) * t_unit_ray(
j);
1586 if (t_unit_ray(
i) * t_face_normal(
i) > std::cos(M_PI / 3)) {
1587 auto dot = std::sqrt(t_chi(
i,
j) * t_chi(
i,
j));
1588 m[dot] = face_out[ii];
1594 auto get_tag_data = [
this](
auto tag,
auto face,
auto &vec) {
1598 vec.resize(tag_length);
1604 auto create_tag = [
this](
const std::string tag_name,
const int size) {
1605 double def_VAL[] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
1609 tag_name.c_str(), size, MB_TYPE_DOUBLE,
th,
1610 MB_TAG_CREAT | MB_TAG_SPARSE, def_VAL);
1617 auto set_float_precision = [](
const double x) {
1618 if (std::abs(x) < std::numeric_limits<float>::epsilon())
1625 auto save_scal_tag = [&](
auto &
th,
auto v,
const int gg) {
1628 v = set_float_precision(
v);
1635 auto get_fe_adjacencies = [
this](
auto fe_ent) {
1638 &fe_ent, 1, 2,
false, adj_faces, moab::Interface::UNION),
1640 std::set<int> adj_ids;
1641 for (
auto f : adj_faces) {
1647 auto get_face_id = [
this](
auto face) {
1656 auto get_body_id = [
this](
auto face) {
1665 auto get_face_part = [
this](
auto face) {
1666 ParallelComm *pcomm_post_proc_mesh = ParallelComm::get_pcomm(
1670 pcomm_post_proc_mesh->part_tag(), &face, 1, &part) == MB_SUCCESS) {
1676 auto check_face = [&](
auto face,
auto fe_id,
auto part) {
1677 auto face_id = get_face_id(face);
1678 auto face_part = get_face_part(face);
1679 if (face_id == fe_id && face_part == part)
1687 auto save_vec_tag = [&](
auto &
th,
auto &t_d,
const int gg) {
1691 for (
auto &
a :
v.data())
1692 a = set_float_precision(
a);
1694 &*
v.data().begin());
1699 Tag th_mark = create_tag(
"contact_mark", 1);
1700 Tag th_mark_slave = create_tag(
"contact_mark_slave", 1);
1701 Tag th_body_id = create_tag(
"contact_body_id", 1);
1702 Tag th_gap = create_tag(
"contact_gap", 1);
1703 Tag th_tn_master = create_tag(
"contact_tn_master", 1);
1704 Tag th_tn_slave = create_tag(
"contact_tn_slave", 1);
1705 Tag th_contact_traction = create_tag(
"contact_traction", 3);
1706 Tag th_contact_traction_master = create_tag(
"contact_traction_master", 3);
1707 Tag th_contact_traction_slave = create_tag(
"contact_traction_slave", 3);
1708 Tag th_c = create_tag(
"contact_c", 1);
1709 Tag th_normal = create_tag(
"contact_normal", 3);
1710 Tag th_dist = create_tag(
"contact_dip", 3);
1712 auto t_ele_centre = get_ele_centre(getFTensor1Coords());
1713 auto ele_radius = get_ele_radius(t_ele_centre, getFTensor1Coords());
1719 auto adj_fe_ids = get_fe_adjacencies(fe_ent);
1721 for (
auto gg = 0; gg != nb_gauss_pts; ++gg) {
1724 t_spatial_coords(
i) = t_coords(
i) + t_disp_h1(
i);
1727 CHKERR save_vec_tag(th_contact_traction, t_traction, gg);
1730 auto faces_close = get_closet_face(&t_spatial_coords(0), ele_radius);
1731 for (
auto face_close : faces_close) {
1732 if (check_face(face_close, fe_id, m_field.get_comm_rank())) {
1734 auto body_id = get_body_id(face_close);
1736 auto master_face_conn = get_face_conn(face_close);
1737 std::array<double, 9> master_coords;
1740 master_coords.data());
1741 std::array<double, 9> master_traction;
1744 master_traction.data());
1745 auto t_normal_face_close = get_normal(master_coords);
1746 t_normal_face_close.normalize();
1750 CHKERR save_scal_tag(th_mark,
m, gg);
1751 CHKERR save_scal_tag(th_body_id,
static_cast<double>(body_id), gg);
1752 CHKERR save_vec_tag(th_normal, t_normal_face_close, gg);
1753 CHKERR save_vec_tag(th_contact_traction, t_traction, gg);
1757 t_unit_ray(
i) = -t_normal_face_close(
i);
1760 t_spatial_coords(
i) -
1763 constexpr double eps = 1e-3;
1764 auto [faces_out, faces_dist] =
1765 get_faces_out(&t_ray_point(0), &t_unit_ray(0),
1769 auto m = make_map(faces_out, faces_dist, t_ray_point, t_unit_ray,
1771 for (
auto m_it =
m.begin(); m_it !=
m.end(); ++m_it) {
1772 auto face = m_it->second;
1773 if (face != face_close) {
1777 (adj_fe_ids.find(get_face_id(face)) == adj_fe_ids.end() ||
1778 get_face_part(face) != m_field.get_comm_rank())
1783 shadow_vec.back().gaussPtNb = gg;
1785 auto slave_face_conn = get_face_conn(face);
1786 std::array<double, 9> slave_coords;
1789 slave_coords.data());
1790 auto t_normal_face = get_normal(slave_coords);
1791 std::array<double, 9> slave_tractions;
1794 slave_tractions.data());
1796 auto t_master_point =
1797 getFTensor1FromPtr<3>(shadow_vec.back().masterPoint.data());
1798 auto t_slave_point =
1799 getFTensor1FromPtr<3>(shadow_vec.back().slavePoint.data());
1800 auto t_ray_point_data =
1801 getFTensor1FromPtr<3>(shadow_vec.back().rayPoint.data());
1802 auto t_unit_ray_data =
1803 getFTensor1FromPtr<3>(shadow_vec.back().unitRay.data());
1805 t_slave_point(
i) = t_ray_point(
i) + m_it->first * t_unit_ray(
i);
1807 auto eval_position = [&](
auto &&t_elem_coords,
auto &&t_point) {
1808 std::array<double, 2> loc_coords;
1811 &t_elem_coords(0, 0), &t_point(0), 1,
1813 "get local coords");
1822 t_point_out(
i) = t_shape_fun(
j) * t_elem_coords(
j,
i);
1826 auto t_master_point_updated = eval_position(
1827 getFTensor2FromPtr<3, 3>(master_coords.data()),
1828 getFTensor1FromPtr<3>(shadow_vec.back().masterPoint.data()));
1829 t_master_point(
i) = t_master_point_updated(
i);
1831 auto t_slave_point_updated = eval_position(
1832 getFTensor2FromPtr<3, 3>(slave_coords.data()),
1833 getFTensor1FromPtr<3>(shadow_vec.back().slavePoint.data()));
1834 t_slave_point(
i) = t_slave_point_updated(
i);
1836 t_ray_point_data(
i) = t_ray_point(
i);
1837 t_unit_ray_data(
i) = t_unit_ray(
i);
1839 std::copy(master_coords.begin(), master_coords.end(),
1840 shadow_vec.back().masterPointNodes.begin());
1841 std::copy(master_traction.begin(), master_traction.end(),
1842 shadow_vec.back().masterTractionNodes.begin());
1843 std::copy(slave_coords.begin(), slave_coords.end(),
1844 shadow_vec.back().slavePointNodes.begin());
1845 std::copy(slave_tractions.begin(), slave_tractions.end(),
1846 shadow_vec.back().slaveTractionNodes.begin());
1848 shadow_vec.back().eleRadius = ele_radius;
1858 auto [gap, tn_master, tn_slave,
c, t_master_traction,
1860 multiGetGap(&(shadow_vec.back()), t_spatial_coords);
1862 t_gap_vec(
i) = t_slave_point(
i) - t_spatial_coords(
i);
1863 CHKERR save_scal_tag(th_gap, gap, gg);
1864 CHKERR save_scal_tag(th_tn_master, tn_master, gg);
1865 CHKERR save_scal_tag(th_tn_slave, tn_slave, gg);
1866 CHKERR save_scal_tag(th_c,
c, gg);
1868 CHKERR save_scal_tag(th_mark_slave,
m, gg);
1869 CHKERR save_vec_tag(th_dist, t_gap_vec, gg);
1870 CHKERR save_vec_tag(th_contact_traction_master,
1871 t_master_traction, gg);
1872 CHKERR save_vec_tag(th_contact_traction_slave, t_slave_traction,
1890 const std::string block_name,
int dim) {
1896 std::regex((boost::format(
"%s(.*)") % block_name).str())
1900 for (
auto bc : bcs) {
1904 "get meshset ents");
1911boost::shared_ptr<ForcesAndSourcesCore>
1914 auto &m_field = ep.
mField;
1916 boost::shared_ptr<ContactTree> fe_contact_tree;
1923 std::map<int, Range> map;
1929 (boost::format(
"%s(.*)") % name).str()
1936 m_field.get_moab(), dim, ents,
true),
1938 map[m_ptr->getMeshsetId()] = ents;
1939 MOFEM_LOG(
"EPSYNC", sev) <<
"Meshset: " << m_ptr->getMeshsetId() <<
" "
1940 << ents.size() <<
" entities";
1947 auto get_map_skin = [&](
auto &&map) {
1948 ParallelComm *pcomm =
1949 ParallelComm::get_pcomm(&m_field.get_moab(),
MYPCOMM_INDEX);
1951 Skinner skin(&m_field.get_moab());
1952 for (
auto &
m : map) {
1954 CHKERR skin.find_skin(0,
m.second,
false, skin_faces);
1956 skin_faces, PSTATUS_SHARED | PSTATUS_MULTISHARED,
1957 PSTATUS_NOT, -1,
nullptr),
1959 m.second.swap(skin_faces);
1969 auto contact_common_data_ptr = boost::make_shared<ContactOps::CommonData>();
1971 auto calcs_side_traction = [&](
auto &pip) {
1975 using SideEleOp = EleOnSide::UserDataOperator;
1978 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
1979 boost::make_shared<CGGUserPolynomialBase>();
1980 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
1981 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
1983 op_loop_domain_side->getOpPtrVector().push_back(
1985 ep.
piolaStress, contact_common_data_ptr->contactTractionPtr(),
1986 boost::make_shared<double>(1.0)));
1987 pip.push_back(op_loop_domain_side);
1991 auto add_contact_three = [&]() {
1993 auto tree_moab_ptr = boost::make_shared<moab::Core>();
1994 fe_contact_tree = boost::make_shared<ContactTree>(
1997 fe_contact_tree->getOpPtrVector().push_back(
1999 ep.
contactDisp, contact_common_data_ptr->contactDispPtr()));
2000 CHKERR calcs_side_traction(fe_contact_tree->getOpPtrVector());
2001 auto u_h1_ptr = boost::make_shared<MatrixDouble>();
2002 fe_contact_tree->getOpPtrVector().push_back(
2004 fe_contact_tree->getOpPtrVector().push_back(
2005 new OpMoveNode(fe_contact_tree, contact_common_data_ptr, u_h1_ptr));
2009 CHKERR add_contact_three();
2016 struct exclude_sdf {
2017 exclude_sdf(
Range &&r) : map(r) {}
2018 bool operator()(
FEMethod *fe_method_ptr) {
2020 if (map.find(ent) != map.end()) {
2030 fe_contact_tree->exeTestHook =
2033 return fe_contact_tree;
2038 std::map<int, Range> map;
2043 (boost::format(
"%s(.*)") % name).str()
2052 map[m_ptr->getMeshsetId()] = ents;
2059 EshelbianCore &ep, boost::shared_ptr<ForcesAndSourcesCore> fe_ptr,
2060 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pip) {
2063 auto contact_tree_ptr = boost::dynamic_pointer_cast<ContactTree>(fe_ptr);
2065 auto &m_field = ep.
mField;
2071 using SideEleOp = EleOnSide::UserDataOperator;
2072 using BdyEleOp = BoundaryEle::UserDataOperator;
2079 auto rule_contact = [](int, int,
int o) {
return -1; };
2082 auto set_rule_contact = [refine](
2085 int order_col,
int order_data
2089 auto rule = 2 * order_data;
2094 op_loop_skeleton_side->getSideFEPtr()->getRuleHook = rule_contact;
2095 op_loop_skeleton_side->getSideFEPtr()->setRuleHook = set_rule_contact;
2097 EshelbianPlasticity::AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
2103 auto broken_data_ptr = boost::make_shared<std::vector<BrokenBaseSideData>>();
2106 auto contact_common_data_ptr = boost::make_shared<ContactOps::CommonData>();
2108 auto add_ops_domain_side = [&](
auto &pip) {
2113 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
2114 boost::make_shared<CGGUserPolynomialBase>();
2116 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
2117 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
2119 op_loop_domain_side->getOpPtrVector().push_back(
2122 op_loop_domain_side->getOpPtrVector().push_back(
2124 ep.
piolaStress, contact_common_data_ptr->contactTractionPtr()));
2125 pip.push_back(op_loop_domain_side);
2129 auto add_ops_contact_rhs = [&](
auto &pip) {
2132 auto contact_sfd_map_range_ptr = boost::make_shared<std::map<int, Range>>(
2136 ep.
contactDisp, contact_common_data_ptr->contactDispPtr()));
2137 auto u_h1_ptr = boost::make_shared<MatrixDouble>();
2141 contact_tree_ptr, u_h1_ptr,
2142 contact_common_data_ptr->contactTractionPtr(),
2146 ep.
contactDisp, contact_common_data_ptr, contact_tree_ptr,
2147 contact_sfd_map_range_ptr));
2149 broken_data_ptr, contact_common_data_ptr, contact_tree_ptr));
2155 CHKERR add_ops_domain_side(op_loop_skeleton_side->getOpPtrVector());
2156 CHKERR add_ops_contact_rhs(op_loop_skeleton_side->getOpPtrVector());
2159 pip.push_back(op_loop_skeleton_side);
2165 EshelbianCore &ep, boost::shared_ptr<ForcesAndSourcesCore> fe_ptr,
2166 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pip) {
2169 auto contact_tree_ptr = boost::dynamic_pointer_cast<ContactTree>(fe_ptr);
2170 auto &m_field = ep.
mField;
2176 using SideEleOp = EleOnSide::UserDataOperator;
2177 using BdyEleOp = BoundaryEle::UserDataOperator;
2184 auto rule_contact = [](int, int,
int o) {
return -1; };
2187 auto set_rule_contact = [refine](
2190 int order_col,
int order_data
2194 auto rule = 2 * order_data;
2199 op_loop_skeleton_side->getSideFEPtr()->getRuleHook = rule_contact;
2200 op_loop_skeleton_side->getSideFEPtr()->setRuleHook = set_rule_contact;
2202 EshelbianPlasticity::AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
2208 auto broken_data_ptr = boost::make_shared<std::vector<BrokenBaseSideData>>();
2211 auto contact_common_data_ptr = boost::make_shared<ContactOps::CommonData>();
2213 auto add_ops_domain_side = [&](
auto &pip) {
2218 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
2219 boost::make_shared<CGGUserPolynomialBase>();
2221 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
2222 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
2224 op_loop_domain_side->getOpPtrVector().push_back(
2227 op_loop_domain_side->getOpPtrVector().push_back(
2229 ep.
piolaStress, contact_common_data_ptr->contactTractionPtr()));
2230 pip.push_back(op_loop_domain_side);
2234 auto add_ops_contact_lhs = [&](
auto &pip) {
2237 ep.
contactDisp, contact_common_data_ptr->contactDispPtr()));
2238 auto u_h1_ptr = boost::make_shared<MatrixDouble>();
2242 contact_tree_ptr, u_h1_ptr,
2243 contact_common_data_ptr->contactTractionPtr(),
2248 auto contact_sfd_map_range_ptr = boost::make_shared<std::map<int, Range>>(
2253 contact_tree_ptr, contact_sfd_map_range_ptr));
2256 ep.
contactDisp, broken_data_ptr, contact_common_data_ptr,
2257 contact_tree_ptr, contact_sfd_map_range_ptr));
2260 broken_data_ptr, ep.
contactDisp, contact_common_data_ptr,
2267 CHKERR add_ops_domain_side(op_loop_skeleton_side->getOpPtrVector());
2268 CHKERR add_ops_contact_lhs(op_loop_skeleton_side->getOpPtrVector());
2271 pip.push_back(op_loop_skeleton_side);
2278 boost::shared_ptr<ForcesAndSourcesCore> fe_ptr,
2279 boost::shared_ptr<MatrixDouble> u_h1_ptr,
2280 boost::shared_ptr<MatrixDouble> contact_traction_ptr,
2281 Range r, moab::Interface *post_proc_mesh_ptr,
2282 std::vector<EntityHandle> *map_gauss_pts_ptr) {
2284 auto &m_field = ep.
mField;
2285 auto contact_tree_ptr = boost::dynamic_pointer_cast<ContactTree>(fe_ptr);
2287 contact_tree_ptr, u_h1_ptr, contact_traction_ptr,
2289 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]
MoFEMErrorCode writeFile(const std::string file_name)
wrote results in (MOAB) format, use "file_name.h5m"
#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
boost::shared_ptr< ContactSDFPython > setupContactSdf()
Read SDF file and setup contact SDF.
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.
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)
static auto getFTensor0FromVec(ublas::vector< T, A > &data)
Get tensor rank 0 (scalar) form data vector.
PetscErrorCode PetscOptionsGetString(PetscOptions *, const char pre[], const char name[], char str[], size_t size, PetscBool *set)
OpBaseImpl< PETSC, EdgeEleOp > OpBase
FTensor::Index< 'm', 3 > m
boost::shared_ptr< Range > frontAdjEdges
static double dynamicTime
MoFEM::Interface & mField
const std::string materialH1Positions
const std::string elementVolumeName
static PetscBool dynamicRelaxation
const std::string spatialH1Disp
const std::string piolaStress
int contactRefinementLevels
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)
Integrate grad-grad operator.
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)
Class dedicated to integrate operator.
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
boost::shared_ptr< ContactTree > contactTreePtr
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
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....
FTensor::Tensor1< FTensor::PackPtr< double *, Tensor_Dim >, Tensor_Dim > 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.
Interface for managing meshsets containing materials and boundary conditions.
VectorDouble locF
local entity vector
int nbRows
number of dofs on rows
MatrixDouble locMat
local entity block matrix
Operator for broken loop side.
Calculate trace of vector (Hdiv/Hcurl) space.
Specialization for double precision vector field values calculation.
Element used to execute operators on side of the element.
Template struct for dimension-specific finite element types.
MoFEMErrorCode preProcess()
Generate vertices and elements.
std::string optionsPrefix
Prefix for options.
auto & getPostProcMesh()
Get postprocessing mesh.
MoFEMErrorCode postProcess()
Post-processing function executed at loop completion.
std::map< EntityType, PostProcGenerateRefMeshPtr > refElementsMap
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.
BoundaryEle::UserDataOperator BdyEleOp
double zeta
Viscous hardening.