1 #ifndef __CS_MATRIX_ASSEMBLER_PRIV_H__
2 #define __CS_MATRIX_ASSEMBLER_PRIV_H__
3
4 /*============================================================================
5 * Incremental or general construction of matrix.
6 *============================================================================*/
7
8 /*
9 This file is part of Code_Saturne, a general-purpose CFD tool.
10
11 Copyright (C) 1998-2021 EDF S.A.
12
13 This program is free software; you can redistribute it and/or modify it under
14 the terms of the GNU General Public License as published by the Free Software
15 Foundation; either version 2 of the License, or (at your option) any later
16 version.
17
18 This program is distributed in the hope that it will be useful, but WITHOUT
19 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
20 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
21 details.
22
23 You should have received a copy of the GNU General Public License along with
24 this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
25 Street, Fifth Floor, Boston, MA 02110-1301, USA.
26 */
27
28 /*----------------------------------------------------------------------------*/
29
30 #include "cs_defs.h"
31
32 /*----------------------------------------------------------------------------
33 * Standard C library headers
34 *----------------------------------------------------------------------------*/
35
36 /*----------------------------------------------------------------------------
37 * Local headers
38 *----------------------------------------------------------------------------*/
39
40 #include "cs_defs.h"
41 #include "cs_log.h"
42 #include "cs_rank_neighbors.h"
43 #include "cs_timer.h"
44
45 #include "cs_matrix.h"
46
47 /*----------------------------------------------------------------------------
48 * Header for the current file
49 *----------------------------------------------------------------------------*/
50
51 /*----------------------------------------------------------------------------*/
52
53 BEGIN_C_DECLS
54
55 /*! \cond DOXYGEN_SHOULD_SKIP_THIS */
56
57 /*=============================================================================
58 * Local Macro Definitions
59 *============================================================================*/
60
61 /*=============================================================================
62 * Local Structure Definitions
63 *============================================================================*/
64
65 /*----------------------------------------------------------------------------
66 * Structure used to pre-build a matrix
67 *----------------------------------------------------------------------------*/
68
69 struct _cs_matrix_assembler_t {
70
71 bool separate_diag; /* is diagonal handled separately ? */
72
73 int flags; /* sum (bitwise or) of option constants */
74
75 cs_gnum_t l_range[2]; /* local global row range */
76 cs_gnum_t n_g_rows; /* global number of rows */
77 cs_lnum_t n_rows; /* local number of rows */
78
79 cs_lnum_t size; /* current insertion array size */
80 cs_lnum_t max_size; /* maximum insertion array size */
81
82 const cs_lnum_t *r_idx; /* shared main row index (0 to n-1) */
83 const cs_lnum_t *c_id; /* shared main column ids (0 to n-1) */
84
85 cs_lnum_t *_r_idx; /* private main row index (0 to n-1) */
86 cs_lnum_t *_c_id; /* private main column ids (0 to n-1) */
87
88 cs_lnum_t *d_r_idx; /* distant row index (0 to n-1) */
89 cs_gnum_t *d_g_c_id; /* distant global column ids (0 to n-1) */
90
91 cs_gnum_t *g_rc_id; /* global row and column ids
92 (local and distant) */
93
94 #if defined(HAVE_MPI)
95
96 /* Distant columns associated with local rows */
97
98 /* Metadata for exchange of matrix coefficient values with other ranks */
99
100 int n_coeff_ranks; /* number of MPI ranks with which
101 coefficients are exchanged */
102 int *coeff_rank; /* ranks with which coefficients are
103 exchanged */
104
105 cs_lnum_t coeff_send_size; /* number of coefficients to send */
106 cs_lnum_t coeff_recv_size; /* number of coefficients to receive */
107
108 cs_lnum_t coeff_send_n_rows; /* number of matching rows */
109 cs_lnum_t *coeff_send_index; /* index of sent coefficient rows */
110 cs_gnum_t *coeff_send_row_g_id; /* global ids matching rows (ordered) */
111 cs_gnum_t *coeff_send_col_g_id; /* global ids matching columns
112 (ordered) */
113
114 cs_lnum_t *coeff_rank_send_index; /* index of data to send */
115 cs_lnum_t *coeff_rank_recv_index; /* index of data to receive */
116
117 cs_lnum_t *coeff_recv_row_id; /* local row ids associated with
118 received data; */
119 cs_lnum_t *coeff_recv_col_idx; /* local column index associated with
120 received data; the column numbering
121 implicitely assumes local terms
122 first, distant ones second */
123 cs_gnum_t *coeff_recv_col_g_id; /* global column id couples
124 associated with received data */
125
126 /* Associated communicator */
127
128 MPI_Comm comm; /* associated MPI communicator */
129
130 /* Statistics */
131
132 int n_ranks_init[2]; /* Number of ranks for initial exchange
133 for distant rows then columns */
134 #endif /* HAVE_MPI */
135
136 /* Associated vector ghost element info */
137
138 const cs_halo_t *halo; /* shared halo for associated vectors */
139 cs_halo_t *_halo; /* private halo for associated vectors */
140
141 cs_lnum_t n_e_g_ids; /* number of external global ids */
142 cs_gnum_t *e_g_id; /* global ids associated with halo
143 elements (size: n_e_g_ids */
144
145 };
146
147 /*----------------------------------------------------------------------------
148 * Structure managing matrix coefficient contributions.
149 *----------------------------------------------------------------------------*/
150
151 struct _cs_matrix_assembler_values_t {
152
153 const cs_matrix_assembler_t *ma; /* associated matrix assembler */
154
155 bool separate_diag; /* is diagonal handled separately ? */
156 bool final_assembly; /* are we ready for final assembly ? */
157
158 cs_lnum_t db_size[4]; /* Diag Block size including padding:
159 0: useful block size
160 1: vector block extents
161 2: matrix line extents
162 3: matrix line*column extents */
163
164 cs_lnum_t eb_size[4]; /* Extradiag block size including padding:
165 0: useful block size
166 1: vector block extents
167 2: matrix line extents
168 3: matrix line*column extents */
169
170 cs_lnum_t *diag_idx; /* Local index of diagonal in each row
171 when conversion beween separate
172 diagonal and included diagonal is
173 required */
174
175 /* Accumulated contributions to distant rows, indexed as per
176 coeff_send_index of the matching assembler structure */
177
178 #if defined(HAVE_MPI)
179
180 cs_real_t *coeff_send;
181
182 #endif
183
184 /* Matching structure and function pointers; some function type may not be
185 useful for certain matrix structures or libraries. */
186
187 void *matrix; /* pointer to
188 matrix structure */
189
190 cs_matrix_assembler_values_init_t *init;
191 cs_matrix_assembler_values_add_t *add_values;
192 cs_matrix_assembler_values_add_g_t *add_values_g;
193 cs_matrix_assembler_values_begin_t *assembly_begin; /* optional */
194 cs_matrix_assembler_values_end_t *assembly_end; /* optional */
195
196 };
197
198 /*============================================================================
199 * Public inline function definitions
200 *============================================================================*/
201
202 /*----------------------------------------------------------------------------*/
203 /*!
204 * \brief Binary search for a given local id in a given array of
205 * ordered local ids, when the id might not be present
206 *
207 * We assume the id is present in the array.
208 *
209 * \param[in] l_id_array size array_size
210 * \param[in] l_id local id to search for
211 * \param[in] l_id_array ordered unique local ids array
212 *
213 * \return index of l_id in l_id_array, or -1 if not found
214 */
215 /*----------------------------------------------------------------------------*/
216
217 static inline cs_lnum_t
_l_id_binary_search(cs_lnum_t l_id_array_size,cs_lnum_t l_id,const cs_lnum_t l_id_array[])218 _l_id_binary_search(cs_lnum_t l_id_array_size,
219 cs_lnum_t l_id,
220 const cs_lnum_t l_id_array[])
221 {
222 if (l_id_array_size < 1)
223 return -1;
224
225 cs_lnum_t start_id = 0;
226 cs_lnum_t end_id = l_id_array_size - 1;
227 cs_lnum_t mid_id = end_id/2;
228 while (start_id < end_id) {
229 if (l_id_array[mid_id] < l_id)
230 start_id = mid_id + 1;
231 else if (l_id_array[mid_id] > l_id)
232 end_id = mid_id - 1;
233 else
234 break;
235 mid_id = start_id + (end_id - start_id)/2;
236 }
237 if (l_id_array[mid_id] != l_id)
238 mid_id = -1;
239
240 return mid_id;
241 }
242
243 /*----------------------------------------------------------------------------*/
244 /*!
245 * \brief Binary search for a given global id in a given array of
246 * ordered global ids, when we know the id is present.
247 *
248 * We assume the id is present in the array.
249 *
250 * \param[in] g_id_array size array_size
251 * \param[in] g_id global id to search for
252 * \param[in] g_id_array ordered unique global ids array
253 *
254 * \return index of g_id in g_id_array.
255 */
256 /*----------------------------------------------------------------------------*/
257
258 static inline cs_lnum_t
_g_id_binary_find(cs_lnum_t g_id_array_size,cs_gnum_t g_id,const cs_gnum_t g_id_array[])259 _g_id_binary_find(cs_lnum_t g_id_array_size,
260 cs_gnum_t g_id,
261 const cs_gnum_t g_id_array[])
262 {
263 cs_lnum_t start_id = 0;
264 cs_lnum_t end_id = g_id_array_size - 1;
265 cs_lnum_t mid_id = (end_id -start_id) / 2;
266 while (start_id < end_id) {
267 if (g_id_array[mid_id] < g_id)
268 start_id = mid_id + 1;
269 else if (g_id_array[mid_id] > g_id)
270 end_id = mid_id - 1;
271 else
272 break;
273 mid_id = start_id + ((end_id -start_id) / 2);
274 }
275 assert(g_id_array[mid_id] == g_id);
276
277 return mid_id;
278 }
279
280 /*! (DOXYGEN_SHOULD_SKIP_THIS) \endcond */
281
282 /*----------------------------------------------------------------------------*/
283
284 END_C_DECLS
285
286 #endif /* __CS_MATRIX_ASSEMBLER_PRIV_H__ */
287