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
    • 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
    • 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.
    • 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.
    • 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(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
    • 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
    • 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 WITHOUT recycles: uses parallel execution for maximum speed
      • For processes WITH recycles: uses hybrid execution - parallel for feed-forward sections, then graph-based iteration for recycle sections
      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
    • 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
    • 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
    • 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
    • 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
    • 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
    • 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
    • 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
    • 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
    • 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)

      getEntropyProduction.

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

      public double getExergyChange(String unit)

      getExergyChange.

      Parameters:
      unit - a String object
      Returns:
      a double
    • 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:
    • 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:
    • 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).

    • 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
    • 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. Only works for equipment that implements 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).

      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. Only equipment with capacity analysis enabled is checked.

      Returns:
      true if any HARD constraint is exceeded
    • getCapacityUtilizationSummary

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

      Returns a map of equipment names to their maximum constraint utilization. Only equipment with capacity analysis enabled is included. Useful for displaying overall process capacity status.

      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). Only equipment with capacity analysis enabled is included. Useful for identifying potential future bottlenecks.

      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