14inline int tensorIndex(
const int ii,
const int jj) {
return 3 * ii + jj; }
18 mat.resize(3, 3,
false);
25 mat.resize(9, 9,
false);
35template <
int MODEL_TYPE>
37 : nstatv(nstatv), nprops(nprops), props(nprops, 0.0), statev(nstatv, 0.0) {}
47template <
int MODEL_TYPE>
50 const std::string &material_name) {
59 std::memset(filename, 0,
sizeof(filename));
60 std::strncpy(filename, library_path.c_str(),
sizeof(filename) - 1);
62 std::memset(cmname,
' ',
sizeof(cmname));
63 const auto material_name_size = material_name.size() <
sizeof(cmname)
64 ? material_name.size()
66 std::memcpy(cmname, material_name.data(), material_name_size);
68 handle = dlopen(filename, RTLD_NOW | RTLD_LOCAL);
71 "Failed to open UMAT library %s: %s", filename, dlerror());
77 "Failed to resolve symbol umat_ in %s: %s", filename, dlerror());
83template <
int MODEL_TYPE>
89 "UMAT function pointer is not initialised");
92 umat(stress.data(), statev.data(), ddsdde.data(), &sse, &spd, &scd, &rpl,
93 ddsddt, drplde, &drpldt, stran.data(), dstran.data(), time, &dtime,
94 &
temp, &dtemp, predef.data(), dpred.data(), cmname, &ndi, &nshr, &ntens,
95 &nstatv, props.data(), &nprops, coords, drot.data(), &pnewdt, &celent,
96 dfgrd0.data(), dfgrd1.data(), &noel, &npt, &layer, &kspt, &kstep, &kinc,
102template <
int MODEL_TYPE>
108 for (
int dd = 0; dd != 3; ++dd)
109 dfgrd0[dd + 3 * dd] = 1.0;
114template <
int MODEL_TYPE>
120 for (
int dd = 0; dd != 3; ++dd)
121 drot[dd + 3 * dd] = 1.0;
126template <
int MODEL_TYPE>
128 const MatrixDouble &grad,
bool use_deformation_gradient) {
132 for (
int dd = 0; dd != 3; ++dd)
133 dfgrd1[dd + 3 * dd] = 1.0;
135 for (
int row = 0; row != DIM; ++row) {
136 for (
int col = 0; col != DIM; ++col) {
137 const double grad_value = grad(row, col);
138 dfgrd1[row + 3 * col] = use_deformation_gradient
140 : grad_value + (row == col ? 1.0 : 0.0);
147template <
int MODEL_TYPE>
150 double time_increment) {
153 time[1] = current_time;
154 dtime = time_increment;
155 time[0] = current_time - time_increment;
160template <
int MODEL_TYPE>
163 int increment_number) {
167 kinc = increment_number;
172template <
int MODEL_TYPE>
177 auto get_small_strain_voigt = [](
const std::array<double, 9> &dfgrd,
179 std::array<double, 9> grad = dfgrd;
180 for (
int dd = 0; dd != DIM; ++dd)
181 grad[dd + 3 * dd] -= 1.0;
187 strain[3] = grad[1] + grad[3];
188 strain[4] = grad[2] + grad[6];
189 strain[5] = grad[5] + grad[7];
194 strain[3] = grad[1] + grad[3];
198 strain[2] = grad[1] + grad[3];
203 strain[3] = grad[1] + grad[3];
206 "UMAT strain increment is not implemented for this model type");
210 std::array<double, NTENS> reference_strain{};
211 std::array<double, NTENS> current_strain{};
212 get_small_strain_voigt(dfgrd0, reference_strain);
213 get_small_strain_voigt(dfgrd1, current_strain);
215 for (
int ii = 0; ii != NTENS; ++ii) {
216 stran[ii] = reference_strain[ii];
217 dstran[ii] = current_strain[ii] - reference_strain[ii];
223template <
int MODEL_TYPE>
225 int n_statev,
const std::vector<double> &state_var_values) {
231template <
int MODEL_TYPE>
236 for (
int row = 0; row != DIM; ++row)
237 for (
int col = 0; col != DIM; ++col)
238 F(row, col) = dfgrd1[row + 3 * col];
242template <
int MODEL_TYPE>
248 sigma(0, 0) = stress[0];
249 sigma(1, 1) = stress[1];
250 sigma(2, 2) = stress[2];
251 sigma(0, 1) = sigma(1, 0) = stress[3];
252 sigma(0, 2) = sigma(2, 0) = stress[4];
253 sigma(1, 2) = sigma(2, 1) = stress[5];
256 sigma(0, 0) = stress[0];
257 sigma(1, 1) = stress[1];
258 sigma(2, 2) = stress[2];
259 sigma(0, 1) = sigma(1, 0) = stress[3];
261 sigma(0, 0) = stress[0];
262 sigma(1, 1) = stress[1];
263 sigma(0, 1) = sigma(1, 0) = stress[2];
266 "UMAT stress conversion is not implemented for this model type");
271template <
int MODEL_TYPE>
277 static const std::array<std::pair<int, int>, 6> pairs = {
278 std::pair<int, int>{0, 0}, {1, 1}, {2, 2}, {0, 1}, {0, 2}, {1, 2}};
279 for (
int row = 0; row != 6; ++row) {
280 const auto [
i,
j] = pairs[row];
281 for (
int col = 0; col != 6; ++col) {
282 const auto [
k,
l] = pairs[col];
283 const double value = ddsdde[row + 6 * col];
292 static const std::array<std::pair<int, int>, 4> pairs = {
293 std::pair<int, int>{0, 0}, {1, 1}, {2, 2}, {0, 1}};
294 for (
int row = 0; row != 4; ++row) {
295 const auto [
i,
j] = pairs[row];
296 for (
int col = 0; col != 4; ++col) {
297 const auto [
k,
l] = pairs[col];
298 const double value = ddsdde[row + 4 * col];
306 static const std::array<std::pair<int, int>, 3> pairs = {
307 std::pair<int, int>{0, 0}, {1, 1}, {0, 1}};
308 for (
int row = 0; row != 3; ++row) {
309 const auto [
i,
j] = pairs[row];
310 for (
int col = 0; col != 3; ++col) {
311 const auto [
k,
l] = pairs[col];
312 const double value = ddsdde[row + 3 * col];
321 "UMAT tangent conversion is not implemented for this model type");
void(*)(double *stress, double *statev, double *ddsdde, double *sse, double *spd, double *scd, double *rpl, double *ddsddt, double *drplde, double *drpldt, double *stran, double *dstran, double *time, double *dtime, double *temp, double *dtemp, double *predef, double *dpred, char *cmname, int *ndi, int *nshr, int *ntens, int *nstatv, double *props, int *nprops, double *coords, double *drot, double *pnewdt, double *celent, double *dfgrd0, double *dfgrd1, int *noel, int *npt, int *layer, int *kspt, int *kstep, int *kinc, std::size_t cmname_len) umat_f
#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 ...
@ MOFEM_OPERATION_UNSUCCESSFUL
#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 ...
FTensor::Index< 'i', SPACE_DIM > i
FTensor::Index< 'l', 3 > l
FTensor::Index< 'j', 3 > j
FTensor::Index< 'k', 3 > k
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
implementation of Data Operators for Forces and Sources
MoFEMErrorCode resizeTensor2(MatrixDouble &mat)
MoFEMErrorCode resizeTensor4(MatrixDouble &mat)
int tensorIndex(const int ii, const int jj)
void temp(int x, int y=10)
MoFEMErrorCode setStepData(int step_number, int increment_number)
MoFEMErrorCode initialise(const std::string &library_path="./umat.so", const std::string &material_name="UMAT")
MoFEMErrorCode setTimeData(double current_time, double time_increment)
MoFEMErrorCode getCauchyTangentTensor(MatrixDouble &cauchy_tangent) const
MoFEMErrorCode setIdentityRotationIncrement()
MoFEMErrorCode setStrainIncrementFromDeformationGradient()
MoFEMErrorCode callUmat()
UmatInterface(int nstatv=0, int nprops=2)
MoFEMErrorCode storeStateVar(int n_state_var, const std::vector< double > &state_var_values)
MoFEMErrorCode setDeformationGradient(const MatrixDouble &grad, bool use_deformation_gradient)
MoFEMErrorCode setIdentityDeformationGradient()
MoFEMErrorCode getCauchyStressTensor(MatrixDouble &sigma) const
MoFEMErrorCode getDeformationGradient(MatrixDouble &F) const
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)