14#include "arcane/cartesianmesh/internal/CartesianMeshUniqueIdRenumbering.h"
16#include "arcane/utils/PlatformUtils.h"
18#include "arcane/cartesianmesh/ICartesianMesh.h"
19#include "arcane/cartesianmesh/ICartesianMeshPatch.h"
21#include "arcane/core/CartesianGridDimension.h"
22#include "arcane/core/VariableTypes.h"
23#include "arcane/core/IMesh.h"
24#include "arcane/core/IItemFamily.h"
25#include "arcane/core/IParallelMng.h"
26#include "arcane/core/ICartesianMeshGenerationInfo.h"
49 cells.fill(NULL_ITEM_UNIQUE_ID);
50 nodes.fill(NULL_ITEM_UNIQUE_ID);
51 faces.fill(NULL_ITEM_UNIQUE_ID);
56 void markCellNoRenumber(
Cell c)
59 for (
Node n :
c.nodes())
61 for (
Face f :
c.faces())
64 Int64 maxUniqueId()
const
66 return math::max(max_cell_uid, max_node_uid, max_face_uid);
77 Int64 max_cell_uid = NULL_ITEM_UNIQUE_ID;
78 Int64 max_node_uid = NULL_ITEM_UNIQUE_ID;
79 Int64 max_face_uid = NULL_ITEM_UNIQUE_ID;
83 void _setNode(
Node node)
87 if (uid > max_node_uid)
90 void _setFace(
Face face)
94 if (uid > max_face_uid)
97 void _setCell(
Cell cell)
101 if (uid > max_cell_uid)
109CartesianMeshUniqueIdRenumbering::
113, m_cartesian_mesh(
cmesh)
118 if (platform::getEnvironmentVariable(
"ARCANE_DEBUG_AMR_RENUMBERING") ==
"1")
125void CartesianMeshUniqueIdRenumbering::
130 const Int32 dimension = mesh->
dimension();
133 const bool use_v2 = (m_patch_method == 3);
134 info() <<
"Apply UniqueId renumbering to mesh '" << mesh->
name() <<
"'"
136 <<
" global_nb_cell_by_dim=" << m_generation_info->globalNbCells()
137 <<
" mesh_dimension=" << dimension
138 <<
" patch_method=" << m_patch_method
148 if (m_patch_method != 4)
161 Int32 patch_level = 0;
164 patch_level = c.level();
165 new_uids.markCellNoRenumber(c);
166 Cell parent = c.hParent();
168 new_uids.markCellNoRenumber(parent);
172 Int64 nb_cell_x = global_nb_cells_by_direction[
MD_DirX];
173 Int64 nb_cell_y = global_nb_cells_by_direction[
MD_DirY];
174 Int64 nb_cell_z = global_nb_cells_by_direction[
MD_DirZ];
177 ARCANE_FATAL(
"Bad value '{0}' for globalNbCells()[MD_DirX] (should be >0)", nb_cell_x);
178 if (dimension >= 2 && nb_cell_y <= 0)
179 ARCANE_FATAL(
"Bad value '{0}' for globalNbCells()[MD_DirY] (should be >0)", nb_cell_y);
180 if (dimension >= 3 && nb_cell_z <= 0)
181 ARCANE_FATAL(
"Bad value '{0}' for globalNbCells()[MD_DirZ] (should be >0)", nb_cell_z);
185 info() <<
"PatchLevel=" << patch_level <<
" use_default_path=" << use_default_patch;
186 Int32 multiplier = 1;
187 for (
Int32 z = 0; z < patch_level; ++z)
189 nb_cell_x *= multiplier;
190 nb_cell_y *= multiplier;
191 nb_cell_z *= multiplier;
193 CartesianGridDimension grid(nb_cell_x, nb_cell_y, nb_cell_z);
195 Int64 max_item_uid = pm->
reduce(Parallel::ReduceMax, new_uids.maxUniqueId());
196 info() <<
"MaxItem uniqueId=" << max_item_uid;
197 Int64 base_adder = 1 + max_item_uid;
198 if (use_default_patch)
204 if (dimension == 2) {
205 CartesianGridDimension::CellUniqueIdComputer2D cell_uid_computer(0, nb_cell_x);
208 Int64 uid = cell.uniqueId();
209 Int32 level = cell.level();
210 auto [coord_i, coord_j, coord_k] = cell_uid_computer.compute(uid);
212 info() <<
"Renumbering: PARENT: cell_uid=" << uid <<
" I=" << coord_i
213 <<
" J=" << coord_j <<
" nb_cell_x=" << nb_cell_x;
214 if (use_default_patch)
217 _applyChildrenCell2D(cell, new_uids, coord_i, coord_j, nb_cell_x, nb_cell_y, level, base_adder);
220 else if (dimension == 3) {
221 CartesianGridDimension::CellUniqueIdComputer3D cell_uid_computer(grid.getCellComputer3D(0));
224 Int64 uid = cell.uniqueId();
225 auto [coord_i, coord_j, coord_k] = cell_uid_computer.compute(uid);
226 Int32 level = cell.level();
228 info() <<
"Renumbering: PARENT: cell_uid=" << uid <<
" level=" << level
229 <<
" I=" << coord_i <<
" J=" << coord_j <<
" K=" << coord_k
230 <<
" nb_cell_x=" << nb_cell_x <<
" nb_cell_y=" << nb_cell_y <<
" nb_cell_z=" << nb_cell_z;
232 _applyChildrenCell3DV2(cell, new_uids, coord_i, coord_j, coord_k,
233 nb_cell_x, nb_cell_y, nb_cell_z, level,
234 base_adder, base_adder, base_adder);
236 _applyChildrenCell3D(cell, new_uids, coord_i, coord_j, coord_k,
237 nb_cell_x, nb_cell_y, nb_cell_z, level,
238 base_adder, base_adder, base_adder);
246 _applyFamilyRenumbering(mesh->
cellFamily(), new_uids.cells);
247 _applyFamilyRenumbering(mesh->
nodeFamily(), new_uids.nodes);
248 _applyFamilyRenumbering(mesh->
faceFamily(), new_uids.faces);
255void CartesianMeshUniqueIdRenumbering::
258 info() <<
"Change uniqueId() for family=" << family->name();
259 items_new_uid.synchronize();
260 ENUMERATE_ (Item, iitem, family->allItems()) {
262 Int64 current_uid = item.uniqueId();
263 Int64 new_uid = items_new_uid[iitem];
264 if (new_uid >= 0 && new_uid != current_uid) {
266 info() <<
"Change ItemUID old=" << current_uid <<
" new=" << new_uid;
267 item.mutableItemBase().setUniqueId(new_uid);
270 family->notifyItemsUniqueIdChanged();
276void CartesianMeshUniqueIdRenumbering::
277_applyChildrenCell2D(Cell cell, NewUniqueIdList& new_uids,
284 if (coord_i >= nb_cell_x)
285 ARCANE_FATAL(
"Bad coordinate X={0} max={1}", coord_i, nb_cell_x);
286 if (coord_j >= nb_cell_y)
287 ARCANE_FATAL(
"Bad coordinate Y={0} max={1}", coord_j, nb_cell_y);
294 const Int64 nb_node_x = nb_cell_x + 1;
295 const Int64 nb_node_y = nb_cell_y + 1;
296 const Int64 cell_adder = base_adder + (nb_cell_x * nb_cell_y * level);
297 const Int64 nb_face_x = nb_cell_x + 1;
298 const Int64 node_adder = base_adder + (nb_node_x * nb_node_y * level);
299 const Int64 face_adder = base_adder + (node_adder * 2);
307 if (cell.nbNode() != 4)
308 ARCANE_FATAL(
"Invalid number of nodes N={0}, expected=4", cell.nbNode());
309 std::array<Int64, 4> node_uids;
310 node_uids[0] = (coord_i + 0) + ((coord_j + 0) * nb_node_x);
311 node_uids[1] = (coord_i + 1) + ((coord_j + 0) * nb_node_x);
312 node_uids[2] = (coord_i + 1) + ((coord_j + 1) * nb_node_x);
313 node_uids[3] = (coord_i + 0) + ((coord_j + 1) * nb_node_x);
314 for (Integer z = 0; z < 4; ++z) {
315 Node node = cell.node(z);
316 if (new_uids.nodes[node] < 0) {
317 node_uids[z] += node_adder;
319 info() <<
"APPLY_NODE_CHILD: uid=" << node.uniqueId() <<
" parent_cell=" << cell.uniqueId()
320 <<
" I=" << z <<
" new_uid=" << node_uids[z];
321 new_uids.nodes[node] = node_uids[z];
328 if (cell.nbFace() != 4)
329 ARCANE_FATAL(
"Invalid number of faces N={0}, expected=4", cell.nbFace());
330 std::array<Int64, 4> face_uids;
331 face_uids[0] = (coord_i + 0) + ((coord_j + 0) * nb_face_x);
332 face_uids[1] = (coord_i + 1) + ((coord_j + 0) * nb_face_x);
333 face_uids[2] = (coord_i + 1) + ((coord_j + 1) * nb_face_x);
334 face_uids[3] = (coord_i + 0) + ((coord_j + 1) * nb_face_x);
335 for (Integer z = 0; z < 4; ++z) {
336 Face face = cell.face(z);
337 if (new_uids.faces[face] < 0) {
338 face_uids[z] += face_adder;
340 info() <<
"APPLY_FACE_CHILD: uid=" << face.uniqueId() <<
" parent_cell=" << cell.uniqueId()
341 <<
" I=" << z <<
" new_uid=" << face_uids[z];
342 new_uids.faces[face] = face_uids[z];
353 Int32 nb_child = cell.nbHChildren();
354 for (
Int32 icell = 0; icell < nb_child; ++icell) {
355 Cell sub_cell = cell.hChild(icell);
356 Int64 my_coord_i = coord_i + icell % 2;
357 Int64 my_coord_j = coord_j + icell / 2;
358 Int64 new_uid = (my_coord_i + my_coord_j * nb_cell_x) + cell_adder;
360 info() <<
"APPLY_CELL_CHILD: uid=" << sub_cell.uniqueId() <<
" I=" << my_coord_i <<
" J=" << my_coord_j
361 <<
" level=" << level <<
" new_uid=" << new_uid <<
" CellAdder=" << cell_adder;
363 _applyChildrenCell2D(sub_cell, new_uids, my_coord_i, my_coord_j,
364 nb_cell_x, nb_cell_y, level + 1, base_adder);
365 if (new_uids.cells[sub_cell] < 0)
366 new_uids.cells[sub_cell] = new_uid;
373void CartesianMeshUniqueIdRenumbering::
374_applyChildrenCell3D(Cell cell, NewUniqueIdList& new_uids,
376 Int64 current_level_nb_cell_x,
Int64 current_level_nb_cell_y,
Int64 current_level_nb_cell_z,
379 if (coord_i >= current_level_nb_cell_x)
380 ARCANE_FATAL(
"Bad coordinate X={0} max={1}", coord_i, current_level_nb_cell_x);
381 if (coord_j >= current_level_nb_cell_y)
382 ARCANE_FATAL(
"Bad coordinate Y={0} max={1}", coord_j, current_level_nb_cell_y);
383 if (coord_k >= current_level_nb_cell_z)
384 ARCANE_FATAL(
"Bad coordinate Z={0} max={1}", coord_k, current_level_nb_cell_z);
389 const Int64 current_level_nb_node_x = current_level_nb_cell_x + 1;
390 const Int64 current_level_nb_node_y = current_level_nb_cell_y + 1;
391 const Int64 current_level_nb_node_z = current_level_nb_cell_z + 1;
393 const Int64 current_level_nb_face_x = current_level_nb_cell_x + 1;
394 const Int64 current_level_nb_face_y = current_level_nb_cell_y + 1;
395 const Int64 current_level_nb_face_z = current_level_nb_cell_z + 1;
422 Int64 new_uid = (coord_i + coord_j * current_level_nb_cell_x + coord_k * current_level_nb_cell_x * current_level_nb_cell_y) + cell_adder;
423 if (new_uids.cells[cell] < 0) {
424 new_uids.cells[cell] = new_uid;
426 info() <<
"APPLY_CELL_CHILD: uid=" << cell.uniqueId() <<
" I=" << coord_i <<
" J=" << coord_j <<
" K=" << coord_k
427 <<
" current_level=" << current_level <<
" new_uid=" << new_uid <<
" CellAdder=" << cell_adder;
437 if (cell.nbNode() != 8)
438 ARCANE_FATAL(
"Invalid number of nodes N={0}, expected=8", cell.nbNode());
439 std::array<Int64, 8> node_uids;
440 node_uids[0] = (coord_i + 0) + ((coord_j + 0) * current_level_nb_node_x) + ((coord_k + 0) * current_level_nb_node_x * current_level_nb_node_y);
441 node_uids[1] = (coord_i + 1) + ((coord_j + 0) * current_level_nb_node_x) + ((coord_k + 0) * current_level_nb_node_x * current_level_nb_node_y);
442 node_uids[2] = (coord_i + 1) + ((coord_j + 1) * current_level_nb_node_x) + ((coord_k + 0) * current_level_nb_node_x * current_level_nb_node_y);
443 node_uids[3] = (coord_i + 0) + ((coord_j + 1) * current_level_nb_node_x) + ((coord_k + 0) * current_level_nb_node_x * current_level_nb_node_y);
445 node_uids[4] = (coord_i + 0) + ((coord_j + 0) * current_level_nb_node_x) + ((coord_k + 1) * current_level_nb_node_x * current_level_nb_node_y);
446 node_uids[5] = (coord_i + 1) + ((coord_j + 0) * current_level_nb_node_x) + ((coord_k + 1) * current_level_nb_node_x * current_level_nb_node_y);
447 node_uids[6] = (coord_i + 1) + ((coord_j + 1) * current_level_nb_node_x) + ((coord_k + 1) * current_level_nb_node_x * current_level_nb_node_y);
448 node_uids[7] = (coord_i + 0) + ((coord_j + 1) * current_level_nb_node_x) + ((coord_k + 1) * current_level_nb_node_x * current_level_nb_node_y);
450 for (Integer z = 0; z < 8; ++z) {
451 Node node = cell.node(z);
452 if (new_uids.nodes[node] < 0) {
453 node_uids[z] += node_adder;
455 info() <<
"APPLY_NODE_CHILD: uid=" << node.uniqueId() <<
" parent_cell=" << cell.uniqueId()
456 <<
" I=" << z <<
" new_uid=" << node_uids[z];
457 new_uids.nodes[node] = node_uids[z];
502 const Int64 total_face_xy = current_level_nb_face_z * current_level_nb_cell_x * current_level_nb_cell_y;
503 const Int64 total_face_xy_yz = total_face_xy + current_level_nb_face_x * current_level_nb_cell_y * current_level_nb_cell_z;
504 const Int64 total_face_xy_yz_zx = total_face_xy_yz + current_level_nb_face_y * current_level_nb_cell_z * current_level_nb_cell_x;
506 if (cell.nbFace() != 6)
507 ARCANE_FATAL(
"Invalid number of faces N={0}, expected=6", cell.nbFace());
508 std::array<Int64, 6> face_uids;
536 const Int64 nb_cell_before_j = coord_j * current_level_nb_cell_x;
538 face_uids[0] = (coord_k * current_level_nb_cell_x * current_level_nb_cell_y) + nb_cell_before_j + (coord_i);
540 face_uids[3] = face_uids[0] + current_level_nb_cell_x * current_level_nb_cell_y;
542 face_uids[1] = (coord_k * current_level_nb_face_x * current_level_nb_cell_y) + (coord_j * current_level_nb_face_x) + (coord_i) + total_face_xy;
544 face_uids[4] = face_uids[1] + 1;
546 face_uids[2] = (coord_k * current_level_nb_cell_x * current_level_nb_face_y) + nb_cell_before_j + (coord_i) + total_face_xy_yz;
548 face_uids[5] = face_uids[2] + current_level_nb_cell_x;
550 for (Integer z = 0; z < 6; ++z) {
551 Face face = cell.face(z);
552 if (new_uids.faces[face] < 0) {
553 face_uids[z] += face_adder;
555 info() <<
"APPLY_FACE_CHILD: uid=" << face.uniqueId() <<
" parent_cell=" << cell.uniqueId()
556 <<
" I=" << z <<
" new_uid=" << face_uids[z];
557 new_uids.faces[face] = face_uids[z];
569 cell_adder += current_level_nb_cell_x * current_level_nb_cell_y * current_level_nb_cell_z;
570 node_adder += current_level_nb_node_x * current_level_nb_node_y * current_level_nb_node_z;
571 face_adder += total_face_xy_yz_zx;
577 current_level_nb_cell_x *= 2;
578 current_level_nb_cell_y *= 2;
579 current_level_nb_cell_z *= 2;
583 Int32 nb_child = cell.nbHChildren();
584 for (
Int32 icell = 0; icell < nb_child; ++icell) {
585 Cell sub_cell = cell.hChild(icell);
586 Int64 my_coord_i = coord_i + icell % 2;
587 Int64 my_coord_j = coord_j + (icell % 4) / 2;
588 Int64 my_coord_k = coord_k + icell / 4;
590 _applyChildrenCell3D(sub_cell, new_uids, my_coord_i, my_coord_j, my_coord_k,
591 current_level_nb_cell_x, current_level_nb_cell_y, current_level_nb_cell_z,
592 current_level, cell_adder, node_adder, face_adder);
599void CartesianMeshUniqueIdRenumbering::
600_applyChildrenCell3DV2(Cell cell, NewUniqueIdList& new_uids,
602 Int64 current_level_nb_cell_x,
Int64 current_level_nb_cell_y,
Int64 current_level_nb_cell_z,
605 if (coord_i >= current_level_nb_cell_x)
606 ARCANE_FATAL(
"Bad coordinate X={0} max={1}", coord_i, current_level_nb_cell_x);
607 if (coord_j >= current_level_nb_cell_y)
608 ARCANE_FATAL(
"Bad coordinate Y={0} max={1}", coord_j, current_level_nb_cell_y);
609 if (coord_k >= current_level_nb_cell_z)
610 ARCANE_FATAL(
"Bad coordinate Z={0} max={1}", coord_k, current_level_nb_cell_z);
616 current_level_nb_cell_x *= 2;
617 current_level_nb_cell_y *= 2;
618 current_level_nb_cell_z *= 2;
620 CartesianGridDimension grid(current_level_nb_cell_x, current_level_nb_cell_y, current_level_nb_cell_z);
621 CartesianGridDimension::CellUniqueIdComputer3D cell_uid_computer(grid.getCellComputer3D(cell_adder));
622 CartesianGridDimension::FaceUniqueIdComputer3D face_uid_computer(grid.getFaceComputer3D(face_adder));
623 CartesianGridDimension::NodeUniqueIdComputer3D node_uid_computer(grid.getNodeComputer3D(node_adder));
628 Int64x3 grid_nb_node = grid.nbNode();
629 Int64x3 grid_nb_face = grid.nbFace();
633 Int64 new_uid = cell_uid_computer.compute(coord_i, coord_j, coord_k);
634 if (new_uids.cells[cell] < 0) {
635 new_uids.cells[cell] = new_uid;
637 info() <<
"APPLY_CELL_CHILD: uid=" << cell.uniqueId() <<
" I=" << coord_i <<
" J=" << coord_j <<
" K=" << coord_k
638 <<
" current_level=" << current_level <<
" new_uid=" << new_uid <<
" CellAdder=" << cell_adder;
642 static constexpr Int32 const_cell_nb_node = 8;
645 std::array<Int64, const_cell_nb_node> node_uids = node_uid_computer.computeForCell(coord_i, coord_j, coord_k);
647 for (Integer z = 0; z < const_cell_nb_node; ++z) {
648 Node node = cell.node(z);
649 if (new_uids.nodes[node] < 0) {
651 info() <<
"APPLY_NODE_CHILD: uid=" << node.uniqueId() <<
" parent_cell=" << cell.uniqueId()
652 <<
" I=" << z <<
" new_uid=" << node_uids[z];
653 new_uids.nodes[node] = node_uids[z];
702 std::array<Int64, 6> face_uids = face_uid_computer.computeForCell(coord_i, coord_j, coord_k);
704 for (Integer z = 0; z < 6; ++z) {
705 Face face = cell.face(z);
706 if (new_uids.faces[face] < 0) {
707 const bool do_print =
false;
709 info() <<
"Parent_cell=" << cell.uniqueId() <<
" level=" << cell.level()
710 <<
" face_adder=" << face_adder <<
" z=" << z
711 <<
" x=" << coord_i <<
" y=" << coord_j <<
" z=" << coord_k
712 <<
" cx=" << current_level_nb_cell_x <<
" cy=" << current_level_nb_cell_y <<
" cz=" << current_level_nb_cell_z;
714 if (m_is_verbose || do_print)
715 info() <<
"APPLY_FACE_CHILD: uid=" << face.uniqueId() <<
" parent_cell=" << cell.uniqueId()
716 <<
" I=" << z <<
" new_uid=" << face_uids[z];
717 new_uids.faces[face] = face_uids[z];
729 cell_adder += grid.totalNbCell();
730 node_adder += grid_nb_node.x * grid_nb_node.y * grid_nb_node.z;
731 face_adder += grid_nb_face.x * grid_nb_face.y * grid_nb_face.z;
735 Int32 nb_child = cell.nbHChildren();
736 for (
Int32 icell = 0; icell < nb_child; ++icell) {
737 Cell sub_cell = cell.hChild(icell);
738 Int64 my_coord_i = coord_i + icell % 2;
739 Int64 my_coord_j = coord_j + (icell % 4) / 2;
740 Int64 my_coord_k = coord_k + icell / 4;
742 _applyChildrenCell3DV2(sub_cell, new_uids, my_coord_i, my_coord_j, my_coord_k,
743 current_level_nb_cell_x, current_level_nb_cell_y, current_level_nb_cell_z,
744 current_level, cell_adder, node_adder, face_adder);
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
Fonctions utilitaires sur le maillage.
Patch AMR d'un maillage cartésien.
CellGroup cells()
Groupe de mailles du patch.
Informations sur la génération des maillages cartésiens.
Interface d'un maillage cartésien.
virtual IMesh * mesh() const =0
Maillage associé à ce maillage cartésien.
virtual ICartesianMeshPatch * patch(Int32 index) const =0
Retourne le index-ième patch du maillage.
virtual IItemFamily * nodeFamily()=0
Retourne la famille des noeuds.
virtual String name() const =0
Nom du maillage.
virtual Integer dimension()=0
Dimension du maillage (1D, 2D ou 3D).
virtual IItemFamily * faceFamily()=0
Retourne la famille des faces.
virtual IItemFamily * cellFamily()=0
Retourne la famille des mailles.
virtual IParallelMng * parallelMng()=0
Gestionnaire de parallèlisme.
virtual void checkValidMesh()=0
Vérification de la validité des structues internes de maillage (interne)
Interface du gestionnaire de parallélisme pour un sous-domaine.
virtual char reduce(eReduceType rt, char v)=0
Effectue la réduction de type rt sur le réel v et retourne la valeur.
ItemUniqueId uniqueId() const
Identifiant unique sur tous les domaines.
Lecteur des fichiers de maillage via la bibliothèque LIMA.
Paramètres nécessaires à la construction d'une variable.
Classe d'accès aux traces.
TraceMessage info() const
Flot pour un message d'information.
T max(const T &a, const T &b, const T &c)
Retourne le maximum de trois éléments.
ItemVariableScalarRefT< Int64 > VariableItemInt64
Grandeur de type entier 64 bits.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
ConstArrayView< Int64 > Int64ConstArrayView
Equivalent C d'un tableau à une dimension d'entiers 64 bits.