v0.15.4
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_SCALING
14
15 /**
16 * @brief Definition of Neo-hookean function
17 *
18 * P(i, I) = 2. * c10_default * (tF(i, I) - tInvF(i, I)) +
19 * K_default * log(detF) * tInvF(i, I)
20 * tCof(i, I) = detF * tInvF(I, i)
21 * Psi = c10* (trace(tCof) + 2ln(det(F)) - 3) + (K/2.) * (log(detF))^2
22 *
23 * @param c10
24 * @param v
25 * @return double
26 */
27 static inline double fun_neohookean(double c10, double v) {
28 return (2.0 * c10) * (-1. + EshelbianCore::f(2 * v));
29 }
30
31 /**
32 * @brief Definition of derivative of Neo-hookean function
33 *
34 * @param c10
35 * @param v
36 * @return * double
37 */
38 static inline double fun_d_neohookean(double c10, double v) {
39 return
40
41 (4.0 * c10) * EshelbianCore::d_f(2 * v);
42 }
43
44 /**
45 * @brief Definition of axiator of Neo-hookean function
46 *
47 * Psi = (K/2.) * (log(J))^2 = (K/2.) * (log(exp tr H))^2 = (K/2.) * (tr H)^2
48 *
49 * @param c10
50 * @param v
51 * @return double
52 */
53 static inline double fun_neohookean_bulk(double K, double tr) {
54 return K * tr;
55 }
56
57 /**
58 * @brief Definition of derivative of axiator of Neo-hookean function
59 *
60 * @param K
61 * @param tr
62 * @return double
63 */
64 static inline double fun_diff_neohookean_bulk(double K, double tr) {
65 return K;//K * exp(tr) * (1. + tr); // K*2*ln(J)/J
66 }
67
68 static constexpr int numberOfActiveVariables = 9;
69 static constexpr int numberOfDependentVariables = 9;
70
71 HMHNeohookean(MoFEM::Interface &m_field, const double c10, const double K)
73 mField(m_field), c10_default(c10), K_default(K) {
74
75 CHK_THROW_MESSAGE(getOptions(), "get options failed");
77 "extract block data failed");
78
79#ifdef NEOHOOKEAN_SCALING
80 if (blockData.size()) {
81 double ave_K = 0;
82 for (auto b : blockData) {
83 ave_K += b.K;
84 }
85 eqScaling = ave_K / blockData.size();
86 }
87#endif
88
89 MOFEM_LOG("EP", Sev::inform) << "Neo-Hookean scaling = " << eqScaling;
90
91 if (adolCOn == PETSC_FALSE) {
94 "Stretch selector is not equal to LOG");
95 } else {
96 if (EshelbianCore::exponentBase != exp(1)) {
98 "Exponent base is not equal to exp(1)");
99 }
100 }
101 }
102 }
103
105 for (auto &b : blockData) {
106 if (b.blockEnts.find(ent) != b.blockEnts.end()) {
107 return std::make_pair(b.c10, b.K);
108 }
109 }
110 if (blockData.size() != 0)
112 "Block not found for entity handle. If you mat set "
113 "block, set it to all elements");
114 return std::make_pair(c10_default, K_default);
115 }
116
118 OpGetScale(boost::shared_ptr<double> scale_ptr,
119 boost::shared_ptr<PhysicalEquations> physics_ptr)
121 scalePtr(scale_ptr), physicsPtr(physics_ptr) {}
122
123 MoFEMErrorCode doWork(int side, EntityType type,
124 EntitiesFieldData::EntData &data) {
126 auto neohookean_ptr =
127 boost::dynamic_pointer_cast<HMHNeohookean>(physicsPtr);
128 *(scalePtr) = neohookean_ptr->eqScaling;
130 }
131
132 private:
133 boost::shared_ptr<double> scalePtr;
134 boost::shared_ptr<PhysicalEquations> physicsPtr;
135 };
136
138 returnOpSetScale(boost::shared_ptr<double> scale_ptr,
139 boost::shared_ptr<PhysicalEquations> physics_ptr) {
140
141 return new OpGetScale(scale_ptr, physics_ptr);
142 };
143
144 struct OpJacobian : public EshelbianPlasticity::OpJacobian {
145 using EshelbianPlasticity::OpJacobian::OpJacobian;
146 MoFEMErrorCode evaluateRhs(EntData &data) { return 0; }
147 MoFEMErrorCode evaluateLhs(EntData &data) { return 0; }
148 };
149
151 returnOpJacobian(const int tag, const bool eval_rhs, const bool eval_lhs,
152 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
153 boost::shared_ptr<PhysicalEquations> physics_ptr) {
154 if (adolCOn) {
155 return PhysicalEquations::returnOpJacobian(tag, eval_rhs, eval_lhs,
156 data_ptr, physics_ptr);
157 } else {
158 return (new OpJacobian(tag, eval_rhs, eval_lhs, data_ptr, physics_ptr));
159 }
160 }
161
162 MoFEMErrorCode getOptions() {
164 PetscOptionsBegin(PETSC_COMM_WORLD, "neo_hookean_", "", "none");
165
166 c10_default = 1;
167 CHKERR PetscOptionsScalar("-c10", "C10", "", c10_default, &c10_default,
168 PETSC_NULLPTR);
169 K_default = 1;
170 CHKERR PetscOptionsScalar("-K", "Bulk modulus K", "", K_default, &K_default,
171 PETSC_NULLPTR);
172
173 alphaGradU = 0;
174 CHKERR PetscOptionsScalar("-viscosity_alpha_grad_u", "viscosity", "",
175 alphaGradU, &alphaGradU, PETSC_NULLPTR);
176
177 CHKERR PetscOptionsBool("-adolc_on", "adolc ON", "", adolCOn, &adolCOn,
178 PETSC_NULLPTR);
179
180 PetscOptionsEnd();
181
182 MOFEM_LOG_CHANNEL("WORLD");
183 MOFEM_TAG_AND_LOG("WORLD", Sev::inform, "MatBlock Neo-Hookean (default)")
184 << "c10 = " << c10_default << " K = " << K_default
185 << " grad alpha u = " << alphaGradU;
186 MOFEM_TAG_AND_LOG("WORLD", Sev::inform, "MatBlock Neo-Hookean (default)")
187 << "ADOL-C On " << (adolCOn)
188 ? "Yes"
189 : "No";
191 }
192
193 MoFEMErrorCode extractBlockData(Sev sev) {
194 return extractBlockData(
195
196 mField.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(std::regex(
197
198 (boost::format("%s(.*)") % "MAT_NEOHOOKEAN").str()
199
200 )),
201
202 sev);
203 }
204
205 MoFEMErrorCode
206 extractBlockData(std::vector<const CubitMeshSets *> meshset_vec_ptr,
207 Sev sev) {
209
210 for (auto m : meshset_vec_ptr) {
211 MOFEM_LOG("EP", sev) << *m;
212 std::vector<double> block_data;
213 CHKERR m->getAttributes(block_data);
214 if (block_data.size() < 2) {
215 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
216 "Expected that block has atleast two attributes");
217 }
218 auto get_block_ents = [&]() {
219 Range ents;
220 CHKERR mField.get_moab().get_entities_by_handle(m->meshset, ents, true);
221 return ents;
222 };
223
224 double c10 = block_data[0];
225 double K = block_data[1];
226
227 blockData.push_back({c10, K, get_block_ents()});
228
229 MOFEM_LOG("EP", sev) << "MatBlock Neo-Hookean c10 = "
230 << blockData.back().c10
231 << " K = " << blockData.back().K << " nb ents. = "
232 << blockData.back().blockEnts.size();
233 }
235 }
236
237 MoFEMErrorCode recordTape(const int tape, DTensor2Ptr *t_h_ptr) {
239
240 FTENSOR_INDEX(3, i);
241 FTENSOR_INDEX(3, j);
242 FTENSOR_INDEX(3, I);
243 FTENSOR_INDEX(3, J);
244
245 auto large = [&]() {
247
248 constexpr auto t_kd = FTensor::Kronecker_Delta<int>();
249
250 auto ih = get_h();
251 if (t_h_ptr)
252 ih(i, j) = (*t_h_ptr)(i, j);
253 else {
254 ih(i, j) = t_kd(i, j);
255 }
256
257 auto r_P = get_P();
258
259 enableMinMaxUsingAbs();
260 trace_on(tape);
261
262 // Set active variables to ADOL-C
263 th(i, j) <<= get_h()(i, j);
264
265 tF(i, I) = th(i, I);
266 CHKERR determinantTensor3by3(tF, detF);
267 CHKERR invertTensor3by3(tF, detF, tInvF);
268
269 // tCof(i, I) = detF * tInvF(I, i);
270
271 // Psi = c10* (trace(tCof) + 2ln(det(F)) - 3) + (K/2.) * (log(detF))^2;
272
273 tP(i, I) = 2. * c10_default * (tF(i, I) - tInvF(i, I)) +
274 K_default * log(detF) * tInvF(i, I);
275
276 // Set dependent variables to ADOL-C
277 tP(i, j) >>= r_P(i, j);
278
279 trace_off();
280
282 };
283
286 case LARGE_ROT:
287 case MODERATE_ROT:
288 CHKERR large();
289 break;
290 default:
291 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
292 "gradApproximator not handled");
293 };
294
296 }
297
299
300 OpSpatialPhysical(const std::string &field_name,
301 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
302 const double alpha_u);
303
304 MoFEMErrorCode integrate(EntData &data);
305
306 private:
307 const double alphaU;
308 };
309
310 virtual VolUserDataOperator *
312 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
313 const double alpha_u) {
314 if (adolCOn) {
316 alpha_u);
317 } else {
318 return new OpSpatialPhysical(field_name, data_ptr, alpha_u);
319 }
320 }
321
323
325 const std::string &field_name,
326 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
327 boost::shared_ptr<ExternalStrainVec> external_strain_vec_ptr,
328 std::map<std::string, boost::shared_ptr<ScalingMethod>> smv);
329
330 MoFEMErrorCode integrate(EntData &data);
331
332 private:
333 boost::shared_ptr<ExternalStrainVec> externalStrainVecPtr;
334 std::map<std::string, boost::shared_ptr<ScalingMethod>> scalingMethodsMap;
335 };
336
338 const std::string &field_name,
339 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
340 boost::shared_ptr<ExternalStrainVec> external_strain_vec_ptr,
341 std::map<std::string, boost::shared_ptr<ScalingMethod>> smv) {
342 return new OpSpatialPhysicalExternalStrain(field_name, data_ptr,
343 external_strain_vec_ptr, smv);
344 }
345
347 OpSpatialPhysical_du_du(std::string row_field, std::string col_field,
348 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
349 const double alpha);
350 MoFEMErrorCode integrate(EntData &row_data, EntData &col_data);
351
352 private:
353 const double alphaU;
354 };
355
357 std::string row_field, std::string col_field,
358 boost::shared_ptr<DataAtIntegrationPts> data_ptr, const double alpha) {
359 if (adolCOn) {
361 row_field, col_field, data_ptr, alpha);
362 } else {
363 return new OpSpatialPhysical_du_du(row_field, col_field, data_ptr, alpha);
364 }
365 }
366
367private:
369
371 double K_default;
373 struct BlockData {
374 double c10;
375 double K;
377 };
378 std::vector<BlockData> blockData;
379
380 double eqScaling = 1.;
381
382 // ADOL-C
383 PetscBool adolCOn = PETSC_FALSE;
384
391};
392
394 const std::string &field_name,
395 boost::shared_ptr<DataAtIntegrationPts> data_ptr, const double alpha_u)
396 : OpAssembleVolume(field_name, data_ptr, OPROW), alphaU(alpha_u) {}
397
398extern "C" {
399void tetcircumcenter_tp(double a[3], double b[3], double c[3], double d[3],
400 double circumcenter[3], double *xi, double *eta,
401 double *zeta);
402}
403
406
407 auto neohookean_ptr =
408 boost::dynamic_pointer_cast<HMHNeohookean>(dataAtPts->physicsPtr);
409 if (!neohookean_ptr) {
410 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
411 "Pointer to HMHNeohookean is null");
412 }
413 auto [def_c10, def_K] =
414 neohookean_ptr->getMaterialParameters(getFEEntityHandle());
415
416 double c10 = def_c10 / neohookean_ptr->eqScaling;
417 double alpha_u = alphaU / neohookean_ptr->eqScaling;
418 double K = def_K / neohookean_ptr->eqScaling;
419
420 auto time_step = getTStimeStep();
421 double alpha_grad_u =
422 neohookean_ptr->alphaGradU / neohookean_ptr->eqScaling;// / time_step;
423
425 auto t_L = symm_L_tensor();
426
427 constexpr auto t_kd_sym = FTensor::Kronecker_Delta_symmetric<int>();
428 constexpr auto t_kd = FTensor::Kronecker_Delta<int>();
429
430 int nb_dofs = data.getIndices().size();
431 int nb_integration_pts = data.getN().size1();
432 auto v = getVolume();
433 auto t_w = getFTensor0IntegrationWeight();
434 auto t_approx_P_adjoint_log_du =
435 getFTensor1FromMat<size_symm>(dataAtPts->adjointPdUAtPts);
436 auto t_u = getFTensor2SymmetricFromMat<3>(dataAtPts->stretchTensorAtPts);
437 auto t_grad_h1 = getFTensor2FromMat<3, 3>(dataAtPts->wGradH1AtPts);
438 auto t_dot_log_u =
439 getFTensor2SymmetricFromMat<3>(dataAtPts->logStretchDotTensorAtPts);
440 auto t_diff_u =
441 getFTensor4DdgFromMat<3, 3, 1>(dataAtPts->diffStretchTensorAtPts);
442 auto t_log_u =
443 getFTensor2SymmetricFromMat<3>(dataAtPts->logStretchTensorAtPts);
444 auto t_grad_log_u =
445 getFTensor2FromMat<6, 3>(dataAtPts->gradLogStretchDotTensorAtPts);
446 auto t_log_u2_h1 =
447 getFTensor2SymmetricFromMat<3>(dataAtPts->logStretch2H1AtPts);
448
449 auto t_eigen_vals = getFTensor1FromMat<3>(dataAtPts->eigenVals);
450 auto t_eigen_vecs = getFTensor2FromMat<3, 3>(dataAtPts->eigenVecs);
451 auto &nbUniq = dataAtPts->nbUniq;
452 auto t_nb_uniq =
453 FTensor::Tensor0<FTensor::PackPtr<int *, 1>>(nbUniq.data().data());
454
455 auto t_diff = diff_tensor();
456
463
464 auto get_ftensor2 = [](auto &v) {
466 &v[0], &v[1], &v[2], &v[3], &v[4], &v[5]);
467 };
468
469 int nb_base_functions = data.getN().size2();
470 auto t_row_base_fun = data.getFTensor0N();
471 auto t_grad_base_fun = data.getFTensor1DiffN<3>();
472
473 auto no_h1 = [&]() {
475
476 for (int gg = 0; gg != nb_integration_pts; ++gg) {
477 double a = v * t_w;
478 ++t_w;
479
480 auto neohookean = [c10](auto v) { return fun_neohookean(c10, v); };
481 auto t_neohookean_hencky =
482 EigenMatrix::getMat(t_eigen_vals, t_eigen_vecs, neohookean);
483 ++t_eigen_vals;
484 ++t_eigen_vecs;
485 ++t_nb_uniq;
486
487 const double tr = t_log_u(i, i);
489 t_P(L) = t_L(i, j, L) * (t_neohookean_hencky(i, j) +
490 t_kd(i, j) * fun_neohookean_bulk(K, tr));
492 t_viscous_P(L) = alpha_u * (t_L(i, j, L) * t_dot_log_u(i, j));
493
495 t_residual(L) = t_approx_P_adjoint_log_du(L) - t_P(L) - t_viscous_P(L);
496 t_residual(L) *= a;
497
499 t_grad_residual(L, i) = alpha_grad_u * t_grad_log_u(L, i);
500 t_grad_residual(L, i) *= a;
501
502 ++t_approx_P_adjoint_log_du;
503 ++t_log_u;
504 ++t_dot_log_u;
505 ++t_grad_log_u;
506
507 auto t_nf = getFTensor1FromPtr<size_symm>(&*nF.data().begin());
508 int bb = 0;
509 for (; bb != nb_dofs / size_symm; ++bb) {
510 t_nf(L) -= t_row_base_fun * t_residual(L);
511 t_nf(L) += t_grad_base_fun(i) * t_grad_residual(L, i);
512 ++t_nf;
513 ++t_row_base_fun;
514 ++t_grad_base_fun;
515 }
516 for (; bb != nb_base_functions; ++bb) {
517 ++t_row_base_fun;
518 ++t_grad_base_fun;
519 }
520 }
521
523 };
524
525 auto large = [&]() {
527 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
528 "Not implemented for Neo-Hookean (used ADOL-C)");
530 };
531
534 CHKERR no_h1();
535 break;
536 case LARGE_ROT:
537 case MODERATE_ROT:
538 CHKERR large();
539 break;
540 default:
541 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
542 "gradApproximator not handled");
543 };
544
546}
547
549 const std::string &field_name,
550 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
551 boost::shared_ptr<ExternalStrainVec> external_strain_vec_ptr,
552 std::map<std::string, boost::shared_ptr<ScalingMethod>> smv)
553 : OpAssembleVolume(field_name, data_ptr, OPROW),
554 externalStrainVecPtr(external_strain_vec_ptr), scalingMethodsMap{smv} {}
555
556MoFEMErrorCode
559
560 auto neohookean_ptr =
561 boost::dynamic_pointer_cast<HMHNeohookean>(dataAtPts->physicsPtr);
562 if (!neohookean_ptr) {
563 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
564 "Pointer to HMHNeohookean is null");
565 }
566
567 double time = OpAssembleVolume::getFEMethod()->ts_t;
570 }
571 // get entity of tet
573 // iterate over all block data
574
575 for (auto &ext_strain_block : (*externalStrainVecPtr)) {
576 auto block_name = "(.*)ANALYTICAL_EXTERNALSTRAIN(.*)";
577 std::regex reg_name(block_name);
578 if (std::regex_match(ext_strain_block.blockName, reg_name)) {
579 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
580 "Analytical external strain not implemented for Neo-Hookean "
581 "material.");
582 }
583 // check if finite element entity is part of the EXTERNALSTRAIN block
584 if (ext_strain_block.ents.find(fe_ent) != ext_strain_block.ents.end()) {
585 double scale = 1;
586 if (scalingMethodsMap.find(ext_strain_block.blockName) !=
587 scalingMethodsMap.end()) {
588 scale *=
589 scalingMethodsMap.at(ext_strain_block.blockName)->getScale(time);
590 } else {
591 MOFEM_LOG("SELF", Sev::warning)
592 << "No scaling method found for " << ext_strain_block.blockName;
593 }
594
595 auto [def_c10, def_K] =
596 neohookean_ptr->getMaterialParameters(getFEEntityHandle());
597 double c10 = def_c10 / neohookean_ptr->eqScaling;
598 // get ExternalStrain block data
599 double external_strain_val = scale * ext_strain_block.val;
600 double K = ext_strain_block.bulkModulusK;
601
603 auto t_L = symm_L_tensor();
604 constexpr auto t_kd = FTensor::Kronecker_Delta<int>();
605
606 int nb_dofs = data.getIndices().size();
607 int nb_integration_pts = data.getN().size1();
608 auto v = getVolume();
609 auto t_w = getFTensor0IntegrationWeight();
610
617
618 int nb_base_functions = data.getN().size2();
619 auto t_row_base_fun = data.getFTensor0N();
620
621 const double tr = 3.0 * external_strain_val;
622 const double sigma_J = K * tr;
623
624 for (int gg = 0; gg != nb_integration_pts; ++gg) {
625 double a = v * t_w;
626 ++t_w;
627
629 t_residual(L) = 0.0;
630 t_residual(L) += (t_L(i, j, L) * t_kd(i, j)) * sigma_J;
631 t_residual(L) *= a;
632
633 auto t_nf = getFTensor1FromPtr<size_symm>(&*nF.data().begin());
634 int bb = 0;
635 for (; bb != nb_dofs / size_symm; ++bb) {
636 t_nf(L) -= t_row_base_fun * t_residual(L);
637 ++t_nf;
638 ++t_row_base_fun;
639 }
640 for (; bb != nb_base_functions; ++bb) {
641 ++t_row_base_fun;
642 }
643 }
644 }
645 }
647}
648
650 std::string row_field, std::string col_field,
651 boost::shared_ptr<DataAtIntegrationPts> data_ptr, const double alpha)
652 : OpAssembleVolumePositiveDefine(row_field, col_field, data_ptr, OPROWCOL,
653 false),
654 alphaU(alpha) {
655 sYmm = false;
656}
657
658MoFEMErrorCode
660 EntData &col_data) {
662
663 auto neohookean_ptr =
664 boost::dynamic_pointer_cast<HMHNeohookean>(dataAtPts->physicsPtr);
665 if (!neohookean_ptr) {
666 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
667 "Pointer to HMHNeohookean is null");
668 }
669 auto [def_c10, def_K] =
670 neohookean_ptr->getMaterialParameters(getFEEntityHandle());
671
672 double c10 = def_c10 / neohookean_ptr->eqScaling;
673 double alpha_u = alphaU / neohookean_ptr->eqScaling;
674 double lambda = def_K / neohookean_ptr->eqScaling;
675
676 auto time_step = getTStimeStep();
677 double alpha_grad_u =
678 neohookean_ptr->alphaGradU / neohookean_ptr->eqScaling;// / time_step;
679
682
683 constexpr auto t_kd_sym = FTensor::Kronecker_Delta_symmetric<int>();
684 constexpr auto t_kd = FTensor::Kronecker_Delta<int>();
685
686 auto t_L = symm_L_tensor();
687 auto t_diff = diff_tensor();
688
689 int nb_integration_pts = row_data.getN().size1();
690 int row_nb_dofs = row_data.getIndices().size();
691 int col_nb_dofs = col_data.getIndices().size();
692
693 auto get_ftensor2 = [](MatrixDouble &m, const int r, const int c) {
695 size_symm>(
696
697 &m(r + 0, c + 0), &m(r + 0, c + 1), &m(r + 0, c + 2), &m(r + 0, c + 3),
698 &m(r + 0, c + 4), &m(r + 0, c + 5),
699
700 &m(r + 1, c + 0), &m(r + 1, c + 1), &m(r + 1, c + 2), &m(r + 1, c + 3),
701 &m(r + 1, c + 4), &m(r + 1, c + 5),
702
703 &m(r + 2, c + 0), &m(r + 2, c + 1), &m(r + 2, c + 2), &m(r + 2, c + 3),
704 &m(r + 2, c + 4), &m(r + 2, c + 5),
705
706 &m(r + 3, c + 0), &m(r + 3, c + 1), &m(r + 3, c + 2), &m(r + 3, c + 3),
707 &m(r + 3, c + 4), &m(r + 3, c + 5),
708
709 &m(r + 4, c + 0), &m(r + 4, c + 1), &m(r + 4, c + 2), &m(r + 4, c + 3),
710 &m(r + 4, c + 4), &m(r + 4, c + 5),
711
712 &m(r + 5, c + 0), &m(r + 5, c + 1), &m(r + 5, c + 2), &m(r + 5, c + 3),
713 &m(r + 5, c + 4), &m(r + 5, c + 5)
714
715 );
716 };
717
724
725 auto v = getVolume();
726 auto ts_a = getTSa();
727 auto t_w = getFTensor0IntegrationWeight();
728
729 int row_nb_base_functions = row_data.getN().size2();
730 auto t_row_base_fun = row_data.getFTensor0N();
731 auto t_row_grad_fun = row_data.getFTensor1DiffN<3>();
732
733 auto t_grad_h1 = getFTensor2FromMat<3, 3>(dataAtPts->wGradH1AtPts);
734 auto t_diff_u =
735 getFTensor4DdgFromMat<3, 3, 1>(dataAtPts->diffStretchTensorAtPts);
736 auto t_log_u =
737 getFTensor2SymmetricFromMat<3>(dataAtPts->logStretchTensorAtPts);
738 auto t_log_u2_h1 =
739 getFTensor2SymmetricFromMat<3>(dataAtPts->logStretch2H1AtPts);
740 auto t_u = getFTensor2SymmetricFromMat<3>(dataAtPts->stretchTensorAtPts);
741 auto t_approx_P_adjoint__dstretch =
742 getFTensor2FromMat<3, 3>(dataAtPts->adjointPdstretchAtPts);
743 auto t_eigen_vals = getFTensor1FromMat<3>(dataAtPts->eigenVals);
744 auto t_eigen_vecs = getFTensor2FromMat<3, 3>(dataAtPts->eigenVecs);
745 auto &nbUniq = dataAtPts->nbUniq;
746 auto t_nb_uniq =
747 FTensor::Tensor0<FTensor::PackPtr<int *, 1>>(nbUniq.data().data());
748
749 auto no_h1 = [&]() {
751
752 for (int gg = 0; gg != nb_integration_pts; ++gg) {
753 double a = v * t_w;
754 ++t_w;
755
756 auto neohookean = [c10](auto v) { return fun_neohookean(c10, v); };
757 auto d_neohookean = [c10, lambda](auto v) {
758 return fun_d_neohookean(c10, v);
759 };
760
761 auto t_diff_neohookean = EigenMatrix::getDiffMat(
762 t_eigen_vals, t_eigen_vecs, neohookean, d_neohookean, t_nb_uniq);
763
764 const auto tr = t_log_u(i, i);
766 t_dP(L, J) = -t_L(i, j, L) * ((t_diff_neohookean(i, j, k, l) +
768 t_kd_sym(i, j) * t_kd_sym(k, l)) *
769 t_L(k, l, J));
770 t_dP(L, J) -= (alpha_u * ts_a) *
771 (t_L(i, j, L) * (t_diff(i, j, k, l) * t_L(k, l, J)));
772
773 if constexpr (1) {
775 t_deltaP(i, j) = (t_approx_P_adjoint__dstretch(i, j) ||
776 t_approx_P_adjoint__dstretch(j, i)) /
777 2.;
778 auto t_diff2_uP = EigenMatrix::getDiffDiffMat(
779 t_eigen_vals, t_eigen_vecs, EshelbianCore::f, EshelbianCore::d_f,
780 EshelbianCore::dd_f, t_deltaP, t_nb_uniq);
781 t_dP(L, J) += t_L(i, j, L) * (t_diff2_uP(i, j, k, l) * t_L(k, l, J));
782 }
783 ++t_approx_P_adjoint__dstretch;
784 ++t_log_u;
785 ++t_eigen_vals;
786 ++t_eigen_vecs;
787 ++t_nb_uniq;
788
789 int rr = 0;
790 for (; rr != row_nb_dofs / size_symm; ++rr) {
791 auto t_col_base_fun = col_data.getFTensor0N(gg, 0);
792 auto t_col_grad_fun = col_data.getFTensor1DiffN<3>(gg, 0);
793
794 auto t_m = get_ftensor2(K, 6 * rr, 0);
795 for (int cc = 0; cc != col_nb_dofs / size_symm; ++cc) {
796 double b = a * t_row_base_fun * t_col_base_fun;
797 double c = (a * alpha_grad_u * ts_a) *
798 (t_row_grad_fun(i) * t_col_grad_fun(i));
799 t_m(L, J) -= b * t_dP(L, J);
800 t_m(L, J) += c * t_kd_sym(L, J);
801
802 ++t_m;
803 ++t_col_base_fun;
804 ++t_col_grad_fun;
805 }
806 ++t_row_base_fun;
807 ++t_row_grad_fun;
808 }
809
810 for (; rr != row_nb_base_functions; ++rr) {
811 ++t_row_base_fun;
812 ++t_row_grad_fun;
813 }
814
815 }
817 };
818
819 auto large = [&]() {
821 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
822 "Not implemented for Neo-Hookean (used ADOL-C)");
824 };
825
828 CHKERR no_h1();
829 break;
830 case LARGE_ROT:
831 case MODERATE_ROT:
832 CHKERR large();
833 break;
834 default:
835 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
836 "gradApproximator not handled");
837 };
838
840}
841
842} // 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
@ 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.
constexpr auto t_kd
double eta
#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.
void tetcircumcenter_tp(double a[3], double b[3], double c[3], double d[3], double circumcenter[3], double *xi, double *eta, double *zeta)
ForcesAndSourcesCore::UserDataOperator UserDataOperator
static constexpr auto size_symm
constexpr IntegrationType I
constexpr auto field_name
FTensor::Index< 'm', 3 > m
static enum StretchSelector stretchSelector
static double dynamicTime
static enum RotSelector gradApproximator
static PetscBool dynamicRelaxation
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)
std::map< std::string, boost::shared_ptr< ScalingMethod > > scalingMethodsMap
OpSpatialPhysicalExternalStrain(const std::string &field_name, boost::shared_ptr< DataAtIntegrationPts > data_ptr, boost::shared_ptr< ExternalStrainVec > external_strain_vec_ptr, std::map< std::string, boost::shared_ptr< ScalingMethod > > smv)
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)
static double fun_diff_neohookean_bulk(double K, double tr)
Definition of derivative of axiator of Neo-hookean function.
static double fun_d_neohookean(double c10, double v)
Definition of derivative of Neo-hookean function.
static double fun_neohookean_bulk(double K, double tr)
Definition of axiator of Neo-hookean function.
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)
static double fun_neohookean(double c10, double v)
Definition of Neo-hookean function.
auto getMaterialParameters(EntityHandle ent)
static constexpr int numberOfActiveVariables
virtual VolUserDataOperator * returnOpSpatialPhysicalExternalStrain(const std::string &field_name, boost::shared_ptr< DataAtIntegrationPts > data_ptr, boost::shared_ptr< ExternalStrainVec > external_strain_vec_ptr, std::map< std::string, boost::shared_ptr< ScalingMethod > > smv)
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)
UserDataOperator * 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)
virtual VolUserDataOperator * returnOpSpatialPhysical_du_du(std::string row_field, std::string col_field, boost::shared_ptr< DataAtIntegrationPts > data_ptr, const double alpha)
virtual UserDataOperator * 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 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 degrees of freedom on entity.
EntityHandle getFEEntityHandle() const
Return finite element entity handle.
const FEMethod * getFEMethod() const
Return raw pointer to Finite Element Method object.
PetscReal ts_t
Current time value.
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.
double scale
Definition plastic.cpp:123
double zeta
Viscous hardening.
Definition plastic.cpp:130