38#ifdef ENABLE_PYTHON_BINDING
39#include <boost/python.hpp>
40#include <boost/python/def.hpp>
41#include <boost/python/numpy.hpp>
42namespace bp = boost::python;
43namespace np = boost::python::numpy;
46#include <ContactOps.hpp>
52 double circumcenter[3],
double *xi,
double *
eta);
57#ifdef ENABLE_PYTHON_BINDING
58struct ContactSDFPython :
public ContactOps::SDFPython {
59 using ContactOps::SDFPython::SDFPython;
66 boost::shared_ptr<ContactSDFPython> sdf_python_ptr;
68#ifdef ENABLE_PYTHON_BINDING
70 auto file_exists = [](std::string myfile) {
71 std::ifstream file(myfile.c_str());
78 char sdf_file_name[255] =
"sdf.py";
80 sdf_file_name, 255, PETSC_NULLPTR);
82 if (file_exists(sdf_file_name)) {
83 MOFEM_LOG(
"EP", Sev::inform) << sdf_file_name <<
" file found";
84 sdf_python_ptr = boost::make_shared<ContactSDFPython>();
85 CHKERR sdf_python_ptr->sdfInit(sdf_file_name);
86 ContactOps::sdfPythonWeakPtr = sdf_python_ptr;
87 MOFEM_LOG(
"EP", Sev::inform) <<
"SdfPython initialized";
89 MOFEM_LOG(
"EP", Sev::warning) << sdf_file_name <<
" file NOT found";
94 return sdf_python_ptr;
104 boost::shared_ptr<moab::Core> core_mesh_ptr,
int max_order,
105 std::map<int, Range> &&body_map);
142 using MapFaceData = std::map<EntityHandle, std::vector<FaceData>>;
146 auto it = map_face_data.find(fe_ent);
147 if (it == map_face_data.end()) {
148 return (std::vector<FaceData> *)
nullptr;
150 return &(it->second);
154 std::vector<FaceData> *vec_ptr) {
156 if (it != vec_ptr->end()) {
157 if (it->gaussPtNb == gg) {
158 face_data_ptr = &(*it);
162 return face_data_ptr;
187 for (
auto &m_sdf : sdf_map_range) {
188 if (m_sdf.second.find(fe_ent) != m_sdf.second.end())
194template <
typename OP_PTR>
198 auto nb_gauss_pts = op_ptr->getGaussPts().size2();
200 auto ts_time = op_ptr->getTStime();
201 auto ts_time_step = op_ptr->getTStimeStep();
208 op_ptr->getFTensor1CoordsAtGaussPts(),
209 getFTensor1FromMat<3>(contact_disp), nb_gauss_pts);
211 op_ptr->getFTensor1NormalsAtGaussPts(), nb_gauss_pts);
213 ts_time_step, ts_time, nb_gauss_pts, m_spatial_coords, m_normals_at_pts,
216 ts_time_step, ts_time, nb_gauss_pts, m_spatial_coords, m_normals_at_pts,
220 if (v_sdf.size() != nb_gauss_pts)
222 "Wrong number of integration pts");
223 if (m_grad_sdf.size1() != nb_gauss_pts)
225 "Wrong number of integration pts");
226 if (m_grad_sdf.size2() != 3)
232 ts_time_step, ts_time, nb_gauss_pts, m_spatial_coords, m_normals_at_pts,
234 return std::make_tuple(block_id, m_normals_at_pts, v_sdf, m_grad_sdf,
238 return std::make_tuple(block_id, m_normals_at_pts, v_sdf, m_grad_sdf,
254template <
typename T1>
257 std::array<double, 3> &unit_ray, std::array<double, 3> &point,
259 std::array<double, 9> &elem_point_nodes,
260 std::array<double, 9> &elem_traction_nodes,
265 auto t_unit_ray = getFTensor1FromPtr<3>(unit_ray.data());
266 auto t_point = getFTensor1FromPtr<3>(point.data());
268 auto get_normal = [](
auto &ele_coords) {
274 auto t_normal = get_normal(elem_point_nodes);
275 t_normal(
i) /= t_normal.l2();
277 auto sn = t_normal(
i) * t_point(
i);
278 auto nm = t_normal(
i) * t_spatial_coords(
i);
279 auto nr = t_normal(
i) * t_unit_ray(
i);
281 auto gamma = (sn - nm) / nr;
284 t_point_current(
i) = t_spatial_coords(
i) + gamma * t_unit_ray(
i);
286 auto get_local_point_shape_functions = [&](
auto &&t_elem_coords,
288 std::array<T1, 2> loc_coords;
291 &t_elem_coords(0, 0), &t_point(0), 1, loc_coords.data()),
294 N_MBTRI1(loc_coords[0], loc_coords[1]),
295 N_MBTRI2(loc_coords[0], loc_coords[1])};
298 auto eval_position = [&](
auto &&t_field,
auto &t_shape_fun) {
302 t_point_out(
i) = t_shape_fun(
j) * t_field(
j,
i);
306 auto t_shape_fun = get_local_point_shape_functions(
307 getFTensor2FromPtr<3, 3>(elem_point_nodes.data()), t_point_current);
308 auto t_slave_point_updated = eval_position(
309 getFTensor2FromPtr<3, 3>(elem_point_nodes.data()), t_shape_fun);
310 auto t_traction_updated = eval_position(
311 getFTensor2FromPtr<3, 3>(elem_traction_nodes.data()), t_shape_fun);
313 return std::make_tuple(t_slave_point_updated, t_traction_updated, t_normal);
316template <
typename T1>
329template <
typename T1>
345template <
typename T1>
349 auto [t_slave_point_current, t_slave_traction_current, t_slave_normal] =
351 auto [t_master_point_current, t_master_traction_current, t_master_normal] =
357 t_normal(
i) = t_master_normal(
i) - t_slave_normal(
i);
360 auto gap = t_normal(
i) * (t_slave_point_current(
i) - t_spatial_coords(
i));
361 auto tn_master = t_master_traction_current(
i) * t_normal(
i);
362 auto tn_slave = t_slave_traction_current(
i) * t_normal(
i);
363 auto tn = std::max(-tn_master, tn_slave);
365 return std::make_tuple(gap, tn_master, tn_slave,
367 t_master_traction_current, t_slave_traction_current);
374template <
typename T1,
typename T2,
typename T3>
387 t_u(
i) = t_spatial_coords(
i) - t_coords(
i);
394 auto [t_slave_point_current, t_slave_traction_current, t_slave_normal] =
396 auto [t_master_point_current, t_master_traction_current, t_master_normal] =
401 t_normal(
i) = t_master_normal(
i) - t_slave_normal(
i);
406 t_P(
i,
j) = t_normal(
i) * t_normal(
j);
408 t_Q(
i,
j) = kronecker_delta(
i,
j) - t_P(
i,
j);
410 constexpr double beta = 0.5;
417 auto f_min_gap = [
zeta](
auto d,
auto s) {
418 return 0.5 * (d + s - std::sqrt((d - s) * (d - s) +
zeta));
421 auto f_diff_min_gap = [
zeta](
auto d,
auto s) {
422 return 0.5 * (1 - (d - s) / std::sqrt((d - s) * (d - s) +
zeta));
426 auto f_barrier = [alpha1, alpha2, f_min_gap, f_diff_min_gap](
auto g,
430 0.5 * (tn + f_min_gap(d, tn) + f_diff_min_gap(d, tn) * (d - tn));
431 auto b2 = alpha2 * f_min_gap(
g, 0) *
g;
436 t_gap_vec(
i) = beta * t_spatial_coords(
i) +
437 (1 - beta) * t_slave_point_current(
i) - t_spatial_coords(
i);
440 -beta * t_master_traction(
i) + (beta - 1) * t_slave_traction_current(
i);
442 auto t_gap = t_normal(
i) * t_gap_vec(
i);
443 auto t_tn = t_normal(
i) * t_traction_vec(
i);
444 auto barrier = f_barrier(t_gap, t_tn);
448 t_traction_bar(
i) = t_normal(
i) * barrier;
452 t_Q(
i,
j) * t_master_traction(
j) +
454 t_P(
i,
j) * (t_master_traction(
j) - t_traction_bar(
j));
457 auto is_nan_or_inf = [](
double value) ->
bool {
458 return std::isnan(value) || std::isinf(value);
461 double v = std::complex<double>(t_rhs(
i) * t_rhs(
i)).real();
462 if (is_nan_or_inf(
v)) {
464 MOFEM_LOG(
"SELF", Sev::error) <<
"t_rhs " << t_rhs;
480 const std::string row_field_name,
481 boost::shared_ptr<ContactOps::CommonData> common_data_ptr,
482 boost::shared_ptr<ContactTree> contact_tree_ptr,
483 boost::shared_ptr<std::map<int, Range>> sdf_map_range_ptr =
nullptr);
494 const std::string row_field_name,
495 boost::shared_ptr<ContactOps::CommonData> common_data_ptr,
496 boost::shared_ptr<ContactTree> contact_tree_ptr,
497 boost::shared_ptr<std::map<int, Range>> sdf_map_range_ptr)
500 commonDataPtr(common_data_ptr), contactTreePtr(contact_tree_ptr),
501 sdfMapRangePtr(sdf_map_range_ptr) {
510 "get alpha contact failed");
512 PETSC_NULLPTR,
"",
"-alpha_contact_quadratic",
514 "get alpha contact failed");
518 "get alpha contact failed");
538 const size_t nb_gauss_pts = getGaussPts().size2();
543 "Wrong number of integration pts %ld != %ld",
551 auto t_w = getFTensor0IntegrationWeight();
552 auto t_coords = getFTensor1CoordsAtGaussPts();
553 auto t_disp = getFTensor1FromMat<3>(
commonDataPtr->contactDisp);
554 auto t_traction = getFTensor1FromMat<3>(
commonDataPtr->contactTraction);
559 auto [block_id, m_normals_at_pts, v_sdf, m_grad_sdf, m_hess_sdf] =
564 auto t_grad_sdf_v = getFTensor1FromMat<3>(m_grad_sdf);
565 auto t_normalize_normal = getFTensor1FromMat<3>(m_normals_at_pts);
572 ++t_normalize_normal;
577 auto face_data_vec_ptr =
579 auto face_gauss_pts_it = face_data_vec_ptr->begin();
581 auto nb_base_functions = data.
getN().size2();
583 for (
auto gg = 0; gg != nb_gauss_pts; ++gg) {
586 auto face_data_ptr =
contactTreePtr->getFaceDataPtr(face_gauss_pts_it, gg,
589 auto check_face_contact = [&]() {
599#ifdef ENABLE_PYTHON_BINDING
601 if (ContactOps::sdfPythonWeakPtr.lock()) {
602 auto tn = t_traction(
i) * t_grad_sdf_v(
i);
606 constexpr double c = 0;
609 if (!
c && check_face_contact()) {
611 t_spatial_coords(
i) = t_coords(
i) + t_disp(
i);
612 auto t_rhs_tmp =
multiPointRhs(face_data_ptr, t_coords, t_spatial_coords,
614 t_rhs(
i) = t_rhs_tmp(
i);
618#ifdef ENABLE_PYTHON_BINDING
621 if (ContactOps::sdfPythonWeakPtr.lock()) {
623 t_cP(
i,
j) = (
c * t_grad_sdf_v(
i)) * t_grad_sdf_v(
j);
624 t_cQ(
i,
j) = kronecker_delta(
i,
j) - t_cP(
i,
j);
625 t_rhs(
i) = t_cQ(
i,
j) * t_traction(
j) +
626 (
c * inv_cn * t_sdf_v) * t_grad_sdf_v(
i);
628 t_rhs(
i) = t_traction(
i);
631 t_rhs(
i) = t_traction(
i);
635 auto t_nf = getFTensor1FromPtr<3>(&nf[0]);
636 const double alpha = t_w * getMeasure();
639 for (; bb != nbRows / 3; ++bb) {
640 const double beta = alpha * t_base;
641 t_nf(
i) -= beta * t_rhs(
i);
645 for (; bb < nb_base_functions; ++bb)
656template <AssemblyType A>
664 boost::shared_ptr<std::vector<BrokenBaseSideData>> broken_base_side_data,
665 boost::shared_ptr<ContactOps::CommonData> common_data_ptr,
666 boost::shared_ptr<ContactTree> contact_tree_ptr);
675template <AssemblyType A>
678 boost::shared_ptr<std::vector<BrokenBaseSideData>>
679 broken_base_side_data,
680 boost::shared_ptr<ContactOps::CommonData> common_data_ptr,
681 boost::shared_ptr<ContactTree> contact_tree_ptr)
682 :
OP(broken_base_side_data), commonDataPtr(common_data_ptr),
683 contactTreePtr(contact_tree_ptr) {}
685template <AssemblyType A>
695 const size_t nb_gauss_pts = OP::getGaussPts().size2();
698 if (commonDataPtr->contactDisp.size1() != nb_gauss_pts) {
700 "Wrong number of integration pts %ld != %ld",
701 commonDataPtr->contactDisp.size1(), nb_gauss_pts);
708 auto t_w = OP::getFTensor0IntegrationWeight();
709 auto t_material_normal = OP::getFTensor1NormalsAtGaussPts();
710 auto t_coords = OP::getFTensor1CoordsAtGaussPts();
712 auto t_disp = getFTensor1FromMat<3>(commonDataPtr->contactDisp);
713 auto t_traction = getFTensor1FromMat<3>(commonDataPtr->contactTraction);
723 auto face_data_vec_ptr =
724 contactTreePtr->findFaceDataVecPtr(OP::getFEEntityHandle());
725 auto face_gauss_pts_it = face_data_vec_ptr->begin();
727 auto nb_base_functions = data.
getN().size2() / 3;
729 for (
auto gg = 0; gg != nb_gauss_pts; ++gg) {
731 auto t_nf = getFTensor1FromPtr<3>(&nf[0]);
732 const double alpha = t_w / 2.;
735 for (; bb != OP::nbRows / 3; ++bb) {
736 const double beta = alpha * t_base(
i) * t_material_normal(
i);
737 t_nf(
i) += beta * t_disp(
i);
741 for (; bb < nb_base_functions; ++bb)
753 const std::string row_field_name,
const std::string col_field_name,
754 boost::shared_ptr<ContactOps::CommonData> common_data_ptr,
755 boost::shared_ptr<ContactTree> contact_tree_ptr,
756 boost::shared_ptr<std::map<int, Range>> sdf_map_range_ptr =
nullptr);
768 const std::string row_field_name,
const std::string col_field_name,
769 boost::shared_ptr<ContactOps::CommonData> common_data_ptr,
770 boost::shared_ptr<ContactTree> contact_tree_ptr,
771 boost::shared_ptr<std::map<int, Range>> sdf_map_range_ptr)
774 commonDataPtr(common_data_ptr), contactTreePtr(contact_tree_ptr),
775 sdfMapRangePtr(sdf_map_range_ptr) {
794 auto &locMat = AssemblyBoundaryEleOp::locMat;
795 locMat.resize(nb_rows, nb_cols,
false);
798 if (nb_cols && nb_rows) {
800 auto nb_gauss_pts = getGaussPts().size2();
801 auto t_w = getFTensor0IntegrationWeight();
802 auto t_coords = getFTensor1CoordsAtGaussPts();
803 auto t_disp = getFTensor1FromMat<3>(
commonDataPtr->contactDisp);
804 auto t_traction = getFTensor1FromMat<3>(
commonDataPtr->contactTraction);
807 auto [block_id, m_normals_at_pts, v_sdf, m_grad_sdf, m_hess_sdf] =
812 auto t_grad_sdf_v = getFTensor1FromMat<3>(m_grad_sdf);
813 auto t_hess_sdf_v = getFTensor2SymmetricFromMat<3>(m_hess_sdf);
814 auto t_normalized_normal = getFTensor1FromMat<3>(m_normals_at_pts);
824 ++t_normalized_normal;
827 auto face_data_vec_ptr =
829 auto face_gauss_pts_it = face_data_vec_ptr->begin();
832 auto nb_face_functions = row_data.
getN().size2() / 3;
835 for (
size_t gg = 0; gg != nb_gauss_pts; ++gg) {
837 auto face_data_ptr =
contactTreePtr->getFaceDataPtr(face_gauss_pts_it, gg,
840 auto check_face_contact = [&]() {
852#ifdef ENABLE_PYTHON_BINDING
854 if (ContactOps::sdfPythonWeakPtr.lock()) {
855 auto tn = t_traction(
i) * t_grad_sdf_v(
i);
859 constexpr double c = 0;
862 if (!
c && check_face_contact()) {
864 t_spatial_coords(
i) = t_coords(
i) + t_disp(
i);
865 constexpr double eps = std::numeric_limits<float>::epsilon();
866 for (
auto ii = 0; ii < 3; ++ii) {
868 t_spatial_coords(0), t_spatial_coords(1), t_spatial_coords(2)};
869 t_spatial_coords_cx(ii) +=
eps * 1
i;
873 for (
int jj = 0; jj != 3; ++jj) {
874 auto v = t_rhs_tmp(jj).imag();
875 t_res_dU(jj, ii) =
v /
eps;
881#ifdef ENABLE_PYTHON_BINDING
883 if (ContactOps::sdfPythonWeakPtr.lock()) {
887 (-
c) * (t_hess_sdf_v(
i,
j) * t_grad_sdf_v(
k) * t_traction(
k) +
888 t_grad_sdf_v(
i) * t_hess_sdf_v(
k,
j) * t_traction(
k))
890 + (
c * inv_cn) * (t_sdf_v * t_hess_sdf_v(
i,
j) +
892 t_grad_sdf_v(
j) * t_grad_sdf_v(
i));
901 auto alpha = t_w * getMeasure();
904 for (; rr != nb_rows / 3; ++rr) {
906 auto t_mat = getFTensor2FromArray<3, 3, 3>(locMat, 3 * rr);
909 for (
size_t cc = 0; cc != nb_cols / 3; ++cc) {
910 auto beta = alpha * t_row_base * t_col_base;
911 t_mat(
i,
j) -= beta * t_res_dU(
i,
j);
918 for (; rr < nb_face_functions; ++rr)
930template <AssemblyType A>
938 std::string row_field_name,
939 boost::shared_ptr<std::vector<BrokenBaseSideData>> broken_base_side_data,
940 boost::shared_ptr<ContactOps::CommonData> common_data_ptr,
941 boost::shared_ptr<ContactTree> contact_tree_ptr,
942 boost::shared_ptr<std::map<int, Range>> sdf_map_range_ptr =
nullptr);
953template <AssemblyType A>
956 std::string row_field_name,
957 boost::shared_ptr<std::vector<BrokenBaseSideData>>
958 broken_base_side_data,
959 boost::shared_ptr<ContactOps::CommonData> common_data_ptr,
960 boost::shared_ptr<ContactTree> contact_tree_ptr,
961 boost::shared_ptr<std::map<int, Range>> sdf_map_range_ptr)
962 :
OP(row_field_name, broken_base_side_data, false, false),
963 commonDataPtr(common_data_ptr), contactTreePtr(contact_tree_ptr),
964 sdfMapRangePtr(sdf_map_range_ptr) {
968template <AssemblyType A>
984 auto &locMat = AssemblyBoundaryEleOp::locMat;
985 locMat.resize(nb_rows, nb_cols,
false);
988 if (nb_cols && nb_rows) {
990 const size_t nb_gauss_pts = OP::getGaussPts().size2();
992 auto t_w = OP::getFTensor0IntegrationWeight();
993 auto t_disp = getFTensor1FromMat<3>(commonDataPtr->contactDisp);
994 auto t_traction = getFTensor1FromMat<3>(commonDataPtr->contactTraction);
995 auto t_coords = OP::getFTensor1CoordsAtGaussPts();
996 auto t_material_normal = OP::getFTensor1NormalsAtGaussPts();
999 auto [block_id, m_normals_at_pts, v_sdf, m_grad_sdf, m_hess_sdf] =
1000 getSdf(
this, commonDataPtr->contactDisp,
1001 checkSdf(OP::getFEEntityHandle(), *sdfMapRangePtr),
false);
1004 auto t_grad_sdf_v = getFTensor1FromMat<3>(m_grad_sdf);
1011 ++t_material_normal;
1016 auto face_data_vec_ptr =
1017 contactTreePtr->findFaceDataVecPtr(OP::getFEEntityHandle());
1018 auto face_gauss_pts_it = face_data_vec_ptr->begin();
1021 auto nb_face_functions = row_data.
getN().size2();
1025 for (
size_t gg = 0; gg != nb_gauss_pts; ++gg) {
1027 auto face_data_ptr = contactTreePtr->getFaceDataPtr(face_gauss_pts_it, gg,
1030 auto check_face_contact = [&]() {
1031 if (
checkSdf(OP::getFEEntityHandle(), *sdfMapRangePtr) != -1)
1034 if (face_data_ptr) {
1042#ifdef ENABLE_PYTHON_BINDING
1044 if (ContactOps::sdfPythonWeakPtr.lock()) {
1045 auto tn = t_traction(
i) * t_grad_sdf_v(
i);
1049 constexpr double c = 0;
1052 if (!
c && check_face_contact()) {
1054 t_spatial_coords(
i) = t_coords(
i) + t_disp(
i);
1055 constexpr double eps = std::numeric_limits<float>::epsilon();
1056 for (
auto ii = 0; ii != 3; ++ii) {
1058 t_traction(0), t_traction(1), t_traction(2)};
1059 t_traction_cx(ii) +=
eps * 1
i;
1063 for (
int jj = 0; jj != 3; ++jj) {
1064 auto v = t_rhs_tmp(jj).imag();
1065 t_res_dP(jj, ii) =
v /
eps;
1070#ifdef ENABLE_PYTHON_BINDING
1071 if (ContactOps::sdfPythonWeakPtr.lock()) {
1073 t_cP(
i,
j) = (
c * t_grad_sdf_v(
i)) * t_grad_sdf_v(
j);
1074 t_cQ(
i,
j) = kronecker_delta(
i,
j) - t_cP(
i,
j);
1075 t_res_dP(
i,
j) = t_cQ(
i,
j);
1084 const double alpha = t_w / 2.;
1086 for (; rr != nb_rows / 3; ++rr) {
1088 auto t_mat = getFTensor2FromArray<3, 3, 3>(locMat, 3 * rr);
1091 for (
size_t cc = 0; cc != nb_cols / 3; ++cc) {
1092 auto col_base = t_col_base(
i) * t_material_normal(
i);
1093 const double beta = alpha * t_row_base * col_base;
1094 t_mat(
i,
j) -= beta * t_res_dP(
i,
j);
1101 for (; rr < nb_face_functions; ++rr)
1111template <AssemblyType A, IntegrationType I>
1114template <AssemblyType A>
1122 boost::shared_ptr<std::vector<BrokenBaseSideData>> broken_base_side_data,
1123 std::string col_field_name,
1124 boost::shared_ptr<ContactOps::CommonData> common_data_ptr,
1125 boost::shared_ptr<ContactTree> contact_tree_ptr);
1135template <AssemblyType A>
1138 boost::shared_ptr<std::vector<BrokenBaseSideData>>
1139 broken_base_side_data,
1140 std::string col_field_name,
1141 boost::shared_ptr<ContactOps::CommonData> common_data_ptr,
1142 boost::shared_ptr<ContactTree> contact_tree_ptr)
1143 :
OP(col_field_name, broken_base_side_data, true, true),
1144 commonDataPtr(common_data_ptr), contactTreePtr(contact_tree_ptr) {
1148template <AssemblyType A>
1167 auto &locMat = AssemblyBoundaryEleOp::locMat;
1168 locMat.resize(nb_rows, nb_cols,
false);
1171 if (nb_cols && nb_rows) {
1173 const size_t nb_gauss_pts = OP::getGaussPts().size2();
1175 auto t_w = OP::getFTensor0IntegrationWeight();
1176 auto t_disp = getFTensor1FromMat<3>(commonDataPtr->contactDisp);
1177 auto t_traction = getFTensor1FromMat<3>(commonDataPtr->contactTraction);
1178 auto t_coords = OP::getFTensor1CoordsAtGaussPts();
1179 auto t_material_normal = OP::getFTensor1NormalsAtGaussPts();
1186 ++t_material_normal;
1191 auto face_data_vec_ptr =
1192 contactTreePtr->findFaceDataVecPtr(OP::getFEEntityHandle());
1193 auto face_gauss_pts_it = face_data_vec_ptr->begin();
1196 auto nb_face_functions = row_data.
getN().size2() / 3;
1197 for (
size_t gg = 0; gg != nb_gauss_pts; ++gg) {
1199 const auto alpha = t_w / 2.;
1202 for (; rr != nb_rows / 3; ++rr) {
1204 auto row_base = alpha * (t_row_base(
i) * t_material_normal(
i));
1206 auto t_mat = getFTensor2FromArray<3, 3, 3>(locMat, 3 * rr);
1209 for (
size_t cc = 0; cc != nb_cols / 3; ++cc) {
1210 const auto beta = row_base * t_col_base;
1218 for (; rr < nb_face_functions; ++rr)
1225 locMat = trans(locMat);
1231 boost::shared_ptr<moab::Core> core_mesh_ptr,
1232 int max_order, std::map<int, Range> &&body_map)
1233 :
Base(m_field, core_mesh_ptr,
"contact"), maxOrder(max_order),
1236 auto ref_ele_ptr = boost::make_shared<PostProcGenerateRefMesh<MBTRI>>();
1237 ref_ele_ptr->hoNodes =
1242 "Error when generating reference element");
1244 MOFEM_LOG(
"EP", Sev::inform) <<
"Contact hoNodes " << ref_ele_ptr->hoNodes
1248 <<
"Contact maxOrder " << ref_ele_ptr->defMaxLevel;
1252 int def_ele_id = -1;
1254 MB_TAG_CREAT | MB_TAG_DENSE,
1257 thBodyId, MB_TAG_CREAT | MB_TAG_DENSE,
1277 std::array<double, 3> def_small_x{0., 0., 0.};
1279 MB_TAG_CREAT | MB_TAG_DENSE,
1280 def_small_x.data());
1282 MB_TAG_CREAT | MB_TAG_DENSE,
1283 def_small_x.data());
1285 std::array<double, 3> def_tractions{0., 0., 0.};
1287 "TRACTION", 3, MB_TYPE_DOUBLE,
thTraction, MB_TAG_CREAT | MB_TAG_DENSE,
1288 &*def_tractions.begin());
1303 PetscBarrier(
nullptr);
1306 if (pcomm_post_proc_mesh ==
nullptr)
1309 auto brodacts = [&](
auto &brodacts_ents) {
1313 pcomm_post_proc_mesh->broadcast_entities(
1320 Range brodacts_ents;
1322 CHKERR brodacts(brodacts_ents);
1341 treeSurfPtr = boost::shared_ptr<OrientedBoxTreeTool>(
1352 OpMoveNode(boost::shared_ptr<ContactTree> contact_tree_ptr,
1353 boost::shared_ptr<ContactOps::CommonData> common_data_ptr,
1354 boost::shared_ptr<MatrixDouble> u_h1_ptr);
1365 boost::shared_ptr<ContactTree> contact_tree_ptr,
1366 boost::shared_ptr<ContactOps::CommonData> common_data_ptr,
1367 boost::shared_ptr<MatrixDouble> u_h1_ptr)
1368 :
UOP(
NOSPACE,
UOP::OPSPACE), contactTreePtr(contact_tree_ptr),
1369 uH1Ptr(u_h1_ptr), commonDataPtr(common_data_ptr) {}
1377 auto get_body_id = [&](
auto fe_ent) {
1378 for (
auto &
m : contact_tree_ptr->bodyMap) {
1379 if (
m.second.find(fe_ent) !=
m.second.end()) {
1386 auto &moab_post_proc_mesh = contact_tree_ptr->getPostProcMesh();
1387 auto &post_proc_ents = contact_tree_ptr->getPostProcElements();
1389 auto fe_ent = getNumeredEntFiniteElementPtr()->getEnt();
1391 auto body_id = get_body_id(fe_ent);
1392 auto &map_gauss_pts = contact_tree_ptr->getMapGaussPts();
1394 CHKERR moab_post_proc_mesh.tag_clear_data(contact_tree_ptr->thEleId,
1395 post_proc_ents, &fe_id);
1396 CHKERR moab_post_proc_mesh.tag_clear_data(contact_tree_ptr->thBodyId,
1397 post_proc_ents, &body_id);
1399 auto nb_gauss_pts = getGaussPts().size2();
1400 auto t_u_h1 = getFTensor1FromMat<3>(*
uH1Ptr);
1401 auto t_u_l2 = getFTensor1FromMat<3>(
commonDataPtr->contactDisp);
1402 auto t_coords = getFTensor1CoordsAtGaussPts();
1405 auto t_x_h1 = getFTensor1FromPtr<3>(&x_h1(0, 0));
1407 auto t_x_l2 = getFTensor1FromPtr<3>(&x_l2(0, 0));
1414 for (
auto gg = 0; gg != nb_gauss_pts; ++gg) {
1415 t_x_h1(
i) = t_coords(
i) + t_u_h1(
i);
1416 t_x_l2(
i) = t_coords(
i) + t_u_l2(
i);
1425 CHKERR moab_post_proc_mesh.set_coords(
1426 &*map_gauss_pts.begin(), map_gauss_pts.size(), &*x_h1.data().begin());
1427 CHKERR moab_post_proc_mesh.tag_set_data(
1428 contact_tree_ptr->thSmallX, &*map_gauss_pts.begin(),
1429 map_gauss_pts.size(), &*x_h1.data().begin());
1430 CHKERR moab_post_proc_mesh.tag_set_data(
1431 contact_tree_ptr->thLargeX, &*map_gauss_pts.begin(),
1432 map_gauss_pts.size(), &*coords.data().begin());
1433 CHKERR moab_post_proc_mesh.tag_set_data(
1434 contact_tree_ptr->thTraction, &*map_gauss_pts.begin(),
1435 map_gauss_pts.size(), &*tractions.data().begin());
1439 "ContactTree pointer expired in OpMoveNode");
1449 OpTreeSearch(boost::shared_ptr<ContactTree> contact_tree_ptr,
1450 boost::shared_ptr<MatrixDouble> u_h1_ptr,
1451 boost::shared_ptr<MatrixDouble> traction_ptr,
Range r,
1453 moab::Interface *post_proc_mesh_ptr,
1454 std::vector<EntityHandle> *map_gauss_pts_ptr
1471 boost::shared_ptr<MatrixDouble> u_h1_ptr,
1472 boost::shared_ptr<MatrixDouble> traction_ptr,
1475 moab::Interface *post_proc_mesh_ptr,
1476 std::vector<EntityHandle> *map_gauss_pts_ptr
1479 :
UOP(
NOSPACE,
UOP::OPSPACE), contactTreePtr(contact_tree_ptr),
1480 uH1Ptr(u_h1_ptr), tractionPtr(traction_ptr),
1481 postProcMeshPtr(post_proc_mesh_ptr), mapGaussPtsPtr(map_gauss_pts_ptr),
1488 auto &m_field = getPtrFE()->mField;
1489 auto fe_ent = getNumeredEntFiniteElementPtr()->getEnt();
1498 const auto nb_gauss_pts = getGaussPts().size2();
1500 auto t_disp_h1 = getFTensor1FromMat<3>(*
uH1Ptr);
1501 auto t_coords = getFTensor1CoordsAtGaussPts();
1502 auto t_traction = getFTensor1FromMat<3>(*
tractionPtr);
1510 auto get_ele_centre = [
i](
auto t_ele_coords) {
1512 t_ele_center(
i) = 0;
1513 for (
int nn = 0; nn != 3; nn++) {
1514 t_ele_center(
i) += t_ele_coords(
i);
1517 t_ele_center(
i) /= 3;
1518 return t_ele_center;
1521 auto get_ele_radius = [
i](
auto t_ele_center,
auto t_ele_coords) {
1523 t_n0(
i) = t_ele_center(
i) - t_ele_coords(
i);
1527 auto get_face_conn = [
this](
auto face) {
1531 face, conn, num_nodes,
true),
1533 if (num_nodes != 3) {
1539 auto get_face_coords = [
this](
auto conn) {
1540 std::array<double, 9> coords;
1545 auto get_closet_face = [
this](
auto *point_ptr,
auto r) {
1547 std::vector<EntityHandle> faces_out;
1551 "get closest faces");
1555 auto get_faces_out = [
this](
auto *point_ptr,
auto *unit_ray_ptr,
auto radius,
1557 std::vector<double> distances_out;
1558 std::vector<EntityHandle> faces_out;
1563 point_ptr, unit_ray_ptr, &radius),
1565 "get closest faces");
1566 return std::make_pair(faces_out, distances_out);
1569 auto get_normal = [](
auto &ele_coords) {
1575 auto make_map = [&](
auto &face_out,
auto &face_dist,
auto &t_ray_point,
1576 auto &t_unit_ray,
auto &t_master_coord) {
1579 std::map<double, EntityHandle>
m;
1580 for (
auto ii = 0; ii != face_out.size(); ++ii) {
1581 auto face_conn = get_face_conn(face_out[ii]);
1584 t_face_normal.normalize();
1586 t_x(
i) = t_ray_point(
i) + t_unit_ray(
i) * face_dist[ii];
1589 t_x(
i) * t_face_normal(
j) - t_master_coord(
i) * t_unit_ray(
j);
1590 if (t_unit_ray(
i) * t_face_normal(
i) > std::cos(M_PI / 3)) {
1591 auto dot = std::sqrt(t_chi(
i,
j) * t_chi(
i,
j));
1592 m[dot] = face_out[ii];
1598 auto get_tag_data = [
this](
auto tag,
auto face,
auto &vec) {
1602 vec.resize(tag_length);
1608 auto create_tag = [
this](
const std::string tag_name,
const int size) {
1609 double def_VAL[] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
1613 tag_name.c_str(), size, MB_TYPE_DOUBLE,
th,
1614 MB_TAG_CREAT | MB_TAG_SPARSE, def_VAL);
1621 auto set_float_precision = [](
const double x) {
1622 if (std::abs(x) < std::numeric_limits<float>::epsilon())
1629 auto save_scal_tag = [&](
auto &
th,
auto v,
const int gg) {
1632 v = set_float_precision(
v);
1639 auto get_fe_adjacencies = [
this](
auto fe_ent) {
1642 &fe_ent, 1, 2,
false, adj_faces, moab::Interface::UNION),
1644 std::set<int> adj_ids;
1645 for (
auto f : adj_faces) {
1651 auto get_face_id = [
this](
auto face) {
1660 auto get_body_id = [
this](
auto face) {
1669 auto get_face_part = [
this](
auto face) {
1670 const moab::Core *core_mesh_ptr =
1671 dynamic_cast<const moab::Core *
>(&
contactTreePtr->getPostProcMesh());
1672 auto pcomm_post_proc_mesh =
1676 pcomm_post_proc_mesh->part_tag(), &face, 1, &part) == MB_SUCCESS) {
1682 auto check_face = [&](
auto face,
auto fe_id,
auto part) {
1683 auto face_id = get_face_id(face);
1684 auto face_part = get_face_part(face);
1685 if (face_id == fe_id && face_part == part)
1693 auto save_vec_tag = [&](
auto &
th,
auto &t_d,
const int gg) {
1697 for (
auto &
a :
v.data())
1698 a = set_float_precision(
a);
1700 &*
v.data().begin());
1705 Tag th_mark = create_tag(
"contact_mark", 1);
1706 Tag th_mark_slave = create_tag(
"contact_mark_slave", 1);
1707 Tag th_body_id = create_tag(
"contact_body_id", 1);
1708 Tag th_gap = create_tag(
"contact_gap", 1);
1709 Tag th_tn_master = create_tag(
"contact_tn_master", 1);
1710 Tag th_tn_slave = create_tag(
"contact_tn_slave", 1);
1711 Tag th_contact_traction = create_tag(
"contact_traction", 3);
1712 Tag th_contact_traction_master = create_tag(
"contact_traction_master", 3);
1713 Tag th_contact_traction_slave = create_tag(
"contact_traction_slave", 3);
1714 Tag th_c = create_tag(
"contact_c", 1);
1715 Tag th_normal = create_tag(
"contact_normal", 3);
1716 Tag th_dist = create_tag(
"contact_dip", 3);
1718 auto t_ele_centre = get_ele_centre(getFTensor1Coords());
1719 auto ele_radius = get_ele_radius(t_ele_centre, getFTensor1Coords());
1725 auto adj_fe_ids = get_fe_adjacencies(fe_ent);
1727 for (
auto gg = 0; gg != nb_gauss_pts; ++gg) {
1730 t_spatial_coords(
i) = t_coords(
i) + t_disp_h1(
i);
1733 CHKERR save_vec_tag(th_contact_traction, t_traction, gg);
1736 auto faces_close = get_closet_face(&t_spatial_coords(0), ele_radius);
1737 for (
auto face_close : faces_close) {
1738 if (check_face(face_close, fe_id, m_field.get_comm_rank())) {
1740 auto body_id = get_body_id(face_close);
1742 auto master_face_conn = get_face_conn(face_close);
1743 std::array<double, 9> master_coords;
1746 master_coords.data());
1747 std::array<double, 9> master_traction;
1750 master_traction.data());
1751 auto t_normal_face_close = get_normal(master_coords);
1752 t_normal_face_close.normalize();
1756 CHKERR save_scal_tag(th_mark,
m, gg);
1757 CHKERR save_scal_tag(th_body_id,
static_cast<double>(body_id), gg);
1758 CHKERR save_vec_tag(th_normal, t_normal_face_close, gg);
1759 CHKERR save_vec_tag(th_contact_traction, t_traction, gg);
1763 t_unit_ray(
i) = -t_normal_face_close(
i);
1766 t_spatial_coords(
i) -
1769 constexpr double eps = 1e-3;
1770 auto [faces_out, faces_dist] =
1771 get_faces_out(&t_ray_point(0), &t_unit_ray(0),
1775 auto m = make_map(faces_out, faces_dist, t_ray_point, t_unit_ray,
1777 for (
auto m_it =
m.begin(); m_it !=
m.end(); ++m_it) {
1778 auto face = m_it->second;
1779 if (face != face_close) {
1783 (adj_fe_ids.find(get_face_id(face)) == adj_fe_ids.end() ||
1784 get_face_part(face) != m_field.get_comm_rank())
1789 shadow_vec.back().gaussPtNb = gg;
1791 auto slave_face_conn = get_face_conn(face);
1792 std::array<double, 9> slave_coords;
1795 slave_coords.data());
1796 auto t_normal_face = get_normal(slave_coords);
1797 std::array<double, 9> slave_tractions;
1800 slave_tractions.data());
1802 auto t_master_point =
1803 getFTensor1FromPtr<3>(shadow_vec.back().masterPoint.data());
1804 auto t_slave_point =
1805 getFTensor1FromPtr<3>(shadow_vec.back().slavePoint.data());
1806 auto t_ray_point_data =
1807 getFTensor1FromPtr<3>(shadow_vec.back().rayPoint.data());
1808 auto t_unit_ray_data =
1809 getFTensor1FromPtr<3>(shadow_vec.back().unitRay.data());
1811 t_slave_point(
i) = t_ray_point(
i) + m_it->first * t_unit_ray(
i);
1813 auto eval_position = [&](
auto &&t_elem_coords,
auto &&t_point) {
1814 std::array<double, 2> loc_coords;
1817 &t_elem_coords(0, 0), &t_point(0), 1,
1819 "get local coords");
1828 t_point_out(
i) = t_shape_fun(
j) * t_elem_coords(
j,
i);
1832 auto t_master_point_updated = eval_position(
1833 getFTensor2FromPtr<3, 3>(master_coords.data()),
1834 getFTensor1FromPtr<3>(shadow_vec.back().masterPoint.data()));
1835 t_master_point(
i) = t_master_point_updated(
i);
1837 auto t_slave_point_updated = eval_position(
1838 getFTensor2FromPtr<3, 3>(slave_coords.data()),
1839 getFTensor1FromPtr<3>(shadow_vec.back().slavePoint.data()));
1840 t_slave_point(
i) = t_slave_point_updated(
i);
1842 t_ray_point_data(
i) = t_ray_point(
i);
1843 t_unit_ray_data(
i) = t_unit_ray(
i);
1845 std::copy(master_coords.begin(), master_coords.end(),
1846 shadow_vec.back().masterPointNodes.begin());
1847 std::copy(master_traction.begin(), master_traction.end(),
1848 shadow_vec.back().masterTractionNodes.begin());
1849 std::copy(slave_coords.begin(), slave_coords.end(),
1850 shadow_vec.back().slavePointNodes.begin());
1851 std::copy(slave_tractions.begin(), slave_tractions.end(),
1852 shadow_vec.back().slaveTractionNodes.begin());
1854 shadow_vec.back().eleRadius = ele_radius;
1864 auto [gap, tn_master, tn_slave,
c, t_master_traction,
1866 multiGetGap(&(shadow_vec.back()), t_spatial_coords);
1868 t_gap_vec(
i) = t_slave_point(
i) - t_spatial_coords(
i);
1869 CHKERR save_scal_tag(th_gap, gap, gg);
1870 CHKERR save_scal_tag(th_tn_master, tn_master, gg);
1871 CHKERR save_scal_tag(th_tn_slave, tn_slave, gg);
1872 CHKERR save_scal_tag(th_c,
c, gg);
1874 CHKERR save_scal_tag(th_mark_slave,
m, gg);
1875 CHKERR save_vec_tag(th_dist, t_gap_vec, gg);
1876 CHKERR save_vec_tag(th_contact_traction_master,
1877 t_master_traction, gg);
1878 CHKERR save_vec_tag(th_contact_traction_slave, t_slave_traction,
1896 const std::string block_name,
int dim) {
1902 std::regex((boost::format(
"%s(.*)") % block_name).str())
1906 for (
auto bc : bcs) {
1910 "get meshset ents");
1917boost::shared_ptr<ForcesAndSourcesCore>
1920 auto &m_field = ep.
mField;
1922 boost::shared_ptr<ContactTree> fe_contact_tree;
1929 std::map<int, Range> map;
1935 (boost::format(
"%s(.*)") % name).str()
1942 m_field.get_moab(), dim, ents,
true),
1944 map[m_ptr->getMeshsetId()] = ents;
1945 MOFEM_LOG(
"EPSYNC", sev) <<
"Meshset: " << m_ptr->getMeshsetId() <<
" "
1946 << ents.size() <<
" entities";
1953 auto get_map_skin = [&](
auto &&map) {
1954 ParallelComm *pcomm =
1955 ParallelComm::get_pcomm(&m_field.get_moab(),
MYPCOMM_INDEX);
1957 Skinner skin(&m_field.get_moab());
1958 for (
auto &
m : map) {
1960 CHKERR skin.find_skin(0,
m.second,
false, skin_faces);
1962 skin_faces, PSTATUS_SHARED | PSTATUS_MULTISHARED,
1963 PSTATUS_NOT, -1,
nullptr),
1965 m.second.swap(skin_faces);
1975 auto contact_common_data_ptr = boost::make_shared<ContactOps::CommonData>();
1977 auto calcs_side_traction = [&](
auto &pip) {
1981 using SideEleOp = EleOnSide::UserDataOperator;
1984 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
1985 boost::make_shared<CGGUserPolynomialBase>(
nullptr,
true);
1986 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
1987 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
1989 op_loop_domain_side->getOpPtrVector().push_back(
1991 ep.
piolaStress, contact_common_data_ptr->contactTractionPtr(),
1992 boost::make_shared<double>(1.0)));
1993 pip.push_back(op_loop_domain_side);
1997 auto add_contact_three = [&]() {
1999 auto tree_moab_ptr = boost::make_shared<moab::Core>();
2000 fe_contact_tree = boost::make_shared<ContactTree>(
2003 fe_contact_tree->getOpPtrVector().push_back(
2005 ep.
contactDisp, contact_common_data_ptr->contactDispPtr()));
2006 CHKERR calcs_side_traction(fe_contact_tree->getOpPtrVector());
2007 auto u_h1_ptr = boost::make_shared<MatrixDouble>();
2008 fe_contact_tree->getOpPtrVector().push_back(
2010 fe_contact_tree->getOpPtrVector().push_back(
2011 new OpMoveNode(fe_contact_tree, contact_common_data_ptr, u_h1_ptr));
2015 CHKERR add_contact_three();
2022 struct exclude_sdf {
2023 exclude_sdf(
Range &&r) : map(r) {}
2024 bool operator()(
FEMethod *fe_method_ptr) {
2026 if (map.find(ent) != map.end()) {
2036 fe_contact_tree->exeTestHook =
2039 return fe_contact_tree;
2044 std::map<int, Range> map;
2049 (boost::format(
"%s(.*)") % name).str()
2058 map[m_ptr->getMeshsetId()] = ents;
2065 EshelbianCore &ep, boost::shared_ptr<ForcesAndSourcesCore> fe_ptr,
2066 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pip) {
2069 auto contact_tree_ptr = boost::dynamic_pointer_cast<ContactTree>(fe_ptr);
2071 auto &m_field = ep.
mField;
2077 using SideEleOp = EleOnSide::UserDataOperator;
2078 using BdyEleOp = BoundaryEle::UserDataOperator;
2085 auto rule_contact = [](int, int,
int o) {
return -1; };
2088 auto set_rule_contact = [refine](
2091 int order_col,
int order_data
2095 auto rule = 2 * order_data;
2100 op_loop_skeleton_side->getSideFEPtr()->getRuleHook = rule_contact;
2101 op_loop_skeleton_side->getSideFEPtr()->setRuleHook = set_rule_contact;
2103 EshelbianPlasticity::AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
2109 auto broken_data_ptr = boost::make_shared<std::vector<BrokenBaseSideData>>();
2112 auto contact_common_data_ptr = boost::make_shared<ContactOps::CommonData>();
2114 auto add_ops_domain_side = [&](
auto &pip) {
2119 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
2120 boost::make_shared<CGGUserPolynomialBase>(
nullptr,
true);
2122 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
2123 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
2125 op_loop_domain_side->getOpPtrVector().push_back(
2128 op_loop_domain_side->getOpPtrVector().push_back(
2130 ep.
piolaStress, contact_common_data_ptr->contactTractionPtr()));
2131 pip.push_back(op_loop_domain_side);
2135 auto add_ops_contact_rhs = [&](
auto &pip) {
2138 auto contact_sfd_map_range_ptr = boost::make_shared<std::map<int, Range>>(
2142 ep.
contactDisp, contact_common_data_ptr->contactDispPtr()));
2143 auto u_h1_ptr = boost::make_shared<MatrixDouble>();
2147 contact_tree_ptr, u_h1_ptr,
2148 contact_common_data_ptr->contactTractionPtr(),
2152 ep.
contactDisp, contact_common_data_ptr, contact_tree_ptr,
2153 contact_sfd_map_range_ptr));
2155 broken_data_ptr, contact_common_data_ptr, contact_tree_ptr));
2161 CHKERR add_ops_domain_side(op_loop_skeleton_side->getOpPtrVector());
2162 CHKERR add_ops_contact_rhs(op_loop_skeleton_side->getOpPtrVector());
2165 pip.push_back(op_loop_skeleton_side);
2171 EshelbianCore &ep, boost::shared_ptr<ForcesAndSourcesCore> fe_ptr,
2172 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pip) {
2175 auto contact_tree_ptr = boost::dynamic_pointer_cast<ContactTree>(fe_ptr);
2176 auto &m_field = ep.
mField;
2182 using SideEleOp = EleOnSide::UserDataOperator;
2183 using BdyEleOp = BoundaryEle::UserDataOperator;
2190 auto rule_contact = [](int, int,
int o) {
return -1; };
2193 auto set_rule_contact = [refine](
2196 int order_col,
int order_data
2200 auto rule = 2 * order_data;
2205 op_loop_skeleton_side->getSideFEPtr()->getRuleHook = rule_contact;
2206 op_loop_skeleton_side->getSideFEPtr()->setRuleHook = set_rule_contact;
2208 EshelbianPlasticity::AddHOOps<SPACE_DIM - 1, SPACE_DIM, SPACE_DIM>::add(
2214 auto broken_data_ptr = boost::make_shared<std::vector<BrokenBaseSideData>>();
2217 auto contact_common_data_ptr = boost::make_shared<ContactOps::CommonData>();
2219 auto add_ops_domain_side = [&](
auto &pip) {
2224 op_loop_domain_side->getSideFEPtr()->getUserPolynomialBase() =
2225 boost::make_shared<CGGUserPolynomialBase>(
nullptr,
true);
2227 EshelbianPlasticity::AddHOOps<SPACE_DIM, SPACE_DIM, SPACE_DIM>::add(
2228 op_loop_domain_side->getOpPtrVector(), {HDIV, H1, L2},
2230 op_loop_domain_side->getOpPtrVector().push_back(
2233 op_loop_domain_side->getOpPtrVector().push_back(
2235 ep.
piolaStress, contact_common_data_ptr->contactTractionPtr()));
2236 pip.push_back(op_loop_domain_side);
2240 auto add_ops_contact_lhs = [&](
auto &pip) {
2243 ep.
contactDisp, contact_common_data_ptr->contactDispPtr()));
2244 auto u_h1_ptr = boost::make_shared<MatrixDouble>();
2248 contact_tree_ptr, u_h1_ptr,
2249 contact_common_data_ptr->contactTractionPtr(),
2254 auto contact_sfd_map_range_ptr = boost::make_shared<std::map<int, Range>>(
2259 contact_tree_ptr, contact_sfd_map_range_ptr));
2262 ep.
contactDisp, broken_data_ptr, contact_common_data_ptr,
2263 contact_tree_ptr, contact_sfd_map_range_ptr));
2266 broken_data_ptr, ep.
contactDisp, contact_common_data_ptr,
2273 CHKERR add_ops_domain_side(op_loop_skeleton_side->getOpPtrVector());
2274 CHKERR add_ops_contact_lhs(op_loop_skeleton_side->getOpPtrVector());
2277 pip.push_back(op_loop_skeleton_side);
2284 boost::shared_ptr<ForcesAndSourcesCore> fe_ptr,
2285 boost::shared_ptr<MatrixDouble> u_h1_ptr,
2286 boost::shared_ptr<MatrixDouble> contact_traction_ptr,
2287 Range r, moab::Interface *post_proc_mesh_ptr,
2288 std::vector<EntityHandle> *map_gauss_pts_ptr) {
2290 auto &m_field = ep.
mField;
2291 auto contact_tree_ptr = boost::dynamic_pointer_cast<ContactTree>(fe_ptr);
2293 contact_tree_ptr, u_h1_ptr, contact_traction_ptr,
2295 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)
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.
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.