@@ -579,6 +579,40 @@ def IdzFun(q, n, B, m, Sb, Y0, L, shape):
579579
580580
581581class GetLinearSVVariables :
582+
583+ """
584+ Pre-compute steady-state and linearized shallow-water (Saint-Venant) variables
585+ for a 1D open-channel flow in a rectangular cross-section.
586+
587+ This helper class sets up arrays at staggered nodes (Q- and H-points) commonly
588+ used in finite-difference schemes for open-channel hydraulics. Given nominal
589+ flow and geometry along the reach, it computes:
590+ - Geometric arrays (top width, area, wetted perimeter, hydraulic radius),
591+ - Kinematic/dynamic arrays (velocity, Froude number, friction slope),
592+ - Auxiliary coefficients (delta, kappa, f2, gamma) used in linearized models.
593+
594+ **Grid and staggering**
595+ - There are `n_level_nodes` water-level (H) nodes along the reach (including
596+ both ends). Discharge (Q) points are located in a staggered manner, resulting
597+ in `2*n_level_nodes - 1` interlaced positions for mixed variables.
598+ - Spatial step: `dx = length / (n_level_nodes - 1)`
599+
600+ **Assumptions**
601+ - Rectangular channel cross-section with constant top width `width` along x.
602+ - Linearly varying nominal depth from downstream (`y_nominal_down`) to upstream
603+ (`y_nominal`), constructed via `np.linspace`.
604+ - Uniform nominal discharge `q_nominal` (replicated across Q-points).
605+ - Hydrostatic pressure distribution and 1D Saint-Venant framework.
606+ - Friction modeled via a Chezy/Manning-like term condensed into
607+ `friction_coefficient` (dimensionless here; ensure consistency with your model).
608+ - Gravitational acceleration is fixed to `g = 9.80665 m/s²`.
609+
610+ **Units (recommended)**
611+ - length, h_b_up, h_b_down, y_nominal, y_nominal_down, width : meters [m]
612+ - q_nominal : cubic meters per second [m³/s]
613+ - friction_coefficient : dimensionless (model-dependent)
614+ """
615+
582616 def __init__ (
583617 self ,
584618 n_level_nodes = 4 ,
@@ -591,6 +625,39 @@ def __init__(
591625 y_nominal_down = 0 ,
592626 friction_coefficient = 0 ,
593627 ):
628+
629+ """
630+ Initialize channel and nominal-flow parameters.
631+
632+ Parameters
633+ ----------
634+ n_level_nodes : int, default=4
635+ Number of water level (H) nodes along the channel, including both ends.
636+ Must be >= 2 to form at least one segment.
637+ length : float, default=0.0
638+ Channel reach length [m].
639+ h_b_up : float, default=0.0
640+ Upstream bed elevation [m].
641+ h_b_down : float, default=0.0
642+ Downstream bed elevation [m].
643+ q_nominal : float, default=0.0
644+ Nominal discharge, assumed uniform across Q-points [m³/s].
645+ width : float, default=0.0
646+ Channel top width (rectangular section) [m].
647+ y_nominal : float, default=0.0
648+ Nominal *upstream* flow depth [m].
649+ y_nominal_down : float, default=0.0
650+ Nominal *downstream* flow depth [m].
651+ friction_coefficient : float, default=0.0
652+ Friction coefficient (dimensionless). Interpretation depends on your
653+ chosen friction law; ensure consistency across the model.
654+
655+ Notes
656+ -----
657+ This constructor only stores inputs. Call :meth:`getVariables` to compute
658+ all derived arrays.
659+ """
660+
594661 self .n_level_nodes = n_level_nodes
595662 self .length = length
596663 self .h_b_up = h_b_up
@@ -602,6 +669,82 @@ def __init__(
602669 self .friction_coefficient = friction_coefficient
603670
604671 def getVariables (self ):
672+
673+ """
674+ Compute and store all derived steady/linearized arrays in-place.
675+
676+ After calling this method, the following attributes are created:
677+
678+ Geometry / base fields
679+ ----------------------
680+ q0 : list[float], length n_level_nodes + 1
681+ Nominal discharge at Q-points (staggered), replicated from `q_nominal`.
682+ t0 : list[float], length n_level_nodes
683+ Channel top width at H-nodes (constant = `width` for rectangular).
684+ y0 : np.ndarray, length n_level_nodes
685+ Nominal water depth at H-nodes, linearly interpolated from
686+ downstream (`y_nominal_down`) to upstream (`y_nominal`).
687+ a0 : list[float], length n_level_nodes
688+ Wetted area at H-nodes. For rectangular section: `a0 = t0 * y0`.
689+ p0 : list[float], length n_level_nodes
690+ Wetted perimeter at H-nodes. Rectangular: `p0 = t0 + 2*y0`.
691+ r : list[float], length n_level_nodes
692+ Hydraulic radius at H-nodes: `r = a0 / p0`.
693+
694+ Kinematics / dynamics (staggered)
695+ ---------------------------------
696+ v0 : list[float], length 2*n_level_nodes - 1
697+ Velocity at staggered Q/H points. Computed via discharge and
698+ adjacent areas depending on the location (Q vs H points).
699+ sf : list[float], length 2*n_level_nodes - 1
700+ Friction slope at staggered points. Uses squared discharge and
701+ a composite term with area and hydraulic radius.
702+ c0 : list[float], length n_level_nodes + 1
703+ Gravity-wave celerity at Q-points (staggered): `c0 = sqrt(g * y)`.
704+ f0 : list[float], length 2*n_level_nodes - 1
705+ Local Froude number at staggered points: `f0 = v0 / c0` (interpolated
706+ where needed).
707+ dydx : list[float], length 2*n_level_nodes - 1
708+ Water-surface slope at staggered points from gradually-varied flow:
709+ `dydx = (s_b - sf) / (1 - f0^2)`, where `s_b` is bed slope.
710+
711+ Linearization auxiliaries
712+ -------------------------
713+ delta : list[float], length n_level_nodes + 1
714+ Array used in linearized momentum relations, coefficient of the
715+ discharge term; set to zeros if
716+ `q_nominal == 0` to avoid division by zero, otherwise computed from
717+ `v0`, `s_b`, and `dydx`.
718+ kappa : list[float], length n_level_nodes
719+ Coefficient derived from linearization for rectangular cross-sections:
720+ `kappa = 7/3 - (4*a0)/(3*t0*p0) * 2` (the final `* 2` reflects the
721+ PDE coefficient due to rectangular geometry).
722+ f2 : list[float], length n_level_nodes
723+ Froude number: `f2 = v0(H)^2 * t0 / (g * a0)`, where `v0(H)`
724+ is taken at the H-indexed staggered position (even index).
725+ gamma : list[float], length n_level_nodes
726+ Coefficient of the water level term, coming from the
727+ Froude-related contributions, and bed slope. Computed at H-nodes.
728+
729+ Notes
730+ -----
731+ - Gravitational acceleration is set to `g = 9.80665 m/s²`.
732+ - Bed slope: `s_b = (h_b_up - h_b_down) / length`.
733+ - Spatial step: `dx = length / (n_level_nodes - 1)`.
734+ - This function does not return a value; it populates instance attributes.
735+ - If `q_nominal == 0`, `delta` is set to a zero array (to prevent division
736+ by zero in `v0` terms).
737+ - The detailed description of this linearization of the Saint-Venant equations
738+ can be found in Litrico, X., & Fromion, V. (2009). Modeling and control of
739+ hydrosystems. London: Springer London.
740+
741+ Raises
742+ ------
743+ ZeroDivisionError
744+ If `length == 0` or `n_level_nodes < 2`, divisions by zero may occur.
745+ Ensure inputs are physically meaningful before calling.
746+ """
747+
605748 s_b = (self .h_b_up - self .h_b_down ) / self .length
606749 g_n = 9.80665
607750 dx = self .length / (self .n_level_nodes - 1 )
@@ -745,6 +888,38 @@ def getVariables(self):
745888
746889
747890class GetIDZVariables :
891+
892+ """
893+ Compute IDZ (Integrator Delay Zero) model variables for a 1D open‑channel flow
894+ segment, based on nominal discharge, geometry, slope, and friction.
895+
896+ This class wraps a call to an external function `IdzFun`, which performs
897+ the core IDZ hydraulic computations and returns:
898+
899+ - Linearized model coefficients: p11, p12, p21, p22
900+ - Upstream/Downstream amplification factors: Au, Ad
901+ - Travel times: tu_hat, td_hat
902+ - Additional geometric outputs: yn, x2 (not stored here)
903+
904+ The class stores the key IDZ coefficients and mean delay time.
905+
906+ **Intended use**
907+ ----------------
908+ Instantiate, then call :meth:`getVariables`:
909+
910+ >>> model = GetIDZVariables(length=5000, h_b_up=3, h_b_down=2,
911+ q_nominal=50, width=20, y_nominal=2,
912+ side_slope=2, friction_coefficient=0.03)
913+ >>> model.getVariables()
914+ >>> model.Delay_in_hour, model.p11, model.p12
915+
916+ Notes
917+ -----
918+ - The computation relies on the function `IdzFun`, which must be available
919+ in the current namespace.
920+ - This class stores only a subset of the results produced by `IdzFun`.
921+ """
922+
748923 def __init__ (
749924 self ,
750925 length = 0 ,
@@ -797,5 +972,3 @@ def getVariables(self):
797972 self .p22 = p22_inf_hat
798973
799974
800- # Test function
801- # res = IdzFun(2.7, 0.02, 7.0, 1.5, 0.0001, 2.1, 7000, 0)
0 commit comments