EngineeringFluids 0.1.5

dotnet add package EngineeringFluids --version 0.1.5
                    
NuGet\Install-Package EngineeringFluids -Version 0.1.5
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="EngineeringFluids" Version="0.1.5" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="EngineeringFluids" Version="0.1.5" />
                    
Directory.Packages.props
<PackageReference Include="EngineeringFluids" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add EngineeringFluids --version 0.1.5
                    
#r "nuget: EngineeringFluids, 0.1.5"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package EngineeringFluids@0.1.5
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=EngineeringFluids&version=0.1.5
                    
Install as a Cake Addin
#tool nuget:?package=EngineeringFluids&version=0.1.5
                    
Install as a Cake Tool

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 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

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.

Version Downloads Last Updated
0.1.5 0 10/19/2026
0.1.4 204 9/30/2026
0.1.3 117 9/30/2026