Materials#
Material properties are set on femorph_solver.Model either
through assign() (the native API), which
takes a property dict and stores it under a material id, or — for
users porting an existing deck — through the APDL-dialect wrapper
femorph_solver.interop.mapdl.APDL.
Native API#
The native primitive is Model.assign(), which declares an
element kernel and its material in a single call:
import femorph_solver as fs
model = fs.Model.from_grid(grid)
model.assign(
fs.ELEMENTS.HEX8,
{"EX": 2.1e11, "PRXY": 0.30, "DENS": 7850.0},
)
The first argument is an ELEMENTS spec; the
second is a property dict whose keys are the scalar property names
listed below. Units are whatever’s consistent across EX, the
element geometry, and any forces — femorph-solver does not track
units.
Supported properties#
The femorph_solver.MaterialProperty enum enumerates every
property name femorph-solver’s element kernels currently look up.
Accepting the enum member or the raw string is equivalent:
Token |
Meaning |
Used by |
|---|---|---|
|
Young’s modulus |
All solids, beams, shells, plane, truss. |
|
Poisson’s ratio (isotropic) |
All solids, beams, shells, plane. |
|
Mass density |
Every element that contributes to \(M\). |
|
Transverse shear modulus |
Reserved for future shell / beam transverse-shear paths. |
|
Thermal expansion coefficient |
Reserved for future thermal-strain coupling. |
from femorph_solver import MaterialProperty as MP
model.assign(fs.ELEMENTS.HEX8, {MP.EX: 2.1e11, MP.PRXY: 0.30, MP.DENS: 7850.0})
Multiple materials#
Pass mat_id= to Model.assign() to register more than one
material:
model.assign(fs.ELEMENTS.HEX8,
{"EX": 2.1e11, "PRXY": 0.30, "DENS": 7850.0},
mat_id=1)
model.assign(fs.ELEMENTS.HEX8,
{"EX": 7.0e10, "PRXY": 0.33, "DENS": 2700.0},
mat_id=2)
When a foreign deck is loaded (CDB / BDF / INP / FEM), each element arrives with a material id already stamped; the readers populate the material table for you.
Introspection#
The current material table is available as Model.materials:
model.materials
# {1: {'EX': 2.1e11, 'PRXY': 0.3, 'DENS': 7850.0},
# 2: {'EX': 7.0e10, 'PRXY': 0.33, 'DENS': 2700.0}}
Element kernels read the matching dict directly, so any additional
scalar you stash under a known property name is visible to them.
Per-element-class formulation knobs (e.g. _HEX8_INTEGRATION,
_HEX20_INTEGRATION, _HEX20_MASS, _QUAD4_PLANE_MODE,
_PYR13_INTEGRATION, _PYR13_PYRAMID_RULE) live in the same
dict; the cleanest way to set them is via the ELEMENTS spec
classes (see the element library), which
write the appropriate underscore-prefixed key for you.
Limitations (today)#
Linear isotropic only. Orthotropic / anisotropic tensors, rate dependence, plasticity, temperature-dependent curves are not yet implemented.
Tensor-valued constitutive blocks (
DMATRIX/ANELin the foreign-deck readers) aren’t round-tripped yet; they are parsed on load but ignored during assembly.
See also#
Real constants and sections — per-element-type geometric data.
Element library — which properties each element class reads.