Code for Xinanjiang Model in C++ by OOP
从XinanjiangModel/Example中下载全部文件,按照示例修改输入文件,双击XAJ.exe即可运行输出流域出口断面流量过程Q.txt。
如果想对新安江模型的代码进行修改,可从XinanjiangModel/SourceCode中下载全部文件,包括头文件、源文件和工程文件,使用Visual Studio 2019打开工程文件,即可修改源码。
在学习了现代水文模拟及预报,并通过C++二级考试后,想尝试用面向对象的**重新编写三水源新安江模型。
初步思路是按流域分单元,蒸散发分层次,产流分水源,汇流分阶段把模型分成多个模型类。
参考文献:
[1]赵人俊.流域水文模型——新安江模型与陕北模型。北京:水利电力出版社,1983.
[2]包为民.水文预报,第5版,北京:**水利水电出版社,2017
[3]李致家.现代水文模拟与预报技术,南京:河海大学出版社,2010
[4]翟家瑞.常用水文预报算法和计算程序,郑州:黄河水利出版社,1995
今天听导师讲解了模型数据在类间传递的方法,采用类指针的方法,在各类间传递参数、状态等数据。要保证是始终一个数据流。还学习了从文本读入数据的方法。
把原来的各类分成单独的文件,更加清晰,方便复用。
和xl讨论自由水蓄水库三分水源问题,Q 是每个计算步长内的净雨量,mm。R 是总径流量,PE是单元流域降雨深度。
把R按5mm分,实际操作就是把PE按5mm分,是为了减小产流面积变化的差分误差。
自由水蓄水库只发生在产流面积上,其底宽为产流面积FR,显然FR是随时间变化的。
产流量R进入水库即在产流面积上产生PE的径流深。FR = f / F = R / PE。
编程参考《常用水文预报算法和计算程序》这本书。
今天就净雨量问题请教了大李老师,老师回答如下,纠正了我之前的想法,我之前理解成后者了,现在看来扣除雨期蒸发指的是流域的蒸发而不是土壤的蒸发。代码也做了相应修改。
Q:李老师好,向您请教一个问题,新安江模型中的净雨量PE是等于P-K*EM,还是等于P-(EU+EL+ED)?
我在赵人俊老师(《流域水文模拟—新安江模型与陕北模型》)、翟家瑞老师(《常用水文预报算法和计算程序》)和李致家老师(《现代水文模拟与预报技术》)的书里里看到的都是前者,
这两个数值相差还是挺大的,一般都是EU+EL+ED小于K*EM,这对后面计算产流量R和水源划分RS、RI、RG都有影响。想请老师解答下我的疑惑。
A:应该是前者。净雨,指的是降雨大于蒸发能力的部分。
今天把模型各个部分组装在了一起,但计算结果为负数,且有-nan(ind)。
导师讲解了调试方法:
- 使用C++自带函数_isnan()设置断点
- 将蒸散发、产流、汇流各模块分开输出结果调试
在调试中,我改正了如下错误:
- RIM不透水面积的产流计算应该判断PE是否小于0
- 头文件不能相互包含
经过调试,我发现深层张力水蓄量WD出现负数是导致结果为负数的原因,而这又是因为我没有将各单元流域的状态参数分开。因此
- 添加判断WD是否为负数的判断,为负数则置为0
- 创建各单元流域状态对象动态数组
发现马斯京根汇流没有分段考虑,于是修改了马斯京根汇流部分代码,实现分段汇流演算。
修改了程序中的可执行程序路径设置,现在将程序输入文件与XAJ.exe放在同一个目录下,即可运行输出Q.txt。
后续工作就是参数率定和灵敏度分析,这些都有自动优化分析的工具,如PEST++、dokata等。
在使用Dakota研究过程中,发现Q会出现NAN。
检查代码发现原来的PE < 0 条件过于严格,改为 PE < 1e-5,且添加FR > 1的判断。保证了PE略大于0时,FR不会大于1。