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