NeqSim Cost Estimation Framework
This document provides comprehensive documentation for the NeqSim cost estimation framework, which enables capital and operating cost estimation for process equipment and complete process systems.
Table of Contents
- Overview
- Architecture
- Core Classes
- Equipment Cost Estimation
- Process-Level Cost Estimation
- Result Schema and Reconciliation
- Currency and Location Support
- Operating Cost (OPEX) Estimation
- Financial Metrics
- Usage Examples
- Extending the Framework
- References
Overview
The NeqSim cost estimation framework provides tools for estimating:
- Capital Costs (CAPEX)
- Purchased Equipment Cost (PEC)
- Bare Module Cost (BMC)
- Total Module Cost (TMC)
- Grass Roots Cost (GRC)
- Operating Costs (OPEX)
- Utility costs (electricity, steam, cooling water)
- Maintenance costs
- Operating labor
- Administrative overhead
- Financial Metrics
- Payback period
- Return on Investment (ROI)
- Net Present Value (NPV)
The framework uses industry-standard correlations from:
- Turton et al. - “Analysis, Synthesis and Design of Chemical Processes”
- Peters & Timmerhaus - “Plant Design and Economics for Chemical Engineers”
- GPSA Engineering Data Book
- Various API standards
Architecture
neqsim.process.costestimation/
├── CostEstimationCalculator.java # Core calculation utilities
├── UnitCostEstimateBaseClass.java # Base class for equipment costs
├── ProcessCostEstimate.java # System-level cost aggregation
├── SystemMechanicalDesign.java # Mechanical design aggregation
│
├── absorber/
│ └── AbsorberCostEstimate.java # Absorber tower costs
├── column/
│ └── ColumnCostEstimate.java # Distillation column costs
├── compressor/
│ └── CompressorCostEstimate.java # Compressor costs
├── ejector/
│ └── EjectorCostEstimate.java # Ejector/vacuum system costs
├── expander/
│ └── ExpanderCostEstimate.java # Turboexpander costs
├── heatexchanger/
│ └── HeatExchangerCostEstimate.java # Heat exchanger costs
├── mixer/
│ └── MixerCostEstimate.java # Mixer costs
├── pipe/
│ └── PipeCostEstimate.java # Piping costs
├── pump/
│ └── PumpCostEstimate.java # Pump costs
├── separator/
│ └── SeparatorCostEstimate.java # Separator vessel costs
├── splitter/
│ └── SplitterCostEstimate.java # Splitter/manifold costs
├── tank/
│ └── TankCostEstimate.java # Storage tank costs
└── valve/
└── ValveCostEstimate.java # Control valve costs
Core Classes
CostEstimationCalculator
The central utility class providing cost calculation methods and constants.
CostEstimationCalculator calc = new CostEstimationCalculator();
// Set CEPCI index (default: 816.0 for 2024)
calc.setCepci(816.0);
// Currency support
calc.setCurrencyCode("EUR");
double eurCost = calc.convertFromUSD(1000000.0);
// Location factors
calc.setLocationByRegion("North Sea");
double adjustedCost = baseCost * calc.getLocationFactor();
Available Currencies
| Code | Currency | Default Exchange Rate |
|---|---|---|
| USD | US Dollar | 1.00 |
| EUR | Euro | 0.92 |
| NOK | Norwegian Krone | 11.00 |
| GBP | British Pound | 0.79 |
| CNY | Chinese Yuan | 7.25 |
| JPY | Japanese Yen | 155.00 |
Location Factors
| Region | Factor | Notes |
|---|---|---|
| US Gulf Coast | 1.00 | Base reference |
| North Sea / Norway | 1.35 | High labor costs |
| Western Europe | 1.20 | |
| Eastern Europe | 0.85 | |
| Middle East | 1.10 | |
| Asia Pacific | 0.90 | |
| China | 0.75 | Lower labor costs |
| India | 0.70 | |
| South America | 0.95 | |
| Africa | 1.05 | |
| Australia | 1.25 | Remote location premium |
UnitCostEstimateBaseClass
Abstract base class for all equipment cost estimators.
Key Methods:
calculateCostEstimate()- Calculates all cost metricsgetPurchasedEquipmentCost()- Returns PECgetBareModuleCost()- Returns BMCgetTotalModuleCost()- Returns TMCgetGrassRootsCost()- Returns GRCgetInstallationManHours()- Returns estimated installation hoursgetCostBreakdown()- Returns detailed cost breakdown maptoMap()- Returns all data as a map for JSON export
Equipment Cost Estimation
Separator Cost
For vertical and horizontal separators, scrubbers, and slug catchers.
Separator separator = new Separator("HP Separator", feed);
separator.run();
separator.initMechanicalDesign();
SeparatorCostEstimate costEst = new SeparatorCostEstimate(
(SeparatorMechanicalDesign) separator.getMechanicalDesign());
costEst.calculateCostEstimate();
double pec = costEst.getPurchasedEquipmentCost();
Supported Types:
- Vertical vessels
- Horizontal vessels
- Three-phase separators
Compressor Cost
For centrifugal and reciprocating compressors.
CompressorCostEstimate costEst = new CompressorCostEstimate(compMecDesign);
costEst.setCompressorType("centrifugal"); // or "reciprocating"
costEst.setIncludeDriver(true);
costEst.setDriverType("electric-motor"); // or "gas-turbine", "steam-turbine"
costEst.calculateCostEstimate();
Parameters:
- Compressor type (centrifugal, reciprocating)
- Driver type and inclusion
- Spare parts package
Heat Exchanger Cost
For shell-and-tube, plate, air-cooled, and other heat exchangers.
HeatExchangerCostEstimate costEst = new HeatExchangerCostEstimate(hxMecDesign);
costEst.setHeatExchangerType("shell-tube"); // or "plate", "air-cooled"
costEst.setShellMaterial("carbon-steel");
costEst.setTubeMaterial("stainless-steel");
costEst.calculateCostEstimate();
Pump Cost
For centrifugal and positive displacement pumps.
PumpCostEstimate costEst = new PumpCostEstimate(pumpMecDesign);
costEst.setPumpType("centrifugal"); // or "reciprocating", "gear"
costEst.setIncludeDriver(true);
costEst.calculateCostEstimate();
Valve Cost
For control valves, safety valves, and manual valves.
ValveCostEstimate costEst = new ValveCostEstimate(valveMecDesign);
costEst.setValveType("globe"); // or "ball", "butterfly", "gate"
costEst.setActuatorType("pneumatic"); // or "electric", "hydraulic", "manual"
costEst.calculateCostEstimate();
Tank Cost
For atmospheric and pressurized storage tanks per API 650/620.
TankCostEstimate costEst = new TankCostEstimate(tankMecDesign);
// Tank configuration
costEst.setTankType("fixed-cone-roof"); // See table below
costEst.setTankVolume(5000.0); // m³
costEst.setTankDiameter(20.0); // m
costEst.setTankHeight(16.0); // m
costEst.setDesignPressure(0.1); // barg (for pressurized)
// Optional components
costEst.setIncludeFoundation(true);
costEst.setIncludeHeatingCoils(false);
costEst.setIncludeInsulation(true);
costEst.setInsulationThickness(75.0); // mm
costEst.calculateCostEstimate();
Map<String, Object> breakdown = costEst.getCostBreakdown();
Supported Tank Types:
| Type | Description | Standards |
|---|---|---|
fixed-cone-roof |
Cone roof atmospheric tank | API 650 |
fixed-dome-roof |
Dome roof atmospheric tank | API 650 |
floating-roof |
External/internal floating roof | API 650 |
spherical |
Spherical pressure vessel | API 620 |
horizontal |
Horizontal cylindrical tank | API 620 |
Expander Cost
For turboexpanders used in gas processing and cryogenic applications.
ExpanderCostEstimate costEst = new ExpanderCostEstimate(expMecDesign);
// Expander configuration
costEst.setExpanderType("radial-inflow"); // or "axial", "mixed-flow"
costEst.setShaftPower(2000.0); // kW (if no MechanicalDesign)
costEst.setCryogenicService(true); // Below -40°C
// Load configuration
costEst.setLoadType("generator"); // or "compressor", "brake"
costEst.setIncludeLoad(true);
// Auxiliary systems
costEst.setIncludeGearbox(false);
costEst.setIncludeLubeOilSystem(true);
costEst.setIncludeControlSystem(true);
costEst.calculateCostEstimate();
Cost Factors:
- Cryogenic service: +40% for special materials
- Axial type: +20% vs radial-inflow
- Generator load: Based on power output
Mixer Cost
For static mixers and inline mixing devices.
MixerCostEstimate costEst = new MixerCostEstimate(null); // Can work standalone
costEst.setMixerType("static"); // or "inline", "tee", "vessel"
costEst.setPipeDiameter(8.0); // inches
costEst.setNumberOfElements(12); // For static mixers
costEst.setPressureClass(300); // ASME pressure class
costEst.setFlangedConnections(true);
costEst.calculateCostEstimate();
Mixer Types:
| Type | Description | Typical Use |
|---|---|---|
static |
Static mixing elements | Chemical injection |
inline |
Motorized inline mixer | High-shear mixing |
tee |
Simple mixing tee | Low-intensity mixing |
vessel |
Agitated mixing vessel | Batch operations |
Splitter Cost
For flow distribution manifolds and headers.
SplitterCostEstimate costEst = new SplitterCostEstimate(null);
costEst.setSplitterType("manifold"); // or "header", "tee", "vessel"
costEst.setNumberOfOutlets(4);
costEst.setInletDiameter(10.0); // inches
costEst.setOutletDiameter(6.0); // inches
costEst.setPressureClass(600); // ASME class
// Optional control equipment
costEst.setIncludeControlValves(true);
costEst.setIncludeFlowMeters(false);
costEst.calculateCostEstimate();
Ejector Cost
For steam ejectors, gas ejectors, and vacuum systems.
EjectorCostEstimate costEst = new EjectorCostEstimate(null);
costEst.setEjectorType("steam"); // or "gas", "liquid", "hybrid"
costEst.setNumberOfStages(2);
costEst.setSuctionPressure(50.0); // mbar abs
costEst.setDischargePressure(1.013); // bara
costEst.setSuctionCapacity(500.0); // kg/hr
costEst.setMotivePressure(10.0); // bara (steam/gas pressure)
// Condensers
costEst.setIncludeIntercondensers(true);
costEst.setIncludeAftercondenser(true);
costEst.calculateCostEstimate();
Ejector Types:
| Type | Description | Motive Fluid |
|---|---|---|
steam |
Steam jet ejector | Steam |
gas |
Gas jet ejector | Process gas |
liquid |
Liquid jet ejector | Water/liquid |
hybrid |
Ejector + liquid ring pump | Combined |
Absorber Cost
For gas absorption towers (TEG contactors, amine columns, etc.).
AbsorberCostEstimate costEst = new AbsorberCostEstimate(null);
// Column configuration
costEst.setAbsorberType("packed"); // or "trayed", "spray"
costEst.setColumnDiameter(2.0); // m
costEst.setColumnHeight(15.0); // m
costEst.setDesignPressure(60.0); // barg
// For packed columns
costEst.setPackingType("structured"); // or "random"
costEst.setPackingHeight(10.0); // m
// For trayed columns
costEst.setTrayType("valve"); // or "sieve", "bubble-cap"
costEst.setNumberOfStages(15);
// Internals
costEst.setIncludeLiquidDistributor(true);
costEst.setIncludeMistEliminator(true);
// Auxiliaries
costEst.setIncludeReboiler(false);
costEst.setIncludeRefluxSystem(false);
costEst.calculateCostEstimate();
Column Cost
For distillation and fractionation columns.
ColumnCostEstimate costEst = new ColumnCostEstimate(columnMecDesign);
costEst.setColumnType("trayed");
costEst.setNumberOfTrays(40);
costEst.setTrayType("valve");
costEst.calculateCostEstimate();
Pipe Cost
For process piping systems.
PipeCostEstimate costEst = new PipeCostEstimate(pipeMecDesign);
costEst.setPipeLength(100.0); // m
costEst.setPipeDiameter(8.0); // inches
costEst.setSchedule("40");
costEst.setMaterial("carbon-steel");
costEst.calculateCostEstimate();
Process-Level Cost Estimation
The ProcessCostEstimate class aggregates costs across an entire process system.
// Create and run process
ProcessSystem process = new ProcessSystem();
process.add(feed);
process.add(separator);
process.add(compressor);
process.add(cooler);
process.run();
// Calculate costs
ProcessCostEstimate processCost = new ProcessCostEstimate(process);
processCost.setLocationFactor(1.35); // North Sea
processCost.setComplexityFactor(1.1); // Complex process
processCost.calculateAllCosts();
// Get results
double pec = processCost.getPurchasedEquipmentCost();
double bmc = processCost.getBareModuleCost();
double tmc = processCost.getTotalModuleCost();
double grc = processCost.getGrassRootsCost();
// Print summary report
processCost.printCostSummary();
Field-Development Split: DRILEX, SURF, Facilities
For field-development screening, wrap the process simulation in
FieldDevelopmentCostEstimator. The report keeps the normal project split:
getDrilexCapex()- drilling and completion expenditure for producers and injectorsgetSurfCapex()- subsea, umbilicals, risers, and flowlinesgetFacilitiesCapex()- topsides or host-facility CAPEX from the process simulation
The legacy getSubseaCapex() value remains available as DRILEX + SURF for
older integrations.
import neqsim.process.util.fielddevelopment.FieldDevelopmentCostEstimator;
FieldDevelopmentCostEstimator estimator = new FieldDevelopmentCostEstimator(process);
estimator.setConceptType(FieldDevelopmentCostEstimator.ConceptType.SUBSEA_TIEBACK);
estimator.setFidelityLevel(FieldDevelopmentCostEstimator.FidelityLevel.PRE_FEED);
estimator.setSubseaParameters(25.0, 350.0); // tieback length [km], water depth [m]
estimator.setWellParameters(4, 1, 4200.0); // producers, injectors, average MD [m]
FieldDevelopmentCostEstimator.FieldDevelopmentCostReport report = estimator.estimateDevelopmentCosts();
double drilexUsd = report.getDrilexCapex();
double surfUsd = report.getSurfCapex();
double facilitiesUsd = report.getFacilitiesCapex();
double totalUsd = report.getTotalCapex();
The report JSON writes these buckets as drilex_USD, surf_USD,
facilities_USD, and total_USD. Use subsea_USD only as the compatibility
subtotal for DRILEX plus SURF.
Cost Breakdown by Category
Map<String, Double> byType = processCost.getCostByEquipmentType();
// Returns: {Vessels: 321414, Compressors: 168940, ...}
Map<String, Double> byDiscipline = processCost.getCostByDiscipline();
// Returns: {Process Equipment: 544382, Piping & Valves: 1867911, ...}
Result Schema and Reconciliation
CostEstimateResult is the report-ready schema used by unit, process,
topsides, SURF, subsea, and development estimates. It separates additive cost
lines, supplementary breakdown lines, subtotal/total lines, and non-cost
quantities so reported totals can be reconciled without double-counting.
| Map | Contents | Add These Rows Into Totals? |
|---|---|---|
capitalCosts_USD |
Additive direct capital-cost lines, such as purchased equipment, flowlines, or topsides bulk categories | Yes, when the report scope matches the map scope |
capitalCostBreakdown_USD |
Supplementary detail behind a capital line, such as module.* topsides detail |
No, unless the report explicitly replaces the parent line with this detail |
capitalCostSummary_USD |
Capital subtotals and totals, such as bareModuleCost, grassRootsCost, directFieldCost, totalSURF, or totalDevelopment |
No, these are already totals or subtotals |
projectCosts_USD |
Additive project-cost lines, such as engineering, construction management, owner cost, and annual operating cost | Yes, when building the matching project total |
projectCostSummary_USD |
Project totals, such as totalProjectCost or totalTopsidesCapex |
No, use as reported totals |
quantityBasis |
Non-cost quantities with value and unit, such as installationManHours and totalVesselDays |
No, these are not currency values |
weightBasis_kg |
Weight basis used by the estimate | No, these are physical quantities |
materialTakeOff |
Material take-off lines with quantities, weights, costs, and source labels | Usually no; use for traceability or to rebuild a controlled MTO total |
Scope-Safe Totals
Use the summary maps as the authoritative totals for their scope:
- Equipment estimates:
purchasedEquipmentCostis additive incapitalCosts_USD;bareModuleCost,totalModuleCost, andgrassRootsCostare incapitalCostSummary_USD. - Process estimates: process-level PEC/BMC/TMC/grass-roots totals are in
capitalCostSummary_USD;totalProjectCostis inprojectCostSummary_USD; total installation hours are inquantityBasis. - Topsides estimates: direct field cost and excluded non-topsides scope are in
capitalCostSummary_USD; total topsides CAPEX is inprojectCostSummary_USD; module detail is incapitalCostBreakdown_USD. - SURF and development estimates:
totalSURFandtotalDevelopmentare capital summary values, while vessel days are inquantityBasis.
Located and Base Equipment Rows
ProcessCostEstimate.toJson() reports equipment rows with location-adjusted
costs under the standard *_USD fields so the equipment rows reconcile with
process totals and costByEquipmentType_USD. The original unlocated equipment
estimates remain available as basePurchasedEquipmentCost_USD,
baseBareModuleCost_USD, baseTotalModuleCost_USD, and
baseGrassRootsCost_USD, with the row-specific locationFactor stated
explicitly.
Reporting Rule
When producing a report, choose one basis per table:
- Additive detail table: sum only
capitalCosts_USDorprojectCosts_USDrows for the same scope. - Summary table: show
capitalCostSummary_USDandprojectCostSummary_USDrows without re-adding them. - Basis table: show
quantityBasis,weightBasis_kg, andmaterialTakeOffseparately from currency totals. - Location basis: compare located totals to located equipment rows, or base totals to base rows, but do not mix them in one reconciliation.
Currency and Location Support
Setting Currency
ProcessCostEstimate processCost = new ProcessCostEstimate(process);
processCost.setCurrency("NOK"); // Norwegian Krone
processCost.calculateAllCosts();
// Get costs in selected currency
Map<String, Double> costs = processCost.getCostsInCurrency();
Setting Location
processCost.setLocationByRegion("North Sea");
// Automatically sets location factor to 1.35
// Or set directly
processCost.setLocationFactor(1.40);
Custom Exchange Rates
CostEstimationCalculator calc = new CostEstimationCalculator();
calc.setCurrencyCode("EUR");
calc.setExchangeRate(0.95); // Override default
Operating Cost (OPEX) Estimation
The framework calculates annual operating costs based on utility consumption and industry factors.
ProcessCostEstimate processCost = new ProcessCostEstimate(process);
processCost.calculateAllCosts();
// Calculate OPEX (8000 operating hours/year typical)
double annualOpex = processCost.calculateOperatingCost(8000);
// Get breakdown
Map<String, Double> opexBreakdown = processCost.getOperatingCostBreakdown();
// Returns:
// - Electricity: based on power consumption
// - Steam: based on heating duty
// - Cooling Water: based on cooling duty
// - Maintenance: 3-5% of CAPEX
// - Operating Labor: industry factors
// - Administrative Overhead: 25% of labor
Default Utility Prices
| Utility | Default Price | Unit |
|---|---|---|
| Electricity | 0.08 | USD/kWh |
| Steam (LP) | 15.0 | USD/ton |
| Cooling Water | 0.05 | USD/m³ |
Financial Metrics
Calculate key financial metrics for project evaluation:
ProcessCostEstimate processCost = new ProcessCostEstimate(process);
processCost.calculateAllCosts();
processCost.calculateOperatingCost(8000);
double capex = processCost.getGrassRootsCost();
double annualRevenue = 10000000.0; // USD/year
// Payback Period
double payback = processCost.calculatePaybackPeriod(annualRevenue);
// Returns years to recover investment
// Return on Investment
double roi = processCost.calculateROI(annualRevenue);
// Returns (Revenue - OPEX) / CAPEX as percentage
// Net Present Value
double discountRate = 0.10; // 10%
int projectLife = 20; // years
double npv = processCost.calculateNPV(annualRevenue, discountRate, projectLife);
Usage Examples
Example 1: Simple Equipment Cost
// Create and size a separator
SystemInterface fluid = new SystemSrkEos(298.15, 50.0);
fluid.addComponent("methane", 0.9);
fluid.addComponent("ethane", 0.1);
fluid.setMixingRule("classic");
Stream feed = new Stream("Feed", fluid);
feed.setFlowRate(10000, "kg/hr");
feed.run();
Separator sep = new Separator("HP Separator", feed);
sep.run();
sep.initMechanicalDesign();
// Estimate cost
SeparatorCostEstimate costEst = new SeparatorCostEstimate(
(SeparatorMechanicalDesign) sep.getMechanicalDesign());
costEst.calculateCostEstimate();
System.out.println("PEC: $" + String.format("%,.0f", costEst.getPurchasedEquipmentCost()));
System.out.println("Grass Roots: $" + String.format("%,.0f", costEst.getGrassRootsCost()));
Example 2: Complete Process Costing
// Build process
ProcessSystem process = new ProcessSystem();
process.add(feed);
process.add(separator);
process.add(compressor);
process.add(cooler);
process.run();
// Cost estimation with North Sea location
ProcessCostEstimate processCost = new ProcessCostEstimate(process);
processCost.setLocationByRegion("North Sea");
processCost.setCurrency("NOK");
processCost.calculateAllCosts();
// Calculate OPEX
double opex = processCost.calculateOperatingCost(8000);
// Financial analysis
double revenue = 50000000.0; // NOK/year
double payback = processCost.calculatePaybackPeriod(revenue);
double npv = processCost.calculateNPV(revenue, 0.08, 25);
// Print detailed report
processCost.printCostSummary();
Example 3: Standalone Equipment Costing
Some cost estimators can work without mechanical design for quick estimates:
// Tank cost without process simulation
TankCostEstimate tankCost = new TankCostEstimate(null);
tankCost.setTankType("floating-roof");
tankCost.setTankVolume(50000.0); // 50,000 m³
tankCost.setIncludeFoundation(true);
tankCost.calculateCostEstimate();
System.out.println("Tank Cost: $" +
String.format("%,.0f", tankCost.getPurchasedEquipmentCost()));
Example 4: Export to JSON
ProcessCostEstimate processCost = new ProcessCostEstimate(process);
processCost.calculateAllCosts();
// Get as JSON string
String json = processCost.toJson();
// Or get as Map for custom serialization
Map<String, Object> data = processCost.toMap();
Extending the Framework
Adding New Equipment Types
- Create a new package under
neqsim.process.costestimation - Create the cost estimate class extending
UnitCostEstimateBaseClass - Implement required methods
package neqsim.process.costestimation.myequipment;
public class MyEquipmentCostEstimate extends UnitCostEstimateBaseClass {
public MyEquipmentCostEstimate(MechanicalDesign mechanicalEquipment) {
super(mechanicalEquipment);
setEquipmentType("myequipment");
}
@Override
protected double calcPurchasedEquipmentCost() {
// Implement cost correlation
double size = getEquipmentSize();
double baseCost = correlationFunction(size);
return baseCost * getMaterialFactor() *
(getCostCalculator().getCurrentCepci() / 607.5);
}
@Override
public Map<String, Object> getCostBreakdown() {
Map<String, Object> breakdown = new LinkedHashMap<>();
breakdown.put("equipmentType", getEquipmentType());
breakdown.put("size", getEquipmentSize());
breakdown.put("purchasedCost", getPurchasedEquipmentCost());
return breakdown;
}
}
Adding New Currency
// In CostEstimationCalculator or your code
public static final String CURRENCY_CHF = "CHF"; // Swiss Franc
// Add to getDefaultExchangeRates()
rates.put("CHF", 0.88); // 1 USD = 0.88 CHF
Adding New Location Factor
// In CostEstimationCalculator
locationFactors.put("Arctic / Remote", 1.50);
References
Cost Correlations
- Turton, R., et al. “Analysis, Synthesis and Design of Chemical Processes” 5th Ed.
- Peters, M.S. & Timmerhaus, K.D. “Plant Design and Economics for Chemical Engineers” 5th Ed.
- Couper, J.R. “Chemical Process Equipment: Selection and Design” 3rd Ed.
- GPSA Engineering Data Book, 14th Edition
Industry Standards
- API 650 - Welded Tanks for Oil Storage
- API 620 - Design and Construction of Large, Welded, Low-Pressure Storage Tanks
- API 617 - Axial and Centrifugal Compressors and Expander-compressors
- ASME B16.5 - Pipe Flanges and Flanged Fittings
- HEI Standards for Steam Jet Vacuum Systems
Cost Indices
- Chemical Engineering Plant Cost Index (CEPCI)
- 2024 average: ~816
- 2001 base: 397
- Update via
CostEstimationCalculator.setCepci(value)
Version History
| Version | Date | Changes |
|---|---|---|
| 1.0 | Jan 2026 | Initial framework with basic equipment |
| 1.1 | Jan 2026 | Added Tank, Expander, Mixer, Splitter, Ejector, Absorber |
| 1.2 | Jan 2026 | Added currency conversion and location factors |
| 1.3 | Jan 2026 | Added OPEX calculation and financial metrics |
Document last updated: January 2026