solprop.gasflow#
Steady gas flow in a hollow fibre: the fill, the choked end and the flow regime.
A hollow fibre filled from gas cells at its ends carries a steady laminar flow. For an
isothermal ideal gas in Poiseuille flow the mass flow is constant along each stage and
proportional to \(a^4\,p\,\mathrm{d}p/\mathrm{d}z\), which makes \(p^2\) linear
in the hydraulic resistance \(R = \int a^{-4}\,\mathrm{d}z\)
(solprop.profiles.PressureGradient, Pennetta et al., APL Photonics 4, 056105
(2019), eq. 6). The PV throughput of a stage is
Choked ends. An end that exhausts into a pumped chamber cannot pass more than the
sonic throughput \(p_e \pi a_e^2 c\). Equating the two, as HiSol.jl’s
choked_pressure does (which then drops \(p_e^2\)), gives
solved here in that non-cancelling form. steady_fill() applies
\(\max(\text{declared}, \text{choked}, \text{floor})\) at each outer end that is the
low end of its stage: a fill “to vacuum” ends at its choked pressure, not at zero and
not at a numerical floor. c is the adiabatic sound speed at the fill temperature,
as HiSol takes it; an independent integration of the one-dimensional compressible
flow (tests/test_gasflow.py) brackets the result between an isothermal and an
adiabatic wall, which is why the adiabatic speed is kept (docs/dev/decisions.md).
Flow regime. Gebhardt et al., Opt. Express 29, 6957 (2021), measured output-beam
instabilities in differentially pumped capillaries from \(Re \approx 2040\), worst
near 2400, and recommend \(Re < 2000\) (their eq. 4); the laminar fill itself is not
valid there. With \(Re = 4\dot m/(\pi d \eta)\) and the mass flow constant along a
stage, the narrowest point of a taper has the largest Reynolds number. At the other
extreme the gas stops being a continuum: with \(Kn = \lambda / d\), first-order
wall slip raises the throughput by \(8\,Kn\), and above 0.1 the flow is
transitional. steady_fill() warns
(GasFlowWarning) for a Reynolds number above 2000, for a
stage whose Knudsen number at its mean pressure and narrowest bore exceeds 0.01, or for
one with more than 1 % of its gas where the Knudsen number exceeds 0.1, and otherwise
logs the exit’s Knudsen number. It does not replace the laminar law: a turbulent or
rarefied fill is out of scope.
Pressures are in bar at this interface (docs/dev/conventions.md section 1);
throughputs are in Pa m^3 s^-1, with mbar_litres_per_second() and
standard_litres_per_minute() for the units vacuum practice quotes.
Module Attributes
How a fill treats an outer end below its choked pressure. |
|
Peak Reynolds number above which a fill warns that it is not laminar. |
|
Mean-pressure Knudsen number |
|
Knudsen number |
|
Share of a stage's column density |
|
Temperature in K of a standard litre, for |
|
Pressure in Pa of a standard litre, for |
Functions
|
Return the pressure at which a pump removes a given throughput. |
|
Return the choked exit pressure of a bore fed at one end and pumped at the other. |
|
Return the steady laminar flow a fill implies, stage by stage. |
|
Return the Knudsen number |
|
Return the mass flow carried by a PV throughput measured at a given pressure. |
|
Convert a PV throughput to mbar l/s. |
|
Return the Reynolds number of a steady flow at each position along a bore. |
|
Convert a PV throughput at a gas temperature to standard litres per minute. |
|
Build the steady-flow fill of a bore: taper-aware, choked, regime-checked. |
|
Return the flow weight |
|
Return the laminar PV throughput of a bore between two pressures. |
Classes
|
The steady flow of a fill: per stage, and at the outer ends. |
|
The steady flow through one stage of a fill. |
- class solprop.gasflow.FlowReport(stages, viscosity, sound_speed, choked_start_bar, choked_end_bar, start_is_choked, end_is_choked)[source]#
Bases:
DisplayedThe steady flow of a fill: per stage, and at the outer ends.
- Attributes:
- stagestuple of StageFlow
One entry per stage, in order along z.
- viscosityfloat
The gas viscosity in Pa s.
- sound_speedfloat
The dilute adiabatic sound speed in m s^-1.
- choked_start_bar, choked_end_barfloat or None
The choked pressure in bar of the first and last outer end, where that end is the low end of its stage;
Nonewhere it is not.- start_is_choked, end_is_chokedbool
Whether that end’s pressure is at (or, with
vacuum_end="floor", below) its choked value, so that the exit throughput is the sonic limit.
- property peak_knudsen: float[source]#
Return the largest Knudsen number of the fill.
- Returns:
- float
The maximum over the stages.
- property peak_reynolds: float[source]#
Return the largest Reynolds number of the fill.
- Returns:
- float
The maximum over the stages.
- solprop.gasflow.KNUDSEN_SLIP_LIMIT: Final = 0.01#
Mean-pressure Knudsen number
lambda(p_bar) / d_minabove which a stage warns.p_baris the mean of the stage’s end pressures andd_minits narrowest diameter. First-order wall slip raises a tube’s throughput toQ_Poiseuille (1 + 8 Kn(p_bar)), so above 0.01 the laminar throughput, the Reynolds number and the choked pressure are off by about ten per cent or more.
- solprop.gasflow.KNUDSEN_TRANSITION_LIMIT: Final = 0.1#
Knudsen number
lambda / dabove which the gas is transitional, not a continuum.The conventional transition-flow boundary for pipe flow.
- solprop.gasflow.REYNOLDS_LAMINAR_LIMIT: Final = 2000.0#
Peak Reynolds number above which a fill warns that it is not laminar.
Gebhardt et al., Opt. Express 29, 6957 (2021), eq. (4) and Fig. 6: output-beam instabilities appear from Re = 2040 and they recommend Re < 2000; pipe flow becomes sustained-turbulent near Re = 2040 (Avila et al., Science 333, 192 (2011)).
- solprop.gasflow.STANDARD_PRESSURE: Final = 101325.0#
Pressure in Pa of a standard litre, for
standard_litres_per_minute().
- solprop.gasflow.STANDARD_TEMPERATURE: Final = 273.15#
Temperature in K of a standard litre, for
standard_litres_per_minute().
- class solprop.gasflow.StageFlow(start, end, start_bar, end_bar, temperature, throughput, mass_flow, peak_reynolds, peak_reynolds_position, knudsen_start, knudsen_end, peak_knudsen, peak_knudsen_position, mean_knudsen, transitional_length, transitional_fraction)[source]#
Bases:
DisplayedThe steady flow through one stage of a fill.
- Attributes:
- start, endfloat
The stage’s ends in m.
- start_bar, end_barfloat
The fill’s pressures in bar at the two ends.
- temperaturefloat
Gas temperature in K.
- throughputfloat
Laminar PV throughput in Pa m^3 s^-1, from the higher to the lower end.
- mass_flowfloat
Mass flow in kg s^-1, from the throughput at the stage’s low end (
mass_flow()).- peak_reynoldsfloat
The largest Reynolds number on the stage.
- peak_reynolds_positionfloat
Where it is, in m: the narrowest point of the bore.
- knudsen_start, knudsen_endfloat
Knudsen numbers
lambda / dat the two ends; infinite at zero pressure.- peak_knudsenfloat
The largest Knudsen number on the stage.
- peak_knudsen_positionfloat
Where it is, in m.
- mean_knudsenfloat
The Knudsen number at the stage’s mean end pressure and narrowest diameter, which sets the first-order slip correction
8 Knof its throughput.- transitional_lengthfloat
The length in m over which the Knudsen number exceeds
KNUDSEN_TRANSITION_LIMIT.- transitional_fractionfloat
The share of the stage’s column density
int p dzthat lies there.
- property exit_knudsen: float[source]#
Return the Knudsen number at the stage’s lower-pressure end.
- Returns:
- float
knudsen_endwhen the flow runs towards +z, elseknudsen_start.
- property throughput_mbar_litres_per_second: float[source]#
Return the throughput in mbar l/s.
- Returns:
- float
- solprop.gasflow.TRANSITIONAL_COLUMN_LIMIT: Final = 0.01#
Share of a stage’s column density
int p dzthat may be transitional unwarned.A choked helium exit is transitional over micrometres (about 6 um of a 1 m helium gradient fibre), which carries a negligible part of the gas and of the nonlinear phase; a stage warns only when more than one per cent of its gas lies where the Knudsen number exceeds
KNUDSEN_TRANSITION_LIMIT.
- solprop.gasflow.VacuumEnd#
How a fill treats an outer end below its choked pressure.
"choked"raises it to the choked pressure of the flow, the default wherever the fill knows the gas and the bore;"floor"keeps the declared value, raised only to the numerical floor ofsolprop.profiles.PressureGradient, which is what a comparison with a fill whose end is a true vacuum needs. Either way a taper’s fill follows the bore: the choice concerns the ends only.alias of
Literal[‘choked’, ‘floor’]
- solprop.gasflow.chamber_pressure(throughput, pump_speed)[source]#
Return the pressure at which a pump removes a given throughput.
Solves
p S(p) = Q, as HiSol.jl’sgradient_end_pressuredoes: the pressure of the chamber an end exhausts into. If it is below the fill’s choked pressure the fibre end is choked and stays at that value.- Parameters:
- throughputfloat
PV throughput in Pa m^3 s^-1, >= 0.
- pump_speedfloat or callable
Pumping speed in m^3 s^-1, > 0, or a function of the chamber pressure in bar returning it (a pump’s characteristic curve).
- Returns:
- float
The chamber pressure in bar.
- Raises:
- TranslationError
If the throughput or a speed is invalid, or a characteristic’s throughput
p S(p)does not reach throughput between 1e-12 bar and 10 bar.
Examples
A 35 m^3/h pump taking 15.3 mbar l/s:
>>> from solprop.gasflow import chamber_pressure >>> f"{chamber_pressure(1.534, 35.0 / 3600.0) * 1e3:.3f}" '1.578'
- solprop.gasflow.choked_pressure(gas, radius, length, high_bar, *, exit_end='end', temperature=293.15)[source]#
Return the choked exit pressure of a bore fed at one end and pumped at the other.
- Parameters:
- gasGas, str, Species, Mapping or Mixture
One built-in gas, gases to mole fractions, or a mixture with a shared fill.
- radiusfloat or ZProfile
Core radius in m, > 0, over
[0, length].- lengthfloat
Length in m, > 0.
- high_barfloat
Pressure in bar at the fed end, >= 0.
- exit_end{‘end’, ‘start’}, optional
Which end exhausts:
z = length(the default) orz = 0. Its radius sets the sonic throughput.- temperaturefloat, optional
Gas temperature in K.
- Returns:
- float
The exit pressure in bar below which the exit throughput would exceed the sonic limit; the module docstring gives the relation.
- Raises:
- TranslationError
If a pressure, the length, the radius or exit_end is invalid.
- MaterialError
If the gas has no transport data at this temperature.
Examples
>>> from solprop.gasflow import choked_pressure >>> f"{choked_pressure('N2', 250e-6, 5.0, 4.2) * 1e3:.1f}" '224.3' >>> f"{choked_pressure('Ar', 15e-6, 1.0, 20.0) * 1e3:.1f}" '79.1'
- solprop.gasflow.flow_report(fill, gas, *, radius, temperature=293.15)[source]#
Return the steady laminar flow a fill implies, stage by stage.
- Parameters:
- fillsolprop.profiles.PressureGradient
The fill, in bar.
- gasGas, str, Species, Mapping or Mixture
One built-in gas, gases to mole fractions, or a mixture with a shared fill.
- radiusfloat or ZProfile
The core radius in m the fill runs through, > 0.
- temperaturefloat or ZProfile, optional
Gas temperature in K, or a path of it along z in m. Along a path the flow law is weighted by
eta(T) T, the Reynolds number takes the local viscosity, the Knudsen numbers the local mean free path, a choked end the viscosity and sound speed at its own temperature, and each stage’s throughput is quoted at its low end’s temperature; the report’s viscosity and sound_speed are those at the fill’s first position.
- Returns:
- FlowReport
Per stage the throughput, mass flow, peak Reynolds number and Knudsen numbers, and the choked state of the outer ends.
- Raises:
- TranslationError
If the radius is not positive or cannot be integrated.
- MaterialError
If the gas has no transport data at this temperature, or a mixture has independent populations.
Examples
>>> from solprop.gasflow import flow_report, steady_fill >>> fill = steady_fill("N2", [0.0, 5.0], [2.9, 0.0], radius=250e-6) >>> report = flow_report(fill, "N2", radius=250e-6) >>> round(report.peak_reynolds), report.end_is_choked (1223, True)
- solprop.gasflow.knudsen_number(gas, pressure_bar, radius, *, temperature=293.15)[source]#
Return the Knudsen number
lambda / dof a gas in a bore.- Parameters:
- gasGas, str, Species, Mapping or Mixture
One built-in gas, gases to mole fractions, or a mixture with a shared fill.
- pressure_bararray_like or float
Pressure in bar, >= 0; zero gives an infinite Knudsen number.
- radiusarray_like or float
Core radius in m, > 0, broadcast against pressure_bar.
- temperaturefloat, optional
Gas temperature in K.
- Returns:
- numpy.ndarray
lambda(p, T) / (2 a)with the mean free path ofsolprop.physdata.transport.mean_free_path(), in the broadcast shape.
- Raises:
- TranslationError
If a pressure is negative or a radius is not positive.
- MaterialError
If the gas has no transport data at this temperature.
Examples
>>> from solprop.gasflow import knudsen_number >>> f"{float(knudsen_number('N2', 0.01, 250e-6)):.4f}" '0.0130'
- solprop.gasflow.mass_flow(gas, throughput, pressure_bar, *, temperature=293.15)[source]#
Return the mass flow carried by a PV throughput measured at a given pressure.
mdot = Q rho(p, T) / pwith the real-gas mass density at the reference state(pressure_bar, temperature); a mixture sums its species’ partial densities. A throughput is conventionally quoted at the low-pressure end, where the gas is close to ideal and this isQ M / (R T), which is also the limit taken at zero pressure.- Parameters:
- gasGas, str, Species, Mapping or Mixture
One built-in gas, gases to mole fractions, or a mixture with a shared fill.
- throughputfloat
PV throughput in Pa m^3 s^-1, >= 0.
- pressure_barfloat
Pressure in bar at which the throughput is measured, >= 0.
- temperaturefloat, optional
Gas temperature in K.
- Returns:
- float
Mass flow in kg s^-1.
- Raises:
- TranslationError
If the throughput or the pressure is invalid.
- MaterialError
If the gas has no transport data at this temperature.
Examples
>>> from solprop.gasflow import mass_flow >>> f"{mass_flow('N2', 1.0, 0.0):.4e}" '1.1493e-05'
- solprop.gasflow.mbar_litres_per_second(throughput)[source]#
Convert a PV throughput to mbar l/s.
- Parameters:
- throughputfloat
PV throughput in Pa m^3 s^-1.
- Returns:
- float
The throughput in mbar l s^-1 (1 Pa m^3/s = 10 mbar l/s).
Examples
>>> from solprop.gasflow import mbar_litres_per_second >>> mbar_litres_per_second(1.0) 10.0
- solprop.gasflow.reynolds_number(gas, mass_flow, radius, z, *, temperature=293.15)[source]#
Return the Reynolds number of a steady flow at each position along a bore.
Re = 4 mdot / (pi d eta) = 2 mdot / (pi a eta): Gebhardt et al.’s4 M Q / (R T pi d eta)written with the mass flow, which is constant along a stage, so the narrowest point has the largest value.- Parameters:
- gasGas, str, Species, Mapping or Mixture
One built-in gas, gases to mole fractions, or a mixture with a shared fill.
- mass_flowfloat
Mass flow in kg s^-1, >= 0.
- radiusfloat or ZProfile
Core radius in m, > 0.
- znumpy.ndarray
Positions in m, shape
(n_z,).- temperaturefloat, optional
Gas temperature in K.
- Returns:
- numpy.ndarray
The Reynolds number at each position, shape
(n_z,).
- Raises:
- TranslationError
If the mass flow is negative or the radius is not positive.
- MaterialError
If the gas has no transport data at this temperature.
Examples
>>> import numpy as np >>> from solprop.gasflow import reynolds_number >>> reynolds_number("N2", 1e-5, 250e-6, np.array([0.0])).round(1) array([1450.2])
- solprop.gasflow.standard_litres_per_minute(throughput, temperature=293.15)[source]#
Convert a PV throughput at a gas temperature to standard litres per minute.
A standard litre is the ideal-gas amount in one litre at
STANDARD_TEMPERATUREandSTANDARD_PRESSURE(0 degrees C, one atmosphere). The throughputQ = p dV/dtat temperatureTcarriesQ/(k_B T)molecules per second, so the flow isQ (T_std/T) / p_stdstandard cubic metres per second, returned in litres per minute. HiSol.jl’sslpmomits the ratioT_std/T(7 % at 293.15 K). A mass-flow controller calibrated to another standard temperatureT_ref(20 degrees C, for example) readsT_ref/T_stdtimes this number.- Parameters:
- throughputfloat
PV throughput in Pa m^3 s^-1 at temperature.
- temperaturefloat, optional
Temperature in K at which the throughput is measured, > 0.
- Returns:
- float
The flow in standard litres per minute.
Examples
>>> from solprop.gasflow import standard_litres_per_minute >>> f"{standard_litres_per_minute(1.0, 273.15):.4f}" '0.5922'
- solprop.gasflow.steady_fill(gas, positions, pressures_bar, *, radius, temperature=293.15, vacuum_end='choked', floor=None)[source]#
Build the steady-flow fill of a bore: taper-aware, choked, regime-checked.
The fill follows the bore (
solprop.profiles.PressureGradientwith radius). Withvacuum_end="choked"each outer end that is the low end of its stage takesmax(declared, choked, floor): a declared zero replaced by the choked pressure is logged at INFO, a nonzero declared pressure raised to it at WARNING, naming both. Interior stage pressures are never choked (the chamber between two fibres is not modelled); an interior zero keeps the numerical floor, whichfrom_stages()logs. Withvacuum_end="floor"the declared pressures are kept, exactly as before; the fill still follows a varying bore (a uniform one is bitwise the previous fill).The flow is then checked (
flow_report()) and warns withGasFlowWarningfor a peak Reynolds number aboveREYNOLDS_LAMINAR_LIMIT, or for a stage whose Knudsen number at its mean pressure and narrowest bore exceedsKNUDSEN_SLIP_LIMIT, or with more thanTRANSITIONAL_COLUMN_LIMITof its column density where the Knudsen number exceedsKNUDSEN_TRANSITION_LIMIT; otherwise each stage’s exit Knudsen number and transitional length are logged at INFO.- Parameters:
- gasGas, str, Species, Mapping or Mixture
One built-in gas, gases to mole fractions (a shared fill), or a mixture with a shared fill.
- positionsarray_like
Stage boundaries in m, strictly increasing, at least two.
- pressures_bararray_like
Declared pressure in bar at each boundary, >= 0.
- radiusfloat or ZProfile
Core radius in m, > 0, over the fill.
- temperaturefloat or ZProfile, optional
Gas temperature in K, which sets the viscosity and the sound speed, or a path of it along z in m: the fill then follows the flow weight
eta(T) T(solprop.profiles.PressureGradient), a choked end takes the viscosity and the sound speed at its own temperature, and the regime checks the local ones (flow_report()). A constant path is the number, bit for bit.- vacuum_end{‘choked’, ‘floor’}, optional
How an outer end below its choked pressure is treated (
VacuumEnd).- floorfloat or None, optional
The numerical floor in bar;
Noneissolprop.profiles.DEFAULT_PRESSURE_FLOOR_FRACTIONof the highest stage pressure, and0.0withvacuum_end="floor"a true vacuum end.
- Returns:
- solprop.profiles.PressureGradient
The fill in bar.
- Raises:
- TranslationError
If the stage table, the radius or vacuum_end is invalid.
- MaterialError
If the gas has no transport data at this temperature (a custom species, or a temperature outside the data’s range): pass
vacuum_end="floor"to build the fill without the choke, whose flow regime is then not checked. A temperature path needs the data whatever vacuum_end is.
- Warns:
- GasFlowWarning
If the fill is not laminar, or is transitional between continuum and molecular flow.
Examples
>>> from solprop.gasflow import steady_fill >>> fill = steady_fill("He", [0.0, 3.0], [5.0, 0.0], radius=125e-6) >>> f"{fill.pressures[-1] * 1e3:.2f} mbar" '41.18 mbar'
- solprop.gasflow.temperature_weight(gas, temperature, positions)[source]#
Return the flow weight
eta(T) Tof a gas along a fill, in Pa s K.A steady laminar flow of an ideal gas carries the mass flow
mdot = pi a^4 M d(p^2)/dz / (16 R eta(T) T), sop^2is linear inint eta(T) T a^-4 dz;solprop.profiles.PressureGradienttakes this weight as its weight. Along a temperature path the viscosity is a converged Chebyshev series inTover the temperatures the path takes on the fill, and the weight asolprop.profiles.SeriesOfPathof the path.- Parameters:
- gasGas, str, Species, Mapping or Mixture
One built-in gas, gases to mole fractions, or a mixture with a shared fill.
- temperaturefloat or ZProfile
Gas temperature in K, or a path of it along z in m.
- positionsarray_like
The fill’s stage boundaries in m, strictly increasing: the span over which the temperature range is taken.
- Returns:
- ZProfile
The weight along z: a
Constantfor a constant temperature, aSeriesOfPathotherwise.
- Raises:
- TranslationError
If the positions are invalid.
- MaterialError
If the temperature is not positive, or the gas has no transport data over its range.
Examples
>>> import numpy as np >>> from solprop.gasflow import temperature_weight >>> from solprop.profiles import Linear >>> weight = temperature_weight("N2", Linear(293.15, 350.0, 1.0), [0.0, 1.0]) >>> f"{float(weight(np.array([0.0]))[0]):.4e}" '5.1476e-03'
- solprop.gasflow.throughput(gas, radius, length, start_bar, end_bar, *, temperature=293.15)[source]#
Return the laminar PV throughput of a bore between two pressures.
Q = pi (p_h^2 - p_l^2) / (16 eta R)withR = int_0^length a^-4 dz.- Parameters:
- gasGas, str, Species, Mapping or Mixture
One built-in gas, gases to mole fractions, or a mixture with a shared fill.
- radiusfloat or ZProfile
Core radius in m, > 0, over
[0, length].- lengthfloat
Length in m, > 0.
- start_bar, end_barfloat
Pressures in bar at
z = 0andz = length, >= 0.- temperaturefloat, optional
Gas temperature in K.
- Returns:
- float
The throughput in Pa m^3 s^-1, from the higher to the lower end, >= 0.
- Raises:
- TranslationError
If a pressure, the length or the radius is invalid.
- MaterialError
If the gas has no transport data at this temperature.
Examples
Gebhardt et al.’s 5 m, 500 um nitrogen capillary at 4.2 bar into vacuum:
>>> from solprop.gasflow import mbar_litres_per_second, throughput >>> q = throughput("N2", 250e-6, 5.0, 4.2, 0.0) >>> f"{mbar_litres_per_second(q):.2f}" '15.41'