Arcane  4.1.12.0
Developer documentation
Loading...
Searching...
No Matches
SimpleMeshGenerator.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/* SimpleMeshGenerator.cc (C) 2000-2025 */
9/* */
10/* 'Simple' mesh generation service. */
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/*---------------------------------------------------------------------------*/
49
55Integer SimpleMeshGenerator::
56_addNode(Real3 pos)
57{
58 auto i = m_coords_to_uid.find(pos);
59 if (i == m_coords_to_uid.end()) {
60 Integer current_id = m_nodes_unique_id.size();
61 m_nodes_unique_id.add(current_id);
62 m_nodes_coords.add(pos);
63 m_coords_to_uid.insert(std::make_pair(pos, current_id));
64 return current_id;
65 }
66 return i->second;
67}
68
69/*---------------------------------------------------------------------------*/
70/*---------------------------------------------------------------------------*/
71
77Integer SimpleMeshGenerator::
78_addNode(Real x, Real y, Real z)
79{
80 return _addNode(Real3(x, y, z));
81}
82
83/*---------------------------------------------------------------------------*/
84/*---------------------------------------------------------------------------*/
85
86void SimpleMeshGenerator::
87_addCell(Int16 type_id, ConstArrayView<Int64> nodes_id)
88{
89 Integer current_id = m_current_nb_cell;
90 ++m_current_nb_cell;
91 m_mesh_modifier_internal->addCell(ItemUniqueId(current_id), ItemTypeId(type_id), nodes_id);
92}
93
94/*---------------------------------------------------------------------------*/
95/*---------------------------------------------------------------------------*/
96
100void SimpleMeshGenerator::
101_addCell(ItemTypeId type_id, ConstArrayView<Real3> nodes_coords)
102{
103 Integer current_id = m_current_nb_cell;
104 ++m_current_nb_cell;
105 const Int32 nb_node = nodes_coords.size();
106 SmallArray<Int64> nodes_unique_id(nb_node);
107 for (Int32 i = 0; i < nb_node; ++i)
108 nodes_unique_id[i] = _addNode(nodes_coords[i]);
109 m_mesh_modifier_internal->addCell(ItemUniqueId(current_id), type_id, nodes_unique_id);
110}
111
112/*---------------------------------------------------------------------------*/
113/*---------------------------------------------------------------------------*/
114
115bool SimpleMeshGenerator::
116readOptions(XmlNode node)
117{
118 XmlNode modeNode = node.child(String("mode"));
119 m_mode = modeNode.valueAsInteger();
120 if (m_mode < 1 || m_mode > 4) {
121 info() << "Bad syntax for <meshgenerator>";
122 info() << "Expected is <meshgenerator><simple><mode>mode</simple></meshgenerator>";
123 info() << "with mode between 1 and 3";
124 error() << "Bad syntax for <meshgenerator>";
125 return true;
126 }
127 return false;
128}
129
130/*---------------------------------------------------------------------------*/
131/*---------------------------------------------------------------------------*/
132
133void SimpleMeshGenerator::
134_createSimpleHemiHexa7(Real x0, Real y0, Real z1, Real z2)
135{
136 FixedArray<Int64, 7> ids;
137 ids[0] = _addNode(x0, y0, z1);
138 ids[1] = _addNode(x0 + 1., y0, z1);
139 ids[2] = _addNode(x0 + 1., y0, z2);
140 ids[3] = _addNode(x0 + 1., y0 + 1., z2);
141 ids[4] = _addNode(x0, y0 + 1., z2);
142 ids[5] = _addNode(x0, y0 + 1., z1);
143 ids[6] = _addNode(x0 + 1., y0 + 1., z1);
144 _addCell(IT_HemiHexa7, ids.view());
145}
146
147/*---------------------------------------------------------------------------*/
148/*---------------------------------------------------------------------------*/
149
150void SimpleMeshGenerator::
151_createSimpleHemiHexa6(Real x0, Real y0, Real z1, Real z2)
152{
153 FixedArray<Int64, 6> ids;
154 ids[0] = _addNode(x0, y0, z1);
155 ids[1] = _addNode(x0 + 1., y0, z1);
156 ids[2] = _addNode(x0 + 1., y0, z2);
157 ids[3] = _addNode(x0 + 1., y0 + 1., z1);
158 ids[4] = _addNode(x0, y0 + 1., z2);
159 ids[5] = _addNode(x0, y0 + 1., z1);
160 _addCell(IT_HemiHexa6, ids.view());
161}
162
163/*---------------------------------------------------------------------------*/
164/*---------------------------------------------------------------------------*/
165
166void SimpleMeshGenerator::
167_createSimpleHemiHexa5(Real x0, Real y0, Real z1, Real z2)
168{
169 FixedArray<Int64, 5> ids;
170 ids[0] = _addNode(x0, y0, z1);
171 ids[1] = _addNode(x0 + 1., y0, z1);
172 ids[2] = _addNode(x0 + 1., y0, z2);
173 ids[3] = _addNode(x0 + 1., y0 + 1., z1);
174 ids[4] = _addNode(x0, y0 + 1., z1);
175 _addCell(IT_HemiHexa5, ids.view());
176}
177
178/*---------------------------------------------------------------------------*/
179/*---------------------------------------------------------------------------*/
180
181void SimpleMeshGenerator::
182_createSimpleAntiWedgeLeft6(Real x0, Real y0, Real z1, Real z2)
183{
184 FixedArray<Int64, 6> ids;
185 ids[0] = _addNode(x0, y0, z1);
186 ids[1] = _addNode(x0, y0 + 1., z1);
187 ids[2] = _addNode(x0, y0 + .5, z2);
188 ids[3] = _addNode(x0 + 1., y0, z1);
189 ids[4] = _addNode(x0 + 1., y0 + 1., z1);
190 ids[5] = _addNode(x0 + 1., y0 + .5, (z1 + z2) / 2);
191 _addCell(IT_AntiWedgeLeft6, ids.view());
192}
193
194/*---------------------------------------------------------------------------*/
195/*---------------------------------------------------------------------------*/
196
197void SimpleMeshGenerator::
198_createSimpleAntiWedgeRight6(Real x0, Real y0, Real z1, Real z2)
199{
200 FixedArray<Int64, 6> ids;
201 ids[0] = _addNode(x0, y0, z1);
202 ids[1] = _addNode(x0, y0 + 1., z1);
203 ids[2] = _addNode(x0, y0 + .5, (z1 + z2) / 2);
204 ids[3] = _addNode(x0 + 1., y0, z1);
205 ids[4] = _addNode(x0 + 1., y0 + 1., z1);
206 ids[5] = _addNode(x0 + 1., y0 + .5, z2);
207 _addCell(IT_AntiWedgeRight6, ids.view());
208}
209
210/*---------------------------------------------------------------------------*/
211/*---------------------------------------------------------------------------*/
212
213void SimpleMeshGenerator::
214_createSimpleDiTetra5(Real x0, Real y0, Real z1, Real z2)
215{
216 FixedArray<Int64, 5> ids;
217 ids[0] = _addNode(x0, y0, z2);
218 ids[1] = _addNode(x0 + 1., y0, z1);
219 ids[2] = _addNode(x0 + 2., y0, z2);
220 ids[3] = _addNode(x0 + 1., y0 + 1., (z2 + z1) / 2);
221 ids[4] = _addNode(x0 + 1., y0 - 1., (z2 + z1) / 2);
222 _addCell(IT_DiTetra5, ids.view());
223}
224
225/*---------------------------------------------------------------------------*/
226/*---------------------------------------------------------------------------*/
227
228void SimpleMeshGenerator::
229_fillHexaedronCoordinates(ItemTypeId type_id, ArrayView<Real3> coords, Real x0, Real y0, Real z1, Real z2)
230{
231 coords[0] = Real3(x0, y0, z1);
232 coords[1] = Real3(x0 + 1., y0, z1);
233 coords[2] = Real3(x0 + 1., y0 + 1., z1);
234 coords[3] = Real3(x0, y0 + 1., z1);
235 coords[4] = Real3(x0, y0, z2);
236 coords[5] = Real3(x0 + 1., y0, z2);
237 coords[6] = Real3(x0 + 1., y0 + 1., z2);
238 coords[7] = Real3(x0, y0 + 1., z2);
239
240 // Adds the face centers
241 if (type_id == ITI_Hexaedron20 || type_id == ITI_Hexaedron27) {
242 // Hexahedron of order 2 or higher
243 coords[8] = _center(coords, 0, 1);
244 coords[9] = _center(coords, 1, 2);
245 coords[10] = _center(coords, 2, 3);
246 coords[11] = _center(coords, 3, 0);
247 coords[12] = _center(coords, 4, 5);
248 coords[13] = _center(coords, 5, 6);
249 coords[14] = _center(coords, 6, 7);
250 coords[15] = _center(coords, 7, 4);
251 coords[16] = _center(coords, 0, 4);
252 coords[17] = _center(coords, 1, 5);
253 coords[18] = _center(coords, 2, 6);
254 coords[19] = _center(coords, 3, 7);
255 }
256 if (type_id == ITI_Hexaedron27) {
257 // Adds the face centers
258 // TODO: Use the LocalFace type of the type to ensure
259 // numbering consistency
260 coords[20] = _center(coords, 0, 4, 7, 3);
261 coords[21] = _center(coords, 1, 2, 6, 5);
262 coords[22] = _center(coords, 0, 1, 5, 4);
263 coords[23] = _center(coords, 2, 3, 7, 6);
264 coords[24] = _center(coords, 0, 3, 2, 1);
265 coords[25] = _center(coords, 4, 5, 6, 7);
266
267 // Adds the cell center
268 Real3 center;
269 for (Int32 i = 0; i < 8; ++i)
270 center += coords[i];
271 center /= 8.0;
272 coords[26] = center;
273 }
274}
275
276/*---------------------------------------------------------------------------*/
277/*---------------------------------------------------------------------------*/
278
279void SimpleMeshGenerator::
280_createSimpleHexaedron(ItemTypeId type_id, Real x0, Real y0, Real z1, Real z2)
281{
282 if (type_id != ITI_Hexaedron8 && type_id != ITI_Hexaedron27 && type_id != ITI_Hexaedron20)
283 ARCANE_FATAL("Invalid hexaedron type '{0}'", type_id);
284 FixedArray<Real3, 27> coords_array;
285 Int32 nb_node = m_item_type_mng->typeFromId(type_id)->nbLocalNode();
286 ArrayView<Real3> coords(coords_array.view().subView(0, nb_node));
287 _fillHexaedronCoordinates(type_id, coords, x0, y0, z1, z2);
288 _addCell(type_id, coords);
289}
290
291/*---------------------------------------------------------------------------*/
292/*---------------------------------------------------------------------------*/
293
294void SimpleMeshGenerator::
295_createSimpleHexaedron8(Real x0, Real y0, Real z1, Real z2)
296{
297 _createSimpleHexaedron(ITI_Hexaedron8, x0, y0, z1, z2);
298}
299
300/*---------------------------------------------------------------------------*/
301/*---------------------------------------------------------------------------*/
302
303void SimpleMeshGenerator::
304_createSimpleOctaedron12(Real x0, Real y0, Real z1, Real z2)
305{
306 FixedArray<Int64, 12> ids;
307 ids[0] = _addNode(x0, y0 + 0.5, z1);
308 ids[1] = _addNode(x0 + 0.25, y0, z1);
309 ids[2] = _addNode(x0 + 0.75, y0, z1);
310 ids[3] = _addNode(x0 + 1.0, y0 + 0.5, z1);
311 ids[4] = _addNode(x0 + 0.75, y0 + 1., z1);
312 ids[5] = _addNode(x0 + 0.25, y0 + 1., z1);
313
314 ids[6] = _addNode(x0, y0 + 0.5, z2);
315 ids[7] = _addNode(x0 + 0.25, y0, z2);
316 ids[8] = _addNode(x0 + 0.75, y0, z2);
317 ids[9] = _addNode(x0 + 1., y0 + 0.5, z2);
318 ids[10] = _addNode(x0 + 0.75, y0 + 1., z2);
319 ids[11] = _addNode(x0 + 0.25, y0 + 1., z2);
320 _addCell(IT_Octaedron12, ids.view());
321}
322
323/*---------------------------------------------------------------------------*/
324/*---------------------------------------------------------------------------*/
325
326void SimpleMeshGenerator::
327_createSimpleHeptaedron10(Real x0, Real y0, Real z1, Real z2)
328{
329 FixedArray<Int64, 10> ids;
330 ids[0] = _addNode(x0, y0 + 0.5, z1);
331 ids[1] = _addNode(x0 + 1. / 2., y0, z1);
332 ids[2] = _addNode(x0 + 2. / 2., y0 + 0.25, z1);
333 ids[3] = _addNode(x0 + 2. / 2., y0 + 0.75, z1);
334 ids[4] = _addNode(x0 + 1. / 2., y0 + 1, z1);
335
336 ids[5] = _addNode(x0, y0 + 0.5, z2);
337 ids[6] = _addNode(x0 + 1. / 2., y0, z2);
338 ids[7] = _addNode(x0 + 2. / 2., y0 + 0.25, z2);
339 ids[8] = _addNode(x0 + 2. / 2., y0 + 0.75, z2);
340 ids[9] = _addNode(x0 + 1. / 2., y0 + 1., z2);
341 _addCell(IT_Heptaedron10, ids.view());
342}
343
344/*---------------------------------------------------------------------------*/
345/*---------------------------------------------------------------------------*/
346
347void SimpleMeshGenerator::
348_createSimplePentaedron6(Real x0, Real y0, Real z1, Real z2)
349{
350 FixedArray<Int64, 6> ids;
351 ids[0] = _addNode(x0, y0, z1);
352 ids[1] = _addNode(x0 + 1., y0 + 1. / 2., z1);
353 ids[2] = _addNode(x0, y0 + 1., z1);
354 ids[3] = _addNode(x0, y0, z2);
355 ids[4] = _addNode(x0 + 1., y0 + 1. / 2., z2);
356 ids[5] = _addNode(x0, y0 + 1., z2);
357 _addCell(IT_Pentaedron6, ids.view());
358}
359
360/*---------------------------------------------------------------------------*/
361/*---------------------------------------------------------------------------*/
362
363void SimpleMeshGenerator::
364_createSimplePyramid5(Real x0, Real y0, Real z1, Real z2)
365{
366 FixedArray<Int64, 5> ids;
367 ids[0] = _addNode(x0, y0, z1);
368 ids[1] = _addNode(x0 + 1., y0, z1);
369 ids[2] = _addNode(x0 + 1., y0 + 1., z1);
370 ids[3] = _addNode(x0, y0 + 1., z1);
371 ids[4] = _addNode(x0 + 0.5, y0 + 0.5, z2);
372 _addCell(IT_Pyramid5, ids.view());
373}
374
375/*---------------------------------------------------------------------------*/
376/*---------------------------------------------------------------------------*/
377
378void SimpleMeshGenerator::
379_createSimpleTetraedron4(Real x0, Real y0, Real z1, Real z2)
380{
381 FixedArray<Int64, 4> ids;
382 ids[0] = _addNode(x0, y0, z1);
383 ids[1] = _addNode(x0 + 1., y0, z1);
384 ids[2] = _addNode(x0 + 0.5, y0 + 1., z1);
385 ids[3] = _addNode(x0 + 0.5, y0 + 0.5, z2);
386 _addCell(IT_Tetraedron4, ids.view());
387}
388
389/*---------------------------------------------------------------------------*/
390/*---------------------------------------------------------------------------*/
391
392bool SimpleMeshGenerator::
393generateMesh()
394{
395 IPrimaryMesh* mesh = m_mesh;
396
397 info() << "Using simple mesh generator";
398 mesh->setDimension(3);
399 m_item_type_mng = mesh->itemTypeMng();
400
401 if (m_mode == 1) {
402 _createSimpleHexaedron8(2., 0., 0., 1.);
403 _createSimpleOctaedron12(4., 0., 0., 1.);
404 _createSimpleHeptaedron10(6., 0., 0., 1.);
405 _createSimplePentaedron6(8., 0., 0., 1.);
406 _createSimplePyramid5(10., 0., 0., 1.);
407 _createSimpleTetraedron4(12., 0., 0., 1.);
408 _createSimpleHemiHexa7(14., 0., 0., 1.);
409 _createSimpleHemiHexa6(16., 0., 0., 1.);
410 _createSimpleHemiHexa5(18., 0., 0., 1.);
411 _createSimpleAntiWedgeLeft6(20., 0., 0., 1.);
412 _createSimpleAntiWedgeRight6(22., 0., 0., 1.);
413 _createSimpleDiTetra5(24., 0., 0., 1.);
414 }
415
416 if (m_mode == 2) {
417 _createSimpleHexaedron8(0., 0., 0., 1.);
418 _createSimpleHemiHexa7(0., 0., 1., 2.);
419 _createSimpleHexaedron8(1., 0., 0., 1.);
420
421 _createSimpleHexaedron8(2., 0., 0., 1.);
422 _createSimpleHemiHexa6(2., 0., 1., 2.);
423 _createSimpleHexaedron8(3., 0., 0., 1.);
424
425 _createSimpleHexaedron8(4., 0., 0., 1.);
426 _createSimpleHemiHexa5(4., 0., 1., 2.);
427 _createSimpleHexaedron8(5., 0., 0., 1.);
428
429 _createSimpleHexaedron8(6., 0., 0., 1.);
430 _createSimpleAntiWedgeLeft6(6., 0., 1., 2.);
431 _createSimpleHexaedron8(7., 0., 0., 1.);
432
433 _createSimpleHexaedron8(8., 0., 0., 1.);
434 _createSimpleAntiWedgeRight6(8., 0., 1., 2.);
435 _createSimpleHexaedron8(9., 0., 0., 1.);
436
437 _createSimpleHexaedron8(10., 0., 0., 1.);
438 _createSimplePyramid5(10., 0., 1., 2.);
439 _createSimpleHexaedron8(11., 0., 0., 1.);
440 }
441
442 if (m_mode == 3) {
443 _createSimpleHexaedron8(2., 0., 0., 1.);
444 _createSimpleOctaedron12(4., 0., 0., 1.);
445 _createSimpleHeptaedron10(6., 0., 0., 1.);
446 _createSimplePentaedron6(8., 0., 0., 1.);
447 _createSimplePyramid5(10., 0., 0., 1.);
448 _createSimpleTetraedron4(12., 0., 0., 1.);
449 }
450
451 if (m_mode == 4) {
452 _createSimpleHexaedron(ITI_Hexaedron20, 0., 0., 0., 1.);
453 _createSimpleHexaedron(ITI_Hexaedron20, 1., 0., 0., 1.);
454 _createSimpleHexaedron(ITI_Hexaedron27, 2., 0., 0., 1.);
455 _createSimpleHexaedron(ITI_Hexaedron27, 3., 0., 0., 1.);
456 }
457
458 UniqueArray<Int64> cells_infos(m_cells_infos.size());
459 for (Integer i = 0; i < m_cells_infos.size(); ++i)
460 cells_infos[i] = m_cells_infos[i];
461 mesh->endAllocate();
462
463 UniqueArray<Int64> nodes_unique_id(m_nodes_unique_id.size());
464 for (Integer i = 0; i < m_nodes_unique_id.size(); ++i)
465 nodes_unique_id[i] = m_nodes_unique_id[i];
466
467 VariableNodeReal3& nodes_coord_var(mesh->nodesCoordinates());
468 {
469 // Fills the variable containing the node coordinates
470 UniqueArray<Int32> nodes_local_id(nodes_unique_id.size());
471 IItemFamily* family = mesh->itemFamily(IK_Node);
472 family->itemsUniqueIdToLocalId(nodes_local_id, nodes_unique_id);
473 NodeInfoListView nodes_internal(family);
474 Integer nb_node_local_id = nodes_local_id.size();
475 for (Integer i = 0; i < nb_node_local_id; ++i) {
476 Node node = nodes_internal[nodes_local_id[i]];
477 //Int64 unique_id = nodes_unique_id[i];
478 nodes_coord_var[node] = m_nodes_coords[i];
479 //info() << "Set coord " << ItemPrinter(node) << " coord=" << nodes_coord_var[node];
480 }
481 }
482 nodes_coord_var.synchronize();
483
484 return false;
485}
486
487/*---------------------------------------------------------------------------*/
488/*---------------------------------------------------------------------------*/
489
490} // namespace Arcane
491
492/*---------------------------------------------------------------------------*/
493/*---------------------------------------------------------------------------*/
#define ARCANE_FATAL(...)
Macro throwing a FatalErrorException.
Constant view of an array of type T.
constexpr Integer size() const noexcept
Number of elements in the array.
Type of an entity (Item).
Definition ItemTypeId.h:33
Unique identifier of an entity.
Class managing a 3-dimensional real vector.
Definition Real3.h:132
Integer _addNode(Real3 position)
Adds or retrieves the node with coordinates pos.
Real3Map m_coords_to_uid
Coordinates --> Unique index mapping. For automatic merging of nodes at the same coordinates,...
1D data array with pre-allocated stack buffer.
Node of a DOM tree.
Definition XmlNode.h:51
XmlNode child(const String &name) const
Child node of this node with name name.
Definition XmlNode.cc:73
Integer valueAsInteger(bool throw_exception=false) const
Node value converted to integer.
Definition XmlNode.cc:441
MeshVariableScalarRefT< Node, Real3 > VariableNodeReal3
Coordinate type quantity at node.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
Int32 Integer
Type representing an integer.
std::int16_t Int16
Signed integer type of 16 bits.
double Real
Type representing a real number.
std::int32_t Int32
Signed integer type of 32 bits.