GRASS 8 Programmer's Manual 8.6.0dev(2026)-4bb960b182
Loading...
Searching...
No Matches
n_les_assemble.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: functions to assemble a linear equation system
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 <math.h>
16#include <grass/N_pde.h>
17
18/* local protos */
19static int make_les_entry_2d(int i, int j, int offset_i, int offset_j,
20 int count, int pos, N_les *les,
23 double entry, int cell_type);
24
25static int make_les_entry_3d(int i, int j, int k, int offset_i, int offset_j,
26 int offset_k, int count, int pos, N_les *les,
29 double entry, int cell_type);
30
31/* *************************************************************** *
32 * ********************** N_alloc_5star ************************** *
33 * *************************************************************** */
34/*!
35 * \brief allocate a 5 point star data structure
36 *
37 * \return N_data_star *
38 * */
40{
41 N_data_star *star = (N_data_star *)G_calloc(1, sizeof(N_data_star));
42
43 star->type = N_5_POINT_STAR;
44 star->count = 5;
45 return star;
46}
47
48/* *************************************************************** *
49 * ********************* N_alloc_7star *************************** *
50 * *************************************************************** */
51/*!
52 * \brief allocate a 7 point star data structure
53 *
54 * \return N_data_star *
55 * */
57{
58 N_data_star *star = (N_data_star *)G_calloc(1, sizeof(N_data_star));
59
60 star->type = N_7_POINT_STAR;
61 star->count = 7;
62 return star;
63}
64
65/* *************************************************************** *
66 * ********************* N_alloc_9star *************************** *
67 * *************************************************************** */
68/*!
69 * \brief allocate a 9 point star data structure
70 *
71 * \return N_data_star *
72 *
73 * \attention The 9 point start is not yet implemented in the matrix assembling
74 * function
75 *
76 * */
78{
79 N_data_star *star = (N_data_star *)G_calloc(1, sizeof(N_data_star));
80
81 star->type = N_9_POINT_STAR;
82 star->count = 9;
83 return star;
84}
85
86/* *************************************************************** *
87 * ********************* N_alloc_27star ************************** *
88 * *************************************************************** */
89/*!
90 * \brief allocate a 27 point star data structure
91 *
92 * \return N_data_star *
93 *
94 * \attention The 27 point start is not yet implemented in the matrix assembling
95 * function
96 *
97 * */
99{
100 N_data_star *star = (N_data_star *)G_calloc(1, sizeof(N_data_star));
101
102 star->type = N_27_POINT_STAR;
103 star->count = 27;
104 return star;
105}
106
107/* *************************************************************** *
108 * ********************** N_create_5star ************************* *
109 * *************************************************************** */
110/*!
111 * \brief allocate and initialize a 5 point star data structure
112 *
113 * \param C double
114 * \param W double
115 * \param E double
116 * \param N double
117 * \param S double
118 * \param V double
119 * \return N_data_star *
120 * */
121N_data_star *N_create_5star(double C, double W, double E, double N, double S,
122 double V)
123{
124 N_data_star *star = N_alloc_5star();
125
126 star->C = C;
127 star->W = W;
128 star->E = E;
129 star->N = N;
130 star->S = S;
131
132 star->V = V;
133
134 G_debug(5, "N_create_5star: w %g e %g n %g s %g c %g v %g\n", star->W,
135 star->E, star->N, star->S, star->C, star->V);
136
137 return star;
138}
139
140/* *************************************************************** *
141 * ************************* N_create_7star ********************** *
142 * *************************************************************** */
143/*!
144 * \brief allocate and initialize a 7 point star data structure
145 *
146 * \param C double
147 * \param W double
148 * \param E double
149 * \param N double
150 * \param S double
151 * \param T double
152 * \param B double
153 * \param V double
154 * \return N_data_star *
155 * */
156N_data_star *N_create_7star(double C, double W, double E, double N, double S,
157 double T, double B, double V)
158{
159 N_data_star *star = N_alloc_7star();
160
161 star->C = C;
162 star->W = W;
163 star->E = E;
164 star->N = N;
165 star->S = S;
166
167 star->T = T;
168 star->B = B;
169
170 star->V = V;
171
172 G_debug(5, "N_create_7star: w %g e %g n %g s %g t %g b %g c %g v %g\n",
173 star->W, star->E, star->N, star->S, star->T, star->B, star->C,
174 star->V);
175
176 return star;
177}
178
179/* *************************************************************** *
180 * ************************ N_create_9star *********************** *
181 * *************************************************************** */
182/*!
183 * \brief allocate and initialize a 9 point star data structure
184 *
185 * \param C double
186 * \param W double
187 * \param E double
188 * \param N double
189 * \param S double
190 * \param NW double
191 * \param SW double
192 * \param NE double
193 * \param SE double
194 * \param V double
195 * \return N_data_star *
196 * */
197N_data_star *N_create_9star(double C, double W, double E, double N, double S,
198 double NW, double SW, double NE, double SE,
199 double V)
200{
201 N_data_star *star = N_alloc_9star();
202
203 star->C = C;
204 star->W = W;
205 star->E = E;
206 star->N = N;
207 star->S = S;
208
209 star->NW = NW;
210 star->SW = SW;
211 star->NE = NE;
212 star->SE = SE;
213
214 star->V = V;
215
216 G_debug(5,
217 "N_create_9star: w %g e %g n %g s %g nw %g sw %g ne %g se %g c %g "
218 "v %g\n",
219 star->W, star->E, star->N, star->S, star->NW, star->SW, star->NE,
220 star->SE, star->C, star->V);
221
222 return star;
223}
224
225/* *************************************************************** *
226 * ************************ N_create_27star *********************** *
227 * *************************************************************** */
228/*!
229 * \brief allocate and initialize a 27 point star data structure
230 *
231 * \param C double
232 * \param W double
233 * \param E double
234 * \param N double
235 * \param S double
236 * \param NW double
237 * \param SW double
238 * \param NE double
239 * \param SE double
240 * \param T double
241 * \param W_T double
242 * \param E_T double
243 * \param N_T double
244 * \param S_T double
245 * \param NW_T double
246 * \param SW_T double
247 * \param NE_T double
248 * \param SE_T double
249 * \param B double
250 * \param W_B double
251 * \param E_B double
252 * \param N_B double
253 * \param S_B double
254 * \param NW_B double
255 * \param SW_B double
256 * \param NE_B double
257 * \param SE_B double
258 * \param V double
259 * \return N_data_star *
260 * */
261N_data_star *N_create_27star(double C, double W, double E, double N, double S,
262 double NW, double SW, double NE, double SE,
263 double T, double W_T, double E_T, double N_T,
264 double S_T, double NW_T, double SW_T, double NE_T,
265 double SE_T, double B, double W_B, double E_B,
266 double N_B, double S_B, double NW_B, double SW_B,
267 double NE_B, double SE_B, double V)
268{
269 N_data_star *star = N_alloc_27star();
270
271 star->C = C;
272 star->W = W;
273 star->E = E;
274 star->N = N;
275 star->S = S;
276
277 star->NW = NW;
278 star->SW = SW;
279 star->NE = NE;
280 star->SE = SE;
281
282 star->T = T;
283 star->W_T = W_T;
284 star->E_T = E_T;
285 star->N_T = N_T;
286 star->S_T = S_T;
287
288 star->NW_T = NW_T;
289 star->SW_T = SW_T;
290 star->NE_T = NE_T;
291 star->SE_T = SE_T;
292
293 star->B = B;
294 star->W_B = W_B;
295 star->E_B = E_B;
296 star->N_B = N_B;
297 star->S_B = S_B;
298
299 star->NW_B = NW_B;
300 star->SW_B = SW_B;
301 star->NE_B = NE_B;
302 star->SE_B = SE_B;
303
304 star->V = V;
305
306 G_debug(5,
307 "N_create_27star: w %g e %g n %g s %g nw %g sw %g ne %g se %g c "
308 "%g v %g\n",
309 star->W, star->E, star->N, star->S, star->NW, star->SW, star->NE,
310 star->SE, star->C, star->V);
311
312 G_debug(5,
313 "N_create_27star: w_t %g e_t %g n_t %g s_t %g nw_t %g sw_t %g "
314 "ne_t %g se_t %g t %g \n",
315 star->W_T, star->E_T, star->N_T, star->S_T, star->NW_T, star->SW_T,
316 star->NE_T, star->SE_T, star->T);
317
318 G_debug(5,
319 "N_create_27star: w_b %g e_b %g n_b %g s_b %g nw_b %g sw_b %g "
320 "ne_b %g se_B %g b %g\n",
321 star->W_B, star->E_B, star->N_B, star->S_B, star->NW_B, star->SW_B,
322 star->NE_B, star->SE_B, star->B);
323
324 return star;
325}
326
327/* *************************************************************** *
328 * ****************** N_set_les_callback_3d_func ***************** *
329 * *************************************************************** */
330/*!
331 * \brief Set the callback function which is called while assembling the les in
332 * 3d
333 *
334 * \param data N_les_callback_3d *
335 * \param callback_func_3d N_data_star *
336 * \return void
337 * */
339 N_data_star *(*callback_func_3d)(void *,
340 N_geom_data *,
341 int, int, int))
342{
344}
345
346/* *************************************************************** *
347 * *************** N_set_les_callback_2d_func ******************** *
348 * *************************************************************** */
349/*!
350 * \brief Set the callback function which is called while assembling the les in
351 * 2d
352 *
353 * \param data N_les_callback_2d *
354 * \param callback_func_2d N_data_star *
355 * \return void
356 * */
358 N_data_star *(*callback_func_2d)(void *,
359 N_geom_data *,
360 int, int))
361{
363}
364
365/* *************************************************************** *
366 * ************** N_alloc_les_callback_3d ************************ *
367 * *************************************************************** */
368/*!
369 * \brief Allocate the structure holding the callback function
370 *
371 * A template callback is set. Use N_set_les_callback_3d_func
372 * to set up a specific function.
373 *
374 * \return N_les_callback_3d *
375 * */
377{
379
381 call->callback = N_callback_template_3d;
382
383 return call;
384}
385
386/* *************************************************************** *
387 * *************** N_alloc_les_callback_2d *********************** *
388 * *************************************************************** */
389/*!
390 * \brief Allocate the structure holding the callback function
391 *
392 * A template callback is set. Use N_set_les_callback_2d_func
393 * to set up a specific function.
394 *
395 * \return N_les_callback_2d *
396 * */
398{
400
402 call->callback = N_callback_template_2d;
403
404 return call;
405}
406
407/* *************************************************************** *
408 * ******************** N_callback_template_3d ******************* *
409 * *************************************************************** */
410/*!
411 * \brief A callback template creates a 7 point star structure
412 *
413 * This is a template callback for mass balance calculation with 7 point stars
414 * based on 3d data (g3d).
415 *
416 * \param data void * (unused)
417 * \param geom N_geom_data *
418 * \param depth int (unused)
419 * \param row int (unused)
420 * \param col int (unused)
421 * \return N_data_star *
422 *
423 * */
425 int col G_UNUSED, int row G_UNUSED,
426 int depth G_UNUSED)
427{
428 N_data_star *star = N_alloc_7star();
429
430 star->E = 1 / geom->dx;
431 star->W = 1 / geom->dx;
432 star->N = 1 / geom->dy;
433 star->S = 1 / geom->dy;
434 star->T = 1 / geom->dz;
435 star->B = 1 / geom->dz;
436 star->C = -1 * (2 / geom->dx + 2 / geom->dy + 2 / geom->dz);
437 star->V = -1;
438
439 G_debug(
440 5, "N_callback_template_3d: w %g e %g n %g s %g t %g b %g c %g v %g\n",
441 star->W, star->E, star->N, star->S, star->T, star->B, star->C, star->V);
442
443 return star;
444}
445
446/* *************************************************************** *
447 * ********************* N_callback_template_2d ****************** *
448 * *************************************************************** */
449/*!
450 * \brief A callback template creates a 9 point star structure
451 *
452 * This is a template callback for mass balance calculation with 9 point stars
453 * based on 2d data (raster).
454 *
455 * \param data void * (unused)
456 * \param geom N_geom_data *
457 * \param col int (unused)
458 * \param row int (unused)
459 * \return N_data_star *
460 *
461 * */
463 int col G_UNUSED, int row G_UNUSED)
464{
465 N_data_star *star = N_alloc_9star();
466
467 star->E = 1 / geom->dx;
468 star->NE = 1 / sqrt(geom->dx * geom->dx + geom->dy * geom->dy);
469 star->SE = 1 / sqrt(geom->dx * geom->dx + geom->dy * geom->dy);
470 star->W = 1 / geom->dx;
471 star->NW = 1 / sqrt(geom->dx * geom->dx + geom->dy * geom->dy);
472 star->SW = 1 / sqrt(geom->dx * geom->dx + geom->dy * geom->dy);
473 star->N = 1 / geom->dy;
474 star->S = 1 / geom->dy;
475 star->C = -1 * (star->E + star->NE + star->SE + star->W + star->NW +
476 star->SW + star->N + star->S);
477 star->V = 0;
478
479 return star;
480}
481
482/* *************************************************************** *
483 * ******************** N_assemble_les_2d ************************ *
484 * *************************************************************** */
485/*!
486 * \brief Assemble a linear equation system (les) based on 2d location data
487 * (raster) and active cells
488 *
489 * This function calls #N_assemble_les_2d_param
490 *
491 */
499
500/*!
501 * \brief Assemble a linear equation system (les) based on 2d location data
502 * (raster) and active cells
503 *
504 * This function calls #N_assemble_les_2d_param
505 *
506 */
514
515/*!
516 * \brief Assemble a linear equation system (les) based on 2d location data
517 * (raster) and active and dirichlet cells
518 *
519 * This function calls #N_assemble_les_2d_param
520 *
521 */
529
530/*!
531 * \brief Assemble a linear equation system (les) based on 2d location data
532 * (raster)
533 *
534 *
535 * The linear equation system type can be set to N_NORMAL_LES to create a
536 * regular matrix, or to N_SPARSE_LES to create a sparse matrix. This function
537 * returns a new created linear equation system which can be solved with linear
538 * equation solvers. An 2d array with start values and an 2d status array must
539 * be provided as well as the location geometry and a void pointer to data
540 * passed to the callback which creates the les row entries. This callback
541 * must be defined in the N_les_callback_2d structure.
542 *
543 * The creation of the les is parallelized with OpenMP.
544 * If you implement new callbacks, please make sure that the
545 * function calls are thread safe.
546 *
547 *
548 * the les can be created in two ways, with dirichlet and similar cells and
549 * without them, to spare some memory. If the les is created with dirichlet
550 * cell, the dirichlet boundary condition must be added.
551 *
552 * \param les_type int
553 * \param geom N_geom_data*
554 * \param status N_array_2d *
555 * \param start_val N_array_2d *
556 * \param data void *
557 * \param cell_type int -- les assemble based on N_CELL_ACTIVE or
558 * N_CELL_DIRICHLET \param call N_les_callback_2d * \return N_les *
559 * */
562 void *data, N_les_callback_2d *call,
563 int cell_type)
564{
565 int i, j, count = 0, pos = 0;
566 int cell_type_count = 0;
567 int **index_ij;
569 N_les *les = NULL;
570
571 G_debug(
572 2,
573 "N_assemble_les_2d: starting to assemble the linear equation system");
574
575 /* At first count the number of valid cells and save
576 * each number in a new 2d array. Those numbers are used
577 * to create the linear equation system.
578 * */
579
580 cell_count = N_alloc_array_2d(geom->cols, geom->rows, 1, CELL_TYPE);
581
582 /* include dirichlet cells in the les */
584 for (j = 0; j < geom->rows; j++) {
585 for (i = 0; i < geom->cols; i++) {
586 /*use all non-inactive cells for les creation */
587 if (N_CELL_INACTIVE < N_get_array_2d_c_value(status, i, j) &&
590 }
591 }
592 }
593 /*use only active cell in the les */
594 if (cell_type == N_CELL_ACTIVE) {
595 for (j = 0; j < geom->rows; j++) {
596 for (i = 0; i < geom->cols; i++) {
597 /*count only active cells */
598 if (N_CELL_ACTIVE == N_get_array_2d_d_value(status, i, j))
600 }
601 }
602 }
603
604 G_debug(2, "N_assemble_les_2d: number of used cells %i\n", cell_type_count);
605
606 if (cell_type_count == 0)
607 G_fatal_error("Not enough cells [%i] to create the linear equation "
608 "system. Check the cell status. Only active cells (value "
609 "= 1) are used to create the equation system.",
611
612 /* Then allocate the memory for the linear equation system (les).
613 * Only valid cells are used to create the les. */
614 index_ij = (int **)G_calloc(cell_type_count, sizeof(int *));
615 for (i = 0; i < cell_type_count; i++)
616 index_ij[i] = (int *)G_calloc(2, sizeof(int));
617
619
620 count = 0;
621
622 /*count the number of cells which should be used to create the linear
623 * equation system */
624 /*save the i and j indices and create a ordered numbering */
625 for (j = 0; j < geom->rows; j++) {
626 for (i = 0; i < geom->cols; i++) {
627 /*count every non-inactive cell */
629 if (N_CELL_INACTIVE < N_get_array_2d_c_value(status, i, j) &&
632 index_ij[count][0] = i;
633 index_ij[count][1] = j;
634 count++;
635 G_debug(5,
636 "N_assemble_les_2d: non-inactive cells count %i at "
637 "pos x[%i] y[%i]\n",
638 count, i, j);
639 }
640 /*count every active cell */
641 }
642 else if (N_CELL_ACTIVE == N_get_array_2d_c_value(status, i, j)) {
644 index_ij[count][0] = i;
645 index_ij[count][1] = j;
646 count++;
647 G_debug(5,
648 "N_assemble_les_2d: active cells count %i at pos x[%i] "
649 "y[%i]\n",
650 count, i, j);
651 }
652 }
653 }
654
655 G_debug(2, "N_assemble_les_2d: starting the parallel assemble loop");
656
657 /* Assemble the matrix in parallel */
658#pragma omp parallel for private(i, j, pos, count) schedule(static)
659 for (count = 0; count < cell_type_count; count++) {
660 i = index_ij[count][0];
661 j = index_ij[count][1];
662
663 /*create the entries for the */
664 N_data_star *items = call->callback(data, geom, i, j);
665
666 /* we need a sparse vector pointer anytime */
668
669 /*allocate a sprase vector */
670 if (les_type == N_SPARSE_LES) {
672 }
673 /* initial conditions */
675
676 /* the entry in the vector b */
677 les->b[count] = items->V;
678
679 /* pos describes the position in the sparse vector.
680 * the first entry is always the diagonal entry of the matrix*/
681 pos = 0;
682
683 if (les_type == N_SPARSE_LES) {
684 spvect->index[pos] = count;
685 spvect->values[pos] = items->C;
686 }
687 else {
688 les->A[count][count] = items->C;
689 }
690 /* western neighbour, entry is col - 1 */
691 if (i > 0) {
692 pos = make_les_entry_2d(i, j, -1, 0, count, pos, les, spvect,
693 cell_count, status, start_val, items->W,
694 cell_type);
695 }
696 /* eastern neighbour, entry col + 1 */
697 if (i < geom->cols - 1) {
698 pos = make_les_entry_2d(i, j, 1, 0, count, pos, les, spvect,
699 cell_count, status, start_val, items->E,
700 cell_type);
701 }
702 /* northern neighbour, entry row - 1 */
703 if (j > 0) {
704 pos = make_les_entry_2d(i, j, 0, -1, count, pos, les, spvect,
705 cell_count, status, start_val, items->N,
706 cell_type);
707 }
708 /* southern neighbour, entry row + 1 */
709 if (j < geom->rows - 1) {
710 pos = make_les_entry_2d(i, j, 0, 1, count, pos, les, spvect,
711 cell_count, status, start_val, items->S,
712 cell_type);
713 }
714 /*in case of a nine point star, we have additional entries */
715 if (items->type == N_9_POINT_STAR) {
716 /* north-western neighbour, entry is col - 1 row - 1 */
717 if (i > 0 && j > 0) {
718 pos = make_les_entry_2d(i, j, -1, -1, count, pos, les, spvect,
719 cell_count, status, start_val,
720 items->NW, cell_type);
721 }
722 /* north-eastern neighbour, entry col + 1 row - 1 */
723 if (i < geom->cols - 1 && j > 0) {
724 pos = make_les_entry_2d(i, j, 1, -1, count, pos, les, spvect,
725 cell_count, status, start_val,
726 items->NE, cell_type);
727 }
728 /* south-western neighbour, entry is col - 1 row + 1 */
729 if (i > 0 && j < geom->rows - 1) {
730 pos = make_les_entry_2d(i, j, -1, 1, count, pos, les, spvect,
731 cell_count, status, start_val,
732 items->SW, cell_type);
733 }
734 /* south-eastern neighbour, entry col + 1 row + 1 */
735 if (i < geom->cols - 1 && j < geom->rows - 1) {
736 pos = make_les_entry_2d(i, j, 1, 1, count, pos, les, spvect,
737 cell_count, status, start_val,
738 items->SE, cell_type);
739 }
740 }
741
742 /*How many entries in the les */
743 if (les->type == N_SPARSE_LES) {
744 spvect->cols = pos + 1;
746 }
747
748 if (items)
749 G_free(items);
750 }
751
752 /*release memory */
754
755 for (i = 0; i < cell_type_count; i++)
756 G_free(index_ij[i]);
757
759
760 return les;
761}
762
763/*!
764 * \brief Integrate Dirichlet or Transmission boundary conditions into the les
765 * (2s)
766 *
767 * Dirichlet and Transmission boundary conditions will be integrated into
768 * the provided linear equation system. This is meaningful if
769 * the les was created with #N_assemble_les_2d_dirichlet, because in
770 * this case Dirichlet boundary conditions are not automatically included.
771 *
772 * The provided les will be modified:
773 *
774 * Ax = b will be split into Ax_u + Ax_d = b
775 *
776 * x_u - the unknowns
777 * x_d - the Dirichlet cells
778 *
779 * Ax_u = b -Ax_d will be computed. Then the matrix A will be modified to
780 *
781 * | A_u 0 | x_u
782 * | 0 I | x_d
783 *
784 * \param les N_les* -- the linear equation system
785 * \param geom N_geom_data* -- geometrical data information
786 * \param status N_array_2d* -- the status array containing the cell types
787 * \param start_val N_array_2d* -- an array with start values
788 * \return int -- 1 = success, 0 = failure
789 * */
792{
793 int rows, cols;
794 int count = 0;
795 int i, j, x, y, stat;
796 double *dvect1;
797 double *dvect2;
798
799 G_debug(2, "N_les_integrate_dirichlet_2d: integrating the dirichlet "
800 "boundary condition");
801
802 rows = geom->rows;
803 cols = geom->cols;
804
805 /*we need to additional vectors */
806 dvect1 = (double *)G_calloc(les->cols, sizeof(double));
807 dvect2 = (double *)G_calloc(les->cols, sizeof(double));
808
809 /*fill the first one with the x vector data of Dirichlet cells */
810 count = 0;
811 for (y = 0; y < rows; y++) {
812 for (x = 0; x < cols; x++) {
813 stat = N_get_array_2d_c_value(status, x, y);
816 count++;
817 }
818 else if (stat == N_CELL_ACTIVE) {
819 dvect1[count] = 0.0;
820 count++;
821 }
822 }
823 }
824
825#pragma omp parallel default(shared)
826 {
827 /*perform the matrix vector product and */
828 if (les->type == N_SPARSE_LES)
829 G_math_Ax_sparse(les->Asp, dvect1, dvect2, les->rows);
830 else
831 G_math_d_Ax(les->A, dvect1, dvect2, les->rows, les->cols);
832#pragma omp for schedule(static) private(i)
833 for (i = 0; i < les->cols; i++)
834 les->b[i] = les->b[i] - dvect2[i];
835 }
836
837 /*now set the Dirichlet cell rows and cols to zero and the
838 * diagonal entry to 1*/
839 count = 0;
840 for (y = 0; y < rows; y++) {
841 for (x = 0; x < cols; x++) {
842 stat = N_get_array_2d_c_value(status, x, y);
844 if (les->type == N_SPARSE_LES) {
845 /*set the rows to zero */
846 for (i = 0; (unsigned int)i < les->Asp[count]->cols; i++)
847 les->Asp[count]->values[i] = 0.0;
848 /*set the cols to zero */
849 for (i = 0; i < les->rows; i++) {
850 for (j = 0; (unsigned int)j < les->Asp[i]->cols; j++) {
851 if (les->Asp[i]->index[j] == (unsigned int)count)
852 les->Asp[i]->values[j] = 0.0;
853 }
854 }
855
856 /*entry on the diagonal */
857 les->Asp[count]->values[0] = 1.0;
858 }
859 else {
860 /*set the rows to zero */
861 for (i = 0; i < les->cols; i++)
862 les->A[count][i] = 0.0;
863 /*set the cols to zero */
864 for (i = 0; i < les->rows; i++)
865 les->A[i][count] = 0.0;
866
867 /*entry on the diagonal */
868 les->A[count][count] = 1.0;
869 }
870 }
871 if (stat >= N_CELL_ACTIVE)
872 count++;
873 }
874 }
875 G_free(dvect1);
876 G_free(dvect2);
877
878 return 0;
879}
880
881/* **************************************************************** */
882/* **** make an entry in the les (2d) ***************************** */
883/* **************************************************************** */
884int make_les_entry_2d(int i, int j, int offset_i, int offset_j, int count,
885 int pos, N_les *les, G_math_spvector *spvect,
887 N_array_2d *start_val, double entry, int cell_type)
888{
889 int K;
890 int di = offset_i;
891 int dj = offset_j;
892
895
896 /* active cells build the linear equation system */
897 if (cell_type == N_CELL_ACTIVE) {
898 /* dirichlet or transmission cells must be handled like this */
899 if (N_get_array_2d_c_value(status, i + di, j + dj) > N_CELL_ACTIVE &&
901 les->b[count] -=
903 else if (N_get_array_2d_c_value(status, i + di, j + dj) ==
905 if ((count + K) >= 0 && (count + K) < les->cols) {
906 G_debug(5,
907 " make_les_entry_2d: (N_CELL_ACTIVE) create matrix "
908 "entry at row[%i] col[%i] value %g\n",
909 count, count + K, entry);
910 pos++;
911 if (les->type == N_SPARSE_LES) {
912 spvect->index[pos] = count + K;
913 spvect->values[pos] = entry;
914 }
915 else {
916 les->A[count][count + K] = entry;
917 }
918 }
919 }
920 } /* if dirichlet cells should be used then check for all valid cell
921 neighbours */
922 else if (cell_type == N_CELL_DIRICHLET) {
923 /* all valid cells */
924 if (N_get_array_2d_c_value(status, i + di, j + dj) > N_CELL_INACTIVE &&
925 N_get_array_2d_c_value(status, i + di, j + dj) < N_MAX_CELL_STATE) {
926 if ((count + K) >= 0 && (count + K) < les->cols) {
927 G_debug(5,
928 " make_les_entry_2d: (N_CELL_DIRICHLET) create matrix "
929 "entry at row[%i] col[%i] value %g\n",
930 count, count + K, entry);
931 pos++;
932 if (les->type == N_SPARSE_LES) {
933 spvect->index[pos] = count + K;
934 spvect->values[pos] = entry;
935 }
936 else {
937 les->A[count][count + K] = entry;
938 }
939 }
940 }
941 }
942
943 return pos;
944}
945
946/* *************************************************************** *
947 * ******************** N_assemble_les_3d ************************ *
948 * *************************************************************** */
949/*!
950 * \brief Assemble a linear equation system (les) based on 3d location data
951 * (g3d) active cells
952 *
953 * This function calls #N_assemble_les_3d_param
954 * */
962
963/*!
964 * \brief Assemble a linear equation system (les) based on 3d location data
965 * (g3d) active cells
966 *
967 * This function calls #N_assemble_les_3d_param
968 * */
976
977/*!
978 * \brief Assemble a linear equation system (les) based on 3d location data
979 * (g3d) active and dirichlet cells
980 *
981 * This function calls #N_assemble_les_3d_param
982 * */
990
991/*!
992 * \brief Assemble a linear equation system (les) based on 3d location data
993 * (g3d)
994 *
995 * The linear equation system type can be set to N_NORMAL_LES to create a
996 * regular matrix, or to N_SPARSE_LES to create a sparse matrix. This function
997 * returns a new created linear equation system which can be solved with linear
998 * equation solvers. An 3d array with start values and an 3d status array must
999 * be provided as well as the location geometry and a void pointer to data
1000 * passed to the callback which creates the les row entries. This callback
1001 * must be defined in the N_les_callback_3d structure.
1002 *
1003 * The creation of the les is parallelized with OpenMP.
1004 * If you implement new callbacks, please make sure that the
1005 * function calls are thread safe.
1006 *
1007 * the les can be created in two ways, with dirichlet and similar cells and
1008 * without them, to spare some memory. If the les is created with dirichlet
1009 * cell, the dirichlet boundary condition must be added.
1010 *
1011 * \param les_type int
1012 * \param geom N_geom_data*
1013 * \param status N_array_3d *
1014 * \param start_val N_array_3d *
1015 * \param data void *
1016 * \param call N_les_callback_3d *
1017 * \param cell_type int -- les assemble based on N_CELL_ACTIVE or
1018 * N_CELL_DIRICHLET \return N_les *
1019 * */
1022 void *data, N_les_callback_3d *call,
1023 int cell_type)
1024{
1025 int i, j, k, count = 0, pos = 0;
1026 int cell_type_count = 0;
1028 N_les *les = NULL;
1029 int **index_ij;
1030
1031 G_debug(
1032 2,
1033 "N_assemble_les_3d: starting to assemble the linear equation system");
1034
1035 cell_count =
1036 N_alloc_array_3d(geom->cols, geom->rows, geom->depths, 1, DCELL_TYPE);
1037
1038 /* First count the number of valid cells and save
1039 * each number in a new 3d array. Those numbers are used
1040 * to create the linear equation system.*/
1041
1042 if (cell_type == N_CELL_DIRICHLET) {
1043 /* include dirichlet cells in the les */
1044 for (k = 0; k < geom->depths; k++) {
1045 for (j = 0; j < geom->rows; j++) {
1046 for (i = 0; i < geom->cols; i++) {
1047 /*use all non-inactive cells for les creation */
1048 if (N_CELL_INACTIVE <
1049 (int)N_get_array_3d_d_value(status, i, j, k) &&
1050 (int)N_get_array_3d_d_value(status, i, j, k) <
1053 }
1054 }
1055 }
1056 }
1057 else {
1058 /*use only active cell in the les */
1059 for (k = 0; k < geom->depths; k++) {
1060 for (j = 0; j < geom->rows; j++) {
1061 for (i = 0; i < geom->cols; i++) {
1062 /*count only active cells */
1063 if (N_CELL_ACTIVE ==
1064 (int)N_get_array_3d_d_value(status, i, j, k))
1066 }
1067 }
1068 }
1069 }
1070
1071 G_debug(2, "N_assemble_les_3d: number of used cells %i\n",
1073
1074 if (cell_type_count == 0.0)
1076 "Not enough active cells [%i] to create the linear equation "
1077 "system. Check the cell status. Only active cells (value = 1) are "
1078 "used to create the equation system.",
1080
1081 /* allocate the memory for the linear equation system (les).
1082 * Only valid cells are used to create the les. */
1084
1085 index_ij = (int **)G_calloc(cell_type_count, sizeof(int *));
1086 for (i = 0; i < cell_type_count; i++)
1087 index_ij[i] = (int *)G_calloc(3, sizeof(int));
1088
1089 count = 0;
1090 /*count the number of cells which should be used to create the linear
1091 * equation system */
1092 /*save the k, i and j indices and create a ordered numbering */
1093 for (k = 0; k < geom->depths; k++) {
1094 for (j = 0; j < geom->rows; j++) {
1095 for (i = 0; i < geom->cols; i++) {
1096 if (cell_type == N_CELL_DIRICHLET) {
1097 if (N_CELL_INACTIVE <
1098 (int)N_get_array_3d_d_value(status, i, j, k) &&
1099 (int)N_get_array_3d_d_value(status, i, j, k) <
1102 index_ij[count][0] = i;
1103 index_ij[count][1] = j;
1104 index_ij[count][2] = k;
1105 count++;
1106 G_debug(5,
1107 "N_assemble_les_3d: non-inactive cells count "
1108 "%i at pos x[%i] y[%i] z[%i]\n",
1109 count, i, j, k);
1110 }
1111 }
1112 else if (N_CELL_ACTIVE ==
1113 (int)N_get_array_3d_d_value(status, i, j, k)) {
1115 index_ij[count][0] = i;
1116 index_ij[count][1] = j;
1117 index_ij[count][2] = k;
1118 count++;
1119 G_debug(5,
1120 "N_assemble_les_3d: active cells count %i at pos "
1121 "x[%i] y[%i] z[%i]\n",
1122 count, i, j, k);
1123 }
1124 }
1125 }
1126 }
1127
1128 G_debug(2, "N_assemble_les_3d: starting the parallel assemble loop");
1129
1130#pragma omp parallel for private(i, j, k, pos, count) schedule(static)
1131 for (count = 0; count < cell_type_count; count++) {
1132 i = index_ij[count][0];
1133 j = index_ij[count][1];
1134 k = index_ij[count][2];
1135
1136 /*create the entries for the */
1137 N_data_star *items = call->callback(data, geom, i, j, k);
1138
1140
1141 /*allocate a sprase vector */
1142 if (les_type == N_SPARSE_LES)
1144 /* initial conditions */
1145
1147
1148 /* the entry in the vector b */
1149 les->b[count] = items->V;
1150
1151 /* pos describes the position in the sparse vector.
1152 * the first entry is always the diagonal entry of the matrix*/
1153 pos = 0;
1154
1155 if (les_type == N_SPARSE_LES) {
1156 spvect->index[pos] = count;
1157 spvect->values[pos] = items->C;
1158 }
1159 else {
1160 les->A[count][count] = items->C;
1161 }
1162 /* western neighbour, entry is col - 1 */
1163 if (i > 0) {
1164 pos = make_les_entry_3d(i, j, k, -1, 0, 0, count, pos, les, spvect,
1165 cell_count, status, start_val, items->W,
1166 cell_type);
1167 }
1168 /* eastern neighbour, entry col + 1 */
1169 if (i < geom->cols - 1) {
1170 pos = make_les_entry_3d(i, j, k, 1, 0, 0, count, pos, les, spvect,
1171 cell_count, status, start_val, items->E,
1172 cell_type);
1173 }
1174 /* northern neighbour, entry row -1 */
1175 if (j > 0) {
1176 pos = make_les_entry_3d(i, j, k, 0, -1, 0, count, pos, les, spvect,
1177 cell_count, status, start_val, items->N,
1178 cell_type);
1179 }
1180 /* southern neighbour, entry row +1 */
1181 if (j < geom->rows - 1) {
1182 pos = make_les_entry_3d(i, j, k, 0, 1, 0, count, pos, les, spvect,
1183 cell_count, status, start_val, items->S,
1184 cell_type);
1185 }
1186 /*only for a 7 star entry needed */
1187 if (items->type == N_7_POINT_STAR || items->type == N_27_POINT_STAR) {
1188 /* the upper cell (top), entry depth + 1 */
1189 if (k < geom->depths - 1) {
1190 pos = make_les_entry_3d(i, j, k, 0, 0, 1, count, pos, les,
1191 spvect, cell_count, status, start_val,
1192 items->T, cell_type);
1193 }
1194 /* the lower cell (bottom), entry depth - 1 */
1195 if (k > 0) {
1196 pos = make_les_entry_3d(i, j, k, 0, 0, -1, count, pos, les,
1197 spvect, cell_count, status, start_val,
1198 items->B, cell_type);
1199 }
1200 }
1201
1202 /*How many entries in the les */
1203 if (les->type == N_SPARSE_LES) {
1204 spvect->cols = pos + 1;
1206 }
1207
1208 if (items)
1209 G_free(items);
1210 }
1211
1213
1214 for (i = 0; i < cell_type_count; i++)
1215 G_free(index_ij[i]);
1216
1218
1219 return les;
1220}
1221
1222/*!
1223 * \brief Integrate Dirichlet or Transmission boundary conditions into the les
1224 * (3d)
1225 *
1226 * Dirichlet and Transmission boundary conditions will be integrated into
1227 * the provided linear equation system. This is meaningful if
1228 * the les was created with #N_assemble_les_2d_dirichlet, because in
1229 * this case Dirichlet boundary conditions are not automatically included.
1230 *
1231 * The provided les will be modified:
1232 *
1233 * Ax = b will be split into Ax_u + Ax_d = b
1234 *
1235 * x_u - the unknowns
1236 * x_d - the Dirichlet cells
1237 *
1238 * Ax_u = b -Ax_d will be computed. Then the matrix A will be modified to
1239 *
1240 * | A_u 0 | x_u
1241 * | 0 I | x_d
1242 *
1243 * \param les N_les* -- the linear equation system
1244 * \param geom N_geom_data* -- geometrical data information
1245 * \param status N_array_2d* -- the status array containing the cell types
1246 * \param start_val N_array_2d* -- an array with start values
1247 * \return int -- 1 = success, 0 = failure
1248 * */
1251{
1252 int rows, cols, depths;
1253 int count = 0;
1254 int i, j, x, y, z, stat;
1255 double *dvect1;
1256 double *dvect2;
1257
1258 G_debug(2, "N_les_integrate_dirichlet_3d: integrating the dirichlet "
1259 "boundary condition");
1260
1261 rows = geom->rows;
1262 cols = geom->cols;
1263 depths = geom->depths;
1264
1265 /*we need to additional vectors */
1266 dvect1 = (double *)G_calloc(les->cols, sizeof(double));
1267 dvect2 = (double *)G_calloc(les->cols, sizeof(double));
1268
1269 /*fill the first one with the x vector data of Dirichlet cells */
1270 count = 0;
1271 for (z = 0; z < depths; z++) {
1272 for (y = 0; y < rows; y++) {
1273 for (x = 0; x < cols; x++) {
1274 stat = (int)N_get_array_3d_d_value(status, x, y, z);
1277 count++;
1278 }
1279 else if (stat == N_CELL_ACTIVE) {
1280 dvect1[count] = 0.0;
1281 count++;
1282 }
1283 }
1284 }
1285 }
1286
1287#pragma omp parallel default(shared)
1288 {
1289 /*perform the matrix vector product and */
1290 if (les->type == N_SPARSE_LES)
1291 G_math_Ax_sparse(les->Asp, dvect1, dvect2, les->rows);
1292 else
1293 G_math_d_Ax(les->A, dvect1, dvect2, les->rows, les->cols);
1294#pragma omp for schedule(static) private(i)
1295 for (i = 0; i < les->cols; i++)
1296 les->b[i] = les->b[i] - dvect2[i];
1297 }
1298
1299 /*now set the Dirichlet cell rows and cols to zero and the
1300 * diagonal entry to 1*/
1301 count = 0;
1302 for (z = 0; z < depths; z++) {
1303 for (y = 0; y < rows; y++) {
1304 for (x = 0; x < cols; x++) {
1305 stat = (int)N_get_array_3d_d_value(status, x, y, z);
1307 if (les->type == N_SPARSE_LES) {
1308 /*set the rows to zero */
1309 for (i = 0; (unsigned int)i < les->Asp[count]->cols;
1310 i++)
1311 les->Asp[count]->values[i] = 0.0;
1312 /*set the cols to zero */
1313 for (i = 0; i < les->rows; i++) {
1314 for (j = 0; (unsigned int)j < les->Asp[i]->cols;
1315 j++) {
1316 if (les->Asp[i]->index[j] ==
1317 (unsigned int)count)
1318 les->Asp[i]->values[j] = 0.0;
1319 }
1320 }
1321
1322 /*entry on the diagonal */
1323 les->Asp[count]->values[0] = 1.0;
1324 }
1325 else {
1326 /*set the rows to zero */
1327 for (i = 0; i < les->cols; i++)
1328 les->A[count][i] = 0.0;
1329 /*set the cols to zero */
1330 for (i = 0; i < les->rows; i++)
1331 les->A[i][count] = 0.0;
1332
1333 /*entry on the diagonal */
1334 les->A[count][count] = 1.0;
1335 }
1336 }
1337 count++;
1338 }
1339 }
1340 }
1341 G_free(dvect2);
1342 G_free(dvect1);
1343 return 0;
1344}
1345
1346/* **************************************************************** */
1347/* **** make an entry in the les (3d) ***************************** */
1348/* **************************************************************** */
1349int 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,
1352 N_array_3d *status, N_array_3d *start_val, double entry,
1353 int cell_type)
1354{
1355 int K;
1356 int di = offset_i;
1357 int dj = offset_j;
1358 int dk = offset_k;
1359
1360 K = (int)N_get_array_3d_d_value(cell_count, i + di, j + dj, k + dk) -
1362
1363 if (cell_type == N_CELL_ACTIVE) {
1364 if ((int)N_get_array_3d_d_value(status, i + di, j + dj, k + dk) >
1365 N_CELL_ACTIVE &&
1366 (int)N_get_array_3d_d_value(status, i + di, j + dj, k + dk) <
1368 les->b[count] -=
1369 N_get_array_3d_d_value(start_val, i + di, j + dj, k + dk) *
1370 entry;
1371 else if ((int)N_get_array_3d_d_value(status, i + di, j + dj, k + dk) ==
1372 N_CELL_ACTIVE) {
1373 if ((count + K) >= 0 && (count + K) < les->cols) {
1374 G_debug(5,
1375 " make_les_entry_3d: (N_CELL_ACTIVE) create matrix "
1376 "entry at row[%i] col[%i] value %g\n",
1377 count, count + K, entry);
1378 pos++;
1379 if (les->type == N_SPARSE_LES) {
1380 spvect->index[pos] = count + K;
1381 spvect->values[pos] = entry;
1382 }
1383 else {
1384 les->A[count][count + K] = entry;
1385 }
1386 }
1387 }
1388 }
1389 else if (cell_type == N_CELL_DIRICHLET) {
1390 if ((int)N_get_array_3d_d_value(status, i + di, j + dj, k + dk) !=
1392 if ((count + K) >= 0 && (count + K) < les->cols) {
1393 G_debug(5,
1394 " make_les_entry_3d: (N_CELL_DIRICHLET) create matrix "
1395 "entry at row[%i] col[%i] value %g\n",
1396 count, count + K, entry);
1397 pos++;
1398 if (les->type == N_SPARSE_LES) {
1399 spvect->index[pos] = count + K;
1400 spvect->values[pos] = entry;
1401 }
1402 else {
1403 les->A[count][count + K] = entry;
1404 }
1405 }
1406 }
1407 }
1408
1409 return pos;
1410}
#define N_27_POINT_STAR
Definition N_pde.h:40
#define N_5_POINT_STAR
Definition N_pde.h:37
#define N_9_POINT_STAR
Definition N_pde.h:39
#define N_CELL_DIRICHLET
Definition N_pde.h:29
#define N_CELL_INACTIVE
Definition N_pde.h:27
#define N_CELL_ACTIVE
Definition N_pde.h:28
#define N_MAX_CELL_STATE
the maximum number of available cell states (eg: boundary condition, inactiven active)
Definition N_pde.h:35
#define N_7_POINT_STAR
Definition N_pde.h:38
#define N_SPARSE_LES
Definition N_pde.h:23
#define NULL
Definition ccmath.h:32
#define SE
Definition dataquad.h:27
#define SW
Definition dataquad.h:26
#define NE
Definition dataquad.h:25
#define NW
Definition dataquad.h:24
void G_free(void *)
Free allocated memory.
Definition gis/alloc.c:145
#define G_calloc(m, n)
Definition defs/gis.h:137
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 N
#define G_UNUSED
A macro for an attribute, if attached to a variable, indicating that the variable is not used.
Definition gis.h:43
int count
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.
Definition n_arrays.c:716
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.
Definition n_arrays.c:311
void N_free_array_3d(N_array_3d *data)
Release the memory of a N_array_3d.
Definition n_arrays.c:771
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
void N_free_array_2d(N_array_2d *data)
Release the memory of a N_array_2d structure.
Definition n_arrays.c:129
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
N_array_2d * N_alloc_array_2d(int cols, int rows, int offset, int type)
Allocate memory for a N_array_2d data structure.
Definition n_arrays.c:72
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_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.
Definition n_arrays.c:513
N_les * N_alloc_les_Ax_b(int rows, int type)
Allocate memory for a quadratic linear equation system which includes the Matrix A,...
Definition n_les.c:146
N_data_star * N_alloc_27star(void)
allocate a 27 point star data structure
N_data_star * N_callback_template_3d(void *data, N_geom_data *geom, int col, int row, int depth)
A callback template creates a 7 point star 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_create_5star(double C, double W, double E, double N, double S, double V)
allocate and initialize a 5 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_data_star * N_alloc_7star(void)
allocate a 7 point star data structure
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_alloc_9star(void)
allocate a 9 point star data structure
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 * 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.
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_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.
N_data_star * N_callback_template_2d(void *data, N_geom_data *geom, int col, int row)
A callback template creates a 9 point star structure.
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_alloc_5star(void)
allocate a 5 point star data structure
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_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_callback_2d * N_alloc_les_callback_2d(void)
Allocate the structure holding the callback function.
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.
N_les_callback_3d * N_alloc_les_callback_3d(void)
Allocate the structure holding the callback function.
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_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)
#define W
Definition ogsf.h:144
#define DCELL_TYPE
Definition raster.h:13
#define CELL_TYPE
Definition raster.h:11
The row vector of the sparse matrix.
Definition gmath.h:54
Matrix entries for a mass balance 5/7/9 star system.
Definition N_pde.h:292
double W_B
Definition N_pde.h:299
double E
Definition N_pde.h:295
double S
Definition N_pde.h:295
double NE
Definition N_pde.h:295
double E_B
Definition N_pde.h:299
double N_T
Definition N_pde.h:297
double SE
Definition N_pde.h:295
double N_B
Definition N_pde.h:299
double NW
Definition N_pde.h:295
double W
Definition N_pde.h:295
double S_T
Definition N_pde.h:297
double NW_T
Definition N_pde.h:297
double E_T
Definition N_pde.h:297
double NW_B
Definition N_pde.h:299
double S_B
Definition N_pde.h:299
double W_T
Definition N_pde.h:297
double SW
Definition N_pde.h:295
double SW_T
Definition N_pde.h:297
double C
Definition N_pde.h:295
int type
Definition N_pde.h:293
double T
Definition N_pde.h:297
double SW_B
Definition N_pde.h:299
double NE_T
Definition N_pde.h:297
double N
Definition N_pde.h:295
double B
Definition N_pde.h:299
double SE_T
Definition N_pde.h:297
int count
Definition N_pde.h:294
double SE_B
Definition N_pde.h:299
double NE_B
Definition N_pde.h:299
double V
Definition N_pde.h:295
Geometric information about the structured grid.
Definition N_pde.h:98
callback structure for 2d matrix assembling
Definition N_pde.h:312
N_data_star *(* callback)(void *, N_geom_data *, int, int)
Definition N_pde.h:313
callback structure for 3d matrix assembling
Definition N_pde.h:305
N_data_star *(* callback)(void *, N_geom_data *, int, int, int)
Definition N_pde.h:306
The linear equation system (les) structure.
Definition N_pde.h:68
#define x