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 except 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)  # type: ignore
 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    ddsdde[:] = [
23        lam + 2.0 * G, lam, lam, 0.0, 0.0, 0.0,
24        lam, lam + 2.0 * G, lam, 0.0, 0.0, 0.0,
25        lam, lam, lam + 2.0 * G, 0.0, 0.0, 0.0,
26        0.0, 0.0, 0.0, G, 0.0, 0.0,
27        0.0, 0.0, 0.0, 0.0, G, 0.0,
28        0.0, 0.0, 0.0, 0.0, 0.0, G,
29    ]  # fmt: skip
30    for i in range(6):
31        for j in range(6):
32            stress[i] += ddsdde[6 * i + j] * dstran[j]
 1import cython
 2
 3
 4@cython.infer_types(True)  # type: ignore
 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    ddsdde[:] = [
16        lam + 2.0 * G, lam, lam, 0.0, 0.0, 0.0,
17        lam, lam + 2.0 * G, lam, 0.0, 0.0, 0.0,
18        lam, lam, lam + 2.0 * G, 0.0, 0.0, 0.0,
19        0.0, 0.0, 0.0, G, 0.0, 0.0,
20        0.0, 0.0, 0.0, 0.0, G, 0.0,
21        0.0, 0.0, 0.0, 0.0, 0.0, G,
22    ]  # fmt: skip
23    for i in range(6):
24        for j in range(6):
25            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).