Arcane  v3.14.10.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-2024 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-2024 */
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:
56 : AbstractItemFamilyTopologyModifier(f), m_true_family(f){}
57 void replaceNode(ItemLocalId item_lid,Integer index,ItemLocalId new_lid) override
58 {
59 m_true_family->replaceNode(item_lid,index,new_lid);
60 }
61 void replaceEdge(ItemLocalId item_lid,Integer index,ItemLocalId new_lid) override
62 {
63 m_true_family->replaceEdge(item_lid,index,new_lid);
64 }
65 void replaceFace(ItemLocalId item_lid,Integer index,ItemLocalId new_lid) override
66 {
67 m_true_family->replaceFace(item_lid,index,new_lid);
68 }
69 void replaceCell(ItemLocalId item_lid,Integer index,ItemLocalId new_lid) override
70 {
71 m_true_family->replaceCell(item_lid,index,new_lid);
72 }
73 private:
74 FaceFamily* m_true_family;
75};
76
77/*---------------------------------------------------------------------------*/
78/*---------------------------------------------------------------------------*/
79
80FaceFamily::
81FaceFamily(IMesh* mesh,const String& name)
82: ItemFamily(mesh,IK_Face,name)
83{
84 _setTopologyModifier(new TopologyModifier(this));
85}
86
87/*---------------------------------------------------------------------------*/
88/*---------------------------------------------------------------------------*/
89
90FaceFamily::
91~FaceFamily()
92{
93}
94
95/*---------------------------------------------------------------------------*/
96/*---------------------------------------------------------------------------*/
97
98void FaceFamily::
99build()
100{
101 ItemFamily::build();
102
103 m_node_family = ARCANE_CHECK_POINTER(dynamic_cast<NodeFamily*>(m_mesh->nodeFamily()));
104 m_edge_family = ARCANE_CHECK_POINTER(dynamic_cast<EdgeFamily*>(m_mesh->edgeFamily()));
105
106 if (m_mesh->useMeshItemFamilyDependencies()) // temporary to fill legacy, even with family dependencies
107 {
108 m_node_connectivity = dynamic_cast<NewWithLegacyConnectivityType<FaceFamily,NodeFamily>::type*>(m_mesh->itemFamilyNetwork()->getConnectivity(this,mesh()->nodeFamily(),connectivityName(this,mesh()->nodeFamily())));
109 m_edge_connectivity = dynamic_cast<NewWithLegacyConnectivityType<FaceFamily,EdgeFamily>::type*>(m_mesh->itemFamilyNetwork()->getConnectivity(this,mesh()->edgeFamily(),connectivityName(this,mesh()->edgeFamily())));
110 m_face_connectivity = dynamic_cast<NewWithLegacyConnectivityType<FaceFamily,FaceFamily>::type*>(m_mesh->itemFamilyNetwork()->getConnectivity(this,mesh()->faceFamily(),connectivityName(this,mesh()->faceFamily())));
111 m_cell_connectivity = dynamic_cast<NewWithLegacyConnectivityType<FaceFamily,CellFamily>::type*>(m_mesh->itemFamilyNetwork()->getConnectivity(this,mesh()->cellFamily(),connectivityName(this,mesh()->cellFamily())));
112 }
113 else
114 {
115 m_node_connectivity = new NodeConnectivity(this,mesh()->nodeFamily(),"FaceNode");
116 m_edge_connectivity = new EdgeConnectivity(this,mesh()->edgeFamily(),"FaceEdge");
117 m_face_connectivity = new FaceConnectivity(this,mesh()->faceFamily(),"FaceFace");
118 m_cell_connectivity = new CellConnectivity(this,mesh()->cellFamily(),"FaceCell");
119 }
120 m_hparent_connectivity = new HParentConnectivity(this, this, "HParentFace");
121 m_hchild_connectivity = new HChildConnectivity(this, this, "HChildFace");
122
123 _addConnectivitySelector(m_node_connectivity);
124 _addConnectivitySelector(m_edge_connectivity);
125 _addConnectivitySelector(m_face_connectivity);
126 _addConnectivitySelector(m_cell_connectivity);
127 _addConnectivitySelector(m_hparent_connectivity);
128 _addConnectivitySelector(m_hchild_connectivity);
129
130 _buildConnectivitySelectors();
131}
132
133/*---------------------------------------------------------------------------*/
134/*---------------------------------------------------------------------------*/
135
136inline void FaceFamily::
137_createOne(ItemInternal* item,Int64 uid,ItemTypeInfo* type)
138{
139 m_item_internal_list->faces = _itemsInternal();
140 _allocateInfos(item,uid,type);
141 auto nc = m_node_connectivity->trueCustomConnectivity();
142 if (nc)
143 nc->addConnectedItems(ItemLocalId(item),type->nbLocalNode());
144}
145
146/*---------------------------------------------------------------------------*/
147/*---------------------------------------------------------------------------*/
148
149inline void FaceFamily::
150_createOne(ItemInternal* item,Int64 uid,ItemTypeId type_id)
151{
152 _createOne(item,uid,_itemTypeMng()->typeFromId(type_id));
153}
154
155/*---------------------------------------------------------------------------*/
156/*---------------------------------------------------------------------------*/
166{
167 ++mesh_info.nbFace();
168 return allocOne(uid,type_id);
169}
170
171/*---------------------------------------------------------------------------*/
172/*---------------------------------------------------------------------------*/
177allocOne(Int64 uid,ItemTypeInfo* type)
178{
179 ItemInternal* item = _allocOne(uid);
180 _createOne(item,uid,type);
181 return item;
182}
183
184/*---------------------------------------------------------------------------*/
185/*---------------------------------------------------------------------------*/
198{
199 auto face = findOrAllocOne(uid,type_id,is_alloc);
200 if (is_alloc)
201 ++mesh_info.nbFace();
202 return face;
203}
204
205/*---------------------------------------------------------------------------*/
206/*---------------------------------------------------------------------------*/
214findOrAllocOne(Int64 uid,ItemTypeInfo* type,bool& is_alloc)
215{
216 ItemInternal* item = _findOrAllocOne(uid,is_alloc);
217 if (is_alloc){
218 _createOne(item,uid,type);
219 }
220 return item;
221}
222
223/*---------------------------------------------------------------------------*/
224/*---------------------------------------------------------------------------*/
225
227allocOne(Int64 uid,ItemTypeId type_id)
228{
229 ItemInternal* item = _allocOne(uid);
230 _createOne(item,uid,type_id);
231 return item;
232}
233
234/*---------------------------------------------------------------------------*/
235/*---------------------------------------------------------------------------*/
236
239{
240 ItemInternal* item = _findOrAllocOne(uid,is_alloc);
241 if (is_alloc){
242 _createOne(item,uid,type_id);
243 }
244 return item;
245}
246
247/*---------------------------------------------------------------------------*/
248/*---------------------------------------------------------------------------*/
249
250void FaceFamily::
251preAllocate(Integer nb_item)
252{
253 if (!m_has_face)
254 return;
255 // On ne préalloue pas par défaut car on ne souhaite pas pré-allouer
256 // pour la connectivité face->face car c'est dernière n'est utilisée que
257 // s'il y a des TiedInterface et cela n'est pas fréquent.
258 // Du coup on pré-alloue explicitement les connectivités qu'on souhaite.
259 this->_preAllocate(nb_item,false);
260 m_node_connectivity->trueCustomConnectivity()->reserveMemoryForNbSourceItems(nb_item,true);
261 if (Connectivity::hasConnectivity(m_mesh_connectivity,Connectivity::CT_HasEdge))
262 m_edge_connectivity->trueCustomConnectivity()->reserveMemoryForNbSourceItems(nb_item,true);
263 m_cell_connectivity->trueCustomConnectivity()->reserveMemoryForNbSourceItems(nb_item,true);
264}
265
266/*---------------------------------------------------------------------------*/
267/*---------------------------------------------------------------------------*/
268
271{
272 debug() << "Creating the list of ghosts faces";
274}
275
276/*---------------------------------------------------------------------------*/
277/*---------------------------------------------------------------------------*/
283replaceNode(ItemLocalId face,Integer index,ItemLocalId node)
284{
285 m_node_connectivity->replaceItem(face,index,node);
286}
287
288/*---------------------------------------------------------------------------*/
289/*---------------------------------------------------------------------------*/
295replaceEdge(ItemLocalId face,Integer index,ItemLocalId edge)
296{
297 m_edge_connectivity->replaceItem(face,index,edge);
298}
299
300/*---------------------------------------------------------------------------*/
301/*---------------------------------------------------------------------------*/
307replaceFace(ItemLocalId face,Integer index,ItemLocalId face2)
308{
309 m_face_connectivity->replaceItem(face,index,face2);
310}
311
312/*---------------------------------------------------------------------------*/
313/*---------------------------------------------------------------------------*/
319replaceCell(ItemLocalId face,Integer index,ItemLocalId cell)
320{
321 m_cell_connectivity->replaceItem(face,index,cell);
322}
323
324/*---------------------------------------------------------------------------*/
325/*---------------------------------------------------------------------------*/
336{
340 auto c = m_cell_connectivity->trueCustomConnectivity();
341 if (c){
343 // Supprime toutes les mailles connectées.
344 // TODO: optimiser en ne supprimant pas s'il n'y a pas besoin pour éviter
345 // des réallocations.
346 c->removeConnectedItems(face_lid);
347 if (front_cell_lid==NULL_ITEM_LOCAL_ID){
348 if (back_cell_lid!=NULL_ITEM_LOCAL_ID){
349 // Reste uniquement la back_cell ou aucune maille.
350 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.
351 }
352 // Ici reste aucune maille mais comme on a tout supprimé il n'y a rien
353 // à faire.
354 }
355 else if (back_cell_lid==NULL_ITEM_LOCAL_ID){
356 // Reste uniquement la front cell
357 c->IncrementalItemConnectivity::addConnectedItem(face_lid,front_cell_lid);
358 }
359 else{
360 // Il y a deux mailles connectées. La back_cell est toujours la première.
361 c->IncrementalItemConnectivity::addConnectedItem(face_lid,back_cell_lid);
362 c->IncrementalItemConnectivity::addConnectedItem(face_lid,front_cell_lid);
363 }
364 }
365}
366
367/*---------------------------------------------------------------------------*/
368/*---------------------------------------------------------------------------*/
369
372{
373 _checkValidSourceTargetItems(face,new_cell);
374
375 Integer nb_cell = face.nbCell();
376
377 // SDP: les tests suivants sont imcompatibles avec le raffinement
378 // par couches
380 Cell current_cell = face.backCell();
382 ARCANE_FATAL("Face already having a back cell."
383 " This is most probably due to the fact that the face"
384 " is connected to a reverse cell with a negative volume."
385 " Face={0}. new_cell={1} current_cell={2}",FullItemPrinter(face),
387 }
388 }
389
390 if (nb_cell>=2)
391 ARCANE_FATAL("face '{0}' already has two cells",FullItemPrinter(face));
392
393 _updateSharedInfo();
394
395 // Si on a déjà une maille, il s'agit de la front cell.
396 Int32 front_cell_lid = (nb_cell==1) ? face.cellId(0) : NULL_ITEM_LOCAL_ID;
398}
399
400/*---------------------------------------------------------------------------*/
401/*---------------------------------------------------------------------------*/
402
405{
406 _checkValidSourceTargetItems(face,new_cell);
407
408 Integer nb_cell = face.nbCell();
409
410 // SDP: les tests suivants sont imcompatibles avec le raffinement
411 // par couches
413 Cell current_cell = face.frontCell();
415 ARCANE_FATAL("Face already having a front cell."
416 " This is most probably due to the fact that the face"
417 " is connected to a reverse cell with a negative volume."
418 " Face={0}. new_cell={1} current_cell={2}",FullItemPrinter(face),
420 }
421 }
422
423 if (nb_cell>=2)
424 ARCANE_FATAL("face '{0}' already has two cells",FullItemPrinter(face));
425
426 _updateSharedInfo();
427
428 // Si on a déjà une maille, il s'agit de la back cell.
429 Int32 back_cell_lid = (nb_cell==1) ? face.cellId(0) : NULL_ITEM_LOCAL_ID;
431}
432
434/*---------------------------------------------------------------------------*/
435/*---------------------------------------------------------------------------*/
436
439{
440 ARCANE_ASSERT((face.nbCell() ==2),("Face should have back and front cells"));
441
442 Cell current_cell = face.backCell();
444}
445
446/*---------------------------------------------------------------------------*/
447/*---------------------------------------------------------------------------*/
448
449void FaceFamily::
450replaceFrontCellToFace(Face face,ItemLocalId new_cell)
451{
452 ARCANE_ASSERT((face.nbCell() ==2),("Face should have back and front cells"));
453
454 Cell current_cell = face.frontCell();
456}
457
458/*---------------------------------------------------------------------------*/
459/*---------------------------------------------------------------------------*/
460
461void FaceFamily::
462addBackFrontCellsFromParentFace(Face subface,Face face)
463{
464 Cell fcell= face.frontCell();
465 Cell bcell= face.backCell();
466
467 if (subface.itemBase().flags() & ItemFlags::II_HasBackCell){
468 if(fcell.isActive())
470 else if(bcell.isActive())
472 }
473 else if (subface.itemBase().flags() & ItemFlags::II_HasFrontCell){
474 if(bcell.isActive())
475 addBackCellToFace(subface,face.backCell());
476 else if (fcell.isActive())
477 addBackCellToFace(subface,face.frontCell());
478 }
479 ARCANE_ASSERT((subface.backCell() != subface.frontCell()),("back front cells error"));
480}
481
482/*---------------------------------------------------------------------------*/
483/*---------------------------------------------------------------------------*/
484
485void FaceFamily::
486replaceBackFrontCellsFromParentFace(Cell subcell,Face subface,
487 Cell cell,Face face)
488{
489 Cell fscell= subface.frontCell();
490 Cell bscell= subface.backCell();
491 Cell fcell= face.frontCell();
492 Cell bcell= face.backCell();
493 if (fscell.localId()==subcell.localId()) {
494 if(fcell.localId()==cell.localId()) {
495 if(bcell.level()>bscell.level()) {
496 replaceBackCellToFace(subface,bcell);
497 }
498 }
499 else {
500 if(fcell.level() > bscell.level()){
501 replaceBackCellToFace(subface,fcell);
502 }
503 }
504 }
505 else {
506 if (fcell.localId()==cell.localId()){
507 if (bcell.level() > fscell.level()){
508 replaceFrontCellToFace(subface,bcell);
509 }
510 }
511 else{
512 if(fcell.level()>fscell.level()){
513 replaceFrontCellToFace(subface,fcell);
514 }
515 }
516 }
517}
518
519/*---------------------------------------------------------------------------*/
520/*---------------------------------------------------------------------------*/
521
522bool FaceFamily::
523isSubFaceInFace(Face subface,Face face) const
524{
525 const Real tol= 1e-02;
526 bool is_true= false;
527
528 //TODO : un std::binary_search pour accelerer la recherche
529 for( Node inode : subface.nodes() ){
530 for( Node inode2 : face.nodes() ){
531 if (inode.uniqueId() == inode2.uniqueId()) {// il suffit qu'un seul noeud concide
532 is_true = true;
533 break;
534 }
535 }
536 }
537 if (!is_true)
538 return false;
539
540 SharedVariableNodeReal3 orig_nodes_coords(mesh()->sharedNodesCoordinates());
541 Real3 normal_face = _computeFaceNormal(face,orig_nodes_coords);
542 Real3 normal_subface = _computeFaceNormal(subface,orig_nodes_coords);
543 Real ps = math::dot(normal_face,normal_subface);
544 Real residual = math::abs(ps)-1.;
545 return math::abs(residual) < tol ? true: false;
546}
547
548/*---------------------------------------------------------------------------*/
549/*---------------------------------------------------------------------------*/
550
551bool FaceFamily::
552isChildOnFace(ItemWithNodes child,Face face) const
553{
554 //TODO : un std::binary_search pour accelerer la recherche
555 for( Node inode : face.nodes() ){
556 for( Node inode2 : child.nodes() ){
557 if (inode.uniqueId() == inode2.uniqueId()) // il suffit qu'un seul noeud concide
558 return true;
559 }
560 }
561 return false;
562}
563
564/*---------------------------------------------------------------------------*/
565/*---------------------------------------------------------------------------*/
566
567void FaceFamily::
568subFaces(Face face,Array<ItemInternal*>& subfaces)
569{
570 Cell cell;
571 const Integer nb_cell= face.nbCell();
572
573 if (nb_cell == 2) {
574 Cell fcell = face.frontCell();
575 cell = (fcell.hasHChildren()) ? face.frontCell() : face.backCell();
576 }
577 else
578 cell = face.cell(0);
579
580 for( Integer c=0;c<cell.nbHChildren();c++){
581 Cell child = cell.hChild(c);
582 if (isChildOnFace(child,face)){
583 //debug() << "current FACE:" << FullItemPrinter(face)
584 //<< "\n current child CELL:" << FullItemPrinter(child)
585 //<< "\n";
586 for( Face subface : child.faces() ){
587 if(isSubFaceInFace(subface,face)){
588 subfaces.add(ItemCompatibility::_itemInternal(subface));
589 }
590 }
591 }
592 }
593 //info() << "\n SUBFACE NB= " << subfaces.size();
594}
595
596/*---------------------------------------------------------------------------*/
597/*---------------------------------------------------------------------------*/
598
599void FaceFamily::
600allSubFaces(Face face,Array<ItemInternal*>& subfaces)
601{
602 subfaces.add(ItemCompatibility::_itemInternal(face));
603
604 Cell cell;
605 const Integer nb_cell= face.nbCell();
606 if (nb_cell == 2){
607 Cell fcell= face.frontCell();
608 if(fcell.hasHChildren() && fcell.isOwn())
609 cell = face.frontCell() ;
610 else
611 cell = face.backCell();
612 }
613 else{
614 cell= face.cell(0);
615 }
616
617 for(Integer c=0;c<cell.nbHChildren();c++){
618 Cell child = cell.hChild(c);
619 if (isChildOnFace(child,face)){
620 for( Face subface : child.faces() ){
621 if(isSubFaceInFace(subface,face)){
622 allSubFaces(subface,subfaces);
623 }
624 }
625 }
626 }
627}
628
629/*---------------------------------------------------------------------------*/
630/*---------------------------------------------------------------------------*/
631
632void FaceFamily::
633activeSubFaces(Face face,Array<ItemInternal*>& subfaces)
634{
635 Cell cell;
636 const Integer nb_cell= face.nbCell();
637
638 if(nb_cell==2) {
639 Cell fcell = face.frontCell();
640 Cell bcell = face.backCell();
641 if(fcell.level() > bcell.level())
642 cell = face.frontCell();
643 else {
644 if(bcell.isOwn())
645 cell= face.backCell();
646 else
647 cell= face.frontCell();
648 }
649 }
650 else {
651 cell = face.cell(0);
652 }
653 Cell pcell = cell.topHParent();
654
655 UniqueArray<ItemInternal*> cell_family;
656 activeFamilyTree (cell_family,pcell);
657 for(Integer c=0;c<cell_family.size();c++){
658 Cell child = cell_family[c];
659 if(isChildOnFace(child,face)){
660 //debug() << "current FACE:" << FullItemPrinter(face)
661 //<< "\n current child CELL:" << FullItemPrinter(child)
662 //<< "\n";
663 for( Face subface : child.faces() ){
664 if(isSubFaceInFace(subface,face)){
665 subfaces.add(ItemCompatibility::_itemInternal(subface));
666 }
667 }
668 }
669 }
670 //info() << "\n SUBFACE NB= " << subfaces.size();
671}
672
673/*---------------------------------------------------------------------------*/
674/*---------------------------------------------------------------------------*/
675
676void FaceFamily::
677familyTree(Array<ItemInternal*>& family,Cell item,
678 const bool reset) const
679{
680 ARCANE_ASSERT((!item.isSubactive()),("The family tree doesn't include subactive items"));
681 // Clear the array if the flag reset tells us to.
682 if (reset)
683 family.clear();
684 // Add this item to the family tree.
685 family.add(ItemCompatibility::_itemInternal(item));
686 // Recurse into the items children, if it has them.
687 // Do not clear the array any more.
688 if (!item.isActive())
689 for (Integer c=0, cs=item.nbHChildren(); c<cs; c++){
690 Cell ichild= item.hChild(c);
691 familyTree (family,ichild, false);
692 }
693}
694
695/*---------------------------------------------------------------------------*/
696/*---------------------------------------------------------------------------*/
697
698void FaceFamily::
699activeFamilyTree(Array<ItemInternal*>& family,Cell item,const bool reset) const
700{
701 ARCANE_ASSERT((!item.isSubactive()),("The family tree doesn't include subactive items"));
702 // Clear the array if the flag reset tells us to.
703 if (reset)
704 family.clear();
705 // Add this item to the family tree.
706 if(item.isActive())
707 family.add(ItemCompatibility::_itemInternal(item));
708 else
709 for (Integer c=0, cs=item.nbHChildren(); c<cs; c++){
710 Cell ichild= item.hChild(c);
711 if (ichild.isOwn())
712 activeFamilyTree(family,ichild,false);
713 }
714
715}
716
717/*---------------------------------------------------------------------------*/
718/*---------------------------------------------------------------------------*/
719
720void FaceFamily::
721_addParentFaceToFace(Face parent_face, Face child_face)
722{
723 m_hparent_connectivity->addConnectedItem(ItemLocalId(child_face), ItemLocalId(parent_face));
724}
725
726/*---------------------------------------------------------------------------*/
727/*---------------------------------------------------------------------------*/
728
729void FaceFamily::
730_addChildFaceToFace(Face parent_face, Face child_face)
731{
732 m_hchild_connectivity->addConnectedItem(ItemLocalId(parent_face), ItemLocalId(child_face));
733}
734
735// OFF AMR
736
737/*---------------------------------------------------------------------------*/
738/*---------------------------------------------------------------------------*/
739
742{
743 if (!Connectivity::hasConnectivity(m_mesh_connectivity,Connectivity::CT_FaceToEdge))
744 return;
745
746 _checkValidSourceTargetItems(face,new_edge);
747 m_edge_connectivity->addConnectedItem(ItemLocalId(face),ItemLocalId(new_edge));;
748}
749
750/*---------------------------------------------------------------------------*/
751/*---------------------------------------------------------------------------*/
752
755{
756 if (!Connectivity::hasConnectivity(m_mesh_connectivity,Connectivity::CT_FaceToEdge))
757 return;
758
759 _checkValidSourceTargetItems(face,edge_to_remove);
760 m_edge_connectivity->removeConnectedItem(ItemLocalId(face),ItemLocalId(edge_to_remove));
761}
762
763/*---------------------------------------------------------------------------*/
764/*---------------------------------------------------------------------------*/
765
766inline void FaceFamily::
767_removeFace(Face face)
768{
769 ItemLocalId face_lid = face;
770 for( Int32 edge : face.edgeIds() )
771 m_edge_family->removeFaceFromEdge(ItemLocalId(edge),face_lid);
772 for( Int32 node : face.nodeIds() )
773 m_node_family->removeFaceFromNode(ItemLocalId(node),face_lid);
774 _removeOne(face);
775 // On ne supprime pas ici les autres relations (ici aucune)
776 // Car l'autre de suppression doit toujours être cell, face, edge, node
777 // donc node est en dernier et tout est déjà fait
778 // Par ailleurs, cela évite des problèmes de récursivité
779}
780
781/*---------------------------------------------------------------------------*/
782/*---------------------------------------------------------------------------*/
783
784Real3 FaceFamily::
785_computeFaceNormal(Face face, const SharedVariableNodeReal3& nodes_coord) const
786{
787 Real3 normal_face = Real3::zero();
788 Integer nb_node= face.nbNode();
790 for( Integer i=0; i<nb_node; ++i ){
791 cord_face[i] = nodes_coord[face.node(i)];
792 }
793 switch(nb_node)
794 {
795 case(4):
796 {
797 GeometricUtilities::QuadMapping face_mapping;
798 face_mapping.m_pos[0] = cord_face[0];
799 face_mapping.m_pos[1] = cord_face[1];
800 face_mapping.m_pos[2] = cord_face[2];
801 face_mapping.m_pos[3] = cord_face[3];
802 normal_face= face_mapping.normal();
803 }
804 break ;
805 case(3):
806 {
807 Real3 v1 = cord_face[1] - cord_face[0];
808 Real3 v2 = cord_face[2] - cord_face[0];
809 normal_face = math::vecMul(v1,v2).normalize();
810 }
811 break ;
812 case(2):
813 {
814 normal_face=cord_face[0]-cord_face[1];
815 normal_face.normalize();
816 }
817 break ;
818 default: ARCANE_FATAL("This kind of face is not handled");
819 }
820 return normal_face;
821}
822
823/*---------------------------------------------------------------------------*/
824/*---------------------------------------------------------------------------*/
825
828{
829 _checkValidItem(face);
830
831 Integer nb_cell = face.nbCell();
832
833#ifdef ARCANE_CHECK
834 if (face.itemBase().isSuppressed())
835 ARCANE_FATAL("Can not remove cell from destroyed face={0}",ItemPrinter(face));
836 if (nb_cell==0)
837 ARCANE_FATAL("Can not remove cell lid={0} from face uid={1} with no cell connected",
839#endif /* ARCANE_CHECK */
840
841 Integer nb_cell_after = nb_cell-1;
842 const Int32 null_cell_lid = NULL_ITEM_LOCAL_ID;
844 // forcer la suppression d'une face entre deux mailles de niveaux differents
845 // car cette face n'est topologiquement attachée a la maille de niveau inferieur
846 if (nb_cell == 2){
847 if(face.backCell().level() != face.frontCell().level())
848 nb_cell_after = 0;
849 else if (! (face.backCell().isActive() && face.frontCell().isActive())){
850 // TODO: GG: pour des raisons de performance, il est préférable d'éviter
851 // les allocations dans cette méthode car elle est appelée très souvent.
853 subFaces(face,subfaces);
854 for(Integer s=0,ss=subfaces.size();s<ss;s++){
856 Int32 cell0 = face2->cellId(0);
857 Int32 cell1 = face2->cellId(1);
858 // On avait obligatoirement deux mailles connectées avant,
859 // donc la back_cell est la maille 0, la front cell la maille 1
861 // Reste la front cell
863 }
864 else{
865 // Reste la back cell
867 }
868 _updateSharedInfo();
869 }
870 }
871 }
872 // OFF AMR
873 if (nb_cell_after!=0){
874 Int32 cell0 = face.cellId(0);
875 Int32 cell1 = face.cellId(1);
876 // On avait obligatoirement deux mailles connectées avant,
877 // donc la back_cell est la maille 0, la front cell la maille 1
879 // Reste la front cell
881 }
882 else{
883 // Reste la back cell
885 }
886 }
887 else{
889 }
890
891 _updateSharedInfo();
892}
893
894/*---------------------------------------------------------------------------*/
895/*---------------------------------------------------------------------------*/
896
899{
900 _checkValidItem(face);
901
902 if (!face.itemBase().isSuppressed() && face.nbCell()==0){
903 _removeFace(face);
904 }
905}
906
907/*---------------------------------------------------------------------------*/
908/*---------------------------------------------------------------------------*/
909
910void FaceFamily::
911_addMasterFaceToFace(Face face,Face master_face)
912{
913 m_face_connectivity->addConnectedItem(face,master_face);
915}
916
917/*---------------------------------------------------------------------------*/
918/*---------------------------------------------------------------------------*/
919
920void FaceFamily::
922{
923 Integer nb_slave = slave_faces_lid.size();
924 for( Integer i=0; i<nb_slave; ++i )
925 m_face_connectivity->addConnectedItem(master_face,ItemLocalId(slave_faces_lid[i]));
926 master_face.mutableItemBase().addFlags(ItemFlags::II_MasterFace);
927}
928
929/*---------------------------------------------------------------------------*/
930/*---------------------------------------------------------------------------*/
931
932void FaceFamily::
933_removeMasterFaceToFace(Face face)
934{
935 m_face_connectivity->removeConnectedItems(face);
936 face.mutableItemBase().removeFlags(ItemFlags::II_SlaveFace);
937}
938
939/*---------------------------------------------------------------------------*/
940/*---------------------------------------------------------------------------*/
941
942void FaceFamily::
943_removeSlaveFacesToFace(Face master_face)
944{
945 m_face_connectivity->removeConnectedItems(master_face);
946 master_face.mutableItemBase().removeFlags(ItemFlags::II_MasterFace);
947}
948
949/*---------------------------------------------------------------------------*/
950/*---------------------------------------------------------------------------*/
951
954{
957
960 Integer index = imaster_face.index();
962 Integer nb_slave = slave_tied_faces.size();
963 slave_faces.clear();
964 for( Integer zz=0; zz<nb_slave; ++zz ){
965 const TiedFace& tn = tied_faces[index][zz];
966 Face slave_face = tn.face();
967 slave_faces.add(slave_face.localId());
968 _addMasterFaceToFace(slave_face,master_face);
969 }
970 _addSlaveFacesToFace(master_face,slave_faces);
971 }
972}
973
974/*---------------------------------------------------------------------------*/
975/*---------------------------------------------------------------------------*/
976
979{
981
984 Integer index = imaster_face.index();
986 Integer nb_slave = slave_tied_faces.size();
987 for( Integer zz=0; zz<nb_slave; ++zz ){
988 const TiedFace& tn = tied_faces[index][zz];
989 Face slave_face = tn.face();
990 _removeMasterFaceToFace(slave_face);
991 }
992 _removeSlaveFacesToFace(master_face);
993 }
994}
995
996/*---------------------------------------------------------------------------*/
997/*---------------------------------------------------------------------------*/
998
999void FaceFamily::
1000setConnectivity(const Integer c)
1001{
1002 m_mesh_connectivity = c;
1003 m_has_face = Connectivity::hasConnectivity(m_mesh_connectivity,Connectivity::CT_HasFace);
1004 if (m_has_face){
1005 m_node_prealloc = Connectivity::getPrealloc(m_mesh_connectivity,IK_Face,IK_Node);
1006 if (Connectivity::hasConnectivity(m_mesh_connectivity,Connectivity::CT_HasEdge))
1007 m_edge_prealloc = Connectivity::getPrealloc(m_mesh_connectivity,IK_Face,IK_Edge);
1008 m_face_connectivity->setPreAllocatedSize(4);
1009 m_cell_prealloc = Connectivity::getPrealloc(m_mesh_connectivity,IK_Face,IK_Cell);
1010 m_node_connectivity->setPreAllocatedSize(m_node_prealloc);
1011 m_cell_connectivity->setPreAllocatedSize(m_cell_prealloc);
1012 debug() << "Family " << name() << " prealloc "
1013 << m_node_prealloc << " by node, "
1014 << m_edge_prealloc << " by edge, "
1015 << m_cell_prealloc << " by cell.";
1016 }
1017}
1018
1019/*---------------------------------------------------------------------------*/
1020/*---------------------------------------------------------------------------*/
1021
1022void FaceFamily::
1023reorientFacesIfNeeded()
1024{
1025 // Réoriente les faces si nécessaire. Cela est le cas par exemple si on
1026 // a changé la numérotation des uniqueId() des noeuds.
1027 mesh::FaceReorienter face_reorienter(mesh());
1028 ENUMERATE_ (Face, iface, allItems()) {
1029 face_reorienter.checkAndChangeOrientationAMR(*iface);
1030 }
1031}
1032
1033/*---------------------------------------------------------------------------*/
1034/*---------------------------------------------------------------------------*/
1035
1036} // End namespace Arcane::mesh
1037
1038/*---------------------------------------------------------------------------*/
1039/*---------------------------------------------------------------------------*/
#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:1178
bool isActive() const
Definition Item.h:1306
Int32 level() const
Definition Item.h:1328
Arête d'une maille.
Definition Item.h:798
Face d'une maille.
Definition Item.h:932
Cell frontCell() const
Maille devant la face (maille nulle si aucune)
Definition Item.h:1604
CellLocalId cellId(Int32 i) const
i-ème maille de la face
Definition Item.h:1015
Int32 nbCell() const
Nombre de mailles de la face (1 ou 2)
Definition Item.h:1006
Cell backCell() const
Maille derrière la face (maille nulle si aucune)
Definition Item.h:1598
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'un Item dans une variable.
Definition ItemLocalId.h:40
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:768
Int32 nbNode() const
Nombre de noeuds de l'entité
Definition Item.h:765
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:365
constexpr Int32 localId() const
Identifiant local de l'entité dans le sous-domaine du processeur.
Definition Item.h:210
ItemUniqueId uniqueId() const
Identifiant unique sur tous les domaines.
Definition Item.h:216
impl::ItemBase itemBase() const
Partie interne de l'entité.
Definition Item.h:354
Lecteur des fichiers de maillage via la bibliothèque LIMA.
Definition Lima.cc:120
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
Real3 & normalize()
Normalise le triplet.
Definition Real3.h:362
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:69
void replaceEdge(ItemLocalId item_lid, Integer index, ItemLocalId new_lid) override
Remplace une arête d'une entité.
Definition FaceFamily.cc:61
void replaceNode(ItemLocalId item_lid, Integer index, ItemLocalId new_lid) override
Remplace un noeud d'une entité.
Definition FaceFamily.cc:57
void replaceFace(ItemLocalId item_lid, Integer index, ItemLocalId new_lid) override
Remplace une face d'une entité.
Definition FaceFamily.cc:65
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:379
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:125
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.