14#include "arcane/mesh/OneMeshItemAdder.h"
16#include "arcane/utils/NotSupportedException.h"
17#include "arcane/utils/ValueConvert.h"
18#include "arcane/utils/FixedArray.h"
19#include "arcane/utils/HashTableMap2.h"
22#include "arcane/core/MeshToMeshTransposer.h"
23#include "arcane/core/IParallelMng.h"
24#include "arcane/core/ItemPrinter.h"
25#include "arcane/core/ItemTypeInfoBuilder.h"
26#include "arcane/core/internal/ItemTypeMngInternal.h"
28#include "arcane/mesh/DynamicMesh.h"
29#include "arcane/mesh/DynamicMeshIncrementalBuilder.h"
30#include "arcane/mesh/ItemTools.h"
31#include "arcane/mesh/ConnectivityNewWithDependenciesTypes.h"
32#include "arcane/mesh/GraphDoFs.h"
50 bool allow_build_face =
false)
51 : m_type_info(type_info)
52 , m_cell_uid(cell_uid)
56 , m_allow_build_face(allow_build_face)
59 Int64 uniqueId()
const {
return m_cell_uid; }
60 ItemTypeId itemTypeId()
const {
return m_type_id; }
62 Int32 owner()
const {
return m_owner; }
63 Integer nbNode()
const {
return m_info.size(); }
64 Integer nbFace()
const {
return m_type_info->nbLocalFace(); }
65 Integer nbEdge()
const {
return m_type_info->nbLocalEdge(); }
66 Int64 nodeUniqueId(
Integer i_node)
const {
return m_info[i_node]; }
70 bool allowBuildFace()
const {
return m_allow_build_face; }
71 bool allowBuildEdge()
const {
return m_allow_build_face; }
78 Int64 m_cell_uid = NULL_ITEM_UNIQUE_ID;
80 Int32 m_owner = A_NULL_RANK;
82 bool m_allow_build_face =
false;
91, m_mesh(mesh_builder->
mesh())
92, m_mesh_builder(mesh_builder)
93, m_cell_family(m_mesh->trueCellFamily())
94, m_node_family(m_mesh->trueNodeFamily())
95, m_face_family(m_mesh->trueFaceFamily())
96, m_edge_family(m_mesh->trueEdgeFamily())
97, m_item_type_mng(m_mesh->itemTypeMng())
102 m_work_face_orig_nodes_uid.reserve(100);
112 ItemInternal* node = m_node_family.findOrAllocOne(node_uid, is_add);
134 if (item.
nbNode() != nb_node)
135 ARCANE_FATAL(
"Trying to add existing item (kind='{0}', uid={1}) with different number of node (existing={2} new={3})",
139 for (
Int32 i = 0; i < nb_node; ++i) {
140 Int64 new_uid = nodes_uid[i];
142 if (new_uid != current_uid) {
143 std::ostringstream ostr;
144 for (
Int32 k = 0; k < nb_node; ++k)
146 ARCANE_FATAL(
"Trying to add existing item (kind='{0}', uid={1}) with different nodes (index={2} existing='{3}' new='{4}')",
147 item.
kind(), item.
uniqueId(), i, ostr.str(), nodes_uid);
162 if (uid != NULL_ITEM_UNIQUE_ID)
201 bool is_add_face =
false;
202 Face face = m_face_family.findOrAllocOne(face_uid, type_id, is_add_face);
207 for (
Integer i_node = 0; i_node < face_nb_node; ++i_node) {
209 m_face_family.replaceNode(face, i_node, node);
210 m_node_family.addFaceToNode(node, face);
218 return ItemCompatibility::_itemInternal(face);
227 m_work_edge_sorted_nodes.
resize(2);
228 m_work_edge_orig_nodes_uid.
resize(2);
230 for (
Integer z = 0; z < 2; ++z)
231 m_work_edge_orig_nodes_uid[z] = nodes_uid[z];
235 bool is_add_edge =
false;
242 for (
Integer i_node = 0; i_node < 2; ++i_node) {
245 m_node_family.addEdgeToNode(current_node_internal, edge);
255Face OneMeshItemAdder::
256_findInternalFace(
Integer i_face,
const FullCellInfo& cell_info,
bool& is_add)
258 const Int64 face_unique_id = cell_info.faceUniqueId(i_face);
259 ItemTypeInfo* cell_type_info = cell_info.
typeInfo();
260 const ItemTypeInfo::LocalFace& lf = cell_type_info->
localFace(i_face);
261 ItemTypeInfo* face_type_info = m_item_type_mng->typeFromId(lf.typeId());
262 return m_face_family.findOrAllocOne(face_unique_id, face_type_info, is_add);
269Face OneMeshItemAdder::
272 const ItemInternalMap& nodes_map = m_mesh->nodesMap();
273 ItemTypeInfo* cell_type_info = cell_info.typeInfo();
274 const ItemTypeInfo::LocalFace& lf = cell_type_info->localFace(i_face);
276 Int64 face_unique_id = NULL_ITEM_UNIQUE_ID;
286 face_internal = m_face_family.itemsMap().tryFind(face_unique_id);
291 Node nbi = nodes_map.findItem(face_sorted_nodes[0]);
294 if (face_internal.null()) {
298 info() <<
"BadCell uid=" << cell_info.uniqueId();
299 for (
Int32 i = 0; i < cell_info.nbNode(); ++i)
300 info() <<
"Cell node I=" << i <<
" uid=" << cell_info.nodeUniqueId(i);
301 ARCANE_FATAL(
"On the fly face allocation is not allowed here.\n"
302 " You need to add faces with IMeshModifier::addFaces().\n"
303 " CellUid={0} LocalFace={1} FaceNodes={2}",
304 cell_info.uniqueId(), i_face, face_sorted_nodes);
310 ItemTypeInfo* face_type = m_item_type_mng->typeFromId(lf.typeId());
311 return m_face_family.allocOne(face_unique_id, face_type);
315 return face_internal;
323Edge OneMeshItemAdder::
324_findInternalEdge(
Integer i_edge,
const FullCellInfo& cell_info,
325 Int64 first_node,
Int64 second_node,
bool& is_add)
327 ARCANE_UNUSED(first_node);
328 ARCANE_UNUSED(second_node);
330 const Int64 edge_unique_id = cell_info.edgeUniqueId(i_edge);
331 return m_edge_family.findOrAllocOne(edge_unique_id, is_add);
338Edge OneMeshItemAdder::
341 ARCANE_UNUSED(i_edge);
344 FixedArray<Int64, 2> nodes;
345 Int64 edge_unique_id = NULL_ITEM_UNIQUE_ID;
348 nodes[0] = first_node;
349 nodes[1] = second_node;
350 edge_unique_id = MeshUtils::generateHashUniqueId(nodes.view());
351 edge_internal = m_edge_family.itemsMap().tryFind(edge_unique_id);
354 const ItemInternalMap& nodes_map = m_mesh->nodesMap();
355 Node nbi = nodes_map.findItem(first_node);
358 if (edge_internal.null()) {
359 if (!cell_info.allowBuildEdge() && !use_hash)
360 ARCANE_FATAL(
"On the fly edge allocation is not allowed here."
361 " You need to add edges before with IMeshModifier::addEdges()");
365 return m_edge_family.allocOne(edge_unique_id);
369 return edge_internal;
391ItemInternal* OneMeshItemAdder::
392addOneCell(ItemTypeId type_id,
Int64 cell_uid,
Int32 owner,
393 ConstArrayView<Int64> nodes_uid,
bool allow_build_face)
395 if (type_id == ITI_GenericPolyhedron)
396 return _addOnePolyhedron(cell_uid, nodes_uid, owner, allow_build_face);
397 CellInfoProxy cell_info_proxy(type_id, m_item_type_mng->typeFromId(type_id), cell_uid, owner, nodes_uid, allow_build_face);
427 ARCANE_ASSERT(m_mesh->
itemFamilyNetwork(), (
"ItemFamilyNetwork is required to call OneMeshItemAdder::addOneItem"));
428 bool is_alloc =
true;
429 Item item = family_modifier->findOrAllocOne(item_uid, type_id,
m_mesh_info, is_alloc);
433 for (
Integer family_index = 0; family_index < nb_connected_family; ++family_index) {
436 Int32 nb_connected_item = CheckedConvert::toInt32(connectivity_info[info_index++]);
439 String connectivity_name = mesh::connectivityName(family, connected_family);
440 String reverse_connectivity_name = mesh::connectivityName(connected_family, family);
441 bool is_dependency =
false;
447 _clearConnectivity(
ItemLocalId(item), family_to_connected_family);
448 if (connected_family_to_family)
449 _clearReverseConnectivity(
ItemLocalId(item), family_to_connected_family, connected_family_to_family);
454 for (
Integer connected_item_index = 0; connected_item_index < nb_connected_item; ++connected_item_index) {
455 if (family_to_connected_family) {
462 if (connected_family_to_family)
463 connected_family_to_family->
addConnectedItem(ItemLocalId(connected_item_lids[connected_item_index]), ItemLocalId(item));
465 info_index += nb_connected_item;
469 return ItemCompatibility::_itemInternal(item);
474ItemInternal* OneMeshItemAdder::
475addOneItem2(IItemFamily* family,
476 IItemFamilyModifier* family_modifier,
484 ARCANE_ASSERT(m_mesh->itemFamilyNetwork(), (
"ItemFamilyNetwork is required to call OneMeshItemAdder::addOneItem"));
485 bool is_alloc =
true;
486 Item item = family_modifier->findOrAllocOne(item_uid, type_id,
m_mesh_info, is_alloc);
490 for (
Integer family_index = 0; family_index < nb_connected_family; ++family_index) {
494 Int32 nb_connected_item = CheckedConvert::toInt32(connectivity_info[info_index++]);
495 if (nb_connected_item == 0)
497 IItemFamily* connected_family =
nullptr;
498 switch (family_kind) {
500 connected_family = m_mesh->findItemFamily(family_kind, ParticleFamily::defaultFamilyName(),
false,
false);
503 if (family->name() == GraphDoFs::dualNodeFamilyName())
504 connected_family = m_mesh->findItemFamily(family_kind, GraphDoFs::linkFamilyName(),
false,
false);
506 connected_family = m_mesh->findItemFamily(family_kind, GraphDoFs::dualNodeFamilyName(),
false,
false);
509 connected_family = m_mesh->itemFamily(family_kind);
513 String connectivity_name = mesh::connectivityName(family, connected_family);
514 bool is_dependency =
false;
515 IIncrementalItemConnectivity* family_to_connected_family = m_mesh->itemFamilyNetwork()->getConnectivity(family, connected_family, connectivity_name, is_dependency);
516 if (!family_to_connected_family)
517 ARCANE_FATAL(
"Cannot find connectivity name={0}", connectivity_name);
518 bool is_deep_connectivity = m_mesh->itemFamilyNetwork()->isDeep(family_to_connected_family);
519 bool is_relation = !(is_dependency && is_deep_connectivity);
523 bool do_fatal = is_relation ? false :
true;
524 connected_family->itemsUniqueIdToLocalId(connected_item_lids, connectivity_info.subView(info_index, nb_connected_item), do_fatal);
526 Integer nb_connected_item_found = nb_connected_item;
528 for (
Integer index = 0; index < connected_item_lids.size();) {
529 if (connected_item_lids[index] == NULL_ITEM_LOCAL_ID) {
530 connected_item_lids.remove(index);
531 --nb_connected_item_found;
537 for (
Integer connected_item_index = 0; connected_item_index < nb_connected_item_found; ++connected_item_index) {
538 if (family_to_connected_family) {
540 auto connected_item_lid = ItemLocalId{ connected_item_lids[connected_item_index] };
542 if (!family_to_connected_family->hasConnectedItem(ItemLocalId(item), connected_item_lid)) {
543 family_to_connected_family->addConnectedItem(ItemLocalId(item), connected_item_lid);
547 family_to_connected_family->replaceConnectedItem(ItemLocalId(item), connected_item_index, connected_item_lid);
551 info_index += nb_connected_item;
554 debug(
Trace::Highest) <<
"[addItems] ADD_ITEM " << ItemPrinter(item) <<
" in " << family->name();
557 return ItemCompatibility::_itemInternal(item);
562void OneMeshItemAdder::
563_printRelations(ItemInternal* item)
565 debug(
Trace::Highest) <<
"[addItems] RELATIONS for " << ItemPrinter(item) <<
" in " << item->family()->name();
566 for (
const auto& relation : m_mesh->itemFamilyNetwork()->getChildRelations(item->family())) {
569 ConnectivityItemVector connected_items(relation);
570 for (
const auto& connected_item : connected_items.connectedItems(ItemLocalId(item))) {
579void OneMeshItemAdder::
580_clearConnectivity(ItemLocalId item, IIncrementalItemConnectivity* connectivity)
583 ConnectivityItemVector accessor(connectivity);
585 connectivity->removeConnectedItem(item, connected_item);
592void OneMeshItemAdder::
593_clearReverseConnectivity(ItemLocalId item, IIncrementalItemConnectivity* connectivity, IIncrementalItemConnectivity* reverse_connectivity)
595 ConnectivityItemVector accessor(connectivity);
597 reverse_connectivity->removeConnectedItem(connected_item, item);
604template <>
void OneMeshItemAdder::
608 if (m_mesh->isAmrActivated()) {
611 if (cell_info.
level() != 0) {
612 Integer child_rank = cell_info.whichChildAmI();
613 Int64 hParent_uid = cell_info.hParentCellUniqueId();
616 Cell hParent_cell = m_cell_family.findOrAllocOne(hParent_uid, cell_type, is_add);
617 m_cell_family._addParentCellToCell(new_cell, hParent_cell);
618 m_cell_family._addChildCellToCell(hParent_cell, child_rank, new_cell);
623template <>
void OneMeshItemAdder::
624_AMR_Patch(
Cell cell,
const CellInfoProxy& cell_info)
627 ARCANE_UNUSED(cell_info);
637template <
typename CellInfo>
645 const bool is_verbose =
false;
647 info() <<
"AddNewCell type_id=" << cell_type_id <<
" nb_node=" << cell_info.nbNode()
648 <<
" type=" << cell_type_info->
typeName();
653 inew_cell = m_cell_family.findOrAllocOne(cell_info.uniqueId(), cell_type_info, is_add);
656 Cell cell2(inew_cell);
658 for (
Integer i = 0, is = cell_info.nbNode(); i < is; ++i)
659 if (cell_info.nodeUniqueId(i) != cell2.
node(i).
uniqueId())
660 ARCANE_FATAL(
"trying to add existing cell (uid={0}) with different nodes",
661 cell_info.uniqueId());
663 return ItemCompatibility::_itemInternal(inew_cell);
667 Cell new_cell(inew_cell);
671 const MeshKind& mesh_kind = m_mesh->meshKind();
673 const Int32 cell_nb_face = cell_info.nbFace();
676 mut_cell.
addFlags(ItemFlags::II_HasEdgeFor1DItems);
680 if (cell_info.nbNode() != inew_cell.
nbNode())
681 ARCANE_FATAL(
"Incoherent number of nodes v={0} expected={1}", inew_cell.
nbNode(), cell_info.nbNode());
682 if (cell_nb_face != inew_cell.
nbFace())
683 ARCANE_FATAL(
"Incoherent number of faces v={0} expected={1}", inew_cell.
nbFace(), cell_nb_face);
685 ARCANE_FATAL(
"Type '{0}' is not allowed for 'Cell' (cell_uid={1})",
686 cell_type_info->
typeName(), cell_info.uniqueId());
687 if (!allow_multi_dim_cell) {
689 Int32 mesh_dimension = m_mesh->dimension();
690 if (cell_dimension >= 0 && cell_dimension != mesh_dimension)
691 ARCANE_FATAL(
"Incoherent dimension for cell uid={0} cell_dim={1} mesh_dim={2} type={3}",
692 cell_info.uniqueId(), cell_dimension, mesh_dimension, cell_type_info->
typeName());
701 if (m_mesh_builder->hasEdge()) {
702 const Int32 cell_nb_edge = cell_info.nbEdge();
704 for (
Integer i_edge = 0; i_edge < cell_nb_edge; ++i_edge) {
707 Int64 second_node = cell_info.nodeUniqueId(le.
endNode());
708 if (first_node > second_node)
709 std::swap(first_node, second_node);
712 Edge edge_internal = _findInternalEdge(i_edge, cell_info, first_node, second_node, is_add);
720 m_edge_family.replaceNode(
ItemLocalId(edge_internal), 0, current_node);
721 m_node_family.addEdgeToNode(current_node, edge_internal);
725 m_edge_family.replaceNode(
ItemLocalId(edge_internal), 1, current_node);
726 m_node_family.addEdgeToNode(current_node, edge_internal);
732 m_edge_family.addCellToEdge(edge_internal, inew_cell);
737 for (
Integer i_face = 0; i_face < cell_nb_face; ++i_face) {
741 const bool is_reorder = _isReorder(i_face, lf, cell_info);
744 Face face = _findInternalFace(i_face, cell_info, is_add);
751 info() <<
"AddFaceToCell (cell_uid=" << new_cell.
uniqueId() <<
": Create face (index=" << i_face
754 <<
" type=" << face_type_info->
typeName()
755 <<
" face_nb_linear_node=" << face_nb_linear_node
756 <<
" sorted_nodes=" << face_sorted_nodes;
760 for (
Integer i_node = 0; i_node < face_nb_node; ++i_node) {
762 info() <<
"AddNodeToFace i_node=" << i_node <<
" uid=" << face_sorted_nodes[i_node];
763 Node current_node = nodes_map.
findItem(face_sorted_nodes[i_node]);
764 m_face_family.replaceNode(face, i_node, current_node);
765 if (i_node < face_nb_linear_node) {
766 m_node_family.addFaceToNode(current_node, face);
770 if (m_mesh_builder->hasEdge()) {
772 for (
Integer i_edge = 0; i_edge < face_nb_edge; ++i_edge) {
774 m_face_family.addEdgeToFace(face, current_edge);
775 m_edge_family.addFaceToEdge(current_edge, face);
780 m_cell_family.replaceFace(new_cell, i_face, face);
783 if (m_mesh->isAmrActivated()) {
786 m_face_family.replaceFrontCellToFace(face, new_cell);
788 m_face_family.addFrontCellToFace(face, inew_cell);
792 m_face_family.replaceBackCellToFace(face, new_cell);
794 m_face_family.addBackCellToFace(face, inew_cell);
799 m_face_family.addFrontCellToFace(face, inew_cell);
802 m_face_family.addBackCellToFace(face, inew_cell);
807 _AMR_Patch(inew_cell, cell_info);
808 return ItemCompatibility::_itemInternal(inew_cell);
817 const bool is_verbose =
false;
819 info() <<
"AddNewPolyhedronCell nb_connectivity=" << connectivity_infos.
size()
820 <<
" c=" << connectivity_infos;
838 Int16 nb_local_node = 0;
839 nodes_of_cell.
clear();
840 connectivity_to_local_index.clear();
841 local_nodes_of_cell.
clear();
842 arcane_faces_nb_node.
clear();
843 arcane_faces_nodes.
clear();
851 Int32 array_size =
static_cast<Int32>(connectivity_infos[0]);
852 if (array_size != connectivity_infos.
size())
853 ARCANE_FATAL(
"Incoherent size array_size={0} connectivity_info={1}", array_size, connectivity_infos.
size());
854 Int32 scheme_version =
static_cast<Int32>(connectivity_infos[1]);
855 if (scheme_version != 1)
856 ARCANE_FATAL(
"Insupported scheme version '{0}'. Only supported value is 1", scheme_version);
857 const Int32 cell_nb_face =
static_cast<Int32>(connectivity_infos[2]);
859 info() <<
"NB_FACE=" << cell_nb_face;
860 Int32 index_in_connectivity = 3;
861 for (
Int32 z = 0; z < cell_nb_face; ++z) {
862 const Int16 face_nb_node =
static_cast<Int16>(connectivity_infos[index_in_connectivity]);
863 ++index_in_connectivity;
865 info() <<
"NB_FACE_NODE=" << face_nb_node;
866 nodes_of_face.
resize(face_nb_node);
867 arcane_faces_nb_node.
add(face_nb_node);
868 for (
Int16 k = 0; k < face_nb_node; ++k) {
869 Int64 node_id = connectivity_infos[index_in_connectivity];
870 ++index_in_connectivity;
871 auto x = connectivity_to_local_index.find(node_id);
872 Int16 local_node_index = -1;
874 if (x == connectivity_to_local_index.end()) {
875 local_node_index = nb_local_node;
876 connectivity_to_local_index[node_id] = nb_local_node;
878 local_nodes_of_cell.
add(local_node_index);
879 nodes_of_cell.
add(node_id);
880 cell_nodes_uid.
add(node_id);
883 local_node_index = x->second;
884 nodes_of_face[k] = local_node_index;
885 arcane_faces_nodes.
add(local_node_index);
889 info() <<
" Polyhedral face=" << z <<
" nb_node=" << face_nb_node
890 <<
" nodes=" << nodes_of_face.
view() <<
" index=" << index_in_connectivity;
894 info() <<
"EndCreateTypeForPolyhedron nb_node=" << nodes_of_cell.
size();
895 ItemTypeMngInternal* api = m_item_type_mng->_internalApi();
896 SmallArray<Int32> type_ids_buffer;
897 ItemTypeInfoBuilder cell_type_info;
898 api->fillTemporaryTypeForPolyhedron(&cell_type_info, &type_ids_buffer, nodes_of_cell.
size(),
899 arcane_faces_nb_node, arcane_faces_nodes);
900 CellInfoProxy cell_info_proxy(ITI_GenericPolyhedron, &cell_type_info, cell_uid, owner, nodes_of_cell, allow_build_face);
929 if (item.
type() == IT_Line2 && submesh_kind ==
IK_Cell)
931 if (item.
type() == IT_Vertex && submesh_kind ==
IK_Face)
942 switch (submesh_kind) {
944 new_item = m_node_family.findOrAllocOne(item.
uniqueId(), is_add);
948 new_item = m_edge_family.findOrAllocOne(item.
uniqueId(), is_add);
952 new_item = m_face_family.findOrAllocOne(item.
uniqueId(),
type, is_add);
958 new_item = m_cell_family.findOrAllocOne(item.
uniqueId(), type_id, is_add);
966 if (fatal_on_existing_item)
967 ARCANE_FATAL(
"Cannot add already existing parent item in submesh");
969 return ItemCompatibility::_itemInternal(new_item);
981 switch (submesh_kind) {
983 item_nb_face =
type->nbLocalFace();
984 item_nb_edge =
type->nbLocalEdge();
985 item_nb_node =
type->nbLocalNode();
988 item_nb_edge =
type->nbLocalEdge();
989 item_nb_node =
type->nbLocalNode();
992 item_nb_node =
type->nbLocalNode();
998 if (!m_mesh_builder->hasEdge())
1004 for (
Integer z = 0; z < item_nb_face; ++z)
1005 new_item->_setFace(z, NULL_ITEM_ID);
1006 for (
Integer z = 0; z < item_nb_edge; ++z)
1007 new_item->_setEdge(z, NULL_ITEM_ID);
1008 for (
Integer z = 0; z < item_nb_node; ++z)
1009 new_item->_setNode(z, NULL_ITEM_ID);
1014 DynamicMeshKindInfos::ItemInternalMap& nodes_map = m_mesh->nodesMap();
1016 DynamicMeshKindInfos::ItemInternalMap& parent_nodes_map = parent_mesh->nodesMap();
1021 const bool direct_node_order =
1022 !(submesh_kind ==
IK_Cell && kind ==
IK_Face && !(item.
toFace().isSubDomainBoundaryOutside()));
1025 for (
Integer i_node = 0; i_node < item_nb_node; ++i_node) {
1027 if (
type->typeId() == IT_FaceVertex)
1030 Int32 idx = ((direct_node_order) ? i_node : (item_nb_node - 1 - i_node));
1033 Int64 new_node_uid = nodes_uid[i_node] = parent_item.
uniqueId();
1034 ItemInternal* node_internal = m_node_family.findOrAllocOne(new_node_uid, is_add);
1036#ifdef ARCANE_DEBUG_DYNAMIC_MESH
1037 info() <<
"Création node " << new_node_uid <<
' '
1048 switch (submesh_kind) {
1050 m_cell_family.replaceNode(new_item_lid, i_node, node_lid);
1051 m_node_family.addCellToNode(node_internal, new_item.
toCell());
1054 m_face_family.replaceNode(new_item_lid, i_node, node_lid);
1055 m_node_family.addFaceToNode(node_internal, new_item.
toFace());
1058 m_edge_family.replaceNode(new_item_lid, i_node, node_lid);
1059 m_node_family.addEdgeToNode(node_internal, new_item.
toEdge());
1067 for (
Integer i_edge = 0; i_edge < item_nb_edge; ++i_edge) {
1072 if (first_node > second_node)
1073 std::swap(first_node, second_node);
1076 if (parent_item.
null())
1081 ItemInternal* edge_internal = m_edge_family.findOrAllocOne(new_edge_uid, is_add);
1083#ifdef ARCANE_DEBUG_DYNAMIC_MESH
1084 info() <<
"Création edge " << new_edge_uid <<
' '
1092 m_edge_family.replaceNode(
ItemLocalId(edge_internal), 0, current_node);
1093 m_node_family.addEdgeToNode(current_node, edge_internal);
1097 m_edge_family.replaceNode(
ItemLocalId(edge_internal), 1, current_node);
1098 m_node_family.addEdgeToNode(current_node, edge_internal);
1104 switch (submesh_kind) {
1107 m_edge_family.addCellToEdge(edge_internal, new_item.
toCell());
1111 m_edge_family.addFaceToEdge(edge_internal, new_item.
toFace());
1120 for (
Integer i_face = 0; i_face < item_nb_face; ++i_face) {
1124 m_work_face_orig_nodes_uid.resize(face_nb_node);
1125 for (
Integer z = 0; z < face_nb_node; ++z)
1126 m_work_face_orig_nodes_uid[z] = nodes_uid[lf.
node(z)];
1127 bool is_reorder =
false;
1128 if (m_mesh->dimension() == 1) {
1129 is_reorder =
m_face_reorderer.reorder1D(i_face, m_work_face_orig_nodes_uid[0]);
1141 if (m_mesh->dimension() == 1) {
1142 parent_item = parent_nodes_map.
findItem(face_sorted_nodes[0]);
1146 Int64 first_node = face_sorted_nodes[0];
1147 Int64 second_node = face_sorted_nodes[1];
1148 if (first_node > second_node)
1149 std::swap(first_node, second_node);
1155 if (parent_item.
null())
1160 ItemInternal* face_internal = m_face_family.findOrAllocOne(new_face_uid, face_type, is_add);
1162#ifdef ARCANE_DEBUG_DYNAMIC_MESH
1163 info() <<
"Création face " << new_face_uid <<
' '
1169 for (
Integer i_node = 0; i_node < face_nb_node; ++i_node) {
1170 Node current_node = nodes_map.
findItem(face_sorted_nodes[i_node]);
1171 m_face_family.replaceNode(
ItemLocalId(face_internal), i_node, current_node);
1172 m_node_family.addFaceToNode(current_node, face_internal);
1175 if (m_mesh_builder->hasEdge()) {
1177 for (
Integer i_edge = 0; i_edge < face_nb_edge; ++i_edge) {
1179 Edge current_edge = new_item.
itemBase().edgeBase(edge_idx);
1180 m_face_family.addEdgeToFace(face_internal, current_edge);
1181 m_edge_family.addFaceToEdge(current_edge, face_internal);
1188 m_face_family.addFrontCellToFace(face_internal, new_item.
toCell());
1191 m_face_family.addBackCellToFace(face_internal, new_item.
toCell());
1195 return ItemCompatibility::_itemInternal(new_item);
1204template <
typename CellInfo>
1208 Integer cell_nb_node = cell_info.nbNode();
1211 for (
Integer i_node = 0; i_node < cell_nb_node; ++i_node) {
1212 Int64 node_unique_id = cell_info.nodeUniqueId(i_node);
1213 bool is_add =
false;
1214 ItemInternal* node_internal = m_node_family.findOrAllocOne(node_unique_id, is_add);
1219 m_node_family.addCellToNode(node_internal, cell);
1220 m_cell_family.replaceNode(cell, i_node,
ItemLocalId(node_internal));
1227template <
typename CellInfo>
1228bool OneMeshItemAdder::
1232 m_work_face_orig_nodes_uid.
resize(face_nb_node);
1233 for (
Integer i_node = 0; i_node < face_nb_node; ++i_node)
1234 m_work_face_orig_nodes_uid[i_node] = cell_info.nodeUniqueId(lf.
node(i_node));
1235 bool is_reorder =
false;
1237 is_reorder =
m_face_reorderer.reorder1D(i_face, m_work_face_orig_nodes_uid[0]);
1265 ARCANE_FATAL(
"Can not call this method when edge or face are already created");
#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.
Utility functions for the mesh.
bool reorderNodesOfFace(Int64ConstArrayView before_ids, Int64ArrayView after_ids)
Reorders the nodes of a face.
Int64 generateHashUniqueId(SmallSpan< const Int64 > nodes_unique_id)
Generates a unique identifier from a list of node identifiers.
Integer size() const
Number of elements in the vector.
void resize(Int64 s)
Changes the number of elements in the array to s.
void clear()
Removes the elements from the array.
void add(ConstReferenceType val)
Adds element val to the end of the array.
ArrayView< T > view() const
Mutable view of this array.
Face face(Int32 i) const
i-th face of the cell
Int32 nbFace() const
Number of faces of the cell.
Edge edge(Int32 i) const
i-th edge of the cell
Constant view of an array of type T.
constexpr ConstArrayView< T > subView(Integer abegin, Integer asize) const noexcept
Sub-view (constant) starting from element abegin and containing asize elements.
constexpr Integer size() const noexcept
Number of elements in the array.
Int32 nbCell() const
Number of cells of the face (1 or 2).
bool isSubDomainBoundary() const
Indicates if the face is on the subdomain boundary (i.e nbCell()==1).
Interface for managing an incremental connectivity.
virtual void replaceConnectedItem(ItemLocalId source_item, Integer index, ItemLocalId target_local_id)=0
Replaces the entity at index index of source_item with the entity with localId() target_local_id.
virtual void addConnectedItem(ItemLocalId source_item, ItemLocalId target_local_id)=0
Adds the entity with localId() target_local_id to the connectivity of source_item.
Interface for modifying a family.
virtual IIncrementalItemConnectivity * getStoredConnectivity(IItemFamily *source_family, IItemFamily *target_family, const String &name)=0
Returns, if associated with storage, the connectivity between the families source_family and target_f...
Interface of an entity family.
virtual String name() const =0
Family name.
virtual void itemsUniqueIdToLocalId(Int32ArrayView local_ids, Int64ConstArrayView unique_ids, bool do_fatal=true) const =0
Converts an array of unique numbers to local numbers.
ItemUniqueId uniqueId() const
Unique number of the entity.
ItemTypeInfo * typeInfo() const
Type of the entity.
Int32 localId() const
Local number (in the subdomain) of the entity.
Internal structure of a mesh entity.
Index of an Item in a variable.
Type of an entity (Item).
static ItemTypeId fromInteger(Int64 v)
Creates an instance from an integer.
Local information about a cell edge.
Integer endNode() const
Local index in the cell of the ending node of the edge.
Integer beginNode() const
Local index in the cell of the starting node of the edge.
Local information about a cell face.
Integer node(Integer i) const
Local index in the cell of the i-th node of the face.
Integer nbEdge() const
Number of edges of the face.
Integer typeId() const
Type of the face entity.
Integer edge(Integer i) const
Edge of the face.
Integer nbNode() const
Number of nodes of the face.
Info on a mesh entity type.
LocalEdge localEdge(Integer id) const
Local connectivity of the i-th edge of the cell.
LocalFace localFace(Integer id) const
Local connectivity of the i-th face of the cell.
const ItemTypeInfo * linearTypeInfo() const
Type of the corresponding linear element.
Int16 dimension() const
Dimension of the element (<0 if unknown).
Integer nbLocalNode() const
Number of nodes of the entity.
String typeName() const
Type name.
Integer nbLocalFace() const
Number of faces of the entity.
bool isValidForCell() const
Indicates if the type is valid for creating a cell.
ItemTypeId itemTypeId() const
Type number.
Mesh entity type manager.
ItemTypeInfo * typeFromId(Integer id) const
Type corresponding to the number id.
Mesh element based on nodes (Edge,Face,Cell).
Node node(Int32 i) const
i-th node of the entity
Int32 nbNode() const
Number of nodes of the entity.
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.
Edge toEdge() const
Converts the entity to the Edge kind.
Int32 owner() const
Owner subdomain number of the entity.
ItemWithNodes toItemWithNodes() const
Converts the entity to the ItemWithNodes kind.
Cell toCell() const
Converts the entity to the Cell kind.
ItemUniqueId uniqueId() const
Unique identifier across all domains.
constexpr bool null() const
true if the entity is null (i.e. not connected to the mesh)
Face toFace() const
Converts the entity to the Face kind.
impl::ItemBase itemBase() const
Internal part of the entity.
constexpr eItemKind kind() const
Entity kind.
Int16 type() const
Entity type.
Characteristics of a mesh.
bool isMonoDimension() const
True if the mesh structure is eMeshCellDimensionKind::MonoDimension.
static eItemKind kindTranspose(eItemKind kindA, IMesh *meshA, IMesh *meshB)
Transpose the kind kindA of mesh meshA to the associated kind in meshB.
Methods allowing modification of ItemBase.
void setOwner(Integer suid, Int32 current_sub_domain)
Sets the sub-domain number of the entity owner.
void setParent(Int32 aindex, Int32 parent_local_id)
Sets the i-th parent (currently aindex must be 0).
void addFlags(Int32 added_flags)
Adds the flags added_flags to those of the entity.
Exception when an operation is not supported.
1D data array with pre-allocated stack buffer.
Unicode character string.
TraceAccessor(ITraceMng *m)
Constructs an accessor via the trace manager m.
TraceMessageDbg debug(Trace::eDebugLevel=Trace::Medium) const
Flow for a debug message.
TraceMessage info() const
Flow for an information message.
ITraceMng * traceMng() const
Trace manager.
1D data vector with value semantics (STL style).
Implementation of std::unordered_map.
Implementation of a mesh.
IItemFamily * itemFamily(eItemKind ik) override
Returns the entity family of type ik.
Integer dimension() override
Mesh dimension (1D, 2D, or 3D).
IItemFamilyNetwork * itemFamilyNetwork() override
Family network interface (connected families).
Item findOrAllocOne(Int64 uid, ItemTypeId type_id, MeshInfos &mesh_info, bool &is_alloc) override
Retrieves or allocates a unique numbered edge uid and of type type.Generic item addition.
Info to create/serialize a cell knowing the uniqueId() and owner() of all these sub-entities (cells,...
Integer level() const
AMR.
Associative array of ItemInternal.
impl::ItemBase findItem(Int64 uid) const
Returns the unique ID entity uid.
Int32 rank() const
Number of this subdomain.
Integer & nbEdge()
Number of edges in the mesh.
Integer & nbNode()
Number of nodes in the mesh.
void _checkSameItemCoherency(ItemWithNodes item, ConstArrayView< Int64 > nodes_uid)
Checks the coherence of nodes for an already added item.
void _addNodesToCell(Cell cell, const CellInfo &cell_info)
Adds the nodes nodes_uid to the cell cell.
NodesOfItemReorderer m_face_reorderer
Work arrays.
ItemInternal * _addOneCell(const CellInfo &cell_info)
Adds a cell.
MeshInfos m_mesh_info
General information about the mesh (sub-domain number, number of items...).
Int64 _checkGenerateFaceUniqueId(Int64 uid, ConstArrayView< Int64 > nodes_uid)
Generates a uniqueId() for the face if uid is null.
Int64 m_next_edge_uid
Next uniqueId() number used for generating edges.
void setUseNodeUniqueIdToGenerateEdgeAndFaceUniqueId(bool v)
Positions the uniqueId() numbering mechanism.
void resetAfterDeallocate()
Resets the structures to allow for re-allocation.
bool m_use_hash_for_edge_and_face_unique_id
If true, generates face uniqueIds from node uniqueIds.
Int64 m_next_face_uid
Next uniqueId() number used for generating faces.
ItemInternal * addOneParentItem(const Item &item, const eItemKind submesh_kind, const bool fatal_on_existing_item=true)
Adds a parent item.
ItemInternal * addOneFace(ItemTypeId type_id, Int64 face_uid, Int32 owner_rank, Int64ConstArrayView nodes_uid)
Adds a face.
bool arcaneIsCheck()
True if running in check mode.
UniqueArray< Int64 > Int64UniqueArray
Dynamic 1D array of 64-bit integers.
std::int64_t Int64
Signed integer type of 64 bits.
Int32 Integer
Type representing an integer.
ConstArrayView< Int64 > Int64ConstArrayView
C equivalent of a 1D array of 64-bit integers.
UniqueArray< Int32 > Int32UniqueArray
Dynamic 1D array of 32-bit integers.
eItemKind
Mesh entity type.
@ IK_Particle
Particle mesh entity.
@ IK_Node
Node mesh entity.
@ IK_Cell
Cell mesh entity.
@ IK_Face
Face mesh entity.
@ IK_DoF
Degree of Freedom mesh entity.
@ IK_Edge
Edge mesh entity.
std::int16_t Int16
Signed integer type of 16 bits.
std::int32_t Int32
Signed integer type of 32 bits.