Create a model#

A model encapsulates the material parameters and physics of a simulation (_Simu) and they are accessible in the EasyFEA.Models namespace.


Linear elastic models#

All elastic models expose a .C property: the stiffness tensor in Kelvin–Mandel notation, a symmetric positive-definite matrix that maps strains \(\boldsymbol{\varepsilon}\) to stresses \(\boldsymbol{\varsigma}\):

\[ \boldsymbol{\sigma} = \Crm \, \boldsymbol{\varepsilon} \]
  • In 2D: \(\Crm\) is \((3 \times 3)\), with components \([\sigma_{xx},\, \sigma_{yy},\, \sqrt{2}\,\sigma_{xy}]\).

  • In 3D: \(\Crm\) is \((6 \times 6)\), with components \([\sigma_{xx},\, \sigma_{yy},\, \sigma_{zz},\, \sqrt{2}\,\sigma_{yz},\, \sqrt{2}\,\sigma_{xz},\, \sqrt{2}\,\sigma_{xy}]\).

Isotropic#

Defined by Young’s modulus E and Poisson’s ratio v:

from EasyFEA import Models

# 2D plane stress (default), steel
mat = Models.Elastic.Isotropic(dim=2, E=210000, v=0.3, planeStress=True, thickness=1.0)

# 3D
mat3d = Models.Elastic.Isotropic(dim=3, E=210000, v=0.3)

planeStress=True (default) applies the plane-stress assumption in 2D. Set planeStress=False for plane strain.

TransverselyIsotropic#

One isotropic plane (T, R) with a distinct longitudinal direction L:

from EasyFEA import Models

mat = Models.Elastic.TransverselyIsotropic(
    dim=2,
    El=12000,    # longitudinal Young's modulus
    Et=800,      # transverse Young's modulus
    Gl=500,      # longitudinal shear modulus
    vl=0.3,      # longitudinal Poisson ratio
    vt=0.4,      # transverse Poisson ratio
    axis_l=(1, 0, 0),
    axis_t=(0, 1, 0),
)

Orthotropic#

Three distinct material axes, each with its own Young’s modulus, shear modulus, and Poisson ratio:

from EasyFEA import Models

mat = Models.Elastic.Orthotropic(
    dim=3,
    E1=12000, E2=800, E3=500,
    G23=200, G13=300, G12=400,
    v23=0.3, v13=0.25, v12=0.4,
    axis_1=(1, 0, 0),
    axis_2=(0, 1, 0),
)

Anisotropic#

Provide the full stiffness matrix C directly in the material basis:

import numpy as np
from EasyFEA import Models

C = np.eye(3) * 210000   # example — replace with your actual matrix
mat = Models.Elastic.Anisotropic(
    dim=2,
    C=C,
    useVoigtNotation=False,  # True if C is expressed in Voigt notation
    axis1=(1, 0, 0),
    axis2=(0, 1, 0),
)

Hyperelastic models#

NeoHookean#

from EasyFEA import Models

mat = Models.HyperElastic.NeoHookean(dim=2, K=100000, thickness=1.0)

MooneyRivlin#

from EasyFEA import Models

mat = Models.HyperElastic.MooneyRivlin(dim=2, K1=80000, K2=20000, K=0.0)

SaintVenantKirchhoff#

from EasyFEA import Models

E, nu = 210000.0, 0.3
lmbda = E * nu / ((1 + nu) * (1 - 2 * nu))
mu    = E / (2 * (1 + nu))

mat = Models.HyperElastic.SaintVenantKirchhoff(dim=3, lmbda=lmbda, mu=mu)

HolzapfelOgden#

For fiber-reinforced soft tissues with two fiber families:

import numpy as np
from EasyFEA import Models

mat = Models.HyperElastic.HolzapfelOgden(
    dim=3,
    C0=0.059, C1=8.0, C2=0.0,
    C3=18.6, C4=16.5, C5=0.0,
    C6=0.0, C7=0.0,
    K=100.0,
    Mu1=0.059, Mu2=0.059,
    T1=np.array([1, 0, 0]),   # fiber direction 1
    T2=np.array([0, 1, 0]),   # fiber direction 2
)

Thermal model#

Defined by thermal conductivity k and, for transient problems, heat capacity c:

from EasyFEA import Models

# static (k only)
mat = Models.Thermal(k=1.0)

# transient (k + c)
mat_transient = Models.Thermal(k=1.0, c=500.0, thickness=1.0)

Phase-field model#

PhaseField wraps an elastic model and adds the fracture parameters:

from EasyFEA import Models

mat_elas = Models.Elastic.Isotropic(dim=2, E=210000, v=0.3)

mat = Models.PhaseField(
    material=mat_elas,
    split=Models.PhaseField.SplitType.Bourdin,   # energy split
    regularization=Models.PhaseField.ReguType.AT2,
    Gc=0.07,   # critical energy release rate [J/m²]
    l0=0.01,   # half crack width [m]
)

WeakForms model#

WeakForms takes the bilinear and linear form functions defined with @BiLinearForm / @LinearForm decorators:

from EasyFEA.FEM import Field, BiLinearForm

field = Field(mesh.groupElem, dof_n=1)

@BiLinearForm
def a(u: Field, v: Field):
    return u.grad.dot(v.grad)

model = Models.WeakForms(field, computeK=a)