====== User defined materials ====== This section explains how any user can define its own constitutive equation in Metafor (usermat or user-defined feature). The idea is to create a Python class (e.g., in the input file) that derives from the C++ class `PythonHyperMaterial` and overwrites the following functions: * ''def PythonHyperMaterial.__init__(self, _no):'' with ''_no'' being the material number chosen. * ''def computeStressPython(self, FTotal):'' * **Input:** The total deformation gradient ''FTotal'', sent from C++ to Python through a ''std::vector'' [F11, F12, F13, F21, F22, F23, F31, F32, F33], hence ''FTotal[0] = F11'', etc. * **Output:** The Cauchy stress, in the current configuration, returned from Python to C++ through a Python list [Sig11, Sig22, Sig33, Sig12, Sig13, Sig23] The relation between stress and strain is defined by the user. Selective integration with pressure report ''SRIPR'' for the integration will not work. The material tangent moduli is automatically approximated using finite central difference. ===== Example: A NeoHookean Model ===== from wrap import * import numpy as np metafor = None class PythonHyperMaterial: def __init__(self, _no): self._no = _no class UserMat(PythonHyperMaterial): def __init__(self, _no): PythonHyperMaterial.__init__(self, _no) def computeStressPython(self, FTotal): C1 = 0.5 K = 1000 F = np.array(FTotal).reshape(3, 3) J = np.linalg.det(FTotal) Fbar = J**(-1/3) * F Bbar = np.dot(Fbar.T, Fbar) cauchyStress = C1/J * Bbar + (-1/3 * np.trace(Bbar) + K*(J-1)) * np.identity(3) return [cauchyStress[0, 0], cauchyStress[1, 1], cauchyStress[2, 2], cauchyStress[0, 1], cauchyStress[0, 2], cauchyStress[1, 2]] def getMetafor(_p): # ... some code ... # myNeoHookean = UserMat(1) domain.getMaterialSet().add(myNeoHookean) # ... some code ... # elementsProps = ElementProperties(Volume2DElement) elementsProps.put(MATERIAL, 1) # ... some code ... # return metafor