From c622ad66b4840c1c314c8d18303460f574f1bd5e Mon Sep 17 00:00:00 2001 From: JinduanChen Date: Wed, 23 Jan 2013 00:35:11 -0500 Subject: [PATCH] Added one test case and three api functions. The test will run but WQ result is not accurate. --- src/lemontiger.c | 116 +++++++++++++++++++++++++++++++++++++++++++++++ src/lemontiger.h | 11 +++++ src/testLT.c | 82 +++++++++++++++++++++++++++++++++ 3 files changed, 209 insertions(+) create mode 100644 src/lemontiger.c create mode 100644 src/lemontiger.h create mode 100644 src/testLT.c diff --git a/src/lemontiger.c b/src/lemontiger.c new file mode 100644 index 0000000..5634d22 --- /dev/null +++ b/src/lemontiger.c @@ -0,0 +1,116 @@ +#include "types.h" +#include "vars.h" +#include "funcs.h" +#include "toolkit.h" +#include "lemontiger.h" + +extern char OutOfMemory; + + +int ENopeninitHQ() { + int errcode = 0; + Statflag = FALSE; //disable status report + + if (errcode = ENopenH()) return errcode; + + // Open WQ solver, but don't check SaveHflag as in ENopenQ() + ERRCODE(openqual()); + if (!errcode) OpenQflag = TRUE; + else { + errmsg(errcode); + return errcode; + } + + if (errcode = ENinitH(1)) return errcode; + if (errcode = ENinitQ(0)) return errcode; + + Rtime = Rstep; //use ENinitH()'s setup + return errcode; +} + +int ENrunstepHQ(long* pstime /* Simulation time pointer */ + , long* ptleft /* Time left in the simulation*/) { + long hydtime; /* Hydraulic solution time */ + long hydstep; /* Hydraulic time step */ + int errcode = 0; + long dt, hstep, tstep; + + /* Update reported simulation time */ + *pstime = Qtime; + + /* if needed, push forward hydraulic simulation */ + if (Qtime == Htime) + { + if ( (errcode = runhyd(&hydtime)) || + (errcode = nexthyd(&hydstep)) + ) return errcode; + /* If simulating WQ: */ + if (Qualflag != NONE && Qtime < Dur) { + + /* Compute reaction rate coeffs. */ + if (Reactflag && Qualflag != AGE) ratecoeffs(); + + /* Initialize pipe segments (at time 0) or */ + /* else re-orient segments if flow reverses.*/ + if (Qtime == 0) initsegs(); + else reorientsegs(); + } + Htime = hydtime + hydstep; + } + + /* run WQ simulation similar to stepqual() */ + tstep = Qstep; + + do + { + dt = tstep; + hstep = Htime - Qtime; + if (hstep < dt) + { + dt = hstep; + if (Qualflag != NONE) transport(dt); + Qtime += dt; + + /* if needed, push forward hydraulic simulation */ + if ( (errcode = runhyd(&hydtime)) || + (errcode = nexthyd(&hydstep)) + ) return errcode; + if (Qualflag != NONE && Qtime < Dur) { + + /* Compute reaction rate coeffs. */ + if (Reactflag && Qualflag != AGE) ratecoeffs(); + + /* Initialize pipe segments (at time 0) or */ + /* else re-orient segments if flow reverses.*/ + if (Qtime == 0) initsegs(); + else reorientsegs(); + } + + Htime = hydtime + hydstep; + + Qtime = hydtime; + } + else + { + if (Qualflag != NONE) transport(dt); + Qtime += dt; + } + tstep -= dt; + if (OutOfMemory) errcode = 101; + } while (!errcode && tstep > 0); + + *ptleft = Dur - Qtime; + if (!errcode && Saveflag && *ptleft == 0) errcode = savefinaloutput(); + return(errcode); +} + +int ENcloseHQ() { + int errcode = 0; + if ( (errcode = ENcloseQ()) || (errcode = ENcloseH()) ) + return errcode; + return errcode; +} + + + + \ No newline at end of file diff --git a/src/lemontiger.h b/src/lemontiger.h new file mode 100644 index 0000000..885f429 --- /dev/null +++ b/src/lemontiger.h @@ -0,0 +1,11 @@ +#ifndef LEMONTIGER_H +#define LEMONTIGER_H + +int ENopeninitHQ(); + +int ENrunstepHQ(long*, long*); + +int ENcloseHQ(); + + +#endif \ No newline at end of file diff --git a/src/testLT.c b/src/testLT.c new file mode 100644 index 0000000..97b29b9 --- /dev/null +++ b/src/testLT.c @@ -0,0 +1,82 @@ +/* Test file for epanet LemonTiger - Jinduan's version + The extension enables syncronized computation of hydraulics + and water quality */ + +#include +#include "types.h" +#include "vars.h" +#include "toolkit.h" +#include "lemontiger.h" + + +#ifdef CLE_LT + +int main(int argc, char* argv[]) { + int err = 0; //error code + long stime = 0; //simulation time point, = t = Htime + long step = 1; //time to next time point, = tstep = hydstep + long tleft = 0; //time left in the simulation + int id; // some node id + float value; // some node/link value + int TIME_A = 3600*10; + int TIME_B = 3600*20; //two time points for testing + + + /* Asychronous solver (old epanet) */ + + if (err=ENopen(argv[1], argv[2], "")) return err; + ENgetnodeindex("184", &id); + + for (ENopenH(), ENinitH(1), step=1; + // must save intermediate results to disk (initH(1)), otherwise WQ solver won't execute + step>0; ) { + + ENrunH(&stime); ENnextH(&step); + printf("stime = %d sec, step = %d sec.\n", stime, step); + + if (stime == TIME_A || stime == TIME_B) { // grab some results + ENgetnodevalue(id, EN_HEAD, &value); + printf("Node 184's head = %f.\n", value); + } + } + ENcloseH(); + + printf("Reset time pointer and run WQ.\n"); + for (ENopenQ(), ENinitQ(0), step=1; step>0; ) { + /* this operation resets the internal time pointer (back to 0)*/ + ENrunQ(&stime); ENnextQ(&step); + printf("stime = %d sec, step = %d sec.\n", stime, step); + + // grab some results + if (stime == TIME_A || stime == TIME_B) { + ENgetnodevalue(id, EN_QUALITY, &value); + printf("Node 184's quality = %f.\n", value); + } + } + ENcloseQ(); + ENclose(); + + + /* Sychronous solver (LemonTiger) */ + + if (err=ENopen(argv[1], argv[2], "")) return err; + + for (ENopeninitHQ(), tleft=Dur; tleft>0; ) { + ENrunstepHQ(&stime, &tleft); + printf("stime = %d sec, time left = %d sec.\n", stime, tleft); + + if (stime == TIME_A || stime == TIME_B) { + ENgetnodevalue(id, EN_HEAD, &value); + printf("Node 184's head = %f.\n", value); + ENgetnodevalue(id, EN_QUALITY, &value); + printf("Node 184's quality = %f.\n", value); + } + } + ENcloseHQ(); + ENclose(); + + +} + + +#endif \ No newline at end of file