6#ifndef MAT_UMAT_IMPL_HPP
7#define MAT_UMAT_IMPL_HPP
24template <
int DIM,
int MODEL_TYPE>
30 EntityHandle entity,
int gg)
override {
34 "UMAT interface is not initialised");
38 umat.noel =
static_cast<int>(entity);
49 CHKERR umat.setStrainIncrementFromDeformationGradient();
59 boost::shared_ptr<MatOpsData> mat_ops_data_ptr)
override {
62 auto set_stress_from_umat_cauchy = [&]() {
65 auto t_P = getFTensor2FromPtr<DIM, DIM>(
66 mat_ops_data_ptr->getDependentDataPtr(
"P")->data().data());
71 for (
int i = 0;
i != DIM; ++
i)
72 for (
int Jidx = 0; Jidx != DIM; ++Jidx)
73 t_P(
i, Jidx) = sigma(
i, Jidx);
78 CHKERR set_stress_from_umat_cauchy();
84 boost::shared_ptr<MatOpsData> mat_ops_data_ptr)
override {
87 auto set_tangent_from_umat_cauchy = [&]() {
90 auto t_dP = getFTensor4FromPtr<DIM, DIM, DIM, DIM>(
91 mat_ops_data_ptr->getDependentDerivativesDataPtr(
"P_dF")
96 CHKERR umat.getCauchyTangentTensor(d_sigma_d_eps);
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)
108 CHKERR set_tangent_from_umat_cauchy();
113template <
int DIM,
int MODEL_TYPE>
119 EntityHandle entity,
int gg)
override {
129 boost::shared_ptr<MatOpsData> mat_ops_data_ptr)
override {
132 (void)mat_ops_data_ptr;
138 boost::shared_ptr<MatOpsData> mat_ops_data_ptr)
override {
141 (void)mat_ops_data_ptr;
146template <
int DIM,
int MODEL_TYPE>
152 EntityHandle entity,
int gg)
override {
162 boost::shared_ptr<MatOpsData> mat_ops_data_ptr)
override {
165 (void)mat_ops_data_ptr;
171 boost::shared_ptr<MatOpsData> mat_ops_data_ptr)
override {
174 (void)mat_ops_data_ptr;
179template <
int DIM,
int MODEL_TYPE>
181 using MatPiolaResponse::MatPiolaResponse;
191 tag_name += std::to_string(index);
196 createOp(boost::shared_ptr<PhysicalEquations> physical_ptr,
bool eval_stress,
197 bool eval_tangent,
bool update)
override;
206 char umat_library[PETSC_MAX_PATH_LEN] =
"./umat.so";
207 char umat_name[80] =
"UMAT";
208 PetscInt nstatev = 0;
210 const char *list_strain_type[] = {
"small",
"hencky",
"finite"};
212 PetscOptionsBegin(PETSC_COMM_WORLD,
"umat_",
"",
"none");
213 CHKERR PetscOptionsString(
"-library",
"Path to UMAT shared library",
"",
214 umat_library, umat_library,
sizeof(umat_library),
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",
"",
224 CHKERR PetscOptionsScalar(
"-poisson_ratio",
"Default second property",
"",
227 "-strain_type",
"Strain type",
"", list_strain_type, 3,
228 list_strain_type[choice_strain], &choice_strain, PETSC_NULLPTR);
235 strainHandler = std::make_unique<SmallStrainHandler<DIM, MODEL_TYPE>>();
238 strainHandler = std::make_unique<HenckyStrainHandler<DIM, MODEL_TYPE>>();
241 strainHandler = std::make_unique<FiniteStrainHandler<DIM, MODEL_TYPE>>();
245 "Unsupported UMAT strain type");
250 "UMAT requires a positive number of properties");
255 "UMAT requires a non-negative number of state variables");
279 std::string block_name =
"MAT_UMAT";
282 std::regex((boost::format(
"%s(.*)") % block_name).str()))) {
283 std::vector<double> block_data;
284 CHKERR m->getAttributes(block_data);
287 "MAT_UMAT block requires at least %d attributes", nprops);
290 auto get_block_ents = [&]() {
293 m->meshset, ents,
true),
294 "can not get block entities");
300 std::vector<double>(block_data.begin(),
303 std::ostringstream properties_stream;
304 properties_stream <<
"[";
307 properties_stream <<
", ";
308 properties_stream << block_data[ii];
310 properties_stream <<
"]";
313 << *
m <<
" properties = " << properties_stream.str();
347 if (range.find(ent) != range.end()) {
369 DIM * DIM, DIM * DIM,
false);
418 for (
int dd = 0; dd != 3; ++dd)
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);
452 has_stored_gradient = has_stored_gradient || std::abs(value) > 0;
456 if (!has_stored_gradient) {
468 for (
int row = 0; row != DIM; ++row) {
469 for (
int col = 0; col != DIM; ++col) {
470 (*state_ptr)(row *DIM + col, 0) =
#define MOFEM_TAG_AND_LOG(channel, severity, tag)
Tag and log in channel.
#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
@ MOFEM_DATA_INCONSISTENCY
#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
implementation of Data Operators for Forces and Sources
FTensor::Index< 'm', 3 > m
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.
static bool useDeformationGradient
Otherwise the displacement gradient is supplied and I is added.
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
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
int numberMaterialProperties
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
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
boost::shared_ptr< MatOpsData > matOpsDataPtr
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)