v0.16.0
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.setStrainIncrementFromDeformationGradient();
49 CHKERR matUmatImpl.loadCoordinates(entity, gg);
50 CHKERR matUmatImpl.loadPredef(entity, gg);
51
52 CHKERR umat.callUmat();
54 }
55
58 boost::shared_ptr<MatOpsData> mat_ops_data_ptr) override {
60 auto &umat = *matUmatImpl.umatInterfacePtr;
61 auto set_stress_from_umat_cauchy = [&]() {
63
64 auto t_P = getFTensor2FromPtr<DIM, DIM>(
65 mat_ops_data_ptr->getDependentDataPtr("P")->data().data());
66
67 MatrixDouble sigma;
68 CHKERR umat.getCauchyStressTensor(sigma);
69
70 for (int i = 0; i != DIM; ++i)
71 for (int Jidx = 0; Jidx != DIM; ++Jidx)
72 t_P(i, Jidx) = sigma(i, Jidx);
73
75 };
76
77 CHKERR set_stress_from_umat_cauchy();
79 }
80
83 boost::shared_ptr<MatOpsData> mat_ops_data_ptr) override {
85 auto &umat = *matUmatImpl.umatInterfacePtr;
86 auto set_tangent_from_umat_cauchy = [&]() {
88
89 auto t_dP = getFTensor4FromPtr<DIM, DIM, DIM, DIM>(
90 mat_ops_data_ptr->getDependentDerivativesDataPtr("P_dF")
91 ->data()
92 .data());
93
94 MatrixDouble d_sigma_d_eps;
95 CHKERR umat.getCauchyTangentTensor(d_sigma_d_eps);
96
97 for (int i = 0; i != DIM; ++i)
98 for (int Jidx = 0; Jidx != DIM; ++Jidx)
99 for (int m = 0; m != DIM; ++m)
100 for (int N = 0; N != DIM; ++N)
101 t_dP(i, Jidx, m, N) = d_sigma_d_eps(umatTensorIndex(i, Jidx),
103
105 };
106
107 CHKERR set_tangent_from_umat_cauchy();
109 }
110};
111
112template <int DIM, int MODEL_TYPE>
113struct HenckyStrainHandler : public StrainHandler<DIM, MODEL_TYPE> {
114
116
118 EntityHandle entity, int gg) override {
120 (void)matUmatImpl;
121 (void)entity;
122 (void)gg;
124 }
125
128 boost::shared_ptr<MatOpsData> mat_ops_data_ptr) override {
130 (void)matUmatImpl;
131 (void)mat_ops_data_ptr;
133 }
134
137 boost::shared_ptr<MatOpsData> mat_ops_data_ptr) override {
139 (void)matUmatImpl;
140 (void)mat_ops_data_ptr;
142 }
143};
144
145template <int DIM, int MODEL_TYPE>
146struct FiniteStrainHandler : public StrainHandler<DIM, MODEL_TYPE> {
147
149
151 EntityHandle entity, int gg) override {
153 (void)matUmatImpl;
154 (void)entity;
155 (void)gg;
157 }
158
161 boost::shared_ptr<MatOpsData> mat_ops_data_ptr) override {
163 (void)matUmatImpl;
164 (void)mat_ops_data_ptr;
166 }
167
170 boost::shared_ptr<MatOpsData> mat_ops_data_ptr) override {
172 (void)matUmatImpl;
173 (void)mat_ops_data_ptr;
175 }
176};
177
178template <int DIM, int MODEL_TYPE>
183 static constexpr auto DFGRD0_TAG_NAME = "UMAT_DFGRD0";
184 static constexpr auto STRESS_TAG_NAME = "UMAT_STRESS";
185 static constexpr auto STATEV_TAG_NAME = "UMAT_STATEV";
186
187 static std::string getStateVariableTagName(const int index) {
188 return (boost::format("%s_%d") % STATEV_TAG_NAME % index).str();
189 }
190
191 inline static bool useDeformationGradient =
192 false; // by default use common data pass gradient of displacement
193
195 createOp(boost::shared_ptr<PhysicalEquations> physical_ptr, bool eval_stress,
196 bool eval_tangent, bool update) override;
197
198 MoFEMErrorCode getOptions(MoFEM::Interface *m_field_ptr = nullptr) override {
200
201 mField = m_field_ptr;
202
203 MOFEM_LOG_CHANNEL("WORLD");
204
205 char umat_library[PETSC_MAX_PATH_LEN] = "./umat.so";
206 char umat_name[80] = "UMAT";
207 PetscInt nstatev = 0;
208 PetscInt nprops = 2;
209 const char *list_strain_type[] = {"small", "hencky", "finite"};
210 PetscInt choice_strain = StrainType::SMALL;
211 PetscOptionsBegin(PETSC_COMM_WORLD, "umat_", "", "none");
212 CHKERR PetscOptionsString("-library", "Path to UMAT shared library", "",
213 umat_library, umat_library, sizeof(umat_library),
214 PETSC_NULLPTR);
215 CHKERR PetscOptionsString("-name", "UMAT material name", "", umat_name,
216 umat_name, sizeof(umat_name), PETSC_NULLPTR);
217 CHKERR PetscOptionsInt("-nstatev", "Number of UMAT state variables", "",
218 nstatev, &nstatev, PETSC_NULLPTR);
219 CHKERR PetscOptionsInt("-nprops", "Number of UMAT material properties", "",
220 nprops, &nprops, PETSC_NULLPTR);
221 CHKERR PetscOptionsScalar("-young_modulus", "Default first property", "",
222 youngModulus, &youngModulus, PETSC_NULLPTR);
223 CHKERR PetscOptionsScalar("-poisson_ratio", "Default second property", "",
224 poissonRatio, &poissonRatio, PETSC_NULLPTR);
225 CHKERR PetscOptionsEList(
226 "-strain_type", "Strain type", "", list_strain_type, 3,
227 list_strain_type[choice_strain], &choice_strain, PETSC_NULLPTR);
228 PetscOptionsEnd();
229
230 strainType = static_cast<StrainType>(choice_strain);
231
232 switch (strainType) {
233 case SMALL:
234 strainHandler = std::make_unique<SmallStrainHandler<DIM, MODEL_TYPE>>();
235 break;
236 case HENCKY:
237 strainHandler = std::make_unique<HenckyStrainHandler<DIM, MODEL_TYPE>>();
238 break;
239 case FINITE:
240 strainHandler = std::make_unique<FiniteStrainHandler<DIM, MODEL_TYPE>>();
241 break;
242 default:
243 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
244 "Unsupported UMAT strain type");
245 }
246
247 if (nprops <= 0) {
248 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
249 "UMAT requires a positive number of properties");
250 }
251
252 if (nstatev < 0) {
253 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
254 "UMAT requires a non-negative number of state variables");
255 }
256
257 numberStateVariables = static_cast<int>(nstatev);
258 stateVar.resize(numberStateVariables, 0.0);
259 numberMaterialProperties = static_cast<int>(nprops);
260 materialName = umat_name;
261 libraryPath = umat_library;
262
268
269 MOFEM_TAG_AND_LOG("WORLD", Sev::inform, "Default Umat parameters:")
270 << " umat_library = " << libraryPath << " name = " << materialName
271 << " umat_nstatev = " << numberStateVariables
272 << " umat_nprops = " << numberMaterialProperties;
273
274 std::string block_name = "MAT_UMAT";
275 for (auto &m :
276 m_field_ptr->getInterface<MeshsetsManager>()->getCubitMeshsetPtr(
277 std::regex((boost::format("%s(.*)") % block_name).str()))) {
278 std::vector<double> block_data;
279 CHKERR m->getAttributes(block_data);
280 if ((int)block_data.size() < numberMaterialProperties) {
281 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
282 "MAT_UMAT block requires at least %d attributes", nprops);
283 }
284
285 auto get_block_ents = [&]() {
286 Range ents;
287 CHK_MOAB_THROW(m_field_ptr->get_moab().get_entities_by_handle(
288 m->meshset, ents, true),
289 "can not get block entities");
290 return ents;
291 };
292
293 A::paramVecByRange.push_back(
294 {get_block_ents(),
295 std::vector<double>(block_data.begin(),
296 block_data.begin() + numberMaterialProperties)});
297
298 std::ostringstream properties_stream;
299 properties_stream << "[";
300 for (int ii = 0; ii != numberMaterialProperties; ++ii) {
301 if (ii)
302 properties_stream << ", ";
303 properties_stream << block_data[ii];
304 }
305 properties_stream << "]";
306
307 MOFEM_TAG_AND_LOG("WORLD", Sev::inform, "MatBlock for Umat")
308 << *m << " properties = " << properties_stream.str();
309 }
310
311 umatInterfacePtr = std::make_unique<UmatInterfaceType>(
314
315 if (m_field_ptr) {
316 CHKERR A::matOpsDataPtr->bindStateTag(*m_field_ptr, DFGRD0_TAG_NAME,
317 DIM * DIM);
318 CHKERR A::matOpsDataPtr->bindStateTag(*m_field_ptr, STRESS_TAG_NAME,
320 if (numberStateVariables > 0) {
321 for (int ii = 0; ii != numberStateVariables; ++ii) {
322 CHKERR A::matOpsDataPtr->bindStateTag(*m_field_ptr,
324 }
325 }
326 CHKERR bindAuxiliaryStateTags(*m_field_ptr);
327 CHKERR A::matOpsDataPtr->setupStateData();
328 }
329
331 }
332
333 MoFEMErrorCode setParams(FEMethod *fe_ptr, int gg) override {
335 (void)gg;
336 currentTimeStep = fe_ptr->ts_step;
337 currentTime = fe_ptr->ts_t;
338 currentTimeIncrement = fe_ptr->ts_dt;
339 const auto ent = fe_ptr->getFEEntityHandle();
341 for (auto &[range, param_vec] : A::paramVecByRange) {
342 if (range.find(ent) != range.end()) {
343 currentMaterialParameters = param_vec;
344 break;
345 }
346 }
348 }
349
352
353 A::matOpsDataPtr->insertCommonData("grad", MatrixDouble());
354 A::matOpsDataPtr->insertCommonData("P", MatrixDouble());
355 A::matOpsDataPtr->insertCommonData("P_dF", MatrixDouble());
356
357 A::matOpsDataPtr->insertActiveData("F", MatrixDouble());
358 A::matOpsDataPtr->insertDependentData("P", MatrixDouble());
359 A::matOpsDataPtr->insertDependentDerivativesData("P_dF", MatrixDouble());
360
361 A::matOpsDataPtr->getActiveDataPtr("F")->resize(DIM, DIM, false);
362 A::matOpsDataPtr->getDependentDataPtr("P")->resize(DIM, DIM, false);
363 A::matOpsDataPtr->getDependentDerivativesDataPtr("P_dF")->resize(
364 DIM * DIM, DIM * DIM, false);
365
367
369 }
370
371 MoFEMErrorCode evaluateVariable(int, EntityHandle entity, int gg) override {
373 CHKERR strainHandler->runUmat(*this, entity, gg);
374 CHKERR strainHandler->convertStress(*this, A::matOpsDataPtr);
376 }
377
378 MoFEMErrorCode evaluateDerivatives(int, EntityHandle entity,
379 int gg) override {
381 CHKERR strainHandler->runUmat(*this, entity, gg);
382 CHKERR strainHandler->convertTangent(*this, A::matOpsDataPtr);
384 }
385
386 MoFEMErrorCode updateState(int, EntityHandle entity, int gg) override {
388 CHKERR strainHandler->runUmat(*this, entity, gg);
390 CHKERR storeCurrentStress(entity, gg);
393 }
394
395protected:
401
406
407 // TODO: Populate UMAT COORDS from integration-point coordinates when needed.
408 // The default keeps COORDS zero; coordinate-dependent UMATs should override it.
409 virtual MoFEMErrorCode loadCoordinates(EntityHandle entity, int gg) {
411 (void)entity;
412 (void)gg;
413 for (int dd = 0; dd != 3; ++dd)
414 umatInterfacePtr->coords[dd] = 0.0;
416 }
417
418 virtual MoFEMErrorCode loadPredef(EntityHandle entity, int gg) {
420 (void)entity;
421 (void)gg;
422 if (umatInterfacePtr->predef.empty()) {
423 umatInterfacePtr->predef.push_back(0.0);
424 }
425 if (umatInterfacePtr->dpred.empty()) {
426 umatInterfacePtr->dpred.push_back(0.0);
427 }
428 std::fill(umatInterfacePtr->predef.begin(), umatInterfacePtr->predef.end(),
429 0.0);
430 std::fill(umatInterfacePtr->dpred.begin(), umatInterfacePtr->dpred.end(),
431 0.0);
433 }
434
435 MoFEMErrorCode loadPreviousDeformationGradient(EntityHandle entity, int gg) {
437
438 CHKERR umatInterfacePtr->setIdentityDeformationGradient();
439
440 auto state_ptr =
441 A::matOpsDataPtr->getStateDataPtr(DFGRD0_TAG_NAME, entity, gg);
442 bool has_stored_gradient = false;
443 for (int row = 0; row != DIM; ++row) {
444 for (int col = 0; col != DIM; ++col) {
445 const double value = (*state_ptr)(row * DIM + col, 0);
446 umatInterfacePtr->dfgrd0[row + 3 * col] = value;
447 has_stored_gradient = has_stored_gradient || std::abs(value) > 0;
448 }
449 }
450
451 if (!has_stored_gradient) {
452 CHKERR umatInterfacePtr->setIdentityDeformationGradient();
453 }
454
456 }
457
458 MoFEMErrorCode storeCurrentDeformationGradient(EntityHandle entity, int gg) {
460
461 auto state_ptr =
462 A::matOpsDataPtr->getStateDataPtr(DFGRD0_TAG_NAME, entity, gg);
463 for (int row = 0; row != DIM; ++row) {
464 for (int col = 0; col != DIM; ++col) {
465 (*state_ptr)(row *DIM + col, 0) =
466 umatInterfacePtr->dfgrd1[row + 3 * col];
467 }
468 }
469
471 }
472
473 MoFEMErrorCode loadPreviousStress(EntityHandle entity, int gg) {
475
476 auto state_ptr =
477 A::matOpsDataPtr->getStateDataPtr(STRESS_TAG_NAME, entity, gg);
478 for (int ii = 0; ii != UmatInterfaceType::NTENS; ++ii) {
479 umatInterfacePtr->stress[ii] = (*state_ptr)(ii, 0);
480 }
481
483 }
484
485 MoFEMErrorCode loadPreviousStateVariables(EntityHandle entity, int gg) {
487
488 umatInterfacePtr->statev.assign(numberStateVariables, -1);
491 }
492
493 for (int ii = 0; ii != numberStateVariables; ++ii) {
494 auto state_ptr = A::matOpsDataPtr->getStateDataPtr(
495 getStateVariableTagName(ii), entity, gg);
496 umatInterfacePtr->statev[ii] = (*state_ptr)(0, 0);
497 }
498
500 }
501
502 MoFEMErrorCode storeCurrentStress(EntityHandle entity, int gg) {
504
505 auto state_ptr =
506 A::matOpsDataPtr->getStateDataPtr(STRESS_TAG_NAME, entity, gg);
507 for (int ii = 0; ii != UmatInterfaceType::NTENS; ++ii) {
508 (*state_ptr)(ii, 0) = umatInterfacePtr->stress[ii];
509 }
510
512 }
513
514 MoFEMErrorCode storeCurrentStateVariables(EntityHandle entity, int gg) {
516
519 }
520
521 for (int ii = 0; ii != numberStateVariables; ++ii) {
522 auto state_ptr = A::matOpsDataPtr->getStateDataPtr(
523 getStateVariableTagName(ii), entity, gg);
524 (*state_ptr)(0, 0) = umatInterfacePtr->statev[ii];
525 }
526
528 }
529
531 std::unique_ptr<UmatInterfaceType> umatInterfacePtr;
532 std::string libraryPath = "./umat.so";
533 std::string materialName = "UMAT";
535 PetscInt currentTimeStep = 0;
536 PetscReal currentTime = 0;
537 PetscReal currentTimeIncrement = 0;
538 double youngModulus = 1.0;
539 double poissonRatio = 0.3;
544 std::vector<double> stateVar = std::vector<double>(numberStateVariables, 0.0);
545 friend struct SmallStrainHandler<DIM, MODEL_TYPE>;
546 friend struct HenckyStrainHandler<DIM, MODEL_TYPE>;
547 friend struct FiniteStrainHandler<DIM, MODEL_TYPE>;
548 std::unique_ptr<StrainHandler<DIM, MODEL_TYPE>> strainHandler;
549};
550
551} // namespace MatOps
552
553#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
static constexpr auto STATEV_TAG_NAME
MoFEMErrorCode storeCurrentStateVariables(EntityHandle entity, int gg)
MoFEMErrorCode setParams(FEMethod *fe_ptr, int gg) override
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
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:162
boost::shared_ptr< MatOpsData > matOpsDataPtr
Definition MatOps.hpp:164
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)