diff --git a/.gitignore b/.gitignore old mode 100644 new mode 100755 index 7cb42f4..57e8651 --- a/.gitignore +++ b/.gitignore @@ -19,16 +19,117 @@ # 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 +*.suo +*.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 + +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 + diff --git a/README.md b/README.md old mode 100644 new mode 100755 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/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/MSVS/LemonTigerJ.sln b/build/MSVS/LemonTigerJ.sln new file mode 100755 index 0000000..f61001a --- /dev/null +++ b/build/MSVS/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/build/MSVS/LemonTigerJ.vcxproj b/build/MSVS/LemonTigerJ.vcxproj new file mode 100755 index 0000000..7ffa87b --- /dev/null +++ b/build/MSVS/LemonTigerJ.vcxproj @@ -0,0 +1,105 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {4B66D9F0-407B-4995-B625-1CA1B72662C6} + Win32Proj + + + + DynamicLibrary + true + v110 + + + Application + false + v110 + + + + + + + + + + + + + true + + + true + + + + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS + MultiThreadedDebugDLL + Level3 + ProgramDatabase + Disabled + .\include + + + MachineX86 + true + Console + + + + + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + MultiThreadedDLL + Level3 + ProgramDatabase + + + MachineX86 + true + Console + true + true + + + + + + \ No newline at end of file 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 old mode 100644 new mode 100755 index bb0c2b8..f7a110a --- a/build/Xcode/epanet/epanet.xcodeproj/project.pbxproj +++ b/build/Xcode/epanet/epanet.xcodeproj/project.pbxproj @@ -25,7 +25,6 @@ 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 */; }; @@ -41,8 +40,21 @@ 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 */; }; + 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 */; }; + 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 */; }; + 226537E0179EDEEB00258C60 /* epanet2.h in Headers */ = {isa = PBXBuildFile; fileRef = 22322FA9106836B000641384 /* epanet2.h */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -58,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; }; @@ -70,16 +82,15 @@ 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; }; 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 = ""; }; + 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 */ @@ -91,6 +102,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 2255753817551217009946B1 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; D289988505E68E00004EDB86 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -114,12 +132,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 */, @@ -132,7 +150,6 @@ 22322F7F1068369500641384 /* rules.c */, 22322F801068369500641384 /* smatrix.c */, 22322F811068369500641384 /* text.h */, - 22322F821068369500641384 /* toolkit.h */, 22322F831068369500641384 /* types.h */, 22322F841068369500641384 /* vars.h */, ); @@ -144,6 +161,7 @@ children = ( D2AAC0630554660B00DB518D /* libepanet.dylib */, 22322F66106833BB00641384 /* runepanet */, + 2255753B17551217009946B1 /* libepanet-static.a */, ); name = Products; sourceTree = ""; @@ -151,7 +169,6 @@ 22322FA8106836A000641384 /* Include */ = { isa = PBXGroup; children = ( - 22322FAD106836D900641384 /* malloc.h */, 22322FA9106836B000641384 /* epanet2.h */, ); name = Include; @@ -160,6 +177,14 @@ /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ + 2255753917551217009946B1 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 226537E0179EDEEB00258C60 /* epanet2.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; D2AAC0600554660B00DB518D /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; @@ -170,10 +195,8 @@ 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; }; @@ -197,6 +220,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" */; @@ -219,6 +259,9 @@ /* Begin PBXProject section */ 08FB7793FE84155DC02AAC07 /* Project object */ = { isa = PBXProject; + attributes = { + LastUpgradeCheck = 0500; + }; buildConfigurationList = 1DEB914E08733D8E0010E9CD /* Build configuration list for PBXProject "epanet" */; compatibilityVersion = "Xcode 3.2"; developmentRegion = English; @@ -235,6 +278,7 @@ targets = ( D2AAC0620554660B00DB518D /* epanet */, 22322F65106833BB00641384 /* runepanet */, + 2255753A17551217009946B1 /* epanet-static */, ); }; /* End PBXProject section */ @@ -260,6 +304,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; @@ -295,12 +359,13 @@ 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_PREPROCESSOR_DEFINITIONS = "EN_API_FLOAT_TYPE=double"; GCC_VERSION = com.apple.compilers.llvm.clang.1_0; INSTALL_PATH = /usr/local/lib; PRODUCT_NAME = epanet; @@ -312,9 +377,11 @@ 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; + 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; @@ -325,15 +392,23 @@ 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; - PREBINDING = NO; SDKROOT = ""; }; name = Debug; @@ -341,13 +416,21 @@ 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; - PREBINDING = NO; SDKROOT = ""; }; name = Release; @@ -358,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; @@ -376,18 +457,57 @@ 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; }; + 2255753C17551217009946B1 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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 = "EN_API_FLOAT_TYPE=double"; + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + MACOSX_DEPLOYMENT_TARGET = 10.8; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + SKIP_INSTALL = YES; + }; + name = Debug; + }; + 2255753D17551217009946B1 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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_PREPROCESSOR_DEFINITIONS = "EN_API_FLOAT_TYPE=double"; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + MACOSX_DEPLOYMENT_TARGET = 10.8; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + SKIP_INSTALL = YES; + }; + name = Release; + }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ @@ -418,6 +538,15 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + 2255753E17551217009946B1 /* Build configuration list for PBXNativeTarget "epanet-static" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 2255753C17551217009946B1 /* Debug */, + 2255753D17551217009946B1 /* 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 100755 index 0000000..052c6dc --- /dev/null +++ b/build/Xcode/epanet/epanet.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + 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. -=============================================================================== diff --git a/include/epanet2.h b/include/epanet2.h index d1d37f1..6c3a7fa 100755 --- a/include/epanet2.h +++ b/include/epanet2.h @@ -1,14 +1,44 @@ /* -** EPANET2.H -** -** C/C++ header file for EPANET Programmers Toolkit -** -** Last updated on 2/14/08 (2.00.12) -*/ + ******************************************************************* + + EPANET2.H - Prototypes for EPANET Functions Exported to DLL Toolkit + + VERSION: 2.00 + DATE: 5/8/00 + 10/25/00 + 3/1/01 + 8/15/07 (2.00.11) + 2/14/08 (2.00.12) + AUTHORS: L. Rossman - US EPA - NRMRL + OpenWaterAnalytics members: see git stats for contributors + + ******************************************************************* + */ #ifndef EPANET2_H #define EPANET2_H +#ifndef EN_API_FLOAT_TYPE +#define EN_API_FLOAT_TYPE float +#endif + +#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 the EPANET toolkit constants #define EN_ELEVATION 0 /* Node parameters */ @@ -36,8 +66,8 @@ #define EN_MAXLEVEL 21 #define EN_MIXFRACTION 22 #define EN_TANK_KBULK 23 - -#define EN_TANKVOLUME 24 /* TNT */ +#define EN_TANKVOLUME 24 +#define EN_MAXVOLUME 25 #define EN_DIAMETER 0 /* Link parameters */ #define EN_LENGTH 1 @@ -65,9 +95,16 @@ #define EN_RULESTEP 7 #define EN_STATISTIC 8 #define EN_PERIODS 9 -#define EN_STARTTIME 10 /* Added TNT 10/2/2009 */ +#define EN_STARTTIME 10 /* Added TNT 10/2/2009 */ +#define EN_HTIME 11 +#define EN_QTIME 12 +#define EN_HALTFLAG 13 +#define EN_NEXTEVENT 14 -#define EN_NODECOUNT 0 /* Component counts */ +#define EN_ITERATIONS 0 +#define EN_RELATIVEERROR 1 + +#define EN_NODECOUNT 0 /* Component counts */ #define EN_TANKCOUNT 1 #define EN_LINKCOUNT 2 #define EN_PATCOUNT 3 @@ -78,8 +115,8 @@ #define EN_RESERVOIR 1 #define EN_TANK 2 -#define EN_CVPIPE 0 /* Link types */ -#define EN_PIPE 1 +#define EN_CVPIPE 0 /* Link types. */ +#define EN_PIPE 1 /* See LinkType in TYPES.H */ #define EN_PUMP 2 #define EN_PRV 3 #define EN_PSV 4 @@ -88,19 +125,19 @@ #define EN_TCV 7 #define EN_GPV 8 -#define EN_NONE 0 /* Quality analysis types */ -#define EN_CHEM 1 +#define EN_NONE 0 /* Quality analysis types. */ +#define EN_CHEM 1 /* See QualType in TYPES.H */ #define EN_AGE 2 #define EN_TRACE 3 -#define EN_CONCEN 0 /* Source quality types */ -#define EN_MASS 1 +#define EN_CONCEN 0 /* Source quality types. */ +#define EN_MASS 1 /* See SourceType in TYPES.H. */ #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_CFS 0 /* Flow units types. */ +#define EN_GPM 1 /* See FlowUnitsType */ +#define EN_MGD 2 /* in TYPES.H. */ #define EN_IMGD 3 #define EN_AFD 4 #define EN_LPS 5 @@ -115,13 +152,13 @@ #define EN_EMITEXPON 3 #define EN_DEMANDMULT 4 -#define EN_LOWLEVEL 0 /* Control types */ -#define EN_HILEVEL 1 -#define EN_TIMER 2 +#define EN_LOWLEVEL 0 /* Control types. */ +#define EN_HILEVEL 1 /* See ControlType */ +#define EN_TIMER 2 /* in TYPES.H. */ #define EN_TIMEOFDAY 3 #define EN_AVERAGE 1 /* Time statistic types. */ -#define EN_MINIMUM 2 +#define EN_MINIMUM 2 /* See TstatType in TYPES.H */ #define EN_MAXIMUM 3 #define EN_RANGE 4 @@ -132,120 +169,93 @@ #define EN_NOSAVE 0 /* Save-results-to-file flag */ #define EN_SAVE 1 -#define EN_INITFLOW 10 /* Re-initialize flow flag */ + +#define EN_INITFLOW 10 /* Re-initialize flows 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 +// --- Declare the EPANET toolkit functions +#if defined(__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 ENepanet(char *inpFile, char *rptFile, char *binOutFile, void (*callback) (char *)); - int DLLEXPORT ENgetcurve(int curveIndex, int *nValues, float **xValues, float **yValues); + int DLLEXPORT ENopen(char *inpFile, char *rptFile, char *binOutFile); + int DLLEXPORT ENsaveinpfile(char *filename); + int DLLEXPORT ENclose(); - int DLLEXPORT ENgetversion(int *); + 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(); + 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 *line); + int DLLEXPORT ENreport(); + int DLLEXPORT ENresetreport(); + int DLLEXPORT ENsetreport(char *reportFormat); + + 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 *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 *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 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 *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 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 -}; + + int DLLEXPORT ENgetversion(int *version); + + 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 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) +} #endif -#endif +#endif //TOOLKIT_H \ No newline at end of file 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 9148a2e..a4aae2b 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 @@ -107,17 +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 */ - -/*** 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 @@ -137,14 +126,14 @@ 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" +#include "epanet2.h" void (* viewprog) (char *); /* Pointer to progress viewing function */ @@ -318,6 +307,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()); @@ -754,7 +744,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()); @@ -974,7 +965,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) @@ -1020,9 +1011,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); } @@ -1053,7 +1044,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 @@ -1063,7 +1054,7 @@ int DLLEXPORT ENgetoption(int code, float *value) */ { double v = 0.0; - *value = 0.0f; + *value = 0.0; if (!Openflag) return(102); switch (code) { @@ -1079,7 +1070,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 +1187,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 +1197,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); } @@ -1233,6 +1224,19 @@ int DLLEXPORT ENgetqualtype(int *qualcode, int *tracenode) return(0); } +int DLLEXPORT ENgetqualinfo(int *qualcode, char *chemname, char *chemunits, int *tracenode) +{ + ENgetqualtype(qualcode, tracenode); + if (Qualflag == TRACE) { + strncpy(chemname, "", MAXID); + strncpy(chemunits, "dimensionless", MAXID); + } + else { + strncpy(chemname,ChemName,MAXID); + strncpy(chemunits,ChemUnits,MAXID); + } + return 0; +} int DLLEXPORT ENgeterror(int errcode, char *errmsg, int n) /*---------------------------------------------------------------- @@ -1258,7 +1262,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 @@ -1269,10 +1273,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; @@ -1345,7 +1349,22 @@ int DLLEXPORT ENgetnodetype(int index, int *code) } -int DLLEXPORT ENgetnodevalue(int index, int code, float *value) +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 ** code = node parameter code (see TOOLKIT.H) @@ -1360,7 +1379,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); @@ -1438,19 +1457,19 @@ int DLLEXPORT ENgetnodevalue(int index, int code, float *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) @@ -1487,7 +1506,7 @@ int DLLEXPORT ENgetnodevalue(int index, int code, float *value) v = (Tank[index-Njuncs].Hmin - Node[index].El) * Ucf[ELEV]; } break; - + case EN_MAXLEVEL: v = 0.0; if ( index > Njuncs ) @@ -1513,12 +1532,12 @@ int DLLEXPORT ENgetnodevalue(int index, int code, float *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); } - *value = (float)v; + *value = (EN_API_FLOAT_TYPE)v; return(0); } @@ -1603,7 +1622,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 +1635,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); @@ -1643,9 +1662,12 @@ int DLLEXPORT ENgetlinkvalue(int index, int code, float *value) break; case EN_MINORLOSS: - v = Link[index].Km; if (Link[index].Type != PUMP) + { + v = Link[index].Km; v *= (SQR(Link[index].Diam)*SQR(Link[index].Diam)/0.02517); + } + else v = 0.0; break; case EN_INITSTATUS: @@ -1677,8 +1699,7 @@ int DLLEXPORT ENgetlinkvalue(int index, int code, float *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; @@ -1686,7 +1707,7 @@ int DLLEXPORT ENgetlinkvalue(int index, int code, float *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 { @@ -1699,26 +1720,31 @@ int DLLEXPORT ENgetlinkvalue(int index, int code, float *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: @@ -1743,12 +1769,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, 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 @@ -1764,17 +1790,17 @@ 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)); int iPoint; for (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; } + strncpy(id, curve.ID, MAXID); *nValues = nPoints; *xValues = pointX; *yValues = pointY; @@ -1782,6 +1808,7 @@ int DLLEXPORT ENgetcurve(int curveIndex, int *nValues, float **xValues, float * return err; } + /* ---------------------------------------------------------------- Functions for changing network data @@ -1790,7 +1817,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) @@ -1878,7 +1905,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) @@ -1908,7 +1935,7 @@ int DLLEXPORT ENsetnodevalue(int index, int code, float v) Tank[j].Hmin += value; Tank[j].Hmax += value; Node[index].El += value; - H[index] += value; + NodeHead[index] += value; } break; @@ -1965,14 +1992,16 @@ int DLLEXPORT ENsetnodevalue(int index, int code, float 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); 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); @@ -1989,7 +2018,7 @@ int DLLEXPORT ENsetnodevalue(int index, int code, float 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 { @@ -1998,7 +2027,9 @@ int DLLEXPORT ENsetnodevalue(int index, int code, float v) || value < Tank[j].Hmin) return(202); Tank[j].H0 = value; Tank[j].V0 = tankvolume(j, Tank[j].H0); - H[index] = Tank[j].H0; + // Resetting Volume in addition to initial volume + Tank[j].V = Tank[j].V0; + NodeHead[index] = Tank[j].H0; } break; @@ -2087,7 +2118,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) @@ -2153,7 +2184,7 @@ int DLLEXPORT ENsetlinkvalue(int index, int code, float 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: @@ -2180,7 +2211,7 @@ int DLLEXPORT ENsetlinkvalue(int index, int code, float 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; @@ -2274,7 +2305,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 @@ -2303,7 +2334,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 @@ -2334,62 +2365,93 @@ 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) - { - 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); } -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 ** Output: none -** Returns: error code -** Purpose: sets value for an analysis option +** Returns: error code +** Purpose: sets value for an analysis option **---------------------------------------------------------------- */ { @@ -2751,13 +2813,13 @@ void initpointers() **---------------------------------------------------------------- */ { - D = NULL; - C = NULL; - H = NULL; + NodeDemand = NULL; + NodeQual = NULL; + NodeHead = NULL; Q = NULL; - R = NULL; - S = NULL; - K = NULL; + PipeRateCoeff = NULL; + LinkStatus = NULL; + LinkSetting = NULL; OldStat = NULL; Node = NULL; @@ -2768,10 +2830,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; @@ -2784,8 +2848,8 @@ void initpointers() XLNZ = NULL; NZSUB = NULL; LNZ = NULL; - Nht = NULL; - Lht = NULL; + NodeHashTable = NULL; + LinkHashTable = NULL; initrules(); } @@ -2803,10 +2867,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 */ /************************************************************* @@ -2818,13 +2882,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 */ @@ -2833,12 +2897,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, */ @@ -2851,12 +2915,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 */ @@ -2874,7 +2940,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) */ @@ -2935,12 +3013,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) @@ -2991,8 +3069,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); } @@ -3106,7 +3184,7 @@ int findnode(char *id) **---------------------------------------------------------------- */ { - return(HTfind(Nht,id)); + return(ENHashTableFind(NodeHashTable,id)); } @@ -3119,7 +3197,7 @@ int findlink(char *id) **---------------------------------------------------------------- */ { - return(HTfind(Lht,id)); + return(ENHashTableFind(LinkHashTable,id)); } @@ -3181,6 +3259,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); @@ -3251,22 +3331,43 @@ 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; - /* 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=d->Base*Ucf[FLOW]; - return 0; + *baseDemand=(EN_API_FLOAT_TYPE)(d->Base*Ucf[FLOW]); + } + else { + *baseDemand=(EN_API_FLOAT_TYPE)(0.0); + } + 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; - int n=0; + int n=1; /* Check for valid arguments */ if (!Openflag) return(102); if (nodeIndex <= 0 || nodeIndex > Nnodes) return(203); @@ -3276,5 +3377,28 @@ 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); + int i; + for (i=0; i @@ -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 8195afd..2952ae6 100755 --- a/src/hash.h +++ b/src/hash.h @@ -4,21 +4,25 @@ ** */ -#define HTMAXSIZE 1999 +#ifndef HASH_H +#define HASH_H + +#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/hydraul.c b/src/hydraul.c index a56e14a..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 */ @@ -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); @@ -372,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; } @@ -399,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); @@ -603,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. */ @@ -616,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]; } } } @@ -629,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 */ @@ -661,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) @@ -686,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++; @@ -761,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) { @@ -799,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 && @@ -835,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; } @@ -951,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 */ @@ -998,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; @@ -1008,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) @@ -1050,15 +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) 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); + if (Tank[i].V + NodeDemand[n] >= Tank[i].Vmax) { + Tank[i].V = Tank[i].Vmax; + } + else if (Tank[i].V - NodeDemand[n] <= Tank[i].Vmin) { + Tank[i].V = Tank[i].Vmin; + } + NodeHead[n] = tankgrade(i,Tank[i].V); } } /* End of tanklevels */ @@ -1182,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; @@ -1238,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 */ @@ -1268,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); } } @@ -1307,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; @@ -1336,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; } } @@ -1369,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) @@ -1443,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) @@ -1471,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) @@ -1521,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) @@ -1574,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); } @@ -1609,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 */ @@ -1675,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; } @@ -1686,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]); @@ -1735,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; @@ -1755,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) @@ -1774,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]; } } @@ -1855,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; @@ -1871,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 */ @@ -1898,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 */ @@ -1919,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 */ @@ -1986,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)); } @@ -2013,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]; @@ -2142,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) @@ -2160,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; @@ -2169,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) */ @@ -2235,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 */ @@ -2247,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). */ @@ -2267,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 */ @@ -2300,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) @@ -2327,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 @@ -2373,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 @@ -2417,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]; @@ -2426,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; @@ -2468,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/input2.c b/src/input2.c index a0fa344..b372867 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 (0); //return(coordata()); case _LABELS: return(0); case _TAGS: return(0); case _VERTICES: return(0); @@ -416,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); } @@ -433,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); } @@ -513,6 +520,43 @@ 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; // 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; + c->next = Coordlist; + Coordlist = c; + } + } + return(0); +} STmplist *findID(char *id, STmplist *list) /* @@ -705,6 +749,65 @@ 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) + { + // BAD! ---> i = coordinateList->i; + i = findnode(coordinateList->ID); + 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..d0922f6 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; @@ -97,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 */ @@ -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() /* @@ -627,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/mempool.h b/src/mempool.h index c12d448..ca04993 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 4f20dfb..0e18bb8 100755 --- a/src/output.c +++ b/src/output.c @@ -152,29 +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; - else x[i] = (REAL4)Q[i]; + 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); @@ -285,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; @@ -338,7 +339,6 @@ int saveoutput() /* Write out node results, then link results */ for (j=DEMAND; j<=QUALITY; j++) ERRCODE(nodeoutput(j,x,Ucf[j])); for (j=FLOW; j<=FRICTION; j++) ERRCODE(linkoutput(j,x,Ucf[j])); - free(x); return(errcode); } /* End of saveoutput */ @@ -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 */ @@ -380,7 +380,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 @@ -413,10 +413,10 @@ int linkoutput(int j, float *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, float *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; } @@ -455,7 +456,7 @@ int linkoutput(int j, float *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 */ @@ -464,7 +465,7 @@ int linkoutput(int j, float *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 8cc1ffe..be9193d 100755 --- a/src/quality.c +++ b/src/quality.c @@ -106,10 +106,10 @@ 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)); - R = (double *) calloc((Nlinks+1), sizeof(double)); - ERRCODE(MEMCHECK(X)); - ERRCODE(MEMCHECK(R)); + TempQual = (double *) calloc(MAX((Nnodes+1),(Nlinks+1)),sizeof(double)); + PipeRateCoeff = (double *) calloc((Nlinks+1), sizeof(double)); + ERRCODE(MEMCHECK(TempQual)); + ERRCODE(MEMCHECK(PipeRateCoeff)); /* Allocate memory for WQ solver */ n = Nlinks+Ntanks+1; @@ -148,12 +148,16 @@ 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++) - if (Node[i].S != NULL) Node[i].S->Smass = 0.0; - + 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; @@ -161,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) @@ -189,13 +193,18 @@ void initqual() Wsource = 0.0; /* Re-position hydraulics file */ + if (!OpenHflag) { fseek(HydFile,HydOffset,SEEK_SET); + } + /* Set elapsed times to zero */ Htime = 0; Qtime = 0; Rtime = Rstart; Nperiods = 0; + + initsegs(); } @@ -221,8 +230,40 @@ int runqual(long *t) if (Qtime == Htime) { errcode = gethyd(&hydtime, &hydstep); - Htime = hydtime + hydstep; + if (!OpenHflag) { // test for sequential vs stepwise + // sequential + Htime = hydtime + hydstep; + } + else { + // stepwise calculation - hydraulic results are already in memory + for (int i=1; i<= Ntanks; ++i) { + QTankVolumes[i-1] = Tank[i].V; + } + + for (int i=1; i<= Nlinks; ++i) + { + if (LinkStatus[i] <= CLOSED) { + QLinkFlow[i-1] = Q[i]; + } + } + + } } + else { + // stepwise calculation + for (int i=1; i<= Ntanks; ++i) { + QTankVolumes[i-1] = Tank[i].V; + } + + for (int i=1; i<= Nlinks; ++i) + { + if (LinkStatus[i] <= CLOSED) { + QLinkFlow[i-1] = Q[i]; + } + } + + } + return(errcode); } @@ -243,8 +284,41 @@ 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]; + NodeHead[n] = tankgrade(i,Tank[i].V); + } + } + + // restore the previous step's pipe link flows + for (int i=1; i<=Nlinks; i++) { + if (LinkStatus[i] <= CLOSED) { + Q[i] = 0.0; + } + } + } + /* Perform water quality routing over this time step */ if (Qualflag != NONE && hydstep > 0) transport(hydstep); @@ -255,6 +329,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]; + NodeHead[n] = tankgrade(i,Tank[i].V); + } + } + + for (int i=1; i<=Nlinks; ++i) { + if (LinkStatus[i] <= CLOSED) { + Q[i] = QLinkFlow[i-1]; + } + } + + free(tankVolumes); + } + return(errcode); } @@ -320,8 +414,10 @@ int closequal() free(FlowDir); free(VolIn); free(MassIn); - free(R); - free(X); + free(PipeRateCoeff); + free(TempQual); + free(QTankVolumes); + free(QLinkFlow); return(errcode); } @@ -344,10 +440,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) @@ -365,12 +465,20 @@ 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 hydraulics are open, or if we're in sequential mode (where qtime can increase) + if (OpenHflag || Qtime != 0) { + reorientsegs(); + } + } return(errcode); } @@ -415,7 +523,7 @@ void transport(long tstep) */ { long qtime, dt; - + /* Repeat until elapsed time equals hydraulic time step */ AllocSetPool(SegPool); //(2.00.11 - LR) @@ -431,6 +539,7 @@ void transport(long tstep) release(dt); /* Release new nodal flows */ } updatesourcenodes(tstep); /* Update quality at source nodes */ + } @@ -451,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; @@ -460,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 */ @@ -518,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 */ @@ -584,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; } } @@ -666,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(X,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) */ @@ -685,9 +800,13 @@ void accumulate(long dt) VolIn[j]++; } } - for (k=1; k<=Nnodes; k++) - if (VolIn[k] > 0.0) X[k] = MassIn[k]/VolIn[k]; - + + for (k=1; k<=Nnodes; k++) { + if (VolIn[k] > 0.0) { + TempQual[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)); @@ -705,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); @@ -767,27 +886,33 @@ 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. TempQual[i] contains ** average concen. of segments adjacent to node i, used in case ** there was no inflow into i. **--------------------------------------------------------------------------- */ { - 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] = X[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 (NodeDemand[i] < 0.0) { + VolIn[i] -= NodeDemand[i]*dt; + } + if (VolIn[i] > 0.0) { + NodeQual[i] = MassIn[i]/VolIn[i]; + } + else { + NodeQual[i] = TempQual[i]; + } + } + + /* Update tank quality */ + updatetanks(dt); + + /* For flow tracing, set source node concen. to 100. */ + if (Qualflag == TRACE) NodeQual[TraceNode] = 100.0; } @@ -809,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 X */ - memset(X,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; @@ -824,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 */ @@ -840,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; @@ -860,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 > NodeQual[n]) { + massadded = (s-NodeQual[n])*volout; + } + else { + massadded = 0.0; + } + break; /* Flow-Paced Booster Source: */ /* Mass added = source concen. times outflow volume */ @@ -872,7 +1001,7 @@ void sourceinput(long dt) } /* Source concen. contribution = (mass added / outflow volume) */ - X[n] = massadded/volout; + TempQual[n] = massadded/volout; /* Update total mass added for time period & simulation */ source->Smass += massadded; @@ -888,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]; } } } @@ -923,7 +1052,7 @@ void release(long dt) v = q*dt; /* Include source contribution in quality released from node. */ - c = C[n] + X[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.*/ @@ -952,7 +1081,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) +** (TempQual[n] = concen. added by source at node n) **--------------------------------------------------- */ { @@ -968,13 +1097,13 @@ void updatesourcenodes(long dt) if (source == NULL) continue; /* Add source to current node concen. */ - C[n] += X[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 */ @@ -997,21 +1126,22 @@ 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; + NodeQual[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; + } + } } } @@ -1043,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; //} @@ -1068,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. */ @@ -1081,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 ***/ @@ -1118,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; @@ -1174,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; } @@ -1209,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]; @@ -1250,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) @@ -1300,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; @@ -1368,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; } @@ -1423,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. ); } @@ -1443,8 +1573,8 @@ void ratecoeffs() { kw = Link[k].Kw; if (kw != 0.0) kw = piperate(k); - Link[k].R = kw; - R[k] = 0.0; + Link[k].Rc = kw; + PipeRateCoeff[k] = 0.0; } } /* End of ratecoeffs */ @@ -1526,7 +1656,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/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/testLemonTiger.cpp b/src/testLemonTiger.cpp new file mode 100755 index 0000000..0863e9a --- /dev/null +++ b/src/testLemonTiger.cpp @@ -0,0 +1,332 @@ +#include +#include +#include +#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; +} nodeState_t; + +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 + + + +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[]) { + + // create storage structures for results. + result_t epanetResults, lemonTigerResults; + + cout << "Lemon Tiger TEST" << endl + << "________________" << endl; + + + long simulationTime = 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], (char*)""), "ENopen" ); + + checkErr( ENopenH(), "ENopenH" ); + checkErr( ENinitH(EN_SAVE), "ENinitH" ); + + cout << "Running hydraulics..." << endl; + do { + + /* Solve for hydraulics & advance to next time period */ + checkErr( ENrunH(&simulationTime), "ENrunH" ); + checkErr( ENnextH(&nextEventH), "ENnextH" ); + + // gather hydraulic results + saveHydResults(&epanetResults[simulationTime]); + + + + } while (nextEventH > 0); + // hydraulics are done + checkErr( ENcloseH(), "ENcloseH" ); + cout << "\t\t\tdone." << endl; + cout << "Running WQ..." << endl; + + checkErr( ENopenQ(), "ENopenQ" ); + checkErr( ENinitQ(EN_NOSAVE), "ENinitQ" ); + + do { + + checkErr( ENrunQ(&simulationTime), "ENrunQ" ); + checkErr( ENnextQ(&nextEventH), "ENstepQ" ); + + // gather quality results + saveQualResults(&epanetResults[simulationTime]); + + } while (nextEventH > 0); + // water quality is done + checkErr( ENcloseQ(), "ENcloseQ" ); + cout << "\t\t\tdone." << endl; + + // 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], (char*)""), "ENopen" ); + + checkErr( ENopenH(), "ENopenH" ); + checkErr( ENinitH(EN_NOSAVE), "ENinitH" ); + checkErr( ENopenQ(), "ENopenQ" ); + checkErr( ENinitQ(EN_NOSAVE), "ENinitQ" ); + + cout << "Running stepwise hydraulics and water quality..." << endl; + do { + /* 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; + + // all done + checkErr( ENcloseH(), "ENcloseH" ); + checkErr( ENcloseQ(), "ENcloseQ" ); + checkErr( ENclose(), "ENclose" ); + + + // summarize the results + printResults(&epanetResults, &lemonTigerResults, cout); + compare(&epanetResults, &lemonTigerResults, cout); + + } catch (int err) { + cerr << "exiting with error " << err << endl; + } +} + + +void saveHydResults(networkState_t* networkState) { + int nNodes, nLinks; + float head, demand, flow; + ENgetcount(EN_NODECOUNT, &nNodes); + ENgetcount(EN_LINKCOUNT, &nLinks); + for (int iNode = 1; iNode <= nNodes; ++iNode) { + ENgetnodevalue(iNode, EN_HEAD, &head); + ENgetnodevalue(iNode, EN_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; + } +} + + +void saveQualResults(networkState_t* networkState) { + int nNodes; + float quality; + ENgetcount(EN_NODECOUNT, &nNodes); + + for (int iNode = 1; iNode <= nNodes; iNode++) { + ENgetnodevalue(iNode, EN_QUALITY, &quality); + (*networkState).nodeState[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 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()) { + // 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; + // 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 + networkNodeState_t::const_iterator 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; + 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 = networkLinkState1.begin(); networkLinkIterator != networkLinkState1.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; + char errmsg[1024]; + ENgeterror(err, errmsg, 1024); + cerr << errmsg << endl; + throw err; + } +} diff --git a/src/testLemonTiger.h b/src/testLemonTiger.h new file mode 100755 index 0000000..5c1cc2f --- /dev/null +++ b/src/testLemonTiger.h @@ -0,0 +1,15 @@ +// +// testLemonTiger.h +// epanet +// +// Created by Sam Hatchett on 2/1/13. +// +// + +#ifndef __epanet__testLemonTiger__ +#define __epanet__testLemonTiger__ + +#include +#include + +#endif /* defined(__epanet__testLemonTiger__) */ 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 c125b26..6078898 100755 --- a/src/toolkit.h +++ b/src/toolkit.h @@ -1,255 +1,255 @@ -/* -******************************************************************* - -TOOLKIT.H - Prototypes for EPANET Functions Exported to DLL Toolkit - -VERSION: 2.00 -DATE: 5/8/00 - 10/25/00 - 3/1/01 - 8/15/07 (2.00.11) - 2/14/08 (2.00.12) -AUTHOR: L. Rossman - US EPA - NRMRL - -******************************************************************* -*/ - - -#ifndef DLLEXPORT - #ifdef DLL - #ifdef __cplusplus - #define DLLEXPORT extern "C" __declspec(dllexport) - #else +/* +******************************************************************* + +TOOLKIT.H - Prototypes for EPANET Functions Exported to DLL Toolkit + +VERSION: 2.00 +DATE: 5/8/00 + 10/25/00 + 3/1/01 + 8/15/07 (2.00.11) + 2/14/08 (2.00.12) +AUTHOR: L. Rossman + US EPA - NRMRL + +******************************************************************* +*/ + + +#ifndef DLLEXPORT + #ifdef DLL + #ifdef __cplusplus + #define DLLEXPORT extern "C" __declspec(dllexport) + #else #define DLLEXPORT __declspec(dllexport) __stdcall - #endif - #elif defined(CYGWIN) - #define DLLEXPORT __stdcall - #else - #ifdef __cplusplus - #define DLLEXPORT - #else - #define DLLEXPORT - #endif - #endif -#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 -#define EN_MAXVOLUME 25 - -#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_LINKPATTERN 15 - -#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_HTIME 11 -#define EN_HALTFLAG 12 -#define EN_NEXTEVENT 13 - -#define EN_ITERATIONS 0 -#define EN_RELATIVEERROR 1 - -#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 /* See LinkType in TYPES.H */ -#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 /* See QualType in TYPES.H */ -#define EN_AGE 2 -#define EN_TRACE 3 - -#define EN_CONCEN 0 /* Source quality types. */ -#define EN_MASS 1 /* See SourceType in TYPES.H. */ -#define EN_SETPOINT 2 -#define EN_FLOWPACED 3 - -#define EN_CFS 0 /* Flow units types. */ -#define EN_GPM 1 /* See FlowUnitsType */ -#define EN_MGD 2 /* in TYPES.H. */ -#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 /* See ControlType */ -#define EN_TIMER 2 /* in TYPES.H. */ -#define EN_TIMEOFDAY 3 - -#define EN_AVERAGE 1 /* Time statistic types. */ -#define EN_MINIMUM 2 /* See TstatType in TYPES.H */ -#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 flows flag */ - -#define EN_CONST_HP 0 /* constant horsepower */ -#define EN_POWER_FUNC 1 /* power function */ -#define EN_CUSTOM 2 /* user-defined custom curve */ - -// --- Declare the EPANET toolkit functions -#if defined(__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 ENgetstatistic(int code, int* value); - - 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 ENgetheadcurve(int, char *); - int DLLEXPORT ENgetpumptype(int, int *); - - 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 *); - -#if defined(__cplusplus) -} -#endif + #endif + #elif defined(CYGWIN) + #define DLLEXPORT __stdcall + #else + #ifdef __cplusplus + #define DLLEXPORT + #else + #define DLLEXPORT + #endif + #endif +#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 +#define EN_MAXVOLUME 25 + +#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_LINKPATTERN 15 + +#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_HTIME 11 +#define EN_HALTFLAG 12 +#define EN_NEXTEVENT 13 + +#define EN_ITERATIONS 0 +#define EN_RELATIVEERROR 1 + +#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 /* See LinkType in TYPES.H */ +#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 /* See QualType in TYPES.H */ +#define EN_AGE 2 +#define EN_TRACE 3 + +#define EN_CONCEN 0 /* Source quality types. */ +#define EN_MASS 1 /* See SourceType in TYPES.H. */ +#define EN_SETPOINT 2 +#define EN_FLOWPACED 3 + +#define EN_CFS 0 /* Flow units types. */ +#define EN_GPM 1 /* See FlowUnitsType */ +#define EN_MGD 2 /* in TYPES.H. */ +#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 /* See ControlType */ +#define EN_TIMER 2 /* in TYPES.H. */ +#define EN_TIMEOFDAY 3 + +#define EN_AVERAGE 1 /* Time statistic types. */ +#define EN_MINIMUM 2 /* See TstatType in TYPES.H */ +#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 flows flag */ + +#define EN_CONST_HP 0 /* constant horsepower */ +#define EN_POWER_FUNC 1 /* power function */ +#define EN_CUSTOM 2 /* user-defined custom curve */ + +// --- Declare the EPANET toolkit functions +#if defined(__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 ENgetstatistic(int code, int* value); + + 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 ENgetheadcurve(int, char *); + int DLLEXPORT ENgetpumptype(int, int *); + + 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 *); + +#if defined(__cplusplus) +} +#endif diff --git a/src/types.h b/src/types.h index 68a495e..3119edd 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). */ @@ -26,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) /* @@ -35,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 */ @@ -165,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 */ @@ -206,6 +215,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 +461,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..77b7284 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 */ @@ -70,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 */ @@ -81,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 */ @@ -91,7 +99,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 +128,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 +141,38 @@ 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 *LinkStatus, /* Link status */ *OldStat; /* Previous link/tank status */ -EXTERN 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 */ - *R, /* Pipe reaction rate */ - *X; /* General purpose array */ -EXTERN double *H; /* Node heads */ + *PipeRateCoeff, /* Pipe reaction rate */ + *X, /* General purpose array */ + *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 */ 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 */ 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 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 @@ -180,18 +194,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.inp b/test/Net3.inp new file mode 100755 index 0000000..8e39dd1 --- /dev/null +++ b/test/Net3.inp @@ -0,0 +1,481 @@ +[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/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] diff --git a/test/simplenet.inp b/test/simplenet.inp new file mode 100755 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]