infiltration.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. #include <math.h>
  2. #include <grass/gis.h>
  3. #include <grass/glocale.h>
  4. #include "global.h"
  5. /* The Green-and-Ampt Model */
  6. double calculate_infiltration(int timestep, double R)
  7. {
  8. static double cumf = 0.0, f = 0.0;
  9. static char ponding = 0;
  10. double t, df, f1, f2, fc, R2, cnst, pt, psi_dtheta, sum;
  11. int factorial;
  12. int i, j;
  13. /* reset if there is no rainfall */
  14. if (R <= 0.0) {
  15. cumf = 0.0;
  16. f = 0.0;
  17. ponding = 0;
  18. return 0.0;
  19. }
  20. t = timestep * input.dt;
  21. f1 = cnst = pt = 0.0;
  22. psi_dtheta = params.psi * params.dtheta;
  23. if (!ponding) {
  24. if (cumf) {
  25. f1 = cumf;
  26. R2 = -params.K0 / params.m *
  27. (psi_dtheta + f1) / (1 - exp(f1 / params.m));
  28. /* rainfall intensity is greater than infiltration
  29. * rate, so ponding starts */
  30. if (R2 < R) {
  31. f = cumf;
  32. pt = t - input.dt;
  33. ponding = 1;
  34. goto cont1;
  35. }
  36. }
  37. f2 = cumf + R * input.dt;
  38. R2 = -params.K0 / params.m *
  39. (psi_dtheta + f2) / (1 - exp(f2 / params.m));
  40. /* rainfall intensity is less than infiltration rate. all
  41. * rainfall will be infiltrated. */
  42. if (f2 == 0.0 || R2 > R)
  43. goto cont2;
  44. /* rainfall intensity is greater than infiltration rate. */
  45. f = cumf + R2 * input.dt;
  46. for (i = 0; i < MAXITER; i++) {
  47. R2 = -params.K0 / params.m *
  48. (psi_dtheta + f) / (1 - exp(f / params.m));
  49. if (R2 > R) {
  50. f1 = f;
  51. f = (f + f2) / 2.0;
  52. df = f - f1;
  53. }
  54. else {
  55. f2 = f;
  56. f = (f + f1) / 2.0;
  57. df = f - f2;
  58. }
  59. if (fabs(df) <= TOLERANCE)
  60. break;
  61. }
  62. if (i == MAXITER)
  63. G_warning(
  64. _("Maximum number of iterations exceeded at timestep %d."),
  65. timestep);
  66. pt = t - input.dt + (f - cumf) / R;
  67. if (pt > t)
  68. goto cont2;
  69. cont1:
  70. cnst = 0.0;
  71. factorial = 1;
  72. fc = f + psi_dtheta;
  73. for (j = 1; j <= NTERMS; j++) {
  74. factorial *= j;
  75. cnst += pow(fc / params.m, (double)j) / (double)(j * factorial);
  76. }
  77. cnst = log(fc) - (log(fc) + cnst) / exp(psi_dtheta / params.m);
  78. f += R * (t - pt) / 2.0;
  79. ponding = 1;
  80. }
  81. /* Newton-Raphson */
  82. for (i = 0; i < MAXITER; i++) {
  83. fc = f + psi_dtheta;
  84. sum = 0.0;
  85. factorial = 1;
  86. for (j = 1; j <= NTERMS; j++) {
  87. factorial *= j;
  88. sum += pow(fc / params.m, (double)j) / (double)(j * factorial);
  89. }
  90. f1 = -(log(fc) - (log(fc) + sum) /
  91. exp(psi_dtheta / params.m) - cnst) /
  92. (params.K0 / params.m) - (t - pt);
  93. f2 = (exp(f / params.m) - 1.0) / (fc * params.K0 / params.m);
  94. df = -f1 / f2;
  95. f += df;
  96. if (fabs(df) <= TOLERANCE)
  97. break;
  98. }
  99. if (i == MAXITER)
  100. G_warning(_("Maximum number of iterations exceeded at timestep %d."),
  101. timestep);
  102. if (f < cumf + R * input.dt) {
  103. df = (f - cumf) / input.dt;
  104. cumf = f;
  105. /* initial guess for next time step */
  106. f += df * input.dt;
  107. return df;
  108. }
  109. cont2:
  110. df = R;
  111. cumf += df * input.dt;
  112. ponding = 0;
  113. return df;
  114. }