TRUST 1.9.8
HPC thermohydraulic platform
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 construction de la structure som_elem pour le domaine donnee On cree pour chaque sommet i la liste des elements adjacents a ce sommet
45 *
46 * (c'est la liste des elements k tels que il existe j tel que 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 // Nombre d'elements du domaine
60 const _SIZE_ nb_elem = (include_virtual) ? les_elems.dimension_tot(0) : les_elems.dimension(0);
61 // Nombre de sommets par element
62 const _SIZE_ nb_sommets_par_element = les_elems.dimension(1);
63
64 // Construction d'un tableau initialise a zero : pour chaque sommet,
65 // nombre d'elements voisins de ce sommet
66 ArrOfInt_T<_SIZE_> nb_elements_voisins(nb_sommets);
67
68 // Premier passage : on calcule le nombre d'elements voisins de chaque
69 // sommet pour creer la structure de donnees
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 cas des polyedres
77 if (sommet==-1) break;
78 nb_elements_voisins[sommet]++;
79 }
80 }
81 som_elem.set_list_sizes(nb_elements_voisins);
82
83 // On reutilise le tableau pour stocker le nombre d'elements dans
84 // chaque liste pendant qu'on la remplit
85 nb_elements_voisins = 0;
86
87 // Remplissage du tableau des elements voisins.
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 cas des polyedres
95 if (sommet==-1) break;
96 _SIZE_ n = (nb_elements_voisins[sommet])++;
97 som_elem.set_value(sommet, n, elem);
98 }
99 }
100
101 // Tri de toutes les listes dans l'ordre croissant
102 som_elem.trier_liste(-1);
103}
104
105/*! @brief Cherche les elements qui contiennent tous les sommets du tableau sommets_to_find (permet de trouver les elements
106 *
107 * adjacents a une face ou une arete)
108 *
109 * @param (som_elem) pour chaque sommet, liste triee des elements adjacents (voir construire_connectivite_som_elem)
110 * @param (sommets_to_find) une liste de sommets
111 * @param (elements) resultat de la recherche: la liste des elements qui contiennent tous les sommets de sommets_to_find. Si sommets_to_find est vide, on renvoie un tableau vide. (en cas d'appels repetes a cette fonction, il est conseille de mettre le drapeau "smart_resize")
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 // on retire les sommets valant -1 (cas ou plusieurs types de faces)
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 // Algorithme: on initialise elements avec tous les elements adjacents
127 // au premier sommet de la liste.
128 // Puis pour chacun des autres sommets de la liste, on retire du tableau
129 // "elements" les elements qui ne sont pas voisins du sommet.
130 // A la fin, il ne reste que les elements qui sont dans toutes les listes.
131 {
132 // Initialisation avec les elements adjacents au premier sommet
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 // Calcul des elements communs entre elements[.] et som_elem(sommet,.)
148 // Nombre d'elements communs entre elements et la nouvelle liste de sommets
149 int nb_elems_restants = 0;
150 // Nombre d'elements adjacents au "sommet"
151 const int nb_elem_liste = (int)som_elem.get_list_size(sommet);
152 // On suppose que les listes d'elements sont triees dans l'ordre croissant
153 // On parcourt simultanement les deux listes et on conserve les elements
154 // communs.
155 int i=0, j=0;
156 if (nb_elem_found == 0)
157 break;
158 if (nb_elem_liste > 0)
159 {
160 while (1)
161 {
162 const _SIZE_ elem_i = elements[i];
163 const _SIZE_ elem_j = som_elem(sommet, j);
164 if (elem_i == elem_j)
165 {
166 // Element commun aux deux listes, on le garde
167 elements[nb_elems_restants] = elem_i;
168 nb_elems_restants++;
169 }
170 if (elem_i >= elem_j)
171 {
172 j++;
173 if (j >= nb_elem_liste)
174 break;
175 }
176 if (elem_j >= elem_i)
177 {
178 i++;
179 if (i >= nb_elem_found)
180 break;
181 }
182 }
183 }
184 else
185 {
186 nb_elems_restants = 0;
187 }
188 nb_elem_found = nb_elems_restants;
189 }
190 elements.resize_array(nb_elem_found);
191}
192
193template 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);
194template void find_adjacent_elements(const Static_Int_Lists_32_64<int>& som_elem, const SmallArrOfTID_T<int>& sommets_to_find, SmallArrOfTID_T<int>& elements);
195
196#if INT_is_64_ == 2
197template 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);
198template void find_adjacent_elements(const Static_Int_Lists_32_64<trustIdType>& som_elem, const SmallArrOfTID_T<trustIdType>& sommets_to_find, SmallArrOfTID_T<trustIdType>& elements);
199#endif
Cette classe permet de stocker des listes d'entiers accessibles en temps constant.
void copy_list_to_array(int_t i_liste, ArrOfInt_t &array) const
copie la i-ieme liste dans le tableau fourni Le tableau array doit etre resizable.
void set_value(int_t i_liste, int_t i_element, int_t valeur)
affecte la "valeur" au j-ieme element de la i-ieme liste avec 0 <= i < get_nb_lists() et 0 <= j < get...
int_t get_list_size(int_t i_liste) const
renvoie le nombre d'elements de la liste i
void trier_liste(int_t i)
tri par ordre croissant des valeurs de la i-ieme liste.
void set_list_sizes(const ArrOfInt_t &sizes)
detruit les listes existantes et en cree de nouvelles.
_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