12 double circumcenter[3],
double *xi,
double *
eta);
18 for (
auto &m_sdf : sdf_map_range) {
19 if (m_sdf.second.find(fe_ent) != m_sdf.second.end())
25 template <
typename OP_PTR>
29 auto nb_gauss_pts = op_ptr->getGaussPts().size2();
31 auto ts_time = op_ptr->getTStime();
32 auto ts_time_step = op_ptr->getTStimeStep();
35 op_ptr->getFTensor1CoordsAtGaussPts(),
36 getFTensor1FromMat<3>(contact_disp), nb_gauss_pts);
38 op_ptr->getFTensor1NormalsAtGaussPts(), nb_gauss_pts);
40 ts_time_step, ts_time, nb_gauss_pts, m_spatial_coords, m_normals_at_pts,
43 ts_time_step, ts_time, nb_gauss_pts, m_spatial_coords, m_normals_at_pts,
47 if (v_sdf.size() != nb_gauss_pts)
49 "Wrong number of integration pts");
50 if (m_grad_sdf.size2() != nb_gauss_pts)
52 "Wrong number of integration pts");
53 if (m_grad_sdf.size1() != 3)
59 ts_time_step, ts_time, nb_gauss_pts, m_spatial_coords, m_normals_at_pts,
61 return std::make_tuple(block_id, m_normals_at_pts, v_sdf, m_grad_sdf,
65 return std::make_tuple(block_id, m_normals_at_pts, v_sdf, m_grad_sdf,
81 template <
typename T1>
84 std::array<double, 3> &unit_ray, std::array<double, 3> &point,
86 std::array<double, 9> &elem_point_nodes,
87 std::array<double, 9> &elem_traction_nodes,
92 auto t_unit_ray = getFTensor1FromPtr<3>(unit_ray.data());
93 auto t_point = getFTensor1FromPtr<3>(point.data());
95 auto get_normal = [](
auto &ele_coords) {
97 Tools::getTriNormal(ele_coords.data(), &t_normal(0));
101 auto t_normal = get_normal(elem_point_nodes);
102 t_normal(
i) /= t_normal.l2();
104 auto sn = t_normal(
i) * t_point(
i);
105 auto nm = t_normal(
i) * t_spatial_coords(
i);
106 auto nr = t_normal(
i) * t_unit_ray(
i);
108 auto gamma = (sn - nm) / nr;
111 t_point_current(
i) = t_spatial_coords(
i) + gamma * t_unit_ray(
i);
113 auto get_local_point_shape_functions = [&](
auto &&t_elem_coords,
115 std::array<T1, 2> loc_coords;
117 Tools::getLocalCoordinatesOnReferenceThreeNodeTri(
118 &t_elem_coords(0, 0), &t_point(0), 1, loc_coords.data()),
121 N_MBTRI1(loc_coords[0], loc_coords[1]),
122 N_MBTRI2(loc_coords[0], loc_coords[1])};
125 auto eval_position = [&](
auto &&t_field,
auto &t_shape_fun) {
129 t_point_out(
i) = t_shape_fun(
j) * t_field(
j,
i);
133 auto t_shape_fun = get_local_point_shape_functions(
134 getFTensor2FromPtr<3, 3>(elem_point_nodes.data()), t_point_current);
135 auto t_slave_point_updated = eval_position(
136 getFTensor2FromPtr<3, 3>(elem_point_nodes.data()), t_shape_fun);
137 auto t_traction_updated = eval_position(
138 getFTensor2FromPtr<3, 3>(elem_traction_nodes.data()), t_shape_fun);
140 return std::make_tuple(t_slave_point_updated, t_traction_updated, t_normal);
143 template <
typename T1>
156 template <
typename T1>
172 template <
typename T1>
176 auto [t_slave_point_current, t_slave_traction_current, t_slave_normal] =
178 auto [t_master_point_current, t_master_traction_current, t_master_normal] =
184 t_normal(
i) = t_master_normal(
i) - t_slave_normal(
i);
187 auto gap = t_normal(
i) * (t_slave_point_current(
i) - t_spatial_coords(
i));
188 auto tn_master = t_master_traction_current(
i) * t_normal(
i);
189 auto tn_slave = t_slave_traction_current(
i) * t_normal(
i);
190 auto tn = std::max(-tn_master, tn_slave);
192 return std::make_tuple(gap, tn_master, tn_slave,
194 t_master_traction_current, t_slave_traction_current);
201 template <
typename T1,
typename T2,
typename T3>
214 t_u(
i) = t_spatial_coords(
i) - t_coords(
i);
221 auto [t_slave_point_current, t_slave_traction_current, t_slave_normal] =
223 auto [t_master_point_current, t_master_traction_current, t_master_normal] =
228 t_normal(
i) = t_master_normal(
i) - t_slave_normal(
i);
233 t_P(
i,
j) = t_normal(
i) * t_normal(
j);
237 constexpr
double beta = 0.5;
244 auto f_min_gap = [
zeta](
auto d,
auto s) {
245 return 0.5 * (
d + s - std::sqrt((
d - s) * (
d - s) +
zeta));
248 auto f_diff_min_gap = [
zeta](
auto d,
auto s) {
249 return 0.5 * (1 - (
d - s) / std::sqrt((
d - s) * (
d - s) +
zeta));
253 auto f_barrier = [alpha1, alpha2, f_min_gap, f_diff_min_gap](
auto g,
257 0.5 * (tn + f_min_gap(
d, tn) + f_diff_min_gap(
d, tn) * (
d - tn));
258 auto b2 = alpha2 * f_min_gap(
g, 0) *
g;
263 t_gap_vec(
i) = beta * t_spatial_coords(
i) +
264 (1 - beta) * t_slave_point_current(
i) - t_spatial_coords(
i);
267 -beta * t_master_traction(
i) + (beta - 1) * t_slave_traction_current(
i);
269 auto t_gap = t_normal(
i) * t_gap_vec(
i);
270 auto t_tn = t_normal(
i) * t_traction_vec(
i);
271 auto barrier = f_barrier(t_gap, t_tn);
275 t_traction_bar(
i) = t_normal(
i) * barrier;
279 t_Q(
i,
j) * t_master_traction(
j) +
281 t_P(
i,
j) * (t_master_traction(
j) - t_traction_bar(
j));
284 auto is_nan_or_inf = [](
double value) ->
bool {
285 return std::isnan(value) || std::isinf(value);
288 double v = std::complex<double>(t_rhs(
i) * t_rhs(
i)).real();
289 if (is_nan_or_inf(
v)) {
291 MOFEM_LOG(
"SELF", Sev::error) <<
"t_rhs " << t_rhs;
306 const std::string row_field_name,
307 boost::shared_ptr<ContactOps::CommonData> common_data_ptr,
308 boost::shared_ptr<ContactTree> contact_tree_ptr,
309 boost::shared_ptr<std::map<int, Range>> sdf_map_range_ptr)
312 commonDataPtr(common_data_ptr), contactTreePtr(contact_tree_ptr),
313 sdfMapRangePtr(sdf_map_range_ptr) {
321 "get alpha contact failed");
325 "get alpha contact failed");
329 "get alpha contact failed");
350 const size_t nb_gauss_pts = getGaussPts().size2();
355 "Wrong number of integration pts %d != %d",
363 auto t_w = getFTensor0IntegrationWeight();
364 auto t_coords = getFTensor1CoordsAtGaussPts();
365 auto t_disp = getFTensor1FromMat<3>(
commonDataPtr->contactDisp);
366 auto t_traction = getFTensor1FromMat<3>(
commonDataPtr->contactTraction);
371 auto [block_id, m_normals_at_pts, v_sdf, m_grad_sdf, m_hess_sdf] =
376 auto t_grad_sdf_v = getFTensor1FromMat<3>(m_grad_sdf);
377 auto t_normalize_normal = getFTensor1FromMat<3>(m_normals_at_pts);
384 ++t_normalize_normal;
389 auto face_data_vec_ptr =
391 auto face_gauss_pts_it = face_data_vec_ptr->begin();
393 auto nb_base_functions = data.getN().size2();
394 auto t_base = data.getFTensor0N();
395 for (
auto gg = 0; gg != nb_gauss_pts; ++gg) {
398 auto face_data_ptr =
contactTreePtr->getFaceDataPtr(face_gauss_pts_it, gg,
401 auto check_face_contact = [&]() {
409 auto tn = t_traction(
i) * t_grad_sdf_v(
i);
412 constexpr
double c = 0;
415 if (!
c && check_face_contact()) {
417 t_spatial_coords(
i) = t_coords(
i) + t_disp(
i);
418 auto t_rhs_tmp =
multiPointRhs(face_data_ptr, t_coords, t_spatial_coords,
420 t_rhs(
i) = t_rhs_tmp(
i);
428 t_cP(
i,
j) = (
c * t_grad_sdf_v(
i)) * t_grad_sdf_v(
j);
431 t_cQ(
i,
j) * t_traction(
j) + (
c * inv_cn * t_sdf_v) * t_grad_sdf_v(
i);
433 t_rhs(
i) = t_traction(
i);
437 auto t_nf = getFTensor1FromPtr<3>(&nf[0]);
438 const double alpha = t_w * getMeasure();
441 for (; bb != nbRows / 3; ++bb) {
442 const double beta = alpha * t_base;
443 t_nf(
i) += beta * t_rhs(
i);
447 for (; bb < nb_base_functions; ++bb)
456 template <AssemblyType A>
459 boost::shared_ptr<std::vector<BrokenBaseSideData>>
460 broken_base_side_data,
461 boost::shared_ptr<ContactOps::CommonData> common_data_ptr,
462 boost::shared_ptr<ContactTree> contact_tree_ptr)
463 :
OP(broken_base_side_data), commonDataPtr(common_data_ptr),
464 contactTreePtr(contact_tree_ptr) {}
466 template <AssemblyType A>
476 const size_t nb_gauss_pts = OP::getGaussPts().size2();
479 if (commonDataPtr->contactDisp.size2() != nb_gauss_pts) {
481 "Wrong number of integration pts %d != %d",
482 commonDataPtr->contactDisp.size2(), nb_gauss_pts);
489 auto t_w = OP::getFTensor0IntegrationWeight();
490 auto t_material_normal = OP::getFTensor1NormalsAtGaussPts();
491 auto t_coords = OP::getFTensor1CoordsAtGaussPts();
493 auto t_disp = getFTensor1FromMat<3>(commonDataPtr->contactDisp);
494 auto t_traction = getFTensor1FromMat<3>(commonDataPtr->contactTraction);
504 auto face_data_vec_ptr =
505 contactTreePtr->findFaceDataVecPtr(OP::getFEEntityHandle());
506 auto face_gauss_pts_it = face_data_vec_ptr->begin();
508 auto nb_base_functions = data.getN().size2() / 3;
509 auto t_base = data.getFTensor1N<3>();
510 for (
auto gg = 0; gg != nb_gauss_pts; ++gg) {
512 auto t_nf = getFTensor1FromPtr<3>(&nf[0]);
513 const double alpha = t_w / 2.;
516 for (; bb != OP::nbRows / 3; ++bb) {
517 const double beta = alpha * t_base(
i) * t_material_normal(
i);
518 t_nf(
i) -= beta * t_disp(
i);
522 for (; bb < nb_base_functions; ++bb)
532 const std::string row_field_name,
const std::string col_field_name,
533 boost::shared_ptr<ContactOps::CommonData> common_data_ptr,
534 boost::shared_ptr<ContactTree> contact_tree_ptr,
535 boost::shared_ptr<std::map<int, Range>> sdf_map_range_ptr)
538 commonDataPtr(common_data_ptr), contactTreePtr(contact_tree_ptr),
539 sdfMapRangePtr(sdf_map_range_ptr) {
555 auto nb_rows = row_data.getIndices().size();
556 auto nb_cols = col_data.getIndices().size();
558 auto &locMat = AssemblyBoundaryEleOp::locMat;
559 locMat.resize(nb_rows, nb_cols,
false);
562 if (nb_cols && nb_rows) {
564 auto nb_gauss_pts = getGaussPts().size2();
565 auto t_w = getFTensor0IntegrationWeight();
566 auto t_coords = getFTensor1CoordsAtGaussPts();
567 auto t_disp = getFTensor1FromMat<3>(
commonDataPtr->contactDisp);
568 auto t_traction = getFTensor1FromMat<3>(
commonDataPtr->contactTraction);
571 auto [block_id, m_normals_at_pts, v_sdf, m_grad_sdf, m_hess_sdf] =
576 auto t_grad_sdf_v = getFTensor1FromMat<3>(m_grad_sdf);
577 auto t_hess_sdf_v = getFTensor2SymmetricFromMat<3>(m_hess_sdf);
578 auto t_normalized_normal = getFTensor1FromMat<3>(m_normals_at_pts);
588 ++t_normalized_normal;
591 auto face_data_vec_ptr =
593 auto face_gauss_pts_it = face_data_vec_ptr->begin();
595 auto t_row_base = row_data.getFTensor0N();
596 auto nb_face_functions = row_data.getN().size2() / 3;
599 for (
size_t gg = 0; gg != nb_gauss_pts; ++gg) {
601 auto face_data_ptr =
contactTreePtr->getFaceDataPtr(face_gauss_pts_it, gg,
604 auto check_face_contact = [&]() {
614 auto tn = t_traction(
i) * t_grad_sdf_v(
i);
617 constexpr
double c = 0;
620 if (!
c && check_face_contact()) {
622 t_spatial_coords(
i) = t_coords(
i) + t_disp(
i);
623 constexpr
double eps = std::numeric_limits<float>::epsilon();
624 for (
auto ii = 0; ii < 3; ++ii) {
626 t_spatial_coords(0), t_spatial_coords(1), t_spatial_coords(2)};
627 t_spatial_coords_cx(ii) +=
eps * 1
i;
631 for (
int jj = 0; jj != 3; ++jj) {
632 auto v = t_rhs_tmp(jj).imag();
633 t_res_dU(jj, ii) =
v /
eps;
645 (-
c) * (t_hess_sdf_v(
i,
j) * t_grad_sdf_v(
k) * t_traction(
k) +
646 t_grad_sdf_v(
i) * t_hess_sdf_v(
k,
j) * t_traction(
k))
648 + (
c * inv_cn) * (t_sdf_v * t_hess_sdf_v(
i,
j) +
650 t_grad_sdf_v(
j) * t_grad_sdf_v(
i));
657 auto alpha = t_w * getMeasure();
660 for (; rr != nb_rows / 3; ++rr) {
662 auto t_mat = getFTensor2FromArray<3, 3, 3>(locMat, 3 * rr);
663 auto t_col_base = col_data.getFTensor0N(gg, 0);
665 for (
size_t cc = 0; cc != nb_cols / 3; ++cc) {
666 auto beta = alpha * t_row_base * t_col_base;
667 t_mat(
i,
j) += beta * t_res_dU(
i,
j);
674 for (; rr < nb_face_functions; ++rr)
684 template <AssemblyType A>
687 std::string row_field_name,
688 boost::shared_ptr<std::vector<BrokenBaseSideData>>
689 broken_base_side_data,
690 boost::shared_ptr<ContactOps::CommonData> common_data_ptr,
691 boost::shared_ptr<ContactTree> contact_tree_ptr,
692 boost::shared_ptr<std::map<int, Range>> sdf_map_range_ptr)
693 :
OP(row_field_name, broken_base_side_data, false, false),
699 template <AssemblyType A>
712 auto nb_rows = row_data.getIndices().size();
713 auto nb_cols = col_data.getIndices().size();
715 auto &locMat = AssemblyBoundaryEleOp::locMat;
716 locMat.resize(nb_rows, nb_cols,
false);
719 if (nb_cols && nb_rows) {
721 const size_t nb_gauss_pts = OP::getGaussPts().size2();
723 auto t_w = OP::getFTensor0IntegrationWeight();
724 auto t_disp = getFTensor1FromMat<3>(commonDataPtr->contactDisp);
725 auto t_traction = getFTensor1FromMat<3>(commonDataPtr->contactTraction);
726 auto t_coords = OP::getFTensor1CoordsAtGaussPts();
727 auto t_material_normal = OP::getFTensor1NormalsAtGaussPts();
730 auto [block_id, m_normals_at_pts, v_sdf, m_grad_sdf, m_hess_sdf] =
731 getSdf(
this, commonDataPtr->contactDisp,
732 checkSdf(OP::getFEEntityHandle(), *sdfMapRangePtr),
false);
735 auto t_grad_sdf_v = getFTensor1FromMat<3>(m_grad_sdf);
747 auto face_data_vec_ptr =
748 contactTreePtr->findFaceDataVecPtr(OP::getFEEntityHandle());
749 auto face_gauss_pts_it = face_data_vec_ptr->begin();
751 auto t_row_base = row_data.getFTensor0N();
752 auto nb_face_functions = row_data.getN().size2();
756 for (
size_t gg = 0; gg != nb_gauss_pts; ++gg) {
758 auto face_data_ptr = contactTreePtr->getFaceDataPtr(face_gauss_pts_it, gg,
761 auto check_face_contact = [&]() {
771 auto tn = t_traction(
i) * t_grad_sdf_v(
i);
774 constexpr
double c = 0;
777 if (!
c && check_face_contact()) {
779 t_spatial_coords(
i) = t_coords(
i) + t_disp(
i);
780 constexpr
double eps = std::numeric_limits<float>::epsilon();
781 for (
auto ii = 0; ii != 3; ++ii) {
783 t_traction(0), t_traction(1), t_traction(2)};
784 t_traction_cx(ii) +=
eps * 1
i;
788 for (
int jj = 0; jj != 3; ++jj) {
789 auto v = t_rhs_tmp(jj).imag();
790 t_res_dP(jj, ii) =
v /
eps;
797 t_cP(
i,
j) = (
c * t_grad_sdf_v(
i)) * t_grad_sdf_v(
j);
799 t_res_dP(
i,
j) = t_cQ(
i,
j);
805 const double alpha = t_w / 2.;
807 for (; rr != nb_rows / 3; ++rr) {
809 auto t_mat = getFTensor2FromArray<3, 3, 3>(locMat, 3 * rr);
810 auto t_col_base = col_data.getFTensor1N<3>(gg, 0);
812 for (
size_t cc = 0; cc != nb_cols / 3; ++cc) {
813 auto col_base = t_col_base(
i) * t_material_normal(
i);
814 const double beta = alpha * t_row_base * col_base;
815 t_mat(
i,
j) += beta * t_res_dP(
i,
j);
822 for (; rr < nb_face_functions; ++rr)
832 template <AssemblyType A>
835 boost::shared_ptr<std::vector<BrokenBaseSideData>>
836 broken_base_side_data,
837 std::string col_field_name,
838 boost::shared_ptr<ContactOps::CommonData> common_data_ptr,
839 boost::shared_ptr<ContactTree> contact_tree_ptr)
840 :
OP(col_field_name, broken_base_side_data, true, true),
841 commonDataPtr(common_data_ptr), contactTreePtr(contact_tree_ptr) {
845 template <AssemblyType A>
861 auto nb_rows = row_data.getIndices().size();
862 auto nb_cols = col_data.getIndices().size();
864 auto &locMat = AssemblyBoundaryEleOp::locMat;
865 locMat.resize(nb_rows, nb_cols,
false);
868 if (nb_cols && nb_rows) {
870 const size_t nb_gauss_pts = OP::getGaussPts().size2();
872 auto t_w = OP::getFTensor0IntegrationWeight();
873 auto t_disp = getFTensor1FromMat<3>(commonDataPtr->contactDisp);
874 auto t_traction = getFTensor1FromMat<3>(commonDataPtr->contactTraction);
875 auto t_coords = OP::getFTensor1CoordsAtGaussPts();
876 auto t_material_normal = OP::getFTensor1NormalsAtGaussPts();
888 auto face_data_vec_ptr =
889 contactTreePtr->findFaceDataVecPtr(OP::getFEEntityHandle());
890 auto face_gauss_pts_it = face_data_vec_ptr->begin();
892 auto t_row_base = row_data.getFTensor1N<3>();
893 auto nb_face_functions = row_data.getN().size2() / 3;
894 for (
size_t gg = 0; gg != nb_gauss_pts; ++gg) {
896 const auto alpha = t_w / 2.;
899 for (; rr != nb_rows / 3; ++rr) {
901 auto row_base = alpha * (t_row_base(
i) * t_material_normal(
i));
903 auto t_mat = getFTensor2FromArray<3, 3, 3>(locMat, 3 * rr);
904 auto t_col_base = col_data.getFTensor0N(gg, 0);
906 for (
size_t cc = 0; cc != nb_cols / 3; ++cc) {
907 const auto beta = row_base * t_col_base;
915 for (; rr < nb_face_functions; ++rr)
922 locMat = trans(locMat);
928 boost::shared_ptr<moab::Core> core_mesh_ptr,
929 int max_order, std::map<int, Range> &&body_map)
930 :
Base(m_field, core_mesh_ptr,
"contact"), maxOrder(max_order),
933 auto ref_ele_ptr = boost::make_shared<PostProcGenerateRefMesh<MBTRI>>();
934 ref_ele_ptr->hoNodes =
939 "Error when generating reference element");
941 MOFEM_LOG(
"EP", Sev::inform) <<
"Contact hoNodes " << ref_ele_ptr->hoNodes
945 <<
"Contact maxOrder " << ref_ele_ptr->defMaxLevel;
951 MB_TAG_CREAT | MB_TAG_DENSE,
954 thBodyId, MB_TAG_CREAT | MB_TAG_DENSE,
957 const auto nb_nodes = (
refElementsMap.at(MBTRI)->hoNodes) ? 6 : 3;
977 std::array<double, 3> def_small_x{0., 0., 0.};
979 MB_TAG_CREAT | MB_TAG_DENSE,
982 MB_TAG_CREAT | MB_TAG_DENSE,
985 std::array<double, 3> def_tractions{0., 0., 0.};
987 "TRACTION", 3, MB_TYPE_DOUBLE,
thTraction, MB_TAG_CREAT | MB_TAG_DENSE,
988 &*def_tractions.begin());
993 CHKERR Base::preProcess();
1000 CHKERR Base::postProcess();
1003 PetscBarrier(
nullptr);
1005 ParallelComm *pcomm_post_proc_mesh =
1007 if (pcomm_post_proc_mesh ==
nullptr)
1012 auto brodacts = [&](
auto &brodacts_ents) {
1016 pcomm_post_proc_mesh->broadcast_entities(
1023 Range brodacts_ents;
1025 CHKERR brodacts(brodacts_ents);
1044 treeSurfPtr = boost::shared_ptr<OrientedBoxTreeTool>(
1054 boost::shared_ptr<ContactTree> contact_tree_ptr,
1055 boost::shared_ptr<ContactOps::CommonData> common_data_ptr,
1056 boost::shared_ptr<MatrixDouble> u_h1_ptr)
1057 :
UOP(
NOSPACE,
UOP::OPSPACE), contactTreePtr(contact_tree_ptr),
1058 uH1Ptr(u_h1_ptr), commonDataPtr(common_data_ptr) {}
1064 auto get_body_id = [&](
auto fe_ent) {
1066 if (
m.second.find(fe_ent) !=
m.second.end()) {
1076 auto fe_ent = getNumeredEntFiniteElementPtr()->getEnt();
1078 auto body_id = get_body_id(fe_ent);
1082 post_proc_ents, &fe_id);
1084 post_proc_ents, &body_id);
1086 auto nb_gauss_pts = getGaussPts().size2();
1087 auto t_u_h1 = getFTensor1FromMat<3>(*
uH1Ptr);
1088 auto t_u_l2 = getFTensor1FromMat<3>(
commonDataPtr->contactDisp);
1089 auto t_coords = getFTensor1CoordsAtGaussPts();
1092 auto t_x_h1 = getFTensor1FromPtr<3>(&x_h1(0, 0));
1094 auto t_x_l2 = getFTensor1FromPtr<3>(&x_l2(0, 0));
1101 for (
auto gg = 0; gg != nb_gauss_pts; ++gg) {
1102 t_x_h1(
i) = t_coords(
i) + t_u_h1(
i);
1103 t_x_l2(
i) = t_coords(
i) + t_u_l2(
i);
1112 CHKERR moab_post_proc_mesh.set_coords(
1113 &*map_gauss_pts.begin(), map_gauss_pts.size(), &*x_h1.data().begin());
1114 CHKERR moab_post_proc_mesh.tag_set_data(
1115 contactTreePtr->thSmallX, &*map_gauss_pts.begin(), map_gauss_pts.size(),
1116 &*x_h1.data().begin());
1117 CHKERR moab_post_proc_mesh.tag_set_data(
1118 contactTreePtr->thLargeX, &*map_gauss_pts.begin(), map_gauss_pts.size(),
1119 &*coords.data().begin());
1120 CHKERR moab_post_proc_mesh.tag_set_data(
1121 contactTreePtr->thTraction, &*map_gauss_pts.begin(), map_gauss_pts.size(),
1122 &*tractions.data().begin());
1128 boost::shared_ptr<ContactTree> contact_tree_ptr,
1129 boost::shared_ptr<ContactOps::CommonData> common_data_ptr,
1130 boost::shared_ptr<MatrixDouble> u_h1_ptr,
Range r,
1133 std::vector<EntityHandle> *map_gauss_pts_ptr
1136 :
UOP(
NOSPACE,
UOP::OPSPACE), contactTreePtr(contact_tree_ptr),
1137 commonDataPtr(common_data_ptr), uH1Ptr(u_h1_ptr),
1138 postProcMeshPtr(post_proc_mesh_ptr), mapGaussPtsPtr(map_gauss_pts_ptr),
1145 auto &m_field = getPtrFE()->mField;
1146 auto fe_ent = getNumeredEntFiniteElementPtr()->getEnt();
1155 const auto nb_gauss_pts = getGaussPts().size2();
1157 auto t_disp_h1 = getFTensor1FromMat<3>(*
uH1Ptr);
1158 auto t_coords = getFTensor1CoordsAtGaussPts();
1159 auto t_traction = getFTensor1FromMat<3>(
commonDataPtr->contactTraction);
1167 auto get_ele_centre = [
i](
auto t_ele_coords) {
1169 t_ele_center(
i) = 0;
1170 for (
int nn = 0; nn != 3; nn++) {
1171 t_ele_center(
i) += t_ele_coords(
i);
1174 t_ele_center(
i) /= 3;
1175 return t_ele_center;
1178 auto get_ele_radius = [
i](
auto t_ele_center,
auto t_ele_coords) {
1180 t_n0(
i) = t_ele_center(
i) - t_ele_coords(
i);
1184 auto get_face_conn = [
this](
auto face) {
1188 face, conn, num_nodes,
true),
1190 if (num_nodes != 3) {
1196 auto get_face_coords = [
this](
auto conn) {
1197 std::array<double, 9> coords;
1202 auto get_closet_face = [
this](
auto *point_ptr,
auto r) {
1204 std::vector<EntityHandle> faces_out;
1208 "get closest faces");
1212 auto get_faces_out = [
this](
auto *point_ptr,
auto *unit_ray_ptr,
auto radius,
1214 std::vector<double> distances_out;
1215 std::vector<EntityHandle> faces_out;
1220 point_ptr, unit_ray_ptr, &radius),
1222 "get closest faces");
1223 return std::make_pair(faces_out, distances_out);
1226 auto get_normal = [](
auto &ele_coords) {
1228 Tools::getTriNormal(ele_coords.data(), &t_normal(0));
1232 auto make_map = [&](
auto &face_out,
auto &face_dist,
auto &t_ray_point,
1233 auto &t_unit_ray,
auto &t_master_coord) {
1236 std::map<double, EntityHandle>
m;
1237 for (
auto ii = 0; ii != face_out.size(); ++ii) {
1238 auto face_conn = get_face_conn(face_out[ii]);
1241 t_face_normal.normalize();
1243 t_x(
i) = t_ray_point(
i) + t_unit_ray(
i) * face_dist[ii];
1246 t_x(
i) * t_face_normal(
j) - t_master_coord(
i) * t_unit_ray(
j);
1247 if (t_unit_ray(
i) * t_face_normal(
i) > std::cos(M_PI / 3)) {
1248 auto dot = std::sqrt(t_chi(
i,
j) * t_chi(
i,
j));
1249 m[dot] = face_out[ii];
1255 auto get_tag_data = [
this](
auto tag,
auto face,
auto &vec) {
1259 vec.resize(tag_length);
1265 auto create_tag = [
this](
const std::string tag_name,
const int size) {
1266 double def_VAL[] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
1270 tag_name.c_str(), size, MB_TYPE_DOUBLE,
th,
1271 MB_TAG_CREAT | MB_TAG_SPARSE, def_VAL);
1278 auto set_float_precision = [](
const double x) {
1279 if (std::abs(x) < std::numeric_limits<float>::epsilon())
1286 auto save_scal_tag = [&](
auto &
th,
auto v,
const int gg) {
1289 v = set_float_precision(
v);
1296 auto get_fe_adjacencies = [
this](
auto fe_ent) {
1299 &fe_ent, 1, 2,
false, adj_faces, moab::Interface::UNION),
1301 std::set<int> adj_ids;
1302 for (
auto f : adj_faces) {
1308 auto get_face_id = [
this](
auto face) {
1317 auto get_body_id = [
this](
auto face) {
1326 auto get_face_part = [
this](
auto face) {
1327 ParallelComm *pcomm_post_proc_mesh = ParallelComm::get_pcomm(
1331 pcomm_post_proc_mesh->part_tag(), &face, 1, &part) == MB_SUCCESS) {
1337 auto check_face = [&](
auto face,
auto fe_id,
auto part) {
1338 auto face_id = get_face_id(face);
1339 auto face_part = get_face_part(face);
1340 if (face_id == fe_id && face_part == part)
1348 auto save_vec_tag = [&](
auto &
th,
auto &t_d,
const int gg) {
1352 for (
auto &
a :
v.data())
1353 a = set_float_precision(
a);
1355 &*
v.data().begin());
1360 Tag th_mark = create_tag(
"contact_mark", 1);
1361 Tag th_mark_slave = create_tag(
"contact_mark_slave", 1);
1362 Tag th_body_id = create_tag(
"contact_body_id", 1);
1363 Tag th_gap = create_tag(
"contact_gap", 1);
1364 Tag th_tn_master = create_tag(
"contact_tn_master", 1);
1365 Tag th_tn_slave = create_tag(
"contact_tn_slave", 1);
1366 Tag th_contact_traction = create_tag(
"contact_traction", 3);
1367 Tag th_contact_traction_master = create_tag(
"contact_traction_master", 3);
1368 Tag th_contact_traction_slave = create_tag(
"contact_traction_slave", 3);
1369 Tag th_c = create_tag(
"contact_c", 1);
1370 Tag th_normal = create_tag(
"contact_normal", 3);
1371 Tag th_dist = create_tag(
"contact_dip", 3);
1373 auto t_ele_centre = get_ele_centre(getFTensor1Coords());
1374 auto ele_radius = get_ele_radius(t_ele_centre, getFTensor1Coords());
1380 auto adj_fe_ids = get_fe_adjacencies(fe_ent);
1382 for (
auto gg = 0; gg != nb_gauss_pts; ++gg) {
1385 t_spatial_coords(
i) = t_coords(
i) + t_disp_h1(
i);
1388 CHKERR save_vec_tag(th_contact_traction, t_traction, gg);
1391 auto faces_close = get_closet_face(&t_spatial_coords(0), ele_radius);
1392 for (
auto face_close : faces_close) {
1393 if (check_face(face_close, fe_id, m_field.get_comm_rank())) {
1395 auto body_id = get_body_id(face_close);
1397 auto master_face_conn = get_face_conn(face_close);
1398 std::array<double, 9> master_coords;
1401 master_coords.data());
1402 std::array<double, 9> master_traction;
1405 master_traction.data());
1406 auto t_normal_face_close = get_normal(master_coords);
1407 t_normal_face_close.normalize();
1411 CHKERR save_scal_tag(th_mark,
m, gg);
1412 CHKERR save_scal_tag(th_body_id,
static_cast<double>(body_id), gg);
1413 CHKERR save_vec_tag(th_normal, t_normal_face_close, gg);
1414 CHKERR save_vec_tag(th_contact_traction, t_traction, gg);
1418 t_unit_ray(
i) = -t_normal_face_close(
i);
1421 t_spatial_coords(
i) -
1424 constexpr
double eps = 1e-3;
1425 auto [faces_out, faces_dist] =
1426 get_faces_out(&t_ray_point(0), &t_unit_ray(0),
1430 auto m = make_map(faces_out, faces_dist, t_ray_point, t_unit_ray,
1432 for (
auto m_it =
m.begin(); m_it !=
m.end(); ++m_it) {
1433 auto face = m_it->second;
1434 if (face != face_close) {
1438 body_id != get_body_id(face) &&
1439 (adj_fe_ids.find(get_face_id(face)) == adj_fe_ids.end() ||
1440 get_face_part(face) != m_field.get_comm_rank())
1445 shadow_vec.back().gaussPtNb = gg;
1447 auto slave_face_conn = get_face_conn(face);
1448 std::array<double, 9> slave_coords;
1451 slave_coords.data());
1452 auto t_normal_face = get_normal(slave_coords);
1453 std::array<double, 9> slave_tractions;
1456 slave_tractions.data());
1458 auto t_master_point =
1459 getFTensor1FromPtr<3>(shadow_vec.back().masterPoint.data());
1460 auto t_slave_point =
1461 getFTensor1FromPtr<3>(shadow_vec.back().slavePoint.data());
1462 auto t_ray_point_data =
1463 getFTensor1FromPtr<3>(shadow_vec.back().rayPoint.data());
1464 auto t_unit_ray_data =
1465 getFTensor1FromPtr<3>(shadow_vec.back().unitRay.data());
1467 t_slave_point(
i) = t_ray_point(
i) + m_it->first * t_unit_ray(
i);
1469 auto eval_position = [&](
auto &&t_elem_coords,
auto &&t_point) {
1470 std::array<double, 2> loc_coords;
1472 Tools::getLocalCoordinatesOnReferenceThreeNodeTri(
1473 &t_elem_coords(0, 0), &t_point(0), 1,
1475 "get local coords");
1484 t_point_out(
i) = t_shape_fun(
j) * t_elem_coords(
j,
i);
1488 auto t_master_point_updated = eval_position(
1489 getFTensor2FromPtr<3, 3>(master_coords.data()),
1490 getFTensor1FromPtr<3>(shadow_vec.back().masterPoint.data()));
1491 t_master_point(
i) = t_master_point_updated(
i);
1493 auto t_slave_point_updated = eval_position(
1494 getFTensor2FromPtr<3, 3>(slave_coords.data()),
1495 getFTensor1FromPtr<3>(shadow_vec.back().slavePoint.data()));
1496 t_slave_point(
i) = t_slave_point_updated(
i);
1498 t_ray_point_data(
i) = t_ray_point(
i);
1499 t_unit_ray_data(
i) = t_unit_ray(
i);
1501 std::copy(master_coords.begin(), master_coords.end(),
1502 shadow_vec.back().masterPointNodes.begin());
1503 std::copy(master_traction.begin(), master_traction.end(),
1504 shadow_vec.back().masterTractionNodes.begin());
1505 std::copy(slave_coords.begin(), slave_coords.end(),
1506 shadow_vec.back().slavePointNodes.begin());
1507 std::copy(slave_tractions.begin(), slave_tractions.end(),
1508 shadow_vec.back().slaveTractionNodes.begin());
1510 shadow_vec.back().eleRadius = ele_radius;
1520 auto [gap, tn_master, tn_slave,
c, t_master_traction,
1522 multiGetGap(&(shadow_vec.back()), t_spatial_coords);
1524 t_gap_vec(
i) = t_slave_point(
i) - t_spatial_coords(
i);
1525 CHKERR save_scal_tag(th_gap, gap, gg);
1526 CHKERR save_scal_tag(th_tn_master, tn_master, gg);
1527 CHKERR save_scal_tag(th_tn_slave, tn_slave, gg);
1528 CHKERR save_scal_tag(th_c,
c, gg);
1530 CHKERR save_scal_tag(th_mark_slave,
m, gg);
1531 CHKERR save_vec_tag(th_dist, t_gap_vec, gg);
1532 CHKERR save_vec_tag(th_contact_traction_master,
1533 t_master_traction, gg);
1534 CHKERR save_vec_tag(th_contact_traction_slave, t_slave_traction,