14#include "arcane/cartesianmesh/CartesianMeshCoarsening.h"
16#include "arcane/utils/FatalErrorException.h"
17#include "arcane/utils/ValueConvert.h"
19#include "arcane/core/IMesh.h"
20#include "arcane/core/ItemGroup.h"
21#include "arcane/core/IParallelMng.h"
22#include "arcane/core/CartesianGridDimension.h"
23#include "arcane/core/IMeshModifier.h"
24#include "arcane/core/SimpleSVGMeshExporter.h"
25#include "arcane/core/ItemPrinter.h"
26#include "arcane/core/MeshStats.h"
28#include "arcane/cartesianmesh/ICartesianMesh.h"
29#include "arcane/cartesianmesh/CellDirectionMng.h"
31#include <unordered_set>
42CartesianMeshCoarsening::
43CartesianMeshCoarsening(ICartesianMesh* m)
44: TraceAccessor(m->traceMng())
47 if (
auto v = Convert::Type<Int32>::tryParseFromEnvironment(
"ARCANE_CARTESIANMESH_COARSENING_VERBOSITY_LEVEL",
true))
48 m_verbosity_level = v.value();
55Int64 CartesianMeshCoarsening::
56_getMaxUniqueId(
const ItemGroup& group)
61 if (max_offset < item.uniqueId())
62 max_offset = item.uniqueId();
70void CartesianMeshCoarsening::
73 if (m_is_create_coarse_called)
75 m_is_create_coarse_called =
true;
77 const bool is_verbose = m_verbosity_level > 0;
78 IMesh* mesh = m_cartesian_mesh->mesh();
79 Integer nb_patch = m_cartesian_mesh->nbPatch();
81 ARCANE_FATAL(
"This method is only valid for 1 patch (nb_patch={0})", nb_patch);
83 if (!mesh->isAmrActivated())
95 const Int32 my_rank = pm->
commRank();
96 info() <<
"CoarseCartesianMesh nb_direction=" << nb_dir;
98 for (Integer idir = 0; idir < nb_dir; ++idir) {
101 info() <<
"NB_OWN_CELL dir=" << idir <<
" n=" << nb_own_cell;
102 if ((nb_own_cell % 2) != 0)
103 ARCANE_FATAL(
"Invalid number of cells ({0}) for direction {1}. Should be a multiple of 2",
111 Int64 max_cell_uid = _getMaxUniqueId(mesh->
allCells());
112 Int64 max_face_uid = _getMaxUniqueId(mesh->
allFaces());
113 const Int64 coarse_grid_cell_offset = 1 + pm->
reduce(Parallel::ReduceMax, math::max(max_cell_uid, max_face_uid));
114 m_first_own_cell_unique_id_offset = coarse_grid_cell_offset;
123 CartesianGridDimension::CellUniqueIdComputer2D refined_cell_uid_computer(refined_grid_dim.getCellComputer2D(0));
124 CartesianGridDimension::NodeUniqueIdComputer2D refined_node_uid_computer(refined_grid_dim.getNodeComputer2D(0));
125 CartesianGridDimension::CellUniqueIdComputer2D coarse_cell_uid_computer(coarse_grid_dim.getCellComputer2D(coarse_grid_cell_offset));
126 CartesianGridDimension::FaceUniqueIdComputer2D coarse_face_uid_computer(coarse_grid_dim.getFaceComputer2D(coarse_grid_cell_offset));
136 Int32 nb_coarse_face = 0;
137 Int32 nb_coarse_cell = 0;
143 Int64x3 cell_xy = refined_cell_uid_computer.compute(cell_uid);
144 const Int64 cell_x = cell_xy.x;
145 const Int64 cell_y = cell_xy.y;
148 if ((cell_x % 2) != 0 || (cell_y % 2) != 0)
151 info() <<
"CELLCoarse uid=" << cell_uid <<
" x=" << cell_x <<
" y=" << cell_y;
152 const Int64 coarse_cell_x = cell_x / 2;
153 const Int64 coarse_cell_y = cell_y / 2;
154 std::array<Int64, 4> node_uids_container;
156 node_uids[0] = refined_node_uid_computer.compute(cell_x + 0, cell_y + 0);
157 node_uids[1] = refined_node_uid_computer.compute(cell_x + 2, cell_y + 0);
158 node_uids[2] = refined_node_uid_computer.compute(cell_x + 2, cell_y + 2);
159 node_uids[3] = refined_node_uid_computer.compute(cell_x + 0, cell_y + 2);
161 info() <<
"CELLNodes uid=" << node_uids;
162 std::array<Int64, 4> coarse_face_uids = coarse_face_uid_computer.computeForCell(coarse_cell_x, coarse_cell_y);
165 for (Int32 z = 0; z < 4; ++z) {
167 faces_infos.
add(IT_Line2);
168 faces_infos.
add(coarse_face_uids[z]);
169 faces_infos.
add(node_uids[lface.
node(0)]);
170 faces_infos.
add(node_uids[lface.
node(1)]);
175 cells_infos.
add(IT_Quad4);
176 cells_infos.
add(coarse_cell_uid_computer.compute(coarse_cell_x, coarse_cell_y));
177 for (Int32 z = 0; z < 4; ++z)
178 cells_infos.
add(node_uids[z]);
186 cells_local_ids.
resize(nb_coarse_cell);
187 faces_local_ids.
resize(nb_coarse_face);
226 m_coarse_cells.resize(nb_coarse_cell);
227 m_refined_cells.resize(nb_coarse_cell, 4);
233 Int32 coarse_index = 0;
234 std::array<Int32, 4> sub_cell_lids_container;
238 Cell coarse_cell = *icell;
239 if (!(coarse_cell.
itemBase().
flags() & ItemFlags::II_UserMark1))
243 m_coarse_cells[coarse_index] = coarse_cell.
itemLocalId();
244 Cell first_child_cell = cells[first_child_cell_local_ids[coarse_index]];
247 sub_cell_lids[0] = first_child_cell.
localId();
248 sub_cell_lids[1] = cdm_x[first_child_cell].next().localId();
249 sub_cell_lids[2] = cdm_y[
CellLocalId(sub_cell_lids[1])].next().localId();
250 sub_cell_lids[3] = cdm_y[first_child_cell].next().localId();
252 info() <<
"AddChildForCoarseCell i=" << coarse_index <<
" coarse=" <<
ItemPrinter(coarse_cell)
253 <<
" children_lid=" << sub_cell_lids;
254 for (Int32 z = 0; z < 4; ++z) {
256 m_refined_cells[coarse_index][z] = sub_local_id;
258 info() <<
" AddParentCellToCell: z=" << z <<
" child=" <<
ItemPrinter(cells[sub_local_id]);
271 const bool dump_coarse_mesh =
false;
272 if (dump_coarse_mesh) {
273 String filename = String::format(
"mesh_coarse_{0}.svg", my_rank);
274 std::ofstream ofile(filename.
localstr());
283void CartesianMeshCoarsening::
286 if (!m_is_create_coarse_called)
287 ARCANE_FATAL(
"You need to call createCoarseCells() before");
288 if (m_is_remove_refined_called)
290 m_is_remove_refined_called =
true;
292 IMesh* mesh = m_cartesian_mesh->mesh();
297 std::unordered_set<Int32> coarse_cells_set;
298 for (Int32 cell_lid : m_coarse_cells)
299 coarse_cells_set.insert(cell_lid);
303 Int32 local_id = icell.itemLocalId();
305 if (!cell.
isOwn() || (coarse_cells_set.find(local_id) != coarse_cells_set.end()))
306 cells_to_remove.
add(local_id);
322 _recomputeMeshGenerationInfo();
325 m_cartesian_mesh->computeDirections();
333void CartesianMeshCoarsening::
334_recomputeMeshGenerationInfo()
336 IMesh* mesh = m_cartesian_mesh->mesh();
337 auto* cmgi = ICartesianMeshGenerationInfo::getReference(mesh,
false);
346 cmgi->setOwnCellOffsets(v[0] / cf, v[1] / cf, v[2] / cf);
349 ConstArrayView<Int64> v = cmgi->globalNbCells();
350 cmgi->setGlobalNbCells(v[0] / cf, v[1] / cf, v[2] / cf);
353 ConstArrayView<Int32> v = cmgi->ownNbCells();
354 cmgi->setOwnNbCells(v[0] / cf, v[1] / cf, v[2] / cf);
356 cmgi->setFirstOwnCellUniqueId(m_first_own_cell_unique_id_offset);
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
Informations sur les dimensions d'une grille cartésienne.
Infos sur les mailles d'une direction spécifique X,Y ou Z d'un maillage structuré.
Int64 globalNbCell() const
Nombre global de mailles dans cette direction.
Int32 ownNbCell() const
Nombre de mailles propres dans cette direction.
Vue sur les informations des mailles.
CellLocalId itemLocalId() const
Identifiant local de l'entité dans le sous-domaine du processeur.
Interface d'une famille d'entités.
virtual void notifyItemsOwnerChanged()=0
Notifie que les entités propres au sous-domaine de la famille ont été modifiées.
virtual ItemVectorView view(Int32ConstArrayView local_ids)=0
Vue sur les entités.
virtual void itemsUniqueIdToLocalId(Int32ArrayView local_ids, Int64ConstArrayView unique_ids, bool do_fatal=true) const =0
Converti un tableau de numéros uniques en numéros locaux.
virtual CellGroup ownCells()=0
Groupe de toutes les mailles propres au domaine.
virtual FaceGroup allFaces()=0
Groupe de toutes les faces.
virtual Integer dimension()=0
Dimension du maillage (1D, 2D ou 3D).
virtual IItemFamily * faceFamily()=0
Retourne la famille des faces.
virtual CellGroup allCells()=0
Groupe de toutes les mailles.
virtual IItemFamily * cellFamily()=0
Retourne la famille des mailles.
Interface de modification du maillage.
virtual void updateGhostLayers()=0
Mise à jour de la couche fantôme.
virtual void setDynamic(bool v)=0
Positionne la propriété indiquant si le maillage peut évoluer.
virtual void removeCells(Int32ConstArrayView cells_local_id)=0
Supprime des mailles.
virtual void addFaces(Integer nb_face, Int64ConstArrayView face_infos, Int32ArrayView face_lids=Int32ArrayView())=0
Ajoute des faces.
virtual void addCells(Integer nb_cell, Int64ConstArrayView cell_infos, Int32ArrayView cells_lid=Int32ArrayView())=0
Ajoute des mailles.
virtual void endUpdate()=0
Notifie l'instance de la fin de la modification du maillage.
virtual IParallelMng * parallelMng()=0
Gestionnaire de parallèlisme.
virtual IMeshModifier * modifier()=0
Interface de modification associée.
Interface du gestionnaire de parallélisme pour un sous-domaine.
virtual Int32 commRank() const =0
Rang de cette instance dans le communicateur.
virtual char reduce(eReduceType rt, char v)=0
Effectue la réduction de type rt sur le réel v et retourne la valeur.
Int32 flags() const
Flags de l'entité
Classe utilitaire pour imprimer les infos sur une entité.
Informations locales sur une face d'une maille.
Integer node(Integer i) const
Indice locale dans la maille du i-ème noeud de la face.
Infos sur un type d'entité du maillage.
LocalFace localFace(Integer id) const
Connectivité locale de la i-ème face de la maille.
Node node(Int32 i) const
i-ème noeud de l'entité
const ItemTypeInfo * typeInfo() const
Infos sur le type de l'entité.
impl::MutableItemBase mutableItemBase() const
Partie interne modifiable de l'entité.
constexpr Int32 localId() const
Identifiant local de l'entité dans le sous-domaine du processeur.
bool isOwn() const
true si l'entité est appartient au sous-domaine
Int32 owner() const
Numéro du sous-domaine propriétaire de l'entité
ItemUniqueId uniqueId() const
Identifiant unique sur tous les domaines.
impl::ItemBase itemBase() const
Partie interne de l'entité.
Arguments pour IMeshModifier::addCells().
Arguments pour IMeshModifier::addFaces().
void dumpStats() override
Imprime des infos sur le maillage.
void setOwner(Integer suid, Int32 current_sub_domain)
Positionne le numéro du sous-domaine propriétaire de l'entité.
void addFlags(Int32 added_flags)
Ajoute les flags \added_flags à ceux de l'entité
void removeFlags(Int32 removed_flags)
Supprime les flags \added_flags de ceux de l'entité
Exportation d'un maillage au format SVG.
void write(const CellGroup &cells)
Exporte les entités du groupe cells.
Vue modifiable d'un tableau d'un type T.
void resize(Int64 s)
Change le nombre d'éléments du tableau à s.
void add(ConstReferenceType val)
Ajoute l'élément val à la fin du tableau.
Vue constante d'un tableau de type T.
Chaîne de caractères unicode.
const char * localstr() const
Retourne la conversion de l'instance dans l'encodage UTF-8.
Vecteur 1D de données avec sémantique par valeur (style STL).
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-