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);
58 using ContactOps::SDFPython::SDFPython;
62 boost::shared_ptr<ContactSDFPython> sdf_python_ptr;
64#ifdef ENABLE_PYTHON_BINDING
66 auto file_exists = [](std::string myfile) {
67 std::ifstream file(myfile.c_str());
74 char sdf_file_name[255] =
"sdf.py";
76 sdf_file_name, 255, PETSC_NULLPTR);
78 if (file_exists(sdf_file_name)) {
79 MOFEM_LOG(
"EP", Sev::inform) << sdf_file_name <<
" file found";
80 sdf_python_ptr = boost::make_shared<ContactSDFPython>();
81 CHKERR sdf_python_ptr->sdfInit(sdf_file_name);
82 ContactOps::sdfPythonWeakPtr = sdf_python_ptr;
83 MOFEM_LOG(
"EP", Sev::inform) <<
"SdfPython initialized";
85 MOFEM_LOG(
"EP", Sev::warning) << sdf_file_name <<
" file NOT found";
90 return sdf_python_ptr;
100 boost::shared_ptr<moab::Core> core_mesh_ptr,
int max_order,
101 std::map<int, Range> &&body_map);
138 using MapFaceData = std::map<EntityHandle, std::vector<FaceData>>;
142 auto it = map_face_data.find(fe_ent);
143 if (it == map_face_data.end()) {
144 return (std::vector<FaceData> *)
nullptr;
146 return &(it->second);
150 std::vector<FaceData> *vec_ptr) {
152 if (it != vec_ptr->end()) {
153 if (it->gaussPtNb == gg) {
154 face_data_ptr = &(*it);
158 return face_data_ptr;
183 for (
auto &m_sdf : sdf_map_range) {
184 if (m_sdf.second.find(fe_ent) != m_sdf.second.end())
190template <
typename OP_PTR>
194 auto nb_gauss_pts = op_ptr->getGaussPts().size2();
196 auto ts_time = op_ptr->getTStime();
197 auto ts_time_step = op_ptr->getTStimeStep();
204 op_ptr->getFTensor1CoordsAtGaussPts(),
205 getFTensor1FromMat<3>(contact_disp), nb_gauss_pts);
207 op_ptr->getFTensor1NormalsAtGaussPts(), nb_gauss_pts);
209 ts_time_step, ts_time, nb_gauss_pts, m_spatial_coords, m_normals_at_pts,
212 ts_time_step, ts_time, nb_gauss_pts, m_spatial_coords, m_normals_at_pts,
216 if (v_sdf.size() != nb_gauss_pts)
218 "Wrong number of integration pts");
219 if (m_grad_sdf.size2() != nb_gauss_pts)
221 "Wrong number of integration pts");
222 if (m_grad_sdf.size1() != 3)
228 ts_time_step, ts_time, nb_gauss_pts, m_spatial_coords, m_normals_at_pts,
230 return std::make_tuple(block_id, m_normals_at_pts, v_sdf, m_grad_sdf,
234 return std::make_tuple(block_id, m_normals_at_pts, v_sdf, m_grad_sdf,
250template <
typename T1>
253 std::array<double, 3> &unit_ray, std::array<double, 3> &point,
255 std::array<double, 9> &elem_point_nodes,
256 std::array<double, 9> &elem_traction_nodes,
261 auto t_unit_ray = getFTensor1FromPtr<3>(unit_ray.data());
262 auto t_point = getFTensor1FromPtr<3>(point.data());
264 auto get_normal = [](
auto &ele_coords) {
270 auto t_normal = get_normal(elem_point_nodes);
271 t_normal(
i) /= t_normal.l2();
273 auto sn = t_normal(
i) * t_point(
i);
274 auto nm = t_normal(
i) * t_spatial_coords(
i);
275 auto nr = t_normal(
i) * t_unit_ray(
i);
277 auto gamma = (sn - nm) / nr;
280 t_point_current(
i) = t_spatial_coords(
i) + gamma * t_unit_ray(
i);
282 auto get_local_point_shape_functions = [&](
auto &&t_elem_coords,
284 std::array<T1, 2> loc_coords;
287 &t_elem_coords(0, 0), &t_point(0), 1, loc_coords.data()),
290 N_MBTRI1(loc_coords[0], loc_coords[1]),
291 N_MBTRI2(loc_coords[0], loc_coords[1])};
294 auto eval_position = [&](
auto &&t_field,
auto &t_shape_fun) {
298 t_point_out(
i) = t_shape_fun(
j) * t_field(
j,
i);
302 auto t_shape_fun = get_local_point_shape_functions(
303 getFTensor2FromPtr<3, 3>(elem_point_nodes.data()), t_point_current);
304 auto t_slave_point_updated = eval_position(
305 getFTensor2FromPtr<3, 3>(elem_point_nodes.data()), t_shape_fun);
306 auto t_traction_updated = eval_position(
307 getFTensor2FromPtr<3, 3>(elem_traction_nodes.data()), t_shape_fun);
309 return std::make_tuple(t_slave_point_updated, t_traction_updated, t_normal);
312template <
typename T1>
325template <
typename T1>
341template <
typename T1>
345 auto [t_slave_point_current, t_slave_traction_current, t_slave_normal] =
347 auto [t_master_point_current, t_master_traction_current, t_master_normal] =
353 t_normal(
i) = t_master_normal(
i) - t_slave_normal(
i);
356 auto gap = t_normal(
i) * (t_slave_point_current(
i) - t_spatial_coords(
i));
357 auto tn_master = t_master_traction_current(
i) * t_normal(
i);
358 auto tn_slave = t_slave_traction_current(
i) * t_normal(
i);
359 auto tn = std::max(-tn_master, tn_slave);
361 return std::make_tuple(gap, tn_master, tn_slave,
363 t_master_traction_current, t_slave_traction_current);
370template <
typename T1,
typename T2,
typename T3>
383 t_u(
i) = t_spatial_coords(
i) - t_coords(
i);
390 auto [t_slave_point_current, t_slave_traction_current, t_slave_normal] =
392 auto [t_master_point_current, t_master_traction_current, t_master_normal] =
397 t_normal(
i) = t_master_normal(
i) - t_slave_normal(
i);
402 t_P(
i,
j) = t_normal(
i) * t_normal(
j);
404 t_Q(
i,
j) = kronecker_delta(
i,
j) - t_P(
i,
j);
406 constexpr double beta = 0.5;
413 auto f_min_gap = [
zeta](
auto d,
auto s) {
414 return 0.5 * (d + s - std::sqrt((d - s) * (d - s) +
zeta));
417 auto f_diff_min_gap = [
zeta](
auto d,
auto s) {
418 return 0.5 * (1 - (d - s) / std::sqrt((d - s) * (d - s) +
zeta));
422 auto f_barrier = [alpha1, alpha2, f_min_gap, f_diff_min_gap](
auto g,
426 0.5 * (tn + f_min_gap(d, tn) + f_diff_min_gap(d, tn) * (d - tn));
427 auto b2 = alpha2 * f_min_gap(
g, 0) *
g;
432 t_gap_vec(
i) = beta * t_spatial_coords(
i) +
433 (1 - beta) * t_slave_point_current(
i) - t_spatial_coords(
i);
436 -beta * t_master_traction(
i) + (beta - 1) * t_slave_traction_current(
i);
438 auto t_gap = t_normal(
i) * t_gap_vec(
i);
439 auto t_tn = t_normal(
i) * t_traction_vec(
i);
440 auto barrier = f_barrier(t_gap, t_tn);
444 t_traction_bar(
i) = t_normal(
i) * barrier;
448 t_Q(
i,
j) * t_master_traction(
j) +
450 t_P(
i,
j) * (t_master_traction(
j) - t_traction_bar(
j));
453 auto is_nan_or_inf = [](
double value) ->
bool {
454 return std::isnan(value) || std::isinf(value);
457 double v = std::complex<double>(t_rhs(
i) * t_rhs(
i)).real();
458 if (is_nan_or_inf(
v)) {
460 MOFEM_LOG(
"SELF", Sev::error) <<
"t_rhs " << t_rhs;
476 const std::string row_field_name,
477 boost::shared_ptr<ContactOps::CommonData> common_data_ptr,
478 boost::shared_ptr<ContactTree> contact_tree_ptr,
479 boost::shared_ptr<std::map<int, Range>> sdf_map_range_ptr =
nullptr);
490 const std::string row_field_name,
491 boost::shared_ptr<ContactOps::CommonData> common_data_ptr,
492 boost::shared_ptr<ContactTree> contact_tree_ptr,
493 boost::shared_ptr<std::map<int, Range>> sdf_map_range_ptr)
496 commonDataPtr(common_data_ptr), contactTreePtr(contact_tree_ptr),
497 sdfMapRangePtr(sdf_map_range_ptr) {
506 "get alpha contact failed");
508 PETSC_NULLPTR,
"",
"-alpha_contact_quadratic",
510 "get alpha contact failed");
514 "get alpha contact failed");
534 const size_t nb_gauss_pts = getGaussPts().size2();
539 "Wrong number of integration pts %ld != %ld",
547 auto t_w = getFTensor0IntegrationWeight();
548 auto t_coords = getFTensor1CoordsAtGaussPts();
549 auto t_disp = getFTensor1FromMat<3>(
commonDataPtr->contactDisp);
550 auto t_traction = getFTensor1FromMat<3>(
commonDataPtr->contactTraction);
555 auto [block_id, m_normals_at_pts, v_sdf, m_grad_sdf, m_hess_sdf] =
560 auto t_grad_sdf_v = getFTensor1FromMat<3>(m_grad_sdf);
561 auto t_normalize_normal = getFTensor1FromMat<3>(m_normals_at_pts);
568 ++t_normalize_normal;
573 auto face_data_vec_ptr =
575 auto face_gauss_pts_it = face_data_vec_ptr->begin();
577 auto nb_base_functions = data.
getN().size2();
579 for (
auto gg = 0; gg != nb_gauss_pts; ++gg) {
582 auto face_data_ptr =
contactTreePtr->getFaceDataPtr(face_gauss_pts_it, gg,
585 auto check_face_contact = [&]() {
595#ifdef ENABLE_PYTHON_BINDING
597 if (ContactOps::sdfPythonWeakPtr.lock()) {
598 auto tn = t_traction(
i) * t_grad_sdf_v(
i);
602 constexpr double c = 0;
605 if (!
c && check_face_contact()) {
607 t_spatial_coords(
i) = t_coords(
i) + t_disp(
i);
608 auto t_rhs_tmp =
multiPointRhs(face_data_ptr, t_coords, t_spatial_coords,
610 t_rhs(
i) = t_rhs_tmp(
i);
614#ifdef ENABLE_PYTHON_BINDING
617 if (ContactOps::sdfPythonWeakPtr.lock()) {
619 t_cP(
i,
j) = (
c * t_grad_sdf_v(
i)) * t_grad_sdf_v(
j);
620 t_cQ(
i,
j) = kronecker_delta(
i,
j) - t_cP(
i,
j);
621 t_rhs(
i) = t_cQ(
i,
j) * t_traction(
j) +
622 (
c * inv_cn * t_sdf_v) * t_grad_sdf_v(
i);
624 t_rhs(
i) = t_traction(
i);
627 t_rhs(
i) = t_traction(
i);
631 auto t_nf = getFTensor1FromPtr<3>(&nf[0]);
632 const double alpha = t_w * getMeasure();
635 for (; bb != nbRows / 3; ++bb) {
636 const double beta = alpha * t_base;
637 t_nf(
i) -= beta * t_rhs(
i);
641 for (; bb < nb_base_functions; ++bb)
652template <AssemblyType A>
660 boost::shared_ptr<std::vector<BrokenBaseSideData>> broken_base_side_data,
661 boost::shared_ptr<ContactOps::CommonData> common_data_ptr,
662 boost::shared_ptr<ContactTree> contact_tree_ptr);
671template <AssemblyType A>
674 boost::shared_ptr<std::vector<BrokenBaseSideData>>
675 broken_base_side_data,
676 boost::shared_ptr<ContactOps::CommonData> common_data_ptr,
677 boost::shared_ptr<ContactTree> contact_tree_ptr)
678 :
OP(broken_base_side_data), commonDataPtr(common_data_ptr),
679 contactTreePtr(contact_tree_ptr) {}
681template <AssemblyType A>
691 const size_t nb_gauss_pts = OP::getGaussPts().size2();
694 if (commonDataPtr->contactDisp.size2() != nb_gauss_pts) {
696 "Wrong number of integration pts %ld != %ld",
697 commonDataPtr->contactDisp.size2(), nb_gauss_pts);
704 auto t_w = OP::getFTensor0IntegrationWeight();
705 auto t_material_normal = OP::getFTensor1NormalsAtGaussPts();
706 auto t_coords = OP::getFTensor1CoordsAtGaussPts();
708 auto t_disp = getFTensor1FromMat<3>(commonDataPtr->contactDisp);
709 auto t_traction = getFTensor1FromMat<3>(commonDataPtr->contactTraction);
719 auto face_data_vec_ptr =
720 contactTreePtr->findFaceDataVecPtr(OP::getFEEntityHandle());
721 auto face_gauss_pts_it = face_data_vec_ptr->begin();
723 auto nb_base_functions = data.
getN().size2() / 3;
725 for (
auto gg = 0; gg != nb_gauss_pts; ++gg) {
727 auto t_nf = getFTensor1FromPtr<3>(&nf[0]);
728 const double alpha = t_w / 2.;
731 for (; bb != OP::nbRows / 3; ++bb) {
732 const double beta = alpha * t_base(
i) * t_material_normal(
i);
733 t_nf(
i) += beta * t_disp(
i);
737 for (; bb < nb_base_functions; ++bb)
749 const std::string row_field_name,
const std::string col_field_name,
750 boost::shared_ptr<ContactOps::CommonData> common_data_ptr,
751 boost::shared_ptr<ContactTree> contact_tree_ptr,
752 boost::shared_ptr<std::map<int, Range>> sdf_map_range_ptr =
nullptr);
764 const std::string row_field_name,
const std::string col_field_name,
765 boost::shared_ptr<ContactOps::CommonData> common_data_ptr,
766 boost::shared_ptr<ContactTree> contact_tree_ptr,
767 boost::shared_ptr<std::map<int, Range>> sdf_map_range_ptr)
770 commonDataPtr(common_data_ptr), contactTreePtr(contact_tree_ptr),
771 sdfMapRangePtr(sdf_map_range_ptr) {
790 auto &locMat = AssemblyBoundaryEleOp::locMat;
791 locMat.resize(nb_rows, nb_cols,
false);
794 if (nb_cols && nb_rows) {
796 auto nb_gauss_pts = getGaussPts().size2();
797 auto t_w = getFTensor0IntegrationWeight();
798 auto t_coords = getFTensor1CoordsAtGaussPts();
799 auto t_disp = getFTensor1FromMat<3>(
commonDataPtr->contactDisp);
800 auto t_traction = getFTensor1FromMat<3>(
commonDataPtr->contactTraction);
803 auto [block_id, m_normals_at_pts, v_sdf, m_grad_sdf, m_hess_sdf] =
808 auto t_grad_sdf_v = getFTensor1FromMat<3>(m_grad_sdf);
809 auto t_hess_sdf_v = getFTensor2SymmetricFromMat<3>(m_hess_sdf);
810 auto t_normalized_normal = getFTensor1FromMat<3>(m_normals_at_pts);
820 ++t_normalized_normal;
823 auto face_data_vec_ptr =
825 auto face_gauss_pts_it = face_data_vec_ptr->begin();
828 auto nb_face_functions = row_data.
getN().size2() / 3;
831 for (
size_t gg = 0; gg != nb_gauss_pts; ++gg) {
833 auto face_data_ptr =
contactTreePtr->getFaceDataPtr(face_gauss_pts_it, gg,
836 auto check_face_contact = [&]() {
848#ifdef ENABLE_PYTHON_BINDING
850 if (ContactOps::sdfPythonWeakPtr.lock()) {
851 auto tn = t_traction(
i) * t_grad_sdf_v(
i);
855 constexpr double c = 0;
858 if (!
c && check_face_contact()) {
860 t_spatial_coords(
i) = t_coords(
i) + t_disp(
i);
861 constexpr double eps = std::numeric_limits<float>::epsilon();
862 for (
auto ii = 0; ii < 3; ++ii) {
864 t_spatial_coords(0), t_spatial_coords(1), t_spatial_coords(2)};
865 t_spatial_coords_cx(ii) +=
eps * 1
i;
869 for (
int jj = 0; jj != 3; ++jj) {
870 auto v = t_rhs_tmp(jj).imag();
871 t_res_dU(jj, ii) =
v /
eps;
877#ifdef ENABLE_PYTHON_BINDING
879 if (ContactOps::sdfPythonWeakPtr.lock()) {
883 (-
c) * (t_hess_sdf_v(
i,
j) * t_grad_sdf_v(
k) * t_traction(
k) +
884 t_grad_sdf_v(
i) * t_hess_sdf_v(
k,
j) * t_traction(
k))
886 + (
c * inv_cn) * (t_sdf_v * t_hess_sdf_v(
i,
j) +
888 t_grad_sdf_v(
j) * t_grad_sdf_v(
i));
897 auto alpha = t_w * getMeasure();
900 for (; rr != nb_rows / 3; ++rr) {
902 auto t_mat = getFTensor2FromArray<3, 3, 3>(locMat, 3 * rr);
905 for (
size_t cc = 0; cc != nb_cols / 3; ++cc) {
906 auto beta = alpha * t_row_base * t_col_base;
907 t_mat(
i,
j) -= beta * t_res_dU(
i,
j);
914 for (; rr < nb_face_functions; ++rr)
926template <AssemblyType A>
934 std::string row_field_name,
935 boost::shared_ptr<std::vector<BrokenBaseSideData>> broken_base_side_data,
936 boost::shared_ptr<ContactOps::CommonData> common_data_ptr,
937 boost::shared_ptr<ContactTree> contact_tree_ptr,
938 boost::shared_ptr<std::map<int, Range>> sdf_map_range_ptr =
nullptr);
949template <AssemblyType A>
952 std::string row_field_name,
953 boost::shared_ptr<std::vector<BrokenBaseSideData>>
954 broken_base_side_data,
955 boost::shared_ptr<ContactOps::CommonData> common_data_ptr,
956 boost::shared_ptr<ContactTree> contact_tree_ptr,
957 boost::shared_ptr<std::map<int, Range>> sdf_map_range_ptr)
958 :
OP(row_field_name, broken_base_side_data, false, false),
959 commonDataPtr(common_data_ptr), contactTreePtr(contact_tree_ptr),
960 sdfMapRangePtr(sdf_map_range_ptr) {
964template <AssemblyType A>
980 auto &locMat = AssemblyBoundaryEleOp::locMat;
981 locMat.resize(nb_rows, nb_cols,
false);
984 if (nb_cols && nb_rows) {
986 const size_t nb_gauss_pts = OP::getGaussPts().size2();
988 auto t_w = OP::getFTensor0IntegrationWeight();
989 auto t_disp = getFTensor1FromMat<3>(commonDataPtr->contactDisp);
990 auto t_traction = getFTensor1FromMat<3>(commonDataPtr->contactTraction);
991 auto t_coords = OP::getFTensor1CoordsAtGaussPts();
992 auto t_material_normal = OP::getFTensor1NormalsAtGaussPts();
995 auto [block_id, m_normals_at_pts, v_sdf, m_grad_sdf, m_hess_sdf] =
996 getSdf(
this, commonDataPtr->contactDisp,
997 checkSdf(OP::getFEEntityHandle(), *sdfMapRangePtr),
false);
1000 auto t_grad_sdf_v = getFTensor1FromMat<3>(m_grad_sdf);
1007 ++t_material_normal;
1012 auto face_data_vec_ptr =
1013 contactTreePtr->findFaceDataVecPtr(OP::getFEEntityHandle());
1014 auto face_gauss_pts_it = face_data_vec_ptr->begin();
1017 auto nb_face_functions = row_data.
getN().size2();
1021 for (
size_t gg = 0; gg != nb_gauss_pts; ++gg) {
1023 auto face_data_ptr = contactTreePtr->getFaceDataPtr(face_gauss_pts_it, gg,
1026 auto check_face_contact = [&]() {
1027 if (
checkSdf(OP::getFEEntityHandle(), *sdfMapRangePtr) != -1)
1030 if (face_data_ptr) {
1038#ifdef ENABLE_PYTHON_BINDING
1040 if (ContactOps::sdfPythonWeakPtr.lock()) {
1041 auto tn = t_traction(
i) * t_grad_sdf_v(
i);
1045 constexpr double c = 0;
1048 if (!
c && check_face_contact()) {
1050 t_spatial_coords(
i) = t_coords(
i) + t_disp(
i);
1051 constexpr double eps = std::numeric_limits<float>::epsilon();
1052 for (
auto ii = 0; ii != 3; ++ii) {
1054 t_traction(0), t_traction(1), t_traction(2)};
1055 t_traction_cx(ii) +=
eps * 1
i;
1059 for (
int jj = 0; jj != 3; ++jj) {
1060 auto v = t_rhs_tmp(jj).imag();
1061 t_res_dP(jj, ii) =
v /
eps;
1066#ifdef ENABLE_PYTHON_BINDING
1067 if (ContactOps::sdfPythonWeakPtr.lock()) {
1069 t_cP(
i,
j) = (
c * t_grad_sdf_v(
i)) * t_grad_sdf_v(
j);
1070 t_cQ(
i,
j) = kronecker_delta(
i,
j) - t_cP(
i,
j);
1071 t_res_dP(
i,
j) = t_cQ(
i,
j);
1080 const double alpha = t_w / 2.;
1082 for (; rr != nb_rows / 3; ++rr) {
1084 auto t_mat = getFTensor2FromArray<3, 3, 3>(locMat, 3 * rr);
1087 for (
size_t cc = 0; cc != nb_cols / 3; ++cc) {
1088 auto col_base = t_col_base(
i) * t_material_normal(
i);
1089 const double beta = alpha * t_row_base * col_base;
1090 t_mat(
i,
j) -= beta * t_res_dP(
i,
j);
1097 for (; rr < nb_face_functions; ++rr)
1107template <AssemblyType A, IntegrationType I>
1110template <AssemblyType A>
1118 boost::shared_ptr<std::vector<BrokenBaseSideData>> broken_base_side_data,
1119 std::string col_field_name,
1120 boost::shared_ptr<ContactOps::CommonData> common_data_ptr,
1121 boost::shared_ptr<ContactTree> contact_tree_ptr);
1131template <AssemblyType A>
1134 boost::shared_ptr<std::vector<BrokenBaseSideData>>
1135 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)
1139 :
OP(col_field_name, broken_base_side_data, true, true),
1140 commonDataPtr(common_data_ptr), contactTreePtr(contact_tree_ptr) {
1144template <AssemblyType A>
1163 auto &locMat = AssemblyBoundaryEleOp::locMat;
1164 locMat.resize(nb_rows, nb_cols,
false);
1167 if (nb_cols && nb_rows) {
1169 const size_t nb_gauss_pts = OP::getGaussPts().size2();
1171 auto t_w = OP::getFTensor0IntegrationWeight();
1172 auto t_disp = getFTensor1FromMat<3>(commonDataPtr->contactDisp);
1173 auto t_traction = getFTensor1FromMat<3>(commonDataPtr->contactTraction);
1174 auto t_coords = OP::getFTensor1CoordsAtGaussPts();
1175 auto t_material_normal = OP::getFTensor1NormalsAtGaussPts();
1182 ++t_material_normal;
1187 auto face_data_vec_ptr =
1188 contactTreePtr->findFaceDataVecPtr(OP::getFEEntityHandle());
1189 auto face_gauss_pts_it = face_data_vec_ptr->begin();
1192 auto nb_face_functions = row_data.
getN().size2() / 3;
1193 for (
size_t gg = 0; gg != nb_gauss_pts; ++gg) {
1195 const auto alpha = t_w / 2.;
1198 for (; rr != nb_rows / 3; ++rr) {
1200 auto row_base = alpha * (t_row_base(
i) * t_material_normal(
i));
1202 auto t_mat = getFTensor2FromArray<3, 3, 3>(locMat, 3 * rr);
1205 for (
size_t cc = 0; cc != nb_cols / 3; ++cc) {
1206 const auto beta = row_base * t_col_base;
1214 for (; rr < nb_face_functions; ++rr)
1221 locMat = trans(locMat);
1227 boost::shared_ptr<moab::Core> core_mesh_ptr,
1228 int max_order, std::map<int, Range> &&body_map)
1229 :
Base(m_field, core_mesh_ptr,
"contact"), maxOrder(max_order),
1232 auto ref_ele_ptr = boost::make_shared<PostProcGenerateRefMesh<MBTRI>>();
1233 ref_ele_ptr->hoNodes =
1238 "Error when generating reference element");
1240 MOFEM_LOG(
"EP", Sev::inform) <<
"Contact hoNodes " << ref_ele_ptr->hoNodes
1244 <<
"Contact maxOrder " << ref_ele_ptr->defMaxLevel;
1248 int def_ele_id = -1;
1250 MB_TAG_CREAT | MB_TAG_DENSE,
1253 thBodyId, MB_TAG_CREAT | MB_TAG_DENSE,
1273 std::array<double, 3> def_small_x{0., 0., 0.};
1275 MB_TAG_CREAT | MB_TAG_DENSE,
1276 def_small_x.data());
1278 MB_TAG_CREAT | MB_TAG_DENSE,
1279 def_small_x.data());
1281 std::array<double, 3> def_tractions{0., 0., 0.};
1283 "TRACTION", 3, MB_TYPE_DOUBLE,
thTraction, MB_TAG_CREAT | MB_TAG_DENSE,
1284 &*def_tractions.begin());
1299 PetscBarrier(
nullptr);
1302 if (pcomm_post_proc_mesh ==
nullptr)
1305 auto brodacts = [&](
auto &brodacts_ents) {
1309 pcomm_post_proc_mesh->broadcast_entities(
1316 Range brodacts_ents;
1318 CHKERR brodacts(brodacts_ents);
1337 treeSurfPtr = boost::shared_ptr<OrientedBoxTreeTool>(
1348 OpMoveNode(boost::shared_ptr<ContactTree> contact_tree_ptr,
1349 boost::shared_ptr<ContactOps::CommonData> common_data_ptr,
1350 boost::shared_ptr<MatrixDouble> u_h1_ptr);
1361 boost::shared_ptr<ContactTree> contact_tree_ptr,
1362 boost::shared_ptr<ContactOps::CommonData> common_data_ptr,
1363 boost::shared_ptr<MatrixDouble> u_h1_ptr)
1364 :
UOP(
NOSPACE,
UOP::OPSPACE), contactTreePtr(contact_tree_ptr),
1365 uH1Ptr(u_h1_ptr), commonDataPtr(common_data_ptr) {}
1373 auto get_body_id = [&](
auto fe_ent) {
1374 for (
auto &
m : contact_tree_ptr->bodyMap) {
1375 if (
m.second.find(fe_ent) !=
m.second.end()) {
1382 auto &moab_post_proc_mesh = contact_tree_ptr->getPostProcMesh();
1383 auto &post_proc_ents = contact_tree_ptr->getPostProcElements();
1385 auto fe_ent = getNumeredEntFiniteElementPtr()->getEnt();
1387 auto body_id = get_body_id(fe_ent);
1388 auto &map_gauss_pts = contact_tree_ptr->getMapGaussPts();
1390 CHKERR moab_post_proc_mesh.tag_clear_data(contact_tree_ptr->thEleId,
1391 post_proc_ents, &fe_id);
1392 CHKERR moab_post_proc_mesh.tag_clear_data(contact_tree_ptr->thBodyId,
1393 post_proc_ents, &body_id);
1395 auto nb_gauss_pts = getGaussPts().size2();
1396 auto t_u_h1 = getFTensor1FromMat<3>(*
uH1Ptr);
1397 auto t_u_l2 = getFTensor1FromMat<3>(
commonDataPtr->contactDisp);
1398 auto t_coords = getFTensor1CoordsAtGaussPts();
1401 auto t_x_h1 = getFTensor1FromPtr<3>(&x_h1(0, 0));
1403 auto t_x_l2 = getFTensor1FromPtr<3>(&x_l2(0, 0));
1410 for (
auto gg = 0; gg != nb_gauss_pts; ++gg) {
1411 t_x_h1(
i) = t_coords(
i) + t_u_h1(
i);
1412 t_x_l2(
i) = t_coords(
i) + t_u_l2(
i);
1421 CHKERR moab_post_proc_mesh.set_coords(
1422 &*map_gauss_pts.begin(), map_gauss_pts.size(), &*x_h1.data().begin());
1423 CHKERR moab_post_proc_mesh.tag_set_data(
1424 contact_tree_ptr->thSmallX, &*map_gauss_pts.begin(),
1425 map_gauss_pts.size(), &*x_h1.data().begin());
1426 CHKERR moab_post_proc_mesh.tag_set_data(
1427 contact_tree_ptr->thLargeX, &*map_gauss_pts.begin(),
1428 map_gauss_pts.size(), &*coords.data().begin());
1429 CHKERR moab_post_proc_mesh.tag_set_data(
1430 contact_tree_ptr->thTraction, &*map_gauss_pts.begin(),
1431 map_gauss_pts.size(), &*tractions.data().begin());
1435 "ContactTree pointer expired in OpMoveNode");
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 auto pcomm_post_proc_mesh =
contactTreePtr->getPostProcMeshPcommPtr();
1667 if (pcomm_post_proc_mesh ==
nullptr)
1671 pcomm_post_proc_mesh->part_tag(), &face, 1, &part) == MB_SUCCESS) {
1677 auto check_face = [&](
auto face,
auto fe_id,
auto part) {
1678 auto face_id = get_face_id(face);
1679 auto face_part = get_face_part(face);
1680 if (face_id == fe_id && face_part == part)
1688 auto save_vec_tag = [&](
auto &
th,
auto &t_d,
const int gg) {
1692 for (
auto &
a :
v.data())
1693 a = set_float_precision(
a);
1695 &*
v.data().begin());
1700 Tag th_mark = create_tag(
"contact_mark", 1);
1701 Tag th_mark_slave = create_tag(
"contact_mark_slave", 1);
1702 Tag th_body_id = create_tag(
"contact_body_id", 1);
1703 Tag th_gap = create_tag(
"contact_gap", 1);
1704 Tag th_tn_master = create_tag(
"contact_tn_master", 1);
1705 Tag th_tn_slave = create_tag(
"contact_tn_slave", 1);
1706 Tag th_contact_traction = create_tag(
"contact_traction", 3);
1707 Tag th_contact_traction_master = create_tag(
"contact_traction_master", 3);
1708 Tag th_contact_traction_slave = create_tag(
"contact_traction_slave", 3);
1709 Tag th_c = create_tag(
"contact_c", 1);
1710 Tag th_normal = create_tag(
"contact_normal", 3);
1711 Tag th_dist = create_tag(
"contact_dip", 3);
1713 auto t_ele_centre = get_ele_centre(getFTensor1Coords());
1714 auto ele_radius = get_ele_radius(t_ele_centre, getFTensor1Coords());
1720 auto adj_fe_ids = get_fe_adjacencies(fe_ent);
1722 for (
auto gg = 0; gg != nb_gauss_pts; ++gg) {
1725 t_spatial_coords(
i) = t_coords(
i) + t_disp_h1(
i);
1728 CHKERR save_vec_tag(th_contact_traction, t_traction, gg);
1731 auto faces_close = get_closet_face(&t_spatial_coords(0), ele_radius);
1732 for (
auto face_close : faces_close) {
1733 if (check_face(face_close, fe_id, m_field.get_comm_rank())) {
1735 auto body_id = get_body_id(face_close);
1737 auto master_face_conn = get_face_conn(face_close);
1738 std::array<double, 9> master_coords;
1741 master_coords.data());
1742 std::array<double, 9> master_traction;
1745 master_traction.data());
1746 auto t_normal_face_close = get_normal(master_coords);
1747 t_normal_face_close.normalize();
1751 CHKERR save_scal_tag(th_mark,
m, gg);
1752 CHKERR save_scal_tag(th_body_id,
static_cast<double>(body_id), gg);
1753 CHKERR save_vec_tag(th_normal, t_normal_face_close, gg);
1754 CHKERR save_vec_tag(th_contact_traction, t_traction, gg);
1758 t_unit_ray(
i) = -t_normal_face_close(
i);
1761 t_spatial_coords(
i) -
1764 constexpr double eps = 1e-3;
1765 auto [faces_out, faces_dist] =
1766 get_faces_out(&t_ray_point(0), &t_unit_ray(0),
1770 auto m = make_map(faces_out, faces_dist, t_ray_point, t_unit_ray,
1772 for (
auto m_it =
m.begin(); m_it !=
m.end(); ++m_it) {
1773 auto face = m_it->second;
1774 if (face != face_close) {
1778 (adj_fe_ids.find(get_face_id(face)) == adj_fe_ids.end() ||
1779 get_face_part(face) != m_field.get_comm_rank())
1784 shadow_vec.back().gaussPtNb = gg;
1786 auto slave_face_conn = get_face_conn(face);
1787 std::array<double, 9> slave_coords;
1790 slave_coords.data());
1791 auto t_normal_face = get_normal(slave_coords);
1792 std::array<double, 9> slave_tractions;
1795 slave_tractions.data());
1797 auto t_master_point =
1798 getFTensor1FromPtr<3>(shadow_vec.back().masterPoint.data());
1799 auto t_slave_point =
1800 getFTensor1FromPtr<3>(shadow_vec.back().slavePoint.data());
1801 auto t_ray_point_data =
1802 getFTensor1FromPtr<3>(shadow_vec.back().rayPoint.data());
1803 auto t_unit_ray_data =
1804 getFTensor1FromPtr<3>(shadow_vec.back().unitRay.data());
1806 t_slave_point(
i) = t_ray_point(
i) + m_it->first * t_unit_ray(
i);
1808 auto eval_position = [&](
auto &&t_elem_coords,
auto &&t_point) {
1809 std::array<double, 2> loc_coords;
1812 &t_elem_coords(0, 0), &t_point(0), 1,
1814 "get local coords");
1823 t_point_out(
i) = t_shape_fun(
j) * t_elem_coords(
j,
i);
1827 auto t_master_point_updated = eval_position(
1828 getFTensor2FromPtr<3, 3>(master_coords.data()),
1829 getFTensor1FromPtr<3>(shadow_vec.back().masterPoint.data()));
1830 t_master_point(
i) = t_master_point_updated(
i);
1832 auto t_slave_point_updated = eval_position(
1833 getFTensor2FromPtr<3, 3>(slave_coords.data()),
1834 getFTensor1FromPtr<3>(shadow_vec.back().slavePoint.data()));
1835 t_slave_point(
i) = t_slave_point_updated(
i);
1837 t_ray_point_data(
i) = t_ray_point(
i);
1838 t_unit_ray_data(
i) = t_unit_ray(
i);
1840 std::copy(master_coords.begin(), master_coords.end(),
1841 shadow_vec.back().masterPointNodes.begin());
1842 std::copy(master_traction.begin(), master_traction.end(),
1843 shadow_vec.back().masterTractionNodes.begin());
1844 std::copy(slave_coords.begin(), slave_coords.end(),
1845 shadow_vec.back().slavePointNodes.begin());
1846 std::copy(slave_tractions.begin(), slave_tractions.end(),
1847 shadow_vec.back().slaveTractionNodes.begin());
1849 shadow_vec.back().eleRadius = ele_radius;
1859 auto [gap, tn_master, tn_slave,
c, t_master_traction,
1861 multiGetGap(&(shadow_vec.back()), t_spatial_coords);
1863 t_gap_vec(
i) = t_slave_point(
i) - t_spatial_coords(
i);
1864 CHKERR save_scal_tag(th_gap, gap, gg);
1865 CHKERR save_scal_tag(th_tn_master, tn_master, gg);
1866 CHKERR save_scal_tag(th_tn_slave, tn_slave, gg);
1867 CHKERR save_scal_tag(th_c,
c, gg);
1869 CHKERR save_scal_tag(th_mark_slave,
m, gg);
1870 CHKERR save_vec_tag(th_dist, t_gap_vec, gg);
1871 CHKERR save_vec_tag(th_contact_traction_master,
1872 t_master_traction, gg);
1873 CHKERR save_vec_tag(th_contact_traction_slave, t_slave_traction,
1891 const std::string block_name,
int dim) {
1897 std::regex((boost::format(
"%s(.*)") % block_name).str())
1901 for (
auto bc : bcs) {
1905 "get meshset ents");
1912boost::shared_ptr<ForcesAndSourcesCore>
1915 auto &m_field = ep.
mField;
1917 boost::shared_ptr<ContactTree> fe_contact_tree;
1924 std::map<int, Range> map;
1930 (boost::format(
"%s(.*)") % name).str()
1937 m_field.get_moab(), dim, ents,
true),
1939 map[m_ptr->getMeshsetId()] = ents;
1940 MOFEM_LOG(
"EPSYNC", sev) <<
"Meshset: " << m_ptr->getMeshsetId() <<
" "
1941 << ents.size() <<
" entities";
1948 auto get_map_skin = [&](
auto &&map) {
1949 ParallelComm *pcomm =
1950 ParallelComm::get_pcomm(&m_field.get_moab(),
MYPCOMM_INDEX);
1952 Skinner skin(&m_field.get_moab());
1953 for (
auto &
m : map) {
1955 CHKERR skin.find_skin(0,
m.second,
false, skin_faces);
1957 skin_faces, PSTATUS_SHARED | PSTATUS_MULTISHARED,
1958 PSTATUS_NOT, -1,
nullptr),
1960 m.second.swap(skin_faces);
1970 auto contact_common_data_ptr = boost::make_shared<ContactOps::CommonData>();
1972 auto calcs_side_traction = [&](
auto &pip) {
1976 using SideEleOp = EleOnSide::UserDataOperator;
1979 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
1980 boost::make_shared<CGGUserPolynomialBase>(
nullptr,
true);
1981 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
1982 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
1984 op_loop_domain_side->getOpPtrVector().push_back(
1986 ep.
piolaStress, contact_common_data_ptr->contactTractionPtr(),
1987 boost::make_shared<double>(1.0)));
1988 pip.push_back(op_loop_domain_side);
1992 auto add_contact_three = [&]() {
1994 auto tree_moab_ptr = boost::make_shared<moab::Core>();
1995 fe_contact_tree = boost::make_shared<ContactTree>(
1998 fe_contact_tree->getOpPtrVector().push_back(
2000 ep.
contactDisp, contact_common_data_ptr->contactDispPtr()));
2001 CHKERR calcs_side_traction(fe_contact_tree->getOpPtrVector());
2002 auto u_h1_ptr = boost::make_shared<MatrixDouble>();
2003 fe_contact_tree->getOpPtrVector().push_back(
2005 fe_contact_tree->getOpPtrVector().push_back(
2006 new OpMoveNode(fe_contact_tree, contact_common_data_ptr, u_h1_ptr));
2010 CHKERR add_contact_three();
2017 struct exclude_sdf {
2018 exclude_sdf(
Range &&r) : map(r) {}
2019 bool operator()(
FEMethod *fe_method_ptr) {
2021 if (map.find(ent) != map.end()) {
2031 fe_contact_tree->exeTestHook =
2034 return fe_contact_tree;
2039 std::map<int, Range> map;
2044 (boost::format(
"%s(.*)") % name).str()
2053 map[m_ptr->getMeshsetId()] = ents;
2060 EshelbianCore &ep, boost::shared_ptr<ForcesAndSourcesCore> fe_ptr,
2061 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pip) {
2064 auto contact_tree_ptr = boost::dynamic_pointer_cast<ContactTree>(fe_ptr);
2066 auto &m_field = ep.
mField;
2072 using SideEleOp = EleOnSide::UserDataOperator;
2073 using BdyEleOp = BoundaryEle::UserDataOperator;
2080 auto rule_contact = [](int, int,
int o) {
return -1; };
2083 auto set_rule_contact = [refine](
2086 int order_col,
int order_data
2090 auto rule = 2 * order_data;
2095 op_loop_skeleton_side->getSideFEPtr()->getRuleHook = rule_contact;
2096 op_loop_skeleton_side->getSideFEPtr()->setRuleHook = set_rule_contact;
2098 EshelbianPlasticity::AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
2104 auto broken_data_ptr = boost::make_shared<std::vector<BrokenBaseSideData>>();
2107 auto contact_common_data_ptr = boost::make_shared<ContactOps::CommonData>();
2109 auto add_ops_domain_side = [&](
auto &pip) {
2114 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
2115 boost::make_shared<CGGUserPolynomialBase>(
nullptr,
true);
2117 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
2118 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
2120 op_loop_domain_side->getOpPtrVector().push_back(
2123 op_loop_domain_side->getOpPtrVector().push_back(
2125 ep.
piolaStress, contact_common_data_ptr->contactTractionPtr()));
2126 pip.push_back(op_loop_domain_side);
2130 auto add_ops_contact_rhs = [&](
auto &pip) {
2133 auto contact_sfd_map_range_ptr = boost::make_shared<std::map<int, Range>>(
2137 ep.
contactDisp, contact_common_data_ptr->contactDispPtr()));
2138 auto u_h1_ptr = boost::make_shared<MatrixDouble>();
2142 contact_tree_ptr, u_h1_ptr,
2143 contact_common_data_ptr->contactTractionPtr(),
2147 ep.
contactDisp, contact_common_data_ptr, contact_tree_ptr,
2148 contact_sfd_map_range_ptr));
2150 broken_data_ptr, contact_common_data_ptr, contact_tree_ptr));
2156 CHKERR add_ops_domain_side(op_loop_skeleton_side->getOpPtrVector());
2157 CHKERR add_ops_contact_rhs(op_loop_skeleton_side->getOpPtrVector());
2160 pip.push_back(op_loop_skeleton_side);
2166 EshelbianCore &ep, boost::shared_ptr<ForcesAndSourcesCore> fe_ptr,
2167 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pip) {
2170 auto contact_tree_ptr = boost::dynamic_pointer_cast<ContactTree>(fe_ptr);
2171 auto &m_field = ep.
mField;
2177 using SideEleOp = EleOnSide::UserDataOperator;
2178 using BdyEleOp = BoundaryEle::UserDataOperator;
2185 auto rule_contact = [](int, int,
int o) {
return -1; };
2188 auto set_rule_contact = [refine](
2191 int order_col,
int order_data
2195 auto rule = 2 * order_data;
2200 op_loop_skeleton_side->getSideFEPtr()->getRuleHook = rule_contact;
2201 op_loop_skeleton_side->getSideFEPtr()->setRuleHook = set_rule_contact;
2203 EshelbianPlasticity::AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
2209 auto broken_data_ptr = boost::make_shared<std::vector<BrokenBaseSideData>>();
2212 auto contact_common_data_ptr = boost::make_shared<ContactOps::CommonData>();
2214 auto add_ops_domain_side = [&](
auto &pip) {
2219 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
2220 boost::make_shared<CGGUserPolynomialBase>(
nullptr,
true);
2222 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
2223 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
2225 op_loop_domain_side->getOpPtrVector().push_back(
2228 op_loop_domain_side->getOpPtrVector().push_back(
2230 ep.
piolaStress, contact_common_data_ptr->contactTractionPtr()));
2231 pip.push_back(op_loop_domain_side);
2235 auto add_ops_contact_lhs = [&](
auto &pip) {
2238 ep.
contactDisp, contact_common_data_ptr->contactDispPtr()));
2239 auto u_h1_ptr = boost::make_shared<MatrixDouble>();
2243 contact_tree_ptr, u_h1_ptr,
2244 contact_common_data_ptr->contactTractionPtr(),
2249 auto contact_sfd_map_range_ptr = boost::make_shared<std::map<int, Range>>(
2254 contact_tree_ptr, contact_sfd_map_range_ptr));
2257 ep.
contactDisp, broken_data_ptr, contact_common_data_ptr,
2258 contact_tree_ptr, contact_sfd_map_range_ptr));
2261 broken_data_ptr, ep.
contactDisp, contact_common_data_ptr,
2268 CHKERR add_ops_domain_side(op_loop_skeleton_side->getOpPtrVector());
2269 CHKERR add_ops_contact_lhs(op_loop_skeleton_side->getOpPtrVector());
2272 pip.push_back(op_loop_skeleton_side);
2279 boost::shared_ptr<ForcesAndSourcesCore> fe_ptr,
2280 boost::shared_ptr<MatrixDouble> u_h1_ptr,
2281 boost::shared_ptr<MatrixDouble> contact_traction_ptr,
2282 Range r, moab::Interface *post_proc_mesh_ptr,
2283 std::vector<EntityHandle> *map_gauss_pts_ptr) {
2285 auto &m_field = ep.
mField;
2286 auto contact_tree_ptr = boost::dynamic_pointer_cast<ContactTree>(fe_ptr);
2288 contact_tree_ptr, u_h1_ptr, contact_traction_ptr,
2290 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)
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)
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....
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.
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.
auto getPostProcMeshPcommPtr()
std::map< EntityType, PostProcGenerateRefMeshPtr > refElementsMap
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.
BoundaryEle::UserDataOperator BdyEleOp
double zeta
Viscous hardening.