Skip to the content.

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:

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:

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:

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:

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:

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:

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:

Tanks (API 650/620)

Design calculations include:

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

By Discipline

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:

// 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

  1. Always run equipment before calculating design - The mechanical design uses process conditions from the simulation.

  2. Set design standards early - Call setCompanySpecificDesignStandards() before calcDesign().

  3. Use system-level design for complete estimates - SystemMechanicalDesign handles all equipment consistently.

  4. Export JSON for documentation - The toJson() method provides comprehensive, structured output.

  5. 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");

See Also