v0.16.3
Loading...
Searching...
No Matches
MatUmatImpl.hpp
Go to the documentation of this file.
1/**
2 * @file MatUmatImpl.hpp
3 * @brief Shared UMAT implementation details for built-in and user-defined UMATs.
4 */
5
6#ifndef MAT_UMAT_IMPL_HPP
7#define MAT_UMAT_IMPL_HPP
8
9#include <MoFEM.hpp>
10
11#include "MatOps.hpp"
12#include "MatUmat.hpp"
13#include <sstream>
14#include <UmatInterface.hpp>
15
16namespace MatOps {
17
18using namespace MoFEM;
19
20inline int umatTensorIndex(const int ii, const int jj) { return 3 * ii + jj; }
21
23
24template <int DIM, int MODEL_TYPE>
25struct SmallStrainHandler : public StrainHandler<DIM, MODEL_TYPE> {
26
28
30 EntityHandle entity, int gg) override {
32 if (!matUmatImpl.umatInterfacePtr) {
33 SETERRQ(PETSC_COMM_SELF, MOFEM_OPERATION_UNSUCCESSFUL,
34 "UMAT interface is not initialised");
35 }
36 auto &umat = *matUmatImpl.umatInterfacePtr;
37 umat.props = matUmatImpl.currentMaterialParameters;
38 umat.noel = static_cast<int>(entity);
39 umat.npt = gg + 1;
40 CHKERR umat.setTimeData(matUmatImpl.currentTime,
41 matUmatImpl.currentTimeIncrement);
42 CHKERR matUmatImpl.loadPreviousDeformationGradient(entity, gg);
43 CHKERR matUmatImpl.loadPreviousStress(entity, gg);
44 CHKERR matUmatImpl.loadPreviousStateVariables(entity, gg);
45 CHKERR umat.setDeformationGradient(
46 *matUmatImpl.matOpsDataPtr->getActiveDataPtr("F"),
47 matUmatImpl.useDeformationGradient);
48 CHKERR umat.setIdentityRotationIncrement();
49 CHKERR umat.setStrainIncrementFromDeformationGradient();
50 CHKERR matUmatImpl.loadCoordinates(entity, gg);
51 CHKERR matUmatImpl.loadPredef(entity, gg);
52
53 CHKERR umat.callUmat();
55 }
56
59 boost::shared_ptr<MatOpsData> mat_ops_data_ptr) override {
61 auto &umat = *matUmatImpl.umatInterfacePtr;
62 auto set_stress_from_umat_cauchy = [&]() {
64
65 auto t_P = getFTensor2FromPtr<DIM, DIM>(
66 mat_ops_data_ptr->getDependentDataPtr("P")->data().data());
67
68 MatrixDouble sigma;
69 CHKERR umat.getCauchyStressTensor(sigma);
70
71 for (int i = 0; i != DIM; ++i)
72 for (int Jidx = 0; Jidx != DIM; ++Jidx)
73 t_P(i, Jidx) = sigma(i, Jidx);
74
76 };
77
78 CHKERR set_stress_from_umat_cauchy();
80 }
81
84 boost::shared_ptr<MatOpsData> mat_ops_data_ptr) override {
86 auto &umat = *matUmatImpl.umatInterfacePtr;
87 auto set_tangent_from_umat_cauchy = [&]() {
89
90 auto t_dP = getFTensor4FromPtr<DIM, DIM, DIM, DIM>(
91 mat_ops_data_ptr->getDependentDerivativesDataPtr("P_dF")
92 ->data()
93 .data());
94
95 MatrixDouble d_sigma_d_eps;
96 CHKERR umat.getCauchyTangentTensor(d_sigma_d_eps);
97
98 for (int i = 0; i != DIM; ++i)
99 for (int Jidx = 0; Jidx != DIM; ++Jidx)
100 for (int m = 0; m != DIM; ++m)
101 for (int N = 0; N != DIM; ++N)
102 t_dP(i, Jidx, m, N) = d_sigma_d_eps(umatTensorIndex(i, Jidx),
104
106 };
107
108 CHKERR set_tangent_from_umat_cauchy();
110 }
111};
112
113template <int DIM, int MODEL_TYPE>
114struct HenckyStrainHandler : public StrainHandler<DIM, MODEL_TYPE> {
115
117
119 EntityHandle entity, int gg) override {
121 (void)matUmatImpl;
122 (void)entity;
123 (void)gg;
125 }
126
129 boost::shared_ptr<MatOpsData> mat_ops_data_ptr) override {
131 (void)matUmatImpl;
132 (void)mat_ops_data_ptr;
134 }
135
138 boost::shared_ptr<MatOpsData> mat_ops_data_ptr) override {
140 (void)matUmatImpl;
141 (void)mat_ops_data_ptr;
143 }
144};
145
146template <int DIM, int MODEL_TYPE>
147struct FiniteStrainHandler : public StrainHandler<DIM, MODEL_TYPE> {
148
150
152 EntityHandle entity, int gg) override {
154 (void)matUmatImpl;
155 (void)entity;
156 (void)gg;
158 }
159
162 boost::shared_ptr<MatOpsData> mat_ops_data_ptr) override {
164 (void)matUmatImpl;
165 (void)mat_ops_data_ptr;
167 }
168
171 boost::shared_ptr<MatOpsData> mat_ops_data_ptr) override {
173 (void)matUmatImpl;
174 (void)mat_ops_data_ptr;
176 }
177};
178
179template <int DIM, int MODEL_TYPE>
181 using MatPiolaResponse::MatPiolaResponse;
184 static constexpr auto DFGRD0_TAG_NAME = "UMAT_DFGRD0";
185 static constexpr auto STRESS_TAG_NAME = "UMAT_STRESS";
186 static constexpr char STATEV_TAG_NAME[] = "UMAT_STATEV";
187
188 static std::string getStateVariableTagName(const int index) {
189 std::string tag_name(STATEV_TAG_NAME, sizeof(STATEV_TAG_NAME) - 1);
190 tag_name += '_';
191 tag_name += std::to_string(index);
192 return tag_name;
193 }
194
196 createOp(boost::shared_ptr<PhysicalEquations> physical_ptr, bool eval_stress,
197 bool eval_tangent, bool update) override;
198
199 MoFEMErrorCode getOptions(MoFEM::Interface *m_field_ptr = nullptr) override {
201
202 mField = m_field_ptr;
203
204 MOFEM_LOG_CHANNEL("WORLD");
205
206 char umat_library[PETSC_MAX_PATH_LEN] = "./umat.so";
207 char umat_name[80] = "UMAT";
208 PetscInt nstatev = 0;
209 PetscInt nprops = 2;
210 const char *list_strain_type[] = {"small", "hencky", "finite"};
211 PetscInt choice_strain = StrainType::SMALL;
212 PetscOptionsBegin(PETSC_COMM_WORLD, "umat_", "", "none");
213 CHKERR PetscOptionsString("-library", "Path to UMAT shared library", "",
214 umat_library, umat_library, sizeof(umat_library),
215 PETSC_NULLPTR);
216 CHKERR PetscOptionsString("-name", "UMAT material name", "", umat_name,
217 umat_name, sizeof(umat_name), PETSC_NULLPTR);
218 CHKERR PetscOptionsInt("-nstatev", "Number of UMAT state variables", "",
219 nstatev, &nstatev, PETSC_NULLPTR);
220 CHKERR PetscOptionsInt("-nprops", "Number of UMAT material properties", "",
221 nprops, &nprops, PETSC_NULLPTR);
222 CHKERR PetscOptionsScalar("-young_modulus", "Default first property", "",
223 youngModulus, &youngModulus, PETSC_NULLPTR);
224 CHKERR PetscOptionsScalar("-poisson_ratio", "Default second property", "",
225 poissonRatio, &poissonRatio, PETSC_NULLPTR);
226 CHKERR PetscOptionsEList(
227 "-strain_type", "Strain type", "", list_strain_type, 3,
228 list_strain_type[choice_strain], &choice_strain, PETSC_NULLPTR);
229 PetscOptionsEnd();
230
231 strainType = static_cast<StrainType>(choice_strain);
232
233 switch (strainType) {
234 case SMALL:
235 strainHandler = std::make_unique<SmallStrainHandler<DIM, MODEL_TYPE>>();
236 break;
237 case HENCKY:
238 strainHandler = std::make_unique<HenckyStrainHandler<DIM, MODEL_TYPE>>();
239 break;
240 case FINITE:
241 strainHandler = std::make_unique<FiniteStrainHandler<DIM, MODEL_TYPE>>();
242 break;
243 default:
244 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
245 "Unsupported UMAT strain type");
246 }
247
248 if (nprops <= 0) {
249 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
250 "UMAT requires a positive number of properties");
251 }
252
253 if (nstatev < 0) {
254 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
255 "UMAT requires a non-negative number of state variables");
256 }
257
258 numberStateVariables = static_cast<int>(nstatev);
259 stateVar.resize(numberStateVariables, 0.0);
261 for (int ii = 0; ii != numberStateVariables; ++ii) {
263 }
264 numberMaterialProperties = static_cast<int>(nprops);
265 materialName = umat_name;
266 libraryPath = umat_library;
267
273
274 MOFEM_TAG_AND_LOG("WORLD", Sev::inform, "Default Umat parameters:")
275 << " umat_library = " << libraryPath << " name = " << materialName
276 << " umat_nstatev = " << numberStateVariables
277 << " umat_nprops = " << numberMaterialProperties;
278
279 std::string block_name = "MAT_UMAT";
280 for (auto &m :
281 m_field_ptr->getInterface<MeshsetsManager>()->getCubitMeshsetPtr(
282 std::regex((boost::format("%s(.*)") % block_name).str()))) {
283 std::vector<double> block_data;
284 CHKERR m->getAttributes(block_data);
285 if ((int)block_data.size() < numberMaterialProperties) {
286 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
287 "MAT_UMAT block requires at least %d attributes", nprops);
288 }
289
290 auto get_block_ents = [&]() {
291 Range ents;
292 CHK_MOAB_THROW(m_field_ptr->get_moab().get_entities_by_handle(
293 m->meshset, ents, true),
294 "can not get block entities");
295 return ents;
296 };
297
298 A::paramVecByRange.push_back(
299 {get_block_ents(),
300 std::vector<double>(block_data.begin(),
301 block_data.begin() + numberMaterialProperties)});
302
303 std::ostringstream properties_stream;
304 properties_stream << "[";
305 for (int ii = 0; ii != numberMaterialProperties; ++ii) {
306 if (ii)
307 properties_stream << ", ";
308 properties_stream << block_data[ii];
309 }
310 properties_stream << "]";
311
312 MOFEM_TAG_AND_LOG("WORLD", Sev::inform, "MatBlock for Umat")
313 << *m << " properties = " << properties_stream.str();
314 }
315
316 umatInterfacePtr = std::make_unique<UmatInterfaceType>(
319
320 if (m_field_ptr) {
321 CHKERR A::matOpsDataPtr->bindStateTag(*m_field_ptr, DFGRD0_TAG_NAME,
322 DIM * DIM);
323 CHKERR A::matOpsDataPtr->bindStateTag(*m_field_ptr, STRESS_TAG_NAME,
325 if (numberStateVariables > 0) {
326 for (int ii = 0; ii != numberStateVariables; ++ii) {
327 CHKERR A::matOpsDataPtr->bindStateTag(*m_field_ptr,
329 }
330 }
331 CHKERR bindAuxiliaryStateTags(*m_field_ptr);
332 CHKERR A::matOpsDataPtr->setupStateData();
333 }
334
336 }
337
338 MoFEMErrorCode setParams(FEMethod *fe_ptr, int gg) override {
340 (void)gg;
341 currentTimeStep = fe_ptr->ts_step;
342 currentTime = fe_ptr->ts_t;
343 currentTimeIncrement = fe_ptr->ts_dt;
344 const auto ent = fe_ptr->getFEEntityHandle();
346 for (auto &[range, param_vec] : A::paramVecByRange) {
347 if (range.find(ent) != range.end()) {
348 currentMaterialParameters = param_vec;
349 break;
350 }
351 }
353 }
354
357
358 A::matOpsDataPtr->insertCommonData("grad", MatrixDouble());
359 A::matOpsDataPtr->insertCommonData("P", MatrixDouble());
360 A::matOpsDataPtr->insertCommonData("P_dF", MatrixDouble());
361
362 A::matOpsDataPtr->insertActiveData("F", MatrixDouble());
363 A::matOpsDataPtr->insertDependentData("P", MatrixDouble());
364 A::matOpsDataPtr->insertDependentDerivativesData("P_dF", MatrixDouble());
365
366 A::matOpsDataPtr->getActiveDataPtr("F")->resize(DIM, DIM, false);
367 A::matOpsDataPtr->getDependentDataPtr("P")->resize(DIM, DIM, false);
368 A::matOpsDataPtr->getDependentDerivativesDataPtr("P_dF")->resize(
369 DIM * DIM, DIM * DIM, false);
370
372
374 }
375
376 MoFEMErrorCode evaluateVariable(int, EntityHandle entity, int gg) override {
378 CHKERR strainHandler->runUmat(*this, entity, gg);
379 CHKERR strainHandler->convertStress(*this, A::matOpsDataPtr);
381 }
382
383 MoFEMErrorCode evaluateDerivatives(int, EntityHandle entity,
384 int gg) override {
386 CHKERR strainHandler->runUmat(*this, entity, gg);
387 CHKERR strainHandler->convertTangent(*this, A::matOpsDataPtr);
389 }
390
391 MoFEMErrorCode updateState(int, EntityHandle entity, int gg) override {
393 CHKERR strainHandler->runUmat(*this, entity, gg);
395 CHKERR storeCurrentStress(entity, gg);
398 }
399
400protected:
406
411
412 // TODO: Populate UMAT COORDS from integration-point coordinates when needed.
413 // The default keeps COORDS zero; coordinate-dependent UMATs should override it.
414 virtual MoFEMErrorCode loadCoordinates(EntityHandle entity, int gg) {
416 (void)entity;
417 (void)gg;
418 for (int dd = 0; dd != 3; ++dd)
419 umatInterfacePtr->coords[dd] = 0.0;
421 }
422
423 virtual MoFEMErrorCode loadPredef(EntityHandle entity, int gg) {
425 (void)entity;
426 (void)gg;
427 if (umatInterfacePtr->predef.empty()) {
428 umatInterfacePtr->predef.push_back(0.0);
429 }
430 if (umatInterfacePtr->dpred.empty()) {
431 umatInterfacePtr->dpred.push_back(0.0);
432 }
433 std::fill(umatInterfacePtr->predef.begin(), umatInterfacePtr->predef.end(),
434 0.0);
435 std::fill(umatInterfacePtr->dpred.begin(), umatInterfacePtr->dpred.end(),
436 0.0);
438 }
439
440 MoFEMErrorCode loadPreviousDeformationGradient(EntityHandle entity, int gg) {
442
443 CHKERR umatInterfacePtr->setIdentityDeformationGradient();
444
445 auto state_ptr =
446 A::matOpsDataPtr->getStateDataPtr(DFGRD0_TAG_NAME, entity, gg);
447 bool has_stored_gradient = false;
448 for (int row = 0; row != DIM; ++row) {
449 for (int col = 0; col != DIM; ++col) {
450 const double value = (*state_ptr)(row * DIM + col, 0);
451 umatInterfacePtr->dfgrd0[row + 3 * col] = value;
452 has_stored_gradient = has_stored_gradient || std::abs(value) > 0;
453 }
454 }
455
456 if (!has_stored_gradient) {
457 CHKERR umatInterfacePtr->setIdentityDeformationGradient();
458 }
459
461 }
462
463 MoFEMErrorCode storeCurrentDeformationGradient(EntityHandle entity, int gg) {
465
466 auto state_ptr =
467 A::matOpsDataPtr->getStateDataPtr(DFGRD0_TAG_NAME, entity, gg);
468 for (int row = 0; row != DIM; ++row) {
469 for (int col = 0; col != DIM; ++col) {
470 (*state_ptr)(row *DIM + col, 0) =
471 umatInterfacePtr->dfgrd1[row + 3 * col];
472 }
473 }
474
476 }
477
478 MoFEMErrorCode loadPreviousStress(EntityHandle entity, int gg) {
480
481 auto state_ptr =
482 A::matOpsDataPtr->getStateDataPtr(STRESS_TAG_NAME, entity, gg);
483 for (int ii = 0; ii != UmatInterfaceType::NTENS; ++ii) {
484 umatInterfacePtr->stress[ii] = (*state_ptr)(ii, 0);
485 }
486
488 }
489
490 MoFEMErrorCode loadPreviousStateVariables(EntityHandle entity, int gg) {
492
493 umatInterfacePtr->statev.assign(numberStateVariables, -1);
496 }
497
498 for (int ii = 0; ii != numberStateVariables; ++ii) {
499 auto state_ptr = A::matOpsDataPtr->getStateDataPtr(
500 vStateVariableTagNames[ii], entity, gg);
501 umatInterfacePtr->statev[ii] = (*state_ptr)(0, 0);
502 }
503
505 }
506
507 MoFEMErrorCode storeCurrentStress(EntityHandle entity, int gg) {
509
510 auto state_ptr =
511 A::matOpsDataPtr->getStateDataPtr(STRESS_TAG_NAME, entity, gg);
512 for (int ii = 0; ii != UmatInterfaceType::NTENS; ++ii) {
513 (*state_ptr)(ii, 0) = umatInterfacePtr->stress[ii];
514 }
515
517 }
518
519 MoFEMErrorCode storeCurrentStateVariables(EntityHandle entity, int gg) {
521
524 }
525
526 for (int ii = 0; ii != numberStateVariables; ++ii) {
527 auto state_ptr = A::matOpsDataPtr->getStateDataPtr(
528 vStateVariableTagNames[ii], entity, gg);
529 (*state_ptr)(0, 0) = umatInterfacePtr->statev[ii];
530 }
531
533 }
534
536 std::unique_ptr<UmatInterfaceType> umatInterfacePtr;
537 std::string libraryPath = "./umat.so";
538 std::string materialName = "UMAT";
540 PetscInt currentTimeStep = 0;
541 PetscReal currentTime = 0;
542 PetscReal currentTimeIncrement = 0;
543 double youngModulus = 1.0;
544 double poissonRatio = 0.3;
549 std::vector<double> stateVar = std::vector<double>(numberStateVariables, 0.0);
550 std::vector<std::string> vStateVariableTagNames;
551 friend struct SmallStrainHandler<DIM, MODEL_TYPE>;
552 friend struct HenckyStrainHandler<DIM, MODEL_TYPE>;
553 friend struct FiniteStrainHandler<DIM, MODEL_TYPE>;
554 std::unique_ptr<StrainHandler<DIM, MODEL_TYPE>> strainHandler;
555};
556
557} // namespace MatOps
558
559#endif // MAT_UMAT_IMPL_HPP
#define MOFEM_TAG_AND_LOG(channel, severity, tag)
Tag and log in channel.
UmatInterface.
#define MoFEMFunctionReturnHot(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
#define CHK_MOAB_THROW(err, msg)
Check error code of MoAB function and throw MoFEM exception.
@ MOFEM_OPERATION_UNSUCCESSFUL
Definition definitions.h:34
@ 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.
#define MoFEMFunctionBeginHot
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
#define MOFEM_LOG_CHANNEL(channel)
Set and reset channel.
FTensor::Index< 'i', SPACE_DIM > i
int umatTensorIndex(const int ii, const int jj)
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
UBlasMatrix< double > MatrixDouble
Definition Types.hpp:77
implementation of Data Operators for Forces and Sources
Definition Common.hpp:10
FTensor::Index< 'm', 3 > m
const int N
Definition speed_test.cpp:3
MoFEMErrorCode runUmat(MatUmatImpl< DIM, MODEL_TYPE > &matUmatImpl, EntityHandle entity, int gg) override
MoFEMErrorCode convertTangent(MatUmatImpl< DIM, MODEL_TYPE > &matUmatImpl, boost::shared_ptr< MatOpsData > mat_ops_data_ptr) override
MoFEMErrorCode convertStress(MatUmatImpl< DIM, MODEL_TYPE > &matUmatImpl, boost::shared_ptr< MatOpsData > mat_ops_data_ptr) override
MoFEMErrorCode convertTangent(MatUmatImpl< DIM, MODEL_TYPE > &matUmatImpl, boost::shared_ptr< MatOpsData > mat_ops_data_ptr) override
MoFEMErrorCode runUmat(MatUmatImpl< DIM, MODEL_TYPE > &matUmatImpl, EntityHandle entity, int gg) override
MoFEMErrorCode convertStress(MatUmatImpl< DIM, MODEL_TYPE > &matUmatImpl, boost::shared_ptr< MatOpsData > mat_ops_data_ptr) override
Constitutive response expressed by first Piola stress.
Definition MatOps.hpp:186
static bool useDeformationGradient
Otherwise the displacement gradient is supplied and I is added.
Definition MatOps.hpp:189
MoFEMErrorCode storeCurrentDeformationGradient(EntityHandle entity, int gg)
MoFEMErrorCode loadPreviousStress(EntityHandle entity, int gg)
MoFEMErrorCode storeCurrentStress(EntityHandle entity, int gg)
static constexpr auto STRESS_TAG_NAME
static std::string getStateVariableTagName(const int index)
MoFEMErrorCode getOptions(MoFEM::Interface *m_field_ptr=nullptr) override
virtual MoFEMErrorCode recordAuxiliaryMatOpsData()
virtual MoFEMErrorCode loadPredef(EntityHandle entity, int gg)
ForcesAndSourcesCore::UserDataOperator * createOp(boost::shared_ptr< PhysicalEquations > physical_ptr, bool eval_stress, bool eval_tangent, bool update) override
Definition MatUmat.cpp:21
std::vector< double > defaultMaterialParameters
MoFEMErrorCode recordTape() override
std::vector< double > currentMaterialParameters
std::unique_ptr< UmatInterfaceType > umatInterfacePtr
MoFEMErrorCode storeCurrentStateVariables(EntityHandle entity, int gg)
MoFEMErrorCode setParams(FEMethod *fe_ptr, int gg) override
std::vector< std::string > vStateVariableTagNames
std::string materialName
MoFEMErrorCode evaluateVariable(int, EntityHandle entity, int gg) override
static constexpr auto DFGRD0_TAG_NAME
virtual MoFEMErrorCode loadCoordinates(EntityHandle entity, int gg)
MoFEMErrorCode updateState(int, EntityHandle entity, int gg) override
std::string libraryPath
static constexpr char STATEV_TAG_NAME[]
std::unique_ptr< StrainHandler< DIM, MODEL_TYPE > > strainHandler
virtual MoFEMErrorCode bindAuxiliaryStateTags(MoFEM::Interface &m_field)
MoFEMErrorCode loadPreviousDeformationGradient(EntityHandle entity, int gg)
MoFEM::Interface * mField
std::vector< double > stateVar
MoFEMErrorCode loadPreviousStateVariables(EntityHandle entity, int gg)
MoFEMErrorCode evaluateDerivatives(int, EntityHandle entity, int gg) override
PetscReal currentTimeIncrement
std::vector< std::pair< Range, std::vector< double > > > paramVecByRange
Definition MatOps.hpp:174
boost::shared_ptr< MatOpsData > matOpsDataPtr
Definition MatOps.hpp:176
MoFEMErrorCode runUmat(MatUmatImpl< DIM, MODEL_TYPE > &matUmatImpl, EntityHandle entity, int gg) override
MoFEMErrorCode convertTangent(MatUmatImpl< DIM, MODEL_TYPE > &matUmatImpl, boost::shared_ptr< MatOpsData > mat_ops_data_ptr) override
MoFEMErrorCode convertStress(MatUmatImpl< DIM, MODEL_TYPE > &matUmatImpl, boost::shared_ptr< MatOpsData > mat_ops_data_ptr) override
Deprecated interface functions.
Structure for user loop methods on finite elements.
EntityHandle getFEEntityHandle() const
Get the entity handle of the current finite element.
Interface for managing meshsets containing materials and boundary conditions.
PetscReal ts_t
Current time value.
PetscReal ts_dt
Current time step size.
PetscInt ts_step
Current time step number.
static constexpr int NTENS
subroutine umat(stress, statev, ddsdde, sse, spd, scd, rpl, ddsddt, drplde, drpldt, stran, dstran, time, dtime, temp, dtemp, predef, dpred, cmname, ndi, nshr, ntens, nstatv, props, nprops, coords, drot, pnewdt, celent, dfgrd0, dfgrd1, noel, npt, layer, kspt, kstep, kinc)