NeqSim provides a comprehensive mechanical design framework for sizing and specifying process equipment according to industry standards. This document describes the architecture, usage patterns, and JSON export capabilities.
π Related Documentation
Topic Documentation Pipelines Pipeline Mechanical Design - Wall thickness, stress analysis, cost estimation Mathematical Methods Pipeline Design Math - Complete formula reference Design Standards Mechanical Design Standards - Industry standards reference Database Mechanical Design Database - Material properties, design factors Cost Estimation COST_ESTIMATION_FRAMEWORK.md - CAPEX, OPEX, currency, location factors Design Parameters EQUIPMENT_DESIGN_PARAMETERS.md - autoSize vs manual sizing guide
Overview
The mechanical design system calculates:
- Equipment sizing - Vessel dimensions, wall thickness, nozzle sizes
- Weight estimation - Empty, operating, and test weights with breakdowns
- Design conditions - Pressure and temperature with appropriate margins
- Module dimensions - Plot space requirements for installation planning
- Utility requirements - Power consumption, heating/cooling duties
- Cost estimation - Material, fabrication, installation, and project costs
- Bill of Materials - Complete BOM with quantities and costs
Architecture
Class Hierarchy
MechanicalDesign (base class)
βββ SeparatorMechanicalDesign β ASME VIII / API 12J
βββ GasScrubberMechanicalDesign β ASME VIII / API 12J
βββ CompressorMechanicalDesign β API 617
βββ PumpMechanicalDesign β API 610
βββ ValveMechanicalDesign β IEC 60534 / ANSI/ISA-75
βββ ExpanderMechanicalDesign β API 617
βββ TankMechanicalDesign β API 650/620
βββ HeatExchangerMechanicalDesign β TEMA
βββ PipelineMechanicalDesign β ASME B31.3/B31.4/B31.8, DNV-OS-F101, API 5L
β βββ PipeMechanicalDesignCalculator (wall thickness, stress, cost)
βββ AdsorberMechanicalDesign β ASME VIII
βββ AbsorberMechanicalDesign β ASME VIII
βββ DistillationColumnMechanicalDesign
β βββ Tray/packing flood, Fs, demister K-factor, pressure drop, and bottleneck rating
βββ EjectorMechanicalDesign β HEI
βββ SafetyValveMechanicalDesign β API 520/521
βββ WellMechanicalDesign β NORSOK D-010 / API 5CT / API Bull 5C3
βββ WellDesignCalculator (casing burst, collapse, tension)
βββ WellCostEstimator (drilling, completion, wellhead costs)
MotorMechanicalDesign (standalone) β IEC 60034, IEEE 841, ISO 10816-3, ISO 281, NORSOK S-002
βββ Foundation, vibration, cooling, bearings, noise, enclosure, derating
EquipmentDesignReport (aggregator)
βββ Combines MechanicalDesign + ElectricalDesign + MotorMechanicalDesign
with feasibility verdict (FEASIBLE / FEASIBLE_WITH_WARNINGS / NOT_FEASIBLE)
Pipeline Mechanical Design Features
The PipelineMechanicalDesign class provides comprehensive pipeline design including:
| Feature | Description |
|---|---|
| Wall Thickness | ASME B31.3/B31.4/B31.8, DNV-OS-F101 calculations |
| Stress Analysis | Hoop, longitudinal, von Mises stress |
| External Pressure | Collapse and propagation buckling |
| Weight/Buoyancy | Steel, coating, concrete, contents |
| Thermal Design | Expansion loops, insulation sizing |
| Structural Design | Support spacing, spans, bend radius |
| Fatigue Analysis | S-N curves per DNV-RP-C203 |
| Cost Estimation | Complete project cost with BOM |
See Pipeline Mechanical Design for details.
Response Classes for JSON Export
MechanicalDesignResponse (base class)
βββ CompressorMechanicalDesignResponse
βββ PumpMechanicalDesignResponse
βββ ValveMechanicalDesignResponse
βββ SeparatorMechanicalDesignResponse
βββ HeatExchangerMechanicalDesignResponse
System-Level Aggregation
SystemMechanicalDesign
βββ Aggregates all equipment in a ProcessSystem
βββ Total weights and volumes
βββ Weight breakdown by equipment type
βββ Weight breakdown by discipline
βββ Utility requirements summary
βββ Equipment list with design parameters
Usage Patterns
Individual Equipment Design
// Create and run process equipment
SystemInterface fluid = new SystemSrkEos(298.0, 50.0);
fluid.addComponent("methane", 0.9);
fluid.addComponent("ethane", 0.1);
fluid.setMixingRule("classic");
Stream inlet = new Stream("feed", fluid);
inlet.setFlowRate(10000.0, "kg/hr");
inlet.run();
Separator separator = new Separator("V-100", inlet);
separator.run();
// Access mechanical design
MechanicalDesign mecDesign = separator.getMechanicalDesign();
// Set design standards (optional - uses defaults if not specified)
mecDesign.setCompanySpecificDesignStandards("Equinor");
// Prefer explicit units for operating conditions; canonical storage is bara and K
mecDesign.setMaxOperationPressure(1450.38, "psia");
mecDesign.setMaxOperationTemperature(250.0, "F");
// Calculate design
mecDesign.calcDesign();
// Access results
double weight = mecDesign.getWeightTotal(); // kg
double wallThickness = mecDesign.getWallThickness(); // m for this separator
double innerDiameter = mecDesign.getInnerDiameter(); // m
double length = mecDesign.getTantanLength(); // m
double designPressure = mecDesign.getMaxDesignPressure(); // bara
// Display results in GUI
mecDesign.displayResults();
Consistent separator sizing results
SeparatorMechanicalDesign.calcDesign() calculates pressure-wall thickness using the final
sized inner diameter, including any liquid-separation sizing override. Outside diameter,
shell weight, internals and dependent module weights then use that same geometry. The
autoSize() sizing path and GasScrubberMechanicalDesign.calcDesign() follow the same order.
An unchanged design does not require a second setDesign() / calcDesign() cycle to obtain
consistent thickness and weights. Use setDesign() to apply the designβs process-side settings.
For separators and gas scrubbers, getWallThickness() returns metres and
setCorrosionAllowance(double) takes millimetres. Outside diameter is inner diameter plus
twice the wall thickness. Changing the pressure basis, corrosion allowance or process flow
requires recalculating the design before consuming its geometry or weights. The existing
pressure-code correlations and empirical weight estimates are unchanged; this consistency
fix does not add fabrication details or code certification.
Gas-liquid contactor capacity
The mechanical design attached to PackedColumn, AbsorptionColumn, StrippingColumn, and
DistillationColumn is a DistillationColumnMechanicalDesign. After the process column has
converged, it can rate a fixed vessel or size new internals and expose the controlling utilization
through ContactorCapacityResult.
For packed brownfield contactors, configure the actual diameter, packing flood target, optional
vendor-supported relative capacity factor, outlet demister database subtype, and maximum pressure
drop. The result and toJson() include Fs, packing or tray flood, wetting status, demister
Souders-Brown K-factor, pressure drop, overall utilization, estimated gas headroom, and bottleneck.
comparePackedInternals(...) holds vessel diameter and process conditions fixed while screening a
candidate packing and demister. See Absorbers and Strippers
for the executable TEG contactor example and the correlation limitations.
Declared design conditions and units
DesignConditions stores data-sheet declarations separately from calculated sizing results. Legacy
single-argument setters retain their documented canonical units: pressure in bara, temperature in
degrees Celsius, and corrosion allowance in mm. Unit-aware overloads should be preferred for new
code:
DesignConditions conditions = separator.getDesignConditions();
conditions.setDesignPressure(1450.38, "psia");
conditions.setMaxDesignTemperature(250.0, "F");
conditions.setMinDesignTemperature(-50.0, "C");
conditions.setReliefSetPressure(100.0, "barg");
conditions.setCorrosionAllowance(0.125, "in");
double designPressureBara = conditions.getDesignPressure("bara");
double maximumTemperatureC = conditions.getMaxDesignTemperature("C");
DesignConditionValue adds an immutable typed representation for pressure, temperature, and length
conditions. DesignConditions.getCondition(type) and getConditions() expose typed defensive
snapshots. Values are converted to the conditionβs canonical unit on creation, invalid units fail
closed, and physically impossible pressure, temperature, or corrosion values are rejected.
System-Wide Mechanical Design
// Build a process system
ProcessSystem process = new ProcessSystem();
process.add(inlet);
process.add(separator);
process.add(gasStream);
process.add(compressor);
process.add(cooler);
process.add(outlet);
process.run();
// Create system mechanical design
SystemMechanicalDesign sysMecDesign = new SystemMechanicalDesign(process);
// Set company standards for all equipment
sysMecDesign.setCompanySpecificDesignStandards("Equinor");
// Prefer the structured API so partial system totals cannot be mistaken for complete results
SystemMechanicalDesignResult calculation =
sysMecDesign.calculate(SystemDesignExecutionMode.BEST_EFFORT);
if (!calculation.isComplete()) {
for (EquipmentDesignOutcome outcome : calculation.getEquipmentOutcomes()) {
if (outcome.getStatus() == EquipmentDesignOutcome.Status.FAILED) {
logger.error("Design failed for {}: {}", outcome.getEquipmentName(), outcome.getMessage());
}
}
}
// The aggregate is cached on the ProcessSystem and survives copy/serialization
boolean calculated = sysMecDesign.hasRunDesignCalculation();
long revision = sysMecDesign.getDesignCalculationRevision();
// Access aggregated results
double totalWeight = sysMecDesign.getTotalWeight(); // kg
double totalVolume = sysMecDesign.getTotalVolume(); // mΒ³
double plotSpace = sysMecDesign.getTotalPlotSpace(); // mΒ²
double powerRequired = sysMecDesign.getTotalPowerRequired(); // kW
double heatingDuty = sysMecDesign.getTotalHeatingDuty(); // kW
double coolingDuty = sysMecDesign.getTotalCoolingDuty(); // kW
// Get breakdowns
Map<String, Double> weightByType = sysMecDesign.getWeightByEquipmentType();
Map<String, Double> weightByDiscipline = sysMecDesign.getWeightByDiscipline();
Map<String, Integer> countByType = sysMecDesign.getEquipmentCountByType();
// Print summary report
System.out.println(sysMecDesign.generateSummaryReport());
System-wide calculation reuses each equipmentβs current MechanicalDesign object. Standards,
limits, and sizing inputs configured before the call are therefore preserved. Repeated calls
replace the aggregate totals instead of accumulating them and increment the calculation revision.
The system-level result is serialized with ProcessSystem, including its equipment summaries and
breakdowns. Collection getters return defensive snapshots, so modifying a returned summary does not
alter the stored design state.
calculate(BEST_EFFORT) continues with independent equipment after a calculation error and returns
an immutable outcome for every item. Aggregate weights, dimensions, and utilities then contain only
successfully calculated equipment, and isComplete() is false. calculate(FAIL_FAST) stops on the
first failure and throws SystemMechanicalDesignException; getPartialResult() preserves the
calculated, failed, and skipped outcomes. Exception class and message are included in the serialized
result, while stack traces remain in the application log. The legacy runDesignCalculation() method
retains best-effort behavior for source compatibility; inspect getLastCalculationResult() before
using its aggregates.
JSON Export
Exporting Individual Equipment
// Calculate design
separator.getMechanicalDesign().calcDesign();
// Export to JSON
String json = separator.getMechanicalDesign().toJson();
// Example output:
/*
{
"name": "V-100",
"equipmentType": "Separator",
"equipmentClass": "Separator",
"designStandard": "ASME VIII / API 12J",
"isSystemLevel": false,
"totalWeight": 15420.5,
"vesselWeight": 8500.0,
"internalsWeight": 1200.0,
"pipingWeight": 2100.0,
"eiWeight": 1500.0,
"structuralWeight": 2120.5,
"maxDesignPressure": 55.0,
"maxDesignTemperature": 80.0,
"innerDiameter": 2.4,
"tangentLength": 7.2,
"wallThickness": 0.0285,
"wallThicknessUnit": "m",
"moduleLength": 10.0,
"moduleWidth": 5.0,
"moduleHeight": 4.5,
...
}
*/
JSON for 3D geometry and design calculations
Use toDesignDataJson() on any mechanical design for the versioned, unit-labelled
contract. The same snapshot is included as designData in response-based
toJson() exports. The dedicated method also works for equipment with its own
legacy exporter. Run the process and calcDesign() after changing inputs, then
export; exporting does not run calculations or change the equipment.
// After running the process:
MechanicalDesign design = separator.getMechanicalDesign();
design.calcDesign();
String designDataJson = design.toDesignDataJson();
java.nio.file.Files.write(java.nio.file.Paths.get("separator-design.json"),
designDataJson.getBytes(java.nio.charset.StandardCharsets.UTF_8));
The contract has schemaVersion: "1.0". Every numeric quantity inside geometry,
operatingConditions and designBasis has value, unit, source and status.
Lengths use m, absolute pressures Pa, temperatures K, power/duty W,
mass flow kg/s, area m2, conductance W/K, and efficiency 1.
Unavailable or non-finite values are JSON null with status unavailable.
available means a finite getter value is present; it does not establish
calculation completion, freshness, compliance or fabrication readiness.
calculationStatus is explicitly not_tracked. Configured operating/design limits
are marked configured_or_default and kept separate from live stream conditions.
| Equipment | Legacy getWallThickness() / JSON unit |
Normalized geometry and calculation interpretation |
|---|---|---|
| Separator, absorber | m | Sized cylindrical shell; orientation from process owner; head type/profile unavailable |
| Compressor | m | Envelope gap, not pressure-casing thickness; pressureCasingWallThickness and pressureCasingInnerDiameter come separately from the casing calculator |
| Heat exchanger, heater/cooler | m | Selected sizing envelope; an equivalent diameter does not imply a cylindrical exchanger |
| Pump | mm | Casing envelope, impeller and shaft sizes converted to m |
| Pipeline/riser | mm | Geometry uses the pipeβs specified ID/thickness/length; designBasis.designWallThickness preserves the design getter separately (minimum sizing result after calcDesign) |
| Valve | m | Envelope; face-to-face, body thickness and stem getters use mm where documented |
| Distillation column | mm | Column envelope; height exported separately |
| Filter, adsorber | m | Getter dimensions exported with the diameter/thickness consistency check |
| Membrane | mm | Getter dimensions converted; detailed housing layout is not inferred |
| Other design classes | Unqualified | Thickness is unavailable in normalized output until its unit contract is qualified |
Existing getter numeric units remain unchanged. Legacy response JSON now declares
wallThicknessUnit; for example separator wallThickness = 0.0285 m, whereas
its explicitly millimetre-valued shellThickness = 28.5 mm. Compressor and pump
impeller/shaft legacy fields remain mm. Previously unpopulated floating-point
response fields use Double.NaN in the Java DTO and now serialize as null, and non-finite nested calculator values
also become null in response-based exports. Compact and pretty response exports
have the same fields. Legacy zero counts/false flags are not a completeness test;
consume the versioned contract for geometry automation.
Compressor inlet/outlet pressures and efficiencies come from the live compressor, not the design envelope defaults. Compressor, pump and valve maximum design pressure/temperature fields use their own calculation results. Heat-exchanger exports now use their specialized response, selected type, required area and thermal coefficient. Shell dimensions are populated only for a shell-and-tube selection. No head thickness or product geometry is invented when its source is absent.
geometryConsistency checks whether positive finite ID, OD and thickness satisfy
OD = ID + 2t. It is consistent, inconsistent or incomplete. This checks
geometric arithmetic only, not pressure-code adequacy. Correct an inconsistent
source design before meshing it. A missing head type is expected: the separator
model does not specify a fabrication head profile.
Compressor snapshots also expose impellerSizingFeasible and impellerSizingIssues.
Check these before using impeller dimensions: diameter, shaft speed, tip speed,
equal-stage head and inlet flow coefficient are screened together. An infeasible
candidate retains its head-based dimensions even outside the sizing limits; shell
geometryConsistency does not qualify it. The unit-labelled designBasis includes
the sizing speed (rpm), tip speed (m/s), inlet flow coefficient, head per stage
(J/kg) and stage count. See Compressor Mechanical Design
for the assumptions and limits. These checks do not establish aerodynamic or
fabrication qualification.
An invalid compressor sizing attempt clears the previous envelope, shaft, rotor, weight and layout results. Their JSON quantities are unavailable instead of retaining values from an earlier successful run, and the casing calculation is absent.
The runnable JSON-to-mesh example
uses trimesh and rejects missing units, unavailable dimensions and inconsistent
shell geometry. With the JSON above saved as separator-design.json:
python -m pip install trimesh numpy
python examples/mechanical_design_json_to_mesh.py separator-design.json separator-shell.stl
# For a compressor, pump or exchanger plot-space envelope:
python examples/mechanical_design_json_to_mesh.py compressor-design.json compressor-skid.glb --mode envelope
The shell mesh is an open-ended tube wall, without heads, nozzles or supports.
Horizontal vessels have their axis along X; vertical vessels along Z. The example
checks watertightness of the wall solid and its mesh volume against
pi * (OD^2 - ID^2) * tangentLength / 4. The STL/GLB sidecar retains metre units,
source design data, bounds, representation and the volume error. STL itself does
not encode units. Envelope mode creates a plot-space box including access
allowances, so its volume must not be interpreted as metal volume or used for mass.
For design calculations, retain the JSONβs sources and statuses alongside each result. Wall-metal volume times a separately specified material density gives a shell-only mass estimate. Pressure-thickness or hoop-stress calculations also need an explicitly selected pressure differential, material allowable stress, joint factor, corrosion allowance and applicable design method. Absolute operating pressure is not automatically the pressure differential across a wall. Existing mechanical/casing calculators remain the source of their design results; a CAD mesh is not a substitute for those calculations or a fabrication drawing.
The regression test MechanicalDesignJsonContractTest runs the equipment, checks
getter/JSON values and unit conversions, preserves configured limits across
reruns, checks missing values, and writes separator/compressor JSON fixtures for
the mesh example under target/design-json/.
Exporting System-Wide Design
SystemMechanicalDesign sysMecDesign = new SystemMechanicalDesign(process);
sysMecDesign.runDesignCalculation();
String json = sysMecDesign.toJson();
// Example output:
/*
{
"isSystemLevel": true,
"processName": "Gas Processing Unit",
"equipmentCount": 12,
"totalWeight": 185000.0,
"totalVolume": 450.5,
"totalPlotSpace": 1200.0,
"totalPowerRequired": 2500.0,
"totalPowerRecovered": 150.0,
"netPower": 2350.0,
"totalHeatingDuty": 500.0,
"totalCoolingDuty": 1800.0,
"footprintLength": 40.0,
"footprintWidth": 30.0,
"maxHeight": 15.0,
"weightByType": {
"Separator": 45000.0,
"Compressor": 85000.0,
"HeatExchanger": 25000.0,
"Valve": 5000.0,
"Pump": 12000.0,
"Other": 13000.0
},
"weightByDiscipline": {
"Mechanical": 120000.0,
"Piping": 35000.0,
"E&I": 18000.0,
"Structural": 12000.0
},
"equipmentList": [
{
"name": "V-100",
"type": "Separator",
"weight": 15420.5,
"designPressure": 55.0,
"designTemperature": 80.0,
"power": 0.0,
"duty": 0.0,
"dimensions": "ID 2.4m x TT 7.2m"
},
...
]
}
*/
Comprehensive Mechanical Design Report (JSON)
The MechanicalDesignReport class provides a combined JSON output that includes all mechanical design data for a process system, similar to how Report.generateJsonReport() works for process simulation:
// Create comprehensive mechanical design report
MechanicalDesignReport mechReport = new MechanicalDesignReport(process);
mechReport.runDesignCalculations();
// Generate combined JSON with all mechanical design data
String json = mechReport.toJson();
// Write to file
mechReport.writeJsonReport("mechanical_design_report.json");
// Example output structure:
/*
{
"processName": "Gas Processing Unit",
"reportType": "MechanicalDesignReport",
"generatedAt": "2026-01-11T10:30:00Z",
"systemSummary": {
"totalEquipmentWeight_kg": 185000.0,
"totalPipingWeight_kg": 35000.0,
"totalWeight_kg": 220000.0,
"totalVolume_m3": 450.5,
"totalPlotSpace_m2": 1200.0,
"equipmentCount": 12
},
"utilityRequirements": {
"totalPowerRequired_kW": 2500.0,
"totalPowerRecovered_kW": 150.0,
"netPowerRequirement_kW": 2350.0,
"totalHeatingDuty_kW": 500.0,
"totalCoolingDuty_kW": 1800.0
},
"weightByEquipmentType": {
"Separator": 45000.0,
"Compressor": 85000.0,
"HeatExchanger": 25000.0,
"Valve": 5000.0,
"Pump": 12000.0
},
"weightByDiscipline": {
"Mechanical": 120000.0,
"Piping": 35000.0,
"E&I": 18000.0,
"Structural": 12000.0
},
"equipment": [
{
"name": "V-100",
"type": "Separator",
"mechanicalDesign": {
"designPressure": 55.0,
"designTemperature": 80.0,
"wallThickness": 0.0285,
"wallThicknessUnit": "m",
"weight": 15420.5,
...
}
},
...
],
"pipingDesign": {
"totalLength_m": 450.0,
"totalWeight_kg": 35000.0,
"valveWeight_kg": 8500.0,
"flangeWeight_kg": 4200.0,
"fittingWeight_kg": 3100.0,
"weightBySize": {
"4 inch": 5200.0,
"6 inch": 8400.0,
"8 inch": 12300.0,
...
},
"pipeSegments": [
{
"fromEquipment": "V-100",
"toEquipment": "K-100",
"nominalSizeInch": 8.0,
"outsideDiameter_mm": 219.1,
"wallThickness_mm": 8.18,
"schedule": "40",
"length_m": 25.0,
"weight_kg": 1050.0,
"designPressure_bara": 55.0,
"material": "A106-B",
"isGasService": true
},
...
]
}
}
*/
Comparison: Process Simulation vs Mechanical Design JSON
| Use Case | Class | Method |
|---|---|---|
| Process simulation results | Report |
generateJsonReport() |
| System mechanical design only | SystemMechanicalDesign |
toJson() |
| Complete mechanical design with piping | MechanicalDesignReport |
toJson() |
The MechanicalDesignReport.toJson() method provides the most comprehensive output, combining:
- System-level aggregation from
SystemMechanicalDesign - Individual equipment mechanical design data
- Piping interconnection design from
ProcessInterconnectionDesign
Using Specialized Response Classes
For equipment-specific data, use the typed response:
// Compressor-specific response
CompressorMechanicalDesignResponse response =
(CompressorMechanicalDesignResponse) compressor.getMechanicalDesign().getResponse();
int stages = response.getNumberOfStages();
double impellerDiameter = response.getImpellerDiameter(); // mm
double tipSpeed = response.getTipSpeed(); // m/s
double driverPower = response.getDriverPower(); // kW
double tripSpeed = response.getTripSpeed(); // rpm
// Valve-specific response
ValveMechanicalDesignResponse valveResponse =
(ValveMechanicalDesignResponse) valve.getMechanicalDesign().getResponse();
int ansiClass = valveResponse.getAnsiPressureClass();
double cvRequired = valveResponse.getCvRequired();
double cvMax = valveResponse.getCvMax();
double trimUtilization = valveResponse.getTrimCvUtilization();
boolean trimFeasible = valveResponse.isTrimFeasible();
double faceToFace = valveResponse.getFaceToFace(); // mm
String valveType = valveResponse.getValveType();
Round-Trip Parsing
// Export to JSON
String json = sysMecDesign.toJson();
// Parse back to object
MechanicalDesignResponse parsed = MechanicalDesignResponse.fromJson(json);
// Access parsed data
double weight = parsed.getTotalWeight();
boolean isSystem = parsed.isSystemLevel();
Merging with Process Data
// Get mechanical design response
MechanicalDesignResponse mecResponse = sysMecDesign.getResponse();
// Get process simulation JSON
String processJson = process.toJson();
// Merge into combined document
String combined = mecResponse.mergeWithEquipmentJson(processJson);
// Result has both "processData" and "mechanicalDesign" sections
Process Design Parameters
Process design parameters define the sizing basis and validation limits for equipment per industry standards. These parameters can be loaded from the database or set manually.
Loading from Database
// Load company-specific process design standards
separator.getMechanicalDesign().setCompanySpecificDesignStandards("MyCompany");
separator.getMechanicalDesign().loadProcessDesignParameters(); // Loads from TechnicalRequirements_Process table
Equipment Process Design Parameters
Separator Process Design Parameters
| Parameter | Method | Unit | Typical Range | Description |
|---|---|---|---|---|
| Foam allowance factor | getFoamAllowanceFactor() |
- | 1.0-1.5 | Liquid level increase due to foaming |
| Gas-liquid droplet diameter | getDropletDiameterGasLiquid() |
ΞΌm | 100-150 | Design droplet size for gas-liquid separation |
| Liquid-liquid droplet diameter | getDropletDiameterLiquidLiquid() |
ΞΌm | 300-500 | Design droplet size for liquid-liquid separation |
| Maximum gas velocity | getMaxGasVelocityLimit() |
m/s | 2.0-4.0 | Upper limit for gas velocity |
| Maximum liquid velocity | getMaxLiquidVelocity() |
m/s | 0.5-1.5 | Upper limit for liquid outlet velocity |
| Minimum oil retention time | getMinOilRetentionTime() |
min | 2.0-5.0 | Minimum oil residence time |
| Minimum water retention time | getMinWaterRetentionTime() |
min | 3.0-10.0 | Minimum water residence time |
| Demister pressure drop | getDemisterPressureDrop() |
mbar | 1.0-3.0 | Design pressure drop across mist eliminator |
| Demister void fraction | getDemisterVoidFraction() |
- | 0.97-0.99 | Wire mesh demister void fraction |
| Design pressure margin | getDesignPressureMargin() |
- | 1.05-1.15 | Factor above max operating pressure |
Compressor Process Design Parameters
| Parameter | Method | Unit | Typical Range | Description |
|---|---|---|---|---|
| Surge margin | getSurgeMarginPercent() |
% | 10-20 | Minimum margin from surge line |
| Stonewall margin | getStonewallMarginPercent() |
% | 10-15 | Minimum margin from stonewall |
| Minimum turndown | getTurndownPercent() |
% | 60-80 | Minimum operating flow as % of design |
| Target polytropic efficiency | getTargetPolytropicEfficiency() |
% | 75-85 | Design efficiency target |
| Maximum discharge temperature | getMaxDischargeTemperatureC() |
Β°C | 150-180 | Material/process limit |
| Maximum pressure ratio per stage | getMaxPressureRatioPerStage() |
- | 2.5-3.5 | Single stage limit |
| Maximum vibration | getMaxVibrationMmPerSec() |
mm/s | 2.0-4.0 | Unfiltered vibration limit |
| Seal type | getSealType() |
- | - | Dry gas, oil film, labyrinth |
| Bearing type | getBearingType() |
- | - | Tilting pad, plain, magnetic |
Pump Process Design Parameters (API-610)
| Parameter | Method | Unit | Typical Range | Description |
|---|---|---|---|---|
| NPSH margin factor | getNpshMarginFactor() |
- | 1.1-1.3 | NPSHa / NPSHr requirement |
| Hydraulic power margin | getHydraulicPowerMargin() |
- | 1.05-1.15 | Driver sizing margin |
| POR low fraction | getPorLowFraction() |
- | 0.70 | Preferred Operating Region low limit (of BEP) |
| POR high fraction | getPorHighFraction() |
- | 1.20 | Preferred Operating Region high limit (of BEP) |
| AOR low fraction | getAorLowFraction() |
- | 0.60-0.70 | Allowable Operating Region low limit |
| AOR high fraction | getAorHighFraction() |
- | 1.20-1.30 | Allowable Operating Region high limit |
| Maximum suction specific speed | getMaxSuctionSpecificSpeed() |
- | 8000-13000 | Nss limit for stable operation |
| Head margin factor | getHeadMarginFactor() |
- | 1.05-1.10 | Head design margin |
Heat Exchanger Process Design Parameters (TEMA)
| Parameter | Method | Unit | Typical Range | Description |
|---|---|---|---|---|
| Shell fouling resistance (HC) | getFoulingResistanceShellHC() |
mΒ²K/W | 0.00018-0.00053 | Hydrocarbon service |
| Tube fouling resistance (HC) | getFoulingResistanceTubeHC() |
mΒ²K/W | 0.00018-0.00053 | Hydrocarbon service |
| Shell fouling resistance (water) | getFoulingResistanceShellWater() |
mΒ²K/W | 0.00009-0.00035 | Water service |
| Tube fouling resistance (water) | getFoulingResistanceTubeWater() |
mΒ²K/W | 0.00009-0.00035 | Water service |
| Maximum tube velocity | getMaxTubeVelocity() |
m/s | 2.0-4.0 | Erosion limit |
| Minimum tube velocity | getMinTubeVelocity() |
m/s | 0.5-1.0 | Fouling prevention |
| Maximum shell velocity | getMaxShellVelocity() |
m/s | 1.5-3.0 | Vibration/erosion limit |
| Minimum approach temperature | getMinApproachTemperatureC() |
Β°C | 5-15 | Heat exchanger pinch |
| Maximum tube length | getMaxTubeLengthM() |
m | 3.0-9.0 | Physical/mechanical limit |
| TEMA class | getTemaClass() |
- | R, C, B | Equipment class designation |
Design Validation
The mechanical design framework includes validation methods to verify designs against process requirements and industry standards. Each equipment class provides both individual parameter validation and comprehensive design validation.
Validation Result Classes
Each equipment type has a validation result class that collects issues:
// Separator validation
SeparatorMechanicalDesign.SeparatorValidationResult result = sepDesign.validateDesignComprehensive();
if (!result.isValid()) {
for (String issue : result.getIssues()) {
System.out.println("Issue: " + issue);
}
}
// Compressor validation
CompressorMechanicalDesign.CompressorValidationResult result = compDesign.validateDesign();
// Pump validation
PumpMechanicalDesign.PumpValidationResult result = pumpDesign.validateDesign();
// Heat exchanger validation
HeatExchangerMechanicalDesign.HeatExchangerValidationResult result = hxDesign.validateDesign();
Individual Parameter Validation
Separator Validation Methods
SeparatorMechanicalDesign sepDesign = (SeparatorMechanicalDesign) separator.getMechanicalDesign();
// Validate gas velocity
boolean gasVelOk = sepDesign.validateGasVelocity(actualVelocity); // m/s
// Validate liquid velocity
boolean liqVelOk = sepDesign.validateLiquidVelocity(actualVelocity); // m/s
// Validate retention time (isOil = true for oil, false for water)
boolean retTimeOk = sepDesign.validateRetentionTime(actualMinutes, isOil);
// Validate droplet diameter (isGasLiquid = true for gas-liquid separation)
boolean dropletOk = sepDesign.validateDropletDiameter(actualDiameterUm, isGasLiquid);
Compressor Validation Methods
CompressorMechanicalDesign compDesign = compressor.getMechanicalDesign();
// Validate polytropic efficiency (value as percentage, e.g., 78.0 for 78%)
boolean effOk = compDesign.validateEfficiency(actualEfficiencyPercent);
// Validate discharge temperature
boolean tempOk = compDesign.validateDischargeTemperature(actualTempC);
// Validate pressure ratio per stage
boolean prOk = compDesign.validatePressureRatioPerStage(actualPressureRatio);
// Validate vibration
boolean vibOk = compDesign.validateVibration(actualVibrationMmPerSec);
Pump Validation Methods
PumpMechanicalDesign pumpDesign = pump.getMechanicalDesign();
// Validate NPSH margin
boolean npshOk = pumpDesign.validateNpshMargin(npshAvailable, npshRequired);
// Validate operating in Preferred Operating Region
boolean porOk = pumpDesign.validateOperatingInPOR(operatingFlow, bepFlow);
// Validate operating in Allowable Operating Region
boolean aorOk = pumpDesign.validateOperatingInAOR(operatingFlow, bepFlow);
// Validate suction specific speed
boolean nssOk = pumpDesign.validateSuctionSpecificSpeed(actualNss);
Heat Exchanger Validation Methods
HeatExchangerMechanicalDesign hxDesign = heatExchanger.getMechanicalDesign();
// Validate tube velocity (must be between min and max)
boolean tubeVelOk = hxDesign.validateTubeVelocity(actualVelocity);
// Validate shell velocity
boolean shellVelOk = hxDesign.validateShellVelocity(actualVelocity);
// Validate approach temperature
boolean approachOk = hxDesign.validateApproachTemperature(actualApproachC);
// Validate tube length
boolean lengthOk = hxDesign.validateTubeLength(actualLengthM);
Comprehensive Validation Example
// Run equipment
separator.run();
separator.getMechanicalDesign().calcDesign();
// Comprehensive validation
SeparatorMechanicalDesign sepDesign = (SeparatorMechanicalDesign) separator.getMechanicalDesign();
SeparatorMechanicalDesign.SeparatorValidationResult result = sepDesign.validateDesignComprehensive();
System.out.println("Design valid: " + result.isValid());
System.out.println("Issues found: " + result.getIssues().size());
for (String issue : result.getIssues()) {
System.out.println(" - " + issue);
}
// Example output:
// Design valid: false
// Issues found: 2
// - Gas velocity 3.50 m/s exceeds maximum 3.00 m/s
// - L/D ratio 7.5 outside recommended range 2.0-6.0
Equipment-Specific Design Standards
Separators (API 12J / ASME VIII / NORSOK P-001)
SeparatorMechanicalDesign sepDesign =
(SeparatorMechanicalDesign) separator.getMechanicalDesign();
// Key parameters
double gasLoadFactor = sepDesign.getGasLoadFactor(); // K-factor
double retentionTime = sepDesign.getRetentionTime(); // seconds
double liquidLevelFraction = sepDesign.getFg(); // Fg factor
// Process design parameters
double foamFactor = sepDesign.getFoamAllowanceFactor();
double maxGasVel = sepDesign.getMaxGasVelocityLimit();
double minOilRetention = sepDesign.getMinOilRetentionTime(); // minutes
Design calculations include:
- Gas capacity based on Souders-Brown equation
- Liquid retention time requirements
- Vessel L/D optimization
- Demister sizing with pressure drop calculation
- Nozzle sizing per API RP 14E
- Foam allowance for foaming services
Compressors (API 617)
CompressorMechanicalDesign compDesign =
(CompressorMechanicalDesign) compressor.getMechanicalDesign();
// Key parameters
int stages = compDesign.getNumberOfStages();
double headPerStage = compDesign.getHeadPerStage(); // kJ/kg
double impellerDia = compDesign.getImpellerDiameter(); // mm
double tipSpeed = compDesign.getTipSpeed(); // m/s
double driverPower = compDesign.getDriverPower(); // kW
// Process design parameters
double surgeMargin = compDesign.getSurgeMarginPercent();
double stonewallMargin = compDesign.getStonewallMarginPercent();
double turndown = compDesign.getTurndownPercent();
double targetEff = compDesign.getTargetPolytropicEfficiency();
double maxDischargeTemp = compDesign.getMaxDischargeTemperatureC();
String sealType = compDesign.getSealType();
String bearingType = compDesign.getBearingType();
Design calculations include:
- Number of stages based on max head per stage (30 kJ/kg typical)
- Impeller sizing based on flow coefficient
- Driver margin per API 617 (10-25% depending on power)
- Casing type selection (barrel vs split)
- Rotordynamic estimates (critical speeds)
- Surge/stonewall margin verification
- Discharge temperature limit checking
Pumps (API 610)
PumpMechanicalDesign pumpDesign =
(PumpMechanicalDesign) pump.getMechanicalDesign();
pumpDesign.setApi610PumpType(PumpApi610DesignCalculator.Api610PumpType.OH2);
pumpDesign.setMaximumSuctionPressure(8.0); // bara, purchaser maximum
pumpDesign.setFurnishedCasingMawp(25.0); // bara, vendor value
pumpDesign.calcDesign();
// Key parameters
double specificSpeed = pumpDesign.getSpecificSpeed();
double npshRequired = pumpDesign.getNpshRequired(); // m
double impellerDia = pumpDesign.getImpellerDiameter(); // mm
double driverPower = pumpDesign.getDriverPower(); // kW
// Process design parameters
double npshMarginFactor = pumpDesign.getNpshMarginFactor();
double porLow = pumpDesign.getPorLowFraction(); // Preferred Operating Region
double porHigh = pumpDesign.getPorHighFraction();
double aorLow = pumpDesign.getAorLowFraction(); // Allowable Operating Region
double aorHigh = pumpDesign.getAorHighFraction();
double maxNss = pumpDesign.getMaxSuctionSpecificSpeed();
double headMargin = pumpDesign.getHeadMarginFactor();
// Structured API 610 screening result
PumpApi610DesignCalculator api610 = pumpDesign.getApi610Assessment();
PumpApi610DesignCalculator.AssessmentStatus status = api610.getAssessmentStatus();
List<PumpApi610DesignCalculator.Check> checks = api610.getChecks();
Design calculations include:
- Exact API 610 construction type (OH1-OH6, BB1-BB5 or VS1-VS7), supplied by the purchaser or preliminarily recommended
- Impeller sizing from affinity laws
- Speed-aware vendor BEP, shutoff-head and NPSHr ingestion
- Rated-point, POR and AOR screening relative to vendor BEP
- NPSH head and ratio margin verification
- Maximum-discharge-pressure, furnished MAWP and preliminary hydrotest-pressure screening
- Driver selection without double-counting pump efficiency
- ISO 281 rolling-element bearing life when vendor bearing load data are supplied
- Vendor-evidence checks for shaft deflection, critical speed, nozzle loads and vibration
The result is an API 610 13th-edition engineering screen, not a certificate of conformity. Checks that require vendor
geometry, loads, analysis or test data return NOT_EVALUATED until those data are provided. Project criteria and the
purchased standard remain governing.
Valves (IEC 60534)
ValveMechanicalDesign valveDesign =
(ValveMechanicalDesign) valve.getMechanicalDesign();
// Key parameters
double cvMax = valveDesign.getValveCvMax();
double requiredCv = valveDesign.getRequiredCv();
int ansiClass = valveDesign.getAnsiPressureClass();
double faceToFace = valveDesign.getFaceToFace(); // mm
double actuatorThrust = valveDesign.getRequiredActuatorThrust(); // N
Design calculations include:
- Cv/Kv sizing per IEC 60534
- Explicit vendor trim catalogs with relative trim size, maximum design Cv, utilization, margin, and feasibility
- Material/construction provenance for severe-service trims without unsupported generic derating factors
- ANSI pressure class selection
- Body sizing and wall thickness
- Actuator sizing
- Face-to-face dimensions per ANSI/ISA
Heat Exchangers (TEMA)
HeatExchangerMechanicalDesign hxDesign =
(HeatExchangerMechanicalDesign) heatExchanger.getMechanicalDesign();
// Key parameters
double area = hxDesign.getHeatTransferArea(); // mΒ²
double uValue = hxDesign.getOverallHeatTransferCoefficient(); // W/mΒ²K
int tubeCount = hxDesign.getTubeCount();
double shellDiameter = hxDesign.getShellDiameter(); // mm
// Process design parameters
double shellFouling = hxDesign.getFoulingResistanceShellHC(); // mΒ²K/W
double tubeFouling = hxDesign.getFoulingResistanceTubeHC(); // mΒ²K/W
double maxTubeVel = hxDesign.getMaxTubeVelocity(); // m/s
double minTubeVel = hxDesign.getMinTubeVelocity(); // m/s
double maxShellVel = hxDesign.getMaxShellVelocity(); // m/s
double minApproach = hxDesign.getMinApproachTemperatureC(); // Β°C
double maxTubeLength = hxDesign.getMaxTubeLengthM(); // m
String temaClass = hxDesign.getTemaClass(); // "R", "C", or "B"
// Calculate clean and fouled U-values
double cleanU = hxDesign.calculateCleanU(shellHTC, tubeHTC, wallThickness, conductivity);
double fouledU = hxDesign.calculateFouledU(cleanU, shellIsWater, tubeIsWater);
Design calculations include:
- Heat transfer area calculation with fouling allowance
- Tube count and layout per TEMA standards
- Shell diameter sizing
- Baffle spacing optimization
- Pressure drop verification
- Velocity limits for erosion/fouling prevention
- Approach temperature validation
- TEMA class (R, C, B) specification
Tanks (API 650/620)
Design calculations include:
- Shell course thickness
- Bottom plate sizing
- Roof type selection
- Wind/seismic loads
- Foundation requirements
API 2000 venting is a separate process-safety interface, not part of the API 650/620 shell screen. Use the API 2000 tank-venting guide for the exact 7th-edition caller-controlled normal/emergency demand and rated-capacity screen. Vent-demand derivation, detailed device sizing, and tank construction acceptance remain external.
Weight Breakdown Categories
By Equipment Type
- Separator
- Compressor
- Pump
- Valve
- HeatExchanger
- Tank
- Expander
- Pipeline
- Other
By Discipline
- Mechanical - Vessel shells, rotating equipment, internals
- Piping - Process piping, valves, fittings
- E&I - Electrical, instrumentation, control systems
- Structural - Steel supports, platforms, ladders
Design Margins
The framework applies industry-standard margins:
| Parameter | Margin | Standard |
|---|---|---|
| Design Pressure | +10% above max operating | ASME VIII |
| Design Temperature | +30Β°C above max operating | ASME VIII |
| Driver Power (small) | +25% for < 22 kW | API 610/617 |
| Driver Power (medium) | +15% for 22-75 kW | API 610/617 |
| Driver Power (large) | +10% for > 75 kW | API 610/617 |
| Wall Thickness | +CA (corrosion allowance) | ASME VIII |
Integration with Cost Estimation
Each mechanical design class has an associated cost estimation class in neqsim.process.costestimation:
// Access cost estimate from mechanical design
UnitCostEstimateBaseClass costEstimate = mecDesign.getCostEstimate();
double equipmentCost = costEstimate.getEquipmentCost(); // USD
double installedCost = costEstimate.getInstalledCost(); // USD
Comprehensive Cost Estimation Framework
For detailed cost estimation including OPEX, financial metrics, currency conversion, and location factors, see the dedicated cost estimation documentation:
| Document | Description |
|---|---|
| COST_ESTIMATION_FRAMEWORK.md | Comprehensive guide to capital and operating cost estimation |
| COST_ESTIMATION_API_REFERENCE.md | Detailed API reference for all cost estimation classes |
Key Features:
- Equipment costs using Turton et al., Peters & Timmerhaus, GPSA correlations
- 14+ equipment types (separators, compressors, heat exchangers, tanks, expanders, ejectors, absorbers, etc.)
- Multi-currency support (USD, EUR, NOK, GBP, CNY, JPY)
- Location factors for 11 global regions
- Operating cost (OPEX) calculation with utility costs
- Financial metrics (payback period, ROI, NPV)
- Process-level cost aggregation with
ProcessCostEstimate
// Example: Process-level cost estimation
ProcessCostEstimate processCost = new ProcessCostEstimate(process);
// Set location and currency
processCost.setLocationByRegion("North Sea");
processCost.setCurrency("NOK");
// Calculate costs
processCost.calculateCosts();
// Get results in selected currency
double totalCAPEX = processCost.getTotalCapitalCost(); // NOK
double totalOPEX = processCost.calculateOperatingCost(8760); // NOK/year
// Export comprehensive JSON report
String json = processCost.toJson();
Best Practices
-
Always run equipment before calculating design - The mechanical design uses process conditions from the simulation.
-
Set design standards early - Call
setCompanySpecificDesignStandards()beforecalcDesign(). -
Use system-level design for complete estimates -
SystemMechanicalDesignhandles all equipment consistently. -
Export JSON for documentation - The
toJson()method provides comprehensive, structured output. -
Verify critical parameters - Check that design pressure/temperature exceed operating conditions.
Example: Complete Workflow
// 1. Create fluid system
SystemInterface fluid = new SystemSrkEos(298.0, 50.0);
fluid.addComponent("methane", 0.85);
fluid.addComponent("ethane", 0.10);
fluid.addComponent("propane", 0.05);
fluid.setMixingRule("classic");
// 2. Build process
Stream feed = new Stream("feed", fluid);
feed.setFlowRate(50000.0, "kg/hr");
Separator separator = new Separator("V-100", feed);
Stream gas = new Stream("gas", separator.getGasOutStream());
Compressor compressor = new Compressor("K-100", gas);
compressor.setOutletPressure(80.0, "bara");
Cooler cooler = new Cooler("E-100", compressor.getOutletStream());
cooler.setOutTemperature(40.0, "C");
ProcessSystem process = new ProcessSystem();
process.add(feed);
process.add(separator);
process.add(gas);
process.add(compressor);
process.add(cooler);
process.run();
// 3. Calculate mechanical design
SystemMechanicalDesign sysMecDesign = new SystemMechanicalDesign(process);
sysMecDesign.setCompanySpecificDesignStandards("Equinor");
sysMecDesign.runDesignCalculation();
// 4. Generate reports
System.out.println(sysMecDesign.generateSummaryReport());
// 5. Export JSON for documentation/integration
String json = sysMecDesign.toJson();
Files.write(Paths.get("mechanical_design.json"), json.getBytes());
// 6. Access specific equipment details
CompressorMechanicalDesignResponse compResponse =
(CompressorMechanicalDesignResponse) compressor.getMechanicalDesign().getResponse();
System.out.println("Compressor stages: " + compResponse.getNumberOfStages());
System.out.println("Driver power: " + compResponse.getDriverPower() + " kW");