Friday, July 29, 2016

Solving Manning's equation with Python

Manning's equation is a very common formula used in hydraulic engineering. It is an empirical formula that estimates the average velocity of open channel flow, based on a roughness coefficient.



The problem of solving Manning's formula is that it is an implicit formula, for the water depth variable, that defines the R (Hydraulic Radius).

A common approach for solving this equation is using numerical methods, as the Newton-Raphson method. An implementation for the resolution of the Manning Formula for pipes, by the Newton-Raphson approximation, is shown below.
def manningTub(depth, args):
    Q = args[0]
    diamMM = args[1]
    nMann = args[2]
    slope = args[3]
    diamM = diamMM / 1000.0
    angle = 2*acos(1-2*depth/diamM)
    area = diamM*diamM/8.0*(angle-sin(angle))
    radius = diamM/4*(1-sin(angle)/angle)
    mannR = (Q*nMann/slope**0.5)-(area*radius**(2.0/3.0))
    return mannR

def solve(f, x0, h, args):
    lastX = x0
    nextX = lastX + 10* h  # "different than lastX so loop starts OK
    while (abs(lastX - nextX) > h):  # this is how you terminate the loop - note use of abs()
        newY = f(nextX,args)  # just for debug... see what happens
        print "f(", nextX, ") = ", newY     # print out progress... again just debug
        lastX = nextX
        nextX = lastX - newY / derivative(f, lastX, h, args)  # update estimate using N-R
    return nextX

def derivative(f, x, h, args):
      return (f(x+h,args) - f(x-h,args)) / (2.0*h)  # might want to return a small non-zero if ==0

#### EXAMPLE CALL

xFound = solve(manningTub, initDepth, 0.001, [flowRate,diam,nMann,enSlope])    # call the solver