Merge pull request #267 from LRossman/lrossman-dev
Made mempool.c threadsafe (#234)
This commit is contained in:
@@ -9,6 +9,7 @@ env:
|
|||||||
before_install:
|
before_install:
|
||||||
- sudo apt-get -qq update
|
- sudo apt-get -qq update
|
||||||
- sudo apt-get install -y libboost-test-dev
|
- sudo apt-get install -y libboost-test-dev
|
||||||
|
- sudo apt-get install -y libboost-thread-dev
|
||||||
- sudo apt-get install -y swig
|
- sudo apt-get install -y swig
|
||||||
|
|
||||||
#install:
|
#install:
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
Release Notes for EPANET 2.2 (Draft)
|
Release Notes for EPANET 2.2 (Draft)
|
||||||
============================
|
============================
|
||||||
|
|
||||||
@@ -49,15 +47,18 @@ These new parameters augment the current `EN_ACCURACY` option which always remai
|
|||||||
## Improved Linear Solver Routine
|
## Improved Linear Solver Routine
|
||||||
EPANET's hydraulic solver requires solving a system of linear equations over a series of iterations until a set of convergence criteria are met. The coefficient matrix of this linear system is square and symmetric. It has a row for each network node and a non-zero off-diagonal coefficient for each link. The numerical effort needed to solve the linear system can be reduced if the nodes are re-ordered so that the non-zero coefficients cluster more tightly around the diagonal.
|
EPANET's hydraulic solver requires solving a system of linear equations over a series of iterations until a set of convergence criteria are met. The coefficient matrix of this linear system is square and symmetric. It has a row for each network node and a non-zero off-diagonal coefficient for each link. The numerical effort needed to solve the linear system can be reduced if the nodes are re-ordered so that the non-zero coefficients cluster more tightly around the diagonal.
|
||||||
|
|
||||||
EPANET's original node re-ordering scheme has been replaced by the more powerful **Multiple Minimum Degree (MMD)** algorithm. On a series of eight networks ranging in size from 7,700 to 100,000 nodes **MMD** reduced the solution time for a single period (steady state) hydraulic analysis by an average of more than 50%.
|
EPANET's original node re-ordering scheme has been replaced by the more powerful **Multiple Minimum Degree (MMD)** algorithm. On a series of eight networks ranging in size from 7,700 to 100,000 nodes **MMD** reduced the solution time for a single period (steady state) hydraulic analysis by an average of 58%.
|
||||||
|
|
||||||
## Pressure Dependent Demands
|
## Pressure Dependent Demands
|
||||||
EPANET has always employed a Demand Driven Analysis (**DDA**) when modeling network hydraulics. Under this approach nodal demands at a given point in time are fixed values that must be delivered no matter what nodal heads and link flows are produced by a hydraulic solution. This can result in situations where required demands are satisfied at nodes that have negative pressures - a physical impossibility.
|
EPANET has always employed a Demand Driven Analysis (**DDA**) when modeling network hydraulics. Under this approach nodal demands at a given point in time are fixed values that must be delivered no matter what nodal heads and link flows are produced by a hydraulic solution. This can result in situations where required demands are satisfied at nodes that have negative pressures - a physical impossibility.
|
||||||
|
|
||||||
To address this issue EPANET has been extended to use a Pressure Driven Analysis (**PDA**) if so desired. Under **PDA**, the demand *D* delivered at a node depends on the node's available pressure *P* according to:
|
To address this issue EPANET has been extended to use a Pressure Driven Analysis (**PDA**) if so desired. Under **PDA**, the demand *D* delivered at a node depends on the node's available pressure *P* according to:
|
||||||
$$D =D_f\left(\frac{P-P_{min}}{P_{req}-P_{min}}\right)^{P_{exp}} for P_{0}<=P<=P_{req}$$where *D<sub>f</sub>* is the full demand required, *P<sub>min</sub>* is the pressure below which demand is zero, *P<sub>req</sub>* is the pressure required to deliver the full required demand and *P<sub>exp</sub>* is an exponent. When *P < P<sub>min</sub>* demand is 0 and when *P > P<sub>req</sub>* demand equals *D<sub>f</sub>*.
|
|
||||||
|
|
||||||
To implement pressure dependent analysis four new parameters have been added to the [OPTIONS] section of the EPANET input file:
|
*D = D<sub>f</sub> [ (P - P<sub>min</sub>) / (P<sub>req</sub> - P<sub>min</sub>) ]<sup>P<sub>exp</sub></sup>*
|
||||||
|
|
||||||
|
where *D<sub>f</sub>* is the full demand required, *P<sub>min</sub>* is the pressure below which demand is zero, *P<sub>req</sub>* is the pressure required to deliver the full required demand and *P<sub>exp</sub>* is an exponent. When *P < P<sub>min</sub>* demand is 0 and when *P > P<sub>req</sub>* demand equals *D<sub>f</sub>*.
|
||||||
|
|
||||||
|
To implement pressure driven analysis four new parameters have been added to the [OPTIONS] section of the EPANET input file:
|
||||||
|
|
||||||
|
|
||||||
| Parameter | Description | Default |
|
| Parameter | Description | Default |
|
||||||
@@ -81,7 +82,8 @@ for the thread-safe API. Some additional points regarding the new **PDA** option
|
|||||||
|
|
||||||
- If no DEMAND MODEL and its parameters are specified then the analysis defaults to being demand driven (**DDA**).
|
- If no DEMAND MODEL and its parameters are specified then the analysis defaults to being demand driven (**DDA**).
|
||||||
- This implementation of **PDA** assumes that the same parameters apply to all nodes in the network. Extending the framework to allow different parameters for specific nodes is straightforward to do but is left as a future feature to implement.
|
- This implementation of **PDA** assumes that the same parameters apply to all nodes in the network. Extending the framework to allow different parameters for specific nodes is straightforward to do but is left as a future feature to implement.
|
||||||
- *P<sub>0</sub>* is allowed to equal to *P<sub>req</sub>*. This condition can be used to find a solution that results in the smallest amount of demand reductions needed to insure that no node delivers positive demand at a pressure below *P<sub>min</min>*.
|
- *P<sub>min</sub>* is allowed to equal to *P<sub>req</sub>*. This condition can be used to find a solution that results in the smallest amount of demand reductions needed to insure that no node delivers positive demand at a pressure below *P<sub>min</min>*.
|
||||||
|
|
||||||
|
|
||||||
## Code Changes
|
## Code Changes
|
||||||
|
|
||||||
|
|||||||
@@ -1179,6 +1179,8 @@ extern "C" {
|
|||||||
***************************************************/
|
***************************************************/
|
||||||
int DLLEXPORT EN_createproject(EN_ProjectHandle *ph);
|
int DLLEXPORT EN_createproject(EN_ProjectHandle *ph);
|
||||||
int DLLEXPORT EN_deleteproject(EN_ProjectHandle *ph);
|
int DLLEXPORT EN_deleteproject(EN_ProjectHandle *ph);
|
||||||
|
int DLLEXPORT EN_runproject(EN_ProjectHandle ph, const char *f1, const char *f2,
|
||||||
|
const char *f3, void (*pviewprog)(char *));
|
||||||
|
|
||||||
void DLLEXPORT EN_clearError(EN_ProjectHandle ph);
|
void DLLEXPORT EN_clearError(EN_ProjectHandle ph);
|
||||||
int DLLEXPORT EN_checkError(EN_ProjectHandle ph, char** msg_buffer);
|
int DLLEXPORT EN_checkError(EN_ProjectHandle ph, char** msg_buffer);
|
||||||
|
|||||||
21
src/epanet.c
21
src/epanet.c
@@ -613,6 +613,27 @@ int DLLEXPORT EN_deleteproject(EN_ProjectHandle *ph)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int DLLEXPORT EN_runproject(EN_ProjectHandle ph, const char *f1, const char *f2,
|
||||||
|
const char *f3, void (*pviewprog)(char *))
|
||||||
|
{
|
||||||
|
int errcode = 0;
|
||||||
|
EN_Project *p = NULL;
|
||||||
|
|
||||||
|
ERRCODE(EN_open(ph, f1, f2, f3));
|
||||||
|
p = (EN_Project*)(ph);
|
||||||
|
p->viewprog = pviewprog;
|
||||||
|
|
||||||
|
if (p->out_files.Hydflag != USE) {
|
||||||
|
ERRCODE(EN_solveH(ph));
|
||||||
|
}
|
||||||
|
|
||||||
|
ERRCODE(EN_solveQ(ph));
|
||||||
|
ERRCODE(EN_report(ph));
|
||||||
|
|
||||||
|
EN_close(ph);
|
||||||
|
|
||||||
|
return errcode;
|
||||||
|
}
|
||||||
|
|
||||||
int DLLEXPORT EN_init(EN_ProjectHandle ph, char *f2, char *f3,
|
int DLLEXPORT EN_init(EN_ProjectHandle ph, char *f2, char *f3,
|
||||||
EN_FlowUnits UnitsType, EN_FormType HeadlossFormula)
|
EN_FlowUnits UnitsType, EN_FormType HeadlossFormula)
|
||||||
|
|||||||
238
src/mempool.c
238
src/mempool.c
@@ -1,17 +1,9 @@
|
|||||||
/* mempool.c
|
/* mempool.c
|
||||||
**
|
**
|
||||||
** A simple fast memory allocation package.
|
** A simple fast pooled memory allocation package.
|
||||||
**
|
**
|
||||||
** By Steve Hill in Graphics Gems III, David Kirk (ed.),
|
** Based on code by Steve Hill in Graphics Gems III,
|
||||||
** Academic Press, Boston, MA, 1992
|
** David Kirk (ed.), Academic Press, Boston, MA, 1992
|
||||||
**
|
|
||||||
** Modified by Lew Rossman, 8/13/94.
|
|
||||||
**
|
|
||||||
** AllocInit() - create an alloc pool, returns the old pool handle
|
|
||||||
** Alloc() - allocate memory
|
|
||||||
** AllocReset() - reset the current pool
|
|
||||||
** AllocSetPool() - set the current pool
|
|
||||||
** AllocFree() - free the memory used by the current pool.
|
|
||||||
**
|
**
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -28,94 +20,79 @@
|
|||||||
|
|
||||||
#define ALLOC_BLOCK_SIZE 64000 /*(62*1024)*/
|
#define ALLOC_BLOCK_SIZE 64000 /*(62*1024)*/
|
||||||
|
|
||||||
/*
|
struct MemBlock
|
||||||
** alloc_hdr_t - Header for each block of memory.
|
|
||||||
*/
|
|
||||||
|
|
||||||
typedef struct alloc_hdr_s
|
|
||||||
{
|
{
|
||||||
struct alloc_hdr_s *next; /* Next Block */
|
struct MemBlock *next; // Next block
|
||||||
char *block, /* Start of block */
|
char *block, // Start of block
|
||||||
*free, /* Next free in block */
|
*free, // Next free position in block
|
||||||
*end; /* block + block size */
|
*end; // block + block size
|
||||||
} alloc_hdr_t;
|
};
|
||||||
|
|
||||||
/*
|
struct Mempool
|
||||||
** alloc_root_t - Header for the whole pool.
|
|
||||||
*/
|
|
||||||
|
|
||||||
typedef struct alloc_root_s
|
|
||||||
{
|
{
|
||||||
alloc_hdr_t *first, /* First header in pool */
|
struct MemBlock *first;
|
||||||
*current; /* Current header */
|
struct MemBlock *current;
|
||||||
} alloc_root_t;
|
};
|
||||||
|
|
||||||
/*
|
static struct MemBlock* createMemBlock()
|
||||||
** root - Pointer to the current pool.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static alloc_root_t *root;
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** AllocHdr()
|
|
||||||
**
|
|
||||||
** Private routine to allocate a header and memory block.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static alloc_hdr_t *AllocHdr(void);
|
|
||||||
|
|
||||||
static alloc_hdr_t * AllocHdr()
|
|
||||||
{
|
{
|
||||||
alloc_hdr_t *hdr;
|
struct MemBlock* memBlock = malloc(sizeof(struct MemBlock));
|
||||||
char *block;
|
if (memBlock)
|
||||||
|
{
|
||||||
block = (char *) malloc(ALLOC_BLOCK_SIZE);
|
memBlock->block = malloc(ALLOC_BLOCK_SIZE * sizeof(char));
|
||||||
hdr = (alloc_hdr_t *) malloc(sizeof(alloc_hdr_t));
|
if (memBlock->block == NULL)
|
||||||
|
{
|
||||||
if (hdr == NULL || block == NULL) return(NULL);
|
free(memBlock);
|
||||||
hdr->block = block;
|
return NULL;
|
||||||
hdr->free = block;
|
}
|
||||||
hdr->next = NULL;
|
memBlock->free = memBlock->block;
|
||||||
hdr->end = block + ALLOC_BLOCK_SIZE;
|
memBlock->next = NULL;
|
||||||
|
memBlock->end = memBlock->block + ALLOC_BLOCK_SIZE;
|
||||||
return(hdr);
|
}
|
||||||
|
return memBlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
static void deleteMemBlock(struct MemBlock* memBlock)
|
||||||
** AllocInit()
|
|
||||||
**
|
|
||||||
** Create a new memory pool with one block.
|
|
||||||
** Returns pointer to the new pool.
|
|
||||||
*/
|
|
||||||
|
|
||||||
DLLEXPORT alloc_handle_t * AllocInit()
|
|
||||||
{
|
{
|
||||||
alloc_handle_t *newpool;
|
free(memBlock->block);
|
||||||
root = (alloc_root_t *) malloc(sizeof(alloc_root_t));
|
free(memBlock);
|
||||||
if (root == NULL) {
|
|
||||||
return(NULL);
|
|
||||||
}
|
|
||||||
if ( (root->first = AllocHdr()) == NULL) {
|
|
||||||
return(NULL);
|
|
||||||
}
|
|
||||||
root->current = root->first;
|
|
||||||
newpool = (alloc_handle_t *) root;
|
|
||||||
return(newpool);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
struct Mempool * mempool_create()
|
||||||
** Alloc()
|
{
|
||||||
**
|
struct Mempool *mempool;
|
||||||
** Use as a direct replacement for malloc(). Allocates
|
mempool = (struct Mempool *)malloc(sizeof(struct Mempool));
|
||||||
** memory from the current pool.
|
if (mempool == NULL) return NULL;
|
||||||
*/
|
mempool->first = createMemBlock();
|
||||||
|
mempool->current = mempool->first;
|
||||||
DLLEXPORT char *Alloc(long size)
|
if (mempool->first == NULL) return NULL;
|
||||||
|
return mempool;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mempool_delete(struct Mempool *mempool)
|
||||||
|
{
|
||||||
|
if (mempool == NULL) return;
|
||||||
|
while (mempool->first)
|
||||||
|
{
|
||||||
|
mempool->current = mempool->first->next;
|
||||||
|
deleteMemBlock(mempool->first);
|
||||||
|
mempool->first = mempool->current;
|
||||||
|
}
|
||||||
|
free(mempool);
|
||||||
|
mempool = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mempool_reset(struct Mempool *mempool)
|
||||||
|
{
|
||||||
|
mempool->current = mempool->first;
|
||||||
|
mempool->current->free = mempool->current->block;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
char * mempool_alloc(struct Mempool *mempool, size_t size)
|
||||||
{
|
{
|
||||||
alloc_hdr_t *hdr = root->current;
|
|
||||||
char* ptr;
|
char* ptr;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -124,86 +101,37 @@ DLLEXPORT char *Alloc(long size)
|
|||||||
*/
|
*/
|
||||||
size = (size + 3) & 0xfffffffc;
|
size = (size + 3) & 0xfffffffc;
|
||||||
|
|
||||||
ptr = hdr->free;
|
if (!mempool->current) return NULL;
|
||||||
hdr->free += size;
|
ptr = mempool->current->free;
|
||||||
|
mempool->current->free += size;
|
||||||
|
|
||||||
/* Check if the current block is exhausted. */
|
// Check if the current block is exhausted
|
||||||
|
|
||||||
if (hdr->free >= hdr->end)
|
if (mempool->current->free >= mempool->current->end)
|
||||||
{
|
{
|
||||||
/* Is the next block already allocated? */
|
// Is the next block already allocated?
|
||||||
|
|
||||||
if (hdr->next != NULL)
|
if (mempool->current->next)
|
||||||
{
|
{
|
||||||
/* re-use block */
|
// re-use block
|
||||||
hdr->next->free = hdr->next->block;
|
mempool->current->next->free = mempool->current->next->block;
|
||||||
root->current = hdr->next;
|
mempool->current = mempool->current->next;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* extend the pool with a new block */
|
// extend the pool with a new block
|
||||||
if ( (hdr->next = AllocHdr()) == NULL) return(NULL);
|
mempool->current->next = createMemBlock();
|
||||||
root->current = hdr->next;
|
if (!mempool->current->next) return NULL;
|
||||||
|
mempool->current = mempool->current->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* set ptr to the first location in the next block */
|
// set ptr to the first location in the next block
|
||||||
ptr = root->current->free;
|
|
||||||
root->current->free += size;
|
ptr = mempool->current->free;
|
||||||
|
mempool->current->free += size;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return pointer to allocated memory. */
|
// Return pointer to allocated memory
|
||||||
|
|
||||||
return(ptr);
|
return ptr;
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** AllocSetPool()
|
|
||||||
**
|
|
||||||
** Change the current pool. Return the old pool.
|
|
||||||
*/
|
|
||||||
|
|
||||||
DLLEXPORT alloc_handle_t * AllocSetPool(alloc_handle_t *newpool)
|
|
||||||
{
|
|
||||||
alloc_handle_t *old = (alloc_handle_t *) root;
|
|
||||||
root = (alloc_root_t *) newpool;
|
|
||||||
return(old);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** AllocReset()
|
|
||||||
**
|
|
||||||
** Reset the current pool for re-use. No memory is freed,
|
|
||||||
** so this is very fast.
|
|
||||||
*/
|
|
||||||
|
|
||||||
DLLEXPORT void AllocReset()
|
|
||||||
{
|
|
||||||
root->current = root->first;
|
|
||||||
root->current->free = root->current->block;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** AllocFreePool()
|
|
||||||
**
|
|
||||||
** Free the memory used by the current pool.
|
|
||||||
** Don't use where AllocReset() could be used.
|
|
||||||
*/
|
|
||||||
|
|
||||||
DLLEXPORT void AllocFreePool()
|
|
||||||
{
|
|
||||||
alloc_hdr_t *tmp,
|
|
||||||
*hdr = root->first;
|
|
||||||
|
|
||||||
while (hdr != NULL)
|
|
||||||
{
|
|
||||||
tmp = hdr->next;
|
|
||||||
free((char *) hdr->block);
|
|
||||||
free((char *) hdr);
|
|
||||||
hdr = tmp;
|
|
||||||
}
|
|
||||||
free((char *) root);
|
|
||||||
root = NULL;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,41 +3,17 @@
|
|||||||
**
|
**
|
||||||
** Header for mempool.c
|
** Header for mempool.c
|
||||||
**
|
**
|
||||||
** The type alloc_handle_t provides an opaque reference to the
|
** A simple pooled memory allocator
|
||||||
** alloc pool - only the alloc routines know its structure.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef MEMPOOL_H
|
#ifndef MEMPOOL_H
|
||||||
#define MEMPOOL_H
|
#define MEMPOOL_H
|
||||||
|
|
||||||
#ifndef DLLEXPORT
|
struct Mempool;
|
||||||
#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
|
|
||||||
|
|
||||||
|
struct Mempool * mempool_create();
|
||||||
typedef struct
|
void mempool_delete(struct Mempool *mempool);
|
||||||
{
|
void mempool_reset(struct Mempool *mempool);
|
||||||
long dummy;
|
char * mempool_alloc(struct Mempool *mempool, size_t size);
|
||||||
} alloc_handle_t;
|
|
||||||
|
|
||||||
alloc_handle_t *AllocInit(void);
|
|
||||||
char *Alloc(long);
|
|
||||||
alloc_handle_t *AllocSetPool(alloc_handle_t *);
|
|
||||||
void AllocReset(void);
|
|
||||||
void AllocFreePool(void);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -29,9 +29,9 @@ AUTHOR: L. Rossman
|
|||||||
closequal() -- called from ENcloseQ() in EPANET.C
|
closequal() -- called from ENcloseQ() in EPANET.C
|
||||||
|
|
||||||
Calls are made to:
|
Calls are made to:
|
||||||
AllocInit()
|
mempool_create()
|
||||||
Alloc()
|
mempool_alloc()
|
||||||
AllocFree()
|
mempool_delete()
|
||||||
in MEMPOOL.C to utilize a memory pool to prevent excessive malloc'ing
|
in MEMPOOL.C to utilize a memory pool to prevent excessive malloc'ing
|
||||||
when constantly creating and destroying pipe sub-segments during
|
when constantly creating and destroying pipe sub-segments during
|
||||||
the water quality transport calculations.
|
the water quality transport calculations.
|
||||||
@@ -89,7 +89,7 @@ int openqual(EN_Project *pr)
|
|||||||
|
|
||||||
/* Allocate memory pool for WQ segments */
|
/* Allocate memory pool for WQ segments */
|
||||||
qu->OutOfMemory = FALSE;
|
qu->OutOfMemory = FALSE;
|
||||||
qu->SegPool = AllocInit();
|
qu->SegPool = mempool_create();
|
||||||
if (qu->SegPool == NULL) {
|
if (qu->SegPool == NULL) {
|
||||||
errcode = 101;
|
errcode = 101;
|
||||||
}
|
}
|
||||||
@@ -193,8 +193,7 @@ void initqual(EN_Project *pr)
|
|||||||
|
|
||||||
/* Reset memory pool */
|
/* Reset memory pool */
|
||||||
qu->FreeSeg = NULL;
|
qu->FreeSeg = NULL;
|
||||||
AllocSetPool(qu->SegPool);
|
mempool_reset(qu->SegPool);
|
||||||
AllocReset();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize avg. reaction rates */
|
/* Initialize avg. reaction rates */
|
||||||
@@ -438,8 +437,7 @@ int closequal(EN_Project *pr)
|
|||||||
/* Free memory pool */
|
/* Free memory pool */
|
||||||
if (qu->SegPool)
|
if (qu->SegPool)
|
||||||
{
|
{
|
||||||
AllocSetPool(qu->SegPool);
|
mempool_delete(qu->SegPool);
|
||||||
AllocFreePool();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
free(qu->FirstSeg);
|
free(qu->FirstSeg);
|
||||||
@@ -573,7 +571,6 @@ void transport(EN_Project *pr, long tstep)
|
|||||||
|
|
||||||
/* Repeat until elapsed time equals hydraulic time step */
|
/* Repeat until elapsed time equals hydraulic time step */
|
||||||
|
|
||||||
AllocSetPool(qu->SegPool);
|
|
||||||
qtime = 0;
|
qtime = 0;
|
||||||
while (!qu->OutOfMemory && qtime < tstep) { /* Qstep is quality time step */
|
while (!qu->OutOfMemory && qtime < tstep) { /* Qstep is quality time step */
|
||||||
dt = MIN(qu->Qstep, tstep - qtime); /* Current time step */
|
dt = MIN(qu->Qstep, tstep - qtime); /* Current time step */
|
||||||
@@ -793,7 +790,7 @@ void addseg(EN_Project *pr, int k, double v, double c)
|
|||||||
seg = qu->FreeSeg;
|
seg = qu->FreeSeg;
|
||||||
qu->FreeSeg = seg->prev;
|
qu->FreeSeg = seg->prev;
|
||||||
} else {
|
} else {
|
||||||
seg = (struct Sseg *)Alloc(sizeof(struct Sseg));
|
seg = (struct Sseg *) mempool_alloc(qu->SegPool, sizeof(struct Sseg));
|
||||||
if (seg == NULL) {
|
if (seg == NULL) {
|
||||||
qu->OutOfMemory = TRUE;
|
qu->OutOfMemory = TRUE;
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ AUTHOR: L. Rossman
|
|||||||
|
|
||||||
#include "epanet2.h"
|
#include "epanet2.h"
|
||||||
#include "hash.h"
|
#include "hash.h"
|
||||||
#include "mempool.h"
|
|
||||||
#include "util/errormanager.h"
|
#include "util/errormanager.h"
|
||||||
|
|
||||||
|
|
||||||
@@ -538,6 +537,8 @@ typedef struct s_ActItem /* Action list item */
|
|||||||
} ActItem;
|
} ActItem;
|
||||||
|
|
||||||
|
|
||||||
|
// Forward declaration of the Mempool structure defined in mempool.h
|
||||||
|
struct Mempool;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char
|
char
|
||||||
@@ -578,7 +579,7 @@ typedef struct {
|
|||||||
Qtime; /// Current quality time (sec)
|
Qtime; /// Current quality time (sec)
|
||||||
|
|
||||||
char OutOfMemory; /* Out of memory indicator */
|
char OutOfMemory; /* Out of memory indicator */
|
||||||
alloc_handle_t *SegPool; // Memory pool for water quality segments
|
struct Mempool *SegPool; // Memory pool for water quality segments
|
||||||
|
|
||||||
Pseg FreeSeg; /* Pointer to unused segment */
|
Pseg FreeSeg; /* Pointer to unused segment */
|
||||||
Pseg *FirstSeg, /* First (downstream) segment in each pipe */
|
Pseg *FirstSeg, /* First (downstream) segment in each pipe */
|
||||||
|
|||||||
@@ -16,9 +16,18 @@ enable_testing()
|
|||||||
# Sets for output directory for executables and libraries.
|
# Sets for output directory for executables and libraries.
|
||||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
|
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
|
||||||
|
|
||||||
|
if(UNIX)
|
||||||
|
set(CMAKE_CXX_FLAGS "-std=c++11")
|
||||||
|
endif(UNIX)
|
||||||
|
|
||||||
#Prep ourselves for compiling boost
|
#Prep ourselves for compiling boost
|
||||||
find_package(Boost REQUIRED)
|
if(MSVC)
|
||||||
|
set(Boost_DEBUG OFF)
|
||||||
|
set(Boost_DETAILED_FAILURE_MSG OFF)
|
||||||
|
set(Boost_USE_STATIC_LIBS ON)
|
||||||
|
endif(MSVC)
|
||||||
|
set(Boost_THREAD_FOUND OFF)
|
||||||
|
find_package(Boost COMPONENTS thread)
|
||||||
include_directories (${Boost_INCLUDE_DIRS})
|
include_directories (${Boost_INCLUDE_DIRS})
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
481
tests/data/example_0.inp
Normal file
481
tests/data/example_0.inp
Normal file
@@ -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
|
||||||
|
177 25.92 10.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]
|
||||||
178
tests/data/example_1.inp
Normal file
178
tests/data/example_1.inp
Normal file
@@ -0,0 +1,178 @@
|
|||||||
|
[TITLE]
|
||||||
|
EPANET Example Network 1
|
||||||
|
A simple example of modeling chlorine decay. Both bulk and
|
||||||
|
wall reactions are included.
|
||||||
|
|
||||||
|
[JUNCTIONS]
|
||||||
|
;ID Elev Demand Pattern
|
||||||
|
10 710 0 ;
|
||||||
|
11 710 150 ;
|
||||||
|
12 700 150 ;
|
||||||
|
13 695 100 ;
|
||||||
|
21 700 150 ;
|
||||||
|
22 695 200 ;
|
||||||
|
23 690 150 ;
|
||||||
|
31 700 100 ;
|
||||||
|
32 710 100 ;
|
||||||
|
|
||||||
|
[RESERVOIRS]
|
||||||
|
;ID Head Pattern
|
||||||
|
9 800 ;
|
||||||
|
|
||||||
|
[TANKS]
|
||||||
|
;ID Elevation InitLevel MinLevel MaxLevel Diameter MinVol VolCurve
|
||||||
|
2 850 120 100 150 50.5 0 ;
|
||||||
|
|
||||||
|
[PIPES]
|
||||||
|
;ID Node1 Node2 Length Diameter Roughness MinorLoss Status
|
||||||
|
10 10 11 10530 18 100 0 Open ;
|
||||||
|
11 11 12 5280 14 100 0 Open ;
|
||||||
|
12 12 13 5280 10 100 0 Open ;
|
||||||
|
21 21 22 5280 10 100 0 Open ;
|
||||||
|
22 22 23 5280 12 100 0 Open ;
|
||||||
|
31 31 32 5280 6 100 0 Open ;
|
||||||
|
110 2 12 200 18 100 0 Open ;
|
||||||
|
111 11 21 5280 10 100 0 Open ;
|
||||||
|
112 12 22 5280 12 100 0 Open ;
|
||||||
|
113 13 23 5280 8 100 0 Open ;
|
||||||
|
121 21 31 5280 8 100 0 Open ;
|
||||||
|
122 22 32 5280 6 100 0 Open ;
|
||||||
|
|
||||||
|
[PUMPS]
|
||||||
|
;ID Node1 Node2 Parameters
|
||||||
|
9 9 10 HEAD 1 ;
|
||||||
|
|
||||||
|
[VALVES]
|
||||||
|
;ID Node1 Node2 Diameter Type Setting MinorLoss
|
||||||
|
|
||||||
|
[TAGS]
|
||||||
|
|
||||||
|
[DEMANDS]
|
||||||
|
;Junction Demand Pattern Category
|
||||||
|
|
||||||
|
[STATUS]
|
||||||
|
;ID Status/Setting
|
||||||
|
|
||||||
|
[PATTERNS]
|
||||||
|
;ID Multipliers
|
||||||
|
;Demand Pattern
|
||||||
|
1 1.0 1.2 1.4 1.6 1.4 1.2
|
||||||
|
1 1.0 0.8 0.6 0.4 0.6 0.8
|
||||||
|
|
||||||
|
[CURVES]
|
||||||
|
;ID X-Value Y-Value
|
||||||
|
;PUMP: Pump Curve for Pump 9
|
||||||
|
1 1500 250
|
||||||
|
|
||||||
|
[CONTROLS]
|
||||||
|
LINK 9 OPEN IF NODE 2 BELOW 110
|
||||||
|
LINK 9 CLOSED IF NODE 2 ABOVE 140
|
||||||
|
|
||||||
|
|
||||||
|
[RULES]
|
||||||
|
|
||||||
|
[ENERGY]
|
||||||
|
Global Efficiency 75
|
||||||
|
Global Price 0.0
|
||||||
|
Demand Charge 0.0
|
||||||
|
|
||||||
|
[EMITTERS]
|
||||||
|
;Junction Coefficient
|
||||||
|
|
||||||
|
[QUALITY]
|
||||||
|
;Node InitQual
|
||||||
|
10 0.5
|
||||||
|
11 0.5
|
||||||
|
12 0.5
|
||||||
|
13 0.5
|
||||||
|
21 0.5
|
||||||
|
22 0.5
|
||||||
|
23 0.5
|
||||||
|
31 0.5
|
||||||
|
32 0.5
|
||||||
|
9 1.0
|
||||||
|
2 1.0
|
||||||
|
|
||||||
|
[SOURCES]
|
||||||
|
;Node Type Quality Pattern
|
||||||
|
|
||||||
|
[REACTIONS]
|
||||||
|
;Type Pipe/Tank Coefficient
|
||||||
|
|
||||||
|
|
||||||
|
[REACTIONS]
|
||||||
|
Order Bulk 1
|
||||||
|
Order Tank 1
|
||||||
|
Order Wall 1
|
||||||
|
Global Bulk -.5
|
||||||
|
Global Wall -1
|
||||||
|
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 2: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 Chlorine mg/L
|
||||||
|
Diffusivity 1.0
|
||||||
|
Tolerance 0.01
|
||||||
|
|
||||||
|
[COORDINATES]
|
||||||
|
;Node X-Coord Y-Coord
|
||||||
|
10 20.00 70.00
|
||||||
|
11 30.00 70.00
|
||||||
|
12 50.00 70.00
|
||||||
|
13 70.00 70.00
|
||||||
|
21 30.00 40.00
|
||||||
|
22 50.00 40.00
|
||||||
|
23 70.00 40.00
|
||||||
|
31 30.00 10.00
|
||||||
|
32 50.00 10.00
|
||||||
|
9 10.00 70.00
|
||||||
|
2 50.00 90.00
|
||||||
|
|
||||||
|
[VERTICES]
|
||||||
|
;Link X-Coord Y-Coord
|
||||||
|
|
||||||
|
[LABELS]
|
||||||
|
;X-Coord Y-Coord Label & Anchor Node
|
||||||
|
6.99 73.63 "Source"
|
||||||
|
13.48 68.13 "Pump"
|
||||||
|
43.85 91.21 "Tank"
|
||||||
|
|
||||||
|
[BACKDROP]
|
||||||
|
DIMENSIONS 7.00 6.00 73.00 94.00
|
||||||
|
UNITS None
|
||||||
|
FILE
|
||||||
|
OFFSET 0.00 0.00
|
||||||
|
|
||||||
|
[END]
|
||||||
65
tests/test_reent.cpp
Normal file
65
tests/test_reent.cpp
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
/*
|
||||||
|
* test_reent.cpp
|
||||||
|
*
|
||||||
|
* Created: 8/30/2018
|
||||||
|
* Author: Michael E. Tryby
|
||||||
|
* US EPA - ORD/NRMRL
|
||||||
|
*
|
||||||
|
* Multi-threading / reentrancy test for EPANET Toolkit API.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include <boost/thread.hpp>
|
||||||
|
|
||||||
|
#include "epanet2.h"
|
||||||
|
|
||||||
|
#define NUM_THREADS 2
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
void epanet_thread(long i)
|
||||||
|
{
|
||||||
|
int errorcode = 0;
|
||||||
|
EN_ProjectHandle ph;
|
||||||
|
|
||||||
|
string prefix = "example_";
|
||||||
|
string suffix = ".inp";
|
||||||
|
string input = prefix + to_string(static_cast<long long>(i)) + suffix;
|
||||||
|
|
||||||
|
suffix = ".rpt";
|
||||||
|
string report = prefix + to_string(static_cast<long long>(i)) + suffix;
|
||||||
|
|
||||||
|
suffix = ".out";
|
||||||
|
string output = prefix + to_string(static_cast<long long>(i)) + suffix;
|
||||||
|
|
||||||
|
printf("Thread #%ld starting EPANET ...\n", i);
|
||||||
|
|
||||||
|
EN_createproject(&ph);
|
||||||
|
errorcode = EN_runproject(ph, input.c_str(), report.c_str(), output.c_str(), NULL);
|
||||||
|
EN_deleteproject(&ph);
|
||||||
|
|
||||||
|
printf("Thread #%ld EPANET done. Status = %d\n", i, errorcode);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
long i;
|
||||||
|
boost::thread *threads[NUM_THREADS];
|
||||||
|
|
||||||
|
for (i = 0; i < NUM_THREADS; i++) {
|
||||||
|
threads[i] = new boost::thread(epanet_thread, i);
|
||||||
|
printf("Main: creating thread %ld.\n", i);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < NUM_THREADS; i++) {
|
||||||
|
threads[i]->join();
|
||||||
|
printf("Main: joining thread %ld.\n", i);
|
||||||
|
delete threads[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Main: program completed. Exiting.\n");
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user