Examples

Below are some examples of how to use the library. To compile the examples into an object file (.obj) that can be used by Abaqus, you can run the following command:

abqcy compile <path-to-your-subroutine>

Note

It shoule be noted that temporary variables do not required to be typed in Cython excepted for integers. In the following examples, the cython.infer_types directive is used to infer types of untyped variables in function bodies including integers. This directive does a work similar to the auto keyword in C++ for the readers who are familiar with this language feature. It can be of great help to cut down on the need to type everything, but it also can lead to surprises.

See Determining where to add types for more information.

Example: Elastic umat subroutine

This example shows how to write an Abaqus elastic umat subroutine in Cython.

 1import cython
 2
 3
 4cdef extern from "<aba_for_c.h>":
 5    pass
 6
 7
 8@cython.infer_types(True)
 9cdef extern void umat(
10    double *stress, double *statev, double *ddsdde, double *sse, double *spd,
11    double *scd, double *rpl, double *ddsddt, double *drplde, double *drpldt,
12    double *stran, double *dstran, double *time, double *dtime, double *temp,
13    double *dtemp, double *predef, double *dpred, char *cmname, int *ndi,
14    int *nshr, int *ntens, int *nstatv, double *props, int *nprops, double *coords,
15    double *drot, double *pnewdt, double *celent, double *dfgrd0, double *dfgrd1,
16    int *noel, int *npt, int *layer, int *kspt, int *jstep, int *kinc,
17):
18    E, nu = props[0], props[1]
19    lam = E * nu / ((1.0 + nu) * (1.0 - 2.0 * nu))
20    G = E / (2.0 * (1.0 + nu))
21
22    for i in range(3):
23        for j in range(3):
24            ddsdde[6 * i + j] = lam
25        ddsdde[6 * i + i] += 2.0 * G
26        ddsdde[6 * (i + 3) + (i + 3)] = G
27    for i in range(6):
28        for j in range(6):
29            stress[i] += ddsdde[6 * i + j] * dstran[j]
 1import cython
 2
 3
 4@cython.infer_types(True)
 5def umat(
 6    stress, statev, ddsdde, sse, spd, scd, rpl, ddsddt, drplde, drpldt, stran, dstran,
 7    time, dtime, temp, dtemp, predef, dpred, cmname, ndi, nshr, ntens, nstatv, props,
 8    nprops, coords, drot, pnewdt, celent, dfgrd0, dfgrd1, noel, npt, layer, kspt,
 9    jstep, kinc,
10):  # fmt: skip
11    E, nu = props[0], props[1]
12    lam = E * nu / ((1.0 + nu) * (1.0 - 2.0 * nu))
13    G = E / (2.0 * (1.0 + nu))
14
15    for i in range(3):
16        for j in range(3):
17            ddsdde[6 * i + j] = lam
18        ddsdde[6 * i + i] += 2.0 * G
19        ddsdde[6 * (i + 3) + (i + 3)] = G
20    for i in range(6):
21        for j in range(6):
22            stress[i] += ddsdde[6 * i + j] * dstran[j]

Note

You will need to add the Cython header file (.pxd) along with the Python file (.py) in order to use the Cython declarations.

 1cdef extern from "<aba_for_c.h>":
 2    pass
 3
 4
 5cdef extern void umat(
 6    double *stress, double *statev, double *ddsdde, double *sse, double *spd,
 7    double *scd, double *rpl, double *ddsddt, double *drplde, double *drpldt,
 8    double *stran, double *dstran, double *time, double *dtime, double *temp,
 9    double *dtemp, double *predef, double *dpred, char *cmname, int *ndi,
10    int *nshr, int *ntens, int *nstatv, double *props, int *nprops, double *coords,
11    double *drot, double *pnewdt, double *celent, double *dfgrd0, double *dfgrd1,
12    int *noel, int *npt, int *layer, int *kspt, int *jstep, int *kinc,
13)

Note

This file is required to use the Cython declarations in the Python file (.py).