Replaced the Doxygen files in the doc folder (issue #373)

This commit is contained in:
Lew Rossman
2019-01-24 10:51:37 -05:00
parent 2626ab9982
commit 821d13497f
28 changed files with 31089 additions and 282 deletions

15958
doc/DataFlow.eps Normal file

File diff suppressed because it is too large Load Diff

BIN
doc/DataFlow.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

195
doc/DoxygenLayout.xml Normal file
View File

@@ -0,0 +1,195 @@
<doxygenlayout version="1.0">
<!-- Generated by doxygen 1.8.10 -->
<!-- Navigation index tabs for HTML output -->
<navindex>
<tab type="mainpage" visible="yes" title=""/>
<tab type="pages" visible="yes" title="" intro=""/>
<tab type="modules" visible="yes" title="Reference"
intro="These topics describe the Toolkit's functions, symbolic constants, and other details related to its usage."/>
<tab type="namespaces" visible="yes" title="">
<tab type="namespacelist" visible="yes" title="" intro=""/>
<tab type="namespacemembers" visible="yes" title="" intro=""/>
</tab>
<tab type="classes" visible="yes" title="">
<tab type="classlist" visible="yes" title="" intro=""/>
<tab type="classindex" visible="$ALPHABETICAL_INDEX" title=""/>
<tab type="hierarchy" visible="yes" title="" intro=""/>
<tab type="classmembers" visible="yes" title="" intro=""/>
</tab>
<tab type="files" visible="no" title="">
<tab type="filelist" visible="no" title="" intro=""/>
<tab type="globals" visible="no" title="" intro=""/>
</tab>
<tab type="examples" visible="yes" title="" intro=""/>
</navindex>
<!-- Layout definition for a class page -->
<class>
<briefdescription visible="yes"/>
<includes visible="$SHOW_INCLUDE_FILES"/>
<inheritancegraph visible="$CLASS_GRAPH"/>
<collaborationgraph visible="$COLLABORATION_GRAPH"/>
<memberdecl>
<nestedclasses visible="yes" title=""/>
<publictypes title=""/>
<services title=""/>
<interfaces title=""/>
<publicslots title=""/>
<signals title=""/>
<publicmethods title=""/>
<publicstaticmethods title=""/>
<publicattributes title=""/>
<publicstaticattributes title=""/>
<protectedtypes title=""/>
<protectedslots title=""/>
<protectedmethods title=""/>
<protectedstaticmethods title=""/>
<protectedattributes title=""/>
<protectedstaticattributes title=""/>
<packagetypes title=""/>
<packagemethods title=""/>
<packagestaticmethods title=""/>
<packageattributes title=""/>
<packagestaticattributes title=""/>
<properties title=""/>
<events title=""/>
<privatetypes title=""/>
<privateslots title=""/>
<privatemethods title=""/>
<privatestaticmethods title=""/>
<privateattributes title=""/>
<privatestaticattributes title=""/>
<friends title=""/>
<related title="" subtitle=""/>
<membergroups visible="yes"/>
</memberdecl>
<detaileddescription title=""/>
<memberdef>
<inlineclasses title=""/>
<typedefs title=""/>
<enums title=""/>
<services title=""/>
<interfaces title=""/>
<constructors title=""/>
<functions title=""/>
<related title=""/>
<variables title=""/>
<properties title=""/>
<events title=""/>
</memberdef>
<allmemberslink visible="yes"/>
<usedfiles visible="$SHOW_USED_FILES"/>
<authorsection visible="yes"/>
</class>
<!-- Layout definition for a namespace page -->
<namespace>
<briefdescription visible="yes"/>
<memberdecl>
<nestednamespaces visible="yes" title=""/>
<constantgroups visible="yes" title=""/>
<classes visible="yes" title=""/>
<typedefs title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
<membergroups visible="yes"/>
</memberdecl>
<detaileddescription title=""/>
<memberdef>
<inlineclasses title=""/>
<typedefs title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
</memberdef>
<authorsection visible="yes"/>
</namespace>
<!-- Layout definition for a file page -->
<file>
<briefdescription visible="yes"/>
<includes visible="$SHOW_INCLUDE_FILES"/>
<includegraph visible="$INCLUDE_GRAPH"/>
<includedbygraph visible="$INCLUDED_BY_GRAPH"/>
<sourcelink visible="yes"/>
<memberdecl>
<classes visible="yes" title=""/>
<namespaces visible="yes" title=""/>
<constantgroups visible="yes" title=""/>
<defines title=""/>
<typedefs title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
<membergroups visible="yes"/>
</memberdecl>
<detaileddescription title=""/>
<memberdef>
<inlineclasses title=""/>
<defines title=""/>
<typedefs title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
</memberdef>
<authorsection/>
</file>
<!-- Layout definition for a group page -->
<group>
<briefdescription visible="yes"/>
<groupgraph visible="$GROUP_GRAPHS"/>
<memberdecl>
<nestedgroups visible="yes" title="File Sections"/>
<dirs visible="yes" title=""/>
<files visible="yes" title=""/>
<namespaces visible="yes" title=""/>
<classes visible="yes" title=""/>
<defines title=""/>
<typedefs title=""/>
<enums title=""/>
<enumvalues title=""/>
<functions title=""/>
<variables title=""/>
<signals title=""/>
<publicslots title=""/>
<protectedslots title=""/>
<privateslots title=""/>
<events title=""/>
<properties title=""/>
<friends title=""/>
<membergroups visible="yes"/>
</memberdecl>
<detaileddescription title="Overview"/>
<memberdef>
<pagedocs/>
<inlineclasses title=""/>
<defines title=""/>
<typedefs title=""/>
<enums title=""/>
<enumvalues title=""/>
<functions title=""/>
<variables title=""/>
<signals title=""/>
<publicslots title=""/>
<protectedslots title=""/>
<privateslots title=""/>
<events title=""/>
<properties title=""/>
<friends title=""/>
</memberdef>
<authorsection visible="yes"/>
</group>
<!-- Layout definition for a directory page -->
<directory>
<briefdescription visible="yes"/>
<directorygraph visible="yes"/>
<memberdecl>
<dirs visible="yes"/>
<files visible="yes"/>
</memberdecl>
<detaileddescription title=""/>
</directory>
</doxygenlayout>

5118
doc/Example2.eps Normal file

File diff suppressed because it is too large Load Diff

BIN
doc/Example2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

View File

@@ -1,43 +0,0 @@
/**
@page how-to-use How to Use the Toolkit
The following topics briefly describe how to accomplish some basic tasks for which the Toolkit would be used. See the Example Applications topic for code listings of complete applications of the Toolkit.
@section open-close Opening and Closing the Toolkit
The Toolkit must open an EPANET [Input File](Input-File) to obtain a description of the pipe network to be analyzed before any of its other functions can be called. (The exception to this is the @ref ENepanet function, which performs a complete hydraulic/water quality simulation similar to a command line execution of EPANET). Once all analysis is completed, it must close itself down to free all allocated memory. The functions for doing this are @ref ENopen and @ref ENclose, respectively. An example of using these functions is shown below.
~~~~~~~~~~~~~~~{.c}
char *f1, // Name of input file
*f2, // name of report file
*f3; // name of output file (can be blank)
int errcode;
errcode = ENopen(f1, f2, f3);
if (errcode > 0) {
ENclose();
return;
}
{ Call functions that perform desired analysis }
ENclose();
~~~~~~~~~~~~~~~
@section parameters Retrieving and Setting Network Parameters
The Toolkit has various functions available for retrieving and setting the parameters that define the design and operation of the pipe network being analyzed. The names of retrieval functions all begin with `ENget` (e.g., [ENgetnodevalue](ENgetnodevalue), [ENgetoption](ENgetoption), etc.) while the functions used for setting parameter values begin with `ENset` (e.g., [ENsetnodevalue](ENsetnodevalue), [ENsetoption](ENsetoption), etc.).
Most of these functions use an index number to reference a specific network component (such as a node, link, or time pattern). This number is simply the position of the component in the list of all components of similar type (e.g., node 10 is the tenth node, starting from 1, in the network) and is not the same as the ID label assigned to the component in the Input File being processed. A series of functions exist to determine a component's index number given its ID label (see [ENgetlinkindex](ENgetlinkindex), [ENgetnodeindex](ENgetnodeindex), and [ENgetpatternindex](ENgetpatternindex)). Likewise, functions exist to retrieve a component's ID label given its index number (see [ENgetlinkid](ENgetlinkid), [ENgetnodeid](ENgetnodeid), and [ENgetpatternid](ENgetpatternid)). The [ENgetcount](ENgetcount) function can be used to determine the number of different components in the network.
The code below is an example of using the parameter retrieval and setting functions. It changes all pipes with diameter of 10 inches to 12 inches.
~~~~~~~~~~~~~~~{.c}
int i, Nlinks;
float D;
ENgetcount(EN_LINKCOUNT, &Nlinks);
for (i = 1; i <= Nlinks; i++) {
ENgetlinkvalue(i, EN_DIAMETER, &D);
if (D == 10) ENsetlinkvalue(i, EN_DIAMETER, 12);
}
~~~~~~~~~~~~~~~
*/

8420
doc/Network.eps Normal file

File diff suppressed because it is too large Load Diff

BIN
doc/Network.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View File

@@ -1,23 +0,0 @@
/**
@page toolkit-overview Toolkit Overview
The Programmer's Toolkit is an extension of the EPANET simulation package. EPANET performs extended period simulation of hydraulic and water quality behavior within pressurized pipe networks. A network can consist of pipes, nodes (pipe junctions), pumps, valves and storage tanks or reservoirs. EPANET tracks the flow of water in each pipe, the pressure at each node, the height of water in each tank, and the concentration of a chemical species throughout the network during a multi-time period simulation. In addition to chemical species, water age and source tracing can also be simulated.
The Toolkit provides a series of functions that allow programmers to customize the use of EPANET's hydraulic and water quality solution engine to their own applications. Before using the Toolkit one should become familiar with the way that EPANET represents a pipe network and the design and operating information it requires to perform a simulation. This information can be obtained from reading EPANET's on-line Help file or from the EPANET Users Manual.
A typical usage of the Toolkit functions to analyze a distribution system might look as follows:
1. Use the @ref ENopen function to open the Toolkit system, along with an EPANET [Input file](Input-File).
2. Use the `ENsetxxx` series of functions to change selected system characteristics.
3. Run a full hydraulic simulation using the @ref ENsolveH function (which automatically saves results to a [Hydraulics file](Hydraulics-File)) or use the @ref ENopenH - @ref ENinitH - @ref ENrunH - @ref ENnextH - @ref ENcloseH series of functions to step through a hydraulic simulation, accessing results along the way with the `ENgetxxx` series of functions.
4. Run a full water quality simulation using @ref ENsolveQ (which automatically saves hydraulic and water quality results to an [Output file](Output-File)) or use the @ref ENopenQ - @ref ENinitQ - @ref ENrunQ - @ref ENnextQ (or @ref ENstepQ) - @ref ENcloseQ series of functions to step through a water quality simulation, accessing results along the way with the `ENgetxxx` series of functions.
5. Return to Step 2 to run additional analyses or use the @ref ENreport function to write a formatted report to the [Report file](Report-File).
6. Call the @ref ENclose function to close all files and release system memory.
More specific examples of using the functions can be found in the [Example Applications](Example-Applications) topic.
- @subpage how-to-use
*/

View File

@@ -1,4 +1,4 @@
# Doxyfile 1.8.11
# Doxyfile 1.8.10
# This file describes the settings to be used by the documentation system
# doxygen (www.doxygen.org) for a project.
@@ -32,13 +32,13 @@ DOXYFILE_ENCODING = UTF-8
# title of most generated pages and in a few other places.
# The default value is: My Project.
PROJECT_NAME = EPANET
PROJECT_NAME = "OWA-EPANET Toolkit"
# The PROJECT_NUMBER tag can be used to enter a project or revision number. This
# could be handy for archiving the generated documentation or if some version
# control system is used.
PROJECT_NUMBER = 2.1
PROJECT_NUMBER = 2.2
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a
@@ -58,7 +58,7 @@ PROJECT_LOGO =
# entered, it will be relative to the location where doxygen was started. If
# left blank the current directory will be used.
OUTPUT_DIRECTORY = ../epanet-owa-dox
OUTPUT_DIRECTORY =
# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub-
# directories (in 2 levels) under the output directory of each output format and
@@ -226,7 +226,7 @@ SEPARATE_MEMBER_PAGES = NO
# uses this value to replace tabs by spaces in code fragments.
# Minimum value: 1, maximum value: 16, default value: 4.
TAB_SIZE = 2
TAB_SIZE = 4
# This tag can be used to specify a number of aliases that act as commands in
# the documentation. An alias has the form:
@@ -694,7 +694,7 @@ FILE_VERSION_FILTER =
# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE
# tag is left empty.
LAYOUT_FILE =
LAYOUT_FILE = DoxygenLayout.xml
# The CITE_BIB_FILES tag can be used to specify one or more bib files containing
# the reference definitions. This must be a list of .bib files. The .bib
@@ -749,12 +749,6 @@ WARN_IF_DOC_ERROR = YES
WARN_NO_PARAMDOC = NO
# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when
# a warning is encountered.
# The default value is: NO.
WARN_AS_ERROR = NO
# The WARN_FORMAT tag determines the format of the warning messages that doxygen
# can produce. The string should contain the $file, $line, and $text tags, which
# will be replaced by the file and line number from which the warning originated
@@ -781,10 +775,13 @@ WARN_LOGFILE =
# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
# Note: If this tag is empty the current directory is searched.
INPUT = ../include \
../src \
../doc \
../
INPUT = main.dox \
toolkit-usage.dox \
toolkit-examples.dox \
modules.dox \
../include/epanet2_2.h \
../include/epanet2_enums.h \
output-format.dox
# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
@@ -806,8 +803,8 @@ INPUT_ENCODING = UTF-8
# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp,
# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h,
# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc,
# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.pyw, *.f90, *.f, *.for, *.tcl,
# *.vhd, *.vhdl, *.ucf, *.qsf, *.as and *.js.
# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.f90, *.f, *.for, *.tcl, *.vhd,
# *.vhdl, *.ucf, *.qsf, *.as and *.js.
FILE_PATTERNS = *.c \
*.cc \
@@ -856,7 +853,7 @@ FILE_PATTERNS = *.c \
# be searched for input files as well.
# The default value is: NO.
RECURSIVE = NO
RECURSIVE = YES
# The EXCLUDE tag can be used to specify files and/or directories that should be
# excluded from the INPUT source files. This way you can easily exclude a
@@ -918,7 +915,7 @@ EXAMPLE_RECURSIVE = NO
# that contain images that are to be included in the documentation (see the
# \image command).
IMAGE_PATH =
IMAGE_PATH = .
# The INPUT_FILTER tag can be used to specify a program that doxygen should
# invoke to filter for each input file. Doxygen will invoke the filter program
@@ -934,10 +931,6 @@ IMAGE_PATH =
# Note that the filter must not add or remove lines; it is applied before the
# code is scanned, but not when the output code is generated. If lines are added
# or removed, the anchors will not be placed correctly.
#
# Note that for custom extensions or not directly supported extensions you also
# need to set EXTENSION_MAPPING for the extension otherwise the files are not
# properly processed by doxygen.
INPUT_FILTER =
@@ -947,10 +940,6 @@ INPUT_FILTER =
# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how
# filters are used. If the FILTER_PATTERNS tag is empty or if none of the
# patterns match the file name, INPUT_FILTER is applied.
#
# Note that for custom extensions or not directly supported extensions you also
# need to set EXTENSION_MAPPING for the extension otherwise the files are not
# properly processed by doxygen.
FILTER_PATTERNS =
@@ -1068,7 +1057,7 @@ VERBATIM_HEADERS = YES
# rich C++ code for which doxygen's built-in parser lacks the necessary type
# information.
# Note: The availability of this option depends on whether or not doxygen was
# generated with the -Duse-libclang=ON option for CMake.
# compiled with the --with-libclang option.
# The default value is: NO.
CLANG_ASSISTED_PARSING = NO
@@ -1122,7 +1111,7 @@ GENERATE_HTML = YES
# The default directory is: html.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_OUTPUT = ../../epanet-owa-dox
HTML_OUTPUT = html
# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each
# generated HTML page (for example: .htm, .php, .asp).
@@ -1159,7 +1148,7 @@ HTML_HEADER =
# that doxygen normally uses.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_FOOTER =
HTML_FOOTER = newfooter.html
# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style
# sheet that is used by each HTML page. It can be used to fine-tune the look of
@@ -1184,7 +1173,7 @@ HTML_STYLESHEET =
# list). For an example see the documentation.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_EXTRA_STYLESHEET =
HTML_EXTRA_STYLESHEET = extrastylesheet.css
# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
# other source files which should be copied to the HTML output directory. Note
@@ -1323,7 +1312,7 @@ GENERATE_HTMLHELP = NO
# written to the html output directory.
# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
CHM_FILE =
CHM_FILE = owa_epanet.chm
# The HHC_LOCATION tag can be used to specify the location (absolute path
# including file name) of the HTML help compiler (hhc.exe). If non-empty,
@@ -1331,7 +1320,7 @@ CHM_FILE =
# The file has to be specified with full path.
# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
HHC_LOCATION =
HHC_LOCATION = "c:\Program Files (x86)\HTML Help Workshop\hhc.exe"
# The GENERATE_CHI flag controls if a separate .chi index file is generated
# (YES) or that it should be included in the master .chm file (NO).
@@ -1453,7 +1442,7 @@ ECLIPSE_DOC_ID = org.doxygen.Project
# The default value is: NO.
# This tag requires that the tag GENERATE_HTML is set to YES.
DISABLE_INDEX = NO
DISABLE_INDEX = YES
# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
# structure should be generated to display hierarchical information. If the tag
@@ -1480,7 +1469,7 @@ GENERATE_TREEVIEW = YES
# Minimum value: 0, maximum value: 20, default value: 4.
# This tag requires that the tag GENERATE_HTML is set to YES.
ENUM_VALUES_PER_LINE = 4
ENUM_VALUES_PER_LINE = 0
# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used
# to set the initial width (in pixels) of the frame in which the tree is shown.
@@ -1658,7 +1647,7 @@ EXTRA_SEARCH_MAPPINGS =
# If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX output.
# The default value is: YES.
GENERATE_LATEX = NO
GENERATE_LATEX = yes
# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a
# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
@@ -1729,7 +1718,7 @@ EXTRA_PACKAGES =
# to HTML_HEADER.
# This tag requires that the tag GENERATE_LATEX is set to YES.
LATEX_HEADER =
LATEX_HEADER = header.tex
# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the
# generated LaTeX document. The footer should contain everything after the last
@@ -1792,7 +1781,7 @@ LATEX_BATCHMODE = NO
# The default value is: NO.
# This tag requires that the tag GENERATE_LATEX is set to YES.
LATEX_HIDE_INDICES = NO
LATEX_HIDE_INDICES = YES
# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source
# code with syntax highlighting in the LaTeX output.
@@ -1812,14 +1801,6 @@ LATEX_SOURCE_CODE = NO
LATEX_BIB_STYLE = plain
# If the LATEX_TIMESTAMP tag is set to YES then the footer of each generated
# page will contain the date and time when the page was generated. Setting this
# to NO can help when comparing the output of multiple runs.
# The default value is: NO.
# This tag requires that the tag GENERATE_LATEX is set to YES.
LATEX_TIMESTAMP = NO
#---------------------------------------------------------------------------
# Configuration options related to the RTF output
#---------------------------------------------------------------------------
@@ -2059,7 +2040,7 @@ MACRO_EXPANSION = YES
# The default value is: NO.
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
EXPAND_ONLY_PREDEF = YES
EXPAND_ONLY_PREDEF = NO
# If the SEARCH_INCLUDES tag is set to YES, the include files in the
# INCLUDE_PATH will be searched if a #include is found.
@@ -2175,7 +2156,7 @@ PERL_PATH = /usr/bin/perl
# powerful graphs.
# The default value is: YES.
CLASS_DIAGRAMS = YES
CLASS_DIAGRAMS = NO
# You can define message sequence charts within doxygen comments using the \msc
# command. Doxygen will then run the mscgen tool (see:

2
doc/extrastylesheet.css Normal file
View File

@@ -0,0 +1,2 @@
h1 { font-size:1.5em; }

12
doc/footer.tex Normal file
View File

@@ -0,0 +1,12 @@
% Latex footer for doxygen 1.8.10
%--- End generated contents ---
% Index
\backmatter
\newpage
\phantomsection
\clearemptydoublepage
\addcontentsline{toc}{chapter}{Index}
\printindex
\end{document}

141
doc/header.tex Normal file
View File

@@ -0,0 +1,141 @@
% Latex header for doxygen 1.8.10
\documentclass[twoside]{book}
% Packages required by doxygen
\usepackage{fixltx2e}
\usepackage{calc}
\usepackage{doxygen}
\usepackage[export]{adjustbox} % also loads graphicx
\usepackage{graphicx}
\usepackage[utf8]{inputenc}
\usepackage{makeidx}
\usepackage{multicol}
\usepackage{multirow}
\PassOptionsToPackage{warn}{textcomp}
\usepackage{textcomp}
\usepackage[nointegrals]{wasysym}
\usepackage[table]{xcolor}
% Font selection
\usepackage[T1]{fontenc}
\usepackage[scaled=.90]{helvet}
\usepackage{courier}
\usepackage{amssymb}
\usepackage{sectsty}
\renewcommand{\familydefault}{\sfdefault}
\allsectionsfont{%
\fontseries{bc}\selectfont%
\color{darkgray}%
}
\renewcommand{\DoxyLabelFont}{%
\fontseries{bc}\selectfont%
\color{darkgray}%
}
\newcommand{\+}{\discretionary{\mbox{\scriptsize$\hookleftarrow$}}{}{}}
% Page & text layout
\usepackage{geometry}
\geometry{%
a4paper,%
top=2.5cm,%
bottom=2.5cm,%
left=2.5cm,%
right=2.5cm%
}
\tolerance=750
\hfuzz=15pt
\hbadness=750
\setlength{\emergencystretch}{15pt}
\setlength{\parindent}{0cm}
\setlength{\parskip}{0.2cm}
\makeatletter
\renewcommand{\paragraph}{%
\@startsection{paragraph}{4}{0ex}{-1.0ex}{1.0ex}{%
\normalfont\normalsize\bfseries\SS@parafont%
}%
}
\renewcommand{\subparagraph}{%
\@startsection{subparagraph}{5}{0ex}{-1.0ex}{1.0ex}{%
\normalfont\normalsize\bfseries\SS@subparafont%
}%
}
\makeatother
% Headers & footers
\usepackage{fancyhdr}
\pagestyle{fancyplain}
\fancyhead[LE]{\fancyplain{}{\bfseries\thepage}}
\fancyhead[CE]{\fancyplain{}{}}
\fancyhead[RE]{\fancyplain{}{\bfseries\leftmark}}
\fancyhead[LO]{\fancyplain{}{\bfseries\rightmark}}
\fancyhead[CO]{\fancyplain{}{}}
\fancyhead[RO]{\fancyplain{}{\bfseries\thepage}}
\fancyfoot[LE]{\fancyplain{}{}}
\fancyfoot[CE]{\fancyplain{}{}}
\fancyfoot[RE]{\fancyplain{}{\bfseries\scriptsize OWA-EPANET 2.2 \textcopyright 2019}}
\fancyfoot[LO]{\fancyplain{}{\bfseries\scriptsize OWA-EPANET 2.2 \textcopyright 2019}}
\fancyfoot[CO]{\fancyplain{}{}}
\fancyfoot[RO]{\fancyplain{}{}}
\renewcommand{\footrulewidth}{0.4pt}
\renewcommand{\chaptermark}[1]{%
\markboth{#1}{}%
}
\renewcommand{\sectionmark}[1]{%
\markright{\thesection\ #1}%
}
% Indices & bibliography
\usepackage{natbib}
\usepackage[titles]{tocloft}
\setcounter{tocdepth}{1}
\setcounter{secnumdepth}{5}
\makeindex
% Hyperlinks (required, but should be loaded last)
\usepackage{ifpdf}
\ifpdf
\usepackage[pdftex,pagebackref=true]{hyperref}
\else
\usepackage[ps2pdf,pagebackref=true]{hyperref}
\fi
\hypersetup{%
colorlinks=true,%
linkcolor=blue,%
citecolor=blue,%
unicode%
}
% Custom commands
\newcommand{\clearemptydoublepage}{%
\newpage{\pagestyle{empty}\cleardoublepage}%
}
%===== C O N T E N T S =====
\begin{document}
% Titlepage & ToC
\hypersetup{pageanchor=false,
bookmarks=true,
bookmarksnumbered=true,
pdfencoding=unicode
}
\pagenumbering{roman}
\begin{titlepage}
\vspace*{7cm}
\begin{center}%
{\Large OWA-EPANET Toolkit\linebreak\linebreak 2.2}\\
\vspace*{1cm}
{\large January 2019}\\
%\vspace*{0.5cm}
%{\small Wed Jan 23 2019 17:57:36}\\
\end{center}
\end{titlepage}
\clearemptydoublepage
\tableofcontents
\clearemptydoublepage
\pagenumbering{arabic}
\hypersetup{pageanchor=true}
%--- Begin generated contents ---

View File

@@ -1,12 +1,98 @@
/**
@mainpage EPANET Open Source
@mainpage Overview
The EPANET Open-Source Library is a pressurized pipe network hydraulic and water quality analysis toolkit, originally developed by USEPA, written in C.
EPANET is a program that performs extended period simulation of hydraulic and water quality behavior within pressurized pipe networks. A network can consist of pipes, nodes (pipe junctions), pumps, valves and storage tanks or reservoirs. EPANET tracks the flow of water in each pipe, the pressure at each node, the height of water in each tank, and the concentration of a chemical species throughout the network during a multi-time period simulation. In addition to chemical species, water age and source tracing can also be simulated. The EPANET Programmer's Toolkit is a library of functions (or API) that allow programmers to customize the use of EPANET's hydraulic and water quality solution engine to their own applications. Both EPANET and its toolkit were originally developed and are currently maintained by the U.S. Environmental Protection Agency (USEPA).
__Note:__ This repository is not affiliated with, or endorsed by, the USEPA. For the "official" release of EPANET (2.00.12 UI and Toolkit) please go to the [EPA's GitHub repo](https://github.com/USEPA/Water-Distribution-Network-Model) or [the USEPA website](http://www2.epa.gov/water-research/epanet). It is also not the graphical user interface version. This is the hydraulic and water quality solver engine.
The OWA-EPANET Toolkit is an open-source version of the original EPANET Toolkit that extends its capabilities by:
- providing a full set of functions to set and retrieve values for all parameters contained in a network model
- allowing networks to be built completely from function calls instead of from an input file
- allowing multiple projects to be analyzed in parallel in a thread-safe manner
- adding the ability to use pressure dependent demands in hydraulic analyses
- producing more robust results with regard to hydraulic convergence, low/zero flow conditions, and water quality mass balance
- achieving faster run times for hydraulic analyses.
However, if you are interested in extending EPANET for academic, personal, or commercial use, then you've come to the right place. For community discussion, FAQ, and roadmapping of the project, go to the [Community Forum](http://community.wateranalytics.org/category/epanet).
Before using the OWA-EPANET Toolkit one should be familiar with the way that EPANET represents a pipe network, the design and operating information it requires, and the steps it uses to simulate a network's behavior. The following topics provide some introductory material on these subjects:
- @subpage DataModel "Network Data Model"
- @subpage DataFlow "Data Flow Diagram"
- @subpage ToolkitVersions "Toolkit Versions"
- @subpage toolkit-overview "Toolkit Overview"
More detailed information can be obtained from reading the <a href="https://nepis.epa.gov/Adobe/PDF/P1007WWU.pdf">EPANET 2 Users Manual</a>.
__Note:__ OWA (Open Water Analytics) exists on GitHub as an open community for the exchange of information and ideas related to computing in the water & wastewater industries. It's activities and code projects are neither affiliated with nor endorsed by the USEPA.
*/
/**
@page DataModel Network Data Model
EPANET models a pipe network as a collection of links connected to nodes. The links represent pipes, pumps, and control valves. The nodes represent junctions, tanks, and reservoirs. The figure below illustrates how these objects can be connected to one another to form a network.
@image html Network.png
@image latex Network.eps
Junctions have a user-supplied water withdrawal rate (i.e., consumer demand) associated with them. Tanks are storage units whose water level changes over time. Reservoirs are boundary points where a fixed hydraulic head applies.
Pipes have a length, diameter and roughness coefficient that determines their head loss as a function of flow rate. Pumps have either a constant power rating or a head curve that determines the head they add as a function of flow rate. Valves are used to regulate either flow or pressure. Controls can be applied to completely open or close a link or to adjust its setting (pump speed or valve setting).
In addition to these physical objects an EPANET model can also contain the following data objects:
- time patterns that allow demands, quality source inflows and pump speed settings to vary at fixed
intervals of time
- data curves that describe relationships between two quantities, such as head versus flow for pumps and
volume versus water level for tanks
- simple controls that adjust a link's setting (such as a pump's status) based on node pressure, tank
level, elapsed time, ot time of day
- rule-based controls that consist of one or more premises that if true result in one set of actions
being taken and if false result in a different set of actions being taken.
An EPANET model also contains a number of analysis options that specify:
- the project's flow units which in turn determines its unit system (US or SI)
- the formula used to compute head loss
- whether to use a demand driven or a pressure driven analysis
- hydraulic convergence criteria
- the type of water quality analysis to perform
- time steps used for hydraulic, water quality and reporting
- global values for reaction coefficients that can be overridden for individual pipes
- global values for energy usage parameters that can be overridden for individual pumps.
Please refer to the <a href="https://nepis.epa.gov/Adobe/PDF/P1007WWU.pdf">EPANET 2 Users Manual</a>
for more information on EPANET's data model.
*/
/**
@page DataFlow Data Flow Diagram
The EPANET Toolkit contains separate code modules for network building, hydraulic analysis, water quality analysis, and report generation. The data flow diagram for analyzing a pipe network is shown below. The processing steps depicted in this diagram can be summarized as follows:
@image html DataFlow.png
@image latex DataFlow.eps
- The network builder receives a description of the network being simulated either from an external input file (.inp) or from a series of function calls that create network objects and assign their properties via code. These data are stored in a Project data structure.
- The hydraulics solver carries out an extended period hydraulic simulation. The results obtained at every time step can be written to an external, unformatted (binary) hydraulics file (.hyd). Some of these time steps might represent intermediate points in time where system conditions change because of tanks becoming full or empty or pumps turning on or off due to level controls or timed operation.
- If a water quality simulation is requested, the water quality solver accesses the flow data from the hydraulics file as it computes substance transport and reaction throughout the network over each hydraulic time step. During this process it can write both the formerly computed hydraulic results as well as its water quality results for each preset reporting interval to an unformatted (binary) output file (.out). If no water quality analysis was called for, then the hydraulic results stored in the .hyd file can simply be written out to the binary output file at uniform reporting intervals.
- If requested, a report writer reads back the computed simulation results from the binary output file (.out) for each reporting period and writes out selected values to a formatted report file (.rpt). Any error or warning messages generated during the run are also written to this file.
Toolkit functions exist to carry out all of these steps under the programmer's control, including the ability to read and modify the contents of the Project data structure.
*/
/**
@page ToolkitVersions Toolkit Versions
The toolkit comes with two sets of identical functions that programmers can utilize:
- the single-threaded version of the toolkit is compatible with previous releases and only works
with single threaded applications.
- the multi-threaded version allows users to create multiple EPANET data sets (called projects) that can be
analyzed concurrently.
Both toolkit versions utilize identical function names and argument lists with the following exceptions:
- Function names in the single-threaded library begin with `EN` while those in the multi-threaded
library begin with `EN_`.
- The multi-threaded functions contain an additional argument that references a particular network project
that the function is applied to.
- The multi-threaded library contains two additional functions that allow users to create and delete
EPANET projects.
- The single-threaded library uses single precision for its floating point arguments while the
multi-threaded library uses double precision.
To avoid unnecessary duplication this document only discusses the multi-threaded version of the
toolkit.
*/

438
doc/modules.dox Normal file
View File

@@ -0,0 +1,438 @@
/**
@defgroup Project Project Functions
These functions are used to manage a project.
*/
/**
@defgroup Hydraulics Hydraulic Analysis Functions
These functions are used to perform a hydraulic analysis.
*/
/**
@defgroup Quality Water Quality Analysis Functions
These functions are used to perform a water quality analysis.
*/
/**
@defgroup Reporting Reporting Functions
These functions are used to report simulation results.
*/
/**
@defgroup Options Analysis Options Functions
These functions are used to get and set analysis options.
*/
/**
@defgroup Nodes Network Node Functions
These functions are used for working with network nodes.
*/
/**
@defgroup Demands Nodal Demand Functions
These functions are used for managing nodal demands.
*/
/**
@defgroup Links Network Link Functions
These functions are used for working with network links.
*/
/**
@defgroup Patterns Time Pattern Functions
These functions are used for working with time patterns.
*/
/**
@defgroup Curves Data Curve Functions
These functions are used for working with data curves.
*/
/**
@defgroup Controls Simple Control Functions
These functions are used for working with simple conditional controls.
*/
/**
@defgroup Rules Rule-Based Control Functions
These functions are used for working with rule-based controls.
*/
/**
@defgroup Constants Symbolic Constants
These are symbolic constants used as function arguments.
*/
/**
@addtogroup Project
@{
@fn int EN_createproject(EN_Project *ph)
@fn int EN_deleteproject(EN_Project *ph)
@fn int EN_runproject(EN_Project ph, const char *f1, const char *f2, const char *f3, void (*pviewprog)(char *))
@fn int EN_init(EN_Project ph, const char *rptFile, const char *outFile, int unitsType, int headLossType)
@fn int EN_open(EN_Project ph, const char *inpFile, const char *rptFile, const char *binOutFile)
@fn int EN_saveinpfile(EN_Project ph, const char *filename)
@fn int EN_close(EN_Project ph)
@}
*/
/**
@addtogroup Hydraulics
@{
@fn int EN_solveH(EN_Project ph)
@fn int EN_usehydfile(EN_Project ph, char *filename)
@fn int EN_openH(EN_Project ph)
@fn int EN_initH(EN_Project ph, int initFlag)
@fn int EN_runH(EN_Project ph, long *currentTime)
@fn int EN_nextH(EN_Project ph, long *tStep)
@fn int EN_saveH(EN_Project ph)
@fn int EN_savehydfile(EN_Project ph, char *filename)
@fn int EN_closeH(EN_Project ph)
@}
*/
/**
@addtogroup Quality
@{
@fn int EN_solveQ(EN_Project ph)
@fn int EN_openQ(EN_Project ph)
@fn int EN_initQ(EN_Project ph, int saveFlag)
@fn int EN_runQ(EN_Project ph, long *currentTime)
@fn int EN_nextQ(EN_Project ph, long *tStep)
@fn int EN_stepQ(EN_Project ph, long *timeLeft)
@fn int EN_closeQ(EN_Project ph)
@}
*/
/**
@addtogroup Reporting
@{
@fn int EN_writeline(EN_Project ph, char *line)
@fn int EN_report(EN_Project ph)
@fn int EN_resetreport(EN_Project ph)
@fn int EN_setreport(EN_Project ph, char *reportFormat)
@fn int EN_setstatusreport(EN_Project ph, int code)
@fn int EN_getversion(int *version)
@fn int EN_getcount(EN_Project ph, int code, int *count)
@fn int EN_geterror(int errcode, char *errmsg, int maxLen)
@fn int EN_getstatistic(EN_Project ph, int type, double* value)
@}
*/
/**
@addtogroup Options
@{
@fn int EN_getoption(EN_Project ph, int option, double *value)
@fn int EN_setoption(EN_Project ph, int option, double value)
@fn int EN_getflowunits(EN_Project ph, int *units)
@fn int EN_setflowunits(EN_Project ph, int units)
@fn int EN_gettimeparam(EN_Project ph, int param, long *value)
@fn int EN_settimeparam(EN_Project ph, int param, long value)
@fn int EN_getqualinfo(EN_Project ph, int *qualType, char *chemName, char *chemUnits, int *traceNode)
@fn int EN_getqualtype(EN_Project ph, int *qualType, int *traceNode)
@fn int EN_setqualtype(EN_Project ph, int qualType, char *chemName, char *chemUnits, char *traceNode)
@}
*/
/**
@addtogroup Nodes
@{
@fn int EN_addnode(EN_Project ph, char *id, int nodeType)
@fn int EN_deletenode(EN_Project ph, int index, int actionCode)
@fn int EN_getnodeindex(EN_Project ph, char *id, int *index)
@fn int EN_getnodeid(EN_Project ph, int index, char *id)
@fn int EN_setnodeid(EN_Project ph, int index, char *newid)
@fn int EN_getnodetype(EN_Project ph, int index, int *code)
@fn int EN_getnodevalue(EN_Project ph, int index, int code, double *value)
@fn int EN_setnodevalue(EN_Project ph, int index, int code, double v)
@fn int EN_setjuncdata(EN_Project ph, int index, double elev, double dmnd, char *dmndpat)
@fn int EN_settankdata(EN_Project ph, int index, double elev, double initlvl,
double minlvl, double maxlvl, double diam, double minvol, char *volcurve)
@fn int EN_getcoord(EN_Project ph, int index, double *x, double *y)
@fn int EN_setcoord(EN_Project ph, int index, double x, double y)
@}
*/
/**
@addtogroup Demands
@{
@fn int EN_getdemandmodel(EN_Project ph, int *type, double *pmin, double *preq, double *pexp)
@fn int EN_setdemandmodel(EN_Project ph, int type, double pmin, double preq, double pexp)
@fn int EN_getnumdemands(EN_Project ph, int nodeIndex, int *numDemands)
@fn int EN_getbasedemand(EN_Project ph, int nodeIndex, int demandIndex, double *baseDemand)
@fn int EN_setbasedemand(EN_Project ph, int nodeIndex, int demandIndex, double baseDemand)
@fn int EN_getdemandpattern(EN_Project ph, int nodeIndex, int demandIndex, int *pattIndex)
@fn int EN_setdemandpattern(EN_Project ph, int nodeIndex, int demandIndex, int patIndex)
@fn int EN_getdemandname(EN_Project ph, int nodeIndex, int demandIdx, char *demandName)
@fn int EN_setdemandname(EN_Project ph, int nodeIndex, int demandIdx, char *demandName)
@}
*/
/**
@addtogroup Links
@{
@fn int EN_addlink(EN_Project ph, char *id, int linkType, char *fromNode, char *toNode)
@fn int EN_deletelink(EN_Project ph, int index, int actionCode)
@fn int EN_getlinkindex(EN_Project ph, char *id, int *index)
@fn int EN_getlinkid(EN_Project ph, int index, char *id)
@fn int EN_setlinkid(EN_Project ph, int index, char *newid)
@fn int EN_getlinktype(EN_Project ph, int index, int *linkType)
@fn int EN_setlinktype(EN_Project ph, int *index, int linkType, int actionCode)
@fn int EN_getlinknodes(EN_Project ph, int index, int *node1, int *node2)
@fn int EN_setlinknodes(EN_Project ph, int index, int node1, int node2)
@fn int EN_getlinkvalue(EN_Project ph, int index, int property, double *value)
@fn int EN_setlinkvalue(EN_Project ph, int index, int property, double value)
@fn int EN_setpipedata(EN_Project ph, int index, double length, double diam, double rough, double mloss)
@fn int EN_getpumptype(EN_Project ph, int linkIndex, int *pumpType)
@fn int EN_getheadcurveindex(EN_Project ph, int pumpIndex, int *curveIndex)
@fn int EN_setheadcurveindex(EN_Project ph, int pumpIndex, int curveIndex)
@}
*/
/**
@addtogroup Patterns
@{
@fn int EN_addpattern(EN_Project ph, char *id)
@fn int EN_getpatternindex(EN_Project ph, char *id, int *index)
@fn int EN_getpatternid(EN_Project ph, int index, char *id)
@fn int EN_getpatternlen(EN_Project ph, int index, int *len)
@fn int EN_getpatternvalue(EN_Project ph, int index, int period, double *value)
@fn int EN_setpatternvalue(EN_Project ph, int index, int period, double value)
@fn int EN_getaveragepatternvalue(EN_Project ph, int index, double *value)
@fn int EN_setpattern(EN_Project ph, int index, double *f, int len)
@}
*/
/**
@addtogroup Curves
@{
@fn int EN_addcurve(EN_Project ph, char *id)
@fn int EN_getcurveindex(EN_Project ph, char *id, int *index)
@fn int EN_getcurveid(EN_Project ph, int index, char *id)
@fn int EN_getcurvelen(EN_Project ph, int index, int *len)
@fn int EN_getcurvetype(EN_Project ph, int index, int *type)
@fn int EN_getcurvevalue(EN_Project ph, int curveIndex, int pointIndex, double *x, double *y)
@fn int EN_setcurvevalue(EN_Project ph, int curveIndex, int pointIndex, double x, double y)
@fn int EN_getcurve(EN_Project ph, int curveIndex, char* id, int *nPoints, double **xValues, double **yValues)
@fn int EN_setcurve(EN_Project ph, int index, double *xValues, double *yValues, int nPoints)
@}
*/
/**
@addtogroup Controls
@{
@fn int EN_addcontrol(EN_Project ph, int type, int linkIndex, double setting, int nodeIndex, double level, int *index)
@fn int EN_deletecontrol(EN_Project ph, int index)
@fn int EN_getcontrol(EN_Project ph, int index, int *type, int *linkIndex, double *setting, int *nodeIndex, double *level)
@fn int EN_setcontrol(EN_Project ph, int index, int type, int linkIndex, double setting, int nodeIndex, double level)
@}
*/
/**
@addtogroup Rules
@{
@fn int EN_addrule(EN_Project ph, char *rule)
@fn int EN_deleterule(EN_Project ph, int index)
@fn int EN_getrule(EN_Project ph, int index, int *nPremises, int *nThenActions, int *nElseActions, double *priority)
@fn int EN_getruleID(EN_Project ph, int index, char* id);
@fn int EN_getpremise(EN_Project ph, int ruleIndex, int premiseIndex, int *logop, int *object, int *objIndex,
int *variable, int *relop, int *status, double *value)
@fn int EN_setpremise(EN_Project ph, int ruleIndex, int premiseIndex,
int logop, int object, int objIndex, int variable, int relop, int status, double value)
@fn int EN_setpremiseindex(EN_Project ph, int ruleIndex, int premiseIndex, int objIndex)
@fn int EN_setpremisestatus(EN_Project ph, int ruleIndex, int premiseIndex, int status)
@fn int EN_setpremisevalue(EN_Project ph, int ruleIndex, int premiseIndex, double value)
@fn int EN_getthenaction(EN_Project ph, int ruleIndex, int actionIndex, int *linkIndex, int *status, double *setting)
@fn int EN_setthenaction(EN_Project ph, int ruleIndex, int actionIndex, int linkIndex, int status, double setting)
@fn int EN_getelseaction(EN_Project ph, int ruleIndex, int actionIndex, int *linkIndex, int *status, double *setting)
@fn int EN_setelseaction(EN_Project ph, int ruleIndex, int actionIndex, int linkIndex, int status, double setting)
@fn int EN_setrulepriority(EN_Project ph, int index, double priority)
@}
*/
/**
@addtogroup Constants
@{
@file epanet2_enums.h
\enum EN_CountType
\enum EN_NodeType
\enum EN_LinkType
\enum EN_PumpType
\enum EN_CurveType
\enum EN_QualityType
\enum EN_SourceType
\enum EN_ControlType
\enum EN_HeadLossType
\enum EN_NodeProperty
\enum EN_LinkProperty
\enum EN_TimeParameter
\enum EN_Option
\enum EN_FlowUnits
\enum EN_DemandModel
\enum EN_MixingModel
\enum EN_StatusReport
\enum EN_StatisticType
\enum EN_InitHydOption
\enum EN_ActionCodeType
\enum EN_AnalysisStatistic
\enum EN_RuleObject
\enum EN_RuleVariable
\enum EN_RuleOperator
\enum EN_RuleStatus
@}
*/
/**
@defgroup Files File Descriptions
These are the various files used by the Toolkit.
@section InputFile Input File
The Input file is a standard EPANET input data file that describes the system being analyzed. It can either be created external to the application being developed with the Toolkit or by the application itself. It is the first file name supplied to the @ref EN_open function. The format of the file is described in Appendix C of the <a href="https://nepis.epa.gov/Adobe/PDF/P1007WWU.pdf">EPANET 2 Users Manual</a>. A project's data associated with its Input file remains accessible until the project is closed down with the @ref EN_close or deleted with @ref EN_deleteproject.
@section ReportFile Report File
The Report file is the second file name supplied to the @ref EN_open function (or the first file name to @ref EN_init). It is used to log any error messages that occur when the Input file is being processed and to record all status messages that are generated during a hydraulic simulation. In addition, if the @ref EN_report function is called the resulting report can also be written to this file as can user-generated lines of text using the @ref EN_writeline function. The format of the report is controlled by statements placed in the [REPORT] section of the Input file and by similar statements included in calls to the @ref EN_setreport function. Only results at a specified uniform reporting time interval are written to this file.
To suppress the writing of all error and warning messages to the Report file either include the command `MESSAGES NO` in the [REPORT] section of the Input file or call the Toolkit function `EN_setreport("MESSAGES NO")`.
To route a formatted report to a different file than the Report file either include the command `FILE filename` in the [REPORT] section of the Input file or call the Toolkit function `EN_setreport("FILE filename")`, where `filename` is the name of the file to use.
@section OutputFile Output File
The Output file is an unformatted binary file used to store both hydraulic and water quality results at uniform reporting intervals (see @ref OutFileFormat). It is the third file name supplied to the @ref EN_open function (or second name to @ref EN_init). If an empty string ("") is used as its name then a scratch temporary file will be used. Otherwise the Output file will be saved after the @ref EN_close function is called. Saving this file is useful if further post-processing of the output results are needed. The function @ref EN_saveH will transfer hydraulic results to the Output file if no water quality analysis will be made. Using @ref EN_solveQ to run a water quality analysis automatically saves both hydraulic and water quality results to this file. If the @ref EN_initQ - @ref EN_runQ - @ref EN_nextQ set of functions is used to perform a water quality analysis, then results will be saved only if the `saveflag` argument of @ref EN_initQ is set to @ref EN_SAVE. Again, the need to save results to the Output file is application-dependent. If a formatted output report is to be generated using @ref EN_report, then results must first be saved to the Output file.
@section HydraulicsFile Hydraulics File
The Hydraulics file is an unformatted binary file used to store the results of a hydraulic analysis. Results for all time periods are stored, including those at intermediate times when special hydraulic events occur (e.g., pumps and tanks opening or closing because control conditions have been satisfied).
Normally it is a temporary file that is deleted after the @ref EN_deleteproject function is called. However, it will be saved if the @ref EN_savehydfile function is called before that.
Likewise, a previously saved Hydraulics file can be used if the command `HYDRAULICS USE` filename appears in the [OPTIONS] section of the input file, or if the @ref EN_usehydfile function is called.
When the Toolkit function @ref EN_solveH is used to make a hydraulic analysis, results are automatically saved to the Hydraulics file. When the @ref EN_initH - @ref EN_runH - @ref EN_nextH set of functions is used, the `initFlag` argument to @ref EN_initH determines whether results are saved or not. The need to save hydraulic results is application-dependent. They must always be saved to the Hydraulics file if a water quality analysis will follow.
*/
/**
@defgroup ErrorCodes Error Codes
| Code | Meaning |
|------|--------- |
| 0 | No error |
| 101 | Insufficient memory available |
| 102 | No network data available |
| 103 | Hydraulic solver not opened |
| 104 | No hydraulics for water quality analysis |
| 105 | Water quality solver not opened |
| 106 | No results saved to report on |
| 107 | Hydraulics supplied from external file |
| 108 | Cannot use external file while hydraulics solver is open |
| 110 | Cannot solve network hydraulic equations |
| 120 | Cannot solve water quality transport equations |
| ||
| 200 | One or more errors in an input file |
| 201 | Syntax error |
| 202 | Function call contains an illegal numeric value |
| 203 | Function call refers to an undefined node |
| 204 | Function call refers to an undefined link |
| 205 | Function call refers to an undefined time pattern |
| 206 | Function call refers to an undefined curve |
| 207 | Function call attempts to control a check valve pipe or a GPV valve |
| 209 | Function call contains an illegal node property value |
| 211 | Function call contains an illegal link property value |
| 212 | Function call refers to an undefined Trace Node |
| 213 | Function call contains an invalid option value |
| 214 | Too many characters in a line of an input file |
| 215 | Function call contains a duplicate ID label |
| 216 | Function call refers to an undefined pump |
| 217 | Invalid pump energy data |
| 219 | Illegal valve connection to tank node |
| 220 | Illegal valve connection to another valve |
| 221 | Mis-placed clause in rule-based control |
| 222 | Link assigned same start and end nodes |
| 223 | Not enough nodes in network |
| 224 | No tanks or reservoirs in network |
| 225 | Invalid lower/upper levels for tank |
| 226 | No head curve or power rating for pump |
| 227 | Invalid head curve for pump |
| 230 | Nonincreasing x-values for curve |
| 233 | Network has unconnected node |
| 240 | Function call refers to nonexistent water quality source |
| 241 | Function call refers to nonexistent control |
| 250 | Function call contains invalid format (e.g. too long an ID name) |
| 251 | Function call contains invalid parameter code |
| 253 | Function call refers to nonexistent demand category |
| 254 | Function call refers to node with no coordinates |
| 257 | Function call refers to nonexistent rule |
| 258 | Function call refers to nonexistent rule clause |
| 260 | Function call attempts to delete node assigned as a Trace Node |
| 261 | Function call attempts to delete a node or link contained in a control |
| 262 | Function call attempts to modify network structure while a solver is open |
| ||
| 301 | Identical file names used for different types of files |
| 302 | Cannot open input file |
| 303 | Cannot open report file |
| 304 | Cannot open output file |
| 305 | Cannot open hydraulics file |
| 306 | Hydraulics file does not match network data |
| 307 | Cannot read hydraulics file |
| 308 | Cannot save results to binary file |
| 309 | Cannot save results to report file |
*/
/**
@defgroup WarningCodes Warning Codes
| Code | Description |
|------|--------- |
|1 | System hydraulically unbalanced - convergence to a hydraulic solution was not achieved in the allowed number of trials |
|2 | System may be hydraulically unstable - hydraulic convergence was only achieved after the status of all links was held fixed |
|3 | System disconnected - one or more nodes with positive demands were disconnected from all supply sources |
|4 | Pumps cannot deliver enough flow or head - one or more pumps were forced to either shut down (due to insufficient head) or operate beyond the maximum rated flow |
|5 | Valves cannot deliver enough flow - one or more flow control valves could not deliver the required flow even when fully open |
|6 | System has negative pressures - negative pressures occurred at one or more junctions with positive demand |
*/
/**
@defgroup Units Parameter Units
| Parameter | US Customary | SI Metric |
|----------------|-------------------------|---------------------------|
|Concentration | mg/L or ug/L | mg/L or ug/L |
|Demand | (see Flow units) | (see Flow units) |
|Diameter (Pipes)| inches | millimeters |
|Diameter (Tanks)| feet | meters |
|Efficiency | percent | percent |
|Elevation | feet | meters |
|Emitter Coeff. | flow units @ 1 psi drop | flow units @ 1 meter drop |
|Energy | kwatt - hours | kwatt - hours |
|Flow | CFS (cubic feet / sec) | LPS (liters / sec) |
| | GPM (gallons / min) | LPM (liters / min) |
| | MGD (million gal / day) | MLD (megaliters / day) |
| | IMGD (Imperial MGD) | CMH (cubic meters / hr) |
| | AFD (acre-feet / day) | CMD (cubic meters / day) |
|Friction Factor | unitless | unitless |
|Head | feet | meters |
|Length | feet | meters |
|Minor Loss Coeff. | unitless | unitless |
|Power | horsepower | kwatts |
|Pressure | psi | meters |
|Reaction Coeff. (Bulk) | 1/day (1st-order)| 1/day (1st-order) |
|Reaction Coeff. (Wall) | mass/sq-ft/day (0-order) | mass/sq-m/day (0-order) |
| | ft/day (1st-order) | meters/day (1st-order) |
|Roughness Coeff. | millifeet (Darcy-Weisbach) unitless otherwise| mm (Darcy-Weisbach) unitless otherwise |
|Source Mass Injection | mass/minute | mass/minute |
|Velocity | ft/sec | meters/sec |
|Volume | cubic feet | cubic meters |
|Water Age | hours | hours |
*/
/**
@defgroup OutFileFormat Output File Format
*/

View File

@@ -1,12 +0,0 @@
/**
@defgroup Controls Managing Controls
@addtogroup Controls
@{
@enum EN_ControlType
@fn int ENgetcontrol(int controlIndex, int *controlType, int *linkIndex, EN_API_FLOAT_TYPE *setting, int *nodeIndex, EN_API_FLOAT_TYPE *level)
@fn int ENsetcontrol(int cindex, int ctype, int lindex, EN_API_FLOAT_TYPE setting, int nindex, EN_API_FLOAT_TYPE level)
@}
*/

View File

@@ -1,20 +0,0 @@
/**
@defgroup Curves
@addtogroup Curves
@{
@fn int ENgetcurve(int curveIndex, char* id, int *nValues, EN_API_FLOAT_TYPE **xValues, EN_API_FLOAT_TYPE **yValues)
@fn int ENgetheadcurveindex(int index, int *curveindex)
@fn int ENgetpumptype(int index, int *type)
@fn int ENgetheadcurve(int linkIndex, char *curveId)
@fn int ENgetcurveindex(char *id, int *index)
@fn int ENgetcurveid(int index, char *id)
@fn int ENgetcurvelen(int index, int *len)
@fn int ENgetcurvevalue(int index, int pnt, EN_API_FLOAT_TYPE *x, EN_API_FLOAT_TYPE *y)
@fn int ENsetcurvevalue(int index, int pnt, EN_API_FLOAT_TYPE x, EN_API_FLOAT_TYPE y)
@fn int ENsetcurve(int index, EN_API_FLOAT_TYPE *x, EN_API_FLOAT_TYPE *y, int len)
@fn int ENaddcurve(char *id)
@}
*/

View File

@@ -1,20 +0,0 @@
/**
@defgroup FileManagement File Management
@addtogroup FileManagement
@{
@fn int ENwriteline (char *line)
@fn int ENreport ()
@fn int ENresetreport ()
@fn int ENsetreport (char *reportFormat)
@fn int ENopen (char *inpFile, char *rptFile, char *binOutFile)
@fn int ENsaveinpfile (char *filename)
@fn int ENclose()
@}
*/

View File

@@ -1,41 +0,0 @@
/**
@defgroup HydraulicFunctions Hydraulic Analysis
~~~~~~~~~~~~~~~{.c}
int errcode;
long t, tstep;
errcode = ENopenH();
if (!errcode) {
errcode = ENinitH(EN_SAVE);
if (!errcode) {
do {
tstep = 0;
ERRCODE(ENrunH(&t));
ERRCODE(ENnextH(&tstep));
} while (tstep > 0);
}
}
ENcloseH();
~~~~~~~~~~~~~~~
@addtogroup HydraulicFunctions
@{
@fn int ENsolveH()
@fn int ENsaveH()
@fn int ENopenH()
@fn int ENinitH(int initFlag)
@fn int ENrunH(long *currentTime)
@fn int ENnextH(long *tStep)
@fn int ENcloseH()
@fn int ENsavehydfile(char *filename)
@fn int ENusehydfile(char *filename)
@fn int ENgetstatistic(int code, EN_API_FLOAT_TYPE* value)
@}
*/

View File

@@ -1,16 +0,0 @@
/**
@defgroup NetworkInfo Network Info
@addtogroup NetworkInfo
@{
@fn int ENgetcount (int code, int *count)
@fn int ENgetnodeindex (char *id, int *index)
@fn int ENgetnodeid (int index, char *id)
@fn int ENgetnodetype (int index, int *code)
@fn int ENgetnodevalue (int index, int code, EN_API_FLOAT_TYPE *value)
@fn int ENgetcoord (int index, EN_API_FLOAT_TYPE *x, EN_API_FLOAT_TYPE *y)
@fn int ENsetcoord (int index, EN_API_FLOAT_TYPE x, EN_API_FLOAT_TYPE y)
@}
*/

View File

@@ -1,18 +0,0 @@
/**
@defgroup Patterns
@addtogroup Patterns
@{
@fn int ENgetpatternindex (char *id, int *index)
@fn int ENgetpatternid (int index, char *id)
@fn int ENgetpatternlen (int index, int *len)
@fn int ENgetpatternvalue (int index, int period, EN_API_FLOAT_TYPE *value)
@fn int ENgetaveragepatternvalue (int index, EN_API_FLOAT_TYPE *value)
@fn int ENgetdemandpattern(int nodeIndex, int demandIndex, int *pattIndex)
@fn int ENaddpattern(char *id)
@fn int ENsetpattern(int index, EN_API_FLOAT_TYPE *f, int len)
@fn int ENsetpatternvalue(int index, int period, EN_API_FLOAT_TYPE value)
@}
*/

View File

@@ -1,17 +0,0 @@
/**
@defgroup QualityFunctions Water Quality Functions
@addtogroup QualityFunctions
@{
@fn int ENsolveQ ()
@fn int ENopenQ ()
@fn int ENinitQ (int saveFlag)
@fn int ENrunQ (long *currentTime)
@fn int ENnextQ (long *tStep)
@fn int ENstepQ (long *timeLeft)
@fn int ENcloseQ ()
@}
*/

View File

@@ -1,14 +0,0 @@
/**
@defgroup ToolkitOptions Toolkit Options
@addtogroup ToolkitOptions
@{
@fn int ENgetoption (int code, EN_API_FLOAT_TYPE *value)
@fn int ENgettimeparam (int code, long *value)
@fn int ENgetflowunits (int *code)
@fn int ENgetqualtype (int *qualcode, int *tracenode)
@fn int ENgeterror (int errcode, char *errmsg, int maxLen)
@}
*/

15
doc/newfooter.html Normal file
View File

@@ -0,0 +1,15 @@
<!-- HTML footer for doxygen 1.8.10-->
<!-- start footer part -->
<!--BEGIN GENERATE_TREEVIEW-->
<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
<ul>
$navpath
<li class="footer">OWA-EPANET Toolkit 2.2 &copy 2019</li>
</ul>
</div>
<!--END GENERATE_TREEVIEW-->
<!--BEGIN !GENERATE_TREEVIEW-->
<li class="footer">OWA-EPANET Toolkit 2.2 &copy 2019</li>
<!--END !GENERATE_TREEVIEW-->
</body>
</html>

140
doc/output-format.dox Normal file
View File

@@ -0,0 +1,140 @@
/**
@addtogroup OutFileFormat
@{
The Toolkit uses an unformatted binary output file to store both hydraulic and water quality results at uniform reporting intervals. Data written to the file is either 4-byte integers, 4-byte floats, or fixed-size strings whose size is a multiple of 4 bytes. This allows the file to be divided conveniently into 4-byte records. The file consists of four sections of the following sizes in bytes:
| Section | Size in Bytes |
|----------------|----------------------------------------|
|Prolog | 884 + 36*Nnodes + 52*Nlinks + 8*Ntanks |
|Energy Usage | 28*Npumps + 4 |
|Dynamic Results | (16*Nnodes + 32*Nlinks)*Nperiods |
|Epilog | 28 |
where:
- Nnodes = number of nodes (junctions + reservoirs + tanks),
- Nlinks = number of links (pipes + pumps + valves),
- Ntanks = number of tanks and reservoirs,
- Npumps = number of pumps,
- Nperiods = number of reporting periods.
All of these counts are themselves written to the file's Prolog or Epilog sections.
@}
*/
/**
@page Output_Prolog Prolog Section
@ingroup OutFileFormat
The Prolog section of an EPANET binary output file contains the following data:
|Item | Type | # Bytes |
|----------------|-----------|-----------|
| Magic Number = 516114521 | Integer | 4 |
| Version (= 200) | Integer | 4 |
| Number of Nodes | Integer | 4 |
| Number of Reservoirs & Tanks | Integer | 4|
| Number of Links | Integer | 4 |
| Number of Pumps | Integer | 4 |
| Number of Valves | Integer | 4 |
| Water Quality Option - see @ref EN_QualityType | Integer | 4 |
| Traced Node Index | Integer | 4 |
| Flow Units Option | Integer | 4 |
| Pressure Units Option | Integer | 4 |
| 0 = psi || |
| 1 = meters || |
| 2 = kPa || |
| Report Statistic Type - see @ref EN_StatisticType | Integer | 4 |
| Reporting Start Time (sec) | Integer | 4 |
| Reporting Time Step (sec) | Integer | 4 |
| Simulation Duration (sec) | Integer | 4 |
| Project Title (1st line) | Char | 80 |
| Project Title (2nd line) | Char | 80 |
| Project Title (3rd line) | Char | 80 |
| Name of Input File | Char | 260 |
| Name of Report File | Char | 260 |
| Name of Quality Chemical | Char | 32 |
| Chemical Concentration Units | Char | 32 |
| ID String of Each Node | Char | 32*Nnodes |
| ID String of Each Link | Char | 32*Nlinks |
| Index of Head Node of Each Link | Integer | 4*Nlinks |
| Index of Tail Node of Each Link | Integer | 4*Nlinks |
| Type Code of Each Link (see @ref EN_LinkType) | Integer | 4*Nlinks |
| Node Index of Each Tank | Integer | 4*Ntanks |
| Surface Area of Each Tank | Float | 4*Ntanks |
| Elevation of Each Node | Float | 4*Nnodes |
| Length of Each Link | Float | 4*Nlinks |
| Diameter of Each Link | Float | 4*Nlinks |
*/
/**
@page Output_Energy Energy Usage Section
@ingroup OutFileFormat
The Energy Usage section of an EPANET binary output file contains the following data:
|Item (Repeated for Each Pump) | Type | # Bytes |
|------------------------------|---------|---------|
| Pump Index in list of links | Integer | 4 |
| Pump Utilization (%) | Float | 4 |
| Average Efficiency (%) | Float | 4 |
| Average kwatts/MGal (or kwatts/cu m) | Float | 4 |
| Average kwatts | Float | 4 |
| Peak kwatts | Float | 4 |
| Average Cost per Day | Float | 4 |
| Peak Energy Usage (kw-hrs) | Float | 4 |
*/
/**
@page Output_Results Dynamic Results Section
@ingroup OutFileFormat
The Dynamic Results section of an EPANET binary output file contains the following set of data for each reporting period (the reporting time step is written to the Output File's @ref Output_Prolog and the number of such steps is written to the @ref Output_Epilog):
| Item | Type | # Bytes |
|------|------|---------|
|Demand at Each Node | Float | 4*Nnodes |
|Head (Grade) at Each Node | Float | 4*Nnodes |
|Pressure at Each Node | Float | 4*Nnodes |
|Water Quality at Each Node | Float | 4*Nnodes |
|Flow in Each Link | Float | 4*Nlinks |
|(negative for reverse flow) || |
|Velocity in Each Link | Float | 4*Nlinks |
|Headloss per 1000 Units of Length for Each Link | Float | 4*Nlinks |
|(total head for pumps and head loss for valves) || |
|Average Water Quality in Each Link | Float | 4*Nlinks |
| Status Code for Each Link | Float | 4*Nlinks |
| 0 = closed (pump shutoff head exceeded) || |
| 1 = temporarily closed || |
| 2 = closed || |
| 3 = open || |
| 4 = active (partially open || |
| 5 = open (pump max. flow exceeded) || |
| 6 = open (FCV can't supply flow || |
| 7 = open (PRV/PSV can't supply pressure) || |
| Setting for Each Link | Float | 4*Nlinks |
|Reaction Rate for Each Link (mass/L/day) | Float | 4*Nlinks |
|Friction Factor for Each Link | Float | 4*Nlinks |
*/
/**
@page Output_Epilog Epilog Section
@ingroup OutFileFormat
The Epilog section of an EPANET binary output file contains the following data:
|Item | Type | # Bytes |
|-----|------|---------|
|Average bulk reaction rate (mass/hr) | Float | 4 |
|Average wall reaction rate (mass/hr) | Float | 4 |
|Average tank reaction rate (mass/hr) | Float | 4 |
|Average source inflow rate (mass/hr) | Float | 4 |
|Number of Reporting Periods | Integer | 4 |
|Warning Flag: | Integer | 4 |
|0 = no warnings || |
|1 = warnings were generated || |
|Magic Number = 516114521 | Integer | 4 |
*/

61
doc/readme.txt Normal file
View File

@@ -0,0 +1,61 @@
Generating Documentation for OWA-EPANET 2.2
===========================================
You must have Doxygen (http://www.doxygen.nl/)installed on your machine to generate
documentation for OWA-EPANET's API (aka Toolkit). Assuming this is the case, open a
terminal window, navigate to the project's 'doc' directory and issue the command
'doxygen' to generate documentation in the following formats:
- HTML documentation will be placed in the 'html' sub-directory. Launch 'index.html'
to view it in a web browser.
- Latex documentation will be placed in the 'latex' sub-directory. Assuming you
have a TeX system, such as MikTex (https://miktex.org), installed on your machine
you can generate a PDF of the documentation by issuing the 'make pdf' command from
within the 'latex' directory. The resulting pdf file will be named 'refman.pdf'.
To generate a Windows compiled HTML Help file you must have Microsoft's HTML Help Workshop
(https://www.microsoft.com/en-us/download/details.aspx?id=21138) installed. In this case
you need to first edit the Doxygen configuration file 'Doxyfile' as follows:
1. Change the 'GENERATE_HTMLHELP' setting to 'YES'.
2. Enter the location where the Help Workshop system was installed next to the
'HHC_LOCATION' setting.
After running 'doxygen' again the resulting Help file named 'owa-epanet.chm' will
appear in the 'html' sub-directory.
Doxygen uses the special comments placed in the project's 'epanet2_2.h' and
'epanet2_enums.h' header files to document EPANET's API. It also uses supplementary
material contained in the following files of the project's 'doc' folder to generate
additional pages of documentation:
main.dox - generates the Overview pages.
toolkit-usage.dox: generates the Toolkit Usage page.
toolkit-examples.dox : generates the Toolkit Examples pages.
modules.dox: generates the Reference section of the document consisting of several
module pages that describe Toolkit functions by group, enumerated
constants, file descriptions, error codes, property units, and output
file format.
output-format.dox: generates the pages that describe the format used in different
sections of the output file.
Finally, a group of special Doxygen files are used to customize the format of the
generated documentation. These include the following:
Doxyfile - the main Doxygen configuration file
DoxygenLayout.xml - replaces the title "Modules" with "Reference" and hides the
"Files" section in the tree view pane of the document.
extrastylesheet.css - reduces the size of the the h1 heading style.
newfooter.html - replaces the default Doxygen footer in HTML output with a custom one.
header.tex - replaces the standard title page and footer text used in Latex output.

223
doc/toolkit-examples.dox Normal file
View File

@@ -0,0 +1,223 @@
/** @page ToolkitExamples Examples
Here are several examples of how the Toolkit can be used for different types of network analyses.
- @subpage Example1 "Embedded Engine Example"
- @subpage Example2 "Network Building Example"
- @subpage Example3 "Hydrant Rating Curve Example"
- @subpage Example4 "Chlorine Dosage Example"
*/
/** @page Example1 Embedded Engine Example
This example shows how simple it is for the Toolkit to provide a network analysis engine for other applications. There are three steps that the application would need to take:
-# Have the application write network data to an EPANET-formatted input file.
-# Create a project and call EN_runproject, supplying the name of the EPANET input file, the name of a Report file where status and error messages are written, and the name of a binary Output file which will contain analysis results.
-# Have the application access the output file to display desired analysis results (see @ref OutFileFormat).
Here is an example where a callback function `writeConsole` is provided to write EPANET's progress messages to the console:
\code {.c}
#include "epanet2_2.h"
void writeConsole(char *s)
{
fprintf(stdout, "\n%s", s);
}
int runEpanet(char* inpFile, char* rptFile, char* outFile)
{
int errcode;
EN_project ph;
EN_createproject(&pH);
errcode = EN_runproject(ph, inpFile, rptFile, outFile, &writeConsole);
EN_deleteproject(&ph);
return errcode;
}
\endcode
*/
/** @page Example2 Network Building Example
This example shows how a network can be built just through toolkit function calls, eliminating the
need to always use an EPANET formatted input file. This creates opportunities to use other sources
of network data in one's code, such as relational database files or GIS/CAD files.
Below is a schematic of the network to be built.
@image html Example2.png
\code {.c}
#include "epanet2_2.h"
void netbuilder()
{
// Create a project that uses gpm for flow units and
// the Hazen-Williams formula for head loss
EN_Project ph;
EN_createproject(&ph);
EN_init(ph, "", "", EN_GPM, EN_HW);
// Add the first junction node to the project with
// an elevation of 700 ft and a demand of 0
EN_addnode(ph, "J1", EN_JUNCTION);
EN_setjuncdata(ph, 1, 700, 0, "");
// Add the remaining two junctions with elevations of
// 710 ft and demands of 250 and 500 gpm, respectively
EN_addnode(ph, "J2", EN_JUNCTION);
EN_setjuncdata(ph, 2, 710, 250, "");
EN_addnode(ph, "J3", EN_JUNCTION);
EN_setjuncdata(ph, 3, 710, 500, "");
// Add the reservoir at an elevation of 650 ft
EN_addnode(ph, "R1", EN_RESERVOIR);
EN_setnodevalue(ph, 4, EN_ELEVATION, 650);
// Add the tank node at elevation of 850 ft, initial water level
// at 120 ft, minimum level at 100 ft, maximum level at 150 ft
// and a diameter of 50.5 ft
EN_addnode(ph, "T1", EN_TANK);
EN_settankdata(ph, 5, 850, 120, 100, 150, 50.5, 0, "");
// Add the pipes to the project, setting their length,
// diameter, and roughness values
EN_addlink(ph, "P1", EN_PIPE, "J1", "J2");
EN_setpipedata(ph, 1, 10560, 12, 100, 0);
EN_addlink(ph, "P2", EN_PIPE, "J1", "T1");
EN_setpipedata(ph, 2, 5280, 14, 100, 0);
EN_addlink(ph, "P3", EN_PIPE, "J1", "J3");
EN_setpipedata(ph, 3, 5280, 14, 100, 0);
EN_addlink(ph, "P4", EN_PIPE, "J2", "J3");
EN_setpipedata(ph, 4, 5280, 14, 100, 0);
// Add a pump to the project
EN_addlink(ph, "PUMP", EN_PUMP, "R1", "J1");
// Create a single point head curve (index = 1) and
// assign it to the pump (index = 5)
EN_addcurve(ph, "C1");
EN_setcurvevalue(ph, 1, 1, 1500, 250);
EN_setlinkvalue(ph, 5, EN_PUMP_HCURVE, 1);
// Save the project for future use
EN_saveinpfile(ph, "example2.inp");
// Delete the project
EN_deleteproject(&ph);
}
\endcode
*/
/** @page Example3 Hydrant Rating Curve Example
This example illustrates how the Toolkit could be used to develop a hydrant rating curve used in fire flow studies. This curve shows the amount of flow available at a node in the system as a function of pressure. The curve is generated by running a number of steady state hydraulic analyses with the node of interest subjected to a different demand in each analysis. For this example we assume that the ID label of the node of interest is `MyNode` and that `N` different demand levels stored in the array `D` need to be examined. The corresponding pressures will be stored in `P`. To keep the code more readable, no error checking is made on the results returned from the Toolkit function calls.
\code {.c}
#include "epanet2_2.h"
void HydrantRating(char *MyNode, int N, double D[], double P[])
{
EN_Project ph;
int i, nodeindex;
long t;
double pressure;
// Create a project
EN_createproject(&ph);
// Retrieve network data from an input file
EN_open(ph, "example2.inp", "example2.rpt", "");
// Open the hydraulic solver
EN_openH(ph);
// Get the index of the node of interest
EN_getnodeindex(ph, MyNode, &nodeindex);
// Iterate over all demands
for (i=1; i<N; i++)
{
// Set nodal demand, initialize hydraulics, make a
// single period run, and retrieve pressure
EN_setnodevalue(ph, nodeindex, EN_BASEDEMAND, D[i]);
EN_initH(ph, 0);
EN_runH(ph, &t);
EN_getnodevalue(ph, nodeindex, EN_PRESSURE, &pressure);
P[i] = pressure;
}
// Close hydraulics solver & delete the project
EN_closeH(ph);
EN_deleteproject(&ph);
}
\endcode
*/
/** @page Example4 Chlorine Dosage Example
This example illustrates how the Toolkit could be used to determine the lowest dose of chlorine applied at the entrance to a distribution system needed to ensure that a minimum residual is met throughout the system. We assume that the EPANET input file contains the proper set of kinetic coefficients that describe the rate at which chlorine will decay in the system being studied. In the example code, the ID label of the source node is contained in `SourceID`, the minimum residual target is given by `Ctarget`, and the target is only checked after a start-up duration of 5 days (432,000 seconds). To keep the code more readable, no error checking is made on the results returned from the Toolkit function calls.
\code {.c}
#include "epanet2_2.h"
double cl2dose(char *SourceID, double Ctarget)
{
int i, nnodes, sourceindex, violation;
double c, csource;
long t, tstep;
EN_Project ph;
// Open the toolkit & obtain a hydraulic solution
EN_createproject(&ph);
EN_open(ph, "example3.inp", "example3.rpt", "");
EN_solveH(ph);
// Get the number of nodes and the source node's index
EN_getcount(ph, EN_NODES, &nnodes);
EN_getnodeindex(ph, SourceID, &sourceindex);
// Setup the system to analyze for chlorine
// (in case it was not done in the input file)
EN_setqualtype(ph, EN_CHEM, "Chlorine", "mg/L", "");
// Open the water quality solver
EN_openQ(ph);
// Begin the search for the source concentration
csource = 0.0;
do {
// Update source concentration to next level
csource = csource + 0.1;
EN_setnodevalue(ph, sourceindex, EN_SOURCEQUAL, csource);
// Run WQ simulation checking for target violations
violation = 0;
EN_initQ(ph, 0);
do {
EN_runQ(ph, &t);
if (t > 432000) {
for (i=1; i<=nnodes; i++) {
EN_getnodevalue(ph, i, EN_QUALITY, &c);
if (c < Ctarget) {
violation = 1;
break;
}
}
}
EN_nextQ(ph, &tstep);
// End WQ run if violation found
} while (!violation && tstep > 0);
// Continue search if violation found
} while (violation && csource <= 4.0);
// Close up the WQ solver and delete the project
EN_closeQ(ph);
EN_deleteproject(&ph);
return csource;
}
\endcode
*/

241
doc/toolkit-usage.dox Normal file
View File

@@ -0,0 +1,241 @@
/**
@page toolkit-usage Usage
The following topics briefly describe how to accomplish some basic tasks using the OWA-EPANET Toolkit. See the @ref ToolkitExamples topic for code listings of complete applications of the Toolkit.
@section CreateProject Creating a Project
Before any use is made of the Toolkit, a project and its handle must be created. After all processing is
completed the project should be deleted. See the code snippet below:
\code {.c}
EN_Project ph; // a project handle
EN_createproject(&ph);
// Call functions that perform desired analysis
EN_deleteproject(&ph);
\endcode
@section DetectingErrors Detecting Error Conditions
All of the Toolkit functions return an error/warning code. A 0 indicates that the function ran successfully. A number greater than 0 but less than 100 indicates that a warning condition was generated while a number higher than 100 indicates that the function failed.
The meaning of specific error and warning codes are listed in the @ref ErrorCodes and @ref WarningCodes sections of this guide. The Toolkit function @ref EN_geterror can be used to obtain the text of a specific error/warning code. The following example uses a macro named `ERRCODE` along with a variable named `errcode` to execute Toolkit commands only if no fatal errors have already been detected:
\code {.c}
#define ERRCODE(x) (errcode = ((errcode > 100) ? (errcode) : (x)))
void runHydraulics(EN_Project ph, char *inputFile, char *reportFile)
{
int errcode = 0;
char errmsg[EN_MAXMSG + 1];
ERRCODE(EN_open(ph, inputFile, reportFile, ""));
ERRCODE(EN_solveH(ph));
ERRCODE(EN_saveH(ph));
ERRCODE(EN_report(ph));
EN_geterror(ph, errcode, errmsg);
if (errcode) printf("\n%s\n", errmsg);
}
\endcode
@section NetworkData Providing Network Data
Once a project is created there are two ways in which it can be populated with data. The first is to use the @ref EN_open function to load an EPANET-formatted input file that provides a description of the network to be analyzed. The format of this file is described in Appendix C of the <a href="https://nepis.epa.gov/Adobe/PDF/P1007WWU.pdf">EPANET 2 Users Manual</a>. This function should be called immediately after a project is created. It takes as arguments the name of the input file to open and the names of a report file and a binary output file, both of which are optional. Here is a code sample showing this approach:
\code {.c}
EN_Project ph;
int errcode;
EN_createproject(&ph);
errcode = EN_open(ph, "net1.inp", "net1.rpt", "");
if (errcode == 0)
{
// Call functions that perform desired analysis
}
EN_deleteproject(&ph);
\endcode
Note that after an input file has been loaded in this fashion the resulting network can have objects added or deleted, and their properties set using various Toolkit functions .
The second method for supplying network data to a project is to use the Toolkit's functions to add objects and to set their properties via code. In this case the @ref EN_init function should be called immediately after creating a project, passing in the names of a report and binary output files (both optional) as well as the choices of flow units and head loss formulas to use. After that the various `EN_add` functions, such as @ref EN_addnode, @ref EN_addlink, @ref EN_addpattern, @ref EN_addcontrol, etc., can be called to add new objects to the network. Here is a partial example:
\code {.c}
EN_Project ph;
EN_createproject(&ph);
EN_init(ph, "net1.rpt", "", EN_GPM, EN_HW);
EN_addnode(ph, "J1", EN_JUNCTION);
EN_addnode(ph, "J2", EN_JUNCTION);
EN_addlink(ph, "P1", EN_PIPE, "J1", "J2");
// additional function calls to complete building the network
\endcode
See the @ref Example2 for a more complete example. While adding objects their properties can be set as described in the next section. Attemtping to change a network's structure by adding or deleting nodes and links while the Toolkit's hydraulic or water quality solvers are open will result in an error condition.
@section Properties Setting Object Properties
The Toolkit contains several functions for retrieving and setting the properties of a network's objects and its analysis options. The names of retrieval functions all begin with `EN_get` (e.g., @ref EN_getnodevalue, @ref EN_getoption, etc.) while the functions used for setting parameter values begin with `EN_set` (e.g., @ref EN_setnodevalue, @ref EN_setoption, etc.).
Most of these functions use an index number to refer to a specific network component (such as a node, link, time pattern or data curve). This number is simply the position of the component in the list of all components of similar type (e.g., node 10 is the tenth node, starting from 1, in the network) and is not the same as the ID label assigned to the component. A series of functions exist to determine a component's index number given its ID label (see @ref EN_getnodeindex, @ref EN_getlinkindex, @ref EN_getpatternindex, and @ref EN_getcurveindex). Likewise, functions exist to retrieve a component's ID label given its index number (see @ref EN_getlinkid, @ref EN_getnodeid, @ref EN_getpatternid, and @ref EN_getcurveid). The @ref EN_getcount function can be used to determine the number of different components in the network. Be aware that a component's index can change as elements are added or deleted from the network.
The code below is an example of using the property retrieval and setting functions. It changes all links with diameter of 10 inches to 12 inches.
\code {.c}
void changeDiameters(EN_Project ph)
{
int i, nLinks;
double diam;
EN_getcount(ph, EN_LINKCOUNT, &nLinks);
for (i = 1; i <= nLinks; i++)
{
EN_getlinkvalue(ph, i, EN_DIAMETER, &diam);
if (diam == 10) ENsetlinkvalue(i, EN_DIAMETER, 12);
}
}
\endcode
@section hydraulics Computing Hydraulics
There are two ways to use the Toolkit to run a hydraulic analysis:
-# Use the @ref EN_solveH function to run a complete extended period analysis, without having access to intermediate results.
-# Use the @ref EN_openH - @ref EN_initH - @ref EN_runH - @ref EN_nextH - @ref EN_closeH series of functions to step through the simulation one hydraulic time step at a time.
Method 1 is useful if you only want to run a single hydraulic analysis, perhaps to provide input to a water quality analysis. With this method hydraulic results are always saved to an intermediate hydraulics file at every time step.
Method 2 must be used if you need to access results between time steps or if you wish to run many analyses efficiently. To accomplish the latter, you would make only one call to `EN_openH` to begin the process, then make successive calls to `EN_initH` - `EN_runH` - `EN_nextH` to perform each analysis, and finally call EN_closeH to close down the hydraulics system. An example of this is shown below (calls to `EN_nextH` are not needed because we are only making a single period analysis in this example).
\code {.c}
void runHydraulics(EN_Project ph, int nRuns)
{
int i;
long t;
EN_openH(ph);
for (i = 1; i <= nRuns; i++)
{
// user-supplied function to set parameters
setparams(ph, i);
// initialize hydraulics; don't save them to file
EN_initH(ph, EN_NOSAVE);
// solve hydraulics
EN_runH(ph, &t);
// user-supplied function to process results
getresults(ph, i);
}
EN_closeH(ph);
}
\endcode
@section quality Computing Water Quality
As with a hydraulic analysis, there are two ways to carry out a water quality analysis:
-# Use the @ref EN_solveQ function to run a complete extended period analysis, without having access to intermediate results. A complete set of hydraulic results must have been generated either from running a hydraulic analysis or from importing a saved hydraulics file from a previous run.
-# Use the @ref EN_openQ - @ref EN_initQ - @ref EN_runQ - @ref EN_nextQ - @ref EN_closeQ series of functions to step through the simulation one hydraulic time step at a time. (Replacing `EN_nextQ` with @ref EN_stepQ will step through one water quality time step at a time.)
The second option can either be carried out after a hydraulic analysis has been run or simultaneously as hydraulics are being computed. Example code for these two alternatives is shown below:
\code {.c}
int runSequentialQuality(EN_Project ph)
{
int err;
long t, tStep;
err = EN_solveH(ph);
if (err > 100) return err;
EN_openQ(ph);
EN_initQ(ph, EN_NOSAVE);
do {
EN_runQ(ph, &t);
// Access quality results for time t here
EN_nextQ(ph, &tStep);
} while (tStep > 0);
EN_closeQ(ph);
return 0;
}
int runConcurrentQuality(EN_Project ph)
{
int err = 0;
long t, tStep;
EN_openH(ph);
EN_initH(ph, EN_NOSAVE);
EN_openQ(ph);
EN_initQ(ph, EN_NOSAVE);
do {
err = EN_runH(ph, &t);
if (err > 100) break;
EN_runQ(ph, &t);
// Access hydraulic & quality results for time t here
EN_nextH(ph, &tStep);
EN_nextQ(ph, &tStep);
} while (tStep > 0);
EN_closeH(ph);
EN_closeQ(ph);
return err;
}
\endcode
@section results Retrieving Computed Results
The @ref EN_getnodevalue and @ref EN_getlinkvalue functions can also be used to retrieve the results of hydraulic and water quality simulations. The computed parameters (and their Toolkit codes) that can be retrieved are as follows:
|For Nodes: | For Links: |
|----------------------------------- | ----------------------------------------- |
|`EN_DEMAND` (demand) |`EN_FLOW` (flow rate) |
|`EN_HEAD` (hydraulic head) |`EN_VELOCITY` (flow velocity) |
|`EN_PRESSURE` (pressure) |`EN_HEADLOSS` (head loss) |
|`EN_TANKLEVEL` (tank water level) |`EN_STATUS` (link status) |
|`EN_TANKVOLUME` (tank water volume) |`EN_SETTING` (pump speed or valve setting) |
|`EN_QUALITY` (water quality) |`EN_ENERGY` (pump energy usage) |
|`EN_SOURCEMASS` (source mass inflow)|`EN_PUMP_EFFIC` (pump efficiency) |
The following code shows how to retrieve the pressure at each node of a network after each time step of a hydraulic analysis (`writetofile` is a user-defined function that will write a record to a file):
\code {.c}
void getPressures(EN_Project ph)
{
int i, numNodes;
long t, tStep;
double p;
char id[EN_MAXID + 1];
EN_getcount(ph, EN_NODECOUNT, &numNodes);
EN_openH(ph);
ENinitH(ph, EN_NOSAVE);
do {
ENrunH(ph, &t);
for (i = 1; i <= NumNodes; i++) {
EN_getnodevalue(ph, i, EN_PRESSURE, &p);
EN_getnodeid(ph, i, id);
writetofile(t, id, p);
}
EN_nextH(&tStep);
} while (tStep > 0);
ENcloseH(ph);
}
\endcode
@section report Writing a Report
The Toolkit has some built-in capabilities to produce formatted output results saved to a file. More specialized reporting needs can always be handled by writing custom code.
The @ref EN_setreport function is used to define the format of a report while the @ref EN_report function actually writes the report. The latter should be called only after a hydraulic or water quality analysis has been made. An example of creating a report that lists all nodes where the pressure variation over the duration of the simulation exceeds 20 psi is shown below:
\code {.c}
void reportPressureVariation(EN_Project ph)
{
// Compute ranges (max - min)
EN_settimeparam(ph, EN_STATISTIC, EN_RANGE);
// Solve and save hydraulics
EN_solveH(ph);
EN_saveH(ph);
// Define contents of the report
EN_resetreport(ph);
ENsetreport(ph, "FILE myfile.rpt");
EN_setreport(ph, "NODES ALL");
EN_setreport(ph, "PRESSURE PRECISION 1");
EN_setreport(ph, "PRESSURE ABOVE 20");
// Write the report to file
EN_report(ph);
}
\endcode
*/