graph-based process simulation functionality by EvenSol · Pull Request #1770 · equinor/neqsim

Pull Request: Graph-Based Process Representation

Summary

Adds graph-based process representation to NeqSim, enabling automatic dependency analysis, optimized execution order, and parallel simulation of independent equipment and process systems.

New Features

  • ProcessGraph - Represents process flowsheets as directed acyclic graphs (DAGs)
  • Topological sorting - Automatic calculation order based on stream dependencies
  • Parallel execution - Run independent equipment concurrently via runParallel()
  • Automatic optimization - runOptimal() selects best execution strategy
  • Cycle detection - Identifies recycle loops using Tarjan's SCC algorithm
  • Graph validation - Detects orphan nodes, missing connections, and configuration issues
  • ProcessModule parallel analysis - Analyze which ProcessSystems can run in parallel

New Classes

  • ProcessGraph - Core graph with analysis algorithms
  • ProcessNode - Equipment wrapper with dependency tracking
  • ProcessEdge - Stream connection between equipment
  • ProcessGraphBuilder - Auto-builds graph from ProcessSystem
  • ProcessModelGraph - Hierarchical graph for ProcessModule (multi-system analysis)
  • ProcessModelGraphBuilder - Builds graphs for ProcessModule with inter-system connection detection

ProcessSystem Enhancements

process.buildGraph()                    // Build dependency graph
process.runParallel()                   // Parallel execution
process.runOptimal()                    // Auto-select best strategy
process.isParallelExecutionBeneficial() // Check parallelization potential

ProcessModule Parallel Analysis

ProcessModule module = new ProcessModule("Plant");
module.add(trainA);  // ProcessSystem
module.add(trainB);  // ProcessSystem
module.add(trainC);  // ProcessSystem

ProcessModelGraph modelGraph = module.buildModelGraph();

// Check if sub-systems can run in parallel
modelGraph.isParallelSubSystemExecutionBeneficial()  // true if >= 2 parallel

// Get parallel execution partition
ModuleParallelPartition partition = modelGraph.partitionSubSystemsForParallelExecution();
partition.getLevelCount()      // Number of execution levels
partition.getMaxParallelism()  // Max systems that can run concurrently
partition.getLevelNames()      // Sub-system names at each level

// Get dependencies between sub-systems
Map<String, Set<String>> deps = modelGraph.getSubSystemDependencies();

Example Output

For a diamond pattern (Feed → [TrainA, TrainB] → Merge):

Parallel Execution Analysis:
Parallel beneficial: true
Execution levels: 3
Max parallelism: 2
  Level 0: Feed System
  Level 1: Train A, Train B [parallel]
  Level 2: Merge System

Supported Equipment

All TwoPortInterface equipment plus special handling for:

  • Splitter / Mixer
  • Manifold (N inputs → M outputs)
  • Separator (gas + liquid outlets)
  • ThreePhaseSeparator (gas + oil + aqueous outlets)
  • HeatExchanger (2 streams)
  • MultiStreamHeatExchanger
  • TurboExpanderCompressor

Performance

~1.4x speedup for processes with 4+ independent branches using parallel execution.

Tests

48 tests covering graph construction, topological sort, parallel execution, cycle detection, complex process scenarios, and ProcessModule parallel analysis.