Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Calculate the flow from/to a surface model #111

Open
lrntct opened this issue Dec 4, 2017 · 101 comments
Open

Calculate the flow from/to a surface model #111

lrntct opened this issue Dec 4, 2017 · 101 comments

Comments

@lrntct
Copy link

lrntct commented Dec 4, 2017

Some recent discussions on the OpenSWMM mailing list shows that there is some interest in linking SWMM to a 2D surface domain.
This as been done by some commercial packages, and by researchers as well [1, 2].
I achieved this in Itzï by using Cython, but it could be much cleaner (and possibly faster) if this computation is done directly in the SWMM model.

I believe this would be a nice addition to SWMM. I have an adea on how it could be implemented. I'll detail it is subsequent posts.

See related issues:
#110

[1] Seyoum, Solomon Dagnachew, Zoran Vojinovic, Roland K Price, and Sutat Weesakul. 2012. “Coupled 1D and Noninertia 2D Flood Inundation Model for Simulation of Urban Flooding.” Journal of Hydraulic Engineering 138 (1). American Society of Civil Engineers:23–34.
[2] Leandro, J., and R. Martins. 2016. “A Methodology for Linking 2D Overland Flow Models with the Sewer Network Model SWMM 5.1 Based on Dynamic Link Libraries.” Water Science and Technology 73 (12):3017–26. https://doi.org/10.2166/wst.2016.171.

@lrntct
Copy link
Author

lrntct commented Dec 4, 2017

I think that it could be implemented in the following way, by using orifice and weir equations to calculate the flow:

A function that loop through the nodes, calling another function for each node:

  • if the node is not linked, continue
  • determine the type of equation to use, according to the relative heads in the node and the domain
  • calculate and apply the lateral flow

To calculate the flow, the main function needs to be aware of two values from the surface model:

  • The surface area on which it applies (i.e, raster cell, computing element, etc.)
  • The water depth on the surface (considering that the ground surface elevation is equal to the crest elevation)

This could be done in two way:

  • Either the loop function takes as an argument a AoS of the same size as the SWMM Node array, or
  • the Node struct contain those values, which are set with another function

I think that the first option my be the best, as the AoS could contain the calculated flow, as a feedback to the surface model.

The TNode struct should have new values added:

  • The linkage type (int), from an Enum that could be:
    • Not linked
    • Linked, no flow
    • Orifice
    • Free weir
    • Submerged weir
  • Orifice coefficient
  • Free weir coefficient
  • Submerged weir coefficient

A more advanced way could be to link to another "manhole cover" object, that would determine those coefficients and the manhole shape. Those values influence the actual flow

My knowledge of the SWMM code base is not very deep, so I'd be glad to have the opinion of other developers on that.

It might be adequate to use ExtInflow for the calculated flow, as it could transfer pollutants. However, could ExtInflow be negative in case of outflow?

@lrntct
Copy link
Author

lrntct commented Dec 4, 2017

Some theory on the use of weir and orifice for the flow calculation are found here:
http://documents.irevues.inist.fr/bitstream/handle/2042/25250/0465_239chen.pdf

I would propose to simplify the solution described in this paper by using only the orifice equation when the node is overflowing.

This solution as been proven with comparison to a physical model:

Rubinato, Matteo, Ricardo Martins, Georges Kesserwani, Jorge Leandro, Slobodan Djordjević, and James Shucksmith. 2017. “Experimental Calibration and Validation of Sewer/surface Flow Exchange Equations in Steady and Unsteady Flow Conditions.” Journal of Hydrology 552 (September):421–32. https://doi.org/10.1016/j.jhydrol.2017.06.024.

@RudyFrom3
Copy link

I would expect that there would be a benefit to having BOTH the Weir and orifice equation applying, as described in many texts such as the 1956 John Hopkins University "The Design of Storm Water Inlets", whereby the opening operates as a weir, until it is drowned and then acts as an orifice. For this to occur an effective weir length L is required and an effective clear opening area A (accounting for bars etc.)

Noting that at times there may be two sets of these required for say a Grated Opening plus a Kerb Inlet.

The Alternative approach is a RATING Curve.

Note also that application of a Blockage factor or functional would also be very useful.

@lrntct
Copy link
Author

lrntct commented Dec 4, 2017

I would expect that there would be a benefit to having BOTH the Weir and orifice equation applying, as described in many texts such as the 1956 John Hopkins University "The Design of Storm Water Inlets", whereby the opening operates as a weir, until it is drowned and then acts as an orifice. For this to occur an effective weir length L is required and an effective clear opening area A (accounting for bars etc.)

What I propose:

  • When the surface drains into the sewer, use free weir, submerged weir or orifice, depending on the relative water heads and crest elevation (see the PDF I shared)
  • When the drainage is overflowing, orifice.

However, different authors use different combinations, and it does not seems that there is a definite answer to that.

For the weir length and opening area, I was thinking that we could start with a simplified model that:

  • consider the opening area equal to the manhole surface area.
  • deduce the weir width from the manhole area, assuming it is circular.

However, in reality the lid is usually smaller than the actual manhole, and a more complex system might be useful. It is what I was referring to when proposing the addition of a "manhole cover" object. This object could contain the following information:

  • cover surface area
  • circumference of the opening
  • orifice and weir coefficients
  • ...

Noting that at times there may be two sets of these required for say a Grated Opening plus a Kerb Inlet.

Of course, the reality is more complex, and there are way to represent it more finely. For example, see this article about drainage and overflow from various inlets, and taking into account the lifting force of the manhole cover:

Chen, A. S., Leandro, J., & Djordjević, S. (2015). Modelling sewer discharge via displacement of manhole covers during flood events using 1D/2D SIPSON/P-DWave dual drainage simulations. Urban Water Journal, 9006(August), 1–11. https://doi.org/10.1080/1573062X.2015.1041991

However, implementing a solution like this might be much more complex, and we have to evaluate the its actual benefit. For a software like SWMM that is usually used on a large scale (city-wide), I'm not sure if it is worth the pain.
In the real world, having complete information of the main drainage network is already quite rare. I don't know if many utilities have informations about the inlets locations and numbers, yet alone their types.
There might be some use cases where those modelling details are useful, but for now it looks like a first world problem to me.

Note also that application of a Blockage factor or functional would also be very useful.

That would be indeed interesting. Do you have any literature recommendation on that matter?

@RudyFrom3
Copy link

In Australia there are a few papers on Culvert Blockage (more so than pits) however many local authorities require a blockage factor to be applied when undertaking analysis. I will try and track down resources. For example Wollongong City Council specifies 50% and 80% blockage in:

http://www.wollongong.nsw.gov.au/council/governance/Policies/Wollongong%20DCP%202009%20Chapter%20E14%20-%20Stormwater%20Management.pdf
Similarly:
http://www.nillumbik.vic.gov.au/files/assets/public/council/council-publications/drainage_design_guidelines_january_2013.pdf

However the notion of using a Factor on the calculated flow (Q) for the pit inlet capacity is useful, for both analysing the impact of blockage, but also testing the system with say a Factor of 2 to double the capacity (to easily assess impact of doubling the pit capacity).

@lrntct
Copy link
Author

lrntct commented Dec 7, 2017

@RudyFrom3 It seems to me that those documents are more like general design guidelines that call for a "safety factor", more than the actual occurring clogging, and even less how the blockage build-up in time during an event.
We could potentially add a inlet efficiency coefficient, but it might be redundant with the weir and orifice coefficients. Furthermore, clogging is not the only source of inlet inefficiency [1]. Accurately estimating the actual flow passing through an inlet is a complex subject and it does not seems settled yet among the scientific and engineering community

[1] Inefficiency of storm water inlets as a source of urban floods
J. Despotovic, J. Plavsic, N. Stefanovic, D. Pavlovic
Water Science and Technology Jan 2005, 51 (2) 139-145;

@lrntct
Copy link
Author

lrntct commented Dec 7, 2017

As for representing multiple inlets, creating multiple smaller junctions (see #112) might be the easiest way to do it, instead of setting complex multiple-linking elements.

@RudyFrom3
Copy link

I would have thought that the NODE simply be given some surface OPENING characteristics that define how FLOW from the surface enters the NODE. The NODE is simply a small storage that is part of the the internal transfer between links, and allows for additional surface flow to enter through the OPENING that is on the surface. Typically the opening would act as a weir initially and then at some higher depth act as an orifice. (Or it could be described by a rating curve Depth Versus Flow)

@lrntct
Copy link
Author

lrntct commented Dec 7, 2017

@RudyFrom3 I agree with you. That is why I was proposing a a "manhole cover" object. See my post above.

However, in reality the lid is usually smaller than the actual manhole, and a more complex system might be useful. It is what I was referring to when proposing the addition of a "manhole cover" object. This object could contain the following information:

cover surface area
circumference of the opening
orifice and weir coefficients
...

But this does not negate the need of a way to set the manhole (not opening) area individually.

@RudyFrom3
Copy link

The only reason I think it would be useful for the Manhole Lid Object to have Multiple Child Objects that represent openings is as in the following example:
image
Where the Grate has a Weir Length initially (Pink Lines) then an Effective Area (The openings in the grate) and the Kerb Inlet has initially a weir length (green line) followed by a vertical orifice opening being the yellow outline....
So the calculation for discharge would involve:
Qgrate(low) = CLD^1.5
Qkerb(low) =CLD^1.5
Qgrate(high) = Q = Cd A\sqrt{2gD}
Qkerb(high) = Q = Cd A\sqrt{2gD} (Or better for large lateral apertures?)

Etc....

@lrntct
Copy link
Author

lrntct commented Dec 8, 2017

@RudyFrom3 Maybe one Node object could have multiple nodeOpenning objects to take into account those cases?
But then again, this type of approach implies substantial changes in the swmm code.

As a first step, we could consider that the nodes are circular and have one opening of the size of the node surfaceArea. It is far from perfect and it is a strong simplification, but the implementation would be much easier. I think I could implement this rather quickly, as I already did something very similar in another software. This would allow us to test it and work on the interface with our respective 2d models.
Then, later, we could work on adding the nodeOpenning objects.

But, the nodeOpenning object struct would have the advantage of structuring better the data. Without it, we will have orifice/weir coefficients inside the Node struct, which is not ideal.

@lrntct
Copy link
Author

lrntct commented Dec 8, 2017

Another thing to think about is what happen to the overflow and ponding calculations that are already present in swmm.

@lrntct
Copy link
Author

lrntct commented Dec 10, 2017

I'm working on an implementation. It might take some time before it is functional.

@dickinsonre
Copy link

You should also worry about what happens when a manhole surcharges as it shifts to a new node solution when the depth in the node is above the ycrown of the highest connecting link to the node. It might be cleaner to just have storage nodes connect to a 2D mesh.

@lrntct
Copy link
Author

lrntct commented Dec 10, 2017

@dickinsonre Thank you for your comment.
I think you refer to what is done in setNodeDepth()?
Why is a surcharged node treated differently? If it is for stability, what would make a storage more stable?

@dickinsonre
Copy link

A quick answer and a better answer is to took at the EPA Hydraulics manual for SWMM5, Lew Rossman does a great job of presenting HOW the Surcharge solution is different than the normal node continuity equation. Here is a link as well as on OPENSWMM.ORG
https://www.openswmm.org/Topic/4341/surcharged-conduits-and-phantom-storage
talks about problems with tunnels and the surcharge algorithm. If i may make a suggestion, before you make changes to the SWMM5 code you should try to understand how it works fully, but to answer your last question. A storage nodes has a solution that is very different in many aspects than a node that is surcharged and a node that is not surcharged. If you would look at the SWMM5 dynamic wave code it will be more clear as to HOW it is different.

@dickinsonre
Copy link

dickinsonre commented Dec 10, 2017

Thinking about this more there might be a simple flag that can be added to make the solution for storage or surcharged node transparent to the user. A key engine parameter is called yCrown (the crown of the highest connected pipe to a node), The program shifts to the surcharge algorithm at 0.96 * yCrown. If you change the code so that a 2D node has a yCrown above the rim elevation of the node then the surcharge algothim will not be used for node but the normal node continuity equation with the default surface area.

Regarding the weir vs orifice, i would suggest a weir only for the following reason
​Note: Weir and Orifice Flow Equations for a Weir in SWMM 5
If you use a weir in SWMM 5 then two flow equations are used

  1.   The weir uses the weir flow equation when the head at the weir is between the invert elevation of the weir and the crown of the weir and
    
  2.  An orifice equation when the head is above the weir crown or the weir is submerged
    

Image is shown below
https://swmm5.org/2013/08/04/weir-and-orifice-flow-equations-for-a-weir-in-swmm-5/

@lrntct
Copy link
Author

lrntct commented Dec 10, 2017

@dickinsonre Thank you ery much for your comments.

A storage nodes has a solution that is very different in many aspects than a node that is surcharged and a node that is not surcharged. If you would look at the SWMM5 dynamic wave code it will be more clear as to HOW it is different.

I read the relevant part in the swmm hydraulic manual. I think I understand HOW the codes that update H for surcharged node and storage nodes are different. What I still fail to understand is WHY it is different. In dynamic wave routing, a node will always have a minSurfaceArea and a volume. So it is a kind of simplified storage. AFAIU, a storage node can surcharge (i.e all connected links are full), but will always use the under-relaxation scheme for updating its water depth, never the surcharge scheme. Why all types nodes are not doing the same?

Thinking about this more there might be a simple flag that can be added to make the solution for storage or surcharged node transparent to the user. A key engine parameter is called yCrown (the crown of the highest connected pipe to a node), The program shifts to the surcharge algorithm at 0.96 * yCrown. If you change the code so that a 2D node has a yCrown above the rim elevation of the node then the surcharge algothim will not be used for node but the normal node continuity equation with the default surface area.

That is indeed a neat idea. The drawback is that those nodes will never be reported as surcharged, I guess.

The other option would be to create another class of node, but it will imply large changes in the engine.

Regarding the weir vs orifice, i would suggest a weir only for the following reason
​Note: Weir and Orifice Flow Equations for a Weir in SWMM 5
If you use a weir in SWMM 5 then two flow equations are used

  The weir uses the weir flow equation when the head at the weir is between the invert elevation of the weir and the crown of the weir and

 An orifice equation when the head is above the weir crown or the weir is submerged

Image is shown below
https://swmm5.org/2013/08/04/weir-and-orifice-flow-equations-for-a-weir-in-swmm-5/

I was thinking of simply hard-coding the weir and orifice equations in the coupling function. But it could make sense to re-use the swmm weir/orifice equations.

@dickinsonre
Copy link

dickinsonre commented Dec 11, 2017

It is always better to use the existing code. You can automatically make a new orifice and/or weir in the engine to communicate flows. Key code from SWMM5 for the handling of the calculation of depth in junctions, storage nodes etc

void setNodeDepth(int i, double dt)
//
//  Input:   i  = node index
//           dt = time step (sec)
//  Output:  none
//  Purpose: sets depth at non-outfall node after current time step.
//
{
    int     canPond;                   // TRUE if node can pond overflows
    int     isPonded;                  // TRUE if node is currently ponded 
    double  dQ;                        // inflow minus outflow at node (cfs)
    double  dV;                        // change in node volume (ft3)
    double  dy;                        // change in node depth (ft)
    double  yMax;                      // max. depth at node (ft)
    double  yOld;                      // node depth at previous time step (ft)
    double  yLast;                     // previous node depth (ft)
    double  yNew;                      // new node depth (ft)
    double  yCrown;                    // depth to node crown (ft)
    double  surfArea;                  // node surface area (ft2)
    double  denom;                     // denominator term
    double  corr;                      // correction factor
    double  f=0.0;                     // relative surcharge depth

    // --- see if node can pond water above it
    canPond = (AllowPonding && Node[i].pondedArea > 0.0);
    isPonded = (canPond && Node[i].newDepth > Node[i].fullDepth);

    // --- initialize values
    yCrown = Node[i].crownElev - Node[i].invertElev;
    yOld = Node[i].oldDepth;
    yLast = Node[i].newDepth;
    Node[i].overflow = 0.0;
    surfArea = Xnode[i].newSurfArea;

    // --- determine average net flow volume into node over the time step
    dQ = Node[i].inflow - Node[i].outflow;
    dV = 0.5 * (Node[i].oldNetInflow + dQ) * dt;

    **# // --- if node not surcharged or the node is a storage node , base depth change on surface area**        
    if ( yLast <= yCrown || Node[i].type == STORAGE || isPonded )
    {
        dy = dV / surfArea;
        yNew = yOld + dy;

        // --- save non-ponded surface area for use in surcharge algorithm     //(5.1.002)
        if ( !isPonded ) Xnode[i].oldSurfArea = surfArea;                      //(5.1.002)

        // --- apply under-relaxation to new depth estimate
        if ( Steps > 0 )
        {
            yNew = (1.0 - Omega) * yLast + Omega * yNew;
        }

        // --- don't allow a ponded node to drop much below full depth
        if ( isPonded && yNew < Node[i].fullDepth )
            yNew = Node[i].fullDepth - FUDGE;
    }

    // --- if node surcharged, base depth change on dqdh
    //     NOTE: depth change is w.r.t depth from previous
    //     iteration; also, do not apply under-relaxation.
    else
    {
        // --- apply correction factor for upstream terminal nodes
        corr = 1.0;
        if ( Node[i].degree < 0 ) corr = 0.6;

        // --- allow surface area from last non-surcharged condition
        //     to influence dqdh if depth close to crown depth
        denom = Xnode[i].sumdqdh;
        if ( yLast < 1.25 * yCrown )
        {
            f = (yLast - yCrown) / yCrown;
            denom += (Xnode[i].oldSurfArea/dt -             
                     Xnode[i].sumdqdh) * exp(-15.0 * f);     
        }

        // --- compute new estimate of node depth
        if ( denom == 0.0 ) dy = 0.0;
        else dy = corr * dQ / denom;
        yNew = yLast + dy;
        if ( yNew < yCrown ) yNew = yCrown - FUDGE;

        // --- don't allow a newly ponded node to rise much above full depth
        if ( canPond && yNew > Node[i].fullDepth )
            yNew = Node[i].fullDepth + FUDGE;
    }

    // --- depth cannot be negative
    if ( yNew < 0 ) yNew = 0.0;

    // --- determine max. non-flooded depth
    yMax = Node[i].fullDepth;
    if ( canPond == FALSE ) yMax += Node[i].surDepth;

    // --- find flooded depth & volume
    if ( yNew > yMax )
    {
        yNew = getFloodedDepth(i, canPond, dV, yNew, yMax, dt);
    }
    else Node[i].newVolume = node_getVolume(i, yNew);

    // --- compute change in depth w.r.t. time
    Xnode[i].dYdT = fabs(yNew - yOld) / dt;

@RudyFrom3
Copy link

based on #124 being closed off, I am assuming that the weir/orifice connection to SWMM is now operational and that the stumbling block for 2D models now is only on how to link the exchange of information to and from SWMM? So to drive the Weir/Orifice a value of depth is required that is representative of the depth over a pit Top. For Pits that Surcharge, the Flow from SWMM needs to be passed back to the 2D model. There is the third required component.... Once the depth is passed, the Weir/Orifice calculation identifies a Flow, which may or may not be excepted by the connecting pipe link. So a secondary calculation is required in SWMM to identify that the Pipe has the capacity to except the total flow (that coming from pipes upstream if any, and the Pit Top Flow). This calculation may inform that the PitTop flow is in fact limited to something less than that calculated by the PitTop. It is important to do this check as this is the flow that needs to be removed from the 2D model, and also to ensure Volumetric accounting is accurate. That is, no water is lost, because of differences in Pipe & Pit capacities! So to Summarise there are three pieces of information required and a further check:

  • Water Depth in the 2D domain
  • Calculated PitTop FLOW
  • Confirmed Pit Top Flow (Adjusted based on pipe Capacity) (Flow taken from the 2D domain)
  • CHECK if Flow Surcharged in the case that the upstream pipe has greater capacity than a downstream pipe and the PitTop inflow is negative... (Surcharging)

@lrntct
Copy link
Author

lrntct commented Aug 3, 2018

@RudyFrom3

Once the depth is passed, the Weir/Orifice calculation identifies a Flow, which may or may not be excepted by the connecting pipe link. So a secondary calculation is required in SWMM to identify that the Pipe has the capacity to except the total flow (that coming from pipes upstream if any, and the Pit Top Flow)

When using the dynamic solver, a SWMM node is a storage. All the flows that enter a node(from pipes, user inflow, catchment, etc.) are added to/subtracted from the amount of water stored in the node. This in turn changes the water surface elevation in the node. The latter is used to calculate the flow in the pipes connected to the node at the next time step.
The mass balance is maintained at all time.

Now, the added interchange code can add or remove quite a bit of mass from one time-step to another, which in turn could induce oscillations. Some techniques are implemented in the code to limit the potential instabilities. See especially the coupling_findNodeInflow function. First the exchange flow cannot change sign from one time-step to another. Second, there is a flow limiter that prevents negative depth in the surface model.

In my PhD thesis there are more details on how this was implemented in Itzï, and the influence of those techniques on the coupled model stability. The sections of interest are 2.2 and 3.2.

@RudyFrom3
Copy link

Hi all, just a desperate Plea for a Status Update ??
What needs to be completed for there to be a Generic available method to link SWMM to 2D models ?
I am at a point where I am willing to pay some one if there needs to be coding done ?
Where to from here ?

@bemcdonnell
Copy link
Member

@RudyFrom3,

the feature "as-is" is already sitting in the feature-2dflood feature branch. The biggest thing that needs to happen at this point are unit/reg tests and documentation. I'm not sure of the status of it - but if you are to begin using it, you should log bugs and other issues that you have with it. When a contributor brings this 2D link implementation to the finish line, the we can merge it all the way up to the develop branch. But nothing should be stopping anyone from using it "as-is" today.

Does this make sense?

@bemcdonnell
Copy link
Member

I'm particularly interesting in @dickinsonre's thoughts on this as well

@RudyFrom3
Copy link

Ok... is there any where a small example of how it is to operate ?
- How to pass Depth from the 2D model to SWMM
- How to check the SWMM state (Pipes already full ? or able to accept Water)
- Report Flow accepted by SWMM back to 2D model
- Pass Flow from 'End of Pipe' to the 2D model

Once I can determine how this is done I'd be very happy to set up various tests....

@dickinsonre
Copy link

dickinsonre commented Oct 17, 2018

I will comment on this, Rudy, later in the week. It might take me all werk @RudyFrom3 due to just getting back to my normal work schedule after a long month of traveling

@lrntct
Copy link
Author

lrntct commented Sep 18, 2020

@bemcdonnell what would be the requirements to have the feature2dflood branch merged into dev? Right now, I see this:

Is the OWA core team open to have such a feature included in the main branch?

@michaeltryby
Copy link

@lrntct and @bemcdonnell my understanding from a recent conversation I had with @LRossman is that he is working on a feature that may complement the work proposed here.

@LRossman
Copy link

The feature that I am working on is to add storm drain inlet analysis to SWMM. It computes the amount of surface flow captured by street inlet structures (grates and curb openings) and sent into a below ground sewer system using the FHWA HEC-22 methodology. HEC-22 is the de facto standard used in the US for analyzing street drainage systems, referred to in numerous state and local agency design manuals.

image

HEC-22 uses different sets of equations to compute capture efficiency depending on whether an inlet is located on grade or on sag. Similar to feature2dflood there is no need to explicitly represent the transfer between the surface (major) system and sub-surface (minor) system with an orifice or weir element. Once the amount of flow captured by the inlet is computed it is directly transferred between the two systems. Below is the single additional function that accomplishes this for Dynamic Wave analysis, called for each link after new flows have been found and before new node depths are computed:

void redirectInletFlows(int i)
//
//  Input:   i = link index
//  Output:  none
//  Purpose: removes flow captured by an inlet placed in link i and adds
//           it to the inlet's designated receptor node.
//
{
    int j, m;
    double qc;

    // --- check that link has an inlet receptor node
    m = inlet_getReceptorNode(i);
    if (m < 0) return;

    // --- find flow captured by the inlet
    qc = inlet_getCapturedFlow(i);

    // --- find which end of link to remove flow from
    if (Link[i].newFlow >= 0.0)
        j = Link[i].node2;
    else
        j = Link[i].node1;

    // --- remove flow from link's end node and add it to receptor node
    Node[j].inflow -= qc;
    Node[m].inflow += qc;
}

Similar code exists for inlet analysis under Steady Flow and Kinematic Wave routing. There is also the option to send the captured flow onto a subcatchment which could contain an LID control. All of the HEC-22 calculations are made in a new code module named inlet.c.

This feature is purely optional and doesn't interfere with any of SWMM's normal calculations if it is not deployed. I expect to have a completed version of it by the end of the month and will be happy to share it with OWA-SWMM.

@michaeltryby
Copy link

@LRossman Thanks for the update!

@bemcdonnell
Copy link
Member

@LRossman that's pretty impressive actually. Thanks (in advance) for making those updates!

@valterhydrodynamics
Copy link

valterhydrodynamics commented Sep 18, 2020 via email

@dickinsonre
Copy link

This is fantastic Lew and helpful to so many people. I have a few questions - what happens if the sub surface pipe system is full and there is surcharge? Does the inlet flow reverse and flow goes into the street?

@LRossman
Copy link

@dickinsonre yes, that's the idea although I haven't implemented it yet. I will probably use the on sag HEC-22 equations for this, even for on grade inlets, as they are orifice/weir based. It will also require that the program adjust the rim elevations of the receptor sewer nodes so they equal the elevation of the top of the street curb they receive captured flow from. Once implemented, the inlet_getCapturedFlow() function in the code listed above will simply be returning a negative value.

I forgot to mention that another feature being added is a re-usable Street Cross Section object that makes it easier to set up a surface street network. The shape and its parameters are shown below and the program automatically computes an internally used transect with the relevant geometric properties for it.

Street_xsect6

@lrntct
Copy link
Author

lrntct commented Sep 18, 2020

@LRossman That's neat! It is a different approach than the solution proposed here, but they could share some code?
For instance optionally using a HEC22 inlet formula instead of weir/orifice equation for the flow interchange with an external model?

@LRossman
Copy link

@lrntct it seems it would be awkward to share code between the two types of flow exchange applications. One major difference is that the HEC-22 inlets are placed in street conduits, not at the street junction nodes. And there can be more than one inlet per street and a different number per each side of the street (they get evaluated sequentially for on grade conditions).

There are two new data structures defined in inlet.h that hold information about inlets. The TInletDesign struct contains information on a particular inlet's design (inlet type and its dimensions). The collection of a project's available designs are stored in a InletDesign array. The TInletUsage struct indicates which inlet design a street conduit should use, how many inlets to use, where to send the captured flow, and to what degree the inlet is clogged. The only linkage between these new inlet-related objects and SWMM's original data structures is through a new property added to the TLink struct, named inlet which is a pointer to a TInletUsage struct. It's not apparent to me how these data structures could be shared with flow exchanges to an external 2-D surface model. Perhaps you can see an opportunity (or it might be easier to look for it after the source code is posted).

@RudyFrom3
Copy link

Hi All, The ANUGA team has now got a number of ANU Students assisting with Coding... The Students have got working code, but are struggling to get access to the correct Paramters to ensure their volumetric check is correct. Can anyone please List the complete volumetric check at the NODES... Thank you

@dickinsonre
Copy link

If they are reading the code then HOW node depths, node areas, and flooded volume is calculated is shown in the function setNodeDepth in the SWMM5 Code. If you want to see the overall volume check have them read the SWMM5 hydraulics reference manual or looks at the code in statsrpt.c. Please remember, the flooded loss is different with the Extran and Slot options and surface or non surface ponding. The slot option is a cleaner solution for 2D connections, IMO.

@Chen-Huang-326
Copy link

Hi all, we are the ANUGA team from ANU. Currently, we have implemented a method to couple ANUGA and PySWMM. However, we have some confusions about some parameters in PySWMM.
As we try to calculate the water loss in each time step during a flooding simulation, we basically use the real water volume minus expected water volume in each time step. The expected water volume is the water we pour into the ANUGA domain which is used for simulation (a constant input water with velocity 0.25 m3/s, so the total expected water volume = 0.25 m3/s * t). And the real water volume is the water on the ground (we can use a method to get all water on ANUGA domain) plus the water in the SWMM pipe system. However, we are not sure which PySWMM parameters should be involved. We would be grateful if you have any suggestions about what parameters should be involved to calculate the water in the pipe system.
From my perspective, the water in the pipe system should be the combination of the water in the conduits. But, there are two parameters related to the water in a conduit, "flow" and "volume". I would like to confirm the difference between these two parameters. Or, perhaps there are any additional water should be considered, such as the water at each node?

In addition, we have some confusions about the total_inflow and total_outflow at each node. From my understanding, the total_inflow is the inflow rate at a node and total_outflow is the outflow rate at a node that both units of them are volume per time step. We would be grateful if you could help us check our understanding. In addition, we found that the total_outflow at an outfall type of node is always 0. We are confusing about why the total_outflow at the node with outfall type cannot be obtained.

Furthermore, we found that the water loss we aim to calculate is related to the loss of SWMM and we would like to compare the two losses. According to the SWMM system, we found that there is a parameter in PySWMM called flow_routing_error which indicates the water loss during the whole simulation process. However, the flow_routing_error is always 0 when we would like to call it and print it.

Thank you in advance. We appreciate any suggestions.

@dickinsonre
Copy link

But, there are two parameters related to the water in a conduit, "flow" and "volume" - flow in SWMM5 is the solution to the St Venant 1D equation based on the hydraulic characteristics at the ends of the links. The hydraulic characteristics are based on the depth at the upstream and downstream ends of the link. The volume is based on depth. Volume is not the same as flow. For example, you can have a full pipe with no flow if the HGL is flat or there is a backwater condition to the pipe. There is one flow per link but three depths.

@dickinsonre
Copy link

Storage nodes have a volume of water at each time step so "water at each node" is important. How is knowing the total volume of the network at each time step helping your computer flooding loss?

@Chen-Huang-326
Copy link

But, there are two parameters related to the water in a conduit, "flow" and "volume" - flow in SWMM5 is the solution to the St Venant 1D equation based on the hydraulic characteristics at the ends of the links. The hydraulic characteristics are based on the depth at the upstream and downstream ends of the link. The volume is based on depth. Volume is not the same as flow. For example, you can have a full pipe with no flow if the HGL is flat or there is a backwater condition to the pipe. There is one flow per link but three depths.

So when there is a backwater in a pipe, the flow may be 0 as it is offset by the backwater? And whether it means the volume is calculated by the average depth of water in the link? Volume is the total water volume in that link in a specific time step?

@Chen-Huang-326
Copy link

Storage nodes have a volume of water at each time step so "water at each node" is important. How is knowing the total volume of the network at each time step helping your computer flooding loss?

From our consideration, the total volume of the network at each time can give us the total volume which is not on the ANUGA domain. As the water will be pass to the network from ANUGA domain when coupling in each time step, the water passed into the network will be eliminated from the ANUGA domain. Therefore, we believe the water remained on the ANUGA domain and water in the network is the total water in a specific time. So when can we use the value to compare with the expected volume (a constant input volume * simulation duration) to get how much water will be lost during simulation. Actually, if we can only compare the water volume at the end of simulation, that's acceptable as well. We would like to check whether our hypothesis
is manipulatable.

@dickinsonre
Copy link

The volume in a link is

Link[j].newVolume = aMid * link_getLength(j) * barrels;

where aMid is the cross-sectional area of the link based on the Midpoint depth. The Midpoint depth is the average of the upstream and downstream depths in the link. Barrels are just the number of the same links with the same hydraulic characteristics between the same two nodes. It is normally one. Length is the length of the link - some links are lengthened if the pipe is short and the user selects that option. So volume is related to flow but you cannot just take flow and get the link volume. Flow is the solution - volume is a calculated value. It changes every time step and is calculated at every iteration.

@dickinsonre
Copy link

the total volume of the network at each time == the total volume at each time is also affected by the inflows to the nodes, and outflows from the outfalls - you seem to have one inflow and no outfalls so maybe this is not a concern now of yours but should be a concern in the future.

@RudyFrom3
Copy link

From My Perspective in terms of functionality:

  • ANUGA is the overland flow model
  • SWMM the Pipe Network Model
  • At the start of a simulation both are Dry, As rainfall starts initially the ANUGA Domain is wet and runoff starts to build and flow toward the NODE locations.
  • The depth of water at the NODE locations determines the Potential inflow,
  • The flow starts to fill the Node (Pit) and drive FLow into the PIpe Segment
  • As the flow increases at some point the inflow Potential (Driven by the depth) into the Pit may exceed the Pipe Capacity, hence some of the inflow as determined by the driving depth cannot be accepted.
  • When the rain stops and runoff reduces, eventually the overland flow stops, and some time after that the remain volume in the pipe network drains out... leaving both essentially dry...
  • The volumetric check is important to ensure the total mass at every time step is fully accounted for ensuring a totally mathematical stable simulation.....

@dickinsonre
Copy link

dickinsonre commented Apr 10, 2021

Comments in Quotes

• At the start of a simulation both are Dry, As rainfall starts initially the ANUGA Domain is wet, and runoff starts to build and flow toward the NODE locations. “What about the 1D network? Is that dry at the start as well?”
• The depth of water at the NODE locations determines the Potential inflow, “The depth above the Rim Elevation of the node? What happens if you have bad DEM data and the ANUGA grid is below or above the Rim Elevation of the Node?”
• The flow starts to fill the Node (Pit) and drive Flow into the PIpe Segment “The flow in the pipe is based on the depth of water in the node above the Invert of the node – the invert of the pipe matters as well if there is a pipe offset from the node invert. Should you not use Elevation instead of depth to drive the flow into ou out of the node?”
• As the flow increases at some point the inflow Potential (Driven by the depth) into the Pit may exceed the Pipe Capacity, hence some of the inflow as determined by the driving depth cannot be accepted. “The pipe capacity does not matter – the solution of SWMM5 is a 1D St Venant iterative solution based on the HGL at both ends of the link. The HGL is often related to the nide HGL but not always if there is an offset in the link.”
• When the rain stops and runoff reduces, eventually the overland flow stops, and sometime after that the remaining volume in the pipe network drains out... leaving both essentially dry... “Okay”
• The volumetric check is important to ensure the total mass at every time step is fully accounted for ensuring a totally mathematical stable simulation... “In SWMM5 there is overall network volume check and a node-by-node volume check. You need to check the 1D to 2D node continuity as well. You could have an overall good balance but a bad balance at certain nodes.”

@RudyFrom3
Copy link

• At the start of a simulation both are Dry, As rainfall starts initially the ANUGA Domain is wet, and runoff starts to build and flow toward the NODE locations.
“What about the 1D network? Is that dry at the start as well?” {The assumption is prior to Any Rainfall unless there is back water and a water source down stream (River Lake Tide, the Piped System is Dry...}

• The depth of water at the NODE locations determines the Potential inflow,
“The depth above the Rim Elevation of the node? What happens if you have bad DEM data and the ANUGA grid is below or above the Rim Elevation of the Node?”
{There are ways to easily check this and adjust this so this is not the case..}

• The flow starts to fill the Node (Pit) and drive Flow into the PIpe Segment
“The flow in the pipe is based on the depth of water in the node above the Invert of the node – the invert of the pipe matters as well if there is a pipe offset from the node invert. Should you not use Elevation instead of depth to drive the flow into ou out of the node?” Depth is determined from Elevations (Elevation of Water, Ground, and Invert}

• As the flow increases at some point the inflow Potential (Driven by the depth) into the Pit may exceed the Pipe Capacity, hence some of the inflow as determined by the driving depth cannot be accepted.
“The pipe capacity does not matter – the solution of SWMM5 is a 1D St Venant iterative solution based on the HGL at both ends of the link. The HGL is often related to the nide HGL but not always if there is an offset in the link.”
{If this is the case you are saying that SWMM accounts for the pipe capacity being less than pit capacity automatically ?}

• When the rain stops and runoff reduces, eventually the overland flow stops, and sometime after that the remaining volume in the pipe network drains out... leaving both essentially dry... “Okay”

• The volumetric check is important to ensure the total mass at every time step is fully accounted for ensuring a totally mathematical stable simulation...
“In SWMM5 there is overall network volume check and a node-by-node volume check. You need to check the 1D to 2D node continuity as well. You could have an overall good balance but a bad balance at certain nodes.
{The mass continuity in ANUGA is cell to cell not overall.... hence for example the current Culvert Routines in ANUGA have full mass accounting for inflow and outflow at every time step...}

@dickinsonre
Copy link

dickinsonre commented Apr 11, 2021

Comment on this note of yours " Depth is determined from Elevations (Elevation of Water, Ground, and Invert}"

For example, say the rim elevation of the node is 100 meters, the invert of the node is 90 meters but the centroid of your ANGUA mesh cell is at 80 meters - the depth of water on the mesh would have to reach 20 meters for you to have any inflow from the mesh to the 1D network.

Another example, say the mesh centroid is at 110 meters then if you use only depths the flooded water can leave the node rim to the mesh as soon as there is a flooded depth - since the mesh has zero depth. I guess i just don't understand how using depth is correct.

I am probably not even understanding your approach to using depths.

Now reading https://www.wikiwand.com/en/ANUGA_Hydro

and other documentation. I see you have a Github location

2017/05/20: Github Branch created to initiate the development of SWMMLINK 1D Pipe network to ANUGA 2D Dr. Ole Nielsen, Assoc. Prof. Stephen Roberts, Rudy Van Drie, Dr. Petar Milevski

past swmm5 discussion which helps (me)

https://www.openswmm.org/Topic/9964/how-to-surcharge-swmm-into-a-2d-domain

this helps as well

https://github.com/GeoscienceAustralia/anuga_core

https://iwaponline.com/wst/article/73/12/3017/20354/A-methodology-for-linking-2D-overland-flow-models

@RudyFrom3
Copy link

Thank you for directing to those resources...
ANUGA has conserved quantities of Momentum X & Y and Stage (Water Level Elevation) and Ground Elevation, ANUGA does not know about depth. However in needing to calculate an inflow capacity in a INLET PIT or a CULVERT headwall, DEPTH is required. Hence various OPERATORS in ANUGA determine DEPTH and report on depth for these calculations.
For the SWMM LINK project I assume a similar process as currently occurs in the CULVERT OPERATORS would occur, where depth is calculated to determine the Inflow Capacity. ANUGA has available to it several methods by which the terrain can be forced to match PIT LIP Levels... so differences in terrain in the 2D domain and the PIT level are not so much an issue...

The coding in ANUGA to date has been very strict in terms of its accurate accounting for volume... the SWMM LINK needs to ensure an equivalent level of robustness...

@RudyFrom3
Copy link

I am really Struggling to Understand why it appears so difficult to talk to SWMM and extract something as simple as the Volume ?
What is the Volume in the System ?
Should it not simply be the Summation of the Link(s) Volume and Node(s) Volume ?

If we can track the Volume in ANUGA at every time step, we need to ensure that the SWMM doesnt Create or Loose any Volume? Currently Students working on this are finding a Volume Loss in SWMM.... which may be a reporting problem... or a real problem ?? This issue needs to be understood and fully identified before moving forward... Can any one please provide insight ? What happened to the SWMM LID TOP idea, to calculate the inflow through a Grate or a Lintel ??

@LRossman
Copy link

@RudyFrom3 I believe you can use the SystemStats class in PySwmm to get the components of the system flow balance (including the system volume contained in the member named final_storage) at each time step of a simulation. Please see this link.

I wonder if the reason your team is seeing a volume loss is because they are relying on the results displayed at each reporting time step and ignoring results at intermediate steps which are not reported.

Finally, if by "the SWMM LID TOP idea, to calculate the inflow through a Grate or a Lintel" you mean the comment I posted to this thread on 9/18/2020, it has been incorporated into a soon to be released version of EPA SWMM (not PySwmm). You can view a slide presentation about it here.

@valterhydrodynamics
Copy link

valterhydrodynamics commented Apr 21, 2021 via email

@dickinsonre
Copy link

SWMM5 is a link/node system in which the area of the node is found from the width times 1/2 length of the connecting links (if there are no offsets between node and link). I hope you are not getting the volume from the node area? I

t should be the volume in the links plus the actual volume of the nodes if you want to compare it to your 2D network. Can you make a time series to show the following:

  1. Volume in ANGUA, 2. Volume in SWMM5, 3. Inflow Volume from the 2D 4. Outflow volume from the 1D for each time step so at least others can see a numerical value for your volume questions. In general, does ANGUA lose volume over the time step? Evaporation, infiltration, or loss through a boundary?

@Chen-Huang-326
Copy link

Hi all, we have found the issues about water loss, it is attributed to the flooding loss when node.depth excesses the maximum depth + surcharge_depth at a node. And I found the flooding can be gotten by nodes.flooding. However, the unit of flooding seems always cubic feet even why have set the unit as cubic meters in SWMM. In other words, such as the unit of links.volume is cubic meters, the unit of nodes.flooding is still cubic feet.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests