NeqSim represents pressure letdown and control-valve calculations with classes in
neqsim.process.equipment.valve. This page focuses on the current
ThrottlingValve API. For pressure-safety valves and production-choke
correlations, use the dedicated guides linked below.
Available valve classes
| Class | Purpose |
|---|---|
ThrottlingValve |
Isenthalpic pressure letdown, specified outlet pressure, or Cv/Kv-based calculation |
ControlValve |
Named specialization of ThrottlingValve for control applications |
SafetyValve |
Scenario-based relieving valve with transient opening and blowdown behavior |
SafetyReliefValve |
Dynamic PSV model with configurable opening law and rated Cv |
BlowdownValve |
Timed emergency blowdown-valve opening |
ESDValve |
Emergency-shutdown valve with stroke-time behavior |
There is no ChokeValve class. Represent a production choke with
ThrottlingValve and select a multiphase choke model through its
ValveMechanicalDesign object.
Complete pressure-letdown example
The following program creates a gas stream, flashes it through a valve, and checks the defining isenthalpic relationship. Pressure units are absolute.
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import neqsim.process.equipment.stream.Stream;
import neqsim.process.equipment.valve.ThrottlingValve;
import neqsim.thermo.system.SystemInterface;
import neqsim.thermo.system.SystemSrkEos;
public final class ValveLetdownExample {
private static final Logger logger = LogManager.getLogger(ValveLetdownExample.class);
private ValveLetdownExample() {}
public static void main(String[] args) {
SystemInterface fluid = new SystemSrkEos(273.15 + 30.0, 80.0);
fluid.addComponent("methane", 0.90);
fluid.addComponent("ethane", 0.07);
fluid.addComponent("propane", 0.03);
fluid.setMixingRule("classic");
Stream inlet = new Stream("feed", fluid);
inlet.setFlowRate(10_000.0, "kg/hr");
inlet.setTemperature(30.0, "C");
inlet.setPressure(80.0, "bara");
inlet.run();
double inletEnthalpy = inlet.getFluid().getEnthalpy("J/mol");
double inletTemperature = inlet.getTemperature("C");
ThrottlingValve valve = new ThrottlingValve("PV-100", inlet);
valve.setOutletPressure(30.0, "bara");
valve.run();
double outletEnthalpy = valve.getOutletStream().getFluid().getEnthalpy("J/mol");
double outletTemperature = valve.getOutletStream().getTemperature("C");
double enthalpyResidual = outletEnthalpy - inletEnthalpy;
logger.info("Outlet temperature: {} C", outletTemperature);
logger.info("Temperature change: {} K", outletTemperature - inletTemperature);
logger.info("Molar-enthalpy residual: {} J/mol", enthalpyResidual);
}
}
The outlet temperature is calculated by an isenthalpic flash. The sign and magnitude of the Joule–Thomson temperature change depend on the fluid, temperature, pressure, and thermodynamic model.
Requested outlet pressure above the inlet
A throttling valve is a pressure-letdown device: it does not add shaft work or
compress the fluid. ThrottlingValve nevertheless accepts a specified outlet
pressure above the inlet by default. The acceptNegativeDP flag controls how
that requested thermodynamic pressure state is handled; it does not enable a
reverse-flow calculation.
| Requested pressure | acceptNegativeDP |
Outlet thermodynamic pressure | Hydraulic driving differential |
|---|---|---|---|
Pout <= Pin |
either value | Requested Pout |
Pin - Pout |
Pout > Pin |
false |
Clamped to Pin |
Zero |
Pout > Pin |
true (default) |
Requested Pout is retained |
Zero |
Use setAcceptNegativeDP(false) for a one-way pressure-letdown model that
must not report an outlet pressure above its inlet:
ThrottlingValve valve = new ThrottlingValve("PV-100", inlet);
valve.setOutletPressure(85.0, "bara");
valve.setAcceptNegativeDP(false);
valve.run();
With the flag set to true, a higher requested outlet pressure can represent
a boundary condition owned by another model. NeqSim retains that pressure for
the outlet thermodynamic state, but the valve hydraulic calculation clips the
driving differential to zero. This setting does not calculate compressor
work, valve reverse flow, or a bidirectional network solution. Model those
effects with the appropriate equipment or network formulation.
Cv, Kv, and valve opening
Cv uses the US convention and Kv the SI convention. NeqSim stores the
coefficient internally as Kv and converts with $C_v = 1.156K_v$.
ThrottlingValve valve = new ThrottlingValve("FV-100", inlet);
valve.setCv(150.0, "US");
valve.setPercentValveOpening(50.0);
double cvUS = valve.getCv("US");
double kvSI = valve.getCv("SI");
double opening = valve.getPercentValveOpening();
Setting an outlet pressure and calling run() performs a specified-pressure
letdown. To solve outlet pressure from the inlet flow, coefficient, and opening,
set the Cv/Kv and call setIsCalcOutPressure(true) before running the valve.
The result depends on the selected gas/liquid sizing behavior and valid inlet
physical properties. The legacy default sizing strategy leaves choked-flow
capacity limiting disabled, which keeps the forward flow and reverse pressure
calculations continuous and mutually invertible. The named IEC 60534,
IEC 60534 full, and prod choke strategies enable the limit by default. Set
the intended behavior explicitly after selecting the sizing strategy when the
service and configured $x_T$ require it:
valve.setAllowChoked(true);
When capacity limiting is enabled and the requested flow reaches the choked limit, downstream pressure is no longer uniquely determined by flow and Kv alone.
Initialize the inlet at the design conditions (for example, inlet.run())
before calling autoSize(safetyFactor, designOpeningPercent). Sizing preserves
the inlet flow, phase split, density, compressibility factor and heat-capacity
ratio. In particular, it must not reset an already flashed rich-gas inlet while
restoring an unchanged flow rate. A Cv copied with setCv(sizedValve.getCv())
then reproduces the same forward flow when the initialized inlet, opening,
sizing method, gas/liquid selection and correction settings are the same.
calculateOutletPressure(adjustedKv) and getOutletPressure() return bara.
Internally calculated absolute pressures are converted to the configured unit
before applying them, including when the original setpoint used barg or
kPa. This applies to both steady-state and transient calculations and avoids
adding atmospheric pressure twice. Use getOutletStream().getPressure(unit)
to read the resulting stream pressure in another unit. The one-argument
setOutletPressure(value) continues to use the previously configured unit;
use the two-argument setter when supplying a value in a different unit.
Valve characteristic and mechanical design
The inherent characteristic belongs to ValveMechanicalDesign, not directly to
ThrottlingValve. Supported strings include linear, equal percentage, and
quick opening.
import neqsim.process.mechanicaldesign.valve.ValveMechanicalDesign;
ThrottlingValve valve = new ThrottlingValve("PCV-101", inlet);
valve.setOutletPressure(60.0, "bara");
valve.run();
ValveMechanicalDesign design = valve.getMechanicalDesign();
design.setValveCharacterization("equal percentage");
design.setValveSizingStandard("IEC 60534");
design.calcDesign();
String characteristic = design.getValveCharacterization();
int ansiClass = design.getAnsiPressureClass();
double nominalSize = design.getNominalSizeInches();
double actuatorThrust = design.getRequiredActuatorThrust();
double totalWeight = design.getWeightTotal();
Mechanical-design results are preliminary sizing estimates. Review the selected standard, service, correction factors, material requirements, vendor data, and project design basis before engineering use.
Production chokes
Use ThrottlingValve; configure the choke correlation through the existing
mechanical-design object. Do not import or instantiate ChokeValve.
ThrottlingValve choke = new ThrottlingValve("Production choke", wellStream);
choke.setOutletPressure(30.0, "bara");
ValveMechanicalDesign design = choke.getMechanicalDesign();
design.setValveSizingStandard("Sachdeva");
design.setChokeDiameter(32.0, "64ths");
design.setChokeDischargeCoefficient(0.84);
The available multiphase methods and their input assumptions are documented in Multiphase Choke Flow Models.
Dynamic valve travel
ThrottlingValve supports linear travel or a first-order lag. The current and
requested openings are separate during a transient.
import java.util.UUID;
import neqsim.process.equipment.valve.ValveTravelModel;
valve.setCalculateSteadyState(false);
valve.setTravelModel(ValveTravelModel.LINEAR_RATE_LIMIT);
valve.setTravelTime(10.0);
valve.setPercentValveOpening(20.0);
valve.setTargetPercentValveOpening(80.0);
valve.runTransient(1.0, UUID.randomUUID());
double currentOpening = valve.getPercentValveOpening();
double targetOpening = valve.getTargetPercentValveOpening();
For an on/off emergency function with a prescribed stroke time, use ESDValve.
For blowdown activation logic, use BlowdownValve.
Physical and numerical checks
For every valve calculation, verify:
- the requested outlet pressure and
acceptNegativeDPsetting match the intended pressure-boundary model; - mass flow is conserved;
- a normal throttling calculation preserves specific enthalpy within numerical tolerance;
- temperature and phase changes are physically plausible for the selected fluid model;
- Cv/Kv units and pressure basis are explicit;
- choked-flow and laminar-flow assumptions match the service;
- valve opening remains within configured minimum and maximum limits.