Arcane  v3.16.0.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-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)
35: TraceAccessor(cmesh->traceMng())
36, m_mesh(cmesh)
37, m_amr_patch_index(patch_index)
38, m_level(0)
39{
40 Integer nb_dir = cmesh->mesh()->dimension();
41 for( Integer i=0; i<nb_dir; ++i ){
42 eMeshDirection dir = static_cast<eMeshDirection>(i);
43 m_cell_directions[i]._internalInit(cmesh,dir,patch_index);
44 m_face_directions[i]._internalInit(cmesh,dir,patch_index);
45 m_node_directions[i]._internalInit(cmesh,dir,patch_index);
46 }
47}
48
49/*---------------------------------------------------------------------------*/
50/*---------------------------------------------------------------------------*/
51
52CartesianMeshPatch::
53~CartesianMeshPatch()
54{
55 for( Integer i=0; i<3; ++i ){
56 m_cell_directions[i]._internalDestroy();
57 m_face_directions[i]._internalDestroy();
58 m_node_directions[i]._internalDestroy();
59 }
60}
61
62/*---------------------------------------------------------------------------*/
63/*---------------------------------------------------------------------------*/
64
65/*---------------------------------------------------------------------------*/
66/*---------------------------------------------------------------------------*/
67
68CellGroup CartesianMeshPatch::
69cells()
70{
71 // Le groupe de mailles du patch est le même dans toutes les directions.
72 return cellDirection(MD_DirX).allCells();
73}
74
75/*---------------------------------------------------------------------------*/
76/*---------------------------------------------------------------------------*/
77/*
78 * \brief Calcule les infos sur les noeuds avant/après et gauche/droite d'une maille
79 * pour chaque direction.
80 */
81void CartesianMeshPatch::
82_computeNodeCellInformations2D(Cell cell0,Real3 cell0_coord,VariableNodeReal3& nodes_coord)
83{
84 using Int8 = std::int8_t;
85 Int8 nodes_indirection_i[CellDirectionMng::MAX_NB_NODE];
86 ArrayView<Int8> nodes_indirection(CellDirectionMng::MAX_NB_NODE,nodes_indirection_i);
87 Int32 nb_node = cell0.nbNode();
88 if (nb_node!=4)
89 ARCANE_FATAL("Number of nodes should be '4' (v={0})",nb_node);
90 Int8 i8_nb_node = 4;
91 Real3 cell_coord = cell0_coord;
92 bool is_2d = m_mesh->mesh()->dimension()==2;
93 if (!is_2d)
94 ARCANE_FATAL("Invalid call. This mesh is not a 2D mesh");
95
96 // Direction X
97 nodes_indirection.fill(-1);
98 for( Int8 i=0; i<i8_nb_node; ++i ){
99 Node node = cell0.node(i);
100 Real3 node_coord = nodes_coord[node];
101 if (node_coord.x>cell_coord.x){
102 if (node_coord.y>cell_coord.y)
103 nodes_indirection[CNP_NextLeft] = i;
104 else
105 nodes_indirection[CNP_NextRight] = i;
106 }
107 else{
108 if (node_coord.y>cell_coord.y)
109 nodes_indirection[CNP_PreviousLeft] = i;
110 else
111 nodes_indirection[CNP_PreviousRight] = i;
112 }
113 }
114 cellDirection(MD_DirX).setNodesIndirection(nodes_indirection);
115
116 // Direction Y
117 nodes_indirection.fill(-1);
118 for( Int8 i=0; i<i8_nb_node; ++i ){
119 Node node = cell0.node(i);
120 Real3 node_coord = nodes_coord[node];
121 if (node_coord.y>cell_coord.y){
122 if (node_coord.x>cell_coord.x)
123 nodes_indirection[CNP_NextRight] = i;
124 else
125 nodes_indirection[CNP_NextLeft] = i;
126 }
127 else{
128 if (node_coord.x>cell_coord.x)
129 nodes_indirection[CNP_PreviousRight] = i;
130 else
131 nodes_indirection[CNP_PreviousLeft] = i;
132 }
133 }
134 cellDirection(MD_DirY).setNodesIndirection(nodes_indirection);
135}
136
137/*---------------------------------------------------------------------------*/
138/*---------------------------------------------------------------------------*/
139/*
140 * \brief Calcule les infos sur les noeuds avant/après et gauche/droite d'une maille
141 * pour chaque direction.
142 */
143void CartesianMeshPatch::
144_computeNodeCellInformations3D(Cell cell0,Real3 cell0_coord,VariableNodeReal3& nodes_coord)
145{
146 using Int8 = std::int8_t;
147 Int8 nodes_indirection_i[CellDirectionMng::MAX_NB_NODE];
148 ArrayView<Int8> nodes_indirection(CellDirectionMng::MAX_NB_NODE,nodes_indirection_i);
149 Integer nb_node = cell0.nbNode();
150 if (nb_node!=8)
151 ARCANE_FATAL("Number of nodes should be '8' (v={0})",nb_node);
152 Int8 i8_nb_node = 8;
153 Real3 cell_coord = cell0_coord;
154 bool is_3d = m_mesh->mesh()->dimension()==3;
155 if (!is_3d)
156 ARCANE_FATAL("Invalid call. This mesh is not a 3D mesh");
157
158 // Direction X
159 nodes_indirection.fill(-1);
160 for( Int8 i=0; i<i8_nb_node; ++i ){
161 Node node = cell0.node(i);
162 Real3 node_coord = nodes_coord[node];
163 if (node_coord.z>cell_coord.z){
164 if (node_coord.x>cell_coord.x){
165 if (node_coord.y>cell_coord.y)
166 nodes_indirection[CNP_TopNextLeft] = i;
167 else
168 nodes_indirection[CNP_TopNextRight] = i;
169 }
170 else{
171 if (node_coord.y>cell_coord.y)
172 nodes_indirection[CNP_TopPreviousLeft] = i;
173 else
174 nodes_indirection[CNP_TopPreviousRight] = i;
175 }
176 }
177 else{
178 if (node_coord.x>cell_coord.x){
179 if (node_coord.y>cell_coord.y)
180 nodes_indirection[CNP_NextLeft] = i;
181 else
182 nodes_indirection[CNP_NextRight] = i;
183 }
184 else{
185 if (node_coord.y>cell_coord.y)
186 nodes_indirection[CNP_PreviousLeft] = i;
187 else
188 nodes_indirection[CNP_PreviousRight] = i;
189 }
190 }
191 }
192 cellDirection(MD_DirX).setNodesIndirection(nodes_indirection);
193
194 // Direction Y
195 nodes_indirection.fill(-1);
196 for( Int8 i=0; i<i8_nb_node; ++i ){
197 Node node = cell0.node(i);
198 Real3 node_coord = nodes_coord[node];
199 if (node_coord.z>cell_coord.z){
200 if (node_coord.y>cell_coord.y){
201 if (node_coord.x>cell_coord.x)
202 nodes_indirection[CNP_TopNextRight] = i;
203 else
204 nodes_indirection[CNP_TopNextLeft] = i;
205 }
206 else{
207 if (node_coord.x>cell_coord.x)
208 nodes_indirection[CNP_TopPreviousRight] = i;
209 else
210 nodes_indirection[CNP_TopPreviousLeft] = i;
211 }
212 }
213 else{
214 if (node_coord.y>cell_coord.y){
215 if (node_coord.x>cell_coord.x)
216 nodes_indirection[CNP_NextRight] = i;
217 else
218 nodes_indirection[CNP_NextLeft] = i;
219 }
220 else{
221 if (node_coord.x>cell_coord.x)
222 nodes_indirection[CNP_PreviousRight] = i;
223 else
224 nodes_indirection[CNP_PreviousLeft] = i;
225 }
226 }
227 }
228 cellDirection(MD_DirY).setNodesIndirection(nodes_indirection);
229
230 nodes_indirection.fill(-1);
231 for( Int8 i=0; i<i8_nb_node; ++i ){
232 Node node = cell0.node(i);
233 Real3 node_coord = nodes_coord[node];
234 if (node_coord.y>cell_coord.y){
235 if (node_coord.z>cell_coord.z){
236 if (node_coord.x>cell_coord.x)
237 nodes_indirection[CNP_TopNextRight] = i;
238 else
239 nodes_indirection[CNP_TopNextLeft] = i;
240 }
241 else{
242 if (node_coord.x>cell_coord.x)
243 nodes_indirection[CNP_TopPreviousRight] = i;
244 else
245 nodes_indirection[CNP_TopPreviousLeft] = i;
246 }
247 }
248 else{
249 if (node_coord.z>cell_coord.z){
250 if (node_coord.x>cell_coord.x)
251 nodes_indirection[CNP_NextRight] = i;
252 else
253 nodes_indirection[CNP_NextLeft] = i;
254 }
255 else{
256 if (node_coord.x>cell_coord.x)
257 nodes_indirection[CNP_PreviousRight] = i;
258 else
259 nodes_indirection[CNP_PreviousLeft] = i;
260 }
261 }
262 }
263 cellDirection(MD_DirZ).setNodesIndirection(nodes_indirection);
264}
265
266/*---------------------------------------------------------------------------*/
267/*---------------------------------------------------------------------------*/
268
269void CartesianMeshPatch::
270_internalComputeNodeCellInformations(Cell cell0,Real3 cell0_coord,VariableNodeReal3& nodes_coord)
271{
272 int dim = m_mesh->mesh()->dimension();
273 if (dim==3)
274 _computeNodeCellInformations3D(cell0,cell0_coord,nodes_coord);
275 else if (dim==2)
276 _computeNodeCellInformations2D(cell0,cell0_coord,nodes_coord);
277 else
278 ARCANE_THROW(NotImplementedException,"this method is implemented only for 2D and 3D mesh (dim={0})",dim);
279}
280
281/*---------------------------------------------------------------------------*/
282/*---------------------------------------------------------------------------*/
283
284void CartesianMeshPatch::
285checkValid() const
286{
287 // Vérifie que toutes les mailles avant/après appartiennent au groupe de
288 // mailles de la direction
289 Integer nb_dir = m_mesh->mesh()->dimension();
290 for( Integer i=0; i<nb_dir; ++i ){
291 CellDirectionMng dm = m_cell_directions[i];
292 FaceDirectionMng face_dm = m_face_directions[i];
293 std::set<Int32> cells_ids;
294 CellGroup dm_cells = dm.allCells();
295 info(4) << "PATCH i=" << m_amr_patch_index << " nb_cell=" << dm_cells.size();
296 ENUMERATE_CELL(icell,dm_cells){
297 cells_ids.insert(icell.itemLocalId());
298 }
299 Int64 nb_null_face_cell = 0;
300 ENUMERATE_CELL(icell,dm_cells){
301 Cell cell = *icell;
302 DirCell cc(dm.cell(cell));
303 Cell next_cell = cc.next();
304 if (!next_cell.null()){
305 if (cells_ids.find(next_cell.localId())==cells_ids.end())
306 ARCANE_FATAL("Bad next cell dir={0} cell={1} next={2}",i,ItemPrinter(cell),ItemPrinter(next_cell));
307 }
308 Cell previous_cell = cc.previous();
309 if (!previous_cell.null()){
310 if (cells_ids.find(previous_cell.localId())==cells_ids.end())
311 ARCANE_FATAL("Bad previous cell dir={0} cell={1} previous={2}",i,ItemPrinter(cell),ItemPrinter(previous_cell));
312 }
313 // Regarde si les infos des faces sont valides
314
315 DirCellFace cell_face(dm.cellFace(cell));
316 Face prev_face = cell_face.previous();
317 Face next_face = cell_face.next();
318 DirFace dir_face_prev(face_dm[prev_face]);
319 Cell face_cell_prev = dir_face_prev.previousCell();
320 if (face_cell_prev.null())
321 ++nb_null_face_cell;
322 DirFace dir_face_next(face_dm[next_face]);
323 Cell face_cell_next = dir_face_next.nextCell();
324 if (face_cell_next.null())
325 ++nb_null_face_cell;
326 }
327 info(4) << "PATCH i=" << m_amr_patch_index << " nb_null_face_cell=" << nb_null_face_cell;
328 }
329}
330
331/*---------------------------------------------------------------------------*/
332/*---------------------------------------------------------------------------*/
333
334} // End namespace Arcane
335
336/*---------------------------------------------------------------------------*/
337/*---------------------------------------------------------------------------*/
#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.
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é