v0.15.5
Loading...
Searching...
No Matches
HMHHencky.cpp
Go to the documentation of this file.
1/**
2 * @file Hencky.cpp
3 * @brief Implementation of Hencky material
4 * @date 2024-08-31
5 *
6 * @copyright Copyright (c) 2024
7 *
8 */
9
10
11namespace EshelbianPlasticity {
12
14
15 HMHHencky(MoFEM::Interface &m_field, const double E, const double nu)
16 : PhysicalEquations(0, 0), mField(m_field), E(E), nu(nu) {}
17
18 MoFEMErrorCode recordTape(const int tag, DTensor2Ptr *t_h) { return 0; }
19
20 struct OpHenckyJacobian : public OpJacobian {
21 OpHenckyJacobian(boost::shared_ptr<DataAtIntegrationPts> data_ptr,
22 boost::shared_ptr<HMHHencky> hencky_ptr)
23 : OpJacobian(), dataAtGaussPts(data_ptr), henckyPtr(hencky_ptr) {
25 "getOptions failed");
26 CHK_THROW_MESSAGE(henckyPtr->extractBlockData(Sev::verbose),
27 "Can not get data from block");
28 }
29
30 MoFEMErrorCode doWork(int side, EntityType type,
31 EntitiesFieldData::EntData &data) {
33
34 for (auto &b : henckyPtr->blockData) {
35 if (b.blockEnts.find(getFEEntityHandle()) != b.blockEnts.end()) {
36 dataAtGaussPts->mu = b.shearModulusG;
37 dataAtGaussPts->lambda = b.bulkModulusK - 2 * b.shearModulusG / 3;
38 CHKERR henckyPtr->getMatDPtr(dataAtGaussPts->getMatDPtr(),
39 dataAtGaussPts->getMatAxiatorDPtr(),
40 dataAtGaussPts->getMatDeviatorDPtr(),
41 b.bulkModulusK, b.shearModulusG);
43 }
44 }
45 const auto E = henckyPtr->E;
46 const auto nu = henckyPtr->nu;
47
48 double bulk_modulus_K = E / (3 * (1 - 2 * nu));
49 double shear_modulus_G = E / (2 * (1 + nu));
50
53
54 CHKERR henckyPtr->getMatDPtr(dataAtGaussPts->getMatDPtr(),
55 dataAtGaussPts->getMatAxiatorDPtr(),
56 dataAtGaussPts->getMatDeviatorDPtr(),
58
60 }
61
62 MoFEMErrorCode evaluateRhs(EntData &data) { return 0; }
63 MoFEMErrorCode evaluateLhs(EntData &data) { return 0; }
64
65 private:
66 boost::shared_ptr<DataAtIntegrationPts> dataAtGaussPts;
67 boost::shared_ptr<HMHHencky> henckyPtr;
68 };
69
70 virtual UserDataOperator *
71 returnOpJacobian(const int tag, const bool eval_rhs, const bool eval_lhs,
72 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
73 boost::shared_ptr<PhysicalEquations> physics_ptr) {
74 return (new OpHenckyJacobian(
75 data_ptr, boost::dynamic_pointer_cast<HMHHencky>(physics_ptr)));
76 }
77
79
80 OpSpatialPhysical(const std::string &field_name,
81 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
82 const double alpha_u);
83
84 MoFEMErrorCode integrate(EntData &data);
85
86 MoFEMErrorCode integrateHencky(EntData &data);
87
88 MoFEMErrorCode integratePolyconvexHencky(EntData &data);
89
90 private:
91 const double alphaU;
92 PetscBool polyConvex = PETSC_FALSE;
93 };
94
95 virtual VolUserDataOperator *
97 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
98 const double alpha_u) {
99 return new OpSpatialPhysical(field_name, data_ptr, alpha_u);
100 }
101
104 const std::string &field_name,
105 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
106 boost::shared_ptr<ExternalStrainVec> &external_strain_vec_ptr,
107 std::map<std::string, boost::shared_ptr<ScalingMethod>> smv);
108
109 MoFEMErrorCode integrate(EntData &data);
110
111 private:
112 boost::shared_ptr<ExternalStrainVec> externalStrainVecPtr;
113 std::map<std::string, boost::shared_ptr<ScalingMethod>> scalingMethodsMap;
114 };
115
117 const std::string &field_name,
118 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
119 boost::shared_ptr<ExternalStrainVec> external_strain_vec_ptr,
120 std::map<std::string, boost::shared_ptr<ScalingMethod>> smv)
121 {
123 field_name, data_ptr, external_strain_vec_ptr, smv);
124 }
125
127 const double alphaU;
128 OpSpatialPhysical_du_du(std::string row_field, std::string col_field,
129 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
130 const double alpha);
131 MoFEMErrorCode integrate(EntData &row_data, EntData &col_data);
132 MoFEMErrorCode integrateHencky(EntData &row_data, EntData &col_data);
133 MoFEMErrorCode integratePolyconvexHencky(EntData &row_data,
134 EntData &col_data);
135
136 private:
137 PetscBool polyConvex = PETSC_FALSE;
138
139 MatrixDouble dP;
140 };
141
143 std::string row_field, std::string col_field,
144 boost::shared_ptr<DataAtIntegrationPts> data_ptr, const double alpha) {
145 return new OpSpatialPhysical_du_du(row_field, col_field, data_ptr, alpha);
146 }
147
148 /**
149 * @brief Calculate energy density for Hencky material model
150 *
151 *
152 * \f[
153 *
154 * \Psi(\log{\mathbf{U}}) = \frac{1}{2} U_{IJ} D_{IJKL} U_{KL} = \frac{1}{2}
155 * U_{IJ} T_{IJ}
156 *
157 * \f]
158 * where \f$T_{IJ} = D_{IJKL} U_{KL}\f$ is a a Hencky stress.
159 *
160 */
162
163 OpCalculateEnergy(boost::shared_ptr<DataAtIntegrationPts> data_ptr,
164 boost::shared_ptr<double> total_energy_ptr);
165 MoFEMErrorCode doWork(int side, EntityType type, EntData &data);
166
167 private:
168 boost::shared_ptr<DataAtIntegrationPts> dataAtPts;
169 boost::shared_ptr<double> totalEnergyPtr;
170 };
171
173 returnOpCalculateEnergy(boost::shared_ptr<DataAtIntegrationPts> data_ptr,
174 boost::shared_ptr<double> total_energy_ptr) {
175 return new OpCalculateEnergy(data_ptr, total_energy_ptr);
176 }
177
180 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
181 boost::shared_ptr<MatrixDouble> strain_ptr,
182 boost::shared_ptr<MatrixDouble> stress_ptr,
183 boost::shared_ptr<HMHHencky> hencky_ptr);
184 MoFEMErrorCode doWork(int side, EntityType type, EntData &data);
185
186 private:
187 boost::shared_ptr<DataAtIntegrationPts>
188 dataAtPts; ///< data at integration pts
189 boost::shared_ptr<MatrixDouble> strainPtr;
190 boost::shared_ptr<MatrixDouble> stressPtr;
191 boost::shared_ptr<HMHHencky> henckyPtr;
192 };
193
195 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
196 boost::shared_ptr<PhysicalEquations> physics_ptr) {
198 data_ptr, data_ptr->getLogStretchTensorAtPts(),
199 data_ptr->getApproxPAtPts(),
200 boost::dynamic_pointer_cast<HMHHencky>(physics_ptr));
201 }
202
204 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
205 boost::shared_ptr<PhysicalEquations> physics_ptr) {
207 data_ptr, data_ptr->getVarLogStreachPts(), data_ptr->getVarPiolaPts(),
208 boost::dynamic_pointer_cast<HMHHencky>(physics_ptr));
209 }
210
211 MoFEMErrorCode getOptions(boost::shared_ptr<DataAtIntegrationPts> data_ptr) {
213 PetscOptionsBegin(PETSC_COMM_WORLD, "hencky_", "", "none");
214
215 CHKERR PetscOptionsScalar("-young_modulus", "Young modulus", "", E, &E,
216 PETSC_NULLPTR);
217 CHKERR PetscOptionsScalar("-poisson_ratio", "poisson ratio", "", nu, &nu,
218 PETSC_NULLPTR);
219
220 PetscOptionsEnd();
221
223 << "Hencky: E = " << E << " nu = " << nu;
224 getOptionsSeverityLevels = Sev::verbose;
225
226 CHKERRG(ierr);
227
229 }
230
231 MoFEMErrorCode extractBlockData(Sev sev) {
232 return extractBlockData(
233
234 mField.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(std::regex(
235
236 (boost::format("%s(.*)") % "MAT_ELASTIC").str()
237
238 )),
239
240 sev);
241 }
242
243 MoFEMErrorCode
244 extractBlockData(std::vector<const CubitMeshSets *> meshset_vec_ptr,
245 Sev sev) {
247
248 for (auto m : meshset_vec_ptr) {
249 MOFEM_TAG_AND_LOG("WORLD", sev, "MatBlock") << *m;
250 std::vector<double> block_data;
251 CHKERR m->getAttributes(block_data);
252 if (block_data.size() < 2) {
253 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
254 "Expected that block has atleast two attributes");
255 }
256 auto get_block_ents = [&]() {
257 Range ents;
258 CHKERR mField.get_moab().get_entities_by_handle(m->meshset, ents, true);
259 return ents;
260 };
261
262 double young_modulus = block_data[0];
263 double poisson_ratio = block_data[1];
264 double bulk_modulus_K = young_modulus / (3 * (1 - 2 * poisson_ratio));
265 double shear_modulus_G = young_modulus / (2 * (1 + poisson_ratio));
266
267 MOFEM_TAG_AND_LOG("WORLD", sev, "MatBlock")
268 << "E = " << young_modulus << " nu = " << poisson_ratio;
269
270 blockData.push_back({bulk_modulus_K, shear_modulus_G, get_block_ents()});
271 }
272 MOFEM_LOG_CHANNEL("WORLD");
274 }
275
276 MoFEMErrorCode getMatDPtr(boost::shared_ptr<MatrixDouble> mat_D_ptr,
277 boost::shared_ptr<MatrixDouble> mat_axiator_D_ptr,
278 boost::shared_ptr<MatrixDouble> mat_deviator_D_ptr,
279 double bulk_modulus_K, double shear_modulus_G) {
281 //! [Calculate elasticity tensor]
282 auto set_material_stiffness = [&]() {
288 auto t_D = getFTensor4DdgFromPtr<SPACE_DIM, SPACE_DIM, 0>(
289 &*(mat_D_ptr->data().begin()));
290 auto t_axiator_D = getFTensor4DdgFromPtr<SPACE_DIM, SPACE_DIM, 0>(
291 &*mat_axiator_D_ptr->data().begin());
292 auto t_deviator_D = getFTensor4DdgFromPtr<SPACE_DIM, SPACE_DIM, 0>(
293 &*mat_deviator_D_ptr->data().begin());
294 t_axiator_D(i, j, k, l) = (bulk_modulus_K - (2. / 3.) * shear_modulus_G) *
295 t_kd(i, j) * t_kd(k, l);
296 t_deviator_D(i, j, k, l) =
297 2 * shear_modulus_G * ((t_kd(i, k) ^ t_kd(j, l)) / 4.);
298 t_D(i, j, k, l) = t_axiator_D(i, j, k, l) + t_deviator_D(i, j, k, l);
299 };
300 //! [Calculate elasticity tensor]
301 constexpr auto size_symm = (SPACE_DIM * (SPACE_DIM + 1)) / 2;
302 mat_D_ptr->resize(size_symm, size_symm, false);
303 mat_axiator_D_ptr->resize(size_symm, size_symm, false);
304 mat_deviator_D_ptr->resize(size_symm, size_symm, false);
305 set_material_stiffness();
307 }
308
309 MoFEMErrorCode
310 getInvMatDPtr(boost::shared_ptr<MatrixDouble> mat_inv_D_ptr,
311 double bulk_modulus_K, double shear_modulus_G) {
313 //! [Calculate elasticity tensor]
314 auto set_material_compilance = [&]() {
320 const double A = 1. / (2. * shear_modulus_G);
321 const double B =
322 (1. / (9. * bulk_modulus_K)) - (1. / (6. * shear_modulus_G));
323 auto t_inv_D = getFTensor4DdgFromPtr<SPACE_DIM, SPACE_DIM, 0>(
324 &*(mat_inv_D_ptr->data().begin()));
325 t_inv_D(i, j, k, l) =
326 A * ((t_kd(i, k) ^ t_kd(j, l)) / 4.) + B * t_kd(i, j) * t_kd(k, l);
327 };
328 //! [Calculate elasticity tensor]
329 constexpr auto size_symm = (SPACE_DIM * (SPACE_DIM + 1)) / 2;
330 mat_inv_D_ptr->resize(size_symm, size_symm, false);
331 set_material_compilance();
333 }
334
336
337 OpTopoSpatialPhysical(const std::string &field_name,
338 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
339 SmartPetscObj<Vec> assemble_vec,
340 boost::shared_ptr<TopologicalData> topo_ptr,
341 const double alpha_u);
342
343 MoFEMErrorCode integrate(EntData &data);
344
345 MoFEMErrorCode integrateHencky(EntData &data);
346
347 MoFEMErrorCode integratePolyconvexHencky(EntData &data);
348
349 MoFEMErrorCode assemble(EntData &data) override;
350
351 private:
352 const double alphaU;
353 PetscBool polyConvex = PETSC_FALSE;
354 boost::shared_ptr<TopologicalData> topoDataPtr;
355 SmartPetscObj<Vec> assembleVec;
356 };
357
358 virtual VolUserDataOperator *
360 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
361 SmartPetscObj<Vec> assemble_vec,
362 boost::shared_ptr<TopologicalData> topo_ptr,
363 const double alpha_u) {
364 return new OpTopoSpatialPhysical(field_name, data_ptr, assemble_vec,
365 topo_ptr, alpha_u);
366 }
367
368private:
370
376 std::vector<BlockData> blockData;
377
378 double E;
379 double nu;
380
381 // Set verbosity level, it verbile can changes that informatno is pronated
382 // only once at particular level
383 Sev getOptionsSeverityLevels = Sev::inform;
384};
385
387 const std::string &field_name,
388 boost::shared_ptr<DataAtIntegrationPts> data_ptr, const double alpha_u)
389 : OpAssembleVolume(field_name, data_ptr, OPROW), alphaU(alpha_u) {
390
391 CHK_MOAB_THROW(PetscOptionsGetBool(PETSC_NULLPTR, "", "-poly_convex",
392 &polyConvex, PETSC_NULLPTR),
393 "get polyconvex option failed");
394}
395
398 if (polyConvex) {
399 CHKERR integratePolyconvexHencky(data);
400 } else {
401 CHKERR integrateHencky(data);
402 }
404}
405
408
410 auto t_L = symm_L_tensor();
411
412 int nb_dofs = data.getIndices().size();
413 int nb_integration_pts = data.getN().size1();
414 auto v = getVolume();
415 auto t_w = getFTensor0IntegrationWeight();
416 auto t_approx_P_adjoint_log_du =
417 getFTensor1FromMat<size_symm>(dataAtPts->adjointPdUAtPts);
418 auto t_log_stretch_h1 =
419 getFTensor2SymmetricFromMat<3>(dataAtPts->logStretchTotalTensorAtPts);
420 auto t_dot_log_u =
421 getFTensor2SymmetricFromMat<3>(dataAtPts->logStretchDotTensorAtPts);
422
423 auto t_D = getFTensor4DdgFromPtr<3, 3, 0>(&*dataAtPts->matD.data().begin());
424
425 FTensor::Index<'i', 3> i;
426 FTensor::Index<'j', 3> j;
427 FTensor::Index<'k', 3> k;
428 FTensor::Index<'l', 3> l;
429 auto get_ftensor2 = [](auto &v) {
431 &v[0], &v[1], &v[2], &v[3], &v[4], &v[5]);
432 };
433
434 int nb_base_functions = data.getN().size2();
435 auto t_row_base_fun = data.getFTensor0N();
436 for (int gg = 0; gg != nb_integration_pts; ++gg) {
437 double a = v * t_w;
438 auto t_nf = get_ftensor2(nF);
439
441 t_T(i, j) =
442 t_D(i, j, k, l) * (t_log_stretch_h1(k, l) + alphaU * t_dot_log_u(k, l));
444 t_residual(L) =
445 a * (t_approx_P_adjoint_log_du(L) - t_L(i, j, L) * t_T(i, j));
446
447 int bb = 0;
448 for (; bb != nb_dofs / 6; ++bb) {
449 t_nf(L) -= t_row_base_fun * t_residual(L);
450 ++t_nf;
451 ++t_row_base_fun;
452 }
453 for (; bb != nb_base_functions; ++bb)
454 ++t_row_base_fun;
455
456 ++t_w;
457 ++t_approx_P_adjoint_log_du;
458 ++t_dot_log_u;
459 ++t_log_stretch_h1;
460 }
462}
463
464MoFEMErrorCode
467
469 auto t_L = symm_L_tensor();
470
471 int nb_dofs = data.getIndices().size();
472 int nb_integration_pts = data.getN().size1();
473 auto v = getVolume();
474 auto t_w = getFTensor0IntegrationWeight();
475 auto t_approx_P_adjoint_log_du =
476 getFTensor1FromMat<size_symm>(dataAtPts->adjointPdUAtPts);
477 auto t_log_stretch_h1 =
478 getFTensor2SymmetricFromMat<3>(dataAtPts->logStretchTotalTensorAtPts);
479 auto t_dot_log_u =
480 getFTensor2SymmetricFromMat<3>(dataAtPts->logStretchDotTensorAtPts);
481
482 auto t_D = getFTensor4DdgFromPtr<3, 3, 0>(&*dataAtPts->matD.data().begin());
483
484 FTensor::Index<'i', 3> i;
485 FTensor::Index<'j', 3> j;
486 FTensor::Index<'k', 3> k;
487 FTensor::Index<'l', 3> l;
488 auto get_ftensor2 = [](auto &v) {
490 &v[0], &v[1], &v[2], &v[3], &v[4], &v[5]);
491 };
492
493 constexpr double nohat_k = 1. / 4;
494 constexpr double hat_k = 1. / 8;
495 double mu = dataAtPts->mu;
496 double lambda = dataAtPts->lambda;
497
498 constexpr double third = boost::math::constants::third<double>();
500 auto t_diff_deviator = diff_deviator(diff_tensor());
501
502 int nb_base_functions = data.getN().size2();
503 auto t_row_base_fun = data.getFTensor0N();
504 for (int gg = 0; gg != nb_integration_pts; ++gg) {
505 double a = v * t_w;
506 auto t_nf = get_ftensor2(nF);
507
508 double log_det = t_log_stretch_h1(i, i);
509 double log_det2 = log_det * log_det;
511 t_dev(i, j) = t_log_stretch_h1(i, j) - t_kd(i, j) * (third * log_det);
512 double dev_norm2 = t_dev(i, j) * t_dev(i, j);
513
515 auto A = 2 * mu * std::exp(nohat_k * dev_norm2);
516 auto B = lambda * std::exp(hat_k * log_det2) * log_det;
517 t_T(i, j) =
518
519 A * (t_dev(k, l) * t_diff_deviator(k, l, i, j))
520
521 +
522
523 B * t_kd(i, j)
524
525 +
526
527 alphaU * t_D(i, j, k, l) * t_dot_log_u(k, l);
528
530 t_residual(L) =
531 a * (t_approx_P_adjoint_log_du(L) - t_L(i, j, L) * t_T(i, j));
532
533 int bb = 0;
534 for (; bb != nb_dofs / size_symm; ++bb) {
535 t_nf(L) -= t_row_base_fun * t_residual(L);
536 ++t_nf;
537 ++t_row_base_fun;
538 }
539 for (; bb != nb_base_functions; ++bb)
540 ++t_row_base_fun;
541
542 ++t_w;
543 ++t_approx_P_adjoint_log_du;
544 ++t_dot_log_u;
545 ++t_log_stretch_h1;
546 }
548}
549
551 std::string row_field, std::string col_field,
552 boost::shared_ptr<DataAtIntegrationPts> data_ptr, const double alpha)
553 : OpAssembleVolume(row_field, col_field, data_ptr, OPROWCOL, false),
554 alphaU(alpha) {
555 sYmm = false;
556
557 CHK_MOAB_THROW(PetscOptionsGetBool(PETSC_NULLPTR, "", "-poly_convex",
558 &polyConvex, PETSC_NULLPTR),
559 "get polyconvex option failed");
560}
561
563 const std::string &field_name,
564 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
565 boost::shared_ptr<ExternalStrainVec> &external_strain_vec_ptr,
566 std::map<std::string, boost::shared_ptr<ScalingMethod>> smv)
567 : OpAssembleVolume(field_name, data_ptr, OPROW),
568 externalStrainVecPtr(external_strain_vec_ptr), scalingMethodsMap(smv) {}
569
570MoFEMErrorCode
573
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 // check if finite element entity is part of the EXTERNALSTRAIN block
586 if (ext_strain_block.ents.find(fe_ent) != ext_strain_block.ents.end()) {
587
588 double scale = 1;
589 if (scalingMethodsMap.find(ext_strain_block.blockName) !=
590 scalingMethodsMap.end()) {
591 scale *=
592 scalingMethodsMap.at(ext_strain_block.blockName)->getScale(time);
593 } else {
594 MOFEM_LOG("SELF", Sev::warning)
595 << "No scaling method found for " << ext_strain_block.blockName;
596 }
597
598 int nb_dofs = data.getIndices().size();
599 int nb_integration_pts = data.getN().size1();
600 auto v = getVolume();
601 auto t_w = getFTensor0IntegrationWeight();
603
604 double external_strain_val;
605 VectorDouble v_external_strain;
606 auto block_name = "(.*)ANALYTICAL_EXTERNALSTRAIN(.*)";
607 std::regex reg_name(block_name);
608 if (std::regex_match(ext_strain_block.blockName, reg_name)) {
609 VectorDouble analytical_external_strain;
610 std::string block_name_tmp;
611 std::tie(block_name_tmp, v_external_strain) =
612 getAnalyticalExternalStrain(this, analytical_external_strain,
613 ext_strain_block.blockName);
614 } else {
615 // get ExternalStrain data from block
616 external_strain_val = scale * ext_strain_block.val;
617 // fill with same scalar value for all integration points
618 v_external_strain.resize(nb_integration_pts);
619 std::fill(v_external_strain.begin(), v_external_strain.end(),
620 external_strain_val);
621 }
622 auto t_external_strain = getFTensor0FromVec(v_external_strain);
623 double bulk_modulus_K = ext_strain_block.bulkModulusK;
624 auto t_L = symm_L_tensor();
625
626 FTensor::Index<'i', 3> i;
627 FTensor::Index<'j', 3> j;
628 FTensor::Index<'k', 3> k;
629 FTensor::Index<'l', 3> l;
630 auto get_ftensor2 = [](auto &v) {
632 &v[0], &v[1], &v[2], &v[3], &v[4], &v[5]);
633 };
634
635 int nb_base_functions = data.getN().size2();
636 auto t_row_base_fun = data.getFTensor0N();
637 for (int gg = 0; gg != nb_integration_pts; ++gg) {
638 auto tr = 3.0 * t_external_strain;
639 double a = v * t_w;
640 auto t_nf = get_ftensor2(nF);
641
643
644 t_T(i, j) = -bulk_modulus_K * tr * t_kd(i, j);
645
647 t_residual(L) = a * (t_L(i, j, L) * t_T(i, j));
648
649 int bb = 0;
650 for (; bb != nb_dofs / 6; ++bb) {
651 t_nf(L) += t_row_base_fun * t_residual(L);
652 ++t_nf;
653 ++t_row_base_fun;
654 }
655 for (; bb != nb_base_functions; ++bb)
656 ++t_row_base_fun;
657 ++t_external_strain;
658 ++t_w;
659 }
660 }
661 }
662
664}
665
666MoFEMErrorCode
668 EntData &col_data) {
670
671 if (polyConvex) {
672 CHKERR integratePolyconvexHencky(row_data, col_data);
673 } else {
674 CHKERR integrateHencky(row_data, col_data);
675 }
677}
678
679MoFEMErrorCode
681 EntData &col_data) {
683
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 FTensor::Index<'i', 3> i;
718 FTensor::Index<'j', 3> j;
719 FTensor::Index<'k', 3> k;
720 FTensor::Index<'l', 3> l;
721 FTensor::Index<'m', 3> m;
722 FTensor::Index<'n', 3> n;
723
724 auto v = getVolume();
725 auto t_w = getFTensor0IntegrationWeight();
726
727 auto t_approx_P_adjoint__dstretch =
728 getFTensor2FromMat<3, 3>(dataAtPts->adjointPdstretchAtPts);
729 auto t_eigen_vals = getFTensor1FromMat<3>(dataAtPts->eigenVals);
730 auto t_eigen_vecs = getFTensor2FromMat<3, 3>(dataAtPts->eigenVecs);
731
732 int row_nb_base_functions = row_data.getN().size2();
733 auto t_row_base_fun = row_data.getFTensor0N();
734
735 auto get_dP = [&]() {
736 dP.resize(size_symm * size_symm, nb_integration_pts, false);
737 auto ts_a = getTSa();
738
739 auto t_D = getFTensor4DdgFromPtr<3, 3, 0>(&*dataAtPts->matD.data().begin());
741 t_dP_tmp(L, J) = -(1 + alphaU * ts_a) *
742 (t_L(i, j, L) *
743 ((t_D(i, j, m, n) * t_diff(m, n, k, l)) * t_L(k, l, J)));
744
747 auto t_approx_P_adjoint__dstretch =
748 getFTensor2FromMat<3, 3>(dataAtPts->adjointPdstretchAtPts);
749 auto t_eigen_vals = getFTensor1FromMat<3>(dataAtPts->eigenVals);
750 auto t_eigen_vecs = getFTensor2FromMat<3, 3>(dataAtPts->eigenVecs);
751 auto &nbUniq = dataAtPts->nbUniq;
752
753 auto t_dP = getFTensor2FromMat<size_symm, size_symm>(dP);
754 for (auto gg = 0; gg != nb_integration_pts; ++gg) {
755
756 // Work of symmetric tensor on undefined tensor is equal to the work
757 // of the symmetric part of it
759 t_sym(i, j) = (t_approx_P_adjoint__dstretch(i, j) ||
760 t_approx_P_adjoint__dstretch(j, i));
761 t_sym(i, j) /= 2.0;
762 auto t_diff2_uP2 = EigenMatrix::getDiffDiffMat(
763 t_eigen_vals, t_eigen_vecs, EshelbianCore::f, EshelbianCore::d_f,
764 EshelbianCore::dd_f, t_sym, nbUniq[gg]);
765 t_dP(L, J) = t_L(i, j, L) *
766 ((t_diff2_uP2(i, j, k, l) + t_diff2_uP2(k, l, i, j)) *
767 t_L(k, l, J)) /
768 2. +
769 t_dP_tmp(L, J);
770
771 ++t_dP;
772 ++t_approx_P_adjoint__dstretch;
773 ++t_eigen_vals;
774 ++t_eigen_vecs;
775 }
776 } else {
777 auto t_dP = getFTensor2FromMat<size_symm, size_symm>(dP);
778 for (auto gg = 0; gg != nb_integration_pts; ++gg) {
779 t_dP(L, J) = t_dP_tmp(L, J);
780 ++t_dP;
781 }
782 }
783
784 return getFTensor2FromMat<size_symm, size_symm>(dP);
785 };
786
787 auto t_dP = get_dP();
788 for (int gg = 0; gg != nb_integration_pts; ++gg) {
789 double a = v * t_w;
790
791 int rr = 0;
792 for (; rr != row_nb_dofs / 6; ++rr) {
793 auto t_col_base_fun = col_data.getFTensor0N(gg, 0);
794 auto t_m = get_ftensor2(K, 6 * rr, 0);
795 for (int cc = 0; cc != col_nb_dofs / 6; ++cc) {
796 const double b = a * t_row_base_fun * t_col_base_fun;
797 t_m(L, J) -= b * t_dP(L, J);
798 ++t_m;
799 ++t_col_base_fun;
800 }
801 ++t_row_base_fun;
802 }
803
804 for (; rr != row_nb_base_functions; ++rr) {
805 ++t_row_base_fun;
806 }
807
808 ++t_w;
809 ++t_dP;
810 }
812}
813
815 EntData &row_data, EntData &col_data) {
817
820 auto t_L = symm_L_tensor();
821 auto t_diff = diff_tensor();
822
823 int nb_integration_pts = row_data.getN().size1();
824 int row_nb_dofs = row_data.getIndices().size();
825 int col_nb_dofs = col_data.getIndices().size();
826
827 auto get_ftensor2 = [](MatrixDouble &m, const int r, const int c) {
829 size_symm>(
830
831 &m(r + 0, c + 0), &m(r + 0, c + 1), &m(r + 0, c + 2), &m(r + 0, c + 3),
832 &m(r + 0, c + 4), &m(r + 0, c + 5),
833
834 &m(r + 1, c + 0), &m(r + 1, c + 1), &m(r + 1, c + 2), &m(r + 1, c + 3),
835 &m(r + 1, c + 4), &m(r + 1, c + 5),
836
837 &m(r + 2, c + 0), &m(r + 2, c + 1), &m(r + 2, c + 2), &m(r + 2, c + 3),
838 &m(r + 2, c + 4), &m(r + 2, c + 5),
839
840 &m(r + 3, c + 0), &m(r + 3, c + 1), &m(r + 3, c + 2), &m(r + 3, c + 3),
841 &m(r + 3, c + 4), &m(r + 3, c + 5),
842
843 &m(r + 4, c + 0), &m(r + 4, c + 1), &m(r + 4, c + 2), &m(r + 4, c + 3),
844 &m(r + 4, c + 4), &m(r + 4, c + 5),
845
846 &m(r + 5, c + 0), &m(r + 5, c + 1), &m(r + 5, c + 2), &m(r + 5, c + 3),
847 &m(r + 5, c + 4), &m(r + 5, c + 5)
848
849 );
850 };
851 FTensor::Index<'i', 3> i;
852 FTensor::Index<'j', 3> j;
853 FTensor::Index<'k', 3> k;
854 FTensor::Index<'l', 3> l;
855 FTensor::Index<'m', 3> m;
856 FTensor::Index<'n', 3> n;
857
858 auto v = getVolume();
859 auto t_w = getFTensor0IntegrationWeight();
860
861 int row_nb_base_functions = row_data.getN().size2();
862 auto t_row_base_fun = row_data.getFTensor0N();
863
864 auto get_dP = [&]() {
865 dP.resize(size_symm * size_symm, nb_integration_pts, false);
866 auto ts_a = getTSa();
867
868 auto t_D = getFTensor4DdgFromPtr<3, 3, 0>(&*dataAtPts->matD.data().begin());
869
870 constexpr double nohat_k = 1. / 4;
871 constexpr double hat_k = 1. / 8;
872 double mu = dataAtPts->mu;
873 double lambda = dataAtPts->lambda;
874
875 constexpr double third = boost::math::constants::third<double>();
877 auto t_diff_deviator = diff_deviator(diff_tensor());
878
879 auto t_approx_P_adjoint__dstretch =
880 getFTensor2FromMat<3, 3>(dataAtPts->adjointPdstretchAtPts);
881 auto t_log_stretch_h1 =
882 getFTensor2SymmetricFromMat<3>(dataAtPts->logStretchTotalTensorAtPts);
883 auto t_eigen_vals = getFTensor1FromMat<3>(dataAtPts->eigenVals);
884 auto t_eigen_vecs = getFTensor2FromMat<3, 3>(dataAtPts->eigenVecs);
885 auto &nbUniq = dataAtPts->nbUniq;
886
887 auto t_dP = getFTensor2FromMat<size_symm, size_symm>(dP);
888 for (auto gg = 0; gg != nb_integration_pts; ++gg) {
889
890 double log_det = t_log_stretch_h1(i, i);
891 double log_det2 = log_det * log_det;
893 t_dev(i, j) = t_log_stretch_h1(i, j) - t_kd(i, j) * (third * log_det);
894 double dev_norm2 = t_dev(i, j) * t_dev(i, j);
895
896 auto A = 2 * mu * std::exp(nohat_k * dev_norm2);
897 auto B = lambda * std::exp(hat_k * log_det2) * log_det;
898
899 FTensor::Tensor2_symmetric<double, 3> t_A_diff, t_B_diff;
900 t_A_diff(i, j) =
901 (A * 2 * nohat_k) * (t_dev(k, l) * t_diff_deviator(k, l, i, j));
902 t_B_diff(i, j) = (B * 2 * hat_k) * log_det * t_kd(i, j) +
903 lambda * std::exp(hat_k * log_det2) * t_kd(i, j);
905 t_dT(i, j, k, l) =
906 t_A_diff(i, j) * (t_dev(m, n) * t_diff_deviator(m, n, k, l))
907
908 +
909
910 A * t_diff_deviator(m, n, i, j) * t_diff_deviator(m, n, k, l)
911
912 +
913
914 t_B_diff(i, j) * t_kd(k, l);
915
916 t_dP(L, J) = -t_L(i, j, L) *
917 ((
918
919 t_dT(i, j, k, l)
920
921 +
922
923 (alphaU * ts_a) * (t_D(i, j, m, n) * t_diff(m, n, k, l)
924
925 )) *
926 t_L(k, l, J));
927
928 // Work of symmetric tensor on undefined tensor is equal to the work
929 // of the symmetric part of it
933 t_sym(i, j) = (t_approx_P_adjoint__dstretch(i, j) ||
934 t_approx_P_adjoint__dstretch(j, i));
935 t_sym(i, j) /= 2.0;
936 auto t_diff2_uP2 = EigenMatrix::getDiffDiffMat(
937 t_eigen_vals, t_eigen_vecs, EshelbianCore::f, EshelbianCore::d_f,
938 EshelbianCore::dd_f, t_sym, nbUniq[gg]);
939 t_dP(L, J) += t_L(i, j, L) *
940 ((t_diff2_uP2(i, j, k, l) + t_diff2_uP2(k, l, i, j)) *
941 t_L(k, l, J)) /
942 2.;
943 }
944
945 ++t_dP;
946 ++t_approx_P_adjoint__dstretch;
947 ++t_log_stretch_h1;
948 ++t_eigen_vals;
949 ++t_eigen_vecs;
950 }
951
952 return getFTensor2FromMat<size_symm, size_symm>(dP);
953 };
954
955 auto t_dP = get_dP();
956 for (int gg = 0; gg != nb_integration_pts; ++gg) {
957 double a = v * t_w;
958
959 int rr = 0;
960 for (; rr != row_nb_dofs / 6; ++rr) {
961 auto t_col_base_fun = col_data.getFTensor0N(gg, 0);
962 auto t_m = get_ftensor2(K, 6 * rr, 0);
963 for (int cc = 0; cc != col_nb_dofs / 6; ++cc) {
964 const double b = a * t_row_base_fun * t_col_base_fun;
965 t_m(L, J) -= b * t_dP(L, J);
966 ++t_m;
967 ++t_col_base_fun;
968 }
969 ++t_row_base_fun;
970 }
971
972 for (; rr != row_nb_base_functions; ++rr) {
973 ++t_row_base_fun;
974 }
975
976 ++t_w;
977 ++t_dP;
978 }
980}
981
983 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
984 boost::shared_ptr<double> total_energy_ptr)
985 : VolUserDataOperator(NOSPACE, OPSPACE), dataAtPts(data_ptr),
986 totalEnergyPtr(total_energy_ptr) {
987
988 if (!dataAtPts) {
990 "dataAtPts is not allocated. Please set it before "
991 "using this operator.");
992 }
993
994}
995
996MoFEMErrorCode HMHHencky::OpCalculateEnergy::doWork(int side, EntityType type,
997 EntData &data) {
999
1004
1005 int nb_integration_pts = getGaussPts().size2();
1006 auto t_log_u =
1007 getFTensor2SymmetricFromMat<3>(dataAtPts->logStretchTotalTensorAtPts);
1008
1009
1010 auto &mat_d = dataAtPts->matD;
1011 if (mat_d.size1() != size_symm || mat_d.size2() != size_symm) {
1012 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1013 "wrong matD size, should be 6 by 6 but is %d by %d", size_symm,
1014 size_symm);
1015 }
1016
1017 auto t_D = getFTensor4DdgFromPtr<3, 3, 0>(mat_d.data().data());
1018
1019 dataAtPts->energyAtPts.resize(nb_integration_pts, false);
1020 auto t_energy = getFTensor0FromVec(dataAtPts->energyAtPts);
1021
1022 for (auto gg = 0; gg != nb_integration_pts; ++gg) {
1023
1024 t_energy = 0.5 * (t_log_u(i, j) * (t_D(i, j, k, l) * t_log_u(k, l)));
1025
1026 ++t_log_u;
1027 ++t_energy;
1028 }
1029
1030 if (totalEnergyPtr) {
1031 auto t_w = getFTensor0IntegrationWeight();
1032 auto t_energy = getFTensor0FromVec(dataAtPts->energyAtPts);
1033 double loc_energy = 0;
1034 for (auto gg = 0; gg != nb_integration_pts; ++gg) {
1035 loc_energy += t_energy * t_w;
1036 ++t_w;
1037 ++t_energy;
1038 }
1039 *totalEnergyPtr += getMeasure() * loc_energy;
1040 }
1041
1043}
1044
1046 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
1047 boost::shared_ptr<MatrixDouble> strain_ptr,
1048 boost::shared_ptr<MatrixDouble> stress_ptr,
1049 boost::shared_ptr<HMHHencky> hencky_ptr)
1050 : VolUserDataOperator(NOSPACE, OPSPACE), dataAtPts(data_ptr),
1051 strainPtr(strain_ptr), stressPtr(stress_ptr), henckyPtr(hencky_ptr) {}
1052
1054 EntityType type,
1055 EntData &data) {
1057
1064
1065 auto nb_integration_pts = stressPtr->size2();
1066#ifndef NDEBUG
1067 if (nb_integration_pts != getGaussPts().size2()) {
1068 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1069 "inconsistent number of integration points");
1070 }
1071#endif // NDEBUG
1072
1073 auto get_D = [&]() {
1075 for (auto &b : henckyPtr->blockData) {
1076
1077 if (b.blockEnts.find(getFEEntityHandle()) != b.blockEnts.end()) {
1078 dataAtPts->mu = b.shearModulusG;
1079 dataAtPts->lambda = b.bulkModulusK - 2 * b.shearModulusG / 3;
1080 CHKERR henckyPtr->getMatDPtr(
1081 dataAtPts->getMatDPtr(), dataAtPts->getMatAxiatorDPtr(),
1082 dataAtPts->getMatDeviatorDPtr(), b.bulkModulusK, b.shearModulusG);
1083 CHKERR henckyPtr->getInvMatDPtr(dataAtPts->getMatInvDPtr(),
1084 b.bulkModulusK, b.shearModulusG);
1086 }
1087 }
1088
1089 const auto E = henckyPtr->E;
1090 const auto nu = henckyPtr->nu;
1091
1092 double bulk_modulus_K = E / (3 * (1 - 2 * nu));
1093 double shear_modulus_G = E / (2 * (1 + nu));
1094
1095 dataAtPts->mu = shear_modulus_G;
1096 dataAtPts->lambda = bulk_modulus_K - 2 * shear_modulus_G / 3;
1097
1098 CHKERR henckyPtr->getMatDPtr(
1099 dataAtPts->getMatDPtr(), dataAtPts->getMatAxiatorDPtr(),
1100 dataAtPts->getMatDeviatorDPtr(), bulk_modulus_K, shear_modulus_G);
1101 CHKERR henckyPtr->getInvMatDPtr(dataAtPts->getMatInvDPtr(), bulk_modulus_K,
1104 };
1105
1106 CHKERR get_D();
1107
1108 strainPtr->resize(size_symm, nb_integration_pts, false);
1109 auto t_strain = getFTensor2SymmetricFromMat<3>(*strainPtr);
1110 auto t_stress = getFTensor2FromMat<SPACE_DIM, SPACE_DIM>(*stressPtr);
1111 auto t_inv_D = getFTensor4DdgFromPtr<SPACE_DIM, SPACE_DIM, 0>(
1112 &*dataAtPts->matInvD.data().begin());
1113#ifndef NDEBUG
1114 auto t_D = getFTensor4DdgFromPtr<SPACE_DIM, SPACE_DIM, 0>(
1115 &*dataAtPts->matD.data().begin());
1116#endif
1117
1119
1120 // note: add rotation, so we can extract rigid body motion, work then with
1121 // symmetric part.
1122 for (auto gg = 0; gg != nb_integration_pts; ++gg) {
1123 t_strain(i, j) = t_inv_D(i, j, k, l) * t_stress(k, l);
1124
1125#ifndef NDEBUG
1126 FTensor::Tensor2_symmetric<double, 3> t_stress_symm_debug;
1127 t_stress_symm_debug(i, j) = (t_stress(i, j) || t_stress(j, i)) / 2;
1128 FTensor::Tensor2_symmetric<double, 3> t_stress_symm_debug_diff;
1129 t_stress_symm_debug_diff(i, j) =
1130 t_D(i, j, k, l) * t_strain(k, l) - t_stress_symm_debug(i, j);
1131 double nrm =
1132 t_stress_symm_debug_diff(i, j) * t_stress_symm_debug_diff(i, j);
1133 double nrm0 = t_stress_symm_debug(i, j) * t_stress_symm_debug(i, j) +
1134 std::numeric_limits<double>::epsilon();
1135 constexpr double eps = 1e-10;
1136 if (std::fabs(std::sqrt(nrm / nrm0)) > eps) {
1137 MOFEM_LOG("SELF", Sev::error)
1138 << "Stress symmetry check failed: " << std::endl
1139 << t_stress_symm_debug_diff << std::endl
1140 << t_stress;
1142 "Norm is too big: " + std::to_string(nrm / nrm0));
1143 }
1144 ++t_D;
1145#endif
1146
1147 ++t_strain;
1148 ++t_stress;
1149 ++t_inv_D;
1150 }
1151
1153}
1154
1155template <typename OP_PTR>
1156std::tuple<std::string, VectorDouble>
1157getAnalyticalExternalStrain(OP_PTR op_ptr, VectorDouble &analytical_expr,
1158 const std::string block_name) {
1159
1160 auto nb_gauss_pts = op_ptr->getGaussPts().size2();
1161
1162 auto ts_time = op_ptr->getTStime();
1163 auto ts_time_step = op_ptr->getTStimeStep();
1166 ts_time_step = EshelbianCore::dynamicStep;
1167 }
1168
1169 MatrixDouble m_ref_coords = op_ptr->getCoordsAtGaussPts();
1170
1171 auto v_analytical_expr = analytical_externalstrain_function(
1172 ts_time_step, ts_time, nb_gauss_pts, m_ref_coords, block_name);
1173
1174#ifndef NDEBUG
1175 if (v_analytical_expr.size() != nb_gauss_pts)
1177 "Wrong number of integration pts");
1178#endif // NDEBUG
1179
1180 return std::make_tuple(block_name, v_analytical_expr);
1181};
1182
1183// Topo
1184
1186 const std::string &field_name,
1187 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
1188 SmartPetscObj<Vec> assemble_vec,
1189 boost::shared_ptr<TopologicalData> topo_ptr, const double alpha_u)
1190 : OpAssembleVolume(field_name, data_ptr, OPROW), alphaU(alpha_u),
1191 topoDataPtr(topo_ptr), assembleVec(assemble_vec) {
1192
1193 CHK_MOAB_THROW(PetscOptionsGetBool(PETSC_NULLPTR, "", "-poly_convex",
1194 &polyConvex, PETSC_NULLPTR),
1195 "get polyconvex option failed");
1196}
1197
1200 if (polyConvex) {
1201 CHKERR integratePolyconvexHencky(data);
1202 } else {
1203 CHKERR integrateHencky(data);
1204 }
1206}
1207
1210
1211 FTensor::Index<'L', size_symm> L;
1212 auto t_L = symm_L_tensor();
1213
1214 int nb_dofs = data.getIndices().size();
1215 int nb_integration_pts = data.getN().size1();
1216 auto v = getVolume();
1217 auto t_w = getFTensor0IntegrationWeight();
1218 auto t_approx_P_adjoint_log_du =
1219 getFTensor1FromMat<size_symm>(dataAtPts->adjointPdUAtPts);
1220 auto t_log_stretch_h1 =
1221 getFTensor2SymmetricFromMat<3>(dataAtPts->logStretchTotalTensorAtPts);
1222 auto t_dot_log_u =
1223 getFTensor2SymmetricFromMat<3>(dataAtPts->logStretchDotTensorAtPts);
1224 auto t_var_log_u = getFTensor1FromMat<SPACE_DIM>(dataAtPts->varLogStreach);
1225
1226 auto t_D = getFTensor4DdgFromPtr<3, 3, 0>(&*dataAtPts->matD.data().begin());
1227
1228 auto t_det = getFTensor0FromVec(topoDataPtr->detJacobianAtPts);
1229 auto t_inv_jac =
1230 getFTensor2FromMat<SPACE_DIM, SPACE_DIM>(topoDataPtr->invJacobianAtPtr);
1231
1232 FTensor::Index<'i', 3> i;
1233 FTensor::Index<'j', 3> j;
1234 FTensor::Index<'k', 3> k;
1235 FTensor::Index<'l', 3> l;
1236 auto get_ftensor2 = [](auto &v) {
1238 &v[0], &v[1], &v[2], &v[3], &v[4], &v[5]);
1239 };
1240
1241 int nb_base_functions = data.getN().size2();
1242 auto t_diff_base = data.getFTensor1DiffN<3>();
1243 for (int gg = 0; gg != nb_integration_pts; ++gg) {
1244
1245 // Calculate the variation of the gradient due to geometry change
1247 t_cof(i, j) = t_det * t_inv_jac(j, i);
1248
1249
1250 double a = v * t_w;
1251 auto t_nf = get_ftensor2(nF);
1252
1254 t_T(i, j) =
1255 t_D(i, j, k, l) * (t_log_stretch_h1(k, l) + alphaU * t_dot_log_u(k, l));
1257 t_residual(L) =
1258 a * (t_approx_P_adjoint_log_du(L) - t_L(i, j, L) * t_T(i, j));
1259
1260 int bb = 0;
1261 for (; bb != nb_dofs / 6; ++bb) {
1262 t_nf(i) -=
1263 t_var_log_u(L) * t_residual(L) * t_cof(i, j) * t_diff_base(j);
1264 ++t_nf;
1265 ++t_diff_base;
1266 }
1267 for (; bb != nb_base_functions; ++bb)
1268 ++t_diff_base;
1269
1270 ++t_w;
1271 ++t_approx_P_adjoint_log_du;
1272 ++t_dot_log_u;
1273 ++t_log_stretch_h1;
1274 ++t_var_log_u;
1275
1276 ++t_det;
1277 ++t_inv_jac;
1278 }
1280}
1281
1282MoFEMErrorCode
1285 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
1286 "Polyconvex Hencky is not implemented yet");
1288}
1289
1292 double *vec_ptr = nF.data().data();
1293 const int nb_dofs = data.getIndices().size();
1294 int *ind_ptr = data.getIndices().data().data();
1295 CHKERR VecSetValues(assembleVec, nb_dofs, ind_ptr, vec_ptr, ADD_VALUES);
1297}
1298
1299} // namespace EshelbianPlasticity
constexpr double third
#define MOFEM_TAG_AND_LOG(channel, severity, tag)
Tag and log in channel.
#define FTENSOR_INDEX(DIM, I)
constexpr double a
static PetscErrorCode ierr
static const double eps
constexpr int SPACE_DIM
Kronecker Delta class symmetric.
#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 ...
#define CHKERRG(n)
Check error code of MoFEM/MOAB/PETSc function.
#define CHK_MOAB_THROW(err, msg)
Check error code of MoAB function and throw MoFEM exception.
@ 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.
double bulk_modulus_K
double shear_modulus_G
constexpr auto t_kd
auto get_D
Create deviatoric stress tensor.
#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 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.
VectorDouble analytical_externalstrain_function(double delta_t, double t, int nb_gauss_pts, MatrixDouble &m_ref_coords, const std::string block_name)
auto diff_deviator(FTensor::Ddg< double, 3, 3 > &&t_diff_stress)
std::tuple< std::string, VectorDouble > getAnalyticalExternalStrain(OP_PTR op_ptr, VectorDouble &analytical_expr, const std::string block_name)
ForcesAndSourcesCore::UserDataOperator UserDataOperator
static constexpr auto size_symm
constexpr AssemblyType A
constexpr auto field_name
FTensor::Index< 'm', 3 > m
static enum StretchSelector stretchSelector
static double dynamicTime
static int dynamicStep
static enum RotSelector gradApproximator
static PetscBool dynamicRelaxation
static boost::function< double(const double)> f
static boost::function< double(const double)> dd_f
static boost::function< double(const double)> d_f
Calculate energy density for Hencky material model.
MoFEMErrorCode doWork(int side, EntityType type, EntData &data)
OpCalculateEnergy(boost::shared_ptr< DataAtIntegrationPts > data_ptr, boost::shared_ptr< double > total_energy_ptr)
boost::shared_ptr< DataAtIntegrationPts > dataAtPts
boost::shared_ptr< DataAtIntegrationPts > dataAtPts
data at integration pts
MoFEMErrorCode doWork(int side, EntityType type, EntData &data)
OpCalculateStretchFromStress(boost::shared_ptr< DataAtIntegrationPts > data_ptr, boost::shared_ptr< MatrixDouble > strain_ptr, boost::shared_ptr< MatrixDouble > stress_ptr, boost::shared_ptr< HMHHencky > hencky_ptr)
MoFEMErrorCode evaluateRhs(EntData &data)
Definition HMHHencky.cpp:62
boost::shared_ptr< HMHHencky > henckyPtr
Definition HMHHencky.cpp:67
MoFEMErrorCode evaluateLhs(EntData &data)
Definition HMHHencky.cpp:63
OpHenckyJacobian(boost::shared_ptr< DataAtIntegrationPts > data_ptr, boost::shared_ptr< HMHHencky > hencky_ptr)
Definition HMHHencky.cpp:21
boost::shared_ptr< DataAtIntegrationPts > dataAtGaussPts
Definition HMHHencky.cpp:66
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
Definition HMHHencky.cpp:30
std::map< std::string, boost::shared_ptr< ScalingMethod > > scalingMethodsMap
boost::shared_ptr< ExternalStrainVec > externalStrainVecPtr
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 integrateHencky(EntData &row_data, EntData &col_data)
MoFEMErrorCode integratePolyconvexHencky(EntData &row_data, EntData &col_data)
MoFEMErrorCode integrate(EntData &row_data, EntData &col_data)
MoFEMErrorCode integratePolyconvexHencky(EntData &data)
OpSpatialPhysical(const std::string &field_name, boost::shared_ptr< DataAtIntegrationPts > data_ptr, const double alpha_u)
MoFEMErrorCode integrateHencky(EntData &data)
OpTopoSpatialPhysical(const std::string &field_name, boost::shared_ptr< DataAtIntegrationPts > data_ptr, SmartPetscObj< Vec > assemble_vec, boost::shared_ptr< TopologicalData > topo_ptr, const double alpha_u)
boost::shared_ptr< TopologicalData > topoDataPtr
MoFEMErrorCode integratePolyconvexHencky(EntData &data)
MoFEMErrorCode assemble(EntData &data) override
virtual VolUserDataOperator * returnOpSpatialPhysical(const std::string &field_name, boost::shared_ptr< DataAtIntegrationPts > data_ptr, const double alpha_u)
Definition HMHHencky.cpp:96
VolUserDataOperator * returnOpCalculateStretchFromStress(boost::shared_ptr< DataAtIntegrationPts > data_ptr, boost::shared_ptr< PhysicalEquations > physics_ptr)
MoFEMErrorCode extractBlockData(Sev sev)
std::vector< BlockData > blockData
virtual VolUserDataOperator * returnOpTopoSpatialPhysical(const std::string &field_name, boost::shared_ptr< DataAtIntegrationPts > data_ptr, SmartPetscObj< Vec > assemble_vec, boost::shared_ptr< TopologicalData > topo_ptr, const double alpha_u)
MoFEMErrorCode extractBlockData(std::vector< const CubitMeshSets * > meshset_vec_ptr, Sev sev)
HMHHencky(MoFEM::Interface &m_field, const double E, const double nu)
Definition HMHHencky.cpp:15
VolUserDataOperator * returnOpCalculateVarStretchFromStress(boost::shared_ptr< DataAtIntegrationPts > data_ptr, boost::shared_ptr< PhysicalEquations > physics_ptr)
VolUserDataOperator * returnOpCalculateEnergy(boost::shared_ptr< DataAtIntegrationPts > data_ptr, boost::shared_ptr< double > total_energy_ptr)
MoFEMErrorCode getMatDPtr(boost::shared_ptr< MatrixDouble > mat_D_ptr, boost::shared_ptr< MatrixDouble > mat_axiator_D_ptr, boost::shared_ptr< MatrixDouble > mat_deviator_D_ptr, double bulk_modulus_K, double shear_modulus_G)
MoFEMErrorCode getOptions(boost::shared_ptr< DataAtIntegrationPts > data_ptr)
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)
Definition HMHHencky.cpp:71
VolUserDataOperator * returnOpSpatialPhysical_du_du(std::string row_field, std::string col_field, boost::shared_ptr< DataAtIntegrationPts > data_ptr, const double alpha)
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)
MoFEMErrorCode recordTape(const int tag, DTensor2Ptr *t_h)
Definition HMHHencky.cpp:18
MoFEMErrorCode getInvMatDPtr(boost::shared_ptr< MatrixDouble > mat_inv_D_ptr, double bulk_modulus_K, double shear_modulus_G)
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 young_modulus
Young modulus.
Definition plastic.cpp:125
double poisson_ratio
Poisson ratio.
Definition plastic.cpp:126
double scale
Definition plastic.cpp:123