This guide documents the viscosity calculation methods available in NeqSim for gas, liquid, and multiphase systems.
Table of Contents
Overview
Viscosity describes a fluid’s resistance to flow. NeqSim provides several viscosity models suitable for different applications:
Units:
- Default output: Pa·s (Pascal-seconds)
- Alternative: cP (centipoise), where 1 cP = 0.001 Pa·s
Setting a viscosity model:
fluid.initPhysicalProperties();
fluid.getPhase("gas").getPhysicalProperties().setViscosityModel("friction theory");
fluid.getPhase("oil").getPhysicalProperties().setViscosityModel("LBC");
fluid.getPhase("gas").initPhysicalProperties();
fluid.getPhase("oil").initPhysicalProperties();
Select the model after the flash and initial property calculation, then reinitialize each changed phase as shown. Model keys are case-sensitive. Unlike conductivity selection, an unsupported viscosity key leaves the current model unchanged; verify the selected key in tests rather than assuming a fallback.
Available Models
Letsou-Stiel saturated-liquid estimator
Letsou-Stiel is an opt-in pure-liquid estimator when fitted viscosity data are unavailable.
It uses critical temperature, critical pressure, molar mass and acentric factor. It implements
the polynomial representation of the Letsou-Stiel tables in the ChemSep book,
equations 10.158–10.161, also documented by COCO/TEA.
This is an estimation alternative, not a replacement for a fluid-specific reference correlation.
The supported reduced-temperature interval is $0.76 \leq T/T_c \leq 0.98$. The result estimates saturated-liquid viscosity; selecting it on a compressed-liquid phase does not add a pressure correction. The implementation refuses mixtures, gas/solid phases, nonfinite or nonpositive required inputs, and temperatures outside that interval. Selection validates the current state before replacing the previous model. Establish the liquid phase with a flash before selecting it. Later out-of-range state changes are rejected by the model; the existing physical-property initialization handler may log such an exception, so callers must keep subsequent states inside the supported interval.
Class: LetsouStielViscosity. Its static calculateViscosity API takes temperature and
critical temperature in K, molar mass in kg/mol, critical pressure in bara, and returns Pa s.
The inherited liquid-model getPureComponentViscosity(0) interface retains mPa s.
No database coefficients or fitted binary interactions are required. No mixture mixing rule
or automatic fallback is claimed.
SystemInterface fluid = new SystemSrkEos(500.0, 40.0);
fluid.addComponent("benzene", 1.0);
fluid.setMixingRule("classic");
new ThermodynamicOperations(fluid).TPflash();
fluid.initProperties();
fluid.getPhase("oil").getPhysicalProperties().setViscosityModel("Letsou-Stiel");
fluid.getPhase("oil").initPhysicalProperties();
double saturatedLiquidEstimatePas = fluid.getPhase("oil").getViscosity("kg/msec");
LetsouStielViscosityTest executes this example and the independent ethanol example
(400 K, 46.07 g/mol, 516.25 K, 6.383 MPa, acentric factor 0.6371), which gives
0.0002036150875308 Pa s. That is a correlation implementation check, not an experimental
accuracy claim for ethanol or associating liquids. See the method audit.
The Viscosity liquid mixture method uses tabulated gijvisc interactions from
the inter component-pair table in its Grunberg-Nissan mixing expression.
Pairs without tabulated data use zero interaction. Ions and TBP fractions are
excluded from this pair lookup; their presence does not suppress later valid
component pairs. These parameters affect the liquid mixture method, not the
separate LBCViscosityMethod implementation described below.
LBC (Lohrenz-Bray-Clark)
The Lohrenz-Bray-Clark (1964) method is widely used in reservoir simulation. It combines a dilute gas correlation with a dense fluid polynomial correction.
Class: LBCViscosityMethod
Equation: \(\eta = \eta^* + \frac{(\eta_r - 0.0001)^4}{\xi}\)
where:
- $\eta^*$ is the dilute gas viscosity
- $\eta_r$ is a function of reduced density
- $\xi$ is the inverse viscosity parameter
The dense fluid contribution uses a polynomial: \(\eta_r = a_0 + a_1\rho_r + a_2\rho_r^2 + a_3\rho_r^3 + a_4\rho_r^4\)
Default parameters: {0.10230, 0.023364, 0.058533, -0.040758, 0.0093324}
Applicable phases: Gas, Oil
Best for:
- Reservoir simulation
- Light to medium oils
- Systems where tuning to lab data is available
Usage:
fluid.getPhase("oil").getPhysicalProperties().setViscosityModel("LBC");
fluid.getPhase("oil").initPhysicalProperties();
Friction Theory
The Quiñones-Cisneros and Firoozabadi (2000) friction theory relates viscosity to the repulsive and attractive pressure contributions from the equation of state.
Class: FrictionTheoryViscosityMethod
Equation: \(\eta = \eta_0 + \kappa_a P_a + \kappa_{aa} P_a^2 + \kappa_r P_r + \kappa_{rr} P_r^2\)
where:
- $\eta_0$ is the dilute gas viscosity (Chung low-density term + Wilke mixture rule)
- $P_a$ is the attractive pressure from EoS
- $P_r$ is the repulsive pressure from EoS
- $\kappa$ are friction coefficients (EoS-dependent)
Applicable phases: Gas, Oil (any EoS-based phase)
Best for:
- Wide pressure/temperature ranges
- Near-critical conditions
- When using SRK or PR EoS
Automatic EoS detection: The method automatically selects SRK or PR constants based on the phase type.
Implementation notes in NeqSim (2026 update):
- SRK and PR friction constants are selected automatically.
- The dilute-gas baseline now uses Wilke mixing, which is the standard state-of-practice for mixture dilute viscosities.
- The Chung correction factor $F_c$ includes acentric factor, dipole moment, and component viscosity correction term to better handle polar species.
- If friction theory is called for a non-EoS phase, NeqSim falls back to total pressure as repulsive contribution and zero attractive contribution, with a warning in logs.
Usage:
fluid.getPhase("oil").getPhysicalProperties().setViscosityModel("friction theory");
fluid.getPhase("oil").initPhysicalProperties();
Custom constants (advanced use):
FrictionTheoryViscosityMethod viscModel =
(FrictionTheoryViscosityMethod) fluid.getPhase("oil")
.getPhysicalProperties().getViscosityModel();
// Values must come from an independently validated parameter set.
viscModel.setFrictionTheoryConstants(kapac, kaprc, kaprrc, kapa, kapr, kaprr);
Here kapac, kaprc, kaprrc, and kaprr are scalar double values; kapa and
kapr are double[][] matrices. This API replaces the model’s complete parameter set and is not
a general fitting shortcut.
PFCT (Pedersen)
The Pedersen Friction Corresponding States Theory uses methane as a reference fluid with shape factors for mixture calculations.
The model can be selected with either "PFCT" or "CSP". The "CSP" alias is intended for PVT workflows and external reports that label the Pedersen/PFCT viscosity model as CSP viscosity.
Classes:
PFCTViscosityMethodMod86- Standard Pedersen method (1987)PFCTViscosityMethodHeavyOil- Extended for heavy oils
Equation: \(\eta_{mix} = \eta_{ref} \cdot \frac{f_\eta \cdot \alpha_{mix}}{\alpha_0}\)
where:
- $\eta_{ref}$ is the reference fluid (methane) viscosity
- $f_\eta$ is the shape factor ratio
- $\alpha$ are molecular weight correction factors
Applicable phases: Gas, Oil
Best for:
- Petroleum mixtures with characterized fractions
- Heavy oil systems (use
"PFCT-Heavy-Oil") - Wide-range predictions
- PVT viscosity matching with four CSP correction factors
Usage:
// Standard Pedersen
fluid.getPhase("oil").getPhysicalProperties().setViscosityModel("PFCT");
fluid.getPhase("oil").initPhysicalProperties();
Use "CSP" as an equivalent alias for "PFCT", or select "PFCT-Heavy-Oil" for
characterized heavy fractions. Reinitialize the phase after any selection.
PFCT, PFCT-Mod86 and PFCT-Heavy-Oil clones keep independent mutable methane reference fluids. This includes the default gas/oil transport models on cloned process streams, so parallel branches can evaluate viscosity at different temperatures and pressures without overwriting a sibling reference state. Model parameters and correction factors are retained. Configure fluids and mixing parameters before launching parallel calculations; do not mutate a stream that another calculation is using.
Polynomial Correlation
Uses component-specific polynomial coefficients from the database.
Class: Viscosity (liquid), GasViscosity (gas)
Equation: \(\ln(\eta) = A + \frac{B}{T} + C\ln(T) + DT\)
where A, B, C, D are component-specific parameters from COMP database.
Database columns: LIQVISC1, LIQVISC2, LIQVISC3, LIQVISC4
Applicable phases: Primarily liquid
Best for:
- Pure components with available parameters
- Simple mixtures with mixing rules
Usage:
fluid.getPhase("oil").getPhysicalProperties().setViscosityModel("polynom");
fluid.getPhase("oil").initPhysicalProperties();
Reference Fluid Methods
Specialized high-accuracy methods for specific fluids:
Methane (Reference)
Class: MethaneViscosityMethod
- Uses Setzmann & Wagner reference equation
- High accuracy for pure methane
- Used as reference in PFCT calculations
CO₂
Class: CO2ViscosityMethod
- Laesecke–Muzny (2017) background viscosity: dilute, initial-density Rainwater–Friend and residual terms.
- The 2026 NIST IR 8608, section 11 retains this reference formulation.
- Pure CO₂ only, using the phase’s current temperature and mass density. An unavailable or nonfinite phase density uses the existing Span–Wagner density fallback. Wrong species and mixtures raise an argument exception.
calculateViscosity(temperature, density)accepts K and kg/m³ and returns Pa s. It supports 100–2000 K mathematically; callers must establish a physical gas, liquid or supercritical state inside the paper’s range. Input checks do not enforce the melting curve or qualify every accepted temperature/density pair.calculateDiluteGasViscosity(temperature)supports 100–10000 K. Temperatures above 2000 K are the paper’s explicitly documented zero-density extrapolation, and are refused by the finite-density API.- Critical enhancement is excluded. The paper identifies a region approximately bounded by 300–310 K and 300–600 kg/m³ where this contribution can exceed 1%. These boundaries are guidance, not a sharp cutoff. This implementation does not establish near-critical viscosity accuracy.
The earlier implementation omitted the linear-in-density contribution and failed all six finite-density
check values in Laesecke and Muzny (2017), Table 6, with an error up to 6.8%.
CO2ViscosityReferenceValuesTest now checks all nine Table 6 values to their printed rounding precision.
CO2ViscosityMethodTest also checks seven Table 8 pressure-temperature recommendations through the existing
Span–Wagner phase/property path with a 0.1% tolerance. This is a bounded implementation and EOS integration
check, not a universal experimental-accuracy statement.
Both stateless APIs use the existing MCP runCapability invocation route. The ordinary CO2Model key and
the existing pure-CO₂ Span–Wagner defaults use the corrected background model. PFCT mixtures are unaffected.
See the method audit for parameter provenance, remaining critical-enhancement work,
and computation-cost evidence.
Hydrogen
Classes: MuznyViscosityMethod, MuznyModViscosityMethod
- High-accuracy hydrogen viscosity
- Important for hydrogen energy applications
The implemented case-sensitive keys and their constraints are:
| Key | Intended fluid |
|---|---|
MethaneModel |
Pure methane |
CO2Model |
Pure CO₂ |
Muzny, Muzny_mod |
Pure hydrogen |
KTA, KTA_mod |
Pure helium |
Salt Water |
Aqueous water/brine phase |
For example, select and recalculate a pure-hydrogen gas phase with:
fluid.getPhase("gas").getPhysicalProperties().setViscosityModel("Muzny");
fluid.getPhase("gas").initPhysicalProperties();
Model Selection Guide
| Application | Recommended Model | Notes |
|---|---|---|
| Reservoir simulation | LBC | Tunable, industry standard |
| Wide P-T range | Friction Theory | Good near critical |
| Heavy oils | PFCT-Heavy-Oil | Extended for high MW |
| Characterized crudes | PFCT | Works with pseudo-components |
| General gas processing | Friction theory or PFCT | Validate against representative data |
| Pure CO₂ | CO2Model | Reference background correlation; critical enhancement excluded |
| Pure H₂ | Muzny | Reference accuracy |
| Pure helium | KTA | Reference-fluid correlation |
| Aqueous systems | Salt Water | Water/brine correlation |
Tuning Parameters
LBC viscosity-only critical volumes
LBCViscosityMethod.getCriticalVolumes() returns the effective per-component
volumes used by the correlation, in cm³/mol and phase component order.
setCriticalVolumes(double[]) accepts a positive finite value for every
component. It configures the viscosity correlation independently of each
component’s thermodynamic critical volume. Passing null clears the override and
restores the legacy estimation route, including the existing Whitson-based TBP
estimate. The input and output arrays are defensive copies, and overrides remain
independent after model cloning or compatible-version native serialization.
Changing the component slate requires a new array; stale counts fail explicitly.
This optional contract supports VCRITVIS E300 delivery
and JSON viscosityModel.criticalVolumesCm3PerMol reload without silently
re-estimating the transport parameter. Configure the same effective volumes and
LBC coefficients on every phase that may become active. The guarded PVT delivery
rejects phase-specific settings that one E300 component block cannot represent.
The enabled LbcFluidRoundTripTest
checks these APIs and actual petroleum-oil viscosity over pressure states.
LBC Parameter Tuning
The LBC method is commonly tuned to match laboratory viscosity data:
fluid.getPhase("oil").getPhysicalProperties().setViscosityModel("LBC");
// Set all 5 parameters
double[] params = {0.1023, 0.023364, 0.058533, -0.040758, 0.0093324};
fluid.getPhase("oil").getPhysicalProperties().setLbcParameters(params);
// Or tune individual parameters
fluid.getPhase("oil").getPhysicalProperties().setLbcParameter(0, 0.105);
fluid.getPhase("oil").initPhysicalProperties();
Tuning procedure:
- Measure viscosity at multiple P-T conditions
- Run flash and calculate properties
- Adjust parameters to minimize error
- Validate at other conditions
CSP PFCT Parameter Tuning
The PFCT/CSP viscosity model exposes four dimensionless CSP correction factors. All factors default to 1.0, preserving the historical NeqSim calculation unless a user supplies tuned values. External PVT tools may report fitted vectors such as 0.6232, 1.1507, 1.0000, 1.0000; these can be supplied directly as the four-value CSP viscosity parameter vector.
| Index | Regression parameter | Corrected PFCT term |
|---|---|---|
| 0 | VISCOSITY_CSP_1 |
Critical-temperature scaling exponent |
| 1 | VISCOSITY_CSP_2 |
Critical-pressure scaling exponent |
| 2 | VISCOSITY_CSP_3 |
Molar-mass scaling exponent |
| 3 | VISCOSITY_CSP_4 |
Alpha/molecular-weight correction exponent |
Use PhysicalProperties.setCspViscosityParameters(double[]) to set all four parameters, setCspViscosityParameter(int, double) to tune one parameter, and getCspViscosityParameters() to read the active values. The longer setCspViscosityCorrectionFactors and getCspViscosityCorrectionFactors names are equivalent aliases.
For automated fitting, add viscosity measurements to PVTRegression with addViscosityData(...), then register RegressionParameter.VISCOSITY_CSP_1 through VISCOSITY_CSP_4 individually or call addCspViscosityRegressionParameters() to fit all four together. Viscosity observations are expected in Pa s and can target gas, oil, liquid, aqueous, or water phases.
Usage Examples
Basic Viscosity Calculation
import neqsim.thermo.system.SystemSrkEos;
import neqsim.thermo.system.SystemInterface;
import neqsim.thermodynamicoperations.ThermodynamicOperations;
// Create and flash fluid
SystemInterface fluid = new SystemSrkEos(298.15, 4.0);
fluid.addComponent("n-heptane", 0.5);
fluid.addComponent("nC10", 0.5);
fluid.setMixingRule("classic");
ThermodynamicOperations ops = new ThermodynamicOperations(fluid);
ops.TPflash();
// Initialize physical properties
fluid.initPhysicalProperties();
fluid.getPhase("oil").getPhysicalProperties().setViscosityModel("LBC");
fluid.getPhase("oil").initPhysicalProperties();
// Get viscosity
double oilVisc = fluid.getPhase("oil").getViscosity("cP");
if (!(oilVisc > 0.0) || !Double.isFinite(oilVisc)) {
throw new IllegalStateException("Expected positive finite oil viscosity");
}
Comparing Viscosity Models
String[] models = {"LBC", "friction theory", "PFCT"};
double[] viscositiesCp = new double[models.length];
for (int i = 0; i < models.length; i++) {
SystemInterface fluid = new SystemSrkEos(298.15, 4.0);
fluid.addComponent("n-heptane", 0.5);
fluid.addComponent("nC10", 0.5);
fluid.setMixingRule("classic");
ThermodynamicOperations ops = new ThermodynamicOperations(fluid);
ops.TPflash();
fluid.initPhysicalProperties();
fluid.getPhase("oil").getPhysicalProperties().setViscosityModel(models[i]);
fluid.getPhase("oil").initPhysicalProperties();
viscositiesCp[i] = fluid.getPhase("oil").getViscosity("cP");
}
Viscosity vs Temperature
SystemInterface baseFluid = new SystemSrkEos(300.0, 20.0);
baseFluid.addComponent("nC10", 1.0);
baseFluid.setMixingRule("classic");
double[] temps = {300, 320, 340, 360, 380, 400}; // K
double[] viscositiesCp = new double[temps.length];
for (int i = 0; i < temps.length; i++) {
SystemInterface fluid = baseFluid.clone();
fluid.setTemperature(temps[i], "K");
ThermodynamicOperations ops = new ThermodynamicOperations(fluid);
ops.TPflash();
fluid.initPhysicalProperties();
fluid.getPhase("oil").getPhysicalProperties().setViscosityModel("LBC");
fluid.getPhase("oil").initPhysicalProperties();
viscositiesCp[i] = fluid.getPhase("oil").getViscosity("cP");
}
Mathematical Details
Dilute Gas Viscosity (Chapman-Enskog)
For dilute gases, viscosity is calculated from kinetic theory:
\[\eta_0 = \frac{5}{16} \frac{\sqrt{\pi m k_B T}}{\pi \sigma^2 \Omega^{(2,2)*}}\]where:
- $m$ is molecular mass
- $\sigma$ is Lennard-Jones diameter
- $\Omega^{(2,2)*}$ is the collision integral
Mixing Rules
Mixing behavior is model-specific. Common forms include logarithmic molar weighting:
\[\eta_{mix} = \exp\left(\sum_i x_i \ln \eta_i\right)\]or the more rigorous:
\[\eta_{mix} = \frac{\sum_i x_i \sqrt{M_i} \eta_i}{\sum_i x_i \sqrt{M_i}}\]References
- Lohrenz, J., Bray, B.G., Clark, C.R. (1964). Calculating Viscosities of Reservoir Fluids from Their Compositions. JPT.
- Quiñones-Cisneros, S.E., Firoozabadi, A. (2000). One Parameter Friction Theory. AIChE J.
- Pedersen, K.S., et al. (1987). Viscosity of Crude Oils. Chem. Eng. Sci.
- Chung, T.H., et al. (1988). Generalized Multiparameter Correlation for Nonpolar and Polar Fluid Transport Properties. I&EC Res.