14#include "arcane/utils/TraceAccessor.h"
15#include "arcane/utils/NotImplementedException.h"
16#include "arcane/utils/AutoDestroyUserData.h"
17#include "arcane/utils/IUserDataList.h"
18#include "arcane/utils/Ref.h"
19#include "arcane/utils/ScopedPtr.h"
20#include "arcane/utils/PlatformUtils.h"
22#include "arcane/utils/Convert.h"
24#include "arcane/core/IMesh.h"
25#include "arcane/core/ItemPrinter.h"
26#include "arcane/core/IItemFamily.h"
27#include "arcane/core/IParallelMng.h"
28#include "arcane/core/VariableTypes.h"
29#include "arcane/core/Properties.h"
30#include "arcane/core/IMeshModifier.h"
31#include "arcane/core/MeshStats.h"
32#include "arcane/core/ICartesianMeshGenerationInfo.h"
33#include "arcane/core/MeshEvents.h"
34#include "arcane/core/MeshKind.h"
35#include "arcane/core/internal/IMeshInternal.h"
37#include "arcane/cartesianmesh/internal/CartesianPatchGroup.h"
38#include "arcane/cartesianmesh/ICartesianMesh.h"
39#include "arcane/cartesianmesh/AMRZonePosition.h"
40#include "arcane/cartesianmesh/CartesianConnectivity.h"
41#include "arcane/cartesianmesh/CartesianMeshRenumberingInfo.h"
42#include "arcane/cartesianmesh/CartesianMeshCoarsening.h"
43#include "arcane/cartesianmesh/CartesianMeshCoarsening2.h"
44#include "arcane/cartesianmesh/CartesianMeshPatchListView.h"
45#include "arcane/cartesianmesh/internal/CartesianMeshPatch.h"
46#include "arcane/cartesianmesh/internal/ICartesianMeshInternal.h"
48#include "arcane/cartesianmesh/internal/CartesianMeshUniqueIdRenumbering.h"
49#include "arcane/cartesianmesh/v2/CartesianMeshUniqueIdRenumberingV2.h"
50#include "arcane/cartesianmesh/CartesianMeshNumberingMng.h"
52#include "arcane/cartesianmesh/internal/CartesianMeshAMRPatchMng.h"
53#include "arcane/core/IGhostLayerMng.h"
54#include "arcane/cartesianmesh/internal/CartesianMeshNumberingMngInternal.h"
79class CartesianMeshImpl
88 explicit InternalApi(CartesianMeshImpl* cartesian_mesh)
89 : m_cartesian_mesh(cartesian_mesh)
97 return m_cartesian_mesh->_createCartesianMeshCoarsening2();
101 m_cartesian_mesh->_addPatchFromExistingChildren(parent_cells_local_id);
105 if (m_numbering_mng.isNull()) {
108 if (m_amr_mng.isNull()) {
118 if (m_numbering_mng.isNull()) {
124 return m_numbering_mng;
132 CartesianMeshImpl* m_cartesian_mesh =
nullptr;
143 void build()
override;
153 return m_all_items_direction_info->cellDirection(dir);
158 return m_all_items_direction_info->cellDirection(idir);
163 return m_all_items_direction_info->faceDirection(dir);
168 return m_all_items_direction_info->faceDirection(idir);
173 return m_all_items_direction_info->nodeDirection(dir);
178 return m_all_items_direction_info->nodeDirection(idir);
187 return m_connectivity;
214 void computeDirectionsPatchV2(
Integer index)
override;
222 void _computeDirectionsV2();
226 InternalApi m_internal_api;
230 IMesh* m_mesh =
nullptr;
236 bool m_is_amr =
false;
242 bool m_is_mesh_event_added =
false;
243 Int64 m_mesh_timestamp = 0;
262 void _saveInfosInProperties();
264 std::tuple<CellGroup, NodeGroup>
266 void _checkNeedComputeDirections();
267 void _checkAddObservableMeshChanged();
285CartesianMeshImpl(IMesh* mesh)
286: TraceAccessor(mesh->traceMng())
287, m_internal_api(this)
289, m_nodes_to_cell_storage(platform::getDefaultDataAllocator())
290, m_cells_to_node_storage(platform::getDefaultDataAllocator())
291, m_permutation_storage(platform::getDefaultDataAllocator())
293, m_amr_type(mesh->meshKind().meshAMRKind())
296 m_internal_api.initCartesianMeshNumberingMngInternal();
297 m_internal_api.initCartesianMeshAMRPatchMng();
299 m_all_items_direction_info = m_patch_group.groundPatch();
305void CartesianMeshImpl::
308 m_properties =
new Properties(*(mesh()->properties()),
"CartesianMesh");
309 if (m_amr_type == eMeshAMRKind::PatchCartesianMeshOnly) {
310 m_internal_api.cartesianMeshNumberingMngInternal()->build();
312 m_patch_group.build();
317 const Int32 SERIALIZE_VERSION = 1;
323void CartesianMeshImpl::
324_checkNeedComputeDirections()
326 Int64 new_timestamp = mesh()->timestamp();
327 if (m_mesh_timestamp != new_timestamp) {
328 info() <<
"Le horodatage du maillage a changé (ancien=" << m_mesh_timestamp <<
" nouveau=" << new_timestamp <<
")";
336void CartesianMeshImpl::
337_saveInfosInProperties()
340 m_properties->set(
"Version", SERIALIZE_VERSION);
342 m_patch_group.saveInfosInProperties();
344 if (m_amr_type == eMeshAMRKind::PatchCartesianMeshOnly) {
345 m_internal_api.cartesianMeshNumberingMngInternal()->saveInfosInProperties();
353void CartesianMeshImpl::
356 info() <<
"Création des infos 'CartesianMesh' à partir du dump";
359 m_internal_api.cartesianMeshNumberingMngInternal()->recreateFromDump();
360 m_internal_api.cartesianMeshNumberingMngInternal()->printStatus();
364 Int32 v = m_properties->getInt32(
"Version");
365 if (v != SERIALIZE_VERSION)
366 ARCANE_FATAL(
"Mauvaise version de sérialisation : tentative de lecture à partir d'un point de contrôle incompatible v={0} attendu={1}",
367 v, SERIALIZE_VERSION);
379void CartesianMeshImpl::
380_checkAddObservableMeshChanged()
382 if (m_is_mesh_event_added)
384 m_is_mesh_event_added =
true;
387 auto f1 = [&](
const MeshEventArgs&) { this->_checkNeedComputeDirections(); };
388 mesh()->eventObservable(eMeshEventType::EndPrepareDump).attach(m_event_pool, f1);
394void CartesianMeshImpl::
399 m_internal_api.cartesianMeshNumberingMngInternal()->renumberingFacesLevel0FromOriginalArcaneNumbering();
400 _computeDirectionsV2();
403 info() <<
"CartesianMesh: computeDirections()";
405 m_mesh_timestamp =
mesh()->timestamp();
406 _checkAddObservableMeshChanged();
408 m_is_amr = m_mesh->isAmrActivated();
418 for (NodeLocalId inode : cell.
nodeIds())
419 center += nodes_coord[inode];
421 cells_center[icell] = center;
426 for (NodeLocalId inode : face.
nodeIds())
427 center += nodes_coord[inode];
429 faces_center[iface] = center;
434 Int32 next_face_x = -1;
435 Int32 next_face_y = -1;
436 Int32 next_face_z = -1;
439 Cell cell0 = cell_view[0];
442 Real3 cell_center = cells_center[cell0];
449 info(4) <<
"Cartesian mesh compute directions is_amr=" << m_is_amr;
451 for (
Integer i = 0; i < nb_node; ++i) {
453 info(4) <<
"Nœud I=" << i <<
" nœud=" <<
ItemPrinter(node) <<
" pos=" << nodes_coord[node];
456 bool is_3d = m_mesh->dimension() == 3;
466 for (
Integer i = 0; i < nb_face; ++i) {
469 Real3 next_center = faces_center[f];
471 Real diff_x = next_center.
x - cell_center.
x;
472 Real diff_y = next_center.
y - cell_center.
y;
473 Real diff_z = next_center.
z - cell_center.
z;
475 info(4) <<
"FACE_SUIVANTE=" <<
ItemPrinter(f) <<
" centre=" << next_center <<
" diff=" <<
Real3(diff_x, diff_y, diff_z);
477 if (diff_x > max_x) {
482 if (diff_y > max_y) {
487 if (diff_z > max_z) {
492 info(4) <<
"Avancement dans la direction X -> " << next_face_x;
493 info(4) <<
"Avancement dans la direction Y -> " << next_face_y;
494 info(4) <<
"Avancement dans la direction Z -> " << next_face_z;
500 for (
Integer i = 0; i < nb_face; ++i) {
503 Real3 next_center = faces_center[f];
505 Real diff_x = next_center.
x - cell_center.
x;
506 Real diff_y = next_center.
y - cell_center.
y;
508 info(4) <<
"FACE_SUIVANTE=" <<
ItemPrinter(f) <<
" centre=" << next_center <<
" diff=" <<
Real2(diff_x, diff_y);
510 if (diff_x > max_x) {
515 if (diff_y > max_y) {
520 info(4) <<
"Avancement dans la direction X -> " << next_face_x;
521 info(4) <<
"Avancement dans la direction Y -> " << next_face_y;
523 m_all_items_direction_info->_internalComputeNodeCellInformations(cell0, cells_center[cell0], nodes_coord);
525 info() <<
"Informations des propriétés IMesh:";
527 auto* cmgi = ICartesianMeshGenerationInfo::getReference(m_mesh,
true);
529 info() <<
"GlobalNbCell = " << cmgi->globalNbCells();
530 info() <<
"OwnNbCell: " << cmgi->ownNbCells();
531 info() <<
"SubDomainOffset: " << cmgi->subDomainOffsets();
532 info() <<
"OwnCellOffset: " << cmgi->ownCellOffsets();
537 auto x = _buildPatchGroups(
mesh()->allLevelCells(0), 0);
538 all_cells = std::get<0>(x);
539 all_nodes = std::get<1>(x);
542 if (next_face_x != (-1)) {
544 _computeMeshDirection(*m_all_items_direction_info.get(),
MD_DirX, cells_center, faces_center, all_cells, all_nodes);
546 if (next_face_y != (-1)) {
548 _computeMeshDirection(*m_all_items_direction_info.get(),
MD_DirY, cells_center, faces_center, all_cells, all_nodes);
550 if (next_face_z != (-1)) {
552 _computeMeshDirection(*m_all_items_direction_info.get(),
MD_DirZ, cells_center, faces_center, all_cells, all_nodes);
556 for (
Integer idir = 0, nb_dir =
mesh()->dimension(); idir < nb_dir; ++idir) {
558 cdm._internalSetOffsetAndNbCellInfos(cmgi->globalNbCells()[idir], cmgi->ownNbCells()[idir],
559 cmgi->subDomainOffsets()[idir], cmgi->ownCellOffsets()[idir]);
562 info() <<
"Calcul de la connectivité cartésienne";
564 m_permutation_storage.resize(1);
565 m_permutation_storage[0].compute();
566 m_nodes_to_cell_storage.resize(
mesh()->nodeFamily()->maxLocalId());
567 m_cells_to_node_storage.resize(
mesh()->cellFamily()->maxLocalId());
568 m_connectivity._setStorage(m_nodes_to_cell_storage, m_cells_to_node_storage, &m_permutation_storage[0]);
569 m_connectivity._computeInfos(
mesh(), nodes_coord, cells_center);
576 info() <<
"Nom du patch AMR=" << cells.
name() <<
" taille=" << cells.
size() <<
" index=" << patch_index <<
" nbPatch=" <<
m_patch_group.nbPatch();
577 patch->_internalComputeNodeCellInformations(cell0, cells_center[cell0], nodes_coord);
578 auto [patch_cells, patch_nodes] = _buildPatchGroups(cells, patch_index);
579 _computeMeshDirection(*
patch.get(),
MD_DirX, cells_center, faces_center, patch_cells, patch_nodes);
580 _computeMeshDirection(*
patch.get(),
MD_DirY, cells_center, faces_center, patch_cells, patch_nodes);
582 _computeMeshDirection(*
patch.get(),
MD_DirZ, cells_center, faces_center, patch_cells, patch_nodes);
588 _saveInfosInProperties();
594std::tuple<CellGroup, NodeGroup> CartesianMeshImpl::
607 String cell_group_name =
String(
"AMRPatchCells") + patch_level;
612 String node_group_name =
String(
"AMRPatchNodes") + patch_level;
616 info(4) <<
"PATCH_CELLS nom=" << patch_cells.
name() <<
" taille=" << patch_cells.
size();
617 info(4) <<
"PATCH_NODES nom=" << patch_nodes.
name() <<
" taille=" << patch_nodes.
size();
618 return { patch_cells, patch_nodes };
624void CartesianMeshImpl::
625_computeMeshDirection(CartesianMeshPatch& cdi, eMeshDirection dir, VariableCellReal3& cells_center,
626 VariableFaceReal3& faces_center, CellGroup all_cells, NodeGroup all_nodes)
628 IItemFamily* cell_family = m_mesh->cellFamily();
629 IItemFamily* face_family = m_mesh->faceFamily();
630 IItemFamily* node_family = m_mesh->nodeFamily();
632 Int32 max_cell_id = cell_family->
maxLocalId();
633 Int32 max_face_id = face_family->maxLocalId();
634 Int32 max_node_id = node_family->maxLocalId();
636 CellDirectionMng& cell_dm = cdi.cellDirection(dir);
637 cell_dm._internalResizeInfos(max_cell_id);
639 FaceDirectionMng& face_dm = cdi.faceDirection(dir);
640 face_dm._internalResizeInfos(max_face_id);
642 NodeDirectionMng& node_dm = cdi.nodeDirection(dir);
643 node_dm._internalResizeInfos(max_node_id);
646 info(4) <<
"COMPUTE DIRECTION dir=" << dir;
648 Int32 prev_local_face = -1;
649 Int32 next_local_face = m_local_face_direction[dir];
650 Integer mesh_dim = m_mesh->dimension();
653 prev_local_face = (next_local_face + 2) % 4;
654 else if (mesh_dim == 3)
655 prev_local_face = (next_local_face + 3) % 6;
657 cell_dm._internalSetLocalFaceIndex(next_local_face, prev_local_face);
661 std::set<Int32> cells_set;
663 cells_set.insert(icell.itemLocalId());
670 Int32 my_level = cell.level();
671 Face next_face = cell.face(next_local_face);
672 Cell next_cell = next_face.backCell() == cell ? next_face.frontCell() : next_face.backCell();
673 if (cells_set.find(next_cell.localId()) == cells_set.end())
675 else if (next_cell.level() != my_level)
678 Face prev_face = cell.face(prev_local_face);
679 Cell prev_cell = prev_face.backCell() == cell ? prev_face.frontCell() : prev_face.backCell();
680 if (cells_set.find(prev_cell.localId()) == cells_set.end())
682 else if (prev_cell.level() != my_level)
684 cell_dm.m_infos_view[icell.itemLocalId()] = CellDirectionMng::ItemDirectionInfo(next_cell, prev_cell);
686 cell_dm._internalComputeInnerAndOuterItems(all_cells);
687 face_dm._internalComputeInfos(cell_dm, cells_center, faces_center);
688 node_dm._internalComputeInfos(cell_dm, all_nodes, cells_center);
694void CartesianMeshImpl::
695_computeDirectionsV2()
697 info() <<
"CartesianMesh: computeDirectionsV2()";
699 m_mesh_timestamp = mesh()->timestamp();
700 _checkAddObservableMeshChanged();
702 m_is_amr = m_mesh->isAmrActivated();
704 if (m_mesh->dimension() == 3) {
705 m_local_face_direction[
MD_DirX] = 4;
706 m_local_face_direction[
MD_DirY] = 5;
707 m_local_face_direction[
MD_DirZ] = 3;
710 m_local_face_direction[
MD_DirX] = 1;
711 m_local_face_direction[
MD_DirY] = 2;
714 info() <<
"Compute cartesian connectivity";
716 m_permutation_storage.resize(1);
717 m_permutation_storage[0].compute();
718 m_nodes_to_cell_storage.resize(mesh()->nodeFamily()->maxLocalId());
719 m_cells_to_node_storage.resize(mesh()->cellFamily()->maxLocalId());
720 m_connectivity._setStorage(m_nodes_to_cell_storage, m_cells_to_node_storage, &m_permutation_storage[0]);
721 m_connectivity._computeInfos(
this);
724 for (Integer patch_index = 0; patch_index < m_patch_group.nbPatch(); ++patch_index) {
725 computeDirectionsPatchV2(patch_index);
731 _saveInfosInProperties();
737void CartesianMeshImpl::
738computeDirectionsPatchV2(Integer patch_index)
740 bool is_3d = m_mesh->dimension() == 3;
742 CellGroup cells = m_patch_group.allCells(patch_index);
743 Ref<CartesianMeshPatch> patch = m_patch_group.patch(patch_index);
745 if (patch->index() == -1) {
746 auto* cmgi = ICartesianMeshGenerationInfo::getReference(m_mesh,
true);
747 info() <<
"Informations depuis les propriétés IMesh:";
748 info() <<
"GlobalNbCell = " << cmgi->globalNbCells();
749 info() <<
"OwnNbCell: " << cmgi->ownNbCells();
750 info() <<
"SubDomainOffset: " << cmgi->subDomainOffsets();
751 info() <<
"OwnCellOffset: " << cmgi->ownCellOffsets();
753 for (Integer idir = 0, nb_dir = mesh()->dimension(); idir < nb_dir; ++idir) {
754 CellDirectionMng& cdm = m_all_items_direction_info->cellDirection(idir);
755 cdm._internalSetOffsetAndNbCellInfos(cmgi->globalNbCells()[idir], cmgi->ownNbCells()[idir],
756 cmgi->subDomainOffsets()[idir], cmgi->ownCellOffsets()[idir]);
760 info() <<
"Nom du patch AMR=" << cells.
name() <<
" taille=" << cells.size() <<
" index=" << patch_index <<
" trueindex=" << patch->index() <<
" nbPatch=" << m_patch_group.nbPatch();
762 const AMRPatchPosition position = patch->position();
763 info() <<
" position min=" << position.minPoint() <<
" max=" << position.maxPoint() <<
" level=" << position.level() <<
" overlapLayerSize=" << position.overlapLayerSize();
765 patch->_internalComputeNodeCellInformations();
766 auto [patch_cells, patch_nodes] = _buildPatchGroups(cells, patch_index);
767 _computeMeshDirectionV2(*patch.get(), MD_DirX, m_patch_group.allCells(patch_index), m_patch_group.inPatchCells(patch_index), m_patch_group.overlapCells(patch_index), patch_nodes);
768 _computeMeshDirectionV2(*patch.get(), MD_DirY, m_patch_group.allCells(patch_index), m_patch_group.inPatchCells(patch_index), m_patch_group.overlapCells(patch_index), patch_nodes);
770 _computeMeshDirectionV2(*patch.get(), MD_DirZ, m_patch_group.allCells(patch_index), m_patch_group.inPatchCells(patch_index), m_patch_group.overlapCells(patch_index), patch_nodes);
776void CartesianMeshImpl::
777_computeMeshDirectionV2(CartesianMeshPatch& cdi, eMeshDirection dir, CellGroup all_cells, CellGroup in_patch_cells, CellGroup overlap_cells, NodeGroup all_nodes)
779 IItemFamily* cell_family = m_mesh->cellFamily();
780 IItemFamily* face_family = m_mesh->faceFamily();
781 IItemFamily* node_family = m_mesh->nodeFamily();
783 Int32 max_cell_id = cell_family->maxLocalId();
784 Int32 max_face_id = face_family->maxLocalId();
785 Int32 max_node_id = node_family->maxLocalId();
787 CellDirectionMng& cell_dm = cdi.cellDirection(dir);
788 cell_dm._internalResizeInfos(max_cell_id);
790 FaceDirectionMng& face_dm = cdi.faceDirection(dir);
791 face_dm._internalResizeInfos(max_face_id);
793 NodeDirectionMng& node_dm = cdi.nodeDirection(dir);
794 node_dm._internalResizeInfos(max_node_id);
797 info(4) <<
"COMPUTE DIRECTION dir=" << dir;
799 Int32 prev_local_face = -1;
800 Int32 next_local_face = m_local_face_direction[dir];
801 Integer mesh_dim = m_mesh->dimension();
804 prev_local_face = (next_local_face + 2) % 4;
805 else if (mesh_dim == 3)
806 prev_local_face = (next_local_face + 3) % 6;
808 cell_dm._internalSetLocalFaceIndex(next_local_face, prev_local_face);
812 std::set<Int32> cells_set;
814 cells_set.insert(icell.itemLocalId());
821 Int32 my_level = cell.level();
822 Face next_face = cell.face(next_local_face);
823 Cell next_cell = next_face.backCell() == cell ? next_face.frontCell() : next_face.backCell();
824 if (!cells_set.contains(next_cell.localId()) || next_cell.level() != my_level) {
828 Face prev_face = cell.face(prev_local_face);
829 Cell prev_cell = prev_face.backCell() == cell ? prev_face.frontCell() : prev_face.backCell();
830 if (!cells_set.contains(prev_cell.localId()) || prev_cell.level() != my_level) {
834 cell_dm.m_infos_view[icell.itemLocalId()] = CellDirectionMng::ItemDirectionInfo(next_cell, prev_cell);
836 cell_dm._internalComputeCellGroups(all_cells, in_patch_cells, overlap_cells);
837 face_dm._internalComputeInfos(cell_dm);
838 node_dm._internalComputeInfos(cell_dm, all_nodes);
844void CartesianMeshImpl::
847 info() <<
"REFINEMENT 2D position=" << position <<
" length=" << length;
854void CartesianMeshImpl::
857 info() <<
"REFINEMENT 3D position=" << position <<
" length=" << length;
864void CartesianMeshImpl::
867 _applyRefine(position);
868 _saveInfosInProperties();
874void CartesianMeshImpl::
877 info() <<
"COARSEN 2D position=" << position <<
" length=" << length;
884void CartesianMeshImpl::
887 info() <<
"COARSEN 3D position=" << position <<
" length=" << length;
894void CartesianMeshImpl::
897 _applyCoarse(position);
898 _saveInfosInProperties();
908 ARCANE_FATAL(
"Vous ne pouvez pas réduire le nombre de couches fantômes du niveau 0 avec cette méthode");
912 const Int32 max_nb_layer = 128;
916 level_max = std::max(level_max, icell->level());
924 Integer level_0_nb_ghost_layer = m_mesh->ghostLayerMng()->nbGhostLayer();
927 if (level_0_nb_ghost_layer == 0) {
936 if (target_nb_ghost_layers % 2 != 0) {
937 target_nb_ghost_layers++;
940 if (target_nb_ghost_layers == nb_ghost_layer) {
941 return nb_ghost_layer;
946 Integer parent_level = level - 1;
947 Integer parent_target_nb_ghost_layer = target_nb_ghost_layers / 2;
953 std::function<void(
Cell)> children_list;
955 children_list = [&cell_lid2, &children_list](
Cell cell) ->
void {
956 for (
Integer i = 0; i < cell.nbHChildren(); ++i) {
958 cell_lid2[cell.level()].
add(cell.hChild(i).localId());
959 children_list(cell.hChild(i));
972 Cell front_cell = iface->frontCell();
973 Cell back_cell = iface->backCell();
975 ((front_cell.
null() || (!front_cell.
isOwn() && front_cell.
level() == parent_level)) && ((!back_cell.
null()) && (back_cell.
isOwn() && back_cell.
level() == parent_level))) ||
976 ((back_cell.
null() || (!back_cell.
isOwn() && back_cell.
level() == parent_level)) && ((!front_cell.
null()) && (front_cell.
isOwn() && front_cell.
level() == parent_level)))) {
977 for (
Node node : iface->nodes()) {
978 level_node[node] = 0;
984 bool is_modif =
true;
985 Int32 current_layer = 0;
990 if (icell->isOwn() || icell->level() != parent_level || level_cell[icell] != -1) {
994 Int32 min = max_nb_layer;
997 for (
Node node : icell->nodes()) {
998 Int32 nlevel = level_node[node];
1000 min = std::min(min, nlevel);
1001 max = std::max(max, nlevel);
1006 if (min != current_layer) {
1011 if (min == max_nb_layer && max == -1) {
1015 Integer new_level = ((min == max) ? min + 1 : max);
1017 for (
Node node : icell->nodes()) {
1018 Int32 nlevel = level_node[node];
1020 level_node[node] = new_level;
1026 level_cell[icell] = min;
1031 if (min >= parent_target_nb_ghost_layer) {
1032 children_list(*icell);
1036 if (current_layer >= max_nb_layer) {
1037 ARCANE_FATAL(
"Erreur dans l'algorithme du compteur de couches fantômes. Signalez-le s'il vous plaît.");
1042 for (
Integer i = level_max - 1; i >= 0; --i) {
1049 m_mesh->modifier()->flagCellToCoarsen(cell_lid2[i]);
1050 m_mesh->modifier()->coarsenItemsV2(
false);
1053 info() <<
"Nb de couches fantômes pour le niveau " << level <<
" : " << target_nb_ghost_layers;
1055 return target_nb_ghost_layers;
1061void CartesianMeshImpl::
1064 _addPatch(parent_cells_local_id);
1072void CartesianMeshImpl::
1080 for (
Int32 cell_local_id : parent_cells) {
1081 Cell c = cells[cell_local_id];
1094void CartesianMeshImpl::
1102 info(4) <<
"Local_NbCellToRefine = " << nb_cell;
1106 info(4) <<
"Global_NbCellToRefine = " << total_nb_cell;
1107 if (total_nb_cell == 0)
1110 debug() <<
"Raffine avec modifier() (pour tous les types de maillage)";
1111 m_mesh->modifier()->flagCellToRefine(cells_local_id);
1112 m_mesh->modifier()->adapt();
1114 _addPatch(cells_local_id);
1117 else if (m_amr_type == eMeshAMRKind::PatchCartesianMeshOnly) {
1118 debug() <<
"Raffine avec un raffineur spécifique (pour maillage cartésien uniquement)";
1119 m_patch_group.addPatch(position);
1122 else if (m_amr_type == eMeshAMRKind::Patch) {
1123 ARCANE_FATAL(
"L'AMR de patch général n'est pas implémenté. Veuillez utiliser PatchCartesianMeshOnly (3)");
1130 MeshStats ms(traceMng(), m_mesh, m_mesh->parallelMng());
1138void CartesianMeshImpl::
1139_applyCoarse(
const AMRZonePosition& zone_position)
1141 if (m_amr_type == eMeshAMRKind::Cell) {
1142 UniqueArray<Int32> cells_local_id;
1144 zone_position.cellsInPatch(mesh(), cells_local_id);
1146 Integer nb_cell = cells_local_id.size();
1147 info(4) <<
"Local_NbCellToCoarsen = " << nb_cell;
1149 IParallelMng* pm = m_mesh->parallelMng();
1150 Int64 total_nb_cell = pm->
reduce(Parallel::ReduceSum, nb_cell);
1151 info(4) <<
"Global_NbCellToCoarsen = " << total_nb_cell;
1152 if (total_nb_cell == 0)
1155 debug() <<
"Coarsening avec modifier() (pour tous les types de maillage)";
1156 m_patch_group.removeCellsInAllPatches(cells_local_id);
1158 m_mesh->modifier()->flagCellToCoarsen(cells_local_id);
1159 m_mesh->modifier()->coarsenItemsV2(
true);
1162 else if (m_amr_type == eMeshAMRKind::PatchCartesianMeshOnly) {
1163 debug() <<
"Coarsening avec un grossisseur spécifique (pour maillage cartésien uniquement)";
1164 m_patch_group.removeCellsInZone(zone_position);
1167 else if (m_amr_type == eMeshAMRKind::Patch) {
1168 ARCANE_FATAL(
"L'AMR de patch général n'est pas implémenté. Veuillez utiliser PatchCartesianMeshOnly (3)");
1175 MeshStats ms(traceMng(), m_mesh, m_mesh->parallelMng());
1183void CartesianMeshImpl::
1186 info(4) <<
"Vérification du maillage cartésien valide";
1188 for (
Integer i = 0; i < nb_patch; ++i) {
1197void CartesianMeshImpl::
1200 auto* cmgi = ICartesianMeshGenerationInfo::getReference(m_mesh,
true);
1203 Int32 face_method = v.renumberFaceMethod();
1204 if (face_method != 0 && face_method != 1)
1205 ARCANE_FATAL(
"Valeur '{0}' invalide pour renumberFaceMethod(). Les valeurs valides sont 0 ou 1",
1207 if (face_method == 1)
1211 Int32 patch_method = v.renumberPatchMethod();
1212 if (patch_method < 0 || patch_method > 4) {
1213 ARCANE_FATAL(
"Valeur '{0}' invalide pour renumberPatchMethod(). Les valeurs valides sont 0, 1, 2, 3 ou 4",
1217 ARCANE_FATAL(
"La renumérotation des éléments du maillage n'est pas compatible avec ce type d'AMR");
1220 if (patch_method == 1 || patch_method == 3 || patch_method == 4) {
1222 renumberer.renumber();
1224 else if (patch_method == 2) {
1225 warning() <<
"La méthode de patch 2 est expérimentale !";
1227 renumberer.renumber();
1231 if (v.isSortAfterRenumbering()) {
1232 info() <<
"Compactage et tri après renumérotation";
1233 m_mesh->nodeFamily()->compactItems(
true);
1234 m_mesh->faceFamily()->compactItems(
true);
1235 m_mesh->cellFamily()->compactItems(
true);
1244createCartesianMeshCoarsening()
1253_createCartesianMeshCoarsening2()
1269 const char* name =
"CartesianMesh";
1278 ARCANE_FATAL(
"Le maillage {0} n'a pas encore été créé", h.meshName());
1285 mesh->_internalApi()->setMeshKind(mk);
1291 ARCANE_FATAL(
"Impossible de caster en ICartesianMesh*");
1292 return adud->data();
#define ARCANE_THROW(exception_class,...)
Macro pour envoyer une exception avec formattage.
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
Fichier contenant les mécanismes de gestion des évènements.
Classe permettant de définir une zone d'un maillage.
void cellsInPatch(IMesh *mesh, UniqueArray< Int32 > &cells_local_id) const
Méthode permettant de retrouver les mailles incluses dans la zone.
Integer size() const
Nombre d'éléments du vecteur.
void add(ConstReferenceType val)
Ajoute l'élément val à la fin du tableau.
UserData s'auto-détruisant une fois détaché.
Informations de connectivité d'un maillage cartésien.
Déraffine un maillage cartésien par 2.
Déraffine un maillage cartésien par 2.
void initCartesianMeshNumberingMngInternal() override
Méthode permettant de créer une instance de CartesianMeshNumberingMngInternal.
Ref< ICartesianMeshNumberingMngInternal > cartesianMeshNumberingMngInternal() override
Méthode permettant de récupérer l'instance de CartesianMeshNumberingMngInternal.
void addPatchFromExistingChildren(ConstArrayView< Int32 > parent_cells_local_id) override
Créé un patch avec tous les enfants des mailles parent_cells_local_id.
Ref< ICartesianMeshAMRPatchMng > cartesianMeshAMRPatchMng() override
Méthode permettant de récupérer l'instance de CartesianMeshAMRPatchMng.
Ref< CartesianMeshCoarsening2 > createCartesianMeshCoarsening2() override
Créé une instance pour gérer le déraffinement du maillage (V2).
void saveInfosInProperties() override
Méthode permettant de lancer la sauvegarde pour reprise.
void initCartesianMeshAMRPatchMng() override
Méthode permettant de créer une instance de CartesianMeshAMRPatchMng.
CartesianPatchGroup & cartesianPatchGroup() override
Méthode permettant de récupérer le CartesianPatchGroup.
Informations spécifiques pour un maillage cartésien.
void refinePatch3D(Real3 position, Real3 length) override
Raffine en 3D un bloc du maillage cartésien.
Int32 nbPatch() const override
Nombre de patchs du maillage.
Integer reduceNbGhostLayers(Integer level, Integer target_nb_ghost_layers) override
Méthode permettant de supprimer une ou plusieurs couches de mailles fantômes sur un niveau de raffine...
CartesianPatchGroup m_patch_group
Groupe de mailles pour chaque patch AMR.
void refinePatch(const AMRZonePosition &position) override
Raffine un bloc du maillage cartésien.
ITraceMng * traceMng() const override
Gestionnaire de traces associé.
CellDirectionMng cellDirection(Integer idir) override
Liste des mailles dans la direction dir (0, 1 ou 2).
void recreateFromDump() override
Recalcule les informations de cartésiennes après une reprise.
void computeDirections() override
Calcule les infos pour les accès par direction.
FaceDirectionMng faceDirection(Integer idir) override
Liste des faces dans la direction dir (0, 1 ou 2).
void coarseZone(const AMRZonePosition &position) override
Dé-raffine un bloc du maillage cartésien.
NodeDirectionMng nodeDirection(Integer idir) override
Liste des noeuds dans la direction dir (0, 1 ou 2).
Int32 m_local_face_direction[3]
Indice dans la numérotation locale de la maille, de la face dans.
void checkValid() const override
Effectue des vérifications sur la validité de l'instance.
IMesh * mesh() const override
Maillage associé à ce maillage cartésien.
FaceDirectionMng faceDirection(eMeshDirection dir) override
Liste des faces dans la direction dir.
NodeDirectionMng nodeDirection(eMeshDirection dir) override
Liste des noeuds dans la direction dir.
void refinePatch2D(Real2 position, Real2 length) override
Raffine en 2D un bloc du maillage cartésien.
ICartesianMeshPatch * patch(Int32 index) const override
Retourne le index-ième patch du maillage.
void coarseZone2D(Real2 position, Real2 length) override
Dé-raffine en 2D un bloc du maillage cartésien.
void renumberItemsUniqueId(const CartesianMeshRenumberingInfo &v) override
Renumérote les uniqueId() des entités.
ICartesianMeshInternal * _internalApi() override
API interne à Arcane.
void coarseZone3D(Real3 position, Real3 length) override
Dé-raffine en 3D un bloc du maillage cartésien.
Ref< CartesianMeshCoarsening > createCartesianMeshCoarsening() override
Créé une instance pour gérer le déraffinement du maillage.
CartesianPatch amrPatch(Int32 index) const override
Retourne le index-ième patch du maillage.
CellDirectionMng cellDirection(eMeshDirection dir) override
Liste des mailles dans la direction dir.
void _addPatch(ConstArrayView< Int32 > parent_cells)
Crée un patch avec tous les enfants du groupe parent_cells.
CartesianMeshPatchListView patches() const override
Vue sur la liste des patchs.
CartesianConnectivity connectivity() override
Informations sur la connectivité
Vue sur une liste de patchs.
Informations par direction pour chaque genre d'entité du maillage.
Informations pour la renumérotation.
Renumérotation des uniqueId() pour les maillages cartésiens.
Renumérotation des uniqueId() pour les maillages cartésiens.
Patch AMR d'un maillage cartésien.
Infos sur les mailles d'une direction spécifique X,Y ou Z d'un maillage structuré.
Vue sur les informations des mailles.
Int32 nbHChildren() const
Nombre d'enfants pour l'AMR.
Face face(Int32 i) const
i-ème face de la maille
Int32 nbFace() const
Nombre de faces de la maille.
Cell hChild(Int32 i) const
i-ème enfant AMR
Vue constante d'un tableau de type T.
Conserve des références d'observateurs.
Infos sur les face d'une direction spécifique X,Y ou Z d'un maillage structuré.
Partie interne de ICartesianMesh.
Interface d'un patch AMR d'un maillage cartésien.
virtual void checkValid() const =0
Effectue des vérifications sur la validité de l'instance.
Interface d'un maillage cartésien.
virtual IMesh * mesh() const =0
Maillage associé à ce maillage cartésien.
Interface d'une famille d'entités.
virtual ItemGroup allItems() const =0
Groupe de toutes les entités.
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 Int32 maxLocalId() const =0
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.
Interface du gestionnaire de traces.
Interface d'une liste qui gère des données utilisateurs.
virtual void setData(const String &name, IUserData *ud)=0
Positionne le user-data associé au nom name.
virtual IUserData * data(const String &name, bool allow_null=false) const =0
Donnée associée à name.
Interface pour une donnée utilisateur attachée à un autre objet.
Classe de base d'une vue sur une connectivité non structurée.
NodeGroup nodeGroup() const
Groupe des noeuds des éléments de ce groupe.
const String & name() const
Nom du groupe.
ItemVectorView view() const
Vue sur les entités du groupe.
Integer size() const
Nombre d'éléments du groupe.
IItemFamily * itemFamily() const
Famille d'entité à laquelle appartient ce groupe (0 pour le group nul).
void setItems(Int32ConstArrayView items_local_id)
Positionne les entités du groupe.
Classe utilitaire pour imprimer les infos sur une entité.
Int32ConstArrayView localIds() const
Tableau des numéros locaux des entités.
Node node(Int32 i) const
i-ème noeud de l'entité
Int32 nbNode() const
Nombre de noeuds de l'entité
NodeLocalIdView nodeIds() const
Liste des noeuds de l'entité
constexpr Int32 localId() const
Identifiant local de l'entité dans le sous-domaine du processeur.
constexpr bool null() const
true si l'entité est nul (i.e. non connecté au maillage)
constexpr bool isOwn() const
true si l'entité est appartient au sous-domaine
Arguments des évènements sur le maillage.
Classe de compatibilité pour contenir un MeshHandle ou un IMesh*.
const MeshHandle & handle() const
handle associé.
IMesh * meshOrNull() const
Retourne le maillage associé à cette instance.
IUserDataList * meshUserDataList() const
Données utilisateurs associées.
Caractéristiques d'un maillage.
Infos sur les noeuds d'une direction spécifique X,Y ou Z d'un maillage structuré.
Exception lorsqu'une fonction n'est pas implémentée.
Classe gérant un vecteur réel 2-dimensionnel.
Classe gérant un vecteur réel de 3 dimensions.
Référence à une instance.
Encapsulation d'un pointeur qui se détruit automatiquement.
Chaîne de caractères unicode.
TraceAccessor(ITraceMng *m)
Construit un accesseur via le gestionnaire de trace m.
TraceMessage info() const
Flot pour un message d'information.
TraceMessage warning() const
Flot pour un message d'avertissement.
ITraceMng * traceMng() const
Gestionnaire de trace.
Vecteur 1D de données avec sémantique par valeur (style STL).
Paramètres nécessaires à la construction d'une variable.
ItemGroupT< Cell > CellGroup
Groupe de mailles.
ItemVectorViewT< Cell > CellVectorView
Vue sur un vecteur de mailles.
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.
MeshVariableScalarRefT< Node, Int32 > VariableNodeInt32
Grandeur au noeud de type entier 32 bits.
MeshVariableScalarRefT< Face, Real3 > VariableFaceReal3
Grandeur aux faces de type coordonnées.
MeshVariableScalarRefT< Cell, Int32 > VariableCellInt32
Grandeur au centre des mailles de type entier 32 bits.
Int32 toInt32(Real r)
Convertit un Real en Int32.
@ ReduceSum
Somme des valeurs.
@ ReduceMax
Maximum des valeurs.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
bool arcaneIsCheck()
Vrai si on est en mode vérification.
std::int64_t Int64
Type entier signé sur 64 bits.
Int32 Integer
Type représentant un entier.
ConstArrayView< Int32 > Int32ConstArrayView
Equivalent C d'un tableau à une dimension d'entiers 32 bits.
@ Cartesian
Maillage cartésien.
eMeshDirection
Type de la direction pour un maillage structuré
double Real
Type représentant un réel.
auto makeRef(InstanceType *t) -> Ref< InstanceType >
Créé une référence sur un pointeur.
ICartesianMesh * arcaneCreateCartesianMesh(IMesh *mesh)
eMeshAMRKind
Type de maillage AMR.
@ Cell
Le maillage est AMR par maille.
@ PatchCartesianMeshOnly
Le maillage est AMR par patch cartésien (rectangulaire).
std::int32_t Int32
Type entier signé sur 32 bits.
Real y
deuxième composante du triplet
Real z
troisième composante du triplet
Real x
première composante du triplet