Class LoopedPipeNetwork
java.lang.Object
neqsim.util.NamedBaseClass
neqsim.process.SimulationBaseClass
neqsim.process.equipment.ProcessEquipmentBaseClass
neqsim.process.equipment.network.LoopedPipeNetwork
- All Implemented Interfaces:
Serializable, Runnable, ProcessEquipmentInterface, SimulationInterface, NamedInterface
Pipeline network supporting looped topologies with Hardy Cross solver.
This class extends the basic pipeline network concept to support looped configurations commonly found in water distribution systems, oil and gas gathering networks, and gas transmission systems. The Hardy Cross method is used to iteratively solve for flow distribution in networks with loops.
Hardy Cross Method
The Hardy Cross method is an iterative technique for solving networks with loops:
- Initial flow estimates are made for each pipe
- Independent loops are identified using DFS spanning tree algorithm
- For each loop, calculate head loss imbalance: ΔH = ∑(h·sign)
- Calculate flow correction: ΔQ = -ΔH / ∑(|dh/dQ|)
- Apply corrections to all pipes in each loop
- Repeat until convergence (ΔH < tolerance for all loops)
Network Topology
The network supports:
- Multiple source nodes (wells, compressor stations)
- Multiple sink nodes (customers, export terminals)
- Junction nodes where pipes connect
- Looped configurations for redundancy
Example Usage
// Create a simple ring main network
SystemInterface gas = new SystemSrkEos(298.15, 50.0);
gas.addComponent("methane", 0.9);
gas.addComponent("ethane", 0.1);
gas.setMixingRule("classic");
LoopedPipeNetwork network = new LoopedPipeNetwork("ring main");
network.setFluidTemplate(gas);
// Add nodes
network.addSourceNode("supply", 50.0, 1000.0); // 50 bar, 1000 kg/hr
network.addJunctionNode("A");
network.addJunctionNode("B");
network.addJunctionNode("C");
network.addSinkNode("customer1", 100.0); // 100 kg/hr demand
network.addSinkNode("customer2", 200.0);
// Connect with pipes (creates loops)
network.addPipe("supply", "A", "pipe1", 1000.0, 0.3);
network.addPipe("A", "B", "pipe2", 500.0, 0.2);
network.addPipe("B", "C", "pipe3", 500.0, 0.2);
network.addPipe("C", "A", "pipe4", 500.0, 0.2); // Creates a loop
network.addPipe("B", "customer1", "pipe5", 200.0, 0.15);
network.addPipe("C", "customer2", "pipe6", 200.0, 0.15);
// Solve using Hardy Cross
network.setSolverType(SolverType.HARDY_CROSS);
network.setTolerance(1e-6);
network.run();
// Get results
System.out.println("Converged in " + network.getIterationCount() + " iterations");
for (String pipeName : network.getPipeNames()) {
System.out.println(pipeName + ": " + network.getPipeFlowRate(pipeName) + " kg/hr");
}
- Version:
- 1.0
- Author:
- Even Solbraa
- See Also:
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic classRepresents a node in the pipe network.static classRepresents a pipe in the network.static enumNode type in the network.static enumSolver type for network analysis. -
Field Summary
FieldsModifier and TypeFieldDescriptionprivate booleanprivate SystemInterfaceprivate intprivate static final org.apache.logging.log4j.LoggerLogger for this class.private List<NetworkLoop> private intprivate doubleprivate final Map<String, LoopedPipeNetwork.NetworkNode> private final Map<String, LoopedPipeNetwork.NetworkPipe> private doubleprivate static final longprivate LoopedPipeNetwork.SolverTypeprivate doubleFields inherited from class ProcessEquipmentBaseClass
conditionAnalysisMessage, energyStream, hasController, isSolved, properties, reportFields inherited from class SimulationBaseClass
calcIdentifier, calculateSteadyState, timeFields inherited from class NamedBaseClass
name -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionvoidaddJunctionNode(String name) Add a junction node to the network.Add a pipe connecting two nodes.voidaddSinkNode(String name, double demandKgHr) Add a sink node (demand point) to the network.voidaddSourceNode(String name, double pressureBar, double flowRateKgHr) Add a source node to the network.private doubleCalculate head loss for a pipe using Darcy-Weisbach equation.private doubleCalculate derivative of head loss with respect to flow rate.private voidDetect loops in the network using DFS spanning tree algorithm.Get the fluid template.intGet number of iterations in last solve.getLoops()Get detected loops in the network.intGet maximum iterations.doubleGet maximum residual from last iteration.doublegetNodePressure(String nodeName) Get pressure at a node in bara.intGet number of loops in the network.doublegetPipeFlowRate(String pipeName) Get flow rate for a specific pipe in kg/hr.Get all pipe names.doubleGet relaxation factor.Get a summary of the network solution.Get the solver type.doubleGet convergence tolerance.private doubleGet total conductance of all pipes.private voidInitialize pipe flow estimates using topological analysis.private voidInitialize AdiabaticPipe models for each pipe.booleanCheck if solution converged.private voidpropagatePressure(String nodeName, SystemInterface fluid) Propagate pressure from a node to connected nodes.voidIn this method all thermodynamic and unit operations will be calculated in a steady state calculation.private voidrunHardyCross(UUID id) Run Hardy Cross iterative solver.private voidrunSequential(UUID id) Run sequential solver for tree networks.voidsetFluidTemplate(SystemInterface fluid) Set the fluid template for the network.voidsetMaxIterations(int max) Set maximum number of iterations.voidsetRelaxationFactor(double factor) Set relaxation factor for Hardy Cross (0 < factor <= 1).voidSet the solver type.voidsetTolerance(double tol) Set convergence tolerance for head loss balance (Pa).toJson()Serializes the Process Equipment along with its state to a JSON string.private voidUpdate node pressures based on calculated head losses.Methods inherited from class ProcessEquipmentBaseClass
copy, displayResult, equals, getConditionAnalysisMessage, getController, getEffectiveCapacityFactor, getEnergyStream, getEntropyProduction, getExergyChange, getFailureMode, getMassBalance, getMassBalance, getMechanicalDesign, getMinimumFlow, getPressure, getPressure, getProperty, getReport_json, getResultTable, getSpecification, getTemperature, getTemperature, getThermoSystem, hashCode, initMechanicalDesign, isActive, isActive, isCapacityAnalysisEnabled, isFailed, isSetEnergyStream, reportResults, restoreFromFailure, run_step, runConditionAnalysis, setCapacityAnalysisEnabled, setController, setEnergyStream, setEnergyStream, setFailureMode, setFlowValveController, setMinimumFlow, setPressure, setRegulatorOutSignal, setSpecification, setTemperature, simulateDegradedOperation, simulateTrip, solved, toJsonMethods inherited from class SimulationBaseClass
getCalculateSteadyState, getCalculationIdentifier, getTime, increaseTime, isRunInSteps, setCalculateSteadyState, setCalculationIdentifier, setRunInSteps, setTimeMethods inherited from class NamedBaseClass
getName, getTagName, setName, setTagNameMethods inherited from class Object
clone, finalize, getClass, notify, notifyAll, toString, wait, wait, waitMethods inherited from interface NamedInterface
getName, getTagName, setName, setTagNameMethods inherited from interface ProcessEquipmentInterface
getCapacityDuty, getCapacityMax, getExergyChange, getFluid, getOperatingEnvelopeViolation, getRestCapacity, getSimulationValidationErrors, isSimulationValid, isWithinOperatingEnvelope, needRecalculation, validateSetupMethods inherited from interface SimulationInterface
getCalculateSteadyState, getCalculationIdentifier, getTime, increaseTime, isRunInSteps, run, run_step, runTransient, runTransient, setCalculateSteadyState, setCalculationIdentifier, setRunInSteps, setTime
-
Field Details
-
serialVersionUID
private static final long serialVersionUID- See Also:
-
logger
private static final org.apache.logging.log4j.Logger loggerLogger for this class. -
nodes
-
pipes
-
pipeNames
-
solverType
-
tolerance
private double tolerance -
maxIterations
private int maxIterations -
relaxationFactor
private double relaxationFactor -
loops
-
iterationCount
private int iterationCount -
maxResidual
private double maxResidual -
converged
private boolean converged -
fluidTemplate
-
-
Constructor Details
-
LoopedPipeNetwork
Create a new looped pipe network.- Parameters:
name- network name
-
-
Method Details
-
setFluidTemplate
Set the fluid template for the network.- Parameters:
fluid- the fluid system to use as template
-
getFluidTemplate
-
addSourceNode
Add a source node to the network.- Parameters:
name- node namepressureBar- fixed pressure in baraflowRateKgHr- supply flow rate in kg/hr (optional, for validation)
-
addSinkNode
Add a sink node (demand point) to the network.- Parameters:
name- node namedemandKgHr- demand flow rate in kg/hr
-
addJunctionNode
Add a junction node to the network.- Parameters:
name- node name
-
addPipe
public LoopedPipeNetwork.NetworkPipe addPipe(String fromNode, String toNode, String pipeName, double lengthM, double diameterM) Add a pipe connecting two nodes.- Parameters:
fromNode- source node nametoNode- target node namepipeName- pipe namelengthM- pipe length in metersdiameterM- pipe inner diameter in meters- Returns:
- the created pipe
-
setSolverType
Set the solver type.- Parameters:
type- solver type
-
getSolverType
-
setTolerance
public void setTolerance(double tol) Set convergence tolerance for head loss balance (Pa).- Parameters:
tol- tolerance in Pa
-
getTolerance
public double getTolerance()Get convergence tolerance.- Returns:
- tolerance in Pa
-
setMaxIterations
public void setMaxIterations(int max) Set maximum number of iterations.- Parameters:
max- maximum iterations
-
getMaxIterations
public int getMaxIterations()Get maximum iterations.- Returns:
- max iterations
-
setRelaxationFactor
public void setRelaxationFactor(double factor) Set relaxation factor for Hardy Cross (0 < factor <= 1).- Parameters:
factor- relaxation factor
-
getRelaxationFactor
public double getRelaxationFactor()Get relaxation factor.- Returns:
- relaxation factor
-
getIterationCount
public int getIterationCount()Get number of iterations in last solve.- Returns:
- iteration count
-
getMaxResidual
public double getMaxResidual()Get maximum residual from last iteration.- Returns:
- max residual in Pa
-
isConverged
public boolean isConverged()Check if solution converged.- Returns:
- true if converged
-
getLoops
-
getNumberOfLoops
public int getNumberOfLoops()Get number of loops in the network.- Returns:
- number of loops
-
getPipeNames
-
getPipeFlowRate
Get flow rate for a specific pipe in kg/hr.- Parameters:
pipeName- pipe name- Returns:
- flow rate in kg/hr
-
getNodePressure
Get pressure at a node in bara.- Parameters:
nodeName- node name- Returns:
- pressure in bara
-
initializeFlowEstimates
private void initializeFlowEstimates()Initialize pipe flow estimates using topological analysis. -
getTotalConductance
private double getTotalConductance()Get total conductance of all pipes.- Returns:
- total conductance
-
calculateHeadLoss
Calculate head loss for a pipe using Darcy-Weisbach equation.- Parameters:
pipe- the pipefluid- fluid properties- Returns:
- head loss in Pa
-
calculateHeadLossDerivative
private double calculateHeadLossDerivative(LoopedPipeNetwork.NetworkPipe pipe, SystemInterface fluid) Calculate derivative of head loss with respect to flow rate.- Parameters:
pipe- the pipefluid- fluid properties- Returns:
- dh/dQ in Pa/(kg/s)
-
detectLoops
private void detectLoops()Detect loops in the network using DFS spanning tree algorithm. -
runHardyCross
Run Hardy Cross iterative solver.- Parameters:
id- calculation identifier
-
runSequential
Run sequential solver for tree networks.- Parameters:
id- calculation identifier
-
initializePipeModels
private void initializePipeModels()Initialize AdiabaticPipe models for each pipe. -
updateNodePressures
Update node pressures based on calculated head losses.- Parameters:
fluid- fluid for calculations
-
propagatePressure
Propagate pressure from a node to connected nodes.- Parameters:
nodeName- starting node namefluid- fluid for calculations
-
run
Description copied from interface:SimulationInterfaceIn this method all thermodynamic and unit operations will be calculated in a steady state calculation.
- Parameters:
id- UUID
-
getSolutionSummary
-
toJson
Description copied from class:ProcessEquipmentBaseClassSerializes the Process Equipment along with its state to a JSON string.
- Specified by:
toJsonin interfaceProcessEquipmentInterface- Overrides:
toJsonin classProcessEquipmentBaseClass- Returns:
- json string.
-