Arcane  4.2.2.0
Developer documentation
Loading...
Searching...
No Matches
PolyhedralMesh.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2026 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
4// See the top-level COPYRIGHT file for details.
5// SPDX-License-Identifier: Apache-2.0
6//-----------------------------------------------------------------------------
7/*---------------------------------------------------------------------------*/
8/* PolyhedralMesh.cc (C) 2000-2026 */
9/* */
10/* Polyhedral mesh implementation using Neo data structure. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include <memory>
15
16#include "arcane/mesh/PolyhedralMesh.h"
17
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"
44
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"
51#include "arccore/base/StringBuilder.h"
52
53#ifdef ARCANE_HAS_POLYHEDRAL_MESH_TOOLS
54
55#include "arcane/core/IMeshMng.h"
56#include "arcane/core/MeshHandle.h"
57#include "arcane/core/IItemFamily.h"
58#include "arcane/core/internal/IMeshInternal.h"
59#include "arcane/core/IVariableSynchronizer.h"
60#include "arcane/mesh/ItemFamilyPolicyMng.h"
61#include "arcane/mesh/ItemFamilySerializer.h"
62#include "arcane/utils/Collection.h"
63#include "arcane/utils/List.h"
64#include "arcane/utils/PlatformUtils.h"
65
66#include "neo/Mesh.h"
67#include "neo/Utils.h"
68#include "ItemConnectivityMng.h"
69
70#include "arcane/core/ItemPrinter.h"
71
72#endif
73
74// #define ARCANE_DEBUG_POLYHEDRAL_MESH
75#define ARCANE_DEBUG_LOAD_BALANCING
76
77#ifdef ARCANE_DEBUG_LOAD_BALANCING
78static bool arcane_debug_load_balancing = true;
79#else
80static bool arcane_debug_load_balancing = false;
81#endif
82
83/*---------------------------------------------------------------------------*/
84/*---------------------------------------------------------------------------*/
85
86void Arcane::mesh::PolyhedralMesh::
87_errorEmptyMesh() const
88{
89 ARCANE_FATAL("Cannot use PolyhedralMesh if Arcane is not linked with lib Neo");
90}
91
92/*---------------------------------------------------------------------------*/
93/*---------------------------------------------------------------------------*/
94
95#ifdef ARCANE_HAS_POLYHEDRAL_MESH_TOOLS
96
97/*---------------------------------------------------------------------------*/
98/*---------------------------------------------------------------------------*/
99
100namespace Arcane::mesh
101{
102namespace PolyhedralTools
103{
104 class ItemLocalIds
105 {
106 Neo::FutureItemRange m_future_items;
107 std::shared_ptr<Neo::EndOfMeshUpdate> m_mesh_state = nullptr;
108
109 public:
110
111 void fillArrayView(Int32ArrayView local_ids, Neo::EndOfMeshUpdate mesh_state)
112 {
113 auto lids = m_future_items.get(mesh_state);
114 if (local_ids.size() != lids.size())
115 ARCANE_FATAL("Cannot fill local_ids view, its size {0} != {1} (added item size)", local_ids.size(), m_future_items.size());
116 std::copy(lids.begin(), lids.end(), local_ids.begin());
117 }
118
119 void fillArrayView(Int32ArrayView local_ids)
120 {
121 ARCANE_CHECK_POINTER2(m_mesh_state.get(), "PolyhedralTools::ItemLocalIds must have a valid end of mesh state");
122 fillArrayView(local_ids, *m_mesh_state);
123 }
124
125 Integer size() const noexcept { return m_future_items.size(); }
126 bool isFilled() const noexcept { return m_mesh_state.get() != nullptr; };
127 void checkIsFilled(String error_message) const noexcept
128 {
129 if (!isFilled())
130 ARCANE_FATAL("Item local ids are not filled." + error_message);
131 }
132 friend class mesh::PolyhedralMeshImpl;
133 friend class mesh::PolyhedralMesh;
134 };
135} // namespace PolyhedralTools
136
137/*---------------------------------------------------------------------------*/
138/*---------------------------------------------------------------------------*/
139
140class PolyhedralFamilySerializer;
141class PolyhedralFamilySerializerMng : public IItemFamilySerializerMngInternal
142{
143 PolyhedralMesh* m_mesh = nullptr;
144 Integer m_nb_serializers = 0;
145 UniqueArray<PolyhedralFamilySerializer*> m_serializers;
146
147 public:
148
149 explicit PolyhedralFamilySerializerMng(PolyhedralMesh* mesh)
150 : m_mesh(mesh)
151 {
152 ARCANE_CHECK_POINTER2(mesh, "Must give a non null PolyhedralMesh pointer.");
153 }
154
155 void addSerializer(PolyhedralFamilySerializer* serializer)
156 {
157 m_serializers.push_back(serializer);
158 ++m_nb_serializers;
159 }
160
161 void finalizeItemAllocation() override;
162};
163
164/*---------------------------------------------------------------------------*/
165/*---------------------------------------------------------------------------*/
166
167class PolyhedralFamilySerializer : public IItemFamilySerializer
168{
169 private:
170
171 PolyhedralMesh* m_mesh = nullptr;
172 IItemFamily* m_family = nullptr;
173 PolyhedralFamilySerializerMng* m_mng = nullptr;
174 ItemData m_item_data;
175 UniqueArray<Int32Array*> m_deserialized_lids_array;
176 UniqueArray<std::shared_ptr<PolyhedralTools::ItemLocalIds>> m_future_item_lids_array;
177 ItemAllocationInfo::FamilyInfo m_family_info;
178
179 public:
180
181 explicit PolyhedralFamilySerializer(PolyhedralMesh* mesh, IItemFamily* family, PolyhedralFamilySerializerMng* mng)
182 : m_mesh(mesh)
183 , m_family(family)
184 , m_mng(mng)
185 {}
186
187 PolyhedralFamilySerializer(const PolyhedralFamilySerializer&) = delete;
188 PolyhedralFamilySerializer& operator=(const PolyhedralFamilySerializer&) = delete;
189
190 ArrayView<std::shared_ptr<PolyhedralTools::ItemLocalIds>> itemLidsArray() { return m_future_item_lids_array.view(); }
191
192 public:
193
194 void serializeItems(ISerializer* buf, Int32ConstArrayView items_local_ids) override;
195 void deserializeItems(ISerializer* buf, Int32Array* items_local_ids) override;
196
197 void clear()
198 {
199 m_item_data.clear();
200 m_deserialized_lids_array.clear();
201 m_future_item_lids_array.clear();
202 m_family_info.clear();
203 }
204
205 void fillDeserializedLocalIds()
206 {
207 auto index = 0;
208 for (auto item_lids_array : m_deserialized_lids_array) {
209 auto& future_item_lids = m_future_item_lids_array[index];
210 future_item_lids->checkIsFilled("Cannot fill deserialized local ids, future item local ids are not filled.");
211 item_lids_array->resize(future_item_lids->size());
212 future_item_lids->fillArrayView(item_lids_array->view());
213 ++index;
214 }
215 clear();
216 }
217
218 IItemFamilySerializerMngInternal* mng()
219 {
220 return m_mng;
221 }
222
223 // no need to distinguish between dependency or relation in Neo graph
224 void serializeItemRelations(ISerializer*, Int32ConstArrayView) override {}
225 void deserializeItemRelations(ISerializer*, Int32Array*) override {}
226
227 private:
228
229 void _fillItemData(Int32ConstArrayView items_local_ids);
230 void _fillItemFamilyInfo(const ItemData& item_data,
231 StringConstArrayView connected_family_names,
232 StringConstArrayView connectivity_names)
233 {
234 // clear data
235 m_family_info.clear();
236 // Check info in ItemData
237 if (m_family != item_data.itemFamily())
238 ARCANE_FATAL("PolyhedralFamilySerializer: Family mismatch. Synchronized family is {0} and serialized family is {1}",
239 m_family->name(), item_data.itemFamily()->name());
240 m_family_info.name = item_data.itemFamily()->name();
241 m_family_info.item_kind = item_data.itemFamily()->itemKind();
242 auto& connected_family_infos = m_family_info.connected_family_infos;
243 auto nb_connected_family = item_data.itemInfos()[0];
244 connected_family_infos.resize(nb_connected_family);
245 auto& item_uids = m_family_info._item_uids_data;
246 item_uids.reserve(item_data.nbItems());
247 auto item_infos = item_data.itemInfos();
248 for (auto connected_family_info : connected_family_infos) {
249 connected_family_info._connected_items_uids_data.reserve(4 * item_uids.size());
250 connected_family_info._nb_connected_items_per_item_data.reserve(item_uids.size());
251 }
252 for (auto index = 1; index < item_infos.size();) {
253 item_uids.push_back(item_infos[index + 1]); // first index is item type, not used in polyhedral
254 index += 2;
255 for (auto connected_family_index = 0; connected_family_index < nb_connected_family; ++connected_family_index) {
256 eItemKind family_kind = static_cast<eItemKind>(item_infos[index]);
257 auto* connected_family = m_mesh->findItemFamily(family_kind, connected_family_names[connected_family_index], false, false);
258 ARCANE_CHECK_POINTER(connected_family);
259 auto& current_connected_family_infos = connected_family_infos[connected_family_index];
260 current_connected_family_infos.item_kind = family_kind;
261 current_connected_family_infos.name = connected_family->name();
262 current_connected_family_infos.connectivity_name = connectivity_names[connected_family_index];
263 ++index;
264 auto nb_connected_items = static_cast<Int32>(item_infos[index]);
265 ++index;
266 current_connected_family_infos._nb_connected_items_per_item_data.push_back(nb_connected_items);
267 auto real_nb_connected_items = nb_connected_items;
268 if (m_family->itemKind() == IK_Face && connected_family->itemKind() == IK_Cell)
269 real_nb_connected_items = 2; // 2 cells are stored, even if one is null (boundary)
270 current_connected_family_infos._connected_items_uids_data.addRange(item_infos.subView(index, real_nb_connected_items));
271 index += real_nb_connected_items;
272 }
273 }
274 // Update FamilyInfo views
275 m_family_info.updateViewsFromInternalData();
276 // get owners
277 m_family_info.item_owners = item_data.itemOwners();
278 }
279
280 IItemFamily* family() const override
281 {
282 return m_family;
283 }
284};
285
286/*---------------------------------------------------------------------------*/
287/*---------------------------------------------------------------------------*/
288
289void PolyhedralFamilySerializerMng::
290finalizeItemAllocation()
291{
292 UniqueArray<std::shared_ptr<PolyhedralTools::ItemLocalIds>> future_item_lids;
293 for (auto family_serializer : m_serializers) {
294 for (auto& item_lids : family_serializer->itemLidsArray()) {
295 future_item_lids.push_back(item_lids);
296 }
297 }
298 m_mesh->applyScheduledAllocateItems(future_item_lids);
299 for (auto family_serializer : m_serializers) {
300 family_serializer->fillDeserializedLocalIds();
301 }
302 m_serializers.clear();
303}
304
305/*---------------------------------------------------------------------------*/
306/*---------------------------------------------------------------------------*/
307
308class PolyhedralFamilyPolicyMng
309: public ItemFamilyPolicyMng
310{
311 public:
312
313 PolyhedralFamilyPolicyMng(PolyhedralMesh* mesh, ItemFamily* family)
314 : ItemFamilyPolicyMng(family)
315 , m_mesh(mesh)
316 , m_family(family)
317 {}
318
319 public:
320
321 IItemFamilySerializer* createSerializer(bool) override
322 {
323 return new PolyhedralFamilySerializer(m_mesh, m_family, m_mesh->polyhedralFamilySerializerMng());
324 }
325
326 private:
327
328 PolyhedralMesh* m_mesh = nullptr;
329 ItemFamily* m_family = nullptr;
330};
331
332/*---------------------------------------------------------------------------*/
333/*---------------------------------------------------------------------------*/
334
335class PolyhedralFamily
336: public ItemFamily
337, public IDoFFamily
338{
339 ItemSharedInfoWithType* m_shared_info = nullptr;
340 Int32UniqueArray m_empty_connectivity{ 0 };
341 Int32UniqueArray m_empty_connectivity_indexes;
342 Int32UniqueArray m_empty_connectivity_nb_item;
343 PolyhedralMesh* m_mesh = nullptr;
344
345 public:
346
347 inline static const String m_arcane_item_lids_property_name{ "Arcane_Item_Lids" }; // inline used to initialize within the declaration
348 inline static const String m_arcane_remove_item_property_name{ "Arcane_Remove_Items" }; // inline used to initialize within the declaration
349
350 public:
351
352 PolyhedralFamily(PolyhedralMesh* mesh, eItemKind ik, String name)
353 : ItemFamily(mesh, ik, name)
354 , m_mesh(mesh)
355 {}
356
357 public:
358
359 void preAllocate(Integer nb_item)
360 {
361 Integer nb_hash = itemsMap().nbBucket();
362 Integer wanted_size = 2 * (nb_item + nbItem());
363 if (nb_hash < wanted_size)
364 itemsMap().resize(wanted_size, true);
365 m_empty_connectivity_indexes.resize(nb_item + nbItem(), 0);
366 m_empty_connectivity_nb_item.resize(nb_item + nbItem(), 0);
367 _updateEmptyConnectivity();
368 }
369
370 ItemInternal* _allocItem(const Int64 uid, const Int32 owner)
371 {
372 bool need_alloc; // given by alloc
373 ItemInternal* item_internal = ItemFamily::_findOrAllocOne(uid, need_alloc);
374 if (!need_alloc)
375 item_internal->setUniqueId(uid);
376 else {
377 _allocateInfos(item_internal, uid, m_shared_info);
378 }
379 item_internal->setOwner(owner, m_sub_domain_id);
380 return item_internal;
381 }
382
383 void addItems(Int64ConstSmallSpan uids, Int32ArrayView items)
384 {
385 Int32UniqueArray owners(uids.size(), m_sub_domain_id);
386 addItems(uids, items, owners);
387 }
388
389 void addItems(Int64ConstSmallSpan uids, Int32ArrayView items, Int32ConstArrayView owners)
390 {
391 if (uids.empty())
392 return;
393 ARCANE_ASSERT((uids.size() == items.size()), ("one must have items.size==uids.size()"));
394 preAllocate(uids.size());
395 auto index{ 0 };
396 for (auto uid : uids) {
397 ItemInternal* ii = _allocItem(uid, owners[index]);
398 items[index] = ii->localId();
399 ++index;
400 }
401 m_need_prepare_dump = true;
402 _updateItemInternalList();
403 }
404
405 void removeItems(Int32ConstArrayView local_ids)
406 {
407 _removeMany(local_ids);
408 }
409
410 void _updateItemInternalList()
411 {
412 switch (itemKind()) {
413 case IK_Cell:
414 m_item_internal_list->cells = _itemsInternal();
415 break;
416 case IK_Face:
417 m_item_internal_list->faces = _itemsInternal();
418 break;
419 case IK_Edge:
420 m_item_internal_list->edges = _itemsInternal();
421 break;
422 case IK_Node:
423 m_item_internal_list->nodes = _itemsInternal();
424 break;
425 case IK_DoF:
426 case IK_Particle:
427 case IK_Unknown:
428 break;
429 }
430 }
431
432 void _updateEmptyConnectivity()
433 {
434 auto item_internal_connectivity_list = itemInternalConnectivityList();
435 for (auto item_kind = 0; item_kind < ItemInternalConnectivityList::MAX_ITEM_KIND; ++item_kind) {
436 item_internal_connectivity_list->_setConnectivityList(item_kind, m_empty_connectivity);
437 item_internal_connectivity_list->_setConnectivityIndex(item_kind, m_empty_connectivity_indexes);
438 item_internal_connectivity_list->_setConnectivityNbItem(item_kind, m_empty_connectivity_nb_item);
439 }
440 }
441
442 // IItemFamily
443 IDoFFamily* toDoFFamily() override
444 {
445 return this;
446 }
447 // todo block all IItemFamily allocation methods
448
449 void build() override
450 {
451 ItemFamily::build();
452 m_sub_domain_id = subDomain()->subDomainId();
453 ItemTypeMng* itm = m_mesh->itemTypeMng();
454 ItemTypeInfo* dof_type_info = itm->typeFromId(IT_NullType);
455 m_shared_info = _findSharedInfo(dof_type_info);
456 _updateEmptyConnectivity();
457 ItemFamily::setPolicyMng(new PolyhedralFamilyPolicyMng{ m_mesh, this });
458 }
459
460 void addGhostItems(Int64ConstArrayView unique_ids, Int32ArrayView items, Int32ConstArrayView owners) override
461 {
462 auto* polyhedral_mesh_modifier = m_mesh->_internalApi()->polyhedralMeshModifier();
463 ARCANE_CHECK_POINTER(polyhedral_mesh_modifier);
464 polyhedral_mesh_modifier->addItems(unique_ids, items, owners, ItemFamily::itemKind(), name());
465 }
466
467 // IDoFFamily
468 String name() const override { return ItemFamily::name(); }
469 String fullName() const override { return ItemFamily::fullName(); }
470 Integer nbItem() const override { return ItemFamily::nbItem(); }
471 ItemGroup allItems() const override { return ItemFamily::allItems(); }
472 void endUpdate() override
473 {
474 return ItemFamily::endUpdate();
475 }
476 IItemFamily* itemFamily() override { return this; }
477
478 DoFVectorView addDoFs(Int64ConstArrayView dof_uids, Int32ArrayView dof_lids) override
479 {
480 auto* polyhedral_mesh_modifier = m_mesh->_internalApi()->polyhedralMeshModifier();
481 ARCANE_CHECK_POINTER(polyhedral_mesh_modifier);
482 polyhedral_mesh_modifier->addItems(dof_uids, dof_lids, ItemFamily::itemKind(), name());
483 return ItemFamily::view(dof_lids);
484 }
485
486 DoFVectorView addGhostDoFs(Int64ConstArrayView dof_uids, Int32ArrayView dof_lids,
487 Int32ConstArrayView owners) override
488 {
489 addGhostItems(dof_uids, dof_lids, owners);
490 return ItemFamily::view(dof_lids);
491 }
492
493 void removeDoFs(Int32ConstArrayView items_local_id) override
494 {
495 auto* mesh_modifier = m_mesh->_internalApi()->polyhedralMeshModifier();
496 mesh_modifier->removeItems(items_local_id, ItemFamily::itemKind(), m_name);
497 }
498};
499
500} // namespace Arcane::mesh
501/*---------------------------------------------------------------------------*/
502/*---------------------------------------------------------------------------*/
503
504/*---------------------------------------------------------------------------*/
505/*---------------------------------------------------------------------------*/
506
507namespace Arcane
508{
509
510/*---------------------------------------------------------------------------*/
511/*---------------------------------------------------------------------------*/
512
513namespace mesh
514{
515
516 /*---------------------------------------------------------------------------*/
517 /*---------------------------------------------------------------------------*/
518
520 {
521 ISubDomain* m_subdomain;
522 Neo::Mesh m_mesh{ "Test" };
523
524 template <eItemKind IK>
525 class ItemKindTraits
526 {
527 static const Neo::ItemKind item_kind = Neo::ItemKind::IK_None;
528 };
529
530 public:
531
532 static Neo::ItemKind itemKindArcaneToNeo(eItemKind ik)
533 {
534 switch (ik) {
535 case IK_Cell:
536 return Neo::ItemKind::IK_Cell;
537 case IK_Face:
538 return Neo::ItemKind::IK_Face;
539 case IK_Edge:
540 return Neo::ItemKind::IK_Edge;
541 case IK_Node:
542 return Neo::ItemKind::IK_Node;
543 case IK_DoF:
544 return Neo::ItemKind::IK_Dof;
545 case IK_Unknown:
546 case IK_Particle:
547 return Neo::ItemKind::IK_None;
548 }
549 return Neo::ItemKind::IK_Node;
550 }
551
552 static eItemKind itemKindNeoToArcane(Neo::ItemKind ik)
553 {
554 switch (ik) {
555 case Neo::ItemKind::IK_Cell:
556 return IK_Cell;
557 case Neo::ItemKind::IK_Face:
558 return IK_Face;
559 case Neo::ItemKind::IK_Edge:
560 return IK_Edge;
561 case Neo::ItemKind::IK_Node:
562 return IK_Node;
563 case Neo::ItemKind::IK_Dof:
564 return IK_DoF;
565 case Neo::ItemKind::IK_None:
566 return IK_Unknown;
567 }
568 return IK_Node;
569 }
570
571 public:
572
573 explicit PolyhedralMeshImpl(ISubDomain* subDomain)
574 : m_subdomain(subDomain)
575 , m_mesh(String::format(subDomain->defaultMeshHandle().meshName(), "Polyhedral").localstr(), subDomain->parallelMng()->commRank())
576 {}
577
578 public:
579
580 String name() const { return m_mesh.name(); }
581
582 Integer dimension() const { return m_mesh.dimension(); }
583
584 Integer nbNode() const { return m_mesh.nbNodes(); }
585 Integer nbEdge() const { return m_mesh.nbEdges(); }
586 Integer nbFace() const { return m_mesh.nbFaces(); }
587 Integer nbCell() const { return m_mesh.nbCells(); }
588 Integer nbItem(eItemKind ik) const { return m_mesh.nbItems(itemKindArcaneToNeo(ik)); }
589
590 SmallSpan<const Neo::Mesh::Connectivity> connectivities(IItemFamily* source_family)
591 {
592 auto& neo_source_family = m_mesh.findFamily(itemKindArcaneToNeo(source_family->itemKind()), source_family->name().localstr());
593 auto connectivities = m_mesh.getConnectivities(neo_source_family);
594 return { connectivities.begin(), connectivities.size() };
595 }
596
597 static void _setFaceInfos(Int32 mod_flags, Face& face)
598 {
599 Int32 face_flags = face.itemBase().flags();
600 face_flags &= ~ItemFlags::II_InterfaceFlags;
601 face_flags |= mod_flags;
602 face.mutableItemBase().setFlags(face_flags);
603 }
604
605 /*---------------------------------------------------------------------------*/
606
607 void addFamily(eItemKind ik, const String& name)
608 {
609 m_mesh.addFamily(itemKindArcaneToNeo(ik), name.localstr());
610 }
611
612 /*---------------------------------------------------------------------------*/
613
614 void scheduleAddItems(PolyhedralFamily* arcane_item_family,
616 PolyhedralTools::ItemLocalIds& item_local_ids)
617 {
618 scheduleAddItems(arcane_item_family, uids, Int32ConstSmallSpan{}, item_local_ids);
619 }
620
621 /*---------------------------------------------------------------------------*/
622
623 void scheduleAddItems(PolyhedralFamily* arcane_item_family,
625 Int32ConstSmallSpan owners,
626 PolyhedralTools::ItemLocalIds& item_local_ids)
627 {
628 auto& added_items = item_local_ids.m_future_items;
629 auto& item_family = m_mesh.findFamily(itemKindArcaneToNeo(arcane_item_family->itemKind()),
630 arcane_item_family->name().localstr());
631 m_mesh.scheduleAddItems(item_family, std::vector<Int64>{ uids.begin(), uids.end() }, added_items);
632 // add arcane items
633 auto& mesh_graph = m_mesh.internalMeshGraph();
634 item_family.addMeshScalarProperty<Neo::utils::Int32>(PolyhedralFamily::m_arcane_item_lids_property_name.localstr());
635 // copy uids and owners to send them to Neo
636 UniqueArray<Int64> uids_copy(uids);
637 UniqueArray<Int32> owners_copy(owners);
638 mesh_graph.addAlgorithm(Neo::MeshKernel::InProperty{ item_family, item_family.lidPropName() },
639 Neo::MeshKernel::OutProperty{ item_family, PolyhedralFamily::m_arcane_item_lids_property_name.localstr() },
640 "AddArcaneItems"+std::string{arcane_item_family->name().localstr()},
641 [arcane_item_family, uids_local=std::move(uids_copy), &added_items, owners_local=std::move(owners_copy)]
642 ([[maybe_unused]] Neo::ItemLidsProperty const& lids_property,
643 Neo::MeshScalarPropertyT<Neo::utils::Int32>&) {
644 auto new_items_lids{added_items.new_items.localIds()};
645 Int32ConstSpan neo_items{ new_items_lids.data(), static_cast<Int32>(new_items_lids.size()) };
646 UniqueArray<Int32> arcane_items(added_items.new_items.size());
647 if (owners_local.empty())
648 arcane_item_family->addItems(uids_local, arcane_items);
649 else
650 arcane_item_family->addItems(uids_local, arcane_items, Int32ConstArrayView{ owners_local.size(), owners_local.data() });
651 // debug check lid matching.
652 if (!arcane_items.size() == added_items.new_items.size())
653 arcane_item_family->traceMng()->fatal() << "Inconsistent item lids generation between Arcane and Neo, nb items Neo "
654 << added_items.new_items.size() << " nb items Arcane " << arcane_items.size();
655 if (!std::equal(added_items.new_items.begin(), added_items.new_items.end(), arcane_items.begin())) {
656 arcane_item_family->traceMng()->info() << "Arcane Items " << arcane_items;
657 std::cout << "Neo Items ";
658 std::ranges::copy(neo_items,std::ostream_iterator<int>(std::cout," "));
659 std::cout << "\n";
660 arcane_item_family->traceMng()->fatal() << "Inconsistent item lids generation between Arcane and Neo in ItemFamily " << arcane_item_family->name();
661 }
662 });
663 }
664
665 /*---------------------------------------------------------------------------*/
666
667 void scheduleRemoveItems(PolyhedralFamily* arcane_item_family,
668 Int32ConstArrayView local_ids)
669 {
670 auto& item_family = m_mesh.findFamily(itemKindArcaneToNeo(arcane_item_family->itemKind()),
671 arcane_item_family->name().localstr());
672 Neo::ItemRange removed_items{ Neo::ItemLocalIds{ { local_ids.begin(), local_ids.end() }, 0, 0 } };
673 m_mesh.scheduleRemoveItems(item_family, removed_items);
674 // Remove Arcane items
675 auto& mesh_graph = m_mesh.internalMeshGraph();
676 item_family.addMeshScalarProperty<Neo::utils::Int32>(PolyhedralFamily::m_arcane_remove_item_property_name.localstr());
677 mesh_graph.addAlgorithm(Neo::MeshKernel::InProperty{ item_family, m_mesh._removeItemPropertyName(item_family) },
678 Neo::MeshKernel::OutProperty{ item_family, PolyhedralFamily::m_arcane_remove_item_property_name.localstr() },
679 "RemoveArcaneFamily"+std::string{arcane_item_family->name().localstr()},
680 [arcane_item_family, local_ids](Neo::MeshScalarPropertyT<Neo::utils::Int32> const&,
681 Neo::MeshScalarPropertyT<Neo::utils::Int32>&) {
682 arcane_item_family->removeItems(local_ids);
683 });
684 }
685
686 /*---------------------------------------------------------------------------*/
687
688 void scheduleAddConnectivity(PolyhedralFamily* arcane_source_item_family,
689 PolyhedralTools::ItemLocalIds& source_items,
690 Integer nb_connected_items_per_item,
691 PolyhedralFamily* arcane_target_item_family,
692 Int64ConstArrayView target_items_uids,
693 String const& name)
694 {
695 // add connectivity in Neo
696 _scheduleAddConnectivity(arcane_source_item_family,
697 source_items,
698 nb_connected_items_per_item,
699 arcane_target_item_family,
700 target_items_uids,
701 name);
702 }
703
704 /*---------------------------------------------------------------------------*/
705
706 void scheduleAddConnectivity(PolyhedralFamily* arcane_source_item_family,
707 PolyhedralTools::ItemLocalIds& source_items,
708 Int32ConstSmallSpan nb_connected_items_per_item,
709 PolyhedralFamily* arcane_target_item_family,
710 Int64ConstSmallSpan target_items_uids,
711 String const& connectivity_name)
712 {
713 _scheduleAddConnectivity(arcane_source_item_family,
714 source_items,
715 std::vector<Int32>{ nb_connected_items_per_item.begin(), nb_connected_items_per_item.end() },
716 arcane_target_item_family,
717 target_items_uids,
718 connectivity_name);
719 }
720
721 /*---------------------------------------------------------------------------*/
722 /*---------------------------------------------------------------------------*/
723
724 void scheduleUpdateConnectivity(PolyhedralFamily* arcane_source_item_family,
725 PolyhedralTools::ItemLocalIds& source_items,
726 Integer nb_connected_items_per_item,
727 PolyhedralFamily* arcane_target_item_family,
728 Int64ConstArrayView target_items_uids,
729 String const& name)
730 {
731 // add connectivity in Neo
732 _scheduleAddConnectivity(arcane_source_item_family,
733 source_items,
734 nb_connected_items_per_item,
735 arcane_target_item_family,
736 target_items_uids,
737 name,
738 Neo::Mesh::ConnectivityOperation::Modify);
739 }
740
741 /*---------------------------------------------------------------------------*/
742
743 void scheduleUpdateConnectivity(PolyhedralFamily* arcane_source_item_family,
744 PolyhedralTools::ItemLocalIds& source_items,
745 Int32ConstSmallSpan nb_connected_items_per_item,
746 PolyhedralFamily* arcane_target_item_family,
747 Int64ConstSmallSpan target_items_uids,
748 String const& connectivity_name)
749 {
750 _scheduleAddConnectivity(arcane_source_item_family,
751 source_items,
752 std::vector<Int32>{ nb_connected_items_per_item.begin(), nb_connected_items_per_item.end() },
753 arcane_target_item_family,
754 target_items_uids,
755 connectivity_name,
756 Neo::Mesh::ConnectivityOperation::Modify);
757 }
758
759 /*---------------------------------------------------------------------------*/
760
761 // template to handle nb_items_per_item type (an int or an array)
762 template <typename ConnectivitySizeType>
763 void _scheduleAddConnectivity(PolyhedralFamily* arcane_source_item_family,
764 PolyhedralTools::ItemLocalIds& source_items,
765 ConnectivitySizeType&& nb_connected_items_per_item,
766 PolyhedralFamily* arcane_target_item_family,
767 Int64ConstSmallSpan target_item_uids,
768 String const& connectivity_name,
769 Neo::Mesh::ConnectivityOperation operation = Neo::Mesh::ConnectivityOperation::Add)
770 {
771 // add connectivity in Neo
772 auto& source_family = m_mesh.findFamily(itemKindArcaneToNeo(arcane_source_item_family->itemKind()),
773 arcane_source_item_family->name().localstr());
774 auto& target_family = m_mesh.findFamily(itemKindArcaneToNeo(arcane_target_item_family->itemKind()),
775 arcane_target_item_family->name().localstr());
776 // Copy data to send them to Neo
777 UniqueArray<Int64> target_item_uids_copy(target_item_uids);
778 // Remove connectivities with a null item
779 std::vector<Int64> target_item_uids_filtered;
780 target_item_uids_filtered.reserve(target_item_uids.size());
781 std::copy_if(target_item_uids.begin(),
782 target_item_uids.end(),
783 std::back_inserter(target_item_uids_filtered),
784 [](auto uid) { return uid != NULL_ITEM_UNIQUE_ID; });
785 // Add connectivity in Neo (async)
786 m_mesh.scheduleAddConnectivity(source_family, source_items.m_future_items, target_family,
787 std::forward<ConnectivitySizeType>(nb_connected_items_per_item),
788 std::move(target_item_uids_filtered),
789 connectivity_name.localstr(),
790 operation);
791 // Register Neo connectivities in Arcane
792 auto& mesh_graph = m_mesh.internalMeshGraph();
793 std::string connectivity_add_output_property_name = std::string{ "EndOf" } + connectivity_name.localstr() + "Add";
794 source_family.addScalarProperty<Neo::utils::Int32>(connectivity_add_output_property_name);
795 // todo is operation == Modify, the update algo should not be needed. To check
796 mesh_graph.addAlgorithm(Neo::MeshKernel::InProperty{ source_family, connectivity_name.localstr() },
797 Neo::MeshKernel::OutProperty{ source_family, connectivity_add_output_property_name },
798 "UpdateArcaneConnectivity"+std::string{connectivity_name.localstr()},
799 [arcane_source_item_family, arcane_target_item_family, &source_family, &target_family, this]
800 (Neo::Mesh::ConnectivityPropertyType const& neo_connectivity,
801 Neo::ScalarPropertyT<Neo::utils::Int32>&) {
802 auto rank = arcane_source_item_family->mesh()->parallelMng()->commRank();
803 Neo::printer(rank) << "==Algorithm update Arcane connectivity: "<< neo_connectivity.name() << Neo::endline;
804 auto item_internal_connectivity_list = arcane_source_item_family->itemInternalConnectivityList();
805 // todo check if families are default families
806 auto connectivity = m_mesh.getConnectivity(source_family, target_family, neo_connectivity.name());
807 // to access connectivity data (for initializing Arcane connectivities) create a proxy on Neo connectivity
808 auto& connectivity_values = source_family.getConcreteProperty<Neo::Mesh::ConnectivityPropertyType>(neo_connectivity.name());
809 Neo::MeshArrayPropertyProxyT<Neo::Mesh::ConnectivityPropertyType::PropertyDataType> connectivity_proxy{ connectivity_values };
810 auto nb_item_data = connectivity_proxy.arrayPropertySizes();
811 auto nb_item_size = connectivity_proxy.arrayPropertySizesSize();
812 item_internal_connectivity_list->_setConnectivityNbItem(arcane_target_item_family->itemKind(),
813 Int32ArrayView{ Integer(nb_item_size), nb_item_data });
814 auto max_nb_connected_items = connectivity.maxNbConnectedItems();
815 item_internal_connectivity_list->_setMaxNbConnectedItem(arcane_target_item_family->itemKind(), max_nb_connected_items);
816 auto connectivity_values_data = connectivity_proxy.arrayPropertyData();
817 auto connectivity_values_size = connectivity_proxy.arrayPropertyDataSize();
818 item_internal_connectivity_list->_setConnectivityList(arcane_target_item_family->itemKind(),
819 Int32ArrayView{ Integer(connectivity_values_size), connectivity_values_data });
820 auto connectivity_index_data = connectivity_proxy.arrayPropertyIndex();
821 auto connectivity_index_size = connectivity_proxy.arrayPropertyIndexSize();
822 item_internal_connectivity_list->_setConnectivityIndex(arcane_target_item_family->itemKind(),
823 Int32ArrayView{ Integer(connectivity_index_size), connectivity_index_data }); }, Neo::MeshKernel::AlgorithmPropertyGraph::AlgorithmPersistence::KeepAfterExecution);
824 // If FaceToCellConnectivity Add face flags II_Boundary, II_SubdomainBoundary, II_HasFrontCell, II_HasBackCell
825 if (arcane_source_item_family->itemKind() == IK_Face && arcane_target_item_family->itemKind() == IK_Cell) {
826 std::string flag_definition_output_property_name{ "EndOfFlagDefinition" };
827 source_family.addScalarProperty<Neo::utils::Int32>(flag_definition_output_property_name);
828 // update Face flags after connectivity add
829 mesh_graph.addAlgorithm(Neo::MeshKernel::InProperty{ source_family, connectivity_add_output_property_name }, Neo::MeshKernel::OutProperty{ source_family, flag_definition_output_property_name },
830 "UpdateFaceFlagsAfterConnectivityDefinition",
831 [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&) {
832 auto current_face_index = 0;
833 auto arcane_faces = arcane_source_item_family->itemInfoListView();
834 Int32UniqueArray target_item_lids(target_item_uids_local.size());
835 arcane_target_item_family->itemsUniqueIdToLocalId(target_item_lids, target_item_uids_local, false);
836 for (auto face_lid : source_items.m_future_items.new_items) {
837 Face current_face = arcane_faces[face_lid].toFace();
838 if (target_item_lids[2 * current_face_index + 1] == NULL_ITEM_LOCAL_ID) {
839 // Only back cell or none
840 Int32 mod_flags = (target_item_lids[2 * current_face_index] != NULL_ITEM_LOCAL_ID) ? (ItemFlags::II_Boundary | ItemFlags::II_HasBackCell | ItemFlags::II_BackCellIsFirst) : 0;
841 _setFaceInfos(mod_flags, current_face);
842 }
843 else if (target_item_lids[2 * current_face_index] == NULL_ITEM_LOCAL_ID) {
844 // Only front cell or none
846 }
847 else {
848 // Both back and front cells
850 }
851 ++current_face_index;
852 }
853 });
854 // Add an algorithm to update Face flags when a connected cell is removed
855 auto const isolated_items_property_name = m_mesh._isolatedItemLidsPropertyName(source_family,target_family);
856 std::string const flag_update_output_property_name{ "EndOfFlagUpdate" };
857 source_family.addScalarProperty<Neo::utils::Int32>(flag_update_output_property_name);
858
859 mesh_graph.addAlgorithm(Neo::MeshKernel::InProperty{ source_family, isolated_items_property_name },
860 Neo::MeshKernel::OutProperty{ source_family, flag_update_output_property_name },
861 "UpdateFaceFlagsAfterCellRemoval",
862 [arcane_source_item_family,&source_family,connectivity_name](Neo::MeshScalarPropertyT<Neo::utils::Int32> const&, Neo::ScalarPropertyT<Neo::utils::Int32> const&) {
863 auto const rank = arcane_source_item_family->mesh()->parallelMng()->commRank();
864 Neo::printer(rank) << "==Algorithm update Face flags after cell removal" << Neo::endline;
865 // todo should be an input property
866 auto const removed_target_item_index_prop_name = Neo::Mesh::removedTargetItemIndexfilteredItemPropertyName(connectivity_name.localstr());
867 auto& null_item_connected = source_family.getConcreteProperty<Neo::MeshArrayPropertyT<Neo::utils::Int32>>(removed_target_item_index_prop_name);
868 null_item_connected.debugPrint(rank);
869 ENUMERATE_(Face,iface,arcane_source_item_family->allItems())
870 {
871 Face current_face = *iface;
872 auto null_items_connected_to_face = null_item_connected[iface.localId()];
873 if (null_items_connected_to_face.size() > 2)
874 {
875 ARCANE_FATAL("More than one null item connected to face {0}",iface.localId());
876 }
877 // If no cell removed nothing to do
878 if (null_items_connected_to_face.size() == 0)
879 continue;
880 // If only one cell, check if back or front remains
881 // front cell remains
882 if (null_items_connected_to_face[0] == 0)
883 {
886 }
887 else if (null_items_connected_to_face[0] == 1)
888 {
891 }
892 }
893
894 },
895 Neo::MeshKernel::AlgorithmPropertyGraph::AlgorithmPersistence::KeepAfterExecution
896 );
897 }
898 // Add an algorithm to remove items isolated after a connectivity update. Add it only once, when connectivity is added
899 if (operation == Neo::Mesh::ConnectivityOperation::Modify)
900 return;
901 auto isolated_item_property_name = m_mesh._isolatedItemLidsPropertyName(source_family, target_family);
902 auto end_of_isolated_removal_property_name = std::string{ "EndOf" } + isolated_item_property_name;
903 source_family.addScalarProperty<Neo::utils::Int32>(end_of_isolated_removal_property_name);
904 mesh_graph.addAlgorithm(Neo::MeshKernel::InProperty{ source_family, isolated_item_property_name },
905 Neo::MeshKernel::OutProperty{ source_family, end_of_isolated_removal_property_name },
906 "RemoveIsolatedArcaneItemsIn"+std::string{ arcane_source_item_family->name().localstr() },
907 [arcane_source_item_family](Neo::MeshScalarPropertyT<Neo::utils::Int32> const& isolated_items_lids_property,
908 Neo::ScalarPropertyT<Neo::utils::Int32>& end_of_isolated_removal_property) {
909 end_of_isolated_removal_property.set(1);
910 // remove Arcane items
911 Int32UniqueArray isolated_item_lids;
912 isolated_item_lids.reserve(isolated_items_lids_property.size());
913 ENUMERATE_(Item,iitem,arcane_source_item_family->allItems()) {
914 if (isolated_items_lids_property[iitem->localId()] == 1) {
915 isolated_item_lids.push_back(iitem->localId());
916 }
917 }
918 std::sort(isolated_item_lids.begin(), isolated_item_lids.end());
919 arcane_source_item_family->traceMng()->info() << "Remove isolated in Arcane for family "
920 << arcane_source_item_family->name() << " lids : " << isolated_item_lids;
921 isolated_items_lids_property.debugPrint();
922 arcane_source_item_family->removeItems(isolated_item_lids);
923 }, Neo::MeshKernel::AlgorithmPropertyGraph::AlgorithmPersistence::KeepAfterExecution);
924 }
925
926 /*---------------------------------------------------------------------------*/
927
928 void scheduleSetItemCoordinates(PolyhedralFamily* item_family, PolyhedralTools::ItemLocalIds& local_ids, Real3ConstSmallSpan item_coords, VariableItemReal3& arcane_coords)
929 {
930 auto& _item_family = m_mesh.findFamily(itemKindArcaneToNeo(item_family->itemKind()), item_family->name().localstr());
931 std::vector<Neo::utils::Real3> _node_coords(item_coords.size());
932 auto node_index = 0;
933 for (auto&& node_coord : item_coords) {
934 _node_coords[node_index++] = Neo::utils::Real3{ node_coord.x, node_coord.y, node_coord.z };
935 }
936 m_mesh.scheduleSetItemCoords(_item_family, local_ids.m_future_items, _node_coords);
937 // Fill Arcane Variable
938 auto& mesh_graph = m_mesh.internalMeshGraph();
939 _item_family.addScalarProperty<Int32>("NoOutProperty42"); // todo remove : create noOutput algo in Neo
940 mesh_graph.addAlgorithm(Neo::MeshKernel::InProperty{ _item_family, m_mesh._itemCoordPropertyName(_item_family) },
941 Neo::MeshKernel::OutProperty{ _item_family, "NoOutProperty42" },
942 "UpdateArcaneCoordsIn"+std::string{item_family->name().localstr()},
943 [this, item_family, &_item_family, &arcane_coords](Neo::Mesh::CoordPropertyType const& item_coords_property,
944 Neo::ScalarPropertyT<Neo::utils::Int32>&) {
945 // enumerate nodes : ensure again Arcane/Neo local_ids are identicals
946 auto& all_items = _item_family.all();
947 VariableNodeReal3 node_coords{ VariableBuildInfo{ item_family->mesh(), "NodeCoord" } };
948 for (auto item : all_items) {
949 arcane_coords[ItemLocalId{ item }] = { item_coords_property[item].x,
950 item_coords_property[item].y,
951 item_coords_property[item].z };
952 }
953 });
954 }
955
956 /*---------------------------------------------------------------------------*/
957
958 Neo::EndOfMeshUpdate applyScheduledOperations() noexcept
959 {
960 return m_mesh.applyScheduledOperations();
961 }
962 };
963
964 template <> class PolyhedralMeshImpl::ItemKindTraits<IK_Cell>
965 {
966 static const Neo::ItemKind item_kind = Neo::ItemKind::IK_Cell;
967 };
968 template <> class PolyhedralMeshImpl::ItemKindTraits<IK_Face>
969 {
970 static const Neo::ItemKind item_kind = Neo::ItemKind::IK_Face;
971 };
972 template <> class PolyhedralMeshImpl::ItemKindTraits<IK_Edge>
973 {
974 static const Neo::ItemKind item_kind = Neo::ItemKind::IK_Edge;
975 };
976 template <> class PolyhedralMeshImpl::ItemKindTraits<IK_Node>
977 {
978 static const Neo::ItemKind item_kind = Neo::ItemKind::IK_Node;
979 };
980 template <> class PolyhedralMeshImpl::ItemKindTraits<IK_DoF>
981 {
982 static const Neo::ItemKind item_kind = Neo::ItemKind::IK_Dof;
983 };
984
985 /*---------------------------------------------------------------------------*/
986
987 void PolyhedralFamilySerializer::serializeItems(ISerializer* buf, Int32ConstArrayView items_local_ids)
988 {
989 ARCANE_CHECK_POINTER(m_family);
991
992 switch (buf->mode()) {
993 case ISerializer::ModeReserve: {
994 _fillItemData(items_local_ids);
995 m_item_data.serialize(buf);
996 auto connectivities = m_mesh->_impl()->connectivities(m_family);
997 for (auto out_connectivity : connectivities) {
998 buf->reserve(out_connectivity.target_family.name());
999 buf->reserve(out_connectivity.name);
1000 }
1001 break;
1002 }
1003 case ISerializer::ModePut: {
1004 m_item_data.serialize(buf);
1005 auto connectivities = m_mesh->_impl()->connectivities(m_family);
1006 for (auto out_connectivity : connectivities) {
1007 buf->put(out_connectivity.target_family.name());
1008 buf->put(out_connectivity.name);
1009 }
1010 clear();
1011 break;
1012 }
1013 case ISerializer::ModeGet: {
1014 deserializeItems(buf, nullptr);
1015 break;
1016 }
1017 }
1018 }
1019
1020 /*---------------------------------------------------------------------------*/
1021
1022 void PolyhedralFamilySerializer::deserializeItems(ISerializer* buf, Int32Array* items_local_ids)
1023 {
1024 ARCANE_ASSERT((buf->mode() == ISerializer::ModeGet),
1025 ("Impossible to deserialize a buffer not in ModeGet. In ItemData::deserialize.Exiting"))
1026 ARCANE_CHECK_POINTER(m_mesh);
1027 ARCANE_CHECK_POINTER(m_family);
1028 ARCANE_CHECK_POINTER(m_mng);
1029 ItemData item_data;
1030 if (items_local_ids)
1031 item_data.deserialize(buf, m_mesh, *items_local_ids);
1032 else
1033 item_data.deserialize(buf, m_mesh);
1034 auto connectivities = m_mesh->_impl()->connectivities(m_family);
1035 auto nb_connectivities = connectivities.size();
1036 StringUniqueArray connected_family_names(nb_connectivities);
1037 StringUniqueArray connectivity_names(nb_connectivities);
1038 auto index = 0;
1039 for (auto out_connectivity : connectivities) {
1040 buf->get(connected_family_names[index]);
1041 buf->get(connectivity_names[index]);
1042 ++index;
1043 }
1044 _fillItemFamilyInfo(item_data, connected_family_names, connectivity_names);
1045
1046 if (items_local_ids) {
1047 m_deserialized_lids_array.push_back(items_local_ids);
1048 // and that's all, they will be filled in finalizeItemAllocation
1049 }
1050 m_future_item_lids_array.push_back(std::make_shared<PolyhedralTools::ItemLocalIds>());
1051 m_mesh->scheduleAllocateItems(m_family_info, *m_future_item_lids_array.back().get());
1052
1053 // Add serializer in mng. Update is triggered when finalizeItemAllocation is called
1054 m_mng->addSerializer(this);
1055 }
1056
1057 /*---------------------------------------------------------------------------*/
1058 void PolyhedralFamilySerializer::_fillItemData(Int32ConstArrayView items_local_ids)
1059 {
1060 m_item_data = ItemData{ items_local_ids.size(), 0, m_family, nullptr, m_family->parallelMng()->commRank() };
1061 Int64Array& item_infos = m_item_data.itemInfos();
1062 Int32ArrayView item_owners = m_item_data.itemOwners();
1063 // Reserve size
1064 const Integer nb_item = items_local_ids.size();
1065 item_infos.reserve(1 + nb_item * 32); // Size evaluation for hexa cell (the more data to store) : 1_family_info + nb_item *(2_info_per_family + 6 (faces) + 12 (edges) + 8 (vertices) connected elements) = 1 + nb_item *(6 + 6 + 12 +8)
1066 // Fill item data (cf ItemData.h)
1067 PolyhedralMeshImpl* mesh_impl = m_mesh->_impl();
1068 auto connectivities = mesh_impl->connectivities(m_family);
1069 item_infos.add(connectivities.size());
1070 bool is_face_family = m_family->itemKind() == IK_Face;
1071 ENUMERATE_ITEM (item, m_family->view(items_local_ids)) {
1072 item_infos.add(42); // Item type, not used for polyhedral mesh
1073 item_infos.add(item->uniqueId().asInt64());
1074 item_owners[item.index()] = item->owner();
1075 for (auto out_connectivity : connectivities) {
1076 auto target_family = m_mesh->findItemFamily(PolyhedralMeshImpl::itemKindNeoToArcane(out_connectivity.target_family.itemKind()),
1077 out_connectivity.target_family.name(), false, false);
1078 // auto arcane_connected_items = target_family->view();
1079 auto arcane_connected_items = target_family->itemInfoListView();
1080 bool is_face_cell_connection = is_face_family && target_family->itemKind() == IK_Cell;
1081 item_infos.add(PolyhedralMeshImpl::itemKindNeoToArcane(out_connectivity.target_family.itemKind()));
1082 auto connected_items = out_connectivity[item.localId()];
1083 auto nb_connected_items = connected_items.size();
1084 item_infos.add(nb_connected_items);
1085 if (is_face_cell_connection && item->itemBase().isBoundary() && item->itemBase().backCell().isNull()) {
1086 item_infos.add(NULL_ITEM_UNIQUE_ID);
1087 }
1088 for (auto connected_item_lid : connected_items) {
1089 item_infos.add(arcane_connected_items[connected_item_lid].uniqueId().asInt64());
1090 }
1091 if (is_face_cell_connection && item->itemBase().isBoundary() && !item->itemBase().backCell().isNull()) {
1092 item_infos.add(NULL_ITEM_UNIQUE_ID);
1093 }
1094 }
1095 }
1096 }
1097
1098} // End namespace mesh
1099
1100/*---------------------------------------------------------------------------*/
1101/*---------------------------------------------------------------------------*/
1102
1103class mesh::PolyhedralMesh::PolyhedralMeshModifier
1105{
1106 public:
1107
1108 explicit PolyhedralMeshModifier(PolyhedralMesh* mesh)
1109 : m_mesh(mesh)
1110 {}
1111
1112 void addItems(Int64ConstArrayView unique_ids, Int32ArrayView local_ids, eItemKind ik, const String& family_name) override
1113 {
1114 m_mesh->addItems(unique_ids, local_ids, ik, family_name);
1115 }
1116
1117 void addItems(Int64ConstArrayView unique_ids, Int32ArrayView local_ids, Int32ConstArrayView owners, eItemKind ik, const String& family_name) override
1118 {
1119 m_mesh->addItems(unique_ids, local_ids, owners, ik, family_name);
1120 }
1121
1122 void removeItems(Int32ConstArrayView local_ids, eItemKind ik, const String& family_name) override
1123 {
1124 m_mesh->removeItems(local_ids, ik, family_name);
1125 }
1126
1127 private:
1128
1129 PolyhedralMesh* m_mesh;
1130};
1131
1132/*---------------------------------------------------------------------------*/
1133/*---------------------------------------------------------------------------*/
1134
1135class mesh::PolyhedralMesh::InternalApi
1136: public IMeshInternal
1137, public IMeshModifierInternal
1138{
1139 public:
1140
1141 explicit InternalApi(PolyhedralMesh* mesh)
1142 : m_mesh(mesh)
1143 , m_connectivity_mng(std::make_unique<ItemConnectivityMng>(mesh->traceMng()))
1144 , m_polyhedral_mesh_modifier(std::make_unique<PolyhedralMeshModifier>(mesh))
1145 {}
1146
1147 public:
1148
1149 void setMeshKind(const MeshKind& v) override
1150 {
1151 if (v.meshStructure() != eMeshStructure::Polyhedral && v.meshAMRKind() != eMeshAMRKind::None) {
1152 ARCANE_FATAL("Incompatible mesh structure ({0}) and amr kind ({1}) for Polyhedral mesh {2}. Must be (Polyhedral,None). ",
1153 v.meshStructure(), v.meshAMRKind(), m_mesh->name());
1154 }
1155 m_mesh->m_mesh_kind = v;
1156 }
1157
1158 IItemConnectivityMng* dofConnectivityMng() const noexcept override
1159 {
1160 return m_connectivity_mng.get();
1161 }
1162
1163 IPolyhedralMeshModifier* polyhedralMeshModifier() const noexcept override
1164 {
1165 return m_polyhedral_mesh_modifier.get();
1166 }
1167
1168 void removeNeedRemoveMarkedItems() override
1169 {
1170 m_mesh->removeNeedRemoveMarkedItems();
1171 }
1172 NodeLocalId addNode([[maybe_unused]] ItemUniqueId unique_id) override
1173 {
1174 ARCANE_THROW(NotImplementedException, "");
1175 }
1176 FaceLocalId addFace([[maybe_unused]] ItemUniqueId unique_id,
1177 [[maybe_unused]] ItemTypeId type_id,
1178 [[maybe_unused]] ConstArrayView<Int64> nodes_uid) override
1179 {
1180 ARCANE_THROW(NotImplementedException, "");
1181 }
1182 CellLocalId addCell([[maybe_unused]] ItemUniqueId unique_id,
1183 [[maybe_unused]] ItemTypeId type_id,
1184 [[maybe_unused]] ConstArrayView<Int64> nodes_uid) override
1185 {
1186 ARCANE_THROW(NotImplementedException, "");
1187 }
1188
1189 IItemFamilySerializerMngInternal* familySerializerMng() const noexcept override
1190 {
1191 return m_mesh->polyhedralFamilySerializerMng();
1192 }
1193
1194 private:
1195
1196 PolyhedralMesh* m_mesh = nullptr;
1197 std::unique_ptr<IItemConnectivityMng> m_connectivity_mng = nullptr;
1198 std::unique_ptr<IPolyhedralMeshModifier> m_polyhedral_mesh_modifier = nullptr;
1199};
1200
1201/*---------------------------------------------------------------------------*/
1202/*---------------------------------------------------------------------------*/
1203
1204class mesh::PolyhedralMesh::NoCompactionMeshCompacter
1205: public IMeshCompacter
1206{
1207 public:
1208
1209 explicit NoCompactionMeshCompacter(PolyhedralMesh* mesh)
1210 : m_mesh(mesh)
1211 , m_trace_mng(mesh->traceMng())
1212 {}
1213
1214 void doAllActions() override { _info(); };
1215
1216 void beginCompact() override { _info(); };
1217 void compactVariablesAndGroups() override { _info(); };
1218 void updateInternalReferences() override { _info(); };
1219 void endCompact() override { _info(); };
1220 void finalizeCompact() override { _info(); };
1221
1222 IMesh* mesh() const override { return m_mesh; };
1223
1224 const ItemFamilyCompactInfos* findCompactInfos(IItemFamily*) const override
1225 {
1226 _info();
1227 return nullptr;
1228 }
1229
1230 ePhase phase() const override
1231 {
1232 _info();
1233 return ePhase::Ended;
1234 }
1235
1236 void setSorted(bool) override { _info(); };
1237
1238 bool isSorted() const override
1239 {
1240 _info();
1241 return false;
1242 };
1243
1244 ItemFamilyCollection families() const override
1245 {
1246 _info();
1247 return ItemFamilyCollection{};
1248 };
1249
1250 void _setCompactVariablesAndGroups(bool) override { _info(); };
1251
1252 private:
1253
1254 PolyhedralMesh* m_mesh = nullptr;
1255 ITraceMng* m_trace_mng = nullptr;
1256
1257 void _info() const { m_trace_mng->info() << A_FUNCINFO << "No compacting in PolyhedralMesh"; }
1258};
1259
1260/*---------------------------------------------------------------------------*/
1261/*---------------------------------------------------------------------------*/
1262
1263class mesh::PolyhedralMesh::NoCompactionMeshCompactMng
1264: public IMeshCompactMng
1265{
1266 public:
1267
1268 explicit NoCompactionMeshCompactMng(PolyhedralMesh* mesh)
1269 : m_mesh(mesh)
1270 , m_trace_mng(mesh->traceMng())
1271 , m_mesh_compacter{ std::make_unique<NoCompactionMeshCompacter>(m_mesh) }
1272 {}
1273
1274 IMesh* mesh() const override { return m_mesh; }
1275 IMeshCompacter* beginCompact() override
1276 {
1277 _info();
1278 return m_mesh_compacter.get();
1279 }
1280
1281 IMeshCompacter* beginCompact(IItemFamily* family) override
1282 {
1283 ARCANE_UNUSED(family);
1284 _info();
1285 return m_mesh_compacter.get();
1286 };
1287
1288 void endCompact() override { _info(); };
1289
1290 IMeshCompacter* compacter() override
1291 {
1292 _info();
1293 return m_mesh_compacter.get();
1294 };
1295
1296 private:
1297
1298 PolyhedralMesh* m_mesh = nullptr;
1299 ITraceMng* m_trace_mng = nullptr;
1300 std::unique_ptr<IMeshCompacter> m_mesh_compacter = nullptr;
1301
1302 void _info() const { m_trace_mng->info() << A_FUNCINFO << "No compacting in PolyhedralMesh"; }
1303};
1304
1305/*---------------------------------------------------------------------------*/
1306/*---------------------------------------------------------------------------*/
1307
1308mesh::PolyhedralMesh::
1309~PolyhedralMesh()
1310{
1311 m_mesh_handle._setMesh(nullptr);
1312}
1313
1314/*---------------------------------------------------------------------------*/
1315/*---------------------------------------------------------------------------*/
1316
1317ITraceMng* mesh::PolyhedralMesh::
1318traceMng()
1319{
1320 return m_subdomain->traceMng();
1321}
1322
1323/*---------------------------------------------------------------------------*/
1324/*---------------------------------------------------------------------------*/
1325
1326MeshHandle mesh::PolyhedralMesh::
1327handle() const
1328{
1329 return m_mesh_handle;
1330}
1331
1332/*---------------------------------------------------------------------------*/
1333/*---------------------------------------------------------------------------*/
1334mesh::PolyhedralMesh::
1335PolyhedralMesh(ISubDomain* subdomain, const MeshBuildInfo& mbi)
1336: EmptyMesh{ subdomain->traceMng() }
1337, m_name{ mbi.name() }
1338, m_subdomain{ subdomain }
1339, m_mesh_handle{ m_subdomain->defaultMeshHandle() }
1340, m_properties(std::make_unique<Properties>(subdomain->propertyMng(), String("ArcaneMeshProperties_") + m_name))
1341, m_mesh{ std::make_unique<mesh::PolyhedralMeshImpl>(m_subdomain) }
1342, m_parallel_mng{ mbi.parallelMngRef().get() }
1343, m_mesh_part_info{ makeMeshPartInfoFromParallelMng(m_parallel_mng) }
1344, m_item_type_mng(ItemTypeMng::_singleton())
1345, m_mesh_kind(mbi.meshKind())
1346, m_polyhedral_family_serializer_mng{ std::make_unique<PolyhedralFamilySerializerMng>(this) }
1347, m_initial_allocator(*this)
1348, m_variable_mng{ subdomain->variableMng() }
1349, m_mesh_checker{ this }
1350, m_internal_api{ std::make_unique<InternalApi>(this) }
1351, m_compact_mng{ std::make_unique<NoCompactionMeshCompactMng>(this) }
1352, m_mesh_utilities{ std::make_unique<UnstructuredMeshUtilities>(this) }
1353, m_mesh_exchange_mng{ std::make_unique<MeshExchangeMng>(this) }
1354, m_item_family_network{ std::make_unique<ItemFamilyNetwork>(m_trace_mng) }
1355, m_ghost_layer_mng{ std::make_unique<GhostLayerMng>(m_trace_mng) }
1356, m_connectivity(VariableBuildInfo{ subdomain, mbi.name() + "MeshConnectivity" })
1357{
1358 m_mesh_handle._setMesh(this);
1359 m_mesh_item_internal_list.mesh = this;
1360 m_default_arcane_families.fill(nullptr);
1361}
1362
1363/*---------------------------------------------------------------------------*/
1364/*---------------------------------------------------------------------------*/
1365
1366void Arcane::mesh::PolyhedralMesh::
1367allocateItems(const Arcane::ItemAllocationInfo& item_allocation_info)
1368{
1369 _allocateItems(item_allocation_info, ArrayView<Int32UniqueArray>{});
1370}
1371
1372/*---------------------------------------------------------------------------*/
1373
1374void Arcane::mesh::PolyhedralMesh::
1375allocateItems(const Arcane::ItemAllocationInfo& item_allocation_info, ArrayView<Int32UniqueArray> family_lids)
1376{
1377 _allocateItems(item_allocation_info, family_lids);
1378}
1379
1380/*---------------------------------------------------------------------------*/
1381
1382void Arcane::mesh::PolyhedralMesh::
1383_allocateItems(const Arcane::ItemAllocationInfo& item_allocation_info, ArrayView<Int32UniqueArray> family_lids)
1384{
1385 // Second step read a vtk polyhedral mesh
1386 m_subdomain->traceMng()->info() << "--PolyhedralMesh: allocate items --";
1387 UniqueArray<PolyhedralTools::ItemLocalIds> item_local_ids(item_allocation_info.family_infos.size());
1388 auto family_index = 0;
1389 // Prepare item creation
1390 for (auto& family_info : item_allocation_info.family_infos) {
1391 bool create_if_needed = true;
1392 auto* item_family = _findItemFamily(family_info.item_kind, family_info.name, create_if_needed);
1393 m_trace_mng->debug(Trace::High) << "- Create items " << family_info.name;
1394 m_mesh->scheduleAddItems(item_family, family_info.item_uids, family_info.item_owners.constSmallSpan(), item_local_ids[family_index++]);
1395 }
1396 // Prepare connectivity creation
1397 family_index = 0;
1398 for (auto& family_info : item_allocation_info.family_infos) {
1399 auto* item_family = _findItemFamily(family_info.item_kind, family_info.name);
1400 m_trace_mng->debug(Trace::High) << "- Current family " << family_info.name;
1401 for (auto& current_connected_family_info : family_info.connected_family_infos) {
1402 auto connected_family = _findItemFamily(current_connected_family_info.item_kind, current_connected_family_info.name);
1403 m_trace_mng->debug(Trace::High) << "- Create connectivity " << current_connected_family_info.connectivity_name;
1404 // check if connected family exists
1405 if (!connected_family) {
1406 ARCANE_WARNING((String::format("Cannot find family {0} with kind {1} "
1407 "The connectivity between {1} and this family is skipped",
1408 current_connected_family_info.name,
1409 current_connected_family_info.item_kind,
1410 item_family->name())
1411 .localstr()));
1412 continue;
1413 }
1414 m_mesh->scheduleAddConnectivity(item_family,
1415 item_local_ids[family_index],
1416 current_connected_family_info.nb_connected_items_per_item,
1417 connected_family,
1418 current_connected_family_info.connected_items_uids,
1419 current_connected_family_info.connectivity_name);
1420 Connectivity connectivity{ m_connectivity };
1421 connectivity.enableConnectivity(Connectivity::kindsToConnectivity(item_family->itemKind(), connected_family->itemKind()));
1422 }
1423 ++family_index;
1424 }
1425 // Create items and connectivities
1426 m_mesh->applyScheduledOperations();
1427 // Create variable for coordinates. This has to be done before call to family::endUpdate. Todo add to the graph
1428 for (auto& family_info : item_allocation_info.family_infos) {
1429 if (family_info.item_kind != IK_Node && family_info.item_coordinates.empty()) { // variable is created for node even if no coords (parallel)
1430 continue;
1431 }
1432 auto* item_family = _findItemFamily(family_info.item_kind, family_info.name);
1433 if (item_family == itemFamily(IK_Node)) { // create mesh node coords if doesn't exist
1434 if (!m_arcane_node_coords.get()) {
1435 m_arcane_node_coords = std::make_unique<VariableNodeReal3>(VariableBuildInfo(this, family_info.item_coordinates_variable_name));
1436 m_arcane_node_coords->setUsed(true);
1437 }
1438 }
1439 else {
1440 auto arcane_item_coords_var_ptr = std::make_unique<VariableItemReal3>(VariableBuildInfo(this, family_info.item_coordinates_variable_name),
1441 item_family->itemKind());
1442 arcane_item_coords_var_ptr->setUsed(true);
1443 m_arcane_item_coords.push_back(std::move(arcane_item_coords_var_ptr));
1444 }
1445 }
1446 // Call Arcane ItemFamily endUpdate
1447 for (auto& family : m_arcane_families) {
1448 family->endUpdate();
1449 }
1450 endUpdate();
1451 // Add coordinates when needed (nodes, or dof, or particles...)
1452 family_index = 0;
1453 auto index = 0;
1454 for (auto& family_info : item_allocation_info.family_infos) {
1455 if (family_info.item_coordinates.empty()) {
1456 ++family_index;
1457 continue;
1458 }
1459 auto* item_family = _findItemFamily(family_info.item_kind, family_info.name);
1460 if (item_family == itemFamily(IK_Node)) { // mesh node coords
1461 m_mesh->scheduleSetItemCoordinates(item_family, item_local_ids[family_index], family_info.item_coordinates, *m_arcane_node_coords);
1462 }
1463 else
1464 m_mesh->scheduleSetItemCoordinates(item_family, item_local_ids[family_index], family_info.item_coordinates, *m_arcane_item_coords[index++].get());
1465 }
1466 auto mesh_state = m_mesh->applyScheduledOperations();
1467 m_is_allocated = true;
1468 // indicates mesh contains general Cells
1469 itemTypeMng()->setMeshWithGeneralCells(this);
1470
1471 if (!family_lids.empty()) {
1472 auto index = 0;
1473 ARCANE_ASSERT((family_lids.size() == item_local_ids.size()), ("Incoherence in item number"));
1474 for (auto& lid_array : item_local_ids) {
1475 family_lids[index].resize(lid_array.size());
1476 lid_array.fillArrayView(family_lids[index].view(), mesh_state);
1477 ++index;
1478 }
1479 }
1480}
1481
1482/*---------------------------------------------------------------------------*/
1483
1484void Arcane::mesh::PolyhedralMesh::
1485scheduleAllocateItems(const Arcane::ItemAllocationInfo::FamilyInfo& family_info, mesh::PolyhedralTools::ItemLocalIds& item_local_ids)
1486{
1487 // Second step read a vtk polyhedral mesh
1488 m_subdomain->traceMng()->info() << "--PolyhedralMesh: schedule allocate items --";
1489 // Prepare item creation
1490 bool create_if_needed = true;
1491 auto* item_family = _findItemFamily(family_info.item_kind, family_info.name, create_if_needed);
1492 m_trace_mng->debug(Trace::High) << "- Current family " << family_info.name;
1493 m_trace_mng->debug(Trace::High) << "- Create items ";
1494 m_mesh->scheduleAddItems(item_family, family_info.item_uids, family_info.item_owners.constSmallSpan(), item_local_ids);
1495 // Prepare connectivity creation
1496 for (auto& current_connected_family_info : family_info.connected_family_infos) {
1497 auto connected_family = _findItemFamily(current_connected_family_info.item_kind, current_connected_family_info.name);
1498 m_trace_mng->debug(Trace::High) << "- Create connectivity " << current_connected_family_info.connectivity_name;
1499 // check if connected family exists
1500 if (!connected_family) {
1501 ARCANE_WARNING((String::format("Cannot find family {0} with kind {1} "
1502 "The connectivity between {1} and this family is skipped",
1503 current_connected_family_info.name,
1504 current_connected_family_info.item_kind,
1505 item_family->name())
1506 .localstr()));
1507 continue;
1508 }
1509 m_mesh->scheduleUpdateConnectivity(item_family,
1510 item_local_ids,
1511 current_connected_family_info.nb_connected_items_per_item,
1512 connected_family,
1513 current_connected_family_info.connected_items_uids,
1514 current_connected_family_info.connectivity_name);
1515 }
1516}
1517
1518/*---------------------------------------------------------------------------*/
1519
1520void Arcane::mesh::PolyhedralMesh::
1521applyScheduledAllocateItems(UniqueArray<std::shared_ptr<PolyhedralTools::ItemLocalIds>> item_lids)
1522{
1523 // Create items and connectivities
1524 auto mesh_state = m_mesh->applyScheduledOperations();
1525 // Fill item_lids (they are already filled in applyScheduledOperations: unlock them setting the mesh_state)
1526 for (auto item_local_ids : item_lids) {
1527 item_local_ids->m_mesh_state = std::make_shared<Neo::EndOfMeshUpdate>(mesh_state);
1528 }
1529
1530 // Call Arcane ItemFamily endUpdate and mesh end update
1531 for (auto& family : m_arcane_families) {
1532 family->endUpdate();
1533 }
1534 endUpdate();
1535 m_is_allocated = true;
1536 // indicates mesh contains general Cells
1537 itemTypeMng()->setMeshWithGeneralCells(this);
1538}
1539
1540/*---------------------------------------------------------------------------*/
1541
1542void mesh::PolyhedralMesh::removeNeedRemoveMarkedItems()
1543{
1544 // Loop through all item families in the mesh: must include DoF and Particles
1545 for (auto family_index = 0; family_index < m_arcane_families.size(); ++family_index) {
1546 // Get the list of local IDs for items to remove
1547 auto* family = m_arcane_families[family_index].get();
1548 Int32UniqueArray items_to_remove;
1549 items_to_remove.reserve(family->nbItem());
1550 auto& items_map = family->itemsMap();
1551 if (items_map.count() == 0)
1552 continue;
1553 items_map.eachItem([&](ItemBase item) {
1554 // Schedule removal of items marked for removal
1555 auto f = item.flags();
1556 if (f & ItemFlags::II_NeedRemove) {
1557 f &= ~ItemFlags::II_NeedRemove & ItemFlags::II_Suppressed;
1558 item.toMutable().setFlags(f);
1559 items_to_remove.add(item.localId());
1560 }
1561 });
1562 if (!items_to_remove.empty()) {
1563 removeItems(items_to_remove, family);
1564 }
1565 }
1566}
1567
1568/*---------------------------------------------------------------------------*/
1569
1570Arcane::mesh::PolyhedralFamilySerializerMng* mesh::PolyhedralMesh::
1571polyhedralFamilySerializerMng()
1572{
1573 return m_polyhedral_family_serializer_mng.get();
1574}
1575
1576/*---------------------------------------------------------------------------*/
1577/*---------------------------------------------------------------------------*/
1578
1579void Arcane::mesh::PolyhedralMesh::
1580_endUpdateFamilies()
1581{
1582 for (auto& family : m_arcane_families) {
1583 family->endUpdate();
1584 }
1585}
1586
1587/*---------------------------------------------------------------------------*/
1588/*---------------------------------------------------------------------------*/
1589
1590void Arcane::mesh::PolyhedralMesh::
1591_computeFamilySynchronizeInfos()
1592{
1593 m_subdomain->traceMng()->info() << "Computing family synchronization information for " << name();
1594 for (auto& family : m_arcane_families) {
1595 family->computeSynchronizeInfos();
1596 }
1597
1598 // Write topology for cell synchronization
1599 if (!platform::getEnvironmentVariable("ARCANE_DUMP_VARIABLE_SYNCHRONIZER_TOPOLOGY").null()) {
1600 auto* var_syncer = cellFamily()->allItemsSynchronizer();
1601 Int32 iteration = m_subdomain->commonVariables().globalIteration();
1602 String file_name = String::format("{0}_sync_topology_iter{1}.json", name(), iteration);
1603 mesh_utils::dumpSynchronizerTopologyJSON(var_syncer, file_name);
1604 }
1605}
1606
1607/*---------------------------------------------------------------------------*/
1608/*---------------------------------------------------------------------------*/
1609
1610void Arcane::mesh::PolyhedralMesh::
1611_notifyEndUpdateForFamilies()
1612{
1613 for (auto& family : m_arcane_families)
1614 family->_internalApi()->notifyEndUpdateFromMesh();
1615}
1616
1617/*---------------------------------------------------------------------------*/
1618/*---------------------------------------------------------------------------*/
1619
1620void Arcane::mesh::PolyhedralMesh::
1621_computeGroupSynchronizeInfos()
1622{
1623 auto action = [](ItemGroup& group) {
1624 if (group.hasSynchronizer())
1625 group.synchronizer()->compute();
1626 };
1627
1628 m_trace_mng->info() << "Computing group synchronization information for " << name();
1629 meshvisitor::visitGroups(this, action);
1630}
1631
1632/*---------------------------------------------------------------------------*/
1633/*---------------------------------------------------------------------------*/
1634
1636name() const
1637{
1638 return m_name;
1639}
1640
1641/*---------------------------------------------------------------------------*/
1642/*---------------------------------------------------------------------------*/
1643
1645dimension()
1646{
1647 return m_mesh->dimension();
1648}
1649
1650/*---------------------------------------------------------------------------*/
1651/*---------------------------------------------------------------------------*/
1652
1654nbNode()
1655{
1656 return m_mesh->nbNode();
1657}
1658
1659/*---------------------------------------------------------------------------*/
1660/*---------------------------------------------------------------------------*/
1661
1663nbEdge()
1664{
1665 return m_mesh->nbEdge();
1666}
1667
1668/*---------------------------------------------------------------------------*/
1669/*---------------------------------------------------------------------------*/
1670
1672nbFace()
1673{
1674 return m_mesh->nbFace();
1675}
1676
1677/*---------------------------------------------------------------------------*/
1678/*---------------------------------------------------------------------------*/
1679
1681nbCell()
1682{
1683 return m_mesh->nbCell();
1684}
1685
1686/*---------------------------------------------------------------------------*/
1687/*---------------------------------------------------------------------------*/
1688
1690nbItem(eItemKind ik)
1691{
1692 return m_mesh->nbItem(ik);
1693}
1694
1695/*---------------------------------------------------------------------------*/
1696/*---------------------------------------------------------------------------*/
1697
1699allNodes()
1700{
1701 if (m_default_arcane_families[IK_Node])
1702 return m_default_arcane_families[IK_Node]->allItems();
1703 else
1704 return NodeGroup{};
1705}
1706
1707/*---------------------------------------------------------------------------*/
1708/*---------------------------------------------------------------------------*/
1709
1711allEdges()
1712{
1713 if (m_default_arcane_families[IK_Edge])
1714 return m_default_arcane_families[IK_Edge]->allItems();
1715 else
1716 return EdgeGroup{};
1717}
1718
1719/*---------------------------------------------------------------------------*/
1720/*---------------------------------------------------------------------------*/
1721
1723allFaces()
1724{
1725 if (m_default_arcane_families[IK_Face])
1726 return m_default_arcane_families[IK_Face]->allItems();
1727 else
1728 return FaceGroup{};
1729}
1730
1731/*---------------------------------------------------------------------------*/
1732/*---------------------------------------------------------------------------*/
1733
1735allCells()
1736{
1737 if (m_default_arcane_families[IK_Cell])
1738 return m_default_arcane_families[IK_Cell]->allItems();
1739 else
1740 return CellGroup{};
1741}
1742
1743/*---------------------------------------------------------------------------*/
1744/*---------------------------------------------------------------------------*/
1745
1747ownNodes()
1748{
1749 if (m_default_arcane_families[IK_Node])
1750 return m_default_arcane_families[IK_Node]->allItems().own();
1751 else
1752 return NodeGroup{};
1753}
1754
1755/*---------------------------------------------------------------------------*/
1756/*---------------------------------------------------------------------------*/
1757
1759ownEdges()
1760{
1761 if (m_default_arcane_families[IK_Edge])
1762 return m_default_arcane_families[IK_Edge]->allItems().own();
1763 else
1764 return EdgeGroup{};
1765}
1766
1767/*---------------------------------------------------------------------------*/
1768/*---------------------------------------------------------------------------*/
1769
1771ownFaces()
1772{
1773 if (m_default_arcane_families[IK_Face])
1774 return m_default_arcane_families[IK_Face]->allItems().own();
1775 else
1776 return FaceGroup{};
1777}
1778
1779/*---------------------------------------------------------------------------*/
1780/*---------------------------------------------------------------------------*/
1781
1783ownCells()
1784{
1785 if (m_default_arcane_families[IK_Cell])
1786 return m_default_arcane_families[IK_Cell]->allItems().own();
1787 else
1788 return CellGroup{};
1789}
1790
1791/*---------------------------------------------------------------------------*/
1792/*---------------------------------------------------------------------------*/
1793
1795outerFaces()
1796{
1797 if (m_default_arcane_families[IK_Cell])
1798 return m_default_arcane_families[IK_Cell]->allItems().outerFaceGroup();
1799 else
1800 return FaceGroup{};
1801}
1802
1803/*---------------------------------------------------------------------------*/
1804/*---------------------------------------------------------------------------*/
1805
1806mesh::PolyhedralFamily* mesh::PolyhedralMesh::
1807_createItemFamily(eItemKind ik, const String& name)
1808{
1809 m_mesh->addFamily(ik, name);
1810 m_arcane_families.push_back(std::make_unique<PolyhedralFamily>(this, ik, name));
1811 auto current_family = m_arcane_families.back().get();
1812 if (m_default_arcane_families[ik] == nullptr) {
1813 m_default_arcane_families[ik] = current_family;
1814 _updateMeshInternalList(ik);
1815 }
1816 m_item_family_collection.add(current_family);
1817 current_family->build();
1818 return current_family;
1819}
1820
1821/*---------------------------------------------------------------------------*/
1822/*---------------------------------------------------------------------------*/
1823
1824IItemFamily* mesh::PolyhedralMesh::
1825createItemFamily(eItemKind ik, const String& name)
1826{
1827 return _createItemFamily(ik, name);
1828}
1829
1830/*---------------------------------------------------------------------------*/
1831/*---------------------------------------------------------------------------*/
1832
1833void mesh::PolyhedralMesh::
1834_createUnitMesh()
1835{
1836 createItemFamily(IK_Cell, "CellFamily");
1837 createItemFamily(IK_Node, "NodeFamily");
1838 auto cell_family = m_default_arcane_families[IK_Cell];
1839 auto node_family = m_default_arcane_families[IK_Node];
1840 Int64UniqueArray cell_uids{ 0 }, node_uids{ 0, 1, 2, 3, 4, 5 };
1841 // todo add a cell_lids struct (containing future)
1842 PolyhedralTools::ItemLocalIds cell_lids, node_lids;
1843 m_mesh->scheduleAddItems(cell_family, cell_uids.constView(), cell_lids);
1844 m_mesh->scheduleAddItems(node_family, node_uids.constView(), node_lids);
1845 int nb_node = 6;
1846 Int64UniqueArray node_cells_uids{ 0, 0, 0, 0, 0, 0 };
1847 m_mesh->scheduleAddConnectivity(cell_family, cell_lids, nb_node, node_family, node_uids, String{ "CellToNodes" });
1848 m_mesh->scheduleAddConnectivity(node_family, node_lids, 1, cell_family,
1849 node_cells_uids, String{ "NodeToCells" });
1850 m_mesh->applyScheduledOperations();
1851 cell_family->endUpdate();
1852 node_family->endUpdate();
1853 endUpdate();
1854 // Mimic what IMeshModifier::endUpdate would do => default families are completed.
1855 // Families created after a first endUpdate call are not default families
1856}
1857
1858/*---------------------------------------------------------------------------*/
1859/*---------------------------------------------------------------------------*/
1860
1862endUpdate()
1863{
1864 // create empty default families not already created
1865 for (auto ik = 0; ik < NB_ITEM_KIND; ++ik) {
1866 if (m_default_arcane_families[ik] == nullptr && ik != eItemKind::IK_DoF) {
1867 String name = String::concat(itemKindName((eItemKind)ik), "EmptyFamily");
1868 m_empty_arcane_families[ik] = std::make_unique<mesh::PolyhedralFamily>(this, (eItemKind)ik, name);
1869 m_default_arcane_families[ik] = m_empty_arcane_families[ik].get();
1870 }
1871 }
1872}
1873
1874/*---------------------------------------------------------------------------*/
1875/*---------------------------------------------------------------------------*/
1876
1877IItemFamily* mesh::PolyhedralMesh::
1878nodeFamily()
1879{
1880 return m_default_arcane_families[IK_Node];
1881}
1882
1883/*---------------------------------------------------------------------------*/
1884/*---------------------------------------------------------------------------*/
1885
1886IItemFamily* mesh::PolyhedralMesh::
1887edgeFamily()
1888{
1889 return m_default_arcane_families[IK_Edge];
1890}
1891
1892/*---------------------------------------------------------------------------*/
1893/*---------------------------------------------------------------------------*/
1894
1895IItemFamily* mesh::PolyhedralMesh::
1896faceFamily()
1897{
1898 return m_default_arcane_families[IK_Face];
1899}
1900
1901/*---------------------------------------------------------------------------*/
1902/*---------------------------------------------------------------------------*/
1903
1904IItemFamily* mesh::PolyhedralMesh::
1905cellFamily()
1906{
1907 return m_default_arcane_families[IK_Cell];
1908}
1909
1910void mesh::PolyhedralMesh::
1911_updateMeshInternalList(eItemKind kind)
1912{
1913 switch (kind) {
1914 case IK_Cell:
1915 m_mesh_item_internal_list.cells = m_default_arcane_families[kind]->itemsInternal();
1916 m_mesh_item_internal_list._internalSetCellSharedInfo(m_default_arcane_families[kind]->commonItemSharedInfo());
1917 break;
1918 case IK_Face:
1919 m_mesh_item_internal_list.faces = m_default_arcane_families[kind]->itemsInternal();
1920 m_mesh_item_internal_list._internalSetFaceSharedInfo(m_default_arcane_families[kind]->commonItemSharedInfo());
1921 break;
1922 case IK_Edge:
1923 m_mesh_item_internal_list.edges = m_default_arcane_families[kind]->itemsInternal();
1924 m_mesh_item_internal_list._internalSetEdgeSharedInfo(m_default_arcane_families[kind]->commonItemSharedInfo());
1925 break;
1926 case IK_Node:
1927 m_mesh_item_internal_list.nodes = m_default_arcane_families[kind]->itemsInternal();
1928 m_mesh_item_internal_list._internalSetNodeSharedInfo(m_default_arcane_families[kind]->commonItemSharedInfo());
1929 break;
1930 case IK_DoF:
1931 case IK_Particle:
1932 case IK_Unknown:
1933 break;
1934 }
1935}
1936
1937/*---------------------------------------------------------------------------*/
1938/*---------------------------------------------------------------------------*/
1939
1940mesh::PolyhedralFamily* mesh::PolyhedralMesh::
1941_itemFamily(eItemKind ik)
1942{
1943 return m_default_arcane_families[ik];
1944}
1945
1946/*---------------------------------------------------------------------------*/
1947/*---------------------------------------------------------------------------*/
1948
1949IItemFamily* mesh::PolyhedralMesh::
1951{
1952 return _itemFamily(ik);
1953}
1954
1955/*---------------------------------------------------------------------------*/
1956/*---------------------------------------------------------------------------*/
1957
1958ItemTypeMng* mesh::PolyhedralMesh::
1959itemTypeMng() const
1960{
1961 return m_item_type_mng;
1962}
1963
1964/*---------------------------------------------------------------------------*/
1965/*---------------------------------------------------------------------------*/
1966
1967mesh::PolyhedralFamily* mesh::PolyhedralMesh::
1968_findItemFamily(eItemKind ik, const String& name, bool create_if_needed)
1969{
1970 // Check if is a default family
1971 auto found_family = _itemFamily(ik);
1972 if (found_family) {
1973 if (found_family->name() == name)
1974 return found_family;
1975 }
1976 for (auto& family : m_arcane_families) {
1977 if (family->itemKind() == ik && family->name() == name)
1978 return family.get();
1979 }
1980 if (!create_if_needed)
1981 return nullptr;
1982 return _createItemFamily(ik, name);
1983}
1984
1985/*---------------------------------------------------------------------------*/
1986/*---------------------------------------------------------------------------*/
1987
1988IItemFamily* mesh::PolyhedralMesh::
1989findItemFamily(eItemKind ik, const String& name, bool create_if_needed, bool register_modifier_if_created)
1990{
1991 ARCANE_UNUSED(register_modifier_if_created); // IItemFamilyModifier not yet used in polyhedral mesh
1992 return _findItemFamily(ik, name, create_if_needed);
1993}
1994
1995/*---------------------------------------------------------------------------*/
1996/*---------------------------------------------------------------------------*/
1997
1998mesh::PolyhedralFamily* mesh::PolyhedralMesh::
1999arcaneDefaultFamily(eItemKind ik)
2000{
2001 return m_default_arcane_families[ik];
2002}
2003
2004/*---------------------------------------------------------------------------*/
2005/*---------------------------------------------------------------------------*/
2006
2009{
2010 ARCANE_ASSERT(m_arcane_node_coords, ("Node coordinates not yet loaded."));
2011 return *m_arcane_node_coords;
2012}
2013
2014/*---------------------------------------------------------------------------*/
2015/*---------------------------------------------------------------------------*/
2016
2017ItemGroup mesh::PolyhedralMesh::
2018findGroup(const String& name)
2019{
2020 ItemGroup group;
2021 for (auto& family : m_arcane_families) {
2022 group = family->findGroup(name);
2023 if (!group.null())
2024 return group;
2025 }
2026 return group;
2027}
2028
2029/*---------------------------------------------------------------------------*/
2030/*---------------------------------------------------------------------------*/
2031
2033groups()
2034{
2035 m_all_groups.clear();
2036 for (auto& family : m_arcane_families) {
2037 for (ItemGroupCollection::Enumerator i_group(family->groups()); ++i_group;)
2038 m_all_groups.add(*i_group);
2039 }
2040 return m_all_groups;
2041}
2042
2043/*---------------------------------------------------------------------------*/
2044/*---------------------------------------------------------------------------*/
2045
2048{
2049 for (auto& family : m_arcane_families) {
2050 family->destroyGroups();
2051 }
2052}
2053
2054/*---------------------------------------------------------------------------*/
2055/*---------------------------------------------------------------------------*/
2056
2057IItemFamilyCollection mesh::PolyhedralMesh::
2058itemFamilies()
2059{
2060 return m_item_family_collection;
2061}
2062
2063/*---------------------------------------------------------------------------*/
2064/*---------------------------------------------------------------------------*/
2065
2066IMeshInternal* mesh::PolyhedralMesh::
2068{
2069 return m_internal_api.get();
2070}
2071
2072/*---------------------------------------------------------------------------*/
2073/*---------------------------------------------------------------------------*/
2074
2075IMeshCompactMng* mesh::PolyhedralMesh::
2077{
2078 return m_compact_mng.get();
2079}
2080
2081/*---------------------------------------------------------------------------*/
2082/*---------------------------------------------------------------------------*/
2083
2084void mesh::PolyhedralMesh::
2085addItems(Int64ConstArrayView unique_ids, Int32ArrayView local_ids, eItemKind ik, const String& family_name)
2086{
2087 ARCANE_ASSERT((unique_ids.size() == local_ids.size()), ("local and unique ids arrays must have same size"))
2088 auto* item_family = _findItemFamily(ik, family_name, false);
2089 PolyhedralTools::ItemLocalIds item_local_ids;
2090 m_mesh->scheduleAddItems(item_family, unique_ids, item_local_ids);
2091 auto mesh_state = m_mesh->applyScheduledOperations();
2092 item_local_ids.fillArrayView(local_ids, mesh_state);
2093}
2094
2095/*---------------------------------------------------------------------------*/
2096/*---------------------------------------------------------------------------*/
2097
2098void mesh::PolyhedralMesh::
2099addItems(Int64ConstArrayView unique_ids, Int32ArrayView local_ids, Int32ConstArrayView owners, eItemKind ik, const String& family_name)
2100{
2101 ARCANE_ASSERT((unique_ids.size() == local_ids.size() && (unique_ids.size() == owners.size())), ("local/unique ids and owners arrays must have same size"))
2102 auto* item_family = _findItemFamily(ik, family_name, false);
2103 PolyhedralTools::ItemLocalIds item_local_ids;
2104 m_mesh->scheduleAddItems(item_family, unique_ids, owners, item_local_ids);
2105 auto mesh_state = m_mesh->applyScheduledOperations();
2106 item_local_ids.fillArrayView(local_ids, mesh_state);
2107}
2108
2109/*---------------------------------------------------------------------------*/
2110/*---------------------------------------------------------------------------*/
2111
2112void mesh::PolyhedralMesh::
2113removeItems(Int32ConstArrayView local_ids, eItemKind ik, const String& family_name)
2114{
2115 auto* item_family = _findItemFamily(ik, family_name, false);
2116 if (!item_family) {
2117 ARCANE_FATAL("ItemFamily with name {0} and kind {1} does not exist in the mesh.", family_name, ik);
2118 }
2119 m_mesh->scheduleRemoveItems(item_family, local_ids);
2120 m_mesh->applyScheduledOperations();
2121}
2122
2123/*---------------------------------------------------------------------------*/
2124/*---------------------------------------------------------------------------*/
2125
2126void mesh::PolyhedralMesh::
2127removeItems(Int32ConstArrayView local_ids, IItemFamily* family)
2128{
2129 if (local_ids.empty())
2130 return;
2131 if (!family) {
2132 ARCANE_FATAL("Invalid IItemFamily passed to removeItems.");
2133 }
2134 removeItems(local_ids, family->itemKind(), family->name());
2135}
2136
2137/*---------------------------------------------------------------------------*/
2138/*---------------------------------------------------------------------------*/
2139
2141addNodes(Int64ConstArrayView nodes_uid, Int32ArrayView nodes_lid)
2142{
2143 addItems(nodes_uid, nodes_lid, IK_Node, nodeFamily()->name());
2144}
2145
2146/*---------------------------------------------------------------------------*/
2147/*---------------------------------------------------------------------------*/
2148
2151{
2152 m_trace_mng->info() << "PolyhedralMesh::_exchangeItems() do_compact?=" << "false"
2153 << " nb_exchange=" << 0 << " version=" << 0;
2154 _exchangeItems();
2155 String check_exchange = platform::getEnvironmentVariable("ARCANE_CHECK_EXCHANGE");
2156 if (!check_exchange.null()) {
2157 m_mesh_checker.checkGhostCells();
2158 m_trace_mng->pwarning() << "CHECKING SYNCHRONISATION !";
2159 m_mesh_checker.checkVariablesSynchronization();
2160 m_mesh_checker.checkItemGroupsSynchronization();
2161 }
2162 if (checkLevel() >= 2)
2163 m_mesh_checker.checkValidMesh();
2164 else if (checkLevel() >= 1)
2165 m_mesh_checker.checkValidConnectivity();
2166}
2167
2168/*---------------------------------------------------------------------------*/
2169/*---------------------------------------------------------------------------*/
2170
2171void mesh::PolyhedralMesh::
2172_exchangeItems()
2173{
2174 // todo handle submeshes, cf. DynamicMesh
2175
2176 Trace::Setter mci(traceMng(), _className());
2177
2178 if (!m_is_dynamic)
2179 ARCANE_FATAL("property isDynamic() has to be 'true'");
2180
2181 if (arcane_debug_load_balancing) {
2182 for (auto& family : m_arcane_families) {
2183 family->itemsNewOwner().checkIfSync();
2184 }
2185 }
2186
2187 IMeshExchanger* iexchanger = m_mesh_exchange_mng->beginExchange();
2188
2189 // If no entity to exchange return
2190 if (iexchanger->computeExchangeInfos()) {
2191 m_trace_mng->pwarning() << "No load balance is performed";
2192 m_mesh_exchange_mng->endExchange();
2193 return;
2194 }
2195
2196 // Do exchange info
2197 iexchanger->processExchange();
2198
2199 // Remove items no longer on the current subdomain
2200 iexchanger->removeNeededItems();
2201
2202 // Update groups : remove gone entities
2203 // invalidate computed groups
2204 {
2205 auto action = [](ItemGroup& group) {
2206 if (group.internal()->hasComputeFunctor() || group.isLocalToSubDomain())
2207 group.invalidate();
2208 else
2209 group.internal()->removeSuppressedItems();
2210 };
2211 meshvisitor::visitGroups(this, action);
2212 }
2213
2214 iexchanger->allocateReceivedItems();
2215
2216 // Equivalent of DynamicMesh::_internalEndUpdateInit
2217 _endUpdateFamilies();
2218 _computeFamilySynchronizeInfos();
2219
2220 // Update groups
2221 iexchanger->updateItemGroups();
2222
2223 _computeGroupSynchronizeInfos();
2224
2225 iexchanger->updateVariables();
2226
2227 // Equivalent DynamicMesh::_internalEndUpdateFinal(bool)
2228 // check mesh is conform with reference (complete sequential connectivity on a file)
2229 m_mesh_checker.checkMeshFromReferenceFile();
2230 _notifyEndUpdateForFamilies();
2231
2232 iexchanger->finalizeExchange();
2233
2234 m_mesh_exchange_mng->endExchange();
2235
2236 // // todo handle extra ghost
2237 // if (m_extra_ghost_cells_builder->hasBuilder() || m_extra_ghost_particles_builder->hasBuilder())
2238 // this->endUpdate(true,false);
2239 // else
2240 this->endUpdate();
2241}
2242
2243/*---------------------------------------------------------------------------*/
2244/*---------------------------------------------------------------------------*/
2245
2248{
2249 // do nothing for now
2250 auto want_dump = false;
2251 auto need_compact = false;
2252 m_trace_mng->info(4) << "DynamicMesh::prepareForDump() name=" << name()
2253 << " need_compact?=" << need_compact
2254 << " want_dump?=" << want_dump
2255 << " timestamp=" << 0;
2256
2257 {
2259 m_mesh_events.eventObservable(t).notify(MeshEventArgs(this, t));
2260 }
2261
2262 // todo use Properties
2263 if (want_dump) {
2264 for (auto& family : m_arcane_families) {
2265 family->prepareForDump();
2266 }
2267 }
2268
2269 {
2271 m_mesh_events.eventObservable(t).notify(MeshEventArgs(this, t));
2272 }
2273}
2274
2275/*---------------------------------------------------------------------------*/
2276/*---------------------------------------------------------------------------*/
2277
2280{
2281 return allCells().activeCellGroup();
2282}
2283
2284/*---------------------------------------------------------------------------*/
2285/*---------------------------------------------------------------------------*/
2286
2288{
2289 return allCells().ownActiveCellGroup();
2290}
2291
2292/*---------------------------------------------------------------------------*/
2293/*---------------------------------------------------------------------------*/
2294
2296allLevelCells(const Integer& level)
2297{
2298 return allCells().levelCellGroup(level);
2299}
2300
2301/*---------------------------------------------------------------------------*/
2302/*---------------------------------------------------------------------------*/
2303
2305ownLevelCells(const Integer& level)
2306{
2307 return allCells().ownLevelCellGroup(level);
2308}
2309
2310/*---------------------------------------------------------------------------*/
2311/*---------------------------------------------------------------------------*/
2312
2315{
2316 return allCells().activeFaceGroup();
2317}
2318
2319/*---------------------------------------------------------------------------*/
2320/*---------------------------------------------------------------------------*/
2321
2324{
2325 return allCells().ownActiveFaceGroup();
2326}
2327
2328/*---------------------------------------------------------------------------*/
2329/*---------------------------------------------------------------------------*/
2330
2333{
2334 return allCells().innerActiveFaceGroup();
2335}
2336
2337/*---------------------------------------------------------------------------*/
2338/*---------------------------------------------------------------------------*/
2339
2342{
2343 return allCells().outerActiveFaceGroup();
2344}
2345
2346/*---------------------------------------------------------------------------*/
2347/*---------------------------------------------------------------------------*/
2348
2349IMeshUtilities* mesh::PolyhedralMesh::
2350utilities()
2351{
2352 return m_mesh_utilities.get();
2353}
2354
2355/*---------------------------------------------------------------------------*/
2356/*---------------------------------------------------------------------------*/
2357
2360{
2361 IItemFamily* item_family = _itemFamily(ik);
2362 ARCANE_CHECK_POINTER(item_family);
2363 return item_family->itemsNewOwner();
2364}
2365
2366/*---------------------------------------------------------------------------*/
2367/*---------------------------------------------------------------------------*/
2368
2370checkLevel() const
2371{
2372 return m_mesh_checker.checkLevel();
2373}
2374
2375/*---------------------------------------------------------------------------*/
2376/*---------------------------------------------------------------------------*/
2377
2378IItemFamilyNetwork* mesh::PolyhedralMesh::
2380{
2381 return m_item_family_network.get();
2382}
2383
2384/*---------------------------------------------------------------------------*/
2385/*---------------------------------------------------------------------------*/
2386
2387IGhostLayerMng* mesh::PolyhedralMesh::
2388ghostLayerMng() const
2389{
2390 return m_ghost_layer_mng.get();
2391}
2392
2393/*---------------------------------------------------------------------------*/
2394/*---------------------------------------------------------------------------*/
2395
2396IMeshModifierInternal* mesh::PolyhedralMesh::
2398{
2399 return m_internal_api.get();
2400}
2401
2402/*---------------------------------------------------------------------------*/
2403/*---------------------------------------------------------------------------*/
2404
2405mesh::PolyhedralMeshImpl* mesh::PolyhedralMesh::_impl()
2406{
2407 return m_mesh.get();
2408}
2409
2410/*---------------------------------------------------------------------------*/
2411/*---------------------------------------------------------------------------*/
2412
2413} // End namespace Arcane
2414
2415/*---------------------------------------------------------------------------*/
2416/*---------------------------------------------------------------------------*/
2417
2418#else // ARCANE_HAS_POLYHEDRAL_MESH_TOOLS
2419
2420/*---------------------------------------------------------------------------*/
2421/*---------------------------------------------------------------------------*/
2422
2423namespace Arcane::mesh
2424{
2427} // namespace Arcane::mesh
2428
2429/*---------------------------------------------------------------------------*/
2430/*---------------------------------------------------------------------------*/
2431
2432Arcane::mesh::PolyhedralMesh::
2433~PolyhedralMesh() = default;
2434
2435/*---------------------------------------------------------------------------*/
2436/*---------------------------------------------------------------------------*/
2437
2438Arcane::mesh::PolyhedralMesh::
2439PolyhedralMesh(ISubDomain* subdomain, const MeshBuildInfo& mbi)
2440: EmptyMesh{ subdomain->traceMng() }
2441, m_subdomain{ subdomain }
2442, m_mesh{ nullptr }
2443, m_mesh_kind(mbi.meshKind())
2444{
2445}
2446
2447/*---------------------------------------------------------------------------*/
2448/*---------------------------------------------------------------------------*/
2449
2450void Arcane::mesh::PolyhedralMesh::
2451read([[maybe_unused]] const String& filename)
2452{
2453 _errorEmptyMesh();
2454}
2455
2456/*---------------------------------------------------------------------------*/
2457/*---------------------------------------------------------------------------*/
2458
2459void Arcane::mesh::PolyhedralMesh::
2460allocateItems(const Arcane::ItemAllocationInfo& item_allocation_info)
2461{
2462 ARCANE_UNUSED(item_allocation_info);
2463 _errorEmptyMesh();
2464}
2465
2466/*---------------------------------------------------------------------------*/
2467/*---------------------------------------------------------------------------*/
2468
2469#endif // ARCANE_HAS_POLYHEDRAL_MESH_TOOLS
2470
2471/*---------------------------------------------------------------------------*/
2472/*---------------------------------------------------------------------------*/
2473
2474namespace Arcane
2475{
2476
2477class ARCANE_MESH_EXPORT PolyhedralMeshFactory
2478: public AbstractService
2479, public IMeshFactory
2480{
2481 public:
2482
2483 explicit PolyhedralMeshFactory(const ServiceBuildInfo& sbi)
2484 : AbstractService(sbi)
2485 {}
2486
2487 public:
2488
2489 void build() override {}
2490 IPrimaryMesh* createMesh(IMeshMng* mm, const MeshBuildInfo& build_info) override
2491 {
2493 return new mesh::PolyhedralMesh(sd, build_info);
2494 }
2495
2496 static String name() { return "ArcanePolyhedralMeshFactory"; }
2497};
2498
2500 ServiceProperty(PolyhedralMeshFactory::name().localstr(), ST_Application),
2502
2503/*---------------------------------------------------------------------------*/
2504/*---------------------------------------------------------------------------*/
2505
2506#if ARCANE_HAS_POLYHEDRAL_MESH_TOOLS
2507
2508/*---------------------------------------------------------------------------*/
2509/*---------------------------------------------------------------------------*/
2510
2512factoryName() const
2513{
2514 return PolyhedralMeshFactory::name();
2515}
2516
2517/*---------------------------------------------------------------------------*/
2518/*---------------------------------------------------------------------------*/
2519
2520#endif // ARCANE_HAS_POLYHEDRAL_MESH_TOOLS
2521
2522/*---------------------------------------------------------------------------*/
2523/*---------------------------------------------------------------------------*/
2524
2525} // End namespace Arcane
2526
2527/*---------------------------------------------------------------------------*/
2528/*---------------------------------------------------------------------------*/
#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.
#define ENUMERATE_(type, name, group)
Generic enumerator for an entity group.
#define ENUMERATE_ITEM(name, group)
Generic enumerator for a node group.
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.
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.
Internal part of IMesh.
Mesh manager interface.
Definition IMeshMng.h:41
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.
Interface of the subdomain manager.
Definition ISubDomain.h:78
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.
Definition ItemFlags.h:54
@ II_NeedRemove
The entity must be removed.
Definition ItemFlags.h:63
@ II_HasBackCell
The entity has a back cell.
Definition ItemFlags.h:53
@ II_SubDomainBoundary
The entity is at the boundary of two subdomains.
Definition ItemFlags.h:60
@ II_Suppressed
The entity has just been suppressed.
Definition ItemFlags.h:58
@ II_Boundary
The entity is on the boundary.
Definition ItemFlags.h:51
@ II_HasFrontCell
The entity has a front cell.
Definition ItemFlags.h:52
@ II_BackCellIsFirst
The first cell of the entity is the back cell.
Definition ItemFlags.h:55
FaceGroup activeFaceGroup() const
Group of active faces.
Definition ItemGroup.cc:344
FaceGroup innerActiveFaceGroup() const
Group of internal faces of the elements of this group.
Definition ItemGroup.cc:371
FaceGroup ownActiveFaceGroup() const
Group of active faces belonging to the domain of the elements of this group.
Definition ItemGroup.cc:356
CellGroup levelCellGroup(const Integer &level) const
Group of level l cells of the elements of this group.
Definition ItemGroup.cc:321
CellGroup ownActiveCellGroup() const
Group of own active cells of the elements of this group.
Definition ItemGroup.cc:309
CellGroup ownLevelCellGroup(const Integer &level) const
Group of own level l cells of the elements of this group.
Definition ItemGroup.cc:333
FaceGroup outerActiveFaceGroup() const
Group of active external faces of the elements of this group.
Definition ItemGroup.cc:383
CellGroup activeCellGroup() const
AMR.
Definition ItemGroup.cc:297
FaceGroup outerFaceGroup() const
Group of external faces of the elements of this group.
Definition ItemGroup.cc:282
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.
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.
Definition ItemTypes.h:316
ItemGroupT< Cell > CellGroup
Group of cells.
Definition ItemTypes.h:184
ItemGroupT< Face > FaceGroup
Group of faces.
Definition ItemTypes.h:179
ItemGroupT< Edge > EdgeGroup
Group of edges.
Definition ItemTypes.h:174
ItemGroupT< Node > NodeGroup
Group of nodes.
Definition ItemTypes.h:168
#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
String getEnvironmentVariable(const String &name)
Environment variable named name.
Array< Int64 > Int64Array
Dynamic one-dimensional array of 64-bit integers.
Definition UtilsTypes.h:119
UniqueArray< Int64 > Int64UniqueArray
Dynamic 1D array of 64-bit integers.
Definition UtilsTypes.h:333
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.
Definition UtilsTypes.h:476
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.
Definition UtilsTypes.h:474
SmallSpan< const Real3 > Real3ConstSmallSpan
Read-only view of a 1D array of Real3.
Definition UtilsTypes.h:626
eMeshEventType
Events generated by IMesh.
Definition MeshEvents.h:30
@ EndPrepareDump
Event sent at the end of prepareForDump().
Definition MeshEvents.h:34
@ BeginPrepareDump
Event sent at the beginning of prepareForDump().
Definition MeshEvents.h:32
UniqueArray< Int32 > Int32UniqueArray
Dynamic 1D array of 32-bit integers.
Definition UtilsTypes.h:335
ArrayView< Int32 > Int32ArrayView
C equivalent of a 1D array of 32-bit integers.
Definition UtilsTypes.h:447
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.
Definition UtilsTypes.h:610
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.
Definition UtilsTypes.h:121
UniqueArray< String > StringUniqueArray
Dynamic 1D array of strings.
Definition UtilsTypes.h:353
Span< const Int32 > Int32ConstSpan
Read-only view of a 1D array of 32-bit integers.
Definition UtilsTypes.h:548
SmallSpan< const Int32 > Int32ConstSmallSpan
Read-only view of a 1D array of 32-bit integers.
Definition UtilsTypes.h:612
std::int32_t Int32
Signed integer type of 32 bits.