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