15#include "arcane/utils/ApplicationInfo.h"
16#include "arcane/utils/CommandLineArguments.h"
17#include "arcane/utils/List.h"
18#include "arcane/utils/MDDim.h"
20#include "arcane/core/IMeshSubdivider.h"
21#include "arcane/impl/ArcaneBasicMeshSubdividerService_axl.h"
23#include "arcane/core/ItemGroup.h"
24#include "arcane/core/ItemPrinter.h"
25#include "arcane/core/IItemFamily.h"
26#include "arcane/core/IGhostLayerMng.h"
28#include "arcane/core/IMeshModifier.h"
30#include "arcane/core/SimpleSVGMeshExporter.h"
33#include "arcane/core/ServiceBuilder.h"
34#include "arcane/core/Directory.h"
35#include "arcane/core/IVariableMng.h"
36#include "arcane/core/IParallelMng.h"
37#include "arcane/core/BasicService.h"
38#include "arcane/core/IPrimaryMesh.h"
39#include "arcane/core/Item.h"
41#include "arcane/core/PostProcessorWriterBase.h"
43#include "arcane/core/VariableBuildInfo.h"
44#include "arcane/core/IMeshUtilities.h"
45#include "arcane/core/ISubDomain.h"
46#include "arcane/cartesianmesh/ICartesianMesh.h"
47#include "arcane/core/Properties.h"
48#include "arcane/std/IMeshGenerator.h"
51#include <unordered_set>
62typedef UniqueArray<UniqueArray<Int64>> StorageRefine;
63namespace MeshSubdivider
111 this->child_faces = child_faces;
121 , child_faces(other.child_faces)
124 Pattern(
const Pattern&) =
delete;
126 Pattern(Pattern& other) noexcept
133 , child_faces(other.child_faces)
135 Pattern& operator=(
const Pattern& other)
137 if (
this != &other) {
144 child_faces = other.child_faces;
149 Pattern& operator=(Pattern&& other)
noexcept
151 if (
this != &other) {
158 child_faces = other.child_faces;
162 Pattern& operator=(Pattern& other)
noexcept
164 if (
this != &other) {
171 child_faces = other.child_faces;
253 StorageRefine faces({
267 StorageRefine cells({
273 StorageRefine child_faces({
280 return { IT_Quad4, IT_Line2, IT_Quad4, nodes, faces, cells, child_faces };
301MeshSubdivider::Pattern PatternBuilder::quadtotri()
303 StorageRefine nodes({});
304 StorageRefine faces({
311 StorageRefine cells({ { 0, 3, 2 }, { 2, 1, 0 } });
312 StorageRefine child_faces({});
313 return { IT_Quad4, IT_Line2, IT_Triangle3, nodes, faces, cells, child_faces };
338MeshSubdivider::Pattern PatternBuilder::tritotri()
340 StorageRefine nodes({
345 StorageRefine faces({
356 StorageRefine cells({ { 3, 0, 5 },
360 StorageRefine child_faces(
364 return { IT_Triangle3, IT_Line2, IT_Triangle3, nodes, faces, cells, child_faces };
367MeshSubdivider::Pattern PatternBuilder::tritoquad()
369 StorageRefine nodes({
375 StorageRefine faces({
378 StorageRefine cells({
383 StorageRefine child_faces({});
384 return { IT_Triangle3, IT_Line2, IT_Quad4, nodes, faces, cells, child_faces };
388MeshSubdivider::Pattern PatternBuilder::hextohex()
390 StorageRefine nodes = {
409 { 0, 1, 5, 4, 3, 2, 7, 6 }
411 StorageRefine faces = {
452 StorageRefine child_faces = {
460 StorageRefine cells = {
461 { 0, 8, 20, 9, 10, 21, 26, 22 },
462 { 10, 21, 26, 22, 4, 16, 25, 17 },
463 { 8, 1, 11, 20, 21, 12, 23, 26 },
464 { 21, 12, 23, 26, 16, 5, 18, 25 },
465 { 9, 20, 13, 3, 22, 26, 24, 15 },
466 { 22, 26, 24, 15, 17, 25, 19, 7 },
467 { 20, 11, 2, 13, 26, 23, 14, 24 },
468 { 26, 23, 14, 24, 25, 18, 6, 19 }
470 return { IT_Hexaedron8, IT_Quad4, IT_Hexaedron8, nodes, faces, cells, child_faces };
473MeshSubdivider::Pattern PatternBuilder::tettotet()
475 StorageRefine nodes = {
484 StorageRefine faces = {
510 StorageRefine child_faces = {
516 StorageRefine cells = {
526 return { IT_Tetraedron4, IT_Triangle3, IT_Tetraedron4, nodes, faces, cells, child_faces };
530MeshSubdivider::Pattern PatternBuilder::hextotet()
532 StorageRefine nodes = {};
533 StorageRefine faces = {
553 StorageRefine child_faces = {
561 StorageRefine cells = {
568 return { IT_Hexaedron8, IT_Triangle3, IT_Tetraedron4, nodes, faces, cells, child_faces };
571MeshSubdivider::Pattern PatternBuilder::tettohex()
573 StorageRefine nodes = {
586 StorageRefine faces = {
606 StorageRefine child_faces = {
616 StorageRefine cells = {
629 { 7, 10, 14, 13, 0, 4, 12, 6 },
630 { 8, 11, 5, 2, 13, 14, 12, 6 },
631 { 3, 9, 11, 8, 7, 10, 14, 13 },
632 { 9, 1, 5, 11, 10, 4, 12, 14 }
634 return { IT_Tetraedron4, IT_Quad4, IT_Hexaedron8, nodes, faces, cells, child_faces };
637MeshSubdivider::Pattern PatternBuilder::hextotet24()
639 StorageRefine nodes({
646 { 0, 1, 2, 3, 4, 5, 6, 7 },
648 StorageRefine faces({
711 StorageRefine cells({
743 StorageRefine child_faces({
753 return { IT_Hexaedron8, IT_Triangle3, IT_Tetraedron4, nodes, faces, cells, child_faces };
829 std::unordered_map<Arccore::Int16, MeshSubdivider::Pattern>
pattern_manager;
835 std::string prefix(
"subdivider_pattern2D_");
836 mesh->
utilities()->writeToFile(prefix +
"tritotri.vtk",
"VtkLegacyMeshWriter");
842 mesh->
utilities()->writeToFile(prefix +
"tritoquad.vtk",
"VtkLegacyMeshWriter");
848 mesh->
utilities()->writeToFile(prefix +
"quadtoquad.vtk",
"VtkLegacyMeshWriter");
854 mesh->
utilities()->writeToFile(prefix +
"quadtotri.vtk",
"VtkLegacyMeshWriter");
859 std::unordered_map<Arccore::Int16, MeshSubdivider::Pattern>
pattern_manager;
860 std::string prefix(
"subdivider_pattern3D_");
865 mesh->
utilities()->writeToFile(prefix +
"tettotet.vtk",
"VtkLegacyMeshWriter");
871 mesh->
utilities()->writeToFile(prefix +
"tettohex.vtk",
"VtkLegacyMeshWriter");
877 mesh->
utilities()->writeToFile(prefix +
"hextohex.vtk",
"VtkLegacyMeshWriter");
883 mesh->
utilities()->writeToFile(prefix +
"hextotet24.vtk",
"VtkLegacyMeshWriter");
889 mesh->
utilities()->writeToFile(prefix +
"subdivider_hextotet.vtk",
"VtkLegacyMeshWriter");
938 info() <<
"#subdivide mesh";
949 info() <<
"subdivide mesh with " <<
options()->nbSubdivision() <<
" nb_refine";
954 debug() <<
"PART 3D nb ghostlayer" <<
gm->nbGhostLayer();
957 Int32 version =
gm->builderVersion();
959 gm->setBuilderVersion(3);
961 gm->setNbGhostLayer(0);
1010 ARCANE_ASSERT((mesh->
nbEdge() == 0), (
"Wrong number of edge"));
1037 debug() <<
"Refining element";
1081 debug() <<
"Noeuds initiaux";
1083 for (Int32 i = 0; i < cell.
nbNode(); i++) {
1091 debug() <<
"Génération des uid noeuds";
1099 std::sort(
tmp.begin(),
tmp.end());
1100 Int64 uid = MeshUtils::generateHashUniqueId(
tmp.constView());
1111 ARCANE_FATAL(
"Wrong size for refined pattern with code IT:'{0}'",
p.cell_type);
1115 ARCANE_FATAL(
"Bad coordinate for new node, the node '{0}' probably has a default coordinate (0.0,0.0,0.0).", uid);
1144 debug() <<
"Refine face";
1145 for (Integer i = 0; i <
face_refine.size(); i++) {
1152 std::sort(
tmp.begin(),
tmp.end());
1154 Int64 uid = Arcane::MeshUtils::generateHashUniqueId(
tmp.constView());
1178 debug() <<
"Gestion face groupe";
1179 for (Integer i = 0; i < child_faces.
size(); i++) {
1181 for (Integer
j = 0;
j < child_faces[i].
size();
j++) {
1189 debug() <<
"Génération des cellules enfants";
1197 std::sort(
tmp.begin(),
tmp.end());
1198 Int64 cell_uid = Arcane::MeshUtils::generateHashUniqueId(
tmp.constView());
1245 info() <<
"After addCells";
1287 info() <<
"#groups: OWN";
1291 info() <<
"#groups: ALLITEMS";
1294 info() <<
"#groups: Added ";
1312 info() <<
"#groups: OWN";
1316 info() <<
"#groups: ALLITEMS";
1320 info() <<
"#groups: Added ";
1350 mesh->
cellFamily()->notifyItemsOwnerChanged();
1373 gm2->setNbGhostLayer(1);
1374 mesh->updateGhostLayers(
true);
1380 auto it = std::min_element(node.
cells().begin(), node.
cells().end());
1381 Cell cell = node.
cell(
static_cast<Int32
>(std::distance(node.
cells().begin(),
it)));
1389 auto it = std::min_element(face.
cells().begin(), face.
cells().end());
1390 Cell cell = face.
cell(
static_cast<Int32
>(std::distance(face.
cells().begin(),
it)));
1399 gm2->setNbGhostLayer(0);
1400 mesh->updateGhostLayers(
true);
1421 mesh->
nodeFamily()->notifyItemsOwnerChanged();
1428 mesh->
faceFamily()->notifyItemsOwnerChanged();
1432 mesh->updateGhostLayers(
true);
1466 info() <<
"#_refineWithArcaneFaces";
1469 info() <<
"cell[" <<
icell->localId() <<
"," <<
icell->uniqueId() <<
"] type="
1470 <<
icell->type() <<
", nb nodes=" <<
icell->nbNode();
1473 info() <<
"Face " << face.uniqueId() <<
" Noeuds ";
1474 for (
Node node : face.nodes()) {
1475 info() << node.uniqueId() <<
" ";
1480 ARCANE_ASSERT((!
p.cells.empty()), (
"Pattern not init"));
1493 info() <<
"Get Pattern";
1497 info() <<
"Get Nodes";
1498 for (Integer i = 0; i < cell.
nbNode(); i++) {
1506 info() <<
"test " << i;
1510 Int64 uid = cell.
nbNode() + i;
1541 for (Integer i = 0; i < cells.
size(); i++) {
1544 cells_infos.
add(
p.cell_type);
1547 info() <<
"Cell " << i;
1548 for (Integer
j = 0;
j < cells[i].
size();
j++) {
1554 info() <<
"test2bisbis ";
1567 info() <<
"After nodes";
1570 info() <<
"After faces";
1584 info() <<
"#NODESHERE";
1595 info() <<
"#My mesh ";
1602 for (
Node node : face.nodes()) {
1603 stuff.add(node.uniqueId());
1605 info() <<
"Faces " << face.uniqueId() <<
" node " <<
stuff;
1609 info() <<
"#Arcane face numbering:";
1614 std::cout <<
"{" << face.
nodes()[0].uniqueId().asInt64();
1616 for (Integer i = 1; i < face.
nodes().size(); i++) {
1617 std::cout <<
"," << face.
nodes()[i].uniqueId().asInt64();
1624 std::cout <<
"}," << std::endl;
1637 (*arcane_cell_uid)[
icell] =
icell->uniqueId().asInt64();
1640 (*arcane_face_uid)[
iface] =
iface->uniqueId().asInt64();
1644 (*arcane_node_uid)[
inode] =
inode->uniqueId().asInt64();
1686 info() <<
"#ENDSUBDV ";
1691 mesh->
utilities()->writeToFile(
"subdivider_one_quad_input.vtk",
"VtkLegacyMeshWriter");
1696 info() <<
"cell[" <<
icell->localId() <<
"," <<
icell->uniqueId() <<
"] type="
1697 <<
icell->type() <<
", nb nodes=" <<
icell->nbNode();
1706 for (Integer i = 0; i < 4; i++)
1721 cells_infos[0] = IT_Quad4;
1722 cells_infos[1] = 44;
1731 mesh->
utilities()->writeToFile(
"subdivider_one_quad_ouput.vtk",
"VtkLegacyMeshWriter");
1737 mesh->
utilities()->writeToFile(
"subdivider_one_hexa_input.vtk",
"VtkLegacyMeshWriter");
1741 info() <<
"cell[" <<
icell->localId() <<
"," <<
icell->uniqueId() <<
"] type="
1742 <<
icell->type() <<
", nb nodes=" <<
icell->nbNode();
1750 for (Integer i = 0; i < 3; i++)
1764 cells_infos[0] = IT_Triangle3;
1765 cells_infos[1] = 44;
1773 mesh->
utilities()->writeToFile(
"subdivider_one_tri.vtk",
"VtkLegacyMeshWriter");
1788 std::sort(
tmp.begin(),
tmp.end());
1795ArcaneBasicMeshSubdividerService::
1803 mesh->
utilities()->writeToFile(
"subdivider_one_hexa_input.vtk",
"VtkLegacyMeshWriter");
1807 info() <<
"cell[" <<
icell->localId() <<
"," <<
icell->uniqueId() <<
"] type="
1808 <<
icell->type() <<
", nb nodes=" <<
icell->nbNode();
1816 for (Integer i = 0; i < 8; i++)
1835 cells_infos[0] = IT_Hexaedron8;
1836 cells_infos[1] = 44;
1858 mesh->
utilities()->writeToFile(
"subdivider_one_hexa_ouput.vtk",
"VtkLegacyMeshWriter");
1864 mesh->
utilities()->writeToFile(
"subdivider_one_tetra_input.vtk",
"VtkLegacyMeshWriter");
1870 info() <<
"cell[" <<
icell->localId() <<
"," <<
icell->uniqueId() <<
"] type="
1871 <<
icell->type() <<
", nb nodes=" <<
icell->nbNode();
1880 info() <<
"===================== THE MESH IS EMPTY";
1884 for (Integer i = 0; i < 4; i++)
1890 info() <<
"===================== THE MESH IS EMPTY";
1902 cells_infos[0] = IT_Tetraedron4;
1903 cells_infos[1] = 44;
1923 info() <<
"===================== THE CELLS ARE ADDED";
1929 mesh->
utilities()->writeToFile(
"3D_last_input_seq.vtk",
"VtkLegacyMeshWriter");
1930 info() <<
"#ORDRE FACES";
1936 for (
Node node : face.nodes()) {
1937 n.add(node.uniqueId().asInt64());
1939 info() << face.uniqueId() <<
" nodes " << n;
1947 std::unordered_map<Arccore::Int16, MeshSubdivider::Pattern>
pattern_manager;
1954 for (Integer i = 0; i <
options()->nbSubdivision; i++) {
1956 debug() << i <<
"refine done";
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
Fonctions utilitaires sur le maillage.
Generation de la classe de base du Service.
CaseOptionsArcaneBasicMeshSubdividerService * options() const
Options du jeu de données du service.
Service Arcane un maillage du jeu de données.
static UniqueArray< Int64 > _computeNodeUid(UniqueArray< Int64 > nodes_uid, const StorageRefine &node_pattern)
Calcule le unique id en fonction des noeuds de node_uid.
void _generatePattern2D(IPrimaryMesh *mesh)
Methode pour obtenir les fichier vtk pour les différent pattern disponibles en 2D.
void _generatePattern3D(IPrimaryMesh *mesh)
Methode pour obtenir les fichier vtk pour les différent pattern disponibles en 3D.
void subdivideMesh(IPrimaryMesh *mesh) override
Raffine le maillage un nombre nb-subdivision.
void _generateOneTri(IPrimaryMesh *mesh)
Génère un triangle.
void _generateOneQuad(IPrimaryMesh *mesh)
Génère un quadrilatère.
void _getArcaneOrder(IPrimaryMesh *mesh)
Methode pour avoir la manière dont sont crée les nouvelles faces pour un élément. Utile pour remplir ...
void _generatePattern(IPrimaryMesh *mesh)
Méthode pour générer les motifs sur un seul élément de base.
void _refineOnce(IPrimaryMesh *mesh, std::unordered_map< Arccore::Int16, MeshSubdivider::Pattern > &pattern_manager)
Raffine une fois le maillage avec les motifs présent dans le pattern_manager.
void _generateOneTetra(IPrimaryMesh *mesh)
Génère un tetraèdre.
void _faceOrderArcane(IPrimaryMesh *mesh)
Génère l'ordre des faces arcane pour tout les motifs.
void _refineWithArcaneFaces(IPrimaryMesh *mesh, MeshSubdivider::Pattern p)
Raffine en utilisant les faces d'arcane et le motif (Pattern) p.
void _generateOneHexa(IPrimaryMesh *mesh)
Génère un hexaèdre.
FaceConnectedListViewType faces() const
Liste des faces de la maille.
Face face(Int32 i) const
i-ème face de la maille
Cell cell(Int32 i) const
i-ème maille de la face
CellConnectedListViewType cells() const
Liste des mailles de la face.
Interface d'une famille d'entités.
virtual IItemFamily * nodeFamily()=0
Retourne la famille des noeuds.
virtual Integer nbCell()=0
Nombre de mailles du maillage.
virtual CellGroup ownCells()=0
Groupe de toutes les mailles propres au domaine.
virtual FaceGroup ownFaces()=0
Groupe de toutes les faces propres au domaine.
virtual FaceGroup allFaces()=0
Groupe de toutes les faces.
virtual Integer nbEdge()=0
Nombre d'arêtes du maillage.
virtual Integer dimension()=0
Dimension du maillage (1D, 2D ou 3D).
virtual IItemFamily * faceFamily()=0
Retourne la famille des faces.
virtual NodeGroup allNodes()=0
Groupe de tous les noeuds.
virtual CellGroup allCells()=0
Groupe de toutes les mailles.
virtual Integer nbFace()=0
Nombre de faces du maillage.
virtual IItemFamily * cellFamily()=0
Retourne la famille des mailles.
Interface de modification du maillage.
virtual void removeCells(Int32ConstArrayView cells_local_id)=0
Supprime des mailles.
virtual void addNodes(Int64ConstArrayView nodes_uid, Int32ArrayView nodes_lid=Int32ArrayView())=0
Ajoute des noeuds.
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.
virtual IMeshUtilities * utilities()=0
Interface des fonctions utilitaires associée.
virtual IGhostLayerMng * ghostLayerMng() const =0
Gestionnare de couche fantômes associé
virtual VariableNodeReal3 & nodesCoordinates()=0
Coordonnées des noeuds.
Groupe d'entités de maillage.
bool isOwn() const
Retourne si le groupe contient uniquement des éléments propres au sous-domaine.
const String & fullName() const
Nom du groupe.
void addItems(Int32ConstArrayView items_local_id, bool check_if_present=true)
Ajoute des entités.
bool isAllItems() const
Indique si le groupe est celui de toutes les entités.
Node node(Int32 i) const
i-ème noeud de l'entité
NodeConnectedListViewType nodes() const
Liste des noeuds de l'entité
Int32 nbNode() const
Nombre de noeuds de l'entité
NodeLocalIdView nodeIds() const
Liste des noeuds de l'entité
Classe de base d'un élément de maillage.
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.
ItemTypeId itemTypeId() const
Type de l'entité
Int16 type() const
Type de l'entité
Lecteur des fichiers de maillage via la bibliothèque LIMA.
Classe Pattern qui permet de manipuler un motif (pattern en anglais) de raffinement.
StorageRefine faces
Matrice pour la génération des nouvelles faces.
StorageRefine cells
Matrice pour la génération des nouvelles cellules.
Int16 type
Type de l'élément a rafiner.
StorageRefine nodes
Matrice pour la génération des nouveaux noeuds.
Int16 face_type
Type de la face de l'élément a rafiner.
Int16 cell_type
Type des cellules enfants.
void setOwner(Integer suid, Int32 current_sub_domain)
Positionne le numéro du sous-domaine propriétaire de l'entité.
Vue sur les informations des noeuds.
Cell cell(Int32 i) const
i-ème maille du noeud
CellConnectedListViewType cells() const
Liste des mailles du noeud.
Classe qui permet de construire des patterns.
Classe gérant un vecteur de réel de dimension 3.
Structure contenant les informations pour créer un service.
Paramètres nécessaires à la construction d'une variable.
Integer size() const
Nombre d'éléments du vecteur.
void add(ConstReferenceType val)
Ajoute l'élément val à la fin du tableau.
TraceMessageDbg debug(Trace::eDebugLevel=Trace::Medium) const
Flot pour un message de debug.
TraceMessage info() const
Flot pour un message d'information.
Vecteur 1D de données avec sémantique par valeur (style STL).
MeshVariableScalarRefT< Cell, Int64 > VariableCellInt64
Grandeur au centre des mailles de type entier 64 bits.
MeshVariableScalarRefT< Node, Int64 > VariableNodeInt64
Grandeur au noeud de type entier 64 bits.
MeshVariableScalarRefT< Face, Int64 > VariableFaceInt64
Grandeur aux faces de type entier 64 bits.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-