Arcane  v4.1.2.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
CartesianMeshPatch.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/* CartesianMeshPatch.cc (C) 2000-2025 */
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/*
97 * \brief Calcule les infos sur les noeuds avant/après et gauche/droite d'une maille
98 * pour chaque direction.
99 */
100void CartesianMeshPatch::
101_computeNodeCellInformations2D(Cell cell0,Real3 cell0_coord,VariableNodeReal3& nodes_coord)
102{
103 using Int8 = std::int8_t;
104 Int8 nodes_indirection_i[CellDirectionMng::MAX_NB_NODE];
105 ArrayView<Int8> nodes_indirection(CellDirectionMng::MAX_NB_NODE,nodes_indirection_i);
106 Int32 nb_node = cell0.nbNode();
107 if (nb_node!=4)
108 ARCANE_FATAL("Number of nodes should be '4' (v={0})",nb_node);
109 Int8 i8_nb_node = 4;
110 Real3 cell_coord = cell0_coord;
111 bool is_2d = m_mesh->mesh()->dimension()==2;
112 if (!is_2d)
113 ARCANE_FATAL("Invalid call. This mesh is not a 2D mesh");
114
115 // Direction X
116 nodes_indirection.fill(-1);
117 for( Int8 i=0; i<i8_nb_node; ++i ){
118 Node node = cell0.node(i);
119 Real3 node_coord = nodes_coord[node];
120 if (node_coord.x>cell_coord.x){
121 if (node_coord.y>cell_coord.y)
122 nodes_indirection[CNP_NextLeft] = i;
123 else
124 nodes_indirection[CNP_NextRight] = i;
125 }
126 else{
127 if (node_coord.y>cell_coord.y)
128 nodes_indirection[CNP_PreviousLeft] = i;
129 else
130 nodes_indirection[CNP_PreviousRight] = i;
131 }
132 }
133 cellDirection(MD_DirX).setNodesIndirection(nodes_indirection);
134
135 // Direction Y
136 nodes_indirection.fill(-1);
137 for( Int8 i=0; i<i8_nb_node; ++i ){
138 Node node = cell0.node(i);
139 Real3 node_coord = nodes_coord[node];
140 if (node_coord.y>cell_coord.y){
141 if (node_coord.x>cell_coord.x)
142 nodes_indirection[CNP_NextRight] = i;
143 else
144 nodes_indirection[CNP_NextLeft] = i;
145 }
146 else{
147 if (node_coord.x>cell_coord.x)
148 nodes_indirection[CNP_PreviousRight] = i;
149 else
150 nodes_indirection[CNP_PreviousLeft] = i;
151 }
152 }
153 cellDirection(MD_DirY).setNodesIndirection(nodes_indirection);
154}
155
156/*---------------------------------------------------------------------------*/
157/*---------------------------------------------------------------------------*/
158/*
159 * \brief Calcule les infos sur les noeuds avant/après et gauche/droite d'une maille
160 * pour chaque direction.
161 */
162void CartesianMeshPatch::
163_computeNodeCellInformations3D(Cell cell0,Real3 cell0_coord,VariableNodeReal3& nodes_coord)
164{
165 using Int8 = std::int8_t;
166 Int8 nodes_indirection_i[CellDirectionMng::MAX_NB_NODE];
167 ArrayView<Int8> nodes_indirection(CellDirectionMng::MAX_NB_NODE,nodes_indirection_i);
168 Integer nb_node = cell0.nbNode();
169 if (nb_node!=8)
170 ARCANE_FATAL("Number of nodes should be '8' (v={0})",nb_node);
171 Int8 i8_nb_node = 8;
172 Real3 cell_coord = cell0_coord;
173 bool is_3d = m_mesh->mesh()->dimension()==3;
174 if (!is_3d)
175 ARCANE_FATAL("Invalid call. This mesh is not a 3D mesh");
176
177 // Direction X
178 nodes_indirection.fill(-1);
179 for( Int8 i=0; i<i8_nb_node; ++i ){
180 Node node = cell0.node(i);
181 Real3 node_coord = nodes_coord[node];
182 if (node_coord.z>cell_coord.z){
183 if (node_coord.x>cell_coord.x){
184 if (node_coord.y>cell_coord.y)
185 nodes_indirection[CNP_TopNextLeft] = i;
186 else
187 nodes_indirection[CNP_TopNextRight] = i;
188 }
189 else{
190 if (node_coord.y>cell_coord.y)
191 nodes_indirection[CNP_TopPreviousLeft] = i;
192 else
193 nodes_indirection[CNP_TopPreviousRight] = i;
194 }
195 }
196 else{
197 if (node_coord.x>cell_coord.x){
198 if (node_coord.y>cell_coord.y)
199 nodes_indirection[CNP_NextLeft] = i;
200 else
201 nodes_indirection[CNP_NextRight] = i;
202 }
203 else{
204 if (node_coord.y>cell_coord.y)
205 nodes_indirection[CNP_PreviousLeft] = i;
206 else
207 nodes_indirection[CNP_PreviousRight] = i;
208 }
209 }
210 }
211 cellDirection(MD_DirX).setNodesIndirection(nodes_indirection);
212
213 // Direction Y
214 nodes_indirection.fill(-1);
215 for( Int8 i=0; i<i8_nb_node; ++i ){
216 Node node = cell0.node(i);
217 Real3 node_coord = nodes_coord[node];
218 if (node_coord.z>cell_coord.z){
219 if (node_coord.y>cell_coord.y){
220 if (node_coord.x>cell_coord.x)
221 nodes_indirection[CNP_TopNextRight] = i;
222 else
223 nodes_indirection[CNP_TopNextLeft] = i;
224 }
225 else{
226 if (node_coord.x>cell_coord.x)
227 nodes_indirection[CNP_TopPreviousRight] = i;
228 else
229 nodes_indirection[CNP_TopPreviousLeft] = i;
230 }
231 }
232 else{
233 if (node_coord.y>cell_coord.y){
234 if (node_coord.x>cell_coord.x)
235 nodes_indirection[CNP_NextRight] = i;
236 else
237 nodes_indirection[CNP_NextLeft] = i;
238 }
239 else{
240 if (node_coord.x>cell_coord.x)
241 nodes_indirection[CNP_PreviousRight] = i;
242 else
243 nodes_indirection[CNP_PreviousLeft] = i;
244 }
245 }
246 }
247 cellDirection(MD_DirY).setNodesIndirection(nodes_indirection);
248
249 nodes_indirection.fill(-1);
250 for( Int8 i=0; i<i8_nb_node; ++i ){
251 Node node = cell0.node(i);
252 Real3 node_coord = nodes_coord[node];
253 if (node_coord.y>cell_coord.y){
254 if (node_coord.z>cell_coord.z){
255 if (node_coord.x>cell_coord.x)
256 nodes_indirection[CNP_TopNextRight] = i;
257 else
258 nodes_indirection[CNP_TopNextLeft] = i;
259 }
260 else{
261 if (node_coord.x>cell_coord.x)
262 nodes_indirection[CNP_TopPreviousRight] = i;
263 else
264 nodes_indirection[CNP_TopPreviousLeft] = i;
265 }
266 }
267 else{
268 if (node_coord.z>cell_coord.z){
269 if (node_coord.x>cell_coord.x)
270 nodes_indirection[CNP_NextRight] = i;
271 else
272 nodes_indirection[CNP_NextLeft] = i;
273 }
274 else{
275 if (node_coord.x>cell_coord.x)
276 nodes_indirection[CNP_PreviousRight] = i;
277 else
278 nodes_indirection[CNP_PreviousLeft] = i;
279 }
280 }
281 }
282 cellDirection(MD_DirZ).setNodesIndirection(nodes_indirection);
283}
284
285/*---------------------------------------------------------------------------*/
286/*---------------------------------------------------------------------------*/
287
288void CartesianMeshPatch::
289_internalComputeNodeCellInformations(Cell cell0,Real3 cell0_coord,VariableNodeReal3& nodes_coord)
290{
291 int dim = m_mesh->mesh()->dimension();
292 if (dim==3)
293 _computeNodeCellInformations3D(cell0,cell0_coord,nodes_coord);
294 else if (dim==2)
295 _computeNodeCellInformations2D(cell0,cell0_coord,nodes_coord);
296 else
297 ARCANE_THROW(NotImplementedException,"this method is implemented only for 2D and 3D mesh (dim={0})",dim);
298}
299
300/*---------------------------------------------------------------------------*/
301/*---------------------------------------------------------------------------*/
302
303void CartesianMeshPatch::
304_internalComputeNodeCellInformations()
305{
306 int dim = m_mesh->mesh()->dimension();
307 Int8 nodes_indirection[CellDirectionMng::MAX_NB_NODE];
308 ArrayView av_nodes_indirection(CellDirectionMng::MAX_NB_NODE, nodes_indirection);
309 // DirX (Top->Z=1 / Previous->X=0 / Next->X=1 / Right->Y=0 / Left->Y=1)
310 av_nodes_indirection.fill(-1);
311 av_nodes_indirection[CNP_NextLeft] = 2;
312 av_nodes_indirection[CNP_NextRight] = 1;
313 av_nodes_indirection[CNP_PreviousRight] = 0;
314 av_nodes_indirection[CNP_PreviousLeft] = 3;
315 if (dim == 3) {
316 av_nodes_indirection[CNP_TopNextLeft] = 6;
317 av_nodes_indirection[CNP_TopNextRight] = 5;
318 av_nodes_indirection[CNP_TopPreviousRight] = 4;
319 av_nodes_indirection[CNP_TopPreviousLeft] = 7;
320 }
321 cellDirection(MD_DirX).setNodesIndirection(av_nodes_indirection);
322
323 // DirY (Top->Z=1 / Previous->Y=0 / Next->Y=1 / Right->X=1 / Left->X=0)
324 av_nodes_indirection.fill(-1);
325 av_nodes_indirection[CNP_NextLeft] = 3;
326 av_nodes_indirection[CNP_NextRight] = 2;
327 av_nodes_indirection[CNP_PreviousRight] = 1;
328 av_nodes_indirection[CNP_PreviousLeft] = 0;
329 if (dim == 3) {
330 av_nodes_indirection[CNP_TopNextLeft] = 7;
331 av_nodes_indirection[CNP_TopNextRight] = 6;
332 av_nodes_indirection[CNP_TopPreviousRight] = 5;
333 av_nodes_indirection[CNP_TopPreviousLeft] = 4;
334 }
335 cellDirection(MD_DirY).setNodesIndirection(av_nodes_indirection);
336
337 if (dim == 3) {
338 // DirZ (Top->Y=1 / Previous->Z=0 / Next->Z=1 / Right->X=1 / Left->X=0)
339 av_nodes_indirection.fill(-1);
340 av_nodes_indirection[CNP_NextLeft] = 4;
341 av_nodes_indirection[CNP_NextRight] = 5;
342 av_nodes_indirection[CNP_PreviousRight] = 1;
343 av_nodes_indirection[CNP_PreviousLeft] = 0;
344 av_nodes_indirection[CNP_TopNextLeft] = 7;
345 av_nodes_indirection[CNP_TopNextRight] = 6;
346 av_nodes_indirection[CNP_TopPreviousRight] = 2;
347 av_nodes_indirection[CNP_TopPreviousLeft] = 3;
348 cellDirection(MD_DirZ).setNodesIndirection(av_nodes_indirection);
349 }
350}
351
352/*---------------------------------------------------------------------------*/
353/*---------------------------------------------------------------------------*/
354
355void CartesianMeshPatch::
356checkValid() const
357{
358 // Vérifie que toutes les mailles avant/après appartiennent au groupe de
359 // mailles de la direction
360 Integer nb_dir = m_mesh->mesh()->dimension();
361 for( Integer i=0; i<nb_dir; ++i ){
362 CellDirectionMng dm = m_cell_directions[i];
363 FaceDirectionMng face_dm = m_face_directions[i];
364 std::set<Int32> cells_ids;
365 CellGroup dm_cells = dm.allCells();
366 info(4) << "PATCH i=" << m_amr_patch_index << " nb_cell=" << dm_cells.size();
367 ENUMERATE_CELL(icell,dm_cells){
368 cells_ids.insert(icell.itemLocalId());
369 }
370 Int64 nb_null_face_cell = 0;
371 ENUMERATE_CELL(icell,dm_cells){
372 Cell cell = *icell;
373 DirCell cc(dm.cell(cell));
374 Cell next_cell = cc.next();
375 if (!next_cell.null()){
376 if (cells_ids.find(next_cell.localId())==cells_ids.end())
377 ARCANE_FATAL("Bad next cell dir={0} cell={1} next={2}",i,ItemPrinter(cell),ItemPrinter(next_cell));
378 }
379 Cell previous_cell = cc.previous();
380 if (!previous_cell.null()){
381 if (cells_ids.find(previous_cell.localId())==cells_ids.end())
382 ARCANE_FATAL("Bad previous cell dir={0} cell={1} previous={2}",i,ItemPrinter(cell),ItemPrinter(previous_cell));
383 }
384 // Regarde si les infos des faces sont valides
385
386 DirCellFace cell_face(dm.cellFace(cell));
387 Face prev_face = cell_face.previous();
388 Face next_face = cell_face.next();
389 DirFace dir_face_prev(face_dm[prev_face]);
390 Cell face_cell_prev = dir_face_prev.previousCell();
391 if (face_cell_prev.null())
392 ++nb_null_face_cell;
393 DirFace dir_face_next(face_dm[next_face]);
394 Cell face_cell_next = dir_face_next.nextCell();
395 if (face_cell_next.null())
396 ++nb_null_face_cell;
397 }
398 info(4) << "PATCH i=" << m_amr_patch_index << " nb_null_face_cell=" << nb_null_face_cell;
399 }
400}
401
402/*---------------------------------------------------------------------------*/
403/*---------------------------------------------------------------------------*/
404
405} // End namespace Arcane
406
407/*---------------------------------------------------------------------------*/
408/*---------------------------------------------------------------------------*/
#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.
CellDirectionMng & cellDirection(eMeshDirection dir) override
Liste des mailles dans la direction dir.
Infos sur les mailles d'une direction spécifique X,Y ou Z d'un maillage structuré.
CellGroup allCells() const
Groupe de toutes les mailles dans la direction.
DirCellFace cellFace(Cell c) const
Maille avec infos directionnelles aux faces correspondant à la maille c.
DirCell cell(Cell c) const
Maille direction correspondant à la maille c.
Maille d'un maillage.
Definition Item.h:1214
Maille avec info directionnelle des faces.
Face next() const
Face connectée à la maille d'après la maille courante dans la direction.
Face previous() const
Face connectée à la maille d'avant la maille courante dans la direction.
Maille avant et après une maille suivant une direction.
Infos sur maille avant et après une face suivant une direction.
Infos sur les face d'une direction spécifique X,Y ou Z d'un maillage structuré.
Face d'une maille.
Definition Item.h:964
Interface d'un maillage cartésien.
Integer size() const
Nombre d'éléments du groupe.
Definition ItemGroup.h:88
Classe utilitaire pour imprimer les infos sur une entité.
Definition ItemPrinter.h:34
constexpr Int32 localId() const
Identifiant local de l'entité dans le sous-domaine du processeur.
Definition Item.h:219
constexpr bool null() const
true si l'entité est nul (i.e. non connecté au maillage)
Definition Item.h:216
TraceMessage info() const
Flot pour un message d'information.
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.
std::int64_t Int64
Type entier signé sur 64 bits.
Int32 Integer
Type représentant un entier.
eMeshDirection
Type de la direction pour un maillage structuré
@ MD_DirX
Direction X.