8#ifndef __CONTACTOPS_HPP__
9#define __CONTACTOPS_HPP__
14struct CommonData :
public boost::enable_shared_from_this<CommonData> {
28 static SmartPetscObj<Vec>
32 constexpr int ghosts[] = {0, 1, 2, 3, 4};
34 createGhostVector(m_field.
get_comm(),
58 return boost::shared_ptr<MatrixDouble>(shared_from_this(),
63 return boost::shared_ptr<MatrixDouble>(shared_from_this(), &
contactDisp);
67 return boost::shared_ptr<MatrixDouble>(shared_from_this(),
72 return boost::shared_ptr<VectorDouble>(shared_from_this(), &
sdfVals);
76 return boost::shared_ptr<MatrixDouble>(shared_from_this(), &
gradsSdf);
80 return boost::shared_ptr<MatrixDouble>(shared_from_this(), &
hessSdf);
84 return boost::shared_ptr<VectorDouble>(shared_from_this(), &
constraintVals);
93#ifdef ENABLE_PYTHON_BINDING
95 SDFPython() =
default;
96 virtual ~SDFPython() =
default;
98 MoFEMErrorCode sdfInit(
const std::string py_file) {
103 auto main_module = bp::import(
"__main__");
104 mainNamespace = main_module.attr(
"__dict__");
105 bp::exec_file(py_file.c_str(), mainNamespace, mainNamespace);
107 sdfFun = mainNamespace[
"sdf"];
108 sdfGradFun = mainNamespace[
"grad_sdf"];
109 sdfHessFun = mainNamespace[
"hess_sdf"];
111 }
catch (bp::error_already_set
const &) {
119 template <
typename T>
120 inline std::vector<T>
121 py_list_to_std_vector(
const boost::python::object &iterable) {
122 return std::vector<T>(boost::python::stl_input_iterator<T>(iterable),
123 boost::python::stl_input_iterator<T>());
128 double delta_t,
double t, np::ndarray x, np::ndarray y, np::ndarray z,
129 np::ndarray tx, np::ndarray ty, np::ndarray tz,
int block_id,
137 sdf = bp::extract<np::ndarray>(
138 sdfFun(delta_t,
t, x, y, z, tx, ty, tz, block_id));
140 }
catch (bp::error_already_set
const &) {
150 double delta_t,
double t, np::ndarray x, np::ndarray y, np::ndarray z,
151 np::ndarray tx, np::ndarray ty, np::ndarray tz,
int block_id,
152 np::ndarray &grad_sdf
159 grad_sdf = bp::extract<np::ndarray>(
160 sdfGradFun(delta_t,
t, x, y, z, tx, ty, tz, block_id));
162 }
catch (bp::error_already_set
const &) {
172 double delta_t,
double t, np::ndarray x, np::ndarray y, np::ndarray z,
173 np::ndarray tx, np::ndarray ty, np::ndarray tz,
int block_id,
174 np::ndarray &hess_sdf
181 hess_sdf = bp::extract<np::ndarray>(
182 sdfHessFun(delta_t,
t, x, y, z, tx, ty, tz, block_id));
184 }
catch (bp::error_already_set
const &) {
193 bp::object mainNamespace;
195 bp::object sdfGradFun;
196 bp::object sdfHessFun;
199static boost::weak_ptr<SDFPython> sdfPythonWeakPtr;
201inline np::ndarray convert_to_numpy(VectorDouble &data,
int nb_gauss_pts,
203 auto dtype = np::dtype::get_builtin<double>();
204 auto size = bp::make_tuple(nb_gauss_pts);
205 auto stride = bp::make_tuple(3 *
sizeof(
double));
206 return (np::from_data(&data[
id], dtype, size, stride, bp::object()));
212 double delta_t,
double t,
int nb_gauss_pts, MatrixDouble &spatial_coords,
213 MatrixDouble &normals_at_pts,
int block_id)>;
216 double delta_t,
double t,
int nb_gauss_pts, MatrixDouble &spatial_coords,
217 MatrixDouble &normals_at_pts,
int block_id)>;
220 double delta_t,
double t,
int nb_gauss_pts, MatrixDouble &spatial_coords,
221 MatrixDouble &normals_at_pts,
int block_id)>;
225 MatrixDouble &m_spatial_coords,
226 MatrixDouble &m_normals_at_pts,
229#ifdef ENABLE_PYTHON_BINDING
230 if (
auto sdf_ptr = sdfPythonWeakPtr.lock()) {
232 VectorDouble v_spatial_coords = m_spatial_coords.data();
233 VectorDouble v_normal_at_pts = m_normals_at_pts.data();
235 bp::list python_coords;
236 bp::list python_normals;
238 for (
int idx = 0; idx < 3; ++idx) {
239 python_coords.append(
240 convert_to_numpy(v_spatial_coords, nb_gauss_pts, idx));
241 python_normals.append(
242 convert_to_numpy(v_normal_at_pts, nb_gauss_pts, idx));
245 np::ndarray np_sdf = np::empty(bp::make_tuple(nb_gauss_pts),
246 np::dtype::get_builtin<double>());
248 bp::extract<np::ndarray>(python_coords[0]),
249 bp::extract<np::ndarray>(python_coords[1]),
250 bp::extract<np::ndarray>(python_coords[2]),
251 bp::extract<np::ndarray>(python_normals[0]),
252 bp::extract<np::ndarray>(python_normals[1]),
253 bp::extract<np::ndarray>(python_normals[2]),
255 "Failed python call");
258 if (np_sdf.get_nd() != 1 || np_sdf.get_shape()[0] != nb_gauss_pts) {
261 "Wrong number of dimensions or size of SDF returned from "
262 "python, expected: dim 1, got: " +
263 std::to_string(np_sdf.get_nd()) +
", expected size: (" +
264 std::to_string(nb_gauss_pts) +
")");
267 double *sdf_val_ptr =
reinterpret_cast<double *
>(np_sdf.get_data());
270 v_sdf.resize(nb_gauss_pts,
false);
272 for (
size_t gg = 0; gg < nb_gauss_pts; ++gg)
273 v_sdf[gg] = *(sdf_val_ptr + gg);
279 v_sdf.resize(nb_gauss_pts,
false);
280 auto t_coords = getFTensor1FromPtr<3>(&m_spatial_coords(0, 0));
282 for (
size_t gg = 0; gg < nb_gauss_pts; ++gg) {
283 v_sdf[gg] = -t_coords(2) - 0.1;
292 MatrixDouble &m_spatial_coords,
293 MatrixDouble &m_normals_at_pts,
int block_id) {
294#ifdef ENABLE_PYTHON_BINDING
295 if (
auto sdf_ptr = sdfPythonWeakPtr.lock()) {
297 VectorDouble v_spatial_coords = m_spatial_coords.data();
298 VectorDouble v_normal_at_pts = m_normals_at_pts.data();
300 bp::list python_coords;
301 bp::list python_normals;
303 for (
int idx = 0; idx < 3; ++idx) {
304 python_coords.append(
305 convert_to_numpy(v_spatial_coords, nb_gauss_pts, idx));
306 python_normals.append(
307 convert_to_numpy(v_normal_at_pts, nb_gauss_pts, idx));
310 np::ndarray np_grad_sdf = np::empty(bp::make_tuple(nb_gauss_pts, 3),
311 np::dtype::get_builtin<double>());
313 delta_t,
t, bp::extract<np::ndarray>(python_coords[0]),
314 bp::extract<np::ndarray>(python_coords[1]),
315 bp::extract<np::ndarray>(python_coords[2]),
316 bp::extract<np::ndarray>(python_normals[0]),
317 bp::extract<np::ndarray>(python_normals[1]),
318 bp::extract<np::ndarray>(python_normals[2]), block_id,
320 "Failed python call");
323 if (np_grad_sdf.get_shape()[0] != nb_gauss_pts ||
324 np_grad_sdf.get_shape()[1] != 3) {
326 "Wrong shape of gradient of SDF returned from "
327 "python, expected: (" +
328 std::to_string(nb_gauss_pts) +
", 3), got: (" +
329 std::to_string(np_grad_sdf.get_shape()[0]) +
", " +
330 std::to_string(np_grad_sdf.get_shape()[1]) +
")");
333 double *grad_ptr =
reinterpret_cast<double *
>(np_grad_sdf.get_data());
335 MatrixDouble m_grad_sdf;
336 m_grad_sdf.resize(3, nb_gauss_pts,
false);
337 for (
size_t gg = 0; gg < nb_gauss_pts; ++gg) {
338 for (
int idx = 0; idx < 3; ++idx)
339 m_grad_sdf(idx, gg) = *(grad_ptr + (3 * gg + idx));
344 MatrixDouble m_grad_sdf;
345 m_grad_sdf.resize(3, nb_gauss_pts,
false);
348 auto t_grad_sdf = getFTensor1FromMat<3>(m_grad_sdf);
350 for (
size_t gg = 0; gg < nb_gauss_pts; ++gg) {
351 t_grad_sdf(
i) = t_grad_sdf_set(
i);
360 MatrixDouble &m_spatial_coords,
361 MatrixDouble &m_normals_at_pts,
int block_id) {
362#ifdef ENABLE_PYTHON_BINDING
363 if (
auto sdf_ptr = sdfPythonWeakPtr.lock()) {
365 VectorDouble v_spatial_coords = m_spatial_coords.data();
366 VectorDouble v_normal_at_pts = m_normals_at_pts.data();
368 bp::list python_coords;
369 bp::list python_normals;
371 for (
int idx = 0; idx < 3; ++idx) {
372 python_coords.append(
373 convert_to_numpy(v_spatial_coords, nb_gauss_pts, idx));
374 python_normals.append(
375 convert_to_numpy(v_normal_at_pts, nb_gauss_pts, idx));
378 np::ndarray np_hess_sdf = np::empty(bp::make_tuple(nb_gauss_pts, 6),
379 np::dtype::get_builtin<double>());
381 delta_t,
t, bp::extract<np::ndarray>(python_coords[0]),
382 bp::extract<np::ndarray>(python_coords[1]),
383 bp::extract<np::ndarray>(python_coords[2]),
384 bp::extract<np::ndarray>(python_normals[0]),
385 bp::extract<np::ndarray>(python_normals[1]),
386 bp::extract<np::ndarray>(python_normals[2]), block_id,
388 "Failed python call");
391 if (np_hess_sdf.get_shape()[0] != nb_gauss_pts ||
392 np_hess_sdf.get_shape()[1] != 6) {
394 "Wrong shape of Hessian of SDF returned from "
395 "python, expected: (" +
396 std::to_string(nb_gauss_pts) +
", 6), got: (" +
397 std::to_string(np_hess_sdf.get_shape()[0]) +
", " +
398 std::to_string(np_hess_sdf.get_shape()[1]) +
")");
401 double *hess_ptr =
reinterpret_cast<double *
>(np_hess_sdf.get_data());
403 MatrixDouble m_hess_sdf;
404 m_hess_sdf.resize(6, nb_gauss_pts,
false);
405 for (
size_t gg = 0; gg < nb_gauss_pts; ++gg) {
406 for (
int idx = 0; idx < 6; ++idx)
407 m_hess_sdf(idx, gg) =
408 *(hess_ptr + (6 * gg + idx));
413 MatrixDouble m_hess_sdf;
414 m_hess_sdf.resize(6, nb_gauss_pts,
false);
418 auto t_hess_sdf = getFTensor2SymmetricFromMat<3>(m_hess_sdf);
420 for (
size_t gg = 0; gg < nb_gauss_pts; ++gg) {
421 t_hess_sdf(
i,
j) = t_hess_sdf_set(
i,
j);
427template <
int DIM, IntegrationType I,
typename BoundaryEleOp>
430template <
int DIM, IntegrationType I,
typename BoundaryEleOp>
433template <
int DIM, IntegrationType I,
typename BoundaryEleOp>
436template <
int DIM, IntegrationType I,
typename AssemblyBoundaryEleOp>
439template <
int DIM, IntegrationType I,
typename AssemblyBoundaryEleOp>
442template <
int DIM, IntegrationType I,
typename AssemblyBoundaryEleOp>
445template <
typename T1,
typename T2,
int DIM1,
int DIM2>
448 size_t nb_gauss_pts) {
449 MatrixDouble m_spatial_coords(nb_gauss_pts, 3);
450 m_spatial_coords.clear();
451 auto t_spatial_coords = getFTensor1FromPtr<3>(&m_spatial_coords(0, 0));
453 for (
auto gg = 0; gg != nb_gauss_pts; ++gg) {
454 t_spatial_coords(
i) = t_coords(
i) + t_disp(
i);
459 return m_spatial_coords;
462template <
typename T1,
int DIM1>
464 size_t nb_gauss_pts) {
465 MatrixDouble m_normals_at_pts(3, nb_gauss_pts);
466 m_normals_at_pts.clear();
468 auto t_set_normal = getFTensor1FromMat<3>(m_normals_at_pts);
469 for (
auto gg = 0; gg != nb_gauss_pts; ++gg) {
470 t_set_normal(
i) = t_normal_at_pts(
i) / t_normal_at_pts.l2();
474 return m_normals_at_pts;
477template <
int DIM,
typename BoundaryEleOp>
481 boost::shared_ptr<CommonData> common_data_ptr,
double scale = 1,
483 MoFEMErrorCode doWork(
int side, EntityType type,
EntData &data);
491template <
int DIM,
typename BoundaryEleOp>
495 boost::shared_ptr<CommonData> common_data_ptr,
497 boost::shared_ptr<Range> contact_range_ptr =
nullptr);
498 MoFEMErrorCode doWork(
int side, EntityType type,
EntData &data);
510template <
int DIM,
typename BoundaryEleOp>
513 MoFEMErrorCode doWork(
int side, EntityType type,
EntData &data);
525template <
int DIM,
typename AssemblyBoundaryEleOp>
529 boost::shared_ptr<CommonData> common_data_ptr,
531 MoFEMErrorCode iNtegrate(EntitiesFieldData::EntData &data);
542template <
int DIM,
typename AssemblyBoundaryEleOp>
546 const std::string col_field_name,
547 boost::shared_ptr<CommonData> common_data_ptr,
549 MoFEMErrorCode iNtegrate(EntitiesFieldData::EntData &row_data,
550 EntitiesFieldData::EntData &col_data);
562template <
int DIM,
typename AssemblyBoundaryEleOp>
566 const std::string row_field_name,
const std::string col_field_name,
567 boost::shared_ptr<CommonData> common_data_ptr,
569 MoFEMErrorCode iNtegrate(EntitiesFieldData::EntData &row_data,
570 EntitiesFieldData::EntData &col_data);
582 template <
int DIM, IntegrationType I>
586 template <
int DIM, IntegrationType I>
590 template <
int DIM, IntegrationType I>
598 template <
int DIM, IntegrationType I>
602 template <
int DIM, IntegrationType I>
606 template <
int DIM, IntegrationType I>
613 constexpr auto eps = std::numeric_limits<float>::epsilon();
614 if (std::abs(x) <
eps)
622inline double w(
const double sdf,
const double tn) {
640template <
int DIM,
typename BoundaryEleOp>
643 boost::shared_ptr<CommonData> common_data_ptr,
double scale,
646 commonDataPtr(common_data_ptr), scaleTraction(
scale),
649template <
int DIM,
typename BoundaryEleOp>
652 int side, EntityType type,
EntData &data) {
658 auto t_w = BoundaryEleOp::getFTensor0IntegrationWeight();
659 auto t_traction = getFTensor1FromMat<DIM>(commonDataPtr->contactTraction);
660 auto t_coords = BoundaryEleOp::getFTensor1CoordsAtGaussPts();
662 const auto nb_gauss_pts = BoundaryEleOp::getGaussPts().size2();
663 for (
auto gg = 0; gg != nb_gauss_pts; ++gg) {
664 double jacobian = 1.;
665 if (isAxisymmetric) {
666 jacobian = 2. * M_PI * t_coords(0);
668 const double alpha = t_w * jacobian * BoundaryEleOp::getMeasure();
669 t_sum_t(
i) += alpha * t_traction(
i);
675 t_sum_t(
i) *= scaleTraction;
677 constexpr int ind[] = {0, 1, 2};
678 CHKERR VecSetValues(commonDataPtr->totalTraction, 3, ind, &t_sum_t(0),
683template <
int DIM,
typename BoundaryEleOp>
687 boost::shared_ptr<Range> contact_range_ptr)
690 contactRange(contact_range_ptr) {}
692template <
int DIM,
typename BoundaryEleOp>
695 int side, EntityType type,
EntData &data) {
698 auto fe_type = BoundaryEleOp::getFEType();
700 const auto fe_ent = BoundaryEleOp::getFEEntityHandle();
702 if (contactRange->find(fe_ent) != contactRange->end()) {
707 auto t_w = BoundaryEleOp::getFTensor0IntegrationWeight();
708 auto t_traction = getFTensor1FromMat<DIM>(commonDataPtr->contactTraction);
709 auto t_coords = BoundaryEleOp::getFTensor1CoordsAtGaussPts();
711 auto t_grad = getFTensor2FromMat<DIM, DIM>(commonDataPtr->contactDispGrad);
712 auto t_normal_at_pts = BoundaryEleOp::getFTensor1NormalsAtGaussPts();
714 const auto nb_gauss_pts = BoundaryEleOp::getGaussPts().size2();
716 BoundaryEleOp::getFTensor1CoordsAtGaussPts(),
717 getFTensor1FromMat<DIM>(commonDataPtr->contactDisp), nb_gauss_pts);
719 BoundaryEleOp::getFTensor1NormalsAtGaussPts(), nb_gauss_pts);
721 auto t_normal = getFTensor1FromMat<3>(m_normals_at_pts);
722 auto ts_time = BoundaryEleOp::getTStime();
723 auto ts_time_step = BoundaryEleOp::getTStimeStep();
726 surfaceDistanceFunction(ts_time_step, ts_time, nb_gauss_pts,
727 m_spatial_coords, m_normals_at_pts, block_id);
728 auto m_grad_sdf = gradSurfaceDistanceFunction(
729 ts_time_step, ts_time, nb_gauss_pts, m_spatial_coords, m_normals_at_pts,
731 auto t_sdf = getFTensor0FromVec(v_sdf);
732 auto t_grad_sdf = getFTensor1FromMat<3>(m_grad_sdf);
733 for (
auto gg = 0; gg != nb_gauss_pts; ++gg) {
734 double jacobian = 1.;
735 if (isAxisymmetric) {
736 jacobian = 2. * M_PI * t_coords(0);
738 auto tn = -t_traction(
i) * t_grad_sdf(
i);
740 double alpha = t_w * jacobian;
746 F(
i,
j) = t_grad(
i,
j) + kronecker_delta(
i,
j);
747 auto det = determinantTensor(
F);
748 CHKERR invertTensor(
F, det, invF);
749 t_normal_current(
i) = det * (invF(
j,
i) * t_normal_at_pts(
j));
751 alpha *= sqrt(t_normal_current(
i) * t_normal_current(
i));
753 if (fe_type == MBTRI) {
769 constexpr int ind[] = {3, 4};
770 CHKERR VecSetValues(commonDataPtr->totalTraction, 2, ind, &t_sum_a(0),
776template <
int DIM,
typename BoundaryEleOp>
778 boost::shared_ptr<CommonData> common_data_ptr)
780 commonDataPtr(common_data_ptr) {}
782template <
int DIM,
typename BoundaryEleOp>
788 const auto nb_gauss_pts = BoundaryEleOp::getGaussPts().size2();
789 auto &sdf_vec = commonDataPtr->sdfVals;
790 auto &grad_mat = commonDataPtr->gradsSdf;
791 auto &hess_mat = commonDataPtr->hessSdf;
792 auto &constraint_vec = commonDataPtr->constraintVals;
793 auto &contactTraction_mat = commonDataPtr->contactTraction;
795 sdf_vec.resize(nb_gauss_pts,
false);
796 grad_mat.resize(DIM, nb_gauss_pts,
false);
797 hess_mat.resize((DIM * (DIM + 1)) / 2, nb_gauss_pts,
false);
798 constraint_vec.resize(nb_gauss_pts,
false);
800 auto t_traction = getFTensor1FromMat<DIM>(contactTraction_mat);
802 auto t_sdf = getFTensor0FromVec(sdf_vec);
803 auto t_grad_sdf = getFTensor1FromMat<DIM>(grad_mat);
804 auto t_hess_sdf = getFTensor2SymmetricFromMat<DIM>(hess_mat);
805 auto t_constraint = getFTensor0FromVec(constraint_vec);
807 auto t_disp = getFTensor1FromMat<DIM>(commonDataPtr->contactDisp);
808 auto t_coords = BoundaryEleOp::getFTensor1CoordsAtGaussPts();
809 auto t_normal_at_pts = BoundaryEleOp::getFTensor1NormalsAtGaussPts();
814 auto ts_time = BoundaryEleOp::getTStime();
815 auto ts_time_step = BoundaryEleOp::getTStimeStep();
818 BoundaryEleOp::getFTensor1CoordsAtGaussPts(),
819 getFTensor1FromMat<DIM>(commonDataPtr->contactDisp), nb_gauss_pts);
821 BoundaryEleOp::getFTensor1NormalsAtGaussPts(), nb_gauss_pts);
827 surfaceDistanceFunction(ts_time_step, ts_time, nb_gauss_pts,
828 m_spatial_coords, m_normals_at_pts, block_id);
831 gradSurfaceDistanceFunction(ts_time_step, ts_time, nb_gauss_pts,
832 m_spatial_coords, m_normals_at_pts, block_id);
835 hessSurfaceDistanceFunction(ts_time_step, ts_time, nb_gauss_pts,
836 m_spatial_coords, m_normals_at_pts, block_id);
838 auto t_sdf_v = getFTensor0FromVec(v_sdf);
839 auto t_grad_sdf_v = getFTensor1FromMat<3>(m_grad_sdf);
840 auto t_hess_sdf_v = getFTensor2SymmetricFromMat<3>(m_hess_sdf);
854 for (
auto gg = 0; gg != nb_gauss_pts; ++gg) {
856 auto tn = -t_traction(
i) * t_grad_sdf_v(
i);
860 t_grad_sdf(
i) = t_grad_sdf_v(
i);
861 t_hess_sdf(
i,
j) = t_hess_sdf_v(
i,
j);
870template <
int DIM,
typename AssemblyBoundaryEleOp>
873 boost::shared_ptr<CommonData> common_data_ptr,
879template <
int DIM,
typename AssemblyBoundaryEleOp>
882 EntitiesFieldData::EntData &data) {
890 const size_t nb_gauss_pts = AssemblyBoundaryEleOp::getGaussPts().size2();
892 auto &nf = AssemblyBoundaryEleOp::locF;
894 auto t_normal_at_pts = AssemblyBoundaryEleOp::getFTensor1NormalsAtGaussPts();
896 auto t_w = AssemblyBoundaryEleOp::getFTensor0IntegrationWeight();
897 auto t_disp = getFTensor1FromMat<DIM>(commonDataPtr->contactDisp);
898 auto t_traction = getFTensor1FromMat<DIM>(commonDataPtr->contactTraction);
899 auto t_coords = AssemblyBoundaryEleOp::getFTensor1CoordsAtGaussPts();
901 size_t nb_base_functions = data.getN().size2() / 3;
902 auto t_base = data.getFTensor1N<3>();
905 BoundaryEleOp::getFTensor1CoordsAtGaussPts(),
906 getFTensor1FromMat<DIM>(commonDataPtr->contactDisp), nb_gauss_pts);
908 BoundaryEleOp::getFTensor1NormalsAtGaussPts(), nb_gauss_pts);
910 auto t_normal = getFTensor1FromMat<3>(m_normals_at_pts);
912 auto ts_time = AssemblyBoundaryEleOp::getTStime();
913 auto ts_time_step = AssemblyBoundaryEleOp::getTStimeStep();
919 surfaceDistanceFunction(ts_time_step, ts_time, nb_gauss_pts,
920 m_spatial_coords, m_normals_at_pts, block_id);
923 gradSurfaceDistanceFunction(ts_time_step, ts_time, nb_gauss_pts,
924 m_spatial_coords, m_normals_at_pts, block_id);
926 auto t_sdf = getFTensor0FromVec(v_sdf);
927 auto t_grad_sdf = getFTensor1FromMat<3>(m_grad_sdf);
929 for (
size_t gg = 0; gg != nb_gauss_pts; ++gg) {
931 auto t_nf = getFTensor1FromPtr<DIM>(&nf[0]);
933 double jacobian = 1.;
934 if (isAxisymmetric) {
935 jacobian = 2. * M_PI * t_coords(0);
937 const double alpha = t_w * jacobian * AssemblyBoundaryEleOp::getMeasure();
939 auto tn = -t_traction(
i) * t_grad_sdf(
i);
943 t_cP(
i,
j) = (
c * t_grad_sdf(
i)) * t_grad_sdf(
j);
945 t_cQ(
i,
j) = kronecker_delta(
i,
j) - t_cP(
i,
j);
954 t_cP(
i,
j) * t_disp(
j) +
955 c * (t_sdf * t_grad_sdf(
i));
958 for (; bb != AssemblyBoundaryEleOp::nbRows / DIM; ++bb) {
959 const double beta = alpha * (t_base(
i) * t_normal(
i));
960 t_nf(
i) -= beta * t_rhs(
i);
965 for (; bb < nb_base_functions; ++bb)
980template <
int DIM,
typename AssemblyBoundaryEleOp>
983 const std::string col_field_name,
984 boost::shared_ptr<CommonData> common_data_ptr,
989 AssemblyBoundaryEleOp::sYmm =
false;
992template <
int DIM,
typename AssemblyBoundaryEleOp>
995 EntitiesFieldData::EntData &row_data,
996 EntitiesFieldData::EntData &col_data) {
1003 const size_t nb_gauss_pts = AssemblyBoundaryEleOp::getGaussPts().size2();
1004 auto &locMat = AssemblyBoundaryEleOp::locMat;
1006 auto t_normal_at_pts = AssemblyBoundaryEleOp::getFTensor1NormalsAtGaussPts();
1007 auto t_traction = getFTensor1FromMat<DIM>(commonDataPtr->contactTraction);
1008 auto t_coords = AssemblyBoundaryEleOp::getFTensor1CoordsAtGaussPts();
1010 auto t_w = AssemblyBoundaryEleOp::getFTensor0IntegrationWeight();
1011 auto t_row_base = row_data.getFTensor1N<3>();
1012 size_t nb_face_functions = row_data.getN().size2() / 3;
1015 BoundaryEleOp::getFTensor1CoordsAtGaussPts(),
1016 getFTensor1FromMat<DIM>(commonDataPtr->contactDisp), nb_gauss_pts);
1018 BoundaryEleOp::getFTensor1NormalsAtGaussPts(), nb_gauss_pts);
1020 auto t_normal = getFTensor1FromMat<3>(m_normals_at_pts);
1022 auto ts_time = AssemblyBoundaryEleOp::getTStime();
1023 auto ts_time_step = AssemblyBoundaryEleOp::getTStimeStep();
1029 surfaceDistanceFunction(ts_time_step, ts_time, nb_gauss_pts,
1030 m_spatial_coords, m_normals_at_pts, block_id);
1033 gradSurfaceDistanceFunction(ts_time_step, ts_time, nb_gauss_pts,
1034 m_spatial_coords, m_normals_at_pts, block_id);
1037 hessSurfaceDistanceFunction(ts_time_step, ts_time, nb_gauss_pts,
1038 m_spatial_coords, m_normals_at_pts, block_id);
1040 auto t_sdf = getFTensor0FromVec(v_sdf);
1041 auto t_grad_sdf = getFTensor1FromMat<3>(m_grad_sdf);
1042 auto t_hess_sdf = getFTensor2SymmetricFromMat<3>(m_hess_sdf);
1044 for (
size_t gg = 0; gg != nb_gauss_pts; ++gg) {
1046 double jacobian = 1.;
1047 if (isAxisymmetric) {
1048 jacobian = 2. * M_PI * t_coords(0);
1050 const double alpha = t_w * jacobian * AssemblyBoundaryEleOp::getMeasure();
1052 auto tn = -t_traction(
i) * t_grad_sdf(
i);
1056 t_cP(
i,
j) = (
c * t_grad_sdf(
i)) * t_grad_sdf(
j);
1058 t_cQ(
i,
j) = kronecker_delta(
i,
j) - t_cP(
i,
j);
1061 t_res_dU(
i,
j) = kronecker_delta(
i,
j) + t_cP(
i,
j);
1066 (t_hess_sdf(
i,
j) * (t_grad_sdf(
k) * t_traction(
k)) +
1067 t_grad_sdf(
i) * t_hess_sdf(
k,
j) * t_traction(
k)) +
1068 c * t_sdf * t_hess_sdf(
i,
j);
1072 for (; rr != AssemblyBoundaryEleOp::nbRows / DIM; ++rr) {
1074 auto t_mat = getFTensor2FromArray<DIM, DIM, DIM>(locMat, DIM * rr);
1076 const double row_base = t_row_base(
i) * t_normal(
i);
1078 auto t_col_base = col_data.getFTensor0N(gg, 0);
1079 for (
size_t cc = 0; cc != AssemblyBoundaryEleOp::nbCols / DIM; ++cc) {
1080 const double beta = alpha * row_base * t_col_base;
1082 t_mat(
i,
j) -= beta * t_res_dU(
i,
j);
1090 for (; rr < nb_face_functions; ++rr)
1105template <
int DIM,
typename AssemblyBoundaryEleOp>
1108 const std::string row_field_name,
const std::string col_field_name,
1113 AssemblyBoundaryEleOp::sYmm =
false;
1116template <
int DIM,
typename AssemblyBoundaryEleOp>
1119 iNtegrate(EntitiesFieldData::EntData &row_data,
1120 EntitiesFieldData::EntData &col_data) {
1127 const size_t nb_gauss_pts = AssemblyBoundaryEleOp::getGaussPts().size2();
1128 auto &locMat = AssemblyBoundaryEleOp::locMat;
1130 auto t_normal_at_pts = AssemblyBoundaryEleOp::getFTensor1NormalsAtGaussPts();
1131 auto t_traction = getFTensor1FromMat<DIM>(commonDataPtr->contactTraction);
1132 auto t_coords = AssemblyBoundaryEleOp::getFTensor1CoordsAtGaussPts();
1134 auto t_w = AssemblyBoundaryEleOp::getFTensor0IntegrationWeight();
1135 auto t_row_base = row_data.getFTensor1N<3>();
1136 size_t nb_face_functions = row_data.getN().size2() / 3;
1139 BoundaryEleOp::getFTensor1CoordsAtGaussPts(),
1140 getFTensor1FromMat<DIM>(commonDataPtr->contactDisp), nb_gauss_pts);
1142 BoundaryEleOp::getFTensor1NormalsAtGaussPts(), nb_gauss_pts);
1144 auto t_normal = getFTensor1FromMat<3>(m_normals_at_pts);
1146 auto ts_time = AssemblyBoundaryEleOp::getTStime();
1147 auto ts_time_step = AssemblyBoundaryEleOp::getTStimeStep();
1153 surfaceDistanceFunction(ts_time_step, ts_time, nb_gauss_pts,
1154 m_spatial_coords, m_normals_at_pts, block_id);
1157 gradSurfaceDistanceFunction(ts_time_step, ts_time, nb_gauss_pts,
1158 m_spatial_coords, m_normals_at_pts, block_id);
1160 auto t_sdf = getFTensor0FromVec(v_sdf);
1161 auto t_grad_sdf = getFTensor1FromMat<3>(m_grad_sdf);
1163 for (
size_t gg = 0; gg != nb_gauss_pts; ++gg) {
1165 double jacobian = 1.;
1166 if (isAxisymmetric) {
1167 jacobian = 2. * M_PI * t_coords(0);
1169 const double alpha = t_w * jacobian * AssemblyBoundaryEleOp::getMeasure();
1171 auto tn = -t_traction(
i) * t_grad_sdf(
i);
1175 t_cP(
i,
j) = (
c * t_grad_sdf(
i)) * t_grad_sdf(
j);
1177 t_cQ(
i,
j) = kronecker_delta(
i,
j) - t_cP(
i,
j);
1183 for (; rr != AssemblyBoundaryEleOp::nbRows / DIM; ++rr) {
1185 auto t_mat = getFTensor2FromArray<DIM, DIM, DIM>(locMat, DIM * rr);
1186 const double row_base = t_row_base(
i) * t_normal(
i);
1188 auto t_col_base = col_data.getFTensor1N<3>(gg, 0);
1189 for (
size_t cc = 0; cc != AssemblyBoundaryEleOp::nbCols / DIM; ++cc) {
1190 const double col_base = t_col_base(
i) * t_normal(
i);
1191 const double beta = alpha * row_base * col_base;
1193 t_mat(
i,
j) -= beta * t_res_dt(
i,
j);
1201 for (; rr < nb_face_functions; ++rr)
1215template <
int DIM, AssemblyType A, IntegrationType I,
typename DomainEleOp>
1217 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pip,
1221 using B =
typename FormsIntegrators<DomainEleOp>::template Assembly<
1223 using OpMixDivURhs =
typename B::template OpMixDivTimesU<3, DIM, DIM>;
1224 using OpMixDivUCylRhs =
1225 typename B::template OpMixDivTimesU<3, DIM, DIM, CYLINDRICAL>;
1227 using OpMixLambdaGradURhs =
typename B::template OpMixTensorTimesGradU<DIM>;
1228 using OpMixUTimesDivLambdaRhs =
1229 typename B::template OpMixVecTimesDivLambda<SPACE_DIM>;
1230 using OpMixUTimesLambdaRhs =
1233 auto common_data_ptr = boost::make_shared<ContactOps::CommonData>();
1234 auto mat_grad_ptr = boost::make_shared<MatrixDouble>();
1235 auto div_stress_ptr = boost::make_shared<MatrixDouble>();
1236 auto contact_stress_ptr = boost::make_shared<MatrixDouble>();
1241 return 2. * M_PI * r;
1246 pip.push_back(
new OpCalculateVectorFieldValues<DIM>(
1247 u, common_data_ptr->contactDispPtr()));
1249 new OpCalculateHVecTensorField<DIM, DIM>(sigma, contact_stress_ptr));
1253 new OpCalculateHVecTensorDivergence<DIM, DIM>(sigma, div_stress_ptr));
1255 pip.push_back(
new OpCalculateHVecTensorDivergence<DIM, DIM, CYLINDRICAL>(
1256 sigma, div_stress_ptr));
1259 pip.push_back(
new OpCalculateVectorFieldGradient<DIM, DIM>(u, mat_grad_ptr));
1263 new OpMixDivURhs(sigma, common_data_ptr->contactDispPtr(), jacobian));
1265 pip.push_back(
new OpMixDivUCylRhs(sigma, common_data_ptr->contactDispPtr(),
1269 pip.push_back(
new OpMixLambdaGradURhs(sigma, mat_grad_ptr, jacobian));
1270 pip.push_back(
new OpMixUTimesDivLambdaRhs(u, div_stress_ptr, jacobian));
1271 pip.push_back(
new OpMixUTimesLambdaRhs(u, contact_stress_ptr, jacobian));
1277 using OpMixLhs::OpMixLhs;
1278 MoFEMErrorCode
doWork(
int row_side,
int col_side, EntityType row_type,
1279 EntityType col_type,
1280 EntitiesFieldData::EntData &row_data,
1281 EntitiesFieldData::EntData &col_data) {
1283 auto side_fe_entity = OpMixLhs::getSidePtrFE()->getFEEntityHandle();
1284 auto side_fe_data = OpMixLhs::getSideEntity(row_side, row_type);
1286 if (side_fe_entity == side_fe_data) {
1287 CHKERR OpMixLhs::doWork(row_side, col_side, row_type, col_type, row_data,
1294template <
int DIM, AssemblyType A, IntegrationType I,
typename DomainEle>
1297 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pip,
1298 std::string fe_domain_name, std::string sigma, std::string u,
1299 std::string geom, ForcesAndSourcesCore::RuleHookFun rule,
1303 using DomainEleOp =
typename DomainEle::UserDataOperator;
1305 auto op_loop_side =
new OpLoopSide<DomainEle>(
1306 m_field, fe_domain_name, DIM, Sev::noisy,
1307 boost::make_shared<ForcesAndSourcesCore::UserDataOperator::AdjCache>());
1308 pip.push_back(op_loop_side);
1313 using B =
typename FormsIntegrators<DomainEleOp>::template Assembly<
1316 using OpMixDivULhs =
typename B::template OpMixDivTimesVec<DIM>;
1317 using OpMixDivUCylLhs =
1318 typename B::template OpMixDivTimesVec<DIM, CYLINDRICAL>;
1319 using OpLambdaGraULhs =
typename B::template OpMixTensorTimesGrad<DIM>;
1325 auto unity = []() {
return 1; };
1329 return 2. * M_PI * r;
1335 op_loop_side->getOpPtrVector().push_back(
1336 new OpMixDivULhsSide(sigma, u, unity, jacobian,
true));
1338 op_loop_side->getOpPtrVector().push_back(
1339 new OpMixDivUCylLhsSide(sigma, u, unity, jacobian,
true));
1341 op_loop_side->getOpPtrVector().push_back(
1342 new OpLambdaGraULhsSide(sigma, u, unity, jacobian,
true));
1344 op_loop_side->getSideFEPtr()->getRuleHook = rule;
1348template <
int DIM, AssemblyType A, IntegrationType I,
typename BoundaryEleOp>
1350 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pip,
1356 auto common_data_ptr = boost::make_shared<ContactOps::CommonData>();
1358 pip.push_back(
new OpCalculateVectorFieldValues<DIM>(
1359 u, common_data_ptr->contactDispPtr()));
1360 pip.push_back(
new OpCalculateHVecTensorTrace<DIM, BoundaryEleOp>(
1361 sigma, common_data_ptr->contactTractionPtr()));
1363 new typename C::template Assembly<A>::template OpConstrainBoundaryLhs_dU<
1365 pip.push_back(
new typename C::template Assembly<A>::
1366 template OpConstrainBoundaryLhs_dTraction<DIM, GAUSS>(
1372template <
int DIM, AssemblyType A, IntegrationType I,
typename BoundaryEleOp>
1374 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pip,
1380 auto common_data_ptr = boost::make_shared<ContactOps::CommonData>();
1382 pip.push_back(
new OpCalculateVectorFieldValues<DIM>(
1383 u, common_data_ptr->contactDispPtr()));
1384 pip.push_back(
new OpCalculateHVecTensorTrace<DIM, BoundaryEleOp>(
1385 sigma, common_data_ptr->contactTractionPtr()));
1387 new typename C::template Assembly<A>::template OpConstrainBoundaryRhs<
1393template <
int DIM, IntegrationType I,
typename BoundaryEleOp>
1395 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pip,
1401 auto common_data_ptr = boost::make_shared<ContactOps::CommonData>();
1402 pip.push_back(
new OpCalculateHVecTensorTrace<DIM, BoundaryEleOp>(
1403 sigma, common_data_ptr->contactTractionPtr()));
1404 pip.push_back(
new typename C::template OpAssembleTotalContactTraction<DIM, I>(
1410template <
int DIM, IntegrationType I,
typename BoundaryEleOp>
1412 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pip,
1413 OpLoopSide<SideEle> *op_loop_side, std::string sigma, std::string u,
1415 boost::shared_ptr<Range> contact_range_ptr =
nullptr) {
1419 auto common_data_ptr = boost::make_shared<ContactOps::CommonData>();
1421 op_loop_side->getOpPtrVector().push_back(
1422 new OpCalculateVectorFieldGradient<SPACE_DIM, SPACE_DIM>(
1423 "U", common_data_ptr->contactDispGradPtr()));
1425 if (contact_range_ptr) {
1426 pip.push_back(
new OpCalculateVectorFieldValues<DIM>(
1427 u, common_data_ptr->contactDispPtr()));
1428 pip.push_back(
new OpCalculateHVecTensorTrace<DIM, BoundaryEleOp>(
1429 sigma, common_data_ptr->contactTractionPtr()));
1430 pip.push_back(op_loop_side);
1431 pip.push_back(
new typename C::template OpAssembleTotalContactArea<DIM, I>(
#define CHK_THROW_MESSAGE(err, msg)
Check and throw MoFEM exception.
#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_OPERATION_UNSUCCESSFUL
@ MOFEM_DATA_INCONSISTENCY
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
FTensor::Index< 'i', SPACE_DIM > i
const double c
speed of light (cm/ns)
FTensor::Index< 'l', 3 > l
FTensor::Index< 'j', 3 > j
FTensor::Index< 'k', 3 > k
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
hess_sdf(delta_t, t, x, y, z, tx, ty, tz, block_id)
grad_sdf(delta_t, t, x, y, z, tx, ty, tz, block_id)
FormsIntegrators< DomainEleOp >::Assembly< A >::LinearForm< I >::OpGradTimesTensor< 1, FIELD_DIM, SPACE_DIM > OpGradTimesTensor
constexpr double t
plate stiffness
constexpr auto field_name
virtual MPI_Comm & get_comm() const =0
virtual int get_comm_rank() const =0
Deprecated interface functions.