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"
56, m_index_new_patches(1)
57, m_size_of_overlap_layer_top_level(0)
59, m_target_nb_levels(0)
60, m_latest_call_level(-1)
66void CartesianPatchGroup::
69 m_properties =
makeRef(
new Properties(*(m_cmesh->mesh()->properties()),
"CartesianPatchGroup"));
75void CartesianPatchGroup::
76saveInfosInProperties()
78 m_properties->set(
"Version", 1);
80 if (m_cmesh->mesh()->meshKind().meshAMRKind() != eMeshAMRKind::PatchCartesianMeshOnly) {
81 UniqueArray<String> patch_group_names;
82 for (Integer i = 1; i < m_amr_patches_pointer.size(); ++i) {
83 patch_group_names.add(allCells(i).name());
85 m_properties->set(
"PatchGroupNames", patch_group_names);
89 UniqueArray<String> patch_group_names(m_amr_patches_pointer.size() - 1);
90 UniqueArray<Int32> level(m_amr_patches_pointer.size());
91 UniqueArray<Int32> overlap(m_amr_patches_pointer.size());
92 UniqueArray<Int32> index(m_amr_patches_pointer.size());
93 UniqueArray<CartCoord> min_point(m_amr_patches_pointer.size() * 3);
94 UniqueArray<CartCoord> max_point(m_amr_patches_pointer.size() * 3);
96 for (Integer i = 0; i < m_amr_patches_pointer.size(); ++i) {
97 const AMRPatchPosition& position = m_amr_patches_pointer[i]->_internalApi()->positionRef();
98 level[i] = position.level();
99 overlap[i] = position.overlapLayerSize();
100 index[i] = m_amr_patches_pointer[i]->index();
103 min_point[pos + 0] = position.minPoint().x;
104 min_point[pos + 1] = position.minPoint().y;
105 min_point[pos + 2] = position.minPoint().z;
106 max_point[pos + 0] = position.maxPoint().x;
107 max_point[pos + 1] = position.maxPoint().y;
108 max_point[pos + 2] = position.maxPoint().z;
111 patch_group_names[i - 1] = allCells(i).name();
114 m_properties->set(
"LevelPatches", level);
115 m_properties->set(
"OverlapSizePatches", overlap);
116 m_properties->set(
"IndexPatches", index);
117 m_properties->set(
"MinPointPatches", min_point);
118 m_properties->set(
"MaxPointPatches", max_point);
125 m_properties->set(
"PatchGroupNamesAvailable", m_available_group_index);
126 m_properties->set(
"PatchGroupNames", patch_group_names);
133void CartesianPatchGroup::
136 Trace::Setter mci(traceMng(),
"CartesianPatchGroup");
139 Int32 v = m_properties->getInt32(
"Version");
141 ARCANE_FATAL(
"Bad serializer version: trying to read from incompatible checkpoint v={0} expected={1}", v, 1);
147 UniqueArray<String> patch_group_names;
148 m_properties->get(
"PatchGroupNames", patch_group_names);
150 if (m_cmesh->mesh()->meshKind().meshAMRKind() != eMeshAMRKind::PatchCartesianMeshOnly) {
151 info(4) <<
"Found n=" << patch_group_names.size() <<
" patchs";
153 IItemFamily* cell_family = m_cmesh->mesh()->cellFamily();
154 for (
const String& x : patch_group_names) {
155 CellGroup group = cell_family->findGroup(x);
158 addPatchAfterRestore(group);
162 UniqueArray<Int32> level;
163 UniqueArray<Int32> overlap;
164 UniqueArray<Int32> index;
165 UniqueArray<CartCoord> min_point;
166 UniqueArray<CartCoord> max_point;
168 m_properties->get(
"LevelPatches", level);
169 m_properties->get(
"OverlapSizePatches", overlap);
170 m_properties->get(
"IndexPatches", index);
171 m_properties->get(
"MinPointPatches", min_point);
172 m_properties->get(
"MaxPointPatches", max_point);
174 if (index.size() < 1) {
179 ConstArrayView
min(min_point.subConstView(0, 3));
180 ConstArrayView
max(max_point.subConstView(0, 3));
182 AMRPatchPosition position(
188 m_amr_patches_pointer[0]->_internalApi()->setPosition(position);
191 IItemFamily* cell_family = m_cmesh->mesh()->cellFamily();
193 for (Integer i = 1; i < index.size(); ++i) {
194 ConstArrayView
min(min_point.subConstView(i * 3, 3));
195 ConstArrayView
max(max_point.subConstView(i * 3, 3));
197 AMRPatchPosition position(
203 const String& x = patch_group_names[i - 1];
204 CellGroup cell_group = cell_family->findGroup(x);
205 if (cell_group.null())
208 auto* cdi =
new CartesianMeshPatch(m_cmesh, index[i], position);
209 _addPatchInstance(
makeRef(cdi));
210 _addCellGroup(cell_group, cdi);
213 UniqueArray<Int32> available_index;
214 m_properties->get(
"PatchGroupNamesAvailable", available_index);
215 rebuildAvailableGroupIndex(available_index);
222Ref<CartesianMeshPatch> CartesianPatchGroup::
225 _createGroundPatch();
232void CartesianPatchGroup::
233addPatch(ConstArrayView<Int32> cells_local_id)
235 if (m_cmesh->mesh()->meshKind().meshAMRKind() == eMeshAMRKind::PatchCartesianMeshOnly) {
239 Integer index = _nextIndexForNewPatch();
240 String children_group_name = String(
"CartesianMeshPatchCells") + index;
241 IItemFamily* cell_family = m_cmesh->mesh()->cellFamily();
242 CellGroup children_cells = cell_family->createGroup(children_group_name, cells_local_id,
true);
243 addPatch(children_cells, index);
251addPatchAfterRestore(CellGroup cell_group)
253 const String& name = cell_group.name();
255 if (name.startsWith(
"CartesianMeshPatchCells")) {
256 String index_str = name.substring(23);
257 group_index = std::stoi(index_str.localstr());
263 addPatch(cell_group, group_index);
270void CartesianPatchGroup::
271addPatch(CellGroup cell_group, Integer group_index)
273 _createGroundPatch();
274 if (cell_group.null())
277 AMRPatchPosition position;
279 auto* cdi =
new CartesianMeshPatch(m_cmesh, group_index, position);
280 _addPatchInstance(
makeRef(cdi));
281 _addCellGroup(cell_group, cdi);
287void CartesianPatchGroup::
288addPatch(
const AMRZonePosition& zone_position)
290 Trace::Setter mci(traceMng(),
"CartesianPatchGroup");
292 info() <<
"addPatch() with zone"
293 <<
" -- Position : " << zone_position.position()
294 <<
" -- Length : " << zone_position.length();
296 clearRefineRelatedFlags();
298 auto amr = m_cmesh->_internalApi()->cartesianMeshAMRPatchMng();
299 auto numbering = m_cmesh->_internalApi()->cartesianMeshNumberingMngInternal();
301 AMRPatchPosition position = zone_position.toAMRPatchPosition(m_cmesh);
302 Int32 level = position.level();
303 Int32 level_up = level + 1;
304 Int32 nb_overlap_cells = 0;
306 Int32 higher_level = m_higher_level;
311 if (level_up >= higher_level) {
312 higher_level = level_up;
313 nb_overlap_cells = m_size_of_overlap_layer_top_level / numbering->pattern();
314 debug() <<
"Higher level -- Old : " << m_higher_level <<
" -- New : " << higher_level;
330 nb_overlap_cells = overlapLayerSize(level + 1) / numbering->pattern();
332 position.setOverlapLayerSize(nb_overlap_cells);
334 debug() <<
"Zone to intermediary patch"
335 <<
" -- minPoint : " << position.minPoint()
336 <<
" -- maxPoint : " << position.maxPoint()
337 <<
" -- overlapLayerSize : " << position.overlapLayerSize()
338 <<
" -- level : " << level;
340 ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allLevelCells(level)) {
341 if (!icell->hasHChildren()) {
342 const CartCoord3 pos = numbering->cellUniqueIdToCoord(*icell);
343 if (position.isInWithOverlap(pos)) {
344 icell->mutableItemBase().addFlags(ItemFlags::II_Refine);
351 AMRPatchPosition position_up = position.patchUp(m_cmesh->mesh()->dimension(), higher_level, m_size_of_overlap_layer_top_level);
353 info() <<
"Zone to Patch"
354 <<
" -- minPoint : " << position_up.minPoint()
355 <<
" -- maxPoint : " << position_up.maxPoint()
356 <<
" -- overlapLayerSize : " << position_up.overlapLayerSize()
357 <<
" -- level : " << position_up.level();
359 _addPatch(position_up);
360 _updateHigherLevel();
363 _checkPatchesAndMesh();
374 return m_amr_patches.size();
380Ref<CartesianMeshPatch> CartesianPatchGroup::
381patch(
const Integer index)
const
383 return m_amr_patches[index];
389CartesianMeshPatchListView CartesianPatchGroup::
392 return CartesianMeshPatchListView{ m_amr_patches_pointer };
399allCells(
const Integer index)
402 ARCANE_FATAL(
"You cannot get cells of ground patch with this method");
404 return m_amr_patch_cell_groups_all[index - 1];
411inPatchCells(Integer index)
413 if (m_cmesh->mesh()->meshKind().meshAMRKind() != eMeshAMRKind::PatchCartesianMeshOnly) {
414 ARCANE_FATAL(
"Method available only with AMR PatchCartesianMeshOnly");
417 ARCANE_FATAL(
"You cannot get cells of ground patch with this method");
419 return m_amr_patch_cell_groups_inpatch[index - 1];
426overlapCells(Integer index)
428 if (m_cmesh->mesh()->meshKind().meshAMRKind() != eMeshAMRKind::PatchCartesianMeshOnly) {
429 ARCANE_FATAL(
"Method available only with AMR PatchCartesianMeshOnly");
432 ARCANE_FATAL(
"You cannot get cells of ground patch with this method");
434 return m_amr_patch_cell_groups_overlap[index - 1];
441void CartesianPatchGroup::
445 _createGroundPatch();
451void CartesianPatchGroup::
452removePatch(
const Integer index)
454 if (m_patches_to_delete.contains(index)) {
460 if (index < 1 || index >= m_amr_patches.size()) {
464 m_patches_to_delete.add(index);
470void CartesianPatchGroup::
471removeCellsInAllPatches(ConstArrayView<Int32> cells_local_id)
473 if (m_cmesh->mesh()->meshKind().meshAMRKind() == eMeshAMRKind::PatchCartesianMeshOnly) {
476 for (CellGroup cells : m_amr_patch_cell_groups_all) {
477 cells.removeItems(cells_local_id);
484void CartesianPatchGroup::
485_removeCellsInAllPatches(
const AMRPatchPosition& zone_to_delete)
489 const Integer nb_patchs = m_amr_patches_pointer.size();
490 for (Integer i = 1; i < nb_patchs; ++i) {
491 ICartesianMeshPatch* patch = m_amr_patches_pointer[i];
500 if (zone_to_delete.haveIntersection(patch->position())) {
501 _removePartOfPatch(i, zone_to_delete);
504 _updatePatchFlagsOfCellsLevel(zone_to_delete.level(),
false);
510void CartesianPatchGroup::
511removeCellsInZone(
const AMRZonePosition& zone_to_delete)
513 if (m_cmesh->mesh()->meshKind().meshAMRKind() != eMeshAMRKind::PatchCartesianMeshOnly) {
514 ARCANE_FATAL(
"Method available only with AMR PatchCartesianMeshOnly");
516 clearRefineRelatedFlags();
518 UniqueArray<Int32> cells_local_id;
520 AMRPatchPosition patch_position;
521 zone_to_delete.cellsInPatch(m_cmesh, cells_local_id, patch_position);
523 _removeCellsInAllPatches(patch_position);
524 applyPatchEdit(
false);
525 auto amr = m_cmesh->_internalApi()->cartesianMeshAMRPatchMng();
526 auto numbering = m_cmesh->_internalApi()->cartesianMeshNumberingMngInternal();
528 Int32 level = patch_position.level();
530 ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allLevelCells(level)) {
531 if (!icell->hasHChildren()) {
532 const CartCoord3 pos = numbering->cellUniqueIdToCoord(*icell);
533 if (patch_position.isIn(pos)) {
534 icell->mutableItemBase().addFlags(ItemFlags::II_Coarsen);
542 _checkPatchesAndMesh();
549void CartesianPatchGroup::
550applyPatchEdit(
bool remove_empty_patches)
554 std::stable_sort(m_patches_to_delete.begin(), m_patches_to_delete.end(),
555 [](
const Integer a,
const Integer b) {
559 _removeMultiplePatches(m_patches_to_delete);
560 m_patches_to_delete.clear();
562 if (remove_empty_patches) {
563 if (m_cmesh->mesh()->meshKind().meshAMRKind() == eMeshAMRKind::PatchCartesianMeshOnly) {
564 ARCANE_FATAL(
"remove_empty_patches=true available only with AMR Cell");
566 UniqueArray<Integer> size_of_patches(m_amr_patch_cell_groups_all.size());
567 for (Integer i = 0; i < m_amr_patch_cell_groups_all.size(); ++i) {
568 size_of_patches[i] = m_amr_patch_cell_groups_all[i].size();
570 m_cmesh->mesh()->parallelMng()->reduce(MessagePassing::ReduceMax, size_of_patches);
571 for (Integer i = 0; i < size_of_patches.size(); ++i) {
572 if (size_of_patches[i] == 0) {
573 m_patches_to_delete.add(i + 1);
576 _removeMultiplePatches(m_patches_to_delete);
577 m_patches_to_delete.clear();
580 if (m_cmesh->mesh()->meshKind().meshAMRKind() == eMeshAMRKind::PatchCartesianMeshOnly) {
581 _updateHigherLevel();
588void CartesianPatchGroup::
589updateLevelsAndAddGroundPatch()
591 if (m_cmesh->mesh()->meshKind().meshAMRKind() != eMeshAMRKind::PatchCartesianMeshOnly) {
594 auto numbering = m_cmesh->_internalApi()->cartesianMeshNumberingMngInternal();
598 for (ICartesianMeshPatch* patch : m_amr_patches_pointer) {
599 const Int32 level = patch->position().level();
602 const CartCoord3 max_point = patch->position().maxPoint();
603 if (m_cmesh->mesh()->dimension() == 2) {
604 patch->_internalApi()->positionRef().setMaxPoint({
605 numbering->offsetLevelToLevel(max_point.x, level, level - 1),
606 numbering->offsetLevelToLevel(max_point.y, level, level - 1),
611 patch->_internalApi()->positionRef().setMaxPoint({
612 numbering->offsetLevelToLevel(max_point.x, level, level - 1),
613 numbering->offsetLevelToLevel(max_point.y, level, level - 1),
614 numbering->offsetLevelToLevel(max_point.z, level, level - 1),
620 patch->_internalApi()->positionRef().setLevel(level + 1);
624 AMRPatchPosition old_ground;
625 old_ground.setLevel(1);
626 old_ground.setMinPoint({ 0, 0, 0 });
627 old_ground.setMaxPoint({ numbering->globalNbCellsX(1), numbering->globalNbCellsY(1), numbering->globalNbCellsZ(1) });
628 old_ground.computeOverlapLayerSize(m_higher_level + 1, m_size_of_overlap_layer_top_level);
630 _addPatch(old_ground);
631 _updatePatchFlagsOfCellsGroundLevel();
632 _updateHigherLevel();
635 _checkPatchesAndMesh();
643_nextIndexForNewPatch()
645 if (!m_available_group_index.empty()) {
646 const Integer elem = m_available_group_index.back();
647 m_available_group_index.popBack();
650 return m_index_new_patches++;
656void CartesianPatchGroup::
659 if (m_cmesh->mesh()->meshKind().meshAMRKind() != eMeshAMRKind::PatchCartesianMeshOnly) {
663 UniqueArray<std::pair<Integer, Int64>> index_n_nb_cells;
666 for (
auto patch : m_amr_patches_pointer) {
667 index_n_nb_cells.add({ index++, patch->position().nbCells() });
679 std::stable_sort(index_n_nb_cells.begin(), index_n_nb_cells.end(),
680 [](
const std::pair<Integer, Int64>& a,
const std::pair<Integer, Int64>& b) {
681 return a.second < b.second;
684 for (Integer p0 = 0; p0 < index_n_nb_cells.size(); ++p0) {
685 auto [index_p0, nb_cells_p0] = index_n_nb_cells[p0];
687 AMRPatchPosition& patch_fusion_0 = m_amr_patches_pointer[index_p0]->_internalApi()->positionRef();
688 if (patch_fusion_0.isNull())
695 for (Integer p1 = p0 + 1; p1 < m_amr_patches_pointer.size(); ++p1) {
696 auto [index_p1, nb_cells_p1] = index_n_nb_cells[p1];
698 AMRPatchPosition& patch_fusion_1 = m_amr_patches_pointer[index_p1]->_internalApi()->positionRef();
699 if (patch_fusion_1.isNull())
710 if (patch_fusion_0.fusion(patch_fusion_1)) {
712 index_n_nb_cells[p0].second = patch_fusion_0.nbCells();
714 UniqueArray<Int32> local_ids;
715 allCells(index_p1).view().fillLocalIds(local_ids);
716 allCells(index_p0).addItems(local_ids,
false);
719 removePatch(index_p1);
731 _checkPatchesAndMesh();
738void CartesianPatchGroup::
739beginAdaptMesh(Int32 nb_levels, Int32 level_to_refine_first)
741 if (m_cmesh->mesh()->meshKind().meshAMRKind() != eMeshAMRKind::PatchCartesianMeshOnly) {
742 ARCANE_FATAL(
"Method available only with AMR PatchCartesianMeshOnly");
744 if (m_latest_call_level != -1) {
745 ARCANE_FATAL(
"Call endAdaptMesh() before restart mesh adaptation");
748 Trace::Setter mci(traceMng(),
"CartesianPatchGroup");
749 info() <<
"Begin adapting mesh with higher level = " << (nb_levels - 1);
753 if (nb_levels - 1 != m_higher_level) {
754 debug() <<
"beginAdaptMesh() -- First call -- Change overlap layer size -- Old higher level : " << m_higher_level
755 <<
" -- Asked higher level : " << (nb_levels - 1)
756 <<
" -- Adapt level lower than : " << level_to_refine_first;
758 for (Int32 level = 1; level <= level_to_refine_first; ++level) {
759 _changeOverlapSizeLevel(level, m_higher_level, nb_levels - 1);
765 for (Integer p = 1; p < m_amr_patches_pointer.size(); ++p) {
766 Int32 level = m_amr_patches_pointer[p]->_internalApi()->positionRef().level();
767 if (level > level_to_refine_first) {
772 applyPatchEdit(
false);
777 for (Integer l = level_to_refine_first + 1; l <= max_level; ++l) {
778 ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allLevelCells(l)) {
779 icell->mutableItemBase().removeFlags(ItemFlags::II_Overlap | ItemFlags::II_InPatch);
783 m_target_nb_levels = nb_levels;
784 m_latest_call_level = level_to_refine_first;
790void CartesianPatchGroup::
793 if (m_cmesh->mesh()->meshKind().meshAMRKind() != eMeshAMRKind::PatchCartesianMeshOnly) {
794 ARCANE_FATAL(
"Method available only with AMR PatchCartesianMeshOnly");
796 if (m_latest_call_level == -1) {
799 Trace::Setter mci(traceMng(),
"CartesianPatchGroup");
800 info() <<
"Finalizing adapting mesh with higher level = " << (m_target_nb_levels - 1);
802 auto amr = m_cmesh->_internalApi()->cartesianMeshAMRPatchMng();
808 m_higher_level = m_latest_call_level + 1;
816 if (m_higher_level + 1 < m_target_nb_levels) {
817 info() <<
"Reduce higher level from " << (m_target_nb_levels - 1) <<
" to " << m_higher_level;
819 for (Int32 level = 1; level <= m_higher_level; ++level) {
820 _changeOverlapSizeLevel(level, m_target_nb_levels - 1, m_higher_level);
827 ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allCells()) {
828 if (icell->level() > max_level) {
829 max_level = icell->level();
832 max_level = m_cmesh->mesh()->parallelMng()->reduce(MessagePassing::ReduceMax, max_level);
834 debug() <<
"Max level of cells : " << max_level;
837 for (Integer level = max_level; level > 0; --level) {
838 Integer nb_cells_to_coarse = 0;
839 ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allLevelCells(level)) {
840 if (!icell->hasFlags(ItemFlags::II_InPatch) && !icell->hasFlags(ItemFlags::II_Overlap)) {
842 icell->mutableItemBase().addFlags(ItemFlags::II_Coarsen);
843 nb_cells_to_coarse++;
846 debug() <<
"Remove " << nb_cells_to_coarse <<
" refined cells without flag in level " << level;
847 nb_cells_to_coarse = m_cmesh->mesh()->parallelMng()->reduce(MessagePassing::ReduceMax, nb_cells_to_coarse);
848 if (nb_cells_to_coarse != 0) {
853 m_target_nb_levels = 0;
854 m_latest_call_level = -1;
855 clearRefineRelatedFlags();
857 info() <<
"Patch list:";
859 for (Integer i = 0; i <= m_higher_level; ++i) {
860 for (
auto p : m_amr_patches_pointer) {
861 auto& position = p->_internalApi()->positionRef();
862 if (position.level() == i) {
863 info() <<
"\tPatch #" << p->index()
864 <<
" -- Level : " << position.level()
865 <<
" -- Min point : " << position.minPoint()
866 <<
" -- Max point : " << position.maxPoint()
867 <<
" -- Overlap layer size : " << position.overlapLayerSize();
872 _checkPatchesAndMesh();
879void CartesianPatchGroup::
880adaptLevel(Int32 level_to_adapt)
882 if (m_cmesh->mesh()->meshKind().meshAMRKind() != eMeshAMRKind::PatchCartesianMeshOnly) {
883 ARCANE_FATAL(
"Method available only with AMR PatchCartesianMeshOnly");
886 if (m_latest_call_level == -1) {
887 ARCANE_FATAL(
"Call beginAdaptMesh() before to begin a mesh adaptation");
890 Trace::Setter mci(traceMng(),
"CartesianPatchGroup");
892 if (level_to_adapt + 1 >= m_target_nb_levels || level_to_adapt < 0) {
893 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);
901 if (level_to_adapt < m_latest_call_level) {
903 for (Integer p = 1; p < m_amr_patches_pointer.size(); ++p) {
904 Int32 level = m_amr_patches_pointer[p]->_internalApi()->positionRef().level();
905 if (level > level_to_adapt) {
910 applyPatchEdit(
false);
912 for (Integer l = level_to_adapt + 1; l <= max_level; ++l) {
913 ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allLevelCells(l)) {
914 icell->mutableItemBase().removeFlags(ItemFlags::II_Overlap | ItemFlags::II_InPatch);
919 m_latest_call_level = level_to_adapt;
920 auto amr = m_cmesh->_internalApi()->cartesianMeshAMRPatchMng();
921 auto numbering = m_cmesh->_internalApi()->cartesianMeshNumberingMngInternal();
935 Int32 nb_overlap_cells = overlapLayerSize(level_to_adapt + 1) / numbering->pattern();
937 info() <<
"adaptLevel()"
938 <<
" -- level_to_adapt : " << level_to_adapt
939 <<
" -- nb_overlap_cells : " << nb_overlap_cells;
945 ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allCells()) {
946 if (icell->hasFlags(ItemFlags::II_Refine)) {
947 if (icell->level() != level_to_adapt) {
948 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);
950 if (level_to_adapt != 0 && !icell->hasFlags(ItemFlags::II_InPatch)) {
951 const CartCoord3 pos = numbering->cellUniqueIdToCoord(*icell);
952 ARCANE_FATAL(
"Cannot refine cell not in patch -- Pos : {0} -- CellUID : {1} -- CellLevel : {2}", pos, icell->uniqueId(), icell->level());
957 UniqueArray<AMRPatchPositionSignature> sig_array;
965 if (level_to_adapt == 0) {
966 AMRPatchPosition all_level;
967 all_level.setLevel(level_to_adapt);
968 all_level.setMinPoint({ 0, 0, 0 });
969 all_level.setMaxPoint({ numbering->globalNbCellsX(level_to_adapt), numbering->globalNbCellsY(level_to_adapt), numbering->globalNbCellsZ(level_to_adapt) });
971 all_level.setOverlapLayerSize(nb_overlap_cells);
972 AMRPatchPositionSignature sig(all_level, m_cmesh);
991 for (
auto patch : m_amr_patches_pointer) {
992 Integer level = patch->_internalApi()->positionRef().level();
993 if (level == level_to_adapt) {
994 auto position = patch->position();
995 position.setOverlapLayerSize(nb_overlap_cells);
996 AMRPatchPositionSignature sig(position, m_cmesh);
1002 AMRPatchPositionSignatureCut::cut(sig_array);
1006 ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allLevelCells(level_to_adapt)) {
1007 if (!icell->hasHChildren()) {
1008 const CartCoord3 pos = numbering->cellUniqueIdToCoord(*icell);
1009 for (
const AMRPatchPositionSignature& patch_signature : sig_array) {
1010 if (patch_signature.patch().isInWithOverlap(pos)) {
1011 if (!icell->hasFlags(ItemFlags::II_InPatch) && !icell->hasFlags(ItemFlags::II_Overlap)) {
1012 ARCANE_FATAL(
"Internal error -- Refine algo error -- Pos : {0}", pos);
1014 icell->mutableItemBase().addFlags(ItemFlags::II_Refine);
1053 ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allLevelCells(level_to_adapt)) {
1054 icell->mutableItemBase().removeFlags(ItemFlags::II_Refine);
1062 UniqueArray<AMRPatchPosition> all_patches;
1063 for (
const auto& elem : sig_array) {
1064 all_patches.add(elem.patch().patchUp(m_cmesh->mesh()->dimension(), m_target_nb_levels - 1, m_size_of_overlap_layer_top_level));
1068 AMRPatchPositionLevelGroup::fusionPatches(all_patches,
true);
1070 for (
const AMRPatchPosition& patch : all_patches) {
1071 debug() <<
"\tPatch AAA"
1072 <<
" -- Level : " << patch.level()
1073 <<
" -- Min point : " << patch.minPoint()
1074 <<
" -- Max point : " << patch.maxPoint()
1075 <<
" -- overlapLayerSize : " << patch.overlapLayerSize();
1138 for (
const AMRPatchPosition& patch : all_patches) {
1139 Integer index = _addPatch(patch);
1141 m_cmesh->computeDirectionsPatchV2(index + 1);
1144 debug() <<
"adaptLevel() -- End call -- Actual patch list:";
1146 for (Integer i = 0; i <= m_target_nb_levels; ++i) {
1147 for (
auto p : m_amr_patches_pointer) {
1148 auto& position = p->_internalApi()->positionRef();
1149 if (position.level() == i) {
1150 debug() <<
"\tPatch #" << p->index()
1151 <<
" -- Level : " << position.level()
1152 <<
" -- Min point : " << position.minPoint()
1153 <<
" -- Max point : " << position.maxPoint()
1154 <<
" -- Overlap layer size : " << position.overlapLayerSize();
1163void CartesianPatchGroup::
1164_increaseOverlapSizeLevel(Int32 level_to_increate, Int32 new_size)
1166 if (level_to_increate == 0) {
1170 auto amr = m_cmesh->_internalApi()->cartesianMeshAMRPatchMng();
1171 auto numbering = m_cmesh->_internalApi()->cartesianMeshNumberingMngInternal();
1173 bool has_cell_to_refine =
false;
1182 for (Integer p = 1; p < m_amr_patches_pointer.size(); ++p) {
1183 Int32 level = m_amr_patches_pointer[p]->_internalApi()->positionRef().level();
1184 if (level == level_to_increate) {
1185 AMRPatchPosition& position = m_amr_patches_pointer[p]->_internalApi()->positionRef();
1187 Int32 size_layer = position.overlapLayerSize();
1188 if (size_layer > new_size) {
1189 ARCANE_FATAL(
"Cannot reduce layer with _increaseOverlapSizeLevel method");
1195 if (size_layer == new_size) {
1199 has_cell_to_refine =
true;
1200 position.setOverlapLayerSize(new_size);
1206 ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allLevelCells(level_to_increate - 1)) {
1207 const CartCoord3 pos = numbering->offsetLevelToLevel(numbering->cellUniqueIdToCoord(*icell), level_to_increate - 1, level_to_increate);
1208 if (position.isInWithOverlap(pos) && !icell->hasHChildren()) {
1209 icell->mutableItemBase().addFlags(ItemFlags::II_Refine);
1214 has_cell_to_refine = m_cmesh->mesh()->parallelMng()->reduce(MessagePassing::ReduceMax, has_cell_to_refine);
1215 if (!has_cell_to_refine) {
1223 ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allLevelCells(level_to_increate - 1)) {
1224 icell->mutableItemBase().removeFlags(ItemFlags::II_Refine);
1227 UniqueArray<Int32> cell_to_add;
1230 for (Integer p = 1; p < m_amr_patches_pointer.size(); ++p) {
1231 Int32 level = m_amr_patches_pointer[p]->_internalApi()->positionRef().level();
1232 if (level == level_to_increate) {
1233 AMRPatchPosition& position = m_amr_patches_pointer[p]->_internalApi()->positionRef();
1235 ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allLevelCells(level_to_increate)) {
1236 if (!icell->hasFlags(ItemFlags::II_JustAdded))
1239 const CartCoord3 pos = numbering->cellUniqueIdToCoord(*icell);
1241 if (position.isIn(pos)) {
1242 icell->mutableItemBase().addFlags(ItemFlags::II_InPatch);
1244 else if (position.isInWithOverlap(pos)) {
1245 cell_to_add.add(icell.localId());
1246 icell->mutableItemBase().addFlags(ItemFlags::II_Overlap);
1250 m_amr_patch_cell_groups_all[p - 1].addItems(cell_to_add,
true);
1251 m_amr_patch_cell_groups_overlap[p - 1].addItems(cell_to_add,
true);
1252 cell_to_add.clear();
1255 m_cmesh->computeDirectionsPatchV2(p);
1259 ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allLevelCells(level_to_increate)) {
1260 icell->mutableItemBase().removeFlags(ItemFlags::II_JustAdded);
1267void CartesianPatchGroup::
1268_reduceOverlapSizeLevel(Int32 level_to_reduce, Int32 new_size)
1277 if (level_to_reduce == 0) {
1281 auto amr = m_cmesh->_internalApi()->cartesianMeshAMRPatchMng();
1282 auto numbering = m_cmesh->_internalApi()->cartesianMeshNumberingMngInternal();
1289 bool has_cell_to_mark =
false;
1290 UniqueArray<Int32> cell_to_remove;
1292 for (Integer p = 1; p < m_amr_patches_pointer.size(); ++p) {
1293 Int32 level = m_amr_patches_pointer[p]->_internalApi()->positionRef().level();
1294 if (level == level_to_reduce) {
1295 AMRPatchPosition& position = m_amr_patches_pointer[p]->_internalApi()->positionRef();
1297 Int32 size_layer = position.overlapLayerSize();
1298 if (size_layer < new_size) {
1299 ARCANE_FATAL(
"Cannot add layer with _reduceOverlapSizeLevel method");
1301 if (size_layer == new_size) {
1305 has_cell_to_mark =
true;
1306 position.setOverlapLayerSize(new_size);
1308 ENUMERATE_ (Cell, icell, m_amr_patch_cell_groups_overlap[p - 1]) {
1309 const CartCoord3 pos = numbering->cellUniqueIdToCoord(*icell);
1310 if (!position.isInWithOverlap(pos)) {
1311 cell_to_remove.add(icell.localId());
1315 m_amr_patch_cell_groups_all[p - 1].removeItems(cell_to_remove,
true);
1316 m_amr_patch_cell_groups_overlap[p - 1].removeItems(cell_to_remove,
true);
1317 cell_to_remove.clear();
1320 has_cell_to_mark = m_cmesh->mesh()->parallelMng()->reduce(MessagePassing::ReduceMax, has_cell_to_mark);
1321 if (!has_cell_to_mark) {
1326 _updatePatchFlagsOfCellsLevel(level_to_reduce,
true);
1328 for (Integer p = 1; p < m_amr_patches_pointer.size(); ++p) {
1329 Int32 level = m_amr_patches_pointer[p]->_internalApi()->positionRef().level();
1330 if (level == level_to_reduce) {
1331 m_cmesh->computeDirectionsPatchV2(p);
1339void CartesianPatchGroup::
1343 Int32 new_higher_level = 0;
1344 for (
const auto patch : m_amr_patches_pointer) {
1345 const Int32 level = patch->_internalApi()->positionRef().level();
1346 if (level > new_higher_level) {
1347 new_higher_level = level;
1351 if (new_higher_level == m_higher_level) {
1355 auto amr = m_cmesh->_internalApi()->cartesianMeshAMRPatchMng();
1357 for (Int32 level = 1; level <= new_higher_level; ++level) {
1358 _changeOverlapSizeLevel(level, m_higher_level, new_higher_level);
1360 m_higher_level = new_higher_level;
1366 for (Integer level = m_higher_level; level > 0; --level) {
1367 Integer nb_cells_to_coarse = 0;
1368 ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allLevelCells(level)) {
1369 if (!icell->hasFlags(ItemFlags::II_InPatch) && !icell->hasFlags(ItemFlags::II_Overlap)) {
1371 icell->mutableItemBase().addFlags(ItemFlags::II_Coarsen);
1372 nb_cells_to_coarse++;
1375 debug() <<
"Remove " << nb_cells_to_coarse <<
" refined cells without flag in level " << level;
1376 nb_cells_to_coarse = m_cmesh->mesh()->parallelMng()->reduce(MessagePassing::ReduceMax, nb_cells_to_coarse);
1377 if (nb_cells_to_coarse != 0) {
1386void CartesianPatchGroup::
1387_changeOverlapSizeLevel(Int32 level, Int32 previous_higher_level, Int32 new_higher_level)
1389 if (previous_higher_level == new_higher_level) {
1393 Int32 old_overlap_size = ((level > previous_higher_level) ? 0 : AMRPatchPosition::computeOverlapLayerSize(level, previous_higher_level, m_size_of_overlap_layer_top_level));
1394 Int32 new_overlap_size = AMRPatchPosition::computeOverlapLayerSize(level, new_higher_level, m_size_of_overlap_layer_top_level);
1396 if (old_overlap_size == new_overlap_size) {
1399 if (old_overlap_size < new_overlap_size) {
1400 _increaseOverlapSizeLevel(level, new_overlap_size);
1403 _reduceOverlapSizeLevel(level, new_overlap_size);
1410void CartesianPatchGroup::
1411_updatePatchFlagsOfCellsLevel(Int32 level,
bool use_cell_groups)
1414 _updatePatchFlagsOfCellsGroundLevel();
1418 auto numbering = m_cmesh->_internalApi()->cartesianMeshNumberingMngInternal();
1420 ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allLevelCells(level)) {
1421 icell->mutableItemBase().removeFlags(ItemFlags::II_InPatch | ItemFlags::II_Overlap);
1427 if (use_cell_groups) {
1428 for (Integer p = 1; p < m_amr_patches_pointer.size(); ++p) {
1429 Int32 level_patch = m_amr_patches_pointer[p]->_internalApi()->positionRef().level();
1430 if (level_patch == level) {
1431 ENUMERATE_ (Cell, icell, m_amr_patch_cell_groups_inpatch[p - 1]) {
1432 icell->mutableItemBase().addFlags(ItemFlags::II_InPatch);
1434 ENUMERATE_ (Cell, icell, m_amr_patch_cell_groups_overlap[p - 1]) {
1435 icell->mutableItemBase().addFlags(ItemFlags::II_Overlap);
1444 ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allLevelCells(level)) {
1445 bool in_overlap =
false;
1446 bool in_patch =
false;
1454 const CartCoord3 pos = numbering->cellUniqueIdToCoord(*icell);
1456 for (Integer p = 1; p < m_amr_patches_pointer.size(); ++p) {
1457 auto& patch = m_amr_patches_pointer[p]->_internalApi()->positionRef();
1458 if (patch.level() != level) {
1462 if (patch.isIn(pos)) {
1465 else if (patch.isInWithOverlap(pos)) {
1468 if (in_patch && in_overlap) {
1472 if (in_patch && in_overlap) {
1473 icell->mutableItemBase().addFlags(ItemFlags::II_Overlap);
1474 icell->mutableItemBase().addFlags(ItemFlags::II_InPatch);
1476 else if (in_overlap) {
1477 icell->mutableItemBase().addFlags(ItemFlags::II_Overlap);
1478 icell->mutableItemBase().removeFlags(ItemFlags::II_InPatch);
1480 else if (in_patch) {
1481 icell->mutableItemBase().addFlags(ItemFlags::II_InPatch);
1482 icell->mutableItemBase().removeFlags(ItemFlags::II_Overlap);
1485 icell->mutableItemBase().removeFlags(ItemFlags::II_InPatch);
1486 icell->mutableItemBase().removeFlags(ItemFlags::II_Overlap);
1495void CartesianPatchGroup::
1496_updatePatchFlagsOfCellsGroundLevel()
1498 ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allLevelCells(0)) {
1499 icell->mutableItemBase().addFlags(ItemFlags::II_InPatch);
1506void CartesianPatchGroup::
1507_checkPatchesAndMesh()
1509 auto numbering = m_cmesh->_internalApi()->cartesianMeshNumberingMngInternal();
1511 Int32 higher_level = 0;
1512 ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allCells()) {
1513 if (icell->level() > higher_level) {
1514 higher_level = icell->level();
1517 higher_level = m_cmesh->mesh()->parallelMng()->reduce(MessagePassing::ReduceMax, higher_level);
1518 if (higher_level != m_higher_level) {
1519 ARCANE_FATAL(
"_checkPatchesAndMesh -- Bad higher level -- m_higher_level : {0} -- Found : {1}", m_higher_level, higher_level);
1523 for (Int32 level = 0; level < m_higher_level; ++level) {
1524 Int32 check_overlap = overlapLayerSize(level);
1525 for (Integer p = 0; p < m_amr_patches_pointer.size(); ++p) {
1526 auto& position = m_amr_patches_pointer[p]->_internalApi()->positionRef();
1527 if (position.level() == level) {
1528 if (check_overlap == -1) {
1529 check_overlap = position.overlapLayerSize();
1531 else if (check_overlap != position.overlapLayerSize()) {
1532 ARCANE_FATAL(
"_checkPatchesAndMesh -- Overlap size incoherence -- Patch pos : {0} -- Previous size : {1} -- Found : {2}", p, check_overlap, position.overlapLayerSize());
1541 ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allCells()) {
1542 Integer level = icell->level();
1544 bool in_overlap =
false;
1545 bool in_patch =
false;
1547 const CartCoord3 pos = numbering->cellUniqueIdToCoord(*icell);
1549 for (Integer p = 0; p < m_amr_patches_pointer.size(); ++p) {
1550 auto& patch = m_amr_patches_pointer[p]->_internalApi()->positionRef();
1551 if (patch.level() != level) {
1555 if (patch.isIn(pos)) {
1558 else if (patch.isInWithOverlap(pos)) {
1561 if (in_patch && in_overlap) {
1565 if (in_patch && in_overlap) {
1566 icell->mutableItemBase().addFlags(ItemFlags::II_UserMark1);
1567 icell->mutableItemBase().addFlags(ItemFlags::II_UserMark2);
1569 else if (in_overlap) {
1570 icell->mutableItemBase().addFlags(ItemFlags::II_UserMark1);
1571 icell->mutableItemBase().removeFlags(ItemFlags::II_UserMark2);
1573 else if (in_patch) {
1574 icell->mutableItemBase().addFlags(ItemFlags::II_UserMark2);
1575 icell->mutableItemBase().removeFlags(ItemFlags::II_UserMark1);
1578 icell->mutableItemBase().removeFlags(ItemFlags::II_UserMark2);
1579 icell->mutableItemBase().removeFlags(ItemFlags::II_UserMark1);
1582 ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allCells()) {
1583 if (icell->hasFlags(ItemFlags::II_UserMark1)) {
1584 if (!icell->hasFlags(ItemFlags::II_Overlap)) {
1585 ARCANE_FATAL(
"_checkPatchesAndMesh -- II_UserMark1 but not II_Overlap -- CellUID : {0}", icell->uniqueId());
1588 if (icell->hasFlags(ItemFlags::II_UserMark2)) {
1589 if (!icell->hasFlags(ItemFlags::II_InPatch)) {
1590 ARCANE_FATAL(
"_checkPatchesAndMesh -- II_UserMark2 but not II_InPatch -- CellUID : {0}", icell->uniqueId());
1593 if (icell->hasFlags(ItemFlags::II_Overlap)) {
1594 if (!icell->hasFlags(ItemFlags::II_UserMark1)) {
1595 ARCANE_FATAL(
"_checkPatchesAndMesh -- II_Overlap but not II_UserMark1 -- CellUID : {0}", icell->uniqueId());
1598 if (icell->hasFlags(ItemFlags::II_InPatch)) {
1599 if (!icell->hasFlags(ItemFlags::II_UserMark2)) {
1600 ARCANE_FATAL(
"_checkPatchesAndMesh -- II_InPatch but not II_UserMark2 -- CellUID : {0}", icell->uniqueId());
1606 icell->mutableItemBase().removeFlags(ItemFlags::II_UserMark1);
1607 icell->mutableItemBase().removeFlags(ItemFlags::II_UserMark2);
1615void CartesianPatchGroup::
1616clearRefineRelatedFlags()
const
1618 constexpr ItemFlags::FlagType flags_to_remove = (ItemFlags::II_Coarsen | ItemFlags::II_Refine |
1619 ItemFlags::II_JustCoarsened | ItemFlags::II_JustRefined |
1620 ItemFlags::II_JustAdded | ItemFlags::II_CoarsenInactive);
1621 ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allCells()) {
1622 icell->mutableItemBase().removeFlags(flags_to_remove);
1629void CartesianPatchGroup::
1630rebuildAvailableGroupIndex(ConstArrayView<Integer> available_group_index)
1632 m_available_group_index = available_group_index;
1638ConstArrayView<Int32> CartesianPatchGroup::
1639availableGroupIndex()
1641 return m_available_group_index;
1647void CartesianPatchGroup::
1648setOverlapLayerSizeTopLevel(Int32 size_of_overlap_layer_top_level)
1650 auto numbering = m_cmesh->_internalApi()->cartesianMeshNumberingMngInternal();
1652 Int32 new_size_of_overlap_layer_top_level = 0;
1655 if (size_of_overlap_layer_top_level == -1)
1656 new_size_of_overlap_layer_top_level = -1;
1660 new_size_of_overlap_layer_top_level = size_of_overlap_layer_top_level + (size_of_overlap_layer_top_level % numbering->pattern());
1662 if (new_size_of_overlap_layer_top_level == m_size_of_overlap_layer_top_level) {
1668 for (Int32 level = 1; level <= m_higher_level; ++level) {
1669 Int32 old_overlap_size = AMRPatchPosition::computeOverlapLayerSize(level, m_higher_level, m_size_of_overlap_layer_top_level);
1670 Int32 new_overlap_size = AMRPatchPosition::computeOverlapLayerSize(level, m_higher_level, new_size_of_overlap_layer_top_level);
1672 if (old_overlap_size == new_overlap_size) {
1675 if (old_overlap_size < new_overlap_size) {
1676 _increaseOverlapSizeLevel(level, new_overlap_size);
1679 _reduceOverlapSizeLevel(level, new_overlap_size);
1682 m_size_of_overlap_layer_top_level = new_size_of_overlap_layer_top_level;
1688Int32 CartesianPatchGroup::
1689overlapLayerSize(Int32 level)
1698 Int32 higher_level = m_higher_level;
1699 if (m_target_nb_levels != 0) {
1700 higher_level = m_target_nb_levels - 1;
1702 return AMRPatchPosition::computeOverlapLayerSize(level, higher_level, m_size_of_overlap_layer_top_level);
1708void CartesianPatchGroup::
1709_addPatchInstance(Ref<CartesianMeshPatch> v)
1711 m_amr_patches.add(v);
1712 m_amr_patches_pointer.add(v.get());
1718void CartesianPatchGroup::
1719_removeOnePatch(Integer index)
1721 m_available_group_index.add(m_amr_patches[index]->index());
1724 m_amr_patch_cell_groups_all[index - 1].clear();
1725 m_amr_patch_cell_groups_all.remove(index - 1);
1727 if (m_cmesh->mesh()->meshKind().meshAMRKind() == eMeshAMRKind::PatchCartesianMeshOnly) {
1728 m_amr_patch_cell_groups_inpatch[index - 1].clear();
1729 m_amr_patch_cell_groups_inpatch.remove(index - 1);
1730 m_amr_patch_cell_groups_overlap[index - 1].clear();
1731 m_amr_patch_cell_groups_overlap.remove(index - 1);
1734 m_amr_patches_pointer.remove(index);
1735 m_amr_patches.remove(index);
1742void CartesianPatchGroup::
1743_removeMultiplePatches(ConstArrayView<Integer> indexes)
1746 for (
const Integer index : indexes) {
1747 _removeOnePatch(index - count);
1755void CartesianPatchGroup::
1758 Ref<CartesianMeshPatch> ground_patch = m_amr_patches.front();
1760 for (CellGroup cell_group : m_amr_patch_cell_groups_all) {
1763 m_amr_patch_cell_groups_all.clear();
1765 if (m_cmesh->mesh()->meshKind().meshAMRKind() == eMeshAMRKind::PatchCartesianMeshOnly) {
1766 for (CellGroup cell_group : m_amr_patch_cell_groups_inpatch) {
1769 for (CellGroup cell_group : m_amr_patch_cell_groups_overlap) {
1772 m_amr_patch_cell_groups_inpatch.clear();
1773 m_amr_patch_cell_groups_overlap.clear();
1776 m_amr_patches_pointer.clear();
1777 m_amr_patches.clear();
1778 m_available_group_index.clear();
1779 m_patches_to_delete.clear();
1780 m_index_new_patches = 1;
1782 m_amr_patches.add(ground_patch);
1783 m_amr_patches_pointer.add(ground_patch.get());
1790void CartesianPatchGroup::
1793 if (!m_amr_patches.empty())
1795 auto patch =
makeRef(
new CartesianMeshPatch(m_cmesh, -1));
1797 if (m_cmesh->mesh()->meshKind().meshAMRKind() == eMeshAMRKind::PatchCartesianMeshOnly) {
1798 auto numbering = m_cmesh->_internalApi()->cartesianMeshNumberingMngInternal();
1799 patch->_internalApi()->positionRef().setMinPoint({ 0, 0, 0 });
1800 patch->_internalApi()->positionRef().setMaxPoint({ numbering->globalNbCellsX(0), numbering->globalNbCellsY(0), numbering->globalNbCellsZ(0) });
1801 patch->_internalApi()->positionRef().setLevel(0);
1802 _updatePatchFlagsOfCellsGroundLevel();
1805 _addPatchInstance(patch);
1812_addCellGroup(CellGroup cell_group, CartesianMeshPatch* patch)
1814 m_amr_patch_cell_groups_all.add(cell_group);
1816 if (m_cmesh->mesh()->meshKind().meshAMRKind() != eMeshAMRKind::PatchCartesianMeshOnly) {
1820 return m_amr_patch_cell_groups_all.size() - 1;
1823 AMRPatchPosition patch_position = patch->position();
1824 Ref<ICartesianMeshNumberingMngInternal> numbering = m_cmesh->_internalApi()->cartesianMeshNumberingMngInternal();
1826 UniqueArray<Int32> inpatch_items_lid;
1827 UniqueArray<Int32> overlap_items_lid;
1831 const CartCoord3 pos = numbering->cellUniqueIdToCoord(cell);
1833 if (patch_position.isIn(pos)) {
1834 inpatch_items_lid.add(cell.localId());
1837 overlap_items_lid.add(cell.localId());
1842 m_amr_patch_cell_groups_inpatch.add(own);
1845 m_amr_patch_cell_groups_overlap.add(overlap);
1847 return m_amr_patch_cell_groups_all.
size() - 1;
1858void CartesianPatchGroup::
1859_removePartOfPatch(Integer index_patch_to_edit,
const AMRPatchPosition& part_to_remove)
1890 std::pair to_return{ -1, -1 };
1891 if (p1_min > p0_min && p1_min < p0_max) {
1892 to_return.first = p1_min;
1894 if (p1_max > p0_min && p1_max < p0_max) {
1895 to_return.second = p1_max;
1900 ICartesianMeshPatch* patch = m_amr_patches_pointer[index_patch_to_edit];
1901 AMRPatchPosition patch_position = patch->position();
1903 UniqueArray<AMRPatchPosition> new_patch_out;
1905 CartCoord3 min_point_of_patch_to_exclude(-1, -1, -1);
1909 UniqueArray<AMRPatchPosition> new_patch_in;
1913 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);
1917 if (cut_point_x.first == -1 && cut_point_x.second == -1) {
1918 min_point_of_patch_to_exclude.x = patch_position.minPoint().x;
1919 new_patch_out.add(patch_position);
1923 else if (cut_point_x.second == -1) {
1924 min_point_of_patch_to_exclude.x = cut_point_x.first;
1925 auto [fst, snd] = patch_position.cut(cut_point_x.first, MD_DirX);
1926 new_patch_out.add(fst);
1927 new_patch_out.add(snd);
1931 else if (cut_point_x.first == -1) {
1932 min_point_of_patch_to_exclude.x = patch_position.minPoint().x;
1933 auto [fst, snd] = patch_position.cut(cut_point_x.second, MD_DirX);
1934 new_patch_out.add(fst);
1935 new_patch_out.add(snd);
1940 min_point_of_patch_to_exclude.x = cut_point_x.first;
1941 auto [fst, snd_thr] = patch_position.cut(cut_point_x.first, MD_DirX);
1942 new_patch_out.add(fst);
1943 auto [snd, thr] = snd_thr.cut(cut_point_x.second, MD_DirX);
1944 new_patch_out.add(snd);
1945 new_patch_out.add(thr);
1951 std::swap(new_patch_out, new_patch_in);
1953 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);
1957 if (cut_point_y.first == -1 && cut_point_y.second == -1) {
1958 for (
const AMRPatchPosition& patch_x : new_patch_in) {
1959 min_point_of_patch_to_exclude.y = patch_x.minPoint().y;
1960 new_patch_out.add(patch_x);
1965 else if (cut_point_y.second == -1) {
1966 min_point_of_patch_to_exclude.y = cut_point_y.first;
1967 for (
const AMRPatchPosition& patch_x : new_patch_in) {
1968 auto [fst, snd] = patch_x.cut(cut_point_y.first, MD_DirY);
1969 new_patch_out.add(fst);
1970 new_patch_out.add(snd);
1975 else if (cut_point_y.first == -1) {
1976 for (
const AMRPatchPosition& patch_x : new_patch_in) {
1977 min_point_of_patch_to_exclude.y = patch_x.minPoint().y;
1978 auto [fst, snd] = patch_x.cut(cut_point_y.second, MD_DirY);
1979 new_patch_out.add(fst);
1980 new_patch_out.add(snd);
1986 min_point_of_patch_to_exclude.y = cut_point_y.first;
1987 for (
const AMRPatchPosition& patch_x : new_patch_in) {
1988 auto [fst, snd_thr] = patch_x.cut(cut_point_y.first, MD_DirY);
1989 new_patch_out.add(fst);
1990 auto [snd, thr] = snd_thr.cut(cut_point_y.second, MD_DirY);
1991 new_patch_out.add(snd);
1992 new_patch_out.add(thr);
1998 if (m_cmesh->mesh()->dimension() == 3) {
1999 std::swap(new_patch_out, new_patch_in);
2000 new_patch_out.clear();
2002 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);
2006 if (cut_point_z.first == -1 && cut_point_z.second == -1) {
2007 for (
const AMRPatchPosition& patch_y : new_patch_in) {
2008 min_point_of_patch_to_exclude.z = patch_y.minPoint().z;
2009 new_patch_out.add(patch_y);
2014 else if (cut_point_z.second == -1) {
2015 for (
const AMRPatchPosition& patch_y : new_patch_in) {
2016 min_point_of_patch_to_exclude.z = cut_point_z.first;
2017 auto [fst, snd] = patch_y.cut(cut_point_z.first, MD_DirZ);
2018 new_patch_out.add(fst);
2019 new_patch_out.add(snd);
2024 else if (cut_point_z.first == -1) {
2025 for (
const AMRPatchPosition& patch_y : new_patch_in) {
2026 min_point_of_patch_to_exclude.z = patch_y.minPoint().z;
2027 auto [fst, snd] = patch_y.cut(cut_point_z.second, MD_DirZ);
2028 new_patch_out.add(fst);
2029 new_patch_out.add(snd);
2035 for (
const AMRPatchPosition& patch_y : new_patch_in) {
2036 min_point_of_patch_to_exclude.z = cut_point_z.first;
2037 auto [fst, snd_thr] = patch_y.cut(cut_point_z.first, MD_DirZ);
2038 new_patch_out.add(fst);
2039 auto [snd, thr] = snd_thr.cut(cut_point_z.second, MD_DirZ);
2040 new_patch_out.add(snd);
2041 new_patch_out.add(thr);
2049 if (m_cmesh->mesh()->dimension() == 2) {
2050 min_point_of_patch_to_exclude.z = 0;
2056 for (AMRPatchPosition& new_patch : new_patch_out) {
2057 if (new_patch.minPoint() == min_point_of_patch_to_exclude) {
2058 new_patch.setLevel(-2);
2068 AMRPatchPositionLevelGroup::fusionPatches(new_patch_out,
false);
2072 for (
const auto& new_patch : new_patch_out) {
2073 if (!new_patch.isNull()) {
2078 _addCutPatch(new_patch, m_amr_patch_cell_groups_all[index_patch_to_edit - 1]);
2085 removePatch(index_patch_to_edit);
2091void CartesianPatchGroup::
2092_addCutPatch(
const AMRPatchPosition& new_patch_position, CellGroup parent_patch_cell_group)
2097 if (parent_patch_cell_group.null())
2100 IItemFamily* cell_family = m_cmesh->mesh()->cellFamily();
2101 Integer group_index = _nextIndexForNewPatch();
2102 String patch_group_name = String(
"CartesianMeshPatchCells") + group_index;
2104 auto* cdi =
new CartesianMeshPatch(m_cmesh, group_index, new_patch_position);
2105 _addPatchInstance(
makeRef(cdi));
2107 UniqueArray<Int32> cells_local_id;
2109 auto numbering = m_cmesh->_internalApi()->cartesianMeshNumberingMngInternal();
2110 ENUMERATE_ (Cell, icell, parent_patch_cell_group) {
2111 const CartCoord3 pos = numbering->cellUniqueIdToCoord(*icell);
2112 if (new_patch_position.isIn(pos)) {
2113 cells_local_id.add(icell.localId());
2117 CellGroup parent_cells = cell_family->createGroup(patch_group_name, cells_local_id,
true);
2118 _addCellGroup(parent_cells, cdi);
2131_addPatch(
const AMRPatchPosition& new_patch_position)
2133 UniqueArray<Int32> cells_local_id;
2135 auto numbering = m_cmesh->_internalApi()->cartesianMeshNumberingMngInternal();
2138 ENUMERATE_ (Cell, icell, m_cmesh->mesh()->allLevelCells(new_patch_position.level())) {
2146 const CartCoord3 pos = numbering->cellUniqueIdToCoord(*icell);
2148 if (new_patch_position.isIn(pos)) {
2149 icell->mutableItemBase().addFlags(ItemFlags::II_InPatch);
2150 cells_local_id.add(icell.localId());
2152 else if (new_patch_position.isInWithOverlap(pos)) {
2153 icell->mutableItemBase().addFlags(ItemFlags::II_Overlap);
2154 cells_local_id.add(icell.localId());
2158 IItemFamily* cell_family = m_cmesh->mesh()->cellFamily();
2159 Integer group_index = _nextIndexForNewPatch();
2160 String patch_group_name = String(
"CartesianMeshPatchCells") + group_index;
2162 auto* cdi =
new CartesianMeshPatch(m_cmesh, group_index, new_patch_position);
2164 _addPatchInstance(
makeRef(cdi));
2165 CellGroup parent_cells = cell_family->createGroup(patch_group_name, cells_local_id,
true);
2166 Integer array_index = _addCellGroup(parent_cells, cdi);
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
Interface d'un maillage cartésien.
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 IItemFamily * cellFamily()=0
Retourne la famille des mailles.
Integer size() const
Nombre d'éléments du groupe.
IMesh * mesh() const
Maillage auquel appartient ce groupe (0 pour le group nul)
Classe d'accès aux traces.
__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.
-*- 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.
Int32x3 CartCoord3
Représente les coordonnées 3D d'un élément dans la grille cartésienne {x, y, z}.