Class Separator

All Implemented Interfaces:
Serializable, Runnable, AutoSizeable, CapacityConstrainedEquipment, ProcessEquipmentInterface, SeparatorInterface, StateVectorProvider, ProcessElementInterface, SimulationInterface, NamedInterface
Direct Known Subclasses:
CryogenicSeparator, EndFlash, GasFlotationUnit, GasScrubber, GasScrubberSimple, Hydrocyclone, Hydrocyclone, NeqGasScrubber, SimpleAbsorber, ThreePhaseSeparator, TwoPhaseSeparator

Separator class.

Capacity Utilization Calculations

To get meaningful capacity utilization results from getCapacityUtilization(), the following parameters must be set on the separator:

  1. Internal diametersetInternalDiameter(double) [m]. Default: 1.0 m. Defines the cross-sectional area available for gas flow.
  2. Separator lengthsetSeparatorLength(double) [m]. Default: 5.0 m. Used for volume calculations.
  3. OrientationsetOrientation(String), either "horizontal" (default) or "vertical". Determines how gas cross-sectional area is computed.
  4. Design gas load factor (K-factor)setDesignGasLoadFactor(double) [m/s]. Default: 0.11 m/s. This is the design K-factor from the Souders-Brown equation. Typical range: 0.07–0.15 m/s for horizontal separators, 0.04–0.10 m/s for vertical scrubbers.
  5. Design liquid level fraction (vertical only) — setDesignLiquidLevelFraction(double). Default: 0.8. The fraction of cross-sectional area occupied by liquid at design conditions.

Gas-only (dry gas) operation: If the feed contains no liquid phase, the utilization is still computed using a default liquid density of 1000 kg/m³ (DEFAULT_LIQUID_DENSITY_FOR_SIZING). This ensures scrubbers and dry-gas separators still report a meaningful gas velocity utilization.

Example usage:

Separator scrubber = new Separator("inlet scrubber", feedStream);
scrubber.setInternalDiameter(1.5); // 1.5 m ID
scrubber.setSeparatorLength(4.0); // 4.0 m length
scrubber.setOrientation("vertical");
scrubber.setDesignGasLoadFactor(0.08); // K = 0.08 m/s
scrubber.run();

double utilization = scrubber.getCapacityUtilization(); // e.g. 0.75 = 75%
Version:
$Id: $Id
Author:
Even Solbraa
See Also:
  • Field Details

    • serialVersionUID

      private static final long serialVersionUID
      Serialization version UID.
      See Also:
    • logger

      static org.apache.logging.log4j.Logger logger
      Logger object for class.
    • thermoSystem

      SystemInterface thermoSystem
    • gasSystem

      SystemInterface gasSystem
    • waterSystem

      SystemInterface waterSystem
    • liquidSystem

      SystemInterface liquidSystem
    • thermoSystemCloned

      SystemInterface thermoSystemCloned
    • thermoSystem2

      SystemInterface thermoSystem2
    • isInitTransient

      boolean isInitTransient
    • orientation

      private String orientation
      Orientation of separator. "horizontal" or "vertical"
    • gasOutStream

      StreamInterface gasOutStream
    • liquidOutStream

      StreamInterface liquidOutStream
    • pressureDrop

      private double pressureDrop
    • numberOfInputStreams

      public int numberOfInputStreams
    • inletStreamMixer

      Mixer inletStreamMixer
    • efficiency

      private double efficiency
    • liquidCarryoverFraction

      private double liquidCarryoverFraction
    • gasCarryunderFraction

      private double gasCarryunderFraction
    • specifiedStream

      private String specifiedStream
    • oilInGas

      private double oilInGas
    • oilInGasSpec

      private String oilInGasSpec
    • waterInGas

      private double waterInGas
    • waterInGasSpec

      private String waterInGasSpec
    • gasInLiquid

      private double gasInLiquid
    • gasInLiquidSpec

      private String gasInLiquidSpec
    • liquidLevel

      protected double liquidLevel
      Liquid level height in meters. Initialised to 50% of internal diameter during construction.
    • MIN_HEADSPACE_FRACTION

      private static final double MIN_HEADSPACE_FRACTION
      See Also:
    • MIN_HEADSPACE_VOLUME

      private static final double MIN_HEADSPACE_VOLUME
      See Also:
    • DEFAULT_LIQUID_DENSITY_FOR_SIZING

      public static final double DEFAULT_LIQUID_DENSITY_FOR_SIZING
      Default liquid density for sizing calculations when no liquid phase is present [kg/m³]. Assumes water density for conservative sizing.
      See Also:
    • liquidVolume

      double liquidVolume
    • gasVolume

      double gasVolume
    • separatorSection

      ArrayList<SeparatorSection> separatorSection
    • separatorMechanicalDesign

      SeparatorMechanicalDesign separatorMechanicalDesign
    • electricalDesign

      SeparatorElectricalDesign electricalDesign
    • instrumentDesign

      SeparatorInstrumentDesign instrumentDesign
    • lastEnthalpy

      private double lastEnthalpy
    • lastFlowRate

      private double lastFlowRate
    • lastPressure

      private double lastPressure
    • setHeatInput

      private boolean setHeatInput
    • heatInput

      private double heatInput
    • heatInputUnit

      private String heatInputUnit
    • DEFAULT_DESIGN_GAS_LOAD_FACTOR

      private static final double DEFAULT_DESIGN_GAS_LOAD_FACTOR
      Default design gas load factor (K-factor) [m/s]. Used to detect user overrides.
      See Also:
    • designGasLoadFactor

      private double designGasLoadFactor
      Design gas load factor (K-factor) from mechanical design [m/s].
    • designLiquidLevelFraction

      private double designLiquidLevelFraction
      Liquid level fraction (Fg) from mechanical design.
    • maxDesignGasFlowRate

      private double maxDesignGasFlowRate
      Maximum gas volumetric flow rate from design [m3/s].
    • weirHeight

      private double weirHeight
      Weir height in meters — liquid spills over the weir to the outlet.
    • weirLength

      private double weirLength
      Weir length (crest length) in meters across the separator.
    • bootVolume

      private double bootVolume
      Boot (sump) volume in m3 for water/heavy liquid collection.
    • mistEliminatorDpCoeff

      private double mistEliminatorDpCoeff
      Mist eliminator pressure drop coefficient (dP = coeff * rho * v^2 / 2).
    • mistEliminatorThickness

      private double mistEliminatorThickness
      Mist eliminator thickness in meters.
    • enforceCapacityLimits

      private boolean enforceCapacityLimits
      Whether to enforce capacity limits during simulation.
    • capacityConstraints

      private Map<String, CapacityConstraint> capacityConstraints
      Capacity constraints map for this separator.
    • performanceCalculator

      private transient SeparatorPerformanceCalculator performanceCalculator
      Optional detailed performance calculator using droplet size distributions and grade efficiency curves. When enabled, this replaces the simple entrainment fractions with physics-based calculations. Marked transient because it is not serializable by default.
    • useDetailedEntrainmentCalculation

      private boolean useDetailedEntrainmentCalculation
      Whether to use the detailed performance calculator for entrainment computation. When false (default), the simple entrainment fraction model is used.
    • autoSized

      private boolean autoSized
      Flag indicating if separator has been auto-sized.
    • MIN_DEFAULT_VOLUME_FLOW

      private static final double MIN_DEFAULT_VOLUME_FLOW
      Minimum default design volume flow in m3/hr for zero flow cases.
      See Also:
    • DEFAULT_K_VALUE_LIMIT

      public static final double DEFAULT_K_VALUE_LIMIT
      Default K-value limit per Equinor TR3500 SR-50535 [m/s]. K-value must be less than this limit related to HLL.
      See Also:
    • DEFAULT_DROPLET_CUTSIZE_LIMIT

      public static final double DEFAULT_DROPLET_CUTSIZE_LIMIT
      Default droplet cut size limit per Equinor TR3500 SR-50535 [m]. Droplet cut size must be less than 150 µm (150e-6 m).
      See Also:
    • DEFAULT_INLET_MOMENTUM_LIMIT

      public static final double DEFAULT_INLET_MOMENTUM_LIMIT
      Default inlet momentum flux limit per Equinor Revamp Limit [Pa].
      See Also:
    • DEFAULT_MIN_OIL_RETENTION_TIME

      public static final double DEFAULT_MIN_OIL_RETENTION_TIME
      Default minimum oil retention time per API 12J [minutes]. Typically 3-5 minutes for oil gravities above 35° API.
      See Also:
    • DEFAULT_MIN_WATER_RETENTION_TIME

      public static final double DEFAULT_MIN_WATER_RETENTION_TIME
      Default minimum water retention time per API 12J [minutes].
      See Also:
  • Constructor Details

    • Separator

      public Separator(String name)
      Constructor for Separator.
      Parameters:
      name - Name of separator
    • Separator

      public Separator(String name, StreamInterface inletStream)
      Constructor for Separator.
      Parameters:
      name - a String object
      inletStream - a StreamInterface object
  • Method Details

    • initializeTransientCalculation

      public void initializeTransientCalculation()
      Initializes separator for transient calculations.
    • getMechanicalDesign

      public SeparatorMechanicalDesign getMechanicalDesign()

      Get a mechanicalDesign for the equipment.

      Specified by:
      getMechanicalDesign in interface ProcessEquipmentInterface
      Overrides:
      getMechanicalDesign in class ProcessEquipmentBaseClass
      Returns:
      a MechanicalDesign object
    • initMechanicalDesign

      public void initMechanicalDesign()

      Initialize a initMechanicalDesign for the equipment.

      Specified by:
      initMechanicalDesign in interface ProcessEquipmentInterface
      Overrides:
      initMechanicalDesign in class ProcessEquipmentBaseClass
    • getElectricalDesign

      public SeparatorElectricalDesign getElectricalDesign()

      Get an electricalDesign for the equipment.

      Specified by:
      getElectricalDesign in interface ProcessEquipmentInterface
      Returns:
      a ElectricalDesign object
    • initElectricalDesign

      public void initElectricalDesign()

      Initialize an electricalDesign for the equipment.

      Specified by:
      initElectricalDesign in interface ProcessEquipmentInterface
      Overrides:
      initElectricalDesign in class ProcessEquipmentBaseClass
    • getInstrumentDesign

      public SeparatorInstrumentDesign getInstrumentDesign()
      Get an instrumentDesign for the equipment.
      Specified by:
      getInstrumentDesign in interface ProcessEquipmentInterface
      Returns:
      a InstrumentDesign object
    • initInstrumentDesign

      public void initInstrumentDesign()
      Initialize an instrumentDesign for the equipment.
      Specified by:
      initInstrumentDesign in interface ProcessEquipmentInterface
      Overrides:
      initInstrumentDesign in class ProcessEquipmentBaseClass
    • setInletStream

      public void setInletStream(StreamInterface inletStream)

      setInletStream.

      Parameters:
      inletStream - a StreamInterface object
    • addStream

      public void addStream(StreamInterface newStream)

      addStream.

      Parameters:
      newStream - a StreamInterface object
    • getLiquidOutStream

      public StreamInterface getLiquidOutStream()

      Getter for the field liquidOutStream.

      Returns:
      a StreamInterface object
    • getGasOutStream

      public StreamInterface getGasOutStream()

      Getter for the field gasOutStream.

      Returns:
      a StreamInterface object
    • getGas

      public StreamInterface getGas()

      getGas.

      Returns:
      a StreamInterface object
    • getLiquid

      public StreamInterface getLiquid()

      getLiquid.

      Returns:
      a StreamInterface object
    • getInletStreams

      public List<StreamInterface> getInletStreams()
      Returns all inlet streams connected to this equipment. Subclasses override to report their specific inlets. Used by graph builders, DEXPI export, and auto-instrumentation to discover topology without instanceof checks.
      Specified by:
      getInletStreams in interface ProcessEquipmentInterface
      Returns:
      unmodifiable list of inlet streams (empty by default)
    • getOutletStreams

      public List<StreamInterface> getOutletStreams()
      Returns all outlet streams produced by this equipment. Subclasses override to report their specific outlets. Used by graph builders, DEXPI export, and auto-instrumentation to discover topology without instanceof checks.
      Specified by:
      getOutletStreams in interface ProcessEquipmentInterface
      Returns:
      unmodifiable list of outlet streams (empty by default)
    • getEquipmentState

      public Map<String, Map<String,Object>> getEquipmentState(String temperatureUnit, String pressureUnit, String flowUnit)
      Returns a map of key equipment properties with values and units.

      Provides a unified way to access equipment state without knowing the specific equipment type. Each entry in the outer map has a property name (e.g. "temperature", "pressure"). Each inner map contains "value" (Double) and "unit" (String).

      The default implementation uses ProcessEquipmentInterface.getOutletStreams() to report outlet conditions. Subclasses override this to add equipment-specific properties (e.g., valve opening, compressor power, separator liquid levels).

      Specified by:
      getEquipmentState in interface ProcessEquipmentInterface
      Parameters:
      temperatureUnit - temperature unit (e.g. "C")
      pressureUnit - pressure unit (e.g. "bara")
      flowUnit - flow unit (e.g. "kg/hr")
      Returns:
      map of property name to value/unit maps
    • getThermoSystem

      public SystemInterface getThermoSystem()

      getThermoSystem.

      Specified by:
      getThermoSystem in interface ProcessEquipmentInterface
      Specified by:
      getThermoSystem in interface SeparatorInterface
      Overrides:
      getThermoSystem in class ProcessEquipmentBaseClass
      Returns:
      a SystemInterface object
    • setEntrainment

      public void setEntrainment(double val, String specType, String specifiedStream, String phaseFrom, String phaseTo)

      setEntrainment.

      Parameters:
      val - a double specifying the entrainment amount
      specType - a String object describing the specification unit
      specifiedStream - a String object describing the reference stream
      phaseFrom - a String object describing the phase entrained from
      phaseTo - a String object describing the phase entrained to
    • updateEntrainmentFromPerformanceCalculator

      protected void updateEntrainmentFromPerformanceCalculator()
      Updates the entrainment fractions from the detailed performance calculator. Called during run() when detailed entrainment calculation is enabled. Extracts fluid properties from the flashed thermodynamic system and runs the performance calculator.
    • run

      public void run(UUID id)

      In this method all thermodynamic and unit operations will be calculated in a steady state calculation.

      Specified by:
      run in interface SimulationInterface
      Parameters:
      id - UUID
    • displayResult

      public void displayResult()

      displayResult.

      Specified by:
      displayResult in interface ProcessEquipmentInterface
      Overrides:
      displayResult in class ProcessEquipmentBaseClass
    • getResultTable

      public String[][] getResultTable()

      getResultTable.

      Specified by:
      getResultTable in interface ProcessEquipmentInterface
      Overrides:
      getResultTable in class ProcessEquipmentBaseClass
      Returns:
      an array of String objects
    • updateEntrainmentForTransient

      protected void updateEntrainmentForTransient()
      Updates entrainment fractions from the performance calculator using the live vessel state. This method is used during transient simulation where thermoSystem (the vessel inventory) is the post-VU-flash system, as opposed to steady-state which uses thermoSystem2. Gas velocity is estimated from the gas outlet stream throughput rather than the vessel inventory flow rate. The method updates oilInGas, waterInGas, and gasInLiquid fields in the same way as the steady-state version.
    • runTransient

      public void runTransient(double dt, UUID id)

      runTransient

      This method calculates thermodynamic and unit operations using difference equations if available and calculateSteadyState is true. Use setCalculateSteadyState to set the parameter. Sets calc identifier UUID.
      Specified by:
      runTransient in interface SimulationInterface
      Parameters:
      dt - Delta time [s]
      id - Calculation identifier
    • setTempPres

      public void setTempPres(double temp, double pres)

      setTempPres.

      Parameters:
      temp - a double
      pres - a double
    • getEfficiency

      public double getEfficiency()

      Getter for the field efficiency.

      Returns:
      a double
    • setEfficiency

      public void setEfficiency(double efficiency)

      Setter for the field efficiency.

      Parameters:
      efficiency - a double
    • getLiquidCarryoverFraction

      public double getLiquidCarryoverFraction()

      Getter for the field liquidCarryoverFraction.

      Returns:
      a double
    • setLiquidCarryoverFraction

      public void setLiquidCarryoverFraction(double liquidCarryoverFraction)

      Setter for the field liquidCarryoverFraction.

      Parameters:
      liquidCarryoverFraction - a double
    • getGasCarryunderFraction

      public double getGasCarryunderFraction()

      Getter for the field gasCarryunderFraction.

      Returns:
      a double
    • setGasCarryunderFraction

      public void setGasCarryunderFraction(double gasCarryunderFraction)

      Setter for the field gasCarryunderFraction.

      Parameters:
      gasCarryunderFraction - a double
    • setDetailedEntrainmentCalculation

      public void setDetailedEntrainmentCalculation(boolean enabled)
      Enables or disables the detailed droplet-based entrainment calculation. When enabled, the separator uses a SeparatorPerformanceCalculator with droplet size distributions and grade efficiency curves instead of simple entrainment fractions.
      Parameters:
      enabled - true to enable detailed calculation, false to use simple fractions
    • isDetailedEntrainmentCalculation

      public boolean isDetailedEntrainmentCalculation()
      Returns whether detailed entrainment calculation is enabled.
      Returns:
      true if detailed calculation is enabled
    • getPerformanceCalculator

      public SeparatorPerformanceCalculator getPerformanceCalculator()
      Gets the detailed performance calculator. Creates one if it does not exist.
      Returns:
      the performance calculator
    • setPerformanceCalculator

      public void setPerformanceCalculator(SeparatorPerformanceCalculator calculator)
      Sets the detailed performance calculator.
      Parameters:
      calculator - the performance calculator to use
    • setEnhancedEntrainmentCalculation

      public void setEnhancedEntrainmentCalculation(boolean enabled)
      Enables the enhanced (state-of-the-art) entrainment calculation with flow regime prediction, inlet device modeling, detailed vessel geometry, and database-driven internals. This automatically enables the detailed entrainment calculation.
      Parameters:
      enabled - true to enable enhanced calculation
    • isEnhancedEntrainmentCalculation

      public boolean isEnhancedEntrainmentCalculation()
      Returns whether the enhanced entrainment calculation is enabled.
      Returns:
      true if enhanced calculation is enabled
    • setInletDeviceType

      public void setInletDeviceType(InletDeviceModel.InletDeviceType deviceType)
      Sets the inlet device type for the enhanced entrainment calculation.
      Parameters:
      deviceType - the inlet device type
    • setInletPipeDiameter

      public void setInletPipeDiameter(double diameter)
      Sets the inlet pipe diameter for flow regime calculation. This affects the DSD generated from inlet pipe flow regime correlations.
      Parameters:
      diameter - inlet pipe internal diameter [m]
    • setGasLiquidSurfaceTension

      public void setGasLiquidSurfaceTension(double sigma)
      Sets the gas-liquid interfacial tension for DSD generation in the enhanced model.
      Parameters:
      sigma - interfacial tension [N/m]
    • getInletFlowRegime

      public MultiphaseFlowRegime.FlowRegime getInletFlowRegime()
      Gets the predicted inlet flow regime from the last enhanced calculation.
      Returns:
      flow regime enum or null if not calculated
    • getKFactor

      public double getKFactor()
      Gets the K-factor (Souders-Brown) from the last enhanced calculation.
      Returns:
      K-factor [m/s] or 0 if not calculated
    • getKFactorUtilization

      public double getKFactorUtilization()
      Gets the K-factor utilization from the last enhanced calculation.
      Returns:
      utilization ratio (operating/design), values above 1.0 indicate flooding
    • isMistEliminatorFlooded

      public boolean isMistEliminatorFlooded()
      Returns whether the mist eliminator was detected as flooded in the last calculation.
      Returns:
      true if flooded
    • setLiquidLevel

      public void setLiquidLevel(double liquidlev)

      Setter for the field liquidLevel.

      Specified by:
      setLiquidLevel in interface SeparatorInterface
      Parameters:
      liquidlev - a double
    • getLiquidLevel

      public double getLiquidLevel()

      Getter for the field liquidLevel in percentage.

      Returns:
      a double
    • getPressureDrop

      public double getPressureDrop()

      Getter for the field pressureDrop.

      Returns:
      the pressureDrop
    • setPressureDrop

      public void setPressureDrop(double pressureDrop)

      Setter for the field pressureDrop.

      Parameters:
      pressureDrop - the pressureDrop to set
    • getInternalDiameter

      public double getInternalDiameter()
      Returns the vessel internal diameter [m]. The value is stored in the MechanicalDesign (single source of truth) and accessed here via delegation.
      Returns:
      internal diameter in metres
    • setInternalDiameter

      public void setInternalDiameter(double diameter)

      setInternalDiameter.

      Specified by:
      setInternalDiameter in interface SeparatorInterface
      Parameters:
      diameter - a double
    • getInternalRadius

      private double getInternalRadius()
      Returns the internal radius [m], computed from the internal diameter.
      Returns:
      half of the internal diameter
    • getSepCrossArea

      private double getSepCrossArea()
      Returns the cross-sectional area of the separator [m2], computed from the internal diameter.
      Returns:
      pi/4 * D^2
    • getSeparatorVolume

      private double getSeparatorVolume()
      Returns the total separator volume [m3], computed from cross-sectional area and length.
      Returns:
      cross-sectional area * length
    • hasGeometry

      public boolean hasGeometry()
      Checks whether vessel geometry has been explicitly set on this separator. When false, methods that depend on geometry (capacity utilization, gas velocity, dynamic volumes) may return NaN or zero.
      Returns:
      true if internal diameter is greater than zero
    • getGasSuperficialVelocity

      public double getGasSuperficialVelocity()

      getGasSuperficialVelocity. Uses design liquid level fraction to determine available gas area, independent of operating liquid level.

      Returns:
      gas superficial velocity [m/s]
    • getGasLoadFactor

      public double getGasLoadFactor()

      getGasLoadFactor.

      Returns:
      a double
    • getGasLoadFactor

      public double getGasLoadFactor(int phaseNumber)

      getGasLoadFactor.

      Parameters:
      phaseNumber - a int
      Returns:
      a double
    • getDeRatedGasLoadFactor

      public double getDeRatedGasLoadFactor()

      getDeRatedGasLoadFactor.

      Returns:
      a double
    • getDeRatedGasLoadFactor

      public double getDeRatedGasLoadFactor(int phaseNum)

      getDeRatedGasLoadFactor.

      Parameters:
      phaseNum - a int
      Returns:
      a double
    • getDesignGasLoadFactor

      public double getDesignGasLoadFactor()
      Gets the design gas load factor (K-factor) that the separator is designed for.
      Returns:
      design gas load factor [m/s]
    • setDesignGasLoadFactor

      public void setDesignGasLoadFactor(double kFactor)
      Sets the design gas load factor (K-factor) for the separator. This is the key parameter for capacity utilization calculations via the Souders-Brown equation. Also updates the associated capacity constraint if one exists.

      Typical values:

      • Horizontal separator: 0.07–0.15 m/s
      • Vertical separator/scrubber: 0.04–0.10 m/s
      • With mesh/vane demister: towards upper end of range
      • Without internals: towards lower end of range
      Parameters:
      kFactor - design gas load factor [m/s], typically 0.04–0.15 depending on type
      See Also:
    • getMaxAllowableGasVelocity

      public double getMaxAllowableGasVelocity()
      Calculates the maximum allowable gas velocity based on the design K-factor. Uses the Souders-Brown equation: V_max = K * sqrt((rho_liq - rho_gas) / rho_gas)

      If no liquid phase is present, a default liquid density of 1000 kg/m³ is assumed for sizing purposes.

      Returns:
      maximum allowable gas velocity [m/s]
    • getMaxAllowableGasFlowRate

      public double getMaxAllowableGasFlowRate()
      Calculates the maximum allowable gas volumetric flow rate based on separator design. This combines the max allowable gas velocity (from the Souders-Brown equation) with the available gas flow area, which depends on the separator orientation, internal diameter, and liquid level.
      Returns:
      maximum allowable gas flow rate [m3/s]
      See Also:
    • getCapacityUtilization

      public double getCapacityUtilization()
      Gets the capacity utilization as a fraction (current gas flow / max design gas flow). A value greater than 1.0 indicates the separator is overloaded.

      For single-phase gas (no liquid), the utilization is still computed using a default liquid density of 1000 kg/m³ (DEFAULT_LIQUID_DENSITY_FOR_SIZING). This is important for scrubbers that handle dry gas — the gas velocity capacity limit still applies.

      The calculation depends on the following parameters being set:

      Returns:
      capacity utilization fraction (0.0 to 1.0+ if overloaded), or 0.0 if liquid-only (no gas separation needed), or Double.NaN if calculation error
      See Also:
    • isSinglePhase

      public boolean isSinglePhase()
      Checks if the separator feed is single-phase (no separation required).
      Returns:
      true if the thermodynamic system has only one phase
    • isOverloaded

      public boolean isOverloaded()
      Checks if the separator is overloaded (operating above design capacity).
      Returns:
      true if capacity utilization is greater than 1.0
    • isSimulationValid

      public boolean isSimulationValid()
      Checks if the current simulation result is physically valid.

      Returns false if calculated values are outside physically possible ranges. This method should be overridden by specific equipment types to perform equipment-specific validation. For example:

      • Compressor: power must be positive, head must be positive
      • Heat exchanger: duty direction must match temperature change
      • Separator: phase fractions must sum to 1.0

      Validates that the separator simulation produced physically reasonable results.

      Specified by:
      isSimulationValid in interface ProcessEquipmentInterface
      Returns:
      true if simulation results are physically valid, false otherwise
    • getSimulationValidationErrors

      public List<String> getSimulationValidationErrors()
      Gets validation errors for the current simulation state.

      Returns a list of human-readable error messages describing why the simulation result is invalid. Returns an empty list if the simulation is valid.

      Specified by:
      getSimulationValidationErrors in interface ProcessEquipmentInterface
      Returns:
      list of validation error messages, empty if valid
    • isWithinOperatingEnvelope

      public boolean isWithinOperatingEnvelope()
      Checks if the equipment is operating within its valid operating envelope.

      This is different from capacity utilization - it checks whether the equipment can physically operate at the current conditions, not whether it's operating efficiently. For example:

      • Compressor: checks if between surge and stonewall
      • Pump: checks if above minimum flow (no cavitation)
      • Heat exchanger: checks if approach temperature is positive

      Checks if the separator is operating within its valid envelope. For separators, this means not overloaded (gas velocity within design limits).

      Specified by:
      isWithinOperatingEnvelope in interface ProcessEquipmentInterface
      Returns:
      true if operating within valid envelope
    • getOperatingEnvelopeViolation

      public String getOperatingEnvelopeViolation()
      Gets the reason why equipment is outside its operating envelope.
      Specified by:
      getOperatingEnvelopeViolation in interface ProcessEquipmentInterface
      Returns:
      description of envelope violation, or null if within envelope
    • isEnforceCapacityLimits

      public boolean isEnforceCapacityLimits()
      Gets whether capacity limits are enforced during simulation.
      Returns:
      true if capacity limits are enforced
    • setEnforceCapacityLimits

      public void setEnforceCapacityLimits(boolean enforce)
      Sets whether to enforce capacity limits during simulation. When enabled, the simulation will check if flow exceeds separator design capacity.
      Parameters:
      enforce - true to enforce capacity limits
    • sizeFromFlow

      public void sizeFromFlow(double safetyFactor)
      Sizes the separator diameter based on the current flow conditions and design K-factor. Uses the Souders-Brown equation to calculate the required diameter.

      If no liquid phase is present, a default liquid density of 1000 kg/m³ is assumed for sizing purposes.

      Parameters:
      safetyFactor - design safety factor (typically 1.1-1.5)
    • autoSize

      public void autoSize(double safetyFactor)
      Automatically size the equipment based on connected stream conditions.

      This method calculates dimensions and design parameters using the inlet stream properties and applies the specified safety factor. The equipment must have a valid inlet stream connected before calling this method.

      Specified by:
      autoSize in interface AutoSizeable
      Parameters:
      safetyFactor - multiplier for design capacity, typically 1.1-1.3 (10-30% over design)
    • autoSize

      public void autoSize()
      Automatically size using default safety factor (1.2 = 20% margin).
      Specified by:
      autoSize in interface AutoSizeable
    • autoSize

      public void autoSize(String company, String trDocument)
      Automatically size using company-specific design standards.

      This method applies design rules from the specified company's technical requirements (TR) documents. The standards are loaded from the NeqSim design database.

      Specified by:
      autoSize in interface AutoSizeable
      Parameters:
      company - company name (e.g., "Equinor", "Shell", "TotalEnergies")
      trDocument - TR document reference (e.g., "TR2000", "DEP-31.38.01.11")
    • isAutoSized

      public boolean isAutoSized()
      Check if equipment has been auto-sized.
      Specified by:
      isAutoSized in interface AutoSizeable
      Returns:
      true if autoSize() has been called successfully
    • getSizingReport

      public String getSizingReport()
      Get a detailed sizing report after auto-sizing.

      The report includes:

      • Design basis (flow rates, pressures, temperatures)
      • Calculated dimensions
      • Design parameters (K-factor, Cv, velocity, etc.)
      • Safety margins
      Specified by:
      getSizingReport in interface AutoSizeable
      Returns:
      formatted sizing report string
    • getSizingReportJson

      public String getSizingReportJson()
      Get sizing report as JSON for programmatic access.
      Specified by:
      getSizingReportJson in interface AutoSizeable
      Returns:
      JSON string with sizing data
    • initDesignFromFlow

      public void initDesignFromFlow()
      Initializes separator dimensions from mechanical design calculations. This uses the mechanical design module to size the separator based on flow.
    • getOrientation

      public String getOrientation()

      Getter for the field orientation.

      Returns:
      the orientation
    • setOrientation

      public void setOrientation(String orientation)

      Setter for the field orientation.

      Parameters:
      orientation - the orientation to set
    • liquidArea

      public double liquidArea(double level)

      Calculates both gas and liquid fluid section areas for horizontal separators. Results can be used for volume calculation, gas superficial velocity, and settling time.

      Parameters:
      level - current liquid level inside the separator [m]
      Returns:
      separator liquid area.
    • calcLiquidVolume

      public double calcLiquidVolume()

      calculates liquid volume based on separator type.

      Returns:
      liquid level in the separator
    • updateHoldupVolumes

      private void updateHoldupVolumes()
      Keeps cached gas/liquid holdup volumes aligned with current geometry and level.
    • enforceHeadspace

      protected void enforceHeadspace()
    • getMaxLiquidHeight

      private double getMaxLiquidHeight()
    • getMinGasVolume

      private double getMinGasVolume()
    • clampLiquidHeight

      private double clampLiquidHeight(double height)
    • getInnerSurfaceArea

      public double getInnerSurfaceArea()
      Calculates the total inner surface area of the separator, including shell and heads.
      Returns:
      inner surface area in square meters
    • getWettedArea

      public double getWettedArea()
      Estimates the wetted inner surface area based on current liquid level and orientation.

      For horizontal separators, the wetted area uses the circular segment defined by the liquid level to apportion the cylindrical shell and head areas. For vertical separators, the wetted area is the side area up to the current level plus the bottom head.

      Returns:
      wetted area in square meters
    • getUnwettedArea

      public double getUnwettedArea()
      Estimates the unwetted (dry) area as the remaining inner area not in contact with liquid.
      Returns:
      unwetted area in square meters
    • evaluateFireExposure

      Evaluates fire exposure using the separator geometry and process conditions.
      Parameters:
      config - fire scenario configuration
      Returns:
      aggregated fire exposure result
    • evaluateFireExposure

      public SeparatorFireExposure.FireExposureResult evaluateFireExposure(SeparatorFireExposure.FireScenarioConfig config, Flare flare, double flareGroundDistanceM)
      Evaluates fire exposure using separator geometry and process conditions while accounting for flare radiation based on the real flaring heat duty.
      Parameters:
      config - fire scenario configuration
      flare - flare supplying heat duty and radiation parameters
      flareGroundDistanceM - horizontal distance from flare base to separator [m]
      Returns:
      aggregated fire exposure result
    • levelFromVolume

      public double levelFromVolume(double volumeTarget)

      Estimates liquid level based on volume for horizontal separators using bisection method. Vertical separators too. tol and maxIter are bisection loop parameters.

      Parameters:
      volumeTarget - desired liquid volume to be held in the separator [m3]
      Returns:
      liquid level in the separator
    • getSeparatorLength

      public double getSeparatorLength()
      Returns the separator tan-tan length [m]. The value is stored in the MechanicalDesign (single source of truth).
      Returns:
      separator length in metres
    • setSeparatorLength

      public void setSeparatorLength(double length)
      Sets the separator tan-tan length [m]. The value is stored in the MechanicalDesign (single source of truth).
      Parameters:
      length - the separator length to set [m]
    • setWeirHeight

      public void setWeirHeight(double height)
      Sets the weir height in meters. Liquid overflows the weir to the outlet. The liquid outlet flow is modelled as Francis weir flow: Q = Cw * Lw * h_ow^1.5 where h_ow is the liquid height above the weir.
      Parameters:
      height - weir height in meters (must be positive, less than internal diameter)
    • getWeirHeight

      public double getWeirHeight()
      Gets the weir height in meters.
      Returns:
      the weir height
    • setWeirLength

      public void setWeirLength(double length)
      Sets the weir length (crest length) in meters.
      Parameters:
      length - the weir crest length in meters
    • getWeirLength

      public double getWeirLength()
      Gets the weir length in meters.
      Returns:
      the weir length
    • setBootVolume

      public void setBootVolume(double volume)
      Sets the boot (sump) volume in cubic meters. The boot is used for water or heavy liquid collection below the main separator body.
      Parameters:
      volume - boot volume in m3
    • getBootVolume

      public double getBootVolume()
      Gets the boot volume in cubic meters.
      Returns:
      the boot volume
    • setMistEliminatorDpCoeff

      public void setMistEliminatorDpCoeff(double coefficient)
      Sets the mist eliminator pressure drop coefficient. The pressure drop across the mist eliminator is calculated as dP = coeff * 0.5 * rho_gas * v_gas^2.
      Parameters:
      coefficient - the pressure drop coefficient (dimensionless)
    • getMistEliminatorDpCoeff

      public double getMistEliminatorDpCoeff()
      Gets the mist eliminator pressure drop coefficient.
      Returns:
      the pressure drop coefficient
    • setMistEliminatorThickness

      public void setMistEliminatorThickness(double thickness)
      Sets the mist eliminator thickness in meters.
      Parameters:
      thickness - the mist eliminator pad thickness in meters
    • getMistEliminatorThickness

      public double getMistEliminatorThickness()
      Gets the mist eliminator thickness in meters.
      Returns:
      the thickness in meters
    • getWeirOverflowRate

      public double getWeirOverflowRate()
      Calculates the liquid overflow rate over the weir using the Francis weir formula. Q = Cw * Lw * h_ow^1.5 where Cw is the weir coefficient (1.84 for SI units), Lw is the weir crest length, and h_ow is the liquid height above the weir.
      Returns:
      the volumetric overflow rate in m3/s, or 0 if liquid is below the weir
    • getMistEliminatorPressureDrop

      public double getMistEliminatorPressureDrop()
      Calculates the mist eliminator pressure drop in Pascal based on the current gas velocity and density.
      Returns:
      pressure drop in Pa, or 0 if no mist eliminator is configured
    • getSeparatorSection

      public SeparatorSection getSeparatorSection(int i)

      Getter for the field separatorSection.

      Parameters:
      i - a int
      Returns:
      a SeparatorSection object
    • getSeparatorSection

      public SeparatorSection getSeparatorSection(String name)

      Getter for the field separatorSection.

      Parameters:
      name - a String object
      Returns:
      a SeparatorSection object
    • getSeparatorSections

      public ArrayList<SeparatorSection> getSeparatorSections()

      getSeparatorSections.

      Returns:
      a ArrayList object
    • addSeparatorSection

      public void addSeparatorSection(String name, String type)

      addSeparatorSection.

      Parameters:
      name - a String object
      type - a String object
    • getDesignLiquidLevelFraction

      public double getDesignLiquidLevelFraction()

      Getter for the field designLiquidLevelFraction.

      Returns:
      the designGasLevelFraction
    • setDesignLiquidLevelFraction

      public void setDesignLiquidLevelFraction(double designLiquidLevelFraction)

      Setter for the field designLiquidLevelFraction.

      Parameters:
      designLiquidLevelFraction - a double
    • getPressure

      public double getPressure()

      Getter for the field pressure.

      Specified by:
      getPressure in interface ProcessEquipmentInterface
      Overrides:
      getPressure in class ProcessEquipmentBaseClass
      Returns:
      Pressure in bara
    • getEntropyProduction

      public double getEntropyProduction(String unit)

      getEntropyProduction.

      Specified by:
      getEntropyProduction in interface ProcessEquipmentInterface
      Overrides:
      getEntropyProduction in class ProcessEquipmentBaseClass
      Parameters:
      unit - a String object
      Returns:
      a double
    • getMassBalance

      public double getMassBalance(String unit)

      getMassBalance.

      Specified by:
      getMassBalance in interface ProcessEquipmentInterface
      Overrides:
      getMassBalance in class ProcessEquipmentBaseClass
      Parameters:
      unit - a String object
      Returns:
      a double
    • getExergyChange

      public double getExergyChange(String unit, double surroundingTemperature)
      Get exergy change production of the process equipment.
      Specified by:
      getExergyChange in interface ProcessEquipmentInterface
      Overrides:
      getExergyChange in class ProcessEquipmentBaseClass
      Parameters:
      unit - Supported units are J and kJ
      surroundingTemperature - The surrounding temperature in Kelvin
      Returns:
      change in exergy in specified unit
    • hashCode

      public int hashCode()
      Specified by:
      hashCode in interface ProcessEquipmentInterface
      Overrides:
      hashCode in class ProcessEquipmentBaseClass
    • equals

      public boolean equals(Object obj)
      Specified by:
      equals in interface ProcessEquipmentInterface
      Overrides:
      equals in class ProcessEquipmentBaseClass
    • getFeedStream

      public StreamInterface getFeedStream()

      getFeedStream.

      Returns:
      a StreamInterface object
    • toJson

      public String toJson()

      Serializes the Process Equipment along with its state to a JSON string.

      Specified by:
      toJson in interface ProcessEquipmentInterface
      Overrides:
      toJson in class ProcessEquipmentBaseClass
      Returns:
      json string.
    • toJson

      public String toJson(ReportConfig cfg)
      Serializes the Process Equipment with configurable level of detail.
      Specified by:
      toJson in interface ProcessEquipmentInterface
      Overrides:
      toJson in class ProcessEquipmentBaseClass
      Parameters:
      cfg - report configuration
      Returns:
      json string
    • setHeatInput

      public void setHeatInput(double heatInput)
      Set heat input to the separator (e.g., from flare radiation, external heating).
      Specified by:
      setHeatInput in interface SeparatorInterface
      Parameters:
      heatInput - heat duty in watts
    • setHeatInput

      public void setHeatInput(double heatInput, String unit)
      Set heat input to the separator with specified unit.
      Specified by:
      setHeatInput in interface SeparatorInterface
      Parameters:
      heatInput - heat duty value
      unit - heat duty unit (W, kW, MW, J/s, etc.)
    • setHeatDuty

      public void setHeatDuty(double heatDuty)
      Set heat duty (alias for setHeatInput).
      Parameters:
      heatDuty - heat duty in watts
    • setHeatDuty

      public void setHeatDuty(double heatDuty, String unit)
      Set heat duty with unit (alias for setHeatInput).
      Parameters:
      heatDuty - heat duty value
      unit - heat duty unit
    • setDuty

      public void setDuty(double heatDuty)
      Set heat duty (alias preserved for compatibility with energy-stream style naming).
      Parameters:
      heatDuty - heat duty in watts
    • setDuty

      public void setDuty(double heatDuty, String unit)
      Set heat duty with unit (alias preserved for compatibility with energy-stream style naming).
      Parameters:
      heatDuty - heat duty value
      unit - heat duty unit
    • getHeatInput

      public double getHeatInput()
      Get heat input in watts.
      Specified by:
      getHeatInput in interface SeparatorInterface
      Returns:
      heat input in watts
    • getHeatInput

      public double getHeatInput(String unit)
      Get heat input in specified unit.
      Specified by:
      getHeatInput in interface SeparatorInterface
      Parameters:
      unit - desired unit (W, kW, MW)
      Returns:
      heat input in specified unit
    • getHeatDuty

      public double getHeatDuty()
      Get heat duty (alias for getHeatInput).
      Returns:
      heat duty in watts
    • getHeatDuty

      public double getHeatDuty(String unit)
      Get heat duty in specified unit.
      Parameters:
      unit - desired unit
      Returns:
      heat duty in specified unit
    • isSetHeatInput

      public boolean isSetHeatInput()
      Check if heat input is set.
      Specified by:
      isSetHeatInput in interface SeparatorInterface
      Returns:
      true if heat input is explicitly set
    • getExergyChange

      public double getExergyChange(String unit)

      getExergyChange.

      Specified by:
      getExergyChange in interface ProcessEquipmentInterface
      Parameters:
      unit - a String object
      Returns:
      a double
    • getCapacityDuty

      public double getCapacityDuty()

      getCapacityDuty.

      For separators, capacity duty is defined as the gas outlet volumetric flow rate in m³/hr. This is used in conjunction with getCapacityMax() for bottleneck analysis via ProcessSystem.getBottleneck().

      Specified by:
      getCapacityDuty in interface ProcessEquipmentInterface
      Returns:
      gas outlet flow rate in m³/hr
    • getCapacityMax

      public double getCapacityMax()

      getCapacityMax.

      For separators, maximum capacity is defined by the mechanical design's maximum gas volume flow in m³/hr. If not set, the value is derived from the gas load factor design: designGasLoadFactor * crossSectionalArea * 3600.

      Specified by:
      getCapacityMax in interface ProcessEquipmentInterface
      Returns:
      maximum design gas volume flow in m³/hr
      See Also:
    • getStateVector

      public StateVector getStateVector()
      Get the current state as a standardized vector.

      The state vector should include all observable variables relevant for control and monitoring. Values should be in physical units with appropriate bounds.

      Returns state vector containing:

      • pressure - Separator pressure [bar]
      • temperature - Separator temperature [K]
      • liquid_level - Liquid level fraction [0-1]
      • gas_density - Gas phase density [kg/m³]
      • liquid_density - Liquid phase density [kg/m³]
      • gas_flow - Gas outlet flow [kg/s]
      • liquid_flow - Liquid outlet flow [kg/s]
      • gas_load_factor - Gas load factor [-]
      Specified by:
      getStateVector in interface StateVectorProvider
      Returns:
      current state vector
    • validateSetup

      public ValidationResult validateSetup()
      Validate the process equipment before execution.

      Checks for common setup errors:

      • Equipment has a valid name
      • Input streams connected
      • Operating parameters in valid ranges

      Validates the separator setup before execution. Checks that:

      • Equipment has a valid name
      • At least one inlet stream is connected
      • Separator dimensions are positive
      • Liquid level is within valid range
      Specified by:
      validateSetup in interface ProcessEquipmentInterface
      Returns:
      validation result with errors and warnings
    • initializeCapacityConstraints

      protected void initializeCapacityConstraints()
      Initializes default capacity constraints for this separator.

      Creates constraints for gas load factor based on the separator's design parameters. Additional constraints like liquid residence time can be added after construction.

      Note: All separator constraints (gas load factor, K-value, droplet cut size, inlet momentum, retention times) are disabled by default for backwards compatibility with the optimizer. Use useEquinorConstraints(), useAPIConstraints(), or useAllConstraints() to enable them explicitly for capacity analysis.

    • setKValueLimit

      public void setKValueLimit(double limit)
      Set custom K-value limit for the separator constraint.
      Parameters:
      limit - K-value limit in m/s (default 0.15 per TR3500)
    • setDropletCutSizeLimit

      public void setDropletCutSizeLimit(double limitMicrons)
      Set custom droplet cut size limit for the separator constraint.
      Parameters:
      limitMicrons - droplet cut size limit in micrometers (default 150 µm per TR3500)
    • setInletMomentumLimit

      public void setInletMomentumLimit(double limitPa)
      Set custom inlet momentum limit for the separator constraint.
      Parameters:
      limitPa - momentum flux limit in Pa (default 16000 Pa per Equinor Revamp)
    • setMinOilRetentionTime

      public void setMinOilRetentionTime(double minMinutes)
      Set custom minimum oil retention time for the separator constraint.
      Parameters:
      minMinutes - minimum oil retention time in minutes (default 3 min per API 12J)
    • setMinWaterRetentionTime

      public void setMinWaterRetentionTime(double minMinutes)
      Set custom minimum water retention time for the separator constraint.
      Parameters:
      minMinutes - minimum water retention time in minutes (default 3 min per API 12J)
    • getConstraintSummary

      public String getConstraintSummary()
      Get a summary of all constraint utilizations.
      Returns:
      constraint summary as formatted string
    • getCapacityConstraints

      public Map<String, CapacityConstraint> getCapacityConstraints()
      Gets all capacity constraints defined for this equipment.

      Returns an unmodifiable map of constraint name to constraint object. Constraints are used by the optimization framework to detect bottlenecks, enforce limits, and guide production allocation. Equipment subclasses populate this map via ProcessEquipmentInterface.addCapacityConstraint(CapacityConstraint).

      Specified by:
      getCapacityConstraints in interface CapacityConstrainedEquipment
      Specified by:
      getCapacityConstraints in interface ProcessEquipmentInterface
      Overrides:
      getCapacityConstraints in class ProcessEquipmentBaseClass
      Returns:
      unmodifiable map of constraint name to constraint, empty if none defined
    • getBottleneckConstraint

      public CapacityConstraint getBottleneckConstraint()
      Gets the bottleneck (most limiting) constraint for this equipment.

      Returns the enabled constraint with the highest utilization ratio. If no constraints are defined or enabled, returns null.

      Specified by:
      getBottleneckConstraint in interface CapacityConstrainedEquipment
      Specified by:
      getBottleneckConstraint in interface ProcessEquipmentInterface
      Overrides:
      getBottleneckConstraint in class ProcessEquipmentBaseClass
      Returns:
      the most limiting constraint, or null if none
    • isCapacityExceeded

      public boolean isCapacityExceeded()
      Checks if any capacity constraint is violated (exceeds 100% utilization).

      A violated constraint means the equipment is operating beyond its design capacity. For HARD constraints, this may indicate equipment trip or failure. For SOFT constraints, this indicates reduced efficiency or accelerated wear.

      Specified by:
      isCapacityExceeded in interface CapacityConstrainedEquipment
      Specified by:
      isCapacityExceeded in interface ProcessEquipmentInterface
      Overrides:
      isCapacityExceeded in class ProcessEquipmentBaseClass
      Returns:
      true if any enabled constraint utilization exceeds 1.0 (100%)
    • isHardLimitExceeded

      public boolean isHardLimitExceeded()
      Checks if any HARD constraint limit is exceeded.

      HARD limits represent absolute equipment limits (e.g., maximum speed) that cannot be exceeded without equipment trip or damage. This is more severe than general capacity exceedance.

      Specified by:
      isHardLimitExceeded in interface CapacityConstrainedEquipment
      Specified by:
      isHardLimitExceeded in interface ProcessEquipmentInterface
      Overrides:
      isHardLimitExceeded in class ProcessEquipmentBaseClass
      Returns:
      true if any enabled HARD constraint's max value is exceeded
    • getMaxUtilization

      public double getMaxUtilization()
      Gets the maximum utilization across all enabled constraints.

      Returns the highest utilization ratio across all enabled constraints. Values above 1.0 indicate the equipment is over capacity. Returns 0.0 if no constraints are defined or enabled.

      Specified by:
      getMaxUtilization in interface CapacityConstrainedEquipment
      Specified by:
      getMaxUtilization in interface ProcessEquipmentInterface
      Overrides:
      getMaxUtilization in class ProcessEquipmentBaseClass
      Returns:
      maximum utilization as fraction (1.0 = 100% of design capacity)
    • addCapacityConstraint

      public void addCapacityConstraint(CapacityConstraint constraint)
      Adds a capacity constraint to this equipment.

      Constraints can be added at any time. If a constraint with the same name already exists, it is replaced. Use the fluent builder API on CapacityConstraint to configure the constraint before adding.

      Specified by:
      addCapacityConstraint in interface CapacityConstrainedEquipment
      Specified by:
      addCapacityConstraint in interface ProcessEquipmentInterface
      Overrides:
      addCapacityConstraint in class ProcessEquipmentBaseClass
      Parameters:
      constraint - the capacity constraint to add (ignored if null)
    • removeCapacityConstraint

      public boolean removeCapacityConstraint(String constraintName)
      Removes a capacity constraint by name.
      Specified by:
      removeCapacityConstraint in interface CapacityConstrainedEquipment
      Parameters:
      constraintName - the name of the constraint to remove
      Returns:
      true if the constraint was found and removed
    • clearCapacityConstraints

      public void clearCapacityConstraints()
      Clears all capacity constraints from this equipment.
      Specified by:
      clearCapacityConstraints in interface CapacityConstrainedEquipment
    • useConstraints

      public void useConstraints(String... constraintNames)
      Enable only the specified constraints by name. All other constraints are removed.

      Available constraint names:

      • "gasLoadFactor" - Gas load factor (K-factor)
      • "kValue" - K-value (Souders-Brown) at HLL per TR3500
      • "dropletCutSize" - Droplet cut size per TR3500
      • "inletMomentum" - Inlet nozzle momentum flux
      • "oilRetentionTime" - Oil retention time per API 12J
      • "waterRetentionTime" - Water retention time per API 12J
      Parameters:
      constraintNames - names of constraints to enable (all others will be disabled)
    • enableConstraints

      public void enableConstraints(String... constraintNames)
      Enable specific constraints by name (additive - doesn't disable others). Use this to add constraints to the existing set without clearing others.
      Parameters:
      constraintNames - names of constraints to enable
    • disableConstraints

      public void disableConstraints(String... constraintNames)
      Disable specific constraints by name.
      Parameters:
      constraintNames - names of constraints to disable
    • useEquinorConstraints

      public void useEquinorConstraints()
      Use Equinor TR3500 constraints (K-value, droplet cut size, inlet momentum, retention times). Enables these constraints in addition to the default gas load factor.
    • useAPIConstraints

      public void useAPIConstraints()
      Use API 12J constraints (K-value, retention times). Enables these constraints in addition to the default gas load factor.
    • useGasScrubberConstraints

      public void useGasScrubberConstraints()
      Use gas scrubber constraints (gas load factor and inlet momentum). For gas scrubbers, the gas load factor (K-factor) is the primary performance metric as liquid retention is not relevant - the focus is on removing liquid droplets from gas. Inlet momentum is also checked to ensure the inlet nozzle velocity does not re-entrain separated liquid.
    • useGasCapacityConstraints

      public void useGasCapacityConstraints()
      Use gas capacity constraints (gas load factor, K-value, droplet cut size, inlet momentum).
    • useLiquidCapacityConstraints

      public void useLiquidCapacityConstraints()
      Use liquid capacity constraints (retention times).
    • useAllConstraints

      public void useAllConstraints()
      Use all available constraints. Enables all constraints including the new TR3500/API 12J constraints.
    • disableConstraint

      public boolean disableConstraint(String constraintName)
      Disable a specific constraint by name.
      Parameters:
      constraintName - name of constraint to disable
      Returns:
      true if constraint was found and disabled
    • isConstraintEnabled

      public boolean isConstraintEnabled(String constraintName)
      Check if a specific constraint is enabled.
      Parameters:
      constraintName - name of constraint to check
      Returns:
      true if constraint exists and is enabled
    • getEnabledConstraintNames

      public List<String> getEnabledConstraintNames()
      Get list of all enabled constraint names.
      Returns:
      list of constraint names that are enabled
    • calcGasAreaAboveLevel

      public double calcGasAreaAboveLevel(double liquidLevelHeight)
      Calculate the gas area above the specified liquid level for horizontal separator.
      Parameters:
      liquidLevelHeight - liquid level height in meters
      Returns:
      gas area in m²
    • calcGasVelocityAboveLevel

      public double calcGasVelocityAboveLevel(double liquidLevelHeight)
      Calculate gas velocity above the specified liquid level.
      Parameters:
      liquidLevelHeight - liquid level height in meters (e.g., HLL)
      Returns:
      gas velocity in m/s
    • calcKValue

      public double calcKValue(double liquidLevelHeight)
      Calculate the K-value (Souders-Brown factor) above the specified liquid level. K = v_gas * sqrt(ρ_gas / (ρ_liquid - ρ_gas))

      Per Equinor TR3500 SR-50535: K-value must be less than 0.15 m/s related to HLL.

      Parameters:
      liquidLevelHeight - liquid level height in meters (typically HLL)
      Returns:
      K-value in m/s
    • calcKValueAtHLL

      public double calcKValueAtHLL()
      Calculate the K-value at the design HLL from mechanical design. Uses HLL fraction from SeparatorMechanicalDesign if available.
      Returns:
      K-value in m/s at HLL
    • isKValueWithinLimit

      public boolean isKValueWithinLimit(double limit)
      Check if K-value is within the specified limit.
      Parameters:
      limit - K-value limit in m/s (default 0.15 per TR3500)
      Returns:
      true if K-value is below the limit
    • isKValueWithinLimit

      public boolean isKValueWithinLimit()
      Check if K-value is within the default limit (0.15 m/s per TR3500).
      Returns:
      true if K-value is below the default limit
    • calcDropletCutSize

      public double calcDropletCutSize(double effectiveGasLength, double freeHeightAboveLiquid)
      Calculate the oil droplet cut size in the gas section above liquid level. Based on Stokes law for terminal settling velocity.

      Per Equinor TR3500 SR-50535: Droplet cut size must be less than 150 µm.

      Parameters:
      effectiveGasLength - effective gas separation length in meters
      freeHeightAboveLiquid - free height above liquid level in meters
      Returns:
      droplet cut size in meters (multiply by 1e6 for µm)
    • calcDropletCutSizeAtHLL

      public double calcDropletCutSizeAtHLL()
      Calculate the oil droplet cut size at HLL using mechanical design parameters.
      Returns:
      droplet cut size in meters
    • isDropletCutSizeWithinLimit

      public boolean isDropletCutSizeWithinLimit(double limitMicrons)
      Check if droplet cut size is within the specified limit.
      Parameters:
      limitMicrons - droplet cut size limit in micrometers (default 150 µm per TR3500)
      Returns:
      true if droplet cut size is below the limit
    • isDropletCutSizeWithinLimit

      public boolean isDropletCutSizeWithinLimit()
      Check if droplet cut size is within the default limit (150 µm per TR3500).
      Returns:
      true if droplet cut size is below the default limit
    • calcInletMomentumFlux

      public double calcInletMomentumFlux(double nozzleDiameter)
      Calculate the inlet nozzle momentum flux. M = ρ_mix * v_mix²

      Per Equinor Revamp Limit: Momentum flux should be less than 16000 Pa.

      Parameters:
      nozzleDiameter - inlet nozzle internal diameter in meters
      Returns:
      momentum flux in Pa
    • calcInletMomentumFlux

      public double calcInletMomentumFlux()
      Calculate the inlet momentum flux using mechanical design nozzle size.
      Returns:
      momentum flux in Pa
    • isInletMomentumWithinLimit

      public boolean isInletMomentumWithinLimit(double limitPa)
      Check if inlet momentum flux is within the specified limit.
      Parameters:
      limitPa - momentum flux limit in Pa (default 16000 Pa for revamp)
      Returns:
      true if momentum flux is below the limit
    • isInletMomentumWithinLimit

      public boolean isInletMomentumWithinLimit()
      Check if inlet momentum flux is within the default limit (16000 Pa).
      Returns:
      true if momentum flux is below the default limit
    • calcSegmentArea

      public static double calcSegmentArea(double diameter, double levelHeight)
      Calculate the liquid area (circular segment) at a given level height.
      Parameters:
      diameter - vessel internal diameter in meters
      levelHeight - liquid level height in meters
      Returns:
      segment area in m²
    • calcOilRetentionTime

      public double calcOilRetentionTime()
      Calculate oil retention time between NIL and NLL. Per API 12J and TR3500 SR-83381: Should be 3-5 minutes for light oils.
      Returns:
      oil retention time in minutes
    • calcWaterRetentionTime

      public double calcWaterRetentionTime()
      Calculate water retention time below NIL. Per API 12J and TR3500 SR-83381: Should be 3-5 minutes for light oils.
      Returns:
      water retention time in minutes
    • isOilRetentionTimeAboveMinimum

      public boolean isOilRetentionTimeAboveMinimum(double minMinutes)
      Check if oil retention time meets the minimum requirement.
      Parameters:
      minMinutes - minimum retention time in minutes (default 3 minutes per API 12J)
      Returns:
      true if retention time is above the minimum
    • isOilRetentionTimeAboveMinimum

      public boolean isOilRetentionTimeAboveMinimum()
      Check if oil retention time meets the default minimum (3 minutes).
      Returns:
      true if retention time is above the default minimum
    • isWaterRetentionTimeAboveMinimum

      public boolean isWaterRetentionTimeAboveMinimum(double minMinutes)
      Check if water retention time meets the minimum requirement.
      Parameters:
      minMinutes - minimum retention time in minutes (default 3 minutes per API 12J)
      Returns:
      true if retention time is above the minimum
    • isWaterRetentionTimeAboveMinimum

      public boolean isWaterRetentionTimeAboveMinimum()
      Check if water retention time meets the default minimum (3 minutes).
      Returns:
      true if retention time is above the default minimum
    • isWithinAllLimits

      public boolean isWithinAllLimits()
      Check if all separator performance parameters are within limits. Uses default limits from Equinor TR3500 and API 12J.
      Returns:
      true if all parameters are within limits
    • getPerformanceSummary

      public String getPerformanceSummary()
      Get a summary of all performance parameters with limit checks.
      Returns:
      performance summary as formatted string
    • readObject

      private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException
      Custom deserialization to reinitialize transient fields.

      After deserialization, the capacity constraints need to be reinitialized because the valueSupplier lambdas are transient and cannot be serialized. This method clears any deserialized constraints and creates fresh ones with proper value suppliers bound to this separator instance.

      Parameters:
      in - the ObjectInputStream to read from
      Throws:
      IOException - if an I/O error occurs
      ClassNotFoundException - if the class of a serialized object cannot be found
    • builder

      public static Separator.Builder builder(String name)
      Creates a new Builder for constructing a Separator with a fluent API.

      Example usage:

      Separator sep = Separator.builder("V-100").inletStream(feed).orientation("horizontal")
          .length(5.0).diameter(2.0).liquidLevel(0.5).build();
      
      Parameters:
      name - the name of the separator
      Returns:
      a new Builder instance