v0.15.5
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
117 MoFEMErrorCode setParams(const int tag, EntityHandle ent, int gg) {
119 auto [def_c10, def_K] = getMaterialParameters(ent);
120 std::vector<double> params = {def_c10, def_K};
121 set_param_vec(tag, params.size(), params.data());
123 };
124
126 OpGetScale(boost::shared_ptr<double> scale_ptr,
127 boost::shared_ptr<PhysicalEquations> physics_ptr)
129 scalePtr(scale_ptr), physicsPtr(physics_ptr) {}
130
131 MoFEMErrorCode doWork(int side, EntityType type,
132 EntitiesFieldData::EntData &data) {
134 auto neohookean_ptr =
135 boost::dynamic_pointer_cast<HMHNeohookean>(physicsPtr);
136 *(scalePtr) = neohookean_ptr->eqScaling;
138 }
139
140 private:
141 boost::shared_ptr<double> scalePtr;
142 boost::shared_ptr<PhysicalEquations> physicsPtr;
143 };
144
146 returnOpSetScale(boost::shared_ptr<double> scale_ptr,
147 boost::shared_ptr<PhysicalEquations> physics_ptr) {
148
149 return new OpGetScale(scale_ptr, physics_ptr);
150 };
151
152 struct OpJacobian : public EshelbianPlasticity::OpJacobian {
153 using EshelbianPlasticity::OpJacobian::OpJacobian;
154 MoFEMErrorCode evaluateRhs(EntData &data) { return 0; }
155 MoFEMErrorCode evaluateLhs(EntData &data) { return 0; }
156 };
157
159 returnOpJacobian(const int tag, const bool eval_rhs, const bool eval_lhs,
160 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
161 boost::shared_ptr<PhysicalEquations> physics_ptr) {
162 if (adolCOn) {
163 return PhysicalEquations::returnOpJacobian(tag, eval_rhs, eval_lhs,
164 data_ptr, physics_ptr);
165 } else {
166 return (new OpJacobian(tag, eval_rhs, eval_lhs, data_ptr, physics_ptr));
167 }
168 }
169
170 MoFEMErrorCode getOptions() {
172 PetscOptionsBegin(PETSC_COMM_WORLD, "neo_hookean_", "", "none");
173
174 c10_default = 1;
175 CHKERR PetscOptionsScalar("-c10", "C10", "", c10_default, &c10_default,
176 PETSC_NULLPTR);
177 K_default = 1;
178 CHKERR PetscOptionsScalar("-K", "Bulk modulus K", "", K_default, &K_default,
179 PETSC_NULLPTR);
180
181 alphaGradU = 0;
182 CHKERR PetscOptionsScalar("-viscosity_alpha_grad_u", "viscosity", "",
183 alphaGradU, &alphaGradU, PETSC_NULLPTR);
184
185 CHKERR PetscOptionsBool("-adolc_on", "adolc ON", "", adolCOn, &adolCOn,
186 PETSC_NULLPTR);
187
188 PetscOptionsEnd();
189
190 MOFEM_LOG_CHANNEL("WORLD");
191 MOFEM_TAG_AND_LOG("WORLD", Sev::inform, "MatBlock Neo-Hookean (default)")
192 << "c10 = " << c10_default << " K = " << K_default
193 << " grad alpha u = " << alphaGradU;
194 MOFEM_TAG_AND_LOG("WORLD", Sev::inform, "MatBlock Neo-Hookean (default)")
195 << "ADOL-C On " << (adolCOn)
196 ? "Yes"
197 : "No";
199 }
200
201 MoFEMErrorCode extractBlockData(Sev sev) {
202 return extractBlockData(
203
204 mField.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(std::regex(
205
206 (boost::format("%s(.*)") % "MAT_NEOHOOKEAN").str()
207
208 )),
209
210 sev);
211 }
212
213 MoFEMErrorCode
214 extractBlockData(std::vector<const CubitMeshSets *> meshset_vec_ptr,
215 Sev sev) {
217
218 for (auto m : meshset_vec_ptr) {
219 MOFEM_LOG("EP", sev) << *m;
220 std::vector<double> block_data;
221 CHKERR m->getAttributes(block_data);
222 if (block_data.size() < 2) {
223 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
224 "Expected that block has atleast two attributes");
225 }
226 auto get_block_ents = [&]() {
227 Range ents;
228 CHKERR mField.get_moab().get_entities_by_handle(m->meshset, ents, true);
229 return ents;
230 };
231
232 double c10 = block_data[0];
233 double K = block_data[1];
234
235 blockData.push_back({c10, K, get_block_ents()});
236
237 MOFEM_LOG("EP", sev) << "MatBlock Neo-Hookean c10 = "
238 << blockData.back().c10
239 << " K = " << blockData.back().K << " nb ents. = "
240 << blockData.back().blockEnts.size();
241 }
243 }
244
245 MoFEMErrorCode recordTape(const int tape, DTensor2Ptr *t_h_ptr) {
247
248 FTENSOR_INDEX(3, i);
249 FTENSOR_INDEX(3, j);
250 FTENSOR_INDEX(3, I);
251 FTENSOR_INDEX(3, J);
252
253 auto large = [&]() {
255
256 constexpr auto t_kd = FTensor::Kronecker_Delta<int>();
257
258 auto ih = get_h();
259 if (t_h_ptr)
260 ih(i, j) = (*t_h_ptr)(i, j);
261 else {
262 ih(i, j) = t_kd(i, j);
263 }
264
265 auto r_P = get_P();
266
267 enableMinMaxUsingAbs();
268 trace_on(tape);
269
270 // Set active variables to ADOL-C
271 th(i, j) <<= get_h()(i, j);
272
273 tF(i, I) = th(i, I);
274 CHKERR determinantTensor3by3(tF, detF);
275 CHKERR invertTensor3by3(tF, detF, tInvF);
276
277 // tCof(i, I) = detF * tInvF(I, i);
278
279 // Psi = c10* (trace(tCof) + 2ln(det(F)) - 3) + (K/2.) * (log(detF))^2;
280
281 auto p_c10 = mkparam(c10_default);
282 auto p_K = mkparam(K_default);
283 tP(i, I) =
284 2. * p_c10 * (tF(i, I) - tInvF(i, I)) + p_K * log(detF) * tInvF(i, I);
285
286 // Set dependent variables to ADOL-C
287 tP(i, j) >>= r_P(i, j);
288
289 trace_off();
290
292 };
293
296 case LARGE_ROT:
297 case MODERATE_ROT:
298 CHKERR large();
299 break;
300 default:
301 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
302 "gradApproximator not handled");
303 };
304
306 }
307
309
310 OpSpatialPhysical(const std::string &field_name,
311 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
312 const double alpha_u);
313
314 MoFEMErrorCode integrate(EntData &data);
315
316 private:
317 const double alphaU;
318 };
319
320 virtual VolUserDataOperator *
322 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
323 const double alpha_u) {
324 if (adolCOn) {
326 alpha_u);
327 } else {
328 return new OpSpatialPhysical(field_name, data_ptr, alpha_u);
329 }
330 }
331
333
335 const std::string &field_name,
336 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
337 boost::shared_ptr<ExternalStrainVec> external_strain_vec_ptr,
338 std::map<std::string, boost::shared_ptr<ScalingMethod>> smv);
339
340 MoFEMErrorCode integrate(EntData &data);
341
342 private:
343 boost::shared_ptr<ExternalStrainVec> externalStrainVecPtr;
344 std::map<std::string, boost::shared_ptr<ScalingMethod>> scalingMethodsMap;
345 };
346
348 const std::string &field_name,
349 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
350 boost::shared_ptr<ExternalStrainVec> external_strain_vec_ptr,
351 std::map<std::string, boost::shared_ptr<ScalingMethod>> smv) {
352 return new OpSpatialPhysicalExternalStrain(field_name, data_ptr,
353 external_strain_vec_ptr, smv);
354 }
355
357 OpSpatialPhysical_du_du(std::string row_field, std::string col_field,
358 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
359 const double alpha);
360 MoFEMErrorCode integrate(EntData &row_data, EntData &col_data);
361
362 private:
363 const double alphaU;
364 };
365
367 std::string row_field, std::string col_field,
368 boost::shared_ptr<DataAtIntegrationPts> data_ptr, const double alpha) {
369 if (adolCOn) {
371 row_field, col_field, data_ptr, alpha);
372 } else {
373 return new OpSpatialPhysical_du_du(row_field, col_field, data_ptr, alpha);
374 }
375 }
376
377private:
379
381 double K_default;
383 struct BlockData {
384 double c10;
385 double K;
387 };
388 std::vector<BlockData> blockData;
389
390 double eqScaling = 1.;
391
392 // ADOL-C
393 PetscBool adolCOn = PETSC_FALSE;
394
401};
402
404 const std::string &field_name,
405 boost::shared_ptr<DataAtIntegrationPts> data_ptr, const double alpha_u)
406 : OpAssembleVolume(field_name, data_ptr, OPROW), alphaU(alpha_u) {}
407
408extern "C" {
409void tetcircumcenter_tp(double a[3], double b[3], double c[3], double d[3],
410 double circumcenter[3], double *xi, double *eta,
411 double *zeta);
412}
413
416
417 auto neohookean_ptr =
418 boost::dynamic_pointer_cast<HMHNeohookean>(dataAtPts->physicsPtr);
419 if (!neohookean_ptr) {
420 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
421 "Pointer to HMHNeohookean is null");
422 }
423 auto [def_c10, def_K] =
424 neohookean_ptr->getMaterialParameters(getFEEntityHandle());
425
426 double c10 = def_c10 / neohookean_ptr->eqScaling;
427 double alpha_u = alphaU / neohookean_ptr->eqScaling;
428 double K = def_K / neohookean_ptr->eqScaling;
429
430 double alpha_grad_u =
431 neohookean_ptr->alphaGradU / neohookean_ptr->eqScaling;
432
434 auto t_L = symm_L_tensor();
435
436 constexpr auto t_kd_sym = FTensor::Kronecker_Delta_symmetric<int>();
437 constexpr auto t_kd = FTensor::Kronecker_Delta<int>();
438
439 int nb_dofs = data.getIndices().size();
440 int nb_integration_pts = data.getN().size1();
441 auto v = getVolume();
442 auto t_w = getFTensor0IntegrationWeight();
443 auto t_approx_P_adjoint_log_du =
444 getFTensor1FromMat<size_symm>(dataAtPts->adjointPdUAtPts);
445 auto t_u = getFTensor2SymmetricFromMat<3>(dataAtPts->stretchTensorAtPts);
446 auto t_grad_h1 = getFTensor2FromMat<3, 3>(dataAtPts->wGradH1AtPts);
447 auto t_dot_log_u =
448 getFTensor2SymmetricFromMat<3>(dataAtPts->logStretchDotTensorAtPts);
449 auto t_diff_u =
450 getFTensor4DdgFromMat<3, 3, 1>(dataAtPts->diffStretchTensorAtPts);
451 auto t_log_u =
452 getFTensor2SymmetricFromMat<3>(dataAtPts->logStretchTensorAtPts);
453 auto t_grad_log_u =
454 getFTensor2FromMat<6, 3>(dataAtPts->gradLogStretchDotTensorAtPts);
455 auto t_log_u2_h1 =
456 getFTensor2SymmetricFromMat<3>(dataAtPts->logStretch2H1AtPts);
457
458 auto t_eigen_vals = getFTensor1FromMat<3>(dataAtPts->eigenVals);
459 auto t_eigen_vecs = getFTensor2FromMat<3, 3>(dataAtPts->eigenVecs);
460 auto &nbUniq = dataAtPts->nbUniq;
461 auto t_nb_uniq =
462 FTensor::Tensor0<FTensor::PackPtr<int *, 1>>(nbUniq.data().data());
463
464 auto t_diff = diff_tensor();
465
472
473 auto get_ftensor2 = [](auto &v) {
475 &v[0], &v[1], &v[2], &v[3], &v[4], &v[5]);
476 };
477
478 int nb_base_functions = data.getN().size2();
479 auto t_row_base_fun = data.getFTensor0N();
480 auto t_grad_base_fun = data.getFTensor1DiffN<3>();
481
482 auto no_h1 = [&]() {
484
485 for (int gg = 0; gg != nb_integration_pts; ++gg) {
486 double a = v * t_w;
487 ++t_w;
488
489 auto neohookean = [c10](auto v) { return fun_neohookean(c10, v); };
490 auto t_neohookean_hencky =
491 EigenMatrix::getMat(t_eigen_vals, t_eigen_vecs, neohookean);
492 ++t_eigen_vals;
493 ++t_eigen_vecs;
494 ++t_nb_uniq;
495
496 const double tr = t_log_u(i, i);
498 t_P(L) = t_L(i, j, L) * (t_neohookean_hencky(i, j) +
499 t_kd(i, j) * fun_neohookean_bulk(K, tr));
501 t_viscous_P(L) = alpha_u * (t_L(i, j, L) * t_dot_log_u(i, j));
502
504 t_residual(L) = t_approx_P_adjoint_log_du(L) - t_P(L) - t_viscous_P(L);
505 t_residual(L) *= a;
506
508 t_grad_residual(L, i) = alpha_grad_u * t_grad_log_u(L, i);
509 t_grad_residual(L, i) *= a;
510
511 ++t_approx_P_adjoint_log_du;
512 ++t_log_u;
513 ++t_dot_log_u;
514 ++t_grad_log_u;
515
516 auto t_nf = getFTensor1FromPtr<size_symm>(&*nF.data().begin());
517 int bb = 0;
518 for (; bb != nb_dofs / size_symm; ++bb) {
519 t_nf(L) -= t_row_base_fun * t_residual(L);
520 t_nf(L) += t_grad_base_fun(i) * t_grad_residual(L, i);
521 ++t_nf;
522 ++t_row_base_fun;
523 ++t_grad_base_fun;
524 }
525 for (; bb != nb_base_functions; ++bb) {
526 ++t_row_base_fun;
527 ++t_grad_base_fun;
528 }
529 }
530
532 };
533
534 auto large = [&]() {
536 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
537 "Not implemented for Neo-Hookean (used ADOL-C)");
539 };
540
543 CHKERR no_h1();
544 break;
545 case LARGE_ROT:
546 case MODERATE_ROT:
547 CHKERR large();
548 break;
549 default:
550 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
551 "gradApproximator not handled");
552 };
553
555}
556
558 const std::string &field_name,
559 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
560 boost::shared_ptr<ExternalStrainVec> external_strain_vec_ptr,
561 std::map<std::string, boost::shared_ptr<ScalingMethod>> smv)
562 : OpAssembleVolume(field_name, data_ptr, OPROW),
563 externalStrainVecPtr(external_strain_vec_ptr), scalingMethodsMap{smv} {}
564
565MoFEMErrorCode
568
569 auto neohookean_ptr =
570 boost::dynamic_pointer_cast<HMHNeohookean>(dataAtPts->physicsPtr);
571 if (!neohookean_ptr) {
572 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
573 "Pointer to HMHNeohookean is null");
574 }
575
576 double time = OpAssembleVolume::getFEMethod()->ts_t;
579 }
580 // get entity of tet
582 // iterate over all block data
583
584 for (auto &ext_strain_block : (*externalStrainVecPtr)) {
585 auto block_name = "(.*)ANALYTICAL_EXTERNALSTRAIN(.*)";
586 std::regex reg_name(block_name);
587 if (std::regex_match(ext_strain_block.blockName, reg_name)) {
588 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
589 "Analytical external strain not implemented for Neo-Hookean "
590 "material.");
591 }
592 // check if finite element entity is part of the EXTERNALSTRAIN block
593 if (ext_strain_block.ents.find(fe_ent) != ext_strain_block.ents.end()) {
594 double scale = 1;
595 if (scalingMethodsMap.find(ext_strain_block.blockName) !=
596 scalingMethodsMap.end()) {
597 scale *=
598 scalingMethodsMap.at(ext_strain_block.blockName)->getScale(time);
599 } else {
600 MOFEM_LOG("SELF", Sev::warning)
601 << "No scaling method found for " << ext_strain_block.blockName;
602 }
603
604 // get ExternalStrain block data
605 double external_strain_val = scale * ext_strain_block.val;
606 double K = ext_strain_block.bulkModulusK;
607
609 auto t_L = symm_L_tensor();
610 constexpr auto t_kd = FTensor::Kronecker_Delta<int>();
611
612 int nb_dofs = data.getIndices().size();
613 int nb_integration_pts = data.getN().size1();
614 auto v = getVolume();
615 auto t_w = getFTensor0IntegrationWeight();
616
623
624 int nb_base_functions = data.getN().size2();
625 auto t_row_base_fun = data.getFTensor0N();
626
627 const double tr = 3.0 * external_strain_val;
628 const double sigma_J = K * tr;
629
630 for (int gg = 0; gg != nb_integration_pts; ++gg) {
631 double a = v * t_w;
632 ++t_w;
633
635 t_residual(L) = 0.0;
636 t_residual(L) += (t_L(i, j, L) * t_kd(i, j)) * sigma_J;
637 t_residual(L) *= a;
638
639 auto t_nf = getFTensor1FromPtr<size_symm>(&*nF.data().begin());
640 int bb = 0;
641 for (; bb != nb_dofs / size_symm; ++bb) {
642 t_nf(L) -= t_row_base_fun * t_residual(L);
643 ++t_nf;
644 ++t_row_base_fun;
645 }
646 for (; bb != nb_base_functions; ++bb) {
647 ++t_row_base_fun;
648 }
649 }
650 }
651 }
653}
654
656 std::string row_field, std::string col_field,
657 boost::shared_ptr<DataAtIntegrationPts> data_ptr, const double alpha)
658 : OpAssembleVolumePositiveDefine(row_field, col_field, data_ptr, OPROWCOL,
659 false),
660 alphaU(alpha) {
661 sYmm = false;
662}
663
664MoFEMErrorCode
666 EntData &col_data) {
668
669 auto neohookean_ptr =
670 boost::dynamic_pointer_cast<HMHNeohookean>(dataAtPts->physicsPtr);
671 if (!neohookean_ptr) {
672 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
673 "Pointer to HMHNeohookean is null");
674 }
675 auto [def_c10, def_K] =
676 neohookean_ptr->getMaterialParameters(getFEEntityHandle());
677
678 double c10 = def_c10 / neohookean_ptr->eqScaling;
679 double alpha_u = alphaU / neohookean_ptr->eqScaling;
680 double lambda = def_K / neohookean_ptr->eqScaling;
681
682 double alpha_grad_u =
683 neohookean_ptr->alphaGradU / neohookean_ptr->eqScaling;
684
687
688 constexpr auto t_kd_sym = FTensor::Kronecker_Delta_symmetric<int>();
689 constexpr auto t_kd = FTensor::Kronecker_Delta<int>();
690
691 auto t_L = symm_L_tensor();
692 auto t_diff = diff_tensor();
693
694 int nb_integration_pts = row_data.getN().size1();
695 int row_nb_dofs = row_data.getIndices().size();
696 int col_nb_dofs = col_data.getIndices().size();
697
698 auto get_ftensor2 = [](MatrixDouble &m, const int r, const int c) {
700 size_symm>(
701
702 &m(r + 0, c + 0), &m(r + 0, c + 1), &m(r + 0, c + 2), &m(r + 0, c + 3),
703 &m(r + 0, c + 4), &m(r + 0, c + 5),
704
705 &m(r + 1, c + 0), &m(r + 1, c + 1), &m(r + 1, c + 2), &m(r + 1, c + 3),
706 &m(r + 1, c + 4), &m(r + 1, c + 5),
707
708 &m(r + 2, c + 0), &m(r + 2, c + 1), &m(r + 2, c + 2), &m(r + 2, c + 3),
709 &m(r + 2, c + 4), &m(r + 2, c + 5),
710
711 &m(r + 3, c + 0), &m(r + 3, c + 1), &m(r + 3, c + 2), &m(r + 3, c + 3),
712 &m(r + 3, c + 4), &m(r + 3, c + 5),
713
714 &m(r + 4, c + 0), &m(r + 4, c + 1), &m(r + 4, c + 2), &m(r + 4, c + 3),
715 &m(r + 4, c + 4), &m(r + 4, c + 5),
716
717 &m(r + 5, c + 0), &m(r + 5, c + 1), &m(r + 5, c + 2), &m(r + 5, c + 3),
718 &m(r + 5, c + 4), &m(r + 5, c + 5)
719
720 );
721 };
722
729
730 auto v = getVolume();
731 auto ts_a = getTSa();
732 auto t_w = getFTensor0IntegrationWeight();
733
734 int row_nb_base_functions = row_data.getN().size2();
735 auto t_row_base_fun = row_data.getFTensor0N();
736 auto t_row_grad_fun = row_data.getFTensor1DiffN<3>();
737
738 auto t_grad_h1 = getFTensor2FromMat<3, 3>(dataAtPts->wGradH1AtPts);
739 auto t_diff_u =
740 getFTensor4DdgFromMat<3, 3, 1>(dataAtPts->diffStretchTensorAtPts);
741 auto t_log_u =
742 getFTensor2SymmetricFromMat<3>(dataAtPts->logStretchTensorAtPts);
743 auto t_log_u2_h1 =
744 getFTensor2SymmetricFromMat<3>(dataAtPts->logStretch2H1AtPts);
745 auto t_u = getFTensor2SymmetricFromMat<3>(dataAtPts->stretchTensorAtPts);
746 auto t_approx_P_adjoint__dstretch =
747 getFTensor2FromMat<3, 3>(dataAtPts->adjointPdstretchAtPts);
748 auto t_eigen_vals = getFTensor1FromMat<3>(dataAtPts->eigenVals);
749 auto t_eigen_vecs = getFTensor2FromMat<3, 3>(dataAtPts->eigenVecs);
750 auto &nbUniq = dataAtPts->nbUniq;
751 auto t_nb_uniq =
752 FTensor::Tensor0<FTensor::PackPtr<int *, 1>>(nbUniq.data().data());
753
754 auto no_h1 = [&]() {
756
757 for (int gg = 0; gg != nb_integration_pts; ++gg) {
758 double a = v * t_w;
759 ++t_w;
760
761 auto neohookean = [c10](auto v) { return fun_neohookean(c10, v); };
762 auto d_neohookean = [c10, lambda](auto v) {
763 return fun_d_neohookean(c10, v);
764 };
765
766 auto t_diff_neohookean = EigenMatrix::getDiffMat(
767 t_eigen_vals, t_eigen_vecs, neohookean, d_neohookean, t_nb_uniq);
768
769 const auto tr = t_log_u(i, i);
771 t_dP(L, J) = -t_L(i, j, L) * ((t_diff_neohookean(i, j, k, l) +
773 t_kd_sym(i, j) * t_kd_sym(k, l)) *
774 t_L(k, l, J));
775 t_dP(L, J) -= (alpha_u * ts_a) *
776 (t_L(i, j, L) * (t_diff(i, j, k, l) * t_L(k, l, J)));
777
778 if constexpr (1) {
780 t_deltaP(i, j) = (t_approx_P_adjoint__dstretch(i, j) ||
781 t_approx_P_adjoint__dstretch(j, i)) /
782 2.;
783 auto t_diff2_uP = EigenMatrix::getDiffDiffMat(
784 t_eigen_vals, t_eigen_vecs, EshelbianCore::f, EshelbianCore::d_f,
785 EshelbianCore::dd_f, t_deltaP, t_nb_uniq);
786 t_dP(L, J) += t_L(i, j, L) * (t_diff2_uP(i, j, k, l) * t_L(k, l, J));
787 }
788 ++t_approx_P_adjoint__dstretch;
789 ++t_log_u;
790 ++t_eigen_vals;
791 ++t_eigen_vecs;
792 ++t_nb_uniq;
793
794 int rr = 0;
795 for (; rr != row_nb_dofs / size_symm; ++rr) {
796 auto t_col_base_fun = col_data.getFTensor0N(gg, 0);
797 auto t_col_grad_fun = col_data.getFTensor1DiffN<3>(gg, 0);
798
799 auto t_m = get_ftensor2(K, 6 * rr, 0);
800 for (int cc = 0; cc != col_nb_dofs / size_symm; ++cc) {
801 double b = a * t_row_base_fun * t_col_base_fun;
802 double c = (a * alpha_grad_u * ts_a) *
803 (t_row_grad_fun(i) * t_col_grad_fun(i));
804 t_m(L, J) -= b * t_dP(L, J);
805 t_m(L, J) += c * t_kd_sym(L, J);
806
807 ++t_m;
808 ++t_col_base_fun;
809 ++t_col_grad_fun;
810 }
811 ++t_row_base_fun;
812 ++t_row_grad_fun;
813 }
814
815 for (; rr != row_nb_base_functions; ++rr) {
816 ++t_row_base_fun;
817 ++t_row_grad_fun;
818 }
819
820 }
822 };
823
824 auto large = [&]() {
826 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
827 "Not implemented for Neo-Hookean (used ADOL-C)");
829 };
830
833 CHKERR no_h1();
834 break;
835 case LARGE_ROT:
836 case MODERATE_ROT:
837 CHKERR large();
838 break;
839 default:
840 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
841 "gradApproximator not handled");
842 };
843
845}
846
847} // 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)
MoFEMErrorCode setParams(const int tag, EntityHandle ent, int gg)
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