Compile LemonTiger as a Win32 DLL. Use "LemonTiger.h" to access its functions. Added one new function - ENrunnextHQ().

This commit is contained in:
JinduanChen
2013-01-28 15:14:10 -05:00
parent ca2bc04cba
commit 719114cb2e
12 changed files with 419 additions and 368 deletions

View File

@@ -2,13 +2,12 @@
#include "vars.h"
#include "funcs.h"
#include "toolkit.h"
#include "lemontiger.h"
extern char OutOfMemory;
extern int Haltflag;
int ENopeninitHQ() {
int DLLEXPORT ENopeninitHQ() {
int errcode = 0;
if (Hstep % Qstep) {
@@ -36,102 +35,67 @@ int ENopeninitHQ() {
return errcode;
}
long timestepLT(void)
/*
**----------------------------------------------------------------
** Input: none
** Output: returns time step until next change in hydraulics
** Purpose: computes time step to advance hydraulic simulation, but don't update tank levels
** Let nextqual() to do the job.
**----------------------------------------------------------------
*/
{
long n,t,tstep;
long timestepLT();
/* computes the length of the time step to next hydraulic simulation, but don't
update tank volumne and tank levels. During a sync HQ simulation,
nextqual() will update the tank vols */
/* Normal time step is hydraulic time step */
tstep = Hstep;
int nexthydLT(long *tstep);
/* finds length of next time step but don't save
results to hydraulics file. ignore reporting functions. */
/* Revise time step based on time until next demand period */
n = ((Htime+Pstart)/Pstep) + 1; /* Next pattern period */
t = n*Pstep - Htime; /* Time till next period */
if (t > 0 && t < tstep) tstep = t;
void updateTanklevels();
//Prior to running hydraulic simulation, update the tank levels.
/* Revise time step based on time until next reporting period */
t = Rtime - Htime;
if (t > 0 && t < tstep) tstep = t;
int DLLEXPORT ENrunnextHQ(long* pstime, /*Simulation time pointer*/
long* ptstep /*next time step*/ ) {
/* The lemonTiger equivalent of ENnextQ, hydraulic solver is called on-demand*/
long hydtime; /* Hydraulic solution time */
long hydstep; /* Hydraulic time step */
int errcode = 0;
/* Revise time step based on smallest time to fill or drain a tank */
tanktimestep(&tstep);
/* Revise time step based on smallest time to activate a control */
controltimestep(&tstep);
/* Evaluate rule-based controls (which will also update tank levels) */
if (Nrules > 0) ruletimestep(&tstep);
return(tstep);
}
int nexthydLT(long *tstep)
/*
**--------------------------------------------------------------
** Input: none
** Output: tstep = pointer to time step (in seconds)
** Returns: error code
** Purpose: finds length of next time step & updates tank
** levels and rule-based contol actions. don't save
** results to hydraulics file. don't consider Report time.
**--------------------------------------------------------------
*/
{
long hydstep; /* Actual time step */
int errcode = 0; /* Error code */
if (Haltflag) Htime = Dur;
/* Compute next time step & update tank levels */
*tstep = 0;
hydstep = 0;
if (Htime < Dur) hydstep = timestepLT();
/* Compute pumping energy */
if (Dur == 0) addenergy(0);
else if (Htime < Dur) addenergy(hydstep);
/* Update current time. */
if (Htime < Dur) /* More time remains */
/* if needed, push forward hydraulic simulation, similar to runqual() */
if (Qtime == Htime)
{
Htime += hydstep;
if ( (errcode = runhyd(&hydtime)) ||
(errcode = nexthydLT(&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;
}
else
{
Htime++; /* Force completion of analysis */
}
*tstep = hydstep;
*pstime = Htime;
hydstep = Htime - Qtime;
/* Perform water quality routing over this time step */
if (Qualflag != NONE && hydstep > 0) transport(hydstep);
updateTanklevels();
/* Update current time */
if (OutOfMemory) errcode = 101;
if (!errcode) *ptstep = hydstep;
Qtime += hydstep;
/* Save final output if no more time steps */
if (!errcode && Saveflag && *ptstep == 0) errcode = savefinaloutput();
return(errcode);
}
void updateTanklevels() {
int i,n;
int DLLEXPORT ENrunstepHQ(long* pstime /* Simulation time pointer */
,long* ptleft /* Time left in the simulation*/) {
for (i=1; i<=Ntanks; i++)
{
/* Skip reservoirs */
if (Tank[i].A == 0.0) continue;
/* The LemonTiger equivalence of ENstepQ, hydraulic solver is called on-demand */
n = Tank[i].Node;
/* Check if tank full/empty within next second */
if (Tank[i].V + D[n] >= Tank[i].Vmax) Tank[i].V = Tank[i].Vmax;
if (Tank[i].V - D[n] <= Tank[i].Vmin) Tank[i].V = Tank[i].Vmin;
H[n] = tankgrade(i,Tank[i].V);
}
}
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;
@@ -224,7 +188,8 @@ int ENrunstepHQ(long* pstime /* Simulation time pointer */
return(errcode);
}
int ENcloseHQ() {
int DLLEXPORT ENcloseHQ() {
int errcode = 0;
if ( (errcode = ENcloseQ()) || (errcode = ENcloseH()) )
return errcode;
@@ -232,5 +197,85 @@ int ENcloseHQ() {
}
long timestepLT(void) {
/* computes time step to advance hydraulic simulation, but don't
update tank levels. Instead, let nextqual() do the job. */
long n,t,tstep;
/* Normal time step is hydraulic time step */
tstep = Hstep;
/* Revise time step based on time until next demand period */
n = ((Htime+Pstart)/Pstep) + 1; /* Next pattern period */
t = n*Pstep - Htime; /* Time till next period */
if (t > 0 && t < tstep) tstep = t;
/* Revise time step based on time until next reporting period */
t = Rtime - Htime;
if (t > 0 && t < tstep) tstep = t;
/* Revise time step based on smallest time to fill or drain a tank */
tanktimestep(&tstep);
/* Revise time step based on smallest time to activate a control */
controltimestep(&tstep);
/* Evaluate rule-based controls (which will also update tank levels) */
if (Nrules > 0) ruletimestep(&tstep);
return(tstep);
}
int nexthydLT(long *tstep) {
/* finds length of next time step but don't updates tank volumnes and tank
levels and rule-based contol actions. don't save
results to hydraulics file. don't consider Report time. */
long hydstep; /* Actual time step */
int errcode = 0; /* Error code */
if (Haltflag) Htime = Dur;
/* Compute next time step & update tank levels */
*tstep = 0;
hydstep = 0;
if (Htime < Dur) hydstep = timestepLT();
/* Compute pumping energy */
if (Dur == 0) addenergy(0);
else if (Htime < Dur) addenergy(hydstep);
/* Update current time. */
if (Htime < Dur) /* More time remains */
{
Htime += hydstep;
}
else
{
Htime++; /* Force completion of analysis */
}
*tstep = hydstep;
return(errcode);
}
void updateTanklevels() { //Prior to doing hydraulic simulation, update the tank levels
int i,n;
for (i=1; i<=Ntanks; i++) {
/* Skip reservoirs */
if (Tank[i].A == 0.0) continue;
n = Tank[i].Node;
/* Check if tank full/empty within next second */
if (Tank[i].V + D[n] >= Tank[i].Vmax) Tank[i].V = Tank[i].Vmax;
if (Tank[i].V - D[n] <= Tank[i].Vmin) Tank[i].V = Tank[i].Vmin;
H[n] = tankgrade(i,Tank[i].V);
}
}