13#include "arcane/cartesianmesh/internal/CartesianPatchGroup.h"
15#include "arcane/utils/FixedArray.h"
16#include "arcane/utils/Vector3.h"
17#include "arcane/utils/StringBuilder.h"
18#include "arcane/utils/ITraceMng.h"
20#include "arcane/core/IMesh.h"
21#include "arcane/core/IParallelMng.h"
22#include "arcane/core/MeshKind.h"
23#include "arcane/core/Properties.h"
25#include "arcane/cartesianmesh/ICartesianMesh.h"
26#include "arcane/cartesianmesh/AMRZonePosition.h"
28#include "arcane/cartesianmesh/internal/CartesianMeshPatch.h"
29#include "arcane/cartesianmesh/internal/ICartesianMeshInternal.h"
30#include "arcane/cartesianmesh/internal/AMRPatchPositionLevelGroup.h"
31#include "arcane/cartesianmesh/internal/AMRPatchPositionSignature.h"
32#include "arcane/cartesianmesh/internal/AMRPatchPositionSignatureCut.h"
33#include "arcane/cartesianmesh/internal/ICartesianMeshNumberingMngInternal.h"
48, m_index_new_patches(1)
49, m_size_of_overlap_layer_top_level(0)
51, m_target_nb_levels(0)
52, m_latest_call_level(-2)
58void CartesianPatchGroup::
61 m_properties =
makeRef(
new Properties(*(m_cmesh->mesh()->properties()),
"CartesianPatchGroup"));
67void CartesianPatchGroup::
68saveInfosInProperties()
70 m_properties->set(
"Version", 1);
72 if (m_cmesh->mesh()->meshKind().meshAMRKind() != eMeshAMRKind::PatchCartesianMeshOnly) {
73 UniqueArray<String> patch_group_names;
74 for (Integer i = 1; i < m_amr_patches_pointer.size(); ++i) {
75 patch_group_names.add(allCells(i).name());
77 m_properties->set(
"PatchGroupNames", patch_group_names);
82 UniqueArray<String> patch_group_names(m_amr_patches_pointer.size() - 1);
83 UniqueArray<Int32> level(m_amr_patches_pointer.size() - 1);
84 UniqueArray<Int32> overlap(m_amr_patches_pointer.size() - 1);
85 UniqueArray<Int32> index(m_amr_patches_pointer.size() - 1);
86 UniqueArray<CartCoord> min_point((m_amr_patches_pointer.size() - 1) * 3);
87 UniqueArray<CartCoord> max_point((m_amr_patches_pointer.size() - 1) * 3);
89 for (Integer patch = 1; patch < m_amr_patches_pointer.size(); ++patch) {
90 const Integer pos_in_array = patch - 1;
91 const AMRPatchPosition& position = m_amr_patches_pointer[patch]->_internalApi()->positionRef();
92 level[pos_in_array] = position.level();
93 overlap[pos_in_array] = position.overlapLayerSize();
94 index[pos_in_array] = m_amr_patches_pointer[patch]->index();
96 const Integer pos = pos_in_array * 3;
97 min_point[pos + 0] = position.minPoint().x;
98 min_point[pos + 1] = position.minPoint().y;
99 min_point[pos + 2] = position.minPoint().z;
100 max_point[pos + 0] = position.maxPoint().x;
101 max_point[pos + 1] = position.maxPoint().y;
102 max_point[pos + 2] = position.maxPoint().z;
104 patch_group_names[pos_in_array] = allCells(patch).name();
106 m_properties->set(
"LevelPatches", level);
107 m_properties->set(
"OverlapSizePatches", overlap);
108 m_properties->set(
"IndexPatches", index);
109 m_properties->set(
"MinPointPatches", min_point);
110 m_properties->set(
"MaxPointPatches", max_point);
116 m_properties->set(
"PatchGroupNamesAvailable", m_available_group_index);
117 m_properties->set(
"PatchGroupNames", patch_group_names);
124void CartesianPatchGroup::
127 Trace::Setter mci(traceMng(),
"CartesianPatchGroup");
130 Int32 v = m_properties->getInt32(
"Version");
132 ARCANE_FATAL(
"Bad serializer version: trying to read from incompatible checkpoint v={0} expected={1}", v, 1);
136 _createGroundPatch();
139 UniqueArray<String> patch_group_names;
140 m_properties->get(
"PatchGroupNames", patch_group_names);
142 if (m_cmesh->mesh()->meshKind().meshAMRKind() != eMeshAMRKind::PatchCartesianMeshOnly) {
143 info(4) <<
"Found n=" << patch_group_names.size() <<
" patchs";
145 IItemFamily* cell_family = m_cmesh->mesh()->cellFamily();
146 for (
const String& x : patch_group_names) {
147 CellGroup group = cell_family->findGroup(x);
150 _addPatchAfterRestore(group);
154 UniqueArray<Int32> level;
155 UniqueArray<Int32> overlap;
156 UniqueArray<Int32> index;
157 UniqueArray<CartCoord> min_point;
158 UniqueArray<CartCoord> max_point;
160 m_properties->get(
"LevelPatches", level);
161 m_properties->get(
"OverlapSizePatches", overlap);
162 m_properties->get(
"IndexPatches", index);
163 m_properties->get(
"MinPointPatches", min_point);
164 m_properties->get(
"MaxPointPatches", max_point);
166 IItemFamily* cell_family = m_cmesh->mesh()->cellFamily();
169 for (Integer pos_in_array = 0; pos_in_array < index.size(); ++pos_in_array) {
170 ConstArrayView
min(min_point.subConstView(pos_in_array * 3, 3));
171 ConstArrayView
max(max_point.subConstView(pos_in_array * 3, 3));
173 AMRPatchPosition position(
177 overlap[pos_in_array]);
179 const String& x = patch_group_names[pos_in_array];
180 CellGroup cell_group = cell_family->findGroup(x);
181 if (cell_group.null())
184 auto* cdi =
new CartesianMeshPatch(m_cmesh, index[pos_in_array], position);
185 _addPatchInstance(
makeRef(cdi));
186 _addCellGroup(cell_group, cdi,
true);
189 UniqueArray<Int32> available_index;
190 m_properties->get(
"PatchGroupNamesAvailable", available_index);
191 rebuildAvailableGroupIndex(available_index);
201 _createGroundPatch();
208void CartesianPatchGroup::
215 Integer index = _nextIndexForNewPatch();
216 String children_group_name =
String(
"CartesianMeshPatchCells") + index;
219 _addPatch(children_cells, index);
227_addPatchAfterRestore(
CellGroup cell_group)
231 if (name.
startsWith(
"CartesianMeshPatchCells")) {
233 group_index = std::stoi(index_str.
localstr());
239 _addPatch(cell_group, group_index);
246void CartesianPatchGroup::
247_addPatch(CellGroup cell_group, Integer group_index)
249 _createGroundPatch();
250 if (group_index == -1) {
253 if (cell_group.null())
256 AMRPatchPosition position;
258 auto* cdi =
new CartesianMeshPatch(m_cmesh, group_index, position);
259 _addPatchInstance(
makeRef(cdi));
260 _addCellGroup(cell_group, cdi,
true);
266void CartesianPatchGroup::
270 ARCANE_FATAL(
"Method available only with AMR PatchCartesianMeshOnly");
275 info() <<
"addPatch() with zone"
276 <<
" -- Position : " << zone_position.
position()
277 <<
" -- Length : " << zone_position.
length();
279 clearRefineRelatedFlags();
281 auto amr = m_cmesh->_internalApi()->cartesianMeshAMRPatchMng();
282 auto numbering = m_cmesh->_internalApi()->cartesianMeshNumberingMngInternal();
290 Int32 level_up = level + 1;
291 Int32 nb_overlap_cells = 0;
293 Int32 higher_level = m_higher_level;
298 if (level_up >= higher_level) {
299 higher_level = level_up;
303 nb_overlap_cells = m_size_of_overlap_layer_top_level / numbering->pattern();
304 debug() <<
"Higher level -- Old : " << m_higher_level <<
" -- New : " << higher_level;
318 nb_overlap_cells = overlapLayerSize(level + 1) / numbering->pattern();
322 debug() <<
"Zone to intermediary patch"
323 <<
" -- minPoint : " << position.
minPoint()
324 <<
" -- maxPoint : " << position.
maxPoint()
326 <<
" -- level : " << level;
332 if (!icell->hasHChildren()) {
333 const CartCoord3 pos = numbering->cellUniqueIdToCoord(*icell);
343 AMRPatchPosition position_up = position.
patchUp(m_cmesh->mesh()->dimension(), higher_level, m_size_of_overlap_layer_top_level);
345 info() <<
"Zone to Patch"
346 <<
" -- minPoint : " << position_up.
minPoint()
347 <<
" -- maxPoint : " << position_up.
maxPoint()
349 <<
" -- level : " << position_up.
level();
352 _addPatch(position_up);
356 _updateHigherLevel();
359 _checkPatchesAndMesh();
369 return m_amr_patches.size();
375Ref<CartesianMeshPatch> CartesianPatchGroup::
376patch(
const Integer index)
const
378 return m_amr_patches[index];
384CartesianMeshPatchListView CartesianPatchGroup::
387 return CartesianMeshPatchListView{ m_amr_patches_pointer };
396 return m_amr_patch_cell_groups_all[index];
406 ARCANE_FATAL(
"Method available only with AMR PatchCartesianMeshOnly");
408 return m_amr_patch_cell_groups_inpatch[index];
418 ARCANE_FATAL(
"Method available only with AMR PatchCartesianMeshOnly");
420 return m_amr_patch_cell_groups_overlap[index];
428void CartesianPatchGroup::
437void CartesianPatchGroup::
438removePatch(
const Integer index)
440 if (m_patches_to_delete.contains(index)) {
446 if (index < 1 || index >= m_amr_patches.size()) {
450 m_patches_to_delete.add(index);
456void CartesianPatchGroup::
464 for (
Integer i = 1; i < m_amr_patch_cell_groups_all.size(); ++i) {
465 allCells(i).removeItems(cells_local_id);
473void CartesianPatchGroup::
478 const Integer nb_patchs = m_amr_patches_pointer.size();
479 for (
Integer i = 1; i < nb_patchs; ++i) {
490 _removePartOfPatch(i, zone_to_delete);
498void CartesianPatchGroup::
502 ARCANE_FATAL(
"Method available only with AMR PatchCartesianMeshOnly");
504 clearRefineRelatedFlags();
509 zone_to_delete.
cellsInPatch(m_cmesh, cells_local_id, patch_position);
511 _removeCellsInAllPatches(patch_position);
513 _updatePatchFlagsOfItemsLevel(patch_position.
level(),
true);
514 _updateHigherLevel();
515 _coarsenUselessCells(
true);
518 _checkPatchesAndMesh();
525void CartesianPatchGroup::
526applyPatchEdit(
bool remove_empty_patches,
bool update_higher_level)
530 std::stable_sort(m_patches_to_delete.begin(), m_patches_to_delete.end(),
535 _removeMultiplePatches(m_patches_to_delete);
536 m_patches_to_delete.clear();
541 for (
Integer i = 0; i < m_amr_patch_cell_groups_all.size(); ++i) {
542 size_of_patches[i] = m_amr_patch_cell_groups_all[i].
size();
545 for (
Integer i = 0; i < size_of_patches.
size(); ++i) {
546 if (size_of_patches[i] == 0) {
547 m_patches_to_delete.add(i);
550 _removeMultiplePatches(m_patches_to_delete);
551 m_patches_to_delete.clear();
556 _updateHigherLevel();
557 _coarsenUselessCells(
true);
564void CartesianPatchGroup::
565updateLevelsAndAddGroundPatch()
571 auto numbering = m_cmesh->_internalApi()->cartesianMeshNumberingMngInternal();
572 auto amr = m_cmesh->_internalApi()->cartesianMeshAMRPatchMng();
574 amr->createSubLevel();
579 const Int32 level = patch->position().level();
582 const CartCoord3 max_point = patch->position().maxPoint();
583 if (m_cmesh->mesh()->dimension() == 2) {
584 patch->_internalApi()->positionRef().setMaxPoint({
585 numbering->offsetLevelToLevel(max_point.x, level, level - 1),
586 numbering->offsetLevelToLevel(max_point.y, level, level - 1),
591 patch->_internalApi()->positionRef().setMaxPoint({
592 numbering->offsetLevelToLevel(max_point.x, level, level - 1),
593 numbering->offsetLevelToLevel(max_point.y, level, level - 1),
594 numbering->offsetLevelToLevel(max_point.z, level, level - 1),
600 patch->_internalApi()->positionRef().setLevel(level + 1);
608 old_ground.
setMaxPoint({ numbering->globalNbCellsX(1), numbering->globalNbCellsY(1), numbering->globalNbCellsZ(1) });
610 _addPatch(old_ground);
613 m_cmesh->computeDirectionsPatchV2(0);
615 _updatePatchFlagsOfItemsGroundLevel();
620 _updateHigherLevel();
623 _checkPatchesAndMesh();
631_nextIndexForNewPatch()
633 if (!m_available_group_index.empty()) {
634 const Integer elem = m_available_group_index.back();
635 m_available_group_index.popBack();
638 return m_index_new_patches++;
644void CartesianPatchGroup::
647 if (m_cmesh->mesh()->meshKind().meshAMRKind() != eMeshAMRKind::PatchCartesianMeshOnly) {
650 UniqueArray<Int32> new_merged_patches;
653 UniqueArray<std::pair<Integer, Int64>> index_n_nb_cells;
656 for (
auto patch : m_amr_patches_pointer) {
657 index_n_nb_cells.add({ index++, patch->position().nbCells() });
669 std::stable_sort(index_n_nb_cells.begin(), index_n_nb_cells.end(),
670 [](
const std::pair<Integer, Int64>& a,
const std::pair<Integer, Int64>& b) {
671 return a.second < b.second;
674 for (Integer p0 = 0; p0 < index_n_nb_cells.size(); ++p0) {
675 auto [index_p0, nb_cells_p0] = index_n_nb_cells[p0];
677 AMRPatchPosition& patch_fusion_0 = m_amr_patches_pointer[index_p0]->_internalApi()->positionRef();
678 if (patch_fusion_0.isNull())
685 for (Integer p1 = p0 + 1; p1 < m_amr_patches_pointer.size(); ++p1) {
686 auto [index_p1, nb_cells_p1] = index_n_nb_cells[p1];
688 AMRPatchPosition& patch_fusion_1 = m_amr_patches_pointer[index_p1]->_internalApi()->positionRef();
689 if (patch_fusion_1.isNull())
700 if (patch_fusion_0.fusion(patch_fusion_1)) {
702 index_n_nb_cells[p0].second = patch_fusion_0.nbCells();
705 removePatch(index_p1);
707 if (!new_merged_patches.contains(index_p0)) {
708 new_merged_patches.add(index_p0);
711 auto find_p1 = new_merged_patches.span().findFirst(index_p1);
712 if (find_p1.has_value()) {
713 new_merged_patches.remove(find_p1.value());
726 UniqueArray<Int32> levels_edited;
727 for (Int32 patch_index : new_merged_patches) {
728 _updateCellGroups(patch_index,
false);
730 Int32 level = patch(patch_index)->_internalApi()->positionRef().level();
731 if (!levels_edited.contains(level)) {
732 levels_edited.add(level);
735 applyPatchEdit(
false,
false);
737 for (Int32 level : levels_edited) {
738 _updatePatchFlagsOfItemsLevel(level,
true);
742 _checkPatchesAndMesh();
749void CartesianPatchGroup::
750beginAdaptMesh(Int32 nb_levels, Int32 level_to_refine_first)
752 if (m_cmesh->mesh()->meshKind().meshAMRKind() != eMeshAMRKind::PatchCartesianMeshOnly) {
753 ARCANE_FATAL(
"Method available only with AMR PatchCartesianMeshOnly");
755 if (m_latest_call_level != -2) {
756 ARCANE_FATAL(
"Call endAdaptMesh() before restart mesh adaptation");
758 if (level_to_refine_first > m_higher_level) {
759 ARCANE_FATAL(
"Cannot begin to refine level higher than the actual higher level -- Level to refine first : {0} -- Higher level : {1}", level_to_refine_first, m_higher_level);
762 Trace::Setter mci(traceMng(),
"CartesianPatchGroup");
763 info() <<
"Begin adapting mesh with higher level = " << (nb_levels - 1);
767 for (Integer p = 1; p < m_amr_patches_pointer.size(); ++p) {
768 Int32 level = m_amr_patches_pointer[p]->_internalApi()->positionRef().level();
769 if (level > level_to_refine_first) {
774 applyPatchEdit(
false,
false);
778 for (Integer l = level_to_refine_first + 1; l <= max_level; ++l) {
779 _removePatchFlagsOfItemsLevel(l);
783 if (nb_levels - 1 != m_higher_level) {
784 debug() <<
"beginAdaptMesh() -- Change overlap layer size -- Old higher level : " << m_higher_level
785 <<
" -- Asked higher level : " << (nb_levels - 1)
786 <<
" -- Adapt level lower than : " << level_to_refine_first;
788 for (Int32 level = 1; level <= level_to_refine_first; ++level) {
789 _changeOverlapSizeLevel(level, m_higher_level, nb_levels - 1);
793 m_target_nb_levels = nb_levels;
794 m_latest_call_level = level_to_refine_first - 1;
801void CartesianPatchGroup::
804 if (m_cmesh->mesh()->meshKind().meshAMRKind() != eMeshAMRKind::PatchCartesianMeshOnly) {
805 ARCANE_FATAL(
"Method available only with AMR PatchCartesianMeshOnly");
807 if (m_latest_call_level == -2) {
810 Trace::Setter mci(traceMng(),
"CartesianPatchGroup");
811 info() <<
"Finalizing adapting mesh with higher level = " << (m_target_nb_levels - 1);
813 auto amr = m_cmesh->_internalApi()->cartesianMeshAMRPatchMng();
821 m_higher_level = m_latest_call_level + 1;
828 if (m_higher_level + 1 < m_target_nb_levels) {
829 info() <<
"Reduce higher level from " << (m_target_nb_levels - 1) <<
" to " << m_higher_level;
831 for (Int32 level = 1; level <= m_higher_level; ++level) {
832 _changeOverlapSizeLevel(level, m_target_nb_levels - 1, m_higher_level);
836 _coarsenUselessCells(
true);
838 m_target_nb_levels = 0;
839 m_latest_call_level = -2;
840 clearRefineRelatedFlags();
842 info() <<
"Patch list:";
844 for (Integer i = 0; i <= m_higher_level; ++i) {
845 for (
auto p : m_amr_patches_pointer) {
846 auto& position = p->_internalApi()->positionRef();
847 if (position.level() == i) {
848 info() <<
"\tPatch #" << p->index()
849 <<
" -- Level : " << position.level()
850 <<
" -- Min point : " << position.minPoint()
851 <<
" -- Max point : " << position.maxPoint()
852 <<
" -- Overlap layer size : " << position.overlapLayerSize();
857 _checkPatchesAndMesh();
864void CartesianPatchGroup::
865adaptLevel(Int32 level_to_adapt,
bool do_fatal_if_useless)
867 if (m_cmesh->mesh()->meshKind().meshAMRKind() != eMeshAMRKind::PatchCartesianMeshOnly) {
868 ARCANE_FATAL(
"Method available only with AMR PatchCartesianMeshOnly");
870 if (m_latest_call_level == -2) {
871 ARCANE_FATAL(
"Call beginAdaptMesh() before to begin a mesh adaptation");
873 if (level_to_adapt + 1 >= m_target_nb_levels || level_to_adapt < 0) {
874 ARCANE_FATAL(
"Bad level to adapt -- Level to adapt : {0} (creating level {1}) -- Max nb levels : {2}", level_to_adapt, level_to_adapt + 1, m_target_nb_levels);
877 Trace::Setter mci(traceMng(),
"CartesianPatchGroup");
879 if (level_to_adapt > m_latest_call_level + 1) {
880 if (do_fatal_if_useless) {
881 ARCANE_FATAL(
"You must refine level {0} before.", (m_latest_call_level + 1));
883 warning() << String::format(
"Useless call -- You must refine level {0} before.", (m_latest_call_level + 1));
892 if (level_to_adapt < m_latest_call_level) {
894 for (Integer p = 1; p < m_amr_patches_pointer.size(); ++p) {
895 Int32 level = m_amr_patches_pointer[p]->_internalApi()->positionRef().level();
896 if (level > level_to_adapt) {
901 applyPatchEdit(
false,
false);
903 for (Integer l = level_to_adapt + 1; l <= max_level; ++l) {
904 _removePatchFlagsOfItemsLevel(l);
908 auto amr = m_cmesh->_internalApi()->cartesianMeshAMRPatchMng();
909 auto numbering = m_cmesh->_internalApi()->cartesianMeshNumberingMngInternal();
923 Int32 nb_overlap_cells = overlapLayerSize(level_to_adapt + 1) / numbering->pattern();
925 info() <<
"adaptLevel()"
926 <<
" -- Level to adapt : " << level_to_adapt
927 <<
" -- Nb of overlap cells (intermediary patch) : " << nb_overlap_cells;
934 bool has_cell_to_refine =
false;
935 ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allCells()) {
936 if (icell->hasFlags(ItemFlags::II_Refine)) {
937 if (icell->level() != level_to_adapt) {
938 ARCANE_FATAL(
"Flag II_Refine found on Cell (UID={0} - Level={1}) not in level to refine (={2})", icell->uniqueId(), icell->level(), level_to_adapt);
940 if (level_to_adapt != 0 && !icell->hasFlags(ItemFlags::II_InPatch)) {
941 const CartCoord3 pos = numbering->cellUniqueIdToCoord(*icell);
942 ARCANE_FATAL(
"Cannot refine cell not in patch -- Pos : {0} -- CellUID : {1} -- CellLevel : {2}", pos, icell->uniqueId(), icell->level());
944 has_cell_to_refine =
true;
947 has_cell_to_refine = m_cmesh->mesh()->parallelMng()->reduce(MessagePassing::ReduceMax, has_cell_to_refine);
949 if (!has_cell_to_refine) {
950 if (do_fatal_if_useless) {
966 m_latest_call_level = level_to_adapt - 1;
967 debug() <<
"adaptLevel() -- End call -- No refine -- Actual patch list:";
969 for (Integer i = 0; i <= m_target_nb_levels; ++i) {
970 for (
auto p : m_amr_patches_pointer) {
971 auto& position = p->_internalApi()->positionRef();
972 if (position.level() == i) {
973 debug() <<
"\tPatch #" << p->index()
974 <<
" -- Level : " << position.level()
975 <<
" -- Min point : " << position.minPoint()
976 <<
" -- Max point : " << position.maxPoint()
977 <<
" -- Overlap layer size : " << position.overlapLayerSize();
984 m_latest_call_level = level_to_adapt;
986 UniqueArray<AMRPatchPositionSignature> sig_array;
994 if (level_to_adapt == 0) {
995 AMRPatchPosition all_level;
996 all_level.setLevel(level_to_adapt);
997 all_level.setMinPoint({ 0, 0, 0 });
998 all_level.setMaxPoint({ numbering->globalNbCellsX(level_to_adapt), numbering->globalNbCellsY(level_to_adapt), numbering->globalNbCellsZ(level_to_adapt) });
1000 all_level.setOverlapLayerSize(nb_overlap_cells);
1001 AMRPatchPositionSignature sig(all_level, m_cmesh);
1016 for (
auto patch : m_amr_patches_pointer) {
1017 Integer level = patch->_internalApi()->positionRef().level();
1018 if (level == level_to_adapt) {
1019 auto position = patch->position();
1020 position.setOverlapLayerSize(nb_overlap_cells);
1021 AMRPatchPositionSignature sig(position, m_cmesh);
1027 AMRPatchPositionSignatureCut::cut(sig_array);
1031 ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allLevelCells(level_to_adapt)) {
1032 if (!icell->hasHChildren()) {
1033 const CartCoord3 pos = numbering->cellUniqueIdToCoord(*icell);
1034 for (
const AMRPatchPositionSignature& patch_signature : sig_array) {
1035 if (patch_signature.patch().isInWithOverlap(pos)) {
1036 if (!icell->hasFlags(ItemFlags::II_InPatch) && !icell->hasFlags(ItemFlags::II_Overlap)) {
1037 ARCANE_FATAL(
"Internal error -- Refine algo error -- Pos : {0}", pos);
1039 icell->mutableItemBase().addFlags(ItemFlags::II_Refine);
1078 ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allLevelCells(level_to_adapt)) {
1079 icell->mutableItemBase().removeFlags(ItemFlags::II_Refine);
1084 UniqueArray<AMRPatchPosition> all_patches;
1085 for (
const auto& elem : sig_array) {
1086 all_patches.add(elem.patch().patchUp(m_cmesh->mesh()->dimension(), m_target_nb_levels - 1, m_size_of_overlap_layer_top_level));
1090 AMRPatchPositionLevelGroup::fusionPatches(all_patches,
true);
1159 for (
const AMRPatchPosition& patch : all_patches) {
1160 Integer index = _addPatch(patch);
1162 m_cmesh->computeDirectionsPatchV2(index);
1165 debug() <<
"adaptLevel() -- End call -- Actual patch list:";
1167 for (Integer i = 0; i <= m_target_nb_levels; ++i) {
1168 for (
auto p : m_amr_patches_pointer) {
1169 auto& position = p->_internalApi()->positionRef();
1170 if (position.level() == i) {
1171 debug() <<
"\tPatch #" << p->index()
1172 <<
" -- Level : " << position.level()
1173 <<
" -- Min point : " << position.minPoint()
1174 <<
" -- Max point : " << position.maxPoint()
1175 <<
" -- Overlap layer size : " << position.overlapLayerSize();
1184void CartesianPatchGroup::
1185_increaseOverlapSizeLevel(Int32 level_to_increate, Int32 new_size)
1187 if (level_to_increate == 0) {
1191 auto amr = m_cmesh->_internalApi()->cartesianMeshAMRPatchMng();
1192 auto numbering = m_cmesh->_internalApi()->cartesianMeshNumberingMngInternal();
1194 bool has_cell_to_refine =
false;
1202 for (Integer p = 1; p < m_amr_patches_pointer.size(); ++p) {
1203 Int32 level = m_amr_patches_pointer[p]->_internalApi()->positionRef().level();
1204 if (level == level_to_increate) {
1205 AMRPatchPosition& position = m_amr_patches_pointer[p]->_internalApi()->positionRef();
1207 Int32 size_layer = position.overlapLayerSize();
1208 if (size_layer > new_size) {
1209 ARCANE_FATAL(
"Cannot reduce layer with _increaseOverlapSizeLevel method");
1214 if (size_layer == new_size) {
1218 has_cell_to_refine =
true;
1219 position.setOverlapLayerSize(new_size);
1224 ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allLevelCells(level_to_increate - 1)) {
1225 const CartCoord3 pos = numbering->offsetLevelToLevel(numbering->cellUniqueIdToCoord(*icell), level_to_increate - 1, level_to_increate);
1226 if (position.isInWithOverlap(pos) && !icell->hasHChildren()) {
1227 icell->mutableItemBase().addFlags(ItemFlags::II_Refine);
1232 has_cell_to_refine = m_cmesh->mesh()->parallelMng()->reduce(MessagePassing::ReduceMax, has_cell_to_refine);
1233 if (!has_cell_to_refine) {
1241 ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allLevelCells(level_to_increate - 1)) {
1242 icell->mutableItemBase().removeFlags(ItemFlags::II_Refine);
1245 UniqueArray<Int32> cell_to_add;
1248 for (Integer p = 1; p < m_amr_patches_pointer.size(); ++p) {
1249 Int32 level = m_amr_patches_pointer[p]->_internalApi()->positionRef().level();
1250 if (level == level_to_increate) {
1251 AMRPatchPosition& position = m_amr_patches_pointer[p]->_internalApi()->positionRef();
1253 ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allLevelCells(level_to_increate)) {
1254 if (!icell->hasFlags(ItemFlags::II_JustAdded))
1257 const CartCoord3 pos = numbering->cellUniqueIdToCoord(*icell);
1259 if (position.isInWithOverlap(pos)) {
1260 cell_to_add.add(icell.localId());
1261 icell->mutableItemBase().addFlags(ItemFlags::II_Overlap);
1262 for (Face face : icell->faces()) {
1263 face.mutableItemBase().addFlags(ItemFlags::II_Overlap);
1265 for (Node node : icell->nodes()) {
1266 node.mutableItemBase().addFlags(ItemFlags::II_Overlap);
1269 else if (position.isIn(pos)) {
1270 icell->mutableItemBase().addFlags(ItemFlags::II_InPatch);
1271 for (Face face : icell->faces()) {
1272 face.mutableItemBase().addFlags(ItemFlags::II_InPatch);
1274 for (Node node : icell->nodes()) {
1275 node.mutableItemBase().addFlags(ItemFlags::II_InPatch);
1280 allCells(p).addItems(cell_to_add,
true);
1281 overlapCells(p).addItems(cell_to_add,
true);
1282 cell_to_add.clear();
1285 m_cmesh->computeDirectionsPatchV2(p);
1289 ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allLevelCells(level_to_increate)) {
1290 icell->mutableItemBase().removeFlags(ItemFlags::II_JustAdded);
1297void CartesianPatchGroup::
1298_reduceOverlapSizeLevel(Int32 level_to_reduce, Int32 new_size)
1304 if (level_to_reduce == 0) {
1308 auto amr = m_cmesh->_internalApi()->cartesianMeshAMRPatchMng();
1309 auto numbering = m_cmesh->_internalApi()->cartesianMeshNumberingMngInternal();
1316 bool has_cell_to_mark =
false;
1317 UniqueArray<Int32> cell_to_remove;
1319 for (Integer p = 1; p < m_amr_patches_pointer.size(); ++p) {
1320 Int32 level = m_amr_patches_pointer[p]->_internalApi()->positionRef().level();
1321 if (level == level_to_reduce) {
1322 AMRPatchPosition& position = m_amr_patches_pointer[p]->_internalApi()->positionRef();
1324 Int32 size_layer = position.overlapLayerSize();
1325 if (size_layer < new_size) {
1326 ARCANE_FATAL(
"Cannot add layer with _reduceOverlapSizeLevel method");
1328 if (size_layer == new_size) {
1332 has_cell_to_mark =
true;
1333 position.setOverlapLayerSize(new_size);
1336 const CartCoord3 pos = numbering->cellUniqueIdToCoord(*icell);
1337 if (!position.isInWithOverlap(pos)) {
1338 cell_to_remove.add(icell.localId());
1342 allCells(p).removeItems(cell_to_remove,
true);
1343 overlapCells(p).removeItems(cell_to_remove,
true);
1344 cell_to_remove.clear();
1347 has_cell_to_mark = m_cmesh->mesh()->parallelMng()->reduce(MessagePassing::ReduceMax, has_cell_to_mark);
1348 if (!has_cell_to_mark) {
1353 _updatePatchFlagsOfItemsLevel(level_to_reduce,
true);
1355 for (Integer p = 1; p < m_amr_patches_pointer.size(); ++p) {
1356 Int32 level = m_amr_patches_pointer[p]->_internalApi()->positionRef().level();
1357 if (level == level_to_reduce) {
1358 m_cmesh->computeDirectionsPatchV2(p);
1366void CartesianPatchGroup::
1370 Int32 higher_level_patch = 0;
1372 for (
const auto patch : m_amr_patches_pointer) {
1373 const Int32 level = patch->_internalApi()->positionRef().level();
1374 if (level > higher_level_patch) {
1375 higher_level_patch = level;
1379 if (higher_level_patch != m_higher_level) {
1380 for (Int32 level = 1; level <= higher_level_patch; ++level) {
1381 _changeOverlapSizeLevel(level, m_higher_level, higher_level_patch);
1384 m_higher_level = higher_level_patch;
1391void CartesianPatchGroup::
1392_changeOverlapSizeLevel(Int32 level, Int32 previous_higher_level, Int32 new_higher_level)
1394 if (previous_higher_level == new_higher_level) {
1398 Int32 old_overlap_size = ((level > previous_higher_level) ? 0 : AMRPatchPosition::computeOverlapLayerSize(level, previous_higher_level, m_size_of_overlap_layer_top_level));
1399 Int32 new_overlap_size = AMRPatchPosition::computeOverlapLayerSize(level, new_higher_level, m_size_of_overlap_layer_top_level);
1401 if (old_overlap_size == new_overlap_size) {
1404 if (old_overlap_size < new_overlap_size) {
1405 _increaseOverlapSizeLevel(level, new_overlap_size);
1408 _reduceOverlapSizeLevel(level, new_overlap_size);
1415void CartesianPatchGroup::
1416_coarsenUselessCells(
bool use_cells_level)
1418 Int32 higher_level_patch = m_higher_level;
1419 if (use_cells_level) {
1420 ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allCells()) {
1421 if (icell->level() > higher_level_patch) {
1422 higher_level_patch = icell->level();
1425 higher_level_patch = m_cmesh->mesh()->parallelMng()->reduce(MessagePassing::ReduceMax, higher_level_patch);
1429 for (Integer level = higher_level_patch; level > 0; --level) {
1430 _coarsenUselessCellsInLevel(level);
1437void CartesianPatchGroup::
1438_coarsenUselessCellsInLevel(Int32 level)
1440 Integer nb_cells_to_coarse = 0;
1441 ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allLevelCells(level)) {
1442 if (!icell->hasFlags(ItemFlags::II_InPatch) && !icell->hasFlags(ItemFlags::II_Overlap)) {
1444 icell->mutableItemBase().addFlags(ItemFlags::II_Coarsen);
1445 nb_cells_to_coarse++;
1448 debug() <<
"Remove " << nb_cells_to_coarse <<
" refined cells without flag in level " << level;
1449 nb_cells_to_coarse = m_cmesh->mesh()->parallelMng()->reduce(MessagePassing::ReduceMax, nb_cells_to_coarse);
1451 auto amr = m_cmesh->_internalApi()->cartesianMeshAMRPatchMng();
1452 if (nb_cells_to_coarse != 0) {
1460void CartesianPatchGroup::
1461_updatePatchFlagsOfItemsLevel(Int32 level,
bool use_cell_groups)
1464 _updatePatchFlagsOfItemsGroundLevel();
1468 auto numbering = m_cmesh->_internalApi()->cartesianMeshNumberingMngInternal();
1470 ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allLevelCells(level)) {
1471 icell->mutableItemBase().removeFlags(ItemFlags::II_InPatch | ItemFlags::II_Overlap);
1473 ENUMERATE_ (Face, iface, m_cmesh->mesh()->allLevelCells(level).faceGroup()) {
1474 iface->mutableItemBase().removeFlags(ItemFlags::II_InPatch | ItemFlags::II_Overlap);
1476 ENUMERATE_ (Node, inode, m_cmesh->mesh()->allLevelCells(level).nodeGroup()) {
1477 inode->mutableItemBase().removeFlags(ItemFlags::II_InPatch | ItemFlags::II_Overlap);
1483 if (use_cell_groups) {
1484 for (Integer p = 1; p < m_amr_patches_pointer.size(); ++p) {
1485 Int32 level_patch = m_amr_patches_pointer[p]->_internalApi()->positionRef().level();
1486 if (level_patch == level) {
1488 icell->mutableItemBase().addFlags(ItemFlags::II_InPatch);
1490 ENUMERATE_ (Face, iface, inPatchCells(p).faceGroup()) {
1491 iface->mutableItemBase().addFlags(ItemFlags::II_InPatch);
1493 ENUMERATE_ (Node, inode, inPatchCells(p).nodeGroup()) {
1494 inode->mutableItemBase().addFlags(ItemFlags::II_InPatch);
1498 icell->mutableItemBase().addFlags(ItemFlags::II_Overlap);
1500 ENUMERATE_ (Face, iface, overlapCells(p).faceGroup()) {
1501 iface->mutableItemBase().addFlags(ItemFlags::II_Overlap);
1503 ENUMERATE_ (Node, inode, overlapCells(p).nodeGroup()) {
1504 inode->mutableItemBase().addFlags(ItemFlags::II_Overlap);
1513 ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allLevelCells(level)) {
1514 bool in_overlap =
false;
1515 bool in_patch =
false;
1523 const CartCoord3 pos = numbering->cellUniqueIdToCoord(*icell);
1525 for (Integer p = 1; p < m_amr_patches_pointer.size(); ++p) {
1526 auto& patch = m_amr_patches_pointer[p]->_internalApi()->positionRef();
1527 if (patch.level() != level) {
1531 if (patch.isIn(pos)) {
1534 else if (patch.isInWithOverlap(pos)) {
1537 if (in_patch && in_overlap) {
1541 if (in_patch && in_overlap) {
1542 icell->mutableItemBase().addFlags(ItemFlags::II_InPatch | ItemFlags::II_Overlap);
1543 for (Face face : icell->faces()) {
1544 face.mutableItemBase().addFlags(ItemFlags::II_InPatch | ItemFlags::II_Overlap);
1546 for (Node node : icell->nodes()) {
1547 node.mutableItemBase().addFlags(ItemFlags::II_InPatch | ItemFlags::II_Overlap);
1550 else if (in_overlap) {
1551 icell->mutableItemBase().addFlags(ItemFlags::II_Overlap);
1552 icell->mutableItemBase().removeFlags(ItemFlags::II_InPatch);
1553 for (Face face : icell->faces()) {
1554 face.mutableItemBase().addFlags(ItemFlags::II_Overlap);
1556 for (Node node : icell->nodes()) {
1557 node.mutableItemBase().addFlags(ItemFlags::II_Overlap);
1560 else if (in_patch) {
1561 icell->mutableItemBase().addFlags(ItemFlags::II_InPatch);
1562 icell->mutableItemBase().removeFlags(ItemFlags::II_Overlap);
1563 for (Face face : icell->faces()) {
1564 face.mutableItemBase().addFlags(ItemFlags::II_InPatch);
1566 for (Node node : icell->nodes()) {
1567 node.mutableItemBase().addFlags(ItemFlags::II_InPatch);
1571 icell->mutableItemBase().removeFlags(ItemFlags::II_InPatch | ItemFlags::II_Overlap);
1580void CartesianPatchGroup::
1581_updatePatchFlagsOfItemsGroundLevel()
1583 ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allLevelCells(0)) {
1584 icell->mutableItemBase().addFlags(ItemFlags::II_InPatch);
1586 ENUMERATE_ (Face, iface, m_cmesh->mesh()->allLevelCells(0).faceGroup()) {
1587 iface->mutableItemBase().addFlags(ItemFlags::II_InPatch);
1589 ENUMERATE_ (Node, inode, m_cmesh->mesh()->allLevelCells(0).nodeGroup()) {
1590 inode->mutableItemBase().addFlags(ItemFlags::II_InPatch);
1597void CartesianPatchGroup::
1598_removePatchFlagsOfItemsLevel(Int32 level)
1600 ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allLevelCells(level)) {
1601 icell->mutableItemBase().removeFlags(ItemFlags::II_Overlap | ItemFlags::II_InPatch);
1603 ENUMERATE_ (Face, iface, m_cmesh->mesh()->allLevelCells(level).faceGroup()) {
1604 iface->mutableItemBase().removeFlags(ItemFlags::II_Overlap | ItemFlags::II_InPatch);
1606 ENUMERATE_ (Node, inode, m_cmesh->mesh()->allLevelCells(level).nodeGroup()) {
1607 inode->mutableItemBase().removeFlags(ItemFlags::II_Overlap | ItemFlags::II_InPatch);
1614void CartesianPatchGroup::
1615_checkPatchesAndMesh()
1617 auto numbering = m_cmesh->_internalApi()->cartesianMeshNumberingMngInternal();
1619 Int32 higher_level = 0;
1620 ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allCells()) {
1621 if (icell->level() > higher_level) {
1622 higher_level = icell->level();
1625 higher_level = m_cmesh->mesh()->parallelMng()->reduce(MessagePassing::ReduceMax, higher_level);
1626 if (higher_level != m_higher_level) {
1627 ARCANE_FATAL(
"_checkPatchesAndMesh -- Bad higher level -- m_higher_level : {0} -- Found : {1}", m_higher_level, higher_level);
1631 for (Int32 level = 0; level < m_higher_level; ++level) {
1632 Int32 check_overlap = overlapLayerSize(level);
1633 for (Integer p = 0; p < m_amr_patches_pointer.size(); ++p) {
1634 auto& position = m_amr_patches_pointer[p]->_internalApi()->positionRef();
1635 if (position.level() == level) {
1636 if (check_overlap == -1) {
1637 check_overlap = position.overlapLayerSize();
1639 else if (check_overlap != position.overlapLayerSize()) {
1640 ARCANE_FATAL(
"_checkPatchesAndMesh -- Overlap size incoherence -- Patch pos : {0} -- Previous size : {1} -- Found : {2}", p, check_overlap, position.overlapLayerSize());
1649 ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allCells()) {
1650 Integer level = icell->level();
1652 bool in_overlap =
false;
1653 bool in_patch =
false;
1655 const CartCoord3 pos = numbering->cellUniqueIdToCoord(*icell);
1657 for (
auto p : m_amr_patches_pointer) {
1658 auto& patch = p->_internalApi()->positionRef();
1659 if (patch.level() != level) {
1663 if (patch.isIn(pos)) {
1666 else if (patch.isInWithOverlap(pos)) {
1669 if (in_patch && in_overlap) {
1673 if (in_patch && in_overlap) {
1674 icell->mutableItemBase().addFlags(ItemFlags::II_UserMark1);
1675 icell->mutableItemBase().addFlags(ItemFlags::II_UserMark2);
1677 else if (in_overlap) {
1678 icell->mutableItemBase().addFlags(ItemFlags::II_UserMark1);
1679 icell->mutableItemBase().removeFlags(ItemFlags::II_UserMark2);
1681 else if (in_patch) {
1682 icell->mutableItemBase().addFlags(ItemFlags::II_UserMark2);
1683 icell->mutableItemBase().removeFlags(ItemFlags::II_UserMark1);
1686 icell->mutableItemBase().removeFlags(ItemFlags::II_UserMark2);
1687 icell->mutableItemBase().removeFlags(ItemFlags::II_UserMark1);
1690 ENUMERATE_ (Face, iface, m_cmesh->mesh()->allFaces()) {
1691 Int32 max_level = 0;
1692 for (Cell cell : iface->cells()) {
1693 if (cell.level() > max_level) {
1694 max_level = cell.level();
1697 for (Cell cell : iface->cells()) {
1698 if (cell.level() != max_level) {
1701 if (cell.hasFlags(ItemFlags::II_UserMark1)) {
1702 iface->mutableItemBase().addFlags(ItemFlags::II_UserMark1);
1704 if (cell.hasFlags(ItemFlags::II_UserMark2)) {
1705 iface->mutableItemBase().addFlags(ItemFlags::II_UserMark2);
1709 ENUMERATE_ (Node, inode, m_cmesh->mesh()->allNodes()) {
1710 Int32 max_level = 0;
1711 for (Cell cell : inode->cells()) {
1712 if (cell.level() > max_level) {
1713 max_level = cell.level();
1716 for (Cell cell : inode->cells()) {
1717 if (cell.level() != max_level) {
1720 if (cell.hasFlags(ItemFlags::II_UserMark1)) {
1721 inode->mutableItemBase().addFlags(ItemFlags::II_UserMark1);
1723 if (cell.hasFlags(ItemFlags::II_UserMark2)) {
1724 inode->mutableItemBase().addFlags(ItemFlags::II_UserMark2);
1729 ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allCells()) {
1730 if (icell->hasFlags(ItemFlags::II_UserMark1)) {
1731 if (!icell->hasFlags(ItemFlags::II_Overlap)) {
1732 ARCANE_FATAL(
"_checkPatchesAndMesh -- II_UserMark1 but not II_Overlap -- CellUID : {0}", icell->uniqueId());
1735 if (icell->hasFlags(ItemFlags::II_UserMark2)) {
1736 if (!icell->hasFlags(ItemFlags::II_InPatch)) {
1737 ARCANE_FATAL(
"_checkPatchesAndMesh -- II_UserMark2 but not II_InPatch -- CellUID : {0}", icell->uniqueId());
1740 if (icell->hasFlags(ItemFlags::II_Overlap)) {
1741 if (!icell->hasFlags(ItemFlags::II_UserMark1)) {
1742 ARCANE_FATAL(
"_checkPatchesAndMesh -- II_Overlap but not II_UserMark1 -- CellUID : {0}", icell->uniqueId());
1745 if (icell->hasFlags(ItemFlags::II_InPatch)) {
1746 if (!icell->hasFlags(ItemFlags::II_UserMark2)) {
1747 ARCANE_FATAL(
"_checkPatchesAndMesh -- II_InPatch but not II_UserMark2 -- CellUID : {0}", icell->uniqueId());
1753 icell->mutableItemBase().removeFlags(ItemFlags::II_UserMark1);
1754 icell->mutableItemBase().removeFlags(ItemFlags::II_UserMark2);
1756 ENUMERATE_ (Face, iface, m_cmesh->mesh()->allFaces()) {
1757 if (iface->hasFlags(ItemFlags::II_UserMark1)) {
1758 if (!iface->hasFlags(ItemFlags::II_Overlap)) {
1759 ARCANE_FATAL(
"_checkPatchesAndMesh -- II_UserMark1 but not II_Overlap -- FaceUID : {0}", iface->uniqueId());
1762 if (iface->hasFlags(ItemFlags::II_UserMark2)) {
1763 if (!iface->hasFlags(ItemFlags::II_InPatch)) {
1764 ARCANE_FATAL(
"_checkPatchesAndMesh -- II_UserMark2 but not II_InPatch -- FaceUID : {0}", iface->uniqueId());
1767 if (iface->hasFlags(ItemFlags::II_Overlap)) {
1768 if (!iface->hasFlags(ItemFlags::II_UserMark1)) {
1769 ARCANE_FATAL(
"_checkPatchesAndMesh -- II_Overlap but not II_UserMark1 -- FaceUID : {0}", iface->uniqueId());
1772 if (iface->hasFlags(ItemFlags::II_InPatch)) {
1773 if (!iface->hasFlags(ItemFlags::II_UserMark2)) {
1774 ARCANE_FATAL(
"_checkPatchesAndMesh -- II_InPatch but not II_UserMark2 -- FaceUID : {0}", iface->uniqueId());
1778 iface->mutableItemBase().removeFlags(ItemFlags::II_UserMark1);
1779 iface->mutableItemBase().removeFlags(ItemFlags::II_UserMark2);
1781 ENUMERATE_ (Node, inode, m_cmesh->mesh()->allNodes()) {
1782 if (inode->hasFlags(ItemFlags::II_UserMark1)) {
1783 if (!inode->hasFlags(ItemFlags::II_Overlap)) {
1784 ARCANE_FATAL(
"_checkPatchesAndMesh -- II_UserMark1 but not II_Overlap -- NodeUID : {0}", inode->uniqueId());
1787 if (inode->hasFlags(ItemFlags::II_UserMark2)) {
1788 if (!inode->hasFlags(ItemFlags::II_InPatch)) {
1789 ARCANE_FATAL(
"_checkPatchesAndMesh -- II_UserMark2 but not II_InPatch -- NodeUID : {0}", inode->uniqueId());
1792 if (inode->hasFlags(ItemFlags::II_Overlap)) {
1793 if (!inode->hasFlags(ItemFlags::II_UserMark1)) {
1794 ARCANE_FATAL(
"_checkPatchesAndMesh -- II_Overlap but not II_UserMark1 -- NodeUID : {0}", inode->uniqueId());
1797 if (inode->hasFlags(ItemFlags::II_InPatch)) {
1798 if (!inode->hasFlags(ItemFlags::II_UserMark2)) {
1799 ARCANE_FATAL(
"_checkPatchesAndMesh -- II_InPatch but not II_UserMark2 -- NodeUID : {0}", inode->uniqueId());
1803 inode->mutableItemBase().removeFlags(ItemFlags::II_UserMark1);
1804 inode->mutableItemBase().removeFlags(ItemFlags::II_UserMark2);
1812void CartesianPatchGroup::
1813clearRefineRelatedFlags()
const
1815 constexpr ItemFlags::FlagType flags_to_remove = (ItemFlags::II_Coarsen | ItemFlags::II_Refine |
1816 ItemFlags::II_JustCoarsened | ItemFlags::II_JustRefined |
1817 ItemFlags::II_JustAdded | ItemFlags::II_CoarsenInactive);
1818 ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allCells()) {
1819 icell->mutableItemBase().removeFlags(flags_to_remove);
1826void CartesianPatchGroup::
1827rebuildAvailableGroupIndex(ConstArrayView<Integer> available_group_index)
1829 m_available_group_index = available_group_index;
1835ConstArrayView<Int32> CartesianPatchGroup::
1836availableGroupIndex()
1838 return m_available_group_index;
1844void CartesianPatchGroup::
1845setOverlapLayerSizeTopLevel(Int32 size_of_overlap_layer_top_level)
1847 auto numbering = m_cmesh->_internalApi()->cartesianMeshNumberingMngInternal();
1849 Int32 new_size_of_overlap_layer_top_level = 0;
1851 if (size_of_overlap_layer_top_level == -1)
1852 new_size_of_overlap_layer_top_level = -1;
1856 new_size_of_overlap_layer_top_level = size_of_overlap_layer_top_level + (size_of_overlap_layer_top_level % numbering->pattern());
1858 if (new_size_of_overlap_layer_top_level == m_size_of_overlap_layer_top_level) {
1864 for (Int32 level = 1; level <= m_higher_level; ++level) {
1865 Int32 old_overlap_size = AMRPatchPosition::computeOverlapLayerSize(level, m_higher_level, m_size_of_overlap_layer_top_level);
1866 Int32 new_overlap_size = AMRPatchPosition::computeOverlapLayerSize(level, m_higher_level, new_size_of_overlap_layer_top_level);
1868 if (old_overlap_size == new_overlap_size) {
1871 if (old_overlap_size < new_overlap_size) {
1872 _increaseOverlapSizeLevel(level, new_overlap_size);
1875 _reduceOverlapSizeLevel(level, new_overlap_size);
1878 m_size_of_overlap_layer_top_level = new_size_of_overlap_layer_top_level;
1884Int32 CartesianPatchGroup::
1885overlapLayerSize(Int32 level)
1894 Int32 higher_level = m_higher_level;
1895 if (m_target_nb_levels != 0) {
1896 higher_level = m_target_nb_levels - 1;
1898 return AMRPatchPosition::computeOverlapLayerSize(level, higher_level, m_size_of_overlap_layer_top_level);
1904void CartesianPatchGroup::
1905_addPatchInstance(Ref<CartesianMeshPatch> v)
1907 m_amr_patches.add(v);
1908 m_amr_patches_pointer.add(v.get());
1914void CartesianPatchGroup::
1915_removeOnePatch(Integer index)
1917 m_available_group_index.add(m_amr_patches[index]->index());
1920 m_amr_patch_cell_groups_all[index].clear();
1921 m_amr_patch_cell_groups_all.remove(index);
1923 if (m_cmesh->mesh()->meshKind().meshAMRKind() == eMeshAMRKind::PatchCartesianMeshOnly) {
1924 m_amr_patch_cell_groups_inpatch[index].clear();
1925 m_amr_patch_cell_groups_inpatch.remove(index);
1926 m_amr_patch_cell_groups_overlap[index].clear();
1927 m_amr_patch_cell_groups_overlap.remove(index);
1930 m_amr_patches_pointer.remove(index);
1931 m_amr_patches.remove(index);
1938void CartesianPatchGroup::
1939_removeMultiplePatches(ConstArrayView<Integer> indexes)
1942 for (
const Integer index : indexes) {
1943 _removeOnePatch(index - count);
1951void CartesianPatchGroup::
1954 for (Integer i = 1; i < m_amr_patch_cell_groups_all.size(); ++i) {
1955 m_amr_patch_cell_groups_all[i].clear();
1957 m_amr_patch_cell_groups_all.clear();
1959 if (m_cmesh->mesh()->meshKind().meshAMRKind() == eMeshAMRKind::PatchCartesianMeshOnly) {
1960 for (Integer i = 0; i < m_amr_patch_cell_groups_inpatch.size(); ++i) {
1961 m_amr_patch_cell_groups_inpatch[i].clear();
1962 m_amr_patch_cell_groups_overlap[i].clear();
1964 m_amr_patch_cell_groups_inpatch.clear();
1965 m_amr_patch_cell_groups_overlap.clear();
1968 m_amr_patches_pointer.clear();
1969 m_amr_patches.clear();
1970 m_available_group_index.clear();
1971 m_patches_to_delete.clear();
1972 m_index_new_patches = 1;
1980void CartesianPatchGroup::
1983 if (!m_amr_patches.empty())
1985 auto patch =
makeRef(
new CartesianMeshPatch(m_cmesh, -1));
1987 if (m_cmesh->mesh()->meshKind().meshAMRKind() == eMeshAMRKind::PatchCartesianMeshOnly) {
1988 auto numbering = m_cmesh->_internalApi()->cartesianMeshNumberingMngInternal();
1989 patch->_internalApi()->positionRef().setMinPoint({ 0, 0, 0 });
1990 patch->_internalApi()->positionRef().setMaxPoint({ numbering->globalNbCellsX(0), numbering->globalNbCellsY(0), numbering->globalNbCellsZ(0) });
1991 patch->_internalApi()->positionRef().setLevel(0);
1994 _addPatchInstance(patch);
1995 _addCellGroup(m_cmesh->mesh()->allLevelCells(0), patch.get(),
true);
2002_addCellGroup(CellGroup cell_group, CartesianMeshPatch* patch,
bool add_flags)
2004 m_amr_patch_cell_groups_all.add(cell_group);
2006 if (m_cmesh->mesh()->meshKind().meshAMRKind() != eMeshAMRKind::PatchCartesianMeshOnly) {
2010 return m_amr_patch_cell_groups_all.size() - 1;
2013 AMRPatchPosition patch_position = patch->position();
2014 Ref<ICartesianMeshNumberingMngInternal> numbering = m_cmesh->_internalApi()->cartesianMeshNumberingMngInternal();
2016 UniqueArray<Int32> inpatch_items_lid;
2017 UniqueArray<Int32> overlap_items_lid;
2021 const CartCoord3 pos = numbering->cellUniqueIdToCoord(cell);
2023 if (patch_position.isIn(pos)) {
2024 inpatch_items_lid.add(cell.localId());
2027 overlap_items_lid.add(cell.localId());
2032 m_amr_patch_cell_groups_inpatch.add(own);
2035 m_amr_patch_cell_groups_overlap.add(overlap);
2042 icell->mutableItemBase().addFlags(ItemFlags::II_InPatch);
2045 iface->mutableItemBase().addFlags(ItemFlags::II_InPatch);
2048 inode->mutableItemBase().addFlags(ItemFlags::II_InPatch);
2052 icell->mutableItemBase().addFlags(ItemFlags::II_Overlap);
2054 ENUMERATE_ (Face, iface, overlap.faceGroup()) {
2055 iface->mutableItemBase().addFlags(ItemFlags::II_Overlap);
2057 ENUMERATE_ (Node, inode, overlap.nodeGroup()) {
2058 inode->mutableItemBase().addFlags(ItemFlags::II_Overlap);
2062 return m_amr_patch_cell_groups_all.
size() - 1;
2068void CartesianPatchGroup::
2069_updateCellGroups(Integer index,
bool update_flags)
2071 if (m_cmesh->mesh()->meshKind().meshAMRKind() != eMeshAMRKind::PatchCartesianMeshOnly) {
2072 ARCANE_FATAL(
"Method available only with AMR PatchCartesianMeshOnly");
2075 CellGroup patch_all_cells = allCells(index);
2076 CellGroup patch_inpatch = inPatchCells(index);
2077 CellGroup patch_overlap = overlapCells(index);
2079 patch_all_cells.clear();
2080 patch_inpatch.clear();
2081 patch_overlap.clear();
2083 const auto& position = patch(index)->_internalApi()->positionRef();
2085 Int32 level = position.level();
2087 UniqueArray<Int32> inpatch_items_lid;
2088 UniqueArray<Int32> overlap_items_lid;
2090 auto numbering = m_cmesh->_internalApi()->cartesianMeshNumberingMngInternal();
2093 ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allLevelCells(level)) {
2094 const CartCoord3 pos = numbering->cellUniqueIdToCoord(*icell);
2096 if (position.isIn(pos)) {
2097 inpatch_items_lid.add(icell.localId());
2099 else if (position.isInWithOverlap(pos)) {
2100 overlap_items_lid.add(icell.localId());
2104 patch_all_cells.addItems(inpatch_items_lid,
false);
2105 patch_all_cells.addItems(overlap_items_lid,
false);
2107 patch_inpatch.addItems(inpatch_items_lid,
false);
2108 patch_overlap.addItems(overlap_items_lid,
false);
2112 icell->mutableItemBase().addFlags(ItemFlags::II_InPatch);
2114 ENUMERATE_ (Face, iface, patch_inpatch.faceGroup()) {
2115 iface->mutableItemBase().addFlags(ItemFlags::II_InPatch);
2117 ENUMERATE_ (Node, inode, patch_inpatch.nodeGroup()) {
2118 inode->mutableItemBase().addFlags(ItemFlags::II_InPatch);
2122 icell->mutableItemBase().addFlags(ItemFlags::II_Overlap);
2124 ENUMERATE_ (Face, iface, patch_overlap.faceGroup()) {
2125 iface->mutableItemBase().addFlags(ItemFlags::II_Overlap);
2127 ENUMERATE_ (Node, inode, patch_overlap.nodeGroup()) {
2128 inode->mutableItemBase().addFlags(ItemFlags::II_Overlap);
2140void CartesianPatchGroup::
2141_removePartOfPatch(Integer index_patch_to_edit,
const AMRPatchPosition& part_to_remove)
2171 std::pair to_return{ -1, -1 };
2172 if (p1_min > p0_min && p1_min < p0_max) {
2173 to_return.first = p1_min;
2175 if (p1_max > p0_min && p1_max < p0_max) {
2176 to_return.second = p1_max;
2181 ICartesianMeshPatch* patch = m_amr_patches_pointer[index_patch_to_edit];
2182 AMRPatchPosition patch_position = patch->position();
2184 UniqueArray<AMRPatchPosition> new_patch_out;
2186 CartCoord3 min_point_of_patch_to_exclude(-1, -1, -1);
2190 UniqueArray<AMRPatchPosition> new_patch_in;
2194 auto cut_point_x = cut_points_p0(patch_position.minPoint().x, patch_position.maxPoint().x, part_to_remove.minPoint().x, part_to_remove.maxPoint().x);
2198 if (cut_point_x.first == -1 && cut_point_x.second == -1) {
2199 min_point_of_patch_to_exclude.x = patch_position.minPoint().x;
2200 new_patch_out.add(patch_position);
2204 else if (cut_point_x.second == -1) {
2205 min_point_of_patch_to_exclude.x = cut_point_x.first;
2206 auto [fst, snd] = patch_position.cut(cut_point_x.first, MD_DirX);
2207 new_patch_out.add(fst);
2208 new_patch_out.add(snd);
2212 else if (cut_point_x.first == -1) {
2213 min_point_of_patch_to_exclude.x = patch_position.minPoint().x;
2214 auto [fst, snd] = patch_position.cut(cut_point_x.second, MD_DirX);
2215 new_patch_out.add(fst);
2216 new_patch_out.add(snd);
2221 min_point_of_patch_to_exclude.x = cut_point_x.first;
2222 auto [fst, snd_thr] = patch_position.cut(cut_point_x.first, MD_DirX);
2223 new_patch_out.add(fst);
2224 auto [snd, thr] = snd_thr.cut(cut_point_x.second, MD_DirX);
2225 new_patch_out.add(snd);
2226 new_patch_out.add(thr);
2232 std::swap(new_patch_out, new_patch_in);
2234 auto cut_point_y = cut_points_p0(patch_position.minPoint().y, patch_position.maxPoint().y, part_to_remove.minPoint().y, part_to_remove.maxPoint().y);
2238 if (cut_point_y.first == -1 && cut_point_y.second == -1) {
2239 for (
const AMRPatchPosition& patch_x : new_patch_in) {
2240 min_point_of_patch_to_exclude.y = patch_x.minPoint().y;
2241 new_patch_out.add(patch_x);
2246 else if (cut_point_y.second == -1) {
2247 min_point_of_patch_to_exclude.y = cut_point_y.first;
2248 for (
const AMRPatchPosition& patch_x : new_patch_in) {
2249 auto [fst, snd] = patch_x.cut(cut_point_y.first, MD_DirY);
2250 new_patch_out.add(fst);
2251 new_patch_out.add(snd);
2256 else if (cut_point_y.first == -1) {
2257 for (
const AMRPatchPosition& patch_x : new_patch_in) {
2258 min_point_of_patch_to_exclude.y = patch_x.minPoint().y;
2259 auto [fst, snd] = patch_x.cut(cut_point_y.second, MD_DirY);
2260 new_patch_out.add(fst);
2261 new_patch_out.add(snd);
2267 min_point_of_patch_to_exclude.y = cut_point_y.first;
2268 for (
const AMRPatchPosition& patch_x : new_patch_in) {
2269 auto [fst, snd_thr] = patch_x.cut(cut_point_y.first, MD_DirY);
2270 new_patch_out.add(fst);
2271 auto [snd, thr] = snd_thr.cut(cut_point_y.second, MD_DirY);
2272 new_patch_out.add(snd);
2273 new_patch_out.add(thr);
2279 if (m_cmesh->mesh()->dimension() == 3) {
2280 std::swap(new_patch_out, new_patch_in);
2281 new_patch_out.clear();
2283 auto cut_point_z = cut_points_p0(patch_position.minPoint().z, patch_position.maxPoint().z, part_to_remove.minPoint().z, part_to_remove.maxPoint().z);
2287 if (cut_point_z.first == -1 && cut_point_z.second == -1) {
2288 for (
const AMRPatchPosition& patch_y : new_patch_in) {
2289 min_point_of_patch_to_exclude.z = patch_y.minPoint().z;
2290 new_patch_out.add(patch_y);
2295 else if (cut_point_z.second == -1) {
2296 for (
const AMRPatchPosition& patch_y : new_patch_in) {
2297 min_point_of_patch_to_exclude.z = cut_point_z.first;
2298 auto [fst, snd] = patch_y.cut(cut_point_z.first, MD_DirZ);
2299 new_patch_out.add(fst);
2300 new_patch_out.add(snd);
2305 else if (cut_point_z.first == -1) {
2306 for (
const AMRPatchPosition& patch_y : new_patch_in) {
2307 min_point_of_patch_to_exclude.z = patch_y.minPoint().z;
2308 auto [fst, snd] = patch_y.cut(cut_point_z.second, MD_DirZ);
2309 new_patch_out.add(fst);
2310 new_patch_out.add(snd);
2316 for (
const AMRPatchPosition& patch_y : new_patch_in) {
2317 min_point_of_patch_to_exclude.z = cut_point_z.first;
2318 auto [fst, snd_thr] = patch_y.cut(cut_point_z.first, MD_DirZ);
2319 new_patch_out.add(fst);
2320 auto [snd, thr] = snd_thr.cut(cut_point_z.second, MD_DirZ);
2321 new_patch_out.add(snd);
2322 new_patch_out.add(thr);
2330 if (m_cmesh->mesh()->dimension() == 2) {
2331 min_point_of_patch_to_exclude.z = 0;
2337 for (AMRPatchPosition& new_patch : new_patch_out) {
2338 if (new_patch.minPoint() == min_point_of_patch_to_exclude) {
2339 new_patch.setLevel(-2);
2349 AMRPatchPositionLevelGroup::fusionPatches(new_patch_out,
false);
2353 for (
const auto& new_patch : new_patch_out) {
2354 if (!new_patch.isNull()) {
2359 _addCutPatch(new_patch, allCells(index_patch_to_edit));
2366 removePatch(index_patch_to_edit);
2372void CartesianPatchGroup::
2373_addCutPatch(
const AMRPatchPosition& new_patch_position, CellGroup parent_patch_cell_group)
2378 if (parent_patch_cell_group.null())
2381 IItemFamily* cell_family = m_cmesh->mesh()->cellFamily();
2382 Integer group_index = _nextIndexForNewPatch();
2383 String patch_group_name = String(
"CartesianMeshPatchCells") + group_index;
2385 auto* cdi =
new CartesianMeshPatch(m_cmesh, group_index, new_patch_position);
2386 _addPatchInstance(
makeRef(cdi));
2388 UniqueArray<Int32> cells_local_id;
2390 auto numbering = m_cmesh->_internalApi()->cartesianMeshNumberingMngInternal();
2391 ENUMERATE_ (Cell, icell, parent_patch_cell_group) {
2392 const CartCoord3 pos = numbering->cellUniqueIdToCoord(*icell);
2393 if (new_patch_position.isIn(pos)) {
2394 cells_local_id.add(icell.localId());
2398 CellGroup parent_cells = cell_family->createGroup(patch_group_name, cells_local_id,
true);
2400 _addCellGroup(parent_cells, cdi,
false);
2413_addPatch(
const AMRPatchPosition& new_patch_position)
2415 UniqueArray<Int32> cells_local_id;
2417 auto numbering = m_cmesh->_internalApi()->cartesianMeshNumberingMngInternal();
2420 ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allLevelCells(new_patch_position.level())) {
2421 const CartCoord3 pos = numbering->cellUniqueIdToCoord(*icell);
2423 if (new_patch_position.isInWithOverlap(pos)) {
2424 cells_local_id.add(icell.localId());
2428 IItemFamily* cell_family = m_cmesh->mesh()->cellFamily();
2429 Integer group_index = _nextIndexForNewPatch();
2430 String patch_group_name = String(
"CartesianMeshPatchCells") + group_index;
2432 auto* cdi =
new CartesianMeshPatch(m_cmesh, group_index, new_patch_position);
2434 _addPatchInstance(
makeRef(cdi));
2435 CellGroup parent_cells = cell_family->createGroup(patch_group_name, cells_local_id,
true);
2436 Integer array_index = _addCellGroup(parent_cells, cdi,
true);
#define ARCANE_FATAL(...)
Macro throwing a FatalErrorException.
Class allowing the definition of a patch position in the Cartesian mesh.
AMRPatchPosition patchUp(Integer dim, Int32 higher_level, Int32 overlap_layer_size_top_level) const
Method to create an AMRPatchPosition for the higher level.
bool isInWithOverlap(CartCoord x, CartCoord y, CartCoord z) const
Method to know if a cell at position x,y,z is included in this patch with overlap layer.
static Int32 computeOverlapLayerSize(Int32 level, Int32 higher_level, Int32 overlap_layer_size_top_level)
Method to calculate the number of overlap cell layers for a given level.
CartCoord3 minPoint() const
Method to retrieve the min position of the enclosing box.
void setMinPoint(CartCoord3 min_point)
Method to set the min position of the enclosing box.
void setLevel(Int32 level)
Method to set the patch level.
CartCoord3 maxPoint() const
Method to retrieve the max position of the enclosing box.
bool haveIntersection(const AMRPatchPosition &other) const
Method to know if our patch is in contact with other.
Int32 overlapLayerSize() const
Method to retrieve the number of overlap cell layers of the patch.
void setOverlapLayerSize(Int32 layer_size)
Method to set the number of overlap cell layers of the patch.
Int32 level() const
Method to retrieve the patch level.
void setMaxPoint(CartCoord3 max_point)
Method to set the max position of the enclosing box.
Class allowing the definition of a mesh zone.
void cellsInPatch(IMesh *mesh, UniqueArray< Int32 > &cells_local_id) const
Method allowing retrieval of the cells included in the zone.
Real3 length() const
Method allowing retrieval of the zone's size.
Real3 position() const
Method allowing retrieval of the zone's position.
AMRPatchPosition toAMRPatchPosition(ICartesianMesh *mesh) const
Method allowing conversion of this AMRZonePosition into AMRPatchPosition.
Integer size() const
Number of elements in the vector.
CellGroup allCells(Integer index)
Method to retrieve the group of all cells in the requested patch.
void applyPatchEdit(bool remove_empty_patches, bool update_higher_level)
Method to delete patches pending deletion.
Constant view of an array of type T.
Interface of an AMR patch of a Cartesian mesh.
Interface of a Cartesian mesh.
Interface of an entity family.
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 IMesh * mesh() const =0
Associated mesh.
virtual IItemFamily * cellFamily()=0
Returns the cell family.
@ II_Refine
The entity is marked for refinement.
const String & name() const
Group name.
Integer size() const
Number of elements in the group.
IMesh * mesh() const
Mesh to which this group belongs (0 for the null group).
Reference to an instance.
Unicode character string.
bool startsWith(const String &s) const
Indicates if the string starts with the characters of s.
const char * localstr() const
Returns the conversion of the instance into UTF-8 encoding.
String substring(Int64 pos) const
Substring starting at position pos.
TraceMessageDbg debug(Trace::eDebugLevel=Trace::Medium) const
Flow for a debug message.
TraceMessage info() const
Flow for an information message.
ITraceMng * traceMng() const
Trace manager.
1D data vector with value semantics (STL style).
__host__ __device__ Real2 min(Real2 a, Real2 b)
Returns the minimum of two Real2.
T max(const T &a, const T &b, const T &c)
Returns the maximum of three elements.
ItemGroupT< Cell > CellGroup
Group of cells.
@ ReduceMax
Maximum of values.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
Int32 CartCoord
Represents a coordinate of an element in the Cartesian grid (in X or Y or Z).
Int32 Integer
Type representing an integer.
auto makeRef(InstanceType *t) -> Ref< InstanceType >
Creates a reference on a pointer.
@ Cell
The mesh is AMR by cell.
@ PatchCartesianMeshOnly
The mesh is AMR by Cartesian patch (rectangular).
std::int32_t Int32
Signed integer type of 32 bits.
Int32x3 CartCoord3
Represents the 3D coordinates of an element in the Cartesian grid {x, y, z}.