19 #include <grass/N_pde.h>
22 static int make_les_entry_2d(
int i,
int j,
int offset_i,
int offset_j,
26 double entry,
int cell_type);
28 static int make_les_entry_3d(
int i,
int j,
int k,
int offset_i,
int offset_j,
32 double entry,
int cell_type);
137 G_debug(5,
"N_create_5star: w %g e %g n %g s %g c %g v %g\n", star->
W,
138 star->
E, star->
N, star->
S, star->
C, star->
V);
160 double T,
double B,
double V)
175 G_debug(5,
"N_create_7star: w %g e %g n %g s %g t %g b %g c %g v %g\n",
176 star->
W, star->
E, star->
N, star->
S, star->
T, star->
B, star->
C,
201 double NW,
double SW,
double NE,
double SE,
220 "N_create_9star: w %g e %g n %g s %g nw %g sw %g ne %g se %g c %g "
222 star->
W, star->
E, star->
N, star->
S, star->
NW, star->
SW, star->
NE,
223 star->
SE, star->
C, star->
V);
265 double NW,
double SW,
double NE,
double SE,
266 double T,
double W_T,
double E_T,
double N_T,
267 double S_T,
double NW_T,
double SW_T,
double NE_T,
268 double SE_T,
double B,
double W_B,
double E_B,
269 double N_B,
double S_B,
double NW_B,
double SW_B,
270 double NE_B,
double SE_B,
double V)
310 "N_create_27star: w %g e %g n %g s %g nw %g sw %g ne %g se %g c "
312 star->
W, star->
E, star->
N, star->
S, star->
NW, star->
SW, star->
NE,
313 star->
SE, star->
C, star->
V);
316 "N_create_27star: w_t %g e_t %g n_t %g s_t %g nw_t %g sw_t %g "
317 "ne_t %g se_t %g t %g \n",
322 "N_create_27star: w_b %g e_b %g n_b %g s_b %g nw_b %g sw_b %g "
323 "ne_b %g se_B %g b %g\n",
433 star->
E = 1 / geom->
dx;
434 star->
W = 1 / geom->
dx;
435 star->
N = 1 / geom->
dy;
436 star->
S = 1 / geom->
dy;
437 star->
T = 1 / geom->
dz;
438 star->
B = 1 / geom->
dz;
439 star->
C = -1 * (2 / geom->
dx + 2 / geom->
dy + 2 / geom->
dz);
443 5,
"N_callback_template_3d: w %g e %g n %g s %g t %g b %g c %g v %g\n",
444 star->
W, star->
E, star->
N, star->
S, star->
T, star->
B, star->
C, star->
V);
470 star->
E = 1 / geom->
dx;
471 star->
NE = 1 / sqrt(geom->
dx * geom->
dx + geom->
dy * geom->
dy);
472 star->
SE = 1 / sqrt(geom->
dx * geom->
dx + geom->
dy * geom->
dy);
473 star->
W = 1 / geom->
dx;
474 star->
NW = 1 / sqrt(geom->
dx * geom->
dx + geom->
dy * geom->
dy);
475 star->
SW = 1 / sqrt(geom->
dx * geom->
dx + geom->
dy * geom->
dy);
476 star->
N = 1 / geom->
dy;
477 star->
S = 1 / geom->
dy;
478 star->
C = -1 * (star->
E + star->
NE + star->
SE + star->
W + star->
NW +
479 star->
SW + star->
N + star->
S);
568 int i, j,
count = 0, pos = 0;
569 int cell_type_count = 0;
576 "N_assemble_les_2d: starting to assemble the linear equation system");
587 for (j = 0; j < geom->
rows; j++) {
588 for (i = 0; i < geom->
cols; i++) {
598 for (j = 0; j < geom->
rows; j++) {
599 for (i = 0; i < geom->
cols; i++) {
607 G_debug(2,
"N_assemble_les_2d: number of used cells %i\n", cell_type_count);
609 if (cell_type_count == 0)
610 G_fatal_error(
"Not enough cells [%i] to create the linear equation "
611 "system. Check the cell status. Only active cells (value "
612 "= 1) are used to create the equation system.",
617 index_ij = (
int **)
G_calloc(cell_type_count,
sizeof(
int *));
618 for (i = 0; i < cell_type_count; i++)
619 index_ij[i] = (
int *)
G_calloc(2,
sizeof(
int));
628 for (j = 0; j < geom->
rows; j++) {
629 for (i = 0; i < geom->
cols; i++) {
635 index_ij[
count][0] = i;
636 index_ij[
count][1] = j;
639 "N_assemble_les_2d: non-inactive cells count %i at "
647 index_ij[
count][0] = i;
648 index_ij[
count][1] = j;
651 "N_assemble_les_2d: active cells count %i at pos x[%i] "
658 G_debug(2,
"N_assemble_les_2d: starting the parallel assemble loop");
661 #pragma omp parallel for private(i, j, pos, count) schedule(static)
663 i = index_ij[
count][0];
664 j = index_ij[
count][1];
688 spvect->
values[pos] = items->
C;
695 pos = make_les_entry_2d(i, j, -1, 0,
count, pos, les, spvect,
696 cell_count, status, start_val, items->
W,
700 if (i < geom->cols - 1) {
701 pos = make_les_entry_2d(i, j, 1, 0,
count, pos, les, spvect,
702 cell_count, status, start_val, items->
E,
707 pos = make_les_entry_2d(i, j, 0, -1,
count, pos, les, spvect,
708 cell_count, status, start_val, items->
N,
712 if (j < geom->rows - 1) {
713 pos = make_les_entry_2d(i, j, 0, 1,
count, pos, les, spvect,
714 cell_count, status, start_val, items->
S,
720 if (i > 0 && j > 0) {
721 pos = make_les_entry_2d(i, j, -1, -1,
count, pos, les, spvect,
722 cell_count, status, start_val,
723 items->
NW, cell_type);
726 if (i < geom->cols - 1 && j > 0) {
727 pos = make_les_entry_2d(i, j, 1, -1,
count, pos, les, spvect,
728 cell_count, status, start_val,
729 items->
NE, cell_type);
732 if (i > 0 && j < geom->rows - 1) {
733 pos = make_les_entry_2d(i, j, -1, 1,
count, pos, les, spvect,
734 cell_count, status, start_val,
735 items->
SW, cell_type);
738 if (i < geom->cols - 1 && j < geom->rows - 1) {
739 pos = make_les_entry_2d(i, j, 1, 1,
count, pos, les, spvect,
740 cell_count, status, start_val,
741 items->
SE, cell_type);
747 spvect->
cols = pos + 1;
758 for (i = 0; i < cell_type_count; i++)
798 int i, j,
x, y, stat;
802 G_debug(2,
"N_les_integrate_dirichlet_2d: integrating the dirichlet "
803 "boundary condition");
814 for (y = 0; y < rows; y++) {
815 for (
x = 0;
x < cols;
x++) {
828 #pragma omp parallel default(shared)
835 #pragma omp for schedule(static) private(i)
836 for (i = 0; i < les->
cols; i++)
837 les->
b[i] = les->
b[i] - dvect2[i];
843 for (y = 0; y < rows; y++) {
844 for (
x = 0;
x < cols;
x++) {
849 for (i = 0; (
unsigned int)i < les->Asp[
count]->cols; i++)
852 for (i = 0; i < les->
rows; i++) {
853 for (j = 0; (
unsigned int)j < les->Asp[i]->cols; j++) {
864 for (i = 0; i < les->
cols; i++)
867 for (i = 0; i < les->
rows; i++)
885 int make_les_entry_2d(
int i,
int j,
int offset_i,
int offset_j,
int count,
888 N_array_2d *start_val,
double entry,
int cell_type)
908 " make_les_entry_2d: (N_CELL_ACTIVE) create matrix "
909 "entry at row[%i] col[%i] value %g\n",
914 spvect->
values[pos] = entry;
929 " make_les_entry_2d: (N_CELL_DIRICHLET) create matrix "
930 "entry at row[%i] col[%i] value %g\n",
935 spvect->
values[pos] = entry;
1026 int i, j, k,
count = 0, pos = 0;
1027 int cell_type_count = 0;
1034 "N_assemble_les_3d: starting to assemble the linear equation system");
1045 for (k = 0; k < geom->
depths; k++) {
1046 for (j = 0; j < geom->
rows; j++) {
1047 for (i = 0; i < geom->
cols; i++) {
1060 for (k = 0; k < geom->
depths; k++) {
1061 for (j = 0; j < geom->
rows; j++) {
1062 for (i = 0; i < geom->
cols; i++) {
1072 G_debug(2,
"N_assemble_les_3d: number of used cells %i\n",
1075 if (cell_type_count == 0.0)
1077 "Not enough active cells [%i] to create the linear equation "
1078 "system. Check the cell status. Only active cells (value = 1) are "
1079 "used to create the equation system.",
1086 index_ij = (
int **)
G_calloc(cell_type_count,
sizeof(
int *));
1087 for (i = 0; i < cell_type_count; i++)
1088 index_ij[i] = (
int *)
G_calloc(3,
sizeof(
int));
1094 for (k = 0; k < geom->
depths; k++) {
1095 for (j = 0; j < geom->
rows; j++) {
1096 for (i = 0; i < geom->
cols; i++) {
1103 index_ij[
count][0] = i;
1104 index_ij[
count][1] = j;
1105 index_ij[
count][2] = k;
1108 "N_assemble_les_3d: non-inactive cells count "
1109 "%i at pos x[%i] y[%i] z[%i]\n",
1116 index_ij[
count][0] = i;
1117 index_ij[
count][1] = j;
1118 index_ij[
count][2] = k;
1121 "N_assemble_les_3d: active cells count %i at pos "
1122 "x[%i] y[%i] z[%i]\n",
1129 G_debug(2,
"N_assemble_les_3d: starting the parallel assemble loop");
1131 #pragma omp parallel for private(i, j, k, pos, count) schedule(static)
1133 i = index_ij[
count][0];
1134 j = index_ij[
count][1];
1135 k = index_ij[
count][2];
1158 spvect->
values[pos] = items->
C;
1165 pos = make_les_entry_3d(i, j, k, -1, 0, 0,
count, pos, les, spvect,
1166 cell_count, status, start_val, items->
W,
1170 if (i < geom->cols - 1) {
1171 pos = make_les_entry_3d(i, j, k, 1, 0, 0,
count, pos, les, spvect,
1172 cell_count, status, start_val, items->
E,
1177 pos = make_les_entry_3d(i, j, k, 0, -1, 0,
count, pos, les, spvect,
1178 cell_count, status, start_val, items->
N,
1182 if (j < geom->rows - 1) {
1183 pos = make_les_entry_3d(i, j, k, 0, 1, 0,
count, pos, les, spvect,
1184 cell_count, status, start_val, items->
S,
1190 if (k < geom->depths - 1) {
1191 pos = make_les_entry_3d(i, j, k, 0, 0, 1,
count, pos, les,
1192 spvect, cell_count, status, start_val,
1193 items->
T, cell_type);
1197 pos = make_les_entry_3d(i, j, k, 0, 0, -1,
count, pos, les,
1198 spvect, cell_count, status, start_val,
1199 items->
B, cell_type);
1205 spvect->
cols = pos + 1;
1215 for (i = 0; i < cell_type_count; i++)
1253 int rows, cols, depths;
1255 int i, j,
x, y, z, stat;
1259 G_debug(2,
"N_les_integrate_dirichlet_3d: integrating the dirichlet "
1260 "boundary condition");
1267 dvect1 = (
double *)
G_calloc(les->
cols,
sizeof(
double));
1268 dvect2 = (
double *)
G_calloc(les->
cols,
sizeof(
double));
1272 for (z = 0; z < depths; z++) {
1273 for (y = 0; y < rows; y++) {
1274 for (
x = 0;
x < cols;
x++) {
1281 dvect1[
count] = 0.0;
1288 #pragma omp parallel default(shared)
1295 #pragma omp for schedule(static) private(i)
1296 for (i = 0; i < les->
cols; i++)
1297 les->
b[i] = les->
b[i] - dvect2[i];
1303 for (z = 0; z < depths; z++) {
1304 for (y = 0; y < rows; y++) {
1305 for (
x = 0;
x < cols;
x++) {
1310 for (i = 0; (
unsigned int)i < les->Asp[
count]->cols;
1314 for (i = 0; i < les->
rows; i++) {
1315 for (j = 0; (
unsigned int)j < les->Asp[i]->cols;
1318 (
unsigned int)
count)
1328 for (i = 0; i < les->
cols; i++)
1331 for (i = 0; i < les->
rows; i++)
1349 int make_les_entry_3d(
int i,
int j,
int k,
int offset_i,
int offset_j,
1350 int offset_k,
int count,
int pos,
N_les *les,
1375 " make_les_entry_3d: (N_CELL_ACTIVE) create matrix "
1376 "entry at row[%i] col[%i] value %g\n",
1381 spvect->
values[pos] = entry;
1394 " make_les_entry_3d: (N_CELL_DIRICHLET) create matrix "
1395 "entry at row[%i] col[%i] value %g\n",
1400 spvect->
values[pos] = entry;
#define N_MAX_CELL_STATE
the maximum number of available cell states (eg: boundary condition, inactiven active)
void G_free(void *)
Free allocated memory.
void void void void G_fatal_error(const char *,...) __attribute__((format(printf
int G_debug(int, const char *,...) __attribute__((format(printf
G_math_spvector * G_math_alloc_spvector(int)
Allocate memory for a sparse vector.
void G_math_Ax_sparse(G_math_spvector **, double *, double *, int)
Compute the matrix - vector product of sparse matrix **Asp and vector x.
int G_math_add_spvector(G_math_spvector **, G_math_spvector *, int)
Adds a sparse vector to a sparse matrix at position row.
void G_math_d_Ax(double **, double *, double *, int, int)
Compute the matrix - vector product of matrix A and vector x.
#define UNUSED
A macro for an attribute, if attached to a variable, indicating that the variable is not used.
CELL N_get_array_2d_c_value(N_array_2d *data, int col, int row)
Returns the value of type CELL at position col, row.
void N_free_array_3d(N_array_3d *data)
Release the memory of a N_array_3d.
DCELL N_get_array_2d_d_value(N_array_2d *data, int col, int row)
Returns the value of type DCELL at position col, row.
N_array_3d * N_alloc_array_3d(int cols, int rows, int depths, int offset, int type)
Allocate memory for a N_array_3d data structure.
N_array_2d * N_alloc_array_2d(int cols, int rows, int offset, int type)
Allocate memory for a N_array_2d data structure.
void N_free_array_2d(N_array_2d *data)
Release the memory of a N_array_2d structure.
void N_put_array_3d_d_value(N_array_3d *data, int col, int row, int depth, double value)
Writes a double value to the N_array_3d struct at position col, row, depth.
double N_get_array_3d_d_value(N_array_3d *data, int col, int row, int depth)
This function returns the value of type float at position col, row, depth.
void N_put_array_2d_c_value(N_array_2d *data, int col, int row, CELL value)
Writes a CELL value to the N_array_2d struct at position col, row.
N_les * N_alloc_les_Ax_b(int rows, int type)
Allocate memory for a quadratic linear equation system which includes the Matrix A,...
N_data_star * N_alloc_27star(void)
allocate a 27 point star data structure
N_les * N_assemble_les_2d_dirichlet(int les_type, N_geom_data *geom, N_array_2d *status, N_array_2d *start_val, void *data, N_les_callback_2d *call)
Assemble a linear equation system (les) based on 2d location data (raster) and active and dirichlet c...
N_data_star * N_alloc_9star(void)
allocate a 9 point star data structure
N_les * N_assemble_les_2d_param(int les_type, N_geom_data *geom, N_array_2d *status, N_array_2d *start_val, void *data, N_les_callback_2d *call, int cell_type)
Assemble a linear equation system (les) based on 2d location data (raster)
N_les * N_assemble_les_3d_param(int les_type, N_geom_data *geom, N_array_3d *status, N_array_3d *start_val, void *data, N_les_callback_3d *call, int cell_type)
Assemble a linear equation system (les) based on 3d location data (g3d)
int N_les_integrate_dirichlet_3d(N_les *les, N_geom_data *geom, N_array_3d *status, N_array_3d *start_val)
Integrate Dirichlet or Transmission boundary conditions into the les (3d)
N_les_callback_3d * N_alloc_les_callback_3d(void)
Allocate the structure holding the callback function.
N_les * N_assemble_les_2d(int les_type, N_geom_data *geom, N_array_2d *status, N_array_2d *start_val, void *data, N_les_callback_2d *call)
Assemble a linear equation system (les) based on 2d location data (raster) and active cells.
N_data_star * N_create_9star(double C, double W, double E, double N, double S, double NW, double SW, double NE, double SE, double V)
allocate and initialize a 9 point star data structure
N_les * N_assemble_les_3d_active(int les_type, N_geom_data *geom, N_array_3d *status, N_array_3d *start_val, void *data, N_les_callback_3d *call)
Assemble a linear equation system (les) based on 3d location data (g3d) active cells.
int N_les_integrate_dirichlet_2d(N_les *les, N_geom_data *geom, N_array_2d *status, N_array_2d *start_val)
Integrate Dirichlet or Transmission boundary conditions into the les (2s)
N_les_callback_2d * N_alloc_les_callback_2d(void)
Allocate the structure holding the callback function.
N_les * N_assemble_les_2d_active(int les_type, N_geom_data *geom, N_array_2d *status, N_array_2d *start_val, void *data, N_les_callback_2d *call)
Assemble a linear equation system (les) based on 2d location data (raster) and active cells.
N_data_star * N_callback_template_3d(void *data UNUSED, N_geom_data *geom, int col UNUSED, int row UNUSED, int depth UNUSED)
A callback template creates a 7 point star structure.
N_data_star * N_callback_template_2d(void *data UNUSED, N_geom_data *geom, int col UNUSED, int row UNUSED)
A callback template creates a 9 point star structure.
N_data_star * N_alloc_7star(void)
allocate a 7 point star data structure
N_data_star * N_create_27star(double C, double W, double E, double N, double S, double NW, double SW, double NE, double SE, double T, double W_T, double E_T, double N_T, double S_T, double NW_T, double SW_T, double NE_T, double SE_T, double B, double W_B, double E_B, double N_B, double S_B, double NW_B, double SW_B, double NE_B, double SE_B, double V)
allocate and initialize a 27 point star data structure
N_les * N_assemble_les_3d_dirichlet(int les_type, N_geom_data *geom, N_array_3d *status, N_array_3d *start_val, void *data, N_les_callback_3d *call)
Assemble a linear equation system (les) based on 3d location data (g3d) active and dirichlet cells.
N_data_star * N_alloc_5star(void)
allocate a 5 point star data structure
N_les * N_assemble_les_3d(int les_type, N_geom_data *geom, N_array_3d *status, N_array_3d *start_val, void *data, N_les_callback_3d *call)
Assemble a linear equation system (les) based on 3d location data (g3d) active cells.
void N_set_les_callback_3d_func(N_les_callback_3d *data, N_data_star *(*callback_func_3d)(void *, N_geom_data *, int, int, int))
Set the callback function which is called while assembling the les in 3d.
void N_set_les_callback_2d_func(N_les_callback_2d *data, N_data_star *(*callback_func_2d)(void *, N_geom_data *, int, int))
Set the callback function which is called while assembling the les in 2d.
N_data_star * N_create_7star(double C, double W, double E, double N, double S, double T, double B, double V)
allocate and initialize a 7 point star data structure
N_data_star * N_create_5star(double C, double W, double E, double N, double S, double V)
allocate and initialize a 5 point star data structure
The row vector of the sparse matrix.
Matrix entries for a mass balance 5/7/9 star system.
Geometric information about the structured grid.
callback structure for 2d matrix assembling
N_data_star *(* callback)(void *, N_geom_data *, int, int)
callback structure for 3d matrix assembling
N_data_star *(* callback)(void *, N_geom_data *, int, int, int)
The linear equation system (les) structure.