Class MercuryRemovalBed
- All Implemented Interfaces:
Serializable, Runnable, ProcessEquipmentInterface, TwoPortInterface, ProcessElementInterface, SimulationInterface, NamedInterface
Models irreversible chemisorption of elemental mercury (Hg0) onto metal-sulphide sorbents such as CuS, FeS, or ZnS pellets commonly used in LNG pre-treatment. Unlike physical adsorption the reaction is non-regenerable: the bed is replaced when spent.
Features:
- Irreversible Langmuir–Hinshelwood chemisorption kinetics
- Time-dependent bed loading and mercury breakthrough tracking
- Mass-transfer-zone (MTZ) length estimation
- Degradation modelling for fouled/degraded column internals
- Ergun-equation pressure drop
- Integrated mechanical design and cost estimation
- Version:
- 1.0
- Author:
- Even Solbraa
- See Also:
-
Field Summary
FieldsModifier and TypeFieldDescriptionprivate doubleActivation energy for the chemisorption reaction (J/mol).private doubleInternal diameter of the bed vessel (m).private doubleLength/height of the packed section (m).private booleanWhether breakthrough has been detected.private doubleBreakthrough threshold as fraction of inlet Hg concentration (0–1).private doubleTime at which breakthrough was first detected (hours).private doubleFraction of bed that is bypassed due to channelling caused by degraded internals (0–1).private booleanWhether to calculate pressure drop via Ergun equation.private double[]Gas-phase Hg concentration in each cell (microgram/Nm3).private double[]Mercury loading in each cell (mg Hg / kg sorbent).private doubleOverall degradation factor (0–1).private doubleTotal elapsed on-stream time (hours).private static final org.apache.logging.log4j.LoggerLogger object for this class.private doubleMaximum mercury loading capacity of the sorbent (mg Hg / kg sorbent).private intIndex of the mercury component in the thermodynamic system (-1 if not present).private intNumber of axial cells.private doubleSorbent particle diameter (m).private doublePressure drop across the bed (Pa).private doubleFirst-order rate constant for chemisorption (1/s).private doubleReference temperature for the rate constant (K).private doublePractical sorbent utilisation at replacement (0–1).private static final longSerialization version UID.private doubleBulk density of the sorbent (kg/m3).private StringName or trade-mark of the sorbent material (e.g.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
ConstructorsConstructorDescriptionMercuryRemovalBed(String name) Constructor for MercuryRemovalBed.MercuryRemovalBed(String name, StreamInterface inletStream) Constructor for MercuryRemovalBed 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 doubleCalculate the inlet mercury concentration in microgram/Nm3.private doubleeffectiveRateConstant(double temperatureK) Calculate the temperature-corrected effective rate constant using an Arrhenius relation.doubleEstimate bed lifetime (hours) based on current inlet conditions and bed capacity.private voidFind the index of elemental mercury in the thermodynamic system.doubleGet the activation energy.doubleGet the average mercury loading across the entire bed.doubleGet the bed internal diameter.doubleGet the bed length.doubleGet the bed utilisation factor (average loading / effective capacity).doubleGet the bed volume.doubleGet the breakthrough time.doubleGet the bypass fraction.double[]Get the gas-phase mercury concentration profile along the bed.doubleGet the degradation factor.doubleGet the elapsed on-stream time in hours.double[]Get the mercury loading profile along the bed.doubleEstimate the length of the mass transfer zone (MTZ).doubleGet the maximum mercury loading capacity.Get amechanicalDesignfor the equipment.intGet the number of axial cells.doubleGet the particle diameter.doubleGet the pressure drop across the bed.doublegetPressureDrop(String unit) Get the pressure drop across the bed in a specified unit.doubleGet the chemisorption reaction rate constant.doubleGet the reference temperature for the Arrhenius rate constant.doubleGet the outlet mercury removal efficiency based on the most recent calculation.doubleGet the practical replacement utilisation factor.doubleGet the sorbent bulk density.doubleGet the total mass of sorbent in the bed.Get the sorbent type name.doubleGet the void fraction.voidInitialise the axial discretisation grid with empty sorbent.booleanCheck if mercury breakthrough has occurred.voidpreloadBed(double fractionalSaturation) Pre-load the bed to simulate a partially spent sorbent.voidresetBed()Reset the bed to a fresh (unloaded) state.voidIn this method all thermodynamic and unit operations will be calculated in a steady state calculation.voidrunTransient(double dt, UUID id) runTransientvoidsetActivationEnergy(double energy) Set the activation energy for the chemisorption reaction.voidsetBedDiameter(double diameter) Set the bed internal diameter.voidsetBedLength(double length) Set the bed length.voidsetBreakthroughThreshold(double threshold) Set the breakthrough detection threshold.voidsetBypassFraction(double fraction) Set the bypass fraction to model channelling due to degraded internals.voidsetCalculatePressureDrop(boolean calculate) Set whether to calculate pressure drop from the Ergun equation.voidsetDegradationFactor(double factor) Set the degradation factor for column internals or sorbent fouling.voidsetMaxMercuryCapacity(double capacity) Set the maximum mercury loading capacity of the sorbent.voidsetNumberOfCells(int cells) Set the number of axial cells for spatial discretisation.private voidsetOutletMercuryFromConcentration(SystemInterface sys, double outletConc, double inletConc) Set the outlet mercury content by scaling the inlet mole fraction.voidsetParticleDiameter(double diameter) Set the sorbent particle diameter.voidsetReactionRateConstant(double k) Set the chemisorption reaction rate constant.voidsetReferenceTemperature(double temperature) Set the reference temperature for the Arrhenius rate constant.voidsetReplacementUtilisation(double utilisation) Set the practical replacement utilisation factor.voidsetSorbentBulkDensity(double density) Set the sorbent bulk density.voidsetSorbentType(String sorbentType) Set the sorbent type name (e.g.voidsetVoidFraction(double voidFraction) Set the void fraction (inter-particle porosity).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, 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. -
bedDiameter
private double bedDiameterInternal diameter of the bed vessel (m). -
bedLength
private double bedLengthLength/height of the packed section (m). -
voidFraction
private double voidFractionVoid fraction (inter-particle porosity). -
sorbentType
Name or trade-mark of the sorbent material (e.g. "PuraSpec", "MRU-CuS"). -
sorbentBulkDensity
private double sorbentBulkDensityBulk density of the sorbent (kg/m3). -
particleDiameter
private double particleDiameterSorbent particle diameter (m). -
maxMercuryCapacity
private double maxMercuryCapacityMaximum mercury loading capacity of the sorbent (mg Hg / kg sorbent). Typical PuraSpec values are 10–25 wt% Hg; default 10 wt% = 100 000 mg/kg. -
reactionRateConstant
private double reactionRateConstantFirst-order rate constant for chemisorption (1/s). Relates to the linear-driving-force approximation: r = k * C_Hg * (1 - theta). Typical value for PuraSpec-type CuS sorbents: 0.3-0.8 s⁻¹. -
activationEnergy
private double activationEnergyActivation energy for the chemisorption reaction (J/mol). -
referenceTemperature
private double referenceTemperatureReference temperature for the rate constant (K). -
degradationFactor
private double degradationFactorOverall degradation factor (0–1). At 1.0 the bed is brand-new; at lower values the effective capacity and/or rate constant are reduced because of fouling, liquid carry-over, or other damage to column internals. -
bypassFraction
private double bypassFractionFraction of bed that is bypassed due to channelling caused by degraded internals (0–1). At 0 there is no bypass. Gas that bypasses does not contact sorbent. -
numberOfCells
private int numberOfCellsNumber of axial cells. -
cellLoading
private double[] cellLoadingMercury loading in each cell (mg Hg / kg sorbent). -
cellHgConcentration
private double[] cellHgConcentrationGas-phase Hg concentration in each cell (microgram/Nm3). -
transientInitialised
private boolean transientInitialisedWhether the transient grid has been initialised. -
elapsedTimeHours
private double elapsedTimeHoursTotal elapsed on-stream time (hours). -
replacementUtilisation
private double replacementUtilisationPractical sorbent utilisation at replacement (0–1). In practice operators change out sorbent when only a fraction of the theoretical capacity has been used, because the mass-transfer zone leaves the tail of the bed under-utilised and a safety margin is maintained before breakthrough. Typical values: 0.4–0.6 for single beds, 0.7–0.9 for lead–lag configurations. -
breakthroughThreshold
private double breakthroughThresholdBreakthrough threshold as fraction of inlet Hg concentration (0–1). -
breakthroughOccurred
private boolean breakthroughOccurredWhether breakthrough has been detected. -
breakthroughTimeHours
private double breakthroughTimeHoursTime at which breakthrough was first detected (hours). -
pressureDrop
private double pressureDropPressure drop across the bed (Pa). -
calculatePressureDrop
private boolean calculatePressureDropWhether to calculate pressure drop via Ergun equation. -
mercuryIndex
private int mercuryIndexIndex of the mercury component in the thermodynamic system (-1 if not present). -
system
Working copy of the thermodynamic system.
-
-
Constructor Details
-
MercuryRemovalBed
Constructor for MercuryRemovalBed.- Parameters:
name- the name of the unit operation
-
MercuryRemovalBed
Constructor for MercuryRemovalBed with inlet stream.- Parameters:
name- the name of the unit operationinletStream- the inlet gas stream
-
-
Method Details
-
run
In this method all thermodynamic and unit operations will be calculated in a steady state calculation.
Steady-state mode assumes the bed is not yet saturated and calculates mercury removal based on the overall NTU/efficiency for the current bed geometry and kinetics.
- 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.Advances the bed state by
dtseconds. The bed is discretised into axial cells; each cell tracks its local mercury loading and gas-phase Hg concentration. The irreversible chemisorption kinetics consume mercury from the gas phase and accumulate it on the sorbent until the local capacity is exhausted.- Parameters:
dt- time-step size in secondsid- calculation identifier
-
initialiseTransientGrid
public void initialiseTransientGrid()Initialise the axial discretisation grid with empty sorbent. -
preloadBed
public void preloadBed(double fractionalSaturation) Pre-load the bed to simulate a partially spent sorbent.- Parameters:
fractionalSaturation- fraction of maximum capacity already consumed (0 = fresh, 1 = spent)
-
resetBed
public void resetBed()Reset the bed to a fresh (unloaded) state. -
getLoadingProfile
public double[] getLoadingProfile()Get the mercury loading profile along the bed.- Returns:
- array of loading values (mg Hg / kg sorbent) per axial cell
-
getConcentrationProfile
public double[] getConcentrationProfile()Get the gas-phase mercury concentration profile along the bed.- Returns:
- array of concentrations (microgram/Nm3) per axial cell
-
getAverageLoading
public double getAverageLoading()Get the average mercury loading across the entire bed.- Returns:
- average loading in mg Hg / kg sorbent
-
getBedUtilisation
public double getBedUtilisation()Get the bed utilisation factor (average loading / effective capacity).- Returns:
- utilisation factor (0 to 1)
-
getMassTransferZoneLength
public double getMassTransferZoneLength()Estimate the length of the mass transfer zone (MTZ).The MTZ is defined as the axial distance over which the normalised gas-phase Hg concentration transitions from 0.05 to 0.95 of the inlet concentration.
- Returns:
- MTZ length in metres, 0 if not applicable
-
estimateBedLifetime
public double estimateBedLifetime()Estimate bed lifetime (hours) based on current inlet conditions and bed capacity.- Returns:
- estimated lifetime in hours, or -1 if mercury is not present
-
getSorbentMass
public double getSorbentMass()Get the total mass of sorbent in the bed.- Returns:
- sorbent mass in kg
-
getBedVolume
public double getBedVolume()Get the bed volume.- Returns:
- bed volume in m3
-
getRemovalEfficiency
public double getRemovalEfficiency()Get the outlet mercury removal efficiency based on the most recent calculation.- Returns:
- removal efficiency (0 to 1), or -1 if not yet calculated
-
getMechanicalDesign
Get a
mechanicalDesignfor the equipment.- Specified by:
getMechanicalDesignin interfaceProcessEquipmentInterface- Overrides:
getMechanicalDesignin classProcessEquipmentBaseClass- Returns:
- a
MechanicalDesignobject
-
findMercuryIndex
Find the index of elemental mercury in the thermodynamic system.- Parameters:
sys- the thermodynamic system
-
effectiveRateConstant
private double effectiveRateConstant(double temperatureK) Calculate the temperature-corrected effective rate constant using an Arrhenius relation.- Parameters:
temperatureK- temperature in Kelvin- Returns:
- effective rate constant (1/s)
-
calcInletHgConcentration
Calculate the inlet mercury concentration in microgram/Nm3.- Parameters:
sys- the thermodynamic system with mercury present- Returns:
- inlet Hg concentration in microgram/Nm3
-
setOutletMercuryFromConcentration
private void setOutletMercuryFromConcentration(SystemInterface sys, double outletConc, double inletConc) Set the outlet mercury content by scaling the inlet mole fraction.- Parameters:
sys- the working thermodynamic system to modifyoutletConc- outlet Hg concentration (microgram/Nm3)inletConc- inlet Hg concentration (microgram/Nm3)
-
calcErgunPressureDrop
Calculate pressure drop across the packed bed using the Ergun equation.- Parameters:
sys- the thermodynamic system for fluid propertiesus- superficial velocity (m/s)- Returns:
- total pressure drop (Pa)
-
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)
-
getSorbentType
-
setSorbentType
Set the sorbent type name (e.g. "PuraSpec", "MRU-CuS").- Parameters:
sorbentType- sorbent type
-
getSorbentBulkDensity
public double getSorbentBulkDensity()Get the sorbent bulk density.- Returns:
- bulk density in kg/m3
-
setSorbentBulkDensity
public void setSorbentBulkDensity(double density) Set the sorbent 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 sorbent particle diameter.- Parameters:
diameter- particle diameter in metres
-
getMaxMercuryCapacity
public double getMaxMercuryCapacity()Get the maximum mercury loading capacity.- Returns:
- maximum capacity in mg Hg / kg sorbent
-
setMaxMercuryCapacity
public void setMaxMercuryCapacity(double capacity) Set the maximum mercury loading capacity of the sorbent.- Parameters:
capacity- maximum capacity in mg Hg / kg sorbent (typical PuraSpec: 100 000)
-
getReactionRateConstant
public double getReactionRateConstant()Get the chemisorption reaction rate constant.- Returns:
- rate constant in 1/s
-
setReactionRateConstant
public void setReactionRateConstant(double k) Set the chemisorption reaction rate constant.- Parameters:
k- rate constant in 1/s
-
getReplacementUtilisation
public double getReplacementUtilisation()Get the practical replacement utilisation factor.- Returns:
- replacement utilisation (0 to 1)
-
setReplacementUtilisation
public void setReplacementUtilisation(double utilisation) Set the practical replacement utilisation factor. This is the fraction of theoretical sorbent capacity that can be used before the bed must be replaced. Typical 0.4–0.6 for single beds, 0.7–0.9 for lead–lag.- Parameters:
utilisation- replacement utilisation factor (0 to 1)
-
getActivationEnergy
public double getActivationEnergy()Get the activation energy.- Returns:
- activation energy in J/mol
-
setActivationEnergy
public void setActivationEnergy(double energy) Set the activation energy for the chemisorption reaction.- Parameters:
energy- activation energy in J/mol
-
getDegradationFactor
public double getDegradationFactor()Get the degradation factor.- Returns:
- degradation factor (0 to 1)
-
setDegradationFactor
public void setDegradationFactor(double factor) Set the degradation factor for column internals or sorbent fouling.A value of 1.0 means brand-new / undegraded bed. Lower values reduce both the effective capacity and the reaction rate to simulate fouling, liquid carry-over, or damaged internals.
- Parameters:
factor- degradation factor (0 to 1)
-
getBypassFraction
public double getBypassFraction()Get the bypass fraction.- Returns:
- bypass fraction (0 to 1)
-
setBypassFraction
public void setBypassFraction(double fraction) Set the bypass fraction to model channelling due to degraded internals.- Parameters:
fraction- bypass fraction (0 to <1)
-
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 discretisation.- Parameters:
cells- number of cells (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 skip
-
getElapsedTimeHours
public double getElapsedTimeHours()Get the elapsed on-stream time in hours.- Returns:
- elapsed time in hours
-
isBreakthroughOccurred
public boolean isBreakthroughOccurred()Check if mercury breakthrough has occurred.- Returns:
- true if breakthrough detected
-
getBreakthroughTimeHours
public double getBreakthroughTimeHours()Get the breakthrough time.- Returns:
- breakthrough time in hours, or -1 if not yet occurred
-
setBreakthroughThreshold
public void setBreakthroughThreshold(double threshold) Set the breakthrough detection threshold.- Parameters:
threshold- outlet/inlet Hg concentration ratio (0 to 1)
-
setReferenceTemperature
public void setReferenceTemperature(double temperature) Set the reference temperature for the Arrhenius rate constant.- Parameters:
temperature- reference temperature in Kelvin
-
getReferenceTemperature
public double getReferenceTemperature()Get the reference temperature for the Arrhenius rate constant.- Returns:
- reference temperature in Kelvin
-