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);
117 m_properties->set(
"PatchGroupNamesAvailable", m_available_group_index);
118 m_properties->set(
"PatchGroupNames", patch_group_names);
125void CartesianPatchGroup::
128 Trace::Setter mci(traceMng(),
"CartesianPatchGroup");
131 Int32 v = m_properties->getInt32(
"Version");
133 ARCANE_FATAL(
"Bad serializer version: trying to read from incompatible checkpoint v={0} expected={1}", v, 1);
137 _createGroundPatch();
140 UniqueArray<String> patch_group_names;
141 m_properties->get(
"PatchGroupNames", patch_group_names);
143 if (m_cmesh->mesh()->meshKind().meshAMRKind() != eMeshAMRKind::PatchCartesianMeshOnly) {
144 info(4) <<
"Found n=" << patch_group_names.size() <<
" patchs";
146 IItemFamily* cell_family = m_cmesh->mesh()->cellFamily();
147 for (
const String& x : patch_group_names) {
148 CellGroup group = cell_family->findGroup(x);
151 _addPatchAfterRestore(group);
155 UniqueArray<Int32> level;
156 UniqueArray<Int32> overlap;
157 UniqueArray<Int32> index;
158 UniqueArray<CartCoord> min_point;
159 UniqueArray<CartCoord> max_point;
161 m_properties->get(
"LevelPatches", level);
162 m_properties->get(
"OverlapSizePatches", overlap);
163 m_properties->get(
"IndexPatches", index);
164 m_properties->get(
"MinPointPatches", min_point);
165 m_properties->get(
"MaxPointPatches", max_point);
167 IItemFamily* cell_family = m_cmesh->mesh()->cellFamily();
170 for (Integer pos_in_array = 0; pos_in_array < index.size(); ++pos_in_array) {
171 ConstArrayView
min(min_point.subConstView(pos_in_array * 3, 3));
172 ConstArrayView
max(max_point.subConstView(pos_in_array * 3, 3));
174 AMRPatchPosition position(
178 overlap[pos_in_array]);
180 const String& x = patch_group_names[pos_in_array];
181 CellGroup cell_group = cell_family->findGroup(x);
182 if (cell_group.null())
185 auto* cdi =
new CartesianMeshPatch(m_cmesh, index[pos_in_array], position);
186 _addPatchInstance(
makeRef(cdi));
187 _addCellGroup(cell_group, cdi,
true);
190 UniqueArray<Int32> available_index;
191 m_properties->get(
"PatchGroupNamesAvailable", available_index);
192 rebuildAvailableGroupIndex(available_index);
202 _createGroundPatch();
209void CartesianPatchGroup::
216 Integer index = _nextIndexForNewPatch();
217 String children_group_name =
String(
"CartesianMeshPatchCells") + index;
220 _addPatch(children_cells, index);
228_addPatchAfterRestore(
CellGroup cell_group)
232 if (name.
startsWith(
"CartesianMeshPatchCells")) {
234 group_index = std::stoi(index_str.
localstr());
240 _addPatch(cell_group, group_index);
247void CartesianPatchGroup::
248_addPatch(CellGroup cell_group, Integer group_index)
250 _createGroundPatch();
251 if (group_index == -1) {
254 if (cell_group.null())
257 AMRPatchPosition position;
259 auto* cdi =
new CartesianMeshPatch(m_cmesh, group_index, position);
260 _addPatchInstance(
makeRef(cdi));
261 _addCellGroup(cell_group, cdi,
true);
267void CartesianPatchGroup::
271 ARCANE_FATAL(
"Method available only with AMR PatchCartesianMeshOnly");
276 info() <<
"addPatch() with zone"
277 <<
" -- Position : " << zone_position.
position()
278 <<
" -- Length : " << zone_position.
length();
280 clearRefineRelatedFlags();
282 auto amr = m_cmesh->_internalApi()->cartesianMeshAMRPatchMng();
283 auto numbering = m_cmesh->_internalApi()->cartesianMeshNumberingMngInternal();
292 Int32 level_up = level + 1;
293 Int32 nb_overlap_cells = 0;
295 Int32 higher_level = m_higher_level;
300 if (level_up >= higher_level) {
301 higher_level = level_up;
306 nb_overlap_cells = m_size_of_overlap_layer_top_level / numbering->pattern();
307 debug() <<
"Higher level -- Old : " << m_higher_level <<
" -- New : " << higher_level;
323 nb_overlap_cells = overlapLayerSize(level + 1) / numbering->pattern();
327 debug() <<
"Zone to intermediary patch"
328 <<
" -- minPoint : " << position.
minPoint()
329 <<
" -- maxPoint : " << position.
maxPoint()
331 <<
" -- level : " << level;
337 if (!icell->hasHChildren()) {
338 const CartCoord3 pos = numbering->cellUniqueIdToCoord(*icell);
348 AMRPatchPosition position_up = position.
patchUp(m_cmesh->mesh()->dimension(), higher_level, m_size_of_overlap_layer_top_level);
350 info() <<
"Zone to Patch"
351 <<
" -- minPoint : " << position_up.
minPoint()
352 <<
" -- maxPoint : " << position_up.
maxPoint()
354 <<
" -- level : " << position_up.
level();
357 _addPatch(position_up);
362 _updateHigherLevel();
365 _checkPatchesAndMesh();
375 return m_amr_patches.size();
381Ref<CartesianMeshPatch> CartesianPatchGroup::
382patch(
const Integer index)
const
384 return m_amr_patches[index];
390CartesianMeshPatchListView CartesianPatchGroup::
393 return CartesianMeshPatchListView{ m_amr_patches_pointer };
402 return m_amr_patch_cell_groups_all[index];
412 ARCANE_FATAL(
"Method available only with AMR PatchCartesianMeshOnly");
414 return m_amr_patch_cell_groups_inpatch[index];
424 ARCANE_FATAL(
"Method available only with AMR PatchCartesianMeshOnly");
426 return m_amr_patch_cell_groups_overlap[index];
434void CartesianPatchGroup::
443void CartesianPatchGroup::
444removePatch(
const Integer index)
446 if (m_patches_to_delete.contains(index)) {
452 if (index < 1 || index >= m_amr_patches.size()) {
456 m_patches_to_delete.add(index);
462void CartesianPatchGroup::
470 for (
Integer i = 1; i < m_amr_patch_cell_groups_all.size(); ++i) {
471 allCells(i).removeItems(cells_local_id);
479void CartesianPatchGroup::
484 const Integer nb_patchs = m_amr_patches_pointer.size();
485 for (
Integer i = 1; i < nb_patchs; ++i) {
496 _removePartOfPatch(i, zone_to_delete);
504void CartesianPatchGroup::
508 ARCANE_FATAL(
"Method available only with AMR PatchCartesianMeshOnly");
510 clearRefineRelatedFlags();
515 zone_to_delete.
cellsInPatch(m_cmesh, cells_local_id, patch_position);
517 _removeCellsInAllPatches(patch_position);
519 _updatePatchFlagsOfItemsLevel(patch_position.
level(),
true);
520 _updateHigherLevel();
521 _coarsenUselessCells(
true);
524 _checkPatchesAndMesh();
531void CartesianPatchGroup::
532applyPatchEdit(
bool remove_empty_patches,
bool update_higher_level)
536 std::stable_sort(m_patches_to_delete.begin(), m_patches_to_delete.end(),
541 _removeMultiplePatches(m_patches_to_delete);
542 m_patches_to_delete.clear();
547 for (
Integer i = 0; i < m_amr_patch_cell_groups_all.size(); ++i) {
548 size_of_patches[i] = m_amr_patch_cell_groups_all[i].
size();
551 for (
Integer i = 0; i < size_of_patches.
size(); ++i) {
552 if (size_of_patches[i] == 0) {
553 m_patches_to_delete.add(i);
556 _removeMultiplePatches(m_patches_to_delete);
557 m_patches_to_delete.clear();
562 _updateHigherLevel();
563 _coarsenUselessCells(
true);
570void CartesianPatchGroup::
571updateLevelsAndAddGroundPatch()
577 auto numbering = m_cmesh->_internalApi()->cartesianMeshNumberingMngInternal();
578 auto amr = m_cmesh->_internalApi()->cartesianMeshAMRPatchMng();
580 amr->createSubLevel();
585 const Int32 level = patch->position().level();
588 const CartCoord3 max_point = patch->position().maxPoint();
589 if (m_cmesh->mesh()->dimension() == 2) {
590 patch->_internalApi()->positionRef().setMaxPoint({
591 numbering->offsetLevelToLevel(max_point.x, level, level - 1),
592 numbering->offsetLevelToLevel(max_point.y, level, level - 1),
597 patch->_internalApi()->positionRef().setMaxPoint({
598 numbering->offsetLevelToLevel(max_point.x, level, level - 1),
599 numbering->offsetLevelToLevel(max_point.y, level, level - 1),
600 numbering->offsetLevelToLevel(max_point.z, level, level - 1),
606 patch->_internalApi()->positionRef().setLevel(level + 1);
614 old_ground.
setMaxPoint({ numbering->globalNbCellsX(1), numbering->globalNbCellsY(1), numbering->globalNbCellsZ(1) });
616 _addPatch(old_ground);
619 m_cmesh->computeDirectionsPatchV2(0);
621 _updatePatchFlagsOfItemsGroundLevel();
627 _updateHigherLevel();
630 _checkPatchesAndMesh();
638_nextIndexForNewPatch()
640 if (!m_available_group_index.empty()) {
641 const Integer elem = m_available_group_index.back();
642 m_available_group_index.popBack();
645 return m_index_new_patches++;
651void CartesianPatchGroup::
654 if (m_cmesh->mesh()->meshKind().meshAMRKind() != eMeshAMRKind::PatchCartesianMeshOnly) {
657 UniqueArray<Int32> new_merged_patches;
660 UniqueArray<std::pair<Integer, Int64>> index_n_nb_cells;
663 for (
auto patch : m_amr_patches_pointer) {
664 index_n_nb_cells.add({ index++, patch->position().nbCells() });
676 std::stable_sort(index_n_nb_cells.begin(), index_n_nb_cells.end(),
677 [](
const std::pair<Integer, Int64>& a,
const std::pair<Integer, Int64>& b) {
678 return a.second < b.second;
681 for (Integer p0 = 0; p0 < index_n_nb_cells.size(); ++p0) {
682 auto [index_p0, nb_cells_p0] = index_n_nb_cells[p0];
684 AMRPatchPosition& patch_fusion_0 = m_amr_patches_pointer[index_p0]->_internalApi()->positionRef();
685 if (patch_fusion_0.isNull())
692 for (Integer p1 = p0 + 1; p1 < m_amr_patches_pointer.size(); ++p1) {
693 auto [index_p1, nb_cells_p1] = index_n_nb_cells[p1];
695 AMRPatchPosition& patch_fusion_1 = m_amr_patches_pointer[index_p1]->_internalApi()->positionRef();
696 if (patch_fusion_1.isNull())
707 if (patch_fusion_0.fusion(patch_fusion_1)) {
709 index_n_nb_cells[p0].second = patch_fusion_0.nbCells();
712 removePatch(index_p1);
714 if (!new_merged_patches.contains(index_p0)) {
715 new_merged_patches.add(index_p0);
718 auto find_p1 = new_merged_patches.span().findFirst(index_p1);
719 if (find_p1.has_value()) {
720 new_merged_patches.remove(find_p1.value());
733 UniqueArray<Int32> levels_edited;
734 for (Int32 patch_index : new_merged_patches) {
735 _updateCellGroups(patch_index,
false);
737 Int32 level = patch(patch_index)->_internalApi()->positionRef().level();
738 if (!levels_edited.contains(level)) {
739 levels_edited.add(level);
742 applyPatchEdit(
false,
false);
744 for (Int32 level : levels_edited) {
745 _updatePatchFlagsOfItemsLevel(level,
true);
749 _checkPatchesAndMesh();
756void CartesianPatchGroup::
757beginAdaptMesh(Int32 nb_levels, Int32 level_to_refine_first)
759 if (m_cmesh->mesh()->meshKind().meshAMRKind() != eMeshAMRKind::PatchCartesianMeshOnly) {
760 ARCANE_FATAL(
"Method available only with AMR PatchCartesianMeshOnly");
762 if (m_latest_call_level != -2) {
763 ARCANE_FATAL(
"Call endAdaptMesh() before restart mesh adaptation");
765 if (level_to_refine_first > m_higher_level) {
766 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);
769 Trace::Setter mci(traceMng(),
"CartesianPatchGroup");
770 info() <<
"Begin adapting mesh with higher level = " << (nb_levels - 1);
774 for (Integer p = 1; p < m_amr_patches_pointer.size(); ++p) {
775 Int32 level = m_amr_patches_pointer[p]->_internalApi()->positionRef().level();
776 if (level > level_to_refine_first) {
781 applyPatchEdit(
false,
false);
786 for (Integer l = level_to_refine_first + 1; l <= max_level; ++l) {
787 _removePatchFlagsOfItemsLevel(l);
791 if (nb_levels - 1 != m_higher_level) {
792 debug() <<
"beginAdaptMesh() -- Change overlap layer size -- Old higher level : " << m_higher_level
793 <<
" -- Asked higher level : " << (nb_levels - 1)
794 <<
" -- Adapt level lower than : " << level_to_refine_first;
796 for (Int32 level = 1; level <= level_to_refine_first; ++level) {
797 _changeOverlapSizeLevel(level, m_higher_level, nb_levels - 1);
801 m_target_nb_levels = nb_levels;
802 m_latest_call_level = level_to_refine_first - 1;
809void CartesianPatchGroup::
812 if (m_cmesh->mesh()->meshKind().meshAMRKind() != eMeshAMRKind::PatchCartesianMeshOnly) {
813 ARCANE_FATAL(
"Method available only with AMR PatchCartesianMeshOnly");
815 if (m_latest_call_level == -2) {
818 Trace::Setter mci(traceMng(),
"CartesianPatchGroup");
819 info() <<
"Finalizing adapting mesh with higher level = " << (m_target_nb_levels - 1);
821 auto amr = m_cmesh->_internalApi()->cartesianMeshAMRPatchMng();
830 m_higher_level = m_latest_call_level + 1;
838 if (m_higher_level + 1 < m_target_nb_levels) {
839 info() <<
"Reduce higher level from " << (m_target_nb_levels - 1) <<
" to " << m_higher_level;
841 for (Int32 level = 1; level <= m_higher_level; ++level) {
842 _changeOverlapSizeLevel(level, m_target_nb_levels - 1, m_higher_level);
846 _coarsenUselessCells(
true);
848 m_target_nb_levels = 0;
849 m_latest_call_level = -2;
850 clearRefineRelatedFlags();
852 info() <<
"Patch list:";
854 for (Integer i = 0; i <= m_higher_level; ++i) {
855 for (
auto p : m_amr_patches_pointer) {
856 auto& position = p->_internalApi()->positionRef();
857 if (position.level() == i) {
858 info() <<
"\tPatch #" << p->index()
859 <<
" -- Level : " << position.level()
860 <<
" -- Min point : " << position.minPoint()
861 <<
" -- Max point : " << position.maxPoint()
862 <<
" -- Overlap layer size : " << position.overlapLayerSize();
867 _checkPatchesAndMesh();
874void CartesianPatchGroup::
875adaptLevel(Int32 level_to_adapt,
bool do_fatal_if_useless)
877 if (m_cmesh->mesh()->meshKind().meshAMRKind() != eMeshAMRKind::PatchCartesianMeshOnly) {
878 ARCANE_FATAL(
"Method available only with AMR PatchCartesianMeshOnly");
880 if (m_latest_call_level == -2) {
881 ARCANE_FATAL(
"Call beginAdaptMesh() before to begin a mesh adaptation");
883 if (level_to_adapt + 1 >= m_target_nb_levels || level_to_adapt < 0) {
884 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);
887 Trace::Setter mci(traceMng(),
"CartesianPatchGroup");
889 if (level_to_adapt > m_latest_call_level + 1) {
890 if (do_fatal_if_useless) {
891 ARCANE_FATAL(
"You must refine level {0} before.", (m_latest_call_level + 1));
893 warning() << String::format(
"Useless call -- You must refine level {0} before.", (m_latest_call_level + 1));
902 if (level_to_adapt < m_latest_call_level) {
904 for (Integer p = 1; p < m_amr_patches_pointer.size(); ++p) {
905 Int32 level = m_amr_patches_pointer[p]->_internalApi()->positionRef().level();
906 if (level > level_to_adapt) {
911 applyPatchEdit(
false,
false);
913 for (Integer l = level_to_adapt + 1; l <= max_level; ++l) {
914 _removePatchFlagsOfItemsLevel(l);
918 auto amr = m_cmesh->_internalApi()->cartesianMeshAMRPatchMng();
919 auto numbering = m_cmesh->_internalApi()->cartesianMeshNumberingMngInternal();
933 Int32 nb_overlap_cells = overlapLayerSize(level_to_adapt + 1) / numbering->pattern();
935 info() <<
"adaptLevel()"
936 <<
" -- Level to adapt : " << level_to_adapt
937 <<
" -- Nb of overlap cells (intermediary patch) : " << nb_overlap_cells;
945 bool has_cell_to_refine =
false;
946 ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allCells()) {
947 if (icell->hasFlags(ItemFlags::II_Refine)) {
948 if (icell->level() != level_to_adapt) {
949 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);
951 if (level_to_adapt != 0 && !icell->hasFlags(ItemFlags::II_InPatch)) {
952 const CartCoord3 pos = numbering->cellUniqueIdToCoord(*icell);
953 ARCANE_FATAL(
"Cannot refine cell not in patch -- Pos : {0} -- CellUID : {1} -- CellLevel : {2}", pos, icell->uniqueId(), icell->level());
955 has_cell_to_refine =
true;
958 has_cell_to_refine = m_cmesh->mesh()->parallelMng()->reduce(MessagePassing::ReduceMax, has_cell_to_refine);
960 if (!has_cell_to_refine) {
961 if (do_fatal_if_useless) {
977 m_latest_call_level = level_to_adapt - 1;
978 debug() <<
"adaptLevel() -- End call -- No refine -- Actual patch list:";
980 for (Integer i = 0; i <= m_target_nb_levels; ++i) {
981 for (
auto p : m_amr_patches_pointer) {
982 auto& position = p->_internalApi()->positionRef();
983 if (position.level() == i) {
984 debug() <<
"\tPatch #" << p->index()
985 <<
" -- Level : " << position.level()
986 <<
" -- Min point : " << position.minPoint()
987 <<
" -- Max point : " << position.maxPoint()
988 <<
" -- Overlap layer size : " << position.overlapLayerSize();
995 m_latest_call_level = level_to_adapt;
997 UniqueArray<AMRPatchPositionSignature> sig_array;
1005 if (level_to_adapt == 0) {
1006 AMRPatchPosition all_level;
1007 all_level.setLevel(level_to_adapt);
1008 all_level.setMinPoint({ 0, 0, 0 });
1009 all_level.setMaxPoint({ numbering->globalNbCellsX(level_to_adapt), numbering->globalNbCellsY(level_to_adapt), numbering->globalNbCellsZ(level_to_adapt) });
1011 all_level.setOverlapLayerSize(nb_overlap_cells);
1012 AMRPatchPositionSignature sig(all_level, m_cmesh);
1031 for (
auto patch : m_amr_patches_pointer) {
1032 Integer level = patch->_internalApi()->positionRef().level();
1033 if (level == level_to_adapt) {
1034 auto position = patch->position();
1035 position.setOverlapLayerSize(nb_overlap_cells);
1036 AMRPatchPositionSignature sig(position, m_cmesh);
1042 AMRPatchPositionSignatureCut::cut(sig_array);
1046 ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allLevelCells(level_to_adapt)) {
1047 if (!icell->hasHChildren()) {
1048 const CartCoord3 pos = numbering->cellUniqueIdToCoord(*icell);
1049 for (
const AMRPatchPositionSignature& patch_signature : sig_array) {
1050 if (patch_signature.patch().isInWithOverlap(pos)) {
1051 if (!icell->hasFlags(ItemFlags::II_InPatch) && !icell->hasFlags(ItemFlags::II_Overlap)) {
1052 ARCANE_FATAL(
"Internal error -- Refine algo error -- Pos : {0}", pos);
1054 icell->mutableItemBase().addFlags(ItemFlags::II_Refine);
1093 ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allLevelCells(level_to_adapt)) {
1094 icell->mutableItemBase().removeFlags(ItemFlags::II_Refine);
1102 UniqueArray<AMRPatchPosition> all_patches;
1103 for (
const auto& elem : sig_array) {
1104 all_patches.add(elem.patch().patchUp(m_cmesh->mesh()->dimension(), m_target_nb_levels - 1, m_size_of_overlap_layer_top_level));
1108 AMRPatchPositionLevelGroup::fusionPatches(all_patches,
true);
1178 for (
const AMRPatchPosition& patch : all_patches) {
1179 Integer index = _addPatch(patch);
1181 m_cmesh->computeDirectionsPatchV2(index);
1184 debug() <<
"adaptLevel() -- End call -- Actual patch list:";
1186 for (Integer i = 0; i <= m_target_nb_levels; ++i) {
1187 for (
auto p : m_amr_patches_pointer) {
1188 auto& position = p->_internalApi()->positionRef();
1189 if (position.level() == i) {
1190 debug() <<
"\tPatch #" << p->index()
1191 <<
" -- Level : " << position.level()
1192 <<
" -- Min point : " << position.minPoint()
1193 <<
" -- Max point : " << position.maxPoint()
1194 <<
" -- Overlap layer size : " << position.overlapLayerSize();
1203void CartesianPatchGroup::
1204_increaseOverlapSizeLevel(Int32 level_to_increate, Int32 new_size)
1206 if (level_to_increate == 0) {
1210 auto amr = m_cmesh->_internalApi()->cartesianMeshAMRPatchMng();
1211 auto numbering = m_cmesh->_internalApi()->cartesianMeshNumberingMngInternal();
1213 bool has_cell_to_refine =
false;
1222 for (Integer p = 1; p < m_amr_patches_pointer.size(); ++p) {
1223 Int32 level = m_amr_patches_pointer[p]->_internalApi()->positionRef().level();
1224 if (level == level_to_increate) {
1225 AMRPatchPosition& position = m_amr_patches_pointer[p]->_internalApi()->positionRef();
1227 Int32 size_layer = position.overlapLayerSize();
1228 if (size_layer > new_size) {
1229 ARCANE_FATAL(
"Cannot reduce layer with _increaseOverlapSizeLevel method");
1235 if (size_layer == new_size) {
1239 has_cell_to_refine =
true;
1240 position.setOverlapLayerSize(new_size);
1246 ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allLevelCells(level_to_increate - 1)) {
1247 const CartCoord3 pos = numbering->offsetLevelToLevel(numbering->cellUniqueIdToCoord(*icell), level_to_increate - 1, level_to_increate);
1248 if (position.isInWithOverlap(pos) && !icell->hasHChildren()) {
1249 icell->mutableItemBase().addFlags(ItemFlags::II_Refine);
1254 has_cell_to_refine = m_cmesh->mesh()->parallelMng()->reduce(MessagePassing::ReduceMax, has_cell_to_refine);
1255 if (!has_cell_to_refine) {
1263 ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allLevelCells(level_to_increate - 1)) {
1264 icell->mutableItemBase().removeFlags(ItemFlags::II_Refine);
1267 UniqueArray<Int32> cell_to_add;
1270 for (Integer p = 1; p < m_amr_patches_pointer.size(); ++p) {
1271 Int32 level = m_amr_patches_pointer[p]->_internalApi()->positionRef().level();
1272 if (level == level_to_increate) {
1273 AMRPatchPosition& position = m_amr_patches_pointer[p]->_internalApi()->positionRef();
1275 ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allLevelCells(level_to_increate)) {
1276 if (!icell->hasFlags(ItemFlags::II_JustAdded))
1279 const CartCoord3 pos = numbering->cellUniqueIdToCoord(*icell);
1281 if (position.isInWithOverlap(pos)) {
1282 cell_to_add.add(icell.localId());
1283 icell->mutableItemBase().addFlags(ItemFlags::II_Overlap);
1284 for (Face face : icell->faces()) {
1285 face.mutableItemBase().addFlags(ItemFlags::II_Overlap);
1287 for (Node node : icell->nodes()) {
1288 node.mutableItemBase().addFlags(ItemFlags::II_Overlap);
1291 else if (position.isIn(pos)) {
1292 icell->mutableItemBase().addFlags(ItemFlags::II_InPatch);
1293 for (Face face : icell->faces()) {
1294 face.mutableItemBase().addFlags(ItemFlags::II_InPatch);
1296 for (Node node : icell->nodes()) {
1297 node.mutableItemBase().addFlags(ItemFlags::II_InPatch);
1302 allCells(p).addItems(cell_to_add,
true);
1303 overlapCells(p).addItems(cell_to_add,
true);
1304 cell_to_add.clear();
1307 m_cmesh->computeDirectionsPatchV2(p);
1311 ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allLevelCells(level_to_increate)) {
1312 icell->mutableItemBase().removeFlags(ItemFlags::II_JustAdded);
1319void CartesianPatchGroup::
1320_reduceOverlapSizeLevel(Int32 level_to_reduce, Int32 new_size)
1329 if (level_to_reduce == 0) {
1333 auto amr = m_cmesh->_internalApi()->cartesianMeshAMRPatchMng();
1334 auto numbering = m_cmesh->_internalApi()->cartesianMeshNumberingMngInternal();
1341 bool has_cell_to_mark =
false;
1342 UniqueArray<Int32> cell_to_remove;
1344 for (Integer p = 1; p < m_amr_patches_pointer.size(); ++p) {
1345 Int32 level = m_amr_patches_pointer[p]->_internalApi()->positionRef().level();
1346 if (level == level_to_reduce) {
1347 AMRPatchPosition& position = m_amr_patches_pointer[p]->_internalApi()->positionRef();
1349 Int32 size_layer = position.overlapLayerSize();
1350 if (size_layer < new_size) {
1351 ARCANE_FATAL(
"Cannot add layer with _reduceOverlapSizeLevel method");
1353 if (size_layer == new_size) {
1357 has_cell_to_mark =
true;
1358 position.setOverlapLayerSize(new_size);
1361 const CartCoord3 pos = numbering->cellUniqueIdToCoord(*icell);
1362 if (!position.isInWithOverlap(pos)) {
1363 cell_to_remove.add(icell.localId());
1367 allCells(p).removeItems(cell_to_remove,
true);
1368 overlapCells(p).removeItems(cell_to_remove,
true);
1369 cell_to_remove.clear();
1372 has_cell_to_mark = m_cmesh->mesh()->parallelMng()->reduce(MessagePassing::ReduceMax, has_cell_to_mark);
1373 if (!has_cell_to_mark) {
1378 _updatePatchFlagsOfItemsLevel(level_to_reduce,
true);
1380 for (Integer p = 1; p < m_amr_patches_pointer.size(); ++p) {
1381 Int32 level = m_amr_patches_pointer[p]->_internalApi()->positionRef().level();
1382 if (level == level_to_reduce) {
1383 m_cmesh->computeDirectionsPatchV2(p);
1391void CartesianPatchGroup::
1395 Int32 higher_level_patch = 0;
1397 for (
const auto patch : m_amr_patches_pointer) {
1398 const Int32 level = patch->_internalApi()->positionRef().level();
1399 if (level > higher_level_patch) {
1400 higher_level_patch = level;
1404 if (higher_level_patch != m_higher_level) {
1405 for (Int32 level = 1; level <= higher_level_patch; ++level) {
1406 _changeOverlapSizeLevel(level, m_higher_level, higher_level_patch);
1409 m_higher_level = higher_level_patch;
1416void CartesianPatchGroup::
1417_changeOverlapSizeLevel(Int32 level, Int32 previous_higher_level, Int32 new_higher_level)
1419 if (previous_higher_level == new_higher_level) {
1423 Int32 old_overlap_size = ((level > previous_higher_level) ? 0 : AMRPatchPosition::computeOverlapLayerSize(level, previous_higher_level, m_size_of_overlap_layer_top_level));
1424 Int32 new_overlap_size = AMRPatchPosition::computeOverlapLayerSize(level, new_higher_level, m_size_of_overlap_layer_top_level);
1426 if (old_overlap_size == new_overlap_size) {
1429 if (old_overlap_size < new_overlap_size) {
1430 _increaseOverlapSizeLevel(level, new_overlap_size);
1433 _reduceOverlapSizeLevel(level, new_overlap_size);
1440void CartesianPatchGroup::
1441_coarsenUselessCells(
bool use_cells_level)
1443 Int32 higher_level_patch = m_higher_level;
1444 if (use_cells_level) {
1445 ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allCells()) {
1446 if (icell->level() > higher_level_patch) {
1447 higher_level_patch = icell->level();
1450 higher_level_patch = m_cmesh->mesh()->parallelMng()->reduce(MessagePassing::ReduceMax, higher_level_patch);
1454 for (Integer level = higher_level_patch; level > 0; --level) {
1455 _coarsenUselessCellsInLevel(level);
1462void CartesianPatchGroup::
1463_coarsenUselessCellsInLevel(Int32 level)
1465 Integer nb_cells_to_coarse = 0;
1466 ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allLevelCells(level)) {
1467 if (!icell->hasFlags(ItemFlags::II_InPatch) && !icell->hasFlags(ItemFlags::II_Overlap)) {
1469 icell->mutableItemBase().addFlags(ItemFlags::II_Coarsen);
1470 nb_cells_to_coarse++;
1473 debug() <<
"Remove " << nb_cells_to_coarse <<
" refined cells without flag in level " << level;
1474 nb_cells_to_coarse = m_cmesh->mesh()->parallelMng()->reduce(MessagePassing::ReduceMax, nb_cells_to_coarse);
1476 auto amr = m_cmesh->_internalApi()->cartesianMeshAMRPatchMng();
1477 if (nb_cells_to_coarse != 0) {
1485void CartesianPatchGroup::
1486_updatePatchFlagsOfItemsLevel(Int32 level,
bool use_cell_groups)
1489 _updatePatchFlagsOfItemsGroundLevel();
1493 auto numbering = m_cmesh->_internalApi()->cartesianMeshNumberingMngInternal();
1495 ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allLevelCells(level)) {
1496 icell->mutableItemBase().removeFlags(ItemFlags::II_InPatch | ItemFlags::II_Overlap);
1498 ENUMERATE_ (Face, iface, m_cmesh->mesh()->allLevelCells(level).faceGroup()) {
1499 iface->mutableItemBase().removeFlags(ItemFlags::II_InPatch | ItemFlags::II_Overlap);
1501 ENUMERATE_ (Node, inode, m_cmesh->mesh()->allLevelCells(level).nodeGroup()) {
1502 inode->mutableItemBase().removeFlags(ItemFlags::II_InPatch | ItemFlags::II_Overlap);
1508 if (use_cell_groups) {
1509 for (Integer p = 1; p < m_amr_patches_pointer.size(); ++p) {
1510 Int32 level_patch = m_amr_patches_pointer[p]->_internalApi()->positionRef().level();
1511 if (level_patch == level) {
1513 icell->mutableItemBase().addFlags(ItemFlags::II_InPatch);
1515 ENUMERATE_ (Face, iface, inPatchCells(p).faceGroup()) {
1516 iface->mutableItemBase().addFlags(ItemFlags::II_InPatch);
1518 ENUMERATE_ (Node, inode, inPatchCells(p).nodeGroup()) {
1519 inode->mutableItemBase().addFlags(ItemFlags::II_InPatch);
1523 icell->mutableItemBase().addFlags(ItemFlags::II_Overlap);
1525 ENUMERATE_ (Face, iface, overlapCells(p).faceGroup()) {
1526 iface->mutableItemBase().addFlags(ItemFlags::II_Overlap);
1528 ENUMERATE_ (Node, inode, overlapCells(p).nodeGroup()) {
1529 inode->mutableItemBase().addFlags(ItemFlags::II_Overlap);
1538 ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allLevelCells(level)) {
1539 bool in_overlap =
false;
1540 bool in_patch =
false;
1548 const CartCoord3 pos = numbering->cellUniqueIdToCoord(*icell);
1550 for (Integer p = 1; p < m_amr_patches_pointer.size(); ++p) {
1551 auto& patch = m_amr_patches_pointer[p]->_internalApi()->positionRef();
1552 if (patch.level() != level) {
1556 if (patch.isIn(pos)) {
1559 else if (patch.isInWithOverlap(pos)) {
1562 if (in_patch && in_overlap) {
1566 if (in_patch && in_overlap) {
1567 icell->mutableItemBase().addFlags(ItemFlags::II_InPatch | ItemFlags::II_Overlap);
1568 for (Face face : icell->faces()) {
1569 face.mutableItemBase().addFlags(ItemFlags::II_InPatch | ItemFlags::II_Overlap);
1571 for (Node node : icell->nodes()) {
1572 node.mutableItemBase().addFlags(ItemFlags::II_InPatch | ItemFlags::II_Overlap);
1575 else if (in_overlap) {
1576 icell->mutableItemBase().addFlags(ItemFlags::II_Overlap);
1577 icell->mutableItemBase().removeFlags(ItemFlags::II_InPatch);
1578 for (Face face : icell->faces()) {
1579 face.mutableItemBase().addFlags(ItemFlags::II_Overlap);
1581 for (Node node : icell->nodes()) {
1582 node.mutableItemBase().addFlags(ItemFlags::II_Overlap);
1585 else if (in_patch) {
1586 icell->mutableItemBase().addFlags(ItemFlags::II_InPatch);
1587 icell->mutableItemBase().removeFlags(ItemFlags::II_Overlap);
1588 for (Face face : icell->faces()) {
1589 face.mutableItemBase().addFlags(ItemFlags::II_InPatch);
1591 for (Node node : icell->nodes()) {
1592 node.mutableItemBase().addFlags(ItemFlags::II_InPatch);
1596 icell->mutableItemBase().removeFlags(ItemFlags::II_InPatch | ItemFlags::II_Overlap);
1605void CartesianPatchGroup::
1606_updatePatchFlagsOfItemsGroundLevel()
1608 ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allLevelCells(0)) {
1609 icell->mutableItemBase().addFlags(ItemFlags::II_InPatch);
1611 ENUMERATE_ (Face, iface, m_cmesh->mesh()->allLevelCells(0).faceGroup()) {
1612 iface->mutableItemBase().addFlags(ItemFlags::II_InPatch);
1614 ENUMERATE_ (Node, inode, m_cmesh->mesh()->allLevelCells(0).nodeGroup()) {
1615 inode->mutableItemBase().addFlags(ItemFlags::II_InPatch);
1622void CartesianPatchGroup::
1623_removePatchFlagsOfItemsLevel(Int32 level)
1625 ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allLevelCells(level)) {
1626 icell->mutableItemBase().removeFlags(ItemFlags::II_Overlap | ItemFlags::II_InPatch);
1628 ENUMERATE_ (Face, iface, m_cmesh->mesh()->allLevelCells(level).faceGroup()) {
1629 iface->mutableItemBase().removeFlags(ItemFlags::II_Overlap | ItemFlags::II_InPatch);
1631 ENUMERATE_ (Node, inode, m_cmesh->mesh()->allLevelCells(level).nodeGroup()) {
1632 inode->mutableItemBase().removeFlags(ItemFlags::II_Overlap | ItemFlags::II_InPatch);
1639void CartesianPatchGroup::
1640_checkPatchesAndMesh()
1642 auto numbering = m_cmesh->_internalApi()->cartesianMeshNumberingMngInternal();
1644 Int32 higher_level = 0;
1645 ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allCells()) {
1646 if (icell->level() > higher_level) {
1647 higher_level = icell->level();
1650 higher_level = m_cmesh->mesh()->parallelMng()->reduce(MessagePassing::ReduceMax, higher_level);
1651 if (higher_level != m_higher_level) {
1652 ARCANE_FATAL(
"_checkPatchesAndMesh -- Bad higher level -- m_higher_level : {0} -- Found : {1}", m_higher_level, higher_level);
1656 for (Int32 level = 0; level < m_higher_level; ++level) {
1657 Int32 check_overlap = overlapLayerSize(level);
1658 for (Integer p = 0; p < m_amr_patches_pointer.size(); ++p) {
1659 auto& position = m_amr_patches_pointer[p]->_internalApi()->positionRef();
1660 if (position.level() == level) {
1661 if (check_overlap == -1) {
1662 check_overlap = position.overlapLayerSize();
1664 else if (check_overlap != position.overlapLayerSize()) {
1665 ARCANE_FATAL(
"_checkPatchesAndMesh -- Overlap size incoherence -- Patch pos : {0} -- Previous size : {1} -- Found : {2}", p, check_overlap, position.overlapLayerSize());
1674 ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allCells()) {
1675 Integer level = icell->level();
1677 bool in_overlap =
false;
1678 bool in_patch =
false;
1680 const CartCoord3 pos = numbering->cellUniqueIdToCoord(*icell);
1682 for (
auto p : m_amr_patches_pointer) {
1683 auto& patch = p->_internalApi()->positionRef();
1684 if (patch.level() != level) {
1688 if (patch.isIn(pos)) {
1691 else if (patch.isInWithOverlap(pos)) {
1694 if (in_patch && in_overlap) {
1698 if (in_patch && in_overlap) {
1699 icell->mutableItemBase().addFlags(ItemFlags::II_UserMark1);
1700 icell->mutableItemBase().addFlags(ItemFlags::II_UserMark2);
1702 else if (in_overlap) {
1703 icell->mutableItemBase().addFlags(ItemFlags::II_UserMark1);
1704 icell->mutableItemBase().removeFlags(ItemFlags::II_UserMark2);
1706 else if (in_patch) {
1707 icell->mutableItemBase().addFlags(ItemFlags::II_UserMark2);
1708 icell->mutableItemBase().removeFlags(ItemFlags::II_UserMark1);
1711 icell->mutableItemBase().removeFlags(ItemFlags::II_UserMark2);
1712 icell->mutableItemBase().removeFlags(ItemFlags::II_UserMark1);
1715 ENUMERATE_ (Face, iface, m_cmesh->mesh()->allFaces()) {
1716 Int32 max_level = 0;
1717 for (Cell cell : iface->cells()) {
1718 if (cell.level() > max_level) {
1719 max_level = cell.level();
1722 for (Cell cell : iface->cells()) {
1723 if (cell.level() != max_level) {
1726 if (cell.hasFlags(ItemFlags::II_UserMark1)) {
1727 iface->mutableItemBase().addFlags(ItemFlags::II_UserMark1);
1729 if (cell.hasFlags(ItemFlags::II_UserMark2)) {
1730 iface->mutableItemBase().addFlags(ItemFlags::II_UserMark2);
1734 ENUMERATE_ (Node, inode, m_cmesh->mesh()->allNodes()) {
1735 Int32 max_level = 0;
1736 for (Cell cell : inode->cells()) {
1737 if (cell.level() > max_level) {
1738 max_level = cell.level();
1741 for (Cell cell : inode->cells()) {
1742 if (cell.level() != max_level) {
1745 if (cell.hasFlags(ItemFlags::II_UserMark1)) {
1746 inode->mutableItemBase().addFlags(ItemFlags::II_UserMark1);
1748 if (cell.hasFlags(ItemFlags::II_UserMark2)) {
1749 inode->mutableItemBase().addFlags(ItemFlags::II_UserMark2);
1754 ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allCells()) {
1755 if (icell->hasFlags(ItemFlags::II_UserMark1)) {
1756 if (!icell->hasFlags(ItemFlags::II_Overlap)) {
1757 ARCANE_FATAL(
"_checkPatchesAndMesh -- II_UserMark1 but not II_Overlap -- CellUID : {0}", icell->uniqueId());
1760 if (icell->hasFlags(ItemFlags::II_UserMark2)) {
1761 if (!icell->hasFlags(ItemFlags::II_InPatch)) {
1762 ARCANE_FATAL(
"_checkPatchesAndMesh -- II_UserMark2 but not II_InPatch -- CellUID : {0}", icell->uniqueId());
1765 if (icell->hasFlags(ItemFlags::II_Overlap)) {
1766 if (!icell->hasFlags(ItemFlags::II_UserMark1)) {
1767 ARCANE_FATAL(
"_checkPatchesAndMesh -- II_Overlap but not II_UserMark1 -- CellUID : {0}", icell->uniqueId());
1770 if (icell->hasFlags(ItemFlags::II_InPatch)) {
1771 if (!icell->hasFlags(ItemFlags::II_UserMark2)) {
1772 ARCANE_FATAL(
"_checkPatchesAndMesh -- II_InPatch but not II_UserMark2 -- CellUID : {0}", icell->uniqueId());
1778 icell->mutableItemBase().removeFlags(ItemFlags::II_UserMark1);
1779 icell->mutableItemBase().removeFlags(ItemFlags::II_UserMark2);
1781 ENUMERATE_ (Face, iface, m_cmesh->mesh()->allFaces()) {
1782 if (iface->hasFlags(ItemFlags::II_UserMark1)) {
1783 if (!iface->hasFlags(ItemFlags::II_Overlap)) {
1784 ARCANE_FATAL(
"_checkPatchesAndMesh -- II_UserMark1 but not II_Overlap -- FaceUID : {0}", iface->uniqueId());
1787 if (iface->hasFlags(ItemFlags::II_UserMark2)) {
1788 if (!iface->hasFlags(ItemFlags::II_InPatch)) {
1789 ARCANE_FATAL(
"_checkPatchesAndMesh -- II_UserMark2 but not II_InPatch -- FaceUID : {0}", iface->uniqueId());
1792 if (iface->hasFlags(ItemFlags::II_Overlap)) {
1793 if (!iface->hasFlags(ItemFlags::II_UserMark1)) {
1794 ARCANE_FATAL(
"_checkPatchesAndMesh -- II_Overlap but not II_UserMark1 -- FaceUID : {0}", iface->uniqueId());
1797 if (iface->hasFlags(ItemFlags::II_InPatch)) {
1798 if (!iface->hasFlags(ItemFlags::II_UserMark2)) {
1799 ARCANE_FATAL(
"_checkPatchesAndMesh -- II_InPatch but not II_UserMark2 -- FaceUID : {0}", iface->uniqueId());
1803 iface->mutableItemBase().removeFlags(ItemFlags::II_UserMark1);
1804 iface->mutableItemBase().removeFlags(ItemFlags::II_UserMark2);
1806 ENUMERATE_ (Node, inode, m_cmesh->mesh()->allNodes()) {
1807 if (inode->hasFlags(ItemFlags::II_UserMark1)) {
1808 if (!inode->hasFlags(ItemFlags::II_Overlap)) {
1809 ARCANE_FATAL(
"_checkPatchesAndMesh -- II_UserMark1 but not II_Overlap -- NodeUID : {0}", inode->uniqueId());
1812 if (inode->hasFlags(ItemFlags::II_UserMark2)) {
1813 if (!inode->hasFlags(ItemFlags::II_InPatch)) {
1814 ARCANE_FATAL(
"_checkPatchesAndMesh -- II_UserMark2 but not II_InPatch -- NodeUID : {0}", inode->uniqueId());
1817 if (inode->hasFlags(ItemFlags::II_Overlap)) {
1818 if (!inode->hasFlags(ItemFlags::II_UserMark1)) {
1819 ARCANE_FATAL(
"_checkPatchesAndMesh -- II_Overlap but not II_UserMark1 -- NodeUID : {0}", inode->uniqueId());
1822 if (inode->hasFlags(ItemFlags::II_InPatch)) {
1823 if (!inode->hasFlags(ItemFlags::II_UserMark2)) {
1824 ARCANE_FATAL(
"_checkPatchesAndMesh -- II_InPatch but not II_UserMark2 -- NodeUID : {0}", inode->uniqueId());
1828 inode->mutableItemBase().removeFlags(ItemFlags::II_UserMark1);
1829 inode->mutableItemBase().removeFlags(ItemFlags::II_UserMark2);
1837void CartesianPatchGroup::
1838clearRefineRelatedFlags()
const
1840 constexpr ItemFlags::FlagType flags_to_remove = (ItemFlags::II_Coarsen | ItemFlags::II_Refine |
1841 ItemFlags::II_JustCoarsened | ItemFlags::II_JustRefined |
1842 ItemFlags::II_JustAdded | ItemFlags::II_CoarsenInactive);
1843 ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allCells()) {
1844 icell->mutableItemBase().removeFlags(flags_to_remove);
1851void CartesianPatchGroup::
1852rebuildAvailableGroupIndex(ConstArrayView<Integer> available_group_index)
1854 m_available_group_index = available_group_index;
1860ConstArrayView<Int32> CartesianPatchGroup::
1861availableGroupIndex()
1863 return m_available_group_index;
1869void CartesianPatchGroup::
1870setOverlapLayerSizeTopLevel(Int32 size_of_overlap_layer_top_level)
1872 auto numbering = m_cmesh->_internalApi()->cartesianMeshNumberingMngInternal();
1874 Int32 new_size_of_overlap_layer_top_level = 0;
1877 if (size_of_overlap_layer_top_level == -1)
1878 new_size_of_overlap_layer_top_level = -1;
1882 new_size_of_overlap_layer_top_level = size_of_overlap_layer_top_level + (size_of_overlap_layer_top_level % numbering->pattern());
1884 if (new_size_of_overlap_layer_top_level == m_size_of_overlap_layer_top_level) {
1890 for (Int32 level = 1; level <= m_higher_level; ++level) {
1891 Int32 old_overlap_size = AMRPatchPosition::computeOverlapLayerSize(level, m_higher_level, m_size_of_overlap_layer_top_level);
1892 Int32 new_overlap_size = AMRPatchPosition::computeOverlapLayerSize(level, m_higher_level, new_size_of_overlap_layer_top_level);
1894 if (old_overlap_size == new_overlap_size) {
1897 if (old_overlap_size < new_overlap_size) {
1898 _increaseOverlapSizeLevel(level, new_overlap_size);
1901 _reduceOverlapSizeLevel(level, new_overlap_size);
1904 m_size_of_overlap_layer_top_level = new_size_of_overlap_layer_top_level;
1910Int32 CartesianPatchGroup::
1911overlapLayerSize(Int32 level)
1920 Int32 higher_level = m_higher_level;
1921 if (m_target_nb_levels != 0) {
1922 higher_level = m_target_nb_levels - 1;
1924 return AMRPatchPosition::computeOverlapLayerSize(level, higher_level, m_size_of_overlap_layer_top_level);
1930void CartesianPatchGroup::
1931_addPatchInstance(Ref<CartesianMeshPatch> v)
1933 m_amr_patches.add(v);
1934 m_amr_patches_pointer.add(v.get());
1940void CartesianPatchGroup::
1941_removeOnePatch(Integer index)
1943 m_available_group_index.add(m_amr_patches[index]->index());
1946 m_amr_patch_cell_groups_all[index].clear();
1947 m_amr_patch_cell_groups_all.remove(index);
1949 if (m_cmesh->mesh()->meshKind().meshAMRKind() == eMeshAMRKind::PatchCartesianMeshOnly) {
1950 m_amr_patch_cell_groups_inpatch[index].clear();
1951 m_amr_patch_cell_groups_inpatch.remove(index);
1952 m_amr_patch_cell_groups_overlap[index].clear();
1953 m_amr_patch_cell_groups_overlap.remove(index);
1956 m_amr_patches_pointer.remove(index);
1957 m_amr_patches.remove(index);
1964void CartesianPatchGroup::
1965_removeMultiplePatches(ConstArrayView<Integer> indexes)
1968 for (
const Integer index : indexes) {
1969 _removeOnePatch(index - count);
1977void CartesianPatchGroup::
1980 for (Integer i = 1; i < m_amr_patch_cell_groups_all.size(); ++i) {
1981 m_amr_patch_cell_groups_all[i].clear();
1983 m_amr_patch_cell_groups_all.clear();
1985 if (m_cmesh->mesh()->meshKind().meshAMRKind() == eMeshAMRKind::PatchCartesianMeshOnly) {
1986 for (Integer i = 0; i < m_amr_patch_cell_groups_inpatch.size(); ++i) {
1987 m_amr_patch_cell_groups_inpatch[i].clear();
1988 m_amr_patch_cell_groups_overlap[i].clear();
1990 m_amr_patch_cell_groups_inpatch.clear();
1991 m_amr_patch_cell_groups_overlap.clear();
1994 m_amr_patches_pointer.clear();
1995 m_amr_patches.clear();
1996 m_available_group_index.clear();
1997 m_patches_to_delete.clear();
1998 m_index_new_patches = 1;
2006void CartesianPatchGroup::
2009 if (!m_amr_patches.empty())
2011 auto patch =
makeRef(
new CartesianMeshPatch(m_cmesh, -1));
2013 if (m_cmesh->mesh()->meshKind().meshAMRKind() == eMeshAMRKind::PatchCartesianMeshOnly) {
2014 auto numbering = m_cmesh->_internalApi()->cartesianMeshNumberingMngInternal();
2015 patch->_internalApi()->positionRef().setMinPoint({ 0, 0, 0 });
2016 patch->_internalApi()->positionRef().setMaxPoint({ numbering->globalNbCellsX(0), numbering->globalNbCellsY(0), numbering->globalNbCellsZ(0) });
2017 patch->_internalApi()->positionRef().setLevel(0);
2020 _addPatchInstance(patch);
2021 _addCellGroup(m_cmesh->mesh()->allLevelCells(0), patch.get(),
true);
2028_addCellGroup(CellGroup cell_group, CartesianMeshPatch* patch,
bool add_flags)
2030 m_amr_patch_cell_groups_all.add(cell_group);
2032 if (m_cmesh->mesh()->meshKind().meshAMRKind() != eMeshAMRKind::PatchCartesianMeshOnly) {
2036 return m_amr_patch_cell_groups_all.size() - 1;
2039 AMRPatchPosition patch_position = patch->position();
2040 Ref<ICartesianMeshNumberingMngInternal> numbering = m_cmesh->_internalApi()->cartesianMeshNumberingMngInternal();
2042 UniqueArray<Int32> inpatch_items_lid;
2043 UniqueArray<Int32> overlap_items_lid;
2047 const CartCoord3 pos = numbering->cellUniqueIdToCoord(cell);
2049 if (patch_position.isIn(pos)) {
2050 inpatch_items_lid.add(cell.localId());
2053 overlap_items_lid.add(cell.localId());
2058 m_amr_patch_cell_groups_inpatch.add(own);
2061 m_amr_patch_cell_groups_overlap.add(overlap);
2071 icell->mutableItemBase().addFlags(ItemFlags::II_InPatch);
2074 iface->mutableItemBase().addFlags(ItemFlags::II_InPatch);
2077 inode->mutableItemBase().addFlags(ItemFlags::II_InPatch);
2081 icell->mutableItemBase().addFlags(ItemFlags::II_Overlap);
2083 ENUMERATE_ (Face, iface, overlap.faceGroup()) {
2084 iface->mutableItemBase().addFlags(ItemFlags::II_Overlap);
2086 ENUMERATE_ (Node, inode, overlap.nodeGroup()) {
2087 inode->mutableItemBase().addFlags(ItemFlags::II_Overlap);
2091 return m_amr_patch_cell_groups_all.
size() - 1;
2097void CartesianPatchGroup::
2098_updateCellGroups(Integer index,
bool update_flags)
2100 if (m_cmesh->mesh()->meshKind().meshAMRKind() != eMeshAMRKind::PatchCartesianMeshOnly) {
2101 ARCANE_FATAL(
"Method available only with AMR PatchCartesianMeshOnly");
2104 CellGroup patch_all_cells = allCells(index);
2105 CellGroup patch_inpatch = inPatchCells(index);
2106 CellGroup patch_overlap = overlapCells(index);
2108 patch_all_cells.clear();
2109 patch_inpatch.clear();
2110 patch_overlap.clear();
2112 const auto& position = patch(index)->_internalApi()->positionRef();
2114 Int32 level = position.level();
2116 UniqueArray<Int32> inpatch_items_lid;
2117 UniqueArray<Int32> overlap_items_lid;
2119 auto numbering = m_cmesh->_internalApi()->cartesianMeshNumberingMngInternal();
2122 ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allLevelCells(level)) {
2123 const CartCoord3 pos = numbering->cellUniqueIdToCoord(*icell);
2125 if (position.isIn(pos)) {
2126 inpatch_items_lid.add(icell.localId());
2128 else if (position.isInWithOverlap(pos)) {
2129 overlap_items_lid.add(icell.localId());
2133 patch_all_cells.addItems(inpatch_items_lid,
false);
2134 patch_all_cells.addItems(overlap_items_lid,
false);
2136 patch_inpatch.addItems(inpatch_items_lid,
false);
2137 patch_overlap.addItems(overlap_items_lid,
false);
2141 icell->mutableItemBase().addFlags(ItemFlags::II_InPatch);
2143 ENUMERATE_ (Face, iface, patch_inpatch.faceGroup()) {
2144 iface->mutableItemBase().addFlags(ItemFlags::II_InPatch);
2146 ENUMERATE_ (Node, inode, patch_inpatch.nodeGroup()) {
2147 inode->mutableItemBase().addFlags(ItemFlags::II_InPatch);
2151 icell->mutableItemBase().addFlags(ItemFlags::II_Overlap);
2153 ENUMERATE_ (Face, iface, patch_overlap.faceGroup()) {
2154 iface->mutableItemBase().addFlags(ItemFlags::II_Overlap);
2156 ENUMERATE_ (Node, inode, patch_overlap.nodeGroup()) {
2157 inode->mutableItemBase().addFlags(ItemFlags::II_Overlap);
2170void CartesianPatchGroup::
2171_removePartOfPatch(Integer index_patch_to_edit,
const AMRPatchPosition& part_to_remove)
2202 std::pair to_return{ -1, -1 };
2203 if (p1_min > p0_min && p1_min < p0_max) {
2204 to_return.first = p1_min;
2206 if (p1_max > p0_min && p1_max < p0_max) {
2207 to_return.second = p1_max;
2212 ICartesianMeshPatch* patch = m_amr_patches_pointer[index_patch_to_edit];
2213 AMRPatchPosition patch_position = patch->position();
2215 UniqueArray<AMRPatchPosition> new_patch_out;
2217 CartCoord3 min_point_of_patch_to_exclude(-1, -1, -1);
2221 UniqueArray<AMRPatchPosition> new_patch_in;
2225 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);
2229 if (cut_point_x.first == -1 && cut_point_x.second == -1) {
2230 min_point_of_patch_to_exclude.x = patch_position.minPoint().x;
2231 new_patch_out.add(patch_position);
2235 else if (cut_point_x.second == -1) {
2236 min_point_of_patch_to_exclude.x = cut_point_x.first;
2237 auto [fst, snd] = patch_position.cut(cut_point_x.first, MD_DirX);
2238 new_patch_out.add(fst);
2239 new_patch_out.add(snd);
2243 else if (cut_point_x.first == -1) {
2244 min_point_of_patch_to_exclude.x = patch_position.minPoint().x;
2245 auto [fst, snd] = patch_position.cut(cut_point_x.second, MD_DirX);
2246 new_patch_out.add(fst);
2247 new_patch_out.add(snd);
2252 min_point_of_patch_to_exclude.x = cut_point_x.first;
2253 auto [fst, snd_thr] = patch_position.cut(cut_point_x.first, MD_DirX);
2254 new_patch_out.add(fst);
2255 auto [snd, thr] = snd_thr.cut(cut_point_x.second, MD_DirX);
2256 new_patch_out.add(snd);
2257 new_patch_out.add(thr);
2263 std::swap(new_patch_out, new_patch_in);
2265 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);
2269 if (cut_point_y.first == -1 && cut_point_y.second == -1) {
2270 for (
const AMRPatchPosition& patch_x : new_patch_in) {
2271 min_point_of_patch_to_exclude.y = patch_x.minPoint().y;
2272 new_patch_out.add(patch_x);
2277 else if (cut_point_y.second == -1) {
2278 min_point_of_patch_to_exclude.y = cut_point_y.first;
2279 for (
const AMRPatchPosition& patch_x : new_patch_in) {
2280 auto [fst, snd] = patch_x.cut(cut_point_y.first, MD_DirY);
2281 new_patch_out.add(fst);
2282 new_patch_out.add(snd);
2287 else if (cut_point_y.first == -1) {
2288 for (
const AMRPatchPosition& patch_x : new_patch_in) {
2289 min_point_of_patch_to_exclude.y = patch_x.minPoint().y;
2290 auto [fst, snd] = patch_x.cut(cut_point_y.second, MD_DirY);
2291 new_patch_out.add(fst);
2292 new_patch_out.add(snd);
2298 min_point_of_patch_to_exclude.y = cut_point_y.first;
2299 for (
const AMRPatchPosition& patch_x : new_patch_in) {
2300 auto [fst, snd_thr] = patch_x.cut(cut_point_y.first, MD_DirY);
2301 new_patch_out.add(fst);
2302 auto [snd, thr] = snd_thr.cut(cut_point_y.second, MD_DirY);
2303 new_patch_out.add(snd);
2304 new_patch_out.add(thr);
2310 if (m_cmesh->mesh()->dimension() == 3) {
2311 std::swap(new_patch_out, new_patch_in);
2312 new_patch_out.clear();
2314 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);
2318 if (cut_point_z.first == -1 && cut_point_z.second == -1) {
2319 for (
const AMRPatchPosition& patch_y : new_patch_in) {
2320 min_point_of_patch_to_exclude.z = patch_y.minPoint().z;
2321 new_patch_out.add(patch_y);
2326 else if (cut_point_z.second == -1) {
2327 for (
const AMRPatchPosition& patch_y : new_patch_in) {
2328 min_point_of_patch_to_exclude.z = cut_point_z.first;
2329 auto [fst, snd] = patch_y.cut(cut_point_z.first, MD_DirZ);
2330 new_patch_out.add(fst);
2331 new_patch_out.add(snd);
2336 else if (cut_point_z.first == -1) {
2337 for (
const AMRPatchPosition& patch_y : new_patch_in) {
2338 min_point_of_patch_to_exclude.z = patch_y.minPoint().z;
2339 auto [fst, snd] = patch_y.cut(cut_point_z.second, MD_DirZ);
2340 new_patch_out.add(fst);
2341 new_patch_out.add(snd);
2347 for (
const AMRPatchPosition& patch_y : new_patch_in) {
2348 min_point_of_patch_to_exclude.z = cut_point_z.first;
2349 auto [fst, snd_thr] = patch_y.cut(cut_point_z.first, MD_DirZ);
2350 new_patch_out.add(fst);
2351 auto [snd, thr] = snd_thr.cut(cut_point_z.second, MD_DirZ);
2352 new_patch_out.add(snd);
2353 new_patch_out.add(thr);
2361 if (m_cmesh->mesh()->dimension() == 2) {
2362 min_point_of_patch_to_exclude.z = 0;
2368 for (AMRPatchPosition& new_patch : new_patch_out) {
2369 if (new_patch.minPoint() == min_point_of_patch_to_exclude) {
2370 new_patch.setLevel(-2);
2380 AMRPatchPositionLevelGroup::fusionPatches(new_patch_out,
false);
2384 for (
const auto& new_patch : new_patch_out) {
2385 if (!new_patch.isNull()) {
2390 _addCutPatch(new_patch, allCells(index_patch_to_edit));
2397 removePatch(index_patch_to_edit);
2403void CartesianPatchGroup::
2404_addCutPatch(
const AMRPatchPosition& new_patch_position, CellGroup parent_patch_cell_group)
2409 if (parent_patch_cell_group.null())
2412 IItemFamily* cell_family = m_cmesh->mesh()->cellFamily();
2413 Integer group_index = _nextIndexForNewPatch();
2414 String patch_group_name = String(
"CartesianMeshPatchCells") + group_index;
2416 auto* cdi =
new CartesianMeshPatch(m_cmesh, group_index, new_patch_position);
2417 _addPatchInstance(
makeRef(cdi));
2419 UniqueArray<Int32> cells_local_id;
2421 auto numbering = m_cmesh->_internalApi()->cartesianMeshNumberingMngInternal();
2422 ENUMERATE_ (Cell, icell, parent_patch_cell_group) {
2423 const CartCoord3 pos = numbering->cellUniqueIdToCoord(*icell);
2424 if (new_patch_position.isIn(pos)) {
2425 cells_local_id.add(icell.localId());
2429 CellGroup parent_cells = cell_family->createGroup(patch_group_name, cells_local_id,
true);
2431 _addCellGroup(parent_cells, cdi,
false);
2444_addPatch(
const AMRPatchPosition& new_patch_position)
2446 UniqueArray<Int32> cells_local_id;
2448 auto numbering = m_cmesh->_internalApi()->cartesianMeshNumberingMngInternal();
2451 ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allLevelCells(new_patch_position.level())) {
2452 const CartCoord3 pos = numbering->cellUniqueIdToCoord(*icell);
2454 if (new_patch_position.isInWithOverlap(pos)) {
2455 cells_local_id.add(icell.localId());
2459 IItemFamily* cell_family = m_cmesh->mesh()->cellFamily();
2460 Integer group_index = _nextIndexForNewPatch();
2461 String patch_group_name = String(
"CartesianMeshPatchCells") + group_index;
2463 auto* cdi =
new CartesianMeshPatch(m_cmesh, group_index, new_patch_position);
2465 _addPatchInstance(
makeRef(cdi));
2466 CellGroup parent_cells = cell_family->createGroup(patch_group_name, cells_local_id,
true);
2467 Integer array_index = _addCellGroup(parent_cells, cdi,
true);
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
Classe permettant de définir la position d'un patch dans le maillage cartésien.
AMRPatchPosition patchUp(Integer dim, Int32 higher_level, Int32 overlap_layer_size_top_level) const
Méthode permettant de créer un AMRPatchPosition pour le niveau supérieur.
bool isInWithOverlap(CartCoord x, CartCoord y, CartCoord z) const
Méthode permettant de savoir si une maille de position x,y,z est incluse dans ce patch avec couche de...
static Int32 computeOverlapLayerSize(Int32 level, Int32 higher_level, Int32 overlap_layer_size_top_level)
Méthode permettant de calculer le nombre de couches de mailles de recouvrement pour un niveau donné.
CartCoord3 minPoint() const
Méthode permettant de récupérer la position min de la boite englobante.
void setMinPoint(CartCoord3 min_point)
Méthode permettant de définir la position min de la boite englobante.
void setLevel(Int32 level)
Méthode permettant de définir le niveau du patch.
CartCoord3 maxPoint() const
Méthode permettant de récupérer la position max de la boite englobante.
bool haveIntersection(const AMRPatchPosition &other) const
Méthode permettant de savoir si notre patch est en contact avec le patch other.
Int32 overlapLayerSize() const
Méthode permettant de récupérer le nombre de couches de mailles de recouvrement du patch.
void setOverlapLayerSize(Int32 layer_size)
Méthode permettant de définir le nombre de couches de mailles de recouvrement du patch.
Int32 level() const
Méthode permettant de récupérer le niveau du patch.
void setMaxPoint(CartCoord3 max_point)
Méthode permettant de définir la position max de la boite englobante.
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.
Real3 length() const
Méthode permettant de retrouver la taille de la zone.
Real3 position() const
Méthode permettant de retrouver la position de la zone.
AMRPatchPosition toAMRPatchPosition(ICartesianMesh *mesh) const
Méthode permettant de convertir ce AMRZonePosition en AMRPatchPosition.
Integer size() const
Nombre d'éléments du vecteur.
CellGroup allCells(Integer index)
Méthode permettant de récupérer le groupe de toutes les mailles du patch demandé.
void applyPatchEdit(bool remove_empty_patches, bool update_higher_level)
Méthode permettant de supprimer les patchs en attente de suppression.
Vue constante d'un tableau de type T.
Interface d'un patch AMR d'un maillage cartésien.
Interface d'un maillage cartésien.
Interface d'une famille d'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 IMesh * mesh() const =0
Maillage associé
virtual IItemFamily * cellFamily()=0
Retourne la famille des mailles.
@ II_Refine
L'entité est marquée pour raffinement.
const String & name() const
Nom du groupe.
Integer size() const
Nombre d'éléments du groupe.
IMesh * mesh() const
Maillage auquel appartient ce groupe (0 pour le group nul)
Référence à une instance.
Chaîne de caractères unicode.
bool startsWith(const String &s) const
Indique si la chaîne commence par les caractères de s.
const char * localstr() const
Retourne la conversion de l'instance dans l'encodage UTF-8.
String substring(Int64 pos) const
Sous-chaîne commençant à la position pos.
Classe d'accès aux traces.
TraceMessageDbg debug(Trace::eDebugLevel=Trace::Medium) const
Flot pour un message de debug.
TraceMessage info() const
Flot pour un message d'information.
ITraceMng * traceMng() const
Gestionnaire de trace.
Positionne une classe de message.
Vecteur 1D de données avec sémantique par valeur (style STL).
__host__ __device__ Real2 min(Real2 a, Real2 b)
Retourne le minimum de deux Real2.
T max(const T &a, const T &b, const T &c)
Retourne le maximum de trois éléments.
ItemGroupT< Cell > CellGroup
Groupe de mailles.
@ ReduceMax
Maximum des valeurs.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
Int32 CartCoord
Représente une coordonnée d'un élément dans la grille cartésienne (en X ou en Y ou en Z).
Int32 Integer
Type représentant un entier.
auto makeRef(InstanceType *t) -> Ref< InstanceType >
Créé une référence sur un pointeur.
@ 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.
Int32x3 CartCoord3
Représente les coordonnées 3D d'un élément dans la grille cartésienne {x, y, z}.