Skip to content

Commit 524392d

Browse files
committed
[arcane:cartesianmesh] Add methods to enable overlap cells layer
1 parent be2f9fe commit 524392d

File tree

5 files changed

+125
-21
lines changed

5 files changed

+125
-21
lines changed

arcane/ceapart/src/arcane/tests/AMRCartesianMeshTesterModule.cc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -513,6 +513,8 @@ void AMRCartesianMeshTesterModule::
513513
_initAMR()
514514
{
515515
CartesianMeshAMRMng amr_mng(m_cartesian_mesh);
516+
amr_mng.enableOverlapLayer(false);
517+
516518
// Regarde si on dé-raffine le maillage initial
517519
if (options()->coarseAtInit()){
518520
// Il faut que les directions aient été calculées avant d'appeler le dé-raffinement
@@ -842,7 +844,7 @@ _checkDirections()
842844
}
843845

844846
if (cell_hash != expected_hash)
845-
ARCANE_FATAL("Bad hash for uniqueId() for direction items of family '{0}' v= {1} expected='{2}'",
847+
ARCANE_FATAL("Bad hash for uniqueId() for direction items of family '{0}' v='{1}' expected='{2}'",
846848
item_family->fullName(), cell_hash, expected_hash);
847849
};
848850

arcane/src/arcane/cartesianmesh/CartesianMeshAMRMng.cc

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,13 +90,42 @@ coarseZone(const AMRZonePosition& position) const
9090
/*---------------------------------------------------------------------------*/
9191

9292
void CartesianMeshAMRMng::
93-
adaptMesh(bool clear_refine_flag) const
93+
adaptMesh() const
9494
{
95+
/*
96+
* Dans le cas d'un raffinement niveau par niveau, il est possible de mettre
97+
* le paramètre \a clear_refine_flag à false afin de garder les flags des
98+
* niveaux inférieurs et d'éviter d'avoir à les recalculer. Pour le dernier
99+
* niveau, il est recommandé de mettre le paramètre \a clear_refine_flag à
100+
* true pour supprimer les flags devenu inutiles (ou d'appeler la méthode
101+
* clearRefineRelatedFlags()).
102+
*
103+
* Les mailles n'ayant pas de flag "II_Refine" seront déraffinées.
104+
*
105+
* Afin d'éviter les mailles orphelines, si une maille est marquée
106+
* "II_Refine", alors la maille parente est marquée "II_Refine".
107+
*
108+
* Exemple d'exécution :
109+
* ```
110+
* CartesianMeshAMRMng amr_mng(cmesh());
111+
* amr_mng.clearRefineRelatedFlags();
112+
* for (Integer level = 0; level < 2; ++level){
113+
* computeInLevel(level); // Va mettre des flags II_Refine sur les mailles
114+
* amr_mng.adaptMesh(false);
115+
* }
116+
* amr_mng.clearRefineRelatedFlags();
117+
* ```
118+
*
119+
* Cette opération est collective.
120+
*
121+
* \param clear_refine_flag true si l'on souhaite supprimer les flags
122+
* II_Refine après adaptation.
123+
*/
95124
auto amr_type = m_cmesh->mesh()->meshKind().meshAMRKind();
96125
if (amr_type == eMeshAMRKind::Cell) {
97126
ARCANE_FATAL("Method available only with AMR PatchCartesianMeshOnly");
98127
}
99-
m_cmesh->_internalApi()->cartesianPatchGroup().refine(clear_refine_flag);
128+
m_cmesh->_internalApi()->cartesianPatchGroup().refine(true);
100129
}
101130

102131
/*---------------------------------------------------------------------------*/
@@ -111,6 +140,20 @@ clearRefineRelatedFlags() const
111140
/*---------------------------------------------------------------------------*/
112141
/*---------------------------------------------------------------------------*/
113142

143+
void CartesianMeshAMRMng::
144+
enableOverlapLayer(bool enable) const
145+
{
146+
auto amr_type = m_cmesh->mesh()->meshKind().meshAMRKind();
147+
if (amr_type == eMeshAMRKind::Cell) {
148+
return;
149+
}
150+
m_cmesh->_internalApi()->cartesianPatchGroup().setOverlapLayerSizeTopLevel(enable ? 2 : 0);
151+
m_cmesh->computeDirections();
152+
}
153+
154+
/*---------------------------------------------------------------------------*/
155+
/*---------------------------------------------------------------------------*/
156+
114157
Integer CartesianMeshAMRMng::
115158
reduceNbGhostLayers(Integer level, Integer target_nb_ghost_layers) const
116159
{

arcane/src/arcane/cartesianmesh/CartesianMeshAMRMng.h

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,8 @@ class ARCANE_CARTESIANMESH_EXPORT CartesianMeshAMRMng
105105
* \brief Méthode permettant d'adapter le raffinement du maillage selon les
106106
* mailles à raffiner.
107107
*
108+
* \warning Méthode expérimentale.
109+
*
108110
* Cette méthode ne peut être appelée que si le maillage est un maillage
109111
* AMR (IMesh::isAmrActivated()==true) et que le type de l'AMR est 3
110112
* (PatchCartesianMeshOnly).
@@ -115,13 +117,7 @@ class ARCANE_CARTESIANMESH_EXPORT CartesianMeshAMRMng
115117
* déjà).
116118
* Pour être sûr de n'avoir aucun flag déjà présent sur le maillage, il est
117119
* possible d'appeler la méthode \a clearRefineRelatedFlags().
118-
* Dans le cas d'un raffinement niveau par niveau, il est possible de mettre
119-
* le paramètre \a clear_refine_flag à false afin de garder les flags des
120-
* niveaux inférieurs et d'éviter d'avoir à les recalculer. Pour le dernier
121-
* niveau, il est recommandé de mettre le paramètre \a clear_refine_flag à
122-
* true pour supprimer les flags devenu inutiles (ou d'appeler la méthode
123-
* clearRefineRelatedFlags()).
124-
*
120+
125121
* Les mailles n'ayant pas de flag "II_Refine" seront déraffinées.
126122
*
127123
* Afin d'éviter les mailles orphelines, si une maille est marquée
@@ -132,18 +128,16 @@ class ARCANE_CARTESIANMESH_EXPORT CartesianMeshAMRMng
132128
* CartesianMeshAMRMng amr_mng(cmesh());
133129
* amr_mng.clearRefineRelatedFlags();
134130
* for (Integer level = 0; level < 2; ++level){
135-
* computeInLevel(level); // Va mettre des flags II_Refine sur les mailles
136-
* amr_mng.adaptMesh(false);
131+
* // Va faire ses calculs et mettre des flags II_Refine sur les mailles
132+
* // du niveau 0 jusqu'au niveau level.
133+
* computeInLevel(0, level);
134+
* amr_mng.adaptMesh();
137135
* }
138-
* amr_mng.clearRefineRelatedFlags();
139136
* ```
140137
*
141138
* Cette opération est collective.
142-
*
143-
* \param clear_refine_flag true si l'on souhaite supprimer les flags
144-
* II_Refine après adaptation.
145139
*/
146-
void adaptMesh(bool clear_refine_flag) const;
140+
void adaptMesh() const;
147141

148142
/*!
149143
* \brief Méthode permettant de supprimer les flags liés au raffinement de
@@ -159,7 +153,9 @@ class ARCANE_CARTESIANMESH_EXPORT CartesianMeshAMRMng
159153
*/
160154
void clearRefineRelatedFlags() const;
161155

162-
/*!
156+
void enableOverlapLayer(bool enable) const;
157+
158+
/*!
163159
* \brief Méthode permettant de supprimer une ou plusieurs couches
164160
* de mailles fantômes sur un niveau de raffinement défini.
165161
*

arcane/src/arcane/cartesianmesh/internal/CartesianPatchGroup.cc

Lines changed: 61 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ CartesianPatchGroup::
5050
CartesianPatchGroup(ICartesianMesh* cmesh)
5151
: m_cmesh(cmesh)
5252
, m_index_new_patches(1)
53+
, m_size_of_overlap_layer_sub_top_level(0)
54+
, m_higher_level(0)
5355
{}
5456

5557
/*---------------------------------------------------------------------------*/
@@ -171,6 +173,9 @@ addPatch(CellGroup cell_group, Integer group_index)
171173
position.setMinPoint({ min[MD_DirX], min[MD_DirY], min[MD_DirZ] });
172174
position.setMaxPoint({ max[MD_DirX], max[MD_DirY], max[MD_DirZ] });
173175
position.setLevel(level_r);
176+
177+
if (level_r > m_higher_level)
178+
m_higher_level = level_r;
174179
}
175180

176181
auto* cdi = new CartesianMeshPatch(m_cmesh, group_index, position);
@@ -364,6 +369,14 @@ applyPatchEdit(bool remove_empty_patches)
364369
_removeMultiplePatches(m_patches_to_delete);
365370
m_patches_to_delete.clear();
366371
}
372+
373+
m_higher_level = 0;
374+
for (const auto patch : m_amr_patches_pointer) {
375+
const Integer level = patch->_internalApi()->positionRef().level();
376+
if (level > m_higher_level) {
377+
m_higher_level = level;
378+
}
379+
}
367380
}
368381

369382
/*---------------------------------------------------------------------------*/
@@ -399,6 +412,9 @@ updateLevelsBeforeAddGroundPatch()
399412
// Sinon, on "surélève" le niveau des patchs vu qu'il va y avoir le patch "-1"
400413
else {
401414
patch->_internalApi()->positionRef().setLevel(level + 1);
415+
if (level + 1 > m_higher_level) {
416+
m_higher_level = level + 1;
417+
}
402418
}
403419
}
404420
}
@@ -504,11 +520,17 @@ mergePatches()
504520
void CartesianPatchGroup::
505521
refine(bool clear_refine_flag)
506522
{
523+
// TODO : Le paramètre clear_refine_flag doit être à true pour l'instant.
524+
// À cause des mailles de recouvrements, on doit regénérer les patchs
525+
// de tous les niveaux à chaque fois. Pour que ça fonctionne, il
526+
// faudrait demander le nombre de niveaux qui sera généré en tout,
527+
// pour cette itération, pour calculer en avance la taille de la
528+
// couche de recouvrement de chaque niveau.
507529
if (m_cmesh->mesh()->meshKind().meshAMRKind() != eMeshAMRKind::PatchCartesianMeshOnly) {
508530
ARCANE_FATAL("Method available only with AMR PatchCartesianMeshOnly");
509531
}
510532
Integer dimension = m_cmesh->mesh()->dimension();
511-
Integer nb_overlap_cells = 1;
533+
Integer nb_overlap_cells = m_size_of_overlap_layer_sub_top_level;
512534
Integer min_level = 0;
513535
Integer future_max_level = -1; // Désigne le niveau max qui aura des enfants, donc le futur level max +1.
514536
Integer old_max_level = -1; // Mais s'il reste des mailles à des niveaux plus haut, il faut les retirer.
@@ -558,7 +580,7 @@ refine(bool clear_refine_flag)
558580
AMRPatchPosition all_level;
559581
all_level.setLevel(level);
560582
all_level.setMinPoint({ 0, 0, 0 });
561-
all_level.setMaxPoint({ static_cast<Integer>(numbering->globalNbCellsX(level)), static_cast<Integer>(numbering->globalNbCellsY(level)), static_cast<Integer>(numbering->globalNbCellsZ(level)) });
583+
all_level.setMaxPoint({ numbering->globalNbCellsX(level), numbering->globalNbCellsY(level), numbering->globalNbCellsZ(level) });
562584
all_level.setOverlapLayerSize(nb_overlap_cells);
563585

564586
AMRPatchPositionSignature sig(all_level, m_cmesh, &all_patches);
@@ -843,6 +865,35 @@ availableGroupIndex()
843865
/*---------------------------------------------------------------------------*/
844866
/*---------------------------------------------------------------------------*/
845867

868+
void CartesianPatchGroup::
869+
setOverlapLayerSizeTopLevel(Integer size_of_overlap_layer_top_level)
870+
{
871+
m_size_of_overlap_layer_sub_top_level = (size_of_overlap_layer_top_level + 1) / 2;
872+
}
873+
874+
/*---------------------------------------------------------------------------*/
875+
/*---------------------------------------------------------------------------*/
876+
877+
Integer CartesianPatchGroup::
878+
overlapLayerSize(Integer level)
879+
{
880+
if (level < 0 || level > m_higher_level) {
881+
ARCANE_FATAL("Level doesn't exist");
882+
}
883+
if (level == m_higher_level) {
884+
return m_size_of_overlap_layer_sub_top_level * 2;
885+
}
886+
Integer nb_overlap_cells = m_size_of_overlap_layer_sub_top_level;
887+
for (Integer i = m_higher_level - 1; i > level; --i) {
888+
nb_overlap_cells /= 2;
889+
nb_overlap_cells += 1;
890+
}
891+
return nb_overlap_cells;
892+
}
893+
894+
/*---------------------------------------------------------------------------*/
895+
/*---------------------------------------------------------------------------*/
896+
846897
void CartesianPatchGroup::
847898
_addPatchInstance(Ref<CartesianMeshPatch> v)
848899
{
@@ -1233,6 +1284,9 @@ _splitPatch(Integer index_patch, const AMRPatchPosition& part_to_remove)
12331284
void CartesianPatchGroup::
12341285
_addCutPatch(const AMRPatchPosition& new_patch_position, CellGroup parent_patch_cell_group)
12351286
{
1287+
// Si cette méthode est utilisé par une autre méthode que _splitPatch(),
1288+
// voir si la mise à jour de m_higher_level est nécessaire.
1289+
// (jusque-là, ce n'est pas utile vu qu'il y aura appel à applyPatchEdit()).
12361290
if (parent_patch_cell_group.null())
12371291
ARCANE_FATAL("Null cell group");
12381292

@@ -1250,7 +1304,7 @@ _addCutPatch(const AMRPatchPosition& new_patch_position, CellGroup parent_patch_
12501304
Int64 pos_x = numbering->cellUniqueIdToCoordX(*icell);
12511305
Int64 pos_y = numbering->cellUniqueIdToCoordY(*icell);
12521306
Int64 pos_z = numbering->cellUniqueIdToCoordZ(*icell);
1253-
if (new_patch_position.isIn(pos_x, pos_y, pos_z)) { // TODO : Ajouter overlap dans .arc
1307+
if (new_patch_position.isIn(pos_x, pos_y, pos_z)) {
12541308
cells_local_id.add(icell.localId());
12551309
}
12561310
}
@@ -1293,6 +1347,10 @@ _addPatch(const AMRPatchPosition& new_patch_position)
12931347
CellGroup parent_cells = cell_family->createGroup(patch_group_name, cells_local_id, true);
12941348
_addCellGroup(parent_cells, cdi);
12951349

1350+
if (new_patch_position.level() > m_higher_level) {
1351+
m_higher_level = new_patch_position.level();
1352+
}
1353+
12961354
// m_cmesh->traceMng()->info() << "_addPatch()"
12971355
// << " -- m_amr_patch_cell_groups : " << m_amr_patch_cell_groups_all.size()
12981356
// << " -- m_amr_patches : " << m_amr_patches.size()

arcane/src/arcane/cartesianmesh/internal/CartesianPatchGroup.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,9 @@ class ARCANE_CARTESIANMESH_EXPORT CartesianPatchGroup
7979

8080
ConstArrayView<Int32> availableGroupIndex();
8181

82+
void setOverlapLayerSizeTopLevel(Integer size_of_overlap_layer_top_level);
83+
Integer overlapLayerSize(Integer level);
84+
8285
private:
8386

8487
Integer _nextIndexForNewPatch();
@@ -108,6 +111,8 @@ class ARCANE_CARTESIANMESH_EXPORT CartesianPatchGroup
108111
UniqueArray<Integer> m_patches_to_delete;
109112
Int32 m_index_new_patches;
110113
UniqueArray<Integer> m_available_group_index;
114+
Integer m_size_of_overlap_layer_sub_top_level;
115+
Integer m_higher_level;
111116
};
112117

113118
/*---------------------------------------------------------------------------*/

0 commit comments

Comments
 (0)