1 /*============================================================================
2  * Selection criteria for cells, boundary and interior faces.
3  *============================================================================*/
4 
5 /*
6   This file is part of Code_Saturne, a general-purpose CFD tool.
7 
8   Copyright (C) 1998-2021 EDF S.A.
9 
10   This program is free software; you can redistribute it and/or modify it under
11   the terms of the GNU General Public License as published by the Free Software
12   Foundation; either version 2 of the License, or (at your option) any later
13   version.
14 
15   This program is distributed in the hope that it will be useful, but WITHOUT
16   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17   FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
18   details.
19 
20   You should have received a copy of the GNU General Public License along with
21   this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
22   Street, Fifth Floor, Boston, MA 02110-1301, USA.
23 */
24 
25 /*----------------------------------------------------------------------------*/
26 
27 #include "cs_defs.h"
28 
29 /*----------------------------------------------------------------------------*/
30 
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include <assert.h>
35 #include <math.h>
36 
37 #include "bft_mem_usage.h"
38 #include "bft_mem.h"
39 #include "bft_error.h"
40 #include "bft_printf.h"
41 
42 #include "fvm_selector.h"
43 
44 #include "cs_halo.h"
45 #include "cs_mesh.h"
46 #include "cs_mesh_quantities.h"
47 
48 #include "cs_selector.h"
49 
50 /*----------------------------------------------------------------------------*/
51 
52 BEGIN_C_DECLS
53 
54 /*! \cond DOXYGEN_SHOULD_SKIP_THIS */
55 
56 /*=============================================================================
57  * Local Macro Definitions
58  *============================================================================*/
59 
60 /*=============================================================================
61  * Local Type Definitions
62  *============================================================================*/
63 
64 /*============================================================================
65  *  Global variables
66  *============================================================================*/
67 
68 /*============================================================================
69  * Private function definitions
70  *============================================================================*/
71 
72 /*! (DOXYGEN_SHOULD_SKIP_THIS) \endcond */
73 
74 /*=============================================================================
75  * Public function definitions
76  *============================================================================*/
77 
78 /*----------------------------------------------------------------------------
79  * Fill a list of boundary face numbers verifying a given selection criteria.
80  *
81  * parameters:
82  *   criteria        <-- selection criteria string
83  *   n_b_faces       --> number of selected interior faces
84  *   b_face_num_list --> list of selected boundary face numbers
85  *                       (1 to n, preallocated to cs_glob_mesh->n_b_faces)
86  *----------------------------------------------------------------------------*/
87 
88 void
cs_selector_get_b_face_num_list(const char * criteria,cs_lnum_t * n_b_faces,cs_lnum_t b_face_num_list[])89 cs_selector_get_b_face_num_list(const char  *criteria,
90                                 cs_lnum_t   *n_b_faces,
91                                 cs_lnum_t    b_face_num_list[])
92 {
93   int c_id;
94 
95   *n_b_faces = 0;
96 
97   if (cs_glob_mesh->select_b_faces == NULL)
98     bft_error(__FILE__, __LINE__, 0,
99               _("%sd: %s is not defined at this stage."),
100                 __func__, "cs_glob_mesh->select_b_faces");
101 
102   c_id = fvm_selector_get_list(cs_glob_mesh->select_b_faces,
103                                criteria,
104                                1,
105                                n_b_faces,
106                                b_face_num_list);
107 
108   if (fvm_selector_n_missing(cs_glob_mesh->select_b_faces, c_id) > 0) {
109     const char *missing
110       = fvm_selector_get_missing(cs_glob_mesh->select_b_faces, c_id, 0);
111     cs_base_warn(__FILE__, __LINE__);
112     bft_printf(_("The group \"%s\" in the selection criteria:\n"
113                  "\"%s\"\n"
114                  " does not correspond to any boundary face.\n"),
115                missing, criteria);
116   }
117 }
118 
119 /*----------------------------------------------------------------------------
120  * Fill a list of interior faces verifying a given selection criteria.
121  *
122  * parameters:
123  *   criteria        <-- selection criteria string
124  *   n_i_faces       --> number of selected interior faces
125  *   i_face_num_list --> list of selected interior face numbers
126  *                       (1 to n, preallocated to cs_glob_mesh->n_i_faces)
127  *----------------------------------------------------------------------------*/
128 
129 void
cs_selector_get_i_face_num_list(const char * criteria,cs_lnum_t * n_i_faces,cs_lnum_t i_face_num_list[])130 cs_selector_get_i_face_num_list(const char  *criteria,
131                                 cs_lnum_t   *n_i_faces,
132                                 cs_lnum_t    i_face_num_list[])
133 {
134   int c_id;
135 
136   *n_i_faces = 0;
137 
138   if (cs_glob_mesh->select_i_faces == NULL)
139     bft_error(__FILE__, __LINE__, 0,
140               _("%sd: %s is not defined at this stage."),
141                 __func__, "cs_glob_mesh->select_i_faces");
142 
143   c_id = fvm_selector_get_list(cs_glob_mesh->select_i_faces,
144                                criteria,
145                                1,
146                                n_i_faces,
147                                i_face_num_list);
148 
149   if (fvm_selector_n_missing(cs_glob_mesh->select_i_faces, c_id) > 0) {
150     const char *missing
151       = fvm_selector_get_missing(cs_glob_mesh->select_i_faces, c_id, 0);
152     cs_base_warn(__FILE__, __LINE__);
153     bft_printf(_("The group \"%s\" in the selection criteria:\n"
154                  "\"%s\"\n"
155                  " does not correspond to any interior face.\n"),
156                missing, criteria);
157   }
158 }
159 
160 /*----------------------------------------------------------------------------
161  * Fill a list of cells verifying a given selection criteria.
162  *
163  * parameters:
164  *   criteria      <-- selection criteria string
165  *   n_cells       --> number of selected cells
166  *   cell_num_list --> list of selected cell numbers
167  *                     (1 to n, preallocated to cs_glob_mesh->n_cells)
168  *----------------------------------------------------------------------------*/
169 
170 void
cs_selector_get_cell_num_list(const char * criteria,cs_lnum_t * n_cells,cs_lnum_t cell_num_list[])171 cs_selector_get_cell_num_list(const char  *criteria,
172                               cs_lnum_t   *n_cells,
173                               cs_lnum_t    cell_num_list[])
174 {
175   int c_id;
176 
177   *n_cells = 0;
178 
179   if (cs_glob_mesh->select_b_faces == NULL)
180     bft_error(__FILE__, __LINE__, 0,
181               _("%sd: %s is not defined at this stage."),
182                 __func__, "cs_glob_mesh->select_b_faces");
183 
184   c_id = fvm_selector_get_list(cs_glob_mesh->select_cells,
185                                criteria,
186                                1,
187                                n_cells,
188                                cell_num_list);
189 
190   if (fvm_selector_n_missing(cs_glob_mesh->select_cells, c_id) > 0) {
191     const char *missing
192       = fvm_selector_get_missing(cs_glob_mesh->select_cells, c_id, 0);
193     cs_base_warn(__FILE__, __LINE__);
194     bft_printf(_("The group \"%s\" in the selection criteria:\n"
195                  "\"%s\"\n"
196                  " does not correspond to any cell.\n"),
197                missing, criteria);
198   }
199 }
200 
201 /*----------------------------------------------------------------------------*/
202 /*!
203  * \brief Fill a list of boundary faces verifying a given selection criteria.
204  *
205  * \param[in]   criteria     selection criteria string
206  * \param[out]  n_b_faces    number of selected boundary faces
207  * \param[out]  b_face_list  list of selected boundary faces
208  *                           (0 to n-1, preallocated to cs_glob_mesh->n_b_faces)
209  */
210 /*----------------------------------------------------------------------------*/
211 
212 void
cs_selector_get_b_face_list(const char * criteria,cs_lnum_t * n_b_faces,cs_lnum_t b_face_list[])213 cs_selector_get_b_face_list(const char  *criteria,
214                             cs_lnum_t   *n_b_faces,
215                             cs_lnum_t    b_face_list[])
216 {
217   int c_id;
218 
219   *n_b_faces = 0;
220 
221   if (cs_glob_mesh->select_b_faces != NULL) {
222 
223     c_id = fvm_selector_get_list(cs_glob_mesh->select_b_faces,
224                                  criteria,
225                                  0,
226                                  n_b_faces,
227                                  b_face_list);
228 
229     if (fvm_selector_n_missing(cs_glob_mesh->select_b_faces, c_id) > 0) {
230       const char *missing
231         = fvm_selector_get_missing(cs_glob_mesh->select_b_faces, c_id, 0);
232       cs_base_warn(__FILE__, __LINE__);
233       bft_printf(_("The group \"%s\" in the selection criteria:\n"
234                    "\"%s\"\n"
235                    " does not correspond to any boundary face.\n"),
236                  missing, criteria);
237 
238     }
239 
240   }
241 
242   else {
243 
244     cs_mesh_t *mesh = cs_glob_mesh;
245 
246     bool del_class_defs = (mesh->class_defs == NULL) ? true : false;
247 
248     cs_mesh_init_group_classes(mesh);
249 
250     cs_real_t  *b_face_cog = NULL, *b_face_normal = NULL;
251 
252     cs_mesh_quantities_b_faces(mesh, &b_face_cog, &b_face_normal);
253 
254     fvm_selector_t *sel_b_faces = fvm_selector_create(mesh->dim,
255                                                       mesh->n_b_faces,
256                                                       mesh->class_defs,
257                                                       mesh->b_face_family,
258                                                       1,
259                                                       b_face_cog,
260                                                       b_face_normal);
261 
262     c_id = fvm_selector_get_list(sel_b_faces,
263                                  criteria,
264                                  0,
265                                  n_b_faces,
266                                  b_face_list);
267 
268     BFT_FREE(b_face_cog);
269     BFT_FREE(b_face_normal);
270 
271     if (del_class_defs)
272       mesh->class_defs = fvm_group_class_set_destroy(mesh->class_defs);
273 
274     sel_b_faces = fvm_selector_destroy(sel_b_faces);
275 
276   }
277 }
278 
279 /*----------------------------------------------------------------------------*/
280 /*!
281  * \brief Fill a list of interior faces verifying a given selection criteria.
282  *
283  * \param[in]   criteria     selection criteria string
284  * \param[out]  n_i_faces    number of selected interior faces
285  * \param[out]  i_face_list  list of selected interior faces
286  *                           (0 to n-1, preallocated to cs_glob_mesh->n_i_faces)
287  */
288 /*----------------------------------------------------------------------------*/
289 
290 void
cs_selector_get_i_face_list(const char * criteria,cs_lnum_t * n_i_faces,cs_lnum_t i_face_list[])291 cs_selector_get_i_face_list(const char  *criteria,
292                             cs_lnum_t   *n_i_faces,
293                             cs_lnum_t    i_face_list[])
294 {
295   int c_id;
296 
297   *n_i_faces = 0;
298 
299   if (cs_glob_mesh->select_b_faces != NULL) {
300 
301     c_id = fvm_selector_get_list(cs_glob_mesh->select_i_faces,
302                                  criteria,
303                                  0,
304                                  n_i_faces,
305                                  i_face_list);
306 
307     if (fvm_selector_n_missing(cs_glob_mesh->select_i_faces, c_id) > 0) {
308       const char *missing
309         = fvm_selector_get_missing(cs_glob_mesh->select_i_faces, c_id, 0);
310       cs_base_warn(__FILE__, __LINE__);
311       bft_printf(_("The group \"%s\" in the selection criteria:\n"
312                    "\"%s\"\n"
313                    " does not correspond to any interior face.\n"),
314                  missing, criteria);
315     }
316 
317   }
318 
319   else {
320 
321     cs_mesh_t *mesh = cs_glob_mesh;
322 
323     bool del_class_defs = (mesh->class_defs == NULL) ? true : false;
324 
325     cs_mesh_init_group_classes(mesh);
326 
327     cs_real_t  *i_face_cog = NULL, *i_face_normal = NULL;
328 
329     cs_mesh_quantities_i_faces(mesh, &i_face_cog, &i_face_normal);
330 
331     fvm_selector_t *sel_i_faces = fvm_selector_create(mesh->dim,
332                                                       mesh->n_i_faces,
333                                                       mesh->class_defs,
334                                                       mesh->i_face_family,
335                                                       1,
336                                                       i_face_cog,
337                                                       i_face_normal);
338 
339     c_id = fvm_selector_get_list(sel_i_faces,
340                                  criteria,
341                                  0,
342                                  n_i_faces,
343                                  i_face_list);
344 
345     BFT_FREE(i_face_cog);
346     BFT_FREE(i_face_normal);
347 
348     if (del_class_defs)
349       mesh->class_defs = fvm_group_class_set_destroy(mesh->class_defs);
350 
351     sel_i_faces = fvm_selector_destroy(sel_i_faces);
352 
353   }
354 
355 }
356 
357 /*----------------------------------------------------------------------------*/
358 /*!
359  * \brief Fill a list of cells verifying a given selection criteria.
360  *
361  * \param[in]   criteria   selection criteria string
362  * \param[out]  n_cells    number of selected cells
363  * \param[out]  cell_list  list of selected cells
364  *                         (0 to n-1, preallocated to cs_glob_mesh->n_cells)
365  */
366 /*----------------------------------------------------------------------------*/
367 
368 void
cs_selector_get_cell_list(const char * criteria,cs_lnum_t * n_cells,cs_lnum_t cell_list[])369 cs_selector_get_cell_list(const char  *criteria,
370                           cs_lnum_t   *n_cells,
371                           cs_lnum_t    cell_list[])
372 {
373   int c_id;
374 
375   *n_cells = 0;
376 
377   if (cs_glob_mesh->select_cells != NULL) {
378 
379     c_id = fvm_selector_get_list(cs_glob_mesh->select_cells,
380                                  criteria,
381                                  0,
382                                  n_cells,
383                                  cell_list);
384 
385     if (fvm_selector_n_missing(cs_glob_mesh->select_cells, c_id) > 0) {
386       const char *missing
387         = fvm_selector_get_missing(cs_glob_mesh->select_cells, c_id, 0);
388       cs_base_warn(__FILE__, __LINE__);
389       bft_printf(_("The group \"%s\" in the selection criteria:\n"
390                    "\"%s\"\n"
391                    " does not correspond to any cell.\n"),
392                  missing, criteria);
393     }
394 
395   }
396 
397   else {
398 
399     cs_mesh_t *mesh = cs_glob_mesh;
400 
401     bool del_class_defs = (mesh->class_defs == NULL) ? true : false;
402 
403     cs_mesh_init_group_classes(mesh);
404 
405     cs_real_t  *i_face_cog = NULL, *i_face_normal = NULL;
406     cs_real_t  *b_face_cog = NULL, *b_face_normal = NULL;
407     cs_real_t  *cell_cen = NULL;
408     BFT_MALLOC(cell_cen, mesh->n_cells_with_ghosts*3, cs_real_t);
409 
410     cs_mesh_quantities_i_faces(mesh, &i_face_cog, &i_face_normal);
411     cs_mesh_quantities_b_faces(mesh, &b_face_cog, &b_face_normal);
412 
413     cs_mesh_quantities_cell_faces_cog(mesh,
414                                       i_face_normal,
415                                       i_face_cog,
416                                       b_face_normal,
417                                       b_face_cog,
418                                       cell_cen);
419 
420     BFT_FREE(b_face_normal);
421     BFT_FREE(b_face_cog);
422     BFT_FREE(i_face_normal);
423     BFT_FREE(i_face_cog);
424 
425     fvm_selector_t *sel_cells = fvm_selector_create(mesh->dim,
426                                                     mesh->n_cells,
427                                                     mesh->class_defs,
428                                                     mesh->cell_family,
429                                                     1,
430                                                     cell_cen,
431                                                     NULL);
432 
433     c_id = fvm_selector_get_list(sel_cells,
434                                  criteria,
435                                  0,
436                                  n_cells,
437                                  cell_list);
438 
439     BFT_FREE(cell_cen);
440 
441     if (del_class_defs)
442       mesh->class_defs = fvm_group_class_set_destroy(mesh->class_defs);
443 
444     sel_cells = fvm_selector_destroy(sel_cells);
445 
446   }
447 
448 }
449 
450 /*----------------------------------------------------------------------------*/
451 /*!
452  * \brief Fill a list of cells verifying a given selection criteria.
453  *
454  * \param[in]   criteria    selection criteria string
455  * \param[out]  n_vertices  number of selected vertices
456  * \param[out]  vtx_ids     list of selected vertices
457  *                          (0 to n-1, preallocated to cs_glob_mesh->n_vertices)
458  */
459 /*----------------------------------------------------------------------------*/
460 
461 void
cs_selector_get_cell_vertices_list(const char * criteria,cs_lnum_t * n_vertices,cs_lnum_t vtx_ids[])462 cs_selector_get_cell_vertices_list(const char  *criteria,
463                                    cs_lnum_t   *n_vertices,
464                                    cs_lnum_t    vtx_ids[])
465 {
466   cs_lnum_t  n_cells = 0;
467   cs_lnum_t  *cell_ids = NULL;
468 
469   BFT_MALLOC(cell_ids, cs_glob_mesh->n_cells, cs_lnum_t);
470 
471   cs_selector_get_cell_list(criteria, &n_cells, cell_ids);
472   cs_selector_get_cell_vertices_list_by_ids(n_cells,
473                                             cell_ids,
474                                             n_vertices,
475                                             vtx_ids);
476 
477   BFT_FREE(cell_ids);
478 }
479 
480 /*----------------------------------------------------------------------------*/
481 /*!
482  * \brief Fill a list of vertices belonging to a given list of cells.
483  *
484  * \param[in]   n_cells     number of selected cells
485  * \param[in]   cell_ids    ids of selected cells
486  * \param[out]  n_vertices  number of selected vertices
487  * \param[out]  vtx_ids     list of selected vertices
488  *                          (0 to n-1, preallocated to cs_glob_mesh->n_vertices)
489  */
490 /*----------------------------------------------------------------------------*/
491 
492 void
cs_selector_get_cell_vertices_list_by_ids(cs_lnum_t n_cells,const cs_lnum_t cell_ids[],cs_lnum_t * n_vertices,cs_lnum_t vtx_ids[])493 cs_selector_get_cell_vertices_list_by_ids(cs_lnum_t         n_cells,
494                                           const cs_lnum_t   cell_ids[],
495                                           cs_lnum_t        *n_vertices,
496                                           cs_lnum_t         vtx_ids[])
497 {
498   const cs_mesh_t *m = cs_glob_mesh;
499   const cs_lnum_t _n_vertices = m->n_vertices;
500 
501   char *cell_flag;
502   BFT_MALLOC(cell_flag, m->n_cells, char);
503 
504   for (cs_lnum_t i = 0; i < m->n_cells; i++)
505     cell_flag[i] = 0;
506 
507   if (cell_ids != NULL) {
508     for (cs_lnum_t i = 0; i < n_cells; i++)
509       cell_flag[cell_ids[i]] = 1;
510   }
511   else {
512     for (cs_lnum_t i = 0; i < n_cells; i++)
513       cell_flag[i] = 1;
514   }
515 
516   for (cs_lnum_t i = 0; i < _n_vertices; i++)
517     vtx_ids[i] = -1;
518 
519   /* Now mark associated vertices using main connectivty
520      (could be faster when some adjacencies are available) */
521 
522   for (cs_lnum_t i = 0; i < m->n_i_faces; i++) {
523     for (cs_lnum_t j = 0; j < 2; j++) {
524       cs_lnum_t c_id = m->i_face_cells[i][j];
525       if (c_id < m->n_cells) {
526         if (cell_flag[c_id] != 0) {
527           cs_lnum_t s_id = m->i_face_vtx_idx[i];
528           cs_lnum_t e_id = m->i_face_vtx_idx[i+1];
529           for (cs_lnum_t k = s_id; k < e_id; k++)
530             vtx_ids[m->i_face_vtx_lst[k]] = 1;
531         }
532       }
533     }
534   }
535 
536   for (cs_lnum_t i = 0; i < m->n_b_faces; i++) {
537     cs_lnum_t c_id = m->b_face_cells[i];
538     if (cell_flag[c_id] != 0) {
539       cs_lnum_t s_id = m->b_face_vtx_idx[i];
540       cs_lnum_t e_id = m->b_face_vtx_idx[i+1];
541       for (cs_lnum_t k = s_id; k < e_id; k++)
542         vtx_ids[m->b_face_vtx_lst[k]] = 1;
543     }
544   }
545 
546   BFT_FREE(cell_flag);
547 
548   /* Now compact list */
549 
550   cs_lnum_t n = 0;
551   for (cs_lnum_t i = 0; i < _n_vertices; i++) {
552     if (vtx_ids[i] != -1) {
553       vtx_ids[n] = i;
554       n++;
555     }
556   }
557 
558   *n_vertices = n;
559 }
560 
561 /*----------------------------------------------------------------------------*/
562 /*!
563  * \brief Fill a list of vertices verifying a given boundary selection criteria.
564  *
565  * \param[in]   criteria    selection criteria string
566  * \param[out]  n_vertices  number of selected vertices
567  * \param[out]  vtx_ids     list of selected vertices
568  *                          (0 to n-1, preallocated to cs_glob_mesh->n_vertices)
569  */
570 /*----------------------------------------------------------------------------*/
571 
572 void
cs_selector_get_b_face_vertices_list(const char * criteria,cs_lnum_t * n_vertices,cs_lnum_t vtx_ids[])573 cs_selector_get_b_face_vertices_list(const char *criteria,
574                                      cs_lnum_t  *n_vertices,
575                                      cs_lnum_t   vtx_ids[])
576 {
577 
578   cs_lnum_t  n_faces = 0;
579   cs_lnum_t  *face_ids = NULL;
580 
581   BFT_MALLOC(face_ids, cs_glob_mesh->n_b_faces, cs_lnum_t);
582 
583   cs_selector_get_b_face_list(criteria, &n_faces, face_ids);
584   cs_selector_get_b_face_vertices_list_by_ids(n_faces,
585                                               face_ids,
586                                               n_vertices,
587                                               vtx_ids);
588 
589   BFT_FREE(face_ids);
590 }
591 
592 /*----------------------------------------------------------------------------*/
593 /*!
594  * \brief Fill a list of vertices belonging to a given list of boundary faces.
595  *
596  * \param[in]   n_cells     number of selected cells
597  * \param[in]   cell_ids    ids of selected cells
598  * \param[out]  n_vertices  number of selected vertices
599  * \param[out]  vtx_ids     list of selected vertices
600  *                          (0 to n-1, preallocated to cs_glob_mesh->n_vertices)
601  */
602 /*----------------------------------------------------------------------------*/
603 
604 void
cs_selector_get_b_face_vertices_list_by_ids(cs_lnum_t n_faces,const cs_lnum_t face_ids[],cs_lnum_t * n_vertices,cs_lnum_t vtx_ids[])605 cs_selector_get_b_face_vertices_list_by_ids(cs_lnum_t         n_faces,
606                                             const cs_lnum_t   face_ids[],
607                                             cs_lnum_t        *n_vertices,
608                                             cs_lnum_t         vtx_ids[])
609 {
610 
611   const cs_mesh_t *m = cs_glob_mesh;
612   const cs_lnum_t _n_vertices = m->n_vertices;
613 
614   for (cs_lnum_t i = 0; i < _n_vertices; i++)
615     vtx_ids[i] = -1;
616 
617   /* Mark vertices */
618   if (face_ids != NULL) {
619     for (cs_lnum_t i = 0; i < n_faces; i++) {
620       cs_lnum_t f_id = face_ids[i];
621       cs_lnum_t s_id = m->b_face_vtx_idx[f_id];
622       cs_lnum_t e_id = m->b_face_vtx_idx[f_id+1];
623       for (cs_lnum_t k = s_id; k < e_id; k++)
624         vtx_ids[m->b_face_vtx_lst[k]] = 1;
625     }
626   }
627   else {
628     for (cs_lnum_t i = 0; i < n_faces; i++) {
629       cs_lnum_t s_id = m->b_face_vtx_idx[i];
630       cs_lnum_t e_id = m->b_face_vtx_idx[i+1];
631       for (cs_lnum_t k = s_id; k < e_id; k++)
632         vtx_ids[m->b_face_vtx_lst[k]] = 1;
633     }
634   }
635 
636   /* Now compact list */
637 
638   cs_lnum_t n = 0;
639   for (cs_lnum_t i = 0; i < _n_vertices; i++) {
640     if (vtx_ids[i] != -1) {
641       vtx_ids[n] = i;
642       n++;
643     }
644   }
645 
646   *n_vertices = n;
647 
648 }
649 
650 /*----------------------------------------------------------------------------*/
651 /*!
652  * \brief Fill lists of faces at the boundary of a set of cells verifying
653  *        a given selection criteria.
654  *
655  * \param[in]   criteria   selection criteria string
656  * \param[out]  n_i_faces  number of selected interior faces
657  * \param[out]  n_b_faces  number of selected boundary faces
658  * \param[out]  i_face_id  list of selected interior faces
659  *                         (0 to n-1, preallocated to cs_glob_mesh->n_i_faces)
660  * \param[out]  b_face_id  list of selected boundary faces
661  *                         (0 to n-1, preallocated to cs_glob_mesh->n_b_faces)
662  */
663 /*----------------------------------------------------------------------------*/
664 
665 void
cs_selector_get_cells_boundary(const char * criteria,cs_lnum_t * n_i_faces,cs_lnum_t * n_b_faces,cs_lnum_t i_face_id[],cs_lnum_t b_face_id[])666 cs_selector_get_cells_boundary(const char  *criteria,
667                                cs_lnum_t   *n_i_faces,
668                                cs_lnum_t   *n_b_faces,
669                                cs_lnum_t    i_face_id[],
670                                cs_lnum_t    b_face_id[])
671 {
672   cs_lnum_t ii, n_cells;
673   cs_lnum_t *cell_list, *cell_flag;
674 
675   const cs_mesh_t *mesh = cs_glob_mesh;
676 
677   /* Mark cells inside zone selection */
678 
679   BFT_MALLOC(cell_list, mesh->n_cells, cs_lnum_t);
680   BFT_MALLOC(cell_flag, mesh->n_cells_with_ghosts, cs_lnum_t);
681 
682   for (ii = 0; ii < mesh->n_cells; ii++)
683     cell_flag[ii] = 0;
684 
685   n_cells = 0;
686 
687   cs_selector_get_cell_list(criteria, &n_cells, cell_list);
688 
689   for (ii = 0; ii < n_cells; ii++)
690     cell_flag[cell_list[ii]] = 1;
691 
692   BFT_FREE(cell_list);
693 
694   if (mesh->halo != NULL)
695     cs_halo_sync_num(mesh->halo, CS_HALO_STANDARD, cell_flag);
696 
697   /* Now build lists of faces on cell boundaries */
698 
699   for (ii = 0; ii < mesh->n_i_faces; ii++) {
700     cs_lnum_t c_id_0 = mesh->i_face_cells[ii][0];
701     cs_lnum_t c_id_1 = mesh->i_face_cells[ii][1];
702     if (cell_flag[c_id_0] != cell_flag[c_id_1]) {
703       i_face_id[*n_i_faces] = ii;
704       *n_i_faces += 1;
705     }
706   }
707 
708   for (ii = 0; ii < mesh->n_b_faces; ii++) {
709     cs_lnum_t c_id = mesh->b_face_cells[ii];
710     if (cell_flag[c_id] == 1) {
711       b_face_id[*n_b_faces] = ii;
712       *n_b_faces += 1;
713     }
714   }
715 
716   BFT_FREE(cell_flag);
717 }
718 
719 /*----------------------------------------------------------------------------*/
720 /*!
721  * \brief Fill a list of interior faces belonging to a given periodicity.
722  *
723  * \param[in]   perio_num  periodicity number
724  * \param[out]  n_i_faces  number of selected interior faces
725  * \param[out]  i_face_id  list of selected interior faces
726  *                         (0 to n-1, preallocated to cs_glob_mesh->n_i_faces)
727  */
728 /*----------------------------------------------------------------------------*/
729 
730 void
cs_selector_get_perio_face_list(int perio_num,cs_lnum_t * n_i_faces,cs_lnum_t i_face_id[])731 cs_selector_get_perio_face_list(int         perio_num,
732                                 cs_lnum_t  *n_i_faces,
733                                 cs_lnum_t   i_face_id[])
734 {
735   int ii;
736   int *face_perio_num = NULL;
737 
738   BFT_MALLOC(face_perio_num, cs_glob_mesh->n_i_faces, int);
739 
740   cs_mesh_get_face_perio_num(cs_glob_mesh, face_perio_num);
741 
742   *n_i_faces = 0;
743   for (ii = 0; ii < cs_glob_mesh->n_i_faces; ii++) {
744     if (CS_ABS(face_perio_num[ii]) == perio_num) {
745       i_face_id[*n_i_faces] = ii;
746       *n_i_faces += 1;
747     }
748   }
749 
750   BFT_FREE(face_perio_num);
751 }
752 
753 /*----------------------------------------------------------------------------*/
754 /*!
755  * \brief Fill a list of families verifying a given selection criteria.
756  *
757  * \param[in]   criteria     selection criteria string
758  * \param[out]  n_families   number of selected families
759  * \param[out]  family_list  list of selected family ids (preallocated to
760  *                           cs_glob_mesh->n_families + 1)
761  */
762 /*----------------------------------------------------------------------------*/
763 
764 void
cs_selector_get_family_list(const char * criteria,int * n_families,int family_list[])765 cs_selector_get_family_list(const char  *criteria,
766                             int         *n_families,
767                             int          family_list[])
768 {
769   int c_id;
770 
771   *n_families = 0;
772 
773   /* As all selectors were built with the same group class definitions,
774      any selector may be used here. */
775   c_id = fvm_selector_get_gc_list(cs_glob_mesh->select_cells,
776                                   criteria,
777                                   n_families,
778                                   family_list);
779 
780   if (fvm_selector_n_missing(cs_glob_mesh->select_b_faces, c_id) > 0) {
781     const char *missing
782       = fvm_selector_get_missing(cs_glob_mesh->select_b_faces, c_id, 0);
783     cs_base_warn(__FILE__, __LINE__);
784     bft_printf(_("The group \"%s\" in the selection criteria:\n"
785                  "\"%s\"\n"
786                  " is not present in the mesh.\n"),
787                missing, criteria);
788   }
789 
790   /* Families seen in mesh are 1-based, while selector is 0-based */
791 
792   for (int i = 0; i < *n_families; i++)
793     family_list[i] += 1;
794 }
795 
796 /*----------------------------------------------------------------------------*/
797 
798 END_C_DECLS
799