Pascal source code for SHP4FPC [26th April 2012]
As you may have gathered by now, ALL my hydraulics programs are entirely FREE for you to use as you wish. However, my current 10 programs are defined as FREEWARE (where you just get the executable version) and not OPEN SOURCE (where you get the actual Basic, C++, Java, Delphi etc. coding) and sometimes called FOSS or FLOSS.
To continue to offer the best software for the Fire Protection Industry, I have now decided to release a complete and working hydraulics calculations program, called SHP4FPC as the source code listing below. This matches up with the excellent OPEN SOURCE Free Pascal Compiler at www.freepascal.org and, as I prefer the Pascal language, it did not take me long to produce the approx 700 lines. I have also shown what data it requires (as a little test job) and how the command line driven program actually operates and the Results printout so produced.
This will be especially useful if you want a foreign language version for your own country or you wish to learn a computer language such as Pascal. You can use, extend or modify this program as you like or convert it into another programming language entirely for NOTHING and without further reference to me but my Email address is at the top of this page if you want any more information.
Visual Basic source code for SHP4MVB [3rd October 2012]
As some of my users found the Pascal documentation a bit difficult to follow, I have redone virtually the same program suitable for the Microsoft Visual Basic 2010 Express application which you can download from the appropriate website (not the Visual Studio one). It does run to over 160 Mb and you then have to update the Microsoft .NET Framework 4 add-ones that downloads another 100 Mb, so set aside an hour for all this to happen automatically. Check that this runs on your computer and register it with Microsoft to extend the 30 day trial period to become a licenced user, entirely for free.
Now click here to download shp4mvbzip.zip and copy it to your computer - it is only 430 Kbytes so should not take long - you should then copy it from any "Downloads" folder onto the root of your C: or D: hard discs. Select this from the Windows Explorer to see 'shpzip' as a folder name - click on it and then on 'Extract all files' at the top of the screen, accept the defaults on the screen that follows to UNZIP the various folders and 80 files totalling about 1 Mb (again you should really choose a separate folder / directories, but you can use the same one as the zipped folder if you want).
Run Microsoft Visual Basic 2010 Express again and :-
- Select "Open Project ..." from the "File" menu
- Click through the folders / directories where you have stored my unzipped items, until you see a "Microsoft Visual Studio Solution" file called SHP4MVB.
- Click on this and then "Open" - for the first time, you will see a 'Solution Explorer' window at the top right with some icons and items below
- Double click on "Form1.vb" to see the form appear in the main window looking like the screen shot below
- Now click on the "View Code" icon in the 'Solution Explorer' to see the first set of basic listing (the total number of lines is 915)
- Press the 'F5' key to compile and run the program (less than a second) and have a go with the 'Demo' to begin and 'Exit' to get back to the source code / form designer
- Don't forget to select "Save All" from the "File" menu before exiting the program
- The next time you run Microsoft Visual Basic 2010 Express, it will have remembered the above settings so you only have to select "Recent Projects and Solutions" from the "File" menu
- Yes I know this is NOT how Microsoft wants Visual Basic programs to be sent to other people, but I don't have all the (presumably paid-for) extensions on my website that they insist is used. Besides I wanted to give you the "source code" for free, again not what Microsoft ever thought was required.
If you already have the Microsoft .NET Framework 4 on your computer, then you may be able to run the SHP4MVB application (just 55 Kbytes) directly from the /Debug or /Release parts under the unzipped program folder. In either case, SHP4MVB looks like :-
I have kept the SAME file, input data and results formats as the original SHP4FPC program listed on the rest of this page but you should have a monitor of at least 1366 x 768 pixels (preferably 1920 x 1080 HD) so can see the data and the results on the same screen. Obviously you can change the colours, positioning etc of the Form1 and there is lots of information about Visual Basic on the Microsoft MSDN website, in books from your Library or purchased on-line. You will find it virtually imposible to make any typing errors as the application is continually prompting hints and help as you go - so if you have a variable called FRED, then type in FRAD instead, then it underlines it in green and refuses to compile the program until you correct it.
Note that this is a complete Windows program, runs entirely within Windows and looks like all the other Windows programs you have - it even has "hints"! It would have been quite easy to produce an EN12845 version, but I only ever got requests from people wanting the NFPA 13/15 Rules since April / May this year. I hope you find this of interest but if you need any more information, then my Email address is at the top on the page. I have also removed the "You can convert it to another programming language ..." and "[27th April 2012] Suggested WINDOWS format ..." sections and the 3 little screen-shots in the previous version of this page as I have now done what I suggested you might want to try. I think I still prefer DELPHI to BASIC but appreciate you may not wish to learn another programming language, so here it is.
For the FREE PASCAL COMPILER, you should ...
Visit www.freepascal.org and get the version of the FREE PASCAL COMPILER corresponding to your chosen operating system - it is available for DOS, WINDOWS 98/ME/NT/2000/XP/Vista/7 in 32 and 64 bit, MAC OSX, LINUX, UNIX and many others. There is no registration, Email addresses, licences etc. Sound familiar? This will only take a few minutes to download and install - accept all the default options. There is copious documentation as several PDF files but you do not need to read them all and many hundreds of little examples explaining key features.
Create another directory / folder on your computer, perhaps C:\shp4fpc and click the mouse over the start of the '{ Copyright ...' line below and drag the mouse down until all the text to the last 'end.' is highlighted - press [CTRL]+C to copy it, open 'NotePad' or similar, then press [CTRL]+V to paste and see the 700 lines. Save it as 'shp4fpc.pp' in your new folder and select 'New' to clear the screen. Return to this webpage, go down to the Typical Data File heading and the start of the 'First Test Example' line and do the same highlight, drag down to the end of the '143 144 ...' line, [CTRL]+C, goto Notepad, [CTRL]+V but this time save the 37 lines to 'Test001.txt'.
You now need to compile the program - although there is a good Free Pascal IDE, I found it best to do this from the 'Command Prompt' in Windows. You only need to do this once, unless you change the shp4fpc.pp source code for any reason. Just type :-
CD \directory1
FPC \directory2\SHP4FPC.PP
where directory1 is the location of the Free Pascal Compiler (given when you hover your mouse over the 'Free Pascal IDE' icon on the desktop or if that doesn't work, then 'right-click' and select 'Properties') and directory2 is where you have saved the .pp and .txt files. After less than a second, the shp4fpc.exe program will be generated and saved back in your directory2 folder.
[27th April 2012 - To save yourself 15 minutes, and learning something useful, you can DOWNLOAD the DOS version shp4fpc.exe by clicking here (it is only about 100KBytes) and saving it to a specific directory - you MUST then "copy / paste" the Test001.txt file from below to this same directory as described in the above paragraph and then run the "Command Prompt" otherwise it won't work.]
You can now type :-
CD \directory2
SHP4FPC TEST001.TXT
to see the following on the screen :-
SHP4FPC by Alan Ashfield - April 2012 Please visit www.freehc.net for more information Developed with the Free Pascal Compiler V2.6.0 at www.freepascal.org for multiple operating systems Started checking Test001.TXT and creating Test001.BAK Started on calculations for 12 pipes to 6 heads Pipe sizes from 25 to 100 mm and highest head = 5.000 m Source flow = 566.2 L/min at 2.302 bars Balanced in 10 steps, errors 0.000289 bars + 0.027 L/min Results now stored in Test001Results.TXT End of SHP4FPC by Alan Ashfield - www.freehc.net
You can now go back to Windows and use 'NotePad' or similar to view the Test001Results.TXT file (all in the same directory) which should look like
START OF RESULTS PRINTOUT FROM SHP4FPC BY ALAN ASHFIELD
.
Q1 Project name = First Test Example
Q2 Project number = 1
Q3 Location = Somewhere over the rainbow
Q4 Drawings = Drawings
Q5 Remotest area = Most Remote
Q6 Occupancy = Dont know
Q7 System / Hazard = Ordinary Hazard
Q8 Contractor = Put your name here
Q9 Address = Your address
Q10 Designer = Alan Ashfield
Q11 A.H.J. = AHJ
Q12 Water supply = Calculate min duty
Q13 Static bars = 0.000
Q14 Residual bars = 0.000
Q15 Residual L/min = 0
Q16 Application area = 54.0
Q17 Density mm/min = 10.00
Q18 Head area sq.m = 9.000
.
SOURCE DUTY AT NODE 100 = 566.2 L/min at 2.302 bars
.
Remote head is at node 144 = 90.0 L/min, 1.266 bars and 5.000 m
.
Node1 Flow Q S i z e Fittings Length Type Pt
Heights Kfactor Head q mm ELT4BGS Fitts Cfactor Pe
Node2 L/min B o r e LTX5VVC Totalm mbar/m Pf
--------------------------------------------------------------------------
100 0.000 566.2 100 1.500 S40 2.302
0000010 0.610 120 0.147
110 1.500 102.26 2.110 1.7 0.004
--------------------------------------------------------------------------
110 1.500 566.2 100 3.000 S40 2.151
0000100 3.658 120 0.294
120 4.500 102.26 6.658 1.7 0.012
--------------------------------------------------------------------------
120 4.500 566.2 100 30.000 S40 1.845
1000000 3.048 120 0.000
130 4.500 102.26 33.048 1.7 0.058
--------------------------------------------------------------------------
130 4.500 283.8 40 0.500 S40 1.788
0010000 2.438 120 0.049
131 5.000 40.90 2.938 42.1 0.124
--------------------------------------------------------------------------
131 5.000 283.8 40 1.000 S40 1.615
80.0 98.7 1000000 1.219 120 0.000
132 5.000 40.90 2.219 42.1 0.093
--------------------------------------------------------------------------
132 5.000 185.1 32 3.000 S40 1.522
80.0 94.7 0000000 0.000 120 0.000
133 5.000 35.10 3.000 40.2 0.121
--------------------------------------------------------------------------
133 5.000 90.4 25 3.000 S40 1.401
80.0 90.4 0000000 0.000 120 0.000
134 5.000 26.60 3.000 41.2 0.124
--------------------------------------------------------------------------
130 4.500 282.5 65 3.000 S40 1.788
0000000 0.000 120 0.000
140 4.500 62.70 3.000 5.2 0.016
--------------------------------------------------------------------------
140 4.500 282.5 40 0.500 S40 1.772
0010000 2.438 120 0.049
141 5.000 40.90 2.938 41.7 0.123
--------------------------------------------------------------------------
141 5.000 282.5 40 1.000 S40 1.600
80.0 98.2 1000000 1.219 120 0.000
142 5.000 40.90 2.219 41.7 0.093
--------------------------------------------------------------------------
142 5.000 184.3 32 3.000 S40 1.508
80.0 94.3 0000000 0.000 120 0.000
143 5.000 35.10 3.000 39.9 0.120
--------------------------------------------------------------------------
143 5.000 90.0 25 3.000 S40 1.388
80.0 90.0 0000000 0.000 120 0.000
144 5.000 26.60 3.000 40.9 0.123
--------------------------------------------------------------------------
.
END OF PRINTOUT FROM SHP4FPC BY ALAN ASHFIELD
.
You can also view the 'Test001.BAK' file which shows the data file all properly formatted (not given here). You can now see how this simple program operates - one creates or edits a .txt job data file and saves it. You then run the program from the 'Run' box or 'Command prompt' (shp4fpc filename.txt), to see the messages generated, check if OK or action required and then one views the filenameResults.txt output file in 'NotePad'.
Data required for SHP4FPC ...
This program will carry out the calculations for the most hydraulically demanding design area of any hazard of end- or centre-fed branch line sprinkler system to the NFPA 13 Rules in metric units, either with Q13-15 all zero (as shown) or to any defined water supply. You can therefore apply it to roof only or roof + rack protection, ESFR, large drop, wet / dry systems or deluge / drencher / spray fire protection pipework layouts. I have just entered sizes from 25 to 300mm for a few pipe types and all 7 fittings given in the NFPA Tables. The results printout above is the minimum necessary and I have, of course, checked it against my existing FREESHP program as giving the same answers.
The first 18 questions should be obvious so one starts noding up at the source and proceeds outwards to the operating heads / nozzles. Node numbers are allocated at junctions where 2, 3 or 4 pipes meet, at operating heads and where changes in pipe size or type occur other than at elbows, tees etc. Pipes are therefore defined as being between the 'From' node to the 'To' node where the 'From' node is nearer to the source. In other words, you number up the pipes away from the source out into the pipework system, such that the 'From' node must have been given as a previous 'To' node and any operating heads / nozzles are at the 'To' nodes. The pipes data starts at line 26 and consists of :-
- 'From' node - where pipe starts in the range of 1 to 9999 eg. 100 and must be the same (apart from first pipe) as a previously entered 'To' node
- 'To' node - where this pipe ends eg. 110
- Size in mm - from 25 to 300 reducing in size into the system eg. 65
- Pipe type - just S40, MW or DIN to start with; the program will check it and the size exists eg. S40
- Horizontal pipe length in metres - any value from 0 to 500 eg. 3
- Vertical pipe length in metres - any value from -50 (if going downwards) or +50 (if going upwards) or 0 if horizontal. Eg. for these 2 values, 3.0 0.0 means a horizontal run or 0.0 4.0 means a pipe 4m upwards or 4.0 3.0 means a pipe 5m long at a slope of 36 degrees. This gives complete flexibility without requiring special codes
- Fittings - you can have from 0 to 9 of each of the 7 applicable fittings in those columns, 90deg elbow, long turn elbow, tee/cross, 45deg elbow, butterfly valve, gate valve or swing check valve. You can leave out trailing zeros eg. 0 means no fittings, 1 means 1 elbow or 004 means 4 tees
- Only if there is an operating head at the 'To' node, do you enter the "K" factor eg. 80 or 115 or any number from 1 to 999 and the minimum flow rate (normally density times area covered) in L/min eg. 100 or any number in the range 10 to 1999
These 7 or 9 numbers are typed in, separated by one or more 'spaces', but you do not have to line them up under the specific headings but it sometimes makes it easier to check. Neither must you put in the required decimal values so 3 is the same as 3.0 or 3.000 as a horizontal / vertical length. In any case, SHP4FPC automatically produces a .BAK version of your data file with any corrected data all aligned properly.
This data can be typed out in any line or screen based editor applicable to your operating system EDIT for MS.DOS, NotePad for Windows or Vi for Unix. You can save it whenever you want and at the end when completed. When you run SHP4FPC, you will either see the results in a separate file or may need to get back to your input data and correct one or more items given in the warning / error messages.
What to do when you have tried out SHP4FPC ...
What you have obviously realised is that SHP4FPC is not as 'user friendly' as my other FREEWARE programs nor others you may have already used. Well, that is because it does not have a USER INTERFACE!
The Free Pascal Compiler is NOT just for Windows which you are currently using - it can produce programs for a wide range of operating systems (remember MS.DOS?) all from the SAME listing. This is both a good thing and a bad thing. Good, because once you get a specific function working you can apply it everywhere but bad, because it does not have a general way of displaying items (edit boxes, command buttons, menus, graphics screens etc) as these vary enormously between operating systems. Hence the compromise. Oh, did I mention that this is all FREE?
If you have paid hundreds for your existing program (and hundreds more a year for updates), then it must come as a bit of a surprise that the actual coding for the flow and pressure CALCULATIONS is only about a hundred lines long! Much more of the program is devoted to checking the information, producing suitable warning or error messages and generating the results printout. The calculations part is the easiest bit (for me but not for you I suspect, which is the whole reason for this page) - conceiving the best way to get the user (you!) to enter the data with the minimum number of errors or problems is the hard part.
By showing you all this (reasonably easy to follow) listing, I wish to demonstrate how meticulous and exact the programmer has to be to cope with all foreseeable eventualities but it is not some 'black magic' that only really clever people can create. The mathematics involved is really trivial and the 'reducing error' calculation method is widely available, if you know where to look, which is why several independent companies have all come up with just variations on this basic procedure, as there is obviously only one 'correct' result for any given sprinkler hydraulic calculation. Well, you know where to look now - this webpage!
You can ignore this page entirely ...
It really does not matter if the 3 days or so that it has taken me to conceive and produce SHP4FPC has been entirely wasted if nobody ever does anything with the Pascal coding. You can just carry on with one or more of my other FREEWARE programs (such as FREESHP) or your existing software package. It was really the innovation of the £30 Raspberry Pi single board PC running Linux or the VIA APC single board PC running Android. So, in an effort to get other people interested in computer programming, I thought I would release the code listing to match the Free Pascal Compiler project, as being much better / faster than Basic.
You can continue with the Free Pascal Compiler ...
There are plenty of sites on the Internet devoted to the Delphi variant of Pascal - you can buy the XE starter version for about £200 up to the full package for over £2000. This will enable you to produce Windows programs like FREESHP, AACALC7 and others. However, Free Pascal is what it says it is; FREE. So although you can visit sites like www.delphibasics.co.uk and www.delphi.about.com and get one of the many excellent books about Delphi, these may need adapting slightly to work under the Free Pascal Compiler. There are extensive PDF files provided on the www.freepascal.org site and these will be a good place to start if you wish to learn Pascal. Remember the 80/20 rule - for 80% of the time you may only use 20% of your knowledge about a specific topic. Well in Pascal, this is more like 95/5 - it is capable of doing far more than you will ever need. Most people will find Pascal easier to learn and apply than other alternatives like Basic or C++.
You will therefore have your OWN program to extend, revise and make better to suit your individual requirements. The first place to start would be the Results section to include extra information or a better format - just look at the "paid for" alternatives for ideas. Just make any changes on a backup copy so if they don't work out you can return to the previous iteration. Best of Luck.
You may want to produce a version for another set of Sprinkler Rules ...
Obviously, I have decided to include the NFPA 13 / 15 Rules in the SHP4FPC program as more sprinkler systems have been installed to them in the World than all the other ones put together. For fog / mist systems to NFPA 750, you will need smaller sizes of different pipe types / fittings and the Darcy-Weisbach pressure drop formula so the density and viscosity of the fluid can be changed. For the FM Global Rules, you will need to revise the 'Fittings' lines for some more equivalent lengths, extend the part on the input data / results and may need to make 'fact1:=1.0;' in the ' //adjust for not S40' part.
[31st May 2012] If you are interested in LPS 1283 WATERMIST systems (following on from DD 8489), then you can easily modify my source code for the COLEBROOK-WHITE pressure drop equation. LPS 1283 requires that hydraulic calculations are made before and after testing for the various categories of hazard / protection, so if you have produced your OWN program you will able to substantiate those calculations rather than relying on 'bought in' software which will be based on the Hazen-Williams formula, only used in the fire protection industry. The Colebrook-White formula is used extensively for single- and two-pipe heating, pumped and gravity fed hot and cold water distribution systems, chilled water circulation and supply / extract ventilation systems etc. by the rest of the building industry as the density / viscosity / temperature of the fluid is included.
For the CEA, CEN, CP52, DBI, AS2008 etc. Rules you will have to replace the 'head min L/min' column with the 'area covered' (and possibly the density, minimum pressure), do a separate summation of area to compare with Q16, redo Q12-15 for 8 to 11 flow / pressure points on a water supply / pump curve (and polynomial curve fitting - look it up - you cannot use straight line interpolation as that just wouldn't be right) as well as identifying the 4 most remotest heads and the matching area / density calculation. The new format of the Results presentation could be copied from my AACALC7 or EASYSHP programs shown elsewhere on this website after you have revised the 'PipeTypes' and 'Fittings' arrays. You may find such an exercise quite instructive and compelling and more aware of what is actually involved in doing the full hydraulic calculations for your future jobs.
You may want to produce your own language version ...
All my existing programs and those other "paid for" programs are usually only available in English, which may not be your first language nor that of any reviewers to which you may have to send hydraulic calculations results printouts. Unfortunately, the Free Pascal Compiler and all it's documentation is also only available in English as these computer languages were all developed in English speaking counties. So whichever way you may want, you are going to have to learn English (unless you are using an on-line 'translate' service to read this text).
I have done my best to help out in this respect within SHP4FPC. Only the 'Questions' part (the first 25 lines on the results) and the text of the 2 lines within each 'ShowError' lines in the listing will need translating from English into your own language. You don't use commencer and fin in French for begin and end, you use begin and end (even in France) because they are Pascal keywords.
You would use an editor like NotePad to amend the appropriate lines in the listing below (putting // at the beginning of a line makes it a 'comment' which is ignored so just leave the 'English' lines there before your translation). Save the new .pp file and run the Free Pascal Compiler (as originally) to produce the new .exe version. In the spirit of OPEN SOURCE network, if you do create a matching version of SHP4FPC in another language, please let me know (Email at top of page) and I will either publish a link to it or show the corresponding listing on this webpage. I mean, were you going to make a charge for such a program?
If you prefer BASIC then please go back to the second heading above about SHP4MVB
Free Pascal source code listing of shp4fpc.pp
{ Copyright (C) 2012 Alan Ashfield
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.}
//
program shp4fpc;
//
uses sysutils;
//
function Trim(sstrg1:String):String;
// Removes leading/trailing blanks
begin
Trim:=TrimLeft(TrimRight(sstrg1));
end; //of Trim
//
function Num2Str(sval,slen,sdec:Single):String;
// formats a string:len:dec points
var sstrg:string;
begin
Str(sval:Trunc(ABS(slen)):Trunc(sdec),sstrg);
if slen<0 then sstrg:=Trim(sstrg);
Num2Str :=sstrg;
end; //of Num2Str
//
procedure ShowError(sstrg1,sstrg2:string);
// Shows 2 lines of messages on screen with 3rd blank
begin
WriteLn(sstrg1);
WriteLn(sstrg2);
WriteLn(' ');
end; //of ShowError
//
procedure AllInOne(filename:string);
var
numlines,numpipes,numheads,numsizes,numpipetypes :SmallInt;
numfittings,linenum,dspos,fromnode,tonode,sourcenode :Smallint;
nomsize,ptnum,ptypesnum,mmnum,nearmm,sizenum,fitnum :Smallint;
fitquant,headnum,pipenum,upstream,givenb4,minsizemm :SmallInt;
maxsizemm,numsteps,remotepipe,numnoflow,headsunder :Smallint;
headsover:Smallint;
staticp,residp,residf,darea,density,headsqm,m2bars :Single;
value,boremm,actboremm,horizm,vertm,actualm,fittingsm:Single;
eqlfeet,hwcfactor,boreS40,headkf,headlmin,maxmpers :Single;
headbars,fact1,fact2,maxheadm,pipelmin,pipebar :Single;
maxbars,sourcelmin,sourcebars,totallmin,errorbar :Single;
icode:LongInt;
lineofchars,origline,ss1,ss2,ss3,pttype,fittslist :String;
underline,bakfile,resultsfile:String;
inout:TextFile;
Sizemm : array[1..20] of SmallInt; //Nominal sizes
PipeTypes : array[1..10] of String; //Bores in mm
Fittings : array[1..10] of String; //Eq lengths
Questions : array[1..23] of String; //For results
JobData : array[1..1200] of String; //All input data
PipeI : array[1..9 ,1..1000] of Smallint; //Integer data
PipeS : array[1..19,1..1000] of Single; //Real data
PipeF : array[1..1000] of String[7]; //just fittings
begin
//
// SETUP
//
ShowError('SHP4FPC by Alan Ashfield - April 2012',
'Please visit www.freehc.net for more information');
ShowError('Developed with the Free Pascal Compiler V2.6.0',
'at www.freepascal.org for multiple operating systems');
Sizemm[1] :=25;
Sizemm[2] :=32;
Sizemm[3] :=40;
Sizemm[4] :=50;
Sizemm[5] :=65;
Sizemm[6] :=80;
Sizemm[7] :=90;
Sizemm[8] :=100;
Sizemm[9] :=125;
Sizemm[10] :=150;
Sizemm[11] :=200;
Sizemm[12] :=250;
Sizemm[13] :=300;
numsizes :=13; //no of above
PipeTypes[1] :='S40 26.60 35.10 40.90 52.50 62.70 77.90 90.10 '+
'102.26 128.20 154.10 202.70 254.50 303.20 120';
PipeTypes[2] :='MW 27.31 35.97 41.86 52.98 68.67 80.68 0.00 '+
'105.14 0.00 155.32 0.00 0.00 0.00 120';
PipeTypes[3] :='DIN 27.20 35.90 41.80 53.00 70.90 83.10 0.00 '+
'107.90 0.00 160.30 210.10 263.00 312.70 120';
numpipetypes :=3; //no of above
Fittings [1] :='EL 2.0 3.0 4.0 5.0 6.0 7.0 8.0 '+
' 10.0 12.0 14.0 18.0 22.0 27.0 ';
Fittings [2] :='LT 2.0 2.0 2.0 3.0 4.0 5.0 5.0 '+
' 6.0 8.0 9.0 13.0 16.0 18.0 ';
Fittings [3] :='TX 5.0 6.0 8.0 10.0 12.0 15.0 17.0 '+
' 20.0 25.0 30.0 35.0 50.0 60.0 ';
Fittings [4] :='45 1.0 1.0 2.0 2.0 3.0 3.0 3.0 '+
' 4.0 5.0 7.0 9.0 11.0 13.0 ';
Fittings [5] :='BV 0.0 0.0 0.0 6.0 7.0 10.0 0.0 '+
' 12.0 9.0 10.0 12.0 19.0 21.0 ';
Fittings [6] :='GV 0.0 0.0 0.0 1.0 1.0 1.0 1.0 '+
' 2.0 2.0 3.0 4.0 5.0 6.0 ';
Fittings [7] :='SC 5.0 7.0 9.0 11.0 14.0 16.0 19.0 '+
' 22.0 27.0 32.0 45.0 55.0 65.0 ';
numfittings :=7; //no of above
m2bars :=0.098; //metres to bars
// All this text will need translating into your language
Questions[1] :='Q1 Project name =';
Questions[2] :='Q2 Project number =';
Questions[3] :='Q3 Location =';
Questions[4] :='Q4 Drawings =';
Questions[5] :='Q5 Remotest area =';
Questions[6] :='Q6 Occupancy =';
Questions[7] :='Q7 System / Hazard =';
Questions[8] :='Q8 Contractor =';
Questions[9] :='Q9 Address =';
Questions[10]:='Q10 Designer =';
Questions[11]:='Q11 A.H.J. =';
Questions[12]:='Q12 Water supply =';
Questions[13]:='Q13 Static bars =';
Questions[14]:='Q14 Residual bars =';
Questions[15]:='Q15 Residual L/min =';
Questions[16]:='Q16 Application area =';
Questions[17]:='Q17 Density mm/min =';
Questions[18]:='Q18 Head area sq.m =';
Questions[19]:='Q19 Spare =';
Questions[20]:='Q20 Spare =';
Questions[21]:='Q21 Spare =';
Questions[22]:='Q22 Spare =';
Questions[23]:='Q23 Spare =';
//
// READ IN USERS DATA FILE
//
dspos :=Pos('.',filename);
bakfile :=Copy(filename,1,dspos)+'BAK';
resultsfile :=Copy(filename,1,dspos-1)+'Results.TXT';
numlines :=0;
ShowError('Started checking '+filename,'and creating '+bakfile);
// Open this file
Assign(inout,filename);
ReSet (inout);
While Not EOF(inout) do begin //read in all lines into JobData
ReadLn (inout,lineofchars);
numlines :=numlines+1;
JobData[numlines]:=Trim(lineofchars);
end;
// Close input file
Close(inout);
//
// Begin checking
//
Val(JobData[13],staticp,icode);
if staticp< 1.0 then staticp:=0.0;
if staticp>30.0 then staticp:=30.0;
Val(JobData[14],residp,icode);
if residp<0.0 then residp :=0.0;
if residp>staticp then residp :=staticp;
if residp>30.0 then residp :=30.0;
Val(JobData[15],residf,icode);
if residf<0.0 then residf :=0.0;
if residf>30000.0 then residf :=30000.0;
if (staticp>1.0) and (residf<500.0) then residf:=500.0;
Val(JobData[16],darea,icode);
if darea<0.0 then darea :=0.0;
if darea>2000.0 then darea :=2000.0;
Val(JobData[17],density,icode);
if density<0.0 then density:=0.0;
if density>99.0 then density:=99.0;
Val(JobData[18],headsqm,icode);
if headsqm<0.0 then headsqm:=0.0;
if headsqm>50.0 then headsqm:=50.0;
// Save BackUp file
JobData[13]:=Num2Str(staticp,-9,3);
JobData[14]:=Num2Str(residp,-9,3);
JobData[15]:=Num2Str(residf,-9,0);
JobData[16]:=Num2Str(darea,-9,1);
JobData[17]:=Num2Str(density,-9,2);
JobData[18]:=Num2Str(headsqm,-9,3);
Assign (inout,bakfile);
ReWrite (inout);
for linenum:=1 to 25 do WriteLn(inout,JobData[linenum]);
numpipes :=0;
numheads :=0;
maxheadm :=-99999.9;
minsizemm :=999;
maxsizemm :=0;
for pipenum:=1 to 1000 do begin
for icode:=1 to 9 do PipeI[icode,pipenum]:=0;
for icode:=1 to 19 do PipeS[icode,pipenum]:=0.0;
PipeF[pipenum]:=' ';
end;
//
// Now go through data line by line
//
for linenum :=26 to numlines do begin
lineofchars:=Trim(UpCase(JobData[linenum]))+' ';
origline :=lineofchars;
if Length(lineofchars)<10 then Continue; //skip cos too short
// Remove all double spaces in line
Repeat
dspos :=Pos(' ',lineofchars);
if dspos>0 then lineofchars:=Copy(lineofchars,1,dspos-1)+
' '+Copy(lineofchars,dspos+2,99);
Until dspos=0;
// Check From node
dspos :=Pos(' ',lineofchars);
Val(Copy(lineofchars,1,dspos-1),value,icode);
if value<0.0 then value:=0.0;
if value>9999.0 then value:=9999.0;
lineofchars:=Copy(lineofchars,dspos+1,99);
fromnode :=Trunc(value);
upstream :=0;
if numpipes=0 then sourcenode:=fromnode; //first pipe
if numpipes>0 then begin
// Check if at start
if fromnode=sourcenode then begin
ShowError('Pipe '+Num2Str(numpipes+1,6,0)+' = '+origline,
'From node equals first node = '+
Num2Str(sourcenode,-6,0));
fromnode:=0;
end;
// Find upstream pipe number
for pipenum:=1 to numpipes do
if (fromnode=PipeI[2,pipenum]) and (upstream=0) then
upstream:=pipenum;
// Error if not there
if (upstream=0) and (fromnode>0) then begin
tonode :=PipeI[2,numpipes];
ShowError('Pipe '+Num2Str(numpipes+1,6,0)+' = '+origline,
'From node '+Num2Str(fromnode,-6,0)+
' has not been given as a previous To node so'+
' changed to '+Num2Str(tonode,-6,0));
fromnode:=tonode;
upstream:=numpipes;
end;
end;
// Check To node
dspos :=Pos(' ',lineofchars);
Val(Copy(lineofchars,1,dspos-1),value,icode);
if value<0.0 then value:=0.0;
if value>9999.0 then value:=9999.0;
lineofchars:=Copy(lineofchars,dspos+1,99);
tonode :=Trunc(value);
// Check if same as From node
if fromnode=tonode then begin
ShowError('Pipe '+Num2Str(numpipes+1,6,0)+' = '+origline,
'From node equals To node = '+
Num2Str(tonode,-6,0));
fromnode:=0;
tonode :=0;
end;
// Check if at start
if tonode=sourcenode then begin
ShowError('Pipe '+Num2Str(numpipes+1,6,0)+' = '+origline,
'To node equals first From node = '+
Num2Str(tonode,-6,0));
fromnode:=0;
tonode :=0;
end;
// Check if a repeat
if (numpipes>0) and (tonode>0) then begin
givenb4 :=0;
for pipenum:=1 to numpipes do
if (tonode=PipeI[2,pipenum]) and
(givenb4=0) then givenb4:=pipenum;
if givenb4>0 then begin
ShowError('Pipe '+Num2Str(numpipes+1,6,0)+' = '+origline,
'To node of '+Num2Str(tonode,-6,0)+
' repeats a previous To node at pipe '+
Num2Str(givenb4,-6,0)+' so has been deleted.');
fromnode:=0;
tonode :=0;
end;
// Check if a duplicate
givenb4:=0;
for pipenum:=1 to numpipes do
if (fromnode=PipeI[1,pipenum]) and
(tonode =PipeI[2,pipenum]) and
(givenb4=0) then givenb4:=pipenum;
if givenb4>0 then begin
ShowError('Pipe '+Num2Str(numpipes+1,6,0)+' = '+origline,
'Is a repeat of previous pipe '+
Num2Str(givenb4,-6,0)+' so has been deleted.');
fromnode:=0;
tonode :=0;
end;
end;
if (fromnode=0) or (tonode=0) then Continue; //skip to next
// Check nominal pipe size
dspos :=Pos(' ',lineofchars);
Val(Copy(lineofchars,1,dspos-1),value,icode);
if value<0.0 then value:=0.0;
if value>9999.0 then value:=9999.0;
lineofchars:=Copy(lineofchars,dspos+1,99);
nomsize :=Trunc(value);
// Check pipe type given
dspos :=Pos(' ',lineofchars);
pttype :=Copy(lineofchars,1,dspos-1);
lineofchars:=Copy(lineofchars,dspos+1,99);
ptnum :=0;
for ptypesnum:=1 to numpipetypes do //check if in list
if pttype=Copy(PipeTypes[ptypesnum],1,Length(pttype)) then
ptnum:=ptypesnum;
if ptnum=0 then begin
ShowError('Pipe '+Num2Str(numpipes+1,6,0)+' = '+origline,
'Pipe type = '+pttype+' is not in database so'+
' changed to '+Copy(PipeTypes[1],1,4));
ptnum :=1;
end;
ss1 :=Trim(Copy(PipeTypes[ptnum],
Length(PipeTypes[ptnum])-5,6));
Val(ss1,hwcfactor,icode);
// Check nominal size exists
mmnum :=0;
actboremm :=0.0;
nearmm :=999;
for sizenum:=1 to numsizes do begin
ss1 :=Trim(Copy(PipeTypes[ptnum],4+(sizenum-1)*7,7));
Val(ss1,boremm,icode);
if (Abs(nomsize-Sizemm[sizenum])<=nearmm) and
(boremm>=1.0) then begin
nearmm :=Abs(nomsize-Sizemm[sizenum]);
mmnum :=sizenum;
actboremm:=boremm;
end;
end;
if nearmm<>0 then begin
ShowError('Pipe '+Num2Str(numpipes+1,6,0)+' = '+origline,
'Pipe size of '+Num2Str(nomsize,-6,0)+
' mm is not available in pipe type '+
Copy(PipeTypes[ptnum],1,4)+
' so changed to nearest of '+
Num2Str(Sizemm[mmnum],-6,0)+' mm');
nomsize:=Sizemm[mmnum];
end;
if nomsize<=minsizemm then minsizemm:=nomsize;
if nomsize>=maxsizemm then maxsizemm:=nomsize;
// Check this size is not BIGGER than upstream pipe
if upstream>0 then begin
if nomsize>PipeI[3,upstream] then
ShowError('Pipe '+Num2Str(numpipes+1,6,0)+' = '+origline,
'Pipe size of '+Num2Str(nomsize,-6,0)+
' mm is BIGGER than upstream pipe '+
Num2Str(PipeI[1,upstream],-6,0)+' to '+
Num2Str(PipeI[2,upstream],-6,0)+' which is '+
Num2Str(PipeI[3,upstream],-6,0)+' mm');
end;
// Check horizontal pipe length
dspos :=Pos(' ',lineofchars);
Val(Copy(lineofchars,1,dspos-1),value,icode);
if value<0.0 then value:=0.0;
if value>500.0 then value:=500.0;
lineofchars:=Copy(lineofchars,dspos+1,99);
horizm :=value;
// Check vertical pipe length
dspos :=Pos(' ',lineofchars);
Val(Copy(lineofchars,1,dspos-1),value,icode);
if value<-50.0 then value:=-50.0;
if value>50.0 then value:=50.0;
lineofchars:=Copy(lineofchars,dspos+1,99);
vertm :=value;
actualm :=Sqrt(horizm*horizm+vertm*vertm);
if actualm<0.1 then actualm:=0.1;
fittingsm :=0.0;
// Check fittings
dspos :=Pos(' ',lineofchars);
fittslist :=Copy(lineofchars,1,dspos-1)+'0000000000';
lineofchars:=Copy(lineofchars,dspos+1,99);
fact1 :=1.0;
ss1 :=Trim(Copy(PipeTypes[1],4+(mmnum-1)*7,7));
Val(ss1,boreS40,icode);
if (ptnum<>1) and (boreS40>1.0) then //adjust for not S40
fact1:=Exp(Ln(actboremm/boreS40)*4.87);
fact2 :=Exp(Ln(hwcfactor/120.0)*1.85); //adjust for not 120
for fitnum :=1 to numfittings do begin
Val(Copy(fittslist,fitnum,1),fitquant,icode);
if fitquant>0 then begin
ss1 :=Trim(Copy(Fittings[fitnum],4+(mmnum-1)*7,7));
Val(ss1,eqlfeet,icode);
fittingsm:=fittingsm+(fitquant*eqlfeet*0.3048*fact1*fact2);
end;
end;
// Check head k factor and minimum flow rate
headkf :=0.0;
headlmin:=0.0;
headbars:=0;
headnum :=0;
if Length(lineofchars)>3 then begin
dspos :=Pos(' ',lineofchars);
Val(Copy(lineofchars,1,dspos-1),value,icode);
if value<1.0 then value:=1.0;
if value>999.0 then value:=999.0;
lineofchars:=Copy(lineofchars,dspos+1,99);
headkf :=value;
dspos :=Pos(' ',lineofchars);
Val(Copy(lineofchars,1,dspos-1),value,icode);
if value<10.0 then value:=10.0;
if value>1999.0 then value:=1999.0;
headlmin :=value;
value :=(headlmin*headlmin)/(headkf*headkf);
if value<7.0*0.0689 then headlmin:=headkf*Sqrt(7.0*0.0689);
if value>12.0 then headlmin:=headkf*Sqrt(12.0);
headbars :=(headlmin*headlmin)/(headkf*headkf);
numheads :=numheads+1;
headnum :=numheads;
end;
//
// Remember all this data
//
value :=(actualm+fittingsm)*605000.0/
Exp(Ln(hwcfactor)*1.85)/Exp(Ln(actboremm)*4.87);
numpipes :=numpipes+1;
if numpipes>1000 then numpipes:=1000;
PipeI[1 ,numpipes]:=fromnode; //From or start node 1-9999
PipeI[2 ,numpipes]:=tonode; //To or end node 1-9999
PipeI[3 ,numpipes]:=nomsize; //size in mm 25-300
PipeI[4 ,numpipes]:=mmnum; //size code 1-13
PipeI[5 ,numpipes]:=ptnum; //pipe type 1-3
PipeI[6 ,numpipes]:=upstream; //upstream pipe number 0-numpipes
PipeI[7 ,numpipes]:=headnum; //head number or 0 if none
PipeI[8 ,numpipes]:=0; //Spare
PipeI[9 ,numpipes]:=0; //spare
PipeS[1 ,numpipes]:=actualm; //length in m 0.1-999
PipeS[2 ,numpipes]:=vertm; //elevation change in m 0 to +-50
PipeS[3 ,numpipes]:=actboremm; //internal diameter in mm
PipeS[4 ,numpipes]:=fittingsm; //fittings equivalent length
PipeS[5 ,numpipes]:=hwcfactor; //pipe "C" factor 120
PipeS[6 ,numpipes]:=vertm; //height of end node in m
if upstream>0 then Pipes[6,numpipes]:=Pipes[6,upstream]+vertm;
PipeS[7 ,numpipes]:=headkf; //0 or head "K" factor 1-999
PipeS[8 ,numpipes]:=headlmin; //0 or head minimum flow
PipeS[9 ,numpipes]:=headbars; //0 or head min pressure
PipeS[10,numpipes]:=headlmin; //actual head flow rate
PipeS[11,numpipes]:=headbars; //actual head pressure
PipeS[12,numpipes]:=value; //H-W formula so just Q^1.85 to do
PipeS[13,numpipes]:=0.0; //Calculated flow rate
PipeS[14,numpipes]:=0.0; //Calculated pressure drop
PipeS[15,numpipes]:=0.0; //Velocity m/s
PipeS[16,numpipes]:=0.0; //Total pressure drop from source
PipeS[17,numpipes]:=0.0; //Start pressure bars
PipeS[18,numpipes]:=0.0; //End pressure bars
PipeS[19,numpipes]:=0.0; //Spare
PipeF[numpipes] :=fittslist; //7 fitting quants
if (headnum>0) and (PipeS[6,numpipes]>maxheadm) then
maxheadm:=PipeS[6,numpipes];
ss1:=Num2Str(fromnode,4,0)+Num2Str(tonode,5,0)+
Num2Str(nomsize,4,0)+' '+Copy(PipeTypes[ptnum],1,4)+
Num2Str(horizm,8,3)+Num2Str(vertm,8,3)+' '+
Copy(fittslist,1,numfittings);
if headkf>0 then ss1:=ss1+Num2Str(headkf,7,1)+
Num2Str(headlmin,8,2);
WriteLn(inout,ss1); //same formatted line
end; //of each pipe line so close backup file
Close(inout);
//
// START CALCULATIONS
//
ShowError('Started on calculations for '+Num2Str(numpipes,-6,0)+
' pipes to '+Num2Str(numheads,-6,0)+' heads',
'Pipe sizes from '+Num2Str(minsizemm,-6,0)+' to '+
Num2Str(maxsizemm,-6,0)+' mm and highest head = '+
Num2Str(maxheadm,-12,3)+' m');
numsteps :=0;
remotepipe :=0;
Repeat
numsteps :=numsteps+1;
for pipenum:=1 to numpipes do PipeS[13,pipenum]:=0.0;
// Cumulate head flows in pipes back to source
for pipenum:=1 to numpipes do begin
if PipeI[7,pipenum]>0 then begin
upstream :=pipenum;
pipelmin :=PipeS[10,pipenum];
Repeat
PipeS[13,upstream]:=PipeS[13,upstream]+pipelmin;
upstream :=PipeI[6 ,upstream];
Until upstream=0;
end; //next head
end; //next pipe
// Calculate pipe pressure drops
for pipenum:=1 to numpipes do begin
pipebar :=0.0;
if PipeS[13,pipenum]>0.001 then //cant do Ln(0)
pipebar :=PipeS[12,pipenum]*
Exp(Ln(PipeS[13,pipenum])*1.85);
PipeS[14,pipenum]:=pipebar;
end;
// Calculate total pressure drop to heads
maxbars :=-99999.9;
errorbar:=-99999.9;
for pipenum:=1 to numpipes do PipeS[16,pipenum]:=0.0;
for pipenum:=1 to numpipes do begin
if PipeI[7,pipenum]>0 then begin
upstream :=pipenum;
pipebar :=PipeS[11,pipenum]+
PipeS[6,pipenum]*m2bars;
Repeat
pipebar :=pipebar+PipeS[14,upstream];
upstream :=PipeI[6 ,upstream];
Until upstream=0;
PipeS[16,pipenum] :=pipebar;
if pipebar>maxbars then begin
maxbars :=pipebar;
if numsteps=1 then remotepipe:=pipenum;
end;
end; //next head
end; //next pipe
sourcelmin:=PipeS[13,1];
sourcebars:=PipeS[16,remotepipe];
totallmin :=0.0;
// Check against specified source if given
if (staticp >1.0) and
(residp >0.8) and
(residf >400.0) then begin
sourcebars:=staticp-(staticp-residp)*
Exp(Ln(sourcelmin/residf)*1.85);
if sourcebars<=residp then sourcebars:=residp;
end;
// Calculate new flows / pressures at heads
for pipenum:=1 to numpipes do begin
if PipeI[7,pipenum]>0 then begin
value :=PipeS[11,pipenum];
PipeS[11,pipenum]:=value+0.5*
(sourcebars-PipeS[16,pipenum]);
if PipeS[11,pipenum]<0.001 then
PipeS[11,pipenum]:=0.001;
PipeS[10,pipenum]:=PipeS[7,pipenum]*
Sqrt(PipeS[11,pipenum]);
totallmin :=totallmin+PipeS[10,pipenum];
if Abs(PipeS[11,pipenum]-value)>errorbar then
errorbar:=Abs(PipeS[11,pipenum]-value);
end; //next head
end; //next pipe
// Remove comments to see progress of calcs
{ShowError('Step '+Num2Str(numsteps,5,0)+Num2Str(sourcelmin,12,3)+
' L/min at'+Num2Str(sourcebars,12,6)+' bar',
'Errors ='+Num2Str(Abs(sourcelmin-totallmin),12,6)+
' L/min and'+Num2Str(errorbar,12,6)+' bar',);}
Until (errorbar<0.0005) or (numsteps>299);
//
// Calculations all balanced - do velocities / end pressures
//
maxmpers :=0.0;
numnoflow :=0;
headsunder :=0;
headsover :=0;
for pipenum:=1 to numpipes do begin
PipeS[15,pipenum] :=PipeS[13,pipenum]*1000.0/60.0/
(Pi*PipeS[3,pipenum]*PipeS[3,pipenum]);
if PipeS[15,pipenum]>maxmpers then maxmpers:=PipeS[15,pipenum];
if PipeS[13,pipenum]<0.01 then
numnoflow :=numnoflow+1;
value :=PipeS[2,pipenum]*m2bars;
upstream :=PipeI[6,pipenum];
if pipenum=1 then begin //first pipe
PipeS[17,1] :=sourcebars;
PipeS[18,1] :=sourcebars-PipeS[14,1]-value;
end;
if upstream>0 then begin //subsequent pipes
PipeS[17,pipenum]:=PipeS[18,upstream];
PipeS[18,pipenum]:=PipeS[17,pipenum]-PipeS[14,pipenum]-value;
end;
if PipeI[7,pipenum]>0 then begin //check over / under pressure
if PipeS[11,pipenum]>=12.0 then headsover:=headsover+1;
if (PipeS[10,pipenum]<=PipeS[8,pipenum]-0.001) or
(PipeS[11,pipenum]<=PipeS[9,pipenum]-0.001) then
headsunder :=headsunder+1;
end;
end; //next pipe
ShowError('Source flow = '+Num2Str(sourcelmin,-12,1)+' L/min at '+
Num2Str(sourcebars,-12,3)+' bars','Balanced in '+
Num2Str(numsteps,-6,0)+' steps, errors '+
Num2Str(errorbar,-12,6)+' bars + '+
Num2Str(Abs(sourcelmin-totallmin),-12,3)+' L/min');
// Give any error messages
if (sourcelmin>=30000.0) or (sourcebars>=30.0) then
ShowError('This appears much too high to be right',
'Perhaps wrong K factors, min flows or undersized'+
' pipes');
if headsunder>0 then
ShowError('There are '+Num2Str(headsunder,-6,0)+
' heads under their minimum flows / pressures',
'Perhaps caused by excessive pressure drops,'+
' undersized pipes or inadequate water supply');
if headsover >0 then
ShowError('There are '+Num2Str(headsover,-6,0)+
' heads with pressures over 12 bars',
'Perhaps too high water supply or execessive'+
' flows based on their K factors');
if maxmpers >20 then
ShowError('Maximum velocity is '+
Num2Str(maxmpers,-9,2)+' m/s',
'Perhaps one or more pipes are undesized or flows'+
' are higher than anticipated');
if numnoflow>0 then
ShowError('There are '+Num2Str(numnoflow,-6,0)+
' pipes with zero flow rate',
'Perhaps they do not feed any operating heads or'+
' you have not finished the input data yet');
if (staticp>1.0) and (sourcelmin>residf) then
ShowError('The source flow of '+
Num2Str(sourcelmin,-9,1)+' L/min exceeds the '+
Num2Str(residf,-9,1)+' L/min given in'+
' question 15',
'The Q15 value has been ignored so the source'+
' pressure is the '+Num2Str(residp,-9,3)+
' bars in Q14');
//
// START ON RESULTS PRINTOUT
//
Assign (inout,resultsfile);
ReWrite(inout);
WriteLn(inout,'START OF RESULTS PRINTOUT FROM SHP4FPC BY ALAN ASHFIELD');
WriteLn(inout,' ');
// First 18 lines of Questions
for linenum:=1 to 18 do begin
ss1 :=Questions[linenum]+' '+JobData[linenum];
WriteLn(inout,ss1);
end;
WriteLn(inout,' ');
// Source duty
ss1 :='SOURCE DUTY AT NODE '+Num2Str(sourcenode,-6,0)+' = '+
Num2Str(sourcelmin,-9,1)+' L/min at '+
Num2Str(sourcebars,-9,3)+' bars';
WriteLn(inout,ss1);
WriteLn(inout,' ');
// Remotest head
ss1 :='Remote head is at node '+
Num2Str(PipeI[2, remotepipe],-6,0)+' = '+
Num2Str(PipeS[13,remotepipe],-9,1)+' L/min, '+
Num2Str(PipeS[18,remotepipe],-9,3)+' bars and '+
Num2Str(PipeS[6, remotepipe],-9,3)+' m';
WriteLn(inout,ss1);
WriteLn(inout,' ');
// Any other summaries you want can go here
//
// Show headings
//
WriteLn(inout,'Node1 Flow Q S i z e Fittings'+
' Length Type Pt');
WriteLn(inout,' Heights Kfactor Head q mm ELT4BGS'+
' Fitts Cfactor Pe');
WriteLn(inout,'Node2 L/min B o r e LTX5VVC'+
' Totalm mbar/m Pf');
underline:= '------------------------------------------------'+
'--------------------------';
WriteLn(inout,underline);
for pipenum:=1 to numpipes do begin
// Line 1 of 3
ss1:=Num2Str(PipeI[1 ,pipenum],5,0)+
Num2Str(PipeS[6 ,pipenum]-PipeS[2,pipenum],8,3)+
' '+
Num2Str(PipeS[13,pipenum],8,1)+
Num2Str(PipeI[3 ,pipenum],6,0)+' '+' '+
Num2Str(PipeS[1 ,pipenum],8,3)+' '+
Copy(PipeTypes[PipeI[5,pipenum]],1,4)+' '+
Num2Str(PipeS[17,pipenum],9,3);
WriteLn(inout,ss1);
// Line 2 of 3
ss2:=Num2Str(PipeS[7 ,pipenum],8,1);
ss3:=Num2Str(PipeS[10,pipenum],8,1);
if PipeS[7,pipenum]<0.1 then ss2:=' ';
if PipeS[7,pipenum]<0.1 then ss3:=' ';
ss1:=' '+' '+ss2+ss3+' '+' '+
PipeF[pipenum]+
Num2Str(PipeS[4,pipenum],8,3)+
Num2Str(PipeS[5,pipenum],7,0)+' '+
Num2Str(PipeS[2,pipenum]*m2bars,9,3);
WriteLn(inout,ss1);
// Line 3 of 3
value:=PipeS[14,pipenum]*1000.0/
(PipeS[1,pipenum]+PipeS[4,pipenum]);
ss1:=Num2Str(PipeI[2,pipenum],5,0)+
Num2Str(PipeS[6,pipenum],8,3)+' '+' '+
Num2Str(PipeS[3,pipenum],9,2)+' '+
Num2Str(PipeS[1,pipenum]+PipeS[4,pipenum],8,3)+
Num2Str(value,9,1)+Num2Str(PipeS[14,pipenum],9,3);
WriteLn(inout,ss1);
WriteLn(inout,underline);
end; //next pipe
WriteLn(inout,' ');
WriteLn(inout,'END OF PRINTOUT FROM SHP4FPC BY ALAN ASHFIELD');
Close(inout);
ShowError('Results now stored in '+resultsfile,
'End of SHP4FPC by Alan Ashfield - www.freehc.net');
end;
//
// MAIN PROGRAM STARTS HERE
//
begin
if FileExists(ParamStr(1))=False then
ShowError('You have missed out the job file name'+
' - correct command is',
'shp4fpc \directory\file name '+
' eg. shp4fpc \jobs\myjob1.txt');
if FileExists(ParamStr(1))=True then AllInOne(ParamStr(1));
end. //of shp4fpc by Alan Ashfield
Typical Data File - 2 ranges of 3 heads
First Test Example 1 Somewhere over the rainbow Drawings Most Remote Dont know Ordinary Hazard Put your name here Your address Alan Ashfield AHJ Calculate min duty 0 0 0 54.0 10.00 9.00 Q19 Q20 Q21 Q22 Q23 From To Size Type Pipe lengths ELT4BGS Head / Nozzle node node mm Horiz m Vert m LTX5VVC Kfact L/min 100 110 100 S40 0.0 1.5 000001 110 120 100 S40 0.0 3.0 00001 120 130 100 S40 30 0.0 1 130 131 40 S40 0.0 0.5 001 131 132 40 S40 1.0 0.0 1 80 90 132 133 32 S40 3.0 0.0 0 80 90 133 134 25 S40 3.0 0.0 0 80 90 130 140 65 S40 3.0 0.0 0 140 141 40 S40 0.0 0.5 001 141 142 40 S40 1.0 0.0 1 80 90 142 143 32 S40 3.0 0.0 0 80 90 143 144 25 S40 3.0 0.0 0 80 90
That's All Folks ...
Really critical or observant people may have realised that there are one or two superfluous equals signs '=' in some if---then statements above - although my underlying source code was right, some browsers corrupted the following lines - presumably looking at the '>' and '<' symbols and changing the HTML code! I could not find anyway around this - right click on the code and select "View Source ..." to check.