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/internal/ItemTypeMngInternal.h"
27#include "arcane/mesh/DynamicMesh.h"
28#include "arcane/mesh/DynamicMeshIncrementalBuilder.h"
29#include "arcane/mesh/ItemTools.h"
30#include "arcane/mesh/ConnectivityNewWithDependenciesTypes.h"
31#include "arcane/mesh/GraphDoFs.h"
49 bool allow_build_face =
false)
50 : m_type_info(type_info)
51 , m_cell_uid(cell_uid)
55 , m_allow_build_face(allow_build_face)
58 Int64 uniqueId()
const {
return m_cell_uid; }
59 ItemTypeId itemTypeId()
const {
return m_type_id; }
61 Int32 owner()
const {
return m_owner; }
62 Integer nbNode()
const {
return m_info.size(); }
63 Integer nbFace()
const {
return m_type_info->nbLocalFace(); }
64 Integer nbEdge()
const {
return m_type_info->nbLocalEdge(); }
65 Int64 nodeUniqueId(
Integer i_node)
const {
return m_info[i_node]; }
69 bool allowBuildFace()
const {
return m_allow_build_face; }
70 bool allowBuildEdge()
const {
return m_allow_build_face; }
77 Int64 m_cell_uid = NULL_ITEM_UNIQUE_ID;
79 Int32 m_owner = A_NULL_RANK;
81 bool m_allow_build_face =
false;
90, m_mesh(mesh_builder->
mesh())
91, m_mesh_builder(mesh_builder)
92, m_cell_family(m_mesh->trueCellFamily())
93, m_node_family(m_mesh->trueNodeFamily())
94, m_face_family(m_mesh->trueFaceFamily())
95, m_edge_family(m_mesh->trueEdgeFamily())
96, m_item_type_mng(m_mesh->itemTypeMng())
101 m_work_face_orig_nodes_uid.reserve(100);
111 ItemInternal* node = m_node_family.findOrAllocOne(node_uid, is_add);
133 if (item.
nbNode() != nb_node)
134 ARCANE_FATAL(
"Trying to add existing item (kind='{0}', uid={1}) with different number of node (existing={2} new={3})",
138 for (
Int32 i = 0; i < nb_node; ++i) {
139 Int64 new_uid = nodes_uid[i];
141 if (new_uid != current_uid) {
142 std::ostringstream ostr;
143 for (
Int32 k = 0; k < nb_node; ++k)
145 ARCANE_FATAL(
"Trying to add existing item (kind='{0}', uid={1}) with different nodes (index={2} existing='{3}' new='{4}')",
146 item.
kind(), item.
uniqueId(), i, ostr.str(), nodes_uid);
161 if (uid != NULL_ITEM_UNIQUE_ID)
200 bool is_add_face =
false;
201 Face face = m_face_family.findOrAllocOne(face_uid, type_id, is_add_face);
206 for (
Integer i_node = 0; i_node < face_nb_node; ++i_node) {
208 m_face_family.replaceNode(face, i_node, node);
209 m_node_family.addFaceToNode(node, face);
217 return ItemCompatibility::_itemInternal(face);
226 m_work_edge_sorted_nodes.
resize(2);
227 m_work_edge_orig_nodes_uid.
resize(2);
229 for (
Integer z = 0; z < 2; ++z)
230 m_work_edge_orig_nodes_uid[z] = nodes_uid[z];
234 bool is_add_edge =
false;
241 for (
Integer i_node = 0; i_node < 2; ++i_node) {
244 m_node_family.addEdgeToNode(current_node_internal, edge);
254Face OneMeshItemAdder::
255_findInternalFace(
Integer i_face,
const FullCellInfo& cell_info,
bool& is_add)
257 const Int64 face_unique_id = cell_info.faceUniqueId(i_face);
258 ItemTypeInfo* cell_type_info = cell_info.
typeInfo();
259 const ItemTypeInfo::LocalFace& lf = cell_type_info->
localFace(i_face);
260 ItemTypeInfo* face_type_info = m_item_type_mng->typeFromId(lf.typeId());
261 return m_face_family.findOrAllocOne(face_unique_id, face_type_info, is_add);
268Face OneMeshItemAdder::
271 const ItemInternalMap& nodes_map = m_mesh->nodesMap();
272 ItemTypeInfo* cell_type_info = cell_info.typeInfo();
273 const ItemTypeInfo::LocalFace& lf = cell_type_info->localFace(i_face);
275 Int64 face_unique_id = NULL_ITEM_UNIQUE_ID;
285 face_internal = m_face_family.itemsMap().tryFind(face_unique_id);
290 Node nbi = nodes_map.findItem(face_sorted_nodes[0]);
293 if (face_internal.null()) {
297 info() <<
"BadCell uid=" << cell_info.uniqueId();
298 for (
Int32 i = 0; i < cell_info.nbNode(); ++i)
299 info() <<
"Cell node I=" << i <<
" uid=" << cell_info.nodeUniqueId(i);
300 ARCANE_FATAL(
"On the fly face allocation is not allowed here.\n"
301 " You need to add faces with IMeshModifier::addFaces().\n"
302 " CellUid={0} LocalFace={1} FaceNodes={2}",
303 cell_info.uniqueId(), i_face, face_sorted_nodes);
309 ItemTypeInfo* face_type = m_item_type_mng->typeFromId(lf.typeId());
310 return m_face_family.allocOne(face_unique_id, face_type);
314 return face_internal;
322Edge OneMeshItemAdder::
323_findInternalEdge(
Integer i_edge,
const FullCellInfo& cell_info,
324 Int64 first_node,
Int64 second_node,
bool& is_add)
326 ARCANE_UNUSED(first_node);
327 ARCANE_UNUSED(second_node);
329 const Int64 edge_unique_id = cell_info.edgeUniqueId(i_edge);
330 return m_edge_family.findOrAllocOne(edge_unique_id, is_add);
337Edge OneMeshItemAdder::
340 ARCANE_UNUSED(i_edge);
343 FixedArray<Int64, 2> nodes;
344 Int64 edge_unique_id = NULL_ITEM_UNIQUE_ID;
347 nodes[0] = first_node;
348 nodes[1] = second_node;
349 edge_unique_id = MeshUtils::generateHashUniqueId(nodes.view());
350 edge_internal = m_edge_family.itemsMap().tryFind(edge_unique_id);
353 const ItemInternalMap& nodes_map = m_mesh->nodesMap();
354 Node nbi = nodes_map.findItem(first_node);
357 if (edge_internal.null()) {
358 if (!cell_info.allowBuildEdge() && !use_hash)
359 ARCANE_FATAL(
"On the fly edge allocation is not allowed here."
360 " You need to add edges before with IMeshModifier::addEdges()");
364 return m_edge_family.allocOne(edge_unique_id);
368 return edge_internal;
390ItemInternal* OneMeshItemAdder::
391addOneCell(ItemTypeId type_id,
Int64 cell_uid,
Int32 owner,
392 ConstArrayView<Int64> nodes_uid,
bool allow_build_face)
394 if (type_id == ITI_GenericPolyhedron)
395 return _addOnePolyhedron(cell_uid, nodes_uid, owner, allow_build_face);
396 CellInfoProxy cell_info_proxy(type_id, m_item_type_mng->typeFromId(type_id), cell_uid, owner, nodes_uid, allow_build_face);
426 ARCANE_ASSERT(m_mesh->
itemFamilyNetwork(), (
"ItemFamilyNetwork is required to call OneMeshItemAdder::addOneItem"));
427 bool is_alloc =
true;
428 Item item = family_modifier->findOrAllocOne(item_uid, type_id,
m_mesh_info, is_alloc);
432 for (
Integer family_index = 0; family_index < nb_connected_family; ++family_index) {
435 Int32 nb_connected_item = CheckedConvert::toInt32(connectivity_info[info_index++]);
438 String connectivity_name = mesh::connectivityName(family, connected_family);
439 String reverse_connectivity_name = mesh::connectivityName(connected_family, family);
440 bool is_dependency =
false;
446 _clearConnectivity(
ItemLocalId(item), family_to_connected_family);
447 if (connected_family_to_family)
448 _clearReverseConnectivity(
ItemLocalId(item), family_to_connected_family, connected_family_to_family);
453 for (
Integer connected_item_index = 0; connected_item_index < nb_connected_item; ++connected_item_index) {
454 if (family_to_connected_family) {
461 if (connected_family_to_family)
462 connected_family_to_family->
addConnectedItem(ItemLocalId(connected_item_lids[connected_item_index]), ItemLocalId(item));
464 info_index += nb_connected_item;
468 return ItemCompatibility::_itemInternal(item);
473ItemInternal* OneMeshItemAdder::
474addOneItem2(IItemFamily* family,
475 IItemFamilyModifier* family_modifier,
483 ARCANE_ASSERT(m_mesh->itemFamilyNetwork(), (
"ItemFamilyNetwork is required to call OneMeshItemAdder::addOneItem"));
484 bool is_alloc =
true;
485 Item item = family_modifier->findOrAllocOne(item_uid, type_id,
m_mesh_info, is_alloc);
489 for (
Integer family_index = 0; family_index < nb_connected_family; ++family_index) {
493 Int32 nb_connected_item = CheckedConvert::toInt32(connectivity_info[info_index++]);
494 if (nb_connected_item == 0)
496 IItemFamily* connected_family =
nullptr;
497 switch (family_kind) {
499 connected_family = m_mesh->findItemFamily(family_kind, ParticleFamily::defaultFamilyName(),
false,
false);
502 if (family->name() == GraphDoFs::dualNodeFamilyName())
503 connected_family = m_mesh->findItemFamily(family_kind, GraphDoFs::linkFamilyName(),
false,
false);
505 connected_family = m_mesh->findItemFamily(family_kind, GraphDoFs::dualNodeFamilyName(),
false,
false);
508 connected_family = m_mesh->itemFamily(family_kind);
512 String connectivity_name = mesh::connectivityName(family, connected_family);
513 bool is_dependency =
false;
514 IIncrementalItemConnectivity* family_to_connected_family = m_mesh->itemFamilyNetwork()->getConnectivity(family, connected_family, connectivity_name, is_dependency);
515 if (!family_to_connected_family)
516 ARCANE_FATAL(
"Cannot find connectivity name={0}", connectivity_name);
517 bool is_deep_connectivity = m_mesh->itemFamilyNetwork()->isDeep(family_to_connected_family);
518 bool is_relation = !(is_dependency && is_deep_connectivity);
522 bool do_fatal = is_relation ? false :
true;
523 connected_family->itemsUniqueIdToLocalId(connected_item_lids, connectivity_info.subView(info_index, nb_connected_item), do_fatal);
525 Integer nb_connected_item_found = nb_connected_item;
527 for (
Integer index = 0; index < connected_item_lids.size();) {
528 if (connected_item_lids[index] == NULL_ITEM_LOCAL_ID) {
529 connected_item_lids.remove(index);
530 --nb_connected_item_found;
536 for (
Integer connected_item_index = 0; connected_item_index < nb_connected_item_found; ++connected_item_index) {
537 if (family_to_connected_family) {
539 auto connected_item_lid = ItemLocalId{ connected_item_lids[connected_item_index] };
541 if (!family_to_connected_family->hasConnectedItem(ItemLocalId(item), connected_item_lid)) {
542 family_to_connected_family->addConnectedItem(ItemLocalId(item), connected_item_lid);
546 family_to_connected_family->replaceConnectedItem(ItemLocalId(item), connected_item_index, connected_item_lid);
550 info_index += nb_connected_item;
553 debug(
Trace::Highest) <<
"[addItems] ADD_ITEM " << ItemPrinter(item) <<
" in " << family->name();
556 return ItemCompatibility::_itemInternal(item);
561void OneMeshItemAdder::
562_printRelations(ItemInternal* item)
564 debug(
Trace::Highest) <<
"[addItems] RELATIONS for " << ItemPrinter(item) <<
" in " << item->family()->name();
565 for (
const auto& relation : m_mesh->itemFamilyNetwork()->getChildRelations(item->family())) {
568 ConnectivityItemVector connected_items(relation);
569 for (
const auto& connected_item : connected_items.connectedItems(ItemLocalId(item))) {
578void OneMeshItemAdder::
579_clearConnectivity(ItemLocalId item, IIncrementalItemConnectivity* connectivity)
582 ConnectivityItemVector accessor(connectivity);
584 connectivity->removeConnectedItem(item, connected_item);
591void OneMeshItemAdder::
592_clearReverseConnectivity(ItemLocalId item, IIncrementalItemConnectivity* connectivity, IIncrementalItemConnectivity* reverse_connectivity)
594 ConnectivityItemVector accessor(connectivity);
596 reverse_connectivity->removeConnectedItem(connected_item, item);
603template <>
void OneMeshItemAdder::
607 if (m_mesh->isAmrActivated()) {
610 if (cell_info.
level() != 0) {
611 Integer child_rank = cell_info.whichChildAmI();
612 Int64 hParent_uid = cell_info.hParentCellUniqueId();
615 Cell hParent_cell = m_cell_family.findOrAllocOne(hParent_uid, cell_type, is_add);
616 m_cell_family._addParentCellToCell(new_cell, hParent_cell);
617 m_cell_family._addChildCellToCell(hParent_cell, child_rank, new_cell);
622template <>
void OneMeshItemAdder::
623_AMR_Patch(
Cell cell,
const CellInfoProxy& cell_info)
626 ARCANE_UNUSED(cell_info);
636template <
typename CellInfo>
644 const bool is_verbose =
false;
646 info() <<
"AddNewCell type_id=" << cell_type_id <<
" nb_node=" << cell_info.nbNode()
647 <<
" type=" << cell_type_info->
typeName();
652 inew_cell = m_cell_family.findOrAllocOne(cell_info.uniqueId(), cell_type_info, is_add);
655 Cell cell2(inew_cell);
657 for (
Integer i = 0, is = cell_info.nbNode(); i < is; ++i)
658 if (cell_info.nodeUniqueId(i) != cell2.
node(i).
uniqueId())
659 ARCANE_FATAL(
"trying to add existing cell (uid={0}) with different nodes",
660 cell_info.uniqueId());
662 return ItemCompatibility::_itemInternal(inew_cell);
666 Cell new_cell(inew_cell);
670 const MeshKind& mesh_kind = m_mesh->meshKind();
672 const Int32 cell_nb_face = cell_info.nbFace();
675 mut_cell.
addFlags(ItemFlags::II_HasEdgeFor1DItems);
679 if (cell_info.nbNode() != inew_cell.
nbNode())
680 ARCANE_FATAL(
"Incoherent number of nodes v={0} expected={1}", inew_cell.
nbNode(), cell_info.nbNode());
681 if (cell_nb_face != inew_cell.
nbFace())
682 ARCANE_FATAL(
"Incoherent number of faces v={0} expected={1}", inew_cell.
nbFace(), cell_nb_face);
684 ARCANE_FATAL(
"Type '{0}' is not allowed for 'Cell' (cell_uid={1})",
685 cell_type_info->
typeName(), cell_info.uniqueId());
686 if (!allow_multi_dim_cell) {
688 Int32 mesh_dimension = m_mesh->dimension();
689 if (cell_dimension >= 0 && cell_dimension != mesh_dimension)
690 ARCANE_FATAL(
"Incoherent dimension for cell uid={0} cell_dim={1} mesh_dim={2} type={3}",
691 cell_info.uniqueId(), cell_dimension, mesh_dimension, cell_type_info->
typeName());
700 if (m_mesh_builder->hasEdge()) {
701 const Int32 cell_nb_edge = cell_info.nbEdge();
703 for (
Integer i_edge = 0; i_edge < cell_nb_edge; ++i_edge) {
706 Int64 second_node = cell_info.nodeUniqueId(le.
endNode());
707 if (first_node > second_node)
708 std::swap(first_node, second_node);
711 Edge edge_internal = _findInternalEdge(i_edge, cell_info, first_node, second_node, is_add);
719 m_edge_family.replaceNode(
ItemLocalId(edge_internal), 0, current_node);
720 m_node_family.addEdgeToNode(current_node, edge_internal);
724 m_edge_family.replaceNode(
ItemLocalId(edge_internal), 1, current_node);
725 m_node_family.addEdgeToNode(current_node, edge_internal);
731 m_edge_family.addCellToEdge(edge_internal, inew_cell);
736 for (
Integer i_face = 0; i_face < cell_nb_face; ++i_face) {
740 const bool is_reorder = _isReorder(i_face, lf, cell_info);
743 Face face = _findInternalFace(i_face, cell_info, is_add);
750 info() <<
"AddFaceToCell (cell_uid=" << new_cell.
uniqueId() <<
": Create face (index=" << i_face
753 <<
" type=" << face_type_info->
typeName()
754 <<
" face_nb_linear_node=" << face_nb_linear_node
755 <<
" sorted_nodes=" << face_sorted_nodes;
759 for (
Integer i_node = 0; i_node < face_nb_node; ++i_node) {
761 info() <<
"AddNodeToFace i_node=" << i_node <<
" uid=" << face_sorted_nodes[i_node];
762 Node current_node = nodes_map.
findItem(face_sorted_nodes[i_node]);
763 m_face_family.replaceNode(face, i_node, current_node);
764 if (i_node < face_nb_linear_node) {
765 m_node_family.addFaceToNode(current_node, face);
769 if (m_mesh_builder->hasEdge()) {
771 for (
Integer i_edge = 0; i_edge < face_nb_edge; ++i_edge) {
773 m_face_family.addEdgeToFace(face, current_edge);
774 m_edge_family.addFaceToEdge(current_edge, face);
779 m_cell_family.replaceFace(new_cell, i_face, face);
782 if (m_mesh->isAmrActivated()) {
785 m_face_family.replaceFrontCellToFace(face, new_cell);
787 m_face_family.addFrontCellToFace(face, inew_cell);
791 m_face_family.replaceBackCellToFace(face, new_cell);
793 m_face_family.addBackCellToFace(face, inew_cell);
798 m_face_family.addFrontCellToFace(face, inew_cell);
801 m_face_family.addBackCellToFace(face, inew_cell);
806 _AMR_Patch(inew_cell, cell_info);
807 return ItemCompatibility::_itemInternal(inew_cell);
816 const bool is_verbose =
false;
818 info() <<
"AddNewPolyhedronCell nb_connectivity=" << connectivity_infos.
size()
819 <<
" c=" << connectivity_infos;
834 Int16 nb_local_node = 0;
835 nodes_of_cell.
clear();
836 connectivity_to_local_index.clear();
837 local_nodes_of_cell.
clear();
838 arcane_faces_nb_node.
clear();
839 arcane_faces_nodes.
clear();
847 Int32 array_size = connectivity_infos[0];
848 if (array_size != connectivity_infos.
size())
849 ARCANE_FATAL(
"Incoherent size array_size={0} connectivity_info={1}", array_size, connectivity_infos.
size());
850 Int32 scheme_version = connectivity_infos[1];
851 if (scheme_version != 1)
852 ARCANE_FATAL(
"Insupported scheme version '{0}'. Only supported value is 1", scheme_version);
853 const Int32 cell_nb_face =
static_cast<Int32>(connectivity_infos[2]);
855 info() <<
"NB_FACE=" << cell_nb_face;
856 Int32 index_in_connectivity = 3;
857 for (
Int32 z = 0; z < cell_nb_face; ++z) {
858 const Int16 face_nb_node =
static_cast<Int16>(connectivity_infos[index_in_connectivity]);
859 ++index_in_connectivity;
861 info() <<
"NB_FACE_NODE=" << face_nb_node;
862 nodes_of_face.
resize(face_nb_node);
863 arcane_faces_nb_node.
add(face_nb_node);
864 for (
Int16 k = 0; k < face_nb_node; ++k) {
865 Int64 node_id = connectivity_infos[index_in_connectivity];
866 ++index_in_connectivity;
867 auto x = connectivity_to_local_index.find(node_id);
868 Int16 local_node_index = -1;
870 if (x == connectivity_to_local_index.end()) {
871 local_node_index = nb_local_node;
872 connectivity_to_local_index[node_id] = nb_local_node;
874 local_nodes_of_cell.
add(local_node_index);
875 nodes_of_cell.
add(node_id);
876 cell_nodes_uid.
add(node_id);
879 local_node_index = x->second;
880 nodes_of_face[k] = local_node_index;
881 arcane_faces_nodes.
add(local_node_index);
885 info() <<
" Polyhedral face=" << z <<
" nb_node=" << face_nb_node
886 <<
" nodes=" << nodes_of_face.
view() <<
" index=" << index_in_connectivity;
890 info() <<
"EndCreateTypeForPolyhedron nb_node=" << nodes_of_cell.
size();
891 ItemTypeMngInternal* api = m_item_type_mng->_internalApi();
892 ItemTypeInfo* cell_type_info = api->findOrAddPolyhedron(nodes_of_cell.
size(),
893 arcane_faces_nb_node, arcane_faces_nodes);
894 CellInfoProxy cell_info_proxy(ITI_GenericPolyhedron, cell_type_info, cell_uid, owner, nodes_of_cell, allow_build_face);
923 if (item.
type() == IT_Line2 && submesh_kind ==
IK_Cell)
925 if (item.
type() == IT_Vertex && submesh_kind ==
IK_Face)
936 switch (submesh_kind) {
938 new_item = m_node_family.findOrAllocOne(item.
uniqueId(), is_add);
942 new_item = m_edge_family.findOrAllocOne(item.
uniqueId(), is_add);
946 new_item = m_face_family.findOrAllocOne(item.
uniqueId(),
type, is_add);
952 new_item = m_cell_family.findOrAllocOne(item.
uniqueId(), type_id, is_add);
960 if (fatal_on_existing_item)
961 ARCANE_FATAL(
"Cannot add already existing parent item in submesh");
963 return ItemCompatibility::_itemInternal(new_item);
975 switch (submesh_kind) {
977 item_nb_face =
type->nbLocalFace();
978 item_nb_edge =
type->nbLocalEdge();
979 item_nb_node =
type->nbLocalNode();
982 item_nb_edge =
type->nbLocalEdge();
983 item_nb_node =
type->nbLocalNode();
986 item_nb_node =
type->nbLocalNode();
992 if (!m_mesh_builder->hasEdge())
998 for (
Integer z = 0; z < item_nb_face; ++z)
999 new_item->_setFace(z, NULL_ITEM_ID);
1000 for (
Integer z = 0; z < item_nb_edge; ++z)
1001 new_item->_setEdge(z, NULL_ITEM_ID);
1002 for (
Integer z = 0; z < item_nb_node; ++z)
1003 new_item->_setNode(z, NULL_ITEM_ID);
1008 DynamicMeshKindInfos::ItemInternalMap& nodes_map = m_mesh->nodesMap();
1010 DynamicMeshKindInfos::ItemInternalMap& parent_nodes_map = parent_mesh->nodesMap();
1015 const bool direct_node_order =
1016 !(submesh_kind ==
IK_Cell && kind ==
IK_Face && !(item.
toFace().isSubDomainBoundaryOutside()));
1019 for (
Integer i_node = 0; i_node < item_nb_node; ++i_node) {
1021 if (
type->typeId() == IT_FaceVertex)
1024 Int32 idx = ((direct_node_order) ? i_node : (item_nb_node - 1 - i_node));
1027 Int64 new_node_uid = nodes_uid[i_node] = parent_item.
uniqueId();
1028 ItemInternal* node_internal = m_node_family.findOrAllocOne(new_node_uid, is_add);
1030#ifdef ARCANE_DEBUG_DYNAMIC_MESH
1031 info() <<
"Création node " << new_node_uid <<
' '
1042 switch (submesh_kind) {
1044 m_cell_family.replaceNode(new_item_lid, i_node, node_lid);
1045 m_node_family.addCellToNode(node_internal, new_item.
toCell());
1048 m_face_family.replaceNode(new_item_lid, i_node, node_lid);
1049 m_node_family.addFaceToNode(node_internal, new_item.
toFace());
1052 m_edge_family.replaceNode(new_item_lid, i_node, node_lid);
1053 m_node_family.addEdgeToNode(node_internal, new_item.
toEdge());
1061 for (
Integer i_edge = 0; i_edge < item_nb_edge; ++i_edge) {
1066 if (first_node > second_node)
1067 std::swap(first_node, second_node);
1070 if (parent_item.
null())
1075 ItemInternal* edge_internal = m_edge_family.findOrAllocOne(new_edge_uid, is_add);
1077#ifdef ARCANE_DEBUG_DYNAMIC_MESH
1078 info() <<
"Création edge " << new_edge_uid <<
' '
1086 m_edge_family.replaceNode(
ItemLocalId(edge_internal), 0, current_node);
1087 m_node_family.addEdgeToNode(current_node, edge_internal);
1091 m_edge_family.replaceNode(
ItemLocalId(edge_internal), 1, current_node);
1092 m_node_family.addEdgeToNode(current_node, edge_internal);
1098 switch (submesh_kind) {
1101 m_edge_family.addCellToEdge(edge_internal, new_item.
toCell());
1105 m_edge_family.addFaceToEdge(edge_internal, new_item.
toFace());
1114 for (
Integer i_face = 0; i_face < item_nb_face; ++i_face) {
1118 m_work_face_orig_nodes_uid.resize(face_nb_node);
1119 for (
Integer z = 0; z < face_nb_node; ++z)
1120 m_work_face_orig_nodes_uid[z] = nodes_uid[lf.
node(z)];
1121 bool is_reorder =
false;
1122 if (m_mesh->dimension() == 1) {
1123 is_reorder =
m_face_reorderer.reorder1D(i_face, m_work_face_orig_nodes_uid[0]);
1135 if (m_mesh->dimension() == 1) {
1136 parent_item = parent_nodes_map.
findItem(face_sorted_nodes[0]);
1140 Int64 first_node = face_sorted_nodes[0];
1141 Int64 second_node = face_sorted_nodes[1];
1142 if (first_node > second_node)
1143 std::swap(first_node, second_node);
1149 if (parent_item.
null())
1154 ItemInternal* face_internal = m_face_family.findOrAllocOne(new_face_uid, face_type, is_add);
1156#ifdef ARCANE_DEBUG_DYNAMIC_MESH
1157 info() <<
"Création face " << new_face_uid <<
' '
1163 for (
Integer i_node = 0; i_node < face_nb_node; ++i_node) {
1164 Node current_node = nodes_map.
findItem(face_sorted_nodes[i_node]);
1165 m_face_family.replaceNode(
ItemLocalId(face_internal), i_node, current_node);
1166 m_node_family.addFaceToNode(current_node, face_internal);
1169 if (m_mesh_builder->hasEdge()) {
1171 for (
Integer i_edge = 0; i_edge < face_nb_edge; ++i_edge) {
1173 Edge current_edge = new_item.
itemBase().edgeBase(edge_idx);
1174 m_face_family.addEdgeToFace(face_internal, current_edge);
1175 m_edge_family.addFaceToEdge(current_edge, face_internal);
1182 m_face_family.addFrontCellToFace(face_internal, new_item.
toCell());
1185 m_face_family.addBackCellToFace(face_internal, new_item.
toCell());
1189 return ItemCompatibility::_itemInternal(new_item);
1198template <
typename CellInfo>
1202 Integer cell_nb_node = cell_info.nbNode();
1205 for (
Integer i_node = 0; i_node < cell_nb_node; ++i_node) {
1206 Int64 node_unique_id = cell_info.nodeUniqueId(i_node);
1207 bool is_add =
false;
1208 ItemInternal* node_internal = m_node_family.findOrAllocOne(node_unique_id, is_add);
1213 m_node_family.addCellToNode(node_internal, cell);
1214 m_cell_family.replaceNode(cell, i_node,
ItemLocalId(node_internal));
1221template <
typename CellInfo>
1222bool OneMeshItemAdder::
1226 m_work_face_orig_nodes_uid.
resize(face_nb_node);
1227 for (
Integer i_node = 0; i_node < face_nb_node; ++i_node)
1228 m_work_face_orig_nodes_uid[i_node] = cell_info.nodeUniqueId(lf.
node(i_node));
1229 bool is_reorder =
false;
1231 is_reorder =
m_face_reorderer.reorder1D(i_face, m_work_face_orig_nodes_uid[0]);
1259 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.
Construction of a mesh incrementally.
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.
void replaceNode(ItemLocalId edge, Integer index, ItemLocalId node)
Replaces the node at index index of the edge edge with * that of localId() node_lid.
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.