~ubuntu-branches/ubuntu/precise/code-saturne/precise

« back to all changes in this revision

Viewing changes to src/mesh/cs_mesh_connect.c

  • Committer: Package Import Robot
  • Author(s): Sylvestre Ledru
  • Date: 2011-11-01 17:43:32 UTC
  • mto: (6.1.7 sid)
  • mto: This revision was merged to the branch mainline in revision 11.
  • Revision ID: package-import@ubuntu.com-20111101174332-tl4vk45no0x3emc3
Tags: upstream-2.1.0
ImportĀ upstreamĀ versionĀ 2.1.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*============================================================================
 
2
 * Extract nodal connectivity mesh representations from a native mesh.
 
3
 *============================================================================*/
 
4
 
 
5
/*
 
6
  This file is part of Code_Saturne, a general-purpose CFD tool.
 
7
 
 
8
  Copyright (C) 1998-2011 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
#if defined(HAVE_CONFIG_H)
 
28
#include "cs_config.h"
 
29
#endif
 
30
 
 
31
/*----------------------------------------------------------------------------
 
32
 * Standard C library headers
 
33
 *----------------------------------------------------------------------------*/
 
34
 
 
35
#include <assert.h>
 
36
#include <stdio.h>
 
37
#include <stdlib.h>
 
38
#include <string.h>
 
39
 
 
40
/*----------------------------------------------------------------------------
 
41
 * BFT library headers
 
42
 *----------------------------------------------------------------------------*/
 
43
 
 
44
#include <bft_error.h>
 
45
#include <bft_mem.h>
 
46
 
 
47
/*----------------------------------------------------------------------------
 
48
 * Local headers
 
49
 *----------------------------------------------------------------------------*/
 
50
 
 
51
#include "cs_base.h"
 
52
#include "cs_mesh.h"
 
53
 
 
54
#include <fvm_defs.h>
 
55
#include <fvm_nodal.h>
 
56
#include <fvm_nodal_from_desc.h>
 
57
#include <fvm_nodal_order.h>
 
58
 
 
59
/*----------------------------------------------------------------------------
 
60
 *  Header for the current file
 
61
 *----------------------------------------------------------------------------*/
 
62
 
 
63
#include "cs_mesh_connect.h"
 
64
 
 
65
/*----------------------------------------------------------------------------*/
 
66
 
 
67
BEGIN_C_DECLS
 
68
 
 
69
/*=============================================================================
 
70
 * Local Macro Definitions
 
71
 *============================================================================*/
 
72
 
 
73
/*=============================================================================
 
74
 * Local Type Definitions
 
75
 *============================================================================*/
 
76
 
 
77
/*============================================================================
 
78
 *  Global variables
 
79
 *============================================================================*/
 
80
 
 
81
/*============================================================================
 
82
 * Private function definitions
 
83
 *============================================================================*/
 
84
 
 
85
/*----------------------------------------------------------------------------
 
86
 * Add a subset of a mesh's faces to an external mesh.
 
87
 *
 
88
 * The lists of faces to extract are optional (if none is given, boundary
 
89
 * faces are extracted by default); they do not need to be ordered on input,
 
90
 * but they are always ordered on exit (as faces are extracted by increasing
 
91
 * number traversal, the lists are reordered to ensure the coherency of
 
92
 * the extracted mesh's link to its parent faces, built using these lists).
 
93
 *
 
94
 * parameters:
 
95
 *   mesh             <-- base mesh
 
96
 *   extr_mesh        <-- extracted mesh name
 
97
 *   include_families <-- include family info if true
 
98
 *   i_face_list_size <-- size of i_face_list[] array
 
99
 *   b_face_list_size <-- size of b_face_list[] array
 
100
 *   i_face_list      <-> list of interior faces (1 to n), or NULL
 
101
 *   b_face_list      <-> list of boundary faces (1 to n), or NULL
 
102
 *
 
103
 * returns:
 
104
 *   pointer to extracted nodal mesh
 
105
 *----------------------------------------------------------------------------*/
 
106
 
 
107
static void
 
108
_add_faces_to_nodal(const cs_mesh_t  *mesh,
 
109
                    fvm_nodal_t      *extr_mesh,
 
110
                    cs_bool_t         include_families,
 
111
                    fvm_lnum_t        i_face_list_size,
 
112
                    fvm_lnum_t        b_face_list_size,
 
113
                    fvm_lnum_t        i_face_list[],
 
114
                    fvm_lnum_t        b_face_list[])
 
115
{
 
116
  fvm_lnum_t   face_id, i;
 
117
 
 
118
  fvm_lnum_t   n_max_faces = 0;
 
119
  fvm_lnum_t   b_face_count = 0;
 
120
  fvm_lnum_t   i_face_count = 0;
 
121
  fvm_lnum_t   extr_face_count = 0;
 
122
  fvm_lnum_t  *extr_face_idx = NULL;
 
123
  fvm_lnum_t  *extr_face_list = NULL;
 
124
 
 
125
  fvm_lnum_t   face_num_shift[3];
 
126
  fvm_lnum_t  *face_vertices_idx[2];
 
127
  fvm_lnum_t  *face_vertices_num[2];
 
128
  const int   *_face_families[2];
 
129
  const int   **face_families = NULL;
 
130
 
 
131
  fvm_gnum_t  *num_glob_fac = NULL;
 
132
 
 
133
  assert(sizeof(int) == sizeof(fvm_lnum_t)); /* For families */
 
134
 
 
135
  /* Count the number of faces to convert */
 
136
 
 
137
  n_max_faces = mesh->n_i_faces + mesh->n_b_faces;
 
138
  BFT_MALLOC(extr_face_idx, n_max_faces, fvm_lnum_t);
 
139
 
 
140
  /* Initialize index as marker */
 
141
 
 
142
  for (face_id = 0; face_id < n_max_faces; face_id++)
 
143
    extr_face_idx[face_id] = -1;
 
144
 
 
145
  if (b_face_list_size == mesh->n_b_faces) {
 
146
    for (face_id = 0; face_id < mesh->n_b_faces; face_id++)
 
147
      extr_face_idx[face_id] = 1;
 
148
  }
 
149
  else if (b_face_list != NULL) {
 
150
    for (face_id = 0; face_id < b_face_list_size; face_id++)
 
151
      extr_face_idx[b_face_list[face_id] - 1] = 1;
 
152
  }
 
153
 
 
154
  if (i_face_list_size == mesh->n_i_faces) {
 
155
    for (face_id = 0; face_id < mesh->n_i_faces; face_id++)
 
156
      extr_face_idx[face_id + mesh->n_b_faces] = 1;
 
157
  }
 
158
  else if (i_face_list != NULL) {
 
159
    for (face_id = 0; face_id < i_face_list_size; face_id++)
 
160
      extr_face_idx[i_face_list[face_id] - 1 + mesh->n_b_faces] = 1;
 
161
  }
 
162
 
 
163
  /* Convert marked ids to indexes (1 to n) and reconstruct values of
 
164
     b_face_list[] and i_face_list[] to ensure that they are ordered. */
 
165
 
 
166
  b_face_count = 0;
 
167
  i_face_count = 0;
 
168
 
 
169
  if (b_face_list != NULL) {
 
170
    for (face_id = 0; face_id < mesh->n_b_faces; face_id++) {
 
171
      if (extr_face_idx[face_id] == 1) {
 
172
        b_face_list[b_face_count] = face_id + 1;
 
173
        b_face_count++;
 
174
      }
 
175
    }
 
176
  }
 
177
  else
 
178
    b_face_count = CS_MIN(b_face_list_size, mesh->n_b_faces);
 
179
 
 
180
  if (i_face_list != NULL) {
 
181
    for (face_id = 0, i = mesh->n_b_faces;
 
182
         face_id < mesh->n_i_faces;
 
183
         face_id++, i++) {
 
184
      if (extr_face_idx[i] == 1) {
 
185
        i_face_list[i_face_count] = face_id + 1;
 
186
        i_face_count++;
 
187
      }
 
188
    }
 
189
  }
 
190
  else
 
191
    i_face_count = CS_MIN(i_face_list_size, mesh->n_i_faces);
 
192
 
 
193
  BFT_FREE(extr_face_idx);
 
194
 
 
195
  /* Build a contiguous list (boundary faces, interior faces) */
 
196
 
 
197
  extr_face_count = b_face_count + i_face_count;
 
198
 
 
199
  BFT_MALLOC(extr_face_list, extr_face_count, fvm_lnum_t);
 
200
 
 
201
  if (b_face_list != NULL) {
 
202
    for (face_id = 0; face_id < b_face_count; face_id++)
 
203
      extr_face_list[face_id] = b_face_list[face_id];
 
204
  }
 
205
  else if (b_face_list == NULL) { /* boundary faces by default if no list */
 
206
    for (face_id = 0; face_id < b_face_count; face_id++)
 
207
      extr_face_list[face_id] = face_id + 1;
 
208
  }
 
209
 
 
210
  if (i_face_list != NULL) {
 
211
    for (face_id = 0, i = b_face_count; face_id < i_face_count; face_id++, i++)
 
212
      extr_face_list[i] = i_face_list[face_id] + mesh->n_b_faces;
 
213
  }
 
214
  else if (i_face_list == NULL) {
 
215
    for (face_id = 0, i = b_face_count; face_id < i_face_count; face_id++, i++)
 
216
      extr_face_list[i] = face_id + mesh->n_b_faces + 1;
 
217
  }
 
218
 
 
219
  if (include_families) {
 
220
    _face_families[0] = mesh->b_face_family;
 
221
    _face_families[1] = mesh->i_face_family;
 
222
    face_families = _face_families;
 
223
  }
 
224
 
 
225
  /* Build the nodal connectivity */
 
226
 
 
227
  face_num_shift[0] = 0;
 
228
  face_num_shift[1] = mesh->n_b_faces + face_num_shift[0];
 
229
  face_num_shift[2] = mesh->n_i_faces + face_num_shift[1];
 
230
 
 
231
  face_vertices_idx[0] = mesh->b_face_vtx_idx;
 
232
  face_vertices_idx[1] = mesh->i_face_vtx_idx;
 
233
  face_vertices_num[0] = mesh->b_face_vtx_lst;
 
234
  face_vertices_num[1] = mesh->i_face_vtx_lst;
 
235
 
 
236
  fvm_nodal_from_desc_add_faces(extr_mesh,
 
237
                                extr_face_count,
 
238
                                extr_face_list,
 
239
                                2,
 
240
                                face_num_shift,
 
241
                                (const fvm_lnum_t **)face_vertices_idx,
 
242
                                (const fvm_lnum_t **)face_vertices_num,
 
243
                                face_families,
 
244
                                NULL);
 
245
 
 
246
  BFT_FREE(extr_face_list);
 
247
 
 
248
  /* In case of parallelism or face renumbering, sort faces by
 
249
     increasing global number */
 
250
 
 
251
  if (mesh->global_i_face_num != NULL || mesh->global_b_face_num != NULL) {
 
252
 
 
253
    BFT_MALLOC(num_glob_fac, n_max_faces, fvm_gnum_t);
 
254
 
 
255
    if (mesh->global_b_face_num == NULL) {
 
256
      for (face_id = 0; face_id < mesh->n_b_faces; face_id++)
 
257
        num_glob_fac[face_id] = face_id + 1;
 
258
    }
 
259
    else {
 
260
      for (face_id = 0; face_id < mesh->n_b_faces; face_id++)
 
261
        num_glob_fac[face_id] = mesh->global_b_face_num[face_id];
 
262
    }
 
263
 
 
264
    assert(mesh->n_g_b_faces + mesh->n_g_i_faces > 0);
 
265
 
 
266
    if (mesh->global_i_face_num == NULL) {
 
267
      for (face_id = 0, i = mesh->n_b_faces;
 
268
           face_id < mesh->n_i_faces;
 
269
           face_id++, i++)
 
270
        num_glob_fac[i] = face_id + 1 + mesh->n_g_b_faces;
 
271
    }
 
272
    else {
 
273
      for (face_id = 0, i = mesh->n_b_faces;
 
274
           face_id < mesh->n_i_faces;
 
275
           face_id++, i++)
 
276
        num_glob_fac[i] = mesh->global_i_face_num[face_id] + mesh->n_g_b_faces;
 
277
    }
 
278
 
 
279
  }
 
280
 
 
281
  /* Sort faces by increasing global number */
 
282
 
 
283
  fvm_nodal_order_faces(extr_mesh, num_glob_fac);
 
284
  fvm_nodal_init_io_num(extr_mesh, num_glob_fac, 2);
 
285
 
 
286
  if (num_glob_fac != NULL)
 
287
    BFT_FREE(num_glob_fac);
 
288
}
 
289
 
 
290
/*============================================================================
 
291
 * Public function definitions
 
292
 *============================================================================*/
 
293
 
 
294
/*----------------------------------------------------------------------------
 
295
 * Extract a mesh's "cells -> faces" connectivity.
 
296
 *
 
297
 * We consider a common numbering for internal and boundary faces, in which
 
298
 * boundary faces are defined first. The common id for the i-th boundary
 
299
 * face is thus i, and that of the j-th interior face is n_b_faces + j.
 
300
 *
 
301
 * If ind_cel_extr != NULL, then:
 
302
 * --- ind_cel_extr[cell_id] = id in the list to extract (0 to n-1)
 
303
 *     if cell cell_id should be extracted
 
304
 * --- ind_cel_extr[cell_id] = -1 if cells cell_id should be ignored
 
305
 *
 
306
 * parameters:
 
307
 *   mesh             <-- pointer to mesh structure
 
308
 *   extr_cell_size   <-- size of extr_cell_id[] array
 
309
 *   extr_cell_id     <-- extr_cell_id = ids of extracted cells, or -1
 
310
 *   p_cell_faces_idx --> cells -> faces index
 
311
 *   p_cell_faces_val --> cells -> faces connectivity
 
312
 *----------------------------------------------------------------------------*/
 
313
 
 
314
void
 
315
cs_mesh_connect_get_cell_faces(const cs_mesh_t             *mesh,
 
316
                               fvm_lnum_t                   extr_cell_size,
 
317
                               const fvm_lnum_t             extr_cell_id[],
 
318
                               fvm_lnum_t          * *const p_cell_faces_idx,
 
319
                               fvm_lnum_t          * *const p_cell_faces_val)
 
320
{
 
321
  fvm_lnum_t  cell_id, c_id1, c_id2, face_id, n_loc_cells;
 
322
 
 
323
  fvm_lnum_t  *cell_face_count = NULL;
 
324
  fvm_lnum_t  *cell_faces_idx = NULL;
 
325
  fvm_lnum_t  *cell_faces_val = NULL;
 
326
 
 
327
  /* Allocate and initialize cell ->faces index */
 
328
 
 
329
  n_loc_cells = mesh->n_cells;
 
330
  if (extr_cell_id != NULL)
 
331
    n_loc_cells = extr_cell_size;
 
332
 
 
333
  BFT_MALLOC(cell_faces_idx, n_loc_cells + 1, cs_int_t);
 
334
 
 
335
  for (cell_id = 0; cell_id < n_loc_cells + 1; cell_id++)
 
336
    cell_faces_idx[cell_id] = 0;
 
337
 
 
338
  /* Count number of faces per cell (we assign the temporary counter
 
339
     corresponding to cell_id to cell_faces_idx[cell_id + 1] rather than
 
340
     cell_faces_idx[cell_id] to simplify the next step) */
 
341
 
 
342
  /* Remark: test if cell_id < mesh->n_cells on internal faces so
 
343
     as to ignore ghost cells */
 
344
 
 
345
  for (face_id = 0; face_id < mesh->n_b_faces; face_id++) {
 
346
    cell_id = mesh->b_face_cells[face_id] - 1;
 
347
    if (extr_cell_id != NULL)
 
348
      cell_id = extr_cell_id[cell_id];
 
349
    if (cell_id > -1)
 
350
      cell_faces_idx[cell_id + 1] += 1;
 
351
  }
 
352
 
 
353
  for (face_id = 0; face_id < mesh->n_i_faces; face_id++) {
 
354
    c_id1 = mesh->i_face_cells[face_id*2    ] - 1;
 
355
    c_id2 = mesh->i_face_cells[face_id*2 + 1] - 1;
 
356
    if (extr_cell_id != NULL) {
 
357
      if (c_id1 < mesh->n_cells)
 
358
        c_id1 = extr_cell_id[c_id1];
 
359
      else
 
360
        c_id1 = -1;
 
361
      if (c_id2 < mesh->n_cells)
 
362
        c_id2 = extr_cell_id[c_id2];
 
363
      else
 
364
        c_id2 = -1;
 
365
    }
 
366
    if (c_id1 > -1 && c_id1 < mesh->n_cells)
 
367
      cell_faces_idx[c_id1 + 1] += 1;
 
368
    if (c_id2 > -1 && c_id2 < mesh->n_cells)
 
369
      cell_faces_idx[c_id2 + 1] += 1;
 
370
  }
 
371
 
 
372
  /* Build cell -> faces index */
 
373
 
 
374
  cell_faces_idx[0] = 1;
 
375
  for (cell_id = 0; cell_id < n_loc_cells; cell_id++)
 
376
    cell_faces_idx[cell_id + 1] += cell_faces_idx[cell_id];
 
377
 
 
378
  /* Build array of values */
 
379
 
 
380
  BFT_MALLOC(cell_faces_val, cell_faces_idx[n_loc_cells] - 1, cs_int_t);
 
381
  BFT_MALLOC(cell_face_count, n_loc_cells, cs_int_t);
 
382
 
 
383
  for (cell_id = 0; cell_id < n_loc_cells; cell_id++)
 
384
    cell_face_count[cell_id] = 0;
 
385
 
 
386
  for (face_id = 0; face_id < mesh->n_b_faces; face_id++) {
 
387
    cell_id = mesh->b_face_cells[face_id] - 1;
 
388
    if (extr_cell_id != NULL)
 
389
      cell_id = extr_cell_id[cell_id];
 
390
    if (cell_id > -1) {
 
391
      cell_faces_val[cell_faces_idx[cell_id] + cell_face_count[cell_id] - 1]
 
392
        = face_id + 1;
 
393
      cell_face_count[cell_id] += 1;
 
394
    }
 
395
  }
 
396
 
 
397
  for (face_id = 0; face_id < mesh->n_i_faces; face_id++) {
 
398
    c_id1 = mesh->i_face_cells[face_id*2    ] - 1;
 
399
    c_id2 = mesh->i_face_cells[face_id*2 + 1] - 1;
 
400
    if (extr_cell_id != NULL) {
 
401
      if (c_id1 < mesh->n_cells)
 
402
        c_id1 = extr_cell_id[c_id1];
 
403
      else
 
404
        c_id1 = -1;
 
405
      if (c_id2 < mesh->n_cells)
 
406
        c_id2 = extr_cell_id[c_id2];
 
407
      else
 
408
        c_id2 = -1;
 
409
    }
 
410
    if (c_id1 > -1 && c_id1 < mesh->n_cells) {
 
411
      cell_faces_val[cell_faces_idx[c_id1] + cell_face_count[c_id1] - 1]
 
412
        =   face_id + mesh->n_b_faces + 1;
 
413
      cell_face_count[c_id1] += 1;
 
414
    }
 
415
    if (c_id2 > -1 && c_id2 < mesh->n_cells) {
 
416
      cell_faces_val[cell_faces_idx[c_id2] + cell_face_count[c_id2] - 1]
 
417
        = -(face_id + mesh->n_b_faces + 1);
 
418
      cell_face_count[c_id2] += 1;
 
419
    }
 
420
  }
 
421
 
 
422
  BFT_FREE(cell_face_count);
 
423
 
 
424
  /* Return values */
 
425
 
 
426
  *p_cell_faces_idx = cell_faces_idx;
 
427
  *p_cell_faces_val = cell_faces_val;
 
428
 
 
429
#if 0 && defined(DEBUG) && !defined(NDEBUG)
 
430
 {
 
431
   cs_int_t ipos, ival;
 
432
   /* Print arrays */
 
433
   bft_printf("dbg : cs_mesh_ret_cel_fac\n"
 
434
              "nombre de cellules extraites = %d\n", extr_cell_size);
 
435
   for (ipos = 0; ipos < extr_cell_size; ipos++) {
 
436
     bft_printf("  cellule %d\n", ipos);
 
437
     bft_printf("    cell_faces_idx[%d] = %d\n", ipos, cell_faces_idx[ipos]);
 
438
     for (ival = cell_faces_idx[ipos]     - 1;
 
439
          ival < cell_faces_idx[ipos + 1] - 1;
 
440
          ival++)
 
441
       bft_printf("      cell_faces_val[%d] = %d\n",
 
442
                  ival, cell_faces_val[ival]);
 
443
   }
 
444
   bft_printf("  cell_faces_idx[%d] = %d\n", ipos, cell_faces_idx[ipos]);
 
445
 }
 
446
#endif
 
447
 
 
448
}
 
449
 
 
450
/*----------------------------------------------------------------------------
 
451
 * Build a nodal connectivity structure from a subset of a mesh's cells.
 
452
 *
 
453
 * The list of cells to extract is optional (if none is given, all cells
 
454
 * faces are extracted by default); it does not need to be ordered on input,
 
455
 * but is always ordered on exit (as cells are extracted by increasing number
 
456
 * traversal, the list is reordered to ensure the coherency of the extracted
 
457
 * mesh's link to its parent cells, built using this list).
 
458
 *
 
459
 * parameters:
 
460
 *   mesh             <-- base mesh
 
461
 *   name             <-- extracted mesh name
 
462
 *   include_families <-- include family info if true
 
463
 *   cell_list_size   <-- size of cell_list[] array
 
464
 *   cell_list        <-> list of cells (1 to n), or NULL
 
465
 *
 
466
 * returns:
 
467
 *   pointer to extracted nodal mesh
 
468
 *----------------------------------------------------------------------------*/
 
469
 
 
470
fvm_nodal_t  *
 
471
cs_mesh_connect_cells_to_nodal(const cs_mesh_t  *mesh,
 
472
                               const char       *name,
 
473
                               cs_bool_t         include_families,
 
474
                               fvm_lnum_t        cell_list_size,
 
475
                               fvm_lnum_t        cell_list[])
 
476
{
 
477
  fvm_lnum_t   face_id, cell_id;
 
478
 
 
479
  int          null_family = 0;
 
480
  fvm_lnum_t   extr_cell_count = 0, i_face_count = 0, b_face_count = 0;
 
481
  fvm_lnum_t  *extr_cell_idx = NULL;
 
482
 
 
483
  fvm_lnum_t  *cell_face_idx = NULL;
 
484
  fvm_lnum_t  *cell_face_num = NULL;
 
485
 
 
486
  fvm_lnum_t  *i_face_list= NULL, *b_face_list = NULL;
 
487
 
 
488
  fvm_lnum_t  face_num_shift[3];
 
489
  fvm_lnum_t  *face_vertices_idx[2];
 
490
  fvm_lnum_t  *face_vertices_num[2];
 
491
  fvm_lnum_t  *polyhedra_faces = NULL;
 
492
  const int   *cell_family = NULL;
 
493
 
 
494
  fvm_nodal_t  *extr_mesh;
 
495
 
 
496
  /* If a family has no attributes, it must be 1st by construction
 
497
     (as families are sorted when merging duplicates) */
 
498
 
 
499
  if (mesh->n_families > 0) {
 
500
    if (mesh->family_item[0] == 0)
 
501
      null_family = 1;
 
502
  }
 
503
 
 
504
  /* Check that the mesh contains face -> vertices connectivity */
 
505
 
 
506
  if (mesh->b_face_vtx_idx == NULL || mesh->i_face_vtx_idx == NULL)
 
507
    bft_error(__FILE__, __LINE__, 0,
 
508
              _("The main mesh does not contain any face -> vertices\n"
 
509
                "connectivity, necessary for the nodal connectivity\n"
 
510
                "reconstruction (cs_mesh_connect_cells_to_nodal)."));
 
511
 
 
512
  if (include_families) {
 
513
    BFT_MALLOC(i_face_list, mesh->n_i_faces, fvm_lnum_t);
 
514
    BFT_MALLOC(b_face_list, mesh->n_b_faces, fvm_lnum_t);
 
515
  }
 
516
 
 
517
  /* Count the number of cells to convert */
 
518
 
 
519
  if (cell_list != NULL) {
 
520
 
 
521
    BFT_MALLOC(extr_cell_idx, mesh->n_cells, fvm_lnum_t);
 
522
 
 
523
    /* Initialize index as marker */
 
524
 
 
525
    for (cell_id = 0; cell_id < mesh->n_cells; cell_id++)
 
526
      extr_cell_idx[cell_id] = -1;
 
527
    for (cell_id = 0; cell_id < cell_list_size; cell_id++) {
 
528
      if (cell_list[cell_id] <= mesh->n_cells)
 
529
        extr_cell_idx[cell_list[cell_id] - 1] = 1;
 
530
    }
 
531
 
 
532
    /* Also mark faces bearing families */
 
533
 
 
534
    if (include_families) {
 
535
 
 
536
      for (face_id = 0; face_id < mesh->n_i_faces; face_id++) {
 
537
        fvm_lnum_t c_id_0 = mesh->i_face_cells[face_id*2] - 1;
 
538
        fvm_lnum_t c_id_1 = mesh->i_face_cells[face_id*2 + 1] - 1;
 
539
        if (   (extr_cell_idx[c_id_0] == 1 || extr_cell_idx[c_id_1] == 1)
 
540
            && (mesh->i_face_family[face_id] != null_family)) {
 
541
          i_face_list[i_face_count++] = face_id + 1;
 
542
        }
 
543
      }
 
544
      BFT_REALLOC(i_face_list, i_face_count, fvm_lnum_t);
 
545
 
 
546
      for (face_id = 0; face_id < mesh->n_b_faces; face_id++) {
 
547
        fvm_lnum_t c_id = mesh->b_face_cells[face_id] - 1;
 
548
        if (   (extr_cell_idx[c_id] == 1)
 
549
            && (mesh->b_face_family[face_id] != null_family)) {
 
550
          b_face_list[b_face_count++] = face_id + 1;
 
551
        }
 
552
      }
 
553
      BFT_REALLOC(b_face_list, b_face_count, fvm_lnum_t);
 
554
 
 
555
    }
 
556
 
 
557
    /* Convert marked ids to indexes (1 to n) and reconstruct values of
 
558
       cell_list[] to ensure that it is ordered. */
 
559
 
 
560
    extr_cell_count = 0;
 
561
    for (cell_id = 0; cell_id < mesh->n_cells; cell_id++) {
 
562
      if (extr_cell_idx[cell_id] == 1) {
 
563
        cell_list[extr_cell_count] = cell_id + 1;
 
564
        extr_cell_idx[cell_id] = extr_cell_count++;
 
565
      }
 
566
    }
 
567
 
 
568
    assert(extr_cell_count <= cell_list_size);
 
569
 
 
570
  }
 
571
  else {
 
572
    extr_cell_count = CS_MIN(mesh->n_cells, cell_list_size);
 
573
    extr_cell_idx = NULL;
 
574
 
 
575
    if (include_families && extr_cell_count > 0) {
 
576
 
 
577
      for (face_id = 0; face_id < mesh->n_i_faces; face_id++) {
 
578
        fvm_lnum_t c_id_0 = mesh->i_face_cells[face_id*2] - 1;
 
579
        fvm_lnum_t c_id_1 = mesh->i_face_cells[face_id*2 + 1] - 1;
 
580
        if (   (c_id_0 < extr_cell_count || c_id_1 < extr_cell_count)
 
581
            && (mesh->i_face_family[face_id] != null_family)) {
 
582
          i_face_list[i_face_count++] = face_id + 1;
 
583
        }
 
584
      }
 
585
      BFT_REALLOC(i_face_list, i_face_count, fvm_lnum_t);
 
586
 
 
587
      for (face_id = 0; face_id < mesh->n_b_faces; face_id++) {
 
588
        fvm_lnum_t c_id = mesh->b_face_cells[face_id] - 1;
 
589
        if (   (c_id < extr_cell_count)
 
590
            && (mesh->b_face_family[face_id] != null_family)) {
 
591
          b_face_list[b_face_count++] = face_id + 1;
 
592
        }
 
593
      }
 
594
      BFT_REALLOC(b_face_list, b_face_count, fvm_lnum_t);
 
595
 
 
596
    }
 
597
  }
 
598
 
 
599
  /* Extract "cells -> faces" connectivity */
 
600
 
 
601
  cs_mesh_connect_get_cell_faces(mesh,
 
602
                                 extr_cell_count,
 
603
                                 extr_cell_idx,
 
604
                                 &cell_face_idx,
 
605
                                 &cell_face_num);
 
606
 
 
607
  if (extr_cell_idx != NULL)
 
608
    BFT_FREE(extr_cell_idx);
 
609
 
 
610
  /* Build nodal connectivity */
 
611
 
 
612
  face_num_shift[0] = 0;
 
613
  face_num_shift[1] = mesh->n_b_faces + face_num_shift[0];
 
614
  face_num_shift[2] = mesh->n_i_faces + face_num_shift[1];
 
615
 
 
616
  face_vertices_idx[0] = mesh->b_face_vtx_idx;
 
617
  face_vertices_idx[1] = mesh->i_face_vtx_idx;
 
618
  face_vertices_num[0] = mesh->b_face_vtx_lst;
 
619
  face_vertices_num[1] = mesh->i_face_vtx_lst;
 
620
 
 
621
  extr_mesh = fvm_nodal_create(name, 3);
 
622
 
 
623
  assert(sizeof(int) == sizeof(fvm_lnum_t)); /* For families */
 
624
 
 
625
  if (include_families)
 
626
    cell_family = mesh->cell_family;
 
627
 
 
628
  fvm_nodal_from_desc_add_cells(extr_mesh,
 
629
                                extr_cell_count,
 
630
                                NULL,
 
631
                                2,
 
632
                                face_num_shift,
 
633
                                (const fvm_lnum_t **)face_vertices_idx,
 
634
                                (const fvm_lnum_t **)face_vertices_num,
 
635
                                cell_face_idx,
 
636
                                cell_face_num,
 
637
                                cell_family,
 
638
                                cell_list,
 
639
                                &polyhedra_faces);
 
640
 
 
641
  /* Also add faces bearing families */
 
642
 
 
643
  if (include_families) {
 
644
 
 
645
    _add_faces_to_nodal(mesh,
 
646
                        extr_mesh,
 
647
                        include_families,
 
648
                        i_face_count,
 
649
                        b_face_count,
 
650
                        i_face_list,
 
651
                        b_face_list);
 
652
 
 
653
    BFT_FREE(i_face_list);
 
654
    BFT_FREE(b_face_list);
 
655
  }
 
656
 
 
657
  fvm_nodal_set_shared_vertices(extr_mesh, mesh->vtx_coord);
 
658
  fvm_nodal_set_group_class_set(extr_mesh, mesh->class_defs);
 
659
 
 
660
  /* Free memory */
 
661
 
 
662
  BFT_FREE(polyhedra_faces);
 
663
 
 
664
  BFT_FREE(cell_face_idx);
 
665
  BFT_FREE(cell_face_num);
 
666
 
 
667
  /* Sort cells by increasing global number */
 
668
 
 
669
  fvm_nodal_order_cells(extr_mesh, mesh->global_cell_num);
 
670
  fvm_nodal_init_io_num(extr_mesh, mesh->global_cell_num, 3);
 
671
 
 
672
  /* Sort vertices by increasing global number */
 
673
 
 
674
  fvm_nodal_order_vertices(extr_mesh, mesh->global_vtx_num);
 
675
  fvm_nodal_init_io_num(extr_mesh, mesh->global_vtx_num, 0);
 
676
 
 
677
  /* We are done */
 
678
 
 
679
  return extr_mesh;
 
680
}
 
681
 
 
682
/*----------------------------------------------------------------------------
 
683
 * Build a nodal connectivity structure from a subset of a mesh's faces.
 
684
 *
 
685
 * The lists of faces to extract are optional (if none is given, boundary
 
686
 * faces are extracted by default); they do not need to be ordered on input,
 
687
 * but they are always ordered on exit (as faces are extracted by increasing
 
688
 * number traversal, the lists are reordered to ensure the coherency of
 
689
 * the extracted mesh's link to its parent faces, built using these lists).
 
690
 *
 
691
 * parameters:
 
692
 *   mesh             <-- base mesh
 
693
 *   name             <-- extracted mesh name
 
694
 *   include_families <-- include family info if true
 
695
 *   i_face_list_size <-- size of i_face_list[] array
 
696
 *   b_face_list_size <-- size of b_face_list[] array
 
697
 *   i_face_list      <-> list of interior faces (1 to n), or NULL
 
698
 *   b_face_list      <-> list of boundary faces (1 to n), or NULL
 
699
 *
 
700
 * returns:
 
701
 *   pointer to extracted nodal mesh
 
702
 *----------------------------------------------------------------------------*/
 
703
 
 
704
fvm_nodal_t *
 
705
cs_mesh_connect_faces_to_nodal(const cs_mesh_t  *mesh,
 
706
                               const char       *name,
 
707
                               cs_bool_t         include_families,
 
708
                               fvm_lnum_t        i_face_list_size,
 
709
                               fvm_lnum_t        b_face_list_size,
 
710
                               fvm_lnum_t        i_face_list[],
 
711
                               fvm_lnum_t        b_face_list[])
 
712
{
 
713
  fvm_nodal_t  *extr_mesh = NULL;
 
714
 
 
715
  assert(sizeof(int) == sizeof(fvm_lnum_t)); /* For families */
 
716
 
 
717
  /* Check that the mesh contains face -> vertices connectivity */
 
718
 
 
719
  if (mesh->b_face_vtx_idx == NULL || mesh->i_face_vtx_idx == NULL)
 
720
    bft_error(__FILE__, __LINE__, 0,
 
721
              _("The main mesh does not contain any face -> vertices\n"
 
722
                "connectivity, necessary for the nodal connectivity\n"
 
723
                "reconstruction (cs_mesh_connect_faces_to_nodal)."));
 
724
 
 
725
  extr_mesh = fvm_nodal_create(name, 3);
 
726
 
 
727
  _add_faces_to_nodal(mesh,
 
728
                      extr_mesh,
 
729
                      include_families,
 
730
                      i_face_list_size,
 
731
                      b_face_list_size,
 
732
                      i_face_list,
 
733
                      b_face_list);
 
734
 
 
735
  fvm_nodal_set_shared_vertices(extr_mesh,
 
736
                                mesh->vtx_coord);
 
737
 
 
738
  /* Sort vertices by increasing global number */
 
739
 
 
740
  fvm_nodal_order_vertices(extr_mesh, mesh->global_vtx_num);
 
741
  fvm_nodal_init_io_num(extr_mesh, mesh->global_vtx_num, 0);
 
742
 
 
743
  /* Define group classes */
 
744
 
 
745
  if (include_families)
 
746
    fvm_nodal_set_group_class_set(extr_mesh, mesh->class_defs);
 
747
 
 
748
  /* We are done */
 
749
 
 
750
  return extr_mesh;
 
751
}
 
752
 
 
753
/*----------------------------------------------------------------------------*/
 
754
 
 
755
END_C_DECLS