v0.14.0
EshelbianOperators.cpp
Go to the documentation of this file.
1 /**
2  * \file EshelbianOperators.cpp
3  * \example EshelbianOperators.cpp
4  *
5  * \brief Implementation of operators
6  */
7 
8 #include <MoFEM.hpp>
9 using namespace MoFEM;
10 
11 #include <EshelbianPlasticity.hpp>
12 #include <boost/math/constants/constants.hpp>
13 
14 #include <lapack_wrap.h>
15 
16 #include <MatrixFunction.hpp>
17 
18 namespace EshelbianPlasticity {
19 
20 inline auto diff_deviator(FTensor::Ddg<double, 3, 3> &&t_diff_stress) {
25 
26  FTensor::Ddg<double, 3, 3> t_diff_deviator;
27  t_diff_deviator(i, j, k, l) = t_diff_stress(i, j, k, l);
28 
29  constexpr double third = boost::math::constants::third<double>();
30 
31  t_diff_deviator(0, 0, 0, 0) -= third;
32  t_diff_deviator(0, 0, 1, 1) -= third;
33 
34  t_diff_deviator(1, 1, 0, 0) -= third;
35  t_diff_deviator(1, 1, 1, 1) -= third;
36 
37  t_diff_deviator(2, 2, 0, 0) -= third;
38  t_diff_deviator(2, 2, 1, 1) -= third;
39 
40  t_diff_deviator(0, 0, 2, 2) -= third;
41  t_diff_deviator(1, 1, 2, 2) -= third;
42  t_diff_deviator(2, 2, 2, 2) -= third;
43 
44  return t_diff_deviator;
45 }
46 
47 constexpr static auto size_symm = (3 * (3 + 1)) / 2;
48 
49 inline auto diff_tensor() {
56  t_diff(i, j, k, l) = (t_kd(i, k) ^ t_kd(j, l)) / 4.;
57  return t_diff;
58 };
59 
60 inline auto symm_L_tensor() {
65  t_L(i, j, L) = 0;
66  t_L(0, 0, 0) = 1;
67  t_L(1, 1, 3) = 1;
68  t_L(2, 2, 5) = 1;
69  t_L(1, 0, 1) = 1;
70  t_L(2, 0, 2) = 1;
71  t_L(2, 1, 4) = 1;
72  return t_L;
73 }
74 
75 inline auto diff_symmetrize() {
76 
81 
83 
84  t_diff(i, j, k, l) = 0;
85  t_diff(0, 0, 0, 0) = 1;
86  t_diff(1, 1, 1, 1) = 1;
87 
88  t_diff(1, 0, 1, 0) = 0.5;
89  t_diff(1, 0, 0, 1) = 0.5;
90 
91  t_diff(0, 1, 0, 1) = 0.5;
92  t_diff(0, 1, 1, 0) = 0.5;
93 
94  if constexpr (SPACE_DIM == 3) {
95  t_diff(2, 2, 2, 2) = 1;
96 
97  t_diff(2, 0, 2, 0) = 0.5;
98  t_diff(2, 0, 0, 2) = 0.5;
99  t_diff(0, 2, 0, 2) = 0.5;
100  t_diff(0, 2, 2, 0) = 0.5;
101 
102  t_diff(2, 1, 2, 1) = 0.5;
103  t_diff(2, 1, 1, 2) = 0.5;
104  t_diff(1, 2, 1, 2) = 0.5;
105  t_diff(1, 2, 2, 1) = 0.5;
106  }
107 
108  return t_diff;
109 }
110 
111 template <class T> struct TensorTypeExtractor {
113 };
114 template <class T, int I> struct TensorTypeExtractor<FTensor::PackPtr<T, I>> {
116 };
117 
118 template <typename T>
120  RotSelector rotSelector = LARGE_ROT) {
121 
122  using D = typename TensorTypeExtractor<T>::Type;
123 
128 
129  constexpr auto t_kd = FTensor::Kronecker_Delta<int>();
130  t_R(i, j) = t_kd(i, j);
131 
133  t_Omega(i, j) = FTensor::levi_civita<double>(i, j, k) * t_omega(k);
134 
135  if (rotSelector == SMALL_ROT) {
136  t_R(i, j) += t_Omega(i, j);
137  return t_R;
138  }
139 
140  const auto angle =
141  sqrt(t_omega(i) * t_omega(i)) + std::numeric_limits<double>::epsilon();
142  const auto a = sin(angle) / angle;
143  t_R(i, j) += a * t_Omega(i, j);
144  if (rotSelector == MODERATE_ROT)
145  return t_R;
146 
147  const auto ss_2 = sin(angle / 2.) / angle;
148  const auto b = 2. * ss_2 * ss_2;
149  t_R(i, j) += b * t_Omega(i, k) * t_Omega(k, j);
150 
151  return t_R;
152 }
153 
154 template <typename T>
156  RotSelector rotSelector = LARGE_ROT) {
157 
158  using D = typename TensorTypeExtractor<T>::Type;
159 
164 
166 
167  const auto angle =
168  sqrt(t_omega(i) * t_omega(i)) + std::numeric_limits<double>::epsilon();
169  if (rotSelector == SMALL_ROT) {
170  t_diff_R(i, j, k) = FTensor::levi_civita<double>(i, j, k);
171  return t_diff_R;
172  }
173 
174  const auto ss = sin(angle);
175  const auto a = ss / angle;
176  t_diff_R(i, j, k) = a * FTensor::levi_civita<double>(i, j, k);
177 
179  t_Omega(i, j) = FTensor::levi_civita<double>(i, j, k) * t_omega(k);
180 
181  const auto angle2 = angle * angle;
182  const auto cc = cos(angle);
183  const auto diff_a = (angle * cc - ss) / angle2;
184  t_diff_R(i, j, k) += diff_a * t_Omega(i, j) * (t_omega(k) / angle);
185  if (rotSelector == MODERATE_ROT)
186  return t_diff_R;
187 
188  const auto ss_2 = sin(angle / 2.);
189  const auto cc_2 = cos(angle / 2.);
190  const auto b = 2. * ss_2 * ss_2 / angle2;
191  t_diff_R(i, j, k) +=
192  b * (t_Omega(i, l) * FTensor::levi_civita<double>(l, j, k) +
193  FTensor::levi_civita<double>(i, l, k) * t_Omega(l, j));
194  const auto diff_b =
195  (2. * angle * ss_2 * cc_2 - 4. * ss_2 * ss_2) / (angle2 * angle);
196  t_diff_R(i, j, k) +=
197  diff_b * t_Omega(i, l) * t_Omega(l, j) * (t_omega(k) / angle);
198 
199  return t_diff_R;
200 }
201 
202 template <typename T>
204  RotSelector rotSelector = LARGE_ROT) {
205 
206  using D = typename TensorTypeExtractor<T>::Type;
207 
210 
211  constexpr double eps = 1e-10;
212  for (int l = 0; l != 3; ++l) {
214  t_omega_c(i) = t_omega(i);
215  t_omega_c(l) += std::complex<double>(0, eps);
216  auto t_diff_R_c = get_diff_rotation_form_vector(t_omega_c, rotSelector);
217  for (int i = 0; i != 3; ++i) {
218  for (int j = 0; j != 3; ++j) {
219  for (int k = 0; k != 3; ++k) {
220  t_diff2_R(i, j, k, l) = t_diff_R_c(i, j, k).imag() / eps;
221  }
222  }
223  }
224  }
225 
226  return t_diff2_R;
227 }
228 
229 struct isEq {
230  static inline auto check(const double &a, const double &b) {
231  constexpr double eps = std::numeric_limits<float>::epsilon();
232  return std::abs(a - b) / absMax < eps;
233  }
234  static double absMax;
235 };
236 
237 double isEq::absMax = 1;
238 
239 inline auto is_eq(const double &a, const double &b) {
240  return isEq::check(a, b);
241 };
242 
243 template <int DIM> inline auto get_uniq_nb(double *ptr) {
244  std::array<double, DIM> tmp;
245  std::copy(ptr, &ptr[DIM], tmp.begin());
246  std::sort(tmp.begin(), tmp.end());
247  isEq::absMax = std::max(std::abs(tmp[0]), std::abs(tmp[DIM - 1]));
248  constexpr double eps = std::numeric_limits<float>::epsilon();
249  isEq::absMax = std::max(isEq::absMax, static_cast<double>(eps));
250  return std::distance(tmp.begin(), std::unique(tmp.begin(), tmp.end(), is_eq));
251 }
252 
253 template <int DIM>
256 
257  isEq::absMax =
258  std::max(std::max(std::abs(eig(0)), std::abs(eig(1))), std::abs(eig(2)));
259 
260  int i = 0, j = 1, k = 2;
261 
262  if (is_eq(eig(0), eig(1))) {
263  i = 0;
264  j = 2;
265  k = 1;
266  } else if (is_eq(eig(0), eig(2))) {
267  i = 0;
268  j = 1;
269  k = 2;
270  } else if (is_eq(eig(1), eig(2))) {
271  i = 1;
272  j = 0;
273  k = 2;
274  }
275 
276  FTensor::Tensor2<double, 3, 3> eigen_vec_c{
277  eigen_vec(i, 0), eigen_vec(i, 1), eigen_vec(i, 2),
278 
279  eigen_vec(j, 0), eigen_vec(j, 1), eigen_vec(j, 2),
280 
281  eigen_vec(k, 0), eigen_vec(k, 1), eigen_vec(k, 2)};
282 
283  FTensor::Tensor1<double, 3> eig_c{eig(i), eig(j), eig(k)};
284 
285  {
288  eig(i) = eig_c(i);
289  eigen_vec(i, j) = eigen_vec_c(i, j);
290  }
291 }
292 
293 MoFEMErrorCode OpCalculateStretchFromStress::doWork(int side, EntityType type,
294  EntData &data) {
296 
303 
304  auto nb_integration_pts = dataAtPts->approxPAtPts.size2();
305 #ifdef NDEBUG
306  if (nb_integration_pts != getGaussPts().size2()) {
307  SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
308  "inconsistent number of integration points");
309  }
310 #endif // NDEBUG
311 
312  auto get_invert_D = [&]() {
314  dataAtPts->matInvD.resize(size_symm * size_symm, 1, false);
315  MatrixDouble inv_mat(size_symm, size_symm);
316  for (auto r = 0; r != size_symm; ++r) {
317  for (auto c = 0; c != size_symm; ++c) {
318  inv_mat(r, c) = dataAtPts->matD(r * size_symm + c, 0);
319  }
320  }
321  CHKERR computeMatrixInverse(inv_mat);
322  dataAtPts->matInvD.resize(size_symm * size_symm, 1, true);
323  for (auto r = 0; r != size_symm; ++r) {
324  for (auto c = 0; c != size_symm; ++c) {
325  dataAtPts->matInvD(r * size_symm + c, 0) = inv_mat(r, c);
326  }
327  }
329  };
330 
331  CHKERR get_invert_D();
332 
333  dataAtPts->logStretchTensorAtPts.resize(size_symm, nb_integration_pts, false);
334 
335  auto t_log_u =
336  getFTensor2SymmetricFromMat<3>(dataAtPts->logStretchTensorAtPts);
337  auto t_approx_P =
338  getFTensor2FromMat<SPACE_DIM, SPACE_DIM>(dataAtPts->approxPAtPts);
339  auto t_inv_D =
340  getFTensor4DdgFromMat<SPACE_DIM, SPACE_DIM, 0>(dataAtPts->matInvD);
341 
342  // note: add rotation, so we can extract rigid body motion, work then with
343  // symmetric part.
344  for (auto gg = 0; gg != nb_integration_pts; ++gg) {
345  t_log_u(i, j) = t_inv_D(i, j, k, l) * t_approx_P(k, l);
346  ++t_log_u;
347  ++t_approx_P;
348  ++t_inv_D;
349  }
350 
352 }
353 
354 MoFEMErrorCode OpCalculateRotationAndSpatialGradient::doWork(int side,
355  EntityType type,
356  EntData &data) {
358 
360  auto t_L = symm_L_tensor();
361 
362  int nb_integration_pts = getGaussPts().size2();
369 
370  dataAtPts->hAtPts.resize(9, nb_integration_pts, false);
371  dataAtPts->hdOmegaAtPts.resize(9 * 3, nb_integration_pts, false);
372  dataAtPts->hdLogStretchAtPts.resize(9 * 6, nb_integration_pts, false);
373  dataAtPts->leviKirchhoffAtPts.resize(3, nb_integration_pts, false);
374  dataAtPts->leviKirchhoffPAtPts.resize(9 * 3, nb_integration_pts, false);
375  dataAtPts->leviKirchhoffOmegaAtPts.resize(9, nb_integration_pts, false);
376 
377  dataAtPts->adjointPdstretchAtPts.resize(9, nb_integration_pts, false);
378  dataAtPts->adjointPdUAtPts.resize(size_symm, nb_integration_pts, false);
379  dataAtPts->adjointPdUdPAtPts.resize(9 * size_symm, nb_integration_pts, false);
380  dataAtPts->adjointPdUdOmegaAtPts.resize(3 * size_symm, nb_integration_pts,
381  false);
382  dataAtPts->rotMatAtPts.resize(9, nb_integration_pts, false);
383  dataAtPts->diffRotMatAtPts.resize(27, nb_integration_pts, false);
384  dataAtPts->stretchTensorAtPts.resize(6, nb_integration_pts, false);
385  dataAtPts->diffStretchTensorAtPts.resize(36, nb_integration_pts, false);
386  dataAtPts->eigenVals.resize(3, nb_integration_pts, false);
387  dataAtPts->eigenVecs.resize(9, nb_integration_pts, false);
388  dataAtPts->nbUniq.resize(nb_integration_pts, false);
389 
390  dataAtPts->logStretchTotalTensorAtPts.resize(6, nb_integration_pts, false);
391 
392  auto t_h = getFTensor2FromMat<3, 3>(dataAtPts->hAtPts);
393  auto t_h_domega = getFTensor3FromMat<3, 3, 3>(dataAtPts->hdOmegaAtPts);
394  auto t_h_dlog_u =
395  getFTensor3FromMat<3, 3, size_symm>(dataAtPts->hdLogStretchAtPts);
396  auto t_levi_kirchoff = getFTensor1FromMat<3>(dataAtPts->leviKirchhoffAtPts);
397  auto t_levi_kirchoff_dP =
398  getFTensor3FromMat<3, 3, 3>(dataAtPts->leviKirchhoffPAtPts);
399  auto t_levi_kirchoff_domega =
400  getFTensor2FromMat<3, 3>(dataAtPts->leviKirchhoffOmegaAtPts);
401  auto t_approx_P_adjont_dstretch =
402  getFTensor2FromMat<3, 3>(dataAtPts->adjointPdstretchAtPts);
403  auto t_approx_P_adjont_log_du =
404  getFTensor1FromMat<size_symm>(dataAtPts->adjointPdUAtPts);
405  auto t_approx_P_adjont_log_du_dP =
406  getFTensor3FromMat<3, 3, size_symm>(dataAtPts->adjointPdUdPAtPts);
407  auto t_approx_P_adjont_log_du_domega =
408  getFTensor2FromMat<3, size_symm>(dataAtPts->adjointPdUdOmegaAtPts);
409  auto t_omega = getFTensor1FromMat<3>(dataAtPts->rotAxisAtPts);
410  auto t_R = getFTensor2FromMat<3, 3>(dataAtPts->rotMatAtPts);
411  auto t_diff_R = getFTensor3FromMat<3, 3, 3>(dataAtPts->diffRotMatAtPts);
412  auto t_log_u =
413  getFTensor2SymmetricFromMat<3>(dataAtPts->logStretchTensorAtPts);
414  auto t_u = getFTensor2SymmetricFromMat<3>(dataAtPts->stretchTensorAtPts);
415  auto t_approx_P = getFTensor2FromMat<3, 3>(dataAtPts->approxPAtPts);
416  auto t_diff_u =
417  getFTensor4DdgFromMat<3, 3, 1>(dataAtPts->diffStretchTensorAtPts);
418  auto t_eigen_vals = getFTensor1FromMat<3>(dataAtPts->eigenVals);
419  auto t_eigen_vecs = getFTensor2FromMat<3, 3>(dataAtPts->eigenVecs);
420 
421  auto &nbUniq = dataAtPts->nbUniq;
422  auto t_grad_h1 = getFTensor2FromMat<3, 3>(dataAtPts->wGradH1AtPts);
423  auto t_log_stretch_total =
424  getFTensor2SymmetricFromMat<3>(dataAtPts->logStretchTotalTensorAtPts);
426 
427  for (int gg = 0; gg != nb_integration_pts; ++gg) {
428 
434  FTensor::Tensor2<double, 3, 3> t_approx_P_intermidiate;
435 
436  switch (EshelbianCore::gradApperoximator) {
437  case NO_H1_CONFIGURATION:
438  t_h1(i, j) = t_kd(i, j);
439  break;
440  case LARGE_ROT:
441  case MODERATE_ROT:
442  t_h1(i, j) = t_grad_h1(i, j) + t_kd(i, j);
443  break;
444  case SMALL_ROT:
445  t_h1(i, j) = t_kd(i, j);
446  break;
447  };
448 
449  auto calculate_rotation = [&]() {
450  auto t0_diff =
451  get_diff_rotation_form_vector(t_omega, EshelbianCore::rotSelector);
452  auto t0 = get_rotation_form_vector(t_omega, EshelbianCore::rotSelector);
453  t_diff_R(i, j, k) = t0_diff(i, j, k);
454  t_R(i, j) = t0(i, j);
455  };
456 
457  auto calculate_stretch = [&]() {
458  eigen_vec(i, j) = t_log_u(i, j);
459  CHKERR computeEigenValuesSymmetric(eigen_vec, eig);
460  // rare case when two eigen values are equal
461  nbUniq[gg] = get_uniq_nb<3>(&eig(0));
462  if (nbUniq[gg] < 3) {
463  sort_eigen_vals<3>(eig, eigen_vec);
464  }
465  t_eigen_vals(i) = eig(i);
466  t_eigen_vecs(i, j) = eigen_vec(i, j);
467  auto t_u_tmp =
468  EigenMatrix::getMat(t_eigen_vals, t_eigen_vecs, EshelbianCore::f);
469  t_u(i, j) = t_u_tmp(i, j);
470  auto t_diff_u_tmp =
471  EigenMatrix::getDiffMat(t_eigen_vals, t_eigen_vecs, EshelbianCore::f,
472  EshelbianCore::d_f, nbUniq[gg]);
473  t_diff_u(i, j, k, l) = t_diff_u_tmp(i, j, k, l);
474  t_Ldiff_u(i, j, L) = t_diff_u(i, j, m, n) * t_L(m, n, L);
475  };
476 
477  calculate_rotation();
478 
479  if (!EshelbianCore::noStretch) {
480 
481  calculate_stretch();
482 
483  switch (EshelbianCore::gradApperoximator) {
484  case NO_H1_CONFIGURATION:
485  case LARGE_ROT:
486 
487  // rotation can be large, moderate or small
488  t_Ru(i, m) = t_R(i, l) * t_u(l, m);
489  t_h(i, j) = t_Ru(i, m) * t_h1(m, j);
490  t_h_domega(i, j, k) = (t_diff_R(i, l, k) * t_u(l, m)) * t_h1(m, j);
491  t_h_dlog_u(i, j, L) = (t_R(i, l) * t_Ldiff_u(l, m, L)) * t_h1(m, j);
492 
493  // conservation of angular momentum at current configuration
494  t_approx_P_intermidiate(i, m) = t_approx_P(i, j) * t_h1(m, j);
495  t_approx_P_adjont_dstretch(l, m) =
496  t_approx_P_intermidiate(i, m) * t_R(i, l);
497 
498  t_levi_kirchoff(k) =
499  levi_civita(l, m, k) * (t_approx_P_adjont_dstretch(l, m));
500  t_levi_kirchoff_dP(i, j, k) =
501  (levi_civita(l, m, k) * t_R(i, l)) * t_h1(m, j);
502  t_levi_kirchoff_domega(k, n) =
503  levi_civita(l, m, k) *
504  (t_approx_P_intermidiate(i, m) * t_diff_R(i, l, n));
505 
506  t_approx_P_adjont_log_du(L) =
507  t_Ldiff_u(l, m, L) * t_approx_P_adjont_dstretch(l, m);
508  t_approx_P_adjont_log_du_dP(i, j, L) = t_h_dlog_u(i, j, L);
509  t_approx_P_adjont_log_du_domega(n, L) =
510  t_Ldiff_u(l, m, L) *
511  (t_approx_P_intermidiate(i, m) * t_diff_R(i, l, n));
512 
513  break;
514  case MODERATE_ROT:
515 
516  {
517 
518  // assume small current rotation
520  t_Omega(i, j) = FTensor::levi_civita<double>(i, j, k) * t_omega(k);
521  t_Ru(i, m) = t_Omega(i, m) + t_u(i, m);
522  t_h(i, j) = t_Ru(i, m) * t_h1(m, j);
523  t_h_domega(i, j, k) =
524  FTensor::levi_civita<double>(i, m, k) * t_h1(m, j);
525  t_h_dlog_u(i, j, L) = t_Ldiff_u(i, m, L) * t_h1(m, j);
526 
527  // conservation of angular momentum at intermediate configuration
528  t_approx_P_intermidiate(i, m) = t_approx_P(i, j) * t_h1(m, j);
529  t_approx_P_adjont_dstretch(i, m) = t_approx_P_intermidiate(i, m);
530 
531  t_levi_kirchoff(k) =
532  levi_civita(i, m, k) * (t_approx_P_adjont_dstretch(i, m));
533  t_levi_kirchoff_dP(i, j, k) = levi_civita(i, m, k) * t_h1(m, j);
534  t_levi_kirchoff_domega(k, n) = 0;
535 
536  t_approx_P_adjont_log_du(L) =
537  t_Ldiff_u(i, m, L) * t_approx_P_adjont_dstretch(i, m);
538  t_approx_P_adjont_log_du_dP(i, j, L) = t_h_dlog_u(i, j, L);
539  t_approx_P_adjont_log_du_domega(n, L) = 0;
540 
541  }
542 
543  break;
544 
545  case SMALL_ROT:
546 
547  {
548 
549  // assume small current rotation
551  t_Omega(i, j) = FTensor::levi_civita<double>(i, j, k) * t_omega(k);
552  t_h(i, j) = t_Omega(i, j) + t_u(i, j);
553  t_h_domega(i, j, k) = FTensor::levi_civita<double>(i, j, k);
554  t_h_dlog_u(i, j, L) = t_Ldiff_u(i, j, L);
555 
556  // conservation of angular momentum at reference condition
557  t_levi_kirchoff(k) = levi_civita(i, j, k) * t_approx_P(i, j);
558  t_levi_kirchoff_dP(i, j, k) = levi_civita(i, j, k);
559  t_levi_kirchoff_domega(k, l) = 0;
560 
561  t_approx_P_adjont_dstretch(i, j) = t_approx_P(i, j);
562  t_approx_P_adjont_log_du(L) =
563  t_Ldiff_u(i, j, L) * t_approx_P_adjont_dstretch(i, j);
564  t_approx_P_adjont_log_du_dP(i, j, L) = t_h_dlog_u(i, j, L);
565  t_approx_P_adjont_log_du_domega(m, L) = 0;
566 
567  }
568 
569  break;
570  }
571 
573  t_C_h1(i, j) = t_h1(k, i) * t_h1(k, j);
574  eigen_vec(i, j) = t_C_h1(i, j);
575  CHKERR computeEigenValuesSymmetric(eigen_vec, eig);
576  switch (EshelbianCore::stretchSelector) {
578  break;
580  for (int ii = 0; ii != 3; ++ii) {
581  eig(ii) = std::max(
582  eig(ii), 2 * EshelbianCore::inv_f(EshelbianCore::f(
583  std::numeric_limits<float>::min_exponent)));
584  }
585  break;
586  }
587 
588  switch (EshelbianCore::gradApperoximator) {
589  case NO_H1_CONFIGURATION:
590  t_log_stretch_total(i, j) = t_log_u(i, j);
591  break;
592  case LARGE_ROT:
593  case MODERATE_ROT: {
594  auto t_log_u2_h1_tmp =
595  EigenMatrix::getMat(eig, eigen_vec, EshelbianCore::inv_f);
596  t_log_stretch_total(i, j) = t_log_u2_h1_tmp(i, j) / 2 + t_log_u(i, j);
597  } break;
598  case SMALL_ROT:
599  t_log_stretch_total(i, j) = t_log_u(i, j);
600  break;
601  };
602 
603  } else {
604 
606 
608  t_Omega(i, j) = FTensor::levi_civita<double>(i, j, k) * t_omega(k);
609  t_u(i, j) = t_kd(i, j) + t_log_u(i, j);
610  t_h(i, j) = t_Omega(i, j) + t_u(i, j);
611  t_h_domega(i, j, k) = FTensor::levi_civita<double>(i, j, k);
612 
613  // conservation of angular momentum at reference condition
614  t_levi_kirchoff(k) = levi_civita(i, j, k) * t_approx_P(i, j);
615  t_levi_kirchoff_dP(i, j, k) = levi_civita(i, j, k);
616  t_levi_kirchoff_domega(k, l) = 0;
617  }
618 
619  ++t_h;
620  ++t_h_domega;
621  ++t_h_dlog_u;
622  ++t_levi_kirchoff;
623  ++t_levi_kirchoff_dP;
624  ++t_levi_kirchoff_domega;
625  ++t_approx_P_adjont_dstretch;
626  ++t_approx_P_adjont_log_du;
627  ++t_approx_P_adjont_log_du_dP;
628  ++t_approx_P_adjont_log_du_domega;
629  ++t_approx_P;
630  ++t_R;
631  ++t_diff_R;
632  ++t_log_u;
633  ++t_u;
634  ++t_diff_u;
635  ++t_eigen_vals;
636  ++t_eigen_vecs;
637  ++t_omega;
638  ++t_grad_h1;
639  ++t_log_stretch_total;
640  }
641 
643 }
644 
645 MoFEMErrorCode OpSpatialEquilibrium::integrate(EntData &data) {
647  int nb_dofs = data.getIndices().size();
648  int nb_integration_pts = data.getN().size1();
649  auto v = getVolume();
650  auto t_w = getFTensor0IntegrationWeight();
651  auto t_div_P = getFTensor1FromMat<3>(dataAtPts->divPAtPts);
652  auto t_s_dot_w = getFTensor1FromMat<3>(dataAtPts->wL2DotAtPts);
653  if (dataAtPts->wL2DotDotAtPts.size1() == 0 &&
654  dataAtPts->wL2DotDotAtPts.size2() != nb_integration_pts) {
655  dataAtPts->wL2DotDotAtPts.resize(3, nb_integration_pts);
656  dataAtPts->wL2DotDotAtPts.clear();
657  }
658  auto t_s_dot_dot_w = getFTensor1FromMat<3>(dataAtPts->wL2DotDotAtPts);
659 
660  int nb_base_functions = data.getN().size2();
661  auto t_row_base_fun = data.getFTensor0N();
662 
664  auto get_ftensor1 = [](auto &v) {
666  &v[2]);
667  };
668 
669  for (int gg = 0; gg != nb_integration_pts; ++gg) {
670  double a = v * t_w;
671  auto t_nf = get_ftensor1(nF);
672  int bb = 0;
673  for (; bb != nb_dofs / 3; ++bb) {
674  t_nf(i) += a * t_row_base_fun * t_div_P(i);
675  t_nf(i) -= a * t_row_base_fun * alphaW * t_s_dot_w(i);
676  t_nf(i) -= a * t_row_base_fun * alphaRho * t_s_dot_dot_w(i);
677  ++t_nf;
678  ++t_row_base_fun;
679  }
680  for (; bb != nb_base_functions; ++bb)
681  ++t_row_base_fun;
682  ++t_w;
683  ++t_div_P;
684  ++t_s_dot_w;
685  ++t_s_dot_dot_w;
686  }
687 
689 }
690 
691 MoFEMErrorCode OpSpatialRotation::integrate(EntData &data) {
693  int nb_dofs = data.getIndices().size();
694  int nb_integration_pts = getGaussPts().size2();
695  auto v = getVolume();
696  auto t_w = getFTensor0IntegrationWeight();
697  auto t_levi_kirchoff = getFTensor1FromMat<3>(dataAtPts->leviKirchhoffAtPts);
698  int nb_base_functions = data.getN().size2();
699  auto t_row_base_fun = data.getFTensor0N();
703  auto get_ftensor1 = [](auto &v) {
705  &v[2]);
706  };
707  for (int gg = 0; gg != nb_integration_pts; ++gg) {
708  double a = v * t_w;
709  auto t_nf = get_ftensor1(nF);
710  int bb = 0;
711  for (; bb != nb_dofs / 3; ++bb) {
712  t_nf(k) += (a * t_row_base_fun) * t_levi_kirchoff(k);
713  ++t_nf;
714  ++t_row_base_fun;
715  }
716  for (; bb != nb_base_functions; ++bb) {
717  ++t_row_base_fun;
718  }
719  ++t_w;
720  ++t_levi_kirchoff;
721  }
723 }
724 
725 MoFEMErrorCode OpSpatialPhysical::integrate(EntData &data) {
727 
728  if (dataAtPts->physicsPtr->dependentVariablesPiola.size()) {
729  CHKERR integratePiola(data);
730  } else {
731  if (polyConvex) {
732  CHKERR integratePolyconvexHencky(data);
733  } else {
734  CHKERR integrateHencky(data);
735  }
736  }
737 
739 }
740 
741 MoFEMErrorCode OpSpatialPhysical::integrateHencky(EntData &data) {
743 
745  auto t_L = symm_L_tensor();
746 
747  int nb_dofs = data.getIndices().size();
748  int nb_integration_pts = data.getN().size1();
749  auto v = getVolume();
750  auto t_w = getFTensor0IntegrationWeight();
751  auto t_approx_P_adjont_log_du =
752  getFTensor1FromMat<size_symm>(dataAtPts->adjointPdUAtPts);
753  auto t_log_stretch_h1 =
754  getFTensor2SymmetricFromMat<3>(dataAtPts->logStretchTotalTensorAtPts);
755  auto t_dot_log_u =
756  getFTensor2SymmetricFromMat<3>(dataAtPts->logStretchDotTensorAtPts);
757 
758  auto t_D = getFTensor4DdgFromMat<3, 3, 0>(dataAtPts->matD);
759 
764  auto get_ftensor2 = [](auto &v) {
766  &v[0], &v[1], &v[2], &v[3], &v[4], &v[5]);
767  };
768 
769  int nb_base_functions = data.getN().size2();
770  auto t_row_base_fun = data.getFTensor0N();
771  for (int gg = 0; gg != nb_integration_pts; ++gg) {
772  double a = v * t_w;
773  auto t_nf = get_ftensor2(nF);
774 
776  t_T(i, j) =
777  t_D(i, j, k, l) * (t_log_stretch_h1(k, l) + alphaU * t_dot_log_u(k, l));
779  t_residual(L) =
780  a * (t_approx_P_adjont_log_du(L) - t_L(i, j, L) * t_T(i, j));
781 
782  int bb = 0;
783  for (; bb != nb_dofs / 6; ++bb) {
784  t_nf(L) += t_row_base_fun * t_residual(L);
785  ++t_nf;
786  ++t_row_base_fun;
787  }
788  for (; bb != nb_base_functions; ++bb)
789  ++t_row_base_fun;
790 
791  ++t_w;
792  ++t_approx_P_adjont_log_du;
793  ++t_dot_log_u;
794  ++t_log_stretch_h1;
795  }
797 }
798 
799 MoFEMErrorCode OpSpatialPhysical::integratePolyconvexHencky(EntData &data) {
801 
803  auto t_L = symm_L_tensor();
804 
805  int nb_dofs = data.getIndices().size();
806  int nb_integration_pts = data.getN().size1();
807  auto v = getVolume();
808  auto t_w = getFTensor0IntegrationWeight();
809  auto t_approx_P_adjont_log_du =
810  getFTensor1FromMat<size_symm>(dataAtPts->adjointPdUAtPts);
811  auto t_log_stretch_h1 =
812  getFTensor2SymmetricFromMat<3>(dataAtPts->logStretchTotalTensorAtPts);
813  auto t_dot_log_u =
814  getFTensor2SymmetricFromMat<3>(dataAtPts->logStretchDotTensorAtPts);
815 
816  auto t_D = getFTensor4DdgFromMat<3, 3, 0>(dataAtPts->matD);
817 
822  auto get_ftensor2 = [](auto &v) {
824  &v[0], &v[1], &v[2], &v[3], &v[4], &v[5]);
825  };
826 
827  constexpr double nohat_k = 1. / 4;
828  constexpr double hat_k = 1. / 8;
829  double mu = dataAtPts->mu;
830  double lambda = dataAtPts->lambda;
831 
832  constexpr double third = boost::math::constants::third<double>();
834  auto t_diff_deviator = diff_deviator(diff_tensor());
835 
836  int nb_base_functions = data.getN().size2();
837  auto t_row_base_fun = data.getFTensor0N();
838  for (int gg = 0; gg != nb_integration_pts; ++gg) {
839  double a = v * t_w;
840  auto t_nf = get_ftensor2(nF);
841 
842  double log_det = t_log_stretch_h1(i, i);
843  double log_det2 = log_det * log_det;
845  t_dev(i, j) = t_log_stretch_h1(i, j) - t_kd(i, j) * (third * log_det);
846  double dev_norm2 = t_dev(i, j) * t_dev(i, j);
847 
849  auto A = 2 * mu * std::exp(nohat_k * dev_norm2);
850  auto B = lambda * std::exp(hat_k * log_det2) * log_det;
851  t_T(i, j) =
852 
853  A * (t_dev(k, l) * t_diff_deviator(k, l, i, j))
854 
855  +
856 
857  B * t_kd(i, j)
858 
859  +
860 
861  alphaU * t_D(i, j, k, l) * t_log_stretch_h1(k, l);
862 
864  t_residual(L) =
865  a * (t_approx_P_adjont_log_du(L) - t_L(i, j, L) * t_T(i, j));
866 
867  int bb = 0;
868  for (; bb != nb_dofs / 6; ++bb) {
869  t_nf(L) += t_row_base_fun * t_residual(L);
870  ++t_nf;
871  ++t_row_base_fun;
872  }
873  for (; bb != nb_base_functions; ++bb)
874  ++t_row_base_fun;
875 
876  ++t_w;
877  ++t_approx_P_adjont_log_du;
878  ++t_dot_log_u;
879  ++t_log_stretch_h1;
880  }
882 }
883 
884 MoFEMErrorCode OpSpatialPhysical::integratePiola(EntData &data) {
886 
888  auto t_L = symm_L_tensor();
889 
890  int nb_dofs = data.getIndices().size();
891  int nb_integration_pts = data.getN().size1();
892  auto v = getVolume();
893  auto t_w = getFTensor0IntegrationWeight();
894  auto t_approx_P_adjont_log_du =
895  getFTensor1FromMat<size_symm>(dataAtPts->adjointPdUAtPts);
896  auto t_P = getFTensor2FromMat<3, 3>(dataAtPts->PAtPts);
897  auto t_dot_log_u =
898  getFTensor2SymmetricFromMat<3>(dataAtPts->logStretchDotTensorAtPts);
899  auto t_diff_u =
900  getFTensor4DdgFromMat<3, 3, 1>(dataAtPts->diffStretchTensorAtPts);
901 
906  auto get_ftensor2 = [](auto &v) {
908  &v[0], &v[1], &v[2], &v[3], &v[4], &v[5]);
909  };
910 
911  int nb_base_functions = data.getN().size2();
912  auto t_row_base_fun = data.getFTensor0N();
913  for (int gg = 0; gg != nb_integration_pts; ++gg) {
914  double a = v * t_w;
915  auto t_nf = get_ftensor2(nF);
916 
918  t_Ldiff_u(i, j, L) = t_diff_u(i, j, k, l) * t_L(k, l, L);
919 
921  t_viscous_P(i, j) =
922  alphaU *
923  t_dot_log_u(i,
924  j); // That is chit, should be split on axiator and deviator
925 
927  t_residual(L) =
928  a * (t_approx_P_adjont_log_du(L) - t_Ldiff_u(i, j, L) * t_P(i, j) -
929  t_L(i, j, L) * t_viscous_P(i, j));
930 
931  int bb = 0;
932  for (; bb != nb_dofs / 6; ++bb) {
933  t_nf(L) += t_row_base_fun * t_residual(L);
934  ++t_nf;
935  ++t_row_base_fun;
936  }
937  for (; bb != nb_base_functions; ++bb)
938  ++t_row_base_fun;
939 
940  ++t_w;
941  ++t_approx_P_adjont_log_du;
942  ++t_P;
943  ++t_dot_log_u;
944  ++t_diff_u;
945  }
947 }
948 
949 MoFEMErrorCode OpSpatialConsistencyP::integrate(EntData &data) {
951  int nb_dofs = data.getIndices().size();
952  int nb_integration_pts = data.getN().size1();
953  auto v = getVolume();
954  auto t_w = getFTensor0IntegrationWeight();
955  auto t_h = getFTensor2FromMat<3, 3>(dataAtPts->hAtPts);
956 
957  int nb_base_functions = data.getN().size2() / 3;
958  auto t_row_base_fun = data.getFTensor1N<3>();
963 
964  auto get_ftensor1 = [](auto &v) {
966  &v[2]);
967  };
968 
969  for (int gg = 0; gg != nb_integration_pts; ++gg) {
970  double a = v * t_w;
971  auto t_nf = get_ftensor1(nF);
972 
973  constexpr auto t_kd = FTensor::Kronecker_Delta<int>();
975  t_residuum(i, j) = t_h(i, j) - t_kd(i, j);
976 
977  int bb = 0;
978  for (; bb != nb_dofs / 3; ++bb) {
979  t_nf(i) += a * t_row_base_fun(j) * t_residuum(i, j);
980  ++t_nf;
981  ++t_row_base_fun;
982  }
983 
984  for (; bb != nb_base_functions; ++bb)
985  ++t_row_base_fun;
986 
987  ++t_w;
988  ++t_h;
989  }
990 
992 }
993 
994 MoFEMErrorCode OpSpatialConsistencyBubble::integrate(EntData &data) {
996  int nb_dofs = data.getIndices().size();
997  int nb_integration_pts = data.getN().size1();
998  auto v = getVolume();
999  auto t_w = getFTensor0IntegrationWeight();
1000  auto t_h = getFTensor2FromMat<3, 3>(dataAtPts->hAtPts);
1001 
1002  int nb_base_functions = data.getN().size2() / 9;
1003  auto t_row_base_fun = data.getFTensor2N<3, 3>();
1008 
1009  auto get_ftensor0 = [](auto &v) {
1011  };
1012 
1013  for (int gg = 0; gg != nb_integration_pts; ++gg) {
1014  double a = v * t_w;
1015  auto t_nf = get_ftensor0(nF);
1016 
1017  constexpr auto t_kd = FTensor::Kronecker_Delta<int>();
1018  FTensor::Tensor2<double, 3, 3> t_residuum;
1019  t_residuum(i, j) = t_h(i, j) - t_kd(i, j);
1020 
1021  int bb = 0;
1022  for (; bb != nb_dofs; ++bb) {
1023  t_nf += a * t_row_base_fun(i, j) * t_residuum(i, j);
1024  ++t_nf;
1025  ++t_row_base_fun;
1026  }
1027  for (; bb != nb_base_functions; ++bb) {
1028  ++t_row_base_fun;
1029  }
1030  ++t_w;
1031  ++t_h;
1032  }
1033 
1035 }
1036 
1037 MoFEMErrorCode OpSpatialConsistencyDivTerm::integrate(EntData &data) {
1039  int nb_dofs = data.getIndices().size();
1040  int nb_integration_pts = data.getN().size1();
1041  auto v = getVolume();
1042  auto t_w = getFTensor0IntegrationWeight();
1043  auto t_w_l2 = getFTensor1FromMat<3>(dataAtPts->wL2AtPts);
1044  int nb_base_functions = data.getN().size2() / 3;
1045  auto t_row_diff_base_fun = data.getFTensor2DiffN<3, 3>();
1047  auto get_ftensor1 = [](auto &v) {
1049  &v[2]);
1050  };
1051 
1052  for (int gg = 0; gg != nb_integration_pts; ++gg) {
1053  double a = v * t_w;
1054  auto t_nf = get_ftensor1(nF);
1055  int bb = 0;
1056  for (; bb != nb_dofs / 3; ++bb) {
1057  double div_row_base = t_row_diff_base_fun(i, i);
1058  t_nf(i) += a * div_row_base * t_w_l2(i);
1059  ++t_nf;
1060  ++t_row_diff_base_fun;
1061  }
1062  for (; bb != nb_base_functions; ++bb) {
1063  ++t_row_diff_base_fun;
1064  }
1065  ++t_w;
1066  ++t_w_l2;
1067  }
1068 
1070 }
1071 
1072 MoFEMErrorCode OpDispBc::integrate(EntData &data) {
1074  // get entity of face
1075  EntityHandle fe_ent = getFEEntityHandle();
1076  // interate over all boundary data
1077  for (auto &bc : (*bcDispPtr)) {
1078  // check if finite element entity is part of boundary condition
1079  if (bc.faces.find(fe_ent) != bc.faces.end()) {
1080  int nb_dofs = data.getIndices().size();
1081  int nb_integration_pts = data.getN().size1();
1082  auto t_normal = getFTensor1Normal();
1083  auto t_w = getFTensor0IntegrationWeight();
1084  int nb_base_functions = data.getN().size2() / 3;
1085  auto t_row_base_fun = data.getFTensor1N<3>();
1086 
1089  auto get_ftensor1 = [](auto &v) {
1091  &v[2]);
1092  };
1093 
1094  double scale = 1;
1095  for (auto &sm : scalingMethodsVec) {
1096  scale *= sm->getScale(getFEMethod()->ts_t);
1097  }
1098 
1099  // get bc data
1100  FTensor::Tensor1<double, 3> t_bc_disp(bc.vals[0], bc.vals[1], bc.vals[2]);
1101  t_bc_disp(i) *= scale;
1102 
1103  for (int gg = 0; gg != nb_integration_pts; ++gg) {
1104  FTensor::Tensor1<double, 3> t_bc_res;
1105  t_bc_res(i) = t_bc_disp(i);
1106  auto t_nf = get_ftensor1(nF);
1107  int bb = 0;
1108  for (; bb != nb_dofs / 3; ++bb) {
1109  t_nf(i) -=
1110  t_w * (t_row_base_fun(j) * t_normal(j)) * t_bc_res(i) * 0.5;
1111  ++t_nf;
1112  ++t_row_base_fun;
1113  }
1114  for (; bb != nb_base_functions; ++bb)
1115  ++t_row_base_fun;
1116 
1117  ++t_w;
1118  }
1119  }
1120  }
1122 }
1123 
1124 MoFEMErrorCode OpRotationBc::integrate(EntData &data) {
1126  // get entity of face
1127  EntityHandle fe_ent = getFEEntityHandle();
1128  // interate over all boundary data
1129  for (auto &bc : (*bcRotPtr)) {
1130  // check if finite element entity is part of boundary condition
1131  if (bc.faces.find(fe_ent) != bc.faces.end()) {
1132  int nb_dofs = data.getIndices().size();
1133  int nb_integration_pts = data.getN().size1();
1134  auto t_normal = getFTensor1Normal();
1135  auto t_w = getFTensor0IntegrationWeight();
1136 
1137  int nb_base_functions = data.getN().size2() / 3;
1138  auto t_row_base_fun = data.getFTensor1N<3>();
1142  auto get_ftensor1 = [](auto &v) {
1144  &v[2]);
1145  };
1146 
1147  // get bc data
1148  FTensor::Tensor1<double, 3> t_center(bc.vals[0], bc.vals[1], bc.vals[2]);
1149 
1150  double theta = bc.theta;
1151  theta *= getFEMethod()->ts_t;
1152 
1154  const double a = sqrt(t_normal(i) * t_normal(i));
1155  t_omega(i) = t_normal(i) * (theta / a);
1156  auto t_R = get_rotation_form_vector(t_omega, LARGE_ROT);
1157  auto t_coords = getFTensor1CoordsAtGaussPts();
1158 
1159  for (int gg = 0; gg != nb_integration_pts; ++gg) {
1161  t_delta(i) = t_center(i) - t_coords(i);
1163  t_disp(i) = t_delta(i) - t_R(i, j) * t_delta(j);
1164 
1165  auto t_nf = get_ftensor1(nF);
1166  int bb = 0;
1167  for (; bb != nb_dofs / 3; ++bb) {
1168  t_nf(i) -= t_w * (t_row_base_fun(j) * t_normal(j)) * t_disp(i) * 0.5;
1169  ++t_nf;
1170  ++t_row_base_fun;
1171  }
1172  for (; bb != nb_base_functions; ++bb)
1173  ++t_row_base_fun;
1174 
1175  ++t_w;
1176  ++t_coords;
1177  }
1178  }
1179  }
1181 }
1182 
1183 MoFEMErrorCode FeTractionBc::preProcess() {
1185 
1186  struct FaceRule {
1187  int operator()(int p_row, int p_col, int p_data) const {
1188  return 2 * (p_data + 1);
1189  }
1190  };
1191 
1192  if (ts_ctx == CTX_TSSETIFUNCTION) {
1193 
1194  // Loop boundary elements with traction boundary conditions
1197  {HDIV});
1198  fe.getOpPtrVector().push_back(
1199  new OpTractionBc(std::string("P") /* + "_RT"*/, *this));
1200  fe.getRuleHook = FaceRule();
1201  fe.ts_t = ts_t;
1202  CHKERR mField.loop_finite_elements(problemPtr->getName(), "ESSENTIAL_BC",
1203  fe, nullptr, MF_ZERO,
1204  this->getCacheWeakPtr());
1205  }
1206 
1208 }
1209 
1210 MoFEMErrorCode OpTractionBc::doWork(int side, EntityType type, EntData &data) {
1212 
1215 
1216  auto t_normal = getFTensor1Normal();
1217  const double nrm2 = sqrt(t_normal(i) * t_normal(i));
1218  FTensor::Tensor1<double, 3> t_unit_normal;
1219  t_unit_normal(i) = t_normal(i) / nrm2;
1220  int nb_dofs = data.getFieldData().size();
1221  int nb_integration_pts = data.getN().size1();
1222  int nb_base_functions = data.getN().size2() / 3;
1223  double ts_t = getFEMethod()->ts_t;
1224 
1225  auto integrate_matrix = [&]() {
1227 
1228  auto t_w = getFTensor0IntegrationWeight();
1229  matPP.resize(nb_dofs / 3, nb_dofs / 3, false);
1230  matPP.clear();
1231 
1232  auto t_row_base_fun = data.getFTensor1N<3>();
1233  for (int gg = 0; gg != nb_integration_pts; ++gg) {
1234 
1235  int rr = 0;
1236  for (; rr != nb_dofs / 3; ++rr) {
1237  const double a = t_row_base_fun(i) * t_unit_normal(i);
1238  auto t_col_base_fun = data.getFTensor1N<3>(gg, 0);
1239  for (int cc = 0; cc != nb_dofs / 3; ++cc) {
1240  const double b = t_col_base_fun(i) * t_unit_normal(i);
1241  matPP(rr, cc) += t_w * a * b;
1242  ++t_col_base_fun;
1243  }
1244  ++t_row_base_fun;
1245  }
1246 
1247  for (; rr != nb_base_functions; ++rr)
1248  ++t_row_base_fun;
1249 
1250  ++t_w;
1251  }
1252 
1254  };
1255 
1256  auto integrate_rhs = [&](auto &bc) {
1258 
1259  auto t_w = getFTensor0IntegrationWeight();
1260  vecPv.resize(3, nb_dofs / 3, false);
1261  vecPv.clear();
1262 
1263  auto t_row_base_fun = data.getFTensor1N<3>();
1264  double ts_t = getFEMethod()->ts_t;
1265 
1266  for (int gg = 0; gg != nb_integration_pts; ++gg) {
1267  int rr = 0;
1268  for (; rr != nb_dofs / 3; ++rr) {
1269  const double t = ts_t * t_w * t_row_base_fun(i) * t_unit_normal(i);
1270  for (int dd = 0; dd != 3; ++dd)
1271  if (bc.flags[dd])
1272  vecPv(dd, rr) += t * bc.vals[dd];
1273  ++t_row_base_fun;
1274  }
1275  for (; rr != nb_base_functions; ++rr)
1276  ++t_row_base_fun;
1277  ++t_w;
1278  }
1280  };
1281 
1282  auto integrate_rhs_cook = [&](auto &bc) {
1284 
1285  vecPv.resize(3, nb_dofs / 3, false);
1286  vecPv.clear();
1287 
1288  auto t_w = getFTensor0IntegrationWeight();
1289  auto t_row_base_fun = data.getFTensor1N<3>();
1290  auto t_coords = getFTensor1CoordsAtGaussPts();
1291 
1292  for (int gg = 0; gg != nb_integration_pts; ++gg) {
1293 
1294  auto calc_tau = [](double y) {
1295  y -= 44;
1296  y /= (60 - 44);
1297  return -y * (y - 1) / 0.25;
1298  };
1299 
1300  const double tau = calc_tau(t_coords(1));
1301 
1302  int rr = 0;
1303  for (; rr != nb_dofs / 3; ++rr) {
1304  const double t = ts_t * t_w * t_row_base_fun(i) * t_unit_normal(i);
1305  for (int dd = 0; dd != 3; ++dd)
1306  if (bc.flags[dd])
1307  vecPv(dd, rr) += t * tau * bc.vals[dd];
1308  ++t_row_base_fun;
1309  }
1310 
1311  for (; rr != nb_base_functions; ++rr)
1312  ++t_row_base_fun;
1313  ++t_w;
1314  ++t_coords;
1315  }
1317  };
1318 
1319  // get entity of face
1320  EntityHandle fe_ent = getFEEntityHandle();
1321  for (auto &bc : *(bcFe.bcData)) {
1322  if (bc.faces.find(fe_ent) != bc.faces.end()) {
1323 
1324  int nb_dofs = data.getFieldData().size();
1325  if (nb_dofs) {
1326 
1327  CHKERR integrate_matrix();
1328  if (std::regex_match(bc.blockName, std::regex(".*COOK.*")))
1329  CHKERR integrate_rhs_cook(bc);
1330  else
1331  CHKERR integrate_rhs(bc);
1332 
1333  const auto info =
1334  lapack_dposv('L', nb_dofs / 3, 3, &*matPP.data().begin(),
1335  nb_dofs / 3, &*vecPv.data().begin(), nb_dofs / 3);
1336  if (info > 0)
1337  SETERRQ1(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
1338  "The leading minor of order %i is "
1339  "not positive; definite;\nthe "
1340  "solution could not be computed",
1341  info);
1342 
1343  for (int dd = 0; dd != 3; ++dd)
1344  if (bc.flags[dd])
1345  for (int rr = 0; rr != nb_dofs / 3; ++rr)
1346  data.getFieldDofs()[3 * rr + dd]->getFieldData() = vecPv(dd, rr);
1347  }
1348  }
1349  }
1350 
1352 }
1353 
1354 MoFEMErrorCode OpSpatialEquilibrium_dw_dP::integrate(EntData &row_data,
1355  EntData &col_data) {
1357  int nb_integration_pts = row_data.getN().size1();
1358  int row_nb_dofs = row_data.getIndices().size();
1359  int col_nb_dofs = col_data.getIndices().size();
1360  auto get_ftensor1 = [](MatrixDouble &m, const int r, const int c) {
1362  &m(r + 0, c + 0), &m(r + 1, c + 1), &m(r + 2, c + 2));
1363  };
1365  auto v = getVolume();
1366  auto t_w = getFTensor0IntegrationWeight();
1367  int row_nb_base_functions = row_data.getN().size2();
1368  auto t_row_base_fun = row_data.getFTensor0N();
1369  for (int gg = 0; gg != nb_integration_pts; ++gg) {
1370  double a = v * t_w;
1371  int rr = 0;
1372  for (; rr != row_nb_dofs / 3; ++rr) {
1373  auto t_col_diff_base_fun = col_data.getFTensor2DiffN<3, 3>(gg, 0);
1374  auto t_m = get_ftensor1(K, 3 * rr, 0);
1375  for (int cc = 0; cc != col_nb_dofs / 3; ++cc) {
1376  double div_col_base = t_col_diff_base_fun(i, i);
1377  t_m(i) += a * t_row_base_fun * div_col_base;
1378  ++t_m;
1379  ++t_col_diff_base_fun;
1380  }
1381  ++t_row_base_fun;
1382  }
1383  for (; rr != row_nb_base_functions; ++rr)
1384  ++t_row_base_fun;
1385  ++t_w;
1386  }
1388 }
1389 
1390 MoFEMErrorCode OpSpatialEquilibrium_dw_dw::integrate(EntData &row_data,
1391  EntData &col_data) {
1393 
1394  if (alphaW < std::numeric_limits<double>::epsilon() &&
1395  alphaRho < std::numeric_limits<double>::epsilon())
1397 
1398  const int nb_integration_pts = row_data.getN().size1();
1399  const int row_nb_dofs = row_data.getIndices().size();
1400  auto get_ftensor1 = [](MatrixDouble &m, const int r, const int c) {
1402  &m(r + 0, c + 0), &m(r + 1, c + 1), &m(r + 2, c + 2)
1403 
1404  );
1405  };
1407 
1408  auto v = getVolume();
1409  auto t_w = getFTensor0IntegrationWeight();
1410 
1411  int row_nb_base_functions = row_data.getN().size2();
1412  auto t_row_base_fun = row_data.getFTensor0N();
1413 
1414  double ts_scale = alphaW * getTSa();
1415  if (std::abs(alphaRho) > std::numeric_limits<double>::epsilon())
1416  ts_scale += alphaRho * getTSaa();
1417 
1418  for (int gg = 0; gg != nb_integration_pts; ++gg) {
1419  double a = v * t_w * ts_scale;
1420 
1421  int rr = 0;
1422  for (; rr != row_nb_dofs / 3; ++rr) {
1423 
1424  auto t_col_base_fun = row_data.getFTensor0N(gg, 0);
1425  auto t_m = get_ftensor1(K, 3 * rr, 0);
1426  for (int cc = 0; cc != row_nb_dofs / 3; ++cc) {
1427  const double b = a * t_row_base_fun * t_col_base_fun;
1428  t_m(i) -= b;
1429  ++t_m;
1430  ++t_col_base_fun;
1431  }
1432 
1433  ++t_row_base_fun;
1434  }
1435 
1436  for (; rr != row_nb_base_functions; ++rr)
1437  ++t_row_base_fun;
1438 
1439  ++t_w;
1440  }
1441 
1443 }
1444 
1445 MoFEMErrorCode OpSpatialPhysical_du_dP::integrate(EntData &row_data,
1446  EntData &col_data) {
1448 
1450 
1451  int nb_integration_pts = row_data.getN().size1();
1452  int row_nb_dofs = row_data.getIndices().size();
1453  int col_nb_dofs = col_data.getIndices().size();
1454  auto get_ftensor3 = [](MatrixDouble &m, const int r, const int c) {
1456 
1457  &m(r + 0, c + 0), &m(r + 0, c + 1), &m(r + 0, c + 2),
1458 
1459  &m(r + 1, c + 0), &m(r + 1, c + 1), &m(r + 1, c + 2),
1460 
1461  &m(r + 2, c + 0), &m(r + 2, c + 1), &m(r + 2, c + 2),
1462 
1463  &m(r + 3, c + 0), &m(r + 3, c + 1), &m(r + 3, c + 2),
1464 
1465  &m(r + 4, c + 0), &m(r + 4, c + 1), &m(r + 4, c + 2),
1466 
1467  &m(r + 5, c + 0), &m(r + 5, c + 1), &m(r + 5, c + 2));
1468  };
1469 
1472 
1473  auto v = getVolume();
1474  auto t_w = getFTensor0IntegrationWeight();
1475  auto t_approx_P_adjont_log_du_dP =
1476  getFTensor3FromMat<3, 3, size_symm>(dataAtPts->adjointPdUdPAtPts);
1477  int row_nb_base_functions = row_data.getN().size2();
1478  auto t_row_base_fun = row_data.getFTensor0N();
1479  for (int gg = 0; gg != nb_integration_pts; ++gg) {
1480  double a = v * t_w;
1481  int rr = 0;
1482  for (; rr != row_nb_dofs / 6; ++rr) {
1483 
1484  auto t_col_base_fun = col_data.getFTensor1N<3>(gg, 0);
1485  auto t_m = get_ftensor3(K, 6 * rr, 0);
1486 
1487  for (int cc = 0; cc != col_nb_dofs / 3; ++cc) {
1488  t_m(L, i) +=
1489  a * (t_approx_P_adjont_log_du_dP(i, j, L) * t_col_base_fun(j)) *
1490  t_row_base_fun;
1491  ++t_col_base_fun;
1492  ++t_m;
1493  }
1494 
1495  ++t_row_base_fun;
1496  }
1497  for (; rr != row_nb_base_functions; ++rr)
1498  ++t_row_base_fun;
1499  ++t_w;
1500  ++t_approx_P_adjont_log_du_dP;
1501  }
1503 }
1504 
1505 MoFEMErrorCode OpSpatialPhysical_du_dBubble::integrate(EntData &row_data,
1506  EntData &col_data) {
1508 
1510 
1511  int nb_integration_pts = row_data.getN().size1();
1512  int row_nb_dofs = row_data.getIndices().size();
1513  int col_nb_dofs = col_data.getIndices().size();
1514  auto get_ftensor2 = [](MatrixDouble &m, const int r, const int c) {
1516  &m(r + 0, c), &m(r + 1, c), &m(r + 2, c), &m(r + 3, c), &m(r + 4, c),
1517  &m(r + 5, c));
1518  };
1519 
1522 
1523  auto v = getVolume();
1524  auto t_w = getFTensor0IntegrationWeight();
1525  auto t_approx_P_adjont_log_du_dP =
1526  getFTensor3FromMat<3, 3, size_symm>(dataAtPts->adjointPdUdPAtPts);
1527 
1528  int row_nb_base_functions = row_data.getN().size2();
1529  auto t_row_base_fun = row_data.getFTensor0N();
1530  for (int gg = 0; gg != nb_integration_pts; ++gg) {
1531  double a = v * t_w;
1532  int rr = 0;
1533  for (; rr != row_nb_dofs / 6; ++rr) {
1534  auto t_m = get_ftensor2(K, 6 * rr, 0);
1535  auto t_col_base_fun = col_data.getFTensor2N<3, 3>(gg, 0);
1536  for (int cc = 0; cc != col_nb_dofs; ++cc) {
1537  t_m(L) +=
1538  a * (t_approx_P_adjont_log_du_dP(i, j, L) * t_col_base_fun(i, j)) *
1539  t_row_base_fun;
1540  ++t_m;
1541  ++t_col_base_fun;
1542  }
1543  ++t_row_base_fun;
1544  }
1545  for (; rr != row_nb_base_functions; ++rr)
1546  ++t_row_base_fun;
1547  ++t_w;
1548  ++t_approx_P_adjont_log_du_dP;
1549  }
1551 }
1552 
1553 MoFEMErrorCode OpSpatialPhysical_du_du::integrate(EntData &row_data,
1554  EntData &col_data) {
1556  if (dataAtPts->physicsPtr->dependentVariablesPiola.size()) {
1557  CHKERR integratePiola(row_data, col_data);
1558  } else {
1559  if (polyConvex) {
1560  CHKERR integratePolyconvexHencky(row_data, col_data);
1561  } else {
1562  CHKERR integrateHencky(row_data, col_data);
1563  }
1564  }
1566 }
1567 
1568 MoFEMErrorCode OpSpatialPhysical_du_du::integrateHencky(EntData &row_data,
1569  EntData &col_data) {
1571 
1574  auto t_L = symm_L_tensor();
1575  auto t_diff = diff_tensor();
1576 
1577  int nb_integration_pts = row_data.getN().size1();
1578  int row_nb_dofs = row_data.getIndices().size();
1579  int col_nb_dofs = col_data.getIndices().size();
1580 
1581  auto get_ftensor2 = [](MatrixDouble &m, const int r, const int c) {
1583  size_symm>(
1584 
1585  &m(r + 0, c + 0), &m(r + 0, c + 1), &m(r + 0, c + 2), &m(r + 0, c + 3),
1586  &m(r + 0, c + 4), &m(r + 0, c + 5),
1587 
1588  &m(r + 1, c + 0), &m(r + 1, c + 1), &m(r + 1, c + 2), &m(r + 1, c + 3),
1589  &m(r + 1, c + 4), &m(r + 1, c + 5),
1590 
1591  &m(r + 2, c + 0), &m(r + 2, c + 1), &m(r + 2, c + 2), &m(r + 2, c + 3),
1592  &m(r + 2, c + 4), &m(r + 2, c + 5),
1593 
1594  &m(r + 3, c + 0), &m(r + 3, c + 1), &m(r + 3, c + 2), &m(r + 3, c + 3),
1595  &m(r + 3, c + 4), &m(r + 3, c + 5),
1596 
1597  &m(r + 4, c + 0), &m(r + 4, c + 1), &m(r + 4, c + 2), &m(r + 4, c + 3),
1598  &m(r + 4, c + 4), &m(r + 4, c + 5),
1599 
1600  &m(r + 5, c + 0), &m(r + 5, c + 1), &m(r + 5, c + 2), &m(r + 5, c + 3),
1601  &m(r + 5, c + 4), &m(r + 5, c + 5)
1602 
1603  );
1604  };
1611 
1612  auto v = getVolume();
1613  auto t_w = getFTensor0IntegrationWeight();
1614 
1615  auto t_approx_P_adjont_dstretch =
1616  getFTensor2FromMat<3, 3>(dataAtPts->adjointPdstretchAtPts);
1617  auto t_eigen_vals = getFTensor1FromMat<3>(dataAtPts->eigenVals);
1618  auto t_eigen_vecs = getFTensor2FromMat<3, 3>(dataAtPts->eigenVecs);
1619  auto &nbUniq = dataAtPts->nbUniq;
1620 
1621  int row_nb_base_functions = row_data.getN().size2();
1622  auto t_row_base_fun = row_data.getFTensor0N();
1623 
1624  auto get_dP = [&]() {
1625  dP.resize(size_symm * size_symm, nb_integration_pts, false);
1626  auto ts_a = getTSa();
1627 
1628  auto t_D = getFTensor4DdgFromMat<3, 3, 0>(dataAtPts->matD);
1630  t_dP_tmp(L, J) = -(1 + alphaU * ts_a) *
1631  (t_L(i, j, L) *
1632  ((t_D(i, j, m, n) * t_diff(m, n, k, l)) * t_L(k, l, J)));
1633 
1634  if (EshelbianCore::stretchSelector > LINEAR) {
1635  auto t_approx_P_adjont_dstretch =
1636  getFTensor2FromMat<3, 3>(dataAtPts->adjointPdstretchAtPts);
1637  auto t_eigen_vals = getFTensor1FromMat<3>(dataAtPts->eigenVals);
1638  auto t_eigen_vecs = getFTensor2FromMat<3, 3>(dataAtPts->eigenVecs);
1639  auto &nbUniq = dataAtPts->nbUniq;
1640 
1641  auto t_dP = getFTensor2FromMat<size_symm, size_symm>(dP);
1642  for (auto gg = 0; gg != nb_integration_pts; ++gg) {
1643 
1644  // Work of symmetric tensor on undefined tensor is equal to the work
1645  // of the symmetric part of it
1647  t_sym(i, j) = (t_approx_P_adjont_dstretch(i, j) ||
1648  t_approx_P_adjont_dstretch(j, i));
1649  t_sym(i, j) /= 2.0;
1650  auto t_diff2_uP2 = EigenMatrix::getDiffDiffMat(
1651  t_eigen_vals, t_eigen_vecs, EshelbianCore::f, EshelbianCore::d_f,
1652  EshelbianCore::dd_f, t_sym, nbUniq[gg]);
1653  t_dP(L, J) = t_L(i, j, L) *
1654  ((t_diff2_uP2(i, j, k, l) + t_diff2_uP2(k, l, i, j)) *
1655  t_L(k, l, J)) /
1656  2. +
1657  t_dP_tmp(L, J);
1658 
1659  ++t_dP;
1660  ++t_approx_P_adjont_dstretch;
1661  ++t_eigen_vals;
1662  ++t_eigen_vecs;
1663  }
1664  } else {
1665  auto t_dP = getFTensor2FromMat<size_symm, size_symm>(dP);
1666  for (auto gg = 0; gg != nb_integration_pts; ++gg) {
1667  t_dP(L, J) = t_dP_tmp(L, J);
1668  ++t_dP;
1669  }
1670  }
1671 
1672  return getFTensor2FromMat<size_symm, size_symm>(dP);
1673  };
1674 
1675  auto t_dP = get_dP();
1676  for (int gg = 0; gg != nb_integration_pts; ++gg) {
1677  double a = v * t_w;
1678 
1679  int rr = 0;
1680  for (; rr != row_nb_dofs / 6; ++rr) {
1681  auto t_col_base_fun = col_data.getFTensor0N(gg, 0);
1682  auto t_m = get_ftensor2(K, 6 * rr, 0);
1683  for (int cc = 0; cc != col_nb_dofs / 6; ++cc) {
1684  const double b = a * t_row_base_fun * t_col_base_fun;
1685  t_m(L, J) += b * t_dP(L, J);
1686  ++t_m;
1687  ++t_col_base_fun;
1688  }
1689  ++t_row_base_fun;
1690  }
1691 
1692  for (; rr != row_nb_base_functions; ++rr) {
1693  ++t_row_base_fun;
1694  }
1695 
1696  ++t_w;
1697  ++t_dP;
1698  }
1700 }
1701 
1703 OpSpatialPhysical_du_du::integratePolyconvexHencky(EntData &row_data,
1704  EntData &col_data) {
1706 
1709  auto t_L = symm_L_tensor();
1710  auto t_diff = diff_tensor();
1711 
1712  int nb_integration_pts = row_data.getN().size1();
1713  int row_nb_dofs = row_data.getIndices().size();
1714  int col_nb_dofs = col_data.getIndices().size();
1715 
1716  auto get_ftensor2 = [](MatrixDouble &m, const int r, const int c) {
1718  size_symm>(
1719 
1720  &m(r + 0, c + 0), &m(r + 0, c + 1), &m(r + 0, c + 2), &m(r + 0, c + 3),
1721  &m(r + 0, c + 4), &m(r + 0, c + 5),
1722 
1723  &m(r + 1, c + 0), &m(r + 1, c + 1), &m(r + 1, c + 2), &m(r + 1, c + 3),
1724  &m(r + 1, c + 4), &m(r + 1, c + 5),
1725 
1726  &m(r + 2, c + 0), &m(r + 2, c + 1), &m(r + 2, c + 2), &m(r + 2, c + 3),
1727  &m(r + 2, c + 4), &m(r + 2, c + 5),
1728 
1729  &m(r + 3, c + 0), &m(r + 3, c + 1), &m(r + 3, c + 2), &m(r + 3, c + 3),
1730  &m(r + 3, c + 4), &m(r + 3, c + 5),
1731 
1732  &m(r + 4, c + 0), &m(r + 4, c + 1), &m(r + 4, c + 2), &m(r + 4, c + 3),
1733  &m(r + 4, c + 4), &m(r + 4, c + 5),
1734 
1735  &m(r + 5, c + 0), &m(r + 5, c + 1), &m(r + 5, c + 2), &m(r + 5, c + 3),
1736  &m(r + 5, c + 4), &m(r + 5, c + 5)
1737 
1738  );
1739  };
1746 
1747  auto v = getVolume();
1748  auto t_w = getFTensor0IntegrationWeight();
1749 
1750  int row_nb_base_functions = row_data.getN().size2();
1751  auto t_row_base_fun = row_data.getFTensor0N();
1752 
1753  auto get_dP = [&]() {
1754  dP.resize(size_symm * size_symm, nb_integration_pts, false);
1755  auto ts_a = getTSa();
1756 
1757  auto t_D = getFTensor4DdgFromMat<3, 3, 0>(dataAtPts->matD);
1758 
1759  constexpr double nohat_k = 1. / 4;
1760  constexpr double hat_k = 1. / 8;
1761  double mu = dataAtPts->mu;
1762  double lambda = dataAtPts->lambda;
1763 
1764  constexpr double third = boost::math::constants::third<double>();
1766  auto t_diff_deviator = diff_deviator(diff_tensor());
1767 
1768  auto t_approx_P_adjont_dstretch =
1769  getFTensor2FromMat<3, 3>(dataAtPts->adjointPdstretchAtPts);
1770  auto t_log_stretch_h1 =
1771  getFTensor2SymmetricFromMat<3>(dataAtPts->logStretchTotalTensorAtPts);
1772  auto t_eigen_vals = getFTensor1FromMat<3>(dataAtPts->eigenVals);
1773  auto t_eigen_vecs = getFTensor2FromMat<3, 3>(dataAtPts->eigenVecs);
1774  auto &nbUniq = dataAtPts->nbUniq;
1775 
1776  auto t_dP = getFTensor2FromMat<size_symm, size_symm>(dP);
1777  for (auto gg = 0; gg != nb_integration_pts; ++gg) {
1778 
1779  double log_det = t_log_stretch_h1(i, i);
1780  double log_det2 = log_det * log_det;
1782  t_dev(i, j) = t_log_stretch_h1(i, j) - t_kd(i, j) * (third * log_det);
1783  double dev_norm2 = t_dev(i, j) * t_dev(i, j);
1784 
1785  auto A = 2 * mu * std::exp(nohat_k * dev_norm2);
1786  auto B = lambda * std::exp(hat_k * log_det2) * log_det;
1787 
1788  FTensor::Tensor2_symmetric<double, 3> t_A_diff, t_B_diff;
1789  t_A_diff(i, j) =
1790  (A * 2 * nohat_k) * (t_dev(k, l) * t_diff_deviator(k, l, i, j));
1791  t_B_diff(i, j) = (B * 2 * hat_k) * log_det * t_kd(i, j) +
1792  lambda * std::exp(hat_k * log_det2) * t_kd(i, j);
1794  t_dT(i, j, k, l) =
1795  t_A_diff(i, j) * (t_dev(m, n) * t_diff_deviator(m, n, k, l))
1796 
1797  +
1798 
1799  A * t_diff_deviator(m, n, i, j) * t_diff_deviator(m, n, k, l)
1800 
1801  +
1802 
1803  t_B_diff(i, j) * t_kd(k, l);
1804 
1805  t_dP(L, J) = -t_L(i, j, L) *
1806  ((
1807 
1808  t_dT(i, j, k, l)
1809 
1810  +
1811 
1812  (alphaU * ts_a) * (t_D(i, j, m, n) * t_diff(m, n, k, l)
1813 
1814  )) *
1815  t_L(k, l, J));
1816 
1817  // Work of symmetric tensor on undefined tensor is equal to the work
1818  // of the symmetric part of it
1819  if (EshelbianCore::stretchSelector > LINEAR) {
1821  t_sym(i, j) = (t_approx_P_adjont_dstretch(i, j) ||
1822  t_approx_P_adjont_dstretch(j, i));
1823  t_sym(i, j) /= 2.0;
1824  auto t_diff2_uP2 = EigenMatrix::getDiffDiffMat(
1825  t_eigen_vals, t_eigen_vecs, EshelbianCore::f, EshelbianCore::d_f,
1826  EshelbianCore::dd_f, t_sym, nbUniq[gg]);
1827  t_dP(L, J) += t_L(i, j, L) *
1828  ((t_diff2_uP2(i, j, k, l) + t_diff2_uP2(k, l, i, j)) *
1829  t_L(k, l, J)) /
1830  2.;
1831  }
1832 
1833  ++t_dP;
1834  ++t_approx_P_adjont_dstretch;
1835  ++t_log_stretch_h1;
1836  ++t_eigen_vals;
1837  ++t_eigen_vecs;
1838  }
1839 
1840  return getFTensor2FromMat<size_symm, size_symm>(dP);
1841  };
1842 
1843  auto t_dP = get_dP();
1844  for (int gg = 0; gg != nb_integration_pts; ++gg) {
1845  double a = v * t_w;
1846 
1847  int rr = 0;
1848  for (; rr != row_nb_dofs / 6; ++rr) {
1849  auto t_col_base_fun = col_data.getFTensor0N(gg, 0);
1850  auto t_m = get_ftensor2(K, 6 * rr, 0);
1851  for (int cc = 0; cc != col_nb_dofs / 6; ++cc) {
1852  const double b = a * t_row_base_fun * t_col_base_fun;
1853  t_m(L, J) += b * t_dP(L, J);
1854  ++t_m;
1855  ++t_col_base_fun;
1856  }
1857  ++t_row_base_fun;
1858  }
1859 
1860  for (; rr != row_nb_base_functions; ++rr) {
1861  ++t_row_base_fun;
1862  }
1863 
1864  ++t_w;
1865  ++t_dP;
1866  }
1868 }
1869 
1870 MoFEMErrorCode OpSpatialPhysical_du_du::integratePiola(EntData &row_data,
1871  EntData &col_data) {
1873 
1876  auto t_L = symm_L_tensor();
1877  auto t_diff = diff_tensor();
1878 
1879  int nb_integration_pts = row_data.getN().size1();
1880  int row_nb_dofs = row_data.getIndices().size();
1881  int col_nb_dofs = col_data.getIndices().size();
1882 
1883  auto get_ftensor2 = [](MatrixDouble &m, const int r, const int c) {
1885  size_symm>(
1886 
1887  &m(r + 0, c + 0), &m(r + 0, c + 1), &m(r + 0, c + 2), &m(r + 0, c + 3),
1888  &m(r + 0, c + 4), &m(r + 0, c + 5),
1889 
1890  &m(r + 1, c + 0), &m(r + 1, c + 1), &m(r + 1, c + 2), &m(r + 1, c + 3),
1891  &m(r + 1, c + 4), &m(r + 1, c + 5),
1892 
1893  &m(r + 2, c + 0), &m(r + 2, c + 1), &m(r + 2, c + 2), &m(r + 2, c + 3),
1894  &m(r + 2, c + 4), &m(r + 2, c + 5),
1895 
1896  &m(r + 3, c + 0), &m(r + 3, c + 1), &m(r + 3, c + 2), &m(r + 3, c + 3),
1897  &m(r + 3, c + 4), &m(r + 3, c + 5),
1898 
1899  &m(r + 4, c + 0), &m(r + 4, c + 1), &m(r + 4, c + 2), &m(r + 4, c + 3),
1900  &m(r + 4, c + 4), &m(r + 4, c + 5),
1901 
1902  &m(r + 5, c + 0), &m(r + 5, c + 1), &m(r + 5, c + 2), &m(r + 5, c + 3),
1903  &m(r + 5, c + 4), &m(r + 5, c + 5)
1904 
1905  );
1906  };
1913 
1914  auto v = getVolume();
1915  auto t_w = getFTensor0IntegrationWeight();
1916 
1917  auto get_dP = [&]() {
1918  dP.resize(size_symm * size_symm, nb_integration_pts, false);
1919  auto ts_a = getTSa();
1920 
1921  auto t_P = getFTensor2FromMat<3, 3>(dataAtPts->PAtPts);
1922  auto r_P_du = getFTensor4FromMat<3, 3, 3, 3>(dataAtPts->P_du);
1923  auto t_approx_P_adjont_dstretch =
1924  getFTensor2FromMat<3, 3>(dataAtPts->adjointPdstretchAtPts);
1925  auto t_dot_log_u =
1926  getFTensor2SymmetricFromMat<3>(dataAtPts->logStretchDotTensorAtPts);
1927  auto t_u = getFTensor2SymmetricFromMat<3>(dataAtPts->stretchTensorAtPts);
1928  auto t_diff_u =
1929  getFTensor4DdgFromMat<3, 3, 1>(dataAtPts->diffStretchTensorAtPts);
1930  auto t_eigen_vals = getFTensor1FromMat<3>(dataAtPts->eigenVals);
1931  auto t_eigen_vecs = getFTensor2FromMat<3, 3>(dataAtPts->eigenVecs);
1932  auto &nbUniq = dataAtPts->nbUniq;
1933 
1934  auto t_dP = getFTensor2FromMat<size_symm, size_symm>(dP);
1935  for (auto gg = 0; gg != nb_integration_pts; ++gg) {
1936 
1938  t_deltaP(i, j) = t_approx_P_adjont_dstretch(i, j) - t_P(i, j);
1939 
1941  t_Ldiff_u(i, j, L) = t_diff_u(i, j, m, n) * t_L(m, n, L);
1942  t_dP(L, J) =
1943  -t_Ldiff_u(i, j, L) * (r_P_du(i, j, k, l) * t_Ldiff_u(k, l, J));
1944  // viscous stress derivative
1945  t_dP(L, J) -= (alphaU * ts_a) *
1946  (t_L(i, j, L) * (t_diff(i, j, k, l) * t_L(k, l, J)));
1947 
1948  if (EshelbianCore::stretchSelector > LINEAR) {
1950  t_deltaP_sym(i, j) = (t_deltaP(i, j) || t_deltaP(j, i));
1951  t_deltaP_sym(i, j) /= 2.0;
1952  auto t_diff2_uP2 = EigenMatrix::getDiffDiffMat(
1953  t_eigen_vals, t_eigen_vecs, EshelbianCore::f, EshelbianCore::d_f,
1954  EshelbianCore::dd_f, t_deltaP_sym, nbUniq[gg]);
1955  t_dP(L, J) += t_L(i, j, L) * (t_diff2_uP2(i, j, k, l) * t_L(k, l, J));
1956  }
1957 
1958  ++t_P;
1959  ++t_dP;
1960  ++r_P_du;
1961  ++t_approx_P_adjont_dstretch;
1962  ++t_dot_log_u;
1963  ++t_u;
1964  ++t_diff_u;
1965  ++t_eigen_vals;
1966  ++t_eigen_vecs;
1967  }
1968 
1969  return getFTensor2FromMat<size_symm, size_symm>(dP);
1970  };
1971 
1972  int row_nb_base_functions = row_data.getN().size2();
1973  auto t_row_base_fun = row_data.getFTensor0N();
1974 
1975  auto t_dP = get_dP();
1976  for (int gg = 0; gg != nb_integration_pts; ++gg) {
1977  double a = v * t_w;
1978 
1979  int rr = 0;
1980  for (; rr != row_nb_dofs / 6; ++rr) {
1981  auto t_col_base_fun = col_data.getFTensor0N(gg, 0);
1982  auto t_m = get_ftensor2(K, 6 * rr, 0);
1983  for (int cc = 0; cc != col_nb_dofs / 6; ++cc) {
1984  const double b = a * t_row_base_fun * t_col_base_fun;
1985  t_m(L, J) += b * t_dP(L, J);
1986  ++t_m;
1987  ++t_col_base_fun;
1988  }
1989  ++t_row_base_fun;
1990  }
1991 
1992  for (; rr != row_nb_base_functions; ++rr) {
1993  ++t_row_base_fun;
1994  }
1995 
1996  ++t_w;
1997  ++t_dP;
1998  }
2000 }
2001 
2002 MoFEMErrorCode OpSpatialPhysical_du_domega::integrate(EntData &row_data,
2003  EntData &col_data) {
2005 
2007  auto t_L = symm_L_tensor();
2008 
2009  int row_nb_dofs = row_data.getIndices().size();
2010  int col_nb_dofs = col_data.getIndices().size();
2011  auto get_ftensor3 = [](MatrixDouble &m, const int r, const int c) {
2013 
2014  &m(r + 0, c + 0), &m(r + 0, c + 1), &m(r + 0, c + 2),
2015 
2016  &m(r + 1, c + 0), &m(r + 1, c + 1), &m(r + 1, c + 2),
2017 
2018  &m(r + 2, c + 0), &m(r + 2, c + 1), &m(r + 2, c + 2),
2019 
2020  &m(r + 3, c + 0), &m(r + 3, c + 1), &m(r + 3, c + 2),
2021 
2022  &m(r + 4, c + 0), &m(r + 4, c + 1), &m(r + 4, c + 2),
2023 
2024  &m(r + 5, c + 0), &m(r + 5, c + 1), &m(r + 5, c + 2)
2025 
2026  );
2027  };
2033 
2034  auto v = getVolume();
2035  auto t_w = getFTensor0IntegrationWeight();
2036  auto t_approx_P_adjont_log_du_domega =
2037  getFTensor2FromMat<3, size_symm>(dataAtPts->adjointPdUdOmegaAtPts);
2038 
2039  int row_nb_base_functions = row_data.getN().size2();
2040  auto t_row_base_fun = row_data.getFTensor0N();
2041 
2042  int nb_integration_pts = row_data.getN().size1();
2043 
2044  for (int gg = 0; gg != nb_integration_pts; ++gg) {
2045  double a = v * t_w;
2046 
2047  int rr = 0;
2048  for (; rr != row_nb_dofs / 6; ++rr) {
2049  auto t_col_base_fun = col_data.getFTensor0N(gg, 0);
2050  auto t_m = get_ftensor3(K, 6 * rr, 0);
2051  for (int cc = 0; cc != col_nb_dofs / 3; ++cc) {
2052  double v = a * t_row_base_fun * t_col_base_fun;
2053  t_m(L, k) += v * t_approx_P_adjont_log_du_domega(k, L);
2054  ++t_m;
2055  ++t_col_base_fun;
2056  }
2057  ++t_row_base_fun;
2058  }
2059 
2060  for (; rr != row_nb_base_functions; ++rr)
2061  ++t_row_base_fun;
2062 
2063  ++t_w;
2064  ++t_approx_P_adjont_log_du_domega;
2065  }
2066 
2068 }
2069 
2070 MoFEMErrorCode OpSpatialRotation_domega_dP::integrate(EntData &row_data,
2071  EntData &col_data) {
2073  int nb_integration_pts = getGaussPts().size2();
2074  int row_nb_dofs = row_data.getIndices().size();
2075  int col_nb_dofs = col_data.getIndices().size();
2076  auto get_ftensor2 = [](MatrixDouble &m, const int r, const int c) {
2078 
2079  &m(r + 0, c + 0), &m(r + 0, c + 1), &m(r + 0, c + 2),
2080 
2081  &m(r + 1, c + 0), &m(r + 1, c + 1), &m(r + 1, c + 2),
2082 
2083  &m(r + 2, c + 0), &m(r + 2, c + 1), &m(r + 2, c + 2)
2084 
2085  );
2086  };
2093  auto v = getVolume();
2094  auto t_w = getFTensor0IntegrationWeight();
2095  auto t_levi_kirchoff_dP =
2096  getFTensor3FromMat<3, 3, 3>(dataAtPts->leviKirchhoffPAtPts);
2097 
2098  int row_nb_base_functions = row_data.getN().size2();
2099  auto t_row_base_fun = row_data.getFTensor0N();
2100 
2101  for (int gg = 0; gg != nb_integration_pts; ++gg) {
2102  double a = v * t_w;
2103  int rr = 0;
2104  for (; rr != row_nb_dofs / 3; ++rr) {
2105  double b = a * t_row_base_fun;
2106  auto t_col_base_fun = col_data.getFTensor1N<3>(gg, 0);
2107  auto t_m = get_ftensor2(K, 3 * rr, 0);
2108  for (int cc = 0; cc != col_nb_dofs / 3; ++cc) {
2109  t_m(k, i) += b * (t_levi_kirchoff_dP(i, l, k) * t_col_base_fun(l));
2110  ++t_m;
2111  ++t_col_base_fun;
2112  }
2113  ++t_row_base_fun;
2114  }
2115  for (; rr != row_nb_base_functions; ++rr) {
2116  ++t_row_base_fun;
2117  }
2118 
2119  ++t_w;
2120  ++t_levi_kirchoff_dP;
2121  }
2123 }
2124 
2125 MoFEMErrorCode OpSpatialRotation_domega_dBubble::integrate(EntData &row_data,
2126  EntData &col_data) {
2128  int nb_integration_pts = getGaussPts().size2();
2129  int row_nb_dofs = row_data.getIndices().size();
2130  int col_nb_dofs = col_data.getIndices().size();
2131 
2132  auto get_ftensor1 = [](MatrixDouble &m, const int r, const int c) {
2134  &m(r + 0, c), &m(r + 1, c), &m(r + 2, c));
2135  };
2136 
2142 
2143  auto v = getVolume();
2144  auto t_w = getFTensor0IntegrationWeight();
2145  auto t_levi_kirchoff_dP =
2146  getFTensor3FromMat<3, 3, 3>(dataAtPts->leviKirchhoffPAtPts);
2147 
2148  int row_nb_base_functions = row_data.getN().size2();
2149  auto t_row_base_fun = row_data.getFTensor0N();
2150 
2151  for (int gg = 0; gg != nb_integration_pts; ++gg) {
2152  double a = v * t_w;
2153  int rr = 0;
2154  for (; rr != row_nb_dofs / 3; ++rr) {
2155  double b = a * t_row_base_fun;
2156  auto t_col_base_fun = col_data.getFTensor2N<3, 3>(gg, 0);
2157  auto t_m = get_ftensor1(K, 3 * rr, 0);
2158  for (int cc = 0; cc != col_nb_dofs; ++cc) {
2159  t_m(k) += b * (t_levi_kirchoff_dP(i, j, k) * t_col_base_fun(i, j));
2160  ++t_m;
2161  ++t_col_base_fun;
2162  }
2163  ++t_row_base_fun;
2164  }
2165 
2166  for (; rr != row_nb_base_functions; ++rr) {
2167  ++t_row_base_fun;
2168  }
2169  ++t_w;
2170  ++t_levi_kirchoff_dP;
2171  }
2173 }
2174 
2175 MoFEMErrorCode OpSpatialRotation_domega_domega::integrate(EntData &row_data,
2176  EntData &col_data) {
2178  int nb_integration_pts = getGaussPts().size2();
2179  int row_nb_dofs = row_data.getIndices().size();
2180  int col_nb_dofs = col_data.getIndices().size();
2181  auto get_ftensor2 = [](MatrixDouble &m, const int r, const int c) {
2183 
2184  &m(r + 0, c + 0), &m(r + 0, c + 1), &m(r + 0, c + 2),
2185 
2186  &m(r + 1, c + 0), &m(r + 1, c + 1), &m(r + 1, c + 2),
2187 
2188  &m(r + 2, c + 0), &m(r + 2, c + 1), &m(r + 2, c + 2)
2189 
2190  );
2191  };
2198 
2199  auto v = getVolume();
2200  auto t_w = getFTensor0IntegrationWeight();
2201  auto t_levi_kirchoff_domega =
2202  getFTensor2FromMat<3, 3>(dataAtPts->leviKirchhoffOmegaAtPts);
2203  int row_nb_base_functions = row_data.getN().size2();
2204  auto t_row_base_fun = row_data.getFTensor0N();
2205  for (int gg = 0; gg != nb_integration_pts; ++gg) {
2206  double a = v * t_w;
2207  int rr = 0;
2208  for (; rr != row_nb_dofs / 3; ++rr) {
2209  auto t_m = get_ftensor2(K, 3 * rr, 0);
2210  const double b = a * t_row_base_fun;
2211  auto t_col_base_fun = col_data.getFTensor0N(gg, 0);
2212  for (int cc = 0; cc != col_nb_dofs / 3; ++cc) {
2213  t_m(k, l) += (b * t_col_base_fun) * t_levi_kirchoff_domega(k, l);
2214  ++t_m;
2215  ++t_col_base_fun;
2216  }
2217  ++t_row_base_fun;
2218  }
2219  for (; rr != row_nb_base_functions; ++rr) {
2220  ++t_row_base_fun;
2221  }
2222  ++t_w;
2223  ++t_levi_kirchoff_domega;
2224  }
2226 }
2227 
2228 MoFEMErrorCode OpSpatialConsistency_dP_dP::integrate(EntData &row_data,
2229  EntData &col_data) {
2231 
2232  auto get_ftensor2 = [](MatrixDouble &m, const int r, const int c) {
2234 
2235  &m(r + 0, c + 0), &m(r + 0, c + 1), &m(r + 0, c + 2),
2236 
2237  &m(r + 1, c + 0), &m(r + 1, c + 1), &m(r + 1, c + 2),
2238 
2239  &m(r + 2, c + 0), &m(r + 2, c + 1), &m(r + 2, c + 2)
2240 
2241  );
2242  };
2243 
2244  int nb_integration_pts = getGaussPts().size2();
2245  int row_nb_dofs = row_data.getIndices().size();
2246  int col_nb_dofs = col_data.getIndices().size();
2247 
2248  auto v = getVolume();
2249  auto t_w = getFTensor0IntegrationWeight();
2250  int row_nb_base_functions = row_data.getN().size2() / 3;
2251 
2258 
2259  auto t_inv_D =
2260  getFTensor4DdgFromMat<SPACE_DIM, SPACE_DIM, 0>(dataAtPts->matInvD);
2261 
2262  auto t_row_base = row_data.getFTensor1N<3>();
2263  for (int gg = 0; gg != nb_integration_pts; ++gg) {
2264  double a = v * t_w;
2265 
2266  int rr = 0;
2267  for (; rr != row_nb_dofs / 3; ++rr) {
2268  auto t_col_base = col_data.getFTensor1N<3>(gg, 0);
2269  auto t_m = get_ftensor2(K, 3 * rr, 0);
2270  for (int cc = 0; cc != col_nb_dofs / 3; ++cc) {
2271  t_m(i, k) += a * t_row_base(j) * (t_inv_D(i, j, k, l) * t_col_base(l));
2272  ++t_m;
2273  ++t_col_base;
2274  }
2275 
2276  ++t_row_base;
2277  }
2278 
2279  for (; rr != row_nb_base_functions; ++rr)
2280  ++t_row_base;
2281 
2282  ++t_w;
2283  ++t_inv_D;
2284  }
2286 }
2287 
2289 OpSpatialConsistency_dBubble_dBubble::integrate(EntData &row_data,
2290  EntData &col_data) {
2292 
2293  int nb_integration_pts = getGaussPts().size2();
2294  int row_nb_dofs = row_data.getIndices().size();
2295  int col_nb_dofs = col_data.getIndices().size();
2296 
2297  auto v = getVolume();
2298  auto t_w = getFTensor0IntegrationWeight();
2299  int row_nb_base_functions = row_data.getN().size2() / 9;
2300 
2307 
2308  auto t_inv_D =
2309  getFTensor4DdgFromMat<SPACE_DIM, SPACE_DIM, 0>(dataAtPts->matInvD);
2310 
2311  auto t_row_base = row_data.getFTensor2N<3, 3>();
2312  for (int gg = 0; gg != nb_integration_pts; ++gg) {
2313  double a = v * t_w;
2314 
2315  int rr = 0;
2316  for (; rr != row_nb_dofs; ++rr) {
2317  auto t_col_base = col_data.getFTensor2N<3, 3>(gg, 0);
2318  for (int cc = 0; cc != col_nb_dofs; ++cc) {
2319  K(rr, cc) +=
2320  a * (t_row_base(i, j) * (t_inv_D(i, j, k, l) * t_col_base(k, l)));
2321  ++t_col_base;
2322  }
2323 
2324  ++t_row_base;
2325  }
2326 
2327  for (; rr != row_nb_base_functions; ++rr)
2328  ++t_row_base;
2329  ++t_w;
2330  ++t_inv_D;
2331  }
2333 }
2334 
2335 MoFEMErrorCode OpSpatialConsistency_dBubble_dP::integrate(EntData &row_data,
2336  EntData &col_data) {
2338 
2339  auto get_ftensor1 = [](MatrixDouble &m, const int r, const int c) {
2341 
2342  &m(r + 0, c + 0), &m(r + 0, c + 1), &m(r + 0, c + 2)
2343 
2344  );
2345  };
2346 
2347  int nb_integration_pts = getGaussPts().size2();
2348  int row_nb_dofs = row_data.getIndices().size();
2349  int col_nb_dofs = col_data.getIndices().size();
2350 
2351  auto v = getVolume();
2352  auto t_w = getFTensor0IntegrationWeight();
2353  int row_nb_base_functions = row_data.getN().size2() / 9;
2354 
2361 
2362  auto t_inv_D =
2363  getFTensor4DdgFromMat<SPACE_DIM, SPACE_DIM, 0>(dataAtPts->matInvD);
2364 
2365  auto t_row_base = row_data.getFTensor2N<3, 3>();
2366  for (int gg = 0; gg != nb_integration_pts; ++gg) {
2367  double a = v * t_w;
2368 
2369  auto t_m = get_ftensor1(K, 0, 0);
2370 
2371  int rr = 0;
2372  for (; rr != row_nb_dofs; ++rr) {
2373  auto t_col_base = col_data.getFTensor1N<3>(gg, 0);
2374  for (int cc = 0; cc != col_nb_dofs / 3; ++cc) {
2375  t_m(k) += a * (t_row_base(i, j) * t_inv_D(i, j, k, l)) * t_col_base(l);
2376  ++t_col_base;
2377  ++t_m;
2378  }
2379 
2380  ++t_row_base;
2381  }
2382 
2383  for (; rr != row_nb_base_functions; ++rr)
2384  ++t_row_base;
2385  ++t_w;
2386  ++t_inv_D;
2387  }
2389 }
2390 
2391 MoFEMErrorCode OpSpatialConsistency_dP_domega::integrate(EntData &row_data,
2392  EntData &col_data) {
2394 
2395  int nb_integration_pts = row_data.getN().size1();
2396  int row_nb_dofs = row_data.getIndices().size();
2397  int col_nb_dofs = col_data.getIndices().size();
2398 
2399  auto get_ftensor2 = [](MatrixDouble &m, const int r, const int c) {
2401 
2402  &m(r + 0, c + 0), &m(r + 0, c + 1), &m(r + 0, c + 2),
2403 
2404  &m(r + 1, c + 0), &m(r + 1, c + 1), &m(r + 1, c + 2),
2405 
2406  &m(r + 2, c + 0), &m(r + 2, c + 1), &m(r + 2, c + 2)
2407 
2408  );
2409  };
2410 
2417 
2418  auto v = getVolume();
2419  auto t_w = getFTensor0IntegrationWeight();
2420  auto t_h_domega = getFTensor3FromMat<3, 3, 3>(dataAtPts->hdOmegaAtPts);
2421  int row_nb_base_functions = row_data.getN().size2() / 3;
2422  auto t_row_base_fun = row_data.getFTensor1N<3>();
2423 
2424  const double ts_a = getTSa();
2425 
2426  for (int gg = 0; gg != nb_integration_pts; ++gg) {
2427  double a = v * t_w;
2428 
2429  constexpr auto t_kd = FTensor::Kronecker_Delta<int>();
2430 
2431  int rr = 0;
2432  for (; rr != row_nb_dofs / 3; ++rr) {
2433 
2435  t_PRT(i, k) = t_row_base_fun(j) * t_h_domega(i, j, k);
2436 
2437  auto t_col_base_fun = col_data.getFTensor0N(gg, 0);
2438  auto t_m = get_ftensor2(K, 3 * rr, 0);
2439  for (int cc = 0; cc != col_nb_dofs / 3; ++cc) {
2440  t_m(i, j) += (a * t_col_base_fun) * t_PRT(i, j);
2441  ++t_m;
2442  ++t_col_base_fun;
2443  }
2444 
2445  ++t_row_base_fun;
2446  }
2447 
2448  for (; rr != row_nb_base_functions; ++rr)
2449  ++t_row_base_fun;
2450  ++t_w;
2451  ++t_h_domega;
2452  }
2454 }
2455 
2457 OpSpatialConsistency_dBubble_domega::integrate(EntData &row_data,
2458  EntData &col_data) {
2460 
2461  int nb_integration_pts = row_data.getN().size1();
2462  int row_nb_dofs = row_data.getIndices().size();
2463  int col_nb_dofs = col_data.getIndices().size();
2464 
2465  auto get_ftensor2 = [](MatrixDouble &m, const int r, const int c) {
2467  &m(r, c + 0), &m(r, c + 1), &m(r, c + 2));
2468  };
2469 
2476 
2477  auto v = getVolume();
2478  auto t_w = getFTensor0IntegrationWeight();
2479  auto t_h_domega = getFTensor3FromMat<3, 3, 3>(dataAtPts->hdOmegaAtPts);
2480  int row_nb_base_functions = row_data.getN().size2() / 9;
2481  auto t_row_base_fun = row_data.getFTensor2N<3, 3>();
2482 
2483  const double ts_a = getTSa();
2484 
2485  for (int gg = 0; gg != nb_integration_pts; ++gg) {
2486  double a = v * t_w;
2487 
2488  int rr = 0;
2489  for (; rr != row_nb_dofs; ++rr) {
2490 
2492  t_PRT(k) = t_row_base_fun(i, j) * t_h_domega(i, j, k);
2493 
2494  auto t_col_base_fun = col_data.getFTensor0N(gg, 0);
2495  auto t_m = get_ftensor2(K, rr, 0);
2496  for (int cc = 0; cc != col_nb_dofs / 3; ++cc) {
2497  t_m(j) += (a * t_col_base_fun) * t_PRT(j);
2498  ++t_m;
2499  ++t_col_base_fun;
2500  }
2501 
2502  ++t_row_base_fun;
2503  }
2504 
2505  for (; rr != row_nb_base_functions; ++rr)
2506  ++t_row_base_fun;
2507 
2508  ++t_w;
2509  ++t_h_domega;
2510  }
2512 }
2513 
2514 MoFEMErrorCode OpPostProcDataStructure::doWork(int side, EntityType type,
2515  EntData &data) {
2517 
2518  auto create_tag = [this](const std::string tag_name, const int size) {
2519  double def_VAL[] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
2520  Tag th;
2521  CHKERR postProcMesh.tag_get_handle(tag_name.c_str(), size, MB_TYPE_DOUBLE,
2522  th, MB_TAG_CREAT | MB_TAG_SPARSE,
2523  def_VAL);
2524  return th;
2525  };
2526 
2527  Tag th_w = create_tag("SpatialDisplacement", 3);
2528  Tag th_omega = create_tag("Omega", 3);
2529  Tag th_approxP = create_tag("Piola1Stress", 9);
2530  Tag th_sigma = create_tag("CauchyStress", 9);
2531  Tag th_log_u = create_tag("LogSpatialStretch", 9);
2532  Tag th_u = create_tag("SpatialStretch", 9);
2533  Tag th_h = create_tag("h", 9);
2534  Tag th_X = create_tag("X", 3);
2535  Tag th_detF = create_tag("detF", 1);
2536  Tag th_angular_momentum = create_tag("AngularMomentum", 3);
2537 
2538  Tag th_u_eig_vec = create_tag("SpatialStretchEigenVec", 9);
2539  Tag th_u_eig_vals = create_tag("SpatialStretchEigenVals", 3);
2540  Tag th_traction = create_tag("traction", 3);
2541 
2542  Tag th_disp = create_tag("H1Displacement", 3);
2543  Tag th_disp_error = create_tag("DisplacementError", 1);
2544  Tag th_lambda_disp = create_tag("ContactDisplacement", 3);
2545 
2546  auto t_w = getFTensor1FromMat<3>(dataAtPts->wL2AtPts);
2547  auto t_omega = getFTensor1FromMat<3>(dataAtPts->rotAxisAtPts);
2548  auto t_h = getFTensor2FromMat<3, 3>(dataAtPts->hAtPts);
2549  auto t_log_u =
2550  getFTensor2SymmetricFromMat<3>(dataAtPts->logStretchTensorAtPts);
2551  auto t_u = getFTensor2SymmetricFromMat<3>(dataAtPts->stretchTensorAtPts);
2552  auto t_R = getFTensor2FromMat<3, 3>(dataAtPts->rotMatAtPts);
2553  auto t_approx_P = getFTensor2FromMat<3, 3>(dataAtPts->approxPAtPts);
2554  auto t_levi_kirchoff = getFTensor1FromMat<3>(dataAtPts->leviKirchhoffAtPts);
2555  auto t_coords = getFTensor1CoordsAtGaussPts();
2556  auto t_normal = getFTensor1NormalsAtGaussPts();
2557  auto t_disp = getFTensor1FromMat<3>(dataAtPts->wH1AtPts);
2558  auto t_lambda_disp = getFTensor1FromMat<3>(dataAtPts->contactL2AtPts);
2559 
2564 
2565  auto set_float_precision = [](const double x) {
2566  if (std::abs(x) < std::numeric_limits<float>::epsilon())
2567  return 0.;
2568  else
2569  return x;
2570  };
2571 
2572  // scalars
2573  auto save_scal_tag = [&](auto &th, auto v, const int gg) {
2575  v = set_float_precision(v);
2576  CHKERR postProcMesh.tag_set_data(th, &mapGaussPts[gg], 1, &v);
2578  };
2579 
2580  // vectors
2581  VectorDouble3 v(3);
2582  FTensor::Tensor1<FTensor::PackPtr<double *, 0>, 3> t_v(&v[0], &v[1], &v[2]);
2583  auto save_vec_tag = [&](auto &th, auto &t_d, const int gg) {
2585  t_v(i) = t_d(i);
2586  for (auto &a : v.data())
2587  a = set_float_precision(a);
2588  CHKERR postProcMesh.tag_set_data(th, &mapGaussPts[gg], 1,
2589  &*v.data().begin());
2591  };
2592 
2593  // tensors
2594 
2595  MatrixDouble3by3 m(3, 3);
2597  &m(0, 0), &m(0, 1), &m(0, 2),
2598 
2599  &m(1, 0), &m(1, 1), &m(1, 2),
2600 
2601  &m(2, 0), &m(2, 1), &m(2, 2));
2602 
2603  auto save_mat_tag = [&](auto &th, auto &t_d, const int gg) {
2605  t_m(i, j) = t_d(i, j);
2606  for (auto &v : m.data())
2607  v = set_float_precision(v);
2608  CHKERR postProcMesh.tag_set_data(th, &mapGaussPts[gg], 1,
2609  &*m.data().begin());
2611  };
2612 
2613  const auto nb_gauss_pts = getGaussPts().size2();
2614  for (auto gg = 0; gg != nb_gauss_pts; ++gg) {
2615 
2616  FTensor::Tensor1<double, 3> t_traction;
2617  t_traction(i) = t_approx_P(i, j) * t_normal(j) / t_normal.l2();
2618 
2619  // vectors
2620  CHKERR save_vec_tag(th_w, t_w, gg);
2621  CHKERR save_vec_tag(th_X, t_coords, gg);
2622  CHKERR save_vec_tag(th_omega, t_omega, gg);
2623  CHKERR save_vec_tag(th_traction, t_traction, gg);
2624 
2625  // tensors
2626  CHKERR save_mat_tag(th_h, t_h, gg);
2627 
2628  FTensor::Tensor2<double, 3, 3> t_log_u_tmp;
2629  for (int ii = 0; ii != 3; ++ii)
2630  for (int jj = 0; jj != 3; ++jj)
2631  t_log_u_tmp(ii, jj) = t_log_u(ii, jj);
2632 
2633  CHKERR save_mat_tag(th_log_u, t_log_u_tmp, gg);
2634 
2636  for (int ii = 0; ii != 3; ++ii)
2637  for (int jj = 0; jj != 3; ++jj)
2638  t_u_tmp(ii, jj) = t_u(ii, jj);
2639 
2640  CHKERR save_mat_tag(th_u, t_u_tmp, gg);
2641  CHKERR save_mat_tag(th_approxP, t_approx_P, gg);
2642  CHKERR save_vec_tag(th_disp, t_disp, gg);
2643  CHKERR save_vec_tag(th_lambda_disp, t_lambda_disp, gg);
2644 
2645  double u_error = sqrt((t_disp(i) - t_w(i)) * (t_disp(i) - t_w(i)));
2646  CHKERR save_scal_tag(th_disp_error, u_error, gg);
2647 
2648  const double jac = determinantTensor3by3(t_h);
2650  t_cauchy(i, j) = (1. / jac) * (t_approx_P(i, k) * t_h(j, k));
2651  CHKERR save_mat_tag(th_sigma, t_cauchy, gg);
2652  CHKERR postProcMesh.tag_set_data(th_detF, &mapGaussPts[gg], 1, &jac);
2653 
2655  t_levi(k) = t_levi_kirchoff(k);
2656  CHKERR postProcMesh.tag_set_data(th_angular_momentum, &mapGaussPts[gg], 1,
2657  &t_levi(0));
2658 
2659  auto get_eiegn_vector_symmetric = [&](auto &t_u) {
2661 
2662  for (int ii = 0; ii != 3; ++ii)
2663  for (int jj = 0; jj != 3; ++jj)
2664  t_m(ii, jj) = t_u(ii, jj);
2665 
2666  VectorDouble3 eigen_values(3);
2667  auto t_eigen_values = getFTensor1FromArray<3>(eigen_values);
2668  CHKERR computeEigenValuesSymmetric(t_m, t_eigen_values);
2669 
2670  CHKERR postProcMesh.tag_set_data(th_u_eig_vec, &mapGaussPts[gg], 1,
2671  &*m.data().begin());
2672  CHKERR postProcMesh.tag_set_data(th_u_eig_vals, &mapGaussPts[gg], 1,
2673  &*eigen_values.data().begin());
2674 
2676  };
2677 
2678  CHKERR get_eiegn_vector_symmetric(t_u);
2679 
2680  ++t_w;
2681  ++t_h;
2682  ++t_log_u;
2683  ++t_u;
2684  ++t_omega;
2685  ++t_R;
2686  ++t_approx_P;
2687  ++t_levi_kirchoff;
2688  ++t_coords;
2689  ++t_normal;
2690  ++t_disp;
2691  ++t_lambda_disp;
2692  }
2693 
2695 }
2696 
2698 OpCalculateStrainEnergy::doWork(int side, EntityType type,
2701  if (type == MBTET) {
2702  int nb_integration_pts = data.getN().size1();
2703  auto v = getVolume();
2704  auto t_w = getFTensor0IntegrationWeight();
2705  auto t_P = getFTensor2FromMat<3, 3>(dataAtPts->approxPAtPts);
2706  auto t_h = getFTensor2FromMat<3, 3>(dataAtPts->hAtPts);
2707 
2710 
2711  for (int gg = 0; gg != nb_integration_pts; ++gg) {
2712  const double a = t_w * v;
2713  // FIXME: this is wrong, energy should be calculated in material
2714  (*energy) += 0;
2715  ++t_w;
2716  ++t_P;
2717  ++t_h;
2718  }
2719  }
2721 }
2722 
2723 } // namespace EshelbianPlasticity
EshelbianPlasticity::sort_eigen_vals
auto sort_eigen_vals(FTensor::Tensor1< double, DIM > &eig, FTensor::Tensor2< double, DIM, DIM > &eigen_vec)
Definition: EshelbianOperators.cpp:254
EigenMatrix::getMat
FTensor::Tensor2_symmetric< double, 3 > getMat(Val< double, 3 > &t_val, Vec< double, 3 > &t_vec, Fun< double > f)
Get the Mat object.
Definition: MatrixFunction.cpp:53
MoFEMFunctionReturnHot
#define MoFEMFunctionReturnHot(a)
Last executable line of each PETSc function used for error handling. Replaces return()
Definition: definitions.h:460
MoFEM::K
VectorDouble K
Definition: Projection10NodeCoordsOnField.cpp:125
MoFEM::EntitiesFieldData::EntData
Data on single entity (This is passed as argument to DataOperator::doWork)
Definition: EntitiesFieldData.hpp:128
EshelbianPlasticity::is_eq
auto is_eq(const double &a, const double &b)
Definition: EshelbianOperators.cpp:239
FTensor
JSON compatible output.
Definition: Christof_constructor.hpp:6
EshelbianPlasticity::get_rotation_form_vector
auto get_rotation_form_vector(FTensor::Tensor1< T, 3 > &t_omega, RotSelector rotSelector=LARGE_ROT)
Definition: EshelbianOperators.cpp:119
EshelbianPlasticity::LINEAR
@ LINEAR
Definition: EshelbianPlasticity.hpp:21
EshelbianPlasticity::size_symm
constexpr static auto size_symm
Definition: EshelbianOperators.cpp:47
MoFEM::Types::VectorDouble3
VectorBoundedArray< double, 3 > VectorDouble3
Definition: Types.hpp:92
FTensor::Tensor1
Definition: Tensor1_value.hpp:8
EntityHandle
MoFEM::ForcesAndSourcesCore::getRuleHook
RuleHookFun getRuleHook
Hook to get rule.
Definition: ForcesAndSourcesCore.hpp:42
MoFEM::Exceptions::MoFEMErrorCode
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
Definition: Exceptions.hpp:56
FTensor::Tensor1::l2
T l2() const
Definition: Tensor1_value.hpp:84
MoFEM::Types::MatrixDouble
UBlasMatrix< double > MatrixDouble
Definition: Types.hpp:77
HenckyOps::d_f
auto d_f
Definition: HenckyOps.hpp:16
EshelbianPlasticity::isEq
Definition: EshelbianOperators.cpp:229
MoFEM::th
Tag th
Definition: Projection10NodeCoordsOnField.cpp:122
MoFEM::EntitiesFieldData::EntData::getFieldData
const VectorDouble & getFieldData() const
get dofs values
Definition: EntitiesFieldData.hpp:1254
FTensor::Kronecker_Delta
Kronecker Delta class.
Definition: Kronecker_Delta.hpp:15
EshelbianPlasticity
Definition: CGGTonsorialBubbleBase.hpp:11
EshelbianPlasticity::diff_tensor
auto diff_tensor()
Definition: EshelbianOperators.cpp:49
MoFEM.hpp
A
constexpr AssemblyType A
Definition: operators_tests.cpp:30
J
FTensor::Index< 'J', DIM1 > J
Definition: level_set.cpp:30
FTensor::Tensor2_symmetric
Definition: Tensor2_symmetric_value.hpp:13
EshelbianPlasticity::NO_H1_CONFIGURATION
@ NO_H1_CONFIGURATION
Definition: EshelbianPlasticity.hpp:20
FTensor::levi_civita
constexpr std::enable_if<(Dim0<=2 &&Dim1<=2), Tensor2_Expr< Levi_Civita< T >, T, Dim0, Dim1, i, j > >::type levi_civita(const Index< i, Dim0 > &, const Index< j, Dim1 > &)
levi_civita functions to make for easy adhoc use
Definition: Levi_Civita.hpp:617
ts_ctx
MoFEM::TsCtx * ts_ctx
Definition: level_set.cpp:1932
sdf.r
int r
Definition: sdf.py:8
EshelbianPlasticity::diff_symmetrize
auto diff_symmetrize()
Definition: EshelbianOperators.cpp:75
FTensor::Tensor2
Definition: Tensor2_value.hpp:16
EshelbianPlasticity::isEq::absMax
static double absMax
Definition: EshelbianOperators.cpp:234
EshelbianPlasticity::get_uniq_nb
auto get_uniq_nb(double *ptr)
Definition: EshelbianOperators.cpp:243
MoFEM::EntitiesFieldData::EntData::getFTensor0N
FTensor::Tensor0< FTensor::PackPtr< double *, 1 > > getFTensor0N(const FieldApproximationBase base)
Get base function as Tensor0.
Definition: EntitiesFieldData.hpp:1502
c
const double c
speed of light (cm/ns)
Definition: initial_diffusion.cpp:39
MoFEM::EntitiesFieldData::EntData::getFTensor2DiffN
FTensor::Tensor2< FTensor::PackPtr< double *, Tensor_Dim0 *Tensor_Dim1 >, Tensor_Dim0, Tensor_Dim1 > getFTensor2DiffN(FieldApproximationBase base)
Get derivatives of base functions for Hdiv space.
Definition: EntitiesFieldData.cpp:660
CHKERR
#define CHKERR
Inline error check.
Definition: definitions.h:548
ContactOps::scale
double scale
Definition: EshelbianContact.hpp:23
FTensor::Tensor3
Definition: Tensor3_value.hpp:12
MoFEM
implementation of Data Operators for Forces and Sources
Definition: Common.hpp:10
SPACE_DIM
constexpr int SPACE_DIM
Definition: child_and_parent.cpp:16
a
constexpr double a
Definition: approx_sphere.cpp:30
convert.type
type
Definition: convert.py:64
MoFEM::EntitiesFieldData::EntData::getIndices
const VectorInt & getIndices() const
Get global indices of dofs on entity.
Definition: EntitiesFieldData.hpp:1214
lapack_wrap.h
MatrixFunction.hpp
MoFEM::EntitiesFieldData::EntData::getFTensor2N
FTensor::Tensor2< FTensor::PackPtr< double *, Tensor_Dim0 *Tensor_Dim1 >, Tensor_Dim0, Tensor_Dim1 > getFTensor2N(FieldApproximationBase base)
Get base functions for Hdiv/Hcurl spaces.
Definition: EntitiesFieldData.cpp:762
MoFEM::FaceElementForcesAndSourcesCore
Face finite element.
Definition: FaceElementForcesAndSourcesCore.hpp:23
MoFEM::L
VectorDouble L
Definition: Projection10NodeCoordsOnField.cpp:124
EshelbianPlasticity.hpp
Eshelbian plasticity interface.
HenckyOps::dd_f
auto dd_f
Definition: HenckyOps.hpp:17
EshelbianPlasticity::FaceRule
Definition: EshelbianPlasticity.cpp:755
MOFEM_OPERATION_UNSUCCESSFUL
@ MOFEM_OPERATION_UNSUCCESSFUL
Definition: definitions.h:34
MoFEM::EntitiesFieldData::EntData::getFieldDofs
const VectorDofs & getFieldDofs() const
get dofs data stature FEDofEntity
Definition: EntitiesFieldData.hpp:1269
FTensor::Tensor4
Definition: Tensor4_value.hpp:18
EshelbianPlasticity::TensorTypeExtractor
Definition: EshelbianOperators.cpp:111
t
constexpr double t
plate stiffness
Definition: plate.cpp:59
EshelbianPlasticity::diff_deviator
auto diff_deviator(FTensor::Ddg< double, 3, 3 > &&t_diff_stress)
Definition: EshelbianOperators.cpp:20
i
FTensor::Index< 'i', SPACE_DIM > i
Definition: hcurl_divergence_operator_2d.cpp:27
t_kd
constexpr auto t_kd
Definition: free_surface.cpp:137
EshelbianPlasticity::symm_L_tensor
auto symm_L_tensor()
Definition: EshelbianOperators.cpp:60
FTensor::Index< 'i', 3 >
MoFEM::AddHOOps
Add operators pushing bases from local to physical configuration.
Definition: HODataOperators.hpp:503
convert.n
n
Definition: convert.py:82
MoFEM::determinantTensor3by3
static auto determinantTensor3by3(T &t)
Calculate the determinant of a 3x3 matrix or a tensor of rank 2.
Definition: Templates.hpp:1518
v
const double v
phase velocity of light in medium (cm/ns)
Definition: initial_diffusion.cpp:40
EshelbianPlasticity::SMALL_ROT
@ SMALL_ROT
Definition: EshelbianPlasticity.hpp:20
FTensor::dd
const Tensor2_symmetric_Expr< const ddTensor0< T, Dim, i, j >, typename promote< T, double >::V, Dim, i, j > dd(const Tensor0< T * > &a, const Index< i, Dim > index1, const Index< j, Dim > index2, const Tensor1< int, Dim > &d_ijk, const Tensor1< double, Dim > &d_xyz)
Definition: ddTensor0.hpp:33
MF_ZERO
@ MF_ZERO
Definition: definitions.h:111
MoFEM::TSMethod::ts_t
PetscReal ts_t
time
Definition: LoopMethods.hpp:162
FTensor::Dg
Definition: Dg_value.hpp:9
EshelbianPlasticity::LARGE_ROT
@ LARGE_ROT
Definition: EshelbianPlasticity.hpp:20
FTensor::Tensor0
Definition: Tensor0.hpp:16
EshelbianPlasticity::LOG
@ LOG
Definition: EshelbianPlasticity.hpp:21
MoFEM::EntitiesFieldData::EntData::getN
MatrixDouble & getN(const FieldApproximationBase base)
get base functions this return matrix (nb. of rows is equal to nb. of Gauss pts, nb....
Definition: EntitiesFieldData.hpp:1318
EshelbianPlasticity::get_diff2_rotation_form_vector
auto get_diff2_rotation_form_vector(FTensor::Tensor1< T, 3 > &t_omega, RotSelector rotSelector=LARGE_ROT)
Definition: EshelbianOperators.cpp:203
HenckyOps::f
auto f
Definition: HenckyOps.hpp:15
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
MoFEM::EntitiesFieldData::EntData::getFTensor1N
FTensor::Tensor1< FTensor::PackPtr< double *, Tensor_Dim >, Tensor_Dim > getFTensor1N(FieldApproximationBase base)
Get base functions for Hdiv/Hcurl spaces.
Definition: EntitiesFieldData.cpp:640
EshelbianPlasticity::RotSelector
RotSelector
Definition: EshelbianPlasticity.hpp:20
FTensor::Ddg< double, 3, 3 >
lapack_dposv
static __CLPK_integer lapack_dposv(char uplo, __CLPK_integer n, __CLPK_integer nrhs, __CLPK_doublereal *a, __CLPK_integer lda, __CLPK_doublereal *b, __CLPK_integer ldb)
Definition: lapack_wrap.h:211
EshelbianPlasticity::OpTractionBc
Definition: EshelbianPlasticity.hpp:632
mu
double mu
Definition: dynamic_first_order_con_law.cpp:98
lambda
static double lambda
Definition: incompressible_elasticity.cpp:199
MoFEM::ForcesAndSourcesCore::getOpPtrVector
boost::ptr_deque< UserDataOperator > & getOpPtrVector()
Use to push back operator for row operator.
Definition: ForcesAndSourcesCore.hpp:83
EigenMatrix::getDiffDiffMat
FTensor::Ddg< double, 3, 3 > getDiffDiffMat(Val< double, 3 > &t_val, Vec< double, 3 > &t_vec, Fun< double > f, Fun< double > d_f, Fun< double > dd_f, FTensor::Tensor2< double, 3, 3 > &t_S, const int nb)
Definition: MatrixFunction.cpp:78
EshelbianPlasticity::get_diff_rotation_form_vector
auto get_diff_rotation_form_vector(FTensor::Tensor1< T, 3 > &t_omega, RotSelector rotSelector=LARGE_ROT)
Definition: EshelbianOperators.cpp:155
MOFEM_DATA_INCONSISTENCY
@ MOFEM_DATA_INCONSISTENCY
Definition: definitions.h:31
MoFEM::computeMatrixInverse
MoFEMErrorCode computeMatrixInverse(MatrixDouble &mat)
compute matrix inverse with lapack dgetri
Definition: Templates.hpp:1343
MoFEM::Types::MatrixDouble3by3
MatrixBoundedArray< double, 9 > MatrixDouble3by3
Definition: Types.hpp:105
ReactionDiffusionEquation::D
const double D
diffusivity
Definition: reaction_diffusion.cpp:20
m
FTensor::Index< 'm', 3 > m
Definition: shallow_wave.cpp:80
FTensor::Kronecker_Delta_symmetric
Kronecker Delta class symmetric.
Definition: Kronecker_Delta.hpp:49
third
constexpr double third
Definition: EshelbianADOL-C.cpp:14
EshelbianPlasticity::isEq::check
static auto check(const double &a, const double &b)
Definition: EshelbianOperators.cpp:230
EshelbianPlasticity::MODERATE_ROT
@ MODERATE_ROT
Definition: EshelbianPlasticity.hpp:20
k
FTensor::Index< 'k', 3 > k
Definition: matrix_function.cpp:20
EshelbianPlasticity::TensorTypeExtractor::Type
std::remove_pointer< T >::type Type
Definition: EshelbianOperators.cpp:112
EigenMatrix::getDiffMat
FTensor::Ddg< double, 3, 3 > getDiffMat(Val< double, 3 > &t_val, Vec< double, 3 > &t_vec, Fun< double > f, Fun< double > d_f, const int nb)
Get the Diff Mat object.
Definition: MatrixFunction.cpp:64
MoFEMFunctionReturn
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
Definition: definitions.h:429
EshelbianPlasticity::TensorTypeExtractor< FTensor::PackPtr< T, I > >::Type
std::remove_pointer< T >::type Type
Definition: EshelbianOperators.cpp:115
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::computeEigenValuesSymmetric
MoFEMErrorCode computeEigenValuesSymmetric(const MatrixDouble &mat, VectorDouble &eig, MatrixDouble &eigen_vec)
compute eigenvalues of a symmetric matrix using lapack dsyev
Definition: Templates.hpp:1430