Materials¶
A material is a MaterialProperties model: a display name, a registry tag, and four groups of properties. Each property is a function of the operating point that returns a pint quantity, so a value carries its unit from the material definition to the sif file, and a temperature-dependent law stays one object. The mesher matches each body to a material by its Material tag, and the sif writer turns the material into an Elmer Material block.
Assign materials by tag¶
import femforge as ff
from femforge.physical import Expression, Param, Static
class Ferrite(ff.materials.MaterialProperties):
"""A soft ferrite whose thermal conductivity falls with temperature."""
def __init__(self) -> None:
super().__init__()
self.name = "Soft Ferrite"
self.tag = "Ferrite"
self.magnetic.rel_permeability = Static(value=2000 * ff.U.dimensionless)
self.electrical.conductivity = Static(value=0.1 * ff.U.S / ff.U.m)
self.thermal.conductivity = Expression(
param_dims={"temperature": "[temperature]"},
result_units="W/(m*K)",
body=4.0 * (1.0 - 0.002 * (Param(name="temperature") - 293.15)),
)
ff.materials.register_material("Ferrite", Ferrite)
domain = ff.DomainConfig(
materials=[
ff.materials.Air(),
ff.materials.N52(),
ff.materials.Steel_1080(),
ff.materials.material("Ferrite"),
],
)
DomainConfig.materials lists the candidates. A body tagged Material=Ferrite gets the material whose tag is Ferrite, ignoring case. A body whose tag matches no candidate stops the mesh with an error. See Geometry and tags.
The catalogue¶
| Class | Tag | What it models |
|---|---|---|
| Air | Air |
Dry air at room temperature: μr = 1, near-zero conductivity. |
| Copper | Copper |
Annealed copper. Conductivity follows σ(T) = σ_ref / (1 + α·(T − 293.15 K)) with σ_ref = 5.96e7 S/m and α = 3.93e-3 1/K. |
| FR4 | FR4 |
The glass-epoxy laminate of printed circuit boards: εr = 4.5, glass transition at 130 °C. |
| N52 | N52 |
Sintered NdFeB, B_r = 1.48 T and H_cb = 955 kA/m at 20 °C. |
| N42 | N42 |
Sintered NdFeB, B_r = 1.30 T and H_cb = 915 kA/m at 20 °C. |
| Neodymium | yours | The base of the NdFeB grades. Pass name, tag, remanence_at_reference and coercivity_at_reference to define another grade. |
| Steel_1080 | Steel1080 |
Annealed high-carbon steel with a nonlinear B-H curve, or a linear μr when you pass rel_permeability. |
| Steel_316 | Steel316 |
Annealed austenitic stainless steel: μr = 1.008, effectively non-magnetic. |
The NdFeB grades scale remanence and coercivity linearly with temperature, with coefficients of −0.12 %/K and −0.60 %/K from 20 °C. A hot magnet drives a weaker field.
The registry holds every catalogue material by tag:
| Function | Returns |
|---|---|
material(tag) |
A fresh instance of the registered material. |
available_materials() |
The registered tags. |
all_materials() |
A fresh instance of every registered material. |
register_material(tag, factory) |
Nothing. It adds or replaces the material class under tag. |
Each call builds a new instance, so an edit to one config's material never leaks into another.
Property groups¶
| Group | Field | Elmer keyword |
|---|---|---|
mechanical |
density |
Density |
elastic_modulus |
Youngs Modulus |
|
yield_strength, ultimate_tensile_strength |
none | |
thermal |
conductivity |
Heat Conductivity |
specific_heat_capacity |
Heat Capacity |
|
convective_heat_transfer_coefficient, glass_transition_temperature |
none | |
magnetic |
rel_permeability |
Relative Permeability |
bh_curve |
H-B Curve |
|
remanence, coercivity |
none | |
electrical |
conductivity |
Electric Conductivity |
permittivity |
Relative Permittivity, written as ε/ε₀ |
|
resistivity, permeability |
none |
Fields without a keyword stay in the material for your own use and never reach the sif. Two of them change how the solve treats a body:
- A
remanencemarks the material as a permanent magnet. Its magnitude sets |M| = B_r/μ₀, and a Magnetization condition sets the direction. - A
conductivityof at least 1 S/m at the operating point marks the material as a conductor. Current-conduction solvers act only on conductors.
Units¶
Every quantity comes from one pint registry, ff.U.
| Write | Gives |
|---|---|
5 * ff.U.mm |
5 mm as a Quantity |
ff.quantity(1.2, "T") |
1.2 T as a typed Quantity |
ff.quantity(300, "kelvin") |
300 K |
q.to("A/m").magnitude |
The magnitude of q in A/m, as a float |
Prefer a string for composite units, such as ff.quantity(2.0, "newton * meter"). Each property and condition field declares a dimensionality and rejects a quantity of another one: a conductivity given in kelvin raises as soon as you set it, long before Elmer runs. The sif writer converts every value to SI.
Property functions¶
A property is a PropertyFunction: it declares its parameters (name to dimensionality) and returns a quantity when called with them.
| Kind | Parameters | Defined by | Serializes | Emits as a field-dependent sif value |
|---|---|---|---|---|
| Static | none | A constant value |
yes | no, a constant |
| Calibration | one | Sample points, interpolated linear, nearest or cubic (monotone) |
yes | yes, as an interpolation table |
| Expression | any | An expression tree built from Param and arithmetic |
yes | yes, as a MATC expression |
| ClosedForm | any | A Python callable, quantities in and out | no | no |
A calibration outside its sample range raises a PropertyRangeError unless you set extrapolate=True, which clamps to the end samples. A missing parameter raises PropertyParameterError, and a parameter of the wrong dimensionality raises PropertyDimensionError.
An Expression body binds each parameter as its SI magnitude, so Param(name="temperature") is in kelvin, and the body returns a magnitude in result_units. Prefer it over ClosedForm whenever the law is arithmetic: it saves with the config and it can reach Elmer as a law.
Field-dependent properties¶
The sif writer evaluates a property in one of two ways:
| Physics | A property of temperature becomes |
|---|---|
THERMAL, JOULE_HEATING |
A sif expression on Elmer's solved Temperature, so the property varies across the model. |
| Every other physics | One value at the operating point, by default 300 K. |
Under thermal physics, a property that depends on temperature and another parameter raises, and so does a ClosedForm of temperature, since Python code cannot become a sif expression.
The operating point belongs to the solver stack. To evaluate the magnets of a magnetostatic solve at 80 °C, set it on the customized stack:
import femforge as ff
config = ff.SimulationConfig(mesh=ff.MeshConfig(step="motor.step"))
config.customize_physics().operating_point.temperature = ff.quantity(353.15, "kelvin")
See Conditions and physics for the solver stack.
Nonlinear steel¶
Steel_1080() carries its normal magnetization curve as bh_curve, a one-parameter Calibration of H over flux_density with monotone cubic interpolation. The sif receives it as an H-B Curve table with Real Monotone Cubic, and Elmer evaluates it at the local |B|. The magnetic solve becomes nonlinear, and the magnetostatic presets allow 50 nonlinear iterations.
Steel_1080(rel_permeability=500.0) drops the curve and freezes a linear μr. Use the linear mode for a quick solve, or when the steel stays well below its knee near 1.5 T. Use the curve when the steel saturates.
How a material reaches Elmer¶
Each distinct material becomes one Elmer Material block that its bodies share. Under the magnetic physics, a magnet body gets its own block, because it carries its Magnetization vector. Each solver in the stack names the keywords a body must supply, and the sif writer checks them before writing:
| Physics | Required keywords |
|---|---|
MAGNETOSTATICS |
Relative Permeability, or an H-B Curve in its place |
THERMAL |
Heat Conductivity |
ELECTROSTATICS |
Relative Permittivity |
CURRENT_CONDUCTION |
Electric Conductivity on conductors |
JOULE_HEATING |
Heat Conductivity, plus Electric Conductivity on conductors |
COIL_MAGNETOSTATICS |
Relative Permeability, plus Electric Conductivity on conductors |
LINEAR_ELASTICITY |
none checked |
A missing keyword raises one error that names the body, the material and the keywords. Under an axisymmetric frame, MAGNETOSTATICS solves with the same requirement.
Reference¶
- Materials API: the property model, the catalogue and the registry.
- Physical API: property functions, expressions and units.