Source code for pyHMT2D.Hydraulic_Models_Data.Backwater_1D.Backwater_1D_Model


import numpy as np
from scipy import integrate

from pyHMT2D.Hydraulic_Models_Data import HydraulicModel

from pyHMT2D.__common__ import *

[docs] class Backwater_1D_Model(HydraulicModel): """Simple 1D backwater curve model . This model only works for subcritical flows!!! It does not work critical flows or transcritical flows. Attributes: """ def __init__(self): """SRH_2D_Model constructor Parameters ---------- """ HydraulicModel.__init__(self, "Backwater-1D", "1.0") #Backwater-1D case data (an object of Backater_1D_Data) self._backwater_1d_data = None #initialize the model self.init_model()
[docs] def init_model(self): """Initialize Backwater-1D model Returns ------- """ print("Initializing Backwater-1D ...")
[docs] def set_simulation_case(self, backwater_1d_data): """Set the simulation case to backwater_1D_data (if it has been created already) Parameters ---------- backwater_1d_data : Backwater_1D_Data an object from class Backwater_1D_Data, which should be created before calling Returns ------- """ self._backwater_1d_data = backwater_1d_data
[docs] def get_simulation_case(self): """Get the simulation case Returns ------- """ if not self._backwater_1d_data: raise Exception("Simulation case, i.e.,, the Backwater_1D_Data object, has not been set yet. Exiting ...") return self._backwater_1d_data
[docs] def run_model(self): """Run the Backwater-1D model It will run the current Backwater-1D case. Returns ------- """ if gVerbose: print("Running Backwater-1D ...") #check whether the case has been set up if not self._backwater_1d_data: raise Exception("Backwater-1D case has not been setup yet. Call set_simulation_case(...) first. Exiting ...") #solve the GVF ODE equation and save the results back into self._backwater_1d_data self._backwater_1d_data.normalDepth, \ self._backwater_1d_data.criticalDepth, \ self._backwater_1d_data.gridx, \ self._backwater_1d_data.waterDepth, \ self._backwater_1d_data.WSE, \ self._backwater_1d_data.gridManningN = \ self._ocf_1D_backwater_curve(self._backwater_1d_data.slope, self._backwater_1d_data.ManningNFunc, self._backwater_1d_data.startx, self._backwater_1d_data.startH, self._backwater_1d_data.startZ, self._backwater_1d_data.riverLength, self._backwater_1d_data.nGrid, self._backwater_1d_data.specificDischarge )
def _ocf_1D_backwater_curve(self, slope, ManningNFunc, startx, startH, startZ, riverLength, nGrid, specificDischarge): """ Open channel flow: 1D backwater curve in a wide, rectangular channel Parameters ---------- slope : float slope of channel ManningNFunc : interp1d Interpolation function for Manning's n startx : float starting x coordinate startH : float starting water depth H startZ : float starting bottom elevation riverLength : float length of river nGrid : int number of grid to be used specificDischarge : float specific discharge (discharge per unit width) Returns ------- normalDepth : float normal depth (only makes sense for uniform Manning's n) criticalDepth: float critical depth (only makes sense for uniform Manning's n) xcoords : numpy array x coordinates of the backwater curve profile waterDepth : numpy array water depth along the backwater curve profile WSE : numpy array water surface elevation (waterDepth + bottom elevation) """ # normal flow depth (only makes sense for uniform Manning's n value; # here we use the Manning's n at x = startx as a constant) const_ManningN = ManningNFunc(startx) normalDepth = (const_ManningN * specificDischarge / np.sqrt(slope)) ** (3.0 / 5.0) # critical flow depth criticalDepth = (specificDischarge ** 2 / 9.81) ** (1.0 / 3.0) #print("Hn, Hc = ", normalDepth, criticalDepth) x = np.linspace(startx, startx + riverLength, nGrid) #calculate Manning's n at grid points ManningN = ManningNFunc(x) #units system factor Kn = 1.486 if self._backwater_1d_data.units == "EN" else 1.0 waterDepth = integrate.odeint(self._F_H_backwater_curve, startH, x, args=(Kn, ManningNFunc, slope, specificDischarge)) waterDepth = waterDepth[:, 0] # convert the returned 2D array to a 1D array # negate the x-coordinate (go from downstream to upstream) # negX = -x # water surface elevation WSE = waterDepth + startZ + (x - startx) * slope return normalDepth, criticalDepth, x, waterDepth, WSE, ManningN def _F_H_backwater_curve(self, H, x, Kn, ManningNFunc, S, qw): """ F(H) function for the backwater curve equation (the right hand side) Parameters ---------- H: water depth x: x coordinate Kn: units system factor (1.486 for EN, 1.0 for SI) ManningNFunc: Interpolation function for Manning's n S: channel slope qw: specific discharge Returns ------- F(H) """ return -(S - qw ** 2 * (ManningNFunc(x) / Kn) ** 2 / (max(H, 0)) ** (10.0 / 3)) / \ (1 - qw ** 2 / 9.81 / (max(H, 0)) ** 3)