///|
pub struct NetworkConnection {
source_id : String
target_id : String
fraction : Double
} derive(Debug)
///|
pub struct NetworkResult {
streams : Array[Stream]
terminal_ids : Array[String]
iterations : Int
converged : Bool
unresolved_connections : Int
} derive(Debug)
///|
pub struct ConvergenceResult {
value : Double
iterations : Int
residual : Double
converged : Bool
} derive(Debug)
///|
pub fn NetworkConnection::NetworkConnection(
source_id~ : String,
target_id~ : String,
fraction~ : Double,
) -> NetworkConnection {
{ source_id, target_id, fraction: fraction.max(0.0) }
}
///|
fn network_find_stream(streams : Array[Stream], id : String) -> Stream? {
for stream in streams {
if stream.id == id {
return Some(stream)
}
}
None
}
///|
fn network_has_id(ids : Array[String], id : String) -> Bool {
for item in ids {
if item == id {
return true
}
}
false
}
///|
pub fn network_terminal_ids(
connections : Array[NetworkConnection],
) -> Array[String] {
let sources : Array[String] = []
for connection in connections {
if !network_has_id(sources, connection.source_id) {
sources.push(connection.source_id)
}
}
let terminals : Array[String] = []
for connection in connections {
if !network_has_id(sources, connection.target_id) &&
!network_has_id(terminals, connection.target_id) {
terminals.push(connection.target_id)
}
}
terminals
}
///|
pub fn propagate_network(
source : Stream,
connections : Array[NetworkConnection],
max_iterations : Int,
) -> NetworkResult {
let streams : Array[Stream] = [source]
let limit = max_iterations.max(1)
let mut iterations = 0
let mut converged = false
for _ in 0..
if network_find_stream(streams, connection.target_id) is None {
streams.push(
input
.with_flow_factor(connection.fraction)
.with_id(connection.target_id),
)
added = true
}
None => ()
}
}
if !added {
converged = true
break
}
}
let mut unresolved = 0
for connection in connections {
if network_find_stream(streams, connection.source_id) is None {
unresolved += 1
}
}
{
streams,
terminal_ids: network_terminal_ids(connections),
iterations,
converged,
unresolved_connections: unresolved,
}
}
///|
pub fn stream_rate(streams : Array[Stream], id : String) -> Double {
match network_find_stream(streams, id) {
Some(stream) => stream.molar_flow()
None => 0.0
}
}
///|
pub fn network_terminal_flow(result : NetworkResult) -> Double {
let mut total = 0.0
for id in result.terminal_ids {
total += stream_rate(result.streams, id)
}
total
}
///|
pub fn network_flow_residual(
result : NetworkResult,
source_flow : Double,
) -> Double {
network_terminal_flow(result) - source_flow
}
///|
pub fn solve_recycle_temperature(
feed_temperature : Double,
recycle_gain : Double,
max_iterations : Int,
tolerance : Double,
) -> ConvergenceResult {
let mut value = feed_temperature
let mut residual = 1.0e30
let mut iterations = 0
let mut converged = false
for _ in 0.. Double {
enthalpy_flow_sum(inlets) - enthalpy_flow_sum(outlets)
}
///|
pub fn network_stream_count(result : NetworkResult) -> Int {
result.streams.length()
}