Arcane  4.1.15.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 }
855 // Add an algorithm to remove items isolated after a connectivity update. Add it only once, when connectivity is added
856 if (operation == Neo::Mesh::ConnectivityOperation::Modify)
857 return;
858 auto isolated_item_property_name = m_mesh._isolatedItemLidsPropertyName(source_family, target_family);
859 auto end_of_isolated_removal_property_name = std::string{ "EndOf" } + isolated_item_property_name;
860 source_family.addScalarProperty<Neo::utils::Int32>(end_of_isolated_removal_property_name);
861 mesh_graph.addAlgorithm(Neo::MeshKernel::InProperty{ source_family, isolated_item_property_name },
862 Neo::MeshKernel::OutProperty{ source_family, end_of_isolated_removal_property_name },
863 "RemoveIsolatedArcaneItemsIn"+std::string{ arcane_source_item_family->name().localstr() },
864 [arcane_source_item_family](Neo::MeshScalarPropertyT<Neo::utils::Int32> const& isolated_items_lids_property,
865 Neo::ScalarPropertyT<Neo::utils::Int32>& end_of_isolated_removal_property) {
866 end_of_isolated_removal_property.set(1);
867 // remove Arcane items
868 Int32UniqueArray isolated_item_lids;
869 isolated_item_lids.reserve(isolated_items_lids_property.size());
870 ENUMERATE_(Item,iitem,arcane_source_item_family->allItems()) {
871 if (isolated_items_lids_property[iitem->localId()] == 1) {
872 isolated_item_lids.push_back(iitem->localId());
873 }
874 }
875 std::sort(isolated_item_lids.begin(), isolated_item_lids.end());
876 arcane_source_item_family->traceMng()->info() << "Remove isolated in Arcane for family "
877 << " lids : " << isolated_item_lids;
878 isolated_items_lids_property.debugPrint();
879 arcane_source_item_family->removeItems(isolated_item_lids);
880 }, Neo::MeshKernel::AlgorithmPropertyGraph::AlgorithmPersistence::KeepAfterExecution);
881 }
882
883 /*---------------------------------------------------------------------------*/
884
885 void scheduleSetItemCoordinates(PolyhedralFamily* item_family, PolyhedralTools::ItemLocalIds& local_ids, Real3ConstSmallSpan item_coords, VariableItemReal3& arcane_coords)
886 {
887 auto& _item_family = m_mesh.findFamily(itemKindArcaneToNeo(item_family->itemKind()), item_family->name().localstr());
888 std::vector<Neo::utils::Real3> _node_coords(item_coords.size());
889 auto node_index = 0;
890 for (auto&& node_coord : item_coords) {
891 _node_coords[node_index++] = Neo::utils::Real3{ node_coord.x, node_coord.y, node_coord.z };
892 }
893 m_mesh.scheduleSetItemCoords(_item_family, local_ids.m_future_items, _node_coords);
894 // Fill Arcane Variable
895 auto& mesh_graph = m_mesh.internalMeshGraph();
896 _item_family.addScalarProperty<Int32>("NoOutProperty42"); // todo remove : create noOutput algo in Neo
897 mesh_graph.addAlgorithm(Neo::MeshKernel::InProperty{ _item_family, m_mesh._itemCoordPropertyName(_item_family) },
898 Neo::MeshKernel::OutProperty{ _item_family, "NoOutProperty42" },
899 "UpdateArcaneCoordsIn"+std::string{item_family->name().localstr()},
900 [this, item_family, &_item_family, &arcane_coords](Neo::Mesh::CoordPropertyType const& item_coords_property,
901 Neo::ScalarPropertyT<Neo::utils::Int32>&) {
902 // enumerate nodes : ensure again Arcane/Neo local_ids are identicals
903 auto& all_items = _item_family.all();
904 VariableNodeReal3 node_coords{ VariableBuildInfo{ item_family->mesh(), "NodeCoord" } };
905 for (auto item : all_items) {
906 arcane_coords[ItemLocalId{ item }] = { item_coords_property[item].x,
907 item_coords_property[item].y,
908 item_coords_property[item].z };
909 }
910 });
911 }
912
913 /*---------------------------------------------------------------------------*/
914
915 Neo::EndOfMeshUpdate applyScheduledOperations() noexcept
916 {
917 return m_mesh.applyScheduledOperations();
918 }
919 };
920
921 template <> class PolyhedralMeshImpl::ItemKindTraits<IK_Cell>
922 {
923 static const Neo::ItemKind item_kind = Neo::ItemKind::IK_Cell;
924 };
925 template <> class PolyhedralMeshImpl::ItemKindTraits<IK_Face>
926 {
927 static const Neo::ItemKind item_kind = Neo::ItemKind::IK_Face;
928 };
929 template <> class PolyhedralMeshImpl::ItemKindTraits<IK_Edge>
930 {
931 static const Neo::ItemKind item_kind = Neo::ItemKind::IK_Edge;
932 };
933 template <> class PolyhedralMeshImpl::ItemKindTraits<IK_Node>
934 {
935 static const Neo::ItemKind item_kind = Neo::ItemKind::IK_Node;
936 };
937 template <> class PolyhedralMeshImpl::ItemKindTraits<IK_DoF>
938 {
939 static const Neo::ItemKind item_kind = Neo::ItemKind::IK_Dof;
940 };
941
942 /*---------------------------------------------------------------------------*/
943
944 void PolyhedralFamilySerializer::serializeItems(ISerializer* buf, Int32ConstArrayView items_local_ids)
945 {
946 ARCANE_CHECK_POINTER(m_family);
948
949 switch (buf->mode()) {
950 case ISerializer::ModeReserve: {
951 _fillItemData(items_local_ids);
952 m_item_data.serialize(buf);
953 auto connectivities = m_mesh->_impl()->connectivities(m_family);
954 for (auto out_connectivity : connectivities) {
955 buf->reserve(out_connectivity.target_family.name());
956 buf->reserve(out_connectivity.name);
957 }
958 break;
959 }
961 m_item_data.serialize(buf);
962 auto connectivities = m_mesh->_impl()->connectivities(m_family);
963 for (auto out_connectivity : connectivities) {
964 buf->put(out_connectivity.target_family.name());
965 buf->put(out_connectivity.name);
966 }
967 clear();
968 break;
969 }
971 deserializeItems(buf, nullptr);
972 break;
973 }
974 }
975 }
976
977 /*---------------------------------------------------------------------------*/
978
979 void PolyhedralFamilySerializer::deserializeItems(ISerializer* buf, Int32Array* items_local_ids)
980 {
981 ARCANE_ASSERT((buf->mode() == ISerializer::ModeGet),
982 ("Impossible to deserialize a buffer not in ModeGet. In ItemData::deserialize.Exiting"))
983 ARCANE_CHECK_POINTER(m_mesh);
984 ARCANE_CHECK_POINTER(m_family);
986 ItemData item_data;
987 if (items_local_ids)
988 item_data.deserialize(buf, m_mesh, *items_local_ids);
989 else
990 item_data.deserialize(buf, m_mesh);
991 auto connectivities = m_mesh->_impl()->connectivities(m_family);
992 auto nb_connectivities = connectivities.size();
993 StringUniqueArray connected_family_names(nb_connectivities);
994 StringUniqueArray connectivity_names(nb_connectivities);
995 auto index = 0;
996 for (auto out_connectivity : connectivities) {
997 buf->get(connected_family_names[index]);
998 buf->get(connectivity_names[index]);
999 ++index;
1000 }
1001 _fillItemFamilyInfo(item_data, connected_family_names, connectivity_names);
1002
1003 if (items_local_ids) {
1004 m_deserialized_lids_array.push_back(items_local_ids);
1005 // and that's all, they will be filled in finalizeItemAllocation
1006 }
1007 m_future_item_lids_array.push_back(std::make_shared<PolyhedralTools::ItemLocalIds>());
1008 m_mesh->scheduleAllocateItems(m_family_info, *m_future_item_lids_array.back().get());
1009
1010 // Add serializer in mng. Update is triggered when finalizeItemAllocation is called
1011 m_mng->addSerializer(this);
1012 }
1013
1014 /*---------------------------------------------------------------------------*/
1015 void PolyhedralFamilySerializer::_fillItemData(Int32ConstArrayView items_local_ids)
1016 {
1017 m_item_data = ItemData{ items_local_ids.size(), 0, m_family, nullptr, m_family->parallelMng()->commRank() };
1018 Int64Array& item_infos = m_item_data.itemInfos();
1019 Int32ArrayView item_owners = m_item_data.itemOwners();
1020 // Reserve size
1021 const Integer nb_item = items_local_ids.size();
1022 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)
1023 // Fill item data (cf ItemData.h)
1024 PolyhedralMeshImpl* mesh_impl = m_mesh->_impl();
1025 auto connectivities = mesh_impl->connectivities(m_family);
1026 item_infos.add(connectivities.size());
1027 bool is_face_family = m_family->itemKind() == IK_Face;
1028 ENUMERATE_ITEM (item, m_family->view(items_local_ids)) {
1029 item_infos.add(42); // Item type, not used for polyhedral mesh
1030 item_infos.add(item->uniqueId().asInt64());
1031 item_owners[item.index()] = item->owner();
1032 for (auto out_connectivity : connectivities) {
1033 auto target_family = m_mesh->findItemFamily(PolyhedralMeshImpl::itemKindNeoToArcane(out_connectivity.target_family.itemKind()),
1034 out_connectivity.target_family.name(), false, false);
1035 // auto arcane_connected_items = target_family->view();
1036 auto arcane_connected_items = target_family->itemInfoListView();
1037 bool is_face_cell_connection = is_face_family && target_family->itemKind() == IK_Cell;
1038 item_infos.add(PolyhedralMeshImpl::itemKindNeoToArcane(out_connectivity.target_family.itemKind()));
1039 auto connected_items = out_connectivity[item.localId()];
1040 auto nb_connected_items = connected_items.size();
1041 item_infos.add(nb_connected_items);
1042 if (is_face_cell_connection && item->itemBase().isBoundary() && item->itemBase().backCell().isNull()) {
1043 item_infos.add(NULL_ITEM_UNIQUE_ID);
1044 }
1045 for (auto connected_item_lid : connected_items) {
1046 item_infos.add(arcane_connected_items[connected_item_lid].uniqueId().asInt64());
1047 }
1048 if (is_face_cell_connection && item->itemBase().isBoundary() && !item->itemBase().backCell().isNull()) {
1049 item_infos.add(NULL_ITEM_UNIQUE_ID);
1050 }
1051 }
1052 }
1053 }
1054
1055} // End namespace mesh
1056
1057/*---------------------------------------------------------------------------*/
1058/*---------------------------------------------------------------------------*/
1059
1060class mesh::PolyhedralMesh::PolyhedralMeshModifier
1062{
1063 public:
1064
1065 explicit PolyhedralMeshModifier(PolyhedralMesh* mesh)
1066 : m_mesh(mesh)
1067 {}
1068
1069 void addItems(Int64ConstArrayView unique_ids, Int32ArrayView local_ids, eItemKind ik, const String& family_name) override
1070 {
1071 m_mesh->addItems(unique_ids, local_ids, ik, family_name);
1072 }
1073
1074 void addItems(Int64ConstArrayView unique_ids, Int32ArrayView local_ids, Int32ConstArrayView owners, eItemKind ik, const String& family_name) override
1075 {
1076 m_mesh->addItems(unique_ids, local_ids, owners, ik, family_name);
1077 }
1078
1079 void removeItems(Int32ConstArrayView local_ids, eItemKind ik, const String& family_name) override
1080 {
1081 m_mesh->removeItems(local_ids, ik, family_name);
1082 }
1083
1084 private:
1085
1086 PolyhedralMesh* m_mesh;
1087};
1088
1089/*---------------------------------------------------------------------------*/
1090/*---------------------------------------------------------------------------*/
1091
1092class mesh::PolyhedralMesh::InternalApi
1093: public IMeshInternal
1094, public IMeshModifierInternal
1095{
1096 public:
1097
1098 explicit InternalApi(PolyhedralMesh* mesh)
1099 : m_mesh(mesh)
1100 , m_connectivity_mng(std::make_unique<ItemConnectivityMng>(mesh->traceMng()))
1101 , m_polyhedral_mesh_modifier(std::make_unique<PolyhedralMeshModifier>(mesh))
1102 {}
1103
1104 public:
1105
1106 void setMeshKind(const MeshKind& v) override
1107 {
1108 if (v.meshStructure() != eMeshStructure::Polyhedral && v.meshAMRKind() != eMeshAMRKind::None) {
1109 ARCANE_FATAL("Incompatible mesh structure ({0}) and amr kind ({1}) for Polyhedral mesh {2}. Must be (Polyhedral,None). ",
1110 v.meshStructure(), v.meshAMRKind(), m_mesh->name());
1111 }
1112 m_mesh->m_mesh_kind = v;
1113 }
1114
1115 IItemConnectivityMng* dofConnectivityMng() const noexcept override
1116 {
1117 return m_connectivity_mng.get();
1118 }
1119
1120 IPolyhedralMeshModifier* polyhedralMeshModifier() const noexcept override
1121 {
1122 return m_polyhedral_mesh_modifier.get();
1123 }
1124
1125 void removeNeedRemoveMarkedItems() override
1126 {
1127 m_mesh->removeNeedRemoveMarkedItems();
1128 }
1129 NodeLocalId addNode([[maybe_unused]] ItemUniqueId unique_id) override
1130 {
1131 ARCANE_THROW(NotImplementedException, "");
1132 }
1133 FaceLocalId addFace([[maybe_unused]] ItemUniqueId unique_id,
1134 [[maybe_unused]] ItemTypeId type_id,
1135 [[maybe_unused]] ConstArrayView<Int64> nodes_uid) override
1136 {
1137 ARCANE_THROW(NotImplementedException, "");
1138 }
1139 CellLocalId addCell([[maybe_unused]] ItemUniqueId unique_id,
1140 [[maybe_unused]] ItemTypeId type_id,
1141 [[maybe_unused]] ConstArrayView<Int64> nodes_uid) override
1142 {
1143 ARCANE_THROW(NotImplementedException, "");
1144 }
1145
1146 IItemFamilySerializerMngInternal* familySerializerMng() const noexcept override
1147 {
1148 return m_mesh->polyhedralFamilySerializerMng();
1149 }
1150
1151 private:
1152
1153 PolyhedralMesh* m_mesh = nullptr;
1154 std::unique_ptr<IItemConnectivityMng> m_connectivity_mng = nullptr;
1155 std::unique_ptr<IPolyhedralMeshModifier> m_polyhedral_mesh_modifier = nullptr;
1156};
1157
1158/*---------------------------------------------------------------------------*/
1159/*---------------------------------------------------------------------------*/
1160
1161class mesh::PolyhedralMesh::NoCompactionMeshCompacter
1162: public IMeshCompacter
1163{
1164 public:
1165
1166 explicit NoCompactionMeshCompacter(PolyhedralMesh* mesh)
1167 : m_mesh(mesh)
1168 , m_trace_mng(mesh->traceMng())
1169 {}
1170
1171 void doAllActions() override { _info(); };
1172
1173 void beginCompact() override { _info(); };
1174 void compactVariablesAndGroups() override { _info(); };
1175 void updateInternalReferences() override { _info(); };
1176 void endCompact() override { _info(); };
1177 void finalizeCompact() override { _info(); };
1178
1179 IMesh* mesh() const override { return m_mesh; };
1180
1181 const ItemFamilyCompactInfos* findCompactInfos(IItemFamily*) const override
1182 {
1183 _info();
1184 return nullptr;
1185 }
1186
1187 ePhase phase() const override
1188 {
1189 _info();
1190 return ePhase::Ended;
1191 }
1192
1193 void setSorted(bool) override { _info(); };
1194
1195 bool isSorted() const override
1196 {
1197 _info();
1198 return false;
1199 };
1200
1201 ItemFamilyCollection families() const override
1202 {
1203 _info();
1204 return ItemFamilyCollection{};
1205 };
1206
1207 void _setCompactVariablesAndGroups(bool) override { _info(); };
1208
1209 private:
1210
1211 PolyhedralMesh* m_mesh = nullptr;
1212 ITraceMng* m_trace_mng = nullptr;
1213
1214 void _info() const { m_trace_mng->info() << A_FUNCINFO << "No compacting in PolyhedralMesh"; }
1215};
1216
1217/*---------------------------------------------------------------------------*/
1218/*---------------------------------------------------------------------------*/
1219
1220class mesh::PolyhedralMesh::NoCompactionMeshCompactMng
1221: public IMeshCompactMng
1222{
1223 public:
1224
1225 explicit NoCompactionMeshCompactMng(PolyhedralMesh* mesh)
1226 : m_mesh(mesh)
1227 , m_trace_mng(mesh->traceMng())
1228 , m_mesh_compacter{ std::make_unique<NoCompactionMeshCompacter>(m_mesh) }
1229 {}
1230
1231 IMesh* mesh() const override { return m_mesh; }
1232 IMeshCompacter* beginCompact() override
1233 {
1234 _info();
1235 return m_mesh_compacter.get();
1236 }
1237
1238 IMeshCompacter* beginCompact(IItemFamily* family) override
1239 {
1240 ARCANE_UNUSED(family);
1241 _info();
1242 return m_mesh_compacter.get();
1243 };
1244
1245 void endCompact() override { _info(); };
1246
1247 IMeshCompacter* compacter() override
1248 {
1249 _info();
1250 return m_mesh_compacter.get();
1251 };
1252
1253 private:
1254
1255 PolyhedralMesh* m_mesh = nullptr;
1256 ITraceMng* m_trace_mng = nullptr;
1257 std::unique_ptr<IMeshCompacter> m_mesh_compacter = nullptr;
1258
1259 void _info() const { m_trace_mng->info() << A_FUNCINFO << "No compacting in PolyhedralMesh"; }
1260};
1261
1262/*---------------------------------------------------------------------------*/
1263/*---------------------------------------------------------------------------*/
1264
1265mesh::PolyhedralMesh::
1266~PolyhedralMesh()
1267{
1268 m_mesh_handle._setMesh(nullptr);
1269}
1270
1271/*---------------------------------------------------------------------------*/
1272/*---------------------------------------------------------------------------*/
1273
1274ITraceMng* mesh::PolyhedralMesh::
1275traceMng()
1276{
1277 return m_subdomain->traceMng();
1278}
1279
1280/*---------------------------------------------------------------------------*/
1281/*---------------------------------------------------------------------------*/
1282
1283MeshHandle mesh::PolyhedralMesh::
1284handle() const
1285{
1286 return m_mesh_handle;
1287}
1288
1289/*---------------------------------------------------------------------------*/
1290/*---------------------------------------------------------------------------*/
1291mesh::PolyhedralMesh::
1292PolyhedralMesh(ISubDomain* subdomain, const MeshBuildInfo& mbi)
1293: EmptyMesh{ subdomain->traceMng() }
1294, m_name{ mbi.name() }
1295, m_subdomain{ subdomain }
1296, m_mesh_handle{ m_subdomain->defaultMeshHandle() }
1297, m_properties(std::make_unique<Properties>(subdomain->propertyMng(), String("ArcaneMeshProperties_") + m_name))
1298, m_mesh{ std::make_unique<mesh::PolyhedralMeshImpl>(m_subdomain) }
1299, m_parallel_mng{ mbi.parallelMngRef().get() }
1300, m_mesh_part_info{ makeMeshPartInfoFromParallelMng(m_parallel_mng) }
1301, m_item_type_mng(ItemTypeMng::_singleton())
1302, m_mesh_kind(mbi.meshKind())
1303, m_polyhedral_family_serializer_mng{ std::make_unique<PolyhedralFamilySerializerMng>(this) }
1304, m_initial_allocator(*this)
1305, m_variable_mng{ subdomain->variableMng() }
1306, m_mesh_checker{ this }
1307, m_internal_api{ std::make_unique<InternalApi>(this) }
1308, m_compact_mng{ std::make_unique<NoCompactionMeshCompactMng>(this) }
1309, m_mesh_utilities{ std::make_unique<UnstructuredMeshUtilities>(this) }
1310, m_mesh_exchange_mng{ std::make_unique<MeshExchangeMng>(this) }
1311, m_item_family_network{ std::make_unique<ItemFamilyNetwork>(m_trace_mng) }
1312, m_ghost_layer_mng{ std::make_unique<GhostLayerMng>(m_trace_mng) }
1313, m_connectivity(VariableBuildInfo{ subdomain, mbi.name() + "MeshConnectivity" })
1314{
1315 m_mesh_handle._setMesh(this);
1316 m_mesh_item_internal_list.mesh = this;
1317 m_default_arcane_families.fill(nullptr);
1318}
1319
1320/*---------------------------------------------------------------------------*/
1321/*---------------------------------------------------------------------------*/
1322
1323void Arcane::mesh::PolyhedralMesh::
1324allocateItems(const Arcane::ItemAllocationInfo& item_allocation_info)
1325{
1326 _allocateItems(item_allocation_info, ArrayView<Int32UniqueArray>{});
1327}
1328
1329/*---------------------------------------------------------------------------*/
1330
1331void Arcane::mesh::PolyhedralMesh::
1332allocateItems(const Arcane::ItemAllocationInfo& item_allocation_info, ArrayView<Int32UniqueArray> family_lids)
1333{
1334 _allocateItems(item_allocation_info, family_lids);
1335}
1336
1337/*---------------------------------------------------------------------------*/
1338
1339void Arcane::mesh::PolyhedralMesh::
1340_allocateItems(const Arcane::ItemAllocationInfo& item_allocation_info, ArrayView<Int32UniqueArray> family_lids)
1341{
1342 // Second step read a vtk polyhedral mesh
1343 m_subdomain->traceMng()->info() << "--PolyhedralMesh: allocate items --";
1344 UniqueArray<PolyhedralTools::ItemLocalIds> item_local_ids(item_allocation_info.family_infos.size());
1345 auto family_index = 0;
1346 // Prepare item creation
1347 for (auto& family_info : item_allocation_info.family_infos) {
1348 bool create_if_needed = true;
1349 auto* item_family = _findItemFamily(family_info.item_kind, family_info.name, create_if_needed);
1350 m_trace_mng->debug(Trace::High) << "- Create items " << family_info.name;
1351 m_mesh->scheduleAddItems(item_family, family_info.item_uids, family_info.item_owners.constSmallSpan(), item_local_ids[family_index++]);
1352 }
1353 // Prepare connectivity creation
1354 family_index = 0;
1355 for (auto& family_info : item_allocation_info.family_infos) {
1356 auto* item_family = _findItemFamily(family_info.item_kind, family_info.name);
1357 m_trace_mng->debug(Trace::High) << "- Current family " << family_info.name;
1358 for (auto& current_connected_family_info : family_info.connected_family_infos) {
1359 auto connected_family = _findItemFamily(current_connected_family_info.item_kind, current_connected_family_info.name);
1360 m_trace_mng->debug(Trace::High) << "- Create connectivity " << current_connected_family_info.connectivity_name;
1361 // check if connected family exists
1362 if (!connected_family) {
1363 ARCANE_WARNING((String::format("Cannot find family {0} with kind {1} "
1364 "The connectivity between {1} and this family is skipped",
1365 current_connected_family_info.name,
1366 current_connected_family_info.item_kind,
1367 item_family->name())
1368 .localstr()));
1369 continue;
1370 }
1371 m_mesh->scheduleAddConnectivity(item_family,
1372 item_local_ids[family_index],
1373 current_connected_family_info.nb_connected_items_per_item,
1374 connected_family,
1375 current_connected_family_info.connected_items_uids,
1376 current_connected_family_info.connectivity_name);
1377 Connectivity connectivity{ m_connectivity };
1378 connectivity.enableConnectivity(Connectivity::kindsToConnectivity(item_family->itemKind(), connected_family->itemKind()));
1379 }
1380 ++family_index;
1381 }
1382 // Create items and connectivities
1383 m_mesh->applyScheduledOperations();
1384 // Create variable for coordinates. This has to be done before call to family::endUpdate. Todo add to the graph
1385 for (auto& family_info : item_allocation_info.family_infos) {
1386 if (family_info.item_kind != IK_Node && family_info.item_coordinates.empty()) { // variable is created for node even if no coords (parallel)
1387 continue;
1388 }
1389 auto* item_family = _findItemFamily(family_info.item_kind, family_info.name);
1390 if (item_family == itemFamily(IK_Node)) { // create mesh node coords if doesn't exist
1391 if (!m_arcane_node_coords.get()) {
1392 m_arcane_node_coords = std::make_unique<VariableNodeReal3>(VariableBuildInfo(this, family_info.item_coordinates_variable_name));
1393 m_arcane_node_coords->setUsed(true);
1394 }
1395 }
1396 else {
1397 auto arcane_item_coords_var_ptr = std::make_unique<VariableItemReal3>(VariableBuildInfo(this, family_info.item_coordinates_variable_name),
1398 item_family->itemKind());
1399 arcane_item_coords_var_ptr->setUsed(true);
1400 m_arcane_item_coords.push_back(std::move(arcane_item_coords_var_ptr));
1401 }
1402 }
1403 // Call Arcane ItemFamily endUpdate
1404 for (auto& family : m_arcane_families) {
1405 family->endUpdate();
1406 }
1407 endUpdate();
1408 // Add coordinates when needed (nodes, or dof, or particles...)
1409 family_index = 0;
1410 auto index = 0;
1411 for (auto& family_info : item_allocation_info.family_infos) {
1412 if (family_info.item_coordinates.empty()) {
1413 ++family_index;
1414 continue;
1415 }
1416 auto* item_family = _findItemFamily(family_info.item_kind, family_info.name);
1417 if (item_family == itemFamily(IK_Node)) { // mesh node coords
1418 m_mesh->scheduleSetItemCoordinates(item_family, item_local_ids[family_index], family_info.item_coordinates, *m_arcane_node_coords);
1419 }
1420 else
1421 m_mesh->scheduleSetItemCoordinates(item_family, item_local_ids[family_index], family_info.item_coordinates, *m_arcane_item_coords[index++].get());
1422 }
1423 auto mesh_state = m_mesh->applyScheduledOperations();
1424 m_is_allocated = true;
1425 // indicates mesh contains general Cells
1426 itemTypeMng()->setMeshWithGeneralCells(this);
1427
1428 if (!family_lids.empty()) {
1429 auto index = 0;
1430 ARCANE_ASSERT((family_lids.size() == item_local_ids.size()), ("Incoherence in item number"));
1431 for (auto& lid_array : item_local_ids) {
1432 family_lids[index].resize(lid_array.size());
1433 lid_array.fillArrayView(family_lids[index].view(), mesh_state);
1434 ++index;
1435 }
1436 }
1437}
1438
1439/*---------------------------------------------------------------------------*/
1440
1441void Arcane::mesh::PolyhedralMesh::
1442scheduleAllocateItems(const Arcane::ItemAllocationInfo::FamilyInfo& family_info, mesh::PolyhedralTools::ItemLocalIds& item_local_ids)
1443{
1444 // Second step read a vtk polyhedral mesh
1445 m_subdomain->traceMng()->info() << "--PolyhedralMesh: schedule allocate items --";
1446 // Prepare item creation
1447 bool create_if_needed = true;
1448 auto* item_family = _findItemFamily(family_info.item_kind, family_info.name, create_if_needed);
1449 m_trace_mng->debug(Trace::High) << "- Current family " << family_info.name;
1450 m_trace_mng->debug(Trace::High) << "- Create items ";
1451 m_mesh->scheduleAddItems(item_family, family_info.item_uids, family_info.item_owners.constSmallSpan(), item_local_ids);
1452 // Prepare connectivity creation
1453 for (auto& current_connected_family_info : family_info.connected_family_infos) {
1454 auto connected_family = _findItemFamily(current_connected_family_info.item_kind, current_connected_family_info.name);
1455 m_trace_mng->debug(Trace::High) << "- Create connectivity " << current_connected_family_info.connectivity_name;
1456 // check if connected family exists
1457 if (!connected_family) {
1458 ARCANE_WARNING((String::format("Cannot find family {0} with kind {1} "
1459 "The connectivity between {1} and this family is skipped",
1460 current_connected_family_info.name,
1461 current_connected_family_info.item_kind,
1462 item_family->name())
1463 .localstr()));
1464 continue;
1465 }
1466 m_mesh->scheduleUpdateConnectivity(item_family,
1467 item_local_ids,
1468 current_connected_family_info.nb_connected_items_per_item,
1469 connected_family,
1470 current_connected_family_info.connected_items_uids,
1471 current_connected_family_info.connectivity_name);
1472 }
1473}
1474
1475/*---------------------------------------------------------------------------*/
1476
1477void Arcane::mesh::PolyhedralMesh::
1478applyScheduledAllocateItems(UniqueArray<std::shared_ptr<PolyhedralTools::ItemLocalIds>> item_lids)
1479{
1480 // Create items and connectivities
1481 auto mesh_state = m_mesh->applyScheduledOperations();
1482 // Fill item_lids (they are already filled in applyScheduledOperations: unlock them setting the mesh_state)
1483 for (auto item_local_ids : item_lids) {
1484 item_local_ids->m_mesh_state = std::make_shared<Neo::EndOfMeshUpdate>(mesh_state);
1485 }
1486
1487 // Call Arcane ItemFamily endUpdate and mesh end update
1488 for (auto& family : m_arcane_families) {
1489 family->endUpdate();
1490 }
1491 endUpdate();
1492 m_is_allocated = true;
1493 // indicates mesh contains general Cells
1494 itemTypeMng()->setMeshWithGeneralCells(this);
1495}
1496
1497/*---------------------------------------------------------------------------*/
1498
1499void mesh::PolyhedralMesh::removeNeedRemoveMarkedItems()
1500{
1501 // Loop through all item families in the mesh: must include DoF and Particles
1502 for (auto family_index = 0; family_index < m_arcane_families.size(); ++family_index) {
1503 // Get the list of local IDs for items to remove
1504 auto* family = m_arcane_families[family_index].get();
1505 Int32UniqueArray items_to_remove;
1506 items_to_remove.reserve(family->nbItem());
1507 auto& items_map = family->itemsMap();
1508 if (items_map.count() == 0)
1509 continue;
1510 items_map.eachItem([&](ItemBase item) {
1511 // Schedule removal of items marked for removal
1512 auto f = item.flags();
1513 if (f & ItemFlags::II_NeedRemove) {
1514 f &= ~ItemFlags::II_NeedRemove & ItemFlags::II_Suppressed;
1515 item.toMutable().setFlags(f);
1516 items_to_remove.add(item.localId());
1517 }
1518 });
1519 if (!items_to_remove.empty()) {
1520 removeItems(items_to_remove, family);
1521 }
1522 }
1523}
1524
1525/*---------------------------------------------------------------------------*/
1526
1527Arcane::mesh::PolyhedralFamilySerializerMng* mesh::PolyhedralMesh::
1528polyhedralFamilySerializerMng()
1529{
1530 return m_polyhedral_family_serializer_mng.get();
1531}
1532
1533/*---------------------------------------------------------------------------*/
1534/*---------------------------------------------------------------------------*/
1535
1536void Arcane::mesh::PolyhedralMesh::
1537_endUpdateFamilies()
1538{
1539 for (auto& family : m_arcane_families) {
1540 family->endUpdate();
1541 }
1542}
1543
1544/*---------------------------------------------------------------------------*/
1545/*---------------------------------------------------------------------------*/
1546
1547void Arcane::mesh::PolyhedralMesh::
1548_computeFamilySynchronizeInfos()
1549{
1550 m_subdomain->traceMng()->info() << "Computing family synchronization information for " << name();
1551 for (auto& family : m_arcane_families) {
1552 family->computeSynchronizeInfos();
1553 }
1554
1555 // Write topology for cell synchronization
1556 if (!platform::getEnvironmentVariable("ARCANE_DUMP_VARIABLE_SYNCHRONIZER_TOPOLOGY").null()) {
1557 auto* var_syncer = cellFamily()->allItemsSynchronizer();
1558 Int32 iteration = m_subdomain->commonVariables().globalIteration();
1559 String file_name = String::format("{0}_sync_topology_iter{1}.json", name(), iteration);
1560 mesh_utils::dumpSynchronizerTopologyJSON(var_syncer, file_name);
1561 }
1562}
1563
1564/*---------------------------------------------------------------------------*/
1565/*---------------------------------------------------------------------------*/
1566
1567void Arcane::mesh::PolyhedralMesh::
1568_notifyEndUpdateForFamilies()
1569{
1570 for (auto& family : m_arcane_families)
1571 family->_internalApi()->notifyEndUpdateFromMesh();
1572}
1573
1574/*---------------------------------------------------------------------------*/
1575/*---------------------------------------------------------------------------*/
1576
1577void Arcane::mesh::PolyhedralMesh::
1578_computeGroupSynchronizeInfos()
1579{
1580 auto action = [](ItemGroup& group) {
1581 if (group.hasSynchronizer())
1582 group.synchronizer()->compute();
1583 };
1584
1585 m_trace_mng->info() << "Computing group synchronization information for " << name();
1586 meshvisitor::visitGroups(this, action);
1587}
1588
1589/*---------------------------------------------------------------------------*/
1590/*---------------------------------------------------------------------------*/
1591
1593name() const
1594{
1595 return m_name;
1596}
1597
1598/*---------------------------------------------------------------------------*/
1599/*---------------------------------------------------------------------------*/
1600
1602dimension()
1603{
1604 return m_mesh->dimension();
1605}
1606
1607/*---------------------------------------------------------------------------*/
1608/*---------------------------------------------------------------------------*/
1609
1611nbNode()
1612{
1613 return m_mesh->nbNode();
1614}
1615
1616/*---------------------------------------------------------------------------*/
1617/*---------------------------------------------------------------------------*/
1618
1620nbEdge()
1621{
1622 return m_mesh->nbEdge();
1623}
1624
1625/*---------------------------------------------------------------------------*/
1626/*---------------------------------------------------------------------------*/
1627
1629nbFace()
1630{
1631 return m_mesh->nbFace();
1632}
1633
1634/*---------------------------------------------------------------------------*/
1635/*---------------------------------------------------------------------------*/
1636
1638nbCell()
1639{
1640 return m_mesh->nbCell();
1641}
1642
1643/*---------------------------------------------------------------------------*/
1644/*---------------------------------------------------------------------------*/
1645
1647nbItem(eItemKind ik)
1648{
1649 return m_mesh->nbItem(ik);
1650}
1651
1652/*---------------------------------------------------------------------------*/
1653/*---------------------------------------------------------------------------*/
1654
1656allNodes()
1657{
1658 if (m_default_arcane_families[IK_Node])
1659 return m_default_arcane_families[IK_Node]->allItems();
1660 else
1661 return NodeGroup{};
1662}
1663
1664/*---------------------------------------------------------------------------*/
1665/*---------------------------------------------------------------------------*/
1666
1668allEdges()
1669{
1670 if (m_default_arcane_families[IK_Edge])
1671 return m_default_arcane_families[IK_Edge]->allItems();
1672 else
1673 return EdgeGroup{};
1674}
1675
1676/*---------------------------------------------------------------------------*/
1677/*---------------------------------------------------------------------------*/
1678
1680allFaces()
1681{
1682 if (m_default_arcane_families[IK_Face])
1683 return m_default_arcane_families[IK_Face]->allItems();
1684 else
1685 return FaceGroup{};
1686}
1687
1688/*---------------------------------------------------------------------------*/
1689/*---------------------------------------------------------------------------*/
1690
1692allCells()
1693{
1694 if (m_default_arcane_families[IK_Cell])
1695 return m_default_arcane_families[IK_Cell]->allItems();
1696 else
1697 return CellGroup{};
1698}
1699
1700/*---------------------------------------------------------------------------*/
1701/*---------------------------------------------------------------------------*/
1702
1704ownNodes()
1705{
1706 if (m_default_arcane_families[IK_Node])
1707 return m_default_arcane_families[IK_Node]->allItems().own();
1708 else
1709 return NodeGroup{};
1710}
1711
1712/*---------------------------------------------------------------------------*/
1713/*---------------------------------------------------------------------------*/
1714
1716ownEdges()
1717{
1718 if (m_default_arcane_families[IK_Edge])
1719 return m_default_arcane_families[IK_Edge]->allItems().own();
1720 else
1721 return EdgeGroup{};
1722}
1723
1724/*---------------------------------------------------------------------------*/
1725/*---------------------------------------------------------------------------*/
1726
1728ownFaces()
1729{
1730 if (m_default_arcane_families[IK_Face])
1731 return m_default_arcane_families[IK_Face]->allItems().own();
1732 else
1733 return FaceGroup{};
1734}
1735
1736/*---------------------------------------------------------------------------*/
1737/*---------------------------------------------------------------------------*/
1738
1740ownCells()
1741{
1742 if (m_default_arcane_families[IK_Cell])
1743 return m_default_arcane_families[IK_Cell]->allItems().own();
1744 else
1745 return CellGroup{};
1746}
1747
1748/*---------------------------------------------------------------------------*/
1749/*---------------------------------------------------------------------------*/
1750
1752outerFaces()
1753{
1754 if (m_default_arcane_families[IK_Cell])
1755 return m_default_arcane_families[IK_Cell]->allItems().outerFaceGroup();
1756 else
1757 return FaceGroup{};
1758}
1759
1760/*---------------------------------------------------------------------------*/
1761/*---------------------------------------------------------------------------*/
1762
1763mesh::PolyhedralFamily* mesh::PolyhedralMesh::
1764_createItemFamily(eItemKind ik, const String& name)
1765{
1766 m_mesh->addFamily(ik, name);
1767 m_arcane_families.push_back(std::make_unique<PolyhedralFamily>(this, ik, name));
1768 auto current_family = m_arcane_families.back().get();
1769 if (m_default_arcane_families[ik] == nullptr) {
1770 m_default_arcane_families[ik] = current_family;
1771 _updateMeshInternalList(ik);
1772 }
1773 m_item_family_collection.add(current_family);
1774 current_family->build();
1775 return current_family;
1776}
1777
1778/*---------------------------------------------------------------------------*/
1779/*---------------------------------------------------------------------------*/
1780
1781IItemFamily* mesh::PolyhedralMesh::
1782createItemFamily(eItemKind ik, const String& name)
1783{
1784 return _createItemFamily(ik, name);
1785}
1786
1787/*---------------------------------------------------------------------------*/
1788/*---------------------------------------------------------------------------*/
1789
1790void mesh::PolyhedralMesh::
1791_createUnitMesh()
1792{
1793 createItemFamily(IK_Cell, "CellFamily");
1794 createItemFamily(IK_Node, "NodeFamily");
1795 auto cell_family = m_default_arcane_families[IK_Cell];
1796 auto node_family = m_default_arcane_families[IK_Node];
1797 Int64UniqueArray cell_uids{ 0 }, node_uids{ 0, 1, 2, 3, 4, 5 };
1798 // todo add a cell_lids struct (containing future)
1799 PolyhedralTools::ItemLocalIds cell_lids, node_lids;
1800 m_mesh->scheduleAddItems(cell_family, cell_uids.constView(), cell_lids);
1801 m_mesh->scheduleAddItems(node_family, node_uids.constView(), node_lids);
1802 int nb_node = 6;
1803 Int64UniqueArray node_cells_uids{ 0, 0, 0, 0, 0, 0 };
1804 m_mesh->scheduleAddConnectivity(cell_family, cell_lids, nb_node, node_family, node_uids, String{ "CellToNodes" });
1805 m_mesh->scheduleAddConnectivity(node_family, node_lids, 1, cell_family,
1806 node_cells_uids, String{ "NodeToCells" });
1807 m_mesh->applyScheduledOperations();
1808 cell_family->endUpdate();
1809 node_family->endUpdate();
1810 endUpdate();
1811 // Mimic what IMeshModifier::endUpdate would do => default families are completed.
1812 // Families created after a first endUpdate call are not default families
1813}
1814
1815/*---------------------------------------------------------------------------*/
1816/*---------------------------------------------------------------------------*/
1817
1819endUpdate()
1820{
1821 // create empty default families not already created
1822 for (auto ik = 0; ik < NB_ITEM_KIND; ++ik) {
1823 if (m_default_arcane_families[ik] == nullptr && ik != eItemKind::IK_DoF) {
1824 String name = String::concat(itemKindName((eItemKind)ik), "EmptyFamily");
1825 m_empty_arcane_families[ik] = std::make_unique<mesh::PolyhedralFamily>(this, (eItemKind)ik, name);
1826 m_default_arcane_families[ik] = m_empty_arcane_families[ik].get();
1827 }
1828 }
1829}
1830
1831/*---------------------------------------------------------------------------*/
1832/*---------------------------------------------------------------------------*/
1833
1834IItemFamily* mesh::PolyhedralMesh::
1835nodeFamily()
1836{
1837 return m_default_arcane_families[IK_Node];
1838}
1839
1840/*---------------------------------------------------------------------------*/
1841/*---------------------------------------------------------------------------*/
1842
1843IItemFamily* mesh::PolyhedralMesh::
1844edgeFamily()
1845{
1846 return m_default_arcane_families[IK_Edge];
1847}
1848
1849/*---------------------------------------------------------------------------*/
1850/*---------------------------------------------------------------------------*/
1851
1852IItemFamily* mesh::PolyhedralMesh::
1853faceFamily()
1854{
1855 return m_default_arcane_families[IK_Face];
1856}
1857
1858/*---------------------------------------------------------------------------*/
1859/*---------------------------------------------------------------------------*/
1860
1861IItemFamily* mesh::PolyhedralMesh::
1862cellFamily()
1863{
1864 return m_default_arcane_families[IK_Cell];
1865}
1866
1867void mesh::PolyhedralMesh::
1868_updateMeshInternalList(eItemKind kind)
1869{
1870 switch (kind) {
1871 case IK_Cell:
1872 m_mesh_item_internal_list.cells = m_default_arcane_families[kind]->itemsInternal();
1873 m_mesh_item_internal_list._internalSetCellSharedInfo(m_default_arcane_families[kind]->commonItemSharedInfo());
1874 break;
1875 case IK_Face:
1876 m_mesh_item_internal_list.faces = m_default_arcane_families[kind]->itemsInternal();
1877 m_mesh_item_internal_list._internalSetFaceSharedInfo(m_default_arcane_families[kind]->commonItemSharedInfo());
1878 break;
1879 case IK_Edge:
1880 m_mesh_item_internal_list.edges = m_default_arcane_families[kind]->itemsInternal();
1881 m_mesh_item_internal_list._internalSetEdgeSharedInfo(m_default_arcane_families[kind]->commonItemSharedInfo());
1882 break;
1883 case IK_Node:
1884 m_mesh_item_internal_list.nodes = m_default_arcane_families[kind]->itemsInternal();
1885 m_mesh_item_internal_list._internalSetNodeSharedInfo(m_default_arcane_families[kind]->commonItemSharedInfo());
1886 break;
1887 case IK_DoF:
1888 case IK_Particle:
1889 case IK_Unknown:
1890 break;
1891 }
1892}
1893
1894/*---------------------------------------------------------------------------*/
1895/*---------------------------------------------------------------------------*/
1896
1897mesh::PolyhedralFamily* mesh::PolyhedralMesh::
1898_itemFamily(eItemKind ik)
1899{
1900 return m_default_arcane_families[ik];
1901}
1902
1903/*---------------------------------------------------------------------------*/
1904/*---------------------------------------------------------------------------*/
1905
1906IItemFamily* mesh::PolyhedralMesh::
1908{
1909 return _itemFamily(ik);
1910}
1911
1912/*---------------------------------------------------------------------------*/
1913/*---------------------------------------------------------------------------*/
1914
1915ItemTypeMng* mesh::PolyhedralMesh::
1916itemTypeMng() const
1917{
1918 return m_item_type_mng;
1919}
1920
1921/*---------------------------------------------------------------------------*/
1922/*---------------------------------------------------------------------------*/
1923
1924mesh::PolyhedralFamily* mesh::PolyhedralMesh::
1925_findItemFamily(eItemKind ik, const String& name, bool create_if_needed)
1926{
1927 // Check if is a default family
1928 auto found_family = _itemFamily(ik);
1929 if (found_family) {
1930 if (found_family->name() == name)
1931 return found_family;
1932 }
1933 for (auto& family : m_arcane_families) {
1934 if (family->itemKind() == ik && family->name() == name)
1935 return family.get();
1936 }
1937 if (!create_if_needed)
1938 return nullptr;
1939 return _createItemFamily(ik, name);
1940}
1941
1942/*---------------------------------------------------------------------------*/
1943/*---------------------------------------------------------------------------*/
1944
1945IItemFamily* mesh::PolyhedralMesh::
1946findItemFamily(eItemKind ik, const String& name, bool create_if_needed, bool register_modifier_if_created)
1947{
1948 ARCANE_UNUSED(register_modifier_if_created); // IItemFamilyModifier not yet used in polyhedral mesh
1949 return _findItemFamily(ik, name, create_if_needed);
1950}
1951
1952/*---------------------------------------------------------------------------*/
1953/*---------------------------------------------------------------------------*/
1954
1955mesh::PolyhedralFamily* mesh::PolyhedralMesh::
1956arcaneDefaultFamily(eItemKind ik)
1957{
1958 return m_default_arcane_families[ik];
1959}
1960
1961/*---------------------------------------------------------------------------*/
1962/*---------------------------------------------------------------------------*/
1963
1966{
1967 ARCANE_ASSERT(m_arcane_node_coords, ("Node coordinates not yet loaded."));
1968 return *m_arcane_node_coords;
1969}
1970
1971/*---------------------------------------------------------------------------*/
1972/*---------------------------------------------------------------------------*/
1973
1974ItemGroup mesh::PolyhedralMesh::
1975findGroup(const String& name)
1976{
1977 ItemGroup group;
1978 for (auto& family : m_arcane_families) {
1979 group = family->findGroup(name);
1980 if (!group.null())
1981 return group;
1982 }
1983 return group;
1984}
1985
1986/*---------------------------------------------------------------------------*/
1987/*---------------------------------------------------------------------------*/
1988
1990groups()
1991{
1992 m_all_groups.clear();
1993 for (auto& family : m_arcane_families) {
1994 for (ItemGroupCollection::Enumerator i_group(family->groups()); ++i_group;)
1995 m_all_groups.add(*i_group);
1996 }
1997 return m_all_groups;
1998}
1999
2000/*---------------------------------------------------------------------------*/
2001/*---------------------------------------------------------------------------*/
2002
2005{
2006 for (auto& family : m_arcane_families) {
2007 family->destroyGroups();
2008 }
2009}
2010
2011/*---------------------------------------------------------------------------*/
2012/*---------------------------------------------------------------------------*/
2013
2014IItemFamilyCollection mesh::PolyhedralMesh::
2015itemFamilies()
2016{
2017 return m_item_family_collection;
2018}
2019
2020/*---------------------------------------------------------------------------*/
2021/*---------------------------------------------------------------------------*/
2022
2023IMeshInternal* mesh::PolyhedralMesh::
2025{
2026 return m_internal_api.get();
2027}
2028
2029/*---------------------------------------------------------------------------*/
2030/*---------------------------------------------------------------------------*/
2031
2032IMeshCompactMng* mesh::PolyhedralMesh::
2034{
2035 return m_compact_mng.get();
2036}
2037
2038/*---------------------------------------------------------------------------*/
2039/*---------------------------------------------------------------------------*/
2040
2041void mesh::PolyhedralMesh::
2042addItems(Int64ConstArrayView unique_ids, Int32ArrayView local_ids, eItemKind ik, const String& family_name)
2043{
2044 ARCANE_ASSERT((unique_ids.size() == local_ids.size()), ("local and unique ids arrays must have same size"))
2045 auto* item_family = _findItemFamily(ik, family_name, false);
2046 PolyhedralTools::ItemLocalIds item_local_ids;
2047 m_mesh->scheduleAddItems(item_family, unique_ids, item_local_ids);
2048 auto mesh_state = m_mesh->applyScheduledOperations();
2049 item_local_ids.fillArrayView(local_ids, mesh_state);
2050}
2051
2052/*---------------------------------------------------------------------------*/
2053/*---------------------------------------------------------------------------*/
2054
2055void mesh::PolyhedralMesh::
2056addItems(Int64ConstArrayView unique_ids, Int32ArrayView local_ids, Int32ConstArrayView owners, eItemKind ik, const String& family_name)
2057{
2058 ARCANE_ASSERT((unique_ids.size() == local_ids.size() && (unique_ids.size() == owners.size())), ("local/unique ids and owners arrays must have same size"))
2059 auto* item_family = _findItemFamily(ik, family_name, false);
2060 PolyhedralTools::ItemLocalIds item_local_ids;
2061 m_mesh->scheduleAddItems(item_family, unique_ids, owners, item_local_ids);
2062 auto mesh_state = m_mesh->applyScheduledOperations();
2063 item_local_ids.fillArrayView(local_ids, mesh_state);
2064}
2065
2066/*---------------------------------------------------------------------------*/
2067/*---------------------------------------------------------------------------*/
2068
2069void mesh::PolyhedralMesh::
2070removeItems(Int32ConstArrayView local_ids, eItemKind ik, const String& family_name)
2071{
2072 auto* item_family = _findItemFamily(ik, family_name, false);
2073 if (!item_family) {
2074 ARCANE_FATAL("ItemFamily with name {0} and kind {1} does not exist in the mesh.", family_name, ik);
2075 }
2076 m_mesh->scheduleRemoveItems(item_family, local_ids);
2077 m_mesh->applyScheduledOperations();
2078}
2079
2080/*---------------------------------------------------------------------------*/
2081/*---------------------------------------------------------------------------*/
2082
2083void mesh::PolyhedralMesh::
2084removeItems(Int32ConstArrayView local_ids, IItemFamily* family)
2085{
2086 if (local_ids.empty())
2087 return;
2088 if (!family) {
2089 ARCANE_FATAL("Invalid IItemFamily passed to removeItems.");
2090 }
2091 removeItems(local_ids, family->itemKind(), family->name());
2092}
2093
2094/*---------------------------------------------------------------------------*/
2095/*---------------------------------------------------------------------------*/
2096
2098addNodes(Int64ConstArrayView nodes_uid, Int32ArrayView nodes_lid)
2099{
2100 addItems(nodes_uid, nodes_lid, IK_Node, nodeFamily()->name());
2101}
2102
2103/*---------------------------------------------------------------------------*/
2104/*---------------------------------------------------------------------------*/
2105
2108{
2109 m_trace_mng->info() << "PolyhedralMesh::_exchangeItems() do_compact?=" << "false"
2110 << " nb_exchange=" << 0 << " version=" << 0;
2111 _exchangeItems();
2112 String check_exchange = platform::getEnvironmentVariable("ARCANE_CHECK_EXCHANGE");
2113 if (!check_exchange.null()) {
2114 m_mesh_checker.checkGhostCells();
2115 m_trace_mng->pwarning() << "CHECKING SYNCHRONISATION !";
2116 m_mesh_checker.checkVariablesSynchronization();
2117 m_mesh_checker.checkItemGroupsSynchronization();
2118 }
2119 if (checkLevel() >= 2)
2120 m_mesh_checker.checkValidMesh();
2121 else if (checkLevel() >= 1)
2122 m_mesh_checker.checkValidConnectivity();
2123}
2124
2125/*---------------------------------------------------------------------------*/
2126/*---------------------------------------------------------------------------*/
2127
2128void mesh::PolyhedralMesh::
2129_exchangeItems()
2130{
2131 // todo handle submeshes, cf. DynamicMesh
2132
2133 Trace::Setter mci(traceMng(), _className());
2134
2135 if (!m_is_dynamic)
2136 ARCANE_FATAL("property isDynamic() has to be 'true'");
2137
2138 if (arcane_debug_load_balancing) {
2139 for (auto& family : m_arcane_families) {
2140 family->itemsNewOwner().checkIfSync();
2141 }
2142 }
2143
2144 IMeshExchanger* iexchanger = m_mesh_exchange_mng->beginExchange();
2145
2146 // If no entity to exchange return
2147 if (iexchanger->computeExchangeInfos()) {
2148 m_trace_mng->pwarning() << "No load balance is performed";
2149 m_mesh_exchange_mng->endExchange();
2150 return;
2151 }
2152
2153 // Do exchange info
2154 iexchanger->processExchange();
2155
2156 // Remove items no longer on the current subdomain
2157 iexchanger->removeNeededItems();
2158
2159 // Update groups : remove gone entities
2160 // invalidate computed groups
2161 {
2162 auto action = [](ItemGroup& group) {
2163 if (group.internal()->hasComputeFunctor() || group.isLocalToSubDomain())
2164 group.invalidate();
2165 else
2166 group.internal()->removeSuppressedItems();
2167 };
2168 meshvisitor::visitGroups(this, action);
2169 }
2170
2171 iexchanger->allocateReceivedItems();
2172
2173 // Equivalent of DynamicMesh::_internalEndUpdateInit
2174 _endUpdateFamilies();
2175 _computeFamilySynchronizeInfos();
2176
2177 // Update groups
2178 iexchanger->updateItemGroups();
2179
2180 _computeGroupSynchronizeInfos();
2181
2182 iexchanger->updateVariables();
2183
2184 // Equivalent DynamicMesh::_internalEndUpdateFinal(bool)
2185 // check mesh is conform with reference (complete sequential connectivity on a file)
2186 m_mesh_checker.checkMeshFromReferenceFile();
2187 _notifyEndUpdateForFamilies();
2188
2189 iexchanger->finalizeExchange();
2190
2191 m_mesh_exchange_mng->endExchange();
2192
2193 // // todo handle extra ghost
2194 // if (m_extra_ghost_cells_builder->hasBuilder() || m_extra_ghost_particles_builder->hasBuilder())
2195 // this->endUpdate(true,false);
2196 // else
2197 this->endUpdate();
2198}
2199
2200/*---------------------------------------------------------------------------*/
2201/*---------------------------------------------------------------------------*/
2202
2205{
2206 // do nothing for now
2207 auto want_dump = false;
2208 auto need_compact = false;
2209 m_trace_mng->info(4) << "DynamicMesh::prepareForDump() name=" << name()
2210 << " need_compact?=" << need_compact
2211 << " want_dump?=" << want_dump
2212 << " timestamp=" << 0;
2213
2214 {
2216 m_mesh_events.eventObservable(t).notify(MeshEventArgs(this, t));
2217 }
2218
2219 // todo use Properties
2220 if (want_dump) {
2221 for (auto& family : m_arcane_families) {
2222 family->prepareForDump();
2223 }
2224 }
2225
2226 {
2228 m_mesh_events.eventObservable(t).notify(MeshEventArgs(this, t));
2229 }
2230}
2231
2232/*---------------------------------------------------------------------------*/
2233/*---------------------------------------------------------------------------*/
2234
2237{
2238 return allCells().activeCellGroup();
2239}
2240
2241/*---------------------------------------------------------------------------*/
2242/*---------------------------------------------------------------------------*/
2243
2245{
2246 return allCells().ownActiveCellGroup();
2247}
2248
2249/*---------------------------------------------------------------------------*/
2250/*---------------------------------------------------------------------------*/
2251
2253allLevelCells(const Integer& level)
2254{
2255 return allCells().levelCellGroup(level);
2256}
2257
2258/*---------------------------------------------------------------------------*/
2259/*---------------------------------------------------------------------------*/
2260
2262ownLevelCells(const Integer& level)
2263{
2264 return allCells().ownLevelCellGroup(level);
2265}
2266
2267/*---------------------------------------------------------------------------*/
2268/*---------------------------------------------------------------------------*/
2269
2272{
2273 return allCells().activeFaceGroup();
2274}
2275
2276/*---------------------------------------------------------------------------*/
2277/*---------------------------------------------------------------------------*/
2278
2281{
2282 return allCells().ownActiveFaceGroup();
2283}
2284
2285/*---------------------------------------------------------------------------*/
2286/*---------------------------------------------------------------------------*/
2287
2290{
2291 return allCells().innerActiveFaceGroup();
2292}
2293
2294/*---------------------------------------------------------------------------*/
2295/*---------------------------------------------------------------------------*/
2296
2299{
2300 return allCells().outerActiveFaceGroup();
2301}
2302
2303/*---------------------------------------------------------------------------*/
2304/*---------------------------------------------------------------------------*/
2305
2306IMeshUtilities* mesh::PolyhedralMesh::
2307utilities()
2308{
2309 return m_mesh_utilities.get();
2310}
2311
2312/*---------------------------------------------------------------------------*/
2313/*---------------------------------------------------------------------------*/
2314
2317{
2318 IItemFamily* item_family = _itemFamily(ik);
2319 ARCANE_CHECK_POINTER(item_family);
2320 return item_family->itemsNewOwner();
2321}
2322
2323/*---------------------------------------------------------------------------*/
2324/*---------------------------------------------------------------------------*/
2325
2327checkLevel() const
2328{
2329 return m_mesh_checker.checkLevel();
2330}
2331
2332/*---------------------------------------------------------------------------*/
2333/*---------------------------------------------------------------------------*/
2334
2335IItemFamilyNetwork* mesh::PolyhedralMesh::
2337{
2338 return m_item_family_network.get();
2339}
2340
2341/*---------------------------------------------------------------------------*/
2342/*---------------------------------------------------------------------------*/
2343
2344IGhostLayerMng* mesh::PolyhedralMesh::
2345ghostLayerMng() const
2346{
2347 return m_ghost_layer_mng.get();
2348}
2349
2350/*---------------------------------------------------------------------------*/
2351/*---------------------------------------------------------------------------*/
2352
2353IMeshModifierInternal* mesh::PolyhedralMesh::
2355{
2356 return m_internal_api.get();
2357}
2358
2359/*---------------------------------------------------------------------------*/
2360/*---------------------------------------------------------------------------*/
2361
2362mesh::PolyhedralMeshImpl* mesh::PolyhedralMesh::_impl()
2363{
2364 return m_mesh.get();
2365}
2366
2367/*---------------------------------------------------------------------------*/
2368/*---------------------------------------------------------------------------*/
2369
2370} // End namespace Arcane
2371
2372/*---------------------------------------------------------------------------*/
2373/*---------------------------------------------------------------------------*/
2374
2375#else // ARCANE_HAS_POLYHEDRAL_MESH_TOOLS
2376
2377/*---------------------------------------------------------------------------*/
2378/*---------------------------------------------------------------------------*/
2379
2380namespace Arcane::mesh
2381{
2384} // namespace Arcane::mesh
2385
2386/*---------------------------------------------------------------------------*/
2387/*---------------------------------------------------------------------------*/
2388
2389Arcane::mesh::PolyhedralMesh::
2390~PolyhedralMesh() = default;
2391
2392/*---------------------------------------------------------------------------*/
2393/*---------------------------------------------------------------------------*/
2394
2395Arcane::mesh::PolyhedralMesh::
2396PolyhedralMesh(ISubDomain* subdomain, const MeshBuildInfo& mbi)
2397: EmptyMesh{ subdomain->traceMng() }
2398, m_subdomain{ subdomain }
2399, m_mesh{ nullptr }
2400, m_mesh_kind(mbi.meshKind())
2401{
2402}
2403
2404/*---------------------------------------------------------------------------*/
2405/*---------------------------------------------------------------------------*/
2406
2407void Arcane::mesh::PolyhedralMesh::
2408read([[maybe_unused]] const String& filename)
2409{
2410 _errorEmptyMesh();
2411}
2412
2413/*---------------------------------------------------------------------------*/
2414/*---------------------------------------------------------------------------*/
2415
2416void Arcane::mesh::PolyhedralMesh::
2417allocateItems(const Arcane::ItemAllocationInfo& item_allocation_info)
2418{
2419 ARCANE_UNUSED(item_allocation_info);
2420 _errorEmptyMesh();
2421}
2422
2423/*---------------------------------------------------------------------------*/
2424/*---------------------------------------------------------------------------*/
2425
2426#endif // ARCANE_HAS_POLYHEDRAL_MESH_TOOLS
2427
2428/*---------------------------------------------------------------------------*/
2429/*---------------------------------------------------------------------------*/
2430
2431namespace Arcane
2432{
2433
2434class ARCANE_MESH_EXPORT PolyhedralMeshFactory
2435: public AbstractService
2436, public IMeshFactory
2437{
2438 public:
2439
2440 explicit PolyhedralMeshFactory(const ServiceBuildInfo& sbi)
2441 : AbstractService(sbi)
2442 {}
2443
2444 public:
2445
2446 void build() override {}
2447 IPrimaryMesh* createMesh(IMeshMng* mm, const MeshBuildInfo& build_info) override
2448 {
2450 return new mesh::PolyhedralMesh(sd, build_info);
2451 }
2452
2453 static String name() { return "ArcanePolyhedralMeshFactory"; }
2454};
2455
2457 ServiceProperty(PolyhedralMeshFactory::name().localstr(), ST_Application),
2459
2460/*---------------------------------------------------------------------------*/
2461/*---------------------------------------------------------------------------*/
2462
2463#if ARCANE_HAS_POLYHEDRAL_MESH_TOOLS
2464
2465/*---------------------------------------------------------------------------*/
2466/*---------------------------------------------------------------------------*/
2467
2469factoryName() const
2470{
2471 return PolyhedralMeshFactory::name();
2472}
2473
2474/*---------------------------------------------------------------------------*/
2475/*---------------------------------------------------------------------------*/
2476
2477#endif // ARCANE_HAS_POLYHEDRAL_MESH_TOOLS
2478
2479/*---------------------------------------------------------------------------*/
2480/*---------------------------------------------------------------------------*/
2481
2482} // End namespace Arcane
2483
2484/*---------------------------------------------------------------------------*/
2485/*---------------------------------------------------------------------------*/
#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:75
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_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:125
UniqueArray< Int64 > Int64UniqueArray
Dynamic 1D array of 64-bit integers.
Definition UtilsTypes.h:339
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:482
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:480
SmallSpan< const Real3 > Real3ConstSmallSpan
Read-only view of a 1D array of Real3.
Definition UtilsTypes.h:632
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:341
ArrayView< Int32 > Int32ArrayView
C equivalent of a 1D array of 32-bit integers.
Definition UtilsTypes.h:453
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:616
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:127
UniqueArray< String > StringUniqueArray
Dynamic 1D array of strings.
Definition UtilsTypes.h:359
Span< const Int32 > Int32ConstSpan
Read-only view of a 1D array of 32-bit integers.
Definition UtilsTypes.h:554
SmallSpan< const Int32 > Int32ConstSmallSpan
Read-only view of a 1D array of 32-bit integers.
Definition UtilsTypes.h:618
std::int32_t Int32
Signed integer type of 32 bits.