file_io.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403
  1. #include <grass/gis.h>
  2. #include <grass/raster.h>
  3. #include "global.h"
  4. void get_line(FILE * fp, char *buffer)
  5. {
  6. char *str;
  7. buffer[0] = 0;
  8. fscanf(fp, "%[^\n]", buffer);
  9. getc(fp);
  10. if ((str = (char *)strchr(buffer, '#')))
  11. *str = 0;
  12. return;
  13. }
  14. void read_inputs(void)
  15. {
  16. char buf[1024];
  17. FILE *fp;
  18. int i, j;
  19. double x;
  20. /* Read topographic index statistics file */
  21. fp = fopen(file.idxstats, "r");
  22. idxstats.atb = (double *)G_malloc(misc.nidxclass * sizeof(double));
  23. idxstats.Aatb_r = (double *)G_malloc(misc.nidxclass * sizeof(double));
  24. misc.ncell = 0;
  25. for (i = 0; i < misc.nidxclass && !feof(fp);) {
  26. get_line(fp, buf);
  27. if (sscanf(buf, "%lf %lf",
  28. &(idxstats.atb[i]), &(idxstats.Aatb_r[i])) == 2)
  29. misc.ncell += (int)idxstats.Aatb_r[i++];
  30. }
  31. misc.nidxclass = i;
  32. fclose(fp);
  33. for (i = 0; i < misc.nidxclass; i++)
  34. idxstats.Aatb_r[i] /= (double)misc.ncell;
  35. for (i = 0; i < misc.nidxclass; i++) {
  36. for (j = i; j < misc.nidxclass; j++) {
  37. if (idxstats.atb[i] < idxstats.atb[j]) {
  38. x = idxstats.atb[i];
  39. idxstats.atb[i] = idxstats.atb[j];
  40. idxstats.atb[j] = x;
  41. x = idxstats.Aatb_r[i];
  42. idxstats.Aatb_r[i] = idxstats.Aatb_r[j];
  43. idxstats.Aatb_r[j] = x;
  44. }
  45. }
  46. }
  47. /* Read parameters file */
  48. fp = fopen(file.params, "r");
  49. for (; !feof(fp);) {
  50. get_line(fp, buf);
  51. i = strlen(buf) - 1;
  52. for (; i >= 0; i--) {
  53. if (buf[i] != ' ' && buf[i] != '\t') {
  54. buf[i + 1] = 0;
  55. break;
  56. }
  57. }
  58. if (i >= 0)
  59. break;
  60. }
  61. params.name = G_store(buf);
  62. for (; !feof(fp);) {
  63. get_line(fp, buf);
  64. if (sscanf(buf, "%lf", &(params.A)) == 1)
  65. break;
  66. }
  67. for (; !feof(fp);) {
  68. get_line(fp, buf);
  69. if (sscanf(buf, "%lf %lf %lf %lf %lf %lf %lf %lf",
  70. &(params.qs0), &(params.lnTe),
  71. &(params.m), &(params.Sr0),
  72. &(params.Srmax), &(params.td),
  73. &(params.vch), &(params.vr)) == 8)
  74. break;
  75. }
  76. if (params.qs0 == 0.0) {
  77. fclose(fp);
  78. G_fatal_error("parameters.qs0 can not be 0.0");
  79. exit(EXIT_FAILURE);
  80. }
  81. for (; !feof(fp);) {
  82. get_line(fp, buf);
  83. if (sscanf(buf, "%d %lf %lf %lf",
  84. &(params.infex), &(params.K0),
  85. &(params.psi), &(params.dtheta)) == 4)
  86. break;
  87. }
  88. for (; !feof(fp);) {
  89. get_line(fp, buf);
  90. if (sscanf(buf, "%d", &(params.nch)) == 1)
  91. break;
  92. }
  93. params.d = (double *)G_malloc(params.nch * sizeof(double));
  94. params.Ad_r = (double *)G_malloc(params.nch * sizeof(double));
  95. for (i = 0; i < params.nch && !feof(fp);) {
  96. get_line(fp, buf);
  97. if (sscanf(buf, "%lf %lf", &(params.d[i]), &(params.Ad_r[i])) == 2)
  98. i++;
  99. }
  100. params.nch = i;
  101. fclose(fp);
  102. /* Read input file */
  103. fp = fopen(file.input, "r");
  104. for (; !feof(fp);) {
  105. get_line(fp, buf);
  106. if (sscanf(buf, "%d %lf", &(input.ntimestep), &(input.dt)) == 2)
  107. break;
  108. }
  109. input.R = (double *)G_malloc(input.ntimestep * sizeof(double));
  110. input.Ep = (double *)G_malloc(input.ntimestep * sizeof(double));
  111. for (i = 0; i < input.ntimestep && !feof(fp);) {
  112. get_line(fp, buf);
  113. if (sscanf(buf, "%lf %lf", &(input.R[i]), &(input.Ep[i])) == 2)
  114. i++;
  115. }
  116. input.ntimestep = i;
  117. fclose(fp);
  118. /* Read Qobs file */
  119. if (file.Qobs) {
  120. fp = fopen(file.Qobs, "r");
  121. misc.Qobs = (double *)G_malloc(input.ntimestep * sizeof(double));
  122. for (i = 0; i < input.ntimestep && !feof(fp);) {
  123. get_line(fp, buf);
  124. if (sscanf(buf, "%lf", &(misc.Qobs[i])) == 1)
  125. i++;
  126. }
  127. input.ntimestep = (input.ntimestep < i ? input.ntimestep : i);
  128. fclose(fp);
  129. }
  130. if (!(misc.timestep > 0 && misc.timestep < input.ntimestep + 1))
  131. misc.timestep = 0;
  132. if (!(misc.idxclass > 0 && misc.idxclass < misc.nidxclass + 1))
  133. misc.idxclass = 0;
  134. return;
  135. }
  136. void write_outputs(void)
  137. {
  138. FILE *fp;
  139. time_t tloc;
  140. struct tm *ltime;
  141. int st, et, si, ei;
  142. int i, j;
  143. time(&tloc);
  144. ltime = localtime(&tloc);
  145. ltime->tm_year += 1900;
  146. ltime->tm_mon++;
  147. fp = fopen(file.output, "w");
  148. fprintf(fp, "# r.topmodel output file for \"%s\"\n", params.name);
  149. fprintf(fp, "# Run time: %.4d-%.2d-%.2d %.2d:%.2d:%.2d\n",
  150. ltime->tm_year, ltime->tm_mon, ltime->tm_mday,
  151. ltime->tm_hour, ltime->tm_min, ltime->tm_sec);
  152. fprintf(fp, "#\n");
  153. if (file.Qobs) {
  154. fprintf(fp, "# %-15s Model efficiency\n", "Em:");
  155. fprintf(fp, "# %-15s Peak observed Q\n"
  156. "# %77s\n", "Qobs_peak:", "[m^3/timestep]");
  157. fprintf(fp, "# %-15s Peak time for observed Q\n"
  158. "# %77s\n", "tobs_peak:", "[timestep]");
  159. fprintf(fp, "# %-15s Mean observed Q\n"
  160. "# %77s\n", "Qobs_mean:", "[m^3/timestep]");
  161. }
  162. fprintf(fp, "# %-15s Peak simulated Q\n"
  163. "# %77s\n", "Qt_peak:", "[m^3/timestep]");
  164. fprintf(fp, "# %-15s Peak time for simulated Q\n"
  165. "# %77s\n", "tt_peak:", "[timestep]");
  166. fprintf(fp, "# %-15s Mean simulated Q\n"
  167. "# %77s\n", "Qt_mean:", "[m^3/timestep]");
  168. fprintf(fp, "# %-15s Number of non-NULL cells\n", "ncell:");
  169. fprintf(fp, "# %-15s Number of topographic index classes\n",
  170. "nidxclass:");
  171. fprintf(fp, "# %-15s Number of delay timesteps (delay time between "
  172. "rainfall and\n#\t\t\tflow response)\n", "ndelay:");
  173. fprintf(fp, "# %-15s Number of reach timesteps "
  174. "(time of concentration)\n", "nreach:");
  175. fprintf(fp, "# %-15s Areal average of ln(T0) = ln(Te)\n"
  176. "# %77s\n", "lnTe:", "[ln(m^2/timestep)]");
  177. fprintf(fp, "# %-15s Main channel routing velocity\n"
  178. "# %77s\n", "vch:", "[m/timestep]");
  179. fprintf(fp, "# %-15s Internal subcatchment routing velocity\n"
  180. "# %77s\n", "vr:", "[m/timestep]");
  181. fprintf(fp, "# %-15s Areal average of topographic index\n"
  182. "# %77s\n", "lambda:", "[ln(m^2)]");
  183. fprintf(fp, "# %-15s Subsurface flow per unit area at a soil surface\n"
  184. "# %77s\n", "qss:", "[m/timestep]");
  185. fprintf(fp, "# %-15s Initial subsurface flow per unit area\n"
  186. "# %77s\n", "qs0:", "[m/timestep]");
  187. fprintf(fp, "#\n");
  188. fprintf(fp, "# %-15s Routing timestep\n"
  189. "# %77s\n", "tch:", "[timestep]");
  190. fprintf(fp, "# %-15s Difference in contribution area for each reach "
  191. "timestep\n" "# %77s\n", "Ad:", "[m^2]");
  192. fprintf(fp, "# %-15s Total flow\n" "# %77s\n", "Qt:", "[m^3/timestep]");
  193. fprintf(fp, "# %-15s Total flow per unit area\n"
  194. "# %77s\n", "qt:", "[m/timestep]");
  195. fprintf(fp, "# %-15s Saturation overland flow per unit area\n"
  196. "# %77s\n", "qo:", "[m/timestep]");
  197. fprintf(fp, "# %-15s Subsurface flow per unit area\n"
  198. "# %77s\n", "qs:", "[m/timestep]");
  199. fprintf(fp, "# %-15s Vertical flux (or drainage flux)\n"
  200. "# %77s\n", "qv:", "[m/timestep]");
  201. fprintf(fp, "# %-15s Mean saturation deficit in the watershed\n"
  202. "# %77s\n", "S_mean:", "[m]");
  203. if (params.infex) {
  204. fprintf(fp, "# %-15s Infiltration rate\n"
  205. "# %30s\n", "f:", "[m/timestep]");
  206. fprintf(fp, "# %-15s Infiltration excess runoff\n"
  207. "# %77s\n", "fex:", "[m/timestep]");
  208. }
  209. if (misc.timestep || misc.idxclass) {
  210. fprintf(fp, "#\n");
  211. fprintf(fp, "# %-15s Root zone storage deficit\n"
  212. "# %77s\n", "Srz:", "[m]");
  213. fprintf(fp, "# %-15s Unsaturated (gravity drainage) zone "
  214. "storage\n" "# %77s\n", "Suz:", "[m]");
  215. fprintf(fp, "# %-15s Local saturated zone deficit due to "
  216. "gravity drainage\n" "# %77s\n", "S:", "[m]");
  217. fprintf(fp, "# %-15s Actual evapotranspiration\n"
  218. "# %77s\n", "Ea:", "[m/timestep]");
  219. fprintf(fp, "# %-15s Excess flow from a fully saturated "
  220. "area per unit area\n" "# %77s\n", "ex:", "[m/timestep]");
  221. }
  222. fprintf(fp, "\n");
  223. if (file.Qobs) {
  224. fprintf(fp, "%-10s ", "Em:");
  225. if (!Rast_is_d_null_value(&misc.Em))
  226. fprintf(fp, "%10.5lf\n", misc.Em);
  227. else
  228. fprintf(fp, "Not resolved due to constant observed Q\n");
  229. fprintf(fp, "%-10s %10.3le\n", "Qobs_peak:", misc.Qobs_peak);
  230. fprintf(fp, "%-10s %10d\n", "tobs_peak:", misc.tobs_peak);
  231. fprintf(fp, "%-10s %10.3le\n", "Qobs_mean:", misc.Qobs_mean);
  232. }
  233. fprintf(fp, "%-10s %10.3le\n", "Qt_peak:", misc.Qt_peak);
  234. fprintf(fp, "%-10s %10d\n", "tt_peak:", misc.tt_peak);
  235. fprintf(fp, "%-10s %10.3le\n", "Qt_mean:", misc.Qt_mean);
  236. fprintf(fp, "%-10s %10d\n", "ncell:", misc.ncell);
  237. fprintf(fp, "%-10s %10d\n", "nidxclass:", misc.nidxclass);
  238. fprintf(fp, "%-10s %10d\n", "ndelay:", misc.ndelay);
  239. fprintf(fp, "%-10s %10d\n", "nreach:", misc.nreach);
  240. fprintf(fp, "%-10s %10.3le\n", "lnTe:", misc.lnTe);
  241. fprintf(fp, "%-10s %10.3le\n", "vch:", misc.vch);
  242. fprintf(fp, "%-10s %10.3le\n", "vr:", misc.vr);
  243. fprintf(fp, "%-10s %10.3le\n", "lambda:", misc.lambda);
  244. fprintf(fp, "%-10s %10.3le\n", "qss:", misc.qss);
  245. fprintf(fp, "%-10s %10.3le\n", "qs0:", misc.qs0);
  246. fprintf(fp, "\n");
  247. fprintf(fp, "%10s\n", "tch");
  248. for (i = 0; i < params.nch; i++)
  249. fprintf(fp, "%10.3le\n", misc.tch[i]);
  250. fprintf(fp, "%10s\n", "Ad");
  251. for (i = 0; i < misc.nreach; i++)
  252. fprintf(fp, "%10.3le\n", misc.Ad[i]);
  253. st = et = si = ei = 0;
  254. if (misc.timestep || misc.idxclass) {
  255. if (misc.timestep) {
  256. st = misc.timestep - 1;
  257. et = misc.timestep;
  258. }
  259. else {
  260. st = 0;
  261. et = input.ntimestep;
  262. }
  263. if (misc.idxclass) {
  264. si = misc.idxclass - 1;
  265. ei = misc.idxclass;
  266. }
  267. else {
  268. si = 0;
  269. ei = misc.nidxclass;
  270. }
  271. }
  272. fprintf(fp, "%10s %10s %10s %10s %10s %10s %10s", "timestep", "Qt",
  273. "qt", "qo", "qs", "qv", "S_mean");
  274. if (params.infex)
  275. fprintf(fp, " %10s %10s", "f", "fex");
  276. fprintf(fp, "\n");
  277. for (i = 0; i < input.ntimestep; i++) {
  278. fprintf(fp, "%10d %10.3le %10.3le %10.3le %10.3le %10.3le "
  279. "%10.3le", i + 1, misc.Qt[i],
  280. misc.qt[i][misc.nidxclass],
  281. misc.qo[i][misc.nidxclass], misc.qs[i],
  282. misc.qv[i][misc.nidxclass], misc.S_mean[i]);
  283. if (params.infex)
  284. fprintf(fp, " %10.3le %10.3le", misc.f[i], misc.fex[i]);
  285. fprintf(fp, "\n");
  286. }
  287. if (misc.timestep || misc.idxclass) {
  288. fprintf(fp, "Given ");
  289. if (misc.timestep)
  290. fprintf(fp, "timestep: %5d", misc.timestep);
  291. if (misc.timestep && misc.idxclass)
  292. fprintf(fp, ", ");
  293. if (misc.idxclass)
  294. fprintf(fp, "idxclass: %5d", misc.idxclass);
  295. fprintf(fp, "\n");
  296. if (misc.timestep && !misc.idxclass) {
  297. fprintf(fp, "%10s ", "idxclass");
  298. }
  299. else if (misc.idxclass && !misc.timestep) {
  300. fprintf(fp, "%10s ", "timestep");
  301. }
  302. fprintf(fp, "%10s %10s %10s %10s %10s %10s %10s %10s %10s\n",
  303. "qt", "qo", "qs", "qv", "Srz", "Suz", "S", "Ea", "ex");
  304. for (i = st; i < et; i++)
  305. for (j = si; j < ei; j++) {
  306. if (misc.timestep && !misc.idxclass) {
  307. fprintf(fp, "%10d ", j + 1);
  308. }
  309. else if (misc.idxclass && !misc.timestep) {
  310. fprintf(fp, "%10d ", i + 1);
  311. }
  312. fprintf(fp, "%10.3le %10.3le %10.3le "
  313. "%10.3le %10.3le %10.3le "
  314. "%10.3le %10.3le %10.3le\n",
  315. misc.qt[i][j], misc.qo[i][j],
  316. misc.qs[i], misc.qv[i][j],
  317. misc.Srz[i][j], misc.Suz[i][j],
  318. misc.S[i][j], misc.Ea[i][j], misc.ex[i][j]);
  319. }
  320. }
  321. fclose(fp);
  322. return;
  323. }