v0.15.0
Loading...
Searching...
No Matches
EshelbianOperators.cpp
Go to the documentation of this file.
1/**
2 * \file EshelbianOperators.cpp
3 * \example mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianOperators.cpp
4 *
5 * \brief Implementation of operators
6 */
7
8#include <MoFEM.hpp>
9using namespace MoFEM;
10
12
13#include <boost/math/constants/constants.hpp>
14
15#include <EshelbianAux.hpp>
16
17#include <lapack_wrap.h>
18
19#include <Lie.hpp>
20#include <MatrixFunction.hpp>
21
22#ifdef ENABLE_PYTHON_BINDING
23#include <boost/python.hpp>
24#include <boost/python/def.hpp>
25#include <boost/python/numpy.hpp>
26namespace bp = boost::python;
27namespace np = boost::python::numpy;
28#endif
29
30namespace EshelbianPlasticity {
31
32MoFEMErrorCode OpCalculateEshelbyStress::doWork(int side, EntityType type,
33 EntData &data) {
38
39 int nb_integration_pts = getGaussPts().size2();
40
41 auto t_P = getFTensor2FromMat<SPACE_DIM, SPACE_DIM>(dataAtPts->approxPAtPts);
42 auto t_F = getFTensor2FromMat<SPACE_DIM, SPACE_DIM>(dataAtPts->hAtPts);
43 auto t_energy = getFTensor0FromVec(dataAtPts->energyAtPts);
44
45 dataAtPts->SigmaAtPts.resize(SPACE_DIM * SPACE_DIM, nb_integration_pts,
46 false);
47 auto t_eshelby_stress =
48 getFTensor2FromMat<SPACE_DIM, SPACE_DIM>(dataAtPts->SigmaAtPts);
49
51
52 for (auto gg = 0; gg != nb_integration_pts; ++gg) {
53 t_eshelby_stress(i, j) = t_energy * t_kd(i, j) - t_F(m, i) * t_P(m, j);
54 ++t_energy;
55 ++t_P;
56 ++t_F;
57 ++t_eshelby_stress;
58 }
59
61}
62
64 EntityType type,
65 EntData &data) {
67
68 auto ts_ctx = getTSCtx();
69 int nb_integration_pts = getGaussPts().size2();
70
71 // space size indices
79
80 // sym size indices
82
83 auto t_L = symm_L_tensor();
84
85 dataAtPts->hAtPts.resize(9, nb_integration_pts, false);
86 dataAtPts->hdOmegaAtPts.resize(9 * 3, nb_integration_pts, false);
87 dataAtPts->hdLogStretchAtPts.resize(9 * 6, nb_integration_pts, false);
88
89 dataAtPts->leviKirchhoffAtPts.resize(3, nb_integration_pts, false);
90 dataAtPts->leviKirchhoffdOmegaAtPts.resize(9, nb_integration_pts, false);
91 dataAtPts->leviKirchhoffdLogStreatchAtPts.resize(3 * size_symm,
92 nb_integration_pts, false);
93 dataAtPts->leviKirchhoffPAtPts.resize(9 * 3, nb_integration_pts, false);
94
95 dataAtPts->adjointPdstretchAtPts.resize(9, nb_integration_pts, false);
96 dataAtPts->adjointPdUAtPts.resize(size_symm, nb_integration_pts, false);
97 dataAtPts->adjointPdUdPAtPts.resize(9 * size_symm, nb_integration_pts, false);
98 dataAtPts->adjointPdUdOmegaAtPts.resize(3 * size_symm, nb_integration_pts,
99 false);
100 dataAtPts->rotMatAtPts.resize(9, nb_integration_pts, false);
101 dataAtPts->stretchTensorAtPts.resize(6, nb_integration_pts, false);
102 dataAtPts->diffStretchTensorAtPts.resize(36, nb_integration_pts, false);
103 dataAtPts->eigenVals.resize(3, nb_integration_pts, false);
104 dataAtPts->eigenVecs.resize(9, nb_integration_pts, false);
105 dataAtPts->nbUniq.resize(nb_integration_pts, false);
106 dataAtPts->eigenValsC.resize(3, nb_integration_pts, false);
107 dataAtPts->eigenVecsC.resize(9, nb_integration_pts, false);
108 dataAtPts->nbUniqC.resize(nb_integration_pts, false);
109
110 dataAtPts->logStretch2H1AtPts.resize(6, nb_integration_pts, false);
111 dataAtPts->logStretchTotalTensorAtPts.resize(6, nb_integration_pts, false);
112
113 dataAtPts->internalStressAtPts.resize(9, nb_integration_pts, false);
114 dataAtPts->internalStressAtPts.clear();
115
116 // Calculated values
117 auto t_h = getFTensor2FromMat<3, 3>(dataAtPts->hAtPts);
118 auto t_h_domega = getFTensor3FromMat<3, 3, 3>(dataAtPts->hdOmegaAtPts);
119 auto t_h_dlog_u =
120 getFTensor3FromMat<3, 3, size_symm>(dataAtPts->hdLogStretchAtPts);
121 auto t_levi_kirchhoff = getFTensor1FromMat<3>(dataAtPts->leviKirchhoffAtPts);
122 auto t_levi_kirchhoff_domega =
123 getFTensor2FromMat<3, 3>(dataAtPts->leviKirchhoffdOmegaAtPts);
124 auto t_levi_kirchhoff_dstreach = getFTensor2FromMat<3, size_symm>(
125 dataAtPts->leviKirchhoffdLogStreatchAtPts);
126 auto t_levi_kirchhoff_dP =
127 getFTensor3FromMat<3, 3, 3>(dataAtPts->leviKirchhoffPAtPts);
128 auto t_approx_P_adjoint__dstretch =
129 getFTensor2FromMat<3, 3>(dataAtPts->adjointPdstretchAtPts);
130 auto t_approx_P_adjoint_log_du =
131 getFTensor1FromMat<size_symm>(dataAtPts->adjointPdUAtPts);
132 auto t_approx_P_adjoint_log_du_dP =
133 getFTensor3FromMat<3, 3, size_symm>(dataAtPts->adjointPdUdPAtPts);
134 auto t_approx_P_adjoint_log_du_domega =
135 getFTensor2FromMat<3, size_symm>(dataAtPts->adjointPdUdOmegaAtPts);
136 auto t_R = getFTensor2FromMat<3, 3>(dataAtPts->rotMatAtPts);
137 auto t_u = getFTensor2SymmetricFromMat<3>(dataAtPts->stretchTensorAtPts);
138 auto t_diff_u =
139 getFTensor4DdgFromMat<3, 3, 1>(dataAtPts->diffStretchTensorAtPts);
140 auto t_eigen_vals = getFTensor1FromMat<3>(dataAtPts->eigenVals);
141 auto t_eigen_vecs = getFTensor2FromMat<3, 3>(dataAtPts->eigenVecs);
142 auto &nbUniq = dataAtPts->nbUniq;
143 auto t_nb_uniq =
144 FTensor::Tensor0<FTensor::PackPtr<int *, 1>>(nbUniq.data().data());
145 auto t_eigen_vals_C = getFTensor1FromMat<3>(dataAtPts->eigenValsC);
146 auto t_eigen_vecs_C = getFTensor2FromMat<3, 3>(dataAtPts->eigenVecsC);
147 auto &nbUniqC = dataAtPts->nbUniqC;
148 auto t_nb_uniq_C =
149 FTensor::Tensor0<FTensor::PackPtr<int *, 1>>(nbUniqC.data().data());
150
151 auto t_log_stretch_total =
152 getFTensor2SymmetricFromMat<3>(dataAtPts->logStretchTotalTensorAtPts);
153 auto t_log_u2_h1 =
154 getFTensor2SymmetricFromMat<3>(dataAtPts->logStretch2H1AtPts);
155
156 // Field values
157 auto t_grad_h1 = getFTensor2FromMat<3, 3>(dataAtPts->wGradH1AtPts);
158 auto t_omega = getFTensor1FromMat<3>(dataAtPts->rotAxisAtPts);
159 auto t_approx_P = getFTensor2FromMat<3, 3>(dataAtPts->approxPAtPts);
160 auto t_log_u =
161 getFTensor2SymmetricFromMat<3>(dataAtPts->logStretchTensorAtPts);
162
163 auto next = [&]() {
164 // calculated values
165 ++t_h;
166 ++t_h_domega;
167 ++t_h_dlog_u;
168 ++t_levi_kirchhoff;
169 ++t_levi_kirchhoff_domega;
170 ++t_levi_kirchhoff_dstreach;
171 ++t_levi_kirchhoff_dP;
172 ++t_approx_P_adjoint__dstretch;
173 ++t_approx_P_adjoint_log_du;
174 ++t_approx_P_adjoint_log_du_dP;
175 ++t_approx_P_adjoint_log_du_domega;
176 ++t_R;
177 ++t_u;
178 ++t_diff_u;
179 ++t_eigen_vals;
180 ++t_eigen_vecs;
181 ++t_nb_uniq;
182 ++t_eigen_vals_C;
183 ++t_eigen_vecs_C;
184 ++t_nb_uniq_C;
185 ++t_log_u2_h1;
186 ++t_log_stretch_total;
187 // field values
188 ++t_omega;
189 ++t_grad_h1;
190 ++t_approx_P;
191 ++t_log_u;
192 };
193
196
197 auto bound_eig = [&](auto &eig) {
199 const auto zero = std::exp(std::numeric_limits<double>::min_exponent);
200 const auto large = std::exp(std::numeric_limits<double>::max_exponent);
201 for (int ii = 0; ii != 3; ++ii) {
202 eig(ii) = std::min(std::max(zero, eig(ii)), large);
203 }
205 };
206
207 auto calculate_log_stretch = [&]() {
210 eigen_vec(i, j) = t_log_u(i, j);
211 if (computeEigenValuesSymmetric(eigen_vec, eig) != MB_SUCCESS) {
212 MOFEM_LOG("SELF", Sev::error) << "Failed to compute eigen values";
213 }
214 // CHKERR bound_eig(eig);
215 // rare case when two eigen values are equal
216 t_nb_uniq = get_uniq_nb<3>(&eig(0));
217 if (t_nb_uniq < 3) {
218 sort_eigen_vals(eig, eigen_vec);
219 }
220 t_eigen_vals(i) = eig(i);
221 t_eigen_vecs(i, j) = eigen_vec(i, j);
222 t_u(i, j) =
223 EigenMatrix::getMat(t_eigen_vals, t_eigen_vecs, EshelbianCore::f)(i, j);
224 auto get_t_diff_u = [&]() {
225 return EigenMatrix::getDiffMat(t_eigen_vals, t_eigen_vecs,
227 t_nb_uniq);
228 };
229 t_diff_u(i, j, k, l) = get_t_diff_u()(i, j, k, l);
231 t_Ldiff_u(i, j, L) = t_diff_u(i, j, m, n) * t_L(m, n, L);
232 return t_Ldiff_u;
233 };
234
235 auto calculate_total_stretch = [&](auto &t_h1) {
237
238 t_log_u2_h1(i, j) = 0;
239 t_log_stretch_total(i, j) = t_log_u(i, j);
240
243 t_R_h1(i, j) = t_kd(i, j);
244 t_inv_u_h1(i, j) = t_symm_kd(i, j);
245
246 return std::make_pair(t_R_h1, t_inv_u_h1);
247
248 } else {
249
252
254 t_C_h1(i, j) = t_h1(k, i) * t_h1(k, j);
255 eigen_vec(i, j) = t_C_h1(i, j);
256 if (computeEigenValuesSymmetric(eigen_vec, eig) != MB_SUCCESS) {
257 MOFEM_LOG("SELF", Sev::error) << "Failed to compute eigen values";
258 }
259 // rare case when two eigen values are equal
260 t_nb_uniq_C = get_uniq_nb<3>(&eig(0));
261 if (t_nb_uniq_C < 3) {
262 sort_eigen_vals(eig, eigen_vec);
263 }
265 CHKERR bound_eig(eig);
266 }
267 t_eigen_vals_C(i) = eig(i);
268 t_eigen_vecs_C(i, j) = eigen_vec(i, j);
269
270 t_log_u2_h1(i, j) =
271 EigenMatrix::getMat(eig, eigen_vec, EshelbianCore::inv_f)(i, j);
272 t_log_stretch_total(i, j) = t_log_u2_h1(i, j) / 2 + t_log_u(i, j);
273
274 auto f_inv_sqrt = [](auto e) { return 1. / std::sqrt(e); };
276 t_inv_u_h1(i, j) = EigenMatrix::getMat(eig, eigen_vec, f_inv_sqrt)(i, j);
278 t_R_h1(i, j) = t_h1(i, o) * t_inv_u_h1(o, j);
279
280 return std::make_pair(t_R_h1, t_inv_u_h1);
281 }
282 };
283
284 auto no_h1_loop = [&]() {
286
288 case LARGE_ROT:
289 break;
290 case SMALL_ROT:
291 break;
292 default:
293 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
294 "rotSelector should be large");
295 };
296
297 for (int gg = 0; gg != nb_integration_pts; ++gg) {
298
300
302 t_h1(i, j) = t_kd(i, j);
303
304 // calculate streach
305 auto t_Ldiff_u = calculate_log_stretch();
306
307 // calculate total stretch
308 auto [t_R_h1, t_inv_u_h1] = calculate_total_stretch(t_h1);
309
314
316
317 // rotation
319 case LARGE_ROT:
320 t_R(i, j) = LieGroups::SO3::exp(t_omega, t_omega.l2())(i, j);
321 t_diff_R(i, j, k) =
322 LieGroups::SO3::diffExp(t_omega, t_omega.l2())(i, j, k);
323 // left
324 t_diff_Rr(i, j, l) = t_R(i, k) * levi_civita(k, j, l);
325 t_diff_diff_Rr(i, j, l, m) = t_diff_R(i, k, m) * levi_civita(k, j, l);
326 // right
327 t_diff_Rl(i, j, l) = levi_civita(i, k, l) * t_R(k, j);
328 t_diff_diff_Rl(i, j, l, m) = levi_civita(i, k, l) * t_diff_R(k, j, m);
329 break;
330
331 default:
332 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
333 "rotationSelector not handled");
334 }
335
336 constexpr double half_r = 1 / 2.;
337 constexpr double half_l = 1 / 2.;
338
339 // calculate gradient
340 t_h(i, k) = t_R(i, l) * t_u(l, k);
341
342 // Adjoint stress
343 t_approx_P_adjoint__dstretch(l, k) =
344 (t_R(i, l) * t_approx_P(i, k) + t_R(i, k) * t_approx_P(i, l));
345 t_approx_P_adjoint__dstretch(l, k) /= 2.;
346
347 t_approx_P_adjoint_log_du(L) =
348 (t_approx_P_adjoint__dstretch(l, k) * t_Ldiff_u(l, k, L) +
349 t_approx_P_adjoint__dstretch(k, l) * t_Ldiff_u(l, k, L) +
350 t_approx_P_adjoint__dstretch(l, k) * t_Ldiff_u(k, l, L) +
351 t_approx_P_adjoint__dstretch(k, l) * t_Ldiff_u(k, l, L)) /
352 4.;
353
354 // Kirchhoff stress
355 t_levi_kirchhoff(m) =
356
357 half_r * (t_diff_Rr(i, l, m) * (t_u(l, k) * t_approx_P(i, k)) +
358 t_diff_Rr(i, k, m) * (t_u(l, k) * t_approx_P(i, l)))
359
360 +
361
362 half_l * (t_diff_Rl(i, l, m) * (t_u(l, k) * t_approx_P(i, k)) +
363 t_diff_Rl(i, k, m) * (t_u(l, k) * t_approx_P(i, l)));
364 t_levi_kirchhoff(m) /= 2.;
365
367
369 t_h_domega(i, k, m) = half_r * (t_diff_Rr(i, l, m) * t_u(l, k))
370
371 +
372
373 half_l * (t_diff_Rl(i, l, m) * t_u(l, k));
374 } else {
375 t_h_domega(i, k, m) = t_diff_R(i, l, m) * t_u(l, k);
376 }
377
378 t_h_dlog_u(i, k, L) = t_R(i, l) * t_Ldiff_u(l, k, L);
379
380 t_approx_P_adjoint_log_du_dP(i, k, L) =
381 t_R(i, l) * (t_Ldiff_u(l, k, L) + t_Ldiff_u(k, l, L)) / 2.;
382
385 t_A(k, l, m) = t_diff_Rr(i, l, m) * t_approx_P(i, k) +
386 t_diff_Rr(i, k, m) * t_approx_P(i, l);
387 t_A(k, l, m) /= 2.;
389 t_B(k, l, m) = t_diff_Rl(i, l, m) * t_approx_P(i, k) +
390 t_diff_Rl(i, k, m) * t_approx_P(i, l);
391 t_B(k, l, m) /= 2.;
392
393 t_approx_P_adjoint_log_du_domega(m, L) =
394 half_r * (t_A(k, l, m) *
395 (t_Ldiff_u(k, l, L) + t_Ldiff_u(k, l, L)) / 2) +
396 half_l * (t_B(k, l, m) *
397 (t_Ldiff_u(k, l, L) + t_Ldiff_u(k, l, L)) / 2);
398 } else {
400 t_A(k, l, m) = t_diff_R(i, l, m) * t_approx_P(i, k);
401 t_approx_P_adjoint_log_du_domega(m, L) =
402 t_A(k, l, m) * t_Ldiff_u(k, l, L);
403 }
404
405 t_levi_kirchhoff_dstreach(m, L) =
406 half_r *
407 (t_diff_Rr(i, l, m) * (t_Ldiff_u(l, k, L) * t_approx_P(i, k)))
408
409 +
410
411 half_l *
412 (t_diff_Rl(i, l, m) * (t_Ldiff_u(l, k, L) * t_approx_P(i, k)));
413
414 t_levi_kirchhoff_dP(m, i, k) =
415 half_r * t_diff_Rr(i, l, m) * (t_u(l, k))
416
417 +
418
419 half_l * t_diff_Rl(i, l, m) * (t_u(l, k));
420
421 t_levi_kirchhoff_domega(m, n) =
422 half_r *
423 (t_diff_diff_Rr(i, l, m, n) * (t_u(l, k) * t_approx_P(i, k)) +
424 t_diff_diff_Rr(i, k, m, n) * (t_u(l, k) * t_approx_P(i, l)))
425
426 +
427
428 half_l *
429 (t_diff_diff_Rl(i, l, m, n) * (t_u(l, k) * t_approx_P(i, k)) +
430 t_diff_diff_Rl(i, k, m, n) * (t_u(l, k) * t_approx_P(i, l)));
431 t_levi_kirchhoff_domega(m, n) /= 2.;
432 }
433
434 next();
435 }
436
438 };
439
440 auto large_loop = [&]() {
442
444 case LARGE_ROT:
445 break;
446 case SMALL_ROT:
447 break;
448 default:
449 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
450 "rotSelector should be large");
451 };
452
453 for (int gg = 0; gg != nb_integration_pts; ++gg) {
454
456
460 t_h1(i, j) = t_kd(i, j);
461 break;
462 case LARGE_ROT:
463 t_h1(i, j) = t_grad_h1(i, j) + t_kd(i, j);
464 break;
465 default:
466 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
467 "gradApproximator not handled");
468 };
469
470 // calculate streach
471 auto t_Ldiff_u = calculate_log_stretch();
472 // calculate total stretch
473 auto [t_R_h1, t_inv_u_h1] = calculate_total_stretch(t_h1);
474
476 t_h_u(l, k) = t_u(l, o) * t_h1(o, k);
478 t_Ldiff_h_u(l, k, L) = t_Ldiff_u(l, o, L) * t_h1(o, k);
479
484
486
487 // rotation
489 case LARGE_ROT:
490 t_R(i, j) = LieGroups::SO3::exp(t_omega, t_omega.l2())(i, j);
491 t_diff_R(i, j, k) =
492 LieGroups::SO3::diffExp(t_omega, t_omega.l2())(i, j, k);
493 // left
494 t_diff_Rr(i, j, l) = t_R(i, k) * levi_civita(k, j, l);
495 t_diff_diff_Rr(i, j, l, m) = t_diff_R(i, k, m) * levi_civita(k, j, l);
496 // right
497 t_diff_Rl(i, j, l) = levi_civita(i, k, l) * t_R(k, j);
498 t_diff_diff_Rl(i, j, l, m) = levi_civita(i, k, l) * t_diff_R(k, j, m);
499 break;
500 case SMALL_ROT:
501 t_R(i, k) = t_kd(i, k) + levi_civita(i, k, l) * t_omega(l);
502 t_diff_R(i, j, k) = levi_civita(i, j, k);
503 // left
504 t_diff_Rr(i, j, l) = levi_civita(i, j, l);
505 t_diff_diff_Rr(i, j, l, m) = 0;
506 // right
507 t_diff_Rl(i, j, l) = levi_civita(i, j, l);
508 t_diff_diff_Rl(i, j, l, m) = 0;
509 break;
510
511 default:
512 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
513 "rotationSelector not handled");
514 }
515
516 constexpr double half_r = 1 / 2.;
517 constexpr double half_l = 1 / 2.;
518
519 // calculate gradient
520 t_h(i, k) = t_R(i, l) * t_h_u(l, k);
521
522 // Adjoint stress
523 t_approx_P_adjoint__dstretch(l, o) =
524 (t_R(i, l) * t_approx_P(i, k)) * t_h1(o, k);
525 t_approx_P_adjoint_log_du(L) =
526 t_approx_P_adjoint__dstretch(l, o) * t_Ldiff_u(l, o, L);
527
528 // Kirchhoff stress
529 t_levi_kirchhoff(m) =
530
531 half_r * ((t_diff_Rr(i, l, m) * (t_h_u(l, k)) * t_approx_P(i, k)))
532
533 +
534
535 half_l * ((t_diff_Rl(i, l, m) * (t_h_u(l, k)) * t_approx_P(i, k)));
536
538
540 t_h_domega(i, k, m) = half_r * (t_diff_Rr(i, l, m) * t_h_u(l, k))
541
542 +
543
544 half_l * (t_diff_Rl(i, l, m) * t_h_u(l, k));
545 } else {
546 t_h_domega(i, k, m) = t_diff_R(i, l, m) * t_h_u(l, k);
547 }
548
549 t_h_dlog_u(i, k, L) = t_R(i, l) * t_Ldiff_h_u(l, k, L);
550
551 t_approx_P_adjoint_log_du_dP(i, k, L) =
552 t_R(i, l) * t_Ldiff_h_u(l, k, L);
553
556 t_A(m, L, i, k) = t_diff_Rr(i, l, m) * t_Ldiff_h_u(l, k, L);
558 t_B(m, L, i, k) = t_diff_Rl(i, l, m) * t_Ldiff_h_u(l, k, L);
559
560 t_approx_P_adjoint_log_du_domega(m, L) =
561 half_r * (t_A(m, L, i, k) * t_approx_P(i, k))
562
563 +
564
565 half_l * (t_B(m, L, i, k) * t_approx_P(i, k));
566 } else {
568 t_A(m, L, i, k) = t_diff_R(i, l, m) * t_Ldiff_h_u(l, k, L);
569 t_approx_P_adjoint_log_du_domega(m, L) =
570 t_A(m, L, i, k) * t_approx_P(i, k);
571 }
572
573 t_levi_kirchhoff_dstreach(m, L) =
574 half_r *
575 (t_diff_Rr(i, l, m) * (t_Ldiff_h_u(l, k, L) * t_approx_P(i, k)))
576
577 +
578
579 half_l * (t_diff_Rl(i, l, m) *
580 (t_Ldiff_h_u(l, k, L) * t_approx_P(i, k)));
581
582 t_levi_kirchhoff_dP(m, i, k) =
583
584 half_r * (t_diff_Rr(i, l, m) * t_h_u(l, k))
585
586 +
587
588 half_l * (t_diff_Rl(i, l, m) * t_h_u(l, k));
589
590 t_levi_kirchhoff_domega(m, n) =
591 half_r *
592 (t_diff_diff_Rr(i, l, m, n) * (t_h_u(l, k) * t_approx_P(i, k)))
593
594 +
595
596 half_l *
597 (t_diff_diff_Rl(i, l, m, n) * (t_h_u(l, k) * t_approx_P(i, k)));
598 }
599
600 next();
601 }
602
604 };
605
606 auto moderate_loop = [&]() {
608
610 case LARGE_ROT:
611 break;
612 case SMALL_ROT:
613 break;
614 default:
615 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
616 "rotSelector should be large");
617 };
618
619 for (int gg = 0; gg != nb_integration_pts; ++gg) {
620
622
625 case MODERATE_ROT:
626 t_h1(i, j) = t_grad_h1(i, j) + t_kd(i, j);
627 break;
628 default:
629 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
630 "gradApproximator not handled");
631 };
632
633 // calculate streach
634 auto t_Ldiff_u = calculate_log_stretch();
635 // calculate total stretch
636 auto [t_R_h1, t_inv_u_h1] = calculate_total_stretch(t_h1);
637
639 t_h_u(l, k) = (t_symm_kd(l, o) + t_log_u(l, o)) * t_h1(o, k);
641 t_L_h(l, k, L) = t_L(l, o, L) * t_h1(o, k);
642
647
649
650 // rotation
652 case LARGE_ROT:
653 t_R(i, j) = LieGroups::SO3::exp(t_omega, t_omega.l2())(i, j);
654 t_diff_R(i, j, k) =
655 LieGroups::SO3::diffExp(t_omega, t_omega.l2())(i, j, k);
656 // left
657 t_diff_Rr(i, j, l) = t_R(i, k) * levi_civita(k, j, l);
658 t_diff_diff_Rr(i, j, l, m) = t_diff_R(i, k, m) * levi_civita(k, j, l);
659 // right
660 t_diff_Rl(i, j, l) = levi_civita(i, k, l) * t_R(k, j);
661 t_diff_diff_Rl(i, j, l, m) = levi_civita(i, k, l) * t_diff_R(k, j, m);
662 break;
663 case SMALL_ROT:
664 t_R(i, k) = t_kd(i, k) + levi_civita(i, k, l) * t_omega(l);
665 t_diff_R(i, j, l) = levi_civita(i, j, l);
666 // left
667 t_diff_Rr(i, j, l) = levi_civita(i, j, l);
668 t_diff_diff_Rr(i, j, l, m) = 0;
669 // right
670 t_diff_Rl(i, j, l) = levi_civita(i, j, l);
671 t_diff_diff_Rl(i, j, l, m) = 0;
672 break;
673
674 default:
675 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
676 "rotationSelector not handled");
677 }
678
679 constexpr double half_r = 1 / 2.;
680 constexpr double half_l = 1 / 2.;
681
682 // calculate gradient
683 t_h(i, k) = t_R(i, l) * t_h_u(l, k);
684
685 // Adjoint stress
686 t_approx_P_adjoint__dstretch(l, o) =
687 (t_R(i, l) * t_approx_P(i, k)) * t_h1(o, k);
688
689 t_approx_P_adjoint_log_du(L) =
690 t_approx_P_adjoint__dstretch(l, o) * t_L(l, o, L);
691
692 // Kirchhoff stress
693 t_levi_kirchhoff(m) =
694
695 half_r * ((t_diff_Rr(i, l, m) * (t_h_u(l, k)) * t_approx_P(i, k)))
696
697 +
698
699 half_l * ((t_diff_Rl(i, l, m) * (t_h_u(l, k)) * t_approx_P(i, k)));
700
702
704 t_h_domega(i, k, m) = half_r * (t_diff_Rr(i, l, m) * t_h_u(l, k))
705
706 +
707
708 half_l * (t_diff_Rl(i, l, m) * t_h_u(l, k));
709 } else {
710 t_h_domega(i, k, m) = t_diff_R(i, l, m) * t_h_u(l, k);
711 }
712
713 t_h_dlog_u(i, k, L) = t_R(i, l) * t_L_h(l, k, L);
714
715 t_approx_P_adjoint_log_du_dP(i, k, L) = t_R(i, l) * t_L_h(l, k, L);
716
719 t_A(m, L, i, k) = t_diff_Rr(i, l, m) * t_L_h(l, k, L);
721 t_B(m, L, i, k) = t_diff_Rl(i, l, m) * t_L_h(l, k, L);
722 t_approx_P_adjoint_log_du_domega(m, L) =
723 half_r * (t_A(m, L, i, k) * t_approx_P(i, k))
724
725 +
726
727 half_l * (t_B(m, L, i, k) * t_approx_P(i, k));
728 } else {
730 t_A(m, L, i, k) = t_diff_R(i, l, m) * t_L_h(l, k, L);
731 t_approx_P_adjoint_log_du_domega(m, L) =
732 t_A(m, L, i, k) * t_approx_P(i, k);
733 }
734
735 t_levi_kirchhoff_dstreach(m, L) =
736 half_r * (t_diff_Rr(i, l, m) * (t_L_h(l, k, L) * t_approx_P(i, k)))
737
738 +
739
740 half_l * (t_diff_Rl(i, l, m) * (t_L_h(l, k, L) * t_approx_P(i, k)));
741
742 t_levi_kirchhoff_dP(m, i, k) =
743
744 half_r * (t_diff_Rr(i, l, m) * t_h_u(l, k))
745
746 +
747
748 half_l * (t_diff_Rl(i, l, m) * t_h_u(l, k));
749
750 t_levi_kirchhoff_domega(m, n) =
751 half_r *
752 (t_diff_diff_Rr(i, l, m, n) * (t_h_u(l, k) * t_approx_P(i, k)))
753
754 +
755
756 half_l *
757 (t_diff_diff_Rl(i, l, m, n) * (t_h_u(l, k) * t_approx_P(i, k)));
758 }
759
760 next();
761 }
762
764 };
765
766 auto small_loop = [&]() {
769 case SMALL_ROT:
770 break;
771 default:
772 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
773 "rotSelector should be small");
774 };
775
776 for (int gg = 0; gg != nb_integration_pts; ++gg) {
777
780 case SMALL_ROT:
781 t_h1(i, j) = t_kd(i, j);
782 break;
783 default:
784 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
785 "gradApproximator not handled");
786 };
787
788 // calculate streach
790
792 t_Ldiff_u(i, j, L) = calculate_log_stretch()(i, j, L);
793 } else {
794 t_u(i, j) = t_symm_kd(i, j) + t_log_u(i, j);
795 t_Ldiff_u(i, j, L) = t_L(i, j, L);
796 }
797 t_log_u2_h1(i, j) = 0;
798 t_log_stretch_total(i, j) = t_log_u(i, j);
799
801 t_h(i, j) = levi_civita(i, j, k) * t_omega(k) + t_u(i, j);
802
803 t_h_domega(i, j, k) = levi_civita(i, j, k);
804 t_h_dlog_u(i, j, L) = t_Ldiff_u(i, j, L);
805
806 // Adjoint stress
807 t_approx_P_adjoint__dstretch(i, j) = t_approx_P(i, j);
808 t_approx_P_adjoint_log_du(L) =
809 t_approx_P_adjoint__dstretch(i, j) * t_Ldiff_u(i, j, L);
810 t_approx_P_adjoint_log_du_dP(i, j, L) = t_Ldiff_u(i, j, L);
811 t_approx_P_adjoint_log_du_domega(m, L) = 0;
812
813 // Kirchhoff stress
814 t_levi_kirchhoff(k) = levi_civita(i, j, k) * t_approx_P(i, j);
815 t_levi_kirchhoff_dstreach(m, L) = 0;
816 t_levi_kirchhoff_dP(k, i, j) = levi_civita(i, j, k);
817 t_levi_kirchhoff_domega(m, n) = 0;
818
819 next();
820 }
821
823 };
824
827 CHKERR no_h1_loop();
828 break;
829 case LARGE_ROT:
830 CHKERR large_loop();
832 break;
833 case MODERATE_ROT:
834 CHKERR moderate_loop();
836 break;
837 case SMALL_ROT:
838 CHKERR small_loop();
840 break;
841 default:
842 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
843 "gradApproximator not handled");
844 break;
845 };
846
848}
849
851 EntData &data) {
855
856 auto N_InLoop = getNinTheLoop();
857 auto sensee = getSkeletonSense();
858 auto nb_gauss_pts = getGaussPts().size2();
859 auto t_normal = getFTensor1NormalsAtGaussPts();
860
861 auto t_sigma_ptr =
862 getFTensor2FromMat<SPACE_DIM, SPACE_DIM>(dataAtPts->approxPAtPts);
863 if (N_InLoop == 0) {
864 dataAtPts->tractionAtPts.resize(SPACE_DIM, nb_gauss_pts, false);
865 dataAtPts->tractionAtPts.clear();
866 }
867 auto t_traction = getFTensor1FromMat<SPACE_DIM>(dataAtPts->tractionAtPts);
868
869 for (int gg = 0; gg != nb_gauss_pts; gg++) {
870 t_traction(i) = t_sigma_ptr(i, j) * sensee * (t_normal(j) / t_normal.l2());
871 ++t_traction;
872 ++t_sigma_ptr;
873 ++t_normal;
874 }
875
877}
878
880 EntData &data) {
882 if (blockEntities.find(getFEEntityHandle()) == blockEntities.end()) {
884 };
888 int nb_integration_pts = getGaussPts().size2();
889 auto t_w = getFTensor0IntegrationWeight();
890 auto t_traction = getFTensor1FromMat<SPACE_DIM>(dataAtPts->tractionAtPts);
891 auto t_coords = getFTensor1CoordsAtGaussPts();
892 auto t_spatial_disp = getFTensor1FromMat<SPACE_DIM>(dataAtPts->wL2AtPts);
893
894 FTensor::Tensor1<double, 3> t_coords_spatial{0., 0., 0.};
895 // Offset for center of mass. Can be added in the future.
896 FTensor::Tensor1<double, 3> t_off{0.0, 0.0, 0.0};
897 FTensor::Tensor1<double, 3> loc_reaction_forces{0., 0., 0.};
898 FTensor::Tensor1<double, 3> loc_moment_forces{0., 0., 0.};
899
900 for (auto gg = 0; gg != nb_integration_pts; ++gg) {
901 loc_reaction_forces(i) += (t_traction(i)) * t_w * getMeasure();
902 t_coords_spatial(i) = t_coords(i) + t_spatial_disp(i);
903 // t_coords_spatial(i) -= t_off(i);
904 loc_moment_forces(i) +=
905 (FTensor::levi_civita<double>(i, j, k) * t_coords_spatial(j)) *
906 t_traction(k) * t_w * getMeasure();
907 ++t_coords;
908 ++t_spatial_disp;
909 ++t_w;
910 ++t_traction;
911 }
912
913 reactionVec[0] += loc_reaction_forces(0);
914 reactionVec[1] += loc_reaction_forces(1);
915 reactionVec[2] += loc_reaction_forces(2);
916 reactionVec[3] += loc_moment_forces(0);
917 reactionVec[4] += loc_moment_forces(1);
918 reactionVec[5] += loc_moment_forces(2);
919
921}
922
925 int nb_dofs = data.getIndices().size();
926 int nb_integration_pts = data.getN().size1();
927 auto v = getVolume();
928 auto t_w = getFTensor0IntegrationWeight();
929 auto t_div_P = getFTensor1FromMat<3>(dataAtPts->divPAtPts);
930 auto t_s_dot_w = getFTensor1FromMat<3>(dataAtPts->wL2DotAtPts);
931 if (dataAtPts->wL2DotDotAtPts.size1() == 0 &&
932 dataAtPts->wL2DotDotAtPts.size2() != nb_integration_pts) {
933 dataAtPts->wL2DotDotAtPts.resize(3, nb_integration_pts);
934 dataAtPts->wL2DotDotAtPts.clear();
935 }
936 auto t_s_dot_dot_w = getFTensor1FromMat<3>(dataAtPts->wL2DotDotAtPts);
937
938 auto piola_scale = dataAtPts->piolaScale;
939 auto alpha_w = alphaW / piola_scale;
940 auto alpha_rho = alphaRho / piola_scale;
941
942 int nb_base_functions = data.getN().size2();
943 auto t_row_base_fun = data.getFTensor0N();
944
945 FTensor::Index<'i', 3> i;
946 auto get_ftensor1 = [](auto &v) {
948 &v[2]);
949 };
950
951 for (int gg = 0; gg != nb_integration_pts; ++gg) {
952 double a = v * t_w;
953 auto t_nf = get_ftensor1(nF);
954 int bb = 0;
955 for (; bb != nb_dofs / 3; ++bb) {
956 t_nf(i) -= a * t_row_base_fun * t_div_P(i);
957 t_nf(i) += a * t_row_base_fun * alpha_w * t_s_dot_w(i);
958 t_nf(i) += a * t_row_base_fun * alpha_rho * t_s_dot_dot_w(i);
959 ++t_nf;
960 ++t_row_base_fun;
961 }
962 for (; bb != nb_base_functions; ++bb)
963 ++t_row_base_fun;
964 ++t_w;
965 ++t_div_P;
966 ++t_s_dot_w;
967 ++t_s_dot_dot_w;
968 }
969
971}
972
975 int nb_dofs = data.getIndices().size();
976 int nb_integration_pts = getGaussPts().size2();
977 auto v = getVolume();
978 auto t_w = getFTensor0IntegrationWeight();
979 auto t_levi_kirchhoff = getFTensor1FromMat<3>(dataAtPts->leviKirchhoffAtPts);
980 auto t_omega_grad_dot =
981 getFTensor2FromMat<3, 3>(dataAtPts->rotAxisGradDotAtPts);
982 int nb_base_functions = data.getN().size2();
983 auto t_row_base_fun = data.getFTensor0N();
984 auto t_row_grad_fun = data.getFTensor1DiffN<3>();
985 FTensor::Index<'i', 3> i;
986 FTensor::Index<'j', 3> j;
987 FTensor::Index<'k', 3> k;
988 auto get_ftensor1 = [](auto &v) {
990 &v[2]);
991 };
992 // auto time_step = getTStimeStep();
993
994 for (int gg = 0; gg != nb_integration_pts; ++gg) {
995
996 double a = v * t_w;
997 auto t_nf = get_ftensor1(nF);
998 int bb = 0;
999 for (; bb != nb_dofs / 3; ++bb) {
1000 t_nf(k) -= (a * t_row_base_fun) * t_levi_kirchhoff(k);
1001 t_nf(k) += (a * alphaOmega /*/ time_step*/) *
1002 (t_row_grad_fun(i) * t_omega_grad_dot(k, i));
1003 ++t_nf;
1004 ++t_row_base_fun;
1005 ++t_row_grad_fun;
1006 }
1007 for (; bb != nb_base_functions; ++bb) {
1008 ++t_row_base_fun;
1009 ++t_row_grad_fun;
1010 }
1011 ++t_w;
1012 ++t_levi_kirchhoff;
1013 ++t_omega_grad_dot;
1014 }
1016}
1017
1020 int nb_dofs = data.getIndices().size();
1021 int nb_integration_pts = data.getN().size1();
1022 auto v = getVolume();
1023 auto t_w = getFTensor0IntegrationWeight();
1024
1025 int nb_base_functions = data.getN().size2() / 3;
1026 auto t_row_base_fun = data.getFTensor1N<3>();
1027 FTENSOR_INDEX(3, i);
1028 FTENSOR_INDEX(3, j);
1029 FTENSOR_INDEX(3, k);
1030 FTENSOR_INDEX(3, m);
1031 FTENSOR_INDEX(3, l);
1032
1033 auto get_ftensor1 = [](auto &v) {
1035 &v[2]);
1036 };
1037
1039
1040 auto t_R = getFTensor2FromMat<3, 3>(dataAtPts->rotMatAtPts);
1041 auto t_u = getFTensor2SymmetricFromMat<3>(dataAtPts->stretchTensorAtPts);
1042
1043 for (int gg = 0; gg != nb_integration_pts; ++gg) {
1044 double a = v * t_w;
1045 auto t_nf = get_ftensor1(nF);
1046
1047 constexpr auto t_kd = FTensor::Kronecker_Delta<double>();
1048
1049 int bb = 0;
1050 for (; bb != nb_dofs / 3; ++bb) {
1051 t_nf(i) -= a * (t_row_base_fun(k) * (t_R(i, l) * t_u(l, k)) / 2);
1052 t_nf(i) -= a * (t_row_base_fun(l) * (t_R(i, k) * t_u(l, k)) / 2);
1053 t_nf(i) += a * (t_row_base_fun(j) * t_kd(i, j));
1054 ++t_nf;
1055 ++t_row_base_fun;
1056 }
1057
1058 for (; bb != nb_base_functions; ++bb)
1059 ++t_row_base_fun;
1060
1061 ++t_w;
1062 ++t_R;
1063 ++t_u;
1064 }
1065
1066 } else {
1067
1068 auto t_h = getFTensor2FromMat<3, 3>(dataAtPts->hAtPts);
1069
1070 for (int gg = 0; gg != nb_integration_pts; ++gg) {
1071 double a = v * t_w;
1072 auto t_nf = get_ftensor1(nF);
1073
1074 constexpr auto t_kd = FTensor::Kronecker_Delta<double>();
1076
1077 t_residuum(i, j) = t_h(i, j) - t_kd(i, j);
1078
1079 int bb = 0;
1080 for (; bb != nb_dofs / 3; ++bb) {
1081 t_nf(i) -= a * t_row_base_fun(j) * t_residuum(i, j);
1082 ++t_nf;
1083 ++t_row_base_fun;
1084 }
1085
1086 for (; bb != nb_base_functions; ++bb)
1087 ++t_row_base_fun;
1088
1089 ++t_w;
1090 ++t_h;
1091 }
1092 }
1093
1095}
1096
1099 int nb_dofs = data.getIndices().size();
1100 int nb_integration_pts = data.getN().size1();
1101 auto v = getVolume();
1102 auto t_w = getFTensor0IntegrationWeight();
1103
1104 int nb_base_functions = data.getN().size2() / 9;
1105 auto t_row_base_fun = data.getFTensor2N<3, 3>();
1106 FTENSOR_INDEX(3, i);
1107 FTENSOR_INDEX(3, j);
1108 FTENSOR_INDEX(3, k);
1109 FTENSOR_INDEX(3, m);
1110 FTENSOR_INDEX(3, l);
1111
1112 auto get_ftensor0 = [](auto &v) {
1114 };
1115
1117
1118 auto t_R = getFTensor2FromMat<3, 3>(dataAtPts->rotMatAtPts);
1119 auto t_u = getFTensor2SymmetricFromMat<3>(dataAtPts->stretchTensorAtPts);
1120
1121 for (int gg = 0; gg != nb_integration_pts; ++gg) {
1122 double a = v * t_w;
1123 auto t_nf = get_ftensor0(nF);
1124
1125 constexpr auto t_kd = FTensor::Kronecker_Delta<double>();
1126
1127 int bb = 0;
1128 for (; bb != nb_dofs; ++bb) {
1129 t_nf -= a * t_row_base_fun(i, k) * (t_R(i, l) * t_u(l, k)) / 2;
1130 t_nf -= a * t_row_base_fun(i, l) * (t_R(i, k) * t_u(l, k)) / 2;
1131 ++t_nf;
1132 ++t_row_base_fun;
1133 }
1134 for (; bb != nb_base_functions; ++bb) {
1135 ++t_row_base_fun;
1136 }
1137 ++t_w;
1138 ++t_R;
1139 ++t_u;
1140 }
1141
1142 } else {
1143
1144 auto t_h = getFTensor2FromMat<3, 3>(dataAtPts->hAtPts);
1145
1146 for (int gg = 0; gg != nb_integration_pts; ++gg) {
1147 double a = v * t_w;
1148 auto t_nf = get_ftensor0(nF);
1149
1150 constexpr auto t_kd = FTensor::Kronecker_Delta<double>();
1152 t_residuum(i, j) = t_h(i, j);
1153
1154 int bb = 0;
1155 for (; bb != nb_dofs; ++bb) {
1156 t_nf -= a * t_row_base_fun(i, j) * t_residuum(i, j);
1157 ++t_nf;
1158 ++t_row_base_fun;
1159 }
1160 for (; bb != nb_base_functions; ++bb) {
1161 ++t_row_base_fun;
1162 }
1163 ++t_w;
1164 ++t_h;
1165 }
1166 }
1167
1169}
1170
1173 int nb_dofs = data.getIndices().size();
1174 int nb_integration_pts = data.getN().size1();
1175 auto v = getVolume();
1176 auto t_w = getFTensor0IntegrationWeight();
1177 auto t_w_l2 = getFTensor1FromMat<3>(dataAtPts->wL2AtPts);
1178 int nb_base_functions = data.getN().size2() / 3;
1179 auto t_row_diff_base_fun = data.getFTensor2DiffN<3, 3>();
1180 FTensor::Index<'i', 3> i;
1181 auto get_ftensor1 = [](auto &v) {
1183 &v[2]);
1184 };
1185
1186 for (int gg = 0; gg != nb_integration_pts; ++gg) {
1187 double a = v * t_w;
1188 auto t_nf = get_ftensor1(nF);
1189 int bb = 0;
1190 for (; bb != nb_dofs / 3; ++bb) {
1191 double div_row_base = t_row_diff_base_fun(i, i);
1192 t_nf(i) -= a * div_row_base * t_w_l2(i);
1193 ++t_nf;
1194 ++t_row_diff_base_fun;
1195 }
1196 for (; bb != nb_base_functions; ++bb) {
1197 ++t_row_diff_base_fun;
1198 }
1199 ++t_w;
1200 ++t_w_l2;
1201 }
1202
1204}
1205
1206template <>
1208 EntData &data) {
1210
1211 int nb_integration_pts = getGaussPts().size2();
1212
1213 Tag tag;
1214 CHKERR getPtrFE() -> mField.get_moab().tag_get_handle(tagName.c_str(), tag);
1215 int tag_length;
1216 CHKERR getPtrFE() -> mField.get_moab().tag_get_length(tag, tag_length);
1217 if (tag_length != 9) {
1218 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1219 "Number of internal stress components should be 9 but is %d",
1220 tag_length);
1221 }
1222
1223 VectorDouble const_stress_vec(9);
1224 auto fe_ent = getNumeredEntFiniteElementPtr()->getEnt();
1225 CHKERR getPtrFE() -> mField.get_moab().tag_get_data(
1226 tag, &fe_ent, 1, &*const_stress_vec.data().begin());
1227 auto t_const_stress = getFTensor1FromArray<9, 9>(const_stress_vec);
1228
1229 dataAtPts->internalStressAtPts.resize(tag_length, nb_integration_pts, false);
1230 dataAtPts->internalStressAtPts.clear();
1231 auto t_internal_stress =
1232 getFTensor1FromMat<9>(dataAtPts->internalStressAtPts);
1233
1234 FTensor::Index<'L', 9> L;
1235 for (int gg = 0; gg != nb_integration_pts; ++gg) {
1236 t_internal_stress(L) = t_const_stress(L);
1237 ++t_internal_stress;
1238 }
1239
1241}
1242
1243template <>
1245 EntityType type,
1246 EntData &data) {
1248
1249 int nb_integration_pts = getGaussPts().size2();
1250
1251 Tag tag;
1252 CHKERR getPtrFE() -> mField.get_moab().tag_get_handle(tagName.c_str(), tag);
1253 int tag_length;
1254 CHKERR getPtrFE() -> mField.get_moab().tag_get_length(tag, tag_length);
1255 if (tag_length != 9) {
1256 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1257 "Number of internal stress components should be 9 but is %d",
1258 tag_length);
1259 }
1260
1261 auto fe_ent = getNumeredEntFiniteElementPtr()->getEnt();
1262 const EntityHandle *vert_conn;
1263 int vert_num;
1264 CHKERR getPtrFE() -> mField.get_moab().get_connectivity(fe_ent, vert_conn,
1265 vert_num, true);
1266 VectorDouble vert_data(vert_num * tag_length);
1267 CHKERR getPtrFE() -> mField.get_moab().tag_get_data(tag, vert_conn, vert_num,
1268 &vert_data[0]);
1269
1270 dataAtPts->internalStressAtPts.resize(tag_length, nb_integration_pts, false);
1271 dataAtPts->internalStressAtPts.clear();
1272 auto t_internal_stress =
1273 getFTensor1FromMat<9>(dataAtPts->internalStressAtPts);
1274
1275 auto t_shape_n = data.getFTensor0N();
1276 int nb_shape_fn = data.getN(NOBASE).size2();
1277 FTensor::Index<'L', 9> L;
1278 for (int gg = 0; gg != nb_integration_pts; ++gg) {
1279 auto t_vert_data = getFTensor1FromArray<9, 9>(vert_data);
1280 for (int bb = 0; bb != nb_shape_fn; ++bb) {
1281 t_internal_stress(L) += t_vert_data(L) * t_shape_n;
1282 ++t_vert_data;
1283 ++t_shape_n;
1284 }
1285 ++t_internal_stress;
1286 }
1287
1289}
1290
1291template <>
1294
1295 int nb_dofs = data.getIndices().size();
1296 int nb_integration_pts = data.getN().size1();
1297 auto v = getVolume();
1298 auto t_w = getFTensor0IntegrationWeight();
1299
1300 FTensor::Index<'i', 3> i;
1301 FTensor::Index<'j', 3> j;
1302
1303 auto get_ftensor2 = [](auto &v) {
1305 &v[0], &v[1], &v[2], &v[3], &v[4], &v[5]);
1306 };
1307
1308 auto t_internal_stress =
1309 getFTensor2FromMat<3, 3>(dataAtPts->internalStressAtPts);
1310
1312 auto t_L = symm_L_tensor();
1313
1314 int nb_base_functions = data.getN().size2();
1315 auto t_row_base_fun = data.getFTensor0N();
1316 for (int gg = 0; gg != nb_integration_pts; ++gg) {
1317 double a = v * t_w;
1318 auto t_nf = get_ftensor2(nF);
1319
1320 FTensor::Tensor2<double, 3, 3> t_symm_stress;
1321 t_symm_stress(i, j) =
1322 (t_internal_stress(i, j) + t_internal_stress(j, i)) / 2;
1323
1325 t_residual(L) = t_L(i, j, L) * t_symm_stress(i, j);
1326
1327 int bb = 0;
1328 for (; bb != nb_dofs / 6; ++bb) {
1329 t_nf(L) += a * t_row_base_fun * t_residual(L);
1330 ++t_nf;
1331 ++t_row_base_fun;
1332 }
1333 for (; bb != nb_base_functions; ++bb)
1334 ++t_row_base_fun;
1335
1336 ++t_w;
1337 ++t_internal_stress;
1338 }
1340}
1341
1342template <>
1345
1346 int nb_dofs = data.getIndices().size();
1347 int nb_integration_pts = data.getN().size1();
1348 auto v = getVolume();
1349 auto t_w = getFTensor0IntegrationWeight();
1350
1351 auto get_ftensor2 = [](auto &v) {
1353 &v[0], &v[1], &v[2], &v[3], &v[4], &v[5]);
1354 };
1355
1356 auto t_internal_stress =
1357 getFTensor1FromMat<9>(dataAtPts->internalStressAtPts);
1358
1360 FTensor::Index<'M', size_symm> M;
1362 t_L = voigt_to_symm();
1363
1364 int nb_base_functions = data.getN().size2();
1365 auto t_row_base_fun = data.getFTensor0N();
1366 for (int gg = 0; gg != nb_integration_pts; ++gg) {
1367 double a = v * t_w;
1368 auto t_nf = get_ftensor2(nF);
1369
1371 t_residual(L) = t_L(M, L) * t_internal_stress(M);
1372
1373 int bb = 0;
1374 for (; bb != nb_dofs / 6; ++bb) {
1375 t_nf(L) += a * t_row_base_fun * t_residual(L);
1376 ++t_nf;
1377 ++t_row_base_fun;
1378 }
1379 for (; bb != nb_base_functions; ++bb)
1380 ++t_row_base_fun;
1381
1382 ++t_w;
1383 ++t_internal_stress;
1384 }
1386}
1387
1388template <AssemblyType A>
1391 // get entity of face
1392 EntityHandle fe_ent = OP::getFEEntityHandle();
1393 // iterate over all boundary data
1394 for (auto &bc : (*bcDispPtr)) {
1395 // check if finite element entity is part of boundary condition
1396 if (bc.faces.find(fe_ent) != bc.faces.end()) {
1397 int nb_dofs = data.getIndices().size();
1398
1399 int nb_integration_pts = OP::getGaussPts().size2();
1400 auto t_normal = OP::getFTensor1NormalsAtGaussPts();
1401 auto t_w = OP::getFTensor0IntegrationWeight();
1402 int nb_base_functions = data.getN().size2() / 3;
1403 auto t_row_base_fun = data.getFTensor1N<3>();
1404
1407
1408 double scale = 1;
1409 if (scalingMethodsMap.find(bc.blockName) != scalingMethodsMap.end()) {
1411 scale *= scalingMethodsMap.at(bc.blockName)
1412 ->getScale(EshelbianCore::dynamicTime);
1413 } else {
1414 scale *= scalingMethodsMap.at(bc.blockName)
1415 ->getScale(OP::getFEMethod()->ts_t);
1416 }
1417 } else {
1418 MOFEM_LOG("SELF", Sev::warning)
1419 << "No scaling method found for " << bc.blockName;
1420 }
1421
1422 // get bc data
1423 FTensor::Tensor1<double, 3> t_bc_disp(bc.vals[0], bc.vals[1], bc.vals[2]);
1424 t_bc_disp(i) *= scale;
1425
1426 for (int gg = 0; gg != nb_integration_pts; ++gg) {
1427 auto t_nf = getFTensor1FromPtr<3>(&*OP::locF.begin());
1428 int bb = 0;
1429 for (; bb != nb_dofs / SPACE_DIM; ++bb) {
1430 t_nf(i) +=
1431 t_w * (t_row_base_fun(j) * t_normal(j)) * t_bc_disp(i) * 0.5;
1432 ++t_nf;
1433 ++t_row_base_fun;
1434 }
1435 for (; bb != nb_base_functions; ++bb)
1436 ++t_row_base_fun;
1437
1438 ++t_w;
1439 ++t_normal;
1440 }
1441 }
1442 }
1444}
1445
1447 return OP::iNtegrate(data);
1448}
1449
1450template <AssemblyType A>
1453
1454 FTENSOR_INDEX(3, i);
1455 FTENSOR_INDEX(3, j);
1456 FTENSOR_INDEX(3, k);
1457
1458 double time = OP::getFEMethod()->ts_t;
1461 }
1462
1463 // get entity of face
1464 EntityHandle fe_ent = OP::getFEEntityHandle();
1465 // interate over all boundary data
1466 for (auto &bc : (*bcRotPtr)) {
1467 // check if finite element entity is part of boundary condition
1468 if (bc.faces.find(fe_ent) != bc.faces.end()) {
1469 int nb_dofs = data.getIndices().size();
1470 int nb_integration_pts = OP::getGaussPts().size2();
1471 auto t_normal = OP::getFTensor1NormalsAtGaussPts();
1472 auto t_w = OP::getFTensor0IntegrationWeight();
1473
1474 int nb_base_functions = data.getN().size2() / 3;
1475 auto t_row_base_fun = data.getFTensor1N<3>();
1476
1477 auto get_ftensor1 = [](auto &v) {
1479 &v[2]);
1480 };
1481
1482 // Note: First three values of bc.vals are the center of rotation
1483 // 4th is rotation angle in radians, and remaining values are axis of
1484 // rotation. Also, if rotation axis is not provided, it defaults to the
1485 // normal vector of the face.
1486
1487 // get bc data
1488 FTensor::Tensor1<double, 3> t_center(bc.vals[0], bc.vals[1], bc.vals[2]);
1489
1490 auto get_rotation_angle = [&]() {
1491 double theta = bc.theta;
1492 if (scalingMethodsMap.find(bc.blockName) != scalingMethodsMap.end()) {
1493 theta *= scalingMethodsMap.at(bc.blockName)->getScale(time);
1494 }
1495 return theta;
1496 };
1497
1498 auto get_rotation = [&](auto theta) {
1500 if (bc.vals.size() == 7) {
1501 t_omega(0) = bc.vals[4];
1502 t_omega(1) = bc.vals[5];
1503 t_omega(2) = bc.vals[6];
1504 } else {
1505 // Use gemetric face normal as rotation axis
1506 t_omega(i) = OP::getFTensor1Normal()(i);
1507 }
1508 t_omega.normalize();
1509 t_omega(i) *= theta;
1512 ? 0.
1513 : t_omega.l2());
1514 };
1515
1516 auto t_R = get_rotation(get_rotation_angle());
1517 auto t_coords = OP::getFTensor1CoordsAtGaussPts();
1518
1519 for (int gg = 0; gg != nb_integration_pts; ++gg) {
1521 t_delta(i) = t_center(i) - t_coords(i);
1523 t_disp(i) = t_delta(i) - t_R(i, j) * t_delta(j);
1524
1525 auto t_nf = getFTensor1FromPtr<3>(&*OP::locF.begin());
1526 int bb = 0;
1527 for (; bb != nb_dofs / 3; ++bb) {
1528 t_nf(i) += t_w * (t_row_base_fun(j) * t_normal(j)) * t_disp(i) * 0.5;
1529 ++t_nf;
1530 ++t_row_base_fun;
1531 }
1532 for (; bb != nb_base_functions; ++bb)
1533 ++t_row_base_fun;
1534
1535 ++t_w;
1536 ++t_normal;
1537 ++t_coords;
1538 }
1539 }
1540 }
1542}
1543
1545 return OP::iNtegrate(data);
1546}
1547
1548template <AssemblyType A>
1551
1552 double time = OP::getFEMethod()->ts_t;
1555 }
1556
1557 // get entity of face
1558 EntityHandle fe_ent = OP::getFEEntityHandle();
1559 // iterate over all boundary data
1560 for (auto &bc : (*bcDispPtr)) {
1561 // check if finite element entity is part of boundary condition
1562 if (bc.faces.find(fe_ent) != bc.faces.end()) {
1563
1564 for (auto &bd : (*brokenBaseSideDataPtr)) {
1565
1566 auto t_approx_P = getFTensor2FromMat<3, 3>(bd.getFlux());
1567 auto t_u = getFTensor1FromMat<3>(*hybridDispPtr);
1568 auto t_normal = OP::getFTensor1NormalsAtGaussPts();
1569 auto t_w = OP::getFTensor0IntegrationWeight();
1570
1573
1575
1576 double scale = 1;
1577 if (scalingMethodsMap.find(bc.blockName) != scalingMethodsMap.end()) {
1578 scale *= scalingMethodsMap.at(bc.blockName)->getScale(time);
1579 } else {
1580 MOFEM_LOG("SELF", Sev::warning)
1581 << "No scaling method found for " << bc.blockName;
1582 }
1583
1584 // get bc data
1585 double val = scale * bc.val;
1586
1587 int nb_dofs = data.getIndices().size();
1588 int nb_integration_pts = OP::getGaussPts().size2();
1589 int nb_base_functions = data.getN().size2();
1590 auto t_row_base = data.getFTensor0N();
1591 for (int gg = 0; gg != nb_integration_pts; ++gg) {
1592
1594 t_N(i) = t_normal(i);
1595 t_N.normalize();
1596
1598 t_P(i, j) = t_N(i) * t_N(j);
1600 t_Q(i, j) = t_kd(i, j) - t_P(i, j);
1601
1602 FTensor::Tensor1<double, 3> t_traction;
1603 t_traction(i) = t_approx_P(i, j) * t_N(j);
1604
1606 t_res(i) =
1607 t_Q(i, j) * t_traction(j) + t_P(i, j) * 2 * t_u(j) - t_N(i) * val;
1608
1609 auto t_nf = getFTensor1FromPtr<3>(&*OP::locF.begin());
1610 int bb = 0;
1611 for (; bb != nb_dofs / SPACE_DIM; ++bb) {
1612 t_nf(i) += (t_w * t_row_base * OP::getMeasure()) * t_res(i);
1613 ++t_nf;
1614 ++t_row_base;
1615 }
1616 for (; bb != nb_base_functions; ++bb)
1617 ++t_row_base;
1618
1619 ++t_w;
1620 ++t_normal;
1621 ++t_u;
1622 ++t_approx_P;
1623 }
1624 }
1625 }
1626 }
1628}
1629
1630template <AssemblyType A>
1633 EntData &col_data) {
1635
1636 double time = OP::getFEMethod()->ts_t;
1639 }
1640
1641 int row_nb_dofs = row_data.getIndices().size();
1642 int col_nb_dofs = col_data.getIndices().size();
1643 auto &locMat = OP::locMat;
1644 locMat.resize(row_nb_dofs, col_nb_dofs, false);
1645 locMat.clear();
1646
1647 // get entity of face
1648 EntityHandle fe_ent = OP::getFEEntityHandle();
1649 // iterate over all boundary data
1650 for (auto &bc : (*bcDispPtr)) {
1651 // check if finite element entity is part of boundary condition
1652 if (bc.faces.find(fe_ent) != bc.faces.end()) {
1653
1654 auto t_normal = OP::getFTensor1NormalsAtGaussPts();
1655 auto t_w = OP::getFTensor0IntegrationWeight();
1656
1659
1660 double scale = 1;
1661 if (scalingMethodsMap.find(bc.blockName) != scalingMethodsMap.end()) {
1662 scale *= scalingMethodsMap.at(bc.blockName)->getScale(time);
1663 } else {
1664 MOFEM_LOG("SELF", Sev::warning)
1665 << "No scaling method found for " << bc.blockName;
1666 }
1667
1668 int nb_integration_pts = OP::getGaussPts().size2();
1669 int row_nb_dofs = row_data.getIndices().size();
1670 int col_nb_dofs = col_data.getIndices().size();
1671 int nb_base_functions = row_data.getN().size2();
1672 auto t_row_base = row_data.getFTensor0N();
1673
1675
1676 for (int gg = 0; gg != nb_integration_pts; ++gg) {
1677
1679 t_N(i) = t_normal(i);
1680 t_N.normalize();
1681
1683 t_P(i, j) = t_N(i) * t_N(j);
1684
1686 t_d_res(i, j) = 2.0 * t_P(i, j);
1687
1688 int rr = 0;
1689 for (; rr != row_nb_dofs / SPACE_DIM; ++rr) {
1690 auto t_mat = getFTensor2FromArray<SPACE_DIM, SPACE_DIM, SPACE_DIM>(
1691 locMat, SPACE_DIM * rr);
1692 auto t_col_base = col_data.getFTensor0N(gg, 0);
1693 for (auto cc = 0; cc != col_nb_dofs / SPACE_DIM; ++cc) {
1694 t_mat(i, j) += (t_w * t_row_base * t_col_base) * t_d_res(i, j);
1695 ++t_mat;
1696 ++t_col_base;
1697 }
1698 ++t_row_base;
1699 }
1700
1701 for (; rr != nb_base_functions; ++rr)
1702 ++t_row_base;
1703
1704 ++t_w;
1705 ++t_normal;
1706 }
1707
1708 locMat *= OP::getMeasure();
1709
1710 }
1711 }
1713}
1714
1715template <AssemblyType A>
1718 EntData &col_data) {
1720
1721 double time = OP::getFEMethod()->ts_t;
1724 }
1725
1726 int row_nb_dofs = row_data.getIndices().size();
1727 int col_nb_dofs = col_data.getIndices().size();
1728 auto &locMat = OP::locMat;
1729 locMat.resize(row_nb_dofs, col_nb_dofs, false);
1730 locMat.clear();
1731
1732 // get entity of face
1733 EntityHandle fe_ent = OP::getFEEntityHandle();
1734 // iterate over all boundary data
1735 for (auto &bc : (*bcDispPtr)) {
1736 // check if finite element entity is part of boundary condition
1737 if (bc.faces.find(fe_ent) != bc.faces.end()) {
1738
1739 auto t_normal = OP::getFTensor1NormalsAtGaussPts();
1740 auto t_w = OP::getFTensor0IntegrationWeight();
1741
1745
1747
1748 double scale = 1;
1749 if (scalingMethodsMap.find(bc.blockName) != scalingMethodsMap.end()) {
1750 scale *= scalingMethodsMap.at(bc.blockName)->getScale(time);
1751 } else {
1752 MOFEM_LOG("SELF", Sev::warning)
1753 << "No scaling method found for " << bc.blockName;
1754 }
1755
1756 int nb_integration_pts = OP::getGaussPts().size2();
1757 int nb_base_functions = row_data.getN().size2();
1758 auto t_row_base = row_data.getFTensor0N();
1759
1760 for (int gg = 0; gg != nb_integration_pts; ++gg) {
1761
1763 t_N(i) = t_normal(i);
1764 t_N.normalize();
1765
1767 t_P(i, j) = t_N(i) * t_N(j);
1769 t_Q(i, j) = t_kd(i, j) - t_P(i, j);
1770
1772 t_d_res(i, j) = t_Q(i, j);
1773
1774 int rr = 0;
1775 for (; rr != row_nb_dofs / SPACE_DIM; ++rr) {
1776 auto t_mat = getFTensor2FromArray<SPACE_DIM, SPACE_DIM, SPACE_DIM>(
1777 OP::locMat, SPACE_DIM * rr);
1778 auto t_col_base = col_data.getFTensor1N<3>(gg, 0);
1779 for (auto cc = 0; cc != col_nb_dofs / SPACE_DIM; ++cc) {
1780 t_mat(i, j) +=
1781 ((t_w * t_row_base) * (t_N(k) * t_col_base(k))) * t_d_res(i, j);
1782 ++t_mat;
1783 ++t_col_base;
1784 }
1785 ++t_row_base;
1786 }
1787
1788 for (; rr != nb_base_functions; ++rr)
1789 ++t_row_base;
1790
1791 ++t_w;
1792 ++t_normal;
1793 }
1794
1795 locMat *= OP::getMeasure();
1796 }
1797 }
1799}
1800
1802 return OP::iNtegrate(data);
1803}
1804
1806 EntData &col_data) {
1807 return OP::iNtegrate(row_data, col_data);
1808}
1809
1811 EntData &col_data) {
1812 return OP::iNtegrate(row_data, col_data);
1813}
1814
1815template <AssemblyType A>
1818
1819 double time = OP::getFEMethod()->ts_t;
1822 }
1823
1824 // get entity of face
1825 EntityHandle fe_ent = OP::getFEEntityHandle();
1826 // iterate over all boundary data
1827 for (auto &bc : (*bcDispPtr)) {
1828 // check if finite element entity is part of boundary condition
1829 if (bc.faces.find(fe_ent) != bc.faces.end()) {
1830
1831 MatrixDouble analytical_expr;
1832 // placeholder to pass boundary block id to python
1833
1834 auto [block_name, v_analytical_expr] =
1835 getAnalyticalExpr(this, analytical_expr, bc.blockName);
1836
1837 int nb_dofs = data.getIndices().size();
1838
1839 int nb_integration_pts = OP::getGaussPts().size2();
1840 auto t_normal = OP::getFTensor1NormalsAtGaussPts();
1841 auto t_w = OP::getFTensor0IntegrationWeight();
1842 int nb_base_functions = data.getN().size2() / 3;
1843 auto t_row_base_fun = data.getFTensor1N<3>();
1844 auto t_coord = OP::getFTensor1CoordsAtGaussPts();
1845
1848
1849 // get bc data
1850 auto t_bc_disp = getFTensor1FromMat<3>(v_analytical_expr);
1851
1852 for (int gg = 0; gg != nb_integration_pts; ++gg) {
1853 auto t_nf = getFTensor1FromPtr<3>(&*OP::locF.begin());
1854
1855 int bb = 0;
1856 for (; bb != nb_dofs / SPACE_DIM; ++bb) {
1857 t_nf(i) +=
1858 t_w * (t_row_base_fun(j) * t_normal(j)) * t_bc_disp(i) * 0.5;
1859 ++t_nf;
1860 ++t_row_base_fun;
1861 }
1862 for (; bb != nb_base_functions; ++bb)
1863 ++t_row_base_fun;
1864
1865 ++t_bc_disp;
1866 ++t_coord;
1867 ++t_w;
1868 ++t_normal;
1869 }
1870 }
1871 }
1873}
1874
1876 return OP::iNtegrate(data);
1877}
1878
1881
1882 FTENSOR_INDEX(3, i);
1883
1884 int nb_dofs = data.getFieldData().size();
1885 int nb_integration_pts = getGaussPts().size2();
1886 int nb_base_functions = data.getN().size2();
1887
1888 double time = getFEMethod()->ts_t;
1891 }
1892
1893#ifndef NDEBUG
1894 if (this->locF.size() != nb_dofs)
1895 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1896 "Size of locF %ld != nb_dofs %d", this->locF.size(), nb_dofs);
1897#endif // NDEBUG
1898
1899 auto integrate_rhs = [&](auto &bc, auto calc_tau, double time_scale) {
1901
1902 auto t_val = getFTensor1FromPtr<3>(&*bc.vals.begin());
1903 auto t_row_base = data.getFTensor0N();
1904 auto t_w = getFTensor0IntegrationWeight();
1905 auto t_coords = getFTensor1CoordsAtGaussPts();
1906
1907 double scale = (piolaScalePtr) ? 1. / (*piolaScalePtr) : 1.0;
1908
1909 for (int gg = 0; gg != nb_integration_pts; ++gg) {
1910
1911 const auto tau = calc_tau(t_coords(0), t_coords(1), t_coords(2));
1912 auto t_f = getFTensor1FromPtr<3>(&*this->locF.begin());
1913 int rr = 0;
1914 for (; rr != nb_dofs / SPACE_DIM; ++rr) {
1915 t_f(i) -= (time_scale * t_w * t_row_base * tau) * (t_val(i) * scale);
1916 ++t_row_base;
1917 ++t_f;
1918 }
1919
1920 for (; rr != nb_base_functions; ++rr)
1921 ++t_row_base;
1922 ++t_w;
1923 ++t_coords;
1924 }
1925 this->locF *= getMeasure();
1927 };
1928
1929 // get entity of face
1930 EntityHandle fe_ent = getFEEntityHandle();
1931 for (auto &bc : *(bcData)) {
1932 if (bc.faces.find(fe_ent) != bc.faces.end()) {
1933
1934 double time_scale = 1;
1935 if (scalingMethodsMap.find(bc.blockName) != scalingMethodsMap.end()) {
1936 time_scale *= scalingMethodsMap.at(bc.blockName)->getScale(time);
1937 }
1938
1939 int nb_dofs = data.getFieldData().size();
1940 if (nb_dofs) {
1941
1942 if (std::regex_match(bc.blockName, std::regex(".*COOK.*"))) {
1943 auto calc_tau = [](double, double y, double) {
1944 y -= 44;
1945 y /= (60 - 44);
1946 return -y * (y - 1) / 0.25;
1947 };
1948 CHKERR integrate_rhs(bc, calc_tau, time_scale);
1949 } else {
1950 CHKERR integrate_rhs(
1951 bc, [](double, double, double) { return 1; }, time_scale);
1952 }
1953 }
1954 }
1955 }
1957}
1958
1961
1962 FTENSOR_INDEX(3, i);
1963
1964 int nb_dofs = data.getFieldData().size();
1965 int nb_integration_pts = getGaussPts().size2();
1966 int nb_base_functions = data.getN().size2();
1967
1968 double time = getFEMethod()->ts_t;
1971 }
1972
1973#ifndef NDEBUG
1974 if (this->locF.size() != nb_dofs)
1975 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1976 "Size of locF %ld != nb_dofs %d", this->locF.size(), nb_dofs);
1977#endif // NDEBUG
1978
1979 auto integrate_rhs = [&](auto &bc, auto calc_tau, double time_scale) {
1981
1982 auto val = bc.val;
1983 auto t_row_base = data.getFTensor0N();
1984 auto t_w = getFTensor0IntegrationWeight();
1985 auto t_coords = getFTensor1CoordsAtGaussPts();
1986 auto t_tangent1 = getFTensor1Tangent1AtGaussPts();
1987 auto t_tangent2 = getFTensor1Tangent2AtGaussPts();
1988
1989 auto t_grad_gamma_u = getFTensor2FromMat<3, 2>(*hybridGradDispPtr);
1990
1991 double scale = (piolaScalePtr) ? 1. / (*piolaScalePtr) : 1.0;
1992
1993 for (int gg = 0; gg != nb_integration_pts; ++gg) {
1994
2000
2004
2005 t_normal(i) = (FTensor::levi_civita<double>(i, j, k) * t_tangent1(j)) *
2006 t_tangent2(k);
2007 } else {
2008 t_normal(i) = (FTensor::levi_civita<double>(i, j, k) *
2009 (t_tangent1(j) + t_grad_gamma_u(j, N0))) *
2010 (t_tangent2(k) + t_grad_gamma_u(k, N1));
2011 }
2012 auto tau = calc_tau(t_coords(0), t_coords(1), t_coords(2));
2013 auto t_val = FTensor::Tensor1<double, 3>();
2014 t_val(i) = (time_scale * t_w * tau * scale * val) * t_normal(i);
2015
2016 auto t_f = getFTensor1FromPtr<3>(&*this->locF.begin());
2017 int rr = 0;
2018 for (; rr != nb_dofs / SPACE_DIM; ++rr) {
2019 t_f(i) += t_row_base * t_val(i);
2020 ++t_row_base;
2021 ++t_f;
2022 }
2023
2024 for (; rr != nb_base_functions; ++rr)
2025 ++t_row_base;
2026 ++t_w;
2027 ++t_coords;
2028 ++t_tangent1;
2029 ++t_tangent2;
2030 ++t_grad_gamma_u;
2031 }
2032 this->locF /= 2.;
2033
2035 };
2036
2037 // get entity of face
2038 EntityHandle fe_ent = getFEEntityHandle();
2039 for (auto &bc : *(bcData)) {
2040 if (bc.faces.find(fe_ent) != bc.faces.end()) {
2041
2042 double time_scale = 1;
2043 if (scalingMethodsMap.find(bc.blockName) != scalingMethodsMap.end()) {
2044 time_scale *= scalingMethodsMap.at(bc.blockName)->getScale(time);
2045 }
2046
2047 int nb_dofs = data.getFieldData().size();
2048 if (nb_dofs) {
2049 CHKERR integrate_rhs(
2050 bc, [](double, double, double) { return 1; }, time_scale);
2051 }
2052 }
2053 }
2055}
2056
2057template <AssemblyType A>
2060 EntData &col_data) {
2062
2066 }
2067
2068 double time = OP::getFEMethod()->ts_t;
2071 }
2072
2073 int nb_base_functions = row_data.getN().size2();
2074 int row_nb_dofs = row_data.getIndices().size();
2075 int col_nb_dofs = col_data.getIndices().size();
2076 int nb_integration_pts = OP::getGaussPts().size2();
2077 auto &locMat = OP::locMat;
2078 locMat.resize(row_nb_dofs, col_nb_dofs, false);
2079 locMat.clear();
2080
2081auto integrate_lhs = [&](auto &bc, auto calc_tau, double time_scale) {
2083
2084 auto val = bc.val;
2085 auto t_row_base = row_data.getFTensor0N();
2086 auto t_w = OP::getFTensor0IntegrationWeight();
2087 auto t_coords = OP::getFTensor1CoordsAtGaussPts();
2088 auto t_tangent1 = OP::getFTensor1Tangent1AtGaussPts();
2089 auto t_tangent2 = OP::getFTensor1Tangent2AtGaussPts();
2090
2091 auto t_grad_gamma_u = getFTensor2FromMat<3, 2>(*hybridGradDispPtr);
2093
2094 for (int gg = 0; gg != nb_integration_pts; ++gg) {
2095
2100
2103
2104 auto tau = calc_tau(t_coords(0), t_coords(1), t_coords(2));
2105 auto t_val = time_scale * t_w * tau * val;
2106
2107 int rr = 0;
2108 for (; rr != row_nb_dofs / SPACE_DIM; ++rr) {
2109 auto t_mat = getFTensor2FromArray<SPACE_DIM, SPACE_DIM, SPACE_DIM>(
2110 locMat, SPACE_DIM * rr);
2111 auto t_diff_col_base = col_data.getFTensor1DiffN<2>(gg, 0);
2112 for (auto cc = 0; cc != col_nb_dofs / SPACE_DIM; ++cc) {
2114 t_normal_du(i, l) = (FTensor::levi_civita<double>(i, j, k) *
2115 (t_tangent2(k) + t_grad_gamma_u(k, N1))) *
2116 t_kd(j, l) * t_diff_col_base(N0)
2117
2118 +
2119
2120 (FTensor::levi_civita<double>(i, j, k) *
2121 (t_tangent1(j) + t_grad_gamma_u(j, N0))) *
2122 t_kd(k, l) * t_diff_col_base(N1);
2123
2124 t_mat(i, j) += (t_w * t_row_base) * t_val * t_normal_du(i, j);
2125 ++t_mat;
2126 ++t_diff_col_base;
2127 }
2128 ++t_row_base;
2129 }
2130
2131 for (; rr != nb_base_functions; ++rr)
2132 ++t_row_base;
2133 ++t_w;
2134 ++t_coords;
2135 ++t_tangent1;
2136 ++t_tangent2;
2137 ++t_grad_gamma_u;
2138 }
2139
2140 OP::locMat /= 2.;
2141
2143 };
2144
2145 // get entity of face
2146 EntityHandle fe_ent = OP::getFEEntityHandle();
2147 for (auto &bc : *(bcData)) {
2148 if (bc.faces.find(fe_ent) != bc.faces.end()) {
2149
2150 double time_scale = 1;
2151 if (scalingMethodsMap.find(bc.blockName) != scalingMethodsMap.end()) {
2152 time_scale *= scalingMethodsMap.at(bc.blockName)->getScale(time);
2153 }
2154
2155 int nb_dofs = row_data.getFieldData().size();
2156 if (nb_dofs) {
2157 CHKERR integrate_lhs(
2158 bc, [](double, double, double) { return 1; }, time_scale);
2159 }
2160 }
2161 }
2162
2164
2165}
2166
2168 EntData &col_data) {
2169 return OP::iNtegrate(row_data, col_data);
2170}
2171
2172
2175
2176 FTENSOR_INDEX(3, i);
2177
2178 int nb_dofs = data.getFieldData().size();
2179 int nb_integration_pts = getGaussPts().size2();
2180 int nb_base_functions = data.getN().size2();
2181
2182 double time = getFEMethod()->ts_t;
2185 }
2186
2187#ifndef NDEBUG
2188 if (this->locF.size() != nb_dofs)
2189 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
2190 "Size of locF %ld != nb_dofs %d", this->locF.size(), nb_dofs);
2191#endif // NDEBUG
2192
2193 // get entity of face
2194 EntityHandle fe_ent = getFEEntityHandle();
2195 for (auto &bc : *(bcData)) {
2196 if (bc.faces.find(fe_ent) != bc.faces.end()) {
2197
2198 MatrixDouble analytical_expr;
2199 // placeholder to pass boundary block id to python
2200 auto [block_name, v_analytical_expr] =
2201 getAnalyticalExpr(this, analytical_expr, bc.blockName);
2202 auto t_val =
2203 getFTensor1FromMat<3>(v_analytical_expr);
2204 auto t_row_base = data.getFTensor0N();
2205 auto t_w = getFTensor0IntegrationWeight();
2206 auto t_coords = getFTensor1CoordsAtGaussPts();
2207
2208 double scale = (piolaScalePtr) ? 1. / (*piolaScalePtr) : 1.0;
2209
2210 for (int gg = 0; gg != nb_integration_pts; ++gg) {
2211
2212 auto t_f = getFTensor1FromPtr<3>(&*this->locF.begin());
2213 int rr = 0;
2214 for (; rr != nb_dofs / SPACE_DIM; ++rr) {
2215 t_f(i) -= t_w * t_row_base * (t_val(i) * scale);
2216 ++t_row_base;
2217 ++t_f;
2218 }
2219
2220 for (; rr != nb_base_functions; ++rr)
2221 ++t_row_base;
2222 ++t_w;
2223 ++t_coords;
2224 ++t_val;
2225 }
2226 this->locF *= getMeasure();
2227 }
2228 }
2230}
2231
2233 EntData &col_data) {
2235 int nb_integration_pts = row_data.getN().size1();
2236 int row_nb_dofs = row_data.getIndices().size();
2237 int col_nb_dofs = col_data.getIndices().size();
2238 auto get_ftensor1 = [](MatrixDouble &m, const int r, const int c) {
2240 &m(r + 0, c + 0), &m(r + 1, c + 1), &m(r + 2, c + 2));
2241 };
2242 FTensor::Index<'i', 3> i;
2243 auto v = getVolume();
2244 auto t_w = getFTensor0IntegrationWeight();
2245 int row_nb_base_functions = row_data.getN().size2();
2246 auto t_row_base_fun = row_data.getFTensor0N();
2247 for (int gg = 0; gg != nb_integration_pts; ++gg) {
2248 double a = v * t_w;
2249 int rr = 0;
2250 for (; rr != row_nb_dofs / 3; ++rr) {
2251 auto t_col_diff_base_fun = col_data.getFTensor2DiffN<3, 3>(gg, 0);
2252 auto t_m = get_ftensor1(K, 3 * rr, 0);
2253 for (int cc = 0; cc != col_nb_dofs / 3; ++cc) {
2254 double div_col_base = t_col_diff_base_fun(i, i);
2255 t_m(i) -= a * t_row_base_fun * div_col_base;
2256 ++t_m;
2257 ++t_col_diff_base_fun;
2258 }
2259 ++t_row_base_fun;
2260 }
2261 for (; rr != row_nb_base_functions; ++rr)
2262 ++t_row_base_fun;
2263 ++t_w;
2264 }
2266}
2267
2269 EntData &col_data) {
2271
2272 if (alphaW < std::numeric_limits<double>::epsilon() &&
2273 alphaRho < std::numeric_limits<double>::epsilon())
2275
2276 const int nb_integration_pts = row_data.getN().size1();
2277 const int row_nb_dofs = row_data.getIndices().size();
2278 auto get_ftensor1 = [](MatrixDouble &m, const int r, const int c) {
2280 &m(r + 0, c + 0), &m(r + 1, c + 1), &m(r + 2, c + 2)
2281
2282 );
2283 };
2284 FTensor::Index<'i', 3> i;
2285
2286 auto v = getVolume();
2287 auto t_w = getFTensor0IntegrationWeight();
2288
2289 auto piola_scale = dataAtPts->piolaScale;
2290 auto alpha_w = alphaW / piola_scale;
2291 auto alpha_rho = alphaRho / piola_scale;
2292
2293 int row_nb_base_functions = row_data.getN().size2();
2294 auto t_row_base_fun = row_data.getFTensor0N();
2295
2296 double ts_scale = alpha_w * getTSa();
2297 if (std::abs(alphaRho) > std::numeric_limits<double>::epsilon())
2298 ts_scale += alpha_rho * getTSaa();
2299
2300 for (int gg = 0; gg != nb_integration_pts; ++gg) {
2301 double a = v * t_w * ts_scale;
2302
2303 int rr = 0;
2304 for (; rr != row_nb_dofs / 3; ++rr) {
2305
2306 auto t_col_base_fun = row_data.getFTensor0N(gg, 0);
2307 auto t_m = get_ftensor1(K, 3 * rr, 0);
2308 for (int cc = 0; cc != row_nb_dofs / 3; ++cc) {
2309 const double b = a * t_row_base_fun * t_col_base_fun;
2310 t_m(i) += b;
2311 ++t_m;
2312 ++t_col_base_fun;
2313 }
2314
2315 ++t_row_base_fun;
2316 }
2317
2318 for (; rr != row_nb_base_functions; ++rr)
2319 ++t_row_base_fun;
2320
2321 ++t_w;
2322 }
2323
2325}
2326
2328 EntData &col_data) {
2330
2336
2337 int nb_integration_pts = row_data.getN().size1();
2338 int row_nb_dofs = row_data.getIndices().size();
2339 int col_nb_dofs = col_data.getIndices().size();
2340 auto get_ftensor3 = [](MatrixDouble &m, const int r, const int c) {
2342
2343 &m(r + 0, c + 0), &m(r + 0, c + 1), &m(r + 0, c + 2),
2344
2345 &m(r + 1, c + 0), &m(r + 1, c + 1), &m(r + 1, c + 2),
2346
2347 &m(r + 2, c + 0), &m(r + 2, c + 1), &m(r + 2, c + 2),
2348
2349 &m(r + 3, c + 0), &m(r + 3, c + 1), &m(r + 3, c + 2),
2350
2351 &m(r + 4, c + 0), &m(r + 4, c + 1), &m(r + 4, c + 2),
2352
2353 &m(r + 5, c + 0), &m(r + 5, c + 1), &m(r + 5, c + 2));
2354 };
2355
2356 auto v = getVolume();
2357 auto t_w = getFTensor0IntegrationWeight();
2358
2359 int row_nb_base_functions = row_data.getN().size2();
2360 auto t_row_base_fun = row_data.getFTensor0N();
2361
2362 auto t_approx_P_adjoint_log_du_dP =
2363 getFTensor3FromMat<3, 3, size_symm>(dataAtPts->adjointPdUdPAtPts);
2364
2365 for (int gg = 0; gg != nb_integration_pts; ++gg) {
2366 double a = v * t_w;
2367 int rr = 0;
2368 for (; rr != row_nb_dofs / 6; ++rr) {
2369
2370 auto t_col_base_fun = col_data.getFTensor1N<3>(gg, 0);
2371 auto t_m = get_ftensor3(K, 6 * rr, 0);
2372
2373 for (int cc = 0; cc != col_nb_dofs / 3; ++cc) {
2374 t_m(L, i) -=
2375 a * (t_approx_P_adjoint_log_du_dP(i, j, L) * t_col_base_fun(j)) *
2376 t_row_base_fun;
2377 ++t_col_base_fun;
2378 ++t_m;
2379 }
2380
2381 ++t_row_base_fun;
2382 }
2383 for (; rr != row_nb_base_functions; ++rr)
2384 ++t_row_base_fun;
2385 ++t_w;
2386 ++t_approx_P_adjoint_log_du_dP;
2387 }
2388
2390}
2391
2393 EntData &col_data) {
2395
2401
2402 int nb_integration_pts = row_data.getN().size1();
2403 int row_nb_dofs = row_data.getIndices().size();
2404 int col_nb_dofs = col_data.getIndices().size();
2405 auto get_ftensor2 = [](MatrixDouble &m, const int r, const int c) {
2407 &m(r + 0, c), &m(r + 1, c), &m(r + 2, c), &m(r + 3, c), &m(r + 4, c),
2408 &m(r + 5, c));
2409 };
2410
2411 auto v = getVolume();
2412 auto t_w = getFTensor0IntegrationWeight();
2413 auto t_row_base_fun = row_data.getFTensor0N();
2414
2415 int row_nb_base_functions = row_data.getN().size2();
2416
2417 auto t_approx_P_adjoint_log_du_dP =
2418 getFTensor3FromMat<3, 3, size_symm>(dataAtPts->adjointPdUdPAtPts);
2419
2420 for (int gg = 0; gg != nb_integration_pts; ++gg) {
2421 double a = v * t_w;
2422 int rr = 0;
2423 for (; rr != row_nb_dofs / 6; ++rr) {
2424 auto t_m = get_ftensor2(K, 6 * rr, 0);
2425 auto t_col_base_fun = col_data.getFTensor2N<3, 3>(gg, 0);
2426 for (int cc = 0; cc != col_nb_dofs; ++cc) {
2427 t_m(L) -=
2428 a * (t_approx_P_adjoint_log_du_dP(i, j, L) * t_col_base_fun(i, j)) *
2429 t_row_base_fun;
2430 ++t_m;
2431 ++t_col_base_fun;
2432 }
2433 ++t_row_base_fun;
2434 }
2435 for (; rr != row_nb_base_functions; ++rr)
2436 ++t_row_base_fun;
2437 ++t_w;
2438 ++t_approx_P_adjoint_log_du_dP;
2439 }
2441}
2442
2444 EntData &col_data) {
2446
2448 auto t_L = symm_L_tensor();
2449
2450 int row_nb_dofs = row_data.getIndices().size();
2451 int col_nb_dofs = col_data.getIndices().size();
2452 auto get_ftensor3 = [](MatrixDouble &m, const int r, const int c) {
2454
2455 &m(r + 0, c + 0), &m(r + 0, c + 1), &m(r + 0, c + 2),
2456
2457 &m(r + 1, c + 0), &m(r + 1, c + 1), &m(r + 1, c + 2),
2458
2459 &m(r + 2, c + 0), &m(r + 2, c + 1), &m(r + 2, c + 2),
2460
2461 &m(r + 3, c + 0), &m(r + 3, c + 1), &m(r + 3, c + 2),
2462
2463 &m(r + 4, c + 0), &m(r + 4, c + 1), &m(r + 4, c + 2),
2464
2465 &m(r + 5, c + 0), &m(r + 5, c + 1), &m(r + 5, c + 2)
2466
2467 );
2468 };
2469 FTensor::Index<'i', 3> i;
2470 FTensor::Index<'j', 3> j;
2471 FTensor::Index<'k', 3> k;
2472 FTensor::Index<'m', 3> m;
2473 FTensor::Index<'n', 3> n;
2474
2475 auto v = getVolume();
2476 auto t_w = getFTensor0IntegrationWeight();
2477 auto t_approx_P_adjoint_log_du_domega =
2478 getFTensor2FromMat<3, size_symm>(dataAtPts->adjointPdUdOmegaAtPts);
2479
2480 int row_nb_base_functions = row_data.getN().size2();
2481 auto t_row_base_fun = row_data.getFTensor0N();
2482
2483 int nb_integration_pts = row_data.getN().size1();
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 / 6; ++rr) {
2490 auto t_col_base_fun = col_data.getFTensor0N(gg, 0);
2491 auto t_m = get_ftensor3(K, 6 * rr, 0);
2492 for (int cc = 0; cc != col_nb_dofs / 3; ++cc) {
2493 double v = a * t_row_base_fun * t_col_base_fun;
2494 t_m(L, k) -= v * t_approx_P_adjoint_log_du_domega(k, L);
2495 ++t_m;
2496 ++t_col_base_fun;
2497 }
2498 ++t_row_base_fun;
2499 }
2500
2501 for (; rr != row_nb_base_functions; ++rr)
2502 ++t_row_base_fun;
2503
2504 ++t_w;
2505 ++t_approx_P_adjoint_log_du_domega;
2506 }
2507
2509}
2510
2512 EntData &col_data) {
2514 int nb_integration_pts = getGaussPts().size2();
2515 int row_nb_dofs = row_data.getIndices().size();
2516 int col_nb_dofs = col_data.getIndices().size();
2517 auto get_ftensor2 = [](MatrixDouble &m, const int r, const int c) {
2519 size_symm>{
2520
2521 &m(r + 0, c + 0), &m(r + 0, c + 1), &m(r + 0, c + 2), &m(r + 0, c + 3),
2522 &m(r + 0, c + 4), &m(r + 0, c + 5),
2523
2524 &m(r + 1, c + 0), &m(r + 1, c + 1), &m(r + 1, c + 2), &m(r + 1, c + 3),
2525 &m(r + 1, c + 4), &m(r + 1, c + 5),
2526
2527 &m(r + 2, c + 0), &m(r + 2, c + 1), &m(r + 2, c + 2), &m(r + 2, c + 3),
2528 &m(r + 2, c + 4), &m(r + 2, c + 5)
2529
2530 };
2531 };
2532
2535
2536 auto v = getVolume();
2537 auto t_w = getFTensor0IntegrationWeight();
2538 auto t_levi_kirchhoff_du = getFTensor2FromMat<3, size_symm>(
2539 dataAtPts->leviKirchhoffdLogStreatchAtPts);
2540 int row_nb_base_functions = row_data.getN().size2();
2541 auto t_row_base_fun = row_data.getFTensor0N();
2542 for (int gg = 0; gg != nb_integration_pts; ++gg) {
2543 double a = v * t_w;
2544 int rr = 0;
2545 for (; rr != row_nb_dofs / 3; ++rr) {
2546 auto t_m = get_ftensor2(K, 3 * rr, 0);
2547 const double b = a * t_row_base_fun;
2548 auto t_col_base_fun = col_data.getFTensor0N(gg, 0);
2549 for (int cc = 0; cc != col_nb_dofs / size_symm; ++cc) {
2550 t_m(k, L) -= (b * t_col_base_fun) * t_levi_kirchhoff_du(k, L);
2551 ++t_m;
2552 ++t_col_base_fun;
2553 }
2554 ++t_row_base_fun;
2555 }
2556 for (; rr != row_nb_base_functions; ++rr) {
2557 ++t_row_base_fun;
2558 }
2559 ++t_w;
2560 ++t_levi_kirchhoff_du;
2561 }
2563}
2564
2566 EntData &col_data) {
2568
2575
2576 int nb_integration_pts = getGaussPts().size2();
2577 int row_nb_dofs = row_data.getIndices().size();
2578 int col_nb_dofs = col_data.getIndices().size();
2579 auto get_ftensor2 = [](MatrixDouble &m, const int r, const int c) {
2581
2582 &m(r + 0, c + 0), &m(r + 0, c + 1), &m(r + 0, c + 2),
2583
2584 &m(r + 1, c + 0), &m(r + 1, c + 1), &m(r + 1, c + 2),
2585
2586 &m(r + 2, c + 0), &m(r + 2, c + 1), &m(r + 2, c + 2)
2587
2588 );
2589 };
2590
2591 auto v = getVolume();
2592 auto t_w = getFTensor0IntegrationWeight();
2593
2594 int row_nb_base_functions = row_data.getN().size2();
2595 auto t_row_base_fun = row_data.getFTensor0N();
2596 auto t_levi_kirchhoff_dP =
2597 getFTensor3FromMat<3, 3, 3>(dataAtPts->leviKirchhoffPAtPts);
2598
2599 for (int gg = 0; gg != nb_integration_pts; ++gg) {
2600 double a = v * t_w;
2601 int rr = 0;
2602 for (; rr != row_nb_dofs / 3; ++rr) {
2603 double b = a * t_row_base_fun;
2604 auto t_col_base_fun = col_data.getFTensor1N<3>(gg, 0);
2605 auto t_m = get_ftensor2(K, 3 * rr, 0);
2606 for (int cc = 0; cc != col_nb_dofs / 3; ++cc) {
2607 t_m(m, i) -= b * (t_levi_kirchhoff_dP(m, i, k) * t_col_base_fun(k));
2608 ++t_m;
2609 ++t_col_base_fun;
2610 }
2611 ++t_row_base_fun;
2612 }
2613 for (; rr != row_nb_base_functions; ++rr) {
2614 ++t_row_base_fun;
2615 }
2616
2617 ++t_w;
2618 ++t_levi_kirchhoff_dP;
2619 }
2621}
2622
2624 EntData &col_data) {
2626 int nb_integration_pts = getGaussPts().size2();
2627 int row_nb_dofs = row_data.getIndices().size();
2628 int col_nb_dofs = col_data.getIndices().size();
2629
2630 auto get_ftensor1 = [](MatrixDouble &m, const int r, const int c) {
2632 &m(r + 0, c), &m(r + 1, c), &m(r + 2, c));
2633 };
2634
2635 FTENSOR_INDEX(3, i);
2636 FTENSOR_INDEX(3, k);
2637 FTENSOR_INDEX(3, m);
2638
2639 auto v = getVolume();
2640 auto t_w = getFTensor0IntegrationWeight();
2641 auto t_levi_kirchoff_dP =
2642 getFTensor3FromMat<3, 3, 3>(dataAtPts->leviKirchhoffPAtPts);
2643
2644 int row_nb_base_functions = row_data.getN().size2();
2645 auto t_row_base_fun = row_data.getFTensor0N();
2646
2647 for (int gg = 0; gg != nb_integration_pts; ++gg) {
2648 double a = v * t_w;
2649 int rr = 0;
2650 for (; rr != row_nb_dofs / 3; ++rr) {
2651 double b = a * t_row_base_fun;
2652 auto t_col_base_fun = col_data.getFTensor2N<3, 3>(gg, 0);
2653 auto t_m = get_ftensor1(K, 3 * rr, 0);
2654 for (int cc = 0; cc != col_nb_dofs; ++cc) {
2655 t_m(m) -= b * (t_levi_kirchoff_dP(m, i, k) * t_col_base_fun(i, k));
2656 ++t_m;
2657 ++t_col_base_fun;
2658 }
2659 ++t_row_base_fun;
2660 }
2661
2662 for (; rr != row_nb_base_functions; ++rr) {
2663 ++t_row_base_fun;
2664 }
2665 ++t_w;
2666 ++t_levi_kirchoff_dP;
2667 }
2669}
2670
2672 EntData &col_data) {
2674 int nb_integration_pts = getGaussPts().size2();
2675 int row_nb_dofs = row_data.getIndices().size();
2676 int col_nb_dofs = col_data.getIndices().size();
2677 auto get_ftensor2 = [](MatrixDouble &m, const int r, const int c) {
2679
2680 &m(r + 0, c + 0), &m(r + 0, c + 1), &m(r + 0, c + 2),
2681
2682 &m(r + 1, c + 0), &m(r + 1, c + 1), &m(r + 1, c + 2),
2683
2684 &m(r + 2, c + 0), &m(r + 2, c + 1), &m(r + 2, c + 2)
2685
2686 );
2687 };
2688 FTensor::Index<'i', 3> i;
2689 FTensor::Index<'j', 3> j;
2690 FTensor::Index<'k', 3> k;
2691 FTensor::Index<'l', 3> l;
2692 FTensor::Index<'m', 3> m;
2693 FTensor::Index<'n', 3> n;
2694
2696
2697 auto v = getVolume();
2698 auto ts_a = getTSa();
2699 auto t_w = getFTensor0IntegrationWeight();
2700 auto t_levi_kirchhoff_domega =
2701 getFTensor2FromMat<3, 3>(dataAtPts->leviKirchhoffdOmegaAtPts);
2702 int row_nb_base_functions = row_data.getN().size2();
2703 auto t_row_base_fun = row_data.getFTensor0N();
2704 auto t_row_grad_fun = row_data.getFTensor1DiffN<3>();
2705
2706 // auto time_step = getTStimeStep();
2707 for (int gg = 0; gg != nb_integration_pts; ++gg) {
2708 double a = v * t_w;
2709 double c = (a * alphaOmega) * (ts_a /*/ time_step*/);
2710
2711 int rr = 0;
2712 for (; rr != row_nb_dofs / 3; ++rr) {
2713 auto t_m = get_ftensor2(K, 3 * rr, 0);
2714 const double b = a * t_row_base_fun;
2715 auto t_col_base_fun = col_data.getFTensor0N(gg, 0);
2716 auto t_col_grad_fun = col_data.getFTensor1DiffN<3>(gg, 0);
2717 for (int cc = 0; cc != col_nb_dofs / 3; ++cc) {
2718 t_m(k, l) -= (b * t_col_base_fun) * t_levi_kirchhoff_domega(k, l);
2719 t_m(k, l) += t_kd(k, l) * (c * (t_row_grad_fun(i) * t_col_grad_fun(i)));
2720 ++t_m;
2721 ++t_col_base_fun;
2722 ++t_col_grad_fun;
2723 }
2724 ++t_row_base_fun;
2725 ++t_row_grad_fun;
2726 }
2727 for (; rr != row_nb_base_functions; ++rr) {
2728 ++t_row_base_fun;
2729 ++t_row_grad_fun;
2730 }
2731 ++t_w;
2732 ++t_levi_kirchhoff_domega;
2733 }
2735}
2736
2738 EntData &col_data) {
2740 if (dataAtPts->matInvD.size1() == size_symm &&
2741 dataAtPts->matInvD.size2() == size_symm) {
2742 MoFEMFunctionReturnHot(integrateImpl<0>(row_data, col_data));
2743 } else {
2744 MoFEMFunctionReturnHot(integrateImpl<size_symm>(row_data, col_data));
2745 }
2747};
2748
2749template <int S>
2751 EntData &col_data) {
2753
2754 auto get_ftensor2 = [](MatrixDouble &m, const int r, const int c) {
2756
2757 &m(r + 0, c + 0), &m(r + 0, c + 1), &m(r + 0, c + 2),
2758
2759 &m(r + 1, c + 0), &m(r + 1, c + 1), &m(r + 1, c + 2),
2760
2761 &m(r + 2, c + 0), &m(r + 2, c + 1), &m(r + 2, c + 2)
2762
2763 );
2764 };
2765
2766 int nb_integration_pts = getGaussPts().size2();
2767 int row_nb_dofs = row_data.getIndices().size();
2768 int col_nb_dofs = col_data.getIndices().size();
2769
2770 auto v = getVolume();
2771 auto t_w = getFTensor0IntegrationWeight();
2772 int row_nb_base_functions = row_data.getN().size2() / 3;
2773
2778
2779 auto t_inv_D = getFTensor4DdgFromPtr<SPACE_DIM, SPACE_DIM, S>(
2780 &*dataAtPts->matInvD.data().begin());
2781
2782 auto t_row_base = row_data.getFTensor1N<3>();
2783 for (int gg = 0; gg != nb_integration_pts; ++gg) {
2784 double a = v * t_w;
2785
2786 int rr = 0;
2787 for (; rr != row_nb_dofs / 3; ++rr) {
2788 auto t_col_base = col_data.getFTensor1N<3>(gg, 0);
2789 auto t_m = get_ftensor2(K, 3 * rr, 0);
2790 for (int cc = 0; cc != col_nb_dofs / 3; ++cc) {
2791 t_m(i, k) -= a * t_row_base(j) * (t_inv_D(i, j, k, l) * t_col_base(l));
2792 ++t_m;
2793 ++t_col_base;
2794 }
2795
2796 ++t_row_base;
2797 }
2798
2799 for (; rr != row_nb_base_functions; ++rr)
2800 ++t_row_base;
2801
2802 ++t_w;
2803 ++t_inv_D;
2804 }
2806}
2807
2810 EntData &col_data) {
2812 if (dataAtPts->matInvD.size1() == size_symm &&
2813 dataAtPts->matInvD.size2() == size_symm) {
2814 MoFEMFunctionReturnHot(integrateImpl<0>(row_data, col_data));
2815 } else {
2816 MoFEMFunctionReturnHot(integrateImpl<size_symm>(row_data, col_data));
2817 }
2819};
2820
2821template <int S>
2824 EntData &col_data) {
2826
2827 int nb_integration_pts = getGaussPts().size2();
2828 int row_nb_dofs = row_data.getIndices().size();
2829 int col_nb_dofs = col_data.getIndices().size();
2830
2831 auto v = getVolume();
2832 auto t_w = getFTensor0IntegrationWeight();
2833 int row_nb_base_functions = row_data.getN().size2() / 9;
2834
2839
2840 auto t_inv_D = getFTensor4DdgFromPtr<SPACE_DIM, SPACE_DIM, S>(
2841 &*dataAtPts->matInvD.data().begin());
2842
2843 auto t_row_base = row_data.getFTensor2N<3, 3>();
2844 for (int gg = 0; gg != nb_integration_pts; ++gg) {
2845 double a = v * t_w;
2846
2847 int rr = 0;
2848 for (; rr != row_nb_dofs; ++rr) {
2849 auto t_col_base = col_data.getFTensor2N<3, 3>(gg, 0);
2850 for (int cc = 0; cc != col_nb_dofs; ++cc) {
2851 K(rr, cc) -=
2852 a * (t_row_base(i, j) * (t_inv_D(i, j, k, l) * t_col_base(k, l)));
2853 ++t_col_base;
2854 }
2855
2856 ++t_row_base;
2857 }
2858
2859 for (; rr != row_nb_base_functions; ++rr)
2860 ++t_row_base;
2861 ++t_w;
2862 ++t_inv_D;
2863 }
2865}
2866
2868 EntData &col_data) {
2870 if (dataAtPts->matInvD.size1() == size_symm &&
2871 dataAtPts->matInvD.size2() == size_symm) {
2872 MoFEMFunctionReturnHot(integrateImpl<0>(row_data, col_data));
2873 } else {
2874 MoFEMFunctionReturnHot(integrateImpl<size_symm>(row_data, col_data));
2875 }
2877};
2878
2879template <int S>
2882 EntData &col_data) {
2884
2885 auto get_ftensor1 = [](MatrixDouble &m, const int r, const int c) {
2887
2888 &m(r + 0, c + 0), &m(r + 0, c + 1), &m(r + 0, c + 2)
2889
2890 );
2891 };
2892
2893 int nb_integration_pts = getGaussPts().size2();
2894 int row_nb_dofs = row_data.getIndices().size();
2895 int col_nb_dofs = col_data.getIndices().size();
2896
2897 auto v = getVolume();
2898 auto t_w = getFTensor0IntegrationWeight();
2899 int row_nb_base_functions = row_data.getN().size2() / 9;
2900
2907
2908 auto t_inv_D = getFTensor4DdgFromPtr<SPACE_DIM, SPACE_DIM, S>(
2909 &*dataAtPts->matInvD.data().begin());
2910
2911 auto t_row_base = row_data.getFTensor2N<3, 3>();
2912 for (int gg = 0; gg != nb_integration_pts; ++gg) {
2913 double a = v * t_w;
2914
2915 auto t_m = get_ftensor1(K, 0, 0);
2916
2917 int rr = 0;
2918 for (; rr != row_nb_dofs; ++rr) {
2919 auto t_col_base = col_data.getFTensor1N<3>(gg, 0);
2920 for (int cc = 0; cc != col_nb_dofs / 3; ++cc) {
2921 t_m(k) -= a * (t_row_base(i, j) * t_inv_D(i, j, k, l)) * t_col_base(l);
2922 ++t_col_base;
2923 ++t_m;
2924 }
2925
2926 ++t_row_base;
2927 }
2928
2929 for (; rr != row_nb_base_functions; ++rr)
2930 ++t_row_base;
2931 ++t_w;
2932 ++t_inv_D;
2933 }
2935}
2936
2938 EntData &col_data) {
2940
2947
2948 int nb_integration_pts = row_data.getN().size1();
2949 int row_nb_dofs = row_data.getIndices().size();
2950 int col_nb_dofs = col_data.getIndices().size();
2951
2952 auto get_ftensor2 = [](MatrixDouble &m, const int r, const int c) {
2954
2955 &m(r + 0, c + 0), &m(r + 0, c + 1), &m(r + 0, c + 2),
2956
2957 &m(r + 1, c + 0), &m(r + 1, c + 1), &m(r + 1, c + 2),
2958
2959 &m(r + 2, c + 0), &m(r + 2, c + 1), &m(r + 2, c + 2)
2960
2961 );
2962 };
2963
2964 auto v = getVolume();
2965 auto t_w = getFTensor0IntegrationWeight();
2966 int row_nb_base_functions = row_data.getN().size2() / 3;
2967 auto t_row_base_fun = row_data.getFTensor1N<3>();
2968
2969 auto t_h_domega = getFTensor3FromMat<3, 3, 3>(dataAtPts->hdOmegaAtPts);
2970
2971 for (int gg = 0; gg != nb_integration_pts; ++gg) {
2972 double a = v * t_w;
2973
2974 int rr = 0;
2975 for (; rr != row_nb_dofs / 3; ++rr) {
2976
2978 t_PRT(i, k) = t_row_base_fun(j) * t_h_domega(i, j, k);
2979
2980 auto t_col_base_fun = col_data.getFTensor0N(gg, 0);
2981 auto t_m = get_ftensor2(K, 3 * rr, 0);
2982 for (int cc = 0; cc != col_nb_dofs / 3; ++cc) {
2983 t_m(i, j) -= (a * t_col_base_fun) * t_PRT(i, j);
2984 ++t_m;
2985 ++t_col_base_fun;
2986 }
2987
2988 ++t_row_base_fun;
2989 }
2990
2991 for (; rr != row_nb_base_functions; ++rr)
2992 ++t_row_base_fun;
2993 ++t_w;
2994 ++t_h_domega;
2995 }
2997}
2998
3001 EntData &col_data) {
3003
3010
3011 int nb_integration_pts = row_data.getN().size1();
3012 int row_nb_dofs = row_data.getIndices().size();
3013 int col_nb_dofs = col_data.getIndices().size();
3014
3015 auto get_ftensor2 = [](MatrixDouble &m, const int r, const int c) {
3017 &m(r, c + 0), &m(r, c + 1), &m(r, c + 2));
3018 };
3019
3020 auto v = getVolume();
3021 auto t_w = getFTensor0IntegrationWeight();
3022 int row_nb_base_functions = row_data.getN().size2() / 9;
3023 auto t_row_base_fun = row_data.getFTensor2N<3, 3>();
3024
3025 auto t_h_domega = getFTensor3FromMat<3, 3, 3>(dataAtPts->hdOmegaAtPts);
3026 for (int gg = 0; gg != nb_integration_pts; ++gg) {
3027 double a = v * t_w;
3028
3029 int rr = 0;
3030 for (; rr != row_nb_dofs; ++rr) {
3031
3033 t_PRT(k) = t_row_base_fun(i, j) * t_h_domega(i, j, k);
3034
3035 auto t_col_base_fun = col_data.getFTensor0N(gg, 0);
3036 auto t_m = get_ftensor2(K, rr, 0);
3037 for (int cc = 0; cc != col_nb_dofs / 3; ++cc) {
3038 t_m(j) -= (a * t_col_base_fun) * t_PRT(j);
3039 ++t_m;
3040 ++t_col_base_fun;
3041 }
3042
3043 ++t_row_base_fun;
3044 }
3045
3046 for (; rr != row_nb_base_functions; ++rr)
3047 ++t_row_base_fun;
3048
3049 ++t_w;
3050 ++t_h_domega;
3051 }
3053}
3054
3056 EntData &data) {
3058
3059 if (tagSense != getSkeletonSense())
3061
3062 auto get_tag = [&](auto name) {
3063 auto &mob = getPtrFE()->mField.get_moab();
3064 Tag tag;
3065 CHK_MOAB_THROW(mob.tag_get_handle(name, tag), "get tag");
3066 return tag;
3067 };
3068
3069 auto get_tag_value = [&](auto &&tag, int dim) {
3070 auto &mob = getPtrFE()->mField.get_moab();
3071 auto face = getSidePtrFE()->getFEEntityHandle();
3072 std::vector<double> value(dim);
3073 CHK_MOAB_THROW(mob.tag_get_data(tag, &face, 1, value.data()), "set tag");
3074 return value;
3075 };
3076
3077 auto create_tag = [this](const std::string tag_name, const int size) {
3078 double def_VAL[] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
3079 Tag th;
3080 CHKERR postProcMesh.tag_get_handle(tag_name.c_str(), size, MB_TYPE_DOUBLE,
3081 th, MB_TAG_CREAT | MB_TAG_SPARSE,
3082 def_VAL);
3083 return th;
3084 };
3085
3086 Tag th_cauchy_streess = create_tag("CauchyStress", 9);
3087 Tag th_detF = create_tag("detF", 1);
3088 Tag th_traction = create_tag("traction", 3);
3089 Tag th_disp_error = create_tag("DisplacementError", 1);
3090
3091 Tag th_energy = create_tag("Energy", 1);
3092
3093 auto t_w = getFTensor1FromMat<3>(dataAtPts->wL2AtPts);
3094 auto t_h = getFTensor2FromMat<3, 3>(dataAtPts->hAtPts);
3095 auto t_approx_P = getFTensor2FromMat<3, 3>(dataAtPts->approxPAtPts);
3096
3097 auto t_normal = getFTensor1NormalsAtGaussPts();
3098 auto t_disp = getFTensor1FromMat<3>(dataAtPts->wH1AtPts);
3099
3100 auto next = [&]() {
3101 ++t_w;
3102 ++t_h;
3103 ++t_approx_P;
3104 ++t_normal;
3105 ++t_disp;
3106 };
3107
3108 if (dataAtPts->energyAtPts.size() == 0) {
3109 // that is for case that energy is not calculated
3110 dataAtPts->energyAtPts.resize(getGaussPts().size2());
3111 dataAtPts->energyAtPts.clear();
3112 }
3113 auto t_energy = getFTensor0FromVec(dataAtPts->energyAtPts);
3114
3115 FTensor::Index<'i', 3> i;
3116 FTensor::Index<'j', 3> j;
3117 FTensor::Index<'k', 3> k;
3118 FTensor::Index<'l', 3> l;
3119
3120 auto set_float_precision = [](const double x) {
3121 if (std::abs(x) < std::numeric_limits<float>::epsilon())
3122 return 0.;
3123 else
3124 return x;
3125 };
3126
3127 // scalars
3128 auto save_scal_tag = [&](auto &th, auto v, const int gg) {
3130 v = set_float_precision(v);
3131 CHKERR postProcMesh.tag_set_data(th, &mapGaussPts[gg], 1, &v);
3133 };
3134
3135 // vectors
3136 VectorDouble3 v(3);
3137 FTensor::Tensor1<FTensor::PackPtr<double *, 0>, 3> t_v(&v[0], &v[1], &v[2]);
3138 auto save_vec_tag = [&](auto &th, auto &t_d, const int gg) {
3140 t_v(i) = t_d(i);
3141 for (auto &a : v.data())
3142 a = set_float_precision(a);
3143 CHKERR postProcMesh.tag_set_data(th, &mapGaussPts[gg], 1,
3144 &*v.data().begin());
3146 };
3147
3148 // tensors
3149
3150 MatrixDouble3by3 m(3, 3);
3152 &m(0, 0), &m(0, 1), &m(0, 2),
3153
3154 &m(1, 0), &m(1, 1), &m(1, 2),
3155
3156 &m(2, 0), &m(2, 1), &m(2, 2));
3157
3158 auto save_mat_tag = [&](auto &th, auto &t_d, const int gg) {
3160 t_m(i, j) = t_d(i, j);
3161 for (auto &v : m.data())
3162 v = set_float_precision(v);
3163 CHKERR postProcMesh.tag_set_data(th, &mapGaussPts[gg], 1,
3164 &*m.data().begin());
3166 };
3167
3168 const auto nb_gauss_pts = getGaussPts().size2();
3169 for (auto gg = 0; gg != nb_gauss_pts; ++gg) {
3170
3171 FTensor::Tensor1<double, 3> t_traction;
3172 t_traction(i) = t_approx_P(i, j) * t_normal(j) / t_normal.l2();
3173 // vectors
3174 CHKERR save_vec_tag(th_traction, t_traction, gg);
3175
3176 double u_error = sqrt((t_disp(i) - t_w(i)) * (t_disp(i) - t_w(i)));
3177 CHKERR save_scal_tag(th_disp_error, u_error, gg);
3178 CHKERR save_scal_tag(th_energy, t_energy, gg);
3179
3180 const double jac = determinantTensor3by3(t_h);
3182 t_cauchy(i, j) = (1. / jac) * (t_approx_P(i, k) * t_h(j, k));
3183 CHKERR save_mat_tag(th_cauchy_streess, t_cauchy, gg);
3184 CHKERR postProcMesh.tag_set_data(th_detF, &mapGaussPts[gg], 1, &jac);
3185
3186 next();
3187 }
3188
3190}
3191
3193 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pipeline,
3194 std::vector<FieldSpace> spaces, std::string geom_field_name,
3195 boost::shared_ptr<Range> crack_front_edges_ptr) {
3197
3198 constexpr bool scale_l2 = false;
3199
3200 if (scale_l2) {
3201 SETERRQ(PETSC_COMM_WORLD, MOFEM_NOT_IMPLEMENTED,
3202 "Scale L2 Ainsworth Legendre base is not implemented");
3203 }
3204
3205 CHKERR MoFEM::AddHOOps<2, 3, 3>::add(pipeline, spaces, geom_field_name);
3206
3208}
3209
3211 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pipeline,
3212 std::vector<FieldSpace> spaces, std::string geom_field_name,
3213 boost::shared_ptr<Range> crack_front_edges_ptr) {
3215
3216 constexpr bool scale_l2 = false;
3217
3218 if (scale_l2) {
3219 SETERRQ(PETSC_COMM_WORLD, MOFEM_NOT_IMPLEMENTED,
3220 "Scale L2 Ainsworth Legendre base is not implemented");
3221 }
3222
3223 CHKERR MoFEM::AddHOOps<2, 2, 3>::add(pipeline, spaces, geom_field_name);
3224
3226}
3227
3229 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pipeline,
3230 std::vector<FieldSpace> spaces, std::string geom_field_name,
3231 boost::shared_ptr<Range> crack_front_edges_ptr,
3232 boost::shared_ptr<MatrixDouble> jac, boost::shared_ptr<VectorDouble> det,
3233 boost::shared_ptr<MatrixDouble> inv_jac) {
3235
3237 auto jac = boost::make_shared<MatrixDouble>();
3238 auto det = boost::make_shared<VectorDouble>();
3240 geom_field_name, jac));
3241 pipeline.push_back(new OpInvertMatrix<3>(jac, det, nullptr));
3242 pipeline.push_back(
3244 }
3245
3246 constexpr bool scale_l2_ainsworth_legendre_base = false;
3247
3248 if (scale_l2_ainsworth_legendre_base) {
3249
3251 : public MoFEM::OpCalculateVectorFieldGradient<SPACE_DIM, SPACE_DIM> {
3252
3254
3255 OpCalculateVectorFieldGradient(const std::string &field_name,
3256 boost::shared_ptr<MatrixDouble> jac,
3257 boost::shared_ptr<Range> edges_ptr)
3258 : OP(field_name, jac), edgesPtr(edges_ptr) {}
3259
3260 MoFEMErrorCode doWork(int side, EntityType type, EntData &data) {
3261
3262 auto ent = data.getFieldEntities().size()
3263 ? data.getFieldEntities()[0]->getEnt()
3264 : 0;
3265
3266 if (type == MBEDGE && edgesPtr->find(ent) != edgesPtr->end()) {
3267 return 0;
3268 } else {
3269 return OP::doWork(side, type, data);
3270 }
3271 };
3272
3273 private:
3274 boost::shared_ptr<Range> edgesPtr;
3275 };
3276
3277 auto jac = boost::make_shared<MatrixDouble>();
3278 auto det = boost::make_shared<VectorDouble>();
3279 pipeline.push_back(new OpCalculateVectorFieldGradient(
3280 geom_field_name, jac,
3281 EshelbianCore::setSingularity ? crack_front_edges_ptr
3282 : boost::make_shared<Range>()));
3283 pipeline.push_back(new OpInvertMatrix<3>(jac, det, nullptr));
3284 pipeline.push_back(new OpScaleBaseBySpaceInverseOfMeasure(
3286 }
3287
3288 CHKERR MoFEM::AddHOOps<3, 3, 3>::add(pipeline, spaces, geom_field_name,
3289 jac, det, inv_jac);
3290
3292}
3293
3294/**
3295 * @brief Caluclate face material force and normal pressure at gauss points
3296 *
3297 * @param side
3298 * @param type
3299 * @param data
3300 * @return MoFEMErrorCode
3301 *
3302 * Reconstruct the full gradient \f$U=\nabla u\f$ on a surface from the symmetric part and the surface gradient.
3303 *
3304 * @details
3305 * Inputs:
3306 * - \c t_strain : \f$\varepsilon=\tfrac12(U+U^\top)\f$ (symmetric strain on S),
3307 * - \c t_grad_u_gamma : \f$u^\Gamma = U P\f$ (right-projected/surface gradient), with \f$P=I-\mathbf N\otimes\mathbf N\f$,
3308 * - \c t_normal : (possibly non‑unit) surface normal.
3309 *
3310 * Procedure (pointwise on S):
3311 * 1) Normalize the normal \f$\mathbf n=\mathbf N/\|\mathbf N\|\f$.
3312 * 2) Form the residual \f$R=\varepsilon-\operatorname{sym}(u^\Gamma)\f$, where
3313 * \f$\operatorname{sym}(A)=\tfrac12(A+A^\top)\f$.
3314 * 3) Recover the normal directional derivative (a vector)
3315 * \f$\mathbf v=\partial_{\mathbf n}u=2R\mathbf n-(\mathbf n^\top R\,\mathbf n)\,\mathbf n\f$.
3316 * 4) Assemble the full gradient
3317 * \f$U = u^\Gamma + \mathbf v\otimes \mathbf n\f$.
3318 *
3319 * Properties (sanity checks):
3320 * - \f$\tfrac12(U+U^\top)=\varepsilon\f$ (matches the given symmetric part),
3321 * - \f$U P = u^\Gamma\f$ (tangential/right-projected columns unchanged),
3322 * - Only the **normal column** is updated via \f$\mathbf v\otimes\mathbf n\f$.
3323 *
3324 * Mapping to variables in this snippet:
3325 * - \f$\varepsilon \leftrightarrow\f$ \c t_strain,
3326 * - \f$u^\Gamma \leftrightarrow\f$ \c t_grad_u_gamma,
3327 * - \f$\mathbf N \leftrightarrow\f$ \c t_normal (normalized into \c t_N),
3328 * - \f$R \leftrightarrow\f$ \c t_R,
3329 * - \f$U \leftrightarrow\f$ \c t_grad_u.
3330 *
3331 * @pre \c t_normal is nonzero; \c t_strain is symmetric.
3332 * @note All indices use Einstein summation; computation is local to the surface point.
3333 *
3334*/
3336 EntData &data) {
3338
3351
3352 dataAtPts->faceMaterialForceAtPts.resize(3, getGaussPts().size2(), false);
3353 dataAtPts->normalPressureAtPts.resize(getGaussPts().size2(), false);
3354 if (getNinTheLoop() == 0) {
3355 dataAtPts->faceMaterialForceAtPts.clear();
3356 dataAtPts->normalPressureAtPts.clear();
3357 }
3358 auto loop_size = getLoopSize();
3359 if (loop_size == 1) {
3360 auto numebered_fe_ptr = getSidePtrFE()->numeredEntFiniteElementPtr;
3361 auto pstatus = numebered_fe_ptr->getPStatus();
3362 if (pstatus & (PSTATUS_SHARED | PSTATUS_MULTISHARED)) {
3363 loop_size = 2;
3364 }
3365 }
3366
3368
3369 auto t_normal = getFTensor1NormalsAtGaussPts();
3370 auto t_T = getFTensor1FromMat<SPACE_DIM>(
3371 dataAtPts->faceMaterialForceAtPts); //< face material force
3372 auto t_p =
3373 getFTensor0FromVec(dataAtPts->normalPressureAtPts); //< normal pressure
3374 auto t_P = getFTensor2FromMat<SPACE_DIM, SPACE_DIM>(dataAtPts->approxPAtPts);
3375 // auto t_grad_P = getFTensor3FromMat<SPACE_DIM, SPACE_DIM, SPACE_DIM>(
3376 // dataAtPts->gradPAtPts);
3377 auto t_u_gamma =
3378 getFTensor1FromMat<SPACE_DIM>(dataAtPts->hybridDispAtPts);
3379 auto t_grad_u_gamma =
3380 getFTensor2FromMat<SPACE_DIM, SPACE_DIM>(dataAtPts->gradHybridDispAtPts);
3381 auto t_strain =
3382 getFTensor2SymmetricFromMat<SPACE_DIM>(dataAtPts->logStretchTensorAtPts);
3383 auto t_omega = getFTensor1FromMat<3>(dataAtPts->rotAxisAtPts);
3384
3390
3391 auto next = [&]() {
3392 ++t_normal;
3393 ++t_P;
3394 // ++t_grad_P;
3395 ++t_omega;
3396 ++t_u_gamma;
3397 ++t_grad_u_gamma;
3398 ++t_strain;
3399 ++t_T;
3400 ++t_p;
3401 };
3402
3404 case GRIFFITH_FORCE:
3405 for (auto gg = 0; gg != getGaussPts().size2(); ++gg) {
3406 t_N(I) = t_normal(I);
3407 t_N.normalize();
3408
3409 t_A(i, j) = levi_civita(i, j, k) * t_omega(k);
3410 t_R(i, k) = t_kd(i, k) + t_A(i, k);
3411 t_grad_u(i, j) = t_R(i, j) + t_strain(i, j);
3412
3413 t_T(I) +=
3414 t_N(J) * (t_grad_u(i, I) * t_P(i, J)) / loop_size;
3415 // note that works only for Hooke material, for nonlinear material we need
3416 // strain energy expressed by stress
3417 t_T(I) -= t_N(I) * ((t_strain(i, K) * t_P(i, K)) / 2.) / loop_size;
3418
3419 t_p += t_N(I) * (t_N(J) * (t_grad_u_gamma(i, I) * t_P(i, J))) / loop_size;
3420
3421 next();
3422 }
3423 break;
3424 case GRIFFITH_SKELETON:
3425 for (auto gg = 0; gg != getGaussPts().size2(); ++gg) {
3426
3427 // Normalize the normal
3428 t_N(I) = t_normal(I);
3429 t_N.normalize();
3430
3431 // R = ε − sym(u^Γ)
3432 t_R(i, j) =
3433 t_strain(i, j) - 0.5 * (t_grad_u_gamma(i, j) + t_grad_u_gamma(j, i));
3434
3435 // U = u^Γ + [2 R N − (Nᵀ R N) N] ⊗ N
3436 t_grad_u(i, J) = t_grad_u_gamma(i, J) + (2 * t_R(i, K) * t_N(K) -
3437 (t_R(k, L) * t_N(k) * t_N(L)) * t_N(i)) *
3438 t_N(J);
3439
3440 t_T(I) += t_N(J) * (t_grad_u(i, I) * t_P(i, J)) / loop_size;
3441 // note that works only for Hooke material, for nonlinear material we need
3442 // strain energy expressed by stress
3443 t_T(I) -= t_N(I) * ((t_strain(i, K) * t_P(i, K)) / 2.) / loop_size;
3444
3445 // calculate nominal face pressure
3446 t_p += t_N(I) * (t_N(J) * (t_grad_u_gamma(i, I) * t_P(i, J))) / loop_size;
3447
3448 next();
3449 }
3450 break;
3451
3452 default:
3453 SETERRQ(PETSC_COMM_WORLD, MOFEM_NOT_IMPLEMENTED,
3454 "Grffith energy release "
3455 "selector not implemented");
3456 };
3457
3458#ifndef NDEBUG
3459 auto side_fe_ptr = getSidePtrFE();
3460 auto side_fe_mi_ptr = side_fe_ptr->numeredEntFiniteElementPtr;
3461 auto pstatus = side_fe_mi_ptr->getPStatus();
3462 if (pstatus) {
3463 auto owner = side_fe_mi_ptr->getOwnerProc();
3464 MOFEM_LOG("SELF", Sev::noisy)
3465 << "OpFaceSideMaterialForce: owner proc is not 0, owner proc: " << owner
3466 << " " << getPtrFE()->mField.get_comm_rank() << " n in the loop "
3467 << getNinTheLoop() << " loop size " << getLoopSize();
3468 }
3469#endif // NDEBUG
3470
3472}
3473
3475 EntData &data) {
3477
3478#ifndef NDEBUG
3479 auto fe_mi_ptr = getFEMethod()->numeredEntFiniteElementPtr;
3480 auto pstatus = fe_mi_ptr->getPStatus();
3481 if (pstatus) {
3482 auto owner = fe_mi_ptr->getOwnerProc();
3483 MOFEM_LOG("SELF", Sev::noisy)
3484 << "OpFaceMaterialForce: owner proc is not 0, owner proc: " << owner
3485 << " " << getPtrFE()->mField.get_comm_rank();
3486 }
3487#endif // NDEBUG
3488
3490
3492 t_face_T(I) = 0.;
3493 double face_pressure = 0.;
3494 auto t_T = getFTensor1FromMat<SPACE_DIM>(
3495 dataAtPts->faceMaterialForceAtPts); //< face material force
3496 auto t_p =
3497 getFTensor0FromVec(dataAtPts->normalPressureAtPts); //< normal pressure
3498 auto t_w = getFTensor0IntegrationWeight();
3499 for (auto gg = 0; gg != getGaussPts().size2(); ++gg) {
3500 t_face_T(I) += t_w * t_T(I);
3501 face_pressure += t_w * t_p;
3502 ++t_w;
3503 ++t_T;
3504 ++t_p;
3505 }
3506 t_face_T(I) *= getMeasure();
3507 face_pressure *= getMeasure();
3508
3509 auto get_tag = [&](auto name, auto dim) {
3510 auto &moab = getPtrFE()->mField.get_moab();
3511 Tag tag;
3512 double def_val[] = {0., 0., 0.};
3513 CHK_MOAB_THROW(moab.tag_get_handle(name, dim, MB_TYPE_DOUBLE, tag,
3514 MB_TAG_CREAT | MB_TAG_SPARSE, def_val),
3515 "create tag");
3516 return tag;
3517 };
3518
3519 auto set_tag = [&](auto &&tag, auto ptr) {
3520 auto &moab = getPtrFE()->mField.get_moab();
3521 auto face = getPtrFE()->getFEEntityHandle();
3522 CHK_MOAB_THROW(moab.tag_set_data(tag, &face, 1, ptr), "set tag");
3523 };
3524
3525 set_tag(get_tag("MaterialForce", 3), &t_face_T(0));
3526 set_tag(get_tag("FacePressure", 1), &face_pressure);
3527
3529}
3530
3531
3532template <typename OP_PTR>
3533std::tuple<std::string, MatrixDouble> getAnalyticalExpr(OP_PTR op_ptr, MatrixDouble &analytical_expr,
3534 const std::string block_name) {
3535
3536 auto nb_gauss_pts = op_ptr->getGaussPts().size2();
3537
3538 auto ts_time = op_ptr->getTStime();
3539 auto ts_time_step = op_ptr->getTStimeStep();
3542 ts_time_step = EshelbianCore::dynamicStep;
3543 }
3544
3545 MatrixDouble m_ref_coords = op_ptr->getCoordsAtGaussPts();
3546 MatrixDouble m_ref_normals = op_ptr->getNormalsAtGaussPts();
3547
3548 auto v_analytical_expr =
3549 analytical_expr_function(ts_time_step, ts_time, nb_gauss_pts,
3550 m_ref_coords, m_ref_normals, block_name);
3551
3552#ifndef NDEBUG
3553 if (v_analytical_expr.size2() != nb_gauss_pts)
3555 "Wrong number of integration pts");
3556#endif // NDEBUG
3557
3558 return std::make_tuple(block_name, v_analytical_expr);
3559}
3560
3561//! [Analytical displacement function from python]
3562#ifdef ENABLE_PYTHON_BINDING
3563
3564 MoFEMErrorCode AnalyticalExprPython::analyticalExprInit(const std::string py_file) {
3566 try {
3567
3568 // create main module
3569 auto main_module = bp::import("__main__");
3570 mainNamespace = main_module.attr("__dict__");
3571 bp::exec_file(py_file.c_str(), mainNamespace, mainNamespace);
3572 // create a reference to python function
3573 analyticalDispFun = mainNamespace["analytical_disp"];
3574 analyticalTractionFun = mainNamespace["analytical_traction"];
3575 analyticalExternalStrainFun = mainNamespace["analytical_external_strain"];
3576
3577 } catch (bp::error_already_set const &) {
3578 // print all other errors to stderr
3579 PyErr_Print();
3581 }
3583 }
3584
3585 MoFEMErrorCode AnalyticalExprPython::evalAnalyticalDisp(
3586
3587 double delta_t, double t, np::ndarray x, np::ndarray y, np::ndarray z,
3588 np::ndarray nx, np::ndarray ny, np::ndarray nz,
3589 const std::string &block_name, np::ndarray &analytical_expr
3590
3591 ) {
3593 try {
3594
3595 // call python function
3596 analytical_expr = bp::extract<np::ndarray>(
3597 analyticalDispFun(delta_t, t, x, y, z, nx, ny, nz, block_name));
3598
3599 } catch (bp::error_already_set const &) {
3600 // print all other errors to stderr
3601 PyErr_Print();
3603 }
3605 }
3606
3607 MoFEMErrorCode AnalyticalExprPython::evalAnalyticalTraction(
3608
3609 double delta_t, double t, np::ndarray x, np::ndarray y, np::ndarray z,
3610 np::ndarray nx, np::ndarray ny, np::ndarray nz,
3611 const std::string& block_name, np::ndarray &analytical_expr
3612
3613 ) {
3615 try {
3616
3617 // call python function
3618 analytical_expr = bp::extract<np::ndarray>(
3619 analyticalTractionFun(delta_t, t, x, y, z, nx, ny, nz, block_name));
3620
3621 } catch (bp::error_already_set const &) {
3622 // print all other errors to stderr
3623 PyErr_Print();
3625 }
3627 }
3628
3629 MoFEMErrorCode AnalyticalExprPython::evalAnalyticalExternalStrain(
3630
3631 double delta_t, double t, np::ndarray x, np::ndarray y, np::ndarray z,
3632 const std::string& block_name, np::ndarray &analytical_expr
3633
3634 ) {
3636 try {
3637
3638 // call python function
3639 analytical_expr = bp::extract<np::ndarray>(
3640 analyticalExternalStrainFun(delta_t, t, x, y, z, block_name));
3641
3642 } catch (bp::error_already_set const &) {
3643 // print all other errors to stderr
3644 PyErr_Print();
3646 }
3648 }
3649
3650boost::weak_ptr<AnalyticalExprPython> AnalyticalExprPythonWeakPtr;
3651
3652inline np::ndarray convert_to_numpy(VectorDouble &data, int nb_gauss_pts,
3653 int id) {
3654 auto dtype = np::dtype::get_builtin<double>();
3655 auto size = bp::make_tuple(nb_gauss_pts);
3656 auto stride = bp::make_tuple(3 * sizeof(double));
3657 return (np::from_data(&data[id], dtype, size, stride, bp::object()));
3658};
3659#endif
3660//! Analytical displacement function from python]
3661
3663 int nb_gauss_pts,
3664 MatrixDouble &m_ref_coords,
3665 MatrixDouble &m_ref_normals,
3666 const std::string block_name) {
3667
3668#ifdef ENABLE_PYTHON_BINDING
3669 if (auto analytical_expr_ptr = AnalyticalExprPythonWeakPtr.lock()) {
3670
3671 VectorDouble v_ref_coords = m_ref_coords.data();
3672 VectorDouble v_ref_normals = m_ref_normals.data();
3673
3674 bp::list python_coords;
3675 bp::list python_normals;
3676
3677 for (int idx = 0; idx < 3; ++idx) {
3678 python_coords.append(convert_to_numpy(v_ref_coords, nb_gauss_pts, idx));
3679 python_normals.append(convert_to_numpy(v_ref_normals, nb_gauss_pts, idx));
3680 }
3681
3682 auto disp_block_name = "(.*)ANALYTICAL_DISPLACEMENT(.*)";
3683 auto traction_block_name = "(.*)ANALYTICAL_TRACTION(.*)";
3684
3685 std::regex reg_disp_name(disp_block_name);
3686 std::regex reg_traction_name(traction_block_name);
3687
3688 np::ndarray np_analytical_expr = np::empty(
3689 bp::make_tuple(nb_gauss_pts, 3), np::dtype::get_builtin<double>());
3690
3691 if (std::regex_match(block_name, reg_disp_name)) {
3692 CHK_MOAB_THROW(analytical_expr_ptr->evalAnalyticalDisp(
3693 delta_t, t, bp::extract<np::ndarray>(python_coords[0]),
3694 bp::extract<np::ndarray>(python_coords[1]),
3695 bp::extract<np::ndarray>(python_coords[2]),
3696 bp::extract<np::ndarray>(python_normals[0]),
3697 bp::extract<np::ndarray>(python_normals[1]),
3698 bp::extract<np::ndarray>(python_normals[2]),
3699 block_name, np_analytical_expr),
3700 "Failed analytical_disp() python call");
3701 } else if (std::regex_match(block_name, reg_traction_name)) {
3702 CHK_MOAB_THROW(analytical_expr_ptr->evalAnalyticalTraction(
3703 delta_t, t, bp::extract<np::ndarray>(python_coords[0]),
3704 bp::extract<np::ndarray>(python_coords[1]),
3705 bp::extract<np::ndarray>(python_coords[2]),
3706 bp::extract<np::ndarray>(python_normals[0]),
3707 bp::extract<np::ndarray>(python_normals[1]),
3708 bp::extract<np::ndarray>(python_normals[2]),
3709 block_name, np_analytical_expr),
3710 "Failed analytical_traction() python call");
3711 } else {
3713 "Unknown analytical block");
3714 }
3715
3716 double *analytical_expr_val_ptr =
3717 reinterpret_cast<double *>(np_analytical_expr.get_data());
3718
3719 MatrixDouble v_analytical_expr;
3720 v_analytical_expr.resize(3, nb_gauss_pts, false);
3721 for (size_t gg = 0; gg < nb_gauss_pts; ++gg) {
3722 for (int idx = 0; idx < 3; ++idx)
3723 v_analytical_expr(idx, gg) =
3724 *(analytical_expr_val_ptr + (3 * gg + idx));
3725 }
3726 return v_analytical_expr;
3727 } else {
3728 // Returns empty vector
3729 }
3730#endif
3731 return MatrixDouble();
3732}
3733
3735 int nb_gauss_pts,
3736 MatrixDouble &m_ref_coords,
3737 const std::string block_name) {
3738
3739#ifdef ENABLE_PYTHON_BINDING
3740 if (auto analytical_expr_ptr = AnalyticalExprPythonWeakPtr.lock()) {
3741
3742 VectorDouble v_ref_coords = m_ref_coords.data();
3743
3744 bp::list python_coords;
3745
3746 for (int idx = 0; idx < 3; ++idx) {
3747 python_coords.append(convert_to_numpy(v_ref_coords, nb_gauss_pts, idx));
3748 }
3749
3750 auto externalstrain_block_name = "(.*)ANALYTICAL_EXTERNALSTRAIN(.*)";
3751
3752 std::regex reg_externalstrain_name(externalstrain_block_name);
3753
3754 np::ndarray np_analytical_expr = np::empty(
3755 bp::make_tuple(nb_gauss_pts), np::dtype::get_builtin<double>());
3756
3757 if (std::regex_match(block_name, reg_externalstrain_name)) {
3758 CHK_MOAB_THROW(analytical_expr_ptr->evalAnalyticalExternalStrain(
3759 delta_t, t, bp::extract<np::ndarray>(python_coords[0]),
3760 bp::extract<np::ndarray>(python_coords[1]),
3761 bp::extract<np::ndarray>(python_coords[2]), block_name,
3762 np_analytical_expr),
3763 "Failed analytical_external_strain() python call");
3764 } else {
3766 "Unknown analytical block");
3767 }
3768
3769 double *analytical_expr_val_ptr =
3770 reinterpret_cast<double *>(np_analytical_expr.get_data());
3771
3772 VectorDouble v_analytical_expr;
3773 v_analytical_expr.resize(nb_gauss_pts, false);
3774 for (size_t gg = 0; gg < nb_gauss_pts; ++gg)
3775 v_analytical_expr[gg] = *(analytical_expr_val_ptr + gg);
3776
3777 return v_analytical_expr;
3778 } else {
3779 // Returns empty vector
3780 }
3781#endif
3782 return VectorDouble();
3783}
3784
3785} // namespace EshelbianPlasticity
Auxilary functions for Eshelbian plasticity.
Eshelbian plasticity interface.
Lie algebra implementation.
#define FTENSOR_INDEX(DIM, I)
constexpr double a
constexpr int SPACE_DIM
[Define dimension]
Kronecker Delta class symmetric.
Kronecker Delta class.
Tensor1< T, Tensor_Dim > normalize()
@ AINSWORTH_LEGENDRE_BASE
Ainsworth Cole (Legendre) approx. base .
Definition definitions.h:60
@ USER_BASE
user implemented approximation base
Definition definitions.h:68
@ NOBASE
Definition definitions.h:59
#define CHK_THROW_MESSAGE(err, msg)
Check and throw MoFEM exception.
#define MoFEMFunctionReturnHot(a)
Last executable line of each PETSc function used for error handling. Replaces return()
@ L2
field with C-1 continuity
Definition definitions.h:88
#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
Definition definitions.h:34
@ MOFEM_DATA_INCONSISTENCY
Definition definitions.h:31
@ MOFEM_NOT_IMPLEMENTED
Definition definitions.h:32
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
#define MoFEMFunctionBeginHot
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
constexpr auto t_kd
#define MOFEM_LOG(channel, severity)
Log.
FTensor::Index< 'i', SPACE_DIM > i
const double c
speed of light (cm/ns)
const double v
phase velocity of light in medium (cm/ns)
const double n
refractive index of diffusive medium
FTensor::Index< 'J', DIM1 > J
Definition level_set.cpp:30
MoFEM::TsCtx * ts_ctx
FTensor::Index< 'l', 3 > l
FTensor::Index< 'j', 3 > j
FTensor::Index< 'k', 3 > k
auto getMat(A &&t_val, B &&t_vec, Fun< double > f)
Get the Mat object.
auto getDiffMat(A &&t_val, B &&t_vec, Fun< double > f, Fun< double > d_f, const int nb)
Get the Diff Mat object.
VectorDouble analytical_externalstrain_function(double delta_t, double t, int nb_gauss_pts, MatrixDouble &m_ref_coords, const std::string block_name)
auto sort_eigen_vals(A &eig, B &eigen_vec)
std::tuple< std::string, MatrixDouble > getAnalyticalExpr(OP_PTR op_ptr, MatrixDouble &analytical_expr, const std::string block_name)
static constexpr auto size_symm
MatrixDouble analytical_expr_function(double delta_t, double t, int nb_gauss_pts, MatrixDouble &m_ref_coords, MatrixDouble &m_ref_normals, const std::string block_name)
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
VectorBoundedArray< double, 3 > VectorDouble3
Definition Types.hpp:92
UBlasMatrix< double > MatrixDouble
Definition Types.hpp:77
UBlasVector< double > VectorDouble
Definition Types.hpp:68
implementation of Data Operators for Forces and Sources
Definition Common.hpp:10
static auto getFTensor0FromVec(ublas::vector< T, A > &data)
Get tensor rank 0 (scalar) form data vector.
MoFEMErrorCode computeEigenValuesSymmetric(const MatrixDouble &mat, VectorDouble &eig, MatrixDouble &eigen_vec)
compute eigenvalues of a symmetric matrix using lapack dsyev
static auto determinantTensor3by3(T &t)
Calculate the determinant of a 3x3 matrix or a tensor of rank 2.
constexpr IntegrationType I
constexpr double t
plate stiffness
Definition plate.cpp:58
constexpr auto field_name
FTensor::Index< 'm', 3 > m
const int N
Definition speed_test.cpp:3
static enum StretchSelector stretchSelector
static double dynamicTime
static PetscBool l2UserBaseScale
static int dynamicStep
static enum RotSelector rotSelector
static enum RotSelector gradApproximator
static PetscBool dynamicRelaxation
static enum SymmetrySelector symmetrySelector
static boost::function< double(const double)> f
static PetscBool setSingularity
static boost::function< double(const double)> d_f
static enum EnergyReleaseSelector energyReleaseSelector
static boost::function< double(const double)> inv_f
static auto diffExp(A &&t_w_vee, B &&theta)
Definition Lie.hpp:79
static auto exp(A &&t_w_vee, B &&theta)
Definition Lie.hpp:48
Add operators pushing bases from local to physical configuration.
Data on single entity (This is passed as argument to DataOperator::doWork)
FTensor::Tensor2< FTensor::PackPtr< double *, Tensor_Dim0 *Tensor_Dim1 >, Tensor_Dim0, Tensor_Dim1 > getFTensor2DiffN(FieldApproximationBase base)
Get derivatives of base functions for Hdiv space.
FTensor::Tensor1< FTensor::PackPtr< double *, Tensor_Dim >, Tensor_Dim > getFTensor1DiffN(const FieldApproximationBase base)
Get derivatives of base functions.
FTensor::Tensor2< FTensor::PackPtr< double *, Tensor_Dim0 *Tensor_Dim1 >, Tensor_Dim0, Tensor_Dim1 > getFTensor2N(FieldApproximationBase base)
Get base functions for Hdiv/Hcurl spaces.
FTensor::Tensor0< FTensor::PackPtr< double *, 1 > > getFTensor0N(const FieldApproximationBase base)
Get base function as Tensor0.
const VectorFieldEntities & getFieldEntities() const
Get field entities (const version)
MatrixDouble & getN(const FieldApproximationBase base)
get base functions this return matrix (nb. of rows is equal to nb. of Gauss pts, nb....
const VectorDouble & getFieldData() const
Get DOF values on entity.
FTensor::Tensor1< FTensor::PackPtr< double *, Tensor_Dim >, Tensor_Dim > getFTensor1N(FieldApproximationBase base)
Get base functions for Hdiv/Hcurl spaces.
const VectorInt & getIndices() const
Get global indices of degrees of freedom on entity.
Get field gradients at integration pts for scalar field rank 0, i.e. vector field.
Operator for inverting matrices at integration points.
Scale base functions by inverses of measure of element.
@ CTX_TSSETIJACOBIAN
Setting up implicit Jacobian.
MoFEMErrorCode iNtegrate(EntData &data)
MoFEMErrorCode iNtegrate(EntData &data)
MoFEMErrorCode iNtegrate(EntData &row_data, EntData &col_data)
MoFEMErrorCode iNtegrate(EntData &data)
MoFEMErrorCode iNtegrate(EntData &data)
MoFEMErrorCode doWork(int row_side, EntityType row_type, EntData &row_data)
Operator for linear form, usually to calculate values on right hand side.
MoFEMErrorCode doWork(int side, EntityType type, EntData &data)
MoFEMErrorCode doWork(int side, EntityType type, EntData &data)
Operator for linear form, usually to calculate values on right hand side.
MoFEMErrorCode doWork(int side, EntityType type, EntData &data)
MoFEMErrorCode iNtegrate(EntData &data)
MoFEMErrorCode doWork(int side, EntityType type, EntData &data)
MoFEMErrorCode doWork(int side, EntityType type, EntData &data)
Caluclate face material force and normal pressure at gauss points.
MoFEMErrorCode doWork(int side, EntityType type, EntData &data)
Operator for linear form, usually to calculate values on right hand side.
MoFEMErrorCode iNtegrate(EntData &row_data, EntData &col_data)
MoFEMErrorCode iNtegrate(EntData &row_data, EntData &col_data)
MoFEMErrorCode iNtegrate(EntData &data)
MoFEMErrorCode doWork(int side, EntityType type, EntData &data)
MoFEMErrorCode iNtegrate(EntData &data)
MoFEMErrorCode integrate(EntData &data)
MoFEMErrorCode integrate(EntData &data)
MoFEMErrorCode integrate(EntData &data)
MoFEMErrorCode integrate(EntData &row_data, EntData &col_data)
MoFEMErrorCode integrateImpl(EntData &row_data, EntData &col_data)
MoFEMErrorCode integrateImpl(EntData &row_data, EntData &col_data)
MoFEMErrorCode integrate(EntData &row_data, EntData &col_data)
MoFEMErrorCode integrate(EntData &row_data, EntData &col_data)
MoFEMErrorCode integrate(EntData &row_data, EntData &col_data)
MoFEMErrorCode integrateImpl(EntData &row_data, EntData &col_data)
MoFEMErrorCode integrate(EntData &row_data, EntData &col_data)
MoFEMErrorCode integrate(EntData &row_data, EntData &col_data)
MoFEMErrorCode integrate(EntData &row_data, EntData &col_data)
MoFEMErrorCode integrate(EntData &data)
MoFEMErrorCode integrate(EntData &row_data)
MoFEMErrorCode integrate(EntData &row_data, EntData &col_data)
MoFEMErrorCode integrate(EntData &row_data, EntData &col_data)
MoFEMErrorCode integrate(EntData &row_data, EntData &col_data)
MoFEMErrorCode integrate(EntData &row_data, EntData &col_data)
MoFEMErrorCode integrate(EntData &row_data, EntData &col_data)
MoFEMErrorCode integrate(EntData &row_data, EntData &col_data)
MoFEMErrorCode integrate(EntData &row_data, EntData &col_data)
MoFEMErrorCode integrate(EntData &data)
double scale
Definition plastic.cpp:123