Skip to content

Commit

Permalink
added function updateruleunits
Browse files Browse the repository at this point in the history
  • Loading branch information
lbutler committed Mar 30, 2023
1 parent 56c569b commit 9cde320
Show file tree
Hide file tree
Showing 6 changed files with 415 additions and 80 deletions.
27 changes: 26 additions & 1 deletion src/epanet.c
Original file line number Diff line number Diff line change
Expand Up @@ -1237,6 +1237,9 @@ int DLLEXPORT EN_setoption(EN_Project p, int option, double value)
int i, j, pat, unit;
double Ke, n, ucf;

double qfactor, hfactor, pfactor, dfactor;
double dcf, pcf, hcf, qcf;

if (!p->Openflag) return 102;

// The EN_UNBALANCED option can be < 0 indicating that the simulation
Expand Down Expand Up @@ -1384,7 +1387,19 @@ int DLLEXPORT EN_setoption(EN_Project p, int option, double value)
if (p->parser.Unitsflag == US && unit > PSI) return 0;
if (p->parser.Unitsflag == SI && unit == PSI) return 0;
p->parser.Pressflag = unit;

dfactor = Ucf[DEMAND];
pfactor = Ucf[PRESSURE];
hfactor = Ucf[HEAD];
qfactor = Ucf[FLOW];
initunits(p);

// Update units in rules
dcf = Ucf[DEMAND] / dfactor;
pcf = Ucf[PRESSURE] / pfactor;
hcf = Ucf[HEAD] / hfactor;
qcf = Ucf[FLOW] / qfactor;
updateruleunits(p, dcf, pcf, hcf, qcf);
break;

default:
Expand Down Expand Up @@ -1420,7 +1435,8 @@ int DLLEXPORT EN_setflowunits(EN_Project p, int units)
Network *net = &p->network;

int i, j;
double qfactor, vfactor, hfactor, efactor, xfactor, yfactor;
double qfactor, vfactor, hfactor, efactor, pfactor, dfactor, xfactor, yfactor;
double dcf, pcf, hcf, qcf;
double *Ucf = p->Ucf;

if (!p->Openflag) return 102;
Expand All @@ -1430,6 +1446,8 @@ int DLLEXPORT EN_setflowunits(EN_Project p, int units)
vfactor = Ucf[VOLUME];
hfactor = Ucf[HEAD];
efactor = Ucf[ELEV];
pfactor = Ucf[PRESSURE];
dfactor = Ucf[DEMAND];

p->parser.Flowflag = units;
switch (units)
Expand All @@ -1452,6 +1470,13 @@ int DLLEXPORT EN_setflowunits(EN_Project p, int units)
else if (p->parser.Pressflag == PSI) p->parser.Pressflag = METERS;
initunits(p);

// Update pressure units in rules
dcf = Ucf[DEMAND] / dfactor;
pcf = Ucf[PRESSURE] / pfactor;
hcf = Ucf[HEAD] / hfactor;
qcf = Ucf[FLOW] / qfactor;
updateruleunits(p, dcf, pcf, hcf, qcf);

//update curves
for (i = 1; i <= net->Ncurves; i++)
{
Expand Down
1 change: 1 addition & 0 deletions src/funcs.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ Spremise *getpremise(Spremise *, int);
Saction *getaction(Saction *, int);
int writerule(Project *, FILE *, int);
int checkrules(Project *, long);
void updateruleunits(Project *pr, double dcf, double pcf, double hcf, double qcf);

// ------- REPORT.C -----------------

Expand Down
120 changes: 120 additions & 0 deletions src/rules.c
Original file line number Diff line number Diff line change
Expand Up @@ -549,6 +549,126 @@ int checkrules(Project *pr, long dt)
return actionCount;
}

void updateruleunits(Project *pr, double dcf, double pcf, double hcf, double qcf)
//-----------------------------------------------------------
// Updates the units of a rule's premises and actions.
//-----------------------------------------------------------
{
Network *net = &pr->network;
Slink *Link = net->Link;

int i, k;
double x;
Spremise *p;
Saction *a;

for (i = 1; i <= net->Nrules; i++)
{
p = net->Rule[i].Premises;
while (p != NULL)
{

switch (p->variable)
{
case r_DEMAND:
p->value *= dcf;
break;

case r_HEAD:
case r_GRADE:
p->value *= hcf;
break;

case r_PRESSURE:
p->value *= pcf;
break;

case r_LEVEL:
p->value *= hcf;
break;

case r_FLOW:
p->value *= qcf;
break;

case r_SETTING:

switch (Link[p->index].Type)
{
case PRV:
case PSV:
case PBV:
p->value *= pcf;
break;
case FCV:
p->value *= qcf;
break;
default:
break;
}
break;

default:
break;

}
p = p->next;
}

a = net->Rule[i].ThenActions;
while (a != NULL)
{
k = a->link;
x = a->setting;

// Change link's setting
if (x != MISSING)
{
switch (net->Link[k].Type)
{
case PRV:
case PSV:
case PBV:
a->setting *= pcf;
break;
case FCV:
a->setting *= qcf;
break;
default:
break;
}
}
a = a->next;
}
a = net->Rule[i].ElseActions;
while (a != NULL)
{
k = a->link;
x = a->setting;

// Change link's setting
if (x != MISSING)
{
switch (net->Link[k].Type)
{
case PRV:
case PSV:
case PBV:
a->setting *= pcf;
break;
case FCV:
a->setting *= qcf;
break;
default:
break;
}
}
a = a->next;
}
}
}


void newrule(Project *pr)
//----------------------------------------------------------
// Adds a new rule to the project
Expand Down
1 change: 1 addition & 0 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ set(toolkit_test_srcs
test_overflow.cpp
test_pda.cpp
test_valve.cpp
test_units.cpp
)

add_executable(test_toolkit ${toolkit_test_srcs})
Expand Down
79 changes: 0 additions & 79 deletions tests/test_project.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,85 +116,6 @@ BOOST_AUTO_TEST_CASE(test_run)
EN_deleteproject(ph);
}

BOOST_FIXTURE_TEST_CASE(test_pressure_units, FixtureInitClose)
{
int index;
long t;
double p, units;

// Create basic network
error = EN_addnode(ph, "R1", EN_RESERVOIR, &index);
BOOST_REQUIRE(error == 0);
error = EN_setnodevalue(ph, index, EN_ELEVATION, 100);
BOOST_REQUIRE(error == 0);
error = EN_addnode(ph, "J1", EN_JUNCTION, &index);
BOOST_REQUIRE(error == 0);
error = EN_addlink(ph, "P1", EN_PIPE, "R1", "J1", &index);
BOOST_REQUIRE(error == 0);

// Run simulation and get junction pressure
error = EN_openH(ph);
BOOST_REQUIRE(error == 0);
error = EN_initH(ph, EN_NOSAVE);
BOOST_REQUIRE(error == 0);
error = EN_runH(ph, &t);
BOOST_REQUIRE(error == 0);
error = EN_getnodevalue(ph, 1, EN_PRESSURE, &p);
BOOST_REQUIRE(error == 0);
BOOST_CHECK(abs(p - 43.33) < 1.e-5);

// Get pressure unit and check that it is PSI
error = EN_getoption(ph, EN_PRESS_UNITS, &units);
BOOST_REQUIRE(error == 0);
BOOST_CHECK(units == EN_PSI);

// Check that pressure unit is PSI
error = EN_setoption(ph, EN_PRESS_UNITS, EN_METERS);
BOOST_REQUIRE(error == 0);

// Change to meters and confirm that units are still PSI
error = EN_getoption(ph, EN_PRESS_UNITS, &units);
BOOST_REQUIRE(error == 0);
BOOST_CHECK(units == EN_PSI);

// Change flow units to LPS to change to metric units and rerun simulation
error = EN_setflowunits(ph, EN_LPS);
BOOST_REQUIRE(error == 0);
error = EN_initH(ph, EN_NOSAVE);
BOOST_REQUIRE(error == 0);
error = EN_runH(ph, &t);
BOOST_REQUIRE(error == 0);

// Confirm that pressure is now in meters
error = EN_getnodevalue(ph, 1, EN_PRESSURE, &p);
BOOST_REQUIRE(error == 0);
BOOST_CHECK(abs(p - 30.48) < 1.e-5);
error = EN_getoption(ph, EN_PRESS_UNITS, &units);
BOOST_REQUIRE(error == 0);
BOOST_CHECK(units == EN_METERS);

// Set and check that pressure units are in kPa
error = EN_setoption(ph, EN_PRESS_UNITS, EN_KPA);
BOOST_REQUIRE(error == 0);
error = EN_getoption(ph, EN_PRESS_UNITS, &units);
BOOST_REQUIRE(error == 0);
BOOST_CHECK(units == EN_KPA);
error = EN_getnodevalue(ph, 1, EN_PRESSURE, &p);
BOOST_REQUIRE(error == 0);
BOOST_CHECK(abs(p - 298.76035) < 1.e-5);

// Set pressure to PSI and check that it remains in kPa
error = EN_setoption(ph, EN_PRESS_UNITS, EN_PSI);
BOOST_REQUIRE(error == 0);
error = EN_getoption(ph, EN_PRESS_UNITS, &units);
BOOST_REQUIRE(error == 0);
BOOST_CHECK(units == EN_KPA);

error = EN_closeH(ph);
BOOST_REQUIRE(error == 0);

}

BOOST_AUTO_TEST_SUITE_END()

BOOST_AUTO_TEST_SUITE(test_proj_fixture)
Expand Down
Loading

0 comments on commit 9cde320

Please sign in to comment.