STAR
Cal STAR — firmware, DAQ server, and engine design
Loading...
Searching...
No Matches
feedtwin.comps.base.HydraulicComponent Class Reference
Inheritance diagram for feedtwin.comps.base.HydraulicComponent:
[legend]

Public Member Functions

None __init__ (self, ComponentInstance instance)
str id (self)
str type (self)
float pressure_drop (self, float mdot, FlowConditions flow)
float static_head (self, FlowConditions flow)
float total_dp (self, float mdot, FlowConditions flow)
float signal (self, FlowConditions flow, str name, float default=1.0)
dict[str, float] diagnostics (self, float mdot, FlowConditions flow)
bool isolates (self, Mapping[str, float]|None signals=None)
float|None flow_ceiling (self, FlowConditions flow)
float|None pinned_flow (self, float dp_available, FlowConditions flow)
bool is_choked (self, float dp_available, FlowConditions flow)
list[Violation] check (self)
int n_residuals (self)
Sequence[float] residuals (self, EvalContext ctx)
Mapping[str, float] outputs (self, EvalContext ctx)
FlowConditions conditions (self, PortState port, Mapping[str, float] signals)
str __repr__ (self)

Public Attributes

 instance = instance
 p = instance.si_params()
 opt = dict(instance.options)

Static Public Attributes

str inlet_port = "inlet"
str outlet_port = "outlet"
bool symmetric = False
 conditions_provider = None

Detailed Description

Base for a component whose loss is a function of flow.

Subclasses implement :meth:`pressure_drop` and, optionally,
:meth:`diagnostics`. Everything else -- the residual adapter, parameter
resolution, reporting -- comes from here.

Definition at line 154 of file base.py.

Constructor & Destructor Documentation

◆ __init__()

None feedtwin.comps.base.HydraulicComponent.__init__ ( self,
ComponentInstance instance )

Definition at line 173 of file base.py.

Member Function Documentation

◆ __repr__()

str feedtwin.comps.base.HydraulicComponent.__repr__ ( self)

Definition at line 373 of file base.py.

◆ check()

list[Violation] feedtwin.comps.base.HydraulicComponent.check ( self)
Design limits this component's configuration breaks.

Configuration only -- nothing here depends on the operating point, so it
can be run the moment a network is loaded and long before it is solved.
Bend radius is the case that motivated it: a line bent tighter than its
tube allows is a fabrication problem, and finding out at the bender is
expensive.

Reimplemented in feedtwin.comps.elements.Bend, feedtwin.comps.elements.FlexHose, feedtwin.comps.manifold.Manifold, feedtwin.comps.regulator.Regulator, feedtwin.comps.relief.ReliefValve, and feedtwin.engine.component.InjectorLeg.

Definition at line 320 of file base.py.

◆ conditions()

FlowConditions feedtwin.comps.base.HydraulicComponent.conditions ( self,
PortState port,
Mapping[str, float] signals )

Definition at line 362 of file base.py.

References conditions_provider.

Referenced by outputs(), and residuals().

◆ diagnostics()

dict[str, float] feedtwin.comps.base.HydraulicComponent.diagnostics ( self,
float mdot,
FlowConditions flow )

◆ flow_ceiling()

float | None feedtwin.comps.base.HydraulicComponent.flow_ceiling ( self,
FlowConditions flow )
Largest mass flow this component can pass [kg/s], or ``None``.

``None`` means "no ceiling", which is true of every liquid component
here and of any gas element below its critical pressure ratio.

A ceiling changes what equation the network solver writes for this
branch, which is why it lives on the base class rather than inside the
one component that has one. See :meth:`is_choked`.

Reimplemented in feedtwin.comps.elements.CheckValve, feedtwin.comps.elements.Valve, feedtwin.comps.gas.GasOrifice, feedtwin.comps.regulator.Regulator, and feedtwin.comps.relief.ReliefValve.

Definition at line 279 of file base.py.

Referenced by feedtwin.comps.relief.ReliefValve.diagnostics().

◆ id()

str feedtwin.comps.base.HydraulicComponent.id ( self)

◆ is_choked()

bool feedtwin.comps.base.HydraulicComponent.is_choked ( self,
float dp_available,
FlowConditions flow )
Whether ``dp_available`` puts this component past its choking point.

Load-bearing for the solver, not just a report. A branch's usual
equation is ``(p_up - p_dn) - dp(mdot) = 0``, which presumes the drop
is a function of the flow. Past choking it is not: mass flow stops
depending on downstream pressure entirely, and the drop can be anything
at or above the critical value. The relation is no longer invertible
and Newton, asked to invert it anyway, runs away -- which is exactly
what a relief valve venting to atmosphere does to a naive solver.

When this returns true the solver writes ``mdot = flow_ceiling``
instead, and reports the branch as choked.

Reimplemented in feedtwin.comps.elements.CheckValve, feedtwin.comps.elements.Valve, feedtwin.comps.gas.GasOrifice, and feedtwin.comps.regulator.Regulator.

Definition at line 304 of file base.py.

Referenced by feedtwin.comps.regulator.Regulator.diagnostics().

◆ isolates()

bool feedtwin.comps.base.HydraulicComponent.isolates ( self,
Mapping[str, float] | None signals = None )
Whether this component is commanded fully shut.

Load-bearing for the solver, not a report. A shut valve used to be
modelled as a very small ``Cv`` on the reasoning that a real seat leaks
and that an exactly-zero capacity makes the network singular. Both
halves of that were wrong in the way that matters.

A branch with a nearly-zero capacity has a nearly-zero derivative, so
Newton cannot move its row: the solve stalls with the residual parked
just above tolerance, and the pressures either side of a shut valve come
back somewhere in between rather than held. On a stand where most valves
are shut most of the time -- which is every stand, most of the time --
that is most of the network.

Reported shut, the branch is *removed* from the unknowns and its ends
are peeled as ordinary stubs, which is both what the hardware does and
what the numerics want. Seat leakage is a real effect and belongs in a
leak-rate model that runs when somebody asks about it, not in the
conditioning of every solve.

Reimplemented in feedtwin.comps.elements.Valve, and feedtwin.comps.relief.ReliefValve.

Definition at line 254 of file base.py.

◆ n_residuals()

int feedtwin.comps.base.HydraulicComponent.n_residuals ( self)

Definition at line 334 of file base.py.

◆ outputs()

◆ pinned_flow()

float | None feedtwin.comps.base.HydraulicComponent.pinned_flow ( self,
float dp_available,
FlowConditions flow )
A flow this component pins at this drop, whatever downstream does.

``None`` -- every component here but an opt-in one -- leaves the branch to
:meth:`flow_ceiling` and :meth:`is_choked`. A component whose choked
flow depends on *which* way it is past its limit returns the flow here:
the compressible regulator seat (:mod:`feedtwin.comps.regulator`) is
both a regulator that shuts (pinned at zero, by the ceiling) and a seat
that chokes wide open (pinned at its capacity, by this). The solver asks
this first and writes ``mdot = pinned`` when it answers.

Reimplemented in feedtwin.comps.regulator.Regulator.

Definition at line 291 of file base.py.

◆ pressure_drop()

float feedtwin.comps.base.HydraulicComponent.pressure_drop ( self,
float mdot,
FlowConditions flow )
Flow-dependent pressure loss [Pa]. Always non-negative.

A *loss*: it opposes the flow, so it lowers the downstream pressure
whichever way the fluid is going. Reverse flow is each component's own
business -- symmetric for a pipe, very much not for a check valve.

Anything that does **not** depend on the direction of flow belongs in
:meth:`static_head`, not here. See that method for why the distinction
is load-bearing rather than tidy.

Reimplemented in feedtwin.comps.elements.Bend, feedtwin.comps.elements.CheckValve, feedtwin.comps.elements.Fitting, feedtwin.comps.elements.FlexHose, feedtwin.comps.elements.MeasuredElement, feedtwin.comps.elements.OrificeCd, feedtwin.comps.elements.OrificeISO5167, feedtwin.comps.elements.Pipe, feedtwin.comps.elements.SegmentedPipe, feedtwin.comps.elements.Valve, feedtwin.comps.gas.GasOrifice, feedtwin.comps.manifold.Manifold, feedtwin.comps.manifold.ManifoldBranch, feedtwin.comps.regulator.IdealRegulator, feedtwin.comps.regulator.Regulator, feedtwin.comps.relief.ReliefValve, and feedtwin.engine.component.InjectorLeg.

Definition at line 190 of file base.py.

Referenced by feedtwin.comps.elements.CheckValve.diagnostics(), feedtwin.comps.elements.MeasuredElement.diagnostics(), feedtwin.comps.elements.OrificeCd.diagnostics(), feedtwin.comps.elements.OrificeISO5167.diagnostics(), feedtwin.comps.elements.SegmentedPipe.diagnostics(), feedtwin.comps.elements.Valve.diagnostics(), feedtwin.comps.gas.GasOrifice.diagnostics(), feedtwin.comps.manifold.ManifoldBranch.diagnostics(), feedtwin.comps.regulator.Regulator.diagnostics(), feedtwin.comps.relief.ReliefValve.diagnostics(), feedtwin.engine.component.InjectorLeg.diagnostics(), feedtwin.comps.regulator.Regulator.envelope_violations(), total_dp(), and feedtwin.comps.regulator.Regulator.total_dp().

◆ residuals()

Sequence[float] feedtwin.comps.base.HydraulicComponent.residuals ( self,
EvalContext ctx )
``(p_in - p_out) - dp(mdot) = 0``.

Requires ``conditions`` to have been provided, because the fluid state
is not in the context yet -- Phase 04 decides how a solver supplies it.

Definition at line 337 of file base.py.

References conditions(), and total_dp().

◆ signal()

float feedtwin.comps.base.HydraulicComponent.signal ( self,
FlowConditions flow,
str name,
float default = 1.0 )
One control input for *this* component.

Looks for ``"<this component's id>.<name>"`` first and falls back to a
bare ``"<name>"``. The qualified form is what a scenario with two main
valves needs -- reading an unqualified ``"command"`` means every valve
in the network moves together, which converges perfectly and models a
system nobody built. The bare fallback is kept so a single-actuator
test can stay terse.

Definition at line 229 of file base.py.

Referenced by feedtwin.comps.elements.Valve._gas(), feedtwin.comps.regulator.Regulator._gas_seat(), feedtwin.comps.elements.Valve._legacy_liquid_ceiling(), feedtwin.comps.regulator.Regulator.commanded_setpoint(), feedtwin.comps.elements.Valve.diagnostics(), feedtwin.comps.regulator.Regulator.diagnostics(), and feedtwin.comps.elements.Valve.pressure_drop().

◆ static_head()

float feedtwin.comps.base.HydraulicComponent.static_head ( self,
FlowConditions flow )
Flow-independent pressure change [Pa], signed. Zero for most things.

Elevation is the case that matters: ``rho g dz`` is set by where the
ends of a pipe are, and does not care which way the fluid is going. A
loss reverses sign with the flow; a static head does not.

Conflating the two is silently wrong exactly when it is hardest to
notice -- a network where a branch reverses, which is any recirculation
loop, any vent path, and most transients. Getting it wrong puts the
answer out by ``2 rho g dz`` on that branch, with everything still
converging and conserving mass.

Reimplemented in feedtwin.comps.elements.Pipe, feedtwin.comps.elements.SegmentedPipe, and feedtwin.comps.manifold.ManifoldBranch.

Definition at line 203 of file base.py.

Referenced by feedtwin.comps.elements.SegmentedPipe.diagnostics(), total_dp(), and feedtwin.comps.regulator.Regulator.total_dp().

◆ total_dp()

float feedtwin.comps.base.HydraulicComponent.total_dp ( self,
float mdot,
FlowConditions flow )
The pressure change a solver needs: ``p_upstream - p_downstream``.

Loss with the sign of the flow, plus static head with its own sign.
This is what network assembly consumes; :meth:`pressure_drop` is what
the validation tests check against published results.

Reimplemented in feedtwin.comps.regulator.Regulator.

Definition at line 218 of file base.py.

References pressure_drop(), and static_head().

Referenced by residuals().

◆ type()

Member Data Documentation

◆ conditions_provider

feedtwin.comps.base.HydraulicComponent.conditions_provider = None
static

Definition at line 358 of file base.py.

Referenced by conditions().

◆ inlet_port

str feedtwin.comps.base.HydraulicComponent.inlet_port = "inlet"
static

Definition at line 163 of file base.py.

◆ instance

◆ opt

◆ outlet_port

str feedtwin.comps.base.HydraulicComponent.outlet_port = "outlet"
static

Definition at line 164 of file base.py.

◆ p

feedtwin.comps.base.HydraulicComponent.p = instance.si_params()

Definition at line 177 of file base.py.

Referenced by feedtwin.comps.elements.OrificeCd._area(), feedtwin.comps.regulator.Regulator._creep(), feedtwin.comps.elements.Pipe._elevation(), feedtwin.comps.elements.Pipe._friction(), feedtwin.comps.elements.FlexHose._friction_factor(), feedtwin.comps.elements.Valve._gas(), feedtwin.comps.relief.ReliefValve._gas(), feedtwin.comps.elements.Valve._gas_choke(), feedtwin.comps.relief.ReliefValve._gas_choke(), feedtwin.comps.regulator.Regulator._gas_seat(), feedtwin.comps.gas.GasOrifice._geometry(), feedtwin.comps.elements.Bend._K(), feedtwin.comps.elements.Fitting._K(), feedtwin.comps.regulator.Regulator._rated_multiple(), feedtwin.comps.regulator.Regulator._seat_dp(), feedtwin.comps.elements.OrificeISO5167._solve_downstream(), feedtwin.comps.elements.Bend.check(), feedtwin.comps.elements.FlexHose.check(), feedtwin.comps.elements.Valve.choked_dp(), feedtwin.comps.regulator.Regulator.commanded_setpoint(), feedtwin.comps.elements.Bend.diagnostics(), feedtwin.comps.elements.CheckValve.diagnostics(), feedtwin.comps.elements.Fitting.diagnostics(), feedtwin.comps.elements.FlexHose.diagnostics(), feedtwin.comps.elements.OrificeCd.diagnostics(), feedtwin.comps.elements.OrificeISO5167.diagnostics(), feedtwin.comps.elements.Pipe.diagnostics(), feedtwin.comps.elements.Valve.diagnostics(), feedtwin.comps.gas.GasOrifice.diagnostics(), feedtwin.comps.regulator.Regulator.diagnostics(), feedtwin.comps.elements.Valve.effective_cv(), feedtwin.comps.regulator.Regulator.envelope_violations(), feedtwin.comps.relief.ReliefValve.full_lift_pressure(), feedtwin.comps.elements.CheckValve.is_choked(), feedtwin.comps.regulator.Regulator.lockup_pressure(), feedtwin.comps.regulator.CurveRegulator.outlet_setpoint(), feedtwin.comps.regulator.Regulator.outlet_setpoint(), feedtwin.comps.elements.Bend.pressure_drop(), feedtwin.comps.elements.CheckValve.pressure_drop(), feedtwin.comps.elements.Fitting.pressure_drop(), feedtwin.comps.elements.FlexHose.pressure_drop(), feedtwin.comps.elements.OrificeCd.pressure_drop(), feedtwin.comps.elements.Valve.pressure_drop(), feedtwin.comps.relief.ReliefValve.pressure_drop(), feedtwin.comps.relief.ReliefValve.rated_capacity(), feedtwin.comps.relief.ReliefValve.reseat_pressure(), feedtwin.comps.regulator.Regulator.seat_capacity(), feedtwin.comps.relief.ReliefValve.set_pressure(), and feedtwin.comps.regulator.Regulator.supply_effect().

◆ symmetric

bool feedtwin.comps.base.HydraulicComponent.symmetric = False
static

Definition at line 171 of file base.py.


The documentation for this class was generated from the following file:
  • lib/feedtwin/feedtwin/comps/base.py