topmodel.c 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324
  1. #include <grass/gis.h>
  2. #include <grass/raster.h>
  3. #include "global.h"
  4. double get_lambda(void)
  5. {
  6. int i;
  7. double retval;
  8. retval = 0.0;
  9. for (i = 1; i < misc.nidxclass; i++)
  10. retval += idxstats.Aatb_r[i] *
  11. (idxstats.atb[i] + idxstats.atb[i - 1]) / 2.0;
  12. return retval;
  13. }
  14. void initialize(void)
  15. {
  16. int i, j, t;
  17. double A1, A2;
  18. misc.lambda = get_lambda();
  19. misc.lnTe = params.lnTe + log(input.dt);
  20. misc.vch = params.vch * input.dt;
  21. misc.vr = params.vr * input.dt;
  22. misc.qs0 = params.qs0 * input.dt;
  23. misc.qss = exp(misc.lnTe - misc.lambda);
  24. misc.tch = (double *)G_malloc(params.nch * sizeof(double));
  25. misc.tch[0] = params.d[0] / misc.vch;
  26. for (i = 1; i < params.nch; i++)
  27. misc.tch[i] = misc.tch[0] + (params.d[i] - params.d[0]) / misc.vr;
  28. misc.nreach = (int)misc.tch[params.nch - 1];
  29. if ((double)misc.nreach < misc.tch[params.nch - 1])
  30. misc.nreach++;
  31. misc.ndelay = (int)misc.tch[0];
  32. misc.nreach -= misc.ndelay;
  33. misc.Ad = (double *)G_malloc(misc.nreach * sizeof(double));
  34. for (i = 0; i < misc.nreach; i++) {
  35. t = misc.ndelay + i + 1;
  36. if (t > misc.tch[params.nch - 1]) {
  37. misc.Ad[i] = 1.0;
  38. }
  39. else {
  40. for (j = 1; j < params.nch; j++) {
  41. if (t <= misc.tch[j]) {
  42. misc.Ad[i] = params.Ad_r[j - 1] +
  43. (params.Ad_r[j] - params.Ad_r[j - 1]) *
  44. (t - misc.tch[j - 1]) /
  45. (misc.tch[j] - misc.tch[j - 1]);
  46. break;
  47. }
  48. }
  49. }
  50. }
  51. A1 = misc.Ad[0];
  52. misc.Ad[0] *= params.A;
  53. for (i = 1; i < misc.nreach; i++) {
  54. A2 = misc.Ad[i];
  55. misc.Ad[i] = A2 - A1;
  56. A1 = A2;
  57. misc.Ad[i] *= params.A;
  58. }
  59. misc.Srz = (double **)G_malloc(input.ntimestep * sizeof(double *));
  60. misc.Suz = (double **)G_malloc(input.ntimestep * sizeof(double *));
  61. for (i = 0; i < input.ntimestep; i++) {
  62. misc.Srz[i] = (double *)G_malloc(misc.nidxclass * sizeof(double));
  63. misc.Suz[i] = (double *)G_malloc(misc.nidxclass * sizeof(double));
  64. }
  65. for (i = 0; i < misc.nidxclass; i++) {
  66. misc.Srz[0][i] = params.Sr0;
  67. misc.Suz[0][i] = 0.0;
  68. }
  69. misc.S_mean = (double *)G_malloc(input.ntimestep * sizeof(double));
  70. misc.S_mean[0] = -params.m * log(misc.qs0 / misc.qss);
  71. misc.Qt = (double *)G_malloc(input.ntimestep * sizeof(double));
  72. for (i = 0; i < input.ntimestep; i++)
  73. misc.Qt[i] = 0.0;
  74. for (i = 0; i < misc.ndelay; i++)
  75. misc.Qt[i] = misc.qs0 * params.A;
  76. A1 = 0.0;
  77. for (i = 0; i < misc.nreach; i++) {
  78. A1 += misc.Ad[i];
  79. misc.Qt[misc.ndelay + i] = misc.qs0 * (params.A - A1);
  80. }
  81. return;
  82. }
  83. void implement(void)
  84. {
  85. int i, j, k;
  86. double Aatb_r;
  87. double R;
  88. double _qo, _qv;
  89. misc.S = (double **)G_malloc(input.ntimestep * sizeof(double *));
  90. misc.Ea = (double **)G_malloc(input.ntimestep * sizeof(double *));
  91. misc.ex = (double **)G_malloc(input.ntimestep * sizeof(double *));
  92. misc.qt = (double **)G_malloc(input.ntimestep * sizeof(double *));
  93. misc.qo = (double **)G_malloc(input.ntimestep * sizeof(double *));
  94. misc.qv = (double **)G_malloc(input.ntimestep * sizeof(double *));
  95. misc.qs = (double *)G_malloc(input.ntimestep * sizeof(double));
  96. misc.f = (double *)G_malloc(input.ntimestep * sizeof(double));
  97. misc.fex = (double *)G_malloc(input.ntimestep * sizeof(double));
  98. for (i = 0; i < input.ntimestep; i++) {
  99. misc.S[i] = (double *)G_malloc(misc.nidxclass * sizeof(double));
  100. misc.Ea[i] = (double *)G_malloc(misc.nidxclass * sizeof(double));
  101. misc.ex[i] = (double *)G_malloc(misc.nidxclass * sizeof(double));
  102. misc.qt[i] = (double *)G_malloc((misc.nidxclass + 1) *
  103. sizeof(double));
  104. misc.qo[i] = (double *)G_malloc((misc.nidxclass + 1) *
  105. sizeof(double));
  106. misc.qv[i] = (double *)G_malloc((misc.nidxclass + 1) *
  107. sizeof(double));
  108. misc.qt[i][misc.nidxclass] = 0.0;
  109. misc.qo[i][misc.nidxclass] = 0.0;
  110. misc.qv[i][misc.nidxclass] = 0.0;
  111. misc.qs[i] = 0.0;
  112. if (params.infex) {
  113. misc.f[i] = input.dt *
  114. get_f((i + 1) * input.dt, input.R[i] / input.dt);
  115. misc.fex[i] = input.R[i] - misc.f[i];
  116. R = misc.f[i];
  117. }
  118. else {
  119. misc.f[i] = 0.0;
  120. misc.fex[i] = 0.0;
  121. R = input.R[i];
  122. }
  123. if (i) {
  124. for (j = 0; j < misc.nidxclass; j++) {
  125. misc.Srz[i][j] = misc.Srz[i - 1][j];
  126. misc.Suz[i][j] = misc.Suz[i - 1][j];
  127. }
  128. }
  129. misc.qs[i] = misc.qss * exp(-misc.S_mean[i] / params.m);
  130. for (j = 0; j < misc.nidxclass; j++) {
  131. Aatb_r = (idxstats.Aatb_r[j] +
  132. (j < misc.nidxclass - 1 ? idxstats.Aatb_r[j + 1]
  133. : 0.0)) / 2.0;
  134. misc.S[i][j] = misc.S_mean[i] +
  135. params.m * (misc.lambda - idxstats.atb[j]);
  136. if (misc.S[i][j] < 0.0)
  137. misc.S[i][j] = 0.0;
  138. misc.Srz[i][j] -= R;
  139. if (misc.Srz[i][j] < 0.0) {
  140. misc.Suz[i][j] -= misc.Srz[i][j];
  141. misc.Srz[i][j] = 0.0;
  142. }
  143. misc.ex[i][j] = 0.0;
  144. if (misc.Suz[i][j] > misc.S[i][j]) {
  145. misc.ex[i][j] = misc.Suz[i][j] - misc.S[i][j];
  146. misc.Suz[i][j] = misc.S[i][j];
  147. }
  148. _qv = 0.0;
  149. if (misc.S[i][j] > 0.0) {
  150. _qv = (params.td > 0.0 ?
  151. misc.Suz[i][j] /
  152. (misc.S[i][j] * params.td) * input.dt
  153. : -params.td * params.K0 *
  154. exp(-misc.S[i][j] / params.m));
  155. if (_qv > misc.Suz[i][j])
  156. _qv = misc.Suz[i][j];
  157. misc.Suz[i][j] -= _qv;
  158. if (misc.Suz[i][j] < ZERO)
  159. misc.Suz[i][j] = 0.0;
  160. _qv *= Aatb_r;
  161. }
  162. misc.qv[i][j] = _qv;
  163. misc.qv[i][misc.nidxclass] += misc.qv[i][j];
  164. misc.Ea[i][j] = 0.0;
  165. if (input.Ep[i] > 0.0) {
  166. misc.Ea[i][j] = input.Ep[i] *
  167. (1 - misc.Srz[i][j] / params.Srmax);
  168. if (misc.Ea[i][j] > params.Srmax - misc.Srz[i][j])
  169. misc.Ea[i][j] = params.Srmax - misc.Srz[i][j];
  170. }
  171. misc.Srz[i][j] += misc.Ea[i][j];
  172. _qo = 0.0;
  173. if (j > 0) {
  174. if (misc.ex[i][j] > 0.0)
  175. _qo = idxstats.Aatb_r[j] *
  176. (misc.ex[i][j - 1] + misc.ex[i][j]) / 2.0;
  177. else if (misc.ex[i][j - 1] > 0.0)
  178. _qo = Aatb_r * misc.ex[i][j - 1] /
  179. (misc.ex[i][j - 1] -
  180. misc.ex[i][j]) * misc.ex[i][j - 1] / 2.0;
  181. }
  182. misc.qo[i][j] = _qo;
  183. misc.qo[i][misc.nidxclass] += misc.qo[i][j];
  184. misc.qt[i][j] = misc.qo[i][j] + misc.qs[i];
  185. }
  186. misc.qo[i][misc.nidxclass] += misc.fex[i];
  187. misc.qt[i][misc.nidxclass] = misc.qo[i][misc.nidxclass] + misc.qs[i];
  188. misc.S_mean[i] = misc.S_mean[i] +
  189. misc.qs[i] - misc.qv[i][misc.nidxclass];
  190. if (i + 1 < input.ntimestep)
  191. misc.S_mean[i + 1] = misc.S_mean[i];
  192. for (j = 0; j < misc.nreach; j++) {
  193. k = i + j + misc.ndelay;
  194. if (k > input.ntimestep - 1)
  195. break;
  196. misc.Qt[k] += misc.qt[i][misc.nidxclass] * misc.Ad[j];
  197. }
  198. }
  199. return;
  200. }
  201. /* Object function for hydrograph suggested by Servet and Dezetter(1991) */
  202. double get_Em(void)
  203. {
  204. int i;
  205. double Em, numerator, denominator;
  206. misc.Qobs_mean = 0.0;
  207. numerator = 0.0;
  208. for (i = 0; i < input.ntimestep; i++) {
  209. misc.Qobs_mean += misc.Qobs[i];
  210. numerator += pow(misc.Qobs[i] - misc.Qt[i], 2.0);
  211. }
  212. misc.Qobs_mean /= input.ntimestep;
  213. denominator = 0.0;
  214. for (i = 0; i < input.ntimestep; i++)
  215. denominator += pow(misc.Qobs[i] - misc.Qobs_mean, 2.0);
  216. if (denominator == 0.0) {
  217. G_warning("Em can not be resolved due to constant " "observed Q");
  218. Rast_set_d_null_value(&Em, 1);
  219. }
  220. else {
  221. Em = 1.0 - numerator / denominator;
  222. }
  223. return Em;
  224. }
  225. void others(void)
  226. {
  227. int i;
  228. misc.Qt_mean = 0.0;
  229. for (i = 0; i < input.ntimestep; i++) {
  230. misc.Qt_mean += misc.Qt[i];
  231. if (!i || misc.Qt_peak < misc.Qt[i]) {
  232. misc.Qt_peak = misc.Qt[i];
  233. misc.tt_peak = i + 1;
  234. }
  235. }
  236. misc.Qt_mean /= input.ntimestep;
  237. if (file.Qobs) {
  238. misc.Em = get_Em();
  239. for (i = 0; i < input.ntimestep; i++) {
  240. if (!i || misc.Qobs_peak < misc.Qobs[i]) {
  241. misc.Qobs_peak = misc.Qobs[i];
  242. misc.tobs_peak = i + 1;
  243. }
  244. }
  245. }
  246. return;
  247. }
  248. void topmodel(void)
  249. {
  250. initialize();
  251. implement();
  252. others();
  253. return;
  254. }