pub struct Substance {
pub name: String,
pub density: Density,
pub thermal: Option<ThermalProps>,
pub mechanical: Option<MechanicalProps>,
pub acoustic: Option<AcousticProps>,
}Expand description
A material, as much of it as is known.
Fields§
§name: StringWhat it is called. Free text: a catalogue designation, a common name, whatever the caller will recognise in a violation message.
density: Densitykg·m⁻³. The one property everything has, which is why it is not optional.
thermal: Option<ThermalProps>Conductivity, specific heat, emissivity and a service limit, if they are known.
Optional because a substance is often only known as far as it needed to be. A domain
asking for what is not here gets None rather than a plausible default, which is the
difference between “unknown” and “zero”.
mechanical: Option<MechanicalProps>Stiffness, restitution and friction, if they are known.
acoustic: Option<AcousticProps>Sound speed and absorption, if they are known.
Implementations§
Source§impl Substance
impl Substance
Sourcepub fn diffusivity(&self) -> Option<Diffusivity>
pub fn diffusivity(&self) -> Option<Diffusivity>
Thermal diffusivity, α = k / (ρ c_p) — the m²/s that decides how fast a
temperature front moves, as opposed to how much heat flows.
This is the number that sets an explicit heat solver’s stability limit
(dt < dx²/2α), so a thermal domain asks for it before it can say how big
a step it can take.
Sourcepub fn heat_capacity(&self, volume: Volume) -> Option<HeatCapacity>
pub fn heat_capacity(&self, volume: Volume) -> Option<HeatCapacity>
Heat capacity of a given volume of this substance.
Sourcepub fn expansion_of(&self, length: Length, rise: Temperature) -> Option<Length>
pub fn expansion_of(&self, length: Length, rise: Temperature) -> Option<Length>
How much a length of this substance grows for a temperature rise. Linear, which is a good approximation for the tens of kelvin an instrument sees and a poor one for hundreds.
Sourcepub fn constrained_stress(&self, rise: Temperature) -> Option<Pressure>
pub fn constrained_stress(&self, rise: Temperature) -> Option<Pressure>
Stress produced by preventing that expansion — the reason a lens bonded rigidly into a metal mount cracks when it warms up.
σ = E α ΔT, independent of size, which is why scaling the part down does
not help.
Sourcepub fn survives(&self, rise: Temperature) -> Option<bool>
pub fn survives(&self, rise: Temperature) -> Option<bool>
Whether that stress would break it.
Sourcepub fn borosilicate_crown() -> Substance
pub fn borosilicate_crown() -> Substance
N-BK7, the borosilicate crown that most of an optical bench is made of.
Sourcepub fn aluminium_6061() -> Substance
pub fn aluminium_6061() -> Substance
6061 aluminium: what the mount holding the glass is made of, and the reason a mount-and-lens pair moves when the room does — its expansion is three times the glass’s.
Sourcepub fn with_emissivity(self, emissivity: f64) -> Substance
pub fn with_emissivity(self, emissivity: f64) -> Substance
The same substance with a different surface finish.
Emissivity is a property of the surface and not of the material, so anodised aluminium is
not a new entry in the catalogue — it is aluminium_6061().with_emissivity(0.9). The
factor of ten between polished and anodised 6061 lands squarely on the radiative loss
path, which is the same order as still-air convection at room temperature.
Clamped to 0..=1: a surface cannot radiate more than a blackbody, and a negative
emissivity would make a body warm itself.
Does nothing to a substance whose thermal properties are unknown, because None means
unknown rather than zero and inventing three of the four fields to set the fourth would
be worse than declining.
Sourcepub fn with_specific_heat(self, specific_heat: SpecificHeat) -> Substance
pub fn with_specific_heat(self, specific_heat: SpecificHeat) -> Substance
The same substance with a different heat capacity.
For the assembly case: a motor, a populated board, a printed part with infill. The bulk
c_p of a mixture is not the c_p of its main constituent, and this is the field where
that difference is worth a factor of two.
Does nothing to a substance whose thermal properties are unknown, for the reason in
Substance::with_emissivity.
Sourcepub fn copper() -> Substance
pub fn copper() -> Substance
Electrolytic tough-pitch copper: windings, heat spreaders, planes.
The values are uncontroversial to three figures. The emissivity is not: this is bright
polished copper at 0.04, and copper oxidises — a tarnished surface runs 0.4 to 0.8, a
factor of fifteen on the radiative path. If the part has been in air for a week, say so
with Substance::with_emissivity.
Sourcepub fn fr4() -> Substance
pub fn fr4() -> Substance
FR-4 glass-epoxy laminate: the board a driver sits on.
The conductivity is the through-plane one, 0.3 W/m/K, and that is the number a
designer wants because it is the one heat has to cross to reach the far side. In-plane it
is nearer 0.8, because the copper-free glass weave conducts better along its fibres —
a factor of about three, and ThermalProps carries one scalar, so the choice has to be
stated rather than averaged. Any real board is dominated by its copper pour anyway, which
is not laminate at all.
The expansion is likewise in-plane, 14 ppm/K. Through-thickness FR-4 expands four to five times faster and goes higher again above its glass transition, which is what breaks plated through-holes; that regime is not modelled here.
Sourcepub fn electrical_steel() -> Substance
pub fn electrical_steel() -> Substance
Non-oriented silicon electrical steel: motor and transformer laminations.
Grade-dependent, and the spread is wide. Silicon content trades core loss against conductivity: 25 W/m/K here is mid-range for non-oriented sheet, and grades run from about 20 to 30. Stacked laminations conduct far worse across the stack than the sheet does, because the interlaminar varnish dominates — a stack is not this substance at all, and treating it as one overstates the conduction out of a motor.
Emissivity 0.3 is varnished sheet; bare mill finish is lower and rusty is much higher.
Sourcepub fn pla() -> Substance
pub fn pla() -> Substance
Solid cast PLA: printed structure, if it were solid, which it is not.
A printed part is not this substance. Infill and layer adhesion move the effective conductivity and density more than the polymer chemistry does: at 20% infill the density is a fifth of this and the through-layer conductivity is lower again, because the path crosses voids and weld lines rather than bulk. Scale the density by the infill fraction at the very least, and treat the conductivity as an upper bound.
That is not a caveat about precision. It is the difference between a part that survives
and one that creeps: PLA softens around 60 °C, and Substance::survives is checking
against a number the print may not reach in practice.