CPU implementation

This function is called for each integration point during each time step of the simulation on the CPU. It defines the behavior of the material, such as its constitutive response, failure criteria, and post-failure behavior.

runMat()

void runMat(UserMatCPU data) const

data

  • Type: UserMatCPU
  • Description: User material data structure. See UserMatCPU for more information on the data structure.

Example

void MatRubber::runMat(UserMatCPU data) const
{
    // Load material parameters
    double C1   = data.p_cmat[6];
    double C2   = data.p_cmat[7];
    double bulk = data.p_cmat[43];

    double fmat[9], c[6], eval[3];

    // Load deformation gradient matrix
    for (int i = 0; i < 9; ++i) {
        fmat[i] = data.p_f_mat[i];
    }

    // Volumetric strain and pressure
    double evol = data.p_strain[0] + data.p_strain[1] + data.p_strain[2];
    double pressure = -bulk * evol;

    mat::cauchy_green_tensor(fmat, c);

    // Re-using fmat array as eigen vector array since fmat array is no longer needed
    double* evec = fmat;

    // Get principal stretches (squared)
    mat::calc_eigen_values(c, eval);
    mat::calc_eigen_vectors(c, eval, evec);

    double alpha = 2.0 * C1 * (eval[0] - eval[2]) - 2.0 * C2 * (1.0 / eval[0] - 1.0 / eval[2]);
    double beta = 2.0 * C1 * (eval[1] - eval[2]) - 2.0 * C2 * (1.0 / eval[1] - 1.0 / eval[2]);

    eval[0] = (2.0 * alpha - 1.0 * beta) / 3.0 - pressure;
    eval[1] = (-1.0 * alpha + 2.0 * beta) / 3.0 - pressure;
    eval[2] = (-1.0 * alpha - 1.0 * beta) / 3.0 - pressure;

    // Re-using c array as local stress array since c array is not longer needed
    double* stress = c;
    for (int i = 0; i < 6; ++i) {
        stress[i] = 0.0;
    }

    for (int i = 0; i < 3; ++i) {
        int vector_offset = i * 3;
        stress[0] += eval[i] * pow(evec[vector_offset + 0], 2);
        stress[1] += eval[i] * pow(evec[vector_offset + 1], 2);
        stress[2] += eval[i] * pow(evec[vector_offset + 2], 2);
        stress[3] += eval[i] * evec[vector_offset + 0] * evec[vector_offset + 1];
        stress[4] += eval[i] * evec[vector_offset + 1] * evec[vector_offset + 2];
        stress[5] += eval[i] * evec[vector_offset + 2] * evec[vector_offset + 0];
    }

    // Save eigen values for contour plot output
    for (int i = 0; i < 3; ++i) {
        data.p_history[i] = eval[i];
    }

    // Save new stress
    for (int i = 0; i < 6; ++i) {
        data.p_stress[i] = stress[i];
    }
}