v0.16.0
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
10namespace EshelbianPlasticity {
11
12static auto G_eff(double C10, double tau) {
13 return 2.0 * C10 * std::exp(-2.0 * tau / 3.0);
14};
15
16static auto E_eff(double C10, double K, double tau) {
17 const double G = 2.0 * C10 * std::exp(-2.0 * tau / 3.0);
18 return G * (3.0 * K + 2.0 * G) / (K + G);
19};
20
21static auto nu_eff(double C10, double K, double tau) {
22 const double G = 2.0 * C10 * std::exp(-2.0 * tau / 3.0);
23 return K / (2.0 * (K + G));
24};
25
26static auto calc_c10(double E, double nu) { return E / (4.0 * (1.0 + nu)); };
27
28static auto calc_K(double E, double nu) {
29 // K in your energy: 0.5 * K * log(J)^2
30 // This is the Lame parameter lambda.
31 return E * nu / ((1.0 + nu) * (1.0 - 2.0 * nu));
32};
33
34static auto calc_bulk_modulus(double lambda, double shear_modulus_G) {
35 return lambda + 2.0 * shear_modulus_G / 3.0;
36}
37
45
46static auto calc_effective_elastic_params(double E, double nu,
47 double diagonal_strain) {
48 const double c10 = calc_c10(E, nu);
49 const double lambda = calc_K(E, nu);
50 const double shear_modulus_G = G_eff(c10, diagonal_strain);
52 const double young_modulus = E_eff(c10, lambda, diagonal_strain);
53 const double poisson_ratio = nu_eff(c10, lambda, diagonal_strain);
54
57}
58
60
61 HMHHencky(MoFEM::Interface &m_field, const double E, const double nu)
62 : PhysicalEquations(), mField(m_field), E(E), nu(nu) {}
63
64 static constexpr int StrideMatD =
66
67 template <int STRIDEMATD = 0> struct OpHenckyJacobian : public OpJacobian {
68 OpHenckyJacobian(boost::shared_ptr<DataAtIntegrationPts> data_ptr,
69 boost::shared_ptr<HMHHencky> hencky_ptr)
70 : OpJacobian(H1, OPLAST), dataAtGaussPts(data_ptr),
71 henckyPtr(hencky_ptr) {
72 std::fill(&doEntities[MBVERTEX], &doEntities[MBMAXTYPE], false);
73 doEntities[MBVERTEX] = true;
74 }
75
76 MoFEMErrorCode doWork(int side, EntityType type,
77 EntitiesFieldData::EntData &data) {
79 CHKERR henckyPtr->computeMaterialParamsAtPts<STRIDEMATD>(this, data,
82 }
83
84 MoFEMErrorCode evaluateRhs(EntData &data) { return 0; }
85 MoFEMErrorCode evaluateLhs(EntData &data) { return 0; }
86
87 private:
88 boost::shared_ptr<DataAtIntegrationPts> dataAtGaussPts;
89 boost::shared_ptr<HMHHencky> henckyPtr;
90 };
91
92 virtual UserDataOperator *
93 returnOpJacobian(const bool eval_rhs, const bool eval_lhs,
94 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
95 boost::shared_ptr<PhysicalEquations> physics_ptr) {
96
97 auto henckyPtr = boost::dynamic_pointer_cast<HMHHencky>(physics_ptr);
98
99 CHK_THROW_MESSAGE(henckyPtr->getOptions(data_ptr), "getOptions failed");
100 CHK_THROW_MESSAGE(henckyPtr->extractBlockData(Sev::verbose),
101 "Can not get data from block");
102
103 // Check if any heterogeneous or analytical block exists
104 for (const auto &b : henckyPtr->blockData) {
105 if (b.matType != HenckyMatType::HOMOGENEOUS) {
107 MOFEM_LOG("WORLD", Sev::verbose)
108 << "Found non-homogeneous material block: " << b.blockName;
109 break;
110 }
111 }
112
115 data_ptr, boost::dynamic_pointer_cast<HMHHencky>(physics_ptr)));
116 } else {
117 return (new OpHenckyJacobian<0>(
118 data_ptr, boost::dynamic_pointer_cast<HMHHencky>(physics_ptr)));
119 }
120 }
121
122 template <int STRIDEMATD = 0>
124
125 OpSpatialPhysical(const std::string &field_name,
126 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
127 const double alpha_u);
128
129 MoFEMErrorCode integrate(EntData &data);
130
131 MoFEMErrorCode integrateHencky(EntData &data);
132
133 MoFEMErrorCode integratePolyconvexHencky(EntData &data);
134
135 private:
136 const double alphaU;
137 PetscBool polyConvex = PETSC_FALSE;
138 };
139
140 virtual VolUserDataOperator *
142 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
143 const double alpha_u) {
145 return new OpSpatialPhysical<StrideMatD>(field_name, data_ptr, alpha_u);
146 } else {
147 return new OpSpatialPhysical<0>(field_name, data_ptr, alpha_u);
148 }
149 }
150
153 const std::string &field_name,
154 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
155 boost::shared_ptr<ExternalStrainVec> &external_strain_vec_ptr,
156 std::map<std::string, boost::shared_ptr<ScalingMethod>> smv);
157
158 MoFEMErrorCode integrate(EntData &data);
159
160 private:
161 boost::shared_ptr<ExternalStrainVec> externalStrainVecPtr;
162 std::map<std::string, boost::shared_ptr<ScalingMethod>> scalingMethodsMap;
163 };
164
166 const std::string &field_name,
167 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
168 boost::shared_ptr<ExternalStrainVec> external_strain_vec_ptr,
169 std::map<std::string, boost::shared_ptr<ScalingMethod>> smv) {
170 return new OpSpatialPhysicalExternalStrain(field_name, data_ptr,
171 external_strain_vec_ptr, smv);
172 }
173
174 template <int STRIDEMATD = 0>
176 const double alphaU;
177 OpSpatialPhysical_du_du(std::string row_field, std::string col_field,
178 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
179 const double alpha);
180 MoFEMErrorCode integrate(EntData &row_data, EntData &col_data);
181 MoFEMErrorCode integrateHencky(EntData &row_data, EntData &col_data);
182 MoFEMErrorCode integratePolyconvexHencky(EntData &row_data,
183 EntData &col_data);
184
185 private:
186 PetscBool polyConvex = PETSC_FALSE;
187
188 MatrixDouble dP;
189 };
190
192 std::string row_field, std::string col_field,
193 boost::shared_ptr<DataAtIntegrationPts> data_ptr, const double alpha) {
194
196 return new OpSpatialPhysical_du_du<StrideMatD>(row_field, col_field,
197 data_ptr, alpha);
198 } else {
199 return new OpSpatialPhysical_du_du<0>(row_field, col_field, data_ptr,
200 alpha);
201 }
202 }
203
204 /**
205 * @brief Calculate energy density for Hencky material model
206 *
207 *
208 * \f[
209 *
210 * \Psi(\log{\mathbf{U}}) = \frac{1}{2} U_{IJ} D_{IJKL} U_{KL} = \frac{1}{2}
211 * U_{IJ} T_{IJ}
212 *
213 * \f]
214 * where \f$T_{IJ} = D_{IJKL} U_{KL}\f$ is a a Hencky stress.
215 *
216 */
217 template <int STRIDEMATD>
219
220 OpCalculateEnergy(boost::shared_ptr<DataAtIntegrationPts> data_ptr,
221 boost::shared_ptr<double> total_energy_ptr);
222 MoFEMErrorCode doWork(int side, EntityType type, EntData &data);
223
224 private:
225 boost::shared_ptr<DataAtIntegrationPts> dataAtPts;
226 boost::shared_ptr<double> totalEnergyPtr;
227 };
228
230 returnOpCalculateEnergy(boost::shared_ptr<DataAtIntegrationPts> data_ptr,
231 boost::shared_ptr<double> total_energy_ptr) {
232
234 return new OpCalculateEnergy<StrideMatD>(data_ptr, total_energy_ptr);
235 } else {
236 return new OpCalculateEnergy<0>(data_ptr, total_energy_ptr);
237 }
238 }
239
240 template <int STRIDEMATD = 0>
243 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
244 boost::shared_ptr<MatrixDouble> strain_ptr,
245 boost::shared_ptr<MatrixDouble> stress_ptr,
246 boost::shared_ptr<HMHHencky> hencky_ptr);
247 MoFEMErrorCode doWork(int side, EntityType type, EntData &data);
248
249 private:
250 boost::shared_ptr<DataAtIntegrationPts>
251 dataAtPts; ///< data at integration pts
252 boost::shared_ptr<MatrixDouble> strainPtr;
253 boost::shared_ptr<MatrixDouble> stressPtr;
254 boost::shared_ptr<HMHHencky> henckyPtr;
255 };
256
258 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
259 boost::shared_ptr<PhysicalEquations> physics_ptr,
260 boost::shared_ptr<MatrixDouble> strain_ptr) override {
261 auto henckyPtr = boost::dynamic_pointer_cast<HMHHencky>(physics_ptr);
262
263 CHK_THROW_MESSAGE(henckyPtr->getOptions(data_ptr), "getOptions failed");
264 CHK_THROW_MESSAGE(henckyPtr->extractBlockData(Sev::verbose),
265 "Can not get data from block");
266
267 // Check if any heterogeneous or analytical block exists
268 for (const auto &b : henckyPtr->blockData) {
269 if (b.matType != HenckyMatType::HOMOGENEOUS) {
271 MOFEM_LOG("WORLD", Sev::verbose)
272 << "Found non-homogeneous material block: " << b.blockName;
273 break;
274 }
275 }
276
279 data_ptr,
280 strain_ptr ? strain_ptr : data_ptr->getLogStretchTensorAtPts(),
281 data_ptr->getApproxPAtPts(),
282 boost::dynamic_pointer_cast<HMHHencky>(physics_ptr));
283 } else {
285 data_ptr,
286 strain_ptr ? strain_ptr : data_ptr->getLogStretchTensorAtPts(),
287 data_ptr->getApproxPAtPts(),
288 boost::dynamic_pointer_cast<HMHHencky>(physics_ptr));
289 }
290 }
291
293 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
294 boost::shared_ptr<PhysicalEquations> physics_ptr) {
295 auto henckyPtr = boost::dynamic_pointer_cast<HMHHencky>(physics_ptr);
296
297 CHK_THROW_MESSAGE(henckyPtr->getOptions(data_ptr), "getOptions failed");
298 CHK_THROW_MESSAGE(henckyPtr->extractBlockData(Sev::verbose),
299 "Can not get data from block");
300
301 // Check if any heterogeneous or analytical block exists
302 for (const auto &b : henckyPtr->blockData) {
303 if (b.matType != HenckyMatType::HOMOGENEOUS) {
305 MOFEM_LOG("WORLD", Sev::verbose)
306 << "Found non-homogeneous material block: " << b.blockName;
307 break;
308 }
309 }
310
313 data_ptr, data_ptr->getVarLogStreachPts(), data_ptr->getVarPiolaPts(),
314 boost::dynamic_pointer_cast<HMHHencky>(physics_ptr));
315 } else {
317 data_ptr, data_ptr->getVarLogStreachPts(), data_ptr->getVarPiolaPts(),
318 boost::dynamic_pointer_cast<HMHHencky>(physics_ptr));
319 }
320 }
321
322 MoFEMErrorCode getOptions(boost::shared_ptr<DataAtIntegrationPts> data_ptr) {
324 PetscOptionsBegin(PETSC_COMM_WORLD, "hencky_", "", "none");
325
326 CHKERR PetscOptionsScalar("-young_modulus", "Young modulus", "", E, &E,
327 PETSC_NULLPTR);
328 CHKERR PetscOptionsScalar("-poisson_ratio", "poisson ratio", "", nu, &nu,
329 PETSC_NULLPTR);
330 CHKERR PetscOptionsBool("-effective_neohookean_stiffness",
331 "Use effective Neo-Hookean stiffness", "",
333 &effectiveNehookeanStiffness, PETSC_NULLPTR);
334 CHKERR PetscOptionsScalar("-effective_diagonal_strain",
335 "Diagonal logarithmic strain for effective "
336 "Neo-Hookean stiffness",
338 &effectiveDiagonalStrain, PETSC_NULLPTR);
339
340 PetscOptionsEnd();
341
343 << "Hencky: E = " << E << " nu = " << nu
344 << " effective_neohookean_stiffness = "
345 << (effectiveNehookeanStiffness ? "true" : "false")
346 << " effective_diagonal_strain = " << effectiveDiagonalStrain;
347 getOptionsSeverityLevels = Sev::verbose;
348
349 CHKERRG(ierr);
350
352 }
353
354 MoFEMErrorCode extractBlockData(Sev sev) {
355 return extractBlockData(
356
357 mField.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(std::regex(
358
359 (boost::format("(.*)%s(.*)") % "_ELASTIC").str()
360
361 )),
362
363 sev);
364 }
365
366 MoFEMErrorCode
367 extractBlockData(std::vector<const CubitMeshSets *> meshset_vec_ptr,
368 Sev sev) {
370
371 for (auto m : meshset_vec_ptr) {
372 MOFEM_TAG_AND_LOG("WORLD", sev, "MatBlock") << *m;
373 std::string block_name = m->getName();
374
375 auto block_name_heterogeneous = "(.*)HETEROGENEOUS_ELASTIC(.*)";
376 auto block_name_analytical = "(.*)ANALYTICAL_ELASTIC(.*)";
377 std::regex reg_name_heterogeneous(block_name_heterogeneous);
378 std::regex reg_name_analytical(block_name_analytical);
379 const bool is_heterogeneous =
380 std::regex_match(block_name, reg_name_heterogeneous);
381 const bool is_analytical =
382 std::regex_match(block_name, reg_name_analytical);
383
384 std::vector<double> block_data;
385 CHKERR m->getAttributes(block_data);
386 if (block_data.size() < 2) {
387 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
388 "Expected that block has atleast two attributes");
389 }
390 auto get_block_ents = [&]() {
391 Range ents;
392 CHKERR mField.get_moab().get_entities_by_handle(m->meshset, ents, true);
393 return ents;
394 };
395
396 double young_modulus = block_data[0];
397 double poisson_ratio = block_data[1];
398
400 if (is_heterogeneous) {
402 } else if (is_analytical) {
403 mat_type = HenckyMatType::ANALYTICAL;
404 }
405
407 mat_type == HenckyMatType::HOMOGENEOUS) {
408 const auto effective_params = calc_effective_elastic_params(
410 young_modulus = effective_params.youngModulus;
411 poisson_ratio = effective_params.poissonRatio;
412 }
413
414 double bulk_modulus_K = young_modulus / (3 * (1 - 2 * poisson_ratio));
415 double shear_modulus_G = young_modulus / (2 * (1 + poisson_ratio));
416
417 MOFEM_TAG_AND_LOG("WORLD", sev, "MatBlock")
418 << "E = " << young_modulus << " nu = " << poisson_ratio;
419
420 blockData.push_back({block_name, young_modulus, poisson_ratio,
421 bulk_modulus_K, shear_modulus_G, get_block_ents(),
422 mat_type});
423 }
424 MOFEM_LOG_CHANNEL("WORLD");
426 }
427
428 template <int STRIDEMATD, typename OP_PTR>
430 OP_PTR op_ptr, EntitiesFieldData::EntData &data,
431 boost::shared_ptr<DataAtIntegrationPts> dataAtGaussPts) {
433
434 auto getMaterialParams = [&](double E, double nu) {
437 }
438
439 const double bulk_modulus_K = E / (3 * (1 - 2 * nu));
440 const double shear_modulus_G = E / (2 * (1 + nu));
441 const double lambda = bulk_modulus_K - 2 * shear_modulus_G / 3;
443 lambda};
444 };
445
446 auto fe_ent = op_ptr->getNumeredEntFiniteElementPtr()->getEnt();
447 int nb_integration_pts = op_ptr->getGaussPts().size2();
448
449 dataAtGaussPts->muAtPts.resize(nb_integration_pts, false);
450 dataAtGaussPts->lambdaAtPts.resize(nb_integration_pts, false);
451 dataAtGaussPts->muAtPts.clear();
452 dataAtGaussPts->lambdaAtPts.clear();
453
454 dataAtGaussPts->youngModulusAtPts.resize(nb_integration_pts, false);
455 dataAtGaussPts->youngModulusAtPts.clear();
456
457 auto t_young_modulus =
458 getFTensor0FromVec(dataAtGaussPts->youngModulusAtPts);
459 auto t_mu = getFTensor0FromVec(dataAtGaussPts->muAtPts);
460 auto t_lambda = getFTensor0FromVec(dataAtGaussPts->lambdaAtPts);
461
462 MatrixSizeHelper<
463 GetFTensor4DdgFromMatType<SPACE_DIM, SPACE_DIM, STRIDEMATD, DL>,
464 DL>::size(dataAtGaussPts->matD, nb_integration_pts);
465 MatrixSizeHelper<
466 GetFTensor4DdgFromMatType<SPACE_DIM, SPACE_DIM, STRIDEMATD, DL>,
467 DL>::size(dataAtGaussPts->matAxiatorD, nb_integration_pts);
468 MatrixSizeHelper<
469 GetFTensor4DdgFromMatType<SPACE_DIM, SPACE_DIM, STRIDEMATD, DL>,
470 DL>::size(dataAtGaussPts->matDeviatorD, nb_integration_pts);
471 MatrixSizeHelper<
472 GetFTensor4DdgFromMatType<SPACE_DIM, SPACE_DIM, STRIDEMATD, DL>,
473 DL>::size(dataAtGaussPts->matInvD, nb_integration_pts);
474
475 dataAtGaussPts->matD.clear();
476 dataAtGaussPts->matAxiatorD.clear();
477 dataAtGaussPts->matDeviatorD.clear();
478 dataAtGaussPts->matInvD.clear();
479
485
486 auto t_D = getFTensor4DdgFromMat<SPACE_DIM, SPACE_DIM, STRIDEMATD>(
487 dataAtGaussPts->matD);
488 auto t_axiator_D = getFTensor4DdgFromMat<SPACE_DIM, SPACE_DIM, STRIDEMATD>(
489 dataAtGaussPts->matAxiatorD);
490 auto t_deviator_D = getFTensor4DdgFromMat<SPACE_DIM, SPACE_DIM, STRIDEMATD>(
491 dataAtGaussPts->matDeviatorD);
492 auto t_inv_D = getFTensor4DdgFromMat<SPACE_DIM, SPACE_DIM, STRIDEMATD>(
493 dataAtGaussPts->matInvD);
494
495 auto next = [&]() {
496 ++t_young_modulus;
497 ++t_mu;
498 ++t_lambda;
499 ++t_D;
500 ++t_axiator_D;
501 ++t_deviator_D;
502 ++t_inv_D;
503 };
504
505 auto evalMatD = [&](double bulk_modulus_K, double shear_modulus_G) {
507 t_axiator_D(i, j, k, l) = (bulk_modulus_K - (2. / 3.) * shear_modulus_G) *
508 t_kd(i, j) * t_kd(k, l);
509 t_deviator_D(i, j, k, l) =
510 2 * shear_modulus_G * ((t_kd(i, k) ^ t_kd(j, l)) / 4.);
511 t_D(i, j, k, l) = t_axiator_D(i, j, k, l) + t_deviator_D(i, j, k, l);
513 };
514
515 auto evalInvMatDPtr = [&](double bulk_modulus_K, double shear_modulus_G) {
517 const double A = 1. / (2. * shear_modulus_G);
518 const double B =
519 (1. / (9. * bulk_modulus_K)) - (1. / (6. * shear_modulus_G));
520 t_inv_D(i, j, k, l) =
521 A * ((t_kd(i, k) ^ t_kd(j, l)) / 4.) + B * t_kd(i, j) * t_kd(k, l);
523 };
524
525 // from block data (MAT_ELASTIC) or (ANALYTICAL_ELASTIC) if provided,
526 // otherwise from command line options
527 for (auto &b : this->blockData) {
528 if (b.blockEnts.find(op_ptr->getFEEntityHandle()) != b.blockEnts.end()) {
529
530 if (b.matType == HMHHencky::HenckyMatType::ANALYTICAL) {
531 VectorDouble analytical_elastic;
532 analytical_elastic = getAnalyticalElastic(op_ptr, b.blockName);
533
534 auto t_analytical_elastic = getFTensor0FromVec(analytical_elastic);
535
536 for (int gg = 0; gg != nb_integration_pts; ++gg) {
537 const auto material_params =
538 getMaterialParams(t_analytical_elastic, b.poissonRatio);
539 t_young_modulus = material_params.youngModulus;
540 t_mu = material_params.shearModulusG;
541 t_lambda = material_params.lambda;
542
543 CHKERR evalMatD(material_params.bulkModulusK,
544 material_params.shearModulusG);
545 CHKERR evalInvMatDPtr(material_params.bulkModulusK,
546 material_params.shearModulusG);
547 ++t_analytical_elastic;
548 next();
549 }
550
551 } else if (b.matType == HMHHencky::HenckyMatType::HETEROGENEOUS) {
552 Tag tag_heterogenous_mat;
553 CHKERR op_ptr->getPtrFE()->mField.get_moab().tag_get_handle(
555 tag_heterogenous_mat);
556 int tag_length;
557 CHKERR op_ptr->getPtrFE()->mField.get_moab().tag_get_length(
558 tag_heterogenous_mat, tag_length);
559 if (tag_length != 1) {
560 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
561 "heterogeneous Young's modulus tag should be 1 but is %d",
562 tag_length);
563 }
565 // Constant interpolation (element-wise)
566 double elem_young_mod = 0.0;
567 CHKERR op_ptr->getPtrFE()->mField.get_moab().tag_get_data(
568 tag_heterogenous_mat, &fe_ent, 1, &elem_young_mod);
569
570 for (int gg = 0; gg != nb_integration_pts; ++gg) {
571 const auto material_params =
572 getMaterialParams(elem_young_mod, b.poissonRatio);
573 t_young_modulus = material_params.youngModulus;
574 t_mu = material_params.shearModulusG;
575 t_lambda = material_params.lambda;
576
577 CHKERR evalMatD(material_params.bulkModulusK,
578 material_params.shearModulusG);
579 CHKERR evalInvMatDPtr(material_params.bulkModulusK,
580 material_params.shearModulusG);
581 next();
582 }
584 // Linear interpolation (vertex-based)
585 const EntityHandle *vert_conn;
586 int vert_num;
587 CHKERR op_ptr->getPtrFE()->mField.get_moab().get_connectivity(
588 fe_ent, vert_conn, vert_num, true);
589
590 VectorDouble vert_young_mod(vert_num);
591 CHKERR op_ptr->getPtrFE()->mField.get_moab().tag_get_data(
592 tag_heterogenous_mat, vert_conn, vert_num, &vert_young_mod[0]);
593
594 auto t_shape_n = data.getFTensor0N();
595 int nb_shape_fn = data.getN(NOBASE).size2();
596
597 for (int gg = 0; gg != nb_integration_pts; ++gg) {
598 t_young_modulus = 0; // Initialize to zero before accumulation
599 auto t_vert_young_mod = getFTensor0FromVec(vert_young_mod);
600 for (int bb = 0; bb != nb_shape_fn; ++bb) {
601 t_young_modulus += t_vert_young_mod * t_shape_n;
602 ++t_vert_young_mod;
603 ++t_shape_n;
604 }
605 const auto material_params =
606 getMaterialParams(t_young_modulus, b.poissonRatio);
607 t_young_modulus = material_params.youngModulus;
608 t_mu = material_params.shearModulusG;
609 t_lambda = material_params.lambda;
610
611 CHKERR evalMatD(material_params.bulkModulusK,
612 material_params.shearModulusG);
613 CHKERR evalInvMatDPtr(material_params.bulkModulusK,
614 material_params.shearModulusG);
615 next();
616 }
617 } else {
618 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
619 "Unsupported heterogeneous Young's modulus interpolation "
620 "order %d",
622 }
623 } else {
624 // MAT_ELASTIC block with homogeneous material properties
625 for (int gg = 0; gg != nb_integration_pts; ++gg) {
626 t_young_modulus = b.youngModulus;
627 t_mu = b.shearModulusG;
628 t_lambda = b.bulkModulusK - 2 * b.shearModulusG / 3;
629
630 CHKERR evalMatD(b.bulkModulusK, b.shearModulusG);
631 CHKERR evalInvMatDPtr(b.bulkModulusK, b.shearModulusG);
632 next();
633 }
634 }
636 }
637 }
638
639 // From command line options if no block data is provided
640 const auto material_params = getMaterialParams(this->E, this->nu);
641
642 // Keep scalar Lamé parameters in sync for homogeneous/default material.
643 dataAtGaussPts->mu = material_params.shearModulusG;
644 dataAtGaussPts->lambda = material_params.lambda;
645
646 for (int gg = 0; gg != nb_integration_pts; ++gg) {
647 t_young_modulus = material_params.youngModulus;
648 t_mu = material_params.shearModulusG;
649 t_lambda = material_params.lambda;
650 CHKERR evalMatD(material_params.bulkModulusK,
651 material_params.shearModulusG);
652 CHKERR evalInvMatDPtr(material_params.bulkModulusK,
653 material_params.shearModulusG);
654 next();
655 }
656
658 }
659
661
662 OpTopoSpatialPhysical(const std::string &field_name,
663 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
664 SmartPetscObj<Vec> assemble_vec,
665 boost::shared_ptr<TopologicalData> topo_ptr,
666 const double alpha_u,
667 boost::shared_ptr<double> J_ptr);
668
669 MoFEMErrorCode integrate(EntData &data);
670
671 MoFEMErrorCode integrateHencky(EntData &data);
672
673 MoFEMErrorCode integratePolyconvexHencky(EntData &data);
674
675 MoFEMErrorCode assemble(int row_side, EntityType row_type,
676 EntData &data) override;
677
678 private:
679 const double alphaU;
680 PetscBool polyConvex = PETSC_FALSE;
681 boost::shared_ptr<TopologicalData> topoDataPtr;
682 SmartPetscObj<Vec> assembleVec;
683 boost::shared_ptr<double> JPtr;
684 double locJ;
685 };
686
687 virtual VolUserDataOperator *
689 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
690 SmartPetscObj<Vec> assemble_vec,
691 boost::shared_ptr<TopologicalData> topo_ptr,
692 const double alpha_u,
693 boost::shared_ptr<double> J_ptr) override {
694 return new OpTopoSpatialPhysical(field_name, data_ptr, assemble_vec,
695 topo_ptr, alpha_u, J_ptr);
696 }
697
698private:
700
711 std::vector<BlockData> blockData;
712
713 double E;
714 double nu;
715 PetscBool effectiveNehookeanStiffness = PETSC_FALSE;
717
718 // Set verbosity level, it verbile can changes that informatno is pronated
719 // only once at particular level
720 Sev getOptionsSeverityLevels = Sev::inform;
721};
722
723template <int STRIDEMATD>
725 const std::string &field_name,
726 boost::shared_ptr<DataAtIntegrationPts> data_ptr, const double alpha_u)
727 : OpAssembleVolume(field_name, data_ptr, OPROW), alphaU(alpha_u) {
728
729 CHK_MOAB_THROW(PetscOptionsGetBool(PETSC_NULLPTR, "", "-poly_convex",
730 &polyConvex, PETSC_NULLPTR),
731 "get polyconvex option failed");
732}
733
734template <int STRIDEMATD>
735MoFEMErrorCode
739 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
740 "Polyconvex Hencky with heterogeneous material properties is not "
741 "implemented");
742 }
743 if (polyConvex) {
744 CHKERR integratePolyconvexHencky(data);
745 } else {
746 CHKERR integrateHencky(data);
747 }
749}
750
751template <int STRIDEMATD>
752MoFEMErrorCode
755
758
759 int nb_dofs = data.getIndices().size();
760 int nb_integration_pts = data.getN().size1();
761 auto v = getVolume();
762 auto t_w = getFTensor0IntegrationWeight();
763 auto t_approx_P_adjoint_log_du =
764 dataAtPts->getFTensorAdjointPdU(nb_integration_pts);
765 auto t_log_stretch_h1 =
766 dataAtPts->getFTensorLogStretchTotal(nb_integration_pts);
767 auto t_dot_log_u = dataAtPts->getFTensorLogStretchDot(nb_integration_pts);
768
769 auto t_D = getFTensor4DdgFromMat<3, 3, STRIDEMATD>(dataAtPts->matD);
770
771 FTensor::Index<'i', 3> i;
772 FTensor::Index<'j', 3> j;
773 FTensor::Index<'k', 3> k;
774 FTensor::Index<'l', 3> l;
775 auto get_ftensor2 = [](auto &v) {
777 &v[0], &v[1], &v[2], &v[3], &v[4], &v[5]);
778 };
779
780 int nb_base_functions = data.getN().size2();
781 auto t_row_base_fun = data.getFTensor0N();
782
783 for (int gg = 0; gg != nb_integration_pts; ++gg) {
784 double a = v * t_w;
785 auto t_nf = get_ftensor2(nF);
786
788 t_T(i, j) =
789 t_D(i, j, k, l) * (t_log_stretch_h1(k, l) + alphaU * t_dot_log_u(k, l));
791 t_residual(L) =
792 a * (t_approx_P_adjoint_log_du(L) - t_L(i, j, L) * t_T(i, j));
793
794 int bb = 0;
795 for (; bb != nb_dofs / 6; ++bb) {
796 t_nf(L) -= t_row_base_fun * t_residual(L);
797 ++t_nf;
798 ++t_row_base_fun;
799 }
800 for (; bb != nb_base_functions; ++bb)
801 ++t_row_base_fun;
802
803 ++t_D;
804 ++t_w;
805 ++t_approx_P_adjoint_log_du;
806 ++t_dot_log_u;
807 ++t_log_stretch_h1;
808 }
809
811}
812
813template <int STRIDEMATD>
814MoFEMErrorCode
816 EntData &data) {
818
821
822 int nb_dofs = data.getIndices().size();
823 int nb_integration_pts = data.getN().size1();
824 auto v = getVolume();
825 auto t_w = getFTensor0IntegrationWeight();
826 auto t_approx_P_adjoint_log_du =
827 dataAtPts->getFTensorAdjointPdU(nb_integration_pts);
828 auto t_log_stretch_h1 =
829 dataAtPts->getFTensorLogStretchTotal(nb_integration_pts);
830 auto t_dot_log_u = dataAtPts->getFTensorLogStretchDot(nb_integration_pts);
831
832 auto t_D = getFTensor4DdgFromMat<3, 3, 0>(dataAtPts->matD);
833
834 FTensor::Index<'i', 3> i;
835 FTensor::Index<'j', 3> j;
836 FTensor::Index<'k', 3> k;
837 FTensor::Index<'l', 3> l;
838 auto get_ftensor2 = [](auto &v) {
840 &v[0], &v[1], &v[2], &v[3], &v[4], &v[5]);
841 };
842
843 constexpr double nohat_k = 1. / 4;
844 constexpr double hat_k = 1. / 8;
845 double mu = dataAtPts->mu;
846 double lambda = dataAtPts->lambda;
847
848 constexpr double third = boost::math::constants::third<double>();
850 auto t_diff_deviator = FTensor::DiffDeviator<double, 3>();
851
852 int nb_base_functions = data.getN().size2();
853 auto t_row_base_fun = data.getFTensor0N();
854 for (int gg = 0; gg != nb_integration_pts; ++gg) {
855 double a = v * t_w;
856 auto t_nf = get_ftensor2(nF);
857
858 double log_det = t_log_stretch_h1(i, i);
859 double log_det2 = log_det * log_det;
861 t_dev(i, j) = t_log_stretch_h1(i, j) - t_kd(i, j) * (third * log_det);
862 double dev_norm2 = t_dev(i, j) * t_dev(i, j);
863
865 auto A = 2 * mu * std::exp(nohat_k * dev_norm2);
866 auto B = lambda * std::exp(hat_k * log_det2) * log_det;
867 t_T(i, j) =
868
869 A * (t_dev(k, l) * t_diff_deviator(k, l, i, j))
870
871 +
872
873 B * t_kd(i, j)
874
875 +
876
877 alphaU * t_D(i, j, k, l) * t_dot_log_u(k, l);
878
880 t_residual(L) =
881 a * (t_approx_P_adjoint_log_du(L) - t_L(i, j, L) * t_T(i, j));
882
883 int bb = 0;
884 for (; bb != nb_dofs / size_symm; ++bb) {
885 t_nf(L) -= t_row_base_fun * t_residual(L);
886 ++t_nf;
887 ++t_row_base_fun;
888 }
889 for (; bb != nb_base_functions; ++bb)
890 ++t_row_base_fun;
891
892 ++t_w;
893 ++t_approx_P_adjoint_log_du;
894 ++t_dot_log_u;
895 ++t_log_stretch_h1;
896 }
898}
899
900template <int STRIDEMATD>
902 std::string row_field, std::string col_field,
903 boost::shared_ptr<DataAtIntegrationPts> data_ptr, const double alpha)
904 : OpAssembleVolume(row_field, col_field, data_ptr, OPROWCOL, false),
905 alphaU(alpha) {
906 sYmm = false;
907
908 CHK_MOAB_THROW(PetscOptionsGetBool(PETSC_NULLPTR, "", "-poly_convex",
909 &polyConvex, PETSC_NULLPTR),
910 "get polyconvex option failed");
911}
912
914 const std::string &field_name,
915 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
916 boost::shared_ptr<ExternalStrainVec> &external_strain_vec_ptr,
917 std::map<std::string, boost::shared_ptr<ScalingMethod>> smv)
918 : OpAssembleVolume(field_name, data_ptr, OPROW),
919 externalStrainVecPtr(external_strain_vec_ptr), scalingMethodsMap(smv) {}
920
921MoFEMErrorCode
924
926
927 double time = OpAssembleVolume::getFEMethod()->ts_t;
930 }
931 // get entity of tet
932 EntityHandle fe_ent = OpAssembleVolume::getFEEntityHandle();
933 // iterate over all block data
934
935 for (auto &ext_strain_block : (*externalStrainVecPtr)) {
936 // check if finite element entity is part of the EXTERNALSTRAIN block
937 if (ext_strain_block.ents.find(fe_ent) != ext_strain_block.ents.end()) {
938
939 double scale = 1;
940 if (scalingMethodsMap.find(ext_strain_block.blockName) !=
941 scalingMethodsMap.end()) {
942 scale *=
943 scalingMethodsMap.at(ext_strain_block.blockName)->getScale(time);
944 } else {
945 MOFEM_LOG("SELF", Sev::warning)
946 << "No scaling method found for " << ext_strain_block.blockName;
947 }
948
949 int nb_dofs = data.getIndices().size();
950 int nb_integration_pts = data.getN().size1();
951 auto v = getVolume();
952 auto t_w = getFTensor0IntegrationWeight();
954
955 double external_strain_val;
956 VectorDouble v_external_strain;
957 auto block_name = "(.*)ANALYTICAL_EXTERNALSTRAIN(.*)";
958 std::regex reg_name(block_name);
959 if (std::regex_match(ext_strain_block.blockName, reg_name)) {
960 VectorDouble analytical_external_strain;
961 std::string block_name_tmp;
962 std::tie(block_name_tmp, v_external_strain) =
963 getAnalyticalExternalStrain(this, analytical_external_strain,
964 ext_strain_block.blockName);
965 } else {
966 // get ExternalStrain data from block
967 external_strain_val = scale * ext_strain_block.val;
968 // fill with same scalar value for all integration points
969 v_external_strain.resize(nb_integration_pts);
970 std::fill(v_external_strain.begin(), v_external_strain.end(),
971 external_strain_val);
972 }
973 auto t_external_strain = getFTensor0FromVec(v_external_strain);
974 double bulk_modulus_K = ext_strain_block.bulkModulusK;
976
977 FTensor::Index<'i', 3> i;
978 FTensor::Index<'j', 3> j;
979 FTensor::Index<'k', 3> k;
980 FTensor::Index<'l', 3> l;
981 auto get_ftensor2 = [](auto &v) {
983 &v[0], &v[1], &v[2], &v[3], &v[4], &v[5]);
984 };
985
986 int nb_base_functions = data.getN().size2();
987 auto t_row_base_fun = data.getFTensor0N();
988 for (int gg = 0; gg != nb_integration_pts; ++gg) {
989 auto tr = 3.0 * t_external_strain;
990 double a = v * t_w;
991 auto t_nf = get_ftensor2(nF);
992
994
995 t_T(i, j) = -bulk_modulus_K * tr * t_kd(i, j);
996
998 t_residual(L) = a * (t_L(i, j, L) * t_T(i, j));
999
1000 int bb = 0;
1001 for (; bb != nb_dofs / 6; ++bb) {
1002 t_nf(L) += t_row_base_fun * t_residual(L);
1003 ++t_nf;
1004 ++t_row_base_fun;
1005 }
1006 for (; bb != nb_base_functions; ++bb)
1007 ++t_row_base_fun;
1008 ++t_external_strain;
1009 ++t_w;
1010 }
1011 }
1012 }
1013
1015}
1016
1017template <int STRIDEMATD>
1018MoFEMErrorCode
1020 EntData &col_data) {
1023 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
1024 "Polyconvex Hencky with heterogeneous material properties is not "
1025 "implemented");
1026 }
1027 if (polyConvex) {
1028 CHKERR integratePolyconvexHencky(row_data, col_data);
1029 } else {
1030 CHKERR integrateHencky(row_data, col_data);
1031 }
1033}
1034
1035template <int STRIDEMATD>
1037 EntData &row_data, EntData &col_data) {
1039
1040 FTensor::Index<'L', size_symm> L;
1043 auto t_diff = FTensor::DiffTensor<double>();
1044
1045 int nb_integration_pts = row_data.getN().size1();
1046 int row_nb_dofs = row_data.getIndices().size();
1047 int col_nb_dofs = col_data.getIndices().size();
1048
1049 auto get_ftensor2 = [](MatrixDouble &m, const int r, const int c) {
1051 size_symm>(
1052
1053 &m(r + 0, c + 0), &m(r + 0, c + 1), &m(r + 0, c + 2), &m(r + 0, c + 3),
1054 &m(r + 0, c + 4), &m(r + 0, c + 5),
1055
1056 &m(r + 1, c + 0), &m(r + 1, c + 1), &m(r + 1, c + 2), &m(r + 1, c + 3),
1057 &m(r + 1, c + 4), &m(r + 1, c + 5),
1058
1059 &m(r + 2, c + 0), &m(r + 2, c + 1), &m(r + 2, c + 2), &m(r + 2, c + 3),
1060 &m(r + 2, c + 4), &m(r + 2, c + 5),
1061
1062 &m(r + 3, c + 0), &m(r + 3, c + 1), &m(r + 3, c + 2), &m(r + 3, c + 3),
1063 &m(r + 3, c + 4), &m(r + 3, c + 5),
1064
1065 &m(r + 4, c + 0), &m(r + 4, c + 1), &m(r + 4, c + 2), &m(r + 4, c + 3),
1066 &m(r + 4, c + 4), &m(r + 4, c + 5),
1067
1068 &m(r + 5, c + 0), &m(r + 5, c + 1), &m(r + 5, c + 2), &m(r + 5, c + 3),
1069 &m(r + 5, c + 4), &m(r + 5, c + 5)
1070
1071 );
1072 };
1073
1074 FTENSOR_INDEXES(SPACE_DIM, i, j, k, l, m, n);
1075
1076 auto v = getVolume();
1077 auto t_w = getFTensor0IntegrationWeight();
1078
1079 auto t_approx_P_adjoint__dstretch =
1080 dataAtPts->getFTensorAdjointPdstretch(nb_integration_pts);
1081 auto t_eigen_vals = dataAtPts->getFTensorEigenVals(nb_integration_pts);
1082 auto t_eigen_vecs = dataAtPts->getFTensorEigenVecs(nb_integration_pts);
1083
1084 int row_nb_base_functions = row_data.getN().size2();
1085 auto t_row_base_fun = row_data.getFTensor0N();
1086
1087 auto get_dP = [&]() {
1088 auto get_stress =
1089 MatrixSizeHelper<GetFTensor2FromMatType<size_symm, size_symm, -1, DL>,
1090 DL>::size(dP, nb_integration_pts);
1091 auto ts_a = getTSa();
1092
1093 auto t_D = getFTensor4DdgFromMat<3, 3, STRIDEMATD>(dataAtPts->matD);
1095 if constexpr (!STRIDEMATD) {
1096 t_dP_tmp(L, J) = -(1 + alphaU * ts_a) *
1097 (t_L(i, j, L) * ((t_D(i, j, m, n) * t_diff(m, n, k, l)) *
1098 t_L(k, l, J)));
1099 }
1100 // allocate FTensors
1102 L_left(i, j, L) = t_L(i, j, L);
1104 L_right(k, l, J) = t_L(k, l, J);
1106
1109 auto t_approx_P_adjoint__dstretch =
1110 dataAtPts->getFTensorAdjointPdstretch(nb_integration_pts);
1111 auto t_eigen_vals = dataAtPts->getFTensorEigenVals(nb_integration_pts);
1112 auto t_eigen_vecs = dataAtPts->getFTensorEigenVecs(nb_integration_pts);
1113 auto &nbUniq = dataAtPts->nbUniq;
1114
1115 auto t_dP = get_stress();
1116 for (auto gg = 0; gg != nb_integration_pts; ++gg) {
1117 if constexpr (STRIDEMATD) {
1118 temp(i, j, k, l) = t_D(i, j, m, n) * t_diff(m, n, k, l);
1119
1120 t_dP_tmp(L, J) =
1121 -(1 + alphaU * ts_a) *
1122 (L_left(i, j, L) * (temp(i, j, k, l) * L_right(k, l, J)));
1123
1124 ++t_D;
1125 }
1126
1127 // Work of symmetric tensor on undefined tensor is equal to the work
1128 // of the symmetric part of it
1130 t_sym(i, j) = (t_approx_P_adjoint__dstretch(i, j) ||
1131 t_approx_P_adjoint__dstretch(j, i));
1132 t_sym(i, j) /= 2.0;
1133 auto t_diff2_uP2 = EigenMatrix::getDiffDiffMat(
1134 t_eigen_vals, t_eigen_vecs, EshelbianCore::f, EshelbianCore::d_f,
1135 EshelbianCore::dd_f, t_sym, nbUniq[gg]);
1136 t_dP(L, J) = t_L(i, j, L) *
1137 ((t_diff2_uP2(i, j, k, l) + t_diff2_uP2(k, l, i, j)) *
1138 t_L(k, l, J)) /
1139 2. +
1140 t_dP_tmp(L, J);
1141
1142 ++t_dP;
1143 ++t_approx_P_adjoint__dstretch;
1144 ++t_eigen_vals;
1145 ++t_eigen_vecs;
1146 }
1147 } else {
1148 auto t_dP = get_stress();
1149 for (auto gg = 0; gg != nb_integration_pts; ++gg) {
1150 if constexpr (STRIDEMATD) {
1151 temp(i, j, k, l) = t_D(i, j, m, n) * t_diff(m, n, k, l);
1152
1153 t_dP_tmp(L, J) =
1154 -(1 + alphaU * ts_a) *
1155 (L_left(i, j, L) * (temp(i, j, k, l) * L_right(k, l, J)));
1156
1157 ++t_D;
1158 }
1159 t_dP(L, J) = t_dP_tmp(L, J);
1160
1161 ++t_dP;
1162 }
1163 }
1164
1165 return get_stress();
1166 };
1167
1168 auto t_dP = get_dP();
1169
1170 for (int gg = 0; gg != nb_integration_pts; ++gg) {
1171 double a = v * t_w;
1172
1173 int rr = 0;
1174 for (; rr != row_nb_dofs / 6; ++rr) {
1175 auto t_col_base_fun = col_data.getFTensor0N(gg, 0);
1176 auto t_m = get_ftensor2(K, 6 * rr, 0);
1177 for (int cc = 0; cc != col_nb_dofs / 6; ++cc) {
1178 const double b = a * t_row_base_fun * t_col_base_fun;
1179 t_m(L, J) -= b * t_dP(L, J);
1180 ++t_m;
1181 ++t_col_base_fun;
1182 }
1183 ++t_row_base_fun;
1184 }
1185
1186 for (; rr != row_nb_base_functions; ++rr) {
1187 ++t_row_base_fun;
1188 }
1189
1190 ++t_w;
1191 ++t_dP;
1192 }
1194}
1195
1196template <int STRIDEMATD>
1197MoFEMErrorCode
1199 EntData &row_data, EntData &col_data) {
1201
1202 FTensor::Index<'L', size_symm> L;
1205 auto t_diff = FTensor::DiffTensor<double>();
1206
1207 int nb_integration_pts = row_data.getN().size1();
1208 int row_nb_dofs = row_data.getIndices().size();
1209 int col_nb_dofs = col_data.getIndices().size();
1210
1211 auto get_ftensor2 = [](MatrixDouble &m, const int r, const int c) {
1213 size_symm>(
1214
1215 &m(r + 0, c + 0), &m(r + 0, c + 1), &m(r + 0, c + 2), &m(r + 0, c + 3),
1216 &m(r + 0, c + 4), &m(r + 0, c + 5),
1217
1218 &m(r + 1, c + 0), &m(r + 1, c + 1), &m(r + 1, c + 2), &m(r + 1, c + 3),
1219 &m(r + 1, c + 4), &m(r + 1, c + 5),
1220
1221 &m(r + 2, c + 0), &m(r + 2, c + 1), &m(r + 2, c + 2), &m(r + 2, c + 3),
1222 &m(r + 2, c + 4), &m(r + 2, c + 5),
1223
1224 &m(r + 3, c + 0), &m(r + 3, c + 1), &m(r + 3, c + 2), &m(r + 3, c + 3),
1225 &m(r + 3, c + 4), &m(r + 3, c + 5),
1226
1227 &m(r + 4, c + 0), &m(r + 4, c + 1), &m(r + 4, c + 2), &m(r + 4, c + 3),
1228 &m(r + 4, c + 4), &m(r + 4, c + 5),
1229
1230 &m(r + 5, c + 0), &m(r + 5, c + 1), &m(r + 5, c + 2), &m(r + 5, c + 3),
1231 &m(r + 5, c + 4), &m(r + 5, c + 5)
1232
1233 );
1234 };
1235 FTensor::Index<'i', 3> i;
1236 FTensor::Index<'j', 3> j;
1237 FTensor::Index<'k', 3> k;
1238 FTensor::Index<'l', 3> l;
1239 FTensor::Index<'m', 3> m;
1240 FTensor::Index<'n', 3> n;
1241
1242 auto v = getVolume();
1243 auto t_w = getFTensor0IntegrationWeight();
1244
1245 int row_nb_base_functions = row_data.getN().size2();
1246 auto t_row_base_fun = row_data.getFTensor0N();
1247
1248 auto get_dP = [&]() {
1249 auto get_stress =
1250 MatrixSizeHelper<GetFTensor2FromMatType<size_symm, size_symm, -1, DL>,
1251 DL>::size(dP, nb_integration_pts);
1252 auto ts_a = getTSa();
1253
1254 auto t_D = getFTensor4DdgFromPtr<3, 3, 0>(&*dataAtPts->matD.data().begin());
1255
1256 constexpr double nohat_k = 1. / 4;
1257 constexpr double hat_k = 1. / 8;
1258 double mu = dataAtPts->mu;
1259 double lambda = dataAtPts->lambda;
1260
1261 constexpr double third = boost::math::constants::third<double>();
1263 auto t_diff_deviator = FTensor::DiffDeviator<double, 3>();
1264
1265 auto t_approx_P_adjoint__dstretch =
1266 dataAtPts->getFTensorAdjointPdstretch(getGaussPts().size2());
1267 auto t_log_stretch_h1 =
1268 dataAtPts->getFTensorLogStretchTotal(getGaussPts().size2());
1269 auto t_eigen_vals = dataAtPts->getFTensorEigenVals(getGaussPts().size2());
1270 auto t_eigen_vecs = dataAtPts->getFTensorEigenVecs(getGaussPts().size2());
1271 auto &nbUniq = dataAtPts->nbUniq;
1272
1273 auto t_dP = get_stress();
1274 for (auto gg = 0; gg != nb_integration_pts; ++gg) {
1275
1276 double log_det = t_log_stretch_h1(i, i);
1277 double log_det2 = log_det * log_det;
1279 t_dev(i, j) = t_log_stretch_h1(i, j) - t_kd(i, j) * (third * log_det);
1280 double dev_norm2 = t_dev(i, j) * t_dev(i, j);
1281
1282 auto A = 2 * mu * std::exp(nohat_k * dev_norm2);
1283 auto B = lambda * std::exp(hat_k * log_det2) * log_det;
1284
1285 FTensor::Tensor2_symmetric<double, 3> t_A_diff, t_B_diff;
1286 t_A_diff(i, j) =
1287 (A * 2 * nohat_k) * (t_dev(k, l) * t_diff_deviator(k, l, i, j));
1288 t_B_diff(i, j) = (B * 2 * hat_k) * log_det * t_kd(i, j) +
1289 lambda * std::exp(hat_k * log_det2) * t_kd(i, j);
1291 t_dT(i, j, k, l) =
1292 t_A_diff(i, j) * (t_dev(m, n) * t_diff_deviator(m, n, k, l))
1293
1294 +
1295
1296 A * t_diff_deviator(m, n, i, j) * t_diff_deviator(m, n, k, l)
1297
1298 +
1299
1300 t_B_diff(i, j) * t_kd(k, l);
1301
1302 t_dP(L, J) = -t_L(i, j, L) *
1303 ((
1304
1305 t_dT(i, j, k, l)
1306
1307 +
1308
1309 (alphaU * ts_a) * (t_D(i, j, m, n) * t_diff(m, n, k, l)
1310
1311 )) *
1312 t_L(k, l, J));
1313
1314 // Work of symmetric tensor on undefined tensor is equal to the work
1315 // of the symmetric part of it
1319 t_sym(i, j) = (t_approx_P_adjoint__dstretch(i, j) ||
1320 t_approx_P_adjoint__dstretch(j, i));
1321 t_sym(i, j) /= 2.0;
1322 auto t_diff2_uP2 = EigenMatrix::getDiffDiffMat(
1323 t_eigen_vals, t_eigen_vecs, EshelbianCore::f, EshelbianCore::d_f,
1324 EshelbianCore::dd_f, t_sym, nbUniq[gg]);
1325 t_dP(L, J) += t_L(i, j, L) *
1326 ((t_diff2_uP2(i, j, k, l) + t_diff2_uP2(k, l, i, j)) *
1327 t_L(k, l, J)) /
1328 2.;
1329 }
1330
1331 ++t_dP;
1332 ++t_approx_P_adjoint__dstretch;
1333 ++t_log_stretch_h1;
1334 ++t_eigen_vals;
1335 ++t_eigen_vecs;
1336 }
1337
1338 return get_stress();
1339 };
1340
1341 auto t_dP = get_dP();
1342 for (int gg = 0; gg != nb_integration_pts; ++gg) {
1343 double a = v * t_w;
1344
1345 int rr = 0;
1346 for (; rr != row_nb_dofs / 6; ++rr) {
1347 auto t_col_base_fun = col_data.getFTensor0N(gg, 0);
1348 auto t_m = get_ftensor2(K, 6 * rr, 0);
1349 for (int cc = 0; cc != col_nb_dofs / 6; ++cc) {
1350 const double b = a * t_row_base_fun * t_col_base_fun;
1351 t_m(L, J) -= b * t_dP(L, J);
1352 ++t_m;
1353 ++t_col_base_fun;
1354 }
1355 ++t_row_base_fun;
1356 }
1357
1358 for (; rr != row_nb_base_functions; ++rr) {
1359 ++t_row_base_fun;
1360 }
1361
1362 ++t_w;
1363 ++t_dP;
1364 }
1366}
1367
1368template <int STRIDEMATD>
1370 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
1371 boost::shared_ptr<double> total_energy_ptr)
1372 : VolUserDataOperator(NOSPACE, OPSPACE), dataAtPts(data_ptr),
1373 totalEnergyPtr(total_energy_ptr) {
1374
1375 if (!dataAtPts) {
1377 "dataAtPts is not allocated. Please set it before "
1378 "using this operator.");
1379 }
1380}
1381
1382template <int STRIDEMATD>
1384 EntityType type,
1385 EntData &data) {
1387
1392
1393 int nb_integration_pts = getGaussPts().size2();
1394 auto t_log_u = dataAtPts->getFTensorLogStretchTotal(nb_integration_pts);
1395
1396#ifndef NDEBUG
1397 auto &mat_d = dataAtPts->matD;
1398 if (mat_d.size2() != size_symm * size_symm) {
1399 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1400 "wrong matD size, number of columns should be %d but is %zu",
1401 size_symm * size_symm, mat_d.size2());
1402 }
1403 if constexpr (STRIDEMATD != 0) {
1404 if (mat_d.size1() != nb_integration_pts) {
1405 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1406 "wrong matD size, number of rows should be %d but is %zu",
1407 nb_integration_pts, mat_d.size1());
1408 }
1409 }
1410#endif
1411
1412 auto t_D = getFTensor4DdgFromMat<3, 3, STRIDEMATD>(dataAtPts->matD);
1413
1414 dataAtPts->energyAtPts.resize(nb_integration_pts, false);
1415 auto t_energy = getFTensor0FromVec(dataAtPts->energyAtPts);
1416
1417 for (auto gg = 0; gg != nb_integration_pts; ++gg) {
1418
1419 t_energy = 0.5 * (t_log_u(i, j) * (t_D(i, j, k, l) * t_log_u(k, l)));
1420
1421 ++t_D;
1422 ++t_log_u;
1423 ++t_energy;
1424 }
1425
1426 if (totalEnergyPtr) {
1427 auto t_w = getFTensor0IntegrationWeight();
1428 auto t_energy = getFTensor0FromVec(dataAtPts->energyAtPts);
1429 double loc_energy = 0;
1430 for (auto gg = 0; gg != nb_integration_pts; ++gg) {
1431 loc_energy += t_energy * t_w;
1432 ++t_w;
1433 ++t_energy;
1434 }
1435 *totalEnergyPtr += getMeasure() * loc_energy;
1436 }
1437
1439}
1440
1441template <int STRIDEMATD>
1444 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
1445 boost::shared_ptr<MatrixDouble> strain_ptr,
1446 boost::shared_ptr<MatrixDouble> stress_ptr,
1447 boost::shared_ptr<HMHHencky> hencky_ptr)
1448 : VolUserDataOperator(H1, OPLAST), dataAtPts(data_ptr),
1449 strainPtr(strain_ptr), stressPtr(stress_ptr), henckyPtr(hencky_ptr) {
1450 std::fill(&doEntities[MBVERTEX], &doEntities[MBMAXTYPE], false);
1451 doEntities[MBVERTEX] = true;
1452}
1453
1454template <int STRIDEMATD>
1456 int side, EntityType type, EntData &data) {
1458
1465
1466 auto nb_integration_pts = stressPtr->size1();
1467#ifndef NDEBUG
1468 if (nb_integration_pts != getGaussPts().size2()) {
1469 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1470 "inconsistent number of integration points");
1471 }
1472#endif // NDEBUG
1473
1474 CHKERR henckyPtr->computeMaterialParamsAtPts<STRIDEMATD>(this, data,
1475 dataAtPts);
1476
1477 auto get_strain =
1478 MatrixSizeHelper<GetFTensor2SymmetricFromMatType<3, -1, DL>, DL>::size(
1479 *strainPtr, nb_integration_pts);
1480 auto t_strain = get_strain();
1481 auto t_stress = getFTensor2FromMat<SPACE_DIM, SPACE_DIM, -1, DL>(*stressPtr);
1482 auto t_inv_D = getFTensor4DdgFromMat<SPACE_DIM, SPACE_DIM, STRIDEMATD>(
1483 dataAtPts->matInvD);
1484#ifndef NDEBUG
1485 auto t_D =
1486 getFTensor4DdgFromMat<SPACE_DIM, SPACE_DIM, STRIDEMATD>(dataAtPts->matD);
1487#endif
1488
1490
1491 // note: add rotation, so we can extract rigid body motion, work then with
1492 // symmetric part.
1493 for (auto gg = 0; gg != nb_integration_pts; ++gg) {
1494 t_strain(i, j) = t_inv_D(i, j, k, l) * t_stress(k, l);
1495
1496#ifndef NDEBUG
1497 FTensor::Tensor2_symmetric<double, 3> t_stress_symm_debug;
1498 t_stress_symm_debug(i, j) = (t_stress(i, j) || t_stress(j, i)) / 2;
1499 FTensor::Tensor2_symmetric<double, 3> t_stress_symm_debug_diff;
1500 t_stress_symm_debug_diff(i, j) =
1501 t_D(i, j, k, l) * t_strain(k, l) - t_stress_symm_debug(i, j);
1502 double nrm =
1503 t_stress_symm_debug_diff(i, j) * t_stress_symm_debug_diff(i, j);
1504 double nrm0 = t_stress_symm_debug(i, j) * t_stress_symm_debug(i, j) +
1505 std::numeric_limits<double>::epsilon();
1506 constexpr double eps = 1e-10;
1507 if (std::fabs(std::sqrt(nrm / nrm0)) > eps) {
1508 MOFEM_LOG("SELF", Sev::error)
1509 << "Stress symmetry check failed: " << std::endl
1510 << t_stress_symm_debug_diff << std::endl
1511 << t_stress;
1513 "Norm is too big: " + std::to_string(nrm / nrm0));
1514 }
1515 ++t_D;
1516#endif
1517
1518 ++t_strain;
1519 ++t_stress;
1520 ++t_inv_D;
1521 }
1522
1524}
1525
1526template <typename OP_PTR>
1527std::tuple<std::string, VectorDouble>
1529 const std::string block_name) {
1530
1531 auto nb_gauss_pts = op_ptr->getGaussPts().size2();
1532
1533 auto ts_time = op_ptr->getTStime();
1534 auto ts_time_step = op_ptr->getTStimeStep();
1537 ts_time_step = EshelbianCore::physicalDt;
1538 }
1539
1540 MatrixDouble m_ref_coords = op_ptr->getCoordsAtGaussPts();
1541
1542 auto v_analytical_expr = analytical_externalstrain_function(
1543 ts_time_step, ts_time, nb_gauss_pts, m_ref_coords, block_name);
1544
1545#ifndef NDEBUG
1546 if (v_analytical_expr.size() != nb_gauss_pts)
1548 "Wrong number of integration pts");
1549#endif // NDEBUG
1550
1551 return std::make_tuple(block_name, v_analytical_expr);
1552};
1553
1554template <typename OP_PTR>
1555VectorDouble getAnalyticalElastic(OP_PTR op_ptr, const std::string block_name) {
1556
1557 auto nb_gauss_pts = op_ptr->getGaussPts().size2();
1558
1559 auto ts_time = op_ptr->getTStime();
1560 auto ts_time_step = op_ptr->getTStimeStep();
1561
1564 ts_time_step = EshelbianCore::physicalStepNumber;
1565 }
1566
1567 MatrixDouble m_ref_coords = op_ptr->getCoordsAtGaussPts();
1568
1569 auto v_analytical_expr = analytical_elastic_function(
1570 ts_time_step, ts_time, nb_gauss_pts, m_ref_coords, block_name);
1571
1572#ifndef NDEBUG
1573 if (v_analytical_expr.size() != nb_gauss_pts)
1575 "Wrong number of integration pts");
1576#endif // NDEBUG
1577
1578 return v_analytical_expr;
1579}
1580
1581// Topo
1582
1584 const std::string &field_name,
1585 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
1586 SmartPetscObj<Vec> assemble_vec,
1587 boost::shared_ptr<TopologicalData> topo_ptr, const double alpha_u,
1588 boost::shared_ptr<double> J_ptr)
1589 : OpAssembleVolume(field_name, data_ptr, OPROW), alphaU(alpha_u),
1590 JPtr(J_ptr), topoDataPtr(topo_ptr), assembleVec(assemble_vec) {
1591
1592 CHK_MOAB_THROW(PetscOptionsGetBool(PETSC_NULLPTR, "", "-poly_convex",
1593 &polyConvex, PETSC_NULLPTR),
1594 "get polyconvex option failed");
1595}
1596
1599 if (polyConvex) {
1600 CHKERR integratePolyconvexHencky(data);
1601 } else {
1602 CHKERR integrateHencky(data);
1603 }
1605}
1606
1607MoFEMErrorCode
1610
1611 FTensor::Index<'L', size_symm> L;
1613
1614 int nb_dofs = data.getIndices().size();
1615 int nb_integration_pts = data.getN().size1();
1616 auto v = getVolume();
1617
1618 FTENSOR_INDEXES(SPACE_DIM, i, j, k, l, I, J);
1619
1620 auto get_ftensor1 = [](auto &v) {
1622 &v[0], &v[1], &v[2]);
1623 };
1624
1625 locJ = 0;
1626 int nb_base_functions = data.getN().size2();
1627
1628 auto integrate = [&](auto t_D) {
1630
1631 auto t_w = getFTensor0IntegrationWeight();
1632 auto t_det = topoDataPtr->getFTensorDetJacobian(nb_integration_pts);
1633 auto t_inv_jac = topoDataPtr->getFTensorInvJacobian(nb_integration_pts);
1634
1635 auto t_var_log_u = dataAtPts->getFTensorVarLogStreach(nb_integration_pts);
1636 auto t_approx_P = dataAtPts->getFTensorApproxP(nb_integration_pts);
1637 auto t_approx_P_adjoint_log_du =
1638 dataAtPts->getFTensorAdjointPdU(nb_integration_pts);
1639 auto t_h_dlog_u =
1640 dataAtPts->getFTensorSmallHdLogStretch(nb_integration_pts);
1641 auto t_log_stretch_h1 =
1642 dataAtPts->getFTensorLogStretchTotal(nb_integration_pts);
1643
1644 // Swithc off rate effects for now, as we don't have the dot_log_u at the
1645 // pts; we would need to compute it from the solution, which is not
1646 // straightforward
1647 // auto t_dot_log_u =
1648 // dataAtPts->getFTensorLogStretchDot(nb_integration_pts);
1649
1650 auto t_diff_base = data.getFTensor1DiffN<SPACE_DIM>();
1651 for (int gg = 0; gg != nb_integration_pts; ++gg) {
1652 const double a = v * t_w;
1653
1655 t_T(i, j) = t_D(i, j, k, l) *
1656 (t_log_stretch_h1(k, l) /*+ alphaU * t_dot_log_u(k, l)*/);
1657
1658 FTensor::Tensor1<double, size_symm> t_stress_residual;
1659 t_stress_residual(L) = t_L(i, j, L) * t_T(i, j);
1660
1662 t_residual(L) = t_approx_P_adjoint_log_du(L) - t_stress_residual(L);
1663
1664 locJ -= (a * t_det) * t_residual(L) * t_var_log_u(L);
1665
1667 t_cof(I, J) = t_det * t_inv_jac(J, I);
1668
1669 const double var_stress_residual = t_var_log_u(L) * t_stress_residual(L);
1670
1671 // detJ cancels the 1 / detJ from the Piola transform; the remaining
1672 // derivative is from J(k, n) * P(i, n).
1674 t_approx_P_adjoint_log_du_dX;
1675 t_approx_P_adjoint_log_du_dX(L, I, J) =
1676 t_h_dlog_u(i, I, L) * t_approx_P(i, J);
1677
1679 t_residual_dX(I, J) =
1680 t_var_log_u(L) * t_approx_P_adjoint_log_du_dX(L, I, J) -
1681 var_stress_residual * t_cof(I, J);
1682
1683 auto t_nf = get_ftensor1(nF);
1684 int bb = 0;
1685 for (; bb != nb_dofs / SPACE_DIM; ++bb) {
1686 t_nf(i) -= a * t_residual_dX(i, j) * t_diff_base(j);
1687 ++t_nf;
1688 ++t_diff_base;
1689 }
1690 for (; bb != nb_base_functions; ++bb)
1691 ++t_diff_base;
1692
1693 ++t_w;
1694 ++t_det;
1695 ++t_inv_jac;
1696 ++t_var_log_u;
1697 ++t_approx_P;
1698 ++t_approx_P_adjoint_log_du;
1699 ++t_h_dlog_u;
1700 ++t_log_stretch_h1;
1701 // ++t_dot_log_u;
1702 ++t_D;
1703 }
1705 };
1706
1708 CHKERR integrate(
1709 getFTensor4DdgFromMat<SPACE_DIM, SPACE_DIM, 0>(dataAtPts->matD));
1710 } else {
1711 CHKERR integrate(
1712 getFTensor4DdgFromMat<SPACE_DIM, SPACE_DIM>(dataAtPts->matD));
1713 }
1714
1716}
1717
1718MoFEMErrorCode
1721 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
1722 "Polyconvex Hencky is not implemented yet");
1724}
1725
1727 EntityType row_type,
1728 EntData &data) {
1730 if (assembleVec) {
1731 double *vec_ptr = nF.data().data();
1732 const int nb_dofs = data.getIndices().size();
1733 int *ind_ptr = data.getIndices().data().data();
1734 CHKERR VecSetValues(assembleVec, nb_dofs, ind_ptr, vec_ptr, ADD_VALUES);
1735 }
1736 if (row_type == MBVERTEX) {
1737 if (JPtr) {
1738 *JPtr += locJ;
1739 }
1740 }
1742}
1743
1744} // namespace EshelbianPlasticity
constexpr double third
std::string type
#define MOFEM_TAG_AND_LOG(channel, severity, tag)
Tag and log in channel.
#define FTENSOR_INDEXES(DIM,...)
#define FTENSOR_INDEX(DIM, I)
constexpr double a
static PetscErrorCode ierr
static const double eps
constexpr int SPACE_DIM
Fourth-order differential deviator tensor.
Fourth-order differential tensor symmetric in both index pairs.
Kronecker Delta class symmetric.
Mapping from symmetric tensor indices to packed storage index.
@ NOBASE
Definition definitions.h:59
#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()
@ H1
continuous field
Definition definitions.h:85
@ 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
#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
constexpr IntegrationType G
Definition level_set.cpp:33
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)
static auto nu_eff(double C10, double K, double tau)
Definition HMHHencky.cpp:21
static auto G_eff(double C10, double tau)
Definition HMHHencky.cpp:12
std::tuple< std::string, VectorDouble > getAnalyticalExternalStrain(OP_PTR op_ptr, VectorDouble &analytical_expr, const std::string block_name)
static auto E_eff(double C10, double K, double tau)
Definition HMHHencky.cpp:16
static auto calc_effective_elastic_params(double E, double nu, double diagonal_strain)
Definition HMHHencky.cpp:46
VectorDouble analytical_elastic_function(double delta_t, double t, int nb_gauss_pts, MatrixDouble &m_ref_coords, const std::string block_name)
EntitiesFieldData::EntData EntData
ForcesAndSourcesCore::UserDataOperator UserDataOperator
static auto calc_c10(double E, double nu)
Definition HMHHencky.cpp:26
VectorDouble getAnalyticalElastic(OP_PTR op_ptr, const std::string block_name)
static auto calc_bulk_modulus(double lambda, double shear_modulus_G)
Definition HMHHencky.cpp:34
static constexpr auto size_symm
static auto calc_K(double E, double nu)
Definition HMHHencky.cpp:28
constexpr IntegrationType I
constexpr AssemblyType A
constexpr auto field_name
FTensor::Index< 'm', 3 > m
void temp(int x, int y=10)
Definition simple.cpp:4
static enum StretchSelector stretchSelector
static enum RotSelector gradApproximator
static double physicalDt
static std::string heterogeneousYoungModTagName
static int physicalStepNumber
static PetscBool physicalTimeFlg
static double currentPhysicalTime
static boost::function< double(const double)> f
static bool hasNonHomogeneousMaterialBlock
static boost::function< double(const double)> dd_f
static boost::function< double(const double)> d_f
static int meshTransferInterpOrder
Calculate energy density for Hencky material model.
MoFEMErrorCode doWork(int side, EntityType type, EntData &data)
boost::shared_ptr< DataAtIntegrationPts > dataAtPts
OpCalculateEnergy(boost::shared_ptr< DataAtIntegrationPts > data_ptr, boost::shared_ptr< double > total_energy_ptr)
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)
boost::shared_ptr< DataAtIntegrationPts > dataAtPts
data at integration pts
MoFEMErrorCode doWork(int side, EntityType type, EntData &data)
MoFEMErrorCode evaluateLhs(EntData &data)
Definition HMHHencky.cpp:85
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
Definition HMHHencky.cpp:76
boost::shared_ptr< DataAtIntegrationPts > dataAtGaussPts
Definition HMHHencky.cpp:88
OpHenckyJacobian(boost::shared_ptr< DataAtIntegrationPts > data_ptr, boost::shared_ptr< HMHHencky > hencky_ptr)
Definition HMHHencky.cpp:68
MoFEMErrorCode evaluateRhs(EntData &data)
Definition HMHHencky.cpp:84
boost::shared_ptr< HMHHencky > henckyPtr
Definition HMHHencky.cpp:89
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)
MoFEMErrorCode integrate(EntData &row_data, EntData &col_data)
MoFEMErrorCode integratePolyconvexHencky(EntData &row_data, EntData &col_data)
MoFEMErrorCode integrateHencky(EntData &row_data, EntData &col_data)
OpSpatialPhysical_du_du(std::string row_field, std::string col_field, boost::shared_ptr< DataAtIntegrationPts > data_ptr, const double alpha)
MoFEMErrorCode integrateHencky(EntData &data)
MoFEMErrorCode integratePolyconvexHencky(EntData &data)
OpSpatialPhysical(const std::string &field_name, boost::shared_ptr< DataAtIntegrationPts > data_ptr, const double alpha_u)
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< double > J_ptr)
MoFEMErrorCode assemble(int row_side, EntityType row_type, EntData &data) override
boost::shared_ptr< TopologicalData > topoDataPtr
MoFEMErrorCode integratePolyconvexHencky(EntData &data)
MoFEMErrorCode computeMaterialParamsAtPts(OP_PTR op_ptr, EntitiesFieldData::EntData &data, boost::shared_ptr< DataAtIntegrationPts > dataAtGaussPts)
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, boost::shared_ptr< double > J_ptr) override
virtual VolUserDataOperator * returnOpSpatialPhysical(const std::string &field_name, boost::shared_ptr< DataAtIntegrationPts > data_ptr, const double alpha_u)
MoFEMErrorCode extractBlockData(Sev sev)
std::vector< BlockData > blockData
static constexpr int StrideMatD
Definition HMHHencky.cpp:64
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:61
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 getOptions(boost::shared_ptr< DataAtIntegrationPts > data_ptr)
VolUserDataOperator * returnOpCalculateStretchFromStress(boost::shared_ptr< DataAtIntegrationPts > data_ptr, boost::shared_ptr< PhysicalEquations > physics_ptr, boost::shared_ptr< MatrixDouble > strain_ptr) override
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)
virtual UserDataOperator * returnOpJacobian(const bool eval_rhs, const bool eval_lhs, boost::shared_ptr< DataAtIntegrationPts > data_ptr, boost::shared_ptr< PhysicalEquations > physics_ptr)
Definition HMHHencky.cpp:93
virtual moab::Interface & get_moab()=0
bool sYmm
If true assume that matrix is symmetric structure.
Deprecated interface functions.
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:126
double poisson_ratio
Poisson ratio.
Definition plastic.cpp:127
double scale
Definition plastic.cpp:124