v0.16.3
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#include <optional>
23
24namespace EshelbianPlasticity {
25
27 VectorPtr external_pressure_ptr,
28 boost::shared_ptr<ExternalStrainVec> external_strain_vec_ptr,
29 std::map<std::string, boost::shared_ptr<ScalingMethod>> smv)
30 : VolUserDataOperator(H1, OPLAST),
31 externalPressurePtr(std::move(external_pressure_ptr)),
32 externalStrainVecPtr(std::move(external_strain_vec_ptr)),
33 scalingMethodsMap(std::move(smv)) {
34 std::fill(&doEntities[MBVERTEX], &doEntities[MBMAXTYPE], false);
35 doEntities[MBVERTEX] = true;
36}
37
39 EntData &) {
41
43 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
44 "External-pressure integration-point vector is null");
45 }
46
47 const int nb_integration_pts = getGaussPts().size2();
48 externalPressurePtr->resize(nb_integration_pts, false);
49 externalPressurePtr->clear();
52 }
53
54 double time = 0;
55 double time_step = 0;
58 time_step = EshelbianCore::physicalDt;
59 } else if ((getFEMethod()->data_ctx & PetscData::CtxSetTime).any()) {
60 time = getTStime();
61 time_step = getTStimeStep();
62 }
63 const EntityHandle fe_ent = getFEEntityHandle();
64 const std::regex analytical_pattern("(.*)ANALYTICAL_EXTERNALSTRAIN(.*)");
65
66 for (const auto &block : *externalStrainVecPtr) {
67 if (block.ents.find(fe_ent) == block.ents.end()) {
68 continue;
69 }
70 if (!std::isfinite(block.bulkModulusK)) {
71 SETERRQ(PETSC_COMM_SELF, MOFEM_INVALID_DATA,
72 "External-strain bulk modulus is not finite in block %s",
73 block.blockName.c_str());
74 }
75
76 VectorDouble external_strain(nb_integration_pts);
77 if (std::regex_match(block.blockName, analytical_pattern)) {
78 auto reference_coordinates = getCoordsAtGaussPts();
79 external_strain = analytical_externalstrain_function(
80 time_step, time, nb_integration_pts, reference_coordinates,
81 block.blockName);
82 } else {
83 double scale = 1;
84 if (const auto it = scalingMethodsMap.find(block.blockName);
85 it != scalingMethodsMap.end()) {
86 if (!it->second) {
87 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
88 "Scaling method is null for external-strain block %s",
89 block.blockName.c_str());
90 }
91 scale = it->second->getScale(time);
92 } else {
93 MOFEM_LOG("EP", Sev::warning)
94 << "No scaling method found for " << block.blockName;
95 }
96 std::fill(external_strain.begin(), external_strain.end(),
97 scale * block.val);
98 }
99
100 if (external_strain.size() != nb_integration_pts) {
101 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
102 "Wrong number of analytical external-strain integration points");
103 }
104 for (int gg = 0; gg != nb_integration_pts; ++gg) {
105 const double q = 3 * block.bulkModulusK * external_strain[gg];
106 if (!std::isfinite(q)) {
107 SETERRQ(PETSC_COMM_SELF, MOFEM_INVALID_DATA,
108 "External pressure q is not finite in block %s",
109 block.blockName.c_str());
110 }
111 (*externalPressurePtr)[gg] += q;
112 if (!std::isfinite((*externalPressurePtr)[gg])) {
113 SETERRQ(PETSC_COMM_SELF, MOFEM_INVALID_DATA,
114 "Accumulated external pressure q is not finite in block %s",
115 block.blockName.c_str());
116 }
117 }
118 }
119
121}
122
123template <typename TInvD, typename TRotation, typename TDiffRotation,
124 typename TStress>
125auto getDiffSpatialGradientDR(TInvD &t_d_u_d_b, TRotation &t_R,
126 TDiffRotation &t_diff_R, TStress &t_P) {
127 FTENSOR_INDEXES(SPACE_DIM, i, j, k, l, m, n);
129 t_d_rotated_p_d_omega;
130 t_d_rotated_p_d_omega(i, j, k) = t_diff_R(n, i, k) * t_P(n, j);
131
133 t_d_b_d_omega(i, j, k) =
134 (t_d_rotated_p_d_omega(i, j, k) || t_d_rotated_p_d_omega(j, i, k)) / 2.;
135
137 t_d_u_d_omega(i, j, k) = t_d_u_d_b(i, j, l, m) * t_d_b_d_omega(l, m, k);
138
140 t_d_h_d_omega(i, j, k) = t_R(i, l) * t_d_u_d_omega(j, l, k);
141
142 return std::make_tuple(t_d_b_d_omega, t_d_u_d_omega, t_d_h_d_omega);
143}
144
146 EntityType type,
147 EntData &data) {
149
150 auto ts_ctx = getTSCtx();
151 int nb_integration_pts = getGaussPts().size2();
152
153 // space size indices
163
164 // sym size indices
166
167 auto t_L = FTensor::SymmLTensor<double, 3>();
168
170 *dataAtPts->getStretchTensorAtPts(), nb_integration_pts);
171 MatrixSizeHelper<GetFTensor4DdgFromMatType<3, 3, -1, DL>, DL>::size(
172 *dataAtPts->getDiffStretchTensorAtPts(), nb_integration_pts);
173 MatrixSizeHelper<GetFTensor2FromMatType<3, 3, -1, DL>, DL>::size(
174 *dataAtPts->getStretchH1AtPts(), nb_integration_pts);
175 MatrixSizeHelper<GetFTensor4FromMatType<3, 3, 3, 3, -1, DL>, DL>::size(
176 *dataAtPts->getDiffStretchH1AtPts(), nb_integration_pts);
177 MatrixSizeHelper<GetFTensor2FromMatType<3, 3, -1, DL>, DL>::size(
178 *dataAtPts->getAdjointPdstretchAtPts(), nb_integration_pts);
180 *dataAtPts->getAdjointPdUAtPts(), nb_integration_pts);
181 MatrixSizeHelper<GetFTensor3FromMatType<3, 3, size_symm, -1, DL>, DL>::size(
182 *dataAtPts->getAdjointPdUdPAtPts(), nb_integration_pts);
184 *dataAtPts->getAdjointPdUdOmegaAtPts(), nb_integration_pts);
185
186 MatrixSizeHelper<GetFTensor2FromMatType<3, 3, -1, DL>, DL>::size(
187 *dataAtPts->getDeformationGradient(), nb_integration_pts);
189 *dataAtPts->getPlasticH(), nb_integration_pts);
191 *dataAtPts->getPlasticF(), nb_integration_pts);
192 MatrixSizeHelper<GetFTensor2FromMatType<3, 3, -1, DL>, DL>::size(
193 *dataAtPts->getInvPlasticF(), nb_integration_pts);
194 MatrixSizeHelper<GetFTensor3FromMatType<3, 3, 3, -1, DL>, DL>::size(
195 dataAtPts->hdOmegaAtPts, nb_integration_pts);
196 MatrixSizeHelper<GetFTensor3FromMatType<3, 3, size_symm, -1, DL>, DL>::size(
197 dataAtPts->hdLogStretchAtPts, nb_integration_pts);
198
199 MatrixSizeHelper<GetFTensor1FromMatType<3, -1, DL>, DL>::size(
200 dataAtPts->leviKirchhoffAtPts, nb_integration_pts);
201 MatrixSizeHelper<GetFTensor1FromMatType<3, -1, DL>, DL>::size(
202 dataAtPts->leviKirchhoff0AtPts, nb_integration_pts);
203 MatrixSizeHelper<GetFTensor2FromMatType<3, 3, -1, DL>, DL>::size(
204 dataAtPts->leviKirchhoffdOmegaAtPts, nb_integration_pts);
206 dataAtPts->leviKirchhoffdLogStreatchAtPts, nb_integration_pts);
207 MatrixSizeHelper<GetFTensor3FromMatType<3, 3, 3, -1, DL>, DL>::size(
208 dataAtPts->leviKirchhoffPAtPts, nb_integration_pts);
209
210 MatrixSizeHelper<GetFTensor2FromMatType<3, 3, -1, DL>, DL>::size(
211 dataAtPts->rotMatAtPts, nb_integration_pts);
212 MatrixSizeHelper<GetFTensor1FromMatType<3, -1, DL>, DL>::size(
213 *dataAtPts->getEigenVals(), nb_integration_pts);
214 MatrixSizeHelper<GetFTensor2FromMatType<3, 3, -1, DL>, DL>::size(
215 *dataAtPts->getEigenVecs(), nb_integration_pts);
216 dataAtPts->nbUniq.resize(nb_integration_pts, false);
217 MatrixSizeHelper<GetFTensor1FromMatType<3, -1, DL>, DL>::size(
218 dataAtPts->eigenValsC, nb_integration_pts);
219 MatrixSizeHelper<GetFTensor2FromMatType<3, 3, -1, DL>, DL>::size(
220 dataAtPts->eigenVecsC, nb_integration_pts);
221 dataAtPts->nbUniqC.resize(nb_integration_pts, false);
222
224 dataAtPts->logStretch2H1AtPts, nb_integration_pts);
226 dataAtPts->logStretchTotalTensorAtPts, nb_integration_pts);
227
228 MatrixSizeHelper<GetFTensor2FromMatType<3, 3, -1, DL>, DL>::size(
229 dataAtPts->internalStressAtPts, nb_integration_pts);
230 dataAtPts->internalStressAtPts.clear();
231
232 // Reconstruct the fixed plastic deformation before evaluating volume
233 // equations. Their work-conjugate stress is the Piola transform
234 // P_bar = P F_p^T / J_p, whereas reference equilibrium continues to use P.
235 auto t_log_plasticH = dataAtPts->getFTensorPlasticH(nb_integration_pts);
236 auto t_plasticF_reconstruct =
237 dataAtPts->getFTensorPlasticF(nb_integration_pts);
238 auto t_invPlasticF_reconstruct =
239 dataAtPts->getFTensorInvPlasticF(nb_integration_pts);
240 const EigenMatrix::Fun<double> exp_fun = [](const double v) {
241 return std::exp(v);
242 };
243 const EigenMatrix::Fun<double> inv_exp_fun = [](const double v) {
244 return std::exp(-v);
245 };
246 for (int gg = 0; gg != nb_integration_pts; ++gg) {
249 t_eigen_vecs(i, j) = t_log_plasticH(i, j);
250 if (computeEigenValuesSymmetric(t_eigen_vecs, t_eigen_vals) != MB_SUCCESS)
251 SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
252 "Failed to diagonalise logarithmic plastic deformation");
253 const auto t_exp_plasticH =
254 EigenMatrix::getMat(t_eigen_vals, t_eigen_vecs, exp_fun);
255 const auto t_inv_exp_plasticH =
256 EigenMatrix::getMat(t_eigen_vals, t_eigen_vecs, inv_exp_fun);
257 t_plasticF_reconstruct(i, j) = t_exp_plasticH(i, j);
258 t_invPlasticF_reconstruct(i, j) = t_inv_exp_plasticH(i, j);
259
260#ifndef NDEBUG
261 const double det_plasticF =
262 determinantTensor3by3(t_plasticF_reconstruct);
263 if (!std::isfinite(det_plasticF) ||
264 det_plasticF <= std::numeric_limits<double>::epsilon())
265 SETERRQ(PETSC_COMM_SELF, MOFEM_INVALID_DATA,
266 "Plastic deformation gradient must have a positive determinant; "
267 "got %g",
268 det_plasticF);
269#endif
270
271 ++t_log_plasticH;
272 ++t_plasticF_reconstruct;
273 ++t_invPlasticF_reconstruct;
274 }
275
276 MatrixDouble intermediate_p_at_pts;
277 MatrixDouble intermediate_p0_at_pts;
278 auto get_intermediate_p =
280 DL>::size(intermediate_p_at_pts, nb_integration_pts);
281 auto get_intermediate_p0 =
283 DL>::size(intermediate_p0_at_pts, nb_integration_pts);
284 auto t_reference_P = dataAtPts->getFTensorApproxP(nb_integration_pts);
285 auto t_reference_P0 = dataAtPts->getFTensorApproxP0(nb_integration_pts);
286 auto t_plasticF = dataAtPts->getFTensorPlasticF(nb_integration_pts);
287 auto t_intermediate_P = get_intermediate_p();
288 auto t_intermediate_P0 = get_intermediate_p0();
289 for (int gg = 0; gg != nb_integration_pts; ++gg) {
290 const double det_plasticF = determinantTensor3by3(t_plasticF);
291 t_intermediate_P(i, j) =
292 t_reference_P(i, k) * t_plasticF(j, k) / det_plasticF;
293 t_intermediate_P0(i, j) =
294 t_reference_P0(i, k) * t_plasticF(j, k) / det_plasticF;
295 ++t_reference_P;
296 ++t_reference_P0;
297 ++t_plasticF;
298 ++t_intermediate_P;
299 ++t_intermediate_P0;
300 }
301
302 // Calculated values
303 auto t_h = dataAtPts->getFTensorSmallH(getGaussPts().size2());
304 auto t_h_domega = dataAtPts->getFTensorSmallHdOmega(getGaussPts().size2());
305 auto t_h_dlog_u =
306 dataAtPts->getFTensorSmallHdLogStretch(getGaussPts().size2());
307 auto t_levi_kirchhoff =
308 dataAtPts->getFTensorLeviKirchhoff(getGaussPts().size2());
309 auto t_levi_kirchhoff0 =
310 dataAtPts->getFTensorLeviKirchhoff0(getGaussPts().size2());
311 auto t_levi_kirchhoff_domega =
312 dataAtPts->getFTensorLeviKirchhoffdOmega(getGaussPts().size2());
313 auto t_levi_kirchhoff_dstreach =
314 dataAtPts->getFTensorLeviKirchhoffdLogStretch(getGaussPts().size2());
315 auto t_levi_kirchhoff_dP =
316 dataAtPts->getFTensorLeviKirchhoffP(getGaussPts().size2());
317 auto t_approx_P_adjoint_dstretch =
318 dataAtPts->getFTensorAdjointPdstretch(getGaussPts().size2());
319 auto t_approx_P_adjoint_log_du =
320 dataAtPts->getFTensorAdjointPdU(getGaussPts().size2());
321 auto t_approx_P_adjoint_log_du_dP =
322 dataAtPts->getFTensorAdjointPdUdP(getGaussPts().size2());
323 auto t_approx_P_adjoint_log_du_domega =
324 dataAtPts->getFTensorAdjointPdUdOmega(getGaussPts().size2());
325 auto t_R = dataAtPts->getFTensorRotMat(getGaussPts().size2());
326 auto t_u = dataAtPts->getFTensorStretch(getGaussPts().size2());
327 auto t_diff_u = dataAtPts->getFTensorDiffStretch(getGaussPts().size2());
328 auto t_eigen_vals = dataAtPts->getFTensorEigenVals(getGaussPts().size2());
329 auto t_eigen_vecs = dataAtPts->getFTensorEigenVecs(getGaussPts().size2());
330 auto &nbUniq = dataAtPts->nbUniq;
331 auto t_nb_uniq =
332 FTensor::Tensor0<FTensor::PackPtr<int *, 1>>(nbUniq.data().data());
333 auto t_eigen_vals_C = dataAtPts->getFTensorEigenValsC(nb_integration_pts);
334 auto t_eigen_vecs_C = dataAtPts->getFTensorEigenVecsC(nb_integration_pts);
335 auto &nbUniqC = dataAtPts->nbUniqC;
336 auto t_nb_uniq_C =
337 FTensor::Tensor0<FTensor::PackPtr<int *, 1>>(nbUniqC.data().data());
338
339 auto t_u_h1 = dataAtPts->getFTensorStretchH1(getGaussPts().size2());
340 auto t_diff_u_h1 = dataAtPts->getFTensorDiffStretchH1(getGaussPts().size2());
341 auto t_log_stretch_total =
342 dataAtPts->getFTensorLogStretchTotal(getGaussPts().size2());
343 auto t_log_u2_h1 = dataAtPts->getFTensorLogStretch2H1(getGaussPts().size2());
344
345 // Field values
346 auto t_grad_h1 = dataAtPts->getFTensorSmallWGradH1(getGaussPts().size2());
347 auto t_omega = dataAtPts->getFTensorRotAxis(getGaussPts().size2());
348 auto t_approx_P = get_intermediate_p();
349 auto t_approx_P0 = get_intermediate_p0();
350 auto t_log_u = dataAtPts->getFTensorLogStretch(getGaussPts().size2());
351
352 // Rot axis 0
353 auto t_omega0 = dataAtPts->getFTensorRotAxis0(getGaussPts().size2());
354 auto t_log_u0 = dataAtPts->getFTensorLogStretch0(getGaussPts().size2());
355
356 auto next = [&]() {
357 // calculated values
358 ++t_h;
359 ++t_h_domega;
360 ++t_h_dlog_u;
361 ++t_levi_kirchhoff;
362 ++t_levi_kirchhoff0;
363 ++t_levi_kirchhoff_domega;
364 ++t_levi_kirchhoff_dstreach;
365 ++t_levi_kirchhoff_dP;
366 ++t_approx_P_adjoint_dstretch;
367 ++t_approx_P_adjoint_log_du;
368 ++t_approx_P_adjoint_log_du_dP;
369 ++t_approx_P_adjoint_log_du_domega;
370 ++t_R;
371 ++t_u;
372 ++t_diff_u;
373 ++t_eigen_vals;
374 ++t_eigen_vecs;
375 ++t_nb_uniq;
376 ++t_eigen_vals_C;
377 ++t_eigen_vecs_C;
378 ++t_nb_uniq_C;
379 ++t_u_h1;
380 ++t_diff_u_h1;
381 ++t_log_u2_h1;
382 ++t_log_stretch_total;
383 // field values
384 ++t_omega;
385 ++t_omega0;
386 ++t_grad_h1;
387 ++t_approx_P;
388 ++t_approx_P0;
389 ++t_log_u;
390 ++t_log_u0;
391 };
392
395 constexpr auto t_diff_sym = FTensor::DiffSymmetrize<double>();
396
397 auto calculate_stretch_from_log = [&](auto &t_log_u_src, auto &t_u_dst,
398 auto &t_eigen_vals_dst,
399 auto &t_eigen_vecs_dst,
400 int &nb_uniq_dst) {
404 eigen_vec(i, j) = t_log_u_src(i, j);
405 if (computeEigenValuesSymmetric(eigen_vec, eig) != MB_SUCCESS) {
406 MOFEM_LOG("SELF", Sev::error) << "Failed to compute eigen values";
407 }
408 // CHKERR bound_eig(eig);
409 // rare case when two eigen values are equal
410 nb_uniq_dst = getUniqNb<3>(eig);
411 if (nb_uniq_dst < 3) {
412 CHKERR sortEigenVals<3>(eig, eigen_vec);
413 }
414 t_eigen_vals_dst(i) = eig(i);
415 t_eigen_vecs_dst(i, j) = eigen_vec(i, j);
416 t_u_dst(i, j) = EigenMatrix::getMat(t_eigen_vals_dst, t_eigen_vecs_dst,
419 };
420
421 auto calculate_log_stretch = [&]() {
423 int nb_uniq_val = 0;
424 CHKERR calculate_stretch_from_log(t_log_u, t_u, t_eigen_vals, t_eigen_vecs,
425 nb_uniq_val);
426 t_nb_uniq = nb_uniq_val;
427 auto get_t_diff_u = [&]() {
428 return EigenMatrix::getDiffMat(t_eigen_vals, t_eigen_vecs,
430 t_nb_uniq);
431 };
432 t_diff_u(i, j, k, l) = get_t_diff_u()(i, j, k, l);
434 t_Ldiff_u(i, j, L) = t_diff_u(i, j, m, n) * t_L(m, n, L);
436 };
437
438 auto calculate_total_stretch = [&](auto &t_h1) {
440 if (EshelbianCore::gradApproximator == NO_H1_CONFIGURATION) {
441
442 t_log_u2_h1(i, j) = 0;
443 t_log_stretch_total(i, j) = t_log_u(i, j);
444
445 } else {
446
448 FTensor::Tensor1<double, 3> t_coordinate_stretch;
450
452 t_C_h1(i, j) = t_h1(k, i) * t_h1(k, j);
453 t_eigen_vec(i, j) = t_C_h1(i, j);
454 if (computeEigenValuesSymmetric(t_eigen_vec, t_eig_C) != MB_SUCCESS) {
455 SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
456 "Failed to compute eigenvalues of F_H1^T F_H1");
457 }
458 // rare case when two eigen values are equal
459 t_nb_uniq_C = getUniqNb<3>(t_eig_C);
460 if (t_nb_uniq_C < 3) {
461 CHKERR sortEigenVals<3>(t_eig_C, t_eigen_vec);
462 }
463 for (int aa = 0; aa != 3; ++aa) {
464 if (!std::isfinite(t_eig_C(aa)) || t_eig_C(aa) <= 0.) {
465 SETERRQ(PETSC_COMM_SELF, MOFEM_INVALID_DATA,
466 "F_H1^T F_H1 must be positive definite; eigenvalue %d is "
467 "%g",
468 aa, t_eig_C(aa));
469 }
470 const double principal_stretch = std::sqrt(t_eig_C(aa));
471 const double coordinate_stretch =
472 EshelbianCore::inv_f(principal_stretch);
473 if (!std::isfinite(coordinate_stretch)) {
474 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_FP,
475 "Non-finite H1 coordinate stretch for principal stretch %g",
476 principal_stretch);
477 }
478 t_coordinate_stretch(aa) = coordinate_stretch;
479 }
480 t_eigen_vals_C(i) = t_eig_C(i);
481 t_eigen_vecs_C(i, j) = t_eigen_vec(i, j);
482
483 t_log_u2_h1(i, j) =
484 EigenMatrix::getMat(t_coordinate_stretch, t_eigen_vec,
485 [](const double v) { return v; })(i, j);
486 // The hand-coded Hencky formulation uses additive stretch coordinates.
487 // For logarithmic coordinates this is log(U_H1) + log(U_increment).
488 t_log_stretch_total(i, j) = t_log_u2_h1(i, j) + t_log_u(i, j);
489 }
491 };
492
493 auto no_h1_loop = [&]() {
495
497 case LARGE_ROT:
498 break;
499 case SMALL_ROT:
500 break;
501 default:
502 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
503 "no_h1_loop is only implemented for LARGE_ROT");
504 };
505
506 for (int gg = 0; gg != nb_integration_pts; ++gg) {
507
509
511 t_h1(i, j) = t_kd(i, j);
512
513 // calculate streach
514 CHKERR calculate_log_stretch();
516 if ((dataAtPts->physicsPtr->getFeatures() &
517 PhysicalEquations::noStretchMask)
518 .any()) {
519 t_u0(i, j) = t_u(i, j);
520 } else {
521 FTensor::Tensor1<double, 3> t_eigen_vals_0;
522 FTensor::Tensor2<double, 3, 3> t_eigen_vecs_0;
523 int nb_uniq_0 = 0;
524 CHKERR calculate_stretch_from_log(t_log_u0, t_u0, t_eigen_vals_0,
525 t_eigen_vecs_0, nb_uniq_0);
526 }
527 // calculate total stretch
528 CHKERR calculate_total_stretch(t_h1);
529
530 t_u_h1(i, j) = t_u(i, j);
531 t_diff_u_h1(i, j, k, l) = t_diff_u(i, j, k, l);
533 t_Ldiff_u(i, j, L) = t_diff_u(i, j, m, n) * t_L(m, n, L);
534
537
538 auto large_rot = [&]() {
539 t_R(i, j) = LieGroups::SO3::exp(t_omega, t_omega.l2())(i, j);
540 t_diff_R(i, j, k) =
541 LieGroups::SO3::diffExp(t_omega, t_omega.l2())(i, j, k);
542 t_diff_diff_R(i, j, k, l) =
543 LieGroups::SO3::diffDiffExp(t_omega, t_omega.l2())(i, j, k, l);
544
546 t_diff_R0(i, j, k) =
547 LieGroups::SO3::diffExp(t_omega0, t_omega0.l2())(i, j, k);
548
549 t_h(i, k) = t_R(i, l) * t_u(l, k);
550
552 t_rotated_P(l, k) = t_R(i, l) * t_approx_P(i, k);
553 t_approx_P_adjoint_dstretch(l, k) =
554 t_diff_sym(l, k, i, j) * t_rotated_P(i, j);
555 t_approx_P_adjoint_log_du(L) =
556 t_approx_P_adjoint_dstretch(l, k) * t_Ldiff_u(l, k, L);
557
558 t_levi_kirchhoff(m) =
559 t_diff_R(i, l, m) * (t_u(l, k) * t_approx_P(i, k));
560 t_levi_kirchhoff0(m) =
561 t_diff_R0(i, l, m) * (t_u0(l, k) * t_approx_P0(i, k));
562
564 t_h_domega(i, k, m) = t_diff_R(i, l, m) * t_u(l, k);
565 t_h_dlog_u(i, k, L) = t_R(i, l) * t_Ldiff_u(l, k, L);
566
567 t_approx_P_adjoint_log_du_dP(i, k, L) =
568 t_R(i, l) * t_Ldiff_u(l, k, L);
569
571 t_A(k, l, m) = t_diff_R(i, l, m) * t_approx_P(i, k);
572 t_approx_P_adjoint_log_du_domega(m, L) =
573 t_A(k, l, m) * t_Ldiff_u(k, l, L);
574
575 t_levi_kirchhoff_dstreach(m, L) =
576 t_diff_R(i, l, m) * (t_Ldiff_u(l, k, L) * t_approx_P(i, k));
577 t_levi_kirchhoff_dP(m, i, k) = t_diff_R(i, l, m) * t_u(l, k);
578 t_levi_kirchhoff_domega(m, n) =
579 t_diff_diff_R(i, l, m, n) * (t_u(l, k) * t_approx_P(i, k));
580
581 if (dataAtPts->physicsPtr->getFeatures().test(
582 PhysicalEquations::NO_STRETCH_NONLINEAR)) {
583 auto t_d_u_d_b = GetFTensor4DdgFromMatImpl<
584 SPACE_DIM, SPACE_DIM, -1, DL, MatrixDouble>::get(
585 dataAtPts->matInvD, gg, 0);
586 auto [t_d_b_d_omega, t_d_u_d_omega, t_d_h_d_omega] =
587 getDiffSpatialGradientDR(t_d_u_d_b, t_R, t_diff_R,
588 t_approx_P);
589
590 t_h_domega(i, k, m) += t_d_h_d_omega(i, k, m);
592 t_d_u_contract_p;
593 t_d_u_contract_p(i, l, n) =
594 t_d_u_d_omega(l, k, n) * t_approx_P(i, k);
595 t_levi_kirchhoff_domega(m, n) +=
596 t_diff_R(i, l, m) * t_d_u_contract_p(i, l, n);
597
598 if constexpr (EshelbianCore::symmetrySelector > SYMMETRIC) {
600 SPACE_DIM>
601 t_d_b_d_p;
602 t_d_b_d_p(i, j, k, l) =
603 t_diff_sym(i, j, m, l) * t_R(k, m);
605 SPACE_DIM>
606 t_d_u_d_p;
607 t_d_u_d_p(i, j, k, l) =
608 t_d_u_d_b(i, j, m, n) * t_d_b_d_p(m, n, k, l);
609 t_levi_kirchhoff_dP(m, k, l) +=
610 t_d_u_d_p(i, j, k, l) * t_d_b_d_omega(i, j, m);
611 }
612 }
613 }
614 };
615
616 auto moderate_rot = [&](auto &t_omega0) {
617 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
618 "moderate_rot is not implemented yet");
619 };
620
621 auto small_rot = [&]() {
622 t_u_h1(i, j) = t_u(i, j);
623 t_diff_u_h1(i, j, k, l) = t_diff_u(i, j, k, l);
625 t_Ldiff_u(i, j, L) = t_diff_u(i, j, m, n) * t_L(m, n, L);
626
627 t_R(i, j) = t_kd(i, j) + levi_civita(i, j, k) * t_omega(k);
628 t_h(i, j) = levi_civita(i, j, k) * t_omega(k) + t_u(i, j);
629
630 t_h_domega(i, j, k) = levi_civita(i, j, k);
631 t_h_dlog_u(i, j, L) = t_Ldiff_u(i, j, L);
632
633 // Adjoint stress
635 t_rotated_P(i, j) = t_R(k, i) * t_approx_P(k, j);
636 t_approx_P_adjoint_dstretch(i, j) =
637 t_diff_sym(i, j, k, l) * t_rotated_P(k, l);
638 t_approx_P_adjoint_log_du(L) =
639 t_approx_P_adjoint_dstretch(i, j) * t_Ldiff_u(i, j, L);
640 t_approx_P_adjoint_log_du_dP(i, j, L) =
641 t_R(i, k) * t_Ldiff_u(k, j, L);
642 t_approx_P_adjoint_log_du_domega(m, L) =
643 levi_civita(k, i, m) * t_approx_P(k, j) *
644 t_Ldiff_u(i, j, L);
645
646 // Kirchhoff stress
647 t_levi_kirchhoff(k) = levi_civita(i, j, k) * t_approx_P(i, j);
648 t_levi_kirchhoff0(k) = levi_civita(i, j, k) * t_approx_P0(i, j);
649 t_levi_kirchhoff_dstreach(m, L) = 0;
650 t_levi_kirchhoff_dP(k, i, j) = levi_civita(i, j, k);
651 t_levi_kirchhoff_domega(m, n) = 0;
652 };
653
654 // rotation
656 case LARGE_ROT:
657 large_rot();
658 break;
659 case MODERATE_ROT:
660 moderate_rot(t_omega0);
661 break;
662 case SMALL_ROT:
663 small_rot();
664 break;
665 default:
666 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
667 "rotationSelector not handled");
668 }
669
670 next();
671 }
672
674 };
675
676 auto large_loop = [&]() {
678
680 case LARGE_ROT:
681 break;
682 case SMALL_ROT:
683 break;
684 default:
685 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
686 "rotSelector should be large or small");
687 };
688
689 for (int gg = 0; gg != nb_integration_pts; ++gg) {
690
692
695 case LARGE_ROT:
696 t_h1(i, j) = t_grad_h1(i, j) + t_kd(i, j);
697 break;
698 default:
699 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
700 "Selected grad approximator not handled");
701 };
702
703 // calculate streach
704 CHKERR calculate_log_stretch();
706 if ((dataAtPts->physicsPtr->getFeatures() &
707 PhysicalEquations::noStretchMask)
708 .any()) {
709 t_u0(i, j) = t_u(i, j);
710 } else {
711 FTensor::Tensor1<double, 3> t_eigen_vals_0;
712 FTensor::Tensor2<double, 3, 3> t_eigen_vecs_0;
713 int nb_uniq_0 = 0;
714 CHKERR calculate_stretch_from_log(t_log_u0, t_u0, t_eigen_vals_0,
715 t_eigen_vecs_0, nb_uniq_0);
716 }
717 // calculate total stretch
718 CHKERR calculate_total_stretch(t_h1);
719
720 t_u_h1(l, k) = t_u(l, o) * t_h1(o, k);
722 t_u_h10(l, k) = t_u0(l, o) * t_h1(o, k);
723 t_diff_u_h1(i, j, k, l) = t_diff_u(i, o, k, l) * t_h1(o, j);
725 t_Ldiff_u_h1(l, k, L) = t_diff_u_h1(l, k, i, j) * t_L(i, j, L);
726
730
731 // rotation
733 case SMALL_ROT:
734 t_R(i, k) = t_kd(i, k) + levi_civita(i, k, l) * t_omega(l);
735 t_diff_R(i, j, k) = levi_civita(i, j, k);
736 t_diff_R0(i, j, k) = levi_civita(i, j, k);
737 t_diff_diff_R(i, j, l, m) = 0;
738 break;
739 case LARGE_ROT:
740 t_R(i, j) = LieGroups::SO3::exp(t_omega, t_omega.l2())(i, j);
741 t_diff_R(i, j, k) =
742 LieGroups::SO3::diffExp(t_omega, t_omega.l2())(i, j, k);
743 t_diff_R0(i, j, k) =
744 LieGroups::SO3::diffExp(t_omega0, t_omega0.l2())(i, j, k);
745 t_diff_diff_R(i, j, k, l) =
746 LieGroups::SO3::diffDiffExp(t_omega, t_omega.l2())(i, j, k, l);
747 break;
748
749 default:
750 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
751 "rotationSelector not handled");
752 }
753
754 // calculate gradient
755 t_h(i, k) = t_R(i, l) * t_u_h1(l, k);
756
757 // Adjoint stress
759 t_rotated_P(l, o) =
760 (t_R(i, l) * t_approx_P(i, k)) * t_h1(o, k);
761 t_approx_P_adjoint_dstretch(l, o) =
762 t_diff_sym(l, o, i, j) * t_rotated_P(i, j);
763 t_approx_P_adjoint_log_du(L) =
764 t_R(i, l) * t_approx_P(i, k) * t_Ldiff_u_h1(l, k, L);
765
766 // Kirchhoff stress
767 t_levi_kirchhoff(m) = t_diff_R(i, l, m) * t_u_h1(l, k) * t_approx_P(i, k);
768 t_levi_kirchhoff0(m) =
769 t_diff_R0(i, l, m) * t_u_h10(l, k) * t_approx_P0(i, k);
770
772
773 t_h_domega(i, k, m) = t_diff_R(i, l, m) * t_u_h1(l, k);
774 t_h_dlog_u(i, k, L) = t_R(i, l) * t_Ldiff_u_h1(l, k, L);
775
776 t_approx_P_adjoint_log_du_dP(i, k, L) =
777 t_R(i, l) * t_Ldiff_u_h1(l, k, L);
778
780 t_A(m, L, i, k) = t_diff_R(i, l, m) * t_Ldiff_u_h1(l, k, L);
781 t_approx_P_adjoint_log_du_domega(m, L) =
782 t_A(m, L, i, k) * t_approx_P(i, k);
783
784 t_levi_kirchhoff_dstreach(m, L) =
785 t_diff_R(i, l, m) * (t_Ldiff_u_h1(l, k, L) * t_approx_P(i, k));
786
787 t_levi_kirchhoff_dP(m, i, k) = t_diff_R(i, l, m) * t_u_h1(l, k);
788 t_levi_kirchhoff_domega(m, n) =
789 t_diff_diff_R(i, l, m, n) * (t_u_h1(l, k) * t_approx_P(i, k));
790 }
791
792 next();
793 }
794
796 };
797
798 auto moderate_loop = [&]() {
800
802 case LARGE_ROT:
803 break;
804 case SMALL_ROT:
805 break;
806 default:
807 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
808 "rotSelector should be large or small");
809 };
810
811 for (int gg = 0; gg != nb_integration_pts; ++gg) {
812
814
817 case MODERATE_ROT:
818 t_h1(i, j) = t_grad_h1(i, j) + t_kd(i, j);
819 break;
820 default:
821 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
822 "Selected grad approximator not handled");
823 };
824
825 // calculate streach
826 CHKERR calculate_log_stretch();
827 // calculate total stretch
828 CHKERR calculate_total_stretch(t_h1);
829
830 auto t_diff = FTensor::DiffTensor<double>();
831
832 t_u_h1(l, k) = (t_kd(l, o) + t_log_u(l, o)) * t_h1(o, k);
834 t_u_h10(l, k) = (t_kd(l, o) + t_log_u0(l, o)) * t_h1(o, k);
835 t_diff_u_h1(i, j, k, l) = t_diff(i, o, k, l) * t_h1(o, j);
837 t_Ldiff_u_h1(l, k, L) = t_diff_u_h1(l, k, i, j) * t_L(i, j, L);
838
842
843 // rotation
845 case SMALL_ROT:
846 t_R(i, k) = t_kd(i, k) + levi_civita(i, k, l) * t_omega(l);
847 t_diff_R(i, j, k) = levi_civita(i, j, k);
848 t_diff_R0(i, j, k) = levi_civita(i, j, k);
849 t_diff_diff_R(i, j, l, m) = 0;
850 break;
851 case LARGE_ROT:
852 t_R(i, j) = LieGroups::SO3::exp(t_omega, t_omega.l2())(i, j);
853 t_diff_R(i, j, k) =
854 LieGroups::SO3::diffExp(t_omega, t_omega.l2())(i, j, k);
855 t_diff_R0(i, j, k) =
856 LieGroups::SO3::diffExp(t_omega0, t_omega0.l2())(i, j, k);
857 t_diff_diff_R(i, j, k, l) =
858 LieGroups::SO3::diffDiffExp(t_omega, t_omega.l2())(i, j, k, l);
859 break;
860
861 default:
862 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
863 "rotationSelector not handled");
864 }
865
866 // calculate gradient
867 t_h(i, k) = t_R(i, l) * t_u_h1(l, k);
868
869 // Adjoint stress
871 t_rotated_P(l, o) =
872 (t_R(i, l) * t_approx_P(i, k)) * t_h1(o, k);
873 t_approx_P_adjoint_dstretch(l, o) =
874 t_diff_sym(l, o, i, j) * t_rotated_P(i, j);
875 t_approx_P_adjoint_log_du(L) =
876 t_R(i, l) * t_approx_P(i, k) * t_Ldiff_u_h1(l, k, L);
877
878 // Kirchhoff stress
879 t_levi_kirchhoff(m) = t_diff_R(i, l, m) * t_u_h1(l, k) * t_approx_P(i, k);
880 t_levi_kirchhoff0(m) =
881 t_diff_R0(i, l, m) * t_u_h10(l, k) * t_approx_P0(i, k);
882
884
885 t_h_domega(i, k, m) = t_diff_R(i, l, m) * t_u_h1(l, k);
886 t_h_dlog_u(i, k, L) = t_R(i, l) * t_Ldiff_u_h1(l, k, L);
887
888 t_approx_P_adjoint_log_du_dP(i, k, L) =
889 t_R(i, l) * t_Ldiff_u_h1(l, k, L);
890
892 t_A(m, L, i, k) = t_diff_R(i, l, m) * t_Ldiff_u_h1(l, k, L);
893 t_approx_P_adjoint_log_du_domega(m, L) =
894 t_A(m, L, i, k) * t_approx_P(i, k);
895
896 t_levi_kirchhoff_dstreach(m, L) =
897 t_diff_R(i, l, m) * (t_Ldiff_u_h1(l, k, L) * t_approx_P(i, k));
898
899 t_levi_kirchhoff_dP(m, i, k) = t_diff_R(i, l, m) * t_u_h1(l, k);
900 t_levi_kirchhoff_domega(m, n) =
901 t_diff_diff_R(i, l, m, n) * (t_u_h1(l, k) * t_approx_P(i, k));
902 }
903
904 next();
905 }
906
908 };
909
910 auto small_loop = [&]() {
913 case SMALL_ROT:
914 break;
915 default:
916 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
917 "rotSelector should be small");
918 };
919
920 for (int gg = 0; gg != nb_integration_pts; ++gg) {
921
924 case SMALL_ROT:
925 t_h1(i, j) = t_kd(i, j);
926 break;
927 default:
928 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
929 "gradApproximator not handled");
930 };
931
933 if (EshelbianCore::stretchSelector > LINEAR) {
934 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
935 "stretchSelector should be linear for small loop");
936 } else {
937 t_u(i, j) = t_symm_kd(i, j) + t_log_u(i, j);
938 t_u_h1(i, j) = t_u(i, j);
939 t_diff_u_h1(i, j, k, l) =
940 (t_kd(i, k) * t_kd(j, l) + t_kd(i, l) * t_kd(j, k));
941 t_diff_u_h1(i, j, k, l) /= 2.;
942 t_Ldiff_u(i, j, L) = t_L(i, j, L);
943 }
944 t_log_u2_h1(i, j) = 0;
945 t_log_stretch_total(i, j) = t_log_u(i, j);
946
947 t_R(i, j) = t_kd(i, j) + levi_civita(i, j, k) * t_omega(k);
948 t_h(i, j) = levi_civita(i, j, k) * t_omega(k) + t_u(i, j);
949
950 t_h_domega(i, j, k) = levi_civita(i, j, k);
951 t_h_dlog_u(i, j, L) = t_Ldiff_u(i, j, L);
952
953 // Adjoint stress
954 t_approx_P_adjoint_dstretch(i, j) =
955 t_diff_sym(i, j, k, l) * t_approx_P(k, l);
956 t_approx_P_adjoint_log_du(L) =
957 t_approx_P_adjoint_dstretch(i, j) * t_Ldiff_u(i, j, L);
958 t_approx_P_adjoint_log_du_dP(i, j, L) = t_Ldiff_u(i, j, L);
959 t_approx_P_adjoint_log_du_domega(m, L) = 0;
960
961 // Kirchhoff stress
962 t_levi_kirchhoff(k) = levi_civita(i, j, k) * t_approx_P(i, j);
963 t_levi_kirchhoff0(k) = levi_civita(i, j, k) * t_approx_P0(i, j);
964 t_levi_kirchhoff_dstreach(m, L) = 0;
965 t_levi_kirchhoff_dP(k, i, j) = levi_civita(i, j, k);
966 t_levi_kirchhoff_domega(m, n) = 0;
967
968 next();
969 }
970
972 };
973
975 case NO_H1_CONFIGURATION:
976 CHKERR no_h1_loop();
977 break;
978 case LARGE_ROT:
979 CHKERR large_loop();
980 break;
981 case MODERATE_ROT:
982 CHKERR moderate_loop();
983 break;
984 case SMALL_ROT:
985 CHKERR small_loop();
986 break;
987 default:
988 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
989 "gradApproximator not handled");
990 break;
991 };
992
994}
995
997 EntData &data) {
1000
1001 auto n_in_the_loop = getNinTheLoop();
1002 auto loop_size = getLoopSize();
1003 auto sense = getSkeletonSense();
1004 auto nb_gauss_pts = getGaussPts().size2();
1005 auto t_normal = getFTensor1NormalsAtGaussPts();
1006
1007 auto t_sigma = dataAtPts->getFTensorApproxP(getGaussPts().size2());
1008 auto get_tracion =
1010 dataAtPts->tractionAtPts, nb_gauss_pts);
1011 if (!n_in_the_loop) {
1012 dataAtPts->tractionAtPts.clear();
1013 }
1014
1015 auto t_traction = get_tracion();
1016 for (int gg = 0; gg != nb_gauss_pts; gg++) {
1017 t_traction(i) +=
1018 t_sigma(i, j) * sense * (t_normal(j) / t_normal.l2()) / loop_size;
1019 ++t_traction;
1020 ++t_sigma;
1021 ++t_normal;
1022 }
1023
1025}
1026
1028 EntData &data) {
1030 if (blockEntities.find(getFEEntityHandle()) == blockEntities.end()) {
1032 };
1036 int nb_integration_pts = getGaussPts().size2();
1037 auto t_w = getFTensor0IntegrationWeight();
1038 auto t_traction = dataAtPts->getFTensorTraction(nb_integration_pts);
1039 auto t_coords = getFTensor1CoordsAtGaussPts();
1040 auto t_spatial_disp = dataAtPts->getFTensorSmallWL2(nb_integration_pts);
1041
1042 FTensor::Tensor1<double, 3> t_coords_spatial{0., 0., 0.};
1043 FTensor::Tensor1<double, 3> loc_reaction_forces{0., 0., 0.};
1044 FTensor::Tensor1<double, 3> loc_moment_forces{0., 0., 0.};
1045
1046 for (auto gg = 0; gg != nb_integration_pts; ++gg) {
1047 double a = t_w * getMeasure();
1048 loc_reaction_forces(i) += a*t_traction(i);
1049 t_coords_spatial(i) = t_coords(i) + t_spatial_disp(i);
1050 loc_moment_forces(i) +=
1051 (a * (FTensor::levi_civita<double>(i, j, k) * t_coords_spatial(j))) *
1052 t_traction(k);
1053 ++t_coords;
1054 ++t_spatial_disp;
1055 ++t_w;
1056 ++t_traction;
1057 }
1058
1059 reactionVec[0] += loc_reaction_forces(0);
1060 reactionVec[1] += loc_reaction_forces(1);
1061 reactionVec[2] += loc_reaction_forces(2);
1062 reactionVec[3] += loc_moment_forces(0);
1063 reactionVec[4] += loc_moment_forces(1);
1064 reactionVec[5] += loc_moment_forces(2);
1065
1067}
1068
1071 int nb_dofs = data.getIndices().size();
1072 int nb_integration_pts = data.getN().size1();
1073 auto v = getVolume();
1074 auto t_w = getFTensor0IntegrationWeight();
1075 auto t_div_P = dataAtPts->getFTensorDivP(nb_integration_pts);
1076 auto t_s_dot_w = dataAtPts->getFTensorSmallWL2Dot(nb_integration_pts);
1077 auto w_l2_dot_dot_at_pts = dataAtPts->getSmallWL2DotDotAtPts();
1078 const bool reset_w_l2_dot_dot =
1079 w_l2_dot_dot_at_pts->size1() != nb_integration_pts ||
1080 w_l2_dot_dot_at_pts->size2() != 3;
1081 MatrixSizeHelper<GetFTensor1FromMatType<3, -1, DL>, DL>::size(
1082 *w_l2_dot_dot_at_pts, nb_integration_pts);
1083 if (reset_w_l2_dot_dot) {
1084 w_l2_dot_dot_at_pts->clear();
1085 }
1086 auto t_s_dot_dot_w = dataAtPts->getFTensorSmallWL2DotDot(nb_integration_pts);
1087
1088 auto piola_scale = dataAtPts->piolaScale;
1089 auto alpha_w = alphaW / piola_scale;
1090 auto alpha_rho = alphaRho / piola_scale;
1091
1092 int nb_base_functions = data.getN().size2();
1093 auto t_row_base_fun = data.getFTensor0N();
1094
1095 FTensor::Index<'i', 3> i;
1096 auto get_ftensor1 = [](auto &v) {
1098 &v[2]);
1099 };
1100
1101 auto next = [&]() {
1102 ++t_w;
1103 ++t_div_P;
1104 ++t_s_dot_w;
1105 ++t_s_dot_dot_w;
1106 };
1107
1108 for (int gg = 0; gg != nb_integration_pts; ++gg) {
1109 double a = v * t_w;
1110 auto t_nf = get_ftensor1(nF);
1111 int bb = 0;
1112 for (; bb != nb_dofs / 3; ++bb) {
1113 t_nf(i) -= a * t_row_base_fun * t_div_P(i);
1114 t_nf(i) += a * t_row_base_fun * alpha_w * t_s_dot_w(i);
1115 t_nf(i) += a * t_row_base_fun * alpha_rho * t_s_dot_dot_w(i);
1116 ++t_nf;
1117 ++t_row_base_fun;
1118 }
1119 for (; bb != nb_base_functions; ++bb)
1120 ++t_row_base_fun;
1121 next();
1122 }
1123
1125}
1126
1129 int nb_dofs = data.getIndices().size();
1130 int nb_integration_pts = getGaussPts().size2();
1131 auto v = getVolume();
1132 auto t_w = getFTensor0IntegrationWeight();
1133 auto t_levi_kirchhoff =
1134 dataAtPts->getFTensorLeviKirchhoff(nb_integration_pts);
1135 auto t_omega = dataAtPts->getFTensorRotAxis(nb_integration_pts);
1136 auto t_omega_grad = dataAtPts->getFTensorRotAxisGrad(nb_integration_pts);
1137 auto t_omega_dot = dataAtPts->getFTensorRotAxisDot(nb_integration_pts);
1138 auto t_omega_grad_dot =
1139 dataAtPts->getFTensorRotAxisGradDot(nb_integration_pts);
1140 auto t_plasticF = dataAtPts->getFTensorPlasticF(nb_integration_pts);
1141 auto t_invPlasticF = dataAtPts->getFTensorInvPlasticF(nb_integration_pts);
1142 int nb_base_functions = data.getN().size2();
1143 auto t_row_base_fun = data.getFTensor0N();
1144 auto t_row_grad_fun = data.getFTensor1DiffN<3>();
1145 FTensor::Index<'i', 3> i;
1146 FTensor::Index<'j', 3> j;
1147 FTensor::Index<'k', 3> k;
1148 auto get_ftensor1 = [](auto &v) {
1150 &v[2]);
1151 };
1152 // auto time_step = getTStimeStep();
1153
1154 for (int gg = 0; gg != nb_integration_pts; ++gg) {
1155
1156 const double det_plasticF = determinantTensor3by3(t_plasticF);
1157
1158 FTensor::Tensor2<double, 3, 3> t_omega_grad_intermediate;
1159 t_omega_grad_intermediate(k, j) =
1160 t_omega_grad(k, i) * t_invPlasticF(i, j);
1161 FTensor::Tensor2<double, 3, 3> t_omega_grad_dot_intermediate;
1162 t_omega_grad_dot_intermediate(k, j) =
1163 t_omega_grad_dot(k, i) * t_invPlasticF(i, j);
1164
1165 double a = v * t_w * det_plasticF;
1166 auto t_nf = get_ftensor1(nF);
1167 int bb = 0;
1168 for (; bb != nb_dofs / 3; ++bb) {
1169 t_nf(k) -= (a * t_row_base_fun) * t_levi_kirchhoff(k);
1170 t_nf(k) += (a * alphaR) * (t_row_base_fun * t_omega(k));
1171 FTensor::Tensor1<double, 3> t_row_grad_intermediate;
1172 t_row_grad_intermediate(j) =
1173 t_row_grad_fun(i) * t_invPlasticF(i, j);
1174 t_nf(k) += (a * alphaOmega) *
1175 (t_row_grad_intermediate(j) *
1176 t_omega_grad_intermediate(k, j));
1177 t_nf(k) += (a * alphaViscousR /*/ time_step*/) *
1178 (t_row_base_fun * t_omega_dot(k));
1179 t_nf(k) += (a * alphaViscousOmega /*/ time_step*/) *
1180 (t_row_grad_intermediate(j) *
1181 t_omega_grad_dot_intermediate(k, j));
1182 ++t_nf;
1183 ++t_row_base_fun;
1184 ++t_row_grad_fun;
1185 }
1186 for (; bb != nb_base_functions; ++bb) {
1187 ++t_row_base_fun;
1188 ++t_row_grad_fun;
1189 }
1190 ++t_w;
1191 ++t_levi_kirchhoff;
1192 ++t_omega;
1193 ++t_omega_grad;
1194 ++t_omega_dot;
1195 ++t_omega_grad_dot;
1196 ++t_plasticF;
1197 ++t_invPlasticF;
1198 }
1200}
1201
1204 int nb_dofs = data.getIndices().size();
1205 int nb_integration_pts = data.getN().size1();
1206 auto v = getVolume();
1207 auto t_w = getFTensor0IntegrationWeight();
1208
1209 int nb_base_functions = data.getN().size2() / 3;
1210 auto t_row_base_fun = data.getFTensor1N<3>();
1211 FTENSOR_INDEX(3, i);
1212 FTENSOR_INDEX(3, j);
1213 FTENSOR_INDEX(3, k);
1214 FTENSOR_INDEX(3, m);
1215 FTENSOR_INDEX(3, l);
1216
1217 auto get_ftensor1 = [](auto &v) {
1219 &v[2]);
1220 };
1221
1222 auto t_h = dataAtPts->getFTensorSmallH(nb_integration_pts);
1223 auto t_plasticF = dataAtPts->getFTensorPlasticF(nb_integration_pts);
1224 auto t_invPlasticF = dataAtPts->getFTensorInvPlasticF(nb_integration_pts);
1225
1226 for (int gg = 0; gg != nb_integration_pts; ++gg) {
1227 const double det_plasticF = determinantTensor3by3(t_plasticF);
1228 double a = v * t_w * det_plasticF;
1229 auto t_nf = get_ftensor1(nF);
1230
1232 t_residuum(i, j) = t_h(i, j) - t_invPlasticF(i, j);
1233
1234 int bb = 0;
1235 for (; bb != nb_dofs / 3; ++bb) {
1236 FTensor::Tensor1<double, 3> t_row_base_piola;
1237 t_row_base_piola(j) =
1238 t_plasticF(j, k) * t_row_base_fun(k) / det_plasticF;
1239 t_nf(i) -= a * t_row_base_piola(j) * t_residuum(i, j);
1240 ++t_nf;
1241 ++t_row_base_fun;
1242 }
1243
1244 for (; bb != nb_base_functions; ++bb)
1245 ++t_row_base_fun;
1246
1247 ++t_w;
1248 ++t_h;
1249 ++t_plasticF;
1250 ++t_invPlasticF;
1251 }
1252
1254}
1255
1258 int nb_dofs = data.getIndices().size();
1259 int nb_integration_pts = data.getN().size1();
1260 auto v = getVolume();
1261 auto t_w = getFTensor0IntegrationWeight();
1262
1263 int nb_base_functions = data.getN().size2() / 9;
1264 auto t_row_base_fun = data.getFTensor2N<3, 3>();
1265 FTENSOR_INDEX(3, i);
1266 FTENSOR_INDEX(3, j);
1267 FTENSOR_INDEX(3, k);
1268 FTENSOR_INDEX(3, m);
1269 FTENSOR_INDEX(3, l);
1270
1271 auto get_ftensor0 = [](auto &v) {
1273 };
1274
1275 auto t_h = dataAtPts->getFTensorSmallH(nb_integration_pts);
1276 auto t_plasticF = dataAtPts->getFTensorPlasticF(nb_integration_pts);
1277 auto t_invPlasticF = dataAtPts->getFTensorInvPlasticF(nb_integration_pts);
1278
1279 for (int gg = 0; gg != nb_integration_pts; ++gg) {
1280 const double det_plasticF = determinantTensor3by3(t_plasticF);
1281 double a = v * t_w * det_plasticF;
1282 auto t_nf = get_ftensor0(nF);
1283
1285 t_residuum(i, j) = t_h(i, j) - t_invPlasticF(i, j);
1286
1287 int bb = 0;
1288 for (; bb != nb_dofs; ++bb) {
1289 FTensor::Tensor2<double, 3, 3> t_row_base_piola;
1290 t_row_base_piola(i, j) =
1291 t_row_base_fun(i, k) * t_plasticF(j, k) / det_plasticF;
1292 t_nf -= a * t_row_base_piola(i, j) * t_residuum(i, j);
1293 ++t_nf;
1294 ++t_row_base_fun;
1295 }
1296 for (; bb != nb_base_functions; ++bb) {
1297 ++t_row_base_fun;
1298 }
1299 ++t_w;
1300 ++t_h;
1301 ++t_plasticF;
1302 ++t_invPlasticF;
1303 }
1304
1306}
1307
1310 int nb_dofs = data.getIndices().size();
1311 int nb_integration_pts = data.getN().size1();
1312 auto v = getVolume();
1313 auto t_w = getFTensor0IntegrationWeight();
1314 auto t_w_l2 = dataAtPts->getFTensorSmallWL2(nb_integration_pts);
1315 auto t_plasticF = dataAtPts->getFTensorPlasticF(nb_integration_pts);
1316 auto t_invPlasticF = dataAtPts->getFTensorInvPlasticF(nb_integration_pts);
1317 int nb_base_functions = data.getN().size2() / 3;
1318 auto t_row_diff_base_fun = data.getFTensor2DiffN<3, 3>();
1319 FTENSOR_INDEX(3, i);
1320 FTENSOR_INDEX(3, j);
1321 FTENSOR_INDEX(3, k);
1322 auto get_ftensor1 = [](auto &v) {
1324 &v[2]);
1325 };
1326
1327 for (int gg = 0; gg != nb_integration_pts; ++gg) {
1328 const double det_plasticF = determinantTensor3by3(t_plasticF);
1329 double a = v * t_w * det_plasticF;
1330 auto t_nf = get_ftensor1(nF);
1331 int bb = 0;
1332 for (; bb != nb_dofs / 3; ++bb) {
1333 const double div_row_base =
1334 (t_plasticF(i, j) * t_row_diff_base_fun(j, k) *
1335 t_invPlasticF(k, i)) /
1336 det_plasticF;
1337 t_nf(i) -= a * div_row_base * t_w_l2(i);
1338 ++t_nf;
1339 ++t_row_diff_base_fun;
1340 }
1341 for (; bb != nb_base_functions; ++bb) {
1342 ++t_row_diff_base_fun;
1343 }
1344 ++t_w;
1345 ++t_w_l2;
1346 ++t_plasticF;
1347 ++t_invPlasticF;
1348 }
1349
1351}
1352
1353template <>
1355 EntData &data) {
1357
1358 int nb_integration_pts = getGaussPts().size2();
1359
1360 Tag tag;
1361 CHKERR getPtrFE() -> mField.get_moab().tag_get_handle(tagName.c_str(), tag);
1362 int tag_length;
1363 CHKERR getPtrFE() -> mField.get_moab().tag_get_length(tag, tag_length);
1364 if (tag_length != 9) {
1365 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1366 "Number of internal stress components should be 9 but is %d",
1367 tag_length);
1368 }
1369
1370 VectorDouble const_stress_vec(9);
1371 auto fe_ent = getNumeredEntFiniteElementPtr()->getEnt();
1372 CHKERR getPtrFE() -> mField.get_moab().tag_get_data(
1373 tag, &fe_ent, 1, &*const_stress_vec.data().begin());
1374 auto t_const_stress = getFTensor1FromArray<9, 9>(const_stress_vec);
1375
1376 auto get_internal_stress =
1377 MatrixSizeHelper<GetFTensor1FromMatType<9, -1, DL>, DL>::size(
1378 dataAtPts->internalStressAtPts, nb_integration_pts);
1379 dataAtPts->internalStressAtPts.clear();
1380 auto t_internal_stress = get_internal_stress();
1381
1382 FTensor::Index<'L', 9> L;
1383 for (int gg = 0; gg != nb_integration_pts; ++gg) {
1384 t_internal_stress(L) = t_const_stress(L);
1385 ++t_internal_stress;
1386 }
1387
1389}
1390
1391template <>
1393 EntData &data) {
1395
1396 int nb_integration_pts = getGaussPts().size2();
1397
1398 Tag tag;
1399 CHKERR getPtrFE() -> mField.get_moab().tag_get_handle(tagName.c_str(), tag);
1400 int tag_length;
1401 CHKERR getPtrFE() -> mField.get_moab().tag_get_length(tag, tag_length);
1402 if (tag_length != 9) {
1403 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1404 "Number of internal stress components should be 9 but is %d",
1405 tag_length);
1406 }
1407
1408 auto fe_ent = getNumeredEntFiniteElementPtr()->getEnt();
1409 const EntityHandle *vert_conn;
1410 int vert_num;
1411 CHKERR getPtrFE() -> mField.get_moab().get_connectivity(fe_ent, vert_conn,
1412 vert_num, true);
1413 VectorDouble vert_data(vert_num * tag_length);
1414 CHKERR getPtrFE() -> mField.get_moab().tag_get_data(tag, vert_conn, vert_num,
1415 &vert_data[0]);
1416
1417 auto get_internal_stress =
1418 MatrixSizeHelper<GetFTensor1FromMatType<9, -1, DL>, DL>::size(
1419 dataAtPts->internalStressAtPts, nb_integration_pts);
1420 dataAtPts->internalStressAtPts.clear();
1421 auto t_internal_stress = get_internal_stress();
1422
1423 auto t_shape_n = data.getFTensor0N();
1424 int nb_shape_fn = data.getN(NOBASE).size2();
1425 FTensor::Index<'L', 9> L;
1426 for (int gg = 0; gg != nb_integration_pts; ++gg) {
1427 auto t_vert_data = getFTensor1FromArray<9, 9>(vert_data);
1428 for (int bb = 0; bb != nb_shape_fn; ++bb) {
1429 t_internal_stress(L) += t_vert_data(L) * t_shape_n;
1430 ++t_vert_data;
1431 ++t_shape_n;
1432 }
1433 ++t_internal_stress;
1434 }
1435
1437}
1438
1439template <>
1443
1444 int nb_dofs = data.getIndices().size();
1445 int nb_integration_pts = data.getN().size1();
1446 auto v = getVolume();
1447 auto t_w = getFTensor0IntegrationWeight();
1448
1449 FTensor::Index<'i', 3> i;
1450 FTensor::Index<'j', 3> j;
1451
1452 auto get_ftensor2 = [](auto &v) {
1454 &v[0], &v[1], &v[2], &v[3], &v[4], &v[5]);
1455 };
1456
1457 auto t_internal_stress =
1458 dataAtPts->getFTensorInternalStress(nb_integration_pts);
1459
1460 const double time = EshelbianCore::physicalTimeFlg
1462 : getFEMethod()->ts_t;
1463
1464 // default scaling is constant
1465 double scale = scalingMethodPtr->getScale(time);
1466
1468 auto t_L = FTensor::SymmLTensor<double, 3>();
1469
1470 int nb_base_functions = data.getN().size2();
1471 auto t_row_base_fun = data.getFTensor0N();
1472 for (int gg = 0; gg != nb_integration_pts; ++gg) {
1473 double a = v * t_w;
1474 auto t_nf = get_ftensor2(nF);
1475
1476 FTensor::Tensor2<double, 3, 3> t_symm_stress;
1477 t_symm_stress(i, j) =
1478 (t_internal_stress(i, j) + t_internal_stress(j, i)) / 2;
1479
1481 t_residual(L) = t_L(i, j, L) * (scale * t_symm_stress(i, j));
1482
1483 int bb = 0;
1484 for (; bb != nb_dofs / 6; ++bb) {
1485 t_nf(L) += a * t_row_base_fun * t_residual(L);
1486 ++t_nf;
1487 ++t_row_base_fun;
1488 }
1489 for (; bb != nb_base_functions; ++bb)
1490 ++t_row_base_fun;
1491
1492 ++t_w;
1493 ++t_internal_stress;
1494 }
1496}
1497
1498template <>
1501
1502 int nb_dofs = data.getIndices().size();
1503 int nb_integration_pts = data.getN().size1();
1504 auto v = getVolume();
1505 auto t_w = getFTensor0IntegrationWeight();
1506
1507 auto get_ftensor2 = [](auto &v) {
1509 &v[0], &v[1], &v[2], &v[3], &v[4], &v[5]);
1510 };
1511
1512 auto t_internal_stress =
1513 dataAtPts->getFTensorInternalStressVec(nb_integration_pts);
1514
1516 FTensor::Index<'M', size_symm> M;
1518 t_L = voigt_to_symm();
1519
1520 const double time = EshelbianCore::physicalTimeFlg
1522 : getFEMethod()->ts_t;
1523
1524 // default is constant
1525 double scale = scalingMethodPtr->getScale(time);
1526
1527 int nb_base_functions = data.getN().size2();
1528 auto t_row_base_fun = data.getFTensor0N();
1529 for (int gg = 0; gg != nb_integration_pts; ++gg) {
1530 double a = v * t_w;
1531 auto t_nf = get_ftensor2(nF);
1532
1534 t_residual(L) = t_L(M, L) * (scale * t_internal_stress(M));
1535
1536 int bb = 0;
1537 for (; bb != nb_dofs / 6; ++bb) {
1538 t_nf(L) += a * t_row_base_fun * t_residual(L);
1539 ++t_nf;
1540 ++t_row_base_fun;
1541 }
1542 for (; bb != nb_base_functions; ++bb)
1543 ++t_row_base_fun;
1544
1545 ++t_w;
1546 ++t_internal_stress;
1547 }
1549}
1550
1551template <AssemblyType A>
1554 // get entity of face
1555 EntityHandle fe_ent = OP::getFEEntityHandle();
1556 // iterate over all boundary data
1557 for (auto &bc : (*bcDispPtr)) {
1558 // check if finite element entity is part of boundary condition
1559 if (bc.faces.find(fe_ent) != bc.faces.end()) {
1560 int nb_dofs = data.getIndices().size();
1561
1562 int nb_integration_pts = OP::getGaussPts().size2();
1563 auto t_normal = OP::getFTensor1NormalsAtGaussPts();
1564 auto t_w = OP::getFTensor0IntegrationWeight();
1565 int nb_base_functions = data.getN().size2() / 3;
1566 auto t_row_base_fun = data.getFTensor1N<3>();
1567
1570
1571 double scale = 1;
1572 if (scalingMethodsMap.find(bc.blockName) != scalingMethodsMap.end()) {
1574 scale *= scalingMethodsMap.at(bc.blockName)
1576 } else {
1577 scale *= scalingMethodsMap.at(bc.blockName)
1578 ->getScale(OP::getFEMethod()->ts_t);
1579 }
1580 } else {
1581 MOFEM_LOG("SELF", Sev::warning)
1582 << "No scaling method found for " << bc.blockName;
1583 }
1584
1585 // get bc data
1586 FTensor::Tensor1<double, 3> t_bc_disp(bc.vals[0], bc.vals[1], bc.vals[2]);
1587 t_bc_disp(i) *= scale;
1588
1589 for (int gg = 0; gg != nb_integration_pts; ++gg) {
1590 auto t_nf = getFTensor1FromPtr<3>(&*OP::locF.begin());
1591 int bb = 0;
1592 for (; bb != nb_dofs / SPACE_DIM; ++bb) {
1593 t_nf(i) +=
1594 t_w * (t_row_base_fun(j) * t_normal(j)) * t_bc_disp(i) * 0.5;
1595 ++t_nf;
1596 ++t_row_base_fun;
1597 }
1598 for (; bb != nb_base_functions; ++bb)
1599 ++t_row_base_fun;
1600
1601 ++t_w;
1602 ++t_normal;
1603 }
1604 }
1605 }
1607}
1608
1610 return OP::iNtegrate(data);
1611}
1612
1615 // get entity of face
1616 EntityHandle fe_ent = OP::getFEEntityHandle();
1617 // iterate over all boundary data
1618 for (auto &bc : (*bcDispPtr)) {
1619 // check if finite element entity is part of boundary condition
1620 if (bc.faces.find(fe_ent) != bc.faces.end()) {
1621 int nb_dofs = data.getIndices().size();
1622
1623 int nb_integration_pts = OP::getGaussPts().size2();
1624 auto t_w = OP::getFTensor0IntegrationWeight();
1625 int nb_base_functions = data.getN().size2();
1626 auto t_row_base_fun = data.getFTensor0N();
1627#ifndef NDEBUG
1628 if (!this->sourceVec) {
1629 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1630 "Source vector for OpTauStabilizationDispRhsBc is not set");
1631 }
1632 if (data.getN().size1() != nb_integration_pts) {
1633 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1634 "Number of integration points in data should be %d but is %d",
1635 nb_integration_pts, (int)data.getN().size1());
1636 }
1637 if (nb_base_functions < nb_dofs / SPACE_DIM) {
1638 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1639 "Number of base functions in data should be %d but is %d",
1640 nb_base_functions, (int)data.getN().size2() / SPACE_DIM);
1641 }
1642
1643#endif
1644
1645 auto t_disp_val =
1646 MatrixSizeHelper<GetFTensor1FromMatType<3, -1, DL>, DL>::get(
1647 *this->sourceVec, nb_integration_pts)();
1648
1651
1652 double scale = 1;
1653 if (scalingMethodsMap.find(bc.blockName) != scalingMethodsMap.end()) {
1655 scale *= scalingMethodsMap.at(bc.blockName)
1657 } else {
1658 scale *= scalingMethodsMap.at(bc.blockName)
1659 ->getScale(OP::getFEMethod()->ts_t);
1660 }
1661 } else {
1662 MOFEM_LOG("SELF", Sev::warning)
1663 << "No scaling method found for " << bc.blockName;
1664 }
1665
1666 // get bc data
1667 FTensor::Tensor1<double, 3> t_bc_disp(bc.vals[0], bc.vals[1], bc.vals[2]);
1668 t_bc_disp(i) *= scale;
1669
1670 auto area = getMeasure();
1671 auto t_coords = OP::getFTensor1CoordsAtGaussPts();
1672 for (int gg = 0; gg != nb_integration_pts; ++gg) {
1673 auto tau_scale =
1674 area * t_w * OP::betaCoeff(t_coords(0), t_coords(1), t_coords(2));
1676 for (int ii = 0; ii != SPACE_DIM; ++ii)
1677 t_bc_residual(ii) =
1678 bc.flags[ii] ? t_disp_val(ii) - t_bc_disp(ii) : 0.;
1679 auto t_nf = getFTensor1FromPtr<3, 3>(OP::locF.data().data());
1680 int bb = 0;
1681 for (; bb != nb_dofs / SPACE_DIM; ++bb) {
1682 t_nf(i) +=
1683 (tau_scale * t_row_base_fun) * t_bc_residual(i);
1684 ++t_nf;
1685 ++t_row_base_fun;
1686 }
1687 for (; bb != nb_base_functions; ++bb)
1688 ++t_row_base_fun;
1689
1690 ++t_w;
1691 ++t_coords;
1692 ++t_disp_val;
1693 }
1694 }
1695 }
1696
1698}
1699
1701 EntData &col_data) {
1703 // get entity of face
1704 EntityHandle fe_ent = OP::getFEEntityHandle();
1705 // iterate over all boundary data
1706 for (auto &bc : (*bcDispPtr)) {
1707 // check if finite element entity is part of boundary condition
1708 if (bc.faces.find(fe_ent) != bc.faces.end()) {
1709 int nb_dofs = row_data.getIndices().size();
1710
1711 int nb_integration_pts = OP::getGaussPts().size2();
1712 auto t_w = OP::getFTensor0IntegrationWeight();
1713 int nb_base_functions = row_data.getN().size2();
1714 auto t_row_base_fun = row_data.getFTensor0N();
1715
1718
1720 for (int ii = 0; ii != SPACE_DIM; ++ii)
1721 t_bc_mask(ii) = bc.flags[ii] ? 1. : 0.;
1722
1723 auto get_t_vec = [&](const int rr) {
1724 std::array<double *, SPACE_DIM> ptrs;
1725 for (auto i = 0; i != SPACE_DIM; ++i)
1726 ptrs[i] = &OP::locMat(rr + i, i);
1728 SPACE_DIM>(ptrs);
1729 };
1730
1731 auto area = getMeasure();
1732 auto t_coords = OP::getFTensor1CoordsAtGaussPts();
1733 for (int gg = 0; gg != nb_integration_pts; ++gg) {
1734 auto tau_scale =
1735 area * t_w * OP::betaCoeff(t_coords(0), t_coords(1), t_coords(2));
1736 int rr = 0;
1737 for (; rr != nb_dofs / SPACE_DIM; ++rr) {
1738 auto t_mat = get_t_vec(SPACE_DIM * rr);
1739 auto t_col_base_fun = col_data.getFTensor0N(gg, 0);
1740 for (int cc = 0; cc != nb_dofs / SPACE_DIM; ++cc) {
1741 t_mat(i) +=
1742 tau_scale * (t_row_base_fun * t_col_base_fun) * t_bc_mask(i);
1743 ++t_col_base_fun;
1744 ++t_mat;
1745 }
1746 ++t_row_base_fun;
1747 }
1748 for (; rr != nb_base_functions; ++rr)
1749 ++t_row_base_fun;
1750
1751 ++t_w;
1752 ++t_coords;
1753 }
1754 }
1755 }
1756
1758}
1759
1762
1763 EntityHandle fe_ent = OP::getFEEntityHandle();
1764 for (auto &bc : (*bcDispPtr)) {
1765 if (bc.faces.find(fe_ent) != bc.faces.end()) {
1767 auto analytical_data = getAnalyticalExpr(this, analytical_expr, bc.blockName);
1768 auto &v_analytical_expr = std::get<1>(analytical_data);
1769
1770 int nb_dofs = data.getIndices().size();
1771 int nb_integration_pts = OP::getGaussPts().size2();
1772 auto t_w = OP::getFTensor0IntegrationWeight();
1773 int nb_base_functions = data.getN().size2();
1774 auto t_row_base_fun = data.getFTensor0N();
1775
1776#ifndef NDEBUG
1777 if (!this->sourceVec) {
1778 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1779 "Source vector for OpTauStabilizationOpAnalyticalDispBc is not "
1780 "set");
1781 }
1782 if (data.getN().size1() != nb_integration_pts) {
1783 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1784 "Number of integration points in data should be %d but is %d",
1785 nb_integration_pts, (int)data.getN().size1());
1786 }
1787 if (nb_base_functions < nb_dofs / SPACE_DIM) {
1788 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1789 "Number of base functions in data should be at least %d but is "
1790 "%d",
1791 nb_dofs / SPACE_DIM, nb_base_functions);
1792 }
1793#endif
1794
1795 auto t_disp_val =
1796 MatrixSizeHelper<GetFTensor1FromMatType<3, -1, DL>, DL>::get(
1797 *this->sourceVec, nb_integration_pts)();
1798 auto t_bc_disp = getFTensor1FromMat<3, -1, DL>(v_analytical_expr);
1799
1801
1802 auto area = getMeasure();
1803 auto t_coords = OP::getFTensor1CoordsAtGaussPts();
1804 for (int gg = 0; gg != nb_integration_pts; ++gg) {
1805 auto tau_scale =
1806 area * t_w * OP::betaCoeff(t_coords(0), t_coords(1), t_coords(2));
1808 for (int ii = 0; ii != SPACE_DIM; ++ii)
1809 t_bc_residual(ii) =
1810 bc.flags[ii] ? t_disp_val(ii) - t_bc_disp(ii) : 0.;
1811 auto t_nf = getFTensor1FromPtr<3, 3>(OP::locF.data().data());
1812 int bb = 0;
1813 for (; bb != nb_dofs / SPACE_DIM; ++bb) {
1814 t_nf(i) +=
1815 (tau_scale * t_row_base_fun) * t_bc_residual(i);
1816 ++t_nf;
1817 ++t_row_base_fun;
1818 }
1819 for (; bb != nb_base_functions; ++bb)
1820 ++t_row_base_fun;
1821
1822 ++t_w;
1823 ++t_coords;
1824 ++t_disp_val;
1825 ++t_bc_disp;
1826 }
1827 }
1828 }
1829
1831}
1832
1834 EntData &row_data, EntData &col_data) {
1836
1837 EntityHandle fe_ent = OP::getFEEntityHandle();
1838 for (auto &bc : (*bcDispPtr)) {
1839 if (bc.faces.find(fe_ent) != bc.faces.end()) {
1840 int nb_dofs = row_data.getIndices().size();
1841 int nb_integration_pts = OP::getGaussPts().size2();
1842 auto t_w = OP::getFTensor0IntegrationWeight();
1843 int nb_base_functions = row_data.getN().size2();
1844 auto t_row_base_fun = row_data.getFTensor0N();
1845
1848 for (int ii = 0; ii != SPACE_DIM; ++ii)
1849 t_bc_mask(ii) = bc.flags[ii] ? 1. : 0.;
1850
1851 auto get_t_vec = [&](const int rr) {
1852 std::array<double *, SPACE_DIM> ptrs;
1853 for (auto i = 0; i != SPACE_DIM; ++i)
1854 ptrs[i] = &OP::locMat(rr + i, i);
1856 SPACE_DIM>(ptrs);
1857 };
1858
1859 auto area = getMeasure();
1860 auto t_coords = OP::getFTensor1CoordsAtGaussPts();
1861 for (int gg = 0; gg != nb_integration_pts; ++gg) {
1862 auto tau_scale =
1863 area * t_w * OP::betaCoeff(t_coords(0), t_coords(1), t_coords(2));
1864 int rr = 0;
1865 for (; rr != nb_dofs / SPACE_DIM; ++rr) {
1866 auto t_mat = get_t_vec(SPACE_DIM * rr);
1867 auto t_col_base_fun = col_data.getFTensor0N(gg, 0);
1868 for (int cc = 0; cc != nb_dofs / SPACE_DIM; ++cc) {
1869 t_mat(i) +=
1870 tau_scale * (t_row_base_fun * t_col_base_fun) * t_bc_mask(i);
1871 ++t_col_base_fun;
1872 ++t_mat;
1873 }
1874 ++t_row_base_fun;
1875 }
1876 for (; rr != nb_base_functions; ++rr)
1877 ++t_row_base_fun;
1878
1879 ++t_w;
1880 ++t_coords;
1881 }
1882 }
1883 }
1884
1886}
1887
1888template <AssemblyType A>
1891
1892 FTENSOR_INDEX(3, i);
1893 FTENSOR_INDEX(3, j);
1894 FTENSOR_INDEX(3, k);
1895
1896 double time = OP::getFEMethod()->ts_t;
1899 }
1900
1901 // get entity of face
1902 EntityHandle fe_ent = OP::getFEEntityHandle();
1903 // interate over all boundary data
1904 for (auto &bc : (*bcRotPtr)) {
1905 // check if finite element entity is part of boundary condition
1906 if (bc.faces.find(fe_ent) != bc.faces.end()) {
1907 int nb_dofs = data.getIndices().size();
1908 int nb_integration_pts = OP::getGaussPts().size2();
1909 auto t_normal = OP::getFTensor1NormalsAtGaussPts();
1910 auto t_w = OP::getFTensor0IntegrationWeight();
1911
1912 int nb_base_functions = data.getN().size2() / 3;
1913 auto t_row_base_fun = data.getFTensor1N<3>();
1914
1915 // Note: First three values of bc.vals are the center of rotation
1916 // 4th is rotation angle in radians, and remaining values are axis of
1917 // rotation. Also, if rotation axis is not provided, it defaults to the
1918 // normal vector of the face.
1919
1920 // get bc data
1921 FTensor::Tensor1<double, 3> t_center(bc.vals[0], bc.vals[1], bc.vals[2]);
1922
1923 auto get_rotation_angle = [&]() {
1924 double theta = bc.theta;
1925 if (scalingMethodsMap.find(bc.blockName) != scalingMethodsMap.end()) {
1926 theta *= scalingMethodsMap.at(bc.blockName)->getScale(time);
1927 }
1928 return theta;
1929 };
1930
1931 auto get_rotation = [&](auto theta) {
1933 if (bc.vals.size() == 7) {
1934 t_omega(0) = bc.vals[4];
1935 t_omega(1) = bc.vals[5];
1936 t_omega(2) = bc.vals[6];
1937 } else {
1938 // Use gemetric face normal as rotation axis
1939 t_omega(i) = OP::getFTensor1Normal()(i);
1940 }
1941 if (t_omega.l2() > std::numeric_limits<double>::epsilon()) {
1942 t_omega.normalize();
1943 } else {
1944 MOFEM_LOG("SELF", Sev::warning)
1945 << "Rotation axis is zero vector for block " << bc.blockName
1946 << ". This may lead to unexpected results.";
1947 }
1948 t_omega(i) *= theta;
1950 RotSelector::SMALL_ROT
1951 ? 0.
1952 : t_omega.l2());
1953 };
1954
1955 auto t_R = get_rotation(get_rotation_angle());
1956 auto t_coords = OP::getFTensor1CoordsAtGaussPts();
1957
1958 for (int gg = 0; gg != nb_integration_pts; ++gg) {
1960 t_delta(i) = t_center(i) - t_coords(i);
1962 t_disp(i) = t_delta(i) - t_R(i, j) * t_delta(j);
1963
1964 auto t_nf = getFTensor1FromPtr<3>(&*OP::locF.begin());
1965 int bb = 0;
1966 for (; bb != nb_dofs / SPACE_DIM; ++bb) {
1967 t_nf(i) += t_w * (t_row_base_fun(j) * t_normal(j)) * t_disp(i) * 0.5;
1968 ++t_nf;
1969 ++t_row_base_fun;
1970 }
1971 for (; bb != nb_base_functions; ++bb)
1972 ++t_row_base_fun;
1973
1974 ++t_w;
1975 ++t_normal;
1976 ++t_coords;
1977 }
1978 }
1979 }
1981}
1982
1984 return OP::iNtegrate(data);
1985}
1986
1989
1990 FTENSOR_INDEX(3, i);
1991 FTENSOR_INDEX(3, j);
1992
1993 double time = OP::getFEMethod()->ts_t;
1996 }
1997
1998 // get entity of face
1999 EntityHandle fe_ent = OP::getFEEntityHandle();
2000 // iterate over all boundary data
2001 for (auto &bc : (*bcRotPtr)) {
2002 // check if finite element entity is part of boundary condition
2003 if (bc.faces.find(fe_ent) != bc.faces.end()) {
2004 int nb_dofs = data.getIndices().size();
2005 int nb_integration_pts = OP::getGaussPts().size2();
2006 auto t_w = OP::getFTensor0IntegrationWeight();
2007
2008 int nb_base_functions = data.getN().size2();
2009 auto t_row_base_fun = data.getFTensor0N();
2010
2011 // Note: First three values of bc.vals are the center of rotation
2012 // 4th is rotation angle in radians, and remaining values are axis of
2013 // rotation. Also, if rotation axis is not provided, it defaults to the
2014 // normal vector of the face.
2015
2016 // get bc data
2017 FTensor::Tensor1<double, 3> t_center(bc.vals[0], bc.vals[1], bc.vals[2]);
2018
2019 auto get_rotation_angle = [&]() {
2020 double theta = bc.theta;
2021 if (scalingMethodsMap.find(bc.blockName) != scalingMethodsMap.end()) {
2022 theta *= scalingMethodsMap.at(bc.blockName)->getScale(time);
2023 }
2024 return theta;
2025 };
2026
2027 auto get_rotation = [&](auto theta) {
2029 if (bc.vals.size() == 7) {
2030 t_omega(0) = bc.vals[4];
2031 t_omega(1) = bc.vals[5];
2032 t_omega(2) = bc.vals[6];
2033 } else {
2034 // Use gemetric face normal as rotation axis
2035 t_omega(i) = OP::getFTensor1Normal()(i);
2036 }
2037 if (t_omega.l2() > std::numeric_limits<double>::epsilon()) {
2038 t_omega.normalize();
2039 }
2040 t_omega(i) *= theta;
2042 RotSelector::SMALL_ROT
2043 ? 0.
2044 : t_omega.l2());
2045 };
2046
2047 auto area = getMeasure();
2048 auto t_R = get_rotation(get_rotation_angle());
2049 auto t_coords = OP::getFTensor1CoordsAtGaussPts();
2050 auto t_disp_val =
2051 MatrixSizeHelper<GetFTensor1FromMatType<3, -1, DL>, DL>::get(
2052 *this->sourceVec, nb_integration_pts)();
2053
2054 for (int gg = 0; gg != nb_integration_pts; ++gg) {
2055 auto tau_scale =
2056 area * t_w * OP::betaCoeff(t_coords(0), t_coords(1), t_coords(2));
2057
2059 t_delta(i) = t_center(i) - t_coords(i);
2061 t_bc_disp(i) = t_delta(i) - t_R(i, j) * t_delta(j);
2062
2063 auto t_nf = getFTensor1FromPtr<3>(&*OP::locF.begin());
2064 int bb = 0;
2065 for (; bb != nb_dofs / SPACE_DIM; ++bb) {
2066 t_nf(i) +=
2067 (tau_scale * t_row_base_fun) * (t_disp_val(i) - t_bc_disp(i));
2068 ++t_nf;
2069 ++t_row_base_fun;
2070 }
2071 for (; bb != nb_base_functions; ++bb)
2072 ++t_row_base_fun;
2073
2074 ++t_w;
2075 ++t_coords;
2076 ++t_disp_val;
2077 }
2078 }
2079 }
2080
2082}
2083
2085 EntData &col_data) {
2087 // get entity of face
2088 EntityHandle fe_ent = OP::getFEEntityHandle();
2089 // iterate over all boundary data
2090 for (auto &bc : (*bcRotPtr)) {
2091 // check if finite element entity is part of boundary condition
2092 if (bc.faces.find(fe_ent) != bc.faces.end()) {
2093 int nb_dofs = row_data.getIndices().size();
2094
2095 int nb_integration_pts = OP::getGaussPts().size2();
2096 auto t_w = OP::getFTensor0IntegrationWeight();
2097 int nb_base_functions = row_data.getN().size2();
2098 auto t_row_base_fun = row_data.getFTensor0N();
2099
2102
2103 auto get_t_vec = [&](const int rr) {
2104 std::array<double *, SPACE_DIM> ptrs;
2105 for (auto i = 0; i != SPACE_DIM; ++i)
2106 ptrs[i] = &OP::locMat(rr + i, i);
2108 SPACE_DIM>(ptrs);
2109 };
2110
2111 auto area = getMeasure();
2112 auto t_coords = OP::getFTensor1CoordsAtGaussPts();
2113 for (int gg = 0; gg != nb_integration_pts; ++gg) {
2114 auto tau_scale =
2115 area * t_w * OP::betaCoeff(t_coords(0), t_coords(1), t_coords(2));
2116 int rr = 0;
2117 for (; rr != nb_dofs / SPACE_DIM; ++rr) {
2118 auto t_mat = get_t_vec(SPACE_DIM * rr);
2119 auto t_col_base_fun = col_data.getFTensor0N(gg, 0);
2120 for (int cc = 0; cc != nb_dofs / SPACE_DIM; ++cc) {
2121 for (int ii = 0; ii != SPACE_DIM; ++ii) {
2122 t_mat(ii) += tau_scale * (t_row_base_fun * t_col_base_fun);
2123 }
2124 ++t_col_base_fun;
2125 ++t_mat;
2126 }
2127 ++t_row_base_fun;
2128 }
2129 for (; rr != nb_base_functions; ++rr)
2130 ++t_row_base_fun;
2131
2132 ++t_w;
2133 ++t_coords;
2134 }
2135 }
2136 }
2137
2139}
2140
2141template <AssemblyType A>
2144
2145 double time = OP::getFEMethod()->ts_t;
2148 }
2149
2150 // get entity of face
2151 EntityHandle fe_ent = OP::getFEEntityHandle();
2152 // iterate over all boundary data
2153 for (auto &bc : (*bcDispPtr)) {
2154 // check if finite element entity is part of boundary condition
2155 if (bc.faces.find(fe_ent) != bc.faces.end()) {
2156
2157 for (auto &bd : (*brokenBaseSideDataPtr)) {
2158
2159 auto t_approx_P = getFTensor2FromMat<3, 3, -1, DL>(bd.getFlux());
2160 auto t_u = getFTensor1FromMat<3, -1, DL>(*hybridDispPtr);
2161 auto t_normal = OP::getFTensor1NormalsAtGaussPts();
2162 auto t_w = OP::getFTensor0IntegrationWeight();
2163
2166
2168
2169 double scale = 1;
2170 if (scalingMethodsMap.find(bc.blockName) != scalingMethodsMap.end()) {
2171 scale *= scalingMethodsMap.at(bc.blockName)->getScale(time);
2172 } else {
2173 MOFEM_LOG("SELF", Sev::warning)
2174 << "No scaling method found for " << bc.blockName;
2175 }
2176
2177 // get bc data
2178 double val = scale * bc.val;
2179
2180 int nb_dofs = data.getIndices().size();
2181 int nb_integration_pts = OP::getGaussPts().size2();
2182 int nb_base_functions = data.getN().size2();
2183 auto t_row_base = data.getFTensor0N();
2184 for (int gg = 0; gg != nb_integration_pts; ++gg) {
2185
2187 t_N(i) = t_normal(i);
2188 t_N.normalize();
2189
2191 t_P(i, j) = t_N(i) * t_N(j);
2193 t_Q(i, j) = t_kd(i, j) - t_P(i, j);
2194
2195 FTensor::Tensor1<double, 3> t_traction;
2196 t_traction(i) = t_approx_P(i, j) * t_N(j);
2197
2199 t_res(i) =
2200 t_Q(i, j) * t_traction(j) + t_P(i, j) * 2 * t_u(j) - t_N(i) * val;
2201
2202 auto t_nf = getFTensor1FromPtr<3>(&*OP::locF.begin());
2203 int bb = 0;
2204 for (; bb != nb_dofs / SPACE_DIM; ++bb) {
2205 t_nf(i) += (t_w * t_row_base * OP::getMeasure()) * t_res(i);
2206 ++t_nf;
2207 ++t_row_base;
2208 }
2209 for (; bb != nb_base_functions; ++bb)
2210 ++t_row_base;
2211
2212 ++t_w;
2213 ++t_normal;
2214 ++t_u;
2215 ++t_approx_P;
2216 }
2217 }
2218 }
2219 }
2221}
2222
2223template <AssemblyType A>
2226 EntData &col_data) {
2228
2229 double time = OP::getFEMethod()->ts_t;
2232 }
2233
2234 int row_nb_dofs = row_data.getIndices().size();
2235 int col_nb_dofs = col_data.getIndices().size();
2236 auto &locMat = OP::locMat;
2237 locMat.resize(row_nb_dofs, col_nb_dofs, false);
2238 locMat.clear();
2239
2240 // get entity of face
2241 EntityHandle fe_ent = OP::getFEEntityHandle();
2242 // iterate over all boundary data
2243 for (auto &bc : (*bcDispPtr)) {
2244 // check if finite element entity is part of boundary condition
2245 if (bc.faces.find(fe_ent) != bc.faces.end()) {
2246
2247 auto t_normal = OP::getFTensor1NormalsAtGaussPts();
2248 auto t_w = OP::getFTensor0IntegrationWeight();
2249
2252
2253 double scale = 1;
2254 if (scalingMethodsMap.find(bc.blockName) != scalingMethodsMap.end()) {
2255 scale *= scalingMethodsMap.at(bc.blockName)->getScale(time);
2256 } else {
2257 MOFEM_LOG("SELF", Sev::warning)
2258 << "No scaling method found for " << bc.blockName;
2259 }
2260
2261 int nb_integration_pts = OP::getGaussPts().size2();
2262 int row_nb_dofs = row_data.getIndices().size();
2263 int col_nb_dofs = col_data.getIndices().size();
2264 int nb_base_functions = row_data.getN().size2();
2265 auto t_row_base = row_data.getFTensor0N();
2266
2267 for (int gg = 0; gg != nb_integration_pts; ++gg) {
2268
2270 t_N(i) = t_normal(i);
2271 t_N.normalize();
2272
2274 t_P(i, j) = t_N(i) * t_N(j);
2275
2277 t_d_res(i, j) = 2.0 * t_P(i, j);
2278
2279 int rr = 0;
2280 for (; rr != row_nb_dofs / SPACE_DIM; ++rr) {
2281 auto t_mat = getFTensor2FromArray<SPACE_DIM, SPACE_DIM, SPACE_DIM>(
2282 locMat, SPACE_DIM * rr);
2283 auto t_col_base = col_data.getFTensor0N(gg, 0);
2284 for (auto cc = 0; cc != col_nb_dofs / SPACE_DIM; ++cc) {
2285 t_mat(i, j) += (t_w * t_row_base * t_col_base) * t_d_res(i, j);
2286 ++t_mat;
2287 ++t_col_base;
2288 }
2289 ++t_row_base;
2290 }
2291
2292 for (; rr != nb_base_functions; ++rr)
2293 ++t_row_base;
2294
2295 ++t_w;
2296 ++t_normal;
2297 }
2298
2299 locMat *= OP::getMeasure();
2300 }
2301 }
2303}
2304
2305template <AssemblyType A>
2308 EntData &col_data) {
2310
2311 double time = OP::getFEMethod()->ts_t;
2314 }
2315
2316 int row_nb_dofs = row_data.getIndices().size();
2317 int col_nb_dofs = col_data.getIndices().size();
2318 auto &locMat = OP::locMat;
2319 locMat.resize(row_nb_dofs, col_nb_dofs, false);
2320 locMat.clear();
2321
2322 // get entity of face
2323 EntityHandle fe_ent = OP::getFEEntityHandle();
2324 // iterate over all boundary data
2325 for (auto &bc : (*bcDispPtr)) {
2326 // check if finite element entity is part of boundary condition
2327 if (bc.faces.find(fe_ent) != bc.faces.end()) {
2328
2329 auto t_normal = OP::getFTensor1NormalsAtGaussPts();
2330 auto t_w = OP::getFTensor0IntegrationWeight();
2331
2335
2337
2338 double scale = 1;
2339 if (scalingMethodsMap.find(bc.blockName) != scalingMethodsMap.end()) {
2340 scale *= scalingMethodsMap.at(bc.blockName)->getScale(time);
2341 } else {
2342 MOFEM_LOG("SELF", Sev::warning)
2343 << "No scaling method found for " << bc.blockName;
2344 }
2345
2346 int nb_integration_pts = OP::getGaussPts().size2();
2347 int nb_base_functions = row_data.getN().size2();
2348 auto t_row_base = row_data.getFTensor0N();
2349
2350 for (int gg = 0; gg != nb_integration_pts; ++gg) {
2351
2353 t_N(i) = t_normal(i);
2354 t_N.normalize();
2355
2357 t_P(i, j) = t_N(i) * t_N(j);
2359 t_Q(i, j) = t_kd(i, j) - t_P(i, j);
2360
2362 t_d_res(i, j) = t_Q(i, j);
2363
2364 int rr = 0;
2365 for (; rr != row_nb_dofs / SPACE_DIM; ++rr) {
2366 auto t_mat = getFTensor2FromArray<SPACE_DIM, SPACE_DIM, SPACE_DIM>(
2367 OP::locMat, SPACE_DIM * rr);
2368 auto t_col_base = col_data.getFTensor1N<3>(gg, 0);
2369 for (auto cc = 0; cc != col_nb_dofs / SPACE_DIM; ++cc) {
2370 t_mat(i, j) +=
2371 ((t_w * t_row_base) * (t_N(k) * t_col_base(k))) * t_d_res(i, j);
2372 ++t_mat;
2373 ++t_col_base;
2374 }
2375 ++t_row_base;
2376 }
2377
2378 for (; rr != nb_base_functions; ++rr)
2379 ++t_row_base;
2380
2381 ++t_w;
2382 ++t_normal;
2383 }
2384
2385 locMat *= OP::getMeasure();
2386 }
2387 }
2389}
2390
2392 return OP::iNtegrate(data);
2393}
2394
2396 EntData &col_data) {
2397 return OP::iNtegrate(row_data, col_data);
2398}
2399
2401 EntData &col_data) {
2402 return OP::iNtegrate(row_data, col_data);
2403}
2404
2407
2408 // get entity of face
2409 EntityHandle fe_ent = OP::getFEEntityHandle();
2410 // iterate over all boundary data
2411 for (auto &bc : (*bcSpringPtr)) {
2412 // check if finite element entity is part of boundary condition
2413 if (bc.faces.find(fe_ent) != bc.faces.end()) {
2414
2415 for (auto &bd : (*brokenBaseSideDataPtr)) {
2416
2417 auto t_approx_P = getFTensor2FromMat<3, 3, -1, DL>(bd.getFlux());
2418 auto t_u = getFTensor1FromMat<3, -1, DL>(*hybridDispPtr);
2419 auto t_normal = OP::getFTensor1NormalsAtGaussPts();
2420 auto t_w = OP::getFTensor0IntegrationWeight();
2421
2424
2426
2427 int nb_dofs = data.getIndices().size();
2428 int nb_integration_pts = OP::getGaussPts().size2();
2429 int nb_base_functions = data.getN().size2();
2430 auto t_row_base = data.getFTensor0N();
2431 for (int gg = 0; gg != nb_integration_pts; ++gg) {
2432
2434 t_N(i) = t_normal(i);
2435 t_N.normalize();
2436
2438 t_P(i, j) = t_N(i) * t_N(j);
2440 t_Q(i, j) = t_kd(i, j) - t_P(i, j);
2441
2442 FTensor::Tensor1<double, 3> t_traction;
2443 t_traction(i) = t_approx_P(i, j) * t_N(j);
2444
2446 t_res(i) = 0.5 *(t_traction(i)) - bc.normalStiffness * t_P(i, j) * t_u(j) -
2447 bc.tangentialStiffness * t_Q(i, j) * t_u(j);
2448
2449 auto t_nf = getFTensor1FromPtr<3>(&*OP::locF.begin());
2450 int bb = 0;
2451 for (; bb != nb_dofs / SPACE_DIM; ++bb) {
2452 t_nf(i) += (t_w * t_row_base * OP::getMeasure()) * t_res(i);
2453 ++t_nf;
2454 ++t_row_base;
2455 }
2456 for (; bb != nb_base_functions; ++bb)
2457 ++t_row_base;
2458
2459 ++t_w;
2460 ++t_normal;
2461 ++t_u;
2462 ++t_approx_P;
2463 }
2464 }
2465 }
2466 }
2468}
2469
2471 EntData &col_data) {
2473
2474 int row_nb_dofs = row_data.getIndices().size();
2475 int col_nb_dofs = col_data.getIndices().size();
2476 auto &locMat = OP::locMat;
2477 locMat.resize(row_nb_dofs, col_nb_dofs, false);
2478 locMat.clear();
2479
2480 // get entity of face
2481 EntityHandle fe_ent = OP::getFEEntityHandle();
2482 // iterate over all boundary data
2483 for (auto &bc : (*bcSpringPtr)) {
2484 // check if finite element entity is part of boundary condition
2485 if (bc.faces.find(fe_ent) != bc.faces.end()) {
2486
2487 auto t_normal = OP::getFTensor1NormalsAtGaussPts();
2488 auto t_w = OP::getFTensor0IntegrationWeight();
2489
2492
2493 int nb_integration_pts = OP::getGaussPts().size2();
2494 int nb_base_functions = row_data.getN().size2();
2495 auto t_row_base = row_data.getFTensor0N();
2496
2498
2499 for (int gg = 0; gg != nb_integration_pts; ++gg) {
2500
2502 t_N(i) = t_normal(i);
2503 t_N.normalize();
2504
2506 t_P(i, j) = t_N(i) * t_N(j);
2508 t_Q(i, j) = t_kd(i, j) - t_P(i, j);
2509
2511 t_d_res(i, j) = -(bc.normalStiffness * t_P(i, j) +
2512 bc.tangentialStiffness * t_Q(i, j));
2513
2514 int rr = 0;
2515 for (; rr != row_nb_dofs / SPACE_DIM; ++rr) {
2516 auto t_mat = getFTensor2FromArray<SPACE_DIM, SPACE_DIM, SPACE_DIM>(
2517 locMat, SPACE_DIM * rr);
2518 auto t_col_base = col_data.getFTensor0N(gg, 0);
2519 for (auto cc = 0; cc != col_nb_dofs / SPACE_DIM; ++cc) {
2520 t_mat(i, j) += (t_w * t_row_base * t_col_base) * t_d_res(i, j);
2521 ++t_mat;
2522 ++t_col_base;
2523 }
2524 ++t_row_base;
2525 }
2526
2527 for (; rr != nb_base_functions; ++rr)
2528 ++t_row_base;
2529
2530 ++t_w;
2531 ++t_normal;
2532 }
2533
2534 locMat *= OP::getMeasure();
2535 }
2536 }
2538}
2539
2541 EntData &col_data) {
2543
2544 int row_nb_dofs = row_data.getIndices().size();
2545 int col_nb_dofs = col_data.getIndices().size();
2546 auto &locMat = OP::locMat;
2547 locMat.resize(row_nb_dofs, col_nb_dofs, false);
2548 locMat.clear();
2549
2550 // get entity of face
2551 EntityHandle fe_ent = OP::getFEEntityHandle();
2552 // iterate over all boundary data
2553 for (auto &bc : (*bcSpringPtr)) {
2554 // check if finite element entity is part of boundary condition
2555 if (bc.faces.find(fe_ent) != bc.faces.end()) {
2556
2557 auto t_normal = OP::getFTensor1NormalsAtGaussPts();
2558 auto t_w = OP::getFTensor0IntegrationWeight();
2559
2563
2564 int nb_integration_pts = OP::getGaussPts().size2();
2565 int nb_base_functions = row_data.getN().size2();
2566 auto t_row_base = row_data.getFTensor0N();
2567
2569
2570 for (int gg = 0; gg != nb_integration_pts; ++gg) {
2571
2573 t_N(i) = t_normal(i);
2574 t_N.normalize();
2575
2576 int rr = 0;
2577 for (; rr != row_nb_dofs / SPACE_DIM; ++rr) {
2578 auto t_mat = getFTensor2FromArray<SPACE_DIM, SPACE_DIM, SPACE_DIM>(
2579 OP::locMat, SPACE_DIM * rr);
2580 auto t_col_base = col_data.getFTensor1N<3>(gg, 0);
2581 for (auto cc = 0; cc != col_nb_dofs / SPACE_DIM; ++cc) {
2582 t_mat(i, j) +=
2583 ((t_w * t_row_base) * (t_N(k) * t_col_base(k))) * 0.5 * t_kd(i, j);
2584 ++t_mat;
2585 ++t_col_base;
2586 }
2587 ++t_row_base;
2588 }
2589
2590 for (; rr != nb_base_functions; ++rr)
2591 ++t_row_base;
2592
2593 ++t_w;
2594 ++t_normal;
2595 }
2596
2597 locMat *= OP::getMeasure();
2598 }
2599 }
2601}
2602
2603template <AssemblyType A>
2606
2607 double time = OP::getFEMethod()->ts_t;
2610 }
2611
2612 // get entity of face
2613 EntityHandle fe_ent = OP::getFEEntityHandle();
2614 // iterate over all boundary data
2615 for (auto &bc : (*bcDispPtr)) {
2616 // check if finite element entity is part of boundary condition
2617 if (bc.faces.find(fe_ent) != bc.faces.end()) {
2618
2620 // placeholder to pass boundary block id to python
2621
2622 auto [block_name, v_analytical_expr] =
2623 getAnalyticalExpr(this, analytical_expr, bc.blockName);
2624
2625 int nb_dofs = data.getIndices().size();
2626 if (!nb_dofs) {
2627 continue;
2628 }
2629
2630 int nb_integration_pts = OP::getGaussPts().size2();
2631 auto t_normal = OP::getFTensor1NormalsAtGaussPts();
2632 auto t_w = OP::getFTensor0IntegrationWeight();
2633 int nb_base_functions = data.getN().size2() / 3;
2634 auto t_row_base_fun = data.getFTensor1N<3>();
2635
2638
2639 // get bc data
2640 auto t_bc_disp = getFTensor1FromMat<3, -1, DL>(v_analytical_expr);
2641
2642 for (int gg = 0; gg != nb_integration_pts; ++gg) {
2643 auto t_nf = getFTensor1FromPtr<3>(&*OP::locF.begin());
2644
2645 int bb = 0;
2646 for (; bb != nb_dofs / SPACE_DIM; ++bb) {
2647 t_nf(i) +=
2648 t_w * (t_row_base_fun(j) * t_normal(j)) * t_bc_disp(i) * 0.5;
2649 ++t_nf;
2650 ++t_row_base_fun;
2651 }
2652 for (; bb != nb_base_functions; ++bb)
2653 ++t_row_base_fun;
2654
2655 ++t_bc_disp;
2656 ++t_w;
2657 ++t_normal;
2658 }
2659 }
2660 }
2662}
2663
2665 return OP::iNtegrate(data);
2666}
2667
2670
2671 FTENSOR_INDEX(3, i);
2672
2673 int nb_dofs = data.getFieldData().size();
2674 int nb_integration_pts = getGaussPts().size2();
2675 int nb_base_functions = data.getN().size2();
2676
2677 double time = getFEMethod()->ts_t;
2680 }
2681
2682#ifndef NDEBUG
2683 if (this->locF.size() != nb_dofs)
2684 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
2685 "Size of locF %ld != nb_dofs %d", this->locF.size(), nb_dofs);
2686#endif // NDEBUG
2687
2688 auto integrate_rhs = [&](auto &bc, auto calc_tau, double time_scale) {
2690
2691 auto t_val = getFTensor1FromPtr<3>(&*bc.vals.begin());
2692 auto t_row_base = data.getFTensor0N();
2693 auto t_w = getFTensor0IntegrationWeight();
2694 auto t_coords = getFTensor1CoordsAtGaussPts();
2695 auto t_normal = getFTensor1NormalsAtGaussPts();
2696
2697 double scale = (piolaScalePtr) ? 1. / (*piolaScalePtr) : 1.0;
2698
2699 for (int gg = 0; gg != nb_integration_pts; ++gg) {
2700
2701 double a = sqrt(t_normal(i) * t_normal(i));
2702 a /= 2.;
2703 const auto tau = calc_tau(t_coords(0), t_coords(1), t_coords(2));
2704 auto t_f = getFTensor1FromPtr<3>(&*this->locF.begin());
2705 int rr = 0;
2706 for (; rr != nb_dofs / SPACE_DIM; ++rr) {
2707 t_f(i) -=
2708 (time_scale * a * t_w * t_row_base * tau) * (t_val(i) * scale);
2709 ++t_row_base;
2710 ++t_f;
2711 }
2712
2713 for (; rr != nb_base_functions; ++rr)
2714 ++t_row_base;
2715 ++t_w;
2716 ++t_coords;
2717 ++t_normal;
2718 }
2720 };
2721
2722 // get entity of face
2723 EntityHandle fe_ent = getFEEntityHandle();
2724 for (auto &bc : *(bcData)) {
2725 if (bc.faces.find(fe_ent) != bc.faces.end()) {
2726
2727 double time_scale = 1;
2728 if (scalingMethodsMap.find(bc.blockName) != scalingMethodsMap.end()) {
2729 time_scale *= scalingMethodsMap.at(bc.blockName)->getScale(time);
2730 }
2731
2732 int nb_dofs = data.getFieldData().size();
2733 if (nb_dofs) {
2734
2735 if (std::regex_match(bc.blockName, std::regex(".*COOK.*"))) {
2736 auto calc_tau = [](double, double y, double) {
2737 y -= 44;
2738 y /= (60 - 44);
2739 return -y * (y - 1) / 0.25;
2740 };
2741 CHKERR integrate_rhs(bc, calc_tau, time_scale);
2742 } else {
2743 CHKERR integrate_rhs(
2744 bc, [](double, double, double) { return 1; }, time_scale);
2745 }
2746 }
2747 }
2748 }
2750}
2751
2754
2755 FTENSOR_INDEX(3, i);
2756
2757 int nb_dofs = data.getFieldData().size();
2758 int nb_integration_pts = getGaussPts().size2();
2759 int nb_base_functions = data.getN().size2();
2760
2761 double time = getFEMethod()->ts_t;
2764 }
2765
2766#ifndef NDEBUG
2767 if (this->locF.size() != nb_dofs)
2768 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
2769 "Size of locF %ld != nb_dofs %d", this->locF.size(), nb_dofs);
2770#endif // NDEBUG
2771
2772 auto integrate_rhs = [&](auto &bc, auto calc_tau, double time_scale) {
2774
2775 auto val = bc.val;
2776 auto t_row_base = data.getFTensor0N();
2777 auto t_w = getFTensor0IntegrationWeight();
2778 auto t_coords = getFTensor1CoordsAtGaussPts();
2779 auto t_tangent1 = getFTensor1Tangent1AtGaussPts();
2780 auto t_tangent2 = getFTensor1Tangent2AtGaussPts();
2781
2782 auto t_grad_gamma_u = getFTensor2FromMat<3, 2, -1, DL>(*hybridGradDispPtr);
2783
2784 double scale = (piolaScalePtr) ? 1. / (*piolaScalePtr) : 1.0;
2785
2786 for (int gg = 0; gg != nb_integration_pts; ++gg) {
2787
2793
2795 if (EshelbianCore::stretchSelector == LINEAR &&
2796 EshelbianCore::gradApproximator < MODERATE_ROT) {
2797
2798 t_normal(i) = (FTensor::levi_civita<double>(i, j, k) * t_tangent1(j)) *
2799 t_tangent2(k);
2800 } else {
2801 t_normal(i) = (FTensor::levi_civita<double>(i, j, k) *
2802 (t_tangent1(j) + t_grad_gamma_u(j, N0))) *
2803 (t_tangent2(k) + t_grad_gamma_u(k, N1));
2804 }
2805 auto tau = calc_tau(t_coords(0), t_coords(1), t_coords(2));
2806 auto t_val = FTensor::Tensor1<double, 3>();
2807 t_val(i) = (time_scale * t_w * tau * scale * val) * t_normal(i);
2808
2809 auto t_f = getFTensor1FromPtr<3>(&*this->locF.begin());
2810 int rr = 0;
2811 for (; rr != nb_dofs / SPACE_DIM; ++rr) {
2812 t_f(i) += t_row_base * t_val(i);
2813 ++t_row_base;
2814 ++t_f;
2815 }
2816
2817 for (; rr != nb_base_functions; ++rr)
2818 ++t_row_base;
2819 ++t_w;
2820 ++t_coords;
2821 ++t_tangent1;
2822 ++t_tangent2;
2823 ++t_grad_gamma_u;
2824 }
2825 this->locF /= 2.;
2826
2828 };
2829
2830 // get entity of face
2831 EntityHandle fe_ent = getFEEntityHandle();
2832 for (auto &bc : *(bcData)) {
2833 if (bc.faces.find(fe_ent) != bc.faces.end()) {
2834
2835 double time_scale = 1;
2836 if (scalingMethodsMap.find(bc.blockName) != scalingMethodsMap.end()) {
2837 time_scale *= scalingMethodsMap.at(bc.blockName)->getScale(time);
2838 }
2839
2840 int nb_dofs = data.getFieldData().size();
2841 if (nb_dofs) {
2842 CHKERR integrate_rhs(
2843 bc, [](double, double, double) { return 1; }, time_scale);
2844 }
2845 }
2846 }
2848}
2849
2850template <AssemblyType A>
2853 EntData &col_data) {
2855
2856 if (EshelbianCore::stretchSelector == LINEAR &&
2857 EshelbianCore::gradApproximator < MODERATE_ROT) {
2859 }
2860
2861 double time = OP::getFEMethod()->ts_t;
2864 }
2865
2866 int nb_base_functions = row_data.getN().size2();
2867 int row_nb_dofs = row_data.getIndices().size();
2868 int col_nb_dofs = col_data.getIndices().size();
2869 int nb_integration_pts = OP::getGaussPts().size2();
2870 auto &locMat = OP::locMat;
2871 locMat.resize(row_nb_dofs, col_nb_dofs, false);
2872 locMat.clear();
2873
2874 auto integrate_lhs = [&](auto &bc, auto calc_tau, double time_scale) {
2876
2877 auto val = bc.val;
2878 auto t_row_base = row_data.getFTensor0N();
2879 auto t_w = OP::getFTensor0IntegrationWeight();
2880 auto t_coords = OP::getFTensor1CoordsAtGaussPts();
2881 auto t_tangent1 = OP::getFTensor1Tangent1AtGaussPts();
2882 auto t_tangent2 = OP::getFTensor1Tangent2AtGaussPts();
2883
2884 auto t_grad_gamma_u = getFTensor2FromMat<3, 2, -1, DL>(*hybridGradDispPtr);
2886
2887 for (int gg = 0; gg != nb_integration_pts; ++gg) {
2888
2893
2896
2897 auto tau = calc_tau(t_coords(0), t_coords(1), t_coords(2));
2898 auto t_val = time_scale * t_w * tau * val;
2899
2900 int rr = 0;
2901 for (; rr != row_nb_dofs / SPACE_DIM; ++rr) {
2902 auto t_mat = getFTensor2FromArray<SPACE_DIM, SPACE_DIM, SPACE_DIM>(
2903 locMat, SPACE_DIM * rr);
2904 auto t_diff_col_base = col_data.getFTensor1DiffN<2>(gg, 0);
2905 for (auto cc = 0; cc != col_nb_dofs / SPACE_DIM; ++cc) {
2907 t_normal_du(i, l) = (FTensor::levi_civita<double>(i, j, k) *
2908 (t_tangent2(k) + t_grad_gamma_u(k, N1))) *
2909 t_kd(j, l) * t_diff_col_base(N0)
2910
2911 +
2912
2913 (FTensor::levi_civita<double>(i, j, k) *
2914 (t_tangent1(j) + t_grad_gamma_u(j, N0))) *
2915 t_kd(k, l) * t_diff_col_base(N1);
2916
2917 t_mat(i, j) += t_row_base * t_val * t_normal_du(i, j);
2918 ++t_mat;
2919 ++t_diff_col_base;
2920 }
2921 ++t_row_base;
2922 }
2923
2924 for (; rr != nb_base_functions; ++rr)
2925 ++t_row_base;
2926 ++t_w;
2927 ++t_coords;
2928 ++t_tangent1;
2929 ++t_tangent2;
2930 ++t_grad_gamma_u;
2931 }
2932
2933 OP::locMat /= 2.;
2934
2936 };
2937
2938 // get entity of face
2939 EntityHandle fe_ent = OP::getFEEntityHandle();
2940 for (auto &bc : *(bcData)) {
2941 if (bc.faces.find(fe_ent) != bc.faces.end()) {
2942
2943 double time_scale = 1;
2944 if (scalingMethodsMap.find(bc.blockName) != scalingMethodsMap.end()) {
2945 time_scale *= scalingMethodsMap.at(bc.blockName)->getScale(time);
2946 }
2947
2948 int nb_dofs = row_data.getFieldData().size();
2949 if (nb_dofs) {
2950 CHKERR integrate_lhs(
2951 bc, [](double, double, double) { return 1; }, time_scale);
2952 }
2953 }
2954 }
2955
2957}
2958
2960 EntData &col_data) {
2961 return OP::iNtegrate(row_data, col_data);
2962}
2963
2966
2967 FTENSOR_INDEX(3, i);
2968
2969 int nb_dofs = data.getFieldData().size();
2970 int nb_integration_pts = getGaussPts().size2();
2971 int nb_base_functions = data.getN().size2();
2972
2973 double time = getFEMethod()->ts_t;
2976 }
2977
2978#ifndef NDEBUG
2979 if (this->locF.size() != nb_dofs)
2980 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
2981 "Size of locF %ld != nb_dofs %d", this->locF.size(), nb_dofs);
2982#endif // NDEBUG
2983
2984 // get entity of face
2985 EntityHandle fe_ent = getFEEntityHandle();
2986 for (auto &bc : *(bcData)) {
2987 if (bc.faces.find(fe_ent) != bc.faces.end()) {
2988
2990 // placeholder to pass boundary block id to python
2991 auto [block_name, v_analytical_expr] =
2992 getAnalyticalExpr(this, analytical_expr, bc.blockName);
2993 auto t_val = getFTensor1FromMat<3, -1, DL>(v_analytical_expr);
2994 auto t_row_base = data.getFTensor0N();
2995 auto t_w = getFTensor0IntegrationWeight();
2996 auto t_coords = getFTensor1CoordsAtGaussPts();
2997
2998 double scale = (piolaScalePtr) ? 1. / (*piolaScalePtr) : 1.0;
2999
3000 for (int gg = 0; gg != nb_integration_pts; ++gg) {
3001
3002 auto t_f = getFTensor1FromPtr<3>(&*this->locF.begin());
3003 int rr = 0;
3004 for (; rr != nb_dofs / SPACE_DIM; ++rr) {
3005 t_f(i) -= t_w * t_row_base * (t_val(i) * scale);
3006 ++t_row_base;
3007 ++t_f;
3008 }
3009
3010 for (; rr != nb_base_functions; ++rr)
3011 ++t_row_base;
3012 ++t_w;
3013 ++t_coords;
3014 ++t_val;
3015 }
3016 this->locF *= getMeasure();
3017 }
3018 }
3020}
3021
3023 EntData &col_data) {
3025 int nb_integration_pts = row_data.getN().size1();
3026 int row_nb_dofs = row_data.getIndices().size();
3027 int col_nb_dofs = col_data.getIndices().size();
3028 auto get_ftensor1 = [](MatrixDouble &m, const int r, const int c) {
3030 &m(r + 0, c + 0), &m(r + 1, c + 1), &m(r + 2, c + 2));
3031 };
3032 FTensor::Index<'i', 3> i;
3033 auto v = getVolume();
3034 auto t_w = getFTensor0IntegrationWeight();
3035 int row_nb_base_functions = row_data.getN().size2();
3036 auto t_row_base_fun = row_data.getFTensor0N();
3037 for (int gg = 0; gg != nb_integration_pts; ++gg) {
3038 double a = v * t_w;
3039 int rr = 0;
3040 for (; rr != row_nb_dofs / 3; ++rr) {
3041 auto t_col_diff_base_fun = col_data.getFTensor2DiffN<3, 3>(gg, 0);
3042 auto t_m = get_ftensor1(K, 3 * rr, 0);
3043 for (int cc = 0; cc != col_nb_dofs / 3; ++cc) {
3044 double div_col_base = t_col_diff_base_fun(i, i);
3045 t_m(i) -= a * t_row_base_fun * div_col_base;
3046 ++t_m;
3047 ++t_col_diff_base_fun;
3048 }
3049 ++t_row_base_fun;
3050 }
3051 for (; rr != row_nb_base_functions; ++rr)
3052 ++t_row_base_fun;
3053 ++t_w;
3054 }
3056}
3057
3059 EntData &col_data) {
3061
3062 if (alphaW < std::numeric_limits<double>::epsilon() &&
3063 alphaRho < std::numeric_limits<double>::epsilon())
3065
3066 const int nb_integration_pts = row_data.getN().size1();
3067 const int row_nb_dofs = row_data.getIndices().size();
3068 auto get_ftensor1 = [](MatrixDouble &m, const int r, const int c) {
3070 &m(r + 0, c + 0), &m(r + 1, c + 1), &m(r + 2, c + 2)
3071
3072 );
3073 };
3074 FTensor::Index<'i', 3> i;
3075
3076 auto v = getVolume();
3077 auto t_w = getFTensor0IntegrationWeight();
3078
3079 auto piola_scale = dataAtPts->piolaScale;
3080 auto alpha_w = alphaW / piola_scale;
3081 auto alpha_rho = alphaRho / piola_scale;
3082
3083 int row_nb_base_functions = row_data.getN().size2();
3084 auto t_row_base_fun = row_data.getFTensor0N();
3085
3086 double ts_scale = alpha_w * getTSa();
3087 if (std::abs(alphaRho) > std::numeric_limits<double>::epsilon())
3088 ts_scale += alpha_rho * getTSaa();
3089
3090 for (int gg = 0; gg != nb_integration_pts; ++gg) {
3091 double a = v * t_w * ts_scale;
3092
3093 int rr = 0;
3094 for (; rr != row_nb_dofs / 3; ++rr) {
3095
3096 auto t_col_base_fun = row_data.getFTensor0N(gg, 0);
3097 auto t_m = get_ftensor1(K, 3 * rr, 0);
3098 for (int cc = 0; cc != row_nb_dofs / 3; ++cc) {
3099 const double b = a * t_row_base_fun * t_col_base_fun;
3100 t_m(i) += b;
3101 ++t_m;
3102 ++t_col_base_fun;
3103 }
3104
3105 ++t_row_base_fun;
3106 }
3107
3108 for (; rr != row_nb_base_functions; ++rr)
3109 ++t_row_base_fun;
3110
3111 ++t_w;
3112 }
3113
3115}
3116
3118 EntData &col_data) {
3120
3126
3127 int nb_integration_pts = row_data.getN().size1();
3128 int row_nb_dofs = row_data.getIndices().size();
3129 int col_nb_dofs = col_data.getIndices().size();
3130 auto get_ftensor3 = [](MatrixDouble &m, const int r, const int c) {
3132
3133 &m(r + 0, c + 0), &m(r + 0, c + 1), &m(r + 0, c + 2),
3134
3135 &m(r + 1, c + 0), &m(r + 1, c + 1), &m(r + 1, c + 2),
3136
3137 &m(r + 2, c + 0), &m(r + 2, c + 1), &m(r + 2, c + 2),
3138
3139 &m(r + 3, c + 0), &m(r + 3, c + 1), &m(r + 3, c + 2),
3140
3141 &m(r + 4, c + 0), &m(r + 4, c + 1), &m(r + 4, c + 2),
3142
3143 &m(r + 5, c + 0), &m(r + 5, c + 1), &m(r + 5, c + 2));
3144 };
3145
3146 auto v = getVolume();
3147 auto t_w = getFTensor0IntegrationWeight();
3148
3149 int row_nb_base_functions = row_data.getN().size2();
3150 auto t_row_base_fun = row_data.getFTensor0N();
3151
3152 auto t_approx_P_adjoint_log_du_dP =
3153 dataAtPts->getFTensorAdjointPdUdP(nb_integration_pts);
3154 auto t_plasticF = dataAtPts->getFTensorPlasticF(nb_integration_pts);
3155
3156 for (int gg = 0; gg != nb_integration_pts; ++gg) {
3157 const double det_plasticF = determinantTensor3by3(t_plasticF);
3158 double a = v * t_w * det_plasticF;
3159 int rr = 0;
3160 for (; rr != row_nb_dofs / 6; ++rr) {
3161
3162 auto t_col_base_fun = col_data.getFTensor1N<3>(gg, 0);
3163 auto t_m = get_ftensor3(K, 6 * rr, 0);
3164
3165 for (int cc = 0; cc != col_nb_dofs / 3; ++cc) {
3166 FTensor::Tensor1<double, 3> t_col_base_piola;
3167 t_col_base_piola(j) =
3168 t_plasticF(j, k) * t_col_base_fun(k) / det_plasticF;
3169 t_m(L, i) -=
3170 a * (t_approx_P_adjoint_log_du_dP(i, j, L) *
3171 t_col_base_piola(j)) *
3172 t_row_base_fun;
3173 ++t_col_base_fun;
3174 ++t_m;
3175 }
3176
3177 ++t_row_base_fun;
3178 }
3179 for (; rr != row_nb_base_functions; ++rr)
3180 ++t_row_base_fun;
3181 ++t_w;
3182 ++t_approx_P_adjoint_log_du_dP;
3183 ++t_plasticF;
3184 }
3185
3187}
3188
3190 EntData &col_data) {
3192
3198
3199 int nb_integration_pts = row_data.getN().size1();
3200 int row_nb_dofs = row_data.getIndices().size();
3201 int col_nb_dofs = col_data.getIndices().size();
3202 auto get_ftensor2 = [](MatrixDouble &m, const int r, const int c) {
3204 &m(r + 0, c), &m(r + 1, c), &m(r + 2, c), &m(r + 3, c), &m(r + 4, c),
3205 &m(r + 5, c));
3206 };
3207
3208 auto v = getVolume();
3209 auto t_w = getFTensor0IntegrationWeight();
3210 auto t_row_base_fun = row_data.getFTensor0N();
3211
3212 int row_nb_base_functions = row_data.getN().size2();
3213
3214 auto t_approx_P_adjoint_log_du_dP =
3215 dataAtPts->getFTensorAdjointPdUdP(nb_integration_pts);
3216 auto t_plasticF = dataAtPts->getFTensorPlasticF(nb_integration_pts);
3217
3218 for (int gg = 0; gg != nb_integration_pts; ++gg) {
3219 const double det_plasticF = determinantTensor3by3(t_plasticF);
3220 double a = v * t_w * det_plasticF;
3221 int rr = 0;
3222 for (; rr != row_nb_dofs / 6; ++rr) {
3223 auto t_m = get_ftensor2(K, 6 * rr, 0);
3224 auto t_col_base_fun = col_data.getFTensor2N<3, 3>(gg, 0);
3225 for (int cc = 0; cc != col_nb_dofs; ++cc) {
3226 FTensor::Tensor2<double, 3, 3> t_col_base_piola;
3227 t_col_base_piola(i, j) =
3228 t_col_base_fun(i, k) * t_plasticF(j, k) / det_plasticF;
3229 t_m(L) -=
3230 a * (t_approx_P_adjoint_log_du_dP(i, j, L) *
3231 t_col_base_piola(i, j)) *
3232 t_row_base_fun;
3233 ++t_m;
3234 ++t_col_base_fun;
3235 }
3236 ++t_row_base_fun;
3237 }
3238 for (; rr != row_nb_base_functions; ++rr)
3239 ++t_row_base_fun;
3240 ++t_w;
3241 ++t_approx_P_adjoint_log_du_dP;
3242 ++t_plasticF;
3243 }
3245}
3246
3248 EntData &col_data) {
3250
3252
3253 int nb_integration_pts = getGaussPts().size2();
3254 int row_nb_dofs = row_data.getIndices().size();
3255 int col_nb_dofs = col_data.getIndices().size();
3256 auto get_ftensor3 = [](MatrixDouble &m, const int r, const int c) {
3258
3259 &m(r + 0, c + 0), &m(r + 0, c + 1), &m(r + 0, c + 2),
3260
3261 &m(r + 1, c + 0), &m(r + 1, c + 1), &m(r + 1, c + 2),
3262
3263 &m(r + 2, c + 0), &m(r + 2, c + 1), &m(r + 2, c + 2),
3264
3265 &m(r + 3, c + 0), &m(r + 3, c + 1), &m(r + 3, c + 2),
3266
3267 &m(r + 4, c + 0), &m(r + 4, c + 1), &m(r + 4, c + 2),
3268
3269 &m(r + 5, c + 0), &m(r + 5, c + 1), &m(r + 5, c + 2)
3270
3271 );
3272 };
3273 FTensor::Index<'i', 3> i;
3274 FTensor::Index<'j', 3> j;
3275 FTensor::Index<'k', 3> k;
3276 FTensor::Index<'m', 3> m;
3277 FTensor::Index<'n', 3> n;
3278
3279 auto v = getVolume();
3280 auto t_w = getFTensor0IntegrationWeight();
3281 auto t_approx_P_adjoint_log_du_domega =
3282 dataAtPts->getFTensorAdjointPdUdOmega(nb_integration_pts);
3283 auto t_plasticF = dataAtPts->getFTensorPlasticF(nb_integration_pts);
3284
3285 int row_nb_base_functions = row_data.getN().size2();
3286 auto t_row_base_fun = row_data.getFTensor0N();
3287
3288 for (int gg = 0; gg != nb_integration_pts; ++gg) {
3289 const double det_plasticF = determinantTensor3by3(t_plasticF);
3290 double a = v * t_w * det_plasticF;
3291
3292 int rr = 0;
3293 for (; rr != row_nb_dofs / 6; ++rr) {
3294 auto t_col_base_fun = col_data.getFTensor0N(gg, 0);
3295 auto t_m = get_ftensor3(K, 6 * rr, 0);
3296 for (int cc = 0; cc != col_nb_dofs / 3; ++cc) {
3297 double v = a * t_row_base_fun * t_col_base_fun;
3298 t_m(L, k) -= v * t_approx_P_adjoint_log_du_domega(k, L);
3299 ++t_m;
3300 ++t_col_base_fun;
3301 }
3302 ++t_row_base_fun;
3303 }
3304
3305 for (; rr != row_nb_base_functions; ++rr)
3306 ++t_row_base_fun;
3307
3308 ++t_w;
3309 ++t_approx_P_adjoint_log_du_domega;
3310 ++t_plasticF;
3311 }
3312
3314}
3315
3317 EntData &col_data) {
3319 int nb_integration_pts = getGaussPts().size2();
3320 int row_nb_dofs = row_data.getIndices().size();
3321 int col_nb_dofs = col_data.getIndices().size();
3322 auto get_ftensor2 = [](MatrixDouble &m, const int r, const int c) {
3324 size_symm>{
3325
3326 &m(r + 0, c + 0), &m(r + 0, c + 1), &m(r + 0, c + 2), &m(r + 0, c + 3),
3327 &m(r + 0, c + 4), &m(r + 0, c + 5),
3328
3329 &m(r + 1, c + 0), &m(r + 1, c + 1), &m(r + 1, c + 2), &m(r + 1, c + 3),
3330 &m(r + 1, c + 4), &m(r + 1, c + 5),
3331
3332 &m(r + 2, c + 0), &m(r + 2, c + 1), &m(r + 2, c + 2), &m(r + 2, c + 3),
3333 &m(r + 2, c + 4), &m(r + 2, c + 5)
3334
3335 };
3336 };
3337
3340
3341 auto v = getVolume();
3342 auto t_w = getFTensor0IntegrationWeight();
3343 auto t_levi_kirchhoff_du =
3344 dataAtPts->getFTensorLeviKirchhoffdLogStretch(nb_integration_pts);
3345 auto t_plasticF = dataAtPts->getFTensorPlasticF(nb_integration_pts);
3346 int row_nb_base_functions = row_data.getN().size2();
3347 auto t_row_base_fun = row_data.getFTensor0N();
3348 for (int gg = 0; gg != nb_integration_pts; ++gg) {
3349 const double det_plasticF = determinantTensor3by3(t_plasticF);
3350 double a = v * t_w * det_plasticF;
3351 int rr = 0;
3352 for (; rr != row_nb_dofs / 3; ++rr) {
3353 auto t_m = get_ftensor2(K, 3 * rr, 0);
3354 const double b = a * t_row_base_fun;
3355 auto t_col_base_fun = col_data.getFTensor0N(gg, 0);
3356 for (int cc = 0; cc != col_nb_dofs / size_symm; ++cc) {
3357 t_m(k, L) -= (b * t_col_base_fun) * t_levi_kirchhoff_du(k, L);
3358 ++t_m;
3359 ++t_col_base_fun;
3360 }
3361 ++t_row_base_fun;
3362 }
3363 for (; rr != row_nb_base_functions; ++rr) {
3364 ++t_row_base_fun;
3365 }
3366 ++t_w;
3367 ++t_levi_kirchhoff_du;
3368 ++t_plasticF;
3369 }
3371}
3372
3374 EntData &col_data) {
3376
3383
3384 int nb_integration_pts = getGaussPts().size2();
3385 int row_nb_dofs = row_data.getIndices().size();
3386 int col_nb_dofs = col_data.getIndices().size();
3387 auto get_ftensor2 = [](MatrixDouble &m, const int r, const int c) {
3389
3390 &m(r + 0, c + 0), &m(r + 0, c + 1), &m(r + 0, c + 2),
3391
3392 &m(r + 1, c + 0), &m(r + 1, c + 1), &m(r + 1, c + 2),
3393
3394 &m(r + 2, c + 0), &m(r + 2, c + 1), &m(r + 2, c + 2)
3395
3396 );
3397 };
3398
3399 auto v = getVolume();
3400 auto t_w = getFTensor0IntegrationWeight();
3401
3402 int row_nb_base_functions = row_data.getN().size2();
3403 auto t_row_base_fun = row_data.getFTensor0N();
3404 auto t_levi_kirchhoff_dP =
3405 dataAtPts->getFTensorLeviKirchhoffP(nb_integration_pts);
3406 auto t_plasticF = dataAtPts->getFTensorPlasticF(nb_integration_pts);
3407
3408 for (int gg = 0; gg != nb_integration_pts; ++gg) {
3409 const double det_plasticF = determinantTensor3by3(t_plasticF);
3410 double a = v * t_w * det_plasticF;
3411 int rr = 0;
3412 for (; rr != row_nb_dofs / 3; ++rr) {
3413 double b = a * t_row_base_fun;
3414 auto t_col_base_fun = col_data.getFTensor1N<3>(gg, 0);
3415 auto t_m = get_ftensor2(K, 3 * rr, 0);
3416 for (int cc = 0; cc != col_nb_dofs / 3; ++cc) {
3417 FTensor::Tensor1<double, 3> t_col_base_piola;
3418 t_col_base_piola(k) =
3419 t_plasticF(k, l) * t_col_base_fun(l) / det_plasticF;
3420 t_m(m, i) -=
3421 b * (t_levi_kirchhoff_dP(m, i, k) * t_col_base_piola(k));
3422 ++t_m;
3423 ++t_col_base_fun;
3424 }
3425 ++t_row_base_fun;
3426 }
3427 for (; rr != row_nb_base_functions; ++rr) {
3428 ++t_row_base_fun;
3429 }
3430
3431 ++t_w;
3432 ++t_levi_kirchhoff_dP;
3433 ++t_plasticF;
3434 }
3436}
3437
3439 EntData &col_data) {
3441 int nb_integration_pts = getGaussPts().size2();
3442 int row_nb_dofs = row_data.getIndices().size();
3443 int col_nb_dofs = col_data.getIndices().size();
3444
3445 auto get_ftensor1 = [](MatrixDouble &m, const int r, const int c) {
3447 &m(r + 0, c), &m(r + 1, c), &m(r + 2, c));
3448 };
3449
3450 FTENSOR_INDEX(3, i);
3451 FTENSOR_INDEX(3, k);
3452 FTENSOR_INDEX(3, l);
3453 FTENSOR_INDEX(3, m);
3454
3455 auto v = getVolume();
3456 auto t_w = getFTensor0IntegrationWeight();
3457 auto t_levi_kirchoff_dP =
3458 dataAtPts->getFTensorLeviKirchhoffP(nb_integration_pts);
3459 auto t_plasticF = dataAtPts->getFTensorPlasticF(nb_integration_pts);
3460
3461 int row_nb_base_functions = row_data.getN().size2();
3462 auto t_row_base_fun = row_data.getFTensor0N();
3463
3464 for (int gg = 0; gg != nb_integration_pts; ++gg) {
3465 const double det_plasticF = determinantTensor3by3(t_plasticF);
3466 double a = v * t_w * det_plasticF;
3467 int rr = 0;
3468 for (; rr != row_nb_dofs / 3; ++rr) {
3469 double b = a * t_row_base_fun;
3470 auto t_col_base_fun = col_data.getFTensor2N<3, 3>(gg, 0);
3471 auto t_m = get_ftensor1(K, 3 * rr, 0);
3472 for (int cc = 0; cc != col_nb_dofs; ++cc) {
3473 FTensor::Tensor2<double, 3, 3> t_col_base_piola;
3474 t_col_base_piola(i, k) =
3475 t_col_base_fun(i, l) * t_plasticF(k, l) / det_plasticF;
3476 t_m(m) -=
3477 b * (t_levi_kirchoff_dP(m, i, k) * t_col_base_piola(i, k));
3478 ++t_m;
3479 ++t_col_base_fun;
3480 }
3481 ++t_row_base_fun;
3482 }
3483
3484 for (; rr != row_nb_base_functions; ++rr) {
3485 ++t_row_base_fun;
3486 }
3487 ++t_w;
3488 ++t_levi_kirchoff_dP;
3489 ++t_plasticF;
3490 }
3492}
3493
3495 EntData &col_data) {
3497 int nb_integration_pts = getGaussPts().size2();
3498 int row_nb_dofs = row_data.getIndices().size();
3499 int col_nb_dofs = col_data.getIndices().size();
3500 auto get_ftensor2 = [](MatrixDouble &m, const int r, const int c) {
3502
3503 &m(r + 0, c + 0), &m(r + 0, c + 1), &m(r + 0, c + 2),
3504
3505 &m(r + 1, c + 0), &m(r + 1, c + 1), &m(r + 1, c + 2),
3506
3507 &m(r + 2, c + 0), &m(r + 2, c + 1), &m(r + 2, c + 2)
3508
3509 );
3510 };
3511 FTensor::Index<'i', 3> i;
3512 FTensor::Index<'j', 3> j;
3513 FTensor::Index<'k', 3> k;
3514 FTensor::Index<'l', 3> l;
3515 FTensor::Index<'m', 3> m;
3516 FTensor::Index<'n', 3> n;
3517
3519
3520 auto v = getVolume();
3521 auto ts_a =
3522 (std::abs(alphaViscousR) > std::numeric_limits<double>::epsilon() ||
3523 std::abs(alphaViscousOmega) > std::numeric_limits<double>::epsilon())
3524 ? getTSa()
3525 : 0.0;
3526 auto t_w = getFTensor0IntegrationWeight();
3527 auto t_levi_kirchhoff_domega =
3528 dataAtPts->getFTensorLeviKirchhoffdOmega(nb_integration_pts);
3529 auto t_plasticF = dataAtPts->getFTensorPlasticF(nb_integration_pts);
3530 auto t_invPlasticF = dataAtPts->getFTensorInvPlasticF(nb_integration_pts);
3531 int row_nb_base_functions = row_data.getN().size2();
3532 auto t_row_base_fun = row_data.getFTensor0N();
3533 auto t_row_grad_fun = row_data.getFTensor1DiffN<3>();
3534
3535 // auto time_step = getTStimeStep();
3536 for (int gg = 0; gg != nb_integration_pts; ++gg) {
3537 const double det_plasticF = determinantTensor3by3(t_plasticF);
3538 double a = v * t_w * det_plasticF;
3539 double mass_coeff =
3540 a * alphaR + (a * alphaViscousR) * (ts_a /*/ time_step*/);
3541 double grad_coeff =
3542 a * alphaOmega + (a * alphaViscousOmega) * (ts_a /*/ time_step*/);
3543
3544 int rr = 0;
3545 for (; rr != row_nb_dofs / 3; ++rr) {
3546 auto t_m = get_ftensor2(K, 3 * rr, 0);
3547 const double row_mass = a * t_row_base_fun;
3548 FTensor::Tensor1<double, 3> t_row_grad_intermediate;
3549 t_row_grad_intermediate(j) =
3550 t_row_grad_fun(i) * t_invPlasticF(i, j);
3551 auto t_col_base_fun = col_data.getFTensor0N(gg, 0);
3552 auto t_col_grad_fun = col_data.getFTensor1DiffN<3>(gg, 0);
3553 for (int cc = 0; cc != col_nb_dofs / 3; ++cc) {
3554 FTensor::Tensor1<double, 3> t_col_grad_intermediate;
3555 t_col_grad_intermediate(j) =
3556 t_col_grad_fun(i) * t_invPlasticF(i, j);
3557 t_m(k, l) -=
3558 (row_mass * t_col_base_fun) * t_levi_kirchhoff_domega(k, l);
3559 t_m(k, l) +=
3560 t_kd(k, l) * (mass_coeff * t_row_base_fun * t_col_base_fun);
3561 t_m(k, l) +=
3562 t_kd(k, l) *
3563 (grad_coeff *
3564 (t_row_grad_intermediate(j) * t_col_grad_intermediate(j)));
3565 ++t_m;
3566 ++t_col_base_fun;
3567 ++t_col_grad_fun;
3568 }
3569 ++t_row_base_fun;
3570 ++t_row_grad_fun;
3571 }
3572 for (; rr != row_nb_base_functions; ++rr) {
3573 ++t_row_base_fun;
3574 ++t_row_grad_fun;
3575 }
3576 ++t_w;
3577 ++t_levi_kirchhoff_domega;
3578 ++t_plasticF;
3579 ++t_invPlasticF;
3580 }
3582}
3583
3584template <typename TInvD, typename TRotation>
3585auto getDiffSpatialGradientDP(TInvD &t_d_u_d_b, TRotation &t_R) {
3586 FTENSOR_INDEXES(SPACE_DIM, i, j, k, l, m, n);
3587 constexpr auto t_diff_sym = FTensor::DiffSymmetrize<double>();
3588
3590 t_d_b_d_p;
3591 t_d_b_d_p(i, j, k, l) = t_diff_sym(i, j, m, l) * t_R(k, m);
3592
3594 t_d_u_d_p;
3595 t_d_u_d_p(i, j, k, l) =
3596 t_d_u_d_b(i, j, m, n) * t_d_b_d_p(m, n, k, l);
3597
3599 t_d_h_d_p;
3600 t_d_h_d_p(i, j, k, l) = t_R(i, m) * t_d_u_d_p(m, j, k, l);
3601 return t_d_h_d_p;
3602}
3603
3605 EntData &col_data) {
3608 dataAtPts->physicsPtr->getFeatures().test(
3609 PhysicalEquations::NO_STRETCH_NONLINEAR)) {
3611 integrateImpl<size_symm * size_symm>(row_data, col_data));
3612 } else {
3613 MoFEMFunctionReturnHot(integrateImpl<0>(row_data, col_data));
3614 }
3616};
3617
3618template <int S>
3620 EntData &col_data) {
3622
3623 auto get_ftensor2 = [](MatrixDouble &m, const int r, const int c) {
3625
3626 &m(r + 0, c + 0), &m(r + 0, c + 1), &m(r + 0, c + 2),
3627
3628 &m(r + 1, c + 0), &m(r + 1, c + 1), &m(r + 1, c + 2),
3629
3630 &m(r + 2, c + 0), &m(r + 2, c + 1), &m(r + 2, c + 2)
3631
3632 );
3633 };
3634
3635 int nb_integration_pts = getGaussPts().size2();
3636 int row_nb_dofs = row_data.getIndices().size();
3637 int col_nb_dofs = col_data.getIndices().size();
3638
3639 auto v = getVolume();
3640 auto t_w = getFTensor0IntegrationWeight();
3641 int row_nb_base_functions = row_data.getN().size2() / 3;
3642
3649
3650 auto t_inv_D =
3651 getFTensor4DdgFromMat<SPACE_DIM, SPACE_DIM, S>(dataAtPts->matInvD);
3652 auto t_R = dataAtPts->getFTensorRotMat(nb_integration_pts);
3653 auto t_plasticF = dataAtPts->getFTensorPlasticF(nb_integration_pts);
3654
3655 auto t_row_base = row_data.getFTensor1N<3>();
3656 for (int gg = 0; gg != nb_integration_pts; ++gg) {
3657 const double det_plasticF = determinantTensor3by3(t_plasticF);
3658 double a = v * t_w * det_plasticF;
3659
3660 auto assemble = [&](auto &t_diff_h_p) {
3661 int rr = 0;
3662 for (; rr != row_nb_dofs / 3; ++rr) {
3663 FTensor::Tensor1<double, 3> t_row_base_piola;
3664 t_row_base_piola(j) =
3665 t_plasticF(j, m) * t_row_base(m) / det_plasticF;
3666 auto t_col_base = col_data.getFTensor1N<3>(gg, 0);
3667 auto t_m = get_ftensor2(K, 3 * rr, 0);
3668 for (int cc = 0; cc != col_nb_dofs / 3; ++cc) {
3669 FTensor::Tensor1<double, 3> t_col_base_piola;
3670 t_col_base_piola(l) =
3671 t_plasticF(l, n) * t_col_base(n) / det_plasticF;
3672 t_m(i, k) -= a * t_row_base_piola(j) *
3673 (t_diff_h_p(i, j, k, l) * t_col_base_piola(l));
3674 ++t_m;
3675 ++t_col_base;
3676 }
3677
3678 ++t_row_base;
3679 }
3680
3681 for (; rr != row_nb_base_functions; ++rr)
3682 ++t_row_base;
3683 };
3684
3685 if (dataAtPts->physicsPtr->getFeatures().test(
3686 PhysicalEquations::NO_STRETCH_NONLINEAR)) {
3687 auto t_diff_h_p = getDiffSpatialGradientDP(t_inv_D, t_R);
3688 assemble(t_diff_h_p);
3689 } else {
3690 assemble(t_inv_D);
3691 }
3692
3693 ++t_w;
3694 ++t_inv_D;
3695 ++t_R;
3696 ++t_plasticF;
3697 }
3699}
3700
3703 EntData &col_data) {
3706 dataAtPts->physicsPtr->getFeatures().test(
3707 PhysicalEquations::NO_STRETCH_NONLINEAR)) {
3709 integrateImpl<size_symm * size_symm>(row_data, col_data));
3710 } else {
3711 MoFEMFunctionReturnHot(integrateImpl<0>(row_data, col_data));
3712 }
3714};
3715
3716template <int S>
3719 EntData &col_data) {
3721
3722 int nb_integration_pts = getGaussPts().size2();
3723 int row_nb_dofs = row_data.getIndices().size();
3724 int col_nb_dofs = col_data.getIndices().size();
3725
3726 auto v = getVolume();
3727 auto t_w = getFTensor0IntegrationWeight();
3728 int row_nb_base_functions = row_data.getN().size2() / 9;
3729
3736
3737 auto t_inv_D =
3738 getFTensor4DdgFromMat<SPACE_DIM, SPACE_DIM, S>(dataAtPts->matInvD);
3739 auto t_R = dataAtPts->getFTensorRotMat(nb_integration_pts);
3740 auto t_plasticF = dataAtPts->getFTensorPlasticF(nb_integration_pts);
3741
3742 auto t_row_base = row_data.getFTensor2N<3, 3>();
3743 for (int gg = 0; gg != nb_integration_pts; ++gg) {
3744 const double det_plasticF = determinantTensor3by3(t_plasticF);
3745 double a = v * t_w * det_plasticF;
3746
3747 auto assemble = [&](auto &t_diff_h_p) {
3748 int rr = 0;
3749 for (; rr != row_nb_dofs; ++rr) {
3750 FTensor::Tensor2<double, 3, 3> t_row_base_piola;
3751 t_row_base_piola(i, j) =
3752 t_row_base(i, m) * t_plasticF(j, m) / det_plasticF;
3753 auto t_col_base = col_data.getFTensor2N<3, 3>(gg, 0);
3754 for (int cc = 0; cc != col_nb_dofs; ++cc) {
3755 FTensor::Tensor2<double, 3, 3> t_col_base_piola;
3756 t_col_base_piola(k, l) =
3757 t_col_base(k, n) * t_plasticF(l, n) / det_plasticF;
3758 K(rr, cc) -=
3759 a * (t_row_base_piola(i, j) *
3760 (t_diff_h_p(i, j, k, l) * t_col_base_piola(k, l)));
3761 ++t_col_base;
3762 }
3763
3764 ++t_row_base;
3765 }
3766
3767 for (; rr != row_nb_base_functions; ++rr)
3768 ++t_row_base;
3769 };
3770
3771 if (dataAtPts->physicsPtr->getFeatures().test(
3772 PhysicalEquations::NO_STRETCH_NONLINEAR)) {
3773 auto t_diff_h_p = getDiffSpatialGradientDP(t_inv_D, t_R);
3774 assemble(t_diff_h_p);
3775 } else {
3776 assemble(t_inv_D);
3777 }
3778
3779 ++t_w;
3780 ++t_inv_D;
3781 ++t_R;
3782 ++t_plasticF;
3783 }
3785}
3786
3788 EntData &col_data) {
3791 dataAtPts->physicsPtr->getFeatures().test(
3792 PhysicalEquations::NO_STRETCH_NONLINEAR)) {
3794 integrateImpl<size_symm * size_symm>(row_data, col_data));
3795 } else {
3796 MoFEMFunctionReturnHot(integrateImpl<0>(row_data, col_data));
3797 }
3799};
3800
3801template <int S>
3804 EntData &col_data) {
3806
3807 auto get_ftensor1 = [](MatrixDouble &m, const int r, const int c) {
3809
3810 &m(r + 0, c + 0), &m(r + 0, c + 1), &m(r + 0, c + 2)
3811
3812 );
3813 };
3814
3815 int nb_integration_pts = getGaussPts().size2();
3816 int row_nb_dofs = row_data.getIndices().size();
3817 int col_nb_dofs = col_data.getIndices().size();
3818
3819 auto v = getVolume();
3820 auto t_w = getFTensor0IntegrationWeight();
3821 int row_nb_base_functions = row_data.getN().size2() / 9;
3822
3829
3830 auto t_inv_D =
3831 getFTensor4DdgFromMat<SPACE_DIM, SPACE_DIM, S>(dataAtPts->matInvD);
3832 auto t_R = dataAtPts->getFTensorRotMat(nb_integration_pts);
3833 auto t_plasticF = dataAtPts->getFTensorPlasticF(nb_integration_pts);
3834
3835 auto t_row_base = row_data.getFTensor2N<3, 3>();
3836 for (int gg = 0; gg != nb_integration_pts; ++gg) {
3837 const double det_plasticF = determinantTensor3by3(t_plasticF);
3838 double a = v * t_w * det_plasticF;
3839
3840 auto assemble = [&](auto &t_diff_h_p) {
3841 auto t_m = get_ftensor1(K, 0, 0);
3842 int rr = 0;
3843 for (; rr != row_nb_dofs; ++rr) {
3844 FTensor::Tensor2<double, 3, 3> t_row_base_piola;
3845 t_row_base_piola(i, j) =
3846 t_row_base(i, m) * t_plasticF(j, m) / det_plasticF;
3847 auto t_col_base = col_data.getFTensor1N<3>(gg, 0);
3848 for (int cc = 0; cc != col_nb_dofs / 3; ++cc) {
3849 FTensor::Tensor1<double, 3> t_col_base_piola;
3850 t_col_base_piola(l) =
3851 t_plasticF(l, n) * t_col_base(n) / det_plasticF;
3852 t_m(k) -=
3853 a * (t_row_base_piola(i, j) * t_diff_h_p(i, j, k, l)) *
3854 t_col_base_piola(l);
3855 ++t_col_base;
3856 ++t_m;
3857 }
3858
3859 ++t_row_base;
3860 }
3861
3862 for (; rr != row_nb_base_functions; ++rr)
3863 ++t_row_base;
3864 };
3865
3866 if (dataAtPts->physicsPtr->getFeatures().test(
3867 PhysicalEquations::NO_STRETCH_NONLINEAR)) {
3868 auto t_diff_h_p = getDiffSpatialGradientDP(t_inv_D, t_R);
3869 assemble(t_diff_h_p);
3870 } else {
3871 assemble(t_inv_D);
3872 }
3873
3874 ++t_w;
3875 ++t_inv_D;
3876 ++t_R;
3877 ++t_plasticF;
3878 }
3880}
3881
3883 EntData &col_data) {
3885
3886 auto get_ftensor1 = [](MatrixDouble &m, const int r, const int c) {
3888
3889 &m(r + 0, c + 0), &m(r + 0, c + 1), &m(r + 0, c + 2)
3890
3891 );
3892 };
3893
3894 int nb_integration_pts = getGaussPts().size2();
3895 int row_nb_dofs = row_data.getIndices().size();
3896 int col_nb_dofs = col_data.getIndices().size();
3897
3898 auto v = getVolume();
3899 auto t_w = getFTensor0IntegrationWeight();
3900 int row_nb_base_functions = row_data.getN().size2() / 9;
3901
3904
3905 auto t_row_base = row_data.getFTensor2N<3, 3>();
3906 for (int gg = 0; gg != nb_integration_pts; ++gg) {
3907 double a = v * t_w;
3908
3909 auto t_m = get_ftensor1(K, 0, 0);
3910
3911 int rr = 0;
3912 for (; rr != row_nb_dofs; ++rr) {
3913 auto t_col_base = col_data.getFTensor1N<3>(gg, 0);
3914 for (int cc = 0; cc != col_nb_dofs / 3; ++cc) {
3915 t_m(k) += a * t_row_base(k, l) * t_col_base(l);
3916 ++t_col_base;
3917 ++t_m;
3918 }
3919
3920 ++t_row_base;
3921 }
3922
3923 for (; rr != row_nb_base_functions; ++rr)
3924 ++t_row_base;
3925 ++t_w;
3926 }
3927
3929}
3930
3932 EntData &col_data) {
3934
3941
3942 int nb_integration_pts = row_data.getN().size1();
3943 int row_nb_dofs = row_data.getIndices().size();
3944 int col_nb_dofs = col_data.getIndices().size();
3945
3946 auto get_ftensor2 = [](MatrixDouble &m, const int r, const int c) {
3948
3949 &m(r + 0, c + 0), &m(r + 0, c + 1), &m(r + 0, c + 2),
3950
3951 &m(r + 1, c + 0), &m(r + 1, c + 1), &m(r + 1, c + 2),
3952
3953 &m(r + 2, c + 0), &m(r + 2, c + 1), &m(r + 2, c + 2)
3954
3955 );
3956 };
3957
3958 auto v = getVolume();
3959 auto t_w = getFTensor0IntegrationWeight();
3960 int row_nb_base_functions = row_data.getN().size2() / 3;
3961 auto t_row_base_fun = row_data.getFTensor1N<3>();
3962
3963 auto t_h_domega = dataAtPts->getFTensorSmallHdOmega(nb_integration_pts);
3964 auto t_plasticF = dataAtPts->getFTensorPlasticF(nb_integration_pts);
3965
3966 for (int gg = 0; gg != nb_integration_pts; ++gg) {
3967 const double det_plasticF = determinantTensor3by3(t_plasticF);
3968 double a = v * t_w * det_plasticF;
3969
3970 int rr = 0;
3971 for (; rr != row_nb_dofs / 3; ++rr) {
3972
3973 FTensor::Tensor1<double, 3> t_row_base_piola;
3974 t_row_base_piola(j) =
3975 t_plasticF(j, m) * t_row_base_fun(m) / det_plasticF;
3977 t_PRT(i, k) = t_row_base_piola(j) * t_h_domega(i, j, k);
3978
3979 auto t_col_base_fun = col_data.getFTensor0N(gg, 0);
3980 auto t_m = get_ftensor2(K, 3 * rr, 0);
3981 for (int cc = 0; cc != col_nb_dofs / 3; ++cc) {
3982 t_m(i, j) -= (a * t_col_base_fun) * t_PRT(i, j);
3983 ++t_m;
3984 ++t_col_base_fun;
3985 }
3986
3987 ++t_row_base_fun;
3988 }
3989
3990 for (; rr != row_nb_base_functions; ++rr)
3991 ++t_row_base_fun;
3992 ++t_w;
3993 ++t_h_domega;
3994 ++t_plasticF;
3995 }
3997}
3998
4001 EntData &col_data) {
4003
4010
4011 int nb_integration_pts = row_data.getN().size1();
4012 int row_nb_dofs = row_data.getIndices().size();
4013 int col_nb_dofs = col_data.getIndices().size();
4014
4015 auto get_ftensor2 = [](MatrixDouble &m, const int r, const int c) {
4017 &m(r, c + 0), &m(r, c + 1), &m(r, c + 2));
4018 };
4019
4020 auto v = getVolume();
4021 auto t_w = getFTensor0IntegrationWeight();
4022 int row_nb_base_functions = row_data.getN().size2() / 9;
4023 auto t_row_base_fun = row_data.getFTensor2N<3, 3>();
4024
4025 auto t_h_domega = dataAtPts->getFTensorSmallHdOmega(nb_integration_pts);
4026 auto t_plasticF = dataAtPts->getFTensorPlasticF(nb_integration_pts);
4027 for (int gg = 0; gg != nb_integration_pts; ++gg) {
4028 const double det_plasticF = determinantTensor3by3(t_plasticF);
4029 double a = v * t_w * det_plasticF;
4030
4031 int rr = 0;
4032 for (; rr != row_nb_dofs; ++rr) {
4033
4034 FTensor::Tensor2<double, 3, 3> t_row_base_piola;
4035 t_row_base_piola(i, j) =
4036 t_row_base_fun(i, m) * t_plasticF(j, m) / det_plasticF;
4038 t_PRT(k) = t_row_base_piola(i, j) * t_h_domega(i, j, k);
4039
4040 auto t_col_base_fun = col_data.getFTensor0N(gg, 0);
4041 auto t_m = get_ftensor2(K, rr, 0);
4042 for (int cc = 0; cc != col_nb_dofs / 3; ++cc) {
4043 t_m(j) -= (a * t_col_base_fun) * t_PRT(j);
4044 ++t_m;
4045 ++t_col_base_fun;
4046 }
4047
4048 ++t_row_base_fun;
4049 }
4050
4051 for (; rr != row_nb_base_functions; ++rr)
4052 ++t_row_base_fun;
4053
4054 ++t_w;
4055 ++t_h_domega;
4056 ++t_plasticF;
4057 }
4059}
4060
4062 EntData &data) {
4064
4065 if (tagSense != getSkeletonSense())
4067
4068 auto create_tag = [this](const std::string tag_name, const int size) {
4069 double def_VAL[] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
4070 Tag th;
4071 CHKERR postProcMesh.tag_get_handle(tag_name.c_str(), size, MB_TYPE_DOUBLE,
4072 th, MB_TAG_CREAT | MB_TAG_SPARSE,
4073 def_VAL);
4074 return th;
4075 };
4076
4077 Tag th_cauchy_streess = create_tag("CauchyStress", 9);
4078 Tag th_detF = create_tag("detF", 1);
4079 Tag th_traction = create_tag("traction", 3);
4080 Tag th_disp_error = create_tag("DisplacementError", 1);
4081
4082 Tag th_energy = create_tag("Energy", 1);
4083 Tag th_young_modulus = create_tag("YoungModulus", 1);
4084
4085 const auto nb_gauss_pts = getGaussPts().size2();
4086 auto t_w = dataAtPts->getFTensorSmallWL2(nb_gauss_pts);
4087 auto t_h = dataAtPts->getFTensorSmallH(nb_gauss_pts);
4088 auto t_approx_P = dataAtPts->getFTensorApproxP(nb_gauss_pts);
4089
4090 auto t_normal = getFTensor1NormalsAtGaussPts();
4091 auto t_disp = dataAtPts->getFTensorSmallWH1(nb_gauss_pts);
4092
4093 // auto sense = getSkeletonSense();
4094
4095 if (dataAtPts->energyAtPts.size() == 0) {
4096 // that is for case that energy is not calculated
4097 dataAtPts->energyAtPts.resize(nb_gauss_pts);
4098 dataAtPts->energyAtPts.clear();
4099 }
4100 auto t_energy = getFTensor0FromVec(dataAtPts->energyAtPts);
4101 std::optional<decltype(getFTensor0FromVec(dataAtPts->youngModulusAtPts))>
4102 t_youngs_modulus;
4103 if (dataAtPts->physicsPtr->getFeatures().test(
4104 PhysicalEquations::NON_HOMOGENEOUS_MATERIAL)) {
4105 if (dataAtPts->youngModulusAtPts.size() != nb_gauss_pts)
4106 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
4107 "Young's modulus postprocessing requires current material data");
4108 t_youngs_modulus.emplace(
4109 getFTensor0FromVec(dataAtPts->youngModulusAtPts));
4110 }
4111
4112 auto next = [&]() {
4113 ++t_w;
4114 ++t_h;
4115 ++t_approx_P;
4116 ++t_normal;
4117 ++t_disp;
4118 if (t_youngs_modulus)
4119 ++*t_youngs_modulus;
4120 ++t_energy;
4121 };
4122
4123 FTensor::Index<'i', 3> i;
4124 FTensor::Index<'j', 3> j;
4125 FTensor::Index<'k', 3> k;
4126 FTensor::Index<'l', 3> l;
4127
4128 auto set_float_precision = [](const double x) {
4129 if (std::abs(x) < std::numeric_limits<float>::epsilon())
4130 return 0.;
4131 else
4132 return x;
4133 };
4134
4135 // scalars
4136 auto save_scal_tag = [&](auto &th, auto v, const int gg) {
4138 v = set_float_precision(v);
4139 CHKERR postProcMesh.tag_set_data(th, &mapGaussPts[gg], 1, &v);
4141 };
4142
4143 // vectors
4144 VectorDouble3 v(3);
4145 FTensor::Tensor1<FTensor::PackPtr<double *, 0>, 3> t_v(&v[0], &v[1], &v[2]);
4146 auto save_vec_tag = [&](auto &th, auto &t_d, const int gg) {
4148 t_v(i) = t_d(i);
4149 for (auto &a : v.data())
4150 a = set_float_precision(a);
4151 CHKERR postProcMesh.tag_set_data(th, &mapGaussPts[gg], 1,
4152 &*v.data().begin());
4154 };
4155
4156 // tensors
4157
4158 MatrixDouble3by3 m(3, 3);
4160 &m(0, 0), &m(0, 1), &m(0, 2),
4161
4162 &m(1, 0), &m(1, 1), &m(1, 2),
4163
4164 &m(2, 0), &m(2, 1), &m(2, 2));
4165
4166 auto save_mat_tag = [&](auto &th, auto &t_d, const int gg) {
4168 t_m(i, j) = t_d(i, j);
4169 for (auto &v : m.data())
4170 v = set_float_precision(v);
4171 CHKERR postProcMesh.tag_set_data(th, &mapGaussPts[gg], 1,
4172 &*m.data().begin());
4174 };
4175
4176 for (auto gg = 0; gg != nb_gauss_pts; ++gg) {
4177
4178 FTensor::Tensor1<double, 3> t_traction;
4179 t_traction(i) = t_approx_P(i, j) * t_normal(j) / t_normal.l2();
4180 // vectors
4181 t_traction(i) *= tagSense;
4182 CHKERR save_vec_tag(th_traction, t_traction, gg);
4183
4184 double u_error = sqrt((t_disp(i) - t_w(i)) * (t_disp(i) - t_w(i)));
4185 if (!std::isfinite(u_error))
4186 u_error = -1.;
4187 CHKERR save_scal_tag(th_disp_error, u_error, gg);
4188 CHKERR save_scal_tag(th_energy, t_energy, gg);
4189 if (t_youngs_modulus)
4190 CHKERR save_scal_tag(th_young_modulus, *t_youngs_modulus, gg);
4191
4192 const double jac = determinantTensor3by3(t_h);
4194 t_cauchy(i, j) = (1. / jac) * (t_approx_P(i, k) * t_h(j, k));
4195 CHKERR save_mat_tag(th_cauchy_streess, t_cauchy, gg);
4196 CHKERR postProcMesh.tag_set_data(th_detF, &mapGaussPts[gg], 1, &jac);
4197
4198 next();
4199 }
4200
4202}
4203
4205 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pipeline,
4206 std::vector<FieldSpace> spaces, std::string geom_field_name,
4207 boost::shared_ptr<Range> crack_front_edges_ptr) {
4209
4210 constexpr bool scale_l2 = false;
4211
4212 if (scale_l2) {
4213 SETERRQ(PETSC_COMM_WORLD, MOFEM_NOT_IMPLEMENTED,
4214 "Scale L2 Ainsworth Legendre base is not implemented");
4215 }
4216
4217 CHKERR MoFEM::AddHOOps<2, 3, 3>::add(pipeline, spaces, geom_field_name);
4218
4220}
4221
4223 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pipeline,
4224 std::vector<FieldSpace> spaces, std::string geom_field_name,
4225 boost::shared_ptr<Range> crack_front_edges_ptr) {
4227
4228 constexpr bool scale_l2 = false;
4229
4230 if (scale_l2) {
4231 SETERRQ(PETSC_COMM_WORLD, MOFEM_NOT_IMPLEMENTED,
4232 "Scale L2 Ainsworth Legendre base is not implemented");
4233 }
4234
4235 CHKERR MoFEM::AddHOOps<2, 2, 3>::add(pipeline, spaces, geom_field_name);
4236
4238}
4239
4241 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pipeline,
4242 std::vector<FieldSpace> spaces, std::string geom_field_name,
4243 boost::shared_ptr<Range> crack_front_edges_ptr,
4244 boost::shared_ptr<MatrixDouble> jac, boost::shared_ptr<VectorDouble> det,
4245 boost::shared_ptr<MatrixDouble> inv_jac) {
4247
4248 if (!geom_field_name.empty()) {
4250 auto jac = boost::make_shared<MatrixDouble>();
4251 auto det = boost::make_shared<VectorDouble>();
4252 pipeline.push_back(
4254 geom_field_name, jac));
4255 pipeline.push_back(new OpInvertMatrix<3>(jac, det, nullptr));
4256 pipeline.push_back(
4258 }
4259 }
4260
4261 constexpr bool scale_l2_ainsworth_legendre_base = false;
4262
4263 if (scale_l2_ainsworth_legendre_base) {
4264
4266 : public MoFEM::OpCalculateVectorFieldGradient<SPACE_DIM, SPACE_DIM> {
4267
4269
4270 OpCalculateVectorFieldGradient(const std::string &field_name,
4271 boost::shared_ptr<MatrixDouble> jac,
4272 boost::shared_ptr<Range> edges_ptr)
4273 : OP(field_name, jac), edgesPtr(edges_ptr) {}
4274
4275 MoFEMErrorCode doWork(int side, EntityType type, EntData &data) {
4276
4277 auto ent = data.getFieldEntities().size()
4278 ? data.getFieldEntities()[0]->getEnt()
4279 : 0;
4280
4281 if (type == MBEDGE && edgesPtr->find(ent) != edgesPtr->end()) {
4282 return 0;
4283 } else {
4284 return OP::doWork(side, type, data);
4285 }
4286 };
4287
4288 private:
4289 boost::shared_ptr<Range> edgesPtr;
4290 };
4291
4292 if (!geom_field_name.empty()) {
4293 auto jac = boost::make_shared<MatrixDouble>();
4294 auto det = boost::make_shared<VectorDouble>();
4295 pipeline.push_back(new OpCalculateVectorFieldGradient(
4296 geom_field_name, jac,
4297 EshelbianCore::setSingularity ? crack_front_edges_ptr
4298 : boost::make_shared<Range>()));
4299 pipeline.push_back(new OpInvertMatrix<3>(jac, det, nullptr));
4300 pipeline.push_back(new OpScaleBaseBySpaceInverseOfMeasure(
4302 }
4303 }
4304
4305 CHKERR MoFEM::AddHOOps<3, 3, 3>::add(pipeline, spaces, geom_field_name, jac,
4306 det, inv_jac);
4307
4309}
4310
4311/**
4312 * @brief Caluclate face material force and normal pressure at gauss points
4313 *
4314 * @param side
4315 * @param type
4316 * @param data
4317 * @return MoFEMErrorCode
4318 *
4319 * Reconstruct the full gradient \f$U=\nabla u\f$ on a surface from the
4320 * symmetric part and the surface gradient.
4321 *
4322 * @details
4323 * Inputs:
4324 * - \c t_strain : \f$\varepsilon=\tfrac12(U+U^\top)\f$ (symmetric strain on
4325 * S),
4326 * - \c t_grad_u_gamma : \f$u^\Gamma = U P\f$ (right-projected/surface
4327 * gradient), with \f$P=I-\mathbf N\otimes\mathbf N\f$,
4328 * - \c t_normal : (possibly non‑unit) surface normal.
4329 *
4330 * Procedure (pointwise on S):
4331 * 1) Normalize the normal \f$\mathbf n=\mathbf N/\|\mathbf N\|\f$.
4332 * 2) Form the residual \f$R=\varepsilon-\operatorname{sym}(u^\Gamma)\f$, where
4333 * \f$\operatorname{sym}(A)=\tfrac12(A+A^\top)\f$.
4334 * 3) Recover the normal directional derivative (a vector)
4335 * \f$\mathbf v=\partial_{\mathbf n}u=2R\mathbf n-(\mathbf n^\top R\,\mathbf
4336 * n)\,\mathbf n\f$. 4) Assemble the full gradient \f$U = u^\Gamma + \mathbf
4337 * v\otimes \mathbf n\f$.
4338 *
4339 * Properties (sanity checks):
4340 * - \f$\tfrac12(U+U^\top)=\varepsilon\f$ (matches the given symmetric part),
4341 * - \f$U P = u^\Gamma\f$ (tangential/right-projected columns unchanged),
4342 * - Only the **normal column** is updated via \f$\mathbf v\otimes\mathbf n\f$.
4343 *
4344 * Mapping to variables in this snippet:
4345 * - \f$\varepsilon \leftrightarrow\f$ \c t_strain,
4346 * - \f$u^\Gamma \leftrightarrow\f$ \c t_grad_u_gamma,
4347 * - \f$\mathbf N \leftrightarrow\f$ \c t_normal (normalized into \c t_N),
4348 * - \f$R \leftrightarrow\f$ \c t_R,
4349 * - \f$U \leftrightarrow\f$ \c t_grad_u.
4350 *
4351 * @pre \c t_normal is nonzero; \c t_strain is symmetric.
4352 * @note All indices use Einstein summation; computation is local to the surface
4353 * point.
4354 *
4355 */
4357 EntData &data) {
4359
4372
4373 const auto nb_gauss_pts = getGaussPts().size2();
4375 dataAtPts->faceMaterialForceAtPts, nb_gauss_pts);
4376 dataAtPts->normalPressureAtPts.resize(nb_gauss_pts, false);
4377 if (getNinTheLoop() == 0) {
4378 dataAtPts->faceMaterialForceAtPts.clear();
4379 dataAtPts->normalPressureAtPts.clear();
4380 }
4381 auto loop_size = getLoopSize();
4382 if (loop_size == 1) {
4383 auto numebered_fe_ptr = getSidePtrFE()->numeredEntFiniteElementPtr;
4384 auto pstatus = numebered_fe_ptr->getPStatus();
4385 if (pstatus & (PSTATUS_SHARED | PSTATUS_MULTISHARED)) {
4386 loop_size = 2;
4387 }
4388 }
4389
4391
4392 auto t_normal = getFTensor1NormalsAtGaussPts();
4393 auto t_T = dataAtPts->getFTensorFaceMaterialForce(
4394 nb_gauss_pts); //< face material force
4395 auto t_p =
4396 getFTensor0FromVec(dataAtPts->normalPressureAtPts); //< normal pressure
4397 auto t_P = dataAtPts->getFTensorApproxP(nb_gauss_pts);
4398 auto t_u_gamma = dataAtPts->getFTensorSmallHybridDisp(nb_gauss_pts);
4399 auto t_grad_u_gamma = dataAtPts->getFTensorGradHybridDisp(nb_gauss_pts);
4400 auto t_strain = dataAtPts->getFTensorLogStretch(nb_gauss_pts);
4401 auto t_omega = dataAtPts->getFTensorRotAxis(nb_gauss_pts);
4402
4408
4409 auto next = [&]() {
4410 ++t_normal;
4411 ++t_P;
4412 // ++t_grad_P;
4413 ++t_omega;
4414 ++t_u_gamma;
4415 ++t_grad_u_gamma;
4416 ++t_strain;
4417 ++t_T;
4418 ++t_p;
4419 };
4420
4422 case GRIFFITH_FORCE:
4423 for (auto gg = 0; gg != getGaussPts().size2(); ++gg) {
4424 t_N(I) = t_normal(I);
4425 t_N.normalize();
4426
4427 t_A(i, j) = levi_civita(i, j, k) * t_omega(k);
4428 t_R(i, k) = t_kd(i, k) + t_A(i, k);
4429 t_grad_u(i, j) = t_R(i, j) + t_strain(i, j);
4430
4431 t_T(I) += t_N(J) * (t_grad_u(i, I) * t_P(i, J)) / loop_size;
4432 // note that works only for Hooke material, for nonlinear material we need
4433 // strain energy expressed by stress
4434 t_T(I) -= t_N(I) * ((t_strain(i, K) * t_P(i, K)) / 2.) / loop_size;
4435
4436 t_p += t_N(I) *
4437 (t_N(J) * ((t_kd(i, I) + t_grad_u_gamma(i, I)) * t_P(i, J))) /
4438 loop_size;
4439
4440 next();
4441 }
4442 break;
4443 case GRIFFITH_SKELETON:
4444 for (auto gg = 0; gg != getGaussPts().size2(); ++gg) {
4445
4446 // Normalize the normal
4447 t_N(I) = t_normal(I);
4448 t_N.normalize();
4449
4450 // R = ε − sym(u^Γ)
4451 t_R(i, j) =
4452 t_strain(i, j) - 0.5 * (t_grad_u_gamma(i, j) + t_grad_u_gamma(j, i));
4453
4454 // U = u^Γ + [2 R N − (Nᵀ R N) N] ⊗ N
4455 t_grad_u(i, J) =
4456 t_grad_u_gamma(i, J) +
4457 (2 * t_R(i, K) * t_N(K) - (t_R(k, L) * t_N(k) * t_N(L)) * t_N(i)) *
4458 t_N(J);
4459
4460 t_T(I) += t_N(J) * (t_grad_u(i, I) * t_P(i, J)) / loop_size;
4461 // note that works only for Hooke material, for nonlinear material we need
4462 // strain energy expressed by stress
4463 t_T(I) -= t_N(I) * ((t_strain(i, K) * t_P(i, K)) / 2.) / loop_size;
4464
4465 // calculate nominal face pressure
4466 t_p += t_N(I) *
4467 (t_N(J) * ((t_kd(i, I) + t_grad_u_gamma(i, I)) * t_P(i, J))) /
4468 loop_size;
4469
4470 next();
4471 }
4472 break;
4473
4474 default:
4475 SETERRQ(PETSC_COMM_WORLD, MOFEM_NOT_IMPLEMENTED,
4476 "Grffith energy release "
4477 "selector not implemented");
4478 };
4479
4480#ifndef NDEBUG
4481 auto side_fe_ptr = getSidePtrFE();
4482 auto side_fe_mi_ptr = side_fe_ptr->numeredEntFiniteElementPtr;
4483 auto pstatus = side_fe_mi_ptr->getPStatus();
4484 if (pstatus) {
4485 auto owner = side_fe_mi_ptr->getOwnerProc();
4486 MOFEM_LOG("SELF", Sev::noisy)
4487 << "OpFaceSideMaterialForce: owner proc is not 0, owner proc: " << owner
4488 << " " << getPtrFE()->mField.get_comm_rank() << " n in the loop "
4489 << getNinTheLoop() << " loop size " << getLoopSize();
4490 }
4491#endif // NDEBUG
4492
4494}
4495
4497 EntData &data) {
4499
4500#ifndef NDEBUG
4501 auto fe_mi_ptr = getFEMethod()->numeredEntFiniteElementPtr;
4502 auto pstatus = fe_mi_ptr->getPStatus();
4503 if (pstatus) {
4504 auto owner = fe_mi_ptr->getOwnerProc();
4505 MOFEM_LOG("SELF", Sev::noisy)
4506 << "OpFaceMaterialForce: owner proc is not 0, owner proc: " << owner
4507 << " " << getPtrFE()->mField.get_comm_rank();
4508 }
4509#endif // NDEBUG
4510
4512
4514 t_face_T(I) = 0.;
4515 double face_pressure = 0.;
4516 auto t_T = dataAtPts->getFTensorFaceMaterialForce(
4517 getGaussPts().size2()); //< face material force
4518 auto t_p =
4519 getFTensor0FromVec(dataAtPts->normalPressureAtPts); //< normal pressure
4520 auto t_w = getFTensor0IntegrationWeight();
4521 for (auto gg = 0; gg != getGaussPts().size2(); ++gg) {
4522 t_face_T(I) += t_w * t_T(I);
4523 face_pressure += t_w * t_p;
4524 ++t_w;
4525 ++t_T;
4526 ++t_p;
4527 }
4528 t_face_T(I) *= getMeasure();
4529 face_pressure *= getMeasure();
4530
4531 auto get_tag = [&](auto name, auto dim) {
4532 auto &moab = getPtrFE()->mField.get_moab();
4533 Tag tag;
4534 double def_val[] = {0., 0., 0.};
4535 CHK_MOAB_THROW(moab.tag_get_handle(name, dim, MB_TYPE_DOUBLE, tag,
4536 MB_TAG_CREAT | MB_TAG_SPARSE, def_val),
4537 "create tag");
4538 return tag;
4539 };
4540
4541 auto set_tag = [&](auto &&tag, auto ptr) {
4542 auto &moab = getPtrFE()->mField.get_moab();
4543 auto face = getPtrFE()->getFEEntityHandle();
4544 CHK_MOAB_THROW(moab.tag_set_data(tag, &face, 1, ptr), "set tag");
4545 };
4546
4547 set_tag(get_tag("MaterialForce", 3), &t_face_T(0));
4548 set_tag(get_tag("FacePressure", 1), &face_pressure);
4549
4551}
4552
4553template <typename OP_PTR>
4554std::tuple<std::string, MatrixDouble>
4556 const std::string block_name) {
4557
4558 auto nb_gauss_pts = op_ptr->getGaussPts().size2();
4559
4560 auto ts_time = op_ptr->getTStime();
4561 auto ts_time_step = op_ptr->getTStimeStep();
4562
4565 ts_time_step = EshelbianCore::physicalDt;
4566 }
4567
4568 MatrixDouble m_ref_coords = op_ptr->getCoordsAtGaussPts();
4569 MatrixDouble m_ref_normals = op_ptr->getNormalsAtGaussPts();
4570
4571 auto v_analytical_expr =
4572 analytical_expr_function(ts_time_step, ts_time, nb_gauss_pts,
4573 m_ref_coords, m_ref_normals, block_name);
4574
4575 if (PetscUnlikely(!v_analytical_expr.size2())) {
4577 "Analytical expression is empty or does not exist, "
4578 "check python file");
4579 }
4580
4581 return std::make_tuple(block_name, v_analytical_expr);
4582}
4583
4585 boost::shared_ptr<std::vector<BrokenBaseSideData>> broken_base_side_data,
4586 boost::shared_ptr<MatrixDouble> vec, ScalarFun beta_coeff,
4587 boost::shared_ptr<Range> ents_ptr)
4588 : OP(broken_base_side_data, ents_ptr) {
4589 this->sourceVec = vec;
4590 this->betaCoeff = beta_coeff;
4591}
4592
4594 boost::shared_ptr<std::vector<BrokenBaseSideData>> broken_base_side_data,
4595 ScalarFun beta_coeff, boost::shared_ptr<Range> ents_ptr)
4596 : OP(broken_base_side_data, ents_ptr) {
4597 this->sourceVec = boost::shared_ptr<MatrixDouble>();
4598 this->betaCoeff = beta_coeff;
4599}
4600
4602OpBrokenBaseTimesBrokenDisp::doWork(int row_side, EntityType row_type,
4603 EntitiesFieldData::EntData &row_data) {
4605
4606 if (OP::entsPtr) {
4607 if (OP::entsPtr->find(this->getFEEntityHandle()) == OP::entsPtr->end())
4609 }
4610
4611#ifndef NDEBUG
4612 if (!brokenBaseSideData) {
4613 SETERRQ(PETSC_COMM_SELF, MOFEM_IMPOSSIBLE_CASE, "space not set");
4614 }
4615#endif // NDEBUG
4616
4617 auto do_work_rhs = [this](int row_side, EntityType row_type,
4618 EntitiesFieldData::EntData &row_data) {
4620 // get number of dofs on row
4621 OP::nbRows = row_data.getIndices().size();
4622 if (!OP::nbRows)
4624 // get number of integration points
4625 OP::nbIntegrationPts = OP::getGaussPts().size2();
4626 // get row base functions
4627 OP::nbRowBaseFunctions = OP::getNbOfBaseFunctions(row_data);
4628 // resize and clear the right hand side vector
4629 OP::locF.resize(OP::nbRows, false);
4630 OP::locF.clear();
4631 // integrate local vector
4632 CHKERR this->iNtegrate(row_data);
4633 // assemble local vector
4634 CHKERR this->aSsemble(row_data);
4636 };
4637
4638 switch (OP::opType) {
4639 case OP::OPSPACE:
4640 for (auto &bd : *brokenBaseSideData) {
4641 this->sourceVec =
4642 boost::shared_ptr<MatrixDouble>(brokenBaseSideData, &bd.getFlux());
4643 CHKERR do_work_rhs(bd.getSide(), bd.getType(), bd.getData());
4644 this->sourceVec.reset();
4645 }
4646 break;
4647 default:
4649 (std::string("wrong op type ") +
4650 OpBaseDerivativesBase::OpTypeNames[OP::opType])
4651 .c_str());
4652 }
4653
4655}
4656
4658 const std::string row_field,
4659 boost::shared_ptr<std::vector<BrokenBaseSideData>> broken_base_side_data,
4660 ScalarFun beta_coeff, boost::shared_ptr<Range> ents_ptr)
4661 : OP(row_field, boost::shared_ptr<MatrixDouble>(), beta_coeff, ents_ptr),
4662 brokenBaseSideDataPtr(broken_base_side_data) {
4663 this->betaCoeff = beta_coeff;
4664}
4665
4669 for (auto &bd : (*brokenBaseSideDataPtr)) {
4670 this->sourceVec =
4671 boost::shared_ptr<MatrixDouble>(brokenBaseSideDataPtr, &bd.getFlux());
4672
4673#ifndef NDEBUG
4674 if (this->sourceVec->size2() != SPACE_DIM) {
4675 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
4676 "Inconsistent size of the source vector");
4677 }
4678 if (this->sourceVec->size1() != OP::getGaussPts().size2()) {
4679 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
4680 "Inconsistent size of the source vector");
4681 }
4682#endif // NDEBUG
4683
4684 CHKERR OP::iNtegrate(data);
4685
4686 this->sourceVec.reset();
4687 }
4689}
4690
4692 std::string row_field,
4693 boost::shared_ptr<std::vector<BrokenBaseSideData>> broken_base_side_data,
4694 ScalarFun beta, const bool assmb_transpose, const bool only_transpose,
4695 boost::shared_ptr<Range> ents_ptr)
4696 : OP(row_field, broken_base_side_data, assmb_transpose, only_transpose,
4697 ents_ptr) {
4698 this->betaCoeff = beta;
4699 this->sYmm = false;
4700}
4701
4703 boost::shared_ptr<std::vector<BrokenBaseSideData>> broken_base_side_data,
4704 ScalarFun beta, boost::shared_ptr<Range> ents_ptr)
4705 : OP(broken_base_side_data, ents_ptr) {
4706 this->sYmm = false;
4707 this->betaCoeff = beta;
4708 OP::assembleTranspose = false;
4709 OP::onlyTranspose = false;
4710}
4711
4713OpBrokenBaseBrokenBase::doWork(int row_side, EntityType row_type,
4714 EntitiesFieldData::EntData &row_data) {
4716
4717 if (OP::entsPtr) {
4718 if (OP::entsPtr->find(this->getFEEntityHandle()) == OP::entsPtr->end())
4720 }
4721
4722#ifndef NDEBUG
4723 if (!brokenBaseSideData) {
4724 SETERRQ(PETSC_COMM_SELF, MOFEM_IMPOSSIBLE_CASE, "space not set");
4725 }
4726#endif // NDEBUG
4727
4728 auto do_work_lhs = [this](int row_side, int col_side, EntityType row_type,
4729 EntityType col_type,
4731 EntitiesFieldData::EntData &col_data) {
4733
4734 auto check_if_assemble_transpose = [&] {
4735 if (this->sYmm) {
4736 if (OP::rowSide != OP::colSide || OP::rowType != OP::colType)
4737 return true;
4738 else
4739 return false;
4740 } else if (OP::assembleTranspose) {
4741 return true;
4742 }
4743 return false;
4744 };
4745
4746 OP::rowSide = row_side;
4747 OP::rowType = row_type;
4748 OP::colSide = col_side;
4749 OP::colType = col_type;
4750 OP::nbCols = col_data.getIndices().size();
4751 OP::locMat.resize(OP::nbRows, OP::nbCols, false);
4752 OP::locMat.clear();
4753 CHKERR this->iNtegrate(row_data, col_data);
4754 CHKERR this->aSsemble(row_data, col_data, check_if_assemble_transpose());
4756 };
4757
4758 switch (OP::opType) {
4759 case OP::OPSPACE:
4760
4761 for (auto &bd : *brokenBaseSideData) {
4762
4763#ifndef NDEBUG
4764 if (!bd.getData().getNSharedPtr(bd.getData().getBase())) {
4765 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
4766 "base functions not set");
4767 }
4768#endif
4769
4770 OP::nbRows = bd.getData().getIndices().size();
4771 if (!OP::nbRows)
4773 OP::nbIntegrationPts = OP::getGaussPts().size2();
4774 OP::nbRowBaseFunctions = OP::getNbOfBaseFunctions(bd.getData());
4775
4776 if (!OP::nbRows)
4778
4779 CHKERR do_work_lhs(
4780
4781 // side
4782 bd.getSide(), bd.getSide(),
4783
4784 // type
4785 bd.getType(), bd.getType(),
4786
4787 // row_data
4788 bd.getData(), bd.getData()
4789
4790 );
4791 }
4792
4793 break;
4794
4795 default:
4797 (std::string("wrong op type ") +
4798 OpBaseDerivativesBase::OpTypeNames[OP::opType])
4799 .c_str());
4800 }
4801
4803}
4804
4805} // namespace EshelbianPlasticity
boost::shared_ptr< DataAtIntegrationPts > dataAtPts
Auxilary functions for Eshelbian plasticity.
Eshelbian plasticity interface.
std::string type
Lie algebra implementation.
#define FTENSOR_INDEXES(DIM,...)
#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
@ H1
continuous field
Definition definitions.h:85
#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_OPERATION_UNSUCCESSFUL
Definition definitions.h:34
@ MOFEM_DATA_INCONSISTENCY
Definition definitions.h:31
@ MOFEM_INVALID_DATA
Definition definitions.h:36
@ 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
boost::function< T(const T)> Fun
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 getDiffSpatialGradientDP(TInvD &t_d_u_d_b, TRotation &t_R)
std::tuple< std::string, MatrixDouble > getAnalyticalExpr(OP_PTR op_ptr, MatrixDouble &analytical_expr, const std::string block_name)
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)
auto getDiffSpatialGradientDR(TInvD &t_d_u_d_b, TRotation &t_R, TDiffRotation &t_diff_R, TStress &t_P)
boost::shared_ptr< VectorDouble > VectorPtr
DataLayoutTraits< DataLayout::GaussByCoeffs > DL
Definition MatHuHu.hpp:33
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
double q
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 constexpr enum SymmetrySelector symmetrySelector
static boost::function< double(const double)> f
static PetscBool setSingularity
static boost::function< double(const double)> d_f
static enum EnergyReleaseSelector energyReleaseSelector
static boost::function< double(const double)> inv_f
static auto 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.
std::array< bool, MBMAXTYPE > doEntities
If true operator is executed for entity.
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.
EntityHandle getFEEntityHandle() const
Return finite element entity handle.
MatrixDouble & getCoordsAtGaussPts()
Gauss points and weight, matrix (nb. of points x 3)
auto getFTensor0IntegrationWeight()
Get integration weights.
const FEMethod * getFEMethod() const
Return raw pointer to Finite Element Method object.
MatrixDouble & getGaussPts()
matrix of integration (Gauss) points for Volume Element
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
Operator for linear form, usually to calculate values on right hand side.
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.
static constexpr Switches CtxSetTime
Time value switch.
@ CTX_TSSETIJACOBIAN
Setting up implicit Jacobian.
MoFEMErrorCode iNtegrate(EntData &data)
MatrixDouble K
local tangent matrix
VectorDouble nF
local right hand side vector
boost::shared_ptr< DataAtIntegrationPts > dataAtPts
data at integration pts
MoFEMErrorCode assemble(int row_side, int col_side, EntityType row_type, EntityType col_type, EntData &row_data, EntData &col_data)
boost::shared_ptr< AnalyticalTractionBcVec > bcData
boost::shared_ptr< double > piolaScalePtr
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 &row_data, EntData &col_data)
boost::shared_ptr< double > piolaScalePtr
MoFEMErrorCode iNtegrate(EntData &data)
std::map< std::string, boost::shared_ptr< ScalingMethod > > scalingMethodsMap
boost::shared_ptr< PressureBcVec > bcData
std::map< std::string, boost::shared_ptr< ScalingMethod > > scalingMethodsMap
boost::shared_ptr< double > piolaScalePtr
boost::shared_ptr< TractionBcVec > bcData
MoFEMErrorCode iNtegrate(EntData &data)
std::map< std::string, boost::shared_ptr< ScalingMethod > > scalingMethodsMap
MoFEMErrorCode doWork(int side, EntityType type, EntData &data) override
Operator for linear form, usually to calculate values on right hand side.
boost::shared_ptr< ExternalStrainVec > externalStrainVecPtr
OpCalculateExternalPressure(VectorPtr external_pressure_ptr, boost::shared_ptr< ExternalStrainVec > external_strain_vec_ptr, std::map< std::string, boost::shared_ptr< ScalingMethod > > smv)
boost::shared_ptr< DataAtIntegrationPts > dataAtPts
data at integration pts
MoFEMErrorCode doWork(int side, EntityType type, EntData &data)
std::array< double, 6 > & reactionVec
MoFEMErrorCode doWork(int side, EntityType type, EntData &data)
Operator for linear form, usually to calculate values on right hand side.
boost::shared_ptr< DataAtIntegrationPts > dataAtPts
data at integration pts
MoFEMErrorCode doWork(int side, EntityType type, EntData &data)
boost::shared_ptr< DataAtIntegrationPts > dataAtPts
data at integration pts
MoFEMErrorCode iNtegrate(EntData &data)
MoFEMErrorCode doWork(int side, EntityType type, EntData &data)
boost::shared_ptr< DataAtIntegrationPts > dataAtPts
data at integration pts
MoFEMErrorCode doWork(int side, EntityType type, EntData &data)
Caluclate face material force and normal pressure at gauss points.
boost::shared_ptr< DataAtIntegrationPts > dataAtPts
data at integration pts
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 &row_data, EntData &col_data)
MoFEMErrorCode iNtegrate(EntData &row_data, EntData &col_data)
MoFEMErrorCode iNtegrate(EntData &data)
std::vector< EntityHandle > & mapGaussPts
boost::shared_ptr< DataAtIntegrationPts > dataAtPts
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 &row_data, EntData &col_data)
MoFEMErrorCode iNtegrate(EntData &row_data, EntData &col_data)
std::map< std::string, boost::shared_ptr< ScalingMethod > > scalingMethodsMap
MoFEMErrorCode iNtegrate(EntData &data)
MoFEMErrorCode iNtegrate(EntData &data)
MoFEMErrorCode iNtegrate(EntData &row_data, EntData &col_data)
MoFEMErrorCode iNtegrate(EntData &row_data, EntData &col_data)
std::map< std::string, boost::shared_ptr< ScalingMethod > > scalingMethodsMap
MoFEMErrorCode iNtegrate(EntData &data)
double scale
Definition plastic.cpp:123
constexpr auto size_symm
Definition plastic.cpp:42