Arcane  v3.16.10.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
SimpleMeshGenerator.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/* SimpleMeshGenerator.cc (C) 2000-2025 */
9/* */
10/* Service de génération de maillage 'Simple'. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/std/SimpleMeshGenerator.h"
15
16#include "arcane/utils/ITraceMng.h"
17#include "arcane/utils/Real3.h"
18#include "arcane/utils/FixedArray.h"
19
20#include "arcane/core/XmlNode.h"
21#include "arcane/core/Item.h"
22#include "arcane/core/IPrimaryMesh.h"
23#include "arcane/core/IItemFamily.h"
24#include "arcane/core/MeshVariable.h"
25#include "arcane/core/IMeshModifier.h"
26#include "arcane/core/internal/IMeshModifierInternal.h"
27
28#include <arcane/utils/SmallArray.h>
29
30/*---------------------------------------------------------------------------*/
31/*---------------------------------------------------------------------------*/
32
33namespace Arcane
34{
35
36/*---------------------------------------------------------------------------*/
37/*---------------------------------------------------------------------------*/
38
39SimpleMeshGenerator::
40SimpleMeshGenerator(IPrimaryMesh* mesh)
41: TraceAccessor(mesh->traceMng())
42, m_mesh(mesh)
43, m_mesh_modifier_internal(mesh->modifier()->_modifierInternalApi())
44{
45}
46
47/*---------------------------------------------------------------------------*/
48/*---------------------------------------------------------------------------*/
54Integer SimpleMeshGenerator::
55_addNode(Real3 pos)
56{
57 auto i = m_coords_to_uid.find(pos);
58 if (i == m_coords_to_uid.end()) {
59 Integer current_id = m_nodes_unique_id.size();
60 m_nodes_unique_id.add(current_id);
61 m_nodes_coords.add(pos);
62 m_coords_to_uid.insert(std::make_pair(pos, current_id));
63 return current_id;
64 }
65 return i->second;
66}
67
68/*---------------------------------------------------------------------------*/
69/*---------------------------------------------------------------------------*/
75Integer SimpleMeshGenerator::
76_addNode(Real x, Real y, Real z)
77{
78 return _addNode(Real3(x, y, z));
79}
80
81/*---------------------------------------------------------------------------*/
82/*---------------------------------------------------------------------------*/
83
84void SimpleMeshGenerator::
85_addCell(Int16 type_id, ConstArrayView<Int64> nodes_id)
86{
87 Integer current_id = m_current_nb_cell;
88 ++m_current_nb_cell;
89 m_mesh_modifier_internal->addCell(ItemUniqueId(current_id), ItemTypeId(type_id), nodes_id);
90}
91
92/*---------------------------------------------------------------------------*/
93/*---------------------------------------------------------------------------*/
97void SimpleMeshGenerator::
98_addCell(ItemTypeId type_id, ConstArrayView<Real3> nodes_coords)
99{
100 Integer current_id = m_current_nb_cell;
101 ++m_current_nb_cell;
102 const Int32 nb_node = nodes_coords.size();
103 SmallArray<Int64> nodes_unique_id(nb_node);
104 for (Int32 i = 0; i < nb_node; ++i)
105 nodes_unique_id[i] = _addNode(nodes_coords[i]);
106 m_mesh_modifier_internal->addCell(ItemUniqueId(current_id), type_id, nodes_unique_id);
107}
108
109/*---------------------------------------------------------------------------*/
110/*---------------------------------------------------------------------------*/
111
112bool SimpleMeshGenerator::
113readOptions(XmlNode node)
114{
115 XmlNode modeNode = node.child(String("mode"));
116 m_mode = modeNode.valueAsInteger();
117 if (m_mode < 1 || m_mode > 4) {
118 info() << "Bad syntax for <meshgenerator>";
119 info() << "Expected is <meshgenerator><simple><mode>mode</simple></meshgenerator>";
120 info() << "with mode between 1 and 3";
121 error() << "Bad syntax for <meshgenerator>";
122 return true;
123 }
124 return false;
125}
126
127/*---------------------------------------------------------------------------*/
128/*---------------------------------------------------------------------------*/
129
130void SimpleMeshGenerator::
131_createSimpleHemiHexa7(Real x0, Real y0, Real z1, Real z2)
132{
133 FixedArray<Int64, 7> ids;
134 ids[0] = _addNode(x0, y0, z1);
135 ids[1] = _addNode(x0 + 1., y0, z1);
136 ids[2] = _addNode(x0 + 1., y0, z2);
137 ids[3] = _addNode(x0 + 1., y0 + 1., z2);
138 ids[4] = _addNode(x0, y0 + 1., z2);
139 ids[5] = _addNode(x0, y0 + 1., z1);
140 ids[6] = _addNode(x0 + 1., y0 + 1., z1);
141 _addCell(IT_HemiHexa7, ids.view());
142}
143
144/*---------------------------------------------------------------------------*/
145/*---------------------------------------------------------------------------*/
146
147void SimpleMeshGenerator::
148_createSimpleHemiHexa6(Real x0, Real y0, Real z1, Real z2)
149{
150 FixedArray<Int64, 6> ids;
151 ids[0] = _addNode(x0, y0, z1);
152 ids[1] = _addNode(x0 + 1., y0, z1);
153 ids[2] = _addNode(x0 + 1., y0, z2);
154 ids[3] = _addNode(x0 + 1., y0 + 1., z1);
155 ids[4] = _addNode(x0, y0 + 1., z2);
156 ids[5] = _addNode(x0, y0 + 1., z1);
157 _addCell(IT_HemiHexa6, ids.view());
158}
159
160/*---------------------------------------------------------------------------*/
161/*---------------------------------------------------------------------------*/
162
163void SimpleMeshGenerator::
164_createSimpleHemiHexa5(Real x0, Real y0, Real z1, Real z2)
165{
166 FixedArray<Int64, 5> ids;
167 ids[0] = _addNode(x0, y0, z1);
168 ids[1] = _addNode(x0 + 1., y0, z1);
169 ids[2] = _addNode(x0 + 1., y0, z2);
170 ids[3] = _addNode(x0 + 1., y0 + 1., z1);
171 ids[4] = _addNode(x0, y0 + 1., z1);
172 _addCell(IT_HemiHexa5, ids.view());
173}
174
175/*---------------------------------------------------------------------------*/
176/*---------------------------------------------------------------------------*/
177
178void SimpleMeshGenerator::
179_createSimpleAntiWedgeLeft6(Real x0, Real y0, Real z1, Real z2)
180{
181 FixedArray<Int64, 6> ids;
182 ids[0] = _addNode(x0, y0, z1);
183 ids[1] = _addNode(x0, y0 + 1., z1);
184 ids[2] = _addNode(x0, y0 + .5, z2);
185 ids[3] = _addNode(x0 + 1., y0, z1);
186 ids[4] = _addNode(x0 + 1., y0 + 1., z1);
187 ids[5] = _addNode(x0 + 1., y0 + .5, (z1 + z2) / 2);
188 _addCell(IT_AntiWedgeLeft6, ids.view());
189}
190
191/*---------------------------------------------------------------------------*/
192/*---------------------------------------------------------------------------*/
193
194void SimpleMeshGenerator::
195_createSimpleAntiWedgeRight6(Real x0, Real y0, Real z1, Real z2)
196{
197 FixedArray<Int64, 6> ids;
198 ids[0] = _addNode(x0, y0, z1);
199 ids[1] = _addNode(x0, y0 + 1., z1);
200 ids[2] = _addNode(x0, y0 + .5, (z1 + z2) / 2);
201 ids[3] = _addNode(x0 + 1., y0, z1);
202 ids[4] = _addNode(x0 + 1., y0 + 1., z1);
203 ids[5] = _addNode(x0 + 1., y0 + .5, z2);
204 _addCell(IT_AntiWedgeRight6, ids.view());
205}
206
207/*---------------------------------------------------------------------------*/
208/*---------------------------------------------------------------------------*/
209
210void SimpleMeshGenerator::
211_createSimpleDiTetra5(Real x0, Real y0, Real z1, Real z2)
212{
213 FixedArray<Int64, 5> ids;
214 ids[0] = _addNode(x0, y0, z2);
215 ids[1] = _addNode(x0 + 1., y0, z1);
216 ids[2] = _addNode(x0 + 2., y0, z2);
217 ids[3] = _addNode(x0 + 1., y0 + 1., (z2 + z1) / 2);
218 ids[4] = _addNode(x0 + 1., y0 - 1., (z2 + z1) / 2);
219 _addCell(IT_DiTetra5, ids.view());
220}
221
222/*---------------------------------------------------------------------------*/
223/*---------------------------------------------------------------------------*/
224
225void SimpleMeshGenerator::
226_fillHexaedronCoordinates(ItemTypeId type_id, ArrayView<Real3> coords, Real x0, Real y0, Real z1, Real z2)
227{
228 coords[0] = Real3(x0, y0, z1);
229 coords[1] = Real3(x0 + 1., y0, z1);
230 coords[2] = Real3(x0 + 1., y0 + 1., z1);
231 coords[3] = Real3(x0, y0 + 1., z1);
232 coords[4] = Real3(x0, y0, z2);
233 coords[5] = Real3(x0 + 1., y0, z2);
234 coords[6] = Real3(x0 + 1., y0 + 1., z2);
235 coords[7] = Real3(x0, y0 + 1., z2);
236
237 // Ajoute le centre des faces
238 if (type_id == ITI_Hexaedron20 || type_id == ITI_Hexaedron27) {
239 // Hexaedre d'ordre 2 ou plus
240 coords[8] = _center(coords, 0, 1);
241 coords[9] = _center(coords, 1, 2);
242 coords[10] = _center(coords, 2, 3);
243 coords[11] = _center(coords, 3, 0);
244 coords[12] = _center(coords, 4, 5);
245 coords[13] = _center(coords, 5, 6);
246 coords[14] = _center(coords, 6, 7);
247 coords[15] = _center(coords, 7, 4);
248 coords[16] = _center(coords, 0, 4);
249 coords[17] = _center(coords, 1, 5);
250 coords[18] = _center(coords, 2, 6);
251 coords[19] = _center(coords, 3, 7);
252 }
253 if (type_id == ITI_Hexaedron27) {
254 // Ajoute le centre des faces
255 // TODO: Utiliser le type LocalFace du type pour garantir
256 // la cohérence de la numérotation
257 coords[20] = _center(coords, 0, 4, 7, 3);
258 coords[21] = _center(coords, 1, 2, 6, 5);
259 coords[22] = _center(coords, 0, 1, 5, 4);
260 coords[23] = _center(coords, 2, 3, 7, 6);
261 coords[24] = _center(coords, 0, 3, 2, 1);
262 coords[25] = _center(coords, 4, 5, 6, 7);
263
264 // Ajoute le centre de la maille
265 Real3 center;
266 for (Int32 i = 0; i < 8; ++i)
267 center += coords[i];
268 center /= 8.0;
269 coords[26] = center;
270 }
271}
272
273/*---------------------------------------------------------------------------*/
274/*---------------------------------------------------------------------------*/
275
276void SimpleMeshGenerator::
277_createSimpleHexaedron(ItemTypeId type_id, Real x0, Real y0, Real z1, Real z2)
278{
279 if (type_id != ITI_Hexaedron8 && type_id != ITI_Hexaedron27 && type_id != ITI_Hexaedron20)
280 ARCANE_FATAL("Invalid hexaedron type '{0}'", type_id);
281 FixedArray<Real3, 27> coords_array;
282 Int32 nb_node = m_item_type_mng->typeFromId(type_id)->nbLocalNode();
283 ArrayView<Real3> coords(coords_array.view().subView(0, nb_node));
284 _fillHexaedronCoordinates(type_id, coords, x0, y0, z1, z2);
285 _addCell(type_id, coords);
286}
287
288/*---------------------------------------------------------------------------*/
289/*---------------------------------------------------------------------------*/
290
291void SimpleMeshGenerator::
292_createSimpleHexaedron8(Real x0, Real y0, Real z1, Real z2)
293{
294 _createSimpleHexaedron(ITI_Hexaedron8, x0, y0, z1, z2);
295}
296
297/*---------------------------------------------------------------------------*/
298/*---------------------------------------------------------------------------*/
299
300void SimpleMeshGenerator::
301_createSimpleOctaedron12(Real x0, Real y0, Real z1, Real z2)
302{
303 FixedArray<Int64, 12> ids;
304 ids[0] = _addNode(x0, y0 + 0.5, z1);
305 ids[1] = _addNode(x0 + 0.25, y0, z1);
306 ids[2] = _addNode(x0 + 0.75, y0, z1);
307 ids[3] = _addNode(x0 + 1.0, y0 + 0.5, z1);
308 ids[4] = _addNode(x0 + 0.75, y0 + 1., z1);
309 ids[5] = _addNode(x0 + 0.25, y0 + 1., z1);
310
311 ids[6] = _addNode(x0, y0 + 0.5, z2);
312 ids[7] = _addNode(x0 + 0.25, y0, z2);
313 ids[8] = _addNode(x0 + 0.75, y0, z2);
314 ids[9] = _addNode(x0 + 1., y0 + 0.5, z2);
315 ids[10] = _addNode(x0 + 0.75, y0 + 1., z2);
316 ids[11] = _addNode(x0 + 0.25, y0 + 1., z2);
317 _addCell(IT_Octaedron12, ids.view());
318}
319
320/*---------------------------------------------------------------------------*/
321/*---------------------------------------------------------------------------*/
322
323void SimpleMeshGenerator::
324_createSimpleHeptaedron10(Real x0, Real y0, Real z1, Real z2)
325{
326 FixedArray<Int64, 10> ids;
327 ids[0] = _addNode(x0, y0 + 0.5, z1);
328 ids[1] = _addNode(x0 + 1. / 2., y0, z1);
329 ids[2] = _addNode(x0 + 2. / 2., y0 + 0.25, z1);
330 ids[3] = _addNode(x0 + 2. / 2., y0 + 0.75, z1);
331 ids[4] = _addNode(x0 + 1. / 2., y0 + 1, z1);
332
333 ids[5] = _addNode(x0, y0 + 0.5, z2);
334 ids[6] = _addNode(x0 + 1. / 2., y0, z2);
335 ids[7] = _addNode(x0 + 2. / 2., y0 + 0.25, z2);
336 ids[8] = _addNode(x0 + 2. / 2., y0 + 0.75, z2);
337 ids[9] = _addNode(x0 + 1. / 2., y0 + 1., z2);
338 _addCell(IT_Heptaedron10, ids.view());
339}
340
341/*---------------------------------------------------------------------------*/
342/*---------------------------------------------------------------------------*/
343
344void SimpleMeshGenerator::
345_createSimplePentaedron6(Real x0, Real y0, Real z1, Real z2)
346{
347 FixedArray<Int64, 6> ids;
348 ids[0] = _addNode(x0, y0, z1);
349 ids[1] = _addNode(x0 + 1., y0 + 1. / 2., z1);
350 ids[2] = _addNode(x0, y0 + 1., z1);
351 ids[3] = _addNode(x0, y0, z2);
352 ids[4] = _addNode(x0 + 1., y0 + 1. / 2., z2);
353 ids[5] = _addNode(x0, y0 + 1., z2);
354 _addCell(IT_Pentaedron6, ids.view());
355}
356
357/*---------------------------------------------------------------------------*/
358/*---------------------------------------------------------------------------*/
359
360void SimpleMeshGenerator::
361_createSimplePyramid5(Real x0, Real y0, Real z1, Real z2)
362{
363 FixedArray<Int64, 5> ids;
364 ids[0] = _addNode(x0, y0, z1);
365 ids[1] = _addNode(x0 + 1., y0, z1);
366 ids[2] = _addNode(x0 + 1., y0 + 1., z1);
367 ids[3] = _addNode(x0, y0 + 1., z1);
368 ids[4] = _addNode(x0 + 0.5, y0 + 0.5, z2);
369 _addCell(IT_Pyramid5, ids.view());
370}
371
372/*---------------------------------------------------------------------------*/
373/*---------------------------------------------------------------------------*/
374
375void SimpleMeshGenerator::
376_createSimpleTetraedron4(Real x0, Real y0, Real z1, Real z2)
377{
378 FixedArray<Int64, 4> ids;
379 ids[0] = _addNode(x0, y0, z1);
380 ids[1] = _addNode(x0 + 1., y0, z1);
381 ids[2] = _addNode(x0 + 0.5, y0 + 1., z1);
382 ids[3] = _addNode(x0 + 0.5, y0 + 0.5, z2);
383 _addCell(IT_Tetraedron4, ids.view());
384}
385
386/*---------------------------------------------------------------------------*/
387/*---------------------------------------------------------------------------*/
388
389bool SimpleMeshGenerator::
390generateMesh()
391{
392 IPrimaryMesh* mesh = m_mesh;
393
394 info() << "Using simple mesh generator";
395 mesh->setDimension(3);
396 m_item_type_mng = mesh->itemTypeMng();
397
398 if (m_mode == 1) {
399 _createSimpleHexaedron8(2., 0., 0., 1.);
400 _createSimpleOctaedron12(4., 0., 0., 1.);
401 _createSimpleHeptaedron10(6., 0., 0., 1.);
402 _createSimplePentaedron6(8., 0., 0., 1.);
403 _createSimplePyramid5(10., 0., 0., 1.);
404 _createSimpleTetraedron4(12., 0., 0., 1.);
405 _createSimpleHemiHexa7(14., 0., 0., 1.);
406 _createSimpleHemiHexa6(16., 0., 0., 1.);
407 _createSimpleHemiHexa5(18., 0., 0., 1.);
408 _createSimpleAntiWedgeLeft6(20., 0., 0., 1.);
409 _createSimpleAntiWedgeRight6(22., 0., 0., 1.);
410 _createSimpleDiTetra5(24., 0., 0., 1.);
411 }
412
413 if (m_mode == 2) {
414 _createSimpleHexaedron8(0., 0., 0., 1.);
415 _createSimpleHemiHexa7(0., 0., 1., 2.);
416 _createSimpleHexaedron8(1., 0., 0., 1.);
417
418 _createSimpleHexaedron8(2., 0., 0., 1.);
419 _createSimpleHemiHexa6(2., 0., 1., 2.);
420 _createSimpleHexaedron8(3., 0., 0., 1.);
421
422 _createSimpleHexaedron8(4., 0., 0., 1.);
423 _createSimpleHemiHexa5(4., 0., 1., 2.);
424 _createSimpleHexaedron8(5., 0., 0., 1.);
425
426 _createSimpleHexaedron8(6., 0., 0., 1.);
427 _createSimpleAntiWedgeLeft6(6., 0., 1., 2.);
428 _createSimpleHexaedron8(7., 0., 0., 1.);
429
430 _createSimpleHexaedron8(8., 0., 0., 1.);
431 _createSimpleAntiWedgeRight6(8., 0., 1., 2.);
432 _createSimpleHexaedron8(9., 0., 0., 1.);
433
434 _createSimpleHexaedron8(10., 0., 0., 1.);
435 _createSimplePyramid5(10., 0., 1., 2.);
436 _createSimpleHexaedron8(11., 0., 0., 1.);
437 }
438
439 if (m_mode == 3) {
440 _createSimpleHexaedron8(2., 0., 0., 1.);
441 _createSimpleOctaedron12(4., 0., 0., 1.);
442 _createSimpleHeptaedron10(6., 0., 0., 1.);
443 _createSimplePentaedron6(8., 0., 0., 1.);
444 _createSimplePyramid5(10., 0., 0., 1.);
445 _createSimpleTetraedron4(12., 0., 0., 1.);
446 }
447
448 if (m_mode == 4) {
449 _createSimpleHexaedron(ITI_Hexaedron20, 0., 0., 0., 1.);
450 _createSimpleHexaedron(ITI_Hexaedron20, 1., 0., 0., 1.);
451 _createSimpleHexaedron(ITI_Hexaedron27, 2., 0., 0., 1.);
452 _createSimpleHexaedron(ITI_Hexaedron27, 3., 0., 0., 1.);
453 }
454
455 UniqueArray<Int64> cells_infos(m_cells_infos.size());
456 for (Integer i = 0; i < m_cells_infos.size(); ++i)
457 cells_infos[i] = m_cells_infos[i];
458 mesh->endAllocate();
459
460 UniqueArray<Int64> nodes_unique_id(m_nodes_unique_id.size());
461 for (Integer i = 0; i < m_nodes_unique_id.size(); ++i)
462 nodes_unique_id[i] = m_nodes_unique_id[i];
463
464 VariableNodeReal3& nodes_coord_var(mesh->nodesCoordinates());
465 {
466 // Remplit la variable contenant les coordonnées des noeuds
467 UniqueArray<Int32> nodes_local_id(nodes_unique_id.size());
468 IItemFamily* family = mesh->itemFamily(IK_Node);
469 family->itemsUniqueIdToLocalId(nodes_local_id, nodes_unique_id);
470 NodeInfoListView nodes_internal(family);
471 Integer nb_node_local_id = nodes_local_id.size();
472 for (Integer i = 0; i < nb_node_local_id; ++i) {
473 Node node = nodes_internal[nodes_local_id[i]];
474 //Int64 unique_id = nodes_unique_id[i];
475 nodes_coord_var[node] = m_nodes_coords[i];
476 //info() << "Set coord " << ItemPrinter(node) << " coord=" << nodes_coord_var[node];
477 }
478 }
479 nodes_coord_var.synchronize();
480
481 return false;
482}
483
484/*---------------------------------------------------------------------------*/
485/*---------------------------------------------------------------------------*/
486
487} // namespace Arcane
488
489/*---------------------------------------------------------------------------*/
490/*---------------------------------------------------------------------------*/
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
Vue constante d'un tableau de type T.
constexpr Integer size() const noexcept
Nombre d'éléments du tableau.
Type d'une entité (Item).
Definition ItemTypeId.h:32
Identifiant unique d'une entité.
Classe gérant un vecteur de réel de dimension 3.
Definition Real3.h:132
Integer _addNode(Real3 position)
Ajoute ou récupère le nœud ayant pour coordonnées pos.
Real3Map m_coords_to_uid
Mapping Coordonnées --> Indice unique. Pour la fusion automatique des noeuds aux mêmes coordonnées,...
Tableau 1D de données avec buffer pré-alloué sur la pile.
Definition SmallArray.h:89
Chaîne de caractères unicode.
Noeud d'un arbre DOM.
Definition XmlNode.h:51
XmlNode child(const String &name) const
Noeud fils de celui-ci de nom name.
Definition XmlNode.cc:64
Integer valueAsInteger(bool throw_exception=false) const
Valeur du noeud convertie en entier.
Definition XmlNode.cc:432
MeshVariableScalarRefT< Node, Real3 > VariableNodeReal3
Grandeur au noeud de type coordonnées.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
Int32 Integer
Type représentant un entier.
std::int16_t Int16
Type entier signé sur 16 bits.
double Real
Type représentant un réel.
std::int32_t Int32
Type entier signé sur 32 bits.