Arcane  v3.15.3.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
CellMerger.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2025 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
4// See the top-level COPYRIGHT file for details.
5// SPDX-License-Identifier: Apache-2.0
6//-----------------------------------------------------------------------------
7/*---------------------------------------------------------------------------*/
8/* CellMerger.cc (C) 2000-2025 */
9/* */
10/* Fusionne deux mailles. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/mesh/CellMerger.h"
15
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"
21
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"
28
29#include "arcane/mesh/FaceReorienter.h"
30
31#include <map>
32#include <set>
33
34/*---------------------------------------------------------------------------*/
35/*---------------------------------------------------------------------------*/
36
37namespace Arcane::mesh
38{
39
40/*---------------------------------------------------------------------------*/
41/*---------------------------------------------------------------------------*/
42
45: public TraceAccessor
46{
47 public:
48
49 explicit ItemSwapperUtils(IMesh* mesh)
50 : TraceAccessor(mesh->traceMng()),
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())
55 {
56 }
57 public:
58
77
96
115
116 void checkAndChangeFaceOrientation(Cell cell)
117 {
118 // Ceci pourrait sans doutes etre optimise
119 for( Integer i=0, n=cell.nbFace(); i<n; ++i) {
120 m_face_reorienter.checkAndChangeOrientation(cell.face(i));
121 }
122 }
123
124 private:
125 FaceReorienter m_face_reorienter;
126 IItemFamilyTopologyModifier* m_cell_tm;
127 IItemFamilyTopologyModifier* m_face_tm;
128 IItemFamilyTopologyModifier* m_node_tm;
129};
130
131/*---------------------------------------------------------------------------*/
132/*---------------------------------------------------------------------------*/
141{
142 public:
143 typedef std::set<Integer> NodesLIDSet;
144
145 private:
148
149 NodesLIDSet m_nodes_lid_set;
150
151 public:
157 const NodesLIDSet& nodesLID() const
158 {
159 return m_nodes_lid_set;
160 }
161
168 Integer cell1LocalNumber() const
169 {
171 }
172
179 Integer cell2LocalNumber() const
180 {
182 }
183
193};
194
195/*---------------------------------------------------------------------------*/
196/*---------------------------------------------------------------------------*/
197
200: m_cell_1_local_number(-1)
201, m_cell_2_local_number(-1)
202{
203 typedef std::map<Integer, Integer> LIDCellMapping;
204 LIDCellMapping faces1; // numero des faces de la maille 1
205 LIDCellMapping faces2; // numero des faces de la maille 2
206
207 { // création des correspondances localId numero dans la maille pour la maille 1
208 Integer n = 0;
209 for( ItemEnumerator i_face(i_cell_1.faces()); i_face(); ++i_face ) {
210 faces1[i_face->localId()] = n;
211 n++;
212 }
213 }
214 { // création des correspondances localId numero dans la maille pour la maille 2
215 Integer n = 0;
216 for( ItemEnumerator i_face(i_cell_2.faces()); i_face(); ++i_face ) {
217 faces2[i_face->localId()] = n;
218 n++;
219 }
220 }
221
222 // On parcours maintenant les deux tables créé précédemment, comme
223 // elles sont triées par localId croissant, on en déduit
224 // simplement la face commune.
225 LIDCellMapping::const_iterator i_face1 = faces1.begin();
226 LIDCellMapping::const_iterator i_face2 = faces2.begin();
227
228 do {
229 const Integer& lid1 = i_face1->first; // localId de la face dans la liste 1
230 const Integer& lid2 = i_face2->first; // localId de la face dans la liste 2
231
232 if (lid1 == lid2) { // on a trouvé la face commune
235
236 // Enregistrement des localId des noeuds de la face commune
238
239 for( NodeEnumerator i_node(common_face.nodes()); i_node(); ++i_node) {
240 m_nodes_lid_set.insert(i_node->localId());
241 }
242 return;
243 }
244 else {
245 if (lid1<lid2) {
246 ++i_face1;
247 } else {
248 ++i_face2;
249 }
250 }
251 } while (i_face1 != faces1.end() && i_face2 != faces2.end());
252
253 ARCANE_FATAL("Face commune non trouvée !");
254}
255
256/*---------------------------------------------------------------------------*/
257/*---------------------------------------------------------------------------*/
258
259/*---------------------------------------------------------------------------*/
260/*---------------------------------------------------------------------------*/
289
290/*---------------------------------------------------------------------------*/
291/*---------------------------------------------------------------------------*/
292
295{
296 typedef std::map<Integer, Integer> LocalIDToLocalNumber;
299
300 {
301 Integer n = 0;
302 for (ItemEnumerator i_node(i_face_1.nodes()); i_node(); ++i_node) {
303 face1_node_localId[i_node->localId()]=n++;
304 }
305 }
306 {
307 Integer n = 0;
308 for (ItemEnumerator i_node(i_face_2.nodes()); i_node(); ++i_node) {
309 face2_node_localId[i_node->localId()]=n++;
310 }
311 }
312
313 //Integer face2_common_edge_node_number = std::numeric_limits<Integer>::max();
314
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;
324 break;
325 } else {
327 ++i;
328 } else {
329 ++j;
330 }
331 }
332 }
333
335}
336
337/*---------------------------------------------------------------------------*/
338/*---------------------------------------------------------------------------*/
339
342: m_face_1_common_node_numbers(std::numeric_limits<Integer>::max())
343, m_face_2_common_node_numbers(std::numeric_limits<Integer>::max())
344, m_face_2_exchanged_node_numbers(std::numeric_limits<Integer>::max())
345{
346 ARCANE_ASSERT(face2.type()==IT_Line2,("The cell is not a line"));
347
349
352}
353
354/*---------------------------------------------------------------------------*/
355/*---------------------------------------------------------------------------*/
361{
362 private:
363
365
372 IntegerUniqueArray m_cell2_edge_face_list;
374
387 Integer common_face_number,
388 const CommonFaceFinder::NodesLIDSet& common_face_nodes)
389 {
390 typedef Integer _EdgeDescriptor;
391 typedef std::map<_EdgeDescriptor, Integer> _EdgeFaceList;
392
394 Integer face_number = 0;
395 // Pour chaque face de la maille
396 for ( FaceEnumerator i_face(i_cell.faces()); i_face(); ++i_face, ++face_number) {
398 continue; // si la face est la face commune, on ne fait rien
399 }
400
401 // On crée la liste des noeuds de cette face qui sont communs
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);
407 }
408 }
409
410 switch (node_list.size()) {
411 case 0: // la face n'est pas à retailler [déjà traitée]
412 case 2:continue;
413 case 1: { // Si la liste ne contient qu'un élément, c'est que la face est à fusionner
414 std::multiset<Integer>::const_iterator i = node_list.begin();
415 const Integer node_lid = *i;
417 break;
418 }
419 default: {
420 ARCANE_FATAL("Unexpected number of nodes on the common face !");
421 }
422 }
423 }
424
425 // On recopie les donnée : on n'a plus besoin des arêtes
426 edge_face_list.reserve((Integer)temp_edge_face_list.size());
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); // on stocke les numéros des faces à fusionner
430 }
431 }
432
433 public:
439 Integer getNumber() const
440 {
442 }
443
451 Integer cell1FaceNumber(Integer i) const
452 {
453 return m_cell1_edge_face_list[i];
454 }
455
463 Integer cell2FaceNumber(Integer i) const
464 {
465 return m_cell2_edge_face_list[i];
466 }
467
477 {
478 this->_setEdgeFaceList(cell1,
480 common_face.cell1LocalNumber(),
481 common_face.nodesLID());
482 this->_setEdgeFaceList(cell2,
483 m_cell2_edge_face_list,
484 common_face.cell2LocalNumber(),
485 common_face.nodesLID());
486
487 ARCANE_ASSERT(m_cell1_edge_face_list.size() == m_cell2_edge_face_list.size(),
488 ("Incompatible number of 2D faces to merge !"));
489 }
490};
491
492/*---------------------------------------------------------------------------*/
493/*---------------------------------------------------------------------------*/
494
495/*---------------------------------------------------------------------------*/
496/*---------------------------------------------------------------------------*/
502{
503 public:
504
510 Integer getNumber() const
511 {
513 }
514
522 Integer cell1FaceNumber(Integer i) const
523 {
524 return m_cell1_edge_face_list[i];
525 }
526
534 Integer cell2FaceNumber(Integer i) const
535 {
536 return m_cell2_edge_face_list[i];
537 }
538
548 {
550 common_face.cell1LocalNumber(),common_face.nodesLID());
551 _setEdgeFaceList(cell2,m_cell2_edge_face_list,
552 common_face.cell2LocalNumber(),common_face.nodesLID());
553
554 ARCANE_ASSERT(m_cell1_edge_face_list.size() == m_cell2_edge_face_list.size(),
555 ("Incompatible number of faces to merge !"));
556 }
557
558 private:
559
561
568 IntegerUniqueArray m_cell2_edge_face_list;
572 Integer common_face_number,
573 const CommonFaceFinder::NodesLIDSet& common_face_nodes);
574};
575
576/*---------------------------------------------------------------------------*/
577/*---------------------------------------------------------------------------*/
578
592 Integer common_face_number,
593 const CommonFaceFinder::NodesLIDSet& common_face_nodes)
594{
595 typedef std::pair<Integer,Integer> _EdgeDescriptor;
596 typedef std::map<_EdgeDescriptor, Integer> _EdgeFaceList;
597
598 _EdgeFaceList temp_edge_face_list; // liste tries des numéros de faces par arêtes
599 Integer face_number = 0;
600 for (FaceEnumerator i_face(i_cell.faces()); i_face(); ++i_face, ++face_number) {
601 if (face_number == common_face_number) { // si la face est la face commune elle n'est pas traitée
602 continue;
603 }
604
605 std::multiset<Integer> node_list; // liste des localIds des noeuds de la face qui sont communs
606 for (NodeEnumerator i_node(i_face->nodes()); i_node(); ++i_node) {
607 Int32 node_lid = i_node->localId();
608 // si le noeud est commun on l'ajoute à la liste des noeuds communs
609 if (common_face_nodes.find(node_lid) != common_face_nodes.end()) {
610 node_list.insert(node_lid);
611 }
612 }
613
614 switch (node_list.size()) {
615 case 0: // la face n'est pas à retailler [déjà traitée]
616 case 4:continue;
617 case 2: {
618 std::multiset<Integer>::const_iterator i = node_list.begin();
619 const Integer first_node_lid = *i;
620 ++i;
621 const Integer second_node_lid = *i;
622 // On crée la correspondance arête/face (les noeuds de l'arête étant triés)
624 break;
625 }
626 default:
627 ARCANE_FATAL("Unexpected number of nodes on the common face !");
628 }
629 }
630
631 // On recopie les donnée : on n'a plus besoin des arêtes. Les
632 // faces numéros des faces sont orientés comme on le souhaite.
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);
637 }
638}
639
640/*---------------------------------------------------------------------------*/
641/*---------------------------------------------------------------------------*/
673
674/*---------------------------------------------------------------------------*/
675/*---------------------------------------------------------------------------*/
676
679{
680 typedef std::map<Integer, Integer> LocalIDToLocalNumber;
683
684 {
685 Integer n = 0;
686 for (NodeEnumerator i_node(i_face_1.nodes()); i_node(); ++i_node) {
687 face1_node_localId[i_node->localId()]=n++;
688 }
689 }
690 {
691 Integer n = 0;
692 for (NodeEnumerator i_node(i_face_2.nodes()); i_node(); ++i_node) {
693 face2_node_localId[i_node->localId()]=n++;
694 }
695 }
696
699
700 std::set<Integer> face2_common_edge_node_number;
701
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;
711 face2_common_edge_node_number.insert(j->second);
712 ++i;++j;
713 } else {
715 ++i;
716 } else {
717 ++j;
718 }
719 }
720 }
721
722 if (m_face_1_common_node_numbers.size() == 0) return false;
723
724 ARCANE_ASSERT((m_face_2_common_node_numbers.size() == 2)
726 ("Incorrect number of shared vertices"));
727
729 for (Integer i = 0; i<m_face_2_common_node_numbers.size(); ++i) {
730 const Integer& node_number = m_face_2_common_node_numbers[i];
731 for (Integer j=0; j<2; ++j) {
732 const Integer& edge_node = m_quad_node_neighbors[node_number][j];
735 break;
736 }
737 }
738 }
739 return true;
740}
741
742
743/*---------------------------------------------------------------------------*/
744/*---------------------------------------------------------------------------*/
745
748{
749 ARCANE_ASSERT(face2.type()==IT_Quad4,("The cell is not a quadrangle"));
750
752 ARCANE_ASSERT(m_face_2_exchanged_node_numbers.size() == 2,
753 ("Incorrect number of exchange vertices"));
754
755 // Echange des sommets des faces
756 for (Integer i = 0; i<2; ++i) {
759 }
760 }
761}
762
763/*---------------------------------------------------------------------------*/
764/*---------------------------------------------------------------------------*/
765
766const Integer
768m_quad_node_neighbors[4][2] = { {1,3},{0,2},{1,3},{0,2} };
769
770/*---------------------------------------------------------------------------*/
771/*---------------------------------------------------------------------------*/
772
773/*---------------------------------------------------------------------------*/
774/*---------------------------------------------------------------------------*/
775
808
809/*---------------------------------------------------------------------------*/
810/*---------------------------------------------------------------------------*/
811
814{
815 typedef std::map<Integer, Integer> LocalIDToLocalNumber;
818
819 {
820 Integer n = 0;
821 for (NodeEnumerator i_node(i_cell_1.nodes()); i_node(); ++i_node) {
822 cell1_node_localId[i_node->localId()] = n++;
823 }
824 }
825 {
826 Integer n = 0;
827 for (NodeEnumerator i_node(i_cell_2.nodes()); i_node(); ++i_node) {
828 cell2_node_localId[i_node->localId()] = n++;
829 }
830 }
831
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;
842 cell2_common_edge_node_number.insert(j->second);
843 ++i;++j;
844 }
845 else {
847 ++i;
848 }
849 else {
850 ++j;
851 }
852 }
853 }
854
855 ARCANE_ASSERT(m_cell_1_common_node_numbers.size() == 2,
856 ("Bad number of shared vertices"));
857
859 for (Integer i = 0; i<m_cell_2_common_node_numbers.size(); ++i) {
860 const Integer& node_number = m_cell_2_common_node_numbers[i];
861 for (Integer j=0; j<2; ++j) {
862 const Integer& edge_node = m_quad_node_neighbors[node_number][j];
865 break;
866 }
867 }
868 }
869}
870
871/*---------------------------------------------------------------------------*/
872/*---------------------------------------------------------------------------*/
873
876{
877 ARCANE_ASSERT(cell2.type()==IT_Quad4,("Cell2 is not a IT_Quad4"));
878
880
881 this->_setCellsNodeNumbers(cell1,cell2);
882
883 // Fusion des mailles de côté
885 for (Integer i = 0; i<faces_to_merge.getNumber(); ++i) {
887 cell1.face(faces_to_merge.cell1FaceNumber(i)),
888 cell2.face(faces_to_merge.cell2FaceNumber(i)));
889 }
890
891 // Echange des faces.
892 swap_utils->swapCellFaces(cell1,cell2,
893 common_face.cell1LocalNumber(),
894 (common_face.cell2LocalNumber()+2)%4); // face opposée
895
896 // Echange des sommets des mailles
897 for (Integer i=0, n=m_cell_1_common_node_numbers.size(); i<n; ++i) {
898 swap_utils->swapCellNodes(cell1,cell2,
901 }
902
903 swap_utils->checkAndChangeFaceOrientation(cell1);
904}
905
906/*---------------------------------------------------------------------------*/
907/*---------------------------------------------------------------------------*/
908
910= { {1,3},{0,2},{1,3},{0,2} };
911
912/*---------------------------------------------------------------------------*/
913/*---------------------------------------------------------------------------*/
945
946/*---------------------------------------------------------------------------*/
947/*---------------------------------------------------------------------------*/
948
951{
952 typedef std::map<Integer, Integer> LocalIDToLocalNumber;
955
956 // On associe les numéros (dans la maille) des noeuds à leur
957 // localId. Ces listes sont triées par localId !
958 {
959 // d'abord pour la maille 1
960 Integer n = 0;
961 for (NodeEnumerator i_node(cell1.nodes()); i_node(); ++i_node) {
962 cell1_node_localId[i_node->localId()] = n++;
963 }
964 }
965 {
966 // puis pour la maille 2
967 Integer n = 0;
968 for (NodeEnumerator i_node(cell2.nodes()); i_node(); ++i_node) {
969 cell2_node_localId[i_node->localId()] = n++;
970 }
971 }
972
973 // On determine ensuite l'ensemble des noeuds communs aux deux
974 // mailles
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) { // si les noeuds sont les mêmes
983 // on stockes les numéros dans la mailles de ces sommets
984 m_cell_1_common_node_numbers.add(i->second); // pour la maille 1
985 m_cell_2_common_node_numbers.add(j->second); // pour la maille 2
986
987 // et on crée l'ensemble ordonné des noeuds communs dans la
988 // seconde maille
989 cell2_common_edge_node_number.insert(j->second);
990 ++i;++j;
991 } else {
993 ++i;
994 } else {
995 ++j;
996 }
997 }
998 }
999
1000 ARCANE_ASSERT(m_cell_1_common_node_numbers.size() == 4,
1001 ("Bad number of shared vertices"));
1002
1003 // On cherche maintenant les sommets voisins des noeuds commun
1004 // appartenant à la seconde maille et qui ne sont pas des sommets
1005 // échangés. Ce sont les sommets qui formeront la nouvelle maille
1006 // par substitution avec les sommets communs de la première maille.
1008 for (Integer i = 0; i<m_cell_2_common_node_numbers.size(); ++i) {
1009 const Integer& node_number = m_cell_2_common_node_numbers[i];
1010 for (Integer j=0; j<3; ++j) {
1011 const Integer& edge_node = m_hexa_node_neighbors[node_number][j];
1014 break;
1015 }
1016 }
1017 }
1018}
1019
1020/*---------------------------------------------------------------------------*/
1021/*---------------------------------------------------------------------------*/
1022
1025{
1026 // TODO: fusionner ce code avec CellToQuadrilateralMerger.
1027
1028 ARCANE_ASSERT(cell2.type() == IT_Hexaedron8,("Cell2 is not a IT_Hexaedron8"));
1029
1031
1032 this->_setCellsNodeNumbers(cell1,cell2);
1033
1034 // Fusion des mailles de côté
1036 for (Integer i = 0; i<faces_to_merge.getNumber(); ++i) {
1038 cell1.face(faces_to_merge.cell1FaceNumber(i)),
1039 cell2.face(faces_to_merge.cell2FaceNumber(i)));
1040 }
1041
1042 // Echange des faces.
1043 swap_utils->swapCellFaces(cell1,cell2,
1044 common_face.cell1LocalNumber(),
1045 (common_face.cell2LocalNumber()+3)%6); // face opposée
1046
1047 // Echange des sommets des mailles
1048 for (Integer i=0, n=m_cell_1_common_node_numbers.size(); i<n; ++i) {
1049 swap_utils->swapCellNodes(cell1,cell2,
1052 }
1053
1054 swap_utils->checkAndChangeFaceOrientation(cell1);
1055}
1056
1057/*---------------------------------------------------------------------------*/
1058/*---------------------------------------------------------------------------*/
1059
1060const Integer
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} };
1063
1064/*---------------------------------------------------------------------------*/
1065/*---------------------------------------------------------------------------*/
1066
1068_typeName(const CellMerger::_Type& t) const
1069{
1070 switch (t) {
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";
1077 }
1078}
1079
1080/*---------------------------------------------------------------------------*/
1081/*---------------------------------------------------------------------------*/
1082
1084_getCellType(const Integer& internal_cell_type) const
1085{
1086 switch(internal_cell_type) {
1087 case IT_Hexaedron8: {
1088 return Hexahedron;
1089 }
1090 case IT_Pyramid5: {
1091 return Pyramid;
1092 }
1093 case IT_Pentaedron6: {
1094 return Pentahedron;
1095 }
1096 case IT_Quad4: {
1097 return Quadrilateral;
1098 }
1099 case IT_Triangle3: {
1100 return Triangle;
1101 }
1102 default: {
1103 return NotMergeable;
1104 }
1105 }
1106}
1107
1108/*---------------------------------------------------------------------------*/
1109/*---------------------------------------------------------------------------*/
1110
1112_promoteType(const _Type& t1,const _Type& t2) const
1113{
1114 switch(t1*t2) {
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;
1120 default:
1121 ARCANE_FATAL("Can not merge cells of type {0} and {1}",_typeName(t1),_typeName(t2));
1122 }
1123}
1124
1125/*---------------------------------------------------------------------------*/
1126/*---------------------------------------------------------------------------*/
1127
1130{
1132 IMesh* mesh = i_cell_1.itemFamily()->mesh();
1134
1135 switch (cell_1_type) {
1136 case Hexahedron:
1137 case Pyramid:
1138 case Pentahedron:
1139 {
1141 return;
1142 }
1143 case Quadrilateral:
1144 case Triangle:{
1145 {
1147 return;
1148 }
1149 }
1150 case NotMergeable: {
1151 ARCANE_FATAL("Impossible to merge the entities !\n");
1152 }
1153 }
1154 ARCANE_FATAL("Merge for this kind of cell not implemented\n");
1155}
1156
1157/*---------------------------------------------------------------------------*/
1158/*---------------------------------------------------------------------------*/
1159
1162{
1165
1167
1168 switch (merged_cell_type) {
1169 case Hexahedron: {
1170 return i_cell_1;
1171 }
1172 case Pyramid:
1173 case Pentahedron: {
1174 if (cell_2_type == Hexahedron) {
1175 return i_cell_1;
1176 } else {
1177 return i_cell_2;
1178 }
1179 }
1180 case Quadrilateral: {
1181 return i_cell_1;
1182 }
1183 case Triangle: {
1184 if (cell_2_type == Quadrilateral) {
1185 return i_cell_1;
1186 } else {
1187 return i_cell_2;
1188 }
1189 }
1190 case NotMergeable: {
1191 ARCANE_FATAL("Impossible to merge the entities !\n");
1192 }
1193 default:
1194 ARCANE_FATAL("Merge for this kind of cell not implemented\n");
1195 }
1196 return 0;
1197}
1198
1199/*---------------------------------------------------------------------------*/
1200/*---------------------------------------------------------------------------*/
1201
1204{
1205 return ItemCompatibility::_itemInternal(getCell(i_cell_1,i_cell_2));
1206}
1207
1208/*---------------------------------------------------------------------------*/
1209/*---------------------------------------------------------------------------*/
1210
1211} // End namespace Arcane::mesh
1212
1213/*---------------------------------------------------------------------------*/
1214/*---------------------------------------------------------------------------*/
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
Types et macros pour itérer sur les entités du maillage.
Tableau d'items de types quelconques.
Maille d'un maillage.
Definition Item.h:1191
Face face(Int32 i) const
i-ème face de la maille
Definition Item.h:1269
Int32 nbFace() const
Nombre de faces de la maille.
Definition Item.h:1266
ARCANE_DEPRECATED_260 void checkAndChangeOrientation(ItemInternal *face)
Face d'une maille.
Definition Item.h:944
virtual void replaceNode(ItemLocalId item_lid, Integer index, ItemLocalId new_node_lid)=0
Remplace un noeud d'une entité.
virtual void findAndReplaceCell(ItemLocalId item_lid, ItemLocalId old_cell_lid, ItemLocalId new_cell_lid)=0
Remplace une maille d'une entité.
virtual void findAndReplaceFace(ItemLocalId item_lid, ItemLocalId old_face_lid, ItemLocalId new_face_lid)=0
Remplace une face d'une entité.
virtual void replaceFace(ItemLocalId item_lid, Integer index, ItemLocalId new_face_lid)=0
Remplace une face d'une entité.
virtual ITraceMng * traceMng()=0
Gestionnaire de message associé
virtual IItemFamily * nodeFamily()=0
Retourne la famille des noeuds.
virtual IItemFamily * faceFamily()=0
Retourne la famille des faces.
virtual IItemFamily * cellFamily()=0
Retourne la famille des mailles.
Enumérateur sur une liste typée d'entités de type ItemType.
Enumérateur sur une liste d'entités.
Structure interne d'une entité de maillage.
Lecteur des fichiers de maillage via la bibliothèque LIMA.
Definition Lima.cc:149
_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 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.
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).
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
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
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.
Definition CellMerger.cc:46
void swapFaceNodes(Face face_1, Face face_2, Integer face1_node_idx, Integer face2_node_idx)
Échange deux noeuds entre deux faces.
Definition CellMerger.cc:65
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.
Definition CellMerger.cc:84
Integer size() const
Nombre d'éléments du vecteur.
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.
Chaîne de caractères unicode.
Vecteur 1D de données avec sémantique par valeur (style STL).
Integer toInteger(Real r)
Converti un Int64 en un Integer.