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