agentleFS
equinorequinor/neqsim/.github/skills/neqsim-acid-gas-treating/SKILL.md

neqsim-acid-gas-treating

Skill167 starsChanged 7 months agoApache-2.0View on GitHub

Guides NeqSim agents through acid-gas and contaminant removal with SimpleAmineAbsorber, SimpleAmineRegenerator, SystemKentEisenberg, SystemDesmukhMather, RateBasedAbsorber, MembraneSeparator, and PressureSwingAdsorptionBed. USE WHEN: screening CO2/H2S sweetening, setting up amine absorption and regeneration, comparing reactive amine thermodynamics, estimating H2S scavenger demand, or comparing membrane, adsorption, and staged-column alternatives.

The file

We split this skill into the rules it gives an agent

3 rules. About 0 are common, 2 are distinctive, and 1 is very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈2

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 1

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Verify component balances, acid-gas loading, H2 purity/recovery, and absorber/regenerator outputs.

    line 16
  2. Very specific:

    Use K and bara in thermo constructors.

    line 202
  3. Distinctive:

    Call it and fix errors before running the bed.

    line 213

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Acid-Gas Treating with NeqSim

When to use this

  • Build a screening acid-gas absorber/regenerator using the SimpleAmine* equipment.
  • Evaluate CO2/H2S phase equilibrium with Kent-Eisenberg or Desmukh-Mather systems.
  • Compare packed-column transfer calculations, equilibrium-stage columns, and shortcut absorbers.
  • Screen an H2S scavenger injection rate or a membrane/PSA component-removal alternative.
  • Inspect an adsorption bed, PSA cascade, or cyclic adsorption controller.
  • Verify component balances, acid-gas loading, H2 purity/recovery, and absorber/regenerator outputs.

The equipment names do not all imply the same fidelity. SimpleAmineAbsorber applies configured removal efficiencies and transfers removed acid gas to a cloned solvent stream; it is not a reactive amine equilibrium or mass-transfer solver. SimpleAmineRegenerator uses simplified loading and duty balances. RateBasedAbsorber has Onda and Billet-Schultes transfer correlations, but requires credible packing, fluid, and calibration inputs. MembraneSeparator and PressureSwingAdsorptionBed are simplified separation models. Use AbsorptionColumn/StrippingColumn or reactive thermo systems when their different physical basis fits the question, and state remaining validation gaps.

Class map

ClassPackageWhat it doesVerified key setters/getters
SimpleAmineAbsorberneqsim.process.equipment.absorberEfficiency-based CO2/H2S removal and solvent loading estimatesetLeanAmineInStream(StreamInterface), setCO2RemovalEfficiency(double), getSweetGasOutStream(), getRichAmineLoading()
SimpleAmineRegeneratorsameSimplified rich-solvent stripping and duty estimatesetRichAmineInStream(StreamInterface), setLeanLoadingTarget(double), getLeanLoading(), getReboilerDutyKW()
AbsorptionColumnsameTray/stage absorber based on DistillationColumnAbsorptionColumn(String,int), addGasInStream(StreamInterface), addSolventInStream(StreamInterface), getGasLoadFactor()
StrippingColumnsameStaged stripping columnStrippingColumn(String,int), addStrippingGasStream(StreamInterface), addRichLiquidStream(StreamInterface), getOverheadGasStream()
RateBasedAbsorbersamePacked-column rate-transfer modelsetColumnDiameter(double), setPackedHeight(double), setMassTransferModel(MassTransferModel), getHeightOfTransferUnit()
H2SScavengersameEmpirical scavenger performance/injection screensetScavengerType(ScavengerType), setScavengerInjectionRate(double,String), calculateRequiredInjectionRate()
SimpleTEGAbsorbersameGas dehydration contactoraddGasInStream(StreamInterface), addSolventInStream(StreamInterface), getGasOutStream(), getSolventOutStream()
WaterStripperColumnsameWater-stripping contactor/columnaddGasInStream(StreamInterface), addSolventInStream(StreamInterface), getGasOutStream(), getWaterDewPointTemperature()
SimpleAbsorbersameShortcut absorber base with convergence diagnosticssetNumberOfTheoreticalStages(double), getLastRunExitReason(), getOutletStream(int)
SystemKentEisenbergneqsim.thermo.systemSRK gas/oil plus Kent-Eisenberg aqueous amine/electrolyte phaseSystemKentEisenberg(double,double), setMixingRule(4), chemicalReactionInit()
SystemDesmukhMathersameSRK gas/oil plus Desmukh-Mather aqueous amine/electrolyte phaseSystemDesmukhMather(double,double), chemicalReactionInit(), createDatabase(true)
MembraneSeparatorneqsim.process.equipment.membranePer-component permeate split or simplified permeability calculationsetPermeateFraction(String,double), setPermeability(String,double), permeate/retentate getters
PressureSwingAdsorptionBedneqsim.process.equipment.adsorberEquilibrium-NTU adsorption with H2 recovery targetsetSorbent(SorbentType), setRecoveryTarget(double), getH2Purity(), getH2Recovery()
PSACascadesamePSA cascade with configurable equalisation/recovery upliftsetConfiguration(CascadeConfiguration), setCycleTime(double), getH2Purity(), getTailGasStream()
AdsorptionBedsameIsotherm/LDF adsorption bed with spatial and transient stategeometry/material setters, getAverageLoading(int), getBedUtilization(int), validateSetup()
SimpleAdsorbersameShortcut stage-efficiency absorber/adsorber basesetAproachToEquilibrium(double), setNumberOfStages(int), getOutletStream(int)
AdsorptionCycleControllersameSchedules adsorption-bed cycle phasesAdsorptionCycleController(AdsorptionBed), addStep(PhaseStep), setAutoLoop(boolean), getCurrentPhase()

The test suite did not demonstrate an amine setup using SystemElectrolyteCPAstatoil; do not describe that system as the validated amine route based on these sources. The verified amine thermo paths are SystemKentEisenberg and SystemDesmukhMather.

Build pattern

This minimal case follows the amine absorber/regenerator test pattern. It runs the equipment sequentially; it does not close a lean-solvent circulation loop.

import neqsim.process.equipment.absorber.SimpleAmineAbsorber;
import neqsim.process.equipment.absorber.SimpleAmineRegenerator;
import neqsim.process.equipment.stream.Stream;
import neqsim.thermo.system.SystemInterface;
import neqsim.thermo.system.SystemSrkEos;

SystemInterface gasFluid = new SystemSrkEos(313.15, 2.0);
gasFluid.addComponent("methane", 0.90);
gasFluid.addComponent("CO2", 0.08);
gasFluid.addComponent("H2S", 0.02);
gasFluid.setMixingRule("classic");
Stream sourGas = new Stream("sour gas", gasFluid);
sourGas.setFlowRate(10000.0, "kg/hr");
sourGas.run();

SystemInterface amineFluid = new SystemSrkEos(318.15, 2.0);
amineFluid.addComponent("CO2", 0.009);
amineFluid.addComponent("H2S", 0.001);
amineFluid.addComponent("water", 0.80);
amineFluid.addComponent("MDEA", 0.19);
amineFluid.setMixingRule("classic");
Stream leanAmine = new Stream("lean amine", amineFluid);
leanAmine.setFlowRate(60000.0, "kg/hr");
leanAmine.run();

SimpleAmineAbsorber absorber = new SimpleAmineAbsorber("amine absorber", sourGas);
absorber.setLeanAmineInStream(leanAmine);
absorber.setAmineType("MDEA");
absorber.setCO2RemovalEfficiency(0.90);
absorber.setH2SRemovalEfficiency(0.99);
absorber.run();

SimpleAmineRegenerator regenerator = new SimpleAmineRegenerator("amine regenerator",
    absorber.getRichAmineOutStream());
regenerator.setAmineType("MDEA");
regenerator.setReboilerTemperatureC(120.0);
regenerator.setLeanLoadingTarget(0.01);
regenerator.setRegenerationEfficiency(0.95);
regenerator.run();
double reboilerDutyKW = regenerator.getReboilerDutyKW();

Equivalent Python class lookup pattern:

from neqsim import jneqsim

SystemSrkEos = jneqsim.thermo.system.SystemSrkEos
Stream = jneqsim.process.equipment.stream.Stream
SimpleAmineAbsorber = jneqsim.process.equipment.absorber.SimpleAmineAbsorber
SimpleAmineRegenerator = jneqsim.process.equipment.absorber.SimpleAmineRegenerator

gas = SystemSrkEos(313.15, 2.0)
for component, amount in (("methane", 0.90), ("CO2", 0.08), ("H2S", 0.02)):
    gas.addComponent(component, amount)
gas.setMixingRule("classic")
sour_gas = Stream("sour gas", gas)
sour_gas.setFlowRate(10000.0, "kg/hr")
sour_gas.run()

solvent = SystemSrkEos(318.15, 2.0)
for component, amount in (("CO2", 0.009), ("H2S", 0.001), ("water", 0.80), ("MDEA", 0.19)):
    solvent.addComponent(component, amount)
solvent.setMixingRule("classic")
lean = Stream("lean amine", solvent)
lean.setFlowRate(60000.0, "kg/hr")
lean.run()

absorber = SimpleAmineAbsorber("amine absorber", sour_gas)
absorber.setLeanAmineInStream(lean)
absorber.setAmineType("MDEA")
absorber.setCO2RemovalEfficiency(0.90)
absorber.setH2SRemovalEfficiency(0.99)
absorber.run()
regenerator = SimpleAmineRegenerator("amine regenerator", absorber.getRichAmineOutStream())
regenerator.setAmineType("MDEA")
regenerator.setReboilerTemperatureC(120.0)
regenerator.setLeanLoadingTarget(0.01)
regenerator.setRegenerationEfficiency(0.95)
regenerator.run()
reboiler_duty_kw = regenerator.getReboilerDutyKW()

For a reactive thermodynamic flash, use the tested system-specific setup rather than the shortcut absorber. Kent-Eisenberg test setup uses numeric mixing rule 4; the reactive Desmukh-Mather test calls chemicalReactionInit(), createDatabase(true), then setMixingRule("classic") before TP flash. SystemElectrolyteCPAstatoil examples in this test area concern electrolyte/CPA cases, not an amine-sweetening validation case.

Membrane and PSA starting points:

MembraneSeparator membrane = new MembraneSeparator("CO2 membrane", sourGas);
membrane.setPermeateFraction("CO2", 0.5);
membrane.setDefaultPermeateFraction(0.1);
membrane.run();

PressureSwingAdsorptionBed psa = new PressureSwingAdsorptionBed("H2 PSA", shiftedSyngas);
psa.setRecoveryTarget(0.85);
psa.run();

Result extraction

ResultExact getterUnits / interpretation
Sweet gas / rich solventgetSweetGasOutStream() / getRichAmineOutStream()Stream objects; inspect per-component rates and compositions
Absorber rich loadinggetRichAmineLoading()mol acid gas/mol amine; loading calculation is simplified
Required solvent flowgetRequiredCirculationRate()m3/h
Required packed heightgetRequiredPackingHeight()m
Design checksvalidateDesign()Map of check keys to DesignCheck; not an external code certification
Regenerator loadinggetRichLoading() / getLeanLoading()mol CO2/mol amine
Regenerator dutygetReboilerDutyKW()kW; components also available by desorption/sensible/steam contribution
Specific dutygetSpecificReboilerDutyMJperKgCO2()MJ/kg CO2 stripped
Rate-based transfergetOverallKGa(), getOverallKLa()1/s; getHeightOfTransferUnit() is m and NTU is dimensionless
ScavengergetH2SRemovalEfficiency(), getH2SRemoved("kg/hr")Fraction and kg/h; injection getter accepts supported unit strings
MembranegetPermeateStream(), getRetentateStream()Streams; compare component molar rates and total feed/outlet flow
PSAgetH2Purity(), getH2Recovery()Mole fraction and dimensionless fraction; tail-gas vector in mol/s
Adsorption bedgetAverageLoading(int), getBedUtilization(int), getMassTransferZoneLength(int)Component-indexed bed outputs; check class docs for each output basis

Gotchas

  • SimpleAmineAbsorber is efficiency-based bookkeeping. The configured amine type, weight percent, loadings, and circulation/packing calculations do not turn it into a reactive equilibrium model.
  • The simple absorber adds captured CO2/H2S to the lean-solvent clone only if that component already exists in the solvent system. Include the acid-gas components (trace if needed) in the lean solvent or the absorber-side material balance will not include those captured moles. The absorber now logs a warning when removed CO2/H2S has no matching component in the lean solvent.
  • SimpleAmineRegenerator reports CO2 loading and duty; it removes H2S separately. Do not read its CO2 loading as total acid-gas loading. Duty getters remain zero when no CO2 is stripped or no positive molar flow is present.
  • For a real lean/rich recycle, use a pressure let-down, cooler, pump, and Recycle/converged flowsheet. Check recycle convergence and make a component-wise balance; a sequential example is not a closed-loop process model.
  • Flash exceptions in the simple amine equipment are logged and caught. A populated output stream can therefore exist after a failed flash; check phase/composition results and finite properties.
  • RateBasedAbsorberTest allows KGa, KLa, wetted area, and HTU to be zero. Treat zero, NaN, or non-finite transfer metrics as an unusable calculation, not a successful separation.
  • MembraneSeparator defaults component permeate fractions to zero. Its permeability option uses permeability * area * feed partial pressure, capped at available component moles; it is a simplified split calculation, not a pressure-driven multi-stage membrane design.
  • PressureSwingAdsorptionBed recovery target is enforced by venting excess product hydrogen to tail gas; it is not the result of simulating industrial cycle sequencing. Use PSACascade or AdsorptionCycleController for the corresponding simplified cycle abstractions.
  • Use K and bara in thermo constructors. SimpleAmineRegenerator.setReboilerTemperatureC(double) takes Celsius; column geometry uses m; scavenger contact time uses seconds; PSA tail flows are mol/s. Use explicit stream flow units.
  • Set the mixing rule before a flash. The tested SystemSrkEos workflows use "classic"; the Kent-Eisenberg test uses numeric 4. The tested reactive Desmukh-Mather workflow order is chemicalReactionInit(), createDatabase(true), then setMixingRule("classic"), TP flash, and initProperties() before transport-property reads. Numeric CPA rule 10 belongs to CPA model workflows; no amine validation test here uses SystemElectrolyteCPAstatoil.
  • AdsorptionBed.validateSetup() reports required geometry/material errors with remediation, e.g. “Bed diameter must be positive” / “Set bed diameter: setBedDiameter(value)” and “Adsorbent material not specified” / “Set adsorbent material: setAdsorbentMaterial(name)”. Call it and fix errors before running the bed.
  • SimpleAbsorber exposes the legacy spelling setAproachToEquilibrium(double); the amine-specific class instead exposes setApproachToEquilibrium(double).

Validation / benchmarks

  • Require sweet-gas acid-gas component fractions/rates below their sour-feed values and verify the captured material appears in rich solvent or the selected removal stream.
  • For a regenerator, require rich loading at least lean loading, positive CO2 in acid-gas overhead, and positive finite duty when CO2 is stripped. Use the duty model as an estimate, not a vendor energy guarantee.
  • Amine loading is mol acid gas/mol amine. Rich loading must exceed lean loading; numeric targets vary with solvent, circulation, pressure, temperature, and feed composition. Compare against measured PVT/plant data or a documented design basis. Reference: Kohl & Nielsen, Gas Purification.
  • The PSA unit documents a typical industrial H2 recovery target range of 0.75-0.90 depending on equalisation steps. Its test uses a 0.85 target, checks purity above 0.85, recovery in 0.80-0.85, and total feed = product + tail gas within 1%. These are model regression checks, not proof of a specific vendor skid rating.
  • For a membrane, verify total molar balance and the intended permeate/retentate enrichment; a set fraction is the assumed selectivity, not evidence of measured membrane performance.
  • AbsorptionColumnTest checks convergence, component balance, and effect of reduced Murphree efficiency. RateBasedAbsorberTest only requires non-negative transfer metrics; add positive, finite-value checks and independent validation for engineering use.
  • References for process context: GPSA Engineering Data Book, Gas Purification (Kohl & Nielsen), and the relevant solvent, packing, membrane, or adsorbent vendor data. No clause-level compliance claim is made here.

Related skills

  • neqsim-process-modeling — connect treating equipment, utilities, recycle, and downstream units.
  • neqsim-teg-dehydration-modeling — validated TEG dehydration flowsheet and regeneration loop.
  • neqsim-hydrogen-production — PSA purification and hydrogen-chain context.
  • neqsim-reaction-engineering — reaction and equilibrium-model selection.
  • neqsim-api-patterns — fluid setup, mixing rules, units, and property initialization.
  • neqsim-input-validation — component, phase, and operating-condition screening.
  • neqsim-troubleshooting — flash, column, and recycle diagnosis.
  • neqsim-standards-lookup — standards identification and clause-to-method traceability.
  • neqsim-professional-reporting — report assumptions, evidence, and limitations.
  • neqsim-sulfur-recovery — route recovered Claus acid gas to sulfur recovery and tail-gas handling.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.