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