TrioCFD 1.9.9_beta
TrioCFD documentation
Loading...
Searching...
No Matches
Connectivite_som_elem.cpp
1/****************************************************************************
2* Copyright (c) 2026, CEA
3* All rights reserved.
4*
5* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
9*
10* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
11* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
12* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
13*
14*****************************************************************************/
15#include <Connectivite_som_elem.h>
16#include <Static_Int_Lists.h>
17#include <TRUSTTabs.h>
18
19namespace
20{
21template <typename _SIZE_>
22void copy_list_internal(const Static_Int_Lists_32_64<_SIZE_>& som_elem, const _SIZE_ sommet,
23 SmallArrOfTID_T<_SIZE_>& elements)
24{ throw; }
25
26template <>
27void copy_list_internal(const Static_Int_Lists_32_64<int>& som_elem, const int sommet,
28 SmallArrOfTID_T<int>& elements)
29{
30 som_elem.copy_list_to_array(sommet, elements);
31}
32#if INT_is_64_ == 2
33template <>
34void copy_list_internal(const Static_Int_Lists_32_64<trustIdType>& som_elem, const trustIdType sommet,
35 SmallArrOfTID_T<trustIdType>& elements)
36{
37 BigArrOfTID elem_as_big;
38 elements.ref_as_big(elem_as_big);
39 som_elem.copy_list_to_array(sommet, elem_as_big);
40}
41#endif
42}
43
44/*! @brief Builds the som_elem structure for the given domain. Creates for each vertex i the list of elements adjacent to this vertex
45 *
46 * (i.e. the list of elements k such that there exists j with les_elems(k,j) == i)
47 *
48 * @param (nb_sommets)
49 * @param (les_elems)
50 * @param (som_elem)
51 * @param (include_virtual)
52 */
53template <typename _SIZE_>
54void construire_connectivite_som_elem(const _SIZE_ nb_sommets,
55 const IntTab_T<_SIZE_>& les_elems,
57 bool include_virtual)
58{
59 // Number of elements in the domain
60 const _SIZE_ nb_elem = (include_virtual) ? les_elems.dimension_tot(0) : les_elems.dimension(0);
61 // Number of vertices per element
62 const _SIZE_ nb_sommets_par_element = les_elems.dimension(1);
63
64 // Build an array initialized to zero: for each vertex,
65 // the number of neighboring elements of this vertex
66 ArrOfInt_T<_SIZE_> nb_elements_voisins(nb_sommets);
67
68 // First pass: compute the number of neighboring elements of each
69 // vertex in order to create the data structure
70 ToDo_Kokkos("critical");
71 for (_SIZE_ elem = 0; elem < nb_elem; elem++)
72 {
73 for (int i = 0; i < nb_sommets_par_element; i++)
74 {
75 _SIZE_ sommet = les_elems(elem, i);
76 // GF case of polyhedra
77 if (sommet==-1) break;
78 nb_elements_voisins[sommet]++;
79 }
80 }
81 som_elem.set_list_sizes(nb_elements_voisins);
82
83 // Reuse the array to store the number of elements in
84 // each list while filling it
85 nb_elements_voisins = 0;
86
87 // Fill the array of neighboring elements.
88 ToDo_Kokkos("critical");
89 for (_SIZE_ elem = 0; elem < nb_elem; elem++)
90 {
91 for (int i = 0; i < nb_sommets_par_element; i++)
92 {
93 _SIZE_ sommet = les_elems(elem, i);
94 // GF case of polyhedra
95 if (sommet==-1) break;
96 _SIZE_ n = (nb_elements_voisins[sommet])++;
97 som_elem.set_value(sommet, n, elem);
98 }
99 }
100
101 // Sort all lists in ascending order
102 som_elem.trier_liste(-1);
103}
104
105/*! @brief Finds the elements that contain all the vertices of the sommets_to_find array (allows finding elements
106 *
107 * adjacent to a face or an edge)
108 *
109 * @param (som_elem) for each vertex, sorted list of adjacent elements (see construire_connectivite_som_elem)
110 * @param (sommets_to_find) a list of vertices
111 * @param (elements) result of the search: the list of elements containing all vertices of sommets_to_find. If sommets_to_find is empty, an empty array is returned. (for repeated calls to this function, it is advised to set the "smart_resize" flag)
112 */
113template <typename _SIZE_>
114void find_adjacent_elements(const Static_Int_Lists_32_64<_SIZE_>& som_elem,
115 const SmallArrOfTID_T<_SIZE_>& sommets_to_find,
116 SmallArrOfTID_T<_SIZE_>& elements)
117{
118 int nb_som_to_find = sommets_to_find.size_array();
119 // remove vertices equal to -1 (case of multiple face types)
120 while (sommets_to_find[nb_som_to_find-1]==-1) nb_som_to_find--;
121 if (nb_som_to_find == 0)
122 {
123 elements.resize_array(0);
124 return;
125 }
126 // Algorithm: initialise elements with all elements adjacent
127 // to the first vertex of the list.
128 // Then for each of the other vertices in the list, remove from the array
129 // "elements" those elements that are not neighbors of the vertex.
130 // At the end, only elements that are in all lists remain.
131 {
132 // Initialization with the elements adjacent to the first vertex
133 const _SIZE_ sommet = sommets_to_find[0];
134 // OK this is a bit technical here: 'elements' is a small array, even in 64b.
135 // But copy_list_to_array() might return a Big array (in 64b). So we cheat, we pass it a big array
136 // which is actually pointing to the same internal memory block as the small one.
137 // Just need to start with the correct size because copy_list_to_array will resize otherwise:
138 int sz = (int)som_elem.get_list_size(sommet);
139 elements.resize_array(sz);
140 ::copy_list_internal<_SIZE_>(som_elem, sommet, elements);
141 }
142 int nb_elem_found = elements.size_array();
143 int i_sommet;
144 for (i_sommet = 1; i_sommet < nb_som_to_find; i_sommet++)
145 {
146 const _SIZE_ sommet = sommets_to_find[i_sommet];
147 // Compute the common elements between elements[.] and som_elem(sommet,.)
148 // Number of common elements between elements and the new vertex list
149 int nb_elems_restants = 0;
150 // Number of elements adjacent to "sommet"
151 const int nb_elem_liste = (int)som_elem.get_list_size(sommet);
152 // Assume the element lists are sorted in ascending order
153 // Traverse both lists simultaneously and keep the common elements
154 int i=0, j=0;
155 if (nb_elem_found == 0)
156 break;
157 if (nb_elem_liste > 0)
158 {
159 while (1)
160 {
161 const _SIZE_ elem_i = elements[i];
162 const _SIZE_ elem_j = som_elem(sommet, j);
163 if (elem_i == elem_j)
164 {
165 // Element common to both lists, keep it
166 elements[nb_elems_restants] = elem_i;
167 nb_elems_restants++;
168 }
169 if (elem_i >= elem_j)
170 {
171 j++;
172 if (j >= nb_elem_liste)
173 break;
174 }
175 if (elem_j >= elem_i)
176 {
177 i++;
178 if (i >= nb_elem_found)
179 break;
180 }
181 }
182 }
183 else
184 {
185 nb_elems_restants = 0;
186 }
187 nb_elem_found = nb_elems_restants;
188 }
189 elements.resize_array(nb_elem_found);
190}
191
192template void construire_connectivite_som_elem(const int nb_sommets, const IntTab_T<int>& les_elems, Static_Int_Lists_32_64<int>& som_elem, bool include_virtual);
193template void find_adjacent_elements(const Static_Int_Lists_32_64<int>& som_elem, const SmallArrOfTID_T<int>& sommets_to_find, SmallArrOfTID_T<int>& elements);
194
195#if INT_is_64_ == 2
196template void construire_connectivite_som_elem(const trustIdType nb_sommets, const IntTab_T<trustIdType>& les_elems, Static_Int_Lists_32_64<trustIdType>& som_elem, bool include_virtual);
197template void find_adjacent_elements(const Static_Int_Lists_32_64<trustIdType>& som_elem, const SmallArrOfTID_T<trustIdType>& sommets_to_find, SmallArrOfTID_T<trustIdType>& elements);
198#endif
This class allows storing lists of integers accessible in constant time.
void copy_list_to_array(int_t i_liste, ArrOfInt_t &array) const
Copies the i-th list into the provided array. The array must be resizable.
void set_value(int_t i_liste, int_t i_element, int_t valeur)
Assigns "valeur" to the j-th element of the i-th list with 0 <= i < get_nb_lists() and 0 <= j < get_l...
int_t get_list_size(int_t i_liste) const
Returns the number of elements in list i.
void trier_liste(int_t i)
Sorts the values of the i-th list in ascending order.
void set_list_sizes(const ArrOfInt_t &sizes)
Destroys existing lists and creates new ones.
_SIZE_ size_array() const
void ref_as_big(TRUSTArray< _TYPE_, trustIdType > &out) const
void resize_array(_SIZE_ new_size, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
_SIZE_ dimension_tot(int) const override
Definition TRUSTTab.tpp:160
_SIZE_ dimension(int d) const
Definition TRUSTTab.tpp:133