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