1 ! 2 ! HDX.B4S: Hardy-Cross Pipe Network Analysis 3 ! 4 ! Include files 5 ! 6 ! TRUTH.B4S 7 .DEFINE .TRUE%=-1% 8 .DEFINE .FALSE%=0% 9 COMMON (FCSERR) err1%, err2% 10 ! 11 ! File channel definitions 12 ! 13 .DEFINE .flows.chan% = 22% 14 .DEFINE .loops.chan% = 23% 15 .DEFINE .tf.out.chan% = 24% 16 .DEFINE .log.chan% = 25% 17 ! 18 ! Constant definitions 19 ! 20 .DEFINE .eof% = -10% 21 .DEFINE .max.iterations% = 10% 22 .DEFINE .num.itn.values% = 32% 23 .DEFINE .flows.buf.siz% = 294% 24 .DEFINE .loops.buf.siz% = 8% 25 .DEFINE .max.args% = 9% 26 .DEFINE .tf.bufsiz% = 128% 27 .DEFINE .cmd.line.siz% = 128% 28 .DEFINE .its.per.page% = 1% 29 ! 30 ! Buffer definitions 31 ! 32 MAP (PIPES) flowbuf$ = .flows.buf.siz% ! map for flow data record 33 MAP (PIPES) loop%, pipe%, other.loop%, diam, q.lit.sec, & length, itrn.val(.num.itn.values%) 34 MAP (PIPES) pipe.c, rest$ = 166% ! map for unpacking heading 35 MAP (LOOPS) loopbuf$ = .loops.buf.siz% 36 MAP (LOOPS) delta.q ! map for loop delta.q 37 MAP (INBUF) inbuf$ = .tf.bufsiz% 38 MAP (CMDBUF) command.buffer$ = .cmd.line.siz% 39 ! 40 COMMON (PASS) flow%, echo%, help%, in.put%, & debug%, more.data%, not.finished%, num.its%, & pipe.coeff 41 ! 42 ! 43 ! *************** GCl parameter input ******************* 44 ! 45 iterations%, debug% = .false% 46 not.finished%, more.data% = .true% 47 ! 48 rwatitle$ = chr$(27%) + "[2J" + chr$(27%) + "[3;1H" + & " Richard Wittenoom and Associates Pty Ltd" + CR + LF + LF + & " HARDY CROSS PIPE NETWORK ANALYSIS" + CR + LF + LF + LF + LF 49 ! 50 frst% = .true% 51 ! 52 WHILE not.finished% 53 ! print "starting n.f. loop" 54 WHILE more.data% 55 ! print "starting m.d. loop" 56 ! 57 IF frst% & THEN prompt$ = rwatitle$ + "HDX>" & \ frst% = .false% & ELSE prompt$ = LF + LF + CR + "HDX>" 58 ! 59 CALL GCL.(prompt$,LEN(prompt$), command.buffer$, .cmd.line.siz%, len.got%, EG%, EF%, ED%) 60 command$ = EDIT$(left$(command.buffer$, len.got%), 32%+128%) 61 fields% = .max.args% 62 CALL READTF (command$, 2%, 0%, 0%, field$(), "", fields%) 63 ! 64 CALL HDXSET(field$(), command$, title$, outfile$, err$) 65 ! 66 print CR + LF + command$ IF echo% 67 do% = fn.help% IF help% 68 GOTO 32000 IF (NOT (not.finished%)) ! bomb directly if req. 69 ! 70 ! print "before the first NEXT - flow%: "; flow% 71 NEXT 72 ! 73 ! print "after the first NEXT " 74 ! 75 loops.fil$ = outfile$ + ".WK2" 76 out.fil$ = outfile$ + ".OUT" 77 INPUT "log file "; log.fil$ IF debug% > 0% ! outfile$ + ".LOG" 78 ! 79 CALL OPEN. (loops.fil$, "W", .loops.chan%, .loops.buf.siz%) 80 CALL OPEN. (out.fil$, "W", .tf.out.chan%, 0%) 81 CALL OPEN. (log.fil$, "W", .log.chan%, 0%) IF debug% > 0% 82 ! 83 do% = fn.dump.loopfile% IF debug% > 4% 84 ! 85 ! ******************* main work area ******************* 86 ! 87 ! initial initialisation 88 ! 89 LET current.loop% = 1% 90 LET sigma.Hl.on.Q = 0 91 LET sigma.Hl = 0 92 ! 93 ! main iteration loop 94 ! 95 ! print "num.its "; num.its% 96 FOR iteration% = 1% to num.its% 97 ! print "iteration "; iteration% 98 offset% = (iteration% - 1%) * 3% 99 ! 100 IF debug% > 2% & THEN outrec$ = "iteration% =" + num1$(iteration%) + " offset% =" + num1$(offset%) + CR + LF & \ CALL PRINT.(.log.chan%, outrec$) 101 ! 102 first% = .true% 103 ! 104 FOR fl.ow% = 1% to flow% 105 ! 106 CALL GET. (.flows.chan%, flowbuf$, fl.ow%) 107 IF first% & THEN current.loop% = loop% & \ first% = .false% 108 ! 109 IF loop% = current.loop% & THEN do% = fn.flow% & ELSE do% = fn.loop% & \ current.loop% = loop% & \ do% = fn.flow% 110 ! 111 NEXT fl.ow% 112 ! 113 do% = fn.loop% 114 do% = fn.apply.delta.qs% 115 ! 116 NEXT iteration% 117 ! 118 do% = fn.output% 119 ! 120 do% = fn.dump.array% IF debug% > 1% 121 ! 122 ! print "leaving the main loop" 123 more.data% = .true% 124 ! 125 NEXT 126 ! 127 ! ********************** FUNCTIONS ************************* 128 ! 129 ! Variables are: 130 ! Q: itrn.val(offset%) 131 ! hl (m): itrn.val(offset% + 1%) 132 ! dQ: itrn.val(offset% + 2%) 133 ! next Q: itrn.val(offset% + 3%) 134 ! 135 ! ************** process the current flow record ************ 136 ! 137 DEF fn.flow% 138 ! 139 do% = fn.calculate.pipe% 140 sigma.hl.on.Q = sigma.hl.on.Q + hl.on.Q ! accumulate 141 sigma.hl = sigma.hl + itrn.val(offset% + 1%) ! (hl) 142 CALL PUT. (.flows.chan%, flowbuf$, fl.ow%) 143 ! 144 FNEND 145 ! 146 ! ***************** process the preceding loop *************** 147 ! 148 DEF fn.loop% 149 ! 150 IF sigma.hl.on.q = 0 & THEN delta.Q = 0 & ELSE delta.Q = -(sigma.hl / (1.85 * sigma.hl.on.Q)) 151 ! 152 IF debug% > 2% & THEN outrec$ = "loop: " + num1$(loop%) + " sigma h: " + num1$(sigma.hl) & + " sigma h/q: " + num1$(sigma.hl.on.q) & + " delta q: " + num1$(delta.q) + CR + LF & \ CALL PRINT.(.log.chan%, outrec$) 153 ! 154 CALL PUT. (.loops.chan%, loopbuf$, current.loop%) 155 current.loop% = loop% IF err1% <> .eof% 156 sigma.hl = 0 157 sigma.hl.on.Q = 0 ! initialise accumulators 158 ! 159 FNEND 160 ! 161 ! ***************** calculate pipe values ********************* 162 ! 163 DEF fn.calculate.pipe% 164 ! 165 K = ((1/(PI * (diam^2)/4.0E6)) / (0.849 * pipe.coeff * ((diam/4.0E3)^0.63)))^1.85 166 q = abs(itrn.val(offset%)) ! set up to avoid negative values 167 q.sign = sgn(itrn.val(offset%)) ! in arguments in exp function 168 itrn.val(offset% + 1%) = K * q.sign * q^1.85 * length ! head 169 ! 170 IF q = 0 & THEN hl.on.q = 0 & ELSE hl.on.q = itrn.val(offset% + 1%) / itrn.val(offset%) 171 ! 172 IF debug% > 3% & THEN outrec$ = "loop: " + num1$(loop%) + " pipe: " + num1$(pipe%) + " q: " & + num1$(itrn.val(offset%)) + " h: " + num1$(itrn.val(offset% + 1%)) & \ CALL PRINT.(.log.chan%, outrec$) 173 ! 174 FNEND 175 ! 176 ! ************* apply flow adjustments to each loop *********** 177 ! 178 DEF fn.apply.delta.Qs% 179 ! 180 FOR I% = 1% to flow% 181 CALL GET. (.flows.chan%, flowbuf$, I%) 182 CALL GET. (.loops.chan%, loopbuf$, loop%) 183 this.loop.delta.q = delta.q 184 ! 185 IF other.loop% = 0% & THEN other.loop.delta.q = 0 & ELSE CALL GET.(.loops.chan%, loopbuf$, other.loop%) & \ other.loop.delta.q = delta.q 186 ! 187 itrn.val(offset% + 2%) = this.loop.delta.q - other.loop.delta.q 188 itrn.val(offset% + 3%) = itrn.val(offset%) + itrn.val(offset% + 2%) 189 ! 190 a$ = "###" 191 z$ = "##.##########" 192 IF debug% > 0% & THEN outrec$ = "pipe: " + format$(pipe%, a$) & + " q: " + format$(itrn.val(offset%), z$) & + " delta q (this): " + format$(this.loop.delta.q, z$) & + " delta q (other): " + format$(other.loop.delta.q, z$) & + " NEXT Q: " + format$(itrn.val(offset% + 3%), z$) & \ CALL PRINT.(.log.chan%, outrec$) 193 ! 194 CALL PUT.(.flows.chan%, flowbuf$, I%) 195 ! 196 NEXT I% 197 ! 198 FNEND 199 ! 200 ! *************** final Q, H and output ***************** 201 ! 202 DEF fn.output% 203 ! 204 head1$ = "; RICHARD WITTENOOM AND ASSOCIATES PTY LTD" 205 head2$ = ";" + CR + LF + "; HDX: Hardy Cross Pipe Network Processing Utility" + CR + LF + ";" 206 head3$ = "; iterations this run: " + num1$(num.its%) + CR + LF + ";" 207 CALL PRINT.(.tf.out.chan%, head1$) 208 CALL PRINT.(.tf.out.chan%, head2$) 209 CALL PRINT.(.tf.out.chan%, head3$) 210 ! 211 CALL PRINT.(.tf.out.chan%, ("TITLE " + title$)) 212 CALL PRINT.(.tf.out.chan%, ";") 213 CALL PRINT.(.tf.out.chan%, ("COEFFICIENT " + num1$(pipe.coeff))) 214 CALL PRINT.(.tf.out.chan%, ";") 215 ! 216 head2$ = "; loop pipe adj.loop diam (mm) q (litres/sec) length (m) Hl (m) delta q (%)" 217 ! 218 CALL PRINT.(.tf.out.chan%, ";") 219 CALL PRINT.(.tf.out.chan%, head2$) ! output the headings 220 CALL PRINT.(.tf.out.chan%, ";") 221 CALL PRINT.(.tf.out.chan%, "START LINES") 222 CALL PRINT.(.tf.out.chan%, ";") 223 ! 224 !### ### ### ###.# ###.### ####.## ###.## ###.## 225 ! 4 7 8 10 10 5 8 226 ! 227 a$ = "###" 228 b$ = "####.##" 229 c$ = "###.###" 230 d$ = "###.#" 231 ! 232 FOR I% = 1% to flow% 233 CALL GET. (.flows.chan%, flowbuf$, I%) 234 final.Q = itrn.val(offset% + 3%) 235 q.sign = sgn(final.Q) 236 final.Q = abs(final.Q) ! setup to avoid -ve arg in, exp expr'n 237 K = ((1/(PI * (diam^2)/4.0E6)) / (0.849 * pipe.coeff * ((diam/4.0E3)^0.63)))^1.85 238 final.hl = K * q.sign * (final.Q ^ 1.85) * length 239 IF final.q = 0 & THEN final.dq.percent = 0 & ELSE final.dQ.percent = (INT((itrn.val(offset% + 2%) * 10000) / itrn.val(offset% + 3%))) / 100 240 ! 241 outrec$ = " " + format$(loop%, a$) + " " + format$(pipe%, a$) + & " " + format$(other.loop%, a$) + " " + & format$(diam, d$) + " " + format$((itrn.val(offset% + 3%) * 1000), c$) & + " " + format$(length, d$) + " " + & format$(final.hl, b$) + " " + & format$(final.dQ.percent, C$) 242 ! 243 CALL PRINT.(.tf.out.chan%, outrec$) 244 ! 245 NEXT I% 246 ! 247 CALL PRINT.(.tf.out.chan%, ";") 248 CALL PRINT.(.tf.out.chan%, "END LINES") 249 CALL PRINT.(.tf.out.chan%, ";") 250 ! 251 FNEND 252 ! 253 ! **************** fn.dump.array% *************** 254 ! 255 DEF fn.dump.array% 256 ! 257 its.done% = 0% 258 x$ = "#.##########" 259 ! 260 WHILE its.done% < num.its% 261 ! 262 FOR fl.ow% = 1% to num.flows% 263 CALL GET. (.flows.chan%, flowbuf$, fl.ow%) 264 outrec$ = "" 265 start% = its.done% * 3% 266 fin% = start% + (.its.per.page% - 1%) * 3% + 2% 267 fin% = (num.its% -1%) * 3% + 2% IF fin% > (num.its% -1%) * 3% + 2% 268 outrec$ = outrec$ + format$(itrn.val(i%), x$) + " " for i% = start% to fin% 269 CALL PRINT.(.log.chan%, outrec$) 270 NEXT fl.ow% 271 CALL PRINT.(.log.chan%, (CR + LF + CR + LF)) 272 ! 273 its.done% = its.done% + .its.per.page% 274 ! 275 NEXT 276 ! 277 FNEND 278 ! 279 ! **************** fn.dump.loopfile% *************** 280 ! 281 DEF fn.dump.loopfile% 282 ! 283 FOR fl.ow% = 1% to num.flows% 284 CALL GET. (.flows.chan%, flowbuf$, fl.ow%) 285 outrec$ = num1$(loop%) + " " + num1$(pipe%) + " " + & num1$(other.loop%) + " " + num1$(diam) + " " & + num1$(q.lit.sec) + " " + num1$(length) & + num1$(itrn.val(0%)) 286 CALL PRINT.(.log.chan%, outrec$) 287 NEXT fl.ow% 288 ! 289 FNEND 290 ! 291 ! ***************** fn.help% ******************* 292 ! 293 DEF fn.help% 294 ! 295 print\print\print 296 print "HARDY CROSS PIPE NETWORK ANALYSIS PROGRAM" 297 print "-----------------------------------------" 298 print 299 print "Input commands are:" 300 print 301 print "INFILE filename.ext ..specify the data file" 302 print "OUTFILE filename ..supply a name which will" 303 print " be used to create names" 304 print " for work and output files" 305 print "ITERATIONS number ..how many cycles required" 306 print "DEBUG number ..sets up what is to be" 307 print " written to a logfile" 308 print " (range is 1 to 5)." 309 print " ..program takes over" 310 print "ECHO ..echo commands on screen" 311 print "DO (or) GO ..execute the program" 312 print "QUIT (or) EXIT ..terminate execution" 313 print "HELP (or) ? ..print this message" 314 print\print 315 ! 316 FNEND 317 ! FNSAW.B4S - spawn & wait function 318 ! returns 1 for success or DSW for failure 319 ! load with: SPEWN.REL, SPA.REL 320 ! local: Spawn.and.Wait% 321 DEF FN.Spawn.and.Wait%(Task$,Command.Line$) 322 CALL SPA (Task$,Command.Line$+CR+LF,6%,Spawn.and.Wait%) 323 IF Spawn.and.Wait% = 1%& THEN CALL WAITFR BY REF (6%,Spawn.and.Wait%) 324 !FI 325 FN.Spawn.and.Wait% = Spawn.and.Wait% 326 FNEND 327 ! 328 ! FNANSCHK.B4S 329 ! 330 DEF fn.ans$ (text$) = edit$ (left$ (text$, 1%), 32%) 331 DEF fn.upper.case$ (text$) = edit$ (text$, 32%) 332 ! 333 DEF fn.ans% (text$) 334 IF ((edit$ (left$ (text$, 1%), 32%) = "Y") OR (text$ = "1")) & THEN fn.ans% = -1% & ELSE fn.ans% = 0% 335 FNEND 336 ! 32000 CALL CLOSE. (.loops.chan%) 32001 CALL CLOSE. (.flows.chan%) 32002 CALL CLOSE. (.tf.out.chan%) 32003 CALL CLOSE. (.log.chan%) 32004 ! 32767 END