Arcane  v3.14.10.0
Documentation utilisateur
Chargement...
Recherche...
Aucune correspondance
FaceDirectionMng.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2023 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/* FaceDirectionMng.cc (C) 2000-2023 */
9/* */
10/* Infos sur les faces d'une direction X Y ou Z d'un maillage structuré. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/cartesianmesh/FaceDirectionMng.h"
15
16#include "arcane/utils/FatalErrorException.h"
17#include "arcane/utils/Real3.h"
18#include "arcane/utils/PlatformUtils.h"
19
20#include "arcane/IItemFamily.h"
21#include "arcane/ItemGroup.h"
22#include "arcane/IMesh.h"
23#include "arcane/VariableTypes.h"
24
25#include "arcane/cartesianmesh/ICartesianMesh.h"
26#include "arcane/cartesianmesh/CellDirectionMng.h"
27
28#include <set>
29
30/*---------------------------------------------------------------------------*/
31/*---------------------------------------------------------------------------*/
32
33namespace Arcane
34{
35
36/*---------------------------------------------------------------------------*/
37/*---------------------------------------------------------------------------*/
38
40{
41 public:
43 public:
44 FaceGroup m_inner_all_items;
45 FaceGroup m_outer_all_items;
46 FaceGroup m_all_items;
47 ICartesianMesh* m_cartesian_mesh = nullptr;
48 Integer m_patch_index = -1;
50};
51
52/*---------------------------------------------------------------------------*/
53/*---------------------------------------------------------------------------*/
54
57: m_direction(MD_DirInvalid)
58, m_p (nullptr)
59{
60}
61
62/*---------------------------------------------------------------------------*/
63/*---------------------------------------------------------------------------*/
64
65void FaceDirectionMng::
66_internalInit(ICartesianMesh* cm,eMeshDirection dir,Integer patch_index)
67{
68 if (m_p)
69 ARCANE_FATAL("Initialisation already done");
70 m_p = new Impl();
71 m_direction = dir;
72 m_p->m_cartesian_mesh = cm;
73 m_p->m_patch_index = patch_index;
74}
75
76/*---------------------------------------------------------------------------*/
77/*---------------------------------------------------------------------------*/
78
79void FaceDirectionMng::
80_internalDestroy()
81{
82 delete m_p;
83 m_p = nullptr;
84}
85
86/*---------------------------------------------------------------------------*/
87/*---------------------------------------------------------------------------*/
88
89void FaceDirectionMng::
90_internalResizeInfos(Int32 new_size)
91{
92 m_p->m_infos.resize(new_size);
93 m_infos_view = m_p->m_infos.view();
94}
95
96/*---------------------------------------------------------------------------*/
97/*---------------------------------------------------------------------------*/
98
99void FaceDirectionMng::
100_internalComputeInfos(const CellDirectionMng& cell_dm,const VariableCellReal3& cells_center,
101 const VariableFaceReal3& faces_center)
102{
103 IMesh* mesh = m_p->m_cartesian_mesh->mesh();
104 IItemFamily* face_family = mesh->faceFamily();
105 IItemFamily* cell_family = mesh->cellFamily();
106 int dir = (int)m_direction;
107 String base_group_name = String("Direction")+dir;
108 if (m_p->m_patch_index>=0)
109 base_group_name = base_group_name + String("AMRPatch")+m_p->m_patch_index;
110
111 // Calcule la liste des faces dans une direction donnée.
112 // Il faut pour chaque maille ajouter dans la liste des faces
113 // les deux faces de la direction souhaitées en prenant bien soin
114 // de ne pas ajouter deux fois la même face.
115 UniqueArray<Int32> faces_lid;
116 {
117 CellGroup all_cells = cell_dm.allCells();
118 faces_lid.reserve(all_cells.size());
119 // Ensemble des faces déjà ajoutées
120 std::set<Int32> done_faces;
121 ENUMERATE_CELL(icell,all_cells){
122 DirCellFace dcf(cell_dm.cellFace(*icell));
123 Face next_face = dcf.next();
124 Face prev_face = dcf.previous();
125
126 //! Ajoute la face d'avant à la liste des faces de cette direction
127 Int32 prev_lid = prev_face.localId();
128 if (done_faces.find(prev_lid)==done_faces.end()){
129 faces_lid.add(prev_lid);
130 done_faces.insert(prev_lid);
131 }
132 Int32 next_lid = next_face.localId();
133 if (done_faces.find(next_lid)==done_faces.end()){
134 faces_lid.add(next_lid);
135 done_faces.insert(next_lid);
136 }
137 }
138 }
139
140 FaceGroup all_faces = face_family->createGroup(String("AllFaces")+base_group_name,Int32ConstArrayView(),true);
141 all_faces.setItems(faces_lid,true);
142
143 UniqueArray<Int32> inner_lids;
144 UniqueArray<Int32> outer_lids;
145 ENUMERATE_FACE(iitem,all_faces){
146 Int32 lid = iitem.itemLocalId();
147 Face face = *iitem;
148 // TODO: ne pas utiser nbCell() mais faire cela via le std::set utilisé précédemment
149 if (face.nbCell()==1)
150 outer_lids.add(lid);
151 else
152 inner_lids.add(lid);
153 }
154 m_p->m_inner_all_items = face_family->createGroup(String("AllInner")+base_group_name,inner_lids,true);
155 m_p->m_outer_all_items = face_family->createGroup(String("AllOuter")+base_group_name,outer_lids,true);
156 m_p->m_all_items = all_faces;
157 m_cells = CellInfoListView(cell_family);
158
159 _computeCellInfos(cell_dm,cells_center,faces_center);
160}
161
162/*---------------------------------------------------------------------------*/
163/*---------------------------------------------------------------------------*/
164
165bool FaceDirectionMng::
166_hasFace(Cell cell,Int32 face_local_id) const
167{
168 for( FaceLocalId iface_lid : cell.faceIds() ){
169 if (iface_lid==face_local_id)
170 return true;
171 }
172 return false;
173}
174
175/*---------------------------------------------------------------------------*/
176/*---------------------------------------------------------------------------*/
177/*!
178 * \brief Calcule des mailles avant et après une face, dans une direction donnée.
179 *
180 * Pour être indépendant de la façon dont est créé le maillage, on utilise les coordonnées
181 * des centres des faces et des centres des mailles.
182 */
183void FaceDirectionMng::
184_computeCellInfos(const CellDirectionMng& cell_dm,const VariableCellReal3& cells_center,
185 const VariableFaceReal3& faces_center)
186{
187 eMeshDirection dir = m_direction;
188
189 // Créé l'ensemble des mailles du patch et s'en sert
190 // pour être sur que chaque maille devant/derrière est dans
191 // cet ensemble
192 std::set<Int32> patch_cells_set;
193 ENUMERATE_CELL(icell,cell_dm.allCells()){
194 patch_cells_set.insert(icell.itemLocalId());
195 }
196
197 ENUMERATE_FACE(iface,m_p->m_all_items){
198 Face face = *iface;
199 Int32 face_lid = iface.itemLocalId();
200 Real3 face_coord = faces_center[iface];
201 Cell front_cell = face.frontCell();
202 Cell back_cell = face.backCell();
203
204 // Vérifie que les mailles sont dans notre patch.
205 if (!front_cell.null())
206 if (patch_cells_set.find(front_cell.localId())==patch_cells_set.end())
207 front_cell = Cell();
208 if (!back_cell.null())
209 if (patch_cells_set.find(back_cell.localId())==patch_cells_set.end())
210 back_cell = Cell();
211
212 bool is_inverse = false;
213 if (!front_cell.null()){
214 Real3 front_coord = cells_center[front_cell];
215 if (dir==MD_DirX){
216 if (front_coord.x<face_coord.x)
217 is_inverse = true;
218 }
219 else if (dir==MD_DirY){
220 if (front_coord.y<face_coord.y)
221 is_inverse = true;
222 }
223 else if (dir==MD_DirZ){
224 if (front_coord.z<face_coord.z)
225 is_inverse = true;
226 }
227 }
228 else{
229 Real3 back_coord = cells_center[back_cell];
230 if (dir==MD_DirX){
231 if (back_coord.x>face_coord.x)
232 is_inverse = true;
233 }
234 else if (dir==MD_DirY){
235 if (back_coord.y>face_coord.y)
236 is_inverse = true;
237 }
238 else if (dir==MD_DirZ){
239 if (back_coord.z>face_coord.z)
240 is_inverse = true;
241 }
242 }
243 // Si la face a deux mailles connectées, regarde le niveau AMR de ces
244 // deux mailles et s'il est différent, ne conserve que la maille
245 // dont le niveau AMR est celui de la face.
246 if (!back_cell.null() && !front_cell.null()){
247 Int32 back_level = back_cell.level();
248 Int32 front_level = front_cell.level();
249 if (back_level!=front_level){
250 // La face n'a pas l'information de son niveau mais si les deux
251 // mailles ne sont pas de même niveau la face n'appartient qu'à une
252 // seule des deux mailles. On ne garde donc que cette dernière.
253 if (!_hasFace(back_cell,face_lid))
254 back_cell = Cell();
255 if (!_hasFace(front_cell,face_lid))
256 front_cell = Cell();
257 }
258 }
259 if (is_inverse)
260 m_infos_view[face_lid] = ItemDirectionInfo(back_cell,front_cell);
261 else
262 m_infos_view[face_lid] = ItemDirectionInfo(front_cell,back_cell);
263 }
264}
265
266/*---------------------------------------------------------------------------*/
267/*---------------------------------------------------------------------------*/
268
270allFaces() const
271{
272 return m_p->m_all_items;
273}
274
275/*---------------------------------------------------------------------------*/
276/*---------------------------------------------------------------------------*/
277
279innerFaces() const
280{
281 return m_p->m_inner_all_items;
282}
283
284/*---------------------------------------------------------------------------*/
285/*---------------------------------------------------------------------------*/
286
288outerFaces() const
289{
290 return m_p->m_outer_all_items;
291}
292
293/*---------------------------------------------------------------------------*/
294/*---------------------------------------------------------------------------*/
295
296} // End namespace Arcane
297
298/*---------------------------------------------------------------------------*/
299/*---------------------------------------------------------------------------*/
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
#define ENUMERATE_FACE(name, group)
Enumérateur générique d'un groupe de faces.
#define ENUMERATE_CELL(name, group)
Enumérateur générique d'un groupe de mailles.
DirFace face(Face f) const
Face direction correspondant à la face f.
FaceDirectionMng()
Créé une instance vide.
FaceGroup innerFaces() const
Groupe de toutes les faces internes dans la direction.
FaceGroup outerFaces() const
Groupe de toutes les faces externes dans la direction.
FaceGroup allFaces() const
Groupe de toutes les faces dans la direction.
Interface d'un maillage cartésien.
virtual IMesh * mesh() const =0
Maillage associé à ce maillage cartésien.
virtual IItemFamily * faceFamily()=0
Retourne la famille des faces.
void setItems(Int32ConstArrayView items_local_id)
Positionne les entités du groupe.
Definition ItemGroup.cc:488
void resize(Int64 s)
Change le nombre d'éléments du tableau à s.
ArrayView< T > view() const
Vue mutable sur ce tableau.
Vecteur 1D de données avec sémantique par valeur (style STL).
ItemGroupT< Cell > CellGroup
Groupe de mailles.
Definition ItemTypes.h:183
ItemGroupT< Face > FaceGroup
Groupe de faces.
Definition ItemTypes.h:178
MeshVariableScalarRefT< Cell, Real3 > VariableCellReal3
Grandeur au centre des mailles de type coordonnées.
MeshVariableScalarRefT< Face, Real3 > VariableFaceReal3
Grandeur aux faces de type coordonnées.
IMemoryAllocator * getDefaultDataAllocator()
Allocateur par défaut pour les données.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
ConstArrayView< Int32 > Int32ConstArrayView
Equivalent C d'un tableau à une dimension d'entiers 32 bits.
Definition UtilsTypes.h:640
eMeshDirection
Type de la direction pour un maillage structuré
@ MD_DirInvalid
Direction invalide ou non initialisée.
@ MD_DirZ
Direction Z.
@ MD_DirY
Direction Y.
@ MD_DirX
Direction X.