111 """One length of one bore, with whatever is fitted to it."""
114 method: str = DEFAULT_METHOD
115 bore: Param |
None =
None
116 length: Param |
None =
None
117 roughness: Param |
None =
None
118 elevation_change: Param |
None =
None
119 K: Param |
None =
None
120 length_basis: str =
"tube"
123 fittings: tuple[Fitting, ...] = ()
124 curve: Curve |
None =
None
125 """Measured Delta p against mdot. A :class:`~feedtwin.model.curve.Curve`,
126 so it carries its own units and provenance and is evaluated in SI like
127 every other curve in the library."""
131 return self.
curve is not None
135 """Flow diameter [m], or zero if the segment does not state one."""
136 return self.
bore.si
if self.
bore is not None else 0.0
140 """The length as written [m], whatever its basis."""
141 return self.
length.si
if self.
length is not None else 0.0
144 """Straight tube in this segment [m], with fitting bodies removed.
146 With ``length_basis == "overall"`` the stated length runs end to end, so
147 each fitting's body less its thread engagement comes out -- otherwise the
148 fittings are paid for twice, once as K and once as the tube they
151 This refuses to guess. If the basis is overall and any fitting has no
152 body length, the stated length is returned whole; the reader has already
153 warned about it. A partial subtraction is a wrong number that looks
154 careful, which is worse than a stated one that is flagged.
159 if any(f.length <= 0.0
for f
in self.
fittings):
161 bodies = sum((f.length - f.engagement) * f.count
for f
in self.
fittings)
162 return max(stated - bodies, 0.0)
165@dataclass(frozen=True, slots=True)