Python 建立流域三层蒸发和蓄满产流模型(二水源划分)

Python 建立流域三层蒸发和蓄满产流模型

  • 流域三层蒸发和蓄满产流简要
    • 三层蒸发模式
    • 蓄满产流量计算
    • 二水源划分
  • 编程前言
  • 代码
    • 含水量变化模型
    • 三层蒸发模型
    • 蓄满产流量模型
    • 二水源划分
  • 总结

流域三层蒸发和蓄满产流简要

依据蓄满产流模式计算流域径流量R,并将径流量R通过二水源划分法分为直接径流RD与地下径流RG,其中蒸发计算方法采用目前国内常用的三层蒸发模式。

三层蒸发模式

由于土壤含水率不宜直接用于水量平衡的产流量计算,常把蒸发与土壤含水率的关系转化为与土壤含水量的关系。三层蒸发模式按照先上层后下层的次序,具体分以下四种情况计算。

(1) 当 WU+P ≥ EP时:EU = EP,EL = 0,ED = 0
(2) 当 WU+P < EP,WL ≥ C * WLM时:EU = WU + P,EL = (EP - EU) * WL / WLM,ED = 0
(3) 当 WU+P < EP,C * (EP - EU) ≤ WL < C * WLM时:EU = WU + P,EL = (EP - EU) * C,ED = 0
(4) 当 WU+P < EP,WL < C * (EP - EU) 时:EU = WU + P,EL = WL,ED = C * (EP - EU) - EL
其中:P-降雨; WU, WL, WD-上、下、深层土壤含水量; WLM-下层土壤含水容量; EP-流域蒸发能力; C-蒸发扩散系数

蓄满产流量计算

蓄满产流是产流机制的一种概化。其基本假设为:任一地点上,土壤含水量达蓄满(即达田间持水量)前,降雨量全部补充土壤含水量,不产流;当土壤蓄满后,其后续降雨量全部产生径流。这种产流机制比较接近或符合土壤缺水量不大的湿润地区。
其计算公式如下

流域初始土湿 a = WMM * [1 - (1 - W/WM) ^ (1/(1+b))]
(1) 当 a + PE ≤ WMM时: R = PE + W - WM + WM * (1 - (PE + a) / WMM) ^ (1+b)
(2) 当 a + PE> WMM时: R = PE - WM + W
其中:b-常数; WMM-流域最大点土壤含水容量; PE-扣除蒸发量的降雨量; R-径流量; W-流域平均初始土壤含水量; WM-全流域平均土壤含水容量

二水源划分

流域坡地上的降雨产流量因产流过程的条件和运动路径不同,受流域的调蓄作用不同,各径流成分在流量过程线上的反应是不一样的。在实际工作中,常需按各种径流成分分别计算或模拟,因而要对产流量进行水源划分。本文采用二水源划分方法,计算公式如下。

产流面积比例 α = R / PE
(1) 当 PE > FC时,RG = α * FC,RD = α * (PE - FC)
(2) 当 PE ≤ FC时,RG = R,RD = 0
其中:FC-土壤下渗能力

编程前言

需要用到Pandas库,利用pandas.read_excel读取Excel数据并进行运算写回,详细见此。
代码主要参考:https://blog.csdn.net/Joyonlyonly/article/details/104843095,在对每一步进行详细的解释的同时,更改了如下几个导致运行错误的语法,确保代码能够如期地运行。

  1. A value is trying to be set on a copy of a slice from a DataFrame
    出现此条提示大多数是由于错误的使用了Pandas条件赋值语法
import pandas as pd
df=pd.read_excel(file_path)
# 错误示范
if df["A"][1] > 0:
    df["B"][1] = 1
# A value is trying to be set on a copy of a slice from a DataFrame

# 正确示范
if df["A"][1] > 0:
    df.loc[1,["B"]] = 1 # 需使用pandas库中loc或者iloc数据筛选函数
  1. IndexError: list index out of range
    出现此条错误主要有两个原因: (1)超出了list范围; (2)list为空,但使用了list[0] 。
# 超出list范围
list=[1,2,3]
print(list[5]) #报错

# list为空,但使用了list[0]
list=[]
print(list[0]) #报错

代码

将"WUM"、“WLM”、“WDM”、深层蒸散发系数"C"、抛物线型蓄水容量曲线指数"b"、“FC"作为已知值,且已知初始"WU”、“WL”、“WD”。
以下代码中的"i"为 for i in range(len(Excel文件)),即表示时刻。

含水量变化模型

i 时刻WU、WL、WD的变化与 i-1 时刻的WU、WL、WD、PE、R有关。需要注意的是若 PE - R > 0,那么降雨量会补充土壤缺水量,但不会超过土壤含水容量。

    if i == 0:
        #设置初始值
        df.loc[i,["WU"]] = "xx"
        df.loc[i,["WL"]] = "xx"
        df.loc[i,["WD"]] = "xx" # 设置初始值
    else:
        ifl = df["PE"][i-1] - df["R"][i-1] #上层蓄水量不为0,则只存在EU;且上层蓄水量与下渗的净降雨有关
        df.loc[i,["WU"]] = df["WU"][i-1] + ifl
        df.loc[i,["WL"]] = df["WL"][i-1] #假设扣除损失量后上层蓄水量仍大于或等于0,则中、深层蓄水量不会变化
        df.loc[i,["WD"]] = df["WD"][i-1]
        if df["WU"][i] < 0: #若上层蓄水量小于损失量
            df.loc[i,["WL"]] = df["WL"][i-1]+df["WU"][i] #则蒸发损失认为发生中层
            df.loc[i,["WU"]] = 0
            df.loc[i,["WD"]] = df["WD"][i-1] #假设扣除损失量后中层蓄水量仍大于或等于0,则深层蓄水量不会变化
            if df["WL"][i] < 0: #若中层蓄水量小于损失量
                df.loc[i,["WD"]] = df["WD"][i-1]+df["WL"][i] #则蒸发损失认为发生深层
                df.loc[i,["WL"]] = 0
                df.loc[i,["WU"]] = 0
                if df["WD"][i] < 0: #若深层蓄水量小于损失量
                    df.loc[i,["WD"]] = 0
                    df.loc[i,["WL"]] = 0
                    df.loc[i,["WU"]] = 0

        #设置蓄水量上限,不应超过蓄水容量
        if df["WU"][i] > WUM: #若扣除损失后入渗量足以补充上层蓄水容量,则多余的会逐层向下补充
            df.loc[i,["WL"]] = df["WU"][i] - WUM + df["WL"][i-1] #首先补充中层
            df.loc[i,["WU"]] = WUM
            df.loc[i,["WD"]] = df["WD"][i - 1]
            if df["WL"][i] > WLM: #若扣除损失后入渗量足以补充中层蓄水容量,则多余的会逐层向下补充
                df.loc[i,["WD"]] = df["WL"][i] - WLM + df["WD"][i-1] #补充深层
                df.loc[i,["WU"]] = WUM
                df.loc[i,["WL"]] = WLM
                if df["WD"][i] > WDM: #完全补充
                    df.loc[i,["WD"]] = WDM
                    df.loc[i,["WU"]] = WUM
                    df.loc[i,["WL"]] = WLM

三层蒸发模型

直接代码化三层蒸发模型公式即可。

#计算EU、EL、ED
    if df["WU"][i] + df["P"][i] >= df["EP"][i]:
        df.loc[i,["EU"]] = df["EP"][i]
        df.loc[i,["EL"]] = 0
        df.loc[i,["ED"]] = 0
    if df["WU"][i] + df["P"][i] < df["EP"][i] and df["WL"][i] >= C * WLM:
        df.loc[i,["EU"]] = df["WU"][i] + df["P"][i]
        df.loc[i,["EL"]] = (df["EP"][i] - df["EU"][i]) * (df["WL"][i] / WLM)
        df.loc[i,["ED"]] = 0
    if df["WU"][i] + df["P"][i] < df["EP"][i] and C * (df["EP"][i] - df["EU"][i]) <= df["WL"][i] and df["WL"][
        i] < C * WLM:
        df.loc[i,["EU"]] = df["WU"][i] + df["P"][i]
        df.loc[i,["EL"]] = C * (df["EP"][i] - df["EU"][i])
        df.loc[i,["ED"]] = 0
    if df["WU"][i] + df["P"][i] < df["EP"][i] and df["WL"][i] < C * (df["EP"][i] - df["EU"][i]):
        df.loc[i,["EU"]] = df["WU"][i] + df["P"][i]
        df.loc[i,["EL"]] = df["WL"][i]
        df.loc[i,["ED"]] = C * (df["EP"][i] - df["EU"][i]) - df["EL"][i]

蓄满产流量模型

在计算径流量之前,需要先计算出"E"、“PE”、"W"的值作为基础。

    df.loc[i,["E"]] = df["EU"][i] + df["EL"][i] + df["ED"][i]
    df.loc[i,["PE"]] = df["P"][i] - df["E"][i]
    df.loc[i,["W"]] = df["WU"][i]+df["WL"][i]+df["WD"][i]

再根据公式计算径流量R:

#计算径流量R
    a = WMM*(1 - math.pow((1 - df["W"][i]/WM),(1/(1+b))))
    if a + df["PE"][i] <= WMM:
        df.loc[i,["R"]] = df["PE"][i] + df["W"][i] - WM + WM*math.pow((1-(df["PE"][i] + a)/WMM),(b+1))
    else:
        df.loc[i,["R"]] = df["PE"][i] - (WM - df["W"][i])
    if df["R"][i] < 0: #避免负值出现
        df.loc[i,["R"]] = 0

二水源划分

直接代码化公式即可。

#分水源计算
    if df["R"][i] > 0:
        df.loc[i,["R/PE"]] = (df["R"][i]) / (df["PE"][i])
        if df["PE"][i] > FC:
            df.loc[i, ["RG"]] = df["R/PE"][i] * FC
            df.loc[i, ["RD"]] = df["R/PE"][i] * (df["PE"][i]-FC)
        else:
            df.loc[i, ["RG"]] = df["R"][i]
            df.loc[i, ["RD"]] = 0

总结

只要掌握了其中的逻辑关系便可容易地建立模型。笔者能力有限,采用最直白的代码进行编程,欢迎大佬对代码进行优化。此外,若有错误,还请多多包涵。

你可能感兴趣的:(Hydrology,python,pandas)