14#include "arcane/cartesianmesh/NodeDirectionMng.h"
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"
22#include "arcane/core/IItemFamily.h"
23#include "arcane/core/ItemGroup.h"
24#include "arcane/core/IMesh.h"
25#include "arcane/core/VariableTypes.h"
26#include "arcane/core/UnstructuredMeshConnectivity.h"
28#include "arcane/cartesianmesh/ICartesianMesh.h"
29#include "arcane/cartesianmesh/CellDirectionMng.h"
30#include "arcane/cartesianmesh/internal/ICartesianMeshInternal.h"
77void NodeDirectionMng::
85 m_p->m_cartesian_mesh = cm;
86 m_p->m_patch_index = patch_index;
92void NodeDirectionMng::
105 m_p->m_infos.
resize(new_size);
106 m_infos_view = m_p->m_infos.view();
112void NodeDirectionMng::
117 m_infos_view.
fill(NodeDirectionMng::ItemDirectionInfo());
127 NodeLocalId node_next_left = cn.nextLeftId();
128 NodeLocalId node_next_right = cn.nextRightId();
130 NodeLocalId node_previous_left = cn.previousLeftId();
131 NodeLocalId node_previous_right = cn.previousRightId();
133 m_infos_view[node_previous_left].m_next_lid = node_next_left;
134 m_infos_view[node_next_left].m_previous_lid = node_previous_left;
136 m_infos_view[node_previous_right].m_next_lid = node_next_right;
137 m_infos_view[node_next_right].m_previous_lid = node_previous_right;
140 NodeLocalId top_node_next_left = cn.topNextLeftId();
141 NodeLocalId top_node_next_right = cn.topNextRightId();
143 NodeLocalId top_node_previous_left = cn.topPreviousLeftId();
144 NodeLocalId top_node_previous_right = cn.topPreviousRightId();
146 m_infos_view[top_node_previous_left].m_next_lid = top_node_next_left;
147 m_infos_view[top_node_next_left].m_previous_lid = top_node_previous_left;
149 m_infos_view[top_node_previous_right].m_next_lid = top_node_next_right;
150 m_infos_view[top_node_next_right].m_previous_lid = top_node_previous_right;
158 Int32 lid = iitem.itemLocalId();
159 Int32 i1 = m_infos_view[lid].m_next_lid;
160 Int32 i2 = m_infos_view[lid].m_previous_lid;
161 if (i1 == NULL_ITEM_LOCAL_ID || i2 == NULL_ITEM_LOCAL_ID)
166 int dir = (int)m_direction;
167 String base_group_name = String(
"Direction")+dir;
168 if (m_p->m_patch_index>=0)
169 base_group_name = base_group_name + String(
"AMRPatch")+m_p->m_patch_index;
170 m_p->m_inner_all_items = family->
createGroup(String(
"AllInner")+base_group_name,inner_lids,
true);
171 m_p->m_outer_all_items = family->createGroup(String(
"AllOuter")+base_group_name,outer_lids,
true);
172 m_p->m_all_items = all_nodes;
175 _computeNodeCellInfos(cell_dm,cells_center);
178 UnstructuredMeshConnectivityView mesh_connectivity;
179 mesh_connectivity.setMesh(m_p->m_cartesian_mesh->mesh());
180 m_node_cell_view = mesh_connectivity.nodeCell();
187void NodeDirectionMng::
190 m_infos_view.fill(ItemDirectionInfo());
192 Integer mesh_dim = m_p->m_cartesian_mesh->mesh()->dimension();
198 DirCellNode cn(cell_dm.cellNode(cell));
200 NodeLocalId node_next_left = cn.nextLeftId();
201 NodeLocalId node_next_right = cn.nextRightId();
203 NodeLocalId node_previous_left = cn.previousLeftId();
204 NodeLocalId node_previous_right = cn.previousRightId();
206 m_infos_view[node_previous_left].m_next_lid = node_next_left;
207 m_infos_view[node_next_left].m_previous_lid = node_previous_left;
209 m_infos_view[node_previous_right].m_next_lid = node_next_right;
210 m_infos_view[node_next_right].m_previous_lid = node_previous_right;
213 NodeLocalId top_node_next_left = cn.topNextLeftId();
214 NodeLocalId top_node_next_right = cn.topNextRightId();
216 NodeLocalId top_node_previous_left = cn.topPreviousLeftId();
217 NodeLocalId top_node_previous_right = cn.topPreviousRightId();
219 m_infos_view[top_node_previous_left].m_next_lid = top_node_next_left;
220 m_infos_view[top_node_next_left].m_previous_lid = top_node_previous_left;
222 m_infos_view[top_node_previous_right].m_next_lid = top_node_next_right;
223 m_infos_view[top_node_next_right].m_previous_lid = top_node_previous_right;
227 UniqueArray<Int32> inner_cells_lid;
228 UniqueArray<Int32> outer_cells_lid;
229 cell_dm.innerCells().view().fillLocalIds(inner_cells_lid);
230 cell_dm.outerCells().view().fillLocalIds(outer_cells_lid);
232 UniqueArray<Int32> inner_lids;
233 UniqueArray<Int32> outer_lids;
234 UniqueArray<Int32> inpatch_lids;
235 UniqueArray<Int32> overall_lids;
236 IItemFamily* family = all_nodes.itemFamily();
238 Int32 lid = inode.itemLocalId();
241 for (
Cell cell : inode->cells()) {
242 if (inner_cells_lid.contains(cell.localId())) {
245 else if (outer_cells_lid.contains(cell.localId())) {
249 if (nb_inner_cells + nb_outer_cells == inode->nbCell()) {
251 inpatch_lids.add(lid);
253 else if (nb_outer_cells != 0) {
255 inpatch_lids.add(lid);
258 overall_lids.add(lid);
261 int dir = (int)m_direction;
262 String base_group_name = String(
"Direction") + dir;
263 if (m_p->m_patch_index >= 0)
264 base_group_name = base_group_name + String(
"AMRPatch") + m_p->m_patch_index;
265 m_p->m_inner_all_items = family->createGroup(String(
"AllInner") + base_group_name, inner_lids,
true);
266 m_p->m_outer_all_items = family->createGroup(String(
"AllOuter") + base_group_name, outer_lids,
true);
267 m_p->m_inpatch_all_items = family->createGroup(String(
"AllInPatch") + base_group_name, inpatch_lids,
true);
268 m_p->m_overall_all_items = family->createGroup(String(
"AllOverall") + base_group_name, overall_lids,
true);
269 m_p->m_all_items = all_nodes;
272 _computeNodeCellInfos();
275 UnstructuredMeshConnectivityView mesh_connectivity;
276 mesh_connectivity.setMesh(m_p->m_cartesian_mesh->mesh());
277 m_node_cell_view = mesh_connectivity.nodeCell();
288void NodeDirectionMng::
292 std::set<NodeLocalId> nodes_set;
294 nodes_set.insert(NodeLocalId(inode.itemLocalId()));
297 for( ItemDirectionInfo& idi : m_infos_view ){
299 Int32 next_lid = idi.m_next_lid;
300 if (next_lid!=NULL_ITEM_LOCAL_ID)
301 if (nodes_set.find(NodeLocalId(next_lid))==nodes_set.end())
302 idi.m_next_lid = NodeLocalId{};
305 Int32 prev_lid = idi.m_previous_lid;
306 if (prev_lid!=NULL_ITEM_LOCAL_ID)
307 if (nodes_set.find(NodeLocalId(prev_lid))==nodes_set.end())
308 idi.m_previous_lid = NodeLocalId{};
318void NodeDirectionMng::
322 IndexType indexes_ptr[8];
323 ArrayView<IndexType> indexes(8,indexes_ptr);
326 NodeGroup dm_all_nodes = node_dm.allNodes();
328 IMesh* mesh = m_p->m_cartesian_mesh->
mesh();
331 if (mesh_dim!=2 && mesh_dim!=3)
332 ARCANE_FATAL(
"Invalid mesh dimension '{0}'. Valid dimensions are 2 or 3",mesh_dim);
336 std::set<CellLocalId> inside_cells;
338 inside_cells.insert(CellLocalId(icell.itemLocalId()));
344 Real3 node_pos = nodes_coord[
node];
345 indexes.fill(DirNode::NULL_CELL);
346 for(
Integer i=0; i<nb_cell; ++i ){
347 const IndexType bi = (IndexType)i;
349 if (inside_cells.find(CellLocalId(cell.localId()))==inside_cells.end())
352 Real3 center = cells_center[cell];
353 Real3 wanted_cell_pos;
354 Real3 wanted_node_pos;
356 wanted_cell_pos = center;
357 wanted_node_pos = node_pos;
359 wanted_cell_pos = Real3(center.y, -center.x, center.z);
360 wanted_node_pos = Real3(node_pos.y, -node_pos.x, node_pos.z);
363 wanted_cell_pos = Real3(center.z, -center.y, center.x);
364 wanted_node_pos = Real3(node_pos.z, -node_pos.y, node_pos.x);
366 bool is_top = ((wanted_cell_pos.z > wanted_node_pos.z) && mesh_dim==3);
368 if (wanted_cell_pos.x > wanted_node_pos.x ){
369 if (wanted_cell_pos.y > wanted_node_pos.y )
370 indexes_ptr[CNP_NextLeft] = bi;
372 indexes_ptr[CNP_NextRight] = bi;
375 if (wanted_cell_pos.y > wanted_node_pos.y )
376 indexes_ptr[CNP_PreviousLeft] = bi;
378 indexes_ptr[CNP_PreviousRight] = bi;
382 if (wanted_cell_pos.x > wanted_node_pos.x ){
383 if (wanted_cell_pos.y > wanted_node_pos.y )
384 indexes_ptr[CNP_TopNextLeft] = bi;
386 indexes_ptr[CNP_TopNextRight] = bi;
389 if (wanted_cell_pos.y > wanted_node_pos.y )
390 indexes_ptr[CNP_TopPreviousLeft] = bi;
392 indexes_ptr[CNP_TopPreviousRight] = bi;
396 m_infos_view[
node.localId()].setCellIndexes(indexes_ptr);
399void NodeDirectionMng::
400_computeNodeCellInfos()
const
402 Ref<ICartesianMeshNumberingMngInternal> numbering = m_p->m_cartesian_mesh->_internalApi()->cartesianMeshNumberingMngInternal();
404 IndexType indexes_ptr[8];
405 ArrayView indexes(8, indexes_ptr);
409 IMesh* mesh = m_p->m_cartesian_mesh->mesh();
410 Integer mesh_dim = mesh->dimension();
413 constexpr Integer nb_cells_max = 4;
415 Int64 uids[nb_cells_max];
416 ArrayView av_uids(nb_cells_max, uids);
434 constexpr Int32 dir_x_pos_2d[nb_cells_max] = { CNP_PreviousRight, CNP_NextRight, CNP_PreviousLeft, CNP_NextLeft };
435 constexpr Int32 dir_y_pos_2d[nb_cells_max] = { CNP_PreviousLeft, CNP_PreviousRight, CNP_NextLeft, CNP_NextRight };
439 numbering->cellUniqueIdsAroundNode(av_uids,
node);
442 indexes.fill(DirNode::NULL_CELL);
444 for (
Integer i = 0; i < nb_cell; ++i) {
447 for (; pos < nb_cells_max; ++pos) {
448 if (cell.uniqueId() == av_uids[pos])
451 if (pos == nb_cells_max)
454 const IndexType bi = (IndexType)i;
456 indexes[dir_x_pos_2d[pos]] = bi;
459 indexes[dir_y_pos_2d[pos]] = bi;
462 m_infos_view[
node.localId()].setCellIndexes(indexes_ptr);
465 else if (mesh_dim == 3) {
466 constexpr Integer nb_cells_max = 8;
468 Int64 uids[nb_cells_max];
469 ArrayView av_uids(nb_cells_max, uids);
489 constexpr Int32 dir_x_pos_3d[nb_cells_max] = { CNP_PreviousRight, CNP_NextRight, CNP_PreviousLeft, CNP_NextLeft, CNP_TopPreviousRight, CNP_TopNextRight, CNP_TopPreviousLeft, CNP_TopNextLeft };
490 constexpr Int32 dir_y_pos_3d[nb_cells_max] = { CNP_PreviousLeft, CNP_PreviousRight, CNP_NextLeft, CNP_NextRight, CNP_TopPreviousLeft, CNP_TopPreviousRight, CNP_TopNextLeft, CNP_TopNextRight };
491 constexpr Int32 dir_z_pos_3d[nb_cells_max] = { CNP_PreviousLeft, CNP_PreviousRight, CNP_TopPreviousLeft, CNP_TopPreviousRight, CNP_NextLeft, CNP_NextRight, CNP_TopNextLeft, CNP_TopNextRight };
495 numbering->cellUniqueIdsAroundNode(av_uids,
node);
498 indexes.fill(DirNode::NULL_CELL);
500 for (
Integer i = 0; i < nb_cell; ++i) {
503 for (; pos < nb_cells_max; ++pos) {
504 if (cell.uniqueId() == av_uids[pos])
507 if (pos == nb_cells_max)
510 const IndexType bi = (IndexType)i;
513 indexes[dir_x_pos_3d[pos]] = bi;
516 indexes[dir_y_pos_3d[pos]] = bi;
519 indexes[dir_z_pos_3d[pos]] = bi;
522 m_infos_view[
node.localId()].setCellIndexes(indexes_ptr);
527 ARCANE_FATAL(
"Invalid mesh dimension '{0}'. Valid dimensions are 2 or 3", mesh_dim);
537 return m_p->m_all_items;
546 return m_p->m_overall_all_items;
555 return m_p->m_inpatch_all_items;
564 return m_p->m_inner_all_items;
573 return m_p->m_outer_all_items;
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
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 avec info directionnelle des noeuds.
Interface d'un maillage cartésien.
virtual IMesh * mesh() const =0
Maillage associé à ce maillage cartésien.
virtual ItemGroup createGroup(const String &name, Int32ConstArrayView local_ids, bool do_override=false)=0
Créé un groupe d'entités de nom name contenant les entités local_ids.
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)
IMesh * mesh() const
Maillage auquel appartient ce groupe (0 pour le group nul)
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.
NodeGroup inPatchNodes() const
Groupe de tous les noeuds du patch dans la direction.
NodeGroup overallNodes() const
Groupe de tous les noeuds de recouvrement dans la direction.
void _internalResizeInfos(Int32 new_size)
Redimensionne le conteneur contenant les ItemDirectionInfo.
Vue sur les informations des noeuds.
Vecteur 1D de données avec sémantique par valeur (style STL).
void resize(Int64 s)
Change le nombre d'éléments du tableau à s.
__host__ __device__ void fill(T o)
Remplit le tableau avec la valeur o.
ItemGroupT< Node > NodeGroup
Groupe de noeuds.
MeshVariableScalarRefT< Cell, Real3 > VariableCellReal3
Grandeur au centre des mailles de type coordonnées.
MeshVariableScalarRefT< Node, Real3 > VariableNodeReal3
Grandeur au noeud de type coordonnées.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
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_DirInvalid
Direction invalide ou non initialisée.
UniqueArray< Int32 > Int32UniqueArray
Tableau dynamique à une dimension d'entiers 32 bits.
@ Cell
Le maillage est AMR par maille.
std::int32_t Int32
Type entier signé sur 32 bits.