Skip to the content.

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

  1. Overview
  2. Architecture
  3. Core Classes
  4. Equipment Cost Estimation
  5. Process-Level Cost Estimation
  6. Result Schema and Reconciliation
  7. Currency and Location Support
  8. Operating Cost (OPEX) Estimation
  9. Financial Metrics
  10. Usage Examples
  11. Extending the Framework
  12. References

Overview

The NeqSim cost estimation framework provides tools for estimating:

The framework uses industry-standard correlations from:


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:


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:


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:


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:


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:

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:

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:

  1. Additive detail table: sum only capitalCosts_USD or projectCosts_USD rows for the same scope.
  2. Summary table: show capitalCostSummary_USD and projectCostSummary_USD rows without re-adding them.
  3. Basis table: show quantityBasis, weightBasis_kg, and materialTakeOff separately from currency totals.
  4. 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

  1. Create a new package under neqsim.process.costestimation
  2. Create the cost estimate class extending UnitCostEstimateBaseClass
  3. 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

  1. Turton, R., et al. “Analysis, Synthesis and Design of Chemical Processes” 5th Ed.
  2. Peters, M.S. & Timmerhaus, K.D. “Plant Design and Economics for Chemical Engineers” 5th Ed.
  3. Couper, J.R. “Chemical Process Equipment: Selection and Design” 3rd Ed.
  4. GPSA Engineering Data Book, 14th Edition

Industry Standards

Cost Indices


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