GRASS 8 Programmer's Manual 8.6.0dev(2026)-c83afef6d3
Loading...
Searching...
No Matches
n_gradient_calc.c
Go to the documentation of this file.
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: gradient management functions
8 * part of the gpde library
9 *
10 * SPDX-FileCopyrightText: 2000 GRASS Development Team
11 * SPDX-License-Identifier: GPL-2.0-or-later
12 *
13 *****************************************************************************/
14
15#include <grass/N_pde.h>
16
17/*! \brief Calculate basic statistics of a gradient field
18 *
19 * The statistic is stored in the gradient field struct
20 *
21 * \param field N_gradient_2d_field *
22 * \return void
23 *
24 * */
26{
27 double minx, miny;
28 double maxx, maxy;
29 double sumx, sumy;
30 int nonullx, nonully;
31
32 G_debug(3, "N_calc_gradient_field_2d_stats: compute gradient field stats");
33
36
37 if (minx < miny)
38 field->min = minx;
39 else
40 field->min = miny;
41
42 if (maxx > maxy)
43 field->max = maxx;
44 else
45 field->max = maxy;
46
47 field->sum = sumx + sumy;
48 field->nonull = nonullx + nonully;
49 field->mean = field->sum / (double)field->nonull;
50
51 return;
52}
53
54/*!
55 * \brief This function computes the gradient based on the input N_array_2d pot
56 * (potential), a weighting factor N_array_2d named weight and the distance
57 between two cells
58 * saved in the N_geom_data struct.
59 *
60 * The gradient is calculated between cells for each cell and direction.
61 * An existing gradient field can be filled with new data or, if a NULL pointer
62 is
63 * given, a new gradient field will be allocated with the appropriate size.
64 *
65 *
66 \verbatim
67 ______________
68 | | | |
69 | | | |
70 |----|-NC-|----|
71 | | | |
72 | WC EC |
73 | | | |
74 |----|-SC-|----|
75 | | | |
76 |____|____|____|
77
78
79 x - direction:
80
81 r = 2 * weight[row][col]*weight[row][col + 1] /
82 (weight[row][col]*weight[row][col + 1]) EC = r * (pot[row][col] - pot[row][col
83 + 1])/dx
84
85 y - direction:
86
87 r = 2 * weight[row][col]*weight[row + 1][col] / (weight[row][col]*weight[row +
88 1][col]) SC = r * (pot[row][col] - pot[row + 1][col])/dy
89
90 the values SC and EC are the values of the next row/col
91
92
93 \endverbatim
94 * \param pot N_array_2d * - the potential N_array_2d
95 * \param weight_x N_array_2d * - the weighting factor N_array_2d used to modify
96 the gradient in x-direction
97 * \param weight_y N_array_2d * - the weighting factor N_array_2d used to modify
98 the gradient in y-direction
99 * \param geom N_geom_data * - geometry data structure
100 * \param gradfield N_gradient_field_2d * - a gradient field of the correct
101 size, if a NULL pointer is provided this gradient field will be new allocated
102 * \return N_gradient_field_2d * - the pointer to the computed gradient field
103
104 *
105 * */
111{
112 int i, j;
113 int rows, cols;
114 double dx, dy, p1, p2, r1, r2, mean, grad, res;
116
117 if (pot->cols != weight_x->cols || pot->cols != weight_y->cols)
119 "N_compute_gradient_field_2d: the arrays are not of equal size");
120
121 if (pot->rows != weight_x->rows || pot->rows != weight_y->rows)
123 "N_compute_gradient_field_2d: the arrays are not of equal size");
124
125 if (pot->cols != geom->cols || pot->rows != geom->rows)
126 G_fatal_error("N_compute_gradient_field_2d: array sizes and geometry "
127 "data are different");
128
129 G_debug(3, "N_compute_gradient_field_2d: compute gradient field");
130
131 rows = pot->rows;
132 cols = pot->cols;
133 dx = geom->dx;
134 dy = geom->dy;
135
136 if (field == NULL) {
137 field = N_alloc_gradient_field_2d(cols, rows);
138 }
139 else {
140 if (field->cols != geom->cols || field->rows != geom->rows)
141 G_fatal_error("N_compute_gradient_field_2d: gradient field sizes "
142 "and geometry data are different");
143 }
144
145 for (j = 0; j < rows; j++)
146 for (i = 0; i < cols - 1; i++) {
147 grad = 0;
148 mean = 0;
149
150 /* Only compute if the arrays are not null */
151 if (!N_is_array_2d_value_null(pot, i, j) &&
152 !N_is_array_2d_value_null(pot, i + 1, j)) {
154 p2 = N_get_array_2d_d_value(pot, i + 1, j);
155 grad = (p1 - p2) / dx; /* gradient */
156 }
161 mean = N_calc_harmonic_mean(r1, r2); /*harmonical mean */
162 }
163
164 res = mean * grad;
165
166 N_put_array_2d_d_value(field->x_array, i + 1, j, res);
167 }
168
169 for (j = 0; j < rows - 1; j++)
170 for (i = 0; i < cols; i++) {
171 grad = 0;
172 mean = 0;
173
174 /* Only compute if the arrays are not null */
175 if (!N_is_array_2d_value_null(pot, i, j) &&
176 !N_is_array_2d_value_null(pot, i, j + 1)) {
178 p2 = N_get_array_2d_d_value(pot, i, j + 1);
179 grad = (p1 - p2) / dy; /* gradient */
180 }
185 mean = N_calc_harmonic_mean(r1, r2); /*harmonical mean */
186 }
187
188 res = -1 * mean * grad;
189
190 N_put_array_2d_d_value(field->y_array, i, j + 1, res);
191 }
192
193 /*Compute gradient field statistics */
195
196 return field;
197}
198
199/*!
200 * \brief Calculate the x and y vector components from a gradient field for each
201 * cell and stores them in the provided N_array_2d structures
202 *
203 * The arrays must have the same size as the gradient field.
204
205 \verbatim
206
207 Based on this storages scheme the gradient vector for each cell is
208 calculated and stored in the provided N_array_2d structures
209
210 ______________
211 | | | |
212 | | | |
213 |----|-NC-|----|
214 | | | |
215 | WC EC |
216 | | | |
217 |----|-SC-|----|
218 | | | |
219 |____|____|____|
220
221 x vector component:
222
223 x = (WC + EC) / 2
224
225 y vector component:
226
227 y = (NC + SC) / 2
228
229 \endverbatim
230 *
231 * \param field N_gradient_field_2d *
232 * \param x_comp N_array_2d * - the array in which the x component will be
233 written
234 * \param y_comp N_array_2d * - the array in which the y component will be
235 written
236 *
237 * \return void
238 * */
242{
243 int i, j;
244
245 int rows, cols;
246
247 double vx, vy;
248
250
251 N_array_2d *y = y_comp;
252
253 N_gradient_2d grad;
254
255 if (!x)
256 G_fatal_error("N_compute_gradient_components_2d: x array is empty");
257 if (!y)
258 G_fatal_error("N_compute_gradient_components_2d: y array is empty");
259
260 cols = field->x_array->cols;
261 rows = field->x_array->rows;
262
263 /*Check the array sizes */
264 if (x->cols != cols || x->rows != rows)
265 G_fatal_error("N_compute_gradient_components_2d: the size of the x "
266 "array doesn't fit the gradient field size");
267 if (y->cols != cols || y->rows != rows)
268 G_fatal_error("N_compute_gradient_components_2d: the size of the y "
269 "array doesn't fit the gradient field size");
270
271 for (j = 0; j < rows; j++)
272 for (i = 0; i < cols; i++) {
273 N_get_gradient_2d(field, &grad, i, j);
274
275 /* in case a gradient is zero, we expect a no flow boundary */
276 if (grad.WC == 0.0 || grad.EC == 0.0)
277 vx = (grad.WC + grad.EC);
278 else
279 vx = (grad.WC + grad.EC) / 2;
280 if (grad.NC == 0.0 || grad.SC == 0.0)
281 vy = (grad.NC + grad.SC);
282 else
283 vy = (grad.NC + grad.SC) / 2;
284
287 }
288
289 return;
290}
291
292/*! \brief Calculate basic statistics of a gradient field
293 *
294 * The statistic is stored in the gradient field struct
295 *
296 * \param field N_gradient_3d_field *
297 * \return void
298 *
299 * */
301{
302 double minx, miny, minz;
303
304 double maxx, maxy, maxz;
305
306 double sumx, sumy, sumz;
307
308 int nonullx, nonully, nonullz;
309
310 G_debug(3, "N_calc_gradient_field_3d_stats: compute gradient field stats");
311
315
316 if (minx <= minz && minx <= miny)
317 field->min = minx;
318 if (miny <= minz && miny <= minx)
319 field->min = miny;
320 if (minz <= minx && minz <= miny)
321 field->min = minz;
322
323 if (maxx >= maxz && maxx >= maxy)
324 field->max = maxx;
325 if (maxy >= maxz && maxy >= maxx)
326 field->max = maxy;
327 if (maxz >= maxx && maxz >= maxy)
328 field->max = maxz;
329
330 field->sum = sumx + sumy + sumz;
331 field->nonull = nonullx + nonully + nonullz;
332 field->mean = field->sum / (double)field->nonull;
333
334 return;
335}
336
337/*!
338 * \brief This function computes the gradient based on the input N_array_3d pot
339 * (that means potential), a weighting factor N_array_3d named weight and the
340 distance between two cells
341 * saved in the N_geom_data struct.
342 *
343 * The gradient is calculated between cells for each cell and direction.
344 * An existing gradient field can be filled with new data or, if a NULL pointer
345 is
346 * given, a new gradient field will be allocated with the appropriate size.
347 *
348 *
349 *
350 *
351 \verbatim
352
353 | /
354 TC NC
355 |/
356 --WC-----EC--
357 /|
358 SC BC
359 / |
360
361 x - direction:
362
363 r = 2 * weight_x[depth][row][col]*weight_x[depth][row][col + 1] /
364 (weight_X[depth][row][col]*weight_x[depth][row][col + 1]) EC = r *
365 (pot[depth][row][col] - pot[depth][row][col + 1])/dx
366
367 y - direction:
368
369 r = 2 * weight_y[depth][row][col]*weight_y[depth][row + 1][col] /
370 (weight_y[depth][row][col]*weight_y[depth][row + 1][col]) SC = r *
371 (pot[depth][row][col] - pot[depth][row + 1][col])/dy
372
373 z - direction:
374
375 r = 2 * weight_z[depth][row][col]*weight_z[depth + 1][row][col] /
376 (weight_z[depth][row][col]*weight_z[depth + 1][row][col]) TC = r *
377 (pot[depth][row][col] - pot[depth + 1][row][col])/dy
378
379 the values BC, NC, WC are the values of the next depth/row/col
380
381
382 \endverbatim
383 * \param pot N_array_3d * - the potential N_array_2d
384 * \param weight_x N_array_3d * - the weighting factor N_array_3d used to modify
385 the gradient in x-direction
386 * \param weight_y N_array_3d * - the weighting factor N_array_3d used to modify
387 the gradient in y-direction
388 * \param weight_z N_array_3d * - the weighting factor N_array_3d used to modify
389 the gradient in z-direction
390 * \param geom N_geom_data * - geometry data structure
391 * \param gradfield N_gradient_field_3d * - a gradient field of the correct
392 size, if a NULL pointer is provided this gradient field will be new allocated
393 * \return N_gradient_field_3d * - the pointer to the computed gradient field
394 *
395 * */
400{
401 int i, j, k;
402
403 int cols, rows, depths;
404
405 double dx, dy, dz, p1, p2, r1, r2, mean, grad, res;
406
408
409 if (pot->cols != weight_x->cols || pot->cols != weight_y->cols ||
410 pot->cols != weight_z->cols)
412 "N_compute_gradient_field_3d: the arrays are not of equal size");
413
414 if (pot->rows != weight_x->rows || pot->rows != weight_y->rows ||
415 pot->rows != weight_z->rows)
417 "N_compute_gradient_field_3d: the arrays are not of equal size");
418
419 if (pot->depths != weight_x->depths || pot->depths != weight_y->depths ||
420 pot->depths != weight_z->depths)
422 "N_compute_gradient_field_3d: the arrays are not of equal size");
423
424 if (pot->cols != geom->cols || pot->rows != geom->rows ||
425 pot->depths != geom->depths)
426 G_fatal_error("N_compute_gradient_field_3d: array sizes and geometry "
427 "data are different");
428
429 G_debug(3, "N_compute_gradient_field_3d: compute gradient field");
430
431 cols = geom->cols;
432 rows = geom->rows;
433 depths = geom->depths;
434 dx = geom->dx;
435 dy = geom->dy;
436 dz = geom->dz;
437
438 if (gradfield == NULL) {
439 field = N_alloc_gradient_field_3d(cols, rows, depths);
440 }
441 else {
442 if (field->cols != geom->cols || field->rows != geom->rows ||
443 field->depths != geom->depths)
444 G_fatal_error("N_compute_gradient_field_3d: gradient field sizes "
445 "and geometry data are different");
446 }
447
448 for (k = 0; k < depths; k++)
449 for (j = 0; j < rows; j++)
450 for (i = 0; i < cols - 1; i++) {
451 grad = 0;
452 mean = 0;
453
454 /*Only compute if the arrays are not null */
455 if (!N_is_array_3d_value_null(pot, i, j, k) &&
456 !N_is_array_3d_value_null(pot, i + 1, j, k)) {
457 p1 = N_get_array_3d_d_value(pot, i, j, k);
458 p2 = N_get_array_3d_d_value(pot, i + 1, j, k);
459 grad = (p1 - p2) / dx; /* gradient */
460 }
461 if (!N_is_array_3d_value_null(weight_x, i, j, k) &&
462 !N_is_array_3d_value_null(weight_x, i + 1, j, k)) {
464 r2 = N_get_array_3d_d_value(weight_x, i + 1, j, k);
465 mean = N_calc_harmonic_mean(r1, r2); /*harmonical mean */
466 }
467
468 res = mean * grad;
469
470 G_debug(6,
471 "N_compute_gradient_field_3d: X-direction insert value "
472 "%6.5g at %i %i %i ",
473 res, k, j, i + 1);
474
475 N_put_array_3d_d_value(field->x_array, i + 1, j, k, res);
476 }
477
478 for (k = 0; k < depths; k++)
479 for (j = 0; j < rows - 1; j++)
480 for (i = 0; i < cols; i++) {
481 grad = 0;
482 mean = 0;
483
484 /* Only compute if the arrays are not null */
485 if (!N_is_array_3d_value_null(pot, i, j, k) &&
486 !N_is_array_3d_value_null(pot, i, j + 1, k)) {
487 p1 = N_get_array_3d_d_value(pot, i, j, k);
488 p2 = N_get_array_3d_d_value(pot, i, j + 1, k);
489 grad = (p1 - p2) / dy; /* gradient */
490 }
491 if (!N_is_array_3d_value_null(weight_y, i, j, k) &&
492 !N_is_array_3d_value_null(weight_y, i, j + 1, k)) {
494 r2 = N_get_array_3d_d_value(weight_y, i, j + 1, k);
495 mean = N_calc_harmonic_mean(r1, r2); /*harmonical mean */
496 }
497
498 res = -1 * mean * grad; /*invert the direction, because we count
499 * from north to south, but the gradient
500 * is defined in y direction */
501
502 G_debug(6,
503 "N_compute_gradient_field_3d: Y-direction insert value "
504 "%6.5g at %i %i %i ",
505 res, k, j + 1, i);
506
507 N_put_array_3d_d_value(field->y_array, i, j + 1, k, res);
508 }
509
510 for (k = 0; k < depths - 1; k++)
511 for (j = 0; j < rows; j++)
512 for (i = 0; i < cols; i++) {
513 grad = 0;
514 mean = 0;
515
516 /* Only compute if the arrays are not null */
517 if (!N_is_array_3d_value_null(pot, i, j, k) &&
518 !N_is_array_3d_value_null(pot, i, j, k + 1)) {
519 p1 = N_get_array_3d_d_value(pot, i, j, k);
520 p2 = N_get_array_3d_d_value(pot, i, j, k + 1);
521 grad = (p1 - p2) / dz; /* gradient */
522 }
523 if (!N_is_array_3d_value_null(weight_z, i, j, k) &&
524 !N_is_array_3d_value_null(weight_z, i, j, k + 1)) {
526 r2 = N_get_array_3d_d_value(weight_z, i, j, k + 1);
527 mean = N_calc_harmonic_mean(r1, r2); /*harmonical mean */
528 }
529
530 res = mean * grad;
531
532 G_debug(6,
533 "N_compute_gradient_field_3d: Z-direction insert value "
534 "%6.5g at %i %i %i ",
535 res, k + 1, j, i);
536
537 N_put_array_3d_d_value(field->z_array, i, j, k + 1, res);
538 }
539
540 /*Compute gradient field statistics */
542
543 return field;
544}
545
546/*!
547 * \brief Calculate the x, y and z vector components from a gradient field for
548 each cell
549 * and store them in the provided N_array_3d structures
550 *
551 * The arrays must have the same size as the gradient field.
552 *
553 \verbatim
554
555 Based on this storages scheme the gradient vector for each cell is
556 calculated and stored in the provided N_array_3d structures
557
558
559 | /
560 TC NC
561 |/
562 --WC-----EC--
563 /|
564 SC BC
565 / |
566
567
568 x vector component:
569
570 x = (WC + EC) / 2
571
572 y vector component:
573
574 y = (NC + SC) / 2
575
576 z vector component:
577
578 z = (TC + BC) / 2
579
580 \endverbatim
581
582 * \param field N_gradient_field_3d *
583 * \param x_comp N_array_3d * - the array in which the x component will be
584 written
585 * \param y_comp N_array_3d * - the array in which the y component will be
586 written
587 * \param z_comp N_array_3d * - the array in which the z component will be
588 written
589 *
590 * \return void
591 * */
596{
597 int i, j, k;
598
599 int rows, cols, depths;
600
601 double vx, vy, vz;
602
604
605 N_array_3d *y = y_comp;
606
607 N_array_3d *z = z_comp;
608
609 N_gradient_3d grad;
610
611 if (!x)
612 G_fatal_error("N_compute_gradient_components_3d: x array is empty");
613 if (!y)
614 G_fatal_error("N_compute_gradient_components_3d: y array is empty");
615 if (!z)
616 G_fatal_error("N_compute_gradient_components_3d: z array is empty");
617
618 cols = field->x_array->cols;
619 rows = field->x_array->rows;
620 depths = field->x_array->depths;
621
622 /*Check the array sizes */
623 if (x->cols != cols || x->rows != rows || x->depths != depths)
624 G_fatal_error("N_compute_gradient_components_3d: the size of the x "
625 "array doesn't fit the gradient field size");
626 if (y->cols != cols || y->rows != rows || y->depths != depths)
627 G_fatal_error("N_compute_gradient_components_3d: the size of the y "
628 "array doesn't fit the gradient field size");
629 if (z->cols != cols || z->rows != rows || z->depths != depths)
630 G_fatal_error("N_compute_gradient_components_3d: the size of the z "
631 "array doesn't fit the gradient field size");
632
633 for (k = 0; k < depths; k++)
634 for (j = 0; j < rows; j++)
635 for (i = 0; i < cols; i++) {
636 N_get_gradient_3d(field, &grad, i, j, k);
637 /* in case a gradient is zero, we expect a no flow boundary */
638 if (grad.WC == 0.0 || grad.EC == 0.0)
639 vx = (grad.WC + grad.EC);
640 else
641 vx = (grad.WC + grad.EC) / 2;
642 if (grad.NC == 0.0 || grad.SC == 0.0)
643 vy = (grad.NC + grad.SC);
644 else
645 vy = (grad.NC + grad.SC) / 2;
646 if (grad.TC == 0.0 || grad.BC == 0.0)
647 vz = (grad.TC + grad.BC);
648 else
649 vz = (grad.TC + grad.BC) / 2;
650
651 N_put_array_3d_d_value(x, i, j, k, vx);
652 N_put_array_3d_d_value(y, i, j, k, vy);
653 N_put_array_3d_d_value(z, i, j, k, vz);
654 }
655
656 return;
657}
double N_calc_harmonic_mean(double a, double b)
Calculate the harmonical mean of values a and b.
Definition n_tools.c:112
#define NULL
Definition ccmath.h:32
void void void void G_fatal_error(const char *,...) __attribute__((format(printf
int G_debug(int, const char *,...) __attribute__((format(printf
float mean(IClass_statistics *statistics, int band)
Helper function for computing mean.
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.
Definition n_arrays.c:377
int N_is_array_3d_value_null(N_array_3d *data, int col, int row, int depth)
This function returns 1 if value of N_array_3d data at position col, row, depth is of type null,...
Definition n_arrays.c:870
int N_is_array_2d_value_null(N_array_2d *data, int col, int row)
Returns 1 if the value of N_array_2d struct at position col, row is of type null, otherwise 0.
Definition n_arrays.c:228
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.
Definition n_arrays.c:1145
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.
Definition n_arrays.c:976
void N_put_array_2d_d_value(N_array_2d *data, int col, int row, DCELL value)
Writes a DCELL value to the N_array_2d struct at position col, row.
Definition n_arrays.c:573
void N_calc_array_3d_stats(N_array_3d *a, double *min, double *max, double *sum, int *nonull, int withoffset)
Calculate basic statistics of the N_array_3d struct.
void N_calc_array_2d_stats(N_array_2d *a, double *min, double *max, double *sum, int *nonull, int withoffset)
Calculate basic statistics of the N_array_2d struct.
N_gradient_field_2d * N_alloc_gradient_field_2d(int cols, int rows)
Allocate a N_gradient_field_2d.
Definition n_gradient.c:893
N_gradient_field_3d * N_alloc_gradient_field_3d(int cols, int rows, int depths)
Allocate a N_gradient_field_3d.
Definition n_gradient.c:990
N_gradient_2d * N_get_gradient_2d(N_gradient_field_2d *field, N_gradient_2d *gradient, int col, int row)
Return a N_gradient_2d structure calculated from the input gradient field at position [row][col].
Definition n_gradient.c:111
N_gradient_3d * N_get_gradient_3d(N_gradient_field_3d *field, N_gradient_3d *gradient, int col, int row, int depth)
Return a N_gradient_3d structure calculated from the input gradient field at position [depth][row][co...
Definition n_gradient.c:243
N_gradient_field_2d * N_compute_gradient_field_2d(N_array_2d *pot, N_array_2d *weight_x, N_array_2d *weight_y, N_geom_data *geom, N_gradient_field_2d *gradfield)
This function computes the gradient based on the input N_array_2d pot (potential),...
void N_compute_gradient_field_components_3d(N_gradient_field_3d *field, N_array_3d *x_comp, N_array_3d *y_comp, N_array_3d *z_comp)
Calculate the x, y and z vector components from a gradient field for each cell and store them in the ...
void N_compute_gradient_field_components_2d(N_gradient_field_2d *field, N_array_2d *x_comp, N_array_2d *y_comp)
Calculate the x and y vector components from a gradient field for each cell and stores them in the pr...
void N_calc_gradient_field_2d_stats(N_gradient_field_2d *field)
Calculate basic statistics of a gradient field.
N_gradient_field_3d * N_compute_gradient_field_3d(N_array_3d *pot, N_array_3d *weight_x, N_array_3d *weight_y, N_array_3d *weight_z, N_geom_data *geom, N_gradient_field_3d *gradfield)
This function computes the gradient based on the input N_array_3d pot (that means potential),...
void N_calc_gradient_field_3d_stats(N_gradient_field_3d *field)
Calculate basic statistics of a gradient field.
int cols
Definition N_pde.h:131
int rows
Definition N_pde.h:131
int rows
Definition N_pde.h:174
int depths
Definition N_pde.h:174
int cols
Definition N_pde.h:174
Geometric information about the structured grid.
Definition N_pde.h:98
Gradient between the cells in X and Y direction.
Definition N_pde.h:454
double EC
Definition N_pde.h:456
double SC
Definition N_pde.h:456
double WC
Definition N_pde.h:456
double NC
Definition N_pde.h:456
Gradient between the cells in X, Y and Z direction.
Definition N_pde.h:461
double WC
Definition N_pde.h:463
double NC
Definition N_pde.h:463
double EC
Definition N_pde.h:463
double SC
Definition N_pde.h:463
double BC
Definition N_pde.h:463
double TC
Definition N_pde.h:463
N_array_2d * y_array
Definition N_pde.h:559
N_array_2d * x_array
Definition N_pde.h:558
N_array_3d * y_array
Definition N_pde.h:570
N_array_3d * x_array
Definition N_pde.h:569
N_array_3d * z_array
Definition N_pde.h:571
#define x