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