15#include "arcane/cartesianmesh/NodeDirectionMng.h"
17#include "arcane/utils/FatalErrorException.h"
18#include "arcane/utils/ArgumentException.h"
19#include "arcane/utils/ITraceMng.h"
20#include "arcane/utils/Real3.h"
21#include "arcane/utils/PlatformUtils.h"
23#include "arcane/core/IItemFamily.h"
24#include "arcane/core/ItemGroup.h"
25#include "arcane/core/IMesh.h"
26#include "arcane/core/VariableTypes.h"
27#include "arcane/core/UnstructuredMeshConnectivity.h"
29#include "arcane/cartesianmesh/ICartesianMesh.h"
30#include "arcane/cartesianmesh/CellDirectionMng.h"
31#include "arcane/cartesianmesh/internal/ICartesianMeshInternal.h"
78void NodeDirectionMng::
86 m_p->m_cartesian_mesh = cm;
87 m_p->m_patch_index = patch_index;
93void NodeDirectionMng::
106 m_p->m_infos.
resize(new_size);
107 m_infos_view = m_p->m_infos.view();
113void NodeDirectionMng::
118 m_infos_view.
fill(NodeDirectionMng::ItemDirectionInfo());
128 NodeLocalId node_next_left = cn.nextLeftId();
129 NodeLocalId node_next_right = cn.nextRightId();
131 NodeLocalId node_previous_left = cn.previousLeftId();
132 NodeLocalId node_previous_right = cn.previousRightId();
134 m_infos_view[node_previous_left].m_next_lid = node_next_left;
135 m_infos_view[node_next_left].m_previous_lid = node_previous_left;
137 m_infos_view[node_previous_right].m_next_lid = node_next_right;
138 m_infos_view[node_next_right].m_previous_lid = node_previous_right;
141 NodeLocalId top_node_next_left = cn.topNextLeftId();
142 NodeLocalId top_node_next_right = cn.topNextRightId();
144 NodeLocalId top_node_previous_left = cn.topPreviousLeftId();
145 NodeLocalId top_node_previous_right = cn.topPreviousRightId();
147 m_infos_view[top_node_previous_left].m_next_lid = top_node_next_left;
148 m_infos_view[top_node_next_left].m_previous_lid = top_node_previous_left;
150 m_infos_view[top_node_previous_right].m_next_lid = top_node_next_right;
151 m_infos_view[top_node_next_right].m_previous_lid = top_node_previous_right;
159 Int32 lid = iitem.itemLocalId();
160 Int32 i1 = m_infos_view[lid].m_next_lid;
161 Int32 i2 = m_infos_view[lid].m_previous_lid;
162 if (i1 == NULL_ITEM_LOCAL_ID || i2 == NULL_ITEM_LOCAL_ID)
167 int dir = (int)m_direction;
168 String base_group_name = String(
"Direction") + dir;
169 if (m_p->m_patch_index >= 0)
170 base_group_name = base_group_name + String(
"AMRPatch") + m_p->m_patch_index;
171 m_p->m_inner_all_items = family->
createGroup(String(
"AllInner") + base_group_name, inner_lids,
true);
172 m_p->m_outer_all_items = family->createGroup(String(
"AllOuter") + base_group_name, outer_lids,
true);
173 m_p->m_all_items = all_nodes;
176 _computeNodeCellInfos(cell_dm, cells_center);
179 UnstructuredMeshConnectivityView mesh_connectivity;
180 mesh_connectivity.setMesh(m_p->m_cartesian_mesh->mesh());
181 m_node_cell_view = mesh_connectivity.nodeCell();
188void NodeDirectionMng::
191 m_infos_view.fill(ItemDirectionInfo());
193 Integer mesh_dim = m_p->m_cartesian_mesh->mesh()->dimension();
199 DirCellNode cn(cell_dm.cellNode(cell));
201 NodeLocalId node_next_left = cn.nextLeftId();
202 NodeLocalId node_next_right = cn.nextRightId();
204 NodeLocalId node_previous_left = cn.previousLeftId();
205 NodeLocalId node_previous_right = cn.previousRightId();
207 m_infos_view[node_previous_left].m_next_lid = node_next_left;
208 m_infos_view[node_next_left].m_previous_lid = node_previous_left;
210 m_infos_view[node_previous_right].m_next_lid = node_next_right;
211 m_infos_view[node_next_right].m_previous_lid = node_previous_right;
214 NodeLocalId top_node_next_left = cn.topNextLeftId();
215 NodeLocalId top_node_next_right = cn.topNextRightId();
217 NodeLocalId top_node_previous_left = cn.topPreviousLeftId();
218 NodeLocalId top_node_previous_right = cn.topPreviousRightId();
220 m_infos_view[top_node_previous_left].m_next_lid = top_node_next_left;
221 m_infos_view[top_node_next_left].m_previous_lid = top_node_previous_left;
223 m_infos_view[top_node_previous_right].m_next_lid = top_node_next_right;
224 m_infos_view[top_node_next_right].m_previous_lid = top_node_previous_right;
228 UniqueArray<Int32> inner_cells_lid;
229 UniqueArray<Int32> outer_cells_lid;
230 cell_dm.innerCells().view().fillLocalIds(inner_cells_lid);
231 cell_dm.outerCells().view().fillLocalIds(outer_cells_lid);
233 UniqueArray<Int32> inner_lids;
234 UniqueArray<Int32> outer_lids;
237 IItemFamily* family = all_nodes.itemFamily();
239 Int32 lid = inode.itemLocalId();
242 for (
Cell cell : inode->cells()) {
243 if (inner_cells_lid.contains(cell.localId())) {
246 else if (outer_cells_lid.contains(cell.localId())) {
250 if (nb_inner_cells + nb_outer_cells == inode->nbCell()) {
253 else if (nb_outer_cells != 0) {
264 int dir = (int)m_direction;
265 String base_group_name = String(
"Direction") + dir;
266 if (m_p->m_patch_index >= 0)
267 base_group_name = base_group_name + String(
"AMRPatch") + m_p->m_patch_index;
268 m_p->m_inner_all_items = family->createGroup(String(
"AllInner") + base_group_name, inner_lids,
true);
269 m_p->m_outer_all_items = family->createGroup(String(
"AllOuter") + base_group_name, outer_lids,
true);
272 m_p->m_inpatch_all_items = cell_dm.inPatchCells().nodeGroup();
273 m_p->m_overlap_all_items = cell_dm.overlapCells().nodeGroup();
274 m_p->m_all_items = all_nodes;
277 _computeNodeCellInfos();
280 UnstructuredMeshConnectivityView mesh_connectivity;
281 mesh_connectivity.setMesh(m_p->m_cartesian_mesh->mesh());
282 m_node_cell_view = mesh_connectivity.nodeCell();
292void NodeDirectionMng::
296 UniqueArray<bool> is_in_patch(
allNodes().itemFamily()->maxLocalId(),
false);
298 is_in_patch[inode.itemLocalId()] =
true;
301 for (ItemDirectionInfo& idi : m_infos_view) {
303 Int32 next_lid = idi.m_next_lid;
304 if (next_lid != NULL_ITEM_LOCAL_ID && !is_in_patch[next_lid])
305 idi.m_next_lid = NodeLocalId{};
308 Int32 prev_lid = idi.m_previous_lid;
309 if (prev_lid != NULL_ITEM_LOCAL_ID && !is_in_patch[prev_lid])
310 idi.m_previous_lid = NodeLocalId{};
321void NodeDirectionMng::
325 IndexType indexes_ptr[8];
326 ArrayView<IndexType> indexes(8, indexes_ptr);
329 NodeGroup dm_all_nodes = node_dm.allNodes();
331 IMesh* mesh = m_p->m_cartesian_mesh->
mesh();
334 if (mesh_dim != 2 && mesh_dim != 3)
335 ARCANE_FATAL(
"Invalid mesh dimension '{0}'. Valid dimensions are 2 or 3", mesh_dim);
339 UniqueArray<bool> is_inside_cell(mesh->cellFamily()->maxLocalId(),
false);
341 is_inside_cell[icell.itemLocalId()] =
true;
347 Real3 node_pos = nodes_coord[
node];
348 indexes.fill(DirNode::NULL_CELL);
349 for (
Integer i = 0; i < nb_cell; ++i) {
350 const IndexType bi = (IndexType)i;
352 if (!is_inside_cell[cell.localId()])
355 Real3 center = cells_center[cell];
356 Real3 wanted_cell_pos;
357 Real3 wanted_node_pos;
359 wanted_cell_pos = center;
360 wanted_node_pos = node_pos;
363 wanted_cell_pos = Real3(center.y, -center.x, center.z);
364 wanted_node_pos = Real3(node_pos.y, -node_pos.x, node_pos.z);
368 wanted_cell_pos = Real3(center.z, -center.y, center.x);
369 wanted_node_pos = Real3(node_pos.z, -node_pos.y, node_pos.x);
371 bool is_top = ((wanted_cell_pos.z > wanted_node_pos.z) && mesh_dim == 3);
373 if (wanted_cell_pos.x > wanted_node_pos.x) {
374 if (wanted_cell_pos.y > wanted_node_pos.y)
375 indexes_ptr[CNP_NextLeft] = bi;
377 indexes_ptr[CNP_NextRight] = bi;
380 if (wanted_cell_pos.y > wanted_node_pos.y)
381 indexes_ptr[CNP_PreviousLeft] = bi;
383 indexes_ptr[CNP_PreviousRight] = bi;
387 if (wanted_cell_pos.x > wanted_node_pos.x) {
388 if (wanted_cell_pos.y > wanted_node_pos.y)
389 indexes_ptr[CNP_TopNextLeft] = bi;
391 indexes_ptr[CNP_TopNextRight] = bi;
394 if (wanted_cell_pos.y > wanted_node_pos.y)
395 indexes_ptr[CNP_TopPreviousLeft] = bi;
397 indexes_ptr[CNP_TopPreviousRight] = bi;
401 m_infos_view[
node.localId()].setCellIndexes(indexes_ptr);
408void NodeDirectionMng::
409_computeNodeCellInfos()
const
411 Ref<ICartesianMeshNumberingMngInternal> numbering = m_p->m_cartesian_mesh->_internalApi()->cartesianMeshNumberingMngInternal();
413 IndexType indexes_ptr[8];
414 ArrayView indexes(8, indexes_ptr);
418 IMesh* mesh = m_p->m_cartesian_mesh->mesh();
419 Integer mesh_dim = mesh->dimension();
422 constexpr Integer nb_cells_max = 4;
424 Int64 uids[nb_cells_max];
425 ArrayView av_uids(nb_cells_max, uids);
443 constexpr Int32 dir_x_pos_2d[nb_cells_max] = { CNP_PreviousRight, CNP_NextRight, CNP_PreviousLeft, CNP_NextLeft };
444 constexpr Int32 dir_y_pos_2d[nb_cells_max] = { CNP_PreviousLeft, CNP_PreviousRight, CNP_NextLeft, CNP_NextRight };
448 numbering->cellUniqueIdsAroundNode(
node, av_uids);
451 indexes.fill(DirNode::NULL_CELL);
453 for (
Integer i = 0; i < nb_cell; ++i) {
456 for (; pos < nb_cells_max; ++pos) {
457 if (cell.uniqueId() == av_uids[pos])
460 if (pos == nb_cells_max)
463 const IndexType bi = (IndexType)i;
465 indexes[dir_x_pos_2d[pos]] = bi;
468 indexes[dir_y_pos_2d[pos]] = bi;
471 m_infos_view[
node.localId()].setCellIndexes(indexes_ptr);
474 else if (mesh_dim == 3) {
475 constexpr Integer nb_cells_max = 8;
477 Int64 uids[nb_cells_max];
478 ArrayView av_uids(nb_cells_max, uids);
498 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 };
499 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 };
500 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 };
504 numbering->cellUniqueIdsAroundNode(
node, av_uids);
507 indexes.fill(DirNode::NULL_CELL);
509 for (
Integer i = 0; i < nb_cell; ++i) {
512 for (; pos < nb_cells_max; ++pos) {
513 if (cell.uniqueId() == av_uids[pos])
516 if (pos == nb_cells_max)
519 const IndexType bi = (IndexType)i;
522 indexes[dir_x_pos_3d[pos]] = bi;
525 indexes[dir_y_pos_3d[pos]] = bi;
528 indexes[dir_z_pos_3d[pos]] = bi;
531 m_infos_view[
node.localId()].setCellIndexes(indexes_ptr);
536 ARCANE_FATAL(
"Invalid mesh dimension '{0}'. Valid dimensions are 2 or 3", mesh_dim);
546 return m_p->m_all_items;
555 return m_p->m_overlap_all_items;
564 return m_p->m_inpatch_all_items;
573 return m_p->m_inner_all_items;
582 return m_p->m_outer_all_items;
#define ARCANE_FATAL(...)
Macro throwing a FatalErrorException.
Info about the cells in a specific X, Y, or Z direction of a structured mesh.
CellGroup allCells() const
Group of all cells in the direction.
DirCellNode cellNode(Cell c) const
cell with directional info at nodes corresponding to cell c.
Cell with directional node information.
Interface of a Cartesian mesh.
virtual IMesh * mesh() const =0
Mesh associated with this Cartesian mesh.
virtual ItemGroup createGroup(const String &name, Int32ConstArrayView local_ids, bool do_override=false)=0
Creates an entity group named name containing the entities local_ids.
virtual IItemFamily * nodeFamily()=0
Returns the node family.
virtual Integer dimension()=0
Mesh dimension (1D, 2D, or 3D).
IItemFamily * itemFamily() const
Entity family to which this group belongs (0 for the null group).
IMesh * mesh() const
Mesh to which this group belongs (0 for the null group).
NodeGroup innerNodes() const
Group of all inner nodes in the direction.
NodeDirectionMng()
Creates an empty instance.
NodeGroup outerNodes() const
Group of all outer nodes in the direction.
NodeGroup overlapNodes() const
Group of all overlap nodes in the direction.
NodeGroup allNodes() const
Group of all nodes in the direction.
DirNode node(Node n) const
Direction node corresponding to node n.
NodeGroup inPatchNodes() const
Group of all patch nodes in the direction.
void _internalResizeInfos(Int32 new_size)
Resizes the container holding the ItemDirectionInfo.
View of node information.
1D data vector with value semantics (STL style).
void resize(Int64 s)
Changes the number of elements in the array to s.
__host__ __device__ void fill(T o)
Fills the array with the value o.
ItemGroupT< Node > NodeGroup
Group of nodes.
MeshVariableScalarRefT< Cell, Real3 > VariableCellReal3
Coordinate type quantity at cell center.
MeshVariableScalarRefT< Node, Real3 > VariableNodeReal3
Coordinate type quantity at node.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
std::int64_t Int64
Signed integer type of 64 bits.
Int32 Integer
Type representing an integer.
eMeshDirection
Direction type for a structured mesh.
@ MD_DirInvalid
Invalid or uninitialized direction.
UniqueArray< Int32 > Int32UniqueArray
Dynamic 1D array of 32-bit integers.
@ Cell
The mesh is AMR by cell.
std::int32_t Int32
Signed integer type of 32 bits.