Compile LemonTiger as a Win32 DLL. Use "LemonTiger.h" to access its functions. Added one new function - ENrunnextHQ().
This commit is contained in:
221
src/lemontiger.c
221
src/lemontiger.c
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user