1 #ifndef __CS_JOIN_UTIL_H__
2 #define __CS_JOIN_UTIL_H__
3 
4 /*============================================================================
5  * Manipulation of low-level structures for joining operations
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  * Standard C library headers
32  *---------------------------------------------------------------------------*/
33 
34 #include <stdio.h>
35 
36 /*----------------------------------------------------------------------------
37  * Local headers
38  *---------------------------------------------------------------------------*/
39 
40 #include "fvm_defs.h"
41 #include "fvm_periodicity.h"
42 
43 #include "cs_base.h"
44 #include "cs_selector.h"
45 #include "cs_timer.h"
46 
47 /*---------------------------------------------------------------------------*/
48 
49 BEGIN_C_DECLS
50 
51 /*============================================================================
52  * Macro and type definitions
53  *============================================================================*/
54 
55 typedef enum {
56 
57   CS_JOIN_TYPE_NULL,
58   CS_JOIN_TYPE_CONFORMING,
59   CS_JOIN_TYPE_NON_CONFORMING
60 
61 } cs_join_type_t;
62 
63 typedef enum {
64 
65   CS_JOIN_STATE_UNDEF,
66   CS_JOIN_STATE_NEW,
67   CS_JOIN_STATE_ORIGIN,
68   CS_JOIN_STATE_PERIO,
69   CS_JOIN_STATE_MERGE,
70   CS_JOIN_STATE_PERIO_MERGE,
71   CS_JOIN_STATE_SPLIT
72 
73 } cs_join_state_t;
74 
75 /*----------------------------------------------------------------------------
76  * Joining statistics
77  *----------------------------------------------------------------------------*/
78 
79 typedef struct {
80 
81   int        n_calls;               /* number of calls */
82 
83   /* Intersection determination info */
84 
85   int        bbox_layout;            /* bounding box layout */
86   cs_gnum_t  bbox_depth[3];          /* box tree depth */
87   cs_gnum_t  n_leaves[3];            /* number of leaves */
88   cs_gnum_t  n_boxes[3];             /* number of boxes */
89   cs_gnum_t  n_th_leaves[3];         /* number leaves over threshold */
90   cs_gnum_t  n_leaf_boxes[3];        /* number of boxes per leaf */
91   cs_gnum_t  box_mem_final[3];       /* final box memory required */
92   cs_gnum_t  box_mem_required[3];    /* memory required */
93 
94   cs_timer_counter_t  t_box_build;   /* box build times */
95   cs_timer_counter_t  t_box_query;   /* box query times */
96   cs_timer_counter_t  t_inter_sort;   /* sort intersections times */
97 
98   /* other info */
99 
100   cs_timer_counter_t  t_l_join_mesh;  /* build local joining mesh times */
101   cs_timer_counter_t  t_edge_inter;   /* edge intersection times */
102   cs_timer_counter_t  t_new_vtx;      /* new vertices times */
103   cs_timer_counter_t  t_merge_vtx;    /* merge vertices times */
104   cs_timer_counter_t  t_u_merge_vtx;  /* update after merge vertices times */
105   cs_timer_counter_t  t_split_faces;  /* split faces times */
106 
107   cs_timer_counter_t  t_total;        /* total time */
108 
109 }  cs_join_stats_t;
110 
111 /*----------------------------------------------------------------------------
112  * Set of user parameters to control the join operation
113  *----------------------------------------------------------------------------*/
114 
115 typedef struct {
116 
117   int  num;         /* number associated to the current join operation */
118   int  perio_type;  /* FVM_PERIODICITY_NULL for non-periodic joinings,
119                        periodicity type for periodic joinings. */
120 
121   double perio_matrix[3][4];  /* Periodicity matrix for periodic joinings */
122 
123   /* Octree - Quadtree search algorithm */
124   /* ---------------------------------- */
125 
126   int    tree_max_level;     /* Deepest level reachable during tree building */
127   int    tree_n_max_boxes;   /* Max. number of boxes which can be related to
128                                a leaf of the tree if level != tree_max_level */
129 
130   float  tree_max_box_ratio; /* Stop building tree when:
131                                 (  n_linked_boxes
132                                  > tree_max_box_ratio * n_init_boxes) */
133   float  tree_max_box_ratio_distrib; /* In parallel, tree_max_box_ratio for
134                                         initial coarse tree used to
135                                         determine load-distribution */
136 
137   /* Geometric parameters */
138   /* -------------------- */
139 
140   /* parameter used to compute the tolerance associated to each vertex.
141      Also used for finding equivalent vertices during edge intersections */
142 
143   float  fraction;
144 
145   /* maximum angle between normals of two faces considered to
146      be in the same plane (for face split) */
147 
148   float  plane; /* in degree */
149   double plane_criteria; /* cos(plane in rad)*cos(plane in rad) */
150 
151   /* Coef. used to modify the tolerance associated to each vertex before the
152      merge operation.
153      If coef = 0.0 => no vertex merge
154      If coef < 1.0 => reduce vertex merge
155      If coef = 1.0 => no change
156      If coef > 1.0 => increase vertex merge */
157 
158   float  merge_tol_coef;
159 
160   /* Coef. used to compute a limit on staightfoward merge between
161      two vertices before the merge step. It should be a small value. */
162 
163   float  pre_merge_factor;
164 
165   /* Maximum number of equivalence breaks */
166 
167   int  n_max_equiv_breaks;
168 
169    /* Tolerance computation mode: tcm
170       1: (default) tol = min. edge length related to a vertex * fraction
171       2: tolerance is computed like in mode 1 with in addition, the
172          multiplication by a coef. which is equal to the max sin(e1, e2)
173          where e1 and e2 are two edges sharing the same vertex V for which
174          we want to compute the tolerance
175      11: like 1 but only in taking into account only the selected faces
176      12: like 2 but only in taking into account only the selected faces */
177 
178   int  tcm;
179 
180    /* Intersection computation mode: icm
181       1: (default) Original algorithm. Try to clip intersection on extremity
182       2: New intersection algorithm. Avoid to clip intersection on extremity
183    */
184 
185   int  icm;
186 
187   /* Maximum number of sub-faces when splitting a face */
188 
189   int  max_sub_faces;
190 
191   /* Verbosity:
192        O : no information printed
193        1 : general information printed
194        2 : more information printed
195        5 and beyond : highest level (DEBUG LEVEL) */
196 
197   int  verbosity;
198 
199   /* Visualization level:
200        O : no visualization output
201        1 : visualization output of joined faces
202        2 : faces modified by joining
203   */
204 
205   int  visualization;
206 
207   /* Preprocessing flag:
208      true if this joining is part of preprocessing, false otherwise */
209 
210   bool preprocessing;
211 
212 } cs_join_param_t;
213 
214 /*----------------------------------------------------------------------------
215  * Set of variables to synchronize single elements
216  *---------------------------------------------------------------------------*/
217 
218 /*! \cond DOXYGEN_SHOULD_SKIP_THIS */
219 
220 typedef struct {
221 
222   cs_lnum_t   n_elts;
223   int         n_ranks;
224   int        *ranks;
225   cs_lnum_t  *index;
226   cs_lnum_t  *array;
227 
228 } cs_join_sync_t;
229 
230 /*----------------------------------------------------------------------------
231  * Structure used to store the result of the extraction of entities
232  * implied in the joining operation
233  *---------------------------------------------------------------------------*/
234 
235 typedef struct {
236 
237   cs_lnum_t     n_init_b_faces;  /* Number of border faces before joining */
238   cs_lnum_t     n_init_i_faces;  /* Number of interior faces before joining */
239   cs_lnum_t     n_init_vertices; /* Number of vertices before joining */
240 
241   cs_lnum_t     n_faces;     /* Number of border faces selected
242                                 for the joining operation */
243   cs_gnum_t     n_g_faces;   /* Global number of border faces selected
244                                 for the joining operation */
245   cs_lnum_t    *faces;       /* List of selected border faces */
246 
247   cs_gnum_t    *compact_face_gnum;    /* Global face numbering defined
248                                          on the selected faces */
249   cs_gnum_t    *compact_rank_index;   /* Distribution of the selected faces
250                                          over the ranks */
251 
252   cs_lnum_t     n_vertices;      /* Number of vertices selected
253                                     for the joining operation */
254   cs_gnum_t     n_g_vertices;    /* Global number of selected vertices */
255   cs_lnum_t     *vertices;        /* List of selected vertices */
256 
257   /* Adjacent faces of the current face selection: border and interior */
258 
259   cs_lnum_t     n_b_adj_faces;
260   cs_lnum_t     n_i_adj_faces;
261 
262   cs_lnum_t    *b_adj_faces;
263   cs_lnum_t    *i_adj_faces;
264 
265   /* Keep the status of all faces of the related cs_mesh_t */
266 
267   cs_join_state_t   *b_face_state;
268   cs_join_state_t   *i_face_state;
269 
270   /* For periodicity handling: list of periodic vertex couples */
271 
272   cs_lnum_t    n_couples;
273   cs_gnum_t   *per_v_couples;
274 
275   /*
276      Single elements (Only possible in parallel). Appear mainly
277      when the domain splitting has a poor quality and elements
278      on the joining interface are prisms or tetrahedra
279      s = single (receiver) / c = coupled (owner).
280   */
281 
282   bool         do_single_sync;
283 
284   cs_join_sync_t  *s_vertices;
285   cs_join_sync_t  *c_vertices;
286   cs_join_sync_t  *s_edges;
287   cs_join_sync_t  *c_edges;
288 
289 } cs_join_select_t;
290 
291 /*----------------------------------------------------------------------------
292  * Highest level structure to manage the joining algorithm
293  *---------------------------------------------------------------------------*/
294 
295 typedef struct {
296 
297   cs_join_param_t   param;       /* Set of parameters used to control
298                                     the joining operations */
299 
300   cs_join_stats_t   stats;       /* Performance statistics */
301 
302   cs_join_select_t  *selection;  /* Store entities implied in the joining
303                                     operation */
304 
305   char              *criteria;   /* Criteria used to select border faces
306                                     implied in the joining operation */
307 
308   char              *log_name;   /* Optional log file name */
309 
310 } cs_join_t;
311 
312 /*=============================================================================
313  * Global variables
314  *===========================================================================*/
315 
316 extern int  cs_glob_join_count;
317 extern int  cs_glob_n_joinings;
318 extern cs_join_t  **cs_glob_join_array;
319 
320 extern FILE  *cs_glob_join_log;
321 
322 /*! (DOXYGEN_SHOULD_SKIP_THIS) \endcond */
323 
324 /*============================================================================
325  * Public function prototypes
326  *===========================================================================*/
327 
328 /*----------------------------------------------------------------------------
329  * Create and initialize a cs_join_t structure.
330  *
331  * parameters:
332  *   join_number   <-- number related to the joining operation
333  *   sel_criteria  <-- boundary face selection criteria
334  *   fraction      <-- value of the fraction parameter
335  *   plane         <-- value of the plane parameter
336  *   perio_type    <-- periodicity type (FVM_PERIODICITY_NULL if none)
337  *   perio_matrix  <-- periodicity transformation matrix
338  *   verbosity     <-- level of verbosity required
339  *   visualization <-- level of visualization required
340  *   preprocessing <-- is joining part of the preprocessing stage ?
341  *
342  * returns:
343  *   a pointer to a new allocated cs_join_t structure
344  *---------------------------------------------------------------------------*/
345 
346 cs_join_t *
347 cs_join_create(int                      join_number,
348                const char              *sel_criteria,
349                float                    fraction,
350                float                    plane,
351                fvm_periodicity_type_t   perio_type,
352                double                   perio_matrix[3][4],
353                int                      verbosity,
354                int                      visualization,
355                bool                     preprocessing);
356 
357 /*----------------------------------------------------------------------------
358  * Destroy a cs_join_t structure.
359  *
360  * parameters:
361  *  join <-> pointer to the cs_join_t structure to destroy
362  *---------------------------------------------------------------------------*/
363 
364 void
365 cs_join_destroy(cs_join_t  **join);
366 
367 /*----------------------------------------------------------------------------
368  * Create and initialize a cs_join_select_t structure.
369  *
370  * parameters:
371  *   selection_criteria <-- pointer to a cs_mesh_select_t structure
372  *   perio_type         <-- periodicity type (FVM_PERIODICITY_NULL if none)
373  *   verbosity          <-- level of verbosity required
374  *
375  * returns:
376  *   pointer to a newly created cs_join_select_t structure
377  *---------------------------------------------------------------------------*/
378 
379 cs_join_select_t *
380 cs_join_select_create(const char              *selection_criteria,
381                       fvm_periodicity_type_t   perio_type,
382                       int                      verbosity);
383 
384 /*----------------------------------------------------------------------------
385  * Destroy a cs_join_select_t structure.
386  *
387  * parameters:
388  *   param       <-- user-defined joining parameters
389  *   join_select <-- pointer to pointer to structure to destroy
390  *---------------------------------------------------------------------------*/
391 
392 void
393 cs_join_select_destroy(cs_join_param_t     param,
394                        cs_join_select_t  **join_select);
395 
396 /*----------------------------------------------------------------------------
397  * Extract vertices from a selection of faces.
398  *
399  * parameters:
400  *   n_select_faces <-- number of selected faces
401  *   select_faces   <-- list of faces selected
402  *   f2v_idx        <-- "face -> vertex" connect. index
403  *   f2v_lst        <-- "face -> vertex" connect. list
404  *   n_vertices     <-- number of vertices
405  *   n_sel_vertices <-> pointer to the number of selected vertices
406  *   sel_vertices   <-> pointer to the list of selected vertices
407  *---------------------------------------------------------------------------*/
408 
409 void
410 cs_join_extract_vertices(cs_lnum_t         n_select_faces,
411                          const cs_lnum_t  *select_faces,
412                          const cs_lnum_t  *f2v_idx,
413                          const cs_lnum_t  *f2v_lst,
414                          cs_lnum_t         n_vertices,
415                          cs_lnum_t        *n_select_vertices,
416                          cs_lnum_t        *select_vertices[]);
417 
418 /*----------------------------------------------------------------------------
419  * Eliminate redundancies found between two lists of elements.
420  * Delete elements in elts[] and keep elements in the reference list.
421  *
422  * parameters:
423  *  n_elts     <-> number of elements in the list to clean
424  *  elts       <-> list of elements in the list to clean
425  *  n_ref_elts <-- number of elements in the reference list
426  *  ref_elts   <-- list of reference elements
427  *---------------------------------------------------------------------------*/
428 
429 void
430 cs_join_clean_selection(cs_lnum_t  *n_elts,
431                         cs_lnum_t  *elts[],
432                         cs_lnum_t   n_ref_elts,
433                         cs_lnum_t   ref_elts[]);
434 
435 /*----------------------------------------------------------------------------
436  * Build vertex -> vertex index for a selection of faces.
437  *
438  * "v2v_idx" is already allocated to the number of vertices in the mesh.
439  * At this stage, it is just a counter.
440  *
441  * parameters:
442  *   n_faces <-- number of selected faces
443  *   faces   <-- list of selected faces
444  *   f2v_idx <-- face -> vertex connectivity index
445  *   f2v_lst <-- face -> vertex connectivity list
446  *   v2v_idx <-> index to build (already allocated and may be used again)
447  *---------------------------------------------------------------------------*/
448 
449 void
450 cs_join_build_edges_idx(cs_lnum_t        n_faces,
451                         const cs_lnum_t  faces[],
452                         const cs_lnum_t  f2v_idx[],
453                         const cs_lnum_t  f2v_lst[],
454                         cs_lnum_t        v2v_idx[]);
455 
456 /*----------------------------------------------------------------------------
457  * Build vertex -> vertex list for a selection of faces.
458  * "count" and "v2v_lst" are already allocated to the number of vertices in
459  * the mesh.
460  *
461  * parameters:
462  *   n_faces <-- number of selected faces
463  *   faces   <-- list of selected faces
464  *   f2v_idx <-- face -> vertex connectivity index
465  *   f2v_lst <-- face -> vertex connectivity list
466  *   count   <-> array used to count the number of values already added
467  *   v2v_idx <-- vertex -> vertex connect. index
468  *   v2v_lst <-> vertex -> vertex connect. list to build (can be used again)
469  *---------------------------------------------------------------------------*/
470 
471 void
472 cs_join_build_edges_lst(cs_lnum_t        n_faces,
473                         const cs_lnum_t  faces[],
474                         const cs_lnum_t  f2v_idx[],
475                         const cs_lnum_t  f2v_lst[],
476                         cs_lnum_t        count[],
477                         const cs_lnum_t  v2v_idx[],
478                         cs_lnum_t        v2v_lst[]);
479 
480 /*---------------------------------------------------------------------------*/
481 
482 END_C_DECLS
483 
484 #endif /* __CS_JOIN_UTIL_H__ */
485