Example #1
0
def right_boundary(linkp, pn, H0, V0, H, V, links1, p, pump, valve, dt, H10,
                   V10, utype, dtype):
    """MOC solution for an individual right boundary pipe.

    Parameters
    ----------
    linkp : object
        Current pipe object
    pn : int
        Current pipe ID
    H : numpy.ndarray
        Head of current pipe at current time step [m]
    V : numpy.ndarray
        Velocity of current pipe at current time step [m/s]
    links1 : list
        Upstream adjacent pipes
    p : list
        pipe list
    pump : list
        Characteristics of the pump
    valve : list
        Characteristics of the valve
    n : int
        Number of discretization of current pipe
    dt : float
        Time step
    H0 : numpy.ndarray
        Head of current pipe at previous time step [m]
    V0 : numpy.ndarray
        Velocity of current pipe at previous time step [m/s]
    H10 : list
        Head of left adjacent nodes at previous time step [m]
    V10 : list
        Velocity of left adjacent nodes at previous time step [m/s]
    utype : list
        Upstream adjacent link type, and if not pipe, their name
    dtype : list
        Downstream adjacent link type, and if not pipe, their name

    Returns
    -------
    H : numpy.ndarray
        Head results of the current pipe at current time step. [m]
    V : numpy.ndarray
        Velocity results of the current pipe at current time step. [m/s]
    """

    # Properties of current pipe
    link1 = [p[abs(i) - 1] for i in links1]
    f = linkp.roughness  # unitless
    D = linkp.diameter  # m
    g = 9.8  # m/s^2
    a = linkp.wavev  # m/s
    n = linkp.number_of_segments  # spatial discretization

    for i in range(n + 1):
        # Pipe start (inner boundary conditions)
        if i == 0:
            V1 = V10
            H1 = H10  # upstream node
            V2 = V0[i + 1]
            H2 = H0[i + 1]  # downstream node
            if utype[0] == 'Pipe':
                elev = linkp.start_node.elevation
                emitter_coeff = linkp.start_node.emitter_coeff + linkp.start_node.demand_coeff
                H[i], V[i] = add_leakage(emitter_coeff, link1, linkp, elev,
                                         H1, V1, H2, V2, dt, g, i,
                                         np.sign(links1), [-1])

            elif utype[0] == 'Pump':
                pumpc = pump[0]
                H[i], V[i] = pump_node(pumpc, link1, linkp, H1, V1, H2, V2, dt,
                                       g, i, np.sign(links1), [-1])
            elif utype[0] == 'Valve':
                valvec = valve[0]
                H[i], V[i] = valve_node(valvec, link1, linkp, H1, V1, H2, V2,
                                        dt, g, i, np.sign(links1), [-1])

        # Pipe end (outer boundary conditions )
        if i == n:
            V1 = V0[i - 1]
            H1 = H0[i - 1]
            if dtype[0] == 'Reservoir' or dtype[0] == 'Tank':
                H[i], V[i] = rev_end(H1, V1, H[i], i, a, g, f, D, dt)
            if dtype[0] == 'Valve':
                H[i], V[i] = valve_end(H1, V1, V[i], i, a, g, f, D, dt)
            if dtype[0] == 'Junction':
                H[i], V[i] = dead_end(linkp, H1, V1, i, a, g, f, D, dt)

        # Interior points
        if (i > 0) and (i < n):
            V1 = V0[i - 1]
            H1 = H0[i - 1]
            V2 = V0[i + 1]
            H2 = H0[i + 1]

            H[i], V[i] = inner_node(linkp, linkp, 0, H1, V1, H2, V2, dt, g, i,
                                    [1], [-1])

    return H, V
Example #2
0
def right_boundary(linkp, pn, H0, V0, H, V, links1, p, pump, valve, dt,
                 H10, V10, utype, dtype,
                 friction, dVdt, dVdx, dVdt10, dVdx10):
    """MOC solution for an individual right boundary pipe.

    Parameters
    ----------
    linkp : object
        Current pipe object
    pn : int
        Current pipe ID
    H : numpy.ndarray
        Head of current pipe at current time step [m]
    V : numpy.ndarray
        Velocity of current pipe at current time step [m/s]
    links1 : list
        Upstream adjacent pipes
    p : list
        pipe list
    pump : list
        Characteristics of the pump
    valve : list
        Characteristics of the valve
    n : int
        Number of discretization of current pipe
    dt : float
        Time step
    H0 : numpy.ndarray
        Head of current pipe at previous time step [m]
    V0 : numpy.ndarray
        Velocity of current pipe at previous time step [m/s]
    H10 : list
        Head of left adjacent nodes at previous time step [m]
    V10 : list
        Velocity of left adjacent nodes at previous time step [m/s]
    utype : list
        Upstream adjacent link type, and if not pipe, their name
    dtype : list
        Downstream adjacent link type, and if not pipe, their name
    friction: str
        friction model, e.g., 'steady', 'quasi-steady', 'unsteady',
        by default 'steady'
    dVdt: numpy.ndarray
        local instantaneous velocity approximation to be used
        for unsteady friction calculation, 0 if not
        in unsteady friction mode [m/s^2]
    dVdx: numpy.ndarray
        convective instantaneous velocity approximation to be used
        for unsteady friction calculation, 0 if not
        in unsteady friction mode [m/s^2]
    dVdt10 : list
        local instantaneous acceleration of left adjacent nodes at previous time step [m]
    dVdx10 : list
        convective instantaneous acceleration of left adjacent nodes at previous time step [m/s]

   Returns
    -------
    H : numpy.ndarray
        Head results of the current pipe at current time step. [m]
    V : numpy.ndarray
        Velocity results of the current pipe at current time step. [m/s]
    """

    # Properties of current pipe
    link1 = [p[abs(i)-1] for i in links1]
    f = linkp.roughness              # unitless
    D = linkp.diameter               # m
    g = 9.8                          # m/s^2
    a = linkp.wavev                  # m/s
    n = linkp.number_of_segments   # spatial discretization
    KD = linkp.roughness_height

    # inner nodes
    if friction == 'steady':
        H[1:-1], V[1:-1] = inner_node_steady(linkp, H0, V0, dt, g)
    elif friction == 'quasi-steady':
        H[1:-1], V[1:-1] = inner_node_quasisteady(linkp, H0, V0, dt, g)
    else:
        H[1:-1], V[1:-1] = inner_node_unsteady(linkp, H0, V0, dt, g,
             dVdx, dVdt)

    # Pipe start (inner boundary conditions)
    V1 = V10; H1 = H10            # upstream node
    V2 = V0[1]; H2 = H0[1]    # downstream node
    dVdx1 = dVdx10 ; dVdx2 = dVdx[0]
    dVdt1 = dVdt10 ; dVdt2 = dVdt[1]
    if utype[0] == 'Pipe':
        if linkp.start_node.transient_node_type == 'SurgeTank':
            shape = linkp.start_node.tank_shape
            H[0], V[0], Qs = surge_tank(shape, link1, linkp,
                H1, V1, H2, V2, dt, g, 0,  np.sign(links1), [-1],
                friction, dVdx1, dVdx2, dVdt1, dVdt2)
            linkp.start_node.water_level = H[0]
            linkp.start_node.tank_flow = Qs
        if linkp.start_node.transient_node_type == 'Chamber':
            shape = linkp.start_node.tank_shape
            H[0], V[0], Qs, zp = air_chamber(shape, link1, linkp,
                H1, V1, H2, V2, dt, g, 0,  np.sign(links1), [-1],
                friction, dVdx1, dVdx2, dVdt1, dVdt2)
            linkp.start_node.water_level = zp
            linkp.start_node.tank_flow = Qs

        else:
            elev = linkp.start_node.elevation
            emitter_coeff = linkp.start_node.emitter_coeff + linkp.start_node.demand_coeff
            block_per =  linkp.start_node.block_per
            H[0], V[0] = add_leakage(emitter_coeff, block_per,link1, linkp, elev,
                H1, V1, H2, V2, dt, g, 0, np.sign(links1), [-1],
                friction, dVdx1, dVdx2, dVdt1, dVdt2)

    elif utype[0] == 'Pump':
        pumpc = pump[0]
        H[0], V[0] = pump_node(pumpc, link1, linkp,
                H1, V1, H2, V2, dt, g, 0,  np.sign(links1), [-1],
                friction, dVdx1, dVdx2, dVdt1, dVdt2)
    elif utype[0] == 'Valve':
        valvec = valve[0]
        H[0], V[0] = valve_node(valvec, link1, linkp,
                H1, V1, H2, V2, dt, g, 0,  np.sign(links1), [-1],
                friction, dVdx1, dVdx2, dVdt1, dVdt2)

    # Pipe end (outer boundary conditions )
    V1 = V0[n-1]; H1 = H0[n-1]
    dVdx1 = dVdx[n-1]
    dVdt1 = dVdt[n-1]
    if dtype[0] == 'Reservoir' or  dtype[0] == 'Tank':
        H[n], V[n] = rev_end (H1, V1, H[n], n, a, g, f, D, dt,
                            KD, friction, dVdx1, dVdt1)
    if  dtype[0] == 'Valve':
        H[n], V[n] = valve_end (H1, V1, V[n], n, a, g, f, D, dt,
                        KD, friction, dVdx1, dVdt1)
    if dtype[0] == 'Junction':
        elev = linkp.end_node.elevation
        H[n], V[n] = dead_end (linkp ,H1, V1, elev, n, a, g, f, D, dt,
                    KD, friction, dVdx1, dVdt1)


    return H, V