Arcane  v3.16.4.0
Documentation utilisateur
Chargement...
Recherche...
Aucune correspondance
Connectivity.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2025 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
4// See the top-level COPYRIGHT file for details.
5// SPDX-License-Identifier: Apache-2.0
6//-----------------------------------------------------------------------------
7/*---------------------------------------------------------------------------*/
8/* DynamicMesh.cc (C) 2000-2025 */
9/* */
10/* Classe de description de la connectivité du maillage. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/core/Connectivity.h"
15#include "arcane/core/IMesh.h"
16
17/*---------------------------------------------------------------------------*/
18/*---------------------------------------------------------------------------*/
19
20namespace Arcane
21{
22
23/*---------------------------------------------------------------------------*/
24/*---------------------------------------------------------------------------*/
25
28: m_connectivity(connectivity)
29{
30 ;
31}
32
33/*---------------------------------------------------------------------------*/
34/*---------------------------------------------------------------------------*/
35
36void Connectivity::
37enableConnectivity(const Integer c)
38{
39 _checkValid(c);
40 _enableConnectivity(c);
41}
42
43/*---------------------------------------------------------------------------*/
44
45void Connectivity::
46disableConnectivity(const Integer c)
47{
48 _checkValid(c);
49 _disableConnectivity(c);
50}
51
52/*---------------------------------------------------------------------------*/
53
54bool Connectivity::
55hasConnectivity(const Integer c) const
56{
57 _checkValid(c);
58 return _hasConnectivity(m_connectivity(), c);
59}
60
61/*---------------------------------------------------------------------------*/
62
63bool Connectivity::
64isFrozen() const
65{
66 return _hasConnectivity(m_connectivity(), CT_Frozen);
67}
68
69/*---------------------------------------------------------------------------*/
70
71void Connectivity::
72freeze(IMesh* mesh)
73{
74 const Integer dim = mesh->dimension();
75
76 switch (dim) {
77 case 1:
78 _enableConnectivity(CT_Default1D);
79 _disableConnectivity(CT_EdgeConnectivity);
80 _enableConnectivity(CT_Dim1D);
81 break;
82 case 2:
83 _enableConnectivity(CT_Default2D);
84 _disableConnectivity(CT_EdgeConnectivity);
85 _enableConnectivity(CT_Dim2D);
86 break;
87 case 3:
88 _enableConnectivity(CT_Default3D);
89 _enableConnectivity(CT_Dim3D);
90 break;
91 default:
92 ARCANE_FATAL("Mesh ({0}) dimension must be set before frezing connectivity (current={1})", mesh->name(), dim);
93 }
94
95 if (_hasConnectivity(m_connectivity(), CT_Dim2D) && hasConnectivity(m_connectivity(), CT_Dim3D))
96 ARCANE_FATAL("A mesh cannot have both dimensions 2 and 3");
97
98 // Connectivité minimale
99 // c'est la relation avec une cellule qui définit le non-rejet d'un item
100 if (hasConnectivity(CT_HasNode))
101 _enableConnectivity(CT_CellToNode);
102 if (hasConnectivity(CT_HasEdge))
103 _enableConnectivity(CT_CellToEdge + CT_NodeToEdge + CT_EdgeToNode + CT_EdgeToCell); // il faudrait faire avec moins
104 if (hasConnectivity(CT_HasFace))
105 _enableConnectivity(CT_CellToFace);
106
107 _enableConnectivity(CT_Frozen);
108}
109
110/*---------------------------------------------------------------------------*/
111
112Integer Connectivity::
113getPrealloc(const Integer connectivity, eItemKind kindA, eItemKind kindB)
114{
115 const Integer x = -1; // illegal value
116
117 Integer dim = 0;
118 if (hasConnectivity(connectivity, CT_Dim1D))
119 dim = 1;
120 if (hasConnectivity(connectivity, CT_Dim2D)) {
121 if (dim != 0) {
122 throw FatalErrorException(A_FUNCINFO, "A mesh cannot have both dimensions 1 and 2");
123 }
124 else {
125 dim = 2;
126 }
127 }
128 if (hasConnectivity(connectivity, CT_Dim3D)) {
129 if (dim != 0) {
130 throw FatalErrorException(A_FUNCINFO, "A mesh cannot have both dimensions (1 or 2) and 3");
131 }
132 else {
133 dim = 3;
134 }
135 }
136
137 if (kindA > NB_ITEM_KIND || kindB > NB_ITEM_KIND)
138 throw FatalErrorException(A_FUNCINFO, String::format("Invalid connectivity kind ({0}To{1})", kindA, kindB));
139
140 Integer prealloc = 0;
141 switch (dim) {
142 case 1: {
143 // utilise l'ordre de l'enum eItemKind (contient tous les kind jusqu'à Particle)
144 // (kindA=ligne,kindB=colonne) => nb d'item de type 'itemB' pour un kind de type 'kindA'
145 Integer preallocs[8][8] = { { x, x, 2, 2, x, x, x, x },
146 { x, x, x, x, x, x, x, x },
147 { 2, x, x, 2, x, x, x, x },
148 { 2, x, 2, x, x, x, x, x },
149 { x, x, x, x, x, x, x, x },
150 { x, x, x, x, x, x, x, x },
151 { x, x, x, x, x, x, x, x },
152 { x, x, x, x, x, x, x, x } };
153 prealloc = preallocs[kindA][kindB];
154 } break;
155 case 2: {
156 // utilise l'ordre de l'enum eItemKind (contient tous les kind jusqu'à Particle)
157 // (kindA=ligne,kindB=colonne) => nb d'item de type 'itemB' pour un kind de type 'kindA'
158 Integer preallocs[8][8] = { { x, x, 4, 4, x, x, x, x },
159 { x, x, x, x, x, x, x, x },
160 { 4, x, x, 2, x, x, x, x },
161 { 4, x, 4, x, x, x, x, x },
162 { x, x, x, x, x, x, x, x },
163 { x, x, x, x, x, x, x, x },
164 { x, x, x, x, x, x, x, x },
165 { x, x, x, x, x, x, x, x } };
166 prealloc = preallocs[kindA][kindB];
167 } break;
168 case 3: {
169 // utilise l'ordre de l'enum eItemKind (contient tous les kind jusqu'à Particle)
170 // (kindA=ligne,kindB=colonne) => nb d'item de type 'itemB' pour un kind de type 'kindA'
171 Integer preallocs[8][8] = { { x, 6, 12, 8, x, x, x, x },
172 { 2, x, 4, 4, x, x, x, x },
173 { 4, 4, x, 2, x, x, x, x },
174 { 8, 12, 6, x, x, x, x, x },
175 { x, x, x, x, x, x, x, x },
176 { x, x, x, x, x, x, x, x },
177 { x, x, x, x, x, x, x, x },
178 { x, x, x, x, x, x, x, x } };
179 prealloc = preallocs[kindA][kindB];
180 } break;
181 default:
182 throw FatalErrorException(A_FUNCINFO, String::format("Not supported mesh dimension (current={0}): must be 1, 2 or 3", dim));
183 }
184
185 if (prealloc == x)
186 throw FatalErrorException(A_FUNCINFO, String::format("Cannot request prealloc of {1} for {0} family", kindA, kindB));
187
188 Integer kindAkindBConnectivity = kindsToConnectivity(kindA, kindB);
189 if (hasConnectivity(connectivity, kindAkindBConnectivity)) {
190 return prealloc;
191 }
192 else {
193 return 0;
194 }
195}
196
197/*---------------------------------------------------------------------------*/
198
200print(std::ostream& o, const Integer connectivity)
201{
202 Integer position = 0;
203 // if (hasConnectivity(connectivity,CT_NodeToNode))
204 // o << ((position++)?"|":"") << "NodeToNode";
205 if (hasConnectivity(connectivity, CT_NodeToEdge))
206 o << ((position++) ? "|" : "") << "NodeToEdge";
207 if (hasConnectivity(connectivity, CT_NodeToFace))
208 o << ((position++) ? "|" : "") << "NodeToFace";
209 if (hasConnectivity(connectivity, CT_NodeToCell))
210 o << ((position++) ? "|" : "") << "NodeToCell";
211 if (hasConnectivity(connectivity, CT_EdgeToNode))
212 o << ((position++) ? "|" : "") << "EdgeToNode";
213 // if (hasConnectivity(connectivity,CT_EdgeToEdge))
214 // o << ((position++)?"|":"") << "EdgeToEdge";
215 if (hasConnectivity(connectivity, CT_EdgeToFace))
216 o << ((position++) ? "|" : "") << "EdgeToFace";
217 if (hasConnectivity(connectivity, CT_EdgeToCell))
218 o << ((position++) ? "|" : "") << "EdgeToCell";
219 if (hasConnectivity(connectivity, CT_FaceToNode))
220 o << ((position++) ? "|" : "") << "FaceToNode";
221 if (hasConnectivity(connectivity, CT_FaceToEdge))
222 o << ((position++) ? "|" : "") << "FaceToEdge";
223 if (hasConnectivity(connectivity, CT_FaceToFace))
224 o << ((position++) ? "|" : "") << "FaceToFace";
225 if (hasConnectivity(connectivity, CT_FaceToCell))
226 o << ((position++) ? "|" : "") << "FaceToCell";
227 if (hasConnectivity(connectivity, CT_CellToNode))
228 o << ((position++) ? "|" : "") << "CellToNode";
229 if (hasConnectivity(connectivity, CT_CellToEdge))
230 o << ((position++) ? "|" : "") << "CellToEdge";
231 if (hasConnectivity(connectivity, CT_CellToFace))
232 o << ((position++) ? "|" : "") << "CellToFace";
233 // if (hasConnectivity(connectivity,CT_CellToCell))
234 // o << ((position++)?"|":"") << "CellToCell";
235 if (hasConnectivity(connectivity, CT_HasNode))
236 o << ((position++) ? "|" : "") << "HasNode";
237 if (hasConnectivity(connectivity, CT_HasEdge))
238 o << ((position++) ? "|" : "") << "HasEdge";
239 if (hasConnectivity(connectivity, CT_HasFace))
240 o << ((position++) ? "|" : "") << "HasFace";
241 if (hasConnectivity(connectivity, CT_HasCell))
242 o << ((position++) ? "|" : "") << "HasCell";
243 if (hasConnectivity(connectivity, CT_Frozen))
244 o << ((position++) ? "|" : "") << "Frozen";
245 // if (hasConnectivity(connectivity,CT_Dim1D))
246 // o << ((position++)?"|":"") << "Dim1D";
247 if (hasConnectivity(connectivity, CT_Dim2D))
248 o << ((position++) ? "|" : "") << "Dim2D";
249 if (hasConnectivity(connectivity, CT_Dim3D))
250 o << ((position++) ? "|" : "") << "Dim3D";
251
252 if (position == 0)
253 o << "Null";
254}
255
256/*---------------------------------------------------------------------------*/
257
258void Connectivity::Printer::print(std::ostream& o) const
259{
260 Connectivity::print(o, m_connectivity);
261}
262
263/*---------------------------------------------------------------------------*/
264
265std::ostream& operator<<(std::ostream& o, const Connectivity::Printer& p)
266{
267 p.print(o);
268 return o;
269}
270
271/*---------------------------------------------------------------------------*/
272/*---------------------------------------------------------------------------*/
273
274void Connectivity::
275_enableConnectivity(const Integer c)
276{
277 _checkFrozen();
278 m_connectivity = m_connectivity() | c;
279}
280
281/*---------------------------------------------------------------------------*/
282
283void Connectivity::
284_disableConnectivity(const Integer c)
285{
286 _checkFrozen();
287 m_connectivity = m_connectivity() & ~c;
288}
289
290/*---------------------------------------------------------------------------*/
291
292void Connectivity::
293_checkValid(const Integer c)
294{
295 if ((c & ~CT_FullConnectivity3D) && (c & ~CT_GraphConnectivity))
296 ARCANE_FATAL("Illegal connectivity flag");
297}
298
299/*---------------------------------------------------------------------------*/
300
301void Connectivity::
302_checkFrozen() const
303{
304 if (m_connectivity() & CT_Frozen)
305 ARCANE_FATAL("Cannot modify frozen connectivity");
306}
307
308/*---------------------------------------------------------------------------*/
309
312{
313 switch (kindA) {
314 case IK_Node:
315 case IK_Edge:
316 case IK_Face:
317 case IK_Cell:
318 case IK_DoF:
319 case IK_Particle:
320 break;
321 default:
322 throw FatalErrorException(A_FUNCINFO, String::format("Connectivity from kind {0} not supported", kindA));
323 }
324 switch (kindB) {
325 case IK_Node:
326 case IK_Edge:
327 case IK_Face:
328 case IK_Cell:
329 case IK_DoF:
330 case IK_Particle:
331 break;
332 default:
333 ARCANE_FATAL("Connectivity to kind {0} not supported", kindB);
334 }
335 if (kindA == IK_DoF) {
336 switch (kindB) {
337 case IK_Node:
338 return CT_DoFToNode;
339 case IK_Edge:
340 return CT_DoFToEdge;
341 case IK_Face:
342 return CT_DoFToFace;
343 case IK_Cell:
344 return CT_DoFToCell;
345 case IK_DoF:
346 return CT_DoFToDoF;
347 case IK_Particle:
348 return CT_DoFToParticle;
349 default:
350 ARCANE_FATAL("Connectivity to kind {0} not supported", kindB);
351 }
352 }
353 else
354 return 1 << (4 * kindA + kindB + 1);
355 ARCANE_FATAL("Connectivity {0} to kind {1} is not supported", kindA, kindB);
356}
357
358/*---------------------------------------------------------------------------*/
359/*---------------------------------------------------------------------------*/
360
361} // End namespace Arcane
362
363/*---------------------------------------------------------------------------*/
364/*---------------------------------------------------------------------------*/
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
static Integer kindsToConnectivity(eItemKind kindA, eItemKind kindB)
Conversion de type en connectivité
static void print(std::ostream &o, Integer connectivity)
Fonction d'écriture sur un flux.
Connectivity(VariableScalarInteger connectivity)
Exception lorsqu'une erreur fatale est survenue.
VariableRefScalarT< Integer > VariableScalarInteger
Variable scalaire de type entier.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
Int32 Integer
Type représentant un entier.
eItemKind
Genre d'entité de maillage.
@ IK_Particle
Entité de maillage de genre particule.
@ IK_Node
Entité de maillage de genre noeud.
@ IK_Cell
Entité de maillage de genre maille.
@ IK_Face
Entité de maillage de genre face.
@ IK_DoF
Entité de maillage de genre degre de liberte.
@ IK_Edge
Entité de maillage de genre arête.
std::ostream & operator<<(std::ostream &ostr, eItemKind item_kind)
Opérateur de sortie sur un flot.