Absorbers and Strippers
Documentation for mass transfer columns in NeqSim.
Table of Contents
Overview
Location: neqsim.process.equipment.absorber
Classes:
| Class | Description |
| ———————– | —————————————————– |
| Absorber | General absorption column |
| SimpleAbsorber | Simplified absorber model (base class) |
| SimpleTEGAbsorber | TEG dehydration with Fs-factor sizing |
| SimpleAmineAbsorber | Amine gas sweetening (MDEA, DEA, MEA) |
| WaterStripperColumn | Water stripping column |
Absorbers transfer components from gas to liquid phase, while strippers transfer from liquid to gas.
Absorber
Basic Usage
import neqsim.process.equipment.absorber.Absorber;
Absorber absorber = new Absorber("Amine Absorber");
absorber.addGasInStream(gasStream);
absorber.addSolventInStream(amineSolution);
absorber.setNumberOfTheoreticalStages(10);
absorber.run();
Stream sweetGas = absorber.getGasOutStream();
Stream richAmine = absorber.getLiquidOutStream();
Absorption Efficiency
// Component removal efficiency
absorber.setRemovalEfficiency("CO2", 0.95); // 95% CO2 removal
absorber.setRemovalEfficiency("H2S", 0.99); // 99% H2S removal
Stage Configuration
absorber.setNumberOfTheoreticalStages(20);
absorber.setStageEfficiency(0.7); // Murphree efficiency
Stripper
Basic Usage
import neqsim.process.equipment.absorber.WaterStripperColumn;
WaterStripperColumn stripper = new WaterStripperColumn("Regenerator");
stripper.setLiquidInStream(richAmine);
stripper.setNumberOfStages(15);
stripper.setReboilerTemperature(120.0, "C");
stripper.run();
Stream leanAmine = stripper.getLiquidOutStream();
Stream acidGas = stripper.getGasOutStream();
Simple Absorber
Simplified mass transfer model.
Usage
import neqsim.process.equipment.absorber.SimpleAbsorber;
SimpleAbsorber absorber = new SimpleAbsorber("CO2 Absorber");
absorber.addGasInStream(feedGas);
absorber.addSolventInStream(solvent);
absorber.setAbsorptionEfficiency(0.90);
absorber.run();
Fs-Factor and Wetting Rate
The base SimpleAbsorber class provides Fs-factor and wetting rate calculations used by all absorber subclasses:
where $v_s$ is the superficial gas velocity (m/s) and $\rho_g$ is gas density (kg/m3).
The wetting rate is the liquid volume flowing per unit packing area:
\[WR = \frac{Q_L}{\pi / 4 \cdot D^2}\]Simple TEG Absorber
SimpleTEGAbsorber extends the base absorber with TEG-specific sizing via the Kremser equation and Fs-factor capacity checking.
Fs-Factor Sizing
The Fs-factor determines whether the contactor diameter is adequate for the gas load. Industry practice limits Fs to approximately 2.5-3.5 (Pa)^0.5 for structured packing:
import neqsim.process.equipment.absorber.SimpleTEGAbsorber;
SimpleTEGAbsorber tegAbsorber = new SimpleTEGAbsorber("TEG Contactor");
tegAbsorber.addGasInStream(wetGasStream);
tegAbsorber.addSolventInStream(leanTEGStream);
tegAbsorber.run();
// Fs-factor capacity check
double fs = tegAbsorber.getFsFactor();
double maxFs = tegAbsorber.getMaxAllowableFsFactor(); // default 3.0
boolean withinLimit = tegAbsorber.isFsFactorWithinDesignLimit();
double utilization = tegAbsorber.getFsFactorUtilization(); // fs / maxFs
// Minimum diameter needed
double minDiameter = tegAbsorber.getMinimumDiameterForFsLimit();
// Full validation report
String report = tegAbsorber.validateContactorDesign();
System.out.println(report);
TEG Quality and Water Dew Point
// Check equilibrium water dew point from TEG purity
double dewPointC = tegAbsorber.getLeanTEGEquilibriumWaterDewPoint(99.5);
System.out.println("Water dew point at 99.5 wt% TEG: " + dewPointC + " °C");
// Check if TEG quality margin is adequate
boolean adequate = tegAbsorber.hasAdequateTEGQualityMargin(99.5, -18.0);
Key Methods
| Method | Description |
|---|---|
getFsFactor() |
Current Fs-factor from gas outlet stream |
getMaxAllowableFsFactor() |
Design limit (default 3.0) |
setMaxAllowableFsFactor(double) |
Override design limit |
isFsFactorWithinDesignLimit() |
Check if Fs is below limit |
getFsFactorUtilization() |
Fraction of capacity used (0-1) |
getMinimumDiameterForFsLimit() |
Minimum diameter at current gas load |
getLeanTEGEquilibriumWaterDewPoint(double) |
Water dew point for a TEG purity |
hasAdequateTEGQualityMargin(double, double) |
TEG purity vs target dew point |
validateContactorDesign() |
Full text validation report |
Simple Amine Absorber
SimpleAmineAbsorber models amine-based gas sweetening for CO2 and H2S removal. It calculates acid gas removal by applying user-specified removal efficiencies, and includes design calculations for column sizing, loading, and validation.
Basic Usage
import neqsim.process.equipment.absorber.SimpleAmineAbsorber;
import neqsim.process.equipment.stream.Stream;
import neqsim.process.processmodel.ProcessSystem;
import neqsim.thermo.system.SystemSrkEos;
// Create sour gas
SystemSrkEos sourGas = new SystemSrkEos(273.15 + 40.0, 70.0);
sourGas.addComponent("methane", 0.85);
sourGas.addComponent("CO2", 0.10);
sourGas.addComponent("H2S", 0.005);
sourGas.addComponent("ethane", 0.045);
sourGas.setMixingRule("classic");
Stream sourGasStream = new Stream("Sour Gas", sourGas);
sourGasStream.setFlowRate(50000.0, "kg/hr");
// Create amine absorber
SimpleAmineAbsorber absorber = new SimpleAmineAbsorber("MDEA Absorber", sourGasStream);
absorber.setAmineType("MDEA");
absorber.setAmineConcentrationWtPct(50.0);
absorber.setCO2RemovalEfficiency(0.95);
absorber.setH2SRemovalEfficiency(0.99);
// Wire into process
ProcessSystem process = new ProcessSystem();
process.add(sourGasStream);
process.add(absorber);
process.run();
// Get treated gas
Stream sweetGas = (Stream) absorber.getSweetGasOutStream();
With Lean Amine Stream
When a lean amine stream is provided, the absorber also calculates the rich amine outlet (acid gas picked up by the solvent):
// Lean amine
SystemSrkEos amineFluid = new SystemSrkEos(273.15 + 42.0, 70.0);
amineFluid.addComponent("MDEA", 0.50);
amineFluid.addComponent("water", 0.50);
amineFluid.setMixingRule("classic");
Stream leanAmine = new Stream("Lean Amine", amineFluid);
leanAmine.setFlowRate(30000.0, "kg/hr");
absorber.setLeanAmineInStream(leanAmine);
process.add(leanAmine);
process.run();
// Rich amine with absorbed acid gas
Stream richAmine = (Stream) absorber.getRichAmineOutStream();
Design Calculations
// Acid gas loading
absorber.setLeanAmineLoading(0.01);
absorber.setApproachToEquilibrium(0.70);
double richLoading = absorber.calcRichAmineLoading(0.50);
// richLoading = 0.01 + (0.50 - 0.01) * 0.70 = 0.353 mol/mol
// Amine circulation rate
double rate = absorber.calcRequiredCirculationRate(
10.0, // mol/s acid gas to remove
1050.0, // kg/m3 amine density
0.119 // kg/mol MDEA molar mass
);
// Packing height with redistribution sections
absorber.setMaxPackingHeightPerSection(5.5);
absorber.calcPackingHeight(1.0, 12.0); // HTU=1.0m, NTU=12
int sections = absorber.getNumberOfPackingSections(); // 3
// Demister K-factor
double kFactor = absorber.calcDemisterKFactor(2.0, 50.0, 1050.0);
boolean withinLimit = absorber.isDemisterWithinLimit(); // K <= 0.08
// Temperature margin check
boolean tempOk = absorber.checkAmineTemperatureMargin(30.0, 37.0); // need 6°C margin
// Foaming derating
double effectiveFlow = absorber.getEffectiveGasCapacityWithFoamingMargin(100.0); // 120.0
Design Validation
// Run all design checks at once
Map<String, SimpleAmineAbsorber.DesignCheck> checks = absorber.validateDesign();
for (Map.Entry<String, SimpleAmineAbsorber.DesignCheck> entry : checks.entrySet()) {
System.out.println(entry.getKey() + ": " +
(entry.getValue().isPassed() ? "PASS" : "FAIL") +
" - " + entry.getValue().getDetail());
}
// Get full design summary
System.out.println(absorber.getDesignSummary());
Design Parameters
| Parameter | Default | Description |
|---|---|---|
| Amine type | MDEA | Amine solvent (MDEA, DEA, MEA) |
| Concentration | 50 wt% | Amine weight percent in lean solvent |
| CO2 removal | 90% | Overall CO2 removal efficiency |
| H2S removal | 99% | Overall H2S removal efficiency |
| Foaming margin | 20% | Capacity derating for foaming |
| Max packing height | 5.5 m | Maximum per section before redistribution |
| Amine temperature margin | 6 °C | Lean amine T above gas feed T |
| Gas carry-under | 0.03 | Am3 gas per Am3 amine |
| Demister K-factor limit | 0.08 m/s | Wire mesh at gas outlet |
| Approach to equilibrium | 70% | Fraction of thermodynamic equilibrium loading |
Examples
Example 1: Amine Gas Treating
import neqsim.thermo.system.SystemSrkCPAstatoil;
import neqsim.process.equipment.stream.Stream;
import neqsim.process.equipment.absorber.Absorber;
// Sour gas
SystemSrkCPAstatoil sourGas = new SystemSrkCPAstatoil(313.15, 70.0);
sourGas.addComponent("methane", 0.85);
sourGas.addComponent("CO2", 0.10);
sourGas.addComponent("H2S", 0.01);
sourGas.addComponent("water", 0.04);
sourGas.setMixingRule("classic");
Stream gasIn = new Stream("Sour Gas", sourGas);
gasIn.setFlowRate(100000.0, "Sm3/hr");
gasIn.run();
// Lean amine (MDEA solution)
SystemSrkCPAstatoil amine = new SystemSrkCPAstatoil(313.15, 70.0);
amine.addComponent("water", 0.50);
amine.addComponent("MDEA", 0.50);
amine.setMixingRule("classic");
Stream leanAmine = new Stream("Lean Amine", amine);
leanAmine.setFlowRate(50000.0, "kg/hr");
leanAmine.run();
// Absorber
Absorber absorber = new Absorber("Amine Contactor");
absorber.addGasInStream(gasIn);
absorber.addSolventInStream(leanAmine);
absorber.setNumberOfTheoreticalStages(15);
absorber.run();
// Results
Stream sweetGas = absorber.getGasOutStream();
double co2Out = sweetGas.getFluid().getMoleFraction("CO2") * 1e6; // ppm
System.out.println("Sweet gas CO2: " + co2Out + " ppm");
Example 2: TEG Dehydration
// Wet natural gas
SystemSrkEos wetGas = new SystemSrkEos(303.15, 70.0);
wetGas.addComponent("methane", 0.90);
wetGas.addComponent("ethane", 0.05);
wetGas.addComponent("propane", 0.03);
wetGas.addComponent("water", 0.02);
wetGas.setMixingRule("classic");
Stream gasIn = new Stream("Wet Gas", wetGas);
gasIn.setFlowRate(5000000.0, "Sm3/day");
gasIn.run();
// Lean TEG
SystemSrkEos teg = new SystemSrkEos(313.15, 70.0);
teg.addComponent("TEG", 0.99);
teg.addComponent("water", 0.01);
teg.setMixingRule("classic");
Stream leanTEG = new Stream("Lean TEG", teg);
leanTEG.setFlowRate(1000.0, "kg/hr");
leanTEG.run();
// Contactor
Absorber contactor = new Absorber("TEG Contactor");
contactor.addGasInStream(gasIn);
contactor.addSolventInStream(leanTEG);
contactor.setNumberOfTheoreticalStages(3);
contactor.run();
Stream dryGas = contactor.getGasOutStream();
double waterContent = dryGas.getFluid().getMoleFraction("water") * 1e6;
System.out.println("Dry gas water content: " + waterContent + " ppm");
Example 3: Water Wash Column
// Gas with methanol
SystemSrkEos gas = new SystemSrkEos(280.0, 50.0);
gas.addComponent("methane", 0.95);
gas.addComponent("methanol", 0.03);
gas.addComponent("water", 0.02);
gas.setMixingRule("classic");
Stream gasIn = new Stream("Gas", gas);
gasIn.setFlowRate(10000.0, "kg/hr");
gasIn.run();
// Wash water
SystemSrkEos water = new SystemSrkEos(290.0, 50.0);
water.addComponent("water", 1.0);
water.setMixingRule("classic");
Stream washWater = new Stream("Wash Water", water);
washWater.setFlowRate(500.0, "kg/hr");
washWater.run();
// Absorber
SimpleAbsorber waterWash = new SimpleAbsorber("Water Wash");
waterWash.addGasInStream(gasIn);
waterWash.addSolventInStream(washWater);
waterWash.setAbsorptionEfficiency(0.85);
waterWash.run();
Stream cleanGas = waterWash.getGasOutStream();
double meohRemaining = cleanGas.getFluid().getMoleFraction("methanol") * 100;
System.out.println("Methanol in clean gas: " + meohRemaining + " mol%");
Related Documentation
- Equipment Index - All equipment
- Water Treatment - Hydrocyclones and gas flotation units
- Distillation - Distillation columns
- Separators - Phase separation
- H2S Scavenger Guide - Chemical scavenging of H2S