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
13
14 HMHHencky(MoFEM::Interface &m_field, const double E, const double nu)
15 : PhysicalEquations(), mField(m_field), E(E), nu(nu) {}
16
17 static constexpr int StrideMatD =
19
20 template <int STRIDEMATD = 0> struct OpHenckyJacobian : public OpJacobian {
21 OpHenckyJacobian(boost::shared_ptr<DataAtIntegrationPts> data_ptr,
22 boost::shared_ptr<HMHHencky> hencky_ptr)
23 : OpJacobian(H1, OPLAST), dataAtGaussPts(data_ptr),
24 henckyPtr(hencky_ptr) {
25 std::fill(&doEntities[MBVERTEX], &doEntities[MBMAXTYPE], false);
26 doEntities[MBVERTEX] = true;
27 }
28
29 MoFEMErrorCode doWork(int side, EntityType type,
30 EntitiesFieldData::EntData &data) {
32 CHKERR henckyPtr->computeMaterialParamsAtPts<STRIDEMATD>(this, data,
35 }
36
37 MoFEMErrorCode evaluateRhs(EntData &data) { return 0; }
38 MoFEMErrorCode evaluateLhs(EntData &data) { return 0; }
39
40 private:
41 boost::shared_ptr<DataAtIntegrationPts> dataAtGaussPts;
42 boost::shared_ptr<HMHHencky> henckyPtr;
43 };
44
45 virtual UserDataOperator *
46 returnOpJacobian(const bool eval_rhs, const bool eval_lhs,
47 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
48 boost::shared_ptr<PhysicalEquations> physics_ptr) {
49
50 auto henckyPtr = boost::dynamic_pointer_cast<HMHHencky>(physics_ptr);
51
52 CHK_THROW_MESSAGE(henckyPtr->getOptions(data_ptr), "getOptions failed");
53 CHK_THROW_MESSAGE(henckyPtr->extractBlockData(Sev::verbose),
54 "Can not get data from block");
55
56 // Check if any heterogeneous or analytical block exists
57 for (const auto &b : henckyPtr->blockData) {
58 if (b.matType != HenckyMatType::HOMOGENEOUS) {
60 MOFEM_LOG("WORLD", Sev::verbose)
61 << "Found non-homogeneous material block: " << b.blockName;
62 break;
63 }
64 }
65
68 data_ptr, boost::dynamic_pointer_cast<HMHHencky>(physics_ptr)));
69 } else {
70 return (new OpHenckyJacobian<0>(
71 data_ptr, boost::dynamic_pointer_cast<HMHHencky>(physics_ptr)));
72 }
73 }
74
75 template <int STRIDEMATD = 0>
77
78 OpSpatialPhysical(const std::string &field_name,
79 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
80 const double alpha_u);
81
82 MoFEMErrorCode integrate(EntData &data);
83
84 MoFEMErrorCode integrateHencky(EntData &data);
85
86 MoFEMErrorCode integratePolyconvexHencky(EntData &data);
87
88 private:
89 const double alphaU;
90 PetscBool polyConvex = PETSC_FALSE;
91 };
92
93 virtual VolUserDataOperator *
95 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
96 const double alpha_u) {
98 return new OpSpatialPhysical<StrideMatD>(field_name, data_ptr, alpha_u);
99 } else {
100 return new OpSpatialPhysical<0>(field_name, data_ptr, alpha_u);
101 }
102 }
103
106 const std::string &field_name,
107 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
108 boost::shared_ptr<ExternalStrainVec> &external_strain_vec_ptr,
109 std::map<std::string, boost::shared_ptr<ScalingMethod>> smv);
110
111 MoFEMErrorCode integrate(EntData &data);
112
113 private:
114 boost::shared_ptr<ExternalStrainVec> externalStrainVecPtr;
115 std::map<std::string, boost::shared_ptr<ScalingMethod>> scalingMethodsMap;
116 };
117
119 const std::string &field_name,
120 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
121 boost::shared_ptr<ExternalStrainVec> external_strain_vec_ptr,
122 std::map<std::string, boost::shared_ptr<ScalingMethod>> smv) {
123 return new OpSpatialPhysicalExternalStrain(field_name, data_ptr,
124 external_strain_vec_ptr, smv);
125 }
126
127 template <int STRIDEMATD = 0>
129 const double alphaU;
130 OpSpatialPhysical_du_du(std::string row_field, std::string col_field,
131 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
132 const double alpha);
133 MoFEMErrorCode integrate(EntData &row_data, EntData &col_data);
134 MoFEMErrorCode integrateHencky(EntData &row_data, EntData &col_data);
135 MoFEMErrorCode integratePolyconvexHencky(EntData &row_data,
136 EntData &col_data);
137
138 private:
139 PetscBool polyConvex = PETSC_FALSE;
140
141 MatrixDouble dP;
142 };
143
145 std::string row_field, std::string col_field,
146 boost::shared_ptr<DataAtIntegrationPts> data_ptr, const double alpha) {
147
149 return new OpSpatialPhysical_du_du<StrideMatD>(row_field, col_field,
150 data_ptr, alpha);
151 } else {
152 return new OpSpatialPhysical_du_du<0>(row_field, col_field, data_ptr,
153 alpha);
154 }
155 }
156
157 /**
158 * @brief Calculate energy density for Hencky material model
159 *
160 *
161 * \f[
162 *
163 * \Psi(\log{\mathbf{U}}) = \frac{1}{2} U_{IJ} D_{IJKL} U_{KL} = \frac{1}{2}
164 * U_{IJ} T_{IJ}
165 *
166 * \f]
167 * where \f$T_{IJ} = D_{IJKL} U_{KL}\f$ is a a Hencky stress.
168 *
169 */
170 template <int STRIDEMATD>
172
173 OpCalculateEnergy(boost::shared_ptr<DataAtIntegrationPts> data_ptr,
174 boost::shared_ptr<double> total_energy_ptr);
175 MoFEMErrorCode doWork(int side, EntityType type, EntData &data);
176
177 private:
178 boost::shared_ptr<DataAtIntegrationPts> dataAtPts;
179 boost::shared_ptr<double> totalEnergyPtr;
180 };
181
183 returnOpCalculateEnergy(boost::shared_ptr<DataAtIntegrationPts> data_ptr,
184 boost::shared_ptr<double> total_energy_ptr) {
185
187 return new OpCalculateEnergy<StrideMatD>(data_ptr, total_energy_ptr);
188 } else {
189 return new OpCalculateEnergy<0>(data_ptr, total_energy_ptr);
190 }
191 }
192
193 template <int STRIDEMATD = 0>
196 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
197 boost::shared_ptr<MatrixDouble> strain_ptr,
198 boost::shared_ptr<MatrixDouble> stress_ptr,
199 boost::shared_ptr<HMHHencky> hencky_ptr);
200 MoFEMErrorCode doWork(int side, EntityType type, EntData &data);
201
202 private:
203 boost::shared_ptr<DataAtIntegrationPts>
204 dataAtPts; ///< data at integration pts
205 boost::shared_ptr<MatrixDouble> strainPtr;
206 boost::shared_ptr<MatrixDouble> stressPtr;
207 boost::shared_ptr<HMHHencky> henckyPtr;
208 };
209
211 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
212 boost::shared_ptr<PhysicalEquations> physics_ptr) {
213 auto henckyPtr = boost::dynamic_pointer_cast<HMHHencky>(physics_ptr);
214
215 CHK_THROW_MESSAGE(henckyPtr->getOptions(data_ptr), "getOptions failed");
216 CHK_THROW_MESSAGE(henckyPtr->extractBlockData(Sev::verbose),
217 "Can not get data from block");
218
219 // Check if any heterogeneous or analytical block exists
220 for (const auto &b : henckyPtr->blockData) {
221 if (b.matType != HenckyMatType::HOMOGENEOUS) {
223 MOFEM_LOG("WORLD", Sev::verbose)
224 << "Found non-homogeneous material block: " << b.blockName;
225 break;
226 }
227 }
228
231 data_ptr, data_ptr->getLogStretchTensorAtPts(),
232 data_ptr->getApproxPAtPts(),
233 boost::dynamic_pointer_cast<HMHHencky>(physics_ptr));
234 } else {
236 data_ptr, data_ptr->getLogStretchTensorAtPts(),
237 data_ptr->getApproxPAtPts(),
238 boost::dynamic_pointer_cast<HMHHencky>(physics_ptr));
239 }
240 }
241
243 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
244 boost::shared_ptr<PhysicalEquations> physics_ptr) {
245 auto henckyPtr = boost::dynamic_pointer_cast<HMHHencky>(physics_ptr);
246
247 CHK_THROW_MESSAGE(henckyPtr->getOptions(data_ptr), "getOptions failed");
248 CHK_THROW_MESSAGE(henckyPtr->extractBlockData(Sev::verbose),
249 "Can not get data from block");
250
251 // Check if any heterogeneous or analytical block exists
252 for (const auto &b : henckyPtr->blockData) {
253 if (b.matType != HenckyMatType::HOMOGENEOUS) {
255 MOFEM_LOG("WORLD", Sev::verbose)
256 << "Found non-homogeneous material block: " << b.blockName;
257 break;
258 }
259 }
260
263 data_ptr, data_ptr->getVarLogStreachPts(), data_ptr->getVarPiolaPts(),
264 boost::dynamic_pointer_cast<HMHHencky>(physics_ptr));
265 } else {
267 data_ptr, data_ptr->getVarLogStreachPts(), data_ptr->getVarPiolaPts(),
268 boost::dynamic_pointer_cast<HMHHencky>(physics_ptr));
269 }
270 }
271
272 MoFEMErrorCode getOptions(boost::shared_ptr<DataAtIntegrationPts> data_ptr) {
274 PetscOptionsBegin(PETSC_COMM_WORLD, "hencky_", "", "none");
275
276 CHKERR PetscOptionsScalar("-young_modulus", "Young modulus", "", E, &E,
277 PETSC_NULLPTR);
278 CHKERR PetscOptionsScalar("-poisson_ratio", "poisson ratio", "", nu, &nu,
279 PETSC_NULLPTR);
280
281 PetscOptionsEnd();
282
284 << "Hencky: E = " << E << " nu = " << nu;
285 getOptionsSeverityLevels = Sev::verbose;
286
287 CHKERRG(ierr);
288
290 }
291
292 MoFEMErrorCode extractBlockData(Sev sev) {
293 return extractBlockData(
294
295 mField.getInterface<MeshsetsManager>()->getCubitMeshsetPtr(std::regex(
296
297 (boost::format("(.*)%s(.*)") % "_ELASTIC").str()
298
299 )),
300
301 sev);
302 }
303
304 MoFEMErrorCode
305 extractBlockData(std::vector<const CubitMeshSets *> meshset_vec_ptr,
306 Sev sev) {
308
309 for (auto m : meshset_vec_ptr) {
310 MOFEM_TAG_AND_LOG("WORLD", sev, "MatBlock") << *m;
311 std::vector<double> block_data;
312 CHKERR m->getAttributes(block_data);
313 if (block_data.size() < 2) {
314 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
315 "Expected that block has atleast two attributes");
316 }
317 auto get_block_ents = [&]() {
318 Range ents;
319 CHKERR mField.get_moab().get_entities_by_handle(m->meshset, ents, true);
320 return ents;
321 };
322
323 double young_modulus = block_data[0];
324 double poisson_ratio = block_data[1];
325 double bulk_modulus_K = young_modulus / (3 * (1 - 2 * poisson_ratio));
326 double shear_modulus_G = young_modulus / (2 * (1 + poisson_ratio));
327
328 MOFEM_TAG_AND_LOG("WORLD", sev, "MatBlock")
329 << "E = " << young_modulus << " nu = " << poisson_ratio;
330
331 std::string block_name = m->getName();
332
333 auto block_name_heterogeneous = "(.*)HETEROGENEOUS_ELASTIC(.*)";
334 auto block_name_analytical = "(.*)ANALYTICAL_ELASTIC(.*)";
335 std::regex reg_name_heterogeneous(block_name_heterogeneous);
336 std::regex reg_name_analytical(block_name_analytical);
337
339 if (std::regex_match(block_name, reg_name_heterogeneous)) {
341 } else if (std::regex_match(block_name, reg_name_analytical)) {
342 mat_type = HenckyMatType::ANALYTICAL;
343 }
344
345 blockData.push_back({block_name, young_modulus, poisson_ratio,
346 bulk_modulus_K, shear_modulus_G, get_block_ents(),
347 mat_type});
348 }
349 MOFEM_LOG_CHANNEL("WORLD");
351 }
352
353 template <int STRIDEMATD, typename OP_PTR>
355 OP_PTR op_ptr, EntitiesFieldData::EntData &data,
356 boost::shared_ptr<DataAtIntegrationPts> dataAtGaussPts) {
358
359 auto getLamesParam = [](double E, double nu) {
360 double bulk_modulus_K = E / (3 * (1 - 2 * nu));
361 double shear_modulus_G = E / (2 * (1 + nu));
362 double mu = shear_modulus_G;
363 double lambda = bulk_modulus_K - 2 * shear_modulus_G / 3;
364 return std::make_pair(mu, lambda);
365 };
366
367 auto fe_ent = op_ptr->getNumeredEntFiniteElementPtr()->getEnt();
368 int nb_integration_pts = op_ptr->getGaussPts().size2();
369
370 dataAtGaussPts->muAtPts.resize(nb_integration_pts, false);
371 dataAtGaussPts->lambdaAtPts.resize(nb_integration_pts, false);
372 dataAtGaussPts->muAtPts.clear();
373 dataAtGaussPts->lambdaAtPts.clear();
374
375 dataAtGaussPts->youngModulusAtPts.resize(nb_integration_pts, false);
376 dataAtGaussPts->youngModulusAtPts.clear();
377
378 auto t_young_modulus =
379 getFTensor0FromVec(dataAtGaussPts->youngModulusAtPts);
380 auto t_mu = getFTensor0FromVec(dataAtGaussPts->muAtPts);
381 auto t_lambda = getFTensor0FromVec(dataAtGaussPts->lambdaAtPts);
382
383 MatrixSizeHelper<
384 GetFTensor4DdgFromMatType<SPACE_DIM, SPACE_DIM, STRIDEMATD, DL>,
385 DL>::size(dataAtGaussPts->matD, nb_integration_pts);
386 MatrixSizeHelper<
387 GetFTensor4DdgFromMatType<SPACE_DIM, SPACE_DIM, STRIDEMATD, DL>,
388 DL>::size(dataAtGaussPts->matAxiatorD, nb_integration_pts);
389 MatrixSizeHelper<
390 GetFTensor4DdgFromMatType<SPACE_DIM, SPACE_DIM, STRIDEMATD, DL>,
391 DL>::size(dataAtGaussPts->matDeviatorD, nb_integration_pts);
392 MatrixSizeHelper<
393 GetFTensor4DdgFromMatType<SPACE_DIM, SPACE_DIM, STRIDEMATD, DL>,
394 DL>::size(dataAtGaussPts->matInvD, nb_integration_pts);
395
396 dataAtGaussPts->matD.clear();
397 dataAtGaussPts->matAxiatorD.clear();
398 dataAtGaussPts->matDeviatorD.clear();
399 dataAtGaussPts->matInvD.clear();
400
406
407 auto t_D = getFTensor4DdgFromMat<SPACE_DIM, SPACE_DIM, STRIDEMATD>(
408 dataAtGaussPts->matD);
409 auto t_axiator_D = getFTensor4DdgFromMat<SPACE_DIM, SPACE_DIM, STRIDEMATD>(
410 dataAtGaussPts->matAxiatorD);
411 auto t_deviator_D = getFTensor4DdgFromMat<SPACE_DIM, SPACE_DIM, STRIDEMATD>(
412 dataAtGaussPts->matDeviatorD);
413 auto t_inv_D = getFTensor4DdgFromMat<SPACE_DIM, SPACE_DIM, STRIDEMATD>(
414 dataAtGaussPts->matInvD);
415
416 auto next = [&]() {
417 ++t_young_modulus;
418 ++t_mu;
419 ++t_lambda;
420 ++t_D;
421 ++t_axiator_D;
422 ++t_deviator_D;
423 ++t_inv_D;
424 };
425
426 auto evalMatD = [&](double bulk_modulus_K, double shear_modulus_G) {
428 t_axiator_D(i, j, k, l) = (bulk_modulus_K - (2. / 3.) * shear_modulus_G) *
429 t_kd(i, j) * t_kd(k, l);
430 t_deviator_D(i, j, k, l) =
431 2 * shear_modulus_G * ((t_kd(i, k) ^ t_kd(j, l)) / 4.);
432 t_D(i, j, k, l) = t_axiator_D(i, j, k, l) + t_deviator_D(i, j, k, l);
434 };
435
436 auto evalInvMatDPtr = [&](double bulk_modulus_K, double shear_modulus_G) {
438 const double A = 1. / (2. * shear_modulus_G);
439 const double B =
440 (1. / (9. * bulk_modulus_K)) - (1. / (6. * shear_modulus_G));
441 t_inv_D(i, j, k, l) =
442 A * ((t_kd(i, k) ^ t_kd(j, l)) / 4.) + B * t_kd(i, j) * t_kd(k, l);
444 };
445
446 // from block data (MAT_ELASTIC) or (ANALYTICAL_ELASTIC) if provided,
447 // otherwise from command line options
448 for (auto &b : this->blockData) {
449 if (b.blockEnts.find(op_ptr->getFEEntityHandle()) != b.blockEnts.end()) {
450
451 if (b.matType == HMHHencky::HenckyMatType::ANALYTICAL) {
452 VectorDouble analytical_elastic;
453 analytical_elastic = getAnalyticalElastic(op_ptr, b.blockName);
454
455 auto t_analytical_elastic = getFTensor0FromVec(analytical_elastic);
456
457 for (int gg = 0; gg != nb_integration_pts; ++gg) {
458 t_young_modulus = t_analytical_elastic;
459 double bulk_modulus_K =
460 t_analytical_elastic / (3 * (1 - 2 * b.poissonRatio));
461 double shear_modulus_G =
462 t_analytical_elastic / (2 * (1 + b.poissonRatio));
463 t_mu = shear_modulus_G;
464 t_lambda = bulk_modulus_K - 2 * shear_modulus_G / 3;
465
467 CHKERR evalInvMatDPtr(bulk_modulus_K, shear_modulus_G);
468 ++t_analytical_elastic;
469 next();
470 }
471
472 } else if (b.matType == HMHHencky::HenckyMatType::HETEROGENEOUS) {
473 Tag tag_heterogenous_mat;
474 CHKERR op_ptr->getPtrFE()->mField.get_moab().tag_get_handle(
476 tag_heterogenous_mat);
477 int tag_length;
478 CHKERR op_ptr->getPtrFE()->mField.get_moab().tag_get_length(
479 tag_heterogenous_mat, tag_length);
480 if (tag_length != 1) {
481 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
482 "heterogeneous Young's modulus tag should be 1 but is %d",
483 tag_length);
484 }
486 // Constant interpolation (element-wise)
487 double elem_young_mod = 0.0;
488 CHKERR op_ptr->getPtrFE()->mField.get_moab().tag_get_data(
489 tag_heterogenous_mat, &fe_ent, 1, &elem_young_mod);
490
491 for (int gg = 0; gg != nb_integration_pts; ++gg) {
492 t_young_modulus = elem_young_mod;
493 auto [mu, lambda] = getLamesParam(elem_young_mod, b.poissonRatio);
494 t_mu = mu;
495 t_lambda = lambda;
496 double bulk_modulus_K =
497 elem_young_mod / (3 * (1 - 2 * b.poissonRatio));
498 double shear_modulus_G =
499 elem_young_mod / (2 * (1 + b.poissonRatio));
500
502 CHKERR evalInvMatDPtr(bulk_modulus_K, shear_modulus_G);
503 next();
504 }
506 // Linear interpolation (vertex-based)
507 const EntityHandle *vert_conn;
508 int vert_num;
509 CHKERR op_ptr->getPtrFE()->mField.get_moab().get_connectivity(
510 fe_ent, vert_conn, vert_num, true);
511
512 VectorDouble vert_young_mod(vert_num);
513 CHKERR op_ptr->getPtrFE()->mField.get_moab().tag_get_data(
514 tag_heterogenous_mat, vert_conn, vert_num, &vert_young_mod[0]);
515
516 auto t_shape_n = data.getFTensor0N();
517 int nb_shape_fn = data.getN(NOBASE).size2();
518
519 for (int gg = 0; gg != nb_integration_pts; ++gg) {
520 t_young_modulus = 0; // Initialize to zero before accumulation
521 auto t_vert_young_mod = getFTensor0FromVec(vert_young_mod);
522 for (int bb = 0; bb != nb_shape_fn; ++bb) {
523 t_young_modulus += t_vert_young_mod * t_shape_n;
524 ++t_vert_young_mod;
525 ++t_shape_n;
526 }
527 auto [mu, lambda] =
528 getLamesParam(t_young_modulus, b.poissonRatio);
529 t_mu = mu;
530 t_lambda = lambda;
531 double bulk_modulus_K =
532 t_young_modulus / (3 * (1 - 2 * b.poissonRatio));
533 double shear_modulus_G =
534 t_young_modulus / (2 * (1 + b.poissonRatio));
535
537 CHKERR evalInvMatDPtr(bulk_modulus_K, shear_modulus_G);
538 next();
539 }
540 } else {
541 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
542 "Unsupported heterogeneous Young's modulus interpolation "
543 "order %d",
545 }
546 } else {
547 // MAT_ELASTIC block with homogeneous material properties
548 for (int gg = 0; gg != nb_integration_pts; ++gg) {
549 t_young_modulus = b.youngModulus;
550 t_mu = b.shearModulusG;
551 t_lambda = b.bulkModulusK - 2 * b.shearModulusG / 3;
552
553 CHKERR evalMatD(b.bulkModulusK, b.shearModulusG);
554 CHKERR evalInvMatDPtr(b.bulkModulusK, b.shearModulusG);
555 next();
556 }
557 }
559 }
560 }
561
562 // From command line options if no block data is provided
563 const auto E = this->E;
564 const auto nu = this->nu;
565
566 double bulk_modulus_K = E / (3 * (1 - 2 * nu));
567 double shear_modulus_G = E / (2 * (1 + nu));
568
569 // Keep scalar Lamé parameters in sync for homogeneous/default material.
570 dataAtGaussPts->mu = shear_modulus_G;
571 dataAtGaussPts->lambda = bulk_modulus_K - 2 * shear_modulus_G / 3;
572
573 for (int gg = 0; gg != nb_integration_pts; ++gg) {
574 t_young_modulus = E;
575 t_mu = shear_modulus_G;
576 t_lambda = bulk_modulus_K - 2 * shear_modulus_G / 3;
578 CHKERR evalInvMatDPtr(bulk_modulus_K, shear_modulus_G);
579 next();
580 }
581
583 }
584
586
587 OpTopoSpatialPhysical(const std::string &field_name,
588 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
589 SmartPetscObj<Vec> assemble_vec,
590 boost::shared_ptr<TopologicalData> topo_ptr,
591 const double alpha_u,
592 boost::shared_ptr<double> J_ptr);
593
594 MoFEMErrorCode integrate(EntData &data);
595
596 MoFEMErrorCode integrateHencky(EntData &data);
597
598 MoFEMErrorCode integratePolyconvexHencky(EntData &data);
599
600 MoFEMErrorCode assemble(int row_side, EntityType row_type,
601 EntData &data) override;
602
603 private:
604 const double alphaU;
605 PetscBool polyConvex = PETSC_FALSE;
606 boost::shared_ptr<TopologicalData> topoDataPtr;
607 SmartPetscObj<Vec> assembleVec;
608 boost::shared_ptr<double> JPtr;
609 double locJ;
610 };
611
612 virtual VolUserDataOperator *
614 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
615 SmartPetscObj<Vec> assemble_vec,
616 boost::shared_ptr<TopologicalData> topo_ptr,
617 const double alpha_u,
618 boost::shared_ptr<double> J_ptr) override {
619 return new OpTopoSpatialPhysical(field_name, data_ptr, assemble_vec,
620 topo_ptr, alpha_u, J_ptr);
621 }
622
623private:
625
636 std::vector<BlockData> blockData;
637
638 double E;
639 double nu;
640
641 // Set verbosity level, it verbile can changes that informatno is pronated
642 // only once at particular level
643 Sev getOptionsSeverityLevels = Sev::inform;
644};
645
646template <int STRIDEMATD>
648 const std::string &field_name,
649 boost::shared_ptr<DataAtIntegrationPts> data_ptr, const double alpha_u)
650 : OpAssembleVolume(field_name, data_ptr, OPROW), alphaU(alpha_u) {
651
652 CHK_MOAB_THROW(PetscOptionsGetBool(PETSC_NULLPTR, "", "-poly_convex",
653 &polyConvex, PETSC_NULLPTR),
654 "get polyconvex option failed");
655}
656
657template <int STRIDEMATD>
658MoFEMErrorCode
662 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
663 "Polyconvex Hencky with heterogeneous material properties is not "
664 "implemented");
665 }
666 if (polyConvex) {
667 CHKERR integratePolyconvexHencky(data);
668 } else {
669 CHKERR integrateHencky(data);
670 }
672}
673
674template <int STRIDEMATD>
675MoFEMErrorCode
678
680 auto t_L = symm_L_tensor();
681
682 int nb_dofs = data.getIndices().size();
683 int nb_integration_pts = data.getN().size1();
684 auto v = getVolume();
685 auto t_w = getFTensor0IntegrationWeight();
686 auto t_approx_P_adjoint_log_du =
687 dataAtPts->getFTensorAdjointPdU(nb_integration_pts);
688 auto t_log_stretch_h1 =
689 dataAtPts->getFTensorLogStretchTotal(nb_integration_pts);
690 auto t_dot_log_u = dataAtPts->getFTensorLogStretchDot(nb_integration_pts);
691
692 auto t_D = getFTensor4DdgFromMat<3, 3, STRIDEMATD>(dataAtPts->matD);
693
694 FTensor::Index<'i', 3> i;
695 FTensor::Index<'j', 3> j;
696 FTensor::Index<'k', 3> k;
697 FTensor::Index<'l', 3> l;
698 auto get_ftensor2 = [](auto &v) {
700 &v[0], &v[1], &v[2], &v[3], &v[4], &v[5]);
701 };
702
703 int nb_base_functions = data.getN().size2();
704 auto t_row_base_fun = data.getFTensor0N();
705
706 for (int gg = 0; gg != nb_integration_pts; ++gg) {
707 double a = v * t_w;
708 auto t_nf = get_ftensor2(nF);
709
711 t_T(i, j) =
712 t_D(i, j, k, l) * (t_log_stretch_h1(k, l) + alphaU * t_dot_log_u(k, l));
714 t_residual(L) =
715 a * (t_approx_P_adjoint_log_du(L) - t_L(i, j, L) * t_T(i, j));
716
717 int bb = 0;
718 for (; bb != nb_dofs / 6; ++bb) {
719 t_nf(L) -= t_row_base_fun * t_residual(L);
720 ++t_nf;
721 ++t_row_base_fun;
722 }
723 for (; bb != nb_base_functions; ++bb)
724 ++t_row_base_fun;
725
726 ++t_D;
727 ++t_w;
728 ++t_approx_P_adjoint_log_du;
729 ++t_dot_log_u;
730 ++t_log_stretch_h1;
731 }
732
734}
735
736template <int STRIDEMATD>
737MoFEMErrorCode
739 EntData &data) {
741
743 auto t_L = symm_L_tensor();
744
745 int nb_dofs = data.getIndices().size();
746 int nb_integration_pts = data.getN().size1();
747 auto v = getVolume();
748 auto t_w = getFTensor0IntegrationWeight();
749 auto t_approx_P_adjoint_log_du =
750 dataAtPts->getFTensorAdjointPdU(nb_integration_pts);
751 auto t_log_stretch_h1 =
752 dataAtPts->getFTensorLogStretchTotal(nb_integration_pts);
753 auto t_dot_log_u = dataAtPts->getFTensorLogStretchDot(nb_integration_pts);
754
755 auto t_D = getFTensor4DdgFromMat<3, 3, 0>(dataAtPts->matD);
756
757 FTensor::Index<'i', 3> i;
758 FTensor::Index<'j', 3> j;
759 FTensor::Index<'k', 3> k;
760 FTensor::Index<'l', 3> l;
761 auto get_ftensor2 = [](auto &v) {
763 &v[0], &v[1], &v[2], &v[3], &v[4], &v[5]);
764 };
765
766 constexpr double nohat_k = 1. / 4;
767 constexpr double hat_k = 1. / 8;
768 double mu = dataAtPts->mu;
769 double lambda = dataAtPts->lambda;
770
771 constexpr double third = boost::math::constants::third<double>();
773 auto t_diff_deviator = diff_deviator(diff_tensor());
774
775 int nb_base_functions = data.getN().size2();
776 auto t_row_base_fun = data.getFTensor0N();
777 for (int gg = 0; gg != nb_integration_pts; ++gg) {
778 double a = v * t_w;
779 auto t_nf = get_ftensor2(nF);
780
781 double log_det = t_log_stretch_h1(i, i);
782 double log_det2 = log_det * log_det;
784 t_dev(i, j) = t_log_stretch_h1(i, j) - t_kd(i, j) * (third * log_det);
785 double dev_norm2 = t_dev(i, j) * t_dev(i, j);
786
788 auto A = 2 * mu * std::exp(nohat_k * dev_norm2);
789 auto B = lambda * std::exp(hat_k * log_det2) * log_det;
790 t_T(i, j) =
791
792 A * (t_dev(k, l) * t_diff_deviator(k, l, i, j))
793
794 +
795
796 B * t_kd(i, j)
797
798 +
799
800 alphaU * t_D(i, j, k, l) * t_dot_log_u(k, l);
801
803 t_residual(L) =
804 a * (t_approx_P_adjoint_log_du(L) - t_L(i, j, L) * t_T(i, j));
805
806 int bb = 0;
807 for (; bb != nb_dofs / size_symm; ++bb) {
808 t_nf(L) -= t_row_base_fun * t_residual(L);
809 ++t_nf;
810 ++t_row_base_fun;
811 }
812 for (; bb != nb_base_functions; ++bb)
813 ++t_row_base_fun;
814
815 ++t_w;
816 ++t_approx_P_adjoint_log_du;
817 ++t_dot_log_u;
818 ++t_log_stretch_h1;
819 }
821}
822
823template <int STRIDEMATD>
825 std::string row_field, std::string col_field,
826 boost::shared_ptr<DataAtIntegrationPts> data_ptr, const double alpha)
827 : OpAssembleVolume(row_field, col_field, data_ptr, OPROWCOL, false),
828 alphaU(alpha) {
829 sYmm = false;
830
831 CHK_MOAB_THROW(PetscOptionsGetBool(PETSC_NULLPTR, "", "-poly_convex",
832 &polyConvex, PETSC_NULLPTR),
833 "get polyconvex option failed");
834}
835
837 const std::string &field_name,
838 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
839 boost::shared_ptr<ExternalStrainVec> &external_strain_vec_ptr,
840 std::map<std::string, boost::shared_ptr<ScalingMethod>> smv)
841 : OpAssembleVolume(field_name, data_ptr, OPROW),
842 externalStrainVecPtr(external_strain_vec_ptr), scalingMethodsMap(smv) {}
843
844MoFEMErrorCode
847
849
850 double time = OpAssembleVolume::getFEMethod()->ts_t;
853 }
854 // get entity of tet
856 // iterate over all block data
857
858 for (auto &ext_strain_block : (*externalStrainVecPtr)) {
859 // check if finite element entity is part of the EXTERNALSTRAIN block
860 if (ext_strain_block.ents.find(fe_ent) != ext_strain_block.ents.end()) {
861
862 double scale = 1;
863 if (scalingMethodsMap.find(ext_strain_block.blockName) !=
864 scalingMethodsMap.end()) {
865 scale *=
866 scalingMethodsMap.at(ext_strain_block.blockName)->getScale(time);
867 } else {
868 MOFEM_LOG("SELF", Sev::warning)
869 << "No scaling method found for " << ext_strain_block.blockName;
870 }
871
872 int nb_dofs = data.getIndices().size();
873 int nb_integration_pts = data.getN().size1();
874 auto v = getVolume();
875 auto t_w = getFTensor0IntegrationWeight();
877
878 double external_strain_val;
879 VectorDouble v_external_strain;
880 auto block_name = "(.*)ANALYTICAL_EXTERNALSTRAIN(.*)";
881 std::regex reg_name(block_name);
882 if (std::regex_match(ext_strain_block.blockName, reg_name)) {
883 VectorDouble analytical_external_strain;
884 std::string block_name_tmp;
885 std::tie(block_name_tmp, v_external_strain) =
886 getAnalyticalExternalStrain(this, analytical_external_strain,
887 ext_strain_block.blockName);
888 } else {
889 // get ExternalStrain data from block
890 external_strain_val = scale * ext_strain_block.val;
891 // fill with same scalar value for all integration points
892 v_external_strain.resize(nb_integration_pts);
893 std::fill(v_external_strain.begin(), v_external_strain.end(),
894 external_strain_val);
895 }
896 auto t_external_strain = getFTensor0FromVec(v_external_strain);
897 double bulk_modulus_K = ext_strain_block.bulkModulusK;
898 auto t_L = symm_L_tensor();
899
900 FTensor::Index<'i', 3> i;
901 FTensor::Index<'j', 3> j;
902 FTensor::Index<'k', 3> k;
903 FTensor::Index<'l', 3> l;
904 auto get_ftensor2 = [](auto &v) {
906 &v[0], &v[1], &v[2], &v[3], &v[4], &v[5]);
907 };
908
909 int nb_base_functions = data.getN().size2();
910 auto t_row_base_fun = data.getFTensor0N();
911 for (int gg = 0; gg != nb_integration_pts; ++gg) {
912 auto tr = 3.0 * t_external_strain;
913 double a = v * t_w;
914 auto t_nf = get_ftensor2(nF);
915
917
918 t_T(i, j) = -bulk_modulus_K * tr * t_kd(i, j);
919
921 t_residual(L) = a * (t_L(i, j, L) * t_T(i, j));
922
923 int bb = 0;
924 for (; bb != nb_dofs / 6; ++bb) {
925 t_nf(L) += t_row_base_fun * t_residual(L);
926 ++t_nf;
927 ++t_row_base_fun;
928 }
929 for (; bb != nb_base_functions; ++bb)
930 ++t_row_base_fun;
931 ++t_external_strain;
932 ++t_w;
933 }
934 }
935 }
936
938}
939
940template <int STRIDEMATD>
941MoFEMErrorCode
943 EntData &col_data) {
946 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
947 "Polyconvex Hencky with heterogeneous material properties is not "
948 "implemented");
949 }
950 if (polyConvex) {
951 CHKERR integratePolyconvexHencky(row_data, col_data);
952 } else {
953 CHKERR integrateHencky(row_data, col_data);
954 }
956}
957
958template <int STRIDEMATD>
960 EntData &row_data, EntData &col_data) {
962
965 auto t_L = symm_L_tensor();
966 auto t_diff = diff_tensor();
967
968 int nb_integration_pts = row_data.getN().size1();
969 int row_nb_dofs = row_data.getIndices().size();
970 int col_nb_dofs = col_data.getIndices().size();
971
972 auto get_ftensor2 = [](MatrixDouble &m, const int r, const int c) {
974 size_symm>(
975
976 &m(r + 0, c + 0), &m(r + 0, c + 1), &m(r + 0, c + 2), &m(r + 0, c + 3),
977 &m(r + 0, c + 4), &m(r + 0, c + 5),
978
979 &m(r + 1, c + 0), &m(r + 1, c + 1), &m(r + 1, c + 2), &m(r + 1, c + 3),
980 &m(r + 1, c + 4), &m(r + 1, c + 5),
981
982 &m(r + 2, c + 0), &m(r + 2, c + 1), &m(r + 2, c + 2), &m(r + 2, c + 3),
983 &m(r + 2, c + 4), &m(r + 2, c + 5),
984
985 &m(r + 3, c + 0), &m(r + 3, c + 1), &m(r + 3, c + 2), &m(r + 3, c + 3),
986 &m(r + 3, c + 4), &m(r + 3, c + 5),
987
988 &m(r + 4, c + 0), &m(r + 4, c + 1), &m(r + 4, c + 2), &m(r + 4, c + 3),
989 &m(r + 4, c + 4), &m(r + 4, c + 5),
990
991 &m(r + 5, c + 0), &m(r + 5, c + 1), &m(r + 5, c + 2), &m(r + 5, c + 3),
992 &m(r + 5, c + 4), &m(r + 5, c + 5)
993
994 );
995 };
996
997 FTENSOR_INDEXES(SPACE_DIM, i, j, k, l, m, n);
998
999 auto v = getVolume();
1000 auto t_w = getFTensor0IntegrationWeight();
1001
1002 auto t_approx_P_adjoint__dstretch =
1003 dataAtPts->getFTensorAdjointPdstretch(nb_integration_pts);
1004 auto t_eigen_vals = dataAtPts->getFTensorEigenVals(nb_integration_pts);
1005 auto t_eigen_vecs = dataAtPts->getFTensorEigenVecs(nb_integration_pts);
1006
1007 int row_nb_base_functions = row_data.getN().size2();
1008 auto t_row_base_fun = row_data.getFTensor0N();
1009
1010 auto get_dP = [&]() {
1011 auto get_stress =
1012 MatrixSizeHelper<GetFTensor2FromMatType<size_symm, size_symm, -1, DL>,
1013 DL>::size(dP, nb_integration_pts);
1014 auto ts_a = getTSa();
1015
1016 auto t_D = getFTensor4DdgFromMat<3, 3, STRIDEMATD>(dataAtPts->matD);
1018 if constexpr (!STRIDEMATD) {
1019 t_dP_tmp(L, J) = -(1 + alphaU * ts_a) *
1020 (t_L(i, j, L) * ((t_D(i, j, m, n) * t_diff(m, n, k, l)) *
1021 t_L(k, l, J)));
1022 }
1023 // allocate FTensors
1025 L_left(i, j, L) = t_L(i, j, L);
1027 L_right(k, l, J) = t_L(k, l, J);
1029
1032 auto t_approx_P_adjoint__dstretch =
1033 dataAtPts->getFTensorAdjointPdstretch(nb_integration_pts);
1034 auto t_eigen_vals = dataAtPts->getFTensorEigenVals(nb_integration_pts);
1035 auto t_eigen_vecs = dataAtPts->getFTensorEigenVecs(nb_integration_pts);
1036 auto &nbUniq = dataAtPts->nbUniq;
1037
1038 auto t_dP = get_stress();
1039 for (auto gg = 0; gg != nb_integration_pts; ++gg) {
1040 if constexpr (STRIDEMATD) {
1041 temp(i, j, k, l) = t_D(i, j, m, n) * t_diff(m, n, k, l);
1042
1043 t_dP_tmp(L, J) =
1044 -(1 + alphaU * ts_a) *
1045 (L_left(i, j, L) * (temp(i, j, k, l) * L_right(k, l, J)));
1046
1047 ++t_D;
1048 }
1049
1050 // Work of symmetric tensor on undefined tensor is equal to the work
1051 // of the symmetric part of it
1053 t_sym(i, j) = (t_approx_P_adjoint__dstretch(i, j) ||
1054 t_approx_P_adjoint__dstretch(j, i));
1055 t_sym(i, j) /= 2.0;
1056 auto t_diff2_uP2 = EigenMatrix::getDiffDiffMat(
1057 t_eigen_vals, t_eigen_vecs, EshelbianCore::f, EshelbianCore::d_f,
1058 EshelbianCore::dd_f, t_sym, nbUniq[gg]);
1059 t_dP(L, J) = t_L(i, j, L) *
1060 ((t_diff2_uP2(i, j, k, l) + t_diff2_uP2(k, l, i, j)) *
1061 t_L(k, l, J)) /
1062 2. +
1063 t_dP_tmp(L, J);
1064
1065 ++t_dP;
1066 ++t_approx_P_adjoint__dstretch;
1067 ++t_eigen_vals;
1068 ++t_eigen_vecs;
1069 }
1070 } else {
1071 auto t_dP = get_stress();
1072 for (auto gg = 0; gg != nb_integration_pts; ++gg) {
1073 if constexpr (STRIDEMATD) {
1074 temp(i, j, k, l) = t_D(i, j, m, n) * t_diff(m, n, k, l);
1075
1076 t_dP_tmp(L, J) =
1077 -(1 + alphaU * ts_a) *
1078 (L_left(i, j, L) * (temp(i, j, k, l) * L_right(k, l, J)));
1079
1080 ++t_D;
1081 }
1082 t_dP(L, J) = t_dP_tmp(L, J);
1083
1084 ++t_dP;
1085 }
1086 }
1087
1088 return get_stress();
1089 };
1090
1091 auto t_dP = get_dP();
1092
1093 for (int gg = 0; gg != nb_integration_pts; ++gg) {
1094 double a = v * t_w;
1095
1096 int rr = 0;
1097 for (; rr != row_nb_dofs / 6; ++rr) {
1098 auto t_col_base_fun = col_data.getFTensor0N(gg, 0);
1099 auto t_m = get_ftensor2(K, 6 * rr, 0);
1100 for (int cc = 0; cc != col_nb_dofs / 6; ++cc) {
1101 const double b = a * t_row_base_fun * t_col_base_fun;
1102 t_m(L, J) -= b * t_dP(L, J);
1103 ++t_m;
1104 ++t_col_base_fun;
1105 }
1106 ++t_row_base_fun;
1107 }
1108
1109 for (; rr != row_nb_base_functions; ++rr) {
1110 ++t_row_base_fun;
1111 }
1112
1113 ++t_w;
1114 ++t_dP;
1115 }
1117}
1118
1119template <int STRIDEMATD>
1120MoFEMErrorCode
1122 EntData &row_data, EntData &col_data) {
1124
1125 FTensor::Index<'L', size_symm> L;
1127 auto t_L = symm_L_tensor();
1128 auto t_diff = diff_tensor();
1129
1130 int nb_integration_pts = row_data.getN().size1();
1131 int row_nb_dofs = row_data.getIndices().size();
1132 int col_nb_dofs = col_data.getIndices().size();
1133
1134 auto get_ftensor2 = [](MatrixDouble &m, const int r, const int c) {
1136 size_symm>(
1137
1138 &m(r + 0, c + 0), &m(r + 0, c + 1), &m(r + 0, c + 2), &m(r + 0, c + 3),
1139 &m(r + 0, c + 4), &m(r + 0, c + 5),
1140
1141 &m(r + 1, c + 0), &m(r + 1, c + 1), &m(r + 1, c + 2), &m(r + 1, c + 3),
1142 &m(r + 1, c + 4), &m(r + 1, c + 5),
1143
1144 &m(r + 2, c + 0), &m(r + 2, c + 1), &m(r + 2, c + 2), &m(r + 2, c + 3),
1145 &m(r + 2, c + 4), &m(r + 2, c + 5),
1146
1147 &m(r + 3, c + 0), &m(r + 3, c + 1), &m(r + 3, c + 2), &m(r + 3, c + 3),
1148 &m(r + 3, c + 4), &m(r + 3, c + 5),
1149
1150 &m(r + 4, c + 0), &m(r + 4, c + 1), &m(r + 4, c + 2), &m(r + 4, c + 3),
1151 &m(r + 4, c + 4), &m(r + 4, c + 5),
1152
1153 &m(r + 5, c + 0), &m(r + 5, c + 1), &m(r + 5, c + 2), &m(r + 5, c + 3),
1154 &m(r + 5, c + 4), &m(r + 5, c + 5)
1155
1156 );
1157 };
1158 FTensor::Index<'i', 3> i;
1159 FTensor::Index<'j', 3> j;
1160 FTensor::Index<'k', 3> k;
1161 FTensor::Index<'l', 3> l;
1162 FTensor::Index<'m', 3> m;
1163 FTensor::Index<'n', 3> n;
1164
1165 auto v = getVolume();
1166 auto t_w = getFTensor0IntegrationWeight();
1167
1168 int row_nb_base_functions = row_data.getN().size2();
1169 auto t_row_base_fun = row_data.getFTensor0N();
1170
1171 auto get_dP = [&]() {
1172 auto get_stress =
1173 MatrixSizeHelper<GetFTensor2FromMatType<size_symm, size_symm, -1, DL>,
1174 DL>::size(dP, nb_integration_pts);
1175 auto ts_a = getTSa();
1176
1177 auto t_D = getFTensor4DdgFromPtr<3, 3, 0>(&*dataAtPts->matD.data().begin());
1178
1179 constexpr double nohat_k = 1. / 4;
1180 constexpr double hat_k = 1. / 8;
1181 double mu = dataAtPts->mu;
1182 double lambda = dataAtPts->lambda;
1183
1184 constexpr double third = boost::math::constants::third<double>();
1186 auto t_diff_deviator = diff_deviator(diff_tensor());
1187
1188 auto t_approx_P_adjoint__dstretch =
1189 dataAtPts->getFTensorAdjointPdstretch(getGaussPts().size2());
1190 auto t_log_stretch_h1 =
1191 dataAtPts->getFTensorLogStretchTotal(getGaussPts().size2());
1192 auto t_eigen_vals = dataAtPts->getFTensorEigenVals(getGaussPts().size2());
1193 auto t_eigen_vecs = dataAtPts->getFTensorEigenVecs(getGaussPts().size2());
1194 auto &nbUniq = dataAtPts->nbUniq;
1195
1196 auto t_dP = get_stress();
1197 for (auto gg = 0; gg != nb_integration_pts; ++gg) {
1198
1199 double log_det = t_log_stretch_h1(i, i);
1200 double log_det2 = log_det * log_det;
1202 t_dev(i, j) = t_log_stretch_h1(i, j) - t_kd(i, j) * (third * log_det);
1203 double dev_norm2 = t_dev(i, j) * t_dev(i, j);
1204
1205 auto A = 2 * mu * std::exp(nohat_k * dev_norm2);
1206 auto B = lambda * std::exp(hat_k * log_det2) * log_det;
1207
1208 FTensor::Tensor2_symmetric<double, 3> t_A_diff, t_B_diff;
1209 t_A_diff(i, j) =
1210 (A * 2 * nohat_k) * (t_dev(k, l) * t_diff_deviator(k, l, i, j));
1211 t_B_diff(i, j) = (B * 2 * hat_k) * log_det * t_kd(i, j) +
1212 lambda * std::exp(hat_k * log_det2) * t_kd(i, j);
1214 t_dT(i, j, k, l) =
1215 t_A_diff(i, j) * (t_dev(m, n) * t_diff_deviator(m, n, k, l))
1216
1217 +
1218
1219 A * t_diff_deviator(m, n, i, j) * t_diff_deviator(m, n, k, l)
1220
1221 +
1222
1223 t_B_diff(i, j) * t_kd(k, l);
1224
1225 t_dP(L, J) = -t_L(i, j, L) *
1226 ((
1227
1228 t_dT(i, j, k, l)
1229
1230 +
1231
1232 (alphaU * ts_a) * (t_D(i, j, m, n) * t_diff(m, n, k, l)
1233
1234 )) *
1235 t_L(k, l, J));
1236
1237 // Work of symmetric tensor on undefined tensor is equal to the work
1238 // of the symmetric part of it
1242 t_sym(i, j) = (t_approx_P_adjoint__dstretch(i, j) ||
1243 t_approx_P_adjoint__dstretch(j, i));
1244 t_sym(i, j) /= 2.0;
1245 auto t_diff2_uP2 = EigenMatrix::getDiffDiffMat(
1246 t_eigen_vals, t_eigen_vecs, EshelbianCore::f, EshelbianCore::d_f,
1247 EshelbianCore::dd_f, t_sym, nbUniq[gg]);
1248 t_dP(L, J) += t_L(i, j, L) *
1249 ((t_diff2_uP2(i, j, k, l) + t_diff2_uP2(k, l, i, j)) *
1250 t_L(k, l, J)) /
1251 2.;
1252 }
1253
1254 ++t_dP;
1255 ++t_approx_P_adjoint__dstretch;
1256 ++t_log_stretch_h1;
1257 ++t_eigen_vals;
1258 ++t_eigen_vecs;
1259 }
1260
1261 return get_stress();
1262 };
1263
1264 auto t_dP = get_dP();
1265 for (int gg = 0; gg != nb_integration_pts; ++gg) {
1266 double a = v * t_w;
1267
1268 int rr = 0;
1269 for (; rr != row_nb_dofs / 6; ++rr) {
1270 auto t_col_base_fun = col_data.getFTensor0N(gg, 0);
1271 auto t_m = get_ftensor2(K, 6 * rr, 0);
1272 for (int cc = 0; cc != col_nb_dofs / 6; ++cc) {
1273 const double b = a * t_row_base_fun * t_col_base_fun;
1274 t_m(L, J) -= b * t_dP(L, J);
1275 ++t_m;
1276 ++t_col_base_fun;
1277 }
1278 ++t_row_base_fun;
1279 }
1280
1281 for (; rr != row_nb_base_functions; ++rr) {
1282 ++t_row_base_fun;
1283 }
1284
1285 ++t_w;
1286 ++t_dP;
1287 }
1289}
1290
1291template <int STRIDEMATD>
1293 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
1294 boost::shared_ptr<double> total_energy_ptr)
1295 : VolUserDataOperator(NOSPACE, OPSPACE), dataAtPts(data_ptr),
1296 totalEnergyPtr(total_energy_ptr) {
1297
1298 if (!dataAtPts) {
1300 "dataAtPts is not allocated. Please set it before "
1301 "using this operator.");
1302 }
1303}
1304
1305template <int STRIDEMATD>
1307 EntityType type,
1308 EntData &data) {
1310
1315
1316 int nb_integration_pts = getGaussPts().size2();
1317 auto t_log_u = dataAtPts->getFTensorLogStretchTotal(nb_integration_pts);
1318
1319#ifndef NDEBUG
1320 auto &mat_d = dataAtPts->matD;
1321 if (mat_d.size2() != size_symm * size_symm) {
1322 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1323 "wrong matD size, number of columns should be %d but is %zu",
1324 size_symm * size_symm, mat_d.size2());
1325 }
1326 if constexpr (STRIDEMATD != 0) {
1327 if (mat_d.size1() != nb_integration_pts) {
1328 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1329 "wrong matD size, number of rows should be %d but is %zu",
1330 nb_integration_pts, mat_d.size1());
1331 }
1332 }
1333#endif
1334
1335 auto t_D = getFTensor4DdgFromMat<3, 3, STRIDEMATD>(dataAtPts->matD);
1336
1337 dataAtPts->energyAtPts.resize(nb_integration_pts, false);
1338 auto t_energy = getFTensor0FromVec(dataAtPts->energyAtPts);
1339
1340 for (auto gg = 0; gg != nb_integration_pts; ++gg) {
1341
1342 t_energy = 0.5 * (t_log_u(i, j) * (t_D(i, j, k, l) * t_log_u(k, l)));
1343
1344 ++t_D;
1345 ++t_log_u;
1346 ++t_energy;
1347 }
1348
1349 if (totalEnergyPtr) {
1350 auto t_w = getFTensor0IntegrationWeight();
1351 auto t_energy = getFTensor0FromVec(dataAtPts->energyAtPts);
1352 double loc_energy = 0;
1353 for (auto gg = 0; gg != nb_integration_pts; ++gg) {
1354 loc_energy += t_energy * t_w;
1355 ++t_w;
1356 ++t_energy;
1357 }
1358 *totalEnergyPtr += getMeasure() * loc_energy;
1359 }
1360
1362}
1363
1364template <int STRIDEMATD>
1367 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
1368 boost::shared_ptr<MatrixDouble> strain_ptr,
1369 boost::shared_ptr<MatrixDouble> stress_ptr,
1370 boost::shared_ptr<HMHHencky> hencky_ptr)
1371 : VolUserDataOperator(H1, OPLAST), dataAtPts(data_ptr),
1372 strainPtr(strain_ptr), stressPtr(stress_ptr), henckyPtr(hencky_ptr) {
1373 std::fill(&doEntities[MBVERTEX], &doEntities[MBMAXTYPE], false);
1374 doEntities[MBVERTEX] = true;
1375}
1376
1377template <int STRIDEMATD>
1379 int side, EntityType type, EntData &data) {
1381
1388
1389 auto nb_integration_pts = stressPtr->size1();
1390#ifndef NDEBUG
1391 if (nb_integration_pts != getGaussPts().size2()) {
1392 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
1393 "inconsistent number of integration points");
1394 }
1395#endif // NDEBUG
1396
1397 CHKERR henckyPtr->computeMaterialParamsAtPts<STRIDEMATD>(this, data,
1398 dataAtPts);
1399
1400 auto get_strain =
1401 MatrixSizeHelper<GetFTensor2SymmetricFromMatType<3, -1, DL>, DL>::size(
1402 *strainPtr, nb_integration_pts);
1403 auto t_strain = get_strain();
1404 auto t_stress = getFTensor2FromMat<SPACE_DIM, SPACE_DIM, -1, DL>(*stressPtr);
1405 auto t_inv_D = getFTensor4DdgFromMat<SPACE_DIM, SPACE_DIM, STRIDEMATD>(
1406 dataAtPts->matInvD);
1407#ifndef NDEBUG
1408 auto t_D =
1409 getFTensor4DdgFromMat<SPACE_DIM, SPACE_DIM, STRIDEMATD>(dataAtPts->matD);
1410#endif
1411
1413
1414 // note: add rotation, so we can extract rigid body motion, work then with
1415 // symmetric part.
1416 for (auto gg = 0; gg != nb_integration_pts; ++gg) {
1417 t_strain(i, j) = t_inv_D(i, j, k, l) * t_stress(k, l);
1418
1419#ifndef NDEBUG
1420 FTensor::Tensor2_symmetric<double, 3> t_stress_symm_debug;
1421 t_stress_symm_debug(i, j) = (t_stress(i, j) || t_stress(j, i)) / 2;
1422 FTensor::Tensor2_symmetric<double, 3> t_stress_symm_debug_diff;
1423 t_stress_symm_debug_diff(i, j) =
1424 t_D(i, j, k, l) * t_strain(k, l) - t_stress_symm_debug(i, j);
1425 double nrm =
1426 t_stress_symm_debug_diff(i, j) * t_stress_symm_debug_diff(i, j);
1427 double nrm0 = t_stress_symm_debug(i, j) * t_stress_symm_debug(i, j) +
1428 std::numeric_limits<double>::epsilon();
1429 constexpr double eps = 1e-10;
1430 if (std::fabs(std::sqrt(nrm / nrm0)) > eps) {
1431 MOFEM_LOG("SELF", Sev::error)
1432 << "Stress symmetry check failed: " << std::endl
1433 << t_stress_symm_debug_diff << std::endl
1434 << t_stress;
1436 "Norm is too big: " + std::to_string(nrm / nrm0));
1437 }
1438 ++t_D;
1439#endif
1440
1441 ++t_strain;
1442 ++t_stress;
1443 ++t_inv_D;
1444 }
1445
1447}
1448
1449template <typename OP_PTR>
1450std::tuple<std::string, VectorDouble>
1452 const std::string block_name) {
1453
1454 auto nb_gauss_pts = op_ptr->getGaussPts().size2();
1455
1456 auto ts_time = op_ptr->getTStime();
1457 auto ts_time_step = op_ptr->getTStimeStep();
1460 ts_time_step = EshelbianCore::physicalDt;
1461 }
1462
1463 MatrixDouble m_ref_coords = op_ptr->getCoordsAtGaussPts();
1464
1465 auto v_analytical_expr = analytical_externalstrain_function(
1466 ts_time_step, ts_time, nb_gauss_pts, m_ref_coords, block_name);
1467
1468#ifndef NDEBUG
1469 if (v_analytical_expr.size() != nb_gauss_pts)
1471 "Wrong number of integration pts");
1472#endif // NDEBUG
1473
1474 return std::make_tuple(block_name, v_analytical_expr);
1475};
1476
1477template <typename OP_PTR>
1478VectorDouble getAnalyticalElastic(OP_PTR op_ptr, const std::string block_name) {
1479
1480 auto nb_gauss_pts = op_ptr->getGaussPts().size2();
1481
1482 auto ts_time = op_ptr->getTStime();
1483 auto ts_time_step = op_ptr->getTStimeStep();
1484
1487 ts_time_step = EshelbianCore::physicalStepNumber;
1488 }
1489
1490 MatrixDouble m_ref_coords = op_ptr->getCoordsAtGaussPts();
1491
1492 auto v_analytical_expr = analytical_elastic_function(
1493 ts_time_step, ts_time, nb_gauss_pts, m_ref_coords, block_name);
1494
1495#ifndef NDEBUG
1496 if (v_analytical_expr.size() != nb_gauss_pts)
1498 "Wrong number of integration pts");
1499#endif // NDEBUG
1500
1501 return v_analytical_expr;
1502}
1503
1504// Topo
1505
1507 const std::string &field_name,
1508 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
1509 SmartPetscObj<Vec> assemble_vec,
1510 boost::shared_ptr<TopologicalData> topo_ptr, const double alpha_u,
1511 boost::shared_ptr<double> J_ptr)
1512 : OpAssembleVolume(field_name, data_ptr, OPROW), alphaU(alpha_u),
1513 JPtr(J_ptr), topoDataPtr(topo_ptr), assembleVec(assemble_vec) {
1514
1515 CHK_MOAB_THROW(PetscOptionsGetBool(PETSC_NULLPTR, "", "-poly_convex",
1516 &polyConvex, PETSC_NULLPTR),
1517 "get polyconvex option failed");
1518}
1519
1522 if (polyConvex) {
1523 CHKERR integratePolyconvexHencky(data);
1524 } else {
1525 CHKERR integrateHencky(data);
1526 }
1528}
1529
1530MoFEMErrorCode
1533
1534 FTensor::Index<'L', size_symm> L;
1535 auto t_L = symm_L_tensor();
1536
1537 int nb_dofs = data.getIndices().size();
1538 int nb_integration_pts = data.getN().size1();
1539 auto v = getVolume();
1540
1541 FTENSOR_INDEXES(SPACE_DIM, i, j, k, l, I, J);
1542
1543 auto get_ftensor1 = [](auto &v) {
1545 &v[0], &v[1], &v[2]);
1546 };
1547
1548 locJ = 0;
1549 int nb_base_functions = data.getN().size2();
1550
1551 auto integrate = [&](auto t_D) {
1553
1554 auto t_w = getFTensor0IntegrationWeight();
1555 auto t_det = topoDataPtr->getFTensorDetJacobian(nb_integration_pts);
1556 auto t_inv_jac = topoDataPtr->getFTensorInvJacobian(nb_integration_pts);
1557
1558 auto t_var_log_u = dataAtPts->getFTensorVarLogStreach(nb_integration_pts);
1559 auto t_approx_P = dataAtPts->getFTensorApproxP(nb_integration_pts);
1560 auto t_approx_P_adjoint_log_du =
1561 dataAtPts->getFTensorAdjointPdU(nb_integration_pts);
1562 auto t_h_dlog_u =
1563 dataAtPts->getFTensorSmallHdLogStretch(nb_integration_pts);
1564 auto t_log_stretch_h1 =
1565 dataAtPts->getFTensorLogStretchTotal(nb_integration_pts);
1566
1567 // Swithc off rate effects for now, as we don't have the dot_log_u at the
1568 // pts; we would need to compute it from the solution, which is not
1569 // straightforward
1570 // auto t_dot_log_u =
1571 // dataAtPts->getFTensorLogStretchDot(nb_integration_pts);
1572
1573 auto t_diff_base = data.getFTensor1DiffN<SPACE_DIM>();
1574 for (int gg = 0; gg != nb_integration_pts; ++gg) {
1575 const double a = v * t_w;
1576
1578 t_T(i, j) = t_D(i, j, k, l) *
1579 (t_log_stretch_h1(k, l) /*+ alphaU * t_dot_log_u(k, l)*/);
1580
1581 FTensor::Tensor1<double, size_symm> t_stress_residual;
1582 t_stress_residual(L) = t_L(i, j, L) * t_T(i, j);
1583
1585 t_residual(L) = t_approx_P_adjoint_log_du(L) - t_stress_residual(L);
1586
1587 locJ -= (a * t_det) * t_residual(L) * t_var_log_u(L);
1588
1590 t_cof(I, J) = t_det * t_inv_jac(J, I);
1591
1592 const double var_stress_residual = t_var_log_u(L) * t_stress_residual(L);
1593
1594 // detJ cancels the 1 / detJ from the Piola transform; the remaining
1595 // derivative is from J(k, n) * P(i, n).
1597 t_approx_P_adjoint_log_du_dX;
1598 t_approx_P_adjoint_log_du_dX(L, I, J) =
1599 t_h_dlog_u(i, I, L) * t_approx_P(i, J);
1600
1602 t_residual_dX(I, J) =
1603 t_var_log_u(L) * t_approx_P_adjoint_log_du_dX(L, I, J) -
1604 var_stress_residual * t_cof(I, J);
1605
1606 auto t_nf = get_ftensor1(nF);
1607 int bb = 0;
1608 for (; bb != nb_dofs / SPACE_DIM; ++bb) {
1609 t_nf(i) -= a * t_residual_dX(i, j) * t_diff_base(j);
1610 ++t_nf;
1611 ++t_diff_base;
1612 }
1613 for (; bb != nb_base_functions; ++bb)
1614 ++t_diff_base;
1615
1616 ++t_w;
1617 ++t_det;
1618 ++t_inv_jac;
1619 ++t_var_log_u;
1620 ++t_approx_P;
1621 ++t_approx_P_adjoint_log_du;
1622 ++t_h_dlog_u;
1623 ++t_log_stretch_h1;
1624 // ++t_dot_log_u;
1625 ++t_D;
1626 }
1628 };
1629
1631 CHKERR integrate(
1632 getFTensor4DdgFromMat<SPACE_DIM, SPACE_DIM, 0>(dataAtPts->matD));
1633 } else {
1634 CHKERR integrate(
1635 getFTensor4DdgFromMat<SPACE_DIM, SPACE_DIM>(dataAtPts->matD));
1636 }
1637
1639}
1640
1641MoFEMErrorCode
1644 SETERRQ(PETSC_COMM_SELF, MOFEM_NOT_IMPLEMENTED,
1645 "Polyconvex Hencky is not implemented yet");
1647}
1648
1650 EntityType row_type,
1651 EntData &data) {
1653 if (assembleVec) {
1654 double *vec_ptr = nF.data().data();
1655 const int nb_dofs = data.getIndices().size();
1656 int *ind_ptr = data.getIndices().data().data();
1657 CHKERR VecSetValues(assembleVec, nb_dofs, ind_ptr, vec_ptr, ADD_VALUES);
1658 }
1659 if (row_type == MBVERTEX) {
1660 if (JPtr) {
1661 *JPtr += locJ;
1662 }
1663 }
1665}
1666
1667} // 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
Kronecker Delta class symmetric.
@ 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
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)
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
VectorDouble getAnalyticalElastic(OP_PTR op_ptr, const std::string block_name)
static constexpr auto size_symm
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:38
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
Definition HMHHencky.cpp:29
boost::shared_ptr< DataAtIntegrationPts > dataAtGaussPts
Definition HMHHencky.cpp:41
OpHenckyJacobian(boost::shared_ptr< DataAtIntegrationPts > data_ptr, boost::shared_ptr< HMHHencky > hencky_ptr)
Definition HMHHencky.cpp:21
MoFEMErrorCode evaluateRhs(EntData &data)
Definition HMHHencky.cpp:37
boost::shared_ptr< HMHHencky > henckyPtr
Definition HMHHencky.cpp:42
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)
Definition HMHHencky.cpp:94
VolUserDataOperator * returnOpCalculateStretchFromStress(boost::shared_ptr< DataAtIntegrationPts > data_ptr, boost::shared_ptr< PhysicalEquations > physics_ptr)
MoFEMErrorCode extractBlockData(Sev sev)
std::vector< BlockData > blockData
static constexpr int StrideMatD
Definition HMHHencky.cpp:17
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:14
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 * 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:46
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