v0.14.0
EshelbianContact.cpp
Go to the documentation of this file.
1 /**
2  * @file EshelbianContact.cpp
3  * @brief
4  * @date 2023-05-13
5  *
6  * @copyright Copyright (c) 2023
7  *
8  */
9 
10 extern "C" {
11 void tricircumcenter3d_tp(double a[3], double b[3], double c[3],
12  double circumcenter[3], double *xi, double *eta);
13 }
14 
15 namespace EshelbianPlasticity {
16 
17 auto checkSdf(EntityHandle fe_ent, std::map<int, Range> &sdf_map_range) {
18  for (auto &m_sdf : sdf_map_range) {
19  if (m_sdf.second.find(fe_ent) != m_sdf.second.end())
20  return m_sdf.first;
21  }
22  return -1;
23 }
24 
25 template <typename OP_PTR>
26 auto getSdf(OP_PTR op_ptr, MatrixDouble &contact_disp, int block_id,
27  bool eval_hessian) {
28 
29  auto nb_gauss_pts = op_ptr->getGaussPts().size2();
30 
31  auto ts_time = op_ptr->getTStime();
32  auto ts_time_step = op_ptr->getTStimeStep();
33 
34  auto m_spatial_coords = ContactOps::get_spatial_coords(
35  op_ptr->getFTensor1CoordsAtGaussPts(),
36  getFTensor1FromMat<3>(contact_disp), nb_gauss_pts);
37  auto m_normals_at_pts = ContactOps::get_normalize_normals(
38  op_ptr->getFTensor1NormalsAtGaussPts(), nb_gauss_pts);
40  ts_time_step, ts_time, nb_gauss_pts, m_spatial_coords, m_normals_at_pts,
41  block_id);
43  ts_time_step, ts_time, nb_gauss_pts, m_spatial_coords, m_normals_at_pts,
44  block_id);
45 
46 #ifndef NDEBUG
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)
54  CHK_THROW_MESSAGE(MOFEM_DATA_INCONSISTENCY, "Should be size of 3");
55 #endif // NDEBUG
56 
57  if (eval_hessian) {
59  ts_time_step, ts_time, nb_gauss_pts, m_spatial_coords, m_normals_at_pts,
60  block_id);
61  return std::make_tuple(block_id, m_normals_at_pts, v_sdf, m_grad_sdf,
62  m_hess_sdf);
63  } else {
64 
65  return std::make_tuple(block_id, m_normals_at_pts, v_sdf, m_grad_sdf,
66  MatrixDouble(6, nb_gauss_pts, 0.));
67  }
68 };
69 
70 /**
71  * @brief Calculate points data on contact surfaces
72  *
73  * @tparam T1
74  * @param unit_ray
75  * @param point
76  * @param elem_point_nodes
77  * @param elem_traction_nodes
78  * @param t_spatial_coords
79  * @return auto
80  */
81 template <typename T1>
83 
84  std::array<double, 3> &unit_ray, std::array<double, 3> &point,
85 
86  std::array<double, 9> &elem_point_nodes,
87  std::array<double, 9> &elem_traction_nodes,
88 
89  FTensor::Tensor1<T1, 3> &t_spatial_coords) {
91 
92  auto t_unit_ray = getFTensor1FromPtr<3>(unit_ray.data());
93  auto t_point = getFTensor1FromPtr<3>(point.data());
94 
95  auto get_normal = [](auto &ele_coords) {
97  Tools::getTriNormal(ele_coords.data(), &t_normal(0));
98  return t_normal;
99  };
100 
101  auto t_normal = get_normal(elem_point_nodes);
102  t_normal(i) /= t_normal.l2();
103 
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);
107 
108  auto gamma = (sn - nm) / nr;
109 
110  FTensor::Tensor1<T1, 3> t_point_current;
111  t_point_current(i) = t_spatial_coords(i) + gamma * t_unit_ray(i);
112 
113  auto get_local_point_shape_functions = [&](auto &&t_elem_coords,
114  auto &t_point) {
115  std::array<T1, 2> loc_coords;
117  Tools::getLocalCoordinatesOnReferenceThreeNodeTri(
118  &t_elem_coords(0, 0), &t_point(0), 1, loc_coords.data()),
119  "get local coords");
120  return FTensor::Tensor1<T1, 3>{N_MBTRI0(loc_coords[0], loc_coords[1]),
121  N_MBTRI1(loc_coords[0], loc_coords[1]),
122  N_MBTRI2(loc_coords[0], loc_coords[1])};
123  };
124 
125  auto eval_position = [&](auto &&t_field, auto &t_shape_fun) {
128  FTensor::Tensor1<T1, 3> t_point_out;
129  t_point_out(i) = t_shape_fun(j) * t_field(j, i);
130  return t_point_out;
131  };
132 
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);
139 
140  return std::make_tuple(t_slave_point_updated, t_traction_updated, t_normal);
141 };
142 
143 template <typename T1>
145 
146  ContactTree::FaceData *face_data_ptr,
147  FTensor::Tensor1<T1, 3> &t_spatial_coords
148 
149 ) {
150 
151  return multiPoint(face_data_ptr->unitRay, face_data_ptr->masterPoint,
152  face_data_ptr->masterPointNodes,
153  face_data_ptr->masterTractionNodes, t_spatial_coords);
154 };
155 
156 template <typename T1>
158 
159  ContactTree::FaceData *face_data_ptr,
160  FTensor::Tensor1<T1, 3> &t_spatial_coords
161 
162 ) {
163 
164  return multiPoint(face_data_ptr->unitRay, face_data_ptr->slavePoint,
165  face_data_ptr->slavePointNodes,
166  face_data_ptr->slaveTractionNodes, t_spatial_coords);
167 };
168 
169 /**
170  * Evaluate gap and tractions between master and slave points
171 */
172 template <typename T1>
173 auto multiGetGap(ContactTree::FaceData *face_data_ptr,
174  FTensor::Tensor1<T1, 3> &t_spatial_coords) {
175 
176  auto [t_slave_point_current, t_slave_traction_current, t_slave_normal] =
177  multiSlavePoint(face_data_ptr, t_spatial_coords);
178  auto [t_master_point_current, t_master_traction_current, t_master_normal] =
179  multiMasterPoint(face_data_ptr, t_spatial_coords);
180 
182 
184  t_normal(i) = t_master_normal(i) - t_slave_normal(i);
185  t_normal.normalize();
186 
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);
191 
192  return std::make_tuple(gap, tn_master, tn_slave,
193  ContactOps::constrain(gap, tn),
194  t_master_traction_current, t_slave_traction_current);
195 };
196 
198 
199 /** Caluclate rhs term for contact
200  */
201 template <typename T1, typename T2, typename T3>
203 
204  ContactTree::FaceData *face_data_ptr, FTensor::Tensor1<T1, 3> &t_coords,
205  FTensor::Tensor1<T2, 3> &t_spatial_coords,
206  FTensor::Tensor1<T3, 3> &t_master_traction, MultiPointRhsType type,
207  bool debug = false
208 
209 ) {
212 
214  t_u(i) = t_spatial_coords(i) - t_coords(i);
215 
217 
218  switch (type) {
219  case MultiPointRhsType::U: {
220 
221  auto [t_slave_point_current, t_slave_traction_current, t_slave_normal] =
222  multiSlavePoint(face_data_ptr, t_spatial_coords);
223  auto [t_master_point_current, t_master_traction_current, t_master_normal] =
224  multiMasterPoint(face_data_ptr, t_spatial_coords);
225 
226  // average normal surface
228  t_normal(i) = t_master_normal(i) - t_slave_normal(i);
229  t_normal.normalize();
230 
231  // get projection operators
233  t_P(i, j) = t_normal(i) * t_normal(j);
235  t_Q(i, j) = kronecker_delta(i, j) - t_P(i, j);
236 
237  constexpr double beta = 0.5;
238 
239  auto zeta = 1e-8 * face_data_ptr->eleRadius;
240  auto alpha1 = ContactOps::alpha_contact_const;
242 
243  // this is regularised std::min(d,s)
244  auto f_min_gap = [zeta](auto d, auto s) {
245  return 0.5 * (d + s - std::sqrt((d - s) * (d - s) + zeta));
246  };
247  // this derivative of regularised std::min(d,s)
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));
250  };
251 
252  // add penalty on penetration side
253  auto f_barrier = [alpha1, alpha2, f_min_gap, f_diff_min_gap](auto g,
254  auto tn) {
255  auto d = alpha1 * g;
256  auto b1 =
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;
259  return b1 - b2;
260  };
261 
262  FTensor::Tensor1<T2, 3> t_gap_vec;
263  t_gap_vec(i) = beta * t_spatial_coords(i) +
264  (1 - beta) * t_slave_point_current(i) - t_spatial_coords(i);
266  t_traction_vec(i) =
267  -beta * t_master_traction(i) + (beta - 1) * t_slave_traction_current(i);
268 
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);
272 
274  // add penalty on penetration side
275  t_traction_bar(i) = t_normal(i) * barrier;
276 
277  t_rhs(i) =
278 
279  t_Q(i, j) * t_master_traction(j) +
280 
281  t_P(i, j) * (t_master_traction(j) - t_traction_bar(j));
282 
283  if (debug) {
284  auto is_nan_or_inf = [](double value) -> bool {
285  return std::isnan(value) || std::isinf(value);
286  };
287 
288  double v = std::complex<double>(t_rhs(i) * t_rhs(i)).real();
289  if (is_nan_or_inf(v)) {
290  MOFEM_LOG_CHANNEL("SELF");
291  MOFEM_LOG("SELF", Sev::error) << "t_rhs " << t_rhs;
292  CHK_MOAB_THROW(MOFEM_DATA_INCONSISTENCY, "rhs is nan or inf");
293  }
294  }
295 
296  } break;
298  CHK_THROW_MESSAGE(MOFEM_DATA_INCONSISTENCY, "not implemented");
299  break;
300  }
301 
302  return t_rhs;
303 };
304 
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)
310  : ContactOps::AssemblyBoundaryEleOp(row_field_name, row_field_name,
311  ContactOps::BoundaryEleOp::OPROW),
312  commonDataPtr(common_data_ptr), contactTreePtr(contact_tree_ptr),
313  sdfMapRangePtr(sdf_map_range_ptr) {
314  CHK_THROW_MESSAGE(PetscOptionsGetScalar(PETSC_NULL, "", "-cn",
315  &ContactOps::cn_contact, PETSC_NULL),
316  "get cn failed");
319  PetscOptionsGetScalar(PETSC_NULL, "", "-alpha_contact_const",
320  &ContactOps::alpha_contact_const, PETSC_NULL),
321  "get alpha contact failed");
323  PetscOptionsGetScalar(PETSC_NULL, "", "-alpha_contact_quadratic",
325  "get alpha contact failed");
327  PetscOptionsGetScalar(PETSC_NULL, "", "-airplane_ray_distance",
328  &ContactOps::airplane_ray_distance, PETSC_NULL),
329  "get alpha contact failed");
330 
331 
332  MOFEM_LOG("EP", Sev::inform) << "cn " << ContactOps::cn_contact;
333  MOFEM_LOG("EP", Sev::inform)
334  << "alpha_contact_const " << ContactOps::alpha_contact_const;
335  MOFEM_LOG("EP", Sev::inform)
336  << "alpha_contact_quadratic " << ContactOps::alpha_contact_quadratic;
337  MOFEM_LOG("EP", Sev::inform)
338  << "airplane_ray_distance " << ContactOps::airplane_ray_distance;
339 }
340 
344 
349 
350  const size_t nb_gauss_pts = getGaussPts().size2();
351 
352 #ifndef NDEBUG
353  if (commonDataPtr->contactDisp.size2() != nb_gauss_pts) {
354  SETERRQ2(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
355  "Wrong number of integration pts %d != %d",
356  commonDataPtr->contactDisp.size2(), nb_gauss_pts);
357  }
358 #endif // !NDEBUG
359 
360  auto &nf = locF;
361  locF.clear();
362 
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);
367 
368  // placeholder to pass boundary block id to python. default SDF is set on
369  // block = -1, one can choose different block by making block "CONTACT_SDF",
370  // then specific SDF can be set to that block.
371  auto [block_id, m_normals_at_pts, v_sdf, m_grad_sdf, m_hess_sdf] =
372  getSdf(this, commonDataPtr->contactDisp,
373  checkSdf(getFEEntityHandle(), *sdfMapRangePtr), false);
374 
375  auto t_sdf_v = getFTensor0FromVec(v_sdf);
376  auto t_grad_sdf_v = getFTensor1FromMat<3>(m_grad_sdf);
377  auto t_normalize_normal = getFTensor1FromMat<3>(m_normals_at_pts);
378 
379  auto next = [&]() {
380  ++t_w;
381  ++t_coords;
382  ++t_disp;
383  ++t_traction;
384  ++t_normalize_normal;
385  ++t_sdf_v;
386  ++t_grad_sdf_v;
387  };
388 
389  auto face_data_vec_ptr =
390  contactTreePtr->findFaceDataVecPtr(getFEEntityHandle());
391  auto face_gauss_pts_it = face_data_vec_ptr->begin();
392 
393  auto nb_base_functions = data.getN().size2();
394  auto t_base = data.getFTensor0N();
395  for (auto gg = 0; gg != nb_gauss_pts; ++gg) {
396 
398  auto face_data_ptr = contactTreePtr->getFaceDataPtr(face_gauss_pts_it, gg,
399  face_data_vec_ptr);
400 
401  auto check_face_contact = [&]() {
402  if (face_data_ptr) {
403  return true;
404  }
405  return false;
406  };
407 
408 #ifdef PYTHON_SDF
409  auto tn = t_traction(i) * t_grad_sdf_v(i);
410  auto c = ContactOps::constrain(t_sdf_v, tn);
411 #else
412  constexpr double c = 0;
413 #endif
414 
415  if (!c && check_face_contact()) {
416  FTensor::Tensor1<double, 3> t_spatial_coords;
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,
419  t_traction, MultiPointRhsType::U, true);
420  t_rhs(i) = t_rhs_tmp(i);
421 
422  } else {
423 
424 #ifdef PYTHON_SDF
425  auto inv_cn = ContactOps::alpha_contact_const;
426 
428  t_cP(i, j) = (c * t_grad_sdf_v(i)) * t_grad_sdf_v(j);
429  t_cQ(i, j) = kronecker_delta(i, j) - t_cP(i, j);
430  t_rhs(i) =
431  t_cQ(i, j) * t_traction(j) + (c * inv_cn * t_sdf_v) * t_grad_sdf_v(i);
432 #else
433  t_rhs(i) = t_traction(i);
434 #endif
435  }
436 
437  auto t_nf = getFTensor1FromPtr<3>(&nf[0]);
438  const double alpha = t_w * getMeasure();
439 
440  size_t bb = 0;
441  for (; bb != nbRows / 3; ++bb) {
442  const double beta = alpha * t_base;
443  t_nf(i) += beta * t_rhs(i);
444  ++t_nf;
445  ++t_base;
446  }
447  for (; bb < nb_base_functions; ++bb)
448  ++t_base;
449 
450  next();
451  }
452 
454 }
455 
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) {}
465 
466 template <AssemblyType A>
470 
475 
476  const size_t nb_gauss_pts = OP::getGaussPts().size2();
477 
478 #ifndef NDEBUG
479  if (commonDataPtr->contactDisp.size2() != nb_gauss_pts) {
480  SETERRQ2(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
481  "Wrong number of integration pts %d != %d",
482  commonDataPtr->contactDisp.size2(), nb_gauss_pts);
483  }
484 #endif // !NDEBUG
485 
486  auto &nf = OP::locF;
487  OP::locF.clear();
488 
489  auto t_w = OP::getFTensor0IntegrationWeight();
490  auto t_material_normal = OP::getFTensor1NormalsAtGaussPts();
491  auto t_coords = OP::getFTensor1CoordsAtGaussPts();
492 
493  auto t_disp = getFTensor1FromMat<3>(commonDataPtr->contactDisp);
494  auto t_traction = getFTensor1FromMat<3>(commonDataPtr->contactTraction);
495 
496  auto next = [&]() {
497  ++t_w;
498  ++t_disp;
499  ++t_traction;
500  ++t_coords;
501  ++t_material_normal;
502  };
503 
504  auto face_data_vec_ptr =
505  contactTreePtr->findFaceDataVecPtr(OP::getFEEntityHandle());
506  auto face_gauss_pts_it = face_data_vec_ptr->begin();
507 
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) {
511 
512  auto t_nf = getFTensor1FromPtr<3>(&nf[0]);
513  const double alpha = t_w / 2.;
514 
515  size_t bb = 0;
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);
519  ++t_nf;
520  ++t_base;
521  }
522  for (; bb < nb_base_functions; ++bb)
523  ++t_base;
524 
525  next();
526  }
527 
529 }
530 
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)
536  : ContactOps::AssemblyBoundaryEleOp(row_field_name, col_field_name,
537  ContactOps::BoundaryEleOp::OPROWCOL),
538  commonDataPtr(common_data_ptr), contactTreePtr(contact_tree_ptr),
539  sdfMapRangePtr(sdf_map_range_ptr) {
540 
541  sYmm = false;
542 }
543 
546  EntitiesFieldData::EntData &col_data) {
548 
549  using namespace ContactOps;
550 
554 
555  auto nb_rows = row_data.getIndices().size();
556  auto nb_cols = col_data.getIndices().size();
557 
558  auto &locMat = AssemblyBoundaryEleOp::locMat;
559  locMat.resize(nb_rows, nb_cols, false);
560  locMat.clear();
561 
562  if (nb_cols && nb_rows) {
563 
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);
569 
570  // placeholder to pass boundary block id to python
571  auto [block_id, m_normals_at_pts, v_sdf, m_grad_sdf, m_hess_sdf] =
572  getSdf(this, commonDataPtr->contactDisp,
573  checkSdf(getFEEntityHandle(), *sdfMapRangePtr), true);
574 
575  auto t_sdf_v = getFTensor0FromVec(v_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);
579 
580  auto next = [&]() {
581  ++t_w;
582  ++t_coords;
583  ++t_disp;
584  ++t_traction;
585  ++t_sdf_v;
586  ++t_grad_sdf_v;
587  ++t_hess_sdf_v;
588  ++t_normalized_normal;
589  };
590 
591  auto face_data_vec_ptr =
592  contactTreePtr->findFaceDataVecPtr(getFEEntityHandle());
593  auto face_gauss_pts_it = face_data_vec_ptr->begin();
594 
595  auto t_row_base = row_data.getFTensor0N();
596  auto nb_face_functions = row_data.getN().size2() / 3;
597  constexpr auto t_kd = FTensor::Kronecker_Delta<int>();
598 
599  for (size_t gg = 0; gg != nb_gauss_pts; ++gg) {
600 
601  auto face_data_ptr = contactTreePtr->getFaceDataPtr(face_gauss_pts_it, gg,
602  face_data_vec_ptr);
603 
604  auto check_face_contact = [&]() {
605  if (face_data_ptr) {
606  return true;
607  }
608  return false;
609  };
610 
612 
613 #ifdef PYTHON_SDF
614  auto tn = t_traction(i) * t_grad_sdf_v(i);
615  auto c = ContactOps::constrain(t_sdf_v, tn);
616 #else
617  constexpr double c = 0;
618 #endif
619 
620  if (!c && check_face_contact()) {
621  FTensor::Tensor1<double, 3> t_spatial_coords;
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) {
625  FTensor::Tensor1<std::complex<double>, 3> t_spatial_coords_cx{
626  t_spatial_coords(0), t_spatial_coords(1), t_spatial_coords(2)};
627  t_spatial_coords_cx(ii) += eps * 1i;
628  auto t_rhs_tmp =
629  multiPointRhs(face_data_ptr, t_coords, t_spatial_coords_cx,
630  t_traction, MultiPointRhsType::U);
631  for (int jj = 0; jj != 3; ++jj) {
632  auto v = t_rhs_tmp(jj).imag();
633  t_res_dU(jj, ii) = v / eps;
634  }
635  }
636 
637  } else {
638 
639 #ifdef PYTHON_SDF
640 
641  auto inv_cn = ContactOps::alpha_contact_const;
642 
643  t_res_dU(i, j) =
644 
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))
647 
648  + (c * inv_cn) * (t_sdf_v * t_hess_sdf_v(i, j) +
649 
650  t_grad_sdf_v(j) * t_grad_sdf_v(i));
651 
652 #else
653  t_res_dU(i, j) = 0;
654 #endif
655  }
656 
657  auto alpha = t_w * getMeasure();
658 
659  size_t rr = 0;
660  for (; rr != nb_rows / 3; ++rr) {
661 
662  auto t_mat = getFTensor2FromArray<3, 3, 3>(locMat, 3 * rr);
663  auto t_col_base = col_data.getFTensor0N(gg, 0);
664 
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);
668  ++t_col_base;
669  ++t_mat;
670  }
671 
672  ++t_row_base;
673  }
674  for (; rr < nb_face_functions; ++rr)
675  ++t_row_base;
676 
677  next();
678  }
679  }
680 
682 }
683 
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),
694  commonDataPtr(common_data_ptr), contactTreePtr(contact_tree_ptr),
695  sdfMapRangePtr(sdf_map_range_ptr) {
696  OP::sYmm = false;
697 }
698 
699 template <AssemblyType A>
702  EntitiesFieldData::EntData &row_data,
703  EntitiesFieldData::EntData &col_data) {
705 
706  using namespace ContactOps;
707 
711 
712  auto nb_rows = row_data.getIndices().size();
713  auto nb_cols = col_data.getIndices().size();
714 
715  auto &locMat = AssemblyBoundaryEleOp::locMat;
716  locMat.resize(nb_rows, nb_cols, false);
717  locMat.clear();
718 
719  if (nb_cols && nb_rows) {
720 
721  const size_t nb_gauss_pts = OP::getGaussPts().size2();
722 
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();
728 
729  // placeholder to pass boundary block id to python
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);
733 
734  auto t_sdf_v = getFTensor0FromVec(v_sdf);
735  auto t_grad_sdf_v = getFTensor1FromMat<3>(m_grad_sdf);
736 
737  auto next = [&]() {
738  ++t_w;
739  ++t_disp;
740  ++t_traction;
741  ++t_coords;
742  ++t_material_normal;
743  ++t_sdf_v;
744  ++t_grad_sdf_v;
745  };
746 
747  auto face_data_vec_ptr =
748  contactTreePtr->findFaceDataVecPtr(OP::getFEEntityHandle());
749  auto face_gauss_pts_it = face_data_vec_ptr->begin();
750 
751  auto t_row_base = row_data.getFTensor0N();
752  auto nb_face_functions = row_data.getN().size2();
753 
754  constexpr auto t_kd = FTensor::Kronecker_Delta<int>();
755 
756  for (size_t gg = 0; gg != nb_gauss_pts; ++gg) {
757 
758  auto face_data_ptr = contactTreePtr->getFaceDataPtr(face_gauss_pts_it, gg,
759  face_data_vec_ptr);
760 
761  auto check_face_contact = [&]() {
762  if (face_data_ptr) {
763  return true;
764  }
765  return false;
766  };
767 
769 
770 #ifdef PYTHON_SDF
771  auto tn = t_traction(i) * t_grad_sdf_v(i);
772  auto c = ContactOps::constrain(t_sdf_v, tn);
773 #else
774  constexpr double c = 0;
775 #endif
776 
777  if (!c && check_face_contact()) {
778  FTensor::Tensor1<double, 3> t_spatial_coords;
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) {
782  FTensor::Tensor1<std::complex<double>, 3> t_traction_cx{
783  t_traction(0), t_traction(1), t_traction(2)};
784  t_traction_cx(ii) += eps * 1i;
785  auto t_rhs_tmp =
786  multiPointRhs(face_data_ptr, t_coords, t_spatial_coords,
787  t_traction_cx, MultiPointRhsType::U);
788  for (int jj = 0; jj != 3; ++jj) {
789  auto v = t_rhs_tmp(jj).imag();
790  t_res_dP(jj, ii) = v / eps;
791  }
792  }
793  } else {
794 
795 #ifdef PYTHON_SDF
797  t_cP(i, j) = (c * t_grad_sdf_v(i)) * t_grad_sdf_v(j);
798  t_cQ(i, j) = kronecker_delta(i, j) - t_cP(i, j);
799  t_res_dP(i, j) = t_cQ(i, j);
800 #else
801  t_res_dP(i, j) = t_kd(i, j);
802 #endif
803  }
804 
805  const double alpha = t_w / 2.;
806  size_t rr = 0;
807  for (; rr != nb_rows / 3; ++rr) {
808 
809  auto t_mat = getFTensor2FromArray<3, 3, 3>(locMat, 3 * rr);
810  auto t_col_base = col_data.getFTensor1N<3>(gg, 0);
811 
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);
816  ++t_col_base;
817  ++t_mat;
818  }
819 
820  ++t_row_base;
821  }
822  for (; rr < nb_face_functions; ++rr)
823  ++t_row_base;
824 
825  next();
826  }
827  }
828 
830 }
831 
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) {
842  OP::sYmm = false;
843 }
844 
845 template <AssemblyType A>
848  EntitiesFieldData::EntData &col_data,
849  EntitiesFieldData::EntData &row_data) {
851 
852  // Note: col_data and row_data are swapped in this function, we going to
853  // transpose locMat at the end
854 
855  using namespace ContactOps;
856 
860 
861  auto nb_rows = row_data.getIndices().size();
862  auto nb_cols = col_data.getIndices().size();
863 
864  auto &locMat = AssemblyBoundaryEleOp::locMat;
865  locMat.resize(nb_rows, nb_cols, false);
866  locMat.clear();
867 
868  if (nb_cols && nb_rows) {
869 
870  const size_t nb_gauss_pts = OP::getGaussPts().size2();
871 
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();
877 
878  auto next = [&]() {
879  ++t_w;
880  ++t_disp;
881  ++t_traction;
882  ++t_coords;
883  ++t_material_normal;
884  };
885 
886  constexpr auto t_kd = FTensor::Kronecker_Delta<int>();
887 
888  auto face_data_vec_ptr =
889  contactTreePtr->findFaceDataVecPtr(OP::getFEEntityHandle());
890  auto face_gauss_pts_it = face_data_vec_ptr->begin();
891 
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) {
895 
896  const auto alpha = t_w / 2.;
897 
898  size_t rr = 0;
899  for (; rr != nb_rows / 3; ++rr) {
900 
901  auto row_base = alpha * (t_row_base(i) * t_material_normal(i));
902 
903  auto t_mat = getFTensor2FromArray<3, 3, 3>(locMat, 3 * rr);
904  auto t_col_base = col_data.getFTensor0N(gg, 0);
905 
906  for (size_t cc = 0; cc != nb_cols / 3; ++cc) {
907  const auto beta = row_base * t_col_base;
908  t_mat(i, j) -= beta * t_kd(i, j);
909  ++t_col_base;
910  ++t_mat;
911  }
912 
913  ++t_row_base;
914  }
915  for (; rr < nb_face_functions; ++rr)
916  ++t_row_base;
917 
918  next();
919  }
920  }
921 
922  locMat = trans(locMat);
923 
925 }
926 
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),
931  bodyMap(body_map) {
932 
933  auto ref_ele_ptr = boost::make_shared<PostProcGenerateRefMesh<MBTRI>>();
934  ref_ele_ptr->hoNodes =
935  PETSC_FALSE; ///< So far only linear geometry is implemented for contact
936 
937  CHK_THROW_MESSAGE(ref_ele_ptr->getOptions(optionsPrefix), "getOptions");
938  CHK_THROW_MESSAGE(ref_ele_ptr->generateReferenceElementMesh(),
939  "Error when generating reference element");
940 
941  MOFEM_LOG("EP", Sev::inform) << "Contact hoNodes " << ref_ele_ptr->hoNodes
942  ? "true"
943  : "false";
944  MOFEM_LOG("EP", Sev::inform)
945  << "Contact maxOrder " << ref_ele_ptr->defMaxLevel;
946 
947  refElementsMap[MBTRI] = ref_ele_ptr;
948 
949  int def_ele_id = -1;
950  CHKERR getPostProcMesh().tag_get_handle("ELE_ID", 1, MB_TYPE_INTEGER, thEleId,
951  MB_TAG_CREAT | MB_TAG_DENSE,
952  &def_ele_id);
953  CHKERR getPostProcMesh().tag_get_handle("BODY_ID", 1, MB_TYPE_INTEGER,
954  thBodyId, MB_TAG_CREAT | MB_TAG_DENSE,
955  &def_ele_id);
956 
957  const auto nb_nodes = (refElementsMap.at(MBTRI)->hoNodes) ? 6 : 3;
958  const auto nb_bases = NBVOLUMETET_L2(maxOrder);
959 
960  // std::vector<int> def_ids(3 * nb_bases, 0);
961  // CHKERR getPostProcMesh().tag_get_handle("IDS", 3 * nb_bases,
962  // MB_TYPE_INTEGER,
963  // thIds, MB_TAG_CREAT | MB_TAG_DENSE,
964  // &*def_ids.begin());
965  // std::vector<double> def_coeffs(3 * nb_bases, 0);
966  // CHKERR getPostProcMesh().tag_get_handle("COEFF", 3 * nb_bases,
967  // MB_TYPE_DOUBLE,
968  // thCoeff, MB_TAG_CREAT |
969  // MB_TAG_DENSE,
970  // &*def_coeffs.begin());
971  // std::vector<double> def_basses(nb_bases, 0);
972  // CHKERR getPostProcMesh().tag_get_handle("BASES", nb_bases, MB_TYPE_DOUBLE,
973  // thBases, MB_TAG_CREAT |
974  // MB_TAG_DENSE,
975  // &*def_basses.begin());
976 
977  std::array<double, 3> def_small_x{0., 0., 0.};
978  CHKERR getPostProcMesh().tag_get_handle("x", 3, MB_TYPE_DOUBLE, thSmallX,
979  MB_TAG_CREAT | MB_TAG_DENSE,
980  def_small_x.data());
981  CHKERR getPostProcMesh().tag_get_handle("X", 3, MB_TYPE_DOUBLE, thLargeX,
982  MB_TAG_CREAT | MB_TAG_DENSE,
983  def_small_x.data());
984 
985  std::array<double, 3> def_tractions{0., 0., 0.};
986  CHKERR getPostProcMesh().tag_get_handle(
987  "TRACTION", 3, MB_TYPE_DOUBLE, thTraction, MB_TAG_CREAT | MB_TAG_DENSE,
988  &*def_tractions.begin());
989 }
990 
993  CHKERR Base::preProcess();
995 }
996 
999 
1000  CHKERR Base::postProcess();
1001  shadowDataMap.clear();
1002 
1003  PetscBarrier(nullptr);
1004 
1005  ParallelComm *pcomm_post_proc_mesh =
1006  ParallelComm::get_pcomm(&getPostProcMesh(), MYPCOMM_INDEX);
1007  if (pcomm_post_proc_mesh == nullptr)
1008  SETERRQ(PETSC_COMM_WORLD, MOFEM_DATA_INCONSISTENCY, "PComm not allocated");
1009 
1010  // MOFEM_LOG("EP", Sev::verbose) << "ContactTree broadcast entities";
1011 
1012  auto brodacts = [&](auto &brodacts_ents) {
1014  Range recived_ents;
1015  for (auto rr = 0; rr != mField.get_comm_size(); ++rr) {
1016  pcomm_post_proc_mesh->broadcast_entities(
1017  rr, rr == mField.get_comm_rank() ? brodacts_ents : recived_ents,
1018  false, true);
1019  }
1021  };
1022 
1023  Range brodacts_ents;
1024  CHKERR getPostProcMesh().get_entities_by_dimension(0, 2, brodacts_ents, true);
1025  CHKERR brodacts(brodacts_ents);
1026 
1027  // MOFEM_LOG("EP", Sev::verbose) << "ContactTree build tree";
1028 
1029  Range ents;
1030  CHKERR getPostProcMesh().get_entities_by_dimension(0, 2, ents, true);
1031  CHKERR buildTree(ents);
1032 
1033  // #ifndef NDEBUG
1034  CHKERR writeFile("debug_tree.h5m");
1035  // #endif // NDEBUG
1036 
1038 }
1039 
1042  // MOFEM_LOG("SELF", Sev::inform) << ents << endl;
1043 
1044  treeSurfPtr = boost::shared_ptr<OrientedBoxTreeTool>(
1045  new OrientedBoxTreeTool(&getPostProcMesh(), "ROOTSETSURF", true));
1046  CHKERR treeSurfPtr->build(ents, rootSetSurf);
1047 
1048  // CHKERR treeSurfPtr->stats(rootSetSurf, std::cerr);
1049 
1051 }
1052 
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) {}
1059 
1063 
1064  auto get_body_id = [&](auto fe_ent) {
1065  for (auto &m : contactTreePtr->bodyMap) {
1066  if (m.second.find(fe_ent) != m.second.end()) {
1067  return m.first;
1068  }
1069  }
1070  return -1;
1071  };
1072 
1073  auto &moab_post_proc_mesh = contactTreePtr->getPostProcMesh();
1074  auto &post_proc_ents = contactTreePtr->getPostProcElements();
1075 
1076  auto fe_ent = getNumeredEntFiniteElementPtr()->getEnt();
1077  auto fe_id = id_from_handle(fe_ent);
1078  auto body_id = get_body_id(fe_ent);
1079  auto &map_gauss_pts = contactTreePtr->getMapGaussPts();
1080 
1081  CHKERR moab_post_proc_mesh.tag_clear_data(contactTreePtr->thEleId,
1082  post_proc_ents, &fe_id);
1083  CHKERR moab_post_proc_mesh.tag_clear_data(contactTreePtr->thBodyId,
1084  post_proc_ents, &body_id);
1085 
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();
1090 
1091  MatrixDouble x_h1(nb_gauss_pts, 3);
1092  auto t_x_h1 = getFTensor1FromPtr<3>(&x_h1(0, 0));
1093  MatrixDouble x_l2(nb_gauss_pts, 3);
1094  auto t_x_l2 = getFTensor1FromPtr<3>(&x_l2(0, 0));
1095  MatrixDouble tractions = trans(commonDataPtr->contactTraction);
1096  MatrixDouble coords = getCoordsAtGaussPts();
1097 
1099 
1100  // VectorDouble bases(nb_bases, 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);
1104 
1105  ++t_coords;
1106  ++t_u_h1;
1107  ++t_u_l2;
1108  ++t_x_h1;
1109  ++t_x_l2;
1110  }
1111 
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());
1123 
1125 }
1126 
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,
1131 
1132  moab::Interface *post_proc_mesh_ptr,
1133  std::vector<EntityHandle> *map_gauss_pts_ptr
1134 
1135  )
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),
1139  contactRange(r) {}
1140 
1144 
1145  auto &m_field = getPtrFE()->mField;
1146  auto fe_ent = getNumeredEntFiniteElementPtr()->getEnt();
1147  auto fe_id = id_from_handle(fe_ent);
1148 
1149  if (contactRange.find(fe_ent) == contactRange.end())
1151 
1154 
1155  const auto nb_gauss_pts = getGaussPts().size2();
1156 
1157  auto t_disp_h1 = getFTensor1FromMat<3>(*uH1Ptr);
1158  auto t_coords = getFTensor1CoordsAtGaussPts();
1159  auto t_traction = getFTensor1FromMat<3>(commonDataPtr->contactTraction);
1160 
1161  auto next = [&]() {
1162  ++t_disp_h1;
1163  ++t_traction;
1164  ++t_coords;
1165  };
1166 
1167  auto get_ele_centre = [i](auto t_ele_coords) {
1168  FTensor::Tensor1<double, 3> t_ele_center;
1169  t_ele_center(i) = 0;
1170  for (int nn = 0; nn != 3; nn++) {
1171  t_ele_center(i) += t_ele_coords(i);
1172  ++t_ele_coords;
1173  }
1174  t_ele_center(i) /= 3;
1175  return t_ele_center;
1176  };
1177 
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);
1181  return t_n0.l2();
1182  };
1183 
1184  auto get_face_conn = [this](auto face) {
1185  const EntityHandle *conn;
1186  int num_nodes;
1187  CHK_MOAB_THROW(contactTreePtr->getPostProcMesh().get_connectivity(
1188  face, conn, num_nodes, true),
1189  "get conn");
1190  if (num_nodes != 3) {
1191  CHK_THROW_MESSAGE(MOFEM_DATA_INCONSISTENCY, "face is not a triangle");
1192  }
1193  return conn;
1194  };
1195 
1196  auto get_face_coords = [this](auto conn) {
1197  std::array<double, 9> coords;
1198  CHKERR contactTreePtr->getPostProcMesh().get_coords(conn, 3, coords.data());
1199  return coords;
1200  };
1201 
1202  auto get_closet_face = [this](auto *point_ptr, auto r) {
1203  FTensor::Tensor1<double, 3> t_point_out;
1204  std::vector<EntityHandle> faces_out;
1206  contactTreePtr->getTreeSurfPtr()->sphere_intersect_triangles(
1207  point_ptr, r / 8, contactTreePtr->getRootSetSurf(), faces_out),
1208  "get closest faces");
1209  return faces_out;
1210  };
1211 
1212  auto get_faces_out = [this](auto *point_ptr, auto *unit_ray_ptr, auto radius,
1213  auto eps) {
1214  std::vector<double> distances_out;
1215  std::vector<EntityHandle> faces_out;
1217 
1218  contactTreePtr->getTreeSurfPtr()->ray_intersect_triangles(
1219  distances_out, faces_out, contactTreePtr->getRootSetSurf(), eps,
1220  point_ptr, unit_ray_ptr, &radius),
1221 
1222  "get closest faces");
1223  return std::make_pair(faces_out, distances_out);
1224  };
1225 
1226  auto get_normal = [](auto &ele_coords) {
1227  FTensor::Tensor1<double, 3> t_normal;
1228  Tools::getTriNormal(ele_coords.data(), &t_normal(0));
1229  return t_normal;
1230  };
1231 
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]);
1239  auto face_coords = get_face_coords(face_conn);
1240  auto t_face_normal = get_normal(face_coords);
1241  t_face_normal.normalize();
1243  t_x(i) = t_ray_point(i) + t_unit_ray(i) * face_dist[ii];
1245  t_chi(i, j) =
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];
1250  }
1251  }
1252  return m;
1253  };
1254 
1255  auto get_tag_data = [this](auto tag, auto face, auto &vec) {
1257  int tag_length;
1258  CHKERR contactTreePtr->getPostProcMesh().tag_get_length(tag, tag_length);
1259  vec.resize(tag_length);
1260  CHKERR contactTreePtr->getPostProcMesh().tag_get_data(tag, &face, 1,
1261  &*vec.begin());
1263  };
1264 
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};
1267  Tag th;
1268  if (postProcMeshPtr) {
1269  CHKERR postProcMeshPtr->tag_get_handle(
1270  tag_name.c_str(), size, MB_TYPE_DOUBLE, th,
1271  MB_TAG_CREAT | MB_TAG_SPARSE, def_VAL);
1272  CHKERR postProcMeshPtr->tag_clear_data(th, &*mapGaussPtsPtr->begin(),
1273  mapGaussPtsPtr->size(), def_VAL);
1274  }
1275  return th;
1276  };
1277 
1278  auto set_float_precision = [](const double x) {
1279  if (std::abs(x) < std::numeric_limits<float>::epsilon())
1280  return 0.;
1281  else
1282  return x;
1283  };
1284 
1285  // scalars
1286  auto save_scal_tag = [&](auto &th, auto v, const int gg) {
1288  if (postProcMeshPtr) {
1289  v = set_float_precision(v);
1290  CHKERR postProcMeshPtr->tag_set_data(th, &(*mapGaussPtsPtr)[gg], 1, &v);
1291  }
1293  };
1294 
1295  // adjacencies
1296  auto get_fe_adjacencies = [this](auto fe_ent) {
1297  Range adj_faces;
1298  CHK_MOAB_THROW(getFaceFE()->mField.get_moab().get_adjacencies(
1299  &fe_ent, 1, 2, false, adj_faces, moab::Interface::UNION),
1300  "get adj");
1301  std::set<int> adj_ids;
1302  for (auto f : adj_faces) {
1303  adj_ids.insert(id_from_handle(f));
1304  }
1305  return adj_ids;
1306  };
1307 
1308  auto get_face_id = [this](auto face) {
1309  int id;
1310  if (contactTreePtr->getPostProcMesh().tag_get_data(
1311  contactTreePtr->thEleId, &face, 1, &id) == MB_SUCCESS) {
1312  return id;
1313  }
1314  return -1;
1315  };
1316 
1317  auto get_body_id = [this](auto face) {
1318  int id;
1319  if (contactTreePtr->getPostProcMesh().tag_get_data(
1320  contactTreePtr->thBodyId, &face, 1, &id) == MB_SUCCESS) {
1321  return id;
1322  }
1323  return -1;
1324  };
1325 
1326  auto get_face_part = [this](auto face) {
1327  ParallelComm *pcomm_post_proc_mesh = ParallelComm::get_pcomm(
1328  &(contactTreePtr->getPostProcMesh()), MYPCOMM_INDEX);
1329  int part;
1330  if (contactTreePtr->getPostProcMesh().tag_get_data(
1331  pcomm_post_proc_mesh->part_tag(), &face, 1, &part) == MB_SUCCESS) {
1332  return part;
1333  }
1334  return -1;
1335  };
1336 
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)
1341  return true;
1342  return false;
1343  };
1344 
1345  // vectors
1346  VectorDouble3 v(3);
1347  FTensor::Tensor1<FTensor::PackPtr<double *, 0>, 3> t_v(&v[0], &v[1], &v[2]);
1348  auto save_vec_tag = [&](auto &th, auto &t_d, const int gg) {
1350  if (postProcMeshPtr) {
1351  t_v(i) = t_d(i);
1352  for (auto &a : v.data())
1353  a = set_float_precision(a);
1354  CHKERR postProcMeshPtr->tag_set_data(th, &(*mapGaussPtsPtr)[gg], 1,
1355  &*v.data().begin());
1356  }
1358  };
1359 
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);
1372 
1373  auto t_ele_centre = get_ele_centre(getFTensor1Coords());
1374  auto ele_radius = get_ele_radius(t_ele_centre, getFTensor1Coords());
1375 
1376  contactTreePtr->shadowDataMap.clear();
1377  auto &shadow_vec = contactTreePtr->shadowDataMap[fe_ent];
1378  shadow_vec.clear();
1379 
1380  auto adj_fe_ids = get_fe_adjacencies(fe_ent);
1381 
1382  for (auto gg = 0; gg != nb_gauss_pts; ++gg) {
1383 
1384  FTensor::Tensor1<double, 3> t_spatial_coords;
1385  t_spatial_coords(i) = t_coords(i) + t_disp_h1(i);
1386 
1387  if (postProcMeshPtr) {
1388  CHKERR save_vec_tag(th_contact_traction, t_traction, gg);
1389  }
1390 
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())) {
1394 
1395  auto body_id = get_body_id(face_close);
1396 
1397  auto master_face_conn = get_face_conn(face_close);
1398  std::array<double, 9> master_coords;
1399  CHKERR contactTreePtr->getPostProcMesh().tag_get_data(
1400  contactTreePtr->thSmallX, master_face_conn, 3,
1401  master_coords.data());
1402  std::array<double, 9> master_traction;
1403  CHKERR contactTreePtr->getPostProcMesh().tag_get_data(
1404  contactTreePtr->thTraction, master_face_conn, 3,
1405  master_traction.data());
1406  auto t_normal_face_close = get_normal(master_coords);
1407  t_normal_face_close.normalize();
1408 
1409  if (postProcMeshPtr) {
1410  double m = 1;
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);
1415  }
1416 
1417  FTensor::Tensor1<double, 3> t_unit_ray;
1418  t_unit_ray(i) = -t_normal_face_close(i);
1419  FTensor::Tensor1<double, 3> t_ray_point;
1420  t_ray_point(i) =
1421  t_spatial_coords(i) -
1422  t_unit_ray(i) * ContactOps::airplane_ray_distance * ele_radius;
1423 
1424  constexpr double eps = 1e-3;
1425  auto [faces_out, faces_dist] =
1426  get_faces_out(&t_ray_point(0), &t_unit_ray(0),
1427  2 * ContactOps::airplane_ray_distance * ele_radius,
1428  eps * ele_radius);
1429 
1430  auto m = make_map(faces_out, faces_dist, t_ray_point, t_unit_ray,
1431  t_spatial_coords);
1432  for (auto m_it = m.begin(); m_it != m.end(); ++m_it) {
1433  auto face = m_it->second;
1434  if (face != face_close) {
1435 
1436  if (
1437 
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())
1441 
1442  ) {
1443 
1444  shadow_vec.push_back(ContactTree::FaceData());
1445  shadow_vec.back().gaussPtNb = gg;
1446 
1447  auto slave_face_conn = get_face_conn(face);
1448  std::array<double, 9> slave_coords;
1449  CHKERR contactTreePtr->getPostProcMesh().tag_get_data(
1450  contactTreePtr->thSmallX, slave_face_conn, 3,
1451  slave_coords.data());
1452  auto t_normal_face = get_normal(slave_coords);
1453  std::array<double, 9> slave_tractions;
1454  CHKERR contactTreePtr->getPostProcMesh().tag_get_data(
1455  contactTreePtr->thTraction, slave_face_conn, 3,
1456  slave_tractions.data());
1457 
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());
1466 
1467  t_slave_point(i) = t_ray_point(i) + m_it->first * t_unit_ray(i);
1468 
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,
1474  loc_coords.data()),
1475  "get local coords");
1476  FTensor::Tensor1<double, 3> t_shape_fun;
1477  CHK_THROW_MESSAGE(Tools::shapeFunMBTRI<0>(&t_shape_fun(0),
1478  &loc_coords[0],
1479  &loc_coords[1], 1),
1480  "calc shape fun");
1483  FTensor::Tensor1<double, 3> t_point_out;
1484  t_point_out(i) = t_shape_fun(j) * t_elem_coords(j, i);
1485  return t_point_out;
1486  };
1487 
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);
1492 
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);
1497 
1498  t_ray_point_data(i) = t_ray_point(i);
1499  t_unit_ray_data(i) = t_unit_ray(i);
1500 
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());
1509 
1510  shadow_vec.back().eleRadius = ele_radius;
1511 
1512  // CHKERR get_tag_data(contactTreePtr->thIds, face,
1513  // shadow_vec.back().dofsSlaveIds);
1514  // CHKERR get_tag_data(contactTreePtr->thCoeff, face,
1515  // shadow_vec.back().dofsSlaveCoeff);
1516  // CHKERR get_tag_data(contactTreePtr->thBases, face,
1517  // shadow_vec.back().baseSlaveFuncs);
1518 
1519  if (postProcMeshPtr) {
1520  auto [gap, tn_master, tn_slave, c, t_master_traction,
1521  t_slave_traction] =
1522  multiGetGap(&(shadow_vec.back()), t_spatial_coords);
1523  FTensor::Tensor1<double, 3> t_gap_vec;
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);
1529  double m = 1;
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,
1535  gg);
1536  }
1537 
1538  break;
1539  }
1540  }
1541  }
1542  break;
1543  }
1544  }
1545  next();
1546  }
1547 
1549 }
1550 
1551 } // namespace EshelbianPlasticity
ContactOps::get_spatial_coords
auto get_spatial_coords(FTensor::Tensor1< T1, DIM1 > &&t_coords, FTensor::Tensor1< T2, DIM2 > &&t_disp, size_t nb_gauss_pts)
Definition: ContactOps.hpp:414
NOSPACE
@ NOSPACE
Definition: definitions.h:83
MoFEMFunctionReturnHot
#define MoFEMFunctionReturnHot(a)
Last executable line of each PETSc function used for error handling. Replaces return()
Definition: definitions.h:460
ContactOps::airplane_ray_distance
double airplane_ray_distance
Definition: EshelbianContact.hpp:25
CHK_MOAB_THROW
#define CHK_MOAB_THROW(err, msg)
Check error code of MoAB function and throw MoFEM exception.
Definition: definitions.h:589
MoFEM::id_from_handle
auto id_from_handle(const EntityHandle h)
Definition: Templates.hpp:1890
g
constexpr double g
Definition: shallow_wave.cpp:63
MYPCOMM_INDEX
#define MYPCOMM_INDEX
default communicator number PCOMM
Definition: definitions.h:228
EshelbianPlasticity::ContactTree::buildTree
MoFEMErrorCode buildTree(Range &ents)
Definition: EshelbianContact.cpp:1040
EshelbianPlasticity::OpTreeSearch::UOP
FaceElementForcesAndSourcesCore::UserDataOperator UOP
Definition: EshelbianContact.hpp:239
MoFEM::Types::VectorDouble3
VectorBoundedArray< double, 3 > VectorDouble3
Definition: Types.hpp:92
FTensor::Tensor1
Definition: Tensor1_value.hpp:8
MOFEM_LOG_CHANNEL
#define MOFEM_LOG_CHANNEL(channel)
Set and reset channel.
Definition: LogManager.hpp:284
EntityHandle
ContactOps::hess_surface_distance_function
MatrixDouble hess_surface_distance_function(double delta_t, double t, int nb_gauss_pts, MatrixDouble &m_spatial_coords, MatrixDouble &m_normals_at_pts, int block_id)
Definition: ContactOps.hpp:338
ContactOps
Definition: contact.cpp:99
ContactOps::constrain
double constrain(double sdf, double tn)
constrain function
Definition: ContactOps.hpp:603
EshelbianPlasticity::OpMoveNode::UOP
FaceElementForcesAndSourcesCore::UserDataOperator UOP
Definition: EshelbianContact.hpp:223
EshelbianPlasticity::OpConstrainBoundaryL2Rhs::sdfMapRangePtr
boost::shared_ptr< std::map< int, Range > > sdfMapRangePtr
Definition: EshelbianContact.hpp:130
CHK_THROW_MESSAGE
#define CHK_THROW_MESSAGE(err, msg)
Check and throw MoFEM exception.
Definition: definitions.h:609
MoFEM::Exceptions::MoFEMErrorCode
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
Definition: Exceptions.hpp:56
EshelbianPlasticity::ContactTree::FaceData::masterPoint
std::array< double, 3 > masterPoint
Definition: EshelbianContact.hpp:57
FTensor::Tensor1::l2
T l2() const
Definition: Tensor1_value.hpp:84
MoFEM::Types::MatrixDouble
UBlasMatrix< double > MatrixDouble
Definition: Types.hpp:77
MoFEM::CoreInterface::get_comm_rank
virtual int get_comm_rank() const =0
MoFEM::th
Tag th
Definition: Projection10NodeCoordsOnField.cpp:122
EshelbianPlasticity::OpTreeSearch::contactTreePtr
boost::shared_ptr< ContactTree > contactTreePtr
Definition: EshelbianContact.hpp:253
FTensor::Kronecker_Delta
Kronecker Delta class.
Definition: Kronecker_Delta.hpp:15
EshelbianPlasticity::OpTreeSearch::OpTreeSearch
OpTreeSearch(boost::shared_ptr< ContactTree > contact_tree_ptr, boost::shared_ptr< ContactOps::CommonData > common_data_ptr, boost::shared_ptr< MatrixDouble > u_h1_ptr, Range r, moab::Interface *post_proc_mesh_ptr, std::vector< EntityHandle > *map_gauss_pts_ptr)
Definition: EshelbianContact.cpp:1127
EshelbianPlasticity
Definition: CGGTonsorialBubbleBase.hpp:11
EshelbianPlasticity::ContactTree::postProcess
MoFEMErrorCode postProcess()
function is run at the end of loop
Definition: EshelbianContact.cpp:997
EshelbianPlasticity::OpTreeSearch::contactRange
Range contactRange
Definition: EshelbianContact.hpp:260
MoFEM::PostProcBrokenMeshInMoabBase< FaceElementForcesAndSourcesCore >::writeFile
MoFEMErrorCode writeFile(const std::string file_name)
wrote results in (MOAB) format, use "file_name.h5m"
Definition: PostProcBrokenMeshInMoabBase.hpp:655
NBVOLUMETET_L2
#define NBVOLUMETET_L2(P)
Number of base functions on tetrahedron for L2 space.
Definition: h1_hdiv_hcurl_l2.h:27
FTENSOR_INDEX
#define FTENSOR_INDEX(DIM, I)
Definition: Templates.hpp:2011
EshelbianPlasticity::OpMoveNode::contactTreePtr
boost::shared_ptr< ContactTree > contactTreePtr
Definition: EshelbianContact.hpp:232
EshelbianPlasticity::checkSdf
auto checkSdf(EntityHandle fe_ent, std::map< int, Range > &sdf_map_range)
Definition: EshelbianContact.cpp:17
zeta
double zeta
Viscous hardening.
Definition: plastic.cpp:126
EshelbianPlasticity::ContactTree::FaceData
Definition: EshelbianContact.hpp:54
sdf.r
int r
Definition: sdf.py:8
FTensor::Tensor2< double, 3, 3 >
EshelbianPlasticity::ContactTree::ContactTree
ContactTree(MoFEM::Interface &m_field, boost::shared_ptr< moab::Core > core_mesh_ptr, int max_order, std::map< int, Range > &&body_map)
Definition: EshelbianContact.cpp:927
EshelbianPlasticity::ContactTree::thSmallX
Tag thSmallX
Definition: EshelbianContact.hpp:107
MoFEM::DeprecatedCoreInterface
Deprecated interface functions.
Definition: DeprecatedCoreInterface.hpp:16
EshelbianPlasticity::OpMoveNode::OpMoveNode
OpMoveNode(boost::shared_ptr< ContactTree > contact_tree_ptr, boost::shared_ptr< ContactOps::CommonData > common_data_ptr, boost::shared_ptr< MatrixDouble > u_h1_ptr)
Definition: EshelbianContact.cpp:1053
EshelbianPlasticity::OpConstrainBoundaryL2Lhs_dU::sdfMapRangePtr
boost::shared_ptr< std::map< int, Range > > sdfMapRangePtr
Definition: EshelbianContact.hpp:169
MoFEM::Interface
DeprecatedCoreInterface Interface
Definition: Interface.hpp:2010
MoFEM::PostProcBrokenMeshInMoabBase< FaceElementForcesAndSourcesCore >::refElementsMap
std::map< EntityType, PostProcGenerateRefMeshPtr > refElementsMap
Definition: PostProcBrokenMeshInMoabBase.hpp:171
EshelbianPlasticity::ContactTree::FaceData::unitRay
std::array< double, 3 > unitRay
Definition: EshelbianContact.hpp:59
c
const double c
speed of light (cm/ns)
Definition: initial_diffusion.cpp:39
EshelbianPlasticity::ContactTree::thEleId
Tag thEleId
Definition: EshelbianContact.hpp:102
MoFEM::OpBaseImpl
Definition: FormsIntegrators.hpp:178
CHKERR
#define CHKERR
Inline error check.
Definition: definitions.h:548
EshelbianPlasticity::ContactTree::rootSetSurf
EntityHandle rootSetSurf
Definition: EshelbianContact.hpp:100
EshelbianPlasticity::ContactTree::shadowDataMap
MapFaceData shadowDataMap
Definition: EshelbianContact.hpp:111
EshelbianPlasticity::OpTreeSearch::postProcMeshPtr
moab::Interface * postProcMeshPtr
Definition: EshelbianContact.hpp:257
SPACE_DIM
constexpr int SPACE_DIM
Definition: child_and_parent.cpp:16
a
constexpr double a
Definition: approx_sphere.cpp:30
BoundaryEleOp
EshelbianPlasticity::ContactTree::FaceData::slavePointNodes
std::array< double, 9 > slavePointNodes
Definition: EshelbianContact.hpp:68
EshelbianPlasticity::ContactTree::thBodyId
Tag thBodyId
Definition: EshelbianContact.hpp:106
ContactOps::get_normalize_normals
auto get_normalize_normals(FTensor::Tensor1< T1, DIM1 > &&t_normal_at_pts, size_t nb_gauss_pts)
Definition: ContactOps.hpp:431
convert.type
type
Definition: convert.py:64
MoFEM::getFTensor0FromVec
static auto getFTensor0FromVec(ublas::vector< T, A > &data)
Get tensor rank 0 (scalar) form data vector.
Definition: Templates.hpp:135
EshelbianPlasticity::OpConstrainBoundaryHDivLhs_dU
Definition: EshelbianContact.hpp:198
EshelbianPlasticity::OpConstrainBoundaryL2Lhs_dU::commonDataPtr
boost::shared_ptr< ContactOps::CommonData > commonDataPtr
Definition: EshelbianContact.hpp:167
EshelbianPlasticity::P
@ P
Definition: EshelbianContact.cpp:197
EshelbianPlasticity::OpConstrainBoundaryL2Lhs_dU::iNtegrate
MoFEMErrorCode iNtegrate(EntitiesFieldData::EntData &row_data, EntitiesFieldData::EntData &col_data)
Definition: EshelbianContact.cpp:545
EshelbianPlasticity::OpConstrainBoundaryHDivRhs
Definition: EshelbianContact.hpp:134
EshelbianPlasticity::MultiPointRhsType
MultiPointRhsType
Definition: EshelbianContact.cpp:197
eta
double eta
Definition: free_surface.cpp:170
MoFEM::CoreInterface::get_comm_size
virtual int get_comm_size() const =0
EshelbianPlasticity::multiPoint
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.
Definition: EshelbianContact.cpp:82
EshelbianPlasticity::ContactTree::FaceData::masterPointNodes
std::array< double, 9 > masterPointNodes
Definition: EshelbianContact.hpp:66
debug
static const bool debug
Definition: dm_create_subdm.cpp:12
EshelbianPlasticity::multiMasterPoint
auto multiMasterPoint(ContactTree::FaceData *face_data_ptr, FTensor::Tensor1< T1, 3 > &t_spatial_coords)
Definition: EshelbianContact.cpp:144
i
FTensor::Index< 'i', SPACE_DIM > i
Definition: hcurl_divergence_operator_2d.cpp:27
EshelbianPlasticity::ContactTree::preProcess
MoFEMErrorCode preProcess()
function is run at the beginning of loop
Definition: EshelbianContact.cpp:991
t_kd
constexpr auto t_kd
Definition: free_surface.cpp:137
EshelbianPlasticity::ContactTree::treeSurfPtr
boost::shared_ptr< OrientedBoxTreeTool > treeSurfPtr
Definition: EshelbianContact.hpp:99
ContactOps::alpha_contact_const
double alpha_contact_const
Definition: EshelbianContact.hpp:21
EntData
EntitiesFieldData::EntData EntData
Definition: child_and_parent.cpp:37
FTensor::Index< 'i', 3 >
FTensor::Tensor1::normalize
Tensor1< T, Tensor_Dim > normalize()
Definition: Tensor1_value.hpp:77
EshelbianPlasticity::OpConstrainBoundaryL2Rhs::OpConstrainBoundaryL2Rhs
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)
Definition: EshelbianContact.cpp:305
N_MBTRI0
#define N_MBTRI0(x, y)
triangle shape function
Definition: fem_tools.h:46
EshelbianPlasticity::ContactTree::Base
PostProcBrokenMeshInMoabBase< FaceElementForcesAndSourcesCore > Base
Definition: EshelbianContact.hpp:37
ContactOps::cn_contact
double cn_contact
Definition: contact.cpp:100
EshelbianPlasticity::ContactTree::thTraction
Tag thTraction
Definition: EshelbianContact.hpp:109
v
const double v
phase velocity of light in medium (cm/ns)
Definition: initial_diffusion.cpp:40
EshelbianPlasticity::ContactTree::FaceData::slavePoint
std::array< double, 3 > slavePoint
Definition: EshelbianContact.hpp:56
Range
EshelbianPlasticity::ContactTree::FaceData::masterTractionNodes
std::array< double, 9 > masterTractionNodes
Definition: EshelbianContact.hpp:67
face_coords
static const double face_coords[4][9]
Definition: forces_and_sources_h1_continuity_check.cpp:13
MOFEM_LOG
#define MOFEM_LOG(channel, severity)
Log.
Definition: LogManager.hpp:308
EshelbianPlasticity::OpTreeSearch::uH1Ptr
boost::shared_ptr< MatrixDouble > uH1Ptr
Definition: EshelbianContact.hpp:255
EshelbianPlasticity::OpMoveNode::commonDataPtr
boost::shared_ptr< ContactOps::CommonData > commonDataPtr
Definition: EshelbianContact.hpp:234
FTensor::kronecker_delta
Tensor2_Expr< Kronecker_Delta< T >, T, Dim0, Dim1, i, j > kronecker_delta(const Index< i, Dim0 > &, const Index< j, Dim1 > &)
Rank 2.
Definition: Kronecker_Delta.hpp:81
HenckyOps::f
auto f
Definition: HenckyOps.hpp:15
EshelbianPlasticity::OpConstrainBoundaryL2Lhs_dU::contactTreePtr
boost::shared_ptr< ContactTree > contactTreePtr
Definition: EshelbianContact.hpp:168
EshelbianPlasticity::OpMoveNode::doWork
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
Definition: EshelbianContact.cpp:1060
N_MBTRI1
#define N_MBTRI1(x, y)
triangle shape function
Definition: fem_tools.h:47
EshelbianPlasticity::OpTreeSearch::doWork
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
Definition: EshelbianContact.cpp:1141
EshelbianPlasticity::multiPointRhs
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)
Definition: EshelbianContact.cpp:202
j
FTensor::Index< 'j', 3 > j
Definition: matrix_function.cpp:19
eps
static const double eps
Definition: check_base_functions_derivatives_on_tet.cpp:11
EshelbianPlasticity::OpMoveNode::uH1Ptr
boost::shared_ptr< MatrixDouble > uH1Ptr
Definition: EshelbianContact.hpp:233
tricircumcenter3d_tp
void tricircumcenter3d_tp(double a[3], double b[3], double c[3], double circumcenter[3], double *xi, double *eta)
EshelbianPlasticity::ContactTree::FaceData::eleRadius
double eleRadius
Definition: EshelbianContact.hpp:60
MOFEM_DATA_INCONSISTENCY
@ MOFEM_DATA_INCONSISTENCY
Definition: definitions.h:31
EshelbianPlasticity::multiGetGap
auto multiGetGap(ContactTree::FaceData *face_data_ptr, FTensor::Tensor1< T1, 3 > &t_spatial_coords)
Definition: EshelbianContact.cpp:173
sdf_hertz_2d_axisymm_plane.d
float d
Definition: sdf_hertz_2d_axisymm_plane.py:4
ContactOps::surface_distance_function
VectorDouble surface_distance_function(double delta_t, double t, int nb_gauss_pts, MatrixDouble &m_spatial_coords, MatrixDouble &m_normals_at_pts, int block_id)
Definition: ContactOps.hpp:223
EshelbianPlasticity::OpConstrainBoundaryL2Rhs::iNtegrate
MoFEMErrorCode iNtegrate(EntitiesFieldData::EntData &row_data)
Definition: EshelbianContact.cpp:342
EshelbianPlasticity::multiSlavePoint
auto multiSlavePoint(ContactTree::FaceData *face_data_ptr, FTensor::Tensor1< T1, 3 > &t_spatial_coords)
Definition: EshelbianContact.cpp:157
EshelbianPlasticity::OpTreeSearch::mapGaussPtsPtr
std::vector< EntityHandle > * mapGaussPtsPtr
Definition: EshelbianContact.hpp:258
EshelbianPlasticity::ContactTree::maxOrder
const int maxOrder
Definition: EshelbianContact.hpp:115
MoFEM::PostProcBrokenMeshInMoabBase< FaceElementForcesAndSourcesCore >::getPostProcMesh
auto & getPostProcMesh()
Get postprocessing mesh.
Definition: PostProcBrokenMeshInMoabBase.hpp:641
m
FTensor::Index< 'm', 3 > m
Definition: shallow_wave.cpp:80
EshelbianPlasticity::OpConstrainBoundaryL2Rhs::contactTreePtr
boost::shared_ptr< ContactTree > contactTreePtr
Definition: EshelbianContact.hpp:129
MoFEM::PetscOptionsGetScalar
PetscErrorCode PetscOptionsGetScalar(PetscOptions *, const char pre[], const char name[], PetscScalar *dval, PetscBool *set)
Definition: DeprecatedPetsc.hpp:162
EshelbianPlasticity::OpConstrainBoundaryL2Lhs_dP
Definition: EshelbianContact.hpp:172
ContactOps::grad_surface_distance_function
MatrixDouble grad_surface_distance_function(double delta_t, double t, int nb_gauss_pts, MatrixDouble &m_spatial_coords, MatrixDouble &m_normals_at_pts, int block_id)
Definition: ContactOps.hpp:281
k
FTensor::Index< 'k', 3 > k
Definition: matrix_function.cpp:20
ContactOps::alpha_contact_quadratic
double alpha_contact_quadratic
Definition: EshelbianContact.hpp:22
OP
MoFEMFunctionReturn
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
Definition: definitions.h:429
EshelbianPlasticity::OpTreeSearch::commonDataPtr
boost::shared_ptr< ContactOps::CommonData > commonDataPtr
Definition: EshelbianContact.hpp:254
EshelbianPlasticity::OpConstrainBoundaryL2Rhs::commonDataPtr
boost::shared_ptr< ContactOps::CommonData > commonDataPtr
Definition: EshelbianContact.hpp:128
EshelbianPlasticity::U
@ U
Definition: EshelbianContact.cpp:197
MoFEMFunctionBegin
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
Definition: definitions.h:359
l
FTensor::Index< 'l', 3 > l
Definition: matrix_function.cpp:21
MoFEM::PostProcBrokenMeshInMoabBase< FaceElementForcesAndSourcesCore >::optionsPrefix
std::string optionsPrefix
Prefix for options.
Definition: PostProcBrokenMeshInMoabBase.hpp:176
EshelbianPlasticity::OpConstrainBoundaryL2Lhs_dU::OpConstrainBoundaryL2Lhs_dU
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)
Definition: EshelbianContact.cpp:531
MoFEM::ForcesAndSourcesCore::mField
Interface & mField
Definition: ForcesAndSourcesCore.hpp:24
N_MBTRI2
#define N_MBTRI2(x, y)
triangle shape function
Definition: fem_tools.h:48
EshelbianPlasticity::getSdf
auto getSdf(OP_PTR op_ptr, MatrixDouble &contact_disp, int block_id, bool eval_hessian)
Definition: EshelbianContact.cpp:26
EshelbianPlasticity::ContactTree::FaceData::slaveTractionNodes
std::array< double, 9 > slaveTractionNodes
Definition: EshelbianContact.hpp:69
EshelbianPlasticity::ContactTree::thLargeX
Tag thLargeX
Definition: EshelbianContact.hpp:108