matto.materials#
The material contract.
A material is a free-energy density W(F; fields, stimuli). The package builds F = variable(I + grad u) once, calls energy(), and takes the first Piola-Kirchhoff stress as diff(W, F). A material says up front which design fields it reads, which stimuli it needs and what shape they have, and which parameters it takes, so a mismatch with the input file is reported at construction instead of surfacing as a KeyError inside UFL.
Subclass Material, set the class attributes, write energy(). The class can live in the package, next to the input scripts, or in the input script itself.
- class matto.materials.base.Material(**parameters)[source]#
Bases:
object- fields = ()#
design fields the energy reads, by name; the input file sets which of them are optimized and which are prescribed
- stimuli = {}#
stimulus name -> shape, () for a scalar and (dim,) for a vector; the load cases supply the values
- parameters = {}#
parameter name -> default, or None when the caller must supply it
- internal_variables = {}#
history variables, name -> shape. Reserved for path-dependent models; check_requirements raises for a material that declares any, since history-dependent models are not supported.
- reference = ''#
where the model comes from
Hard-magnetic soft material, in 2D plane strain or 3D.
- class matto.materials.hmsm.HardMagneticSoftMaterial(**parameters)[source]#
Bases:
MaterialHard-magnetic soft material: a reinforced matrix with remanent magnetization.
The magnetic energy is linear in the applied flux density, -(1/mu0) phi (F B_rem) . B_app, with B_rem of fixed magnitude along the design direction theta.
Fields: rho (density), phi (particle fraction), theta (remanent direction). Stimulus: B_app, the applied flux density vector.
Works in 2D and 3D; pass dim=3 for a 3D problem. theta is one angle in both cases: in 3D the remanent magnetization lies in the x-y plane at that angle, and the applied field may point anywhere.
- fields = ('rho', 'phi', 'theta')#
design fields the energy reads, by name; the input file sets which of them are optimized and which are prescribed
- parameters = {'B_rem_mag': None, 'G0': None, 'dim': 2, 'eps_rho': 1e-06, 'mu0': None, 'p_rho': 3.0}#
parameter name -> default, or None when the caller must supply it
- reference = 'Galloway & Jha, Model-informed joint material-structural optimization of hard-magnetic soft materials, arXiv:2607.14397'#
where the model comes from
Liquid crystal elastomer, plane strain, small-strain energy.
- class matto.materials.lce.LiquidCrystalElastomer(**parameters)[source]#
Bases:
MaterialLiquid crystal elastomer: Saint Venant-Kirchhoff plus a nematic coupling.
The coupling is -1/2 beta dS (Q . E) with Q = 3 n n - I built on the programmed director angle theta. The stimulus is the activation, ramped from zero, which lowers the order parameter from S0: dS = S0 activation.
Fields: rho (density), phi (LCE fraction), theta (director). Stimulus: activation, scalar in [0, 1].
- fields = ('rho', 'phi', 'theta')#
design fields the energy reads, by name; the input file sets which of them are optimized and which are prescribed
- stimuli = {'activation': ()}#
stimulus name -> shape, () for a scalar and (dim,) for a vector; the load cases supply the values
- parameters = {'E_LCE': None, 'S0': None, 'beta': None, 'eps_rho': 1e-06, 'nu': None, 'p_phi': 3.0, 'p_rho': 3.0}#
parameter name -> default, or None when the caller must supply it
- reference = 'Barrera et al. 2024 (LCE energy used in the examples)'#
where the model comes from
Isotropic magneto-active elastomer in a silicone matrix, plane strain.
- class matto.materials.mae.MagnetoActiveElastomer(**parameters)[source]#
Bases:
MaterialIsotropic magneto-active elastomer in a silicone matrix.
The second Mooney-Rivlin coefficient of the active phase stiffens with the applied field; the two phases are mixed by the design fraction phi.
Fields: rho (density), phi (MAE fraction). Stimulus: h, the applied flux density mu0 times the field magnitude, as a scalar.
- fields = ('rho', 'phi')#
design fields the energy reads, by name; the input file sets which of them are optimized and which are prescribed
- stimuli = {'h': ()}#
stimulus name -> shape, () for a scalar and (dim,) for a vector; the load cases supply the values
- parameters = {'C1_Ga': None, 'C1_sil': None, 'C2_Ga': None, 'C2_sil': None, 'K': None, 'a1': None, 'a2': None, 'b1': None, 'b2': None, 'eps_rho': 1e-06, 'mu0': None, 'p_phi': 1.0, 'p_rho': 3.0}#
parameter name -> default, or None when the caller must supply it
- reference = 'Garai & Haldar, Int. J. Mech. Sci. 286 (2025) 109860, doi:10.1016/j.ijmecsci.2024.109860'#
where the model comes from
Anisotropic magneto-active elastomer in a silicone matrix, plane strain.
- class matto.materials.mae_aniso.AnisotropicMagnetoActiveElastomer(**parameters)[source]#
Bases:
MaterialAnisotropic magneto-active elastomer with particle chains, in silicone.
The chains lie along the design direction theta. The magnetic stiffening saturates with the field and scales with the alignment of the chains with the fixed magnetization direction theta_M. The two phases are mixed by the design fraction phi.
Fields: rho (density), phi (MAE fraction), theta (chain direction). Stimulus: h, applied field magnitude as a scalar.
- fields = ('rho', 'phi', 'theta')#
design fields the energy reads, by name; the input file sets which of them are optimized and which are prescribed
- stimuli = {'h': ()}#
stimulus name -> shape, () for a scalar and (dim,) for a vector; the load cases supply the values
- parameters = {'A_Ak': None, 'A_sil': None, 'K_Ak': None, 'K_sil': None, 'a_Ak': None, 'a_sil': None, 'b_Ak': None, 'b_sil': None, 'delta_theta': 1e-06, 'eps_rho': 1e-06, 'hs': None, 'p_phi': 1.0, 'p_rho': 3.0, 'r': None, 's': None, 'theta_M': 0.0}#
parameter name -> default, or None when the caller must supply it
- reference = 'Akbari & Khajehsaeid, Smart Mater. Struct. 30 (2021) 015008, doi:10.1088/1361-665X/abc72f'#
where the model comes from
Linear elasticity as a stored energy.
- class matto.materials.linear.LinearElastic(**parameters)[source]#
Bases:
MaterialSmall-strain isotropic linear elasticity, plane strain in 2D.
W = 1/2 lambda tr(e)^2 + mu e:e with e = sym(grad u), scaled by the SIMP density interpolation.
Fields: rho. No stimuli.
- fields = ('rho',)#
design fields the energy reads, by name; the input file sets which of them are optimized and which are prescribed
- stimuli = {}#
stimulus name -> shape, () for a scalar and (dim,) for a vector; the load cases supply the values
- parameters = {'E': None, 'eps_rho': 1e-06, 'nu': None, 'p_rho': 3.0}#
parameter name -> default, or None when the caller must supply it
Kinematic quantities the material models share.
- class matto.materials.kinematics.IsochoricInvariants(J, Cbar, I1bar, I2bar)#
- Cbar#
Alias for field number 1
- I1bar#
Alias for field number 2
- I2bar#
Alias for field number 3
- J#
Alias for field number 0
- matto.materials.kinematics.plane_strain_3d(F2)[source]#
Embed an in-plane 2x2 deformation gradient as 3x3 plane strain.
- matto.materials.kinematics.isochoric_invariants(F)[source]#
J, the isochoric right Cauchy-Green tensor and its two invariants.
- matto.materials.kinematics.director(theta, dim=2)[source]#
Unit vector at angle theta from the first axis, in the plane.
Design-field interpolation the material models share.
- matto.materials.interpolation.simp(rho, p, eps)[source]#
Solid isotropic material with penalization, eps + (1 - eps) rho^p.
- matto.materials.interpolation.two_phase(W_active, W_matrix, phi_scale)[source]#
Mix an active phase into a matrix by the penalized fraction.
Consistency checks any material should pass, for use in its tests.
check_material() puts the model on a small mesh with an affine displacement, so the deformation gradient is exactly what was asked for, and checks three things at zero stimulus and at the given one.
The reference configuration is stress-free: with u = 0 and no stimulus the internal-force vector vanishes.
Frame indifference: W(Q F) = W(F) for a rotation Q, with any in-plane vector stimulus rotated along.
A moderate stretch raises the stored energy at zero stimulus: W(F) >= W(I) for one stretch F.
Run it on a new material before running an optimization with it.
- matto.materials.testing.check_material(material, field_values=None, stimulus_values=None, comm=mpi4py.MPI.COMM_WORLD, stretch=None, rotation=0.7, rel_tol=1e-08, dim=2, frame_indifference=True)[source]#
Raise AssertionError with a message naming the failed check.
- Parameters:
field_values – name -> constant value for each field the material reads; defaults cover rho, phi, theta.
stimulus_values – name -> value; defaults to zero for every stimulus.
dim – 2 or 3, the dimension the material is meant for.
frame_indifference – skip check 2 for a small-strain model that is not objective by construction.