From 2e22456896c8fb6151c9014b40e0335ebc4cb288 Mon Sep 17 00:00:00 2001 From: JinduanChen Date: Tue, 22 Jan 2013 11:27:12 -0500 Subject: [PATCH 01/49] Set up the environment for building with VS 2012 --- .gitignore | 35 ++++ LemonTigerJ.sln | 20 ++ LemonTigerJ.v11.suo | Bin 0 -> 5632 bytes LemonTigerJ.vcxproj | 101 ++++++++++ src/epanet.c | 13 +- src/hydraul.c | 2 +- test/Net3.inp | 480 ++++++++++++++++++++++++++++++++++++++++++++ test/Net3.rpt | 102 ++++++++++ 8 files changed, 744 insertions(+), 9 deletions(-) create mode 100644 LemonTigerJ.sln create mode 100644 LemonTigerJ.v11.suo create mode 100644 LemonTigerJ.vcxproj create mode 100644 test/Net3.inp create mode 100644 test/Net3.rpt diff --git a/.gitignore b/.gitignore index 4d37fe3..163692f 100644 --- a/.gitignore +++ b/.gitignore @@ -27,3 +27,38 @@ Debug/ *.mode1v3 *.mode2v3 + +# Visual Studio 2012 +*.sdf +*.filters +*.user +*.cdf +*.cache +*.obj +*.ilk +*.resources +*.tlb +*.tli +*.tlh +*.tmp +*.rsp +*.pgc +*.pgd +*.meta +*.tlog +*.manifest +*.res +*.pch +*.exp +*.idb +*.rep +*.xdc +*.pdb +*_manifest.rc +*.bsc +*.sbr +*.xml +*.metagen +*.bi +*.opensdf + diff --git a/LemonTigerJ.sln b/LemonTigerJ.sln new file mode 100644 index 0000000..f61001a --- /dev/null +++ b/LemonTigerJ.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2012 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LemonTigerJ", "LemonTigerJ.vcxproj", "{4B66D9F0-407B-4995-B625-1CA1B72662C6}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {4B66D9F0-407B-4995-B625-1CA1B72662C6}.Debug|Win32.ActiveCfg = Debug|Win32 + {4B66D9F0-407B-4995-B625-1CA1B72662C6}.Debug|Win32.Build.0 = Debug|Win32 + {4B66D9F0-407B-4995-B625-1CA1B72662C6}.Release|Win32.ActiveCfg = Release|Win32 + {4B66D9F0-407B-4995-B625-1CA1B72662C6}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/LemonTigerJ.v11.suo b/LemonTigerJ.v11.suo new file mode 100644 index 0000000000000000000000000000000000000000..b5f0829270d526e8943e58d72aaeeb971bed6014 GIT binary patch literal 5632 zcmeHLO-NKx6h2S0()_87ixx3Zlr0*vWD*Mt%xWkp`Z2J97^iVmw3%j}G%X?mp+#ja zY*7#-w5bRQB#I)ag^T`?Y7>PnUD={61D(F_&3nUZV0>>TCvliF+;`7C=iYbz-`soO zzgsan@L=VbBtg9t%1o?S7Mth_@B(AJTx1b&(q>|@7|DfbK=ZJGJaABg_^INMMmdQ- zEN2)>+fXS*iI^vHBgN{_y_S)uzuqXt;O}6v01iN6P&&m8>21IoB^qbgd{!bO&F;3d ztQ3=wz8dV89$4Ka9gxo!kV6=I(fpb&)%v_t-5M!SSOcsD>XB+*GX089u#&$yd12BR z^3%4TuD`6mX9@agvjcUUHO)pS!5jmRQ}WMT@xcGA|8Lg@KO6P06%6ufKI*>$a&xHu z6>~1aG)pkozp=ImtN0x-*FAY0F9nZy9&*nE#-5IG=6@LTfH?mb7eY{2~ozbDKadSbS@29IZoi~7JyzROsYqUZjLa`{fX^11&s_CHqg zx1^A3kTcnTasN4FykHJ`+HF9(uS>W7^EGdHIyZW&{I^m6$~@QqUwacf`ERa&JM*pP zm@~m@ZZ`P;BHy$&Bh}g)q)t3?L?Spahw=2_5Pup6X^uRy6C)pv*xeZOdV&1iIB2V~ z2h>)K{1U=(oAXtSB3R`^e+pc$b}UzMA>jn={^Nmd+p8Xi)?Rn-UDtQ3j@p`(*U$_s z=u_eb#LpoCi1$KShwOrqT~I0lyb5;`wc?WXP^<}bA7%x?3F5|rHz&=YMRbK7+WkR~ zoB%BdUNwGB*@%_R(tsz|nhlMQ{gB|-%p6vyTHpSB{$%od?}qw{iMv*2mhJNgRN1=v zZ11BBO@l2H>AIjZJMm+*8TAN^jiNcFT{^x@y}0yjXuQAw=D7Rn>%&&2*)k Pj{mq*@%zKegzx_V-n=}~ literal 0 HcmV?d00001 diff --git a/LemonTigerJ.vcxproj b/LemonTigerJ.vcxproj new file mode 100644 index 0000000..d8d39ca --- /dev/null +++ b/LemonTigerJ.vcxproj @@ -0,0 +1,101 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {4B66D9F0-407B-4995-B625-1CA1B72662C6} + Win32Proj + + + + Application + true + v110 + + + Application + false + v110 + + + + + + + + + + + + + true + + + true + + + + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS + MultiThreadedDebugDLL + Level3 + ProgramDatabase + Disabled + + + MachineX86 + true + Console + + + + + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + MultiThreadedDLL + Level3 + ProgramDatabase + + + MachineX86 + true + Console + true + true + + + + + + \ No newline at end of file diff --git a/src/epanet.c b/src/epanet.c index 34e8d53..25cd708 100755 --- a/src/epanet.c +++ b/src/epanet.c @@ -108,16 +108,10 @@ execute function x and set the error code equal to its return value. */ /*** New compile directives ***/ //(2.00.11 - LR) -//#define CLE /* Compile as a command line executable */ +#define CLE /* Compile as a command line executable */ //#define SOL /* Compile as a shared object library */ //#define DLL /* Compile as a Windows DLL */ -/*** Following lines are deprecated ***/ //(2.00.11 - LR) -//#ifdef DLL -//#include -//#include -//#endif - /*** Need to define WINDOWS to use the getTmpName function ***/ //(2.00.12 - LR) // --- define WINDOWS #undef WINDOWS @@ -1745,7 +1739,9 @@ int DLLEXPORT ENgetlinkvalue(int index, int code, float *value) } +/* int DLLEXPORT ENgetcurve(int curveIndex, int *nValues, float **xValues, float **yValues) // !sph +*/ /*---------------------------------------------------------------- ** Input: curveIndex = curve index ** Output: *nValues = number of points on curve @@ -1754,7 +1750,7 @@ int DLLEXPORT ENgetcurve(int curveIndex, int *nValues, float **xValues, float * ** Returns: error code ** Purpose: retrieves end nodes of a specific link **---------------------------------------------------------------- - */ + */ /* { int err = 0; @@ -1777,6 +1773,7 @@ int DLLEXPORT ENgetcurve(int curveIndex, int *nValues, float **xValues, float * return err; } +*/ /* ---------------------------------------------------------------- diff --git a/src/hydraul.c b/src/hydraul.c index a56e14a..fd3cfb9 100755 --- a/src/hydraul.c +++ b/src/hydraul.c @@ -205,7 +205,7 @@ int runhyd(long *t) if (Statflag) writehydstat(iter,relerr); /* solution info */ - _relativeError = relerr; + _relativeError = (int)relerr; _iterations = iter; /*** Updated 3/1/01 ***/ diff --git a/test/Net3.inp b/test/Net3.inp new file mode 100644 index 0000000..5355958 --- /dev/null +++ b/test/Net3.inp @@ -0,0 +1,480 @@ +[TITLE] +EPANET Example Network 3 +Example showing how the percent of Lake water in a dual-source +system changes over time. + +[JUNCTIONS] +;ID Elev Demand Pattern + 10 147 0 ; + 15 32 1 3 ; + 20 129 0 ; + 35 12.5 1 4 ; + 40 131.9 0 ; + 50 116.5 0 ; + 60 0 0 ; + 601 0 0 ; + 61 0 0 ; + 101 42 189.95 ; + 103 43 133.2 ; + 105 28.5 135.37 ; + 107 22 54.64 ; + 109 20.3 231.4 ; + 111 10 141.94 ; + 113 2 20.01 ; + 115 14 52.1 ; + 117 13.6 117.71 ; + 119 2 176.13 ; + 120 0 0 ; + 121 -2 41.63 ; + 123 11 1 2 ; + 125 11 45.6 ; + 127 56 17.66 ; + 129 51 0 ; + 131 6 42.75 ; + 139 31 5.89 ; + 141 4 9.85 ; + 143 -4.5 6.2 ; + 145 1 27.63 ; + 147 18.5 8.55 ; + 149 16 27.07 ; + 151 33.5 144.48 ; + 153 66.2 44.17 ; + 157 13.1 51.79 ; + 159 6 41.32 ; + 161 4 15.8 ; + 163 5 9.42 ; + 164 5 0 ; + 166 -2 2.6 ; + 167 -5 14.56 ; + 169 -5 0 ; + 171 -4 39.34 ; + 173 -4 0 ; + 177 8 58.17 ; + 179 8 0 ; + 181 8 0 ; + 183 11 0 ; + 184 16 0 ; + 185 16 25.65 ; + 187 12.5 0 ; + 189 4 107.92 ; + 191 25 81.9 ; + 193 18 71.31 ; + 195 15.5 0 ; + 197 23 17.04 ; + 199 -2 119.32 ; + 201 0.1 44.61 ; + 203 2 1 5 ; + 204 21 0 ; + 205 21 65.36 ; + 206 1 0 ; + 207 9 69.39 ; + 208 16 0 ; + 209 -2 0.87 ; + 211 7 8.67 ; + 213 7 13.94 ; + 215 7 92.19 ; + 217 6 24.22 ; + 219 4 41.32 ; + 225 8 22.8 ; + 229 10.5 64.18 ; + 231 5 16.48 ; + 237 14 15.61 ; + 239 13 44.61 ; + 241 13 0 ; + 243 14 4.34 ; + 247 18 70.38 ; + 249 18 0 ; + 251 30 24.16 ; + 253 36 54.52 ; + 255 27 40.39 ; + 257 17 0 ; + 259 25 0 ; + 261 0 0 ; + 263 0 0 ; + 265 0 0 ; + 267 21 0 ; + 269 0 0 ; + 271 6 0 ; + 273 8 0 ; + 275 10 0 ; + +[RESERVOIRS] +;ID Head Pattern + River 220.0 ; + Lake 167.0 ; + +[TANKS] +;ID Elevation InitLevel MinLevel MaxLevel Diameter MinVol VolCurve + 1 131.9 13.1 .1 32.1 85 0 ; + 2 116.5 23.5 6.5 40.3 50 0 ; + 3 129.0 29.0 4.0 35.5 164 0 ; + +[PIPES] +;ID Node1 Node2 Length Diameter Roughness MinorLoss Status + 20 3 20 99 99 199 0 Open ; + 40 1 40 99 99 199 0 Open ; + 50 2 50 99 99 199 0 Open ; + 60 River 60 1231 24 140 0 Open ; + 101 10 101 14200 18 110 0 Open ; + 103 101 103 1350 16 130 0 Open ; + 105 101 105 2540 12 130 0 Open ; + 107 105 107 1470 12 130 0 Open ; + 109 103 109 3940 16 130 0 Open ; + 111 109 111 2000 12 130 0 Open ; + 112 115 111 1160 12 130 0 Open ; + 113 111 113 1680 12 130 0 Open ; + 114 115 113 2000 8 130 0 Open ; + 115 107 115 1950 8 130 0 Open ; + 116 113 193 1660 12 130 0 Open ; + 117 263 105 2725 12 130 0 Open ; + 119 115 117 2180 12 130 0 Open ; + 120 119 120 730 12 130 0 Open ; + 121 120 117 1870 12 130 0 Open ; + 122 121 120 2050 8 130 0 Open ; + 123 121 119 2000 30 141 0 Open ; + 125 123 121 1500 30 141 0 Open ; + 129 121 125 930 24 130 0 Open ; + 131 125 127 3240 24 130 0 Open ; + 133 20 127 785 20 130 0 Open ; + 135 127 129 900 24 130 0 Open ; + 137 129 131 6480 16 130 0 Open ; + 145 129 139 2750 8 130 0 Open ; + 147 139 141 2050 8 130 0 Open ; + 149 143 141 1400 8 130 0 Open ; + 151 15 143 1650 8 130 0 Open ; + 153 145 141 3510 12 130 0 Open ; + 155 147 145 2200 12 130 0 Open ; + 159 147 149 880 12 130 0 Open ; + 161 149 151 1020 8 130 0 Open ; + 163 151 153 1170 12 130 0 Open ; + 169 125 153 4560 8 130 0 Open ; + 171 119 151 3460 12 130 0 Open ; + 173 119 157 2080 30 141 0 Open ; + 175 157 159 2910 30 141 0 Open ; + 177 159 161 2000 30 141 0 Open ; + 179 161 163 430 30 141 0 Open ; + 180 163 164 150 14 130 0 Open ; + 181 164 166 490 14 130 0 Open ; + 183 265 169 590 30 141 0 Open ; + 185 167 169 60 8 130 0 Open ; + 186 187 204 99.9 8 130 0 Open ; + 187 169 171 1270 30 141 0 Open ; + 189 171 173 50 30 141 0 Open ; + 191 271 171 760 24 130 0 Open ; + 193 35 181 30 24 130 0 Open ; + 195 181 177 30 12 130 0 Open ; + 197 177 179 30 12 130 0 Open ; + 199 179 183 210 12 130 0 Open ; + 201 40 179 1190 12 130 0 Open ; + 202 185 184 99.9 8 130 0 Open ; + 203 183 185 510 8 130 0 Open ; + 204 184 205 4530. 12 130 0 Open ; + 205 204 185 1325. 12 130 0 Open ; + 207 189 183 1350 12 130 0 Open ; + 209 189 187 500 8 130 0 Open ; + 211 169 269 646 12 130 0 Open ; + 213 191 187 2560 12 130 0 Open ; + 215 267 189 1230 12 130 0 Open ; + 217 191 193 520 12 130 0 Open ; + 219 193 195 360 12 130 0 Open ; + 221 161 195 2300 8 130 0 Open ; + 223 197 191 1150 12 130 0 Open ; + 225 111 197 2790 12 130 0 Open ; + 229 173 199 4000 24 141 0 Open ; + 231 199 201 630 24 141 0 Open ; + 233 201 203 120 24 130 0 Open ; + 235 199 273 725 12 130 0 Open ; + 237 205 207 1200 12 130 0 Open ; + 238 207 206 450 12 130 0 Open ; + 239 275 207 1430 12 130 0 Open ; + 240 206 208 510 12 130 0 Open ; + 241 208 209 885 12 130 0 Open ; + 243 209 211 1210 16 130 0 Open ; + 245 211 213 990 16 130 0 Open ; + 247 213 215 4285 16 130 0 Open ; + 249 215 217 1660 16 130 0 Open ; + 251 217 219 2050 14 130 0 Open ; + 257 217 225 1560 12 130 0 Open ; + 261 213 229 2200 8 130 0 Open ; + 263 229 231 1960 12 130 0 Open ; + 269 211 237 2080 12 130 0 Open ; + 271 237 229 790 8 130 0 Open ; + 273 237 239 510 12 130 0 Open ; + 275 239 241 35 12 130 0 Open ; + 277 241 243 2200 12 130 0 Open ; + 281 241 247 445 10 130 0 Open ; + 283 239 249 430 12 130 0 Open ; + 285 247 249 10 12 130 0 Open ; + 287 247 255 1390 10 130 0 Open ; + 289 50 255 925 10 130 0 Open ; + 291 255 253 1100 10 130 0 Open ; + 293 255 251 1100 8 130 0 Open ; + 295 249 251 1450 12 130 0 Open ; + 297 120 257 645 8 130 0 Open ; + 299 257 259 350 8 130 0 Open ; + 301 259 263 1400 8 130 0 Open ; + 303 257 261 1400 8 130 0 Open ; + 305 117 261 645 12 130 0 Open ; + 307 261 263 350 12 130 0 Open ; + 309 265 267 1580 8 130 0 Open ; + 311 193 267 1170 12 130 0 Open ; + 313 269 189 646 12 130 0 Open ; + 315 181 271 260 24 130 0 Open ; + 317 273 275 2230 8 130 0 Open ; + 319 273 205 645 12 130 0 Open ; + 321 163 265 1200 30 141 0 Open ; + 323 201 275 300 12 130 0 Open ; + 325 269 271 1290 8 130 0 Open ; + 329 61 123 45500 30 140 0 Open ; + 330 60 601 1 30 140 0 Closed ; + 333 601 61 1 30 140 0 Open ; + +[PUMPS] +;ID Node1 Node2 Parameters + 10 Lake 10 HEAD 1 ; + 335 60 61 HEAD 2 ; + +[VALVES] +;ID Node1 Node2 Diameter Type Setting MinorLoss + +[TAGS] + +[DEMANDS] +;Junction Demand Pattern Category + +[STATUS] +;ID Status/Setting + 10 Closed + +[PATTERNS] +;ID Multipliers +;General Default Demand Pattern + 1 1.34 1.94 1.46 1.44 .76 .92 + 1 .85 1.07 .96 1.1 1.08 1.19 + 1 1.16 1.08 .96 .83 .79 .74 + 1 .64 .64 .85 .96 1.24 1.67 +;Demand Pattern for Node 123 + 2 0 0 0 0 0 1219 + 2 0 0 0 1866 1836 1818 + 2 1818 1822 1822 1817 1824 1816 + 2 1833 1817 1830 1814 1840 1859 +;Demand Pattern for Node 15 + 3 620 620 620 620 620 360 + 3 360 0 0 0 0 360 + 3 360 360 360 360 0 0 + 3 0 0 0 0 360 360 +;Demand Pattern for Node 35 + 4 1637 1706 1719 1719 1791 1819 + 4 1777 1842 1815 1825 1856 1801 + 4 1819 1733 1664 1620 1613 1620 + 4 1616 1647 1627 1627 1671 1668 +;Demand Pattern for Node 203 + 5 4439 4531 4511 4582 4531 4582 + 5 4572 4613 4643 4643 4592 4613 + 5 4531 4521 4449 4439 4449 4460 + 5 4439 4419 4368 4399 4470 4480 + +[CURVES] +;ID X-Value Y-Value +;PUMP: Pump Curve for Pump 10 (Lake Source) + 1 0 104. + 1 2000. 92. + 1 4000. 63. +;PUMP: Pump Curve for Pump 335 (River Source) + 2 0 200. + 2 8000. 138. + 2 14000. 86. + +[CONTROLS] +;Lake source operates only part of the day +Link 10 OPEN AT TIME 1 +Link 10 CLOSED AT TIME 15 + +;Pump 335 controlled by level in Tank 1 +;When pump is closed, bypass pipe is opened +Link 335 OPEN IF Node 1 BELOW 17.1 +Link 335 CLOSED IF Node 1 ABOVE 19.1 +Link 330 CLOSED IF Node 1 BELOW 17.1 +Link 330 OPEN IF Node 1 ABOVE 19.1 + + +[RULES] + +[ENERGY] + Global Efficiency 75 + Global Price 0.0 + Demand Charge 0.0 + +[EMITTERS] +;Junction Coefficient + +[QUALITY] +;Node InitQual + +[SOURCES] +;Node Type Quality Pattern + +[REACTIONS] +;Type Pipe/Tank Coefficient + + +[REACTIONS] + Order Bulk 1 + Order Tank 1 + Order Wall 1 + Global Bulk 0.0 + Global Wall 0.0 + Limiting Potential 0.0 + Roughness Correlation 0.0 + +[MIXING] +;Tank Model + +[TIMES] + Duration 24:00 + Hydraulic Timestep 1:00 + Quality Timestep 0:05 + Pattern Timestep 1:00 + Pattern Start 0:00 + Report Timestep 1:00 + Report Start 0:00 + Start ClockTime 12 am + Statistic None + +[REPORT] + Status Yes + Summary No + Page 0 + +[OPTIONS] + Units GPM + Headloss H-W + Specific Gravity 1.0 + Viscosity 1.0 + Trials 40 + Accuracy 0.001 + CHECKFREQ 2 + MAXCHECK 10 + DAMPLIMIT 0 + Unbalanced Continue 10 + Pattern 1 + Demand Multiplier 1.0 + Emitter Exponent 0.5 + Quality Trace Lake + Diffusivity 1.0 + Tolerance 0.01 + +[COORDINATES] +;Node X-Coord Y-Coord + 10 9.00 27.85 + 15 38.68 23.76 + 20 29.44 26.91 + 35 25.46 10.52 + 40 27.02 9.81 + 50 33.01 3.01 + 60 23.90 29.94 + 601 23.00 29.49 + 61 23.71 29.03 + 101 13.81 22.94 + 103 12.96 21.31 + 105 16.97 21.28 + 107 18.45 20.46 + 109 17.64 18.92 + 111 20.21 17.53 + 113 22.04 16.61 + 115 20.98 19.18 + 117 21.69 21.28 + 119 23.70 22.76 + 120 22.08 23.10 + 121 23.54 25.50 + 123 23.37 27.31 + 125 24.59 25.64 + 127 29.29 26.40 + 129 30.32 26.39 + 131 37.89 29.55 + 139 33.28 24.54 + 141 35.68 23.08 + 143 37.47 21.97 + 145 33.02 19.29 + 147 30.24 20.38 + 149 29.62 20.74 + 151 28.29 21.39 + 153 28.13 22.63 + 157 24.85 20.16 + 159 23.12 17.50 + 161 25.10 15.28 + 163 25.39 14.98 + 164 25.98 15.14 + 166 26.48 15.13 + 167 25.88 12.98 + 169 25.68 12.74 + 171 26.65 11.80 + 173 26.87 11.59 + 179 25.71 10.40 + 181 25.72 10.74 + 183 25.45 10.18 + 184 25.15 9.52 + 185 25.01 9.67 + 187 23.64 11.04 + 189 24.15 11.37 + 191 22.10 14.07 + 193 22.88 14.35 + 195 23.18 14.72 + 197 20.97 15.18 + 199 29.42 8.44 + 201 30.89 8.57 + 203 31.14 8.89 + 204 23.80 10.90 + 205 29.20 6.46 + 206 31.66 6.64 + 207 31.00 6.61 + 208 32.54 6.81 + 209 33.76 6.59 + 211 34.20 5.54 + 213 35.26 6.16 + 215 39.95 8.73 + 217 42.11 8.67 + 219 44.86 9.32 + 225 43.53 7.38 + 229 36.16 3.49 + 231 38.38 2.54 + 237 35.37 3.08 + 239 35.76 2.31 + 241 35.87 2.11 + 243 37.04 0.00 + 247 35.02 2.05 + 249 35.02 1.81 + 251 34.15 1.10 + 253 32.17 1.88 + 255 33.51 2.45 + 257 21.17 23.32 + 259 20.80 23.40 + 261 20.79 21.45 + 263 20.32 21.57 + 265 25.39 13.60 + 267 23.38 12.95 + 269 25.03 12.14 + 271 25.97 11.00 + 273 29.16 7.38 + 275 31.07 8.29 + River 24.15 31.06 + Lake 8.00 27.53 + 1 27.46 9.84 + 2 32.99 3.45 + 3 29.41 27.27 + +[VERTICES] +;Link X-Coord Y-Coord + +[LABELS] +;X-Coord Y-Coord Label & Anchor Node + 8.00 29.42 "LAKE" + 25.00 31.10 "RIVER" + +[BACKDROP] + DIMENSIONS 6.16 -1.55 46.70 32.61 + UNITS None + FILE + OFFSET 0.00 0.00 + +[END] diff --git a/test/Net3.rpt b/test/Net3.rpt new file mode 100644 index 0000000..91c383f --- /dev/null +++ b/test/Net3.rpt @@ -0,0 +1,102 @@ + Page 1 Tue Jan 22 11:23:06 2013 + + ****************************************************************** + * E P A N E T * + * Hydraulic and Water Quality * + * Analysis for Pipe Networks * + * Version 2.00.12 * + ****************************************************************** + + Analysis begun Tue Jan 22 11:23:06 2013 + + + Hydraulic Status: + ----------------------------------------------------------------------- + 0:00:00: Balanced after 5 trials + 0:00:00: Reservoir River is emptying + 0:00:00: Reservoir Lake is closed + 0:00:00: Tank 1 is filling at 13.10 ft + 0:00:00: Tank 2 is emptying at 23.50 ft + 0:00:00: Tank 3 is filling at 29.00 ft + + 1:00:00: Pump 10 changed by timer control + 1:00:00: Balanced after 7 trials + 1:00:00: Reservoir Lake is emptying + 1:00:00: Pump 10 changed from closed to open + + 2:00:00: Balanced after 3 trials + 2:00:00: Tank 2 is filling at 20.90 ft + + 3:00:00: Balanced after 2 trials + + 4:00:00: Balanced after 3 trials + + 4:13:33: Pump 335 changed by Tank 1 control + 4:13:33: Pipe 330 changed by Tank 1 control + 4:13:33: Balanced after 4 trials + 4:13:33: Pipe 330 changed from closed to open + 4:13:33: Pump 335 changed from open to closed + + 5:00:00: Balanced after 3 trials + 5:00:00: Tank 3 is emptying at 34.30 ft + + 6:00:00: Balanced after 3 trials + 6:00:00: Tank 3 is filling at 34.12 ft + + 7:00:00: Balanced after 3 trials + + 8:00:00: Balanced after 2 trials + + 9:00:00: Balanced after 3 trials + 9:00:00: Tank 3 is emptying at 35.15 ft + + 10:00:00: Balanced after 2 trials + 10:00:00: Tank 1 is emptying at 22.20 ft + + 11:00:00: Balanced after 3 trials + 11:00:00: Tank 2 is emptying at 27.70 ft + + 12:00:00: Balanced after 2 trials + 12:00:00: Tank 2 is filling at 27.64 ft + + 13:00:00: Balanced after 3 trials + 13:00:00: Tank 1 is filling at 21.73 ft + + 14:00:00: Balanced after 3 trials + + 15:00:00: Pump 10 changed by timer control + 15:00:00: Balanced after 5 trials + 15:00:00: Reservoir Lake is closed + 15:00:00: Tank 1 is emptying at 21.98 ft + 15:00:00: Tank 2 is emptying at 28.20 ft + 15:00:00: Pump 10 changed from open to closed + + 16:00:00: Balanced after 3 trials + + 17:00:00: Balanced after 2 trials + + 18:00:00: Balanced after 3 trials + + 19:00:00: Balanced after 2 trials + + 20:00:00: Balanced after 3 trials + + 21:00:00: Balanced after 2 trials + + 21:19:39: Pump 335 changed by Tank 1 control + 21:19:39: Pipe 330 changed by Tank 1 control + 21:19:39: Balanced after 5 trials + 21:19:39: Tank 1 is filling at 17.10 ft + 21:19:39: Tank 3 is filling at 29.68 ft + 21:19:39: Pipe 330 changed from open to closed + 21:19:39: Pump 335 changed from closed to open + + 22:00:00: Balanced after 3 trials + 22:00:00: Tank 1 is emptying at 17.30 ft + + 23:00:00: Balanced after 3 trials + + 24:00:00: Balanced after 4 trials + 24:00:00: Tank 1 is filling at 15.79 ft + + Analysis ended Tue Jan 22 11:23:18 2013 From c622ad66b4840c1c314c8d18303460f574f1bd5e Mon Sep 17 00:00:00 2001 From: JinduanChen Date: Wed, 23 Jan 2013 00:35:11 -0500 Subject: [PATCH 02/49] Added one test case and three api functions. The test will run but WQ result is not accurate. --- src/lemontiger.c | 116 +++++++++++++++++++++++++++++++++++++++++++++++ src/lemontiger.h | 11 +++++ src/testLT.c | 82 +++++++++++++++++++++++++++++++++ 3 files changed, 209 insertions(+) create mode 100644 src/lemontiger.c create mode 100644 src/lemontiger.h create mode 100644 src/testLT.c diff --git a/src/lemontiger.c b/src/lemontiger.c new file mode 100644 index 0000000..5634d22 --- /dev/null +++ b/src/lemontiger.c @@ -0,0 +1,116 @@ +#include "types.h" +#include "vars.h" +#include "funcs.h" +#include "toolkit.h" +#include "lemontiger.h" + +extern char OutOfMemory; + + +int ENopeninitHQ() { + int errcode = 0; + Statflag = FALSE; //disable status report + + if (errcode = ENopenH()) return errcode; + + // Open WQ solver, but don't check SaveHflag as in ENopenQ() + ERRCODE(openqual()); + if (!errcode) OpenQflag = TRUE; + else { + errmsg(errcode); + return errcode; + } + + if (errcode = ENinitH(1)) return errcode; + if (errcode = ENinitQ(0)) return errcode; + + Rtime = Rstep; //use ENinitH()'s setup + return errcode; +} + +int ENrunstepHQ(long* pstime /* Simulation time pointer */ + , long* ptleft /* Time left in the simulation*/) { + long hydtime; /* Hydraulic solution time */ + long hydstep; /* Hydraulic time step */ + int errcode = 0; + long dt, hstep, tstep; + + /* Update reported simulation time */ + *pstime = Qtime; + + /* if needed, push forward hydraulic simulation */ + if (Qtime == Htime) + { + if ( (errcode = runhyd(&hydtime)) || + (errcode = nexthyd(&hydstep)) + ) return errcode; + /* If simulating WQ: */ + if (Qualflag != NONE && Qtime < Dur) { + + /* Compute reaction rate coeffs. */ + if (Reactflag && Qualflag != AGE) ratecoeffs(); + + /* Initialize pipe segments (at time 0) or */ + /* else re-orient segments if flow reverses.*/ + if (Qtime == 0) initsegs(); + else reorientsegs(); + } + Htime = hydtime + hydstep; + } + + /* run WQ simulation similar to stepqual() */ + tstep = Qstep; + + do + { + dt = tstep; + hstep = Htime - Qtime; + if (hstep < dt) + { + dt = hstep; + if (Qualflag != NONE) transport(dt); + Qtime += dt; + + /* if needed, push forward hydraulic simulation */ + if ( (errcode = runhyd(&hydtime)) || + (errcode = nexthyd(&hydstep)) + ) return errcode; + if (Qualflag != NONE && Qtime < Dur) { + + /* Compute reaction rate coeffs. */ + if (Reactflag && Qualflag != AGE) ratecoeffs(); + + /* Initialize pipe segments (at time 0) or */ + /* else re-orient segments if flow reverses.*/ + if (Qtime == 0) initsegs(); + else reorientsegs(); + } + + Htime = hydtime + hydstep; + + Qtime = hydtime; + } + else + { + if (Qualflag != NONE) transport(dt); + Qtime += dt; + } + tstep -= dt; + if (OutOfMemory) errcode = 101; + } while (!errcode && tstep > 0); + + *ptleft = Dur - Qtime; + if (!errcode && Saveflag && *ptleft == 0) errcode = savefinaloutput(); + return(errcode); +} + +int ENcloseHQ() { + int errcode = 0; + if ( (errcode = ENcloseQ()) || (errcode = ENcloseH()) ) + return errcode; + return errcode; +} + + + + \ No newline at end of file diff --git a/src/lemontiger.h b/src/lemontiger.h new file mode 100644 index 0000000..885f429 --- /dev/null +++ b/src/lemontiger.h @@ -0,0 +1,11 @@ +#ifndef LEMONTIGER_H +#define LEMONTIGER_H + +int ENopeninitHQ(); + +int ENrunstepHQ(long*, long*); + +int ENcloseHQ(); + + +#endif \ No newline at end of file diff --git a/src/testLT.c b/src/testLT.c new file mode 100644 index 0000000..97b29b9 --- /dev/null +++ b/src/testLT.c @@ -0,0 +1,82 @@ +/* Test file for epanet LemonTiger - Jinduan's version + The extension enables syncronized computation of hydraulics + and water quality */ + +#include +#include "types.h" +#include "vars.h" +#include "toolkit.h" +#include "lemontiger.h" + + +#ifdef CLE_LT + +int main(int argc, char* argv[]) { + int err = 0; //error code + long stime = 0; //simulation time point, = t = Htime + long step = 1; //time to next time point, = tstep = hydstep + long tleft = 0; //time left in the simulation + int id; // some node id + float value; // some node/link value + int TIME_A = 3600*10; + int TIME_B = 3600*20; //two time points for testing + + + /* Asychronous solver (old epanet) */ + + if (err=ENopen(argv[1], argv[2], "")) return err; + ENgetnodeindex("184", &id); + + for (ENopenH(), ENinitH(1), step=1; + // must save intermediate results to disk (initH(1)), otherwise WQ solver won't execute + step>0; ) { + + ENrunH(&stime); ENnextH(&step); + printf("stime = %d sec, step = %d sec.\n", stime, step); + + if (stime == TIME_A || stime == TIME_B) { // grab some results + ENgetnodevalue(id, EN_HEAD, &value); + printf("Node 184's head = %f.\n", value); + } + } + ENcloseH(); + + printf("Reset time pointer and run WQ.\n"); + for (ENopenQ(), ENinitQ(0), step=1; step>0; ) { + /* this operation resets the internal time pointer (back to 0)*/ + ENrunQ(&stime); ENnextQ(&step); + printf("stime = %d sec, step = %d sec.\n", stime, step); + + // grab some results + if (stime == TIME_A || stime == TIME_B) { + ENgetnodevalue(id, EN_QUALITY, &value); + printf("Node 184's quality = %f.\n", value); + } + } + ENcloseQ(); + ENclose(); + + + /* Sychronous solver (LemonTiger) */ + + if (err=ENopen(argv[1], argv[2], "")) return err; + + for (ENopeninitHQ(), tleft=Dur; tleft>0; ) { + ENrunstepHQ(&stime, &tleft); + printf("stime = %d sec, time left = %d sec.\n", stime, tleft); + + if (stime == TIME_A || stime == TIME_B) { + ENgetnodevalue(id, EN_HEAD, &value); + printf("Node 184's head = %f.\n", value); + ENgetnodevalue(id, EN_QUALITY, &value); + printf("Node 184's quality = %f.\n", value); + } + } + ENcloseHQ(); + ENclose(); + + +} + + +#endif \ No newline at end of file From 9f8dcadb58558a8136ca3568b0df84c4dd268bcd Mon Sep 17 00:00:00 2001 From: JinduanChen Date: Thu, 24 Jan 2013 00:48:19 -0500 Subject: [PATCH 03/49] Solved the tank level issue. LemonTigerJ now gives right hyd/WQ results. --- .gitignore | 3 + LemonTigerJ.v11.suo | Bin 5632 -> 65536 bytes LemonTigerJ.vcxproj | 5 ++ src/enumstxt.h | 4 ++ src/epanet.c | 12 ++-- src/funcs.h | 6 ++ src/hash.h | 4 ++ src/hydraul.c | 1 - src/inpfile.c | 1 - src/input1.c | 1 - src/input2.c | 1 - src/input3.c | 1 - src/lemontiger.c | 156 +++++++++++++++++++++++++++++++++++++++----- src/mempool.h | 7 ++ src/output.c | 1 - src/quality.c | 27 ++++---- src/report.c | 1 - src/rules.c | 1 - src/smatrix.c | 1 - src/testLT.c | 79 +++++++++++++++------- src/text.h | 5 ++ src/toolkit.h | 11 ++++ src/types.h | 3 + src/vars.h | 65 ++++++++++-------- test/Net3.rpt | 102 ----------------------------- 25 files changed, 295 insertions(+), 203 deletions(-) delete mode 100644 test/Net3.rpt diff --git a/.gitignore b/.gitignore index 163692f..99c1559 100644 --- a/.gitignore +++ b/.gitignore @@ -61,4 +61,7 @@ Debug/ *.metagen *.bi *.opensdf +test/ + + diff --git a/LemonTigerJ.v11.suo b/LemonTigerJ.v11.suo index b5f0829270d526e8943e58d72aaeeb971bed6014..4f787f31457c1af90b9f6147dfdb318166b27f91 100644 GIT binary patch literal 65536 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 Bhr0j( delta 459 zcmZo@U}?~qV8hD7z`($`(NUX;uV8i5r9D5+GI9b%9GE9pF;y|~Fiif&2Qk!@&uX-~#ghZC2#E&NzuFmv`#=+c2{jSiolS<21{A zvNONoZ(;2h&Wsp2-u$sI;Utuz@v-%|c z0|LB0sp%yQ*2=XlJKBBMN4=lS=xi{_D_bD*?$1L#`?kECGG*>d&k1Kjpn6m%AMnZ) z__iecwA{mMe@%{A%rfJZ9YouH^r9 + + @@ -28,12 +30,14 @@ + + {4B66D9F0-407B-4995-B625-1CA1B72662C6} @@ -73,6 +77,7 @@ Level3 ProgramDatabase Disabled + .\include MachineX86 diff --git a/src/enumstxt.h b/src/enumstxt.h index 6a8404e..a546b7e 100755 --- a/src/enumstxt.h +++ b/src/enumstxt.h @@ -11,6 +11,9 @@ AUTHOR: L. Rossman ********************************************************************** */ +#ifndef ENUMSTXT_H +#define ENUMSTXT_H + char *NodeTxt[] = {t_JUNCTION, t_RESERVOIR, t_TANK}; @@ -133,3 +136,4 @@ char *Fldname[] = {t_ELEV, t_DEMAND, t_HEAD, char *LogoTxt[] = {LOGO1,LOGO2,LOGO3,LOGO4,LOGO5,LOGO6,NULL}; +#endif \ No newline at end of file diff --git a/src/epanet.c b/src/epanet.c index 25cd708..e3da576 100755 --- a/src/epanet.c +++ b/src/epanet.c @@ -107,11 +107,6 @@ execute function x and set the error code equal to its return value. ******************************************************************************* */ -/*** New compile directives ***/ //(2.00.11 - LR) -#define CLE /* Compile as a command line executable */ -//#define SOL /* Compile as a shared object library */ -//#define DLL /* Compile as a Windows DLL */ - /*** Need to define WINDOWS to use the getTmpName function ***/ //(2.00.12 - LR) // --- define WINDOWS #undef WINDOWS @@ -131,12 +126,11 @@ execute function x and set the error code equal to its return value. #endif #include #include //(2.00.12 - LR) -#include "hash.h" + #include "text.h" #include "types.h" #include "enumstxt.h" #include "funcs.h" -#define EXTERN #include "vars.h" #include "toolkit.h" @@ -3140,6 +3134,8 @@ char *geterrmsg(int errcode) case 307: strcpy(Msg,ERR307); break; case 308: strcpy(Msg,ERR308); break; case 309: strcpy(Msg,ERR309); break; + + case 401: strcpy(Msg,ERR401); break; default: strcpy(Msg,""); } return(Msg); @@ -3219,7 +3215,7 @@ int DLLEXPORT ENgetbasedemand(int nodeIndex, int demandIdx, float *baseDemand) if (nodeIndex <= 0 || nodeIndex > Nnodes) return(203); for(d=Node[nodeIndex].D; nnext) n++; if(n!=demandIdx) return(253); - *baseDemand=d->Base*Ucf[FLOW]; + *baseDemand=(float)(d->Base*Ucf[FLOW]); return 0; } int DLLEXPORT ENgetdemandpattern(int nodeIndex, int demandIdx, int *pattIdx) diff --git a/src/funcs.h b/src/funcs.h index 1fa5677..d31eca1 100755 --- a/src/funcs.h +++ b/src/funcs.h @@ -25,6 +25,10 @@ AUTHOR: L. Rossman ** NOTE: The exportable functions that can be called ** via the DLL are prototyped in TOOLKIT.H. */ + +#ifndef FUNCS_H +#define FUNCS_H + void initpointers(void); /* Initializes pointers */ int allocdata(void); /* Allocates memory */ void freeTmplist(STmplist *); /* Frees items in linked list */ @@ -279,3 +283,5 @@ int saveepilog(void); /* Saves output file epilog */ /* ------------ INPFILE.C --------------*/ int saveinpfile(char *); /* Saves network to text file */ + +#endif \ No newline at end of file diff --git a/src/hash.h b/src/hash.h index 8195afd..38999d1 100755 --- a/src/hash.h +++ b/src/hash.h @@ -4,6 +4,9 @@ ** */ +#ifndef HASH_H +#define HASH_H + #define HTMAXSIZE 1999 #define NOTFOUND 0 @@ -22,3 +25,4 @@ int HTfind(HTtable *, char *); char *HTfindKey(HTtable *, char *); void HTfree(HTtable *); +#endif \ No newline at end of file diff --git a/src/hydraul.c b/src/hydraul.c index fd3cfb9..bf9cea5 100755 --- a/src/hydraul.c +++ b/src/hydraul.c @@ -58,7 +58,6 @@ AUTHOR: L. Rossman #include "text.h" #include "types.h" #include "funcs.h" -#define EXTERN extern #include "vars.h" #define QZERO 1.e-6 /* Equivalent to zero flow */ diff --git a/src/inpfile.c b/src/inpfile.c index e21fa98..36abd63 100755 --- a/src/inpfile.c +++ b/src/inpfile.c @@ -31,7 +31,6 @@ data describing a piping network to a file in EPANET's text format. #include "text.h" #include "types.h" #include "funcs.h" -#define EXTERN extern #include "vars.h" /* Defined in enumstxt.h in EPANET.C */ diff --git a/src/input1.c b/src/input1.c index 15e1ae8..0e9627c 100755 --- a/src/input1.c +++ b/src/input1.c @@ -32,7 +32,6 @@ AUTHOR: L. Rossman #include "text.h" #include "types.h" #include "funcs.h" -#define EXTERN extern #include "vars.h" /* diff --git a/src/input2.c b/src/input2.c index a0fa344..6a1c3d4 100755 --- a/src/input2.c +++ b/src/input2.c @@ -36,7 +36,6 @@ The following utility functions are all called from INPUT3.C #include "text.h" #include "types.h" #include "funcs.h" -#define EXTERN extern #include "vars.h" #define MAXERRS 10 /* Max. input errors reported */ diff --git a/src/input3.c b/src/input3.c index 0d72c37..8954d78 100755 --- a/src/input3.c +++ b/src/input3.c @@ -31,7 +31,6 @@ All functions in this module are called from newline() in INPUT2.C. #include "text.h" #include "types.h" #include "funcs.h" -#define EXTERN extern #include "vars.h" /* Defined in enumstxt.h in EPANET.C */ diff --git a/src/lemontiger.c b/src/lemontiger.c index 5634d22..eff0c04 100644 --- a/src/lemontiger.c +++ b/src/lemontiger.c @@ -5,11 +5,19 @@ #include "lemontiger.h" extern char OutOfMemory; +extern int Haltflag; int ENopeninitHQ() { int errcode = 0; - Statflag = FALSE; //disable status report + + if (Hstep % Qstep) { + errcode = 401; + errmsg(errcode); + return errcode; + } + + Statflag = TRUE; //disable status report if (errcode = ENopenH()) return errcode; @@ -28,6 +36,100 @@ int ENopeninitHQ() { return errcode; } +long timestepLT(void) +/* +**---------------------------------------------------------------- +** Input: none +** Output: returns time step until next change in hydraulics +** Purpose: computes time step to advance hydraulic simulation, but don't update tank levels +** Let nextqual() to do the job. +**---------------------------------------------------------------- +*/ +{ + long n,t,tstep; + + /* Normal time step is hydraulic time step */ + tstep = Hstep; + + /* Revise time step based on time until next demand period */ + n = ((Htime+Pstart)/Pstep) + 1; /* Next pattern period */ + t = n*Pstep - Htime; /* Time till next period */ + if (t > 0 && t < tstep) tstep = t; + + /* Revise time step based on time until next reporting period */ + t = Rtime - Htime; + if (t > 0 && t < tstep) tstep = t; + + /* Revise time step based on smallest time to fill or drain a tank */ + tanktimestep(&tstep); + + /* Revise time step based on smallest time to activate a control */ + controltimestep(&tstep); + + /* Evaluate rule-based controls (which will also update tank levels) */ + if (Nrules > 0) ruletimestep(&tstep); + + return(tstep); +} + +int nexthydLT(long *tstep) +/* +**-------------------------------------------------------------- +** Input: none +** Output: tstep = pointer to time step (in seconds) +** Returns: error code +** Purpose: finds length of next time step & updates tank +** levels and rule-based contol actions. don't save +** results to hydraulics file. don't consider Report time. +**-------------------------------------------------------------- +*/ +{ + long hydstep; /* Actual time step */ + int errcode = 0; /* Error code */ + + if (Haltflag) Htime = Dur; + + /* Compute next time step & update tank levels */ + *tstep = 0; + hydstep = 0; + if (Htime < Dur) hydstep = timestepLT(); + + /* Compute pumping energy */ + if (Dur == 0) addenergy(0); + else if (Htime < Dur) addenergy(hydstep); + + /* Update current time. */ + if (Htime < Dur) /* More time remains */ + { + Htime += hydstep; + } + else + { + Htime++; /* Force completion of analysis */ + } + *tstep = hydstep; + return(errcode); +} + + +void updateTanklevels() { + int i,n; + + for (i=1; i<=Ntanks; i++) + { + + /* Skip reservoirs */ + if (Tank[i].A == 0.0) continue; + + n = Tank[i].Node; + /* Check if tank full/empty within next second */ + if (Tank[i].V + D[n] >= Tank[i].Vmax) Tank[i].V = Tank[i].Vmax; + if (Tank[i].V - D[n] <= Tank[i].Vmin) Tank[i].V = Tank[i].Vmin; + + H[n] = tankgrade(i,Tank[i].V); + } +} + int ENrunstepHQ(long* pstime /* Simulation time pointer */ , long* ptleft /* Time left in the simulation*/) { long hydtime; /* Hydraulic solution time */ @@ -35,14 +137,11 @@ int ENrunstepHQ(long* pstime /* Simulation time pointer */ int errcode = 0; long dt, hstep, tstep; - /* Update reported simulation time */ - *pstime = Qtime; - - /* if needed, push forward hydraulic simulation */ + /* if needed, push forward hydraulic simulation, similar to runqual() */ if (Qtime == Htime) { if ( (errcode = runhyd(&hydtime)) || - (errcode = nexthyd(&hydstep)) + (errcode = nexthydLT(&hydstep)) ) return errcode; /* If simulating WQ: */ if (Qualflag != NONE && Qtime < Dur) { @@ -58,22 +157,21 @@ int ENrunstepHQ(long* pstime /* Simulation time pointer */ Htime = hydtime + hydstep; } - /* run WQ simulation similar to stepqual() */ + /* run WQ simulation, similar to stepqual() */ tstep = Qstep; - do - { + do { dt = tstep; hstep = Htime - Qtime; - if (hstep < dt) - { + if (hstep < dt) {/* Htime is closer */ dt = hstep; if (Qualflag != NONE) transport(dt); Qtime += dt; + updateTanklevels(); /* if needed, push forward hydraulic simulation */ if ( (errcode = runhyd(&hydtime)) || - (errcode = nexthyd(&hydstep)) + (errcode = nexthydLT(&hydstep)) ) return errcode; if (Qualflag != NONE && Qtime < Dur) { @@ -85,22 +183,44 @@ int ENrunstepHQ(long* pstime /* Simulation time pointer */ if (Qtime == 0) initsegs(); else reorientsegs(); } - Htime = hydtime + hydstep; - Qtime = hydtime; - } - else - { + + } else { /* Qtime is closer */ if (Qualflag != NONE) transport(dt); Qtime += dt; } tstep -= dt; if (OutOfMemory) errcode = 101; - } while (!errcode && tstep > 0); + } while (!errcode && tstep > 0); /*do it until Qstep is elapsed.*/ *ptleft = Dur - Qtime; if (!errcode && Saveflag && *ptleft == 0) errcode = savefinaloutput(); + + /* if needed, push forward hydraulic simulation again, so that hyd and wq states are consistent. */ + if (Qtime == Htime && Htime < Dur) { + updateTanklevels(); + if ( (errcode = runhyd(&hydtime)) || + (errcode = nexthydLT(&hydstep)) + ) return errcode; + // If simulating WQ: + if (Qualflag != NONE && Qtime < Dur) { + + // Compute reaction rate coeffs. + if (Reactflag && Qualflag != AGE) ratecoeffs(); + + // Initialize pipe segments (at time 0) or + // else re-orient segments if flow reverses. + if (Qtime == 0) initsegs(); + else reorientsegs(); + } + Htime = hydtime + hydstep; + } + + + /* Update reported simulation time */ + *pstime = Qtime; + return(errcode); } diff --git a/src/mempool.h b/src/mempool.h index 2e43dde..ede9d44 100755 --- a/src/mempool.h +++ b/src/mempool.h @@ -6,6 +6,10 @@ ** The type alloc_handle_t provides an opaque reference to the ** alloc pool - only the alloc routines know its structure. */ + +#ifndef MEMPOOL_H +#define MEMPOOL_H + #ifndef DLLEXPORT #ifdef DLL #ifdef __cplusplus @@ -24,6 +28,7 @@ #endif #endif + typedef struct { long dummy; @@ -34,3 +39,5 @@ DLLEXPORT char *Alloc(long); DLLEXPORT alloc_handle_t *AllocSetPool(alloc_handle_t *); DLLEXPORT void AllocReset(void); DLLEXPORT void AllocFreePool(void); + +#endif \ No newline at end of file diff --git a/src/output.c b/src/output.c index e25a5d3..ea56057 100755 --- a/src/output.c +++ b/src/output.c @@ -23,7 +23,6 @@ AUTHOR: L. Rossman #include "text.h" #include "types.h" #include "funcs.h" -#define EXTERN extern #include "hash.h" #include "vars.h" diff --git a/src/quality.c b/src/quality.c index 8cc1ffe..b6e2134 100755 --- a/src/quality.c +++ b/src/quality.c @@ -59,7 +59,6 @@ AUTHOR: L. Rossman #include "text.h" #include "types.h" #include "funcs.h" -#define EXTERN extern #include "vars.h" #include "mempool.h" @@ -106,9 +105,9 @@ int openqual() if (SegPool == NULL) errcode = 101; //(2.00.11 - LR) /* Allocate scratch array & reaction rate array*/ - X = (double *) calloc(MAX((Nnodes+1),(Nlinks+1)),sizeof(double)); + XC = (double *) calloc(MAX((Nnodes+1),(Nlinks+1)),sizeof(double)); R = (double *) calloc((Nlinks+1), sizeof(double)); - ERRCODE(MEMCHECK(X)); + ERRCODE(MEMCHECK(XC)); ERRCODE(MEMCHECK(R)); /* Allocate memory for WQ solver */ @@ -321,7 +320,7 @@ int closequal() free(VolIn); free(MassIn); free(R); - free(X); + free(XC); return(errcode); } @@ -666,7 +665,7 @@ void accumulate(long dt) /* Re-set memory used to accumulate mass & volume */ memset(VolIn,0,(Nnodes+1)*sizeof(double)); memset(MassIn,0,(Nnodes+1)*sizeof(double)); - memset(X,0,(Nnodes+1)*sizeof(double)); + memset(XC,0,(Nnodes+1)*sizeof(double)); /* Compute average conc. of segments adjacent to each node */ /* (For use if there is no transport through the node) */ @@ -686,7 +685,7 @@ void accumulate(long dt) } } for (k=1; k<=Nnodes; k++) - if (VolIn[k] > 0.0) X[k] = MassIn[k]/VolIn[k]; + if (VolIn[k] > 0.0) XC[k] = MassIn[k]/VolIn[k]; /* Move mass from first segment of each pipe into downstream node */ memset(VolIn,0,(Nnodes+1)*sizeof(double)); @@ -767,7 +766,7 @@ void updatenodes(long dt) ** Purpose: updates concentration at all nodes to mixture of accumulated ** inflow from connecting pipes. ** -** Note: Does not account for source flow effects. X[i] contains +** Note: Does not account for source flow effects. XC[i] contains ** average concen. of segments adjacent to node i, used in case ** there was no inflow into i. **--------------------------------------------------------------------------- @@ -780,7 +779,7 @@ void updatenodes(long dt) { if (D[i] < 0.0) VolIn[i] -= D[i]*dt; if (VolIn[i] > 0.0) C[i] = MassIn[i]/VolIn[i]; - else C[i] = X[i]; + else C[i] = XC[i]; } /* Update tank quality */ @@ -809,8 +808,8 @@ void sourceinput(long dt) /* Establish a flow cutoff which indicates no outflow from a node */ qcutoff = 10.0*TINY; - /* Zero-out the work array X */ - memset(X,0,(Nnodes+1)*sizeof(double)); + /* Zero-out the work array XC */ + memset(XC,0,(Nnodes+1)*sizeof(double)); if (Qualflag != CHEM) return; /* Consider each node */ @@ -872,7 +871,7 @@ void sourceinput(long dt) } /* Source concen. contribution = (mass added / outflow volume) */ - X[n] = massadded/volout; + XC[n] = massadded/volout; /* Update total mass added for time period & simulation */ source->Smass += massadded; @@ -923,7 +922,7 @@ void release(long dt) v = q*dt; /* Include source contribution in quality released from node. */ - c = C[n] + X[n]; + c = C[n] + XC[n]; /* If link has a last seg, check if its quality */ /* differs from that of the flow released from node.*/ @@ -952,7 +951,7 @@ void updatesourcenodes(long dt) ** Input: dt = current WQ time step ** Output: none ** Purpose: updates quality at source nodes. -** (X[n] = concen. added by source at node n) +** (XC[n] = concen. added by source at node n) **--------------------------------------------------- */ { @@ -968,7 +967,7 @@ void updatesourcenodes(long dt) if (source == NULL) continue; /* Add source to current node concen. */ - C[n] += X[n]; + C[n] += XC[n]; /* For tanks, node concen. = internal concen. */ if (n > Njuncs) diff --git a/src/report.c b/src/report.c index b021461..d74c1a7 100755 --- a/src/report.c +++ b/src/report.c @@ -38,7 +38,6 @@ formatted string S to the report file. #include "text.h" #include "types.h" #include "funcs.h" -#define EXTERN extern #include "vars.h" #define MAXCOUNT 10 /* Max. # of disconnected nodes listed */ diff --git a/src/rules.c b/src/rules.c index aa2e003..e6ac10a 100755 --- a/src/rules.c +++ b/src/rules.c @@ -33,7 +33,6 @@ AUTHOR: L. Rossman #include "text.h" #include "types.h" #include "funcs.h" -#define EXTERN extern #include "vars.h" struct Premise /* Rule Premise Clause */ diff --git a/src/smatrix.c b/src/smatrix.c index 7b0e7f3..f95dada 100755 --- a/src/smatrix.c +++ b/src/smatrix.c @@ -42,7 +42,6 @@ Linsolve() solves the linearized system of hydraulic equations. #include "text.h" #include "types.h" #include "funcs.h" -#define EXTERN extern #include "vars.h" int *Degree; /* Number of links adjacent to each node */ diff --git a/src/testLT.c b/src/testLT.c index 97b29b9..ba173b8 100644 --- a/src/testLT.c +++ b/src/testLT.c @@ -16,60 +16,91 @@ int main(int argc, char* argv[]) { long stime = 0; //simulation time point, = t = Htime long step = 1; //time to next time point, = tstep = hydstep long tleft = 0; //time left in the simulation - int id; // some node id + int id, id2, id3; // some node id float value; // some node/link value - int TIME_A = 3600*10; - int TIME_B = 3600*20; //two time points for testing + int TIME_A = 3600*3; + int TIME_B = 3600*6; //two time points for testing + int TIME_C = 3600*10; /* Asychronous solver (old epanet) */ - + printf("*****Original EPANET results******\n"); + if (err=ENopen(argv[1], argv[2], "")) return err; - ENgetnodeindex("184", &id); - + ENgetnodeindex("184", &id); // a node far away from water source + ENgetlinkindex("101", &id2); // a link close to the lake + ENgetnodeindex("199", &id3); // a node close to the lake (tracer point) + for (ENopenH(), ENinitH(1), step=1; // must save intermediate results to disk (initH(1)), otherwise WQ solver won't execute - step>0; ) { + step>0; ENnextH(&step)) { - ENrunH(&stime); ENnextH(&step); - printf("stime = %d sec, step = %d sec.\n", stime, step); + ENrunH(&stime); + + + if (stime == TIME_A || stime == TIME_B || stime == TIME_C) { // grab some results + printf("Hydraulic simulation time = %d sec, step = %d sec.\n", stime, step); - if (stime == TIME_A || stime == TIME_B) { // grab some results ENgetnodevalue(id, EN_HEAD, &value); - printf("Node 184's head = %f.\n", value); + printf("Node 184's head = \t%f.\n", value); + ENgetlinkvalue(id2, EN_FLOW, &value); + printf("Link 101's flowrate = \t%f. \n", value); + ENgetnodevalue(id3, EN_HEAD, &value); + printf("Node 199's head = \t%f.\n", value); } } ENcloseH(); - printf("Reset time pointer and run WQ.\n"); - for (ENopenQ(), ENinitQ(0), step=1; step>0; ) { - /* this operation resets the internal time pointer (back to 0)*/ - ENrunQ(&stime); ENnextQ(&step); - printf("stime = %d sec, step = %d sec.\n", stime, step); + printf("\nReset time pointer and run WQ.\n"); + for (step=1, ENopenQ(), ENinitQ(0); // this operation resets the internal time pointer (back to 0) + step>0; ENnextQ(&step)) { + ENrunQ(&stime); + // grab some results - if (stime == TIME_A || stime == TIME_B) { + if (stime == TIME_A || stime == TIME_B || stime == TIME_C) { + printf("WQ simulation time = %d sec, step = %d sec.\n", stime, step); + ENgetnodevalue(id, EN_QUALITY, &value); - printf("Node 184's quality = %f.\n", value); + printf("Node 184's quality = \t%f.\n", value); + ENgetnodevalue(id3, EN_QUALITY, &value); + printf("Node 199's quality = \t%f.\n", value); } } ENcloseQ(); ENclose(); - + /* Sychronous solver (LemonTiger) */ - + printf("\n\n*****LemonTiger results******\n\n"); + if (err=ENopen(argv[1], argv[2], "")) return err; for (ENopeninitHQ(), tleft=Dur; tleft>0; ) { ENrunstepHQ(&stime, &tleft); - printf("stime = %d sec, time left = %d sec.\n", stime, tleft); + + - if (stime == TIME_A || stime == TIME_B) { + if (stime == TIME_A || stime == TIME_B || stime == TIME_C) { + //if (! (stime%1800)){ + printf("Simulation = %d sec, time left = %d sec.\n", stime, tleft); ENgetnodevalue(id, EN_HEAD, &value); - printf("Node 184's head = %f.\n", value); + printf("Node 184's head = \t%f.\n", value); + ENgetnodevalue(id, EN_QUALITY, &value); - printf("Node 184's quality = %f.\n", value); + printf("Node 184's quality = \t%f.\n", value); + + ENgetnodevalue(id3, EN_HEAD, &value); + printf("Node 199's head = \t%f.\n", value); + + ENgetnodevalue(id3, EN_QUALITY, &value); + printf("Node 199's quality = \t%f.\n", value); + + ENgetlinkvalue(id2, EN_FLOW, &value); + printf("Link 101's flowrate = \t%f. \n", value); + + + printf("\n"); } } ENcloseHQ(); diff --git a/src/text.h b/src/text.h index 0a0e5c0..890e099 100755 --- a/src/text.h +++ b/src/text.h @@ -14,6 +14,8 @@ AUTHOR: L. Rossman **************************************************** */ /* ------------ Keyword Dictionary ---------- */ +#ifndef TEXT_H +#define TEXT_H #define w_USE "USE" #define w_SAVE "SAVE" @@ -501,6 +503,8 @@ AUTHOR: L. Rossman #define ERR308 "File Error 308: cannot save results to file." #define ERR309 "File Error 309: cannot save results to report file." +#define ERR401 "Sync Error 401: Qstep is not dividable by Hstep. Can't sync." + #define R_ERR201 "Input Error 201: syntax error in following line of " #define R_ERR202 "Input Error 202: illegal numeric value in following line of " #define R_ERR203 "Input Error 203: undefined node in following line of " @@ -528,3 +532,4 @@ AUTHOR: L. Rossman #define WARN5 "WARNING: Valves cannot deliver enough flow." #define WARN6 "WARNING: System has negative pressures." +#endif \ No newline at end of file diff --git a/src/toolkit.h b/src/toolkit.h index 016a31f..3e0501b 100755 --- a/src/toolkit.h +++ b/src/toolkit.h @@ -15,6 +15,15 @@ AUTHOR: L. Rossman ******************************************************************* */ +#ifndef TOOLKIT_H +#define TOOLKIT_H + +/*** New compile directives ***/ //(2.00.11 - LR) +//#define CLE /* Compile as a command line executable */ +#define CLE_LT /* LemonTiger test */ +//#define SOL /* Compile as a shared object library */ +//#define DLL /* Compile as a Windows DLL */ + #ifndef DLLEXPORT #ifdef DLL @@ -247,3 +256,5 @@ extern "C" { #if defined(__cplusplus) } #endif + +#endif \ No newline at end of file diff --git a/src/types.h b/src/types.h index 68a495e..81fe7f1 100755 --- a/src/types.h +++ b/src/types.h @@ -17,6 +17,8 @@ AUTHOR: L. Rossman ********************************************************************** */ +#ifndef TYPES_H +#define TYPES_H /*********************************************************/ /* All floats have been re-declared as doubles (7/3/07). */ @@ -451,3 +453,4 @@ enum HdrType /* Type of table heading */ NODEHDR, /* Node Results */ LINKHDR}; /* Link Results */ +#endif \ No newline at end of file diff --git a/src/vars.h b/src/vars.h index b8b821b..b6d9b49 100755 --- a/src/vars.h +++ b/src/vars.h @@ -11,15 +11,21 @@ AUTHOR: L. Rossman ************************************************************************ */ -EXTERN FILE *InFile, /* Input file pointer */ +#ifndef VARS_H +#define VARS_H + +#include +#include "hash.h" + + FILE *InFile, /* Input file pointer */ *OutFile, /* Output file pointer */ *RptFile, /* Report file pointer */ *HydFile, /* Hydraulics file pointer */ *TmpOutFile; /* Temporary file handle */ -EXTERN long HydOffset, /* Hydraulics file byte offset */ + long HydOffset, /* Hydraulics file byte offset */ OutOffset1, /* 1st output file byte offset */ OutOffset2; /* 2nd output file byte offset */ -EXTERN char Msg[MAXMSG+1], /* Text of output message */ + char Msg[MAXMSG+1], /* Text of output message */ InpFname[MAXFNAME+1], /* Input file name */ Rpt1Fname[MAXFNAME+1], /* Primary report file name */ Rpt2Fname[MAXFNAME+1], /* Secondary report file name */ @@ -59,7 +65,7 @@ EXTERN char Msg[MAXMSG+1], /* Text of output message */ OpenQflag, /* Quality system opened flag */ SaveQflag, /* Quality results saved flag */ Saveflag; /* General purpose save flag */ -EXTERN int MaxNodes, /* Node count from input file */ + int MaxNodes, /* Node count from input file */ MaxLinks, /* Link count from input file */ MaxJuncs, /* Junction count */ MaxPipes, /* Pipe count */ @@ -91,7 +97,7 @@ EXTERN int MaxNodes, /* Node count from input file */ PageSize, /* Lines/page in output report */ CheckFreq, /* Hydraulics solver parameter */ MaxCheck; /* Hydraulics solver parameter */ -EXTERN double Ucf[MAXVAR], /* Unit conversion factors */ + double Ucf[MAXVAR], /* Unit conversion factors */ Ctol, /* Water quality tolerance */ Htol, /* Hydraulic head tolerance */ Qtol, /* Flow rate tolerance */ @@ -120,7 +126,7 @@ EXTERN double Ucf[MAXVAR], /* Unit conversion factors */ Wwall, /* Avg. wall reaction rate */ Wtank, /* Avg. tank reaction rate */ Wsource; /* Avg. mass inflow */ -EXTERN long Tstart, /* Starting time of day (sec) */ + long Tstart, /* Starting time of day (sec) */ Hstep, /* Nominal hyd. time step (sec) */ Qstep, /* Quality time step (sec) */ Pstep, /* Time pattern time step (sec) */ @@ -133,32 +139,33 @@ EXTERN long Tstart, /* Starting time of day (sec) */ Hydstep, /* Actual hydraulic time step */ Rulestep, /* Rule evaluation time step */ Dur; /* Duration of simulation (sec) */ -EXTERN SField Field[MAXVAR]; /* Output reporting fields */ + SField Field[MAXVAR]; /* Output reporting fields */ /* Array pointers not allocated and freed in same routine */ -EXTERN char *S, /* Link status */ + char *S, /* Link status */ *OldStat; /* Previous link/tank status */ -EXTERN double *D, /* Node actual demand */ + double *D, /* Node actual demand */ *C, /* Node actual quality */ *E, /* Emitter flows */ *K, /* Link settings */ *Q, /* Link flows */ *R, /* Pipe reaction rate */ - *X; /* General purpose array */ -EXTERN double *H; /* Node heads */ -EXTERN STmplist *Patlist; /* Temporary time pattern list */ -EXTERN STmplist *Curvelist; /* Temporary list of curves */ -EXTERN Spattern *Pattern; /* Time patterns */ -EXTERN Scurve *Curve; /* Curve data */ -EXTERN Snode *Node; /* Node data */ -EXTERN Slink *Link; /* Link data */ -EXTERN Stank *Tank; /* Tank data */ -EXTERN Spump *Pump; /* Pump data */ -EXTERN Svalve *Valve; /* Valve data */ -EXTERN Scontrol *Control; /* Control data */ -EXTERN HTtable *Nht, *Lht; /* Hash tables for ID labels */ -EXTERN Padjlist *Adjlist; /* Node adjacency lists */ -EXTERN int _relativeError, _iterations; /* Info about hydraulic solution */ + *X, /* General purpose array */ + *XC; /* General Purpose array - WQ */ + double *H; /* Node heads */ + STmplist *Patlist; /* Temporary time pattern list */ + STmplist *Curvelist; /* Temporary list of curves */ + Spattern *Pattern; /* Time patterns */ + Scurve *Curve; /* Curve data */ + Snode *Node; /* Node data */ + Slink *Link; /* Link data */ + Stank *Tank; /* Tank data */ + Spump *Pump; /* Pump data */ + Svalve *Valve; /* Valve data */ + Scontrol *Control; /* Control data */ + HTtable *Nht, *Lht; /* Hash tables for ID labels */ + Padjlist *Adjlist; /* Node adjacency lists */ + int _relativeError, _iterations; /* Info about hydraulic solution */ /* ** NOTE: Hydraulic analysis of the pipe network at a given point in time @@ -180,18 +187,20 @@ EXTERN int _relativeError, _iterations; /* Info about hydraulic solution */ ** The following arrays are used to efficiently manage this sparsity: */ -EXTERN double *Aii, /* Diagonal coeffs. of A */ + double *Aii, /* Diagonal coeffs. of A */ *Aij, /* Non-zero, off-diagonal coeffs. of A */ *F; /* Right hand side coeffs. */ -EXTERN double *P, /* Inverse headloss derivatives */ + double *P, /* Inverse headloss derivatives */ *Y; /* Flow correction factors */ -EXTERN int *Order, /* Node-to-row of A */ + int *Order, /* Node-to-row of A */ *Row, /* Row-to-node of A */ *Ndx; /* Index of link's coeff. in Aij */ /* ** The following arrays store the positions of the non-zero coeffs. ** of the lower triangular portion of A whose values are stored in Aij: */ -EXTERN int *XLNZ, /* Start position of each column in NZSUB */ + int *XLNZ, /* Start position of each column in NZSUB */ *NZSUB, /* Row index of each coeff. in each column */ *LNZ; /* Position of each coeff. in Aij array */ + +#endif \ No newline at end of file diff --git a/test/Net3.rpt b/test/Net3.rpt deleted file mode 100644 index 91c383f..0000000 --- a/test/Net3.rpt +++ /dev/null @@ -1,102 +0,0 @@ - Page 1 Tue Jan 22 11:23:06 2013 - - ****************************************************************** - * E P A N E T * - * Hydraulic and Water Quality * - * Analysis for Pipe Networks * - * Version 2.00.12 * - ****************************************************************** - - Analysis begun Tue Jan 22 11:23:06 2013 - - - Hydraulic Status: - ----------------------------------------------------------------------- - 0:00:00: Balanced after 5 trials - 0:00:00: Reservoir River is emptying - 0:00:00: Reservoir Lake is closed - 0:00:00: Tank 1 is filling at 13.10 ft - 0:00:00: Tank 2 is emptying at 23.50 ft - 0:00:00: Tank 3 is filling at 29.00 ft - - 1:00:00: Pump 10 changed by timer control - 1:00:00: Balanced after 7 trials - 1:00:00: Reservoir Lake is emptying - 1:00:00: Pump 10 changed from closed to open - - 2:00:00: Balanced after 3 trials - 2:00:00: Tank 2 is filling at 20.90 ft - - 3:00:00: Balanced after 2 trials - - 4:00:00: Balanced after 3 trials - - 4:13:33: Pump 335 changed by Tank 1 control - 4:13:33: Pipe 330 changed by Tank 1 control - 4:13:33: Balanced after 4 trials - 4:13:33: Pipe 330 changed from closed to open - 4:13:33: Pump 335 changed from open to closed - - 5:00:00: Balanced after 3 trials - 5:00:00: Tank 3 is emptying at 34.30 ft - - 6:00:00: Balanced after 3 trials - 6:00:00: Tank 3 is filling at 34.12 ft - - 7:00:00: Balanced after 3 trials - - 8:00:00: Balanced after 2 trials - - 9:00:00: Balanced after 3 trials - 9:00:00: Tank 3 is emptying at 35.15 ft - - 10:00:00: Balanced after 2 trials - 10:00:00: Tank 1 is emptying at 22.20 ft - - 11:00:00: Balanced after 3 trials - 11:00:00: Tank 2 is emptying at 27.70 ft - - 12:00:00: Balanced after 2 trials - 12:00:00: Tank 2 is filling at 27.64 ft - - 13:00:00: Balanced after 3 trials - 13:00:00: Tank 1 is filling at 21.73 ft - - 14:00:00: Balanced after 3 trials - - 15:00:00: Pump 10 changed by timer control - 15:00:00: Balanced after 5 trials - 15:00:00: Reservoir Lake is closed - 15:00:00: Tank 1 is emptying at 21.98 ft - 15:00:00: Tank 2 is emptying at 28.20 ft - 15:00:00: Pump 10 changed from open to closed - - 16:00:00: Balanced after 3 trials - - 17:00:00: Balanced after 2 trials - - 18:00:00: Balanced after 3 trials - - 19:00:00: Balanced after 2 trials - - 20:00:00: Balanced after 3 trials - - 21:00:00: Balanced after 2 trials - - 21:19:39: Pump 335 changed by Tank 1 control - 21:19:39: Pipe 330 changed by Tank 1 control - 21:19:39: Balanced after 5 trials - 21:19:39: Tank 1 is filling at 17.10 ft - 21:19:39: Tank 3 is filling at 29.68 ft - 21:19:39: Pipe 330 changed from open to closed - 21:19:39: Pump 335 changed from closed to open - - 22:00:00: Balanced after 3 trials - 22:00:00: Tank 1 is emptying at 17.30 ft - - 23:00:00: Balanced after 3 trials - - 24:00:00: Balanced after 4 trials - 24:00:00: Tank 1 is filling at 15.79 ft - - Analysis ended Tue Jan 22 11:23:18 2013 From 4ae2f0e76c65b65de3be0f7a6ed56bea2c61b277 Mon Sep 17 00:00:00 2001 From: JinduanChen Date: Thu, 24 Jan 2013 00:53:12 -0500 Subject: [PATCH 04/49] Some housekeeping --- .gitignore | 2 +- build/Cyg/Makefile | 125 ------ build/Cyg/Makefile_Rev | 130 ------ build/Cyg/runepanet.sh.template | 4 - build/Linux/Makefile | 108 ----- build/Linux/Makefile_Rev | 111 ----- build/Linux/runepanet.sh.template | 4 - build/MSVC/epanet-dll/epanet-dll.sln | 20 - build/MSVC/epanet-dll/epanet-dll.vcproj | 282 ------------ build/MSVC/epanet-exe/epanet-exe.sln | 20 - build/MSVC/epanet-exe/epanet-exe.vcproj | 284 ------------ build/MSVC/epanet2.mak | 213 --------- build/MingW/CreateMSLib.bat.template | 1 - build/MingW/Makefile | 161 ------- build/MingW/Makefile_Rev | 159 ------- build/MingW/runepanet.sh.template | 4 - .../epanet/epanet.xcodeproj/project.pbxproj | 424 ------------------ build/Xcode/epanet/macinclude/malloc.h | 10 - build/svnname.sh | 3 - doc/LICENSE.txt | 9 - doc/Readme.txt | 54 --- doc/changes.txt | 57 --- 22 files changed, 1 insertion(+), 2184 deletions(-) delete mode 100755 build/Cyg/Makefile delete mode 100755 build/Cyg/Makefile_Rev delete mode 100755 build/Cyg/runepanet.sh.template delete mode 100755 build/Linux/Makefile delete mode 100755 build/Linux/Makefile_Rev delete mode 100755 build/Linux/runepanet.sh.template delete mode 100755 build/MSVC/epanet-dll/epanet-dll.sln delete mode 100755 build/MSVC/epanet-dll/epanet-dll.vcproj delete mode 100755 build/MSVC/epanet-exe/epanet-exe.sln delete mode 100755 build/MSVC/epanet-exe/epanet-exe.vcproj delete mode 100755 build/MSVC/epanet2.mak delete mode 100755 build/MingW/CreateMSLib.bat.template delete mode 100755 build/MingW/Makefile delete mode 100755 build/MingW/Makefile_Rev delete mode 100755 build/MingW/runepanet.sh.template delete mode 100644 build/Xcode/epanet/epanet.xcodeproj/project.pbxproj delete mode 100644 build/Xcode/epanet/macinclude/malloc.h delete mode 100755 build/svnname.sh delete mode 100644 doc/LICENSE.txt delete mode 100755 doc/Readme.txt delete mode 100755 doc/changes.txt diff --git a/.gitignore b/.gitignore index 99c1559..98018e6 100644 --- a/.gitignore +++ b/.gitignore @@ -61,7 +61,7 @@ Debug/ *.metagen *.bi *.opensdf -test/ +test/* diff --git a/build/Cyg/Makefile b/build/Cyg/Makefile deleted file mode 100755 index b900e36..0000000 --- a/build/Cyg/Makefile +++ /dev/null @@ -1,125 +0,0 @@ -# Cygwin Makefile for EPANET - -# This will build EPANET as a cygwin DLL and import -# library (cygepanet.dll/libcygepanet.dll.a) under Cygwin/gcc, -# and a standalone executable (cygepanet.exe). -# The current release of the Cygwin environment can be -# obtained from http://www.cygwin.com - -# The following targets are defined (for execution in -# the build directory under the Cygwin environment): -# make -# -Builds cygepanet2.dll, cygepanet2.def, libcygepanet2.dll.a, -# cygepanet2.exe -# make install -# -Creates shell wrapper runcygepanet2.sh that -# executes cygepanet2.exe. -# The runcygepanet2.sh wrapper simply exports -# environment variables so that the DLL is found at runtime, -# allowing you to specify your own locations for installing -# the DLL. -# -Installs cygepanet2.dll, cygepanet2.exe, and runcygepanet2.sh -# in /bin, where defaults to ~ (and can be set -# below to something different - see "Install directories") -# -Installs libcygepanet2.dll.a (import library), and cygepanet2.def, -# in /lib -# -Installs epanet2.h in /include. This is the required -# header file for the EPANET programmer's toolkit, and thus -# /include should be on your CPP include search path -# for subsequent use of the toolkit and linking with the import -# library libcygepanet2.dll.a. -# make clean -# -Removes object and library files, returning the build directory -# to its pristine state. - -SHELL = /bin/sh - -# C H A N G E H E R E A S N E E D E D -# You may wish to change the install path 'prefix', -# or the compiler flags, but these defaults should be fine. - -# Target filenames -epanetrootname := cygepanet2 -dllname := $(epanetrootname).dll -defname := $(epanetrootname).def -implibname = lib$(dllname).a -exename := $(epanetrootname) -# Shell wrapper -runcmdtemplate = runepanet.sh.template -runcmdname = runcygepanet2.sh -# Location of EPANET toolkit includes -epanetincludedir = ../../include -# Search path for sources -epanetsrcdir = ../../src -VPATH = $(epanetsrcdir):$(epanetincludedir) - -# Install directories -prefix = ~ -exec_prefix = $(prefix) -srcdir = . -libdir = $(exec_prefix)/lib -bindir = $(exec_prefix)/bin -includedir = $(prefix)/include -datarootdir = $(prefix)/share -docdir = $(datarootdir)/doc/epanet - -# Compiler and flags -CC = /bin/gcc -dlltool = /bin/dlltool -CFLAGS = -g -O3 -CPPFLAGS = -I $(srcdir) -I $(epanetincludedir) -LDFLAGS = -L . -W1,-rpath,$(libdir) -lm - -# Installer -INSTALL = install -INSTALL_PROGRAM = $(INSTALL) -INSTALL_DATA = $(INSTALL) -m 644 - -# EPANET object files -epanet_objs=hash.o hydraul.o inpfile.o input1.o input2.o \ - input3.o mempool.o output.o quality.o report.o \ - rules.o smatrix.o -# Epanet header files -epanet_heads=enumstxt.h funcs.h hash.h mempool.h text.h toolkit.h types.h vars.h -epanet_main_heads=epanet2.h -# Epanet main program -epanet_main=epanet - -.PHONY: all -all: $(dllname) $(exename) - -$(dllname): $(epanet_objs) -# $(dlltool) -z $(defname) --dllname $(dllname) --output-lib $(implibname) $^ -# $(CC) $(CFLAGS) $(LDFLAGS) -shared -o $@ $(defname) $^ - $(CC) $(CFLAGS) $(CPPFLAGS) -D SOL -c $(epanetsrcdir)/$(epanet_main).c - $(CC) $(CFLAGS) $(LDFLAGS) -shared -o $@ $(epanet_main).o $^ -Wl,--output-def,$(defname) - $(CC) $(CFLAGS) $(LDFLAGS) -shared -o $@ $(epanet_main).o $^ -Wl,--kill-at - $(dlltool) -d $(defname) --dllname $@ --output-lib $(implibname) --kill-at - -$(exename): $(epanet_objs) - $(CC) $(CFLAGS) $(CPPFLAGS) -D CLE -c $(epanetsrcdir)/$(epanet_main).c - $(CC) $(CFLAGS) -o $@ $(epanet_main).o $^ $(LDFLAGS) - -$(epanet_objs): $(epanet_heads) - -.PHONY: install -install: - cat $(runcmdtemplate) | sed 's|libdir|$(bindir)|' \ - | sed 's|exename|$(bindir)/$(exename)|' \ - > $(runcmdname) - $(INSTALL_PROGRAM) -D $(exename) $(bindir)/$(exename) - $(INSTALL_PROGRAM) -D $(dllname) $(bindir)/$(dllname) - $(INSTALL_PROGRAM) -D $(defname) $(libdir)/$(defname) - $(INSTALL_PROGRAM) -D $(implibname) $(libdir)/$(implibname) - $(INSTALL_DATA) -D $(epanetincludedir)/epanet2.h $(includedir)/epanet2.h - $(INSTALL_PROGRAM) -D $(runcmdname) $(bindir)/$(runcmdname) - -.PHONY: uninstall -uninstall: - -.PHONY: check -check: - -.PHONY: clean -clean: - -/bin/rm *.o $(dllname) $(defname) $(implibname) $(exename).exe $(runcmdname) diff --git a/build/Cyg/Makefile_Rev b/build/Cyg/Makefile_Rev deleted file mode 100755 index c09750c..0000000 --- a/build/Cyg/Makefile_Rev +++ /dev/null @@ -1,130 +0,0 @@ -# Cygwin Makefile for EPANET - -# This will build EPANET as a cygwin DLL and import -# library (cygepanet_gcc_.dll/libcygepanet_gcc_.dll.a) under Cygwin/gcc, -# and a standalone executable (cygepanet_gcc_.exe). -# is the atomic revision number of the EPANET SVN repo, -# so the results of each build can be unambiguously tracked to a repo Rev. -# The current release of the Cygwin environment can be -# obtained from http://www.cygwin.com - -# The following targets are defined (for execution in -# the build directory under the Cygwin environment): -# make -# -Builds cygepanet_gcc_.dll, cygepanet_gcc_.def, libcygepanet_gcc_.dll.a, -# cygepanet_gcc_.exe -# make install -# -Creates shell wrapper runcygepanet_.sh that -# executes cygepanet_gcc_.exe. -# The runcygepanet_.sh wrapper simply exports -# environment variables so that the DLL is found at runtime, -# allowing you to specify your own locations for installing -# the DLL. -# -Installs cygepanet_gcc_.dll, cygepanet_gcc_.exe, and runcygepanet_.sh -# in /bin, where defaults to ~ (and can be set -# below to something different - see "Install directories") -# -Installs libcygepanet_gcc_.dll.a (import library), and cygepanet_gcc_.def, -# in /lib -# -Installs epanet2.h in /include. This is the required -# header file for the EPANET programmer's toolkit, and thus -# /include should be on your CPP include search path -# for subsequent use of the toolkit and linking with the import -# library libcygepanet_gcc_.dll.a. -# make clean -# -Removes object and library files, returning the build directory -# to its pristine state. - -SHELL = /bin/sh - -# C H A N G E H E R E A S N E E D E D -# You may wish to change the install path 'prefix', -# or the compiler flags, but these defaults should be fine. - -# Target filenames -# svnname.sh constructs a name: -# where is the atomic revision number of the svn repo. -epanetsvnpath = ../../.. -epanetrootname := $(shell ../svnname.sh $(epanetsvnpath) "" cygepanet_gcc_ "") -dllname := $(epanetrootname).dll -defname := $(epanetrootname).def -implibname = lib$(dllname).a -exename := $(epanetrootname) -# Shell wrapper -runcmdtemplate = runepanet.sh.template -runcmdname = $(shell ../svnname.sh $(epanetsvnpath) "" runcygepanet_ .sh) -# Location of EPANET toolkit includes -epanetincludedir = ../../include -# Search path for sources -epanetsrcdir = ../../src -VPATH = $(epanetsrcdir):$(epanetincludedir) - -# Install directories -prefix = ~ -exec_prefix = $(prefix) -srcdir = . -libdir = $(exec_prefix)/lib -bindir = $(exec_prefix)/bin -includedir = $(prefix)/include -datarootdir = $(prefix)/share -docdir = $(datarootdir)/doc/epanet - -# Compiler and flags -CC = /bin/gcc -dlltool = /bin/dlltool -CFLAGS = -g -O3 -CPPFLAGS = -I $(srcdir) -I $(epanetincludedir) -LDFLAGS = -L . -W1,-rpath,$(libdir) -lm - -# Installer -INSTALL = install -INSTALL_PROGRAM = $(INSTALL) -INSTALL_DATA = $(INSTALL) -m 644 - -# EPANET object files -epanet_objs=hash.o hydraul.o inpfile.o input1.o input2.o \ - input3.o mempool.o output.o quality.o report.o \ - rules.o smatrix.o -# Epanet header files -epanet_heads=enumstxt.h funcs.h hash.h mempool.h text.h toolkit.h types.h vars.h -epanet_main_heads=epanet2.h -# Epanet main program -epanet_main=epanet - -.PHONY: all -all: $(dllname) $(exename) - -$(dllname): $(epanet_objs) -# $(dlltool) -z $(defname) --dllname $(dllname) --output-lib $(implibname) $^ -# $(CC) $(CFLAGS) $(LDFLAGS) -shared -o $@ $(defname) $^ - $(CC) $(CFLAGS) $(CPPFLAGS) -D SOL -c $(epanetsrcdir)/$(epanet_main).c - $(CC) $(CFLAGS) $(LDFLAGS) -shared -o $@ $(epanet_main).o $^ -Wl,--output-def,$(defname) - $(CC) $(CFLAGS) $(LDFLAGS) -shared -o $@ $(epanet_main).o $^ -Wl,--kill-at - $(dlltool) -d $(defname) --dllname $@ --output-lib $(implibname) --kill-at - -$(exename): $(epanet_objs) - $(CC) $(CFLAGS) $(CPPFLAGS) -D CLE -c $(epanetsrcdir)/$(epanet_main).c - $(CC) $(CFLAGS) -o $@ $(epanet_main).o $^ $(LDFLAGS) - -$(epanet_objs): $(epanet_heads) - -.PHONY: install -install: - cat $(runcmdtemplate) | sed 's|libdir|$(bindir)|' \ - | sed 's|exename|$(bindir)/$(exename)|' \ - > $(runcmdname) - $(INSTALL_PROGRAM) -D $(exename) $(bindir)/$(exename) - $(INSTALL_PROGRAM) -D $(dllname) $(bindir)/$(dllname) - $(INSTALL_PROGRAM) -D $(defname) $(libdir)/$(defname) - $(INSTALL_PROGRAM) -D $(implibname) $(libdir)/$(implibname) - $(INSTALL_DATA) -D $(epanetincludedir)/epanet2.h $(includedir)/epanet2.h - $(INSTALL_PROGRAM) -D $(runcmdname) $(bindir)/$(runcmdname) - -.PHONY: uninstall -uninstall: - -.PHONY: check -check: - -.PHONY: clean -clean: - -/bin/rm *.o $(dllname) $(defname) $(implibname) $(exename).exe $(runcmdname) diff --git a/build/Cyg/runepanet.sh.template b/build/Cyg/runepanet.sh.template deleted file mode 100755 index 55ae0d3..0000000 --- a/build/Cyg/runepanet.sh.template +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh -export PATH=libdir:$PATH -export LD_LIBRARY_PATH=libdir:$LD_LIBRARY_PATH -exec exename "$@" diff --git a/build/Linux/Makefile b/build/Linux/Makefile deleted file mode 100755 index 2a0a396..0000000 --- a/build/Linux/Makefile +++ /dev/null @@ -1,108 +0,0 @@ -# Linux Makefile for EPANET - -# This will build EPANET as a shared object library -# (libepanet2.so) under Linux/Unix, and a standalone -# executable (epanet2). - -# The following targets are defined: -# make -# -Builds libepanet2.so, epanet2 -# make install -# -Creates shell wrapper runepanet2.sh that executes epanet2. -# The runepanet2.sh wrapper simply exports -# environment variables that help locate the runtime library, -# allowing you to specify your own library locations. -# -Installs epanet2 and runepanet2.sh -# in /bin, where defaults to ~ (and can be set -# below to something different - see "Install directories") -# -Installs libepanet2.so in /lib -# -Installs epanet2.h in /include. This is the required -# header file for the EPANET programmer's toolkit, and thus -# /include should be on your CPP include search path -# for subsequent use of the toolkit and linking with the -# library libepanet2.so -# make clean -# -Removes object and library files, returning the build directory -# to its pristine state. - -# You may wish to change the install path 'prefix', -# or the compiler flags, but these defaults should be fine. - -SHELL = /bin/sh - -# Target filenames -epanetrootname := epanet2 -libname := lib$(epanetrootname).so -exename := $(epanetrootname) -# Shell wrapper -runcmdtemplate = runepanet.sh.template -runcmdname = runepanet2.sh -# Location of EPANET toolkit includes -epanetincludedir = ../../include -# Search path for sources -epanetsrcdir = ../../src -VPATH = $(epanetsrcdir):$(epanetincludedir) - -# Install directories -prefix = ~ -exec_prefix = $(prefix) -libdir = $(exec_prefix)/lib -bindir = $(exec_prefix)/bin -includedir = $(prefix)/include -datarootdir = $(prefix)/share -docdir = $(datarootdir)/doc/epanet - -# Compiler and flags -CC = gcc -CFLAGS = -g -O3 -fPIC -CPPFLAGS = -I $(epanetincludedir) -LDFLAGS = -L . -W1,-rpath,$(libdir) -lm - -# Installer -INSTALL = install -INSTALL_PROGRAM = $(INSTALL) -INSTALL_DATA = $(INSTALL) -m 644 - -# Files for the shared object library -epanet_objs=hash.o hydraul.o inpfile.o input1.o input2.o \ - input3.o mempool.o output.o quality.o report.o \ - rules.o smatrix.o -# Epanet header files -epanet_heads=enumstxt.h funcs.h hash.h mempool.h text.h toolkit.h types.h vars.h -# Epanet main program -epanet_main=epanet -# Epanet main program header files -epanet_main_heads=epanet2.h - -.PHONY: all -all: $(libname) $(exename) - -$(libname): $(epanet_objs) - $(CC) $(CFLAGS) $(CPPFLAGS) -D SOL -c $(epanetsrcdir)/$(epanet_main).c - $(CC) $(CFLAGS) $(LDFLAGS) -shared -o $@ $(epanet_main).o $^ - -$(exename): $(libname) $(epanet_main_heads) - $(CC) $(CFLAGS) $(CPPFLAGS) -D CLE -c $(epanetsrcdir)/$(epanet_main).c - $(CC) $(CFLAGS) -o $@ $(epanet_main).o -l$(epanetrootname) $(LDFLAGS) - -$(epanet_objs): $(epanet_heads) - -.PHONY: install -install: - cat $(runcmdtemplate) | sed 's|libdir|$(libdir)|' \ - | sed 's|exename|$(bindir)/$(exename)|' \ - > $(runcmdname) - $(INSTALL_PROGRAM) -D $(exename) $(bindir)/$(exename) - $(INSTALL_PROGRAM) -D $(libname) $(libdir)/$(libname) - $(INSTALL_DATA) -D $(epanetincludedir)/epanet2.h $(includedir)/epanet2.h - $(INSTALL_PROGRAM) -D $(runcmdname) $(bindir)/$(runcmdname) - -.PHONY: uninstall -uninstall: - -.PHONY: check -check: - -.PHONY: clean -clean: - -/bin/rm *.o $(libname) $(exename) $(runcmdname) diff --git a/build/Linux/Makefile_Rev b/build/Linux/Makefile_Rev deleted file mode 100755 index f6e33bc..0000000 --- a/build/Linux/Makefile_Rev +++ /dev/null @@ -1,111 +0,0 @@ -# Linux Makefile for EPANET - -# This will build EPANET as a shared object library -# (libepanet_gcc_.so) under Linux/Unix, and a standalone -# executable (epanet_gcc_). - -# The following targets are defined: -# make -# -Builds libepanet_gcc_.so, epanet_gcc_ -# make install -# -Creates shell wrapper runepanet_.sh that executes epanet_gcc_.exe. -# The runepanet_.sh wrapper simply exports -# environment variables that help locate the runtime library, -# allowing you to specify your own library locations. -# -Installs epanet_gcc_ and runepanet_.sh -# in /bin, where defaults to ~ (and can be set -# below to something different - see "Install directories") -# -Installs libepanet_gcc_.so in /lib -# -Installs epanet2.h in /include. This is the required -# header file for the EPANET programmer's toolkit, and thus -# /include should be on your CPP include search path -# for subsequent use of the toolkit and linking with the -# library libepanet_gcc_.so -# make clean -# -Removes object and library files, returning the build directory -# to its pristine state. - -# You may wish to change the install path 'prefix', -# or the compiler flags, but these defaults should be fine. - -SHELL = /bin/sh - -# Target filenames -# svnname.sh constructs a name: -# where is the atomic revision number of the svn repo. -epanetsvnpath = ../../.. -epanetrootname := $(shell ../svnname.sh $(epanetsvnpath) "" epanet_gcc_ "") -libname := lib$(epanetrootname).so -exename := $(epanetrootname) -# Shell wrapper -runcmdtemplate = runepanet.sh.template -runcmdname = $(shell ../svnname.sh $(epanetsvnpath) "" runepanet_ .sh) -# Location of EPANET toolkit includes -epanetincludedir = ../../include -# Search path for sources -epanetsrcdir = ../../src -VPATH = $(epanetsrcdir):$(epanetincludedir) - -# Install directories -prefix = ~ -exec_prefix = $(prefix) -libdir = $(exec_prefix)/lib -bindir = $(exec_prefix)/bin -includedir = $(prefix)/include -datarootdir = $(prefix)/share -docdir = $(datarootdir)/doc/epanet - -# Compiler and flags -CC = gcc -CFLAGS = -g -O3 -fPIC -CPPFLAGS = -I $(epanetincludedir) -LDFLAGS = -L . -W1,-rpath,$(libdir) -lm - -# Installer -INSTALL = install -INSTALL_PROGRAM = $(INSTALL) -INSTALL_DATA = $(INSTALL) -m 644 - -# Files for the shared object library -epanet_objs=hash.o hydraul.o inpfile.o input1.o input2.o \ - input3.o mempool.o output.o quality.o report.o \ - rules.o smatrix.o -# Epanet header files -epanet_heads=enumstxt.h funcs.h hash.h mempool.h text.h toolkit.h types.h vars.h -# Epanet main program -epanet_main=epanet -# Epanet main program header files -epanet_main_heads=epanet2.h - -.PHONY: all -all: $(libname) $(exename) - -$(libname): $(epanet_objs) - $(CC) $(CFLAGS) $(CPPFLAGS) -D SOL -c $(epanetsrcdir)/$(epanet_main).c - $(CC) $(CFLAGS) $(LDFLAGS) -shared -o $@ $(epanet_main).o $^ - -$(exename): $(libname) $(epanet_main_heads) - $(CC) $(CFLAGS) $(CPPFLAGS) -D CLE -c $(epanetsrcdir)/$(epanet_main).c - $(CC) $(CFLAGS) -o $@ $(epanet_main).o -l$(epanetrootname) $(LDFLAGS) - -$(epanet_objs): $(epanet_heads) - -.PHONY: install -install: - cat $(runcmdtemplate) | sed 's|libdir|$(libdir)|' \ - | sed 's|exename|$(bindir)/$(exename)|' \ - > $(runcmdname) - $(INSTALL_PROGRAM) -D $(exename) $(bindir)/$(exename) - $(INSTALL_PROGRAM) -D $(libname) $(libdir)/$(libname) - $(INSTALL_DATA) -D $(epanetincludedir)/epanet2.h $(includedir)/epanet2.h - $(INSTALL_PROGRAM) -D $(runcmdname) $(bindir)/$(runcmdname) - -.PHONY: uninstall -uninstall: - -.PHONY: check -check: - -.PHONY: clean -clean: - -/bin/rm *.o $(libname) $(exename) $(runcmdname) diff --git a/build/Linux/runepanet.sh.template b/build/Linux/runepanet.sh.template deleted file mode 100755 index 55ae0d3..0000000 --- a/build/Linux/runepanet.sh.template +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh -export PATH=libdir:$PATH -export LD_LIBRARY_PATH=libdir:$LD_LIBRARY_PATH -exec exename "$@" diff --git a/build/MSVC/epanet-dll/epanet-dll.sln b/build/MSVC/epanet-dll/epanet-dll.sln deleted file mode 100755 index ef8b365..0000000 --- a/build/MSVC/epanet-dll/epanet-dll.sln +++ /dev/null @@ -1,20 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 10.00 -# Visual Studio 2008 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "epanet-dll", "epanet-dll.vcproj", "{3646F046-B542-4712-929F-E6A4F0C1F835}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Release|Win32 = Release|Win32 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {3646F046-B542-4712-929F-E6A4F0C1F835}.Debug|Win32.ActiveCfg = Debug|Win32 - {3646F046-B542-4712-929F-E6A4F0C1F835}.Debug|Win32.Build.0 = Debug|Win32 - {3646F046-B542-4712-929F-E6A4F0C1F835}.Release|Win32.ActiveCfg = Release|Win32 - {3646F046-B542-4712-929F-E6A4F0C1F835}.Release|Win32.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/build/MSVC/epanet-dll/epanet-dll.vcproj b/build/MSVC/epanet-dll/epanet-dll.vcproj deleted file mode 100755 index 12dbb3f..0000000 --- a/build/MSVC/epanet-dll/epanet-dll.vcproj +++ /dev/null @@ -1,282 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/build/MSVC/epanet-exe/epanet-exe.sln b/build/MSVC/epanet-exe/epanet-exe.sln deleted file mode 100755 index 76b8fbc..0000000 --- a/build/MSVC/epanet-exe/epanet-exe.sln +++ /dev/null @@ -1,20 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 10.00 -# Visual Studio 2008 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "epanet-exe", "epanet-exe.vcproj", "{67C47E99-8BA3-4597-AFA8-566C26FF9C78}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Release|Win32 = Release|Win32 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {67C47E99-8BA3-4597-AFA8-566C26FF9C78}.Debug|Win32.ActiveCfg = Debug|Win32 - {67C47E99-8BA3-4597-AFA8-566C26FF9C78}.Debug|Win32.Build.0 = Debug|Win32 - {67C47E99-8BA3-4597-AFA8-566C26FF9C78}.Release|Win32.ActiveCfg = Release|Win32 - {67C47E99-8BA3-4597-AFA8-566C26FF9C78}.Release|Win32.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/build/MSVC/epanet-exe/epanet-exe.vcproj b/build/MSVC/epanet-exe/epanet-exe.vcproj deleted file mode 100755 index 7a6d512..0000000 --- a/build/MSVC/epanet-exe/epanet-exe.vcproj +++ /dev/null @@ -1,284 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/build/MSVC/epanet2.mak b/build/MSVC/epanet2.mak deleted file mode 100755 index a5c37ac..0000000 --- a/build/MSVC/epanet2.mak +++ /dev/null @@ -1,213 +0,0 @@ -# Microsoft Developer Studio Generated NMAKE File, Based on epanet2.dsp -!IF "$(CFG)" == "" -CFG=epanet2 - Win32 Release -!MESSAGE No configuration specified. Defaulting to epanet2 - Win32 Release. -!ENDIF - -!IF "$(CFG)" != "epanet2 - Win32 Release" -!MESSAGE Invalid configuration "$(CFG)" specified. -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "epanet2.mak" CFG="epanet2 - Win32 Release" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "epanet2 - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE -!ERROR An invalid configuration is specified. -!ENDIF - -!IF "$(OS)" == "Windows_NT" -NULL= -!ELSE -NULL=nul -!ENDIF - -OUTDIR=.\Release -INTDIR=.\Release -# Begin Custom Macros -OutDir=.\Release -# End Custom Macros - -ALL : "$(OUTDIR)\epanet2.dll" - - -CLEAN : - -@erase "$(INTDIR)\epanet.obj" - -@erase "$(INTDIR)\hash.obj" - -@erase "$(INTDIR)\hydraul.obj" - -@erase "$(INTDIR)\inpfile.obj" - -@erase "$(INTDIR)\input1.obj" - -@erase "$(INTDIR)\input2.obj" - -@erase "$(INTDIR)\input3.obj" - -@erase "$(INTDIR)\mempool.obj" - -@erase "$(INTDIR)\output.obj" - -@erase "$(INTDIR)\quality.obj" - -@erase "$(INTDIR)\report.obj" - -@erase "$(INTDIR)\rules.obj" - -@erase "$(INTDIR)\smatrix.obj" - -@erase "$(INTDIR)\vc60.idb" - -@erase "$(OUTDIR)\epanet2.dll" - -@erase "$(OUTDIR)\epanet2.exp" - -@erase "$(OUTDIR)\epanet2.lib" - -"$(OUTDIR)" : - if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" - -CPP=cl.exe -CPP_PROJ=/nologo /MT /W4 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EPANET2_EXPORTS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c - -.c{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(INTDIR)}.obj:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.c{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cpp{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -.cxx{$(INTDIR)}.sbr:: - $(CPP) @<< - $(CPP_PROJ) $< -<< - -MTL=midl.exe -MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 -RSC=rc.exe -BSC32=bscmake.exe -BSC32_FLAGS=/nologo /o"$(OUTDIR)\epanet2.bsc" -BSC32_SBRS= \ - -LINK32=link.exe -LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /incremental:no /pdb:"$(OUTDIR)\epanet2.pdb" /machine:I386 /def:"..\epanet2.def" /out:"$(OUTDIR)\epanet2.dll" /implib:"$(OUTDIR)\epanet2.lib" -DEF_FILE= \ - "..\epanet2.def" -LINK32_OBJS= \ - "$(INTDIR)\epanet.obj" \ - "$(INTDIR)\hash.obj" \ - "$(INTDIR)\hydraul.obj" \ - "$(INTDIR)\inpfile.obj" \ - "$(INTDIR)\input1.obj" \ - "$(INTDIR)\input2.obj" \ - "$(INTDIR)\input3.obj" \ - "$(INTDIR)\mempool.obj" \ - "$(INTDIR)\output.obj" \ - "$(INTDIR)\quality.obj" \ - "$(INTDIR)\report.obj" \ - "$(INTDIR)\rules.obj" \ - "$(INTDIR)\smatrix.obj" - -"$(OUTDIR)\epanet2.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) - $(LINK32) @<< - $(LINK32_FLAGS) $(LINK32_OBJS) -<< - - -!IF "$(NO_EXTERNAL_DEPS)" != "1" -!IF EXISTS("epanet2.dep") -!INCLUDE "epanet2.dep" -!ELSE -!MESSAGE Warning: cannot find "epanet2.dep" -!ENDIF -!ENDIF - - -!IF "$(CFG)" == "epanet2 - Win32 Release" -SOURCE=..\epanet.c - -"$(INTDIR)\epanet.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=..\hash.c - -"$(INTDIR)\hash.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=..\hydraul.c - -"$(INTDIR)\hydraul.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=..\inpfile.c - -"$(INTDIR)\inpfile.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=..\input1.c - -"$(INTDIR)\input1.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=..\input2.c - -"$(INTDIR)\input2.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=..\input3.c - -"$(INTDIR)\input3.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=..\mempool.c - -"$(INTDIR)\mempool.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=..\output.c - -"$(INTDIR)\output.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=..\quality.c - -"$(INTDIR)\quality.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=..\report.c - -"$(INTDIR)\report.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=..\rules.c - -"$(INTDIR)\rules.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - -SOURCE=..\smatrix.c - -"$(INTDIR)\smatrix.obj" : $(SOURCE) "$(INTDIR)" - $(CPP) $(CPP_PROJ) $(SOURCE) - - - -!ENDIF - diff --git a/build/MingW/CreateMSLib.bat.template b/build/MingW/CreateMSLib.bat.template deleted file mode 100755 index 3f8c06b..0000000 --- a/build/MingW/CreateMSLib.bat.template +++ /dev/null @@ -1 +0,0 @@ -"MSVClibexe" /machine:i386 /def:defname diff --git a/build/MingW/Makefile b/build/MingW/Makefile deleted file mode 100755 index 55d1ae1..0000000 --- a/build/MingW/Makefile +++ /dev/null @@ -1,161 +0,0 @@ -# MinGW Makefile for EPANET - -# Note: This makefile usese MinGW to produce native windows -# libraries and executables. The dll/import library, and -# executable files will have the same names as those produced -# using other Windows compilers, e.g. MSVC++. So be aware that -# there is no way to reliably distinguish between these two compiler -# sources based on output filenames. - -# This will build EPANET as a native windows DLL and import -# library (epanet2.dll/libepanet2.dll.a) using MinGW/gcc, -# and a standalone executable (epanet2.exe). -# This makefile also creates a windows batch file -# (see MScmdname below) that can be run to produce an import -# library for linking the DLL using MSVC. -# This makefile assumes a minimum -# MinGW installation, and uses the MinGW gcc compiler from -# the MinGW install directory. -# The current release of MinGW can be obtained from -# http://www.mingw.org/wiki/Getting_Started -- the easiest -# approach is to download the latest MingW installer and -# accept all of the defaults. - -# The following targets are defined (for execution in -# the build directory): -# make -# -Builds epanet2.dll, epanet2.def, libepanet2.dll.a, -# epanet2.exe -# make install -# -Creates scripts runepanet2.sh and CreateEpanet2Lib.bat that -# execute epanet2.exe, and MSVC 'lib' (to create an MSVC -# import library). The runepanet2.sh wrapper simply exports -# environment variables so that the DLL is found at runtime, -# allowing you to specify your own locations for installing -# the DLL. -# -Installs epanet2.dll, epanet2.exe, and runepanet2.sh -# in /bin, where defaults to ~ (and can be set -# below to something different - see "Install directories") -# -Installs libepanet2.dll.a (import library), epanet2.def, -# and CreateEpanet2Lib.bat in /lib -# -Installs epanet2.h in /include. This is the required -# header file for the EPANET programmer's toolkit, and thus -# /include should be on your CPP include search path -# for subsequent use of the toolkit and linking with the import -# library libepanet2.dll.a or epanet2.lib. -# make clean -# -Removes object and library files, returning the build directory -# to its pristine state. - -SHELL = /bin/sh - -# C H A N G E H E R E A S N E E D E D -# Change (as needed) the MinGW install directory below. -# Change (as needed) the location off the MS LIB tool. -# You may also wish to change the install path 'prefix', -# or the compiler flags, but these defaults should be fine. - -# MinGW top level install directory, accessible from build environment -MinGWdir = /cygdrive/c/MinGW -# Microsoft lib tool directory (for creating an MS import library) -MSVClibexe = c:\\Program Files\\Microsoft Visual Studio 9.0\\VC\\bin\\lib - -# Target filenames -# svnname.sh constructs a name: -# where is the atomic revision number of the svn repo. -epanetrootname := epanet2 -dllname := $(epanetrootname).dll -defname := $(epanetrootname).def -implibname = lib$(dllname).a -exename := $(epanetrootname) -# Shell wrapper -runcmdtemplate = runepanet.sh.template -runcmdname = runepanet2.sh -# MSVC import lib batch file -MScmdtemplate = CreateMSLib.bat.template -MScmdname = CreateEpanet2Lib.bat -# Location of EPANET toolkit includes -epanetincludedir = ../../include -# Search path for sources -epanetsrcdir = ../../src -VPATH = $(epanetsrcdir):$(epanetincludedir) - -# Install directories -winprefix = $(shell cygpath -w $$HOME) -prefix = ~ -exec_prefix = $(prefix) -srcdir = . -libdir = $(exec_prefix)/lib -winlibdir = "$(winprefix)\lib" -bindir = $(exec_prefix)/bin -includedir = $(prefix)/include -winincludedir = "$(winprefix)\include" -datarootdir = $(prefix)/share -docdir = $(datarootdir)/doc/epanet - -# Compiler and flags -# MinGW gcc -CC = $(MinGWdir)/bin/gcc -dlltool = $(MinGWdir)/bin/dlltool -CFLAGS = -g -O3 -CPPFLAGS = -I $(srcdir) -I $(epanetincludedir) -LDFLAGS = -L . -W1,-rpath,$(libdir) -lm - -# Installer -INSTALL = install -INSTALL_PROGRAM = $(INSTALL) -INSTALL_DATA = $(INSTALL) -m 644 - -# EPANET object files -epanet_objs=hash.o hydraul.o inpfile.o input1.o input2.o \ - input3.o mempool.o output.o quality.o report.o \ - rules.o smatrix.o -# Epanet header files -epanet_heads=enumstxt.h funcs.h hash.h mempool.h text.h toolkit.h types.h vars.h -epanet_main_heads=epanet2.h -# Epanet main program -epanet_main=epanet - -.PHONY: all -all: $(dllname) $(exename) - -$(dllname): $(epanet_objs) -# $(dlltool) -z $(defname) --dllname $(dllname) --output-lib $(implibname) $^ -# $(CC) $(CFLAGS) $(LDFLAGS) -shared -o $@ $(defname) $^ - $(CC) $(CFLAGS) $(CPPFLAGS) -D DLL -c $(epanetsrcdir)/epanet.c - $(CC) $(CFLAGS) $(LDFLAGS) -shared -o $@ epanet.o $^ -Wl,--output-def,$(defname) - $(CC) $(CFLAGS) $(LDFLAGS) -shared -o $@ epanet.o $^ -Wl,--kill-at - $(dlltool) -d $(defname) --dllname $@ --output-lib $(implibname) --kill-at - -$(exename): $(epanet_objs) - $(CC) $(CFLAGS) $(CPPFLAGS) -D CLE -c $(epanetsrcdir)/$(epanet_main).c - $(CC) $(CFLAGS) -o $@ $(epanet_main).o $^ $(LDFLAGS) - -$(epanet_objs): $(epanet_heads) - -.PHONY: install -install: - cat $(runcmdtemplate) | sed 's|libdir|$(bindir)|' \ - | sed 's|exename|$(bindir)/$(exename)|' \ - > $(runcmdname) - cat $(MScmdtemplate) | sed 's|MSVClibexe|$(MSVClibexe)|' \ - | sed 's|defname|$(defname)|' \ - | sed 's|libdir|$(libdir)|' \ - > $(MScmdname) - $(INSTALL_PROGRAM) -D $(exename) $(bindir)/$(exename) - $(INSTALL_PROGRAM) -D $(dllname) $(bindir)/$(dllname) - $(INSTALL_PROGRAM) -D $(defname) $(libdir)/$(defname) - $(INSTALL_PROGRAM) -D $(implibname) $(libdir)/$(implibname) - $(INSTALL_DATA) -D $(epanetincludedir)/epanet2.h $(includedir)/epanet2.h - $(INSTALL_PROGRAM) -D $(runcmdname) $(bindir)/$(runcmdname) - $(INSTALL_PROGRAM) -D $(MScmdname) $(libdir)/$(MScmdname) - -.PHONY: uninstall -uninstall: - -.PHONY: check -check: - -.PHONY: clean -clean: - -/bin/rm *.o $(dllname) $(defname) $(implibname) $(exename).exe $(runcmdname) $(MScmdname) diff --git a/build/MingW/Makefile_Rev b/build/MingW/Makefile_Rev deleted file mode 100755 index c88de77..0000000 --- a/build/MingW/Makefile_Rev +++ /dev/null @@ -1,159 +0,0 @@ -# Cygwin/MinGW Makefile for EPANET - -# This will build EPANET as a native windows DLL and import -# library (epanet_gcc_.dll/libepanet_gcc_.dll.a) under Cygwin/MinGW, -# and a standalone executable (epanet_gcc_.exe). -# is the atomic revision number of the EPANET SVN repo, -# so the results of each build can be unambiguously tracked to a repo Rev. -# This makefile also creates a windows batch file -# (see MScmdname below) that will produce an import -# library for linking the DLL using MSVC. -# This makefile assumes a Cygwin environment with minimal -# MinGW installation, and uses the MinGW gcc compiler from -# the MinGW install directory. -# The current release of MinGW can be obtained from -# http://www.mingw.org/wiki/Getting_Started -- the easiest -# approach is to download the latest MingW installer and -# accept all of the defaults. -# The current release of the Cygwin environment can be -# obtained from http://www.cygwin.com - -# The following targets are defined (for execution in -# the build directory under the Cygwin environment): -# make -# -Builds epanet_gcc_.dll, epanet_gcc_.def, libepanet_gcc_.dll.a, -# epanet_gcc_.exe -# make install -# -Creates shell wrappers runepanet_.sh and CreateMSLib_.bat that -# execute epanet_gcc_.exe, and MSVC 'lib' (to create an MSVC -# import library). The runepanet_.sh wrapper simply exports -# environment variables so that the DLL is found at runtime, -# allowing you to specify your own locations for installing -# the DLL. -# -Installs epanet_gcc_.dll, epanet_gcc_.exe, and runepanet_.sh -# in /bin, where defaults to ~ (and can be set -# below to something different - see "Install directories") -# -Installs libepanet_gcc_.dll.a (import library), epanet_gcc_.def, -# and CreateMSLib-.bat in /lib -# -Installs epanet2.h in /include. This is the required -# header file for the EPANET programmer's toolkit, and thus -# /include should be on your CPP include search path -# for subsequent use of the toolkit and linking with the import -# library libepanet_gcc_.dll.a. -# make clean -# -Removes object and library files, returning the build directory -# to its pristine state. - -SHELL = /bin/sh - -# C H A N G E H E R E A S N E E D E D -# Change (as needed) the MinGW install directory below. -# Change (as needed) the location off the MS LIB tool. -# You may also wish to change the install path 'prefix', -# or the compiler flags, but these defaults should be fine. - -# MinGW top level install directory, accessible from build environment -MinGWdir = /cygdrive/c/MinGW -# Microsoft lib tool directory (for creating an MS import library) -MSVClibexe = c:\\Program Files\\Microsoft Visual Studio 9.0\\VC\\bin\\lib - -# Target filenames -# svnname.sh constructs a name: -# where is the atomic revision number of the svn repo. -epanetsvnpath = ../../.. -epanetrootname := $(shell ../svnname.sh $(epanetsvnpath) "" epanet_gcc_ "") -dllname := $(epanetrootname).dll -defname := $(epanetrootname).def -implibname = lib$(dllname).a -exename := $(epanetrootname) -# Shell wrapper -runcmdtemplate = runepanet.sh.template -runcmdname = $(shell ../svnname.sh $(epanetsvnpath) "" runepanet_ .sh) -# MSVC import lib batch file -MScmdtemplate = CreateMSLib.bat.template -MScmdname = $(shell ../svnname.sh $(epanetsvnpath) "" CreateEpanetLib_ .bat) -# Location of EPANET toolkit includes -epanetincludedir = ../../include -# Search path for sources -epanetsrcdir = ../../src -VPATH = $(epanetsrcdir):$(epanetincludedir) - -# Install directories -winprefix = $(shell cygpath -w $$HOME) -prefix = ~ -exec_prefix = $(prefix) -srcdir = . -libdir = $(exec_prefix)/lib -winlibdir = "$(winprefix)\lib" -bindir = $(exec_prefix)/bin -includedir = $(prefix)/include -winincludedir = "$(winprefix)\include" -datarootdir = $(prefix)/share -docdir = $(datarootdir)/doc/epanet - -# Compiler and flags -# MinGW gcc -CC = $(MinGWdir)/bin/gcc -dlltool = $(MinGWdir)/bin/dlltool -CFLAGS = -g -O3 -CPPFLAGS = -I $(srcdir) -I $(epanetincludedir) -LDFLAGS = -L . -W1,-rpath,$(libdir) -lm - -# Installer -INSTALL = install -INSTALL_PROGRAM = $(INSTALL) -INSTALL_DATA = $(INSTALL) -m 644 - -# EPANET object files -epanet_objs=hash.o hydraul.o inpfile.o input1.o input2.o \ - input3.o mempool.o output.o quality.o report.o \ - rules.o smatrix.o -# Epanet header files -epanet_heads=enumstxt.h funcs.h hash.h mempool.h text.h toolkit.h types.h vars.h -epanet_main_heads=epanet2.h -# Epanet main program -epanet_main=epanet - -.PHONY: all -all: $(dllname) $(exename) - -$(dllname): $(epanet_objs) -# $(dlltool) -z $(defname) --dllname $(dllname) --output-lib $(implibname) $^ -# $(CC) $(CFLAGS) $(LDFLAGS) -shared -o $@ $(defname) $^ - $(CC) $(CFLAGS) $(CPPFLAGS) -D DLL -c $(epanetsrcdir)/epanet.c - $(CC) $(CFLAGS) $(LDFLAGS) -shared -o $@ epanet.o $^ -Wl,--output-def,$(defname) - $(CC) $(CFLAGS) $(LDFLAGS) -shared -o $@ epanet.o $^ -Wl,--kill-at - $(dlltool) -d $(defname) --dllname $@ --output-lib $(implibname) --kill-at - -$(exename): $(epanet_objs) - $(CC) $(CFLAGS) $(CPPFLAGS) -D CLE -c $(epanetsrcdir)/$(epanet_main).c - $(CC) $(CFLAGS) -o $@ $(epanet_main).o $^ $(LDFLAGS) - -$(epanet_objs): $(epanet_heads) - -.PHONY: install -install: - cat $(runcmdtemplate) | sed 's|libdir|$(bindir)|' \ - | sed 's|exename|$(bindir)/$(exename)|' \ - > $(runcmdname) - cat $(MScmdtemplate) | sed 's|MSVClibexe|$(MSVClibexe)|' \ - | sed 's|defname|$(defname)|' \ - | sed 's|libdir|$(libdir)|' \ - > $(MScmdname) - $(INSTALL_PROGRAM) -D $(exename) $(bindir)/$(exename) - $(INSTALL_PROGRAM) -D $(dllname) $(bindir)/$(dllname) - $(INSTALL_PROGRAM) -D $(defname) $(libdir)/$(defname) - $(INSTALL_PROGRAM) -D $(implibname) $(libdir)/$(implibname) - $(INSTALL_DATA) -D $(epanetincludedir)/epanet2.h $(includedir)/epanet2.h - $(INSTALL_PROGRAM) -D $(runcmdname) $(bindir)/$(runcmdname) - $(INSTALL_PROGRAM) -D $(MScmdname) $(libdir)/$(MScmdname) - -.PHONY: uninstall -uninstall: - -.PHONY: check -check: - -.PHONY: clean -clean: - -/bin/rm *.o $(dllname) $(defname) $(implibname) $(exename).exe $(runcmdname) $(MScmdname) diff --git a/build/MingW/runepanet.sh.template b/build/MingW/runepanet.sh.template deleted file mode 100755 index 55ae0d3..0000000 --- a/build/MingW/runepanet.sh.template +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh -export PATH=libdir:$PATH -export LD_LIBRARY_PATH=libdir:$LD_LIBRARY_PATH -exec exename "$@" diff --git a/build/Xcode/epanet/epanet.xcodeproj/project.pbxproj b/build/Xcode/epanet/epanet.xcodeproj/project.pbxproj deleted file mode 100644 index 59a4a81..0000000 --- a/build/Xcode/epanet/epanet.xcodeproj/project.pbxproj +++ /dev/null @@ -1,424 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - 22322F851068369500641384 /* enumstxt.h in Headers */ = {isa = PBXBuildFile; fileRef = 22322F701068369500641384 /* enumstxt.h */; }; - 22322F861068369500641384 /* epanet.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F711068369500641384 /* epanet.c */; }; - 22322F871068369500641384 /* funcs.h in Headers */ = {isa = PBXBuildFile; fileRef = 22322F721068369500641384 /* funcs.h */; }; - 22322F881068369500641384 /* hash.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F731068369500641384 /* hash.c */; }; - 22322F891068369500641384 /* hash.h in Headers */ = {isa = PBXBuildFile; fileRef = 22322F741068369500641384 /* hash.h */; }; - 22322F8A1068369500641384 /* hydraul.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F751068369500641384 /* hydraul.c */; }; - 22322F8B1068369500641384 /* inpfile.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F761068369500641384 /* inpfile.c */; }; - 22322F8C1068369500641384 /* input1.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F771068369500641384 /* input1.c */; }; - 22322F8D1068369500641384 /* input2.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F781068369500641384 /* input2.c */; }; - 22322F8E1068369500641384 /* input3.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F791068369500641384 /* input3.c */; }; - 22322F8F1068369500641384 /* mempool.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F7A1068369500641384 /* mempool.c */; }; - 22322F901068369500641384 /* mempool.h in Headers */ = {isa = PBXBuildFile; fileRef = 22322F7B1068369500641384 /* mempool.h */; }; - 22322F911068369500641384 /* output.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F7C1068369500641384 /* output.c */; }; - 22322F921068369500641384 /* quality.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F7D1068369500641384 /* quality.c */; }; - 22322F931068369500641384 /* report.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F7E1068369500641384 /* report.c */; }; - 22322F941068369500641384 /* rules.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F7F1068369500641384 /* rules.c */; }; - 22322F951068369500641384 /* smatrix.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F801068369500641384 /* smatrix.c */; }; - 22322F961068369500641384 /* text.h in Headers */ = {isa = PBXBuildFile; fileRef = 22322F811068369500641384 /* text.h */; }; - 22322F971068369500641384 /* toolkit.h in Headers */ = {isa = PBXBuildFile; fileRef = 22322F821068369500641384 /* toolkit.h */; }; - 22322F981068369500641384 /* types.h in Headers */ = {isa = PBXBuildFile; fileRef = 22322F831068369500641384 /* types.h */; }; - 22322F991068369500641384 /* vars.h in Headers */ = {isa = PBXBuildFile; fileRef = 22322F841068369500641384 /* vars.h */; }; - 22322F9A1068369500641384 /* epanet.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F711068369500641384 /* epanet.c */; }; - 22322F9B1068369500641384 /* hash.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F731068369500641384 /* hash.c */; }; - 22322F9C1068369500641384 /* hydraul.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F751068369500641384 /* hydraul.c */; }; - 22322F9D1068369500641384 /* inpfile.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F761068369500641384 /* inpfile.c */; }; - 22322F9E1068369500641384 /* input1.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F771068369500641384 /* input1.c */; }; - 22322F9F1068369500641384 /* input2.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F781068369500641384 /* input2.c */; }; - 22322FA01068369500641384 /* input3.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F791068369500641384 /* input3.c */; }; - 22322FA11068369500641384 /* mempool.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F7A1068369500641384 /* mempool.c */; }; - 22322FA21068369500641384 /* output.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F7C1068369500641384 /* output.c */; }; - 22322FA31068369500641384 /* quality.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F7D1068369500641384 /* quality.c */; }; - 22322FA41068369500641384 /* report.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F7E1068369500641384 /* report.c */; }; - 22322FA51068369500641384 /* rules.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F7F1068369500641384 /* rules.c */; }; - 22322FA61068369500641384 /* smatrix.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F801068369500641384 /* smatrix.c */; }; - 22322FAA106836BC00641384 /* epanet2.h in Headers */ = {isa = PBXBuildFile; fileRef = 22322FA9106836B000641384 /* epanet2.h */; }; - 22322FAE106836D900641384 /* malloc.h in Headers */ = {isa = PBXBuildFile; fileRef = 22322FAD106836D900641384 /* malloc.h */; }; -/* End PBXBuildFile section */ - -/* Begin PBXContainerItemProxy section */ - 22322FAF1068370B00641384 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = D2AAC0620554660B00DB518D; - remoteInfo = epanet; - }; -/* End PBXContainerItemProxy section */ - -/* Begin PBXFileReference section */ - 22322F66106833BB00641384 /* runepanet */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = runepanet; sourceTree = BUILT_PRODUCTS_DIR; }; - 22322F701068369500641384 /* enumstxt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = enumstxt.h; path = ../../../src/enumstxt.h; sourceTree = SOURCE_ROOT; }; - 22322F711068369500641384 /* epanet.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = epanet.c; path = ../../../src/epanet.c; sourceTree = SOURCE_ROOT; }; - 22322F721068369500641384 /* funcs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = funcs.h; path = ../../../src/funcs.h; sourceTree = SOURCE_ROOT; }; - 22322F731068369500641384 /* hash.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = hash.c; path = ../../../src/hash.c; sourceTree = SOURCE_ROOT; }; - 22322F741068369500641384 /* hash.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = hash.h; path = ../../../src/hash.h; sourceTree = SOURCE_ROOT; }; - 22322F751068369500641384 /* hydraul.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = hydraul.c; path = ../../../src/hydraul.c; sourceTree = SOURCE_ROOT; }; - 22322F761068369500641384 /* inpfile.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = inpfile.c; path = ../../../src/inpfile.c; sourceTree = SOURCE_ROOT; }; - 22322F771068369500641384 /* input1.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = input1.c; path = ../../../src/input1.c; sourceTree = SOURCE_ROOT; }; - 22322F781068369500641384 /* input2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = input2.c; path = ../../../src/input2.c; sourceTree = SOURCE_ROOT; }; - 22322F791068369500641384 /* input3.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = input3.c; path = ../../../src/input3.c; sourceTree = SOURCE_ROOT; }; - 22322F7A1068369500641384 /* mempool.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = mempool.c; path = ../../../src/mempool.c; sourceTree = SOURCE_ROOT; }; - 22322F7B1068369500641384 /* mempool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = mempool.h; path = ../../../src/mempool.h; sourceTree = SOURCE_ROOT; }; - 22322F7C1068369500641384 /* output.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = output.c; path = ../../../src/output.c; sourceTree = SOURCE_ROOT; }; - 22322F7D1068369500641384 /* quality.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = quality.c; path = ../../../src/quality.c; sourceTree = SOURCE_ROOT; }; - 22322F7E1068369500641384 /* report.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = report.c; path = ../../../src/report.c; sourceTree = SOURCE_ROOT; }; - 22322F7F1068369500641384 /* rules.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = rules.c; path = ../../../src/rules.c; sourceTree = SOURCE_ROOT; }; - 22322F801068369500641384 /* smatrix.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = smatrix.c; path = ../../../src/smatrix.c; sourceTree = SOURCE_ROOT; }; - 22322F811068369500641384 /* text.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = text.h; path = ../../../src/text.h; sourceTree = SOURCE_ROOT; }; - 22322F821068369500641384 /* toolkit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = toolkit.h; path = ../../../src/toolkit.h; sourceTree = SOURCE_ROOT; }; - 22322F831068369500641384 /* types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = types.h; path = ../../../src/types.h; sourceTree = SOURCE_ROOT; }; - 22322F841068369500641384 /* vars.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = vars.h; path = ../../../src/vars.h; sourceTree = SOURCE_ROOT; }; - 22322FA9106836B000641384 /* epanet2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = epanet2.h; path = ../../../include/epanet2.h; sourceTree = SOURCE_ROOT; }; - 22322FAD106836D900641384 /* malloc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = malloc.h; path = macinclude/malloc.h; sourceTree = ""; }; - D2AAC0630554660B00DB518D /* libepanet.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libepanet.dylib; sourceTree = BUILT_PRODUCTS_DIR; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 22322F64106833BB00641384 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - D289988505E68E00004EDB86 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 08FB7794FE84155DC02AAC07 /* epanet */ = { - isa = PBXGroup; - children = ( - 22322FA8106836A000641384 /* Include */, - 08FB7795FE84155DC02AAC07 /* Source */, - 1AB674ADFE9D54B511CA2CBB /* Products */, - ); - name = epanet; - sourceTree = ""; - }; - 08FB7795FE84155DC02AAC07 /* Source */ = { - isa = PBXGroup; - children = ( - 22322F701068369500641384 /* enumstxt.h */, - 22322F711068369500641384 /* epanet.c */, - 22322F721068369500641384 /* funcs.h */, - 22322F731068369500641384 /* hash.c */, - 22322F741068369500641384 /* hash.h */, - 22322F751068369500641384 /* hydraul.c */, - 22322F761068369500641384 /* inpfile.c */, - 22322F771068369500641384 /* input1.c */, - 22322F781068369500641384 /* input2.c */, - 22322F791068369500641384 /* input3.c */, - 22322F7A1068369500641384 /* mempool.c */, - 22322F7B1068369500641384 /* mempool.h */, - 22322F7C1068369500641384 /* output.c */, - 22322F7D1068369500641384 /* quality.c */, - 22322F7E1068369500641384 /* report.c */, - 22322F7F1068369500641384 /* rules.c */, - 22322F801068369500641384 /* smatrix.c */, - 22322F811068369500641384 /* text.h */, - 22322F821068369500641384 /* toolkit.h */, - 22322F831068369500641384 /* types.h */, - 22322F841068369500641384 /* vars.h */, - ); - name = Source; - sourceTree = ""; - }; - 1AB674ADFE9D54B511CA2CBB /* Products */ = { - isa = PBXGroup; - children = ( - D2AAC0630554660B00DB518D /* libepanet.dylib */, - 22322F66106833BB00641384 /* runepanet */, - ); - name = Products; - sourceTree = ""; - }; - 22322FA8106836A000641384 /* Include */ = { - isa = PBXGroup; - children = ( - 22322FAD106836D900641384 /* malloc.h */, - 22322FA9106836B000641384 /* epanet2.h */, - ); - name = Include; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXHeadersBuildPhase section */ - D2AAC0600554660B00DB518D /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - 22322FAA106836BC00641384 /* epanet2.h in Headers */, - 22322F851068369500641384 /* enumstxt.h in Headers */, - 22322F871068369500641384 /* funcs.h in Headers */, - 22322F891068369500641384 /* hash.h in Headers */, - 22322F901068369500641384 /* mempool.h in Headers */, - 22322F961068369500641384 /* text.h in Headers */, - 22322F971068369500641384 /* toolkit.h in Headers */, - 22322F981068369500641384 /* types.h in Headers */, - 22322F991068369500641384 /* vars.h in Headers */, - 22322FAE106836D900641384 /* malloc.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXHeadersBuildPhase section */ - -/* Begin PBXNativeTarget section */ - 22322F65106833BB00641384 /* runepanet */ = { - isa = PBXNativeTarget; - buildConfigurationList = 22322F6A106833E600641384 /* Build configuration list for PBXNativeTarget "runepanet" */; - buildPhases = ( - 22322F63106833BB00641384 /* Sources */, - 22322F64106833BB00641384 /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - 22322FB01068370B00641384 /* PBXTargetDependency */, - ); - name = runepanet; - productName = runepanet; - productReference = 22322F66106833BB00641384 /* runepanet */; - productType = "com.apple.product-type.tool"; - }; - D2AAC0620554660B00DB518D /* epanet */ = { - isa = PBXNativeTarget; - buildConfigurationList = 1DEB914A08733D8E0010E9CD /* Build configuration list for PBXNativeTarget "epanet" */; - buildPhases = ( - D2AAC0600554660B00DB518D /* Headers */, - D2AAC0610554660B00DB518D /* Sources */, - D289988505E68E00004EDB86 /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = epanet; - productName = epanet; - productReference = D2AAC0630554660B00DB518D /* libepanet.dylib */; - productType = "com.apple.product-type.library.dynamic"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 08FB7793FE84155DC02AAC07 /* Project object */ = { - isa = PBXProject; - buildConfigurationList = 1DEB914E08733D8E0010E9CD /* Build configuration list for PBXProject "epanet" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 1; - knownRegions = ( - English, - Japanese, - French, - German, - ); - mainGroup = 08FB7794FE84155DC02AAC07 /* epanet */; - projectDirPath = ""; - projectRoot = ../../..; - targets = ( - D2AAC0620554660B00DB518D /* epanet */, - 22322F65106833BB00641384 /* runepanet */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXSourcesBuildPhase section */ - 22322F63106833BB00641384 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 22322F9A1068369500641384 /* epanet.c in Sources */, - 22322F9B1068369500641384 /* hash.c in Sources */, - 22322F9C1068369500641384 /* hydraul.c in Sources */, - 22322F9D1068369500641384 /* inpfile.c in Sources */, - 22322F9E1068369500641384 /* input1.c in Sources */, - 22322F9F1068369500641384 /* input2.c in Sources */, - 22322FA01068369500641384 /* input3.c in Sources */, - 22322FA11068369500641384 /* mempool.c in Sources */, - 22322FA21068369500641384 /* output.c in Sources */, - 22322FA31068369500641384 /* quality.c in Sources */, - 22322FA41068369500641384 /* report.c in Sources */, - 22322FA51068369500641384 /* rules.c in Sources */, - 22322FA61068369500641384 /* smatrix.c in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - D2AAC0610554660B00DB518D /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 22322F861068369500641384 /* epanet.c in Sources */, - 22322F881068369500641384 /* hash.c in Sources */, - 22322F8A1068369500641384 /* hydraul.c in Sources */, - 22322F8B1068369500641384 /* inpfile.c in Sources */, - 22322F8C1068369500641384 /* input1.c in Sources */, - 22322F8D1068369500641384 /* input2.c in Sources */, - 22322F8E1068369500641384 /* input3.c in Sources */, - 22322F8F1068369500641384 /* mempool.c in Sources */, - 22322F911068369500641384 /* output.c in Sources */, - 22322F921068369500641384 /* quality.c in Sources */, - 22322F931068369500641384 /* report.c in Sources */, - 22322F941068369500641384 /* rules.c in Sources */, - 22322F951068369500641384 /* smatrix.c in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXTargetDependency section */ - 22322FB01068370B00641384 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = D2AAC0620554660B00DB518D /* epanet */; - targetProxy = 22322FAF1068370B00641384 /* PBXContainerItemProxy */; - }; -/* End PBXTargetDependency section */ - -/* Begin XCBuildConfiguration section */ - 1DEB914B08733D8E0010E9CD /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - COPY_PHASE_STRIP = NO; - EXECUTABLE_PREFIX = lib; - GCC_DYNAMIC_NO_PIC = NO; - GCC_ENABLE_FIX_AND_CONTINUE = YES; - GCC_MODEL_TUNING = G5; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_VERSION = com.apple.compilers.llvm.clang.1_0; - INSTALL_PATH = /usr/local/lib; - PRODUCT_NAME = epanet; - SDKROOT = ""; - }; - name = Debug; - }; - 1DEB914C08733D8E0010E9CD /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - EXECUTABLE_PREFIX = lib; - GCC_MODEL_TUNING = G5; - GCC_VERSION = com.apple.compilers.llvm.clang.1_0; - INSTALL_PATH = /usr/local/lib; - PRODUCT_NAME = epanet; - SDKROOT = ""; - }; - name = Release; - }; - 1DEB914F08733D8E0010E9CD /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_VERSION = com.apple.compilers.llvm.clang.1_0; - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - HEADER_SEARCH_PATHS = macinclude; - ONLY_ACTIVE_ARCH = YES; - PREBINDING = NO; - SDKROOT = macosx10.6; - }; - name = Debug; - }; - 1DEB915008733D8E0010E9CD /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_VERSION = com.apple.compilers.llvm.clang.1_0; - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - HEADER_SEARCH_PATHS = macinclude; - PREBINDING = NO; - SDKROOT = macosx10.6; - }; - name = Release; - }; - 22322F68106833BC00641384 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - COPY_PHASE_STRIP = NO; - GCC_DYNAMIC_NO_PIC = NO; - GCC_ENABLE_FIX_AND_CONTINUE = YES; - GCC_MODEL_TUNING = G5; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = CLE; - GCC_VERSION = com.apple.compilers.llvm.clang.1_0; - INFOPLIST_PREPROCESSOR_DEFINITIONS = ""; - INSTALL_PATH = /usr/local/bin; - PREBINDING = NO; - PRODUCT_NAME = runepanet; - }; - name = Debug; - }; - 22322F69106833BC00641384 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - COPY_PHASE_STRIP = YES; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - GCC_ENABLE_FIX_AND_CONTINUE = NO; - GCC_MODEL_TUNING = G5; - GCC_PREPROCESSOR_DEFINITIONS = CLE; - GCC_VERSION = com.apple.compilers.llvm.clang.1_0; - INFOPLIST_PREPROCESSOR_DEFINITIONS = ""; - INSTALL_PATH = /usr/local/bin; - PREBINDING = NO; - PRODUCT_NAME = runepanet; - ZERO_LINK = NO; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 1DEB914A08733D8E0010E9CD /* Build configuration list for PBXNativeTarget "epanet" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 1DEB914B08733D8E0010E9CD /* Debug */, - 1DEB914C08733D8E0010E9CD /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 1DEB914E08733D8E0010E9CD /* Build configuration list for PBXProject "epanet" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 1DEB914F08733D8E0010E9CD /* Debug */, - 1DEB915008733D8E0010E9CD /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 22322F6A106833E600641384 /* Build configuration list for PBXNativeTarget "runepanet" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 22322F68106833BC00641384 /* Debug */, - 22322F69106833BC00641384 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 08FB7793FE84155DC02AAC07 /* Project object */; -} diff --git a/build/Xcode/epanet/macinclude/malloc.h b/build/Xcode/epanet/macinclude/malloc.h deleted file mode 100644 index 1a882e9..0000000 --- a/build/Xcode/epanet/macinclude/malloc.h +++ /dev/null @@ -1,10 +0,0 @@ -/* - * malloc.h - * epanet - * - * Created by Sam Hatchett on 9/21/09. - * Copyright 2009 __MyCompanyName__. All rights reserved. - * - */ - -#include \ No newline at end of file diff --git a/build/svnname.sh b/build/svnname.sh deleted file mode 100755 index adc579f..0000000 --- a/build/svnname.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash -SVNREV=`svn info "$1" | grep Revision | awk -F": " '{print $2}'` -echo $2$3${SVNREV}$4 diff --git a/doc/LICENSE.txt b/doc/LICENSE.txt deleted file mode 100644 index e89e95d..0000000 --- a/doc/LICENSE.txt +++ /dev/null @@ -1,9 +0,0 @@ -The EPANET software was developed by Lewis Rossman (US-EPA). - -This public-domain software developed by the U.S. EPA, -National Risk Management Research Laboratory in Cincinnati, Ohio. -Although these programs have been used by the U.S. EPA, no warranty, -expressed or implied, is made by the U.S. EPA as to the accuracy and -functioning of the programs and related program material, nor shall the -fact of distribution constitute any such warranty, and no responsibility -is assumed by the U.S. EPA in connection therewith. diff --git a/doc/Readme.txt b/doc/Readme.txt deleted file mode 100755 index 6a43140..0000000 --- a/doc/Readme.txt +++ /dev/null @@ -1,54 +0,0 @@ -Contents of EPANET2.ZIP -======================= -This archive contains the source code for the EPANET 2 -network hydraulic and water quality solver. The solver -provides functions for simulating the extended period -hydraulic and water quality behavior of water distribution -system pipe networks. It is written in ANSI-compatible C -and can be compiled into either a Windows Dynamic Link -Library of functions or into a command-line executable. - -The archived code is set up for compilation as a DLL. -To compile it as a command line (or console) application -simply comment out the "#define DLL" macro statement at -the top of EPANET.C and un-comment the "#define CLE" macro. - -The DLL version of the solver (epanet2.dll) is used with -the EPANET 2 user interface executable (epanet2w.exe) to -form a complete Windows modeling package. It also serves -as the function library for the EPANET Programmer's Toolkit, -allowing developers to construct their own customized pipe -network analysis applications. - -The following C-code files are included in this archive: - EPANET.C -- main module providing supervisory control - INPUT1.C -- controls processing of input data - INPUT2.C -- reads data from input file - INPUT3.C -- parses individual lines of input data - INPFILE.C -- saves modified input data to a text file - RULES.C -- implements rule-based control of piping system - HYDRAUL.C -- computes extended period hydraulic behavior - QUALITY.C -- tracks transport & fate of water quality - OUTPUT.C -- handles transfer of data to and from binary files - REPORT.C -- handles reporting of results to text file - SMATRIX.C -- sparse matrix linear equation solver routines - MEMPOOL.C -- memory pool management routines - HASH.C -- hash table routines - -Also included are the following header files: - TOOLKIT.H -- function prototypes of exported DLL functions - FUNCS.H -- prototypes of all other functions - TYPES.H -- declaration of global constants and data structures - VARS.H -- declaration of global variables - HASH.H -- header file for hash table routines - MEMPOOL.H -- header file for memory pool routines - ENUMSTXT.H -- string constants for enumerated types - TEXT.H -- declaration of all other string constants - -The comments at the top of each file lists the date when the latest -update was made, and these updates can be located in the code by -searching for comments with the phrase "/*** Updated" or with the -release number (e.g., 2.00.12) in them. - -Other useful documentation that can be consulted includes the EPANET -Programmers Toolkit Help file and the EPANET Version 2 Users Manual. diff --git a/doc/changes.txt b/doc/changes.txt deleted file mode 100755 index 867837d..0000000 --- a/doc/changes.txt +++ /dev/null @@ -1,57 +0,0 @@ ------------------------ -Build 2.00.12 (2/25/08) ------------------------ - -Computational Engine Changes (epanet2.dll and epanet2d.exe): -=============================================================================== -CODE MODULES CHANGES -=============================================================================== -EPANET.C Temporary files are now written to the users's current working -INPUT1.C directory or to the designated Temporary Directory when running -VARS.H the Windows GUI, thus avoiding file access problems for users -FUNCS.H who do not have administrative privileges on their machine. -------------------------------------------------------------------------------- -EPANET.C The following tank parameters were made available for retrieval -TOOLKIT.H using the Toolkit's ENgetnodevalue function: tank diameter, -EPANET2.H minimum volume, index of the tank's volume curve, the initial, - minimum, and maximum water levels, the fraction of a 2-compart- - ment tank devoted to the mixing zone, and the tank's bulk - reaction rate coefficient. These same parameters (with the - exception of the volume curve) were made modifiable using the - ENsetnodevalue function, as was the choice of mixing model. - See the Toolkit Help file for details. -------------------------------------------------------------------------------- -EPANET.C A new Toolkit function, ENaddpattern, was added that allows -TOOLKIT.C programmers to add a new time pattern to the network in any -EPANET2.H custom code that they write. -------------------------------------------------------------------------------- -HYDRAUL.C A DAMPLIMIT parameter was added to control at what point during -INPUT1.C the hydraulic solution iterations status checks on PRVs and PSVs -INPUT3.C begin and subsequent flow changes are dampened. -REPORT.C -VARS.H -TEXT.H -------------------------------------------------------------------------------- -HYDRAUL.C Demands for tanks (net inflows/outflows) were not always being - set to zero when the tank was full or empty which was causing - problems in the water quality routing solutions. -------------------------------------------------------------------------------- -QUALITY.C The water quality functions for all of the tank mixing models - were modified so as to produce more robust results for cases - where there is a significant amount of volume exchange over a - water quality time step. -------------------------------------------------------------------------------- -EPANET.C A problem with the system not recognizing that water quality -QUALITY.C reactions could begin after some initial period of time when -VARS.H the Toolkit was used to modify reaction rate coefficients was - fixed. -------------------------------------------------------------------------------- -INPFILE.C A problem with extraneous lines being written to the [REPORT] - section of an EPANET input file created with the ENsaveinpfile - function was fixed. Also the number of decimal places for some - items written to the saved file, such as nodal demands, was - increased. -------------------------------------------------------------------------------- -TYPES.H The code version was changed to 20012 and INT4 was explicitly - defined as an "int" data type. -=============================================================================== From ca2bc04cba803f8ddf1a909bfa88d2573f202c8c Mon Sep 17 00:00:00 2001 From: Sam Hatchett Date: Thu, 24 Jan 2013 09:10:23 -0500 Subject: [PATCH 05/49] resurrecting xcodeproj, fix gitignore --- .gitignore | 71 ++- .../epanet/epanet.xcodeproj/project.pbxproj | 424 ++++++++++++++++++ .../contents.xcworkspacedata | 7 + 3 files changed, 494 insertions(+), 8 deletions(-) create mode 100644 build/Xcode/epanet/epanet.xcodeproj/project.pbxproj create mode 100644 build/Xcode/epanet/epanet.xcodeproj/project.xcworkspace/contents.xcworkspacedata diff --git a/.gitignore b/.gitignore index 98018e6..d70f877 100644 --- a/.gitignore +++ b/.gitignore @@ -14,19 +14,74 @@ # Doxygen output doxygen_out/ -# Mac Stuff +# mac .DS_Store -*.swp -*~.nib -*.build/ -DerivedData/ -Debug/ -*.xcodeproj/ -!*.xcodeproj/project.pbxproj +##### +# Xcode private settings (window sizes, bookmarks, breakpoints, custom executables, smart groups) +# +# This is complicated: +# +# SOMETIMES you need to put this file in version control. +# Apple designed it poorly - if you use "custom executables", they are +# saved in this file. +# 99% of projects do NOT use those, so they do NOT want to version control this file. +# ..but if you're in the 1%, comment out the line "*.pbxuser" +*.pbxuser *.mode1v3 *.mode2v3 +*.perspectivev3 +# NB: also, whitelist the default ones, some projects need to use these +!default.pbxuser +!default.mode1v3 +!default.mode2v3 +!default.perspectivev3 + + +#### +# Xcode 4 - semi-personal settings, often included in workspaces +# +# You can safely ignore the xcuserdata files - but do NOT ignore the files next to them +# + +xcuserdata + +#### +# XCode 4 workspaces - more detailed +# +# Workspaces are important! They are a core feature of Xcode - don't exclude them :) +# +# Workspace layout is quite spammy. For reference: +# +# (root)/ +# (project-name).xcodeproj/ +# project.pbxproj +# project.xcworkspace/ +# contents.xcworkspacedata +# xcuserdata/ +# (your name).xcuserdatad/ +# WorkspaceSettings.xcsettings +# xcuserdata/ +# (your name).xcuserdatad/ +# xcschemes/ +# (project-name).xcscheme +# +# +# +# Xcode 4 workspaces - SHARED +# +# This is UNDOCUMENTED (google: "developer.apple.com xcshareddata" - 0 results +# But if you're going to kill personal workspaces, at least keep the shared ones... +# +# +!xcshareddata + +#### +# XCode 4 build-schemes +# +# PRIVATE ones are stored inside xcuserdata +!xcschemes # Visual Studio 2012 *.sdf diff --git a/build/Xcode/epanet/epanet.xcodeproj/project.pbxproj b/build/Xcode/epanet/epanet.xcodeproj/project.pbxproj new file mode 100644 index 0000000..59a4a81 --- /dev/null +++ b/build/Xcode/epanet/epanet.xcodeproj/project.pbxproj @@ -0,0 +1,424 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 22322F851068369500641384 /* enumstxt.h in Headers */ = {isa = PBXBuildFile; fileRef = 22322F701068369500641384 /* enumstxt.h */; }; + 22322F861068369500641384 /* epanet.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F711068369500641384 /* epanet.c */; }; + 22322F871068369500641384 /* funcs.h in Headers */ = {isa = PBXBuildFile; fileRef = 22322F721068369500641384 /* funcs.h */; }; + 22322F881068369500641384 /* hash.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F731068369500641384 /* hash.c */; }; + 22322F891068369500641384 /* hash.h in Headers */ = {isa = PBXBuildFile; fileRef = 22322F741068369500641384 /* hash.h */; }; + 22322F8A1068369500641384 /* hydraul.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F751068369500641384 /* hydraul.c */; }; + 22322F8B1068369500641384 /* inpfile.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F761068369500641384 /* inpfile.c */; }; + 22322F8C1068369500641384 /* input1.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F771068369500641384 /* input1.c */; }; + 22322F8D1068369500641384 /* input2.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F781068369500641384 /* input2.c */; }; + 22322F8E1068369500641384 /* input3.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F791068369500641384 /* input3.c */; }; + 22322F8F1068369500641384 /* mempool.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F7A1068369500641384 /* mempool.c */; }; + 22322F901068369500641384 /* mempool.h in Headers */ = {isa = PBXBuildFile; fileRef = 22322F7B1068369500641384 /* mempool.h */; }; + 22322F911068369500641384 /* output.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F7C1068369500641384 /* output.c */; }; + 22322F921068369500641384 /* quality.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F7D1068369500641384 /* quality.c */; }; + 22322F931068369500641384 /* report.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F7E1068369500641384 /* report.c */; }; + 22322F941068369500641384 /* rules.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F7F1068369500641384 /* rules.c */; }; + 22322F951068369500641384 /* smatrix.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F801068369500641384 /* smatrix.c */; }; + 22322F961068369500641384 /* text.h in Headers */ = {isa = PBXBuildFile; fileRef = 22322F811068369500641384 /* text.h */; }; + 22322F971068369500641384 /* toolkit.h in Headers */ = {isa = PBXBuildFile; fileRef = 22322F821068369500641384 /* toolkit.h */; }; + 22322F981068369500641384 /* types.h in Headers */ = {isa = PBXBuildFile; fileRef = 22322F831068369500641384 /* types.h */; }; + 22322F991068369500641384 /* vars.h in Headers */ = {isa = PBXBuildFile; fileRef = 22322F841068369500641384 /* vars.h */; }; + 22322F9A1068369500641384 /* epanet.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F711068369500641384 /* epanet.c */; }; + 22322F9B1068369500641384 /* hash.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F731068369500641384 /* hash.c */; }; + 22322F9C1068369500641384 /* hydraul.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F751068369500641384 /* hydraul.c */; }; + 22322F9D1068369500641384 /* inpfile.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F761068369500641384 /* inpfile.c */; }; + 22322F9E1068369500641384 /* input1.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F771068369500641384 /* input1.c */; }; + 22322F9F1068369500641384 /* input2.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F781068369500641384 /* input2.c */; }; + 22322FA01068369500641384 /* input3.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F791068369500641384 /* input3.c */; }; + 22322FA11068369500641384 /* mempool.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F7A1068369500641384 /* mempool.c */; }; + 22322FA21068369500641384 /* output.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F7C1068369500641384 /* output.c */; }; + 22322FA31068369500641384 /* quality.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F7D1068369500641384 /* quality.c */; }; + 22322FA41068369500641384 /* report.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F7E1068369500641384 /* report.c */; }; + 22322FA51068369500641384 /* rules.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F7F1068369500641384 /* rules.c */; }; + 22322FA61068369500641384 /* smatrix.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F801068369500641384 /* smatrix.c */; }; + 22322FAA106836BC00641384 /* epanet2.h in Headers */ = {isa = PBXBuildFile; fileRef = 22322FA9106836B000641384 /* epanet2.h */; }; + 22322FAE106836D900641384 /* malloc.h in Headers */ = {isa = PBXBuildFile; fileRef = 22322FAD106836D900641384 /* malloc.h */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 22322FAF1068370B00641384 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = D2AAC0620554660B00DB518D; + remoteInfo = epanet; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 22322F66106833BB00641384 /* runepanet */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = runepanet; sourceTree = BUILT_PRODUCTS_DIR; }; + 22322F701068369500641384 /* enumstxt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = enumstxt.h; path = ../../../src/enumstxt.h; sourceTree = SOURCE_ROOT; }; + 22322F711068369500641384 /* epanet.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = epanet.c; path = ../../../src/epanet.c; sourceTree = SOURCE_ROOT; }; + 22322F721068369500641384 /* funcs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = funcs.h; path = ../../../src/funcs.h; sourceTree = SOURCE_ROOT; }; + 22322F731068369500641384 /* hash.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = hash.c; path = ../../../src/hash.c; sourceTree = SOURCE_ROOT; }; + 22322F741068369500641384 /* hash.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = hash.h; path = ../../../src/hash.h; sourceTree = SOURCE_ROOT; }; + 22322F751068369500641384 /* hydraul.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = hydraul.c; path = ../../../src/hydraul.c; sourceTree = SOURCE_ROOT; }; + 22322F761068369500641384 /* inpfile.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = inpfile.c; path = ../../../src/inpfile.c; sourceTree = SOURCE_ROOT; }; + 22322F771068369500641384 /* input1.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = input1.c; path = ../../../src/input1.c; sourceTree = SOURCE_ROOT; }; + 22322F781068369500641384 /* input2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = input2.c; path = ../../../src/input2.c; sourceTree = SOURCE_ROOT; }; + 22322F791068369500641384 /* input3.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = input3.c; path = ../../../src/input3.c; sourceTree = SOURCE_ROOT; }; + 22322F7A1068369500641384 /* mempool.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = mempool.c; path = ../../../src/mempool.c; sourceTree = SOURCE_ROOT; }; + 22322F7B1068369500641384 /* mempool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = mempool.h; path = ../../../src/mempool.h; sourceTree = SOURCE_ROOT; }; + 22322F7C1068369500641384 /* output.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = output.c; path = ../../../src/output.c; sourceTree = SOURCE_ROOT; }; + 22322F7D1068369500641384 /* quality.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = quality.c; path = ../../../src/quality.c; sourceTree = SOURCE_ROOT; }; + 22322F7E1068369500641384 /* report.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = report.c; path = ../../../src/report.c; sourceTree = SOURCE_ROOT; }; + 22322F7F1068369500641384 /* rules.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = rules.c; path = ../../../src/rules.c; sourceTree = SOURCE_ROOT; }; + 22322F801068369500641384 /* smatrix.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = smatrix.c; path = ../../../src/smatrix.c; sourceTree = SOURCE_ROOT; }; + 22322F811068369500641384 /* text.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = text.h; path = ../../../src/text.h; sourceTree = SOURCE_ROOT; }; + 22322F821068369500641384 /* toolkit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = toolkit.h; path = ../../../src/toolkit.h; sourceTree = SOURCE_ROOT; }; + 22322F831068369500641384 /* types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = types.h; path = ../../../src/types.h; sourceTree = SOURCE_ROOT; }; + 22322F841068369500641384 /* vars.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = vars.h; path = ../../../src/vars.h; sourceTree = SOURCE_ROOT; }; + 22322FA9106836B000641384 /* epanet2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = epanet2.h; path = ../../../include/epanet2.h; sourceTree = SOURCE_ROOT; }; + 22322FAD106836D900641384 /* malloc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = malloc.h; path = macinclude/malloc.h; sourceTree = ""; }; + D2AAC0630554660B00DB518D /* libepanet.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libepanet.dylib; sourceTree = BUILT_PRODUCTS_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 22322F64106833BB00641384 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D289988505E68E00004EDB86 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 08FB7794FE84155DC02AAC07 /* epanet */ = { + isa = PBXGroup; + children = ( + 22322FA8106836A000641384 /* Include */, + 08FB7795FE84155DC02AAC07 /* Source */, + 1AB674ADFE9D54B511CA2CBB /* Products */, + ); + name = epanet; + sourceTree = ""; + }; + 08FB7795FE84155DC02AAC07 /* Source */ = { + isa = PBXGroup; + children = ( + 22322F701068369500641384 /* enumstxt.h */, + 22322F711068369500641384 /* epanet.c */, + 22322F721068369500641384 /* funcs.h */, + 22322F731068369500641384 /* hash.c */, + 22322F741068369500641384 /* hash.h */, + 22322F751068369500641384 /* hydraul.c */, + 22322F761068369500641384 /* inpfile.c */, + 22322F771068369500641384 /* input1.c */, + 22322F781068369500641384 /* input2.c */, + 22322F791068369500641384 /* input3.c */, + 22322F7A1068369500641384 /* mempool.c */, + 22322F7B1068369500641384 /* mempool.h */, + 22322F7C1068369500641384 /* output.c */, + 22322F7D1068369500641384 /* quality.c */, + 22322F7E1068369500641384 /* report.c */, + 22322F7F1068369500641384 /* rules.c */, + 22322F801068369500641384 /* smatrix.c */, + 22322F811068369500641384 /* text.h */, + 22322F821068369500641384 /* toolkit.h */, + 22322F831068369500641384 /* types.h */, + 22322F841068369500641384 /* vars.h */, + ); + name = Source; + sourceTree = ""; + }; + 1AB674ADFE9D54B511CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + D2AAC0630554660B00DB518D /* libepanet.dylib */, + 22322F66106833BB00641384 /* runepanet */, + ); + name = Products; + sourceTree = ""; + }; + 22322FA8106836A000641384 /* Include */ = { + isa = PBXGroup; + children = ( + 22322FAD106836D900641384 /* malloc.h */, + 22322FA9106836B000641384 /* epanet2.h */, + ); + name = Include; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + D2AAC0600554660B00DB518D /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 22322FAA106836BC00641384 /* epanet2.h in Headers */, + 22322F851068369500641384 /* enumstxt.h in Headers */, + 22322F871068369500641384 /* funcs.h in Headers */, + 22322F891068369500641384 /* hash.h in Headers */, + 22322F901068369500641384 /* mempool.h in Headers */, + 22322F961068369500641384 /* text.h in Headers */, + 22322F971068369500641384 /* toolkit.h in Headers */, + 22322F981068369500641384 /* types.h in Headers */, + 22322F991068369500641384 /* vars.h in Headers */, + 22322FAE106836D900641384 /* malloc.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 22322F65106833BB00641384 /* runepanet */ = { + isa = PBXNativeTarget; + buildConfigurationList = 22322F6A106833E600641384 /* Build configuration list for PBXNativeTarget "runepanet" */; + buildPhases = ( + 22322F63106833BB00641384 /* Sources */, + 22322F64106833BB00641384 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 22322FB01068370B00641384 /* PBXTargetDependency */, + ); + name = runepanet; + productName = runepanet; + productReference = 22322F66106833BB00641384 /* runepanet */; + productType = "com.apple.product-type.tool"; + }; + D2AAC0620554660B00DB518D /* epanet */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1DEB914A08733D8E0010E9CD /* Build configuration list for PBXNativeTarget "epanet" */; + buildPhases = ( + D2AAC0600554660B00DB518D /* Headers */, + D2AAC0610554660B00DB518D /* Sources */, + D289988505E68E00004EDB86 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = epanet; + productName = epanet; + productReference = D2AAC0630554660B00DB518D /* libepanet.dylib */; + productType = "com.apple.product-type.library.dynamic"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 08FB7793FE84155DC02AAC07 /* Project object */ = { + isa = PBXProject; + buildConfigurationList = 1DEB914E08733D8E0010E9CD /* Build configuration list for PBXProject "epanet" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + ); + mainGroup = 08FB7794FE84155DC02AAC07 /* epanet */; + projectDirPath = ""; + projectRoot = ../../..; + targets = ( + D2AAC0620554660B00DB518D /* epanet */, + 22322F65106833BB00641384 /* runepanet */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXSourcesBuildPhase section */ + 22322F63106833BB00641384 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 22322F9A1068369500641384 /* epanet.c in Sources */, + 22322F9B1068369500641384 /* hash.c in Sources */, + 22322F9C1068369500641384 /* hydraul.c in Sources */, + 22322F9D1068369500641384 /* inpfile.c in Sources */, + 22322F9E1068369500641384 /* input1.c in Sources */, + 22322F9F1068369500641384 /* input2.c in Sources */, + 22322FA01068369500641384 /* input3.c in Sources */, + 22322FA11068369500641384 /* mempool.c in Sources */, + 22322FA21068369500641384 /* output.c in Sources */, + 22322FA31068369500641384 /* quality.c in Sources */, + 22322FA41068369500641384 /* report.c in Sources */, + 22322FA51068369500641384 /* rules.c in Sources */, + 22322FA61068369500641384 /* smatrix.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D2AAC0610554660B00DB518D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 22322F861068369500641384 /* epanet.c in Sources */, + 22322F881068369500641384 /* hash.c in Sources */, + 22322F8A1068369500641384 /* hydraul.c in Sources */, + 22322F8B1068369500641384 /* inpfile.c in Sources */, + 22322F8C1068369500641384 /* input1.c in Sources */, + 22322F8D1068369500641384 /* input2.c in Sources */, + 22322F8E1068369500641384 /* input3.c in Sources */, + 22322F8F1068369500641384 /* mempool.c in Sources */, + 22322F911068369500641384 /* output.c in Sources */, + 22322F921068369500641384 /* quality.c in Sources */, + 22322F931068369500641384 /* report.c in Sources */, + 22322F941068369500641384 /* rules.c in Sources */, + 22322F951068369500641384 /* smatrix.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 22322FB01068370B00641384 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = D2AAC0620554660B00DB518D /* epanet */; + targetProxy = 22322FAF1068370B00641384 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + 1DEB914B08733D8E0010E9CD /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = NO; + EXECUTABLE_PREFIX = lib; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_MODEL_TUNING = G5; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + INSTALL_PATH = /usr/local/lib; + PRODUCT_NAME = epanet; + SDKROOT = ""; + }; + name = Debug; + }; + 1DEB914C08733D8E0010E9CD /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + EXECUTABLE_PREFIX = lib; + GCC_MODEL_TUNING = G5; + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + INSTALL_PATH = /usr/local/lib; + PRODUCT_NAME = epanet; + SDKROOT = ""; + }; + name = Release; + }; + 1DEB914F08733D8E0010E9CD /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = macinclude; + ONLY_ACTIVE_ARCH = YES; + PREBINDING = NO; + SDKROOT = macosx10.6; + }; + name = Debug; + }; + 1DEB915008733D8E0010E9CD /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = macinclude; + PREBINDING = NO; + SDKROOT = macosx10.6; + }; + name = Release; + }; + 22322F68106833BC00641384 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_MODEL_TUNING = G5; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = CLE; + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + INFOPLIST_PREPROCESSOR_DEFINITIONS = ""; + INSTALL_PATH = /usr/local/bin; + PREBINDING = NO; + PRODUCT_NAME = runepanet; + }; + name = Debug; + }; + 22322F69106833BC00641384 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_MODEL_TUNING = G5; + GCC_PREPROCESSOR_DEFINITIONS = CLE; + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + INFOPLIST_PREPROCESSOR_DEFINITIONS = ""; + INSTALL_PATH = /usr/local/bin; + PREBINDING = NO; + PRODUCT_NAME = runepanet; + ZERO_LINK = NO; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1DEB914A08733D8E0010E9CD /* Build configuration list for PBXNativeTarget "epanet" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1DEB914B08733D8E0010E9CD /* Debug */, + 1DEB914C08733D8E0010E9CD /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 1DEB914E08733D8E0010E9CD /* Build configuration list for PBXProject "epanet" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1DEB914F08733D8E0010E9CD /* Debug */, + 1DEB915008733D8E0010E9CD /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 22322F6A106833E600641384 /* Build configuration list for PBXNativeTarget "runepanet" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 22322F68106833BC00641384 /* Debug */, + 22322F69106833BC00641384 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 08FB7793FE84155DC02AAC07 /* Project object */; +} diff --git a/build/Xcode/epanet/epanet.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/build/Xcode/epanet/epanet.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..052c6dc --- /dev/null +++ b/build/Xcode/epanet/epanet.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + From 719114cb2e4b7ef24a0efda11f51006f2bf3b6ca Mon Sep 17 00:00:00 2001 From: JinduanChen Date: Mon, 28 Jan 2013 15:14:10 -0500 Subject: [PATCH 06/49] Compile LemonTiger as a Win32 DLL. Use "LemonTiger.h" to access its functions. Added one new function - ENrunnextHQ(). --- .gitignore | 1 + Debug/LemonTigerJ.dll | Bin 0 -> 282112 bytes Debug/LemonTigerJ.lastbuildstate | 2 + Debug/LemonTigerJ.lib | Bin 0 -> 13646 bytes Debug/LemonTigerJ.log | 27 ++++ LemonTigerJ.v11.suo | Bin 65536 -> 72704 bytes LemonTigerJ.vcxproj | 3 +- include/epanet2.h | 251 ------------------------------- src/lemontiger.c | 221 ++++++++++++++++----------- src/lemontiger.h | 236 ++++++++++++++++++++++++++++- src/testLT.c | 8 +- src/toolkit.h | 38 ++--- 12 files changed, 419 insertions(+), 368 deletions(-) create mode 100644 Debug/LemonTigerJ.dll create mode 100644 Debug/LemonTigerJ.lastbuildstate create mode 100644 Debug/LemonTigerJ.lib create mode 100644 Debug/LemonTigerJ.log delete mode 100755 include/epanet2.h diff --git a/.gitignore b/.gitignore index d70f877..2167a2a 100644 --- a/.gitignore +++ b/.gitignore @@ -84,6 +84,7 @@ xcuserdata !xcschemes # Visual Studio 2012 +*.suo *.sdf *.filters *.user diff --git a/Debug/LemonTigerJ.dll b/Debug/LemonTigerJ.dll new file mode 100644 index 0000000000000000000000000000000000000000..e15dedf44d1b4441c01cb92089d9759419140ddd GIT binary patch literal 282112 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

M)i^{QN3E!qVFa;flYcsyo8UQ%TDhB|4JZQ@J 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�>9WXz@C34;kKNR{l1?dKM&;lgZ62E^ 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

Q?jVIQYay;P3XDorVbZBhvVa*)ct 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 O0TR6)|6BSxfH*aU0c?`hRzX}dFBxX zjSrn(Qd!l&s18gjvyHGNg_X!S#`nCfCdevjh&CSM4YZv!Qk!Js*udR`^h#GWo~4XF zR&kZDONUv3HTC7mGDWaql+Of9V$3EsJJGekx(SBF&YwOvvfknwpFI)p4?*dQ(kYc4 zV@lbfbV`~W0D#?v2oag&{3{-ppQ+zRVFW+YC%-4JjC>NRsMfx9OT+#7@ zZHjxPL^)E7A4ygu*pS$ziCl=Xk#?eUlF&?6(_PtQN5+_ZiI|0W8_hOhdwO!A#My}}-6(6fQhdq_WKbvwA|7?G=^iWF9+V}mJ+HYEVsO)=W z$H`NrTrrhm`d!A~S?~w3_iNb$VbZ1Si+Xx4_=3n6JEe*mQ+Z-Tam7oBoDijp+2x{s z zmTV#w+P?!-=$+2gfbu?v-*xYZ*61g69igF<+L!A6KKjJG!>V1tm+<&u~mTD~{&@ux5 zKOTX+{M3A3+Q5nHl_%2{1<$S>c-6^$Q=)qf=+U(}mW7O5}JTRwkp z1dfdQ-~H>`NS}moq6pfuu8p$!(KgDa$J!{lyy*Dlo?w|A{k?eeAICSKz06h($95d^ z$-jqlljC*Jb6i^s-NJj+UV(DNHS(Y3{05F+0Du_KSja=0TgiWd<0z;BvZ#9*Wk2J3 zYtnCX{1&R@`gIX=niNN^c?gW^a1oGv>!TRLmQ5Fj2`^P^kgK*zJM5Puc)4mv zaMUA}&fx7`m2Sjj^iX;#y}+{iC`TzrD}9xI$}!5ZN`K`z<#^=;5Wo|$c?K$jz{gKg z27?C{W(4b}m*5%;R+rS2MbfyQ>O-}nSu#s;z12rfBV`)z zLvB!bB_g@yRkgDlz*@tRB%ZFBmC**}c}-bxPGeRLK9_`&0`qOmoF$OANK%xGH6za( zn-R&zdLorruc129-RMn(w+HlBK2r1vV$H^qjV(v7;Hqd+A)$HURcgFPT`HwsGX%!rv(7Lmb5uADcnjK)Ml&4e){Ki+fB#rQRZ6R#u=VYs#`+G}wlAA{!+M_~TOr0A1H9KNMg%Lx468G+85+H~&=4T4UIh7gFJGajVV&nDNq27%`H-Hr~DRZ2lN@V2igbq zex^-#2Q&$q21zl3!!sy+al(sVBV6lc>@hf+ts+=b#+v|x)vzOCG6;2ulvkA4QF1dn zQbK^lEP5u=w&?_41m~0ngJogD1?E&%H&ok%C^Q4%N=c}6?ud!O z%JB4((h4xnir`suM`SYukw$k@XAiU&+6Ntg+CJN+dk3g9)Env#m6nH<8Fkf4^^7tl zQ~cpmGNOExILR6nREu4knxqsmI8!zd*?LrKX_RaQ`MC3HKKWGfHVR)Ikjv^$Wt%f*+u!wuePM##o=OyP*8(p0?_dy4swwojN6q1;BC&_*%wky{%GL_XX z8>PCUrHs$c<(QtCK3=4=qR0NUH5y8VX475{xrekB5svZ3PEE^K(hIY)L_3oUG7H4X z?31S}S+ubg+79i6c0+ri{gCoJ>l5k@^@T=5Wl$9~2U-BFgjPdqp!LuuXbZFz+79i5 z4nS>RV4Xv~A=!sh3Ug9KU-HuO#aK-)NX{82j=7oQ`YPrPl}8j$plW$ zO)il4NGXI9M#g9Igu-MoR+IA!l0{w!4@7cJN!8r240D*#P$QyD$j=*JI943fa?(V9 zc&=pmd`xy`B%LcJk+GMHaq{@w0(m`U{CH75-ewT3vMkyr>rnP5D|w83<}t}Ba*PU+ z$BGTXz2x3alm}c^`ZLChpv$0Zp_R~TXbrR;+5~NdwnICi-OxU$|38o~Pytj7RY5mG zw?k{8!^)awGNh;km5V;4L^Z-ZB6UQcQl+_IBjm}JgW|2^%YZL@*VUE63Q=;S#z;y7 zK{J#WYjZ**66?^lO+a4aMj^%nZIHRGO;YDy*V-G}qsbMQ34oTcQX@p%B$MMpH z2+L9^w{^^Itq7 zE3-rV!}C^Q@I)Upc3H5tLq4<{nJ@hOQfkBN6J%y=Ub2EUGwP8*sfa*f*@^z7M?|wy z6eLuQFgkHfv?0QB#Cfc)m@_fY`N4WIK~3f$eMCAFf|#9b)u29^X+{re(LTGRCR>C&fd`JXiM=X#-`=WZ{?GbKVGb3md zxPwh%H-ZDwCML_jZ%1qXOiib&UhpCzQxcy{Q8J}^DC2rvrgSq@7R@HZ9pFG5*1F z0Gu-UC}O()O&dJVpSK}!tH03(TjtN(h%N^Stp1I**cOqtg!Y34DxWF}rrAntDMkOj z4F~Js&-)XJtEZK}99su$?a$kY_Ge_%wc+HxO&U#@-x_ALlHFY!sxGM?sicd27Fo8s z$}~pJb!qY>m?`pEo2)-4{rWfeXxw@-D8K2w1h*~|Up!!8Ml7MYt=6PZEYZY1C2pW5 zd6GKoT&5X_E{^h-ZnamkI4@1njB| zlb|*VE=LDP*mr^iCMYq!v?)p_E_CWNS)gqNnd5Wvr%<+&Eop>qM<=suBOT?WJ4qBS zuV{Q`o+!{PJDR4P)DdKPf!4{knv{*U_*VzfRe5*OkH+={>er;bNCy+T8SgFiWxpFQ zG*1iP23T*t09hmVVEDxSI!RRVPwvBW+j7TGOv|$+$x#vMjI`v`XkF3Q#QVllapO@P zsWx_ry0%=<#I(E|n{2>l%g;?qqp@h)(RmT*rhM?&I3DJ?oucneXY9~1NEl0jjOL{B zl(9DLj*%{=S@bC~4vph3P*DNei)E3pE+Q2eFM)a%irn~`p)>LG5s`<9r$t`0qp|Uh zj6sw3=~rao(Y`=h<@3keNE~C)C(4Y^Daae26=}nkm6@hihLfj!w2{{$bjW9j;h!7`SL(Gfqv-OD@c!qr!ENUyzpDm=|5D2|0~>F*lZnJWRS1>*c*DYh;v@bFbk8{en^t`kQP4Xgb;<=UC30d*`r6y-H9Pqw`%;^0D z4;PzE@}gV@IY0BX#9K$ElzxddUfBG3qWe3)FgrUrugT-Y*1t_S6UR2qisuOt*Q`mz zp75}DlH#v<9&$sjfy329pFo^;lESoky;z$<@HWqjwRyO_Ser>BG&P)?$7JUVfxs#k za+Pb+O^-q(#7FF!blEq%CfwWdJLiJ+r!v;Ij`7zTkkj&M8G(O40x1>2Y5@a^lGQUt ziLF4yY%{D{1F)-%f|tNM!O$oi6~T}VziF^4ES=XP#)>T{aVkP!__lR~X6BYe&bd%M zDy)pMtE$TROahh4vBw0}g)8N;vW9eBv z4scms%Znvu3+JW?c@%FqnVb}!Vhe+MVMjKCx4f8#II9|>vv{8heh{E`lMXa#Pm8#K z1oUMq6%Kn_qellwOu%NbF=|>5fHF3|36-VW@qcF>9gtZ>8PEy&YMq)U@Ltnr(ZR80 z(19o{-e*%Itm;w#RQWoIIU}TZLQZ&-XZbJGi_OUZ*p?VeLHTJZBECq$5K&T-PgRn$ z@v%cq?jgWaP|^C5IT81c@YVeFJc_29wek1;FHP_L_xvqQ>-;_cO4B<3HGfLex~xN~ z8UbA&>JySHQ*6|xb^e~urD+|2a_$qZ3zk-vOTQ(nywUj-U22jiG_40<9&>h4U#=v{ zMH*`~DKA`|e{r8I98}~VdLO%RbVQwMP43fJqv?HE6ZjZ;;gWCxB5qY_PlM3MAL@{C zv$Gyz_lU%BN1ul^naD|4flcofpI_luO^BV#Og;1-|C{-gJ+eOJ`>OtI@)DR;(|#xL zD#lc{(Tq_wEzew2j{nh75&^C;uR`SgS;CKc$TJI9@L$)%Yf^y_V)e|5_>7v|SBvj& z!Mwsm;@EI>;5rsDBLtJlDQf&Lqeujaqd;QB{bKRr0)Y|fXb7Vs ztsT+=5fay96_%37 z7Y2d24jPi5n2v^C#`A@x6UmRn9gD{lmP+$$5+UHCXj8P^e2j(hBI=}P%Ft8Uzr;2~ zo#rva&0~QD!XxSkR6!i0VWmnmoK?mei|es5iOs!0PQ-O#Xo_R=>#=-+j)?qNY`2K# zPK@u4#dgQyxkZdO;oAz&CdW|3awo=c$HpWv{yo-r;1ET?9^!tn=ZIK|-2X6f-7$Su zOs~*qvy*cbLR;mW3q(Y;6G2F*4;muUv2n;x8!P8rpatT3G>lgfYfGf1#m`Y74I&-4 z);Sl*gt!)~D^Uf~0znYhGpH<%6Qakw=t&$YATNdth;q&EEw24f`^Xr&iF`9kSPId| zhNyF&7%yR`6KDMw`NH?~@58TiBfx3aXxJ6JcT~I{fhzt}j&a=r7 z3Zf{Re-NvYvN@6W=wb52BBjHJmIYlB?KYOpiw8S3D=d+rrey^O4BMKO6UoDr6#LP!_(kHjqpzz>4-v%|tZ7y!-uLY2SAPn44=AQM=6vZ);=U656fc{~ zTS3M0&Ej>P^}Jw}h>D8ZswRa+-{bvg)^=i>vGaJ_vH06~%xtVg;}O#{@|{BQjDM$m zY@Pm{vVEW-Al`}4z#-VMy@|u89wIg)P^lZsbCA z>?jkj8_Tef7l|Pl6OESQJ+~rC6(}A1Pi&-UeqlVG>W~t)Au`e_8t&>759}%*8m%Yz z9uF@-7XA`v9%l)W`^I@_ybxWA)}?~{-!vV$Pc$-^e1wi%P~uqxB?%v@Ey*Q0Pvoyh zo;Uw1%IcJjPI?Mx)(l>jnk34_@*)$QQX8)46~eR{&5PW}9`U=|)sb3I_HpDeD%!|w zmM`az=RIsWQC3hRZ;Ws~0o2%rU?3uB8-is+Nz(SHYMtY#Y@%a1M!uh7D-0to4_BVy zkvxD=7GEfk*pGOQ=ttJ$JbBiPk@C{G*&`}Kk<9otTW+vqX5^X}2Su90G9CF2hAmCR zx<~4BzvyS&?B-`N{8H#)X?YR@@$XDv6!WY|pV%J6D4h~b6_Ys#? z#De!3x7ZeKvae$;5#&h`{)?q9-Vwnk@=VdoGK@a*mShAGZ}9%NI2S+lgXK;>L+3;`z}y(8j3NCdH!T6)gn1)ENF1d7hdG)ZKVLxuLjOVqj}y zla1w)7>=??Aejiq7qaNz)`@nbNz<`!e4}B@J;LNf*NuFMJ3X1s*TH5tN(aH~>O>o!0=bLGYg^TaP#4z+GUw%2fV@Et~ z(|dx!#}WDnc7Irp&>{7})f?+o2{*#us|N-i{bq{b@=?|dil0*SXALyzuZCZux-vYX zt_q_CS7DWWFT|hSns@m}zAJ2_|MGj@`EmcG^qGn4L)!4}XvhH>kOieeSrFNAJS`J6 zh$u)fPcWj42xgm>CBJG8=9MY2v}M#;0o@4Q4&4W>g*HN)p;w@{pdHX|XfGu05yPHh zI4=P#sR9hkN-IhefKm)o6YnSx6m*|!z6cP(@yv=X`< zS`FO?t%24;8zFHoA7t@MM;0f3Nc{K>NhLF1v|n%tj=G(CJE7gs-e?<>_)z5#>|2CJ z3WPC+kBTz?FMV=$jeg>xeosq3farIt!w|3BlkWihf9bhe`ucxo1h%Vf<2OFX*;d)C zwNY)m#7#a9Wr}jAXsf;!wB?S-8P_fs zXQdS(MY&p@h3jgRgYEcH83F&b=U9nU7Dq6NUhT`vs~W<*%VbgOsRYDT2VD-{#oBIa z^fWuaC?(HsS5rrdw`WdiH8mx#U}|1L%2eJERe+9n6*G}iS2wA&t{!g`5UVn#^;F&q zHe;&z0UJemzRlFgKus;1K112oda4*cc^;;%P(5!!ksgf{`R+`2o2lZB4>VJ)7>(ys zgUWn*$4};!iC;$G7ZIjb)QV?*g}ZaPum&uptSVTR#_Q4|Z?Akgl2brSd{?a4s z74OG+q|H=jZKiT!yQvK|@@%^7N9yz$5dfQKn#8^2jLLq#MoT<<a`bx>YwKf5%{5}3*? zuWvVXc6G^2UW8d+A=2-W4g=GRw?v8yR;x7P_{xI0ksq^Dj&7A2OiV9qlNpvj8NtAa zx7F~yZzZE`UP)z`-{gr6h;l~jvBCN*en3ioA6-$_iL@A&=x=E8R^2vPwIyX)mD71k zUE~LT`nRu&EZSt=yPKHHDD7z@-3epn)&~n}C-QA`0W>Qgw2Pe<)W-9b#q=;b1GS;_ zATKQnF(Z+lT5aV|2;~Mt@>}z`R^(b>B@GfiBtlXAPG7WkW|=Z1;i~X(m6UN&*(a_> z5E|juNe&C&s5nzbwo0uG3wSG1IQn=gOfdfVHh2c>lI2F8AkWj~?tVNrHY^!Y0CwGthIGea{4zWm#(0PqlGvxZ@+Bm)!mzJe#ay$K>6o)Ns zw~WC5z!7N0`=NO^mZB_Z`f%bM(+cl`KJwvSW?6HSS{!3pCVTv(7k!Wb+9Eo;h3gi!Pio*N7g4*0utvP#0?VD)sOKWU&Q z>>Jz=sxiYjO!(c>5qt%KpMk9{uLr`fHcP_QBWKwMi*WnO@?f|=`o^rt-Dt{Yv+6?) z;rdL3YP7Wh|E4v4fUHMN0{a{AK+lb)xgrBBc;QA_ZU_%Kuiy!W+J5JlsR*IEvO|(j^nO1{!uC>Iv(z?mI%X-Lq!g}8N zr}eJ&sr8NZi`B|^q_2FMF==gIO+_ssM(coums z_FUoF?)l2I&(p!|W}aXUHPg%j^Hg)HS!2#N=b7i5mz&p{x0rXBYt6^a*UTTxw%*>} zle~sE(_82*^EP-Fd9U`~;eFKmg7l39 z)o1xKdlC`{R{jT z_?P;x_pkJ?_P^)<*uU4`D{xF;XuuT+1aboTfl~t&fttXAz=dMIPy*g!zHU|@R-aKn z;O8NF*#q_}`y6|LR-v7zb<~IIi}a=XRm{bG`a}A2`WF2?{UiN*{b#*{ql@DN#~_Ex z;dNv?@*HK3O2^rb1&%8m*EsHWJmA>mc;4}@<3q=%j@^!L9c`T*on4*1oc)}moDQdl z8BBGa=A7y*b5=TQofkMSc3$dS;k@3t#<|Yn+$Xq)yGOfI z-5KsIcdom@J;`0{p5`udSGcR(b?$m*f1Z1Rdy#vwdzt$(_X_v5?i<}J-M70}yYF+a zaj$i+cW-oWa^G*fVeBvpJr{XSGDnyW(`$|~GtFFcB6HnfzGS{*db}ClN!|;*S9(`@ zw|S4Sx?2OSp_ZK)O|kN=)2%YA-a5y+z`Dx1#kz;x_l)(jwaxkzn19?_1=1$M>yopRcXIqraQ~c>f5$=6B1zc&GnK|LgwG{lEMB2ZjV3 zfr-rLnSq7u!nfFm-v*S?ic-d$o~YKVXREiUYt)z3Z&bJa8v85u5AE%>{@Pe=f>y58 zX;*7EX%A@YwC&nn?F8MfXX$zRbiGoaub;19reCA~s<(FZa2(GJTaGNp1jj^2xuby@ zzQA#@<1)uBj$a+!ox_|N&I0E&=W=H6M&|?0kDW;_uWJl*bPY3cJiBeS`)0;-m-~SG zD0bD&#*4-~#;?W^o@~#lo(-PQJbOJSn8VF{v(CK8TxmXJZZWr+Uzx{vU5x8#-b(L$ z?+NJ6$4*&nU2fgXXg+3bwzgWktv%LWYajdNfOP_6Y5Gq0mHQfe z%X}+*xB2e%t@AzUd&Rex(cJGlzz>}a_6Pkn{&W1x*(G=RAMtPUzsyeg!oSb21O_pt z!viYgY6Psn=s;>9Baj8RD+o*q)CSHA+{HM*AK(Xnm1`N}L8@Dwpq8swGs;`kuhgH^ zZuVjJbo;sX%k4MW@3DVv|Ct|LIYt|#`Lzsfx>ltv)Rt?vGwSbX-SysjU%kI>(+BAV zdWn9nzFB{Voz>nEaGdIx={V1^gq`%h<7>yyj$Z7TZ0BTWwexJ}66a>;Hs@!~@0|l( zC%aNy1#&mcb6x9N>3YWX89ShZJJY?8^?aB6e)o&+_uXH@+1eSsj3h%h{Ki;gx>0AG zZ7emeGafNE!Q*xre;92&CwNTHSmtDgC*(QXv&!?3=Q+>oo*kY&p5Hv3&11|Y(`BZb zMP`{4fkEbY(5Rw%kfwE=lMVK4+^*g69VOdTLK#buLbr8lxh6l5cASg9jf}( znXLZ{)!Wn;)wk4LYAbs;`v|+&o@+0$&$BPGUu?h4zTW<-{S*7I_9NL9Bel_5fp&&A zPg|<3(jL=3(SFs2>S_99cEmaQGW|yVLH!^4Tl!b}0sTmJh3YUI8ID3n(6PvIwc~cj zeU6uzEy3w}JCAn`g2Uy)-Bvhnb3O_;d(Ziuv#%@3r88rbkW06_K6f1nhce($f6bqE zGj{`wfKg;zZ#-taV0>zH@Eqr{Jh`4q&r;9bo-LlwkwrbtqfICCbDDXUxdhqswE4RE ziMh{g?>)}zU?*jHbG-%dsbcRmB+v@)L*93olP|n~u%m`qF6$KQRIAQ9kGZ&qv3~>U z^NZEVcbxBJUx{y?Z>et;d*}_{N4}%{C-@!y41c*l>|g9(=YPTfp}%dQd*B52j1lm| zjp_qS1CPUtlsZLO!CbUcd#l6LboC5%u6n8Zs``ogJsQFB?2|F}40}1!=3@J0_IvFQ z*>^A(`|Uk6hjxlqi}bljyG7fey{>(v{igLmGZ>`1^kThAzd~Q7zaaNYN5|0)&Ea#5 zhc8{=xYx1KvCZ+F<6n-h$e4h0g0qy}a=mk{^HrqD9%oP2ajsFWWY-MWeAhB0$7`;4 zU7xu2x_)=HaUbnI8EH}IE=4w6#NN5z{e=4^^ny>^ZH*2_XQR8(+vscbH*CfrG=$-X zYB&tTu#C%$`;9k^kBpy;V?8H(rh3lwoX?y*;rZC}jie^igOyX|A`dG;W4aISqZvv8w*qkW70Bl`jSKrO&5OhZcC zuI=I{qmI#?dYyg&a^W>beuw@E`=GOpjhwz4nwIev4ra<*r8Xim4&hXyy!S>!B+r(NJ&>b%@}Ej#5w=L^o);cdH_t-a2D z&i&2<{7_X}R|i*TS9f;KOjp=-iR%W}gRU*Ex8=NbcMnCIo5PH~g7#)Jh8bx_nNeX> z!Q<+UTj6e>8$Hq9MtPiQaCx4fC+s=Pv)pq%9Bz&0DbGJW?|Z)Y{Nm|i_B8vNqvRgS zGp93W4d&VACFYgpb>?dGQS&YHOY;v?S*a+C6@G`!b&>lN&l#Tky-#@G@{Y2`qG``W z&YuN8yN(&W7cTak^(K3$ov)Ygc;89raHsjE`(`8Auk@{!dugX{5Avw9zc=z|6#CmZ zw6|*iLjTqN2hp*`uId)B1x6x?yn%6n!obu(B@$?T;4`7Ot%>ZdBiUOg!s|3Os4h}3 zQ*TsXSKm{=R`;pDA&L6fPePl^x1VaSwukL!+0SQ=FR@?EEZ=IsoBj5J{WJSsdy1B= z6-#~KTy2SVrFN@!FFL_y?KSj*FSPHq-?dJ9HzZY(uIcG|A-Z{)UJFOOLVsT0ub=EV z-Ep~Nv*Q^PG#>cdML_pv%4Ne1jSN+Bwu^ca3$GxN2SVTo=1;cHQTC z%Jl|Z@Ml+BcV~AWcaHmP^zrN6cQTXjy1#LEWVekm3Yg0ajGK%*jJMcj-=U4S^Yr%& zM^}Qc;EHj z&E9v>CI02@iI$db6V_O<9^+w6PbcLOy`%h5`-ncCUfKCLq&9nf?1X?le|haGnnR?s{8 zx99~rd+TiY-1X?!4?3Q6>|{UnaN3Y+u?8d?x1_F`wI8HXt&$kJKVpxI~hZbQO2o8wXxXv)@bjsc^sZ}&m>Qk=K{}7 zo<}{evOj)7{tqz6n^ool^9F31ml)4akov!yoxI(#Yihg;q@-Wx{fGBN%gJ6i&6ra0=*dM|UVX3Rfw{N(82w86mw&Mf%VCg*F;Pq02ay9T%% zE+5)h4YtWL*Hx_Vmt0$2U${DAdCYcS!peRUZR}IVyo1pXJ#2}w+IZS{nNja3SG47s z26x)%`3F2{n`f8jcTZchJN(F!7DtVFt9ie<0lB`*?C$OB9qb+DwY;Zz^Srf;{%gqc z{oa$2;bm4ey463iFTUkR{RU&v=OaVrv#PK0-GuhE1{?Bu-@Cru$dU%Q&E@`^{SW(} z_rKxa+9M3r3#@auKt>2fGJsvxMDmMNd*cNH7Y*&%13d_FUH3u%T!1a*pd3eZo zu79EPy4?ZySoe5%$W>Sz9wXT}#h8{L3sy4T8;#AztHvIrbqd_0!gH19HqU*G_}iYH zjCV(5z)&+_W@Cw5XWnH#Xg+IhH@`4#-gCXzc-NrE?(lx^J&28WqUA=9&9P=%OVL|5 zA+JBO+W7kW2Kdsj;wpR>`>w$9*ywxK_m=NNpW)B*Pr>G>_n+rqg}w2De;c~%FaAz} zq<|Bfyf|=1U`}9p;0D(AbAj#flOM#m?^Trhr2f=PJr)hht&UYI)OqSEb)C8iopy(` zH~vt2*j?yRMa;nxc>B%v2kcMSUxu$Jnx@rji?l1?=xel1@beF~J=y`d`7!ze{c`;_ zeVzWgeu85-QhSP{7KweK<2q#agO2r%mmF_8K6dP3t^dJl@8=xsRIxy^u=L8{?sL(q zu6Ewyyx+Or`Hb@=(3j8QJO`ZZTzy?Om+G=WU<$EHX0i`1bFF|2-H2^+yK6Oj;!W2F zu3fJE*y!EdebKpe_j&G1-8Z@KaX;mL-Tj$+4tB|v#wz0;<5}Y+<2~aG<7eY2&j`cZ2o{mdE#4hyC>-=(_XKxNg&D zIaWAsbG+jq4hjs##%xS*&TyXVT*f@yhJO2u$72I(r79&w4y#JcU?< zb)Nay8rPyTJ;3O{0Eha-)5`2*_CmuQ35QBECn0fbLB1|EuQl(%E_}iKCogI<t+oz5}Xji)XNMLB*~_i@L|DsI8=3dx?6zdb|3X`o7u$Jas5LKa&-8HfX~w_I2$0E%x{AyWzdZ zYs0lM+GMQ~?t1|oV72y)_M*0po*juMH&XYaU4$eTxLFwM0E4(&F4VgKF7Z8;O*m0_fGZB@YaLD zJ&JDkj`u6?FWwH8*UA8Wn~6q#3;TVGwG)Z>hh_STd}p$XZpNy5*7r6@>bLCq4*stG zWBqn?@KgOW{0*$38~p$DzwQ6T-;G`G1p_)gFf(vL;11S|Frc=u*W0Ka)uTWe($##m zOkJ#A1qSpa*6lvEwfz|T0J|R?=nVT6QZ9;_`39-jkJS>;(zHB~pbOBoS7{Gw|Ipq> z8)=VyJ6JbCf=<(CNc`;%B;+gl8=$Q}>0KSiI!<(qbfhvnv*6NCVpF{VuG+@g-FdRp za85zvzS{Yi^Bs8cSMcGUF1IT~>e}alfZvF%`ykrL$FAet9`~v4sUV=|gAP6Hei@$o zwY!yZ9F}Z`Q3x_rYg}wxYdnage9`#W_!?ZOhv#^7!emdmrykq(X5{6w%*flGubGqM z*!>mKQd(@TVb?zocK4fk1en7x?|5*aTJI9L@I&4wk)7L+o?jw8JA;pouuORIWUE5@ zC9VefSz|p7+Vi2c3(L2)uQ#&vWbEHDAm7ElGkhW61@Pz_ea~P8e~r%A$=}yM68ksV zKM}b)%fCqC-S_+7L1X+Gx!N}{3^XDeta~c^{rteCfmQ7Hje!>eZw5XM>-l;q z$kJT=99QW#==bXD^%t4#?fU0n>unsp9mk;+sc1!~IC7ECHICUx=!?<)Z$%GXt=07;W7>+(XJp`!>?E*GgX8Jx7zUTbeazAUsaN4LBQ4gX;znVm6m0x{#}kfM!CZGc z_9LZwI!|z#&e7;a3!E1^9|m`L9sH;xw(wwN)MzZTV%Pa_!<*oRkGbB%GVAUZ{)wyM zgzMaIgOmTp52Bv{N}g^^H5MAnjr)v8!5qFeel+&8io1B+V6M~9g%+a;J&X?e78u_F z&r#-J(=aEPCFWf7YV!eetN8(I*u*xQfLyBfo(&JY+IuIu=u_BfJEU}KXZ3;$4#P(~ z)+)40L0-=R3%?#dxBc!Z9kKpO}0I%*5tQk8p zZZi7p0+6Mfzz(0aZ)a6}ZvPS8=qT-2R>V2l3ha;jnfd01T-b^yuNJ1^Bgo zjAJzZ!w@$1h3G@;9WQ{Se*lVmBbX;Tg_Z&U4T_Zf9nna&C9-!vE0;PBzHp za;3V)yUMW(moU5cxgJK+eJ;6JJ9igwrQ_U5?h$UM+viTh{}%$?y%lR?jr)1`hweS@ z{qCNihQkdXxZy;j(l`f1_fGiN^YE`vjqkymdSQKdJ(-?~U?OLEu0#jkfW`PGI!Oof zDDyY8UY~a?D|<5h zxt1qe=w0T$9P9Wde02AFU-jGuPzvusy zHTfHBayvfDonV@~k;;2PsP{+K-^x}>Jvx@6wpBZ*oz?E(oPE{)@UB7X5Op}Hj{}Kq zfwHBlbJTOy>(JGAtKY%Nx=X!l23Y4(`&H=aTk*iP#<%0rCQ1$c0_|>W;a%Df+T}>y z-FhF#0EdZ$t$?FE0zcWr>U$e*k_k3limf{z8TtVJ=xu1bdnG?P)-}-O1nJ2Ei>LsL z5T1l5T+d-^y@qZ3yQ{C;fy}IOpMzKVG4~et2h7Sb=vT$a$LruJ{XK)waYuRl#1mAb z<1Ry|TFZ+17<;y-IfOWZN^=?Bg6qI8AHa+Av5X!V?A5&E81>m8ZMRFi_Dk&A6D-Xd zXHB(2avj}EWXH#FjqbjYNSv2^pMo!U!9wZ_!ko$2pMlSFiT@Vxx3Vs`fII%d4(n(`XaN4)P zXLgu7&Ckr;;E{W=2llh~6mMH^2d}cJl@RZIr)IdrDPt6h9FvhAXQD~1Augd6y0Zss zD<8jVDKQ9hz)&wii@p_m>uG!s2f_4uyH3QWHi#)nC#GbMYY}#}@H~71=5zpLuNO}@ zzpl8n!FJV@W^L>M%nS-kN<9HN z;ZW1CgzCVk7ON{jJw8^yU{C&}wzqe+_qHEL{EtTD&xL5t&#^DxwePZjkN(hFJ5uYV zouCcYMrmFxRm)PO)b9D&W0 zqL0%j;+JS3R^L5bncV-;VCuW6O*9#HhBUHe?U-08%T)WUhM1wVNTKgDP6A3)Ii zq5+p17aCW=ciXbNM|sXAUSx&mMtJN)SW7P>Ek5*ofxV=dJ@BLtV5VKn^(kf^F+(%p zu=7A1mz!6Zt61Bwu%jFjg#OeA!C_w zwebWN#}DkacAjDQFv`%>?!?FUy60EV5kzT?06WMxXQHL8!Vmiq{=5TNsv6N)i@mG8 zYeCQt;=Qn}NpRC8Xku&ef&WfC$tk{S(DQYmxu4>J?dv}YZ{0-n^DB^JkK?8IBpQj6 z5tsr-aB<+yz*=;v?SWllocFd;7E3wS3HhZ-uh2w%b=B(SXi|@>AA;fTS9{@yO~G$b z2P$|ysNfU!7qKgUw|69NM8i8b8Nb}MAcLO~k#MBmOXtPaaO4@_H`nW{(Uac+Bltz{ zfhTsPV=Nl-Oh-N1@mdgq1CBo6HWn6PrSk^o-RMpq;~^3pZLDh=t9&_j-!rbAjPL-Y zR-StXqq`7&_(h`O_G97ok^DN#C^Z%^!cTz6?f@HXg+FzmC)HDm?0U$v)nh{g&cV;U zP{zIeB4a@W?l(uus<*M*{_yt0yPd`AtwHCxgeZf1!DODm=k}Jgr2eov<0T#9^ZJr~ zn%V+a2HFF>U8OhBy%oFUJIY9P{yl-{ia( zEO!gq#vW&D{CERE)6-m8uG6s7&tzB`C9UBleIPNbXgM*Z$TItT*c11sQg1r~w zcWqD?s%!DPeh7loLrR{}ptolb*La0}6~4je@lt(>?CF7xG8Fvw6g-3>(A!(EQ@3HK ze2d=G6Qst}Q<>i?ys(#Ildh8%%jfzY{WrZE7U@8Vmrg^%EOY$B@lVGt8U524OVs7e zAto;5Tm*W%0qjL^wPVm5g*3SvT>e>b(rvDfh&|a)6i^ZxQYO1^GSUPE%%-eo_-HLj@M-*&oOA;EOiY1{)|Vl zR>~7?*18gBHc3C7{@v0OW&>3jL7kaMt+ylqn?0E^U zEp(%=JQm)#$#@pd!^5-6e8POjd>0GrSMz8Y*Hq+vAD+AyKR`cXB!_~XJnP?sUC|M2 zL?Ar%fwPc%%Rz0oi^xcVUs_AK*8x6o0&=fGeVVoKDpqS3cKMs&pLY1A$GKiZjs?Q%~3*>i?CR)VdU;%ybgechiJWfx;uMtt(Q zU=jDTr(efr-Hl{Bkthf;devyjSGcZYHN1v4`Gf0Mw8@cf3;A}syT*N``)+K9tw_0D zcxY@yB&QqM#uVdxJT&*ihu<@H6AN+B=!UjodX}IwUxU{CC|;TG!6Qy2N;MfoViu!z z1Ecm3`s0Vh9kutKfVbX-6;X;sx)|>KB)*uPtes!*Y4*29vWK&XhL{6)ejL91h4m{w zsyAW)A1A4}X$h>`8 zTR81#eLT295FPIZIP4~Dk!|`eB9Mg4bAXE%IL^XDe;d(8+woa+L&L~$RuC6)Cz{1t z^!Yc5OFfI|$b*ct@PsWvhgb;$@TI#m93CDbyNQk4+VjFVpU+8Touy#km_40^;I0N2yK0d5F(BRhL!P*6O zGYpMSg<$YoIexM(#h2it}_k$>tf>hAAp0tOzhrn zP@Y!!HjfA2NhYHEF08ID@R&v5&<}I>H;nCY&OV-F(N#p`*O~B`#h%OP$<1hn>)@us z278ZPBjn!!=C-T!D7)!h0rOi%Eamy|oh$G+-HKQ9VQkN5L3rLZKQ+I>xB07Sc~jBS zXGS%hHQt|zacvK>HwLSG5@+w3`WdpJuZH?%~@NZ-L$Y%h$_) z4A`9x0z3|%a~X1PzW);D|1R{J{(%9~cR40-3NgqSOd=;*djFQP&_V9%ue{A}3l)-%|~dd>S$P6Yw?FVJk0l-ptNg=X?&oe>S>$1=jI} z#C-3?_m@Om{Y_X%>xg*SOZ4i|>@R_^O+izyhl4$3yaEUNl9ge|C@$eyTEzZZi>0*F z^OKBw8OSQ};n~l{uY6WC+IXXkxBrN>(#_i+PBsb~DaShn-}2esTabgBuz+_l1Ksf` zkFu|NeBYnX z`}KOBU)a(rG!cK!Uxg>dgDaQ2H@o+N=UZv*xpf-4`)F;lmP{5V1#LuN$?vr?)Tt_N zoz>HWd~rOdy@?%i2KM{k`ku?``ge7hG*-`KEJA=yNsD6i)WEA9?xd?BaB=^(|8Xyi%m(cj>u^i)2%(Ne*qc9Ajn_S)S5KP;o(b zknjE8dXxQH#Tz=3lwlGHxGTJqP3^(<5ODGgSo}tNw$9#LIy#axagfA%4{SUIrXx}g z*`%>9pg&cBMmnO5_QOT`m@SY>zMgs^IK9_Mx`aLOfOOZE0q20(;~27TY3g-x!qrY1D~-!!$@BBC$%d& zR`+$j7>S2s$gO|By>vS6n15mh`@=@s(!lA1ixQ99FS=FhL4IGMhZS<*m#|rH(=!OJG8;A>osb zyK)iycbCqMaQuZkxZd$O`g#FKrqp3{HgUEF$GCV;C%$wEGk9CiaQ|1uL`K6*~05uUOnxuwy#Y=1|e zUMX$DH#yGxewi%j1H6+qyzz1Jd_9pXazNMQ#>$_S-e_OrK|mkkoNZIGP`rw8%qkTh zwV4`<+U3M68>LPqKev(${2|n?eDxOD&|hd{bux8_`^Tfad_?wo6SpDDbP|pBs_7p7 z*bCg0H^8MbDc%0KDKpFq&FfKZ3(Upl=4{spIy<6OwH7Zp3vN9U~gzk2&f&1Ul{oC=RduB1E zH=|V^)LT1+S~2;ar?{bl`zy@pM9)lk;SMGaXurgV?>sRWg5iaorQuBKDe(PV=^Lp~ zs*_%TL`B|x7t`jHd;tdV18(MX*-r^p-cq`vL`Ey4(Yr({>!AJ|+Q9YupoI&Ea+4Yg z2Z%%I@{(BGz*&D`IzlSrG`YEA(u?J|^1kSdA!M~Wp}z<=HQ79!l*SS^=T`Fxa~=q) z$lMMmVLT4}E-=k8xV_*}*DNtK)h1eJF~gUUX8a7l>V~zBDfI?Cz{$-SLRM=G_h*JJ z87{RQzdaMD@)U`U3%EW8yRY5f9$@ca?*=!BLJ5nb)icIE6~yxuxw%5{&W|{kFHpt0 zk#-bm=}BO*WXCel>}TwNgO2N{V>NoZx4pBQ(+Ss%LvJ2~=Q9iLe*oTamOMu#c&7Chq2VnIZ@8g-HknU?o0gI{MDnY~r?f z;2Kl!y7pWP^+b?*UkkTC>A8klc~9J{N*_Zt|KdxCq-Ih}kWLg1_E4Va4E&#^(gD)H zGVFc_%1swtH~xgQ?{-Dp83pDrR!t<|I~~PLC^SbqhIpP+U&)EKIf-kZy`?t!)R1xl8zL?d&q%u-Bdp zk~svX6naW0(z}b9TzN2r+jQEVIJ$rrz4Y1E(fYWpXJH(!C^p20q?GpI`J@>gY%b5eaXvL`yMopWH!?u{saug-4i0KwWM=FX0Y9e>% zV?3Y&Fy>WvF;lIKU0uPp7L8FCO@rB>opkO`DY?crpv=xNxE}bz!#v|@ht7pHr!d>j zvU|!z8a2phFmacHP|pT2)mG7XJIChsrBh`g8?aF>q(c<}uIa6eA^kEN-+u?&`vm$! zx$;nHN9Jssn$E;JuAW1$ti{m}Fa@EZgwr6k(JzdG!_9)hWup?8njV?j@+AJsok>A^ zI81}!mbn9}u!Rmtf7Gxq0ci1|9Z~zxg&zaUxa!f;L3zX1mt9Lhx^tZk9 z@0_A8^foHk&w=DZ6*%t*cv><}Nro#6W&I}1_X$2)E4KpkjnVVd2VrZ)WW}Dlo9Vc* zuQo_~AD{hGG8+5I8lH!zRcMXK8TMul?eXM!4BB2c4tqeom;ALCo9 zO#AIj_nYwDr=}ot1Sb}Y;xNm+6g_4yT9#P5EX#77{=V?28+6IM~9_9Vx)08Y6F-OOd~ zjn_H}rQ`@XrF$faLoAV~ou9xa(&_XXX@`V>DB_rkxhT_3Y%=&^5cjSccix9&QBT<2 z-|*IU;-$R>o?QW7OT#-o;Wz`DEn)w3VtS>bl9f1pKxF;#$0ozc3vtCBqfLgoH4y9s zc-MXX1Oh$5o=`GEL-p*KA8dP_GLpvFwxLLVZBG~#96 zt8%toBe@Ch);ru)4~d?QOv$5o3iB*G`+I8uX*sn^So=NiUqVW5WQs? zpYf#Hg_hlPct{~_RMEp9j8nQ5Wy{CXkFM`*p4SR6w&3PR=-c1m{dz$E_Zc@+xTAL6 zIr}G`**7SGP4N}Rf&9M3uTj}ibJ$A0Anc(y-Y1xptxz{7;mhQ~<+_m+98WTM3HP#4 z&s~+d?z2&9UB9BI1fnX3(x2`MyYsMH29gjKojJksQrRv-8~hoc(?|2CMctY`(^2b6 zUf7P-(wD5vC{XtY;EK5@&Fk?$3(#ANc>?9yLvn=A>0mWOb#CKn&wP~W1NT6MiJ@z~ z4ks<&bIbEc?543sLo|1!ISG9?_hT6I@qKzf%b1a=(r#|}A?|l?vfrag4_+Z3Tu#2b zjyvH;uPTi1JFuzIob(V_-x9FJHuS9=rsRFPz;&ttPpvDOqk~rPY14NojCV=pH#N8B zzR$t2-fG?pmN-l9vkGS?kVH%v*}eq4v*qCPLnzH6mvF}t!E}tXPSHD!rPfE*U%+zV zpm8fX+(g`h18^S=wQDG;gsD7{rS=1;uRXyAmmLosL)raa-D_UxT#mxE3oa8$B6}>G z#!EUgSx>AihZ%0*+;{7~&0!R-T=!|3*M;n$AJ{;@eHzWt`a|e4MxcEtU~SHEwNd}R zq5w6>B%0g?x3AmZ9pED|X8q4C0%NCu_12NZ zO@&>ip*d#Andpu=a=BUw1`wO*ZO(WAIgn{4L#~l;k>ls}?8)!5CehM>Kb+%Uyt^d0 zzW6`of+zEFj|${Vpvq$MP-WyPBGFwWnn*UfUQuweXyqf^?Pd6>naszWm!GOqsqceF zqQu0Z+K&Rc9Oi8}j^ZhP%V5)R(u8HJws6WpB{<#XDEO7+K5O9t2HUGvY%MeR72@Q~419kofBLID#n=7zSDz$-Mw^!wX%b9+ z9$0J9(05-#%}LkQs?Y|I!NY=i$j!%vp5hGilk&IAaNA`WpTo(D{JJmZ}iljO7s zha4gfIpvT;4%{Lk4xF=6gd*jzxkMs|*}tquI^|0Pv)x&H%@g=q~g!iOy)#-awan~6_-zHcKYbCqw42d-9+>u(T*z7uDe9L ze~dUh)sdklS08d!p6 zK38;jlt|EUucFbHhy)G)swlky`k_>L*3}&_79cP=W@&RCMSe zk)S@bBWUn5O@~o}4sO=;0ZKvWtDwGHiVk5M1oi)>={8Exfp;`LLJ1nUps4o&#u3zq zb_MPKR@0j(L8-f%PND?$!+t?SXBCa3uYx8prjpK}1nr$wH2DdUq~B43roUD+c>p|U z`l6yKjJ2S{pDG%?hw%lC0ZUNNEkX11=U=(_>g6l*XS1*U`6hK{wtnB(1ciK%HRxd8ZG?-Lsl`91V z1b--))M>>BL8_P$5KN-CPH5Xmnl6;M-R0%QLbRAK7vhu1#j>@x^R-AR#?0elsi$=G zRK!%h8mWyn^w;EQFsajukA_q+qam2YXgHy5L)acSQz&Vv)k=<;(BfluGpg47E8`lT@lMU!4-tz4tXE7b zTQmWMsTh&07b|1A=Ep)bAFq(QZXvSPoKWo$a$95ZT5J|TJ{avEg^VQ=vUqu2$)g454cM<)J%<>InFjq&23gblg_98Q!A^LcX=mBK+ zhlqYSLiEuvGTR=a$BHA@*>JA`tm9Id=LHYg&nuh*AFok$7wxn zrZcpQ*3cOB(mooeLzJRPnxJW#q8S>YVLD7lXq5Ws0QJ)V4bnjxqWzSnjkJxPr5&`E zx@jx@nfB0L+C~ARbdpZc3v`Nl=tcSyZJ_6ACvBnK)J3cQ&plWz zcDVTJwdtTsw~XgOSN?=ky3AC@u|!yA!N*Gl8ii%Pt@+!z2tGv~d3F4@@zal|Dl*$@ z8%WR(p=#TbjM^Ecvf$aff{ne)HZG~}f{WYXZR0xF@xE%&O6h`ZlZP0z>Tl+;kcWD< z3CO@B=EWwZGSmo(O+3vZ!RF~UvGqciPA9$eQN}Epf13< z3Li+OQ4JF?FP(rz;$^Wa8Ilwwkc2eRrVuu0lZ67-uJKJKGGQRz0V7THfrp4>E6I+y zaKW@$&|p&L+e~T$h>__q!dd1>I;5Cd9as#j!VBk^lj=~zYfY|XWM+9f9&0=y^sf+D z_gFZxZ7i2fN@YYkG;!8m8*rfwQ&!kueV~UdWHHSKp2NZyQ?x-WDf1>A?Fe&hqi=3Lg55iVJ|j`z&_XHC`x{CYs%}W+qSQJJ+|m=ekzY#z*Te zZRT^n=yH~}oEa|`^7Z^6@<8=$NAVr#-)yl+l7>87mnia8flk0K>9ZLd~=(QHMR+d zd4w^BbjfeJvsSHPSV<^vK$}|?7{9d&Nhk1L%f69Kkuo!l$4|KWI)xNJ8u)-M`$oom zH1&K#`22c{XignIoX0n{FMYhReYijZmh=yK#u4WkuWg@iij`Sm*2E_HjKzwdl-k7% z+1G6`)fuc^tju)du}s0fjTXzD?%Ksmn^e#96tTH&vUvL3=!3QHmjUaZjibp!nh)sl z&Alanw>gF<&J8u+8-2bxp8eZ}_+EqSQ`}3Ml^{k_9(g@;T91|?Z`l&VQ)e0<(Bqrh z7xI?pEuI)loc+DVJ8Rw6I9g}CB`|y2Vt7w~_O{3HIx~BreQ1ZnbGIyQ&tS-3c3MPz zfzvixXf^DzXyz6u>7ZT*ny!Y-3c20@R{QP*UPBjcJ%R>ui9J51xbyam`Y%>tz{meWwr9vY&*IQVuD3Sm-EHzd};Cv`^Kh0}iPZHkr#BFZaU-YJ6{%*^0bd z_D%BmrrsBtr9p>t&Ufq9V^s+0phN1w*o975ha8f=YxhRXH?;W(u5juRXZ<0CrZ4Q< zMal#s@328~m)|~I>+34ugCiPGe0uPKJihq|25=5roTOv4j1xFd9kDnvR3yP#AH4wD zs72FXVmwniySl~{n)=AoHd4q7#~qUSe)LrFCLEsmG}S&{U_YMJcn_+|AXxNsKxAD z_8pqPV-|0P4X)*w85+^!7A^KA*Pq1JF$4Mj35(ged_VMU;02AR{+EGon#VU?>melZ zH+T3uDE)UlUdt^Project "C:\Users\owner\Documents\GitHub\epanet\LemonTigerJ.vcxproj" on node 2 (Build target(s)). + 1>ClCompile: + C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\bin\CL.exe /c /I.\include /Zi /nologo /W3 /WX- /Od /Oy- /D WIN32 /D _DEBUG /D _CONSOLE /D _WINDLL /D _CRT_SECURE_NO_WARNINGS /Gm /EHsc /RTC1 /MDd /GS /fp:precise /Zc:wchar_t /Zc:forScope /Fo"Debug\\" /Fd"Debug\vc110.pdb" /Gd /TC /analyze- /errorReport:prompt src\testLT.c + testLT.c + Link: + C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\bin\link.exe /ERRORREPORT:PROMPT /OUT:"C:\Users\owner\Documents\GitHub\epanet\Debug\LemonTigerJ.dll" /INCREMENTAL /NOLOGO kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /MANIFEST /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /manifest:embed /DEBUG /PDB:"C:\Users\owner\Documents\GitHub\epanet\Debug\LemonTigerJ.pdb" /SUBSYSTEM:CONSOLE /TLBID:1 /DYNAMICBASE /NXCOMPAT /IMPLIB:"C:\Users\owner\Documents\GitHub\epanet\Debug\LemonTigerJ.lib" /MACHINE:X86 /DLL Debug\epanet.obj + Debug\hash.obj + Debug\hydraul.obj + Debug\inpfile.obj + Debug\input1.obj + Debug\input2.obj + Debug\input3.obj + Debug\lemontiger.obj + Debug\mempool.obj + Debug\output.obj + Debug\quality.obj + Debug\report.obj + Debug\rules.obj + Debug\smatrix.obj + Debug\testLT.obj + LemonTigerJ.vcxproj -> C:\Users\owner\Documents\GitHub\epanet\Debug\LemonTigerJ.dll + 1>Done Building Project "C:\Users\owner\Documents\GitHub\epanet\LemonTigerJ.vcxproj" (Build target(s)). + +Build succeeded. + +Time Elapsed 00:00:01.13 diff --git a/LemonTigerJ.v11.suo b/LemonTigerJ.v11.suo index 4f787f31457c1af90b9f6147dfdb318166b27f91..d4ca826e770732d11d05cbf7ba46270d963711ba 100644 GIT binary patch delta 7276 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 delta 6872 zcmeHL3viUx75?vLHzb=~vUxuUuz?U0Okj7DK$OG;@&E(!rZ6#rNeGxol4aRYUYa%H zV=9hek9O5k3ei#9u~k?)A&RmZ7_k+Nk0NbD>)YDWiZ-Z0G5yZJ`)B_=)Uo4C>$G?0 zn|uCy&wZVH?sv~!*I}*8rESmhR7MD6tVxo>B}obaz8n}BKqiHFt$kkM)@%qr_vp!O zXZufzG-}bbYBYjA(VV1ijn&BNcd{_svui3q1yS4@bxpc8wZbkQ|=30_eYEuI8R^;PV zMpYS2w$M=R0rxP@BgEHn!CIXFUjAXADVCFL%Bv;(^Vcc6k5?}1Fq4O!a#EbKJoY9C|ah+#|X zix6G{SnXxxuK=$CuK~XUP64k2r-9!Ce*oSAdVwD$G-)N)B{Xb)R2gf7IrNH-;C zQD6KbonSJQznlq+4NP?70qh2oL7IWDnmYha9a)-=a?NNCPRAj>+|^+dp5kbc&vj5Ov~*L1BZYbk(mbJh5#P$Ep-fsR)k$`#T53Y>lrp4R={kHl zBr|AXon)1=APp_EjZ&5)mu;4srFv;CT4bQL9b{gQUVjM5ftvMFrd$)~jqWMD)N?^E z4D>=_9$oBB@;p9PXg&4_VIq4`7`69mJqwJYoP2MtH_eNF_7>yq-Pt=ns5zbc9zLj24i zRT~)00x2CoGuSYwaRt7a-9!LP+zoVb@^gk9NMiwI8@zpK2JyYLx>!ddxya*+624Af zv?vzt(o(~8EKRvT*M`pq9&84YN?J0XTKc(~y2qgg0V=(2$`Z*L1Fg z!(B;QyrJ5;uG!J(U0m?EI9TzXpoij<#Ue_rxob=gPG+uTq2~|mACxy9j3e#x3xnTD z-eBD`Uanh32@VtXK*xQI5A-3efvel3X>jl@fFunr!LpzqWlY-hg7&)lD zU_`A|ReL4PUKyONb!7~dHmo9#Et>BAfjc4C=L}UF3ms^gozFEtoKzX z51XkC9uVxYXjqRqi1&lF3rEzd?Kq!nWqZ`rMh_b$2SgX_XC7^=t!FFK7i*J6yWdCV zn#TCwL0}Bnx2bO5pa*8I|G77DonELmFi+LpbU4R--dENSQBZqg7A(;SkFjISA5(6F zDdsw<1Tk)vv_jehvgVhFAYH+%(ay{P;d#|4YQ@qKmjFd)Ptq}YM|#W7LUzA>=>?Hgl<`4C^E z!6{yW{%0v{=3elC$$j73M(2@d8_(5+RNXwK>=a+^yY1oLo&^>mrjl5`QDH7`+loho zw`ZkE@ZNayD{;5-(ce>bs~9|ZaKeboWonp$6o+=#tR7IGWj@wc`&f;d1* zJoZiPj4SuG0}k_s!G}@wII0KfcZJ4tuRV0q)>ooKi%v4b%TZ+Rq^@~ zI1>Mx5H6ABcoVIe9!|YSGU(C6d&T`^J>IC@TWf)S}pzRCGw>C8KfkB`bcu8l}}jZB^4-D$U`vs zP)z;=rJWv6ubmp8eNU#tkO^VR3TgM#`BZ#*Ihmf#^7>A{rAeP{v)#b89LR90FGdtN zXTK=D+=8F-f~WMS^4-0w#2C+GdQlz4*ThU5f?O$2eyD3HRTD$5)3NZSP&v+B94V4H z{Jl1kV@~CVzXZNgbG6*-45?fy#YMo+|F6~^8C2JBATan6z%)#lhWYCQai>wa=zcx1aB#spmM9~QP9X-wu3u(Y!F@qpFfdBJ$bK-mo4|eGkGeieYP!pagTk*`u zz)5Px*LsN`D^5Hw@Cf=hhdY6`oH#eh!%Z_o{HEay(D5g7z3ZZLmCIGcnuGlg65mzc z51nJwS7DAidZ2-2>%r1~N?3&O_Kj1R8 zjSQaDcTwT6i^MwQnz}BVC$sMqPL4D930=1*OFA8a%UY!ke(Q$u#Wf}!D&>E0OzTlxK@5DBJv#kCI7i& diff --git a/LemonTigerJ.vcxproj b/LemonTigerJ.vcxproj index cab68ab..7ffa87b 100644 --- a/LemonTigerJ.vcxproj +++ b/LemonTigerJ.vcxproj @@ -11,7 +11,6 @@ - @@ -45,7 +44,7 @@ - Application + DynamicLibrary true v110 diff --git a/include/epanet2.h b/include/epanet2.h deleted file mode 100755 index d1d37f1..0000000 --- a/include/epanet2.h +++ /dev/null @@ -1,251 +0,0 @@ -/* -** EPANET2.H -** -** C/C++ header file for EPANET Programmers Toolkit -** -** Last updated on 2/14/08 (2.00.12) -*/ - -#ifndef EPANET2_H -#define EPANET2_H - -// --- Define the EPANET toolkit constants - -#define EN_ELEVATION 0 /* Node parameters */ -#define EN_BASEDEMAND 1 -#define EN_PATTERN 2 -#define EN_EMITTER 3 -#define EN_INITQUAL 4 -#define EN_SOURCEQUAL 5 -#define EN_SOURCEPAT 6 -#define EN_SOURCETYPE 7 -#define EN_TANKLEVEL 8 -#define EN_DEMAND 9 -#define EN_HEAD 10 -#define EN_PRESSURE 11 -#define EN_QUALITY 12 -#define EN_SOURCEMASS 13 -#define EN_INITVOLUME 14 -#define EN_MIXMODEL 15 -#define EN_MIXZONEVOL 16 - -#define EN_TANKDIAM 17 -#define EN_MINVOLUME 18 -#define EN_VOLCURVE 19 -#define EN_MINLEVEL 20 -#define EN_MAXLEVEL 21 -#define EN_MIXFRACTION 22 -#define EN_TANK_KBULK 23 - -#define EN_TANKVOLUME 24 /* TNT */ - -#define EN_DIAMETER 0 /* Link parameters */ -#define EN_LENGTH 1 -#define EN_ROUGHNESS 2 -#define EN_MINORLOSS 3 -#define EN_INITSTATUS 4 -#define EN_INITSETTING 5 -#define EN_KBULK 6 -#define EN_KWALL 7 -#define EN_FLOW 8 -#define EN_VELOCITY 9 -#define EN_HEADLOSS 10 -#define EN_STATUS 11 -#define EN_SETTING 12 -#define EN_ENERGY 13 -#define EN_LINKQUAL 14 /* TNT */ - -#define EN_DURATION 0 /* Time parameters */ -#define EN_HYDSTEP 1 -#define EN_QUALSTEP 2 -#define EN_PATTERNSTEP 3 -#define EN_PATTERNSTART 4 -#define EN_REPORTSTEP 5 -#define EN_REPORTSTART 6 -#define EN_RULESTEP 7 -#define EN_STATISTIC 8 -#define EN_PERIODS 9 -#define EN_STARTTIME 10 /* Added TNT 10/2/2009 */ - -#define EN_NODECOUNT 0 /* Component counts */ -#define EN_TANKCOUNT 1 -#define EN_LINKCOUNT 2 -#define EN_PATCOUNT 3 -#define EN_CURVECOUNT 4 -#define EN_CONTROLCOUNT 5 - -#define EN_JUNCTION 0 /* Node types */ -#define EN_RESERVOIR 1 -#define EN_TANK 2 - -#define EN_CVPIPE 0 /* Link types */ -#define EN_PIPE 1 -#define EN_PUMP 2 -#define EN_PRV 3 -#define EN_PSV 4 -#define EN_PBV 5 -#define EN_FCV 6 -#define EN_TCV 7 -#define EN_GPV 8 - -#define EN_NONE 0 /* Quality analysis types */ -#define EN_CHEM 1 -#define EN_AGE 2 -#define EN_TRACE 3 - -#define EN_CONCEN 0 /* Source quality types */ -#define EN_MASS 1 -#define EN_SETPOINT 2 -#define EN_FLOWPACED 3 - -#define EN_CFS 0 /* Flow units types */ -#define EN_GPM 1 -#define EN_MGD 2 -#define EN_IMGD 3 -#define EN_AFD 4 -#define EN_LPS 5 -#define EN_LPM 6 -#define EN_MLD 7 -#define EN_CMH 8 -#define EN_CMD 9 - -#define EN_TRIALS 0 /* Misc. options */ -#define EN_ACCURACY 1 -#define EN_TOLERANCE 2 -#define EN_EMITEXPON 3 -#define EN_DEMANDMULT 4 - -#define EN_LOWLEVEL 0 /* Control types */ -#define EN_HILEVEL 1 -#define EN_TIMER 2 -#define EN_TIMEOFDAY 3 - -#define EN_AVERAGE 1 /* Time statistic types. */ -#define EN_MINIMUM 2 -#define EN_MAXIMUM 3 -#define EN_RANGE 4 - -#define EN_MIX1 0 /* Tank mixing models */ -#define EN_MIX2 1 -#define EN_FIFO 2 -#define EN_LIFO 3 - -#define EN_NOSAVE 0 /* Save-results-to-file flag */ -#define EN_SAVE 1 -#define EN_INITFLOW 10 /* Re-initialize flow flag */ - - - -// --- define WINDOWS - -#undef WINDOWS -#ifdef _WIN32 - #define WINDOWS -#endif -#ifdef __WIN32__ - #define WINDOWS -#endif - -// --- define DLLEXPORT - -#ifndef DLLEXPORT - #ifdef DLL - #if defined(CYGWIN) - #define DLLEXPORT __stdcall - #elif defined(WINDOWS) - #ifdef __cplusplus - #define DLLEXPORT extern "C" __declspec(dllexport) - #else - #define DLLEXPORT __declspec(dllexport) - #endif - #else - #ifdef __cplusplus - #define DLLEXPORT extern "C" - #else - #define DLLEXPORT - #endif - #endif - #else - #define DLLEXPORT - #endif -#endif - -// --- declare the EPANET toolkit functions -#ifdef __cplusplus -extern "C" { -#endif - int DLLEXPORT ENepanet(char *, char *, char *, void (*) (char *)); - int DLLEXPORT ENopen(char *, char *, char *); - int DLLEXPORT ENsaveinpfile(char *); - int DLLEXPORT ENclose(void); - - int DLLEXPORT ENsolveH(void); - int DLLEXPORT ENsaveH(void); - int DLLEXPORT ENopenH(void); - int DLLEXPORT ENinitH(int); - int DLLEXPORT ENrunH(long *); - int DLLEXPORT ENnextH(long *); - int DLLEXPORT ENcloseH(void); - int DLLEXPORT ENsavehydfile(char *); - int DLLEXPORT ENusehydfile(char *); - - int DLLEXPORT ENsolveQ(void); - int DLLEXPORT ENopenQ(void); - int DLLEXPORT ENinitQ(int); - int DLLEXPORT ENrunQ(long *); - int DLLEXPORT ENnextQ(long *); - int DLLEXPORT ENstepQ(long *); - int DLLEXPORT ENcloseQ(void); - - int DLLEXPORT ENwriteline(char *); - int DLLEXPORT ENreport(void); - int DLLEXPORT ENresetreport(void); - int DLLEXPORT ENsetreport(char *); - - int DLLEXPORT ENgetcontrol(int, int *, int *, float *, - int *, float *); - int DLLEXPORT ENgetcount(int, int *); - int DLLEXPORT ENgetoption(int, float *); - int DLLEXPORT ENgettimeparam(int, long *); - int DLLEXPORT ENgetflowunits(int *); - int DLLEXPORT ENgetpatternindex(char *, int *); - int DLLEXPORT ENgetpatternid(int, char *); - int DLLEXPORT ENgetpatternlen(int, int *); - int DLLEXPORT ENgetpatternvalue(int, int, float *); - int DLLEXPORT ENgetqualtype(int *, int *); - int DLLEXPORT ENgeterror(int, char *, int); - - int DLLEXPORT ENgetnodeindex(char *, int *); - int DLLEXPORT ENgetnodeid(int, char *); - int DLLEXPORT ENgetnodetype(int, int *); - int DLLEXPORT ENgetnodevalue(int, int, float *); - - int DLLEXPORT ENgetnumdemands(int, int *); - int DLLEXPORT ENgetbasedemand(int, int, float *); - int DLLEXPORT ENgetdemandpattern(int, int, int *); - - int DLLEXPORT ENgetlinkindex(char *, int *); - int DLLEXPORT ENgetlinkid(int, char *); - int DLLEXPORT ENgetlinktype(int, int *); - int DLLEXPORT ENgetlinknodes(int, int *, int *); - int DLLEXPORT ENgetlinkvalue(int, int, float *); - - int DLLEXPORT ENgetcurve(int curveIndex, int *nValues, float **xValues, float **yValues); - - int DLLEXPORT ENgetversion(int *); - - int DLLEXPORT ENsetcontrol(int, int, int, float, int, float); - int DLLEXPORT ENsetnodevalue(int, int, float); - int DLLEXPORT ENsetlinkvalue(int, int, float); - int DLLEXPORT ENaddpattern(char *); - int DLLEXPORT ENsetpattern(int, float *, int); - int DLLEXPORT ENsetpatternvalue(int, int, float); - int DLLEXPORT ENsettimeparam(int, long); - int DLLEXPORT ENsetoption(int, float); - int DLLEXPORT ENsetstatusreport(int); - int DLLEXPORT ENsetqualtype(int, char *, char *, char *); -#ifdef __cplusplus -}; -#endif - -#endif diff --git a/src/lemontiger.c b/src/lemontiger.c index eff0c04..7d6d447 100644 --- a/src/lemontiger.c +++ b/src/lemontiger.c @@ -2,13 +2,12 @@ #include "vars.h" #include "funcs.h" #include "toolkit.h" -#include "lemontiger.h" extern char OutOfMemory; extern int Haltflag; -int ENopeninitHQ() { +int DLLEXPORT ENopeninitHQ() { int errcode = 0; if (Hstep % Qstep) { @@ -36,102 +35,67 @@ int ENopeninitHQ() { return errcode; } -long timestepLT(void) -/* -**---------------------------------------------------------------- -** Input: none -** Output: returns time step until next change in hydraulics -** Purpose: computes time step to advance hydraulic simulation, but don't update tank levels -** Let nextqual() to do the job. -**---------------------------------------------------------------- -*/ -{ - long n,t,tstep; +long timestepLT(); +/* computes the length of the time step to next hydraulic simulation, but don't + update tank volumne and tank levels. During a sync HQ simulation, + nextqual() will update the tank vols */ - /* Normal time step is hydraulic time step */ - tstep = Hstep; +int nexthydLT(long *tstep); +/* finds length of next time step but don't save + results to hydraulics file. ignore reporting functions. */ - /* Revise time step based on time until next demand period */ - n = ((Htime+Pstart)/Pstep) + 1; /* Next pattern period */ - t = n*Pstep - Htime; /* Time till next period */ - if (t > 0 && t < tstep) tstep = t; +void updateTanklevels(); +//Prior to running hydraulic simulation, update the tank levels. - /* Revise time step based on time until next reporting period */ - t = Rtime - Htime; - if (t > 0 && t < tstep) tstep = t; +int DLLEXPORT ENrunnextHQ(long* pstime, /*Simulation time pointer*/ + long* ptstep /*next time step*/ ) { +/* The lemonTiger equivalent of ENnextQ, hydraulic solver is called on-demand*/ + long hydtime; /* Hydraulic solution time */ + long hydstep; /* Hydraulic time step */ + int errcode = 0; - /* Revise time step based on smallest time to fill or drain a tank */ - tanktimestep(&tstep); - - /* Revise time step based on smallest time to activate a control */ - controltimestep(&tstep); - - /* Evaluate rule-based controls (which will also update tank levels) */ - if (Nrules > 0) ruletimestep(&tstep); - - return(tstep); -} - -int nexthydLT(long *tstep) -/* -**-------------------------------------------------------------- -** Input: none -** Output: tstep = pointer to time step (in seconds) -** Returns: error code -** Purpose: finds length of next time step & updates tank -** levels and rule-based contol actions. don't save -** results to hydraulics file. don't consider Report time. -**-------------------------------------------------------------- -*/ -{ - long hydstep; /* Actual time step */ - int errcode = 0; /* Error code */ - - if (Haltflag) Htime = Dur; - - /* Compute next time step & update tank levels */ - *tstep = 0; - hydstep = 0; - if (Htime < Dur) hydstep = timestepLT(); - - /* Compute pumping energy */ - if (Dur == 0) addenergy(0); - else if (Htime < Dur) addenergy(hydstep); - - /* Update current time. */ - if (Htime < Dur) /* More time remains */ + /* if needed, push forward hydraulic simulation, similar to runqual() */ + if (Qtime == Htime) { - Htime += hydstep; + if ( (errcode = runhyd(&hydtime)) || + (errcode = nexthydLT(&hydstep)) + ) return errcode; + /* If simulating WQ: */ + if (Qualflag != NONE && Qtime < Dur) { + + /* Compute reaction rate coeffs. */ + if (Reactflag && Qualflag != AGE) ratecoeffs(); + + /* Initialize pipe segments (at time 0) or */ + /* else re-orient segments if flow reverses.*/ + if (Qtime == 0) initsegs(); + else reorientsegs(); + } + Htime = hydtime + hydstep; } - else - { - Htime++; /* Force completion of analysis */ - } - *tstep = hydstep; + *pstime = Htime; + hydstep = Htime - Qtime; + + /* Perform water quality routing over this time step */ + if (Qualflag != NONE && hydstep > 0) transport(hydstep); + + updateTanklevels(); + /* Update current time */ + if (OutOfMemory) errcode = 101; + if (!errcode) *ptstep = hydstep; + Qtime += hydstep; + + /* Save final output if no more time steps */ + if (!errcode && Saveflag && *ptstep == 0) errcode = savefinaloutput(); return(errcode); + } - -void updateTanklevels() { - int i,n; +int DLLEXPORT ENrunstepHQ(long* pstime /* Simulation time pointer */ + ,long* ptleft /* Time left in the simulation*/) { - for (i=1; i<=Ntanks; i++) - { - - /* Skip reservoirs */ - if (Tank[i].A == 0.0) continue; +/* The LemonTiger equivalence of ENstepQ, hydraulic solver is called on-demand */ - n = Tank[i].Node; - /* Check if tank full/empty within next second */ - if (Tank[i].V + D[n] >= Tank[i].Vmax) Tank[i].V = Tank[i].Vmax; - if (Tank[i].V - D[n] <= Tank[i].Vmin) Tank[i].V = Tank[i].Vmin; - - H[n] = tankgrade(i,Tank[i].V); - } -} - -int ENrunstepHQ(long* pstime /* Simulation time pointer */ - , long* ptleft /* Time left in the simulation*/) { long hydtime; /* Hydraulic solution time */ long hydstep; /* Hydraulic time step */ int errcode = 0; @@ -224,7 +188,8 @@ int ENrunstepHQ(long* pstime /* Simulation time pointer */ return(errcode); } -int ENcloseHQ() { + +int DLLEXPORT ENcloseHQ() { int errcode = 0; if ( (errcode = ENcloseQ()) || (errcode = ENcloseH()) ) return errcode; @@ -232,5 +197,85 @@ int ENcloseHQ() { } + + +long timestepLT(void) { +/* computes time step to advance hydraulic simulation, but don't + update tank levels. Instead, let nextqual() do the job. */ + long n,t,tstep; + + /* Normal time step is hydraulic time step */ + tstep = Hstep; + + /* Revise time step based on time until next demand period */ + n = ((Htime+Pstart)/Pstep) + 1; /* Next pattern period */ + t = n*Pstep - Htime; /* Time till next period */ + if (t > 0 && t < tstep) tstep = t; + + /* Revise time step based on time until next reporting period */ + t = Rtime - Htime; + if (t > 0 && t < tstep) tstep = t; + + /* Revise time step based on smallest time to fill or drain a tank */ + tanktimestep(&tstep); + + /* Revise time step based on smallest time to activate a control */ + controltimestep(&tstep); + + /* Evaluate rule-based controls (which will also update tank levels) */ + if (Nrules > 0) ruletimestep(&tstep); + + return(tstep); +} + + +int nexthydLT(long *tstep) { +/* finds length of next time step but don't updates tank volumnes and tank + levels and rule-based contol actions. don't save + results to hydraulics file. don't consider Report time. */ + long hydstep; /* Actual time step */ + int errcode = 0; /* Error code */ + + if (Haltflag) Htime = Dur; + + /* Compute next time step & update tank levels */ + *tstep = 0; + hydstep = 0; + if (Htime < Dur) hydstep = timestepLT(); + + /* Compute pumping energy */ + if (Dur == 0) addenergy(0); + else if (Htime < Dur) addenergy(hydstep); + + /* Update current time. */ + if (Htime < Dur) /* More time remains */ + { + Htime += hydstep; + } + else + { + Htime++; /* Force completion of analysis */ + } + *tstep = hydstep; + return(errcode); +} + + +void updateTanklevels() { //Prior to doing hydraulic simulation, update the tank levels + int i,n; + for (i=1; i<=Ntanks; i++) { + /* Skip reservoirs */ + if (Tank[i].A == 0.0) continue; + + n = Tank[i].Node; + /* Check if tank full/empty within next second */ + if (Tank[i].V + D[n] >= Tank[i].Vmax) Tank[i].V = Tank[i].Vmax; + if (Tank[i].V - D[n] <= Tank[i].Vmin) Tank[i].V = Tank[i].Vmin; + + H[n] = tankgrade(i,Tank[i].V); + } +} + + \ No newline at end of file diff --git a/src/lemontiger.h b/src/lemontiger.h index 885f429..c4d8787 100644 --- a/src/lemontiger.h +++ b/src/lemontiger.h @@ -1,11 +1,239 @@ #ifndef LEMONTIGER_H #define LEMONTIGER_H -int ENopeninitHQ(); +/*The header file to be included for USING Epanet LemonTiger DLL on WINDOWS platforms, +all original Epanet functions remain intact, and the new LT_functions are added. */ -int ENrunstepHQ(long*, long*); +/*Note that this file is not used by the functions in the toolkit itself. +Refer to toolkit.h for the internally used function declarations. */ + +#define DLLIMPORT __declspec(dllimport) + +// --- Define the EPANET toolkit constants + +#define EN_ELEVATION 0 /* Node parameters */ +#define EN_BASEDEMAND 1 +#define EN_PATTERN 2 +#define EN_EMITTER 3 +#define EN_INITQUAL 4 +#define EN_SOURCEQUAL 5 +#define EN_SOURCEPAT 6 +#define EN_SOURCETYPE 7 +#define EN_TANKLEVEL 8 +#define EN_DEMAND 9 +#define EN_HEAD 10 +#define EN_PRESSURE 11 +#define EN_QUALITY 12 +#define EN_SOURCEMASS 13 +#define EN_INITVOLUME 14 +#define EN_MIXMODEL 15 +#define EN_MIXZONEVOL 16 + +#define EN_TANKDIAM 17 +#define EN_MINVOLUME 18 +#define EN_VOLCURVE 19 +#define EN_MINLEVEL 20 +#define EN_MAXLEVEL 21 +#define EN_MIXFRACTION 22 +#define EN_TANK_KBULK 23 + +#define EN_TANKVOLUME 24 /* TNT */ + +#define EN_DIAMETER 0 /* Link parameters */ +#define EN_LENGTH 1 +#define EN_ROUGHNESS 2 +#define EN_MINORLOSS 3 +#define EN_INITSTATUS 4 +#define EN_INITSETTING 5 +#define EN_KBULK 6 +#define EN_KWALL 7 +#define EN_FLOW 8 +#define EN_VELOCITY 9 +#define EN_HEADLOSS 10 +#define EN_STATUS 11 +#define EN_SETTING 12 +#define EN_ENERGY 13 +#define EN_LINKQUAL 14 /* TNT */ + +#define EN_DURATION 0 /* Time parameters */ +#define EN_HYDSTEP 1 +#define EN_QUALSTEP 2 +#define EN_PATTERNSTEP 3 +#define EN_PATTERNSTART 4 +#define EN_REPORTSTEP 5 +#define EN_REPORTSTART 6 +#define EN_RULESTEP 7 +#define EN_STATISTIC 8 +#define EN_PERIODS 9 +#define EN_STARTTIME 10 /* Added TNT 10/2/2009 */ + +#define EN_NODECOUNT 0 /* Component counts */ +#define EN_TANKCOUNT 1 +#define EN_LINKCOUNT 2 +#define EN_PATCOUNT 3 +#define EN_CURVECOUNT 4 +#define EN_CONTROLCOUNT 5 + +#define EN_JUNCTION 0 /* Node types */ +#define EN_RESERVOIR 1 +#define EN_TANK 2 + +#define EN_CVPIPE 0 /* Link types */ +#define EN_PIPE 1 +#define EN_PUMP 2 +#define EN_PRV 3 +#define EN_PSV 4 +#define EN_PBV 5 +#define EN_FCV 6 +#define EN_TCV 7 +#define EN_GPV 8 + +#define EN_NONE 0 /* Quality analysis types */ +#define EN_CHEM 1 +#define EN_AGE 2 +#define EN_TRACE 3 + +#define EN_CONCEN 0 /* Source quality types */ +#define EN_MASS 1 +#define EN_SETPOINT 2 +#define EN_FLOWPACED 3 + +#define EN_CFS 0 /* Flow units types */ +#define EN_GPM 1 +#define EN_MGD 2 +#define EN_IMGD 3 +#define EN_AFD 4 +#define EN_LPS 5 +#define EN_LPM 6 +#define EN_MLD 7 +#define EN_CMH 8 +#define EN_CMD 9 + +#define EN_TRIALS 0 /* Misc. options */ +#define EN_ACCURACY 1 +#define EN_TOLERANCE 2 +#define EN_EMITEXPON 3 +#define EN_DEMANDMULT 4 + +#define EN_LOWLEVEL 0 /* Control types */ +#define EN_HILEVEL 1 +#define EN_TIMER 2 +#define EN_TIMEOFDAY 3 + +#define EN_AVERAGE 1 /* Time statistic types. */ +#define EN_MINIMUM 2 +#define EN_MAXIMUM 3 +#define EN_RANGE 4 + +#define EN_MIX1 0 /* Tank mixing models */ +#define EN_MIX2 1 +#define EN_FIFO 2 +#define EN_LIFO 3 + +#define EN_NOSAVE 0 /* Save-results-to-file flag */ +#define EN_SAVE 1 +#define EN_INITFLOW 10 /* Re-initialize flow flag */ + +// --- declare the EPANET toolkit functions + +#ifdef __cplusplus +extern "C" { +#endif + + int DLLIMPORT ENepanet(char *, char *, char *, void (*) (char *)); + int DLLIMPORT ENopen(char *, char *, char *); + int DLLIMPORT ENsaveinpfile(char *); + int DLLIMPORT ENclose(void); + + int DLLIMPORT ENsolveH(void); + int DLLIMPORT ENsaveH(void); + int DLLIMPORT ENopenH(void); + int DLLIMPORT ENinitH(int); + int DLLIMPORT ENrunH(long *); + int DLLIMPORT ENnextH(long *); + int DLLIMPORT ENcloseH(void); + int DLLIMPORT ENsavehydfile(char *); + int DLLIMPORT ENusehydfile(char *); + + int DLLIMPORT ENsolveQ(void); + int DLLIMPORT ENopenQ(void); + int DLLIMPORT ENinitQ(int); + int DLLIMPORT ENrunQ(long *); + int DLLIMPORT ENnextQ(long *); + int DLLIMPORT ENstepQ(long *); + int DLLIMPORT ENcloseQ(void); + + int DLLIMPORT ENwriteline(char *); + int DLLIMPORT ENreport(void); + int DLLIMPORT ENresetreport(void); + int DLLIMPORT ENsetreport(char *); + + int DLLIMPORT ENgetcontrol(int, int *, int *, float *, + int *, float *); + int DLLIMPORT ENgetcount(int, int *); + int DLLIMPORT ENgetoption(int, float *); + int DLLIMPORT ENgettimeparam(int, long *); + int DLLIMPORT ENgetflowunits(int *); + int DLLIMPORT ENgetpatternindex(char *, int *); + int DLLIMPORT ENgetpatternid(int, char *); + int DLLIMPORT ENgetpatternlen(int, int *); + int DLLIMPORT ENgetpatternvalue(int, int, float *); + int DLLIMPORT ENgetqualtype(int *, int *); + int DLLIMPORT ENgeterror(int, char *, int); + + int DLLIMPORT ENgetnodeindex(char *, int *); + int DLLIMPORT ENgetnodeid(int, char *); + int DLLIMPORT ENgetnodetype(int, int *); + int DLLIMPORT ENgetnodevalue(int, int, float *); + + int DLLIMPORT ENgetnumdemands(int, int *); + int DLLIMPORT ENgetbasedemand(int, int, float *); + int DLLIMPORT ENgetdemandpattern(int, int, int *); + + int DLLIMPORT ENgetlinkindex(char *, int *); + int DLLIMPORT ENgetlinkid(int, char *); + int DLLIMPORT ENgetlinktype(int, int *); + int DLLIMPORT ENgetlinknodes(int, int *, int *); + int DLLIMPORT ENgetlinkvalue(int, int, float *); + + int DLLIMPORT ENgetcurve(int curveIndex, int *nValues, float **xValues, float **yValues); + + int DLLIMPORT ENgetversion(int *); + + int DLLIMPORT ENsetcontrol(int, int, int, float, int, float); + int DLLIMPORT ENsetnodevalue(int, int, float); + int DLLIMPORT ENsetlinkvalue(int, int, float); + int DLLIMPORT ENaddpattern(char *); + int DLLIMPORT ENsetpattern(int, float *, int); + int DLLIMPORT ENsetpatternvalue(int, int, float); + int DLLIMPORT ENsettimeparam(int, long); + int DLLIMPORT ENsetoption(int, float); + int DLLIMPORT ENsetstatusreport(int); + int DLLIMPORT ENsetqualtype(int, char *, char *, char *); + + //LemonTiger functions + /* See testLT.c for a LemonTiger test */ + + //LT equivalent to ENopenH() + ENopenQ() + ENinitH() + ENinitQ() + int DLLIMPORT ENopeninitHQ(); + + //LT equivalent to ENrunQ() + ENnextQ(); + int DLLIMPORT ENrunnextHQ(long*, long*); + + //LT equivalent to ENrunQ() + ENstepQ(); + int DLLIMPORT ENrunstepHQ(long*, long*); + + //LT equivalent to ENcloseH() + ENcloseQ(); + int DLLIMPORT ENcloseHQ(); + + +#ifdef __cplusplus +}; +#endif + + + +#endif //LEMONTIGER_H -int ENcloseHQ(); -#endif \ No newline at end of file diff --git a/src/testLT.c b/src/testLT.c index ba173b8..9729186 100644 --- a/src/testLT.c +++ b/src/testLT.c @@ -5,7 +5,6 @@ #include #include "types.h" #include "vars.h" -#include "toolkit.h" #include "lemontiger.h" @@ -54,6 +53,7 @@ int main(int argc, char* argv[]) { printf("\nReset time pointer and run WQ.\n"); for (step=1, ENopenQ(), ENinitQ(0); // this operation resets the internal time pointer (back to 0) step>0; ENnextQ(&step)) { + ENrunQ(&stime); @@ -77,10 +77,10 @@ int main(int argc, char* argv[]) { if (err=ENopen(argv[1], argv[2], "")) return err; for (ENopeninitHQ(), tleft=Dur; tleft>0; ) { - ENrunstepHQ(&stime, &tleft); - - + //ENrunstepHQ(&stime, &tleft); + ENrunnextHQ(&stime, &tleft); //well I know it should be tstep + if (stime == TIME_A || stime == TIME_B || stime == TIME_C) { //if (! (stime%1800)){ printf("Simulation = %d sec, time left = %d sec.\n", stime, tleft); diff --git a/src/toolkit.h b/src/toolkit.h index 3e0501b..87b0a9b 100755 --- a/src/toolkit.h +++ b/src/toolkit.h @@ -20,28 +20,13 @@ AUTHOR: L. Rossman /*** New compile directives ***/ //(2.00.11 - LR) //#define CLE /* Compile as a command line executable */ -#define CLE_LT /* LemonTiger test */ //#define SOL /* Compile as a shared object library */ //#define DLL /* Compile as a Windows DLL */ +//#define CLE_LT /* LemonTiger test */ //Jinduan Chen +#define DLL_LT /* Compile as a Windows DLL of LemonTiger */ -#ifndef DLLEXPORT - #ifdef DLL - #ifdef __cplusplus - #define DLLEXPORT extern "C" __declspec(dllexport) - #else - #define DLLEXPORT __declspec(dllexport) - #endif - #elif defined(CYGWIN) - #define DLLEXPORT __stdcall - #else - #ifdef __cplusplus - #define DLLEXPORT - #else - #define DLLEXPORT - #endif - #endif -#endif +#define DLLEXPORT __declspec(dllexport) // --- Define the EPANET toolkit constants @@ -253,8 +238,23 @@ extern "C" { int DLLEXPORT ENsetstatusreport(int); int DLLEXPORT ENsetqualtype(int, char *, char *, char *); + //LemonTiger functions + /* See testLT.c for a LemonTiger test */ + + //LT equivalent to ENopenH() + ENopenQ() + ENinitH() + ENinitQ() + int DLLEXPORT ENopeninitHQ(); + + //LT equivalent to ENrunQ() + ENnextQ(); + int DLLEXPORT ENrunnextHQ(long*, long*); + + //LT equivalent to ENrunQ() + ENstepQ(); + int DLLEXPORT ENrunstepHQ(long*, long*); + + //LT equivalent to ENcloseH() + ENcloseQ(); + int DLLEXPORT ENcloseHQ(); + #if defined(__cplusplus) } #endif -#endif \ No newline at end of file +#endif //TOOLKIT_H \ No newline at end of file From a95576cb1e43bd155390e957d122db57f4e412ff Mon Sep 17 00:00:00 2001 From: Sam Hatchett Date: Fri, 25 Jan 2013 09:47:30 -0500 Subject: [PATCH 07/49] project settings --- .../epanet/epanet.xcodeproj/project.pbxproj | 138 +++++++++++++++++- 1 file changed, 134 insertions(+), 4 deletions(-) diff --git a/build/Xcode/epanet/epanet.xcodeproj/project.pbxproj b/build/Xcode/epanet/epanet.xcodeproj/project.pbxproj index 59a4a81..55a8f5a 100644 --- a/build/Xcode/epanet/epanet.xcodeproj/project.pbxproj +++ b/build/Xcode/epanet/epanet.xcodeproj/project.pbxproj @@ -42,7 +42,10 @@ 22322FA51068369500641384 /* rules.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F7F1068369500641384 /* rules.c */; }; 22322FA61068369500641384 /* smatrix.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F801068369500641384 /* smatrix.c */; }; 22322FAA106836BC00641384 /* epanet2.h in Headers */ = {isa = PBXBuildFile; fileRef = 22322FA9106836B000641384 /* epanet2.h */; }; - 22322FAE106836D900641384 /* malloc.h in Headers */ = {isa = PBXBuildFile; fileRef = 22322FAD106836D900641384 /* malloc.h */; }; + 2298EBDA16B17B8E0088A6DC /* libepanet.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = D2AAC0630554660B00DB518D /* libepanet.dylib */; }; + 2298EBDE16B17DE50088A6DC /* testLT.c in Sources */ = {isa = PBXBuildFile; fileRef = 2298EBDC16B17DCE0088A6DC /* testLT.c */; }; + 2298EBE116B17E440088A6DC /* lemontiger.c in Sources */ = {isa = PBXBuildFile; fileRef = 2298EBDF16B17E440088A6DC /* lemontiger.c */; }; + 2298EBE216B17E440088A6DC /* lemontiger.h in Headers */ = {isa = PBXBuildFile; fileRef = 2298EBE016B17E440088A6DC /* lemontiger.h */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -53,8 +56,27 @@ remoteGlobalIDString = D2AAC0620554660B00DB518D; remoteInfo = epanet; }; + 2298EBD816B17B830088A6DC /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = D2AAC0620554660B00DB518D; + remoteInfo = epanet; + }; /* End PBXContainerItemProxy section */ +/* Begin PBXCopyFilesBuildPhase section */ + 2298EBC816B178E70088A6DC /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = /usr/share/man/man1/; + dstSubfolderSpec = 0; + files = ( + ); + runOnlyForDeploymentPostprocessing = 1; + }; +/* End PBXCopyFilesBuildPhase section */ + /* Begin PBXFileReference section */ 22322F66106833BB00641384 /* runepanet */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = runepanet; sourceTree = BUILT_PRODUCTS_DIR; }; 22322F701068369500641384 /* enumstxt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = enumstxt.h; path = ../../../src/enumstxt.h; sourceTree = SOURCE_ROOT; }; @@ -79,7 +101,10 @@ 22322F831068369500641384 /* types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = types.h; path = ../../../src/types.h; sourceTree = SOURCE_ROOT; }; 22322F841068369500641384 /* vars.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = vars.h; path = ../../../src/vars.h; sourceTree = SOURCE_ROOT; }; 22322FA9106836B000641384 /* epanet2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = epanet2.h; path = ../../../include/epanet2.h; sourceTree = SOURCE_ROOT; }; - 22322FAD106836D900641384 /* malloc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = malloc.h; path = macinclude/malloc.h; sourceTree = ""; }; + 2298EBCA16B178E70088A6DC /* testLemonTiger */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testLemonTiger; sourceTree = BUILT_PRODUCTS_DIR; }; + 2298EBDC16B17DCE0088A6DC /* testLT.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = testLT.c; path = ../../../src/testLT.c; sourceTree = ""; }; + 2298EBDF16B17E440088A6DC /* lemontiger.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lemontiger.c; path = ../../../src/lemontiger.c; sourceTree = ""; }; + 2298EBE016B17E440088A6DC /* lemontiger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lemontiger.h; path = ../../../src/lemontiger.h; sourceTree = ""; }; D2AAC0630554660B00DB518D /* libepanet.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libepanet.dylib; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ @@ -91,6 +116,14 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 2298EBC716B178E70088A6DC /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 2298EBDA16B17B8E0088A6DC /* libepanet.dylib in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; D289988505E68E00004EDB86 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -104,6 +137,7 @@ 08FB7794FE84155DC02AAC07 /* epanet */ = { isa = PBXGroup; children = ( + 2298EBDB16B17DBD0088A6DC /* LemonTiger */, 22322FA8106836A000641384 /* Include */, 08FB7795FE84155DC02AAC07 /* Source */, 1AB674ADFE9D54B511CA2CBB /* Products */, @@ -144,6 +178,7 @@ children = ( D2AAC0630554660B00DB518D /* libepanet.dylib */, 22322F66106833BB00641384 /* runepanet */, + 2298EBCA16B178E70088A6DC /* testLemonTiger */, ); name = Products; sourceTree = ""; @@ -151,12 +186,21 @@ 22322FA8106836A000641384 /* Include */ = { isa = PBXGroup; children = ( - 22322FAD106836D900641384 /* malloc.h */, 22322FA9106836B000641384 /* epanet2.h */, ); name = Include; sourceTree = ""; }; + 2298EBDB16B17DBD0088A6DC /* LemonTiger */ = { + isa = PBXGroup; + children = ( + 2298EBDF16B17E440088A6DC /* lemontiger.c */, + 2298EBE016B17E440088A6DC /* lemontiger.h */, + 2298EBDC16B17DCE0088A6DC /* testLT.c */, + ); + name = LemonTiger; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ @@ -173,7 +217,7 @@ 22322F971068369500641384 /* toolkit.h in Headers */, 22322F981068369500641384 /* types.h in Headers */, 22322F991068369500641384 /* vars.h in Headers */, - 22322FAE106836D900641384 /* malloc.h in Headers */, + 2298EBE216B17E440088A6DC /* lemontiger.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -197,6 +241,24 @@ productReference = 22322F66106833BB00641384 /* runepanet */; productType = "com.apple.product-type.tool"; }; + 2298EBC916B178E70088A6DC /* testLemonTiger */ = { + isa = PBXNativeTarget; + buildConfigurationList = 2298EBD116B178E70088A6DC /* Build configuration list for PBXNativeTarget "testLemonTiger" */; + buildPhases = ( + 2298EBC616B178E70088A6DC /* Sources */, + 2298EBC716B178E70088A6DC /* Frameworks */, + 2298EBC816B178E70088A6DC /* CopyFiles */, + ); + buildRules = ( + ); + dependencies = ( + 2298EBD916B17B830088A6DC /* PBXTargetDependency */, + ); + name = testLemonTiger; + productName = testLemonTiger; + productReference = 2298EBCA16B178E70088A6DC /* testLemonTiger */; + productType = "com.apple.product-type.tool"; + }; D2AAC0620554660B00DB518D /* epanet */ = { isa = PBXNativeTarget; buildConfigurationList = 1DEB914A08733D8E0010E9CD /* Build configuration list for PBXNativeTarget "epanet" */; @@ -235,6 +297,7 @@ targets = ( D2AAC0620554660B00DB518D /* epanet */, 22322F65106833BB00641384 /* runepanet */, + 2298EBC916B178E70088A6DC /* testLemonTiger */, ); }; /* End PBXProject section */ @@ -260,6 +323,14 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 2298EBC616B178E70088A6DC /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 2298EBDE16B17DE50088A6DC /* testLT.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; D2AAC0610554660B00DB518D /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -277,6 +348,7 @@ 22322F931068369500641384 /* report.c in Sources */, 22322F941068369500641384 /* rules.c in Sources */, 22322F951068369500641384 /* smatrix.c in Sources */, + 2298EBE116B17E440088A6DC /* lemontiger.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -288,6 +360,11 @@ target = D2AAC0620554660B00DB518D /* epanet */; targetProxy = 22322FAF1068370B00641384 /* PBXContainerItemProxy */; }; + 2298EBD916B17B830088A6DC /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = D2AAC0620554660B00DB518D /* epanet */; + targetProxy = 2298EBD816B17B830088A6DC /* PBXContainerItemProxy */; + }; /* End PBXTargetDependency section */ /* Begin XCBuildConfiguration section */ @@ -388,6 +465,51 @@ }; name = Release; }; + 2298EBD216B178E70088A6DC /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_64_BIT)"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_OBJC_EXCEPTIONS = YES; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + MACOSX_DEPLOYMENT_TARGET = 10.8; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + }; + name = Debug; + }; + 2298EBD316B178E70088A6DC /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_64_BIT)"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_ENABLE_OBJC_EXCEPTIONS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + MACOSX_DEPLOYMENT_TARGET = 10.8; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + }; + name = Release; + }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ @@ -418,6 +540,14 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + 2298EBD116B178E70088A6DC /* Build configuration list for PBXNativeTarget "testLemonTiger" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 2298EBD216B178E70088A6DC /* Debug */, + 2298EBD316B178E70088A6DC /* Release */, + ); + defaultConfigurationIsVisible = 0; + }; /* End XCConfigurationList section */ }; rootObject = 08FB7793FE84155DC02AAC07 /* Project object */; From 4f693792c85fcdda64e578f0087da95efe4e2d6c Mon Sep 17 00:00:00 2001 From: Sam Hatchett Date: Thu, 31 Jan 2013 15:13:40 -0500 Subject: [PATCH 08/49] housekeeping - JC will need to fix this moved visual studio project to its own build directory, added to gitignore so we're not versioning the build products. i don't do windows, so Jinduan will have to make sure everything still works with this directory structure. --- .gitignore | 2 +- Debug/LemonTigerJ.dll | Bin 282112 -> 0 bytes Debug/LemonTigerJ.lastbuildstate | 2 -- Debug/LemonTigerJ.lib | Bin 13646 -> 0 bytes Debug/LemonTigerJ.log | 27 ------------------ LemonTigerJ.v11.suo | Bin 72704 -> 0 bytes LemonTigerJ.sln => build/MSVS/LemonTigerJ.sln | 0 .../MSVS/LemonTigerJ.vcxproj | 0 8 files changed, 1 insertion(+), 30 deletions(-) delete mode 100644 Debug/LemonTigerJ.dll delete mode 100644 Debug/LemonTigerJ.lastbuildstate delete mode 100644 Debug/LemonTigerJ.lib delete mode 100644 Debug/LemonTigerJ.log delete mode 100644 LemonTigerJ.v11.suo rename LemonTigerJ.sln => build/MSVS/LemonTigerJ.sln (100%) rename LemonTigerJ.vcxproj => build/MSVS/LemonTigerJ.vcxproj (100%) diff --git a/.gitignore b/.gitignore index 2167a2a..d13078d 100644 --- a/.gitignore +++ b/.gitignore @@ -118,6 +118,6 @@ xcuserdata *.bi *.opensdf test/* - +Debug/ diff --git a/Debug/LemonTigerJ.dll b/Debug/LemonTigerJ.dll deleted file mode 100644 index e15dedf44d1b4441c01cb92089d9759419140ddd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 282112 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

M)i^{QN3E!qVFa;flYcsyo8UQ%TDhB|4JZQ@J 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�>9WXz@C34;kKNR{l1?dKM&;lgZ62E^ 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

Q?jVIQYay;P3XDorVbZBhvVa*)ct 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 O0TR6)|6BSxfH*aU0c?`hRzX}dFBxX zjSrn(Qd!l&s18gjvyHGNg_X!S#`nCfCdevjh&CSM4YZv!Qk!Js*udR`^h#GWo~4XF zR&kZDONUv3HTC7mGDWaql+Of9V$3EsJJGekx(SBF&YwOvvfknwpFI)p4?*dQ(kYc4 zV@lbfbV`~W0D#?v2oag&{3{-ppQ+zRVFW+YC%-4JjC>NRsMfx9OT+#7@ zZHjxPL^)E7A4ygu*pS$ziCl=Xk#?eUlF&?6(_PtQN5+_ZiI|0W8_hOhdwO!A#My}}-6(6fQhdq_WKbvwA|7?G=^iWF9+V}mJ+HYEVsO)=W z$H`NrTrrhm`d!A~S?~w3_iNb$VbZ1Si+Xx4_=3n6JEe*mQ+Z-Tam7oBoDijp+2x{s z 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 "C:\Users\owner\Documents\GitHub\epanet\LemonTigerJ.vcxproj" on node 2 (Build target(s)). - 1>ClCompile: - C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\bin\CL.exe /c /I.\include /Zi /nologo /W3 /WX- /Od /Oy- /D WIN32 /D _DEBUG /D _CONSOLE /D _WINDLL /D _CRT_SECURE_NO_WARNINGS /Gm /EHsc /RTC1 /MDd /GS /fp:precise /Zc:wchar_t /Zc:forScope /Fo"Debug\\" /Fd"Debug\vc110.pdb" /Gd /TC /analyze- /errorReport:prompt src\testLT.c - testLT.c - Link: - C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\bin\link.exe /ERRORREPORT:PROMPT /OUT:"C:\Users\owner\Documents\GitHub\epanet\Debug\LemonTigerJ.dll" /INCREMENTAL /NOLOGO kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /MANIFEST /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /manifest:embed /DEBUG /PDB:"C:\Users\owner\Documents\GitHub\epanet\Debug\LemonTigerJ.pdb" /SUBSYSTEM:CONSOLE /TLBID:1 /DYNAMICBASE /NXCOMPAT /IMPLIB:"C:\Users\owner\Documents\GitHub\epanet\Debug\LemonTigerJ.lib" /MACHINE:X86 /DLL Debug\epanet.obj - Debug\hash.obj - Debug\hydraul.obj - Debug\inpfile.obj - Debug\input1.obj - Debug\input2.obj - Debug\input3.obj - Debug\lemontiger.obj - Debug\mempool.obj - Debug\output.obj - Debug\quality.obj - Debug\report.obj - Debug\rules.obj - Debug\smatrix.obj - Debug\testLT.obj - LemonTigerJ.vcxproj -> C:\Users\owner\Documents\GitHub\epanet\Debug\LemonTigerJ.dll - 1>Done Building Project "C:\Users\owner\Documents\GitHub\epanet\LemonTigerJ.vcxproj" (Build target(s)). - -Build succeeded. - -Time Elapsed 00:00:01.13 diff --git a/LemonTigerJ.v11.suo b/LemonTigerJ.v11.suo deleted file mode 100644 index d4ca826e770732d11d05cbf7ba46270d963711ba..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 72704 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 Date: Thu, 31 Jan 2013 15:30:07 -0500 Subject: [PATCH 09/49] apple define, some cleanup - apple / *nix defines out the DLL[EX/IM]PORT directives - we should be using dox markup (see ENrunnexHQ for example) --- src/lemontiger.c | 75 ++++++++++++++++++++++++++---------------------- src/lemontiger.h | 8 ++++-- src/toolkit.h | 8 ++++-- 3 files changed, 51 insertions(+), 40 deletions(-) diff --git a/src/lemontiger.c b/src/lemontiger.c index 7d6d447..62f2022 100644 --- a/src/lemontiger.c +++ b/src/lemontiger.c @@ -47,48 +47,55 @@ int nexthydLT(long *tstep); void updateTanklevels(); //Prior to running hydraulic simulation, update the tank levels. -int DLLEXPORT ENrunnextHQ(long* pstime, /*Simulation time pointer*/ - long* ptstep /*next time step*/ ) { -/* The lemonTiger equivalent of ENnextQ, hydraulic solver is called on-demand*/ - long hydtime; /* Hydraulic solution time */ - long hydstep; /* Hydraulic time step */ - int errcode = 0; - - /* if needed, push forward hydraulic simulation, similar to runqual() */ - if (Qtime == Htime) - { - if ( (errcode = runhyd(&hydtime)) || - (errcode = nexthydLT(&hydstep)) - ) return errcode; - /* If simulating WQ: */ - if (Qualflag != NONE && Qtime < Dur) { +/*! + \fn int ENrunnexHQ( long* simTimePtr, long* timeStepPtr ) + \brief equivalent of ENnextQ, hydraulic solver is called on-demand + \param simTimePtr Simulation time (output variable). + \param timeStepPtr Time to next time step boundary (output variable). + \return on error, an error code + */ +int DLLEXPORT ENrunnextHQ(long* simTimePtr, long* timeStepPtr) { + /* The lemonTiger equivalent of ENnextQ, hydraulic solver is called on-demand*/ + long hydtime; /* Hydraulic solution time */ + long hydstep; /* Hydraulic time step */ + int errcode = 0; + + /* if needed, push forward hydraulic simulation, similar to runqual() */ + if (Qtime == Htime) + { + if ( (errcode = runhyd(&hydtime)) || (errcode = nexthydLT(&hydstep)) ) { + return errcode; + } + /* If simulating WQ: */ + if (Qualflag != NONE && Qtime < Dur) { + /* Compute reaction rate coeffs. */ if (Reactflag && Qualflag != AGE) ratecoeffs(); - + /* Initialize pipe segments (at time 0) or */ /* else re-orient segments if flow reverses.*/ if (Qtime == 0) initsegs(); else reorientsegs(); } - Htime = hydtime + hydstep; - } - *pstime = Htime; - hydstep = Htime - Qtime; - - /* Perform water quality routing over this time step */ - if (Qualflag != NONE && hydstep > 0) transport(hydstep); - - updateTanklevels(); - /* Update current time */ - if (OutOfMemory) errcode = 101; - if (!errcode) *ptstep = hydstep; - Qtime += hydstep; - - /* Save final output if no more time steps */ - if (!errcode && Saveflag && *ptstep == 0) errcode = savefinaloutput(); - return(errcode); - + Htime = hydtime + hydstep; + } + *simTimePtr = Htime; + hydstep = Htime - Qtime; + + /* Perform water quality routing over this time step */ + if (Qualflag != NONE && hydstep > 0) transport(hydstep); + + updateTanklevels(); + /* Update current time */ + if (OutOfMemory) errcode = 101; + if (!errcode) *timeStepPtr = hydstep; + Qtime += hydstep; + + /* Save final output if no more time steps */ + if (!errcode && Saveflag && *timeStepPtr == 0) errcode = savefinaloutput(); + return(errcode); + } int DLLEXPORT ENrunstepHQ(long* pstime /* Simulation time pointer */ diff --git a/src/lemontiger.h b/src/lemontiger.h index c4d8787..cdb6585 100644 --- a/src/lemontiger.h +++ b/src/lemontiger.h @@ -6,9 +6,11 @@ all original Epanet functions remain intact, and the new LT_functions are added. /*Note that this file is not used by the functions in the toolkit itself. Refer to toolkit.h for the internally used function declarations. */ - -#define DLLIMPORT __declspec(dllimport) - +#ifdef __APPLE__ + #define DLLIMPORT +#else + #define DLLIMPORT __declspec(dllimport) +#endif // --- Define the EPANET toolkit constants #define EN_ELEVATION 0 /* Node parameters */ diff --git a/src/toolkit.h b/src/toolkit.h index 87b0a9b..1abb018 100755 --- a/src/toolkit.h +++ b/src/toolkit.h @@ -25,9 +25,11 @@ AUTHOR: L. Rossman //#define CLE_LT /* LemonTiger test */ //Jinduan Chen #define DLL_LT /* Compile as a Windows DLL of LemonTiger */ - -#define DLLEXPORT __declspec(dllexport) - +#ifdef __APPLE__ + #define DLLEXPORT +#else + #define DLLEXPORT __declspec(dllexport) +#endif // --- Define the EPANET toolkit constants #define EN_ELEVATION 0 /* Node parameters */ From d9eebbbcf0a092e0c28d99c5c20e647f45e530ad Mon Sep 17 00:00:00 2001 From: Sam Hatchett Date: Thu, 31 Jan 2013 15:30:46 -0500 Subject: [PATCH 10/49] whoops, dox misspelling --- src/lemontiger.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lemontiger.c b/src/lemontiger.c index 62f2022..c4a2ed8 100644 --- a/src/lemontiger.c +++ b/src/lemontiger.c @@ -49,7 +49,7 @@ void updateTanklevels(); /*! - \fn int ENrunnexHQ( long* simTimePtr, long* timeStepPtr ) + \fn int ENrunnextHQ( long* simTimePtr, long* timeStepPtr ) \brief equivalent of ENnextQ, hydraulic solver is called on-demand \param simTimePtr Simulation time (output variable). \param timeStepPtr Time to next time step boundary (output variable). From 7a5e7feb2d77b534dad93254b3817ccf13edea51 Mon Sep 17 00:00:00 2001 From: Sam Hatchett Date: Thu, 31 Jan 2013 15:40:12 -0500 Subject: [PATCH 11/49] cool, lemontiger works on mac - removed CLE_LT def -- what was that for? --- .../epanet/epanet.xcodeproj/project.pbxproj | 31 +++++++++++++++++-- src/testLT.c | 3 +- 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/build/Xcode/epanet/epanet.xcodeproj/project.pbxproj b/build/Xcode/epanet/epanet.xcodeproj/project.pbxproj index 55a8f5a..36e011b 100644 --- a/build/Xcode/epanet/epanet.xcodeproj/project.pbxproj +++ b/build/Xcode/epanet/epanet.xcodeproj/project.pbxproj @@ -42,7 +42,20 @@ 22322FA51068369500641384 /* rules.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F7F1068369500641384 /* rules.c */; }; 22322FA61068369500641384 /* smatrix.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F801068369500641384 /* smatrix.c */; }; 22322FAA106836BC00641384 /* epanet2.h in Headers */ = {isa = PBXBuildFile; fileRef = 22322FA9106836B000641384 /* epanet2.h */; }; - 2298EBDA16B17B8E0088A6DC /* libepanet.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = D2AAC0630554660B00DB518D /* libepanet.dylib */; }; + 227CECA016BB0D5E00E8E7C8 /* lemontiger.c in Sources */ = {isa = PBXBuildFile; fileRef = 2298EBDF16B17E440088A6DC /* lemontiger.c */; }; + 227CECA116BB0D5E00E8E7C8 /* epanet.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F711068369500641384 /* epanet.c */; }; + 227CECA216BB0D5E00E8E7C8 /* hash.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F731068369500641384 /* hash.c */; }; + 227CECA316BB0D5E00E8E7C8 /* hydraul.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F751068369500641384 /* hydraul.c */; }; + 227CECA416BB0D5E00E8E7C8 /* inpfile.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F761068369500641384 /* inpfile.c */; }; + 227CECA516BB0D5E00E8E7C8 /* input1.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F771068369500641384 /* input1.c */; }; + 227CECA616BB0D5E00E8E7C8 /* input2.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F781068369500641384 /* input2.c */; }; + 227CECA716BB0D5E00E8E7C8 /* input3.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F791068369500641384 /* input3.c */; }; + 227CECA816BB0D5E00E8E7C8 /* mempool.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F7A1068369500641384 /* mempool.c */; }; + 227CECA916BB0D5E00E8E7C8 /* output.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F7C1068369500641384 /* output.c */; }; + 227CECAA16BB0D5E00E8E7C8 /* quality.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F7D1068369500641384 /* quality.c */; }; + 227CECAB16BB0D5E00E8E7C8 /* report.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F7E1068369500641384 /* report.c */; }; + 227CECAC16BB0D5E00E8E7C8 /* rules.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F7F1068369500641384 /* rules.c */; }; + 227CECAD16BB0D5E00E8E7C8 /* smatrix.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F801068369500641384 /* smatrix.c */; }; 2298EBDE16B17DE50088A6DC /* testLT.c in Sources */ = {isa = PBXBuildFile; fileRef = 2298EBDC16B17DCE0088A6DC /* testLT.c */; }; 2298EBE116B17E440088A6DC /* lemontiger.c in Sources */ = {isa = PBXBuildFile; fileRef = 2298EBDF16B17E440088A6DC /* lemontiger.c */; }; 2298EBE216B17E440088A6DC /* lemontiger.h in Headers */ = {isa = PBXBuildFile; fileRef = 2298EBE016B17E440088A6DC /* lemontiger.h */; }; @@ -120,7 +133,6 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 2298EBDA16B17B8E0088A6DC /* libepanet.dylib in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -327,6 +339,20 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 227CECA016BB0D5E00E8E7C8 /* lemontiger.c in Sources */, + 227CECA116BB0D5E00E8E7C8 /* epanet.c in Sources */, + 227CECA216BB0D5E00E8E7C8 /* hash.c in Sources */, + 227CECA316BB0D5E00E8E7C8 /* hydraul.c in Sources */, + 227CECA416BB0D5E00E8E7C8 /* inpfile.c in Sources */, + 227CECA516BB0D5E00E8E7C8 /* input1.c in Sources */, + 227CECA616BB0D5E00E8E7C8 /* input2.c in Sources */, + 227CECA716BB0D5E00E8E7C8 /* input3.c in Sources */, + 227CECA816BB0D5E00E8E7C8 /* mempool.c in Sources */, + 227CECA916BB0D5E00E8E7C8 /* output.c in Sources */, + 227CECAA16BB0D5E00E8E7C8 /* quality.c in Sources */, + 227CECAB16BB0D5E00E8E7C8 /* report.c in Sources */, + 227CECAC16BB0D5E00E8E7C8 /* rules.c in Sources */, + 227CECAD16BB0D5E00E8E7C8 /* smatrix.c in Sources */, 2298EBDE16B17DE50088A6DC /* testLT.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -547,6 +573,7 @@ 2298EBD316B178E70088A6DC /* Release */, ); defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; diff --git a/src/testLT.c b/src/testLT.c index 9729186..3af7b68 100644 --- a/src/testLT.c +++ b/src/testLT.c @@ -8,7 +8,7 @@ #include "lemontiger.h" -#ifdef CLE_LT + int main(int argc, char* argv[]) { int err = 0; //error code @@ -110,4 +110,3 @@ int main(int argc, char* argv[]) { } -#endif \ No newline at end of file From 4df40ebc3db02df49d60861461cb40e5aac9bcdf Mon Sep 17 00:00:00 2001 From: Sam Hatchett Date: Fri, 1 Feb 2013 17:19:23 -0500 Subject: [PATCH 12/49] new branch for lemon-tiger with no new api functions --- .../epanet/epanet.xcodeproj/project.pbxproj | 98 ++++++----------- src/testLemonTiger.cpp | 104 ++++++++++++++++++ src/testLemonTiger.h | 14 +++ 3 files changed, 151 insertions(+), 65 deletions(-) create mode 100644 src/testLemonTiger.cpp create mode 100644 src/testLemonTiger.h diff --git a/build/Xcode/epanet/epanet.xcodeproj/project.pbxproj b/build/Xcode/epanet/epanet.xcodeproj/project.pbxproj index 36e011b..ff6645d 100644 --- a/build/Xcode/epanet/epanet.xcodeproj/project.pbxproj +++ b/build/Xcode/epanet/epanet.xcodeproj/project.pbxproj @@ -42,23 +42,9 @@ 22322FA51068369500641384 /* rules.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F7F1068369500641384 /* rules.c */; }; 22322FA61068369500641384 /* smatrix.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F801068369500641384 /* smatrix.c */; }; 22322FAA106836BC00641384 /* epanet2.h in Headers */ = {isa = PBXBuildFile; fileRef = 22322FA9106836B000641384 /* epanet2.h */; }; - 227CECA016BB0D5E00E8E7C8 /* lemontiger.c in Sources */ = {isa = PBXBuildFile; fileRef = 2298EBDF16B17E440088A6DC /* lemontiger.c */; }; - 227CECA116BB0D5E00E8E7C8 /* epanet.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F711068369500641384 /* epanet.c */; }; - 227CECA216BB0D5E00E8E7C8 /* hash.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F731068369500641384 /* hash.c */; }; - 227CECA316BB0D5E00E8E7C8 /* hydraul.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F751068369500641384 /* hydraul.c */; }; - 227CECA416BB0D5E00E8E7C8 /* inpfile.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F761068369500641384 /* inpfile.c */; }; - 227CECA516BB0D5E00E8E7C8 /* input1.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F771068369500641384 /* input1.c */; }; - 227CECA616BB0D5E00E8E7C8 /* input2.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F781068369500641384 /* input2.c */; }; - 227CECA716BB0D5E00E8E7C8 /* input3.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F791068369500641384 /* input3.c */; }; - 227CECA816BB0D5E00E8E7C8 /* mempool.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F7A1068369500641384 /* mempool.c */; }; - 227CECA916BB0D5E00E8E7C8 /* output.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F7C1068369500641384 /* output.c */; }; - 227CECAA16BB0D5E00E8E7C8 /* quality.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F7D1068369500641384 /* quality.c */; }; - 227CECAB16BB0D5E00E8E7C8 /* report.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F7E1068369500641384 /* report.c */; }; - 227CECAC16BB0D5E00E8E7C8 /* rules.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F7F1068369500641384 /* rules.c */; }; - 227CECAD16BB0D5E00E8E7C8 /* smatrix.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F801068369500641384 /* smatrix.c */; }; - 2298EBDE16B17DE50088A6DC /* testLT.c in Sources */ = {isa = PBXBuildFile; fileRef = 2298EBDC16B17DCE0088A6DC /* testLT.c */; }; 2298EBE116B17E440088A6DC /* lemontiger.c in Sources */ = {isa = PBXBuildFile; fileRef = 2298EBDF16B17E440088A6DC /* lemontiger.c */; }; 2298EBE216B17E440088A6DC /* lemontiger.h in Headers */ = {isa = PBXBuildFile; fileRef = 2298EBE016B17E440088A6DC /* lemontiger.h */; }; + 22EF555716BC744C00F3988A /* testLemonTiger.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 22EF555516BC744C00F3988A /* testLemonTiger.cpp */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -69,17 +55,10 @@ remoteGlobalIDString = D2AAC0620554660B00DB518D; remoteInfo = epanet; }; - 2298EBD816B17B830088A6DC /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = D2AAC0620554660B00DB518D; - remoteInfo = epanet; - }; /* End PBXContainerItemProxy section */ /* Begin PBXCopyFilesBuildPhase section */ - 2298EBC816B178E70088A6DC /* CopyFiles */ = { + 22EF554A16BC740400F3988A /* CopyFiles */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; dstPath = /usr/share/man/man1/; @@ -114,10 +93,12 @@ 22322F831068369500641384 /* types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = types.h; path = ../../../src/types.h; sourceTree = SOURCE_ROOT; }; 22322F841068369500641384 /* vars.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = vars.h; path = ../../../src/vars.h; sourceTree = SOURCE_ROOT; }; 22322FA9106836B000641384 /* epanet2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = epanet2.h; path = ../../../include/epanet2.h; sourceTree = SOURCE_ROOT; }; - 2298EBCA16B178E70088A6DC /* testLemonTiger */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testLemonTiger; sourceTree = BUILT_PRODUCTS_DIR; }; 2298EBDC16B17DCE0088A6DC /* testLT.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = testLT.c; path = ../../../src/testLT.c; sourceTree = ""; }; 2298EBDF16B17E440088A6DC /* lemontiger.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lemontiger.c; path = ../../../src/lemontiger.c; sourceTree = ""; }; 2298EBE016B17E440088A6DC /* lemontiger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lemontiger.h; path = ../../../src/lemontiger.h; sourceTree = ""; }; + 22EF554C16BC740400F3988A /* TestLemonTiger */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = TestLemonTiger; sourceTree = BUILT_PRODUCTS_DIR; }; + 22EF555516BC744C00F3988A /* testLemonTiger.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = testLemonTiger.cpp; path = ../../../src/testLemonTiger.cpp; sourceTree = ""; }; + 22EF555616BC744C00F3988A /* testLemonTiger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = testLemonTiger.h; path = ../../../src/testLemonTiger.h; sourceTree = ""; }; D2AAC0630554660B00DB518D /* libepanet.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libepanet.dylib; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ @@ -129,7 +110,7 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 2298EBC716B178E70088A6DC /* Frameworks */ = { + 22EF554916BC740400F3988A /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( @@ -190,7 +171,7 @@ children = ( D2AAC0630554660B00DB518D /* libepanet.dylib */, 22322F66106833BB00641384 /* runepanet */, - 2298EBCA16B178E70088A6DC /* testLemonTiger */, + 22EF554C16BC740400F3988A /* TestLemonTiger */, ); name = Products; sourceTree = ""; @@ -209,6 +190,8 @@ 2298EBDF16B17E440088A6DC /* lemontiger.c */, 2298EBE016B17E440088A6DC /* lemontiger.h */, 2298EBDC16B17DCE0088A6DC /* testLT.c */, + 22EF555516BC744C00F3988A /* testLemonTiger.cpp */, + 22EF555616BC744C00F3988A /* testLemonTiger.h */, ); name = LemonTiger; sourceTree = ""; @@ -253,22 +236,21 @@ productReference = 22322F66106833BB00641384 /* runepanet */; productType = "com.apple.product-type.tool"; }; - 2298EBC916B178E70088A6DC /* testLemonTiger */ = { + 22EF554B16BC740400F3988A /* TestLemonTiger */ = { isa = PBXNativeTarget; - buildConfigurationList = 2298EBD116B178E70088A6DC /* Build configuration list for PBXNativeTarget "testLemonTiger" */; + buildConfigurationList = 22EF555416BC740400F3988A /* Build configuration list for PBXNativeTarget "TestLemonTiger" */; buildPhases = ( - 2298EBC616B178E70088A6DC /* Sources */, - 2298EBC716B178E70088A6DC /* Frameworks */, - 2298EBC816B178E70088A6DC /* CopyFiles */, + 22EF554816BC740400F3988A /* Sources */, + 22EF554916BC740400F3988A /* Frameworks */, + 22EF554A16BC740400F3988A /* CopyFiles */, ); buildRules = ( ); dependencies = ( - 2298EBD916B17B830088A6DC /* PBXTargetDependency */, ); - name = testLemonTiger; - productName = testLemonTiger; - productReference = 2298EBCA16B178E70088A6DC /* testLemonTiger */; + name = TestLemonTiger; + productName = TestLemonTiger; + productReference = 22EF554C16BC740400F3988A /* TestLemonTiger */; productType = "com.apple.product-type.tool"; }; D2AAC0620554660B00DB518D /* epanet */ = { @@ -309,7 +291,7 @@ targets = ( D2AAC0620554660B00DB518D /* epanet */, 22322F65106833BB00641384 /* runepanet */, - 2298EBC916B178E70088A6DC /* testLemonTiger */, + 22EF554B16BC740400F3988A /* TestLemonTiger */, ); }; /* End PBXProject section */ @@ -335,25 +317,11 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 2298EBC616B178E70088A6DC /* Sources */ = { + 22EF554816BC740400F3988A /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 227CECA016BB0D5E00E8E7C8 /* lemontiger.c in Sources */, - 227CECA116BB0D5E00E8E7C8 /* epanet.c in Sources */, - 227CECA216BB0D5E00E8E7C8 /* hash.c in Sources */, - 227CECA316BB0D5E00E8E7C8 /* hydraul.c in Sources */, - 227CECA416BB0D5E00E8E7C8 /* inpfile.c in Sources */, - 227CECA516BB0D5E00E8E7C8 /* input1.c in Sources */, - 227CECA616BB0D5E00E8E7C8 /* input2.c in Sources */, - 227CECA716BB0D5E00E8E7C8 /* input3.c in Sources */, - 227CECA816BB0D5E00E8E7C8 /* mempool.c in Sources */, - 227CECA916BB0D5E00E8E7C8 /* output.c in Sources */, - 227CECAA16BB0D5E00E8E7C8 /* quality.c in Sources */, - 227CECAB16BB0D5E00E8E7C8 /* report.c in Sources */, - 227CECAC16BB0D5E00E8E7C8 /* rules.c in Sources */, - 227CECAD16BB0D5E00E8E7C8 /* smatrix.c in Sources */, - 2298EBDE16B17DE50088A6DC /* testLT.c in Sources */, + 22EF555716BC744C00F3988A /* testLemonTiger.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -386,11 +354,6 @@ target = D2AAC0620554660B00DB518D /* epanet */; targetProxy = 22322FAF1068370B00641384 /* PBXContainerItemProxy */; }; - 2298EBD916B17B830088A6DC /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = D2AAC0620554660B00DB518D /* epanet */; - targetProxy = 2298EBD816B17B830088A6DC /* PBXContainerItemProxy */; - }; /* End PBXTargetDependency section */ /* Begin XCBuildConfiguration section */ @@ -491,14 +454,17 @@ }; name = Release; }; - 2298EBD216B178E70088A6DC /* Debug */ = { + 22EF555216BC740400F3988A /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; ARCHS = "$(ARCHS_STANDARD_64_BIT)"; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; + CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; @@ -512,18 +478,21 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES; MACOSX_DEPLOYMENT_TARGET = 10.8; PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = macosx; + SDKROOT = ""; }; name = Debug; }; - 2298EBD316B178E70088A6DC /* Release */ = { + 22EF555316BC740400F3988A /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; ARCHS = "$(ARCHS_STANDARD_64_BIT)"; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; + CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; @@ -532,7 +501,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES; MACOSX_DEPLOYMENT_TARGET = 10.8; PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = macosx; + SDKROOT = ""; }; name = Release; }; @@ -566,14 +535,13 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 2298EBD116B178E70088A6DC /* Build configuration list for PBXNativeTarget "testLemonTiger" */ = { + 22EF555416BC740400F3988A /* Build configuration list for PBXNativeTarget "TestLemonTiger" */ = { isa = XCConfigurationList; buildConfigurations = ( - 2298EBD216B178E70088A6DC /* Debug */, - 2298EBD316B178E70088A6DC /* Release */, + 22EF555216BC740400F3988A /* Debug */, + 22EF555316BC740400F3988A /* Release */, ); defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; diff --git a/src/testLemonTiger.cpp b/src/testLemonTiger.cpp new file mode 100644 index 0000000..6cfbf28 --- /dev/null +++ b/src/testLemonTiger.cpp @@ -0,0 +1,104 @@ +// +// testLemonTiger.cpp +// epanet +// +// Created by Sam Hatchett on 2/1/13. +// +// + +#include "testLemonTiger.h" +#include "epanet2.h" + +using namespace std; + +int main(int argc, char * argv[]) { + + cout << "Lemon Tiger TEST" << endl; + + int err = 0; //error code + long stime = 0; //simulation time point, = t = Htime + long step = 1; //time to next time point, = tstep = hydstep + long tleft = 0; //time left in the simulation + int id, id2, id3; // some node id + float value; // some node/link value + int TIME_A = 3600*3; + int TIME_B = 3600*6; //two time points for testing + int TIME_C = 3600*10; + + + /* Asychronous solver (old epanet) */ + printf("*****Original EPANET results******\n"); + + if (err=ENopen(argv[1], argv[2], "")) return err; + + + for (ENopenH(), ENinitH(1), step=1; + // must save intermediate results to disk (initH(1)), otherwise WQ solver won't execute + step>0; ENnextH(&step)) { + ENrunH(&stime); + } + ENcloseH(); + + printf("\nReset time pointer and run WQ.\n"); + for (step=1, ENopenQ(), ENinitQ(0); // this operation resets the internal time pointer (back to 0) + step>0; ENnextQ(&step)) { + + ENrunQ(&stime); + + + // grab some results + if (stime == TIME_A || stime == TIME_B || stime == TIME_C) { + printf("WQ simulation time = %d sec, step = %d sec.\n", stime, step); + + ENgetnodevalue(id, EN_QUALITY, &value); + printf("Node 184's quality = \t%f.\n", value); + ENgetnodevalue(id3, EN_QUALITY, &value); + printf("Node 199's quality = \t%f.\n", value); + } + } + ENcloseQ(); + ENclose(); + + + /* Sychronous solver (LemonTiger) */ + printf("\n\n*****LemonTiger results******\n\n"); + + if (err=ENopen(argv[1], argv[2], "")) return err; + + for (ENopeninitHQ(), tleft=Dur; tleft>0; ) { + + //ENrunstepHQ(&stime, &tleft); + ENrunnextHQ(&stime, &tleft); //well I know it should be tstep + + if (stime == TIME_A || stime == TIME_B || stime == TIME_C) { + //if (! (stime%1800)){ + printf("Simulation = %d sec, time left = %d sec.\n", stime, tleft); + ENgetnodevalue(id, EN_HEAD, &value); + printf("Node 184's head = \t%f.\n", value); + + ENgetnodevalue(id, EN_QUALITY, &value); + printf("Node 184's quality = \t%f.\n", value); + + ENgetnodevalue(id3, EN_HEAD, &value); + printf("Node 199's head = \t%f.\n", value); + + ENgetnodevalue(id3, EN_QUALITY, &value); + printf("Node 199's quality = \t%f.\n", value); + + ENgetlinkvalue(id2, EN_FLOW, &value); + printf("Link 101's flowrate = \t%f. \n", value); + + + printf("\n"); + } + } + ENcloseHQ(); + ENclose(); + + +} + + + + +} diff --git a/src/testLemonTiger.h b/src/testLemonTiger.h new file mode 100644 index 0000000..6e16ad2 --- /dev/null +++ b/src/testLemonTiger.h @@ -0,0 +1,14 @@ +// +// testLemonTiger.h +// epanet +// +// Created by Sam Hatchett on 2/1/13. +// +// + +#ifndef __epanet__testLemonTiger__ +#define __epanet__testLemonTiger__ + +#include + +#endif /* defined(__epanet__testLemonTiger__) */ From ab87f72e292c272ff0195a04636ea71fec3e841d Mon Sep 17 00:00:00 2001 From: Sam Hatchett Date: Fri, 1 Feb 2013 18:11:39 -0500 Subject: [PATCH 13/49] this is the shape of the API --- .../epanet/epanet.xcodeproj/project.pbxproj | 16 ++ src/testLemonTiger.cpp | 165 +++++++++--------- src/testLemonTiger.h | 1 + src/toolkit.h | 2 +- 4 files changed, 104 insertions(+), 80 deletions(-) diff --git a/build/Xcode/epanet/epanet.xcodeproj/project.pbxproj b/build/Xcode/epanet/epanet.xcodeproj/project.pbxproj index ff6645d..9a11a6b 100644 --- a/build/Xcode/epanet/epanet.xcodeproj/project.pbxproj +++ b/build/Xcode/epanet/epanet.xcodeproj/project.pbxproj @@ -45,6 +45,7 @@ 2298EBE116B17E440088A6DC /* lemontiger.c in Sources */ = {isa = PBXBuildFile; fileRef = 2298EBDF16B17E440088A6DC /* lemontiger.c */; }; 2298EBE216B17E440088A6DC /* lemontiger.h in Headers */ = {isa = PBXBuildFile; fileRef = 2298EBE016B17E440088A6DC /* lemontiger.h */; }; 22EF555716BC744C00F3988A /* testLemonTiger.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 22EF555516BC744C00F3988A /* testLemonTiger.cpp */; }; + 22EF555A16BC7FF500F3988A /* libepanet.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = D2AAC0630554660B00DB518D /* libepanet.dylib */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -55,6 +56,13 @@ remoteGlobalIDString = D2AAC0620554660B00DB518D; remoteInfo = epanet; }; + 22EF555816BC7FCC00F3988A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = D2AAC0620554660B00DB518D; + remoteInfo = epanet; + }; /* End PBXContainerItemProxy section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -114,6 +122,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 22EF555A16BC7FF500F3988A /* libepanet.dylib in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -247,6 +256,7 @@ buildRules = ( ); dependencies = ( + 22EF555916BC7FCC00F3988A /* PBXTargetDependency */, ); name = TestLemonTiger; productName = TestLemonTiger; @@ -354,6 +364,11 @@ target = D2AAC0620554660B00DB518D /* epanet */; targetProxy = 22322FAF1068370B00641384 /* PBXContainerItemProxy */; }; + 22EF555916BC7FCC00F3988A /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = D2AAC0620554660B00DB518D /* epanet */; + targetProxy = 22EF555816BC7FCC00F3988A /* PBXContainerItemProxy */; + }; /* End PBXTargetDependency section */ /* Begin XCBuildConfiguration section */ @@ -542,6 +557,7 @@ 22EF555316BC740400F3988A /* Release */, ); defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; diff --git a/src/testLemonTiger.cpp b/src/testLemonTiger.cpp index 6cfbf28..8fb8c12 100644 --- a/src/testLemonTiger.cpp +++ b/src/testLemonTiger.cpp @@ -1,104 +1,111 @@ -// -// testLemonTiger.cpp -// epanet -// -// Created by Sam Hatchett on 2/1/13. -// -// #include "testLemonTiger.h" #include "epanet2.h" + using namespace std; +void checkErr(int err, std::string function); + int main(int argc, char * argv[]) { - cout << "Lemon Tiger TEST" << endl; - - int err = 0; //error code - long stime = 0; //simulation time point, = t = Htime - long step = 1; //time to next time point, = tstep = hydstep - long tleft = 0; //time left in the simulation - int id, id2, id3; // some node id - float value; // some node/link value - int TIME_A = 3600*3; - int TIME_B = 3600*6; //two time points for testing - int TIME_C = 3600*10; + cout << "Lemon Tiger TEST" << endl + << "________________" << endl; - /* Asychronous solver (old epanet) */ - printf("*****Original EPANET results******\n"); - - if (err=ENopen(argv[1], argv[2], "")) return err; + long tstep = 0; + long simulationTime = 0; + long nextEventH = 0; + long simTimeRemaining = 0; - - for (ENopenH(), ENinitH(1), step=1; - // must save intermediate results to disk (initH(1)), otherwise WQ solver won't execute - step>0; ENnextH(&step)) { - ENrunH(&stime); - } - ENcloseH(); - - printf("\nReset time pointer and run WQ.\n"); - for (step=1, ENopenQ(), ENinitQ(0); // this operation resets the internal time pointer (back to 0) - step>0; ENnextQ(&step)) { + try { - ENrunQ(&stime); - + /* Batch solver (old epanet) */ + cout << "*****Original EPANET results******" << endl; + checkErr( ENopen(argv[1], argv[2], ""), "ENopen" ); - // grab some results - if (stime == TIME_A || stime == TIME_B || stime == TIME_C) { - printf("WQ simulation time = %d sec, step = %d sec.\n", stime, step); - - ENgetnodevalue(id, EN_QUALITY, &value); - printf("Node 184's quality = \t%f.\n", value); - ENgetnodevalue(id3, EN_QUALITY, &value); - printf("Node 199's quality = \t%f.\n", value); - } - } - ENcloseQ(); - ENclose(); - - - /* Sychronous solver (LemonTiger) */ - printf("\n\n*****LemonTiger results******\n\n"); - - if (err=ENopen(argv[1], argv[2], "")) return err; - - for (ENopeninitHQ(), tleft=Dur; tleft>0; ) { + checkErr( ENopenH(), "ENopenH" ); + checkErr( ENinitH(EN_SAVE), "ENinitH" ); - //ENrunstepHQ(&stime, &tleft); - ENrunnextHQ(&stime, &tleft); //well I know it should be tstep - - if (stime == TIME_A || stime == TIME_B || stime == TIME_C) { - //if (! (stime%1800)){ - printf("Simulation = %d sec, time left = %d sec.\n", stime, tleft); - ENgetnodevalue(id, EN_HEAD, &value); - printf("Node 184's head = \t%f.\n", value); - - ENgetnodevalue(id, EN_QUALITY, &value); - printf("Node 184's quality = \t%f.\n", value); + do { + /* Solve for hydraulics & advance to next time period */ + tstep = 0; + checkErr( ENrunH(&simulationTime), "ENrunH" ); + checkErr( ENnextH(&nextEventH), "ENnextH" ); - ENgetnodevalue(id3, EN_HEAD, &value); - printf("Node 199's head = \t%f.\n", value); + // gather hydraulic results - ENgetnodevalue(id3, EN_QUALITY, &value); - printf("Node 199's quality = \t%f.\n", value); + } while (nextEventH > 0); + // hydraulics are done + checkErr( ENcloseH(), "ENcloseH" ); + + cout << "Running WQ..." << endl; + + checkErr( ENopenQ(), "ENopenQ" ); + checkErr( ENinitQ(EN_SAVE), "ENinitQ" ); + + do { + checkErr( ENrunQ(&simulationTime), "ENrunQ" ); + checkErr( ENstepQ(&simTimeRemaining), "ENstepQ" ); - ENgetlinkvalue(id2, EN_FLOW, &value); - printf("Link 101's flowrate = \t%f. \n", value); + // wq results + } while (simTimeRemaining > 0); + // water quality is done + checkErr( ENcloseQ(), "ENcloseQ" ); + + // everything is done + checkErr( ENclose(), "ENclose" ); + + + nextEventH = 0; + simTimeRemaining = 0; + simulationTime = 0; + + /* stepwise solver (LemonTiger) */ + cout << "*****LemonTiger results******" << endl; + + checkErr( ENopen(argv[1], argv[2], NULL), "ENopen" ); + + checkErr( ENopenH(), "ENopenH" ); + checkErr( ENinitH(EN_SAVE), "ENinitH" ); + checkErr( ENopenQ(), "ENopenQ" ); + checkErr( ENinitQ(EN_SAVE), "ENinitQ" ); + + do { + /* Solve for hydraulics & advance to next time period */ + tstep = 0; + checkErr( ENrunH(&simulationTime), "ENrunH" ); + checkErr( ENnextH(&nextEventH), "ENnextH" ); - printf("\n"); - } - } - ENcloseHQ(); - ENclose(); - - + // hydraulic results + + checkErr( ENrunQ(&simulationTime), "ENrunQ" ); + checkErr( ENstepQ(&simTimeRemaining), "ENstepQ" ); + + // wq results + + } while (simTimeRemaining > 0); + // all done + checkErr( ENcloseH(), "ENcloseH" ); + checkErr( ENcloseQ(), "ENcloseQ" ); + checkErr( ENclose(), "ENclose" ); + + + } catch (int err) { + cerr << "exiting with error " << err << endl; + } } +void checkErr(int err, std::string function) { + if (err > 0) { + cerr << "Error in " << function << ": " << err << endl; + char errmsg[1024]; + ENgeterror(err, errmsg, 1024); + cerr << errmsg << endl; + throw err; + } } diff --git a/src/testLemonTiger.h b/src/testLemonTiger.h index 6e16ad2..5c1cc2f 100644 --- a/src/testLemonTiger.h +++ b/src/testLemonTiger.h @@ -10,5 +10,6 @@ #define __epanet__testLemonTiger__ #include +#include #endif /* defined(__epanet__testLemonTiger__) */ diff --git a/src/toolkit.h b/src/toolkit.h index 1abb018..679e7f8 100755 --- a/src/toolkit.h +++ b/src/toolkit.h @@ -178,7 +178,7 @@ extern "C" { int DLLEXPORT ENopenH(void); int DLLEXPORT ENinitH(int); int DLLEXPORT ENrunH(long *); - int DLLEXPORT ENnextH(long *); + int DLLEXPORT ENnextH(long *tstep); int DLLEXPORT ENcloseH(void); int DLLEXPORT ENsavehydfile(char *); int DLLEXPORT ENusehydfile(char *); From afc80b6b134989872a7cde8a3206797bfb87a432 Mon Sep 17 00:00:00 2001 From: sam hatchett Date: Mon, 4 Feb 2013 16:29:04 -0500 Subject: [PATCH 14/49] trying to incorporate some of the stepwise solution functionality into the regular epanet toolkit functions. --- src/epanet.c | 3 +- src/quality.c | 26 ++++++++++---- src/testLemonTiger.cpp | 78 +++++++++++++++++++++++++++++++----------- test/Net3.inp | 2 +- 4 files changed, 80 insertions(+), 29 deletions(-) diff --git a/src/epanet.c b/src/epanet.c index e3da576..a7ee920 100755 --- a/src/epanet.c +++ b/src/epanet.c @@ -742,7 +742,8 @@ int DLLEXPORT ENopenQ() OpenQflag = FALSE; SaveQflag = FALSE; if (!Openflag) return(102); - if (!SaveHflag) return(104); + // !LT! todo - check for SaveHflag / set sequential/step mode + //if (!SaveHflag) return(104); /* Open WQ solver */ ERRCODE(openqual()); diff --git a/src/quality.c b/src/quality.c index b6e2134..07d0960 100755 --- a/src/quality.c +++ b/src/quality.c @@ -188,7 +188,10 @@ void initqual() Wsource = 0.0; /* Re-position hydraulics file */ - fseek(HydFile,HydOffset,SEEK_SET); + if (!OpenHflag) { + fseek(HydFile,HydOffset,SEEK_SET); + } + /* Set elapsed times to zero */ Htime = 0; @@ -220,7 +223,9 @@ int runqual(long *t) if (Qtime == Htime) { errcode = gethyd(&hydtime, &hydstep); - Htime = hydtime + hydstep; + if (!OpenHflag) { // test for sequential vs stepwise + Htime = hydtime + hydstep; + } } return(errcode); } @@ -343,10 +348,14 @@ int gethyd(long *hydtime, long *hydstep) { int errcode = 0; - /* Read hydraulic results from file */ - if (!readhyd(hydtime)) return(307); - if (!readhydstep(hydstep)) return(307); - Htime = *hydtime; + // if hydraulics are not open, then we're operating in sequential mode. + // else hydraulics are open, so use the hydraulic results in memory rather than reading from the temp file. + if (!OpenHflag) { + /* Read hydraulic results from file */ + if (!readhyd(hydtime)) return(307); + if (!readhydstep(hydstep)) return(307); + Htime = *hydtime; + } /* Save current results to output file */ if (Htime >= Rtime) @@ -1067,7 +1076,10 @@ void tankmix1(int i, long dt) /* Determine tank & volumes */ vold = Tank[i].V; n = Tank[i].Node; - Tank[i].V += D[n]*dt; + if (!OpenHflag) { + Tank[i].V += D[n]*dt; + } + vin = VolIn[n]; /* Compute inflow concen. */ diff --git a/src/testLemonTiger.cpp b/src/testLemonTiger.cpp index 8fb8c12..f97a8f5 100644 --- a/src/testLemonTiger.cpp +++ b/src/testLemonTiger.cpp @@ -1,11 +1,12 @@ #include "testLemonTiger.h" -#include "epanet2.h" +#include "toolkit.h" using namespace std; void checkErr(int err, std::string function); +void stats(); int main(int argc, char * argv[]) { @@ -15,45 +16,64 @@ int main(int argc, char * argv[]) { long tstep = 0; long simulationTime = 0; - long nextEventH = 0; + long nextEventH = 0, nextEventQ = 0; long simTimeRemaining = 0; try { /* Batch solver (old epanet) */ cout << "*****Original EPANET results******" << endl; - checkErr( ENopen(argv[1], argv[2], ""), "ENopen" ); + checkErr( ENopen(argv[1], argv[2], "out.bin"), "ENopen" ); checkErr( ENopenH(), "ENopenH" ); checkErr( ENinitH(EN_SAVE), "ENinitH" ); + cout << "Running hydraulics..." << endl; do { + /* Solve for hydraulics & advance to next time period */ tstep = 0; + checkErr( ENrunH(&simulationTime), "ENrunH" ); checkErr( ENnextH(&nextEventH), "ENnextH" ); + stats(); + // gather hydraulic results } while (nextEventH > 0); // hydraulics are done checkErr( ENcloseH(), "ENcloseH" ); - + cout << "\t\t\tdone." << endl; cout << "Running WQ..." << endl; checkErr( ENopenQ(), "ENopenQ" ); checkErr( ENinitQ(EN_SAVE), "ENinitQ" ); do { + //long htime; + + //ENgettimeparam(EN_HTIME, &htime); + //cout << "Htime = " << htime << endl; + checkErr( ENrunQ(&simulationTime), "ENrunQ" ); - checkErr( ENstepQ(&simTimeRemaining), "ENstepQ" ); + + //ENgettimeparam(EN_HTIME, &htime); + //cout << "Htime = " << htime << endl; + + checkErr( ENnextQ(&nextEventH), "ENstepQ" ); + + //ENgettimeparam(EN_HTIME, &htime); + //cout << "Htime = " << htime << endl; // wq results + //cout << simulationTime << "\t\t" << nextEventH << endl; - } while (simTimeRemaining > 0); + } while (nextEventH > 0); // water quality is done checkErr( ENcloseQ(), "ENcloseQ" ); - + cout << "\t\t\tdone." << endl; + // everything is done checkErr( ENclose(), "ENclose" ); @@ -65,27 +85,34 @@ int main(int argc, char * argv[]) { /* stepwise solver (LemonTiger) */ cout << "*****LemonTiger results******" << endl; - checkErr( ENopen(argv[1], argv[2], NULL), "ENopen" ); + checkErr( ENopen(argv[1], argv[2], "out2.bin"), "ENopen" ); checkErr( ENopenH(), "ENopenH" ); - checkErr( ENinitH(EN_SAVE), "ENinitH" ); + checkErr( ENinitH(EN_NOSAVE), "ENinitH" ); checkErr( ENopenQ(), "ENopenQ" ); - checkErr( ENinitQ(EN_SAVE), "ENinitQ" ); + checkErr( ENinitQ(EN_NOSAVE), "ENinitQ" ); + cout << "Running stepwise hydraulics and water quality..." << endl; do { /* Solve for hydraulics & advance to next time period */ tstep = 0; + checkErr( ENrunH(&simulationTime), "ENrunH" ); - checkErr( ENnextH(&nextEventH), "ENnextH" ); - - // hydraulic results - checkErr( ENrunQ(&simulationTime), "ENrunQ" ); - checkErr( ENstepQ(&simTimeRemaining), "ENstepQ" ); + + //stats(); + + checkErr( ENnextH(&nextEventH), "ENnextH" ); + checkErr( ENnextQ(&nextEventQ), "ENstepQ" ); + + stats(); // wq results + //cout << simulationTime << "\t\t" << nextEventH << endl; - } while (simTimeRemaining > 0); + } while (nextEventH > 0); + cout << "\t\t\tdone." << endl; + // all done checkErr( ENcloseH(), "ENcloseH" ); checkErr( ENcloseQ(), "ENcloseQ" ); @@ -96,10 +123,21 @@ int main(int argc, char * argv[]) { cerr << "exiting with error " << err << endl; } } - - - - + + + +void stats() { + long htime; + int nodeIndex; + float head, volume; + ENgettimeparam(EN_HTIME, &htime); + ENgetnodeindex((char*)"1", &nodeIndex); + ENgetnodevalue(nodeIndex, EN_HEAD, &head); + cout << htime << "\t\t" << head << endl; +} + + + void checkErr(int err, std::string function) { if (err > 0) { cerr << "Error in " << function << ": " << err << endl; diff --git a/test/Net3.inp b/test/Net3.inp index 5355958..f81711b 100644 --- a/test/Net3.inp +++ b/test/Net3.inp @@ -331,7 +331,7 @@ Link 330 OPEN IF Node 1 ABOVE 19.1 ;Tank Model [TIMES] - Duration 24:00 + Duration 6:00 Hydraulic Timestep 1:00 Quality Timestep 0:05 Pattern Timestep 1:00 From b4164f56b4b5ac2a68df812355981669ed9e0eed Mon Sep 17 00:00:00 2001 From: sam hatchett Date: Mon, 4 Feb 2013 21:17:58 -0500 Subject: [PATCH 15/49] more stepwise mods --- .../epanet/epanet.xcodeproj/project.pbxproj | 13 ------ src/hydraul.c | 19 ++++++--- src/quality.c | 28 +++++++------ src/testLemonTiger.cpp | 40 +++++++++---------- test/Net3.inp | 3 +- 5 files changed, 52 insertions(+), 51 deletions(-) diff --git a/build/Xcode/epanet/epanet.xcodeproj/project.pbxproj b/build/Xcode/epanet/epanet.xcodeproj/project.pbxproj index 9a11a6b..7e0c4ce 100644 --- a/build/Xcode/epanet/epanet.xcodeproj/project.pbxproj +++ b/build/Xcode/epanet/epanet.xcodeproj/project.pbxproj @@ -56,13 +56,6 @@ remoteGlobalIDString = D2AAC0620554660B00DB518D; remoteInfo = epanet; }; - 22EF555816BC7FCC00F3988A /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = D2AAC0620554660B00DB518D; - remoteInfo = epanet; - }; /* End PBXContainerItemProxy section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -256,7 +249,6 @@ buildRules = ( ); dependencies = ( - 22EF555916BC7FCC00F3988A /* PBXTargetDependency */, ); name = TestLemonTiger; productName = TestLemonTiger; @@ -364,11 +356,6 @@ target = D2AAC0620554660B00DB518D /* epanet */; targetProxy = 22322FAF1068370B00641384 /* PBXContainerItemProxy */; }; - 22EF555916BC7FCC00F3988A /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = D2AAC0620554660B00DB518D /* epanet */; - targetProxy = 22EF555816BC7FCC00F3988A /* PBXContainerItemProxy */; - }; /* End PBXTargetDependency section */ /* Begin XCBuildConfiguration section */ diff --git a/src/hydraul.c b/src/hydraul.c index bf9cea5..8a91d6d 100755 --- a/src/hydraul.c +++ b/src/hydraul.c @@ -1049,14 +1049,23 @@ void tanklevels(long tstep) /* Update the tank's volume & water elevation */ n = Tank[i].Node; - dv = D[n]*tstep; - Tank[i].V += dv; + + // only adjust tank volume if we're in sequential mode. + // otherwise, the tankmixing function will do it for us. + if (!OpenQflag) { + dv = D[n]*tstep; + Tank[i].V += dv; + } /*** Updated 6/24/02 ***/ /* Check if tank full/empty within next second */ - if (Tank[i].V + D[n] >= Tank[i].Vmax) Tank[i].V = Tank[i].Vmax; - if (Tank[i].V - D[n] <= Tank[i].Vmin) Tank[i].V = Tank[i].Vmin; - + if (Tank[i].V + D[n] >= Tank[i].Vmax) { + Tank[i].V = Tank[i].Vmax; + } + else if (Tank[i].V - D[n] <= Tank[i].Vmin) { + Tank[i].V = Tank[i].Vmin; + } + H[n] = tankgrade(i,Tank[i].V); } } /* End of tanklevels */ diff --git a/src/quality.c b/src/quality.c index 07d0960..cf3a094 100755 --- a/src/quality.c +++ b/src/quality.c @@ -1005,21 +1005,28 @@ void updatetanks(long dt) /* Examine each reservoir & tank */ for (i=1; i<=Ntanks; i++) { - + n = Tank[i].Node; + /* Use initial quality for reservoirs */ if (Tank[i].A == 0.0) { - n = Tank[i].Node; C[n] = Node[n].C0; } /* Update tank WQ based on mixing model */ - else switch(Tank[i].MixModel) - { - case MIX2: tankmix2(i,dt); break; - case FIFO: tankmix3(i,dt); break; - case LIFO: tankmix4(i,dt); break; - default: tankmix1(i,dt); break; + else { + switch(Tank[i].MixModel) + { + case MIX2: tankmix2(i,dt); break; + case FIFO: tankmix3(i,dt); break; + case LIFO: tankmix4(i,dt); break; + default: tankmix1(i,dt); break; + } + + // if we're operating in stepwise mode, we'll need to update tank head conditions + if (OpenHflag) { + H[n] = tankgrade(i,Tank[i].V); + } } } } @@ -1076,10 +1083,7 @@ void tankmix1(int i, long dt) /* Determine tank & volumes */ vold = Tank[i].V; n = Tank[i].Node; - if (!OpenHflag) { - Tank[i].V += D[n]*dt; - } - + Tank[i].V += D[n]*dt; vin = VolIn[n]; /* Compute inflow concen. */ diff --git a/src/testLemonTiger.cpp b/src/testLemonTiger.cpp index f97a8f5..8d986ca 100644 --- a/src/testLemonTiger.cpp +++ b/src/testLemonTiger.cpp @@ -6,7 +6,8 @@ using namespace std; void checkErr(int err, std::string function); -void stats(); +void hydStats(); +void qualStats(); int main(int argc, char * argv[]) { @@ -37,7 +38,7 @@ int main(int argc, char * argv[]) { checkErr( ENrunH(&simulationTime), "ENrunH" ); checkErr( ENnextH(&nextEventH), "ENnextH" ); - stats(); + hydStats(); // gather hydraulic results @@ -51,23 +52,11 @@ int main(int argc, char * argv[]) { checkErr( ENinitQ(EN_SAVE), "ENinitQ" ); do { - //long htime; - - //ENgettimeparam(EN_HTIME, &htime); - //cout << "Htime = " << htime << endl; checkErr( ENrunQ(&simulationTime), "ENrunQ" ); - - //ENgettimeparam(EN_HTIME, &htime); - //cout << "Htime = " << htime << endl; - checkErr( ENnextQ(&nextEventH), "ENstepQ" ); - //ENgettimeparam(EN_HTIME, &htime); - //cout << "Htime = " << htime << endl; - - // wq results - //cout << simulationTime << "\t\t" << nextEventH << endl; + qualStats(); } while (nextEventH > 0); // water quality is done @@ -85,7 +74,7 @@ int main(int argc, char * argv[]) { /* stepwise solver (LemonTiger) */ cout << "*****LemonTiger results******" << endl; - checkErr( ENopen(argv[1], argv[2], "out2.bin"), "ENopen" ); + checkErr( ENopen(argv[1], argv[2], (char*)"out2.bin"), "ENopen" ); checkErr( ENopenH(), "ENopenH" ); checkErr( ENinitH(EN_NOSAVE), "ENinitH" ); @@ -105,7 +94,8 @@ int main(int argc, char * argv[]) { checkErr( ENnextH(&nextEventH), "ENnextH" ); checkErr( ENnextQ(&nextEventQ), "ENstepQ" ); - stats(); + //hydStats(); + qualStats(); // wq results //cout << simulationTime << "\t\t" << nextEventH << endl; @@ -126,14 +116,24 @@ int main(int argc, char * argv[]) { -void stats() { +void hydStats() { long htime; int nodeIndex; - float head, volume; + float head; ENgettimeparam(EN_HTIME, &htime); ENgetnodeindex((char*)"1", &nodeIndex); ENgetnodevalue(nodeIndex, EN_HEAD, &head); - cout << htime << "\t\t" << head << endl; + cout << htime << "\t\th = " << head << endl; +} + +void qualStats() { + long htime; + int nodeIndex; + float quality; + ENgettimeparam(EN_HTIME, &htime); + ENgetnodeindex((char*)"1", &nodeIndex); + ENgetnodevalue(nodeIndex, EN_QUALITY, &quality); + cout << htime << "\t\tc = " << quality << endl; } diff --git a/test/Net3.inp b/test/Net3.inp index f81711b..e169140 100644 --- a/test/Net3.inp +++ b/test/Net3.inp @@ -311,6 +311,7 @@ Link 330 OPEN IF Node 1 ABOVE 19.1 [QUALITY] ;Node InitQual + [SOURCES] ;Node Type Quality Pattern @@ -331,7 +332,7 @@ Link 330 OPEN IF Node 1 ABOVE 19.1 ;Tank Model [TIMES] - Duration 6:00 + Duration 24:00 Hydraulic Timestep 1:00 Quality Timestep 0:05 Pattern Timestep 1:00 From b891ccbdedf1e9b3c776682ddf7d5dea239ce8a8 Mon Sep 17 00:00:00 2001 From: sam hatchett Date: Mon, 4 Feb 2013 21:26:58 -0500 Subject: [PATCH 16/49] project settings / prereq --- build/Xcode/epanet/epanet.xcodeproj/project.pbxproj | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/build/Xcode/epanet/epanet.xcodeproj/project.pbxproj b/build/Xcode/epanet/epanet.xcodeproj/project.pbxproj index 7e0c4ce..9bd2890 100644 --- a/build/Xcode/epanet/epanet.xcodeproj/project.pbxproj +++ b/build/Xcode/epanet/epanet.xcodeproj/project.pbxproj @@ -56,6 +56,13 @@ remoteGlobalIDString = D2AAC0620554660B00DB518D; remoteInfo = epanet; }; + 2259CEF416C0A54F00A35F5E /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = D2AAC0620554660B00DB518D; + remoteInfo = epanet; + }; /* End PBXContainerItemProxy section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -249,6 +256,7 @@ buildRules = ( ); dependencies = ( + 2259CEF516C0A54F00A35F5E /* PBXTargetDependency */, ); name = TestLemonTiger; productName = TestLemonTiger; @@ -356,6 +364,11 @@ target = D2AAC0620554660B00DB518D /* epanet */; targetProxy = 22322FAF1068370B00641384 /* PBXContainerItemProxy */; }; + 2259CEF516C0A54F00A35F5E /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = D2AAC0620554660B00DB518D /* epanet */; + targetProxy = 2259CEF416C0A54F00A35F5E /* PBXContainerItemProxy */; + }; /* End PBXTargetDependency section */ /* Begin XCBuildConfiguration section */ From 7a0dd5ec6d4efc34f115d11371b25927b298ae0e Mon Sep 17 00:00:00 2001 From: sam hatchett Date: Mon, 4 Feb 2013 21:28:27 -0500 Subject: [PATCH 17/49] removed files --- .../epanet/epanet.xcodeproj/project.pbxproj | 10 - src/lemontiger.c | 288 ------------------ src/lemontiger.h | 241 --------------- src/testLT.c | 112 ------- 4 files changed, 651 deletions(-) delete mode 100644 src/lemontiger.c delete mode 100644 src/lemontiger.h delete mode 100644 src/testLT.c diff --git a/build/Xcode/epanet/epanet.xcodeproj/project.pbxproj b/build/Xcode/epanet/epanet.xcodeproj/project.pbxproj index 9bd2890..2a4b1da 100644 --- a/build/Xcode/epanet/epanet.xcodeproj/project.pbxproj +++ b/build/Xcode/epanet/epanet.xcodeproj/project.pbxproj @@ -42,8 +42,6 @@ 22322FA51068369500641384 /* rules.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F7F1068369500641384 /* rules.c */; }; 22322FA61068369500641384 /* smatrix.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F801068369500641384 /* smatrix.c */; }; 22322FAA106836BC00641384 /* epanet2.h in Headers */ = {isa = PBXBuildFile; fileRef = 22322FA9106836B000641384 /* epanet2.h */; }; - 2298EBE116B17E440088A6DC /* lemontiger.c in Sources */ = {isa = PBXBuildFile; fileRef = 2298EBDF16B17E440088A6DC /* lemontiger.c */; }; - 2298EBE216B17E440088A6DC /* lemontiger.h in Headers */ = {isa = PBXBuildFile; fileRef = 2298EBE016B17E440088A6DC /* lemontiger.h */; }; 22EF555716BC744C00F3988A /* testLemonTiger.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 22EF555516BC744C00F3988A /* testLemonTiger.cpp */; }; 22EF555A16BC7FF500F3988A /* libepanet.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = D2AAC0630554660B00DB518D /* libepanet.dylib */; }; /* End PBXBuildFile section */ @@ -101,9 +99,6 @@ 22322F831068369500641384 /* types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = types.h; path = ../../../src/types.h; sourceTree = SOURCE_ROOT; }; 22322F841068369500641384 /* vars.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = vars.h; path = ../../../src/vars.h; sourceTree = SOURCE_ROOT; }; 22322FA9106836B000641384 /* epanet2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = epanet2.h; path = ../../../include/epanet2.h; sourceTree = SOURCE_ROOT; }; - 2298EBDC16B17DCE0088A6DC /* testLT.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = testLT.c; path = ../../../src/testLT.c; sourceTree = ""; }; - 2298EBDF16B17E440088A6DC /* lemontiger.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lemontiger.c; path = ../../../src/lemontiger.c; sourceTree = ""; }; - 2298EBE016B17E440088A6DC /* lemontiger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lemontiger.h; path = ../../../src/lemontiger.h; sourceTree = ""; }; 22EF554C16BC740400F3988A /* TestLemonTiger */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = TestLemonTiger; sourceTree = BUILT_PRODUCTS_DIR; }; 22EF555516BC744C00F3988A /* testLemonTiger.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = testLemonTiger.cpp; path = ../../../src/testLemonTiger.cpp; sourceTree = ""; }; 22EF555616BC744C00F3988A /* testLemonTiger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = testLemonTiger.h; path = ../../../src/testLemonTiger.h; sourceTree = ""; }; @@ -196,9 +191,6 @@ 2298EBDB16B17DBD0088A6DC /* LemonTiger */ = { isa = PBXGroup; children = ( - 2298EBDF16B17E440088A6DC /* lemontiger.c */, - 2298EBE016B17E440088A6DC /* lemontiger.h */, - 2298EBDC16B17DCE0088A6DC /* testLT.c */, 22EF555516BC744C00F3988A /* testLemonTiger.cpp */, 22EF555616BC744C00F3988A /* testLemonTiger.h */, ); @@ -221,7 +213,6 @@ 22322F971068369500641384 /* toolkit.h in Headers */, 22322F981068369500641384 /* types.h in Headers */, 22322F991068369500641384 /* vars.h in Headers */, - 2298EBE216B17E440088A6DC /* lemontiger.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -352,7 +343,6 @@ 22322F931068369500641384 /* report.c in Sources */, 22322F941068369500641384 /* rules.c in Sources */, 22322F951068369500641384 /* smatrix.c in Sources */, - 2298EBE116B17E440088A6DC /* lemontiger.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/src/lemontiger.c b/src/lemontiger.c deleted file mode 100644 index c4a2ed8..0000000 --- a/src/lemontiger.c +++ /dev/null @@ -1,288 +0,0 @@ -#include "types.h" -#include "vars.h" -#include "funcs.h" -#include "toolkit.h" - -extern char OutOfMemory; -extern int Haltflag; - - -int DLLEXPORT ENopeninitHQ() { - int errcode = 0; - - if (Hstep % Qstep) { - errcode = 401; - errmsg(errcode); - return errcode; - } - - Statflag = TRUE; //disable status report - - if (errcode = ENopenH()) return errcode; - - // Open WQ solver, but don't check SaveHflag as in ENopenQ() - ERRCODE(openqual()); - if (!errcode) OpenQflag = TRUE; - else { - errmsg(errcode); - return errcode; - } - - if (errcode = ENinitH(1)) return errcode; - if (errcode = ENinitQ(0)) return errcode; - - Rtime = Rstep; //use ENinitH()'s setup - return errcode; -} - -long timestepLT(); -/* computes the length of the time step to next hydraulic simulation, but don't - update tank volumne and tank levels. During a sync HQ simulation, - nextqual() will update the tank vols */ - -int nexthydLT(long *tstep); -/* finds length of next time step but don't save - results to hydraulics file. ignore reporting functions. */ - -void updateTanklevels(); -//Prior to running hydraulic simulation, update the tank levels. - - -/*! - \fn int ENrunnextHQ( long* simTimePtr, long* timeStepPtr ) - \brief equivalent of ENnextQ, hydraulic solver is called on-demand - \param simTimePtr Simulation time (output variable). - \param timeStepPtr Time to next time step boundary (output variable). - \return on error, an error code - */ -int DLLEXPORT ENrunnextHQ(long* simTimePtr, long* timeStepPtr) { - /* The lemonTiger equivalent of ENnextQ, hydraulic solver is called on-demand*/ - long hydtime; /* Hydraulic solution time */ - long hydstep; /* Hydraulic time step */ - int errcode = 0; - - /* if needed, push forward hydraulic simulation, similar to runqual() */ - if (Qtime == Htime) - { - if ( (errcode = runhyd(&hydtime)) || (errcode = nexthydLT(&hydstep)) ) { - return errcode; - } - /* If simulating WQ: */ - if (Qualflag != NONE && Qtime < Dur) { - - /* Compute reaction rate coeffs. */ - if (Reactflag && Qualflag != AGE) ratecoeffs(); - - /* Initialize pipe segments (at time 0) or */ - /* else re-orient segments if flow reverses.*/ - if (Qtime == 0) initsegs(); - else reorientsegs(); - } - Htime = hydtime + hydstep; - } - *simTimePtr = Htime; - hydstep = Htime - Qtime; - - /* Perform water quality routing over this time step */ - if (Qualflag != NONE && hydstep > 0) transport(hydstep); - - updateTanklevels(); - /* Update current time */ - if (OutOfMemory) errcode = 101; - if (!errcode) *timeStepPtr = hydstep; - Qtime += hydstep; - - /* Save final output if no more time steps */ - if (!errcode && Saveflag && *timeStepPtr == 0) errcode = savefinaloutput(); - return(errcode); - -} - -int DLLEXPORT ENrunstepHQ(long* pstime /* Simulation time pointer */ - ,long* ptleft /* Time left in the simulation*/) { - -/* The LemonTiger equivalence of ENstepQ, hydraulic solver is called on-demand */ - - long hydtime; /* Hydraulic solution time */ - long hydstep; /* Hydraulic time step */ - int errcode = 0; - long dt, hstep, tstep; - - /* if needed, push forward hydraulic simulation, similar to runqual() */ - if (Qtime == Htime) - { - if ( (errcode = runhyd(&hydtime)) || - (errcode = nexthydLT(&hydstep)) - ) return errcode; - /* If simulating WQ: */ - if (Qualflag != NONE && Qtime < Dur) { - - /* Compute reaction rate coeffs. */ - if (Reactflag && Qualflag != AGE) ratecoeffs(); - - /* Initialize pipe segments (at time 0) or */ - /* else re-orient segments if flow reverses.*/ - if (Qtime == 0) initsegs(); - else reorientsegs(); - } - Htime = hydtime + hydstep; - } - - /* run WQ simulation, similar to stepqual() */ - tstep = Qstep; - - do { - dt = tstep; - hstep = Htime - Qtime; - if (hstep < dt) {/* Htime is closer */ - dt = hstep; - if (Qualflag != NONE) transport(dt); - Qtime += dt; - - updateTanklevels(); - /* if needed, push forward hydraulic simulation */ - if ( (errcode = runhyd(&hydtime)) || - (errcode = nexthydLT(&hydstep)) - ) return errcode; - if (Qualflag != NONE && Qtime < Dur) { - - /* Compute reaction rate coeffs. */ - if (Reactflag && Qualflag != AGE) ratecoeffs(); - - /* Initialize pipe segments (at time 0) or */ - /* else re-orient segments if flow reverses.*/ - if (Qtime == 0) initsegs(); - else reorientsegs(); - } - Htime = hydtime + hydstep; - Qtime = hydtime; - - } else { /* Qtime is closer */ - if (Qualflag != NONE) transport(dt); - Qtime += dt; - } - tstep -= dt; - if (OutOfMemory) errcode = 101; - } while (!errcode && tstep > 0); /*do it until Qstep is elapsed.*/ - - *ptleft = Dur - Qtime; - if (!errcode && Saveflag && *ptleft == 0) errcode = savefinaloutput(); - - /* if needed, push forward hydraulic simulation again, so that hyd and wq states are consistent. */ - if (Qtime == Htime && Htime < Dur) { - updateTanklevels(); - if ( (errcode = runhyd(&hydtime)) || - (errcode = nexthydLT(&hydstep)) - ) return errcode; - // If simulating WQ: - if (Qualflag != NONE && Qtime < Dur) { - - // Compute reaction rate coeffs. - if (Reactflag && Qualflag != AGE) ratecoeffs(); - - // Initialize pipe segments (at time 0) or - // else re-orient segments if flow reverses. - if (Qtime == 0) initsegs(); - else reorientsegs(); - } - Htime = hydtime + hydstep; - } - - - /* Update reported simulation time */ - *pstime = Qtime; - - return(errcode); -} - - -int DLLEXPORT ENcloseHQ() { - int errcode = 0; - if ( (errcode = ENcloseQ()) || (errcode = ENcloseH()) ) - return errcode; - return errcode; -} - - - - -long timestepLT(void) { -/* computes time step to advance hydraulic simulation, but don't - update tank levels. Instead, let nextqual() do the job. */ - long n,t,tstep; - - /* Normal time step is hydraulic time step */ - tstep = Hstep; - - /* Revise time step based on time until next demand period */ - n = ((Htime+Pstart)/Pstep) + 1; /* Next pattern period */ - t = n*Pstep - Htime; /* Time till next period */ - if (t > 0 && t < tstep) tstep = t; - - /* Revise time step based on time until next reporting period */ - t = Rtime - Htime; - if (t > 0 && t < tstep) tstep = t; - - /* Revise time step based on smallest time to fill or drain a tank */ - tanktimestep(&tstep); - - /* Revise time step based on smallest time to activate a control */ - controltimestep(&tstep); - - /* Evaluate rule-based controls (which will also update tank levels) */ - if (Nrules > 0) ruletimestep(&tstep); - - return(tstep); -} - - -int nexthydLT(long *tstep) { -/* finds length of next time step but don't updates tank volumnes and tank - levels and rule-based contol actions. don't save - results to hydraulics file. don't consider Report time. */ - long hydstep; /* Actual time step */ - int errcode = 0; /* Error code */ - - if (Haltflag) Htime = Dur; - - /* Compute next time step & update tank levels */ - *tstep = 0; - hydstep = 0; - if (Htime < Dur) hydstep = timestepLT(); - - /* Compute pumping energy */ - if (Dur == 0) addenergy(0); - else if (Htime < Dur) addenergy(hydstep); - - /* Update current time. */ - if (Htime < Dur) /* More time remains */ - { - Htime += hydstep; - } - else - { - Htime++; /* Force completion of analysis */ - } - *tstep = hydstep; - return(errcode); -} - - -void updateTanklevels() { //Prior to doing hydraulic simulation, update the tank levels - int i,n; - for (i=1; i<=Ntanks; i++) { - /* Skip reservoirs */ - if (Tank[i].A == 0.0) continue; - - n = Tank[i].Node; - /* Check if tank full/empty within next second */ - if (Tank[i].V + D[n] >= Tank[i].Vmax) Tank[i].V = Tank[i].Vmax; - if (Tank[i].V - D[n] <= Tank[i].Vmin) Tank[i].V = Tank[i].Vmin; - - H[n] = tankgrade(i,Tank[i].V); - } -} - - - - \ No newline at end of file diff --git a/src/lemontiger.h b/src/lemontiger.h deleted file mode 100644 index cdb6585..0000000 --- a/src/lemontiger.h +++ /dev/null @@ -1,241 +0,0 @@ -#ifndef LEMONTIGER_H -#define LEMONTIGER_H - -/*The header file to be included for USING Epanet LemonTiger DLL on WINDOWS platforms, -all original Epanet functions remain intact, and the new LT_functions are added. */ - -/*Note that this file is not used by the functions in the toolkit itself. -Refer to toolkit.h for the internally used function declarations. */ -#ifdef __APPLE__ - #define DLLIMPORT -#else - #define DLLIMPORT __declspec(dllimport) -#endif -// --- Define the EPANET toolkit constants - -#define EN_ELEVATION 0 /* Node parameters */ -#define EN_BASEDEMAND 1 -#define EN_PATTERN 2 -#define EN_EMITTER 3 -#define EN_INITQUAL 4 -#define EN_SOURCEQUAL 5 -#define EN_SOURCEPAT 6 -#define EN_SOURCETYPE 7 -#define EN_TANKLEVEL 8 -#define EN_DEMAND 9 -#define EN_HEAD 10 -#define EN_PRESSURE 11 -#define EN_QUALITY 12 -#define EN_SOURCEMASS 13 -#define EN_INITVOLUME 14 -#define EN_MIXMODEL 15 -#define EN_MIXZONEVOL 16 - -#define EN_TANKDIAM 17 -#define EN_MINVOLUME 18 -#define EN_VOLCURVE 19 -#define EN_MINLEVEL 20 -#define EN_MAXLEVEL 21 -#define EN_MIXFRACTION 22 -#define EN_TANK_KBULK 23 - -#define EN_TANKVOLUME 24 /* TNT */ - -#define EN_DIAMETER 0 /* Link parameters */ -#define EN_LENGTH 1 -#define EN_ROUGHNESS 2 -#define EN_MINORLOSS 3 -#define EN_INITSTATUS 4 -#define EN_INITSETTING 5 -#define EN_KBULK 6 -#define EN_KWALL 7 -#define EN_FLOW 8 -#define EN_VELOCITY 9 -#define EN_HEADLOSS 10 -#define EN_STATUS 11 -#define EN_SETTING 12 -#define EN_ENERGY 13 -#define EN_LINKQUAL 14 /* TNT */ - -#define EN_DURATION 0 /* Time parameters */ -#define EN_HYDSTEP 1 -#define EN_QUALSTEP 2 -#define EN_PATTERNSTEP 3 -#define EN_PATTERNSTART 4 -#define EN_REPORTSTEP 5 -#define EN_REPORTSTART 6 -#define EN_RULESTEP 7 -#define EN_STATISTIC 8 -#define EN_PERIODS 9 -#define EN_STARTTIME 10 /* Added TNT 10/2/2009 */ - -#define EN_NODECOUNT 0 /* Component counts */ -#define EN_TANKCOUNT 1 -#define EN_LINKCOUNT 2 -#define EN_PATCOUNT 3 -#define EN_CURVECOUNT 4 -#define EN_CONTROLCOUNT 5 - -#define EN_JUNCTION 0 /* Node types */ -#define EN_RESERVOIR 1 -#define EN_TANK 2 - -#define EN_CVPIPE 0 /* Link types */ -#define EN_PIPE 1 -#define EN_PUMP 2 -#define EN_PRV 3 -#define EN_PSV 4 -#define EN_PBV 5 -#define EN_FCV 6 -#define EN_TCV 7 -#define EN_GPV 8 - -#define EN_NONE 0 /* Quality analysis types */ -#define EN_CHEM 1 -#define EN_AGE 2 -#define EN_TRACE 3 - -#define EN_CONCEN 0 /* Source quality types */ -#define EN_MASS 1 -#define EN_SETPOINT 2 -#define EN_FLOWPACED 3 - -#define EN_CFS 0 /* Flow units types */ -#define EN_GPM 1 -#define EN_MGD 2 -#define EN_IMGD 3 -#define EN_AFD 4 -#define EN_LPS 5 -#define EN_LPM 6 -#define EN_MLD 7 -#define EN_CMH 8 -#define EN_CMD 9 - -#define EN_TRIALS 0 /* Misc. options */ -#define EN_ACCURACY 1 -#define EN_TOLERANCE 2 -#define EN_EMITEXPON 3 -#define EN_DEMANDMULT 4 - -#define EN_LOWLEVEL 0 /* Control types */ -#define EN_HILEVEL 1 -#define EN_TIMER 2 -#define EN_TIMEOFDAY 3 - -#define EN_AVERAGE 1 /* Time statistic types. */ -#define EN_MINIMUM 2 -#define EN_MAXIMUM 3 -#define EN_RANGE 4 - -#define EN_MIX1 0 /* Tank mixing models */ -#define EN_MIX2 1 -#define EN_FIFO 2 -#define EN_LIFO 3 - -#define EN_NOSAVE 0 /* Save-results-to-file flag */ -#define EN_SAVE 1 -#define EN_INITFLOW 10 /* Re-initialize flow flag */ - -// --- declare the EPANET toolkit functions - -#ifdef __cplusplus -extern "C" { -#endif - - int DLLIMPORT ENepanet(char *, char *, char *, void (*) (char *)); - int DLLIMPORT ENopen(char *, char *, char *); - int DLLIMPORT ENsaveinpfile(char *); - int DLLIMPORT ENclose(void); - - int DLLIMPORT ENsolveH(void); - int DLLIMPORT ENsaveH(void); - int DLLIMPORT ENopenH(void); - int DLLIMPORT ENinitH(int); - int DLLIMPORT ENrunH(long *); - int DLLIMPORT ENnextH(long *); - int DLLIMPORT ENcloseH(void); - int DLLIMPORT ENsavehydfile(char *); - int DLLIMPORT ENusehydfile(char *); - - int DLLIMPORT ENsolveQ(void); - int DLLIMPORT ENopenQ(void); - int DLLIMPORT ENinitQ(int); - int DLLIMPORT ENrunQ(long *); - int DLLIMPORT ENnextQ(long *); - int DLLIMPORT ENstepQ(long *); - int DLLIMPORT ENcloseQ(void); - - int DLLIMPORT ENwriteline(char *); - int DLLIMPORT ENreport(void); - int DLLIMPORT ENresetreport(void); - int DLLIMPORT ENsetreport(char *); - - int DLLIMPORT ENgetcontrol(int, int *, int *, float *, - int *, float *); - int DLLIMPORT ENgetcount(int, int *); - int DLLIMPORT ENgetoption(int, float *); - int DLLIMPORT ENgettimeparam(int, long *); - int DLLIMPORT ENgetflowunits(int *); - int DLLIMPORT ENgetpatternindex(char *, int *); - int DLLIMPORT ENgetpatternid(int, char *); - int DLLIMPORT ENgetpatternlen(int, int *); - int DLLIMPORT ENgetpatternvalue(int, int, float *); - int DLLIMPORT ENgetqualtype(int *, int *); - int DLLIMPORT ENgeterror(int, char *, int); - - int DLLIMPORT ENgetnodeindex(char *, int *); - int DLLIMPORT ENgetnodeid(int, char *); - int DLLIMPORT ENgetnodetype(int, int *); - int DLLIMPORT ENgetnodevalue(int, int, float *); - - int DLLIMPORT ENgetnumdemands(int, int *); - int DLLIMPORT ENgetbasedemand(int, int, float *); - int DLLIMPORT ENgetdemandpattern(int, int, int *); - - int DLLIMPORT ENgetlinkindex(char *, int *); - int DLLIMPORT ENgetlinkid(int, char *); - int DLLIMPORT ENgetlinktype(int, int *); - int DLLIMPORT ENgetlinknodes(int, int *, int *); - int DLLIMPORT ENgetlinkvalue(int, int, float *); - - int DLLIMPORT ENgetcurve(int curveIndex, int *nValues, float **xValues, float **yValues); - - int DLLIMPORT ENgetversion(int *); - - int DLLIMPORT ENsetcontrol(int, int, int, float, int, float); - int DLLIMPORT ENsetnodevalue(int, int, float); - int DLLIMPORT ENsetlinkvalue(int, int, float); - int DLLIMPORT ENaddpattern(char *); - int DLLIMPORT ENsetpattern(int, float *, int); - int DLLIMPORT ENsetpatternvalue(int, int, float); - int DLLIMPORT ENsettimeparam(int, long); - int DLLIMPORT ENsetoption(int, float); - int DLLIMPORT ENsetstatusreport(int); - int DLLIMPORT ENsetqualtype(int, char *, char *, char *); - - //LemonTiger functions - /* See testLT.c for a LemonTiger test */ - - //LT equivalent to ENopenH() + ENopenQ() + ENinitH() + ENinitQ() - int DLLIMPORT ENopeninitHQ(); - - //LT equivalent to ENrunQ() + ENnextQ(); - int DLLIMPORT ENrunnextHQ(long*, long*); - - //LT equivalent to ENrunQ() + ENstepQ(); - int DLLIMPORT ENrunstepHQ(long*, long*); - - //LT equivalent to ENcloseH() + ENcloseQ(); - int DLLIMPORT ENcloseHQ(); - - -#ifdef __cplusplus -}; -#endif - - - -#endif //LEMONTIGER_H - - - diff --git a/src/testLT.c b/src/testLT.c deleted file mode 100644 index 3af7b68..0000000 --- a/src/testLT.c +++ /dev/null @@ -1,112 +0,0 @@ -/* Test file for epanet LemonTiger - Jinduan's version - The extension enables syncronized computation of hydraulics - and water quality */ - -#include -#include "types.h" -#include "vars.h" -#include "lemontiger.h" - - - - -int main(int argc, char* argv[]) { - int err = 0; //error code - long stime = 0; //simulation time point, = t = Htime - long step = 1; //time to next time point, = tstep = hydstep - long tleft = 0; //time left in the simulation - int id, id2, id3; // some node id - float value; // some node/link value - int TIME_A = 3600*3; - int TIME_B = 3600*6; //two time points for testing - int TIME_C = 3600*10; - - - /* Asychronous solver (old epanet) */ - printf("*****Original EPANET results******\n"); - - if (err=ENopen(argv[1], argv[2], "")) return err; - ENgetnodeindex("184", &id); // a node far away from water source - ENgetlinkindex("101", &id2); // a link close to the lake - ENgetnodeindex("199", &id3); // a node close to the lake (tracer point) - - for (ENopenH(), ENinitH(1), step=1; - // must save intermediate results to disk (initH(1)), otherwise WQ solver won't execute - step>0; ENnextH(&step)) { - - ENrunH(&stime); - - - if (stime == TIME_A || stime == TIME_B || stime == TIME_C) { // grab some results - printf("Hydraulic simulation time = %d sec, step = %d sec.\n", stime, step); - - ENgetnodevalue(id, EN_HEAD, &value); - printf("Node 184's head = \t%f.\n", value); - ENgetlinkvalue(id2, EN_FLOW, &value); - printf("Link 101's flowrate = \t%f. \n", value); - ENgetnodevalue(id3, EN_HEAD, &value); - printf("Node 199's head = \t%f.\n", value); - } - } - ENcloseH(); - - printf("\nReset time pointer and run WQ.\n"); - for (step=1, ENopenQ(), ENinitQ(0); // this operation resets the internal time pointer (back to 0) - step>0; ENnextQ(&step)) { - - ENrunQ(&stime); - - - // grab some results - if (stime == TIME_A || stime == TIME_B || stime == TIME_C) { - printf("WQ simulation time = %d sec, step = %d sec.\n", stime, step); - - ENgetnodevalue(id, EN_QUALITY, &value); - printf("Node 184's quality = \t%f.\n", value); - ENgetnodevalue(id3, EN_QUALITY, &value); - printf("Node 199's quality = \t%f.\n", value); - } - } - ENcloseQ(); - ENclose(); - - - /* Sychronous solver (LemonTiger) */ - printf("\n\n*****LemonTiger results******\n\n"); - - if (err=ENopen(argv[1], argv[2], "")) return err; - - for (ENopeninitHQ(), tleft=Dur; tleft>0; ) { - - //ENrunstepHQ(&stime, &tleft); - ENrunnextHQ(&stime, &tleft); //well I know it should be tstep - - if (stime == TIME_A || stime == TIME_B || stime == TIME_C) { - //if (! (stime%1800)){ - printf("Simulation = %d sec, time left = %d sec.\n", stime, tleft); - ENgetnodevalue(id, EN_HEAD, &value); - printf("Node 184's head = \t%f.\n", value); - - ENgetnodevalue(id, EN_QUALITY, &value); - printf("Node 184's quality = \t%f.\n", value); - - ENgetnodevalue(id3, EN_HEAD, &value); - printf("Node 199's head = \t%f.\n", value); - - ENgetnodevalue(id3, EN_QUALITY, &value); - printf("Node 199's quality = \t%f.\n", value); - - ENgetlinkvalue(id2, EN_FLOW, &value); - printf("Link 101's flowrate = \t%f. \n", value); - - - printf("\n"); - } - } - ENcloseHQ(); - ENclose(); - - -} - - From 44e44e08090e81560a4051144cf47b8f78dede7b Mon Sep 17 00:00:00 2001 From: Sam Hatchett Date: Tue, 5 Feb 2013 09:49:59 -0500 Subject: [PATCH 18/49] testing code for sampletown --- .gitignore | 2 +- src/testLemonTiger.cpp | 8 +-- test/sampletown.inp | 150 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 155 insertions(+), 5 deletions(-) create mode 100755 test/sampletown.inp diff --git a/.gitignore b/.gitignore index d13078d..8782d5f 100644 --- a/.gitignore +++ b/.gitignore @@ -117,7 +117,7 @@ xcuserdata *.metagen *.bi *.opensdf -test/* + Debug/ diff --git a/src/testLemonTiger.cpp b/src/testLemonTiger.cpp index 8d986ca..95e5350 100644 --- a/src/testLemonTiger.cpp +++ b/src/testLemonTiger.cpp @@ -24,7 +24,7 @@ int main(int argc, char * argv[]) { /* Batch solver (old epanet) */ cout << "*****Original EPANET results******" << endl; - checkErr( ENopen(argv[1], argv[2], "out.bin"), "ENopen" ); + checkErr( ENopen(argv[1], argv[2], (char*)""), "ENopen" ); checkErr( ENopenH(), "ENopenH" ); checkErr( ENinitH(EN_SAVE), "ENinitH" ); @@ -74,7 +74,7 @@ int main(int argc, char * argv[]) { /* stepwise solver (LemonTiger) */ cout << "*****LemonTiger results******" << endl; - checkErr( ENopen(argv[1], argv[2], (char*)"out2.bin"), "ENopen" ); + checkErr( ENopen(argv[1], argv[2], (char*)""), "ENopen" ); checkErr( ENopenH(), "ENopenH" ); checkErr( ENinitH(EN_NOSAVE), "ENinitH" ); @@ -121,7 +121,7 @@ void hydStats() { int nodeIndex; float head; ENgettimeparam(EN_HTIME, &htime); - ENgetnodeindex((char*)"1", &nodeIndex); + ENgetnodeindex((char*)"NewportTank", &nodeIndex); ENgetnodevalue(nodeIndex, EN_HEAD, &head); cout << htime << "\t\th = " << head << endl; } @@ -131,7 +131,7 @@ void qualStats() { int nodeIndex; float quality; ENgettimeparam(EN_HTIME, &htime); - ENgetnodeindex((char*)"1", &nodeIndex); + ENgetnodeindex((char*)"NewportTank", &nodeIndex); ENgetnodevalue(nodeIndex, EN_QUALITY, &quality); cout << htime << "\t\tc = " << quality << endl; } diff --git a/test/sampletown.inp b/test/sampletown.inp new file mode 100755 index 0000000..787f689 --- /dev/null +++ b/test/sampletown.inp @@ -0,0 +1,150 @@ +[TITLE] + + +[JUNCTIONS] +;ID Elev Demand Pattern + TreatmentPlant 0 0 ; + Montgomery 0 80 ; + Tennessee 0 250 ; + Reading 0 100 ; + Mills 0 1000 stepdemand ; + Vine 0 50 ; + +[RESERVOIRS] +;ID Head Pattern + Resr 100 ; + +[TANKS] +;ID Elevation InitLevel MinLevel MaxLevel Diameter MinVol VolCurve + NewportTank 50 40 0 80 20 0 ; + +[PIPES] +;ID Node1 Node2 Length Diameter Roughness MinorLoss Status + ReservoirCheckValve Resr TreatmentPlant 10 4 100 0 CV ; + 2 TreatmentPlant Montgomery 3 6 100 0 Open ; + 3 Montgomery Tennessee 6 6 100 0 Open ; + 4 Tennessee Reading 12 6 100 0 Open ; + 5 Reading Mills 24 6 100 0 Open ; + NewportTankPipe Tennessee NewportTank 50 3 100 0 Open ; + 1 Reading Vine 50 6 100 0 Open ; + +[PUMPS] +;ID Node1 Node2 Parameters + +[VALVES] +;ID Node1 Node2 Diameter Type Setting MinorLoss + +[TAGS] + +[DEMANDS] +;Junction Demand Pattern Category + +[STATUS] +;ID Status/Setting + +[PATTERNS] +;ID Multipliers +; + stepdemand 1 1 1 1 1 1 + stepdemand 0 0 0 0 0 0 + +[CURVES] +;ID X-Value Y-Value + +[CONTROLS] + + + + +[RULES] + + + +[ENERGY] + Global Efficiency 75 + Global Price 0 + Demand Charge 0 + +[EMITTERS] +;Junction Coefficient + +[QUALITY] +;Node InitQual + +[SOURCES] +;Node Type Quality Pattern + +[REACTIONS] +;Type Pipe/Tank Coefficient + + +[REACTIONS] + Order Bulk 1 + Order Tank 1 + Order Wall 1 + Global Bulk 0 + Global Wall 0 + Limiting Potential 0 + Roughness Correlation 0 + +[MIXING] +;Tank Model + +[TIMES] + Duration 24:00 + Hydraulic Timestep 0:10 + Quality Timestep 0:01 + Pattern Timestep 1:00 + Pattern Start 0:00 + Report Timestep 1:00 + Report Start 0:00 + Start ClockTime 12 am + Statistic NONE + +[REPORT] + Status No + Summary No + Page 0 + +[OPTIONS] + Units GPM + Headloss H-W + Specific Gravity 1 + Viscosity 1 + Trials 40 + Accuracy 0.001 + CHECKFREQ 2 + MAXCHECK 10 + DAMPLIMIT 0 + Unbalanced Continue 10 + Pattern 1 + Demand Multiplier 1.0 + Emitter Exponent 0.5 + Quality Trace Resr + Diffusivity 1 + Tolerance 0.01 + +[COORDINATES] +;Node X-Coord Y-Coord + TreatmentPlant -1075.95 6943.94 + Montgomery 1273.73 6946.20 + Tennessee 3204.11 6946.20 + Reading 6352.85 6946.20 + Mills 10226.04 6943.94 + Vine 6356.24 5063.29 + Resr -2414.20 6923.08 + NewportTank 3209.76 8318.26 + +[VERTICES] +;Link X-Coord Y-Coord + +[LABELS] +;X-Coord Y-Coord Label & Anchor Node + +[BACKDROP] + DIMENSIONS 0.00 0.00 10000.00 10000.00 + UNITS Meters + FILE + OFFSET 0.00 0.00 + +[END] From 2ad5765dd3d95a3a662d678d831e1fe1c50eed6b Mon Sep 17 00:00:00 2001 From: Sam Hatchett Date: Tue, 5 Feb 2013 10:58:55 -0500 Subject: [PATCH 19/49] pretty output --- src/testLemonTiger.cpp | 150 +++++++++++++++++++++++++++++++---------- 1 file changed, 114 insertions(+), 36 deletions(-) diff --git a/src/testLemonTiger.cpp b/src/testLemonTiger.cpp index 95e5350..e521019 100644 --- a/src/testLemonTiger.cpp +++ b/src/testLemonTiger.cpp @@ -1,21 +1,40 @@ +#include +#include #include "testLemonTiger.h" #include "toolkit.h" +#define COLW 15 +#define OUTPRECISION 6 using namespace std; +typedef struct { + double head; + double demand; + double quality; +} singleState_t; + +typedef map networkState_t; // nodeIndex, state +typedef map result_t; // time, networkState +// access results by, for instance, resultsContainer[time][nodeIndex].head + + + void checkErr(int err, std::string function); -void hydStats(); -void qualStats(); +void saveHydResults(networkState_t* networkState); +void saveQualResults(networkState_t* networkState); +void printResults(result_t* state1, result_t* state2, std::ostream& out); int main(int argc, char * argv[]) { + // create storage structures for results. + result_t epanetResults, lemonTigerResults; + cout << "Lemon Tiger TEST" << endl << "________________" << endl; - long tstep = 0; long simulationTime = 0; long nextEventH = 0, nextEventQ = 0; long simTimeRemaining = 0; @@ -32,15 +51,14 @@ int main(int argc, char * argv[]) { cout << "Running hydraulics..." << endl; do { - /* Solve for hydraulics & advance to next time period */ - tstep = 0; - + /* Solve for hydraulics & advance to next time period */ checkErr( ENrunH(&simulationTime), "ENrunH" ); checkErr( ENnextH(&nextEventH), "ENnextH" ); - hydStats(); - // gather hydraulic results + saveHydResults(&epanetResults[simulationTime]); + + } while (nextEventH > 0); // hydraulics are done @@ -56,7 +74,8 @@ int main(int argc, char * argv[]) { checkErr( ENrunQ(&simulationTime), "ENrunQ" ); checkErr( ENnextQ(&nextEventH), "ENstepQ" ); - qualStats(); + // gather quality results + saveQualResults(&epanetResults[simulationTime]); } while (nextEventH > 0); // water quality is done @@ -83,22 +102,15 @@ int main(int argc, char * argv[]) { cout << "Running stepwise hydraulics and water quality..." << endl; do { - /* Solve for hydraulics & advance to next time period */ - tstep = 0; - + /* Solve for hydraulics & advance to next time period */ checkErr( ENrunH(&simulationTime), "ENrunH" ); checkErr( ENrunQ(&simulationTime), "ENrunQ" ); - - //stats(); - + checkErr( ENnextH(&nextEventH), "ENnextH" ); checkErr( ENnextQ(&nextEventQ), "ENstepQ" ); - //hydStats(); - qualStats(); - - // wq results - //cout << simulationTime << "\t\t" << nextEventH << endl; + saveHydResults(&lemonTigerResults[simulationTime]); + saveQualResults(&lemonTigerResults[simulationTime]); } while (nextEventH > 0); cout << "\t\t\tdone." << endl; @@ -109,34 +121,100 @@ int main(int argc, char * argv[]) { checkErr( ENclose(), "ENclose" ); + // summarize the results + printResults(&epanetResults, &lemonTigerResults, cout); + + } catch (int err) { cerr << "exiting with error " << err << endl; } } - -void hydStats() { - long htime; - int nodeIndex; - float head; - ENgettimeparam(EN_HTIME, &htime); - ENgetnodeindex((char*)"NewportTank", &nodeIndex); - ENgetnodevalue(nodeIndex, EN_HEAD, &head); - cout << htime << "\t\th = " << head << endl; +void saveHydResults(networkState_t* networkState) { + int nNodes; + float head, demand; + ENgetcount(EN_NODECOUNT, &nNodes); + + for (int iNode = 1; iNode <= nNodes; iNode++) { + ENgetnodevalue(iNode, EN_HEAD, &head); + ENgetnodevalue(iNode, EN_DEMAND, &demand); + (*networkState)[iNode].head = head; + (*networkState)[iNode].demand = demand; + } } -void qualStats() { - long htime; - int nodeIndex; + +void saveQualResults(networkState_t* networkState) { + int nNodes; float quality; - ENgettimeparam(EN_HTIME, &htime); - ENgetnodeindex((char*)"NewportTank", &nodeIndex); - ENgetnodevalue(nodeIndex, EN_QUALITY, &quality); - cout << htime << "\t\tc = " << quality << endl; + ENgetcount(EN_NODECOUNT, &nNodes); + + for (int iNode = 1; iNode <= nNodes; iNode++) { + ENgetnodevalue(iNode, EN_QUALITY, &quality); + (*networkState)[iNode].quality = quality; + } } +void printResults(result_t* results1, result_t* results2, std::ostream &out) { + + result_t::const_iterator resultIterator; + + for (resultIterator = (*results1).begin(); resultIterator != (*results1).end(); ++resultIterator) { + // get the current frame + const long time = resultIterator->first; + const networkState_t state1 = resultIterator->second; + + // see if this time is indexed in the second state container + if ((*results2).find(time) == (*results2).end()) { + // nope. + out << "time " << time << " not found in second result set" << endl; + } + else { + // get the second result set's state + const networkState_t state2 = (*results2)[time]; + + // print the current simulation time + out << left; + out << setfill('*') << setw(100) << "*" << endl; + out << setfill(' '); + out << setw(4) << "T = " << setw(6) << time; + out << "|" << setw(3*COLW) << "EPANET"; + out << "|" << setw(3*COLW) << "LemonTiger" << endl; + out << setw(10) << "Index" << "|"; + out << setw(COLW) << "Demand" << setw(COLW) << "Head" << setw(COLW) << "Quality" << "|"; + out << setw(COLW) << "Demand" << setw(COLW) << "Head" << setw(COLW) << "Quality" << endl; + out << setprecision(OUTPRECISION); + + // loop through the nodes in the networkState objs, and print out the results for this time period + networkState_t::const_iterator networkIterator; + for (networkIterator = state1.begin(); networkIterator != state1.end(); ++networkIterator) { + int nodeIndex = networkIterator->first; + // trusting that all nodes are present... + const singleState_t nodeState1 = networkIterator->second; + const singleState_t nodeState2 = state2.at(nodeIndex); + + // epanet + out << setw(10) << nodeIndex << "|"; + out << setw(COLW) << nodeState1.demand; + out << setw(COLW) << nodeState1.head; + out << setw(COLW) << nodeState1.quality; + + // lemontiger + out << "|"; + out << setw(COLW) << nodeState2.demand; + out << setw(COLW) << nodeState2.head; + out << setw(COLW) << nodeState2.quality; + out << endl; + + } + + } + } + +} + void checkErr(int err, std::string function) { if (err > 0) { From 992866e602eb5e061fde30b24ebc1efaa00947c7 Mon Sep 17 00:00:00 2001 From: mickey Date: Fri, 22 Feb 2013 10:51:05 -0500 Subject: [PATCH 20/49] Bug fixed - Wall reaction coefficient variable in water quality simulation is explicitly defined and added since epanet uses the roughness resistance variable as it and caused some error in step wise calculation. --- src/quality.c | 4 ++-- src/types.h | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/quality.c b/src/quality.c index cf3a094..cacbbe9 100755 --- a/src/quality.c +++ b/src/quality.c @@ -1458,7 +1458,7 @@ void ratecoeffs() { kw = Link[k].Kw; if (kw != 0.0) kw = piperate(k); - Link[k].R = kw; + Link[k].Rc = kw; R[k] = 0.0; } } /* End of ratecoeffs */ @@ -1541,7 +1541,7 @@ double pipereact(int k, double c, double v, long dt) /* Otherwise find bulk & wall reaction rates */ rbulk = bulkrate(c,Link[k].Kb,BulkOrder)*Bucf; - rwall = wallrate(c,Link[k].Diam,Link[k].Kw,Link[k].R); + rwall = wallrate(c,Link[k].Diam,Link[k].Kw,Link[k].Rc); /* Find change in concentration over timestep */ dcbulk = rbulk*(double)dt; diff --git a/src/types.h b/src/types.h index 81fe7f1..3374f8f 100755 --- a/src/types.h +++ b/src/types.h @@ -208,6 +208,7 @@ typedef struct /* LINK OBJECT */ double Kb; /* Bulk react. coeff */ double Kw; /* Wall react. coeff */ double R; /* Flow resistance */ + double Rc; /* Reaction cal */ //woohn 2/11/13 char Type; /* Link type */ char Stat; /* Initial status */ char Rpt; /* Reporting flag */ From bd62f399f90dfc2fedee22ad7369053cdb2bc255 Mon Sep 17 00:00:00 2001 From: sam hatchett Date: Sat, 9 Mar 2013 09:46:12 -0500 Subject: [PATCH 21/49] fake data was being written to the binary file. if a link element is nominally closed, even if there's actually flow calculated there, the flow is disregarded upon writing results. so when the flow is read back in, it's zero -- which is different than it would have been if it had stayed in memory. i wonder what that does to mass balance? this version works, at least with Net3, simplenet, and SampleTown -- but the results are non-canonical, as the current workaround for the issue above writes tiny flow values to the binary file for closed elements. presumably we should check for closed status in the transport() function. --- src/epanet.c | 4 +- src/hydraul.c | 12 ++- src/output.c | 6 +- src/quality.c | 53 +++++++++++-- src/testLemonTiger.cpp | 171 ++++++++++++++++++++++++++++++++--------- src/types.h | 2 +- src/vars.h | 1 + test/Net3.inp | 2 +- 8 files changed, 197 insertions(+), 54 deletions(-) diff --git a/src/epanet.c b/src/epanet.c index a7ee920..c9248b9 100755 --- a/src/epanet.c +++ b/src/epanet.c @@ -1668,9 +1668,9 @@ int DLLEXPORT ENgetlinkvalue(int index, int code, float *value) case EN_FLOW: /*** Updated 10/25/00 ***/ - if (S[index] <= CLOSED) v = 0.0; + //if (S[index] <= CLOSED) v = 0.0; - else v = Q[index]*Ucf[FLOW]; + /*else*/ v = Q[index]*Ucf[FLOW]; break; case EN_VELOCITY: diff --git a/src/hydraul.c b/src/hydraul.c index 8a91d6d..6c138f9 100755 --- a/src/hydraul.c +++ b/src/hydraul.c @@ -258,6 +258,9 @@ int nexthyd(long *tstep) else { Htime++; /* Force completion of analysis */ + if (OpenQflag) { + Qtime++; // force completion of wq analysis too + } } *tstep = hydstep; return(errcode); @@ -1049,13 +1052,8 @@ void tanklevels(long tstep) /* Update the tank's volume & water elevation */ n = Tank[i].Node; - - // only adjust tank volume if we're in sequential mode. - // otherwise, the tankmixing function will do it for us. - if (!OpenQflag) { - dv = D[n]*tstep; - Tank[i].V += dv; - } + dv = D[n]*tstep; + Tank[i].V += dv; /*** Updated 6/24/02 ***/ /* Check if tank full/empty within next second */ diff --git a/src/output.c b/src/output.c index ea56057..048a27b 100755 --- a/src/output.c +++ b/src/output.c @@ -161,8 +161,8 @@ int savehyd(long *htime) /* Force flow in closed links to be zero then save flows */ for (i=1; i<=Nlinks; i++) { - if (S[i] <= CLOSED) x[i] = 0.0f; - else x[i] = (REAL4)Q[i]; + //if (S[i] <= CLOSED) x[i] = 0.0f; + /*else*/ x[i] = (REAL4)Q[i]; } fwrite(x+1,sizeof(REAL4),Nlinks,HydFile); @@ -377,7 +377,7 @@ int nodeoutput(int j, REAL4 *x, double ucf) } /* End of nodeoutput */ -int linkoutput(int j, float *x, double ucf) +int linkoutput(int j, REAL4 *x, double ucf) /* **---------------------------------------------------------------- ** Input: j = type of link variable diff --git a/src/quality.c b/src/quality.c index cacbbe9..7311818 100755 --- a/src/quality.c +++ b/src/quality.c @@ -152,7 +152,9 @@ void initqual() for (i=1; i<=Ntanks; i++) Tank[i].V = Tank[i].V0; for (i=1; i<=Nnodes; i++) if (Node[i].S != NULL) Node[i].S->Smass = 0.0; - + + QTankVolumes = calloc(Ntanks, sizeof(double)); // keep track of previous step's tank volumes. + /* Set WQ parameters */ Bucf = 1.0; Tucf = 1.0; @@ -224,8 +226,15 @@ int runqual(long *t) { errcode = gethyd(&hydtime, &hydstep); if (!OpenHflag) { // test for sequential vs stepwise + // sequential Htime = hydtime + hydstep; } + else { + // stepwise + for (int i=1; i<= Ntanks; ++i) { + QTankVolumes[i-1] = Tank[i].V; + } + } } return(errcode); } @@ -249,6 +258,26 @@ int nextqual(long *tstep) *tstep = 0; hydstep = Htime - Qtime; + double *tankVolumes; + // if we're operating in stepwise mode, capture the tank levels so we can restore them later. + if (OpenHflag) { + tankVolumes = calloc(Ntanks, sizeof(double)); + for (int i=1; i<=Ntanks; ++i) { + if (Tank[i].A != 0) { // skip reservoirs + tankVolumes[i-1] = Tank[i].V; + } + } + // restore the previous step's tank volumes + for (int i=1; i<=Ntanks; i++) { + if (Tank[i].A != 0) { // skip reservoirs again + int n = Tank[i].Node; + Tank[i].V = QTankVolumes[i-1]; + H[n] = tankgrade(i,Tank[i].V); + } + } + } + + /* Perform water quality routing over this time step */ if (Qualflag != NONE && hydstep > 0) transport(hydstep); @@ -259,6 +288,19 @@ int nextqual(long *tstep) /* Save final output if no more time steps */ if (!errcode && Saveflag && *tstep == 0) errcode = savefinaloutput(); + + // restore tank levels to post-runH state, if needed. + if (OpenHflag) { + for (int i=1; i<=Ntanks; i++) { + if (Tank[i].A != 0) { // skip reservoirs again + int n = Tank[i].Node; + Tank[i].V = tankVolumes[i-1]; + H[n] = tankgrade(i,Tank[i].V); + } + } + free(tankVolumes); + } + return(errcode); } @@ -326,6 +368,7 @@ int closequal() free(MassIn); free(R); free(XC); + free(QTankVolumes); return(errcode); } @@ -423,6 +466,8 @@ void transport(long tstep) */ { long qtime, dt; + + /* Repeat until elapsed time equals hydraulic time step */ @@ -439,6 +484,8 @@ void transport(long tstep) release(dt); /* Release new nodal flows */ } updatesourcenodes(tstep); /* Update quality at source nodes */ + + } @@ -1023,10 +1070,6 @@ void updatetanks(long dt) default: tankmix1(i,dt); break; } - // if we're operating in stepwise mode, we'll need to update tank head conditions - if (OpenHflag) { - H[n] = tankgrade(i,Tank[i].V); - } } } } diff --git a/src/testLemonTiger.cpp b/src/testLemonTiger.cpp index e521019..7cba39f 100644 --- a/src/testLemonTiger.cpp +++ b/src/testLemonTiger.cpp @@ -1,6 +1,6 @@ #include #include - +#include #include "testLemonTiger.h" #include "toolkit.h" @@ -13,9 +13,19 @@ typedef struct { double head; double demand; double quality; -} singleState_t; +} nodeState_t; -typedef map networkState_t; // nodeIndex, state +typedef struct { + double flow; +} linkState_t; + +typedef map networkNodeState_t; // nodeIndex, state +typedef map networkLinkState_t; // linkIndex, state + +typedef struct { + networkNodeState_t nodeState; + networkLinkState_t linkState; +} networkState_t; typedef map result_t; // time, networkState // access results by, for instance, resultsContainer[time][nodeIndex].head @@ -25,6 +35,7 @@ void checkErr(int err, std::string function); void saveHydResults(networkState_t* networkState); void saveQualResults(networkState_t* networkState); void printResults(result_t* state1, result_t* state2, std::ostream& out); +void compare(result_t* results1, result_t* results2, std::ostream &out); int main(int argc, char * argv[]) { @@ -67,7 +78,7 @@ int main(int argc, char * argv[]) { cout << "Running WQ..." << endl; checkErr( ENopenQ(), "ENopenQ" ); - checkErr( ENinitQ(EN_SAVE), "ENinitQ" ); + checkErr( ENinitQ(EN_NOSAVE), "ENinitQ" ); do { @@ -105,12 +116,14 @@ int main(int argc, char * argv[]) { /* Solve for hydraulics & advance to next time period */ checkErr( ENrunH(&simulationTime), "ENrunH" ); checkErr( ENrunQ(&simulationTime), "ENrunQ" ); - + checkErr( ENnextH(&nextEventH), "ENnextH" ); checkErr( ENnextQ(&nextEventQ), "ENstepQ" ); + saveHydResults(&lemonTigerResults[simulationTime]); saveQualResults(&lemonTigerResults[simulationTime]); + } while (nextEventH > 0); cout << "\t\t\tdone." << endl; @@ -122,8 +135,8 @@ int main(int argc, char * argv[]) { // summarize the results - printResults(&epanetResults, &lemonTigerResults, cout); - + //printResults(&epanetResults, &lemonTigerResults, cout); + compare(&epanetResults, &lemonTigerResults, cout); } catch (int err) { cerr << "exiting with error " << err << endl; @@ -132,15 +145,19 @@ int main(int argc, char * argv[]) { void saveHydResults(networkState_t* networkState) { - int nNodes; - float head, demand; + int nNodes, nLinks; + float head, demand, flow; ENgetcount(EN_NODECOUNT, &nNodes); - - for (int iNode = 1; iNode <= nNodes; iNode++) { + ENgetcount(EN_LINKCOUNT, &nLinks); + for (int iNode = 1; iNode <= nNodes; ++iNode) { ENgetnodevalue(iNode, EN_HEAD, &head); ENgetnodevalue(iNode, EN_DEMAND, &demand); - (*networkState)[iNode].head = head; - (*networkState)[iNode].demand = demand; + (*networkState).nodeState[iNode].head = head; + (*networkState).nodeState[iNode].demand = demand; + } + for (int iLink = 1; iLink <= nLinks; ++iLink) { + ENgetlinkvalue(iLink, EN_FLOW, &flow); + (*networkState).linkState[iLink].flow = flow; } } @@ -152,7 +169,7 @@ void saveQualResults(networkState_t* networkState) { for (int iNode = 1; iNode <= nNodes; iNode++) { ENgetnodevalue(iNode, EN_QUALITY, &quality); - (*networkState)[iNode].quality = quality; + (*networkState).nodeState[iNode].quality = quality; } } @@ -164,7 +181,8 @@ void printResults(result_t* results1, result_t* results2, std::ostream &out) { for (resultIterator = (*results1).begin(); resultIterator != (*results1).end(); ++resultIterator) { // get the current frame const long time = resultIterator->first; - const networkState_t state1 = resultIterator->second; + const networkNodeState_t nodeState1 = resultIterator->second.nodeState; + const networkLinkState_t linkState1 = resultIterator->second.linkState; // see if this time is indexed in the second state container if ((*results2).find(time) == (*results2).end()) { @@ -173,8 +191,8 @@ void printResults(result_t* results1, result_t* results2, std::ostream &out) { } else { // get the second result set's state - const networkState_t state2 = (*results2)[time]; - + const networkNodeState_t networkNodeState2 = (*results2)[time].nodeState; + const networkLinkState_t networkLinkState2 = (*results2)[time].linkState; // print the current simulation time out << left; out << setfill('*') << setw(100) << "*" << endl; @@ -188,34 +206,117 @@ void printResults(result_t* results1, result_t* results2, std::ostream &out) { out << setprecision(OUTPRECISION); // loop through the nodes in the networkState objs, and print out the results for this time period - networkState_t::const_iterator networkIterator; - for (networkIterator = state1.begin(); networkIterator != state1.end(); ++networkIterator) { - int nodeIndex = networkIterator->first; + networkNodeState_t::const_iterator networkNodeIterator; + for (networkNodeIterator = nodeState1.begin(); networkNodeIterator != nodeState1.end(); ++networkNodeIterator) { + int nodeIndex = networkNodeIterator->first; // trusting that all nodes are present... - const singleState_t nodeState1 = networkIterator->second; - const singleState_t nodeState2 = state2.at(nodeIndex); - - // epanet - out << setw(10) << nodeIndex << "|"; - out << setw(COLW) << nodeState1.demand; - out << setw(COLW) << nodeState1.head; - out << setw(COLW) << nodeState1.quality; - - // lemontiger - out << "|"; - out << setw(COLW) << nodeState2.demand; - out << setw(COLW) << nodeState2.head; - out << setw(COLW) << nodeState2.quality; - out << endl; + const nodeState_t nodeState1 = networkNodeIterator->second; + const nodeState_t nodeState2 = networkNodeState2.at(nodeIndex); + if (nodeState1.quality != nodeState2.quality ) { + // epanet + out << setw(10) << nodeIndex << "|"; + out << setw(COLW) << nodeState1.demand; + out << setw(COLW) << nodeState1.head; + out << setw(COLW) << nodeState1.quality; + + // lemontiger + out << "|"; + out << setw(COLW) << nodeState2.demand; + out << setw(COLW) << nodeState2.head; + out << setw(COLW) << nodeState2.quality; + out << endl; + } } + networkLinkState_t::const_iterator networkLinkIterator; + for (networkLinkIterator = linkState1.begin(); networkLinkIterator != linkState1.end(); ++networkLinkIterator) { + int linkIndex = networkLinkIterator->first; + // trusting that all nodes are present... + const linkState_t linkState1 = networkLinkIterator->second; + const linkState_t linkState2 = networkLinkState2.at(linkIndex); + + if ( linkState1.flow != linkState2.flow ) { + // epanet + out << setw(10) << linkIndex << "|"; + out << setw(COLW) << linkState1.flow; + + // lemontiger + out << "|"; + out << setw(COLW) << linkState2.flow; + out << endl; + } + } + + } } } + +void compare(result_t* results1, result_t* results2, std::ostream &out) { + + double sumHeadDiff=0, sumDemandDiff=0, sumQualDiff=0, sumFlowDiff=0; + + result_t::const_iterator resultIterator; + + for (resultIterator = (*results1).begin(); resultIterator != (*results1).end(); ++resultIterator) { + // get the current frame + const long time = resultIterator->first; + const networkNodeState_t nodeState1 = resultIterator->second.nodeState; + const networkLinkState_t linkState1 = resultIterator->second.linkState; + + // see if this time is indexed in the second state container + if ((*results2).find(time) == (*results2).end()) { + // nope. + out << "time " << time << " not found in second result set" << endl; + } + else { + // get the second result set's state + const networkNodeState_t networkNodeState2 = (*results2)[time].nodeState; + const networkLinkState_t networkLinkState2 = (*results2)[time].linkState; + double qualD=0; + + networkNodeState_t::const_iterator networkNodeIterator; + for (networkNodeIterator = nodeState1.begin(); networkNodeIterator != nodeState1.end(); ++networkNodeIterator) { + int nodeIndex = networkNodeIterator->first; + // trusting that all nodes are present... + const nodeState_t nodeState1 = networkNodeIterator->second; + const nodeState_t nodeState2 = networkNodeState2.at(nodeIndex); + + sumHeadDiff += fabs(nodeState1.head - nodeState2.head); + sumDemandDiff += fabs(nodeState1.demand - nodeState2.demand); + + qualD += fabs(nodeState1.quality - nodeState2.quality); + } + //out << "T: " << time << " dq: " << setprecision(20) << qualD << endl; + sumQualDiff += qualD; + + networkLinkState_t::const_iterator networkLinkIterator; + for (networkLinkIterator = linkState1.begin(); networkLinkIterator != linkState1.end(); ++networkLinkIterator) { + int linkIndex = networkLinkIterator->first; + // trusting that all nodes are present... + const linkState_t linkState1 = networkLinkIterator->second; + const linkState_t linkState2 = networkLinkState2.at(linkIndex); + + sumFlowDiff += fabs(linkState1.flow - linkState2.flow); + } + } + } + + int c1 = 18; + int p = 20; + out << setw(c1) << "Head Diff:" << setprecision(p) << sumHeadDiff << endl; + out << setw(c1) << "Demand Diff:" << setprecision(p) << sumDemandDiff << endl; + out << setw(c1) << "Quality Diff:" << setprecision(p) << sumQualDiff << endl; + out << setw(c1) << "Flow Diff:" << setprecision(p) << sumFlowDiff << endl; + + +} + + void checkErr(int err, std::string function) { if (err > 0) { cerr << "Error in " << function << ": " << err << endl; diff --git a/src/types.h b/src/types.h index 3374f8f..343b11f 100755 --- a/src/types.h +++ b/src/types.h @@ -28,7 +28,7 @@ AUTHOR: L. Rossman Definition of 4-byte integers & reals ------------------------------------------- */ -typedef float REAL4; //(2.00.11 - LR) +typedef double REAL4; //(2.00.11 - LR) typedef int INT4; //(2.00.12 - LR) /* diff --git a/src/vars.h b/src/vars.h index b6d9b49..3ea8f49 100755 --- a/src/vars.h +++ b/src/vars.h @@ -153,6 +153,7 @@ AUTHOR: L. Rossman *X, /* General purpose array */ *XC; /* General Purpose array - WQ */ double *H; /* Node heads */ + double *QTankVolumes; STmplist *Patlist; /* Temporary time pattern list */ STmplist *Curvelist; /* Temporary list of curves */ Spattern *Pattern; /* Time patterns */ diff --git a/test/Net3.inp b/test/Net3.inp index e169140..8e39dd1 100644 --- a/test/Net3.inp +++ b/test/Net3.inp @@ -333,7 +333,7 @@ Link 330 OPEN IF Node 1 ABOVE 19.1 [TIMES] Duration 24:00 - Hydraulic Timestep 1:00 + Hydraulic Timestep 1:00 Quality Timestep 0:05 Pattern Timestep 1:00 Pattern Start 0:00 From 8e499b0318112e5b411f9622ff526c2cd7dee110 Mon Sep 17 00:00:00 2001 From: sam hatchett Date: Sat, 9 Mar 2013 09:46:31 -0500 Subject: [PATCH 22/49] adding a very simple network --- test/simplenet.inp | 123 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100644 test/simplenet.inp diff --git a/test/simplenet.inp b/test/simplenet.inp new file mode 100644 index 0000000..a0ccdc0 --- /dev/null +++ b/test/simplenet.inp @@ -0,0 +1,123 @@ +[TITLE] +EPANET Example Network 3 +Example showing how the percent of Lake water in a dual-source +system changes over time. + +[JUNCTIONS] +;ID Elev Demand Pattern + node1 147 1 1 ; + node2 147 1 1 + +[RESERVOIRS] +;ID Head Pattern + reservoir 220.0 ; + +[TANKS] +;ID Elevation InitLevel MinLevel MaxLevel Diameter MinVol VolCurve + +[PIPES] +;ID Node1 Node2 Length Diameter Roughness MinorLoss Status + pipe1 reservoir node1 100 12 100 0 Open ; + pipe2 node1 node2 100 12 100 0 Open ; + +[PUMPS] +;ID Node1 Node2 Parameters + +[VALVES] +;ID Node1 Node2 Diameter Type Setting MinorLoss + +[TAGS] + +[DEMANDS] +;Junction Demand Pattern Category + +[STATUS] +;ID Status/Setting + 10 Closed + +[PATTERNS] +;ID Multipliers +;General Default Demand Pattern + 1 1 + +[CURVES] +;ID X-Value Y-Value + + +[CONTROLS] + +[RULES] + +[ENERGY] + Global Efficiency 75 + Global Price 0.0 + Demand Charge 0.0 + +[EMITTERS] +;Junction Coefficient + +[QUALITY] +;Node InitQual + + +[SOURCES] +;Node Type Quality Pattern + +[REACTIONS] +;Type Pipe/Tank Coefficient + + +[REACTIONS] + Order Bulk 1 + Order Tank 1 + Order Wall 1 + Global Bulk 0.0 + Global Wall 0.0 + Limiting Potential 0.0 + Roughness Correlation 0.0 + +[MIXING] +;Tank Model + +[TIMES] + Duration 24:00 + Hydraulic Timestep 0:05 + Quality Timestep 0:05 + Pattern Timestep 1:00 + Pattern Start 0:00 + Report Timestep 1:00 + Report Start 0:00 + Start ClockTime 12 am + Statistic None + +[REPORT] + Status Yes + Summary No + Page 0 + +[OPTIONS] + Units GPM + Headloss H-W + Specific Gravity 1.0 + Viscosity 1.0 + Trials 40 + Accuracy 0.001 + CHECKFREQ 2 + MAXCHECK 10 + DAMPLIMIT 0 + Unbalanced Continue 10 + Pattern 1 + Demand Multiplier 1.0 + Emitter Exponent 0.5 + Quality Trace reservoir + Diffusivity 1.0 + Tolerance 0.01 + +[COORDINATES] +;Node X-Coord Y-Coord + + +[VERTICES] +;Link X-Coord Y-Coord + +[END] From f883a5551baa191bec6c9ac017f8e7027ff17828 Mon Sep 17 00:00:00 2001 From: mickey Date: Mon, 11 Mar 2013 11:54:03 -0400 Subject: [PATCH 23/49] Instead of changing block out status checking routine, water quality module considers pipe 'closed' status in the routine bypassing flow information just like tank volume changes. --- .../epanet/epanet.xcodeproj/project.pbxproj | 26 ++++++++---- src/epanet.c | 5 +-- src/output.c | 5 ++- src/quality.c | 41 +++++++++++++++---- src/testLemonTiger.cpp | 14 ++++--- src/testLemonTiger.h | 0 src/vars.h | 1 + 7 files changed, 66 insertions(+), 26 deletions(-) mode change 100644 => 100755 src/testLemonTiger.cpp mode change 100644 => 100755 src/testLemonTiger.h diff --git a/build/Xcode/epanet/epanet.xcodeproj/project.pbxproj b/build/Xcode/epanet/epanet.xcodeproj/project.pbxproj index 2a4b1da..0404df9 100644 --- a/build/Xcode/epanet/epanet.xcodeproj/project.pbxproj +++ b/build/Xcode/epanet/epanet.xcodeproj/project.pbxproj @@ -276,6 +276,9 @@ /* Begin PBXProject section */ 08FB7793FE84155DC02AAC07 /* Project object */ = { isa = PBXProject; + attributes = { + LastUpgradeCheck = 0460; + }; buildConfigurationList = 1DEB914E08733D8E0010E9CD /* Build configuration list for PBXProject "epanet" */; compatibilityVersion = "Xcode 3.2"; developmentRegion = English; @@ -366,10 +369,10 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + COMBINE_HIDPI_IMAGES = YES; COPY_PHASE_STRIP = NO; EXECUTABLE_PREFIX = lib; GCC_DYNAMIC_NO_PIC = NO; - GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_MODEL_TUNING = G5; GCC_OPTIMIZATION_LEVEL = 0; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; @@ -383,6 +386,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + COMBINE_HIDPI_IMAGES = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; EXECUTABLE_PREFIX = lib; GCC_MODEL_TUNING = G5; @@ -397,15 +401,19 @@ isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_OPTIMIZATION_LEVEL = 0; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; GCC_WARN_UNUSED_VARIABLE = YES; HEADER_SEARCH_PATHS = macinclude; ONLY_ACTIVE_ARCH = YES; - PREBINDING = NO; - SDKROOT = macosx10.6; + SDKROOT = macosx; }; name = Debug; }; @@ -413,13 +421,17 @@ isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; GCC_WARN_UNUSED_VARIABLE = YES; HEADER_SEARCH_PATHS = macinclude; - PREBINDING = NO; - SDKROOT = macosx10.6; + SDKROOT = macosx; }; name = Release; }; @@ -429,14 +441,12 @@ ALWAYS_SEARCH_USER_PATHS = NO; COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; - GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_MODEL_TUNING = G5; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = CLE; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; INFOPLIST_PREPROCESSOR_DEFINITIONS = ""; INSTALL_PATH = /usr/local/bin; - PREBINDING = NO; PRODUCT_NAME = runepanet; }; name = Debug; @@ -447,13 +457,11 @@ ALWAYS_SEARCH_USER_PATHS = NO; COPY_PHASE_STRIP = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_MODEL_TUNING = G5; GCC_PREPROCESSOR_DEFINITIONS = CLE; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; INFOPLIST_PREPROCESSOR_DEFINITIONS = ""; INSTALL_PATH = /usr/local/bin; - PREBINDING = NO; PRODUCT_NAME = runepanet; ZERO_LINK = NO; }; diff --git a/src/epanet.c b/src/epanet.c index c9248b9..d45da30 100755 --- a/src/epanet.c +++ b/src/epanet.c @@ -1668,9 +1668,8 @@ int DLLEXPORT ENgetlinkvalue(int index, int code, float *value) case EN_FLOW: /*** Updated 10/25/00 ***/ - //if (S[index] <= CLOSED) v = 0.0; - - /*else*/ v = Q[index]*Ucf[FLOW]; + if (S[index] <= CLOSED) v = 0.0; + else v = Q[index]*Ucf[FLOW]; break; case EN_VELOCITY: diff --git a/src/output.c b/src/output.c index 048a27b..8ade442 100755 --- a/src/output.c +++ b/src/output.c @@ -161,8 +161,9 @@ int savehyd(long *htime) /* Force flow in closed links to be zero then save flows */ for (i=1; i<=Nlinks; i++) { - //if (S[i] <= CLOSED) x[i] = 0.0f; - /*else*/ x[i] = (REAL4)Q[i]; + if (S[i] <= CLOSED) x[i] = 0.0f; + else x[i] = (REAL4)Q[i]; + } fwrite(x+1,sizeof(REAL4),Nlinks,HydFile); diff --git a/src/quality.c b/src/quality.c index 7311818..ef3a7ec 100755 --- a/src/quality.c +++ b/src/quality.c @@ -154,6 +154,7 @@ void initqual() if (Node[i].S != NULL) Node[i].S->Smass = 0.0; QTankVolumes = calloc(Ntanks, sizeof(double)); // keep track of previous step's tank volumes. + QLinkFlow = calloc(Nlinks, sizeof(double)); // keep track of previous step's link flows. /* Set WQ parameters */ Bucf = 1.0; @@ -230,10 +231,18 @@ int runqual(long *t) Htime = hydtime + hydstep; } else { - // stepwise + // stepwise calculation for (int i=1; i<= Ntanks; ++i) { QTankVolumes[i-1] = Tank[i].V; } + + for (int i=1; i<= Nlinks; ++i) + { + if (S[i] <= CLOSED) { + QLinkFlow[i-1] = Q[i]; + } + } + } } return(errcode); @@ -256,9 +265,14 @@ int nextqual(long *tstep) /* Determine time step */ *tstep = 0; - hydstep = Htime - Qtime; - + + // hydstep = Htime - Qtime; + + if (Htime <= Dur) hydstep = Htime - Qtime; + else hydstep = 0; + double *tankVolumes; + // if we're operating in stepwise mode, capture the tank levels so we can restore them later. if (OpenHflag) { tankVolumes = calloc(Ntanks, sizeof(double)); @@ -267,6 +281,7 @@ int nextqual(long *tstep) tankVolumes[i-1] = Tank[i].V; } } + // restore the previous step's tank volumes for (int i=1; i<=Ntanks; i++) { if (Tank[i].A != 0) { // skip reservoirs again @@ -275,9 +290,16 @@ int nextqual(long *tstep) H[n] = tankgrade(i,Tank[i].V); } } + + // restore the previous step's pipe link flows + for (int i=1; i<=Nlinks; i++) { + if (S[i] <= CLOSED) { + Q[i] = 0.0; + } + } + } - /* Perform water quality routing over this time step */ if (Qualflag != NONE && hydstep > 0) transport(hydstep); @@ -298,6 +320,13 @@ int nextqual(long *tstep) H[n] = tankgrade(i,Tank[i].V); } } + + for (int i=1; i<=Nlinks; ++i) { + if (S[i] <= CLOSED) { + Q[i] = QLinkFlow[i-1]; + } + } + free(tankVolumes); } @@ -369,6 +398,7 @@ int closequal() free(R); free(XC); free(QTankVolumes); + free(QLinkFlow); return(errcode); } @@ -467,8 +497,6 @@ void transport(long tstep) { long qtime, dt; - - /* Repeat until elapsed time equals hydraulic time step */ AllocSetPool(SegPool); //(2.00.11 - LR) @@ -485,7 +513,6 @@ void transport(long tstep) } updatesourcenodes(tstep); /* Update quality at source nodes */ - } diff --git a/src/testLemonTiger.cpp b/src/testLemonTiger.cpp old mode 100644 new mode 100755 index 7cba39f..0863e9a --- a/src/testLemonTiger.cpp +++ b/src/testLemonTiger.cpp @@ -1,6 +1,8 @@ #include #include #include +#include +#include #include "testLemonTiger.h" #include "toolkit.h" @@ -135,7 +137,7 @@ int main(int argc, char * argv[]) { // summarize the results - //printResults(&epanetResults, &lemonTigerResults, cout); + printResults(&epanetResults, &lemonTigerResults, cout); compare(&epanetResults, &lemonTigerResults, cout); } catch (int err) { @@ -181,8 +183,10 @@ void printResults(result_t* results1, result_t* results2, std::ostream &out) { for (resultIterator = (*results1).begin(); resultIterator != (*results1).end(); ++resultIterator) { // get the current frame const long time = resultIterator->first; - const networkNodeState_t nodeState1 = resultIterator->second.nodeState; - const networkLinkState_t linkState1 = resultIterator->second.linkState; + const networkNodeState_t networkNodeState1= resultIterator->second.nodeState; + //nodeState1 = resultIterator->second.nodeState; + const networkLinkState_t networkLinkState1 = resultIterator->second.linkState; + //linkState1 = resultIterator->second.linkState; // see if this time is indexed in the second state container if ((*results2).find(time) == (*results2).end()) { @@ -207,7 +211,7 @@ void printResults(result_t* results1, result_t* results2, std::ostream &out) { // loop through the nodes in the networkState objs, and print out the results for this time period networkNodeState_t::const_iterator networkNodeIterator; - for (networkNodeIterator = nodeState1.begin(); networkNodeIterator != nodeState1.end(); ++networkNodeIterator) { + for (networkNodeIterator = networkNodeState1.begin(); networkNodeIterator != networkNodeState1.end(); ++networkNodeIterator) { int nodeIndex = networkNodeIterator->first; // trusting that all nodes are present... const nodeState_t nodeState1 = networkNodeIterator->second; @@ -230,7 +234,7 @@ void printResults(result_t* results1, result_t* results2, std::ostream &out) { } networkLinkState_t::const_iterator networkLinkIterator; - for (networkLinkIterator = linkState1.begin(); networkLinkIterator != linkState1.end(); ++networkLinkIterator) { + for (networkLinkIterator = networkLinkState1.begin(); networkLinkIterator != networkLinkState1.end(); ++networkLinkIterator) { int linkIndex = networkLinkIterator->first; // trusting that all nodes are present... const linkState_t linkState1 = networkLinkIterator->second; diff --git a/src/testLemonTiger.h b/src/testLemonTiger.h old mode 100644 new mode 100755 diff --git a/src/vars.h b/src/vars.h index 3ea8f49..47e638b 100755 --- a/src/vars.h +++ b/src/vars.h @@ -154,6 +154,7 @@ AUTHOR: L. Rossman *XC; /* General Purpose array - WQ */ double *H; /* Node heads */ double *QTankVolumes; + double *QLinkFlow; //woohn 03112013 STmplist *Patlist; /* Temporary time pattern list */ STmplist *Curvelist; /* Temporary list of curves */ Spattern *Pattern; /* Time patterns */ From 18d9f16770a902e88a96811afb2ee821b1593ab5 Mon Sep 17 00:00:00 2001 From: sam hatchett Date: Thu, 23 May 2013 18:57:09 -0400 Subject: [PATCH 24/49] removed mac include (empty file) --- build/Xcode/epanet/macinclude/malloc.h | 10 ---------- 1 file changed, 10 deletions(-) delete mode 100644 build/Xcode/epanet/macinclude/malloc.h diff --git a/build/Xcode/epanet/macinclude/malloc.h b/build/Xcode/epanet/macinclude/malloc.h deleted file mode 100644 index 1a882e9..0000000 --- a/build/Xcode/epanet/macinclude/malloc.h +++ /dev/null @@ -1,10 +0,0 @@ -/* - * malloc.h - * epanet - * - * Created by Sam Hatchett on 9/21/09. - * Copyright 2009 __MyCompanyName__. All rights reserved. - * - */ - -#include \ No newline at end of file From 434d78c6ed8b5e4a95380e634798406188ef48e9 Mon Sep 17 00:00:00 2001 From: sam hatchett Date: Thu, 23 May 2013 19:36:03 -0400 Subject: [PATCH 25/49] Lemon Tiger changes --- src/epanet.c | 8 ++-- src/hydraul.c | 11 ++++- src/quality.c | 129 +++++++++++++++++++++++++++++++++++++++++--------- src/text.h | 5 ++ src/toolkit.h | 4 ++ src/types.h | 4 ++ src/vars.h | 14 +++++- 7 files changed, 146 insertions(+), 29 deletions(-) diff --git a/src/epanet.c b/src/epanet.c index 69095a4..3512b04 100755 --- a/src/epanet.c +++ b/src/epanet.c @@ -754,7 +754,8 @@ int DLLEXPORT ENopenQ() OpenQflag = FALSE; SaveQflag = FALSE; if (!Openflag) return(102); - if (!SaveHflag) return(104); + // !LT! todo - check for SaveHflag / set sequential/step mode + //if (!SaveHflag) return(104); /* Open WQ solver */ ERRCODE(openqual()); @@ -1680,7 +1681,6 @@ int DLLEXPORT ENgetlinkvalue(int index, int code, float *value) /*** Updated 10/25/00 ***/ if (S[index] <= CLOSED) v = 0.0; - else v = Q[index]*Ucf[FLOW]; break; @@ -3143,6 +3143,8 @@ char *geterrmsg(int errcode) case 307: strcpy(Msg,ERR307); break; case 308: strcpy(Msg,ERR308); break; case 309: strcpy(Msg,ERR309); break; + + case 401: strcpy(Msg,ERR401); break; default: strcpy(Msg,""); } return(Msg); @@ -3222,7 +3224,7 @@ int DLLEXPORT ENgetbasedemand(int nodeIndex, int demandIdx, float *baseDemand) if (nodeIndex <= 0 || nodeIndex > Nnodes) return(203); for(d=Node[nodeIndex].D; nnext) n++; if(n!=demandIdx) return(253); - *baseDemand=d->Base*Ucf[FLOW]; + *baseDemand=(float)(d->Base*Ucf[FLOW]); return 0; } int DLLEXPORT ENgetdemandpattern(int nodeIndex, int demandIdx, int *pattIdx) diff --git a/src/hydraul.c b/src/hydraul.c index a56e14a..eb97ba7 100755 --- a/src/hydraul.c +++ b/src/hydraul.c @@ -259,6 +259,9 @@ int nexthyd(long *tstep) else { Htime++; /* Force completion of analysis */ + if (OpenQflag) { + Qtime++; // force completion of wq analysis too + } } *tstep = hydstep; return(errcode); @@ -1055,8 +1058,12 @@ void tanklevels(long tstep) /*** Updated 6/24/02 ***/ /* Check if tank full/empty within next second */ - if (Tank[i].V + D[n] >= Tank[i].Vmax) Tank[i].V = Tank[i].Vmax; - if (Tank[i].V - D[n] <= Tank[i].Vmin) Tank[i].V = Tank[i].Vmin; + if (Tank[i].V + D[n] >= Tank[i].Vmax) { + Tank[i].V = Tank[i].Vmax; + } + else if (Tank[i].V - D[n] <= Tank[i].Vmin) { + Tank[i].V = Tank[i].Vmin; + } H[n] = tankgrade(i,Tank[i].V); } diff --git a/src/quality.c b/src/quality.c index 8cc1ffe..abf89fc 100755 --- a/src/quality.c +++ b/src/quality.c @@ -106,7 +106,7 @@ int openqual() if (SegPool == NULL) errcode = 101; //(2.00.11 - LR) /* Allocate scratch array & reaction rate array*/ - X = (double *) calloc(MAX((Nnodes+1),(Nlinks+1)),sizeof(double)); + XC = (double *) calloc(MAX((Nnodes+1),(Nlinks+1)),sizeof(double)); R = (double *) calloc((Nlinks+1), sizeof(double)); ERRCODE(MEMCHECK(X)); ERRCODE(MEMCHECK(R)); @@ -154,6 +154,9 @@ void initqual() for (i=1; i<=Nnodes; i++) if (Node[i].S != NULL) Node[i].S->Smass = 0.0; + QTankVolumes = calloc(Ntanks, sizeof(double)); // keep track of previous step's tank volumes. + QLinkFlow = calloc(Nlinks, sizeof(double)); // keep track of previous step's link flows. + /* Set WQ parameters */ Bucf = 1.0; Tucf = 1.0; @@ -189,7 +192,10 @@ void initqual() Wsource = 0.0; /* Re-position hydraulics file */ + if (!OpenHflag) { fseek(HydFile,HydOffset,SEEK_SET); + } + /* Set elapsed times to zero */ Htime = 0; @@ -221,7 +227,24 @@ int runqual(long *t) if (Qtime == Htime) { errcode = gethyd(&hydtime, &hydstep); + if (!OpenHflag) { // test for sequential vs stepwise + // sequential Htime = hydtime + hydstep; + } + else { + // stepwise calculation + for (int i=1; i<= Ntanks; ++i) { + QTankVolumes[i-1] = Tank[i].V; + } + + for (int i=1; i<= Nlinks; ++i) + { + if (S[i] <= CLOSED) { + QLinkFlow[i-1] = Q[i]; + } + } + + } } return(errcode); } @@ -243,7 +266,40 @@ int nextqual(long *tstep) /* Determine time step */ *tstep = 0; - hydstep = Htime - Qtime; + + // hydstep = Htime - Qtime; + + if (Htime <= Dur) hydstep = Htime - Qtime; + else hydstep = 0; + + double *tankVolumes; + + // if we're operating in stepwise mode, capture the tank levels so we can restore them later. + if (OpenHflag) { + tankVolumes = calloc(Ntanks, sizeof(double)); + for (int i=1; i<=Ntanks; ++i) { + if (Tank[i].A != 0) { // skip reservoirs + tankVolumes[i-1] = Tank[i].V; + } + } + + // restore the previous step's tank volumes + for (int i=1; i<=Ntanks; i++) { + if (Tank[i].A != 0) { // skip reservoirs again + int n = Tank[i].Node; + Tank[i].V = QTankVolumes[i-1]; + H[n] = tankgrade(i,Tank[i].V); + } + } + + // restore the previous step's pipe link flows + for (int i=1; i<=Nlinks; i++) { + if (S[i] <= CLOSED) { + Q[i] = 0.0; + } + } + + } /* Perform water quality routing over this time step */ if (Qualflag != NONE && hydstep > 0) transport(hydstep); @@ -255,6 +311,26 @@ int nextqual(long *tstep) /* Save final output if no more time steps */ if (!errcode && Saveflag && *tstep == 0) errcode = savefinaloutput(); + + // restore tank levels to post-runH state, if needed. + if (OpenHflag) { + for (int i=1; i<=Ntanks; i++) { + if (Tank[i].A != 0) { // skip reservoirs again + int n = Tank[i].Node; + Tank[i].V = tankVolumes[i-1]; + H[n] = tankgrade(i,Tank[i].V); + } + } + + for (int i=1; i<=Nlinks; ++i) { + if (S[i] <= CLOSED) { + Q[i] = QLinkFlow[i-1]; + } + } + + free(tankVolumes); + } + return(errcode); } @@ -321,7 +397,9 @@ int closequal() free(VolIn); free(MassIn); free(R); - free(X); + free(XC); + free(QTankVolumes); + free(QLinkFlow); return(errcode); } @@ -344,10 +422,14 @@ int gethyd(long *hydtime, long *hydstep) { int errcode = 0; + // if hydraulics are not open, then we're operating in sequential mode. + // else hydraulics are open, so use the hydraulic results in memory rather than reading from the temp file. + if (!OpenHflag) { /* Read hydraulic results from file */ if (!readhyd(hydtime)) return(307); if (!readhydstep(hydstep)) return(307); Htime = *hydtime; + } /* Save current results to output file */ if (Htime >= Rtime) @@ -666,7 +748,7 @@ void accumulate(long dt) /* Re-set memory used to accumulate mass & volume */ memset(VolIn,0,(Nnodes+1)*sizeof(double)); memset(MassIn,0,(Nnodes+1)*sizeof(double)); - memset(X,0,(Nnodes+1)*sizeof(double)); + memset(XC,0,(Nnodes+1)*sizeof(double)); /* Compute average conc. of segments adjacent to each node */ /* (For use if there is no transport through the node) */ @@ -686,7 +768,7 @@ void accumulate(long dt) } } for (k=1; k<=Nnodes; k++) - if (VolIn[k] > 0.0) X[k] = MassIn[k]/VolIn[k]; + if (VolIn[k] > 0.0) XC[k] = MassIn[k]/VolIn[k]; /* Move mass from first segment of each pipe into downstream node */ memset(VolIn,0,(Nnodes+1)*sizeof(double)); @@ -767,7 +849,7 @@ void updatenodes(long dt) ** Purpose: updates concentration at all nodes to mixture of accumulated ** inflow from connecting pipes. ** -** Note: Does not account for source flow effects. X[i] contains +** Note: Does not account for source flow effects. XC[i] contains ** average concen. of segments adjacent to node i, used in case ** there was no inflow into i. **--------------------------------------------------------------------------- @@ -780,7 +862,7 @@ void updatenodes(long dt) { if (D[i] < 0.0) VolIn[i] -= D[i]*dt; if (VolIn[i] > 0.0) C[i] = MassIn[i]/VolIn[i]; - else C[i] = X[i]; + else C[i] = XC[i]; } /* Update tank quality */ @@ -809,8 +891,8 @@ void sourceinput(long dt) /* Establish a flow cutoff which indicates no outflow from a node */ qcutoff = 10.0*TINY; - /* Zero-out the work array X */ - memset(X,0,(Nnodes+1)*sizeof(double)); + /* Zero-out the work array XC */ + memset(XC,0,(Nnodes+1)*sizeof(double)); if (Qualflag != CHEM) return; /* Consider each node */ @@ -872,7 +954,7 @@ void sourceinput(long dt) } /* Source concen. contribution = (mass added / outflow volume) */ - X[n] = massadded/volout; + XC[n] = massadded/volout; /* Update total mass added for time period & simulation */ source->Smass += massadded; @@ -923,7 +1005,7 @@ void release(long dt) v = q*dt; /* Include source contribution in quality released from node. */ - c = C[n] + X[n]; + c = C[n] + XC[n]; /* If link has a last seg, check if its quality */ /* differs from that of the flow released from node.*/ @@ -952,7 +1034,7 @@ void updatesourcenodes(long dt) ** Input: dt = current WQ time step ** Output: none ** Purpose: updates quality at source nodes. -** (X[n] = concen. added by source at node n) +** (XC[n] = concen. added by source at node n) **--------------------------------------------------- */ { @@ -968,7 +1050,7 @@ void updatesourcenodes(long dt) if (source == NULL) continue; /* Add source to current node concen. */ - C[n] += X[n]; + C[n] += XC[n]; /* For tanks, node concen. = internal concen. */ if (n > Njuncs) @@ -997,21 +1079,24 @@ void updatetanks(long dt) /* Examine each reservoir & tank */ for (i=1; i<=Ntanks; i++) { + n = Tank[i].Node; /* Use initial quality for reservoirs */ if (Tank[i].A == 0.0) { - n = Tank[i].Node; C[n] = Node[n].C0; } /* Update tank WQ based on mixing model */ - else switch(Tank[i].MixModel) - { - case MIX2: tankmix2(i,dt); break; - case FIFO: tankmix3(i,dt); break; - case LIFO: tankmix4(i,dt); break; - default: tankmix1(i,dt); break; + else { + switch(Tank[i].MixModel) + { + case MIX2: tankmix2(i,dt); break; + case FIFO: tankmix3(i,dt); break; + case LIFO: tankmix4(i,dt); break; + default: tankmix1(i,dt); break; + } + } } } @@ -1443,7 +1528,7 @@ void ratecoeffs() { kw = Link[k].Kw; if (kw != 0.0) kw = piperate(k); - Link[k].R = kw; + Link[k].Rc = kw; R[k] = 0.0; } } /* End of ratecoeffs */ @@ -1526,7 +1611,7 @@ double pipereact(int k, double c, double v, long dt) /* Otherwise find bulk & wall reaction rates */ rbulk = bulkrate(c,Link[k].Kb,BulkOrder)*Bucf; - rwall = wallrate(c,Link[k].Diam,Link[k].Kw,Link[k].R); + rwall = wallrate(c,Link[k].Diam,Link[k].Kw,Link[k].Rc); /* Find change in concentration over timestep */ dcbulk = rbulk*(double)dt; diff --git a/src/text.h b/src/text.h index 0a0e5c0..890e099 100755 --- a/src/text.h +++ b/src/text.h @@ -14,6 +14,8 @@ AUTHOR: L. Rossman **************************************************** */ /* ------------ Keyword Dictionary ---------- */ +#ifndef TEXT_H +#define TEXT_H #define w_USE "USE" #define w_SAVE "SAVE" @@ -501,6 +503,8 @@ AUTHOR: L. Rossman #define ERR308 "File Error 308: cannot save results to file." #define ERR309 "File Error 309: cannot save results to report file." +#define ERR401 "Sync Error 401: Qstep is not dividable by Hstep. Can't sync." + #define R_ERR201 "Input Error 201: syntax error in following line of " #define R_ERR202 "Input Error 202: illegal numeric value in following line of " #define R_ERR203 "Input Error 203: undefined node in following line of " @@ -528,3 +532,4 @@ AUTHOR: L. Rossman #define WARN5 "WARNING: Valves cannot deliver enough flow." #define WARN6 "WARNING: System has negative pressures." +#endif \ No newline at end of file diff --git a/src/toolkit.h b/src/toolkit.h index 016a31f..eb54528 100755 --- a/src/toolkit.h +++ b/src/toolkit.h @@ -15,6 +15,8 @@ AUTHOR: L. Rossman ******************************************************************* */ +#ifndef TOOLKIT_H +#define TOOLKIT_H #ifndef DLLEXPORT #ifdef DLL @@ -247,3 +249,5 @@ extern "C" { #if defined(__cplusplus) } #endif + +#endif //TOOLKIT_H \ No newline at end of file diff --git a/src/types.h b/src/types.h index 68a495e..bc135aa 100755 --- a/src/types.h +++ b/src/types.h @@ -17,6 +17,8 @@ AUTHOR: L. Rossman ********************************************************************** */ +#ifndef TYPES_H +#define TYPES_H /*********************************************************/ /* All floats have been re-declared as doubles (7/3/07). */ @@ -206,6 +208,7 @@ typedef struct /* LINK OBJECT */ double Kb; /* Bulk react. coeff */ double Kw; /* Wall react. coeff */ double R; /* Flow resistance */ + double Rc; /* Reaction cal */ char Type; /* Link type */ char Stat; /* Initial status */ char Rpt; /* Reporting flag */ @@ -451,3 +454,4 @@ enum HdrType /* Type of table heading */ NODEHDR, /* Node Results */ LINKHDR}; /* Link Results */ +#endif \ No newline at end of file diff --git a/src/vars.h b/src/vars.h index b8b821b..ef15924 100755 --- a/src/vars.h +++ b/src/vars.h @@ -11,7 +11,13 @@ AUTHOR: L. Rossman ************************************************************************ */ -EXTERN FILE *InFile, /* Input file pointer */ +#ifndef VARS_H +#define VARS_H + +#include +#include "hash.h" + + FILE *InFile, /* Input file pointer */ *OutFile, /* Output file pointer */ *RptFile, /* Report file pointer */ *HydFile, /* Hydraulics file pointer */ @@ -144,8 +150,10 @@ EXTERN double *D, /* Node actual demand */ *K, /* Link settings */ *Q, /* Link flows */ *R, /* Pipe reaction rate */ - *X; /* General purpose array */ + *XC; /* General purpose array */ EXTERN double *H; /* Node heads */ +EXTERN double *QTankVolumes; +EXTERN double *QLinkFlow; EXTERN STmplist *Patlist; /* Temporary time pattern list */ EXTERN STmplist *Curvelist; /* Temporary list of curves */ EXTERN Spattern *Pattern; /* Time patterns */ @@ -195,3 +203,5 @@ EXTERN int *Order, /* Node-to-row of A */ EXTERN int *XLNZ, /* Start position of each column in NZSUB */ *NZSUB, /* Row index of each coeff. in each column */ *LNZ; /* Position of each coeff. in Aij array */ + +#endif \ No newline at end of file From 2bc8d36a55adce0f4338e17dd87b3bbb7be9c753 Mon Sep 17 00:00:00 2001 From: sam hatchett Date: Thu, 23 May 2013 19:40:56 -0400 Subject: [PATCH 26/49] vars and project settings -- incorporating lemon tiger changes --- .../epanet/epanet.xcodeproj/project.pbxproj | 22 +++++++++++++------ src/hash.h | 4 ++++ src/vars.h | 1 + 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/build/Xcode/epanet/epanet.xcodeproj/project.pbxproj b/build/Xcode/epanet/epanet.xcodeproj/project.pbxproj index bb0c2b8..b5b34ba 100644 --- a/build/Xcode/epanet/epanet.xcodeproj/project.pbxproj +++ b/build/Xcode/epanet/epanet.xcodeproj/project.pbxproj @@ -219,6 +219,9 @@ /* Begin PBXProject section */ 08FB7793FE84155DC02AAC07 /* Project object */ = { isa = PBXProject; + attributes = { + LastUpgradeCheck = 0460; + }; buildConfigurationList = 1DEB914E08733D8E0010E9CD /* Build configuration list for PBXProject "epanet" */; compatibilityVersion = "Xcode 3.2"; developmentRegion = English; @@ -295,10 +298,10 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + COMBINE_HIDPI_IMAGES = YES; COPY_PHASE_STRIP = NO; EXECUTABLE_PREFIX = lib; GCC_DYNAMIC_NO_PIC = NO; - GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_MODEL_TUNING = G5; GCC_OPTIMIZATION_LEVEL = 0; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; @@ -312,6 +315,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + COMBINE_HIDPI_IMAGES = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; EXECUTABLE_PREFIX = lib; GCC_MODEL_TUNING = G5; @@ -326,14 +330,18 @@ isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_OPTIMIZATION_LEVEL = 0; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; GCC_WARN_UNUSED_VARIABLE = YES; HEADER_SEARCH_PATHS = macinclude; ONLY_ACTIVE_ARCH = YES; - PREBINDING = NO; SDKROOT = ""; }; name = Debug; @@ -342,12 +350,16 @@ isa = XCBuildConfiguration; buildSettings = { ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; GCC_WARN_UNUSED_VARIABLE = YES; HEADER_SEARCH_PATHS = macinclude; - PREBINDING = NO; SDKROOT = ""; }; name = Release; @@ -358,14 +370,12 @@ ALWAYS_SEARCH_USER_PATHS = NO; COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; - GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_MODEL_TUNING = G5; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = CLE; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; INFOPLIST_PREPROCESSOR_DEFINITIONS = ""; INSTALL_PATH = /usr/local/bin; - PREBINDING = NO; PRODUCT_NAME = runepanet; }; name = Debug; @@ -376,13 +386,11 @@ ALWAYS_SEARCH_USER_PATHS = NO; COPY_PHASE_STRIP = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_MODEL_TUNING = G5; GCC_PREPROCESSOR_DEFINITIONS = CLE; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; INFOPLIST_PREPROCESSOR_DEFINITIONS = ""; INSTALL_PATH = /usr/local/bin; - PREBINDING = NO; PRODUCT_NAME = runepanet; ZERO_LINK = NO; }; diff --git a/src/hash.h b/src/hash.h index 8195afd..38999d1 100755 --- a/src/hash.h +++ b/src/hash.h @@ -4,6 +4,9 @@ ** */ +#ifndef HASH_H +#define HASH_H + #define HTMAXSIZE 1999 #define NOTFOUND 0 @@ -22,3 +25,4 @@ int HTfind(HTtable *, char *); char *HTfindKey(HTtable *, char *); void HTfree(HTtable *); +#endif \ No newline at end of file diff --git a/src/vars.h b/src/vars.h index ef15924..6ca5be4 100755 --- a/src/vars.h +++ b/src/vars.h @@ -150,6 +150,7 @@ EXTERN double *D, /* Node actual demand */ *K, /* Link settings */ *Q, /* Link flows */ *R, /* Pipe reaction rate */ + *X, /* General purpose array */ *XC; /* General purpose array */ EXTERN double *H; /* Node heads */ EXTERN double *QTankVolumes; From 4c1155745b1daf7e028eb75b7af05557fccb20f8 Mon Sep 17 00:00:00 2001 From: sam hatchett Date: Thu, 23 May 2013 19:53:26 -0400 Subject: [PATCH 27/49] setting float type by define --- .../epanet/epanet.xcodeproj/project.pbxproj | 4 -- src/epanet.c | 58 +++++++++---------- src/toolkit.h | 32 +++++----- 3 files changed, 47 insertions(+), 47 deletions(-) diff --git a/build/Xcode/epanet/epanet.xcodeproj/project.pbxproj b/build/Xcode/epanet/epanet.xcodeproj/project.pbxproj index b5b34ba..b3d2027 100644 --- a/build/Xcode/epanet/epanet.xcodeproj/project.pbxproj +++ b/build/Xcode/epanet/epanet.xcodeproj/project.pbxproj @@ -42,7 +42,6 @@ 22322FA51068369500641384 /* rules.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F7F1068369500641384 /* rules.c */; }; 22322FA61068369500641384 /* smatrix.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F801068369500641384 /* smatrix.c */; }; 22322FAA106836BC00641384 /* epanet2.h in Headers */ = {isa = PBXBuildFile; fileRef = 22322FA9106836B000641384 /* epanet2.h */; }; - 22322FAE106836D900641384 /* malloc.h in Headers */ = {isa = PBXBuildFile; fileRef = 22322FAD106836D900641384 /* malloc.h */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -79,7 +78,6 @@ 22322F831068369500641384 /* types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = types.h; path = ../../../src/types.h; sourceTree = SOURCE_ROOT; }; 22322F841068369500641384 /* vars.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = vars.h; path = ../../../src/vars.h; sourceTree = SOURCE_ROOT; }; 22322FA9106836B000641384 /* epanet2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = epanet2.h; path = ../../../include/epanet2.h; sourceTree = SOURCE_ROOT; }; - 22322FAD106836D900641384 /* malloc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = malloc.h; path = macinclude/malloc.h; sourceTree = ""; }; D2AAC0630554660B00DB518D /* libepanet.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libepanet.dylib; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ @@ -151,7 +149,6 @@ 22322FA8106836A000641384 /* Include */ = { isa = PBXGroup; children = ( - 22322FAD106836D900641384 /* malloc.h */, 22322FA9106836B000641384 /* epanet2.h */, ); name = Include; @@ -173,7 +170,6 @@ 22322F971068369500641384 /* toolkit.h in Headers */, 22322F981068369500641384 /* types.h in Headers */, 22322F991068369500641384 /* vars.h in Headers */, - 22322FAE106836D900641384 /* malloc.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/src/epanet.c b/src/epanet.c index 3512b04..f193147 100755 --- a/src/epanet.c +++ b/src/epanet.c @@ -975,7 +975,7 @@ int DLLEXPORT ENgetversion(int *v) int DLLEXPORT ENgetcontrol(int cindex, int *ctype, int *lindex, - float *setting, int *nindex, float *level) + EN_API_FLOAT_TYPE *setting, int *nindex, EN_API_FLOAT_TYPE *level) /*---------------------------------------------------------------- ** Input: cindex = control index (position of control statement ** in the input file, starting from 1) @@ -1021,9 +1021,9 @@ int DLLEXPORT ENgetcontrol(int cindex, int *ctype, int *lindex, else if (*nindex > 0) lvl = (Control[cindex].Grade - Node[*nindex].El)*Ucf[PRESSURE]; else - lvl = (float)Control[cindex].Time; - *setting = (float)s; - *level = (float)lvl; + lvl = (EN_API_FLOAT_TYPE)Control[cindex].Time; + *setting = (EN_API_FLOAT_TYPE)s; + *level = (EN_API_FLOAT_TYPE)lvl; return(0); } @@ -1054,7 +1054,7 @@ int DLLEXPORT ENgetcount(int code, int *count) } -int DLLEXPORT ENgetoption(int code, float *value) +int DLLEXPORT ENgetoption(int code, EN_API_FLOAT_TYPE *value) /*---------------------------------------------------------------- ** Input: code = option code (see TOOLKIT.H) ** Output: *value = option value @@ -1064,7 +1064,7 @@ int DLLEXPORT ENgetoption(int code, float *value) */ { double v = 0.0; - *value = 0.0f; + *value = 0.0; if (!Openflag) return(102); switch (code) { @@ -1080,7 +1080,7 @@ int DLLEXPORT ENgetoption(int code, float *value) break; default: return(251); } - *value = (float)v; + *value = (EN_API_FLOAT_TYPE)v; return(0); } @@ -1196,7 +1196,7 @@ int DLLEXPORT ENgetpatternlen(int index, int *len) } -int DLLEXPORT ENgetpatternvalue(int index, int period, float *value) +int DLLEXPORT ENgetpatternvalue(int index, int period, EN_API_FLOAT_TYPE *value) /*---------------------------------------------------------------- ** Input: index = index of time pattern ** period = pattern time period @@ -1206,11 +1206,11 @@ int DLLEXPORT ENgetpatternvalue(int index, int period, float *value) ** and pattern **---------------------------------------------------------------- */ -{ *value = 0.0f; +{ *value = 0.0; if (!Openflag) return(102); if (index < 1 || index > Npats) return(205); if (period < 1 || period > Pattern[index].Length) return(251); - *value = (float)Pattern[index].F[period-1]; + *value = (EN_API_FLOAT_TYPE)Pattern[index].F[period-1]; return(0); } @@ -1345,7 +1345,7 @@ int DLLEXPORT ENgetnodetype(int index, int *code) } -int DLLEXPORT ENgetnodevalue(int index, int code, float *value) +int DLLEXPORT ENgetnodevalue(int index, int code, EN_API_FLOAT_TYPE *value) /*---------------------------------------------------------------- ** Input: index = node index ** code = node parameter code (see TOOLKIT.H) @@ -1360,7 +1360,7 @@ int DLLEXPORT ENgetnodevalue(int index, int code, float *value) Psource source; /* Check for valid arguments */ - *value = 0.0f; + *value = 0.0; if (!Openflag) return(102); if (index <= 0 || index > Nnodes) return(203); @@ -1518,7 +1518,7 @@ int DLLEXPORT ENgetnodevalue(int index, int code, float *value) default: return(251); } - *value = (float)v; + *value = (EN_API_FLOAT_TYPE)v; return(0); } @@ -1603,7 +1603,7 @@ int DLLEXPORT ENgetlinknodes(int index, int *node1, int *node2) } -int DLLEXPORT ENgetlinkvalue(int index, int code, float *value) +int DLLEXPORT ENgetlinkvalue(int index, int code, EN_API_FLOAT_TYPE *value) /*------------------------------------------------------------------ ** Input: index = link index ** code = link parameter code (see TOOLKIT.H) @@ -1616,7 +1616,7 @@ int DLLEXPORT ENgetlinkvalue(int index, int code, float *value) double a,h,q, v = 0.0; /* Check for valid arguments */ - *value = 0.0f; + *value = 0.0; if (!Openflag) return(102); if (index <= 0 || index > Nlinks) return(204); @@ -1740,12 +1740,12 @@ int DLLEXPORT ENgetlinkvalue(int index, int code, float *value) default: return(251); } - *value = (float)v; + *value = (EN_API_FLOAT_TYPE)v; return(0); } -int DLLEXPORT ENgetcurve(int curveIndex, int *nValues, float **xValues, float **yValues) // !sph +int DLLEXPORT ENgetcurve(int curveIndex, int *nValues, EN_API_FLOAT_TYPE **xValues, EN_API_FLOAT_TYPE **yValues) // !sph /*---------------------------------------------------------------- ** Input: curveIndex = curve index ** Output: *nValues = number of points on curve @@ -1761,14 +1761,14 @@ int DLLEXPORT ENgetcurve(int curveIndex, int *nValues, float **xValues, float * Scurve curve = Curve[curveIndex]; int nPoints = curve.Npts; - float *pointX = calloc(nPoints, sizeof(float)); - float *pointY = calloc(nPoints, sizeof(float)); + EN_API_FLOAT_TYPE *pointX = calloc(nPoints, sizeof(EN_API_FLOAT_TYPE)); + EN_API_FLOAT_TYPE *pointY = calloc(nPoints, sizeof(EN_API_FLOAT_TYPE)); for (int iPoint = 0; iPoint < nPoints; iPoint++) { double x = curve.X[iPoint] * Ucf[LENGTH]; double y = curve.Y[iPoint] * Ucf[VOLUME]; - pointX[iPoint] = (float)x; - pointY[iPoint] = (float)y; + pointX[iPoint] = (EN_API_FLOAT_TYPE)x; + pointY[iPoint] = (EN_API_FLOAT_TYPE)y; } *nValues = nPoints; @@ -1786,7 +1786,7 @@ int DLLEXPORT ENgetcurve(int curveIndex, int *nValues, float **xValues, float * int DLLEXPORT ENsetcontrol(int cindex, int ctype, int lindex, - float setting, int nindex, float level) + EN_API_FLOAT_TYPE setting, int nindex, EN_API_FLOAT_TYPE level) /*---------------------------------------------------------------- ** Input: cindex = control index (position of control statement ** in the input file, starting from 1) @@ -1874,7 +1874,7 @@ int DLLEXPORT ENsetcontrol(int cindex, int ctype, int lindex, } -int DLLEXPORT ENsetnodevalue(int index, int code, float v) +int DLLEXPORT ENsetnodevalue(int index, int code, EN_API_FLOAT_TYPE v) /*---------------------------------------------------------------- ** Input: index = node index ** code = node parameter code (see TOOLKIT.H) @@ -2083,7 +2083,7 @@ int DLLEXPORT ENsetnodevalue(int index, int code, float v) } -int DLLEXPORT ENsetlinkvalue(int index, int code, float v) +int DLLEXPORT ENsetlinkvalue(int index, int code, EN_API_FLOAT_TYPE v) /*---------------------------------------------------------------- ** Input: index = link index ** code = link parameter code (see TOOLKIT.H) @@ -2270,7 +2270,7 @@ int DLLEXPORT ENaddpattern(char *id) } -int DLLEXPORT ENsetpattern(int index, float *f, int n) +int DLLEXPORT ENsetpattern(int index, EN_API_FLOAT_TYPE *f, int n) /*---------------------------------------------------------------- ** Input: index = time pattern index ** *f = array of pattern multipliers @@ -2299,7 +2299,7 @@ int DLLEXPORT ENsetpattern(int index, float *f, int n) } -int DLLEXPORT ENsetpatternvalue(int index, int period, float value) +int DLLEXPORT ENsetpatternvalue(int index, int period, EN_API_FLOAT_TYPE value) /*---------------------------------------------------------------- ** Input: index = time pattern index ** period = time pattern period @@ -2379,7 +2379,7 @@ int DLLEXPORT ENsettimeparam(int code, long value) } -int DLLEXPORT ENsetoption(int code, float v) +int DLLEXPORT ENsetoption(int code, EN_API_FLOAT_TYPE v) /*---------------------------------------------------------------- ** Input: code = option code (see TOOLKIT.H) ** v = option value @@ -3215,7 +3215,7 @@ int DLLEXPORT ENgetnumdemands(int nodeIndex, int *numDemands) *numDemands=n; return 0; } -int DLLEXPORT ENgetbasedemand(int nodeIndex, int demandIdx, float *baseDemand) +int DLLEXPORT ENgetbasedemand(int nodeIndex, int demandIdx, EN_API_FLOAT_TYPE *baseDemand) { Pdemand d; int n=0; @@ -3224,7 +3224,7 @@ int DLLEXPORT ENgetbasedemand(int nodeIndex, int demandIdx, float *baseDemand) if (nodeIndex <= 0 || nodeIndex > Nnodes) return(203); for(d=Node[nodeIndex].D; nnext) n++; if(n!=demandIdx) return(253); - *baseDemand=(float)(d->Base*Ucf[FLOW]); + *baseDemand=(EN_API_FLOAT_TYPE)(d->Base*Ucf[FLOW]); return 0; } int DLLEXPORT ENgetdemandpattern(int nodeIndex, int demandIdx, int *pattIdx) diff --git a/src/toolkit.h b/src/toolkit.h index eb54528..814fc39 100755 --- a/src/toolkit.h +++ b/src/toolkit.h @@ -18,6 +18,10 @@ AUTHOR: L. Rossman #ifndef TOOLKIT_H #define TOOLKIT_H +#ifndef EN_API_FLOAT_TYPE + #define EN_API_FLOAT_TYPE float +#endif + #ifndef DLLEXPORT #ifdef DLL #ifdef __cplusplus @@ -202,16 +206,16 @@ extern "C" { int DLLEXPORT ENresetreport(void); int DLLEXPORT ENsetreport(char *); - int DLLEXPORT ENgetcontrol(int, int *, int *, float *, - int *, float *); + int DLLEXPORT ENgetcontrol(int, int *, int *, EN_API_FLOAT_TYPE *, + int *, EN_API_FLOAT_TYPE *); int DLLEXPORT ENgetcount(int, int *); - int DLLEXPORT ENgetoption(int, float *); + int DLLEXPORT ENgetoption(int, EN_API_FLOAT_TYPE *); int DLLEXPORT ENgettimeparam(int, long *); int DLLEXPORT ENgetflowunits(int *); int DLLEXPORT ENgetpatternindex(char *, int *); int DLLEXPORT ENgetpatternid(int, char *); int DLLEXPORT ENgetpatternlen(int, int *); - int DLLEXPORT ENgetpatternvalue(int, int, float *); + int DLLEXPORT ENgetpatternvalue(int, int, EN_API_FLOAT_TYPE *); int DLLEXPORT ENgetqualtype(int *, int *); int DLLEXPORT ENgeterror(int, char *, int); int DLLEXPORT ENgetstatistic(int code, int* value); @@ -219,30 +223,30 @@ extern "C" { int DLLEXPORT ENgetnodeindex(char *, int *); int DLLEXPORT ENgetnodeid(int, char *); int DLLEXPORT ENgetnodetype(int, int *); - int DLLEXPORT ENgetnodevalue(int, int, float *); + int DLLEXPORT ENgetnodevalue(int, int, EN_API_FLOAT_TYPE *); int DLLEXPORT ENgetnumdemands(int, int *); - int DLLEXPORT ENgetbasedemand(int, int, float *); + int DLLEXPORT ENgetbasedemand(int, int, EN_API_FLOAT_TYPE *); int DLLEXPORT ENgetdemandpattern(int, int, int *); int DLLEXPORT ENgetlinkindex(char *, int *); int DLLEXPORT ENgetlinkid(int, char *); int DLLEXPORT ENgetlinktype(int, int *); int DLLEXPORT ENgetlinknodes(int, int *, int *); - int DLLEXPORT ENgetlinkvalue(int, int, float *); + int DLLEXPORT ENgetlinkvalue(int, int, EN_API_FLOAT_TYPE *); - int DLLEXPORT ENgetcurve(int curveIndex, int *nValues, float **xValues, float **yValues); + int DLLEXPORT ENgetcurve(int curveIndex, int *nValues, EN_API_FLOAT_TYPE **xValues, EN_API_FLOAT_TYPE **yValues); int DLLEXPORT ENgetversion(int *); - int DLLEXPORT ENsetcontrol(int, int, int, float, int, float); - int DLLEXPORT ENsetnodevalue(int, int, float); - int DLLEXPORT ENsetlinkvalue(int, int, float); + int DLLEXPORT ENsetcontrol(int, int, int, EN_API_FLOAT_TYPE, int, EN_API_FLOAT_TYPE); + int DLLEXPORT ENsetnodevalue(int, int, EN_API_FLOAT_TYPE); + int DLLEXPORT ENsetlinkvalue(int, int, EN_API_FLOAT_TYPE); int DLLEXPORT ENaddpattern(char *); - int DLLEXPORT ENsetpattern(int, float *, int); - int DLLEXPORT ENsetpatternvalue(int, int, float); + int DLLEXPORT ENsetpattern(int, EN_API_FLOAT_TYPE *, int); + int DLLEXPORT ENsetpatternvalue(int, int, EN_API_FLOAT_TYPE); int DLLEXPORT ENsettimeparam(int, long); - int DLLEXPORT ENsetoption(int, float); + int DLLEXPORT ENsetoption(int, EN_API_FLOAT_TYPE); int DLLEXPORT ENsetstatusreport(int); int DLLEXPORT ENsetqualtype(int, char *, char *, char *); From 9da5f4f658164abf0a562476287452db904fa4ae Mon Sep 17 00:00:00 2001 From: Sam Hatchett Date: Fri, 24 May 2013 15:54:02 -0400 Subject: [PATCH 28/49] rtx mods, epanet gets coords --- src/epanet.c | 44 +++++++++++++++-- src/funcs.h | 3 ++ src/input2.c | 133 ++++++++++++++++++++++++++++++++++++++++++++------ src/input3.c | 55 +++++++++++++++++++++ src/toolkit.h | 1 + src/types.h | 7 +++ src/vars.h | 4 ++ 7 files changed, 228 insertions(+), 19 deletions(-) diff --git a/src/epanet.c b/src/epanet.c index f193147..5b7edb1 100755 --- a/src/epanet.c +++ b/src/epanet.c @@ -318,6 +318,7 @@ int DLLEXPORT ENopen(char *f1, char *f2, char *f3) /* Free temporary linked lists used for Patterns & Curves */ freeTmplist(Patlist); freeTmplist(Curvelist); + freeTmplist(Coordlist); /* If using previously saved hydraulics then open its file */ if (Hydflag == USE) ERRCODE(openhydfile()); @@ -1345,6 +1346,21 @@ int DLLEXPORT ENgetnodetype(int index, int *code) } +int DLLEXPORT ENgetcoord(int index, EN_API_FLOAT_TYPE *x, EN_API_FLOAT_TYPE *y) +/*---------------------------------------------------------------- + ** Input: index = node index + ** Output: *x = value of node's coordinate + ** *x = value of node's coordinate + ** Returns: error code + ** Purpose: retrieves coordinate x, y for a node + **---------------------------------------------------------------- + */ +{ + *x = Coord[index].X[0]; + *y = Coord[index].Y[0]; + return 0; +} + int DLLEXPORT ENgetnodevalue(int index, int code, EN_API_FLOAT_TYPE *value) /*---------------------------------------------------------------- ** Input: index = node index @@ -2330,10 +2346,16 @@ int DLLEXPORT ENsettimeparam(int code, long value) { if (!Openflag) return(102); if (OpenHflag || OpenQflag) { - // --> there's nothing wrong with changing certain time parameters during a simulation run - if (code != EN_DURATION) { + // --> there's nothing wrong with changing certain time parameters during a simulation run, or before the run has started. + // todo -- how to tell? + /* + if (code == EN_DURATION || code == EN_HTIME || code == EN_REPORTSTEP || code == EN_DURATION || Htime == 0) { + // it's ok + } + else { return(109); } + */ } if (value < 0) return(202); switch(code) @@ -2730,10 +2752,12 @@ void initpointers() Pattern = NULL; Curve = NULL; Control = NULL; + Coord = NULL; X = NULL; Patlist = NULL; Curvelist = NULL; + Coordlist = NULL; Adjlist = NULL; Aii = NULL; Aij = NULL; @@ -2813,12 +2837,14 @@ int allocdata() Control = (Scontrol *) calloc(MaxControls+1,sizeof(Scontrol)); Pattern = (Spattern *) calloc(MaxPats+1, sizeof(Spattern)); Curve = (Scurve *) calloc(MaxCurves+1, sizeof(Scurve)); + Coord = (Scoord *) calloc(MaxNodes+1, sizeof(Scoord)); ERRCODE(MEMCHECK(Tank)); ERRCODE(MEMCHECK(Pump)); ERRCODE(MEMCHECK(Valve)); ERRCODE(MEMCHECK(Control)); ERRCODE(MEMCHECK(Pattern)); ERRCODE(MEMCHECK(Curve)); + ERRCODE(MEMCHECK(Coord)); } /* Initialize pointers used in patterns, curves, and demand category lists */ @@ -2836,7 +2862,19 @@ int allocdata() Curve[n].X = NULL; Curve[n].Y = NULL; } - for (n=0; n<=MaxNodes; n++) Node[n].D = NULL; + + for (n=0; n<=MaxNodes; n++) + { + // node demand + Node[n].D = NULL; + /* Allocate memory for coord data */ + Coord[n].X = (double *) calloc(1, sizeof(double)); + Coord[n].Y = (double *) calloc(1, sizeof(double)); + if (Coord[n].X == NULL || Coord[n].Y == NULL) return(101); + Coord[n].X[0] = 0; + Coord[n].Y[0] = 0; + } + } /* Allocate memory for rule base (see RULES.C) */ diff --git a/src/funcs.h b/src/funcs.h index 1fa5677..c7907f8 100755 --- a/src/funcs.h +++ b/src/funcs.h @@ -61,11 +61,13 @@ int addnodeID(int, char *); /* Adds node ID to data base */ int addlinkID(int, char *); /* Adds link ID to data base */ int addpattern(char *); /* Adds pattern to data base */ int addcurve(char *); /* Adds curve to data base */ +int addcoord(char *); /* Adds coord to data base */ STmplist *findID(char *, STmplist *); /* Locates ID on linked list */ int unlinked(void); /* Checks for unlinked nodes */ int getpumpparams(void); /* Computes pump curve coeffs.*/ int getpatterns(void); /* Gets pattern data from list*/ int getcurves(void); /* Gets curve data from list */ +int getcoords(void); /* Gets coordinate data from list */ int findmatch(char *,char *[]); /* Finds keyword in line */ int match(char *, char *); /* Checks for word match */ int gettokens(char *); /* Tokenizes input line */ @@ -82,6 +84,7 @@ int pumpdata(void); /* Processes pump data */ int valvedata(void); /* Processes valve data */ int patterndata(void); /* Processes pattern data */ int curvedata(void); /* Processes curve data */ +int coordata(void); /* Processes coordinate data */ int demanddata(void); /* Processes demand data */ int controldata(void); /* Processes simple controls */ int energydata(void); /* Processes energy data */ diff --git a/src/input2.c b/src/input2.c index a0fa344..1c8b873 100755 --- a/src/input2.c +++ b/src/input2.c @@ -48,6 +48,7 @@ char *Tok[MAXTOKS]; /* Array of token strings */ /* Used in INPUT3.C: */ STmplist *PrevPat; /* Pointer to pattern list element */ STmplist *PrevCurve; /* Pointer to curve list element */ +STmplist *PrevCoord; /* Pointer to coordinate list element */ /* Defined in enumstxt.h in EPANET.C */ extern char *SectTxt[]; /* Input section keywords */ @@ -78,7 +79,8 @@ int netsize() MaxRules = 0; MaxCurves = 0; sect = -1; - + MaxCoords = 0; + /* Add a default pattern 0 */ MaxPats = -1; addpattern(""); @@ -106,20 +108,22 @@ int netsize() /* Add to count of current component */ switch(sect) - { - case _JUNCTIONS: MaxJuncs++; break; - case _RESERVOIRS: - case _TANKS: MaxTanks++; break; - case _PIPES: MaxPipes++; break; - case _PUMPS: MaxPumps++; break; - case _VALVES: MaxValves++; break; - case _CONTROLS: MaxControls++; break; - case _RULES: addrule(tok); break; /* See RULES.C */ - case _PATTERNS: errcode = addpattern(tok); - break; - case _CURVES: errcode = addcurve(tok); - break; - } + { + case _JUNCTIONS: MaxJuncs++; break; + case _RESERVOIRS: + case _TANKS: MaxTanks++; break; + case _PIPES: MaxPipes++; break; + case _PUMPS: MaxPumps++; break; + case _VALVES: MaxValves++; break; + case _CONTROLS: MaxControls++; break; + case _RULES: addrule(tok); break; /* See RULES.C */ + case _PATTERNS: errcode = addpattern(tok); + break; + case _CURVES: errcode = addcurve(tok); + break; + case _COORDS: errcode = addcoord(tok); //06.02.2010-woohn + break; + } if (errcode) break; } @@ -172,6 +176,8 @@ int readdata() Npats = MaxPats; PrevPat = NULL; PrevCurve = NULL; + PrevCoord = NULL; + sect = -1; errsum = 0; @@ -239,6 +245,7 @@ int readdata() /* Get pattern & curve data from temp. lists */ if (!errcode) errcode = getpatterns(); if (!errcode) errcode = getcurves(); + if (!errcode) errcode = getcoords(); if (!errcode) errcode = getpumpparams(); /* Free input buffer */ @@ -293,7 +300,7 @@ int newline(int sect, char *line) case _OPTIONS: return(optiondata()); /* Data in these sections are not used for any computations */ - case _COORDS: return(0); + case _COORDS: return(coordata()); case _LABELS: return(0); case _TAGS: return(0); case _VERTICES: return(0); @@ -513,6 +520,42 @@ int addcurve(char *id) return(0); } +int addcoord(char *id) +/* + **------------------------------------------------------------- + ** Input: id = curve ID label + ** Output: returns error code + ** Purpose: adds a new curve to the database + **-------------------------------------------------------------- + */ +{ + STmplist *c; + + /* Check if ID is same as last one processed */ + if (Coordlist != NULL && strcmp(id,Coordlist->ID) == 0) return(0); + + /* Check that coordinate was not already created */ + if (findID(id,Coordlist) == NULL) + { + + /* Update coordinate count & create new list element */ + (MaxCoords)++; + c = (STmplist *) malloc(sizeof(STmplist)); + if (c == NULL) { + return(101); + } + else { + /* Initialize list element properties */ + c->i = MaxCoords; + strncpy(c->ID,id,MAXID); + c->x = NULL; + c->y = NULL; + c->next = Coordlist; + Coordlist = c; + } + } + return(0); +} STmplist *findID(char *id, STmplist *list) /* @@ -705,6 +748,64 @@ int getcurves(void) return(0); } +int getcoords(void) +/* + **----------------------------------------------------------- + ** Input: none + ** Output: returns error code + ** Purpose: retrieves curve data from temporary linked list + **----------------------------------------------------------- + */ +{ + int i,j,n; + double x; + SFloatlist *xFloatList, *yFloatList; + STmplist *coordinateList; + + /* Start at head of coordinate list */ + coordinateList = Coordlist; + + /* Traverse list of coordinates */ + while (coordinateList != NULL) + { + i = coordinateList->i; + if (i >= 1 && i <= MaxNodes) + { + /* Save coordinate ID */ + strcpy(Coord[i].ID, coordinateList->ID); + + n = 1; //Coord[i].Npts + + /* Traverse list of x,y data */ + x = BIG; + xFloatList = coordinateList->x; + yFloatList = coordinateList->y; + j = n - 1; + while (xFloatList != NULL && yFloatList != NULL && j >= 0) + { + + /* Check that x data is in ascending order */ + if (xFloatList->value >= x) + { + sprintf(Msg,ERR230,coordinateList->ID); + writeline(Msg); + return(200); + } + x = xFloatList->value; + + /* Save x,y data in Curve structure */ + Coord[i].X[j] = xFloatList->value; + xFloatList = xFloatList->next; + Coord[i].Y[j] = yFloatList->value; + yFloatList = yFloatList->next; + j--; + } + } + coordinateList = coordinateList->next; + } + return(0); +} + int findmatch(char *line, char *keyword[]) /* diff --git a/src/input3.c b/src/input3.c index 0d72c37..a19bfdc 100755 --- a/src/input3.c +++ b/src/input3.c @@ -42,6 +42,8 @@ extern char *Fldname[]; extern char *Tok[MAXTOKS]; extern STmplist *PrevPat; extern STmplist *PrevCurve; + +extern STmplist *PrevCoord; extern int Ntokens; @@ -577,6 +579,59 @@ int curvedata() return(0); } +int coordata() +/* + **-------------------------------------------------------------- + ** Input: none + ** Output: returns error code + ** Purpose: processes coordinate data + ** Format: + ** [COORD] + ** id x y + **-------------------------------------------------------------- + */ +{ + double x,y; + SFloatlist *fx, *fy; + STmplist *c; + + /* Check for valid curve ID */ + if (Ntokens < 3) return(201); + + if ( + PrevCoord != NULL && + strcmp(Tok[0],PrevCoord->ID) == 0 + ) c = PrevCoord; + else c = findID(Tok[0],Coordlist); + + // c = findID(Tok[0],Coordlist); + if (c == NULL) return(205); + + /* Check for valid data */ + if (!getfloat(Tok[1],&x)) return(202); + if (!getfloat(Tok[2],&y)) return(202); + + /* Add new data point to curve's linked list */ + fx = (SFloatlist *) malloc(sizeof(SFloatlist)); + fy = (SFloatlist *) malloc(sizeof(SFloatlist)); + if (fx == NULL || fy == NULL) return(101); + fx->value = x; + fx->next = c->x; + c->x = fx; + fy->value = y; + fy->next = c->y; + c->y = fy; + //Curve[c->i].Npts++; + + /* Save the pointer to this curve */ + PrevCoord = c; + return(0); + + /* Save coordn data */ + //Coord[Njuncs].X = x; + //Coord[Njuncs].Y = y; + +} /* end of coordata */ int demanddata() /* diff --git a/src/toolkit.h b/src/toolkit.h index 814fc39..b2fa8a7 100755 --- a/src/toolkit.h +++ b/src/toolkit.h @@ -224,6 +224,7 @@ extern "C" { int DLLEXPORT ENgetnodeid(int, char *); int DLLEXPORT ENgetnodetype(int, int *); int DLLEXPORT ENgetnodevalue(int, int, EN_API_FLOAT_TYPE *); + int DLLEXPORT ENgetcoord(int , EN_API_FLOAT_TYPE *, EN_API_FLOAT_TYPE *); int DLLEXPORT ENgetnumdemands(int, int *); int DLLEXPORT ENgetbasedemand(int, int, EN_API_FLOAT_TYPE *); diff --git a/src/types.h b/src/types.h index bc135aa..becf1b2 100755 --- a/src/types.h +++ b/src/types.h @@ -167,6 +167,13 @@ typedef struct /* CURVE OBJECT */ double *Y; /* Y-values */ } Scurve; +typedef struct /* Coord OBJECT */ +{ + char ID[MAXID+1]; /* Coord ID */ + double *X; /* X-values */ + double *Y; /* Y-values */ +} Scoord; + struct Sdemand /* DEMAND CATEGORY OBJECT */ { double Base; /* Baseline demand */ diff --git a/src/vars.h b/src/vars.h index 6ca5be4..99273e3 100755 --- a/src/vars.h +++ b/src/vars.h @@ -76,6 +76,7 @@ EXTERN int MaxNodes, /* Node count from input file */ MaxRules, /* Rule count */ MaxPats, /* Pattern count */ MaxCurves, /* Curve count */ + MaxCoords, /* Coords count */ Nnodes, /* Number of network nodes */ Ntanks, /* Number of tanks */ Njuncs, /* Number of junction nodes */ @@ -87,6 +88,7 @@ EXTERN int MaxNodes, /* Node count from input file */ Nrules, /* Number of control rules */ Npats, /* Number of time patterns */ Ncurves, /* Number of data curves */ + Ncoords, /* Number of Coords */ Nperiods, /* Number of reporting periods */ Ncoeffs, /* Number of non-0 matrix coeffs*/ DefPat, /* Default demand pattern */ @@ -157,8 +159,10 @@ EXTERN double *QTankVolumes; EXTERN double *QLinkFlow; EXTERN STmplist *Patlist; /* Temporary time pattern list */ EXTERN STmplist *Curvelist; /* Temporary list of curves */ +EXTERN STmplist *Coordlist; /* Temporary list of coordinates*/ EXTERN Spattern *Pattern; /* Time patterns */ EXTERN Scurve *Curve; /* Curve data */ +EXTERN Scoord *Coord; /* Coordinate data */ EXTERN Snode *Node; /* Node data */ EXTERN Slink *Link; /* Link data */ EXTERN Stank *Tank; /* Tank data */ From d72162114a6bf5f6f8e209a78d78ae42caf31430 Mon Sep 17 00:00:00 2001 From: Sam Hatchett Date: Tue, 28 May 2013 09:47:25 -0400 Subject: [PATCH 29/49] double-typed en toolkit for compilation --- build/Xcode/epanet/epanet.xcodeproj/project.pbxproj | 2 ++ 1 file changed, 2 insertions(+) diff --git a/build/Xcode/epanet/epanet.xcodeproj/project.pbxproj b/build/Xcode/epanet/epanet.xcodeproj/project.pbxproj index b3d2027..ec5a5ae 100644 --- a/build/Xcode/epanet/epanet.xcodeproj/project.pbxproj +++ b/build/Xcode/epanet/epanet.xcodeproj/project.pbxproj @@ -300,6 +300,7 @@ GCC_DYNAMIC_NO_PIC = NO; GCC_MODEL_TUNING = G5; GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = "EN_API_FLOAT_TYPE=double"; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; INSTALL_PATH = /usr/local/lib; PRODUCT_NAME = epanet; @@ -315,6 +316,7 @@ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; EXECUTABLE_PREFIX = lib; GCC_MODEL_TUNING = G5; + GCC_PREPROCESSOR_DEFINITIONS = "EN_API_FLOAT_TYPE=double"; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; INSTALL_PATH = /usr/local/lib; PRODUCT_NAME = epanet; From 067c0fd95025eb56440d3f26bd6e5788914d240c Mon Sep 17 00:00:00 2001 From: Sam Hatchett Date: Fri, 31 May 2013 11:59:09 -0400 Subject: [PATCH 30/49] fixing coordinates bug, adding useful methods --- .../epanet/epanet.xcodeproj/project.pbxproj | 118 ++++++++++++++++++ src/input2.c | 6 +- 2 files changed, 122 insertions(+), 2 deletions(-) diff --git a/build/Xcode/epanet/epanet.xcodeproj/project.pbxproj b/build/Xcode/epanet/epanet.xcodeproj/project.pbxproj index ec5a5ae..3ef27ef 100644 --- a/build/Xcode/epanet/epanet.xcodeproj/project.pbxproj +++ b/build/Xcode/epanet/epanet.xcodeproj/project.pbxproj @@ -42,6 +42,19 @@ 22322FA51068369500641384 /* rules.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F7F1068369500641384 /* rules.c */; }; 22322FA61068369500641384 /* smatrix.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F801068369500641384 /* smatrix.c */; }; 22322FAA106836BC00641384 /* epanet2.h in Headers */ = {isa = PBXBuildFile; fileRef = 22322FA9106836B000641384 /* epanet2.h */; }; + 2255753F17551234009946B1 /* epanet.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F711068369500641384 /* epanet.c */; }; + 2255754017551234009946B1 /* hash.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F731068369500641384 /* hash.c */; }; + 2255754117551234009946B1 /* hydraul.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F751068369500641384 /* hydraul.c */; }; + 2255754217551234009946B1 /* inpfile.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F761068369500641384 /* inpfile.c */; }; + 2255754317551234009946B1 /* input1.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F771068369500641384 /* input1.c */; }; + 2255754417551234009946B1 /* input2.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F781068369500641384 /* input2.c */; }; + 2255754517551234009946B1 /* input3.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F791068369500641384 /* input3.c */; }; + 2255754617551234009946B1 /* mempool.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F7A1068369500641384 /* mempool.c */; }; + 2255754717551234009946B1 /* output.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F7C1068369500641384 /* output.c */; }; + 2255754817551234009946B1 /* quality.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F7D1068369500641384 /* quality.c */; }; + 2255754917551234009946B1 /* report.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F7E1068369500641384 /* report.c */; }; + 2255754A17551234009946B1 /* rules.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F7F1068369500641384 /* rules.c */; }; + 2255754B17551234009946B1 /* smatrix.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F801068369500641384 /* smatrix.c */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -78,6 +91,7 @@ 22322F831068369500641384 /* types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = types.h; path = ../../../src/types.h; sourceTree = SOURCE_ROOT; }; 22322F841068369500641384 /* vars.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = vars.h; path = ../../../src/vars.h; sourceTree = SOURCE_ROOT; }; 22322FA9106836B000641384 /* epanet2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = epanet2.h; path = ../../../include/epanet2.h; sourceTree = SOURCE_ROOT; }; + 2255753B17551217009946B1 /* libepanet-static.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libepanet-static.a"; sourceTree = BUILT_PRODUCTS_DIR; }; D2AAC0630554660B00DB518D /* libepanet.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libepanet.dylib; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ @@ -89,6 +103,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 2255753817551217009946B1 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; D289988505E68E00004EDB86 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -142,6 +163,7 @@ children = ( D2AAC0630554660B00DB518D /* libepanet.dylib */, 22322F66106833BB00641384 /* runepanet */, + 2255753B17551217009946B1 /* libepanet-static.a */, ); name = Products; sourceTree = ""; @@ -157,6 +179,13 @@ /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ + 2255753917551217009946B1 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; D2AAC0600554660B00DB518D /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; @@ -193,6 +222,23 @@ productReference = 22322F66106833BB00641384 /* runepanet */; productType = "com.apple.product-type.tool"; }; + 2255753A17551217009946B1 /* epanet-static */ = { + isa = PBXNativeTarget; + buildConfigurationList = 2255753E17551217009946B1 /* Build configuration list for PBXNativeTarget "epanet-static" */; + buildPhases = ( + 2255753717551217009946B1 /* Sources */, + 2255753817551217009946B1 /* Frameworks */, + 2255753917551217009946B1 /* Headers */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "epanet-static"; + productName = "epanet-static"; + productReference = 2255753B17551217009946B1 /* libepanet-static.a */; + productType = "com.apple.product-type.library.static"; + }; D2AAC0620554660B00DB518D /* epanet */ = { isa = PBXNativeTarget; buildConfigurationList = 1DEB914A08733D8E0010E9CD /* Build configuration list for PBXNativeTarget "epanet" */; @@ -234,6 +280,7 @@ targets = ( D2AAC0620554660B00DB518D /* epanet */, 22322F65106833BB00641384 /* runepanet */, + 2255753A17551217009946B1 /* epanet-static */, ); }; /* End PBXProject section */ @@ -259,6 +306,26 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 2255753717551217009946B1 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 2255753F17551234009946B1 /* epanet.c in Sources */, + 2255754017551234009946B1 /* hash.c in Sources */, + 2255754117551234009946B1 /* hydraul.c in Sources */, + 2255754217551234009946B1 /* inpfile.c in Sources */, + 2255754317551234009946B1 /* input1.c in Sources */, + 2255754417551234009946B1 /* input2.c in Sources */, + 2255754517551234009946B1 /* input3.c in Sources */, + 2255754617551234009946B1 /* mempool.c in Sources */, + 2255754717551234009946B1 /* output.c in Sources */, + 2255754817551234009946B1 /* quality.c in Sources */, + 2255754917551234009946B1 /* report.c in Sources */, + 2255754A17551234009946B1 /* rules.c in Sources */, + 2255754B17551234009946B1 /* smatrix.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; D2AAC0610554660B00DB518D /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -394,6 +461,49 @@ }; name = Release; }; + 2255753C17551217009946B1 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_64_BIT)"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_WARN_EMPTY_BODY = YES; + COPY_PHASE_STRIP = NO; + EXECUTABLE_PREFIX = lib; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_OBJC_EXCEPTIONS = YES; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + MACOSX_DEPLOYMENT_TARGET = 10.8; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + }; + name = Debug; + }; + 2255753D17551217009946B1 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_64_BIT)"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_WARN_EMPTY_BODY = YES; + COPY_PHASE_STRIP = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + EXECUTABLE_PREFIX = lib; + GCC_ENABLE_OBJC_EXCEPTIONS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + MACOSX_DEPLOYMENT_TARGET = 10.8; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + }; + name = Release; + }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ @@ -424,6 +534,14 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + 2255753E17551217009946B1 /* Build configuration list for PBXNativeTarget "epanet-static" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 2255753C17551217009946B1 /* Debug */, + 2255753D17551217009946B1 /* Release */, + ); + defaultConfigurationIsVisible = 0; + }; /* End XCConfigurationList section */ }; rootObject = 08FB7793FE84155DC02AAC07 /* Project object */; diff --git a/src/input2.c b/src/input2.c index 1c8b873..41fe783 100755 --- a/src/input2.c +++ b/src/input2.c @@ -546,7 +546,8 @@ int addcoord(char *id) } else { /* Initialize list element properties */ - c->i = MaxCoords; + // c->i = MaxCoords; // bug! if coordinates are not in the same order as junctions, then this is a BAD assumption + // do this later: c->i = findnode(id); strncpy(c->ID,id,MAXID); c->x = NULL; c->y = NULL; @@ -768,7 +769,8 @@ int getcoords(void) /* Traverse list of coordinates */ while (coordinateList != NULL) { - i = coordinateList->i; + // BAD! ---> i = coordinateList->i; + i = findnode(coordinateList->ID); if (i >= 1 && i <= MaxNodes) { /* Save coordinate ID */ From a55f5e3e79331202f5df86d0169a8690c0fa73c3 Mon Sep 17 00:00:00 2001 From: Sam Hatchett Date: Tue, 4 Jun 2013 17:33:44 -0400 Subject: [PATCH 31/49] fixing coordinates (as in, disabling) --- src/input2.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/input2.c b/src/input2.c index 41fe783..9f569e0 100755 --- a/src/input2.c +++ b/src/input2.c @@ -121,8 +121,8 @@ int netsize() break; case _CURVES: errcode = addcurve(tok); break; - case _COORDS: errcode = addcoord(tok); //06.02.2010-woohn - break; +// case _COORDS: errcode = addcoord(tok); //06.02.2010-woohn +// break; } if (errcode) break; } @@ -245,7 +245,7 @@ int readdata() /* Get pattern & curve data from temp. lists */ if (!errcode) errcode = getpatterns(); if (!errcode) errcode = getcurves(); - if (!errcode) errcode = getcoords(); + //if (!errcode) errcode = getcoords(); if (!errcode) errcode = getpumpparams(); /* Free input buffer */ @@ -300,7 +300,7 @@ int newline(int sect, char *line) case _OPTIONS: return(optiondata()); /* Data in these sections are not used for any computations */ - case _COORDS: return(coordata()); + case _COORDS: return (0); //return(coordata()); case _LABELS: return(0); case _TAGS: return(0); case _VERTICES: return(0); From 7e731b78abb17ace3257f1bea5ba8419eff2e293 Mon Sep 17 00:00:00 2001 From: jamesuber Date: Wed, 5 Jun 2013 11:33:17 -0400 Subject: [PATCH 32/49] added method ENgetaveragepatternvalue. modified ENgetbasedemand and ENgetdemandpattern to use pattern index starting with 1, consistent with other API functions. --- include/epanet2.h | 1 + src/epanet.c | 41 ++++++++++++++++++++++++++++++++++------- src/toolkit.h | 1 + 3 files changed, 36 insertions(+), 7 deletions(-) diff --git a/include/epanet2.h b/include/epanet2.h index d1d37f1..ff05d27 100755 --- a/include/epanet2.h +++ b/include/epanet2.h @@ -212,6 +212,7 @@ extern "C" { int DLLEXPORT ENgetpatternid(int, char *); int DLLEXPORT ENgetpatternlen(int, int *); int DLLEXPORT ENgetpatternvalue(int, int, float *); + int DLLEXPORT ENgetaveragepatternvalue(int index, EN_API_FLOAT_TYPE *value); int DLLEXPORT ENgetqualtype(int *, int *); int DLLEXPORT ENgeterror(int, char *, int); diff --git a/src/epanet.c b/src/epanet.c index 5b7edb1..4c12d43 100755 --- a/src/epanet.c +++ b/src/epanet.c @@ -3255,20 +3255,25 @@ int DLLEXPORT ENgetnumdemands(int nodeIndex, int *numDemands) } int DLLEXPORT ENgetbasedemand(int nodeIndex, int demandIdx, EN_API_FLOAT_TYPE *baseDemand) { - Pdemand d; - int n=0; - /* Check for valid arguments */ - if (!Openflag) return(102); - if (nodeIndex <= 0 || nodeIndex > Nnodes) return(203); + Pdemand d; + int n=1; + /* Check for valid arguments */ + if (!Openflag) return(102); + if (nodeIndex <= 0 || nodeIndex > Nnodes) return(203); + if (nodeIndex <= Njuncs) { for(d=Node[nodeIndex].D; nnext) n++; if(n!=demandIdx) return(253); *baseDemand=(EN_API_FLOAT_TYPE)(d->Base*Ucf[FLOW]); - return 0; + } + else { + *baseDemand=(EN_API_FLOAT_TYPE)(0.0); + } + return 0; } int DLLEXPORT ENgetdemandpattern(int nodeIndex, int demandIdx, int *pattIdx) { Pdemand d; - int n=0; + int n=1; /* Check for valid arguments */ if (!Openflag) return(102); if (nodeIndex <= 0 || nodeIndex > Nnodes) return(203); @@ -3278,5 +3283,27 @@ int DLLEXPORT ENgetdemandpattern(int nodeIndex, int demandIdx, int *pattIdx) return 0; } +int DLLEXPORT ENgetaveragepatternvalue(int index, EN_API_FLOAT_TYPE *value) +/*---------------------------------------------------------------- + ** Input: index = index of time pattern + ** period = pattern time period + ** Output: *value = pattern multiplier + ** Returns: error code + ** Purpose: retrieves multiplier for a specific time period + ** and pattern + **---------------------------------------------------------------- + */ +{ *value = 0.0; + if (!Openflag) return(102); + if (index < 1 || index > Npats) return(205); + //if (period < 1 || period > Pattern[index].Length) return(251); + for (int i=0; i Date: Mon, 15 Jul 2013 13:47:01 -0400 Subject: [PATCH 33/49] llvm compilation changes (enum scoping) - added useful setMultiplierForSource method to Aggregator. --- build/Xcode/epanet/epanet.xcodeproj/project.pbxproj | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/build/Xcode/epanet/epanet.xcodeproj/project.pbxproj b/build/Xcode/epanet/epanet.xcodeproj/project.pbxproj index 3ef27ef..377eb61 100644 --- a/build/Xcode/epanet/epanet.xcodeproj/project.pbxproj +++ b/build/Xcode/epanet/epanet.xcodeproj/project.pbxproj @@ -473,10 +473,7 @@ EXECUTABLE_PREFIX = lib; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_OBJC_EXCEPTIONS = YES; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); + GCC_PREPROCESSOR_DEFINITIONS = "EN_API_FLOAT_TYPE=double"; GCC_SYMBOLS_PRIVATE_EXTERN = NO; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; MACOSX_DEPLOYMENT_TARGET = 10.8; @@ -497,6 +494,7 @@ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; EXECUTABLE_PREFIX = lib; GCC_ENABLE_OBJC_EXCEPTIONS = YES; + GCC_PREPROCESSOR_DEFINITIONS = "EN_API_FLOAT_TYPE=double"; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; MACOSX_DEPLOYMENT_TARGET = 10.8; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -541,6 +539,7 @@ 2255753D17551217009946B1 /* Release */, ); defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; From 3e92016beecbb20dfc72ed4645b6289ee1b2928d Mon Sep 17 00:00:00 2001 From: Sam Hatchett Date: Fri, 19 Jul 2013 11:13:58 -0400 Subject: [PATCH 34/49] zones are now DMAs --- build/Xcode/epanet/epanet.xcodeproj/project.pbxproj | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/build/Xcode/epanet/epanet.xcodeproj/project.pbxproj b/build/Xcode/epanet/epanet.xcodeproj/project.pbxproj index 377eb61..c66b47b 100644 --- a/build/Xcode/epanet/epanet.xcodeproj/project.pbxproj +++ b/build/Xcode/epanet/epanet.xcodeproj/project.pbxproj @@ -70,7 +70,7 @@ /* Begin PBXFileReference section */ 22322F66106833BB00641384 /* runepanet */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = runepanet; sourceTree = BUILT_PRODUCTS_DIR; }; 22322F701068369500641384 /* enumstxt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = enumstxt.h; path = ../../../src/enumstxt.h; sourceTree = SOURCE_ROOT; }; - 22322F711068369500641384 /* epanet.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = epanet.c; path = ../../../src/epanet.c; sourceTree = SOURCE_ROOT; }; + 22322F711068369500641384 /* epanet.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; lineEnding = 2; name = epanet.c; path = ../../../src/epanet.c; sourceTree = SOURCE_ROOT; xcLanguageSpecificationIdentifier = xcode.lang.c; }; 22322F721068369500641384 /* funcs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = funcs.h; path = ../../../src/funcs.h; sourceTree = SOURCE_ROOT; }; 22322F731068369500641384 /* hash.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = hash.c; path = ../../../src/hash.c; sourceTree = SOURCE_ROOT; }; 22322F741068369500641384 /* hash.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = hash.h; path = ../../../src/hash.h; sourceTree = SOURCE_ROOT; }; @@ -82,7 +82,7 @@ 22322F7A1068369500641384 /* mempool.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = mempool.c; path = ../../../src/mempool.c; sourceTree = SOURCE_ROOT; }; 22322F7B1068369500641384 /* mempool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = mempool.h; path = ../../../src/mempool.h; sourceTree = SOURCE_ROOT; }; 22322F7C1068369500641384 /* output.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = output.c; path = ../../../src/output.c; sourceTree = SOURCE_ROOT; }; - 22322F7D1068369500641384 /* quality.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = quality.c; path = ../../../src/quality.c; sourceTree = SOURCE_ROOT; }; + 22322F7D1068369500641384 /* quality.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; lineEnding = 2; name = quality.c; path = ../../../src/quality.c; sourceTree = SOURCE_ROOT; xcLanguageSpecificationIdentifier = xcode.lang.c; }; 22322F7E1068369500641384 /* report.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = report.c; path = ../../../src/report.c; sourceTree = SOURCE_ROOT; }; 22322F7F1068369500641384 /* rules.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = rules.c; path = ../../../src/rules.c; sourceTree = SOURCE_ROOT; }; 22322F801068369500641384 /* smatrix.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = smatrix.c; path = ../../../src/smatrix.c; sourceTree = SOURCE_ROOT; }; @@ -90,7 +90,7 @@ 22322F821068369500641384 /* toolkit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = toolkit.h; path = ../../../src/toolkit.h; sourceTree = SOURCE_ROOT; }; 22322F831068369500641384 /* types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = types.h; path = ../../../src/types.h; sourceTree = SOURCE_ROOT; }; 22322F841068369500641384 /* vars.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = vars.h; path = ../../../src/vars.h; sourceTree = SOURCE_ROOT; }; - 22322FA9106836B000641384 /* epanet2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = epanet2.h; path = ../../../include/epanet2.h; sourceTree = SOURCE_ROOT; }; + 22322FA9106836B000641384 /* epanet2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 2; name = epanet2.h; path = ../../../include/epanet2.h; sourceTree = SOURCE_ROOT; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; 2255753B17551217009946B1 /* libepanet-static.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libepanet-static.a"; sourceTree = BUILT_PRODUCTS_DIR; }; D2AAC0630554660B00DB518D /* libepanet.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libepanet.dylib; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ From 15d187433fbbf00be8fdf294a8340b44f183aae6 Mon Sep 17 00:00:00 2001 From: Sam Hatchett Date: Fri, 19 Jul 2013 17:36:04 -0400 Subject: [PATCH 35/49] needed mods - adding qtime setter - formatting issues --- .../epanet/epanet.xcodeproj/project.pbxproj | 12 +- include/epanet2.h | 7 +- src/epanet.c | 107 +++++++++++------- src/quality.c | 2 +- 4 files changed, 73 insertions(+), 55 deletions(-) diff --git a/build/Xcode/epanet/epanet.xcodeproj/project.pbxproj b/build/Xcode/epanet/epanet.xcodeproj/project.pbxproj index f2d2e6f..30d1018 100644 --- a/build/Xcode/epanet/epanet.xcodeproj/project.pbxproj +++ b/build/Xcode/epanet/epanet.xcodeproj/project.pbxproj @@ -121,7 +121,6 @@ 08FB7794FE84155DC02AAC07 /* epanet */ = { isa = PBXGroup; children = ( - 2298EBDB16B17DBD0088A6DC /* LemonTiger */, 22322FA8106836A000641384 /* Include */, 08FB7795FE84155DC02AAC07 /* Source */, 1AB674ADFE9D54B511CA2CBB /* Products */, @@ -132,12 +131,12 @@ 08FB7795FE84155DC02AAC07 /* Source */ = { isa = PBXGroup; children = ( - 22322F701068369500641384 /* enumstxt.h */, 22322F711068369500641384 /* epanet.c */, + 22322F751068369500641384 /* hydraul.c */, + 22322F701068369500641384 /* enumstxt.h */, 22322F721068369500641384 /* funcs.h */, 22322F731068369500641384 /* hash.c */, 22322F741068369500641384 /* hash.h */, - 22322F751068369500641384 /* hydraul.c */, 22322F761068369500641384 /* inpfile.c */, 22322F771068369500641384 /* input1.c */, 22322F781068369500641384 /* input2.c */, @@ -174,13 +173,6 @@ name = Include; sourceTree = ""; }; - 2298EBDB16B17DBD0088A6DC /* LemonTiger */ = { - isa = PBXGroup; - children = ( - ); - name = LemonTiger; - sourceTree = ""; - }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ diff --git a/include/epanet2.h b/include/epanet2.h index f54ff9b..d851a43 100644 --- a/include/epanet2.h +++ b/include/epanet2.h @@ -97,8 +97,9 @@ #define EN_PERIODS 9 #define EN_STARTTIME 10 /* Added TNT 10/2/2009 */ #define EN_HTIME 11 -#define EN_HALTFLAG 12 -#define EN_NEXTEVENT 13 +#define EN_QTIME 12 +#define EN_HALTFLAG 13 +#define EN_NEXTEVENT 14 #define EN_ITERATIONS 0 #define EN_RELATIVEERROR 1 @@ -250,7 +251,7 @@ extern "C" { int DLLEXPORT ENsettimeparam(int, long); int DLLEXPORT ENsetoption(int, EN_API_FLOAT_TYPE); int DLLEXPORT ENsetstatusreport(int); - int DLLEXPORT ENsetqualtype(int, char *, char *, char *); + int DLLEXPORT ENsetqualtype(int qualcode, char *chemname, char *chemunits, char *tracenode); //LemonTiger functions /* See testLT.c for a LemonTiger test */ diff --git a/src/epanet.c b/src/epanet.c index 998dd44..d3e0be7 100755 --- a/src/epanet.c +++ b/src/epanet.c @@ -1974,7 +1974,7 @@ int DLLEXPORT ENsetnodevalue(int index, int code, EN_API_FLOAT_TYPE v) if (j < 0 || j > Npats) return(205); source->Pat = j; } - else + else // code == EN_SOURCETYPE { j = ROUND(value); if ( j < CONCEN || j > FLOWPACED) return(251); @@ -2348,44 +2348,69 @@ int DLLEXPORT ENsettimeparam(int code, long value) */ } if (value < 0) return(202); - switch(code) - { - case EN_DURATION: Dur = value; - if (Rstart > Dur) Rstart = 0; - break; - case EN_HYDSTEP: if (value == 0) return(202); - Hstep = value; - Hstep = MIN(Pstep, Hstep); - Hstep = MIN(Rstep, Hstep); - Qstep = MIN(Qstep, Hstep); - break; - case EN_QUALSTEP: if (value == 0) return(202); - Qstep = value; - Qstep = MIN(Qstep, Hstep); - break; - case EN_PATTERNSTEP: if (value == 0) return(202); - Pstep = value; - if (Hstep > Pstep) Hstep = Pstep; - break; - case EN_PATTERNSTART: Pstart = value; - break; - case EN_REPORTSTEP: if (value == 0) return(202); - Rstep = value; - if (Hstep > Rstep) Hstep = Rstep; - break; - case EN_REPORTSTART: if (Rstart > Dur) return(202); - Rstart = value; - break; - case EN_RULESTEP: if (value == 0) return(202); - Rulestep = value; - Rulestep = MIN(Rulestep, Hstep); - break; - case EN_STATISTIC: if (value > RANGE) return(202); - Tstatflag = (char)value; - break; - case EN_HTIME: Htime = value; - break; - default: return(251); + switch(code) + { + case EN_DURATION: + Dur = value; + if (Rstart > Dur) Rstart = 0; + break; + + case EN_HYDSTEP: + if (value == 0) return(202); + Hstep = value; + Hstep = MIN(Pstep, Hstep); + Hstep = MIN(Rstep, Hstep); + Qstep = MIN(Qstep, Hstep); + break; + + case EN_QUALSTEP: + if (value == 0) return(202); + Qstep = value; + Qstep = MIN(Qstep, Hstep); + break; + + case EN_PATTERNSTEP: + if (value == 0) return(202); + Pstep = value; + if (Hstep > Pstep) Hstep = Pstep; + break; + + case EN_PATTERNSTART: + Pstart = value; + break; + + case EN_REPORTSTEP: + if (value == 0) return(202); + Rstep = value; + if (Hstep > Rstep) Hstep = Rstep; + break; + + case EN_REPORTSTART: + if (Rstart > Dur) return(202); + Rstart = value; + break; + + case EN_RULESTEP: + if (value == 0) return(202); + Rulestep = value; + Rulestep = MIN(Rulestep, Hstep); + break; + + case EN_STATISTIC: + if (value > RANGE) return(202); + Tstatflag = (char)value; + break; + + case EN_HTIME: + Htime = value; + break; + + case EN_QTIME: + Qtime = value; + break; + + default: + return(251); } return(0); } @@ -2396,8 +2421,8 @@ int DLLEXPORT ENsetoption(int code, EN_API_FLOAT_TYPE v) ** Input: code = option code (see TOOLKIT.H) ** v = option value ** Output: none -** Returns: error code -** Purpose: sets value for an analysis option +** Returns: error code +** Purpose: sets value for an analysis option **---------------------------------------------------------------- */ { diff --git a/src/quality.c b/src/quality.c index f7925df..d17af7c 100755 --- a/src/quality.c +++ b/src/quality.c @@ -233,7 +233,7 @@ int runqual(long *t) Htime = hydtime + hydstep; } else { - // stepwise calculation + // stepwise calculation - hydraulic results are already in memory for (int i=1; i<= Ntanks; ++i) { QTankVolumes[i-1] = Tank[i].V; } From 99119ef9926a42d7a5e9e05ddbc0e5f9a6a2e193 Mon Sep 17 00:00:00 2001 From: Sam Hatchett Date: Mon, 22 Jul 2013 16:39:09 -0400 Subject: [PATCH 36/49] bug fixes from master --- src/epanet.c | 7 ++++--- src/output.c | 1 + 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/epanet.c b/src/epanet.c index 4c12d43..72e352e 100755 --- a/src/epanet.c +++ b/src/epanet.c @@ -1779,8 +1779,8 @@ int DLLEXPORT ENgetcurve(int curveIndex, int *nValues, EN_API_FLOAT_TYPE **xVal EN_API_FLOAT_TYPE *pointX = calloc(nPoints, sizeof(EN_API_FLOAT_TYPE)); EN_API_FLOAT_TYPE *pointY = calloc(nPoints, sizeof(EN_API_FLOAT_TYPE)); - - for (int iPoint = 0; iPoint < nPoints; iPoint++) { + int iPoint; + for (iPoint = 0; iPoint < nPoints; iPoint++) { double x = curve.X[iPoint] * Ucf[LENGTH]; double y = curve.Y[iPoint] * Ucf[VOLUME]; pointX[iPoint] = (EN_API_FLOAT_TYPE)x; @@ -3297,7 +3297,8 @@ int DLLEXPORT ENgetaveragepatternvalue(int index, EN_API_FLOAT_TYPE *value) if (!Openflag) return(102); if (index < 1 || index > Npats) return(205); //if (period < 1 || period > Pattern[index].Length) return(251); - for (int i=0; i Date: Tue, 23 Jul 2013 09:26:11 -0400 Subject: [PATCH 37/49] removed some old lemontiger declarations. --- include/epanet2.h | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/include/epanet2.h b/include/epanet2.h index d851a43..bf46009 100644 --- a/include/epanet2.h +++ b/include/epanet2.h @@ -1,7 +1,7 @@ /* ******************************************************************* - TOOLKIT.H - Prototypes for EPANET Functions Exported to DLL Toolkit + EPANET2.H - Prototypes for EPANET Functions Exported to DLL Toolkit VERSION: 2.00 DATE: 5/8/00 @@ -253,21 +253,6 @@ extern "C" { int DLLEXPORT ENsetstatusreport(int); int DLLEXPORT ENsetqualtype(int qualcode, char *chemname, char *chemunits, char *tracenode); - //LemonTiger functions - /* See testLT.c for a LemonTiger test */ - - //LT equivalent to ENopenH() + ENopenQ() + ENinitH() + ENinitQ() - int DLLEXPORT ENopeninitHQ(); - - //LT equivalent to ENrunQ() + ENnextQ(); - int DLLEXPORT ENrunnextHQ(long*, long*); - - //LT equivalent to ENrunQ() + ENstepQ(); - int DLLEXPORT ENrunstepHQ(long*, long*); - - //LT equivalent to ENcloseH() + ENcloseQ(); - int DLLEXPORT ENcloseHQ(); - #if defined(__cplusplus) } #endif From e7f6a8a08562292707f75e2e922da93098594935 Mon Sep 17 00:00:00 2001 From: Sam Hatchett Date: Tue, 23 Jul 2013 14:56:12 -0400 Subject: [PATCH 38/49] fixed the getstatistic api call -- should return floattype by ref --- .../epanet/epanet.xcodeproj/project.pbxproj | 4 ++- include/epanet2.h | 2 +- src/epanet.c | 8 +++--- src/hydraul.c | 2 +- src/quality.c | 27 ++++++++++++++----- src/vars.h | 3 ++- 6 files changed, 31 insertions(+), 15 deletions(-) diff --git a/build/Xcode/epanet/epanet.xcodeproj/project.pbxproj b/build/Xcode/epanet/epanet.xcodeproj/project.pbxproj index 30d1018..25795cc 100644 --- a/build/Xcode/epanet/epanet.xcodeproj/project.pbxproj +++ b/build/Xcode/epanet/epanet.xcodeproj/project.pbxproj @@ -40,7 +40,7 @@ 22322FA41068369500641384 /* report.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F7E1068369500641384 /* report.c */; }; 22322FA51068369500641384 /* rules.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F7F1068369500641384 /* rules.c */; }; 22322FA61068369500641384 /* smatrix.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F801068369500641384 /* smatrix.c */; }; - 22322FAA106836BC00641384 /* epanet2.h in Headers */ = {isa = PBXBuildFile; fileRef = 22322FA9106836B000641384 /* epanet2.h */; }; + 22322FAA106836BC00641384 /* epanet2.h in Headers */ = {isa = PBXBuildFile; fileRef = 22322FA9106836B000641384 /* epanet2.h */; settings = {ATTRIBUTES = (Public, ); }; }; 2255753F17551234009946B1 /* epanet.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F711068369500641384 /* epanet.c */; }; 2255754017551234009946B1 /* hash.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F731068369500641384 /* hash.c */; }; 2255754117551234009946B1 /* hydraul.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F751068369500641384 /* hydraul.c */; }; @@ -54,6 +54,7 @@ 2255754917551234009946B1 /* report.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F7E1068369500641384 /* report.c */; }; 2255754A17551234009946B1 /* rules.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F7F1068369500641384 /* rules.c */; }; 2255754B17551234009946B1 /* smatrix.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F801068369500641384 /* smatrix.c */; }; + 226537E0179EDEEB00258C60 /* epanet2.h in Headers */ = {isa = PBXBuildFile; fileRef = 22322FA9106836B000641384 /* epanet2.h */; settings = {ATTRIBUTES = (Public, ); }; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -180,6 +181,7 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( + 226537E0179EDEEB00258C60 /* epanet2.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/include/epanet2.h b/include/epanet2.h index bf46009..5e3cef5 100644 --- a/include/epanet2.h +++ b/include/epanet2.h @@ -219,7 +219,7 @@ extern "C" { int DLLEXPORT ENgetaveragepatternvalue(int index, EN_API_FLOAT_TYPE *value); int DLLEXPORT ENgetqualtype(int *, int *); int DLLEXPORT ENgeterror(int, char *, int); - int DLLEXPORT ENgetstatistic(int code, int* value); + int DLLEXPORT ENgetstatistic(int code, EN_API_FLOAT_TYPE* value); int DLLEXPORT ENgetnodeindex(char *, int *); int DLLEXPORT ENgetnodeid(int, char *); diff --git a/src/epanet.c b/src/epanet.c index 1a10546..c3297f6 100755 --- a/src/epanet.c +++ b/src/epanet.c @@ -1248,7 +1248,7 @@ int DLLEXPORT ENgeterror(int errcode, char *errmsg, int n) else return(0); } -int DLLEXPORT ENgetstatistic(int code, int* value) +int DLLEXPORT ENgetstatistic(int code, EN_API_FLOAT_TYPE* value) /*---------------------------------------------------------------- ** Input: code = type of simulation statistic to retrieve ** Output: value = value of requested statistic @@ -1259,10 +1259,10 @@ int DLLEXPORT ENgetstatistic(int code, int* value) { switch (code) { case EN_ITERATIONS: - *value = _iterations; + *value = (EN_API_FLOAT_TYPE)_iterations; break; case EN_RELATIVEERROR: - *value = _relativeError; + *value = (EN_API_FLOAT_TYPE)_relativeError; break; default: break; @@ -1492,7 +1492,7 @@ int DLLEXPORT ENgetnodevalue(int index, int code, EN_API_FLOAT_TYPE *value) v = (Tank[index-Njuncs].Hmin - Node[index].El) * Ucf[ELEV]; } break; - + case EN_MAXLEVEL: v = 0.0; if ( index > Njuncs ) diff --git a/src/hydraul.c b/src/hydraul.c index bdf0213..8ee6ff8 100755 --- a/src/hydraul.c +++ b/src/hydraul.c @@ -205,7 +205,7 @@ int runhyd(long *t) if (Statflag) writehydstat(iter,relerr); /* solution info */ - _relativeError = (int)relerr; + _relativeError = relerr; _iterations = iter; /*** Updated 3/1/01 ***/ diff --git a/src/quality.c b/src/quality.c index d17af7c..d4d3c0f 100755 --- a/src/quality.c +++ b/src/quality.c @@ -203,6 +203,8 @@ void initqual() Qtime = 0; Rtime = Rstart; Nperiods = 0; + + initsegs(); } @@ -463,12 +465,19 @@ int gethyd(long *hydtime, long *hydstep) { /* Compute reaction rate coeffs. */ - if (Reactflag && Qualflag != AGE) ratecoeffs(); - + if (Reactflag && Qualflag != AGE) { + ratecoeffs(); + } + /* Initialize pipe segments (at time 0) or */ /* else re-orient segments if flow reverses.*/ - if (Qtime == 0) initsegs(); - else reorientsegs(); + //if (Qtime == 0) + // initsegs(); + //else + if (Qtime != 0) { + reorientsegs(); + } + } return(errcode); } @@ -784,9 +793,13 @@ void accumulate(long dt) VolIn[j]++; } } - for (k=1; k<=Nnodes; k++) - if (VolIn[k] > 0.0) XC[k] = MassIn[k]/VolIn[k]; - + + for (k=1; k<=Nnodes; k++) { + if (VolIn[k] > 0.0) { + XC[k] = MassIn[k]/VolIn[k]; + } + } + /* Move mass from first segment of each pipe into downstream node */ memset(VolIn,0,(Nnodes+1)*sizeof(double)); memset(MassIn,0,(Nnodes+1)*sizeof(double)); diff --git a/src/vars.h b/src/vars.h index 4378123..a2780a0 100755 --- a/src/vars.h +++ b/src/vars.h @@ -171,7 +171,8 @@ EXTERN Svalve *Valve; /* Valve data */ EXTERN Scontrol *Control; /* Control data */ EXTERN HTtable *Nht, *Lht; /* Hash tables for ID labels */ EXTERN Padjlist *Adjlist; /* Node adjacency lists */ -EXTERN int _relativeError, _iterations; /* Info about hydraulic solution */ +EXTERN double _relativeError; +EXTERN int _iterations; /* Info about hydraulic solution */ /* ** NOTE: Hydraulic analysis of the pipe network at a given point in time From d7d0472947449359301828c7416548c1f7ea7dd9 Mon Sep 17 00:00:00 2001 From: jamesuber Date: Sun, 25 Aug 2013 23:57:15 -0400 Subject: [PATCH 39/49] ENsetbasedemand() and ENsetnodevalue() - added ENsetbasedemand to allow changes to the base demands for each demand category. Changed behavior of ENsetnodevalue when used with EN_TANKLEVEL to also set the volume in addition to the initial volume (similar to how it sets the initial head and head. Without that, we can't reset the tank head and volume from RTX. --- include/epanet2.h | 1 + src/epanet.c | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/include/epanet2.h b/include/epanet2.h index 5e3cef5..c65d493 100644 --- a/include/epanet2.h +++ b/include/epanet2.h @@ -252,6 +252,7 @@ extern "C" { int DLLEXPORT ENsetoption(int, EN_API_FLOAT_TYPE); int DLLEXPORT ENsetstatusreport(int); int DLLEXPORT ENsetqualtype(int qualcode, char *chemname, char *chemunits, char *tracenode); + int DLLEXPORT ENsetbasedemand(int nodeIndex, int demandIdx, EN_API_FLOAT_TYPE baseDemand); #if defined(__cplusplus) } diff --git a/src/epanet.c b/src/epanet.c index c3297f6..e3f4f3d 100755 --- a/src/epanet.c +++ b/src/epanet.c @@ -2000,6 +2000,8 @@ int DLLEXPORT ENsetnodevalue(int index, int code, EN_API_FLOAT_TYPE v) || value < Tank[j].Hmin) return(202); Tank[j].H0 = value; Tank[j].V0 = tankvolume(j, Tank[j].H0); + // Resetting Volume in addition to initial volume + Tank[j].V = Tank[j].V0; H[index] = Tank[j].H0; } break; @@ -3285,6 +3287,22 @@ int DLLEXPORT ENgetbasedemand(int nodeIndex, int demandIdx, EN_API_FLOAT_TYPE * } return 0; } + +int DLLEXPORT ENsetbasedemand(int nodeIndex, int demandIdx, EN_API_FLOAT_TYPE baseDemand) +{ + Pdemand d; + int n=1; + /* Check for valid arguments */ + if (!Openflag) return(102); + if (nodeIndex <= 0 || nodeIndex > Nnodes) return(203); + if (nodeIndex <= Njuncs) { + for(d=Node[nodeIndex].D; nnext) n++; + if(n!=demandIdx) return(253); + d->Base = baseDemand/Ucf[FLOW]; + } + return 0; +} + int DLLEXPORT ENgetdemandpattern(int nodeIndex, int demandIdx, int *pattIdx) { Pdemand d; From e16de988cf46e56dd8d4141f45a19357ecd20380 Mon Sep 17 00:00:00 2001 From: sam hatchett Date: Sun, 18 Aug 2013 21:04:56 -0400 Subject: [PATCH 40/49] tank geometry and curve time series --- .gitignore | 0 README.md | 0 build/MSVS/LemonTigerJ.sln | 0 build/MSVS/LemonTigerJ.vcxproj | 0 test/Net3.inp | 0 test/simplenet.inp | 0 6 files changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 .gitignore mode change 100644 => 100755 README.md mode change 100644 => 100755 build/MSVS/LemonTigerJ.sln mode change 100644 => 100755 build/MSVS/LemonTigerJ.vcxproj mode change 100644 => 100755 test/Net3.inp mode change 100644 => 100755 test/simplenet.inp diff --git a/.gitignore b/.gitignore old mode 100644 new mode 100755 diff --git a/README.md b/README.md old mode 100644 new mode 100755 diff --git a/build/MSVS/LemonTigerJ.sln b/build/MSVS/LemonTigerJ.sln old mode 100644 new mode 100755 diff --git a/build/MSVS/LemonTigerJ.vcxproj b/build/MSVS/LemonTigerJ.vcxproj old mode 100644 new mode 100755 diff --git a/test/Net3.inp b/test/Net3.inp old mode 100644 new mode 100755 diff --git a/test/simplenet.inp b/test/simplenet.inp old mode 100644 new mode 100755 From 5b151dd09b9855893c090ccae5c5d71d84356803 Mon Sep 17 00:00:00 2001 From: sam hatchett Date: Fri, 23 Aug 2013 12:35:08 -0400 Subject: [PATCH 41/49] added getter for curve id --- build/Xcode/epanet/epanet.xcodeproj/project.pbxproj | 0 .../project.xcworkspace/contents.xcworkspacedata | 0 include/epanet2.h | 2 +- src/epanet.c | 3 ++- 4 files changed, 3 insertions(+), 2 deletions(-) mode change 100644 => 100755 build/Xcode/epanet/epanet.xcodeproj/project.pbxproj mode change 100644 => 100755 build/Xcode/epanet/epanet.xcodeproj/project.xcworkspace/contents.xcworkspacedata mode change 100644 => 100755 include/epanet2.h diff --git a/build/Xcode/epanet/epanet.xcodeproj/project.pbxproj b/build/Xcode/epanet/epanet.xcodeproj/project.pbxproj old mode 100644 new mode 100755 diff --git a/build/Xcode/epanet/epanet.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/build/Xcode/epanet/epanet.xcodeproj/project.xcworkspace/contents.xcworkspacedata old mode 100644 new mode 100755 diff --git a/include/epanet2.h b/include/epanet2.h old mode 100644 new mode 100755 index c65d493..dfd8be9 --- a/include/epanet2.h +++ b/include/epanet2.h @@ -237,7 +237,7 @@ extern "C" { int DLLEXPORT ENgetlinknodes(int, int *, int *); int DLLEXPORT ENgetlinkvalue(int, int, EN_API_FLOAT_TYPE *); - int DLLEXPORT ENgetcurve(int curveIndex, int *nValues, EN_API_FLOAT_TYPE **xValues, EN_API_FLOAT_TYPE **yValues); + int DLLEXPORT ENgetcurve(int curveIndex, char* id, int *nValues, EN_API_FLOAT_TYPE **xValues, EN_API_FLOAT_TYPE **yValues); int DLLEXPORT ENgetversion(int *); diff --git a/src/epanet.c b/src/epanet.c index e3f4f3d..b7f75e7 100755 --- a/src/epanet.c +++ b/src/epanet.c @@ -1750,7 +1750,7 @@ int DLLEXPORT ENgetlinkvalue(int index, int code, EN_API_FLOAT_TYPE *value) } -int DLLEXPORT ENgetcurve(int curveIndex, int *nValues, EN_API_FLOAT_TYPE **xValues, EN_API_FLOAT_TYPE **yValues) +int DLLEXPORT ENgetcurve(int curveIndex, char* id, int *nValues, EN_API_FLOAT_TYPE **xValues, EN_API_FLOAT_TYPE **yValues) /*---------------------------------------------------------------- ** Input: curveIndex = curve index ** Output: *nValues = number of points on curve @@ -1776,6 +1776,7 @@ int DLLEXPORT ENgetcurve(int curveIndex, int *nValues, EN_API_FLOAT_TYPE **xVal pointY[iPoint] = (EN_API_FLOAT_TYPE)y; } + strncpy(id, curve.ID, MAXID); *nValues = nPoints; *xValues = pointX; *yValues = pointY; From 519daf8e3efa5613c7cdbb360d8f7e55a9e5db82 Mon Sep 17 00:00:00 2001 From: sam hatchett Date: Fri, 27 Sep 2013 22:19:54 -0400 Subject: [PATCH 42/49] adding debuggable conditionals, fixing lemontiger bug MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit … reorientsegs was borked --- .../epanet/epanet.xcodeproj/project.pbxproj | 16 ++-- src/epanet.c | 6 +- src/output.c | 2 +- src/quality.c | 77 +++++++++++-------- src/vars.h | 4 +- 5 files changed, 65 insertions(+), 40 deletions(-) diff --git a/build/Xcode/epanet/epanet.xcodeproj/project.pbxproj b/build/Xcode/epanet/epanet.xcodeproj/project.pbxproj index 25795cc..2f904ac 100755 --- a/build/Xcode/epanet/epanet.xcodeproj/project.pbxproj +++ b/build/Xcode/epanet/epanet.xcodeproj/project.pbxproj @@ -260,7 +260,7 @@ 08FB7793FE84155DC02AAC07 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0460; + LastUpgradeCheck = 0500; }; buildConfigurationList = 1DEB914E08733D8E0010E9CD /* Build configuration list for PBXProject "epanet" */; compatibilityVersion = "Xcode 3.2"; @@ -392,16 +392,20 @@ 1DEB914F08733D8E0010E9CD /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; + CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_OPTIMIZATION_LEVEL = 0; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; HEADER_SEARCH_PATHS = macinclude; ONLY_ACTIVE_ARCH = YES; @@ -412,15 +416,19 @@ 1DEB915008733D8E0010E9CD /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; + CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; HEADER_SEARCH_PATHS = macinclude; SDKROOT = ""; @@ -463,7 +471,6 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; - ARCHS = "$(ARCHS_STANDARD_64_BIT)"; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_WARN_EMPTY_BODY = YES; @@ -484,7 +491,6 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; - ARCHS = "$(ARCHS_STANDARD_64_BIT)"; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_WARN_EMPTY_BODY = YES; diff --git a/src/epanet.c b/src/epanet.c index b7f75e7..19f668e 100755 --- a/src/epanet.c +++ b/src/epanet.c @@ -1968,7 +1968,9 @@ int DLLEXPORT ENsetnodevalue(int index, int code, EN_API_FLOAT_TYPE v) source->Pat = 0; Node[index].S = source; } - if (code == EN_SOURCEQUAL) source->C0 = value; + if (code == EN_SOURCEQUAL) { + source->C0 = value; + } else if (code == EN_SOURCEPAT) { j = ROUND(value); @@ -2757,7 +2759,7 @@ void initpointers() C = NULL; H = NULL; Q = NULL; - R = NULL; + PipeRateCoeff = NULL; S = NULL; K = NULL; OldStat = NULL; diff --git a/src/output.c b/src/output.c index 4237736..9d04531 100755 --- a/src/output.c +++ b/src/output.c @@ -455,7 +455,7 @@ int linkoutput(int j, REAL4 *x, double ucf) break; case REACTRATE: /* Overall reaction rate in mass/L/day */ if (Qualflag == NONE) memset(x,0,(Nlinks+1 )*sizeof(REAL4)); - else for (i=1; i<=Nlinks; i++) x[i] = (REAL4)(R[i]*ucf); + else for (i=1; i<=Nlinks; i++) x[i] = (REAL4)(PipeRateCoeff[i]*ucf); break; case FRICTION: /* f = 2ghd/(Lu^2) where f = friction factor */ /* u = velocity, g = grav. accel., h = head */ diff --git a/src/quality.c b/src/quality.c index d4d3c0f..8a5b8dd 100755 --- a/src/quality.c +++ b/src/quality.c @@ -107,9 +107,9 @@ int openqual() /* Allocate scratch array & reaction rate array*/ XC = (double *) calloc(MAX((Nnodes+1),(Nlinks+1)),sizeof(double)); - R = (double *) calloc((Nlinks+1), sizeof(double)); + PipeRateCoeff = (double *) calloc((Nlinks+1), sizeof(double)); ERRCODE(MEMCHECK(XC)); - ERRCODE(MEMCHECK(R)); + ERRCODE(MEMCHECK(PipeRateCoeff)); /* Allocate memory for WQ solver */ n = Nlinks+Ntanks+1; @@ -414,7 +414,7 @@ int closequal() free(FlowDir); free(VolIn); free(MassIn); - free(R); + free(PipeRateCoeff); free(XC); free(QTankVolumes); free(QLinkFlow); @@ -474,7 +474,8 @@ int gethyd(long *hydtime, long *hydstep) //if (Qtime == 0) // initsegs(); //else - if (Qtime != 0) { + // if hydraulics are open, or if we're in sequential mode (where qtime can increase) + if (OpenHflag || Qtime != 0) { reorientsegs(); } @@ -559,8 +560,10 @@ void initsegs() { /* Establish flow direction */ - FlowDir[k] = '+'; - if (Q[k] < 0.) FlowDir[k] = '-'; + FlowDir[k] = '+'; + if (Q[k] < 0.) { + FlowDir[k] = '-'; + } /* Set segs to zero */ LastSeg[k] = NULL; @@ -626,9 +629,13 @@ void reorientsegs() { /* Find new flow direction */ - newdir = '+'; - if (Q[k] == 0.0) newdir = FlowDir[k]; - else if (Q[k] < 0.0) newdir = '-'; + newdir = '+'; + if (Q[k] == 0.0) { + newdir = FlowDir[k]; + } + else if (Q[k] < 0.0) { + newdir = '-'; + } /* If direction changes, then reverse order of segments */ /* (first to last) and save new direction */ @@ -692,8 +699,8 @@ void updatesegs(long dt) } /* Normalize volume-weighted reaction rate */ - if (vsum > 0.0) R[k] = rsum/vsum/dt*SECperDAY; - else R[k] = 0.0; + if (vsum > 0.0) PipeRateCoeff[k] = rsum/vsum/dt*SECperDAY; + else PipeRateCoeff[k] = 0.0; } } @@ -885,21 +892,27 @@ void updatenodes(long dt) **--------------------------------------------------------------------------- */ { - int i; - - /* Update junction quality */ - for (i=1; i<=Njuncs; i++) - { - if (D[i] < 0.0) VolIn[i] -= D[i]*dt; - if (VolIn[i] > 0.0) C[i] = MassIn[i]/VolIn[i]; - else C[i] = XC[i]; - } - - /* Update tank quality */ - updatetanks(dt); - - /* For flow tracing, set source node concen. to 100. */ - if (Qualflag == TRACE) C[TraceNode] = 100.0; + int i; + + /* Update junction quality */ + for (i=1; i<=Njuncs; i++) + { + if (D[i] < 0.0) { + VolIn[i] -= D[i]*dt; + } + if (VolIn[i] > 0.0) { + C[i] = MassIn[i]/VolIn[i]; + } + else { + C[i] = XC[i]; + } + } + + /* Update tank quality */ + updatetanks(dt); + + /* For flow tracing, set source node concen. to 100. */ + if (Qualflag == TRACE) C[TraceNode] = 100.0; } @@ -972,9 +985,13 @@ void sourceinput(long dt) /* Mass added is difference between source */ /* & node concen. times outflow volume */ case SETPOINT: - if (s > C[n]) massadded = (s-C[n])*volout; - else massadded = 0.0; - break; + if (s > C[n]) { + massadded = (s-C[n])*volout; + } + else { + massadded = 0.0; + } + break; /* Flow-Paced Booster Source: */ /* Mass added = source concen. times outflow volume */ @@ -1557,7 +1574,7 @@ void ratecoeffs() kw = Link[k].Kw; if (kw != 0.0) kw = piperate(k); Link[k].Rc = kw; - R[k] = 0.0; + PipeRateCoeff[k] = 0.0; } } /* End of ratecoeffs */ diff --git a/src/vars.h b/src/vars.h index a2780a0..eee1cda 100755 --- a/src/vars.h +++ b/src/vars.h @@ -151,9 +151,9 @@ AUTHOR: L. Rossman *E, /* Emitter flows */ *K, /* Link settings */ *Q, /* Link flows */ - *R, /* Pipe reaction rate */ + *PipeRateCoeff, /* Pipe reaction rate */ *X, /* General purpose array */ - *XC; /* General purpose array */ + *XC; /* General purpose array for water quality */ EXTERN double *H; /* Node heads */ EXTERN double *QTankVolumes; EXTERN double *QLinkFlow; From d1d03bf4461b1203f89c3f28f5e6e603f650072b Mon Sep 17 00:00:00 2001 From: Sam Hatchett Date: Mon, 30 Sep 2013 15:09:36 -0400 Subject: [PATCH 43/49] header file declarations illuminated for better IDE code completion --- include/epanet2.h | 115 +++++++++++++++++++++++----------------------- 1 file changed, 57 insertions(+), 58 deletions(-) diff --git a/include/epanet2.h b/include/epanet2.h index dfd8be9..b216597 100755 --- a/include/epanet2.h +++ b/include/epanet2.h @@ -177,80 +177,79 @@ #if defined(__cplusplus) extern "C" { #endif - int DLLEXPORT ENepanet(char *, char *, char *, void (*) (char *)); + int DLLEXPORT ENepanet(char *inpFile, char *rptFile, char *binOutFile, void (*callback) (char *)); - int DLLEXPORT ENopen(char *, char *, char *); - int DLLEXPORT ENsaveinpfile(char *); - int DLLEXPORT ENclose(void); + int DLLEXPORT ENopen(char *inpFile, char *rptFile, char *binOutFile); + int DLLEXPORT ENsaveinpfile(char *filename); + int DLLEXPORT ENclose(); - int DLLEXPORT ENsolveH(void); - int DLLEXPORT ENsaveH(void); - int DLLEXPORT ENopenH(void); - int DLLEXPORT ENinitH(int); - int DLLEXPORT ENrunH(long *); - int DLLEXPORT ENnextH(long *tstep); - int DLLEXPORT ENcloseH(void); - int DLLEXPORT ENsavehydfile(char *); - int DLLEXPORT ENusehydfile(char *); + int DLLEXPORT ENsolveH(); + int DLLEXPORT ENsaveH(); + int DLLEXPORT ENopenH(); + int DLLEXPORT ENinitH(int initFlag); + int DLLEXPORT ENrunH(long *currentTime); + int DLLEXPORT ENnextH(long *tStep); + int DLLEXPORT ENcloseH(); + int DLLEXPORT ENsavehydfile(char *filename); + int DLLEXPORT ENusehydfile(char *filename); - int DLLEXPORT ENsolveQ(void); - int DLLEXPORT ENopenQ(void); - int DLLEXPORT ENinitQ(int); - int DLLEXPORT ENrunQ(long *); - int DLLEXPORT ENnextQ(long *); - int DLLEXPORT ENstepQ(long *); - int DLLEXPORT ENcloseQ(void); + int DLLEXPORT ENsolveQ(); + int DLLEXPORT ENopenQ(); + int DLLEXPORT ENinitQ(int saveFlag); + int DLLEXPORT ENrunQ(long *currentTime); + int DLLEXPORT ENnextQ(long *tStep); + int DLLEXPORT ENstepQ(long *timeLeft); + int DLLEXPORT ENcloseQ(); - int DLLEXPORT ENwriteline(char *); - int DLLEXPORT ENreport(void); - int DLLEXPORT ENresetreport(void); - int DLLEXPORT ENsetreport(char *); + int DLLEXPORT ENwriteline(char *line); + int DLLEXPORT ENreport(); + int DLLEXPORT ENresetreport(); + int DLLEXPORT ENsetreport(char *reportFormat); - int DLLEXPORT ENgetcontrol(int, int *, int *, EN_API_FLOAT_TYPE *, - int *, EN_API_FLOAT_TYPE *); - int DLLEXPORT ENgetcount(int, int *); - int DLLEXPORT ENgetoption(int, EN_API_FLOAT_TYPE *); - int DLLEXPORT ENgettimeparam(int, long *); - int DLLEXPORT ENgetflowunits(int *); - int DLLEXPORT ENgetpatternindex(char *, int *); - int DLLEXPORT ENgetpatternid(int, char *); - int DLLEXPORT ENgetpatternlen(int, int *); - int DLLEXPORT ENgetpatternvalue(int, int, EN_API_FLOAT_TYPE *); + int DLLEXPORT ENgetcontrol(int controlIndex, int *controlType, int *linkIdx, EN_API_FLOAT_TYPE *setting, int *nodeIdx, EN_API_FLOAT_TYPE *level); + int DLLEXPORT ENgetcount(int code, int *count); + int DLLEXPORT ENgetoption(int code, EN_API_FLOAT_TYPE *value); + int DLLEXPORT ENgettimeparam(int code, long *value); + int DLLEXPORT ENgetflowunits(int *code); + int DLLEXPORT ENgetpatternindex(char *id, int *index); + int DLLEXPORT ENgetpatternid(int index, char *id); + int DLLEXPORT ENgetpatternlen(int index, int *len); + int DLLEXPORT ENgetpatternvalue(int index, int period, EN_API_FLOAT_TYPE *value); int DLLEXPORT ENgetaveragepatternvalue(int index, EN_API_FLOAT_TYPE *value); - int DLLEXPORT ENgetqualtype(int *, int *); - int DLLEXPORT ENgeterror(int, char *, int); + int DLLEXPORT ENgetqualtype(int *qualcode, int *tracenode); + int DLLEXPORT ENgeterror(int errcode, char *errmsg, int maxLen); int DLLEXPORT ENgetstatistic(int code, EN_API_FLOAT_TYPE* value); - int DLLEXPORT ENgetnodeindex(char *, int *); - int DLLEXPORT ENgetnodeid(int, char *); - int DLLEXPORT ENgetnodetype(int, int *); - int DLLEXPORT ENgetnodevalue(int, int, EN_API_FLOAT_TYPE *); - int DLLEXPORT ENgetcoord(int , EN_API_FLOAT_TYPE *, EN_API_FLOAT_TYPE *); + int DLLEXPORT ENgetnodeindex(char *id, int *index); + int DLLEXPORT ENgetnodeid(int index, char *id); + int DLLEXPORT ENgetnodetype(int index, int *code); + int DLLEXPORT ENgetnodevalue(int index, int code, EN_API_FLOAT_TYPE *value); + int DLLEXPORT ENgetcoord(int index, EN_API_FLOAT_TYPE *x, EN_API_FLOAT_TYPE *y); - int DLLEXPORT ENgetnumdemands(int, int *); - int DLLEXPORT ENgetbasedemand(int, int, EN_API_FLOAT_TYPE *); - int DLLEXPORT ENgetdemandpattern(int, int, int *); + int DLLEXPORT ENgetnumdemands(int nodeIndex, int *numDemands); + int DLLEXPORT ENgetbasedemand(int nodeIndex, int demandIdx, EN_API_FLOAT_TYPE *baseDemand); + int DLLEXPORT ENgetdemandpattern(int nodeIndex, int demandIdx, int *pattIdx); - int DLLEXPORT ENgetlinkindex(char *, int *); - int DLLEXPORT ENgetlinkid(int, char *); - int DLLEXPORT ENgetlinktype(int, int *); - int DLLEXPORT ENgetlinknodes(int, int *, int *); - int DLLEXPORT ENgetlinkvalue(int, int, EN_API_FLOAT_TYPE *); + int DLLEXPORT ENgetlinkindex(char *id, int *index); + int DLLEXPORT ENgetlinkid(int index, char *id); + int DLLEXPORT ENgetlinktype(int index, int *code); + int DLLEXPORT ENgetlinknodes(int index, int *node1, int *node2); + int DLLEXPORT ENgetlinkvalue(int index, int code, EN_API_FLOAT_TYPE *value); int DLLEXPORT ENgetcurve(int curveIndex, char* id, int *nValues, EN_API_FLOAT_TYPE **xValues, EN_API_FLOAT_TYPE **yValues); - int DLLEXPORT ENgetversion(int *); + int DLLEXPORT ENgetversion(int *version); - int DLLEXPORT ENsetcontrol(int, int, int, EN_API_FLOAT_TYPE, int, EN_API_FLOAT_TYPE); - int DLLEXPORT ENsetnodevalue(int, int, EN_API_FLOAT_TYPE); - int DLLEXPORT ENsetlinkvalue(int, int, EN_API_FLOAT_TYPE); - int DLLEXPORT ENaddpattern(char *); - int DLLEXPORT ENsetpattern(int, EN_API_FLOAT_TYPE *, int); - int DLLEXPORT ENsetpatternvalue(int, int, EN_API_FLOAT_TYPE); - int DLLEXPORT ENsettimeparam(int, long); + int DLLEXPORT ENsetcontrol(int cindex, int ctype, int lindex, EN_API_FLOAT_TYPE setting, int nindex, EN_API_FLOAT_TYPE level); + int DLLEXPORT ENsetnodevalue(int index, int code, EN_API_FLOAT_TYPE v); + int DLLEXPORT ENsetlinkvalue(int index, int code, EN_API_FLOAT_TYPE v); + int DLLEXPORT ENaddpattern(char *id); + int DLLEXPORT ENsetpattern(int index, EN_API_FLOAT_TYPE *f, int len); + int DLLEXPORT ENsetpatternvalue(int index, int period, EN_API_FLOAT_TYPE value); + int DLLEXPORT ENsettimeparam(int code, long value); int DLLEXPORT ENsetoption(int, EN_API_FLOAT_TYPE); - int DLLEXPORT ENsetstatusreport(int); + int DLLEXPORT ENsetstatusreport(int code); int DLLEXPORT ENsetqualtype(int qualcode, char *chemname, char *chemunits, char *tracenode); int DLLEXPORT ENsetbasedemand(int nodeIndex, int demandIdx, EN_API_FLOAT_TYPE baseDemand); From 10a5ae4cf622fdd103a923574b49dec291f9b13c Mon Sep 17 00:00:00 2001 From: Sam Hatchett Date: Mon, 30 Sep 2013 16:28:12 -0400 Subject: [PATCH 44/49] updated some variable names to make the code a bit more self-documenting --- include/epanet2.h | 6 +- src/epanet.c | 81 ++++++++-------- src/hydraul.c | 232 ++++++++++++++++++++++++---------------------- src/input3.c | 8 +- src/output.c | 53 +++++------ src/quality.c | 96 +++++++++---------- src/report.c | 36 +++---- src/rules.c | 32 +++---- src/vars.h | 14 +-- 9 files changed, 286 insertions(+), 272 deletions(-) diff --git a/include/epanet2.h b/include/epanet2.h index b216597..0543a15 100755 --- a/include/epanet2.h +++ b/include/epanet2.h @@ -9,8 +9,8 @@ 3/1/01 8/15/07 (2.00.11) 2/14/08 (2.00.12) - AUTHOR: L. Rossman - US EPA - NRMRL + AUTHORS: L. Rossman - US EPA - NRMRL + OpenWaterAnalytics members: see git stats for contributors ******************************************************************* */ @@ -248,7 +248,7 @@ extern "C" { int DLLEXPORT ENsetpattern(int index, EN_API_FLOAT_TYPE *f, int len); int DLLEXPORT ENsetpatternvalue(int index, int period, EN_API_FLOAT_TYPE value); int DLLEXPORT ENsettimeparam(int code, long value); - int DLLEXPORT ENsetoption(int, EN_API_FLOAT_TYPE); + int DLLEXPORT ENsetoption(int code, EN_API_FLOAT_TYPE v); int DLLEXPORT ENsetstatusreport(int code); int DLLEXPORT ENsetqualtype(int qualcode, char *chemname, char *chemunits, char *tracenode); int DLLEXPORT ENsetbasedemand(int nodeIndex, int demandIdx, EN_API_FLOAT_TYPE baseDemand); diff --git a/src/epanet.c b/src/epanet.c index 19f668e..2c4aa09 100755 --- a/src/epanet.c +++ b/src/epanet.c @@ -1443,19 +1443,19 @@ int DLLEXPORT ENgetnodevalue(int index, int code, EN_API_FLOAT_TYPE *value) break; //(2.00.11 - LR) case EN_DEMAND: - v = D[index]*Ucf[FLOW]; + v = NodeDemand[index]*Ucf[FLOW]; break; case EN_HEAD: - v = H[index]*Ucf[HEAD]; + v = NodeHead[index]*Ucf[HEAD]; break; case EN_PRESSURE: - v = (H[index] - Node[index].El)*Ucf[PRESSURE]; + v = (NodeHead[index] - Node[index].El)*Ucf[PRESSURE]; break; case EN_QUALITY: - v = C[index]*Ucf[QUALITY]; + v = NodeQual[index]*Ucf[QUALITY]; break; /*** New parameters added for retrieval begins here ***/ //(2.00.12 - LR) @@ -1518,7 +1518,7 @@ int DLLEXPORT ENgetnodevalue(int index, int code, EN_API_FLOAT_TYPE *value) case EN_TANKVOLUME: if (index <= Njuncs) return(251); - v = tankvolume(index-Njuncs, H[index])*Ucf[VOLUME]; + v = tankvolume(index-Njuncs, NodeHead[index])*Ucf[VOLUME]; break; default: return(251); @@ -1685,7 +1685,7 @@ int DLLEXPORT ENgetlinkvalue(int index, int code, EN_API_FLOAT_TYPE *value) case EN_FLOW: /*** Updated 10/25/00 ***/ - if (S[index] <= CLOSED) v = 0.0; + if (LinkStatus[index] <= CLOSED) v = 0.0; else v = Q[index]*Ucf[FLOW]; break; @@ -1693,7 +1693,7 @@ int DLLEXPORT ENgetlinkvalue(int index, int code, EN_API_FLOAT_TYPE *value) if (Link[index].Type == PUMP) v = 0.0; /*** Updated 11/19/01 ***/ - else if (S[index] <= CLOSED) v = 0.0; + else if (LinkStatus[index] <= CLOSED) v = 0.0; else { @@ -1706,26 +1706,31 @@ int DLLEXPORT ENgetlinkvalue(int index, int code, EN_API_FLOAT_TYPE *value) case EN_HEADLOSS: /*** Updated 11/19/01 ***/ - if (S[index] <= CLOSED) v = 0.0; + if (LinkStatus[index] <= CLOSED) v = 0.0; else { - h = H[Link[index].N1] - H[Link[index].N2]; + h = NodeHead[Link[index].N1] - NodeHead[Link[index].N2]; if (Link[index].Type != PUMP) h = ABS(h); v = h*Ucf[HEADLOSS]; } break; case EN_STATUS: - if (S[index] <= CLOSED) v = 0.0; + if (LinkStatus[index] <= CLOSED) v = 0.0; else v = 1.0; break; case EN_SETTING: - if (Link[index].Type == PIPE || Link[index].Type == CV) + if (Link[index].Type == PIPE || Link[index].Type == CV) { return(ENgetlinkvalue(index, EN_ROUGHNESS, value)); - if (K[index] == MISSING) v = 0.0; - else v = K[index]; + } + if (LinkSetting[index] == MISSING) { + v = 0.0; + } + else { + v = LinkSetting[index]; + } switch (Link[index].Type) { case PRV: @@ -1911,7 +1916,7 @@ int DLLEXPORT ENsetnodevalue(int index, int code, EN_API_FLOAT_TYPE v) Tank[j].Hmin += value; Tank[j].Hmax += value; Node[index].El += value; - H[index] += value; + NodeHead[index] += value; } break; @@ -1994,7 +1999,7 @@ int DLLEXPORT ENsetnodevalue(int index, int code, EN_API_FLOAT_TYPE v) Tank[j].Hmin = Tank[j].H0; Tank[j].Hmax = Tank[j].H0; Node[index].El = Tank[j].H0; - H[index] = Tank[j].H0; + NodeHead[index] = Tank[j].H0; } else { @@ -2005,7 +2010,7 @@ int DLLEXPORT ENsetnodevalue(int index, int code, EN_API_FLOAT_TYPE v) Tank[j].V0 = tankvolume(j, Tank[j].H0); // Resetting Volume in addition to initial volume Tank[j].V = Tank[j].V0; - H[index] = Tank[j].H0; + NodeHead[index] = Tank[j].H0; } break; @@ -2160,7 +2165,7 @@ int DLLEXPORT ENsetlinkvalue(int index, int code, EN_API_FLOAT_TYPE v) if (code == EN_INITSTATUS) setlinkstatus(index, s, &Link[index].Stat, &Link[index].Kc); else - setlinkstatus(index, s, &S[index], &K[index]); + setlinkstatus(index, s, &LinkStatus[index], &LinkSetting[index]); break; case EN_INITSETTING: @@ -2187,7 +2192,7 @@ int DLLEXPORT ENsetlinkvalue(int index, int code, EN_API_FLOAT_TYPE v) if (code == EN_INITSETTING) setlinksetting(index, value, &Link[index].Stat, &Link[index].Kc); else - setlinksetting(index, value, &S[index], &K[index]); + setlinksetting(index, value, &LinkStatus[index], &LinkSetting[index]); } break; @@ -2755,13 +2760,13 @@ void initpointers() **---------------------------------------------------------------- */ { - D = NULL; - C = NULL; - H = NULL; + NodeDemand = NULL; + NodeQual = NULL; + NodeHead = NULL; Q = NULL; PipeRateCoeff = NULL; - S = NULL; - K = NULL; + LinkStatus = NULL; + LinkSetting = NULL; OldStat = NULL; Node = NULL; @@ -2824,13 +2829,13 @@ int allocdata() { n = MaxNodes + 1; Node = (Snode *) calloc(n, sizeof(Snode)); - D = (double *) calloc(n, sizeof(double)); - C = (double *) calloc(n, sizeof(double)); - H = (double *) calloc(n, sizeof(double)); + NodeDemand = (double *) calloc(n, sizeof(double)); + NodeQual = (double *) calloc(n, sizeof(double)); + NodeHead = (double *) calloc(n, sizeof(double)); ERRCODE(MEMCHECK(Node)); - ERRCODE(MEMCHECK(D)); - ERRCODE(MEMCHECK(C)); - ERRCODE(MEMCHECK(H)); + ERRCODE(MEMCHECK(NodeDemand)); + ERRCODE(MEMCHECK(NodeQual)); + ERRCODE(MEMCHECK(NodeHead)); } /* Allocate memory for network links */ @@ -2839,12 +2844,12 @@ int allocdata() n = MaxLinks + 1; Link = (Slink *) calloc(n, sizeof(Slink)); Q = (double *) calloc(n, sizeof(double)); - K = (double *) calloc(n, sizeof(double)); - S = (char *) calloc(n, sizeof(char)); + LinkSetting = (double *) calloc(n, sizeof(double)); + LinkStatus = (char *) calloc(n, sizeof(char)); ERRCODE(MEMCHECK(Link)); ERRCODE(MEMCHECK(Q)); - ERRCODE(MEMCHECK(K)); - ERRCODE(MEMCHECK(S)); + ERRCODE(MEMCHECK(LinkSetting)); + ERRCODE(MEMCHECK(LinkStatus)); } /* Allocate memory for tanks, sources, pumps, valves, */ @@ -2955,12 +2960,12 @@ void freedata() Psource source; /* Free memory for computed results */ - free(D); - free(C); - free(H); + free(NodeDemand); + free(NodeQual); + free(NodeHead); free(Q); - free(K); - free(S); + free(LinkSetting); + free(LinkStatus); /* Free memory for node data */ if (Node != NULL) diff --git a/src/hydraul.c b/src/hydraul.c index 8ee6ff8..e9bcbb7 100755 --- a/src/hydraul.c +++ b/src/hydraul.c @@ -123,10 +123,10 @@ void inithyd(int initflag) for (i=1; i<=Ntanks; i++) { Tank[i].V = Tank[i].V0; - H[Tank[i].Node] = Tank[i].H0; + NodeHead[Tank[i].Node] = Tank[i].H0; /*** Updated 10/25/00 ***/ - D[Tank[i].Node] = 0.0; + NodeDemand[Tank[i].Node] = 0.0; OldStat[Nlinks+i] = TEMPCLOSED; } @@ -140,24 +140,24 @@ void inithyd(int initflag) for (i=1; i<=Nlinks; i++) { /* Initialize status and setting */ - S[i] = Link[i].Stat; - K[i] = Link[i].Kc; + LinkStatus[i] = Link[i].Stat; + LinkSetting[i] = Link[i].Kc; /* Start active control valves in ACTIVE position */ //(2.00.11 - LR) if ( (Link[i].Type == PRV || Link[i].Type == PSV || Link[i].Type == FCV) //(2.00.11 - LR) && (Link[i].Kc != MISSING) - ) S[i] = ACTIVE; //(2.00.11 - LR) + ) LinkStatus[i] = ACTIVE; //(2.00.11 - LR) /*** Updated 3/1/01 ***/ /* Initialize flows if necessary */ - if (S[i] <= CLOSED) Q[i] = QZERO; + if (LinkStatus[i] <= CLOSED) Q[i] = QZERO; else if (ABS(Q[i]) <= QZERO || initflag > 0) - initlinkflow(i, S[i], K[i]); + initlinkflow(i, LinkStatus[i], LinkSetting[i]); /* Save initial status */ - OldStat[i] = S[i]; + OldStat[i] = LinkStatus[i]; } /* Reset pump energy usage */ @@ -375,7 +375,7 @@ void setlinkflow(int k, double dh) /* use approx. inverse of formula. */ if (Formflag == DW) { - x = -log(K[k]/3.7/Link[k].Diam); + x = -log(LinkSetting[k]/3.7/Link[k].Diam); y = sqrt(ABS(dh)/Link[k].R/1.32547); Q[k] = x*y; } @@ -402,17 +402,17 @@ void setlinkflow(int k, double dh) /* For custom pump curve, interpolate from curve */ if (Pump[p].Ptype == CUSTOM) { - dh = -dh*Ucf[HEAD]/SQR(K[k]); + dh = -dh*Ucf[HEAD]/SQR(LinkSetting[k]); i = Pump[p].Hcurve; Q[k] = interp(Curve[i].Npts,Curve[i].Y,Curve[i].X, - dh)*K[k]/Ucf[FLOW]; + dh)*LinkSetting[k]/Ucf[FLOW]; } /* Otherwise use inverse of power curve */ else { - h0 = -SQR(K[k])*Pump[p].H0; - x = pow(K[k],2.0-Pump[p].N); + h0 = -SQR(LinkSetting[k])*Pump[p].H0; + x = pow(LinkSetting[k],2.0-Pump[p].N); x = ABS(h0-dh)/(Pump[p].R*x), y = 1.0/Pump[p].N; Q[k] = pow(x,y); @@ -606,7 +606,7 @@ void demands() if (djunc > 0.0) Dsystem += djunc; sum += djunc; } - D[i] = sum; + NodeDemand[i] = sum; } /* Update head at fixed grade nodes with time patterns. */ @@ -619,7 +619,7 @@ void demands() { k = p % (long) Pattern[j].Length; i = Tank[n].Node; - H[i] = Node[i].El*Pattern[j].F[k]; + NodeHead[i] = Node[i].El*Pattern[j].F[k]; } } } @@ -632,7 +632,7 @@ void demands() { i = Pump[n].Link; k = p % (long) Pattern[j].Length; - setlinksetting(i, Pattern[j].F[k], &S[i], &K[i]); + setlinksetting(i, Pattern[j].F[k], &LinkStatus[i], &LinkSetting[i]); } } } /* End of demands */ @@ -664,8 +664,8 @@ int controls() /* Link is controlled by tank level */ if ((n = Control[i].Node) > 0 && n > Njuncs) { - h = H[n]; - vplus = ABS(D[n]); + h = NodeHead[n]; + vplus = ABS(NodeDemand[n]); v1 = tankvolume(n-Njuncs,h); v2 = tankvolume(n-Njuncs,Control[i].Grade); if (Control[i].Type == LOWLEVEL && v1 <= v2 + vplus) @@ -689,16 +689,16 @@ int controls() /* Update link status & pump speed or valve setting */ if (reset == 1) { - if (S[k] <= CLOSED) s1 = CLOSED; + if (LinkStatus[k] <= CLOSED) s1 = CLOSED; else s1 = OPEN; s2 = Control[i].Status; - k1 = K[k]; + k1 = LinkSetting[k]; k2 = k1; if (Link[k].Type > PIPE) k2 = Control[i].Setting; if (s1 != s2 || k1 != k2) { - S[k] = s2; - K[k] = k2; + LinkStatus[k] = s2; + LinkSetting[k] = k2; if (Statflag) writecontrolaction(k,i); // if (s1 != s2) initlinkflow(k, S[k], K[k]); setsum++; @@ -764,8 +764,8 @@ void tanktimestep(long *tstep) { if (Tank[i].A == 0.0) continue; /* Skip reservoirs */ n = Tank[i].Node; - h = H[n]; /* Current tank grade */ - q = D[n]; /* Flow into tank */ + h = NodeHead[n]; /* Current tank grade */ + q = NodeDemand[n]; /* Flow into tank */ if (ABS(q) <= QZERO) continue; if (q > 0.0 && h < Tank[i].Hmax) { @@ -802,8 +802,8 @@ void controltimestep(long *tstep) if ( (n = Control[i].Node) > 0) /* Node control: */ { if ((j = n-Njuncs) <= 0) continue; /* Node is a tank */ - h = H[n]; /* Current tank grade */ - q = D[n]; /* Flow into tank */ + h = NodeHead[n]; /* Current tank grade */ + q = NodeDemand[n]; /* Flow into tank */ if (ABS(q) <= QZERO) continue; if ( (h < Control[i].Grade && @@ -838,8 +838,8 @@ void controltimestep(long *tstep) /* Check if rule actually changes link status or setting */ k = Control[i].Link; if ( - (Link[k].Type > PIPE && K[k] != Control[i].Setting) || - (S[k] != Control[i].Status) + (Link[k].Type > PIPE && LinkSetting[k] != Control[i].Setting) || + (LinkStatus[k] != Control[i].Status) ) *tstep = t; } @@ -954,7 +954,7 @@ void addenergy(long hstep) { /* Skip closed pumps */ k = Pump[j].Link; - if (S[k] <= CLOSED) continue; + if (LinkStatus[k] <= CLOSED) continue; q = MAX(QZERO, ABS(Q[k])); /* Find pump-specific energy cost */ @@ -1001,7 +1001,7 @@ void getenergy(int k, double *kw, double *eff) /*** Updated 6/24/02 ***/ /* No energy if link is closed */ - if (S[k] <= CLOSED) + if (LinkStatus[k] <= CLOSED) { *kw = 0.0; *eff = 0.0; @@ -1011,7 +1011,7 @@ void getenergy(int k, double *kw, double *eff) /* Determine flow and head difference */ q = ABS(Q[k]); - dh = ABS(H[Link[k].N1] - H[Link[k].N2]); + dh = ABS(NodeHead[Link[k].N1] - NodeHead[Link[k].N2]); /* For pumps, find effic. at current flow */ if (Link[k].Type == PUMP) @@ -1053,18 +1053,18 @@ void tanklevels(long tstep) /* Update the tank's volume & water elevation */ n = Tank[i].Node; - dv = D[n]*tstep; + dv = NodeDemand[n]*tstep; Tank[i].V += dv; /*** Updated 6/24/02 ***/ /* Check if tank full/empty within next second */ - if (Tank[i].V + D[n] >= Tank[i].Vmax) { + if (Tank[i].V + NodeDemand[n] >= Tank[i].Vmax) { Tank[i].V = Tank[i].Vmax; } - else if (Tank[i].V - D[n] <= Tank[i].Vmin) { + else if (Tank[i].V - NodeDemand[n] <= Tank[i].Vmin) { Tank[i].V = Tank[i].Vmin; } - H[n] = tankgrade(i,Tank[i].V); + NodeHead[n] = tankgrade(i,Tank[i].V); } } /* End of tanklevels */ @@ -1188,7 +1188,7 @@ int netsolve(int *iter, double *relerr) /* Update current solution. */ /* (Row[i] = row of solution matrix corresponding to node i). */ - for (i=1; i<=Njuncs; i++) H[i] = F[Row[i]]; /* Update heads */ + for (i=1; i<=Njuncs; i++) NodeHead[i] = F[Row[i]]; /* Update heads */ newerr = newflows(); /* Update flows */ *relerr = newerr; @@ -1244,7 +1244,7 @@ int netsolve(int *iter, double *relerr) } /* Add any emitter flows to junction demands */ - for (i=1; i<=Njuncs; i++) D[i] += E[i]; + for (i=1; i<=Njuncs; i++) NodeDemand[i] += E[i]; return(errcode); } /* End of netsolve */ @@ -1274,15 +1274,15 @@ int badvalve(int n) Link[k].Type == PSV || Link[k].Type == FCV) { - if (S[k] == ACTIVE) + if (LinkStatus[k] == ACTIVE) { if (Statflag == FULL) { sprintf(Msg,FMT61,clocktime(Atime,Htime),Link[k].ID); writeline(Msg); } - if (Link[k].Type == FCV) S[k] = XFCV; - else S[k] = XPRESSURE; + if (Link[k].Type == FCV) LinkStatus[k] = XFCV; + else LinkStatus[k] = XPRESSURE; return(1); } } @@ -1313,25 +1313,25 @@ int valvestatus() for (i=1; i<=Nvalves; i++) /* Examine each valve */ { k = Valve[i].Link; /* Link index of valve */ - if (K[k] == MISSING) continue; /* Valve status fixed */ + if (LinkSetting[k] == MISSING) continue; /* Valve status fixed */ n1 = Link[k].N1; /* Start & end nodes */ n2 = Link[k].N2; - s = S[k]; /* Save current status */ + s = LinkStatus[k]; /* Save current status */ // if (s != CLOSED /* No change if flow is */ //(2.00.11 - LR) // && ABS(Q[k]) < Qtol) continue; /* negligible. */ //(2.00.11 - LR) switch (Link[k].Type) /* Evaluate new status: */ { - case PRV: hset = Node[n2].El + K[k]; - S[k] = prvstatus(k,s,hset,H[n1],H[n2]); + case PRV: hset = Node[n2].El + LinkSetting[k]; + LinkStatus[k] = prvstatus(k,s,hset,NodeHead[n1],NodeHead[n2]); break; - case PSV: hset = Node[n1].El + K[k]; - S[k] = psvstatus(k,s,hset,H[n1],H[n2]); + case PSV: hset = Node[n1].El + LinkSetting[k]; + LinkStatus[k] = psvstatus(k,s,hset,NodeHead[n1],NodeHead[n2]); break; //// FCV status checks moved back into the linkstatus() function //// //(2.00.12 - LR) -// case FCV: S[k] = fcvstatus(k,s,H[n1],H[n2]); //(2.00.12 - LR) +// case FCV: S[k] = fcvstatus(k,s,NodeHead[n1],NodeHead[n2]); //(2.00.12 - LR) // break; //(2.00.12 - LR) default: continue; @@ -1342,9 +1342,9 @@ int valvestatus() /* This strategy improves convergence. */ /* Check for status change */ - if (s != S[k]) + if (s != LinkStatus[k]) { - if (Statflag == FULL) writestatchange(k,s,S[k]); + if (Statflag == FULL) writestatchange(k,s,LinkStatus[k]); change = TRUE; } } @@ -1375,29 +1375,29 @@ int linkstatus() { n1 = Link[k].N1; n2 = Link[k].N2; - dh = H[n1] - H[n2]; + dh = NodeHead[n1] - NodeHead[n2]; /* Re-open temporarily closed links (status = XHEAD or TEMPCLOSED) */ - status = S[k]; - if (status == XHEAD || status == TEMPCLOSED) S[k] = OPEN; + status = LinkStatus[k]; + if (status == XHEAD || status == TEMPCLOSED) LinkStatus[k] = OPEN; /* Check for status changes in CVs and pumps */ - if (Link[k].Type == CV) S[k] = cvstatus(S[k],dh,Q[k]); - if (Link[k].Type == PUMP && S[k] >= OPEN && K[k] > 0.0) //(2.00.11 - LR) - S[k] = pumpstatus(k,-dh); + if (Link[k].Type == CV) LinkStatus[k] = cvstatus(LinkStatus[k],dh,Q[k]); + if (Link[k].Type == PUMP && LinkStatus[k] >= OPEN && LinkSetting[k] > 0.0) //(2.00.11 - LR) + LinkStatus[k] = pumpstatus(k,-dh); /* Check for status changes in non-fixed FCVs */ - if (Link[k].Type == FCV && K[k] != MISSING) //(2.00.12 - LR)// - S[k] = fcvstatus(k,status,H[n1],H[n2]); //(2.00.12 - LR)// + if (Link[k].Type == FCV && LinkSetting[k] != MISSING) //(2.00.12 - LR)// + LinkStatus[k] = fcvstatus(k,status,NodeHead[n1],NodeHead[n2]); //(2.00.12 - LR)// /* Check for flow into (out of) full (empty) tanks */ if (n1 > Njuncs || n2 > Njuncs) tankstatus(k,n1,n2); /* Note change in link status; do not revise link flow */ //(2.00.11 - LR) - if (status != S[k]) + if (status != LinkStatus[k]) { change = TRUE; - if (Statflag == FULL) writestatchange(k,status,S[k]); + if (Statflag == FULL) writestatchange(k,status,LinkStatus[k]); //if (S[k] <= CLOSED) Q[k] = QZERO; //(2.00.11 - LR) //else setlinkflow(k, dh); //(2.00.11 - LR) @@ -1449,7 +1449,7 @@ char pumpstatus(int k, double dh) /* Prevent reverse flow through pump */ p = PUMPINDEX(k); if (Pump[p].Ptype == CONST_HP) hmax = BIG; - else hmax = SQR(K[k])*Pump[p].Hmax; + else hmax = SQR(LinkSetting[k])*Pump[p].Hmax; if (dh > hmax + Htol) return(XHEAD); /*** Flow higher than pump curve no longer results in a status change ***/ //(2.00.11 - LR) @@ -1477,7 +1477,7 @@ char prvstatus(int k, char s, double hset, double h1, double h2) double htol = Htol; status = s; - if (K[k] == MISSING) return(status); /* Status fixed by user */ + if (LinkSetting[k] == MISSING) return(status); /* Status fixed by user */ hml = Link[k].Km*SQR(Q[k]); /* Head loss when open */ /*** Status rules below have changed. ***/ //(2.00.11 - LR) @@ -1527,7 +1527,7 @@ char psvstatus(int k, char s, double hset, double h1, double h2) double htol = Htol; status = s; - if (K[k] == MISSING) return(status); /* Status fixed by user */ + if (LinkSetting[k] == MISSING) return(status); /* Status fixed by user */ hml = Link[k].Km*SQR(Q[k]); /* Head loss when open */ /*** Status rules below have changed. ***/ //(2.00.11 - LR) @@ -1580,9 +1580,15 @@ char fcvstatus(int k, char s, double h1, double h2) { char status; /* New valve status */ status = s; - if (h1 - h2 < -Htol) status = XFCV; - else if ( Q[k] < -Qtol ) status = XFCV; //(2.00.11 - LR) - else if (s == XFCV && Q[k] >= K[k]) status = ACTIVE; + if (h1 - h2 < -Htol) { + status = XFCV; + } + else if ( Q[k] < -Qtol ) { + status = XFCV; //(2.00.11 - LR) + } + else if (s == XFCV && Q[k] >= LinkSetting[k]) { + status = ACTIVE; + } return(status); } @@ -1615,39 +1621,39 @@ void tankstatus(int k, int n1, int n2) n2 = n; q = -q; } - h = H[n1] - H[n2]; + h = NodeHead[n1] - NodeHead[n2]; /* Skip reservoirs & closed links */ - if (Tank[i].A == 0.0 || S[k] <= CLOSED) return; + if (Tank[i].A == 0.0 || LinkStatus[k] <= CLOSED) return; /* If tank full, then prevent flow into it */ - if (H[n1] >= Tank[i].Hmax - Htol) + if (NodeHead[n1] >= Tank[i].Hmax - Htol) { /* Case 1: Link is a pump discharging into tank */ if ( Link[k].Type == PUMP ) { - if (Link[k].N2 == n1) S[k] = TEMPCLOSED; + if (Link[k].N2 == n1) LinkStatus[k] = TEMPCLOSED; } /* Case 2: Downstream head > tank head */ /* (i.e., an open outflow check valve would close) */ - else if (cvstatus(OPEN, h, q) == CLOSED) S[k] = TEMPCLOSED; + else if (cvstatus(OPEN, h, q) == CLOSED) LinkStatus[k] = TEMPCLOSED; } /* If tank empty, then prevent flow out of it */ - if (H[n1] <= Tank[i].Hmin + Htol) + if (NodeHead[n1] <= Tank[i].Hmin + Htol) { /* Case 1: Link is a pump discharging from tank */ if ( Link[k].Type == PUMP) { - if (Link[k].N1 == n1) S[k] = TEMPCLOSED; + if (Link[k].N1 == n1) LinkStatus[k] = TEMPCLOSED; } /* Case 2: Tank head > downstream head */ /* (i.e., a closed outflow check valve would open) */ - else if (cvstatus(CLOSED, h, q) == OPEN) S[k] = TEMPCLOSED; + else if (cvstatus(CLOSED, h, q) == OPEN) LinkStatus[k] = TEMPCLOSED; } } /* End of tankstatus */ @@ -1681,10 +1687,10 @@ int pswitch() { /* Determine if control conditions are satisfied */ if (Control[i].Type == LOWLEVEL - && H[n] <= Control[i].Grade + Htol ) + && NodeHead[n] <= Control[i].Grade + Htol ) reset = 1; if (Control[i].Type == HILEVEL - && H[n] >= Control[i].Grade - Htol ) + && NodeHead[n] >= Control[i].Grade - Htol ) reset = 1; } @@ -1692,28 +1698,28 @@ int pswitch() if (reset == 1) { change = 0; - s = S[k]; + s = LinkStatus[k]; if (Link[k].Type == PIPE) { if (s != Control[i].Status) change = 1; } if (Link[k].Type == PUMP) { - if (K[k] != Control[i].Setting) change = 1; + if (LinkSetting[k] != Control[i].Setting) change = 1; } if (Link[k].Type >= PRV) { - if (K[k] != Control[i].Setting) change = 1; - else if (K[k] == MISSING && + if (LinkSetting[k] != Control[i].Setting) change = 1; + else if (LinkSetting[k] == MISSING && s != Control[i].Status) change = 1; } /* If a change occurs, update status & setting */ if (change) { - S[k] = Control[i].Status; - if (Link[k].Type > PIPE) K[k] = Control[i].Setting; - if (Statflag == FULL) writestatchange(k,s,S[k]); + LinkStatus[k] = Control[i].Status; + if (Link[k].Type > PIPE) LinkSetting[k] = Control[i].Setting; + if (Statflag == FULL) writestatchange(k,s,LinkStatus[k]); /* Re-set flow if status has changed */ // if (S[k] != s) initlinkflow(k, S[k], K[k]); @@ -1741,7 +1747,7 @@ double newflows() int k, n, n1, n2; /* Initialize net inflows (i.e., demands) at tanks */ - for (n=Njuncs+1; n <= Nnodes; n++) D[n] = 0.0; + for (n=Njuncs+1; n <= Nnodes; n++) NodeDemand[n] = 0.0; /* Initialize sum of flows & corrections */ qsum = 0.0; @@ -1761,7 +1767,7 @@ double newflows() n1 = Link[k].N1; n2 = Link[k].N2; - dh = H[n1] - H[n2]; + dh = NodeHead[n1] - NodeHead[n2]; dq = Y[k] - P[k]*dh; /* Adjust flow change by the relaxation factor */ //(2.00.11 - LR) @@ -1780,10 +1786,10 @@ double newflows() dqsum += ABS(dq); /* Update net flows to tanks */ - if ( S[k] > CLOSED ) //(2.00.12 - LR) + if ( LinkStatus[k] > CLOSED ) //(2.00.12 - LR) { - if (n1 > Njuncs) D[n1] -= Q[k]; - if (n2 > Njuncs) D[n2] += Q[k]; + if (n1 > Njuncs) NodeDemand[n1] -= Q[k]; + if (n2 > Njuncs) NodeDemand[n2] += Q[k]; } } @@ -1861,7 +1867,7 @@ void linkcoeffs() case PRV: case PSV: /* If valve status fixed then treat as pipe */ /* otherwise ignore the valve for now. */ - if (K[k] == MISSING) valvecoeff(k); //pipecoeff(k); //(2.00.11 - LR) + if (LinkSetting[k] == MISSING) valvecoeff(k); //pipecoeff(k); //(2.00.11 - LR) else continue; break; default: continue; @@ -1877,13 +1883,13 @@ void linkcoeffs() Aii[Row[n1]] += P[k]; /* Diagonal coeff. */ F[Row[n1]] += Y[k]; /* RHS coeff. */ } - else F[Row[n2]] += (P[k]*H[n1]); /* Node n1 is a tank */ + else F[Row[n2]] += (P[k]*NodeHead[n1]); /* Node n1 is a tank */ if (n2 <= Njuncs) /* Node n2 is junction */ { Aii[Row[n2]] += P[k]; /* Diagonal coeff. */ F[Row[n2]] -= Y[k]; /* RHS coeff. */ } - else F[Row[n1]] += (P[k]*H[n2]); /* Node n2 is a tank */ + else F[Row[n1]] += (P[k]*NodeHead[n2]); /* Node n2 is a tank */ } } /* End of linkcoeffs */ @@ -1904,7 +1910,7 @@ void nodecoeffs() /* flow imbalance & add imbalance to RHS array F. */ for (i=1; i<=Njuncs; i++) { - X[i] -= D[i]; + X[i] -= NodeDemand[i]; F[Row[i]] += X[i]; } } /* End of nodecoeffs */ @@ -1925,7 +1931,7 @@ void valvecoeffs() for (i=1; i<=Nvalves; i++) /* Examine each valve */ { k = Valve[i].Link; /* Link index of valve */ - if (K[k] == MISSING) continue; /* Valve status fixed */ + if (LinkSetting[k] == MISSING) continue; /* Valve status fixed */ n1 = Link[k].N1; /* Start & end nodes */ n2 = Link[k].N2; switch (Link[k].Type) /* Call valve-specific */ @@ -1992,7 +1998,7 @@ double emitflowchange(int i) p = 1/RQtol; else p = 1.0/p; - return(E[i]/Qexp - p*(H[i] - Node[i].El)); + return(E[i]/Qexp - p*(NodeHead[i] - Node[i].El)); } @@ -2019,7 +2025,7 @@ void pipecoeff(int k) dfdq; /* Derivative of fric. fact. */ /* For closed pipe use headloss formula: h = CBIG*q */ - if (S[k] <= CLOSED) + if (LinkStatus[k] <= CLOSED) { P[k] = 1.0/CBIG; Y[k] = Q[k]; @@ -2148,8 +2154,10 @@ void pumpcoeff(int k) r, /* Flow resistance coeff. */ n; /* Flow exponent coeff. */ + double setting = LinkSetting[k]; + /* Use high resistance pipe if pump closed or cannot deliver head */ - if (S[k] <= CLOSED || K[k] == 0.0) + if (LinkStatus[k] <= CLOSED || setting == 0.0) { //pipecoeff(k); //(2.00.11 - LR) P[k] = 1.0/CBIG; //(2.00.11 - LR) @@ -2166,7 +2174,7 @@ void pumpcoeff(int k) { /* Find intercept (h0) & slope (r) of pump curve */ /* line segment which contains speed-adjusted flow. */ - curvecoeff(Pump[p].Hcurve,q/K[k],&h0,&r); + curvecoeff(Pump[p].Hcurve, q/setting, &h0, &r); /* Determine head loss coefficients. */ Pump[p].H0 = -h0; @@ -2175,9 +2183,9 @@ void pumpcoeff(int k) } /* Adjust head loss coefficients for pump speed. */ - h0 = SQR(K[k])*Pump[p].H0; + h0 = SQR(setting)*Pump[p].H0; n = Pump[p].N; - r = Pump[p].R*pow(K[k],2.0-n); + r = Pump[p].R*pow(setting,2.0-n); if (n != 1.0) r = n*r*pow(q,n-1.0); /* Compute inverse headloss gradient (P) and flow correction factor (Y) */ @@ -2241,7 +2249,7 @@ void gpvcoeff(int k) /*** Updated 9/7/00 ***/ /* Treat as a pipe if valve closed */ - if (S[k] == CLOSED) valvecoeff(k); //pipecoeff(k); //(2.00.11 - LR) + if (LinkStatus[k] == CLOSED) valvecoeff(k); //pipecoeff(k); //(2.00.11 - LR) /* Otherwise utilize headloss curve */ /* whose index is stored in K */ @@ -2253,7 +2261,7 @@ void gpvcoeff(int k) /*** Updated 10/25/00 ***/ /*** Updated 12/29/00 ***/ - curvecoeff((int)ROUND(K[k]),q,&h0,&r); + curvecoeff((int)ROUND(LinkSetting[k]),q,&h0,&r); /* Compute inverse headloss gradient (P) */ /* and flow correction factor (Y). */ @@ -2273,19 +2281,19 @@ void pbvcoeff(int k) */ { /* If valve fixed OPEN or CLOSED then treat as a pipe */ - if (K[k] == MISSING || K[k] == 0.0) valvecoeff(k); //pipecoeff(k); //(2.00.11 - LR) + if (LinkSetting[k] == MISSING || LinkSetting[k] == 0.0) valvecoeff(k); //pipecoeff(k); //(2.00.11 - LR) /* If valve is active */ else { /* Treat as a pipe if minor loss > valve setting */ - if (Link[k].Km*SQR(Q[k]) > K[k]) valvecoeff(k); //pipecoeff(k); //(2.00.11 - LR) + if (Link[k].Km*SQR(Q[k]) > LinkSetting[k]) valvecoeff(k); //pipecoeff(k); //(2.00.11 - LR) /* Otherwise force headloss across valve to be equal to setting */ else { P[k] = CBIG; - Y[k] = K[k]*CBIG; + Y[k] = LinkSetting[k]*CBIG; } } } /* End of pbvcoeff */ @@ -2306,8 +2314,8 @@ void tcvcoeff(int k) km = Link[k].Km; /* If valve not fixed OPEN or CLOSED, compute its loss coeff. */ - if (K[k] != MISSING) - Link[k].Km = 0.02517*K[k]/(SQR(Link[k].Diam)*SQR(Link[k].Diam)); + if (LinkSetting[k] != MISSING) + Link[k].Km = 0.02517*LinkSetting[k]/(SQR(Link[k].Diam)*SQR(Link[k].Diam)); /* Then apply usual pipe formulas */ valvecoeff(k); //pipecoeff(k); //(2.00.11 - LR) @@ -2333,9 +2341,9 @@ void prvcoeff(int k, int n1, int n2) double hset; /* Valve head setting */ i = Row[n1]; /* Matrix rows of nodes */ j = Row[n2]; - hset = Node[n2].El + K[k]; /* Valve setting */ + hset = Node[n2].El + LinkSetting[k]; /* Valve setting */ - if (S[k] == ACTIVE) + if (LinkStatus[k] == ACTIVE) { /* Set coeffs. to force head at downstream @@ -2379,9 +2387,9 @@ void psvcoeff(int k, int n1, int n2) double hset; /* Valve head setting */ i = Row[n1]; /* Matrix rows of nodes */ j = Row[n2]; - hset = Node[n1].El + K[k]; /* Valve setting */ + hset = Node[n1].El + LinkSetting[k]; /* Valve setting */ - if (S[k] == ACTIVE) + if (LinkStatus[k] == ACTIVE) { /* Set coeffs. to force head at upstream @@ -2423,7 +2431,7 @@ void fcvcoeff(int k, int n1, int n2) { int i,j; /* Rows in solution matrix */ double q; /* Valve flow setting */ - q = K[k]; + q = LinkSetting[k]; i = Row[n1]; j = Row[n2]; @@ -2432,7 +2440,7 @@ void fcvcoeff(int k, int n1, int n2) flow setting as external demand at upstream node and external supply at downstream node. */ - if (S[k] == ACTIVE) + if (LinkStatus[k] == ACTIVE) { X[n1] -= q; F[i] -= q; @@ -2474,7 +2482,7 @@ void valvecoeff(int k) double p; // Valve is closed. Use a very small matrix coeff. - if (S[k] <= CLOSED) + if (LinkStatus[k] <= CLOSED) { P[k] = 1.0/CBIG; Y[k] = Q[k]; diff --git a/src/input3.c b/src/input3.c index a19bfdc..d0922f6 100755 --- a/src/input3.c +++ b/src/input3.c @@ -99,9 +99,9 @@ int juncdata() demand->Pat = p; demand->next = Node[Njuncs].D; Node[Njuncs].D = demand; - D[Njuncs] = y; + NodeDemand[Njuncs] = y; } - else D[Njuncs] = MISSING; + else NodeDemand[Njuncs] = MISSING; /*** end of update ***/ return(0); } /* end of juncdata */ @@ -682,11 +682,11 @@ int demanddata() /*** Updated 6/24/02 ***/ demand = Node[j].D; - if (demand && D[j] != MISSING) + if (demand && NodeDemand[j] != MISSING) { demand->Base = y; demand->Pat = p; - D[j] = MISSING; + NodeDemand[j] = MISSING; } /*** End of update ***/ diff --git a/src/output.c b/src/output.c index 9d04531..0e18bb8 100755 --- a/src/output.c +++ b/src/output.c @@ -152,30 +152,30 @@ int savehyd(long *htime) fwrite(&t,sizeof(INT4),1,HydFile); /* Save current nodal demands (D) */ - for (i=1; i<=Nnodes; i++) x[i] = (REAL4)D[i]; + for (i=1; i<=Nnodes; i++) x[i] = (REAL4)NodeDemand[i]; fwrite(x+1,sizeof(REAL4),Nnodes,HydFile); /* Copy heads (H) to buffer of floats (x) and save buffer */ - for (i=1; i<=Nnodes; i++) x[i] = (REAL4)H[i]; + for (i=1; i<=Nnodes; i++) x[i] = (REAL4)NodeHead[i]; fwrite(x+1,sizeof(REAL4),Nnodes,HydFile); /* Force flow in closed links to be zero then save flows */ for (i=1; i<=Nlinks; i++) { - if (S[i] <= CLOSED) x[i] = 0.0f; + if (LinkStatus[i] <= CLOSED) x[i] = 0.0f; else x[i] = (REAL4)Q[i]; } fwrite(x+1,sizeof(REAL4),Nlinks,HydFile); /* Copy link status to buffer of floats (x) & write buffer */ - for (i=1; i<=Nlinks; i++) x[i] = (REAL4)S[i]; + for (i=1; i<=Nlinks; i++) x[i] = (REAL4)LinkStatus[i]; fwrite(x+1,sizeof(REAL4),Nlinks,HydFile); /* Save link settings & check for successful write-to-disk */ /* (We assume that if any of the previous fwrites failed, */ /* then this one will also fail.) */ - for (i=1; i<=Nlinks; i++) x[i] = (REAL4)K[i]; + for (i=1; i<=Nlinks; i++) x[i] = (REAL4)LinkSetting[i]; if (fwrite(x+1,sizeof(REAL4),Nlinks,HydFile) < (unsigned)Nlinks) errcode = 308; free(x); @@ -286,19 +286,19 @@ int readhyd(long *hydtime) *hydtime = t; if (fread(x+1,sizeof(REAL4),Nnodes,HydFile) < (unsigned)Nnodes) result = 0; - else for (i=1; i<=Nnodes; i++) D[i] = x[i]; + else for (i=1; i<=Nnodes; i++) NodeDemand[i] = x[i]; if (fread(x+1,sizeof(REAL4),Nnodes,HydFile) < (unsigned)Nnodes) result = 0; - else for (i=1; i<=Nnodes; i++) H[i] = x[i]; + else for (i=1; i<=Nnodes; i++) NodeHead[i] = x[i]; if (fread(x+1,sizeof(REAL4),Nlinks,HydFile) < (unsigned)Nlinks) result = 0; else for (i=1; i<=Nlinks; i++) Q[i] = x[i]; if (fread(x+1,sizeof(REAL4),Nlinks,HydFile) < (unsigned)Nlinks) result = 0; - else for (i=1; i<=Nlinks; i++) S[i] = (char) x[i]; + else for (i=1; i<=Nlinks; i++) LinkStatus[i] = (char) x[i]; if (fread(x+1,sizeof(REAL4),Nlinks,HydFile) < (unsigned)Nlinks) result = 0; - else for (i=1; i<=Nlinks; i++) K[i] = x[i]; + else for (i=1; i<=Nlinks; i++) LinkSetting[i] = x[i]; free(x); return result; @@ -361,16 +361,16 @@ int nodeoutput(int j, REAL4 *x, double ucf) switch(j) { case DEMAND: for (i=1; i<=Nnodes; i++) - x[i] = (REAL4)(D[i]*ucf); + x[i] = (REAL4)(NodeDemand[i]*ucf); break; case HEAD: for (i=1; i<=Nnodes; i++) - x[i] = (REAL4)(H[i]*ucf); + x[i] = (REAL4)(NodeHead[i]*ucf); break; case PRESSURE: for (i=1; i<=Nnodes; i++) - x[i] = (REAL4)((H[i] - Node[i].El)*ucf); + x[i] = (REAL4)((NodeHead[i] - Node[i].El)*ucf); break; case QUALITY: for (i=1; i<=Nnodes; i++) - x[i] = (REAL4)(C[i]*ucf); + x[i] = (REAL4)(NodeQual[i]*ucf); } /* Write x[1] to x[Nnodes] to output file */ @@ -413,10 +413,10 @@ int linkoutput(int j, REAL4 *x, double ucf) break; case HEADLOSS: for (i=1; i<=Nlinks; i++) { - if (S[i] <= CLOSED) x[i] = 0.0f; + if (LinkStatus[i] <= CLOSED) x[i] = 0.0f; else { - h = H[Link[i].N1] - H[Link[i].N2]; + h = NodeHead[Link[i].N1] - NodeHead[Link[i].N2]; if (Link[i].Type != PUMP) h = ABS(h); if (Link[i].Type <= PIPE) x[i] = (REAL4)(1000.0*h/Link[i].Len); @@ -428,25 +428,26 @@ int linkoutput(int j, REAL4 *x, double ucf) x[i] = (REAL4)(avgqual(i)*ucf); break; case STATUS: for (i=1; i<=Nlinks; i++) - x[i] = (REAL4)S[i]; + x[i] = (REAL4)LinkStatus[i]; break; case SETTING: for (i=1; i<=Nlinks; i++) { - if (K[i] != MISSING) + double setting = LinkSetting[i]; + if (setting != MISSING) switch (Link[i].Type) { case CV: - case PIPE: x[i] = (REAL4)K[i]; + case PIPE: x[i] = (REAL4)setting; break; - case PUMP: x[i] = (REAL4)K[i]; + case PUMP: x[i] = (REAL4)setting; break; case PRV: case PSV: - case PBV: x[i] = (REAL4)(K[i]*Ucf[PRESSURE]); + case PBV: x[i] = (REAL4)(setting*Ucf[PRESSURE]); break; - case FCV: x[i] = (REAL4)(K[i]*Ucf[FLOW]); + case FCV: x[i] = (REAL4)(setting*Ucf[FLOW]); break; - case TCV: x[i] = (REAL4)K[i]; + case TCV: x[i] = (REAL4)setting; break; default: x[i] = 0.0f; } @@ -464,7 +465,7 @@ int linkoutput(int j, REAL4 *x, double ucf) { if (Link[i].Type <= PIPE && ABS(Q[i]) > TINY) { - h = ABS(H[Link[i].N1] - H[Link[i].N2]); + h = ABS(NodeHead[Link[i].N1] - NodeHead[Link[i].N2]); f = 39.725*h*pow(Link[i].Diam,5)/Link[i].Len/SQR(Q[i]); x[i] = (REAL4)f; } @@ -642,11 +643,11 @@ int savetimestat(REAL4 *x, char objtype) /* Update internal output variables where applicable */ if (objtype == NODEHDR) switch (j) { - case DEMAND: for (i=1; i<=n; i++) D[i] = x[i]/Ucf[DEMAND]; + case DEMAND: for (i=1; i<=n; i++) NodeDemand[i] = x[i]/Ucf[DEMAND]; break; - case HEAD: for (i=1; i<=n; i++) H[i] = x[i]/Ucf[HEAD]; + case HEAD: for (i=1; i<=n; i++) NodeHead[i] = x[i]/Ucf[HEAD]; break; - case QUALITY: for (i=1; i<=n; i++) C[i] = x[i]/Ucf[QUALITY]; + case QUALITY: for (i=1; i<=n; i++) NodeQual[i] = x[i]/Ucf[QUALITY]; break; } else if (j == FLOW) for (i=1; i<=n; i++) Q[i] = x[i]/Ucf[FLOW]; diff --git a/src/quality.c b/src/quality.c index 8a5b8dd..be9193d 100755 --- a/src/quality.c +++ b/src/quality.c @@ -106,9 +106,9 @@ int openqual() if (SegPool == NULL) errcode = 101; //(2.00.11 - LR) /* Allocate scratch array & reaction rate array*/ - XC = (double *) calloc(MAX((Nnodes+1),(Nlinks+1)),sizeof(double)); + TempQual = (double *) calloc(MAX((Nnodes+1),(Nlinks+1)),sizeof(double)); PipeRateCoeff = (double *) calloc((Nlinks+1), sizeof(double)); - ERRCODE(MEMCHECK(XC)); + ERRCODE(MEMCHECK(TempQual)); ERRCODE(MEMCHECK(PipeRateCoeff)); /* Allocate memory for WQ solver */ @@ -148,7 +148,7 @@ void initqual() int i; /* Initialize quality, tank volumes, & source mass flows */ - for (i=1; i<=Nnodes; i++) C[i] = Node[i].C0; + for (i=1; i<=Nnodes; i++) NodeQual[i] = Node[i].C0; for (i=1; i<=Ntanks; i++) Tank[i].C = Node[Tank[i].Node].C0; for (i=1; i<=Ntanks; i++) Tank[i].V = Tank[i].V0; for (i=1; i<=Nnodes; i++) { @@ -165,7 +165,7 @@ void initqual() if (Qualflag != NONE) { /* Initialize WQ at trace node (if applicable) */ - if (Qualflag == TRACE) C[TraceNode] = 100.0; + if (Qualflag == TRACE) NodeQual[TraceNode] = 100.0; /* Compute Schmidt number */ if (Diffus > 0.0) @@ -242,7 +242,7 @@ int runqual(long *t) for (int i=1; i<= Nlinks; ++i) { - if (S[i] <= CLOSED) { + if (LinkStatus[i] <= CLOSED) { QLinkFlow[i-1] = Q[i]; } } @@ -257,7 +257,7 @@ int runqual(long *t) for (int i=1; i<= Nlinks; ++i) { - if (S[i] <= CLOSED) { + if (LinkStatus[i] <= CLOSED) { QLinkFlow[i-1] = Q[i]; } } @@ -306,13 +306,13 @@ int nextqual(long *tstep) if (Tank[i].A != 0) { // skip reservoirs again int n = Tank[i].Node; Tank[i].V = QTankVolumes[i-1]; - H[n] = tankgrade(i,Tank[i].V); + NodeHead[n] = tankgrade(i,Tank[i].V); } } // restore the previous step's pipe link flows for (int i=1; i<=Nlinks; i++) { - if (S[i] <= CLOSED) { + if (LinkStatus[i] <= CLOSED) { Q[i] = 0.0; } } @@ -336,12 +336,12 @@ int nextqual(long *tstep) if (Tank[i].A != 0) { // skip reservoirs again int n = Tank[i].Node; Tank[i].V = tankVolumes[i-1]; - H[n] = tankgrade(i,Tank[i].V); + NodeHead[n] = tankgrade(i,Tank[i].V); } } for (int i=1; i<=Nlinks; ++i) { - if (S[i] <= CLOSED) { + if (LinkStatus[i] <= CLOSED) { Q[i] = QLinkFlow[i-1]; } } @@ -415,7 +415,7 @@ int closequal() free(VolIn); free(MassIn); free(PipeRateCoeff); - free(XC); + free(TempQual); free(QTankVolumes); free(QLinkFlow); return(errcode); @@ -571,7 +571,7 @@ void initsegs() /* Find quality of downstream node */ j = DOWN_NODE(k); - if (j <= Njuncs) c = C[j]; + if (j <= Njuncs) c = NodeQual[j]; else c = Tank[j-Njuncs].C; /* Fill link with single segment with this quality */ @@ -781,7 +781,7 @@ void accumulate(long dt) /* Re-set memory used to accumulate mass & volume */ memset(VolIn,0,(Nnodes+1)*sizeof(double)); memset(MassIn,0,(Nnodes+1)*sizeof(double)); - memset(XC,0,(Nnodes+1)*sizeof(double)); + memset(TempQual,0,(Nnodes+1)*sizeof(double)); /* Compute average conc. of segments adjacent to each node */ /* (For use if there is no transport through the node) */ @@ -803,7 +803,7 @@ void accumulate(long dt) for (k=1; k<=Nnodes; k++) { if (VolIn[k] > 0.0) { - XC[k] = MassIn[k]/VolIn[k]; + TempQual[k] = MassIn[k]/VolIn[k]; } } @@ -824,7 +824,7 @@ void accumulate(long dt) { VolIn[j] += v; seg = FirstSeg[k]; - cseg = C[i]; + cseg = NodeQuali]; if (seg != NULL) cseg = seg->c; MassIn[j] += v*cseg; removesegs(k); @@ -886,7 +886,7 @@ void updatenodes(long dt) ** Purpose: updates concentration at all nodes to mixture of accumulated ** inflow from connecting pipes. ** -** Note: Does not account for source flow effects. XC[i] contains +** Note: Does not account for source flow effects. TempQual[i] contains ** average concen. of segments adjacent to node i, used in case ** there was no inflow into i. **--------------------------------------------------------------------------- @@ -897,14 +897,14 @@ void updatenodes(long dt) /* Update junction quality */ for (i=1; i<=Njuncs; i++) { - if (D[i] < 0.0) { - VolIn[i] -= D[i]*dt; + if (NodeDemand[i] < 0.0) { + VolIn[i] -= NodeDemand[i]*dt; } if (VolIn[i] > 0.0) { - C[i] = MassIn[i]/VolIn[i]; + NodeQual[i] = MassIn[i]/VolIn[i]; } else { - C[i] = XC[i]; + NodeQual[i] = TempQual[i]; } } @@ -912,7 +912,7 @@ void updatenodes(long dt) updatetanks(dt); /* For flow tracing, set source node concen. to 100. */ - if (Qualflag == TRACE) C[TraceNode] = 100.0; + if (Qualflag == TRACE) NodeQual[TraceNode] = 100.0; } @@ -934,14 +934,14 @@ void sourceinput(long dt) /* Establish a flow cutoff which indicates no outflow from a node */ qcutoff = 10.0*TINY; - /* Zero-out the work array XC */ - memset(XC,0,(Nnodes+1)*sizeof(double)); + /* Zero-out the work array TempQual */ + memset(TempQual,0,(Nnodes+1)*sizeof(double)); if (Qualflag != CHEM) return; /* Consider each node */ for (n=1; n<=Nnodes; n++) { - + double thisDemand = NodeDemand[n]; /* Skip node if no WQ source */ source = Node[n].S; if (source == NULL) continue; @@ -949,7 +949,7 @@ void sourceinput(long dt) /* Find total flow volume leaving node */ if (n <= Njuncs) volout = VolIn[n]; /* Junctions */ - else volout = VolIn[n] - D[n]*dt; /* Tanks */ + else volout = VolIn[n] - (thisDemand * dt); /* Tanks */ qout = volout / (double) dt; /* Evaluate source input only if node outflow > cutoff flow */ @@ -965,13 +965,13 @@ void sourceinput(long dt) case CONCEN: /* Only add source mass if demand is negative */ - if (D[n] < 0.0) + if (thisDemand < 0.0) { - massadded = -s*D[n]*dt; + massadded = -s*thisDemand*dt; /* If node is a tank then set concen. to 0. */ /* (It will be re-set to true value in updatesourcenodes()) */ - if (n > Njuncs) C[n] = 0.0; + if (n > Njuncs) NodeQual[n] = 0.0; } else massadded = 0.0; break; @@ -985,8 +985,8 @@ void sourceinput(long dt) /* Mass added is difference between source */ /* & node concen. times outflow volume */ case SETPOINT: - if (s > C[n]) { - massadded = (s-C[n])*volout; + if (s > NodeQual[n]) { + massadded = (s-NodeQual[n])*volout; } else { massadded = 0.0; @@ -1001,7 +1001,7 @@ void sourceinput(long dt) } /* Source concen. contribution = (mass added / outflow volume) */ - XC[n] = massadded/volout; + TempQual[n] = massadded/volout; /* Update total mass added for time period & simulation */ source->Smass += massadded; @@ -1017,8 +1017,8 @@ void sourceinput(long dt) if (Tank[j].A == 0.0) { n = Njuncs + j; - volout = VolIn[n] - D[n]*dt; - if (volout > 0.0) Wsource += volout*C[n]; + volout = VolIn[n] - NodeDemand[n]*dt; + if (volout > 0.0) Wsource += volout*NodeQual[n]; } } } @@ -1052,7 +1052,7 @@ void release(long dt) v = q*dt; /* Include source contribution in quality released from node. */ - c = C[n] + XC[n]; + c = NodeQual[n] + TempQual[n]; /* If link has a last seg, check if its quality */ /* differs from that of the flow released from node.*/ @@ -1081,7 +1081,7 @@ void updatesourcenodes(long dt) ** Input: dt = current WQ time step ** Output: none ** Purpose: updates quality at source nodes. -** (XC[n] = concen. added by source at node n) +** (TempQual[n] = concen. added by source at node n) **--------------------------------------------------- */ { @@ -1097,13 +1097,13 @@ void updatesourcenodes(long dt) if (source == NULL) continue; /* Add source to current node concen. */ - C[n] += XC[n]; + NodeQual[n] += TempQual[n]; /* For tanks, node concen. = internal concen. */ if (n > Njuncs) { i = n - Njuncs; - if (Tank[i].A > 0.0) C[n] = Tank[i].C; + if (Tank[i].A > 0.0) NodeQual[n] = Tank[i].C; } /* Normalize mass added at source to time step */ @@ -1130,7 +1130,7 @@ void updatetanks(long dt) /* Use initial quality for reservoirs */ if (Tank[i].A == 0.0) { - C[n] = Node[n].C0; + NodeQual[n] = Node[n].C0; } /* Update tank WQ based on mixing model */ else { @@ -1173,7 +1173,7 @@ void updatetanks(long dt) // /* Update tank volume & nodal quality */ // Tank[i].V += D[n]*dt; -// C[n] = Tank[i].C; +// NodeQual[n] = Tank[i].C; //} @@ -1198,7 +1198,7 @@ void tankmix1(int i, long dt) /* Determine tank & volumes */ vold = Tank[i].V; n = Tank[i].Node; - Tank[i].V += D[n]*dt; + Tank[i].V += NodeDemand[n]*dt; vin = VolIn[n]; /* Compute inflow concen. */ @@ -1211,7 +1211,7 @@ void tankmix1(int i, long dt) c = MIN(c, cmax); c = MAX(c, 0.0); Tank[i].C = c; - C[n] = Tank[i].C; + NodeQual[n] = Tank[i].C; } /*** Updated 10/25/00 ***/ @@ -1248,7 +1248,7 @@ void tankmix2(int i, long dt) /* Find inflows & outflows */ n = Tank[i].Node; - vnet = D[n]*dt; + vnet = NodeDemand[n]*dt; vin = VolIn[n]; if (vin > 0.0) cin = MassIn[n]/vin; else cin = 0.0; @@ -1304,7 +1304,7 @@ void tankmix2(int i, long dt) /* represent quality of tank since this is where */ /* outflow begins to flow from */ Tank[i].C = seg1->c; - C[n] = Tank[i].C; + NodeQual[n] = Tank[i].C; } @@ -1339,7 +1339,7 @@ void tankmix3(int i, long dt) /* Find inflows & outflows */ n = Tank[i].Node; - vnet = D[n]*dt; + vnet = NodeDemand[n]*dt; vin = VolIn[n]; vout = vin - vnet; if (vin > 0.0) cin = MassIn[n]/VolIn[n]; @@ -1380,7 +1380,7 @@ void tankmix3(int i, long dt) /* to represent overall quality of tank */ if (vsum > 0.0) Tank[i].C = csum/vsum; else Tank[i].C = FirstSeg[k]->c; - C[n] = Tank[i].C; + NodeQual[n] = Tank[i].C; /* Add new last segment for new flow entering tank */ if (vin > 0.0) @@ -1430,7 +1430,7 @@ void tankmix4(int i, long dt) /* Find inflows & outflows */ n = Tank[i].Node; - vnet = D[n]*dt; + vnet = NodeDemand[n]*dt; vin = VolIn[n]; if (vin > 0.0) cin = MassIn[n]/VolIn[n]; else cin = 0.0; @@ -1498,7 +1498,7 @@ void tankmix4(int i, long dt) /* Reported tank quality is mixture of flow released and any inflow */ Tank[i].C = (csum + MassIn[n])/(vsum + vin); } - C[n] = Tank[i].C; + NodeQual[n] = Tank[i].C; } @@ -1553,7 +1553,7 @@ double avgqual(int k) seg = seg->prev; } if (vsum > 0.0) return(msum/vsum); - else return( (C[Link[k].N1] + C[Link[k].N2])/2. ); + else return( (NodeQual[Link[k].N1] + NodeQual[Link[k].N2])/2. ); } diff --git a/src/report.c b/src/report.c index b021461..deffe03 100755 --- a/src/report.c +++ b/src/report.c @@ -296,15 +296,15 @@ void writehydstat(int iter, double relerr) for (i=1; i<=Ntanks; i++) { n = Tank[i].Node; - if (ABS(D[n]) < 0.001) newstat = CLOSED; - else if (D[n] > 0.0) newstat = FILLING; - else if (D[n] < 0.0) newstat = EMPTYING; + if (ABS(NodeDemand[n]) < 0.001) newstat = CLOSED; + else if (NodeDemand[n] > 0.0) newstat = FILLING; + else if (NodeDemand[n] < 0.0) newstat = EMPTYING; else newstat = OldStat[Nlinks+i]; if (newstat != OldStat[Nlinks+i]) { if (Tank[i].A > 0.0) sprintf(s1,FMT50,atime,Node[n].ID,StatTxt[newstat], - (H[n]-Node[n].El)*Ucf[HEAD],Field[HEAD].Units); + (NodeHead[n]-Node[n].El)*Ucf[HEAD],Field[HEAD].Units); else sprintf(s1,FMT51,atime,Node[n].ID,StatTxt[newstat]); writeline(s1); OldStat[Nlinks+i] = newstat; @@ -314,15 +314,15 @@ void writehydstat(int iter, double relerr) /* Display status changes for links */ for (i=1; i<=Nlinks; i++) { - if (S[i] != OldStat[i]) + if (LinkStatus[i] != OldStat[i]) { if (Htime == 0) sprintf(s1,FMT52,atime,LinkTxt[Link[i].Type],Link[i].ID, - StatTxt[S[i]]); + StatTxt[LinkStatus[i]]); else sprintf(s1,FMT53,atime,LinkTxt[Link[i].Type],Link[i].ID, - StatTxt[OldStat[i]],StatTxt[S[i]]); + StatTxt[OldStat[i]],StatTxt[LinkStatus[i]]); writeline(s1); - OldStat[i] = S[i]; + OldStat[i] = LinkStatus[i]; } } writeline(" "); @@ -763,7 +763,7 @@ void writestatchange(int k, char s1, char s2) { /*** Updated 10/25/00 ***/ - setting = K[k]; //Link[k].Kc; + setting = LinkSetting[k]; //Link[k].Kc; switch (Link[k].Type) { @@ -871,7 +871,7 @@ int writehydwarn(int iter, double relerr) /* Check for negative pressures */ for (i=1; i<=Njuncs; i++) { - if (H[i] < Node[i].El && D[i] > 0.0) + if (NodeHead[i] < Node[i].El && NodeDemand[i] > 0.0) { sprintf(Msg,WARN06,clocktime(Atime,Htime)); if (Messageflag) writeline(Msg); @@ -884,10 +884,10 @@ int writehydwarn(int iter, double relerr) for (i=1; i<=Nvalves; i++) { j = Valve[i].Link; - if (S[j] >= XFCV) + if (LinkStatus[j] >= XFCV) { sprintf(Msg,WARN05,LinkTxt[Link[j].Type],Link[j].ID, - StatTxt[S[j]],clocktime(Atime,Htime)); + StatTxt[LinkStatus[j]],clocktime(Atime,Htime)); if (Messageflag) writeline(Msg); flag = 5; } @@ -897,10 +897,10 @@ int writehydwarn(int iter, double relerr) for (i=1; i<=Npumps; i++) { j = Pump[i].Link; - s = S[j]; //(2.00.11 - LR) - if (S[j] >= OPEN) //(2.00.11 - LR) + s = LinkStatus[j]; //(2.00.11 - LR) + if (LinkStatus[j] >= OPEN) //(2.00.11 - LR) { //(2.00.11 - LR) - if (Q[j] > K[j]*Pump[i].Qmax) s = XFLOW; //(2.00.11 - LR) + if (Q[j] > LinkSetting[j]*Pump[i].Qmax) s = XFLOW; //(2.00.11 - LR) if (Q[j] < 0.0) s = XHEAD; //(2.00.11 - LR) } //(2.00.11 - LR) if (s == XHEAD || s == XFLOW) //(2.00.11 - LR) @@ -984,7 +984,7 @@ int disconnected() mcount = Ntanks; for (i=1; i<=Njuncs; i++) { - if (D[i] < 0.0) + if (NodeDemand[i] < 0.0) { mcount++; nodelist[mcount] = i; @@ -999,7 +999,7 @@ int disconnected() count = 0; for (i=1; i<=Njuncs; i++) { - if (!marked[i] && D[i] != 0.0) /* Skip if no demand */ + if (!marked[i] && NodeDemand[i] != 0.0) /* Skip if no demand */ { count++; if (count <= MAXCOUNT && Messageflag) @@ -1068,7 +1068,7 @@ void marknodes(int m, int *nodelist, char *marked) } /* Mark connection node if link not closed */ - if (S[k] > CLOSED) + if (LinkStatus[k] > CLOSED) { marked[j] = 1; m++; diff --git a/src/rules.c b/src/rules.c index aa2e003..7ad038f 100755 --- a/src/rules.c +++ b/src/rules.c @@ -704,7 +704,7 @@ int checkstatus(struct Premise *p) case IS_OPEN: case IS_CLOSED: case IS_ACTIVE: - i = S[p->index]; + i = LinkStatus[p->index]; if (i <= CLOSED) j = IS_CLOSED; else if (i == ACTIVE) j = IS_ACTIVE; else j = IS_OPEN; @@ -736,20 +736,20 @@ int checkvalue(struct Premise *p) /*** Updated 10/25/00 ***/ case r_DEMAND: if (p->object == r_SYSTEM) x = Dsystem*Ucf[DEMAND]; - else x = D[i]*Ucf[DEMAND]; + else x = NodeDemand[i]*Ucf[DEMAND]; break; case r_HEAD: - case r_GRADE: x = H[i]*Ucf[HEAD]; + case r_GRADE: x = NodeHead[i]*Ucf[HEAD]; break; - case r_PRESSURE: x = (H[i]-Node[i].El)*Ucf[PRESSURE]; + case r_PRESSURE: x = (NodeHead[i]-Node[i].El)*Ucf[PRESSURE]; break; - case r_LEVEL: x = (H[i]-Node[i].El)*Ucf[HEAD]; + case r_LEVEL: x = (NodeHead[i]-Node[i].El)*Ucf[HEAD]; break; case r_FLOW: x = ABS(Q[i])*Ucf[FLOW]; break; - case r_SETTING: if (K[i] == MISSING) return(0); - x = K[i]; + case r_SETTING: if (LinkSetting[i] == MISSING) return(0); + x = LinkSetting[i]; switch (Link[i].Type) { case PRV: @@ -761,14 +761,14 @@ int checkvalue(struct Premise *p) case r_FILLTIME: if (i <= Njuncs) return(0); j = i-Njuncs; if (Tank[j].A == 0.0) return(0); - if (D[i] <= TINY) return(0); - x = (Tank[j].Vmax - Tank[j].V)/D[i]; + if (NodeDemand[i] <= TINY) return(0); + x = (Tank[j].Vmax - Tank[j].V)/NodeDemand[i]; break; case r_DRAINTIME: if (i <= Njuncs) return(0); j = i-Njuncs; if (Tank[j].A == 0.0) return(0); - if (D[i] >= -TINY) return(0); - x = (Tank[j].Vmin - Tank[j].V)/D[i]; + if (NodeDemand[i] >= -TINY) return(0); + x = (Tank[j].Vmin - Tank[j].V)/NodeDemand[i]; break; default: return(0); } @@ -875,21 +875,21 @@ int takeactions() flag = FALSE; a = item->action; k = a->link; - s = S[k]; - v = K[k]; + s = LinkStatus[k]; + v = LinkSetting[k]; x = a->setting; /* Switch link from closed to open */ if (a->status == IS_OPEN && s <= CLOSED) { - setlinkstatus(k, 1, &S[k], &K[k]); + setlinkstatus(k, 1, &LinkStatus[k], &LinkSetting[k]); flag = TRUE; } /* Switch link from not closed to closed */ else if (a->status == IS_CLOSED && s > CLOSED) { - setlinkstatus(k, 0, &S[k], &K[k]); + setlinkstatus(k, 0, &LinkStatus[k], &LinkSetting[k]); flag = TRUE; } @@ -905,7 +905,7 @@ int takeactions() } if (ABS(x-v) > tol) { - setlinksetting(k, x, &S[k], &K[k]); + setlinksetting(k, x, &LinkStatus[k], &LinkSetting[k]); flag = TRUE; } } diff --git a/src/vars.h b/src/vars.h index eee1cda..59b92ad 100755 --- a/src/vars.h +++ b/src/vars.h @@ -144,17 +144,17 @@ AUTHOR: L. Rossman SField Field[MAXVAR]; /* Output reporting fields */ /* Array pointers not allocated and freed in same routine */ - char *S, /* Link status */ + char *LinkStatus, /* Link status */ *OldStat; /* Previous link/tank status */ - double *D, /* Node actual demand */ - *C, /* Node actual quality */ + double *NodeDemand, /* Node actual demand */ + *NodeQual, /* Node actual quality */ *E, /* Emitter flows */ - *K, /* Link settings */ + *LinkSetting, /* Link settings */ *Q, /* Link flows */ - *PipeRateCoeff, /* Pipe reaction rate */ + *PipeRateCoeff, /* Pipe reaction rate */ *X, /* General purpose array */ - *XC; /* General purpose array for water quality */ -EXTERN double *H; /* Node heads */ + *TempQual; /* General purpose array for water quality */ +EXTERN double *NodeHead; /* Node heads */ EXTERN double *QTankVolumes; EXTERN double *QLinkFlow; EXTERN STmplist *Patlist; /* Temporary time pattern list */ From 2a6f5bafc42999b3cf244685ca6d24c0a14f8d74 Mon Sep 17 00:00:00 2001 From: Sam Hatchett Date: Mon, 30 Sep 2013 16:34:30 -0400 Subject: [PATCH 45/49] updated version number --- src/types.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/types.h b/src/types.h index f9bcfab..3119edd 100755 --- a/src/types.h +++ b/src/types.h @@ -37,7 +37,7 @@ typedef int INT4; / ----------------------------- */ /*** Updated ***/ -#define CODEVERSION 20012 //(2.00.12 - LR) +#define CODEVERSION 20100 #define MAGICNUMBER 516114521 #define VERSION 200 #define EOFMARK 0x1A /* Use 0x04 for UNIX systems */ From 93036690a00013af6b84a34360706da27f147080 Mon Sep 17 00:00:00 2001 From: Sam Hatchett Date: Fri, 4 Oct 2013 16:38:29 -0400 Subject: [PATCH 46/49] new API function -- get qual info MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit … to retrieve chemName and units --- include/epanet2.h | 1 + src/epanet.c | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/include/epanet2.h b/include/epanet2.h index 0543a15..6c3a7fa 100755 --- a/include/epanet2.h +++ b/include/epanet2.h @@ -251,6 +251,7 @@ extern "C" { int DLLEXPORT ENsetoption(int code, EN_API_FLOAT_TYPE v); int DLLEXPORT ENsetstatusreport(int code); int DLLEXPORT ENsetqualtype(int qualcode, char *chemname, char *chemunits, char *tracenode); + int DLLEXPORT ENgetqualinfo(int *qualcode, char *chemname, char *chemunits, int *tracenode); int DLLEXPORT ENsetbasedemand(int nodeIndex, int demandIdx, EN_API_FLOAT_TYPE baseDemand); #if defined(__cplusplus) diff --git a/src/epanet.c b/src/epanet.c index 2c4aa09..96b87a3 100755 --- a/src/epanet.c +++ b/src/epanet.c @@ -1223,6 +1223,13 @@ int DLLEXPORT ENgetqualtype(int *qualcode, int *tracenode) return(0); } +int DLLEXPORT ENgetqualinfo(int *qualcode, char *chemname, char *chemunits, int *tracenode) +{ + ENgetqualtype(qualcode, tracenode); + strncpy(chemname,ChemName,MAXID); + strncpy(chemunits,ChemUnits,MAXID); + return 0; +} int DLLEXPORT ENgeterror(int errcode, char *errmsg, int n) /*---------------------------------------------------------------- From caa794447cb4eb21c1b6e04b21864f41a8fd12fb Mon Sep 17 00:00:00 2001 From: Sam Hatchett Date: Fri, 31 Jan 2014 11:16:07 -0500 Subject: [PATCH 47/49] updated hash methods. just increasing the size of the hash helps a lot with loading larger networks. perhaps hash could be extended to dynamically size based on network size. --- .../epanet/epanet.xcodeproj/project.pbxproj | 4 +- src/epanet.c | 26 +-- src/hash.c | 186 +++++++++--------- src/hash.h | 20 +- src/input2.c | 4 +- src/vars.h | 2 +- 6 files changed, 126 insertions(+), 116 deletions(-) diff --git a/build/Xcode/epanet/epanet.xcodeproj/project.pbxproj b/build/Xcode/epanet/epanet.xcodeproj/project.pbxproj index 2f904ac..f7a110a 100755 --- a/build/Xcode/epanet/epanet.xcodeproj/project.pbxproj +++ b/build/Xcode/epanet/epanet.xcodeproj/project.pbxproj @@ -54,7 +54,7 @@ 2255754917551234009946B1 /* report.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F7E1068369500641384 /* report.c */; }; 2255754A17551234009946B1 /* rules.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F7F1068369500641384 /* rules.c */; }; 2255754B17551234009946B1 /* smatrix.c in Sources */ = {isa = PBXBuildFile; fileRef = 22322F801068369500641384 /* smatrix.c */; }; - 226537E0179EDEEB00258C60 /* epanet2.h in Headers */ = {isa = PBXBuildFile; fileRef = 22322FA9106836B000641384 /* epanet2.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 226537E0179EDEEB00258C60 /* epanet2.h in Headers */ = {isa = PBXBuildFile; fileRef = 22322FA9106836B000641384 /* epanet2.h */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -484,6 +484,7 @@ MACOSX_DEPLOYMENT_TARGET = 10.8; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = macosx; + SKIP_INSTALL = YES; }; name = Debug; }; @@ -503,6 +504,7 @@ MACOSX_DEPLOYMENT_TARGET = 10.8; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = macosx; + SKIP_INSTALL = YES; }; name = Release; }; diff --git a/src/epanet.c b/src/epanet.c index 96b87a3..ba67420 100755 --- a/src/epanet.c +++ b/src/epanet.c @@ -96,9 +96,9 @@ This module calls the following functions that reside in other modules: writelogo() writereport() HASH.C - HTcreate() - HTfind() - HTfree() + ENHashTablecreate() + ENHashTableFind() + ENHashTableFree() The macro ERRCODE(x) is defined in TYPES.H. It says if the current value of the error code variable (errcode) is not fatal (< 100) then @@ -2802,8 +2802,8 @@ void initpointers() XLNZ = NULL; NZSUB = NULL; LNZ = NULL; - Nht = NULL; - Lht = NULL; + NodeHashTable = NULL; + LinkHashTable = NULL; initrules(); } @@ -2821,10 +2821,10 @@ int allocdata() int errcode = 0; /* Allocate node & link ID hash tables */ - Nht = HTcreate(); - Lht = HTcreate(); - ERRCODE(MEMCHECK(Nht)); - ERRCODE(MEMCHECK(Lht)); + NodeHashTable = ENHashTableCreate(); + LinkHashTable = ENHashTableCreate(); + ERRCODE(MEMCHECK(NodeHashTable)); + ERRCODE(MEMCHECK(LinkHashTable)); /* Allocate memory for network nodes */ /************************************************************* @@ -3023,8 +3023,8 @@ void freedata() freerules(); /* Free hash table memory */ - if (Nht != NULL) HTfree(Nht); - if (Lht != NULL) HTfree(Lht); + if (NodeHashTable != NULL) ENHashTableFree(NodeHashTable); + if (LinkHashTable != NULL) ENHashTableFree(LinkHashTable); } @@ -3138,7 +3138,7 @@ int findnode(char *id) **---------------------------------------------------------------- */ { - return(HTfind(Nht,id)); + return(ENHashTableFind(NodeHashTable,id)); } @@ -3151,7 +3151,7 @@ int findlink(char *id) **---------------------------------------------------------------- */ { - return(HTfind(Lht,id)); + return(ENHashTableFind(LinkHashTable,id)); } diff --git a/src/hash.c b/src/hash.c index 64af9a7..26c07bf 100755 --- a/src/hash.c +++ b/src/hash.c @@ -1,22 +1,22 @@ /*----------------------------------------------------------------------------- -** hash.c -** -** Implementation of a simple Hash Table for string storage & retrieval -** -** Written by L. Rossman -** Last Updated on 6/19/03 -** -** The hash table data structure (HTable) is defined in "hash.h". -** Interface Functions: -** HTcreate() - creates a hash table -** HTinsert() - inserts a string & its index value into a hash table -** HTfind() - retrieves the index value of a string from a table -** HTfree() - frees a hash table -** -********************************************************************* -** NOTE: This is a modified version of the original HASH.C module. -********************************************************************* -*/ + ** hash.c + ** + ** Implementation of a simple Hash Table for string storage & retrieval + ** + ** Written by L. Rossman + ** Last Updated on 6/19/03 + ** + ** The hash table data structure (HTable) is defined in "hash.h". + ** Interface Functions: + ** HTcreate() - creates a hash table + ** HTinsert() - inserts a string & its index value into a hash table + ** HTfind() - retrieves the index value of a string from a table + ** HTfree() - frees a hash table + ** + ********************************************************************* + ** NOTE: This is a modified version of the original HASH.C module. + ********************************************************************* + */ #ifndef __APPLE__ #include @@ -26,89 +26,97 @@ #include #include "hash.h" -/* Use Fletcher's checksum to compute 2-byte hash of string */ -unsigned int hash(char *str) +unsigned int _enHash(char *str); +unsigned int _enHash(char *str) { - unsigned int sum1= 0, check1; - unsigned long sum2= 0L; - while( '\0' != *str ) - { - sum1 += (*str); - str++; - if ( 255 <= sum1 ) sum1 -= 255; - sum2 += sum1; + unsigned int hash = 5381; + int c; + while ((c = *str++)) { + hash = ((hash << 5) + hash) + c; /* hash * 33 + c */ + } + unsigned int retHash = hash % ENHASHTABLEMAXSIZE; + return retHash; +} + +ENHashTable *ENHashTableCreate() +{ + int i; + ENHashTable *ht = (ENHashTable *) calloc(ENHASHTABLEMAXSIZE, sizeof(ENHashTable)); + if (ht != NULL) { + for (i=0; i= ENHASHTABLEMAXSIZE ) { + return(0); + } + entry = (ENHashEntry *) malloc(sizeof(ENHashEntry)); + if (entry == NULL) { + return(0); + } + entry->key = key; + entry->data = data; + entry->next = ht[i]; + ht[i] = entry; + return(1); } -int HTinsert(HTtable *ht, char *key, int data) +int ENHashTableFind(ENHashTable *ht, char *key) { - unsigned int i = hash(key); - struct HTentry *entry; - if ( i >= HTMAXSIZE ) return(0); - entry = (struct HTentry *) malloc(sizeof(struct HTentry)); - if (entry == NULL) return(0); - entry->key = key; - entry->data = data; - entry->next = ht[i]; - ht[i] = entry; - return(1); + unsigned int i = _enHash(key); + ENHashEntry *entry; + if ( i >= ENHASHTABLEMAXSIZE ) { + return(NOTFOUND); + } + entry = ht[i]; + while (entry != NULL) + { + if ( strcmp(entry->key,key) == 0 ) { + return(entry->data); + } + entry = entry->next; + } + return(NOTFOUND); } -int HTfind(HTtable *ht, char *key) +char *ENHashTableFindKey(ENHashTable *ht, char *key) { - unsigned int i = hash(key); - struct HTentry *entry; - if ( i >= HTMAXSIZE ) return(NOTFOUND); - entry = ht[i]; - while (entry != NULL) - { - if ( strcmp(entry->key,key) == 0 ) return(entry->data); - entry = entry->next; - } - return(NOTFOUND); + unsigned int i = _enHash(key); + ENHashEntry *entry; + if ( i >= ENHASHTABLEMAXSIZE ) { + return(NULL); + } + entry = ht[i]; + while (entry != NULL) + { + if ( strcmp(entry->key,key) == 0 ) { + return(entry->key); + } + entry = entry->next; + } + return(NULL); } -char *HTfindKey(HTtable *ht, char *key) +void ENHashTableFree(ENHashTable *ht) { - unsigned int i = hash(key); - struct HTentry *entry; - if ( i >= HTMAXSIZE ) return(NULL); - entry = ht[i]; - while (entry != NULL) - { - if ( strcmp(entry->key,key) == 0 ) return(entry->key); - entry = entry->next; - } - return(NULL); -} - -void HTfree(HTtable *ht) -{ - struct HTentry *entry, - *nextentry; - int i; - for (i=0; inext; - free(entry); - entry = nextentry; - } - } - free(ht); + ENHashEntry *entry, *nextentry; + int i; + for (i=0; inext; + free(entry); + entry = nextentry; + } + } + free(ht); } diff --git a/src/hash.h b/src/hash.h index 38999d1..2952ae6 100755 --- a/src/hash.h +++ b/src/hash.h @@ -7,22 +7,22 @@ #ifndef HASH_H #define HASH_H -#define HTMAXSIZE 1999 +#define ENHASHTABLEMAXSIZE 128000 #define NOTFOUND 0 -struct HTentry +typedef struct HTentryStruct { char *key; int data; - struct HTentry *next; -}; + struct HTentryStruct *next; +} ENHashEntry; -typedef struct HTentry *HTtable; +typedef ENHashEntry *ENHashTable; -HTtable *HTcreate(void); -int HTinsert(HTtable *, char *, int); -int HTfind(HTtable *, char *); -char *HTfindKey(HTtable *, char *); -void HTfree(HTtable *); +ENHashTable *ENHashTableCreate(void); +int ENHashTableInsert(ENHashTable *, char *, int); +int ENHashTableFind(ENHashTable *, char *); +char *ENHashTableFindKey(ENHashTable *, char *); +void ENHashTableFree(ENHashTable *); #endif \ No newline at end of file diff --git a/src/input2.c b/src/input2.c index 9f569e0..b372867 100755 --- a/src/input2.c +++ b/src/input2.c @@ -423,7 +423,7 @@ int addnodeID(int n, char *id) { if (findnode(id)) return(0); /* see EPANET.C */ strncpy(Node[n].ID, id, MAXID); - HTinsert(Nht, Node[n].ID, n); /* see HASH.C */ + ENHashTableInsert(NodeHashTable, Node[n].ID, n); /* see HASH.C */ return(1); } @@ -440,7 +440,7 @@ int addlinkID(int n, char *id) { if (findlink(id)) return(0); /* see EPANET.C */ strncpy(Link[n].ID, id, MAXID); - HTinsert(Lht, Link[n].ID, n); /* see HASH.C */ + ENHashTableInsert(LinkHashTable, Link[n].ID, n); /* see HASH.C */ return(1); } diff --git a/src/vars.h b/src/vars.h index 59b92ad..77b7284 100755 --- a/src/vars.h +++ b/src/vars.h @@ -169,7 +169,7 @@ EXTERN Stank *Tank; /* Tank data */ EXTERN Spump *Pump; /* Pump data */ EXTERN Svalve *Valve; /* Valve data */ EXTERN Scontrol *Control; /* Control data */ -EXTERN HTtable *Nht, *Lht; /* Hash tables for ID labels */ +EXTERN ENHashTable *NodeHashTable, *LinkHashTable; /* Hash tables for ID labels */ EXTERN Padjlist *Adjlist; /* Node adjacency lists */ EXTERN double _relativeError; EXTERN int _iterations; /* Info about hydraulic solution */ From 15278681529813f71d1a12e2bd8dd26a570631f8 Mon Sep 17 00:00:00 2001 From: sam hatchett Date: Sat, 12 Apr 2014 21:33:28 -0400 Subject: [PATCH 48/49] updating gitignore for xc5 --- .gitignore | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.gitignore b/.gitignore index 8782d5f..5e86e62 100755 --- a/.gitignore +++ b/.gitignore @@ -120,4 +120,11 @@ xcuserdata Debug/ +#### +# Xcode 5 - Source Control files +# +# Xcode 5 introduced a new file type .xccheckout. This files contains VCS metadata +# and should therefore not be checked into the VCS. + +*.xccheckout From 71b017e9ffe3380ca808e269b528113b59d3d9f9 Mon Sep 17 00:00:00 2001 From: jamesuber Date: Thu, 28 Aug 2014 15:48:51 -0400 Subject: [PATCH 49/49] minor fix to getqualinfo for trace sim type --- src/epanet.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/epanet.c b/src/epanet.c index ba67420..e4fd77a 100755 --- a/src/epanet.c +++ b/src/epanet.c @@ -1226,8 +1226,14 @@ int DLLEXPORT ENgetqualtype(int *qualcode, int *tracenode) int DLLEXPORT ENgetqualinfo(int *qualcode, char *chemname, char *chemunits, int *tracenode) { ENgetqualtype(qualcode, tracenode); - strncpy(chemname,ChemName,MAXID); - strncpy(chemunits,ChemUnits,MAXID); + if (Qualflag == TRACE) { + strncpy(chemname, "", MAXID); + strncpy(chemunits, "dimensionless", MAXID); + } + else { + strncpy(chemname,ChemName,MAXID); + strncpy(chemunits,ChemUnits,MAXID); + } return 0; }