Arcane  v4.1.4.0
Documentation utilisateur
Chargement...
Recherche...
Aucune correspondance
CartesianMeshPatch.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/* CartesianMeshPatch.cc (C) 2000-2026 */
9/* */
10/* Informations sur un patch AMR d'un maillage cartésien. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/cartesianmesh/internal/CartesianMeshPatch.h"
15
16#include "arcane/IMesh.h"
17#include "arcane/ItemPrinter.h"
18
19#include "arcane/cartesianmesh/ICartesianMesh.h"
20#include "arcane/cartesianmesh/CartesianConnectivity.h"
21
22#include <set>
23
24/*---------------------------------------------------------------------------*/
25/*---------------------------------------------------------------------------*/
26
27namespace Arcane
28{
29
30/*---------------------------------------------------------------------------*/
31/*---------------------------------------------------------------------------*/
32
33CartesianMeshPatch::
34CartesianMeshPatch(ICartesianMesh* cmesh, Integer patch_index, const AMRPatchPosition& position)
35: TraceAccessor(cmesh->traceMng())
36, m_mesh(cmesh)
37, m_position(position)
38, m_amr_patch_index(patch_index)
39, m_impl(this)
40{
41 Integer nb_dir = cmesh->mesh()->dimension();
42 for (Integer i = 0; i < nb_dir; ++i) {
43 eMeshDirection dir = static_cast<eMeshDirection>(i);
44 m_cell_directions[i]._internalInit(cmesh, dir, patch_index);
45 m_face_directions[i]._internalInit(cmesh, dir, patch_index);
46 m_node_directions[i]._internalInit(cmesh, dir, patch_index);
47 }
48}
49
50/*---------------------------------------------------------------------------*/
51/*---------------------------------------------------------------------------*/
52
53CartesianMeshPatch::
54CartesianMeshPatch(ICartesianMesh* cmesh,Integer patch_index)
55: CartesianMeshPatch(cmesh, patch_index, {})
56{
57}
58
59/*---------------------------------------------------------------------------*/
60/*---------------------------------------------------------------------------*/
61
62CartesianMeshPatch::
63~CartesianMeshPatch()
64{
65 for( Integer i=0; i<3; ++i ){
66 m_cell_directions[i]._internalDestroy();
67 m_face_directions[i]._internalDestroy();
68 m_node_directions[i]._internalDestroy();
69 }
70}
71
72/*---------------------------------------------------------------------------*/
73/*---------------------------------------------------------------------------*/
74
75/*---------------------------------------------------------------------------*/
76/*---------------------------------------------------------------------------*/
77
78CellGroup CartesianMeshPatch::
79cells()
80{
81 // Le groupe de mailles du patch est le même dans toutes les directions.
82 return cellDirection(MD_DirX).allCells();
83}
84
85/*---------------------------------------------------------------------------*/
86/*---------------------------------------------------------------------------*/
87
88CellGroup CartesianMeshPatch::
89inPatchCells()
90{
91 return cellDirection(MD_DirX).inPatchCells();
92}
93
94/*---------------------------------------------------------------------------*/
95/*---------------------------------------------------------------------------*/
96
97CellGroup CartesianMeshPatch::
98overlapCells()
99{
100 return cellDirection(MD_DirX).overlapCells();
101}
102
103/*---------------------------------------------------------------------------*/
104/*---------------------------------------------------------------------------*/
105
106/*
107 * \brief Calcule les infos sur les noeuds avant/après et gauche/droite d'une maille
108 * pour chaque direction.
109 */
110void CartesianMeshPatch::
111_computeNodeCellInformations2D(Cell cell0,Real3 cell0_coord,VariableNodeReal3& nodes_coord)
112{
113 using Int8 = std::int8_t;
114 Int8 nodes_indirection_i[CellDirectionMng::MAX_NB_NODE];
115 ArrayView<Int8> nodes_indirection(CellDirectionMng::MAX_NB_NODE,nodes_indirection_i);
116 Int32 nb_node = cell0.nbNode();
117 if (nb_node!=4)
118 ARCANE_FATAL("Number of nodes should be '4' (v={0})",nb_node);
119 Int8 i8_nb_node = 4;
120 Real3 cell_coord = cell0_coord;
121 bool is_2d = m_mesh->mesh()->dimension()==2;
122 if (!is_2d)
123 ARCANE_FATAL("Invalid call. This mesh is not a 2D mesh");
124
125 // Direction X
126 nodes_indirection.fill(-1);
127 for( Int8 i=0; i<i8_nb_node; ++i ){
128 Node node = cell0.node(i);
129 Real3 node_coord = nodes_coord[node];
130 if (node_coord.x>cell_coord.x){
131 if (node_coord.y>cell_coord.y)
132 nodes_indirection[CNP_NextLeft] = i;
133 else
134 nodes_indirection[CNP_NextRight] = i;
135 }
136 else{
137 if (node_coord.y>cell_coord.y)
138 nodes_indirection[CNP_PreviousLeft] = i;
139 else
140 nodes_indirection[CNP_PreviousRight] = i;
141 }
142 }
143 cellDirection(MD_DirX).setNodesIndirection(nodes_indirection);
144
145 // Direction Y
146 nodes_indirection.fill(-1);
147 for( Int8 i=0; i<i8_nb_node; ++i ){
148 Node node = cell0.node(i);
149 Real3 node_coord = nodes_coord[node];
150 if (node_coord.y>cell_coord.y){
151 if (node_coord.x>cell_coord.x)
152 nodes_indirection[CNP_NextRight] = i;
153 else
154 nodes_indirection[CNP_NextLeft] = i;
155 }
156 else{
157 if (node_coord.x>cell_coord.x)
158 nodes_indirection[CNP_PreviousRight] = i;
159 else
160 nodes_indirection[CNP_PreviousLeft] = i;
161 }
162 }
163 cellDirection(MD_DirY).setNodesIndirection(nodes_indirection);
164}
165
166/*---------------------------------------------------------------------------*/
167/*---------------------------------------------------------------------------*/
168/*
169 * \brief Calcule les infos sur les noeuds avant/après et gauche/droite d'une maille
170 * pour chaque direction.
171 */
172void CartesianMeshPatch::
173_computeNodeCellInformations3D(Cell cell0,Real3 cell0_coord,VariableNodeReal3& nodes_coord)
174{
175 using Int8 = std::int8_t;
176 Int8 nodes_indirection_i[CellDirectionMng::MAX_NB_NODE];
177 ArrayView<Int8> nodes_indirection(CellDirectionMng::MAX_NB_NODE,nodes_indirection_i);
178 Integer nb_node = cell0.nbNode();
179 if (nb_node!=8)
180 ARCANE_FATAL("Number of nodes should be '8' (v={0})",nb_node);
181 Int8 i8_nb_node = 8;
182 Real3 cell_coord = cell0_coord;
183 bool is_3d = m_mesh->mesh()->dimension()==3;
184 if (!is_3d)
185 ARCANE_FATAL("Invalid call. This mesh is not a 3D mesh");
186
187 // Direction X
188 nodes_indirection.fill(-1);
189 for( Int8 i=0; i<i8_nb_node; ++i ){
190 Node node = cell0.node(i);
191 Real3 node_coord = nodes_coord[node];
192 if (node_coord.z>cell_coord.z){
193 if (node_coord.x>cell_coord.x){
194 if (node_coord.y>cell_coord.y)
195 nodes_indirection[CNP_TopNextLeft] = i;
196 else
197 nodes_indirection[CNP_TopNextRight] = i;
198 }
199 else{
200 if (node_coord.y>cell_coord.y)
201 nodes_indirection[CNP_TopPreviousLeft] = i;
202 else
203 nodes_indirection[CNP_TopPreviousRight] = i;
204 }
205 }
206 else{
207 if (node_coord.x>cell_coord.x){
208 if (node_coord.y>cell_coord.y)
209 nodes_indirection[CNP_NextLeft] = i;
210 else
211 nodes_indirection[CNP_NextRight] = i;
212 }
213 else{
214 if (node_coord.y>cell_coord.y)
215 nodes_indirection[CNP_PreviousLeft] = i;
216 else
217 nodes_indirection[CNP_PreviousRight] = i;
218 }
219 }
220 }
221 cellDirection(MD_DirX).setNodesIndirection(nodes_indirection);
222
223 // Direction Y
224 nodes_indirection.fill(-1);
225 for( Int8 i=0; i<i8_nb_node; ++i ){
226 Node node = cell0.node(i);
227 Real3 node_coord = nodes_coord[node];
228 if (node_coord.z>cell_coord.z){
229 if (node_coord.y>cell_coord.y){
230 if (node_coord.x>cell_coord.x)
231 nodes_indirection[CNP_TopNextRight] = i;
232 else
233 nodes_indirection[CNP_TopNextLeft] = i;
234 }
235 else{
236 if (node_coord.x>cell_coord.x)
237 nodes_indirection[CNP_TopPreviousRight] = i;
238 else
239 nodes_indirection[CNP_TopPreviousLeft] = i;
240 }
241 }
242 else{
243 if (node_coord.y>cell_coord.y){
244 if (node_coord.x>cell_coord.x)
245 nodes_indirection[CNP_NextRight] = i;
246 else
247 nodes_indirection[CNP_NextLeft] = i;
248 }
249 else{
250 if (node_coord.x>cell_coord.x)
251 nodes_indirection[CNP_PreviousRight] = i;
252 else
253 nodes_indirection[CNP_PreviousLeft] = i;
254 }
255 }
256 }
257 cellDirection(MD_DirY).setNodesIndirection(nodes_indirection);
258
259 nodes_indirection.fill(-1);
260 for( Int8 i=0; i<i8_nb_node; ++i ){
261 Node node = cell0.node(i);
262 Real3 node_coord = nodes_coord[node];
263 if (node_coord.y>cell_coord.y){
264 if (node_coord.z>cell_coord.z){
265 if (node_coord.x>cell_coord.x)
266 nodes_indirection[CNP_TopNextRight] = i;
267 else
268 nodes_indirection[CNP_TopNextLeft] = i;
269 }
270 else{
271 if (node_coord.x>cell_coord.x)
272 nodes_indirection[CNP_TopPreviousRight] = i;
273 else
274 nodes_indirection[CNP_TopPreviousLeft] = i;
275 }
276 }
277 else{
278 if (node_coord.z>cell_coord.z){
279 if (node_coord.x>cell_coord.x)
280 nodes_indirection[CNP_NextRight] = i;
281 else
282 nodes_indirection[CNP_NextLeft] = i;
283 }
284 else{
285 if (node_coord.x>cell_coord.x)
286 nodes_indirection[CNP_PreviousRight] = i;
287 else
288 nodes_indirection[CNP_PreviousLeft] = i;
289 }
290 }
291 }
292 cellDirection(MD_DirZ).setNodesIndirection(nodes_indirection);
293}
294
295/*---------------------------------------------------------------------------*/
296/*---------------------------------------------------------------------------*/
297
298void CartesianMeshPatch::
299_internalComputeNodeCellInformations(Cell cell0,Real3 cell0_coord,VariableNodeReal3& nodes_coord)
300{
301 int dim = m_mesh->mesh()->dimension();
302 if (dim==3)
303 _computeNodeCellInformations3D(cell0,cell0_coord,nodes_coord);
304 else if (dim==2)
305 _computeNodeCellInformations2D(cell0,cell0_coord,nodes_coord);
306 else
307 ARCANE_THROW(NotImplementedException,"this method is implemented only for 2D and 3D mesh (dim={0})",dim);
308}
309
310/*---------------------------------------------------------------------------*/
311/*---------------------------------------------------------------------------*/
312
313void CartesianMeshPatch::
314_internalComputeNodeCellInformations()
315{
316 int dim = m_mesh->mesh()->dimension();
317 Int8 nodes_indirection[CellDirectionMng::MAX_NB_NODE];
318 ArrayView av_nodes_indirection(CellDirectionMng::MAX_NB_NODE, nodes_indirection);
319 // DirX (Top->Z=1 / Previous->X=0 / Next->X=1 / Right->Y=0 / Left->Y=1)
320 av_nodes_indirection.fill(-1);
321 av_nodes_indirection[CNP_NextLeft] = 2;
322 av_nodes_indirection[CNP_NextRight] = 1;
323 av_nodes_indirection[CNP_PreviousRight] = 0;
324 av_nodes_indirection[CNP_PreviousLeft] = 3;
325 if (dim == 3) {
326 av_nodes_indirection[CNP_TopNextLeft] = 6;
327 av_nodes_indirection[CNP_TopNextRight] = 5;
328 av_nodes_indirection[CNP_TopPreviousRight] = 4;
329 av_nodes_indirection[CNP_TopPreviousLeft] = 7;
330 }
331 cellDirection(MD_DirX).setNodesIndirection(av_nodes_indirection);
332
333 // DirY (Top->Z=1 / Previous->Y=0 / Next->Y=1 / Right->X=1 / Left->X=0)
334 av_nodes_indirection.fill(-1);
335 av_nodes_indirection[CNP_NextLeft] = 3;
336 av_nodes_indirection[CNP_NextRight] = 2;
337 av_nodes_indirection[CNP_PreviousRight] = 1;
338 av_nodes_indirection[CNP_PreviousLeft] = 0;
339 if (dim == 3) {
340 av_nodes_indirection[CNP_TopNextLeft] = 7;
341 av_nodes_indirection[CNP_TopNextRight] = 6;
342 av_nodes_indirection[CNP_TopPreviousRight] = 5;
343 av_nodes_indirection[CNP_TopPreviousLeft] = 4;
344 }
345 cellDirection(MD_DirY).setNodesIndirection(av_nodes_indirection);
346
347 if (dim == 3) {
348 // DirZ (Top->Y=1 / Previous->Z=0 / Next->Z=1 / Right->X=1 / Left->X=0)
349 av_nodes_indirection.fill(-1);
350 av_nodes_indirection[CNP_NextLeft] = 4;
351 av_nodes_indirection[CNP_NextRight] = 5;
352 av_nodes_indirection[CNP_PreviousRight] = 1;
353 av_nodes_indirection[CNP_PreviousLeft] = 0;
354 av_nodes_indirection[CNP_TopNextLeft] = 7;
355 av_nodes_indirection[CNP_TopNextRight] = 6;
356 av_nodes_indirection[CNP_TopPreviousRight] = 2;
357 av_nodes_indirection[CNP_TopPreviousLeft] = 3;
358 cellDirection(MD_DirZ).setNodesIndirection(av_nodes_indirection);
359 }
360}
361
362/*---------------------------------------------------------------------------*/
363/*---------------------------------------------------------------------------*/
364
365void CartesianMeshPatch::
366checkValid() const
367{
368 // Vérifie que toutes les mailles avant/après appartiennent au groupe de
369 // mailles de la direction
370 Integer nb_dir = m_mesh->mesh()->dimension();
371 for( Integer i=0; i<nb_dir; ++i ){
372 CellDirectionMng dm = m_cell_directions[i];
373 FaceDirectionMng face_dm = m_face_directions[i];
374 std::set<Int32> cells_ids;
375 CellGroup dm_cells = dm.allCells();
376 info(4) << "PATCH i=" << m_amr_patch_index << " nb_cell=" << dm_cells.size();
377 ENUMERATE_CELL(icell,dm_cells){
378 cells_ids.insert(icell.itemLocalId());
379 }
380 Int64 nb_null_face_cell = 0;
381 ENUMERATE_CELL(icell,dm_cells){
382 Cell cell = *icell;
383 DirCell cc(dm.cell(cell));
384 Cell next_cell = cc.next();
385 if (!next_cell.null()){
386 if (cells_ids.find(next_cell.localId())==cells_ids.end())
387 ARCANE_FATAL("Bad next cell dir={0} cell={1} next={2}",i,ItemPrinter(cell),ItemPrinter(next_cell));
388 }
389 Cell previous_cell = cc.previous();
390 if (!previous_cell.null()){
391 if (cells_ids.find(previous_cell.localId())==cells_ids.end())
392 ARCANE_FATAL("Bad previous cell dir={0} cell={1} previous={2}",i,ItemPrinter(cell),ItemPrinter(previous_cell));
393 }
394 // Regarde si les infos des faces sont valides
395
396 DirCellFace cell_face(dm.cellFace(cell));
397 Face prev_face = cell_face.previous();
398 Face next_face = cell_face.next();
399 DirFace dir_face_prev(face_dm[prev_face]);
400 Cell face_cell_prev = dir_face_prev.previousCell();
401 if (face_cell_prev.null())
402 ++nb_null_face_cell;
403 DirFace dir_face_next(face_dm[next_face]);
404 Cell face_cell_next = dir_face_next.nextCell();
405 if (face_cell_next.null())
406 ++nb_null_face_cell;
407 }
408 info(4) << "PATCH i=" << m_amr_patch_index << " nb_null_face_cell=" << nb_null_face_cell;
409 }
410}
411
412/*---------------------------------------------------------------------------*/
413/*---------------------------------------------------------------------------*/
414
415} // End namespace Arcane
416
417/*---------------------------------------------------------------------------*/
418/*---------------------------------------------------------------------------*/
#define ARCANE_THROW(exception_class,...)
Macro pour envoyer une exception avec formattage.
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
#define ENUMERATE_CELL(name, group)
Enumérateur générique d'un groupe de mailles.
Classe permettant de définir la position d'un patch dans le maillage cartésien.
Interface d'un maillage cartésien.
Integer size() const
Nombre d'éléments du groupe.
Definition ItemGroup.h:88
ItemGroupT< Cell > CellGroup
Groupe de mailles.
Definition ItemTypes.h:183
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
std::int8_t Int8
Type entier signé sur 8 bits.
Int32 Integer
Type représentant un entier.
eMeshDirection
Type de la direction pour un maillage structuré
@ Cell
Le maillage est AMR par maille.
Definition MeshKind.h:52