Measured data as a property source.
The point of this backend is that it sits *in front of* an equation of state and
covers only the region you actually measured. Inside that region your numbers
win; outside it, it raises :class:`OutOfRange` and the fluid's chain falls
through to the equation of state. Nobody writes the "do we have data here?"
branch, because the chain already is that branch::
tab = TabulatedProperties(
p=[...], T=[...], values={"rho": rho_grid}, source="CF-2026-03"
)
n2 = Fluid("nitrogen", chain=[tab, "bicubic", "heos"])
This is the property-layer half of a principle that runs through the whole
project (Decision 02 in the plan): anything modelled can be replaced by
something measured, with the provenance recorded. It is here in Phase 01 rather
than bolted on at Phase 12 because a seam added after the fact is a seam every
existing call site has to be audited against.
A blended fluid -- a real ullage of pressurant over propellant vapour -- is a
mixture, not a table, and belongs to a mixture backend rather than to this one.