Class DistillationColumn

All Implemented Interfaces:
Serializable, Runnable, DistillationInterface, ProcessEquipmentInterface, ProcessElementInterface, SimulationInterface, NamedInterface
Direct Known Subclasses:
PackedColumn, ScrubColumn

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:
    • DEFAULT_TEMPERATURE_TOLERANCE

      private static final double DEFAULT_TEMPERATURE_TOLERANCE
      Recommended base temperature tolerance for adaptive defaults.
      See Also:
    • DEFAULT_MASS_BALANCE_TOLERANCE

      private static final double DEFAULT_MASS_BALANCE_TOLERANCE
      Recommended base mass balance tolerance for adaptive defaults.
      See Also:
    • DEFAULT_ENTHALPY_BALANCE_TOLERANCE

      private static final double DEFAULT_ENTHALPY_BALANCE_TOLERANCE
      Recommended base enthalpy balance tolerance for adaptive defaults.
      See Also:
    • DEFAULT_MESH_RESIDUAL_TOLERANCE

      private static final double DEFAULT_MESH_RESIDUAL_TOLERANCE
      Default scaled MESH residual tolerance when residual gating is enabled.
      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.
    • meshResidualTolerance

      private double meshResidualTolerance
      Scaled MESH residual convergence tolerance.
    • temperatureToleranceCustomized

      private boolean temperatureToleranceCustomized
      Track whether temperature tolerance has been manually overridden.
    • massBalanceToleranceCustomized

      private boolean massBalanceToleranceCustomized
      Track whether mass balance tolerance has been manually overridden.
    • enthalpyBalanceToleranceCustomized

      private boolean enthalpyBalanceToleranceCustomized
      Track whether enthalpy balance tolerance has been manually overridden.
    • 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.
    • enforceMeshResidualTolerance

      private boolean enforceMeshResidualTolerance
      Control whether the MESH residual vector must satisfy tolerance before convergence.
    • doMultiPhaseCheck

      private boolean doMultiPhaseCheck
    • reactive

      private boolean reactive
      When true, trays in the reactive section use ReactiveTray (simultaneous chemical + phase equilibrium via the Modified RAND method) instead of standard VLE SimpleTray. Set this before the first SimulationInterface.run() call.
    • reactiveStartTray

      private int reactiveStartTray
      First tray index (0-based, inclusive) of the reactive section. A value of -1 means all middle trays (i.e. excluding reboiler/condenser) are reactive.
    • reactiveEndTray

      private int reactiveEndTray
      Last tray index (0-based, inclusive) of the reactive section. A value of -1 means all middle trays are reactive.
    • hasBeenSolvedBefore

      private transient boolean hasBeenSolvedBefore
      Flag tracking whether the column has been solved at least once. Used to seed the sequential solver with the previous tray state on re-runs, preventing divergence from an unrelaxed start.
    • lastTotalFeedFlow

      private transient double lastTotalFeedFlow
      Total feed flow (kg/hr) recorded at the end of the previous solve. Used to detect whether the column needs to re-solve or can reuse the previous result.
    • mechanicalDesign

      private DistillationColumnMechanicalDesign mechanicalDesign
      Mechanical design for the distillation column.
    • topSpecification

      private ColumnSpecification topSpecification
      Column specification for the top (condenser) end.
    • bottomSpecification

      private ColumnSpecification bottomSpecification
      Column specification for the bottom (reboiler) end.
    • 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.
    • lastTopSpecificationResidual

      private double lastTopSpecificationResidual
      Last reported top specification residual.
    • lastBottomSpecificationResidual

      private double lastBottomSpecificationResidual
      Last reported bottom specification residual.
    • lastMeshResidual

      private transient ColumnMeshResidual lastMeshResidual
      Latest MESH residual diagnostics.
    • 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
    • murphreeEfficiency

      private double murphreeEfficiency
      Murphree tray efficiency applied to each equilibrium stage (0..1). Default 1.0 = ideal.
    • convergenceHistory

      private transient List<double[]> convergenceHistory
      Per-iteration convergence history: [iteration][0=tempErr, 1=massErr, 2=energyErr].
    • innerLoopSteps

      private int innerLoopSteps
      Number of simplified inner-loop iterations between rigorous flash updates in the IO solver. Higher values reduce flash count but may reduce accuracy. Default 3.
    • dynamicColumnEnabled

      private boolean dynamicColumnEnabled
      Whether the dynamic tray model is enabled for transient simulation.
    • trayLiquidHoldup

      private transient double[] trayLiquidHoldup
      Liquid holdup per tray in moles. Indexed by tray number.
    • trayWeirHeight

      private double trayWeirHeight
      Weir height on each tray in metres.
    • trayWeirLength

      private double trayWeirLength
      Weir length (crest length) on each tray in metres.
    • trayEnthalpy

      private transient double[] trayEnthalpy
      Per-tray enthalpy in J. Indexed by tray number. Null until initialized.
    • trayDryPressureDrop

      private double trayDryPressureDrop
      Dry tray pressure drop in Pa per tray — for vapor hydraulic model.
    • dynamicEnergyEnabled

      private boolean dynamicEnergyEnabled
      Whether per-tray energy balance is active (uses PH flash instead of TP).
    • MAX_CONVERGENCE_HISTORY

      private static final int MAX_CONVERGENCE_HISTORY
      Maximum number of entries stored in the convergence history list.
      See Also:
  • 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
    • applyDirectSpecifications

      private void applyDirectSpecifications()
      Apply specifications that map directly to condenser or reboiler controls.
    • applyDirectSpecification

      private void applyDirectSpecification(ColumnSpecification spec)
      Apply a specification that does not require an outer iteration.
      Parameters:
      spec - the specification to apply
    • hasAdjustableSpecifications

      private boolean hasAdjustableSpecifications()
      Check whether any configured column specification requires iterative adjustment.
      Returns:
      true when an active product/recovery/flow specification is present
    • specificationsSatisfied

      private boolean specificationsSatisfied()
      Check whether all active column specifications are within their configured tolerance.
      Returns:
      true if all specifications are satisfied
    • updateSpecificationResiduals

      private void updateSpecificationResiduals()
      Update the stored residuals for the currently configured column specifications.
    • updateSpecificationResidualDiagnostics

      void updateSpecificationResidualDiagnostics()
      Update the stored specification residuals for package-level diagnostics.
    • updateMeshResiduals

      private void updateMeshResiduals()
      Update the stored MESH residual diagnostics for the current column state.
    • evaluateSpecErrorSafely

      private double evaluateSpecErrorSafely(ColumnSpecification spec)
      Evaluate a specification residual for diagnostics without interrupting a solve.
      Parameters:
      spec - the specification to evaluate
      Returns:
      current residual, zero for no specification, or Double.NaN if unavailable
    • specificationSatisfied

      private boolean specificationSatisfied(ColumnSpecification spec)
      Check whether a single column specification is satisfied.
      Parameters:
      spec - the specification to evaluate
      Returns:
      true if no residual check is needed or the residual is within tolerance
    • solveSelectedSolver

      private ColumnSolveResult solveSelectedSolver(UUID id)
      Solve the column using the currently selected inner solver.
      Parameters:
      id - calculation identifier
    • solveWithSpecifications

      private void solveWithSpecifications(UUID id)
      Solve the column with an outer loop that adjusts condenser/reboiler temperatures to satisfy product specifications. Uses a secant method for each specification that requires adjustment.
      Parameters:
      id - calculation identifier
    • secantStep

      private double secantStep(double t0, double t1, double f0, double f1, double feedTemp)
      Compute the secant method step for temperature adjustment, with safeguards.
      Parameters:
      t0 - previous temperature
      t1 - current temperature
      f0 - spec error at t0
      f1 - spec error at t1
      feedTemp - reference feed temperature for bounding
      Returns:
      the next temperature guess
    • needsAdjustment

      private boolean needsAdjustment(ColumnSpecification spec)
      Checks whether a specification requires iterative temperature adjustment.
      Parameters:
      spec - the column specification to check
      Returns:
      true if the specification is non-null and requires adjustment
    • solveInner

      private void solveInner(UUID id)
      Run the inner column solver (one full solve with the currently selected solver type) without resetting convergence history. Used by solveWithSpecifications(UUID) in the outer adjustment loop.
      Parameters:
      id - calculation identifier
    • solveDirectSubstitution

      void solveDirectSubstitution(UUID id)
      Solve using direct substitution.
      Parameters:
      id - calculation identifier
    • solveDampedSubstitution

      void solveDampedSubstitution(UUID id)
      Solve using damped substitution and the configured relaxation factor.
      Parameters:
      id - calculation identifier
    • solveMeshResidual

      void solveMeshResidual(UUID id)
      Solve using inside-out initialization and temperature-Newton polishing while reporting MESH residual diagnostics.
      Parameters:
      id - calculation identifier
    • evaluateSpecError

      private double evaluateSpecError(ColumnSpecification spec)
      Evaluate how far the current column solution is from satisfying a specification.
      Parameters:
      spec - the column specification to evaluate
      Returns:
      the error (current value minus target value); zero when satisfied
    • getTotalFeedComponentFlow

      private double getTotalFeedComponentFlow(String componentName)
      Calculate the total feed flow of a named component across all feed streams.
      Parameters:
      componentName - the component name
      Returns:
      total molar flow in mol/hr
    • estimateFeedTemperature

      private double estimateFeedTemperature()
      Estimate a representative feed temperature from the assigned feed streams.
      Returns:
      average feed temperature in Kelvin
    • 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
    • getEffectiveTemperatureTolerance

      private double getEffectiveTemperatureTolerance()
      Derive the effective temperature tolerance based on column complexity unless overridden.
      Returns:
      adaptive temperature tolerance in Kelvin
    • getEffectiveMassBalanceTolerance

      private double getEffectiveMassBalanceTolerance()
      Derive the effective mass balance tolerance based on column complexity unless overridden.
      Returns:
      adaptive mass balance tolerance (relative)
    • getEffectiveEnthalpyBalanceTolerance

      private double getEffectiveEnthalpyBalanceTolerance()
      Derive the effective enthalpy balance tolerance based on column complexity unless overridden.
      Returns:
      adaptive energy balance tolerance (relative)
    • computeToleranceComplexityMultiplier

      private double computeToleranceComplexityMultiplier()
      Estimate a scaling factor that reflects the degree of distillation complexity.

      The factor increases with the number of theoretical stages and independent feed streams and is bounded to avoid overly loose convergence criteria.

      Returns:
      scaling multiplier for recommended tolerances
    • getEffectiveStageCount

      private int getEffectiveStageCount()
      Count the number of simple trays, excluding optional reboiler and condenser sections.
      Returns:
      effective number of equilibrium stages
    • getTotalFeedCount

      private int getTotalFeedCount()
      Count connected feed streams across all trays.
      Returns:
      total number of feeds currently attached to the column
    • 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

      void solveInsideOut(UUID id)
      Solve the column using an improved inside-out strategy inspired by Boston and Sullivan (1974).

      Key improvements over basic sequential substitution:

      • K-value caching: previous iteration K-values are stored to track composition convergence and detect stagnation early.
      • Composition-based convergence: monitors maximum relative K-value change alongside temperature and balance residuals.
      • Stripping factor correction: applies a bulk flow correction between outer iterations based on the ratio of computed-to-assumed vapor/liquid split on each tray.
      • Accelerated relaxation ramp: increases relaxation faster (1.3× vs 1.2×) when residuals decrease, enabling the IO method to reach full step sooner.
      • Lazy balance evaluation: mass/energy balances are only recomputed when temperatures are close to tolerance, reducing expensive per-tray flow rate queries.
      Parameters:
      id - calculation identifier
    • computeKvalueResidual

      private double computeKvalueResidual(double[][] previousKvalues)
      Compute the maximum relative K-value change compared to the previous iteration.

      K-values are computed as the ratio of vapor to liquid mole fractions for each component on each tray. This provides a composition-based convergence metric that complements the temperature-based metric, similar to what commercial inside-out implementations track.

      Parameters:
      previousKvalues - K-values from the previous iteration (null if first iteration)
      Returns:
      maximum relative K-value change; Double.POSITIVE_INFINITY if no previous data
    • cacheCurrentKvalues

      private double[][] cacheCurrentKvalues()
      Cache K-values (y/x) for all components on all trays for use in the next iteration comparison.
      Returns:
      2D array [tray][component] of K-values
    • innerLoopIteration

      private double innerLoopIteration(DistillationColumn.SimplifiedKvalueModel model, double relaxation)
      Perform a simplified inner-loop iteration using the K-value model instead of rigorous flash.

      This method updates tray compositions using the simplified K-value correlation and adjusts temperatures via a bubble-point calculation (sum of K*x = 1 condition). No PH-flash is called, making each inner iteration much cheaper than a rigorous outer iteration.

      Parameters:
      model - the fitted simplified K-value model
      relaxation - current relaxation factor
      Returns:
      average absolute temperature change across all trays
    • runBroyden

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

      void solveWegstein(UUID id)
      Solve the column using Wegstein acceleration of successive substitution.

      Wegstein's method uses two consecutive fixed-point iterates to extrapolate a better estimate. For temperatures on each tray the acceleration factor q is computed from the slope of the fixed-point map: q = s / (s - 1) where s = (x_{k} - x_{k-1}) / (g(x_{k}) - g(x_{k-1})). The factor is bounded to [-5, 0] to prevent divergence.

      Parameters:
      id - calculation identifier
    • solveSumRates

      void solveSumRates(UUID id)
      Solve the column using a sum-rates tearing method.

      The sum-rates method adjusts tray liquid flow rates based on the ratio of computed to assumed total flow leaving each tray. This is effective for absorber and stripper columns where the temperature profile is relatively flat. The method alternates between: (1) bubble-point temperature calculations on each tray, and (2) flow rate corrections using the sum-rates formula of Burningham and Otto (1967).

      Parameters:
      id - calculation identifier
    • solveNewton

      void solveNewton(UUID id)
      Solve the column using a Newton-Raphson simultaneous temperature correction method.

      This is inspired by the Naphtali-Sandholm (1971) approach of solving MESH equations simultaneously, adapted to NeqSim's tray-by-tray flash infrastructure. The method treats the N tray temperatures as the independent variables. A residual vector is formed by running full tray sweeps and measuring the temperature discrepancy each tray exhibits after equilibrium. The Jacobian is computed by finite-difference perturbation of each tray temperature.

      Key features:

      • Simultaneous correction: all tray temperatures are updated together using a dense N×N Jacobian solved by Gaussian elimination with partial pivoting.
      • Line search: the full Newton step is scaled back if it increases residuals.
      • Warm-up: a few direct-substitution iterations are performed first to get close to the solution basin where Newton convergence is quadratic.
      Parameters:
      id - calculation identifier
    • performFullTraySweep

      private void performFullTraySweep(UUID id, int firstFeedTrayNumber, StreamInterface[] previousGasStreams, StreamInterface[] previousLiquidStreams, double relaxation)
      Perform a full upward+downward tray sweep, running PH-flash on each tray.
      Parameters:
      id - calculation identifier
      firstFeedTrayNumber - index of the lowest feed tray
      previousGasStreams - cached gas streams from previous iteration (updated in-place)
      previousLiquidStreams - cached liquid streams from previous iteration (updated in-place)
      relaxation - relaxation factor for stream blending
    • computeTemperatureResidual

      private double computeTemperatureResidual()
      Compute the average absolute temperature residual across all trays. The residual is the difference between the tray's stored temperature and its thermo system temperature after a flash.
      Returns:
      average absolute temperature change per tray (K)
    • solveLinearSystem

      private double[] solveLinearSystem(double[][] matrixA, double[] vectorB)
      Solve a dense linear system Ax = b using Gaussian elimination with partial pivoting.
      Parameters:
      matrixA - coefficient matrix (will be modified in-place)
      vectorB - right-hand side vector (will be modified in-place)
      Returns:
      solution vector x, or null if the matrix is singular
    • 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
    • setNumberOfTrays

      public void setNumberOfTrays(int number)

      setNumberOfTrays.

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

      private SimpleTray createMiddleTray(String name, int middleTrayIndex)
      Create a middle tray (between reboiler and condenser). Sets the reactive flash flag when the column is in reactive mode and the tray index falls inside the reactive section.
      Parameters:
      name - the tray name
      middleTrayIndex - 0-based index among the middle trays (excluding reboiler/condenser)
      Returns:
      a new SimpleTray with reactive flash configured
    • isInReactiveSection

      private boolean isInReactiveSection(int middleTrayIndex)
      Check whether a middle-tray index falls inside the reactive section.
      Parameters:
      middleTrayIndex - 0-based index among middle trays
      Returns:
      true when the tray should use reactive flash
    • setReactive

      public void setReactive(boolean reactive)
      Enable or disable reactive distillation for all middle trays. When enabled, middle trays use ReactiveTray (simultaneous chemical + phase equilibrium via the Modified RAND method). Can be called after construction; existing trays will be replaced.
      Parameters:
      reactive - true to enable reactive distillation
    • setReactive

      public void setReactive(boolean reactive, int startTray, int endTray)
      Enable reactive distillation on a specific section of middle trays. Tray indices are 0-based among the middle trays (excluding reboiler/condenser). For example, in a column with reboiler + 10 middle trays + condenser, setReactive(true, 3, 7) makes trays 4–8 (1-based) of the middle section reactive.
      Parameters:
      reactive - true to enable reactive distillation
      startTray - first reactive middle-tray index (0-based, inclusive)
      endTray - last reactive middle-tray index (0-based, inclusive)
    • replaceMiddleTrays

      private void replaceMiddleTrays()
      Update the reactive flash flag on middle trays to match the current reactive mode configuration. Called automatically by setReactive(boolean).
    • isReactive

      public boolean isReactive()
      Check whether reactive distillation mode is enabled.
      Returns:
      true when the column has reactive trays
    • 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
    • meshResidualsSatisfied

      private boolean meshResidualsSatisfied()
      Check whether the latest MESH residual satisfies the optional convergence gate.
      Returns:
      true if MESH residual gating is disabled or the latest residual is acceptable
    • 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
    • getLastTopSpecificationResidual

      public double getLastTopSpecificationResidual()
      Retrieve the latest top specification residual.
      Returns:
      top specification residual as current value minus target value
    • getLastBottomSpecificationResidual

      public double getLastBottomSpecificationResidual()
      Retrieve the latest bottom specification residual.
      Returns:
      bottom specification residual as current value minus target value
    • getLastSpecificationResidual

      public double getLastSpecificationResidual()
      Retrieve the largest absolute active specification residual.
      Returns:
      maximum absolute top or bottom specification residual
    • getLastMeshResidualNorm

      public double getLastMeshResidualNorm()
      Retrieve the latest MESH residual vector infinity norm.
      Returns:
      maximum absolute MESH residual, or Double.NaN if no solve has been run
    • getLastMeshMaterialResidualNorm

      public double getLastMeshMaterialResidualNorm()
      Retrieve the latest MESH material residual infinity norm.
      Returns:
      maximum absolute component material residual, or Double.NaN if unavailable
    • getLastMeshEquilibriumResidualNorm

      public double getLastMeshEquilibriumResidualNorm()
      Retrieve the latest MESH equilibrium residual infinity norm.
      Returns:
      maximum absolute equilibrium residual, or Double.NaN if unavailable
    • getLastMeshSummationResidualNorm

      public double getLastMeshSummationResidualNorm()
      Retrieve the latest MESH summation residual infinity norm.
      Returns:
      maximum absolute summation residual, or Double.NaN if unavailable
    • getLastMeshEnergyResidualNorm

      public double getLastMeshEnergyResidualNorm()
      Retrieve the latest MESH energy residual infinity norm.
      Returns:
      maximum absolute energy residual, or Double.NaN if unavailable
    • getLastMeshSpecificationResidualNorm

      public double getLastMeshSpecificationResidualNorm()
      Retrieve the latest MESH specification residual infinity norm.
      Returns:
      maximum absolute specification residual, or Double.NaN if unavailable
    • getLastMeshResidualVector

      public double[] getLastMeshResidualVector()
      Retrieve a copy of the latest MESH residual vector.
      Returns:
      residual vector copy, or an empty array if no solve has been run
    • getLastMeshResidual

      ColumnMeshResidual getLastMeshResidual()
      Retrieve the latest internal MESH residual diagnostics.
      Returns:
      latest residual diagnostics, or null if no solve has been run
    • getLastMeshResidualNorm

      private double getLastMeshResidualNorm(ColumnMeshEquationType equationType)
      Get a MESH residual norm by equation type.
      Parameters:
      equationType - equation type to inspect
      Returns:
      infinity norm for that equation type, or Double.NaN if unavailable
    • 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
    • setEnforceMeshResidualTolerance

      public void setEnforceMeshResidualTolerance(boolean enforce)
      Control whether the latest MESH residual vector must satisfy tolerance during convergence checks.
      Parameters:
      enforce - true to require MESH residuals to satisfy the configured tolerance
    • isEnforceMeshResidualTolerance

      public boolean isEnforceMeshResidualTolerance()
      Check if convergence requires the latest MESH residual vector to satisfy tolerance.
      Returns:
      true if MESH residuals are part of the convergence check
    • getEnthalpyBalanceTolerance

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

      public double getMeshResidualTolerance()
      Access the configured scaled MESH residual tolerance.
      Returns:
      MESH residual 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
    • calcColumnInternals

      public ColumnInternalsDesigner calcColumnInternals(String internalsType)
      Create and run a column internals designer for this column.

      Evaluates hydraulics on every tray (flooding, weeping, entrainment, downcomer backup, pressure drop, efficiency) and sizes the column diameter from the controlling tray.

      Parameters:
      internalsType - tray type ("sieve", "valve", "bubble-cap") or "packed"
      Returns:
      a fully evaluated ColumnInternalsDesigner with per-tray results
    • calcColumnInternals

      public ColumnInternalsDesigner calcColumnInternals()
      Create and run a column internals designer for this column with default sieve trays.
      Returns:
      a fully evaluated ColumnInternalsDesigner with per-tray results
    • 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
    • getMechanicalDesign

      public MechanicalDesign 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
    • 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
    • setMeshResidualTolerance

      public void setMeshResidualTolerance(double tol)
      Set the scaled MESH residual tolerance used when MESH residual gating is enabled.
      Parameters:
      tol - positive finite tolerance
      Throws:
      IllegalArgumentException - if the tolerance is not positive and finite
    • resetToleranceOverrides

      public void resetToleranceOverrides()
      Restore adaptive default tolerances, discarding manual overrides.
    • 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
    • recordConvergence

      private void recordConvergence(double[] entry)
      Append a residual snapshot to the convergence history, capping at MAX_CONVERGENCE_HISTORY entries.
      Parameters:
      entry - residual array to record
    • applyMurphreeCorrection

      private void applyMurphreeCorrection(int trayIndex)
      Apply Murphree tray efficiency correction to the vapor leaving a tray. The correction blends the equilibrium vapor composition with the inlet vapor composition:
      y_i^out = y_i^in + E_MV * (y_i^eq - y_i^in)
      
      where E_MV is the Murphree efficiency, y_i^eq is the equilibrium composition from the flash, and y_i^in is the inlet vapor composition. When efficiency is 1.0, the tray is ideal and no correction is applied. The correction is skipped for reboilers and condensers (first and last trays).
      Parameters:
      trayIndex - index of the tray in the trays list
    • 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)
    • 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
      Specified by:
      validateSetup in interface ProcessEquipmentInterface
      Returns:
      validation result with errors and warnings
    • 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
    • setMurphreeEfficiency

      public void setMurphreeEfficiency(double efficiency)
      Set the Murphree tray efficiency for all stages.
      Parameters:
      efficiency - value between 0.0 (no separation) and 1.0 (ideal equilibrium stage)
    • getMurphreeEfficiency

      public double getMurphreeEfficiency()
      Retrieve the current Murphree tray efficiency.
      Returns:
      Murphree efficiency
    • setInnerLoopSteps

      public void setInnerLoopSteps(int steps)
      Set the number of simplified inner-loop iterations between rigorous flash updates in the IO solver. A value of 0 disables the simplified model (all iterations use rigorous flash).
      Parameters:
      steps - number of inner-loop steps (0 to disable, typically 2-5)
    • getInnerLoopSteps

      public int getInnerLoopSteps()
      Return the current number of simplified inner-loop iterations per outer flash update.
      Returns:
      inner-loop step count
    • getConvergenceHistory

      public List<double[]> getConvergenceHistory()
      Return the per-iteration convergence history from the most recent solve.

      Each entry is a three-element array: [temperatureResidual, massResidual, energyResidual].

      Returns:
      list of residual arrays, one per iteration; empty if no solve has been run
    • getSolverType

      public DistillationColumn.SolverType getSolverType()
      Retrieve the currently selected solver type.
      Returns:
      solver type enum value
    • getTrays

      public List<SimpleTray> getTrays()
      Returns the list of trays in this column.
      Returns:
      list of SimpleTray objects
    • setCondenserRefluxRatio

      public void setCondenserRefluxRatio(double refluxRatio)
      Sets the reflux ratio on the condenser (if present). Also stores a REFLUX_RATIO top specification so that the column records the user's intent.
      Parameters:
      refluxRatio - the desired reflux ratio (L/D)
    • getTopSpecification

      public ColumnSpecification getTopSpecification()
      Returns the top (condenser) column specification.
      Returns:
      the top specification, or null if not set
    • getBottomSpecification

      public ColumnSpecification getBottomSpecification()
      Returns the bottom (reboiler) column specification.
      Returns:
      the bottom specification, or null if not set
    • setTopSpecification

      public void setTopSpecification(ColumnSpecification spec)
      Sets the top column specification with location validation.
      Parameters:
      spec - the specification (must have location TOP)
      Throws:
      IllegalArgumentException - if the specification location is not TOP
    • setBottomSpecification

      public void setBottomSpecification(ColumnSpecification spec)
      Sets the bottom column specification with location validation.
      Parameters:
      spec - the specification (must have location BOTTOM)
      Throws:
      IllegalArgumentException - if the specification location is not BOTTOM
    • setTopProductPurity

      public void setTopProductPurity(String componentName, double purity)
      Convenience method to specify a target mole fraction purity for the top product.
      Parameters:
      componentName - the component to constrain
      purity - the desired mole fraction (0 to 1)
    • setBottomProductPurity

      public void setBottomProductPurity(String componentName, double purity)
      Convenience method to specify a target mole fraction purity for the bottom product.
      Parameters:
      componentName - the component to constrain
      purity - the desired mole fraction (0 to 1)
    • setReboilerBoilupRatio

      public void setReboilerBoilupRatio(double boilupRatio)
      Convenience method to specify a reboiler boilup ratio (V/B).
      Parameters:
      boilupRatio - the desired boilup ratio
    • setTopComponentRecovery

      public void setTopComponentRecovery(String componentName, double recovery)
      Convenience method to specify a target component recovery in the top product.
      Parameters:
      componentName - the component to constrain
      recovery - the desired recovery fraction (0 to 1)
    • setBottomProductFlowRate

      public void setBottomProductFlowRate(double flowRate, String unit)
      Convenience method to specify a target molar flow rate for the bottom product.
      Parameters:
      flowRate - the desired flow rate value
      unit - the flow rate unit (e.g. "mol/hr")
    • builder

      public static DistillationColumn.Builder builder(String name)
      Creates a new Builder for constructing a DistillationColumn with a fluent API.
      Parameters:
      name - the column name
      Returns:
      a new Builder instance
    • setDynamicColumnEnabled

      public void setDynamicColumnEnabled(boolean enabled)
      Enables or disables the dynamic tray-by-tray model for transient simulation.
      Parameters:
      enabled - true to enable dynamic column model
    • isDynamicColumnEnabled

      public boolean isDynamicColumnEnabled()
      Returns whether the dynamic tray-by-tray model is enabled.
      Returns:
      true if dynamic column model is active
    • setTrayWeirHeight

      public void setTrayWeirHeight(double weirHeight)
      Sets the weir height for all trays (used in Francis weir overflow).
      Parameters:
      weirHeight - weir height in metres
    • getTrayWeirHeight

      public double getTrayWeirHeight()
      Gets the weir height for all trays.
      Returns:
      weir height in metres
    • setTrayWeirLength

      public void setTrayWeirLength(double weirLength)
      Sets the weir crest length for all trays.
      Parameters:
      weirLength - weir length in metres
    • getTrayWeirLength

      public double getTrayWeirLength()
      Gets the weir crest length for all trays.
      Returns:
      weir length in metres
    • getTrayLiquidHoldup

      public double[] getTrayLiquidHoldup()
      Returns the liquid holdup array (moles per tray). May be null if dynamic model has not been initialized.
      Returns:
      array of liquid holdups indexed by tray number, or null
    • getTrayEnthalpy

      public double[] getTrayEnthalpy()
      Returns the per-tray enthalpy array in J. May be null if energy balance has not been initialized.
      Returns:
      array of tray enthalpies indexed by tray number, or null
    • setTrayDryPressureDrop

      public void setTrayDryPressureDrop(double dpPa)
      Sets the dry tray pressure drop per tray in Pa. Used in the dynamic vapor hydraulic model to compute vapor flow rate as a function of pressure difference between trays.
      Parameters:
      dpPa - dry tray pressure drop in Pascals (positive value)
    • getTrayDryPressureDrop

      public double getTrayDryPressureDrop()
      Returns the dry tray pressure drop per tray in Pa.
      Returns:
      dry tray pressure drop in Pa
    • setDynamicEnergyEnabled

      public void setDynamicEnergyEnabled(boolean enabled)
      Enables or disables the per-tray energy balance in dynamic mode. When enabled, each tray's enthalpy is tracked and PH flash is used for re-equilibration instead of TP flash.
      Parameters:
      enabled - true to enable energy-balanced trays
    • isDynamicEnergyEnabled

      public boolean isDynamicEnergyEnabled()
      Returns whether the per-tray energy balance is enabled.
      Returns:
      true if energy-balanced trays are active
    • 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.

      Dynamic distillation column model. When dynamicColumnEnabled is true, performs a single forward-Euler integration step on each tray's liquid holdup using the MESH equations. Liquid leaving each tray is calculated using the Francis weir overflow formula.

      Specified by:
      runTransient in interface SimulationInterface
      Parameters:
      dt - time step in seconds
      id - calculation identifier