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/core/IMesh.h"
32#include "arcane/core/ITiedInterface.h"
33#include "arcane/core/TiedFace.h"
35#include "arcane/core/ItemPrinter.h"
36#include "arcane/core/Connectivity.h"
39#include "arcane/core/GeometricUtilities.h"
40#include "arcane/core/SharedVariable.h"
52:
public AbstractItemFamilyTopologyModifier
56 explicit TopologyModifier(FaceFamily* f)
57 : AbstractItemFamilyTopologyModifier(f)
62 m_true_family->replaceNode(item_lid, index, new_lid);
66 m_true_family->replaceEdge(item_lid, index, new_lid);
70 m_true_family->replaceFace(item_lid, index, new_lid);
74 m_true_family->replaceCell(item_lid, index, new_lid);
77 CellLocalId front_cell_lid)
override
79 Face face(m_true_family->_itemInternal(face_lid));
80 m_true_family->setBackAndFrontCells(face, back_cell_lid, front_cell_lid);
85 FaceFamily* m_true_family =
nullptr;
95 _setTopologyModifier(
new TopologyModifier(
this));
119 m_node_connectivity =
dynamic_cast<NewWithLegacyConnectivityType<FaceFamily, NodeFamily>::type*
>(m_mesh->
itemFamilyNetwork()->getConnectivity(
this,
mesh()->nodeFamily(), connectivityName(
this,
mesh()->nodeFamily())));
120 m_edge_connectivity =
dynamic_cast<NewWithLegacyConnectivityType<FaceFamily, EdgeFamily>::type*
>(m_mesh->
itemFamilyNetwork()->getConnectivity(
this,
mesh()->edgeFamily(), connectivityName(
this,
mesh()->edgeFamily())));
121 m_face_connectivity =
dynamic_cast<NewWithLegacyConnectivityType<FaceFamily, FaceFamily>::type*
>(m_mesh->
itemFamilyNetwork()->getConnectivity(
this,
mesh()->faceFamily(), connectivityName(
this,
mesh()->faceFamily())));
122 m_cell_connectivity =
dynamic_cast<NewWithLegacyConnectivityType<FaceFamily, CellFamily>::type*
>(m_mesh->
itemFamilyNetwork()->getConnectivity(
this,
mesh()->cellFamily(), connectivityName(
this,
mesh()->cellFamily())));
125 m_node_connectivity =
new NodeConnectivity(
this,
mesh()->nodeFamily(),
"FaceNode");
126 m_edge_connectivity =
new EdgeConnectivity(
this,
mesh()->edgeFamily(),
"FaceEdge");
127 m_face_connectivity =
new FaceConnectivity(
this,
mesh()->faceFamily(),
"FaceFace");
128 m_cell_connectivity =
new CellConnectivity(
this,
mesh()->cellFamily(),
"FaceCell");
130 m_hparent_connectivity =
new HParentConnectivity(
this,
this,
"HParentFace");
131 m_hchild_connectivity =
new HChildConnectivity(
this,
this,
"HChildFace");
133 _addConnectivitySelector(m_node_connectivity);
134 _addConnectivitySelector(m_edge_connectivity);
135 _addConnectivitySelector(m_face_connectivity);
136 _addConnectivitySelector(m_cell_connectivity);
137 _addConnectivitySelector(m_hparent_connectivity);
138 _addConnectivitySelector(m_hchild_connectivity);
140 _buildConnectivitySelectors();
146inline void FaceFamily::
147_createOne(ItemInternal* item,
Int64 uid, ItemTypeInfo* type)
149 m_item_internal_list->faces = _itemsInternal();
150 _allocateInfos(item, uid, type);
151 auto nc = m_node_connectivity->trueCustomConnectivity();
153 nc->addConnectedItems(ItemLocalId(item), type->nbLocalNode());
159inline void FaceFamily::
160_createOne(ItemInternal* item,
Int64 uid, ItemTypeId type_id)
162 _createOne(item, uid, _itemTypeMng()->typeFromId(type_id));
190 _createOne(item, uid,
type);
228 _createOne(item, uid,
type);
240 _createOne(item, uid, type_id);
252 _createOne(item, uid, type_id);
269 this->_preAllocate(nb_item,
false);
270 m_node_connectivity->trueCustomConnectivity()->reserveMemoryForNbSourceItems(nb_item,
true);
271 if (Connectivity::hasConnectivity(m_mesh_connectivity, Connectivity::CT_HasEdge))
272 m_edge_connectivity->trueCustomConnectivity()->reserveMemoryForNbSourceItems(nb_item,
true);
273 m_cell_connectivity->trueCustomConnectivity()->reserveMemoryForNbSourceItems(nb_item,
true);
282 debug() <<
"Creating the list of ghosts faces";
295 m_node_connectivity->replaceItem(face, index, node);
307 m_edge_connectivity->replaceItem(face, index, edge);
319 m_face_connectivity->replaceItem(face, index, face2);
331 m_cell_connectivity->replaceItem(face, index, cell);
350 auto c = m_cell_connectivity->trueCustomConnectivity();
356 c->removeConnectedItems(face_lid);
357 if (front_cell_lid == NULL_ITEM_LOCAL_ID) {
358 if (back_cell_lid != NULL_ITEM_LOCAL_ID) {
360 c->IncrementalItemConnectivity::addConnectedItem(face_lid, back_cell_lid);
365 else if (back_cell_lid == NULL_ITEM_LOCAL_ID) {
367 c->IncrementalItemConnectivity::addConnectedItem(face_lid, front_cell_lid);
371 c->IncrementalItemConnectivity::addConnectedItem(face_lid, back_cell_lid);
372 c->IncrementalItemConnectivity::addConnectedItem(face_lid, front_cell_lid);
383 _checkValidSourceTargetItems(face, new_cell);
393 " This is most probably due to the fact that the face"
394 " is connected to a reverse cell with a negative volume."
395 " Face={0}. new_cell={1} current_cell={2}",
407 Int32 front_cell_lid = (nb_cell == 1) ? face.
cellId(0) : NULL_ITEM_LOCAL_ID;
417 _checkValidSourceTargetItems(face, new_cell);
427 " This is most probably due to the fact that the face"
428 " is connected to a reverse cell with a negative volume."
429 " Face={0}. new_cell={1} current_cell={2}",
441 Int32 back_cell_lid = (nb_cell == 1) ? face.
cellId(0) : NULL_ITEM_LOCAL_ID;
451 ARCANE_ASSERT((face.
nbCell() == 2), (
"Face should have back and front cells"));
463 ARCANE_ASSERT((face.
nbCell() == 2), (
"Face should have back and front cells"));
473addBackFrontCellsFromParentFace(
Face subface,
Face face)
490 ARCANE_ASSERT((subface.
backCell() != subface.
frontCell()), (
"back front cells error"));
497replaceBackFrontCellsFromParentFace(
Cell subcell, Face subface,
498 Cell cell, Face face)
500 Cell fscell = subface.frontCell();
501 Cell bscell = subface.backCell();
502 Cell fcell = face.frontCell();
503 Cell bcell = face.backCell();
504 if (fscell.localId() == subcell.localId()) {
505 if (fcell.localId() == cell.localId()) {
506 if (bcell.level() > bscell.level()) {
511 if (fcell.level() > bscell.level()) {
517 if (fcell.localId() == cell.localId()) {
518 if (bcell.level() > fscell.level()) {
519 replaceFrontCellToFace(subface, bcell);
523 if (fcell.level() > fscell.level()) {
524 replaceFrontCellToFace(subface, fcell);
534isSubFaceInFace(Face subface, Face face)
const
536 const Real tol = 1e-02;
537 bool is_true =
false;
540 for (Node inode : subface.nodes()) {
541 for (Node inode2 : face.nodes()) {
542 if (inode.uniqueId() == inode2.uniqueId()) {
552 Real3 normal_face = _computeFaceNormal(face, orig_nodes_coords);
553 Real3 normal_subface = _computeFaceNormal(subface, orig_nodes_coords);
555 Real residual = math::abs(ps) - 1.;
556 return math::abs(residual) < tol ? true :
false;
563isChildOnFace(ItemWithNodes child, Face face)
const
566 for (Node inode : face.nodes()) {
567 for (Node inode2 : child.nodes()) {
568 if (inode.uniqueId() == inode2.uniqueId())
579subFaces(Face face, Array<ItemInternal*>& subfaces)
582 const Integer nb_cell = face.nbCell();
585 Cell fcell = face.frontCell();
586 cell = (fcell.hasHChildren()) ? face.frontCell() : face.backCell();
591 for (
Integer c = 0; c < cell.nbHChildren(); c++) {
592 Cell child = cell.hChild(c);
593 if (isChildOnFace(child, face)) {
597 for (Face subface : child.faces()) {
598 if (isSubFaceInFace(subface, face)) {
599 subfaces.add(ItemCompatibility::_itemInternal(subface));
611allSubFaces(Face face, Array<ItemInternal*>& subfaces)
613 subfaces.add(ItemCompatibility::_itemInternal(face));
616 const Integer nb_cell = face.nbCell();
618 Cell fcell = face.frontCell();
619 if (fcell.hasHChildren() && fcell.isOwn())
620 cell = face.frontCell();
622 cell = face.backCell();
628 for (
Integer c = 0; c < cell.nbHChildren(); c++) {
629 Cell child = cell.hChild(c);
630 if (isChildOnFace(child, face)) {
631 for (Face subface : child.faces()) {
632 if (isSubFaceInFace(subface, face)) {
633 allSubFaces(subface, subfaces);
644activeSubFaces(Face face, Array<ItemInternal*>& subfaces)
647 const Integer nb_cell = face.nbCell();
650 Cell fcell = face.frontCell();
651 Cell bcell = face.backCell();
652 if (fcell.level() > bcell.level())
653 cell = face.frontCell();
656 cell = face.backCell();
658 cell = face.frontCell();
664 Cell pcell = cell.topHParent();
666 UniqueArray<ItemInternal*> cell_family;
667 activeFamilyTree(cell_family, pcell);
668 for (
Integer c = 0; c < cell_family.size(); c++) {
669 Cell child = cell_family[c];
670 if (isChildOnFace(child, face)) {
674 for (Face subface : child.faces()) {
675 if (isSubFaceInFace(subface, face)) {
676 subfaces.add(ItemCompatibility::_itemInternal(subface));
688familyTree(Array<ItemInternal*>& family,
Cell item,
689 const bool reset)
const
691 ARCANE_ASSERT((!item.isSubactive()), (
"The family tree doesn't include subactive items"));
696 family.add(ItemCompatibility::_itemInternal(item));
699 if (!item.isActive())
700 for (
Integer c = 0, cs = item.nbHChildren(); c < cs; c++) {
701 Cell ichild = item.hChild(c);
702 familyTree(family, ichild,
false);
710activeFamilyTree(Array<ItemInternal*>& family,
Cell item,
const bool reset)
const
712 ARCANE_ASSERT((!item.isSubactive()), (
"The family tree doesn't include subactive items"));
718 family.add(ItemCompatibility::_itemInternal(item));
720 for (
Integer c = 0, cs = item.nbHChildren(); c < cs; c++) {
721 Cell ichild = item.hChild(c);
723 activeFamilyTree(family, ichild,
false);
731_addParentFaceToFace(Face parent_face, Face child_face)
733 m_hparent_connectivity->addConnectedItem(ItemLocalId(child_face), ItemLocalId(parent_face));
740_addChildFaceToFace(Face parent_face, Face child_face)
742 m_hchild_connectivity->addConnectedItem(ItemLocalId(parent_face), ItemLocalId(child_face));
753 if (!Connectivity::hasConnectivity(m_mesh_connectivity, Connectivity::CT_FaceToEdge))
756 _checkValidSourceTargetItems(face, new_edge);
767 if (!Connectivity::hasConnectivity(m_mesh_connectivity, Connectivity::CT_FaceToEdge))
770 _checkValidSourceTargetItems(face, edge_to_remove);
777inline void FaceFamily::
778_removeFace(
Face face)
784 for (
Int32 i = 0; i < nb_linear_node; ++i) {
801 Real3 normal_face = Real3::zero();
802 Integer nb_node = face.nbNode();
804 for (
Integer i = 0; i < nb_node; ++i) {
805 cord_face[i] = nodes_coord[face.node(i)];
809 GeometricUtilities::QuadMapping face_mapping;
810 face_mapping.m_pos[0] = cord_face[0];
811 face_mapping.m_pos[1] = cord_face[1];
812 face_mapping.m_pos[2] = cord_face[2];
813 face_mapping.m_pos[3] = cord_face[3];
814 normal_face = face_mapping.normal();
817 Real3 v1 = cord_face[1] - cord_face[0];
818 Real3 v2 = cord_face[2] - cord_face[0];
822 normal_face = cord_face[0] - cord_face[1];
823 normal_face.normalize();
837 _checkValidItem(face);
845 ARCANE_FATAL(
"Can not remove cell lid={0} from face uid={1} with no cell connected",
846 cell_to_remove_lid, face.
uniqueId());
849 Integer nb_cell_after = nb_cell - 1;
850 const Int32 null_cell_lid = NULL_ITEM_LOCAL_ID;
861 subFaces(face, subfaces);
862 for (
Integer s = 0, ss = subfaces.
size(); s < ss; s++) {
864 Int32 cell0 = face2->cellId(0);
865 Int32 cell1 = face2->cellId(1);
868 if (cell0 == cell_to_remove_lid) {
881 if (nb_cell_after != 0) {
886 if (cell0 == cell_to_remove_lid) {
908 _checkValidItem(face);
919_addMasterFaceToFace(
Face face,
Face master_face)
921 m_face_connectivity->addConnectedItem(face, master_face);
932 for (
Integer i = 0; i < nb_slave; ++i)
933 m_face_connectivity->addConnectedItem(master_face,
ItemLocalId(slave_faces_lid[i]));
941_removeMasterFaceToFace(Face face)
943 m_face_connectivity->removeConnectedItems(face);
951_removeSlaveFacesToFace(Face master_face)
953 m_face_connectivity->removeConnectedItems(master_face);
963 TiedInterfaceFaceList tied_faces(interface->
tiedFaces());
967 Face master_face = *imaster_face;
968 Integer index = imaster_face.index();
972 for (
Integer zz = 0; zz < nb_slave; ++zz) {
973 TiedFace tn = tied_faces[index][zz];
976 _addMasterFaceToFace(slave_face, master_face);
978 _addSlaveFacesToFace(master_face, slave_faces);
988 TiedInterfaceFaceList tied_faces(interface->
tiedFaces());
991 Face master_face = *imaster_face;
992 Integer index = imaster_face.index();
995 for (
Integer zz = 0; zz < nb_slave; ++zz) {
996 TiedFace tn = tied_faces[index][zz];
998 _removeMasterFaceToFace(slave_face);
1000 _removeSlaveFacesToFace(master_face);
1008setConnectivity(
const Integer c)
1010 m_mesh_connectivity = c;
1011 m_has_face = Connectivity::hasConnectivity(m_mesh_connectivity, Connectivity::CT_HasFace);
1013 m_node_prealloc = Connectivity::getPrealloc(m_mesh_connectivity,
IK_Face,
IK_Node);
1014 if (Connectivity::hasConnectivity(m_mesh_connectivity, Connectivity::CT_HasEdge))
1015 m_edge_prealloc = Connectivity::getPrealloc(m_mesh_connectivity,
IK_Face,
IK_Edge);
1016 m_face_connectivity->setPreAllocatedSize(4);
1017 m_cell_prealloc = Connectivity::getPrealloc(m_mesh_connectivity,
IK_Face,
IK_Cell);
1018 m_node_connectivity->setPreAllocatedSize(m_node_prealloc);
1019 m_cell_connectivity->setPreAllocatedSize(m_cell_prealloc);
1020 debug() <<
"Family " <<
name() <<
" prealloc "
1021 << m_node_prealloc <<
" by node, "
1022 << m_edge_prealloc <<
" by edge, "
1023 << m_cell_prealloc <<
" by cell.";
1031reorientFacesIfNeeded()
1035 mesh::FaceReorienter face_reorienter(
mesh());
1037 face_reorienter.checkAndChangeOrientationAMR(*iface);
#define ARCANE_CHECK_POINTER(ptr)
Macro returning the pointer ptr if it is not null or throwing an exception if it is null.
#define ARCANE_FATAL(...)
Macro throwing a FatalErrorException.
Integer size() const
Number of elements in the vector.
void clear()
Removes the elements from the array.
void add(ConstReferenceType val)
Adds element val to the end of the array.
Constant view of an array of type T.
constexpr Integer size() const noexcept
Number of elements in the array.
Cell frontCell() const
Cell in front of the face (null cell if none).
CellLocalId cellId(Int32 i) const
i-th cell of the face
EdgeLocalIdView edgeIds() const
List of edges of the face.
Int32 nbCell() const
Number of cells of the face (1 or 2).
Cell backCell() const
Cell behind the face (null cell if none).
virtual void findAndReplaceCell(ItemLocalId item_lid, ItemLocalId old_cell_lid, ItemLocalId new_cell_lid)=0
Finds and replaces a cell of an entity.
virtual IItemFamily * nodeFamily()=0
Returns the node family.
virtual IItemFamily * edgeFamily()=0
Returns the edge family.
virtual bool useMeshItemFamilyDependencies() const =0
check if the network itemFamily dependencies is activated
virtual IItemFamilyNetwork * itemFamilyNetwork()=0
Family network interface (connected families).
Interface of a class managing semi-conforming mesh.
virtual TiedInterfaceFaceList tiedFaces() const =0
List of information about the slave faces of a master face.
virtual FaceGroup masterInterface() const =0
Group containing the master faces.
bool isSuppressed() const
True if the entity is suppressed.
@ II_MasterFace
The entity is a master face of an interface.
@ II_HasBackCell
The entity has a back cell.
@ II_SlaveFace
The entity is a slave face of an interface.
@ II_HasFrontCell
The entity has a front cell.
Internal structure of a mesh entity.
Index of an Item in a variable.
Utility class for printing information about an entity.
Type of an entity (Item).
Info on a mesh entity type.
NodeLocalId nodeId(Int32 index) const
i-th node of the entity.
Int32 nbLinearNode() const
Number of nodes of the associated linear entity (if entity order 2 or more).
Base class for a mesh element.
impl::MutableItemBase mutableItemBase() const
Mutable internal part of the entity.
constexpr Int32 localId() const
Local identifier of the entity in the processor subdomain.
constexpr bool hasFlags(Int32 flags) const
Returns if the flags are set for the entity.
ItemUniqueId uniqueId() const
Unique identifier across all domains.
impl::ItemBase itemBase() const
Internal part of the entity.
void _setFaceBackAndFrontCells(Int32 back_cell_lid, Int32 front_cell_lid)
For a face, positions both the back cell and the front cell.
void addFlags(Int32 added_flags)
Adds the flags added_flags to those of the entity.
Unicode character string.
Semi-conforming mesh face.
Face face() const
Welded face.
TraceMessageDbg debug(Trace::eDebugLevel=Trace::Medium) const
Flow for a debug message.
1D data vector with value semantics (STL style).
void removeFaceFromEdge(ItemLocalId edge, ItemLocalId face_to_remove)
Removes a face from an edge.
void replaceCell(ItemLocalId item_lid, Integer index, ItemLocalId new_lid) override
Replaces a cell of an entity.
void replaceEdge(ItemLocalId item_lid, Integer index, ItemLocalId new_lid) override
Replaces an edge of an entity.
void replaceNode(ItemLocalId item_lid, Integer index, ItemLocalId new_lid) override
Replaces a node of an entity.
void setBackAndFrontCells(FaceLocalId face_lid, CellLocalId back_cell_lid, CellLocalId front_cell_lid) override
Positions a cell in front and behind a face.
void replaceFace(ItemLocalId item_lid, Integer index, ItemLocalId new_lid) override
Replaces a face of an entity.
void replaceNode(ItemLocalId face, Integer index, ItemLocalId node)
Replaces the node at index index of the face face with that of localId() node_lid.
void setBackAndFrontCells(Face face, Int32 back_cell_lid, Int32 front_cell_lid)
Positions the cell behind and in front of the face.
NodeFamily * m_node_family
Node family associated with this family.
void removeEdgeFromFace(Face face, Edge edge_to_remove)
Removes an edge from the face.
void replaceEdge(ItemLocalId face, Integer index, ItemLocalId edge)
Replaces the edge at index index of the face face with that of localId() edge_lid.
Item allocOne(Int64 uid, ItemTypeId type_id, MeshInfos &mesh_info) override
Allocates a face with unique number uid and type type. Generic item addition.
void applyTiedInterface(ITiedInterface *interface)
Sets the information related to the tied interface interface.
Item findOrAllocOne(Int64 uid, ItemTypeId type_id, MeshInfos &mesh_info, bool &is_alloc) override
Retrieves or allocates a face with unique number uid and type type.
EdgeFamily * m_edge_family
Edge family associated with this family.
void removeCellFromFace(Face face, ItemLocalId cell_to_remove_lid)
Removes a cell from the face.
void replaceCell(ItemLocalId face, Integer index, ItemLocalId cell)
Replaces the cell at index index of the face face with that of localId() cell_lid.
void addFrontCellToFace(Face face, Cell new_cell)
Adds a front cell to the face.
bool m_check_orientation
Indicates whether to check the orientation.
virtual void computeSynchronizeInfos() override
Constructs the structures necessary for synchronization.
void addEdgeToFace(Face face, Edge new_edge)
Adds an edge to the face.
void removeFaceIfNotConnected(Face face)
Removes the face if it is no longer connected.
void removeTiedInterface(ITiedInterface *interface)
Removes the information related to the tied interface interface.
void replaceBackCellToFace(Face face, ItemLocalId new_cell)
AMR.
void addBackCellToFace(Face face, Cell new_cell)
Adds a back cell to the face.
void replaceFace(ItemLocalId face, Integer index, ItemLocalId face2)
Replaces the face at index index of the face face with that of localId() face_lid.
IMesh * mesh() const override
Associated mesh.
IItemFamilyTopologyModifier * _topologyModifier() override
Topology modifier interface.
ItemGroup allItems() const override
Group of all entities.
void computeSynchronizeInfos() override
Constructs the structures necessary for synchronization.
String name() const override
Family name.
Class containing mesh information.
Integer & nbFace()
Number of faces in the mesh.
__host__ __device__ Real dot(Real2 u, Real2 v)
Dot product of u by v in .
__host__ __device__ Real3 vecMul(Real3 u, Real3 v)
Vector cross product of u by v in .
std::int64_t Int64
Signed integer type of 64 bits.
Int32 Integer
Type representing an integer.
UniqueArray< Real3 > Real3UniqueArray
Dynamic 1D array of rank 3 vectors.
ConstArrayView< Int32 > Int32ConstArrayView
C equivalent of a 1D array of 32-bit integers.
UniqueArray< Int32 > Int32UniqueArray
Dynamic 1D array of 32-bit integers.
SharedMeshVariableScalarRefT< Node, Real3 > SharedVariableNodeReal3
Quantity at the node of coordinate type.
@ IK_Node
Node mesh entity.
@ IK_Cell
Cell mesh entity.
@ IK_Face
Face mesh entity.
@ IK_Edge
Edge mesh entity.
double Real
Type representing a real number.
@ Cell
The mesh is AMR by cell.
std::int32_t Int32
Signed integer type of 32 bits.