Work in progress
Implementing generic demand pattern lists. Compiles but does not run.
This commit is contained in:
30
src/demand.c
30
src/demand.c
@@ -3,7 +3,7 @@
|
||||
Project: OWA EPANET
|
||||
Version: 2.2
|
||||
Module: demand.c
|
||||
Description: demand pattern list
|
||||
Description: data for demand pattern list
|
||||
Authors: see AUTHORS
|
||||
Copyright: see AUTHORS
|
||||
License: see LICENSE
|
||||
@@ -25,12 +25,12 @@ typedef struct demand_data_s
|
||||
} demand_data_t;
|
||||
|
||||
|
||||
demand_data_t *create_demand_data(double base_demand, int pat_index, char *cat_name)
|
||||
demand_data_t *create_demand_data(double base_demand, int pattern_index, char *category_name)
|
||||
{
|
||||
demand_data_t *demand_data = (demand_data_t *)malloc(sizeof(demand_data_t));
|
||||
|
||||
demand_data->base_demand = base_demand;
|
||||
demand_data->pattern_index = pat_index;
|
||||
demand_data->pattern_index = pattern_index;
|
||||
|
||||
if (cat_name)
|
||||
demand_data->category_name = strdup(cat_name);
|
||||
@@ -72,20 +72,30 @@ bool convert_units(list_node_t *lnode, double unit_conversion)
|
||||
|
||||
double get_base_demand(demand_data_t *data)
|
||||
{
|
||||
return data->base_demand;
|
||||
return get_demand_data(lnode)->base_demand;
|
||||
}
|
||||
|
||||
void set_base_demand(demand_data_t *data, double base_demand)
|
||||
void set_base_demand(list_node_t *lnode, double base_demand)
|
||||
{
|
||||
data->base_demand = base_demand;
|
||||
get_demand_data(lnode)->base_demand = base_demand;
|
||||
}
|
||||
|
||||
int get_pattern_index(demand_data_t *data)
|
||||
int get_pattern_index(list_node_t *lnode)
|
||||
{
|
||||
return data->pattern_index;
|
||||
return get_demand_data(lnode)->pattern_index;
|
||||
}
|
||||
|
||||
char *get_category_name(demand_data_t *data)
|
||||
void set_pattern_index(list_node_t *lnode, int pattern_index)
|
||||
{
|
||||
return data->category_name;
|
||||
get_demand_data(lnode)->pattern_index = pattern_index;
|
||||
}
|
||||
|
||||
char *get_category_name(list_node_t *lnode)
|
||||
{
|
||||
return get_demand_data(lnode)->category_name;
|
||||
}
|
||||
|
||||
void set_category_name(list_node_t *lnode, char *category_name)
|
||||
{
|
||||
get_demand_data(lnode)->category_name = strdup(category_name);
|
||||
}
|
||||
|
||||
16
src/demand.h
16
src/demand.h
@@ -3,7 +3,7 @@
|
||||
Project: OWA EPANET
|
||||
Version: 2.2
|
||||
Module: demand.h
|
||||
Description: demand pattern list
|
||||
Description: data for demand pattern list
|
||||
Authors: see AUTHORS
|
||||
Copyright: see AUTHORS
|
||||
License: see LICENSE
|
||||
@@ -30,19 +30,21 @@ void delete_demand_data(void *data);
|
||||
|
||||
size_t get_demand_data_size(void);
|
||||
|
||||
demand_data_t *get_demand_data(list_node_t *lnode);
|
||||
|
||||
|
||||
bool convert_units(list_node_t *lnode, double unit_conversion);
|
||||
|
||||
|
||||
double get_base_demand(demand_data_t *data);
|
||||
double get_base_demand(list_node_t *lnode);
|
||||
void set_base_demand(list_node_t *lnode, double base_demand);
|
||||
|
||||
void set_base_demand(demand_data_t *data, double base_demand);
|
||||
int get_pattern_index(list_node_t *lnode);
|
||||
void set_pattern_index(list_node_t *lnode, int pattern_index);
|
||||
|
||||
int get_pattern_index(demand_data_t *data);
|
||||
char *get_category_name(list_node_t *lnode);
|
||||
void set_category_name(list_node_t *lnode, char *category_name);
|
||||
|
||||
char *get_category_name(demand_data_t *data);
|
||||
// Make this private?
|
||||
demand_data_t *get_demand_data(list_node_t *lnode);
|
||||
|
||||
|
||||
#endif /* DEMAND_H */
|
||||
|
||||
220
src/epanet.c
220
src/epanet.c
@@ -31,6 +31,7 @@
|
||||
#include "enumstxt.h"
|
||||
|
||||
#include "util/cstr_helper.h"
|
||||
#include "demand.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#define snprintf _snprintf
|
||||
@@ -1724,7 +1725,7 @@ int DLLEXPORT EN_addnode(EN_Project p, char *id, int nodeType)
|
||||
int i, nIdx;
|
||||
int index;
|
||||
int size;
|
||||
struct Sdemand *demand;
|
||||
// struct Sdemand *demand;
|
||||
Stank *tank;
|
||||
Snode *node;
|
||||
Scontrol *control;
|
||||
@@ -1757,12 +1758,12 @@ int DLLEXPORT EN_addnode(EN_Project p, char *id, int nodeType)
|
||||
nIdx = net->Njuncs;
|
||||
node = &net->Node[nIdx];
|
||||
|
||||
demand = (struct Sdemand *)malloc(sizeof(struct Sdemand));
|
||||
demand->Base = 0.0;
|
||||
demand->Pat = 0;
|
||||
demand->Name = NULL;
|
||||
demand->next = NULL;
|
||||
node->D = demand;
|
||||
//demand = (struct Sdemand *)malloc(sizeof(struct Sdemand));
|
||||
//demand->Base = 0.0;
|
||||
//demand->Pat = 0;
|
||||
//demand->Name = NULL;
|
||||
//demand->next = NULL;
|
||||
node->D = NULL;
|
||||
|
||||
// shift rest of Node array
|
||||
for (index = net->Nnodes; index >= net->Njuncs; index--)
|
||||
@@ -1862,7 +1863,7 @@ int DLLEXPORT EN_deletenode(EN_Project p, int index, int actionCode)
|
||||
|
||||
int i, nodeType, tankindex;
|
||||
Snode *node;
|
||||
Pdemand demand, nextdemand;
|
||||
list_t *demand;
|
||||
|
||||
// Cannot modify network structure while solvers are active
|
||||
if (!p->Openflag) return 102;
|
||||
@@ -1896,13 +1897,14 @@ int DLLEXPORT EN_deletenode(EN_Project p, int index, int actionCode)
|
||||
|
||||
// Free memory allocated to node's demands, WQ source & comment
|
||||
demand = node->D;
|
||||
while (demand != NULL)
|
||||
{
|
||||
nextdemand = demand->next;
|
||||
free(demand->Name);
|
||||
free(demand);
|
||||
demand = nextdemand;
|
||||
}
|
||||
delete_list(demand);
|
||||
// while (demand != NULL)
|
||||
// {
|
||||
// nextdemand = demand->next;
|
||||
// free(demand->Name);
|
||||
// free(demand);
|
||||
// demand = nextdemand;
|
||||
// }
|
||||
free(node->S);
|
||||
free(node->Comment);
|
||||
|
||||
@@ -2072,7 +2074,7 @@ int DLLEXPORT EN_getnodevalue(EN_Project p, int index, int property, double *val
|
||||
Quality *qual = &p->quality;
|
||||
|
||||
double v = 0.0;
|
||||
Pdemand demand;
|
||||
//Pdemand demand;
|
||||
Psource source;
|
||||
|
||||
Snode *Node = net->Node;
|
||||
@@ -2102,10 +2104,14 @@ int DLLEXPORT EN_getnodevalue(EN_Project p, int index, int property, double *val
|
||||
// NOTE: primary demand category is last on demand list
|
||||
if (index <= nJuncs)
|
||||
{
|
||||
for (demand = Node[index].D; demand != NULL; demand = demand->next)
|
||||
{
|
||||
v = (demand->Base);
|
||||
}
|
||||
list_t *demand = Node[index].D;
|
||||
if (demand)
|
||||
v = get_base_demand(tail_list(demand));
|
||||
|
||||
//for (demand = Node[index].D; demand != NULL; demand = demand->next)
|
||||
//{
|
||||
// v = (demand->Base);
|
||||
//}
|
||||
}
|
||||
v *= Ucf[FLOW];
|
||||
break;
|
||||
@@ -2115,10 +2121,13 @@ int DLLEXPORT EN_getnodevalue(EN_Project p, int index, int property, double *val
|
||||
// NOTE: primary demand category is last on demand list
|
||||
if (index <= nJuncs)
|
||||
{
|
||||
for (demand = Node[index].D; demand != NULL; demand = demand->next)
|
||||
{
|
||||
v = (double)(demand->Pat);
|
||||
}
|
||||
list_t *demand = Node[index].D;
|
||||
if (demand)
|
||||
v = get_pattern_index(tail_list(demand));
|
||||
//for (demand = Node[index].D; demand != NULL; demand = demand->next)
|
||||
//{
|
||||
// v = (double)(demand->Pat);
|
||||
//}
|
||||
}
|
||||
else v = (double)(Tank[index - nJuncs].Pat);
|
||||
break;
|
||||
@@ -2273,7 +2282,7 @@ int DLLEXPORT EN_setnodevalue(EN_Project p, int index, int property, double valu
|
||||
double *Ucf = p->Ucf;
|
||||
|
||||
int i, j, n;
|
||||
Pdemand demand;
|
||||
// Pdemand demand;
|
||||
Psource source;
|
||||
double hTmp;
|
||||
|
||||
@@ -2299,10 +2308,13 @@ int DLLEXPORT EN_setnodevalue(EN_Project p, int index, int property, double valu
|
||||
// NOTE: primary demand category is last on demand list
|
||||
if (index <= nJuncs)
|
||||
{
|
||||
for (demand = Node[index].D; demand != NULL; demand = demand->next)
|
||||
{
|
||||
if (demand->next == NULL) demand->Base = value / Ucf[FLOW];
|
||||
}
|
||||
list_t *demand = Node[index].D;
|
||||
if (demand)
|
||||
set_base_demand(tail_list(demand), value / Ucf[FLOW]);
|
||||
// for (demand = Node[index].D; demand != NULL; demand = demand->next)
|
||||
// {
|
||||
// if (demand->next == NULL) demand->Base = value / Ucf[FLOW];
|
||||
// }
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -2312,10 +2324,13 @@ int DLLEXPORT EN_setnodevalue(EN_Project p, int index, int property, double valu
|
||||
if (j < 0 || j > nPats) return 205;
|
||||
if (index <= nJuncs)
|
||||
{
|
||||
for (demand = Node[index].D; demand != NULL; demand = demand->next)
|
||||
{
|
||||
if (demand->next == NULL) demand->Pat = j;
|
||||
}
|
||||
list_t *demand = Node[index].D;
|
||||
if (demand)
|
||||
set_pattern_index(tail_list(demand), j);
|
||||
//for (demand = Node[index].D; demand != NULL; demand = demand->next)
|
||||
//{
|
||||
// if (demand->next == NULL) demand->Pat = j;
|
||||
//}
|
||||
}
|
||||
else Tank[index - nJuncs].Pat = j;
|
||||
break;
|
||||
@@ -2512,7 +2527,7 @@ int DLLEXPORT EN_setjuncdata(EN_Project p, int index, double elev,
|
||||
|
||||
int i, patIndex = 0;
|
||||
Snode *Node = net->Node;
|
||||
Pdemand demand;
|
||||
//Pdemand demand;
|
||||
|
||||
// Check that junction exists
|
||||
if (!p->Openflag) return 102;
|
||||
@@ -2534,14 +2549,25 @@ int DLLEXPORT EN_setjuncdata(EN_Project p, int index, double elev,
|
||||
|
||||
// Assign values to junction's parameters
|
||||
Node[index].El = elev / p->Ucf[ELEV];
|
||||
for (demand = Node[index].D; demand != NULL; demand = demand->next)
|
||||
{
|
||||
if (demand->next == NULL)
|
||||
{
|
||||
demand->Base = dmnd / p->Ucf[FLOW];
|
||||
demand->Pat = patIndex;
|
||||
}
|
||||
|
||||
list_t *demand_list = Node[index].D;
|
||||
if (!demand_list) {
|
||||
demand_list = create_list(get_demand_data_size(), delete_demand_data);
|
||||
if (!demand_list) return 101;
|
||||
}
|
||||
demand_data_t *demand_data = create_demand_data(dmnd / p->Ucf[FLOW], patIndex, NULL);
|
||||
if (!demand_data) return 101;
|
||||
|
||||
append_list(demand_list, &demand_data);
|
||||
|
||||
//for (demand = Node[index].D; demand != NULL; demand = demand->next)
|
||||
//{
|
||||
// if (demand->next == NULL)
|
||||
// {
|
||||
// demand->Base = dmnd / p->Ucf[FLOW];
|
||||
// demand->Pat = patIndex;
|
||||
// }
|
||||
//}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2722,16 +2748,20 @@ int DLLEXPORT EN_getnumdemands(EN_Project p, int nodeIndex, int *numDemands)
|
||||
**----------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
Pdemand d;
|
||||
int n = 0;
|
||||
//Pdemand d;
|
||||
//int n = 0;
|
||||
|
||||
// Check for valid arguments
|
||||
if (!p->Openflag) return 102;
|
||||
if (nodeIndex <= 0 || nodeIndex > p->network.Nnodes) return 203;
|
||||
|
||||
// Count the number of demand categories
|
||||
for (d = p->network.Node[nodeIndex].D; d != NULL; d = d->next) n++;
|
||||
*numDemands = n;
|
||||
list_t *demand_list = p->network.Node[nodeIndex].D;
|
||||
if (!demand_list)
|
||||
*numDemands = 0;
|
||||
else
|
||||
*numDemands = size_list(demand_list);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2746,8 +2776,8 @@ int DLLEXPORT EN_getbasedemand(EN_Project p, int nodeIndex, int demandIndex,
|
||||
**----------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
Pdemand d;
|
||||
int n = 1;
|
||||
//Pdemand d;
|
||||
//int n; //= 1;
|
||||
|
||||
// Check for valid arguments
|
||||
if (!p->Openflag) return 102;
|
||||
@@ -2756,10 +2786,13 @@ int DLLEXPORT EN_getbasedemand(EN_Project p, int nodeIndex, int demandIndex,
|
||||
// Retrieve demand for specified category
|
||||
if (nodeIndex <= p->network.Njuncs)
|
||||
{
|
||||
for (d = p->network.Node[nodeIndex].D; n < demandIndex && d->next != NULL;
|
||||
d = d->next) n++;
|
||||
if (n != demandIndex) return 253;
|
||||
*baseDemand = (double)(d->Base * p->Ucf[FLOW]);
|
||||
// Locate demand category record and assign demandName to it
|
||||
list_t *dlist = p->network.Node[nodeIndex].D;
|
||||
list_node_t *lnode = get_nth_list(dlist, demandIndex);
|
||||
if (!lnode)
|
||||
return 253;
|
||||
else
|
||||
*baseDemand = get_base_demand(lnode) * p->Ucf[FLOW];
|
||||
}
|
||||
else *baseDemand = (double)(0.0);
|
||||
return 0;
|
||||
@@ -2777,9 +2810,6 @@ int DLLEXPORT EN_setbasedemand(EN_Project p, int nodeIndex, int demandIndex,
|
||||
**----------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
Pdemand d;
|
||||
int n = 1;
|
||||
|
||||
// Check for valid arguments
|
||||
if (!p->Openflag) return 102;
|
||||
if (nodeIndex <= 0 || nodeIndex > p->network.Nnodes) return 203;
|
||||
@@ -2787,10 +2817,13 @@ int DLLEXPORT EN_setbasedemand(EN_Project p, int nodeIndex, int demandIndex,
|
||||
// Set baseline demand for specified category
|
||||
if (nodeIndex <= p->network.Njuncs)
|
||||
{
|
||||
for (d = p->network.Node[nodeIndex].D; n < demandIndex && d->next != NULL;
|
||||
d = d->next) n++;
|
||||
if (n != demandIndex) return 253;
|
||||
d->Base = baseDemand / p->Ucf[FLOW];
|
||||
// Locate demand category record and assign demandName to it
|
||||
list_t *dlist = p->network.Node[nodeIndex].D;
|
||||
list_node_t *lnode = get_nth_list(dlist, demandIndex);
|
||||
if (!lnode)
|
||||
return 253;
|
||||
else
|
||||
set_base_demand(lnode, baseDemand / p->Ucf[FLOW]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -2806,8 +2839,8 @@ int DLLEXPORT EN_getdemandname(EN_Project p, int nodeIndex, int demandIndex,
|
||||
**----------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
Pdemand d;
|
||||
int n = 1;
|
||||
//Pdemand d;
|
||||
//int n = 1;
|
||||
|
||||
strcpy(demandName, "");
|
||||
|
||||
@@ -2816,12 +2849,19 @@ int DLLEXPORT EN_getdemandname(EN_Project p, int nodeIndex, int demandIndex,
|
||||
if (nodeIndex <= 0 || nodeIndex > p->network.Njuncs) return 203;
|
||||
|
||||
// Locate demand category record and retrieve its name
|
||||
for (d = p->network.Node[nodeIndex].D;
|
||||
n < demandIndex && d->next != NULL; d = d->next) n++;
|
||||
if (n != demandIndex) return 253;
|
||||
list_t *dlist = p->network.Node[nodeIndex].D;
|
||||
list_node_t *lnode = get_nth_list(dlist, demandIndex);
|
||||
if (!lnode)
|
||||
return 253;
|
||||
else
|
||||
demandName = get_category_name(lnode);
|
||||
|
||||
if (d->Name) strcpy(demandName, d->Name);
|
||||
else demandName[0] = '\0';
|
||||
//for (d = p->network.Node[nodeIndex].D;
|
||||
// n < demandIndex && d->next != NULL; d = d->next) n++;
|
||||
//if (n != demandIndex) return 253;
|
||||
|
||||
//if (d->Name) strcpy(demandName, d->Name);
|
||||
//else demandName[0] = '\0';
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2837,8 +2877,8 @@ int DLLEXPORT EN_setdemandname(EN_Project p, int nodeIndex, int demandIndex,
|
||||
**----------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
Pdemand d;
|
||||
int n = 1;
|
||||
//Pdemand d;
|
||||
//int n = 1;
|
||||
|
||||
// Check for valid arguments
|
||||
if (!p->Openflag) return 102;
|
||||
@@ -2848,10 +2888,13 @@ int DLLEXPORT EN_setdemandname(EN_Project p, int nodeIndex, int demandIndex,
|
||||
if (strlen(demandName) > MAXID) return 250;
|
||||
|
||||
// Locate demand category record and assign demandName to it
|
||||
for (d = p->network.Node[nodeIndex].D;
|
||||
n < demandIndex && d->next != NULL; d = d->next) n++;
|
||||
if (n != demandIndex) return 253;
|
||||
d->Name = xstrcpy(&d->Name, demandName, MAXID);
|
||||
list_t *dlist = p->network.Node[nodeIndex].D;
|
||||
list_node_t *lnode = get_nth_list(dlist, demandIndex);
|
||||
if (!lnode)
|
||||
return 253;
|
||||
else
|
||||
set_category_name(lnode, demandName);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2867,16 +2910,21 @@ int DLLEXPORT EN_getdemandpattern(EN_Project p, int nodeIndex, int demandIndex,
|
||||
**----------------------------------------------------------------
|
||||
*/
|
||||
{
|
||||
Pdemand d;
|
||||
int n = 1;
|
||||
//Pdemand d;
|
||||
//int n = 1;
|
||||
|
||||
// Check for valid arguments
|
||||
if (!p->Openflag) return 102;
|
||||
if (nodeIndex <= 0 || nodeIndex > p->network.Nnodes) return 203;
|
||||
for (d = p->network.Node[nodeIndex].D;
|
||||
n < demandIndex && d->next != NULL; d = d->next) n++;
|
||||
if (n != demandIndex) return 253;
|
||||
*patIndex = d->Pat;
|
||||
|
||||
// Locate demand category record and assign demandName to it
|
||||
list_t *dlist = p->network.Node[nodeIndex].D;
|
||||
list_node_t *lnode = get_nth_list(dlist, demandIndex);
|
||||
if (!lnode)
|
||||
return 253;
|
||||
else
|
||||
*patIndex = get_pattern_index(lnode);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2894,8 +2942,8 @@ int DLLEXPORT EN_setdemandpattern(EN_Project p, int nodeIndex, int demandIndex,
|
||||
{
|
||||
Network *net = &p->network;
|
||||
|
||||
Pdemand d;
|
||||
int n = 1;
|
||||
//Pdemand d;
|
||||
//int n = 1;
|
||||
|
||||
// Check for valid arguments
|
||||
if (!p->Openflag) return 102;
|
||||
@@ -2903,12 +2951,14 @@ int DLLEXPORT EN_setdemandpattern(EN_Project p, int nodeIndex, int demandIndex,
|
||||
if (patIndex <= 0 || patIndex > net->Npats) return 205;
|
||||
|
||||
// Locate demand category record and assign time pattern to it
|
||||
if (nodeIndex <= net->Njuncs)
|
||||
{
|
||||
for (d = net->Node[nodeIndex].D;
|
||||
n < demandIndex && d->next != NULL; d = d->next) n++;
|
||||
if (n != demandIndex) return 253;
|
||||
d->Pat = patIndex;
|
||||
if (nodeIndex <= net->Njuncs) {
|
||||
|
||||
list_t *dlist = p->network.Node[nodeIndex].D;
|
||||
list_node_t *lnode = get_nth_list(dlist, demandIndex);
|
||||
if (!lnode)
|
||||
return 253;
|
||||
else
|
||||
set_pattern_index(lnode, patIndex);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -27,6 +27,9 @@
|
||||
#include "funcs.h"
|
||||
#include "text.h"
|
||||
|
||||
#include "demand.h"
|
||||
|
||||
|
||||
const double QZERO = 1.e-6; // Equivalent to zero flow in cfs
|
||||
|
||||
// Imported functions
|
||||
@@ -553,7 +556,7 @@ void demands(Project *pr)
|
||||
int i ,j, n;
|
||||
long k, p;
|
||||
double djunc, sum;
|
||||
Pdemand demand;
|
||||
// Pdemand demand;
|
||||
|
||||
// Determine total elapsed number of pattern periods
|
||||
p = (time->Htime + time->Pstart) / time->Pstep;
|
||||
@@ -563,12 +566,14 @@ void demands(Project *pr)
|
||||
for (i = 1; i <= net->Njuncs; i++)
|
||||
{
|
||||
sum = 0.0;
|
||||
for (demand = net->Node[i].D; demand != NULL; demand = demand->next)
|
||||
list_t *dlist = net->Node[i].D;
|
||||
list_node_t *lnode;
|
||||
for (lnode = first_list(dlist); done_list(lnode); lnode = next_list(lnode))
|
||||
{
|
||||
// pattern period (k) = (elapsed periods) modulus (periods per pattern)
|
||||
j = demand->Pat;
|
||||
j = get_pattern_index(lnode);
|
||||
k = p % (long) net->Pattern[j].Length;
|
||||
djunc = (demand->Base) * net->Pattern[j].F[k] * hyd->Dmult;
|
||||
djunc = (get_base_demand(lnode)) * net->Pattern[j].F[k] * hyd->Dmult;
|
||||
if (djunc > 0.0) hyd->Dsystem += djunc;
|
||||
sum += djunc;
|
||||
}
|
||||
|
||||
@@ -28,6 +28,8 @@ Last Updated: 04/03/2019
|
||||
#include "hash.h"
|
||||
#include "text.h"
|
||||
|
||||
#include "demand.h"
|
||||
|
||||
// Defined in enumstxt.h in EPANET.C
|
||||
extern char *LinkTxt[];
|
||||
extern char *FormTxt[];
|
||||
@@ -137,7 +139,7 @@ int saveinpfile(Project *pr, const char *fname)
|
||||
int i, j, n;
|
||||
double d, kc, ke, km, ucf;
|
||||
char s[MAXLINE + 1], s1[MAXLINE + 1], s2[MAXLINE + 1];
|
||||
Pdemand demand;
|
||||
//Pdemand demand;
|
||||
Psource source;
|
||||
FILE *f;
|
||||
Slink *link;
|
||||
@@ -329,16 +331,22 @@ int saveinpfile(Project *pr, const char *fname)
|
||||
fprintf(f, "\n\n");
|
||||
fprintf(f, s_DEMANDS);
|
||||
ucf = pr->Ucf[DEMAND];
|
||||
|
||||
list_t *dlist;
|
||||
list_node_t *lnode;
|
||||
|
||||
for (i = 1; i <= net->Njuncs; i++)
|
||||
{
|
||||
node = &net->Node[i];
|
||||
for (demand = node->D; demand != NULL; demand = demand->next)
|
||||
{
|
||||
sprintf(s, " %-31s %14.6f", node->ID, ucf * demand->Base);
|
||||
if ((j = demand->Pat) > 0) sprintf(s1, " %-31s", net->Pattern[j].ID);
|
||||
if (dlist = node->D) {
|
||||
for (lnode = first_list(dlist); done_list(lnode); lnode = next_list(lnode)) {
|
||||
|
||||
sprintf(s, " %-31s %14.6f", node->ID, ucf * get_base_demand(lnode));
|
||||
if ((j = get_pattern_index(lnode)) > 0) sprintf(s1, " %-31s", net->Pattern[j].ID);
|
||||
else strcpy(s1, " ");
|
||||
fprintf(f, "\n%s %-31s", s, s1);
|
||||
if (demand->Name) fprintf(f, " ;%s", demand->Name);
|
||||
if (get_category_name(lnode)) fprintf(f, " ;%s", get_category_name(lnode));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -29,6 +29,8 @@
|
||||
#include "types.h"
|
||||
#include "funcs.h"
|
||||
|
||||
#include "demand.h"
|
||||
|
||||
int openfiles(Project *pr, const char *f1, const char *f2, const char *f3)
|
||||
/*----------------------------------------------------------------
|
||||
** Input: f1 = pointer to name of input file
|
||||
@@ -385,7 +387,7 @@ void freedata(Project *pr)
|
||||
*/
|
||||
{
|
||||
int j;
|
||||
Pdemand demand, nextdemand;
|
||||
//Pdemand demand, nextdemand;
|
||||
|
||||
// Free memory for computed results
|
||||
free(pr->hydraul.NodeDemand);
|
||||
@@ -404,14 +406,15 @@ void freedata(Project *pr)
|
||||
for (j = 1; j <= pr->parser.MaxNodes; j++)
|
||||
{
|
||||
// Free memory used for demand category list
|
||||
demand = pr->network.Node[j].D;
|
||||
while (demand != NULL)
|
||||
list_t *demand = pr->network.Node[j].D;
|
||||
delete_list(demand);
|
||||
/*while (demand != NULL)
|
||||
{
|
||||
nextdemand = demand->next;
|
||||
free(demand->Name);
|
||||
free(demand);
|
||||
demand = nextdemand;
|
||||
}
|
||||
}*/
|
||||
// Free memory used for WQ source data
|
||||
free(pr->network.Node[j].S);
|
||||
free(pr->network.Node[j].Comment);
|
||||
@@ -792,6 +795,16 @@ void adjustpattern(int *pat, int index)
|
||||
else if (*pat > index) (*pat)--;
|
||||
}
|
||||
|
||||
|
||||
void _adjustpattern(list_node_t *lnode, int index)
|
||||
{
|
||||
int pat = get_pattern_index(lnode);
|
||||
|
||||
if (pat == index) set_pattern_index(lnode, 0);
|
||||
else if (pat > index) set_pattern_index(lnode, pat--);
|
||||
}
|
||||
|
||||
|
||||
void adjustpatterns(Network *network, int index)
|
||||
/*----------------------------------------------------------------
|
||||
** Input: index = index of time pattern being deleted
|
||||
@@ -801,17 +814,19 @@ void adjustpatterns(Network *network, int index)
|
||||
*/
|
||||
{
|
||||
int j;
|
||||
Pdemand demand;
|
||||
//Pdemand demand;
|
||||
Psource source;
|
||||
|
||||
// Adjust patterns used by junctions
|
||||
for (j = 1; j <= network->Njuncs; j++)
|
||||
{
|
||||
// Adjust demand patterns
|
||||
for (demand = network->Node[j].D; demand != NULL; demand = demand->next)
|
||||
{
|
||||
adjustpattern(&demand->Pat, index);
|
||||
}
|
||||
list_t *dlist = network->Node[j].D;
|
||||
list_node_t *lnode;
|
||||
|
||||
for (lnode = first_list(dlist); done_list(lnode); lnode = next_list(lnode))
|
||||
_adjustpattern(lnode, index);
|
||||
|
||||
// Adjust WQ source patterns
|
||||
source = network->Node[j].S;
|
||||
if (source) adjustpattern(&source->Pat, index);
|
||||
|
||||
@@ -108,8 +108,9 @@ void for_each_list(list_t *list, listIterator iterator)
|
||||
|
||||
list_node_t *node = list->head;
|
||||
bool result = true;
|
||||
|
||||
while(node != NULL && result) {
|
||||
result = iterator(node);
|
||||
result = (iterator);
|
||||
node = node->next;
|
||||
}
|
||||
}
|
||||
@@ -121,6 +122,7 @@ list_node_t *head_list(list_t *list, bool removeFromList)
|
||||
{
|
||||
assert(list->head != NULL);
|
||||
|
||||
if (list) {
|
||||
list_node_t *node = list->head;
|
||||
if (removeFromList) {
|
||||
// Disconnecting head node
|
||||
@@ -129,6 +131,8 @@ list_node_t *head_list(list_t *list, bool removeFromList)
|
||||
}
|
||||
return node;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
list_node_t *tail_list(list_t *list)
|
||||
{
|
||||
@@ -136,6 +140,18 @@ list_node_t *tail_list(list_t *list)
|
||||
return list->tail;
|
||||
}
|
||||
|
||||
list_node_t *get_nth_list(list_t *list, int index)
|
||||
{
|
||||
int n;
|
||||
list_node_t *lnode;
|
||||
|
||||
for (n = 1, lnode = first_list(list); n < index && done_list(lnode); n++, lnode = next_list(lnode));
|
||||
if (n != index)
|
||||
return NULL;
|
||||
else
|
||||
return lnode;
|
||||
}
|
||||
|
||||
int size_list(list_t *list)
|
||||
{
|
||||
return list->logicalLength;
|
||||
@@ -146,6 +162,11 @@ void *get_data(list_node_t *lnode)
|
||||
return lnode->data;
|
||||
}
|
||||
|
||||
list_node_t *get_next(list_node_t *lnode)
|
||||
{
|
||||
return lnode->next;
|
||||
}
|
||||
|
||||
void delete_node(list_t *list, list_node_t *lnode)
|
||||
{
|
||||
if (list->freeFn)
|
||||
@@ -154,29 +175,3 @@ void delete_node(list_t *list, list_node_t *lnode)
|
||||
free(lnode->data);
|
||||
free(lnode);
|
||||
}
|
||||
|
||||
//
|
||||
// Iterator first/done/next operations provide containment for list abstraction
|
||||
// http://www.cs.yale.edu/homes/aspnes/pinewiki/C(2f)Iterators.html
|
||||
// Accessed on April 11, 2019
|
||||
//
|
||||
list_node_t *first_list(list_t *list)
|
||||
{
|
||||
if (list)
|
||||
return list->head;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool done_list(list_node_t *lnode)
|
||||
{
|
||||
return lnode != NULL;
|
||||
}
|
||||
|
||||
list_node_t *next_list(list_node_t *lnode)
|
||||
{
|
||||
if (lnode)
|
||||
return lnode->next;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
@@ -65,6 +66,11 @@ int size_list(list_t *list);
|
||||
*/
|
||||
void *get_data(list_node_t *lnode);
|
||||
|
||||
/**
|
||||
@brief Returns next list node.
|
||||
*/
|
||||
list_node_t *get_next(list_node_t *lnode);
|
||||
|
||||
/**
|
||||
@brief Frees memory associated with a list node.
|
||||
*/
|
||||
@@ -87,21 +93,32 @@ list_node_t *head_list(list_t *list, bool removeFromList);
|
||||
*/
|
||||
list_node_t *tail_list(list_t *list);
|
||||
|
||||
/**
|
||||
@brief Returns nth node of the list or NULL.
|
||||
*/
|
||||
list_node_t *get_nth_list(list_t *list, int index);
|
||||
|
||||
|
||||
//
|
||||
// Iterator first/done/next operations
|
||||
// http://www.cs.yale.edu/homes/aspnes/pinewiki/C(2f)Iterators.html
|
||||
// Accessed on April 11, 2019
|
||||
//
|
||||
|
||||
/**
|
||||
@brief Returns list head node.
|
||||
*/
|
||||
list_node_t *first_list(list_t *list);
|
||||
static inline list_node_t *first_list(list_t *list) { return head_list(list, false); }
|
||||
|
||||
/**
|
||||
@brief Returns true if end of list false otherwise.
|
||||
*/
|
||||
bool done_list(list_node_t *lnode);
|
||||
static inline bool done_list(list_node_t *lnode) { return lnode != NULL; }
|
||||
|
||||
/**
|
||||
@brief Returns next node in the list.
|
||||
*/
|
||||
list_node_t *next_list(list_node_t *lnode);
|
||||
static inline list_node_t *next_list(list_node_t *lnode) { return get_next(lnode); }
|
||||
|
||||
|
||||
#if defined(__cplusplus)
|
||||
|
||||
@@ -64,7 +64,8 @@ BOOST_AUTO_TEST_CASE(test_int_list){
|
||||
}
|
||||
BOOST_CHECK(size_list(list) == 10);
|
||||
|
||||
for_each_list(list, iterate_int);
|
||||
listIterator iterator = (listIterator)iterate_int;
|
||||
for_each_list(list, iterator);
|
||||
|
||||
delete_list(list);
|
||||
}
|
||||
@@ -111,7 +112,8 @@ BOOST_FIXTURE_TEST_CASE(test_string_list, FixtureStrings) {
|
||||
|
||||
BOOST_CHECK(size_list(list) == 5);
|
||||
|
||||
for_each_list(list, iterate_string);
|
||||
listIterator iterator = (listIterator)iterate_string;
|
||||
for_each_list(list, iterator);
|
||||
}
|
||||
|
||||
|
||||
@@ -196,7 +198,8 @@ BOOST_AUTO_TEST_CASE(test_struct_list){
|
||||
|
||||
BOOST_CHECK(size_list(list) == 3);
|
||||
|
||||
for_each_list(list, iterate_test_data);
|
||||
listIterator iterator = (listIterator)iterate_test_data;
|
||||
for_each_list(list, iterator);
|
||||
|
||||
|
||||
list_node_t *lnode;
|
||||
|
||||
Reference in New Issue
Block a user