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