Class ProcessSystem

All Implemented Interfaces:
Serializable, Runnable, SimulationInterface, NamedInterface

public class ProcessSystem extends SimulationBaseClass
Represents a process system containing unit operations.
Author:
esol
See Also:
  • Field Details

    • serialVersionUID

      private static final long serialVersionUID
      Serialization version UID.
      See Also:
    • logger

      static org.apache.logging.log4j.Logger logger
      Logger object for class.
    • thisThread

      transient Thread thisThread
    • measurementHistory

      private ProcessSystem.MeasurementHistory measurementHistory
    • surroundingTemperature

      private double surroundingTemperature
    • timeStepNumber

      private int timeStepNumber
    • unitOperations

      private List<ProcessEquipmentInterface> unitOperations
      List of unit operations in the process system.
    • measurementDevices

      List<MeasurementDeviceInterface> measurementDevices
    • controllerDevices

      List<ControllerDeviceInterface> controllerDevices
    • connections

      private List<ProcessConnection> connections
    • alarmManager

      private ProcessAlarmManager alarmManager
    • recycleController

      RecycleController recycleController
    • timeStep

      private double timeStep
    • runStep

      private boolean runStep
    • equipmentCounter

      private final Map<String,Integer> equipmentCounter
    • lastAddedUnit

      private ProcessEquipmentInterface lastAddedUnit
    • initialStateSnapshot

      private transient ProcessSystem initialStateSnapshot
    • massBalanceErrorThreshold

      private double massBalanceErrorThreshold
    • minimumFlowForMassBalanceError

      private double minimumFlowForMassBalanceError
    • maxTransientIterations

      private int maxTransientIterations
    • enableMassBalanceTracking

      private boolean enableMassBalanceTracking
    • previousTotalMass

      private double previousTotalMass
    • massBalanceError

      private double massBalanceError
    • integrationMethod

      private ProcessSystem.IntegrationMethod integrationMethod
      Integration method used in runTransient. Default is explicit Euler.
    • adaptiveTimestepEnabled

      private boolean adaptiveTimestepEnabled
      Whether adaptive timestep control is enabled.
    • minTimestep

      private double minTimestep
      Minimum allowed timestep in seconds for adaptive control.
    • maxTimestep

      private double maxTimestep
      Maximum allowed timestep in seconds for adaptive control.
    • adaptiveTimestepTolerance

      private double adaptiveTimestepTolerance
      Relative tolerance for adaptive timestep error control.
    • parallelTransientEnabled

      private boolean parallelTransientEnabled
      Whether multi-threaded equipment execution is enabled for transient steps.
    • transientThreadPoolSize

      private int transientThreadPoolSize
      Thread pool size for parallel transient execution.
    • cachedGraph

      private transient ProcessGraph cachedGraph
      Cached process graph for topology analysis.
    • graphDirty

      private boolean graphDirty
      Flag indicating if the cached graph needs to be rebuilt.
    • cachedParallelPlan

      private transient List<List<List<ProcessNode>>> cachedParallelPlan
      Cached parallel execution plan: grouped nodes per level for runParallel().
    • cachedHasAdjusters

      private transient Boolean cachedHasAdjusters
      Cached result of hasAdjusters() - null means not yet computed.
    • cachedHasRecycles

      private transient Boolean cachedHasRecycles
      Cached result of hasRecycles() - null means not yet computed.
    • cachedHasCalculators

      private transient Boolean cachedHasCalculators
      Cached result of hasCalculators() - null means not yet computed.
    • cachedHasMultiInput

      private transient Boolean cachedHasMultiInput
      Cached result of hasMultiInputEquipment() - null means not yet computed.
    • DATAFLOW_UNIT_THRESHOLD

      private static final int DATAFLOW_UNIT_THRESHOLD
      Minimum number of units required for dataflow scheduling (vs level-based parallel) in runOptimized(UUID). Below this threshold the CompletableFuture overhead outweighs the straggler-elimination benefit.
      See Also:
    • useGraphBasedExecution

      private boolean useGraphBasedExecution
      Whether to use graph-based execution order instead of insertion order.
    • useOptimizedExecution

      private boolean useOptimizedExecution
      Whether to use optimized execution (parallel/hybrid) by default when run() is called. When true, run() delegates to runOptimized() which automatically selects the best strategy. When false, run() uses sequential execution in insertion order (legacy behavior). Default is true for optimal performance - runOptimized() automatically falls back to sequential execution for processes with multi-input equipment (mixers, heat exchangers, etc.) to preserve correct mass balance.
    • progressListener

      private transient ProcessSystem.SimulationProgressListener progressListener
      Transient listener for simulation progress callbacks. Used for real-time visualization in Jupyter notebooks and digital twin dashboards. Marked transient to avoid serialization issues.
    • publishEvents

      private boolean publishEvents
      When true, lifecycle events are published to the ProcessEventBus singleton during simulation. Default is false for zero overhead when not needed. Enable via setPublishEvents(true).
    • autoValidate

      private boolean autoValidate
      When true, validateSetup() is auto-invoked on each equipment unit before the first iteration. Validation warnings are logged but do not abort execution. Enable via setAutoValidate(true).
    • useFlashWarmStart

      private boolean useFlashWarmStart
      When true, the iterative TPflash inside every fluid evaluation re-uses the previously converged K-values as a warm start instead of seeding from Wilson on every call. This is applied via ThermodynamicModelSettings.setUseWarmStartKValues(true) for the duration of run(java.util.UUID) and restored afterwards (try/finally), so flowsheet-level usage does not leak into other code on the same thread. Default is false (historical behaviour) — recycle-heavy flowsheets are sensitive to flash trajectory and warm-start can shift the converged fixed point. Opt in via setUseFlashWarmStart(boolean) for 10–20% wall-time reduction on flowsheets that re-flash near-identical conditions.
    • profilingEnabled

      private transient boolean profilingEnabled
      When true, per-unit execution timing is recorded during simulation. After run() completes, call getExecutionProfile() to retrieve a map from equipment name to cumulative execution time in milliseconds. Enable via setProfilingEnabled(boolean).
    • executionTimingNanos

      private transient Map<String,long[]> executionTimingNanos
      Stores cumulative execution time per equipment unit in nanoseconds. Keyed by equipment name. Populated during simulation when profilingEnabled is true.
    • lastRunElapsedNanos

      private transient long lastRunElapsedNanos
      Stores the total elapsed wall-clock time of the last run() call in nanoseconds.
    • systemMechanicalDesign

      private transient SystemMechanicalDesign systemMechanicalDesign
      System-level mechanical design (lazy initialized).
    • processCostEstimate

      private transient ProcessCostEstimate processCostEstimate
      Process-level cost estimate (lazy initialized).
  • Constructor Details

    • ProcessSystem

      public ProcessSystem()

      Constructor for ProcessSystem.

    • ProcessSystem

      public ProcessSystem(String name)
      Constructor for ProcessSystem.
      Parameters:
      name - name of process
  • Method Details

    • add

      public void add(ProcessEquipmentInterface operation)

      Add to end.

      Parameters:
      operation - a ProcessEquipmentInterface object
    • add

      public void add(int position, ProcessEquipmentInterface operation)

      Add to specific position.

      Parameters:
      position - 0-based position
      operation - a ProcessEquipmentInterface object
    • add

      public void add(MeasurementDeviceInterface measurementDevice)

      Add measurementdevice.

      Parameters:
      measurementDevice - a MeasurementDeviceInterface object
    • add

      public void add(ControllerDeviceInterface controllerDevice)
      Add a standalone controller device to the process system. Controllers added here participate in the explicit controller scan during runTransient.
      Parameters:
      controllerDevice - a ControllerDeviceInterface object
    • getAllElements

      public List<ProcessElementInterface> getAllElements()
      Returns an unmodifiable list of all process elements — equipment, measurement devices, and controllers — registered in this system.
      Returns:
      list of all ProcessElementInterface objects
    • getMeasurementDevices

      public List<MeasurementDeviceInterface> getMeasurementDevices()
      Returns the list of measurement devices registered in this process system.
      Returns:
      list of MeasurementDeviceInterface objects
    • getControllerDevices

      public List<ControllerDeviceInterface> getControllerDevices()
      Returns the list of controller devices registered in this process system.
      Returns:
      list of ControllerDeviceInterface objects
    • connect

      public void connect(String sourceEquipment, String sourcePort, String targetEquipment, String targetPort, ProcessConnection.ConnectionType type)
      Declares an explicit connection between two equipment ports. This is a metadata record; it does not create or wire stream objects. Interchange formats like DEXPI and topology analyses can query the connection list via getConnections().
      Parameters:
      sourceEquipment - name of upstream equipment
      sourcePort - port name on source (e.g. "gasOut")
      targetEquipment - name of downstream equipment
      targetPort - port name on target (e.g. "inlet")
      type - connection type
    • connect

      public void connect(String sourceEquipment, String targetEquipment)
      Declares a material connection between two equipment ports with default port names.
      Parameters:
      sourceEquipment - name of upstream equipment
      targetEquipment - name of downstream equipment
    • getConnections

      public List<ProcessConnection> getConnections()
      Returns an unmodifiable view of the declared connections.
      Returns:
      unmodifiable list of ProcessConnection objects
    • add

      public void add(ProcessEquipmentInterface[] operations)

      Add multiple process equipment to end.

      Parameters:
      operations - an array of ProcessEquipmentInterface objects
    • replaceUnit

      public boolean replaceUnit(String name, ProcessEquipmentInterface newObject)

      Replace a unitoperation.

      Parameters:
      name - Name of the object to replace
      newObject - the object to replace it with
      Returns:
      a Boolean object
    • getUnit

      public ProcessEquipmentInterface getUnit(String name)

      Get process equipmen by name.

      Parameters:
      name - Name of
      Returns:
      a ProcessEquipmentInterface object
    • getUnitByReferenceDesignation

      public ProcessEquipmentInterface getUnitByReferenceDesignation(String refDesignation)
      Looks up a process equipment unit by its IEC 81346 reference designation string (e.g. "=A1.B1", "-B1").
      Parameters:
      refDesignation - the reference designation string to match
      Returns:
      the matching equipment, or null if not found
    • generateReferenceDesignations

      public ReferenceDesignationGenerator generateReferenceDesignations(String functionPrefix, String locationPrefix)
      Generates IEC 81346 reference designations for all equipment in this process system. This is a convenience wrapper around ReferenceDesignationGenerator.
      Parameters:
      functionPrefix - the function-aspect prefix (e.g. "A1" for the first process area)
      locationPrefix - the location-aspect prefix (e.g. "G1" for a specific platform)
      Returns:
      the generator instance (for further queries such as toJson())
    • hasUnitName

      public boolean hasUnitName(String name)

      hasUnitName.

      Parameters:
      name - a String object
      Returns:
      a boolean
    • getMeasurementDevice

      public MeasurementDeviceInterface getMeasurementDevice(String name)

      Get MeasureDevice by name.

      Parameters:
      name - Name of measurement device
      Returns:
      a MeasurementDeviceInterface object
    • getMeasurementDeviceByTag

      public MeasurementDeviceInterface getMeasurementDeviceByTag(String tag)
      Look up a measurement device by its instrument tag. Tags are assigned via MeasurementDeviceInterface.setTag(String) and typically correspond to plant historian signal identifiers (e.g. "PT-101", "TT-201").
      Parameters:
      tag - the instrument tag to search for
      Returns:
      the matching device, or null if no device carries the given tag
    • getMeasurementDevicesByRole

      public List<MeasurementDeviceInterface> getMeasurementDevicesByRole(InstrumentTagRole role)
      Returns all measurement devices that have the specified InstrumentTagRole.
      Parameters:
      role - the tag role to filter on
      Returns:
      unmodifiable list of matching devices (may be empty)
    • setFieldData

      public void setFieldData(Map<String,Double> fieldData)
      Sets field data values on measurement devices identified by their instrument tags. Devices with role INPUT will push the values into the model via MeasurementDeviceInterface.applyFieldValue().
      Parameters:
      fieldData - map of instrument tag to field value
    • applyFieldInputs

      public void applyFieldInputs()
      Applies field values from all INPUT instruments to their connected streams or equipment. Call this before running the process to push field boundary conditions into the model.
    • getBenchmarkDeviations

      public Map<String,Double> getBenchmarkDeviations()
      Returns a map of instrument tag to deviation (model minus field) for all BENCHMARK instruments that have field data. Useful for model validation and parameter optimisation.
      Returns:
      map of tag to deviation value
    • getUnitNumber

      public int getUnitNumber(String name)

      getUnitNumber.

      Parameters:
      name - a String object
      Returns:
      a int
    • replaceObject

      public void replaceObject(String unitName, ProcessEquipmentBaseClass operation)

      replaceObject.

      Parameters:
      unitName - a String object
      operation - a ProcessEquipmentBaseClass object
    • getAllUnitNames

      public ArrayList<String> getAllUnitNames()

      getAllUnitNames.

      Returns:
      a ArrayList object
    • getUnitOperations

      public List<ProcessEquipmentInterface> getUnitOperations()

      Gets the list of unit operations.

      Returns:
      the list of unit operations
    • validateSetup

      public ValidationResult validateSetup()
      Validates the process system setup before execution.

      This method validates:

      • The process system has at least one unit operation
      • Each unit operation passes its own validateSetup() check
      • Feed streams are defined
      • Equipment names are unique (warning)
      Returns:
      validation result with errors and warnings for all equipment
    • validateAll

      public Map<String, ValidationResult> validateAll()
      Validates all equipment in the process system and returns individual results.

      Unlike validateSetup() which returns a combined result, this method returns a map of equipment names to their individual validation results, making it easier to identify specific issues.

      Returns:
      map of equipment names to their validation results
    • isReadyToRun

      public boolean isReadyToRun()
      Checks if the process system is ready to run.

      Convenience method that returns true if validateSetup() finds no critical errors.

      Returns:
      true if process system passes validation, false otherwise
    • validateAndReport

      public SimulationResult validateAndReport()
      Validates the process setup and returns a structured SimulationResult.

      Converts ValidationResult issues into SimulationResult.ErrorDetail objects for web API consumption. Returns a success result if no critical errors are found.

      Returns:
      a SimulationResult with validation errors or success status
    • runAndReport

      public SimulationResult runAndReport()
      Runs the process system and returns a structured SimulationResult.

      Validates the setup first, then runs the simulation. Returns a structured result containing the full JSON report on success, or detailed errors on failure. Designed for web API integration.

      Returns:
      a SimulationResult with the simulation report or errors
    • removeUnit

      public void removeUnit(String name)

      removeUnit.

      Parameters:
      name - a String object
    • clearAll

      public void clearAll()

      clearAll.

    • clear

      public void clear()

      clear.

    • setFluid

      public void setFluid(SystemInterface fluid1, SystemInterface fluid2, boolean addNewComponents)

      setFluid.

      Parameters:
      fluid1 - a SystemInterface object
      fluid2 - a SystemInterface object
      addNewComponents - a boolean
    • setFluid

      public void setFluid(SystemInterface fluid1, SystemInterface fluid2)

      setFluid.

      Parameters:
      fluid1 - a SystemInterface object
      fluid2 - a SystemInterface object
    • runAsTask

      public Future<?> runAsTask()
      Runs this process in a separate thread using the global NeqSim thread pool.

      This method submits the process to the shared NeqSimThreadPool and returns a Future that can be used to monitor completion, cancel the task, or retrieve any exceptions that occurred.

      Returns:
      a Future representing the pending completion of the task
      See Also:
    • runOptimized

      public void runOptimized()
      Runs the process system using the optimal execution strategy based on topology analysis.

      This method automatically selects the best execution mode:

      • For processes WITHOUT recycles: uses parallel execution for maximum speed
      • For processes WITH recycles: uses graph-based execution with optimized ordering

      This is the recommended method for most use cases as it provides the best performance without requiring manual configuration.

    • runOptimized

      public void runOptimized(UUID id)
      Runs the process system using the optimal execution strategy based on topology analysis.

      This method automatically selects the best execution mode:

      • For processes with adjusters: sequential execution (adjusters modify upstream variables and read downstream targets, creating implicit feedback loops)
      • For processes with recycles (no adjusters): sequential execution for full convergence
      • For processes with multi-input equipment (Mixer, Manifold, HeatExchanger, etc.): sequential execution to ensure correct mass balance
      • For simple feed-forward processes: parallel execution for maximum speed
      Parameters:
      id - calculation identifier for tracking
    • hasAdjusters

      public boolean hasAdjusters()
      Checks if the process contains any Adjuster units that require iterative convergence.
      Returns:
      true if there are Adjuster units in the process
    • hasCalculators

      public boolean hasCalculators()
      Checks if the process contains any Calculator units.

      Calculator units read input streams and write to an output stream property using signal connections rather than physical stream connections. They create implicit feedback loops that the graph-based partitioner does not detect, so parallel execution cannot place them correctly.

      Returns:
      true if there are any Calculator units in the process
    • hasRecycles

      public boolean hasRecycles()
      Checks if the process contains any Recycle units.

      This method directly checks for Recycle units in the process, which is more reliable than graph-based cycle detection for determining if iterative execution is needed.

      Returns:
      true if there are Recycle units in the process
    • hasMultiInputEquipment

      public boolean hasMultiInputEquipment()
      Checks if the process contains any multi-input equipment.

      Multi-input equipment (Mixer, Manifold, TurboExpanderCompressor, Ejector, HeatExchanger, MultiStreamHeatExchanger) require sequential execution to ensure correct mass balance. Parallel execution can change the order in which input streams are processed, leading to incorrect results.

      Returns:
      true if there are multi-input equipment units in the process
    • isMultiInputNode

      private boolean isMultiInputNode(ProcessNode node)
      Returns true if the given graph node represents multi-input equipment. Used by groupNodesBySharedInputStreams(List) to decide whether shared-stream consumers need to be serialised within a group.
      Parameters:
      node - the graph node
      Returns:
      true if the underlying equipment has 2+ inlet streams or is one of the class-based multi-input types
    • runHybrid

      public void runHybrid(UUID id) throws InterruptedException
      Runs the process using hybrid execution strategy.

      This method partitions the process into:

      • Feed-forward section: Units at the beginning with no recycle dependencies - run in parallel
      • Recycle section: Units that are part of or depend on recycle loops - run with graph-based iteration
      Parameters:
      id - calculation identifier for tracking
      Throws:
      InterruptedException - if thread is interrupted during parallel execution
    • getExecutionStrategyExplanation

      public String getExecutionStrategyExplanation()
      Explains why runOptimized() chose a particular execution strategy.

      Useful for agents or developers who expect full parallel execution and want to know which specific unit(s) forced sequential or hybrid mode. Returns a multi-line string with the selected strategy and the equipment blocking higher parallelism (if any).

      Returns:
      human-readable explanation of the chosen execution strategy
    • appendUnitList

      private void appendUnitList(StringBuilder sb, String label, List<String> names)
      Appends a labelled unit list to a builder if non-empty.
      Parameters:
      sb - target builder
      label - label prefix
      names - unit names
    • isMultiInputUnit

      private boolean isMultiInputUnit(ProcessEquipmentInterface unit)
      Class-based or inlet-count-based multi-input check for a single unit.
      Parameters:
      unit - equipment instance
      Returns:
      true if the unit is multi-input
    • getExecutionPartitionInfo

      public String getExecutionPartitionInfo()
      Gets a description of how the process will be partitioned for execution.

      This method analyzes the process topology and returns information about:

      • Whether the process has recycle loops
      • Number of parallel execution levels
      • Maximum parallelism achievable
      • Which units are in recycle loops
      Returns:
      description of the execution partitioning
    • runParallel

      public void runParallel() throws InterruptedException
      Runs the process system using parallel execution for independent equipment.

      This method uses the process graph to identify equipment that can run in parallel (i.e., equipment with no dependencies between them). Equipment at the same "level" in the dependency graph are executed concurrently using the NeqSim thread pool.

      Note: This method does not handle recycles or adjusters - use regular SimulationInterface.run() for processes with recycle loops. This is suitable for feed-forward processes where maximum parallelism is desired.

      Throws:
      InterruptedException - if the thread is interrupted while waiting for tasks
    • runParallel

      public void runParallel(UUID id) throws InterruptedException
      Runs the process system using parallel execution for independent equipment.

      This method uses the process graph to identify equipment that can run in parallel (i.e., equipment with no dependencies between them). Equipment at the same "level" in the dependency graph are executed concurrently using the NeqSim thread pool.

      Parameters:
      id - calculation identifier for tracking
      Throws:
      InterruptedException - if the thread is interrupted while waiting for tasks
    • runDataflow

      public void runDataflow(UUID id) throws InterruptedException
      Runs the process using dataflow scheduling.

      Unlike runParallel(UUID) which uses level barriers, this method fires each unit (or shared-input group) as soon as its direct predecessors have completed. Eliminates straggler penalty on wide asymmetric flowsheets where a slow unit on one branch currently delays unrelated units on other branches.

      Safety contract is identical to runParallel(UUID):

      Parameters:
      id - calculation identifier for tracking
      Throws:
      InterruptedException - if the thread is interrupted while waiting for dataflow completion
    • groupNodesBySharedInputStreams

      private List<List<ProcessNode>> groupNodesBySharedInputStreams(List<ProcessNode> nodes)
      Groups nodes by shared input streams for parallel execution safety.

      Units that share the same input stream cannot safely run in parallel because they would concurrently read from the same thermo system. This method uses Union-Find to group nodes that share any input stream, so they can be run sequentially within their group while different groups run in parallel.

      Parameters:
      nodes - list of nodes at the same execution level
      Returns:
      list of groups, where each group contains nodes that share input streams
    • getParallelPartition

      public ProcessGraph.ParallelPartition getParallelPartition()
      Gets the parallel execution partition for this process.

      This method returns information about how the process can be parallelized, including: - The number of parallel levels - Maximum parallelism (max units that can run concurrently) - Which units are at each level

      Returns:
      parallel partition result, or null if graph cannot be built
    • isParallelExecutionBeneficial

      public boolean isParallelExecutionBeneficial()
      Checks if parallel execution would be beneficial for this process.

      Parallel execution is considered beneficial when:

      • There are at least 2 units that can run in parallel (maxParallelism >= 2)
      • The process has no recycle loops (which require iterative sequential execution)
      • There are enough units to justify thread overhead (typically > 4 units)
      Returns:
      true if parallel execution is recommended
    • runOptimal

      public void runOptimal()
      Runs the process using the optimal execution strategy.

      This method automatically determines whether to use parallel or sequential execution based on the process structure. It will use parallel execution if:

      • The process has independent branches that can benefit from parallelism
      • There are no recycle loops or adjusters requiring iterative execution
      • The process is large enough to justify the thread management overhead

      For processes with recycles or adjusters, this method falls back to the standard sequential SimulationInterface.run() method which properly handles convergence iterations.

    • runOptimal

      public void runOptimal(UUID id)
      Runs the process using the optimal execution strategy with calculation ID tracking.
      Parameters:
      id - calculation identifier for tracking
      See Also:
    • runAsThread

      @Deprecated public Thread runAsThread()
      Deprecated.
      Use runAsTask() instead for better resource management. This method creates a new unmanaged thread directly.

      runAsThread.

      Returns:
      a Thread object
    • run

      public void run(UUID id)

      In this method all thermodynamic and unit operations will be calculated in a steady state calculation.

      Parameters:
      id - UUID
    • runSequential

      public void runSequential(UUID id)
      Runs the process system using sequential execution.

      This method executes units in insertion order (or topological order if useGraphBasedExecution is enabled). It handles recycle loops by iterating until convergence. This is the legacy execution mode preserved for backward compatibility.

      Parameters:
      id - calculation identifier for tracking
    • run_step

      public void run_step(UUID id)

      run_step

      In this method all thermodynamic and unit operations will be calculated in a steady state calculation. Sets calc identifier UUID. It does not solve recycles - only calculates one step
      Parameters:
      id - Calc identifier UUID to set.
    • setProgressListener

      public void setProgressListener(ProcessSystem.SimulationProgressListener listener)
      Set a listener to receive progress updates during simulation. Useful for real-time visualization in Jupyter notebooks and digital twin dashboards.

      Example usage in Python/Jupyter:

      class MyListener(ProcessSystem.SimulationProgressListener):
          def onUnitComplete(self, unit, index, total, iteration):
              print(f"Completed {unit.getName()} ({index+1}/{total})")
      
      process.setProgressListener(MyListener())
      process.run()
      
      Parameters:
      listener - the progress listener, or null to disable callbacks
    • getProgressListener

      public ProcessSystem.SimulationProgressListener getProgressListener()
      Get the current progress listener.
      Returns:
      the current listener, or null if none is set
    • setPublishEvents

      public void setPublishEvents(boolean publish)
      Enables or disables event publishing to the ProcessEventBus singleton. When enabled, lifecycle events (simulation start/complete, unit errors, threshold crossings) are published to the event bus during steady-state and transient execution.
      Parameters:
      publish - true to enable event publishing, false to disable (default)
    • isPublishEvents

      public boolean isPublishEvents()
      Returns whether event publishing is enabled.
      Returns:
      true if events are published to ProcessEventBus during simulation
    • setAutoValidate

      public void setAutoValidate(boolean validate)
      Enables or disables automatic equipment validation before the first simulation iteration. When enabled, validateSetup() is called on each equipment unit before the first run. Validation failures are logged as warnings but do not abort execution.
      Parameters:
      validate - true to enable auto-validation, false to disable (default)
    • isAutoValidate

      public boolean isAutoValidate()
      Returns whether auto-validation is enabled.
      Returns:
      true if equipment setup is validated before simulation runs
    • setProfilingEnabled

      public void setProfilingEnabled(boolean enabled)
      Enables or disables per-unit execution timing profiling. When enabled, each call to an equipment unit's run() method is timed and accumulated. After simulation completes, use getExecutionProfile() to retrieve timing data and printExecutionProfile() to print it.
      Parameters:
      enabled - true to enable profiling, false to disable (default)
    • isProfilingEnabled

      public boolean isProfilingEnabled()
      Returns whether execution profiling is enabled.
      Returns:
      true if per-unit timing data is being collected
    • getExecutionProfile

      public Map<String,double[]> getExecutionProfile()
      Returns the execution profile from the last simulation run.

      The returned map contains equipment names as keys and arrays of [total_time_ms, call_count] as values. Equipment is sorted by total time descending.

      Returns:
      map from equipment name to [total_time_ms, call_count], or empty map if profiling is disabled
    • getLastRunElapsedMs

      public double getLastRunElapsedMs()
      Returns the total wall-clock elapsed time of the last run() call in milliseconds.
      Returns:
      elapsed time in milliseconds, or 0 if no run has been executed
    • printExecutionProfile

      public void printExecutionProfile()
      Prints the execution profile to System.out in a formatted table.

      Shows each equipment unit's total execution time, percentage of total, and call count. Useful for identifying bottleneck equipment in large process simulations.

    • recordUnitTiming

      private void recordUnitTiming(String unitName, long elapsedNanos)
      Records execution time for a unit operation when profiling is enabled.

      Uses a ConcurrentHashMap and AtomicLong fields on the per-unit timing record to avoid lock contention when multiple units run in parallel. Previously this method used a global synchronized(map) block which serialized all concurrent unit runs and hid real parallel speedup when profiling was enabled.

      Parameters:
      unitName - the name of the equipment unit
      elapsedNanos - the elapsed time in nanoseconds
    • resetExecutionProfile

      private void resetExecutionProfile()
      Resets the execution profile data. Called at the start of each run.
    • runUnitProfiled

      private void runUnitProfiled(ProcessEquipmentInterface unit, UUID id)
      Runs a single equipment unit with optional profiling.
      Parameters:
      unit - the equipment unit to run
      id - the calculation identifier
    • runWithCallback

      public void runWithCallback(Consumer<ProcessEquipmentInterface> callback)
      Run simulation with a simple callback for each completed unit operation. This is a convenience method for Python/Jupyter integration where implementing the full SimulationProgressListener interface may be cumbersome.

      Example usage in Python/Jupyter:

      def on_complete(unit):
          print(f"Completed: {unit.getName()}")
          temp = unit.getOutletStream().getTemperature("C")
          # Update live plot...
      
      process.runWithCallback(on_complete)
      
      Parameters:
      callback - Consumer function called with each completed unit operation. May be null for no callbacks (equivalent to regular run()).
    • runWithCallback

      public void runWithCallback(Consumer<ProcessEquipmentInterface> callback, UUID id)
      Run simulation with a simple callback for each completed unit operation.
      Parameters:
      callback - Consumer function called with each completed unit operation
      id - calculation identifier for tracking
    • runWithProgress

      public void runWithProgress(UUID id)
      Run simulation with full progress monitoring. This method executes the process system and invokes the registered SimulationProgressListener after each unit operation and iteration completes.

      This is the primary method for digital twin applications requiring real-time feedback. It supports:

      • Progress callbacks after each unit operation
      • Iteration callbacks for recycle convergence monitoring
      • Error callbacks with optional continuation
      • Thread interruption handling
      Parameters:
      id - calculation identifier for tracking
    • notifyUnitComplete

      private void notifyUnitComplete(ProcessEquipmentInterface unit, int unitIndex, int totalUnits, int iterationNumber)
      Notify the progress listener that a unit operation has completed.
      Parameters:
      unit - the completed unit
      unitIndex - index of the unit
      totalUnits - total number of units
      iterationNumber - current iteration
    • notifyIterationComplete

      private void notifyIterationComplete(int iterationNumber, boolean converged, double recycleError)
      Notify the progress listener that an iteration has completed.
      Parameters:
      iterationNumber - the completed iteration
      converged - whether the system has converged
      recycleError - maximum recycle error
    • notifyUnitError

      private boolean notifyUnitError(ProcessEquipmentInterface unit, Exception exception)
      Notify the progress listener that a unit operation encountered an error.
      Parameters:
      unit - the unit that failed
      exception - the exception
      Returns:
      true to continue, false to abort
    • notifyBeforeUnit

      private void notifyBeforeUnit(ProcessEquipmentInterface unit, int unitIndex, int totalUnits, int iterationNumber)
      Notify the progress listener that a unit operation is about to start.
      Parameters:
      unit - the unit about to run
      unitIndex - index of the unit
      totalUnits - total number of units
      iterationNumber - current iteration
    • notifyBeforeIteration

      private void notifyBeforeIteration(int iterationNumber)
      Notify the progress listener that an iteration is about to start.
      Parameters:
      iterationNumber - the iteration about to start
    • notifySimulationStart

      private void notifySimulationStart(int totalUnits)
      Notify the progress listener that the simulation is starting.
      Parameters:
      totalUnits - total number of unit operations
    • notifySimulationComplete

      private void notifySimulationComplete(int totalIterations, boolean converged)
      Notify the progress listener that the simulation has completed.
      Parameters:
      totalIterations - total number of iterations executed
      converged - whether the simulation converged
    • publishEvent

      private void publishEvent(ProcessEvent event)
      Publish a process event to the event bus if event publishing is enabled.
      Parameters:
      event - the event to publish
    • runAutoValidation

      private void runAutoValidation(List<ProcessEquipmentInterface> executionOrder)
      Run auto-validation on all equipment units. Called once before the first iteration when autoValidate is enabled.
      Parameters:
      executionOrder - the list of units to validate
    • runTransient

      public void runTransient()

      runTransient.

    • runTransient

      public void runTransient(double dt, UUID id)

      runTransient

      This method calculates thermodynamic and unit operations using difference equations if available and calculateSteadyState is true. Use setCalculateSteadyState to set the parameter. Sets calc identifier UUID.
      Parameters:
      dt - Delta time [s]
      id - Calculation identifier
    • runEquipmentTransientParallel

      private void runEquipmentTransientParallel(double dt, UUID id)
      Runs all equipment transient calculations in parallel using an ExecutorService. Each equipment unit is submitted as an independent task. This is suitable when equipment units are loosely coupled (no data dependencies within a single timestep).
      Parameters:
      dt - time step in seconds
      id - calculation identifier
    • runTransientAdaptive

      public double runTransientAdaptive(double dt, UUID id)
      Runs a single transient step with adaptive timestep control. This method compares a full-step result with two half-step results to estimate the local truncation error and adjusts dt accordingly.

      Usage: call this instead of runTransient(dt, id) when adaptive control is desired.

      Parameters:
      dt - the requested timestep in seconds
      id - calculation identifier
      Returns:
      the actual timestep used (may differ from dt)
    • solved

      public boolean solved()

      Returns whether or not the module has been solved.

      Returns:
      a boolean
    • getTime

      public double getTime()
      Getter for the field time.
      Specified by:
      getTime in interface SimulationInterface
      Overrides:
      getTime in class SimulationBaseClass
      Returns:
      Value of property time.
    • getTime

      public double getTime(String unit)

      Getter for the field time.

      Parameters:
      unit - a String object
      Returns:
      a double
    • calculateTotalSystemMass

      private double calculateTotalSystemMass()
      Calculate total system mass across all equipment and streams.
      Returns:
      Total mass in kg
    • setEnableMassBalanceTracking

      public void setEnableMassBalanceTracking(boolean enable)
      Enable or disable mass balance tracking during transient simulations.
      Parameters:
      enable - true to enable tracking
    • getMassBalanceError

      public double getMassBalanceError()
      Get the current mass balance error percentage.
      Returns:
      Mass balance error in percent
    • setMaxTransientIterations

      public void setMaxTransientIterations(int iterations)
      Set the maximum number of iterations within each transient time step.

      Multiple iterations help converge circular dependencies between equipment. Default is 3. Set to 1 to disable iterative convergence.

      Parameters:
      iterations - Number of iterations (must be >= 1)
    • getMaxTransientIterations

      public int getMaxTransientIterations()
      Get the maximum number of iterations within each transient time step.
      Returns:
      Number of iterations
    • setIntegrationMethod

      public void setIntegrationMethod(ProcessSystem.IntegrationMethod method)
      Sets the integration method for transient simulation.
      Parameters:
      method - the integration method to use
    • getIntegrationMethod

      public ProcessSystem.IntegrationMethod getIntegrationMethod()
      Gets the integration method used for transient simulation.
      Returns:
      the current integration method
    • setAdaptiveTimestepEnabled

      public void setAdaptiveTimestepEnabled(boolean enabled)
      Enables or disables adaptive timestep control. When enabled, the timestep is adjusted based on local error estimates by comparing a full step with two half-steps.
      Parameters:
      enabled - true to enable adaptive timestep
    • isAdaptiveTimestepEnabled

      public boolean isAdaptiveTimestepEnabled()
      Returns whether adaptive timestep control is enabled.
      Returns:
      true if adaptive timestep is enabled
    • setMinTimestep

      public void setMinTimestep(double minDt)
      Sets the minimum timestep for adaptive control.
      Parameters:
      minDt - minimum timestep in seconds
    • getMinTimestep

      public double getMinTimestep()
      Gets the minimum timestep for adaptive control.
      Returns:
      minimum timestep in seconds
    • setMaxTimestep

      public void setMaxTimestep(double maxDt)
      Sets the maximum timestep for adaptive control.
      Parameters:
      maxDt - maximum timestep in seconds
    • getMaxTimestep

      public double getMaxTimestep()
      Gets the maximum timestep for adaptive control.
      Returns:
      maximum timestep in seconds
    • setAdaptiveTimestepTolerance

      public void setAdaptiveTimestepTolerance(double tol)
      Sets the relative tolerance for adaptive timestep error control.
      Parameters:
      tol - relative tolerance (e.g. 0.01 for 1%)
    • getAdaptiveTimestepTolerance

      public double getAdaptiveTimestepTolerance()
      Gets the relative tolerance for adaptive timestep error control.
      Returns:
      relative tolerance
    • setParallelTransientEnabled

      public void setParallelTransientEnabled(boolean enabled)
      Enables or disables multi-threaded equipment execution during transient steps.
      Parameters:
      enabled - true to enable parallel execution
    • isParallelTransientEnabled

      public boolean isParallelTransientEnabled()
      Returns whether parallel transient execution is enabled.
      Returns:
      true if parallel transient is active
    • setTransientThreadPoolSize

      public void setTransientThreadPoolSize(int poolSize)
      Sets the thread pool size for parallel transient execution.
      Parameters:
      poolSize - number of threads
    • getTransientThreadPoolSize

      public int getTransientThreadPoolSize()
      Gets the thread pool size for parallel transient execution.
      Returns:
      number of threads
    • size

      public int size()

      size.

      Returns:
      a int
    • view

      public void view()

      view.

    • displayResult

      public void displayResult()

      displayResult.

    • reportMeasuredValues

      public void reportMeasuredValues()

      reportMeasuredValues.

    • save

      public void save(String filePath)

      save.

      Parameters:
      filePath - a String object
    • open

      public static ProcessSystem open(String filePath)

      open.

      Parameters:
      filePath - a String object
      Returns:
      a ProcessSystem object
    • reportResults

      public String[][] reportResults()

      reportResults.

      Returns:
      an array of String objects
    • getStreamSummaryTable

      public String getStreamSummaryTable()
      Returns a consolidated formatted stream summary table showing key properties for all streams in this process system. Similar to the Workbook/Stream Summary in commercial process simulators.

      The table includes: stream name, temperature (C), pressure (bara), total molar flow (kmole/hr), mass flow (kg/hr), vapor fraction, molar mass (kg/kmol), and mole fraction of each component.

      Returns:
      formatted string table of all stream properties
    • getStreamSummaryJson

      public String getStreamSummaryJson()
      Returns a consolidated stream summary as a JSON string. Each stream is a key in the JSON object containing temperature, pressure, flow rates, vapor fraction, molar mass, and composition.
      Returns:
      JSON string with stream summary data
    • getAllStreams

      public List<StreamInterface> getAllStreams()
      Returns a list of all streams in this process system. Collects all inlet and outlet streams from all equipment, removing duplicates.
      Returns:
      list of unique streams in the process
    • printLogFile

      public void printLogFile(String filename)

      printLogFile.

      Parameters:
      filename - a String object
    • clearHistory

      public void clearHistory()
      Clears all stored transient measurement history entries and resets the time step counter.
    • getHistorySize

      public int getHistorySize()
      Returns the number of stored transient measurement entries.
      Returns:
      number of stored history entries
    • getAlarmManager

      public ProcessAlarmManager getAlarmManager()
      Returns the alarm manager responsible for coordinating alarm evaluation.
      Returns:
      alarm manager
    • getHistorySnapshot

      public String[][] getHistorySnapshot()
      Returns a snapshot of the transient measurement history.
      Returns:
      the measurement history as a two-dimensional array
    • setHistoryCapacity

      public void setHistoryCapacity(int maxEntries)
      Sets the maximum number of entries retained in the measurement history. A value less than or equal to zero disables truncation (unbounded history).
      Parameters:
      maxEntries - maximum number of entries to keep, or non-positive for unlimited
    • getHistoryCapacity

      public int getHistoryCapacity()
      Returns the configured history capacity. A value less than or equal to zero means the history grows without bounds.
      Returns:
      configured maximum number of history entries or non-positive for unlimited
    • storeInitialState

      public void storeInitialState()
      Stores a snapshot of the current process system state that can later be restored with reset().
    • reset

      public void reset()
      Restores the process system to the stored initial state. The initial state is captured automatically the first time a transient run is executed, or manually via storeInitialState().
    • ensureInitialStateSnapshot

      private void ensureInitialStateSnapshot()
    • captureInitialState

      private void captureInitialState(boolean force)
    • applyState

      private void applyState(ProcessSystem source)
    • getTimeStep

      public double getTimeStep()

      Getter for the field timeStep.

      Returns:
      a double
    • setTimeStep

      public void setTimeStep(double timeStep)

      Setter for the field timeStep.

      Parameters:
      timeStep - a double
    • getName

      public String getName()

      Getter for the field name.

      Specified by:
      getName in interface NamedInterface
      Overrides:
      getName in class NamedBaseClass
      Returns:
      a String object
    • setName

      public void setName(String name)

      Setter for the field name.

      Specified by:
      setName in interface NamedInterface
      Overrides:
      setName in class NamedBaseClass
      Parameters:
      name - a String object
    • setRunStep

      public void setRunStep(boolean runStep)
      Setter for the field runStep.
      Parameters:
      runStep - A boolean value if run only one iteration
    • isRunStep

      public boolean isRunStep()
      Getter for the field runStep.
      Returns:
      A boolean value if run only one iteration
    • getEntropyProduction

      public double getEntropyProduction(String unit)
      Sum of the entropy production across all unit operations in this process system. Individual entries are not logged to avoid flooding stdout on large flowsheets; iterate with getUnitOperations() if per-unit detail is required.
      Parameters:
      unit - target unit passed straight through to ProcessEquipmentInterface.getEntropyProduction(String)
      Returns:
      total entropy production
    • getExergyChange

      public double getExergyChange(String unit)
      Net change in stream exergy (outlet minus inlet) aggregated over all unit operations, using this system's surrounding temperature as the dead state. The returned value is in the requested unit (supported values: J, kJ, MJ, W, kW, MW); unknown units fall back to J.
      Parameters:
      unit - energy / power unit of the returned value
      Returns:
      total exergy change across all units in the requested unit
    • getExergyChange

      public double getExergyChange(String unit, double surroundingTemperature)
      Net change in stream exergy aggregated over all unit operations using an explicit surrounding temperature.
      Parameters:
      unit - energy / power unit of the returned value
      surroundingTemperature - dead-state temperature in K
      Returns:
      total exergy change across all units
    • getExergyDestruction

      public double getExergyDestruction(String unit)
      Total exergy destruction rate aggregated over all unit operations, using this system's surrounding temperature.
      Parameters:
      unit - energy / power unit of the returned value
      Returns:
      total exergy destruction in the requested unit
    • getExergyDestruction

      public double getExergyDestruction(String unit, double surroundingTemperature)
      Total exergy destruction rate aggregated over all unit operations using an explicit surrounding temperature.
      Parameters:
      unit - energy / power unit of the returned value
      surroundingTemperature - dead-state temperature in K
      Returns:
      total exergy destruction in the requested unit
    • getExergyAnalysis

      public ExergyAnalysisReport getExergyAnalysis()
      Build a structured ExergyAnalysisReport with one entry per unit operation. Useful for identifying exergy-destruction hot spots on large flowsheets.
      Returns:
      a new report using this system's surrounding temperature
    • getExergyAnalysis

      public ExergyAnalysisReport getExergyAnalysis(double surroundingTemperature)
      Build a structured ExergyAnalysisReport with one entry per unit operation using an explicit dead-state temperature.
      Parameters:
      surroundingTemperature - dead-state temperature in K
      Returns:
      a new report
    • populateExergyAnalysis

      public void populateExergyAnalysis(ExergyAnalysisReport report, double surroundingTemperature, String areaName)
      Populate an existing report with entries for this process system. Intended to be called by ProcessModel.getExergyAnalysis() so that multi-area aggregation keeps area labels on every row.
      Parameters:
      report - report instance to append to
      surroundingTemperature - dead-state temperature in K
      areaName - optional area name tag; may be null
    • convertEnergy

      private static double convertEnergy(double valueJ, String unit)
      Convert a value in Joules to the requested unit.
      Parameters:
      valueJ - value in Joules (or watts, treated identically)
      unit - target unit: J, kJ, MJ, W, kW, MW (unknown falls back to J)
      Returns:
      converted value
    • getPower

      public double getPower(String unit)

      getPower.

      Parameters:
      unit - a String object
      Returns:
      a double
    • getCoolerDuty

      public double getCoolerDuty(String unit)

      getCoolerDuty.

      Parameters:
      unit - a String object
      Returns:
      a double
    • getHeaterDuty

      public double getHeaterDuty(String unit)

      getHeaterDuty.

      Parameters:
      unit - a String object
      Returns:
      a double
    • getSurroundingTemperature

      public double getSurroundingTemperature()

      Getter for the field surroundingTemperature.

      Returns:
      a double
    • setSurroundingTemperature

      public void setSurroundingTemperature(double surroundingTemperature)

      Setter for the field surroundingTemperature.

      Parameters:
      surroundingTemperature - a double
    • copy

      public ProcessSystem copy()

      Create deep copy.

      Returns:
      a ProcessSystem object
    • deepCopy

      private ProcessSystem deepCopy()
    • getConditionMonitor

      public ConditionMonitor getConditionMonitor()

      getConditionMonitor.

      Returns:
      a ConditionMonitor object
    • checkMassBalance

      public Map<String, ProcessSystem.MassBalanceResult> checkMassBalance(String unit)
      Check mass balance of all unit operations in the process system.
      Parameters:
      unit - unit for mass flow rate (e.g., "kg/sec", "kg/hr", "mole/sec")
      Returns:
      a map with unit operation name as key and mass balance result as value
    • checkMassBalance

      public Map<String, ProcessSystem.MassBalanceResult> checkMassBalance()
      Check mass balance of all unit operations in the process system using kg/sec.
      Returns:
      a map with unit operation name as key and mass balance result as value in kg/sec
    • getFailedMassBalance

      public Map<String, ProcessSystem.MassBalanceResult> getFailedMassBalance(String unit, double percentThreshold)
      Get unit operations that failed mass balance check based on percentage error threshold.
      Parameters:
      unit - unit for mass flow rate (e.g., "kg/sec", "kg/hr", "mole/sec")
      percentThreshold - percentage error threshold (default: 0.1%)
      Returns:
      a map with failed unit operation names and their mass balance results
    • getFailedMassBalance

      public Map<String, ProcessSystem.MassBalanceResult> getFailedMassBalance()
      Get unit operations that failed mass balance check using kg/sec and default threshold.
      Returns:
      a map with failed unit operation names and their mass balance results
    • getFailedMassBalance

      public Map<String, ProcessSystem.MassBalanceResult> getFailedMassBalance(double percentThreshold)
      Get unit operations that failed mass balance check using specified threshold.
      Parameters:
      percentThreshold - percentage error threshold
      Returns:
      a map with failed unit operation names and their mass balance results in kg/sec
    • getMassBalanceReport

      public String getMassBalanceReport(String unit)
      Get a formatted mass balance report for this process system.
      Parameters:
      unit - unit for mass flow rate (e.g., "kg/sec", "kg/hr", "mole/sec")
      Returns:
      a formatted string report with mass balance results
    • getMassBalanceReport

      public String getMassBalanceReport()
      Get a formatted mass balance report for this process system using kg/sec.
      Returns:
      a formatted string report with mass balance results
    • getFailedMassBalanceReport

      public String getFailedMassBalanceReport(String unit, double percentThreshold)
      Get a formatted report of failed mass balance checks for this process system.
      Parameters:
      unit - unit for mass flow rate (e.g., "kg/sec", "kg/hr", "mole/sec")
      percentThreshold - percentage error threshold
      Returns:
      a formatted string report with failed unit operations
    • getFailedMassBalanceReport

      public String getFailedMassBalanceReport()
      Get a formatted report of failed mass balance checks for this process system using kg/sec and default threshold.
      Returns:
      a formatted string report with failed unit operations
    • getFailedMassBalanceReport

      public String getFailedMassBalanceReport(double percentThreshold)
      Get a formatted report of failed mass balance checks for this process system using specified threshold.
      Parameters:
      percentThreshold - percentage error threshold
      Returns:
      a formatted string report with failed unit operations in kg/sec
    • setMassBalanceErrorThreshold

      public void setMassBalanceErrorThreshold(double percentThreshold)
      Set the default mass balance error threshold for this process system.
      Parameters:
      percentThreshold - percentage error threshold (e.g., 0.1 for 0.1%)
    • getMassBalanceErrorThreshold

      public double getMassBalanceErrorThreshold()
      Get the default mass balance error threshold for this process system.
      Returns:
      percentage error threshold
    • setMinimumFlowForMassBalanceError

      public void setMinimumFlowForMassBalanceError(double minimumFlow)
      Set the minimum flow threshold for mass balance error checking. Units with inlet flow below this threshold are not considered errors.
      Parameters:
      minimumFlow - minimum flow in kg/sec (e.g., 1e-6)
    • getMinimumFlowForMassBalanceError

      public double getMinimumFlowForMassBalanceError()
      Get the minimum flow threshold for mass balance error checking.
      Returns:
      minimum flow in kg/sec
    • calculateInletFlow

      private double calculateInletFlow(ProcessEquipmentInterface unitOp, String unit)
    • calculatePercentError

      private double calculatePercentError(double massBalanceError, double inletFlow)
    • hashCode

      public int hashCode()
      Overrides:
      hashCode in class Object
    • equals

      public boolean equals(Object obj)
      Overrides:
      equals in class Object
    • getReport_json

      public String getReport_json()

      getReport_json.

      Return results of simulation in json format
      Returns:
      a String
    • addUnit

      public <T extends ProcessEquipmentInterface> T addUnit(String name, String equipmentType)

      addUnit.

      Type Parameters:
      T - a T class
      Parameters:
      name - a String object
      equipmentType - a String object
      Returns:
      a T object
    • addUnit

      public <T extends ProcessEquipmentInterface> T addUnit(String name, EquipmentEnum equipmentEnum)

      addUnit.

      Type Parameters:
      T - a T class
      Parameters:
      name - a String object
      equipmentEnum - a EquipmentEnum object
      Returns:
      a T object
    • addUnit

      public <T extends ProcessEquipmentInterface> T addUnit(String equipmentType)

      addUnit.

      Type Parameters:
      T - a T class
      Parameters:
      equipmentType - a String object
      Returns:
      a T object
    • addUnit

      public <T extends ProcessEquipmentInterface> T addUnit(EquipmentEnum equipmentEnum)

      addUnit.

      Type Parameters:
      T - a T class
      Parameters:
      equipmentEnum - a EquipmentEnum object
      Returns:
      a T object
    • addUnit

      public <T extends ProcessEquipmentInterface> T addUnit(String name, String equipmentType, StreamInterface stream)
      Adds a new process equipment unit of the specified type and name, and sets its inlet stream.
      Type Parameters:
      T - the type of process equipment
      Parameters:
      name - the name of the equipment (if null or empty, a unique name is generated)
      equipmentType - the type of equipment to create (as a String)
      stream - the inlet stream to set for the new equipment
      Returns:
      the created and added process equipment unit
    • addUnit

      public ProcessEquipmentInterface addUnit(String name, ProcessEquipmentInterface equipment)

      addUnit.

      Parameters:
      name - a String object
      equipment - a ProcessEquipmentInterface object
      Returns:
      a ProcessEquipmentInterface object
    • addUnit

      addUnit.

      Parameters:
      equipment - a ProcessEquipmentInterface object
      Returns:
      a ProcessEquipmentInterface object
    • generateUniqueName

      private String generateUniqueName(String equipmentType)
    • autoConnect

      private void autoConnect(ProcessEquipmentInterface fromUnit, ProcessEquipmentInterface toUnit)
    • exportToGraphviz

      public void exportToGraphviz(String filename)

      exportToGraphviz.

      Parameters:
      filename - a String object
    • exportToGraphviz

      public void exportToGraphviz(String filename, ProcessSystemGraphvizExporter.GraphvizExportOptions options)
      Export the process to Graphviz with configurable stream annotations.
      Parameters:
      filename - the Graphviz output file
      options - export options controlling stream annotations and table output
    • loadProcessFromYaml

      public void loadProcessFromYaml(File yamlFile)
      Load a process from a YAML file.
      Parameters:
      yamlFile - the YAML file to load
    • fromJson

      public static SimulationResult fromJson(String json)
      Builds a ProcessSystem from a JSON process definition string.

      This is the primary entry point for web API and Python integration. Accepts a declarative JSON definition of fluids, equipment, and stream connections and returns a structured result with the built ProcessSystem or detailed error information.

      Parameters:
      json - the JSON process definition string
      Returns:
      a SimulationResult containing the built process or errors
      See Also:
    • validateJson

      public static ProcessJsonValidator.ValidationReport validateJson(String json)
    • toJson

      public String toJson()
      Exports this ProcessSystem to the JSON schema consumed by JsonProcessBuilder.

      The exported JSON is round-trippable: the output can be fed back into fromJson(String) to reconstruct an equivalent ProcessSystem. This enables exporting NeqSim process models to external simulators (e.g., UniSim Design via COM automation).

      Returns:
      JSON string representing this process system
      See Also:
    • fromJsonAndRun

      public static SimulationResult fromJsonAndRun(String json)
      Builds and immediately runs a ProcessSystem from a JSON definition.

      Convenience method that combines building and execution in a single call. The result contains the full simulation report JSON.

      Parameters:
      json - the JSON process definition string
      Returns:
      a SimulationResult containing the executed process and report, or errors
      See Also:
    • fromJsonAndRun

      public static SimulationResult fromJsonAndRun(String json, SystemInterface fluid)
      Builds and runs a process simulation from a JSON definition using a pre-built fluid.

      This overload is used when the fluid has been loaded from an external source (e.g., an Eclipse E300 file via EclipseFluidReadWrite) and should be used instead of parsing the fluid section in the JSON. The pre-built fluid preserves all component critical properties (Tc, Pc, acentric factor, MW, BIPs) for both standard and hypothetical/pseudo components.

      Parameters:
      json - the JSON process definition string (the 'fluid' section is ignored)
      fluid - the pre-built thermodynamic system to use
      Returns:
      a SimulationResult containing the executed process and report, or errors
      See Also:
    • resolveStreamReference

      public StreamInterface resolveStreamReference(String ref)
      Resolves a named stream reference within this process system.

      Supports dot-notation for specific outlet ports:

      • "unitName" — default outlet stream
      • "unitName.gasOut" — gas outlet of separator
      • "unitName.liquidOut" — liquid outlet of separator
      • "unitName.outlet" — explicit outlet stream
      Parameters:
      ref - the stream reference (e.g., "feed", "HP Sep.gasOut")
      Returns:
      the resolved StreamInterface, or null if not found
    • wireStream

      public boolean wireStream(String targetUnitName, String sourceRef)
      Wires an inlet stream from a named reference to a target equipment unit.

      Resolves the stream reference by name and connects it to the target unit.

      Parameters:
      targetUnitName - the name of the equipment to wire the inlet to
      sourceRef - the stream reference (e.g., "feed", "HP Sep.gasOut")
      Returns:
      true if wiring succeeded, false if source or target not found
    • getBottleneck

      public ProcessEquipmentInterface getBottleneck()

      getBottleneck.

      Identifies the equipment with the highest capacity utilization. This method checks both:

      Returns:
      a ProcessEquipmentInterface object representing the bottleneck, or null if no equipment has capacity defined
    • getBottleneckUtilization

      public double getBottleneckUtilization()
      Gets the utilization ratio of the bottleneck equipment.
      Returns:
      utilization as fraction (1.0 = 100%), or 0.0 if no bottleneck found
    • buildGraph

      public ProcessGraph buildGraph()
      Builds an explicit graph representation of this process system.

      The graph representation enables:

      • Automatic detection of calculation order (derived from topology, not insertion order)
      • Partitioning for parallel execution
      • AI agents to reason about flowsheet structure
      • Cycle detection for recycle handling
      • Graph neural network compatible representation

      Example usage:

      ProcessSystem system = new ProcessSystem();
      // ... add units ...
      ProcessGraph graph = system.buildGraph();
      
      // Get topology-based calculation order
      List<ProcessEquipmentInterface> order = graph.getCalculationOrder();
      
      // Partition for parallel execution
      ProcessGraph.ParallelPartition partition = graph.partitionForParallelExecution();
      
      Returns:
      the process graph
      See Also:
    • invalidateGraph

      public void invalidateGraph()
      Forces a rebuild of the process graph on next access.

      Use this method when you have made structural changes to the process that the automatic detection may have missed (e.g., modifying stream connections directly).

    • invalidateStructureCaches

      private void invalidateStructureCaches()
      Invalidates all structure-derived caches in a single call. Equivalent to invalidateGraph() but named to reflect the general contract: any mutation of unitOperations (add/remove/replace/clear) MUST call this method. Keeping the invalidation in one place prevents the common bug of adding a new cache field and forgetting to clear it at one of the mutation sites.
    • setRecycleAccelerationMethod

      public int setRecycleAccelerationMethod(AccelerationMethod method)
      Apply an acceleration method to every Recycle unit in this ProcessSystem. Convenience wrapper that avoids iterating and configuring each Recycle individually.

      Wegstein acceleration (see AccelerationMethod.WEGSTEIN) typically reduces outer-loop iteration count by 2-3x on single-variable recycle loops and is a safe default for most flowsheets. Broyden's method is more effective for tightly coupled multi-recycle systems.

      Parameters:
      method - acceleration method to apply (must not be null)
      Returns:
      number of Recycle units updated
    • reorderRecyclesWithinSCCs

      private List<ProcessEquipmentInterface> reorderRecyclesWithinSCCs(List<ProcessEquipmentInterface> iterativeSection)
      Reorder the iterative section so that within each non-trivial SCC the Recycle units appear after their SCC peers. Relative order of non-Recycle units is preserved exactly (stable), and the position of each SCC block relative to units outside the SCC is preserved (anchored at the first member in insertion order).

      This is a safe, conservative refinement of the insertion-order iterative section used by runHybrid(UUID). It only moves Recycle units within their own SCC block, never across SCC boundaries or across non-SCC units, so it cannot change the fixed point of successive substitution. For flowsheets that already follow the common convention of adding Recycle units last, this method is a no-op.

      Parameters:
      iterativeSection - insertion-ordered iterative section
      Returns:
      refined list with recycles moved to end of their SCC block
    • setUseGraphBasedExecution

      public void setUseGraphBasedExecution(boolean useGraphBased)
      Sets whether to use graph-based execution order.

      When enabled, the run() method will execute units in topological order derived from stream connections rather than the order units were added. This can be safer when unit insertion order doesn't match the physical flow.

      Parameters:
      useGraphBased - true to use topological execution order, false to use insertion order
    • isUseGraphBasedExecution

      public boolean isUseGraphBasedExecution()
      Returns whether graph-based execution order is enabled.
      Returns:
      true if using topological execution order
    • setUseOptimizedExecution

      public void setUseOptimizedExecution(boolean useOptimized)
      Sets whether to use optimized execution (parallel/hybrid) by default when run() is called.

      When enabled (default), run() automatically selects the best execution strategy:

      • For processes WITHOUT recycles: parallel execution for maximum speed (28-57% faster)
      • For processes WITH recycles: hybrid execution - parallel for feed-forward sections, then iterative for recycle sections (28-38% faster)

      When disabled, run() uses sequential execution in insertion order (legacy behavior). This may be useful for debugging or when deterministic single-threaded execution is required.

      Parameters:
      useOptimized - true to use optimized execution (default), false for sequential execution
    • isUseOptimizedExecution

      public boolean isUseOptimizedExecution()
      Returns whether optimized execution is enabled.

      When true (default), run() delegates to runOptimized() which automatically selects the best execution strategy based on process topology.

      Returns:
      true if optimized execution is enabled
    • setUseFlashWarmStart

      public void setUseFlashWarmStart(boolean useWarmStart)
      Enable or disable the warm-start K-value path for flash calculations performed during this process system's run(java.util.UUID) (and the no-arg run()).

      When enabled, ThermodynamicModelSettings.setUseWarmStartKValues(true) is set on the calling thread for the duration of the run and restored to its prior value in a finally block. This makes every TPflash issued during equipment evaluation re-use the previously converged K-values as the initial estimate rather than seeding from the Wilson correlation on every call. Recycle loops, parametric sweeps, and any flowsheet that re-flashes the same fluid at near-identical conditions typically see 10–20% wall-time reduction with no change to the converged solution. Default is false (historical behaviour).

      Parameters:
      useWarmStart - true to enable warm-start K-values during run, false to keep the current thread-local setting unchanged
    • isUseFlashWarmStart

      public boolean isUseFlashWarmStart()
      Returns whether flash warm-start is enabled for this process system's run.
      Returns:
      true if warm-start K-values will be activated for the duration of run
    • getTopologicalOrder

      public List<ProcessEquipmentInterface> getTopologicalOrder()
      Gets the calculation order derived from process topology.

      This method returns units in the order they should be calculated based on stream connections, not the order they were added to the ProcessSystem. This is safer than relying on insertion order, which can lead to wrong results if units are rearranged or recycles are added late.

      Returns:
      list of equipment in topology-derived calculation order
    • hasRecycleLoops

      public boolean hasRecycleLoops()
      Checks if the process has recycle loops that require iterative solving.
      Returns:
      true if the process contains cycles (recycles)
    • getParallelLevelCount

      public int getParallelLevelCount()
      Gets the number of levels for parallel execution.

      Units at the same level have no dependencies on each other and can be executed in parallel.

      Returns:
      number of parallel execution levels
    • getMaxParallelism

      public int getMaxParallelism()
      Gets the maximum parallelism (max units that can run simultaneously).
      Returns:
      maximum number of units that can execute in parallel
    • validateStructure

      public List<String> validateStructure()
      Validates the process structure and returns any issues found.

      Checks include:

      • Isolated units (no connections)
      • Duplicate edges
      • Self-loops
      • Unhandled cycles
      Returns:
      list of validation issues (empty if valid)
    • getGraphSummary

      public String getGraphSummary()
      Gets a summary of the process graph structure.
      Returns:
      summary string with node/edge counts, cycles, parallelism info
    • getRecycleBlocks

      public List<List<ProcessEquipmentInterface>> getRecycleBlocks()
      Gets the strongly connected components (SCCs) in the process graph.

      SCCs with more than one unit represent recycle loops that require iterative convergence. This method uses Tarjan's algorithm to identify these components.

      Returns:
      list of SCCs, each containing a list of equipment in that component
    • getRecycleBlockCount

      public int getRecycleBlockCount()
      Gets the number of recycle blocks (cycles) in the process.
      Returns:
      number of strongly connected components with more than one unit
    • isInRecycleLoop

      public boolean isInRecycleLoop(ProcessEquipmentInterface unit)
      Checks if a specific unit is part of a recycle loop.
      Parameters:
      unit - the unit to check
      Returns:
      true if the unit is in a recycle block
    • getRecycleBlockReport

      public String getRecycleBlockReport()
      Gets a diagnostic report of recycle blocks for debugging.
      Returns:
      formatted string describing each recycle block
    • exportState

      public ProcessSystemState exportState()
      Exports the current state of this process system for checkpointing or versioning.

      This method captures all equipment states, fluid compositions, and operating conditions into a serializable format that can be saved to disk, stored in a database, or used for model versioning in digital twin applications.

      Example usage:

      ProcessSystem system = new ProcessSystem();
      // ... configure and run ...
      ProcessSystemState state = system.exportState();
      state.saveToFile("checkpoint_v1.json");
      
      Returns:
      the current state as a serializable object
      See Also:
    • exportStateToFile

      public void exportStateToFile(String filename)
      Exports the current state to a JSON file for versioning or backup.
      Parameters:
      filename - the file path to save the state
    • loadStateFromFile

      public void loadStateFromFile(String filename)
      Loads process state from a JSON file and applies it to this system.

      Note: This method updates equipment states but does not recreate equipment. The process structure must match the saved state.

      Parameters:
      filename - the file path to load state from
    • saveToNeqsim

      public boolean saveToNeqsim(String filename)
      Saves this process system to a compressed .neqsim file using XStream serialization.

      This is the recommended format for production use, providing compact storage with full process state preservation. The file can be loaded with loadFromNeqsim(String).

      Example usage:

      ProcessSystem process = new ProcessSystem();
      // ... configure and run ...
      process.saveToNeqsim("my_model.neqsim");
      
      Parameters:
      filename - the file path to save to (recommended extension: .neqsim)
      Returns:
      true if save was successful, false otherwise
    • loadFromNeqsim

      public static ProcessSystem loadFromNeqsim(String filename)
      Loads a process system from a compressed .neqsim file.

      After loading, the process is automatically run to reinitialize calculations. This ensures the internal state is consistent.

      Example usage:

      ProcessSystem loaded = ProcessSystem.loadFromNeqsim("my_model.neqsim");
      // Process is already run and ready to use
      Stream outlet = (Stream) loaded.getUnit("outlet");
      
      Parameters:
      filename - the file path to load from
      Returns:
      the loaded ProcessSystem, or null if loading fails
    • saveAuto

      public boolean saveAuto(String filename)
      Saves the current state to a file with automatic format detection.

      File format is determined by extension:

      • .neqsim → XStream compressed XML (full serialization)
      • .json → JSON state (lightweight, Git-friendly)
      • other → Java binary serialization (legacy)
      Parameters:
      filename - the file path to save to
      Returns:
      true if save was successful
    • loadAuto

      public static ProcessSystem loadAuto(String filename)
      Loads a process system from a file with automatic format detection.

      File format is determined by extension:

      • .neqsim → XStream compressed XML
      • other → Java binary serialization (legacy)
      Parameters:
      filename - the file path to load from
      Returns:
      the loaded ProcessSystem, or null if loading fails
    • getEmissions

      public EmissionsTracker.EmissionsReport getEmissions()
      Calculates current emissions from all equipment in this process system.

      Tracks CO2-equivalent emissions from:

      • Flares (combustion emissions)
      • Furnaces and burners
      • Compressors (electricity-based, using grid emission factor)
      • Pumps (electricity-based)
      • Heaters and coolers (if fuel-fired or electric)

      Example usage:

      ProcessSystem system = new ProcessSystem();
      // ... configure and run ...
      EmissionsReport report = system.getEmissions();
      System.out.println("Total CO2e: " + report.getTotalCO2e("kg/hr") + " kg/hr");
      report.exportToCSV("emissions_report.csv");
      
      Returns:
      emissions report with breakdown by equipment and category
      See Also:
    • getEmissions

      public EmissionsTracker.EmissionsReport getEmissions(double gridEmissionFactor)
      Calculates emissions using a custom grid emission factor.

      Different regions have different electricity grid carbon intensities. Use this method to apply location-specific emission factors.

      Parameters:
      gridEmissionFactor - kg CO2 per kWh of electricity (e.g., 0.05 for Norway, 0.4 for global average)
      Returns:
      emissions report with equipment breakdown
    • getTotalCO2Emissions

      public double getTotalCO2Emissions()
      Gets total CO2-equivalent emissions from this process in kg/hr.

      This is a convenience method for quick emission checks. For detailed breakdown, use getEmissions().

      Returns:
      total CO2e emissions in kg/hr
    • createBatchStudy

      public BatchStudy.Builder createBatchStudy()
      Creates a batch study builder for running parallel parameter studies on this process.

      Batch studies allow exploring the design space by running many variations of this process in parallel. Useful for concept screening, sensitivity analysis, and optimization.

      Example usage:

      BatchStudy study =
          system.createBatchStudy().addParameter("separator1", "pressure", 30.0, 50.0, 70.0)
              .addParameter("compressor1", "outletPressure", 80.0, 100.0, 120.0)
              .addObjective("totalPower", true) // minimize
              .withParallelism(4).build();
      BatchStudyResult result = study.run();
      
      Returns:
      a new batch study builder configured for this process
      See Also:
    • generateSafetyScenarios

      public List<ProcessSafetyScenario> generateSafetyScenarios()
      Generates automatic safety scenarios based on equipment failure modes.

      This method analyzes the process structure and generates scenarios for common failure modes such as:

      • Cooling system failure
      • Valve stuck open/closed
      • Compressor/pump trips
      • Power failure
      • Blocked outlets

      Example usage:

      List<ProcessSafetyScenario> scenarios = system.generateSafetyScenarios();
      for (ProcessSafetyScenario scenario : scenarios) {
        scenario.applyTo(system.copy());
        system.run();
        // Check for dangerous conditions
      }
      
      Returns:
      list of safety scenarios for this process
      See Also:
    • generateCombinationScenarios

      public List<ProcessSafetyScenario> generateCombinationScenarios(int maxSimultaneousFailures)
      Generates combination failure scenarios (multiple simultaneous failures).

      This is useful for analyzing cascading failures and common-cause scenarios.

      Parameters:
      maxSimultaneousFailures - maximum number of failures to combine (2-3 recommended)
      Returns:
      list of combination scenarios
    • toDOT

      public String toDOT()
      Exports the process as a DOT format diagram string.

      Generates a professional oil & gas style process flow diagram (PFD) following industry conventions:

      • Gravity logic - Gas equipment at top, liquid at bottom
      • Phase-aware styling - Streams colored by vapor/liquid fraction
      • Separator semantics - Gas exits top, liquid exits bottom
      • Equipment shapes matching P&ID symbols

      Example usage:

      String dot = process.toDOT();
      Files.writeString(Path.of("process.dot"), dot);
      // Render with: dot -Tsvg process.dot -o process.svg
      
      Returns:
      Graphviz DOT format string
      See Also:
    • toDOT

      public String toDOT(DiagramDetailLevel detailLevel)
      Exports the process as a DOT format diagram with specified detail level.
      Parameters:
      detailLevel - the level of detail to include (CONCEPTUAL, ENGINEERING, DEBUG)
      Returns:
      Graphviz DOT format string
      See Also:
    • createDiagramExporter

      public ProcessDiagramExporter createDiagramExporter()
      Creates a diagram exporter for this process with full configuration options.

      Example usage:

      process.createDiagramExporter().setTitle("Gas Processing Plant")
          .setDetailLevel(DiagramDetailLevel.ENGINEERING).setVerticalLayout(true)
          .exportSVG(Path.of("diagram.svg"));
      
      Returns:
      a new ProcessDiagramExporter configured for this process
      See Also:
    • exportDiagramSVG

      public void exportDiagramSVG(Path path) throws IOException
      Exports the process diagram to SVG format.

      Requires Graphviz (dot) to be installed and available in PATH.

      Parameters:
      path - the output file path
      Throws:
      IOException - if export fails
    • exportDiagramPNG

      public void exportDiagramPNG(Path path) throws IOException
      Exports the process diagram to PNG format.

      Requires Graphviz (dot) to be installed and available in PATH.

      Parameters:
      path - the output file path
      Throws:
      IOException - if export fails
    • setCapacityAnalysisEnabled

      public int setCapacityAnalysisEnabled(boolean enabled)
      Enables or disables capacity analysis for all equipment in this process system.

      This is a convenience method that applies the setting to all equipment that extends ProcessEquipmentBaseClass. When disabled, equipment is excluded from:

      • System bottleneck detection (findBottleneck())
      • Capacity utilization summaries (getCapacityUtilizationSummary())
      • Equipment near capacity lists (getEquipmentNearCapacityLimit())
      • Optimization constraint checking
      Parameters:
      enabled - true to enable capacity analysis for all equipment, false to disable
      Returns:
      the number of equipment items that were updated
    • getConstrainedEquipment

      public List<CapacityConstrainedEquipment> getConstrainedEquipment()
      Gets all capacity-constrained equipment in the process.

      Returns equipment that implements the CapacityConstrainedEquipment interface, such as separators, compressors, pumps, etc.

      Returns:
      list of capacity-constrained equipment
    • findBottleneck

      public BottleneckResult findBottleneck()
      Finds the process bottleneck with detailed constraint information.

      This method extends getBottleneck() by returning detailed information about which specific constraint is limiting the bottleneck equipment. Uses the universal constraint API on ProcessEquipmentInterface so ALL equipment types are checked, not just those implementing CapacityConstrainedEquipment.

      For simple bottleneck detection without constraint details, use getBottleneck().

      Returns:
      BottleneckResult containing the bottleneck equipment, limiting constraint, and utilization; returns empty result if no constrained equipment found
      See Also:
    • isAnyEquipmentOverloaded

      public boolean isAnyEquipmentOverloaded()
      Checks if any equipment in the process is overloaded (exceeds design capacity).

      All equipment with capacity constraints is checked, not just those implementing CapacityConstrainedEquipment. Only equipment with capacity analysis enabled is checked.

      Returns:
      true if any equipment has capacity utilization above 100%
    • isAnyHardLimitExceeded

      public boolean isAnyHardLimitExceeded()
      Checks if any equipment exceeds a HARD capacity limit.

      HARD limits represent absolute equipment limits that cannot be exceeded without trip or damage, such as maximum compressor speed or surge limits. All equipment is checked.

      Returns:
      true if any HARD constraint is exceeded
    • getCapacityUtilizationSummary

      public Map<String,Double> getCapacityUtilizationSummary()
      Gets a summary of capacity utilization for all equipment with constraints.

      Returns a map of equipment names to their maximum constraint utilization. Only equipment with capacity analysis enabled and at least one enabled constraint is included.

      Returns:
      map of equipment name to utilization percentage
    • getEquipmentNearCapacityLimit

      public List<String> getEquipmentNearCapacityLimit()
      Gets equipment that is near its capacity limit (above warning threshold).

      Returns equipment where at least one constraint is above its warning threshold (typically 90% of design). All equipment is checked.

      Returns:
      list of equipment names that are near capacity limits
    • disableAllConstraints

      public int disableAllConstraints()
      Disables all capacity constraints on all equipment in the process system.

      Use this for what-if scenarios where you want to ignore capacity limits and see what the process would do without constraints. To re-enable, call enableAllConstraints().

      This method also sets capacityAnalysisEnabled = false on each equipment, which prevents the optimizer from using fallback capacity rules for equipment types.

      Returns:
      the total number of constraints that were disabled
    • enableAllConstraints

      public int enableAllConstraints()
      Enables all capacity constraints on all equipment in the process system.

      Re-enables all constraints that were previously disabled. This restores normal capacity analysis mode for the entire process.

      This method also sets capacityAnalysisEnabled = true on each equipment.

      Returns:
      the total number of constraints that were enabled
    • autoSizeEquipment

      public int autoSizeEquipment()
      Automatically sizes all equipment in the process system that implements AutoSizeable.

      This method iterates through all unit operations and calls autoSize() on each one that implements the AutoSizeable interface. Equipment dimensions are calculated based on current flow conditions, so the process should be run before calling this method.

      Example usage:

      processSystem.run(); // Run first to establish flow conditions
      int sized = processSystem.autoSizeEquipment(); // Size all equipment
      processSystem.run(); // Run again to update calculations with new dimensions
      
      Returns:
      the number of equipment items that were auto-sized
    • autoSizeEquipment

      public int autoSizeEquipment(double safetyFactor)
      Automatically sizes all equipment in the process system with specified safety factor.

      This method iterates through all unit operations and calls autoSize() on each one that implements the AutoSizeable interface. Equipment dimensions are calculated based on current flow conditions, so the process should be run before calling this method.

      Parameters:
      safetyFactor - multiplier for design capacity, typically 1.1-1.3 (10-30% over design)
      Returns:
      the number of equipment items that were auto-sized
    • autoSizeEquipment

      public int autoSizeEquipment(String companyStandard, String trDocument)
      Automatically sizes all equipment using company-specific design standards.

      This method applies design rules from the specified company's technical requirements (TR) documents. The standards are loaded from the NeqSim design database.

      Parameters:
      companyStandard - company name (e.g., "Equinor", "Shell", "TotalEnergies")
      trDocument - TR document reference (e.g., "TR2000", "DEP-31.38.01.11")
      Returns:
      the number of equipment items that were auto-sized
    • getDesignReportJson

      public String getDesignReportJson()
      Gets the design report for all auto-sized equipment in JSON format.

      Returns a JSON object containing design reports for all equipment that implements AutoSizeable. Each equipment's report includes design basis, calculated dimensions, and capacity constraints.

      Example usage:

      processSystem.run();
      processSystem.autoSizeEquipment();
      String designReport = processSystem.getDesignReportJson();
      System.out.println(designReport);
      
      Returns:
      JSON string with design reports for all auto-sized equipment
    • getDesignReport

      public String getDesignReport()
      Gets a summary design report for all auto-sized equipment.

      Returns a human-readable text report summarizing the design of all equipment.

      Returns:
      formatted text report
    • createOptimizer

      public ProcessOptimizationEngine createOptimizer()
      Creates a ProcessOptimizationEngine for this process system.

      The optimization engine provides advanced optimization capabilities including:

      • Maximum throughput optimization
      • Constraint evaluation and bottleneck detection
      • Sensitivity analysis
      • Lift curve generation

      Example usage:

      ProcessOptimizationEngine engine = process.createOptimizer();
      engine.setSearchAlgorithm(SearchAlgorithm.BFGS);
      OptimizationResult result = engine.findMaximumThroughput(50, 10, 1000, 100000);
      
      Returns:
      a new ProcessOptimizationEngine configured for this process
    • createFlowRateOptimizer

      public FlowRateOptimizer createFlowRateOptimizer(String inletStreamName, String outletStreamName)
      Creates a FlowRateOptimizer for this process system.

      The FlowRateOptimizer provides detailed flow rate optimization capabilities including lift curve generation and Eclipse VFP export.

      Parameters:
      inletStreamName - name of the inlet stream
      outletStreamName - name of the outlet stream (or equipment)
      Returns:
      a new FlowRateOptimizer configured for this process
    • findMaxThroughput

      public double findMaxThroughput(double inletPressure, double outletPressure, double minFlow, double maxFlow)
      Finds the maximum throughput for given pressure boundaries.

      This is a convenience method that creates an optimizer, runs the optimization, and returns the result. For more control over the optimization process, use createOptimizer().

      Parameters:
      inletPressure - inlet pressure in bara
      outletPressure - outlet pressure in bara
      minFlow - minimum flow rate to consider in kg/hr
      maxFlow - maximum flow rate to consider in kg/hr
      Returns:
      the maximum feasible flow rate in kg/hr, or NaN if optimization fails
    • findMaxThroughput

      public double findMaxThroughput(double inletPressure, double outletPressure)
      Finds the maximum throughput using default flow bounds.

      Uses default minimum flow of 100 kg/hr and maximum flow of 1,000,000 kg/hr.

      Parameters:
      inletPressure - inlet pressure in bara
      outletPressure - outlet pressure in bara
      Returns:
      the maximum feasible flow rate in kg/hr, or NaN if optimization fails
    • optimizeThroughput

      public ProcessOptimizationEngine.OptimizationResult optimizeThroughput(double inletPressure, double outletPressure, double minFlow, double maxFlow)
      Optimizes the process throughput and returns detailed results.

      This method provides a complete optimization result including the optimal flow rate, constraint status, and bottleneck information.

      Parameters:
      inletPressure - inlet pressure in bara
      outletPressure - outlet pressure in bara
      minFlow - minimum flow rate to consider in kg/hr
      maxFlow - maximum flow rate to consider in kg/hr
      Returns:
      optimization result with detailed information
    • evaluateConstraints

      public ProcessOptimizationEngine.ConstraintReport evaluateConstraints()
      Evaluates all equipment constraints in the process.

      Returns a detailed report of all capacity constraints across all equipment in the process. Useful for understanding the current operating status and identifying potential bottlenecks.

      Returns:
      constraint report with utilization information for all equipment
    • generateLiftCurve

      public ProcessOptimizationEngine.LiftCurveData generateLiftCurve(double[] pressures, double[] temperatures, double[] waterCuts, double[] GORs)
      Generates a lift curve for this process.

      Creates a table of maximum flow rates for different pressure and temperature conditions. The result can be exported to Eclipse VFP format for reservoir simulation.

      Parameters:
      pressures - array of pressures to evaluate (bara)
      temperatures - array of temperatures to evaluate (K)
      waterCuts - array of water cuts as fraction
      GORs - array of gas-oil ratios in Sm3/Sm3
      Returns:
      lift curve data
    • analyzeSensitivity

      public ProcessOptimizationEngine.SensitivityResult analyzeSensitivity(double optimalFlow, double inletPressure, double outletPressure)
      Performs sensitivity analysis at the given flow rate.

      Calculates how sensitive the process is to changes in flow rate, identifying which constraints become binding and the rate of change of key variables.

      Parameters:
      optimalFlow - optimal flow rate to analyze in kg/hr
      inletPressure - inlet pressure in bara
      outletPressure - outlet pressure in bara
      Returns:
      sensitivity analysis result
    • optimize

      Creates a fluent optimization builder for this process.

      The builder provides a convenient way to configure and run optimizations with method chaining.

      Example usage:

      double maxFlow = process.optimize().withPressures(50, 10).withFlowBounds(1000, 100000)
          .usingAlgorithm(SearchAlgorithm.BFGS).findMaxThroughput();
      
      Returns:
      a new OptimizationBuilder for this process
    • initAllMechanicalDesigns

      public void initAllMechanicalDesigns()
      Initialize mechanical design for all equipment in the process.

      This method calls initMechanicalDesign() on each equipment item, preparing them for mechanical design calculations. Should be called after process simulation has run.

      Workflow: ProcessSystem.run() → initAllMechanicalDesigns() → runAllMechanicalDesigns() → getCostEstimate()

    • runAllMechanicalDesigns

      public void runAllMechanicalDesigns()
      Run mechanical design calculations for all equipment in the process.

      This method calls calcDesign() on each equipment's mechanical design. Equipment must have had initMechanicalDesign() called first, or this method will call it automatically.

      Workflow: ProcessSystem.run() → initAllMechanicalDesigns() → runAllMechanicalDesigns() → getCostEstimate()

    • getSystemMechanicalDesign

      public SystemMechanicalDesign getSystemMechanicalDesign()
      Get the system-level mechanical design aggregator.

      The SystemMechanicalDesign provides aggregated views of all equipment mechanical designs, including total weights, dimensions, and utility requirements.

      Example:

      
      process.run();
      SystemMechanicalDesign mecDesign = process.getSystemMechanicalDesign();
      mecDesign.runDesignCalculation();
      System.out.println("Total weight: " + mecDesign.getTotalWeight() + " kg");
      System.out.println(mecDesign.toJson());
      
      
      Returns:
      the system mechanical design object
    • getCostEstimate

      public ProcessCostEstimate getCostEstimate()
      Get the process-level cost estimate.

      The ProcessCostEstimate provides comprehensive cost estimation for the entire process, including purchased equipment cost, bare module cost, total module cost, and grass roots cost.

      Workflow: ProcessSystem.run() → getCostEstimate() → calculateAllCosts() → toJson()

      Example:

      
      process.run();
      ProcessCostEstimate costEst = process.getCostEstimate();
      costEst.calculateAllCosts();
      System.out.println("PEC: $" + costEst.getTotalPurchasedEquipmentCost());
      System.out.println("Grass Roots: $" + costEst.getTotalGrassRootsCost());
      System.out.println(costEst.toJson());
      
      
      Returns:
      the process cost estimate object
    • runMechanicalDesignAndCostEstimation

      public void runMechanicalDesignAndCostEstimation()
      Run complete mechanical design and cost estimation for the process.

      This is a convenience method that performs the full workflow:

      1. Initialize all mechanical designs
      2. Run all mechanical design calculations
      3. Calculate system-level mechanical design aggregations
      4. Calculate process cost estimates

      Example:

      
      process.run();
      process.runMechanicalDesignAndCostEstimation();
      
      // Get results
      SystemMechanicalDesign mecDesign = process.getSystemMechanicalDesign();
      ProcessCostEstimate costEst = process.getCostEstimate();
      
      System.out.println("Total weight: " + mecDesign.getTotalWeight() + " kg");
      System.out.println("Grass Roots Cost: $" + costEst.getTotalGrassRootsCost());
      
      
    • getMechanicalDesignAndCostEstimateJson

      public String getMechanicalDesignAndCostEstimateJson()
      Get a comprehensive JSON report of mechanical design and cost estimation.

      This method runs the full mechanical design and cost estimation workflow if not already done, then returns a combined JSON report including both mechanical design data and cost estimates.

      Returns:
      JSON string with combined mechanical design and cost estimate data
    • getEquipmentCostEstimate

      public UnitCostEstimateBaseClass getEquipmentCostEstimate(String equipmentName)
      Get cost estimate for a specific equipment by name.
      Parameters:
      equipmentName - name of the equipment
      Returns:
      the cost estimate for the equipment, or null if not found
    • getEquipmentMechanicalDesign

      public MechanicalDesign getEquipmentMechanicalDesign(String equipmentName)
      Get mechanical design for a specific equipment by name.
      Parameters:
      equipmentName - name of the equipment
      Returns:
      the mechanical design for the equipment, or null if not found
    • initAllElectricalDesigns

      public void initAllElectricalDesigns()
      Initialize electrical design for all equipment in the process.

      Calls initElectricalDesign() on each equipment item, preparing them for electrical design calculations. Should be called after process simulation has run.

    • runAllElectricalDesigns

      public void runAllElectricalDesigns()
      Run electrical design calculations for all equipment in the process.

      Calls calcDesign() on each equipment's electrical design. Automatically initializes electrical designs that have not been initialized.

    • getElectricalLoadList

      public ElectricalLoadList getElectricalLoadList()
      Get the electrical load list for all equipment in the process.

      Aggregates electrical loads from all equipment into a single load list with summary calculations for transformer and generator sizing.

      Example:

      
      process.run();
      process.runAllElectricalDesigns();
      ElectricalLoadList loadList = process.getElectricalLoadList();
      System.out.println("Total demand: " + loadList.getMaximumDemandKW() + " kW");
      System.out.println(loadList.toJson());
      
      
      Returns:
      the electrical load list
    • getEquipmentElectricalDesign

      public ElectricalDesign getEquipmentElectricalDesign(String equipmentName)
      Get electrical design for a specific equipment by name.
      Parameters:
      equipmentName - name of the equipment
      Returns:
      the electrical design, or null if not found
    • getSystemElectricalDesign

      public SystemElectricalDesign getSystemElectricalDesign()
      Create a system-level electrical design for the entire process.

      Runs all equipment-level electrical designs and produces a plant-wide summary including utility loads, UPS loads, and main transformer/generator sizing.

      Returns:
      the system electrical design with aggregated results
    • getSystemInstrumentDesign

      public SystemInstrumentDesign getSystemInstrumentDesign()

      Get a system-wide instrument design summary that aggregates instrument lists, I/O counts, DCS and SIS cabinet sizing, and cost estimates across all equipment in this process system.

      Returns:
      the system instrument design with aggregated results
    • getAutomation

      public ProcessAutomation getAutomation()
      Returns an automation facade for this process system. The facade provides a stable, string-addressable API for scripts and AI agents to interact with the simulation without navigating Java object hierarchies.
      Returns:
      a ProcessAutomation facade
    • getUnitNames

      public List<String> getUnitNames()
      Returns the names of all unit operations in this process system. Convenience delegate for ProcessAutomation.getUnitList().
      Returns:
      unmodifiable list of unit operation names
    • getVariableList

      public List<SimulationVariable> getVariableList(String unitName)
      Returns all available variables for the named unit operation. Convenience delegate for ProcessAutomation.getVariableList(String).
      Parameters:
      unitName - the name of the unit operation
      Returns:
      list of variable descriptors
      Throws:
      IllegalArgumentException - if the unit is not found
    • getVariableValue

      public double getVariableValue(String address, String unitOfMeasure)
      Reads the current value of a simulation variable by its dot-notation address. Convenience delegate for ProcessAutomation.getVariableValue(String, String).
      Parameters:
      address - the dot-notation address, e.g. "separator-1.gasOutStream.temperature"
      unitOfMeasure - the desired unit, e.g. "C", "bara", "kg/hr"
      Returns:
      the variable value in the requested unit
      Throws:
      IllegalArgumentException - if the address cannot be resolved
    • setVariableValue

      public void setVariableValue(String address, double value, String unitOfMeasure)
      Sets the value of a simulation input variable. Convenience delegate for ProcessAutomation.setVariableValue(String, double, String).
      Parameters:
      address - the dot-notation address, e.g. "Compressor.outletPressure"
      value - the value to set
      unitOfMeasure - the unit of the provided value, e.g. "bara", "C"
      Throws:
      IllegalArgumentException - if the address cannot be resolved or the variable is read-only