input.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498
  1. /* input.c (simlib), 20.nov.2002, JH */
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <math.h>
  5. #include <grass/gis.h>
  6. #include <grass/glocale.h>
  7. #include <grass/linkm.h>
  8. #include <grass/gmath.h>
  9. #include <grass/waterglobs.h>
  10. /* Local prototypes for raster map reading and array allocation */
  11. static float ** read_float_raster_map(int rows, int cols, char *name, float unitconv);
  12. static double ** read_double_raster_map(int rows, int cols, char *name, double unitconv);
  13. static float ** create_float_matrix(int rows, int cols, float fill_value);
  14. static double ** create_double_matrix(int rows, int cols, double fill_value);
  15. static void copy_matrix_undef_double_to_float_values(int rows, int cols, double **source, float **target);
  16. static void copy_matrix_undef_float_values(int rows, int cols, float **source, float **target);
  17. /* ************************************************************** */
  18. /* GRASS input procedures, allocations */
  19. /* *************************************************************** */
  20. /*!
  21. * \brief allocate memory, read input rasters, assign UNDEF to NODATA
  22. *
  23. * \return int
  24. */
  25. /* ************************************************************************* */
  26. /* Read all input maps and input values into memory ************************ */
  27. int input_data(void)
  28. {
  29. int rows = my, cols = mx; /* my and mx are global variables */
  30. double unitconv = 0.0000002; /* mm/hr to m/s */
  31. int if_rain = 0;
  32. G_debug(1, "Running MAR 2011 version, started modifications on 20080211");
  33. G_debug(1, "Reading input data");
  34. /* Elevation and gradients are mandatory */
  35. zz = read_float_raster_map(rows, cols, elevin, 1.0);
  36. v1 = read_double_raster_map(rows, cols, dxin, 1.0);
  37. v2 = read_double_raster_map(rows, cols, dyin, 1.0);
  38. /* Update elevation map */
  39. copy_matrix_undef_double_to_float_values(rows, cols, v1, zz);
  40. copy_matrix_undef_double_to_float_values(rows, cols, v2, zz);
  41. /* Manning surface roughnes: read map or use a single value */
  42. if(manin != NULL) {
  43. cchez = read_float_raster_map(rows, cols, manin, 1.0);
  44. } else if(manin_val >= 0.0) { /* If no value set its set to -999.99 */
  45. cchez = create_float_matrix(rows, cols, manin_val);
  46. }else{
  47. G_fatal_error(_("Raster map <%s> not found, and manin_val undefined, choose one to be allowed to process"), manin);
  48. }
  49. /* Rain: read rain map or use a single value for all cells */
  50. if (rain != NULL) {
  51. si = read_double_raster_map(rows, cols, rain, unitconv);
  52. if_rain = 1;
  53. } else if(rain_val >= 0.0) { /* If no value set its set to -999.99 */
  54. si = create_double_matrix(rows, cols, rain_val * unitconv);
  55. if_rain = 1;
  56. } else{
  57. si = create_double_matrix(rows, cols, (double)UNDEF);
  58. if_rain = 0;
  59. }
  60. /* Update elevation map */
  61. copy_matrix_undef_double_to_float_values(rows, cols, si, zz);
  62. /* Load infiltration and traps if rain is present */
  63. if(if_rain == 1) {
  64. /* Infiltration: read map or use a single value */
  65. if (infil != NULL) {
  66. inf = read_double_raster_map(rows, cols, infil, unitconv);
  67. } else if(infil_val >= 0.0) { /* If no value set its set to -999.99 */
  68. inf = create_double_matrix(rows, cols, infil_val * unitconv);
  69. } else{
  70. inf = create_double_matrix(rows, cols, (double)UNDEF);
  71. }
  72. /* Traps */
  73. if (traps != NULL)
  74. trap = read_float_raster_map(rows, cols, traps, 1.0);
  75. else
  76. trap = create_float_matrix(rows, cols, (double)UNDEF);
  77. }
  78. if (detin != NULL) {
  79. dc = read_float_raster_map(rows, cols, detin, 1.0);
  80. copy_matrix_undef_float_values(rows, cols, dc, zz);
  81. }
  82. if (tranin != NULL) {
  83. ct = read_float_raster_map(rows, cols, tranin, 1.0);
  84. copy_matrix_undef_float_values(rows, cols, ct, zz);
  85. }
  86. if (tauin != NULL) {
  87. tau = read_float_raster_map(rows, cols, tauin, 1.0);
  88. copy_matrix_undef_float_values(rows, cols, tau, zz);
  89. }
  90. if (wdepth != NULL) {
  91. gama = read_double_raster_map(rows, cols, wdepth, 1.0);
  92. copy_matrix_undef_double_to_float_values(rows, cols, gama, zz);
  93. }
  94. /* Array for gradient checking */
  95. slope = create_double_matrix(rows, cols, 0.0);
  96. /* Create the observation points and open the logfile */
  97. create_observation_points();
  98. return 1;
  99. }
  100. /* ************************************************************************* */
  101. /* data preparations, sigma, shear, etc. */
  102. int grad_check(void)
  103. {
  104. int k, l;
  105. double zx, zy, zd2, zd4, sinsl;
  106. double cc, cmul2;
  107. double sheer;
  108. double vsum = 0.;
  109. double vmax = 0.;
  110. double chsum = 0.;
  111. double zmin = 1.e12;
  112. double zmax = -1.e12;
  113. double zd2min = 1.e12;
  114. double zd2max = -1.e12;
  115. double smin = 1.e12;
  116. double smax = -1.e12;
  117. double infmin = 1.e12;
  118. double infmax = -1.e12;
  119. double sigmax = -1.e12;
  120. double cchezmax = -1.e12;
  121. double rhow = 1000.;
  122. double gacc = 9.81;
  123. double hh = 1.;
  124. double deltaw = 1.e12;
  125. sisum = 0.;
  126. infsum = 0.;
  127. cmul2 = rhow * gacc;
  128. for (k = 0; k < my; k++) {
  129. for (l = 0; l < mx; l++) {
  130. if (zz[k][l] != UNDEF) {
  131. zx = v1[k][l];
  132. zy = v2[k][l];
  133. zd2 = zx * zx + zy * zy;
  134. sinsl = sqrt(zd2) / sqrt(zd2 + 1); /* sin(terrain slope) */
  135. /* Computing MIN */
  136. zd2 = sqrt(zd2);
  137. zd2min = amin1(zd2min, zd2);
  138. /* Computing MAX */
  139. zd2max = amax1(zd2max, zd2);
  140. zd4 = sqrt(zd2); /* ^.25 */
  141. if (cchez[k][l] != 0.) {
  142. cchez[k][l] = 1. / cchez[k][l]; /* 1/n */
  143. }
  144. else {
  145. G_fatal_error(_("Zero value in Mannings n"));
  146. }
  147. if (zd2 == 0.) {
  148. v1[k][l] = 0.;
  149. v2[k][l] = 0.;
  150. slope[k][l] = 0.;
  151. }
  152. else {
  153. if (wdepth)
  154. hh = pow(gama[k][l], 2. / 3.);
  155. /* hh = 1 if there is no water depth input */
  156. v1[k][l] = (double)hh *cchez[k][l] * zx / zd4;
  157. v2[k][l] = (double)hh *cchez[k][l] * zy / zd4;
  158. slope[k][l] =
  159. sqrt(v1[k][l] * v1[k][l] + v2[k][l] * v2[k][l]);
  160. }
  161. if (wdepth) {
  162. sheer = (double)(cmul2 * gama[k][l] * sinsl); /* shear stress */
  163. /* if critical shear stress >= shear then all zero */
  164. if ((sheer <= tau[k][l]) || (ct[k][l] == 0.)) {
  165. si[k][l] = 0.;
  166. sigma[k][l] = 0.;
  167. }
  168. else {
  169. si[k][l] = (double)(dc[k][l] * (sheer - tau[k][l]));
  170. sigma[k][l] = (double)(dc[k][l] / ct[k][l]) * (sheer - tau[k][l]) / (pow(sheer, 1.5)); /* rill erosion=1.5, sheet = 1.1 */
  171. }
  172. }
  173. sisum += si[k][l];
  174. smin = amin1(smin, si[k][l]);
  175. smax = amax1(smax, si[k][l]);
  176. if (inf) {
  177. infsum += inf[k][l];
  178. infmin = amin1(infmin, inf[k][l]);
  179. infmax = amax1(infmax, inf[k][l]);
  180. }
  181. vmax = amax1(vmax, slope[k][l]);
  182. vsum += slope[k][l];
  183. chsum += cchez[k][l];
  184. zmin = amin1(zmin, (double)zz[k][l]);
  185. zmax = amax1(zmax, (double)zz[k][l]); /* not clear were needed */
  186. if (wdepth)
  187. sigmax = amax1(sigmax, sigma[k][l]);
  188. cchezmax = amax1(cchezmax, cchez[k][l]);
  189. /* saved sqrt(sinsl)*cchez to cchez array for output */
  190. cchez[k][l] *= sqrt(sinsl);
  191. } /* DEFined area */
  192. }
  193. }
  194. if (inf != NULL && smax < infmax)
  195. G_warning(_("Infiltration exceeds the rainfall rate everywhere! No overland flow."));
  196. cc = (double)mx *my;
  197. si0 = sisum / cc;
  198. vmean = vsum / cc;
  199. chmean = chsum / cc;
  200. if (inf)
  201. infmean = infsum / cc;
  202. if (wdepth)
  203. deltaw = 0.8 / (sigmax * vmax); /*time step for sediment */
  204. deltap = 0.25 * sqrt(stepx * stepy) / vmean; /*time step for water */
  205. if (deltaw > deltap)
  206. timec = 4.;
  207. else
  208. timec = 1.25;
  209. miter = (int)(timesec / (deltap * timec)); /* number of iterations = number of cells to pass */
  210. iterout = (int)(iterout / (deltap * timec)); /* number of cells to pass for time series output */
  211. fprintf(stderr, "\n");
  212. G_message(_("Min elevation \t= %.2f m\nMax elevation \t= %.2f m\n"), zmin,
  213. zmax);
  214. G_message(_("Mean Source Rate (rainf. excess or sediment) \t= %f m/s or kg/m2s \n"),
  215. si0);
  216. G_message(_("Mean flow velocity \t= %f m/s\n"), vmean);
  217. G_message(_("Mean Mannings \t= %f\n"), 1.0 / chmean);
  218. deltap = amin1(deltap, deltaw);
  219. G_message(_("Number of iterations \t= %d cells\n"), miter);
  220. G_message(_("Time step \t= %.2f s\n"), deltap);
  221. if (wdepth) {
  222. G_message(_("Sigmax \t= %f\nMax velocity \t= %f m/s\n"), sigmax,
  223. vmax);
  224. G_message(_("Time step used \t= %.2f s\n"), deltaw);
  225. }
  226. /* if (wdepth) deltap = 0.1;
  227. * deltap for sediment is ar. average deltap and deltaw */
  228. /* if (wdepth) deltap = (deltaw+deltap)/2.;
  229. * deltap for sediment is ar. average deltap and deltaw */
  230. /*! For each cell (k,l) compute the length s=(v1,v2) of the path
  231. * that the particle will travel per one time step
  232. * \f$ s(k,l)=v(k,l)*dt \f$, [m]=[m/s]*[s]
  233. * give warning if there is a cell that will lead to path longer than 2 cells
  234. *
  235. * if running erosion, compute sediment transport capacity for each cell si(k,l)
  236. * \f$
  237. * T({\bf r})=K_t({\bf r}) \bigl[\tau({\bf r})\bigr]^p
  238. * =K_t({\bf r}) \bigl[\rho_w\, g h({\bf r}) \sin \beta ({\bf r}) \bigr]^p
  239. * \f$
  240. * [kg/ms]=...
  241. */
  242. for (k = 0; k < my; k++) {
  243. for (l = 0; l < mx; l++) {
  244. if (zz[k][l] != UNDEF) {
  245. v1[k][l] *= deltap;
  246. v2[k][l] *= deltap;
  247. /*if(v1[k][l]*v1[k][l]+v2[k][l]*v2[k][l] > cellsize, warning, napocitaj
  248. *ak viac ako 10%a*/
  249. /* THIS IS CORRECT SOLUTION currently commented out */
  250. if (inf)
  251. inf[k][l] *= timesec;
  252. if (wdepth)
  253. gama[k][l] = 0.;
  254. if (et) {
  255. if (sigma[k][l] == 0. || slope[k][l] == 0.)
  256. si[k][l] = 0.;
  257. else
  258. /* temp for transp. cap. erod */
  259. si[k][l] = si[k][l] / (slope[k][l] * sigma[k][l]);
  260. }
  261. } /* DEFined area */
  262. }
  263. }
  264. /*! compute transport capacity limted erosion/deposition et
  265. * as a divergence of sediment transport capacity
  266. * \f$
  267. D_T({\bf r})= \nabla\cdot {\bf T}({\bf r})
  268. * \f$
  269. */
  270. if (et) {
  271. erod(si); /* compute divergence of t.capc */
  272. if (output_et() != 1)
  273. G_fatal_error(_("Unable to write et file"));
  274. }
  275. /*! compute the inversion operator and store it in sigma - note that after this
  276. * sigma does not store the first order reaction coefficient but the operator
  277. * WRITE the equation here
  278. */
  279. if (wdepth) {
  280. for (k = 0; k < my; k++) {
  281. for (l = 0; l < mx; l++) {
  282. if (zz[k][l] != UNDEF) {
  283. /* get back from temp */
  284. if (et)
  285. si[k][l] = si[k][l] * slope[k][l] * sigma[k][l];
  286. if (sigma[k][l] != 0.)
  287. /* rate of weight loss - w=w*sigma ,
  288. * vaha prechadzky po n-krokoch je sigma^n */
  289. /*!!!!! not clear what's here :-\ !!!!!*/
  290. sigma[k][l] =
  291. exp(-sigma[k][l] * deltap * slope[k][l]);
  292. /* if(sigma[k][l]<0.5) warning, napocitaj,
  293. * ak vacsie ako 50% skonci, zmensi deltap)*/
  294. }
  295. } /*DEFined area */
  296. }
  297. }
  298. return 1;
  299. }
  300. /* ************************************************************************* */
  301. void copy_matrix_undef_double_to_float_values(int rows, int cols, double **source, float **target)
  302. {
  303. int col = 0, row = 0;
  304. for(row = 0; row < rows; row++) {
  305. for(col = 0; col < cols; col++) {
  306. if(source[row][col] == UNDEF)
  307. target[row][col] = UNDEF;
  308. }
  309. }
  310. }
  311. /* ************************************************************************* */
  312. void copy_matrix_undef_float_values(int rows, int cols, float **source, float **target)
  313. {
  314. int col = 0, row = 0;
  315. for(row = 0; row < rows; row++) {
  316. for(col = 0; col < cols; col++) {
  317. if(source[row][col] == UNDEF)
  318. target[row][col] = UNDEF;
  319. }
  320. }
  321. }
  322. /* ************************************************************************* */
  323. float ** create_float_matrix(int rows, int cols, float fill_value)
  324. {
  325. int col = 0, row = 0;
  326. float **matrix = NULL;
  327. G_verbose_message("Creating float matrix with value %g", fill_value);
  328. /* Allocate the float marix */
  329. matrix = G_alloc_fmatrix(rows, cols);
  330. for(row = 0; row < rows; row++) {
  331. for(col = 0; col < cols; col++) {
  332. matrix[row][col] = fill_value;
  333. }
  334. }
  335. return matrix;
  336. }
  337. /* ************************************************************************* */
  338. double ** create_double_matrix(int rows, int cols, double fill_value)
  339. {
  340. int col = 0, row = 0;
  341. double **matrix = NULL;
  342. G_verbose_message("Creating double matrix with value %g", fill_value);
  343. /* Allocate the float marix */
  344. matrix = G_alloc_matrix(rows, cols);
  345. for(row = 0; row < rows; row++) {
  346. for(col = 0; col < cols; col++) {
  347. matrix[row][col] = fill_value;
  348. }
  349. }
  350. return matrix;
  351. }
  352. /* ************************************************************************* */
  353. float ** read_float_raster_map(int rows, int cols, char *name, float unitconv)
  354. {
  355. FCELL *row_buff = NULL;
  356. int fd;
  357. int col = 0, row = 0, row_rev = 0;
  358. float **matrix = NULL;
  359. G_verbose_message("Reading float map %s into memory", name);
  360. /* Open raster map */
  361. fd = Rast_open_old(name, "");
  362. /* Allocate the row buffer */
  363. row_buff = Rast_allocate_f_buf();
  364. /* Allocate the float marix */
  365. matrix = G_alloc_fmatrix(rows, cols);
  366. for(row = 0; row < rows; row++) {
  367. Rast_get_f_row(fd, row_buff, row);
  368. for(col = 0; col < cols; col++) {
  369. /* we fill the arrays from south to north */
  370. row_rev = rows - row - 1;
  371. /* Check for null values */
  372. if (!Rast_is_f_null_value(row_buff + col))
  373. matrix[row_rev][col] = (float)(unitconv * row_buff[col]);
  374. else
  375. matrix[row_rev][col] = UNDEF;
  376. }
  377. }
  378. /* Free the row buffer */
  379. if(row_buff)
  380. G_free(row_buff);
  381. Rast_close(fd);
  382. return matrix;
  383. }
  384. /* ************************************************************************* */
  385. double ** read_double_raster_map(int rows, int cols, char *name, double unitconv)
  386. {
  387. DCELL *row_buff = NULL;
  388. int fd;
  389. int col = 0, row = 0, row_rev;
  390. double **matrix = NULL;
  391. G_verbose_message("Reading double map %s into memory", name);
  392. /* Open raster map */
  393. fd = Rast_open_old(name, "");
  394. /* Allocate the row buffer */
  395. row_buff = Rast_allocate_d_buf();
  396. /* Allocate the double marix */
  397. matrix = G_alloc_matrix(rows, cols);
  398. for(row = 0; row < rows; row++) {
  399. Rast_get_d_row(fd, row_buff, row);
  400. for(col = 0; col < cols; col++) {
  401. /* we fill the arrays from south to north */
  402. row_rev = rows - row - 1;
  403. /* Check for null values */
  404. if (!Rast_is_d_null_value(row_buff + col))
  405. matrix[row_rev][col] = (double)(unitconv * row_buff[col]);
  406. else
  407. matrix[row_rev][col] = UNDEF;
  408. }
  409. }
  410. /* Free the row buffer */
  411. if(row_buff)
  412. G_free(row_buff);
  413. Rast_close(fd);
  414. return matrix;
  415. }