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"
80void NodeDirectionMng::
88 m_p->m_cartesian_mesh = cm;
89 m_p->m_patch_index = patch_index;
95void NodeDirectionMng::
108 m_p->m_infos.
resize(new_size);
109 m_infos_view = m_p->m_infos.view();
115void NodeDirectionMng::
120 m_infos_view.
fill(NodeDirectionMng::ItemDirectionInfo());
130 NodeLocalId node_next_left = cn.nextLeftId();
131 NodeLocalId node_next_right = cn.nextRightId();
133 NodeLocalId node_previous_left = cn.previousLeftId();
134 NodeLocalId node_previous_right = cn.previousRightId();
136 m_infos_view[node_previous_left].m_next_lid = node_next_left;
137 m_infos_view[node_next_left].m_previous_lid = node_previous_left;
139 m_infos_view[node_previous_right].m_next_lid = node_next_right;
140 m_infos_view[node_next_right].m_previous_lid = node_previous_right;
143 NodeLocalId top_node_next_left = cn.topNextLeftId();
144 NodeLocalId top_node_next_right = cn.topNextRightId();
146 NodeLocalId top_node_previous_left = cn.topPreviousLeftId();
147 NodeLocalId top_node_previous_right = cn.topPreviousRightId();
149 m_infos_view[top_node_previous_left].m_next_lid = top_node_next_left;
150 m_infos_view[top_node_next_left].m_previous_lid = top_node_previous_left;
152 m_infos_view[top_node_previous_right].m_next_lid = top_node_next_right;
153 m_infos_view[top_node_next_right].m_previous_lid = top_node_previous_right;
161 Int32 lid = iitem.itemLocalId();
162 Int32 i1 = m_infos_view[lid].m_next_lid;
163 Int32 i2 = m_infos_view[lid].m_previous_lid;
164 if (i1 == NULL_ITEM_LOCAL_ID || i2 == NULL_ITEM_LOCAL_ID)
169 int dir = (int)m_direction;
170 String base_group_name = String(
"Direction") + dir;
171 if (m_p->m_patch_index >= 0)
172 base_group_name = base_group_name + String(
"AMRPatch") + m_p->m_patch_index;
173 m_p->m_inner_all_items = family->
createGroup(String(
"AllInner") + base_group_name, inner_lids,
true);
174 m_p->m_outer_all_items = family->createGroup(String(
"AllOuter") + base_group_name, outer_lids,
true);
175 m_p->m_all_items = all_nodes;
178 _computeNodeCellInfos(cell_dm, cells_center);
181 UnstructuredMeshConnectivityView mesh_connectivity;
182 mesh_connectivity.setMesh(m_p->m_cartesian_mesh->mesh());
183 m_node_cell_view = mesh_connectivity.nodeCell();
190void NodeDirectionMng::
193 m_infos_view.fill(ItemDirectionInfo());
195 Integer mesh_dim = m_p->m_cartesian_mesh->mesh()->dimension();
201 DirCellNode cn(cell_dm.cellNode(cell));
203 NodeLocalId node_next_left = cn.nextLeftId();
204 NodeLocalId node_next_right = cn.nextRightId();
206 NodeLocalId node_previous_left = cn.previousLeftId();
207 NodeLocalId node_previous_right = cn.previousRightId();
209 m_infos_view[node_previous_left].m_next_lid = node_next_left;
210 m_infos_view[node_next_left].m_previous_lid = node_previous_left;
212 m_infos_view[node_previous_right].m_next_lid = node_next_right;
213 m_infos_view[node_next_right].m_previous_lid = node_previous_right;
216 NodeLocalId top_node_next_left = cn.topNextLeftId();
217 NodeLocalId top_node_next_right = cn.topNextRightId();
219 NodeLocalId top_node_previous_left = cn.topPreviousLeftId();
220 NodeLocalId top_node_previous_right = cn.topPreviousRightId();
222 m_infos_view[top_node_previous_left].m_next_lid = top_node_next_left;
223 m_infos_view[top_node_next_left].m_previous_lid = top_node_previous_left;
225 m_infos_view[top_node_previous_right].m_next_lid = top_node_next_right;
226 m_infos_view[top_node_next_right].m_previous_lid = top_node_previous_right;
230 UniqueArray<Int32> inner_cells_lid;
231 UniqueArray<Int32> outer_cells_lid;
232 cell_dm.innerCells().view().fillLocalIds(inner_cells_lid);
233 cell_dm.outerCells().view().fillLocalIds(outer_cells_lid);
235 UniqueArray<Int32> inner_lids;
236 UniqueArray<Int32> outer_lids;
239 IItemFamily* family = all_nodes.itemFamily();
241 Int32 lid = inode.itemLocalId();
244 for (
Cell cell : inode->cells()) {
245 if (inner_cells_lid.contains(cell.localId())) {
248 else if (outer_cells_lid.contains(cell.localId())) {
252 if (nb_inner_cells + nb_outer_cells == inode->nbCell()) {
255 else if (nb_outer_cells != 0) {
266 int dir = (int)m_direction;
267 String base_group_name = String(
"Direction") + dir;
268 if (m_p->m_patch_index >= 0)
269 base_group_name = base_group_name + String(
"AMRPatch") + m_p->m_patch_index;
270 m_p->m_inner_all_items = family->createGroup(String(
"AllInner") + base_group_name, inner_lids,
true);
271 m_p->m_outer_all_items = family->createGroup(String(
"AllOuter") + base_group_name, outer_lids,
true);
274 m_p->m_inpatch_all_items = cell_dm.inPatchCells().nodeGroup();
275 m_p->m_overlap_all_items = cell_dm.overlapCells().nodeGroup();
276 m_p->m_all_items = all_nodes;
279 _computeNodeCellInfos();
282 UnstructuredMeshConnectivityView mesh_connectivity;
283 mesh_connectivity.setMesh(m_p->m_cartesian_mesh->mesh());
284 m_node_cell_view = mesh_connectivity.nodeCell();
294void NodeDirectionMng::
298 std::set<NodeLocalId> nodes_set;
300 nodes_set.insert(NodeLocalId(inode.itemLocalId()));
303 for (ItemDirectionInfo& idi : m_infos_view) {
305 Int32 next_lid = idi.m_next_lid;
306 if (next_lid != NULL_ITEM_LOCAL_ID)
307 if (nodes_set.find(NodeLocalId(next_lid)) == nodes_set.end())
308 idi.m_next_lid = NodeLocalId{};
311 Int32 prev_lid = idi.m_previous_lid;
312 if (prev_lid != NULL_ITEM_LOCAL_ID)
313 if (nodes_set.find(NodeLocalId(prev_lid)) == nodes_set.end())
314 idi.m_previous_lid = NodeLocalId{};
325void NodeDirectionMng::
329 IndexType indexes_ptr[8];
330 ArrayView<IndexType> indexes(8, indexes_ptr);
333 NodeGroup dm_all_nodes = node_dm.allNodes();
335 IMesh* mesh = m_p->m_cartesian_mesh->
mesh();
338 if (mesh_dim != 2 && mesh_dim != 3)
339 ARCANE_FATAL(
"Invalid mesh dimension '{0}'. Valid dimensions are 2 or 3", mesh_dim);
343 std::set<CellLocalId> inside_cells;
345 inside_cells.insert(CellLocalId(icell.itemLocalId()));
351 Real3 node_pos = nodes_coord[
node];
352 indexes.fill(DirNode::NULL_CELL);
353 for (
Integer i = 0; i < nb_cell; ++i) {
354 const IndexType bi = (IndexType)i;
356 if (inside_cells.find(CellLocalId(cell.localId())) == inside_cells.end())
359 Real3 center = cells_center[cell];
360 Real3 wanted_cell_pos;
361 Real3 wanted_node_pos;
363 wanted_cell_pos = center;
364 wanted_node_pos = node_pos;
367 wanted_cell_pos = Real3(center.y, -center.x, center.z);
368 wanted_node_pos = Real3(node_pos.y, -node_pos.x, node_pos.z);
372 wanted_cell_pos = Real3(center.z, -center.y, center.x);
373 wanted_node_pos = Real3(node_pos.z, -node_pos.y, node_pos.x);
375 bool is_top = ((wanted_cell_pos.z > wanted_node_pos.z) && mesh_dim == 3);
377 if (wanted_cell_pos.x > wanted_node_pos.x) {
378 if (wanted_cell_pos.y > wanted_node_pos.y)
379 indexes_ptr[CNP_NextLeft] = bi;
381 indexes_ptr[CNP_NextRight] = bi;
384 if (wanted_cell_pos.y > wanted_node_pos.y)
385 indexes_ptr[CNP_PreviousLeft] = bi;
387 indexes_ptr[CNP_PreviousRight] = bi;
391 if (wanted_cell_pos.x > wanted_node_pos.x) {
392 if (wanted_cell_pos.y > wanted_node_pos.y)
393 indexes_ptr[CNP_TopNextLeft] = bi;
395 indexes_ptr[CNP_TopNextRight] = bi;
398 if (wanted_cell_pos.y > wanted_node_pos.y)
399 indexes_ptr[CNP_TopPreviousLeft] = bi;
401 indexes_ptr[CNP_TopPreviousRight] = bi;
405 m_infos_view[
node.localId()].setCellIndexes(indexes_ptr);
412void NodeDirectionMng::
413_computeNodeCellInfos()
const
415 Ref<ICartesianMeshNumberingMngInternal> numbering = m_p->m_cartesian_mesh->_internalApi()->cartesianMeshNumberingMngInternal();
417 IndexType indexes_ptr[8];
418 ArrayView indexes(8, indexes_ptr);
422 IMesh* mesh = m_p->m_cartesian_mesh->mesh();
423 Integer mesh_dim = mesh->dimension();
426 constexpr Integer nb_cells_max = 4;
428 Int64 uids[nb_cells_max];
429 ArrayView av_uids(nb_cells_max, uids);
447 constexpr Int32 dir_x_pos_2d[nb_cells_max] = { CNP_PreviousRight, CNP_NextRight, CNP_PreviousLeft, CNP_NextLeft };
448 constexpr Int32 dir_y_pos_2d[nb_cells_max] = { CNP_PreviousLeft, CNP_PreviousRight, CNP_NextLeft, CNP_NextRight };
452 numbering->cellUniqueIdsAroundNode(
node, av_uids);
455 indexes.fill(DirNode::NULL_CELL);
457 for (
Integer i = 0; i < nb_cell; ++i) {
460 for (; pos < nb_cells_max; ++pos) {
461 if (cell.uniqueId() == av_uids[pos])
464 if (pos == nb_cells_max)
467 const IndexType bi = (IndexType)i;
469 indexes[dir_x_pos_2d[pos]] = bi;
472 indexes[dir_y_pos_2d[pos]] = bi;
475 m_infos_view[
node.localId()].setCellIndexes(indexes_ptr);
478 else if (mesh_dim == 3) {
479 constexpr Integer nb_cells_max = 8;
481 Int64 uids[nb_cells_max];
482 ArrayView av_uids(nb_cells_max, uids);
502 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 };
503 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 };
504 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 };
508 numbering->cellUniqueIdsAroundNode(
node, av_uids);
511 indexes.fill(DirNode::NULL_CELL);
513 for (
Integer i = 0; i < nb_cell; ++i) {
516 for (; pos < nb_cells_max; ++pos) {
517 if (cell.uniqueId() == av_uids[pos])
520 if (pos == nb_cells_max)
523 const IndexType bi = (IndexType)i;
526 indexes[dir_x_pos_3d[pos]] = bi;
529 indexes[dir_y_pos_3d[pos]] = bi;
532 indexes[dir_z_pos_3d[pos]] = bi;
535 m_infos_view[
node.localId()].setCellIndexes(indexes_ptr);
540 ARCANE_FATAL(
"Invalid mesh dimension '{0}'. Valid dimensions are 2 or 3", mesh_dim);
550 return m_p->m_all_items;
559 return m_p->m_overlap_all_items;
568 return m_p->m_inpatch_all_items;
577 return m_p->m_inner_all_items;
586 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.