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#ifdef ENABLE_PYTHON_BINDING
53struct ContactSDFPython :
public ContactOps::SDFPython {
54 using ContactOps::SDFPython::SDFPython;
61 boost::shared_ptr<ContactSDFPython> sdf_python_ptr;
63#ifdef ENABLE_PYTHON_BINDING
65 auto file_exists = [](std::string myfile) {
66 std::ifstream file(myfile.c_str());
73 char sdf_file_name[255] =
"sdf.py";
74 PetscBool has_sdf_file_option = PETSC_FALSE;
76 sdf_file_name, 255, &has_sdf_file_option);
77 std::string sdf_file = sdf_file_name;
78 if (!has_sdf_file_option) {
79 const auto contact_surface_script =
82 if (!contact_surface_script.empty()) {
83 sdf_file = contact_surface_script;
85 <<
"Using Python script 'contact_surface' from JSON config: "
90 if (file_exists(sdf_file)) {
91 MOFEM_LOG(
"EP", Sev::inform) << sdf_file <<
" file found";
92 sdf_python_ptr = boost::make_shared<ContactSDFPython>();
93 CHKERR sdf_python_ptr->sdfInit(sdf_file);
94 ContactOps::sdfPythonWeakPtr = sdf_python_ptr;
95 MOFEM_LOG(
"EP", Sev::inform) <<
"SdfPython initialized";
97 MOFEM_LOG(
"EP", Sev::warning) << sdf_file <<
" file NOT found";
102 return sdf_python_ptr;
109 using Base::refElementsMap;
112 boost::shared_ptr<moab::Core> core_mesh_ptr,
int max_order,
113 std::map<int, Range> &&body_map);
150 using MapFaceData = std::map<EntityHandle, std::vector<FaceData>>;
154 auto it = map_face_data.find(fe_ent);
155 if (it == map_face_data.end()) {
156 return (std::vector<FaceData> *)
nullptr;
158 return &(it->second);
162 std::vector<FaceData> *vec_ptr) {
164 if (it != vec_ptr->end()) {
165 if (it->gaussPtNb == gg) {
166 face_data_ptr = &(*it);
170 return face_data_ptr;
194auto checkSdf(EntityHandle fe_ent, std::map<int, Range> &sdf_map_range) {
195 for (
auto &m_sdf : sdf_map_range) {
196 if (m_sdf.second.find(fe_ent) != m_sdf.second.end())
202template <
typename OP_PTR>
206 auto nb_gauss_pts = op_ptr->getGaussPts().size2();
208 auto ts_time = op_ptr->getTStime();
209 auto ts_time_step = op_ptr->getTStimeStep();
216 op_ptr->getFTensor1CoordsAtGaussPts(),
217 getFTensor1FromMat<3>(contact_disp), nb_gauss_pts);
219 op_ptr->getFTensor1NormalsAtGaussPts(), nb_gauss_pts);
221 ts_time_step, ts_time, nb_gauss_pts, m_spatial_coords, m_normals_at_pts,
224 ts_time_step, ts_time, nb_gauss_pts, m_spatial_coords, m_normals_at_pts,
228 if (v_sdf.size() != nb_gauss_pts)
230 "Wrong number of integration pts");
231 if (m_grad_sdf.size1() != nb_gauss_pts)
233 "Wrong number of integration pts");
234 if (m_grad_sdf.size2() != 3)
240 ts_time_step, ts_time, nb_gauss_pts, m_spatial_coords, m_normals_at_pts,
242 return std::make_tuple(block_id, m_normals_at_pts, v_sdf, m_grad_sdf,
246 return std::make_tuple(block_id, m_normals_at_pts, v_sdf, m_grad_sdf,
262template <
typename T1>
265 std::array<double, 3> &unit_ray, std::array<double, 3> &point,
267 std::array<double, 9> &elem_point_nodes,
268 std::array<double, 9> &elem_traction_nodes,
273 auto t_unit_ray = getFTensor1FromPtr<3>(unit_ray.data());
274 auto t_point = getFTensor1FromPtr<3>(point.data());
276 auto get_normal = [](
auto &ele_coords) {
282 auto t_normal = get_normal(elem_point_nodes);
283 t_normal(
i) /= t_normal.l2();
285 auto sn = t_normal(
i) * t_point(
i);
286 auto nm = t_normal(
i) * t_spatial_coords(
i);
287 auto nr = t_normal(
i) * t_unit_ray(
i);
289 auto gamma = (sn - nm) / nr;
292 t_point_current(
i) = t_spatial_coords(
i) + gamma * t_unit_ray(
i);
294 auto get_local_point_shape_functions = [&](
auto &&t_elem_coords,
296 std::array<T1, 2> loc_coords;
299 &t_elem_coords(0, 0), &t_point(0), 1, loc_coords.data()),
302 N_MBTRI1(loc_coords[0], loc_coords[1]),
303 N_MBTRI2(loc_coords[0], loc_coords[1])};
306 auto eval_position = [&](
auto &&t_field,
auto &t_shape_fun) {
310 t_point_out(
i) = t_shape_fun(
j) * t_field(
j,
i);
314 auto t_shape_fun = get_local_point_shape_functions(
315 getFTensor2FromPtr<3, 3>(elem_point_nodes.data()), t_point_current);
316 auto t_slave_point_updated = eval_position(
317 getFTensor2FromPtr<3, 3>(elem_point_nodes.data()), t_shape_fun);
318 auto t_traction_updated = eval_position(
319 getFTensor2FromPtr<3, 3>(elem_traction_nodes.data()), t_shape_fun);
321 return std::make_tuple(t_slave_point_updated, t_traction_updated, t_normal);
324template <
typename T1>
337template <
typename T1>
353template <
typename T1>
357 auto [t_slave_point_current, t_slave_traction_current, t_slave_normal] =
359 auto [t_master_point_current, t_master_traction_current, t_master_normal] =
365 t_normal(
i) = t_master_normal(
i) - t_slave_normal(
i);
368 auto gap = t_normal(
i) * (t_slave_point_current(
i) - t_spatial_coords(
i));
369 auto tn_master = t_master_traction_current(
i) * t_normal(
i);
370 auto tn_slave = t_slave_traction_current(
i) * t_normal(
i);
371 auto tn = std::max(-tn_master, tn_slave);
373 return std::make_tuple(gap, tn_master, tn_slave,
375 t_master_traction_current, t_slave_traction_current);
382template <
typename T1,
typename T2,
typename T3>
395 t_u(
i) = t_spatial_coords(
i) - t_coords(
i);
402 auto [t_slave_point_current, t_slave_traction_current, t_slave_normal] =
404 auto [t_master_point_current, t_master_traction_current, t_master_normal] =
409 t_normal(
i) = t_master_normal(
i) - t_slave_normal(
i);
414 t_P(
i,
j) = t_normal(
i) * t_normal(
j);
416 t_Q(
i,
j) = kronecker_delta(
i,
j) - t_P(
i,
j);
418 constexpr double beta = 0.5;
425 auto f_min_gap = [
zeta](
auto d,
auto s) {
426 return 0.5 * (d + s - std::sqrt((d - s) * (d - s) +
zeta));
429 auto f_diff_min_gap = [
zeta](
auto d,
auto s) {
430 return 0.5 * (1 - (d - s) / std::sqrt((d - s) * (d - s) +
zeta));
434 auto f_barrier = [alpha1, alpha2, f_min_gap, f_diff_min_gap](
auto g,
438 0.5 * (tn + f_min_gap(d, tn) + f_diff_min_gap(d, tn) * (d - tn));
439 auto b2 = alpha2 * f_min_gap(
g, 0) *
g;
444 t_gap_vec(
i) = beta * t_spatial_coords(
i) +
445 (1 - beta) * t_slave_point_current(
i) - t_spatial_coords(
i);
448 -beta * t_master_traction(
i) + (beta - 1) * t_slave_traction_current(
i);
450 auto t_gap = t_normal(
i) * t_gap_vec(
i);
451 auto t_tn = t_normal(
i) * t_traction_vec(
i);
452 auto barrier = f_barrier(t_gap, t_tn);
456 t_traction_bar(
i) = t_normal(
i) * barrier;
460 t_Q(
i,
j) * t_master_traction(
j) +
462 t_P(
i,
j) * (t_master_traction(
j) - t_traction_bar(
j));
465 auto is_nan_or_inf = [](
double value) ->
bool {
466 return std::isnan(value) || std::isinf(value);
469 double v = std::complex<double>(t_rhs(
i) * t_rhs(
i)).real();
470 if (is_nan_or_inf(
v)) {
472 MOFEM_LOG(
"SELF", Sev::error) <<
"t_rhs " << t_rhs;
488 const std::string row_field_name,
489 boost::shared_ptr<ContactOps::CommonData> common_data_ptr,
490 boost::shared_ptr<ContactTree> contact_tree_ptr,
491 boost::shared_ptr<std::map<int, Range>> sdf_map_range_ptr =
nullptr);
502 const std::string row_field_name,
503 boost::shared_ptr<ContactOps::CommonData> common_data_ptr,
504 boost::shared_ptr<ContactTree> contact_tree_ptr,
505 boost::shared_ptr<std::map<int, Range>> sdf_map_range_ptr)
508 commonDataPtr(common_data_ptr), contactTreePtr(contact_tree_ptr),
509 sdfMapRangePtr(sdf_map_range_ptr) {
518 "get alpha contact failed");
520 PETSC_NULLPTR,
"",
"-alpha_contact_quadratic",
522 "get alpha contact failed");
526 "get alpha contact failed");
546 const size_t nb_gauss_pts = getGaussPts().size2();
551 "Wrong number of integration pts %ld != %ld",
559 auto t_w = getFTensor0IntegrationWeight();
560 auto t_coords = getFTensor1CoordsAtGaussPts();
561 auto t_disp = getFTensor1FromMat<3>(
commonDataPtr->contactDisp);
562 auto t_traction = getFTensor1FromMat<3>(
commonDataPtr->contactTraction);
567 auto [block_id, m_normals_at_pts, v_sdf, m_grad_sdf, m_hess_sdf] =
572 auto t_grad_sdf_v = getFTensor1FromMat<3>(m_grad_sdf);
573 auto t_normalize_normal = getFTensor1FromMat<3>(m_normals_at_pts);
580 ++t_normalize_normal;
585 auto face_data_vec_ptr =
587 auto face_gauss_pts_it = face_data_vec_ptr->begin();
589 auto nb_base_functions = data.
getN().size2();
591 for (
auto gg = 0; gg != nb_gauss_pts; ++gg) {
594 auto face_data_ptr =
contactTreePtr->getFaceDataPtr(face_gauss_pts_it, gg,
597 auto check_face_contact = [&]() {
607#ifdef ENABLE_PYTHON_BINDING
609 if (ContactOps::sdfPythonWeakPtr.lock()) {
610 auto tn = t_traction(
i) * t_grad_sdf_v(
i);
614 constexpr double c = 0;
617 if (!
c && check_face_contact()) {
619 t_spatial_coords(
i) = t_coords(
i) + t_disp(
i);
620 auto t_rhs_tmp =
multiPointRhs(face_data_ptr, t_coords, t_spatial_coords,
622 t_rhs(
i) = t_rhs_tmp(
i);
626#ifdef ENABLE_PYTHON_BINDING
629 if (ContactOps::sdfPythonWeakPtr.lock()) {
631 t_cP(
i,
j) = (
c * t_grad_sdf_v(
i)) * t_grad_sdf_v(
j);
632 t_cQ(
i,
j) = kronecker_delta(
i,
j) - t_cP(
i,
j);
633 t_rhs(
i) = t_cQ(
i,
j) * t_traction(
j) +
634 (
c * inv_cn * t_sdf_v) * t_grad_sdf_v(
i);
636 t_rhs(
i) = t_traction(
i);
639 t_rhs(
i) = t_traction(
i);
643 auto t_nf = getFTensor1FromPtr<3>(&nf[0]);
644 const double alpha = t_w * getMeasure();
647 for (; bb != nbRows / 3; ++bb) {
648 const double beta = alpha * t_base;
649 t_nf(
i) -= beta * t_rhs(
i);
653 for (; bb < nb_base_functions; ++bb)
664template <AssemblyType A>
672 boost::shared_ptr<std::vector<BrokenBaseSideData>> broken_base_side_data,
673 boost::shared_ptr<ContactOps::CommonData> common_data_ptr,
674 boost::shared_ptr<ContactTree> contact_tree_ptr);
683template <AssemblyType A>
686 boost::shared_ptr<std::vector<BrokenBaseSideData>>
687 broken_base_side_data,
688 boost::shared_ptr<ContactOps::CommonData> common_data_ptr,
689 boost::shared_ptr<ContactTree> contact_tree_ptr)
690 :
OP(broken_base_side_data), commonDataPtr(common_data_ptr),
691 contactTreePtr(contact_tree_ptr) {}
693template <AssemblyType A>
703 const size_t nb_gauss_pts = OP::getGaussPts().size2();
706 if (commonDataPtr->contactDisp.size1() != nb_gauss_pts) {
708 "Wrong number of integration pts %ld != %ld",
709 commonDataPtr->contactDisp.size1(), nb_gauss_pts);
716 auto t_w = OP::getFTensor0IntegrationWeight();
717 auto t_material_normal = OP::getFTensor1NormalsAtGaussPts();
718 auto t_coords = OP::getFTensor1CoordsAtGaussPts();
720 auto t_disp = getFTensor1FromMat<3>(commonDataPtr->contactDisp);
721 auto t_traction = getFTensor1FromMat<3>(commonDataPtr->contactTraction);
731 auto nb_base_functions = data.
getN().size2() / 3;
733 for (
auto gg = 0; gg != nb_gauss_pts; ++gg) {
735 auto t_nf = getFTensor1FromPtr<3>(&nf[0]);
736 const double alpha = t_w / 2.;
739 for (; bb != OP::nbRows / 3; ++bb) {
740 const double beta = alpha * t_base(
i) * t_material_normal(
i);
741 t_nf(
i) += beta * t_disp(
i);
745 for (; bb < nb_base_functions; ++bb)
757 const std::string row_field_name,
const std::string col_field_name,
758 boost::shared_ptr<ContactOps::CommonData> common_data_ptr,
759 boost::shared_ptr<ContactTree> contact_tree_ptr,
760 boost::shared_ptr<std::map<int, Range>> sdf_map_range_ptr =
nullptr);
772 const std::string row_field_name,
const std::string col_field_name,
773 boost::shared_ptr<ContactOps::CommonData> common_data_ptr,
774 boost::shared_ptr<ContactTree> contact_tree_ptr,
775 boost::shared_ptr<std::map<int, Range>> sdf_map_range_ptr)
778 commonDataPtr(common_data_ptr), contactTreePtr(contact_tree_ptr),
779 sdfMapRangePtr(sdf_map_range_ptr) {
798 auto &locMat = AssemblyBoundaryEleOp::locMat;
799 locMat.resize(nb_rows, nb_cols,
false);
802 if (nb_cols && nb_rows) {
804 auto nb_gauss_pts = getGaussPts().size2();
805 auto t_w = getFTensor0IntegrationWeight();
806 auto t_coords = getFTensor1CoordsAtGaussPts();
807 auto t_disp = getFTensor1FromMat<3>(
commonDataPtr->contactDisp);
808 auto t_traction = getFTensor1FromMat<3>(
commonDataPtr->contactTraction);
811 auto [block_id, m_normals_at_pts, v_sdf, m_grad_sdf, m_hess_sdf] =
816 auto t_grad_sdf_v = getFTensor1FromMat<3>(m_grad_sdf);
817 auto t_hess_sdf_v = getFTensor2SymmetricFromMat<3>(m_hess_sdf);
818 auto t_normalized_normal = getFTensor1FromMat<3>(m_normals_at_pts);
828 ++t_normalized_normal;
831 auto face_data_vec_ptr =
833 auto face_gauss_pts_it = face_data_vec_ptr->begin();
836 auto nb_face_functions = row_data.
getN().size2() / 3;
837 for (
size_t gg = 0; gg != nb_gauss_pts; ++gg) {
839 auto face_data_ptr =
contactTreePtr->getFaceDataPtr(face_gauss_pts_it, gg,
842 auto check_face_contact = [&]() {
854#ifdef ENABLE_PYTHON_BINDING
856 if (ContactOps::sdfPythonWeakPtr.lock()) {
857 auto tn = t_traction(
i) * t_grad_sdf_v(
i);
861 constexpr double c = 0;
864 if (!
c && check_face_contact()) {
866 t_spatial_coords(
i) = t_coords(
i) + t_disp(
i);
867 constexpr double eps = std::numeric_limits<float>::epsilon();
868 for (
auto ii = 0; ii < 3; ++ii) {
870 t_spatial_coords(0), t_spatial_coords(1), t_spatial_coords(2)};
871 t_spatial_coords_cx(ii) +=
eps * 1
i;
875 for (
int jj = 0; jj != 3; ++jj) {
876 auto v = t_rhs_tmp(jj).imag();
877 t_res_dU(jj, ii) =
v /
eps;
883#ifdef ENABLE_PYTHON_BINDING
885 if (ContactOps::sdfPythonWeakPtr.lock()) {
889 (-
c) * (t_hess_sdf_v(
i,
j) * t_grad_sdf_v(
k) * t_traction(
k) +
890 t_grad_sdf_v(
i) * t_hess_sdf_v(
k,
j) * t_traction(
k))
892 + (
c * inv_cn) * (t_sdf_v * t_hess_sdf_v(
i,
j) +
894 t_grad_sdf_v(
j) * t_grad_sdf_v(
i));
903 auto alpha = t_w * getMeasure();
906 for (; rr != nb_rows / 3; ++rr) {
908 auto t_mat = getFTensor2FromArray<3, 3, 3>(locMat, 3 * rr);
911 for (
size_t cc = 0; cc != nb_cols / 3; ++cc) {
912 auto beta = alpha * t_row_base * t_col_base;
913 t_mat(
i,
j) -= beta * t_res_dU(
i,
j);
920 for (; rr < nb_face_functions; ++rr)
932template <AssemblyType A>
940 std::string row_field_name,
941 boost::shared_ptr<std::vector<BrokenBaseSideData>> broken_base_side_data,
942 boost::shared_ptr<ContactOps::CommonData> common_data_ptr,
943 boost::shared_ptr<ContactTree> contact_tree_ptr,
944 boost::shared_ptr<std::map<int, Range>> sdf_map_range_ptr =
nullptr);
955template <AssemblyType A>
958 std::string row_field_name,
959 boost::shared_ptr<std::vector<BrokenBaseSideData>>
960 broken_base_side_data,
961 boost::shared_ptr<ContactOps::CommonData> common_data_ptr,
962 boost::shared_ptr<ContactTree> contact_tree_ptr,
963 boost::shared_ptr<std::map<int, Range>> sdf_map_range_ptr)
964 :
OP(row_field_name, broken_base_side_data, false, false),
965 commonDataPtr(common_data_ptr), contactTreePtr(contact_tree_ptr),
966 sdfMapRangePtr(sdf_map_range_ptr) {
970template <AssemblyType A>
986 auto &locMat = AssemblyBoundaryEleOp::locMat;
987 locMat.resize(nb_rows, nb_cols,
false);
990 if (nb_cols && nb_rows) {
992 const size_t nb_gauss_pts = OP::getGaussPts().size2();
994 auto t_w = OP::getFTensor0IntegrationWeight();
995 auto t_disp = getFTensor1FromMat<3>(commonDataPtr->contactDisp);
996 auto t_traction = getFTensor1FromMat<3>(commonDataPtr->contactTraction);
997 auto t_coords = OP::getFTensor1CoordsAtGaussPts();
998 auto t_material_normal = OP::getFTensor1NormalsAtGaussPts();
1001 auto [block_id, m_normals_at_pts, v_sdf, m_grad_sdf, m_hess_sdf] =
1002 getSdf(
this, commonDataPtr->contactDisp,
1003 checkSdf(OP::getFEEntityHandle(), *sdfMapRangePtr),
false);
1006 auto t_grad_sdf_v = getFTensor1FromMat<3>(m_grad_sdf);
1013 ++t_material_normal;
1018 auto face_data_vec_ptr =
1019 contactTreePtr->findFaceDataVecPtr(OP::getFEEntityHandle());
1020 auto face_gauss_pts_it = face_data_vec_ptr->begin();
1023 auto nb_face_functions = row_data.
getN().size2();
1027 for (
size_t gg = 0; gg != nb_gauss_pts; ++gg) {
1029 auto face_data_ptr = contactTreePtr->getFaceDataPtr(face_gauss_pts_it, gg,
1032 auto check_face_contact = [&]() {
1033 if (
checkSdf(OP::getFEEntityHandle(), *sdfMapRangePtr) != -1)
1036 if (face_data_ptr) {
1044#ifdef ENABLE_PYTHON_BINDING
1046 if (ContactOps::sdfPythonWeakPtr.lock()) {
1047 auto tn = t_traction(
i) * t_grad_sdf_v(
i);
1051 constexpr double c = 0;
1054 if (!
c && check_face_contact()) {
1056 t_spatial_coords(
i) = t_coords(
i) + t_disp(
i);
1057 constexpr double eps = std::numeric_limits<float>::epsilon();
1058 for (
auto ii = 0; ii != 3; ++ii) {
1060 t_traction(0), t_traction(1), t_traction(2)};
1061 t_traction_cx(ii) +=
eps * 1
i;
1065 for (
int jj = 0; jj != 3; ++jj) {
1066 auto v = t_rhs_tmp(jj).imag();
1067 t_res_dP(jj, ii) =
v /
eps;
1072#ifdef ENABLE_PYTHON_BINDING
1073 if (ContactOps::sdfPythonWeakPtr.lock()) {
1075 t_cP(
i,
j) = (
c * t_grad_sdf_v(
i)) * t_grad_sdf_v(
j);
1076 t_cQ(
i,
j) = kronecker_delta(
i,
j) - t_cP(
i,
j);
1077 t_res_dP(
i,
j) = t_cQ(
i,
j);
1086 const double alpha = t_w / 2.;
1088 for (; rr != nb_rows / 3; ++rr) {
1090 auto t_mat = getFTensor2FromArray<3, 3, 3>(locMat, 3 * rr);
1093 for (
size_t cc = 0; cc != nb_cols / 3; ++cc) {
1094 auto col_base = t_col_base(
i) * t_material_normal(
i);
1095 const double beta = alpha * t_row_base * col_base;
1096 t_mat(
i,
j) -= beta * t_res_dP(
i,
j);
1103 for (; rr < nb_face_functions; ++rr)
1113template <AssemblyType A, IntegrationType I>
1116template <AssemblyType A>
1124 boost::shared_ptr<std::vector<BrokenBaseSideData>> broken_base_side_data,
1125 std::string col_field_name,
1126 boost::shared_ptr<ContactOps::CommonData> common_data_ptr,
1127 boost::shared_ptr<ContactTree> contact_tree_ptr);
1137template <AssemblyType A>
1140 boost::shared_ptr<std::vector<BrokenBaseSideData>>
1141 broken_base_side_data,
1142 std::string col_field_name,
1143 boost::shared_ptr<ContactOps::CommonData> common_data_ptr,
1144 boost::shared_ptr<ContactTree> contact_tree_ptr)
1145 :
OP(col_field_name, broken_base_side_data, true, true),
1146 commonDataPtr(common_data_ptr), contactTreePtr(contact_tree_ptr) {
1150template <AssemblyType A>
1169 auto &locMat = AssemblyBoundaryEleOp::locMat;
1170 locMat.resize(nb_rows, nb_cols,
false);
1173 if (nb_cols && nb_rows) {
1175 const size_t nb_gauss_pts = OP::getGaussPts().size2();
1177 auto t_w = OP::getFTensor0IntegrationWeight();
1178 auto t_disp = getFTensor1FromMat<3>(commonDataPtr->contactDisp);
1179 auto t_traction = getFTensor1FromMat<3>(commonDataPtr->contactTraction);
1180 auto t_coords = OP::getFTensor1CoordsAtGaussPts();
1181 auto t_material_normal = OP::getFTensor1NormalsAtGaussPts();
1188 ++t_material_normal;
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());
1291 CHKERR Base::preProcess();
1298 CHKERR Base::postProcess();
1301 PetscBarrier(
nullptr);
1304 if (pcomm_post_proc_mesh ==
nullptr)
1307 auto brodacts = [&](
auto &brodacts_ents) {
1311 pcomm_post_proc_mesh->broadcast_entities(
1318 Range brodacts_ents;
1320 CHKERR brodacts(brodacts_ents);
1339 treeSurfPtr = boost::shared_ptr<OrientedBoxTreeTool>(
1350 OpMoveNode(boost::shared_ptr<ContactTree> contact_tree_ptr,
1351 boost::shared_ptr<ContactOps::CommonData> common_data_ptr,
1352 boost::shared_ptr<MatrixDouble> u_h1_ptr);
1363 boost::shared_ptr<ContactTree> contact_tree_ptr,
1364 boost::shared_ptr<ContactOps::CommonData> common_data_ptr,
1365 boost::shared_ptr<MatrixDouble> u_h1_ptr)
1366 :
UOP(
NOSPACE,
UOP::OPSPACE), contactTreePtr(contact_tree_ptr),
1367 uH1Ptr(u_h1_ptr), commonDataPtr(common_data_ptr) {}
1375 auto get_body_id = [&](
auto fe_ent) {
1376 for (
auto &
m : contact_tree_ptr->bodyMap) {
1377 if (
m.second.find(fe_ent) !=
m.second.end()) {
1384 auto &moab_post_proc_mesh = contact_tree_ptr->getPostProcMesh();
1385 auto &post_proc_ents = contact_tree_ptr->getPostProcElements();
1387 auto fe_ent = getNumeredEntFiniteElementPtr()->getEnt();
1389 auto body_id = get_body_id(fe_ent);
1390 auto &map_gauss_pts = contact_tree_ptr->getMapGaussPts();
1392 CHKERR moab_post_proc_mesh.tag_clear_data(contact_tree_ptr->thEleId,
1393 post_proc_ents, &fe_id);
1394 CHKERR moab_post_proc_mesh.tag_clear_data(contact_tree_ptr->thBodyId,
1395 post_proc_ents, &body_id);
1397 auto nb_gauss_pts = getGaussPts().size2();
1398 auto t_u_h1 = getFTensor1FromMat<3>(*
uH1Ptr);
1399 auto t_u_l2 = getFTensor1FromMat<3>(
commonDataPtr->contactDisp);
1400 auto t_coords = getFTensor1CoordsAtGaussPts();
1403 auto t_x_h1 = getFTensor1FromPtr<3>(&x_h1(0, 0));
1405 auto t_x_l2 = getFTensor1FromPtr<3>(&x_l2(0, 0));
1412 for (
auto gg = 0; gg != nb_gauss_pts; ++gg) {
1413 t_x_h1(
i) = t_coords(
i) + t_u_h1(
i);
1414 t_x_l2(
i) = t_coords(
i) + t_u_l2(
i);
1423 CHKERR moab_post_proc_mesh.set_coords(
1424 &*map_gauss_pts.begin(), map_gauss_pts.size(), &*x_h1.data().begin());
1425 CHKERR moab_post_proc_mesh.tag_set_data(
1426 contact_tree_ptr->thSmallX, &*map_gauss_pts.begin(),
1427 map_gauss_pts.size(), &*x_h1.data().begin());
1428 CHKERR moab_post_proc_mesh.tag_set_data(
1429 contact_tree_ptr->thLargeX, &*map_gauss_pts.begin(),
1430 map_gauss_pts.size(), &*coords.data().begin());
1431 CHKERR moab_post_proc_mesh.tag_set_data(
1432 contact_tree_ptr->thTraction, &*map_gauss_pts.begin(),
1433 map_gauss_pts.size(), &*tractions.data().begin());
1437 "ContactTree pointer expired in OpMoveNode");
1447 OpTreeSearch(boost::shared_ptr<ContactTree> contact_tree_ptr,
1448 boost::shared_ptr<MatrixDouble> u_h1_ptr,
1449 boost::shared_ptr<MatrixDouble> traction_ptr,
Range r,
1451 moab::Interface *post_proc_mesh_ptr,
1452 std::vector<EntityHandle> *map_gauss_pts_ptr
1469 boost::shared_ptr<MatrixDouble> u_h1_ptr,
1470 boost::shared_ptr<MatrixDouble> traction_ptr,
1473 moab::Interface *post_proc_mesh_ptr,
1474 std::vector<EntityHandle> *map_gauss_pts_ptr
1477 :
UOP(
NOSPACE,
UOP::OPSPACE), contactTreePtr(contact_tree_ptr),
1478 uH1Ptr(u_h1_ptr), tractionPtr(traction_ptr),
1479 postProcMeshPtr(post_proc_mesh_ptr), mapGaussPtsPtr(map_gauss_pts_ptr),
1486 auto &m_field = getPtrFE()->mField;
1487 auto fe_ent = getNumeredEntFiniteElementPtr()->getEnt();
1496 const auto nb_gauss_pts = getGaussPts().size2();
1498 auto t_disp_h1 = getFTensor1FromMat<3>(*
uH1Ptr);
1499 auto t_coords = getFTensor1CoordsAtGaussPts();
1500 auto t_traction = getFTensor1FromMat<3>(*
tractionPtr);
1508 auto get_ele_centre = [
i](
auto t_ele_coords) {
1510 t_ele_center(
i) = 0;
1511 for (
int nn = 0; nn != 3; nn++) {
1512 t_ele_center(
i) += t_ele_coords(
i);
1515 t_ele_center(
i) /= 3;
1516 return t_ele_center;
1519 auto get_ele_radius = [
i](
auto t_ele_center,
auto t_ele_coords) {
1521 t_n0(
i) = t_ele_center(
i) - t_ele_coords(
i);
1525 auto get_face_conn = [
this](
auto face) {
1526 const EntityHandle *conn;
1529 face, conn, num_nodes,
true),
1531 if (num_nodes != 3) {
1537 auto get_face_coords = [
this](
auto conn) {
1538 std::array<double, 9> coords;
1543 auto get_closet_face = [
this](
auto *point_ptr,
auto r) {
1545 std::vector<EntityHandle> faces_out;
1549 "get closest faces");
1553 auto get_faces_out = [
this](
auto *point_ptr,
auto *unit_ray_ptr,
auto radius,
1555 std::vector<double> distances_out;
1556 std::vector<EntityHandle> faces_out;
1561 point_ptr, unit_ray_ptr, &radius),
1563 "get closest faces");
1564 return std::make_pair(faces_out, distances_out);
1567 auto get_normal = [](
auto &ele_coords) {
1573 auto make_map = [&](
auto &face_out,
auto &face_dist,
auto &t_ray_point,
1574 auto &t_unit_ray,
auto &t_master_coord) {
1577 std::map<double, EntityHandle>
m;
1578 for (
auto ii = 0; ii != face_out.size(); ++ii) {
1579 auto face_conn = get_face_conn(face_out[ii]);
1582 t_face_normal.normalize();
1584 t_x(
i) = t_ray_point(
i) + t_unit_ray(
i) * face_dist[ii];
1587 t_x(
i) * t_face_normal(
j) - t_master_coord(
i) * t_unit_ray(
j);
1588 if (t_unit_ray(
i) * t_face_normal(
i) > std::cos(M_PI / 3)) {
1589 auto dot = std::sqrt(t_chi(
i,
j) * t_chi(
i,
j));
1590 m[dot] = face_out[ii];
1596 auto create_tag = [
this](
const std::string tag_name,
const int size) {
1597 double def_VAL[] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
1601 tag_name.c_str(), size, MB_TYPE_DOUBLE,
th,
1602 MB_TAG_CREAT | MB_TAG_SPARSE, def_VAL);
1609 auto set_float_precision = [](
const double x) {
1610 if (std::abs(x) < std::numeric_limits<float>::epsilon())
1617 auto save_scal_tag = [&](
auto &
th,
auto v,
const int gg) {
1620 v = set_float_precision(
v);
1627 auto get_fe_adjacencies = [
this](
auto fe_ent) {
1630 &fe_ent, 1, 2,
false, adj_faces, moab::Interface::UNION),
1632 std::set<int> adj_ids;
1633 for (
auto f : adj_faces) {
1639 auto get_face_id = [
this](
auto face) {
1648 auto get_body_id = [
this](
auto face) {
1657 auto get_face_part = [
this](
auto face) {
1658 const moab::Core *core_mesh_ptr =
1659 dynamic_cast<const moab::Core *
>(&
contactTreePtr->getPostProcMesh());
1660 auto pcomm_post_proc_mesh =
1664 pcomm_post_proc_mesh->part_tag(), &face, 1, &part) == MB_SUCCESS) {
1670 auto check_face = [&](
auto face,
auto fe_id,
auto part) {
1671 auto face_id = get_face_id(face);
1672 auto face_part = get_face_part(face);
1673 if (face_id == fe_id && face_part == part)
1681 auto save_vec_tag = [&](
auto &
th,
auto &t_d,
const int gg) {
1685 for (
auto &
a :
v.data())
1686 a = set_float_precision(
a);
1688 &*
v.data().begin());
1693 Tag th_mark = create_tag(
"contact_mark", 1);
1694 Tag th_mark_slave = create_tag(
"contact_mark_slave", 1);
1695 Tag th_body_id = create_tag(
"contact_body_id", 1);
1696 Tag th_gap = create_tag(
"contact_gap", 1);
1697 Tag th_tn_master = create_tag(
"contact_tn_master", 1);
1698 Tag th_tn_slave = create_tag(
"contact_tn_slave", 1);
1699 Tag th_contact_traction = create_tag(
"contact_traction", 3);
1700 Tag th_contact_traction_master = create_tag(
"contact_traction_master", 3);
1701 Tag th_contact_traction_slave = create_tag(
"contact_traction_slave", 3);
1702 Tag th_c = create_tag(
"contact_c", 1);
1703 Tag th_normal = create_tag(
"contact_normal", 3);
1704 Tag th_dist = create_tag(
"contact_dip", 3);
1706 auto t_ele_centre = get_ele_centre(getFTensor1Coords());
1707 auto ele_radius = get_ele_radius(t_ele_centre, getFTensor1Coords());
1713 auto adj_fe_ids = get_fe_adjacencies(fe_ent);
1715 for (
auto gg = 0; gg != nb_gauss_pts; ++gg) {
1718 t_spatial_coords(
i) = t_coords(
i) + t_disp_h1(
i);
1721 CHKERR save_vec_tag(th_contact_traction, t_traction, gg);
1724 auto faces_close = get_closet_face(&t_spatial_coords(0), ele_radius);
1725 for (
auto face_close : faces_close) {
1726 if (check_face(face_close, fe_id, m_field.get_comm_rank())) {
1728 auto body_id = get_body_id(face_close);
1730 auto master_face_conn = get_face_conn(face_close);
1731 std::array<double, 9> master_coords;
1734 master_coords.data());
1735 std::array<double, 9> master_traction;
1738 master_traction.data());
1739 auto t_normal_face_close = get_normal(master_coords);
1740 t_normal_face_close.normalize();
1744 CHKERR save_scal_tag(th_mark,
m, gg);
1745 CHKERR save_scal_tag(th_body_id,
static_cast<double>(body_id), gg);
1746 CHKERR save_vec_tag(th_normal, t_normal_face_close, gg);
1747 CHKERR save_vec_tag(th_contact_traction, t_traction, gg);
1751 t_unit_ray(
i) = -t_normal_face_close(
i);
1754 t_spatial_coords(
i) -
1757 constexpr double eps = 1e-3;
1758 auto [faces_out, faces_dist] =
1759 get_faces_out(&t_ray_point(0), &t_unit_ray(0),
1763 auto m = make_map(faces_out, faces_dist, t_ray_point, t_unit_ray,
1765 for (
auto m_it =
m.begin(); m_it !=
m.end(); ++m_it) {
1766 auto face = m_it->second;
1767 if (face != face_close) {
1771 (adj_fe_ids.find(get_face_id(face)) == adj_fe_ids.end() ||
1772 get_face_part(face) != m_field.get_comm_rank())
1777 shadow_vec.back().gaussPtNb = gg;
1779 auto slave_face_conn = get_face_conn(face);
1780 std::array<double, 9> slave_coords;
1783 slave_coords.data());
1784 std::array<double, 9> slave_tractions;
1787 slave_tractions.data());
1789 auto t_master_point =
1790 getFTensor1FromPtr<3>(shadow_vec.back().masterPoint.data());
1791 auto t_slave_point =
1792 getFTensor1FromPtr<3>(shadow_vec.back().slavePoint.data());
1793 auto t_ray_point_data =
1794 getFTensor1FromPtr<3>(shadow_vec.back().rayPoint.data());
1795 auto t_unit_ray_data =
1796 getFTensor1FromPtr<3>(shadow_vec.back().unitRay.data());
1798 t_slave_point(
i) = t_ray_point(
i) + m_it->first * t_unit_ray(
i);
1800 auto eval_position = [&](
auto &&t_elem_coords,
auto &&t_point) {
1801 std::array<double, 2> loc_coords;
1804 &t_elem_coords(0, 0), &t_point(0), 1,
1806 "get local coords");
1815 t_point_out(
i) = t_shape_fun(
j) * t_elem_coords(
j,
i);
1819 auto t_master_point_updated = eval_position(
1820 getFTensor2FromPtr<3, 3>(master_coords.data()),
1821 getFTensor1FromPtr<3>(shadow_vec.back().masterPoint.data()));
1822 t_master_point(
i) = t_master_point_updated(
i);
1824 auto t_slave_point_updated = eval_position(
1825 getFTensor2FromPtr<3, 3>(slave_coords.data()),
1826 getFTensor1FromPtr<3>(shadow_vec.back().slavePoint.data()));
1827 t_slave_point(
i) = t_slave_point_updated(
i);
1829 t_ray_point_data(
i) = t_ray_point(
i);
1830 t_unit_ray_data(
i) = t_unit_ray(
i);
1832 std::copy(master_coords.begin(), master_coords.end(),
1833 shadow_vec.back().masterPointNodes.begin());
1834 std::copy(master_traction.begin(), master_traction.end(),
1835 shadow_vec.back().masterTractionNodes.begin());
1836 std::copy(slave_coords.begin(), slave_coords.end(),
1837 shadow_vec.back().slavePointNodes.begin());
1838 std::copy(slave_tractions.begin(), slave_tractions.end(),
1839 shadow_vec.back().slaveTractionNodes.begin());
1841 shadow_vec.back().eleRadius = ele_radius;
1851 auto [gap, tn_master, tn_slave,
c, t_master_traction,
1853 multiGetGap(&(shadow_vec.back()), t_spatial_coords);
1855 t_gap_vec(
i) = t_slave_point(
i) - t_spatial_coords(
i);
1856 CHKERR save_scal_tag(th_gap, gap, gg);
1857 CHKERR save_scal_tag(th_tn_master, tn_master, gg);
1858 CHKERR save_scal_tag(th_tn_slave, tn_slave, gg);
1859 CHKERR save_scal_tag(th_c,
c, gg);
1861 CHKERR save_scal_tag(th_mark_slave,
m, gg);
1862 CHKERR save_vec_tag(th_dist, t_gap_vec, gg);
1863 CHKERR save_vec_tag(th_contact_traction_master,
1864 t_master_traction, gg);
1865 CHKERR save_vec_tag(th_contact_traction_slave, t_slave_traction,
1883 const std::string block_name,
int dim) {
1889 std::regex((boost::format(
"%s(.*)") % block_name).str())
1893 for (
auto bc : bcs) {
1897 "get meshset ents");
1904boost::shared_ptr<ForcesAndSourcesCore>
1907 auto &m_field = ep.
mField;
1909 boost::shared_ptr<ContactTree> fe_contact_tree;
1916 std::map<int, Range> map;
1922 (boost::format(
"%s(.*)") % name).str()
1929 m_field.get_moab(), dim, ents,
true),
1931 map[m_ptr->getMeshsetId()] = ents;
1932 MOFEM_LOG(
"EPSYNC", sev) <<
"Meshset: " << m_ptr->getMeshsetId() <<
" "
1933 << ents.size() <<
" entities";
1945 auto contact_common_data_ptr = boost::make_shared<ContactOps::CommonData>();
1947 auto calcs_side_traction = [&](
auto &pip) {
1951 using SideEleOp = EleOnSide::UserDataOperator;
1954 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
1955 boost::make_shared<CGGUserPolynomialBase>(
nullptr,
true);
1956 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
1957 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
1959 op_loop_domain_side->getOpPtrVector().push_back(
1961 ep.
piolaStress, contact_common_data_ptr->contactTractionPtr(),
1962 boost::make_shared<double>(1.0)));
1963 pip.push_back(op_loop_domain_side);
1967 auto add_contact_three = [&]() {
1969 auto tree_moab_ptr = boost::make_shared<moab::Core>();
1970 fe_contact_tree = boost::make_shared<ContactTree>(
1973 fe_contact_tree->getOpPtrVector().push_back(
1975 ep.
contactDisp, contact_common_data_ptr->contactDispPtr()));
1976 CHKERR calcs_side_traction(fe_contact_tree->getOpPtrVector());
1977 auto u_h1_ptr = boost::make_shared<MatrixDouble>();
1978 fe_contact_tree->getOpPtrVector().push_back(
1980 fe_contact_tree->getOpPtrVector().push_back(
1981 new OpMoveNode(fe_contact_tree, contact_common_data_ptr, u_h1_ptr));
1985 CHKERR add_contact_three();
1992 struct exclude_sdf {
1993 exclude_sdf(
Range &&r) : map(r) {}
1994 bool operator()(
FEMethod *fe_method_ptr) {
1996 if (map.find(ent) != map.end()) {
2006 fe_contact_tree->exeTestHook =
2009 return fe_contact_tree;
2014 std::map<int, Range> map;
2019 (boost::format(
"%s(.*)") % name).str()
2028 map[m_ptr->getMeshsetId()] = ents;
2035 EshelbianCore &ep, boost::shared_ptr<ForcesAndSourcesCore> fe_ptr,
2036 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pip) {
2039 auto contact_tree_ptr = boost::dynamic_pointer_cast<ContactTree>(fe_ptr);
2041 auto &m_field = ep.
mField;
2047 using SideEleOp = EleOnSide::UserDataOperator;
2048 using BdyEleOp = BoundaryEle::UserDataOperator;
2055 auto rule_contact = [](int, int,
int o) {
return -1; };
2058 auto set_rule_contact = [refine](
2061 int order_col,
int order_data
2065 auto rule = 2 * order_data;
2070 op_loop_skeleton_side->getSideFEPtr()->getRuleHook = rule_contact;
2071 op_loop_skeleton_side->getSideFEPtr()->setRuleHook = set_rule_contact;
2073 EshelbianPlasticity::AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
2079 auto broken_data_ptr = boost::make_shared<std::vector<BrokenBaseSideData>>();
2082 auto contact_common_data_ptr = boost::make_shared<ContactOps::CommonData>();
2084 auto add_ops_domain_side = [&](
auto &pip) {
2089 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
2090 boost::make_shared<CGGUserPolynomialBase>(
nullptr,
true);
2092 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
2093 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
2095 op_loop_domain_side->getOpPtrVector().push_back(
2098 op_loop_domain_side->getOpPtrVector().push_back(
2100 ep.
piolaStress, contact_common_data_ptr->contactTractionPtr()));
2101 pip.push_back(op_loop_domain_side);
2105 auto add_ops_contact_rhs = [&](
auto &pip) {
2108 auto contact_sfd_map_range_ptr = boost::make_shared<std::map<int, Range>>(
2112 ep.
contactDisp, contact_common_data_ptr->contactDispPtr()));
2113 auto u_h1_ptr = boost::make_shared<MatrixDouble>();
2117 contact_tree_ptr, u_h1_ptr,
2118 contact_common_data_ptr->contactTractionPtr(),
2122 ep.
contactDisp, contact_common_data_ptr, contact_tree_ptr,
2123 contact_sfd_map_range_ptr));
2125 broken_data_ptr, contact_common_data_ptr, contact_tree_ptr));
2131 CHKERR add_ops_domain_side(op_loop_skeleton_side->getOpPtrVector());
2132 CHKERR add_ops_contact_rhs(op_loop_skeleton_side->getOpPtrVector());
2135 pip.push_back(op_loop_skeleton_side);
2141 EshelbianCore &ep, boost::shared_ptr<ForcesAndSourcesCore> fe_ptr,
2142 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pip) {
2145 auto contact_tree_ptr = boost::dynamic_pointer_cast<ContactTree>(fe_ptr);
2146 auto &m_field = ep.
mField;
2152 using SideEleOp = EleOnSide::UserDataOperator;
2153 using BdyEleOp = BoundaryEle::UserDataOperator;
2160 auto rule_contact = [](int, int,
int o) {
return -1; };
2163 auto set_rule_contact = [refine](
2166 int order_col,
int order_data
2170 auto rule = 2 * order_data;
2175 op_loop_skeleton_side->getSideFEPtr()->getRuleHook = rule_contact;
2176 op_loop_skeleton_side->getSideFEPtr()->setRuleHook = set_rule_contact;
2178 EshelbianPlasticity::AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
2184 auto broken_data_ptr = boost::make_shared<std::vector<BrokenBaseSideData>>();
2187 auto contact_common_data_ptr = boost::make_shared<ContactOps::CommonData>();
2189 auto add_ops_domain_side = [&](
auto &pip) {
2194 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
2195 boost::make_shared<CGGUserPolynomialBase>(
nullptr,
true);
2197 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
2198 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
2200 op_loop_domain_side->getOpPtrVector().push_back(
2203 op_loop_domain_side->getOpPtrVector().push_back(
2205 ep.
piolaStress, contact_common_data_ptr->contactTractionPtr()));
2206 pip.push_back(op_loop_domain_side);
2210 auto add_ops_contact_lhs = [&](
auto &pip) {
2213 ep.
contactDisp, contact_common_data_ptr->contactDispPtr()));
2214 auto u_h1_ptr = boost::make_shared<MatrixDouble>();
2218 contact_tree_ptr, u_h1_ptr,
2219 contact_common_data_ptr->contactTractionPtr(),
2224 auto contact_sfd_map_range_ptr = boost::make_shared<std::map<int, Range>>(
2229 contact_tree_ptr, contact_sfd_map_range_ptr));
2232 ep.
contactDisp, broken_data_ptr, contact_common_data_ptr,
2233 contact_tree_ptr, contact_sfd_map_range_ptr));
2236 broken_data_ptr, ep.
contactDisp, contact_common_data_ptr,
2243 CHKERR add_ops_domain_side(op_loop_skeleton_side->getOpPtrVector());
2244 CHKERR add_ops_contact_lhs(op_loop_skeleton_side->getOpPtrVector());
2247 pip.push_back(op_loop_skeleton_side);
2254 boost::shared_ptr<ForcesAndSourcesCore> fe_ptr,
2255 boost::shared_ptr<MatrixDouble> u_h1_ptr,
2256 boost::shared_ptr<MatrixDouble> contact_traction_ptr,
2257 Range r, moab::Interface *post_proc_mesh_ptr,
2258 std::vector<EntityHandle> *map_gauss_pts_ptr) {
2260 auto &m_field = ep.
mField;
2261 auto contact_tree_ptr = boost::dynamic_pointer_cast<ContactTree>(fe_ptr);
2263 contact_tree_ptr, u_h1_ptr, contact_traction_ptr,
2265 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 MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
#define CHK_MOAB_THROW(err, msg)
Check error code of MoAB function and throw MoFEM exception.
@ MOFEM_DATA_INCONSISTENCY
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
static const double face_coords[4][9]
#define MOFEM_LOG(channel, severity)
Log.
#define MOFEM_LOG_CHANNEL(channel)
Set and reset channel.
MoFEMErrorCode getCubitMeshsetPtr(const int ms_id, const CubitBCType cubit_bc_type, const CubitMeshSets **cubit_meshset_ptr) const
get cubit meshset
FTensor::Index< 'i', SPACE_DIM > i
const double c
speed of light (cm/ns)
const double v
phase velocity of light in medium (cm/ns)
FTensor::Index< 'l', 3 > l
FTensor::Index< 'j', 3 > j
FTensor::Index< 'k', 3 > k
static auto get_range_from_block(MoFEM::Interface &m_field, const std::string block_name, int dim)
auto checkSdf(EntityHandle fe_ent, std::map< int, Range > &sdf_map_range)
ForcesAndSourcesCore::UserDataOperator * getOpContactDetection(EshelbianCore &ep, boost::shared_ptr< ForcesAndSourcesCore > contact_tree_ptr, boost::shared_ptr< MatrixDouble > u_h1_ptr, boost::shared_ptr< MatrixDouble > contact_traction_ptr, Range r, moab::Interface *post_proc_mesh_ptr, std::vector< EntityHandle > *map_gauss_pts_ptr)
Push operator for contact detection.
boost::shared_ptr< ForcesAndSourcesCore > createContactDetectionFiniteElement(EshelbianCore &ep)
Create a Contact Tree finite element.
auto multiMasterPoint(ContactTree::FaceData *face_data_ptr, FTensor::Tensor1< T1, 3 > &t_spatial_coords)
auto multiGetGap(ContactTree::FaceData *face_data_ptr, FTensor::Tensor1< T1, 3 > &t_spatial_coords)
auto multiPointRhs(ContactTree::FaceData *face_data_ptr, FTensor::Tensor1< T1, 3 > &t_coords, FTensor::Tensor1< T2, 3 > &t_spatial_coords, FTensor::Tensor1< T3, 3 > &t_master_traction, MultiPointRhsType type, bool debug=false)
MoFEMErrorCode pushContactOpsRhs(EshelbianCore &ep, boost::shared_ptr< ForcesAndSourcesCore > contact_tree_ptr, boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pip)
Push contact operations to the right-hand side.
auto multiSlavePoint(ContactTree::FaceData *face_data_ptr, FTensor::Tensor1< T1, 3 > &t_spatial_coords)
auto multiPoint(std::array< double, 3 > &unit_ray, std::array< double, 3 > &point, std::array< double, 9 > &elem_point_nodes, std::array< double, 9 > &elem_traction_nodes, FTensor::Tensor1< T1, 3 > &t_spatial_coords)
Calculate points data on contact surfaces.
MoFEMErrorCode pushContactOpsLhs(EshelbianCore &ep, boost::shared_ptr< ForcesAndSourcesCore > contact_tree_ptr, boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pip)
Push contact operations to the left-hand side.
boost::shared_ptr< ContactSDFPython > setupContactSdf(MoFEM::Interface &m_field)
Read SDF file and setup contact SDF.
static auto get_body_range(MoFEM::Interface &m_field, const std::string name, int dim)
auto getSdf(OP_PTR op_ptr, MatrixDouble &contact_disp, int block_id, bool eval_hessian)
PipelineManager::ElementsAndOpsByDim< SPACE_DIM >::FaceSideEle EleOnSide
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
VectorBoundedArray< double, 3 > VectorDouble3
UBlasMatrix< double > MatrixDouble
implementation of Data Operators for Forces and Sources
auto id_from_handle(const EntityHandle h)
PetscErrorCode PetscOptionsGetScalar(PetscOptions *, const char pre[], const char name[], PetscScalar *dval, PetscBool *set)
PetscErrorCode PetscOptionsGetString(PetscOptions *, const char pre[], const char name[], char str[], size_t size, PetscBool *set)
static auto getFTensor0FromVec(V &data)
Get tensor rank 0 (scalar) form data vector.
FTensor::Index< 'm', 3 > m
boost::shared_ptr< Range > frontAdjEdges
MoFEM::Interface & mField
const std::string materialH1Positions
const std::string elementVolumeName
const std::string spatialH1Disp
const std::string piolaStress
int contactRefinementLevels
static PetscBool physicalTimeFlg
static double currentPhysicalTime
const std::string contactDisp
const std::string contactElement
boost::shared_ptr< ContactOps::CommonData > commonDataPtr
boost::shared_ptr< ContactTree > contactTreePtr
boost::shared_ptr< ContactTree > contactTreePtr
boost::shared_ptr< ContactOps::CommonData > commonDataPtr
boost::shared_ptr< ContactOps::CommonData > commonDataPtr
boost::shared_ptr< std::map< int, Range > > sdfMapRangePtr
boost::shared_ptr< ContactTree > contactTreePtr
boost::shared_ptr< std::map< int, Range > > sdfMapRangePtr
MoFEMErrorCode iNtegrate(EntitiesFieldData::EntData &row_data, EntitiesFieldData::EntData &col_data)
OpConstrainBoundaryL2Lhs_dU(const std::string row_field_name, const std::string col_field_name, boost::shared_ptr< ContactOps::CommonData > common_data_ptr, boost::shared_ptr< ContactTree > contact_tree_ptr, boost::shared_ptr< std::map< int, Range > > sdf_map_range_ptr=nullptr)
boost::shared_ptr< ContactOps::CommonData > commonDataPtr
boost::shared_ptr< ContactTree > contactTreePtr
boost::shared_ptr< std::map< int, Range > > sdfMapRangePtr
boost::shared_ptr< ContactOps::CommonData > commonDataPtr
boost::shared_ptr< ContactTree > contactTreePtr
MoFEMErrorCode iNtegrate(EntitiesFieldData::EntData &row_data)
OpConstrainBoundaryL2Rhs(const std::string row_field_name, boost::shared_ptr< ContactOps::CommonData > common_data_ptr, boost::shared_ptr< ContactTree > contact_tree_ptr, boost::shared_ptr< std::map< int, Range > > sdf_map_range_ptr=nullptr)
boost::shared_ptr< ContactOps::CommonData > commonDataPtr
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
boost::weak_ptr< ContactTree > contactTreePtr
FaceElementForcesAndSourcesCore::UserDataOperator UOP
boost::shared_ptr< MatrixDouble > uH1Ptr
OpMoveNode(boost::shared_ptr< ContactTree > contact_tree_ptr, boost::shared_ptr< ContactOps::CommonData > common_data_ptr, boost::shared_ptr< MatrixDouble > u_h1_ptr)
moab::Interface * postProcMeshPtr
boost::shared_ptr< ContactTree > contactTreePtr
std::vector< EntityHandle > * mapGaussPtsPtr
boost::shared_ptr< MatrixDouble > uH1Ptr
OpTreeSearch(boost::shared_ptr< ContactTree > contact_tree_ptr, boost::shared_ptr< MatrixDouble > u_h1_ptr, boost::shared_ptr< MatrixDouble > traction_ptr, Range r, moab::Interface *post_proc_mesh_ptr, std::vector< EntityHandle > *map_gauss_pts_ptr)
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
boost::shared_ptr< MatrixDouble > tractionPtr
FaceElementForcesAndSourcesCore::UserDataOperator UOP
virtual int get_comm_size() const =0
virtual moab::Interface & get_moab()=0
virtual int get_comm_rank() const =0
Deprecated interface functions.
Data on single entity (This is passed as argument to DataOperator::doWork)
FTensor::Tensor0< FTensor::PackPtr< double *, 1 > > getFTensor0N(const FieldApproximationBase base)
Get base function as Tensor0.
MatrixDouble & getN(const FieldApproximationBase base)
get base functions this return matrix (nb. of rows is equal to nb. of Gauss pts, nb....
auto getFTensor1N(FieldApproximationBase base)
Get base functions for Hdiv/Hcurl spaces.
const VectorInt & getIndices() const
Get global indices of degrees of freedom on entity.
Structure for user loop methods on finite elements.
EntityHandle getFEEntityHandle() const
Get the entity handle of the current finite element.
Base face element used to integrate on skeleton.
default operator for TRI element
structure to get information from mofem into EntitiesFieldData
MatrixDouble gaussPts
Matrix of integration points.
static auto getOrCreate(moab::Core *core_mesh_ptr)
Interface for managing meshsets containing materials and boundary conditions.
Operator for broken loop side.
Calculate trace of vector (Hdiv/Hcurl) space.
Specialization for MatrixDouble vector field values calculation.
Element used to execute operators on side of the element.
Template struct for dimension-specific finite element types.
std::string optionsPrefix
Prefix for options.
MoFEMErrorCode writeFile(const std::string file_name)
wrote results in (MOAB) format, use "file_name.h5m"
auto getPostProcMeshPcommPtr()
auto & getPostProcMesh()
Get postprocessing mesh.
std::map< EntityType, PostProcGenerateRefMeshPtr > refElementsMap
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.
BoundaryEle::UserDataOperator BdyEleOp
double zeta
Viscous hardening.