v0.15.0
Loading...
Searching...
No Matches
HMHNeohookean.cpp
Go to the documentation of this file.
1/**
2 * @file HMHNeohookean.cpp
3 * @brief Implementation of NeoHookean material
4 * @date 2024-08-31
5 *
6 * @copyright Copyright (c) 2024
7 *
8 */
9
10namespace EshelbianPlasticity {
11
12#define NEOHOOKEAN_OFF_INVERSE
13// #define NEOHOOKEAN_SCALING
15
16 static constexpr int numberOfActiveVariables = 0;
17 static constexpr int numberOfDependentVariables = 0;
18
19 HMHNeohookean(MoFEM::Interface &m_field, const double c10, const double K)
21 mField(m_field), c10_default(c10), K_default(K) {
22
23 CHK_THROW_MESSAGE(getOptions(), "get options failed");
25 "extract block data failed");
26
27#ifdef NEOHOOKEAN_SCALING
28 if (blockData.size()) {
29 double ave_K = 0;
30 for (auto b : blockData) {
31 ave_K += b.K;
32 }
33 eqScaling = ave_K / blockData.size();
34 }
35#endif
36
37 MOFEM_LOG("EP", Sev::inform) << "Neo-Hookean scaling = " << eqScaling;
38
41 "Stretch selector is not equal to LOG");
42 } else {
43 if (EshelbianCore::exponentBase != exp(1)) {
45 "Exponent base is not equal to exp(1)");
46 }
47 }
48 }
49
51 for (auto &b : blockData) {
52 if (b.blockEnts.find(ent) != b.blockEnts.end()) {
53 return std::make_pair(b.c10, b.K);
54 }
55 }
56 if (blockData.size() != 0)
58 "Block not found for entity handle. If you mat set "
59 "block, set it to all elements");
60 return std::make_pair(c10_default, K_default);
61 }
62
64 OpGetScale(boost::shared_ptr<double> scale_ptr,
65 boost::shared_ptr<PhysicalEquations> physics_ptr)
67 scalePtr(scale_ptr), physicsPtr(physics_ptr) {}
68
69 MoFEMErrorCode doWork(int side, EntityType type,
70 EntitiesFieldData::EntData &data) {
72 auto neohookean_ptr =
73 boost::dynamic_pointer_cast<HMHNeohookean>(physicsPtr);
74 *(scalePtr) = neohookean_ptr->eqScaling;
76 }
77
78 private:
79 boost::shared_ptr<double> scalePtr;
80 boost::shared_ptr<PhysicalEquations> physicsPtr;
81 };
82
84 returnOpSetScale(boost::shared_ptr<double> scale_ptr,
85 boost::shared_ptr<PhysicalEquations> physics_ptr) {
86
87 return new OpGetScale(scale_ptr, physics_ptr);
88 };
89
90 struct OpJacobian : public EshelbianPlasticity::OpJacobian {
91 using EshelbianPlasticity::OpJacobian::OpJacobian;
92 MoFEMErrorCode evaluateRhs(EntData &data) { return 0; }
93 MoFEMErrorCode evaluateLhs(EntData &data) { return 0; }
94 };
95
96 virtual EshelbianPlasticity::OpJacobian *
97 returnOpJacobian(const int tag, const bool eval_rhs, const bool eval_lhs,
98 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
99 boost::shared_ptr<PhysicalEquations> physics_ptr) {
100 return (new OpJacobian(tag, eval_rhs, eval_lhs, data_ptr, physics_ptr));
101 }
102
103 MoFEMErrorCode getOptions() {
105 PetscOptionsBegin(PETSC_COMM_WORLD, "neo_hookean_", "", "none");
106
107 c10_default = 1;
108 CHKERR PetscOptionsScalar("-c10", "C10", "", c10_default, &c10_default,
109 PETSC_NULLPTR);
110 K_default = 1;
111 CHKERR PetscOptionsScalar("-K", "Bulk modulus K", "", K_default, &K_default,
112 PETSC_NULLPTR);
113
114 alphaGradU = 0;
115 CHKERR PetscOptionsScalar("-viscosity_alpha_grad_u", "viscosity", "",
116 alphaGradU, &alphaGradU, PETSC_NULLPTR);
117
118 PetscOptionsEnd();
119
120 MOFEM_LOG_CHANNEL("WORLD");
121 MOFEM_TAG_AND_LOG("WORLD", Sev::inform, "MatBlock Neo-Hookean (default)")
122 << "c10 = " << c10_default << " K = " << K_default
123 << " grad alpha u = " << alphaGradU;
125 }
126
127 MoFEMErrorCode extractBlockData(Sev sev) {
128 return extractBlockData(
129
130 mField.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(std::regex(
131
132 (boost::format("%s(.*)") % "MAT_NEOHOOKEAN").str()
133
134 )),
135
136 sev);
137 }
138
139 MoFEMErrorCode
140 extractBlockData(std::vector<const CubitMeshSets *> meshset_vec_ptr,
141 Sev sev) {
143
144 for (auto m : meshset_vec_ptr) {
145 MOFEM_LOG("EP", sev) << *m;
146 std::vector<double> block_data;
147 CHKERR m->getAttributes(block_data);
148 if (block_data.size() < 2) {
149 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
150 "Expected that block has atleast two attributes");
151 }
152 auto get_block_ents = [&]() {
153 Range ents;
154 CHKERR mField.get_moab().get_entities_by_handle(m->meshset, ents, true);
155 return ents;
156 };
157
158 double c10 = block_data[0];
159 double K = block_data[1];
160
161 blockData.push_back({c10, K, get_block_ents()});
162
163 MOFEM_LOG("EP", sev) << "MatBlock Neo-Hookean c10 = "
164 << blockData.back().c10
165 << " K = " << blockData.back().K << " nb ents. = "
166 << blockData.back().blockEnts.size();
167 }
169 }
170
171 MoFEMErrorCode recordTape(const int tape, DTensor2Ptr *t_h_ptr) {
174 }
175
177
178 OpSpatialPhysical(const std::string &field_name,
179 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
180 const double alpha_u);
181
182 MoFEMErrorCode integrate(EntData &data);
183
184 private:
185 const double alphaU;
186 };
187
188 virtual VolUserDataOperator *
190 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
191 const double alpha_u) {
192 return new OpSpatialPhysical(field_name, data_ptr, alpha_u);
193 }
194
196 OpSpatialPhysical_du_du(std::string row_field, std::string col_field,
197 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
198 const double alpha);
199 MoFEMErrorCode integrate(EntData &row_data, EntData &col_data);
200
201 private:
202 const double alphaU;
203 };
204
206 std::string row_field, std::string col_field,
207 boost::shared_ptr<DataAtIntegrationPts> data_ptr, const double alpha) {
208 return new OpSpatialPhysical_du_du(row_field, col_field, data_ptr, alpha);
209 }
210
211private:
213
215 double K_default;
217 struct BlockData {
218 double c10;
219 double K;
221 };
222 std::vector<BlockData> blockData;
223
224 double eqScaling = 1.;
225
226};
227
229 const std::string &field_name,
230 boost::shared_ptr<DataAtIntegrationPts> data_ptr, const double alpha_u)
231 : OpAssembleVolume(field_name, data_ptr, OPROW), alphaU(alpha_u) {}
232
235
236 auto neohookean_ptr =
237 boost::dynamic_pointer_cast<HMHNeohookean>(dataAtPts->physicsPtr);
238 if (!neohookean_ptr) {
239 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
240 "Pointer to HMHNeohookean is null");
241 }
242 auto [def_c10, def_K] =
243 neohookean_ptr->getMaterialParameters(getFEEntityHandle());
244
245 double c10 = def_c10 / neohookean_ptr->eqScaling;
246 double alpha_u = alphaU / neohookean_ptr->eqScaling;
247 double K = def_K / neohookean_ptr->eqScaling;
248
249 double alpha_grad_u = neohookean_ptr->alphaGradU / neohookean_ptr->eqScaling;
250
252 auto t_L = symm_L_tensor();
253
254 constexpr auto t_kd_sym = FTensor::Kronecker_Delta_symmetric<int>();
255 constexpr auto t_kd = FTensor::Kronecker_Delta<int>();
256
257 int nb_dofs = data.getIndices().size();
258 int nb_integration_pts = data.getN().size1();
259 auto v = getVolume();
260 auto t_w = getFTensor0IntegrationWeight();
261 auto t_approx_P_adjoint_log_du =
262 getFTensor1FromMat<size_symm>(dataAtPts->adjointPdUAtPts);
263 auto t_u = getFTensor2SymmetricFromMat<3>(dataAtPts->stretchTensorAtPts);
264 auto t_grad_h1 = getFTensor2FromMat<3, 3>(dataAtPts->wGradH1AtPts);
265 auto t_dot_log_u =
266 getFTensor2SymmetricFromMat<3>(dataAtPts->logStretchDotTensorAtPts);
267 auto t_diff_u =
268 getFTensor4DdgFromMat<3, 3, 1>(dataAtPts->diffStretchTensorAtPts);
269 auto t_log_u =
270 getFTensor2SymmetricFromMat<3>(dataAtPts->logStretchTensorAtPts);
271 auto t_grad_log_u =
272 getFTensor2FromMat<6, 3>(dataAtPts->gradLogStretchDotTensorAtPts);
273 auto t_log_u2_h1 =
274 getFTensor2SymmetricFromMat<3>(dataAtPts->logStretch2H1AtPts);
275
276 auto t_eigen_vals = getFTensor1FromMat<3>(dataAtPts->eigenVals);
277 auto t_eigen_vecs = getFTensor2FromMat<3, 3>(dataAtPts->eigenVecs);
278 auto &nbUniq = dataAtPts->nbUniq;
279 auto t_nb_uniq =
280 FTensor::Tensor0<FTensor::PackPtr<int *, 1>>(nbUniq.data().data());
281
282 auto t_diff = diff_tensor();
283
290
291 auto get_ftensor2 = [](auto &v) {
293 &v[0], &v[1], &v[2], &v[3], &v[4], &v[5]);
294 };
295
296 int nb_base_functions = data.getN().size2();
297 auto t_row_base_fun = data.getFTensor0N();
298 auto t_grad_base_fun = data.getFTensor1DiffN<3>();
299
300 auto no_h1 = [&]() {
302
303 for (int gg = 0; gg != nb_integration_pts; ++gg) {
304 double a = v * t_w;
305 ++t_w;
306
307 auto inv_f = [](auto v) { return EshelbianCore::f(-v); };
308 auto t_inv_u = EigenMatrix::getMat(t_eigen_vals, t_eigen_vecs, inv_f);
309 ++t_eigen_vals;
310 ++t_eigen_vecs;
311 ++t_nb_uniq;
312
314 t_Ldiff_u(i, j, L) = t_diff_u(i, j, k, l) * t_L(k, l, L);
315 ++t_diff_u;
316
318 t_Sigma_u(i, j) = 2.0 * c10 * (t_u(i, j) - t_inv_u(i, j));
319 const double tr = t_log_u(i, i);
320 const double Sigma_J = K * tr;
321
323 t_viscous_P(i, j) =
324 alpha_u * (t_dot_log_u(i, j) -
325 t_dot_log_u(k, l) * t_kd_sym(k, l) * t_kd_sym(i, j));
326
328 t_residual(L) = t_approx_P_adjoint_log_du(L);
329 t_residual(L) -= t_Ldiff_u(i, j, L) * t_Sigma_u(i, j);
330 t_residual(L) -= (t_L(i, j, L) * t_kd(i, j)) * Sigma_J;
331 t_residual(L) -= t_L(i, j, L) * t_viscous_P(i, j);
332 t_residual(L) *= a;
333
335 t_grad_residual(L, i) = alpha_grad_u * t_grad_log_u(L, i);
336 t_grad_residual(L, i) *= a;
337
338 ++t_approx_P_adjoint_log_du;
339 ++t_u;
340 ++t_log_u;
341 ++t_dot_log_u;
342 ++t_grad_log_u;
343
344 auto t_nf = getFTensor1FromPtr<size_symm>(&*nF.data().begin());
345 int bb = 0;
346 for (; bb != nb_dofs / size_symm; ++bb) {
347 t_nf(L) -= t_row_base_fun * t_residual(L);
348 t_nf(L) += t_grad_base_fun(i) * t_grad_residual(L, i);
349 ++t_nf;
350 ++t_row_base_fun;
351 ++t_grad_base_fun;
352 }
353 for (; bb != nb_base_functions; ++bb) {
354 ++t_row_base_fun;
355 ++t_grad_base_fun;
356 }
357 }
358
360 };
361
362 auto large = [&]() {
364
365 for (int gg = 0; gg != nb_integration_pts; ++gg) {
366 double a = v * t_w;
367 ++t_w;
368
371 t_h1(i, j) = t_grad_h1(i, j) + t_kd(i, j);
372 t_Ldiff_u(i, j, L) = (t_diff_u(i, m, k, l) * t_h1(m, j)) * t_L(k, l, L);
373 ++t_diff_u;
374 ++t_grad_h1;
375
377 const double tr_h1 = t_log_u2_h1(i, j) * t_kd_sym(i, j) / 2;
378 const double tr_u = t_log_u(i, j) * t_kd_sym(i, j);
379 const double tr = tr_h1 + tr_u;
380
382 t_total_u(i, j) = t_u(i, m) * t_h1(m, j);
383#ifndef NEOHOOKEAN_OFF_INVERSE
385 invertTensor3by3(t_total_u, J, t_inv_total_u);
386#endif // NEOHOOKEAN_OFF_INVERSE
387
388#ifndef NEOHOOKEAN_OFF_INVERSE
389 t_Sigma_u(i, j) = 2.0 * c10 * (t_total_u(i, j) - t_inv_total_u(i, j));
390#else
391 t_Sigma_u(i, j) = 2.0 * c10 * t_total_u(i, j);
392#endif // NEOHOOKEAN_OFF_INVERSE
393
394#ifndef NEOHOOKEAN_OFF_INVERSE
395 const double Sigma_J = K * tr;
396#else
397 const double Sigma_J = K * (tr - 2.0 * c10 / K);
398#endif // NEOHOOKEAN_OFF_INVERSE
399
401 t_viscous_P(i, j) =
402 alpha_u * (t_dot_log_u(i, j) -
403 t_dot_log_u(k, l) * t_kd_sym(k, l) * t_kd_sym(i, j));
404
406 t_residual(L) = t_approx_P_adjoint_log_du(L);
407 t_residual(L) -= t_Ldiff_u(i, j, L) * t_Sigma_u(i, j);
408 t_residual(L) -= (t_L(i, j, L) * t_kd(i, j)) * Sigma_J;
409 t_residual(L) -= t_L(i, j, L) * t_viscous_P(i, j);
410 t_residual(L) *= a;
411
413 t_grad_residual(L, i) = alpha_grad_u * t_grad_log_u(L, i);
414 t_grad_residual(L, i) *= a;
415
416 ++t_approx_P_adjoint_log_du;
417 ++t_u;
418 ++t_log_u;
419 ++t_log_u2_h1;
420 ++t_dot_log_u;
421 ++t_grad_log_u;
422
423 auto t_nf = getFTensor1FromPtr<size_symm>(&*nF.data().begin());
424 int bb = 0;
425 for (; bb != nb_dofs / size_symm; ++bb) {
426 t_nf(L) -= t_row_base_fun * t_residual(L);
427 t_nf(L) += t_grad_base_fun(i) * t_grad_residual(L, i);
428 ++t_nf;
429 ++t_row_base_fun;
430 ++t_grad_base_fun;
431 }
432 for (; bb != nb_base_functions; ++bb) {
433 ++t_row_base_fun;
434 ++t_grad_base_fun;
435 }
436 }
437
439 };
440
443 CHKERR no_h1();
444 break;
445 case LARGE_ROT:
446 case MODERATE_ROT:
447 CHKERR large();
448 break;
449 default:
450 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
451 "gradApproximator not handled");
452 };
453
455}
456
458 std::string row_field, std::string col_field,
459 boost::shared_ptr<DataAtIntegrationPts> data_ptr, const double alpha)
460 : OpAssembleVolumePositiveDefine(row_field, col_field, data_ptr, OPROWCOL,
461 false),
462 alphaU(alpha) {
463 sYmm = false;
464}
465
466MoFEMErrorCode
468 EntData &col_data) {
470
471 auto neohookean_ptr =
472 boost::dynamic_pointer_cast<HMHNeohookean>(dataAtPts->physicsPtr);
473 if (!neohookean_ptr) {
474 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
475 "Pointer to HMHNeohookean is null");
476 }
477 auto [def_c10, def_K] =
478 neohookean_ptr->getMaterialParameters(getFEEntityHandle());
479
480 double c10 = def_c10 / neohookean_ptr->eqScaling;
481 double alpha_u = alphaU / neohookean_ptr->eqScaling;
482 double lambda = def_K / neohookean_ptr->eqScaling;
483
484 double alpha_grad_u = neohookean_ptr->alphaGradU / neohookean_ptr->eqScaling;
485
488
489 constexpr auto t_kd_sym = FTensor::Kronecker_Delta_symmetric<int>();
490 constexpr auto t_kd = FTensor::Kronecker_Delta<int>();
491
492 auto t_L = symm_L_tensor();
493 auto t_diff = diff_tensor();
494
495 int nb_integration_pts = row_data.getN().size1();
496 int row_nb_dofs = row_data.getIndices().size();
497 int col_nb_dofs = col_data.getIndices().size();
498
499 auto get_ftensor2 = [](MatrixDouble &m, const int r, const int c) {
501 size_symm>(
502
503 &m(r + 0, c + 0), &m(r + 0, c + 1), &m(r + 0, c + 2), &m(r + 0, c + 3),
504 &m(r + 0, c + 4), &m(r + 0, c + 5),
505
506 &m(r + 1, c + 0), &m(r + 1, c + 1), &m(r + 1, c + 2), &m(r + 1, c + 3),
507 &m(r + 1, c + 4), &m(r + 1, c + 5),
508
509 &m(r + 2, c + 0), &m(r + 2, c + 1), &m(r + 2, c + 2), &m(r + 2, c + 3),
510 &m(r + 2, c + 4), &m(r + 2, c + 5),
511
512 &m(r + 3, c + 0), &m(r + 3, c + 1), &m(r + 3, c + 2), &m(r + 3, c + 3),
513 &m(r + 3, c + 4), &m(r + 3, c + 5),
514
515 &m(r + 4, c + 0), &m(r + 4, c + 1), &m(r + 4, c + 2), &m(r + 4, c + 3),
516 &m(r + 4, c + 4), &m(r + 4, c + 5),
517
518 &m(r + 5, c + 0), &m(r + 5, c + 1), &m(r + 5, c + 2), &m(r + 5, c + 3),
519 &m(r + 5, c + 4), &m(r + 5, c + 5)
520
521 );
522 };
523
530
531 auto v = getVolume();
532 auto ts_a = getTSa();
533 auto t_w = getFTensor0IntegrationWeight();
534
535 int row_nb_base_functions = row_data.getN().size2();
536 auto t_row_base_fun = row_data.getFTensor0N();
537 auto t_row_grad_fun = row_data.getFTensor1DiffN<3>();
538
539 auto t_grad_h1 = getFTensor2FromMat<3, 3>(dataAtPts->wGradH1AtPts);
540 auto t_diff_u =
541 getFTensor4DdgFromMat<3, 3, 1>(dataAtPts->diffStretchTensorAtPts);
542 auto t_log_u =
543 getFTensor2SymmetricFromMat<3>(dataAtPts->logStretchTensorAtPts);
544 auto t_log_u2_h1 =
545 getFTensor2SymmetricFromMat<3>(dataAtPts->logStretch2H1AtPts);
546 auto t_u = getFTensor2SymmetricFromMat<3>(dataAtPts->stretchTensorAtPts);
547 auto t_approx_P_adjoint_dstretch =
548 getFTensor2FromMat<3, 3>(dataAtPts->adjointPdstretchAtPts);
549 auto t_eigen_vals = getFTensor1FromMat<3>(dataAtPts->eigenVals);
550 auto t_eigen_vecs = getFTensor2FromMat<3, 3>(dataAtPts->eigenVecs);
551 auto &nbUniq = dataAtPts->nbUniq;
552 auto t_nb_uniq =
553 FTensor::Tensor0<FTensor::PackPtr<int *, 1>>(nbUniq.data().data());
554
555 auto no_h1 = [&]() {
557
558 for (int gg = 0; gg != nb_integration_pts; ++gg) {
559 double a = v * t_w;
560 ++t_w;
561
563 t_Ldiff_u(i, j, L) = t_diff_u(i, j, k, l) * t_L(k, l, L);
564 ++t_diff_u;
565
566 const double tr = t_log_u(i, i);
567 const double det_u = EshelbianCore::f(tr);
568 ++t_log_u;
569
570 auto inv_f = [](auto v) { return EshelbianCore::f(-v); };
571 auto inv_d_f = [](auto v) { return -EshelbianCore::d_f(-v); };
572 auto t_inv_u = EigenMatrix::getMat(t_eigen_vals, t_eigen_vecs, inv_f);
573 auto t_diff_inv_u = EigenMatrix::getDiffMat(t_eigen_vals, t_eigen_vecs,
574 inv_f, inv_d_f, t_nb_uniq);
576 t_Ldiff_inv_u(i, j, L) = t_diff_inv_u(i, j, k, l) * t_L(k, l, L);
577
579 Sigma_J_dtr(L) = lambda * (t_kd(i, j) * t_L(i, j, L));
580
582 t_dP(L, J) =
583 (-2.0 * c10) *
584 (t_Ldiff_u(i, j, L) * (t_Ldiff_u(i, j, J) - t_Ldiff_inv_u(i, j, J)));
585 t_dP(L, J) -= (t_L(i, j, L) * t_kd(i, j)) * Sigma_J_dtr(J);
586 t_dP(L, J) -= (alpha_u * ts_a) *
587 (t_L(i, j, L) * (t_diff(i, j, k, l) * t_L(k, l, J) -
588 (t_diff(m, n, k, l) * t_kd_sym(m, n)) *
589 t_kd_sym(i, j) * t_L(k, l, J)));
590
592 t_Sigma_u(i, j) = 2.0 * c10 * (t_u(i, j) - t_inv_u(i, j));
593 ++t_u;
594
595 if constexpr (1) {
597 t_deltaP(i, j) = (t_approx_P_adjoint_dstretch(i, j) ||
598 t_approx_P_adjoint_dstretch(i, j)) /
599 2. -
600 t_Sigma_u(i, j);
601 auto t_diff2_uP = EigenMatrix::getDiffDiffMat(
602 t_eigen_vals, t_eigen_vecs, EshelbianCore::f, EshelbianCore::d_f,
603 EshelbianCore::dd_f, t_deltaP, t_nb_uniq);
604 t_dP(L, J) += t_L(i, j, L) * (t_diff2_uP(i, j, k, l) * t_L(k, l, J));
605 }
606 ++t_approx_P_adjoint_dstretch;
607 ++t_eigen_vals;
608 ++t_eigen_vecs;
609 ++t_nb_uniq;
610
611 int rr = 0;
612 for (; rr != row_nb_dofs / size_symm; ++rr) {
613 auto t_col_base_fun = col_data.getFTensor0N(gg, 0);
614 auto t_col_grad_fun = col_data.getFTensor1DiffN<3>(gg, 0);
615
616 auto t_m = get_ftensor2(K, 6 * rr, 0);
617 for (int cc = 0; cc != col_nb_dofs / size_symm; ++cc) {
618 double b = a * t_row_base_fun * t_col_base_fun;
619 double c = (a * alpha_grad_u * ts_a) *
620 (t_row_grad_fun(i) * t_col_grad_fun(i));
621 t_m(L, J) -= b * t_dP(L, J);
622 t_m(L, J) += c * t_kd_sym(L, J);
623
624 ++t_m;
625 ++t_col_base_fun;
626 ++t_col_grad_fun;
627 }
628 ++t_row_base_fun;
629 ++t_row_grad_fun;
630 }
631
632 for (; rr != row_nb_base_functions; ++rr) {
633 ++t_row_base_fun;
634 ++t_row_grad_fun;
635 }
636
637 }
639 };
640
641 auto large = [&]() {
643
644 for (int gg = 0; gg != nb_integration_pts; ++gg) {
645 double a = v * t_w;
646 ++t_w;
647
650
653 t_h1(i, j) = t_kd(i, j);
654 t_Ldiff_u(i, j, L) = t_diff_u(i, j, k, l) * t_L(k, l, L);
655 break;
656 case LARGE_ROT:
657 case MODERATE_ROT:
658 t_h1(i, j) = t_grad_h1(i, j) + t_kd(i, j);
659 t_Ldiff_u(i, j, L) = (t_diff_u(i, m, k, l) * t_h1(m, j)) * t_L(k, l, L);
660 break;
661 default:
662 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
663 "gradApproximator not handled");
664 };
665 ++t_diff_u;
666 ++t_grad_h1;
667
668 const double tr_h1 = t_log_u2_h1(i, j) * t_kd_sym(i, j) / 2;
669 const double tr_u = t_log_u(i, j) * t_kd_sym(i, j);
670 const double tr = tr_h1 + tr_u;
671 const double det_u = EshelbianCore::f(tr);
672 ++t_log_u;
673 ++t_log_u2_h1;
674
676 Sigma_J_dtr(L) = lambda * (t_kd(i, j) * t_L(i, j, L));
677
679 t_total_u(i, j) = t_u(i, m) * t_h1(m, j);
680#ifndef NEOHOOKEAN_OFF_INVERSE
682 invertTensor3by3(t_total_u, det_u, t_inv_total_u);
683#endif // NEOHOOKEAN_OFF_INVERSE
684 ++t_u;
685
687#ifndef NEOHOOKEAN_OFF_INVERSE
689 t_Sigma_u_du(i, j, J) = t_Ldiff_u(i, j, J) + t_inv_total_u(i, k) *
690 t_Ldiff_u(k, l, J) *
691 t_inv_total_u(l, j);
692 t_dP(L, J) = (-2.0 * c10) * (t_Ldiff_u(i, j, L) * t_Sigma_u_du(i, j, J));
693#else
694 t_dP(L, J) = (-2.0 * c10) * (t_Ldiff_u(i, j, L) * t_Ldiff_u(i, j, J));
695#endif // NEOHOOKEAN_OFF_INVERSE
696
697 t_dP(L, J) -= (t_L(i, j, L) * t_kd(i, j)) * Sigma_J_dtr(J);
698 t_dP(L, J) -= (alpha_u * ts_a) *
699 (t_L(i, j, L) * (t_diff(i, j, k, l) * t_L(k, l, J) -
700 (t_diff(m, n, k, l) * t_kd_sym(m, n)) *
701 t_kd_sym(i, j) * t_L(k, l, J)));
702
704#ifndef NEOHOOKEAN_OFF_INVERSE
705 t_Sigma_u(i, j) = 2.0 * c10 * (t_total_u(i, j) - t_inv_total_u(i, j));
706#else
707 t_Sigma_u(i, j) = 2.0 * c10 * t_total_u(i, j);
708#endif // NEOHOOKEAN_OFF_INVERSE
709
712 case LARGE_ROT:
713 t_deltaP(i, j) =
714 t_approx_P_adjoint_dstretch(i, j) - t_h1(j, n) * t_Sigma_u(i, n);
715 break;
716 case MODERATE_ROT:
717 t_deltaP(i, j) = -t_h1(j, n) * t_Sigma_u(i, n);
718 break;
719 default:
720 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
721 "gradApproximator not handled");
722 };
723 ++t_approx_P_adjoint_dstretch;
724
725 if constexpr (1) {
727 t_deltaP_sym(i, j) = (t_deltaP(i, j) || t_deltaP(j, i));
728 t_deltaP_sym(i, j) /= 2.0;
729 auto t_diff2_uP2 = EigenMatrix::getDiffDiffMat(
730 t_eigen_vals, t_eigen_vecs, EshelbianCore::f, EshelbianCore::d_f,
731 EshelbianCore::dd_f, t_deltaP_sym, nbUniq[gg]);
732 t_dP(L, J) += t_L(i, j, L) * (t_diff2_uP2(i, j, k, l) * t_L(k, l, J));
733 }
734 ++t_eigen_vals;
735 ++t_eigen_vecs;
736
737 int rr = 0;
738 for (; rr != row_nb_dofs / size_symm; ++rr) {
739 auto t_col_base_fun = col_data.getFTensor0N(gg, 0);
740 auto t_col_grad_fun = col_data.getFTensor1DiffN<3>(gg, 0);
741
742 auto t_m = get_ftensor2(K, 6 * rr, 0);
743 for (int cc = 0; cc != col_nb_dofs / size_symm; ++cc) {
744 double b = a * t_row_base_fun * t_col_base_fun;
745 double c = (a * alpha_grad_u * ts_a) *
746 (t_row_grad_fun(i) * t_col_grad_fun(i));
747 t_m(L, J) -= b * t_dP(L, J);
748 t_m(L, J) += c * t_kd_sym(L, J);
749
750 ++t_m;
751 ++t_col_base_fun;
752 ++t_col_grad_fun;
753 }
754 ++t_row_base_fun;
755 ++t_row_grad_fun;
756 }
757
758 for (; rr != row_nb_base_functions; ++rr) {
759 ++t_row_base_fun;
760 ++t_row_grad_fun;
761 }
762
763 }
765 };
766
769 CHKERR no_h1();
770 break;
771 case LARGE_ROT:
772 case MODERATE_ROT:
773 CHKERR large();
774 break;
775 default:
776 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
777 "gradApproximator not handled");
778 };
779
781}
782
783} // namespace EshelbianPlasticity
#define MOFEM_TAG_AND_LOG(channel, severity, tag)
Tag and log in channel.
#define FTENSOR_INDEX(DIM, I)
constexpr double a
constexpr int SPACE_DIM
Kronecker Delta class symmetric.
Kronecker Delta class.
#define CHK_THROW_MESSAGE(err, msg)
Check and throw MoFEM exception.
@ 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.
constexpr auto t_kd
#define MOFEM_LOG(channel, severity)
Log.
#define MOFEM_LOG_CHANNEL(channel)
Set and reset channel.
FTensor::Index< 'i', SPACE_DIM > i
static double lambda
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
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.
static constexpr auto size_symm
constexpr auto field_name
FTensor::Index< 'm', 3 > m
static enum StretchSelector stretchSelector
static enum RotSelector gradApproximator
static double exponentBase
static boost::function< double(const double)> f
static boost::function< double(const double)> dd_f
static boost::function< double(const double)> d_f
OpGetScale(boost::shared_ptr< double > scale_ptr, boost::shared_ptr< PhysicalEquations > physics_ptr)
boost::shared_ptr< PhysicalEquations > physicsPtr
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
OpSpatialPhysical_du_du(std::string row_field, std::string col_field, boost::shared_ptr< DataAtIntegrationPts > data_ptr, const double alpha)
MoFEMErrorCode integrate(EntData &row_data, EntData &col_data)
OpSpatialPhysical(const std::string &field_name, boost::shared_ptr< DataAtIntegrationPts > data_ptr, const double alpha_u)
virtual EshelbianPlasticity::OpJacobian * returnOpJacobian(const int tag, const bool eval_rhs, const bool eval_lhs, boost::shared_ptr< DataAtIntegrationPts > data_ptr, boost::shared_ptr< PhysicalEquations > physics_ptr)
virtual VolUserDataOperator * returnOpSpatialPhysical(const std::string &field_name, boost::shared_ptr< DataAtIntegrationPts > data_ptr, const double alpha_u)
std::vector< BlockData > blockData
MoFEMErrorCode extractBlockData(std::vector< const CubitMeshSets * > meshset_vec_ptr, Sev sev)
MoFEMErrorCode extractBlockData(Sev sev)
static constexpr int numberOfDependentVariables
VolUserDataOperator * returnOpSetScale(boost::shared_ptr< double > scale_ptr, boost::shared_ptr< PhysicalEquations > physics_ptr)
auto getMaterialParameters(EntityHandle ent)
static constexpr int numberOfActiveVariables
HMHNeohookean(MoFEM::Interface &m_field, const double c10, const double K)
VolUserDataOperator * returnOpSpatialPhysical_du_du(std::string row_field, std::string col_field, boost::shared_ptr< DataAtIntegrationPts > data_ptr, const double alpha)
MoFEMErrorCode recordTape(const int tape, DTensor2Ptr *t_h_ptr)
virtual moab::Interface & get_moab()=0
bool sYmm
If true assume that matrix is symmetric structure.
Deprecated interface functions.
Data on single entity (This is passed as argument to DataOperator::doWork)
FTensor::Tensor1< FTensor::PackPtr< double *, Tensor_Dim >, Tensor_Dim > getFTensor1DiffN(const FieldApproximationBase base)
Get derivatives of base functions.
FTensor::Tensor0< FTensor::PackPtr< double *, 1 > > getFTensor0N(const FieldApproximationBase base)
Get base function as Tensor0.
MatrixDouble & getN(const FieldApproximationBase base)
get base functions this return matrix (nb. of rows is equal to nb. of Gauss pts, nb....
const VectorInt & getIndices() const
Get global indices of dofs on entity.
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.