Skip to content

Commit

Permalink
Merge pull request #771 from OpenWaterAnalytics/dev-tank_overflow_fix
Browse files Browse the repository at this point in the history
Account for mass lost in tank overflow
  • Loading branch information
LRossman authored Mar 18, 2024
2 parents 029b441 + 482f658 commit 2f4e4e5
Showing 1 changed file with 60 additions and 7 deletions.
67 changes: 60 additions & 7 deletions src/qualreact.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Description: computes water quality reactions within pipes and tanks
Authors: see AUTHORS
Copyright: see AUTHORS
License: see LICENSE
Last Updated: 05/15/2019
Last Updated: 03/12/2024
******************************************************************************
*/

Expand Down Expand Up @@ -492,6 +492,13 @@ void tankmix1(Project *pr, int i, double vin, double win, double vnet)
seg->v += vnet;
seg->v = MAX(0.0, seg->v);
tank->C = seg->c;

// Account for mass lost in tank overflow
if (seg->v > tank->Vmax)
{
qual->MassBalance.outflow += ((seg->v) - tank->Vmax) * tank->C;
seg->v = tank->Vmax;
}
}
}

Expand All @@ -513,7 +520,8 @@ void tankmix2(Project *pr, int i, double vin, double win, double vnet)

int k;
double vt, // Transferred volume
vmz; // Full mixing zone volume
vmz, // Full mixing zone volume
vsz; // Full stagnant zone volume
Pseg mixzone, // Mixing zone segment
stagzone; // Stagnant zone segment
Stank *tank = &pr->network.Tank[i];
Expand Down Expand Up @@ -559,8 +567,19 @@ void tankmix2(Project *pr, int i, double vin, double win, double vnet)
if (vt > 0.0)
{
mixzone->v = vmz;
if (vnet > 0.0) stagzone->v += vt;
else stagzone->v = MAX(0.0, ((stagzone->v) - vt));
if (vnet > 0.0)
{
stagzone->v += vt;

// Account for mass lost in overflow from stagnant zone
vsz = (tank->Vmax) - vmz;
if (stagzone->v > vsz)
{
qual->MassBalance.outflow += ((stagzone->v) - vsz) * stagzone->c;
stagzone->v = vsz;
}
}
else stagzone->v = MAX(0.0, ((stagzone->v) - vt));
}
else
{
Expand Down Expand Up @@ -612,10 +631,13 @@ void tankmix3(Project *pr, int i, double vin, double win, double vnet)
else addseg(pr, k, vin, cin);
}

// Withdraw flow from first segment
// Find volume leaving tank, adjusted so its volume doesn't exceed Vmax
vout = vin - vnet;
if (tank->V >= tank->Vmax && vnet > 0.0) vout = vin;

// Withdraw outflow from first segment
vsum = 0.0;
wsum = 0.0;
vout = vin - vnet;
while (vout > 0.0)
{
seg = qual->FirstSeg[k];
Expand Down Expand Up @@ -643,6 +665,10 @@ void tankmix3(Project *pr, int i, double vin, double win, double vnet)
if (vsum > 0.0) tank->C = wsum / vsum;
else if (qual->FirstSeg[k] == NULL) tank->C = 0.0;
else tank->C = qual->FirstSeg[k]->c;

// Account for mass lost in overflow from 1st segment
if (tank->V >= tank->Vmax && vnet > 0.0)
qual->MassBalance.outflow += vnet * tank->C;
}


Expand All @@ -669,7 +695,7 @@ void tankmix4(Project *pr, int i, double vin, double win, double vnet)
k = net->Nlinks + i;
if (qual->LastSeg[k] == NULL || qual->FirstSeg[k] == NULL) return;

// Find inflows & outflows
// Find inflow concentration
if (vin > 0.0) cin = win / vin;
else cin = 0.0;

Expand All @@ -687,6 +713,33 @@ void tankmix4(Project *pr, int i, double vin, double win, double vnet)

// Update reported tank quality
tank->C = qual->LastSeg[k]->c;

// If tank full then remove vnet from leading segments
if (tank->V >= tank->Vmax)
{
wsum = 0.0;
while (vnet > 0.0)
{
seg = qual->FirstSeg[k];
if (seg == NULL) break;
vseg = seg->v; // Flow volume from leading seg
vseg = MIN(vseg, vnet);
if (seg == qual->LastSeg[k]) vseg = vnet;
wsum += (seg->c) * vseg;
vnet -= vseg; // Remaining flow volume
if (vnet >= 0.0 && vseg >= seg->v) // Seg used up
{
if (seg->prev)
{
qual->FirstSeg[k] = seg->prev;
seg->prev = qual->FreeSeg;
qual->FreeSeg = seg;
}
}
else seg->v -= vseg; // Remaining volume in segment
}
qual->MassBalance.outflow += wsum;
}
}

// If tank emptying then remove last segments until vnet consumed
Expand Down

0 comments on commit 2f4e4e5

Please sign in to comment.