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"
77class CartesianMeshImpl
86 explicit InternalApi(CartesianMeshImpl* cartesian_mesh)
87 : m_cartesian_mesh(cartesian_mesh)
95 return m_cartesian_mesh->_createCartesianMeshCoarsening2();
99 m_cartesian_mesh->_addPatchFromExistingChildren(parent_cells_local_id);
103 if (m_numbering_mng.isNull()) {
106 if (m_amr_mng.isNull()) {
116 if (m_numbering_mng.isNull()) {
122 return m_numbering_mng;
130 CartesianMeshImpl* m_cartesian_mesh =
nullptr;
141 void build()
override;
151 return m_all_items_direction_info->cellDirection(dir);
156 return m_all_items_direction_info->cellDirection(idir);
161 return m_all_items_direction_info->faceDirection(dir);
166 return m_all_items_direction_info->faceDirection(idir);
171 return m_all_items_direction_info->nodeDirection(dir);
176 return m_all_items_direction_info->nodeDirection(idir);
185 return m_connectivity;
212 void computeDirectionsPatchV2(
Integer index)
override;
220 void _computeDirectionsV2();
224 InternalApi m_internal_api;
228 IMesh* m_mesh =
nullptr;
234 bool m_is_amr =
false;
240 bool m_is_mesh_event_added =
false;
241 Int64 m_mesh_timestamp = 0;
260 void _saveInfosInProperties();
262 std::tuple<CellGroup, NodeGroup>
264 void _checkNeedComputeDirections();
265 void _checkAddObservableMeshChanged();
283CartesianMeshImpl(IMesh* mesh)
284: TraceAccessor(mesh->traceMng())
285, m_internal_api(this)
287, m_nodes_to_cell_storage(platform::getDefaultDataAllocator())
288, m_cells_to_node_storage(platform::getDefaultDataAllocator())
289, m_permutation_storage(platform::getDefaultDataAllocator())
291, m_amr_type(mesh->meshKind().meshAMRKind())
294 m_internal_api.initCartesianMeshNumberingMngInternal();
295 m_internal_api.initCartesianMeshAMRPatchMng();
297 m_all_items_direction_info = m_patch_group.groundPatch();
303void CartesianMeshImpl::
306 m_properties =
new Properties(*(mesh()->properties()),
"CartesianMesh");
307 if (m_amr_type == eMeshAMRKind::PatchCartesianMeshOnly) {
308 m_internal_api.cartesianMeshNumberingMngInternal()->build();
310 m_patch_group.build();
315 const Int32 SERIALIZE_VERSION = 1;
321void CartesianMeshImpl::
322_checkNeedComputeDirections()
324 Int64 new_timestamp = mesh()->timestamp();
325 if (m_mesh_timestamp != new_timestamp) {
326 info() <<
"Le horodatage du maillage a changé (ancien=" << m_mesh_timestamp <<
" nouveau=" << new_timestamp <<
")";
334void CartesianMeshImpl::
335_saveInfosInProperties()
338 m_properties->set(
"Version", SERIALIZE_VERSION);
340 m_patch_group.saveInfosInProperties();
342 if (m_amr_type == eMeshAMRKind::PatchCartesianMeshOnly) {
343 m_internal_api.cartesianMeshNumberingMngInternal()->saveInfosInProperties();
351void CartesianMeshImpl::
354 info() <<
"Création des infos 'CartesianMesh' à partir du dump";
357 m_internal_api.cartesianMeshNumberingMngInternal()->recreateFromDump();
358 m_internal_api.cartesianMeshNumberingMngInternal()->printStatus();
362 Int32 v = m_properties->getInt32(
"Version");
363 if (v != SERIALIZE_VERSION)
364 ARCANE_FATAL(
"Mauvaise version de sérialisation : tentative de lecture à partir d'un point de contrôle incompatible v={0} attendu={1}",
365 v, SERIALIZE_VERSION);
377void CartesianMeshImpl::
378_checkAddObservableMeshChanged()
380 if (m_is_mesh_event_added)
382 m_is_mesh_event_added =
true;
385 auto f1 = [&](
const MeshEventArgs&) { this->_checkNeedComputeDirections(); };
386 mesh()->eventObservable(eMeshEventType::EndPrepareDump).attach(m_event_pool, f1);
392void CartesianMeshImpl::
397 m_internal_api.cartesianMeshNumberingMngInternal()->renumberingFacesLevel0FromOriginalArcaneNumbering();
398 _computeDirectionsV2();
401 info() <<
"CartesianMesh: computeDirections()";
403 m_mesh_timestamp =
mesh()->timestamp();
404 _checkAddObservableMeshChanged();
406 m_is_amr = m_mesh->isAmrActivated();
416 for (NodeLocalId inode : cell.
nodeIds())
417 center += nodes_coord[inode];
419 cells_center[icell] = center;
424 for (NodeLocalId inode : face.
nodeIds())
425 center += nodes_coord[inode];
427 faces_center[iface] = center;
432 Int32 next_face_x = -1;
433 Int32 next_face_y = -1;
434 Int32 next_face_z = -1;
437 Cell cell0 = cell_view[0];
440 Real3 cell_center = cells_center[cell0];
447 info(4) <<
"Cartesian mesh compute directions is_amr=" << m_is_amr;
449 for (
Integer i = 0; i < nb_node; ++i) {
451 info(4) <<
"Nœud I=" << i <<
" nœud=" <<
ItemPrinter(node) <<
" pos=" << nodes_coord[node];
454 bool is_3d = m_mesh->dimension() == 3;
464 for (
Integer i = 0; i < nb_face; ++i) {
467 Real3 next_center = faces_center[f];
469 Real diff_x = next_center.
x - cell_center.
x;
470 Real diff_y = next_center.
y - cell_center.
y;
471 Real diff_z = next_center.
z - cell_center.
z;
473 info(4) <<
"FACE_SUIVANTE=" <<
ItemPrinter(f) <<
" centre=" << next_center <<
" diff=" <<
Real3(diff_x, diff_y, diff_z);
475 if (diff_x > max_x) {
480 if (diff_y > max_y) {
485 if (diff_z > max_z) {
490 info(4) <<
"Avancement dans la direction X -> " << next_face_x;
491 info(4) <<
"Avancement dans la direction Y -> " << next_face_y;
492 info(4) <<
"Avancement dans la direction Z -> " << next_face_z;
498 for (
Integer i = 0; i < nb_face; ++i) {
501 Real3 next_center = faces_center[f];
503 Real diff_x = next_center.
x - cell_center.
x;
504 Real diff_y = next_center.
y - cell_center.
y;
506 info(4) <<
"FACE_SUIVANTE=" <<
ItemPrinter(f) <<
" centre=" << next_center <<
" diff=" <<
Real2(diff_x, diff_y);
508 if (diff_x > max_x) {
513 if (diff_y > max_y) {
518 info(4) <<
"Avancement dans la direction X -> " << next_face_x;
519 info(4) <<
"Avancement dans la direction Y -> " << next_face_y;
521 m_all_items_direction_info->_internalComputeNodeCellInformations(cell0, cells_center[cell0], nodes_coord);
523 info() <<
"Informations des propriétés IMesh:";
525 auto* cmgi = ICartesianMeshGenerationInfo::getReference(m_mesh,
true);
527 info() <<
"GlobalNbCell = " << cmgi->globalNbCells();
528 info() <<
"OwnNbCell: " << cmgi->ownNbCells();
529 info() <<
"SubDomainOffset: " << cmgi->subDomainOffsets();
530 info() <<
"OwnCellOffset: " << cmgi->ownCellOffsets();
535 auto x = _buildPatchGroups(
mesh()->allLevelCells(0), 0);
536 all_cells = std::get<0>(x);
537 all_nodes = std::get<1>(x);
540 if (next_face_x != (-1)) {
542 _computeMeshDirection(*m_all_items_direction_info.get(),
MD_DirX, cells_center, faces_center, all_cells, all_nodes);
544 if (next_face_y != (-1)) {
546 _computeMeshDirection(*m_all_items_direction_info.get(),
MD_DirY, cells_center, faces_center, all_cells, all_nodes);
548 if (next_face_z != (-1)) {
550 _computeMeshDirection(*m_all_items_direction_info.get(),
MD_DirZ, cells_center, faces_center, all_cells, all_nodes);
554 for (
Integer idir = 0, nb_dir =
mesh()->dimension(); idir < nb_dir; ++idir) {
556 cdm._internalSetOffsetAndNbCellInfos(cmgi->globalNbCells()[idir], cmgi->ownNbCells()[idir],
557 cmgi->subDomainOffsets()[idir], cmgi->ownCellOffsets()[idir]);
560 info() <<
"Calcul de la connectivité cartésienne";
562 m_permutation_storage.resize(1);
563 m_permutation_storage[0].compute();
564 m_nodes_to_cell_storage.resize(
mesh()->nodeFamily()->maxLocalId());
565 m_cells_to_node_storage.resize(
mesh()->cellFamily()->maxLocalId());
566 m_connectivity._setStorage(m_nodes_to_cell_storage, m_cells_to_node_storage, &m_permutation_storage[0]);
567 m_connectivity._computeInfos(
mesh(), nodes_coord, cells_center);
574 info() <<
"Nom du patch AMR=" << cells.
name() <<
" taille=" << cells.
size() <<
" index=" << patch_index <<
" nbPatch=" <<
m_patch_group.nbPatch();
575 patch->_internalComputeNodeCellInformations(cell0, cells_center[cell0], nodes_coord);
576 auto [patch_cells, patch_nodes] = _buildPatchGroups(cells, patch_index);
577 _computeMeshDirection(*
patch.get(),
MD_DirX, cells_center, faces_center, patch_cells, patch_nodes);
578 _computeMeshDirection(*
patch.get(),
MD_DirY, cells_center, faces_center, patch_cells, patch_nodes);
580 _computeMeshDirection(*
patch.get(),
MD_DirZ, cells_center, faces_center, patch_cells, patch_nodes);
586 _saveInfosInProperties();
592std::tuple<CellGroup, NodeGroup> CartesianMeshImpl::
605 String cell_group_name =
String(
"AMRPatchCells") + patch_level;
610 String node_group_name =
String(
"AMRPatchNodes") + patch_level;
614 info(4) <<
"PATCH_CELLS nom=" << patch_cells.
name() <<
" taille=" << patch_cells.
size();
615 info(4) <<
"PATCH_NODES nom=" << patch_nodes.
name() <<
" taille=" << patch_nodes.
size();
616 return { patch_cells, patch_nodes };
622void CartesianMeshImpl::
623_computeMeshDirection(CartesianMeshPatch& cdi, eMeshDirection dir, VariableCellReal3& cells_center,
624 VariableFaceReal3& faces_center, CellGroup all_cells, NodeGroup all_nodes)
626 IItemFamily* cell_family = m_mesh->cellFamily();
627 IItemFamily* face_family = m_mesh->faceFamily();
628 IItemFamily* node_family = m_mesh->nodeFamily();
630 Int32 max_cell_id = cell_family->
maxLocalId();
631 Int32 max_face_id = face_family->maxLocalId();
632 Int32 max_node_id = node_family->maxLocalId();
634 CellDirectionMng& cell_dm = cdi.cellDirection(dir);
635 cell_dm._internalResizeInfos(max_cell_id);
637 FaceDirectionMng& face_dm = cdi.faceDirection(dir);
638 face_dm._internalResizeInfos(max_face_id);
640 NodeDirectionMng& node_dm = cdi.nodeDirection(dir);
641 node_dm._internalResizeInfos(max_node_id);
644 info(4) <<
"COMPUTE DIRECTION dir=" << dir;
646 Int32 prev_local_face = -1;
647 Int32 next_local_face = m_local_face_direction[dir];
648 Integer mesh_dim = m_mesh->dimension();
651 prev_local_face = (next_local_face + 2) % 4;
652 else if (mesh_dim == 3)
653 prev_local_face = (next_local_face + 3) % 6;
655 cell_dm._internalSetLocalFaceIndex(next_local_face, prev_local_face);
661 UniqueArray<bool> is_in_cells(m_mesh->cellFamily()->maxLocalId(),
false);
663 is_in_cells[icell.itemLocalId()] =
true;
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 (next_cell.null() || !is_in_cells[next_cell.localId()])
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 (prev_cell.null() || !is_in_cells[prev_cell.localId()])
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 UniqueArray<bool> is_in_cells(m_mesh->cellFamily()->maxLocalId(),
false);
814 is_in_cells[icell.itemLocalId()] =
true;
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 (next_cell.null() || !is_in_cells[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 (prev_cell.null() || !is_in_cells[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