14#include "arcane/mesh/CellMerger.h"
16#include "arcane/utils/FatalErrorException.h"
17#include "arcane/utils/StringBuilder.h"
18#include "arcane/utils/TraceInfo.h"
19#include "arcane/utils/CheckedConvert.h"
20#include "arcane/utils/TraceAccessor.h"
22#include "arcane/core/Item.h"
24#include "arcane/core/IItemFamily.h"
25#include "arcane/core/IItemFamilyTopologyModifier.h"
26#include "arcane/core/IMesh.h"
27#include "arcane/core/internal/IItemFamilyInternal.h"
29#include "arcane/mesh/FaceReorienter.h"
51 m_face_reorienter(
mesh),
52 m_cell_tm(
mesh->cellFamily()->_internalApi()->topologyModifier()),
53 m_face_tm(
mesh->faceFamily()->_internalApi()->topologyModifier()),
54 m_node_tm(
mesh->nodeFamily()->_internalApi()->topologyModifier())
68 NodeLocalId face1_node = face_1.
node(face1_node_idx);
69 NodeLocalId face2_node = face_2.
node(face2_node_idx);
71 m_face_tm->replaceNode(face_1,face1_node_idx,face2_node);
72 m_face_tm->replaceNode(face_2,face2_node_idx,face1_node);
74 m_node_tm->findAndReplaceFace(face1_node,face_1,face_2);
75 m_node_tm->findAndReplaceFace(face2_node,face_2,face_1);
87 NodeLocalId cell1_node = cell1.
node(cell1_node_idx);
88 NodeLocalId cell2_node = cell2.
node(cell2_node_idx);
90 m_cell_tm->replaceNode(cell1,cell1_node_idx,cell2_node);
91 m_cell_tm->replaceNode(cell2,cell2_node_idx,cell1_node);
93 m_node_tm->findAndReplaceCell(cell1_node,cell1,cell2);
94 m_node_tm->findAndReplaceCell(cell2_node,cell2,cell1);
106 FaceLocalId cell1_face = cell1.
face(cell1_face_idx);
107 FaceLocalId cell2_face = cell2.
face(cell2_face_idx);
109 m_cell_tm->replaceFace(cell1,cell1_face_idx,cell2_face);
110 m_cell_tm->replaceFace(cell2,cell2_face_idx,cell1_face);
112 m_face_tm->findAndReplaceCell(cell1_face,cell1,cell2);
113 m_face_tm->findAndReplaceCell(cell2_face,cell2,cell1);
116 void checkAndChangeFaceOrientation(
Cell cell)
125 FaceReorienter m_face_reorienter;
126 IItemFamilyTopologyModifier* m_cell_tm;
127 IItemFamilyTopologyModifier* m_face_tm;
128 IItemFamilyTopologyModifier* m_node_tm;
143 typedef std::set<Integer> NodesLIDSet;
149 NodesLIDSet m_nodes_lid_set;
159 return m_nodes_lid_set;
203 typedef std::map<Integer, Integer> LIDCellMapping;
204 LIDCellMapping faces1;
205 LIDCellMapping faces2;
210 faces1[i_face->localId()] = n;
217 faces2[i_face->localId()] = n;
225 LIDCellMapping::const_iterator i_face1 = faces1.begin();
226 LIDCellMapping::const_iterator i_face2 = faces2.begin();
229 const Integer& lid1 = i_face1->first;
230 const Integer& lid2 = i_face2->first;
240 m_nodes_lid_set.insert(i_node->localId());
251 }
while (i_face1 != faces1.end() && i_face2 != faces2.end());
296 typedef std::map<Integer, Integer> LocalIDToLocalNumber;
297 LocalIDToLocalNumber face1_node_localId;
298 LocalIDToLocalNumber face2_node_localId;
303 face1_node_localId[i_node->localId()]=n++;
309 face2_node_localId[i_node->localId()]=n++;
315 for (LocalIDToLocalNumber::const_iterator
316 i = face1_node_localId.begin(),
317 j = face2_node_localId.begin();
318 i != face1_node_localId.end() && j != face2_node_localId.end();) {
319 Int32 node1_localId = i->first;
320 Int32 node2_localId = j->first;
321 if (node1_localId == node2_localId) {
326 if (node1_localId < node2_localId) {
346 ARCANE_ASSERT(face2.
type()==IT_Line2,(
"The cell is not a line"));
388 const CommonFaceFinder::NodesLIDSet& common_face_nodes)
390 typedef Integer _EdgeDescriptor;
391 typedef std::map<_EdgeDescriptor, Integer> _EdgeFaceList;
393 _EdgeFaceList temp_edge_face_list;
397 if (face_number == common_face_number) {
402 std::multiset<Integer> node_list;
403 for(
NodeEnumerator i_node(i_face->nodes()); i_node(); ++i_node) {
404 const Integer& node_lid = i_node->localId();
405 if (common_face_nodes.find(node_lid) != common_face_nodes.end()) {
406 node_list.insert(node_lid);
410 switch (node_list.size()) {
414 std::multiset<Integer>::const_iterator i = node_list.begin();
416 temp_edge_face_list[node_lid] = face_number;
420 ARCANE_FATAL(
"Unexpected number of nodes on the common face !");
427 for (_EdgeFaceList::const_iterator i = temp_edge_face_list.begin();
428 i != temp_edge_face_list.end(); ++i) {
429 edge_face_list.
add(i->second);
465 return m_cell2_edge_face_list[i];
483 m_cell2_edge_face_list,
488 (
"Incompatible number of 2D faces to merge !"));
536 return m_cell2_edge_face_list[i];
555 (
"Incompatible number of faces to merge !"));
573 const CommonFaceFinder::NodesLIDSet& common_face_nodes);
593 const CommonFaceFinder::NodesLIDSet& common_face_nodes)
595 typedef std::pair<Integer,Integer> _EdgeDescriptor;
596 typedef std::map<_EdgeDescriptor, Integer> _EdgeFaceList;
598 _EdgeFaceList temp_edge_face_list;
601 if (face_number == common_face_number) {
605 std::multiset<Integer> node_list;
606 for (
NodeEnumerator i_node(i_face->nodes()); i_node(); ++i_node) {
607 Int32 node_lid = i_node->localId();
609 if (common_face_nodes.find(node_lid) != common_face_nodes.end()) {
610 node_list.insert(node_lid);
614 switch (node_list.size()) {
618 std::multiset<Integer>::const_iterator i = node_list.begin();
619 const Integer first_node_lid = *i;
621 const Integer second_node_lid = *i;
623 temp_edge_face_list[std::make_pair(first_node_lid, second_node_lid)] = face_number;
627 ARCANE_FATAL(
"Unexpected number of nodes on the common face !");
634 for (_EdgeFaceList::const_iterator i = temp_edge_face_list.begin();
635 i != temp_edge_face_list.end(); ++i) {
636 edge_face_list.
add(i->second);
680 typedef std::map<Integer, Integer> LocalIDToLocalNumber;
681 LocalIDToLocalNumber face1_node_localId;
682 LocalIDToLocalNumber face2_node_localId;
687 face1_node_localId[i_node->localId()]=n++;
693 face2_node_localId[i_node->localId()]=n++;
700 std::set<Integer> face2_common_edge_node_number;
702 for (LocalIDToLocalNumber::const_iterator
703 i = face1_node_localId.begin(),
704 j = face2_node_localId.begin();
705 i != face1_node_localId.end() && j != face2_node_localId.end();) {
706 const Integer& node1_localId = i->first;
707 const Integer& node2_localId = j->first;
708 if (node1_localId == node2_localId) {
711 face2_common_edge_node_number.insert(j->second);
714 if (node1_localId < node2_localId) {
726 (
"Incorrect number of shared vertices"));
733 if (face2_common_edge_node_number.find(edge_node) == face2_common_edge_node_number.end()) {
749 ARCANE_ASSERT(face2.
type()==IT_Quad4,(
"The cell is not a quadrangle"));
753 (
"Incorrect number of exchange vertices"));
756 for (
Integer i = 0; i<2; ++i) {
815 typedef std::map<Integer, Integer> LocalIDToLocalNumber;
816 LocalIDToLocalNumber cell1_node_localId;
817 LocalIDToLocalNumber cell2_node_localId;
822 cell1_node_localId[i_node->localId()] = n++;
828 cell2_node_localId[i_node->localId()] = n++;
832 std::set<Integer> cell2_common_edge_node_number;
833 for (LocalIDToLocalNumber::const_iterator
834 i = cell1_node_localId.begin(),
835 j = cell2_node_localId.begin();
836 i != cell1_node_localId.end() && j != cell2_node_localId.end();) {
837 const Integer& node1_localId = i->first;
838 const Integer& node2_localId = j->first;
839 if (node1_localId == node2_localId) {
842 cell2_common_edge_node_number.insert(j->second);
846 if (node1_localId < node2_localId) {
856 (
"Bad number of shared vertices"));
863 if (cell2_common_edge_node_number.find(edge_node) == cell2_common_edge_node_number.end()) {
877 ARCANE_ASSERT(cell2.
type()==IT_Quad4,(
"Cell2 is not a IT_Quad4"));
903 swap_utils->checkAndChangeFaceOrientation(cell1);
910= { {1,3},{0,2},{1,3},{0,2} };
952 typedef std::map<Integer, Integer> LocalIDToLocalNumber;
953 LocalIDToLocalNumber cell1_node_localId;
954 LocalIDToLocalNumber cell2_node_localId;
962 cell1_node_localId[i_node->localId()] = n++;
969 cell2_node_localId[i_node->localId()] = n++;
975 std::set<Integer> cell2_common_edge_node_number;
976 for (LocalIDToLocalNumber::const_iterator
977 i = cell1_node_localId.begin(),
978 j = cell2_node_localId.begin();
979 i != cell1_node_localId.end() && j != cell2_node_localId.end();) {
980 Integer node1_localId = i->first;
981 Integer node2_localId = j->first;
982 if (node1_localId == node2_localId) {
989 cell2_common_edge_node_number.insert(j->second);
992 if (node1_localId < node2_localId) {
1001 (
"Bad number of shared vertices"));
1012 if (cell2_common_edge_node_number.find(edge_node) == cell2_common_edge_node_number.end()) {
1028 ARCANE_ASSERT(cell2.
type() == IT_Hexaedron8,(
"Cell2 is not a IT_Hexaedron8"));
1054 swap_utils->checkAndChangeFaceOrientation(cell1);
1062m_hexa_node_neighbors[8][3] = { {1,3,4},{0,2,5},{1,3,6},{0,2,7},{0,5,7},{1,4,6},{2,5,7},{3,4,6} };
1071 case Hexahedron:
return "hexahèdre";
1072 case Pyramid:
return "pyramide";
1073 case Pentahedron:
return "pentahèdre";
1074 case Quadrilateral:
return "quadrangle";
1075 case Triangle:
return "triangle";
1076 default:
return "inconnu";
1086 switch(internal_cell_type) {
1087 case IT_Hexaedron8: {
1093 case IT_Pentaedron6: {
1097 return Quadrilateral;
1099 case IT_Triangle3: {
1103 return NotMergeable;
1115 case 1:
return Hexahedron;
1116 case 2:
return Pyramid;
1117 case 3:
return Pentahedron;
1118 case 100:
return Quadrilateral;
1119 case 110:
return Triangle;
1135 switch (cell_1_type) {
1150 case NotMergeable: {
1154 ARCANE_FATAL(
"Merge for this kind of cell not implemented\n");
1168 switch (merged_cell_type) {
1174 if (cell_2_type == Hexahedron) {
1180 case Quadrilateral: {
1184 if (cell_2_type == Quadrilateral) {
1190 case NotMergeable: {
1194 ARCANE_FATAL(
"Merge for this kind of cell not implemented\n");
1205 return ItemCompatibility::_itemInternal(
getCell(i_cell_1,i_cell_2));
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
void reserve(Int64 new_capacity)
Réserve le mémoire pour new_capacity éléments.
void add(ConstReferenceType val)
Ajoute l'élément val à la fin du tableau.
FaceConnectedListViewType faces() const
Liste des faces de la maille.
Face face(Int32 i) const
i-ème face de la maille
Int32 nbFace() const
Nombre de faces de la maille.
ARCANE_DEPRECATED_260 void checkAndChangeOrientation(ItemInternal *face)
virtual IMesh * mesh() const =0
Maillage associé
Structure interne d'une entité de maillage.
Node node(Int32 i) const
i-ème noeud de l'entité
NodeConnectedListViewType nodes() const
Liste des noeuds de l'entité
IItemFamily * itemFamily() const
Famille dont est issue l'entité
Int16 type() const
Type de l'entité
Chaîne de caractères unicode.
TraceAccessor(ITraceMng *m)
Construit un accesseur via le gestionnaire de trace m.
_Type _getCellType(const Integer &internal_cell_type) const
Détermine le _Type de la maille en fonction de son type "ItemInternal".
String _typeName(const _Type &t) const
Retourne le nom associé à type de maille.
void merge(Cell i_cell_1, Cell i_cell_2)
Effectue la fusion des deux mailles i_cell_1 et i_cell_2.
ItemInternal * getItemInternal(ItemInternal *i_cell_1, ItemInternal *i_cell_2)
Retourne l'ItemInteral utilisé par la maille après fusion.
_Type _promoteType(const _Type &t1, const _Type &t2) const
Cell getCell(Cell i_cell_1, Cell i_cell_2)
Retourne la maille utilisé par la maille après fusion.
Cette fonction-classe a pour but de fusionner deux mailles dont la deuxième est forcément un hexahèdr...
void _setCellsNodeNumbers(Cell cell1, Cell cell2)
static const Integer m_hexa_node_neighbors[8][3]
IntegerUniqueArray m_cell_2_exchanged_node_numbers
IntegerUniqueArray m_cell_1_common_node_numbers
IntegerUniqueArray m_cell_2_common_node_numbers
CellToHexahedronMerger(ItemSwapperUtils *swap_utils, Cell cell1, Cell cell2)
static const Integer m_quad_node_neighbors[4][2]
Liste des noeuds voisins par arête dans un quadrangle.
void _setCellsNodeNumbers(Cell i_cell_1, Cell i_cell_2)
IntegerUniqueArray m_cell_2_exchanged_node_numbers
Numéros dans la maille 2 des sommets qui définiront la maille fusionnée.
IntegerUniqueArray m_cell_2_common_node_numbers
Numéros dans la maille 2 des sommets communs avec la maille 1.
CellToQuadrilateralMerger(ItemSwapperUtils *swap_utils, Cell cell1, Cell cell2)
IntegerUniqueArray m_cell_1_common_node_numbers
Numéros dans la maille 1 des sommets communs avec la maille 2.
Recherche la face commune à deux mailles.
Integer m_cell_2_local_number
Numéro de la face commune dans la maille 2.
Integer cell2LocalNumber() const
Integer m_cell_1_local_number
Numéro de la face commune dans la maille 1.
CommonFaceFinder(Cell i_cell_1, Cell i_cell_2)
const NodesLIDSet & nodesLID() const
Ensemble des localId des sommets en communs.
Integer cell1LocalNumber() const
Cett fonction-classe a pour but de fusionner deux faces dont la deuxième est forcément un quadrangle.
IntegerUniqueArray m_face_2_exchanged_node_numbers
IntegerUniqueArray m_face_2_common_node_numbers
bool _setFacesNodeNumbers(Face i_face_1, Face i_face_2)
static const Integer m_quad_node_neighbors[4][2]
IntegerUniqueArray m_face_1_common_node_numbers
FaceToQuadrilateralMerger(ItemSwapperUtils *swap_utils, Face face1, Face face2)
Fusionne deux faces en 2D (en fait deux arêtes).
Integer m_face_2_exchanged_node_numbers
Integer m_face_2_common_node_numbers
Integer m_face_1_common_node_numbers
void _setFacesNodeNumbers(Face i_face_1, Face i_face_2)
Faces2DMerger(ItemSwapperUtils *swap_utils, Face i_face_1, Face i_face_2)
En dimension 2, recherche des faces communes à deux mailles (Les faces sont en fait des arêtes).
Integer cell1FaceNumber(Integer i) const
Integer cell2FaceNumber(Integer i) const
Integer getNumber() const
IntegerUniqueArray m_cell1_edge_face_list
void _setEdgeFaceList(Cell i_cell, IntegerArray &edge_face_list, Integer common_face_number, const CommonFaceFinder::NodesLIDSet &common_face_nodes)
Faces2DToMergeFinder(Cell cell1, Cell cell2, const CommonFaceFinder &common_face)
Cette fonction-classe recherche les faces à fusionner lors de la fusion de deux mailles.
Integer cell1FaceNumber(Integer i) const
Integer cell2FaceNumber(Integer i) const
Integer getNumber() const
IntegerUniqueArray m_cell1_edge_face_list
void _setEdgeFaceList(Cell i_cell, IntegerArray &edge_face_list, Integer common_face_number, const CommonFaceFinder::NodesLIDSet &common_face_nodes)
FacesToMergeFinder(Cell cell1, Cell cell2, const CommonFaceFinder &common_face)
Classe utilitaire pour échanger des entités entre deux entités.
void swapFaceNodes(Face face_1, Face face_2, Integer face1_node_idx, Integer face2_node_idx)
Échange deux noeuds entre deux faces.
void swapCellFaces(Cell cell1, Cell cell2, Integer cell1_face_idx, Integer cell2_face_idx)
Échange deux faces entre deux mailles.
void swapCellNodes(Cell cell1, Cell cell2, Integer cell1_node_idx, Integer cell2_node_idx)
Échange deux noeuds entre deux mailles.
ItemEnumeratorT< Node > NodeEnumerator
Enumérateurs sur des noeuds.
ItemEnumeratorT< Face > FaceEnumerator
Enumérateurs sur des faces.
Integer toInteger(Real r)
Converti un Int64 en un Integer.
Int32 Integer
Type représentant un entier.
Array< Integer > IntegerArray
Tableau dynamique à une dimension d'entiers.
UniqueArray< Integer > IntegerUniqueArray
Tableau dynamique à une dimension d'entiers.
std::int32_t Int32
Type entier signé sur 32 bits.