Arcane  v4.1.11.0
Documentation utilisateur
Chargement...
Recherche...
Aucune correspondance
ItemTypeMng.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2026 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/* ItemTypeMng.cc (C) 2000-2026 */
9/* */
10/* Gestionnaire des types d'entite du maillage. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/core/ItemTypeMng.h"
15
16#include "arcane/utils/ITraceMng.h"
17#include "arcane/utils/TraceAccessor.h"
18#include "arcane/utils/IStackTraceService.h"
19#include "arcane/utils/IOException.h"
20#include "arcane/utils/FatalErrorException.h"
21#include "arcane/utils/MultiBuffer.h"
22#include "arcane/utils/PlatformUtils.h"
23
25#include "arcane/core/ItemTypeId.h"
26#include "arcane/core/ItemTypeInfoBuilder.h"
27#include "arcane/core/IParallelSuperMng.h"
28#include "arcane/core/ItemTypeInfoBuilder.h"
29#include "arcane/core/IMesh.h"
30#include "arcane/core/MeshKind.h"
31#include "arcane/core/ISubDomain.h"
32#include "arcane/core/IApplication.h"
33
34// AMR
35#include "arcane/ItemRefinementPattern.h"
36
37#include <map>
38#include <set>
39
40/*---------------------------------------------------------------------------*/
41/*---------------------------------------------------------------------------*/
42
43namespace Arcane
44{
45namespace
46{
47 // Nombre de noeuds pour les types polygones additionnels.
48 // Les types jusqu'à ITI_Octogon8 existent toujours.
49 Int16 global_polygon_begin_nb_node = 9;
50}
51
52/*---------------------------------------------------------------------------*/
53/*---------------------------------------------------------------------------*/
54
55const Integer ItemTypeMng::m_nb_builtin_item_type = NB_BASIC_ITEM_TYPE;
56
57/*---------------------------------------------------------------------------*/
58/*---------------------------------------------------------------------------*/
59
64
65/*---------------------------------------------------------------------------*/
66/*---------------------------------------------------------------------------*/
67
68ItemTypeMng::
69~ItemTypeMng()
70{
71 delete m_types_buffer;
72}
73
74/*---------------------------------------------------------------------------*/
75/*---------------------------------------------------------------------------*/
76
78build(IMesh* mesh)
79{
80 if (m_initialized)
81 ARCANE_FATAL("ItemTypeMng instance is already initialized");
82 // Récupère le IParallelSuperMng via l'application.
83 // Une fois qu'on aura supprimé l'instance singleton, on pourra
84 // simplement utiliser le IParallelMng.
85 IParallelSuperMng* super_pm = mesh->subDomain()->application()->parallelSuperMng();
86 _buildTypes(mesh, super_pm, mesh->traceMng());
87 m_initialized = true;
88}
89
90/*---------------------------------------------------------------------------*/
91/*---------------------------------------------------------------------------*/
92
94build(IParallelSuperMng* parallel_mng, ITraceMng* trace)
95{
96 _buildSingleton(parallel_mng, trace);
97}
98
99/*---------------------------------------------------------------------------*/
100/*---------------------------------------------------------------------------*/
101
102void ItemTypeMng::
103_buildSingleton(IParallelSuperMng* parallel_mng, ITraceMng* trace)
104{
105 // Avec MPC, cette fonction peut être appelée plusieurs fois
106 // dans des threads différents. Comme tous les threads partagent
107 // le même singleton, seul le premier thread fait réellement l'initialisation.
108 // ATTENTION: Cela est incompatible avec le mode readTypes()
109 // ou on lit les connectivités dans un fichier ARCANE_ITEM_TYPE_FILE.
110 Int32 max_rank = parallel_mng->commSize() + 1;
111 Int32 init_counter = ++m_initialized_counter;
112 if (init_counter == 1) {
113 _buildTypes(nullptr, parallel_mng, trace);
114 m_initialized = true;
115 m_initialized_counter = max_rank;
116 }
117 else
118 // Ceux qui ne font pas l'initialisation doivent attendre que cette dernière
119 // soit faite.
120 while (init_counter < max_rank)
121 init_counter = m_initialized_counter.load();
122}
123
124/*---------------------------------------------------------------------------*/
125/*---------------------------------------------------------------------------*/
126/*!
127 * \brief Construit les types des entités.
128 *
129 * \note Pour l'instance singleton, \a mesh est nul.
130 */
131void ItemTypeMng::
132_buildTypes(IMesh* mesh, IParallelSuperMng* parallel_mng, ITraceMng* trace)
133{
134 // Construit la connectivité des éléments.
135 // Pour les éléments classiques, la connectivité est la même que
136 // celle de VTK, disponible dans le document:
137 //
138 // https://vtk.org/wp-content/uploads/2015/04/file-formats.pdf
139
140 using Dimension = ItemTypeInfoBuilder::Dimension;
141 bool is_non_manifold = false;
142 if (mesh)
143 is_non_manifold = mesh->meshKind().isNonManifold();
144
145 m_trace = trace;
146 m_types.resize(m_nb_builtin_item_type);
147 m_types_buffer = new MultiBufferT<ItemTypeInfoBuilder>();
148
149 // Null
150 {
151 ItemTypeInfoBuilder* type = m_types_buffer->allocOne();
152 m_types[IT_NullType] = type;
153
154 type->setInfos(this, IT_NullType, "NullType", Dimension::DimUnknown, 0, 0, 0);
155 }
156
157 // Vertex
158 {
159 ItemTypeInfoBuilder* type = m_types_buffer->allocOne();
160 m_types[IT_Vertex] = type;
161
162 type->setInfos(this, IT_Vertex, "Vertex", Dimension::Dim0, 0, 0, 0);
163 // TODO regarder si ce type est autorisé pour les mailles.
164 // Si ce n'est pas le cas, il faudrait définir un type
165 // pour les mailles 0D qui sont assimilables à des points.
166 }
167
168 // FaceVertex (face pour les maillages 1D)
169 {
170 ItemTypeInfoBuilder* type = m_types_buffer->allocOne();
171 m_types[IT_FaceVertex] = type;
172
173 type->setInfos(this, IT_FaceVertex, "FaceVertex", Dimension::Dim0, 1, 0, 0);
174 type->setIsValidForCell(false);
175 }
176
177 // Line2
178 {
179 ItemTypeInfoBuilder* type = m_types_buffer->allocOne();
180 m_types[IT_Line2] = type;
181
182 type->setInfos(this, IT_Line2, "Line2", Dimension::Dim1, 2, 0, 0);
183 type->setIsValidForCell(true);
184 }
185
186 // Line3
187 {
188 ItemTypeInfoBuilder* type = m_types_buffer->allocOne();
189 m_types[IT_Line3] = type;
190
191 type->setInfos(this, IT_Line3, "Line3", Dimension::Dim1, 3, 0, 0);
192 type->setOrder(2, ITI_Line2);
193 type->setIsValidForCell(false);
194 }
195
196 // Line4
197 {
198 ItemTypeInfoBuilder* type = m_types_buffer->allocOne();
199 m_types[IT_Line4] = type;
200
201 type->setInfos(this, IT_Line4, "Line4", Dimension::Dim1, 4, 0, 0);
202 type->setOrder(3, ITI_Line2);
203 type->setIsValidForCell(false);
204 }
205
206 // CellLine2 (mailles pour les maillages 1D)
207 {
208 ItemTypeInfoBuilder* type = m_types_buffer->allocOne();
209 m_types[IT_CellLine2] = type;
210
211 type->setInfos(this, IT_CellLine2, "CellLine2", Dimension::Dim1, 2, 0, 2);
212
213 type->addFaceVertex(0, 0);
214 type->addFaceVertex(1, 1);
215 }
216
217 /*
218 * Pour les polygones les faces et les arêtes sont identiques.
219 *
220 * \note lors des declarations des arêtes, on donne pour faces les
221 * arêtes qui sont jointes a l'arête courante
222 */
223
224 // Triangle3
225 {
226 ItemTypeInfoBuilder* type = m_types_buffer->allocOne();
227 m_types[IT_Triangle3] = type;
228
229 type->setInfos(this, IT_Triangle3, "Triangle3", Dimension::Dim2, 3, 3, 3);
230
231 type->addEdgeAndFaceLine(0, { 0, 1 }, { 1, 2 });
232 type->addEdgeAndFaceLine(1, { 1, 2 }, { 2, 0 });
233 type->addEdgeAndFaceLine(2, { 2, 0 }, { 0, 1 });
234 }
235
236 // Triangle6
237 {
238 // TODO: Pour l'instant comme triangle3
239 ItemTypeInfoBuilder* type = m_types_buffer->allocOne();
240 m_types[IT_Triangle6] = type;
241
242 type->setInfos(this, IT_Triangle6, "Triangle6", Dimension::Dim2, 6, 3, 3);
243 type->setOrder(2, ITI_Triangle3);
244
245 type->addFaceLine3(0, 0, 1, 3);
246 type->addFaceLine3(1, 1, 2, 4);
247 type->addFaceLine3(2, 2, 0, 5);
248
249 type->addEdge(0, 0, 1, 1, 2);
250 type->addEdge(1, 1, 2, 2, 0);
251 type->addEdge(2, 2, 0, 0, 1);
252 }
253
254 // Triangle10
255 {
256 // TODO: Pour l'instant comme triangle3
257 ItemTypeInfoBuilder* type = m_types_buffer->allocOne();
258 m_types[IT_Triangle10] = type;
259
260 type->setInfos(this, IT_Triangle10, "Triangle10", Dimension::Dim2, 10, 3, 3);
261 type->setOrder(3, ITI_Triangle3);
262 type->setHasCenterNode(true);
263
264 type->addFaceLine4(0, 0, 1, 3, 4);
265 type->addFaceLine4(1, 1, 2, 5, 6);
266 type->addFaceLine4(2, 2, 0, 7, 8);
267
268 type->addEdge(0, 0, 1, 1, 2);
269 type->addEdge(1, 1, 2, 2, 0);
270 type->addEdge(2, 2, 0, 0, 1);
271 }
272
273 // Quad4
274 {
275 _addPolygonType(IT_Quad4, 4, "Quad4");
276 }
277
278 // Quad8
279 {
280 ItemTypeInfoBuilder* type = m_types_buffer->allocOne();
281 m_types[IT_Quad8] = type;
282
283 type->setInfos(this, IT_Quad8, "Quad8", Dimension::Dim2, 8, 4, 4);
284 type->setOrder(2, ITI_Quad4);
285
286 type->addFaceLine3(0, 0, 1, 4);
287 type->addFaceLine3(1, 1, 2, 5);
288 type->addFaceLine3(2, 2, 3, 6);
289 type->addFaceLine3(3, 3, 0, 7);
290
291 type->addEdge(0, 0, 1, 3, 1);
292 type->addEdge(1, 1, 2, 0, 2);
293 type->addEdge(2, 2, 3, 1, 3);
294 type->addEdge(3, 3, 0, 2, 0);
295 }
296
297 // Quad9
298 {
299 // Comme Quad8 mais avec un noeud en plus au milieu du quadrangle
300 ItemTypeInfoBuilder* type = m_types_buffer->allocOne();
301 m_types[IT_Quad9] = type;
302
303 type->setInfos(this, IT_Quad9, "Quad9", Dimension::Dim2, 9, 4, 4);
304 type->setOrder(2, ITI_Quad4);
305 type->setHasCenterNode(true);
306
307 type->addFaceLine3(0, 0, 1, 4);
308 type->addFaceLine3(1, 1, 2, 5);
309 type->addFaceLine3(2, 2, 3, 6);
310 type->addFaceLine3(3, 3, 0, 7);
311
312 type->addEdge(0, 0, 1, 3, 1);
313 type->addEdge(1, 1, 2, 0, 2);
314 type->addEdge(2, 2, 3, 1, 3);
315 type->addEdge(3, 3, 0, 2, 0);
316 }
317
318 // Pentagon5
319 {
320 _addPolygonType(IT_Pentagon5, 5, "Pentagon5");
321 }
322
323 // Hexagon6
324 {
325 _addPolygonType(IT_Hexagon6, 6, "Hexagon6");
326 }
327
328 // Hexaedron8
329 {
330 ItemTypeInfoBuilder* type = m_types_buffer->allocOne();
331 m_types[IT_Hexaedron8] = type;
332
333 type->setInfos(this, IT_Hexaedron8, "Hexaedron8", Dimension::Dim3, 8, 12, 6);
334
335 type->addFaceQuad(0, 0, 3, 2, 1);
336 type->addFaceQuad(1, 0, 4, 7, 3);
337 type->addFaceQuad(2, 0, 1, 5, 4);
338 type->addFaceQuad(3, 4, 5, 6, 7);
339 type->addFaceQuad(4, 1, 2, 6, 5);
340 type->addFaceQuad(5, 2, 3, 7, 6);
341
342 type->addEdge(0, 0, 1, 2, 0);
343 type->addEdge(1, 1, 2, 4, 0);
344 type->addEdge(2, 2, 3, 5, 0);
345 type->addEdge(3, 3, 0, 1, 0);
346 type->addEdge(4, 0, 4, 1, 2);
347 type->addEdge(5, 1, 5, 2, 4);
348 type->addEdge(6, 2, 6, 4, 5);
349 type->addEdge(7, 3, 7, 5, 1);
350 type->addEdge(8, 4, 5, 3, 2);
351 type->addEdge(9, 5, 6, 3, 4);
352 type->addEdge(10, 6, 7, 3, 5);
353 type->addEdge(11, 7, 4, 3, 1);
354 }
355
356 // Hexaedron20
357 {
358 // Pour l'instant comme Hexaedron8
359 ItemTypeInfoBuilder* type = m_types_buffer->allocOne();
360 m_types[IT_Hexaedron20] = type;
361
362 type->setInfos(this, IT_Hexaedron20, "Hexaedron20", Dimension::Dim3, 20, 12, 6);
363 type->setOrder(2, ITI_Hexaedron8);
364
365 type->addFaceQuad8(0, 0, 4, 7, 3, 16, 15, 19, 11);
366 type->addFaceQuad8(1, 1, 2, 6, 5, 9, 18, 13, 17);
367 type->addFaceQuad8(2, 0, 1, 5, 4, 8, 17, 12, 16);
368 type->addFaceQuad8(3, 0, 3, 2, 1, 11, 10, 9, 8);
369 type->addFaceQuad8(4, 2, 3, 7, 6, 10, 19, 14, 18);
370 type->addFaceQuad8(5, 4, 5, 6, 7, 12, 13, 14, 15);
371
372 type->addEdge(0, 0, 1, 2, 0);
373 type->addEdge(1, 1, 2, 4, 0);
374 type->addEdge(2, 2, 3, 5, 0);
375 type->addEdge(3, 3, 0, 1, 0);
376 type->addEdge(4, 0, 4, 1, 2);
377 type->addEdge(5, 1, 5, 2, 4);
378 type->addEdge(6, 2, 6, 4, 5);
379 type->addEdge(7, 3, 7, 5, 1);
380 type->addEdge(8, 4, 5, 3, 2);
381 type->addEdge(9, 5, 6, 3, 4);
382 type->addEdge(10, 6, 7, 3, 5);
383 type->addEdge(11, 7, 4, 3, 1);
384 }
385
386 // Hexaedron27
387 {
388 // Pour l'instant comme Hexaedron8
389 ItemTypeInfoBuilder* type = m_types_buffer->allocOne();
390 m_types[IT_Hexaedron27] = type;
391
392 type->setInfos(this, IT_Hexaedron27, "Hexaedron27", Dimension::Dim3, 27, 12, 6);
393 type->setOrder(2, ITI_Hexaedron8);
394 type->setHasCenterNode(true);
395
396 type->addFaceQuad9(0, 0, 4, 7, 3, 16, 15, 19, 11, 20);
397 type->addFaceQuad9(1, 1, 2, 6, 5, 9, 18, 13, 17, 21);
398 type->addFaceQuad9(2, 0, 1, 5, 4, 8, 17, 12, 16, 22);
399 type->addFaceQuad9(3, 0, 3, 2, 1, 11, 10, 9, 8, 24);
400 type->addFaceQuad9(4, 2, 3, 7, 6, 10, 19, 14, 18, 23);
401 type->addFaceQuad9(5, 4, 5, 6, 7, 12, 13, 14, 15, 25);
402
403 type->addEdge(0, 0, 1, 2, 0);
404 type->addEdge(1, 1, 2, 4, 0);
405 type->addEdge(2, 2, 3, 5, 0);
406 type->addEdge(3, 3, 0, 1, 0);
407 type->addEdge(4, 0, 4, 1, 2);
408 type->addEdge(5, 1, 5, 2, 4);
409 type->addEdge(6, 2, 6, 4, 5);
410 type->addEdge(7, 3, 7, 5, 1);
411 type->addEdge(8, 4, 5, 3, 2);
412 type->addEdge(9, 5, 6, 3, 4);
413 type->addEdge(10, 6, 7, 3, 5);
414 type->addEdge(11, 7, 4, 3, 1);
415 }
416
417 // Pyramid5
418 {
419 ItemTypeInfoBuilder* type = m_types_buffer->allocOne();
420 m_types[IT_Pyramid5] = type;
421
422 type->setInfos(this, IT_Pyramid5, "Pyramid5", Dimension::Dim3, 5, 8, 5);
423
424 type->addFaceQuad(0, 0, 3, 2, 1);
425 type->addFaceTriangle(1, 0, 4, 3);
426 type->addFaceTriangle(2, 0, 1, 4);
427 type->addFaceTriangle(3, 1, 2, 4);
428 type->addFaceTriangle(4, 2, 3, 4);
429
430 type->addEdge(0, 0, 1, 2, 0);
431 type->addEdge(1, 1, 2, 3, 0);
432 type->addEdge(2, 2, 3, 4, 0);
433 type->addEdge(3, 3, 0, 1, 0);
434 type->addEdge(4, 0, 4, 1, 2);
435 type->addEdge(5, 1, 4, 2, 3);
436 type->addEdge(6, 2, 4, 3, 4);
437 type->addEdge(7, 3, 4, 4, 1);
438 }
439
440 // Pyramid13
441 {
442 ItemTypeInfoBuilder* type = m_types_buffer->allocOne();
443 m_types[IT_Pyramid13] = type;
444 type->setOrder(2, ITI_Pyramid5);
445 type->setInfos(this, IT_Pyramid13, "Pyramid13", Dimension::Dim3, 13, 8, 5);
446
447 type->addFaceQuad8(0, 0, 3, 2, 1, 5, 6, 7, 8);
448 type->addFaceTriangle6(1, 0, 4, 3, 9, 12, 8);
449 type->addFaceTriangle6(2, 0, 1, 4, 5, 10, 9);
450 type->addFaceTriangle6(3, 1, 2, 4, 6, 11, 10);
451 type->addFaceTriangle6(4, 2, 3, 4, 7, 12, 11);
452
453 type->addEdge(0, 0, 1, 2, 0);
454 type->addEdge(1, 1, 2, 3, 0);
455 type->addEdge(2, 2, 3, 4, 0);
456 type->addEdge(3, 3, 0, 1, 0);
457 type->addEdge(4, 0, 4, 1, 2);
458 type->addEdge(5, 1, 4, 2, 3);
459 type->addEdge(6, 2, 4, 3, 4);
460 type->addEdge(7, 3, 4, 4, 1);
461 }
462
463 // Pentaedron6
464 {
465 ItemTypeInfoBuilder* type = m_types_buffer->allocOne();
466 m_types[IT_Pentaedron6] = type;
467
468 type->setInfos(this, IT_Pentaedron6, "Pentaedron6", Dimension::Dim3, 6, 9, 5);
469
470 type->addFaceTriangle(0, 0, 2, 1);
471 type->addFaceQuad(1, 0, 3, 5, 2);
472 type->addFaceQuad(2, 0, 1, 4, 3);
473 type->addFaceTriangle(3, 3, 4, 5);
474 type->addFaceQuad(4, 1, 2, 5, 4);
475
476 type->addEdge(0, 0, 1, 2, 0);
477 type->addEdge(1, 1, 2, 4, 0);
478 type->addEdge(2, 2, 0, 1, 0);
479 type->addEdge(3, 0, 3, 1, 2);
480 type->addEdge(4, 1, 4, 2, 4);
481 type->addEdge(5, 2, 5, 4, 1);
482 type->addEdge(6, 3, 4, 3, 2);
483 type->addEdge(7, 4, 5, 3, 4);
484 type->addEdge(8, 5, 3, 3, 1);
485 }
486
487 // Pentaedron15
488 {
489 ItemTypeInfoBuilder* type = m_types_buffer->allocOne();
490 m_types[IT_Pentaedron15] = type;
491 type->setOrder(2, ITI_Pentaedron15);
492
493 type->setInfos(this, IT_Pentaedron15, "Pentaedron15", Dimension::Dim3, 15, 9, 5);
494
495 type->addFaceTriangle6(0, 0, 2, 1, 6, 7, 8);
496 type->addFaceQuad8(1, 0, 3, 5, 2, 12, 11, 14, 8);
497 type->addFaceQuad8(2, 0, 1, 4, 3, 6, 13, 9, 3);
498 type->addFaceTriangle6(3, 3, 4, 5, 9, 10, 11);
499 type->addFaceQuad8(4, 1, 2, 5, 4, 7, 14, 10, 13);
500
501 type->addEdge(0, 0, 1, 2, 0);
502 type->addEdge(1, 1, 2, 4, 0);
503 type->addEdge(2, 2, 0, 1, 0);
504 type->addEdge(3, 0, 3, 1, 2);
505 type->addEdge(4, 1, 4, 2, 4);
506 type->addEdge(5, 2, 5, 4, 1);
507 type->addEdge(6, 3, 4, 3, 2);
508 type->addEdge(7, 4, 5, 3, 4);
509 type->addEdge(8, 5, 3, 3, 1);
510 }
511
512 // Tetraedron4
513 {
514 ItemTypeInfoBuilder* type = m_types_buffer->allocOne();
515 m_types[IT_Tetraedron4] = type;
516
517 type->setInfos(this, IT_Tetraedron4, "Tetraedron4", Dimension::Dim3, 4, 6, 4);
518
519 type->addFaceTriangle(0, 0, 2, 1);
520 type->addFaceTriangle(1, 0, 3, 2);
521 type->addFaceTriangle(2, 0, 1, 3);
522 type->addFaceTriangle(3, 1, 2, 3);
523
524 type->addEdge(0, 0, 1, 2, 0);
525 type->addEdge(1, 1, 2, 3, 0);
526 type->addEdge(2, 2, 0, 1, 0);
527 type->addEdge(3, 0, 3, 1, 2);
528 type->addEdge(4, 1, 3, 2, 3);
529 type->addEdge(5, 2, 3, 3, 1);
530 }
531
532 // Tetraedron10
533 {
534 // Pour l'instant comme Tetraedron4
535 ItemTypeInfoBuilder* type = m_types_buffer->allocOne();
536 m_types[IT_Tetraedron10] = type;
537
538 type->setInfos(this, IT_Tetraedron10, "Tetraedron10", Dimension::Dim3, 10, 6, 4);
539 type->setOrder(2, ITI_Tetraedron4);
540
541 type->addFaceTriangle6(0, 0, 2, 1, 6, 5, 4);
542 type->addFaceTriangle6(1, 0, 3, 2, 7, 9, 6);
543 type->addFaceTriangle6(2, 0, 1, 3, 4, 8, 7);
544 type->addFaceTriangle6(3, 1, 2, 3, 5, 9, 8);
545
546 type->addEdge(0, 0, 1, 2, 0);
547 type->addEdge(1, 1, 2, 3, 0);
548 type->addEdge(2, 2, 0, 1, 0);
549 type->addEdge(3, 0, 3, 1, 2);
550 type->addEdge(4, 1, 3, 2, 3);
551 type->addEdge(5, 2, 3, 3, 1);
552 }
553
554 // Heptaedron10
555 {
556 ItemTypeInfoBuilder* type = m_types_buffer->allocOne();
557 m_types[IT_Heptaedron10] = type;
558
559 type->setInfos(this, IT_Heptaedron10, "Heptaedron10", Dimension::Dim3, 10, 15, 7);
560
561 type->addFacePentagon(0, 0, 4, 3, 2, 1);
562 type->addFacePentagon(1, 5, 6, 7, 8, 9);
563 type->addFaceQuad(2, 0, 1, 6, 5);
564 type->addFaceQuad(3, 1, 2, 7, 6);
565 type->addFaceQuad(4, 2, 3, 8, 7);
566 type->addFaceQuad(5, 3, 4, 9, 8);
567 type->addFaceQuad(6, 4, 0, 5, 9);
568
569 type->addEdge(0, 0, 1, 2, 0);
570 type->addEdge(1, 1, 2, 3, 0);
571 type->addEdge(2, 2, 3, 4, 0);
572 type->addEdge(3, 3, 4, 5, 0);
573 type->addEdge(4, 4, 0, 6, 0);
574 type->addEdge(5, 5, 6, 1, 2);
575 type->addEdge(6, 6, 7, 1, 3);
576 type->addEdge(7, 7, 8, 1, 4);
577 type->addEdge(8, 8, 9, 1, 5);
578 type->addEdge(9, 9, 5, 1, 6);
579 type->addEdge(10, 0, 5, 6, 2);
580 type->addEdge(11, 1, 6, 2, 3);
581 type->addEdge(12, 2, 7, 3, 4);
582 type->addEdge(13, 3, 8, 4, 5);
583 type->addEdge(14, 4, 9, 5, 6);
584 }
585
586 // Octaedron12
587 {
588 ItemTypeInfoBuilder* type = m_types_buffer->allocOne();
589 m_types[IT_Octaedron12] = type;
590
591 type->setInfos(this, IT_Octaedron12, "Octaedron12", Dimension::Dim3, 12, 18, 8);
592
593 type->addFaceHexagon(0, 0, 5, 4, 3, 2, 1);
594 type->addFaceHexagon(1, 6, 7, 8, 9, 10, 11);
595 type->addFaceQuad(2, 0, 1, 7, 6);
596 type->addFaceQuad(3, 1, 2, 8, 7);
597 type->addFaceQuad(4, 2, 3, 9, 8);
598 type->addFaceQuad(5, 3, 4, 10, 9);
599 type->addFaceQuad(6, 4, 5, 11, 10);
600 type->addFaceQuad(7, 5, 0, 6, 11);
601
602 type->addEdge(0, 0, 1, 2, 0);
603 type->addEdge(1, 1, 2, 3, 0);
604 type->addEdge(2, 2, 3, 4, 0);
605 type->addEdge(3, 3, 4, 5, 0);
606 type->addEdge(4, 4, 5, 6, 0);
607 type->addEdge(5, 5, 0, 7, 0);
608 type->addEdge(6, 6, 7, 1, 2);
609 type->addEdge(7, 7, 8, 1, 3);
610 type->addEdge(8, 8, 9, 1, 4);
611 type->addEdge(9, 9, 10, 1, 5);
612 type->addEdge(10, 10, 11, 1, 6);
613 type->addEdge(11, 11, 6, 1, 7);
614 type->addEdge(12, 0, 6, 7, 2);
615 type->addEdge(13, 1, 7, 2, 3);
616 type->addEdge(14, 2, 8, 3, 4);
617 type->addEdge(15, 3, 9, 4, 5);
618 type->addEdge(16, 4, 10, 5, 6);
619 type->addEdge(17, 5, 11, 6, 7);
620 }
621
622 // HemiHexa7
623 {
624 ItemTypeInfoBuilder* type = m_types_buffer->allocOne();
625 m_types[IT_HemiHexa7] = type;
626
627 type->setInfos(this, IT_HemiHexa7, "HemiHexa7", Dimension::Dim3, 7, 11, 6);
628
629 type->addFaceTriangle(0, 0, 1, 2);
630 type->addFaceQuad(1, 0, 2, 3, 4);
631 type->addFaceQuad(2, 0, 5, 6, 1);
632 type->addFaceTriangle(3, 0, 4, 5);
633 type->addFaceQuad(4, 1, 6, 3, 2);
634 type->addFaceQuad(5, 3, 6, 5, 4);
635
636 type->addEdge(0, 0, 1, 0, 2);
637 type->addEdge(1, 1, 2, 0, 4);
638 type->addEdge(2, 2, 0, 0, 1);
639 type->addEdge(3, 2, 3, 1, 4);
640 type->addEdge(4, 3, 4, 1, 5);
641 type->addEdge(5, 4, 5, 3, 5);
642 type->addEdge(6, 5, 0, 3, 2);
643 type->addEdge(7, 0, 4, 3, 1);
644 type->addEdge(8, 5, 6, 2, 5);
645 type->addEdge(9, 6, 1, 2, 4);
646 type->addEdge(10, 3, 6, 5, 4);
647 }
648
649 // HemiHexa6
650 {
651 ItemTypeInfoBuilder* type = m_types_buffer->allocOne();
652 m_types[IT_HemiHexa6] = type;
653
654 type->setInfos(this, IT_HemiHexa6, "HemiHexa6", Dimension::Dim3, 6, 10, 6);
655
656 type->addFaceTriangle(0, 0, 1, 2);
657 type->addFaceQuad(1, 0, 2, 3, 4);
658 type->addFaceQuad(2, 0, 5, 3, 1);
659 type->addFaceTriangle(3, 0, 4, 5);
660 type->addFaceTriangle(4, 1, 3, 2);
661 type->addFaceTriangle(5, 3, 5, 4);
662
663 type->addEdge(0, 0, 1, 0, 2);
664 type->addEdge(1, 1, 2, 0, 4);
665 type->addEdge(2, 2, 0, 0, 1);
666 type->addEdge(3, 2, 3, 1, 4);
667 type->addEdge(4, 3, 4, 1, 5);
668 type->addEdge(5, 4, 5, 3, 5);
669 type->addEdge(6, 5, 0, 3, 2);
670 type->addEdge(7, 0, 4, 3, 1);
671 type->addEdge(8, 5, 3, 2, 5);
672 type->addEdge(9, 3, 1, 2, 4);
673 }
674
675 // HemiHexa5
676 {
677 ItemTypeInfoBuilder* type = m_types_buffer->allocOne();
678 m_types[IT_HemiHexa5] = type;
679
680 type->setInfos(this, IT_HemiHexa5, "HemiHexa5", Dimension::Dim3, 5, 7, 4);
681
682 type->addFaceTriangle(0, 0, 1, 2);
683 type->addFaceQuad(1, 0, 2, 3, 4);
684 type->addFaceQuad(2, 0, 4, 3, 1);
685 type->addFaceTriangle(3, 1, 3, 2);
686
687 type->addEdge(0, 0, 1, 0, 2);
688 type->addEdge(1, 1, 2, 0, 3);
689 type->addEdge(2, 2, 0, 0, 1);
690 type->addEdge(3, 2, 3, 1, 3);
691 type->addEdge(4, 3, 1, 2, 3);
692 type->addEdge(5, 3, 4, 1, 2);
693 type->addEdge(6, 4, 0, 1, 2);
694 }
695
696 // AntiWedgeLeft6
697 {
698 ItemTypeInfoBuilder* type = m_types_buffer->allocOne();
699 m_types[IT_AntiWedgeLeft6] = type;
700
701 type->setInfos(this, IT_AntiWedgeLeft6, "AntiWedgeLeft6", Dimension::Dim3, 6, 10, 6);
702
703 type->addFaceTriangle(0, 0, 2, 1);
704 type->addFaceQuad(1, 0, 3, 5, 2);
705 type->addFaceQuad(2, 0, 1, 4, 3);
706 type->addFaceTriangle(3, 3, 4, 5);
707 type->addFaceTriangle(4, 1, 2, 4);
708 type->addFaceTriangle(5, 2, 5, 4);
709
710 type->addEdge(0, 0, 1, 0, 2);
711 type->addEdge(1, 1, 2, 4, 0);
712 type->addEdge(2, 2, 0, 1, 0);
713 type->addEdge(3, 0, 3, 1, 2);
714 type->addEdge(4, 1, 4, 2, 4);
715 type->addEdge(5, 2, 5, 5, 1);
716 type->addEdge(6, 3, 4, 3, 2);
717 type->addEdge(7, 4, 5, 3, 5);
718 type->addEdge(8, 5, 3, 3, 1);
719 type->addEdge(9, 2, 4, 4, 5);
720 }
721
722 // AntiWedgeRight6
723 {
724 ItemTypeInfoBuilder* type = m_types_buffer->allocOne();
725 m_types[IT_AntiWedgeRight6] = type;
726
727 type->setInfos(this, IT_AntiWedgeRight6, "AntiWedgeRight6", Dimension::Dim3, 6, 10, 6);
728
729 type->addFaceTriangle(0, 0, 2, 1);
730 type->addFaceQuad(1, 0, 3, 5, 2);
731 type->addFaceQuad(2, 0, 1, 4, 3);
732 type->addFaceTriangle(3, 3, 4, 5);
733 type->addFaceTriangle(4, 1, 2, 5);
734 type->addFaceTriangle(5, 1, 5, 4);
735
736 type->addEdge(0, 0, 1, 0, 2);
737 type->addEdge(1, 1, 2, 4, 0);
738 type->addEdge(2, 2, 0, 1, 0);
739 type->addEdge(3, 0, 3, 1, 2);
740 type->addEdge(4, 1, 4, 2, 5);
741 type->addEdge(5, 2, 5, 4, 1);
742 type->addEdge(6, 3, 4, 3, 2);
743 type->addEdge(7, 4, 5, 3, 5);
744 type->addEdge(8, 5, 3, 3, 1);
745 type->addEdge(9, 1, 5, 5, 4);
746 }
747
748 // DiTetra5
749 {
750 ItemTypeInfoBuilder* type = m_types_buffer->allocOne();
751 m_types[IT_DiTetra5] = type;
752
753 type->setInfos(this, IT_DiTetra5, "DiTetra5", Dimension::Dim3, 5, 9, 6);
754
755 type->addFaceTriangle(0, 0, 1, 3);
756 type->addFaceTriangle(1, 1, 2, 3);
757 type->addFaceTriangle(2, 2, 0, 3);
758 type->addFaceTriangle(3, 1, 0, 4);
759 type->addFaceTriangle(4, 2, 1, 4);
760 type->addFaceTriangle(5, 0, 2, 4);
761
762 type->addEdge(0, 0, 1, 0, 3);
763 type->addEdge(1, 1, 2, 1, 4);
764 type->addEdge(2, 2, 0, 2, 5);
765 type->addEdge(3, 0, 3, 2, 0);
766 type->addEdge(4, 1, 3, 0, 1);
767 type->addEdge(5, 2, 3, 1, 2);
768 type->addEdge(6, 0, 4, 3, 5);
769 type->addEdge(7, 1, 4, 4, 3);
770 type->addEdge(8, 2, 4, 5, 4);
771 }
772
773 // DualNode
774 {
775 ItemTypeInfoBuilder* type = m_types_buffer->allocOne();
776 m_types[IT_DualNode] = type;
777
778 type->setInfos(this, IT_DualNode, "DualNode", 1, 0, 0);
779 }
780 // DualEdge
781 {
782 ItemTypeInfoBuilder* type = m_types_buffer->allocOne();
783 m_types[IT_DualEdge] = type;
784
785 type->setInfos(this, IT_DualEdge, "DualEdge", 1, 0, 0);
786 }
787 // DualFace
788 {
789 ItemTypeInfoBuilder* type = m_types_buffer->allocOne();
790 m_types[IT_DualFace] = type;
791
792 type->setInfos(this, IT_DualFace, "DualFace", 1, 0, 0);
793 }
794 // DualCell
795 {
796 ItemTypeInfoBuilder* type = m_types_buffer->allocOne();
797 m_types[IT_DualCell] = type;
798
799 type->setInfos(this, IT_DualCell, "DualCell", 1, 0, 0);
800 }
801 // DualParticle
802 {
803 ItemTypeInfoBuilder* type = m_types_buffer->allocOne();
804 m_types[IT_DualParticle] = type;
805
806 type->setInfos(this, IT_DualParticle, "DualParticle", 1, 0, 0);
807 }
808 // Link
809 {
810 ItemTypeInfoBuilder* type = m_types_buffer->allocOne();
811 m_types[IT_Link] = type;
812
813 type->setInfos(this, IT_Link, "Link", 0, 0, 0);
814 }
815
816 // Enneedron14
817 {
818 ItemTypeInfoBuilder* type = m_types_buffer->allocOne();
819 m_types[IT_Enneedron14] = type;
820
821 type->setInfos(this, IT_Enneedron14, "Enneedron14", Dimension::Dim3, 14, 21, 9);
822
823 type->addFaceHeptagon(0, 0, 6, 5, 4, 3, 2, 1);
824 type->addFaceHeptagon(1, 7, 8, 9, 10, 11, 12, 13);
825 type->addFaceQuad(2, 0, 1, 8, 7);
826 type->addFaceQuad(3, 1, 2, 9, 8);
827 type->addFaceQuad(4, 2, 3, 10, 9);
828 type->addFaceQuad(5, 3, 4, 11, 10);
829 type->addFaceQuad(6, 4, 5, 12, 11);
830 type->addFaceQuad(7, 5, 6, 13, 12);
831 type->addFaceQuad(8, 6, 0, 7, 13);
832
833 type->addEdge(0, 0, 1, 2, 0);
834 type->addEdge(1, 1, 2, 3, 0);
835 type->addEdge(2, 2, 3, 4, 0);
836 type->addEdge(3, 3, 4, 5, 0);
837 type->addEdge(4, 4, 5, 6, 0);
838 type->addEdge(5, 5, 6, 7, 0);
839 type->addEdge(6, 6, 0, 8, 0);
840 type->addEdge(7, 7, 8, 1, 2);
841 type->addEdge(8, 8, 9, 1, 3);
842 type->addEdge(9, 9, 10, 1, 4);
843 type->addEdge(10, 10, 11, 1, 5);
844 type->addEdge(11, 11, 12, 1, 6);
845 type->addEdge(12, 12, 13, 1, 7);
846 type->addEdge(13, 13, 7, 1, 8);
847 type->addEdge(14, 0, 7, 8, 2);
848 type->addEdge(15, 1, 8, 1, 2);
849 type->addEdge(16, 2, 9, 2, 3);
850 type->addEdge(17, 3, 10, 3, 4);
851 type->addEdge(18, 4, 11, 4, 5);
852 type->addEdge(19, 5, 12, 5, 6);
853 type->addEdge(20, 6, 13, 6, 7);
854 }
855 // Decaedron16
856 {
857 ItemTypeInfoBuilder* type = m_types_buffer->allocOne();
858 m_types[IT_Decaedron16] = type;
859
860 type->setInfos(this, IT_Decaedron16, "Decaedron16", Dimension::Dim3, 16, 24, 10);
861
862 type->addFaceOctogon(0, 0, 7, 6, 5, 4, 3, 2, 1);
863 type->addFaceOctogon(1, 8, 9, 10, 11, 12, 13, 14, 15);
864 type->addFaceQuad(2, 0, 1, 9, 8);
865 type->addFaceQuad(3, 1, 2, 10, 9);
866 type->addFaceQuad(4, 2, 3, 11, 10);
867 type->addFaceQuad(5, 3, 4, 12, 11);
868 type->addFaceQuad(6, 4, 5, 13, 12);
869 type->addFaceQuad(7, 5, 6, 14, 13);
870 type->addFaceQuad(8, 6, 7, 15, 14);
871 type->addFaceQuad(9, 7, 0, 8, 15);
872
873 type->addEdge(0, 0, 1, 2, 0);
874 type->addEdge(1, 1, 2, 3, 0);
875 type->addEdge(2, 2, 3, 4, 0);
876 type->addEdge(3, 3, 4, 5, 0);
877 type->addEdge(4, 4, 5, 6, 0);
878 type->addEdge(5, 5, 6, 7, 0);
879 type->addEdge(6, 6, 7, 8, 0);
880 type->addEdge(7, 7, 0, 9, 0);
881 type->addEdge(8, 8, 9, 1, 2);
882 type->addEdge(9, 9, 10, 1, 3);
883 type->addEdge(10, 10, 11, 1, 4);
884 type->addEdge(11, 11, 12, 1, 5);
885 type->addEdge(12, 12, 13, 1, 6);
886 type->addEdge(13, 13, 14, 1, 7);
887 type->addEdge(14, 14, 15, 1, 8);
888 type->addEdge(15, 15, 8, 1, 9);
889 type->addEdge(16, 0, 8, 9, 2);
890 type->addEdge(17, 1, 9, 2, 3);
891 type->addEdge(18, 2, 10, 3, 4);
892 type->addEdge(19, 3, 11, 4, 5);
893 type->addEdge(20, 4, 12, 5, 6);
894 type->addEdge(21, 5, 13, 6, 7);
895 type->addEdge(22, 6, 14, 7, 8);
896 type->addEdge(23, 7, 15, 8, 9);
897 }
898
899 // Heptagon7
900 {
901 _addPolygonType(IT_Heptagon7, 7, "Heptagon7");
902 }
903
904 // Octogon8
905 {
906 _addPolygonType(IT_Octogon8, 8, "Octogon8");
907 }
908
909 // Cell3D_Line2
910 {
911 ItemTypeInfoBuilder* type = m_types_buffer->allocOne();
912 m_types[IT_Cell3D_Line2] = type;
913
914 type->setInfos(this, IT_Cell3D_Line2, "Cell3D_Line2", Dimension::Dim1, 2, 0, 0);
915 }
916
917 // CellLine3 (maille d'ordre 2 pour les maillages 1D)
918 {
919 ItemTypeInfoBuilder* type = m_types_buffer->allocOne();
920 m_types[IT_CellLine3] = type;
921 type->setOrder(2, ITI_CellLine2);
922
923 type->setInfos(this, IT_CellLine3, "CellLine3", Dimension::Dim1, 3, 0, 2);
924
925 type->addFaceVertex(0, 0);
926 type->addFaceVertex(1, 1);
927 }
928
929 // Cell3D_Line3
930 {
931 ItemTypeInfoBuilder* type = m_types_buffer->allocOne();
932 m_types[IT_Cell3D_Line3] = type;
933 type->setOrder(2, ITI_Cell3D_Line2);
934
935 type->setInfos(this, IT_Cell3D_Line3, "Cell3D_Line3", Dimension::Dim1, 3, 0, 0);
936 }
937
938 // Cell3D_Triangle3
939 {
940 ItemTypeInfoBuilder* type = m_types_buffer->allocOne();
941 m_types[IT_Cell3D_Triangle3] = type;
942 Int32 nb_face = 3;
943 Int32 nb_edge = 0;
944 if (is_non_manifold)
945 std::swap(nb_face, nb_edge);
946
947 type->setInfos(this, IT_Cell3D_Triangle3, "Cell3D_Triangle3", Dimension::Dim2, 3, nb_edge, nb_face);
948
949 if (is_non_manifold) {
950 type->addEdge2D(0, 0, 1);
951 type->addEdge2D(1, 1, 2);
952 type->addEdge2D(2, 2, 0);
953 }
954 else {
955 type->addFaceLine(0, 0, 1);
956 type->addFaceLine(1, 1, 2);
957 type->addFaceLine(2, 2, 0);
958 }
959 }
960
961 // Cell3D_Triangle6
962 {
963 ItemTypeInfoBuilder* type = m_types_buffer->allocOne();
964 m_types[IT_Cell3D_Triangle6] = type;
965 Int32 nb_face = 3;
966 Int32 nb_edge = 0;
967 if (is_non_manifold)
968 std::swap(nb_face, nb_edge);
969
970 type->setInfos(this, IT_Cell3D_Triangle6, "Cell3D_Triangle6", Dimension::Dim2, 6, nb_edge, nb_face);
971 type->setOrder(2, ITI_Cell3D_Triangle3);
972
973 if (is_non_manifold) {
974 type->addEdge2D(0, 0, 1);
975 type->addEdge2D(1, 1, 2);
976 type->addEdge2D(2, 2, 0);
977 }
978 else {
979 type->addFaceLine3(0, 0, 1, 3);
980 type->addFaceLine3(1, 1, 2, 4);
981 type->addFaceLine3(2, 2, 0, 5);
982 }
983 }
984
985 // Cell3D_Quad4
986 {
987 ItemTypeInfoBuilder* type = m_types_buffer->allocOne();
988 m_types[IT_Cell3D_Quad4] = type;
989 Int32 nb_face = 4;
990 Int32 nb_edge = 0;
991 if (is_non_manifold)
992 std::swap(nb_face, nb_edge);
993
994 type->setInfos(this, IT_Cell3D_Quad4, "Cell3D_Quad4", Dimension::Dim2, 4, nb_edge, nb_face);
995 if (is_non_manifold) {
996 type->addEdge2D(0, 0, 1);
997 type->addEdge2D(1, 1, 2);
998 type->addEdge2D(2, 2, 3);
999 type->addEdge2D(3, 3, 0);
1000 }
1001 else {
1002 type->addFaceLine(0, 0, 1);
1003 type->addFaceLine(1, 1, 2);
1004 type->addFaceLine(2, 2, 3);
1005 type->addFaceLine(3, 3, 0);
1006 }
1007 }
1008
1009 // Cell3D_Quad8
1010 {
1011 ItemTypeInfoBuilder* type = m_types_buffer->allocOne();
1012 m_types[IT_Cell3D_Quad8] = type;
1013
1014 Int32 nb_face = 4;
1015 Int32 nb_edge = 0;
1016 if (is_non_manifold)
1017 std::swap(nb_face, nb_edge);
1018
1019 type->setInfos(this, IT_Cell3D_Quad8, "Cell3D_Quad8", Dimension::Dim2, 8, nb_edge, nb_face);
1020 type->setOrder(2, ITI_Cell3D_Quad4);
1021
1022 if (is_non_manifold) {
1023 type->addEdge2D(0, 0, 1);
1024 type->addEdge2D(1, 1, 2);
1025 type->addEdge2D(2, 2, 3);
1026 type->addEdge2D(3, 3, 0);
1027 }
1028 else {
1029 type->addFaceLine3(0, 0, 1, 4);
1030 type->addFaceLine3(1, 1, 2, 5);
1031 type->addFaceLine3(2, 2, 3, 6);
1032 type->addFaceLine3(3, 3, 0, 7);
1033 }
1034 }
1035
1036 // Cell3D_Quad9
1037 {
1038 ItemTypeInfoBuilder* type = m_types_buffer->allocOne();
1039 m_types[IT_Cell3D_Quad9] = type;
1040
1041 Int32 nb_face = 4;
1042 Int32 nb_edge = 0;
1043 if (is_non_manifold)
1044 std::swap(nb_face, nb_edge);
1045
1046 type->setInfos(this, IT_Cell3D_Quad9, "Cell3D_Quad9", Dimension::Dim2, 9, nb_edge, nb_face);
1047 type->setOrder(2, ITI_Cell3D_Quad4);
1048
1049 if (is_non_manifold) {
1050 type->addEdge2D(0, 0, 1);
1051 type->addEdge2D(1, 1, 2);
1052 type->addEdge2D(2, 2, 3);
1053 type->addEdge2D(3, 3, 0);
1054 }
1055 else {
1056 type->addFaceLine3(0, 0, 1, 4);
1057 type->addFaceLine3(1, 1, 2, 5);
1058 type->addFaceLine3(2, 2, 3, 6);
1059 type->addFaceLine3(3, 3, 0, 7);
1060 }
1061 }
1062
1063 { // Polygon & Polyhedron: generic item types
1064 String arcane_item_type_file = platform::getEnvironmentVariable("ARCANE_ITEM_TYPE_FILE");
1065 if (!arcane_item_type_file.null()) {
1066 // verify the existence of item type file. if doesn't exist return an exception
1067 _readTypes(parallel_mng, arcane_item_type_file);
1068 }
1069 }
1070
1071 // Calcul les relations face->arêtes
1072 // Cette opération doit être appelé en fin phase build
1073 for (Integer i = 0; i < m_types.size(); ++i) {
1074 ItemTypeInfoBuilder* type = static_cast<ItemTypeInfoBuilder*>(m_types[i]);
1075 if (!type)
1076 ARCANE_FATAL("ItemType '{0}' is not defined", type);
1077 type->computeFaceEdgeInfos();
1078 }
1079}
1080
1081/*---------------------------------------------------------------------------*/
1082/*---------------------------------------------------------------------------*/
1083
1086{
1087 if (m_has_polygon_type)
1088 return;
1089 m_has_polygon_type = true;
1090 // Ajoute les types polygones génériques
1091 // Ils commencent à 9 noeuds.
1092 const Int16 begin_nb_node = global_polygon_begin_nb_node;
1093 Int16 max_nb_node = 21;
1094 Int16 max_type = IT_GenericPolygon + max_nb_node - begin_nb_node;
1095 ItemTypeInfo* null_type = typeFromId(IT_NullType);
1096 if (m_types.size() <= max_type)
1097 // Remplit les types vides par le type correspondant à l'entité nulle.
1098 m_types.resize(max_type, null_type);
1099 for (Int16 i = begin_nb_node; i < max_nb_node; ++i) {
1100 String name = String::format("Polygon{0}", i);
1101 _addPolygonType(IT_GenericPolygon + i - begin_nb_node, i, name);
1102 }
1103}
1104
1105/*---------------------------------------------------------------------------*/
1106/*---------------------------------------------------------------------------*/
1107/*!
1108 * \brief Ajoute un type polygone générique
1109 *
1110 * Ajoute un type polygone d'ordre 1 avec \a nb_node noeuds.
1111 * Le type aura comme index \a type_id et comme nom \a type_name.
1112 */
1113void ItemTypeMng::
1114_addPolygonType(Int16 type_id, Int32 nb_node, const String& type_name)
1115{
1116 ItemTypeInfoBuilder* type = m_types_buffer->allocOne();
1117 m_types[type_id] = type;
1118 type->setInfos(this, type_id, type_name, ItemTypeInfoBuilder::Dimension::Dim2, nb_node, nb_node, nb_node);
1119
1120 for (Int32 j = 0; j < nb_node; ++j)
1121 type->addFaceLine(j, j, (j + 1) % nb_node);
1122
1123 for (Integer j = 0; j < nb_node; ++j) {
1124 Int32 previous_node = (j - 1) % nb_node;
1125 Int32 next_node = (j + 1) % nb_node;
1126 type->addEdge(j, j, next_node, previous_node, next_node);
1127 }
1128}
1129
1130/*---------------------------------------------------------------------------*/
1131/*---------------------------------------------------------------------------*/
1132
1134printTypes(std::ostream& ostr)
1135{
1136 ARCANE_ASSERT((m_initialized), ("Cannot use not built ItemTypeMng"));
1137 Integer nb_type = m_types.size();
1138 ostr << "** Number of types " << nb_type << '\n';
1139 for (Integer i = 0; i < nb_type; ++i) {
1140 ItemTypeInfo* type = m_types[i];
1141 ostr << " - Type " << type->typeId()
1142 << " Name: " << type->typeName()
1143 << " Nodes: " << type->nbLocalNode()
1144 << " Faces " << type->nbLocalFace() << '\n';
1145 for (Integer z = 0, sz = type->nbLocalFace(); z < sz; ++z) {
1146 ItemTypeInfo::LocalFace lf = type->localFace(z);
1147 ostr << " - - Face " << z << ":";
1148 for (Integer zk = 0, szk = lf.nbNode(); zk < szk; ++zk) {
1149 ostr << " " << lf.node(zk);
1150 }
1151 ostr << "\n";
1152 }
1153 ostr << "\n";
1154 }
1155}
1156
1157/*---------------------------------------------------------------------------*/
1158/*---------------------------------------------------------------------------*/
1159/*!
1160 * \brief Lecture d'un fichier de types voronoi.
1161 *
1162 * Une cellule voronoi est un polytope dont le nombre de faces et de noeuds
1163 * varie d'une cellule a l'autre. Ici, le type de chaque cellule est lu dans
1164 * un fichier de types associe a un maillage d'entree donne.
1165 * Ce fichier est passe dans la variable d'environnement: ARCANE_ITEM_TYPE_FILE
1166 * Ex: setenv ARCANE_ITEM_TYPE_FILE PATH_TO_FILE/item_file
1167 * Le format du fichier est la suivante:
1168 *
1169 * nb_type
1170 * type_id nb_faces nb_edges
1171 * nb_node_face0 node0_face0 ... nodeN_face1
1172 * . . .
1173 * . . .
1174 * . . .
1175 * nb_node_faceN node0_faceN ... nodeN_faceN
1176 *
1177 * node0_edge0 node1_edge1 lefFace_edge0 rightFace_edge0
1178 * .
1179 * .
1180 * .
1181 * node0_edgeN node1_edge1 lefFace_edgeN rightFace_edgeN
1182 */
1183void ItemTypeMng::
1184_readTypes(IParallelSuperMng* pm, const String& filename)
1185{
1186 m_trace->info() << "Reading additional item types from file '" << filename << "'";
1187
1188 UniqueArray<Byte> bytes;
1189 Integer size = 0;
1190
1191 // Lecture parallèle
1192 if (pm->commRank() == 0) {
1193 long unsigned int file_length = platform::getFileLength(filename);
1194 if (file_length == 0)
1195 throw IOException(A_FUNCINFO, "ARCANE_ITEM_TYPE_FILE is an empty file");
1196 std::ifstream ifile;
1197 ifile.open(filename.localstr(), std::ios::binary);
1198 if (ifile.fail())
1199 throw IOException(A_FUNCINFO, "Cannot open ARCANE_ITEM_TYPE_FILE item type file");
1200 bytes.resize(arcaneCheckArraySize(file_length + 1));
1201 ifile.read((char*)bytes.data(), file_length);
1202 bytes[(Integer)file_length] = '\0';
1203 if (ifile.bad())
1204 throw IOException(A_FUNCINFO, "Cannot read ARCANE_ITEM_TYPE_FILE item type file");
1205 size = bytes.size();
1206 }
1207 {
1208 IntegerArrayView bs(1, &size);
1209 pm->broadcast(bs, 0);
1210 }
1211 bytes.resize(size);
1212 if (size != 0) {
1213 pm->broadcast(bytes, 0);
1214 }
1215 else { // CC: add ending '\0'
1216 bytes.resize(1);
1217 bytes[0] = '\0';
1218 }
1219
1220 // Already built polygons (size => identifier)
1221 typedef std::map<Integer, Integer> PolygonMapper;
1222 PolygonMapper built_polygons;
1223 built_polygons[3] = IT_Triangle3;
1224 built_polygons[4] = IT_Quad4;
1225 built_polygons[5] = IT_Pentagon5;
1226 built_polygons[6] = IT_Hexagon6;
1227 typedef std::set<Integer> KnownTypes;
1228 KnownTypes known_types;
1229 for (Integer i_type = 0; i_type < ItemTypeMng::nbBuiltInItemType(); ++i_type)
1230 known_types.insert(i_type);
1231
1232 if (ItemTypeMng::nbBuiltInItemType() != m_types.size())
1233 ARCANE_FATAL("Invalid initialization of built-in item types");
1234
1235 // Analyse du fichier de types
1236 std::istringstream ifile((char*)bytes.unguardedBasePointer(), std::istringstream::in);
1237 Integer nb_type = 0;
1238 ifile >> nb_type;
1239
1240 m_types.resize(ItemTypeMng::nbBuiltInItemType() + nb_type);
1241 Int16 typeId = -1, nbN = 0, nbE = 0, nbF = 0;
1242 for (Integer i = 0; i < nb_type; ++i) {
1243 ItemTypeInfoBuilder* type = m_types_buffer->allocOne();
1244 ifile >> typeId >> nbF >> nbE;
1245 if (typeId >= nb_type || typeId < 0)
1246 ARCANE_THROW(IOException,"Polyhedron reader cannot allow typeId {0}", typeId);
1247 typeId += ItemTypeMng::nbBuiltInItemType(); // translation d'indexation
1248 if (known_types.find(typeId) != known_types.end())
1249 ARCANE_FATAL("Already existing typeId {0}", typeId);
1250 known_types.insert(typeId);
1251 if (nbE == nbF) // 2d case nbN == nbE == nbF
1252 {
1253 nbN = nbE;
1254 }
1255 else
1256 nbN = nbE - nbF + 2; // Calcul du nb de noeuds nbN a partir de nbE et nbF (formule d'Euler)
1257
1258 type->setInfos(this, typeId, String::format("Polyhedron{0}_{1}-{2}-{3}", typeId, nbN, nbE, nbF), nbN, nbE, nbF);
1259 m_trace->debug(Trace::High) << "Adding " << type->typeName() << " type #"
1260 << typeId - ItemTypeMng::nbBuiltInItemType() << " with " << nbN << " nodes, "
1261 << nbE << " edges, " << nbF << " faces.";
1262 m_types[typeId] = type;
1263 for (Integer iface = 0; iface < nbF; ++iface) {
1264 ifile >> nbN;
1265 UniqueArray<Integer> nodeFace(nbN);
1266 for (Integer inodeFace = 0; inodeFace < nbN; ++inodeFace) {
1267 ifile >> nodeFace[inodeFace];
1268 }
1269 PolygonMapper::const_iterator finder = built_polygons.find(nbN);
1270 Int16 face_type = IT_NullType;
1271 if (finder != built_polygons.end()) {
1272 face_type = finder->second;
1273 m_trace->debug(Trace::High) << "\tAdding already existing face type " << face_type
1274 << " for face " << iface << " with " << nbN << " nodes";
1275 }
1276 else {
1277 ItemTypeInfoBuilder* type2 = m_types_buffer->allocOne();
1278
1279 face_type = m_types.size();
1280 m_types.add(type2);
1281 built_polygons[nbN] = face_type;
1282
1283 type2->setInfos(this, face_type, String::format("Polygon{0}", nbN), nbN, nbN, nbN);
1284 for (Integer j = 0; j < nbN; ++j)
1285 type2->addFaceLine(j, j, (j + 1) % nbN);
1286
1287 for (Integer j = 0; j < nbN; ++j)
1288 type2->addEdge(j, j, (j + 1) % nbN, (j - 1 + nbN) % nbN, (j + 1) % nbN);
1289 m_trace->debug(Trace::High) << "\tAdding new face type " << face_type
1290 << " for face " << iface << " with " << nbN << " nodes";
1291 }
1292 type->addFaceGeneric(iface, face_type, nodeFace);
1293 }
1294 Integer node0, node1, leftFace, rightFace;
1295 for (Integer iedge = 0; iedge < nbE; ++iedge) {
1296 ifile >> node0 >> node1 >> leftFace >> rightFace;
1297 type->addEdge(iedge, node0, node1, leftFace, rightFace);
1298 }
1299 }
1300
1301 m_trace->debug(Trace::High) << "Total number of types : " << m_types.size();
1302}
1303
1304/*---------------------------------------------------------------------------*/
1305/*---------------------------------------------------------------------------*/
1306
1309{
1310 return _singleton()->types().size();
1311}
1312
1315{
1316 return m_nb_builtin_item_type;
1317}
1318/*---------------------------------------------------------------------------*/
1319/*---------------------------------------------------------------------------*/
1320
1321//! AMR
1324{
1325 switch (type) {
1326 case IT_Line2:
1327 return 2;
1328 case IT_Triangle3:
1329 return 4;
1330 case IT_Quad4:
1331 return 4;
1332 case IT_Pentagon5:
1333 return 4;
1334 case IT_Hexagon6:
1335 return 4;
1336 case IT_Tetraedron4:
1337 return 8;
1338 case IT_Pyramid5:
1339 return 0;
1340 case IT_Pentaedron6:
1341 return 8;
1342 case IT_Hexaedron8:
1343 return 8;
1344 case IT_Heptaedron10:
1345 case IT_Octaedron12:
1346 case IT_HemiHexa7:
1347 case IT_HemiHexa6:
1348 case IT_HemiHexa5:
1349 case IT_AntiWedgeLeft6:
1350 case IT_AntiWedgeRight6:
1351 case IT_DiTetra5:
1352 return 0;
1353 default:
1354 ARCANE_FATAL("Not supported Item Type '{0}'", type);
1355 }
1356}
1357
1358/*---------------------------------------------------------------------------*/
1359/*---------------------------------------------------------------------------*/
1360
1361ItemTypeMng* ItemTypeMng::singleton_instance = 0;
1362
1363ItemTypeMng* ItemTypeMng::
1364_singleton()
1365{
1366 if (!singleton_instance)
1367 singleton_instance = new ItemTypeMng();
1368 return singleton_instance;
1369}
1370
1371void ItemTypeMng::
1372_destroySingleton()
1373{
1374 //GG: Ca plante avec Windows. Regarder pourquoi.
1375#ifndef ARCANE_OS_WIN32
1376 delete singleton_instance;
1377#endif
1378 singleton_instance = nullptr;
1379}
1380
1381/*---------------------------------------------------------------------------*/
1382/*---------------------------------------------------------------------------*/
1383
1385types() const
1386{
1387 ARCANE_ASSERT((m_initialized), ("Cannot use not built ItemTypeMng"));
1388 return m_types;
1389}
1390
1391/*---------------------------------------------------------------------------*/
1392/*---------------------------------------------------------------------------*/
1393
1394ItemTypeInfo* ItemTypeMng::
1395typeFromId(Integer id) const
1396{
1397 ARCANE_ASSERT((m_initialized), ("Cannot use not built ItemTypeMng"));
1398 return m_types[id];
1399}
1400
1401/*---------------------------------------------------------------------------*/
1402/*---------------------------------------------------------------------------*/
1403
1404ItemTypeInfo* ItemTypeMng::
1405typeFromId(ItemTypeId id) const
1406{
1407 ARCANE_ASSERT((m_initialized), ("Cannot use not built ItemTypeMng"));
1408 return m_types[id.typeId()];
1409}
1410
1411/*---------------------------------------------------------------------------*/
1412/*---------------------------------------------------------------------------*/
1413
1415typeName(Integer id) const
1416{
1417 return typeFromId(id)->typeName();
1418}
1419
1420/*---------------------------------------------------------------------------*/
1421/*---------------------------------------------------------------------------*/
1422
1424typeName(ItemTypeId id) const
1425{
1426 return typeFromId(id)->typeName();
1427}
1428
1429/*---------------------------------------------------------------------------*/
1430/*---------------------------------------------------------------------------*/
1431// Recopie de la fonction obsolète Item::typeName().
1432// TODO: voir pourquoi il y a un test sur nBasicItemType().
1433String ItemTypeMng::
1434_legacyTypeName(Integer t)
1435{
1436 if (t >= 0 && t < nbBasicItemType())
1437 return _singleton()->typeFromId(t)->typeName();
1438 return "InvalidType";
1439}
1440
1441/*---------------------------------------------------------------------------*/
1442/*---------------------------------------------------------------------------*/
1443
1445hasGeneralCells(IMesh* mesh) const
1446{
1447 auto has_general_cells = false;
1448 if (m_mesh_with_general_cells.find(mesh) != m_mesh_with_general_cells.end()) {
1449 has_general_cells = true;
1450 }
1451 return has_general_cells;
1452}
1453
1454/*---------------------------------------------------------------------------*/
1455/*---------------------------------------------------------------------------*/
1456
1458setMeshWithGeneralCells(IMesh* mesh) noexcept
1459{
1460 ARCANE_ASSERT(mesh, ("Trying to indicate a null mesh contains general cells."));
1461 m_mesh_with_general_cells.insert(mesh);
1462}
1463
1464/*---------------------------------------------------------------------------*/
1465/*---------------------------------------------------------------------------*/
1466
1468getPolygonType(Int16 nb_node) const
1469{
1470 ItemTypeId polygon_type;
1471 if (nb_node == 3)
1472 polygon_type = ITI_Triangle3;
1473 else if (nb_node == 4)
1474 polygon_type = ITI_Quad4;
1475 else if (nb_node == 5)
1476 polygon_type = ITI_Pentagon5;
1477 else if (nb_node == 6)
1478 polygon_type = ITI_Hexagon6;
1479 else if (nb_node == 7)
1480 polygon_type = ITI_Heptagon7;
1481 else if (nb_node == 8)
1482 polygon_type = ITI_Octogon8;
1483 else if (nb_node > 8 && nb_node < 20) {
1484 if (!m_has_polygon_type)
1485 ARCANE_THROW(NotSupportedException, "extended polygon requested (nb_node={0}) but ItemTypeMng::buildPolygonTypes() has not been called", nb_node);
1486 polygon_type = ItemTypeId(ITI_GenericPolygon.typeId() + nb_node - 9);
1487 }
1488 else
1489 ARCANE_THROW(NotSupportedException, "polygon with nb_node={0} (3<=nb_node<=20)", nb_node);
1490 return polygon_type;
1491}
1492
1493/*---------------------------------------------------------------------------*/
1494/*---------------------------------------------------------------------------*/
1495
1496} // End namespace Arcane
1497
1498/*---------------------------------------------------------------------------*/
1499/*---------------------------------------------------------------------------*/
#define ARCANE_THROW(exception_class,...)
Macro pour envoyer une exception avec formattage.
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
Déclarations des types généraux de Arcane.
Integer size() const
Nombre d'éléments du vecteur.
void resize(Int64 s)
Change le nombre d'éléments du tableau à s.
const T * data() const
Accès à la racine du tableau hors toute protection.
Vue constante d'un tableau de type T.
virtual IParallelSuperMng * parallelSuperMng()=0
Gestionnaire superviseur du parallélisme.
Exception lorsqu'une erreur d'entrée/sortie est détectée.
Definition IOException.h:32
virtual void broadcast(ByteArrayView send_buf, Integer process_id)=0
Envoie un tableau de valeurs sur tous les processus Cette opération synchronise le tableau de valeur ...
virtual Int32 commRank() const =0
Retourne le numéro du process (compris entre 0 et nbProcess()-1)
virtual IApplication * application() const =0
Retourne le gestionnaire principal.
virtual Int32 commSize() const =0
Retourne le nombre total de process utilisés.
Interface du gestionnaire de traces.
virtual TraceMessage info()=0
Flot pour un message d'information.
Type d'une entité (Item).
Definition ItemTypeId.h:32
void addEdge(Integer edge_index, Integer n0, Integer n1, Integer f_left, Integer f_right)
Ajoute une arête à la liste des arêtes.
void addFaceLine(Integer face_index, Integer n0, Integer n1)
Ajoute une ligne à la liste des faces (pour les elements 2D)
Informations locales sur une face d'une maille.
Integer node(Integer i) const
Indice locale dans la maille du i-ème noeud de la face.
Integer nbNode() const
Nombre de noeuds de la face.
LocalFace localFace(Integer id) const
Connectivité locale de la i-ème face de la maille.
Integer nbLocalNode() const
Nombre de noeuds de l'entité
String typeName() const
Nom du type.
Integer nbLocalFace() const
Nombre de faces de l'entité
Int16 typeId() const
Numéro du type.
Gestionnaire des types d'entités d'un maillage.
Definition ItemTypeMng.h:65
void buildPolygonTypes()
Construit les types pour gérer les polygones.
void setMeshWithGeneralCells(IMesh *mesh) noexcept
Permet au maillage d'indiquer à l'ItemTypeMng s'il a des mailles génériques.
bool hasGeneralCells(IMesh *mesh) const
Indique si le maillage mesh contient des mailles génériques (en dehors des types intégrés ou addition...
ItemTypeMng()
Constructeur vide (non initialisé)
static Int32 nbHChildrenByItemType(Integer type)
AMR.
ItemTypeId getPolygonType(Int16 nb_node) const
Retourne le type pour un polygone ayant nb_node.
static Integer nbBasicItemType()
nombre de types disponibles
ItemTypeInfo * typeFromId(Integer id) const
Type correspondant au numéro id.
void build(IParallelSuperMng *parallel_mng, ITraceMng *trace)
Constructeur effectif.
ConstArrayView< ItemTypeInfo * > types() const
Liste des types disponibles.
static Integer nbBuiltInItemType()
nombre de types intégrés (hors types additionnels)
void printTypes(std::ostream &ostr)
Affiche les infos sur les types disponibles sur le flot ostr.
String typeName(Integer id) const
Nom du type correspondant au numéro id.
Chaîne de caractères unicode.
const char * localstr() const
Retourne la conversion de l'instance dans l'encodage UTF-8.
Definition String.cc:228
Vecteur 1D de données avec sémantique par valeur (style STL).
long unsigned int getFileLength(const String &filename)
Longueur du fichier filename. Si le fichier n'est pas lisible ou n'existe pas, retourne 0.
String getEnvironmentVariable(const String &name)
Variable d'environnement du nom name.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
Integer arcaneCheckArraySize(unsigned long long size)
Vérifie que size peut être converti dans un 'Integer' pour servir de taille à un tableau....
Int32 Integer
Type représentant un entier.
ArrayView< Integer > IntegerArrayView
Equivalent C d'un tableau à une dimension d'entiers.
Definition UtilsTypes.h:457
std::int16_t Int16
Type entier signé sur 16 bits.
std::int32_t Int32
Type entier signé sur 32 bits.