From c659c708173c6e47baf82949920f256706dc370a Mon Sep 17 00:00:00 2001 From: Michael Tryby Date: Mon, 15 Apr 2019 13:35:37 -0400 Subject: [PATCH] Work in progress Implementing demand_list --- src/demand.c | 19 +++++++ src/demand.h | 7 +++ src/input1.c | 44 ++++++++++------ src/input3.c | 135 +++++++++++++++++++++++++++++++----------------- src/util/list.c | 12 +++-- 5 files changed, 150 insertions(+), 67 deletions(-) diff --git a/src/demand.c b/src/demand.c index dc91221..5cba1d9 100644 --- a/src/demand.c +++ b/src/demand.c @@ -50,17 +50,36 @@ void delete_demand_data(void *data) free(demand_data); } +size_t get_demand_data_size(void) +{ + return sizeof(demand_data_t *); +} + demand_data_t *get_demand_data(list_node_t *lnode) { return *(demand_data_t **)get_data(lnode); } +bool convert_units(list_node_t *lnode, double unit_conversion) +{ + demand_data_t *demand_data = get_demand_data(lnode); + double base_demand = get_base_demand(demand_data); + + set_base_demand(demand_data, base_demand/unit_conversion); +} + + double get_base_demand(demand_data_t *data) { return data->base_demand; } +void set_base_demand(demand_data_t *data, double base_demand) +{ + data->base_demand = base_demand; +} + int get_pattern_index(demand_data_t *data) { return data->pattern_index; diff --git a/src/demand.h b/src/demand.h index 73b81c2..bdfd8a2 100644 --- a/src/demand.h +++ b/src/demand.h @@ -28,11 +28,18 @@ demand_data_t *create_demand_data(double base_demand, int pat_index, char *cat_n 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); +void set_base_demand(demand_data_t *data, double base_demand); + int get_pattern_index(demand_data_t *data); char *get_category_name(demand_data_t *data); diff --git a/src/input1.c b/src/input1.c index 219caaf..2d80d5b 100644 --- a/src/input1.c +++ b/src/input1.c @@ -23,6 +23,8 @@ Last Updated: 04/03/2019 #include +#include "demand.h" + #include "types.h" #include "funcs.h" #include "hash.h" @@ -220,9 +222,9 @@ void adjustdata(Project *pr) int i; double ucf; // Unit conversion factor - Pdemand demand; // Pointer to demand record + //Pdemand demand; // Pointer to demand record Slink *link; - Snode *node; + //Snode *node; Stank *tank; // Use 1 hr pattern & report time step if none specified @@ -330,16 +332,19 @@ void adjustdata(Project *pr) if (tank->Kb == MISSING) tank->Kb = qual->Kbulk; } - // Use default pattern if none assigned to a demand - parser->DefPat = findpattern(net, parser->DefPatID); - if (parser->DefPat > 0) for (i = 1; i <= net->Nnodes; i++) - { - node = &net->Node[i]; - for (demand = node->D; demand != NULL; demand = demand->next) - { - if (demand->Pat == 0) demand->Pat = parser->DefPat; - } - } + // It is expensive to iterate over every demand at every node. + // cheaper to apply default pattern when creating the demand data. + +// // Use default pattern if none assigned to a demand +// parser->DefPat = findpattern(net, parser->DefPatID); +// if (parser->DefPat > 0) for (i = 1; i <= net->Nnodes; i++) +// { +// node = &net->Node[i]; +// for (demand = node->D; demand != NULL; demand = demand->next) +// { +// if (demand->Pat == 0) demand->Pat = parser->DefPat; +// } +// } // Remove QUALITY as a reporting variable if no WQ analysis if (qual->Qualflag == NONE) rpt->Field[QUALITY].Enabled = FALSE; @@ -542,7 +547,7 @@ void convertunits(Project *pr) int i, j, k; double ucf; // Unit conversion factor - Pdemand demand; // Pointer to demand record + //Pdemand demand; // Pointer to demand record Snode *node; Stank *tank; Slink *link; @@ -562,11 +567,16 @@ void convertunits(Project *pr) for (i = 1; i <= net->Njuncs; i++) { node = &net->Node[i]; - for (demand = node->D; demand != NULL; demand = demand->next) - { - demand->Base /= pr->Ucf[DEMAND]; - } + list_t *dlist = node->D; + for (list_node_t *lnode = first_list(dlist); done_list(lnode); lnode = next_list(lnode)) + convert_units(lnode, pr->Ucf[DEMAND]); + + // for (demand = node->D; demand != NULL; demand = demand->next) + // { + // demand->Base /= pr->Ucf[DEMAND]; + // } } + hyd->Pmin /= pr->Ucf[PRESSURE]; hyd->Preq /= pr->Ucf[PRESSURE]; diff --git a/src/input3.c b/src/input3.c index 61324a3..617f464 100644 --- a/src/input3.c +++ b/src/input3.c @@ -23,6 +23,7 @@ Last Updated: 04/03/2019 #include +#include "demand.h" #include "types.h" #include "funcs.h" #include "hash.h" @@ -80,12 +81,15 @@ int juncdata(Project *pr) Parser *parser = &pr->parser; Hydraul *hyd = &pr->hydraul; - int p = 0; // time pattern index - int n; // number of tokens - int njuncs; // number of network junction nodes - double el, // elevation - y = 0.0; // base demand - Pdemand demand; // demand record + int p = 0; // time pattern index + int n; // number of tokens + int njuncs; // number of network junction nodes + double el, // elevation + y = 0.0; // base demand + + list_t *demand_list = NULL; // demand list + + Snode *node; // Add new junction to data base @@ -118,14 +122,26 @@ int juncdata(Project *pr) node->Type = JUNCTION; node->Comment = xstrcpy(&node->Comment, parser->Comment, MAXMSG); - // create a demand record, even if no demand is specified here. - demand = (struct Sdemand *) malloc(sizeof(struct Sdemand)); - if (demand == NULL) return 101; - demand->Base = y; - demand->Pat = p; - demand->Name = NULL; - demand->next = NULL; - node->D = demand; + // create demand data only if a demand has been specified + if (y != 0.0) { + demand_data_t *demand_data; + + demand_list = create_list(get_demand_data_size(), delete_demand_data); + if (demand_list == NULL) return 101; + + // apply the default demand pattern and append the data + if (p == 0) p = findpattern(net, parser->DefPatID); + demand_data = create_demand_data(y, p, NULL); + if (demand_data == NULL) return 101; + + append_list(demand_list, &demand_data); + } + //demand->Base = y; + //demand->Pat = p; + //demand->Name = NULL; + //demand->next = NULL; + node->D = demand_list; + hyd->NodeDemand[njuncs] = y; return 0; } @@ -709,8 +725,12 @@ int demanddata(Project *pr) int j, n, p = 0; double y; - Pdemand demand; - Pdemand cur_demand; + + list_t *demand_list = NULL; + demand_data_t *demand_data = NULL; + + //Pdemand demand; + //Pdemand cur_demand; // Extract data from tokens n = parser->Ntokens; @@ -734,38 +754,59 @@ int demanddata(Project *pr) if (p == 0) return setError(parser, 2, 205); } - // Replace any demand entered in [JUNCTIONS] section - demand = net->Node[j].D; - if (hyd->NodeDemand[j] != MISSING) - { - // First category encountered will overwrite "dummy" demand category - // with what is specified in this section - demand->Base = y; - demand->Pat = p; - if (parser->Comment[0]) - { - demand->Name = xstrcpy(&demand->Name, parser->Comment, MAXID); - } - hyd->NodeDemand[j] = MISSING; // marker - next iteration will append a new category. - } + + // if no demands were specified in [JUNCTIONS] create the list here + demand_list = net->Node[j].D; + if (demand_list == NULL) { + demand_list = create_list(get_demand_data_size(), delete_demand_data); + if (demand_list == NULL) return 101; + net->Node[j].D = demand_list; + } + + // else delete the demand data in [JUNCTIONS] section + else if (size_list(demand_list) == 1) { + list_node_t *lnode = head_list(demand_list, true); + delete_node(demand_list, lnode); + } - // Otherwise add new demand to junction - else - { - cur_demand = net->Node[j].D; - while (cur_demand->next != NULL) cur_demand = cur_demand->next; - demand = (struct Sdemand *)malloc(sizeof(struct Sdemand)); - if (demand == NULL) return 101; - demand->Base = y; - demand->Pat = p; - demand->Name = NULL; - if (parser->Comment[0]) - { - demand->Name = xstrcpy(&demand->Name, parser->Comment, MAXID); - } - demand->next = NULL; - cur_demand->next = demand; - } + // apply the default demand pattern and append the data + if (p == 0) p = findpattern(net, parser->DefPatID); + demand_data = create_demand_data(y, p, parser->Comment); + if (demand_data == NULL) return 101; + + append_list(demand_list, &demand_data); + + + // //if (hyd->NodeDemand[j] != MISSING) + // { + // // First category encountered will overwrite "dummy" demand category + // // with what is specified in this section + // demand->Base = y; + // demand->Pat = p; + // if (parser->Comment[0]) + // { + // demand->Name = xstrcpy(&demand->Name, parser->Comment, MAXID); + // } + // hyd->NodeDemand[j] = MISSING; // marker - next iteration will append a new category. + // } + // + // // Otherwise add new demand to junction + // else + // { + // cur_demand = net->Node[j].D; + // while (cur_demand->next != NULL) cur_demand = cur_demand->next; + // demand = (struct Sdemand *)malloc(sizeof(struct Sdemand)); + // if (demand == NULL) return 101; + // demand->Base = y; + // demand->Pat = p; + // demand->Name = NULL; + // if (parser->Comment[0]) + // { + // demand->Name = xstrcpy(&demand->Name, parser->Comment, MAXID); + // } + // demand->next = NULL; + // cur_demand->next = demand; + // } return 0; } diff --git a/src/util/list.c b/src/util/list.c index d3e41d8..fc2237e 100644 --- a/src/util/list.c +++ b/src/util/list.c @@ -162,7 +162,10 @@ void delete_node(list_t *list, list_node_t *lnode) // list_node_t *first_list(list_t *list) { - return list->head; + if (list) + return list->head; + else + return NULL; } bool done_list(list_node_t *lnode) @@ -171,6 +174,9 @@ bool done_list(list_node_t *lnode) } list_node_t *next_list(list_node_t *lnode) -{ - return lnode->next; +{ + if (lnode) + return lnode->next; + else + return NULL; }