Arcane  v3.15.3.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
FaceFamily.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/* FaceFamily.cc (C) 2000-2025 */
9/* */
10/* Famille de faces. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/mesh/FaceFamily.h"
15
16#include "arcane/utils/FatalErrorException.h"
17#include "arcane/utils/NotImplementedException.h"
18#include "arcane/utils/String.h"
19#include "arcane/utils/OStringStream.h"
20
21#include "arcane/mesh/NodeFamily.h"
22#include "arcane/mesh/EdgeFamily.h"
23#include "arcane/mesh/IncrementalItemConnectivity.h"
24#include "arcane/mesh/CompactIncrementalItemConnectivity.h"
25#include "arcane/mesh/ItemConnectivitySelector.h"
26#include "arcane/mesh/AbstractItemFamilyTopologyModifier.h"
27#include "arcane/mesh/ConnectivityNewWithDependenciesTypes.h"
28#include "arcane/mesh/NewWithLegacyConnectivity.h"
29#include "arcane/mesh/FaceReorienter.h"
30
31#include "arcane/IMesh.h"
32#include "arcane/ITiedInterface.h"
33#include "arcane/TiedFace.h"
34#include "arcane/ItemEnumerator.h"
35#include "arcane/ItemPrinter.h"
36#include "arcane/Connectivity.h"
37
39#include "arcane/GeometricUtilities.h"
40#include "arcane/SharedVariable.h"
41
42/*---------------------------------------------------------------------------*/
43/*---------------------------------------------------------------------------*/
44
45namespace Arcane::mesh
46{
47
48/*---------------------------------------------------------------------------*/
49/*---------------------------------------------------------------------------*/
50
53{
54 public:
55
56 explicit TopologyModifier(FaceFamily* f)
57 : AbstractItemFamilyTopologyModifier(f), m_true_family(f){}
58 void replaceNode(ItemLocalId item_lid,Integer index,ItemLocalId new_lid) override
59 {
60 m_true_family->replaceNode(item_lid,index,new_lid);
61 }
62 void replaceEdge(ItemLocalId item_lid,Integer index,ItemLocalId new_lid) override
63 {
64 m_true_family->replaceEdge(item_lid,index,new_lid);
65 }
66 void replaceFace(ItemLocalId item_lid,Integer index,ItemLocalId new_lid) override
67 {
68 m_true_family->replaceFace(item_lid,index,new_lid);
69 }
70 void replaceCell(ItemLocalId item_lid,Integer index,ItemLocalId new_lid) override
71 {
72 m_true_family->replaceCell(item_lid,index,new_lid);
73 }
76 {
77 Face face(m_true_family->_itemInternal(face_lid));
79 }
80
81 private:
82
83 FaceFamily* m_true_family = nullptr;
84};
85
86/*---------------------------------------------------------------------------*/
87/*---------------------------------------------------------------------------*/
88
89FaceFamily::
90FaceFamily(IMesh* mesh,const String& name)
91: ItemFamily(mesh,IK_Face,name)
92{
93 _setTopologyModifier(new TopologyModifier(this));
94}
95
96/*---------------------------------------------------------------------------*/
97/*---------------------------------------------------------------------------*/
98
99FaceFamily::
100~FaceFamily()
101{
102}
103
104/*---------------------------------------------------------------------------*/
105/*---------------------------------------------------------------------------*/
106
107void FaceFamily::
108build()
109{
110 ItemFamily::build();
111
112 m_node_family = ARCANE_CHECK_POINTER(dynamic_cast<NodeFamily*>(m_mesh->nodeFamily()));
113 m_edge_family = ARCANE_CHECK_POINTER(dynamic_cast<EdgeFamily*>(m_mesh->edgeFamily()));
114
115 if (m_mesh->useMeshItemFamilyDependencies()) // temporary to fill legacy, even with family dependencies
116 {
117 m_node_connectivity = dynamic_cast<NewWithLegacyConnectivityType<FaceFamily,NodeFamily>::type*>(m_mesh->itemFamilyNetwork()->getConnectivity(this,mesh()->nodeFamily(),connectivityName(this,mesh()->nodeFamily())));
118 m_edge_connectivity = dynamic_cast<NewWithLegacyConnectivityType<FaceFamily,EdgeFamily>::type*>(m_mesh->itemFamilyNetwork()->getConnectivity(this,mesh()->edgeFamily(),connectivityName(this,mesh()->edgeFamily())));
119 m_face_connectivity = dynamic_cast<NewWithLegacyConnectivityType<FaceFamily,FaceFamily>::type*>(m_mesh->itemFamilyNetwork()->getConnectivity(this,mesh()->faceFamily(),connectivityName(this,mesh()->faceFamily())));
120 m_cell_connectivity = dynamic_cast<NewWithLegacyConnectivityType<FaceFamily,CellFamily>::type*>(m_mesh->itemFamilyNetwork()->getConnectivity(this,mesh()->cellFamily(),connectivityName(this,mesh()->cellFamily())));
121 }
122 else
123 {
124 m_node_connectivity = new NodeConnectivity(this,mesh()->nodeFamily(),"FaceNode");
125 m_edge_connectivity = new EdgeConnectivity(this,mesh()->edgeFamily(),"FaceEdge");
126 m_face_connectivity = new FaceConnectivity(this,mesh()->faceFamily(),"FaceFace");
127 m_cell_connectivity = new CellConnectivity(this,mesh()->cellFamily(),"FaceCell");
128 }
129 m_hparent_connectivity = new HParentConnectivity(this, this, "HParentFace");
130 m_hchild_connectivity = new HChildConnectivity(this, this, "HChildFace");
131
132 _addConnectivitySelector(m_node_connectivity);
133 _addConnectivitySelector(m_edge_connectivity);
134 _addConnectivitySelector(m_face_connectivity);
135 _addConnectivitySelector(m_cell_connectivity);
136 _addConnectivitySelector(m_hparent_connectivity);
137 _addConnectivitySelector(m_hchild_connectivity);
138
139 _buildConnectivitySelectors();
140}
141
142/*---------------------------------------------------------------------------*/
143/*---------------------------------------------------------------------------*/
144
145inline void FaceFamily::
146_createOne(ItemInternal* item,Int64 uid,ItemTypeInfo* type)
147{
148 m_item_internal_list->faces = _itemsInternal();
149 _allocateInfos(item,uid,type);
150 auto nc = m_node_connectivity->trueCustomConnectivity();
151 if (nc)
152 nc->addConnectedItems(ItemLocalId(item),type->nbLocalNode());
153}
154
155/*---------------------------------------------------------------------------*/
156/*---------------------------------------------------------------------------*/
157
158inline void FaceFamily::
159_createOne(ItemInternal* item,Int64 uid,ItemTypeId type_id)
160{
161 _createOne(item,uid,_itemTypeMng()->typeFromId(type_id));
162}
163
164/*---------------------------------------------------------------------------*/
165/*---------------------------------------------------------------------------*/
175{
176 ++mesh_info.nbFace();
177 return allocOne(uid,type_id);
178}
179
180/*---------------------------------------------------------------------------*/
181/*---------------------------------------------------------------------------*/
186allocOne(Int64 uid,ItemTypeInfo* type)
187{
188 ItemInternal* item = _allocOne(uid);
189 _createOne(item,uid,type);
190 return item;
191}
192
193/*---------------------------------------------------------------------------*/
194/*---------------------------------------------------------------------------*/
207{
208 auto face = findOrAllocOne(uid,type_id,is_alloc);
209 if (is_alloc)
210 ++mesh_info.nbFace();
211 return face;
212}
213
214/*---------------------------------------------------------------------------*/
215/*---------------------------------------------------------------------------*/
223findOrAllocOne(Int64 uid,ItemTypeInfo* type,bool& is_alloc)
224{
225 ItemInternal* item = _findOrAllocOne(uid,is_alloc);
226 if (is_alloc){
227 _createOne(item,uid,type);
228 }
229 return item;
230}
231
232/*---------------------------------------------------------------------------*/
233/*---------------------------------------------------------------------------*/
234
236allocOne(Int64 uid,ItemTypeId type_id)
237{
238 ItemInternal* item = _allocOne(uid);
239 _createOne(item,uid,type_id);
240 return item;
241}
242
243/*---------------------------------------------------------------------------*/
244/*---------------------------------------------------------------------------*/
245
248{
249 ItemInternal* item = _findOrAllocOne(uid,is_alloc);
250 if (is_alloc){
251 _createOne(item,uid,type_id);
252 }
253 return item;
254}
255
256/*---------------------------------------------------------------------------*/
257/*---------------------------------------------------------------------------*/
258
259void FaceFamily::
260preAllocate(Integer nb_item)
261{
262 if (!m_has_face)
263 return;
264 // On ne préalloue pas par défaut car on ne souhaite pas pré-allouer
265 // pour la connectivité face->face car c'est dernière n'est utilisée que
266 // s'il y a des TiedInterface et cela n'est pas fréquent.
267 // Du coup on pré-alloue explicitement les connectivités qu'on souhaite.
268 this->_preAllocate(nb_item,false);
269 m_node_connectivity->trueCustomConnectivity()->reserveMemoryForNbSourceItems(nb_item,true);
270 if (Connectivity::hasConnectivity(m_mesh_connectivity,Connectivity::CT_HasEdge))
271 m_edge_connectivity->trueCustomConnectivity()->reserveMemoryForNbSourceItems(nb_item,true);
272 m_cell_connectivity->trueCustomConnectivity()->reserveMemoryForNbSourceItems(nb_item,true);
273}
274
275/*---------------------------------------------------------------------------*/
276/*---------------------------------------------------------------------------*/
277
280{
281 debug() << "Creating the list of ghosts faces";
283}
284
285/*---------------------------------------------------------------------------*/
286/*---------------------------------------------------------------------------*/
292replaceNode(ItemLocalId face,Integer index,ItemLocalId node)
293{
294 m_node_connectivity->replaceItem(face,index,node);
295}
296
297/*---------------------------------------------------------------------------*/
298/*---------------------------------------------------------------------------*/
304replaceEdge(ItemLocalId face,Integer index,ItemLocalId edge)
305{
306 m_edge_connectivity->replaceItem(face,index,edge);
307}
308
309/*---------------------------------------------------------------------------*/
310/*---------------------------------------------------------------------------*/
316replaceFace(ItemLocalId face,Integer index,ItemLocalId face2)
317{
318 m_face_connectivity->replaceItem(face,index,face2);
319}
320
321/*---------------------------------------------------------------------------*/
322/*---------------------------------------------------------------------------*/
328replaceCell(ItemLocalId face,Integer index,ItemLocalId cell)
329{
330 m_cell_connectivity->replaceItem(face,index,cell);
331}
332
333/*---------------------------------------------------------------------------*/
334/*---------------------------------------------------------------------------*/
345{
349 auto c = m_cell_connectivity->trueCustomConnectivity();
350 if (c){
352 // Supprime toutes les mailles connectées.
353 // TODO: optimiser en ne supprimant pas s'il n'y a pas besoin pour éviter
354 // des réallocations.
355 c->removeConnectedItems(face_lid);
356 if (front_cell_lid==NULL_ITEM_LOCAL_ID){
357 if (back_cell_lid!=NULL_ITEM_LOCAL_ID){
358 // Reste uniquement la back_cell ou aucune maille.
359 c->IncrementalItemConnectivity::addConnectedItem(face_lid,back_cell_lid); // add the class name for the case of Face to Cell connectivity. The class is overridden to handle family dependencies but the base method must be called here.
360 }
361 // Ici reste aucune maille mais comme on a tout supprimé il n'y a rien
362 // à faire.
363 }
364 else if (back_cell_lid==NULL_ITEM_LOCAL_ID){
365 // Reste uniquement la front cell
366 c->IncrementalItemConnectivity::addConnectedItem(face_lid,front_cell_lid);
367 }
368 else{
369 // Il y a deux mailles connectées. La back_cell est toujours la première.
370 c->IncrementalItemConnectivity::addConnectedItem(face_lid,back_cell_lid);
371 c->IncrementalItemConnectivity::addConnectedItem(face_lid,front_cell_lid);
372 }
373 }
374}
375
376/*---------------------------------------------------------------------------*/
377/*---------------------------------------------------------------------------*/
378
381{
382 _checkValidSourceTargetItems(face,new_cell);
383
384 Integer nb_cell = face.nbCell();
385
386 // SDP: les tests suivants sont imcompatibles avec le raffinement
387 // par couches
389 Cell current_cell = face.backCell();
391 ARCANE_FATAL("Face already having a back cell."
392 " This is most probably due to the fact that the face"
393 " is connected to a reverse cell with a negative volume."
394 " Face={0}. new_cell={1} current_cell={2}",FullItemPrinter(face),
396 }
397 }
398
399 if (nb_cell>=2)
400 ARCANE_FATAL("face '{0}' already has two cells",FullItemPrinter(face));
401
402 _updateSharedInfo();
403
404 // Si on a déjà une maille, il s'agit de la front cell.
405 Int32 front_cell_lid = (nb_cell==1) ? face.cellId(0) : NULL_ITEM_LOCAL_ID;
407}
408
409/*---------------------------------------------------------------------------*/
410/*---------------------------------------------------------------------------*/
411
414{
415 _checkValidSourceTargetItems(face,new_cell);
416
417 Integer nb_cell = face.nbCell();
418
419 // SDP: les tests suivants sont imcompatibles avec le raffinement
420 // par couches
422 Cell current_cell = face.frontCell();
424 ARCANE_FATAL("Face already having a front cell."
425 " This is most probably due to the fact that the face"
426 " is connected to a reverse cell with a negative volume."
427 " Face={0}. new_cell={1} current_cell={2}",FullItemPrinter(face),
429 }
430 }
431
432 if (nb_cell>=2)
433 ARCANE_FATAL("face '{0}' already has two cells",FullItemPrinter(face));
434
435 _updateSharedInfo();
436
437 // Si on a déjà une maille, il s'agit de la back cell.
438 Int32 back_cell_lid = (nb_cell==1) ? face.cellId(0) : NULL_ITEM_LOCAL_ID;
440}
441
443/*---------------------------------------------------------------------------*/
444/*---------------------------------------------------------------------------*/
445
448{
449 ARCANE_ASSERT((face.nbCell() ==2),("Face should have back and front cells"));
450
451 Cell current_cell = face.backCell();
453}
454
455/*---------------------------------------------------------------------------*/
456/*---------------------------------------------------------------------------*/
457
458void FaceFamily::
459replaceFrontCellToFace(Face face,ItemLocalId new_cell)
460{
461 ARCANE_ASSERT((face.nbCell() ==2),("Face should have back and front cells"));
462
463 Cell current_cell = face.frontCell();
465}
466
467/*---------------------------------------------------------------------------*/
468/*---------------------------------------------------------------------------*/
469
470void FaceFamily::
471addBackFrontCellsFromParentFace(Face subface,Face face)
472{
473 Cell fcell= face.frontCell();
474 Cell bcell= face.backCell();
475
476 if (subface.itemBase().flags() & ItemFlags::II_HasBackCell){
477 if(fcell.isActive())
479 else if(bcell.isActive())
481 }
482 else if (subface.itemBase().flags() & ItemFlags::II_HasFrontCell){
483 if(bcell.isActive())
484 addBackCellToFace(subface,face.backCell());
485 else if (fcell.isActive())
486 addBackCellToFace(subface,face.frontCell());
487 }
488 ARCANE_ASSERT((subface.backCell() != subface.frontCell()),("back front cells error"));
489}
490
491/*---------------------------------------------------------------------------*/
492/*---------------------------------------------------------------------------*/
493
494void FaceFamily::
495replaceBackFrontCellsFromParentFace(Cell subcell,Face subface,
496 Cell cell,Face face)
497{
498 Cell fscell= subface.frontCell();
499 Cell bscell= subface.backCell();
500 Cell fcell= face.frontCell();
501 Cell bcell= face.backCell();
502 if (fscell.localId()==subcell.localId()) {
503 if(fcell.localId()==cell.localId()) {
504 if(bcell.level()>bscell.level()) {
505 replaceBackCellToFace(subface,bcell);
506 }
507 }
508 else {
509 if(fcell.level() > bscell.level()){
510 replaceBackCellToFace(subface,fcell);
511 }
512 }
513 }
514 else {
515 if (fcell.localId()==cell.localId()){
516 if (bcell.level() > fscell.level()){
517 replaceFrontCellToFace(subface,bcell);
518 }
519 }
520 else{
521 if(fcell.level()>fscell.level()){
522 replaceFrontCellToFace(subface,fcell);
523 }
524 }
525 }
526}
527
528/*---------------------------------------------------------------------------*/
529/*---------------------------------------------------------------------------*/
530
531bool FaceFamily::
532isSubFaceInFace(Face subface,Face face) const
533{
534 const Real tol= 1e-02;
535 bool is_true= false;
536
537 //TODO : un std::binary_search pour accelerer la recherche
538 for( Node inode : subface.nodes() ){
539 for( Node inode2 : face.nodes() ){
540 if (inode.uniqueId() == inode2.uniqueId()) {// il suffit qu'un seul noeud concide
541 is_true = true;
542 break;
543 }
544 }
545 }
546 if (!is_true)
547 return false;
548
549 SharedVariableNodeReal3 orig_nodes_coords(mesh()->sharedNodesCoordinates());
550 Real3 normal_face = _computeFaceNormal(face,orig_nodes_coords);
551 Real3 normal_subface = _computeFaceNormal(subface,orig_nodes_coords);
552 Real ps = math::dot(normal_face,normal_subface);
553 Real residual = math::abs(ps)-1.;
554 return math::abs(residual) < tol ? true: false;
555}
556
557/*---------------------------------------------------------------------------*/
558/*---------------------------------------------------------------------------*/
559
560bool FaceFamily::
561isChildOnFace(ItemWithNodes child,Face face) const
562{
563 //TODO : un std::binary_search pour accelerer la recherche
564 for( Node inode : face.nodes() ){
565 for( Node inode2 : child.nodes() ){
566 if (inode.uniqueId() == inode2.uniqueId()) // il suffit qu'un seul noeud concide
567 return true;
568 }
569 }
570 return false;
571}
572
573/*---------------------------------------------------------------------------*/
574/*---------------------------------------------------------------------------*/
575
576void FaceFamily::
577subFaces(Face face,Array<ItemInternal*>& subfaces)
578{
579 Cell cell;
580 const Integer nb_cell= face.nbCell();
581
582 if (nb_cell == 2) {
583 Cell fcell = face.frontCell();
584 cell = (fcell.hasHChildren()) ? face.frontCell() : face.backCell();
585 }
586 else
587 cell = face.cell(0);
588
589 for( Integer c=0;c<cell.nbHChildren();c++){
590 Cell child = cell.hChild(c);
591 if (isChildOnFace(child,face)){
592 //debug() << "current FACE:" << FullItemPrinter(face)
593 //<< "\n current child CELL:" << FullItemPrinter(child)
594 //<< "\n";
595 for( Face subface : child.faces() ){
596 if(isSubFaceInFace(subface,face)){
597 subfaces.add(ItemCompatibility::_itemInternal(subface));
598 }
599 }
600 }
601 }
602 //info() << "\n SUBFACE NB= " << subfaces.size();
603}
604
605/*---------------------------------------------------------------------------*/
606/*---------------------------------------------------------------------------*/
607
608void FaceFamily::
609allSubFaces(Face face,Array<ItemInternal*>& subfaces)
610{
611 subfaces.add(ItemCompatibility::_itemInternal(face));
612
613 Cell cell;
614 const Integer nb_cell= face.nbCell();
615 if (nb_cell == 2){
616 Cell fcell= face.frontCell();
617 if(fcell.hasHChildren() && fcell.isOwn())
618 cell = face.frontCell() ;
619 else
620 cell = face.backCell();
621 }
622 else{
623 cell= face.cell(0);
624 }
625
626 for(Integer c=0;c<cell.nbHChildren();c++){
627 Cell child = cell.hChild(c);
628 if (isChildOnFace(child,face)){
629 for( Face subface : child.faces() ){
630 if(isSubFaceInFace(subface,face)){
631 allSubFaces(subface,subfaces);
632 }
633 }
634 }
635 }
636}
637
638/*---------------------------------------------------------------------------*/
639/*---------------------------------------------------------------------------*/
640
641void FaceFamily::
642activeSubFaces(Face face,Array<ItemInternal*>& subfaces)
643{
644 Cell cell;
645 const Integer nb_cell= face.nbCell();
646
647 if(nb_cell==2) {
648 Cell fcell = face.frontCell();
649 Cell bcell = face.backCell();
650 if(fcell.level() > bcell.level())
651 cell = face.frontCell();
652 else {
653 if(bcell.isOwn())
654 cell= face.backCell();
655 else
656 cell= face.frontCell();
657 }
658 }
659 else {
660 cell = face.cell(0);
661 }
662 Cell pcell = cell.topHParent();
663
664 UniqueArray<ItemInternal*> cell_family;
665 activeFamilyTree (cell_family,pcell);
666 for(Integer c=0;c<cell_family.size();c++){
667 Cell child = cell_family[c];
668 if(isChildOnFace(child,face)){
669 //debug() << "current FACE:" << FullItemPrinter(face)
670 //<< "\n current child CELL:" << FullItemPrinter(child)
671 //<< "\n";
672 for( Face subface : child.faces() ){
673 if(isSubFaceInFace(subface,face)){
674 subfaces.add(ItemCompatibility::_itemInternal(subface));
675 }
676 }
677 }
678 }
679 //info() << "\n SUBFACE NB= " << subfaces.size();
680}
681
682/*---------------------------------------------------------------------------*/
683/*---------------------------------------------------------------------------*/
684
685void FaceFamily::
686familyTree(Array<ItemInternal*>& family,Cell item,
687 const bool reset) const
688{
689 ARCANE_ASSERT((!item.isSubactive()),("The family tree doesn't include subactive items"));
690 // Clear the array if the flag reset tells us to.
691 if (reset)
692 family.clear();
693 // Add this item to the family tree.
694 family.add(ItemCompatibility::_itemInternal(item));
695 // Recurse into the items children, if it has them.
696 // Do not clear the array any more.
697 if (!item.isActive())
698 for (Integer c=0, cs=item.nbHChildren(); c<cs; c++){
699 Cell ichild= item.hChild(c);
700 familyTree (family,ichild, false);
701 }
702}
703
704/*---------------------------------------------------------------------------*/
705/*---------------------------------------------------------------------------*/
706
707void FaceFamily::
708activeFamilyTree(Array<ItemInternal*>& family,Cell item,const bool reset) const
709{
710 ARCANE_ASSERT((!item.isSubactive()),("The family tree doesn't include subactive items"));
711 // Clear the array if the flag reset tells us to.
712 if (reset)
713 family.clear();
714 // Add this item to the family tree.
715 if(item.isActive())
716 family.add(ItemCompatibility::_itemInternal(item));
717 else
718 for (Integer c=0, cs=item.nbHChildren(); c<cs; c++){
719 Cell ichild= item.hChild(c);
720 if (ichild.isOwn())
721 activeFamilyTree(family,ichild,false);
722 }
723
724}
725
726/*---------------------------------------------------------------------------*/
727/*---------------------------------------------------------------------------*/
728
729void FaceFamily::
730_addParentFaceToFace(Face parent_face, Face child_face)
731{
732 m_hparent_connectivity->addConnectedItem(ItemLocalId(child_face), ItemLocalId(parent_face));
733}
734
735/*---------------------------------------------------------------------------*/
736/*---------------------------------------------------------------------------*/
737
738void FaceFamily::
739_addChildFaceToFace(Face parent_face, Face child_face)
740{
741 m_hchild_connectivity->addConnectedItem(ItemLocalId(parent_face), ItemLocalId(child_face));
742}
743
744// OFF AMR
745
746/*---------------------------------------------------------------------------*/
747/*---------------------------------------------------------------------------*/
748
751{
752 if (!Connectivity::hasConnectivity(m_mesh_connectivity,Connectivity::CT_FaceToEdge))
753 return;
754
755 _checkValidSourceTargetItems(face,new_edge);
756 m_edge_connectivity->addConnectedItem(ItemLocalId(face),ItemLocalId(new_edge));;
757}
758
759/*---------------------------------------------------------------------------*/
760/*---------------------------------------------------------------------------*/
761
764{
765 if (!Connectivity::hasConnectivity(m_mesh_connectivity,Connectivity::CT_FaceToEdge))
766 return;
767
768 _checkValidSourceTargetItems(face,edge_to_remove);
769 m_edge_connectivity->removeConnectedItem(ItemLocalId(face),ItemLocalId(edge_to_remove));
770}
771
772/*---------------------------------------------------------------------------*/
773/*---------------------------------------------------------------------------*/
774
775inline void FaceFamily::
776_removeFace(Face face)
777{
778 ItemLocalId face_lid = face;
779 for( Int32 edge : face.edgeIds() )
780 m_edge_family->removeFaceFromEdge(ItemLocalId(edge),face_lid);
781 for( Int32 node : face.nodeIds() )
782 m_node_family->removeFaceFromNode(ItemLocalId(node),face_lid);
783 _removeOne(face);
784 // On ne supprime pas ici les autres relations (ici aucune)
785 // Car l'autre de suppression doit toujours être cell, face, edge, node
786 // donc node est en dernier et tout est déjà fait
787 // Par ailleurs, cela évite des problèmes de récursivité
788}
789
790/*---------------------------------------------------------------------------*/
791/*---------------------------------------------------------------------------*/
792
793Real3 FaceFamily::
794_computeFaceNormal(Face face, const SharedVariableNodeReal3& nodes_coord) const
795{
796 Real3 normal_face = Real3::zero();
797 Integer nb_node= face.nbNode();
799 for( Integer i=0; i<nb_node; ++i ){
800 cord_face[i] = nodes_coord[face.node(i)];
801 }
802 switch(nb_node)
803 {
804 case(4):
805 {
806 GeometricUtilities::QuadMapping face_mapping;
807 face_mapping.m_pos[0] = cord_face[0];
808 face_mapping.m_pos[1] = cord_face[1];
809 face_mapping.m_pos[2] = cord_face[2];
810 face_mapping.m_pos[3] = cord_face[3];
811 normal_face= face_mapping.normal();
812 }
813 break ;
814 case(3):
815 {
816 Real3 v1 = cord_face[1] - cord_face[0];
817 Real3 v2 = cord_face[2] - cord_face[0];
818 normal_face = math::vecMul(v1,v2).normalize();
819 }
820 break ;
821 case(2):
822 {
823 normal_face=cord_face[0]-cord_face[1];
824 normal_face.normalize();
825 }
826 break ;
827 default: ARCANE_FATAL("This kind of face is not handled");
828 }
829 return normal_face;
830}
831
832/*---------------------------------------------------------------------------*/
833/*---------------------------------------------------------------------------*/
834
837{
838 _checkValidItem(face);
839
840 Integer nb_cell = face.nbCell();
841
842#ifdef ARCANE_CHECK
843 if (face.itemBase().isSuppressed())
844 ARCANE_FATAL("Can not remove cell from destroyed face={0}",ItemPrinter(face));
845 if (nb_cell==0)
846 ARCANE_FATAL("Can not remove cell lid={0} from face uid={1} with no cell connected",
848#endif /* ARCANE_CHECK */
849
850 Integer nb_cell_after = nb_cell-1;
851 const Int32 null_cell_lid = NULL_ITEM_LOCAL_ID;
853 // forcer la suppression d'une face entre deux mailles de niveaux differents
854 // car cette face n'est topologiquement attachée a la maille de niveau inferieur
855 if (nb_cell == 2){
856 if(face.backCell().level() != face.frontCell().level())
857 nb_cell_after = 0;
858 else if (! (face.backCell().isActive() && face.frontCell().isActive())){
859 // TODO: GG: pour des raisons de performance, il est préférable d'éviter
860 // les allocations dans cette méthode car elle est appelée très souvent.
862 subFaces(face,subfaces);
863 for(Integer s=0,ss=subfaces.size();s<ss;s++){
865 Int32 cell0 = face2->cellId(0);
866 Int32 cell1 = face2->cellId(1);
867 // On avait obligatoirement deux mailles connectées avant,
868 // donc la back_cell est la maille 0, la front cell la maille 1
870 // Reste la front cell
872 }
873 else{
874 // Reste la back cell
876 }
877 _updateSharedInfo();
878 }
879 }
880 }
881 // OFF AMR
882 if (nb_cell_after!=0){
883 Int32 cell0 = face.cellId(0);
884 Int32 cell1 = face.cellId(1);
885 // On avait obligatoirement deux mailles connectées avant,
886 // donc la back_cell est la maille 0, la front cell la maille 1
888 // Reste la front cell
890 }
891 else{
892 // Reste la back cell
894 }
895 }
896 else{
898 }
899
900 _updateSharedInfo();
901}
902
903/*---------------------------------------------------------------------------*/
904/*---------------------------------------------------------------------------*/
905
908{
909 _checkValidItem(face);
910
911 if (!face.itemBase().isSuppressed() && face.nbCell()==0){
912 _removeFace(face);
913 }
914}
915
916/*---------------------------------------------------------------------------*/
917/*---------------------------------------------------------------------------*/
918
919void FaceFamily::
920_addMasterFaceToFace(Face face,Face master_face)
921{
922 m_face_connectivity->addConnectedItem(face,master_face);
924}
925
926/*---------------------------------------------------------------------------*/
927/*---------------------------------------------------------------------------*/
928
929void FaceFamily::
931{
932 Integer nb_slave = slave_faces_lid.size();
933 for( Integer i=0; i<nb_slave; ++i )
934 m_face_connectivity->addConnectedItem(master_face,ItemLocalId(slave_faces_lid[i]));
935 master_face.mutableItemBase().addFlags(ItemFlags::II_MasterFace);
936}
937
938/*---------------------------------------------------------------------------*/
939/*---------------------------------------------------------------------------*/
940
941void FaceFamily::
942_removeMasterFaceToFace(Face face)
943{
944 m_face_connectivity->removeConnectedItems(face);
945 face.mutableItemBase().removeFlags(ItemFlags::II_SlaveFace);
946}
947
948/*---------------------------------------------------------------------------*/
949/*---------------------------------------------------------------------------*/
950
951void FaceFamily::
952_removeSlaveFacesToFace(Face master_face)
953{
954 m_face_connectivity->removeConnectedItems(master_face);
955 master_face.mutableItemBase().removeFlags(ItemFlags::II_MasterFace);
956}
957
958/*---------------------------------------------------------------------------*/
959/*---------------------------------------------------------------------------*/
960
963{
966
969 Integer index = imaster_face.index();
971 Integer nb_slave = slave_tied_faces.size();
972 slave_faces.clear();
973 for( Integer zz=0; zz<nb_slave; ++zz ){
974 const TiedFace& tn = tied_faces[index][zz];
975 Face slave_face = tn.face();
976 slave_faces.add(slave_face.localId());
977 _addMasterFaceToFace(slave_face,master_face);
978 }
979 _addSlaveFacesToFace(master_face,slave_faces);
980 }
981}
982
983/*---------------------------------------------------------------------------*/
984/*---------------------------------------------------------------------------*/
985
988{
990
993 Integer index = imaster_face.index();
995 Integer nb_slave = slave_tied_faces.size();
996 for( Integer zz=0; zz<nb_slave; ++zz ){
997 const TiedFace& tn = tied_faces[index][zz];
998 Face slave_face = tn.face();
999 _removeMasterFaceToFace(slave_face);
1000 }
1001 _removeSlaveFacesToFace(master_face);
1002 }
1003}
1004
1005/*---------------------------------------------------------------------------*/
1006/*---------------------------------------------------------------------------*/
1007
1008void FaceFamily::
1009setConnectivity(const Integer c)
1010{
1011 m_mesh_connectivity = c;
1012 m_has_face = Connectivity::hasConnectivity(m_mesh_connectivity,Connectivity::CT_HasFace);
1013 if (m_has_face){
1014 m_node_prealloc = Connectivity::getPrealloc(m_mesh_connectivity,IK_Face,IK_Node);
1015 if (Connectivity::hasConnectivity(m_mesh_connectivity,Connectivity::CT_HasEdge))
1016 m_edge_prealloc = Connectivity::getPrealloc(m_mesh_connectivity,IK_Face,IK_Edge);
1017 m_face_connectivity->setPreAllocatedSize(4);
1018 m_cell_prealloc = Connectivity::getPrealloc(m_mesh_connectivity,IK_Face,IK_Cell);
1019 m_node_connectivity->setPreAllocatedSize(m_node_prealloc);
1020 m_cell_connectivity->setPreAllocatedSize(m_cell_prealloc);
1021 debug() << "Family " << name() << " prealloc "
1022 << m_node_prealloc << " by node, "
1023 << m_edge_prealloc << " by edge, "
1024 << m_cell_prealloc << " by cell.";
1025 }
1026}
1027
1028/*---------------------------------------------------------------------------*/
1029/*---------------------------------------------------------------------------*/
1030
1031void FaceFamily::
1032reorientFacesIfNeeded()
1033{
1034 // Réoriente les faces si nécessaire. Cela est le cas par exemple si on
1035 // a changé la numérotation des uniqueId() des noeuds.
1036 mesh::FaceReorienter face_reorienter(mesh());
1037 ENUMERATE_ (Face, iface, allItems()) {
1038 face_reorienter.checkAndChangeOrientationAMR(*iface);
1039 }
1040}
1041
1042/*---------------------------------------------------------------------------*/
1043/*---------------------------------------------------------------------------*/
1044
1045} // End namespace Arcane::mesh
1046
1047/*---------------------------------------------------------------------------*/
1048/*---------------------------------------------------------------------------*/
#define ARCANE_CHECK_POINTER(ptr)
Macro retournant le pointeur ptr s'il est non nul ou lancant une exception s'il est nul.
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
#define ENUMERATE_FACE(name, group)
Enumérateur générique d'un groupe de faces.
#define ENUMERATE_(type, name, group)
Enumérateur générique d'un groupe d'entité
Maille d'un maillage.
Definition Item.h:1191
bool isActive() const
Definition Item.h:1320
Int32 level() const
Definition Item.h:1342
Arête d'une maille.
Definition Item.h:809
Face d'une maille.
Definition Item.h:944
Cell frontCell() const
Maille devant la face (maille nulle si aucune)
Definition Item.h:1620
CellLocalId cellId(Int32 i) const
i-ème maille de la face
Definition Item.h:1028
Int32 nbCell() const
Nombre de mailles de la face (1 ou 2)
Definition Item.h:1019
Cell backCell() const
Maille derrière la face (maille nulle si aucune)
Definition Item.h:1614
virtual void findAndReplaceCell(ItemLocalId item_lid, ItemLocalId old_cell_lid, ItemLocalId new_cell_lid)=0
Remplace une maille d'une entité.
virtual IItemFamily * nodeFamily()=0
Retourne la famille des noeuds.
virtual IItemFamily * edgeFamily()=0
Retourne la famille des arêtes.
virtual IItemFamily * cellFamily()=0
Retourne la famille des mailles.
virtual bool useMeshItemFamilyDependencies() const =0
check if the network itemFamily dependencies is activated
virtual IItemFamilyNetwork * itemFamilyNetwork()=0
Interface du réseau de familles (familles connectées)
Interface d'un classe gérant une semi-conformité du maillage.
virtual TiedInterfaceFaceList tiedFaces() const =0
Liste des informations sur les faces esclaves d'une face maître.
virtual FaceGroup masterInterface() const =0
Groupe contenant les faces maîtres.
bool isSuppressed() const
Vrai si l'entité est supprimée.
Int32 flags() const
Flags de l'entité
@ II_MasterFace
L'entité est une face maître d'une interface.
Definition ItemFlags.h:57
@ II_HasBackCell
L'entité a une maille derrière.
Definition ItemFlags.h:45
@ II_SlaveFace
L'entité est une face esclave d'une interface.
Definition ItemFlags.h:56
@ II_HasFrontCell
L'entité a une maille devant.
Definition ItemFlags.h:44
Structure interne d'une entité de maillage.
Index d'une entité ItemType dans une variable.
Definition ItemLocalId.h:90
Index d'un Item dans une variable.
Definition ItemLocalId.h:41
Classe utilitaire pour imprimer les infos sur une entité.
Definition ItemPrinter.h:35
Type d'une entité (Item).
Definition ItemTypeId.h:32
Infos sur un type d'entité du maillage.
Node node(Int32 i) const
i-ème noeud de l'entité
Definition Item.h:779
Int32 nbNode() const
Nombre de noeuds de l'entité
Definition Item.h:776
Classe de base d'un élément de maillage.
Definition Item.h:83
impl::MutableItemBase mutableItemBase() const
Partie interne modifiable de l'entité.
Definition Item.h:374
constexpr Int32 localId() const
Identifiant local de l'entité dans le sous-domaine du processeur.
Definition Item.h:219
ItemUniqueId uniqueId() const
Identifiant unique sur tous les domaines.
Definition Item.h:225
impl::ItemBase itemBase() const
Partie interne de l'entité.
Definition Item.h:363
Lecteur des fichiers de maillage via la bibliothèque LIMA.
Definition Lima.cc:149
void _setFaceBackAndFrontCells(Int32 back_cell_lid, Int32 front_cell_lid)
Pour une face, positionne à la fois la back cell et la front cell.
void addFlags(Int32 added_flags)
Ajoute les flags \added_flags à ceux de l'entité
Classe gérant un vecteur de réel de dimension 3.
Definition Real3.h:132
Face semi-conforme du maillage.
Definition TiedFace.h:35
Modification de la topologie des entités d'une famille.
void replaceCell(ItemLocalId item_lid, Integer index, ItemLocalId new_lid) override
Remplace une maille d'une entité.
Definition FaceFamily.cc:70
void replaceEdge(ItemLocalId item_lid, Integer index, ItemLocalId new_lid) override
Remplace une arête d'une entité.
Definition FaceFamily.cc:62
void replaceNode(ItemLocalId item_lid, Integer index, ItemLocalId new_lid) override
Remplace un noeud d'une entité.
Definition FaceFamily.cc:58
void setBackAndFrontCells(FaceLocalId face_lid, CellLocalId back_cell_lid, CellLocalId front_cell_lid) override
Positionne la maille devant et derrière une face.
Definition FaceFamily.cc:74
void replaceFace(ItemLocalId item_lid, Integer index, ItemLocalId new_lid) override
Remplace une face d'une entité.
Definition FaceFamily.cc:66
Famille de faces.
Definition FaceFamily.h:53
void replaceNode(ItemLocalId face, Integer index, ItemLocalId node)
Remplace le noeud d'index index de la face face avec celui de localId() node_lid.
void setBackAndFrontCells(Face face, Int32 back_cell_lid, Int32 front_cell_lid)
Positionne la maille derrière et devant la face.
NodeFamily * m_node_family
Famille des noeuds associée à cette famille.
Definition FaceFamily.h:158
void removeEdgeFromFace(Face face, Edge edge_to_remove)
Supprime une arête de la face.
void replaceEdge(ItemLocalId face, Integer index, ItemLocalId edge)
Remplace l'arête d'index index de la face face avec celle de localId() edge_lid.
Item allocOne(Int64 uid, ItemTypeId type_id, MeshInfos &mesh_info) override
Alloue une face de numéro unique uid et de type type. Ajout générique d'item.
void applyTiedInterface(ITiedInterface *interface)
Renseigne les informations liées à l'interface liée interface.
Item findOrAllocOne(Int64 uid, ItemTypeId type_id, MeshInfos &mesh_info, bool &is_alloc) override
Récupère ou alloue une face de numéro unique uid et de type type.
EdgeFamily * m_edge_family
Famille d'arêtes associée à cette famille.
Definition FaceFamily.h:161
void removeCellFromFace(Face face, ItemLocalId cell_to_remove_lid)
Supprime une maille de la face.
void replaceCell(ItemLocalId face, Integer index, ItemLocalId cell)
Remplace la maille d'index index de la face face avec celle de localId() cell_lid.
void addFrontCellToFace(Face face, Cell new_cell)
Ajoute une maille devant la face.
bool m_check_orientation
Indique s'il faut vérifier l'orientation.
Definition FaceFamily.h:164
virtual void computeSynchronizeInfos() override
Construit les structures nécessaires à la synchronisation.
void addEdgeToFace(Face face, Edge new_edge)
Ajoute une arête devant la face.
void removeFaceIfNotConnected(Face face)
Supprime la face si elle n'est plus connectée.
void removeTiedInterface(ITiedInterface *interface)
Supprime les informations liées à l'interface liée interface.
void replaceBackCellToFace(Face face, ItemLocalId new_cell)
AMR.
void addBackCellToFace(Face face, Cell new_cell)
Ajoute une maille derrière la face.
void replaceFace(ItemLocalId face, Integer index, ItemLocalId face2)
Remplace la face d'index index de la face face avec celle de localId() face_lid.
Famille d'entités.
Definition ItemFamily.h:76
IMesh * mesh() const override
Maillage associé
IItemFamilyTopologyModifier * _topologyModifier() override
Interface du modificateur de topologie.
Definition ItemFamily.h:388
ItemGroup allItems() const override
Groupe de toutes les entités.
void computeSynchronizeInfos() override
Construit les structures nécessaires à la synchronisation.
String name() const override
Nom de la famille.
Definition ItemFamily.h:130
Classe factorisant des informations sur le maillage.
Definition MeshInfos.h:36
Vue constante d'un tableau de type T.
Chaîne de caractères unicode.
TraceMessageDbg debug(Trace::eDebugLevel=Trace::Medium) const
Flot pour un message de debug.
Vecteur 1D de données avec sémantique par valeur (style STL).
ARCCORE_HOST_DEVICE Real3 vecMul(Real3 u, Real3 v)
Produit vectoriel de u par v. dans .
Definition MathUtils.h:52
ARCCORE_HOST_DEVICE Real dot(Real2 u, Real2 v)
Produit scalaire de u par v dans .
Definition MathUtils.h:96
SharedMeshVariableScalarRefT< Node, Real3 > SharedVariableNodeReal3
Grandeur au noeud de type coordonnées.
@ IK_Node
Entité de maillage de genre noeud.
@ IK_Cell
Entité de maillage de genre maille.
@ IK_Face
Entité de maillage de genre face.
@ IK_Edge
Entité de maillage de genre arête.
Int32 Integer
Type représentant un entier.