Expand description
Where two domains meet, and how a quantity crosses with its place intact.
Exchange carries one number per channel per step. Four
domains were built on that and none of them minded, but the reason is not that the
design was sufficient — it is that none of them ever had to share a place. A
dichroic absorbing 96 mW hands the whole lot to one lumped mass, because there is no
way to say which part of it got hot.
That is the physics an instrument simulator actually needs. A coating heats where the beam lands, the heat spreads through the glass, and the temperature field it leaves changes the refractive index. Every step of that needs optics and heat to agree about a surface rather than about a total.
§One discretisation, shared, rather than two and an interpolation
The temptation is to let each domain keep its own mesh and interpolate between them. That is where energy goes missing: a resampling that is not conservative loses or invents some, and it does so quietly, in a step that looks like bookkeeping.
So an Interface is a boundary cut into faces that both sides address. A
publisher offers a Flux over those faces and a consumer takes it over the same
ones. A face-count mismatch is refused rather than papered over, and if a caller
genuinely needs to cross discretisations they say so with Flux::resample, which
conserves the total by construction rather than by hoping.
§What this makes auditable that was not
The first design pass said the interface between two discretisations is exactly where
conservation breaks, and then built a coupling whose interface was a single number —
so the check it argued for could not be written. Now it can:
Exchange::audit_transfers names the face
that was left holding something, not just the channel.