14#include "arcane/mesh/FaceFamily.h"
16#include "arcane/utils/FatalErrorException.h"
17#include "arcane/utils/NotImplementedException.h"
18#include "arcane/utils/String.h"
19#include "arcane/utils/OStringStream.h"
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"
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"
39#include "arcane/GeometricUtilities.h"
40#include "arcane/SharedVariable.h"
52:
public AbstractItemFamilyTopologyModifier
56 explicit TopologyModifier(FaceFamily* f)
57 : AbstractItemFamilyTopologyModifier(f), m_true_family(f){}
60 m_true_family->replaceNode(item_lid,index,new_lid);
64 m_true_family->replaceEdge(item_lid,index,new_lid);
68 m_true_family->replaceFace(item_lid,index,new_lid);
72 m_true_family->replaceCell(item_lid,index,new_lid);
75 CellLocalId front_cell_lid)
override
77 Face face(m_true_family->_itemInternal(face_lid));
78 m_true_family->setBackAndFrontCells(face, back_cell_lid, front_cell_lid);
83 FaceFamily* m_true_family =
nullptr;
93 _setTopologyModifier(
new TopologyModifier(
this));
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())));
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");
129 m_hparent_connectivity =
new HParentConnectivity(
this,
this,
"HParentFace");
130 m_hchild_connectivity =
new HChildConnectivity(
this,
this,
"HChildFace");
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);
139 _buildConnectivitySelectors();
145inline void FaceFamily::
146_createOne(ItemInternal* item,
Int64 uid,ItemTypeInfo* type)
148 m_item_internal_list->faces = _itemsInternal();
149 _allocateInfos(item,uid,type);
150 auto nc = m_node_connectivity->trueCustomConnectivity();
152 nc->addConnectedItems(ItemLocalId(item),type->nbLocalNode());
158inline void FaceFamily::
159_createOne(ItemInternal* item,
Int64 uid,ItemTypeId type_id)
161 _createOne(item,uid,_itemTypeMng()->typeFromId(type_id));
189 _createOne(item,uid,
type);
227 _createOne(item,uid,
type);
239 _createOne(item,uid,type_id);
251 _createOne(item,uid,type_id);
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);
281 debug() <<
"Creating the list of ghosts faces";
294 m_node_connectivity->replaceItem(face,index,node);
306 m_edge_connectivity->replaceItem(face,index,edge);
318 m_face_connectivity->replaceItem(face,index,face2);
330 m_cell_connectivity->replaceItem(face,index,cell);
349 auto c = m_cell_connectivity->trueCustomConnectivity();
355 c->removeConnectedItems(face_lid);
356 if (front_cell_lid==NULL_ITEM_LOCAL_ID){
357 if (back_cell_lid!=NULL_ITEM_LOCAL_ID){
359 c->IncrementalItemConnectivity::addConnectedItem(face_lid,back_cell_lid);
364 else if (back_cell_lid==NULL_ITEM_LOCAL_ID){
366 c->IncrementalItemConnectivity::addConnectedItem(face_lid,front_cell_lid);
370 c->IncrementalItemConnectivity::addConnectedItem(face_lid,back_cell_lid);
371 c->IncrementalItemConnectivity::addConnectedItem(face_lid,front_cell_lid);
382 _checkValidSourceTargetItems(face,new_cell);
392 " This is most probably due to the fact that the face"
393 " is connected to a reverse cell with a negative volume."
405 Int32 front_cell_lid = (nb_cell==1) ? face.
cellId(0) : NULL_ITEM_LOCAL_ID;
415 _checkValidSourceTargetItems(face,new_cell);
425 " This is most probably due to the fact that the face"
426 " is connected to a reverse cell with a negative volume."
438 Int32 back_cell_lid = (nb_cell==1) ? face.
cellId(0) : NULL_ITEM_LOCAL_ID;
449 ARCANE_ASSERT((face.
nbCell() ==2),(
"Face should have back and front cells"));
461 ARCANE_ASSERT((face.
nbCell() ==2),(
"Face should have back and front cells"));
471addBackFrontCellsFromParentFace(
Face subface,
Face face)
488 ARCANE_ASSERT((subface.
backCell() != subface.
frontCell()),(
"back front cells error"));
495replaceBackFrontCellsFromParentFace(Cell subcell,Face subface,
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()) {
509 if(fcell.level() > bscell.level()){
515 if (fcell.localId()==cell.localId()){
516 if (bcell.level() > fscell.level()){
517 replaceFrontCellToFace(subface,bcell);
521 if(fcell.level()>fscell.level()){
522 replaceFrontCellToFace(subface,fcell);
532isSubFaceInFace(Face subface,Face face)
const
534 const Real tol= 1e-02;
538 for( Node inode : subface.nodes() ){
539 for( Node inode2 : face.nodes() ){
540 if (inode.uniqueId() == inode2.uniqueId()) {
550 Real3 normal_face = _computeFaceNormal(face,orig_nodes_coords);
551 Real3 normal_subface = _computeFaceNormal(subface,orig_nodes_coords);
553 Real residual = math::abs(ps)-1.;
554 return math::abs(residual) < tol ?
true:
false;
561isChildOnFace(ItemWithNodes child,Face face)
const
564 for( Node inode : face.nodes() ){
565 for( Node inode2 : child.nodes() ){
566 if (inode.uniqueId() == inode2.uniqueId())
577subFaces(Face face,Array<ItemInternal*>& subfaces)
580 const Integer nb_cell= face.nbCell();
583 Cell fcell = face.frontCell();
584 cell = (fcell.hasHChildren()) ? face.frontCell() : face.backCell();
589 for(
Integer c=0;c<cell.nbHChildren();c++){
590 Cell child = cell.hChild(c);
591 if (isChildOnFace(child,face)){
595 for( Face subface : child.faces() ){
596 if(isSubFaceInFace(subface,face)){
597 subfaces.add(ItemCompatibility::_itemInternal(subface));
609allSubFaces(Face face,Array<ItemInternal*>& subfaces)
611 subfaces.add(ItemCompatibility::_itemInternal(face));
614 const Integer nb_cell= face.nbCell();
616 Cell fcell= face.frontCell();
617 if(fcell.hasHChildren() && fcell.isOwn())
618 cell = face.frontCell() ;
620 cell = face.backCell();
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);
642activeSubFaces(Face face,Array<ItemInternal*>& subfaces)
645 const Integer nb_cell= face.nbCell();
648 Cell fcell = face.frontCell();
649 Cell bcell = face.backCell();
650 if(fcell.level() > bcell.level())
651 cell = face.frontCell();
654 cell= face.backCell();
656 cell= face.frontCell();
662 Cell pcell = cell.topHParent();
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)){
672 for( Face subface : child.faces() ){
673 if(isSubFaceInFace(subface,face)){
674 subfaces.add(ItemCompatibility::_itemInternal(subface));
686familyTree(Array<ItemInternal*>& family,Cell item,
687 const bool reset)
const
689 ARCANE_ASSERT((!item.isSubactive()),(
"The family tree doesn't include subactive items"));
694 family.add(ItemCompatibility::_itemInternal(item));
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);
708activeFamilyTree(Array<ItemInternal*>& family,Cell item,
const bool reset)
const
710 ARCANE_ASSERT((!item.isSubactive()),(
"The family tree doesn't include subactive items"));
716 family.add(ItemCompatibility::_itemInternal(item));
718 for (
Integer c=0, cs=item.nbHChildren(); c<cs; c++){
719 Cell ichild= item.hChild(c);
721 activeFamilyTree(family,ichild,
false);
730_addParentFaceToFace(Face parent_face, Face child_face)
732 m_hparent_connectivity->addConnectedItem(ItemLocalId(child_face), ItemLocalId(parent_face));
739_addChildFaceToFace(Face parent_face, Face child_face)
741 m_hchild_connectivity->addConnectedItem(ItemLocalId(parent_face), ItemLocalId(child_face));
752 if (!Connectivity::hasConnectivity(m_mesh_connectivity,Connectivity::CT_FaceToEdge))
755 _checkValidSourceTargetItems(face,new_edge);
765 if (!Connectivity::hasConnectivity(m_mesh_connectivity,Connectivity::CT_FaceToEdge))
768 _checkValidSourceTargetItems(face,edge_to_remove);
775inline void FaceFamily::
776_removeFace(
Face face)
796 Real3 normal_face = Real3::zero();
799 for(
Integer i=0; i<nb_node; ++i ){
800 cord_face[i] = nodes_coord[face.
node(i)];
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();
816 Real3 v1 = cord_face[1] - cord_face[0];
817 Real3 v2 = cord_face[2] - cord_face[0];
823 normal_face=cord_face[0]-cord_face[1];
824 normal_face.normalize();
827 default:
ARCANE_FATAL(
"This kind of face is not handled");
838 _checkValidItem(face);
846 ARCANE_FATAL(
"Can not remove cell lid={0} from face uid={1} with no cell connected",
847 cell_to_remove_lid, face.
uniqueId());
850 Integer nb_cell_after = nb_cell-1;
851 const Int32 null_cell_lid = NULL_ITEM_LOCAL_ID;
862 subFaces(face,subfaces);
865 Int32 cell0 = face2->cellId(0);
866 Int32 cell1 = face2->cellId(1);
869 if (cell0==cell_to_remove_lid){
882 if (nb_cell_after!=0){
887 if (cell0==cell_to_remove_lid){
909 _checkValidItem(face);
920_addMasterFaceToFace(
Face face,
Face master_face)
922 m_face_connectivity->addConnectedItem(face,master_face);
933 for(
Integer i=0; i<nb_slave; ++i )
934 m_face_connectivity->addConnectedItem(master_face,
ItemLocalId(slave_faces_lid[i]));
942_removeMasterFaceToFace(Face face)
944 m_face_connectivity->removeConnectedItems(face);
952_removeSlaveFacesToFace(Face master_face)
954 m_face_connectivity->removeConnectedItems(master_face);
964 TiedInterfaceFaceList tied_faces(interface->
tiedFaces());
968 Face master_face = *imaster_face;
969 Integer index = imaster_face.index();
973 for(
Integer zz=0; zz<nb_slave; ++zz ){
974 const TiedFace& tn = tied_faces[index][zz];
977 _addMasterFaceToFace(slave_face,master_face);
979 _addSlaveFacesToFace(master_face,slave_faces);
989 TiedInterfaceFaceList tied_faces(interface->
tiedFaces());
992 Face master_face = *imaster_face;
993 Integer index = imaster_face.index();
996 for(
Integer zz=0; zz<nb_slave; ++zz ){
997 const TiedFace& tn = tied_faces[index][zz];
999 _removeMasterFaceToFace(slave_face);
1001 _removeSlaveFacesToFace(master_face);
1009setConnectivity(
const Integer c)
1011 m_mesh_connectivity = c;
1012 m_has_face = Connectivity::hasConnectivity(m_mesh_connectivity,Connectivity::CT_HasFace);
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.";
1032reorientFacesIfNeeded()
1036 mesh::FaceReorienter face_reorienter(
mesh());
1038 face_reorienter.checkAndChangeOrientationAMR(*iface);
#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.
Integer size() const
Nombre d'éléments du vecteur.
void clear()
Supprime les éléments du tableau.
void add(ConstReferenceType val)
Ajoute l'élément val à la fin du tableau.
Vue constante d'un tableau de type T.
constexpr Integer size() const noexcept
Nombre d'éléments du tableau.
Cell frontCell() const
Maille devant la face (maille nulle si aucune)
CellLocalId cellId(Int32 i) const
i-ème maille de la face
EdgeLocalIdView edgeIds() const
Liste des arêtes de la face.
Int32 nbCell() const
Nombre de mailles de la face (1 ou 2)
Cell backCell() const
Maille derrière la face (maille nulle si aucune)
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 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.
@ II_HasBackCell
L'entité a une maille derrière.
@ II_SlaveFace
L'entité est une face esclave d'une interface.
@ II_HasFrontCell
L'entité a une maille devant.
Structure interne d'une entité de maillage.
Index d'un Item dans une variable.
Classe utilitaire pour imprimer les infos sur une entité.
Type d'une entité (Item).
Infos sur un type d'entité du maillage.
Node node(Int32 i) const
i-ème noeud de l'entité
Int32 nbNode() const
Nombre de noeuds de l'entité
NodeLocalIdView nodeIds() const
Liste des noeuds de l'entité
Classe de base d'un élément de maillage.
impl::MutableItemBase mutableItemBase() const
Partie interne modifiable de l'entité.
constexpr Int32 localId() const
Identifiant local de l'entité dans le sous-domaine du processeur.
ItemUniqueId uniqueId() const
Identifiant unique sur tous les domaines.
impl::ItemBase itemBase() const
Partie interne de l'entité.
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.
Chaîne de caractères unicode.
Face semi-conforme du maillage.
Face face() const
Face soudée.
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).
void removeFaceFromEdge(ItemLocalId edge, ItemLocalId face_to_remove)
Supprime une maille d'une arête.
void replaceCell(ItemLocalId item_lid, Integer index, ItemLocalId new_lid) override
Remplace une maille d'une entité.
void replaceEdge(ItemLocalId item_lid, Integer index, ItemLocalId new_lid) override
Remplace une arête d'une entité.
void replaceNode(ItemLocalId item_lid, Integer index, ItemLocalId new_lid) override
Remplace un noeud d'une entité.
void setBackAndFrontCells(FaceLocalId face_lid, CellLocalId back_cell_lid, CellLocalId front_cell_lid) override
Positionne la maille devant et derrière une face.
void replaceFace(ItemLocalId item_lid, Integer index, ItemLocalId new_lid) override
Remplace une face d'une entité.
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.
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.
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.
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.
IMesh * mesh() const override
Maillage associé
IItemFamilyTopologyModifier * _topologyModifier() override
Interface du modificateur de topologie.
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.
Classe factorisant des informations sur le maillage.
Integer & nbFace()
Nombre de faces dans le maillage.
__host__ __device__ Real dot(Real2 u, Real2 v)
Produit scalaire de u par v dans .
__host__ __device__ Real3 vecMul(Real3 u, Real3 v)
Produit vectoriel de u par v. dans .
std::int64_t Int64
Type entier signé sur 64 bits.
Int32 Integer
Type représentant un entier.
UniqueArray< Real3 > Real3UniqueArray
Tableau dynamique à une dimension de vecteurs de rang 3.
ConstArrayView< Int32 > Int32ConstArrayView
Equivalent C d'un tableau à une dimension d'entiers 32 bits.
SharedMeshVariableScalarRefT< Node, Real3 > SharedVariableNodeReal3
Grandeur au noeud de type coordonnées.
UniqueArray< Int32 > Int32UniqueArray
Tableau dynamique à une dimension d'entiers 32 bits.
@ 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.
double Real
Type représentant un réel.
std::int32_t Int32
Type entier signé sur 32 bits.