Arcane  v3.14.10.0
Documentation utilisateur
Chargement...
Recherche...
Aucune correspondance
NodeDirectionMng.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/* NodeDirectionMng.cc (C) 2000-2022 */
9/* */
10/* Infos sur les mailles d'une direction X Y ou Z d'un maillage structuré. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/cartesianmesh/NodeDirectionMng.h"
15
16#include "arcane/utils/FatalErrorException.h"
17#include "arcane/utils/ArgumentException.h"
18#include "arcane/utils/ITraceMng.h"
19#include "arcane/utils/Real3.h"
20#include "arcane/utils/PlatformUtils.h"
21
22#include "arcane/IItemFamily.h"
23#include "arcane/ItemGroup.h"
24#include "arcane/IMesh.h"
25#include "arcane/VariableTypes.h"
26#include "arcane/UnstructuredMeshConnectivity.h"
27
28#include "arcane/cartesianmesh/ICartesianMesh.h"
29#include "arcane/cartesianmesh/CellDirectionMng.h"
30
31#include <set>
32
33/*---------------------------------------------------------------------------*/
34/*---------------------------------------------------------------------------*/
35
36namespace Arcane
37{
38
39/*---------------------------------------------------------------------------*/
40/*---------------------------------------------------------------------------*/
41
43{
44 public:
45
47
48 public:
49
50 NodeGroup m_inner_all_items;
51 NodeGroup m_outer_all_items;
52 NodeGroup m_all_items;
53 ICartesianMesh* m_cartesian_mesh = nullptr;
54 Integer m_patch_index = -1;
56};
57
58/*---------------------------------------------------------------------------*/
59/*---------------------------------------------------------------------------*/
60
63: m_direction(MD_DirInvalid)
64, m_p(nullptr)
65{
66}
67
68/*---------------------------------------------------------------------------*/
69/*---------------------------------------------------------------------------*/
70
71/*---------------------------------------------------------------------------*/
72/*---------------------------------------------------------------------------*/
73
74void NodeDirectionMng::
75_internalInit(ICartesianMesh* cm,eMeshDirection dir,Integer patch_index)
76{
77 if (m_p)
78 ARCANE_FATAL("Initialisation already done");
79 m_p = new Impl();
80 m_direction = dir;
81 m_nodes = NodeInfoListView(cm->mesh()->nodeFamily());
82 m_p->m_cartesian_mesh = cm;
83 m_p->m_patch_index = patch_index;
84}
85
86/*---------------------------------------------------------------------------*/
87/*---------------------------------------------------------------------------*/
88
89void NodeDirectionMng::
90_internalDestroy()
91{
92 delete m_p;
93 m_p = nullptr;
94}
95
96/*---------------------------------------------------------------------------*/
97/*---------------------------------------------------------------------------*/
98
100_internalResizeInfos(Int32 new_size)
101{
102 m_p->m_infos.resize(new_size);
103 m_infos_view = m_p->m_infos.view();
104}
105
106/*---------------------------------------------------------------------------*/
107/*---------------------------------------------------------------------------*/
108
109void NodeDirectionMng::
110_internalComputeInfos(const CellDirectionMng& cell_dm,const NodeGroup& all_nodes,
111 const VariableCellReal3& cells_center)
112{
113 Node null_node;
114 m_infos_view.fill(NodeDirectionMng::ItemDirectionInfo());
115
116 Integer mesh_dim = m_p->m_cartesian_mesh->mesh()->dimension();
117 //TODO: ne garder que les noeuds de notre patch
118
119 // Calcul les infos de direction pour les noeuds
120 ENUMERATE_CELL(icell,cell_dm.allCells()){
121 Cell cell = *icell;
122 DirCellNode cn(cell_dm.cellNode(cell));
123
124 NodeLocalId node_next_left = cn.nextLeftId();
125 NodeLocalId node_next_right = cn.nextRightId();
126
127 NodeLocalId node_previous_left = cn.previousLeftId();
128 NodeLocalId node_previous_right = cn.previousRightId();
129
130 m_infos_view[node_previous_left].m_next_lid = node_next_left;
131 m_infos_view[node_next_left].m_previous_lid = node_previous_left;
132
133 m_infos_view[node_previous_right].m_next_lid = node_next_right;
134 m_infos_view[node_next_right].m_previous_lid = node_previous_right;
135
136 if (mesh_dim==3){
137 NodeLocalId top_node_next_left = cn.topNextLeftId();
138 NodeLocalId top_node_next_right = cn.topNextRightId();
139
140 NodeLocalId top_node_previous_left = cn.topPreviousLeftId();
141 NodeLocalId top_node_previous_right = cn.topPreviousRightId();
142
143 m_infos_view[top_node_previous_left].m_next_lid = top_node_next_left;
144 m_infos_view[top_node_next_left].m_previous_lid = top_node_previous_left;
145
146 m_infos_view[top_node_previous_right].m_next_lid = top_node_next_right;
147 m_infos_view[top_node_next_right].m_previous_lid = top_node_previous_right;
148 }
149 }
150
151 Int32UniqueArray inner_lids;
152 Int32UniqueArray outer_lids;
153 IItemFamily* family = all_nodes.itemFamily();
154 ENUMERATE_ITEM(iitem,all_nodes){
155 Int32 lid = iitem.itemLocalId();
156 Int32 i1 = m_infos_view[lid].m_next_lid;
157 Int32 i2 = m_infos_view[lid].m_previous_lid;
158 if (i1==NULL_ITEM_LOCAL_ID || i2==NULL_ITEM_LOCAL_ID)
159 outer_lids.add(lid);
160 else
161 inner_lids.add(lid);
162 }
163 int dir = (int)m_direction;
164 String base_group_name = String("Direction")+dir;
165 if (m_p->m_patch_index>=0)
166 base_group_name = base_group_name + String("AMRPatch")+m_p->m_patch_index;
167 m_p->m_inner_all_items = family->createGroup(String("AllInner")+base_group_name,inner_lids,true);
168 m_p->m_outer_all_items = family->createGroup(String("AllOuter")+base_group_name,outer_lids,true);
169 m_p->m_all_items = all_nodes;
170
171 _filterNodes();
172 _computeNodeCellInfos(cell_dm,cells_center);
173
174 {
175 UnstructuredMeshConnectivityView mesh_connectivity;
176 mesh_connectivity.setMesh(m_p->m_cartesian_mesh->mesh());
177 m_node_cell_view = mesh_connectivity.nodeCell();
178 }
179}
180
181/*---------------------------------------------------------------------------*/
182/*---------------------------------------------------------------------------*/
183/*!
184 * \brief Filtre les noeuds devant/derrière pour ne garder que les
185 * noeuds de notre patch.
186 */
187void NodeDirectionMng::
188_filterNodes()
189{
190 // Ensemble contenant uniquement les noeuds de notre patch
191 std::set<NodeLocalId> nodes_set;
192 ENUMERATE_NODE(inode,allNodes()){
193 nodes_set.insert(NodeLocalId(inode.itemLocalId()));
194 }
195
196 for( ItemDirectionInfo& idi : m_infos_view ){
197 {
198 Int32 next_lid = idi.m_next_lid;
199 if (next_lid!=NULL_ITEM_LOCAL_ID)
200 if (nodes_set.find(NodeLocalId(next_lid))==nodes_set.end())
201 idi.m_next_lid = NodeLocalId{};
202 }
203 {
204 Int32 prev_lid = idi.m_previous_lid;
205 if (prev_lid!=NULL_ITEM_LOCAL_ID)
206 if (nodes_set.find(NodeLocalId(prev_lid))==nodes_set.end())
207 idi.m_previous_lid = NodeLocalId{};
208 }
209 }
210}
211
212/*---------------------------------------------------------------------------*/
213/*---------------------------------------------------------------------------*/
214/*!
215 * \brief Calcul des connectivités noeuds/mailles par direction.
216 */
217void NodeDirectionMng::
218_computeNodeCellInfos(const CellDirectionMng& cell_dm,const VariableCellReal3& cells_center)
219{
220 // TODO: ne traiter que les mailles de notre patch.
221 IndexType indexes_ptr[8];
222 ArrayView<IndexType> indexes(8,indexes_ptr);
223
224 NodeDirectionMng& node_dm = *this;
225 NodeGroup dm_all_nodes = node_dm.allNodes();
226 eMeshDirection dir = m_direction;
227 IMesh* mesh = m_p->m_cartesian_mesh->mesh();
228 Integer mesh_dim = mesh->dimension();
229 VariableNodeReal3& nodes_coord = mesh->nodesCoordinates();
230 if (mesh_dim!=2 && mesh_dim!=3)
231 ARCANE_FATAL("Invalid mesh dimension '{0}'. Valid dimensions are 2 or 3",mesh_dim);
232
233 // Ensemble contenant uniquement les mailles de notre patch
234 // Cela sert à filtrer pour ne garder que ces mailles là dans la connectivité
235 std::set<CellLocalId> inside_cells;
236 ENUMERATE_CELL(icell,cell_dm.allCells()){
237 inside_cells.insert(CellLocalId(icell.itemLocalId()));
238 }
239
240 ENUMERATE_NODE(inode,dm_all_nodes){
241 Node node = *inode;
242 Integer nb_cell = node.nbCell();
243 Real3 node_pos = nodes_coord[node];
244 indexes.fill(DirNode::NULL_CELL);
245 for( Integer i=0; i<nb_cell; ++i ){
246 const IndexType bi = (IndexType)i;
247 Cell cell = node.cell(i);
248 if (inside_cells.find(CellLocalId(cell.localId()))==inside_cells.end())
249 continue;
250
251 Real3 center = cells_center[cell];
252 Real3 wanted_cell_pos;
253 Real3 wanted_node_pos;
254 if (dir==MD_DirX){
255 wanted_cell_pos = center;
256 wanted_node_pos = node_pos;
257 } else if (dir==MD_DirY){
258 wanted_cell_pos = Real3(center.y, -center.x, center.z);
259 wanted_node_pos = Real3(node_pos.y, -node_pos.x, node_pos.z);
260 } else if (dir==MD_DirZ){
261 // TODO: à vérifier pour Y et Z
262 wanted_cell_pos = Real3(center.z, -center.y, center.x);
263 wanted_node_pos = Real3(node_pos.z, -node_pos.y, node_pos.x);
264 }
265 bool is_top = ((wanted_cell_pos.z > wanted_node_pos.z) && mesh_dim==3);
266 if (!is_top){
267 if (wanted_cell_pos.x > wanted_node_pos.x ){
268 if (wanted_cell_pos.y > wanted_node_pos.y )
269 indexes_ptr[CNP_NextLeft] = bi;
270 else
271 indexes_ptr[CNP_NextRight] = bi;
272 }
273 else{
274 if (wanted_cell_pos.y > wanted_node_pos.y )
275 indexes_ptr[CNP_PreviousLeft] = bi;
276 else
277 indexes_ptr[CNP_PreviousRight] = bi;
278 }
279 }
280 else{
281 if (wanted_cell_pos.x > wanted_node_pos.x ){
282 if (wanted_cell_pos.y > wanted_node_pos.y )
283 indexes_ptr[CNP_TopNextLeft] = bi;
284 else
285 indexes_ptr[CNP_TopNextRight] = bi;
286 }
287 else{
288 if (wanted_cell_pos.y > wanted_node_pos.y )
289 indexes_ptr[CNP_TopPreviousLeft] = bi;
290 else
291 indexes_ptr[CNP_TopPreviousRight] = bi;
292 }
293 }
294 }
295 m_infos_view[node.localId()].setCellIndexes(indexes_ptr);
296 }
297}
298
299/*---------------------------------------------------------------------------*/
300/*---------------------------------------------------------------------------*/
301
303allNodes() const
304{
305 return m_p->m_all_items;
306}
307
308/*---------------------------------------------------------------------------*/
309/*---------------------------------------------------------------------------*/
310
312innerNodes() const
313{
314 return m_p->m_inner_all_items;
315}
316
317/*---------------------------------------------------------------------------*/
318/*---------------------------------------------------------------------------*/
319
321outerNodes() const
322{
323 return m_p->m_outer_all_items;
324}
325
326/*---------------------------------------------------------------------------*/
327/*---------------------------------------------------------------------------*/
328
329} // End namespace Arcane
330
331/*---------------------------------------------------------------------------*/
332/*---------------------------------------------------------------------------*/
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
#define ENUMERATE_CELL(name, group)
Enumérateur générique d'un groupe de mailles.
#define ENUMERATE_ITEM(name, group)
Enumérateur générique d'un groupe de noeuds.
#define ENUMERATE_NODE(name, group)
Enumérateur générique d'un groupe de noeuds.
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.
DirCellNode cellNode(Cell c) const
Maille avec infos directionnelles aux noeuds correspondant à la maille c.
Maille d'un maillage.
Definition Item.h:1178
Maille avec info directionnelle des noeuds.
Cell cell(Int32 position) const
Maille en fonction de sa position par rapport à ce noeud.
Interface d'un maillage cartésien.
virtual IMesh * mesh() const =0
Maillage associé à ce maillage cartésien.
virtual IItemFamily * nodeFamily()=0
Retourne la famille des noeuds.
virtual Integer dimension()=0
Dimension du maillage (1D, 2D ou 3D).
IItemFamily * itemFamily() const
Famille d'entité à laquelle appartient ce groupe (0 pour le group nul)
Definition ItemGroup.h:123
NodeGroup innerNodes() const
Groupe de tous les noeuds internes dans la direction.
NodeDirectionMng()
Créé une instance vide.
NodeGroup outerNodes() const
Groupe de tous les noeuds externes dans la direction.
NodeGroup allNodes() const
Groupe de tous les noeuds dans la direction.
DirNode node(Node n) const
Noeud direction correspondant au noeud n.
void _internalResizeInfos(Int32 new_size)
Redimensionne le conteneur contenant les ItemDirectionInfo.
Vue sur les informations des noeuds.
Noeud d'un maillage.
Definition Dom.h:204
void resize(Int64 s)
Change le nombre d'éléments du tableau à s.
ArrayView< T > view() const
Vue mutable sur ce tableau.
__host__ __device__ void fill(T o)
Remplit le tableau avec la valeur o.
Definition Span.h:261
Vecteur 1D de données avec sémantique par valeur (style STL).
ItemGroupT< Node > NodeGroup
Groupe de noeuds.
Definition ItemTypes.h:167
MeshVariableScalarRefT< Cell, Real3 > VariableCellReal3
Grandeur au centre des mailles de type coordonnées.
MeshVariableScalarRefT< Node, Real3 > VariableNodeReal3
Grandeur au noeud 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 -*-
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.
UniqueArray< Int32 > Int32UniqueArray
Tableau dynamique à une dimension d'entiers 32 bits.
Definition UtilsTypes.h:515
Int32 Integer
Type représentant un entier.