Class AdsorptionBed
- All Implemented Interfaces:
Serializable, Runnable, ProcessEquipmentInterface, TwoPortInterface, ProcessElementInterface, SimulationInterface, NamedInterface
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 Summary
FieldsModifier and TypeFieldDescriptionprivate doubleBulk density of the adsorbent packing (kg/m3).private StringName of the solid adsorbent material (matches AdsorptionParameters.csv).private doubleInternal diameter of the bed vessel (m).private doubleLength/height of the packed bed (m).private booleanWhether any component has broken through (outlet/inlet > threshold).private doubleBreakthrough threshold: fraction of inlet concentration (0-1).private doubleTime at which breakthrough was first detected (s).private booleanWhether to model pressure drop with Ergun equation.Current operating phase of the adsorber.private doubleDefault LDF coefficient when not explicitly set (1/s).private booleanWhether the bed is currently in desorption mode.private doubleDesorption pressure for PSA (bara).private doubleDesorption temperature for TSA (K).private doubleTotal elapsed simulation time (s).private double[][]Gas-phase molar concentration in each cell (mol/m3).private AdsorptionInterfaceThe isotherm model instance (created on first use or when type changes).private IsothermTypeIsotherm model type to use.private double[]Overall LDF mass transfer coefficients (1/s), per component.private static final org.apache.logging.log4j.LoggerLogger object for this class.private intNumber of axial cells for the spatial grid.private doubleParticle diameter of the adsorbent pellets/beads (m).private doubleParticle porosity (intra-particle).private doublePressure drop across the bed (Pa).private doubleDesorption purge-gas flow rate (mol/s) — zero means use feed flow.private static final doubleUniversal gas constant (J/(mol K)).private static final longSerialization version UID.private double[][]Solid-phase loading in each cell (mol/kg adsorbent).private SystemInterfaceWorking copy of the thermodynamic system.private booleanWhether the transient grid has been initialised.private doubleVoid fraction (inter-particle porosity).Fields inherited from class TwoPortEquipment
inStream, outStreamFields inherited from class ProcessEquipmentBaseClass
conditionAnalysisMessage, energyStream, hasController, isSolved, properties, reportFields inherited from class SimulationBaseClass
calcIdentifier, calculateSteadyState, timeFields inherited from class NamedBaseClass
name -
Constructor Summary
ConstructorsConstructorDescriptionAdsorptionBed(String name) Constructor for AdsorptionBed.AdsorptionBed(String name, StreamInterface inletStream) Constructor for AdsorptionBed with inlet stream. -
Method Summary
Modifier and TypeMethodDescriptionprivate doublecalcErgunPressureDrop(SystemInterface sys, double us) Calculate pressure drop across the packed bed using the Ergun equation.private voidcheckBreakthrough(double[] inletConc, double[] outletConc) Check whether any component has broken through the bed.private AdsorptionInterfaceCreate a new isotherm model of the configured type.doubleGet the adsorbent bulk density.doubleGet the total mass of adsorbent in the bed.Get the adsorbent material name.doublegetAverageLoading(int component) Get the average solid loading across the entire bed for a component.doubleGet the bed internal diameter.doubleGet the bed length.doublegetBedUtilization(int component) Get the bed utilization factor (average loading / equilibrium loading).doubleGet the bed volume.doubleGet the breakthrough time.double[]getConcentrationProfile(int component) Get the gas-phase concentration profile along the bed.Get the current cycle phase.doubleGet the elapsed simulation time.Get the isotherm model currently used by this bed.Get the isotherm type used by this bed.doublegetKLDF(int component) Get the LDF mass transfer coefficient for a component.double[]getLoadingProfile(int component) Get the solid-phase loading profile along the bed.doublegetMassTransferZoneLength(int component) Estimate the length of the mass transfer zone for a component.intGet the number of axial cells.private AdsorptionInterfaceGet or create the isotherm model.doubleGet the particle diameter.doubleGet the particle porosity.doubleGet the pressure drop across the bed.doublegetPressureDrop(String unit) Get the pressure drop across the bed in a specified unit.doubleGet the void fraction.voidInitialise the axial discretization grid.booleanCheck if breakthrough has occurred.booleanCheck if the bed is in desorption mode.voidpreloadBed(double fractionalSaturation, int phaseNum) Pre-load the bed to a specified fractional saturation.voidresetBed()Reset the bed to a clean state (all loadings and concentrations to zero).voidIn this method all thermodynamic and unit operations will be calculated in a steady state calculation.voidrunTransient(double dt, UUID id) runTransientvoidsetAdsorbentBulkDensity(double density) Set the adsorbent bulk density.voidsetAdsorbentMaterial(String material) Set the adsorbent material name (must match entry in AdsorptionParameters.csv).voidsetBedDiameter(double diameter) Set the bed internal diameter.voidsetBedLength(double length) Set the bed length.voidsetBreakthroughThreshold(double threshold) Set the breakthrough detection threshold.voidsetCalculatePressureDrop(boolean calculate) Set whether to calculate pressure drop from the Ergun equation.voidsetDesorptionMode(boolean desorb) Switch the bed into desorption mode.voidsetDesorptionPressure(double pressure) Set the desorption pressure for PSA blowdown.voidsetDesorptionTemperature(double temperature) Set the desorption temperature for TSA regeneration.voidsetIsothermType(IsothermType type) Set the isotherm type.voidsetKLDF(double value) Set all LDF mass transfer coefficients to the same value.voidsetKLDF(int component, double value) Set the LDF mass transfer coefficient for a component.voidsetNumberOfCells(int cells) Set the number of axial cells for spatial discretization.voidsetParticleDiameter(double diameter) Set the adsorbent particle diameter.voidsetParticlePorosity(double porosity) Set the particle porosity (intra-particle).voidsetPurgeFlowRate(double flowRate) Set the purge gas flow rate during desorption.voidsetVoidFraction(double voidFraction) Set the void fraction (inter-particle porosity).private doublesumArray(double[] arr) Sum the elements of an array.private doubleCalculate superficial velocity from a thermodynamic system.toJson()Serializes the Process Equipment along with its state to a JSON string.Validate the process equipment before execution.Methods inherited from class TwoPortEquipment
getInletPressure, getInletStream, getInletStreams, getInletTemperature, getMassBalance, getOutletPressure, getOutletStream, getOutletStreams, getOutletTemperature, setInletPressure, setInletStream, setInletTemperature, setOutletPressure, setOutletPressure, setOutletStream, setOutletTemperature, setOutletTemperature, toJsonMethods inherited from class ProcessEquipmentBaseClass
addCapacityConstraint, addController, copy, displayResult, equals, getAvailableMargin, getAvailableMarginPercent, getBottleneckConstraint, getCapacityConstraints, getConditionAnalysisMessage, getConstraintEvaluationReport, getController, getController, getControllers, getEffectiveCapacityFactor, getEnergyStream, getEntropyProduction, getExergyChange, getFailureMode, getMassBalance, getMaxUtilization, getMaxUtilizationPercent, getMechanicalDesign, getMinimumFlow, getPressure, getPressure, getProperty, getReferenceDesignation, getReport_json, getResultTable, getSpecification, getTemperature, getTemperature, getThermoSystem, getUtilizationSummary, hashCode, initElectricalDesign, initializeDefaultConstraints, initInstrumentDesign, initMechanicalDesign, isActive, isActive, isCapacityAnalysisEnabled, isCapacityExceeded, isFailed, isHardLimitExceeded, isNearCapacityLimit, isSetEnergyStream, reportResults, restoreFromFailure, run_step, runConditionAnalysis, setCapacityAnalysisEnabled, setController, setEnergyStream, setEnergyStream, setFailureMode, setFlowValveController, setMinimumFlow, setPressure, setReferenceDesignation, setRegulatorOutSignal, setSpecification, setTemperature, simulateDegradedOperation, simulateTrip, solvedMethods inherited from class SimulationBaseClass
getCalculateSteadyState, getCalculationIdentifier, getTime, increaseTime, isRunInSteps, setCalculateSteadyState, setCalculationIdentifier, setRunInSteps, setTimeMethods inherited from class NamedBaseClass
getName, getTagNumber, setName, setTagNumberMethods inherited from class Object
clone, finalize, getClass, notify, notifyAll, toString, wait, wait, waitMethods inherited from interface NamedInterface
getName, getTagName, getTagNumber, setName, setTagName, setTagNumberMethods inherited from interface ProcessEquipmentInterface
getCapacityDuty, getCapacityMax, getElectricalDesign, getEquipmentState, getExergyChange, getExergyDestruction, getExergyDestruction, getFluid, getInstrumentDesign, getOperatingEnvelopeViolation, getOutletFlowRate, getOutletPressure, getOutletTemperature, getReferenceDesignationString, getRestCapacity, getSimulationValidationErrors, isSimulationValid, isWithinOperatingEnvelope, needRecalculationMethods inherited from interface SimulationInterface
getCalculateSteadyState, getCalculationIdentifier, getTime, increaseTime, isRunInSteps, run, run_step, runTransient, setCalculateSteadyState, setCalculationIdentifier, setRunInSteps, setTimeMethods inherited from interface TwoPortInterface
getInStream, getOutStream, setOutPressure, setOutPressure, setOutTemperature, setOutTemperature
-
Field Details
-
serialVersionUID
private static final long serialVersionUIDSerialization version UID.- See Also:
-
logger
private static final org.apache.logging.log4j.Logger loggerLogger object for this class. -
R
private static final double RUniversal gas constant (J/(mol K)).- See Also:
-
bedDiameter
private double bedDiameterInternal diameter of the bed vessel (m). -
bedLength
private double bedLengthLength/height of the packed bed (m). -
voidFraction
private double voidFractionVoid fraction (inter-particle porosity). -
adsorbentMaterial
Name of the solid adsorbent material (matches AdsorptionParameters.csv). -
adsorbentBulkDensity
private double adsorbentBulkDensityBulk density of the adsorbent packing (kg/m3). -
particleDiameter
private double particleDiameterParticle diameter of the adsorbent pellets/beads (m). -
particlePorosity
private double particlePorosityParticle porosity (intra-particle). -
isothermType
Isotherm model type to use. -
isothermModel
The isotherm model instance (created on first use or when type changes). -
kLDF
private double[] kLDFOverall LDF mass transfer coefficients (1/s), per component. -
defaultKLDF
private double defaultKLDFDefault LDF coefficient when not explicitly set (1/s). -
numberOfCells
private int numberOfCellsNumber of axial cells for the spatial grid. -
solidLoading
private double[][] solidLoadingSolid-phase loading in each cell (mol/kg adsorbent). Dimensions:[numberOfCells][numberOfComponents]. -
gasConcentation
private double[][] gasConcentationGas-phase molar concentration in each cell (mol/m3). Dimensions:[numberOfCells][numberOfComponents]. -
elapsedTime
private double elapsedTimeTotal elapsed simulation time (s). -
transientInitialised
private boolean transientInitialisedWhether the transient grid has been initialised. -
pressureDrop
private double pressureDropPressure drop across the bed (Pa). -
calculatePressureDrop
private boolean calculatePressureDropWhether to model pressure drop with Ergun equation. -
currentPhase
Current operating phase of the adsorber. -
desorptionMode
private boolean desorptionModeWhether the bed is currently in desorption mode. -
purgeFlowRate
private double purgeFlowRateDesorption purge-gas flow rate (mol/s) — zero means use feed flow. -
desorptionTemperature
private double desorptionTemperatureDesorption temperature for TSA (K). Zero means same as feed (PSA only). -
desorptionPressure
private double desorptionPressureDesorption pressure for PSA (bara). Zero means same as feed. -
system
Working copy of the thermodynamic system. -
breakthroughThreshold
private double breakthroughThresholdBreakthrough threshold: fraction of inlet concentration (0-1). -
breakthroughOccurred
private boolean breakthroughOccurredWhether any component has broken through (outlet/inlet > threshold). -
breakthroughTime
private double breakthroughTimeTime at which breakthrough was first detected (s).
-
-
Constructor Details
-
AdsorptionBed
Constructor for AdsorptionBed.- Parameters:
name- the name of the unit operation
-
AdsorptionBed
Constructor for AdsorptionBed with inlet stream.- Parameters:
name- the name of the unit operationinletStream- the inlet gas stream to the adsorber
-
-
Method Details
-
run
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
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:
- Convective transport of gas through the cells (upwind scheme)
- LDF mass transfer between gas and solid in each cell
- Update solid loadings and gas concentrations
- 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-trueto enable desorption,falsefor 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
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 propertiesus- superficial velocity (m/s)- Returns:
- total pressure drop (Pa)
-
superficialVelocity
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
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
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
Serializes the Process Equipment along with its state to a JSON string.
- Specified by:
toJsonin interfaceProcessEquipmentInterface- Overrides:
toJsonin classTwoPortEquipment- Returns:
- json string.
-
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:
validateSetupin interfaceProcessEquipmentInterface- Overrides:
validateSetupin classTwoPortEquipment- 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
Get the adsorbent material name.- Returns:
- adsorbent material name
-
setAdsorbentMaterial
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
Get the isotherm type used by this bed.- Returns:
- the isotherm type
-
setIsothermType
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 indexvalue- 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
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
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
Get the isotherm model currently used by this bed.- Returns:
- the adsorption model, or null if not yet created
-