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