1 #ifndef __FVM_NEIGHBORHOOD_H__
2 #define __FVM_NEIGHBORHOOD_H__
3 
4 /*============================================================================
5  * Search octrees and quadtrees of boxes.
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  *  Local headers
34  *----------------------------------------------------------------------------*/
35 
36 #include "fvm_defs.h"
37 
38 /*----------------------------------------------------------------------------*/
39 
40 BEGIN_C_DECLS
41 
42 /*============================================================================
43  * Macro definitions
44  *============================================================================*/
45 
46 /*============================================================================
47  * Type definitions
48  *============================================================================*/
49 
50 typedef struct _fvm_neighborhood_t fvm_neighborhood_t;
51 
52 /*============================================================================
53  * Public function definitions
54  *============================================================================*/
55 
56 /*----------------------------------------------------------------------------
57  * Create a neighborhood_t structure and initialize it.
58  *
59  * parameters:
60  *   comm  <-- associated MPI communicator
61  *
62  * returns:
63  *   pointer to an empty fvm_box_tree_t structure.
64  *----------------------------------------------------------------------------*/
65 
66 #if defined(HAVE_MPI)
67 
68 fvm_neighborhood_t *
69 fvm_neighborhood_create(MPI_Comm  comm);
70 
71 #else
72 
73 fvm_neighborhood_t *
74 fvm_neighborhood_create(void);
75 
76 #endif
77 
78 /*----------------------------------------------------------------------------
79  * Destroy a neighborhood_t structure.
80  *
81  * parameters:
82  *   n <-> pointer to pointer to fvm_neighborhood_t structure to destroy.
83  *----------------------------------------------------------------------------*/
84 
85 void
86 fvm_neighborhood_destroy(fvm_neighborhood_t  **n);
87 
88 /*----------------------------------------------------------------------------
89  * Set non-default algorithm parameters for neighborhood management structure.
90  *
91  * parameters:
92  *   n                     <-> pointer to neighborhood management structure
93  *   max_tree_depth        <-- maximum search tree depth
94  *   leaf_threshold        <-- maximum number of boxes which can be related to
95  *                             a leaf of the tree if level < max_tree_depth
96  *   max_box_ratio         <-- stop adding levels to tree when
97  *                             (n_linked_boxes > max_box_ratio*n_init_boxes)
98  *   max_box_ratio_distrib <-- maximum box ratio when computing coarse
99  *                             tree prior to parallel distribution
100  *---------------------------------------------------------------------------*/
101 
102 void
103 fvm_neighborhood_set_options(fvm_neighborhood_t  *n,
104                              int                  max_tree_depth,
105                              int                  leaf_threshold,
106                              float                max_box_ratio,
107                              float                max_box_ratio_distrib);
108 
109 /*----------------------------------------------------------------------------
110  * Retrieve pointers to of arrays from a neighborhood_t structure.
111  *
112  * Arrays remain the property of the neighborhood_t structure, and must not
113  * be modified by the caller.
114  *
115  * parameters:
116  *   n              <-> pointer to fvm_neighborhood_t structure.
117  *   n_elts         --> number of elements with neighbors in block
118  *                      associated with local rank
119  *   elt_num        --> global element numbers in local block (size: n_elts)
120  *   neighbor_index --> start index of neighbors (size: n_elts + 1)
121  *   neighbor_num   --> global element neighbor numbers
122  *                      (size: neighbor_index[n_elts])
123  *----------------------------------------------------------------------------*/
124 
125 void
126 fvm_neighborhood_get_data(const fvm_neighborhood_t         *n,
127                           cs_lnum_t                        *n_elts,
128                           cs_gnum_t                 **const elt_num,
129                           cs_lnum_t                 **const neighbor_index,
130                           cs_gnum_t                 **const neighbor_num);
131 
132 /*----------------------------------------------------------------------------
133  * Transfer ownership of arrays from a neighborhood_t structure to the
134  * calling program.
135  *
136  * Arrays that are transferred are removed from the structure, so its
137  * use after calling this function is limited to querying timing information
138  * until a new neighborhood is computed.
139  *
140  * parameters:
141  *   n              <-> pointer to fvm_neighborhood_t structure.
142  *   n_elts         --> number of elements with neighbors in block
143  *                      associated with local rank
144  *   elt_num        --> global element numbers in local block (size: n_elts)
145  *   neighbor_index --> start index of neighbors (size: n_elts + 1)
146  *   neighbor_num   --> global element neighbor numbers
147  *                      (size: neighbor_index[n_elts])
148  *----------------------------------------------------------------------------*/
149 
150 void
151 fvm_neighborhood_transfer_data(fvm_neighborhood_t   *n,
152                                cs_lnum_t            *n_elts,
153                                cs_gnum_t           **elt_num,
154                                cs_lnum_t           **neighbor_index,
155                                cs_gnum_t           **neighbor_num);
156 
157 /*----------------------------------------------------------------------------
158  * Determine intersecting boxes.
159  *
160  * Box global numbers and extents may be either copied for the structure's
161  * internal use from the caller, or transferred to the neighborhood management
162  * structure: both the box_gnum and extents arguments have an "assigned"
163  * variant, in which case a pointer to a pointer is provided, and the
164  * argument's property is transferred to the neighborhod management structure.
165  * The unused variant of an argument should be set to NULL.
166  *
167  * Boxes may be distributed among processors, so their intersections are
168  * determined using a block distribution, and defined using their
169  * global numbers.
170  *
171  * All global numbers appearing in box_gnum[] will have a matching entry in
172  * the neighborhod structure. To remove global numbers entries with no
173  * neighbors from the structure, the fvm_neighborhood_prune() function
174  * may be used.
175  *
176  * parameters:
177  *   n                 <-> pointer to neighborhood management structure
178  *   dim               <-- spatial dimension
179  *   n_boxes           <-- local number of boxes
180  *   box_gnum          <-- global numbering of boxes
181  *   extents           <-- coordinate extents (size: n_boxes*dim*2, as
182  *                         xmin1, ymin1, .. xmax1, ymax1, ..., xmin2, ...)
183  *   box_gnum_assigned <-> as box_gnum, ownership transferred (NULL on return)
184  *   extents_assigned  <-> as extents, ownership transferred (NULL on return)
185  *---------------------------------------------------------------------------*/
186 
187 void
188 fvm_neighborhood_by_boxes(fvm_neighborhood_t  *n,
189                           int                  dim,
190                           cs_lnum_t            n_boxes,
191                           const cs_gnum_t     *box_gnum,
192                           const cs_coord_t    *extents,
193                           cs_gnum_t          **box_gnum_assigned,
194                           cs_coord_t         **extents_assigned);
195 
196 /*----------------------------------------------------------------------------
197  * Prune a neighborhood (remove entries with no neighbors).
198  *
199  * parameters:
200  *   n <-> pointer to neighborhood management structure
201  *----------------------------------------------------------------------------*/
202 
203 void
204 fvm_neighborhood_prune(fvm_neighborhood_t  *n);
205 
206 /*----------------------------------------------------------------------------
207  * Get global statistics relative to the search structures used
208  * by fvm_neighborhood_by_boxes().
209  *
210  * All fields returned are optional: if their argument is set to NULL,
211  * the corresponding information will not be returned.
212  *
213  * For each field not set to NULL, 3 values are always returned:
214  * the mean on all ranks (rounded to the closest integer), the minimum,
215  * and the maximum value respectively.
216  *
217  * In serial mode, the mean, minimum, and maximum will be identical for most
218  * fields, but all 3 values are returned nonetheless.
219  *
220  * Note that the final memory use is only relative to the final search
221  * structure, and the comparison of the total (or average) with the minima
222  * and maxima may give an indication on load balancing.
223 
224  * The mem_required field only takes into account the theoretical maximum
225  * memory footprint of the main search structure during its construction phase,
226  * and of that of temporary structures before load balancing in parallel mode,
227  * but does not include minor work arrays or buffers used during the algorithm.
228  *
229  * Neither of the 2 memory fields include the footprint of the arrays
230  * containing the query results.
231  *
232  * parameters:
233  *   n                  <-- pointer to neighborhood management structure
234  *   depth              --> tree depth (max level used)
235  *   n_leaves           --> number of leaves in the tree
236  *   n_boxes            --> number of boxes in the tree
237  *   n_threshold_leaves --> number of leaves where n_boxes > threshold
238  *   n_leaf_boxes       --> number of boxes for a leaf
239  *   mem_final          --> theoretical memory for final search structure
240  *   mem_required       --> theoretical maximum memory for main structures
241  *                          used during the algorithm
242  *
243  * returns:
244  *   the spatial dimension associated with the box tree layout (3, 2, or 1)
245  *----------------------------------------------------------------------------*/
246 
247 int
248 fvm_neighborhood_get_box_stats(const fvm_neighborhood_t  *n,
249                                int                        depth[3],
250                                cs_lnum_t                  n_leaves[3],
251                                cs_lnum_t                  n_boxes[3],
252                                cs_lnum_t                  n_threshold_leaves[3],
253                                cs_lnum_t                  n_leaf_boxes[3],
254                                size_t                     mem_final[3],
255                                size_t                     mem_required[3]);
256 
257 /*----------------------------------------------------------------------------
258  * Return timing information.
259  *
260  * parameters:
261  *   n              <-- pointer to neighborhood management structure
262  *   build_wtime    --> initialization Wall-clock time (or NULL)
263  *   build_cpu_time --> initialization CPU time (or NULL)
264  *   query_wtime    --> query Wall-clock time (or NULL)
265  *   query_cpu_time --> query CPU time (or NULL)
266  *----------------------------------------------------------------------------*/
267 
268 void
269 fvm_neighborhood_get_times(const fvm_neighborhood_t  *n,
270                            double                    *build_wtime,
271                            double                    *build_cpu_time,
272                            double                    *query_wtime,
273                            double                    *query_cpu_time);
274 
275 /*----------------------------------------------------------------------------
276  * Dump a neighborhood management structure.
277  *
278  * parameters:
279  *   n <-- pointer to neighborhood management structure
280  *----------------------------------------------------------------------------*/
281 
282 void
283 fvm_neighborhood_dump(const fvm_neighborhood_t  *n);
284 
285 /*----------------------------------------------------------------------------*/
286 
287 END_C_DECLS
288 
289 #endif /* __FVM_NEIGHBORHOOD_H__ */
290