16#include "arcane/mesh/PolyhedralMesh.h"
18#include "ItemFamilyNetwork.h"
19#include "ItemFamilyPolicyMng.h"
20#include "arcane/mesh/MeshExchangeMng.h"
21#include "arcane/core/ISubDomain.h"
22#include "arcane/core/ItemSharedInfo.h"
23#include "arcane/core/ItemTypeInfo.h"
24#include "arcane/core/ItemTypeMng.h"
25#include "arcane/core/VariableBuildInfo.h"
26#include "arcane/core/MeshBuildInfo.h"
28#include "arcane/core/AbstractService.h"
29#include "arcane/core/CommonVariables.h"
30#include "arcane/core/IMeshFactory.h"
31#include "arcane/core/ItemInternal.h"
32#include "arcane/core/IDoFFamily.h"
33#include "arcane/core/IMeshCompactMng.h"
34#include "arcane/core/IMeshCompacter.h"
35#include "arcane/core/IMeshExchanger.h"
36#include "arcane/core/IGhostLayerMng.h"
37#include "arcane/core/MeshVisitor.h"
38#include "arcane/core/internal/IItemFamilyInternal.h"
39#include "arcane/core/internal/IItemFamilySerializerMngInternal.h"
40#include "arcane/core/internal/IVariableMngInternal.h"
41#include "arcane/core/internal/IPolyhedralMeshModifier.h"
42#include "arcane/core/internal/IMeshModifierInternal.h"
43#include "arcane/core/Connectivity.h"
45#include "arcane/mesh/ItemFamily.h"
46#include "arcane/mesh/DynamicMeshKindInfos.h"
47#include "arcane/mesh/UnstructuredMeshUtilities.h"
48#include "arcane/mesh/GhostLayerMng.h"
49#include "arcane/utils/ITraceMng.h"
50#include "arcane/utils/FatalErrorException.h"
52#ifdef ARCANE_HAS_POLYHEDRAL_MESH_TOOLS
54#include "arcane/core/IMeshMng.h"
55#include "arcane/core/MeshHandle.h"
56#include "arcane/core/IItemFamily.h"
57#include "arcane/core/internal/IMeshInternal.h"
58#include "arcane/core/IVariableSynchronizer.h"
59#include "arcane/mesh/ItemFamilyPolicyMng.h"
60#include "arcane/mesh/ItemFamilySerializer.h"
61#include "arcane/utils/Collection.h"
62#include "arcane/utils/List.h"
63#include "arcane/utils/PlatformUtils.h"
67#include "ItemConnectivityMng.h"
69#include "arcane/core/ItemPrinter.h"
74#define ARCANE_DEBUG_LOAD_BALANCING
76#ifdef ARCANE_DEBUG_LOAD_BALANCING
77static bool arcane_debug_load_balancing =
true;
79static bool arcane_debug_load_balancing =
false;
85void Arcane::mesh::PolyhedralMesh::
86_errorEmptyMesh()
const
88 ARCANE_FATAL(
"Cannot use PolyhedralMesh if Arcane is not linked with lib Neo");
94#ifdef ARCANE_HAS_POLYHEDRAL_MESH_TOOLS
101namespace PolyhedralTools
105 Neo::FutureItemRange m_future_items;
106 std::shared_ptr<Neo::EndOfMeshUpdate> m_mesh_state =
nullptr;
110 void fillArrayView(Int32ArrayView local_ids, Neo::EndOfMeshUpdate mesh_state)
112 auto lids = m_future_items.get(mesh_state);
113 if (local_ids.size() != lids.size())
114 ARCANE_FATAL(
"Cannot fill local_ids view, its size {0} != {1} (added item size)", local_ids.size(), m_future_items.size());
115 std::copy(lids.begin(), lids.end(), local_ids.begin());
118 void fillArrayView(Int32ArrayView local_ids)
120 ARCANE_CHECK_POINTER2(m_mesh_state.get(),
"PolyhedralTools::ItemLocalIds must have a valid end of mesh state");
121 fillArrayView(local_ids, *m_mesh_state);
124 Integer size() const noexcept {
return m_future_items.size(); }
125 bool isFilled() const noexcept {
return m_mesh_state.get() !=
nullptr; };
126 void checkIsFilled(String error_message)
const noexcept
129 ARCANE_FATAL(
"Item local ids are not filled." + error_message);
131 friend class mesh::PolyhedralMeshImpl;
132 friend class mesh::PolyhedralMesh;
139class PolyhedralFamilySerializer;
140class PolyhedralFamilySerializerMng :
public IItemFamilySerializerMngInternal
142 PolyhedralMesh* m_mesh =
nullptr;
144 UniqueArray<PolyhedralFamilySerializer*> m_serializers;
148 explicit PolyhedralFamilySerializerMng(PolyhedralMesh* mesh)
154 void addSerializer(PolyhedralFamilySerializer* serializer)
156 m_serializers.push_back(serializer);
160 void finalizeItemAllocation()
override;
166class PolyhedralFamilySerializer :
public IItemFamilySerializer
170 PolyhedralMesh* m_mesh =
nullptr;
171 IItemFamily* m_family =
nullptr;
172 PolyhedralFamilySerializerMng* m_mng =
nullptr;
173 ItemData m_item_data;
174 UniqueArray<Int32Array*> m_deserialized_lids_array;
175 UniqueArray<std::shared_ptr<PolyhedralTools::ItemLocalIds>> m_future_item_lids_array;
176 ItemAllocationInfo::FamilyInfo m_family_info;
180 explicit PolyhedralFamilySerializer(PolyhedralMesh* mesh, IItemFamily* family, PolyhedralFamilySerializerMng* mng)
186 PolyhedralFamilySerializer(
const PolyhedralFamilySerializer&) =
delete;
187 PolyhedralFamilySerializer& operator=(
const PolyhedralFamilySerializer&) =
delete;
189 ArrayView<std::shared_ptr<PolyhedralTools::ItemLocalIds>> itemLidsArray() {
return m_future_item_lids_array.view(); }
193 void serializeItems(ISerializer* buf, Int32ConstArrayView items_local_ids)
override;
194 void deserializeItems(ISerializer* buf, Int32Array* items_local_ids)
override;
199 m_deserialized_lids_array.clear();
200 m_future_item_lids_array.clear();
201 m_family_info.clear();
204 void fillDeserializedLocalIds()
207 for (
auto item_lids_array : m_deserialized_lids_array) {
208 auto& future_item_lids = m_future_item_lids_array[index];
209 future_item_lids->checkIsFilled(
"Cannot fill deserialized local ids, future item local ids are not filled.");
210 item_lids_array->resize(future_item_lids->size());
211 future_item_lids->fillArrayView(item_lids_array->view());
217 IItemFamilySerializerMngInternal* mng()
223 void serializeItemRelations(ISerializer*, Int32ConstArrayView)
override {}
224 void deserializeItemRelations(ISerializer*, Int32Array*)
override {}
228 void _fillItemData(Int32ConstArrayView items_local_ids);
229 void _fillItemFamilyInfo(
const ItemData& item_data,
230 StringConstArrayView connected_family_names,
231 StringConstArrayView connectivity_names)
234 m_family_info.clear();
236 if (m_family != item_data.itemFamily())
237 ARCANE_FATAL(
"PolyhedralFamilySerializer: Family mismatch. Synchronized family is {0} and serialized family is {1}",
238 m_family->name(), item_data.itemFamily()->name());
239 m_family_info.name = item_data.itemFamily()->name();
240 m_family_info.item_kind = item_data.itemFamily()->itemKind();
241 auto& connected_family_infos = m_family_info.connected_family_infos;
242 auto nb_connected_family = item_data.itemInfos()[0];
243 connected_family_infos.resize(nb_connected_family);
244 auto& item_uids = m_family_info._item_uids_data;
245 item_uids.reserve(item_data.nbItems());
246 auto item_infos = item_data.itemInfos();
247 for (
auto connected_family_info : connected_family_infos) {
248 connected_family_info._connected_items_uids_data.reserve(4 * item_uids.size());
249 connected_family_info._nb_connected_items_per_item_data.reserve(item_uids.size());
251 for (
auto index = 1; index < item_infos.size();) {
252 item_uids.push_back(item_infos[index + 1]);
254 for (
auto connected_family_index = 0; connected_family_index < nb_connected_family; ++connected_family_index) {
256 auto* connected_family = m_mesh->findItemFamily(family_kind, connected_family_names[connected_family_index],
false,
false);
258 auto& current_connected_family_infos = connected_family_infos[connected_family_index];
259 current_connected_family_infos.item_kind = family_kind;
260 current_connected_family_infos.name = connected_family->name();
261 current_connected_family_infos.connectivity_name = connectivity_names[connected_family_index];
263 auto nb_connected_items =
static_cast<Int32
>(item_infos[index]);
265 current_connected_family_infos._nb_connected_items_per_item_data.push_back(nb_connected_items);
266 auto real_nb_connected_items = nb_connected_items;
267 if (m_family->itemKind() == IK_Face && connected_family->itemKind() == IK_Cell)
268 real_nb_connected_items = 2;
269 current_connected_family_infos._connected_items_uids_data.addRange(item_infos.subView(index, real_nb_connected_items));
270 index += real_nb_connected_items;
274 m_family_info.updateViewsFromInternalData();
276 m_family_info.item_owners = item_data.itemOwners();
279 IItemFamily* family()
const override
288void PolyhedralFamilySerializerMng::
289finalizeItemAllocation()
291 UniqueArray<std::shared_ptr<PolyhedralTools::ItemLocalIds>> future_item_lids;
292 for (
auto family_serializer : m_serializers) {
293 for (
auto& item_lids : family_serializer->itemLidsArray()) {
294 future_item_lids.push_back(item_lids);
297 m_mesh->applyScheduledAllocateItems(future_item_lids);
298 for (
auto family_serializer : m_serializers) {
299 family_serializer->fillDeserializedLocalIds();
301 m_serializers.clear();
307class PolyhedralFamilyPolicyMng
312 PolyhedralFamilyPolicyMng(PolyhedralMesh* mesh, ItemFamily* family)
313 : ItemFamilyPolicyMng(family)
322 return new PolyhedralFamilySerializer(m_mesh, m_family, m_mesh->polyhedralFamilySerializerMng());
327 PolyhedralMesh* m_mesh =
nullptr;
328 ItemFamily* m_family =
nullptr;
334class PolyhedralFamily
338 ItemSharedInfoWithType* m_shared_info =
nullptr;
342 PolyhedralMesh* m_mesh =
nullptr;
346 inline static const String m_arcane_item_lids_property_name{
"Arcane_Item_Lids" };
347 inline static const String m_arcane_remove_item_property_name{
"Arcane_Remove_Items" };
351 PolyhedralFamily(PolyhedralMesh* mesh, eItemKind ik, String name)
352 : ItemFamily(mesh, ik, name)
358 void preAllocate(Integer nb_item)
360 Integer nb_hash = itemsMap().nbBucket();
361 Integer wanted_size = 2 * (nb_item + nbItem());
362 if (nb_hash < wanted_size)
363 itemsMap().resize(wanted_size,
true);
364 m_empty_connectivity_indexes.resize(nb_item + nbItem(), 0);
365 m_empty_connectivity_nb_item.resize(nb_item + nbItem(), 0);
366 _updateEmptyConnectivity();
369 ItemInternal* _allocItem(
const Int64 uid,
const Int32 owner)
372 ItemInternal* item_internal = ItemFamily::_findOrAllocOne(uid, need_alloc);
374 item_internal->setUniqueId(uid);
376 _allocateInfos(item_internal, uid, m_shared_info);
378 item_internal->setOwner(owner, m_sub_domain_id);
379 return item_internal;
382 void addItems(Int64ConstSmallSpan uids, Int32ArrayView items)
385 addItems(uids, items, owners);
388 void addItems(Int64ConstSmallSpan uids, Int32ArrayView items, Int32ConstArrayView owners)
392 ARCANE_ASSERT((uids.size() == items.size()), (
"one must have items.size==uids.size()"));
393 preAllocate(uids.size());
395 for (
auto uid : uids) {
396 ItemInternal* ii = _allocItem(uid, owners[index]);
397 items[index] = ii->localId();
400 m_need_prepare_dump =
true;
401 _updateItemInternalList();
404 void removeItems(Int32ConstArrayView local_ids)
406 _removeMany(local_ids);
409 void _updateItemInternalList()
411 switch (itemKind()) {
413 m_item_internal_list->cells = _itemsInternal();
416 m_item_internal_list->faces = _itemsInternal();
419 m_item_internal_list->edges = _itemsInternal();
422 m_item_internal_list->nodes = _itemsInternal();
431 void _updateEmptyConnectivity()
433 auto item_internal_connectivity_list = itemInternalConnectivityList();
434 for (
auto item_kind = 0; item_kind < ItemInternalConnectivityList::MAX_ITEM_KIND; ++item_kind) {
435 item_internal_connectivity_list->_setConnectivityList(item_kind, m_empty_connectivity);
436 item_internal_connectivity_list->_setConnectivityIndex(item_kind, m_empty_connectivity_indexes);
437 item_internal_connectivity_list->_setConnectivityNbItem(item_kind, m_empty_connectivity_nb_item);
442 IDoFFamily* toDoFFamily()
override
448 void build()
override
451 m_sub_domain_id = subDomain()->subDomainId();
452 ItemTypeMng* itm = m_mesh->itemTypeMng();
453 ItemTypeInfo* dof_type_info = itm->typeFromId(IT_NullType);
454 m_shared_info = _findSharedInfo(dof_type_info);
455 _updateEmptyConnectivity();
456 ItemFamily::setPolicyMng(
new PolyhedralFamilyPolicyMng{ m_mesh,
this });
459 void addGhostItems(Int64ConstArrayView unique_ids, Int32ArrayView items, Int32ConstArrayView owners)
override
461 auto* polyhedral_mesh_modifier = m_mesh->_internalApi()->polyhedralMeshModifier();
463 polyhedral_mesh_modifier->addItems(unique_ids, items, owners, ItemFamily::itemKind(), name());
467 String name()
const override {
return ItemFamily::name(); }
468 String fullName()
const override {
return ItemFamily::fullName(); }
469 Integer nbItem()
const override {
return ItemFamily::nbItem(); }
470 ItemGroup allItems()
const override {
return ItemFamily::allItems(); }
471 void endUpdate()
override
473 return ItemFamily::endUpdate();
475 IItemFamily* itemFamily()
override {
return this; }
477 DoFVectorView addDoFs(Int64ConstArrayView dof_uids, Int32ArrayView dof_lids)
override
479 auto* polyhedral_mesh_modifier = m_mesh->_internalApi()->polyhedralMeshModifier();
481 polyhedral_mesh_modifier->addItems(dof_uids, dof_lids, ItemFamily::itemKind(), name());
482 return ItemFamily::view(dof_lids);
485 DoFVectorView addGhostDoFs(Int64ConstArrayView dof_uids, Int32ArrayView dof_lids,
486 Int32ConstArrayView owners)
override
488 addGhostItems(dof_uids, dof_lids, owners);
489 return ItemFamily::view(dof_lids);
492 void removeDoFs(Int32ConstArrayView items_local_id)
override
494 auto* mesh_modifier = m_mesh->_internalApi()->polyhedralMeshModifier();
495 mesh_modifier->removeItems(items_local_id, ItemFamily::itemKind(), m_name);
520 ISubDomain* m_subdomain;
521 Neo::Mesh m_mesh{
"Test" };
523 template <eItemKind IK>
526 static const Neo::ItemKind item_kind = Neo::ItemKind::IK_None;
531 static Neo::ItemKind itemKindArcaneToNeo(
eItemKind ik)
535 return Neo::ItemKind::IK_Cell;
537 return Neo::ItemKind::IK_Face;
539 return Neo::ItemKind::IK_Edge;
541 return Neo::ItemKind::IK_Node;
543 return Neo::ItemKind::IK_Dof;
546 return Neo::ItemKind::IK_None;
548 return Neo::ItemKind::IK_Node;
551 static eItemKind itemKindNeoToArcane(Neo::ItemKind ik)
554 case Neo::ItemKind::IK_Cell:
556 case Neo::ItemKind::IK_Face:
558 case Neo::ItemKind::IK_Edge:
560 case Neo::ItemKind::IK_Node:
562 case Neo::ItemKind::IK_Dof:
564 case Neo::ItemKind::IK_None:
572 explicit PolyhedralMeshImpl(ISubDomain* subDomain)
573 : m_subdomain(subDomain)
574 , m_mesh(String::format(subDomain->defaultMeshHandle().meshName(),
"Polyhedral").localstr(), subDomain->parallelMng()->commRank())
579 String name()
const {
return m_mesh.name(); }
581 Integer dimension()
const {
return m_mesh.dimension(); }
583 Integer nbNode()
const {
return m_mesh.nbNodes(); }
584 Integer nbEdge()
const {
return m_mesh.nbEdges(); }
585 Integer nbFace()
const {
return m_mesh.nbFaces(); }
586 Integer nbCell()
const {
return m_mesh.nbCells(); }
587 Integer nbItem(
eItemKind ik)
const {
return m_mesh.nbItems(itemKindArcaneToNeo(ik)); }
589 SmallSpan<const Neo::Mesh::Connectivity> connectivities(IItemFamily* source_family)
591 auto& neo_source_family = m_mesh.findFamily(itemKindArcaneToNeo(source_family->itemKind()), source_family->name().localstr());
592 auto connectivities = m_mesh.getConnectivities(neo_source_family);
593 return { connectivities.begin(), connectivities.size() };
596 static void _setFaceInfos(
Int32 mod_flags, Face& face)
598 Int32 face_flags = face.itemBase().flags();
599 face_flags &= ~ItemFlags::II_InterfaceFlags;
600 face_flags |= mod_flags;
601 face.mutableItemBase().setFlags(face_flags);
606 void addFamily(
eItemKind ik,
const String& name)
608 m_mesh.addFamily(itemKindArcaneToNeo(ik), name.localstr());
613 void scheduleAddItems(PolyhedralFamily* arcane_item_family,
615 PolyhedralTools::ItemLocalIds& item_local_ids)
622 void scheduleAddItems(PolyhedralFamily* arcane_item_family,
625 PolyhedralTools::ItemLocalIds& item_local_ids)
627 auto& added_items = item_local_ids.m_future_items;
628 auto& item_family = m_mesh.findFamily(itemKindArcaneToNeo(arcane_item_family->itemKind()),
629 arcane_item_family->name().localstr());
630 m_mesh.scheduleAddItems(item_family, std::vector<Int64>{ uids.begin(), uids.end() }, added_items);
632 auto& mesh_graph = m_mesh.internalMeshGraph();
633 item_family.addMeshScalarProperty<Neo::utils::Int32>(PolyhedralFamily::m_arcane_item_lids_property_name.localstr());
635 UniqueArray<Int64> uids_copy(uids);
636 UniqueArray<Int32> owners_copy(owners);
637 mesh_graph.addAlgorithm(Neo::MeshKernel::InProperty{ item_family, item_family.lidPropName() },
638 Neo::MeshKernel::OutProperty{ item_family, PolyhedralFamily::m_arcane_item_lids_property_name.localstr() },
639 [arcane_item_family, uids_local = std::move(uids_copy), &added_items, owners_local = std::move(owners_copy)]([[maybe_unused]] Neo::ItemLidsProperty
const& lids_property,
640 Neo::MeshScalarPropertyT<Neo::utils::Int32>&) {
641 auto new_items_lids{ added_items.new_items.localIds() };
642 Int32ConstSpan neo_items{ new_items_lids.data(),
static_cast<Int32>(new_items_lids.size()) };
643 UniqueArray<Int32> arcane_items(added_items.new_items.size());
644 if (owners_local.empty())
645 arcane_item_family->addItems(uids_local, arcane_items);
647 arcane_item_family->addItems(uids_local, arcane_items,
Int32ConstArrayView{ owners_local.size(), owners_local.data() });
649 if (!arcane_items.size() == added_items.new_items.size())
650 arcane_item_family->traceMng()->fatal() <<
"Inconsistent item lids generation between Arcane and Neo, nb items Neo "
651 << added_items.new_items.size() <<
" nb items Arcane " << arcane_items.size();
652 if (!std::equal(added_items.new_items.begin(), added_items.new_items.end(), arcane_items.begin()))
653 arcane_item_family->traceMng()->fatal() <<
"Inconsistent item lids generation between Arcane and Neo.";
659 void scheduleRemoveItems(PolyhedralFamily* arcane_item_family,
662 auto& item_family = m_mesh.findFamily(itemKindArcaneToNeo(arcane_item_family->itemKind()),
663 arcane_item_family->name().localstr());
664 Neo::ItemRange removed_items{ Neo::ItemLocalIds{ { local_ids.begin(), local_ids.end() }, 0, 0 } };
665 m_mesh.scheduleRemoveItems(item_family, removed_items);
667 auto& mesh_graph = m_mesh.internalMeshGraph();
668 item_family.addMeshScalarProperty<Neo::utils::Int32>(PolyhedralFamily::m_arcane_remove_item_property_name.localstr());
669 mesh_graph.addAlgorithm(Neo::MeshKernel::InProperty{ item_family, m_mesh._removeItemPropertyName(item_family) },
670 Neo::MeshKernel::OutProperty{ item_family, PolyhedralFamily::m_arcane_remove_item_property_name.localstr() },
671 [arcane_item_family, local_ids](Neo::MeshScalarPropertyT<Neo::utils::Int32>
const&,
672 Neo::MeshScalarPropertyT<Neo::utils::Int32>&) {
673 arcane_item_family->removeItems(local_ids);
679 void scheduleAddConnectivity(PolyhedralFamily* arcane_source_item_family,
680 PolyhedralTools::ItemLocalIds& source_items,
681 Integer nb_connected_items_per_item,
682 PolyhedralFamily* arcane_target_item_family,
687 _scheduleAddConnectivity(arcane_source_item_family,
689 nb_connected_items_per_item,
690 arcane_target_item_family,
697 void scheduleAddConnectivity(PolyhedralFamily* arcane_source_item_family,
698 PolyhedralTools::ItemLocalIds& source_items,
700 PolyhedralFamily* arcane_target_item_family,
702 String
const& connectivity_name)
704 _scheduleAddConnectivity(arcane_source_item_family,
706 std::vector<Int32>{ nb_connected_items_per_item.begin(), nb_connected_items_per_item.end() },
707 arcane_target_item_family,
715 void scheduleUpdateConnectivity(PolyhedralFamily* arcane_source_item_family,
716 PolyhedralTools::ItemLocalIds& source_items,
717 Integer nb_connected_items_per_item,
718 PolyhedralFamily* arcane_target_item_family,
723 _scheduleAddConnectivity(arcane_source_item_family,
725 nb_connected_items_per_item,
726 arcane_target_item_family,
729 Neo::Mesh::ConnectivityOperation::Modify);
734 void scheduleUpdateConnectivity(PolyhedralFamily* arcane_source_item_family,
735 PolyhedralTools::ItemLocalIds& source_items,
737 PolyhedralFamily* arcane_target_item_family,
739 String
const& connectivity_name)
741 _scheduleAddConnectivity(arcane_source_item_family,
743 std::vector<Int32>{ nb_connected_items_per_item.begin(), nb_connected_items_per_item.end() },
744 arcane_target_item_family,
747 Neo::Mesh::ConnectivityOperation::Modify);
753 template <
typename ConnectivitySizeType>
754 void _scheduleAddConnectivity(PolyhedralFamily* arcane_source_item_family,
755 PolyhedralTools::ItemLocalIds& source_items,
756 ConnectivitySizeType&& nb_connected_items_per_item,
757 PolyhedralFamily* arcane_target_item_family,
759 String
const& connectivity_name,
760 Neo::Mesh::ConnectivityOperation operation = Neo::Mesh::ConnectivityOperation::Add)
763 auto& source_family = m_mesh.findFamily(itemKindArcaneToNeo(arcane_source_item_family->itemKind()),
764 arcane_source_item_family->name().localstr());
765 auto& target_family = m_mesh.findFamily(itemKindArcaneToNeo(arcane_target_item_family->itemKind()),
766 arcane_target_item_family->name().localstr());
768 UniqueArray<Int64> target_item_uids_copy(target_item_uids);
770 std::vector<Int64> target_item_uids_filtered;
771 target_item_uids_filtered.reserve(target_item_uids.size());
772 std::copy_if(target_item_uids.begin(),
773 target_item_uids.end(),
774 std::back_inserter(target_item_uids_filtered),
775 [](
auto uid) { return uid != NULL_ITEM_UNIQUE_ID; });
777 m_mesh.scheduleAddConnectivity(source_family, source_items.m_future_items, target_family,
778 std::forward<ConnectivitySizeType>(nb_connected_items_per_item),
779 std::move(target_item_uids_filtered),
780 connectivity_name.localstr(),
783 auto& mesh_graph = m_mesh.internalMeshGraph();
784 std::string connectivity_add_output_property_name = std::string{
"EndOf" } + connectivity_name.localstr() +
"Add";
785 source_family.addScalarProperty<Neo::utils::Int32>(connectivity_add_output_property_name);
787 mesh_graph.addAlgorithm(Neo::MeshKernel::InProperty{ source_family, connectivity_name.localstr() }, Neo::MeshKernel::OutProperty{ source_family, connectivity_add_output_property_name }, [arcane_source_item_family, arcane_target_item_family, &source_family, &target_family,
this](Neo::Mesh::ConnectivityPropertyType
const& neo_connectivity, Neo::ScalarPropertyT<Neo::utils::Int32>&) {
788 auto rank = arcane_source_item_family->mesh()->parallelMng()->commRank();
789 Neo::printer(rank) <<
"==Algorithm update Arcane connectivity: "<< neo_connectivity.name() << Neo::endline;
790 auto item_internal_connectivity_list = arcane_source_item_family->itemInternalConnectivityList();
792 auto connectivity = m_mesh.getConnectivity(source_family, target_family, neo_connectivity.name());
794 auto& connectivity_values = source_family.getConcreteProperty<Neo::Mesh::ConnectivityPropertyType>(neo_connectivity.name());
795 Neo::MeshArrayPropertyProxyT<Neo::Mesh::ConnectivityPropertyType::PropertyDataType> connectivity_proxy{ connectivity_values };
796 auto nb_item_data = connectivity_proxy.arrayPropertyOffsets();
797 auto nb_item_size = connectivity_proxy.arrayPropertyOffsetsSize();
798 item_internal_connectivity_list->_setConnectivityNbItem(arcane_target_item_family->itemKind(),
800 auto max_nb_connected_items = connectivity.maxNbConnectedItems();
801 item_internal_connectivity_list->_setMaxNbConnectedItem(arcane_target_item_family->itemKind(), max_nb_connected_items);
802 auto connectivity_values_data = connectivity_proxy.arrayPropertyData();
803 auto connectivity_values_size = connectivity_proxy.arrayPropertyDataSize();
804 item_internal_connectivity_list->_setConnectivityList(arcane_target_item_family->itemKind(),
805 Int32ArrayView{ Integer(connectivity_values_size), connectivity_values_data });
806 auto connectivity_index_data = connectivity_proxy.arrayPropertyIndex();
807 auto connectivity_index_size = connectivity_proxy.arrayPropertyIndexSize();
808 item_internal_connectivity_list->_setConnectivityIndex(arcane_target_item_family->itemKind(),
809 Int32ArrayView{ Integer(connectivity_index_size), connectivity_index_data }); }, Neo::MeshKernel::AlgorithmPropertyGraph::AlgorithmPersistence::KeepAfterExecution);
811 if (arcane_source_item_family->itemKind() ==
IK_Face && arcane_target_item_family->itemKind() ==
IK_Cell) {
812 std::string flag_definition_output_property_name{
"EndOfFlagDefinition" };
813 source_family.addScalarProperty<Neo::utils::Int32>(flag_definition_output_property_name);
815 mesh_graph.addAlgorithm(Neo::MeshKernel::InProperty{ source_family, connectivity_add_output_property_name }, Neo::MeshKernel::OutProperty{ source_family, flag_definition_output_property_name },
816 [arcane_source_item_family, arcane_target_item_family, target_item_uids_local = std::move(target_item_uids_copy), &source_items](Neo::ScalarPropertyT<Neo::utils::Int32>
const&, Neo::ScalarPropertyT<Neo::utils::Int32>
const&) {
817 auto current_face_index = 0;
818 auto arcane_faces = arcane_source_item_family->itemInfoListView();
820 arcane_target_item_family->itemsUniqueIdToLocalId(target_item_lids, target_item_uids_local,
false);
821 for (
auto face_lid : source_items.m_future_items.new_items) {
822 Face current_face = arcane_faces[face_lid].toFace();
823 if (target_item_lids[2 * current_face_index + 1] == NULL_ITEM_LOCAL_ID) {
826 _setFaceInfos(mod_flags, current_face);
828 else if (target_item_lids[2 * current_face_index] == NULL_ITEM_LOCAL_ID) {
836 ++current_face_index;
841 if (operation == Neo::Mesh::ConnectivityOperation::Modify)
843 auto isolated_item_property_name = m_mesh._isolatedItemLidsPropertyName(source_family, target_family);
844 auto end_of_isolated_removal_property_name = std::string{
"EndOf" } + isolated_item_property_name;
845 source_family.addScalarProperty<Neo::utils::Int32>(end_of_isolated_removal_property_name);
846 mesh_graph.addAlgorithm(Neo::MeshKernel::InProperty{ source_family, isolated_item_property_name }, Neo::MeshKernel::OutProperty{ source_family, end_of_isolated_removal_property_name }, [arcane_source_item_family](Neo::MeshScalarPropertyT<Neo::utils::Int32>
const& isolated_items_lids_property, Neo::ScalarPropertyT<Neo::utils::Int32>& end_of_isolated_removal_property) {
847 end_of_isolated_removal_property.set(1);
850 isolated_item_lids.
reserve(isolated_items_lids_property.size());
851 ENUMERATE_(Item,iitem,arcane_source_item_family->allItems()) {
852 if (isolated_items_lids_property[iitem->localId()] == 1) {
853 isolated_item_lids.push_back(iitem->localId());
856 arcane_source_item_family->removeItems(isolated_item_lids); }, Neo::MeshKernel::AlgorithmPropertyGraph::AlgorithmPersistence::KeepAfterExecution);
863 auto& _item_family = m_mesh.findFamily(itemKindArcaneToNeo(item_family->itemKind()), item_family->name().localstr());
864 std::vector<Neo::utils::Real3> _node_coords(item_coords.size());
866 for (
auto&& node_coord : item_coords) {
867 _node_coords[node_index++] = Neo::utils::Real3{ node_coord.x, node_coord.y, node_coord.z };
869 m_mesh.scheduleSetItemCoords(_item_family, local_ids.m_future_items, _node_coords);
871 auto& mesh_graph = m_mesh.internalMeshGraph();
872 _item_family.addScalarProperty<
Int32>(
"NoOutProperty42");
873 mesh_graph.addAlgorithm(Neo::MeshKernel::InProperty{ _item_family, m_mesh._itemCoordPropertyName(_item_family) },
874 Neo::MeshKernel::OutProperty{ _item_family,
"NoOutProperty42" },
875 [
this, item_family, &_item_family, &arcane_coords](Neo::Mesh::CoordPropertyType
const& item_coords_property,
876 Neo::ScalarPropertyT<Neo::utils::Int32>&) {
878 auto& all_items = _item_family.all();
879 VariableNodeReal3 node_coords{ VariableBuildInfo{ item_family->mesh(),
"NodeCoord" } };
880 for (
auto item : all_items) {
881 arcane_coords[ItemLocalId{ item }] = { item_coords_property[item].x,
882 item_coords_property[item].y,
883 item_coords_property[item].z };
890 Neo::EndOfMeshUpdate applyScheduledOperations() noexcept
892 return m_mesh.applyScheduledOperations();
896 template <>
class PolyhedralMeshImpl::ItemKindTraits<
IK_Cell>
898 static const Neo::ItemKind item_kind = Neo::ItemKind::IK_Cell;
900 template <>
class PolyhedralMeshImpl::ItemKindTraits<
IK_Face>
902 static const Neo::ItemKind item_kind = Neo::ItemKind::IK_Face;
904 template <>
class PolyhedralMeshImpl::ItemKindTraits<
IK_Edge>
906 static const Neo::ItemKind item_kind = Neo::ItemKind::IK_Edge;
908 template <>
class PolyhedralMeshImpl::ItemKindTraits<
IK_Node>
910 static const Neo::ItemKind item_kind = Neo::ItemKind::IK_Node;
912 template <>
class PolyhedralMeshImpl::ItemKindTraits<
IK_DoF>
914 static const Neo::ItemKind item_kind = Neo::ItemKind::IK_Dof;
919 void PolyhedralFamilySerializer::serializeItems(ISerializer* buf,
Int32ConstArrayView items_local_ids)
924 switch (buf->mode()) {
925 case ISerializer::ModeReserve: {
926 _fillItemData(items_local_ids);
927 m_item_data.serialize(buf);
928 auto connectivities = m_mesh->_impl()->connectivities(m_family);
929 for (
auto out_connectivity : connectivities) {
930 buf->reserve(out_connectivity.target_family.name());
931 buf->reserve(out_connectivity.name);
936 m_item_data.serialize(buf);
937 auto connectivities = m_mesh->_impl()->connectivities(m_family);
938 for (
auto out_connectivity : connectivities) {
939 buf->put(out_connectivity.target_family.name());
940 buf->put(out_connectivity.name);
946 deserializeItems(buf,
nullptr);
954 void PolyhedralFamilySerializer::deserializeItems(ISerializer* buf,
Int32Array* items_local_ids)
957 (
"Impossible to deserialize a buffer not in ModeGet. In ItemData::deserialize.Exiting"))
963 item_data.deserialize(buf, m_mesh, *items_local_ids);
965 item_data.deserialize(buf, m_mesh);
966 auto connectivities = m_mesh->_impl()->connectivities(m_family);
967 auto nb_connectivities = connectivities.size();
971 for (auto out_connectivity : connectivities) {
972 buf->get(connected_family_names[index]);
973 buf->get(connectivity_names[index]);
976 _fillItemFamilyInfo(item_data, connected_family_names, connectivity_names);
978 if (items_local_ids) {
979 m_deserialized_lids_array.push_back(items_local_ids);
982 m_future_item_lids_array.push_back(std::make_shared<PolyhedralTools::ItemLocalIds>());
983 m_mesh->scheduleAllocateItems(m_family_info, *m_future_item_lids_array.back().get());
986 m_mng->addSerializer(
this);
992 m_item_data =
ItemData{ items_local_ids.size(), 0, m_family,
nullptr, m_family->parallelMng()->commRank() };
993 Int64Array& item_infos = m_item_data.itemInfos();
997 item_infos.reserve(1 + nb_item * 32);
1000 auto connectivities = mesh_impl->connectivities(m_family);
1001 item_infos.add(connectivities.size());
1002 bool is_face_family = m_family->itemKind() ==
IK_Face;
1005 item_infos.add(item->uniqueId().asInt64());
1006 item_owners[item.index()] = item->owner();
1007 for (
auto out_connectivity : connectivities) {
1008 auto target_family = m_mesh->findItemFamily(PolyhedralMeshImpl::itemKindNeoToArcane(out_connectivity.target_family.itemKind()),
1009 out_connectivity.target_family.name(),
false,
false);
1011 auto arcane_connected_items = target_family->itemInfoListView();
1012 bool is_face_cell_connection = is_face_family && target_family->itemKind() ==
IK_Cell;
1013 item_infos.add(PolyhedralMeshImpl::itemKindNeoToArcane(out_connectivity.target_family.itemKind()));
1014 auto connected_items = out_connectivity[item.localId()];
1015 auto nb_connected_items = connected_items.size();
1016 item_infos.add(nb_connected_items);
1017 if (is_face_cell_connection && item->itemBase().isBoundary() && item->itemBase().backCell().isNull()) {
1018 item_infos.add(NULL_ITEM_UNIQUE_ID);
1020 for (
auto connected_item_lid : connected_items) {
1021 item_infos.add(arcane_connected_items[connected_item_lid].uniqueId().asInt64());
1023 if (is_face_cell_connection && item->itemBase().isBoundary() && !item->itemBase().backCell().isNull()) {
1024 item_infos.add(NULL_ITEM_UNIQUE_ID);
1035class mesh::PolyhedralMesh::PolyhedralMeshModifier
1040 explicit PolyhedralMeshModifier(PolyhedralMesh* mesh)
1044 void addItems(Int64ConstArrayView unique_ids, Int32ArrayView local_ids, eItemKind ik,
const String& family_name)
override
1046 m_mesh->addItems(unique_ids, local_ids, ik, family_name);
1049 void addItems(Int64ConstArrayView unique_ids, Int32ArrayView local_ids, Int32ConstArrayView owners, eItemKind ik,
const String& family_name)
override
1051 m_mesh->addItems(unique_ids, local_ids, owners, ik, family_name);
1054 void removeItems(Int32ConstArrayView local_ids, eItemKind ik,
const String& family_name)
override
1056 m_mesh->removeItems(local_ids, ik, family_name);
1061 PolyhedralMesh* m_mesh;
1067class mesh::PolyhedralMesh::InternalApi
1073 explicit InternalApi(PolyhedralMesh* mesh)
1075 , m_connectivity_mng(std::make_unique<ItemConnectivityMng>(mesh->traceMng()))
1076 , m_polyhedral_mesh_modifier(std::make_unique<PolyhedralMeshModifier>(mesh))
1081 void setMeshKind(
const MeshKind& v)
override
1083 if (v.meshStructure() != eMeshStructure::Polyhedral && v.meshAMRKind() != eMeshAMRKind::None) {
1084 ARCANE_FATAL(
"Incompatible mesh structure ({0}) and amr kind ({1}) for Polyhedral mesh {2}. Must be (Polyhedral,None). ",
1085 v.meshStructure(), v.meshAMRKind(), m_mesh->name());
1087 m_mesh->m_mesh_kind = v;
1090 IItemConnectivityMng* dofConnectivityMng() const noexcept
override
1092 return m_connectivity_mng.get();
1095 IPolyhedralMeshModifier* polyhedralMeshModifier() const noexcept
override
1097 return m_polyhedral_mesh_modifier.get();
1100 void removeNeedRemoveMarkedItems()
override
1102 m_mesh->removeNeedRemoveMarkedItems();
1104 NodeLocalId addNode([[maybe_unused]] ItemUniqueId unique_id)
override
1108 FaceLocalId addFace([[maybe_unused]] ItemUniqueId unique_id,
1109 [[maybe_unused]] ItemTypeId type_id,
1110 [[maybe_unused]] ConstArrayView<Int64> nodes_uid)
override
1114 CellLocalId addCell([[maybe_unused]] ItemUniqueId unique_id,
1115 [[maybe_unused]] ItemTypeId type_id,
1116 [[maybe_unused]] ConstArrayView<Int64> nodes_uid)
override
1121 IItemFamilySerializerMngInternal* familySerializerMng() const noexcept
override
1123 return m_mesh->polyhedralFamilySerializerMng();
1128 PolyhedralMesh* m_mesh =
nullptr;
1129 std::unique_ptr<IItemConnectivityMng> m_connectivity_mng =
nullptr;
1130 std::unique_ptr<IPolyhedralMeshModifier> m_polyhedral_mesh_modifier =
nullptr;
1136class mesh::PolyhedralMesh::NoCompactionMeshCompacter
1141 explicit NoCompactionMeshCompacter(PolyhedralMesh* mesh)
1143 , m_trace_mng(mesh->traceMng())
1146 void doAllActions()
override { _info(); };
1148 void beginCompact()
override { _info(); };
1149 void compactVariablesAndGroups()
override { _info(); };
1150 void updateInternalReferences()
override { _info(); };
1151 void endCompact()
override { _info(); };
1152 void finalizeCompact()
override { _info(); };
1154 IMesh* mesh()
const override {
return m_mesh; };
1156 const ItemFamilyCompactInfos* findCompactInfos(IItemFamily*)
const override
1162 ePhase phase()
const override
1165 return ePhase::Ended;
1168 void setSorted(
bool)
override { _info(); };
1170 bool isSorted()
const override
1182 void _setCompactVariablesAndGroups(
bool)
override { _info(); };
1186 PolyhedralMesh* m_mesh =
nullptr;
1187 ITraceMng* m_trace_mng =
nullptr;
1189 void _info()
const { m_trace_mng->info() << A_FUNCINFO <<
"No compacting in PolyhedralMesh"; }
1195class mesh::PolyhedralMesh::NoCompactionMeshCompactMng
1200 explicit NoCompactionMeshCompactMng(PolyhedralMesh* mesh)
1202 , m_trace_mng(mesh->traceMng())
1203 , m_mesh_compacter{ std::make_unique<NoCompactionMeshCompacter>(m_mesh) }
1206 IMesh* mesh()
const override {
return m_mesh; }
1207 IMeshCompacter* beginCompact()
override
1210 return m_mesh_compacter.get();
1213 IMeshCompacter* beginCompact(IItemFamily* family)
override
1215 ARCANE_UNUSED(family);
1217 return m_mesh_compacter.get();
1220 void endCompact()
override { _info(); };
1222 IMeshCompacter* compacter()
override
1225 return m_mesh_compacter.get();
1230 PolyhedralMesh* m_mesh =
nullptr;
1231 ITraceMng* m_trace_mng =
nullptr;
1232 std::unique_ptr<IMeshCompacter> m_mesh_compacter =
nullptr;
1234 void _info()
const { m_trace_mng->info() << A_FUNCINFO <<
"No compacting in PolyhedralMesh"; }
1240mesh::PolyhedralMesh::
1243 m_mesh_handle._setMesh(
nullptr);
1252 return m_subdomain->traceMng();
1261 return m_mesh_handle;
1266mesh::PolyhedralMesh::
1267PolyhedralMesh(ISubDomain* subdomain,
const MeshBuildInfo& mbi)
1269, m_name{ mbi.name() }
1270, m_subdomain{ subdomain }
1271, m_mesh_handle{ m_subdomain->defaultMeshHandle() }
1272, m_properties(std::make_unique<Properties>(subdomain->propertyMng(), String(
"ArcaneMeshProperties_") + m_name))
1274, m_parallel_mng{ mbi.parallelMngRef().get() }
1275, m_mesh_part_info{ makeMeshPartInfoFromParallelMng(m_parallel_mng) }
1276, m_item_type_mng(ItemTypeMng::_singleton())
1277, m_mesh_kind(mbi.meshKind())
1278, m_polyhedral_family_serializer_mng{ std::make_unique<PolyhedralFamilySerializerMng>(this) }
1279, m_initial_allocator(*this)
1280, m_variable_mng{ subdomain->variableMng() }
1281, m_mesh_checker{ this }
1282, m_internal_api{ std::make_unique<InternalApi>(this) }
1283, m_compact_mng{ std::make_unique<NoCompactionMeshCompactMng>(this) }
1284, m_mesh_utilities{ std::make_unique<UnstructuredMeshUtilities>(this) }
1287, m_ghost_layer_mng{ std::make_unique<
GhostLayerMng>(m_trace_mng) }
1288, m_connectivity(VariableBuildInfo{ subdomain, mbi.name() +
"MeshConnectivity" })
1290 m_mesh_handle._setMesh(
this);
1291 m_mesh_item_internal_list.mesh =
this;
1292 m_default_arcane_families.fill(
nullptr);
1298void Arcane::mesh::PolyhedralMesh::
1301 _allocateItems(item_allocation_info, ArrayView<Int32UniqueArray>{});
1306void Arcane::mesh::PolyhedralMesh::
1307allocateItems(
const Arcane::ItemAllocationInfo& item_allocation_info, ArrayView<Int32UniqueArray> family_lids)
1309 _allocateItems(item_allocation_info, family_lids);
1314void Arcane::mesh::PolyhedralMesh::
1315_allocateItems(
const Arcane::ItemAllocationInfo& item_allocation_info, ArrayView<Int32UniqueArray> family_lids)
1318 m_subdomain->traceMng()->info() <<
"--PolyhedralMesh: allocate items --";
1319 UniqueArray<PolyhedralTools::ItemLocalIds> item_local_ids(item_allocation_info.family_infos.size());
1320 auto family_index = 0;
1322 for (
auto& family_info : item_allocation_info.family_infos) {
1323 bool create_if_needed =
true;
1324 auto* item_family = _findItemFamily(family_info.item_kind, family_info.name, create_if_needed);
1325 m_trace_mng->debug(
Trace::High) <<
"- Create items " << family_info.name;
1326 m_mesh->scheduleAddItems(item_family, family_info.item_uids, family_info.item_owners.constSmallSpan(), item_local_ids[family_index++]);
1330 for (
auto& family_info : item_allocation_info.family_infos) {
1331 auto* item_family = _findItemFamily(family_info.item_kind, family_info.name);
1332 m_trace_mng->debug(
Trace::High) <<
"- Current family " << family_info.name;
1333 for (
auto& current_connected_family_info : family_info.connected_family_infos) {
1334 auto connected_family = _findItemFamily(current_connected_family_info.item_kind, current_connected_family_info.name);
1335 m_trace_mng->debug(
Trace::High) <<
"- Create connectivity " << current_connected_family_info.connectivity_name;
1337 if (!connected_family) {
1338 ARCANE_WARNING((String::format(
"Cannot find family {0} with kind {1} "
1339 "The connectivity between {1} and this family is skipped",
1340 current_connected_family_info.name,
1341 current_connected_family_info.item_kind,
1342 item_family->name())
1346 m_mesh->scheduleAddConnectivity(item_family,
1347 item_local_ids[family_index],
1348 current_connected_family_info.nb_connected_items_per_item,
1350 current_connected_family_info.connected_items_uids,
1351 current_connected_family_info.connectivity_name);
1352 Connectivity connectivity{ m_connectivity };
1358 m_mesh->applyScheduledOperations();
1360 for (
auto& family_info : item_allocation_info.family_infos) {
1361 if (family_info.item_kind !=
IK_Node && family_info.item_coordinates.empty()) {
1364 auto* item_family = _findItemFamily(family_info.item_kind, family_info.name);
1365 if (item_family == itemFamily(
IK_Node)) {
1366 if (!m_arcane_node_coords.get()) {
1367 m_arcane_node_coords = std::make_unique<VariableNodeReal3>(VariableBuildInfo(
this, family_info.item_coordinates_variable_name));
1368 m_arcane_node_coords->setUsed(
true);
1372 auto arcane_item_coords_var_ptr = std::make_unique<VariableItemReal3>(VariableBuildInfo(
this, family_info.item_coordinates_variable_name),
1373 item_family->itemKind());
1374 arcane_item_coords_var_ptr->setUsed(
true);
1375 m_arcane_item_coords.push_back(std::move(arcane_item_coords_var_ptr));
1379 for (
auto& family : m_arcane_families) {
1380 family->endUpdate();
1386 for (
auto& family_info : item_allocation_info.family_infos) {
1387 if (family_info.item_coordinates.empty()) {
1391 auto* item_family = _findItemFamily(family_info.item_kind, family_info.name);
1392 if (item_family == itemFamily(
IK_Node)) {
1393 m_mesh->scheduleSetItemCoordinates(item_family, item_local_ids[family_index], family_info.item_coordinates, *m_arcane_node_coords);
1396 m_mesh->scheduleSetItemCoordinates(item_family, item_local_ids[family_index], family_info.item_coordinates, *m_arcane_item_coords[index++].get());
1398 auto mesh_state = m_mesh->applyScheduledOperations();
1399 m_is_allocated =
true;
1401 itemTypeMng()->setMeshWithGeneralCells(
this);
1403 if (!family_lids.empty()) {
1405 ARCANE_ASSERT((family_lids.size() == item_local_ids.size()), (
"Incoherence in item number"));
1406 for (
auto& lid_array : item_local_ids) {
1407 family_lids[index].resize(lid_array.size());
1408 lid_array.fillArrayView(family_lids[index].view(), mesh_state);
1416void Arcane::mesh::PolyhedralMesh::
1417scheduleAllocateItems(
const Arcane::ItemAllocationInfo::FamilyInfo& family_info, mesh::PolyhedralTools::ItemLocalIds& item_local_ids)
1420 m_subdomain->traceMng()->info() <<
"--PolyhedralMesh: schedule allocate items --";
1422 bool create_if_needed =
true;
1423 auto* item_family = _findItemFamily(family_info.item_kind, family_info.name, create_if_needed);
1424 m_trace_mng->debug(
Trace::High) <<
"- Current family " << family_info.name;
1425 m_trace_mng->debug(
Trace::High) <<
"- Create items ";
1426 m_mesh->scheduleAddItems(item_family, family_info.item_uids, family_info.item_owners.
constSmallSpan(), item_local_ids);
1428 for (
auto& current_connected_family_info : family_info.connected_family_infos) {
1429 auto connected_family = _findItemFamily(current_connected_family_info.item_kind, current_connected_family_info.name);
1430 m_trace_mng->debug(
Trace::High) <<
"- Create connectivity " << current_connected_family_info.connectivity_name;
1432 if (!connected_family) {
1433 ARCANE_WARNING((String::format(
"Cannot find family {0} with kind {1} "
1434 "The connectivity between {1} and this family is skipped",
1435 current_connected_family_info.name,
1436 current_connected_family_info.item_kind,
1437 item_family->name())
1441 m_mesh->scheduleUpdateConnectivity(item_family,
1443 current_connected_family_info.nb_connected_items_per_item,
1445 current_connected_family_info.connected_items_uids,
1446 current_connected_family_info.connectivity_name);
1452void Arcane::mesh::PolyhedralMesh::
1453applyScheduledAllocateItems(UniqueArray<std::shared_ptr<PolyhedralTools::ItemLocalIds>> item_lids)
1456 auto mesh_state = m_mesh->applyScheduledOperations();
1458 for (
auto item_local_ids : item_lids) {
1459 item_local_ids->m_mesh_state = std::make_shared<Neo::EndOfMeshUpdate>(mesh_state);
1463 for (
auto& family : m_arcane_families) {
1464 family->endUpdate();
1467 m_is_allocated =
true;
1469 itemTypeMng()->setMeshWithGeneralCells(
this);
1474void mesh::PolyhedralMesh::removeNeedRemoveMarkedItems()
1477 for (
auto family_index = 0; family_index < m_arcane_families.size(); ++family_index) {
1479 auto* family = m_arcane_families[family_index].get();
1481 items_to_remove.
reserve(family->nbItem());
1482 auto& items_map = family->itemsMap();
1483 if (items_map.count() == 0)
1485 items_map.eachItem([&](ItemBase item) {
1487 auto f = item.flags();
1490 item.toMutable().setFlags(f);
1491 items_to_remove.add(item.localId());
1494 if (!items_to_remove.empty()) {
1495 removeItems(items_to_remove, family);
1502Arcane::mesh::PolyhedralFamilySerializerMng* mesh::PolyhedralMesh::
1503polyhedralFamilySerializerMng()
1505 return m_polyhedral_family_serializer_mng.get();
1511void Arcane::mesh::PolyhedralMesh::
1514 for (
auto& family : m_arcane_families) {
1515 family->endUpdate();
1522void Arcane::mesh::PolyhedralMesh::
1523_computeFamilySynchronizeInfos()
1525 m_subdomain->traceMng()->info() <<
"Computing family synchronization information for " << name();
1526 for (
auto& family : m_arcane_families) {
1527 family->computeSynchronizeInfos();
1532 auto* var_syncer = cellFamily()->allItemsSynchronizer();
1533 Int32 iteration = m_subdomain->commonVariables().globalIteration();
1534 String file_name = String::format(
"{0}_sync_topology_iter{1}.json", name(), iteration);
1535 mesh_utils::dumpSynchronizerTopologyJSON(var_syncer, file_name);
1542void Arcane::mesh::PolyhedralMesh::
1543_notifyEndUpdateForFamilies()
1545 for (
auto& family : m_arcane_families)
1546 family->_internalApi()->notifyEndUpdateFromMesh();
1552void Arcane::mesh::PolyhedralMesh::
1553_computeGroupSynchronizeInfos()
1555 auto action = [](ItemGroup& group) {
1556 if (group.hasSynchronizer())
1557 group.synchronizer()->compute();
1560 m_trace_mng->info() <<
"Computing group synchronization information for " << name();
1561 meshvisitor::visitGroups(
this, action);
1579 return m_mesh->dimension();
1588 return m_mesh->nbNode();
1597 return m_mesh->nbEdge();
1606 return m_mesh->nbFace();
1615 return m_mesh->nbCell();
1624 return m_mesh->nbItem(ik);
1633 if (m_default_arcane_families[
IK_Node])
1634 return m_default_arcane_families[
IK_Node]->allItems();
1645 if (m_default_arcane_families[
IK_Edge])
1646 return m_default_arcane_families[
IK_Edge]->allItems();
1657 if (m_default_arcane_families[
IK_Face])
1658 return m_default_arcane_families[
IK_Face]->allItems();
1669 if (m_default_arcane_families[
IK_Cell])
1670 return m_default_arcane_families[
IK_Cell]->allItems();
1681 if (m_default_arcane_families[
IK_Node])
1682 return m_default_arcane_families[
IK_Node]->allItems().own();
1693 if (m_default_arcane_families[
IK_Edge])
1694 return m_default_arcane_families[
IK_Edge]->allItems().own();
1705 if (m_default_arcane_families[
IK_Face])
1706 return m_default_arcane_families[
IK_Face]->allItems().own();
1717 if (m_default_arcane_families[
IK_Cell])
1718 return m_default_arcane_families[
IK_Cell]->allItems().own();
1729 if (m_default_arcane_families[
IK_Cell])
1738mesh::PolyhedralFamily* mesh::PolyhedralMesh::
1739_createItemFamily(
eItemKind ik,
const String& name)
1741 m_mesh->addFamily(ik, name);
1742 m_arcane_families.push_back(std::make_unique<PolyhedralFamily>(
this, ik, name));
1743 auto current_family = m_arcane_families.back().get();
1744 if (m_default_arcane_families[ik] ==
nullptr) {
1745 m_default_arcane_families[ik] = current_family;
1746 _updateMeshInternalList(ik);
1748 m_item_family_collection.add(current_family);
1749 current_family->build();
1750 return current_family;
1759 return _createItemFamily(ik, name);
1765void mesh::PolyhedralMesh::
1768 createItemFamily(
IK_Cell,
"CellFamily");
1769 createItemFamily(
IK_Node,
"NodeFamily");
1770 auto cell_family = m_default_arcane_families[
IK_Cell];
1771 auto node_family = m_default_arcane_families[
IK_Node];
1774 PolyhedralTools::ItemLocalIds cell_lids, node_lids;
1775 m_mesh->scheduleAddItems(cell_family, cell_uids.constView(), cell_lids);
1776 m_mesh->scheduleAddItems(node_family, node_uids.constView(), node_lids);
1779 m_mesh->scheduleAddConnectivity(cell_family, cell_lids, nb_node, node_family, node_uids, String{
"CellToNodes" });
1780 m_mesh->scheduleAddConnectivity(node_family, node_lids, 1, cell_family,
1781 node_cells_uids, String{
"NodeToCells" });
1782 m_mesh->applyScheduledOperations();
1783 cell_family->endUpdate();
1784 node_family->endUpdate();
1797 for (
auto ik = 0; ik < NB_ITEM_KIND; ++ik) {
1800 m_empty_arcane_families[ik] = std::make_unique<mesh::PolyhedralFamily>(
this, (
eItemKind)ik, name);
1801 m_default_arcane_families[ik] = m_empty_arcane_families[ik].get();
1812 return m_default_arcane_families[
IK_Node];
1821 return m_default_arcane_families[
IK_Edge];
1830 return m_default_arcane_families[
IK_Face];
1839 return m_default_arcane_families[
IK_Cell];
1842void mesh::PolyhedralMesh::
1847 m_mesh_item_internal_list.cells = m_default_arcane_families[kind]->itemsInternal();
1848 m_mesh_item_internal_list._internalSetCellSharedInfo(m_default_arcane_families[kind]->commonItemSharedInfo());
1851 m_mesh_item_internal_list.faces = m_default_arcane_families[kind]->itemsInternal();
1852 m_mesh_item_internal_list._internalSetFaceSharedInfo(m_default_arcane_families[kind]->commonItemSharedInfo());
1855 m_mesh_item_internal_list.edges = m_default_arcane_families[kind]->itemsInternal();
1856 m_mesh_item_internal_list._internalSetEdgeSharedInfo(m_default_arcane_families[kind]->commonItemSharedInfo());
1859 m_mesh_item_internal_list.nodes = m_default_arcane_families[kind]->itemsInternal();
1860 m_mesh_item_internal_list._internalSetNodeSharedInfo(m_default_arcane_families[kind]->commonItemSharedInfo());
1872mesh::PolyhedralFamily* mesh::PolyhedralMesh::
1875 return m_default_arcane_families[ik];
1884 return _itemFamily(ik);
1893 return m_item_type_mng;
1899mesh::PolyhedralFamily* mesh::PolyhedralMesh::
1900_findItemFamily(
eItemKind ik,
const String& name,
bool create_if_needed)
1903 auto found_family = _itemFamily(ik);
1905 if (found_family->name() == name)
1906 return found_family;
1908 for (
auto& family : m_arcane_families) {
1909 if (family->itemKind() == ik && family->name() == name)
1910 return family.get();
1912 if (!create_if_needed)
1914 return _createItemFamily(ik, name);
1923 ARCANE_UNUSED(register_modifier_if_created);
1924 return _findItemFamily(ik, name, create_if_needed);
1930mesh::PolyhedralFamily* mesh::PolyhedralMesh::
1933 return m_default_arcane_families[ik];
1942 ARCANE_ASSERT(m_arcane_node_coords, (
"Node coordinates not yet loaded."));
1943 return *m_arcane_node_coords;
1953 for (
auto& family : m_arcane_families) {
1954 group = family->findGroup(name);
1967 m_all_groups.
clear();
1968 for (
auto& family : m_arcane_families) {
1970 m_all_groups.add(*i_group);
1972 return m_all_groups;
1981 for (
auto& family : m_arcane_families) {
1982 family->destroyGroups();
1992 return m_item_family_collection;
2001 return m_internal_api.get();
2010 return m_compact_mng.get();
2016void mesh::PolyhedralMesh::
2019 ARCANE_ASSERT((unique_ids.size() == local_ids.size()), (
"local and unique ids arrays must have same size"))
2020 auto* item_family = _findItemFamily(ik, family_name, false);
2021 PolyhedralTools::ItemLocalIds item_local_ids;
2022 m_mesh->scheduleAddItems(item_family, unique_ids, item_local_ids);
2023 auto mesh_state = m_mesh->applyScheduledOperations();
2024 item_local_ids.fillArrayView(local_ids, mesh_state);
2033 ARCANE_ASSERT((unique_ids.size() == local_ids.size() && (unique_ids.size() == owners.size())), (
"local/unique ids and owners arrays must have same size"))
2034 auto* item_family = _findItemFamily(ik, family_name, false);
2035 PolyhedralTools::ItemLocalIds item_local_ids;
2036 m_mesh->scheduleAddItems(item_family, unique_ids, owners, item_local_ids);
2037 auto mesh_state = m_mesh->applyScheduledOperations();
2038 item_local_ids.fillArrayView(local_ids, mesh_state);
2047 auto* item_family = _findItemFamily(ik, family_name,
false);
2049 ARCANE_FATAL(
"ItemFamily with name {0} and kind {1} does not exist in the mesh.", family_name, ik);
2051 m_mesh->scheduleRemoveItems(item_family, local_ids);
2052 m_mesh->applyScheduledOperations();
2058void mesh::PolyhedralMesh::
2061 if (local_ids.empty())
2064 ARCANE_FATAL(
"Invalid IItemFamily passed to removeItems.");
2066 removeItems(local_ids, family->itemKind(), family->name());
2075 addItems(nodes_uid, nodes_lid,
IK_Node, nodeFamily()->name());
2084 m_trace_mng->info() <<
"PolyhedralMesh::_exchangeItems() do_compact?=" <<
"false"
2085 <<
" nb_exchange=" << 0 <<
" version=" << 0;
2088 if (!check_exchange.null()) {
2089 m_mesh_checker.checkGhostCells();
2090 m_trace_mng->pwarning() <<
"CHECKING SYNCHRONISATION !";
2091 m_mesh_checker.checkVariablesSynchronization();
2092 m_mesh_checker.checkItemGroupsSynchronization();
2094 if (checkLevel() >= 2)
2095 m_mesh_checker.checkValidMesh();
2096 else if (checkLevel() >= 1)
2097 m_mesh_checker.checkValidConnectivity();
2103void mesh::PolyhedralMesh::
2108 Trace::Setter mci(traceMng(), _className());
2113 if (arcane_debug_load_balancing) {
2114 for (
auto& family : m_arcane_families) {
2115 family->itemsNewOwner().checkIfSync();
2119 IMeshExchanger* iexchanger = m_mesh_exchange_mng->beginExchange();
2122 if (iexchanger->computeExchangeInfos()) {
2123 m_trace_mng->pwarning() <<
"No load balance is performed";
2124 m_mesh_exchange_mng->endExchange();
2129 iexchanger->processExchange();
2132 iexchanger->removeNeededItems();
2137 auto action = [](ItemGroup& group) {
2138 if (group.internal()->hasComputeFunctor() || group.isLocalToSubDomain())
2141 group.internal()->removeSuppressedItems();
2143 meshvisitor::visitGroups(
this, action);
2146 iexchanger->allocateReceivedItems();
2149 _endUpdateFamilies();
2150 _computeFamilySynchronizeInfos();
2153 iexchanger->updateItemGroups();
2155 _computeGroupSynchronizeInfos();
2157 iexchanger->updateVariables();
2161 m_mesh_checker.checkMeshFromReferenceFile();
2162 _notifyEndUpdateForFamilies();
2164 iexchanger->finalizeExchange();
2166 m_mesh_exchange_mng->endExchange();
2182 auto want_dump =
false;
2183 auto need_compact =
false;
2184 m_trace_mng->info(4) <<
"DynamicMesh::prepareForDump() name=" << name()
2185 <<
" need_compact?=" << need_compact
2186 <<
" want_dump?=" << want_dump
2187 <<
" timestamp=" << 0;
2191 m_mesh_events.eventObservable(t).notify(MeshEventArgs(
this, t));
2196 for (
auto& family : m_arcane_families) {
2197 family->prepareForDump();
2203 m_mesh_events.eventObservable(t).notify(MeshEventArgs(
this, t));
2284 return m_mesh_utilities.get();
2293 IItemFamily* item_family = _itemFamily(ik);
2295 return item_family->itemsNewOwner();
2304 return m_mesh_checker.checkLevel();
2313 return m_item_family_network.get();
2322 return m_ghost_layer_mng.get();
2331 return m_internal_api.get();
2337mesh::PolyhedralMeshImpl* mesh::PolyhedralMesh::_impl()
2339 return m_mesh.get();
2355namespace Arcane::mesh
2364Arcane::mesh::PolyhedralMesh::
2365~PolyhedralMesh() =
default;
2370Arcane::mesh::PolyhedralMesh::
2372: EmptyMesh{ subdomain->traceMng() }
2373, m_subdomain{ subdomain }
2375, m_mesh_kind(mbi.meshKind())
2382void Arcane::mesh::PolyhedralMesh::
2383read([[maybe_unused]]
const String& filename)
2391void Arcane::mesh::PolyhedralMesh::
2392allocateItems(
const Arcane::ItemAllocationInfo& item_allocation_info)
2394 ARCANE_UNUSED(item_allocation_info);
2409class ARCANE_MESH_EXPORT PolyhedralMeshFactory
2428 static String name() {
return "ArcanePolyhedralMeshFactory"; }
2438#if ARCANE_HAS_POLYHEDRAL_MESH_TOOLS
2446 return PolyhedralMeshFactory::name();
#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_CHECK_POINTER2(ptr, text)
Macro returning the pointer ptr if it is not null or throwing an exception if it is null.
#define ARCANE_THROW(exception_class,...)
Macro for throwing an exception with formatting.
#define ARCANE_FATAL(...)
Macro throwing a FatalErrorException.
This file contains the various service factories and macros for registering services.
#define ARCANE_SERVICE_INTERFACE(ainterface)
Macro to declare an interface when registering a service.
AbstractService(const ServiceBuildInfo &)
Constructor from a ServiceBuildInfo.
constexpr Integer size() const noexcept
Returns the size of the array.
SmallSpan< const T > constSmallSpan() const
Immutable view of this array.
void reserve(Int64 new_capacity)
Reserves memory for new_capacity elements.
void clear()
Removes all elements from the collection.
EnumeratorT< ItemGroup > Enumerator
static Integer kindsToConnectivity(eItemKind kindA, eItemKind kindB)
Type to connectivity conversion.
virtual ITraceMng * traceMng()=0
Associated message manager.
virtual NodeGroup ownNodes()=0
Group of all domain-specific nodes.
virtual MeshHandle handle() const =0
Handle on this mesh.
virtual IItemFamily * nodeFamily()=0
Returns the node family.
virtual String name() const =0
Mesh name.
virtual Integer nbCell()=0
Number of mesh cells.
virtual CellGroup ownCells()=0
Group of all domain-specific cells.
virtual FaceGroup ownFaces()=0
Group of all domain-specific faces.
virtual FaceGroup allFaces()=0
Group of all faces.
virtual Integer nbEdge()=0
Number of mesh edges.
virtual IItemFamily * itemFamily(eItemKind ik)=0
Returns the entity family of type ik.
virtual IItemFamily * edgeFamily()=0
Returns the edge family.
virtual Integer nbNode()=0
Number of mesh nodes.
virtual FaceGroup outerFaces()=0
Group of all faces on the boundary.
virtual IItemFamily * findItemFamily(eItemKind ik, const String &name, bool create_if_needed=false, bool register_modifier_if_created=false)=0
Returns the family named name.
virtual Integer nbItem(eItemKind ik)=0
Number of elements of type ik.
virtual Integer dimension()=0
Mesh dimension (1D, 2D, or 3D).
virtual IItemFamily * faceFamily()=0
Returns the face family.
virtual EdgeGroup ownEdges()=0
Group of all domain-specific edges.
virtual NodeGroup allNodes()=0
Group of all nodes.
virtual CellGroup allCells()=0
Group of all cells.
virtual Integer nbFace()=0
Number of mesh faces.
virtual IItemFamily * cellFamily()=0
Returns the cell family.
virtual IItemFamily * createItemFamily(eItemKind ik, const String &name)=0
Create a particle family named name.
virtual EdgeGroup allEdges()=0
Group of all edges.
Interface for managing the compaction of mesh families.
Management of mesh family compaction.
Interface of the service managing mesh reading.
virtual IVariableMng * variableMng() const =0
Variable manager associated with this manager.
Internal part of IMeshModifier.
virtual void addNodes(Int64ConstArrayView nodes_uid, Int32ArrayView nodes_lid=Int32ArrayView())=0
Adds nodes.
virtual IMeshModifierInternal * _modifierInternalApi()=0
Internal API for Arcane.
virtual VariableNodeReal3 & nodesCoordinates()=0
Node coordinates.
virtual FaceGroup outerActiveFaces()=0
Group of all active faces on the boundary.
virtual void destroyGroups()=0
Destroys all groups of all families.
virtual IMeshUtilities * utilities()=0
Associated utility functions interface.
virtual CellGroup allLevelCells(const Integer &level)=0
Group of all cells of level level.
virtual FaceGroup innerActiveFaces()=0
Group of all active faces.
virtual ItemGroupCollection groups()=0
List of groups.
virtual ItemGroup findGroup(const String &name)=0
Returns the group with name name or a null group if none exists.
virtual String factoryName() const =0
Name of the factory used to create the mesh.
virtual IMeshInternal * _internalApi()=0
Internal Arcane API.
virtual CellGroup allActiveCells()=0
virtual FaceGroup allActiveFaces()=0
Group of all active faces.
virtual ItemTypeMng * itemTypeMng() const =0
Associated entity type manager.
virtual void prepareForDump()=0
Prepares the instance for dumping.
virtual CellGroup ownActiveCells()=0
Group of all active cells specific to the domain.
virtual CellGroup ownLevelCells(const Integer &level)=0
Group of all cells specific to the domain of level level.
virtual IGhostLayerMng * ghostLayerMng() const =0
Associated ghost layer manager.
virtual FaceGroup ownActiveFaces()=0
Group of all active faces specific to the domain.
virtual IItemFamilyNetwork * itemFamilyNetwork()=0
Family network interface (connected families).
virtual IMeshCompactMng * _compactMng()=0
virtual Integer checkLevel() const =0
Current check level.
virtual void exchangeItems()=0
Changes the owning subdomains of entities.
virtual VariableItemInt32 & itemsNewOwner(eItemKind kind)=0
Variable containing the identifier of the owning subdomain.
@ ModePut
The serializer expects reserve().
@ ModeGet
The serializer expects get().
Interface of the subdomain manager.
virtual ISubDomain * internalSubDomain() const =0
Temporary internal function to retrieve the subdomain.
virtual IVariableMngInternal * _internalApi()=0
Internal Arcane API.
@ II_FrontCellIsFirst
The first cell of the entity is the front cell.
@ II_NeedRemove
The entity must be removed.
@ II_HasBackCell
The entity has a back cell.
@ II_Suppressed
The entity has just been suppressed.
@ II_Boundary
The entity is on the boundary.
@ II_HasFrontCell
The entity has a front cell.
@ II_BackCellIsFirst
The first cell of the entity is the back cell.
FaceGroup activeFaceGroup() const
Group of active faces.
FaceGroup innerActiveFaceGroup() const
Group of internal faces of the elements of this group.
FaceGroup ownActiveFaceGroup() const
Group of active faces belonging to the domain of the elements of this group.
CellGroup levelCellGroup(const Integer &level) const
Group of level l cells of the elements of this group.
CellGroup ownActiveCellGroup() const
Group of own active cells of the elements of this group.
CellGroup ownLevelCellGroup(const Integer &level) const
Group of own level l cells of the elements of this group.
FaceGroup outerActiveFaceGroup() const
Group of active external faces of the elements of this group.
CellGroup activeCellGroup() const
AMR.
FaceGroup outerFaceGroup() const
Group of external faces of the elements of this group.
Parameters necessary for building a mesh.
void build() override
Build-level construction of the service.
IPrimaryMesh * createMesh(IMeshMng *mm, const MeshBuildInfo &build_info) override
Creates a mesh with the information from build_info.
Structure containing the information to create a service.
Service creation properties.
Unicode character string.
Manager for the policies of a family of entities.
Interface for the mesh exchange manager between subdomains.
void endUpdate()
Notifies the instance that mesh modification is finished.
ItemVectorViewT< DoF > DoFVectorView
View over a vector of degrees of freedom.
ItemGroupT< Cell > CellGroup
Group of cells.
ItemGroupT< Face > FaceGroup
Group of faces.
ItemGroupT< Edge > EdgeGroup
Group of edges.
ItemGroupT< Node > NodeGroup
Group of nodes.
#define ARCANE_REGISTER_SERVICE(aclass, a_service_property,...)
Macro for registering a service.
MeshVariableScalarRefT< Node, Real3 > VariableNodeReal3
Coordinate type quantity at node.
ItemVariableScalarRefT< Real3 > VariableItemReal3
3D coordinate type quantity
ItemVariableScalarRefT< Int32 > VariableItemInt32
32-bit integer type quantity
Array< Int64 > Int64Array
Dynamic one-dimensional array of 64-bit integers.
UniqueArray< Int64 > Int64UniqueArray
Dynamic 1D array of 64-bit integers.
Collection< ItemGroup > ItemGroupCollection
Collection of mesh item groups.
Int32 Integer
Type representing an integer.
ConstArrayView< Int32 > Int32ConstArrayView
C equivalent of a 1D array of 32-bit integers.
Collection< IItemFamily * > ItemFamilyCollection
Collection of item families.
Collection< IItemFamily * > IItemFamilyCollection
Collection of item families.
@ ST_Application
The service is used at the application level.
ConstArrayView< Int64 > Int64ConstArrayView
C equivalent of a 1D array of 64-bit integers.
SmallSpan< const Real3 > Real3ConstSmallSpan
Read-only view of a 1D array of Real3.
eMeshEventType
Events generated by IMesh.
@ EndPrepareDump
Event sent at the end of prepareForDump().
@ BeginPrepareDump
Event sent at the beginning of prepareForDump().
UniqueArray< Int32 > Int32UniqueArray
Dynamic 1D array of 32-bit integers.
ArrayView< Int32 > Int32ArrayView
C equivalent of a 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_Unknown
Unknown or uninitialized mesh entity.
@ IK_Face
Face mesh entity.
@ IK_DoF
Degree of Freedom mesh entity.
@ IK_Edge
Edge mesh entity.
SmallSpan< const Int64 > Int64ConstSmallSpan
Read-only view of a 1D array of 64-bit integers.
ARCCORE_SERIALIZE_EXPORT Ref< ISerializer > createSerializer()
Creates an instance of ISerializer.
const char * itemKindName(eItemKind kind)
Entity kind name.
Array< Int32 > Int32Array
Dynamic one-dimensional array of 32-bit integers.
UniqueArray< String > StringUniqueArray
Dynamic 1D array of strings.
Span< const Int32 > Int32ConstSpan
Read-only view of a 1D array of 32-bit integers.
SmallSpan< const Int32 > Int32ConstSmallSpan
Read-only view of a 1D array of 32-bit integers.
std::int32_t Int32
Signed integer type of 32 bits.