test_solute_transport.c 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317
  1. /*****************************************************************************
  2. *
  3. * MODULE: Grass PDE Numerical Library
  4. * AUTHOR(S): Soeren Gebbert, Berlin (GER) Dec 2006
  5. * soerengebbert <at> gmx <dot> de
  6. *
  7. * PURPOSE: solute_transport integration tests
  8. *
  9. * COPYRIGHT: (C) 2000 by the GRASS Development Team
  10. *
  11. * This program is free software under the GNU General Public
  12. * License (>=v2). Read the file COPYING that comes with GRASS
  13. * for details.
  14. *
  15. *****************************************************************************/
  16. #include <grass/gis.h>
  17. #include <grass/N_pde.h>
  18. #include <grass/N_solute_transport.h>
  19. #include "test_gpde_lib.h"
  20. /*redefine */
  21. #define TEST_N_NUM_DEPTHS_LOCAL 2
  22. #define TEST_N_NUM_ROWS_LOCAL 3
  23. #define TEST_N_NUM_COLS_LOCAL 3
  24. /* prototypes */
  25. static N_solute_transport_data2d *create_solute_transport_data_2d(void);
  26. static N_solute_transport_data3d *create_solute_transport_data_3d(void);
  27. static int test_solute_transport_2d(void);
  28. static int test_solute_transport_3d(void);
  29. /* *************************************************************** */
  30. /* Performe the solute_transport integration tests ************************* */
  31. /* *************************************************************** */
  32. int integration_test_solute_transport(void)
  33. {
  34. int sum = 0;
  35. G_message("\n++ Running solute_transport integration tests ++");
  36. G_message("\t 1. testing 2d solute_transport");
  37. sum += test_solute_transport_2d();
  38. G_message("\t 2. testing 3d solute_transport");
  39. sum += test_solute_transport_3d();
  40. if (sum > 0)
  41. G_warning("\n-- solute_transport integration tests failure --");
  42. else
  43. G_message("\n-- solute_transport integration tests finished successfully --");
  44. return sum;
  45. }
  46. /* *************************************************************** */
  47. /* Create valid solute transport data **************************** */
  48. /* *************************************************************** */
  49. N_solute_transport_data3d *create_solute_transport_data_3d(void)
  50. {
  51. N_solute_transport_data3d *data;
  52. int i, j, k;
  53. data =
  54. N_alloc_solute_transport_data3d(TEST_N_NUM_COLS_LOCAL,
  55. TEST_N_NUM_ROWS_LOCAL,
  56. TEST_N_NUM_DEPTHS_LOCAL);
  57. #pragma omp parallel for private (i, j, k) shared (data)
  58. for (k = 0; k < TEST_N_NUM_DEPTHS_LOCAL; k++)
  59. for (j = 0; j < TEST_N_NUM_ROWS_LOCAL; j++) {
  60. for (i = 0; i < TEST_N_NUM_COLS_LOCAL; i++) {
  61. if (j == 0) {
  62. N_put_array_3d_d_value(data->c, i, j, k, 1);
  63. N_put_array_3d_d_value(data->c_start, i, j, k, 1);
  64. N_put_array_3d_d_value(data->status, i, j, k, 3);
  65. }
  66. else {
  67. N_put_array_3d_d_value(data->c, i, j, k, 0);
  68. N_put_array_3d_d_value(data->c_start, i, j, k, 0);
  69. N_put_array_3d_d_value(data->status, i, j, k, 1);
  70. }
  71. N_put_array_3d_d_value(data->diff_x, i, j, k, 0.000001);
  72. N_put_array_3d_d_value(data->diff_y, i, j, k, 0.000001);
  73. N_put_array_3d_d_value(data->diff_z, i, j, k, 0.000001);
  74. N_put_array_3d_d_value(data->q, i, j, k, 0.0);
  75. N_put_array_3d_d_value(data->cs, i, j, k, 0.0);
  76. N_put_array_3d_d_value(data->R, i, j, k, 1.0);
  77. N_put_array_3d_d_value(data->nf, i, j, k, 0.1);
  78. if (j == 1 && i == 1 && k == 1)
  79. N_put_array_3d_d_value(data->cs, i, j, k, 5.0);
  80. }
  81. }
  82. return data;
  83. }
  84. /* *************************************************************** */
  85. /* Create valid solute transport data **************************** */
  86. /* *************************************************************** */
  87. N_solute_transport_data2d *create_solute_transport_data_2d(void)
  88. {
  89. int i, j;
  90. N_solute_transport_data2d *data;
  91. data =
  92. N_alloc_solute_transport_data2d(TEST_N_NUM_COLS_LOCAL,
  93. TEST_N_NUM_ROWS_LOCAL);
  94. #pragma omp parallel for private (i, j) shared (data)
  95. for (j = 0; j < TEST_N_NUM_ROWS_LOCAL; j++) {
  96. for (i = 0; i < TEST_N_NUM_COLS_LOCAL; i++) {
  97. if (j == 0) {
  98. N_put_array_2d_d_value(data->c, i, j, 0);
  99. N_put_array_2d_d_value(data->c_start, i, j, 0);
  100. N_put_array_2d_d_value(data->status, i, j, 2);
  101. }
  102. else {
  103. N_put_array_2d_d_value(data->c, i, j, 0);
  104. N_put_array_2d_d_value(data->c_start, i, j, 0);
  105. N_put_array_2d_d_value(data->status, i, j, 1);
  106. }
  107. N_put_array_2d_d_value(data->diff_x, i, j, 0.000001);
  108. N_put_array_2d_d_value(data->diff_y, i, j, 0.000001);
  109. N_put_array_2d_d_value(data->cs, i, j, 0.0);
  110. N_put_array_2d_d_value(data->R, i, j, 1.0);
  111. N_put_array_2d_d_value(data->q, i, j, 0.0);
  112. N_put_array_2d_d_value(data->nf, i, j, 0.1);
  113. N_put_array_2d_d_value(data->top, i, j, 20.0);
  114. N_put_array_2d_d_value(data->bottom, i, j, 0.0);
  115. if (j == 1 && i == 1)
  116. N_put_array_2d_d_value(data->cs, i, j, 1.0);
  117. }
  118. }
  119. /*dispersivity length*/
  120. data->al = 0.2;
  121. data->at = 0.02;
  122. return data;
  123. }
  124. /* *************************************************************** */
  125. /* Test the solute transport in 3d with different solvers ******** */
  126. /* *************************************************************** */
  127. int test_solute_transport_3d(void)
  128. {
  129. N_solute_transport_data3d *data;
  130. N_geom_data *geom;
  131. N_les *les;
  132. N_les_callback_3d *call;
  133. call = N_alloc_les_callback_3d();
  134. N_set_les_callback_3d_func(call, (*N_callback_solute_transport_3d)); /*solute_transport 3d */
  135. data = create_solute_transport_data_3d();
  136. N_calc_solute_transport_disptensor_3d(data);
  137. data->dt = 86400;
  138. geom = N_alloc_geom_data();
  139. geom->dx = 10;
  140. geom->dy = 15;
  141. geom->dz = 3;
  142. geom->Az = 150;
  143. geom->depths = TEST_N_NUM_DEPTHS_LOCAL;
  144. geom->rows = TEST_N_NUM_ROWS_LOCAL;
  145. geom->cols = TEST_N_NUM_COLS_LOCAL;
  146. /*Assemble the matrix */
  147. /*
  148. */
  149. /*BICG*/ les =
  150. N_assemble_les_3d(N_SPARSE_LES, geom, data->status, data->c_start,
  151. (void *)data, call);
  152. G_math_solver_sparse_bicgstab(les->Asp, les->x, les->b, les->rows, 100, 0.1e-8);
  153. N_print_les(les);
  154. N_free_les(les);
  155. /*BICG*/ les =
  156. N_assemble_les_3d(N_NORMAL_LES, geom, data->status, data->c_start,
  157. (void *)data, call);
  158. G_math_solver_bicgstab(les->A, les->x, les->b, les->rows, 100, 0.1e-8);
  159. N_print_les(les);
  160. N_free_les(les);
  161. /*GUASS*/ les =
  162. N_assemble_les_3d(N_NORMAL_LES, geom, data->status, data->c_start,
  163. (void *)data, call);
  164. G_math_solver_gauss(les->A, les->x, les->b, les->rows);
  165. N_print_les(les);
  166. N_free_les(les);
  167. /*LU*/ les =
  168. N_assemble_les_3d(N_NORMAL_LES, geom, data->status, data->c_start,
  169. (void *)data, call);
  170. G_math_solver_lu(les->A, les->x, les->b, les->rows);
  171. N_print_les(les);
  172. N_free_les(les);
  173. N_free_solute_transport_data3d(data);
  174. G_free(geom);
  175. G_free(call);
  176. return 0;
  177. }
  178. /* *************************************************************** */
  179. /* Test the solute transport in 2d with different solvers ******** */
  180. /* *************************************************************** */
  181. int test_solute_transport_2d(void)
  182. {
  183. N_solute_transport_data2d *data = NULL;
  184. N_geom_data *geom = NULL;
  185. N_les *les = NULL;
  186. N_les_callback_2d *call = NULL;
  187. N_array_2d *pot, *relax = NULL;
  188. N_gradient_field_2d *field = NULL;
  189. int i, j;
  190. /*set the callback */
  191. call = N_alloc_les_callback_2d();
  192. N_set_les_callback_2d_func(call, (*N_callback_solute_transport_2d));
  193. pot =
  194. N_alloc_array_2d(TEST_N_NUM_COLS_LOCAL, TEST_N_NUM_ROWS_LOCAL, 1,
  195. DCELL_TYPE);
  196. relax =
  197. N_alloc_array_2d(TEST_N_NUM_COLS_LOCAL, TEST_N_NUM_ROWS_LOCAL, 1,
  198. DCELL_TYPE);
  199. data = create_solute_transport_data_2d();
  200. data->dt = 600;
  201. geom = N_alloc_geom_data();
  202. geom->dx = 10;
  203. geom->dy = 15;
  204. geom->Az = 150;
  205. geom->rows = TEST_N_NUM_ROWS_LOCAL;
  206. geom->cols = TEST_N_NUM_COLS_LOCAL;
  207. for (j = 0; j < TEST_N_NUM_ROWS_LOCAL; j++) {
  208. for (i = 0; i < TEST_N_NUM_COLS_LOCAL; i++) {
  209. N_put_array_2d_d_value(pot, i, j, j);
  210. N_put_array_2d_d_value(relax, i, j, 1);
  211. }
  212. }
  213. field = N_compute_gradient_field_2d(pot, relax, relax, geom, NULL);
  214. N_copy_gradient_field_2d(field, data->grad);
  215. N_free_gradient_field_2d(field);
  216. N_compute_gradient_field_2d(pot, relax, relax, geom, data->grad);
  217. /*The dispersivity tensor*/
  218. N_calc_solute_transport_disptensor_2d(data);
  219. /*Assemble the matrix */
  220. /*
  221. */
  222. /*BICG*/ les =
  223. N_assemble_les_2d(N_SPARSE_LES, geom, data->status, data->c_start,
  224. (void *)data, call);
  225. G_math_solver_sparse_bicgstab(les->Asp, les->x, les->b, les->rows, 100, 0.1e-8);
  226. N_print_les(les);
  227. N_free_les(les);
  228. /*BICG*/ les =
  229. N_assemble_les_2d(N_NORMAL_LES, geom, data->status, data->c_start,
  230. (void *)data, call);
  231. G_math_solver_bicgstab(les->A, les->x, les->b, les->rows, 100, 0.1e-8);
  232. N_print_les(les);
  233. N_free_les(les);
  234. /*GUASS*/ les =
  235. N_assemble_les_2d(N_NORMAL_LES, geom, data->status, data->c_start,
  236. (void *)data, call);
  237. G_math_solver_gauss(les->A, les->x, les->b, les->rows);
  238. N_print_les(les);
  239. N_free_les(les);
  240. /*LU*/ les =
  241. N_assemble_les_2d(N_NORMAL_LES, geom, data->status, data->c_start,
  242. (void *)data, call);
  243. G_math_solver_lu(les->A, les->x, les->b, les->rows);
  244. N_print_les(les);
  245. N_free_les(les);
  246. N_free_solute_transport_data2d(data);
  247. G_free(geom);
  248. G_free(call);
  249. return 0;
  250. }