1 /*============================================================================
2 * Append sections to a nodal representation associated with a mesh
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 * Standard C library headers
31 *----------------------------------------------------------------------------*/
32
33 #include <assert.h>
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <string.h>
37
38 /*----------------------------------------------------------------------------
39 * Local headers
40 *----------------------------------------------------------------------------*/
41
42 #include "bft_mem.h"
43 #include "bft_printf.h"
44
45 #include "fvm_defs.h"
46 #include "fvm_io_num.h"
47 #include "fvm_nodal.h"
48 #include "fvm_nodal_priv.h"
49
50 /*----------------------------------------------------------------------------
51 * Header for the current file
52 *----------------------------------------------------------------------------*/
53
54 #include "fvm_nodal_append.h"
55
56 /*----------------------------------------------------------------------------*/
57
58 BEGIN_C_DECLS
59
60 /*! \cond DOXYGEN_SHOULD_SKIP_THIS */
61
62 /*============================================================================
63 * Static global variables
64 *============================================================================*/
65
66 /*============================================================================
67 * Private function definitions
68 *============================================================================*/
69
70 /*----------------------------------------------------------------------------
71 * Create new section, transferring ownership of the given connectivity
72 * and optional parent number arrays to that section.
73 *
74 * parameters:
75 * n_elements <-- number of elements in section
76 * type <-- type of elements to add
77 * face_index <-- polyhedron -> faces index (O to n-1)
78 * size: n_elements + 1
79 * face_num <-- polyhedron -> face numbers (1 to n, signed,
80 * > 0 for outwards pointing face normal
81 * < 0 for inwards pointing face normal);
82 * size: face_index[n_elements]
83 * vertex_index <-- polygon face -> vertices index (O to n-1)
84 * size: face_index[n_elements]
85 * vertex_num <-- element -> vertex connectivity
86 * parent_element_num <-- element -> parent element number (1 to n) if non
87 * trivial (i.e. if element definitions correspond
88 * to a subset of the parent mesh), NULL otherwise
89 *----------------------------------------------------------------------------*/
90
91 static fvm_nodal_section_t *
_transfer_to_section(cs_lnum_t n_elements,fvm_element_t type,cs_lnum_t face_index[],cs_lnum_t face_num[],cs_lnum_t vertex_index[],cs_lnum_t vertex_num[],cs_lnum_t parent_element_num[])92 _transfer_to_section(cs_lnum_t n_elements,
93 fvm_element_t type,
94 cs_lnum_t face_index[],
95 cs_lnum_t face_num[],
96 cs_lnum_t vertex_index[],
97 cs_lnum_t vertex_num[],
98 cs_lnum_t parent_element_num[])
99 {
100 fvm_nodal_section_t *this_section = NULL;
101
102 this_section = fvm_nodal_section_create(type);
103
104 this_section->n_elements = n_elements;
105
106 /* Connectivity */
107
108 if (type == FVM_CELL_POLY) {
109 this_section->_face_index = face_index;
110 this_section->_face_num = face_num;
111 }
112
113 if (type == FVM_FACE_POLY || type == FVM_CELL_POLY)
114 this_section->_vertex_index = vertex_index;
115
116 this_section->_vertex_num = vertex_num;
117
118 this_section->_parent_element_num = parent_element_num;
119
120 /* Shared arrays */
121
122 this_section->face_index = this_section->_face_index;
123 this_section->face_num = this_section->_face_num;
124 this_section->vertex_index = this_section->_vertex_index;
125 this_section->vertex_num = this_section->_vertex_num;
126 this_section->parent_element_num = this_section->_parent_element_num;
127
128 /* Connectivity size */
129
130 if (this_section->stride != 0)
131 this_section->connectivity_size
132 = this_section->n_elements * this_section->stride;
133
134 else if (this_section->type == FVM_FACE_POLY)
135 this_section->connectivity_size
136 = this_section->vertex_index[this_section->n_elements];
137
138 else if (this_section->type == FVM_CELL_POLY) {
139 cs_lnum_t i, _face_num;
140 for (i = 0;
141 i < this_section->face_index[this_section->n_elements];
142 i++) {
143 _face_num = CS_ABS(this_section->face_num[i]);
144 if (_face_num > this_section->n_faces)
145 this_section->n_faces = _face_num;
146 }
147 this_section->connectivity_size
148 = this_section->vertex_index[this_section->n_faces];
149 }
150
151 return this_section;
152 }
153
154 /*----------------------------------------------------------------------------
155 * Create new section, mapping the given connectivity and optional
156 * parent number arrays to that section.
157 *
158 * parameters:
159 * n_elements <-- number of elements in section
160 * type <-- type of elements to add
161 * face_index <-- polyhedron -> faces index (O to n-1)
162 * size: n_elements + 1
163 * face_num <-- polyhedron -> face numbers (1 to n, signed,
164 * > 0 for outwards pointing face normal
165 * < 0 for inwards pointing face normal);
166 * size: face_index[n_elements]
167 * vertex_index <-- polygon face -> vertices index (O to n-1)
168 * size: face_index[n_elements]
169 * vertex_num <-- element -> vertex connectivity
170 * parent_element_num <-- element -> parent element number (1 to n) if non
171 * trivial (i.e. if element definitions correspond
172 * to a subset of the parent mesh), NULL otherwise
173 *----------------------------------------------------------------------------*/
174
175 static fvm_nodal_section_t *
_map_to_section(cs_lnum_t n_elements,fvm_element_t type,cs_lnum_t face_index[],cs_lnum_t face_num[],cs_lnum_t vertex_index[],cs_lnum_t vertex_num[],cs_lnum_t parent_element_num[])176 _map_to_section(cs_lnum_t n_elements,
177 fvm_element_t type,
178 cs_lnum_t face_index[],
179 cs_lnum_t face_num[],
180 cs_lnum_t vertex_index[],
181 cs_lnum_t vertex_num[],
182 cs_lnum_t parent_element_num[])
183 {
184 fvm_nodal_section_t *this_section = NULL;
185
186 this_section = fvm_nodal_section_create(type);
187
188 this_section->n_elements = n_elements;
189
190 /* Connectivity */
191
192 if (type == FVM_CELL_POLY) {
193 this_section->face_index = face_index;
194 this_section->face_num = face_num;
195 }
196
197 if (type == FVM_FACE_POLY || type == FVM_CELL_POLY)
198 this_section->vertex_index = vertex_index;
199
200 this_section->vertex_num = vertex_num;
201
202 this_section->parent_element_num = parent_element_num;
203
204 /* Connectivity size */
205
206 if (this_section->stride != 0)
207 this_section->connectivity_size
208 = this_section->n_elements * this_section->stride;
209
210 else if (this_section->type == FVM_FACE_POLY)
211 this_section->connectivity_size
212 = this_section->vertex_index[this_section->n_elements];
213
214 else if (this_section->type == FVM_CELL_POLY) {
215 cs_lnum_t i, _face_num;
216 for (i = 0;
217 i < this_section->face_index[this_section->n_elements];
218 i++) {
219 _face_num = CS_ABS(this_section->face_num[i]);
220 if (_face_num > this_section->n_faces)
221 this_section->n_faces = _face_num;
222 }
223 this_section->connectivity_size
224 = this_section->vertex_index[this_section->n_faces];
225 }
226
227 return this_section;
228 }
229
230 /*! (DOXYGEN_SHOULD_SKIP_THIS) \endcond */
231
232 /*============================================================================
233 * Public function definitions
234 *============================================================================*/
235
236 /*----------------------------------------------------------------------------
237 * Append a new section to an existing fvm_nodal mesh, and transfer
238 * ownership of the given connectivity and optional parent number arrays to
239 * that section.
240 *
241 * parameters:
242 * this_nodal <-> nodal mesh structure
243 * n_elements <-- number of elements to add
244 * type <-- type of elements to add
245 * face_index <-- polyhedron -> faces index (O to n-1)
246 * size: n_elements + 1
247 * face_num <-- polyhedron -> face numbers (1 to n, signed,
248 * > 0 for outwards pointing face normal
249 * < 0 for inwards pointing face normal);
250 * size: face_index[n_elements]
251 * vertex_index <-- polygon face -> vertices index (O to n-1)
252 * size: face_index[n_elements]
253 * vertex_num <-- element -> vertex connectivity
254 * parent_element_num <-- element -> parent element number (1 to n) if non
255 * trivial (i.e. if element definitions correspond
256 * to a subset of the parent mesh), NULL otherwise
257 *----------------------------------------------------------------------------*/
258
259 void
fvm_nodal_append_by_transfer(fvm_nodal_t * this_nodal,cs_lnum_t n_elements,fvm_element_t type,cs_lnum_t face_index[],cs_lnum_t face_num[],cs_lnum_t vertex_index[],cs_lnum_t vertex_num[],cs_lnum_t parent_element_num[])260 fvm_nodal_append_by_transfer(fvm_nodal_t *this_nodal,
261 cs_lnum_t n_elements,
262 fvm_element_t type,
263 cs_lnum_t face_index[],
264 cs_lnum_t face_num[],
265 cs_lnum_t vertex_index[],
266 cs_lnum_t vertex_num[],
267 cs_lnum_t parent_element_num[])
268 {
269 fvm_nodal_section_t *new_section = NULL;
270 int n_sections = 0;
271
272 assert(this_nodal != NULL);
273
274 n_sections = this_nodal->n_sections;
275
276 /* Create new section */
277
278 BFT_REALLOC(this_nodal->sections, n_sections + 1, fvm_nodal_section_t *);
279
280 new_section = _transfer_to_section(n_elements,
281 type,
282 face_index,
283 face_num,
284 vertex_index,
285 vertex_num,
286 parent_element_num);
287
288 this_nodal->sections[n_sections] = new_section;
289 this_nodal->n_sections += 1;
290
291 /* Update main structure information */
292
293 switch(new_section->entity_dim) {
294 case 3:
295 this_nodal->n_cells += n_elements;
296 break;
297 case 2:
298 this_nodal->n_faces += n_elements;
299 break;
300 case 1:
301 this_nodal->n_edges += n_elements;
302 break;
303 default:
304 assert(0);
305 }
306
307 }
308
309 /*----------------------------------------------------------------------------
310 * Append a new section to an existing fvm_nodal mesh, sharing the given
311 * given connectivity and optional parent number arrays with the caller.
312 *
313 * The caller should not destroy or modify the arrays passed to this
314 * function until the nodal mesh is destroyed.
315 *
316 * parameters:
317 * this_nodal <-> nodal mesh structure
318 * n_elements <-- number of elements to add
319 * type <-- type of elements to add
320 * face_index <-- polyhedron -> faces index (O to n-1)
321 * size: n_elements + 1
322 * face_num <-- polyhedron -> face numbers (1 to n, signed,
323 * > 0 for outwards pointing face normal
324 * < 0 for inwards pointing face normal);
325 * size: face_index[n_elements]
326 * vertex_index <-- polygon face -> vertices index (O to n-1)
327 * size: face_index[n_elements]
328 * vertex_num <-- element -> vertex connectivity
329 * parent_element_num <-- element -> parent element number (1 to n) if non
330 * trivial (i.e. if element definitions correspond
331 * to a subset of the parent mesh), NULL otherwise
332 *----------------------------------------------------------------------------*/
333
334 void
fvm_nodal_append_shared(fvm_nodal_t * this_nodal,cs_lnum_t n_elements,fvm_element_t type,cs_lnum_t face_index[],cs_lnum_t face_num[],cs_lnum_t vertex_index[],cs_lnum_t vertex_num[],cs_lnum_t parent_element_num[])335 fvm_nodal_append_shared(fvm_nodal_t *this_nodal,
336 cs_lnum_t n_elements,
337 fvm_element_t type,
338 cs_lnum_t face_index[],
339 cs_lnum_t face_num[],
340 cs_lnum_t vertex_index[],
341 cs_lnum_t vertex_num[],
342 cs_lnum_t parent_element_num[])
343 {
344 fvm_nodal_section_t *new_section = NULL;
345 int n_sections = 0;
346
347 assert(this_nodal != NULL);
348
349 n_sections = this_nodal->n_sections;
350
351 /* Create new section */
352
353 BFT_REALLOC(this_nodal->sections, n_sections + 1, fvm_nodal_section_t *);
354
355 new_section = _map_to_section(n_elements,
356 type,
357 face_index,
358 face_num,
359 vertex_index,
360 vertex_num,
361 parent_element_num);
362
363 this_nodal->sections[n_sections] = new_section;
364 this_nodal->n_sections += 1;
365
366 /* Update main structure information */
367
368 switch(new_section->entity_dim) {
369 case 3:
370 this_nodal->n_cells += n_elements;
371 break;
372 case 2:
373 this_nodal->n_faces += n_elements;
374 break;
375 case 1:
376 this_nodal->n_edges += n_elements;
377 break;
378 default:
379 assert(0);
380 }
381
382 }
383
384 /*----------------------------------------------------------------------------*/
385
386 END_C_DECLS
387