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>
116 const MatrixDouble &grad,
bool use_deformation_gradient) {
120 for (
int dd = 0; dd != 3; ++dd)
121 dfgrd1[dd + 3 * dd] = 1.0;
123 for (
int row = 0; row != DIM; ++row) {
124 for (
int col = 0; col != DIM; ++col) {
125 const double grad_value = grad(row, col);
126 dfgrd1[row + 3 * col] = use_deformation_gradient
128 : grad_value + (row == col ? 1.0 : 0.0);
135template <
int MODEL_TYPE>
138 double time_increment) {
141 time[1] = current_time;
142 dtime = time_increment;
143 time[0] = current_time - time_increment;
148template <
int MODEL_TYPE>
151 int increment_number) {
155 kinc = increment_number;
160template <
int MODEL_TYPE>
165 auto get_small_strain_voigt = [](
const std::array<double, 9> &dfgrd,
167 std::array<double, 9> grad = dfgrd;
168 for (
int dd = 0; dd != DIM; ++dd)
169 grad[dd + 3 * dd] -= 1.0;
175 strain[3] = grad[1] + grad[3];
176 strain[4] = grad[2] + grad[6];
177 strain[5] = grad[5] + grad[7];
182 strain[3] = grad[1] + grad[3];
186 strain[2] = grad[1] + grad[3];
189 "UMAT strain increment is not implemented for this model type");
193 std::array<double, NTENS> reference_strain{};
194 std::array<double, NTENS> current_strain{};
195 get_small_strain_voigt(dfgrd0, reference_strain);
196 get_small_strain_voigt(dfgrd1, current_strain);
198 for (
int ii = 0; ii != NTENS; ++ii) {
199 stran[ii] = reference_strain[ii];
200 dstran[ii] = current_strain[ii] - reference_strain[ii];
206template <
int MODEL_TYPE>
208 int n_statev,
const std::vector<double> &state_var_values) {
214template <
int MODEL_TYPE>
219 for (
int row = 0; row != DIM; ++row)
220 for (
int col = 0; col != DIM; ++col)
221 F(row, col) = dfgrd1[row + 3 * col];
225template <
int MODEL_TYPE>
231 sigma(0, 0) = stress[0];
232 sigma(1, 1) = stress[1];
233 sigma(2, 2) = stress[2];
234 sigma(0, 1) = sigma(1, 0) = stress[3];
235 sigma(0, 2) = sigma(2, 0) = stress[4];
236 sigma(1, 2) = sigma(2, 1) = stress[5];
238 sigma(0, 0) = stress[0];
239 sigma(1, 1) = stress[1];
240 sigma(2, 2) = stress[2];
241 sigma(0, 1) = sigma(1, 0) = stress[3];
243 sigma(0, 0) = stress[0];
244 sigma(1, 1) = stress[1];
245 sigma(0, 1) = sigma(1, 0) = stress[2];
248 "UMAT stress conversion is not implemented for this model type");
253template <
int MODEL_TYPE>
259 static const std::array<std::pair<int, int>, 6> pairs = {
260 std::pair<int, int>{0, 0}, {1, 1}, {2, 2}, {0, 1}, {0, 2}, {1, 2}};
261 for (
int row = 0; row != 6; ++row) {
262 const auto [
i,
j] = pairs[row];
263 for (
int col = 0; col != 6; ++col) {
264 const auto [
k,
l] = pairs[col];
265 const double value = ddsdde[row + 6 * col];
273 static const std::array<std::pair<int, int>, 4> pairs = {
274 std::pair<int, int>{0, 0}, {1, 1}, {2, 2}, {0, 1}};
275 for (
int row = 0; row != 4; ++row) {
276 const auto [
i,
j] = pairs[row];
277 for (
int col = 0; col != 4; ++col) {
278 const auto [
k,
l] = pairs[col];
279 const double value = ddsdde[row + 4 * col];
287 static const std::array<std::pair<int, int>, 3> pairs = {
288 std::pair<int, int>{0, 0}, {1, 1}, {0, 1}};
289 for (
int row = 0; row != 3; ++row) {
290 const auto [
i,
j] = pairs[row];
291 for (
int col = 0; col != 3; ++col) {
292 const auto [
k,
l] = pairs[col];
293 const double value = ddsdde[row + 3 * col];
302 "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 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)