.. sectionauthor:: Yasuyuki SHIMIZU ################################################ 1D unsteady flow with constant width ################################################ Basic formulas ============================== The equation of motion and the equation for continuity for unsteady flow in a channel with a constant width and a triangular cross section are... .. math:: :label: d1_1 {{\partial h}\over{\partial t}} +{{\partial (uh)}\over{\partial x}} = 0 .. math:: :label: d1_2 {{\partial (uh)}\over{\partial t}} +{{\partial (u^2 h)}\over{\partial x}} = -gh{{\partial H}\over{\partial x}} + \cfrac{\partial}{\partial x} \left\{ \varepsilon \cfrac{\partial (uh)}{\partial x} \right\} -{{\tau_x}\over{\rho}} Where, :math:`t` is the time, :math:`x` is the distance in the flow direction, :math:`h` is the water depth, :math:`u` is the flow velocity, :math:`g` is the gravitational acceleration, :math:`H` is the water level, :math:`(=z_b+h)`, :math:`z_b` is the riverbed elevation, :math:`\varepsilon` is the eddy viscosity coefficient, :math:`\tau_x` is the riverbed shear force, and :math:`\rho` is the water density. The left side of Equation :eq:`d1_2` is expressed in a form called the “conservation form”. This makes the equation applicable to a water surface with a discontinuous profile. When the water surface has a continuous profile, this means that when and :math:`\displaystyle{{\partial h}\over{\partial x}}` and :math:`\displaystyle{{\partial u}\over{\partial x}}` are present, the left side of Equation :eq:`d1_2` is as follows. .. math:: :label: d1_3 u{{\partial h}\over{\partial t}} +h{{\partial u}\over{\partial t}} + u{{\partial(uh)}\over{\partial x}} +uh{{\partial u}\over{\partial x}} It is possible to develop the equation. Using the equation of continuity, Equation :eq:`d1_1`, Equation :eq:`d1_2` can be converted into the following equation. Note that the diffusion term is an approximation. .. math:: :label: d1_4 {{\partial u}\over{\partial t}} +u{{\partial u}\over{\partial x}} = -g{{\partial H}\over{\partial x}} + \varepsilon {{\partial^2 u}\over{\partial x^2}}-{{\tau_x}\over{\rho h}} The following explanations use this non-conservation form of Equation :eq:`d1_4` for the equation of motion. As a basis, a non-conservation form of the equation of motion cannot deal with discontinuous flow. However, it is known that the CIP method can deal with such a flow to some extent. This is probably because the 3D interpolation function deployed by the CIP method is able to address sudden points of change in the function to some extent. Preparation for applying the CIP method (the split method) ============================================================== To further simplify the discussion, we consider the case where the riverbed shear force (friction) is negligible and the viscosity is also negligible. The basic formulas are... .. math:: :label: ds_1 {{\partial h}\over{\partial t}} +{{\partial (uh)}\over{\partial x}} = 0 .. math:: :label: ds_2 {{\partial u}\over{\partial t}} +u{{\partial u}\over{\partial x}} = -g{{\partial H}\over{\partial x}} As you can see from the equations, the main difference is that, as in Equation :eq:`sr1`, before there was only one unknown variable, :math:`f`, but now there are two unknown variables, :math:`h` and :math:`u`. You can understand the calculation procedure intuitively from the time differential term. We calculate :math:`h` with Equation :eq:`ds_1`, and :math:`u` with Equation :eq:`ds_2`. A split method is applied to Equation :eq:`ds_2` as it is applied to Equation :eq:`sr1`. Therefore, the split is as follows. .. math:: :label: bunri_1 {{\partial u}\over{\partial t}} = -g \displaystyle{\left( {{\partial h}\over{\partial x}} + {{\partial z_b}\over{\partial x}} \right) } .. math:: :label: bunri_2 {{\partial u}\over{\partial t}}+u{{\partial u}\over{\partial x}} = 0 Note that the relationship of :math:`H=h+z_b` is applied. To calculate :math:`u^n \rightarrow u^{n+1}` by using Equation :eq:`ds_2`, place :math:`\widetilde{u}` in the middle, calculate :math:`u^n \rightarrow \widetilde{u}` with Equation :eq:`bunri_1`, and calculate :math:`\widetilde{u} \rightarrow u^{n+1}` with Equation :eq:`bunri_2`. Equation :eq:`bunri_1` includes :math:`h`. Therefore, when calculating Equation :eq:`bunri_1`, Equation :eq:`ds_1` must be satisfied at the same time. Therefore, let us express it as :math:`h^n \rightarrow \widetilde{h}`. However, Equation :eq:`bunri_2` does not include :math:`h`. Therefore, it is impossible to relate it to Equation :eq:`ds_1`. :math:`\widetilde{h}` is the simultaneous solution of Equation :eq:`ds_1` and Equation :eq:`bunri_1` and it is used “as is” for :math:`h^{n+1}`, as follows. .. math:: :label: bunri_3 h^{n+1}=\widetilde{h} The above is summarized in the table below. .. list-table:: Split method for 1D unsteady flow :align: center :header-rows: 1 * - Phase name - Updating :math:`u` and :math:`h` - Equation used * - **[A]** \ non-advection phase - :math:`u^n \rightarrow \widetilde{u}, h^n \rightarrow \widetilde{h}` - Equations :eq:`bunri_1` and :eq:`ds_1` * - **[B]** \ advection phase - :math:`\widetilde{u} \rightarrow u^{n+1}, \widetilde{h} \rightarrow h^{n+1}` - Equations :eq:`bunri_2` and :eq:`bunri_3` The non-advection phase ====================================== First, we calculate :math:`u^n \rightarrow \widetilde{u}` with Equation :eq:`bunri_1`. At the same time, we perform :math:`h^n \rightarrow \widetilde{h}` with Equation :eq:`ds_1`. Then, Equation :eq:`bunri_1` is expressed as follows. .. math:: :label: na_1 {{\widetilde{u}-u^n}\over{\Delta t}} = -g \displaystyle{ \left( {{\partial \widetilde{h}}\over{\partial x}} + {{\partial z_b}\over{\partial x}} \right) } Therefore, we obtain... .. math:: :label: na_2 \widetilde{u}= u^n - g \Delta t {{\partial \widetilde{h}}\over{\partial x}} - g \Delta t {{\partial z_b}\over{\partial x}} Meanwhile, because we obtain :math:`h^n \rightarrow \widetilde{h}` with Equation :eq:`ds_1`, the following equation should be satisfied. .. math:: :label: na_3 {{\widetilde{h}-h^n}\over{\Delta t}} + {{\partial}\over{\partial x}} (\widetilde{u} \widetilde{h} ) =0 Therefore, we need to obtain :math:`\widetilde{h}` and :math:`\widetilde{u}`, the simultaneous solutions to Equation :eq:`na_2` and Equation :eq:`na_3`. In general, when the CIP method is applied to the calculation of a fluid, we use a staggered grid in which the calculation points of :math:`u` and :math:`h` are alternately arranged. Here, let us deploy the arrangement of calculation points shown in :numref:`1d_stk` . .. _1d_stk: .. figure:: images/02/1d_stk.png :align: center :width: 80% : Staggered grids Taking into account this arrangement of calculation points, the difference expression of Equation :eq:`na_2` is... .. math:: :label: ns_1 \widetilde{u}(i) = u^n(i)-g\Delta t {{\widetilde{h}(i+1) - \widetilde{h}(i)}\over{\Delta x}} -g\Delta t {{z_b(i+1) - z_b(i)}\over{\Delta x}} (Here, we assume that the calculation points of :math:`z_b` are the same as those of :math:`h`.) To substitute this for the second term on the left side of Equation :eq:`na_3`, we introduce the unit width discharge, :math:`q`, that satisfies... .. math:: :label: ns_2 \widetilde{q}=\widetilde{u} \widetilde{h} (The calculation points of :math:`q` are the same as those of :math:`u`.) Considering the arrangement of grid points, we use the following equation, .. math:: :label: ns_3 \widetilde{q}(i)= \widetilde{u}(i) {{\widetilde{h}(i+1)+\widetilde{h}(i)}\over{2}} in addition to the following difference equation of Equation :eq:`na_3` that adopted :math:`q`.  .. math:: :label: ns_4 \widetilde{h}(i) = h^n(i) - \left[ \widetilde{q}(i)-\widetilde{q}(i-1) \right] {{\Delta t}\over{\Delta x}} Then, we obtain :math:`\widetilde{h}`. However, :math:`\widetilde{q}` in the right side of Equation :eq:`ns_4` also contain :math:`\widetilde{h}` in implicit form. As shown in :numref:`flowchart`, we need to repeat the calculations. .. _flowchart: .. figure:: images/02/flow_chart.png :align: center :width: 50% : The flow of calculation of :math:`\widetilde{h}(i)` and :math:`\widetilde{u}(i)` in the non-advection phase These repetitions of calculation give us :math:`\widetilde{h}(i)` and :math:`\widetilde{u}(i)`. They are the calculation results for the non-advection phase. Once, :math:`\widetilde{u}(i)` for the non-advection phase is obtained, then :math:`\displaystyle{\widetilde{{\partial u}\over{\partial x}}}` for the non-advection phase needs to be obtained. It can be obtained from the following equation, which is obtained by replacing :math:`f` with :math:`u` in Equation :eq:`na8`. .. math:: :label: ns_5 \widetilde{{\partial u}\over{\partial x}}(i)= {{\partial u}\over{\partial x}}^n(i)+{{1}\over{2\Delta x}} \left[ \widetilde{u}(i+1)-u^n(i+1)-\widetilde{u}(i-1)+u^n(i-1) \right] The advection phase ====================== In the advection phase, the CIP method can be applied directly to Equation :eq:`bunri_2`. By replacing :math:`f` with :math:`u` in Equation :eq:`ir1`, the following equation gives the solution. .. math:: :label: ns_6 {u(i)}^{n+1}=U(X)= \left[(aX+b)X+ \widetilde{{\partial u}\over{\partial x}}(i) \right] X +\widetilde{u}(i) Where, :math:`\widetilde{u}(i)` and :math:`\displaystyle{\widetilde{{\partial u}\over{\partial x}}(i)}` are :math:`u` and the spatial differentiation amounts of :math:`u` in the non-advection phase, respectively. :math:`\displaystyle{\widetilde{{\partial u}\over{\partial x}}(i)}` They are obtained from equations :eq:`ns_1` and :eq:`ns_5`, respectively. Also, :math:`a` and :math:`b` are given by Equation :eq:`ab` in the previous chapter, by replacing :math:`f` with :math:`u`. Therefore, using :math:`U(X)`, :math:`u` in the advection phase is... .. math:: :label: ns_8 u(i)^{n+1}= U(X) Similarly, the spatial differentiation amount of :math:`u` in the advection phase can be obtained from Equation :eq:`br_a4` and Equation :eq:`br_a6` by substituting :math:`f` with :math:`u` as follows. .. math:: :label: ns_9 \widehat{{\partial u}\over{\partial x}}(i) = 3aX^2 + 2bX + \widetilde{{\partial u}\over{\partial x}}(i) and .. math:: :label: ns_10 {{\partial u}\over{\partial x}}^{n+1}(i) = \widehat{{\partial u}\over{\partial x}}(i) -{{u(i+1)-u(i-1))}\over{2\Delta x}}\widehat{{\partial u}\over{\partial x}}(i) \Delta t Boundary conditions ================================== To use the CIP method for this calculation method, in addition to needing the boundary conditions of :math:`u` and :math:`h`, we also need the boundary conditions of :math:`\displaystyle{{\partial u}\over{\partial x}}`. Physical boundary conditions are required that are in line with the phenomenon that is subject to the calculation. The simplest condition is that for all variables, applying below. .. math:: :label: bc_1 {{\partial}\over{\partial x}} =0 This is a free boundary condition. The water level (water depth) must be selected according to the calculation conditions. The details are omitted, but the water level (water depth) boundary conditions at the downstream end can be given for ordinary flow, and those at the upstream end can be given for jet flow. Note that, of course, the boundary conditions must be applied to both the non-advection phase and the advection phase. Summary =============== The flowchart below summarizes the above calculations for the 1D flow with free water surface. .. _flowchart2: .. figure:: images/02/flow_chart2.png :width: 70% :align: center : Flow chart for the 1D flow calculation with free water surface The Python code =============================== An example of code for the above 1D unsteady flow calculation is below. https://github.com/YasuShimizu/1D-Free-Water-Surface Files in this GitHub folder with the extension “py” are the calculation files. Of these, “main.py” file is the main body of the calculation code. Of which, the following part can be used for water surface profile calculations under different conditions by sequentially activating the part of the code with the “yml” file name commented out. .. code-block:: python with open('config.yml','r', encoding='utf-8') as yml: #with open('config_jump.yml','r', encoding='utf-8') as yml: # hydraulic jump #with open('config_trans.yml','r', encoding='utf-8') as yml: # transitional flow #with open('config_back_water.yml','r', encoding='utf-8') as yml: # back water #with open('config_drop_down.yml','r', encoding='utf-8') as yml: # drawdown #with open('config_bump.yml','r', encoding='utf-8') as yml: # flow in a channel with a bump config = yaml.load(yml) The yml file describes the calculation conditions and is included on the above GitHub site. As an example, [config_trans.yml] is shown below. Calculations can be carried out while the conditions are changed by appropriately modifying the items in the comments. For simplicity, the explanation of the calculation method assumes that friction is negligible. In the code, however, a friction term is added to the equations of motion. By setting the coefficient of roughness to zero in the “yml” file, calculations ignoring friction can be performed. .. code-block:: python xl : 200 # channel length (m) nx: 51 # no. of grids in the x-direction j_channel: 2 # condition of the channel (1=constant gradient, 2=gradient changes) # when j_channel=1 slope: 0.002 # entire gradient # when j_channel=2 x_slope : 130 # gradient changing point slope1 : 0.001 # upstream gradient slope2 : 0.01 # downstream gradient xb1 : 4 # distance from the upstream end to the bump starting point (m) xb2 : 5 # distance from the upstream end to the bump crest (m) xb3 : 6 # distance from the upstream end to the bump ending point (m) dbed : 0.00 # bump height (m) qp : 1 # unit width discharge (m**2/2) g : 9.8 # gravitational acceleration snm : 0.025 # coefficient of roughness alh : 0.6 # relaxation factor for water level calculation lmax : 50 # max. replication number of water level calculation errmax : 0.0001 # truncation error hmin : 0.01 # min. water depth (m) j_upstm : 2 # condition of upstream end (1=wall, 2=free, 3=fixed value) j_dwstm : 3 # condition of the downstream end alpha_up: 1.0 # water depth at the upstream end (ratio over the neutral depth) alpha_dw: 1.0 # water depth at the downstream end (ratio over the neutral depth) etime : 400 # calculation end time (sec) dt : 0.05 # calculation time step (sec) tuk : 10 # output interval Regarding xb1, xb2, xb3 and dbed in [config_trans.yml], they are defined as shown in the following figure. .. _bed_cond: .. figure:: images/02/bed_cond.png :width: 80% :align: center : Parameter for setting the riverbed bump Calculation example ================================== Back water ---------------- Examples of calculation results using [config_back_water.yml] are below. The calculation results are from the top, longitudinal profiles of the water level (Water), the bed morphology (Bed), the velocity (Velocity), the unit width discharge (Discharge), and the Froude number (Fr). Equation :eq:`h0` gives the neutral depth, :math:`h_0`, and the critical water depth, :math:`h_c`. They are also shown with the longitudinal profiles of water level. .. math:: :label: h0 h_0=\left(\cfrac{q n}{\sqrt{i}}\right)^{3/5}, \ \ h_c=\left(\cfrac{q^2}{g}\right)^{1/3} .. _backw: .. figure:: images/02/back_water.gif :width: 80% :align: center : Calculating an example of back water The calculations of :numref:`backw` show how the effect of the water level being raised to 20% deeper than the isobath at the downstream end is transmitted upstream. Drawdown --------------- :numref:`drop` shows the the calculation results using [config_drop_down.yml]. In this example, we calculate the conditions of the drawdown whose boundary condition is the water depth at the downstream end being kept at 70% of the neutral depth. .. _drop: .. figure:: images/02/drop_down.gif :width: 80% :align: center : Examples of drawdown calculation Hydraulic jump ---------------------- :numref:`jump` shows the calculation results using [config_jump.yml]. In this example, the hydraulic jumps are calculated for a channel with a steep gradient at the upper reaches and a gentle gradient at the lower reaches. .. _jump: .. figure:: images/02/jump.gif :width: 80% :align: center : Examples of hydraulic jump calculation Transitional flow ----------------------- :numref:`trans1` shows the calculation results using [config_trans.yml]. In this example, the transition from ordinary flow to jet flow is calculated in a channel with a gentle gradient at the upstream end and a steep gradient at the downstream end. .. _trans1: .. figure:: images/02/trans.gif :width: 80% :align: center : Examples of transitional flow calculation Flow in a channel with a bump at the channel center ---------------------------------------------------------------- :numref:`bump` shows the calculation results using [config_bump.yml]. In this example, the flow is calculated for a channel with a bump at the longitudinal midpoint of the channel. Because this example is for ordinary flow, the water level is calculated to be less over the bump than elsewhere. (You studied this phenomena in your hydraulics class. Do you remember?) .. _bump: .. figure:: images/02/bump.gif :width: 80% :align: center : Calculation examples for flow in a channel with a bump at the longitudinal midpoint of the channel.