723 lines
21 KiB
C
723 lines
21 KiB
C
/*
|
|
*********************************************************************
|
|
|
|
INPFILE.C -- Save Input Function for EPANET Program
|
|
|
|
VERSION: 2.00
|
|
DATE: 5/8/00
|
|
3/1/01
|
|
11/19/01
|
|
6/24/02
|
|
8/15/07 (2.00.11)
|
|
2/14/08 (2.00.12)
|
|
AUTHOR: L. Rossman
|
|
US EPA - NRMRL
|
|
|
|
This module contains the function saveinpfile() which saves the
|
|
data describing a piping network to a file in EPANET's text format.
|
|
|
|
********************************************************************
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#ifndef __APPLE__
|
|
#include <malloc.h>
|
|
#else
|
|
#include <stdlib.h>
|
|
#endif
|
|
|
|
#include "hash.h"
|
|
#include "text.h"
|
|
#include "types.h"
|
|
#include "funcs.h"
|
|
#include <math.h>
|
|
//#define EXTERN extern
|
|
//#include "vars.h"
|
|
|
|
/* Defined in enumstxt.h in EPANET.C */
|
|
extern char *LinkTxt[];
|
|
extern char *FormTxt[];
|
|
extern char *StatTxt[];
|
|
extern char *FlowUnitsTxt[];
|
|
extern char *PressUnitsTxt[];
|
|
extern char *ControlTxt[];
|
|
extern char *SourceTxt[];
|
|
extern char *MixTxt[];
|
|
extern char *TstatTxt[];
|
|
extern char *RptFlagTxt[];
|
|
extern char *SectTxt[];
|
|
|
|
void saveauxdata(parser_data_t *parser, FILE *f)
|
|
/*
|
|
------------------------------------------------------------
|
|
Writes auxilary data from original input file to new file.
|
|
------------------------------------------------------------
|
|
*/
|
|
{
|
|
int sect, newsect;
|
|
char *tok;
|
|
char line[MAXLINE + 1];
|
|
char s[MAXLINE + 1];
|
|
FILE *InFile = parser->InFile;
|
|
char Coordflag = parser->Coordflag;
|
|
|
|
sect = -1;
|
|
if (InFile == NULL) {
|
|
return;
|
|
}
|
|
rewind(InFile);
|
|
while (fgets(line, MAXLINE, InFile) != NULL) {
|
|
/* Check if line begins with a new section heading */
|
|
strcpy(s, line);
|
|
tok = strtok(s, SEPSTR);
|
|
if (tok != NULL && *tok == '[') {
|
|
newsect = findmatch(tok, SectTxt);
|
|
if (newsect >= 0) {
|
|
sect = newsect;
|
|
if (sect == _END)
|
|
break;
|
|
switch (sect) {
|
|
// case _RULES:
|
|
case _COORDS:
|
|
if (Coordflag == FALSE) {
|
|
fprintf(f, "%s", line);
|
|
}
|
|
break;
|
|
case _VERTICES:
|
|
case _LABELS:
|
|
case _BACKDROP:
|
|
case _TAGS:
|
|
fprintf(f, "%s", line);
|
|
}
|
|
continue;
|
|
} else
|
|
continue;
|
|
}
|
|
|
|
/* Write lines appearing in the section to file */
|
|
switch (sect) {
|
|
// case _RULES:
|
|
case _COORDS:
|
|
if (Coordflag == FALSE) {
|
|
fprintf(f, "%s", line);
|
|
}
|
|
break;
|
|
case _VERTICES:
|
|
case _LABELS:
|
|
case _BACKDROP:
|
|
case _TAGS:
|
|
fprintf(f, "%s", line);
|
|
}
|
|
}
|
|
}
|
|
|
|
//// This function was heavily modified. ////
|
|
|
|
int saveinpfile(EN_Project *pr, const char *fname)
|
|
/*
|
|
-------------------------------------------------
|
|
Writes network data to text file.
|
|
-------------------------------------------------
|
|
*/
|
|
{
|
|
|
|
EN_Network *net = &pr->network;
|
|
parser_data_t *par = &pr->parser;
|
|
report_options_t *rep = &pr->report;
|
|
out_file_t *out = &pr->out_files;
|
|
hydraulics_t *hyd = &pr->hydraulics;
|
|
quality_t *qu = &pr->quality;
|
|
time_options_t *time = &pr->time_options;
|
|
|
|
int i, j, n;
|
|
int errcode;
|
|
double d, kc, ke, km, ucf;
|
|
char s[MAXLINE + 1], s1[MAXLINE + 1], s2[MAXLINE + 1];
|
|
Pdemand demand;
|
|
Psource source;
|
|
FILE *f;
|
|
Slink *link;
|
|
Stank *tank;
|
|
Snode *node;
|
|
Spump *pump;
|
|
Scontrol *control;
|
|
Scurve *curve;
|
|
Scoord *coord;
|
|
|
|
/* Open the new text file */
|
|
|
|
if ((f = fopen(fname, "wt")) == NULL) {
|
|
return (308);
|
|
}
|
|
|
|
/* Write [TITLE] section */
|
|
|
|
fprintf(f, s_TITLE);
|
|
for (i = 0; i < 3; i++) {
|
|
if (strlen(pr->Title[i]) > 0) {
|
|
fprintf(f, "\n%s", pr->Title[i]);
|
|
}
|
|
}
|
|
|
|
/* Write [JUNCTIONS] section */
|
|
/* (Leave demands for [DEMANDS] section) */
|
|
|
|
fprintf(f, "\n\n");
|
|
fprintf(f, s_JUNCTIONS);
|
|
for (i = 1; i <= net->Njuncs; i++) {
|
|
node = &net->Node[i];
|
|
fprintf(f, "\n %-31s %12.4f ;%s", node->ID, node->El * pr->Ucf[ELEV], node->Comment);
|
|
}
|
|
/* Write [RESERVOIRS] section */
|
|
|
|
fprintf(f, "\n\n");
|
|
fprintf(f, s_RESERVOIRS);
|
|
for (i = 1; i <= net->Ntanks; i++) {
|
|
tank = &net->Tank[i];
|
|
if (tank->A == 0.0) {
|
|
node = &net->Node[tank->Node];
|
|
sprintf(s, " %-31s %12.4f", node->ID, node->El * pr->Ucf[ELEV]);
|
|
if ((j = tank->Pat) > 0) {
|
|
sprintf(s1, " %-31s", net->Pattern[j].ID);
|
|
}
|
|
else {
|
|
strcpy(s1, "");
|
|
}
|
|
fprintf(f, "\n%s %s ;%s", s, s1, node->Comment);
|
|
}
|
|
}
|
|
|
|
/* Write [TANKS] section */
|
|
|
|
fprintf(f, "\n\n");
|
|
fprintf(f, s_TANKS);
|
|
for (i = 1; i <= net->Ntanks; i++) {
|
|
tank = &net->Tank[i];
|
|
if (tank->A > 0.0) {
|
|
node = &net->Node[tank->Node];
|
|
sprintf(s, " %-31s %12.4f %12.4f %12.4f %12.4f %12.4f %12.4f", node->ID,
|
|
node->El * pr->Ucf[ELEV], (tank->H0 - node->El) * pr->Ucf[ELEV],
|
|
(tank->Hmin - node->El) * pr->Ucf[ELEV],
|
|
(tank->Hmax - node->El) * pr->Ucf[ELEV],
|
|
sqrt(4.0 * tank->A / PI) * pr->Ucf[ELEV],
|
|
tank->Vmin * SQR(pr->Ucf[ELEV]) * pr->Ucf[ELEV]);
|
|
if ((j = tank->Vcurve) > 0)
|
|
sprintf(s1, "%-31s", net->Curve[j].ID);
|
|
else
|
|
strcpy(s1, "");
|
|
fprintf(f, "\n%s %s ;%s", s, s1, node->Comment);
|
|
}
|
|
}
|
|
|
|
/* Write [PIPES] section */
|
|
|
|
fprintf(f, "\n\n");
|
|
fprintf(f, s_PIPES);
|
|
for (i = 1; i <= net->Nlinks; i++) {
|
|
link = &net->Link[i];
|
|
if (link->Type <= EN_PIPE) {
|
|
d = link->Diam;
|
|
kc = link->Kc;
|
|
if (hyd->Formflag == DW)
|
|
kc = kc * pr->Ucf[ELEV] * 1000.0;
|
|
km = link->Km * SQR(d) * SQR(d) / 0.02517;
|
|
sprintf(s, " %-31s %-31s %-31s %12.4f %12.4f", link->ID,
|
|
net->Node[link->N1].ID, net->Node[link->N2].ID,
|
|
link->Len * pr->Ucf[LENGTH], d * pr->Ucf[DIAM]);
|
|
if (hyd->Formflag == DW)
|
|
sprintf(s1, "%12.4f %12.4f", kc, km);
|
|
else
|
|
sprintf(s1, "%12.4f %12.4f", kc, km);
|
|
if (link->Type == EN_CVPIPE)
|
|
sprintf(s2, "CV");
|
|
else if (link->Stat == CLOSED)
|
|
sprintf(s2, "CLOSED");
|
|
else
|
|
strcpy(s2, "");
|
|
fprintf(f, "\n%s %s %s ;%s", s, s1, s2, link->Comment);
|
|
}
|
|
}
|
|
|
|
/* Write [PUMPS] section */
|
|
|
|
fprintf(f, "\n\n");
|
|
fprintf(f, s_PUMPS);
|
|
for (i = 1; i <= net->Npumps; i++) {
|
|
n = net->Pump[i].Link;
|
|
link = &net->Link[n];
|
|
pump = &net->Pump[i];
|
|
sprintf(s, " %-31s %-31s %-31s", link->ID, net->Node[link->N1].ID, net->Node[link->N2].ID);
|
|
|
|
/* Pump has constant power */
|
|
if (pump->Ptype == CONST_HP)
|
|
sprintf(s1, " POWER %.4f", link->Km);
|
|
|
|
/* Pump has a head curve */
|
|
else if ((j = pump->Hcurve) > 0)
|
|
sprintf(s1, " HEAD %s", net->Curve[j].ID);
|
|
|
|
/* Old format used for pump curve */
|
|
else {
|
|
fprintf(f, "\n%s %12.4f %12.4f %12.4f 0.0 %12.4f", s,
|
|
-pump->H0 * pr->Ucf[HEAD],
|
|
(-pump->H0 - pump->R * pow(pump->Q0, pump->N)) *
|
|
pr->Ucf[HEAD],
|
|
pump->Q0 * pr->Ucf[FLOW], pump->Qmax * pr->Ucf[FLOW]);
|
|
continue;
|
|
}
|
|
strcat(s, s1);
|
|
|
|
if ((j = pump->Upat) > 0)
|
|
sprintf(s1, " PATTERN %s", net->Pattern[j].ID);
|
|
else
|
|
strcpy(s1, "");
|
|
strcat(s, s1);
|
|
|
|
if (link->Kc != 1.0)
|
|
sprintf(s1, " SPEED %.4f", link->Kc);
|
|
else
|
|
strcpy(s1, "");
|
|
strcat(s, s1);
|
|
|
|
fprintf(f, "\n%s ;%s", s, link->Comment);
|
|
}
|
|
|
|
/* Write [VALVES] section */
|
|
|
|
fprintf(f, "\n\n");
|
|
fprintf(f, s_VALVES);
|
|
for (i = 1; i <= net->Nvalves; i++) {
|
|
n = net->Valve[i].Link;
|
|
link = &net->Link[n];
|
|
d = link->Diam;
|
|
kc = link->Kc;
|
|
if (kc == MISSING)
|
|
kc = 0.0;
|
|
switch (link->Type) {
|
|
case EN_FCV:
|
|
kc *= pr->Ucf[FLOW];
|
|
break;
|
|
case EN_PRV:
|
|
case EN_PSV:
|
|
case EN_PBV:
|
|
kc *= pr->Ucf[PRESSURE];
|
|
break;
|
|
default:
|
|
break;
|
|
// not a valve... pipe/pump/cv
|
|
}
|
|
km = link->Km * SQR(d) * SQR(d) / 0.02517;
|
|
|
|
sprintf(s, " %-31s %-31s %-31s %12.4f %5s", link->ID, net->Node[link->N1].ID,
|
|
net->Node[link->N2].ID, d * pr->Ucf[DIAM], LinkTxt[link->Type]);
|
|
|
|
if (link->Type == EN_GPV && (j = ROUND(link->Kc)) > 0)
|
|
sprintf(s1, "%-31s %12.4f", net->Curve[j].ID, km);
|
|
else
|
|
sprintf(s1, "%12.4f %12.4f", kc, km);
|
|
|
|
fprintf(f, "\n%s %s ;%s", s, s1, link->Comment);
|
|
}
|
|
|
|
/* Write [DEMANDS] section */
|
|
|
|
fprintf(f, "\n\n");
|
|
fprintf(f, s_DEMANDS);
|
|
ucf = pr->Ucf[DEMAND];
|
|
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, " %s", net->Pattern[j].ID);
|
|
else
|
|
strcpy(s1, "");
|
|
fprintf(f, "\n%s %s", s, s1);
|
|
}
|
|
}
|
|
|
|
/* Write [EMITTERS] section */
|
|
|
|
fprintf(f, "\n\n");
|
|
fprintf(f, s_EMITTERS);
|
|
for (i = 1; i <= net->Njuncs; i++) {
|
|
node = &net->Node[i];
|
|
if (node->Ke == 0.0)
|
|
continue;
|
|
ke = pr->Ucf[FLOW] / pow(pr->Ucf[PRESSURE] * node->Ke, (1.0 / hyd->Qexp));
|
|
fprintf(f, "\n %-31s %14.6f", node->ID, ke);
|
|
}
|
|
|
|
/* Write [STATUS] section */
|
|
|
|
fprintf(f, "\n\n");
|
|
fprintf(f, s_STATUS);
|
|
for (i = 1; i <= net->Nlinks; i++) {
|
|
link = &net->Link[i];
|
|
if (link->Type <= EN_PUMP) {
|
|
if (link->Stat == CLOSED)
|
|
fprintf(f, "\n %-31s %s", link->ID, StatTxt[CLOSED]);
|
|
|
|
/* Write pump speed here for pumps with old-style pump curve input */
|
|
else if (link->Type == EN_PUMP) {
|
|
n = findpump(net, i);
|
|
pump = &net->Pump[n];
|
|
if (pump->Hcurve == 0 && pump->Ptype != CONST_HP &&
|
|
link->Kc != 1.0)
|
|
fprintf(f, "\n %-31s %-.4f", link->ID, link->Kc);
|
|
}
|
|
}
|
|
|
|
/* Write fixed-status PRVs & PSVs (setting = MISSING) */
|
|
else if (link->Kc == MISSING) {
|
|
if (link->Stat == OPEN)
|
|
fprintf(f, "\n %-31s %s", link->ID, StatTxt[OPEN]);
|
|
if (link->Stat == CLOSED)
|
|
fprintf(f, "\n%-31s %s", link->ID, StatTxt[CLOSED]);
|
|
}
|
|
}
|
|
|
|
/* Write [PATTERNS] section */
|
|
/* (Use 6 pattern factors per line) */
|
|
|
|
fprintf(f, "\n\n");
|
|
fprintf(f, s_PATTERNS);
|
|
for (i = 1; i <= net->Npats; i++) {
|
|
for (j = 0; j < net->Pattern[i].Length; j++) {
|
|
if (j % 6 == 0)
|
|
fprintf(f, "\n %-31s", net->Pattern[i].ID);
|
|
fprintf(f, " %12.4f", net->Pattern[i].F[j]);
|
|
}
|
|
}
|
|
|
|
/* Write [CURVES] section */
|
|
|
|
fprintf(f, "\n\n");
|
|
fprintf(f, s_CURVES);
|
|
for (i = 1; i <= net->Ncurves; i++) {
|
|
for (j = 0; j < net->Curve[i].Npts; j++) {
|
|
curve = &net->Curve[i];
|
|
fprintf(f, "\n %-31s %12.4f %12.4f", curve->ID, curve->X[j], curve->Y[j]);
|
|
}
|
|
}
|
|
|
|
/* Write [CONTROLS] section */
|
|
|
|
fprintf(f, "\n\n");
|
|
fprintf(f, s_CONTROLS);
|
|
for (i = 1; i <= net->Ncontrols; i++) {
|
|
control = &net->Control[i];
|
|
/* Check that controlled link exists */
|
|
if ((j = control->Link) <= 0)
|
|
continue;
|
|
link = &net->Link[j];
|
|
|
|
/* Get text of control's link status/setting */
|
|
if (control->Setting == MISSING)
|
|
sprintf(s, " LINK %s %s ", link->ID, StatTxt[control->Status]);
|
|
else {
|
|
kc = control->Setting;
|
|
switch (link->Type) {
|
|
case EN_PRV:
|
|
case EN_PSV:
|
|
case EN_PBV:
|
|
kc *= pr->Ucf[PRESSURE];
|
|
break;
|
|
case EN_FCV:
|
|
kc *= pr->Ucf[FLOW];
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
sprintf(s, " LINK %s %.4f", link->ID, kc);
|
|
}
|
|
|
|
switch (control->Type) {
|
|
/* Print level control */
|
|
case LOWLEVEL:
|
|
case HILEVEL:
|
|
n = control->Node;
|
|
node = &net->Node[n];
|
|
kc = control->Grade - node->El;
|
|
if (n > net->Njuncs)
|
|
kc *= pr->Ucf[HEAD];
|
|
else
|
|
kc *= pr->Ucf[PRESSURE];
|
|
fprintf(f, "\n%s IF NODE %s %s %.4f", s, node->ID,
|
|
ControlTxt[control->Type], kc);
|
|
break;
|
|
|
|
/* Print timer control */
|
|
case TIMER:
|
|
fprintf(f, "\n%s AT %s %.4f HOURS", s, ControlTxt[TIMER],
|
|
control->Time / 3600.);
|
|
break;
|
|
|
|
/* Print time-of-day control */
|
|
case TIMEOFDAY:
|
|
fprintf(f, "\n%s AT %s %s", s, ControlTxt[TIMEOFDAY],
|
|
clocktime(rep->Atime, control->Time));
|
|
break;
|
|
}
|
|
}
|
|
|
|
/* Write [RULES] section */
|
|
|
|
fprintf(f, "\n\n");
|
|
fprintf(f, s_RULES);
|
|
for (i = 1; i <= net->Nrules; i++) {
|
|
fprintf(f, "\nRULE %s", pr->rules.Rule[i].label);
|
|
errcode = writeRuleinInp(pr, f, i);
|
|
fprintf(f, "\n");
|
|
}
|
|
|
|
/* Write [QUALITY] section */
|
|
/* (Skip nodes with default quality of 0) */
|
|
|
|
fprintf(f, "\n\n");
|
|
fprintf(f, s_QUALITY);
|
|
for (i = 1; i <= net->Nnodes; i++) {
|
|
node = &net->Node[i];
|
|
if (node->C0 == 0.0)
|
|
continue;
|
|
fprintf(f, "\n %-31s %14.6f", node->ID, node->C0 * pr->Ucf[QUALITY]);
|
|
}
|
|
|
|
/* Write [SOURCES] section */
|
|
|
|
fprintf(f, "\n\n");
|
|
fprintf(f, s_SOURCES);
|
|
for (i = 1; i <= net->Nnodes; i++) {
|
|
node = &net->Node[i];
|
|
source = node->S;
|
|
if (source == NULL)
|
|
continue;
|
|
sprintf(s, " %-31s %-8s %14.6f", node->ID, SourceTxt[source->Type], source->C0);
|
|
if ((j = source->Pat) > 0)
|
|
sprintf(s1, "%s", net->Pattern[j].ID);
|
|
else
|
|
strcpy(s1, "");
|
|
fprintf(f, "\n%s %s", s, s1);
|
|
}
|
|
|
|
/* Write [MIXING] section */
|
|
|
|
fprintf(f, "\n\n");
|
|
fprintf(f, s_MIXING);
|
|
for (i = 1; i <= net->Ntanks; i++) {
|
|
Stank *tank = &net->Tank[i];
|
|
if (tank->A == 0.0)
|
|
continue;
|
|
fprintf(f, "\n %-31s %-8s %12.4f", net->Node[tank->Node].ID,
|
|
MixTxt[tank->MixModel], (tank->V1max / tank->Vmax));
|
|
}
|
|
|
|
/* Write [REACTIONS] section */
|
|
|
|
fprintf(f, "\n\n");
|
|
fprintf(f, s_REACTIONS);
|
|
fprintf(f, "\n ORDER BULK %-.2f", qu->BulkOrder);
|
|
fprintf(f, "\n ORDER WALL %-.0f", qu->WallOrder);
|
|
fprintf(f, "\n ORDER TANK %-.2f", qu->TankOrder);
|
|
fprintf(f, "\n GLOBAL BULK %-.6f", qu->Kbulk * SECperDAY);
|
|
fprintf(f, "\n GLOBAL WALL %-.6f", qu->Kwall * SECperDAY);
|
|
if (qu->Climit > 0.0)
|
|
fprintf(f, "\n LIMITING POTENTIAL %-.6f", qu->Climit);
|
|
if (qu->Rfactor != MISSING && qu->Rfactor != 0.0)
|
|
fprintf(f, "\n ROUGHNESS CORRELATION %-.6f", qu->Rfactor);
|
|
for (i = 1; i <= net->Nlinks; i++) {
|
|
link = &net->Link[i];
|
|
if (link->Type > EN_PIPE)
|
|
continue;
|
|
if (link->Kb != qu->Kbulk)
|
|
fprintf(f, "\n BULK %-31s %-.6f", link->ID, link->Kb * SECperDAY);
|
|
if (link->Kw != qu->Kwall)
|
|
fprintf(f, "\n WALL %-31s %-.6f", link->ID, link->Kw * SECperDAY);
|
|
}
|
|
for (i = 1; i <= net->Ntanks; i++) {
|
|
tank = &net->Tank[i];
|
|
if (tank->A == 0.0)
|
|
continue;
|
|
if (tank->Kb != qu->Kbulk)
|
|
fprintf(f, "\n TANK %-31s %-.6f", net->Node[tank->Node].ID,
|
|
tank->Kb * SECperDAY);
|
|
}
|
|
|
|
/* Write [ENERGY] section */
|
|
|
|
fprintf(f, "\n\n");
|
|
fprintf(f, s_ENERGY);
|
|
if (hyd->Ecost != 0.0)
|
|
fprintf(f, "\n GLOBAL PRICE %-.4f", hyd->Ecost);
|
|
if (hyd->Epat != 0)
|
|
fprintf(f, "\n GLOBAL PATTERN %s", net->Pattern[hyd->Epat].ID);
|
|
fprintf(f, "\n GLOBAL EFFIC %-.4f", hyd->Epump);
|
|
fprintf(f, "\n DEMAND CHARGE %-.4f", hyd->Dcost);
|
|
for (i = 1; i <= net->Npumps; i++) {
|
|
pump = &net->Pump[i];
|
|
if (pump->Ecost > 0.0)
|
|
fprintf(f, "\n PUMP %-31s PRICE %-.4f", net->Link[pump->Link].ID,
|
|
pump->Ecost);
|
|
if (pump->Epat > 0.0)
|
|
fprintf(f, "\n PUMP %-31s PATTERN %s", net->Link[pump->Link].ID,
|
|
net->Pattern[pump->Epat].ID);
|
|
if (pump->Ecurve > 0.0)
|
|
fprintf(f, "\n PUMP %-31s EFFIC %s", net->Link[pump->Link].ID,
|
|
net->Curve[pump->Ecurve].ID);
|
|
}
|
|
|
|
/* Write [TIMES] section */
|
|
|
|
fprintf(f, "\n\n");
|
|
fprintf(f, s_TIMES);
|
|
fprintf(f, "\n DURATION %s", clocktime(rep->Atime, time->Dur));
|
|
fprintf(f, "\n HYDRAULIC TIMESTEP %s", clocktime(rep->Atime, time->Hstep));
|
|
fprintf(f, "\n QUALITY TIMESTEP %s", clocktime(rep->Atime, qu->Qstep));
|
|
fprintf(f, "\n REPORT TIMESTEP %s", clocktime(rep->Atime, time->Rstep));
|
|
fprintf(f, "\n REPORT START %s", clocktime(rep->Atime, time->Rstart));
|
|
fprintf(f, "\n PATTERN TIMESTEP %s", clocktime(rep->Atime, time->Pstep));
|
|
fprintf(f, "\n PATTERN START %s", clocktime(rep->Atime, time->Pstart));
|
|
fprintf(f, "\n RULE TIMESTEP %s", clocktime(rep->Atime, time->Rulestep));
|
|
fprintf(f, "\n START CLOCKTIME %s", clocktime(rep->Atime, time->Tstart));
|
|
fprintf(f, "\n STATISTIC %s", TstatTxt[rep->Tstatflag]);
|
|
|
|
/* Write [OPTIONS] section */
|
|
|
|
fprintf(f, "\n\n");
|
|
fprintf(f, s_OPTIONS);
|
|
fprintf(f, "\n UNITS %s", FlowUnitsTxt[par->Flowflag]);
|
|
fprintf(f, "\n PRESSURE %s", PressUnitsTxt[par->Pressflag]);
|
|
fprintf(f, "\n HEADLOSS %s", FormTxt[hyd->Formflag]);
|
|
if (hyd->DefPat >= 1 && hyd->DefPat <= net->Npats)
|
|
fprintf(f, "\n PATTERN %s", net->Pattern[hyd->DefPat].ID);
|
|
if (out->Hydflag == USE)
|
|
fprintf(f, "\n HYDRAULICS USE %s", out->HydFname);
|
|
if (out->Hydflag == SAVE)
|
|
fprintf(f, "\n HYDRAULICS SAVE %s", out->HydFname);
|
|
if (hyd->ExtraIter == -1)
|
|
fprintf(f, "\n UNBALANCED STOP");
|
|
if (hyd->ExtraIter >= 0)
|
|
fprintf(f, "\n UNBALANCED CONTINUE %d", hyd->ExtraIter);
|
|
if (qu->Qualflag == CHEM)
|
|
fprintf(f, "\n QUALITY %s %s", qu->ChemName, qu->ChemUnits);
|
|
if (qu->Qualflag == TRACE)
|
|
fprintf(f, "\n QUALITY TRACE %-31s", net->Node[qu->TraceNode].ID);
|
|
if (qu->Qualflag == AGE)
|
|
fprintf(f, "\n QUALITY AGE");
|
|
if (qu->Qualflag == NONE)
|
|
fprintf(f, "\n QUALITY NONE");
|
|
fprintf(f, "\n DEMAND MULTIPLIER %-.4f", hyd->Dmult);
|
|
fprintf(f, "\n EMITTER EXPONENT %-.4f", 1.0 / hyd->Qexp);
|
|
fprintf(f, "\n VISCOSITY %-.6f", hyd->Viscos / VISCOS);
|
|
fprintf(f, "\n DIFFUSIVITY %-.6f", qu->Diffus / DIFFUS);
|
|
fprintf(f, "\n SPECIFIC GRAVITY %-.6f", hyd->SpGrav);
|
|
fprintf(f, "\n TRIALS %-d", hyd->MaxIter);
|
|
fprintf(f, "\n ACCURACY %-.8f", hyd->Hacc);
|
|
fprintf(f, "\n TOLERANCE %-.8f", qu->Ctol * pr->Ucf[QUALITY]);
|
|
fprintf(f, "\n CHECKFREQ %-d", hyd->CheckFreq);
|
|
fprintf(f, "\n MAXCHECK %-d", hyd->MaxCheck);
|
|
fprintf(f, "\n DAMPLIMIT %-.8f", hyd->DampLimit);
|
|
if (hyd->HeadErrorLimit > 0.0) {
|
|
fprintf(f, "\n HEADERROR %-.8f", hyd->HeadErrorLimit * pr->Ucf[HEAD]);
|
|
}
|
|
if (hyd->FlowChangeLimit > 0.0) {
|
|
fprintf(f, "\n FLOWCHANGE %-.8f", hyd->FlowChangeLimit * pr->Ucf[FLOW]);
|
|
}
|
|
if (hyd->DemandModel == PDA)
|
|
{
|
|
fprintf(f, "\n DEMAND MODEL PDA");
|
|
fprintf(f, "\n MINIMUM PRESSURE %-.4f", hyd->Pmin * pr->Ucf[PRESSURE]);
|
|
fprintf(f, "\n REQUIRED PRESSURE %-.4f", hyd->Preq * pr->Ucf[PRESSURE]);
|
|
fprintf(f, "\n PRESSURE EXPONENT %-.4f", hyd->Pexp);
|
|
}
|
|
|
|
/* Write [REPORT] section */
|
|
|
|
fprintf(f, "\n\n");
|
|
fprintf(f, s_REPORT);
|
|
fprintf(f, "\n PAGESIZE %d", rep->PageSize);
|
|
fprintf(f, "\n STATUS %s", RptFlagTxt[rep->Statflag]);
|
|
fprintf(f, "\n SUMMARY %s", RptFlagTxt[rep->Summaryflag]);
|
|
fprintf(f, "\n ENERGY %s", RptFlagTxt[rep->Energyflag]);
|
|
fprintf(f, "\n MESSAGES %s", RptFlagTxt[rep->Messageflag]);
|
|
if (strlen(rep->Rpt2Fname) > 0)
|
|
fprintf(f, "\n FILE %s", rep->Rpt2Fname);
|
|
switch (rep->Nodeflag) {
|
|
case 0:
|
|
fprintf(f, "\n NODES NONE");
|
|
break;
|
|
case 1:
|
|
fprintf(f, "\n NODES ALL");
|
|
break;
|
|
default:
|
|
j = 0;
|
|
for (i = 1; i <= net->Nnodes; i++) {
|
|
node = &net->Node[i];
|
|
if (node->Rpt == 1) {
|
|
if (j % 5 == 0)
|
|
fprintf(f, "\n NODES ");
|
|
fprintf(f, "%s ", node->ID);
|
|
j++;
|
|
}
|
|
}
|
|
}
|
|
switch (rep->Linkflag) {
|
|
case 0:
|
|
fprintf(f, "\n LINKS NONE");
|
|
break;
|
|
case 1:
|
|
fprintf(f, "\n LINKS ALL");
|
|
break;
|
|
default:
|
|
j = 0;
|
|
for (i = 1; i <= net->Nlinks; i++) {
|
|
Slink *link = &net->Link[i];
|
|
if (link->Rpt == 1) {
|
|
if (j % 5 == 0)
|
|
fprintf(f, "\n LINKS ");
|
|
fprintf(f, "%s ", link->ID);
|
|
j++;
|
|
}
|
|
}
|
|
}
|
|
for (i = 0; i < FRICTION; i++) {
|
|
SField *field = &rep->Field[i];
|
|
if (field->Enabled == TRUE) {
|
|
fprintf(f, "\n %-20sPRECISION %d", field->Name, field->Precision);
|
|
if (field->RptLim[LOW] < BIG)
|
|
fprintf(f, "\n %-20sBELOW %.6f", field->Name, field->RptLim[LOW]);
|
|
if (field->RptLim[HI] > -BIG)
|
|
fprintf(f, "\n %-20sABOVE %.6f", field->Name, field->RptLim[HI]);
|
|
} else
|
|
fprintf(f, "\n %-20sNO",field->Name);
|
|
}
|
|
fprintf(f, "\n\n");
|
|
|
|
/* Write [COORDINATES] section */
|
|
|
|
if (par->Coordflag == TRUE) {
|
|
fprintf(f, "\n\n");
|
|
fprintf(f, s_COORDS);
|
|
for (i = 1; i <= net->Nnodes; i++) {
|
|
node = &net->Node[i];
|
|
coord = &net->Coord[i];
|
|
if (coord->HaveCoords == TRUE) {
|
|
fprintf(f, "\n %-31s %14.6f %14.6f", node->ID, coord->X, coord->Y);
|
|
}
|
|
}
|
|
fprintf(f, "\n\n");
|
|
}
|
|
|
|
/* Save auxilary data to new input file */
|
|
|
|
saveauxdata(par,f);
|
|
|
|
/* Close the new input file */
|
|
|
|
fprintf(f, "\n");
|
|
fprintf(f, s_END);
|
|
fclose(f);
|
|
return (0);
|
|
}
|