Tensor[4] = { 0.0, 0.0, 0.0, 0.0 }; // Full stress tensor in vector form.
    IsotropicLinearElasticityPlaneStrain::meanStress_refstate(_dim, _numS, numAMean, sOffDisp, sOffDisp_x, s, s_t, s_x,
                                                              aOffMean, NULL, a, a_t, NULL, t, x, numConstants, constants, stressTensor);
    const PylithScalar meanStress = stressTensor[0];

    const PylithScalar* refstress = &a[aOff[i_rstress]]; // stress_xx, stress_yy, stress_zz, stress_xy
    const PylithScalar* refstrain = &a[aOff[i_rstrain]]; // strain_xx, strain_yy, strain_zz, strain_xy

    // Compute reference deviatoric values.
    const PylithReal meanRefStrain = (refstrain[0] + refstrain[1] + refstrain[2])/3.0;
    const PylithScalar devRefStrain[4] = {refstrain[0] - meanRefStrain,
                                          refstrain[1] - meanRefStrain,
                                          refstrain[2] - meanRefStrain,
                                          refstrain[3]};
    const PylithReal meanRefStress = (refstress[0] + refstress[1] + refstress[2])/3.0;
    const PylithScalar devRefStress[4] = {refstress[0] - meanRefStress,
                                          refstress[1] - meanRefStress,
                                          refstress[2] - meanRefStress,
                                          refstress[3]};

    stressVector[0] = meanStress + devRefStress[0] + 2.0 * shearModulus * (visStrainTpdt[0] - devRefStrain[0]); // stress_xx
    stressVector[1] = meanStress + devRefStress[1] + 2.0 * shearModulus * (visStrainTpdt[1] - devRefStrain[1]); // stress_yy
    stressVector[2] = meanStress + devRefStress[2] + 2.0 * shearModulus * (visStrainTpdt[2] - devRefStrain[2]); // stress_zz
    stressVector[3] = devRefStress[3] + 2.0 * shearModulus * (visStrainTpdt[3] - devRefStrain[3]); // stress_xy

} // cauchyStress_refstate


// =====================================================================================================================
// Kernels for isotropic, linear Maxwell viscoelastic 3D material.
// =====================================================================================================================

// ---------------------------------------------------------------------------------------------------------------------
// f1 function for isotropic linear Maxwell 3D material WITHOUT reference stress and strain.
void
pylith::fekernels::IsotropicLinearMaxwell3D::f1v(const PylithInt dim,
                                                 const PylithInt numS,
                                                 const PylithInt numA,
                                                 const PylithInt sOff[],
                                                 const PylithInt sOff_x[],
                                                 const PylithScalar s[],
                                                 const PylithScalar s_t[],
                                                 const PylithScalar s_x[],
                                                 const PylithInt aOff[],
                                                 const PylithInt aOff_x[],
                                                 const PylithScalar a[],
                                                 const PylithScalar a_t[],
                                                 const PylithScalar a_x[],
                                                 const PylithReal t,
                                                 const PylithScalar x[],
                                                 const PylithInt numConstants,
                                                 const PylithScalar constants[],
                                                 PylithScalar f1[]) {
    const PylithInt _dim = 3;

    // Incoming solution fields.
    const PylithInt i_disp = 0;

    // Incoming auxiliary fields.
    const PylithInt i_shearModulus = numA-5;
    const PylithInt i_bulkModulus = numA-4;
    const PylithInt i_maxwellTime = numA-3;
    const PylithInt i_viscousStrain = numA-2;
    const PylithInt i_totalStrain = numA-1;

    assert(_dim == dim);
    assert(numS >= 1);
    assert(numA >= 6);
    assert(sOff);
    assert(sOff[i_disp] >= 0);
    assert(sOff_x);
    assert(sOff_x[i_disp] >= 0);
    assert(aOff);
    assert(aOff[i_shearModulus] >= 0);
    assert(aOff[i_bulkModulus] >= 0);
    assert(aOff[i_maxwellTime] >= 0);
    assert(aOff[i_viscousStrain] >= 0);
    assert(aOff[i_totalStrain] >= 0);

    const PylithInt _numS = 1; // Number passed on to stress kernels.
    const PylithInt sOffDisp[1] = { sOff[i_disp] };
    const PylithInt sOffDisp_x[1] = { sOff_x[i_disp] };

    const PylithInt numAMean = 1; // Number passed to mean stress kernel.
    const PylithInt aOffMean[1] = { aOff[i_bulkModulus] };

    const PylithInt numADev = 4; // Number passed to deviatoric stress kernel.
    const PylithInt aOffDev[4] = {
        aOff[i_shearModulus], aOff[i_maxwellTime], aOff[i_viscousStrain], aOff[i_totalStrain]
    };

    PylithScalar stressTensor[9] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
    IsotropicLinearElasticity3D::meanStress(_dim, _numS, numAMean, sOffDisp, sOffDisp_x, s, s_t, s_x,
                                            aOffMean, NULL, a, a_t, NULL, t, x, numConstants, constants, stressTensor);
    deviatoricStress(_dim, _numS, numADev, sOffDisp, sOffDisp_x, s, s_t, s_x, aOffDev, NULL, a, a_t, NULL,
                     t, x, numConstants, constants, stressTensor);

    for (PylithInt i = 0; i < _dim*_dim; ++i) {
        f1[i] -= stressTensor[i];
    } // for
} // f1v


// ---------------------------------------------------------------------------------------------------------------------
// f1 function for isotropic linear Maxwell viscoelastic 3D material with reference
// stress and strain.
void
pylith::fekernels::IsotropicLinearMaxwell3D::f1v_refstate(const PylithInt dim,
                                                          const PylithInt numS,
                                                          const PylithInt numA,
                                                          const PylithInt sOff[],
                                                          const PylithInt sOff_x[],
                                                          const PylithScalar s[],
                                                          const PylithScalar s_t[],
                                                          const PylithScalar s_x[],
                                                          const PylithInt aOff[],
                                                          const PylithInt aOff_x[],
                                                          const PylithScalar a[],
                                                          const PylithScalar a_t[],
                                                          const PylithScalar a_x[],
                                                          const PylithReal t,
                                                          const PylithScalar x[],
                                                          const PylithInt numConstants,
                                                          const PylithScalar constants[],
                                                          PylithScalar f1[]) {
    const PylithInt _dim = 3;

    // Incoming solution fields.
    const PylithInt i_disp = 0;

    // Incoming auxiliary fields.
    const PylithInt i_rstress = numA-7;
    const PylithInt i_rstrain = numA-6;
    const PylithInt i_shearModulus = numA-5;
    const PylithInt i_bulkModulus = numA-4;
    const PylithInt i_maxwellTime = numA