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