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