EngineeringFluids 0.1.5
dotnet add package EngineeringFluids --version 0.1.5
NuGet\Install-Package EngineeringFluids -Version 0.1.5
<PackageReference Include="EngineeringFluids" Version="0.1.5" />
<PackageVersion Include="EngineeringFluids" Version="0.1.5" />
<PackageReference Include="EngineeringFluids" />
paket add EngineeringFluids --version 0.1.5
#r "nuget: EngineeringFluids, 0.1.5"
#:package EngineeringFluids@0.1.5
#addin nuget:?package=EngineeringFluids&version=0.1.5
#tool nuget:?package=EngineeringFluids&version=0.1.5
EngineeringFluids
Fast, unit-typed thermodynamic and transport properties for engineering fluids in .NET.
Built on EngineeringUnits.Fast: every input and output is a
typed quantity (Pressure, Temperature, Enthalpy, ...), so there are no unit mix-ups and no conversions by hand.
Results match CoolProp / SharpFluids.
| Fluid | Class | Equation of state | Transport |
|---|---|---|---|
| Ammonia (R717) | Ammonia |
Gao et al. (2020) | Fenghour viscosity, Tufeu conductivity |
| Water (R718) | Water |
IAPWS-95 (Wagner and Pruss 2002) | IAPWS 2008 viscosity, IAPWS 2011 conductivity |
| Carbon dioxide (R744) | CarbonDioxide |
Span and Wagner (1996) | Laesecke-Muzny viscosity, Huber conductivity |
| R134a | R134a |
Tillner-Roth and Baehr (1994) | Huber viscosity, McLinden conductivity |
| Propane (R290) | NPropane |
Lemmon et al. (2009) | Vogel viscosity, Marsh conductivity |
| n-Butane (R600) | NButane |
Buecker and Wagner (2006) | Vogel viscosity, Perkins conductivity |
| Isobutane (R600a) | IsoButane |
Buecker and Wagner (2006) | Vogel viscosity, Perkins conductivity |
Brines: propylene glycol and ethylene glycol in water (PropyleneGlycolAqueous, EthyleneGlycolAqueous,
MelinderPropyleneGlycolAqueous; see Brines).
Install
dotnet add package EngineeringFluids
Quick start
using EngineeringFluids.Fluids;
using EngineeringUnits.Fast;
var nh3 = new Ammonia();
// Single-phase state from pressure and temperature
nh3.UpdatePT(Pressure.FromBar(10), Temperature.FromDegreeCelsius(50));
Console.WriteLine(nh3.Density.KilogramPerCubicMeter);
Console.WriteLine(nh3.Enthalpy.JoulePerKilogram);
Console.WriteLine(nh3.Cp.JoulePerKilogramKelvin);
Console.WriteLine(nh3.DynamicViscosity.PascalSecond);
Console.WriteLine(nh3.Phase);
// Two-phase state from pressure and vapor quality (0 = saturated liquid, 1 = saturated vapor)
nh3.UpdatePX(Pressure.FromBar(5), 0.3);
Console.WriteLine(nh3.Temperature.DegreeCelsius); // saturation temperature
Console.WriteLine(nh3.Quality);
// Every fluid has the same API
var water = new Water();
water.UpdatePT(Pressure.FromBar(3), Temperature.FromDegreeCelsius(15));
Console.WriteLine(water.Conductivity.WattPerMeterKelvin);
When the fluid is only known at runtime, create it by name (CoolProp's name or a common alias, any case):
IEngineeringFluid fluid = EngineeringFluid.Create("R718"); // or "Water", "H2O", "Ammonia", "NH3", "CO2", "R134a", "Propane", "R290", "R600", "R600a", ...
fluid.UpdatePH(Pressure.FromBar(3), Enthalpy.FromKilojoulePerKilogram(63));
Code that knows its fluid should use the concrete class: its calls are direct, IEngineeringFluid's go through an
interface.
State updates
| Method | Inputs |
|---|---|
UpdatePT |
pressure, temperature (optionally a phase hint) |
UpdatePH / UpdatePHExact |
pressure, enthalpy |
UpdatePS / UpdatePSExact |
pressure, entropy |
UpdatePX / UpdatePXExact |
pressure, vapor quality |
UpdateTX / UpdateTXExact |
temperature, vapor quality |
UpdateTS |
temperature, entropy |
UpdateHS |
enthalpy, entropy |
UpdateDT |
density, temperature |
UpdateDP |
density, pressure |
UpdateDH / UpdateDS |
density, enthalpy / entropy |
The plain methods read the saturation dome from fast ancillary fits. The Exact variants solve the phase
equilibrium against the equation of state instead: a bit slower, but they agree with CoolProp to about 1e-10 and
work all the way up to the critical point. Use Exact when you need CoolProp-identical results.
Like CoolProp, UpdatePT rejects liquid states below a fluid's melting line (water's ice, CO2's dry ice) - or, for a
fluid CoolProp has no melting line for (ammonia, R134a), below its triple-point temperature - and water's UpdateDP returns the state above
the density maximum (about 4 C) where a liquid density occurs at two temperatures.
Properties
Pressure, temperature, density, enthalpy, entropy, internal energy, Cp, Cv, speed of sound, viscosity, thermal conductivity, Prandtl number, surface tension, fugacity, compressibility, phase, quality, saturation temperature/pressure, critical and triple-point data, and validity limits.
All properties of a state are computed from a single cached equation-of-state evaluation, so reading many properties costs about the same as reading one. Once a state is set, it can be read from multiple threads at the same time.
Brines
Propylene glycol - water and ethylene glycol - water, as CoolProp's incompressible backend has them (INCOMP::MPG and
INCOMP::MEG, Melinder 2010): density, heat capacity, viscosity, conductivity and freezing point are polynomial fits in
temperature and mass fraction, for 0 to 60 % glycol by mass, from the freezing point to 100 °C. INCOMP::MPG2
(MelinderPropyleneGlycolAqueous, SharpFluids' MixMelinderPropyleneGlycol) is another fit of propylene glycol - water,
for 15 to 57 % from the freezing point (or -45 °C) to 40 °C.
// 30 % by mass - SharpFluids' SetNewMedia(FluidList.MixPropyleneGlycolAQ) + SetFraction(30)
var brine = new PropyleneGlycolAqueous(0.30); // or new PropyleneGlycolAqueous(Ratio.FromPercent(30))
brine.UpdatePT(Pressure.FromBar(2), Temperature.FromDegreeCelsius(-5));
Console.WriteLine(brine.Density.KilogramPerCubicMeter);
Console.WriteLine(brine.Prandtl);
Console.WriteLine(brine.T_freeze.DegreeCelsius); // -12.8 °C: no state below it
brine.UpdatePH(Pressure.FromBar(2), Enthalpy.FromKilojoulePerKilogram(40));
// By name: the brine needs its mass fraction, as an argument or in the name the way CoolProp writes it
IEngineeringFluid meg = EngineeringFluid.CreateBrine("MEG", 0.25); // or Create("INCOMP::MEG[0.25]"), Create("MEG-25%")
The results are CoolProp's (8.0.0, as SharpFluids 3.0.518 ships it): the same polynomials evaluated with the same operations (UpdatePT agrees to
the last bit, UpdatePH to a few), more than 100 times faster than CoolProp itself. As in CoolProp the liquid is
incompressible (its density does not depend on pressure), Cv equals Cp, and enthalpy and entropy are zero at
20 °C and 101325 Pa. The updates are UpdatePT, UpdatePH, UpdatePS and UpdateDP; a state below the freezing
point or above 100 °C (MPG2: 40 °C) throws ArgumentOutOfRangeException, and what a brine does not have - two-phase updates, the
Helmholtz members, molar properties, speed of sound, surface tension, saturation and critical properties - throws
NotSupportedException.
How a fluid is defined
Each fluid is a readonly struct implementing IHelmholtzModel<TSelf> - its constants, its Helmholtz equation of
state, its saturation ancillaries and its transport models - and the fluid class is HelmholtzFluid<TModel> for
that model (Ammonia : HelmholtzFluid<AmmoniaModel>). The model's members are static abstract and the model is a
struct, so .NET compiles the state class and every solver separately per fluid with the model inlined: adding fluids
costs no speed.
- The equation-of-state terms are generic, data-driven classes (
EngineeringFluids.Helmholtz.Terms): CoolProp's power, Gaussian and non-analytic residual terms and its ideal-gas terms, declared with the fluid's coefficients. - The saturation ancillaries are generated from the fluid's own equation of state by
Tools/AncillaryGenerator. - Transport uses CoolProp's data-driven correlations (
EngineeringFluids.Transport), or a hand port where CoolProp hard-codes the model (water, ammonia's critical enhancement, and CO2's Laesecke-Muzny and Huber terms).
Adding a fluid
A fluid CoolProp describes with the generic terms (power, Gaussian and non-analytic residual terms; lead, log-tau,
power, Planck-Einstein and enthalpy/entropy-offset ideal-gas terms; Simon or polynomial melting lines) is added by
machine, from the fluid file of the CoolProp version EngineeringFluids matches (8.0.0, as SharpFluids 3.0.518 ships
it; dump the files - and the critical point CoolProp reports, <fluid>.critical.json - from its DLL). For n-butane,
with the fluid files in <json dir>:
dotnet run Tools/TransportCodegen.cs -- <json dir> EngineeringFluids/Transport n-Butane:NButaneTransport
dotnet run Tools/FluidCodegen.cs -- <json dir> . n-Butane:NButane
dotnet run -c Release --project Tools/AncillaryGenerator -- nbutane EngineeringFluids/Helmholtz/Ancillary
dotnet run Tools/FluidCodegen.cs -- <json dir> . n-Butane:NButane
FluidCodegen writes Fluids/NButane.cs (NButane : HelmholtzFluid<NButaneModel>), registers the fluid's names in
EngineeringFluid and adds it to the AncillaryGenerator; the generator then fits the saturation tables to the new
equation of state's own dome, and the second FluidCodegen run wires them in. The tests are a FluidParityTests
definition against SharpFluids (see CarbonDioxideParityTests) and the fluid's line in GenericEosTests, which checks
the generic terms against CoolProp before the fluid is even generated.
Check the generator's report before wiring the tables in. Two things it handles on its own:
- The critical point is the equation of state's own, as CoolProp 8 reports it (located on the EOS: R134a's is 1.97 mK above the tabulated one, propane's 9 microkelvin, isobutane's 7 mK below), and the tables close there.
- Near the triple point of a light hydrocarbon the saturated liquid's compressibility is tiny (n-butane 5e-8, isobutane 2e-9, propane 1.5e-11), so its pressure carries the rounding of the EOS. The saturation solver solves for equal Gibbs energy and takes the saturation pressure from the vapour, and its tolerances never go below the liquid's rounding noise.
CoolProp itself is not a usable reference everywhere: near the triple point its saturation pressure is the liquid's
(noisy), and close to Tc several fluids read critical-region splines instead of solving the dome. A
FluidParityDefinition narrows the comparison with SaturationCheckTmin/Tmax/Pmin/Pmax and SaturationPressureNoise,
and excludes states with Excluded; each such limit is pinned by a KnownSharpFluidsBehaviour_* test of the fluid.
License
MIT
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- EngineeringUnits.Fast (>= 2.2.154)
- Kolbe.LitMath (>= 0.7.0)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on EngineeringFluids:
| Package | Downloads |
|---|---|
|
SharpFluids
Get Fluid properties using this lightweight CoolProp Wrapper |
GitHub repositories
This package is not used by any popular GitHub repositories.