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>
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
195 inline static bool useDeformationGradient =
196 false; // by default use common data pass gradient of displacement
197
199 createOp(boost::shared_ptr<PhysicalEquations> physical_ptr, bool eval_stress,
200 bool eval_tangent, bool update) override;
201
202 MoFEMErrorCode getOptions(MoFEM::Interface *m_field_ptr = nullptr) override {
204
205 mField = m_field_ptr;
206
207 MOFEM_LOG_CHANNEL("WORLD");
208
209 char umat_library[PETSC_MAX_PATH_LEN] = "./umat.so";
210 char umat_name[80] = "UMAT";
211 PetscInt nstatev = 0;
212 PetscInt nprops = 2;
213 const char *list_strain_type[] = {"small", "hencky", "finite"};
214 PetscInt choice_strain = StrainType::SMALL;
215 PetscOptionsBegin(PETSC_COMM_WORLD, "umat_", "", "none");
216 CHKERR PetscOptionsString("-library", "Path to UMAT shared library", "",
217 umat_library, umat_library, sizeof(umat_library),
218 PETSC_NULLPTR);
219 CHKERR PetscOptionsString("-name", "UMAT material name", "", umat_name,
220 umat_name, sizeof(umat_name), PETSC_NULLPTR);
221 CHKERR PetscOptionsInt("-nstatev", "Number of UMAT state variables", "",
222 nstatev, &nstatev, PETSC_NULLPTR);
223 CHKERR PetscOptionsInt("-nprops", "Number of UMAT material properties", "",
224 nprops, &nprops, PETSC_NULLPTR);
225 CHKERR PetscOptionsScalar("-young_modulus", "Default first property", "",
226 youngModulus, &youngModulus, PETSC_NULLPTR);
227 CHKERR PetscOptionsScalar("-poisson_ratio", "Default second property", "",
228 poissonRatio, &poissonRatio, PETSC_NULLPTR);
229 CHKERR PetscOptionsEList(
230 "-strain_type", "Strain type", "", list_strain_type, 3,
231 list_strain_type[choice_strain], &choice_strain, PETSC_NULLPTR);
232 PetscOptionsEnd();
233
234 strainType = static_cast<StrainType>(choice_strain);
235
236 switch (strainType) {
237 case SMALL:
238 strainHandler = std::make_unique<SmallStrainHandler<DIM, MODEL_TYPE>>();
239 break;
240 case HENCKY:
241 strainHandler = std::make_unique<HenckyStrainHandler<DIM, MODEL_TYPE>>();
242 break;
243 case FINITE:
244 strainHandler = std::make_unique<FiniteStrainHandler<DIM, MODEL_TYPE>>();
245 break;
246 default:
247 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
248 "Unsupported UMAT strain type");
249 }
250
251 if (nprops <= 0) {
252 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
253 "UMAT requires a positive number of properties");
254 }
255
256 if (nstatev < 0) {
257 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
258 "UMAT requires a non-negative number of state variables");
259 }
260
261 numberStateVariables = static_cast<int>(nstatev);
262 stateVar.resize(numberStateVariables, 0.0);
264 for (int ii = 0; ii != numberStateVariables; ++ii) {
266 }
267 numberMaterialProperties = static_cast<int>(nprops);
268 materialName = umat_name;
269 libraryPath = umat_library;
270
276
277 MOFEM_TAG_AND_LOG("WORLD", Sev::inform, "Default Umat parameters:")
278 << " umat_library = " << libraryPath << " name = " << materialName
279 << " umat_nstatev = " << numberStateVariables
280 << " umat_nprops = " << numberMaterialProperties;
281
282 std::string block_name = "MAT_UMAT";
283 for (auto &m :
284 m_field_ptr->getInterface<MeshsetsManager>()->getCubitMeshsetPtr(
285 std::regex((boost::format("%s(.*)") % block_name).str()))) {
286 std::vector<double> block_data;
287 CHKERR m->getAttributes(block_data);
288 if ((int)block_data.size() < numberMaterialProperties) {
289 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
290 "MAT_UMAT block requires at least %d attributes", nprops);
291 }
292
293 auto get_block_ents = [&]() {
294 Range ents;
295 CHK_MOAB_THROW(m_field_ptr->get_moab().get_entities_by_handle(
296 m->meshset, ents, true),
297 "can not get block entities");
298 return ents;
299 };
300
301 A::paramVecByRange.push_back(
302 {get_block_ents(),
303 std::vector<double>(block_data.begin(),
304 block_data.begin() + numberMaterialProperties)});
305
306 std::ostringstream properties_stream;
307 properties_stream << "[";
308 for (int ii = 0; ii != numberMaterialProperties; ++ii) {
309 if (ii)
310 properties_stream << ", ";
311 properties_stream << block_data[ii];
312 }
313 properties_stream << "]";
314
315 MOFEM_TAG_AND_LOG("WORLD", Sev::inform, "MatBlock for Umat")
316 << *m << " properties = " << properties_stream.str();
317 }
318
319 umatInterfacePtr = std::make_unique<UmatInterfaceType>(
322
323 if (m_field_ptr) {
324 CHKERR A::matOpsDataPtr->bindStateTag(*m_field_ptr, DFGRD0_TAG_NAME,
325 DIM * DIM);
326 CHKERR A::matOpsDataPtr->bindStateTag(*m_field_ptr, STRESS_TAG_NAME,
328 if (numberStateVariables > 0) {
329 for (int ii = 0; ii != numberStateVariables; ++ii) {
330 CHKERR A::matOpsDataPtr->bindStateTag(*m_field_ptr,
332 }
333 }
334 CHKERR bindAuxiliaryStateTags(*m_field_ptr);
335 CHKERR A::matOpsDataPtr->setupStateData();
336 }
337
339 }
340
341 MoFEMErrorCode setParams(FEMethod *fe_ptr, int gg) override {
343 (void)gg;
344 currentTimeStep = fe_ptr->ts_step;
345 currentTime = fe_ptr->ts_t;
346 currentTimeIncrement = fe_ptr->ts_dt;
347 const auto ent = fe_ptr->getFEEntityHandle();
349 for (auto &[range, param_vec] : A::paramVecByRange) {
350 if (range.find(ent) != range.end()) {
351 currentMaterialParameters = param_vec;
352 break;
353 }
354 }
356 }
357
360
361 A::matOpsDataPtr->insertCommonData("grad", MatrixDouble());
362 A::matOpsDataPtr->insertCommonData("P", MatrixDouble());
363 A::matOpsDataPtr->insertCommonData("P_dF", MatrixDouble());
364
365 A::matOpsDataPtr->insertActiveData("F", MatrixDouble());
366 A::matOpsDataPtr->insertDependentData("P", MatrixDouble());
367 A::matOpsDataPtr->insertDependentDerivativesData("P_dF", MatrixDouble());
368
369 A::matOpsDataPtr->getActiveDataPtr("F")->resize(DIM, DIM, false);
370 A::matOpsDataPtr->getDependentDataPtr("P")->resize(DIM, DIM, false);
371 A::matOpsDataPtr->getDependentDerivativesDataPtr("P_dF")->resize(
372 DIM * DIM, DIM * DIM, false);
373
375
377 }
378
379 MoFEMErrorCode evaluateVariable(int, EntityHandle entity, int gg) override {
381 CHKERR strainHandler->runUmat(*this, entity, gg);
382 CHKERR strainHandler->convertStress(*this, A::matOpsDataPtr);
384 }
385
386 MoFEMErrorCode evaluateDerivatives(int, EntityHandle entity,
387 int gg) override {
389 CHKERR strainHandler->runUmat(*this, entity, gg);
390 CHKERR strainHandler->convertTangent(*this, A::matOpsDataPtr);
392 }
393
394 MoFEMErrorCode updateState(int, EntityHandle entity, int gg) override {
396 CHKERR strainHandler->runUmat(*this, entity, gg);
398 CHKERR storeCurrentStress(entity, gg);
401 }
402
403protected:
409
414
415 // TODO: Populate UMAT COORDS from integration-point coordinates when needed.
416 // The default keeps COORDS zero; coordinate-dependent UMATs should override it.
417 virtual MoFEMErrorCode loadCoordinates(EntityHandle entity, int gg) {
419 (void)entity;
420 (void)gg;
421 for (int dd = 0; dd != 3; ++dd)
422 umatInterfacePtr->coords[dd] = 0.0;
424 }
425
426 virtual MoFEMErrorCode loadPredef(EntityHandle entity, int gg) {
428 (void)entity;
429 (void)gg;
430 if (umatInterfacePtr->predef.empty()) {
431 umatInterfacePtr->predef.push_back(0.0);
432 }
433 if (umatInterfacePtr->dpred.empty()) {
434 umatInterfacePtr->dpred.push_back(0.0);
435 }
436 std::fill(umatInterfacePtr->predef.begin(), umatInterfacePtr->predef.end(),
437 0.0);
438 std::fill(umatInterfacePtr->dpred.begin(), umatInterfacePtr->dpred.end(),
439 0.0);
441 }
442
443 MoFEMErrorCode loadPreviousDeformationGradient(EntityHandle entity, int gg) {
445
446 CHKERR umatInterfacePtr->setIdentityDeformationGradient();
447
448 auto state_ptr =
449 A::matOpsDataPtr->getStateDataPtr(DFGRD0_TAG_NAME, entity, gg);
450 bool has_stored_gradient = false;
451 for (int row = 0; row != DIM; ++row) {
452 for (int col = 0; col != DIM; ++col) {
453 const double value = (*state_ptr)(row * DIM + col, 0);
454 umatInterfacePtr->dfgrd0[row + 3 * col] = value;
455 has_stored_gradient = has_stored_gradient || std::abs(value) > 0;
456 }
457 }
458
459 if (!has_stored_gradient) {
460 CHKERR umatInterfacePtr->setIdentityDeformationGradient();
461 }
462
464 }
465
466 MoFEMErrorCode storeCurrentDeformationGradient(EntityHandle entity, int gg) {
468
469 auto state_ptr =
470 A::matOpsDataPtr->getStateDataPtr(DFGRD0_TAG_NAME, entity, gg);
471 for (int row = 0; row != DIM; ++row) {
472 for (int col = 0; col != DIM; ++col) {
473 (*state_ptr)(row *DIM + col, 0) =
474 umatInterfacePtr->dfgrd1[row + 3 * col];
475 }
476 }
477
479 }
480
481 MoFEMErrorCode loadPreviousStress(EntityHandle entity, int gg) {
483
484 auto state_ptr =
485 A::matOpsDataPtr->getStateDataPtr(STRESS_TAG_NAME, entity, gg);
486 for (int ii = 0; ii != UmatInterfaceType::NTENS; ++ii) {
487 umatInterfacePtr->stress[ii] = (*state_ptr)(ii, 0);
488 }
489
491 }
492
493 MoFEMErrorCode loadPreviousStateVariables(EntityHandle entity, int gg) {
495
496 umatInterfacePtr->statev.assign(numberStateVariables, -1);
499 }
500
501 for (int ii = 0; ii != numberStateVariables; ++ii) {
502 auto state_ptr = A::matOpsDataPtr->getStateDataPtr(
503 vStateVariableTagNames[ii], entity, gg);
504 umatInterfacePtr->statev[ii] = (*state_ptr)(0, 0);
505 }
506
508 }
509
510 MoFEMErrorCode storeCurrentStress(EntityHandle entity, int gg) {
512
513 auto state_ptr =
514 A::matOpsDataPtr->getStateDataPtr(STRESS_TAG_NAME, entity, gg);
515 for (int ii = 0; ii != UmatInterfaceType::NTENS; ++ii) {
516 (*state_ptr)(ii, 0) = umatInterfacePtr->stress[ii];
517 }
518
520 }
521
522 MoFEMErrorCode storeCurrentStateVariables(EntityHandle entity, int gg) {
524
527 }
528
529 for (int ii = 0; ii != numberStateVariables; ++ii) {
530 auto state_ptr = A::matOpsDataPtr->getStateDataPtr(
531 vStateVariableTagNames[ii], entity, gg);
532 (*state_ptr)(0, 0) = umatInterfacePtr->statev[ii];
533 }
534
536 }
537
539 std::unique_ptr<UmatInterfaceType> umatInterfacePtr;
540 std::string libraryPath = "./umat.so";
541 std::string materialName = "UMAT";
543 PetscInt currentTimeStep = 0;
544 PetscReal currentTime = 0;
545 PetscReal currentTimeIncrement = 0;
546 double youngModulus = 1.0;
547 double poissonRatio = 0.3;
552 std::vector<double> stateVar = std::vector<double>(numberStateVariables, 0.0);
553 std::vector<std::string> vStateVariableTagNames;
554 friend struct SmallStrainHandler<DIM, MODEL_TYPE>;
555 friend struct HenckyStrainHandler<DIM, MODEL_TYPE>;
556 friend struct FiniteStrainHandler<DIM, MODEL_TYPE>;
557 std::unique_ptr<StrainHandler<DIM, MODEL_TYPE>> strainHandler;
558};
559
560} // namespace MatOps
561
562#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
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
static bool useDeformationGradient
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)
PhysicalEquations()=delete
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)