v0.16.0
Loading...
Searching...
No Matches
HenckyOps.hpp
Go to the documentation of this file.
1/**
2 * \file HenckyOps.hpp
3 * \example mofem/tutorials/vec-2_nonlinear_elasticity/src/HenckyOps.hpp
4 *
5 * @copyright Copyright (c) 2023
6 */
7
8#ifndef __HENCKY_OPS_HPP__
9#define __HENCKY_OPS_HPP__
10
11namespace HenckyOps {
12
13const double eps = std::sqrt(std::numeric_limits<double>::epsilon());
14
15auto f = [](double v) { return 0.5 * std::log(v); };
16auto d_f = [](double v) { return 0.5 / v; };
17auto dd_f = [](double v) { return -0.5 / (v * v); };
18
19struct CommonData : public boost::enable_shared_from_this<CommonData> {
20 boost::shared_ptr<MatrixDouble> matGradPtr;
21 boost::shared_ptr<MatrixDouble> matDPtr;
22 boost::shared_ptr<MatrixDouble> matLogCPlastic;
23
24 MatrixDouble matEigVal;
25 MatrixDouble matEigVec;
26 MatrixDouble matLogC;
27 MatrixDouble matLogCdC;
28 MatrixDouble matFirstPiolaStress;
30 MatrixDouble matHenckyStress;
31 MatrixDouble matTangent;
32
33 inline auto getMatFirstPiolaStress() {
34 return boost::shared_ptr<MatrixDouble>(shared_from_this(),
36 }
37
38 inline auto getMatHenckyStress() {
39 return boost::shared_ptr<MatrixDouble>(shared_from_this(),
41 }
42
43 inline auto getMatLogC() {
44 return boost::shared_ptr<MatrixDouble>(shared_from_this(), &matLogC);
45 }
46
47 inline auto getMatTangent() {
48 return boost::shared_ptr<MatrixDouble>(shared_from_this(), &matTangent);
49 }
50};
51
52template <int DIM, IntegrationType I, typename DomainEleOp>
54
55template <int DIM, IntegrationType I, typename DomainEleOp>
57
58template <int DIM, IntegrationType I, typename DomainEleOp>
60
61template <int DIM, IntegrationType I, typename DomainEleOp, int S>
63
64template <int DIM, IntegrationType I, typename DomainEleOp, int S>
66
67template <int DIM, IntegrationType I, typename DomainEleOp, int S>
69
70template <int DIM, IntegrationType I, typename DomainEleOp, int S>
72
73template <int DIM, IntegrationType I, typename DomainEleOp, int S>
75
76template <int DIM, IntegrationType I, typename DomainEleOp, int S>
78
79template <int DIM, IntegrationType I, typename DomainEleOp, int S>
81
82template <int DIM, typename DomainEleOp>
83struct OpCalculateEigenValsImpl<DIM, GAUSS, DomainEleOp> : public DomainEleOp {
84
86 boost::shared_ptr<CommonData> common_data)
88 commonDataPtr(common_data) {
89 std::fill(&DomainEleOp::doEntities[MBEDGE],
90 &DomainEleOp::doEntities[MBMAXTYPE], false);
91 }
92
93 MoFEMErrorCode doWork(int side, EntityType type, EntData &data) {
95
96 FTensor::Index<'i', DIM> i;
97 FTensor::Index<'j', DIM> j;
98 FTensor::Index<'k', DIM> k;
99
100 [[maybe_unused]] constexpr auto t_kd = FTensor::Kronecker_Delta<int>();
101 // const size_t nb_gauss_pts = matGradPtr->size2();
102 const size_t nb_gauss_pts = DomainEleOp::getGaussPts().size2();
103
104 auto t_grad = getFTensor2FromMat<DIM, DIM>(*(commonDataPtr->matGradPtr));
105
106 commonDataPtr->matEigVal.resize(nb_gauss_pts, DIM, false);
107 commonDataPtr->matEigVec.resize(nb_gauss_pts, DIM * DIM, false);
108 auto t_eig_val = getFTensor1FromMat<DIM>(commonDataPtr->matEigVal);
109 auto t_eig_vec = getFTensor2FromMat<DIM, DIM>(commonDataPtr->matEigVec);
110
111 for (size_t gg = 0; gg != nb_gauss_pts; ++gg) {
112
117
118 F(i, j) = t_grad(i, j) + t_kd(i, j);
119 C(i, j) = F(k, i) ^ F(k, j);
120
121 for (int ii = 0; ii != DIM; ii++)
122 for (int jj = 0; jj != DIM; jj++)
123 eigen_vec(ii, jj) = C(ii, jj);
124
125 CHKERR computeEigenValuesSymmetric(eigen_vec, eig);
126 for (auto ii = 0; ii != DIM; ++ii)
127 eig(ii) = std::max(eps, eig(ii));
128
129 // rare case when two eigen values are equal
130 auto nb_uniq =
131 getUniqNb<DIM>(getVectorAdaptor(&eig(0), DIM), FTensor::Number<DIM>{});
132 if constexpr (DIM == 3) {
133 if (nb_uniq == 2) {
134 CHKERR sortEigenVals<DIM>(
135 getVectorAdaptor(&eig(0), DIM),
136 getMatrixAdaptor(&eigen_vec(0, 0), DIM, DIM),
138 }
139 }
140
141 t_eig_val(i) = eig(i);
142 t_eig_vec(i, j) = eigen_vec(i, j);
143
144#ifndef NDEBUG
145 auto nb_uniq_test = getUniqNb<DIM>(getVectorAdaptor(&t_eig_val(0), DIM),
147 if (nb_uniq_test != nb_uniq) {
148 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
149 "Inconsistent number of unique eigen values %ld != %ld",
150 nb_uniq, nb_uniq_test);
151 }
152#endif
153
154 ++t_grad;
155 ++t_eig_val;
156 ++t_eig_vec;
157 }
158
160 }
161
162private:
163 boost::shared_ptr<CommonData> commonDataPtr;
164};
165
166template <int DIM, typename DomainEleOp>
167struct OpCalculateLogCImpl<DIM, GAUSS, DomainEleOp> : public DomainEleOp {
168
170 boost::shared_ptr<CommonData> common_data)
172 commonDataPtr(common_data) {
173 std::fill(&DomainEleOp::doEntities[MBEDGE],
174 &DomainEleOp::doEntities[MBMAXTYPE], false);
175 }
176
177 MoFEMErrorCode doWork(int side, EntityType type, EntData &data) {
179
180 FTensor::Index<'i', DIM> i;
181 FTensor::Index<'j', DIM> j;
182
183 // const size_t nb_gauss_pts = matGradPtr->size2();
184 const size_t nb_gauss_pts = DomainEleOp::getGaussPts().size2();
185 constexpr auto size_symm = (DIM * (DIM + 1)) / 2;
186 commonDataPtr->matLogC.resize(nb_gauss_pts, size_symm, false);
187
188 auto t_eig_val = getFTensor1FromMat<DIM>(commonDataPtr->matEigVal);
189 auto t_eig_vec = getFTensor2FromMat<DIM, DIM>(commonDataPtr->matEigVec);
190
191 auto t_logC = getFTensor2SymmetricFromMat<DIM>(commonDataPtr->matLogC);
192
193 for (size_t gg = 0; gg != nb_gauss_pts; ++gg) {
194 t_logC(i, j) = EigenMatrix::getMat(t_eig_val, t_eig_vec, f)(i, j);
195 ++t_eig_val;
196 ++t_eig_vec;
197 ++t_logC;
198 }
199
201 }
202
203private:
204 boost::shared_ptr<CommonData> commonDataPtr;
205};
206
207template <int DIM, typename DomainEleOp>
208struct OpCalculateLogC_dCImpl<DIM, GAUSS, DomainEleOp> : public DomainEleOp {
209
211 boost::shared_ptr<CommonData> common_data)
213 commonDataPtr(common_data) {
214 std::fill(&DomainEleOp::doEntities[MBEDGE],
215 &DomainEleOp::doEntities[MBMAXTYPE], false);
216 }
217
218 MoFEMErrorCode doWork(int side, EntityType type, EntData &data) {
220
221 FTensor::Index<'i', DIM> i;
222 FTensor::Index<'j', DIM> j;
223 FTensor::Index<'k', DIM> k;
224 FTensor::Index<'l', DIM> l;
225
226 const size_t nb_gauss_pts = DomainEleOp::getGaussPts().size2();
227 constexpr auto size_symm = (DIM * (DIM + 1)) / 2;
228 commonDataPtr->matLogCdC.resize(nb_gauss_pts, size_symm * size_symm, false);
229 auto t_logC_dC = getFTensor4DdgFromMat<DIM, DIM>(commonDataPtr->matLogCdC);
230 auto t_eig_val = getFTensor1FromMat<DIM>(commonDataPtr->matEigVal);
231 auto t_eig_vec = getFTensor2FromMat<DIM, DIM>(commonDataPtr->matEigVec);
232
233 for (size_t gg = 0; gg != nb_gauss_pts; ++gg) {
234 // rare case when two eigen values are equal
235 auto nb_uniq = getUniqNb<DIM>(getVectorAdaptor(&t_eig_val(0), DIM),
237 t_logC_dC(i, j, k, l) =
238 2 * EigenMatrix::getDiffMat(t_eig_val, t_eig_vec, f, d_f,
239 nb_uniq)(i, j, k, l);
240
241 ++t_logC_dC;
242 ++t_eig_val;
243 ++t_eig_vec;
244 }
245
247 }
248
249private:
250 boost::shared_ptr<CommonData> commonDataPtr;
251};
252
253template <int DIM, typename DomainEleOp, int S>
255 : public DomainEleOp {
256
258 boost::shared_ptr<CommonData> common_data)
260 commonDataPtr(common_data) {
261 std::fill(&DomainEleOp::doEntities[MBEDGE],
262 &DomainEleOp::doEntities[MBMAXTYPE], false);
263 }
264
265 MoFEMErrorCode doWork(int side, EntityType type, EntData &data) {
267
268 FTensor::Index<'i', DIM> i;
269 FTensor::Index<'j', DIM> j;
270 FTensor::Index<'k', DIM> k;
271 FTensor::Index<'l', DIM> l;
272
273 // const size_t nb_gauss_pts = matGradPtr->size2();
274 const size_t nb_gauss_pts = DomainEleOp::getGaussPts().size2();
275 auto t_D = getFTensor4DdgFromMat<DIM, DIM, S>(*commonDataPtr->matDPtr);
276 auto t_logC = getFTensor2SymmetricFromMat<DIM>(commonDataPtr->matLogC);
277 constexpr auto size_symm = (DIM * (DIM + 1)) / 2;
278 commonDataPtr->matHenckyStress.resize(nb_gauss_pts, size_symm, false);
279 auto t_T = getFTensor2SymmetricFromMat<DIM>(commonDataPtr->matHenckyStress);
280
281 for (size_t gg = 0; gg != nb_gauss_pts; ++gg) {
282 t_T(i, j) = t_D(i, j, k, l) * t_logC(k, l);
283 ++t_logC;
284 ++t_T;
285 ++t_D;
286 }
287
289 }
290
291private:
292 boost::shared_ptr<CommonData> commonDataPtr;
293};
294
295template <int DIM, typename DomainEleOp, int S>
297 : public DomainEleOp {
298
300 const std::string field_name, boost::shared_ptr<VectorDouble> temperature,
301 boost::shared_ptr<CommonData> common_data,
302 boost::shared_ptr<VectorDouble> coeff_expansion_ptr,
303 boost::shared_ptr<double> ref_temp_ptr)
304 : DomainEleOp(field_name, DomainEleOp::OPROW), tempPtr(temperature),
305 commonDataPtr(common_data), coeffExpansionPtr(coeff_expansion_ptr),
306 refTempPtr(ref_temp_ptr) {
307 std::fill(&DomainEleOp::doEntities[MBEDGE],
308 &DomainEleOp::doEntities[MBMAXTYPE], false);
309 }
310
311 MoFEMErrorCode doWork(int side, EntityType type, EntData &data) {
313
314 FTensor::Index<'i', DIM> i;
315 FTensor::Index<'j', DIM> j;
316 FTensor::Index<'k', DIM> k;
317 FTensor::Index<'l', DIM> l;
318
319 [[maybe_unused]] constexpr auto t_kd = FTensor::Kronecker_Delta<int>();
320
321 // const size_t nb_gauss_pts = matGradPtr->size2();
322 const size_t nb_gauss_pts = DomainEleOp::getGaussPts().size2();
323 auto t_D = getFTensor4DdgFromMat<DIM, DIM, S>(*commonDataPtr->matDPtr);
324 auto t_logC = getFTensor2SymmetricFromMat<DIM>(commonDataPtr->matLogC);
325 auto t_logC_dC = getFTensor4DdgFromMat<DIM, DIM>(commonDataPtr->matLogCdC);
326 constexpr auto size_symm = (DIM * (DIM + 1)) / 2;
327 commonDataPtr->matHenckyStress.resize(nb_gauss_pts, size_symm, false);
328 commonDataPtr->matFirstPiolaStress.resize(nb_gauss_pts, DIM * DIM, false);
329 commonDataPtr->matSecondPiolaStress.resize(nb_gauss_pts, size_symm, false);
330 auto t_T = getFTensor2SymmetricFromMat<DIM>(commonDataPtr->matHenckyStress);
331 auto t_P = getFTensor2FromMat<DIM, DIM>(commonDataPtr->matFirstPiolaStress);
332 auto t_S =
333 getFTensor2SymmetricFromMat<DIM>(commonDataPtr->matSecondPiolaStress);
334 auto t_grad = getFTensor2FromMat<DIM, DIM>(*(commonDataPtr->matGradPtr));
335 auto t_temp = getFTensor0FromVec(*tempPtr);
336
338 t_coeff_exp(i, j) = 0;
339 for (auto d = 0; d != SPACE_DIM; ++d) {
340 t_coeff_exp(d, d) = (*coeffExpansionPtr)[d];
341 }
342
343 for (size_t gg = 0; gg != nb_gauss_pts; ++gg) {
344#ifdef HENCKY_SMALL_STRAIN
345 t_P(i, j) = t_D(i, j, k, l) *
346 (t_grad(k, l) - t_coeff_exp(k, l) * (t_temp - (*refTempPtr)));
347#else
348 t_T(i, j) = t_D(i, j, k, l) *
349 (t_logC(k, l) - t_coeff_exp(k, l) * (t_temp - (*refTempPtr)));
351 t_F(i, j) = t_grad(i, j) + t_kd(i, j);
352 t_S(k, l) = t_T(i, j) * t_logC_dC(i, j, k, l);
353 t_P(i, l) = t_F(i, k) * t_S(k, l);
354#endif
355 ++t_grad;
356 ++t_logC;
357 ++t_logC_dC;
358 ++t_P;
359 ++t_T;
360 ++t_S;
361 ++t_D;
362 ++t_temp;
363 }
364
366 }
367
368private:
369 boost::shared_ptr<CommonData> commonDataPtr;
370 boost::shared_ptr<VectorDouble> tempPtr;
371 boost::shared_ptr<VectorDouble> coeffExpansionPtr;
372 boost::shared_ptr<double> refTempPtr;
373};
374
375template <int DIM, typename DomainEleOp, int S>
377 : public DomainEleOp {
378
380 boost::shared_ptr<CommonData> common_data,
381 boost::shared_ptr<MatrixDouble> mat_D_ptr,
382 const double scale = 1)
383 : DomainEleOp(field_name, DomainEleOp::OPROW), commonDataPtr(common_data),
384 scaleStress(scale), matDPtr(mat_D_ptr) {
385 std::fill(&DomainEleOp::doEntities[MBEDGE],
386 &DomainEleOp::doEntities[MBMAXTYPE], false);
387
388 matLogCPlastic = commonDataPtr->matLogCPlastic;
389 }
390
391 MoFEMErrorCode doWork(int side, EntityType type, EntData &data) {
393
394 FTensor::Index<'i', DIM> i;
395 FTensor::Index<'j', DIM> j;
396 FTensor::Index<'k', DIM> k;
397 FTensor::Index<'l', DIM> l;
398
399 // const size_t nb_gauss_pts = matGradPtr->size2();
400 const size_t nb_gauss_pts = DomainEleOp::getGaussPts().size2();
401 auto t_D = getFTensor4DdgFromMat<DIM, DIM, S>(*matDPtr);
402 auto t_logC = getFTensor2SymmetricFromMat<DIM>(commonDataPtr->matLogC);
403 auto t_logCPlastic = getFTensor2SymmetricFromMat<DIM>(*matLogCPlastic);
404 constexpr auto size_symm = (DIM * (DIM + 1)) / 2;
405 commonDataPtr->matHenckyStress.resize(nb_gauss_pts, size_symm, false);
406 auto t_T = getFTensor2SymmetricFromMat<DIM>(commonDataPtr->matHenckyStress);
407
408 for (size_t gg = 0; gg != nb_gauss_pts; ++gg) {
409 t_T(i, j) = t_D(i, j, k, l) * (t_logC(k, l) - t_logCPlastic(k, l));
410 t_T(i, j) /= scaleStress;
411 ++t_logC;
412 ++t_T;
413 ++t_D;
414 ++t_logCPlastic;
415 }
416
418 }
419
420private:
421 boost::shared_ptr<CommonData> commonDataPtr;
422 boost::shared_ptr<MatrixDouble> matDPtr;
423 boost::shared_ptr<MatrixDouble> matLogCPlastic;
424 const double scaleStress;
425};
426
427template <int DIM, typename DomainEleOp, int S>
429 : public DomainEleOp {
430
432 boost::shared_ptr<CommonData> common_data)
434 commonDataPtr(common_data) {
435 std::fill(&DomainEleOp::doEntities[MBEDGE],
436 &DomainEleOp::doEntities[MBMAXTYPE], false);
437 }
438
439 MoFEMErrorCode doWork(int side, EntityType type, EntData &data) {
441
442 FTensor::Index<'i', DIM> i;
443 FTensor::Index<'j', DIM> j;
444 FTensor::Index<'k', DIM> k;
445 FTensor::Index<'l', DIM> l;
446
447 [[maybe_unused]] constexpr auto t_kd = FTensor::Kronecker_Delta<int>();
448
449 // const size_t nb_gauss_pts = matGradPtr->size2();
450 const size_t nb_gauss_pts = DomainEleOp::getGaussPts().size2();
451#ifdef HENCKY_SMALL_STRAIN
452 auto t_D = getFTensor4DdgFromMat<DIM, DIM, S>(*commonDataPtr->matDPtr);
453#endif
454 auto t_logC = getFTensor2SymmetricFromMat<DIM>(commonDataPtr->matLogC);
455 auto t_logC_dC = getFTensor4DdgFromMat<DIM, DIM>(commonDataPtr->matLogCdC);
456 constexpr auto size_symm = (DIM * (DIM + 1)) / 2;
457 commonDataPtr->matFirstPiolaStress.resize(nb_gauss_pts, DIM * DIM, false);
458 commonDataPtr->matSecondPiolaStress.resize(nb_gauss_pts, size_symm, false);
459 auto t_P = getFTensor2FromMat<DIM, DIM>(commonDataPtr->matFirstPiolaStress);
460 auto t_T = getFTensor2SymmetricFromMat<DIM>(commonDataPtr->matHenckyStress);
461 auto t_S =
462 getFTensor2SymmetricFromMat<DIM>(commonDataPtr->matSecondPiolaStress);
463 auto t_grad = getFTensor2FromMat<DIM, DIM>(*(commonDataPtr->matGradPtr));
464
465 for (size_t gg = 0; gg != nb_gauss_pts; ++gg) {
466
467#ifdef HENCKY_SMALL_STRAIN
468 t_P(i, j) = t_D(i, j, k, l) * t_grad(k, l);
469#else
471 t_F(i, j) = t_grad(i, j) + t_kd(i, j);
472 t_S(k, l) = t_T(i, j) * t_logC_dC(i, j, k, l);
473 t_P(i, l) = t_F(i, k) * t_S(k, l);
474#endif
475
476 ++t_grad;
477 ++t_logC;
478 ++t_logC_dC;
479 ++t_P;
480 ++t_T;
481 ++t_S;
482#ifdef HENCKY_SMALL_STRAIN
483 ++t_D;
484#endif
485 }
486
488 }
489
490private:
491 boost::shared_ptr<CommonData> commonDataPtr;
492};
493
494template <int DIM, typename DomainEleOp, int S>
495struct OpHenckyTangentImpl<DIM, GAUSS, DomainEleOp, S> : public DomainEleOp {
497 boost::shared_ptr<CommonData> common_data,
498 boost::shared_ptr<MatrixDouble> mat_D_ptr = nullptr)
500 commonDataPtr(common_data) {
501 std::fill(&DomainEleOp::doEntities[MBEDGE],
502 &DomainEleOp::doEntities[MBMAXTYPE], false);
503 if (mat_D_ptr)
504 matDPtr = mat_D_ptr;
505 else
506 matDPtr = commonDataPtr->matDPtr;
507 }
508
509 MoFEMErrorCode doWork(int side, EntityType type, EntData &data) {
511
512 FTensor::Index<'i', DIM> i;
513 FTensor::Index<'j', DIM> j;
514 FTensor::Index<'k', DIM> k;
515 FTensor::Index<'l', DIM> l;
516 FTensor::Index<'m', DIM> m;
517 FTensor::Index<'n', DIM> n;
518 FTensor::Index<'o', DIM> o;
519 FTensor::Index<'p', DIM> p;
520
521 [[maybe_unused]] constexpr auto t_kd = FTensor::Kronecker_Delta<int>();
522 // const size_t nb_gauss_pts = matGradPtr->size2();
523 const size_t nb_gauss_pts = DomainEleOp::getGaussPts().size2();
524 commonDataPtr->matTangent.resize(nb_gauss_pts, DIM * DIM * DIM * DIM);
525 auto dP_dF =
526 getFTensor4FromMat<DIM, DIM, DIM, DIM>(commonDataPtr->matTangent);
527
528 auto t_D = getFTensor4DdgFromMat<DIM, DIM, S>(*matDPtr);
529 auto t_eig_val = getFTensor1FromMat<DIM>(commonDataPtr->matEigVal);
530 auto t_eig_vec = getFTensor2FromMat<DIM, DIM>(commonDataPtr->matEigVec);
531 auto t_T = getFTensor2SymmetricFromMat<DIM>(commonDataPtr->matHenckyStress);
532 auto t_S =
533 getFTensor2SymmetricFromMat<DIM>(commonDataPtr->matSecondPiolaStress);
534 auto t_grad = getFTensor2FromMat<DIM, DIM>(*(commonDataPtr->matGradPtr));
535 auto t_logC_dC = getFTensor4DdgFromMat<DIM, DIM>(commonDataPtr->matLogCdC);
536
537 for (size_t gg = 0; gg != nb_gauss_pts; ++gg) {
538
539#ifdef HENCKY_SMALL_STRAIN
540 dP_dF(i, j, k, l) = t_D(i, j, k, l);
541#else
542
544 t_F(i, j) = t_grad(i, j) + t_kd(i, j);
545
546 // rare case when two eigen values are equal
547 auto nb_uniq = getUniqNb<DIM>(getVectorAdaptor(&t_eig_val(0), DIM),
550 dC_dF(i, j, k, l) = (t_kd(i, l) * t_F(k, j)) + (t_kd(j, l) * t_F(k, i));
551
552 auto TL = EigenMatrix::getDiffDiffMat(t_eig_val, t_eig_vec, f, d_f, dd_f,
553 t_T, nb_uniq);
554 TL(i, j, k, l) *= 4;
555 FTensor::Ddg<double, DIM, DIM> P_D_P_plus_TL;
556 P_D_P_plus_TL(i, j, k, l) =
557 TL(i, j, k, l) +
558 (t_logC_dC(i, j, o, p) * t_D(o, p, m, n)) * t_logC_dC(m, n, k, l);
559 P_D_P_plus_TL(i, j, k, l) *= 0.5;
560 dP_dF(i, j, m, n) = t_kd(i, m) * (t_kd(k, n) * t_S(k, j));
561 dP_dF(i, j, m, n) +=
562 t_F(i, k) * (P_D_P_plus_TL(k, j, o, p) * dC_dF(o, p, m, n));
563
564#endif
565
566 ++dP_dF;
567
568 ++t_grad;
569 ++t_eig_val;
570 ++t_eig_vec;
571 ++t_logC_dC;
572 ++t_S;
573 ++t_T;
574 ++t_D;
575 }
576
578 }
579
580private:
581 boost::shared_ptr<CommonData> commonDataPtr;
582 boost::shared_ptr<MatrixDouble> matDPtr;
583};
584
585template <int DIM, typename AssemblyDomainEleOp, int S>
587 : public AssemblyDomainEleOp {
589 const std::string row_field_name, const std::string col_field_name,
590 boost::shared_ptr<CommonData> elastic_common_data_ptr,
591 boost::shared_ptr<VectorDouble> coeff_expansion_ptr);
592
593 MoFEMErrorCode iNtegrate(EntitiesFieldData::EntData &row_data,
594 EntitiesFieldData::EntData &col_data);
595
596private:
597 boost::shared_ptr<CommonData> elasticCommonDataPtr;
598 boost::shared_ptr<VectorDouble> coeffExpansionPtr;
599};
600
601template <int DIM, typename AssemblyDomainEleOp, int S>
604 const std::string row_field_name, const std::string col_field_name,
605 boost::shared_ptr<CommonData> elastic_common_data_ptr,
606 boost::shared_ptr<VectorDouble> coeff_expansion_ptr)
607 : AssemblyDomainEleOp(row_field_name, col_field_name,
608 AssemblyDomainEleOp::OPROWCOL),
609 elasticCommonDataPtr(elastic_common_data_ptr),
610 coeffExpansionPtr(coeff_expansion_ptr) {
611 this->sYmm = false;
612}
613
614template <int DIM, typename AssemblyDomainEleOp, int S>
615MoFEMErrorCode
617 iNtegrate(EntitiesFieldData::EntData &row_data,
618 EntitiesFieldData::EntData &col_data) {
620
621 auto &locMat = AssemblyDomainEleOp::locMat;
622
623 const auto nb_integration_pts = row_data.getN().size1();
624 const auto nb_row_base_functions = row_data.getN().size2();
625 auto t_w = this->getFTensor0IntegrationWeight();
626
627 constexpr auto t_kd = FTensor::Kronecker_Delta<int>();
628 auto t_row_diff_base = row_data.getFTensor1DiffN<DIM>();
629 auto t_D = getFTensor4DdgFromMat<DIM, DIM, 0>(*elasticCommonDataPtr->matDPtr);
630 auto t_grad =
631 getFTensor2FromMat<DIM, DIM>(*(elasticCommonDataPtr->matGradPtr));
632 auto t_logC_dC =
633 getFTensor4DdgFromMat<DIM, DIM>(elasticCommonDataPtr->matLogCdC);
636
637 FTensor::Index<'i', DIM> i;
638 FTensor::Index<'j', DIM> j;
639 FTensor::Index<'k', DIM> k;
640 FTensor::Index<'l', DIM> l;
641 FTensor::Index<'m', DIM> m;
642 FTensor::Index<'n', DIM> n;
643 FTensor::Index<'o', DIM> o;
644
646 t_coeff_exp(i, j) = 0;
647 for (auto d = 0; d != SPACE_DIM; ++d) {
648 t_coeff_exp(d, d) = (*coeffExpansionPtr)[d];
649 }
650
651 t_eigen_strain(i, j) = (t_D(i, j, k, l) * t_coeff_exp(k, l));
652
653 for (auto gg = 0; gg != nb_integration_pts; ++gg) {
654
655 t_F(i, j) = t_grad(i, j) + t_kd(i, j);
656
657 double alpha = this->getMeasure() * t_w;
658 auto rr = 0;
659 for (; rr != AssemblyDomainEleOp::nbRows / DIM; ++rr) {
660 auto t_mat =
661 getFTensor1FromMat<DIM, 1,
662 DataLayoutTraits<DataLayout::CoeffsByGauss>>(
663 locMat, rr * DIM);
664 auto t_col_base = col_data.getFTensor0N(gg, 0);
665 for (auto cc = 0; cc != AssemblyDomainEleOp::nbCols; cc++) {
666#ifdef HENCKY_SMALL_STRAIN
667 t_mat(i) -=
668 (t_row_diff_base(j) * t_eigen_strain(i, j)) * (t_col_base * alpha);
669#else
670 t_mat(i) -= (t_row_diff_base(j) *
671 (t_F(i, o) * ((t_D(m, n, k, l) * t_coeff_exp(k, l)) *
672 t_logC_dC(m, n, o, j)))) *
673 (t_col_base * alpha);
674#endif
675
676 ++t_mat;
677 ++t_col_base;
678 }
679
680 ++t_row_diff_base;
681 }
682 for (; rr != nb_row_base_functions; ++rr)
683 ++t_row_diff_base;
684
685 ++t_w;
686 ++t_grad;
687 ++t_logC_dC;
688 ++t_D;
689 }
690
692}
693
694template <typename DomainEleOp> struct HenckyIntegrators {
695 template <int DIM, IntegrationType I>
697
698 template <int DIM, IntegrationType I>
700
701 template <int DIM, IntegrationType I>
703
704 template <int DIM, IntegrationType I, int S>
707
708 template <int DIM, IntegrationType I, int S>
711
712 template <int DIM, IntegrationType I, int S>
715
716 template <int DIM, IntegrationType I, int S>
719
720 template <int DIM, IntegrationType I, int S>
722
723 template <int DIM, IntegrationType I, typename AssemblyDomainEleOp, int S>
726};
727
728template <int DIM>
729MoFEMErrorCode
731 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pip,
732 std::string block_name,
733 boost::shared_ptr<MatrixDouble> mat_D_Ptr, Sev sev,
734 double scale = 1) {
736
737 PetscBool plane_strain_flag = PETSC_FALSE;
738 CHKERR PetscOptionsGetBool(PETSC_NULLPTR, "", "-plane_strain",
739 &plane_strain_flag, PETSC_NULLPTR);
740
741 struct OpMatBlocks : public DomainEleOp {
742 OpMatBlocks(boost::shared_ptr<MatrixDouble> m, double bulk_modulus_K,
743 double shear_modulus_G, MoFEM::Interface &m_field, Sev sev,
744 std::vector<const CubitMeshSets *> meshset_vec_ptr,
745 double scale, PetscBool plane_strain_flag)
746 : DomainEleOp(NOSPACE, DomainEleOp::OPSPACE), matDPtr(m),
747 bulkModulusKDefault(bulk_modulus_K),
748 shearModulusGDefault(shear_modulus_G), scaleYoungModulus(scale),
749 planeStrainFlag(plane_strain_flag) {
750 CHK_THROW_MESSAGE(extractBlockData(m_field, meshset_vec_ptr, sev),
751 "Can not get data from block");
752 }
753
754 MoFEMErrorCode doWork(int side, EntityType type,
755 EntitiesFieldData::EntData &data) {
757
758 for (auto &b : blockData) {
759
760 if (b.blockEnts.find(getFEEntityHandle()) != b.blockEnts.end()) {
761 CHKERR getMatDPtr(matDPtr, b.bulkModulusK * scaleYoungModulus,
762 b.shearModulusG * scaleYoungModulus,
763 planeStrainFlag);
765 }
766 }
767
768 CHKERR getMatDPtr(matDPtr, bulkModulusKDefault * scaleYoungModulus,
769 shearModulusGDefault * scaleYoungModulus,
770 planeStrainFlag);
772 }
773
774 private:
775 boost::shared_ptr<MatrixDouble> matDPtr;
776 const double scaleYoungModulus;
777 const PetscBool planeStrainFlag;
778
779 struct BlockData {
780 double bulkModulusK;
781 double shearModulusG;
782 Range blockEnts;
783 };
784
785 double bulkModulusKDefault;
786 double shearModulusGDefault;
787 std::vector<BlockData> blockData;
788
789 MoFEMErrorCode
790 extractBlockData(MoFEM::Interface &m_field,
791 std::vector<const CubitMeshSets *> meshset_vec_ptr,
792 Sev sev) {
794
795 for (auto m : meshset_vec_ptr) {
796 MOFEM_TAG_AND_LOG("WORLD", sev, "MatBlock") << *m;
797 std::vector<double> block_data;
798 CHKERR m->getAttributes(block_data);
799 if (block_data.size() != 2) {
800 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
801 "Expected that block has two attribute");
802 }
803 auto get_block_ents = [&]() {
804 Range ents;
805 CHKERR
806 m_field.get_moab().get_entities_by_handle(m->meshset, ents, true);
807 return ents;
808 };
809
810 double young_modulus = block_data[0];
811 double poisson_ratio = block_data[1];
812 double bulk_modulus_K = young_modulus / (3 * (1 - 2 * poisson_ratio));
813 double shear_modulus_G = young_modulus / (2 * (1 + poisson_ratio));
814
815 MOFEM_TAG_AND_LOG("WORLD", sev, "MatBlock")
816 << "E = " << young_modulus << " nu = " << poisson_ratio;
817
818 blockData.push_back(
819 {bulk_modulus_K, shear_modulus_G, get_block_ents()});
820 }
821 MOFEM_LOG_CHANNEL("WORLD");
823 }
824
825 MoFEMErrorCode getMatDPtr(boost::shared_ptr<MatrixDouble> mat_D_ptr,
826 double bulk_modulus_K, double shear_modulus_G,
827 PetscBool is_plane_strain) {
829 //! [Calculate elasticity tensor]
830 auto set_material_stiffness = [&]() {
831 FTensor::Index<'i', DIM> i;
832 FTensor::Index<'j', DIM> j;
833 FTensor::Index<'k', DIM> k;
834 FTensor::Index<'l', DIM> l;
836 double A = (SPACE_DIM == 2 && !is_plane_strain)
837 ? 2 * shear_modulus_G /
838 (bulk_modulus_K + (4. / 3.) * shear_modulus_G)
839 : 1;
840 auto t_D = getFTensor4DdgFromMat<DIM, DIM, 0>(*mat_D_ptr);
841 t_D(i, j, k, l) =
842 2 * shear_modulus_G * ((t_kd(i, k) ^ t_kd(j, l)) / 4.) +
843 A * (bulk_modulus_K - (2. / 3.) * shear_modulus_G) * t_kd(i, j) *
844 t_kd(k, l);
845 };
846 //! [Calculate elasticity tensor]
847 constexpr auto size_symm = (DIM * (DIM + 1)) / 2;
848 mat_D_ptr->resize(1, size_symm * size_symm);
849 set_material_stiffness();
851 }
852 };
853
854 double E = 1.0;
855 double nu = 0.3;
856
857 PetscOptionsBegin(PETSC_COMM_WORLD, "", "", "none");
858 CHKERR PetscOptionsScalar("-young_modulus", "Young modulus", "", E, &E,
859 PETSC_NULLPTR);
860 CHKERR PetscOptionsScalar("-poisson_ratio", "poisson ratio", "", nu, &nu,
861 PETSC_NULLPTR);
862 PetscOptionsEnd();
863
864 double bulk_modulus_K = E / (3 * (1 - 2 * nu));
865 double shear_modulus_G = E / (2 * (1 + nu));
866 pip.push_back(new OpMatBlocks(
867 mat_D_Ptr, bulk_modulus_K, shear_modulus_G, m_field, sev,
868
869 // Get blockset using regular expression
870 m_field.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(std::regex(
871
872 (boost::format("%s(.*)") % block_name).str()
873
874 )),
875 scale, plane_strain_flag
876
877 ));
878
880}
881
882template <int DIM, IntegrationType I, typename DomainEleOp>
884 MoFEM::Interface &m_field,
885 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pip,
886 std::string field_name, std::string block_name, Sev sev, double scale = 1) {
887
888 auto common_ptr = boost::make_shared<HenckyOps::CommonData>();
889 common_ptr->matDPtr = boost::make_shared<MatrixDouble>();
890 common_ptr->matGradPtr = boost::make_shared<MatrixDouble>();
891
892 CHK_THROW_MESSAGE(addMatBlockOps<DIM>(m_field, pip, block_name,
893 common_ptr->matDPtr, sev, scale),
894 "addMatBlockOps");
895
897
898 pip.push_back(new OpCalculateVectorFieldGradient<DIM, DIM>(
899 field_name, common_ptr->matGradPtr));
900 pip.push_back(new typename H::template OpCalculateEigenVals<DIM, I>(
901 field_name, common_ptr));
902 pip.push_back(
903 new typename H::template OpCalculateLogC<DIM, I>(field_name, common_ptr));
904 pip.push_back(new typename H::template OpCalculateLogC_dC<DIM, I>(
905 field_name, common_ptr));
906 // Assumes constant D matrix per entity
907 pip.push_back(new typename H::template OpCalculateHenckyStress<DIM, I, 0>(
908 field_name, common_ptr));
909 pip.push_back(new typename H::template OpCalculatePiolaStress<DIM, I, 0>(
910 field_name, common_ptr));
911
912 return common_ptr;
913}
914
915template <int DIM, AssemblyType A, IntegrationType I, typename DomainEleOp>
916MoFEMErrorCode opFactoryDomainRhs(
917 MoFEM::Interface &m_field,
918 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pip,
919 std::string field_name, boost::shared_ptr<HenckyOps::CommonData> common_ptr,
920 Sev sev) {
922
923 using B = typename FormsIntegrators<DomainEleOp>::template Assembly<
924 A>::template LinearForm<I>;
926 typename B::template OpGradTimesTensor<1, DIM, DIM>;
927 pip.push_back(
928 new OpInternalForcePiola("U", common_ptr->getMatFirstPiolaStress()));
929
931}
932
933template <int DIM, AssemblyType A, IntegrationType I, typename DomainEleOp>
934MoFEMErrorCode opFactoryDomainRhs(
935 MoFEM::Interface &m_field,
936 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pip,
937 std::string field_name, std::string block_name, Sev sev, double scale = 1) {
939
940 auto common_ptr = commonDataFactory<DIM, I, DomainEleOp>(
941 m_field, pip, field_name, block_name, sev, scale);
942 CHKERR opFactoryDomainRhs<DIM, A, I, DomainEleOp>(m_field, pip, field_name,
943 common_ptr, sev);
944
946}
947
948template <int DIM, AssemblyType A, IntegrationType I, typename DomainEleOp>
949MoFEMErrorCode opFactoryDomainLhs(
950 MoFEM::Interface &m_field,
951 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pip,
952 std::string field_name, boost::shared_ptr<HenckyOps::CommonData> common_ptr,
953 Sev sev) {
955
956 using B = typename FormsIntegrators<DomainEleOp>::template Assembly<
957 A>::template BiLinearForm<I>;
958 using OpKPiola = typename B::template OpGradTensorGrad<1, DIM, DIM, -1>;
959
961 // Assumes constant D matrix per entity
962 pip.push_back(new typename H::template OpHenckyTangent<DIM, I, 0>(
963 field_name, common_ptr));
964 pip.push_back(
965 new OpKPiola(field_name, field_name, common_ptr->getMatTangent()));
966
968}
969
970template <int DIM, AssemblyType A, IntegrationType I, typename DomainEleOp>
971MoFEMErrorCode opFactoryDomainLhs(
972 MoFEM::Interface &m_field,
973 boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pip,
974 std::string field_name, std::string block_name, Sev sev, double scale = 1) {
976
977 auto common_ptr = commonDataFactory<DIM, I, DomainEleOp>(
978 m_field, pip, field_name, block_name, sev, scale);
979 CHKERR opFactoryDomainLhs<DIM, A, I, DomainEleOp>(m_field, pip, field_name,
980 common_ptr, sev);
981
983}
984} // namespace HenckyOps
985
986#endif // __HENCKY_OPS_HPP__
std::string type
#define MOFEM_TAG_AND_LOG(channel, severity, tag)
Tag and log in channel.
constexpr int SPACE_DIM
DomainEle::UserDataOperator DomainEleOp
Finire element operator type.
Kronecker Delta class symmetric.
Kronecker Delta class.
#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()
@ NOSPACE
Definition definitions.h:83
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
@ MOFEM_DATA_INCONSISTENCY
Definition definitions.h:31
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
double bulk_modulus_K
double shear_modulus_G
@ F
constexpr auto t_kd
#define MOFEM_LOG_CHANNEL(channel)
Set and reset channel.
FTensor::Index< 'i', SPACE_DIM > i
const double v
phase velocity of light in medium (cm/ns)
const double n
refractive index of diffusive medium
FTensor::Index< 'l', 3 > l
FTensor::Index< 'j', 3 > j
FTensor::Index< 'k', 3 > k
auto getMat(A &&t_val, B &&t_vec, Fun< double > f)
Get the Mat object.
auto getDiffMat(A &&t_val, B &&t_vec, Fun< double > f, Fun< double > d_f, const int nb)
Get the Diff Mat object.
auto getDiffDiffMat(A &&t_val, B &&t_vec, Fun< double > f, Fun< double > d_f, Fun< double > dd_f, C &&t_S, const int nb)
Get the Diff Diff Mat object.
MoFEMErrorCode opFactoryDomainLhs(MoFEM::Interface &m_field, boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pip, std::string field_name, boost::shared_ptr< HenckyOps::CommonData > common_ptr, Sev sev)
const double eps
Definition HenckyOps.hpp:13
MoFEMErrorCode opFactoryDomainRhs(MoFEM::Interface &m_field, boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pip, std::string field_name, boost::shared_ptr< HenckyOps::CommonData > common_ptr, Sev sev)
MoFEMErrorCode addMatBlockOps(MoFEM::Interface &m_field, boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pip, std::string block_name, boost::shared_ptr< MatrixDouble > mat_D_Ptr, Sev sev, double scale=1)
auto commonDataFactory(MoFEM::Interface &m_field, boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pip, std::string field_name, std::string block_name, Sev sev, double scale=1)
FormsIntegrators< DomainEleOp >::Assembly< A >::LinearForm< I >::OpGradTimesTensor< 1, FIELD_DIM, SPACE_DIM > OpGradTimesTensor
constexpr AssemblyType A
constexpr auto field_name
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::LinearForm< GAUSS >::OpGradTimesTensor< 1, SPACE_DIM, SPACE_DIM > OpInternalForcePiola
Definition seepage.cpp:65
PetscBool is_plane_strain
Definition seepage.cpp:177
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::BiLinearForm< GAUSS >::OpGradTensorGrad< 1, SPACE_DIM, SPACE_DIM, -1 > OpKPiola
[Only used for dynamics]
Definition seepage.cpp:63
FTensor::Index< 'm', 3 > m
MatrixDouble matEigVec
Definition HenckyOps.hpp:25
boost::shared_ptr< MatrixDouble > matLogCPlastic
Definition HenckyOps.hpp:22
MatrixDouble matHenckyStress
Definition HenckyOps.hpp:30
MatrixDouble matLogCdC
Definition HenckyOps.hpp:27
MatrixDouble matEigVal
Definition HenckyOps.hpp:24
MatrixDouble matFirstPiolaStress
Definition HenckyOps.hpp:28
boost::shared_ptr< MatrixDouble > matDPtr
Definition HenckyOps.hpp:21
MatrixDouble matSecondPiolaStress
Definition HenckyOps.hpp:29
MatrixDouble matLogC
Definition HenckyOps.hpp:26
MatrixDouble matTangent
Definition HenckyOps.hpp:31
boost::shared_ptr< MatrixDouble > matGradPtr
Definition HenckyOps.hpp:20
OpCalculateEigenValsImpl(const std::string field_name, boost::shared_ptr< CommonData > common_data)
Definition HenckyOps.hpp:85
MoFEMErrorCode doWork(int side, EntityType type, EntData &data)
Definition HenckyOps.hpp:93
MoFEMErrorCode doWork(int side, EntityType type, EntData &data)
OpCalculateHenckyPlasticStressImpl(const std::string field_name, boost::shared_ptr< CommonData > common_data, boost::shared_ptr< MatrixDouble > mat_D_ptr, const double scale=1)
OpCalculateHenckyStressImpl(const std::string field_name, boost::shared_ptr< CommonData > common_data)
MoFEMErrorCode doWork(int side, EntityType type, EntData &data)
MoFEMErrorCode doWork(int side, EntityType type, EntData &data)
OpCalculateHenckyThermalStressImpl(const std::string field_name, boost::shared_ptr< VectorDouble > temperature, boost::shared_ptr< CommonData > common_data, boost::shared_ptr< VectorDouble > coeff_expansion_ptr, boost::shared_ptr< double > ref_temp_ptr)
MoFEMErrorCode doWork(int side, EntityType type, EntData &data)
OpCalculateLogCImpl(const std::string field_name, boost::shared_ptr< CommonData > common_data)
MoFEMErrorCode doWork(int side, EntityType type, EntData &data)
OpCalculateLogC_dCImpl(const std::string field_name, boost::shared_ptr< CommonData > common_data)
OpCalculatePiolaStressImpl(const std::string field_name, boost::shared_ptr< CommonData > common_data)
MoFEMErrorCode doWork(int side, EntityType type, EntData &data)
OpHenckyTangentImpl(const std::string field_name, boost::shared_ptr< CommonData > common_data, boost::shared_ptr< MatrixDouble > mat_D_ptr=nullptr)
MoFEMErrorCode doWork(int side, EntityType type, EntData &data)
virtual moab::Interface & get_moab()=0
Deprecated interface functions.
Data on single entity (This is passed as argument to DataOperator::doWork)
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.
double young_modulus
Young modulus.
Definition plastic.cpp:126
double poisson_ratio
Poisson ratio.
Definition plastic.cpp:127
double scale
Definition plastic.cpp:124
constexpr auto size_symm
Definition plastic.cpp:42
double H
Hardening.
Definition plastic.cpp:129