Class DistillationColumn

All Implemented Interfaces:
Serializable, Runnable, DistillationInterface, ProcessEquipmentInterface, SimulationInterface, NamedInterface

public class DistillationColumn extends ProcessEquipmentBaseClass implements DistillationInterface
Models a tray based distillation column with optional condenser and reboiler.

The column is solved using a sequential substitution approach. The init() method sets initial tray temperatures by running the feed tray and linearly distributing temperatures towards the top and bottom. During run(UUID) the trays are iteratively solved in upward and downward sweeps until the summed temperature change between iterations is below the configured temperatureTolerance or the iteration limit is reached.

Author:
esol
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.
    • doInitializion

      private boolean doInitializion
    • hasReboiler

      boolean hasReboiler
    • hasCondenser

      boolean hasCondenser
    • trays

      protected ArrayList<SimpleTray> trays
    • TRAY_ITERATION_FACTOR

      private static final double TRAY_ITERATION_FACTOR
      Scaling factor used to derive a tray-proportional iteration budget.
      See Also:
    • MASS_POLISH_TARGET

      private static final double MASS_POLISH_TARGET
      Target relative mass imbalance for the post-processing polish stage.
      See Also:
    • ENERGY_POLISH_TARGET

      private static final double ENERGY_POLISH_TARGET
      Target relative energy imbalance for the post-processing polish stage.
      See Also:
    • TEMPERATURE_POLISH_TARGET

      private static final double TEMPERATURE_POLISH_TARGET
      Target average temperature drift for the polishing stage in Kelvin.
      See Also:
    • POLISH_ITERATION_MARGIN

      private static final int POLISH_ITERATION_MARGIN
      Extra iterations granted when a polish stage is triggered.
      See Also:
    • ITERATION_OVERFLOW_MULTIPLIER

      private static final int ITERATION_OVERFLOW_MULTIPLIER
      Multiplier governing how much the solver can extend beyond the nominal iteration budget.
      See Also:
    • condenserCoolingDuty

      double condenserCoolingDuty
    • reboilerTemperature

      private double reboilerTemperature
    • condenserTemperature

      private double condenserTemperature
    • topTrayPressure

      double topTrayPressure
    • temperatureTolerance

      private double temperatureTolerance
      Temperature convergence tolerance.
    • massBalanceTolerance

      private double massBalanceTolerance
      Mass balance convergence tolerance.
    • enthalpyBalanceTolerance

      private double enthalpyBalanceTolerance
      Enthalpy balance convergence tolerance.
    • solverType

      private DistillationColumn.SolverType solverType
      Selected solver algorithm. Defaults to direct substitution.
    • relaxationFactor

      private double relaxationFactor
      Relaxation factor used when DistillationColumn.SolverType.DAMPED_SUBSTITUTION is active.
    • minSequentialRelaxation

      private double minSequentialRelaxation
      Minimum relaxation factor used when adaptive damping scales down the sequential step.
    • minInsideOutRelaxation

      private double minInsideOutRelaxation
      Minimum relaxation factor allowed for the inside-out tear streams.
    • maxAdaptiveRelaxation

      private double maxAdaptiveRelaxation
      Maximum relaxation factor allowed by the adaptive controller.
    • relaxationIncreaseFactor

      private double relaxationIncreaseFactor
      Factor used to expand the relaxation factor when residuals shrink.
    • relaxationDecreaseFactor

      private double relaxationDecreaseFactor
      Factor used to shrink the relaxation factor when residuals grow.
    • minTemperatureRelaxation

      private double minTemperatureRelaxation
      Minimum relaxation applied when blending tray temperatures.
    • maxEnergyRelaxationWeight

      private double maxEnergyRelaxationWeight
      Cap applied to energy residual when adjusting relaxation.
    • enforceEnergyBalanceTolerance

      private boolean enforceEnergyBalanceTolerance
      Control whether energy residual must satisfy tolerance before convergence.
    • doMultiPhaseCheck

      private boolean doMultiPhaseCheck
    • feedmixer

      Mixer feedmixer
    • bottomTrayPressure

      double bottomTrayPressure
    • numberOfTrays

      int numberOfTrays
    • maxNumberOfIterations

      int maxNumberOfIterations
    • stream_3

      StreamInterface stream_3
    • gasOutStream

      StreamInterface gasOutStream
    • liquidOutStream

      StreamInterface liquidOutStream
    • stream_3isset

      boolean stream_3isset
    • internalDiameter

      private double internalDiameter
    • distoperations

      ProcessSystem distoperations
    • heater

      Heater heater
    • separator2

      Separator separator2
    • err

      private double err
      Error measure used in solver to check convergence in run().
    • lastIterationCount

      private int lastIterationCount
      Last number of iterations executed by the active solver.
    • lastTemperatureResidual

      private double lastTemperatureResidual
      Last recorded average temperature residual in Kelvin.
    • lastMassResidual

      private double lastMassResidual
      Last recorded relative mass balance residual.
    • lastEnergyResidual

      private double lastEnergyResidual
      Last recorded relative enthalpy residual.
    • lastSolveTimeSeconds

      private double lastSolveTimeSeconds
      Duration of the latest solve step in seconds.
    • feedStreams

      private Map<Integer, List<StreamInterface>> feedStreams
      Instead of Map<Integer,StreamInterface>, we store a list of feed streams per tray number. This allows multiple feeds to the same tray.
    • unassignedFeedStreams

      private List<StreamInterface> unassignedFeedStreams
  • Constructor Details

    • DistillationColumn

      public DistillationColumn(String name, int numberOfTraysLocal, boolean hasReboiler, boolean hasCondenser)

      Constructor for DistillationColumn.

      Parameters:
      name - Name of distillation column
      numberOfTraysLocal - Number of SimpleTrays to add (excluding reboiler/condenser)
      hasReboiler - Set true to add reboiler
      hasCondenser - Set true to add Condenser
  • Method Details

    • setMultiPhaseCheck

      public void setMultiPhaseCheck(boolean doMultiPhaseCheck)

      Setter for the field doMultiPhaseCheck.

      Parameters:
      doMultiPhaseCheck - a boolean
    • isDoMultiPhaseCheck

      public boolean isDoMultiPhaseCheck()

      Getter for the field doMultiPhaseCheck.

      Returns:
      a boolean
    • addFeedStream

      public void addFeedStream(StreamInterface inputStream, int feedTrayNumber)

      Add a feed stream to the specified tray. (Now allows multiple streams on the same trayNumber, using a list.)

      Parameters:
      inputStream - the feed stream
      feedTrayNumber - the tray number (0-based in the code) to which this feed goes
    • addFeedStream

      public void addFeedStream(StreamInterface inputStream)
      Add a feed stream to the column without specifying the tray. The optimal feed tray will be determined automatically based on temperature match.
      Parameters:
      inputStream - the feed stream
    • getFeedStreams

      public List<StreamInterface> getFeedStreams(int feedTrayNumber)
      Return the feed streams connected to a given tray.
      Parameters:
      feedTrayNumber - tray index where feeds are connected
      Returns:
      immutable view of feed streams connected to the tray
    • init

      public void init()
      Prepare the column for calculation by estimating tray temperatures and linking streams between trays.

      The feed tray is solved first to obtain a temperature estimate. This temperature is then used to linearly guess temperatures upwards to the condenser and downwards to the reboiler. Gas and liquid outlet streams are connected to neighbouring trays so that a subsequent call to run(UUID) can iterate to convergence.

    • run

      public void run(UUID id)

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

      Solve the column until tray temperatures converge. The method applies sequential substitution with an adaptive relaxation controller. Pressures are set linearly between bottom and top. Each iteration performs an upward sweep where liquid flows downward followed by a downward sweep where vapour flows upward. Tray temperatures and inter-tray stream flow rates are relaxed if the combined temperature, mass and energy residuals grow, providing basic line-search behaviour.

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

      private void assignUnassignedFeeds()
    • findOptimalNumberOfTrays

      public int findOptimalNumberOfTrays(double productSpec, String componentName, boolean isTopProduct, int maxTrays)
      Find the optimal number of trays to meet a product specification.
      Parameters:
      productSpec - the target purity (mole fraction) of the key component
      componentName - the name of the key component
      isTopProduct - true if the spec is for the top product (distillate), false for bottom
      maxTrays - the maximum number of trays to try
      Returns:
      the optimal number of trays, or -1 if the spec could not be met
    • solveSequential

      private void solveSequential(UUID id, double initialRelaxation)
      Execute the sequential substitution solver with an adaptive relaxation controller.
      Parameters:
      id - calculation identifier
      initialRelaxation - relaxation factor applied to the first iteration
    • computeIterationLimit

      private int computeIterationLimit()
      Determine the iteration limit based on configuration and column size.
      Returns:
      maximum number of solver iterations allowed
    • shouldEvaluateBalances

      private boolean shouldEvaluateBalances(int iteration, int iterationLimit, boolean polishing, double tempResidual, double baseTempTolerance, int balanceCheckStride)
      Decide whether mass and energy balance residuals should be recomputed this iteration.
      Parameters:
      iteration - current iteration index (1-based)
      iterationLimit - current iteration ceiling
      polishing - whether the solver is in the polish stage
      tempResidual - average temperature residual this iteration
      baseTempTolerance - nominal temperature tolerance
      balanceCheckStride - cadence for periodic balance checks
      Returns:
      true if balances should be evaluated
    • prepareColumnForSolve

      private int prepareColumnForSolve()
      Prepare the column for a solving sequence by updating pressures and cloning feed systems.
      Returns:
      index of the lowest feed tray in the column
    • solveInsideOut

      private void solveInsideOut(UUID id)
      Solve the column using an inside-out strategy with adaptive stream relaxation.
      Parameters:
      id - calculation identifier
    • runBroyden

      public void runBroyden(UUID id)
      Solve the column using a simple Broyden mixing of tray temperatures.
      Parameters:
      id - calculation identifier
    • runDamped

      private void runDamped(UUID id)
      Solve the column using the adaptive sequential substitution scheme with a damped starting step.
      Parameters:
      id - calculation identifier
    • displayResult

      public void displayResult()

      displayResult.

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

      public SimpleTray getTray(int trayNumber)

      getTray.

      Parameters:
      trayNumber - a int
      Returns:
      a SimpleTray object
    • getTrays

      public ArrayList<SimpleTray> getTrays()
    • setNumberOfTrays

      public void setNumberOfTrays(int number)

      setNumberOfTrays.

      Specified by:
      setNumberOfTrays in interface DistillationInterface
      Parameters:
      number - a int
    • setSolverType

      public void setSolverType(DistillationColumn.SolverType solverType)
      Select the algorithm used when solving the column.
      Parameters:
      solverType - choice of solver
    • setRelaxationFactor

      public void setRelaxationFactor(double relaxationFactor)
      Set relaxation factor for the damped solver.
      Parameters:
      relaxationFactor - value between 0 and 1
    • setTopCondenserDuty

      public void setTopCondenserDuty(double duty)

      setTopCondenserDuty.

      Parameters:
      duty - a double
    • setTopPressure

      public void setTopPressure(double topPressure)

      setTopPressure.

      Parameters:
      topPressure - a double
    • setBottomPressure

      public void setBottomPressure(double bottomPressure)

      setBottomPressure.

      Parameters:
      bottomPressure - a double
    • solved

      public boolean solved()

      Returns whether or not the module has been solved.

      Specified by:
      solved in interface SimulationInterface
      Overrides:
      solved in class ProcessEquipmentBaseClass
      Returns:
      a boolean
    • setError

      void setError(double err)
    • getLastIterationCount

      public int getLastIterationCount()
      Retrieve the iteration count of the most recent solve.
      Returns:
      iteration count
    • getLastTemperatureResidual

      public double getLastTemperatureResidual()
      Retrieve the latest average temperature residual in Kelvin.
      Returns:
      average temperature residual
    • getLastMassResidual

      public double getLastMassResidual()
      Retrieve the latest relative mass residual.
      Returns:
      relative mass balance residual
    • getLastEnergyResidual

      public double getLastEnergyResidual()
      Retrieve the latest relative enthalpy residual.
      Returns:
      relative enthalpy residual
    • getLastSolveTimeSeconds

      public double getLastSolveTimeSeconds()
      Retrieve the duration of the most recent solve in seconds.
      Returns:
      solve time in seconds
    • getMassBalanceTolerance

      public double getMassBalanceTolerance()
      Access the configured relative mass balance tolerance.
      Returns:
      mass balance tolerance
    • setEnforceEnergyBalanceTolerance

      public void setEnforceEnergyBalanceTolerance(boolean enforce)
      Control whether the solver enforces the energy balance tolerance when determining convergence.
      Parameters:
      enforce - true to require the energy residual to satisfy the configured tolerance
    • isEnforceEnergyBalanceTolerance

      public boolean isEnforceEnergyBalanceTolerance()
      Check if the solver currently enforces the energy balance tolerance during convergence checks.
      Returns:
      true if the energy residual must satisfy its tolerance before convergence
    • getEnthalpyBalanceTolerance

      public double getEnthalpyBalanceTolerance()
      Access the configured relative enthalpy balance tolerance.
      Returns:
      enthalpy balance tolerance
    • getTemperatureTolerance

      public double getTemperatureTolerance()
      Access the configured average temperature tolerance.
      Returns:
      temperature tolerance in Kelvin
    • setMaxNumberOfIterations

      public void setMaxNumberOfIterations(int maxIter)

      Setter for the field maxNumberOfIterations.

      Parameters:
      maxIter - a int
    • setInternalDiameter

      public void setInternalDiameter(double internalDiameter)

      Setter for the field internalDiameter.

      Parameters:
      internalDiameter - a double
    • getInternalDiameter

      public double getInternalDiameter()

      Getter for the field internalDiameter.

      Returns:
      a double
    • getFsFactor

      public double getFsFactor()
      Calculates the Fs factor for the distillation column. The Fs factor is a measure of the gas flow rate through the column relative to the cross-sectional area and the density of the gas.
      Returns:
      the Fs factor as a double value
    • getGasOutStream

      public StreamInterface getGasOutStream()

      Getter for the field gasOutStream.

      Returns:
      a StreamInterface object
    • getLiquidOutStream

      public StreamInterface getLiquidOutStream()

      Getter for the field liquidOutStream.

      Returns:
      a StreamInterface object
    • 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
    • getReboiler

      public Reboiler getReboiler()

      getReboiler.

      Returns:
      a Reboiler object
    • getCondenser

      public Condenser getCondenser()

      getCondenser.

      Returns:
      a Condenser object
    • getReboilerTemperature

      public double getReboilerTemperature()

      Getter for the field reboilerTemperature.

      Returns:
      a double
    • setReboilerTemperature

      public void setReboilerTemperature(double reboilerTemperature)

      Setter for the field reboilerTemperature.

      Parameters:
      reboilerTemperature - a double
    • getCondenserTemperature

      public double getCondenserTemperature()

      Getter for the field condenserTemperature.

      Returns:
      a double
    • setCondenserTemperature

      public void setCondenserTemperature(double condenserTemperature)

      Setter for the field condenserTemperature.

      Parameters:
      condenserTemperature - a double
    • isDoInitializion

      public boolean isDoInitializion()

      isDoInitializion.

      Returns:
      a boolean
    • setDoInitializion

      public void setDoInitializion(boolean doInitializion)

      Setter for the field doInitializion.

      Parameters:
      doInitializion - a boolean
    • setTemperatureTolerance

      public void setTemperatureTolerance(double tol)
      Set temperature convergence tolerance.
      Parameters:
      tol - the tolerance
    • setMassBalanceTolerance

      public void setMassBalanceTolerance(double tol)
      Set mass balance convergence tolerance.
      Parameters:
      tol - the tolerance
    • setEnthalpyBalanceTolerance

      public void setEnthalpyBalanceTolerance(double tol)
      Set enthalpy balance convergence tolerance.
      Parameters:
      tol - the tolerance
    • massBalanceCheck

      public boolean massBalanceCheck()
      Check mass balance for all components.
      Returns:
      true if mass balance is within 1e-6
    • componentMassBalanceCheck

      public boolean componentMassBalanceCheck(String componentName)
      Check mass balance for a specific component.
      Parameters:
      componentName - the component name
      Returns:
      true if mass balance is within 1e-6
    • getMassBalanceError

      public double getMassBalanceError()
      Calculate the relative mass balance error across the column.
      Returns:
      maximum of tray-wise and overall relative mass imbalance
    • getEnergyBalanceError

      public double getEnergyBalanceError()
      Calculates the relative enthalpy imbalance across all trays.
      Returns:
      maximum of tray-wise and overall relative enthalpy imbalance
    • applyRelaxation

      private StreamInterface applyRelaxation(StreamInterface previous, StreamInterface current, double relaxation)
      Blend the current stream update with the previous iterate using the provided relaxation factor.
      Parameters:
      previous - stream from the previous iteration (may be null)
      current - current iteration stream
      relaxation - relaxation factor applied to the update
      Returns:
      relaxed stream instance to be used in the next tear
    • finalizeSolve

      private void finalizeSolve(UUID id, int iterations, double temperatureResidual, double massResidual, double energyResidual, long startTime)
      Finalise a successful solver run by updating iteration metrics and product streams.
      Parameters:
      id - calculation identifier
      iterations - number of iterations performed
      temperatureResidual - final average temperature residual
      massResidual - final relative mass residual
      energyResidual - final relative energy residual
      startTime - nano time when the solve started
    • resetLastSolveMetrics

      private void resetLastSolveMetrics()
      Reset cached solve metrics when no calculation is performed.
    • energyBalanceCheck

      public void energyBalanceCheck()
      Prints a simple energy balance for each tray to the console. The method calculates the total enthalpy of all inlet streams and compares it with the outlet enthalpy in order to highlight any discrepancies in the column setup.
    • main

      public static void main(String[] args)
      The main method demonstrates the creation and operation of a distillation column using the NeqSim library. It performs the following steps:
      1. Creates a test thermodynamic system with methane, ethane, and propane components.
      2. Performs a TP flash calculation on the test system.
      3. Creates two separate feed streams from the test system.
      4. Constructs a distillation column with 5 trays, a reboiler, and a condenser.
      5. Adds the two feed streams to the distillation column at tray 3.
      6. Builds and runs the process system.
      7. Displays the results of the distillation column, including the gas and liquid output streams.
      Parameters:
      args - command line arguments (not used)
    • 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
    • getNumerOfTrays

      public int getNumerOfTrays()

      getNumerOfTrays.

      Returns:
      a int
    • 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 distillation column setup before execution. Checks that:

      • Equipment has a valid name
      • At least one feed stream is connected
      • Number of trays is positive
      • Solver parameters are valid
      Specified by:
      validateSetup in interface ProcessEquipmentInterface
      Returns:
      validation result with errors and warnings
    • builder

      public static DistillationColumn.Builder builder(String name)
      Creates a new Builder for constructing DistillationColumn instances.

      The builder pattern provides a fluent API for configuring complex distillation columns with many optional parameters. This is especially useful when configuring columns with multiple feed streams, custom tolerances, or specific solver settings.

      Example usage:

      DistillationColumn column = DistillationColumn.builder("Deethanizer").numberOfTrays(15)
          .withCondenser().withReboiler().topPressure(25.0, "bara").bottomPressure(26.0, "bara")
          .solverType(SolverType.INSIDE_OUT).temperatureTolerance(0.001).addFeedStream(feedStream, 8)
          .build();
      
      Parameters:
      name - the name of the distillation column
      Returns:
      a new Builder instance