Arcane  v4.1.1.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
CartesianConnectivity.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/* CartesianConnectivity.cc (C) 2000-2025 */
9/* */
10/* Maillage cartésien. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/utils/NotSupportedException.h"
15
16#include "arcane/cartesianmesh/CartesianConnectivity.h"
17#include "arcane/cartesianmesh/ICartesianMesh.h"
18
19#include "arcane/core/IMesh.h"
20#include "arcane/core/IItemFamily.h"
21#include "arcane/core/VariableTypes.h"
22
23#include "arcane/cartesianmesh/internal/ICartesianMeshInternal.h"
24#include "arcane/cartesianmesh/internal/ICartesianMeshNumberingMngInternal.h"
25
26/*---------------------------------------------------------------------------*/
27/*---------------------------------------------------------------------------*/
28
29namespace Arcane
30{
31
32/*---------------------------------------------------------------------------*/
33/*---------------------------------------------------------------------------*/
34
36_setStorage(ArrayView<Index> nodes_to_cell, ArrayView<Index> cells_to_node,
37 const Permutation* permutation)
38{
39 m_nodes_to_cell = nodes_to_cell;
40 m_cells_to_node = cells_to_node;
41 m_permutation = permutation;
42}
43
44/*---------------------------------------------------------------------------*/
45/*---------------------------------------------------------------------------*/
46/*
47 * \brief Calcule les infos de connectivité
48 *
49 * Pour chaque noeud,détermine les 4 mailles autour en fonction des coordonnées
50 * des mailles. Fait de même pour les quatres noeuds d'une maille.
51 */
54 VariableCellReal3& cells_coord)
55{
56 m_nodes = NodeInfoListView(mesh->nodeFamily());
57 m_cells = CellInfoListView(mesh->cellFamily());
58
59 if (mesh->dimension() == 2 || mesh->dimension() == 1)
60 _computeInfos2D(mesh, nodes_coord, cells_coord);
61 else if (mesh->dimension() == 3)
62 _computeInfos3D(mesh, nodes_coord, cells_coord);
63 else
64 throw NotSupportedException(A_FUNCINFO, "Unknown mesh dimension");
65}
66
67/*---------------------------------------------------------------------------*/
68/*---------------------------------------------------------------------------*/
69
72{
73 m_nodes = NodeInfoListView(cmesh->mesh()->nodeFamily());
74 m_cells = CellInfoListView(cmesh->mesh()->cellFamily());
75
76 if (cmesh->mesh()->dimension() == 2 || cmesh->mesh()->dimension() == 1)
77 _computeInfos2D(cmesh);
78 else if (cmesh->mesh()->dimension() == 3)
79 _computeInfos3D(cmesh);
80 else
81 throw NotSupportedException(A_FUNCINFO, "Unknown mesh dimension");
82}
83
84/*---------------------------------------------------------------------------*/
85/*---------------------------------------------------------------------------*/
86
87void CartesianConnectivity::
88_computeInfos2D(IMesh* mesh, VariableNodeReal3& nodes_coord,
89 VariableCellReal3& cells_coord)
90{
91 CartesianConnectivity& cc = *this;
92 IItemFamily* node_family = mesh->nodeFamily();
93 IItemFamily* cell_family = mesh->cellFamily();
94
95 ENUMERATE_NODE (inode, node_family->allItems()) {
96 Node node = *inode;
97 Real3 node_coord = nodes_coord[inode];
98 Index& idx = cc._index(node);
99 idx.fill(NULL_ITEM_LOCAL_ID);
100 Integer nb_cell = node.nbCell();
101 for (Integer i = 0; i < nb_cell; ++i) {
102 Cell cell = node.cell(i);
103 Int32 cell_lid = cell.localId();
104 Real3 cell_coord = cells_coord[cell];
105 if (cell_coord.y > node_coord.y) {
106 if (cell_coord.x > node_coord.x)
107 idx.v[P_UpperRight] = cell_lid;
108 else
109 idx.v[P_UpperLeft] = cell_lid;
110 }
111 else {
112 if (cell_coord.x > node_coord.x)
113 idx.v[P_LowerRight] = cell_lid;
114 else
115 idx.v[P_LowerLeft] = cell_lid;
116 }
117 }
118 }
119
120 ENUMERATE_CELL (icell, cell_family->allItems()) {
121 Cell cell = *icell;
122 Real3 cell_coord = cells_coord[cell];
123 Index& idx = _index(cell);
124 idx.fill(NULL_ITEM_LOCAL_ID);
125 Integer nb_node = cell.nbNode();
126 for (Integer i = 0; i < nb_node; ++i) {
127 Node node = cell.node(i);
128 Int32 node_lid = node.localId();
129 Real3 node_coord = nodes_coord[node];
130 if (node_coord.y > cell_coord.y) {
131 if (node_coord.x > cell_coord.x)
132 idx.v[P_UpperRight] = node_lid;
133 else
134 idx.v[P_UpperLeft] = node_lid;
135 }
136 else {
137 if (node_coord.x > cell_coord.x)
138 idx.v[P_LowerRight] = node_lid;
139 else
140 idx.v[P_LowerLeft] = node_lid;
141 }
142 }
143 }
144}
145
146/*---------------------------------------------------------------------------*/
147/*---------------------------------------------------------------------------*/
148
149void CartesianConnectivity::
150_computeInfos2D(ICartesianMesh* cmesh)
151{
152 Ref<ICartesianMeshNumberingMngInternal> numbering = cmesh->_internalApi()->cartesianMeshNumberingMngInternal();
153
154 CartesianConnectivity& cc = *this;
155 IItemFamily* node_family = cmesh->mesh()->nodeFamily();
156 IItemFamily* cell_family = cmesh->mesh()->cellFamily();
157
158 {
159 constexpr Integer nb_cell_around_node_max = 4;
160 Int64 cells_around[nb_cell_around_node_max];
161 ArrayView av_cells_around(nb_cell_around_node_max, cells_around);
162
163 // Le CartesianMeshNumberingMng nous donne toujours les mailles autour du noeud dans le même ordre :
164 //
165 // |2|3|
166 // .
167 // |0|1|
168 //
169 // y
170 // ^
171 // |->x
172 //
173 constexpr Int32 pos_2d[nb_cell_around_node_max] = { P_LowerLeft, P_LowerRight, P_UpperLeft, P_UpperRight };
174
175 ENUMERATE_ (Node, inode, node_family->allItems()) {
176 Node node = *inode;
177 numbering->cellUniqueIdsAroundNode(av_cells_around, node);
178
179 Index& idx = cc._index(node);
180 idx.fill(NULL_ITEM_LOCAL_ID);
181
182 const Integer nb_cell = node.nbCell();
183 for (Integer i = 0; i < nb_cell; ++i) {
184 Cell cell = node.cell(i);
185 Integer pos = 0;
186 for (; pos < nb_cell_around_node_max; ++pos) {
187 if (cell.uniqueId() == av_cells_around[pos])
188 break;
189 }
190 if (pos == nb_cell_around_node_max)
191 continue;
192
193 const Int32 cell_lid = cell.localId();
194 idx.v[pos_2d[pos]] = cell_lid;
195 }
196 }
197 }
198 {
199 constexpr Integer nb_node_in_cell_max = 4;
200 Int64 nodes_in_cell[nb_node_in_cell_max];
201 ArrayView av_nodes_in_cell(nb_node_in_cell_max, nodes_in_cell);
202
203 // Le CartesianMeshNumberingMng nous donne toujours les noeuds de la maille dans le même ordre :
204 //
205 // |3|2|
206 // .
207 // |0|1|
208 //
209 // y
210 // ^
211 // |->x
212 //
213 constexpr Int32 pos_2d[nb_node_in_cell_max] = { P_LowerLeft, P_LowerRight, P_UpperRight, P_UpperLeft };
214
215 ENUMERATE_ (Cell, icell, cell_family->allItems()) {
216 Cell cell = *icell;
217 numbering->cellNodeUniqueIds(av_nodes_in_cell, cell);
218
219 Index& idx = _index(cell);
220 idx.fill(NULL_ITEM_LOCAL_ID);
221
222 const Integer nb_node = cell.nbNode();
223 for (Integer i = 0; i < nb_node; ++i) {
224 Node node = cell.node(i);
225 Integer pos = 0;
226 for (; pos < nb_node_in_cell_max; ++pos) {
227 if (node.uniqueId() == av_nodes_in_cell[pos])
228 break;
229 }
230 if (pos == nb_node_in_cell_max)
231 continue;
232
233 const Int32 node_lid = node.localId();
234 idx.v[pos_2d[pos]] = node_lid;
235 }
236 }
237 }
238}
239
240/*---------------------------------------------------------------------------*/
241/*---------------------------------------------------------------------------*/
242
243void CartesianConnectivity::
244_computeInfos3D(IMesh* mesh, VariableNodeReal3& nodes_coord,
245 VariableCellReal3& cells_coord)
246{
247 CartesianConnectivity& cc = *this;
248 IItemFamily* node_family = mesh->nodeFamily();
249 IItemFamily* cell_family = mesh->cellFamily();
250
251 ENUMERATE_NODE (inode, node_family->allItems()) {
252 Node node = *inode;
253 Real3 node_coord = nodes_coord[inode];
254 Index& idx = cc._index(node);
255 idx.fill(NULL_ITEM_LOCAL_ID);
256 Integer nb_cell = node.nbCell();
257 for (Integer i = 0; i < nb_cell; ++i) {
258 Cell cell = node.cell(i);
259 Int32 cell_lid = cell.localId();
260 Real3 cell_coord = cells_coord[cell];
261
262 if (cell_coord.z > node_coord.z) {
263 if (cell_coord.y > node_coord.y) {
264 if (cell_coord.x > node_coord.x)
265 idx.v[P_TopZUpperRight] = cell_lid;
266 else
267 idx.v[P_TopZUpperLeft] = cell_lid;
268 }
269 else {
270 if (cell_coord.x > node_coord.x)
271 idx.v[P_TopZLowerRight] = cell_lid;
272 else
273 idx.v[P_TopZLowerLeft] = cell_lid;
274 }
275 }
276 else {
277 if (cell_coord.y > node_coord.y) {
278 if (cell_coord.x > node_coord.x)
279 idx.v[P_UpperRight] = cell_lid;
280 else
281 idx.v[P_UpperLeft] = cell_lid;
282 }
283 else {
284 if (cell_coord.x > node_coord.x)
285 idx.v[P_LowerRight] = cell_lid;
286 else
287 idx.v[P_LowerLeft] = cell_lid;
288 }
289 }
290 }
291 }
292
293 ENUMERATE_CELL (icell, cell_family->allItems()) {
294 Cell cell = *icell;
295 Real3 cell_coord = cells_coord[cell];
296 Index& idx = _index(cell);
297 idx.fill(NULL_ITEM_LOCAL_ID);
298 Integer nb_node = cell.nbNode();
299 for (Integer i = 0; i < nb_node; ++i) {
300 Node node = cell.node(i);
301 Int32 node_lid = node.localId();
302 Real3 node_coord = nodes_coord[node];
303
304 if (node_coord.z > cell_coord.z) {
305 if (node_coord.y > cell_coord.y) {
306 if (node_coord.x > cell_coord.x)
307 idx.v[P_TopZUpperRight] = node_lid;
308 else
309 idx.v[P_TopZUpperLeft] = node_lid;
310 }
311 else {
312 if (node_coord.x > cell_coord.x)
313 idx.v[P_TopZLowerRight] = node_lid;
314 else
315 idx.v[P_TopZLowerLeft] = node_lid;
316 }
317 }
318 else {
319 if (node_coord.y > cell_coord.y) {
320 if (node_coord.x > cell_coord.x)
321 idx.v[P_UpperRight] = node_lid;
322 else
323 idx.v[P_UpperLeft] = node_lid;
324 }
325 else {
326 if (node_coord.x > cell_coord.x)
327 idx.v[P_LowerRight] = node_lid;
328 else
329 idx.v[P_LowerLeft] = node_lid;
330 }
331 }
332 }
333 }
334}
335
336/*---------------------------------------------------------------------------*/
337/*---------------------------------------------------------------------------*/
338
339void CartesianConnectivity::
340_computeInfos3D(ICartesianMesh* cmesh)
341{
342 Ref<ICartesianMeshNumberingMngInternal> numbering = cmesh->_internalApi()->cartesianMeshNumberingMngInternal();
343
344 CartesianConnectivity& cc = *this;
345 IItemFamily* node_family = cmesh->mesh()->nodeFamily();
346 IItemFamily* cell_family = cmesh->mesh()->cellFamily();
347
348 {
349 constexpr Integer nb_cell_around_node_max = 8;
350 Int64 cells_around[nb_cell_around_node_max];
351 ArrayView av_cells_around(nb_cell_around_node_max, cells_around);
352
353 // Le CartesianMeshNumberingMng nous donne toujours les mailles autour du noeud dans le même ordre :
354 //
355 // z = 0 | z = 1
356 // |2|3| | |6|7|
357 // . | .
358 // |0|1| | |4|5|
359 //
360 // y
361 // ^
362 // |->x
363 //
364 constexpr Int32 pos_3d[nb_cell_around_node_max] = { P_LowerLeft, P_LowerRight, P_UpperLeft, P_UpperRight, P_TopZLowerLeft, P_TopZLowerRight, P_TopZUpperLeft, P_TopZUpperRight };
365
366 ENUMERATE_ (Node, inode, node_family->allItems()) {
367 Node node = *inode;
368 numbering->cellUniqueIdsAroundNode(av_cells_around, node);
369
370 Index& idx = cc._index(node);
371 idx.fill(NULL_ITEM_LOCAL_ID);
372
373 const Integer nb_cell = node.nbCell();
374 for (Integer i = 0; i < nb_cell; ++i) {
375 Cell cell = node.cell(i);
376 Integer pos = 0;
377 for (; pos < nb_cell_around_node_max; ++pos) {
378 if (cell.uniqueId() == av_cells_around[pos])
379 break;
380 }
381 if (pos == nb_cell_around_node_max)
382 continue;
383
384 const Int32 cell_lid = cell.localId();
385 idx.v[pos_3d[pos]] = cell_lid;
386 }
387 }
388 }
389 {
390 constexpr Integer nb_node_in_cell_max = 8;
391 Int64 nodes_in_cell[nb_node_in_cell_max];
392 ArrayView av_nodes_in_cell(nb_node_in_cell_max, nodes_in_cell);
393
394 // Le CartesianMeshNumberingMng nous donne toujours les noeuds de la maille dans le même ordre :
395 //
396 // z = 0 | z = 1
397 // |3|2| | |7|6|
398 // . | .
399 // |0|1| | |4|5|
400 //
401 // y
402 // ^
403 // |->x
404 //
405 constexpr Int32 pos_3d[nb_node_in_cell_max] = { P_LowerLeft, P_LowerRight, P_UpperRight, P_UpperLeft, P_TopZLowerLeft, P_TopZLowerRight, P_TopZUpperRight, P_TopZUpperLeft };
406
407 ENUMERATE_ (Cell, icell, cell_family->allItems()) {
408 Cell cell = *icell;
409 numbering->cellNodeUniqueIds(av_nodes_in_cell, cell);
410
411 Index& idx = _index(cell);
412 idx.fill(NULL_ITEM_LOCAL_ID);
413
414 const Integer nb_node = cell.nbNode();
415 for (Integer i = 0; i < nb_node; ++i) {
416 Node node = cell.node(i);
417 Integer pos = 0;
418 for (; pos < nb_node_in_cell_max; ++pos) {
419 if (node.uniqueId() == av_nodes_in_cell[pos])
420 break;
421 }
422 if (pos == nb_node_in_cell_max)
423 continue;
424
425 const Int32 node_lid = node.localId();
426 idx.v[pos_3d[pos]] = node_lid;
427 }
428 }
429 }
430}
431
432/*---------------------------------------------------------------------------*/
433/*---------------------------------------------------------------------------*/
434
441compute()
442{
443 Int32 p[3][8] = {
444 { 0, 1, 2, 3, 4, 5, 6, 7 },
445 { 3, 0, 1, 2, 7, 4, 5, 6 },
446 { 1, 5, 6, 2, 0, 4, 7, 3 }
447 };
448
449 for (Int32 i = 0; i < 3; ++i)
450 for (Int32 j = 0; j < 8; ++j)
451 permutation[i][j] = static_cast<ePosition>(p[i][j]);
452}
453
454/*---------------------------------------------------------------------------*/
455/*---------------------------------------------------------------------------*/
456
457} // End namespace Arcane
458
459/*---------------------------------------------------------------------------*/
460/*---------------------------------------------------------------------------*/
#define ENUMERATE_(type, name, group)
Enumérateur générique d'un groupe d'entité
#define ENUMERATE_CELL(name, group)
Enumérateur générique d'un groupe de mailles.
#define ENUMERATE_NODE(name, group)
Enumérateur générique d'un groupe de noeuds.
Vue modifiable d'un tableau d'un type T.
void _computeInfos(IMesh *mesh, VariableNodeReal3 &nodes_coord, VariableCellReal3 &cells_coord)
Calcule les infos de connectivité.
void _setStorage(ArrayView< Index > nodes_to_cell, ArrayView< Index > cells_to_node, const Permutation *permutation)
Positionne les tableaux contenant les infos de connectivité
Vue sur les informations des mailles.
Interface d'un maillage cartésien.
virtual IMesh * mesh() const =0
Maillage associé à ce maillage cartésien.
virtual IItemFamily * nodeFamily()=0
Retourne la famille des noeuds.
virtual Integer dimension()=0
Dimension du maillage (1D, 2D ou 3D).
virtual IItemFamily * cellFamily()=0
Retourne la famille des mailles.
Vue sur les informations des noeuds.
Exception lorsqu'une opération n'est pas supportée.
MeshVariableScalarRefT< Cell, Real3 > VariableCellReal3
Grandeur au centre des mailles de type coordonnées.
MeshVariableScalarRefT< Node, Real3 > VariableNodeReal3
Grandeur au noeud de type coordonnées.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
std::int64_t Int64
Type entier signé sur 64 bits.
Int32 Integer
Type représentant un entier.
@ Cell
Le maillage est AMR par maille.
Definition MeshKind.h:52
std::int32_t Int32
Type entier signé sur 32 bits.
Liste des 8 entités autout d'une autre entité
void compute()
Calcule les permutations des 8 ePosition pour chaque direction.