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::
 
   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())
 
   90  Integer nb_dir = mesh->dimension();
 
   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());
 
  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);
 
  221  mesh->modifier()->endUpdate();
 
  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;
 
  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) {
 
  255        CellLocalId sub_local_id = CellLocalId(sub_cell_lids[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());
 
  276    writer.
write(mesh->allCells());
 
 
  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.
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.
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.
Vue constante d'un tableau de type T.
Interface d'un maillage cartésien.
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.
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 endUpdate()=0
Notifie l'instance de la fin de la modification du maillage.
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é
@ II_UserMark1
Marque utilisateur.
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.
Int32 owner() const
Numéro du sous-domaine propriétaire de l'entité
ItemUniqueId uniqueId() const
Identifiant unique sur tous les domaines.
constexpr bool isOwn() const
true si l'entité est appartient au sous-domaine
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 removed_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.
Chaîne de caractères unicode.
const char * localstr() const
Retourne la conversion de l'instance dans l'encodage UTF-8.
Classe d'accès aux traces.
TraceMessage info() const
Flot pour un message d'information.
ITraceMng * traceMng() const
Gestionnaire de trace.
Vecteur 1D de données avec sémantique par valeur (style STL).
T max(const T &a, const T &b, const T &c)
Retourne le maximum de trois éléments.
@ ReduceMax
Maximum des valeurs.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
std::int64_t Int64
Type entier signé sur 64 bits.
Int32 Integer
Type représentant un entier.
std::int32_t Int32
Type entier signé sur 32 bits.