Class AdsorptionBed

All Implemented Interfaces:
Serializable, Runnable, ProcessEquipmentInterface, TwoPortInterface, ProcessElementInterface, SimulationInterface, NamedInterface

public class AdsorptionBed extends TwoPortEquipment
Adsorption bed unit operation supporting both steady-state and transient simulation.

Models a fixed-bed adsorber with:

  • Equilibrium and rate-based (LDF) adsorption calculations
  • Mass transfer zone (MTZ) tracking with breakthrough curves
  • Transient bed saturation and regeneration dynamics
  • Support for PSA/TSA cycle scheduling via AdsorptionCycleController
  • Component-specific removal from the gas phase

The bed is discretized into axial cells. Each cell tracks its own solid-phase loading and uses an isotherm model to determine the local equilibrium. A linear driving force (LDF) model couples mass transfer kinetics with the axial convection of gas.

Version:
1.0
Author:
Even Solbraa
See Also:
  • Field Details

    • serialVersionUID

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

      private static final org.apache.logging.log4j.Logger logger
      Logger object for this class.
    • R

      private static final double R
      Universal gas constant (J/(mol K)).
      See Also:
    • bedDiameter

      private double bedDiameter
      Internal diameter of the bed vessel (m).
    • bedLength

      private double bedLength
      Length/height of the packed bed (m).
    • voidFraction

      private double voidFraction
      Void fraction (inter-particle porosity).
    • adsorbentMaterial

      private String adsorbentMaterial
      Name of the solid adsorbent material (matches AdsorptionParameters.csv).
    • adsorbentBulkDensity

      private double adsorbentBulkDensity
      Bulk density of the adsorbent packing (kg/m3).
    • particleDiameter

      private double particleDiameter
      Particle diameter of the adsorbent pellets/beads (m).
    • particlePorosity

      private double particlePorosity
      Particle porosity (intra-particle).
    • isothermType

      private IsothermType isothermType
      Isotherm model type to use.
    • isothermModel

      private transient AdsorptionInterface isothermModel
      The isotherm model instance (created on first use or when type changes).
    • kLDF

      private double[] kLDF
      Overall LDF mass transfer coefficients (1/s), per component.
    • defaultKLDF

      private double defaultKLDF
      Default LDF coefficient when not explicitly set (1/s).
    • numberOfCells

      private int numberOfCells
      Number of axial cells for the spatial grid.
    • solidLoading

      private double[][] solidLoading
      Solid-phase loading in each cell (mol/kg adsorbent). Dimensions: [numberOfCells][numberOfComponents].
    • gasConcentation

      private double[][] gasConcentation
      Gas-phase molar concentration in each cell (mol/m3). Dimensions: [numberOfCells][numberOfComponents].
    • elapsedTime

      private double elapsedTime
      Total elapsed simulation time (s).
    • transientInitialised

      private boolean transientInitialised
      Whether the transient grid has been initialised.
    • pressureDrop

      private double pressureDrop
      Pressure drop across the bed (Pa).
    • calculatePressureDrop

      private boolean calculatePressureDrop
      Whether to model pressure drop with Ergun equation.
    • currentPhase

      Current operating phase of the adsorber.
    • desorptionMode

      private boolean desorptionMode
      Whether the bed is currently in desorption mode.
    • purgeFlowRate

      private double purgeFlowRate
      Desorption purge-gas flow rate (mol/s) — zero means use feed flow.
    • desorptionTemperature

      private double desorptionTemperature
      Desorption temperature for TSA (K). Zero means same as feed (PSA only).
    • desorptionPressure

      private double desorptionPressure
      Desorption pressure for PSA (bara). Zero means same as feed.
    • system

      private SystemInterface system
      Working copy of the thermodynamic system.
    • breakthroughThreshold

      private double breakthroughThreshold
      Breakthrough threshold: fraction of inlet concentration (0-1).
    • breakthroughOccurred

      private boolean breakthroughOccurred
      Whether any component has broken through (outlet/inlet > threshold).
    • breakthroughTime

      private double breakthroughTime
      Time at which breakthrough was first detected (s).
  • Constructor Details

    • AdsorptionBed

      public AdsorptionBed(String name)
      Constructor for AdsorptionBed.
      Parameters:
      name - the name of the unit operation
    • AdsorptionBed

      public AdsorptionBed(String name, StreamInterface inletStream)
      Constructor for AdsorptionBed with inlet stream.
      Parameters:
      name - the name of the unit operation
      inletStream - the inlet gas stream to the adsorber
  • Method Details

    • run

      public void run(UUID id)

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

      In steady-state mode the bed is assumed to be at cyclic-steady-state: the outlet composition reflects the equilibrium loading at the feed conditions scaled by an efficiency factor derived from number-of-transfer-units (NTU).

      Parameters:
      id - UUID
    • 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.

      Transient simulation of the adsorption bed. The bed is discretized into axial cells. Each time-step:

      1. Convective transport of gas through the cells (upwind scheme)
      2. LDF mass transfer between gas and solid in each cell
      3. Update solid loadings and gas concentrations
      4. Determine outlet composition from the last cell
      Parameters:
      dt - time step size (seconds)
      id - calculation identifier
    • initialiseTransientGrid

      public void initialiseTransientGrid()
      Initialise the axial discretization grid. Sets all solid loadings to zero (clean bed) and gas concentrations to zero.
    • preloadBed

      public void preloadBed(double fractionalSaturation, int phaseNum)
      Pre-load the bed to a specified fractional saturation. Useful for simulating partially saturated beds or starting desorption.
      Parameters:
      fractionalSaturation - fraction of equilibrium loading (0 = clean, 1 = saturated)
      phaseNum - the phase number for equilibrium calculation
    • setDesorptionMode

      public void setDesorptionMode(boolean desorb)
      Switch the bed into desorption mode. In desorption mode, the inlet concentration is treated as zero (or purge gas) and the equilibrium loading is recalculated at desorption conditions.
      Parameters:
      desorb - true to enable desorption, false for adsorption
    • setDesorptionTemperature

      public void setDesorptionTemperature(double temperature)
      Set the desorption temperature for TSA regeneration.
      Parameters:
      temperature - desorption temperature in Kelvin
    • setDesorptionPressure

      public void setDesorptionPressure(double pressure)
      Set the desorption pressure for PSA blowdown.
      Parameters:
      pressure - desorption pressure in bara
    • setPurgeFlowRate

      public void setPurgeFlowRate(double flowRate)
      Set the purge gas flow rate during desorption.
      Parameters:
      flowRate - purge gas flow rate in mol/s
    • calcErgunPressureDrop

      private double calcErgunPressureDrop(SystemInterface sys, double us)
      Calculate pressure drop across the packed bed using the Ergun equation.

      The Ergun equation combines viscous (Blake-Kozeny) and inertial (Burke-Plummer) terms:

      $$\frac{\Delta P}{L} = \frac{150 \mu u_s (1-\varepsilon)^2}{\varepsilon^3 d_p^2} + \frac{1.75 \rho u_s^2 (1-\varepsilon)}{\varepsilon^3 d_p}$$
      Parameters:
      sys - the thermodynamic system for fluid properties
      us - superficial velocity (m/s)
      Returns:
      total pressure drop (Pa)
    • superficialVelocity

      private double superficialVelocity(SystemInterface sys)
      Calculate superficial velocity from a thermodynamic system.
      Parameters:
      sys - the thermodynamic system
      Returns:
      superficial velocity in m/s
    • checkBreakthrough

      private void checkBreakthrough(double[] inletConc, double[] outletConc)
      Check whether any component has broken through the bed.
      Parameters:
      inletConc - inlet gas concentrations (mol/m3)
      outletConc - outlet gas concentrations (mol/m3)
    • getOrCreateIsothermModel

      private AdsorptionInterface getOrCreateIsothermModel(SystemInterface sys)
      Get or create the isotherm model. Reuses the existing model if compatible, otherwise creates a new one.
      Parameters:
      sys - the thermodynamic system
      Returns:
      the adsorption model instance
    • createIsothermModel

      private AdsorptionInterface createIsothermModel(SystemInterface sys)
      Create a new isotherm model of the configured type.
      Parameters:
      sys - the thermodynamic system
      Returns:
      the adsorption model instance
    • getLoadingProfile

      public double[] getLoadingProfile(int component)
      Get the solid-phase loading profile along the bed.
      Parameters:
      component - component index
      Returns:
      array of loadings (mol/kg) for each axial cell
    • getConcentrationProfile

      public double[] getConcentrationProfile(int component)
      Get the gas-phase concentration profile along the bed.
      Parameters:
      component - component index
      Returns:
      array of concentrations (mol/m3) for each axial cell
    • getAverageLoading

      public double getAverageLoading(int component)
      Get the average solid loading across the entire bed for a component.
      Parameters:
      component - component index
      Returns:
      average loading in mol/kg
    • getBedUtilization

      public double getBedUtilization(int component)
      Get the bed utilization factor (average loading / equilibrium loading).
      Parameters:
      component - component index
      Returns:
      utilization factor (0 to 1)
    • getMassTransferZoneLength

      public double getMassTransferZoneLength(int component)
      Estimate the length of the mass transfer zone for a component.

      The MTZ is defined as the axial distance over which the normalised gas concentration transitions from 0.05 to 0.95 of the inlet concentration.

      Parameters:
      component - component index
      Returns:
      mass transfer zone length in metres (0 if not applicable)
    • getAdsorbentMass

      public double getAdsorbentMass()
      Get the total mass of adsorbent in the bed.
      Returns:
      adsorbent mass in kg
    • getBedVolume

      public double getBedVolume()
      Get the bed volume.
      Returns:
      bed volume in m3
    • sumArray

      private double sumArray(double[] arr)
      Sum the elements of an array.
      Parameters:
      arr - the array
      Returns:
      the sum
    • 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 TwoPortEquipment
      Returns:
      json string.
    • 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 two-port equipment setup before execution. Checks that:

      • Equipment has a valid name
      • Inlet stream is connected
      • Outlet stream is initialized
      Specified by:
      validateSetup in interface ProcessEquipmentInterface
      Overrides:
      validateSetup in class TwoPortEquipment
      Returns:
      validation result with errors and warnings
    • getBedDiameter

      public double getBedDiameter()
      Get the bed internal diameter.
      Returns:
      bed diameter in metres
    • setBedDiameter

      public void setBedDiameter(double diameter)
      Set the bed internal diameter.
      Parameters:
      diameter - bed diameter in metres
    • getBedLength

      public double getBedLength()
      Get the bed length.
      Returns:
      bed length in metres
    • setBedLength

      public void setBedLength(double length)
      Set the bed length.
      Parameters:
      length - bed length in metres
    • getVoidFraction

      public double getVoidFraction()
      Get the void fraction.
      Returns:
      void fraction (0 to 1)
    • setVoidFraction

      public void setVoidFraction(double voidFraction)
      Set the void fraction (inter-particle porosity).
      Parameters:
      voidFraction - void fraction (0 to 1)
    • getAdsorbentMaterial

      public String getAdsorbentMaterial()
      Get the adsorbent material name.
      Returns:
      adsorbent material name
    • setAdsorbentMaterial

      public void setAdsorbentMaterial(String material)
      Set the adsorbent material name (must match entry in AdsorptionParameters.csv).
      Parameters:
      material - adsorbent material name
    • getAdsorbentBulkDensity

      public double getAdsorbentBulkDensity()
      Get the adsorbent bulk density.
      Returns:
      bulk density in kg/m3
    • setAdsorbentBulkDensity

      public void setAdsorbentBulkDensity(double density)
      Set the adsorbent bulk density.
      Parameters:
      density - bulk density in kg/m3
    • getParticleDiameter

      public double getParticleDiameter()
      Get the particle diameter.
      Returns:
      particle diameter in metres
    • setParticleDiameter

      public void setParticleDiameter(double diameter)
      Set the adsorbent particle diameter.
      Parameters:
      diameter - particle diameter in metres
    • getParticlePorosity

      public double getParticlePorosity()
      Get the particle porosity.
      Returns:
      particle porosity (0 to 1)
    • setParticlePorosity

      public void setParticlePorosity(double porosity)
      Set the particle porosity (intra-particle).
      Parameters:
      porosity - particle porosity (0 to 1)
    • getIsothermType

      public IsothermType getIsothermType()
      Get the isotherm type used by this bed.
      Returns:
      the isotherm type
    • setIsothermType

      public void setIsothermType(IsothermType type)
      Set the isotherm type.
      Parameters:
      type - the isotherm type
    • getKLDF

      public double getKLDF(int component)
      Get the LDF mass transfer coefficient for a component.
      Parameters:
      component - component index
      Returns:
      k_LDF in 1/s
    • setKLDF

      public void setKLDF(int component, double value)
      Set the LDF mass transfer coefficient for a component.
      Parameters:
      component - component index
      value - k_LDF in 1/s
    • setKLDF

      public void setKLDF(double value)
      Set all LDF mass transfer coefficients to the same value.
      Parameters:
      value - k_LDF in 1/s
    • getNumberOfCells

      public int getNumberOfCells()
      Get the number of axial cells.
      Returns:
      number of cells
    • setNumberOfCells

      public void setNumberOfCells(int cells)
      Set the number of axial cells for spatial discretization.
      Parameters:
      cells - number of cells (must be at least 2)
    • getPressureDrop

      public double getPressureDrop()
      Get the pressure drop across the bed.
      Returns:
      pressure drop in Pa
    • getPressureDrop

      public double getPressureDrop(String unit)
      Get the pressure drop across the bed in a specified unit.
      Parameters:
      unit - pressure unit ("Pa", "bar", "bara", "psi")
      Returns:
      pressure drop in the given unit
    • setCalculatePressureDrop

      public void setCalculatePressureDrop(boolean calculate)
      Set whether to calculate pressure drop from the Ergun equation.
      Parameters:
      calculate - true to calculate, false to ignore
    • getElapsedTime

      public double getElapsedTime()
      Get the elapsed simulation time.
      Returns:
      elapsed time in seconds
    • isBreakthroughOccurred

      public boolean isBreakthroughOccurred()
      Check if breakthrough has occurred.
      Returns:
      true if breakthrough detected
    • getBreakthroughTime

      public double getBreakthroughTime()
      Get the breakthrough time.
      Returns:
      breakthrough time in seconds, or -1 if not yet occurred
    • setBreakthroughThreshold

      public void setBreakthroughThreshold(double threshold)
      Set the breakthrough detection threshold.
      Parameters:
      threshold - outlet/inlet concentration ratio (0 to 1)
    • isDesorptionMode

      public boolean isDesorptionMode()
      Check if the bed is in desorption mode.
      Returns:
      true if desorbing
    • getCurrentPhase

      public AdsorptionCycleController.CyclePhase getCurrentPhase()
      Get the current cycle phase.
      Returns:
      current cycle phase
    • resetBed

      public void resetBed()
      Reset the bed to a clean state (all loadings and concentrations to zero).
    • getIsothermModel

      public AdsorptionInterface getIsothermModel()
      Get the isotherm model currently used by this bed.
      Returns:
      the adsorption model, or null if not yet created