v0.16.0
Loading...
Searching...
No Matches
EshelbianOperators.cpp
Go to the documentation of this file.
1/**
2 * \file EshelbianOperators.cpp
3 * \example
4 * mofem/users_modules/eshelbian_plasticity/src/impl/EshelbianOperators.cpp
5 *
6 * \brief Implementation of operators
7 */
8
9#include <MoFEM.hpp>
10using namespace MoFEM;
11
13
14#include <boost/math/constants/constants.hpp>
15
16#include <EshelbianAux.hpp>
17
18#include <lapack_wrap.h>
19
20#include <Lie.hpp>
21#include <MatrixFunction.hpp>
22
23namespace EshelbianPlasticity {
24
26 EntData &data) {
31
32 int nb_integration_pts = getGaussPts().size2();
33
34 auto t_P = dataAtPts->getFTensorApproxP(getGaussPts().size2());
35 auto t_F = dataAtPts->getFTensorSmallH(getGaussPts().size2());
36 auto t_energy = getFTensor0FromVec(dataAtPts->energyAtPts);
37
38 auto get_eshelby_stress =
40 DL>::size(dataAtPts->SigmaAtPts, nb_integration_pts);
41 auto t_eshelby_stress = get_eshelby_stress();
42
44
45 for (auto gg = 0; gg != nb_integration_pts; ++gg) {
46 t_eshelby_stress(i, j) = t_energy * t_kd(i, j) - t_F(m, i) * t_P(m, j);
47 ++t_energy;
48 ++t_P;
49 ++t_F;
50 ++t_eshelby_stress;
51 }
52
54}
55
57 EntityType type,
58 EntData &data) {
60
61 auto ts_ctx = getTSCtx();
62 int nb_integration_pts = getGaussPts().size2();
63
64 // space size indices
72
73 // sym size indices
75
76 auto t_L = symm_L_tensor();
77
79 *dataAtPts->getStretchTensorAtPts(), nb_integration_pts);
81 *dataAtPts->getDiffStretchTensorAtPts(), nb_integration_pts);
83 *dataAtPts->getStretchH1AtPts(), nb_integration_pts);
84 MatrixSizeHelper<GetFTensor4FromMatType<3, 3, 3, 3, -1, DL>, DL>::size(
85 *dataAtPts->getDiffStretchH1AtPts(), nb_integration_pts);
87 *dataAtPts->getAdjointPdstretchAtPts(), nb_integration_pts);
89 *dataAtPts->getAdjointPdUAtPts(), nb_integration_pts);
91 *dataAtPts->getAdjointPdUdPAtPts(), nb_integration_pts);
93 *dataAtPts->getAdjointPdUdOmegaAtPts(), nb_integration_pts);
94
96 *dataAtPts->getDeformationGradient(), nb_integration_pts);
97 MatrixSizeHelper<GetFTensor3FromMatType<3, 3, 3, -1, DL>, DL>::size(
98 dataAtPts->hdOmegaAtPts, nb_integration_pts);
100 dataAtPts->hdLogStretchAtPts, nb_integration_pts);
101
103 dataAtPts->leviKirchhoffAtPts, nb_integration_pts);
104 MatrixSizeHelper<GetFTensor2FromMatType<3, 3, -1, DL>, DL>::size(
105 dataAtPts->leviKirchhoffdOmegaAtPts, nb_integration_pts);
107 dataAtPts->leviKirchhoffdLogStreatchAtPts, nb_integration_pts);
108 MatrixSizeHelper<GetFTensor3FromMatType<3, 3, 3, -1, DL>, DL>::size(
109 dataAtPts->leviKirchhoffPAtPts, nb_integration_pts);
110
111 MatrixSizeHelper<GetFTensor2FromMatType<3, 3, -1, DL>, DL>::size(
112 dataAtPts->rotMatAtPts, nb_integration_pts);
114 *dataAtPts->getEigenVals(), nb_integration_pts);
115 MatrixSizeHelper<GetFTensor2FromMatType<3, 3, -1, DL>, DL>::size(
116 *dataAtPts->getEigenVecs(), nb_integration_pts);
117 dataAtPts->nbUniq.resize(nb_integration_pts, false);
119 dataAtPts->eigenValsC, nb_integration_pts);
120 MatrixSizeHelper<GetFTensor2FromMatType<3, 3, -1, DL>, DL>::size(
121 dataAtPts->eigenVecsC, nb_integration_pts);
122 dataAtPts->nbUniqC.resize(nb_integration_pts, false);
123
125 dataAtPts->logStretch2H1AtPts, nb_integration_pts);
127 dataAtPts->logStretchTotalTensorAtPts, nb_integration_pts);
128
129 MatrixSizeHelper<GetFTensor2FromMatType<3, 3, -1, DL>, DL>::size(
130 dataAtPts->internalStressAtPts, nb_integration_pts);
131 dataAtPts->internalStressAtPts.clear();
132
133 // Calculated values
134 auto t_h = dataAtPts->getFTensorSmallH(getGaussPts().size2());
135 auto t_h_domega = dataAtPts->getFTensorSmallHdOmega(getGaussPts().size2());
136 auto t_h_dlog_u =
137 dataAtPts->getFTensorSmallHdLogStretch(getGaussPts().size2());
138 auto t_levi_kirchhoff =
139 dataAtPts->getFTensorLeviKirchhoff(getGaussPts().size2());
140 auto t_levi_kirchhoff_domega =
141 dataAtPts->getFTensorLeviKirchhoffdOmega(getGaussPts().size2());
142 auto t_levi_kirchhoff_dstreach =
143 dataAtPts->getFTensorLeviKirchhoffdLogStretch(getGaussPts().size2());
144 auto t_levi_kirchhoff_dP =
145 dataAtPts->getFTensorLeviKirchhoffP(getGaussPts().size2());
146 auto t_approx_P_adjoint_dstretch =
147 dataAtPts->getFTensorAdjointPdstretch(getGaussPts().size2());
148 auto t_approx_P_adjoint_log_du =
149 dataAtPts->getFTensorAdjointPdU(getGaussPts().size2());
150 auto t_approx_P_adjoint_log_du_dP =
151 dataAtPts->getFTensorAdjointPdUdP(getGaussPts().size2());
152 auto t_approx_P_adjoint_log_du_domega =
153 dataAtPts->getFTensorAdjointPdUdOmega(getGaussPts().size2());
154 auto t_R = dataAtPts->getFTensorRotMat(getGaussPts().size2());
155 auto t_u = dataAtPts->getFTensorStretch(getGaussPts().size2());
156 auto t_diff_u = dataAtPts->getFTensorDiffStretch(getGaussPts().size2());
157 auto t_eigen_vals = dataAtPts->getFTensorEigenVals(getGaussPts().size2());
158 auto t_eigen_vecs = dataAtPts->getFTensorEigenVecs(getGaussPts().size2());
159 auto &nbUniq = dataAtPts->nbUniq;
160 auto t_nb_uniq =
161 FTensor::Tensor0<FTensor::PackPtr<int *, 1>>(nbUniq.data().data());
162 auto t_eigen_vals_C = dataAtPts->getFTensorEigenValsC(nb_integration_pts);
163 auto t_eigen_vecs_C = dataAtPts->getFTensorEigenVecsC(nb_integration_pts);
164 auto &nbUniqC = dataAtPts->nbUniqC;
165 auto t_nb_uniq_C =
166 FTensor::Tensor0<FTensor::PackPtr<int *, 1>>(nbUniqC.data().data());
167
168 auto t_u_h1 = dataAtPts->getFTensorStretchH1(getGaussPts().size2());
169 auto t_diff_u_h1 = dataAtPts->getFTensorDiffStretchH1(getGaussPts().size2());
170 auto t_log_stretch_total =
171 dataAtPts->getFTensorLogStretchTotal(getGaussPts().size2());
172 auto t_log_u2_h1 = dataAtPts->getFTensorLogStretch2H1(getGaussPts().size2());
173
174 // Field values
175 auto t_grad_h1 = dataAtPts->getFTensorSmallWGradH1(getGaussPts().size2());
176 auto t_omega = dataAtPts->getFTensorRotAxis(getGaussPts().size2());
177 auto t_approx_P = dataAtPts->getFTensorApproxP(getGaussPts().size2());
178 auto t_log_u = dataAtPts->getFTensorLogStretch(getGaussPts().size2());
179
180 // Rot axis 0
181 auto t_omega0 = dataAtPts->getFTensorRotAxis0(getGaussPts().size2());
182
183 auto next = [&]() {
184 // calculated values
185 ++t_h;
186 ++t_h_domega;
187 ++t_h_dlog_u;
188 ++t_levi_kirchhoff;
189 ++t_levi_kirchhoff_domega;
190 ++t_levi_kirchhoff_dstreach;
191 ++t_levi_kirchhoff_dP;
192 ++t_approx_P_adjoint_dstretch;
193 ++t_approx_P_adjoint_log_du;
194 ++t_approx_P_adjoint_log_du_dP;
195 ++t_approx_P_adjoint_log_du_domega;
196 ++t_R;
197 ++t_u;
198 ++t_diff_u;
199 ++t_eigen_vals;
200 ++t_eigen_vecs;
201 ++t_nb_uniq;
202 ++t_eigen_vals_C;
203 ++t_eigen_vecs_C;
204 ++t_nb_uniq_C;
205 ++t_u_h1;
206 ++t_diff_u_h1;
207 ++t_log_u2_h1;
208 ++t_log_stretch_total;
209 // field values
210 ++t_omega;
211 ++t_omega0;
212 ++t_grad_h1;
213 ++t_approx_P;
214 ++t_log_u;
215 };
216
219
220 auto bound_eig = [&](auto &eig) {
222 const auto zero = std::exp(std::numeric_limits<double>::min_exponent);
223 const auto large = std::exp(std::numeric_limits<double>::max_exponent);
224 for (int ii = 0; ii != 3; ++ii) {
225 eig(ii) = std::min(std::max(zero, eig(ii)), large);
226 }
228 };
229
230 auto calculate_log_stretch = [&]() {
234 eigen_vec(i, j) = t_log_u(i, j);
235 if (computeEigenValuesSymmetric(eigen_vec, eig) != MB_SUCCESS) {
236 MOFEM_LOG("SELF", Sev::error) << "Failed to compute eigen values";
237 }
238 // CHKERR bound_eig(eig);
239 // rare case when two eigen values are equal
240 t_nb_uniq = get_uniq_nb<3>(&eig(0));
241 if (t_nb_uniq < 3) {
242 sort_eigen_vals(eig, eigen_vec);
243 }
244 t_eigen_vals(i) = eig(i);
245 t_eigen_vecs(i, j) = eigen_vec(i, j);
246 t_u(i, j) =
247 EigenMatrix::getMat(t_eigen_vals, t_eigen_vecs, EshelbianCore::f)(i, j);
248 auto get_t_diff_u = [&]() {
249 return EigenMatrix::getDiffMat(t_eigen_vals, t_eigen_vecs,
251 t_nb_uniq);
252 };
253 t_diff_u(i, j, k, l) = get_t_diff_u()(i, j, k, l);
255 t_Ldiff_u(i, j, L) = t_diff_u(i, j, m, n) * t_L(m, n, L);
257 // return t_Ldiff_u;
258 };
259
260 auto calculate_total_stretch = [&](auto &t_h1) {
263
264 t_log_u2_h1(i, j) = 0;
265 t_log_stretch_total(i, j) = t_log_u(i, j);
266
267 } else {
268
271
273 t_C_h1(i, j) = t_h1(k, i) * t_h1(k, j);
274 t_eigen_vec(i, j) = t_C_h1(i, j);
275 if (computeEigenValuesSymmetric(t_eigen_vec, t_eig) != MB_SUCCESS) {
276 MOFEM_LOG("SELF", Sev::error) << "Failed to compute eigen values";
277 }
278 // rare case when two eigen values are equal
279 t_nb_uniq_C = get_uniq_nb<3>(&t_eig(0));
280 if (t_nb_uniq_C < 3) {
281 sort_eigen_vals(t_eig, t_eigen_vec);
282 }
284 CHKERR bound_eig(t_eig);
285 }
286 t_eigen_vals_C(i) = t_eig(i);
287 t_eigen_vecs_C(i, j) = t_eigen_vec(i, j);
288
289 t_log_u2_h1(i, j) =
290 EigenMatrix::getMat(t_eig, t_eigen_vec, EshelbianCore::inv_f)(i, j);
291 t_log_stretch_total(i, j) = t_log_u2_h1(i, j) / 2 + t_log_u(i, j);
292 }
294 };
295
296 auto no_h1_loop = [&]() {
298
300 case LARGE_ROT:
301 case MODERATE_ROT:
302 break;
303 default:
304 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
305 "no_h1_loop is implemented only for LARGE_ROT");
306 };
307
308 for (int gg = 0; gg != nb_integration_pts; ++gg) {
309
311
313 t_h1(i, j) = t_kd(i, j);
314
315 // calculate streach
316 CHKERR calculate_log_stretch();
317 // calculate total stretch
318 CHKERR calculate_total_stretch(t_h1);
319
320 t_u_h1(i, j) = t_u(i, j);
321 t_diff_u_h1(i, j, k, l) = t_diff_u(i, j, k, l);
323 t_Ldiff_u(i, j, L) = t_diff_u(i, j, m, n) * t_L(m, n, L);
324
327
328 auto large_rot = [&]() {
329 t_R(i, j) = LieGroups::SO3::exp(t_omega, t_omega.l2())(i, j);
330 t_diff_R(i, j, k) =
331 LieGroups::SO3::diffExp(t_omega, t_omega.l2())(i, j, k);
332 t_diff_diff_R(i, j, k, l) =
333 LieGroups::SO3::diffDiffExp(t_omega, t_omega.l2())(i, j, k, l);
334
335 t_h(i, k) = t_R(i, l) * t_u(l, k);
336
337 t_approx_P_adjoint_dstretch(l, k) = t_R(i, l) * t_approx_P(i, k);
338 t_approx_P_adjoint_log_du(L) =
339 t_approx_P_adjoint_dstretch(l, k) * t_Ldiff_u(l, k, L);
340
341 t_levi_kirchhoff(m) =
342 t_diff_R(i, l, m) * (t_u(l, k) * t_approx_P(i, k));
343
345 t_h_domega(i, k, m) = t_diff_R(i, l, m) * t_u(l, k);
346 t_h_dlog_u(i, k, L) = t_R(i, l) * t_Ldiff_u(l, k, L);
347
348 t_approx_P_adjoint_log_du_dP(i, k, L) =
349 t_R(i, l) * t_Ldiff_u(l, k, L);
350
352 t_A(k, l, m) = t_diff_R(i, l, m) * t_approx_P(i, k);
353 t_approx_P_adjoint_log_du_domega(m, L) =
354 t_A(k, l, m) * t_Ldiff_u(k, l, L);
355
356 t_levi_kirchhoff_dstreach(m, L) =
357 t_diff_R(i, l, m) * (t_Ldiff_u(l, k, L) * t_approx_P(i, k));
358 t_levi_kirchhoff_dP(m, i, k) = t_diff_R(i, l, m) * t_u(l, k);
359 t_levi_kirchhoff_domega(m, n) =
360 t_diff_diff_R(i, l, m, n) * (t_u(l, k) * t_approx_P(i, k));
361 }
362 };
363
364 auto moderate_rot = [&]() {
366 FTensor::Tensor1<double, 3> t_delta_omega;
367 t_delta_omega(m) = t_omega(m) - t_omega0(m);
368 t_R0(i, j) = LieGroups::SO3::exp(t_omega0, t_omega0.l2())(i, j);
369
370 // Store the base rotation and add only the linearised increment to F.
371 t_R(i, j) = t_R0(i, j);
372 t_h(i, k) =
373 t_R0(i, l) *
374 (t_u(l, k) + levi_civita(l, k, m) * t_delta_omega(m));
375
376 t_approx_P_adjoint_dstretch(l, k) = t_R0(i, l) * t_approx_P(i, k);
377 t_approx_P_adjoint_log_du(L) =
378 t_approx_P_adjoint_dstretch(l, k) * t_Ldiff_u(l, k, L);
379
380 t_levi_kirchhoff(m) = t_R0(i, l) * levi_civita(l, k, m) *
381 t_approx_P(i, k);
382
384 t_h_domega(i, k, m) = t_R0(i, l) * levi_civita(l, k, m);
385 t_h_dlog_u(i, k, L) = t_R0(i, l) * t_Ldiff_u(l, k, L);
386
387 t_approx_P_adjoint_log_du_dP(i, k, L) =
388 t_R0(i, l) * t_Ldiff_u(l, k, L);
389 t_approx_P_adjoint_log_du_domega(m, L) = 0;
390
391 t_levi_kirchhoff_dstreach(m, L) = 0;
392 t_levi_kirchhoff_dP(m, i, k) =
393 t_R0(i, l) * levi_civita(l, k, m);
394 t_levi_kirchhoff_domega(m, n) = 0;
395 }
396 };
397
398 // rotation
400 case LARGE_ROT:
401 large_rot();
402 break;
403 case MODERATE_ROT:
404 moderate_rot();
405 break;
406 default:
407 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
408 "rotationSelector not handled");
409 }
410
411 next();
412 }
413
415 };
416
417 auto large_loop = [&]() {
419
421 case LARGE_ROT:
422 break;
423 case SMALL_ROT:
424 break;
425 default:
426 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
427 "rotSelector should be large or small");
428 };
429
430 for (int gg = 0; gg != nb_integration_pts; ++gg) {
431
433
436 case LARGE_ROT:
437 t_h1(i, j) = t_grad_h1(i, j) + t_kd(i, j);
438 break;
439 default:
440 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
441 "Selected grad approximator not handled");
442 };
443
444 // calculate streach
445 CHKERR calculate_log_stretch();
446 // calculate total stretch
447 CHKERR calculate_total_stretch(t_h1);
448
449 t_u_h1(l, k) = t_u(l, o) * t_h1(o, k);
450 t_diff_u_h1(i, j, k, l) = t_diff_u(i, o, k, l) * t_h1(o, j);
452 t_Ldiff_u_h1(l, k, L) = t_diff_u_h1(l, k, i, j) * t_L(i, j, L);
453
456
457 // rotation
459 case SMALL_ROT:
460 t_R(i, k) = t_kd(i, k) + levi_civita(i, k, l) * t_omega(l);
461 t_diff_R(i, j, k) = levi_civita(i, j, k);
462 t_diff_diff_R(i, j, l, m) = 0;
463 break;
464 case LARGE_ROT:
465 t_R(i, j) = LieGroups::SO3::exp(t_omega, t_omega.l2())(i, j);
466 t_diff_R(i, j, k) =
467 LieGroups::SO3::diffExp(t_omega, t_omega.l2())(i, j, k);
468 t_diff_diff_R(i, j, k, l) =
469 LieGroups::SO3::diffDiffExp(t_omega, t_omega.l2())(i, j, k, l);
470 break;
471
472 default:
473 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
474 "rotationSelector not handled");
475 }
476
477 // calculate gradient
478 t_h(i, k) = t_R(i, l) * t_u_h1(l, k);
479
480 // Adjoint stress
481 t_approx_P_adjoint_dstretch(l, o) =
482 (t_R(i, l) * t_approx_P(i, k)) * t_h1(o, k);
483 t_approx_P_adjoint_log_du(L) =
484 t_R(i, l) * t_approx_P(i, k) * t_Ldiff_u_h1(l, k, L);
485
486 // Kirchhoff stress
487 t_levi_kirchhoff(m) = t_diff_R(i, l, m) * t_u_h1(l, k) * t_approx_P(i, k);
488
490
491 t_h_domega(i, k, m) = t_diff_R(i, l, m) * t_u_h1(l, k);
492 t_h_dlog_u(i, k, L) = t_R(i, l) * t_Ldiff_u_h1(l, k, L);
493
494 t_approx_P_adjoint_log_du_dP(i, k, L) =
495 t_R(i, l) * t_Ldiff_u_h1(l, k, L);
496
498 t_A(m, L, i, k) = t_diff_R(i, l, m) * t_Ldiff_u_h1(l, k, L);
499 t_approx_P_adjoint_log_du_domega(m, L) =
500 t_A(m, L, i, k) * t_approx_P(i, k);
501
502 t_levi_kirchhoff_dstreach(m, L) =
503 t_diff_R(i, l, m) * (t_Ldiff_u_h1(l, k, L) * t_approx_P(i, k));
504
505 t_levi_kirchhoff_dP(m, i, k) = t_diff_R(i, l, m) * t_u_h1(l, k);
506 t_levi_kirchhoff_domega(m, n) =
507 t_diff_diff_R(i, l, m, n) * (t_u_h1(l, k) * t_approx_P(i, k));
508 }
509
510 next();
511 }
512
514 };
515
516 auto moderate_loop = [&]() {
518
520 case LARGE_ROT:
521 break;
522 case SMALL_ROT:
523 break;
524 default:
525 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
526 "rotSelector should be large or small");
527 };
528
529 for (int gg = 0; gg != nb_integration_pts; ++gg) {
530
532
535 case MODERATE_ROT:
536 t_h1(i, j) = t_grad_h1(i, j) + t_kd(i, j);
537 break;
538 default:
539 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
540 "Selected grad approximator not handled");
541 };
542
543 // calculate streach
544 CHKERR calculate_log_stretch();
545 // calculate total stretch
546 CHKERR calculate_total_stretch(t_h1);
547
548 auto t_diff = diff_tensor();
549
550 t_u_h1(l, k) = (t_kd(l, o) + t_log_u(l, o)) * t_h1(o, k);
551 t_diff_u_h1(i, j, k, l) = t_diff(i, o, k, l) * t_h1(o, j);
553 t_Ldiff_u_h1(l, k, L) = t_diff_u_h1(l, k, i, j) * t_L(i, j, L);
554
557
558 // rotation
560 case SMALL_ROT:
561 t_R(i, k) = t_kd(i, k) + levi_civita(i, k, l) * t_omega(l);
562 t_diff_R(i, j, k) = levi_civita(i, j, k);
563 t_diff_diff_R(i, j, l, m) = 0;
564 break;
565 case LARGE_ROT:
566 t_R(i, j) = LieGroups::SO3::exp(t_omega, t_omega.l2())(i, j);
567 t_diff_R(i, j, k) =
568 LieGroups::SO3::diffExp(t_omega, t_omega.l2())(i, j, k);
569 t_diff_diff_R(i, j, k, l) =
570 LieGroups::SO3::diffDiffExp(t_omega, t_omega.l2())(i, j, k, l);
571 break;
572
573 default:
574 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
575 "rotationSelector not handled");
576 }
577
578 // calculate gradient
579 t_h(i, k) = t_R(i, l) * t_u_h1(l, k);
580
581 // Adjoint stress
582 t_approx_P_adjoint_dstretch(l, o) =
583 (t_R(i, l) * t_approx_P(i, k)) * t_h1(o, k);
584 t_approx_P_adjoint_log_du(L) =
585 t_R(i, l) * t_approx_P(i, k) * t_Ldiff_u_h1(l, k, L);
586
587 // Kirchhoff stress
588 t_levi_kirchhoff(m) = t_diff_R(i, l, m) * t_u_h1(l, k) * t_approx_P(i, k);
589
591
592 t_h_domega(i, k, m) = t_diff_R(i, l, m) * t_u_h1(l, k);
593 t_h_dlog_u(i, k, L) = t_R(i, l) * t_Ldiff_u_h1(l, k, L);
594
595 t_approx_P_adjoint_log_du_dP(i, k, L) =
596 t_R(i, l) * t_Ldiff_u_h1(l, k, L);
597
599 t_A(m, L, i, k) = t_diff_R(i, l, m) * t_Ldiff_u_h1(l, k, L);
600 t_approx_P_adjoint_log_du_domega(m, L) =
601 t_A(m, L, i, k) * t_approx_P(i, k);
602
603 t_levi_kirchhoff_dstreach(m, L) =
604 t_diff_R(i, l, m) * (t_Ldiff_u_h1(l, k, L) * t_approx_P(i, k));
605
606 t_levi_kirchhoff_dP(m, i, k) = t_diff_R(i, l, m) * t_u_h1(l, k);
607 t_levi_kirchhoff_domega(m, n) =
608 t_diff_diff_R(i, l, m, n) * (t_u_h1(l, k) * t_approx_P(i, k));
609 }
610
611 next();
612 }
613
615 };
616
617 auto small_loop = [&]() {
620 case SMALL_ROT:
621 break;
622 default:
623 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
624 "rotSelector should be small");
625 };
626
627 for (int gg = 0; gg != nb_integration_pts; ++gg) {
628
631 case SMALL_ROT:
632 t_h1(i, j) = t_kd(i, j);
633 break;
634 default:
635 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
636 "gradApproximator not handled");
637 };
638
641 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
642 "stretchSelector should be linear for small loop");
643 } else {
644 t_u(i, j) = t_symm_kd(i, j) + t_log_u(i, j);
645 t_u_h1(i, j) = t_u(i, j);
646 t_diff_u_h1(i, j, k, l) =
647 (t_kd(i, k) * t_kd(j, l) + t_kd(i, l) * t_kd(j, k));
648 t_diff_u_h1(i, j, k, l) /= 2.;
649 t_Ldiff_u(i, j, L) = t_L(i, j, L);
650 }
651 t_log_u2_h1(i, j) = 0;
652 t_log_stretch_total(i, j) = t_log_u(i, j);
653
654 t_R(i, j) = t_kd(i, j) + levi_civita(i, j, k) * t_omega(k);
655 t_h(i, j) = levi_civita(i, j, k) * t_omega(k) + t_u(i, j);
656
657 t_h_domega(i, j, k) = levi_civita(i, j, k);
658 t_h_dlog_u(i, j, L) = t_Ldiff_u(i, j, L);
659
660 // Adjoint stress
661 t_approx_P_adjoint_dstretch(i, j) = t_approx_P(i, j);
662 t_approx_P_adjoint_log_du(L) =
663 t_approx_P_adjoint_dstretch(i, j) * t_Ldiff_u(i, j, L);
664 t_approx_P_adjoint_log_du_dP(i, j, L) = t_Ldiff_u(i, j, L);
665 t_approx_P_adjoint_log_du_domega(m, L) = 0;
666
667 // Kirchhoff stress
668 t_levi_kirchhoff(k) = levi_civita(i, j, k) * t_approx_P(i, j);
669 t_levi_kirchhoff_dstreach(m, L) = 0;
670 t_levi_kirchhoff_dP(k, i, j) = levi_civita(i, j, k);
671 t_levi_kirchhoff_domega(m, n) = 0;
672
673 next();
674 }
675
677 };
678
681 CHKERR no_h1_loop();
682 break;
683 case LARGE_ROT:
684 CHKERR large_loop();
686 break;
687 case MODERATE_ROT:
688 CHKERR moderate_loop();
690 break;
691 case SMALL_ROT:
692 CHKERR small_loop();
694 break;
695 default:
696 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
697 "gradApproximator not handled");
698 break;
699 };
700
702}
703
705 EntData &data) {
709
710 auto N_InLoop = getNinTheLoop();
711 auto sensee = getSkeletonSense();
712 auto nb_gauss_pts = getGaussPts().size2();
713 auto t_normal = getFTensor1NormalsAtGaussPts();
714
715 auto t_sigma_ptr = dataAtPts->getFTensorApproxP(getGaussPts().size2());
716 auto get_tracion =
718 dataAtPts->tractionAtPts, nb_gauss_pts);
719 if (N_InLoop == 0) {
720 dataAtPts->tractionAtPts.clear();
721 }
722
723 auto t_traction = get_tracion();
724 for (int gg = 0; gg != nb_gauss_pts; gg++) {
725 t_traction(i) = t_sigma_ptr(i, j) * sensee * (t_normal(j) / t_normal.l2());
726 ++t_traction;
727 ++t_sigma_ptr;
728 ++t_normal;
729 }
730
732}
733
735 EntData &data) {
737 if (blockEntities.find(getFEEntityHandle()) == blockEntities.end()) {
739 };
743 int nb_integration_pts = getGaussPts().size2();
744 auto t_w = getFTensor0IntegrationWeight();
745 auto t_traction = dataAtPts->getFTensorTraction(nb_integration_pts);
746 auto t_coords = getFTensor1CoordsAtGaussPts();
747 auto t_spatial_disp = dataAtPts->getFTensorSmallWL2(nb_integration_pts);
748
749 FTensor::Tensor1<double, 3> t_coords_spatial{0., 0., 0.};
750 // Offset for center of mass. Can be added in the future.
751 FTensor::Tensor1<double, 3> t_off{0.0, 0.0, 0.0};
752 FTensor::Tensor1<double, 3> loc_reaction_forces{0., 0., 0.};
753 FTensor::Tensor1<double, 3> loc_moment_forces{0., 0., 0.};
754
755 for (auto gg = 0; gg != nb_integration_pts; ++gg) {
756 loc_reaction_forces(i) += (t_traction(i)) * t_w * getMeasure();
757 t_coords_spatial(i) = t_coords(i) + t_spatial_disp(i);
758 // t_coords_spatial(i) -= t_off(i);
759 loc_moment_forces(i) +=
760 (FTensor::levi_civita<double>(i, j, k) * t_coords_spatial(j)) *
761 t_traction(k) * t_w * getMeasure();
762 ++t_coords;
763 ++t_spatial_disp;
764 ++t_w;
765 ++t_traction;
766 }
767
768 reactionVec[0] += loc_reaction_forces(0);
769 reactionVec[1] += loc_reaction_forces(1);
770 reactionVec[2] += loc_reaction_forces(2);
771 reactionVec[3] += loc_moment_forces(0);
772 reactionVec[4] += loc_moment_forces(1);
773 reactionVec[5] += loc_moment_forces(2);
774
776}
777
780 int nb_dofs = data.getIndices().size();
781 int nb_integration_pts = data.getN().size1();
782 auto v = getVolume();
783 auto t_w = getFTensor0IntegrationWeight();
784 auto t_div_P = dataAtPts->getFTensorDivP(nb_integration_pts);
785 auto t_s_dot_w = dataAtPts->getFTensorSmallWL2Dot(nb_integration_pts);
786 auto w_l2_dot_dot_at_pts = dataAtPts->getSmallWL2DotDotAtPts();
787 const bool reset_w_l2_dot_dot =
788 w_l2_dot_dot_at_pts->size1() != nb_integration_pts ||
789 w_l2_dot_dot_at_pts->size2() != 3;
791 *w_l2_dot_dot_at_pts, nb_integration_pts);
792 if (reset_w_l2_dot_dot) {
793 w_l2_dot_dot_at_pts->clear();
794 }
795 auto t_s_dot_dot_w = dataAtPts->getFTensorSmallWL2DotDot(nb_integration_pts);
796
797 auto piola_scale = dataAtPts->piolaScale;
798 auto alpha_w = alphaW / piola_scale;
799 auto alpha_rho = alphaRho / piola_scale;
800
801 int nb_base_functions = data.getN().size2();
802 auto t_row_base_fun = data.getFTensor0N();
803
804 FTensor::Index<'i', 3> i;
805 auto get_ftensor1 = [](auto &v) {
807 &v[2]);
808 };
809
810 auto next = [&]() {
811 ++t_w;
812 ++t_div_P;
813 ++t_s_dot_w;
814 ++t_s_dot_dot_w;
815 };
816
817 for (int gg = 0; gg != nb_integration_pts; ++gg) {
818 double a = v * t_w;
819 auto t_nf = get_ftensor1(nF);
820 int bb = 0;
821 for (; bb != nb_dofs / 3; ++bb) {
822 t_nf(i) -= a * t_row_base_fun * t_div_P(i);
823 t_nf(i) += a * t_row_base_fun * alpha_w * t_s_dot_w(i);
824 t_nf(i) += a * t_row_base_fun * alpha_rho * t_s_dot_dot_w(i);
825 ++t_nf;
826 ++t_row_base_fun;
827 }
828 for (; bb != nb_base_functions; ++bb)
829 ++t_row_base_fun;
830 next();
831 }
832
834}
835
838 int nb_dofs = data.getIndices().size();
839 int nb_integration_pts = getGaussPts().size2();
840 auto v = getVolume();
841 auto t_w = getFTensor0IntegrationWeight();
842 auto t_levi_kirchhoff =
843 dataAtPts->getFTensorLeviKirchhoff(nb_integration_pts);
844 auto t_omega_grad_dot =
845 dataAtPts->getFTensorRotAxisGradDot(nb_integration_pts);
846 int nb_base_functions = data.getN().size2();
847 auto t_row_base_fun = data.getFTensor0N();
848 auto t_row_grad_fun = data.getFTensor1DiffN<3>();
849 FTensor::Index<'i', 3> i;
850 FTensor::Index<'j', 3> j;
851 FTensor::Index<'k', 3> k;
852 auto get_ftensor1 = [](auto &v) {
854 &v[2]);
855 };
856 // auto time_step = getTStimeStep();
857
858 for (int gg = 0; gg != nb_integration_pts; ++gg) {
859
860 double a = v * t_w;
861 auto t_nf = get_ftensor1(nF);
862 int bb = 0;
863 for (; bb != nb_dofs / 3; ++bb) {
864 t_nf(k) -= (a * t_row_base_fun) * t_levi_kirchhoff(k);
865 t_nf(k) += (a * alphaOmega /*/ time_step*/) *
866 (t_row_grad_fun(i) * t_omega_grad_dot(k, i));
867 ++t_nf;
868 ++t_row_base_fun;
869 ++t_row_grad_fun;
870 }
871 for (; bb != nb_base_functions; ++bb) {
872 ++t_row_base_fun;
873 ++t_row_grad_fun;
874 }
875 ++t_w;
876 ++t_levi_kirchhoff;
877 ++t_omega_grad_dot;
878 }
880}
881
884 int nb_dofs = data.getIndices().size();
885 int nb_integration_pts = data.getN().size1();
886 auto v = getVolume();
887 auto t_w = getFTensor0IntegrationWeight();
888
889 int nb_base_functions = data.getN().size2() / 3;
890 auto t_row_base_fun = data.getFTensor1N<3>();
891 FTENSOR_INDEX(3, i);
892 FTENSOR_INDEX(3, j);
893 FTENSOR_INDEX(3, k);
894 FTENSOR_INDEX(3, m);
895 FTENSOR_INDEX(3, l);
896
897 auto get_ftensor1 = [](auto &v) {
899 &v[2]);
900 };
901
902 auto t_h = dataAtPts->getFTensorSmallH(nb_integration_pts);
903
904 for (int gg = 0; gg != nb_integration_pts; ++gg) {
905 double a = v * t_w;
906 auto t_nf = get_ftensor1(nF);
907
908 constexpr auto t_kd = FTensor::Kronecker_Delta<double>();
910
911 t_residuum(i, j) = t_h(i, j) - t_kd(i, j);
912
913 int bb = 0;
914 for (; bb != nb_dofs / 3; ++bb) {
915 t_nf(i) -= a * t_row_base_fun(j) * t_residuum(i, j);
916 ++t_nf;
917 ++t_row_base_fun;
918 }
919
920 for (; bb != nb_base_functions; ++bb)
921 ++t_row_base_fun;
922
923 ++t_w;
924 ++t_h;
925 }
926
928}
929
932 int nb_dofs = data.getIndices().size();
933 int nb_integration_pts = data.getN().size1();
934 auto v = getVolume();
935 auto t_w = getFTensor0IntegrationWeight();
936
937 int nb_base_functions = data.getN().size2() / 9;
938 auto t_row_base_fun = data.getFTensor2N<3, 3>();
939 FTENSOR_INDEX(3, i);
940 FTENSOR_INDEX(3, j);
941 FTENSOR_INDEX(3, k);
942 FTENSOR_INDEX(3, m);
943 FTENSOR_INDEX(3, l);
944
945 auto get_ftensor0 = [](auto &v) {
947 };
948
949 auto t_h = dataAtPts->getFTensorSmallH(nb_integration_pts);
950
951 for (int gg = 0; gg != nb_integration_pts; ++gg) {
952 double a = v * t_w;
953 auto t_nf = get_ftensor0(nF);
954
955 constexpr auto t_kd = FTensor::Kronecker_Delta<double>();
957 t_residuum(i, j) = t_h(i, j);
958
959 int bb = 0;
960 for (; bb != nb_dofs; ++bb) {
961 t_nf -= a * t_row_base_fun(i, j) * t_residuum(i, j);
962 ++t_nf;
963 ++t_row_base_fun;
964 }
965 for (; bb != nb_base_functions; ++bb) {
966 ++t_row_base_fun;
967 }
968 ++t_w;
969 ++t_h;
970 }
971
973}
974
977 int nb_dofs = data.getIndices().size();
978 int nb_integration_pts = data.getN().size1();
979 auto v = getVolume();
980 auto t_w = getFTensor0IntegrationWeight();
981 auto t_w_l2 = dataAtPts->getFTensorSmallWL2(nb_integration_pts);
982 int nb_base_functions = data.getN().size2() / 3;
983 auto t_row_diff_base_fun = data.getFTensor2DiffN<3, 3>();
984 FTensor::Index<'i', 3> i;
985 auto get_ftensor1 = [](auto &v) {
987 &v[2]);
988 };
989
990 for (int gg = 0; gg != nb_integration_pts; ++gg) {
991 double a = v * t_w;
992 auto t_nf = get_ftensor1(nF);
993 int bb = 0;
994 for (; bb != nb_dofs / 3; ++bb) {
995 double div_row_base = t_row_diff_base_fun(i, i);
996 t_nf(i) -= a * div_row_base * t_w_l2(i);
997 ++t_nf;
998 ++t_row_diff_base_fun;
999 }
1000 for (; bb != nb_base_functions; ++bb) {
1001 ++t_row_diff_base_fun;
1002 }
1003 ++t_w;
1004 ++t_w_l2;
1005 }
1006
1008}
1009
1010template <>
1012 EntData &data) {
1014
1015 int nb_integration_pts = getGaussPts().size2();
1016
1017 Tag tag;
1018 CHKERR getPtrFE() -> mField.get_moab().tag_get_handle(tagName.c_str(), tag);
1019 int tag_length;
1020 CHKERR getPtrFE() -> mField.get_moab().tag_get_length(tag, tag_length);
1021 if (tag_length != 9) {
1022 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1023 "Number of internal stress components should be 9 but is %d",
1024 tag_length);
1025 }
1026
1027 VectorDouble const_stress_vec(9);
1028 auto fe_ent = getNumeredEntFiniteElementPtr()->getEnt();
1029 CHKERR getPtrFE() -> mField.get_moab().tag_get_data(
1030 tag, &fe_ent, 1, &*const_stress_vec.data().begin());
1031 auto t_const_stress = getFTensor1FromArray<9, 9>(const_stress_vec);
1032
1033 auto get_internal_stress =
1035 dataAtPts->internalStressAtPts, nb_integration_pts);
1036 dataAtPts->internalStressAtPts.clear();
1037 auto t_internal_stress = get_internal_stress();
1038
1039 FTensor::Index<'L', 9> L;
1040 for (int gg = 0; gg != nb_integration_pts; ++gg) {
1041 t_internal_stress(L) = t_const_stress(L);
1042 ++t_internal_stress;
1043 }
1044
1046}
1047
1048template <>
1050 EntData &data) {
1052
1053 int nb_integration_pts = getGaussPts().size2();
1054
1055 Tag tag;
1056 CHKERR getPtrFE() -> mField.get_moab().tag_get_handle(tagName.c_str(), tag);
1057 int tag_length;
1058 CHKERR getPtrFE() -> mField.get_moab().tag_get_length(tag, tag_length);
1059 if (tag_length != 9) {
1060 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1061 "Number of internal stress components should be 9 but is %d",
1062 tag_length);
1063 }
1064
1065 auto fe_ent = getNumeredEntFiniteElementPtr()->getEnt();
1066 const EntityHandle *vert_conn;
1067 int vert_num;
1068 CHKERR getPtrFE() -> mField.get_moab().get_connectivity(fe_ent, vert_conn,
1069 vert_num, true);
1070 VectorDouble vert_data(vert_num * tag_length);
1071 CHKERR getPtrFE() -> mField.get_moab().tag_get_data(tag, vert_conn, vert_num,
1072 &vert_data[0]);
1073
1074 auto get_internal_stress =
1076 dataAtPts->internalStressAtPts, nb_integration_pts);
1077 dataAtPts->internalStressAtPts.clear();
1078 auto t_internal_stress = get_internal_stress();
1079
1080 auto t_shape_n = data.getFTensor0N();
1081 int nb_shape_fn = data.getN(NOBASE).size2();
1082 FTensor::Index<'L', 9> L;
1083 for (int gg = 0; gg != nb_integration_pts; ++gg) {
1084 auto t_vert_data = getFTensor1FromArray<9, 9>(vert_data);
1085 for (int bb = 0; bb != nb_shape_fn; ++bb) {
1086 t_internal_stress(L) += t_vert_data(L) * t_shape_n;
1087 ++t_vert_data;
1088 ++t_shape_n;
1089 }
1090 ++t_internal_stress;
1091 }
1092
1094}
1095
1096template <>
1100
1101 int nb_dofs = data.getIndices().size();
1102 int nb_integration_pts = data.getN().size1();
1103 auto v = getVolume();
1104 auto t_w = getFTensor0IntegrationWeight();
1105
1106 FTensor::Index<'i', 3> i;
1107 FTensor::Index<'j', 3> j;
1108
1109 auto get_ftensor2 = [](auto &v) {
1111 &v[0], &v[1], &v[2], &v[3], &v[4], &v[5]);
1112 };
1113
1114 auto t_internal_stress =
1115 dataAtPts->getFTensorInternalStress(nb_integration_pts);
1116
1117 const double time = EshelbianCore::physicalTimeFlg
1119 : getFEMethod()->ts_t;
1120
1121 // default scaling is constant
1122 double scale = scalingMethodPtr->getScale(time);
1123
1125 auto t_L = symm_L_tensor();
1126
1127 int nb_base_functions = data.getN().size2();
1128 auto t_row_base_fun = data.getFTensor0N();
1129 for (int gg = 0; gg != nb_integration_pts; ++gg) {
1130 double a = v * t_w;
1131 auto t_nf = get_ftensor2(nF);
1132
1133 FTensor::Tensor2<double, 3, 3> t_symm_stress;
1134 t_symm_stress(i, j) =
1135 (t_internal_stress(i, j) + t_internal_stress(j, i)) / 2;
1136
1138 t_residual(L) = t_L(i, j, L) * (scale * t_symm_stress(i, j));
1139
1140 int bb = 0;
1141 for (; bb != nb_dofs / 6; ++bb) {
1142 t_nf(L) += a * t_row_base_fun * t_residual(L);
1143 ++t_nf;
1144 ++t_row_base_fun;
1145 }
1146 for (; bb != nb_base_functions; ++bb)
1147 ++t_row_base_fun;
1148
1149 ++t_w;
1150 ++t_internal_stress;
1151 }
1153}
1154
1155template <>
1158
1159 int nb_dofs = data.getIndices().size();
1160 int nb_integration_pts = data.getN().size1();
1161 auto v = getVolume();
1162 auto t_w = getFTensor0IntegrationWeight();
1163
1164 auto get_ftensor2 = [](auto &v) {
1166 &v[0], &v[1], &v[2], &v[3], &v[4], &v[5]);
1167 };
1168
1169 auto t_internal_stress =
1170 dataAtPts->getFTensorInternalStressVec(nb_integration_pts);
1171
1175 t_L = voigt_to_symm();
1176
1177 const double time = EshelbianCore::physicalTimeFlg
1179 : getFEMethod()->ts_t;
1180
1181 // default is constant
1182 double scale = scalingMethodPtr->getScale(time);
1183
1184 int nb_base_functions = data.getN().size2();
1185 auto t_row_base_fun = data.getFTensor0N();
1186 for (int gg = 0; gg != nb_integration_pts; ++gg) {
1187 double a = v * t_w;
1188 auto t_nf = get_ftensor2(nF);
1189
1191 t_residual(L) = t_L(M, L) * (scale * t_internal_stress(M));
1192
1193 int bb = 0;
1194 for (; bb != nb_dofs / 6; ++bb) {
1195 t_nf(L) += a * t_row_base_fun * t_residual(L);
1196 ++t_nf;
1197 ++t_row_base_fun;
1198 }
1199 for (; bb != nb_base_functions; ++bb)
1200 ++t_row_base_fun;
1201
1202 ++t_w;
1203 ++t_internal_stress;
1204 }
1206}
1207
1208template <AssemblyType A>
1211 // get entity of face
1212 EntityHandle fe_ent = OP::getFEEntityHandle();
1213 // iterate over all boundary data
1214 for (auto &bc : (*bcDispPtr)) {
1215 // check if finite element entity is part of boundary condition
1216 if (bc.faces.find(fe_ent) != bc.faces.end()) {
1217 int nb_dofs = data.getIndices().size();
1218
1219 int nb_integration_pts = OP::getGaussPts().size2();
1220 auto t_normal = OP::getFTensor1NormalsAtGaussPts();
1221 auto t_w = OP::getFTensor0IntegrationWeight();
1222 int nb_base_functions = data.getN().size2() / 3;
1223 auto t_row_base_fun = data.getFTensor1N<3>();
1224
1227
1228 double scale = 1;
1229 if (scalingMethodsMap.find(bc.blockName) != scalingMethodsMap.end()) {
1231 scale *= scalingMethodsMap.at(bc.blockName)
1233 } else {
1234 scale *= scalingMethodsMap.at(bc.blockName)
1235 ->getScale(OP::getFEMethod()->ts_t);
1236 }
1237 } else {
1238 MOFEM_LOG("SELF", Sev::warning)
1239 << "No scaling method found for " << bc.blockName;
1240 }
1241
1242 // get bc data
1243 FTensor::Tensor1<double, 3> t_bc_disp(bc.vals[0], bc.vals[1], bc.vals[2]);
1244 t_bc_disp(i) *= scale;
1245
1246 for (int gg = 0; gg != nb_integration_pts; ++gg) {
1247 auto t_nf = getFTensor1FromPtr<3>(&*OP::locF.begin());
1248 int bb = 0;
1249 for (; bb != nb_dofs / SPACE_DIM; ++bb) {
1250 t_nf(i) +=
1251 t_w * (t_row_base_fun(j) * t_normal(j)) * t_bc_disp(i) * 0.5;
1252 ++t_nf;
1253 ++t_row_base_fun;
1254 }
1255 for (; bb != nb_base_functions; ++bb)
1256 ++t_row_base_fun;
1257
1258 ++t_w;
1259 ++t_normal;
1260 }
1261 }
1262 }
1264}
1265
1267 return OP::iNtegrate(data);
1268}
1269
1272 // get entity of face
1273 EntityHandle fe_ent = OP::getFEEntityHandle();
1274 // iterate over all boundary data
1275 for (auto &bc : (*bcDispPtr)) {
1276 // check if finite element entity is part of boundary condition
1277 if (bc.faces.find(fe_ent) != bc.faces.end()) {
1278 int nb_dofs = data.getIndices().size();
1279
1280 int nb_integration_pts = OP::getGaussPts().size2();
1281 auto t_w = OP::getFTensor0IntegrationWeight();
1282 int nb_base_functions = data.getN().size2();
1283 auto t_row_base_fun = data.getFTensor0N();
1284#ifndef NDEBUG
1285 if (!this->sourceVec) {
1286 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1287 "Source vector for OpTauStabilizationDispRhsBc is not set");
1288 }
1289 if (data.getN().size1() != nb_integration_pts) {
1290 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1291 "Number of integration points in data should be %d but is %d",
1292 nb_integration_pts, (int)data.getN().size1());
1293 }
1294 if (nb_base_functions < nb_dofs / SPACE_DIM) {
1295 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1296 "Number of base functions in data should be %d but is %d",
1297 nb_base_functions, (int)data.getN().size2() / SPACE_DIM);
1298 }
1299
1300#endif
1301
1302 auto t_disp_val =
1304 *this->sourceVec, nb_integration_pts)();
1305
1308
1309 double scale = 1;
1310 if (scalingMethodsMap.find(bc.blockName) != scalingMethodsMap.end()) {
1312 scale *= scalingMethodsMap.at(bc.blockName)
1314 } else {
1315 scale *= scalingMethodsMap.at(bc.blockName)
1316 ->getScale(OP::getFEMethod()->ts_t);
1317 }
1318 } else {
1319 MOFEM_LOG("SELF", Sev::warning)
1320 << "No scaling method found for " << bc.blockName;
1321 }
1322
1323 // get bc data
1324 FTensor::Tensor1<double, 3> t_bc_disp(bc.vals[0], bc.vals[1], bc.vals[2]);
1325 t_bc_disp(i) *= scale;
1326
1327 auto area = getMeasure();
1328 auto t_coords = OP::getFTensor1CoordsAtGaussPts();
1329 for (int gg = 0; gg != nb_integration_pts; ++gg) {
1330 auto tau_scale =
1331 area * t_w * OP::betaCoeff(t_coords(0), t_coords(1), t_coords(2));
1332 auto t_nf = getFTensor1FromPtr<3, 3>(OP::locF.data().data());
1333 int bb = 0;
1334 for (; bb != nb_dofs / SPACE_DIM; ++bb) {
1335 for (auto ii = 0; ii != SPACE_DIM; ++ii) {
1336 if (bc.flags[ii]) {
1337 t_nf(ii) += (tau_scale * t_row_base_fun) *
1338 (t_disp_val(ii) - t_bc_disp(ii));
1339 }
1340 }
1341 ++t_nf;
1342 ++t_row_base_fun;
1343 }
1344 for (; bb != nb_base_functions; ++bb)
1345 ++t_row_base_fun;
1346
1347 ++t_w;
1348 ++t_coords;
1349 ++t_disp_val;
1350 }
1351 }
1352 }
1353
1355}
1356
1358 EntData &col_data) {
1360 // get entity of face
1361 EntityHandle fe_ent = OP::getFEEntityHandle();
1362 // iterate over all boundary data
1363 for (auto &bc : (*bcDispPtr)) {
1364 // check if finite element entity is part of boundary condition
1365 if (bc.faces.find(fe_ent) != bc.faces.end()) {
1366 int nb_dofs = row_data.getIndices().size();
1367
1368 int nb_integration_pts = OP::getGaussPts().size2();
1369 auto t_w = OP::getFTensor0IntegrationWeight();
1370 int nb_base_functions = row_data.getN().size2();
1371 auto t_row_base_fun = row_data.getFTensor0N();
1372
1375
1376 auto get_t_vec = [&](const int rr) {
1377 std::array<double *, SPACE_DIM> ptrs;
1378 for (auto i = 0; i != SPACE_DIM; ++i)
1379 ptrs[i] = &OP::locMat(rr + i, i);
1381 SPACE_DIM>(ptrs);
1382 };
1383
1384 auto area = getMeasure();
1385 auto t_coords = OP::getFTensor1CoordsAtGaussPts();
1386 for (int gg = 0; gg != nb_integration_pts; ++gg) {
1387 auto tau_scale =
1388 area * t_w * OP::betaCoeff(t_coords(0), t_coords(1), t_coords(2));
1389 int rr = 0;
1390 for (; rr != nb_dofs / SPACE_DIM; ++rr) {
1391 auto t_mat = get_t_vec(SPACE_DIM * rr);
1392 auto t_col_base_fun = col_data.getFTensor0N(gg, 0);
1393 for (int cc = 0; cc != nb_dofs / SPACE_DIM; ++cc) {
1394 for (int ii = 0; ii != SPACE_DIM; ++ii) {
1395 if (bc.flags[ii]) {
1396 t_mat(ii) += tau_scale * (t_row_base_fun * t_col_base_fun);
1397 }
1398 }
1399 ++t_col_base_fun;
1400 ++t_mat;
1401 }
1402 ++t_row_base_fun;
1403 }
1404 for (; rr != nb_base_functions; ++rr)
1405 ++t_row_base_fun;
1406
1407 ++t_w;
1408 ++t_coords;
1409 }
1410 }
1411 }
1412
1414}
1415
1418
1419 EntityHandle fe_ent = OP::getFEEntityHandle();
1420 for (auto &bc : (*bcDispPtr)) {
1421 if (bc.faces.find(fe_ent) != bc.faces.end()) {
1423 auto analytical_data = getAnalyticalExpr(this, analytical_expr, bc.blockName);
1424 auto &v_analytical_expr = std::get<1>(analytical_data);
1425
1426 int nb_dofs = data.getIndices().size();
1427 int nb_integration_pts = OP::getGaussPts().size2();
1428 auto t_w = OP::getFTensor0IntegrationWeight();
1429 int nb_base_functions = data.getN().size2();
1430 auto t_row_base_fun = data.getFTensor0N();
1431
1432#ifndef NDEBUG
1433 if (!this->sourceVec) {
1434 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1435 "Source vector for OpTauStabilizationOpAnalyticalDispBc is not "
1436 "set");
1437 }
1438 if (data.getN().size1() != nb_integration_pts) {
1439 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1440 "Number of integration points in data should be %d but is %d",
1441 nb_integration_pts, (int)data.getN().size1());
1442 }
1443 if (nb_base_functions < nb_dofs / SPACE_DIM) {
1444 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1445 "Number of base functions in data should be at least %d but is "
1446 "%d",
1447 nb_dofs / SPACE_DIM, nb_base_functions);
1448 }
1449#endif
1450
1451 auto t_disp_val =
1453 *this->sourceVec, nb_integration_pts)();
1454 auto t_bc_disp = getFTensor1FromMat<3, -1, DL>(v_analytical_expr);
1455
1456 auto area = getMeasure();
1457 auto t_coords = OP::getFTensor1CoordsAtGaussPts();
1458 for (int gg = 0; gg != nb_integration_pts; ++gg) {
1459 auto tau_scale =
1460 area * t_w * OP::betaCoeff(t_coords(0), t_coords(1), t_coords(2));
1461 auto t_nf = getFTensor1FromPtr<3, 3>(OP::locF.data().data());
1462 int bb = 0;
1463 for (; bb != nb_dofs / SPACE_DIM; ++bb) {
1464 for (auto ii = 0; ii != SPACE_DIM; ++ii) {
1465 if (bc.flags[ii]) {
1466 t_nf(ii) +=
1467 (tau_scale * t_row_base_fun) * (t_disp_val(ii) - t_bc_disp(ii));
1468 }
1469 }
1470 ++t_nf;
1471 ++t_row_base_fun;
1472 }
1473 for (; bb != nb_base_functions; ++bb)
1474 ++t_row_base_fun;
1475
1476 ++t_w;
1477 ++t_coords;
1478 ++t_disp_val;
1479 ++t_bc_disp;
1480 }
1481 }
1482 }
1483
1485}
1486
1488 EntData &row_data, EntData &col_data) {
1490
1491 EntityHandle fe_ent = OP::getFEEntityHandle();
1492 for (auto &bc : (*bcDispPtr)) {
1493 if (bc.faces.find(fe_ent) != bc.faces.end()) {
1494 int nb_dofs = row_data.getIndices().size();
1495 int nb_integration_pts = OP::getGaussPts().size2();
1496 auto t_w = OP::getFTensor0IntegrationWeight();
1497 int nb_base_functions = row_data.getN().size2();
1498 auto t_row_base_fun = row_data.getFTensor0N();
1499
1500 auto get_t_vec = [&](const int rr) {
1501 std::array<double *, SPACE_DIM> ptrs;
1502 for (auto i = 0; i != SPACE_DIM; ++i)
1503 ptrs[i] = &OP::locMat(rr + i, i);
1505 SPACE_DIM>(ptrs);
1506 };
1507
1508 auto area = getMeasure();
1509 auto t_coords = OP::getFTensor1CoordsAtGaussPts();
1510 for (int gg = 0; gg != nb_integration_pts; ++gg) {
1511 auto tau_scale =
1512 area * t_w * OP::betaCoeff(t_coords(0), t_coords(1), t_coords(2));
1513 int rr = 0;
1514 for (; rr != nb_dofs / SPACE_DIM; ++rr) {
1515 auto t_mat = get_t_vec(SPACE_DIM * rr);
1516 auto t_col_base_fun = col_data.getFTensor0N(gg, 0);
1517 for (int cc = 0; cc != nb_dofs / SPACE_DIM; ++cc) {
1518 for (int ii = 0; ii != SPACE_DIM; ++ii) {
1519 if (bc.flags[ii]) {
1520 t_mat(ii) += tau_scale * (t_row_base_fun * t_col_base_fun);
1521 }
1522 }
1523 ++t_col_base_fun;
1524 ++t_mat;
1525 }
1526 ++t_row_base_fun;
1527 }
1528 for (; rr != nb_base_functions; ++rr)
1529 ++t_row_base_fun;
1530
1531 ++t_w;
1532 ++t_coords;
1533 }
1534 }
1535 }
1536
1538}
1539
1540template <AssemblyType A>
1543
1544 FTENSOR_INDEX(3, i);
1545 FTENSOR_INDEX(3, j);
1546 FTENSOR_INDEX(3, k);
1547
1548 double time = OP::getFEMethod()->ts_t;
1551 }
1552
1553 // get entity of face
1554 EntityHandle fe_ent = OP::getFEEntityHandle();
1555 // interate over all boundary data
1556 for (auto &bc : (*bcRotPtr)) {
1557 // check if finite element entity is part of boundary condition
1558 if (bc.faces.find(fe_ent) != bc.faces.end()) {
1559 int nb_dofs = data.getIndices().size();
1560 int nb_integration_pts = OP::getGaussPts().size2();
1561 auto t_normal = OP::getFTensor1NormalsAtGaussPts();
1562 auto t_w = OP::getFTensor0IntegrationWeight();
1563
1564 int nb_base_functions = data.getN().size2() / 3;
1565 auto t_row_base_fun = data.getFTensor1N<3>();
1566
1567 auto get_ftensor1 = [](auto &v) {
1569 &v[2]);
1570 };
1571
1572 // Note: First three values of bc.vals are the center of rotation
1573 // 4th is rotation angle in radians, and remaining values are axis of
1574 // rotation. Also, if rotation axis is not provided, it defaults to the
1575 // normal vector of the face.
1576
1577 // get bc data
1578 FTensor::Tensor1<double, 3> t_center(bc.vals[0], bc.vals[1], bc.vals[2]);
1579
1580 auto get_rotation_angle = [&]() {
1581 double theta = bc.theta;
1582 if (scalingMethodsMap.find(bc.blockName) != scalingMethodsMap.end()) {
1583 theta *= scalingMethodsMap.at(bc.blockName)->getScale(time);
1584 }
1585 return theta;
1586 };
1587
1588 auto get_rotation = [&](auto theta) {
1590 if (bc.vals.size() == 7) {
1591 t_omega(0) = bc.vals[4];
1592 t_omega(1) = bc.vals[5];
1593 t_omega(2) = bc.vals[6];
1594 } else {
1595 // Use gemetric face normal as rotation axis
1596 t_omega(i) = OP::getFTensor1Normal()(i);
1597 }
1598 if (t_omega.l2() > std::numeric_limits<double>::epsilon()) {
1599 t_omega.normalize();
1600 } else {
1601 MOFEM_LOG("SELF", Sev::warning)
1602 << "Rotation axis is zero vector for block " << bc.blockName
1603 << ". This may lead to unexpected results.";
1604 }
1605 t_omega(i) *= theta;
1608 ? 0.
1609 : t_omega.l2());
1610 };
1611
1612 auto t_R = get_rotation(get_rotation_angle());
1613 auto t_coords = OP::getFTensor1CoordsAtGaussPts();
1614
1615 for (int gg = 0; gg != nb_integration_pts; ++gg) {
1617 t_delta(i) = t_center(i) - t_coords(i);
1619 t_disp(i) = t_delta(i) - t_R(i, j) * t_delta(j);
1620
1621 auto t_nf = getFTensor1FromPtr<3>(&*OP::locF.begin());
1622 int bb = 0;
1623 for (; bb != nb_dofs / SPACE_DIM; ++bb) {
1624 t_nf(i) += t_w * (t_row_base_fun(j) * t_normal(j)) * t_disp(i) * 0.5;
1625 ++t_nf;
1626 ++t_row_base_fun;
1627 }
1628 for (; bb != nb_base_functions; ++bb)
1629 ++t_row_base_fun;
1630
1631 ++t_w;
1632 ++t_normal;
1633 ++t_coords;
1634 }
1635 }
1636 }
1638}
1639
1641 return OP::iNtegrate(data);
1642}
1643
1646
1647 FTENSOR_INDEX(3, i);
1648 FTENSOR_INDEX(3, j);
1649
1650 double time = OP::getFEMethod()->ts_t;
1653 }
1654
1655 // get entity of face
1656 EntityHandle fe_ent = OP::getFEEntityHandle();
1657 // iterate over all boundary data
1658 for (auto &bc : (*bcRotPtr)) {
1659 // check if finite element entity is part of boundary condition
1660 if (bc.faces.find(fe_ent) != bc.faces.end()) {
1661 int nb_dofs = data.getIndices().size();
1662 int nb_integration_pts = OP::getGaussPts().size2();
1663 auto t_w = OP::getFTensor0IntegrationWeight();
1664
1665 int nb_base_functions = data.getN().size2();
1666 auto t_row_base_fun = data.getFTensor0N();
1667
1668 auto get_ftensor1 = [](auto &v) {
1670 &v[2]);
1671 };
1672
1673 // Note: First three values of bc.vals are the center of rotation
1674 // 4th is rotation angle in radians, and remaining values are axis of
1675 // rotation. Also, if rotation axis is not provided, it defaults to the
1676 // normal vector of the face.
1677
1678 // get bc data
1679 FTensor::Tensor1<double, 3> t_center(bc.vals[0], bc.vals[1], bc.vals[2]);
1680
1681 auto get_rotation_angle = [&]() {
1682 double theta = bc.theta;
1683 if (scalingMethodsMap.find(bc.blockName) != scalingMethodsMap.end()) {
1684 theta *= scalingMethodsMap.at(bc.blockName)->getScale(time);
1685 }
1686 return theta;
1687 };
1688
1689 auto get_rotation = [&](auto theta) {
1691 if (bc.vals.size() == 7) {
1692 t_omega(0) = bc.vals[4];
1693 t_omega(1) = bc.vals[5];
1694 t_omega(2) = bc.vals[6];
1695 } else {
1696 // Use gemetric face normal as rotation axis
1697 t_omega(i) = OP::getFTensor1Normal()(i);
1698 }
1699 if (t_omega.l2() > std::numeric_limits<double>::epsilon()) {
1700 t_omega.normalize();
1701 }
1702 t_omega(i) *= theta;
1705 ? 0.
1706 : t_omega.l2());
1707 };
1708
1709 auto area = getMeasure();
1710 auto t_R = get_rotation(get_rotation_angle());
1711 auto t_coords = OP::getFTensor1CoordsAtGaussPts();
1712 auto t_disp_val =
1714 *this->sourceVec, nb_integration_pts)();
1715
1716 for (int gg = 0; gg != nb_integration_pts; ++gg) {
1717 auto tau_scale =
1718 area * t_w * OP::betaCoeff(t_coords(0), t_coords(1), t_coords(2));
1719
1721 t_delta(i) = t_center(i) - t_coords(i);
1723 t_bc_disp(i) = t_delta(i) - t_R(i, j) * t_delta(j);
1724
1725 auto t_nf = getFTensor1FromPtr<3>(&*OP::locF.begin());
1726 int bb = 0;
1727 for (; bb != nb_dofs / SPACE_DIM; ++bb) {
1728 t_nf(i) +=
1729 (tau_scale * t_row_base_fun) * (t_disp_val(i) - t_bc_disp(i));
1730 ++t_nf;
1731 ++t_row_base_fun;
1732 }
1733 for (; bb != nb_base_functions; ++bb)
1734 ++t_row_base_fun;
1735
1736 ++t_w;
1737 ++t_coords;
1738 ++t_disp_val;
1739 }
1740 }
1741 }
1742
1744}
1745
1747 EntData &col_data) {
1749 // get entity of face
1750 EntityHandle fe_ent = OP::getFEEntityHandle();
1751 // iterate over all boundary data
1752 for (auto &bc : (*bcRotPtr)) {
1753 // check if finite element entity is part of boundary condition
1754 if (bc.faces.find(fe_ent) != bc.faces.end()) {
1755 int nb_dofs = row_data.getIndices().size();
1756
1757 int nb_integration_pts = OP::getGaussPts().size2();
1758 auto t_w = OP::getFTensor0IntegrationWeight();
1759 int nb_base_functions = row_data.getN().size2();
1760 auto t_row_base_fun = row_data.getFTensor0N();
1761
1764
1765 auto get_t_vec = [&](const int rr) {
1766 std::array<double *, SPACE_DIM> ptrs;
1767 for (auto i = 0; i != SPACE_DIM; ++i)
1768 ptrs[i] = &OP::locMat(rr + i, i);
1770 SPACE_DIM>(ptrs);
1771 };
1772
1773 auto area = getMeasure();
1774 auto t_coords = OP::getFTensor1CoordsAtGaussPts();
1775 for (int gg = 0; gg != nb_integration_pts; ++gg) {
1776 auto tau_scale =
1777 area * t_w * OP::betaCoeff(t_coords(0), t_coords(1), t_coords(2));
1778 int rr = 0;
1779 for (; rr != nb_dofs / SPACE_DIM; ++rr) {
1780 auto t_mat = get_t_vec(SPACE_DIM * rr);
1781 auto t_col_base_fun = col_data.getFTensor0N(gg, 0);
1782 for (int cc = 0; cc != nb_dofs / SPACE_DIM; ++cc) {
1783 for (int ii = 0; ii != SPACE_DIM; ++ii) {
1784 t_mat(ii) += tau_scale * (t_row_base_fun * t_col_base_fun);
1785 }
1786 ++t_col_base_fun;
1787 ++t_mat;
1788 }
1789 ++t_row_base_fun;
1790 }
1791 for (; rr != nb_base_functions; ++rr)
1792 ++t_row_base_fun;
1793
1794 ++t_w;
1795 ++t_coords;
1796 }
1797 }
1798 }
1799
1801}
1802
1803template <AssemblyType A>
1806
1807 double time = OP::getFEMethod()->ts_t;
1810 }
1811
1812 // get entity of face
1813 EntityHandle fe_ent = OP::getFEEntityHandle();
1814 // iterate over all boundary data
1815 for (auto &bc : (*bcDispPtr)) {
1816 // check if finite element entity is part of boundary condition
1817 if (bc.faces.find(fe_ent) != bc.faces.end()) {
1818
1819 for (auto &bd : (*brokenBaseSideDataPtr)) {
1820
1821 auto t_approx_P = getFTensor2FromMat<3, 3, -1, DL>(bd.getFlux());
1822 auto t_u = getFTensor1FromMat<3, -1, DL>(*hybridDispPtr);
1823 auto t_normal = OP::getFTensor1NormalsAtGaussPts();
1824 auto t_w = OP::getFTensor0IntegrationWeight();
1825
1828
1830
1831 double scale = 1;
1832 if (scalingMethodsMap.find(bc.blockName) != scalingMethodsMap.end()) {
1833 scale *= scalingMethodsMap.at(bc.blockName)->getScale(time);
1834 } else {
1835 MOFEM_LOG("SELF", Sev::warning)
1836 << "No scaling method found for " << bc.blockName;
1837 }
1838
1839 // get bc data
1840 double val = scale * bc.val;
1841
1842 int nb_dofs = data.getIndices().size();
1843 int nb_integration_pts = OP::getGaussPts().size2();
1844 int nb_base_functions = data.getN().size2();
1845 auto t_row_base = data.getFTensor0N();
1846 for (int gg = 0; gg != nb_integration_pts; ++gg) {
1847
1849 t_N(i) = t_normal(i);
1850 t_N.normalize();
1851
1853 t_P(i, j) = t_N(i) * t_N(j);
1855 t_Q(i, j) = t_kd(i, j) - t_P(i, j);
1856
1857 FTensor::Tensor1<double, 3> t_traction;
1858 t_traction(i) = t_approx_P(i, j) * t_N(j);
1859
1861 t_res(i) =
1862 t_Q(i, j) * t_traction(j) + t_P(i, j) * 2 * t_u(j) - t_N(i) * val;
1863
1864 auto t_nf = getFTensor1FromPtr<3>(&*OP::locF.begin());
1865 int bb = 0;
1866 for (; bb != nb_dofs / SPACE_DIM; ++bb) {
1867 t_nf(i) += (t_w * t_row_base * OP::getMeasure()) * t_res(i);
1868 ++t_nf;
1869 ++t_row_base;
1870 }
1871 for (; bb != nb_base_functions; ++bb)
1872 ++t_row_base;
1873
1874 ++t_w;
1875 ++t_normal;
1876 ++t_u;
1877 ++t_approx_P;
1878 }
1879 }
1880 }
1881 }
1883}
1884
1885template <AssemblyType A>
1888 EntData &col_data) {
1890
1891 double time = OP::getFEMethod()->ts_t;
1894 }
1895
1896 int row_nb_dofs = row_data.getIndices().size();
1897 int col_nb_dofs = col_data.getIndices().size();
1898 auto &locMat = OP::locMat;
1899 locMat.resize(row_nb_dofs, col_nb_dofs, false);
1900 locMat.clear();
1901
1902 // get entity of face
1903 EntityHandle fe_ent = OP::getFEEntityHandle();
1904 // iterate over all boundary data
1905 for (auto &bc : (*bcDispPtr)) {
1906 // check if finite element entity is part of boundary condition
1907 if (bc.faces.find(fe_ent) != bc.faces.end()) {
1908
1909 auto t_normal = OP::getFTensor1NormalsAtGaussPts();
1910 auto t_w = OP::getFTensor0IntegrationWeight();
1911
1914
1915 double scale = 1;
1916 if (scalingMethodsMap.find(bc.blockName) != scalingMethodsMap.end()) {
1917 scale *= scalingMethodsMap.at(bc.blockName)->getScale(time);
1918 } else {
1919 MOFEM_LOG("SELF", Sev::warning)
1920 << "No scaling method found for " << bc.blockName;
1921 }
1922
1923 int nb_integration_pts = OP::getGaussPts().size2();
1924 int row_nb_dofs = row_data.getIndices().size();
1925 int col_nb_dofs = col_data.getIndices().size();
1926 int nb_base_functions = row_data.getN().size2();
1927 auto t_row_base = row_data.getFTensor0N();
1928
1930
1931 for (int gg = 0; gg != nb_integration_pts; ++gg) {
1932
1934 t_N(i) = t_normal(i);
1935 t_N.normalize();
1936
1938 t_P(i, j) = t_N(i) * t_N(j);
1939
1941 t_d_res(i, j) = 2.0 * t_P(i, j);
1942
1943 int rr = 0;
1944 for (; rr != row_nb_dofs / SPACE_DIM; ++rr) {
1945 auto t_mat = getFTensor2FromArray<SPACE_DIM, SPACE_DIM, SPACE_DIM>(
1946 locMat, SPACE_DIM * rr);
1947 auto t_col_base = col_data.getFTensor0N(gg, 0);
1948 for (auto cc = 0; cc != col_nb_dofs / SPACE_DIM; ++cc) {
1949 t_mat(i, j) += (t_w * t_row_base * t_col_base) * t_d_res(i, j);
1950 ++t_mat;
1951 ++t_col_base;
1952 }
1953 ++t_row_base;
1954 }
1955
1956 for (; rr != nb_base_functions; ++rr)
1957 ++t_row_base;
1958
1959 ++t_w;
1960 ++t_normal;
1961 }
1962
1963 locMat *= OP::getMeasure();
1964 }
1965 }
1967}
1968
1969template <AssemblyType A>
1972 EntData &col_data) {
1974
1975 double time = OP::getFEMethod()->ts_t;
1978 }
1979
1980 int row_nb_dofs = row_data.getIndices().size();
1981 int col_nb_dofs = col_data.getIndices().size();
1982 auto &locMat = OP::locMat;
1983 locMat.resize(row_nb_dofs, col_nb_dofs, false);
1984 locMat.clear();
1985
1986 // get entity of face
1987 EntityHandle fe_ent = OP::getFEEntityHandle();
1988 // iterate over all boundary data
1989 for (auto &bc : (*bcDispPtr)) {
1990 // check if finite element entity is part of boundary condition
1991 if (bc.faces.find(fe_ent) != bc.faces.end()) {
1992
1993 auto t_normal = OP::getFTensor1NormalsAtGaussPts();
1994 auto t_w = OP::getFTensor0IntegrationWeight();
1995
1999
2001
2002 double scale = 1;
2003 if (scalingMethodsMap.find(bc.blockName) != scalingMethodsMap.end()) {
2004 scale *= scalingMethodsMap.at(bc.blockName)->getScale(time);
2005 } else {
2006 MOFEM_LOG("SELF", Sev::warning)
2007 << "No scaling method found for " << bc.blockName;
2008 }
2009
2010 int nb_integration_pts = OP::getGaussPts().size2();
2011 int nb_base_functions = row_data.getN().size2();
2012 auto t_row_base = row_data.getFTensor0N();
2013
2014 for (int gg = 0; gg != nb_integration_pts; ++gg) {
2015
2017 t_N(i) = t_normal(i);
2018 t_N.normalize();
2019
2021 t_P(i, j) = t_N(i) * t_N(j);
2023 t_Q(i, j) = t_kd(i, j) - t_P(i, j);
2024
2026 t_d_res(i, j) = t_Q(i, j);
2027
2028 int rr = 0;
2029 for (; rr != row_nb_dofs / SPACE_DIM; ++rr) {
2030 auto t_mat = getFTensor2FromArray<SPACE_DIM, SPACE_DIM, SPACE_DIM>(
2031 OP::locMat, SPACE_DIM * rr);
2032 auto t_col_base = col_data.getFTensor1N<3>(gg, 0);
2033 for (auto cc = 0; cc != col_nb_dofs / SPACE_DIM; ++cc) {
2034 t_mat(i, j) +=
2035 ((t_w * t_row_base) * (t_N(k) * t_col_base(k))) * t_d_res(i, j);
2036 ++t_mat;
2037 ++t_col_base;
2038 }
2039 ++t_row_base;
2040 }
2041
2042 for (; rr != nb_base_functions; ++rr)
2043 ++t_row_base;
2044
2045 ++t_w;
2046 ++t_normal;
2047 }
2048
2049 locMat *= OP::getMeasure();
2050 }
2051 }
2053}
2054
2056 return OP::iNtegrate(data);
2057}
2058
2060 EntData &col_data) {
2061 return OP::iNtegrate(row_data, col_data);
2062}
2063
2065 EntData &col_data) {
2066 return OP::iNtegrate(row_data, col_data);
2067}
2068
2069template <AssemblyType A>
2072
2073 double time = OP::getFEMethod()->ts_t;
2076 }
2077
2078 // get entity of face
2079 EntityHandle fe_ent = OP::getFEEntityHandle();
2080 // iterate over all boundary data
2081 for (auto &bc : (*bcDispPtr)) {
2082 // check if finite element entity is part of boundary condition
2083 if (bc.faces.find(fe_ent) != bc.faces.end()) {
2084
2086 // placeholder to pass boundary block id to python
2087
2088 auto [block_name, v_analytical_expr] =
2089 getAnalyticalExpr(this, analytical_expr, bc.blockName);
2090
2091 int nb_dofs = data.getIndices().size();
2092
2093 int nb_integration_pts = OP::getGaussPts().size2();
2094 auto t_normal = OP::getFTensor1NormalsAtGaussPts();
2095 auto t_w = OP::getFTensor0IntegrationWeight();
2096 int nb_base_functions = data.getN().size2() / 3;
2097 auto t_row_base_fun = data.getFTensor1N<3>();
2098 auto t_coord = OP::getFTensor1CoordsAtGaussPts();
2099
2102
2103 // get bc data
2104 auto t_bc_disp = getFTensor1FromMat<3, -1, DL>(v_analytical_expr);
2105
2106 for (int gg = 0; gg != nb_integration_pts; ++gg) {
2107 auto t_nf = getFTensor1FromPtr<3>(&*OP::locF.begin());
2108
2109 int bb = 0;
2110 for (; bb != nb_dofs / SPACE_DIM; ++bb) {
2111 t_nf(i) +=
2112 t_w * (t_row_base_fun(j) * t_normal(j)) * t_bc_disp(i) * 0.5;
2113 ++t_nf;
2114 ++t_row_base_fun;
2115 }
2116 for (; bb != nb_base_functions; ++bb)
2117 ++t_row_base_fun;
2118
2119 ++t_bc_disp;
2120 ++t_coord;
2121 ++t_w;
2122 ++t_normal;
2123 }
2124 }
2125 }
2127}
2128
2130 return OP::iNtegrate(data);
2131}
2132
2135
2136 FTENSOR_INDEX(3, i);
2137
2138 int nb_dofs = data.getFieldData().size();
2139 int nb_integration_pts = getGaussPts().size2();
2140 int nb_base_functions = data.getN().size2();
2141
2142 double time = getFEMethod()->ts_t;
2145 }
2146
2147#ifndef NDEBUG
2148 if (this->locF.size() != nb_dofs)
2149 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
2150 "Size of locF %ld != nb_dofs %d", this->locF.size(), nb_dofs);
2151#endif // NDEBUG
2152
2153 auto integrate_rhs = [&](auto &bc, auto calc_tau, double time_scale) {
2155
2156 auto t_val = getFTensor1FromPtr<3>(&*bc.vals.begin());
2157 auto t_row_base = data.getFTensor0N();
2158 auto t_w = getFTensor0IntegrationWeight();
2159 auto t_coords = getFTensor1CoordsAtGaussPts();
2160 auto t_normal = getFTensor1NormalsAtGaussPts();
2161
2162 double scale = (piolaScalePtr) ? 1. / (*piolaScalePtr) : 1.0;
2163
2164 for (int gg = 0; gg != nb_integration_pts; ++gg) {
2165
2166 double a = sqrt(t_normal(i) * t_normal(i));
2167 a /= 2.;
2168 const auto tau = calc_tau(t_coords(0), t_coords(1), t_coords(2));
2169 auto t_f = getFTensor1FromPtr<3>(&*this->locF.begin());
2170 int rr = 0;
2171 for (; rr != nb_dofs / SPACE_DIM; ++rr) {
2172 t_f(i) -=
2173 (time_scale * a * t_w * t_row_base * tau) * (t_val(i) * scale);
2174 ++t_row_base;
2175 ++t_f;
2176 }
2177
2178 for (; rr != nb_base_functions; ++rr)
2179 ++t_row_base;
2180 ++t_w;
2181 ++t_coords;
2182 ++t_normal;
2183 }
2185 };
2186
2187 // get entity of face
2188 EntityHandle fe_ent = getFEEntityHandle();
2189 for (auto &bc : *(bcData)) {
2190 if (bc.faces.find(fe_ent) != bc.faces.end()) {
2191
2192 double time_scale = 1;
2193 if (scalingMethodsMap.find(bc.blockName) != scalingMethodsMap.end()) {
2194 time_scale *= scalingMethodsMap.at(bc.blockName)->getScale(time);
2195 }
2196
2197 int nb_dofs = data.getFieldData().size();
2198 if (nb_dofs) {
2199
2200 if (std::regex_match(bc.blockName, std::regex(".*COOK.*"))) {
2201 auto calc_tau = [](double, double y, double) {
2202 y -= 44;
2203 y /= (60 - 44);
2204 return -y * (y - 1) / 0.25;
2205 };
2206 CHKERR integrate_rhs(bc, calc_tau, time_scale);
2207 } else {
2208 CHKERR integrate_rhs(
2209 bc, [](double, double, double) { return 1; }, time_scale);
2210 }
2211 }
2212 }
2213 }
2215}
2216
2219
2220 FTENSOR_INDEX(3, i);
2221
2222 int nb_dofs = data.getFieldData().size();
2223 int nb_integration_pts = getGaussPts().size2();
2224 int nb_base_functions = data.getN().size2();
2225
2226 double time = getFEMethod()->ts_t;
2229 }
2230
2231#ifndef NDEBUG
2232 if (this->locF.size() != nb_dofs)
2233 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
2234 "Size of locF %ld != nb_dofs %d", this->locF.size(), nb_dofs);
2235#endif // NDEBUG
2236
2237 auto integrate_rhs = [&](auto &bc, auto calc_tau, double time_scale) {
2239
2240 auto val = bc.val;
2241 auto t_row_base = data.getFTensor0N();
2242 auto t_w = getFTensor0IntegrationWeight();
2243 auto t_coords = getFTensor1CoordsAtGaussPts();
2244 auto t_tangent1 = getFTensor1Tangent1AtGaussPts();
2245 auto t_tangent2 = getFTensor1Tangent2AtGaussPts();
2246
2247 auto t_grad_gamma_u = getFTensor2FromMat<3, 2, -1, DL>(*hybridGradDispPtr);
2248
2249 double scale = (piolaScalePtr) ? 1. / (*piolaScalePtr) : 1.0;
2250
2251 for (int gg = 0; gg != nb_integration_pts; ++gg) {
2252
2258
2262
2263 t_normal(i) = (FTensor::levi_civita<double>(i, j, k) * t_tangent1(j)) *
2264 t_tangent2(k);
2265 } else {
2266 t_normal(i) = (FTensor::levi_civita<double>(i, j, k) *
2267 (t_tangent1(j) + t_grad_gamma_u(j, N0))) *
2268 (t_tangent2(k) + t_grad_gamma_u(k, N1));
2269 }
2270 auto tau = calc_tau(t_coords(0), t_coords(1), t_coords(2));
2271 auto t_val = FTensor::Tensor1<double, 3>();
2272 t_val(i) = (time_scale * t_w * tau * scale * val) * t_normal(i);
2273
2274 auto t_f = getFTensor1FromPtr<3>(&*this->locF.begin());
2275 int rr = 0;
2276 for (; rr != nb_dofs / SPACE_DIM; ++rr) {
2277 t_f(i) += t_row_base * t_val(i);
2278 ++t_row_base;
2279 ++t_f;
2280 }
2281
2282 for (; rr != nb_base_functions; ++rr)
2283 ++t_row_base;
2284 ++t_w;
2285 ++t_coords;
2286 ++t_tangent1;
2287 ++t_tangent2;
2288 ++t_grad_gamma_u;
2289 }
2290 this->locF /= 2.;
2291
2293 };
2294
2295 // get entity of face
2296 EntityHandle fe_ent = getFEEntityHandle();
2297 for (auto &bc : *(bcData)) {
2298 if (bc.faces.find(fe_ent) != bc.faces.end()) {
2299
2300 double time_scale = 1;
2301 if (scalingMethodsMap.find(bc.blockName) != scalingMethodsMap.end()) {
2302 time_scale *= scalingMethodsMap.at(bc.blockName)->getScale(time);
2303 }
2304
2305 int nb_dofs = data.getFieldData().size();
2306 if (nb_dofs) {
2307 CHKERR integrate_rhs(
2308 bc, [](double, double, double) { return 1; }, time_scale);
2309 }
2310 }
2311 }
2313}
2314
2315template <AssemblyType A>
2318 EntData &col_data) {
2320
2324 }
2325
2326 double time = OP::getFEMethod()->ts_t;
2329 }
2330
2331 int nb_base_functions = row_data.getN().size2();
2332 int row_nb_dofs = row_data.getIndices().size();
2333 int col_nb_dofs = col_data.getIndices().size();
2334 int nb_integration_pts = OP::getGaussPts().size2();
2335 auto &locMat = OP::locMat;
2336 locMat.resize(row_nb_dofs, col_nb_dofs, false);
2337 locMat.clear();
2338
2339 auto integrate_lhs = [&](auto &bc, auto calc_tau, double time_scale) {
2341
2342 auto val = bc.val;
2343 auto t_row_base = row_data.getFTensor0N();
2344 auto t_w = OP::getFTensor0IntegrationWeight();
2345 auto t_coords = OP::getFTensor1CoordsAtGaussPts();
2346 auto t_tangent1 = OP::getFTensor1Tangent1AtGaussPts();
2347 auto t_tangent2 = OP::getFTensor1Tangent2AtGaussPts();
2348
2349 auto t_grad_gamma_u = getFTensor2FromMat<3, 2, -1, DL>(*hybridGradDispPtr);
2351
2352 for (int gg = 0; gg != nb_integration_pts; ++gg) {
2353
2358
2361
2362 auto tau = calc_tau(t_coords(0), t_coords(1), t_coords(2));
2363 auto t_val = time_scale * t_w * tau * val;
2364
2365 int rr = 0;
2366 for (; rr != row_nb_dofs / SPACE_DIM; ++rr) {
2367 auto t_mat = getFTensor2FromArray<SPACE_DIM, SPACE_DIM, SPACE_DIM>(
2368 locMat, SPACE_DIM * rr);
2369 auto t_diff_col_base = col_data.getFTensor1DiffN<2>(gg, 0);
2370 for (auto cc = 0; cc != col_nb_dofs / SPACE_DIM; ++cc) {
2372 t_normal_du(i, l) = (FTensor::levi_civita<double>(i, j, k) *
2373 (t_tangent2(k) + t_grad_gamma_u(k, N1))) *
2374 t_kd(j, l) * t_diff_col_base(N0)
2375
2376 +
2377
2378 (FTensor::levi_civita<double>(i, j, k) *
2379 (t_tangent1(j) + t_grad_gamma_u(j, N0))) *
2380 t_kd(k, l) * t_diff_col_base(N1);
2381
2382 t_mat(i, j) += (t_w * t_row_base) * t_val * t_normal_du(i, j);
2383 ++t_mat;
2384 ++t_diff_col_base;
2385 }
2386 ++t_row_base;
2387 }
2388
2389 for (; rr != nb_base_functions; ++rr)
2390 ++t_row_base;
2391 ++t_w;
2392 ++t_coords;
2393 ++t_tangent1;
2394 ++t_tangent2;
2395 ++t_grad_gamma_u;
2396 }
2397
2398 OP::locMat /= 2.;
2399
2401 };
2402
2403 // get entity of face
2404 EntityHandle fe_ent = OP::getFEEntityHandle();
2405 for (auto &bc : *(bcData)) {
2406 if (bc.faces.find(fe_ent) != bc.faces.end()) {
2407
2408 double time_scale = 1;
2409 if (scalingMethodsMap.find(bc.blockName) != scalingMethodsMap.end()) {
2410 time_scale *= scalingMethodsMap.at(bc.blockName)->getScale(time);
2411 }
2412
2413 int nb_dofs = row_data.getFieldData().size();
2414 if (nb_dofs) {
2415 CHKERR integrate_lhs(
2416 bc, [](double, double, double) { return 1; }, time_scale);
2417 }
2418 }
2419 }
2420
2422}
2423
2425 EntData &col_data) {
2426 return OP::iNtegrate(row_data, col_data);
2427}
2428
2431
2432 FTENSOR_INDEX(3, i);
2433
2434 int nb_dofs = data.getFieldData().size();
2435 int nb_integration_pts = getGaussPts().size2();
2436 int nb_base_functions = data.getN().size2();
2437
2438 double time = getFEMethod()->ts_t;
2441 }
2442
2443#ifndef NDEBUG
2444 if (this->locF.size() != nb_dofs)
2445 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
2446 "Size of locF %ld != nb_dofs %d", this->locF.size(), nb_dofs);
2447#endif // NDEBUG
2448
2449 // get entity of face
2450 EntityHandle fe_ent = getFEEntityHandle();
2451 for (auto &bc : *(bcData)) {
2452 if (bc.faces.find(fe_ent) != bc.faces.end()) {
2453
2455 // placeholder to pass boundary block id to python
2456 auto [block_name, v_analytical_expr] =
2457 getAnalyticalExpr(this, analytical_expr, bc.blockName);
2458 auto t_val = getFTensor1FromMat<3, -1, DL>(v_analytical_expr);
2459 auto t_row_base = data.getFTensor0N();
2460 auto t_w = getFTensor0IntegrationWeight();
2461 auto t_coords = getFTensor1CoordsAtGaussPts();
2462
2463 double scale = (piolaScalePtr) ? 1. / (*piolaScalePtr) : 1.0;
2464
2465 for (int gg = 0; gg != nb_integration_pts; ++gg) {
2466
2467 auto t_f = getFTensor1FromPtr<3>(&*this->locF.begin());
2468 int rr = 0;
2469 for (; rr != nb_dofs / SPACE_DIM; ++rr) {
2470 t_f(i) -= t_w * t_row_base * (t_val(i) * scale);
2471 ++t_row_base;
2472 ++t_f;
2473 }
2474
2475 for (; rr != nb_base_functions; ++rr)
2476 ++t_row_base;
2477 ++t_w;
2478 ++t_coords;
2479 ++t_val;
2480 }
2481 this->locF *= getMeasure();
2482 }
2483 }
2485}
2486
2488 EntData &col_data) {
2490 int nb_integration_pts = row_data.getN().size1();
2491 int row_nb_dofs = row_data.getIndices().size();
2492 int col_nb_dofs = col_data.getIndices().size();
2493 auto get_ftensor1 = [](MatrixDouble &m, const int r, const int c) {
2495 &m(r + 0, c + 0), &m(r + 1, c + 1), &m(r + 2, c + 2));
2496 };
2497 FTensor::Index<'i', 3> i;
2498 auto v = getVolume();
2499 auto t_w = getFTensor0IntegrationWeight();
2500 int row_nb_base_functions = row_data.getN().size2();
2501 auto t_row_base_fun = row_data.getFTensor0N();
2502 for (int gg = 0; gg != nb_integration_pts; ++gg) {
2503 double a = v * t_w;
2504 int rr = 0;
2505 for (; rr != row_nb_dofs / 3; ++rr) {
2506 auto t_col_diff_base_fun = col_data.getFTensor2DiffN<3, 3>(gg, 0);
2507 auto t_m = get_ftensor1(K, 3 * rr, 0);
2508 for (int cc = 0; cc != col_nb_dofs / 3; ++cc) {
2509 double div_col_base = t_col_diff_base_fun(i, i);
2510 t_m(i) -= a * t_row_base_fun * div_col_base;
2511 ++t_m;
2512 ++t_col_diff_base_fun;
2513 }
2514 ++t_row_base_fun;
2515 }
2516 for (; rr != row_nb_base_functions; ++rr)
2517 ++t_row_base_fun;
2518 ++t_w;
2519 }
2521}
2522
2524 EntData &col_data) {
2526
2527 if (alphaW < std::numeric_limits<double>::epsilon() &&
2528 alphaRho < std::numeric_limits<double>::epsilon())
2530
2531 const int nb_integration_pts = row_data.getN().size1();
2532 const int row_nb_dofs = row_data.getIndices().size();
2533 auto get_ftensor1 = [](MatrixDouble &m, const int r, const int c) {
2535 &m(r + 0, c + 0), &m(r + 1, c + 1), &m(r + 2, c + 2)
2536
2537 );
2538 };
2539 FTensor::Index<'i', 3> i;
2540
2541 auto v = getVolume();
2542 auto t_w = getFTensor0IntegrationWeight();
2543
2544 auto piola_scale = dataAtPts->piolaScale;
2545 auto alpha_w = alphaW / piola_scale;
2546 auto alpha_rho = alphaRho / piola_scale;
2547
2548 int row_nb_base_functions = row_data.getN().size2();
2549 auto t_row_base_fun = row_data.getFTensor0N();
2550
2551 double ts_scale = alpha_w * getTSa();
2552 if (std::abs(alphaRho) > std::numeric_limits<double>::epsilon())
2553 ts_scale += alpha_rho * getTSaa();
2554
2555 for (int gg = 0; gg != nb_integration_pts; ++gg) {
2556 double a = v * t_w * ts_scale;
2557
2558 int rr = 0;
2559 for (; rr != row_nb_dofs / 3; ++rr) {
2560
2561 auto t_col_base_fun = row_data.getFTensor0N(gg, 0);
2562 auto t_m = get_ftensor1(K, 3 * rr, 0);
2563 for (int cc = 0; cc != row_nb_dofs / 3; ++cc) {
2564 const double b = a * t_row_base_fun * t_col_base_fun;
2565 t_m(i) += b;
2566 ++t_m;
2567 ++t_col_base_fun;
2568 }
2569
2570 ++t_row_base_fun;
2571 }
2572
2573 for (; rr != row_nb_base_functions; ++rr)
2574 ++t_row_base_fun;
2575
2576 ++t_w;
2577 }
2578
2580}
2581
2583 EntData &col_data) {
2585
2591
2592 int nb_integration_pts = row_data.getN().size1();
2593 int row_nb_dofs = row_data.getIndices().size();
2594 int col_nb_dofs = col_data.getIndices().size();
2595 auto get_ftensor3 = [](MatrixDouble &m, const int r, const int c) {
2597
2598 &m(r + 0, c + 0), &m(r + 0, c + 1), &m(r + 0, c + 2),
2599
2600 &m(r + 1, c + 0), &m(r + 1, c + 1), &m(r + 1, c + 2),
2601
2602 &m(r + 2, c + 0), &m(r + 2, c + 1), &m(r + 2, c + 2),
2603
2604 &m(r + 3, c + 0), &m(r + 3, c + 1), &m(r + 3, c + 2),
2605
2606 &m(r + 4, c + 0), &m(r + 4, c + 1), &m(r + 4, c + 2),
2607
2608 &m(r + 5, c + 0), &m(r + 5, c + 1), &m(r + 5, c + 2));
2609 };
2610
2611 auto v = getVolume();
2612 auto t_w = getFTensor0IntegrationWeight();
2613
2614 int row_nb_base_functions = row_data.getN().size2();
2615 auto t_row_base_fun = row_data.getFTensor0N();
2616
2617 auto t_approx_P_adjoint_log_du_dP =
2618 dataAtPts->getFTensorAdjointPdUdP(nb_integration_pts);
2619
2620 for (int gg = 0; gg != nb_integration_pts; ++gg) {
2621 double a = v * t_w;
2622 int rr = 0;
2623 for (; rr != row_nb_dofs / 6; ++rr) {
2624
2625 auto t_col_base_fun = col_data.getFTensor1N<3>(gg, 0);
2626 auto t_m = get_ftensor3(K, 6 * rr, 0);
2627
2628 for (int cc = 0; cc != col_nb_dofs / 3; ++cc) {
2629 t_m(L, i) -=
2630 a * (t_approx_P_adjoint_log_du_dP(i, j, L) * t_col_base_fun(j)) *
2631 t_row_base_fun;
2632 ++t_col_base_fun;
2633 ++t_m;
2634 }
2635
2636 ++t_row_base_fun;
2637 }
2638 for (; rr != row_nb_base_functions; ++rr)
2639 ++t_row_base_fun;
2640 ++t_w;
2641 ++t_approx_P_adjoint_log_du_dP;
2642 }
2643
2645}
2646
2648 EntData &col_data) {
2650
2656
2657 int nb_integration_pts = row_data.getN().size1();
2658 int row_nb_dofs = row_data.getIndices().size();
2659 int col_nb_dofs = col_data.getIndices().size();
2660 auto get_ftensor2 = [](MatrixDouble &m, const int r, const int c) {
2662 &m(r + 0, c), &m(r + 1, c), &m(r + 2, c), &m(r + 3, c), &m(r + 4, c),
2663 &m(r + 5, c));
2664 };
2665
2666 auto v = getVolume();
2667 auto t_w = getFTensor0IntegrationWeight();
2668 auto t_row_base_fun = row_data.getFTensor0N();
2669
2670 int row_nb_base_functions = row_data.getN().size2();
2671
2672 auto t_approx_P_adjoint_log_du_dP =
2673 dataAtPts->getFTensorAdjointPdUdP(nb_integration_pts);
2674
2675 for (int gg = 0; gg != nb_integration_pts; ++gg) {
2676 double a = v * t_w;
2677 int rr = 0;
2678 for (; rr != row_nb_dofs / 6; ++rr) {
2679 auto t_m = get_ftensor2(K, 6 * rr, 0);
2680 auto t_col_base_fun = col_data.getFTensor2N<3, 3>(gg, 0);
2681 for (int cc = 0; cc != col_nb_dofs; ++cc) {
2682 t_m(L) -=
2683 a * (t_approx_P_adjoint_log_du_dP(i, j, L) * t_col_base_fun(i, j)) *
2684 t_row_base_fun;
2685 ++t_m;
2686 ++t_col_base_fun;
2687 }
2688 ++t_row_base_fun;
2689 }
2690 for (; rr != row_nb_base_functions; ++rr)
2691 ++t_row_base_fun;
2692 ++t_w;
2693 ++t_approx_P_adjoint_log_du_dP;
2694 }
2696}
2697
2699 EntData &col_data) {
2701
2703 auto t_L = symm_L_tensor();
2704
2705 int nb_integration_pts = getGaussPts().size2();
2706 int row_nb_dofs = row_data.getIndices().size();
2707 int col_nb_dofs = col_data.getIndices().size();
2708 auto get_ftensor3 = [](MatrixDouble &m, const int r, const int c) {
2710
2711 &m(r + 0, c + 0), &m(r + 0, c + 1), &m(r + 0, c + 2),
2712
2713 &m(r + 1, c + 0), &m(r + 1, c + 1), &m(r + 1, c + 2),
2714
2715 &m(r + 2, c + 0), &m(r + 2, c + 1), &m(r + 2, c + 2),
2716
2717 &m(r + 3, c + 0), &m(r + 3, c + 1), &m(r + 3, c + 2),
2718
2719 &m(r + 4, c + 0), &m(r + 4, c + 1), &m(r + 4, c + 2),
2720
2721 &m(r + 5, c + 0), &m(r + 5, c + 1), &m(r + 5, c + 2)
2722
2723 );
2724 };
2725 FTensor::Index<'i', 3> i;
2726 FTensor::Index<'j', 3> j;
2727 FTensor::Index<'k', 3> k;
2728 FTensor::Index<'m', 3> m;
2729 FTensor::Index<'n', 3> n;
2730
2731 auto v = getVolume();
2732 auto t_w = getFTensor0IntegrationWeight();
2733 auto t_approx_P_adjoint_log_du_domega =
2734 dataAtPts->getFTensorAdjointPdUdOmega(nb_integration_pts);
2735
2736 int row_nb_base_functions = row_data.getN().size2();
2737 auto t_row_base_fun = row_data.getFTensor0N();
2738
2739 for (int gg = 0; gg != nb_integration_pts; ++gg) {
2740 double a = v * t_w;
2741
2742 int rr = 0;
2743 for (; rr != row_nb_dofs / 6; ++rr) {
2744 auto t_col_base_fun = col_data.getFTensor0N(gg, 0);
2745 auto t_m = get_ftensor3(K, 6 * rr, 0);
2746 for (int cc = 0; cc != col_nb_dofs / 3; ++cc) {
2747 double v = a * t_row_base_fun * t_col_base_fun;
2748 t_m(L, k) -= v * t_approx_P_adjoint_log_du_domega(k, L);
2749 ++t_m;
2750 ++t_col_base_fun;
2751 }
2752 ++t_row_base_fun;
2753 }
2754
2755 for (; rr != row_nb_base_functions; ++rr)
2756 ++t_row_base_fun;
2757
2758 ++t_w;
2759 ++t_approx_P_adjoint_log_du_domega;
2760 }
2761
2763}
2764
2766 EntData &col_data) {
2768 int nb_integration_pts = getGaussPts().size2();
2769 int row_nb_dofs = row_data.getIndices().size();
2770 int col_nb_dofs = col_data.getIndices().size();
2771 auto get_ftensor2 = [](MatrixDouble &m, const int r, const int c) {
2773 size_symm>{
2774
2775 &m(r + 0, c + 0), &m(r + 0, c + 1), &m(r + 0, c + 2), &m(r + 0, c + 3),
2776 &m(r + 0, c + 4), &m(r + 0, c + 5),
2777
2778 &m(r + 1, c + 0), &m(r + 1, c + 1), &m(r + 1, c + 2), &m(r + 1, c + 3),
2779 &m(r + 1, c + 4), &m(r + 1, c + 5),
2780
2781 &m(r + 2, c + 0), &m(r + 2, c + 1), &m(r + 2, c + 2), &m(r + 2, c + 3),
2782 &m(r + 2, c + 4), &m(r + 2, c + 5)
2783
2784 };
2785 };
2786
2789
2790 auto v = getVolume();
2791 auto t_w = getFTensor0IntegrationWeight();
2792 auto t_levi_kirchhoff_du =
2793 dataAtPts->getFTensorLeviKirchhoffdLogStretch(nb_integration_pts);
2794 int row_nb_base_functions = row_data.getN().size2();
2795 auto t_row_base_fun = row_data.getFTensor0N();
2796 for (int gg = 0; gg != nb_integration_pts; ++gg) {
2797 double a = v * t_w;
2798 int rr = 0;
2799 for (; rr != row_nb_dofs / 3; ++rr) {
2800 auto t_m = get_ftensor2(K, 3 * rr, 0);
2801 const double b = a * t_row_base_fun;
2802 auto t_col_base_fun = col_data.getFTensor0N(gg, 0);
2803 for (int cc = 0; cc != col_nb_dofs / size_symm; ++cc) {
2804 t_m(k, L) -= (b * t_col_base_fun) * t_levi_kirchhoff_du(k, L);
2805 ++t_m;
2806 ++t_col_base_fun;
2807 }
2808 ++t_row_base_fun;
2809 }
2810 for (; rr != row_nb_base_functions; ++rr) {
2811 ++t_row_base_fun;
2812 }
2813 ++t_w;
2814 ++t_levi_kirchhoff_du;
2815 }
2817}
2818
2820 EntData &col_data) {
2822
2829
2830 int nb_integration_pts = getGaussPts().size2();
2831 int row_nb_dofs = row_data.getIndices().size();
2832 int col_nb_dofs = col_data.getIndices().size();
2833 auto get_ftensor2 = [](MatrixDouble &m, const int r, const int c) {
2835
2836 &m(r + 0, c + 0), &m(r + 0, c + 1), &m(r + 0, c + 2),
2837
2838 &m(r + 1, c + 0), &m(r + 1, c + 1), &m(r + 1, c + 2),
2839
2840 &m(r + 2, c + 0), &m(r + 2, c + 1), &m(r + 2, c + 2)
2841
2842 );
2843 };
2844
2845 auto v = getVolume();
2846 auto t_w = getFTensor0IntegrationWeight();
2847
2848 int row_nb_base_functions = row_data.getN().size2();
2849 auto t_row_base_fun = row_data.getFTensor0N();
2850 auto t_levi_kirchhoff_dP =
2851 dataAtPts->getFTensorLeviKirchhoffP(nb_integration_pts);
2852
2853 for (int gg = 0; gg != nb_integration_pts; ++gg) {
2854 double a = v * t_w;
2855 int rr = 0;
2856 for (; rr != row_nb_dofs / 3; ++rr) {
2857 double b = a * t_row_base_fun;
2858 auto t_col_base_fun = col_data.getFTensor1N<3>(gg, 0);
2859 auto t_m = get_ftensor2(K, 3 * rr, 0);
2860 for (int cc = 0; cc != col_nb_dofs / 3; ++cc) {
2861 t_m(m, i) -= b * (t_levi_kirchhoff_dP(m, i, k) * t_col_base_fun(k));
2862 ++t_m;
2863 ++t_col_base_fun;
2864 }
2865 ++t_row_base_fun;
2866 }
2867 for (; rr != row_nb_base_functions; ++rr) {
2868 ++t_row_base_fun;
2869 }
2870
2871 ++t_w;
2872 ++t_levi_kirchhoff_dP;
2873 }
2875}
2876
2878 EntData &col_data) {
2880 int nb_integration_pts = getGaussPts().size2();
2881 int row_nb_dofs = row_data.getIndices().size();
2882 int col_nb_dofs = col_data.getIndices().size();
2883
2884 auto get_ftensor1 = [](MatrixDouble &m, const int r, const int c) {
2886 &m(r + 0, c), &m(r + 1, c), &m(r + 2, c));
2887 };
2888
2889 FTENSOR_INDEX(3, i);
2890 FTENSOR_INDEX(3, k);
2891 FTENSOR_INDEX(3, m);
2892
2893 auto v = getVolume();
2894 auto t_w = getFTensor0IntegrationWeight();
2895 auto t_levi_kirchoff_dP =
2896 dataAtPts->getFTensorLeviKirchhoffP(nb_integration_pts);
2897
2898 int row_nb_base_functions = row_data.getN().size2();
2899 auto t_row_base_fun = row_data.getFTensor0N();
2900
2901 for (int gg = 0; gg != nb_integration_pts; ++gg) {
2902 double a = v * t_w;
2903 int rr = 0;
2904 for (; rr != row_nb_dofs / 3; ++rr) {
2905 double b = a * t_row_base_fun;
2906 auto t_col_base_fun = col_data.getFTensor2N<3, 3>(gg, 0);
2907 auto t_m = get_ftensor1(K, 3 * rr, 0);
2908 for (int cc = 0; cc != col_nb_dofs; ++cc) {
2909 t_m(m) -= b * (t_levi_kirchoff_dP(m, i, k) * t_col_base_fun(i, k));
2910 ++t_m;
2911 ++t_col_base_fun;
2912 }
2913 ++t_row_base_fun;
2914 }
2915
2916 for (; rr != row_nb_base_functions; ++rr) {
2917 ++t_row_base_fun;
2918 }
2919 ++t_w;
2920 ++t_levi_kirchoff_dP;
2921 }
2923}
2924
2926 EntData &col_data) {
2928 int nb_integration_pts = getGaussPts().size2();
2929 int row_nb_dofs = row_data.getIndices().size();
2930 int col_nb_dofs = col_data.getIndices().size();
2931 auto get_ftensor2 = [](MatrixDouble &m, const int r, const int c) {
2933
2934 &m(r + 0, c + 0), &m(r + 0, c + 1), &m(r + 0, c + 2),
2935
2936 &m(r + 1, c + 0), &m(r + 1, c + 1), &m(r + 1, c + 2),
2937
2938 &m(r + 2, c + 0), &m(r + 2, c + 1), &m(r + 2, c + 2)
2939
2940 );
2941 };
2942 FTensor::Index<'i', 3> i;
2943 FTensor::Index<'j', 3> j;
2944 FTensor::Index<'k', 3> k;
2945 FTensor::Index<'l', 3> l;
2946 FTensor::Index<'m', 3> m;
2947 FTensor::Index<'n', 3> n;
2948
2950
2951 auto v = getVolume();
2952 auto ts_a = std::abs(alphaOmega) > std::numeric_limits<double>::epsilon()
2953 ? getTSa()
2954 : 0.0;
2955 auto t_w = getFTensor0IntegrationWeight();
2956 auto t_levi_kirchhoff_domega =
2957 dataAtPts->getFTensorLeviKirchhoffdOmega(nb_integration_pts);
2958 int row_nb_base_functions = row_data.getN().size2();
2959 auto t_row_base_fun = row_data.getFTensor0N();
2960 auto t_row_grad_fun = row_data.getFTensor1DiffN<3>();
2961
2962 // auto time_step = getTStimeStep();
2963 for (int gg = 0; gg != nb_integration_pts; ++gg) {
2964 double a = v * t_w;
2965 double c = (a * alphaOmega) * (ts_a /*/ time_step*/);
2966
2967 int rr = 0;
2968 for (; rr != row_nb_dofs / 3; ++rr) {
2969 auto t_m = get_ftensor2(K, 3 * rr, 0);
2970 const double b = a * t_row_base_fun;
2971 auto t_col_base_fun = col_data.getFTensor0N(gg, 0);
2972 auto t_col_grad_fun = col_data.getFTensor1DiffN<3>(gg, 0);
2973 for (int cc = 0; cc != col_nb_dofs / 3; ++cc) {
2974 t_m(k, l) -= (b * t_col_base_fun) * t_levi_kirchhoff_domega(k, l);
2975 t_m(k, l) += t_kd(k, l) * (c * (t_row_grad_fun(i) * t_col_grad_fun(i)));
2976 ++t_m;
2977 ++t_col_base_fun;
2978 ++t_col_grad_fun;
2979 }
2980 ++t_row_base_fun;
2981 ++t_row_grad_fun;
2982 }
2983 for (; rr != row_nb_base_functions; ++rr) {
2984 ++t_row_base_fun;
2985 ++t_row_grad_fun;
2986 }
2987 ++t_w;
2988 ++t_levi_kirchhoff_domega;
2989 }
2991}
2992
2994 EntData &col_data) {
2996 if (hasNonhomogeneousMatBlock) {
2998 integrateImpl<size_symm * size_symm>(row_data, col_data));
2999 } else {
3000 MoFEMFunctionReturnHot(integrateImpl<0>(row_data, col_data));
3001 }
3003};
3004
3005template <int S>
3007 EntData &col_data) {
3009
3010 auto get_ftensor2 = [](MatrixDouble &m, const int r, const int c) {
3012
3013 &m(r + 0, c + 0), &m(r + 0, c + 1), &m(r + 0, c + 2),
3014
3015 &m(r + 1, c + 0), &m(r + 1, c + 1), &m(r + 1, c + 2),
3016
3017 &m(r + 2, c + 0), &m(r + 2, c + 1), &m(r + 2, c + 2)
3018
3019 );
3020 };
3021
3022 int nb_integration_pts = getGaussPts().size2();
3023 int row_nb_dofs = row_data.getIndices().size();
3024 int col_nb_dofs = col_data.getIndices().size();
3025
3026 auto v = getVolume();
3027 auto t_w = getFTensor0IntegrationWeight();
3028 int row_nb_base_functions = row_data.getN().size2() / 3;
3029
3034
3035 auto t_inv_D =
3036 getFTensor4DdgFromMat<SPACE_DIM, SPACE_DIM, S>(dataAtPts->matInvD);
3037
3038 auto t_row_base = row_data.getFTensor1N<3>();
3039 for (int gg = 0; gg != nb_integration_pts; ++gg) {
3040 double a = v * t_w;
3041
3042 int rr = 0;
3043 for (; rr != row_nb_dofs / 3; ++rr) {
3044 auto t_col_base = col_data.getFTensor1N<3>(gg, 0);
3045 auto t_m = get_ftensor2(K, 3 * rr, 0);
3046 for (int cc = 0; cc != col_nb_dofs / 3; ++cc) {
3047 t_m(i, k) -= a * t_row_base(j) * (t_inv_D(i, j, k, l) * t_col_base(l));
3048 ++t_m;
3049 ++t_col_base;
3050 }
3051
3052 ++t_row_base;
3053 }
3054
3055 for (; rr != row_nb_base_functions; ++rr)
3056 ++t_row_base;
3057
3058 ++t_w;
3059 ++t_inv_D;
3060 }
3062}
3063
3066 EntData &col_data) {
3068 if (hasNonhomogeneousMatBlock) {
3070 integrateImpl<size_symm * size_symm>(row_data, col_data));
3071 } else {
3072 MoFEMFunctionReturnHot(integrateImpl<0>(row_data, col_data));
3073 }
3075};
3076
3077template <int S>
3080 EntData &col_data) {
3082
3083 int nb_integration_pts = getGaussPts().size2();
3084 int row_nb_dofs = row_data.getIndices().size();
3085 int col_nb_dofs = col_data.getIndices().size();
3086
3087 auto v = getVolume();
3088 auto t_w = getFTensor0IntegrationWeight();
3089 int row_nb_base_functions = row_data.getN().size2() / 9;
3090
3095
3096 auto t_inv_D =
3097 getFTensor4DdgFromMat<SPACE_DIM, SPACE_DIM, S>(dataAtPts->matInvD);
3098
3099 auto t_row_base = row_data.getFTensor2N<3, 3>();
3100 for (int gg = 0; gg != nb_integration_pts; ++gg) {
3101 double a = v * t_w;
3102
3103 int rr = 0;
3104 for (; rr != row_nb_dofs; ++rr) {
3105 auto t_col_base = col_data.getFTensor2N<3, 3>(gg, 0);
3106 for (int cc = 0; cc != col_nb_dofs; ++cc) {
3107 K(rr, cc) -=
3108 a * (t_row_base(i, j) * (t_inv_D(i, j, k, l) * t_col_base(k, l)));
3109 ++t_col_base;
3110 }
3111
3112 ++t_row_base;
3113 }
3114
3115 for (; rr != row_nb_base_functions; ++rr)
3116 ++t_row_base;
3117 ++t_w;
3118 ++t_inv_D;
3119 }
3121}
3122
3124 EntData &col_data) {
3126 if (hasNonhomogeneousMatBlock) {
3128 integrateImpl<size_symm * size_symm>(row_data, col_data));
3129 } else {
3130 MoFEMFunctionReturnHot(integrateImpl<0>(row_data, col_data));
3131 }
3133};
3134
3135template <int S>
3138 EntData &col_data) {
3140
3141 auto get_ftensor1 = [](MatrixDouble &m, const int r, const int c) {
3143
3144 &m(r + 0, c + 0), &m(r + 0, c + 1), &m(r + 0, c + 2)
3145
3146 );
3147 };
3148
3149 int nb_integration_pts = getGaussPts().size2();
3150 int row_nb_dofs = row_data.getIndices().size();
3151 int col_nb_dofs = col_data.getIndices().size();
3152
3153 auto v = getVolume();
3154 auto t_w = getFTensor0IntegrationWeight();
3155 int row_nb_base_functions = row_data.getN().size2() / 9;
3156
3163
3164 auto t_inv_D =
3165 getFTensor4DdgFromMat<SPACE_DIM, SPACE_DIM, S>(dataAtPts->matInvD);
3166
3167 auto t_row_base = row_data.getFTensor2N<3, 3>();
3168 for (int gg = 0; gg != nb_integration_pts; ++gg) {
3169 double a = v * t_w;
3170
3171 auto t_m = get_ftensor1(K, 0, 0);
3172
3173 int rr = 0;
3174 for (; rr != row_nb_dofs; ++rr) {
3175 auto t_col_base = col_data.getFTensor1N<3>(gg, 0);
3176 for (int cc = 0; cc != col_nb_dofs / 3; ++cc) {
3177 t_m(k) -= a * (t_row_base(i, j) * t_inv_D(i, j, k, l)) * t_col_base(l);
3178 ++t_col_base;
3179 ++t_m;
3180 }
3181
3182 ++t_row_base;
3183 }
3184
3185 for (; rr != row_nb_base_functions; ++rr)
3186 ++t_row_base;
3187 ++t_w;
3188 ++t_inv_D;
3189 }
3191}
3192
3194 EntData &col_data) {
3196
3197 auto get_ftensor1 = [](MatrixDouble &m, const int r, const int c) {
3199
3200 &m(r + 0, c + 0), &m(r + 0, c + 1), &m(r + 0, c + 2)
3201
3202 );
3203 };
3204
3205 int nb_integration_pts = getGaussPts().size2();
3206 int row_nb_dofs = row_data.getIndices().size();
3207 int col_nb_dofs = col_data.getIndices().size();
3208
3209 auto v = getVolume();
3210 auto t_w = getFTensor0IntegrationWeight();
3211 int row_nb_base_functions = row_data.getN().size2() / 9;
3212
3215
3216 auto t_row_base = row_data.getFTensor2N<3, 3>();
3217 for (int gg = 0; gg != nb_integration_pts; ++gg) {
3218 double a = v * t_w;
3219
3220 auto t_m = get_ftensor1(K, 0, 0);
3221
3222 int rr = 0;
3223 for (; rr != row_nb_dofs; ++rr) {
3224 auto t_col_base = col_data.getFTensor1N<3>(gg, 0);
3225 for (int cc = 0; cc != col_nb_dofs / 3; ++cc) {
3226 t_m(k) += a * t_row_base(k, l) * t_col_base(l);
3227 ++t_col_base;
3228 ++t_m;
3229 }
3230
3231 ++t_row_base;
3232 }
3233
3234 for (; rr != row_nb_base_functions; ++rr)
3235 ++t_row_base;
3236 ++t_w;
3237 }
3238
3240}
3241
3243 EntData &col_data) {
3245
3252
3253 int nb_integration_pts = row_data.getN().size1();
3254 int row_nb_dofs = row_data.getIndices().size();
3255 int col_nb_dofs = col_data.getIndices().size();
3256
3257 auto get_ftensor2 = [](MatrixDouble &m, const int r, const int c) {
3259
3260 &m(r + 0, c + 0), &m(r + 0, c + 1), &m(r + 0, c + 2),
3261
3262 &m(r + 1, c + 0), &m(r + 1, c + 1), &m(r + 1, c + 2),
3263
3264 &m(r + 2, c + 0), &m(r + 2, c + 1), &m(r + 2, c + 2)
3265
3266 );
3267 };
3268
3269 auto v = getVolume();
3270 auto t_w = getFTensor0IntegrationWeight();
3271 int row_nb_base_functions = row_data.getN().size2() / 3;
3272 auto t_row_base_fun = row_data.getFTensor1N<3>();
3273
3274 auto t_h_domega = dataAtPts->getFTensorSmallHdOmega(nb_integration_pts);
3275
3276 for (int gg = 0; gg != nb_integration_pts; ++gg) {
3277 double a = v * t_w;
3278
3279 int rr = 0;
3280 for (; rr != row_nb_dofs / 3; ++rr) {
3281
3283 t_PRT(i, k) = t_row_base_fun(j) * t_h_domega(i, j, k);
3284
3285 auto t_col_base_fun = col_data.getFTensor0N(gg, 0);
3286 auto t_m = get_ftensor2(K, 3 * rr, 0);
3287 for (int cc = 0; cc != col_nb_dofs / 3; ++cc) {
3288 t_m(i, j) -= (a * t_col_base_fun) * t_PRT(i, j);
3289 ++t_m;
3290 ++t_col_base_fun;
3291 }
3292
3293 ++t_row_base_fun;
3294 }
3295
3296 for (; rr != row_nb_base_functions; ++rr)
3297 ++t_row_base_fun;
3298 ++t_w;
3299 ++t_h_domega;
3300 }
3302}
3303
3306 EntData &col_data) {
3308
3315
3316 int nb_integration_pts = row_data.getN().size1();
3317 int row_nb_dofs = row_data.getIndices().size();
3318 int col_nb_dofs = col_data.getIndices().size();
3319
3320 auto get_ftensor2 = [](MatrixDouble &m, const int r, const int c) {
3322 &m(r, c + 0), &m(r, c + 1), &m(r, c + 2));
3323 };
3324
3325 auto v = getVolume();
3326 auto t_w = getFTensor0IntegrationWeight();
3327 int row_nb_base_functions = row_data.getN().size2() / 9;
3328 auto t_row_base_fun = row_data.getFTensor2N<3, 3>();
3329
3330 auto t_h_domega = dataAtPts->getFTensorSmallHdOmega(nb_integration_pts);
3331 for (int gg = 0; gg != nb_integration_pts; ++gg) {
3332 double a = v * t_w;
3333
3334 int rr = 0;
3335 for (; rr != row_nb_dofs; ++rr) {
3336
3338 t_PRT(k) = t_row_base_fun(i, j) * t_h_domega(i, j, k);
3339
3340 auto t_col_base_fun = col_data.getFTensor0N(gg, 0);
3341 auto t_m = get_ftensor2(K, rr, 0);
3342 for (int cc = 0; cc != col_nb_dofs / 3; ++cc) {
3343 t_m(j) -= (a * t_col_base_fun) * t_PRT(j);
3344 ++t_m;
3345 ++t_col_base_fun;
3346 }
3347
3348 ++t_row_base_fun;
3349 }
3350
3351 for (; rr != row_nb_base_functions; ++rr)
3352 ++t_row_base_fun;
3353
3354 ++t_w;
3355 ++t_h_domega;
3356 }
3358}
3359
3361 EntData &data) {
3363
3364 if (tagSense != getSkeletonSense())
3366
3367 auto get_tag = [&](auto name) {
3368 auto &mob = getPtrFE()->mField.get_moab();
3369 Tag tag;
3370 CHK_MOAB_THROW(mob.tag_get_handle(name, tag), "get tag");
3371 return tag;
3372 };
3373
3374 auto get_tag_value = [&](auto &&tag, int dim) {
3375 auto &mob = getPtrFE()->mField.get_moab();
3376 auto face = getSidePtrFE()->getFEEntityHandle();
3377 std::vector<double> value(dim);
3378 CHK_MOAB_THROW(mob.tag_get_data(tag, &face, 1, value.data()), "set tag");
3379 return value;
3380 };
3381
3382 auto create_tag = [this](const std::string tag_name, const int size) {
3383 double def_VAL[] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
3384 Tag th;
3385 CHKERR postProcMesh.tag_get_handle(tag_name.c_str(), size, MB_TYPE_DOUBLE,
3386 th, MB_TAG_CREAT | MB_TAG_SPARSE,
3387 def_VAL);
3388 return th;
3389 };
3390
3391 Tag th_cauchy_streess = create_tag("CauchyStress", 9);
3392 Tag th_detF = create_tag("detF", 1);
3393 Tag th_traction = create_tag("traction", 3);
3394 Tag th_disp_error = create_tag("DisplacementError", 1);
3395
3396 Tag th_energy = create_tag("Energy", 1);
3397 Tag th_young_modulus = create_tag("YoungModulus", 1);
3398
3399 const auto nb_gauss_pts = getGaussPts().size2();
3400 auto t_w = dataAtPts->getFTensorSmallWL2(nb_gauss_pts);
3401 auto t_h = dataAtPts->getFTensorSmallH(nb_gauss_pts);
3402 auto t_approx_P = dataAtPts->getFTensorApproxP(nb_gauss_pts);
3403
3404 auto t_normal = getFTensor1NormalsAtGaussPts();
3405 auto t_disp = dataAtPts->getFTensorSmallWH1(nb_gauss_pts);
3406
3407 // auto sense = getSkeletonSense();
3408
3409 if (dataAtPts->energyAtPts.size() == 0) {
3410 // that is for case that energy is not calculated
3411 dataAtPts->energyAtPts.resize(nb_gauss_pts);
3412 dataAtPts->energyAtPts.clear();
3413 }
3414 auto t_energy = getFTensor0FromVec(dataAtPts->energyAtPts);
3415 auto t_youngs_modulus = getFTensor0FromVec(dataAtPts->youngModulusAtPts);
3416
3417 auto next = [&]() {
3418 ++t_w;
3419 ++t_h;
3420 ++t_approx_P;
3421 ++t_normal;
3422 ++t_disp;
3423 ++t_youngs_modulus;
3424 ++t_energy;
3425 };
3426
3427 FTensor::Index<'i', 3> i;
3428 FTensor::Index<'j', 3> j;
3429 FTensor::Index<'k', 3> k;
3430 FTensor::Index<'l', 3> l;
3431
3432 auto set_float_precision = [](const double x) {
3433 if (std::abs(x) < std::numeric_limits<float>::epsilon())
3434 return 0.;
3435 else
3436 return x;
3437 };
3438
3439 // scalars
3440 auto save_scal_tag = [&](auto &th, auto v, const int gg) {
3442 v = set_float_precision(v);
3443 CHKERR postProcMesh.tag_set_data(th, &mapGaussPts[gg], 1, &v);
3445 };
3446
3447 // vectors
3448 VectorDouble3 v(3);
3449 FTensor::Tensor1<FTensor::PackPtr<double *, 0>, 3> t_v(&v[0], &v[1], &v[2]);
3450 auto save_vec_tag = [&](auto &th, auto &t_d, const int gg) {
3452 t_v(i) = t_d(i);
3453 for (auto &a : v.data())
3454 a = set_float_precision(a);
3455 CHKERR postProcMesh.tag_set_data(th, &mapGaussPts[gg], 1,
3456 &*v.data().begin());
3458 };
3459
3460 // tensors
3461
3462 MatrixDouble3by3 m(3, 3);
3464 &m(0, 0), &m(0, 1), &m(0, 2),
3465
3466 &m(1, 0), &m(1, 1), &m(1, 2),
3467
3468 &m(2, 0), &m(2, 1), &m(2, 2));
3469
3470 auto save_mat_tag = [&](auto &th, auto &t_d, const int gg) {
3472 t_m(i, j) = t_d(i, j);
3473 for (auto &v : m.data())
3474 v = set_float_precision(v);
3475 CHKERR postProcMesh.tag_set_data(th, &mapGaussPts[gg], 1,
3476 &*m.data().begin());
3478 };
3479
3480 for (auto gg = 0; gg != nb_gauss_pts; ++gg) {
3481
3482 FTensor::Tensor1<double, 3> t_traction;
3483 t_traction(i) = t_approx_P(i, j) * t_normal(j) / t_normal.l2();
3484 // vectors
3485 t_traction(i) *= tagSense;
3486 CHKERR save_vec_tag(th_traction, t_traction, gg);
3487
3488 double u_error = sqrt((t_disp(i) - t_w(i)) * (t_disp(i) - t_w(i)));
3489 if (!std::isfinite(u_error))
3490 u_error = -1.;
3491 CHKERR save_scal_tag(th_disp_error, u_error, gg);
3492 CHKERR save_scal_tag(th_energy, t_energy, gg);
3494 CHKERR save_scal_tag(th_young_modulus, t_youngs_modulus, gg);
3495
3496 const double jac = determinantTensor3by3(t_h);
3498 t_cauchy(i, j) = (1. / jac) * (t_approx_P(i, k) * t_h(j, k));
3499 CHKERR save_mat_tag(th_cauchy_streess, t_cauchy, gg);
3500 CHKERR postProcMesh.tag_set_data(th_detF, &mapGaussPts[gg], 1, &jac);
3501
3502 next();
3503 }
3504
3506}
3507
3509 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pipeline,
3510 std::vector<FieldSpace> spaces, std::string geom_field_name,
3511 boost::shared_ptr<Range> crack_front_edges_ptr) {
3513
3514 constexpr bool scale_l2 = false;
3515
3516 if (scale_l2) {
3517 SETERRQ(PETSC_COMM_WORLD, MOFEM_NOT_IMPLEMENTED,
3518 "Scale L2 Ainsworth Legendre base is not implemented");
3519 }
3520
3521 CHKERR MoFEM::AddHOOps<2, 3, 3>::add(pipeline, spaces, geom_field_name);
3522
3524}
3525
3527 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pipeline,
3528 std::vector<FieldSpace> spaces, std::string geom_field_name,
3529 boost::shared_ptr<Range> crack_front_edges_ptr) {
3531
3532 constexpr bool scale_l2 = false;
3533
3534 if (scale_l2) {
3535 SETERRQ(PETSC_COMM_WORLD, MOFEM_NOT_IMPLEMENTED,
3536 "Scale L2 Ainsworth Legendre base is not implemented");
3537 }
3538
3539 CHKERR MoFEM::AddHOOps<2, 2, 3>::add(pipeline, spaces, geom_field_name);
3540
3542}
3543
3545 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pipeline,
3546 std::vector<FieldSpace> spaces, std::string geom_field_name,
3547 boost::shared_ptr<Range> crack_front_edges_ptr,
3548 boost::shared_ptr<MatrixDouble> jac, boost::shared_ptr<VectorDouble> det,
3549 boost::shared_ptr<MatrixDouble> inv_jac) {
3551
3552 if (!geom_field_name.empty()) {
3554 auto jac = boost::make_shared<MatrixDouble>();
3555 auto det = boost::make_shared<VectorDouble>();
3556 pipeline.push_back(
3558 geom_field_name, jac));
3559 pipeline.push_back(new OpInvertMatrix<3>(jac, det, nullptr));
3560 pipeline.push_back(
3562 }
3563 }
3564
3565 constexpr bool scale_l2_ainsworth_legendre_base = false;
3566
3567 if (scale_l2_ainsworth_legendre_base) {
3568
3570 : public MoFEM::OpCalculateVectorFieldGradient<SPACE_DIM, SPACE_DIM> {
3571
3573
3574 OpCalculateVectorFieldGradient(const std::string &field_name,
3575 boost::shared_ptr<MatrixDouble> jac,
3576 boost::shared_ptr<Range> edges_ptr)
3577 : OP(field_name, jac), edgesPtr(edges_ptr) {}
3578
3579 MoFEMErrorCode doWork(int side, EntityType type, EntData &data) {
3580
3581 auto ent = data.getFieldEntities().size()
3582 ? data.getFieldEntities()[0]->getEnt()
3583 : 0;
3584
3585 if (type == MBEDGE && edgesPtr->find(ent) != edgesPtr->end()) {
3586 return 0;
3587 } else {
3588 return OP::doWork(side, type, data);
3589 }
3590 };
3591
3592 private:
3593 boost::shared_ptr<Range> edgesPtr;
3594 };
3595
3596 if (!geom_field_name.empty()) {
3597 auto jac = boost::make_shared<MatrixDouble>();
3598 auto det = boost::make_shared<VectorDouble>();
3599 pipeline.push_back(new OpCalculateVectorFieldGradient(
3600 geom_field_name, jac,
3601 EshelbianCore::setSingularity ? crack_front_edges_ptr
3602 : boost::make_shared<Range>()));
3603 pipeline.push_back(new OpInvertMatrix<3>(jac, det, nullptr));
3604 pipeline.push_back(new OpScaleBaseBySpaceInverseOfMeasure(
3606 }
3607 }
3608
3609 CHKERR MoFEM::AddHOOps<3, 3, 3>::add(pipeline, spaces, geom_field_name, jac,
3610 det, inv_jac);
3611
3613}
3614
3615/**
3616 * @brief Caluclate face material force and normal pressure at gauss points
3617 *
3618 * @param side
3619 * @param type
3620 * @param data
3621 * @return MoFEMErrorCode
3622 *
3623 * Reconstruct the full gradient \f$U=\nabla u\f$ on a surface from the
3624 * symmetric part and the surface gradient.
3625 *
3626 * @details
3627 * Inputs:
3628 * - \c t_strain : \f$\varepsilon=\tfrac12(U+U^\top)\f$ (symmetric strain on
3629 * S),
3630 * - \c t_grad_u_gamma : \f$u^\Gamma = U P\f$ (right-projected/surface
3631 * gradient), with \f$P=I-\mathbf N\otimes\mathbf N\f$,
3632 * - \c t_normal : (possibly non‑unit) surface normal.
3633 *
3634 * Procedure (pointwise on S):
3635 * 1) Normalize the normal \f$\mathbf n=\mathbf N/\|\mathbf N\|\f$.
3636 * 2) Form the residual \f$R=\varepsilon-\operatorname{sym}(u^\Gamma)\f$, where
3637 * \f$\operatorname{sym}(A)=\tfrac12(A+A^\top)\f$.
3638 * 3) Recover the normal directional derivative (a vector)
3639 * \f$\mathbf v=\partial_{\mathbf n}u=2R\mathbf n-(\mathbf n^\top R\,\mathbf
3640 * n)\,\mathbf n\f$. 4) Assemble the full gradient \f$U = u^\Gamma + \mathbf
3641 * v\otimes \mathbf n\f$.
3642 *
3643 * Properties (sanity checks):
3644 * - \f$\tfrac12(U+U^\top)=\varepsilon\f$ (matches the given symmetric part),
3645 * - \f$U P = u^\Gamma\f$ (tangential/right-projected columns unchanged),
3646 * - Only the **normal column** is updated via \f$\mathbf v\otimes\mathbf n\f$.
3647 *
3648 * Mapping to variables in this snippet:
3649 * - \f$\varepsilon \leftrightarrow\f$ \c t_strain,
3650 * - \f$u^\Gamma \leftrightarrow\f$ \c t_grad_u_gamma,
3651 * - \f$\mathbf N \leftrightarrow\f$ \c t_normal (normalized into \c t_N),
3652 * - \f$R \leftrightarrow\f$ \c t_R,
3653 * - \f$U \leftrightarrow\f$ \c t_grad_u.
3654 *
3655 * @pre \c t_normal is nonzero; \c t_strain is symmetric.
3656 * @note All indices use Einstein summation; computation is local to the surface
3657 * point.
3658 *
3659 */
3661 EntData &data) {
3663
3676
3677 const auto nb_gauss_pts = getGaussPts().size2();
3679 dataAtPts->faceMaterialForceAtPts, nb_gauss_pts);
3680 dataAtPts->normalPressureAtPts.resize(nb_gauss_pts, false);
3681 if (getNinTheLoop() == 0) {
3682 dataAtPts->faceMaterialForceAtPts.clear();
3683 dataAtPts->normalPressureAtPts.clear();
3684 }
3685 auto loop_size = getLoopSize();
3686 if (loop_size == 1) {
3687 auto numebered_fe_ptr = getSidePtrFE()->numeredEntFiniteElementPtr;
3688 auto pstatus = numebered_fe_ptr->getPStatus();
3689 if (pstatus & (PSTATUS_SHARED | PSTATUS_MULTISHARED)) {
3690 loop_size = 2;
3691 }
3692 }
3693
3695
3696 auto t_normal = getFTensor1NormalsAtGaussPts();
3697 auto t_T = dataAtPts->getFTensorFaceMaterialForce(
3698 nb_gauss_pts); //< face material force
3699 auto t_p =
3700 getFTensor0FromVec(dataAtPts->normalPressureAtPts); //< normal pressure
3701 auto t_P = dataAtPts->getFTensorApproxP(nb_gauss_pts);
3702 auto t_u_gamma = dataAtPts->getFTensorSmallHybridDisp(nb_gauss_pts);
3703 auto t_grad_u_gamma = dataAtPts->getFTensorGradHybridDisp(nb_gauss_pts);
3704 auto t_strain = dataAtPts->getFTensorLogStretch(nb_gauss_pts);
3705 auto t_omega = dataAtPts->getFTensorRotAxis(nb_gauss_pts);
3706
3712
3713 auto next = [&]() {
3714 ++t_normal;
3715 ++t_P;
3716 // ++t_grad_P;
3717 ++t_omega;
3718 ++t_u_gamma;
3719 ++t_grad_u_gamma;
3720 ++t_strain;
3721 ++t_T;
3722 ++t_p;
3723 };
3724
3726 case GRIFFITH_FORCE:
3727 for (auto gg = 0; gg != getGaussPts().size2(); ++gg) {
3728 t_N(I) = t_normal(I);
3729 t_N.normalize();
3730
3731 t_A(i, j) = levi_civita(i, j, k) * t_omega(k);
3732 t_R(i, k) = t_kd(i, k) + t_A(i, k);
3733 t_grad_u(i, j) = t_R(i, j) + t_strain(i, j);
3734
3735 t_T(I) += t_N(J) * (t_grad_u(i, I) * t_P(i, J)) / loop_size;
3736 // note that works only for Hooke material, for nonlinear material we need
3737 // strain energy expressed by stress
3738 t_T(I) -= t_N(I) * ((t_strain(i, K) * t_P(i, K)) / 2.) / loop_size;
3739
3740 t_p += t_N(I) *
3741 (t_N(J) * ((t_kd(i, I) + t_grad_u_gamma(i, I)) * t_P(i, J))) /
3742 loop_size;
3743
3744 next();
3745 }
3746 break;
3747 case GRIFFITH_SKELETON:
3748 for (auto gg = 0; gg != getGaussPts().size2(); ++gg) {
3749
3750 // Normalize the normal
3751 t_N(I) = t_normal(I);
3752 t_N.normalize();
3753
3754 // R = ε − sym(u^Γ)
3755 t_R(i, j) =
3756 t_strain(i, j) - 0.5 * (t_grad_u_gamma(i, j) + t_grad_u_gamma(j, i));
3757
3758 // U = u^Γ + [2 R N − (Nᵀ R N) N] ⊗ N
3759 t_grad_u(i, J) =
3760 t_grad_u_gamma(i, J) +
3761 (2 * t_R(i, K) * t_N(K) - (t_R(k, L) * t_N(k) * t_N(L)) * t_N(i)) *
3762 t_N(J);
3763
3764 t_T(I) += t_N(J) * (t_grad_u(i, I) * t_P(i, J)) / loop_size;
3765 // note that works only for Hooke material, for nonlinear material we need
3766 // strain energy expressed by stress
3767 t_T(I) -= t_N(I) * ((t_strain(i, K) * t_P(i, K)) / 2.) / loop_size;
3768
3769 // calculate nominal face pressure
3770 t_p += t_N(I) *
3771 (t_N(J) * ((t_kd(i, I) + t_grad_u_gamma(i, I)) * t_P(i, J))) /
3772 loop_size;
3773
3774 next();
3775 }
3776 break;
3777
3778 default:
3779 SETERRQ(PETSC_COMM_WORLD, MOFEM_NOT_IMPLEMENTED,
3780 "Grffith energy release "
3781 "selector not implemented");
3782 };
3783
3784#ifndef NDEBUG
3785 auto side_fe_ptr = getSidePtrFE();
3786 auto side_fe_mi_ptr = side_fe_ptr->numeredEntFiniteElementPtr;
3787 auto pstatus = side_fe_mi_ptr->getPStatus();
3788 if (pstatus) {
3789 auto owner = side_fe_mi_ptr->getOwnerProc();
3790 MOFEM_LOG("SELF", Sev::noisy)
3791 << "OpFaceSideMaterialForce: owner proc is not 0, owner proc: " << owner
3792 << " " << getPtrFE()->mField.get_comm_rank() << " n in the loop "
3793 << getNinTheLoop() << " loop size " << getLoopSize();
3794 }
3795#endif // NDEBUG
3796
3798}
3799
3801 EntData &data) {
3803
3804#ifndef NDEBUG
3805 auto fe_mi_ptr = getFEMethod()->numeredEntFiniteElementPtr;
3806 auto pstatus = fe_mi_ptr->getPStatus();
3807 if (pstatus) {
3808 auto owner = fe_mi_ptr->getOwnerProc();
3809 MOFEM_LOG("SELF", Sev::noisy)
3810 << "OpFaceMaterialForce: owner proc is not 0, owner proc: " << owner
3811 << " " << getPtrFE()->mField.get_comm_rank();
3812 }
3813#endif // NDEBUG
3814
3816
3818 t_face_T(I) = 0.;
3819 double face_pressure = 0.;
3820 auto t_T = dataAtPts->getFTensorFaceMaterialForce(
3821 getGaussPts().size2()); //< face material force
3822 auto t_p =
3823 getFTensor0FromVec(dataAtPts->normalPressureAtPts); //< normal pressure
3824 auto t_w = getFTensor0IntegrationWeight();
3825 for (auto gg = 0; gg != getGaussPts().size2(); ++gg) {
3826 t_face_T(I) += t_w * t_T(I);
3827 face_pressure += t_w * t_p;
3828 ++t_w;
3829 ++t_T;
3830 ++t_p;
3831 }
3832 t_face_T(I) *= getMeasure();
3833 face_pressure *= getMeasure();
3834
3835 auto get_tag = [&](auto name, auto dim) {
3836 auto &moab = getPtrFE()->mField.get_moab();
3837 Tag tag;
3838 double def_val[] = {0., 0., 0.};
3839 CHK_MOAB_THROW(moab.tag_get_handle(name, dim, MB_TYPE_DOUBLE, tag,
3840 MB_TAG_CREAT | MB_TAG_SPARSE, def_val),
3841 "create tag");
3842 return tag;
3843 };
3844
3845 auto set_tag = [&](auto &&tag, auto ptr) {
3846 auto &moab = getPtrFE()->mField.get_moab();
3847 auto face = getPtrFE()->getFEEntityHandle();
3848 CHK_MOAB_THROW(moab.tag_set_data(tag, &face, 1, ptr), "set tag");
3849 };
3850
3851 set_tag(get_tag("MaterialForce", 3), &t_face_T(0));
3852 set_tag(get_tag("FacePressure", 1), &face_pressure);
3853
3855}
3856
3857template <typename OP_PTR>
3858std::tuple<std::string, MatrixDouble>
3860 const std::string block_name) {
3861
3862 auto nb_gauss_pts = op_ptr->getGaussPts().size2();
3863
3864 auto ts_time = op_ptr->getTStime();
3865 auto ts_time_step = op_ptr->getTStimeStep();
3866
3869 ts_time_step = EshelbianCore::physicalDt;
3870 }
3871
3872 MatrixDouble m_ref_coords = op_ptr->getCoordsAtGaussPts();
3873 MatrixDouble m_ref_normals = op_ptr->getNormalsAtGaussPts();
3874
3875 auto v_analytical_expr =
3876 analytical_expr_function(ts_time_step, ts_time, nb_gauss_pts,
3877 m_ref_coords, m_ref_normals, block_name);
3878
3879 if (PetscUnlikely(!v_analytical_expr.size2())) {
3881 "Analytical expression is empty or does not exist, "
3882 "check python file");
3883 }
3884
3885 return std::make_tuple(block_name, v_analytical_expr);
3886}
3887
3889 boost::shared_ptr<std::vector<BrokenBaseSideData>> broken_base_side_data,
3890 boost::shared_ptr<MatrixDouble> vec, ScalarFun beta_coeff,
3891 boost::shared_ptr<Range> ents_ptr)
3892 : OP(broken_base_side_data, ents_ptr) {
3893 this->sourceVec = vec;
3894 this->betaCoeff = beta_coeff;
3895}
3896
3898 boost::shared_ptr<std::vector<BrokenBaseSideData>> broken_base_side_data,
3899 ScalarFun beta_coeff, boost::shared_ptr<Range> ents_ptr)
3900 : OP(broken_base_side_data, ents_ptr) {
3901 this->sourceVec = boost::shared_ptr<MatrixDouble>();
3902 this->betaCoeff = beta_coeff;
3903}
3904
3906OpBrokenBaseTimesBrokenDisp::doWork(int row_side, EntityType row_type,
3907 EntitiesFieldData::EntData &row_data) {
3909
3910 if (OP::entsPtr) {
3911 if (OP::entsPtr->find(this->getFEEntityHandle()) == OP::entsPtr->end())
3913 }
3914
3915#ifndef NDEBUG
3916 if (!brokenBaseSideData) {
3917 SETERRQ(PETSC_COMM_SELF, MOFEM_IMPOSSIBLE_CASE, "space not set");
3918 }
3919#endif // NDEBUG
3920
3921 auto do_work_rhs = [this](int row_side, EntityType row_type,
3922 EntitiesFieldData::EntData &row_data) {
3924 // get number of dofs on row
3925 OP::nbRows = row_data.getIndices().size();
3926 if (!OP::nbRows)
3928 // get number of integration points
3929 OP::nbIntegrationPts = OP::getGaussPts().size2();
3930 // get row base functions
3931 OP::nbRowBaseFunctions = OP::getNbOfBaseFunctions(row_data);
3932 // resize and clear the right hand side vector
3933 OP::locF.resize(OP::nbRows, false);
3934 OP::locF.clear();
3935 // integrate local vector
3936 CHKERR this->iNtegrate(row_data);
3937 // assemble local vector
3938 CHKERR this->aSsemble(row_data);
3940 };
3941
3942 switch (OP::opType) {
3943 case OP::OPSPACE:
3944 for (auto &bd : *brokenBaseSideData) {
3945 this->sourceVec =
3946 boost::shared_ptr<MatrixDouble>(brokenBaseSideData, &bd.getFlux());
3947 CHKERR do_work_rhs(bd.getSide(), bd.getType(), bd.getData());
3948 this->sourceVec.reset();
3949 }
3950 break;
3951 default:
3953 (std::string("wrong op type ") +
3954 OpBaseDerivativesBase::OpTypeNames[OP::opType])
3955 .c_str());
3956 }
3957
3959}
3960
3962 const std::string row_field,
3963 boost::shared_ptr<std::vector<BrokenBaseSideData>> broken_base_side_data,
3964 ScalarFun beta_coeff, boost::shared_ptr<Range> ents_ptr)
3965 : OP(row_field, boost::shared_ptr<MatrixDouble>(), beta_coeff, ents_ptr),
3966 brokenBaseSideDataPtr(broken_base_side_data) {
3967 this->betaCoeff = beta_coeff;
3968}
3969
3973 for (auto &bd : (*brokenBaseSideDataPtr)) {
3974 this->sourceVec =
3975 boost::shared_ptr<MatrixDouble>(brokenBaseSideDataPtr, &bd.getFlux());
3976
3977#ifndef NDEBUG
3978 if (this->sourceVec->size2() != SPACE_DIM) {
3979 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
3980 "Inconsistent size of the source vector");
3981 }
3982 if (this->sourceVec->size1() != OP::getGaussPts().size2()) {
3983 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
3984 "Inconsistent size of the source vector");
3985 }
3986#endif // NDEBUG
3987
3988 CHKERR OP::iNtegrate(data);
3989
3990 this->sourceVec.reset();
3991 }
3993}
3994
3996 std::string row_field,
3997 boost::shared_ptr<std::vector<BrokenBaseSideData>> broken_base_side_data,
3998 ScalarFun beta, const bool assmb_transpose, const bool only_transpose,
3999 boost::shared_ptr<Range> ents_ptr)
4000 : OP(row_field, broken_base_side_data, assmb_transpose, only_transpose,
4001 ents_ptr) {
4002 this->betaCoeff = beta;
4003 this->sYmm = false;
4004}
4005
4007 boost::shared_ptr<std::vector<BrokenBaseSideData>> broken_base_side_data,
4008 ScalarFun beta, boost::shared_ptr<Range> ents_ptr)
4009 : OP(broken_base_side_data, ents_ptr) {
4010 this->sYmm = false;
4011 this->betaCoeff = beta;
4012 OP::assembleTranspose = false;
4013 OP::onlyTranspose = false;
4014}
4015
4017OpBrokenBaseBrokenBase::doWork(int row_side, EntityType row_type,
4018 EntitiesFieldData::EntData &row_data) {
4020
4021 if (OP::entsPtr) {
4022 if (OP::entsPtr->find(this->getFEEntityHandle()) == OP::entsPtr->end())
4024 }
4025
4026#ifndef NDEBUG
4027 if (!brokenBaseSideData) {
4028 SETERRQ(PETSC_COMM_SELF, MOFEM_IMPOSSIBLE_CASE, "space not set");
4029 }
4030#endif // NDEBUG
4031
4032 auto do_work_lhs = [this](int row_side, int col_side, EntityType row_type,
4033 EntityType col_type,
4035 EntitiesFieldData::EntData &col_data) {
4037
4038 auto check_if_assemble_transpose = [&] {
4039 if (this->sYmm) {
4040 if (OP::rowSide != OP::colSide || OP::rowType != OP::colType)
4041 return true;
4042 else
4043 return false;
4044 } else if (OP::assembleTranspose) {
4045 return true;
4046 }
4047 return false;
4048 };
4049
4050 OP::rowSide = row_side;
4051 OP::rowType = row_type;
4052 OP::colSide = col_side;
4053 OP::colType = col_type;
4054 OP::nbCols = col_data.getIndices().size();
4055 OP::locMat.resize(OP::nbRows, OP::nbCols, false);
4056 OP::locMat.clear();
4057 CHKERR this->iNtegrate(row_data, col_data);
4058 CHKERR this->aSsemble(row_data, col_data, check_if_assemble_transpose());
4060 };
4061
4062 switch (OP::opType) {
4063 case OP::OPSPACE:
4064
4065 for (auto &bd : *brokenBaseSideData) {
4066
4067#ifndef NDEBUG
4068 if (!bd.getData().getNSharedPtr(bd.getData().getBase())) {
4069 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
4070 "base functions not set");
4071 }
4072#endif
4073
4074 OP::nbRows = bd.getData().getIndices().size();
4075 if (!OP::nbRows)
4077 OP::nbIntegrationPts = OP::getGaussPts().size2();
4078 OP::nbRowBaseFunctions = OP::getNbOfBaseFunctions(bd.getData());
4079
4080 if (!OP::nbRows)
4082
4083 CHKERR do_work_lhs(
4084
4085 // side
4086 bd.getSide(), bd.getSide(),
4087
4088 // type
4089 bd.getType(), bd.getType(),
4090
4091 // row_data
4092 bd.getData(), bd.getData()
4093
4094 );
4095 }
4096
4097 break;
4098
4099 default:
4101 (std::string("wrong op type ") +
4102 OpBaseDerivativesBase::OpTypeNames[OP::opType])
4103 .c_str());
4104 }
4105
4107}
4108
4109} // namespace EshelbianPlasticity
Auxilary functions for Eshelbian plasticity.
Eshelbian plasticity interface.
std::string type
Lie algebra implementation.
#define FTENSOR_INDEX(DIM, I)
constexpr double a
constexpr int SPACE_DIM
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_IMPOSSIBLE_CASE
Definition definitions.h:35
@ 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
boost::function< double(const double, const double, const double)> ScalarFun
Scalar function type.
#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.
auto sort_eigen_vals(A &eig, B &eigen_vec)
static Tag get_tag(moab::Interface &moab, std::string tag_name, int size)
std::tuple< std::string, MatrixDouble > getAnalyticalExpr(OP_PTR op_ptr, MatrixDouble &analytical_expr, const std::string block_name)
DataLayoutTraits< DataLayout::GaussByCoeffs > DL
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
implementation of Data Operators for Forces and Sources
Definition Common.hpp:10
decltype(GetFTensor2SymmetricFromMatImpl< Tensor_Dim, S, DL, M >::get(std::declval< M & >(), 0, 0)) GetFTensor2SymmetricFromMatType
auto getFTensor2FromMat(M &data)
Get tensor rank 2 (matrix) form data matrix.
decltype(GetFTensor4FromMatImpl< Tensor_Dim0, Tensor_Dim1, Tensor_Dim2, Tensor_Dim3, S, DL, M >::get(std::declval< M & >(), 0, 0)) GetFTensor4FromMatType
decltype(GetFTensor4DdgFromMatImpl< Tensor_Dim01, Tensor_Dim23, S, DL, M >::get(std::declval< M & >(), 0, 0)) GetFTensor4DdgFromMatType
auto getFTensor1FromMat(M &data, int rr=0, int cc=0)
Get tensor rank 1 (vector) form data matrix.
decltype(GetFTensor1FromMatImpl< Tensor_Dim, S, DL, M >::get(std::declval< M & >(), 0, 0)) GetFTensor1FromMatType
MoFEMErrorCode computeEigenValuesSymmetric(const MatrixDouble &mat, VectorDouble &eig, MatrixDouble &eigen_vec)
compute eigenvalues of a symmetric matrix using lapack dsyev
static auto getFTensor0FromVec(V &data)
Get tensor rank 0 (scalar) form data vector.
static auto determinantTensor3by3(T &t)
Calculate the determinant of a 3x3 matrix or a tensor of rank 2.
decltype(GetFTensor3FromMatImpl< Tensor_Dim0, Tensor_Dim1, Tensor_Dim2, S, DL, M >::get(std::declval< M & >(), 0, 0)) GetFTensor3FromMatType
decltype(GetFTensor2FromMatImpl< Tensor_Dim0, Tensor_Dim1, S, DL, M >::get(std::declval< M & >(), 0, 0)) GetFTensor2FromMatType
constexpr IntegrationType I
constexpr auto field_name
FTensor::Index< 'm', 3 > m
const int N
Definition speed_test.cpp:3
static enum StretchSelector stretchSelector
static PetscBool l2UserBaseScale
static enum RotSelector rotSelector
static enum RotSelector gradApproximator
static double physicalDt
static PetscBool physicalTimeFlg
static double currentPhysicalTime
static boost::function< double(const double)> f
static PetscBool setSingularity
static bool hasNonHomogeneousMaterialBlock
static boost::function< double(const double)> d_f
static enum EnergyReleaseSelector energyReleaseSelector
static boost::function< double(const double)> inv_f
static auto diffDiffExp(A &&t_w_vee, B &&theta)
Definition Lie.hpp:105
static auto diffExp(A &&t_w_vee, B &&theta)
Definition Lie.hpp:100
static auto exp(A &&t_w_vee, B &&theta)
Definition Lie.hpp:69
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::Tensor0< FTensor::PackPtr< double *, 1 > > getFTensor0N(const FieldApproximationBase base)
Get base function as Tensor0.
const VectorFieldEntities & getFieldEntities() const
Get field entities (const version)
auto getFTensor2N(FieldApproximationBase base)
Get base functions for Hdiv/Hcurl spaces.
auto getFTensor1DiffN(const FieldApproximationBase base)
Get derivatives of base functions.
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.
auto 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 doWork(int row_side, EntityType row_type, EntitiesFieldData::EntData &row_data)
OpBrokenBaseBrokenBase(boost::shared_ptr< std::vector< BrokenBaseSideData > > broken_base_side_data, ScalarFun beta, boost::shared_ptr< Range > ents_ptr=nullptr)
MoFEMErrorCode doWork(int row_side, EntityType row_type, EntitiesFieldData::EntData &row_data)
OpBrokenBaseTimesBrokenDisp(boost::shared_ptr< std::vector< BrokenBaseSideData > > broken_base_side_data, ScalarFun beta_coeff=[](double, double, double) constexpr { return 1;}, boost::shared_ptr< Range > ents_ptr=nullptr)
OpBrokenBaseTimesHybridDisp(boost::shared_ptr< std::vector< BrokenBaseSideData > > broken_base_side_data, boost::shared_ptr< MatrixDouble > vec, ScalarFun beta_coeff=[](double, double, double) constexpr { return 1;}, boost::shared_ptr< Range > ents_ptr=nullptr)
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)
OpHybridBaseTimesBrokenDisp(const std::string row_field, boost::shared_ptr< std::vector< BrokenBaseSideData > > broken_base_side_data, ScalarFun beta_coeff, boost::shared_ptr< Range > ents_ptr=nullptr)
MoFEMErrorCode iNtegrate(EntitiesFieldData::EntData &data)
boost::shared_ptr< std::vector< BrokenBaseSideData > > brokenBaseSideDataPtr
OpHyrbridBaseBrokenBase(std::string row_field, boost::shared_ptr< std::vector< BrokenBaseSideData > > broken_base_side_data, ScalarFun beta, const bool assmb_transpose, const bool only_transpose, boost::shared_ptr< Range > ents_ptr=nullptr)
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)
MoFEMErrorCode integrate(EntData &row_data, EntData &col_data)
MoFEMErrorCode iNtegrate(EntData &row_data, EntData &col_data)
MoFEMErrorCode iNtegrate(EntData &data)
MoFEMErrorCode iNtegrate(EntData &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:124