Trace values of thermal-hydraulic regime (temperature, pressure, consumption) in the bunched pipeline along the flow direction using norms of heat flux values prescribed by Minenergo Order 325.

m325tracefw(
sender = c(0, 1),
acceptor = c(1, 2),
temperature = c(70, NA_real_),
pressure = c(pipenostics::mpa_kgf(6), NA_real_),
consumption = c(20, NA_real_),
d = rep_len(100, 2),
len = rep_len(72.446, 2),
year = rep_len(1986, 2),
insulation = rep_len(0, 2),
laying = rep_len("tunnel", 2),
beta = rep_len(FALSE, 2),
exp5k = rep_len(TRUE, 2),
roughness = rep_len(0.001, 2),
inlet = c(0.5, 1),
outlet = c(1, 1),
elev_tol = 0.1,
method = "romeo",
verbose = TRUE,
csv = FALSE,
file = "m325tracefw.csv",
maxcores = 2
)

## Arguments

sender identifier of the node which heat carrier flows out. Type: any type that can be painlessly coerced to character by as.character. identifier of the node which heat carrier flows in. According to topology of test bench considered this identifier should be unique for every row. Type: any type that can be painlessly coerced to character by as.character. snapshot of thermal-hydraulic regime state: temperature of heat carrier (water) sensor-measured on the root node, [°C]. Type: assert_double. Use NA_float_s for nodes without temperature sensor. snapshot of thermal-hydraulic regime state: sensor-measured absolute pressure of heat carrier (water) inside the pipe (i.e. acceptor's incoming edge), [MPa]. Type: assert_double. Use NA_float_s for nodes without pressure sensor. snapshot of thermal-hydraulic regime state: sensor-measured amount of heat carrier (water) on root node that is transferred by pipe (i.e. acceptor's incoming edge) during a period, [ton/hour]. Type: assert_double. Use NA_float_s for nodes without consumption sensor. internal diameter of pipe (i.e.diameter of acceptor's incoming edge), [mm]. Type: assert_double. pipe length (i.e. length of acceptor's incoming edge), [m]. Type: assert_double. year when the pipe (i.e. acceptor's incoming edge) is put in operation after laying or total overhaul. Type: assert_integerish. identifier of insulation that covers the exterior of pipe (i.e. acceptor's incoming edge): 0no insulation 1foamed polyurethane or analogue 2polymer concrete Type: assert_subset. type of pipe laying depicting the position of pipe in space. Only five types of pipe laying are considered: air, channel, room, tunnel, underground. Type: assert_subset. logical indicator: should they consider additional heat losses of fittings located on this pipe (i.e. acceptor's incoming edge)? Type: assert_logical. logical indicator for regime of pipe (i.e. acceptor's incoming edge): if TRUE pipe is operated more that 5000 hours per year. Type: assert_logical. roughness of internal wall of pipe (i.e. acceptor's incoming edge), [m]. Type: assert_double. elevation of pipe inlet, [m]. Type: assert_double. elevation of pipe outlet, [m]. Type: assert_double. maximum allowed discrepancy between adjacent outlet and inlet elevations of two subsequent pipes in the traced path, [m]. Type: assert_number. method of determining Darcy friction factor: romeo vatankhan buzelli Type: assert_choice. For more details see dropp. logical indicator: should they watch tracing process on console? Type: assert_flag. logical indicator: should they incrementally dump results to csv-file while tracing? Type: assert_flag. name of csv-file which they dump results to. Type: assert_character of length 1 that can be used safely to create a file and write to it. maximum cores of CPU to use in parallel processing. Type: assert_count.

## Value

data.frame containing results of tracing in long format (narrow format) mostly like it returned by function m325tracebw:

node

identifier of the node for which regime parameters is calculated. Values in this vector are identical to those in argument acceptor. Type: assert_character.

trace

identifiers of nodes from which regime parameters are traced for the given node. Identifier sensor is used when values of regime parameters for the node are sensor readings. Type: assert_character.

backward

identifier of tracing direction. It constantly equals to FALSE. Type: assert_logical.

aggregation

aggregation method associated with values of calculated temperature or pressure in data.frame's row for the node. For forward tracing the only option is identity. Type: assert_character.

temperature

snapshot of thermal-hydraulic regime state: traced temperature of heat carrier (water) that is associated with the node, [°C] Type: assert_double.

pressure

snapshot of thermal-hydraulic regime state: traced pressure of heat carrier (water) that is associated with the node, [MPa] Type: assert_double.

consumption

snapshot of thermal-hydraulic regime state: traced pressure of heat carrier (water) that is associated with the node, [ton/hour] Type: assert_double.

job

value of trace step counter. For forward tracing value of job counts the number of traced paths from root node. Type: assert_integer.

## Details

The calculated (values of) regime may be considered as representation of district heating process in conditions of hypothetically perfect technical state of pipe walls and insulation.

They consider the topology of district heating network much similar to m325testbench:

Tracing starts from sensor-equipped root node and goes forward, i.e along the flow direction. Function m325traceline serves under the hood for tracing identified linear segments from root node to every terminal node. Hence they only need root node to be equipped with sensors. Sensors at other nodes are redundant in forward tracing, since the tracing algorithm by no means consider them for tracing.

Moreover in the forward tracing algorithm they assume the flow of heat carrier is distributed proportionally to the cross-sectional area of the outgoing pipeline. Actually, a lot of reasons may cause significant deviations from this assumption. As a result, the sequence of paired backward/forward tracing may be divergent for regime parameters.

Though some input arguments are natively vectorized their individual values all relate to common part of district heating network, i.e. associated with common object. It is due to isomorphism between vector representation and directed graph of this network. For more details of isomorphic topology description see m325testbench.

They are welcome to couple the algorithm with functionality of data.table.

Other Regime tracing: m325tracebw(), m325traceline()

## Examples

# \donttest{
# Minimum two nodes should be in district heating network graph:
m325tracefw(verbose = FALSE)
#>   node  trace backward aggregation temperature  pressure consumption job
#> 1    1 sensor    FALSE    identity    70.00000 0.5883990          20   0
#> 2    2      1    FALSE    identity    69.71603 0.5813153          20   1
#   node  trace backward aggregation temperature  pressure consumption job
# 1    1 sensor    FALSE    identity    70.00000 0.5883990          20   0
# 2    2      1    FALSE    identity    69.71603 0.5813153          20   1

# Example with the test bench:
nx <- pipenostics::m325testbench

# avoid using numeric identifiers for nodes:
nx$sender <- paste0("N", nx$sender)
nx$acceptor <- paste0("N", nx$acceptor)

# Alter units:
nx$d <- 1e3 * nx$d  # convert [m] to [mm]

# Perform backward tracing to get regime on root node:
bw_report <- do.call("m325tracebw", c(as.list(nx), verbose = FALSE))

# Put the traced values to the root node of the test bench:
root_node_idx <- 12
root_node <- paste0("N", root_node_idx)
regime_param  <- c("temperature", "pressure", "consumption")
nx[root_node_idx, regime_param] <-
subset(bw_report,
node == root_node & aggregation == "median",
regime_param)
rm(root_node, root_node_idx)

# Trace the test bench forward for the first time:
fw_report <- do.call("m325tracefw",
c(as.list(nx), verbose = FALSE, elev_tol = .5))

# Let's compare traced regime at terminal nodes back to test bench:
report <- subset(
rbind(bw_report, fw_report),
node %in% subset(nx, !(acceptor %in% sender))\$acceptor &
aggregation == "identity"
)

regime_delta <- colMeans(
subset(report, backward, regime_param) -
subset(report, !backward, regime_param)
)
print(regime_delta)
#>   temperature      pressure   consumption
#> -4.640201e-01 -5.208802e-03 -5.465713e-16 # temperature      pressure   consumption
# -4.640201e-01 -5.208802e-03 -5.465713e-16

stopifnot(sqrt(regime_delta %*% regime_delta) < 0.5)
# }