1 #ifndef __CS_RANGE_SET_H__
2 #define __CS_RANGE_SET_H__
3 
4 /*============================================================================
5  * Operations related to handling of an owning rank for distributed entities.
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 /*----------------------------------------------------------------------------
31  *  Local headers
32  *----------------------------------------------------------------------------*/
33 
34 #include "cs_defs.h"
35 
36 #include "fvm_group.h"
37 #include "fvm_selector.h"
38 #include "fvm_periodicity.h"
39 
40 #include "cs_base.h"
41 #include "cs_halo.h"
42 #include "cs_interface.h"
43 #include "cs_numbering.h"
44 
45 #include "cs_mesh_builder.h"
46 
47 /*----------------------------------------------------------------------------*/
48 
49 BEGIN_C_DECLS
50 
51 /*=============================================================================
52  * Macro definitions
53  *============================================================================*/
54 
55 /*! Structure for range set management */
56 
57 typedef struct {
58 
59   cs_lnum_t  n_elts[3];             /*!< Number of associated local elements
60                                          (0: local range, 1: total,
61                                          2: first "out of local range" id) */
62 
63   cs_gnum_t  l_range[2];            /*!< global id range assigned to local
64                                          rank: [start, past-the-end[ */
65   const cs_gnum_t  *g_id;           /*!< global id assigned to elements
66                                          (possibly shared) */
67   cs_gnum_t        *_g_id;          /*!< global id assigned to elements
68                                          (private) */
69 
70   const cs_interface_set_t  *ifs;   /*!< Associated interface set, or NULL */
71   const cs_halo_t           *halo;  /*!< Associated halo, or NULL */
72 
73 } cs_range_set_t;
74 
75 /*============================================================================
76  * Type definitions
77  *============================================================================*/
78 
79 /*============================================================================
80  * Static global variables
81  *============================================================================*/
82 
83 /*=============================================================================
84  * Public function prototypes
85  *============================================================================*/
86 
87 /*----------------------------------------------------------------------------*/
88 /*!
89  * \brief Define global ids and a partitioning of data based on local ranges
90  *        for elements which may be shared across ranks or have halo elements.
91  *
92  * This is a utility function, allowing a similar call for cases where matching
93  * elements or parallel ranks are identified using an interface set (for
94  * elements which may be on rank boundaries, such as vertices or faces),
95  * elements with an associated a halo (such as for cells), or neither
96  * (in the single-rank case).
97  *
98  * Global id ranges are assigned to each rank, and global ids are defined
99  * by a parallel scan type operation counting elements on parallel
100  * interfaces only once. Each element will appear inside one rank's range
101  * and outside the range of all other ranks.
102  * Ranges across different ranks are contiguous.
103  *
104  * This allows building distribution information such as that used in many
105  * external libraries, such as PETSc, HYPRE, and may also simplify many
106  * internal operations, where it is needed that elements have a unique owner
107  * rank, and are ghosted on others (such as linear solvers operating on
108  * elements which may be on parallel boundaries, such as vertices, edges,
109  * and faces).
110  *
111  * Elements and their periodic matches will have identical or distinct
112  * global ids depending on the tr_ignore argument.
113  *
114  * \param[in]   ifs          pointer to interface set structure, or NULL
115  * \param[in]   halo         pointer to halo structure, or NULL
116  * \param[in]   n_elts       number of elements
117  * \param[in]   balance      try to balance shared elements across ranks ?
118  *                           (for elements shared across an interface set)
119  * \param[in]   tr_ignore    0: periodic elements will share global ids
120  *                           > 0: ignore periodicity with rotation;
121  *                           > 1: ignore all periodic transforms
122  * \param[in]   g_id_base    global id base index (usually 0, but 1
123  *                           could be used to generate an IO numbering)
124  * \param[out]  l_range      global id range assigned to local rank:
125  *                           [start, past-the-end[
126  * \param[out]  g_id         global id assigned to elements
127  */
128 /*----------------------------------------------------------------------------*/
129 
130 void
131 cs_range_set_define(const cs_interface_set_t  *ifs,
132                     const cs_halo_t           *halo,
133                     cs_lnum_t                  n_elts,
134                     bool                       balance,
135                     int                        tr_ignore,
136                     cs_gnum_t                  g_id_base,
137                     cs_gnum_t                  l_range[2],
138                     cs_gnum_t                 *g_id);
139 
140 /*----------------------------------------------------------------------------*/
141 /*!
142  * \brief Create a range set (with associated range and global ids) for the
143  *        partitioning of data based on local ranges for elements which may
144  *        be shared across ranks or have halo elements.
145  *
146  * Global id ranges are assigned to each rank of the interface set's associated
147  * communicator, and global ids are defined by a parallel scan type operation
148  * counting elements on parallel interfaces only once. Each element will
149  * appear inside one rank's range and outside the range of all other ranks.
150  * Ranges across different ranks are contiguous.
151  *
152  * Elements and their periodic matches will have identical or distinct
153  * global ids depending on the tr_ignore argument.
154  *
155  * The range set maintains pointers to the optional interface set and halo
156  * structures, but does not copy them, so those structures should have a
157  * lifetime at least as long as the returned range set.
158  *
159  * \param[in]   ifs          pointer to interface set structure, or NULL
160  * \param[in]   halo         pointer to halo structure, or NULL
161  * \param[in]   n_elts       number of elements
162  * \param[in]   balance      try to balance shared elements across ranks?
163  *                           (for elements shared across an interface set)
164  * \param[in]   tr_ignore    0: periodic elements will share global ids
165  *                           > 0: ignore periodicity with rotation;
166  *                           > 1: ignore all periodic transforms
167  * \param[in]   g_id_base    global id base index (usually 0, but 1
168  *                           could be used to generate an IO numbering)
169  *
170  * \return  pointer to created range set structure
171  */
172 /*----------------------------------------------------------------------------*/
173 
174 cs_range_set_t *
175 cs_range_set_create(const cs_interface_set_t  *ifs,
176                     const cs_halo_t           *halo,
177                     cs_lnum_t                  n_elts,
178                     bool                       balance,
179                     int                        tr_ignore,
180                     cs_gnum_t                  g_id_base);
181 
182 /*----------------------------------------------------------------------------*/
183 /*!
184  * \brief Create a range set (with associated range and global ids) from
185  *        an existing partition of data based on local ranges for elements
186  *        which may be shared across ranks or have halo elements.
187  *
188  * The optional interface set, halo, and global element id array are only
189  * shared by the range set, not copied, so they should have a lifetime at
190  * least as long as the returned range set.
191  *
192  * \param[in]  ifs      pointer to interface set structure, or NULL
193  * \param[in]  halo     pointer to halo structure, or NULL
194  * \param[in]  n_elts   number of elements
195  * \param[in]  l_range  global id range assigned to local rank:
196  *                      [start, past-the-end[
197  * \param[in]  g_id     global id assigned to elements
198  *
199  * \return  pointer to created range set structure
200  */
201 /*----------------------------------------------------------------------------*/
202 
203 cs_range_set_t *
204 cs_range_set_create_from_shared(const cs_interface_set_t  *ifs,
205                                 const cs_halo_t           *halo,
206                                 cs_lnum_t                  n_elts,
207                                 cs_gnum_t                  l_range[2],
208                                 cs_gnum_t                 *g_id);
209 
210 /*----------------------------------------------------------------------------*/
211 /*!
212  * \brief Destroy a range set structure.
213  *
214  * \param[in, out]  rs  pointer to pointer to structure to destroy
215  */
216 /*----------------------------------------------------------------------------*/
217 
218 void
219 cs_range_set_destroy(cs_range_set_t  **rs);
220 
221 /*----------------------------------------------------------------------------*/
222 /*!
223  * \brief Set values of a given array to zero for indexes of elements
224  *        outside the local range.
225  *
226  * If an interface set used to define the range set is available, it may be
227  * used to accelerate this operation, as only elements on that interface need
228  * to be checked.
229  *
230  * \param[in]       rs        pointer to range set structure, or NULL
231  * \param[in]       datatype  type of data considered
232  * \param[in]       stride    number of values per entity (interlaced)
233  * \param[in, out]  val       pointer to array values
234  */
235 /*----------------------------------------------------------------------------*/
236 
237 void
238 cs_range_set_zero_out_of_range(const cs_range_set_t  *rs,
239                                cs_datatype_t          datatype,
240                                cs_lnum_t              stride,
241                                void                  *val);
242 
243 /*----------------------------------------------------------------------------*/
244 /*!
245  * \brief Synchronize values elements associated with a range set, using
246  *        either a halo or an interface set.
247  *
248  * \param[in]       rs        pointer to range set structure, or NULL
249  * \param[in]       datatype  type of data considered
250  * \param[in]       stride    number of values per entity (interlaced)
251  * \param[in, out]  val       values buffer
252  */
253 /*----------------------------------------------------------------------------*/
254 
255 void
256 cs_range_set_sync(const cs_range_set_t  *rs,
257                   cs_datatype_t          datatype,
258                   cs_lnum_t              stride,
259                   void                  *val);
260 
261 /*----------------------------------------------------------------------------*/
262 /*!
263  * \brief Gather element values associated with a range set to a compact set.
264  *
265  * \param[in]   rs        pointer to range set structure, or NULL
266  * \param[in]   datatype  type of data considered
267  * \param[in]   stride    number of values per entity (interlaced)
268  * \param[in]   src_val   source values buffer
269  * \param[out]  dest_val  destination values buffer (may be identical to
270  *                        src_val, in which case operation is "in-place")
271  */
272 /*----------------------------------------------------------------------------*/
273 
274 void
275 cs_range_set_gather(const cs_range_set_t  *rs,
276                     cs_datatype_t          datatype,
277                     cs_lnum_t              stride,
278                     const void            *src_val,
279                     void                  *dest_val);
280 
281 /*----------------------------------------------------------------------------*/
282 /*!
283  * \brief Scatter element values associated with a range set to the full set.
284  *
285  * This includes parallel synchronization when the range set is associated
286  * with a halo or interface set structure.
287  *
288  * \param[in]   rs        pointer to range set structure, or NULL
289  * \param[in]   datatype  type of data considered
290  * \param[in]   stride    number of values per entity (interlaced)
291  * \param[in]   src_val   source values buffer
292  * \param[out]  dest_val  destination values buffer (may be identical to
293  *                        src_val, in which case operation is "in-place")
294  */
295 /*----------------------------------------------------------------------------*/
296 
297 void
298 cs_range_set_scatter(const cs_range_set_t  *rs,
299                      cs_datatype_t          datatype,
300                      cs_lnum_t              stride,
301                      const void            *src_val,
302                      void                  *dest_val);
303 
304 /*----------------------------------------------------------------------------*/
305 
306 END_C_DECLS
307 
308 #endif /* __CS_RANGE_SET_H__ */
309