hydro.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480
  1. /****************************************************************************
  2. *
  3. * MODULE: simwe library
  4. * AUTHOR(S): Helena Mitasova, Jaro Hofierka, Lubos Mitas:
  5. * PURPOSE: Hydrologic and sediment transport simulation (SIMWE)
  6. *
  7. * COPYRIGHT: (C) 2002 by the GRASS Development Team
  8. *
  9. * This program is free software under the GNU General Public
  10. * License (>=v2). Read the file COPYING that comes with GRASS
  11. * for details.
  12. *
  13. *****************************************************************************/
  14. /* hydro.c (simlib), 20.nov.2002, JH */
  15. #include <stdio.h>
  16. #include <stdlib.h>
  17. #include <math.h>
  18. #include <grass/gis.h>
  19. /* #include <grass/site.h> */
  20. #include <grass/bitmap.h>
  21. #include <grass/linkm.h>
  22. #include <grass/glocale.h>
  23. #include <grass/waterglobs.h>
  24. struct options parm;
  25. struct flags flag;
  26. /*
  27. * Soeren 8. Mar 2011 TODO:
  28. * Put all these global variables into several meaningful structures and
  29. * document use and purpose.
  30. *
  31. * Example:
  32. * Put all file descriptors into a input_files struct and rename the variables:
  33. * input_files.elev
  34. * input_files.dx
  35. * input_files.dy
  36. * input_files.drain
  37. * ...
  38. *
  39. */
  40. FILE *fdelevin, *fddxin, *fddyin, *fdrain, *fdinfil, *fdtraps,
  41. *fdmanin, *fddepth, *fddisch, *fderr;
  42. FILE *fdwdepth, *fddetin, *fdtranin, *fdtauin, *fdtc, *fdet, *fdconc,
  43. *fdflux, *fderdep;
  44. FILE *fdsfile, *fw;
  45. char *elevin;
  46. char *dxin;
  47. char *dyin;
  48. char *rain;
  49. char *infil;
  50. char *traps;
  51. char *manin;
  52. /* char *sfile; */
  53. char *depth;
  54. char *disch;
  55. char *err;
  56. char *outwalk;
  57. char *mapset;
  58. char *mscale;
  59. char *tserie;
  60. char *wdepth;
  61. char *detin;
  62. char *tranin;
  63. char *tauin;
  64. char *tc;
  65. char *et;
  66. char *conc;
  67. char *flux;
  68. char *erdep;
  69. char *rainval;
  70. char *maninval;
  71. char *infilval;
  72. struct seed seed;
  73. struct Cell_head cellhd;
  74. double xmin, ymin, xmax, ymax;
  75. double mayy, miyy, maxx, mixx;
  76. int mx, my;
  77. int mx2, my2;
  78. double bxmi, bymi, bxma, byma, bresx, bresy;
  79. int maxwab;
  80. double step, conv;
  81. double frac;
  82. double bxmi, bymi;
  83. float **zz, **cchez;
  84. double **v1, **v2, **slope;
  85. double **gama, **gammas, **si, **inf, **sigma;
  86. float **dc, **tau, **er, **ct, **trap;
  87. float **dif;
  88. double vavg[MAXW][2], stack[MAXW][3], w[MAXW][3];
  89. int iflag[MAXW];
  90. double hbeta;
  91. double hhmax, sisum, vmean;
  92. double infsum, infmean;
  93. int maxw, maxwa, nwalk;
  94. double rwalk, bresx, bresy, xrand, yrand;
  95. double stepx, stepy, xp0, yp0;
  96. double chmean, si0, deltap, deldif, cch, hhc, halpha;
  97. double eps;
  98. int maxwab, nstack;
  99. int iterout, mx2o, my2o;
  100. int miter, nwalka;
  101. double timec;
  102. int ts, timesec;
  103. double rain_val;
  104. double manin_val;
  105. double infil_val;
  106. struct History history; /* holds meta-data (title, comments,..) */
  107. /* **************************************************** */
  108. /* create walker representation of si */
  109. /* ******************************************************** */
  110. /* .......... iblock loop */
  111. void main_loop(void)
  112. {
  113. int i, ii, l, k;
  114. int icoub, nmult;
  115. int iw, iblock, lw;
  116. int itime, iter1;
  117. int nfiterh, nfiterw;
  118. int mgen, mgen2, mgen3;
  119. int nblock;
  120. int icfl;
  121. int mitfac;
  122. /* int mitfac, p; */
  123. double x, y;
  124. double velx, vely, stxm, stym;
  125. double factor, conn, gaux, gauy;
  126. double d1, addac, decr;
  127. double barea, sarea, walkwe;
  128. double gen, gen2, wei2, wei3, wei, weifac;
  129. float eff;
  130. nblock = 1;
  131. icoub = 0;
  132. icfl = 0;
  133. nstack = 0;
  134. if (maxwa > (MAXW - mx * my)) {
  135. mitfac = maxwa / (MAXW - mx * my);
  136. nblock = mitfac + 1;
  137. maxwa = maxwa / nblock;
  138. }
  139. G_debug(2, " maxwa, nblock %d %d", maxwa, nblock);
  140. for (iblock = 1; iblock <= nblock; iblock++) {
  141. ++icoub;
  142. lw = 0;
  143. walkwe = 0.;
  144. barea = stepx * stepy;
  145. sarea = bresx * bresy;
  146. G_debug(2, " barea,sarea,rwalk,sisum: %f %f %f %f", barea, sarea,
  147. rwalk, sisum);
  148. /* write hh.walkers0 */
  149. for (k = 0; k < my; k++) {
  150. for (l = 0; l < mx; l++) { /* run thru the whole area */
  151. if (zz[k][l] != UNDEF) {
  152. x = xp0 + stepx * (double)(l);
  153. y = yp0 + stepy * (double)(k);
  154. gen = rwalk * si[k][l] / sisum;
  155. mgen = (int)gen;
  156. wei = gen / (double)(mgen + 1);
  157. /*if (si[k][l] != 0.) { */
  158. /* this stuff later for multiscale */
  159. gen2 =
  160. (double)maxwab *si[k][l] / (si0 *
  161. (double)(mx2o * my2o));
  162. gen2 = gen2 * (barea / sarea);
  163. mgen2 = (int)gen2;
  164. wei2 = gen2 / (double)(mgen2 + 1);
  165. mgen3 =
  166. (int)((double)mgen2 * wei2 / ((double)mgen * wei));
  167. nmult = mgen3 + 1;
  168. wei3 = gen2 / (double)((mgen + 1) * (mgen2 + 1));
  169. weifac = wei3 / wei;
  170. /* } else {
  171. nmult = 1;
  172. weifac = 1.;
  173. fprintf(stderr, "\n zero rainfall excess in cell");
  174. } */
  175. /*G_debug(2, " gen,gen2,wei,wei2,mgen3,nmult: %f %f %f %f %d %d",gen,gen2,wei,wei2,mgen3,nmult);
  176. */
  177. for (iw = 1; iw <= mgen + 1; iw++) { /* assign walkers */
  178. ++lw;
  179. if (lw > MAXW)
  180. G_fatal_error(_("nwalk (%d) > maxw (%d)!"), lw, MAXW);
  181. w[lw][1] = x + stepx * (ulec() - 0.5);
  182. w[lw][2] = y + stepy * (ulec() - 0.5);
  183. w[lw][3] = wei;
  184. walkwe += w[lw][3];
  185. vavg[lw][1] = v1[k][l];
  186. vavg[lw][2] = v2[k][l];
  187. if (w[lw][1] >= xmin && w[lw][2] >= ymin &&
  188. w[lw][1] <= xmax && w[lw][2] <= ymax) {
  189. iflag[lw] = 0;
  190. }
  191. else {
  192. iflag[lw] = 1;
  193. }
  194. }
  195. } /*DEFined area */
  196. }
  197. }
  198. nwalk = lw;
  199. G_debug(2, " nwalk, maxw %d %d", nwalk, MAXW);
  200. G_debug(2, " walkwe (walk weight),frac %f %f", walkwe, frac);
  201. stxm = stepx * (double)(mx + 1) - xmin;
  202. stym = stepy * (double)(my + 1) - ymin;
  203. nwalka = 0;
  204. deldif = sqrt(deltap) * frac; /* diffuse factor */
  205. factor = deltap * sisum / (rwalk * (double)nblock);
  206. G_debug(2, " deldif,factor %f %e", deldif, factor);
  207. /* ********************************************************** */
  208. /* main loop over the projection time */
  209. /* *********************************************************** */
  210. G_debug(2, "main loop over the projection time... ");
  211. for (i = 1; i <= miter; i++) { /* iteration loop depending on simulation time and deltap */
  212. G_percent(i, miter, 1);
  213. iter1 = i / iterout;
  214. iter1 *= iterout;
  215. if (iter1 == i) {
  216. nfiterw = i / iterout + 10;
  217. nfiterh = i / iterout + 40;
  218. G_debug(2, "iblock=%d i=%d miter=%d nwalk=%d nwalka=%d",
  219. iblock, i, miter, nwalk, nwalka);
  220. }
  221. if (nwalka == 0 && i > 1)
  222. goto L_800;
  223. /* ************************************************************ */
  224. /* .... propagate one step */
  225. /* ************************************************************ */
  226. addac = factor;
  227. conn = (double)nblock / (double)iblock;
  228. if (i == 1) {
  229. addac = factor * .5;
  230. }
  231. nwalka = 0;
  232. nstack = 0;
  233. for (lw = 1; lw <= nwalk; lw++) {
  234. if (w[lw][3] > EPS) { /* check the walker weight */
  235. ++nwalka;
  236. l = (int)((w[lw][1] + stxm) / stepx) - mx - 1;
  237. k = (int)((w[lw][2] + stym) / stepy) - my - 1;
  238. if (l > mx - 1 || k > my - 1 || k < 0 || l < 0) {
  239. G_debug(2, " k,l=%d,%d", k, l);
  240. printf(" lw,w=%d %f %f", lw, w[lw][1], w[lw][2]);
  241. G_debug(2, " stxym=%f %f", stxm, stym);
  242. printf(" step=%f %f", stepx, stepy);
  243. G_debug(2, " m=%d %d", my, mx);
  244. printf(" nwalka,nwalk=%d %d", nwalka, nwalk);
  245. G_debug(2, " ");
  246. }
  247. if (zz[k][l] != UNDEF) {
  248. if (infil != NULL) { /* infiltration part */
  249. if (inf[k][l] - si[k][l] > 0.) {
  250. decr = pow(addac * w[lw][3], 3. / 5.); /* decreasing factor in m */
  251. if (inf[k][l] > decr) {
  252. inf[k][l] -= decr; /* decrease infilt. in cell and eliminate the walker */
  253. w[lw][3] = 0.;
  254. }
  255. else {
  256. w[lw][3] -= pow(inf[k][l], 5. / 3.) / addac; /* use just proportional part of the walker weight */
  257. inf[k][l] = 0.;
  258. }
  259. }
  260. }
  261. gama[k][l] += (addac * w[lw][3]); /* add walker weigh to water depth or conc. */
  262. d1 = gama[k][l] * conn;
  263. hhc = pow(d1, 3. / 5.);
  264. if (hhc > hhmax && wdepth == NULL) { /* increased diffusion if w.depth > hhmax */
  265. dif[k][l] = (halpha + 1) * deldif;
  266. velx = vavg[lw][1];
  267. vely = vavg[lw][2];
  268. }
  269. else {
  270. dif[k][l] = deldif;
  271. velx = v1[k][l];
  272. vely = v2[k][l];
  273. }
  274. if (traps != NULL && trap[k][l] != 0.) { /* traps */
  275. eff = ulec(); /* random generator */
  276. if (eff <= trap[k][l]) {
  277. velx = -0.1 * v1[k][l]; /* move it slightly back */
  278. vely = -0.1 * v2[k][l];
  279. }
  280. }
  281. gaux = gasdev();
  282. gauy = gasdev();
  283. w[lw][1] += (velx + dif[k][l] * gaux); /* move the walker */
  284. w[lw][2] += (vely + dif[k][l] * gauy);
  285. if (hhc > hhmax && wdepth == NULL) {
  286. vavg[lw][1] = hbeta * (vavg[lw][1] + v1[k][l]);
  287. vavg[lw][2] = hbeta * (vavg[lw][2] + v2[k][l]);
  288. }
  289. if (w[lw][1] <= xmin || w[lw][2] <= ymin || w[lw][1]
  290. >= xmax || w[lw][2] >= ymax) {
  291. w[lw][3] = 1e-10; /* eliminate walker if it is out of area */
  292. }
  293. else {
  294. if (wdepth != NULL) {
  295. l = (int)((w[lw][1] + stxm) / stepx) - mx - 1;
  296. k = (int)((w[lw][2] + stym) / stepy) - my - 1;
  297. w[lw][3] *= sigma[k][l];
  298. }
  299. } /* else */
  300. } /*DEFined area */
  301. else {
  302. w[lw][3] = 1e-10; /* eliminate walker if it is out of area */
  303. }
  304. }
  305. } /* lw loop */
  306. /* Changes made by Soeren 8. Mar 2011 to replace the site walker output implementation */
  307. /* Save all walkers located within the computational region and with valid
  308. z coordinates */
  309. if ((i == miter || i == iter1)) {
  310. nstack = 0;
  311. for (lw = 1; lw <= nwalk; lw++) {
  312. /* Compute the elevation raster map index */
  313. l = (int)((w[lw][1] + stxm) / stepx) - mx - 1;
  314. k = (int)((w[lw][2] + stym) / stepy) - my - 1;
  315. /* Check for correct elevation raster map index */
  316. if(l < 0 || l >= mx || k < 0 || k >= my)
  317. continue;
  318. if (w[lw][3] > EPS && zz[k][l] != UNDEF) {
  319. /* Save the 3d position of the walker */
  320. stack[nstack][1] = mixx / conv + w[lw][1] / conv;
  321. stack[nstack][2] = miyy / conv + w[lw][2] / conv;
  322. stack[nstack][3] = zz[k][l];
  323. nstack++;
  324. }
  325. }
  326. } /* lw loop */
  327. if (i == iter1 && ts == 1) {
  328. /* call output for iteration output */
  329. if (erdep != NULL)
  330. erod(gama); /* divergence of gama field */
  331. conn = (double)nblock / (double)iblock;
  332. itime = (int)(i * deltap * timec);
  333. ii = output_data(itime, conn);
  334. if (ii != 1)
  335. G_fatal_error(_("Unable to write raster maps"));
  336. }
  337. /* Soeren 8. Mar 2011 TODO:
  338. * This hould be replaced by vector functionality and sql database storage */
  339. /* ascii data site file output for gamma - hydrograph or sediment*/
  340. /* cchez incl. sqrt(sinsl) */
  341. /* sediment */
  342. /*defined area */
  343. /*
  344. if (sfile != NULL) {
  345. for (p = 0; p < npoints; p++) {
  346. l = (int)((points[p].east - mixx + stxm) / stepx) - mx -
  347. 1;
  348. k = (int)((points[p].north - miyy + stym) / stepy) - my -
  349. 1;
  350. if (zz[k][l] != UNDEF) {
  351. if (wdepth == NULL) {
  352. points[p].z1 = step * gama[k][l] * cchez[k][l];
  353. }
  354. else
  355. points[p].z1 = gama[k][l] * slope[k][l];
  356. G_debug(2, " k,l,z1 %d %d %f", k, l, points[p].z1);
  357. fprintf(fw, "%f %f %f\n", points[p].east / conv,
  358. points[p].north / conv, points[p].z1);
  359. }
  360. }
  361. }
  362. */
  363. } /* miter */
  364. L_800:
  365. /* Soeren 8. Mar 2011: Why is this commented out?*/
  366. /* if (iwrib != nblock) {
  367. icount = icoub / iwrib;
  368. if (icoub == (icount * iwrib)) {
  369. ++icfl;
  370. nflw = icfl + 50;
  371. conn = (double) nblock / (double) iblock;
  372. }
  373. } */
  374. if (err != NULL) {
  375. for (k = 0; k < my; k++) {
  376. for (l = 0; l < mx; l++) {
  377. if (zz[k][l] != UNDEF) {
  378. d1 = gama[k][l] * (double)conn;
  379. gammas[k][l] += pow(d1, 3. / 5.);
  380. } /* DEFined area */
  381. }
  382. }
  383. }
  384. if (erdep != NULL)
  385. erod(gama);
  386. }
  387. /* ........ end of iblock loop */
  388. }