Source profileQuality 97/100

equinor/neqsim/.github/skills/neqsim-distillation-design/SKILL.md

neqsim-distillation-design

Distillation column design rules for NeqSim. USE WHEN: setting up distillation columns, troubleshooting convergence, selecting internals (trays/packing), sizing columns, or analyzing column performance. Covers DistillationColumn setup, solver selection, feed tray optimization, reflux ratio, and internals selection per industry standards.

Source repository stars
136
Declared platforms
0
Static risk flags
0
Last source update
2026-08-05
Source checked
2026-08-05

Decision brief

What it does—and where it fits

Guide for distillation column modeling and design in NeqSim.

Best for

  • USE WHEN: setting up distillation columns, troubleshooting convergence, selecting internals (trays/packing), sizing columns, or analyzing column performance.

Not for

  • Start with fewer stages (5-8) and get convergence
  • Gradually increase stages

Compatibility matrix

Platform support, with evidence labels

PlatformStatusEvidenceWhat to check
CodexNot declaredNo explicit evidencePortability before use
Claude CodeNot declaredNo explicit evidencePortability before use
CursorNot declaredNo explicit evidencePortability before use
Gemini CLINot declaredNo explicit evidencePortability before use
Open the compatibility checker

Installation

Inspect first. Install second.

The source command is displayed only when detected. A safe inspection prompt is always available so your agent can explain every action before execution.

Source-detected install commandSource
npx skills add https://github.com/equinor/neqsim --skill ".github/skills/neqsim-distillation-design"
Safe inspection promptEditorial

Inspect the Agent Skill "neqsim-distillation-design" from https://github.com/equinor/neqsim/blob/9e8d44a141bba600026d2229969b49af50f34237/.github/skills/neqsim-distillation-design/SKILL.md at commit 9e8d44a141bba600026d2229969b49af50f34237. List every install step, command, network request, credential, file read/write, external action, and rollback step. Explain whether it fits my task. Do not install or execute anything until I approve.

Workflow

What the source asks the agent to do

  1. 01

    Column Setup Pattern

    Review the “Column Setup Pattern” section in the pinned source before continuing.

    Review and apply the “Column Setup Pattern” source section.
  2. 02

    Solver Selection

    Three knobs decide how long a column runs before it gives up. Getting them wrong is the usual cause of a column that burns minutes per solve inside a ProcessModel outer loop.

    Three knobs decide how long a column runs before it gives up. Getting them wrong is the usual cause of a column that burns minutes per solve inside a ProcessModel outer loop.Rule of thumb for a column inside a multi-area ProcessModel: set a hard iteration cap, damp below 0.5 if the tray temperatures oscillate, and match the column tolerance to the model tolerance passed to ProcessModel.runU…solved() is not a single residual. It requires the solve status to be RIGOROUSCONVERGED or RECONCILEDPRODUCTS and every active residual gate to pass:
  3. 03

    Runtime control: iteration budget, damping and tolerance

    Three knobs decide how long a column runs before it gives up. Getting them wrong is the usual cause of a column that burns minutes per solve inside a ProcessModel outer loop.

    Three knobs decide how long a column runs before it gives up. Getting them wrong is the usual cause of a column that burns minutes per solve inside a ProcessModel outer loop.Rule of thumb for a column inside a multi-area ProcessModel: set a hard iteration cap, damp below 0.5 if the tray temperatures oscillate, and match the column tolerance to the model tolerance passed to ProcessModel.runU…
  4. 04

    What solved() actually checks

    solved() is not a single residual. It requires the solve status to be RIGOROUSCONVERGED or RECONCILEDPRODUCTS and every active residual gate to pass:

    solved() is not a single residual. It requires the solve status to be RIGOROUSCONVERGED or RECONCILEDPRODUCTS and every active residual gate to pass:The overall feed/product balance closing to machine precision does not mean the column solved: each tray must close its own component balance too. Read per-tray material imbalance in getConvergenceDiagnostics() before t…Do not gate on the MESH material: infinity norm. Those entries scale each component by its own throughput, so a trace component going from 1e-25 to 1.2e-25 mol/hr reads as a 0.17 residual. Use getLastTrayMaterialBalance…
  5. 05

    Solver Selection Guide

    Review the “Solver Selection Guide” section in the pinned source before continuing.

    Review and apply the “Solver Selection Guide” source section.

Permission review

Static risk signals and limitations

No configured static risk pattern was detected

This is not proof of safety. Runtime behavior, indirect dependencies, and hidden external systems are outside the static scan.

Evidence record

Why each signal appears

EvidenceSourceComputedTestedEditorial
SignalValueEvidence typeMeaning
Quality score97/100ComputedDocumentation, specificity, maintenance, and trust rules
Repository stars136SourceRepository attention, not individual Skill quality
Compatibility0 platformsSourceDeclared in the catalog source record
Usage guideautomated source guideEditorialGenerated or reviewed according to the visible evidence level

Pinned source

Provenance and original SKILL.md

Repository
equinor/neqsim
Skill path
.github/skills/neqsim-distillation-design/SKILL.md
Commit
9e8d44a141bba600026d2229969b49af50f34237
License
Apache-2.0
Collected
2026-08-05
Default branch
master
View the original SKILL.md

Distillation Design Rules

Guide for distillation column modeling and design in NeqSim.

Column Setup Pattern

import neqsim.process.equipment.distillation.DistillationColumn;
import neqsim.process.equipment.stream.Stream;
import neqsim.thermo.system.SystemSrkEos;
import neqsim.thermo.system.SystemInterface;

// Create feed
SystemInterface feed = new SystemSrkEos(273.15 + 50.0, 15.0);
feed.addComponent("methane", 0.10);
feed.addComponent("ethane", 0.25);
feed.addComponent("propane", 0.30);
feed.addComponent("n-butane", 0.20);
feed.addComponent("n-pentane", 0.15);
feed.setMixingRule("classic");

Stream feedStream = new Stream("feed", feed);
feedStream.setFlowRate(10000.0, "kg/hr");
feedStream.setTemperature(50.0, "C");
feedStream.setPressure(15.0, "bara");
feedStream.run();

// Create column (name, stages, hasCondenser, hasReboiler)
DistillationColumn column = new DistillationColumn("Deethanizer", 15, true, true);
column.addFeedStream(feedStream, 8);  // Feed on stage 8

// Specifications
column.setCondenserTemperature(273.15 - 30.0);  // Kelvin
column.getReboiler().setHeatInput(1e6);          // Watts
// OR set reflux ratio:
// column.getCondenser().setRefluxRatio(2.5);

column.run();

Solver Selection

// Direct substitution (default) - robust sequential tray sweeps
column.setSolverType(DistillationColumn.SolverType.DIRECT_SUBSTITUTION);

// Inside-Out — faster for ideal/near-ideal systems
column.setSolverType(DistillationColumn.SolverType.INSIDE_OUT);

// Adaptive matrix inside-out — bypasses matrix setup on small columns,
// tries a component-balance matrix warm start on larger columns, then
// finishes with rigorous inside-out polishing
column.setSolverType(DistillationColumn.SolverType.MATRIX_INSIDE_OUT);

// Damped substitution - for difficult convergence
column.setSolverType(DistillationColumn.SolverType.DAMPED_SUBSTITUTION);

// MESH residual monitor - for residual auditing
column.setSolverType(DistillationColumn.SolverType.MESH_RESIDUAL);

// Naphtali-Sandholm - guarded simultaneous MESH residual Newton solver
column.setSolverType(DistillationColumn.SolverType.NAPHTALI_SANDHOLM);
// Optional: seed stage temperatures as initial guesses only, not fixed specs
column.setSeedTemperature(3, 273.15 + 45.0);
// Adjust max iterations
column.setMaxNumberOfIterations(200);

Runtime control: iteration budget, damping and tolerance

Three knobs decide how long a column runs before it gives up. Getting them wrong is the usual cause of a column that burns minutes per solve inside a ProcessModel outer loop.

// 1. ITERATION BUDGET — setMaxNumberOfIterations(n) is only a SOFT FLOOR.
//    The effective budget is max(n, 5 * numberOfTrays) and can still be expanded
//    by the overflow/polish extensions. setMaxNumberOfIterations(10) on an
//    11-tray column therefore does NOT cap anything (11*5 = 55 -> ~187 with
//    overflow). NeqSim logs a warning when the request is below the tray floor.
column.setMaxNumberOfIterations(20, true);   // HARD cap (2-arg overload)
column.setHardIterationCap(true);            // or flip the flag separately
column.getEffectiveMaxNumberOfIterations();  // what the solver will actually use

// 2. DAMPING — the adaptive controller clamps the sequential step at
//    minSequentialRelaxation (default 0.5). setRelaxationFactor now lowers that
//    floor when you ask for heavier damping, so a request below 0.5 takes effect
//    instead of being silently clamped back. Use this to break limit cycles.
column.setRelaxationFactor(0.3);
column.setMinSequentialRelaxation(0.2);      // explicit floor if needed
column.setMinInsideOutRelaxation(0.2);       // inside-out tear streams

// 3. TOLERANCE — the default absolute temperature tolerance (~0.02-0.03 K) can
//    be ~10x tighter than the enclosing ProcessModel boundary gate (1e-3
//    relative ~ 0.27 K at 270 K), so the column keeps iterating on a residual
//    the plant model already accepts. Align them:
column.setTemperatureToleranceRelative(1.0e-3);  // returns the absolute K value
column.getReferenceTemperature();                // basis used for the conversion

Rule of thumb for a column inside a multi-area ProcessModel: set a hard iteration cap, damp below 0.5 if the tray temperatures oscillate, and match the column tolerance to the model tolerance passed to ProcessModel.runUntilConverged(maxIter, tol).

What solved() actually checks

solved() is not a single residual. It requires the solve status to be RIGOROUS_CONVERGED or RECONCILED_PRODUCTS and every active residual gate to pass:

GateSourceDefault tolerance
Temperaturemean per-tray change of the last sweep~0.02 K x complexity; NaN for simultaneous solvers, which then require the MESH gate instead
Massexternal feed/product balance~0.016 x complexity
Energytray enthalpy balancenot enforced by default (setEnforceEnergyBalanceTolerance(true))
Internal trafficmax tray traffic / feed100
Per-tray material balancegetLastTrayMaterialBalanceError() — summed absolute tray imbalance / tray throughputgetTrayMaterialBalanceTolerance(), default 0.02
MESH infinity normall residual familiesgetMeshResidualTolerance(), default 1.0

The overall feed/product balance closing to machine precision does not mean the column solved: each tray must close its own component balance too. Read per-tray material imbalance in getConvergenceDiagnostics() before trusting duties or a tray profile.

Do not gate on the MESH material: infinity norm. Those entries scale each component by its own throughput, so a trace component going from 1e-25 to 1.2e-25 mol/hr reads as a 0.17 residual. Use getLastTrayMaterialBalanceError(), which weights by tray throughput.

Solver Selection Guide

System TypeRecommended SolverNotes
Ideal HC (demethanizer, deethanizer)INSIDE_OUTFast, robust
Larger HC fractionatorsMATRIX_INSIDE_OUTAdaptive: small columns bypass matrix overhead; larger columns try the matrix warm start before rigorous inside-out polishing
Non-ideal (alcohols, water)DAMPED_SUBSTITUTION or DIRECT_SUBSTITUTIONMore conservative for non-ideal K-values
Absorbers (no condenser/reboiler)SUM_RATES or DIRECT_SUBSTITUTIONFlow-corrected updates can help absorber/stripper cases
Wide-boiling (C1 to C20+)DAMPED_SUBSTITUTIONIncrease iterations and monitor residuals
Cryogenic (< -100°C)INSIDE_OUT with residual diagnosticsCareful with phase identification
Solver audit / residual convergenceMESH_RESIDUAL or NAPHTALI_SANDHOLMMESH_RESIDUAL records diagnostics and enforces the MESH/product-draw gate by default; NAPHTALI_SANDHOLM attempts guarded simultaneous MESH correction

Column Specification Combinations

Bottom SpecTop SpecComment
Reboiler dutyCondenser temperatureMost common
Reboiler dutyReflux ratioAlternative
Top product purityReboiler dutyProduct-quality control
Bottom temperatureReflux ratioDirect T control
// Common specification patterns

// Pattern 1: Condenser T + Reboiler duty
column.setCondenserTemperature(273.15 - 30.0);
column.getReboiler().setHeatInput(1.5e6);

// Pattern 2: Reflux ratio + Reboiler duty
column.getCondenser().setRefluxRatio(3.0);
column.getReboiler().setHeatInput(2.0e6);

// Pattern 3: Product quality plus boilup ratio
column.setTopProductPurity("ethane", 0.98);
column.setReboilerBoilupRatio(2.0);

Reading Column Results

column.run();

// Condenser and reboiler duties
double condenserDuty = column.getCondenser().getDuty();  // Watts
double reboilerDuty = column.getReboiler().getDuty();    // Watts

// Product streams
Stream overhead = (Stream) column.getGasOutStream();
Stream bottoms = (Stream) column.getLiquidOutStream();

// Stage temperatures and compositions
for (int stage = 0; stage < column.getTrays().size(); stage++) {
    double stageTemp = column.getTray(stage).getTemperature() - 273.15;
    // Composition on each stage
}

// Convergence metrics
int iterations = column.getLastIterationCount();
double massResidual = column.getLastMassResidual();
double energyResidual = column.getLastEnergyResidual();
boolean matrixWarmStartUsed = column.wasMatrixInsideOutWarmStartUsed();
boolean matrixWarmStartBypassed = column.wasMatrixInsideOutWarmStartBypassed();
int matrixIterations = column.getLastMatrixInsideOutIterationCount();

Feed Tray Location Rules

Kirkbride Correlation

For binary or pseudo-binary separations:

$$ \log\left(\frac{N_R}{N_S}\right) = 0.206 \log\left[\left(\frac{B}{D}\right) \left(\frac{x_{HK,F}}{x_{LK,F}}\right)^2 \left(\frac{x_{LK,B}}{x_{HK,D}}\right)^2 \right] $$

Where $N_R$ = rectifying stages, $N_S$ = stripping stages, $B/D$ = bottoms/distillate ratio.

Rules of Thumb

Column TypeFeed Tray (from top)Notes
Demethanizer40-60% of stagesLight key is very volatile
Deethanizer50-70% of stagesModerate volatility
Depropanizer40-60% of stagesBalanced separation
Debutanizer50-60% of stagesSimilar to depropanizer
Crude column60-80% of stagesFlash zone near bottom

Minimum Stages and Reflux

Fenske Equation (Minimum Stages)

$$ N_{min} = \frac{\log\left(\frac{x_{LK,D}}{x_{HK,D}} \cdot \frac{x_{HK,B}}{x_{LK,B}}\right)}{\log(\alpha_{LK/HK})} $$

Underwood Equation (Minimum Reflux)

$$ R_{min} = \frac{1}{\alpha - 1}\left(\frac{x_D}{\alpha - \theta} - \frac{1 - x_D}{1 - \theta}\right) $$

Design Heuristics

  • Actual stages ≈ 2 × minimum stages (Gilliland correlation)
  • Actual reflux ≈ 1.2-1.5 × minimum reflux
  • Stage efficiency: 50-70% for trays, 70-90% HETP/stage for packing

Convergence Troubleshooting

ProblemSolution
Column does not convergeIncrease max iterations to 200-500
Oscillating temperature profileReduce condenser/reboiler specs, use DAMPED_SUBSTITUTION; audit with MESH_RESIDUAL before trying NAPHTALI_SANDHOLM
Wrong product splitCheck feed tray location and specifications
Negative flows on stagesToo many stages or wrong specifications
Condenser too coldCheck if subcooled liquid is physical (binary dewpoint)
Reboiler too hotMay be decomposing — check component stability

Steps to Debug

  1. Start with fewer stages (5-8) and get convergence
  2. Gradually increase stages
  3. Use liberal specifications first (higher reflux), then tighten
  4. Check feed condition (vapor fraction) — subcooled feed may need enthalpy adjustment
  5. Verify component K-values make physical sense at column conditions

Column Sizing (Diameter)

Souders-Brown Correlation

$$ V_{flood} = K_{SB} \sqrt{\frac{\rho_L - \rho_V}{\rho_V}} $$

Where $K_{SB}$ = 0.03-0.07 m/s for trays, 0.02-0.05 for packing.

Design velocity = 70-85% of flooding.

// After running column, get phase properties for sizing
SystemInterface topFluid = column.getTray(0).getFluid();
topFluid.initProperties();
double rhoV = topFluid.getPhase("gas").getDensity("kg/m3");
double rhoL = topFluid.getPhase("oil").getDensity("kg/m3");

double Ksb = 0.05;  // m/s for sieve trays
double Vflood = Ksb * Math.sqrt((rhoL - rhoV) / rhoV);
double Vdesign = 0.80 * Vflood;

double gasFlow = column.getGasOutStream().getFlowRate("m3/hr") / 3600.0;
double area = gasFlow / Vdesign;
double diameter = Math.sqrt(4.0 * area / Math.PI);

Internals Selection

InternalsWhen to UseTypical HETP (m)
Sieve traysGeneral service, fouling0.5-0.7
Valve traysVariable turndown0.4-0.6
Bubble cap traysLow liquid rates0.5-0.8
Random packing (Pall rings)Low pressure drop, corrosive0.3-0.6
Structured packing (Mellapak)Vacuum, low ΔP0.2-0.5

Common Pitfalls

  1. Feed flash: Ensure feed is at correct T/P for column conditions
  2. Missing components: All components in feed must be present in EOS
  3. Mixing rule: Always set before column construction
  4. Heavy key in top / light key in bottom: Small amounts are normal — zero means perfect separation (unrealistic)
  5. Column pressure profile: Default is constant — set stage pressures for realistic profile
  6. Condenser type: Total vs partial condenser changes mass balance

Alternatives

Compare before choosing

Computed 10043,034

coreyhaines31/marketingskills

ab-testing

When the user wants to plan, design, or implement an A/B test or experiment, or build a growth experimentation program. Also use when the user mentions "A/B test," "split test," "experiment," "test this change," "variant copy," "multivariate test," "hypothesis," "should I test this," "which version is better," "test two versions," "statistical significance," "how long should I run this test," "growth experiments," "experiment velocity," "experiment backlog," "ICE score," "experimentation program

Computed 10043,034

coreyhaines31/marketingskills

churn-prevention

When the user wants to reduce churn, build cancellation flows, set up save offers, recover failed payments, or implement retention strategies. Also use when the user mentions 'churn,' 'cancel flow,' 'offboarding,' 'save offer,' 'dunning,' 'failed payment recovery,' 'win-back,' 'retention,' 'exit survey,' 'pause subscription,' 'involuntary churn,' 'people keep canceling,' 'churn rate is too high,' 'how do I keep users,' or 'customers are leaving.' Use this whenever someone is losing subscribers o

Computed 10014,533

prowler-cloud/prowler

postgresql-indexing

PostgreSQL indexing best practices for Prowler: index design, partial indexes, partitioned table indexing, EXPLAIN ANALYZE validation, concurrent operations, monitoring, and maintenance. Trigger: When creating or modifying PostgreSQL indexes, analyzing query performance with EXPLAIN, debugging slow queries, reviewing index usage statistics, reindexing, dropping indexes, or working with partitioned table indexes. Also trigger when discussing index strategies, partial indexes, or index maintenance

Computed 100165

JasonColapietro/suede-creator-skills

suede-ab-testing

Suede-owned experimentation discipline for hypotheses, sample sizing, test duration, significance, and repeatable experiment programs. Use when comparing variants, deciding whether a result is reliable, or building an experiment backlog and cadence. NOT FOR: analytics instrumentation (use suede-analytics), post-click conversion diagnosis (use suede-site-alchemy), or writing the variant copy itself (use suede-copy).