Arcane  4.1.12.0
Developer documentation
Loading...
Searching...
No Matches
ItemFamily.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/* ItemFamily.cc (C) 2000-2026 */
9/* */
10/* Mesh info for a given type of entity. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/utils/FatalErrorException.h"
15#include "arcane/utils/ITraceMng.h"
16#include "arcane/utils/StringBuilder.h"
17#include "arcane/utils/ScopedPtr.h"
18#include "arcane/utils/NotImplementedException.h"
19#include "arcane/utils/NotSupportedException.h"
20#include "arcane/utils/ArgumentException.h"
21#include "arcane/utils/CheckedConvert.h"
22#include "arcane/utils/PlatformUtils.h"
23#include "arcane/utils/OStringStream.h"
24#include "arcane/utils/ValueConvert.h"
25#include "arcane/utils/CStringUtils.h"
26
27#include "arcane/core/IParallelMng.h"
28#include "arcane/core/ISubDomain.h"
29#include "arcane/core/VariableTypes.h"
30#include "arcane/core/IVariableMng.h"
31#include "arcane/core/IVariable.h"
32#include "arcane/core/IMesh.h"
33#include "arcane/core/IMeshSubMeshTransition.h"
34#include "arcane/core/IApplication.h"
35#include "arcane/core/IDataFactoryMng.h"
36#include "arcane/core/ItemInfoListView.h"
37#include "arcane/core/ItemPairGroup.h"
38#include "arcane/core/ItemPairGroupImpl.h"
39#include "arcane/core/IMeshUtilities.h"
40#include "arcane/core/IVariableSynchronizer.h"
41#include "arcane/core/ItemInternalSortFunction.h"
42#include "arcane/core/Properties.h"
43#include "arcane/core/ItemFamilyCompactInfos.h"
44#include "arcane/core/IMeshMng.h"
45#include "arcane/core/IMeshCompacter.h"
46#include "arcane/core/IMeshCompactMng.h"
47#include "arcane/core/MeshPartInfo.h"
48#include "arcane/core/ParallelMngUtils.h"
49#include "arcane/core/internal/IDataInternal.h"
50#include "arcane/core/internal/IItemFamilyInternal.h"
51#include "arcane/core/internal/IIncrementalItemConnectivityInternal.h"
52#include "arcane/core/datatype/IDataOperation.h"
53
54#include "arcane/mesh/ItemFamily.h"
55#include "arcane/mesh/ItemSharedInfoList.h"
56#include "arcane/mesh/ItemConnectivityInfo.h"
57#include "arcane/mesh/ItemConnectivitySelector.h"
58#include "arcane/mesh/AbstractItemFamilyTopologyModifier.h"
59#include "arcane/mesh/DynamicMeshKindInfos.h"
60
61#include "arcane/core/parallel/GhostItemsVariableParallelOperation.h"
62#include "arcane/core/parallel/IStat.h"
63
64#include "arcane/core/IIncrementalItemConnectivity.h"
65#include "arcane/core/IItemConnectivityMng.h"
66#include "arcane/core/IItemFamilyPolicyMng.h"
67
68#include "arcane/core/ItemPrinter.h"
69#include "arcane/core/ConnectivityItemVector.h"
70#include "arcane/core/IndexedItemConnectivityView.h"
71
72#include "arcane/mesh/ItemProperty.h"
73#include "arcane/mesh/ItemData.h"
74#include "arcane/mesh/ConnectivityNewWithDependenciesTypes.h"
75
76#include <array>
77
78/*---------------------------------------------------------------------------*/
79/*---------------------------------------------------------------------------*/
80
81namespace Arcane::mesh
82{
83
84/*---------------------------------------------------------------------------*/
85/*---------------------------------------------------------------------------*/
86
87namespace
88{
89
90 template <typename DataType> void
91 _offsetArrayByOne(Array<DataType>* array)
92 {
93 Array<DataType>& v = *array;
94 MeshUtils::checkResizeArray(v, v.size() + 1, false);
95 Int32 n = v.size();
96 for (Int32 i = (n - 1); i >= 1; --i)
97 v[i] = v[i - 1];
98 }
99
100} // namespace
101
102/*---------------------------------------------------------------------------*/
103/*---------------------------------------------------------------------------*/
104
106: public IItemFamilyInternal
107{
108 public:
109
110 explicit InternalApi(ItemFamily* family)
111 : m_family(family)
112 {}
113
114 public:
115
117 {
118 return m_family->_unstructuredItemInternalConnectivityList();
119 }
121 {
122 return m_family->_topologyModifier();
123 }
125 {
126 return m_family->commonItemSharedInfo();
127 }
128 void addSourceConnectivity(IIncrementalItemSourceConnectivity* connectivity) override
129 {
130 m_family->_addSourceConnectivity(connectivity);
131 }
132 void addTargetConnectivity(IIncrementalItemTargetConnectivity* connectivity) override
133 {
134 m_family->_addTargetConnectivity(connectivity);
135 }
136 void endAllocate() override
137 {
138 return m_family->_endAllocate();
139 }
141 {
142 return m_family->_notifyEndUpdateFromMesh();
143 }
144 void addVariable(IVariable* var) override
145 {
146 return m_family->_addVariable(var);
147 }
148 void removeVariable(IVariable* var) override
149 {
150 return m_family->_removeVariable(var);
151 }
152 void resizeVariables(bool force_resize) override
153 {
154 m_family->_resizeShMemVariables();
155 m_family->_resizeVariables(force_resize);
156 }
157
158 private:
159
160 ItemFamily* m_family = nullptr;
161};
162
163/*---------------------------------------------------------------------------*/
164/*---------------------------------------------------------------------------*/
165
167{
168 public:
169
170 Variables(IMesh* mesh,
171 const String& family_name,
172 eItemKind item_kind,
173 const String& shared_data_name,
174 const String& unique_ids_name,
175 const String& items_owner_name,
176 const String& items_flags_name,
177 const String& items_type_id_name,
178 const String& items_nb_parent_name,
179 const String& groups_name,
180 const String& current_id_name,
181 const String& new_owner_name,
182 const String& parent_mesh_name,
183 const String& parent_family_name,
184 const String& parent_family_depth_name,
185 const String& child_meshes_name,
186 const String& child_families_name)
193 , m_groups_name(VariableBuildInfo(mesh, groups_name))
194 , m_current_id(VariableBuildInfo(mesh, current_id_name))
196 , m_parent_mesh_name(VariableBuildInfo(mesh, parent_mesh_name, IVariable::PPrivate))
197 , m_parent_family_name(VariableBuildInfo(mesh, parent_family_name, IVariable::PPrivate))
198 , m_parent_family_depth(VariableBuildInfo(mesh, parent_family_depth_name, IVariable::PPrivate))
199 , m_child_meshes_name(VariableBuildInfo(mesh, child_meshes_name, IVariable::PPrivate))
200 , m_child_families_name(VariableBuildInfo(mesh, child_families_name, IVariable::PPrivate))
201 {}
202
203 public:
204
205 void setUsed()
206 {
207 m_items_new_owner.setUsed(true);
208 }
209
210 public:
211
213 // TODO: use Int16 when the number of ItemSharedInfo is limited to Int16
231 VariableArrayString m_groups_name;
232 VariableScalarInteger m_current_id;
244 VariableScalarString m_parent_mesh_name;
245 VariableScalarString m_parent_family_name;
246 VariableScalarInteger m_parent_family_depth;
247 VariableArrayString m_child_meshes_name;
248 VariableArrayString m_child_families_name;
249};
250
251/*---------------------------------------------------------------------------*/
252/*---------------------------------------------------------------------------*/
253
255_cmpIVariablePtr(const IVariable* a, const IVariable* b)
256{
257 return CStringUtils::isLess(a->name().localstr(), b->name().localstr());
258}
259
260/*---------------------------------------------------------------------------*/
261/*---------------------------------------------------------------------------*/
262
263/*---------------------------------------------------------------------------*/
264/*---------------------------------------------------------------------------*/
265
266ItemFamily::
267ItemFamily(IMesh* mesh, eItemKind ik, const String& name)
268: TraceAccessor(mesh->traceMng())
269, m_name(name)
270, m_mesh(mesh)
271, m_internal_api(new InternalApi(this))
272, m_sub_domain(mesh->subDomain())
273, m_infos(std::make_unique<DynamicMeshKindInfos>(mesh, ik, name))
274, m_item_internal_list(mesh->meshItemInternalList())
275, m_common_item_shared_info(new ItemSharedInfo(this, m_item_internal_list, &m_item_connectivity_list))
276, m_item_shared_infos(new ItemSharedInfoList(this, m_common_item_shared_info))
277, m_used_variables(&_cmpIVariablePtr)
278, m_used_shmem_variables(&_cmpIVariablePtr)
279, m_properties(new Properties(*mesh->properties(), name))
280, m_sub_domain_id(mesh->meshPartInfo().partRank())
281{
282 m_item_connectivity_list.m_items = mesh->meshItemInternalList();
283 m_infos->setItemFamily(this);
284 m_connectivity_selector_list_by_item_kind.resize(ItemInternalConnectivityList::MAX_ITEM_KIND);
285}
286
287/*---------------------------------------------------------------------------*/
288/*---------------------------------------------------------------------------*/
289
290ItemFamily::
291~ItemFamily()
292{
293 delete m_topology_modifier;
294 delete m_policy_mng;
295 delete m_properties;
296 delete m_local_connectivity_info;
297 delete m_global_connectivity_info;
298 delete m_item_sort_function;
299 delete m_internal_variables;
300 delete m_item_shared_infos;
301
302 for (ItemConnectivitySelector* ics : m_connectivity_selector_list)
303 delete ics;
304
305 delete m_common_item_shared_info;
306 delete m_internal_api;
307}
308
309/*---------------------------------------------------------------------------*/
310/*---------------------------------------------------------------------------*/
311
312String ItemFamily::
313_variableName(const String& base_name) const
314{
315 return m_name + base_name;
316}
317
318/*---------------------------------------------------------------------------*/
319/*---------------------------------------------------------------------------*/
320
321void ItemFamily::
322build()
323{
324 m_item_type_mng = m_mesh->itemTypeMng();
325
326 // Create the topology modifier if it hasn't been done by
327 // the derived class.
328 if (!m_topology_modifier)
329 m_topology_modifier = new AbstractItemFamilyTopologyModifier(this);
330
331 m_full_name = m_mesh->name() + "_" + m_name;
332
333 m_local_connectivity_info = new ItemConnectivityInfo();
334 m_global_connectivity_info = new ItemConnectivityInfo();
335
336 IParallelMng* pm = m_mesh->parallelMng();
337 if (!pm->isParallel()) {
338 m_default_sub_domain_owner = 0;
339 m_is_parallel = false;
340 }
341 else
342 m_is_parallel = true;
343
344 // First initialize the infos because this creates the entity groups
345 // and it is essential before creating variables on them.
346 m_infos->build();
347
348 // Constructs the instance that will contain the variables
349 // NOTE: if we change the names here, we must also change them in MeshStats.cc
350 // otherwise the statistics will not be reliable.
351 {
352 String var_unique_ids_name(_variableName("FamilyUniqueIds"));
353 String var_owner_name(_variableName("FamilyOwner"));
354 String var_flags_name(_variableName("FamilyFlags"));
355 String var_typeid_name(_variableName("FamilyItemTypeId"));
356 String var_nb_parent_name(_variableName("FamilyItemNbParent"));
357 String var_count_name(_variableName("FamilyItemsShared"));
358 String var_groups_name(_variableName("FamilyGroupsName"));
359 String var_current_id_name(_variableName("FamilyCurrentId"));
360 String var_new_owner_name(_variableName("FamilyNewOwnerName"));
361 String var_parent_mesh_name(_variableName("ParentMeshName"));
362 String var_parent_family_name(_variableName("ParentFamilyName"));
363 String var_parent_family_depth_name(_variableName("ParentFamilyDepthName"));
364 String var_child_meshes_name(_variableName("ChildMeshesName"));
365 String var_child_families_name(_variableName("ChildFamiliesName"));
366 m_internal_variables = new Variables(m_mesh, name(), itemKind(), var_count_name,
367 var_unique_ids_name, var_owner_name,
368 var_flags_name, var_typeid_name, var_nb_parent_name, var_groups_name,
369 var_current_id_name, var_new_owner_name,
370 var_parent_mesh_name, var_parent_family_name,
371 var_parent_family_depth_name,
372 var_child_meshes_name,
373 var_child_families_name);
374 // These arrays should not be used to access entities because there is an offset
375 // of 1 to manage the null entity. You must use the associated view
376 // which is in m_common_item_shared_info.
377 m_items_unique_id = &m_internal_variables->m_items_unique_id._internalTrueData()->_internalDeprecatedValue();
378 m_items_owner = &m_internal_variables->m_items_owner._internalTrueData()->_internalDeprecatedValue();
379 m_items_flags = &m_internal_variables->m_items_flags._internalTrueData()->_internalDeprecatedValue();
380 m_items_type_id = &m_internal_variables->m_items_type_id._internalTrueData()->_internalDeprecatedValue();
381 m_items_nb_parent = &m_internal_variables->m_items_nb_parent._internalTrueData()->_internalDeprecatedValue();
382
383 // Add notification for view update after an external change
384 _addOnSizeChangedObservable(m_internal_variables->m_items_unique_id);
385 _addOnSizeChangedObservable(m_internal_variables->m_items_owner);
386 _addOnSizeChangedObservable(m_internal_variables->m_items_flags);
387 _addOnSizeChangedObservable(m_internal_variables->m_items_type_id);
388 _addOnSizeChangedObservable(m_internal_variables->m_items_nb_parent);
389
390 _updateItemViews();
391 }
392
393 m_variable_synchronizer = ParallelMngUtils::createSynchronizerRef(pm, this);
394
395 m_item_sort_function = _defaultItemSortFunction();
396
397 {
398 String s = platform::getEnvironmentVariable("ARCANE_USE_LEGACY_COMPACT_ITEMS");
399 if (s == "TRUE" || s == "1") {
400 info() << "WARNING: Using legacy 'compactItem()' without compactReference()'";
401 m_use_legacy_compact_item = true;
402 }
403 }
404 {
405 if (auto v = Convert::Type<Int32>::tryParseFromEnvironment("ARCANE_ITEMFAMILY_SHRINK_AFTER_ALLOCATE", true))
406 m_do_shrink_after_allocate = (v.value() != 0);
407 }
408}
409
410/*---------------------------------------------------------------------------*/
411/*---------------------------------------------------------------------------*/
412
415{
416 return m_infos->findOne(uid);
417}
418ItemInternalMap& ItemFamily::
419itemsMap()
420{
421 return m_infos->itemsMap();
422}
423const DynamicMeshKindInfos& ItemFamily::
424infos() const
425{
426 return *m_infos;
427}
428
429const DynamicMeshKindInfos& ItemFamily::
430_infos() const
431{
432 return *m_infos;
433}
434
435void ItemFamily::
436_removeOne(Item item)
437{
438 // TODO: check in check mode with the new connectivities that the deleted entity
439 // does not have connected objects.
440 m_infos->removeOne(ItemCompatibility::_itemInternal(item));
441}
442void ItemFamily::
443_detachOne(Item item)
444{
445 m_infos->detachOne(ItemCompatibility::_itemInternal(item));
446}
447ItemInternalList ItemFamily::
448_itemsInternal()
449{
450 return m_infos->itemsInternal();
451}
452ItemInternal* ItemFamily::
453_itemInternal(Int32 local_id)
454{
455 return m_infos->itemInternal(local_id);
456}
457ItemInternal* ItemFamily::
458_allocOne(Int64 unique_id)
459{
460 return m_infos->allocOne(unique_id);
461}
462ItemInternal* ItemFamily::
463_allocOne(Int64 unique_id, bool& need_alloc)
464{
465 return m_infos->allocOne(unique_id, need_alloc);
466}
467ItemInternal* ItemFamily::
468_findOrAllocOne(Int64 uid, bool& is_alloc)
469{
470 return m_infos->findOrAllocOne(uid, is_alloc);
471}
472void ItemFamily::
473_setHasUniqueIdMap(bool v)
474{
475 m_infos->setHasUniqueIdMap(v);
476}
477void ItemFamily::
478_removeMany(Int32ConstArrayView local_ids)
479{
480 m_infos->removeMany(local_ids);
481}
482void ItemFamily::
483_removeDetachedOne(Item item)
484{
485 m_infos->removeDetachedOne(ItemCompatibility::_itemInternal(item));
486}
488itemKind() const
489{
490 return m_infos->kind();
491}
492
493/*---------------------------------------------------------------------------*/
494/*---------------------------------------------------------------------------*/
495
497nbItem() const
498{
499 return m_infos->nbItem();
500}
501
502/*---------------------------------------------------------------------------*/
503/*---------------------------------------------------------------------------*/
504
506maxLocalId() const
507{
508 return m_infos->maxUsedLocalId();
509}
510
511/*---------------------------------------------------------------------------*/
512/*---------------------------------------------------------------------------*/
513
516{
517 return m_infos->itemsInternal();
518}
519
520/*---------------------------------------------------------------------------*/
521/*---------------------------------------------------------------------------*/
522
525{
526 return ItemInfoListView(m_common_item_shared_info);
527}
528
529/*---------------------------------------------------------------------------*/
530/*---------------------------------------------------------------------------*/
531
533parentFamily() const
534{
535 return m_parent_family;
536}
537
538/*---------------------------------------------------------------------------*/
539/*---------------------------------------------------------------------------*/
540
543{
544 m_parent_family = parent;
545 if (parent == this) // Self-referencing
546 m_parent_family_depth = 1;
547 else if (!parent) // No parent
548 m_parent_family_depth = 0;
549 else { // Cross-referencing
550 m_parent_family_depth = parent->parentFamilyDepth() + 1;
551 m_parent_family->addChildFamily(this);
552 }
553 ARCANE_ASSERT((m_parent_family_depth < 2), ("Not test if more than one depth level"));
554}
555
556/*---------------------------------------------------------------------------*/
557/*---------------------------------------------------------------------------*/
558
560parentFamilyDepth() const
561{
562 return m_parent_family_depth;
563}
564
565/*---------------------------------------------------------------------------*/
566/*---------------------------------------------------------------------------*/
567
570{
571 ItemFamily* true_family = ARCANE_CHECK_POINTER(dynamic_cast<ItemFamily*>(family));
572 m_child_families.add(true_family);
573}
574
575/*---------------------------------------------------------------------------*/
576/*---------------------------------------------------------------------------*/
577
580{
582 for (Integer i = 0; i < m_child_families.size(); ++i) {
583 collection.add(m_child_families[i]);
584 }
585 return collection;
586}
587
588/*---------------------------------------------------------------------------*/
589/*---------------------------------------------------------------------------*/
590
593{
594 return m_internal_variables->m_items_new_owner;
595}
596
597/*---------------------------------------------------------------------------*/
598/*---------------------------------------------------------------------------*/
599
602{
603 _checkValid();
604 m_item_shared_infos->checkValid();
605}
606
607/*---------------------------------------------------------------------------*/
608/*---------------------------------------------------------------------------*/
609
612{
613 _checkValidConnectivity();
614}
615
616/*---------------------------------------------------------------------------*/
617/*---------------------------------------------------------------------------*/
625{
626 // Recalculate local and global connectivity info for all sub-domains
627 _computeConnectivityInfo(m_local_connectivity_info);
628 _computeConnectivityInfo(m_global_connectivity_info);
629 m_global_connectivity_info->reduce(parallelMng());
630}
631
632/*---------------------------------------------------------------------------*/
633/*---------------------------------------------------------------------------*/
634
636endUpdate()
637{
638 _endUpdate(true);
639 // TODO: test connectivity but it crashes some test cases
640 // (dof, amr2 and mesh_modification). To see if this is normal.
641 //if (arcaneIsCheck())
642 //checkValidConnectivity();
643}
644
645/*---------------------------------------------------------------------------*/
646/*---------------------------------------------------------------------------*/
647
648void ItemFamily::
649_endAllocate()
650{
651 // The variable is not "used" by default because the family is not ready yet.
652 // On sub-families, it is enough to filter setUsed at the time of endAllocate
653 if (!m_parent_family) {
654 m_internal_variables->setUsed();
655 }
656 if (m_do_shrink_after_allocate)
657 _shrinkConnectivityAndPrintInfos();
658}
659
660/*---------------------------------------------------------------------------*/
661/*---------------------------------------------------------------------------*/
662
663void ItemFamily::
664_shrinkConnectivityAndPrintInfos()
665{
666 {
667 ItemConnectivityMemoryInfo mem_info;
668 for (ItemConnectivitySelector* cs : m_connectivity_selector_list) {
669 IIncrementalItemConnectivity* c = cs->customConnectivity();
670 c->_internalApi()->addMemoryInfos(mem_info);
671 }
672 const Int64 total_capacity = mem_info.m_total_capacity;
673 const Int64 total_size = mem_info.m_total_size;
674 Int64 ratio = 100 * (total_capacity - total_size);
675 ratio /= (total_size + 1); // Add 1 to avoid division by zero
676 const Int64 sizeof_int32 = sizeof(Int32);
677 const Int64 mega_byte = 1024 * 1024;
678 Int64 capacity_mega_byte = (mem_info.m_total_capacity * sizeof_int32) / mega_byte;
679 info() << "MemoryUsed for family name=" << name() << " size=" << mem_info.m_total_size
680 << " capacity=" << mem_info.m_total_capacity
681 << " capacity (MegaByte)=" << capacity_mega_byte
682 << " ratio=" << ratio;
683 }
684 OStringStream ostr;
685 std::ostream& o = ostr();
686 o << "Mem=" << platform::getMemoryUsed();
687 for (ItemConnectivitySelector* cs : m_connectivity_selector_list) {
688 IIncrementalItemConnectivity* c = cs->customConnectivity();
689 c->dumpStats(o);
690 o << "\n";
691 c->_internalApi()->shrinkMemory();
692 c->dumpStats(o);
693 o << "\n";
694 }
695 o << "Mem=" << platform::getMemoryUsed();
696 info() << ostr.str();
697}
698
699/*---------------------------------------------------------------------------*/
700/*---------------------------------------------------------------------------*/
701
702bool ItemFamily::
703_partialEndUpdate()
704{
705 bool need_end_update = m_infos->changed();
706 info(4) << "ItemFamily::endUpdate() " << fullName() << " need_end_update?=" << need_end_update;
707 if (!need_end_update) {
708 // Even if no entity is added or removed, if m_need_prepare_dump
709 // is true, it means something has changed in the family. In this
710 // case, it is preferable to increment the current_id. Otherwise, if we call
711 // readFromDump() (for example, following a rollback), the data will not be
712 // restored if current_id has not changed in the meantime.
713 if (m_need_prepare_dump) {
714 _computeConnectivityInfo(m_local_connectivity_info);
715 ++m_current_id;
716 }
717 return true;
718 }
719 m_item_need_prepare_dump = true;
720 _computeConnectivityInfo(m_local_connectivity_info);
721 ++m_current_id;
722
723 // Update "external" connectivities
725 m_connectivity_mng->setModifiedItems(this, m_infos->addedItems(), m_infos->removedItems());
726 //
727 m_infos->finalizeMeshChanged();
728
729 return false;
730}
731
732/*---------------------------------------------------------------------------*/
733/*---------------------------------------------------------------------------*/
734
735void ItemFamily::
736_endUpdate(bool need_check_remove)
737{
738 _resizeShMemVariables();
739 if (_partialEndUpdate())
740 return;
741
742 _resizeVariables(false);
743 info(4) << "ItemFamily:endUpdate(): " << fullName()
744 << " hashmapsize=" << itemsMap().nbBucket()
745 << " nb_group=" << m_item_groups.count();
746
747 _updateGroups(need_check_remove);
748}
749
750/*---------------------------------------------------------------------------*/
751/*---------------------------------------------------------------------------*/
752
755{
756 _partialEndUpdate();
757}
758
759/*---------------------------------------------------------------------------*/
760/*---------------------------------------------------------------------------*/
761
764{
765 _updateGroup(group, true);
766}
767
768/*---------------------------------------------------------------------------*/
769/*---------------------------------------------------------------------------*/
770
771void ItemFamily::
772_updateGroup(ItemGroup group, bool need_check_remove)
773{
774 // No need to recalculate the group of global entities
775 if (group == m_infos->allItems())
776 return;
777
778 if (group.internal()->hasComputeFunctor())
779 group.invalidate();
780 if (need_check_remove) {
781 debug(Trace::High) << "Reset SuppressedItems: " << group.name();
783 }
784 if (arcaneIsCheck())
785 group.checkValid();
786}
787
788/*---------------------------------------------------------------------------*/
789/*---------------------------------------------------------------------------*/
790
791void ItemFamily::
792_updateGroups(bool need_check_remove)
793{
794 for (ItemGroupList::Enumerator i(m_item_groups); ++i;) {
795 ItemGroup group = *i;
796 _updateGroup(group, need_check_remove);
797 }
798}
799
800/*---------------------------------------------------------------------------*/
801/*---------------------------------------------------------------------------*/
802
805{
806 _updateVariable(variable);
807}
808
809/*---------------------------------------------------------------------------*/
810/*---------------------------------------------------------------------------*/
811
812void ItemFamily::
813_updateVariable(IVariable* var)
814{
815 var->resizeFromGroup();
816}
817
818/*---------------------------------------------------------------------------*/
819/*---------------------------------------------------------------------------*/
820
821void ItemFamily::
822_resizeVariables(bool force_resize)
823{
824 debug(Trace::High) << "ItemFamily::resizeVariables: name=" << fullName()
825 << " varsize=" << maxLocalId()
826 << " nb_item=" << nbItem()
827 << " currentsize=" << m_current_variable_item_size;
828 if (force_resize || (maxLocalId() != m_current_variable_item_size)) {
829 info(4) << "ItemFamily::resizeVariables: name=" << fullName()
830 << " varsize=" << maxLocalId()
831 << " nb_item=" << nbItem()
832 << " currentsize=" << m_current_variable_item_size
833 << " group_nb_item=" << allItems().size()
834 << " nb_var=" << m_used_variables.size();
835
836 m_current_variable_item_size = maxLocalId();
837
838 for (IVariable* var : m_used_variables) {
839 _updateVariable(var);
840 }
841 }
842}
843
844/*---------------------------------------------------------------------------*/
845/*---------------------------------------------------------------------------*/
846
847void ItemFamily::
848_resizeShMemVariables()
849{
850 for (IVariable* var : m_used_shmem_variables) {
851 _updateVariable(var);
852 }
853}
854
855/*---------------------------------------------------------------------------*/
856/*---------------------------------------------------------------------------*/
857
858void ItemFamily::
859itemsUniqueIdToLocalId(ArrayView<Int64> ids, bool do_fatal) const
860{
861 m_infos->itemsUniqueIdToLocalId(ids, do_fatal);
862}
863
864/*---------------------------------------------------------------------------*/
865/*---------------------------------------------------------------------------*/
866
867void ItemFamily::
868itemsUniqueIdToLocalId(Int32ArrayView local_ids,
869 Int64ConstArrayView unique_ids,
870 bool do_fatal) const
871{
872 m_infos->itemsUniqueIdToLocalId(local_ids, unique_ids, do_fatal);
873}
874
875/*---------------------------------------------------------------------------*/
876/*---------------------------------------------------------------------------*/
877
878void ItemFamily::
879itemsUniqueIdToLocalId(Int32ArrayView local_ids,
881 bool do_fatal) const
882{
883 m_infos->itemsUniqueIdToLocalId(local_ids, unique_ids, do_fatal);
884}
885
886/*---------------------------------------------------------------------------*/
887/*---------------------------------------------------------------------------*/
888
890subDomain() const
891{
892 return m_sub_domain;
893}
894
895/*---------------------------------------------------------------------------*/
896/*---------------------------------------------------------------------------*/
897
899traceMng() const
900{
902}
903
904/*---------------------------------------------------------------------------*/
905/*---------------------------------------------------------------------------*/
906
908mesh() const
909{
910 return m_mesh;
911}
912
913/*---------------------------------------------------------------------------*/
914/*---------------------------------------------------------------------------*/
915
917parallelMng() const
918{
919 return m_mesh->parallelMng();
920}
921
922/*---------------------------------------------------------------------------*/
923/*---------------------------------------------------------------------------*/
924
926allItems() const
927{
928 _checkNeedEndUpdate();
929 return m_infos->allItems();
930}
931
932/*---------------------------------------------------------------------------*/
933/*---------------------------------------------------------------------------*/
934
936createGroup(const String& name, Int32ConstArrayView elements, bool do_override)
937{
938 debug(Trace::High) << "ItemFamily:createGroup(name,Int32ConstArrayView): " << m_name << ":"
939 << " group_name=" << name
940 << " count=" << elements.size()
941 << " override=" << do_override;
942
943 _checkNeedEndUpdate();
944
945 {
946 ItemGroup group;
947 if (do_override) {
948 group = findGroup(name);
949 if (group.null())
950 group = createGroup(name);
951 }
952 else {
953 group = createGroup(name);
954 }
955 group.setItems(elements);
956 return group;
957 }
958}
959
960/*---------------------------------------------------------------------------*/
961/*---------------------------------------------------------------------------*/
962
964createGroup(const String& name)
965{
966 //#warning SDP CHANGE
967 // SDP: checkpointing/recovery problem ...
968 {
970 if (!g.null()) {
971 fatal() << "Attempting to create an already existing group '" << name << "'";
972 }
973 }
974 debug() << "ItemFamily:createGroup(name): " << m_name << ":"
975 << " name=" << name;
976 ItemGroup group(new ItemGroupImpl(this, name));
977 _processNewGroup(group);
978 return group;
979}
980
981/*---------------------------------------------------------------------------*/
982/*---------------------------------------------------------------------------*/
983
985createGroup(const String& name, const ItemGroup& parent, bool do_override)
986{
987 ItemGroup group = findGroup(name);
988 if (!group.null()) {
989 if (do_override) {
990 if (group.internal()->parentGroup() != parent)
991 fatal() << "Group already existing but with a different parent";
992 if (group == parent)
993 fatal() << "A group can not be its own parent name=" << name;
994 return group;
995 }
996 fatal() << "Attempting to create an already existing group '" << name << "'";
997 }
998 if (parent.null())
999 fatal() << "Attempting to create a group '" << name << "' with no parent.";
1000 debug() << "ItemFamily:createGroup(name,parent): " << m_name << ":"
1001 << " name=" << name
1002 << " parent=" << parent.name();
1003 group = ItemGroup(new ItemGroupImpl(this, parent.internal(), name));
1004 _processNewGroup(group);
1005 return group;
1006}
1007
1008/*---------------------------------------------------------------------------*/
1009/*---------------------------------------------------------------------------*/
1010
1013{
1014 _invalidateComputedGroups();
1015 ItemGroupList current_groups(m_item_groups.clone());
1016 m_item_groups.clear();
1017 for (ItemGroupList::Enumerator i(current_groups); ++i;) {
1018 ItemGroup group(*i);
1019 if (group.isAllItems())
1020 m_item_groups.add(group);
1021 else
1022 group.internal()->destroy();
1023 }
1024 allItems().internal()->destroy();
1025}
1026
1027/*---------------------------------------------------------------------------*/
1028/*---------------------------------------------------------------------------*/
1029
1032{
1033 debug() << "ItemFamily::notifyItemsOwnerChanged()";
1034 for (ItemGroup group : m_item_groups) {
1035 if (m_is_parallel && group.internal()->hasComputeFunctor())
1036 group.invalidate();
1037 }
1038
1039 // Propagate changes to child families
1040 for (Integer i = 0; i < m_child_families.size(); ++i) {
1041 IItemFamily* family = m_child_families[i];
1042 ItemInternalArrayView items(family->itemsInternal());
1043 for (Integer z = 0, zs = items.size(); z < zs; ++z) {
1044 impl::MutableItemBase item(items[z]);
1045 if (item.isSuppressed())
1046 continue;
1047 Item parent_item = item.parentBase(0);
1048 ARCANE_ASSERT((parent_item.uniqueId() == item.uniqueId()), ("Inconsistent parent uid"));
1049 item.setOwner(parent_item.owner(), m_sub_domain_id);
1050 }
1051 family->notifyItemsOwnerChanged();
1052 }
1053}
1054
1055/*---------------------------------------------------------------------------*/
1056/*---------------------------------------------------------------------------*/
1057
1058void ItemFamily::
1059_processNewGroup(ItemGroup group)
1060{
1061 // Checks that the group has the correct type
1062 if (group.itemKind() != itemKind()) {
1063 ARCANE_FATAL("Incoherent family name={0} wanted={1} current={2}",
1064 fullName(), itemKind(), group.itemKind());
1065 }
1066 m_item_groups.add(group);
1067 m_need_prepare_dump = true;
1068 // In sequential mode, all groups are owned groups
1069 // TODO: look into removing the test with 'm_is_parallel' but
1070 // if we do that it crashes some tests with aleph_kappa.
1071 if (!m_is_parallel && m_mesh->meshPartInfo().nbPart() == 1)
1072 group.setOwn(true);
1073}
1074
1075/*---------------------------------------------------------------------------*/
1076/*---------------------------------------------------------------------------*/
1077
1079groups() const
1080{
1081 return m_item_groups;
1082}
1083
1084/*---------------------------------------------------------------------------*/
1085/*---------------------------------------------------------------------------*/
1086
1088findGroup(const String& name) const
1089{
1090 for (const ItemGroup& group : m_item_groups) {
1091 if (group.name() == name)
1092 return group;
1093 }
1094 return ItemGroup();
1095}
1096
1097/*---------------------------------------------------------------------------*/
1098/*---------------------------------------------------------------------------*/
1099
1101findGroup(const String& name, bool create_if_needed)
1102{
1103 ItemGroup group = findGroup(name);
1104 if (group.null()) {
1105 if (create_if_needed)
1106 group = createGroup(name);
1107 }
1108 return group;
1109}
1110
1111/*---------------------------------------------------------------------------*/
1112/*---------------------------------------------------------------------------*/
1113
1116{
1117 itemsMap().notifyUniqueIdsChanged();
1118}
1119
1120/*---------------------------------------------------------------------------*/
1121/*---------------------------------------------------------------------------*/
1122
1123void ItemFamily::
1124_checkNeedEndUpdate() const
1125{
1126 if (m_infos->changed())
1127 ARCANE_FATAL("missing call to endUpdate() after modification");
1128}
1129
1130/*---------------------------------------------------------------------------*/
1131/*---------------------------------------------------------------------------*/
1132
1135{
1136 info(4) << "ItemFamily::prepareForDump(): " << fullName()
1137 << " need=" << m_need_prepare_dump
1138 << " item-need=" << m_item_need_prepare_dump
1139 << " m_item_shared_infos->hasChanged()=" << m_item_shared_infos->hasChanged()
1140 << " nb_item=" << m_infos->nbItem();
1141
1142 {
1143 auto* p = m_properties;
1144 p->setInt32("dump-version", 0x0307);
1145 p->setInt32("nb-item", m_infos->nbItem());
1146 p->setInt32("current-change-id", m_current_id);
1147 }
1148
1149 // TODO: add verification flag if necessary
1150 if (m_item_need_prepare_dump || m_item_shared_infos->hasChanged()) {
1151 info(4) << "Prepare for dump:2: name=" << m_name << " nb_alloc=" << m_nb_allocate_info
1152 << " uid_size=" << m_items_unique_id->size() << " cap=" << m_items_unique_id->capacity()
1153 << " byte=" << m_items_unique_id->capacity() * sizeof(Int64);
1154
1155 // TODO: ability to specify whether or not to compact.
1156 _compactOnlyItems(false);
1157
1158 // Assumes compression
1159 m_infos->prepareForDump();
1160 m_item_shared_infos->prepareForDump();
1161 m_need_prepare_dump = true;
1162 }
1163 m_item_need_prepare_dump = false;
1164 if (m_need_prepare_dump) {
1165 Integer nb_item = m_infos->nbItem();
1166 // TODO: look into whether it would be better to do this in finishCompactItem()
1167 _resizeItemVariables(nb_item, true);
1168 m_internal_variables->m_current_id = m_current_id;
1169 info(4) << " SET FAMILY ID name=" << name() << " id= " << m_current_id
1170 << " saveid=" << m_internal_variables->m_current_id();
1171 ItemInternalList items(m_infos->itemsInternal());
1172 m_internal_variables->m_items_shared_data_index.resize(nb_item);
1173 IntegerArrayView items_shared_data_index(m_internal_variables->m_items_shared_data_index);
1174 info(4) << "ItemFamily::prepareForDump(): " << m_name
1175 << " count=" << nb_item << " currentid=" << m_current_id;
1176 // Normally items[i]->localId()==i for all entities because we performed a compaction.
1177 if (arcaneIsCheck()) {
1178 for (Integer i = 0; i < nb_item; ++i) {
1179 ItemInternal* item = items[i];
1180 if (item->localId() != i)
1181 ARCANE_FATAL("Incoherence between index ({0}) and localId() ({1})", i, item->localId());
1182 }
1183 }
1184 for (Integer i = 0; i < nb_item; ++i) {
1185 ItemInternal* item = items[i];
1186 ItemSharedInfoWithType* isi = m_item_shared_infos->findSharedInfo(item->typeInfo());
1187 items_shared_data_index[i] = isi->index();
1188#if 0
1189#ifdef ARCANE_DEBUG
1190 //if (itemKind()==IK_Particle){
1191 info() << "Item: SHARED_INDEX = " << items_shared_data_index[i]
1192 << " uid = " << item->uniqueId()
1193 << " lid = " << item->localId()
1194 << " dataindex = " << item->dataIndex()
1195 << " flags = " << item->flags();
1196 //}
1197#endif
1198#endif
1199 }
1200
1201 // Family linking data
1202 {
1203 if (m_parent_family) {
1204 m_internal_variables->m_parent_family_name = m_parent_family->name();
1205 m_internal_variables->m_parent_mesh_name = m_parent_family->mesh()->name();
1206 }
1207 m_internal_variables->m_parent_family_depth = m_parent_family_depth;
1208 const Integer child_count = m_child_families.size();
1209 m_internal_variables->m_child_meshes_name.resize(child_count);
1210 m_internal_variables->m_child_families_name.resize(child_count);
1211 for (Integer i = 0; i < child_count; ++i) {
1212 m_internal_variables->m_child_meshes_name[i] = m_child_families[i]->mesh()->name();
1213 m_internal_variables->m_child_families_name[i] = m_child_families[i]->name();
1214 }
1215 }
1216
1217 {
1218 // Determines the number of groups and entities to save.
1219 // We do not save dynamically generated groups
1220 Integer nb_group_to_save = 0;
1221 for (ItemGroupList::Enumerator i(m_item_groups); ++i;) {
1222 const ItemGroup& group = *i;
1223 if (group.internal()->hasComputeFunctor() || group.isLocalToSubDomain())
1224 continue;
1225 debug(Trace::High) << "Save group info name=" << group.name();
1226 ++nb_group_to_save;
1227 }
1228 m_internal_variables->m_groups_name.resize(nb_group_to_save);
1229 {
1230 Integer current_group_index = 0;
1231 for (ItemGroupList::Enumerator i(m_item_groups); ++i;) {
1232 const ItemGroup& group = *i;
1233 if (group.internal()->hasComputeFunctor() || group.isLocalToSubDomain())
1234 continue;
1235 m_internal_variables->m_groups_name[current_group_index] = group.name();
1236 ++current_group_index;
1237 }
1238 }
1239 }
1240 }
1241 // Ensures that the groups are up to date, to ensure that
1242 // the save will be correct.
1243 // NOTE: Should this be done here?
1244 // NOTE: better to use an observer on the group variable?
1245 _applyCheckNeedUpdateOnGroups();
1246
1247 m_need_prepare_dump = false;
1248}
1249
1250/*---------------------------------------------------------------------------*/
1251/*---------------------------------------------------------------------------*/
1252
1255{
1256 // TODO: GG: use a flag to indicate that synchronization info needs to be rebuilt
1257 // but not do it directly in this method.
1258
1259 Int32 nb_item = 0;
1260 Int32 dump_version = 0;
1261 // Indicates if we use the variable containing the entity type for
1262 // to build the ItemInternal. This is only possible with protections
1263 // performed since version 3.7 of Arcane. Before that, we must use
1264 // the m_items_shared_data_index variable.
1265 bool use_type_variable = false;
1266 {
1267 Int32 x = 0;
1268 auto* p = m_properties;
1269 if (p->get("dump-version", x))
1270 dump_version = x;
1271 if (dump_version >= 0x0307) {
1272 use_type_variable = true;
1273 nb_item = p->getInt32("nb-item");
1274 Int32 cid = p->getInt32("current-change-id");
1275 Int32 expected_cid = m_internal_variables->m_current_id();
1276 if (cid != expected_cid)
1277 ARCANE_FATAL("Bad value for current id mesh={0} id={1} expected={2}",
1278 fullName(), cid, expected_cid);
1279 }
1280 }
1281
1282 const bool allow_old_version = true;
1283 if (!allow_old_version)
1284 if (dump_version < 0x0307)
1285 ARCANE_FATAL("Your checkpoint is from a version of Arcane which is too old (mininum version is 3.7)");
1286
1287 // The part number can change during recovery. Therefore, we must
1288 // update it. Similarly, if we transition from a sequential mesh to a
1289 // multi-part mesh during recovery, we must remove isOwn() from the group of all entities.
1290 const MeshPartInfo& part_info = m_mesh->meshPartInfo();
1291 m_sub_domain_id = part_info.partRank();
1292 if (m_infos->allItems().isOwn() && part_info.nbPart() > 1)
1293 m_infos->allItems().setOwn(false);
1294
1295 // NOTE: the current implementation assumes that the dataIndex() of
1296 // entities are consecutive and increasing with the localId() of the entities
1297 // (i.e., the entity with localId() of 0 also has a dataIndex() of 0,
1298 // the one with localId() of 1, the next dataIndex() ...)
1299 // This condition is true if compactReferences() has been called.
1300 // When this is no longer the case (gap in numbering), we will need to
1301 // add a data_index variable to the entities.
1302 IntegerArrayView items_shared_data_index(m_internal_variables->m_items_shared_data_index);
1303 if (!use_type_variable)
1304 nb_item = items_shared_data_index.size();
1305
1306 info(4) << "ItemFamily::readFromDump(): " << fullName()
1307 << " count=" << nb_item
1308 << " currentid=" << m_current_id
1309 << " saveid=" << m_internal_variables->m_current_id()
1310 << " use_type_variable?=" << use_type_variable
1311 << " dump_version=" << dump_version;
1312
1313 if (!use_type_variable) {
1314 // With older protections, there is no variable for the entity type.
1315 // We must allocate it here because we use it when calling ItemInternal::setSharedInfo().
1316 if (nb_item > 0)
1317 MeshUtils::checkResizeArray(*m_items_type_id, nb_item + 1, false);
1318 // There is also no offset of 1 for flags, owner and uniqueId.
1319 // We do this offset here.
1320 _handleOldCheckpoint();
1321 }
1322 _updateItemViews();
1323
1324 if (m_internal_variables->m_current_id() == m_current_id) {
1325 debug() << "Family unchanged. Nothing to do.";
1326 //GG: we still need to recalculate the synchronization info because this family
1327 // on other sub-domains might have changed and in this case this
1328 // function will be called. Similarly, the list of groups might have changed
1329 // and their value also for the calculated groups so we must invalidate them
1331 _readGroups();
1332 _invalidateComputedGroups();
1333 return;
1334 }
1335
1336 m_current_id = m_internal_variables->m_current_id();
1337 // IMPORTANT: reset to zero to force resizing of variables
1338 // upon the next addition of entities.
1339 m_current_variable_item_size = 0;
1340
1341 // Family linking data
1342 {
1343 IMeshMng* mesh_mng = m_mesh->meshMng();
1344 if (!m_internal_variables->m_parent_mesh_name().null()) {
1345 IMesh* parent_mesh = mesh_mng->findMeshHandle(m_internal_variables->m_parent_mesh_name()).mesh();
1346 m_parent_family = parent_mesh->findItemFamily(m_internal_variables->m_parent_family_name(), true); // true=> fatal if not found
1347 }
1348 m_parent_family_depth = m_internal_variables->m_parent_family_depth();
1349 ARCANE_ASSERT((m_internal_variables->m_child_meshes_name.size() == m_internal_variables->m_child_families_name.size()),
1350 ("Incompatible child mesh/family sizes"));
1351 Integer child_count = m_internal_variables->m_child_families_name.size();
1352 for (Integer i = 0; i < child_count; ++i) {
1353 IMesh* child_mesh = mesh_mng->findMeshHandle(m_internal_variables->m_child_meshes_name[i]).mesh();
1354 IItemFamily* child_family = child_mesh->findItemFamily(m_internal_variables->m_child_families_name[i], true); // true=> fatal if not found
1355 m_child_families.add(dynamic_cast<ItemFamily*>(child_family));
1356 }
1357 }
1358
1359 m_item_shared_infos->readFromDump();
1360 m_infos->readFromDump();
1361
1362 // When reading from dump, the entities are compacted, so the max value of localId()
1363 // is equal to the number of entities.
1364
1365 if (use_type_variable) {
1366 ItemTypeMng* type_mng = mesh()->itemTypeMng();
1367 for (Integer i = 0; i < nb_item; ++i) {
1368 ;
1369 ItemTypeId type_id{ m_common_item_shared_info->m_type_ids[i] };
1370 ItemSharedInfoWithType* isi = _findSharedInfo(type_mng->typeFromId(type_id));
1371 Int64 uid = m_items_unique_id_view[i];
1372 ItemInternal* item = m_infos->allocOne(uid);
1373 item->_setSharedInfo(isi->sharedInfo(), type_id);
1374 }
1375 }
1376 else {
1377 // Method used for protections from versions 3.6 and earlier of Arcane.
1378 auto item_shared_infos = m_item_shared_infos->itemSharedInfos();
1379 for (Integer i = 0; i < nb_item; ++i) {
1380 Integer shared_data_index = items_shared_data_index[i];
1381 ItemSharedInfoWithType* isi = item_shared_infos[shared_data_index];
1382 Int64 uid = m_items_unique_id_view[i];
1383 ItemInternal* item = m_infos->allocOne(uid);
1384 item->_setSharedInfo(isi->sharedInfo(), isi->itemTypeId());
1385 }
1386 }
1387
1388 // Clear the entities from the total group because they will be updated
1389 // when calling _endUpdate()
1390 m_infos->allItems().clear();
1391
1392 // Notifies the source connectivities that we just read from dump.
1393 for (auto& c : m_source_incremental_item_connectivities)
1394 c->notifyReadFromDump();
1395
1396 // Recreation of groups if necessary
1397 _readGroups();
1398
1399 // Invalidates the recalculated groups
1400 _invalidateComputedGroups();
1401
1402 _endUpdate(false);
1403
1405}
1406
1407/*---------------------------------------------------------------------------*/
1408/*---------------------------------------------------------------------------*/
1409
1410void ItemFamily::
1411_applyCheckNeedUpdateOnGroups()
1412{
1413 for (ItemGroupList::Enumerator i(m_item_groups); ++i;) {
1414 ItemGroup group = *i;
1415 // No need to recalculate the group of global entities
1416 if (group == m_infos->allItems())
1417 continue;
1418 group.internal()->checkNeedUpdate();
1419 }
1420}
1421
1422/*---------------------------------------------------------------------------*/
1423/*---------------------------------------------------------------------------*/
1424
1425void ItemFamily::
1426_invalidateComputedGroups()
1427{
1428 // If the group has a parent, it does not have an associated variable and
1429 // furthermore, it may contain invalid values following a rollback.
1430 // In this case, we clear it and invalidate it.
1431 for (ItemGroupList::Enumerator i(m_item_groups); ++i;) {
1432 ItemGroup group = *i;
1433 if (!group.internal()->parentGroup().null()) {
1434 group.clear();
1435 group.invalidate();
1436 }
1437 }
1438}
1439
1440/*---------------------------------------------------------------------------*/
1441/*---------------------------------------------------------------------------*/
1447{
1448 // Recréation des groupes si nécessaire
1449 VariableArrayString& groups_var = m_internal_variables->m_groups_name;
1450 debug() << "ItemFamily::readFromDump(): number of group: " << groups_var.size();
1451 for (Integer i = 0, is = groups_var.size(); i < is; ++i) {
1452 String name(groups_var[i]);
1453 debug() << "Readign group again: " << name;
1454 ItemGroup group = findGroup(name);
1455 if (group.null())
1457 }
1458 // Notifie les groupes qu'ils ont été mis à jour de manière
1459 // externe. Cela peut être nécessaire pour recalculer automatiquement
1460 // certaines informations (comme le padding pour la vectorisation)
1461 for (ItemGroup& group : m_item_groups) {
1462 group.incrementTimestamp();
1463 }
1464}
1465
1466/*---------------------------------------------------------------------------*/
1467/*---------------------------------------------------------------------------*/
1476{
1477 Int32 global_changed = parallelMng()->reduce(Parallel::ReduceMax, changed);
1478 if (global_changed != 0)
1480}
1481
1482/*---------------------------------------------------------------------------*/
1483/*---------------------------------------------------------------------------*/
1492_compactOnlyItems(bool do_sort)
1493{
1494 _compactItems(do_sort);
1495
1496 // It is necessary to update the groups.
1497 // TODO verify if this needs to be done all the time
1498 m_need_prepare_dump = true;
1499
1500 // Indicates that a compactReference() will also be required
1501 // during the dump.
1502 // NOTE: specifying this will also force a recompacting during prepareForDump()
1503 // and this compaction is unnecessary in this case.
1504 // TODO: look into how to indicate to prepareForDump() that we only want to
1505 // perform a compactReference().
1506 m_item_need_prepare_dump = true;
1507}
1508
1509/*---------------------------------------------------------------------------*/
1510/*---------------------------------------------------------------------------*/
1515compactItems(bool do_sort)
1516{
1517 _compactOnlyItems(do_sort);
1518
1519 if (!m_use_legacy_compact_item) {
1520 // It is necessary to update the groups
1521 // after a compactReferences().
1522 _applyCheckNeedUpdateOnGroups();
1523 }
1524}
1525
1526/*---------------------------------------------------------------------------*/
1527/*---------------------------------------------------------------------------*/
1532_compactItems(bool do_sort)
1533{
1534 IMeshCompactMng* compact_mng = mesh()->_compactMng();
1535 IMeshCompacter* compacter = compact_mng->beginCompact(this);
1536
1537 try {
1538 compacter->setSorted(do_sort);
1539 compacter->doAllActions();
1540 }
1541 catch (...) {
1542 compact_mng->endCompact();
1543 throw;
1544 }
1545 compact_mng->endCompact();
1546}
1547
1548/*---------------------------------------------------------------------------*/
1549/*---------------------------------------------------------------------------*/
1550
1551void ItemFamily::
1552beginCompactItems(ItemFamilyCompactInfos& compact_infos)
1553{
1554 m_infos->beginCompactItems(compact_infos);
1555
1556 if (arcaneIsCheck())
1557 m_infos->checkValid();
1558
1559 Int32ConstArrayView new_to_old_ids = compact_infos.newToOldLocalIds();
1560 Int32ConstArrayView old_to_new_ids = compact_infos.oldToNewLocalIds();
1561
1562 for (auto& c : m_source_incremental_item_connectivities)
1563 c->notifySourceFamilyLocalIdChanged(new_to_old_ids);
1564
1565 for (auto& c : m_target_incremental_item_connectivities)
1566 c->notifyTargetFamilyLocalIdChanged(old_to_new_ids);
1567
1568 for (IItemConnectivity* c : m_source_item_connectivities)
1569 c->notifySourceFamilyLocalIdChanged(new_to_old_ids);
1570
1572 c->notifyTargetFamilyLocalIdChanged(old_to_new_ids);
1573
1575 m_connectivity_mng->notifyLocalIdChanged(this, old_to_new_ids, nbItem());
1576
1577 // Compacting internal variables associated with the entities
1578 {
1579 if (m_parent_family_depth > 0)
1580 m_internal_variables->m_items_nb_parent.variable()->compact(new_to_old_ids);
1581
1582 _updateItemViews();
1583 }
1584}
1585
1586/*---------------------------------------------------------------------------*/
1587/*---------------------------------------------------------------------------*/
1588
1589void ItemFamily::
1590finishCompactItems(ItemFamilyCompactInfos& compact_infos)
1591{
1592 if (arcaneIsCheck())
1593 m_infos->checkValid();
1594
1595 m_infos->finishCompactItems(compact_infos);
1596
1597 for (ItemConnectivitySelector* ics : m_connectivity_selector_list)
1598 ics->compactConnectivities();
1599}
1600
1601/*---------------------------------------------------------------------------*/
1602/*---------------------------------------------------------------------------*/
1612{
1613 ARCANE_ASSERT(source.size() == destination.size(),
1614 ("Can't copy. Source and destination have different size !"));
1615
1616 if (source.size() != 0) {
1617 for (IVariable* var : m_used_variables) {
1618 // (HP) : as seen with Gilles and Stéphane, we do not apply a filter at this level
1619 // // if the variable is temporary or no restore, we do not copy it
1620 // if (!(var->property() & (IVariable::PTemporary | IVariable::PNoRestore))) {
1621 //if (var->itemFamily()==this) {
1622 var->copyItemsValues(source, destination);
1623 }
1624 for (IVariable* var : m_used_shmem_variables) {
1625 var->copyItemsValues(source, destination);
1626 }
1627 }
1628}
1629
1630/*---------------------------------------------------------------------------*/
1631/*---------------------------------------------------------------------------*/
1643 Int32ConstArrayView second_source,
1644 Int32ConstArrayView destination)
1645{
1646 ARCANE_ASSERT(first_source.size() == destination.size(),
1647 ("Can't copy. : first_source and destination have different size !"));
1648 ARCANE_ASSERT(second_source.size() == destination.size(),
1649 ("Can't copy : second_source and destination have different size !"));
1650
1651 if (first_source.size() != 0) {
1652 for (IVariable* var : m_used_variables) {
1654 var->copyItemsMeanValues(first_source, second_source, destination);
1655 }
1656 }
1657 for (IVariable* var : m_used_shmem_variables) {
1659 var->copyItemsMeanValues(first_source, second_source, destination);
1660 }
1661 }
1662 }
1663}
1664
1665/*---------------------------------------------------------------------------*/
1666/*---------------------------------------------------------------------------*/
1675{
1676 Int32ConstArrayView new_to_old_ids = compact_infos.newToOldLocalIds();
1677 Int32ConstArrayView old_to_new_ids = compact_infos.oldToNewLocalIds();
1678
1679 for (IVariable* var : m_used_variables) {
1680 debug(Trace::High) << "Compact variable " << var->fullName();
1681 var->compact(new_to_old_ids);
1682 }
1683 for (IVariable* var : m_used_shmem_variables) {
1684 debug(Trace::High) << "Compact shmem variable " << var->fullName();
1685 var->compact(new_to_old_ids);
1686 }
1687
1688 m_variable_synchronizer->changeLocalIds(old_to_new_ids);
1689
1690 for (ItemGroupList::Enumerator i(m_item_groups); ++i;) {
1691 ItemGroup group = *i;
1692 debug(Trace::High) << "Change group Ids: " << group.name();
1693 group.internal()->changeIds(old_to_new_ids);
1694 if (group.hasSynchronizer())
1695 group.synchronizer()->changeLocalIds(old_to_new_ids);
1696 }
1697
1698 for (Integer i = 0; i < m_child_families.size(); ++i)
1699 m_child_families[i]->_compactFromParentFamily(compact_infos);
1700
1701 info(4) << "End compact family=" << fullName()
1702 << " max_local_id=" << maxLocalId()
1703 << " nb_item=" << nbItem();
1704
1705 // After compaction, variables will be allocated with the number
1706 // of elements being the number of entities (this is in DynamicMeshKindInfos::finishCompactItems()
1707 // where maxLocalId() becomes equal to nbItem()).
1708 m_current_variable_item_size = nbItem();
1709}
1710
1711/*---------------------------------------------------------------------------*/
1712/*---------------------------------------------------------------------------*/
1719#ifdef NEED_MERGE
1720void ItemFamily::
1721compactConnectivities()
1722{
1723 Int32ConstArrayView new_to_old_ids = m_infos.newToOldLocalIds();
1724 Int32ConstArrayView old_to_new_ids = m_infos.oldToNewLocalIds();
1725 for (IItemConnectivity* c : m_source_connectivities)
1726 c->notifySourceFamilyLocalIdChanged(new_to_old_ids);
1727
1728 for (IItemConnectivity* c : m_target_connectivities)
1729 c->notifyTargetFamilyLocalIdChanged(old_to_new_ids);
1730
1732 m_connectivity_mng->notifyLocalIdChanged(this, old_to_new_ids, nbItem());
1733}
1734#endif
1735
1736/*---------------------------------------------------------------------------*/
1737/*---------------------------------------------------------------------------*/
1738
1741{
1742 debug() << "Compacting child family " << fullName();
1743 if (m_parent_family_depth > 1)
1744 throw NotImplementedException(A_FUNCINFO, "Too deep parent family: not yet implemented");
1745 Int32ConstArrayView old_to_new_lids(compact_infos.oldToNewLocalIds());
1746 ARCANE_ASSERT((nbItem() == 0 || !old_to_new_lids.empty()), ("Empty oldToNewLocalIds"));
1747 debug() << "\tfrom parent family " << m_parent_family->name();
1748 if (this == m_parent_family)
1749 return; // already self compacted
1750 ItemInternalArrayView items(itemsInternal());
1751 for (Integer z = 0, zs = items.size(); z < zs; ++z) {
1752 ItemInternal* item = items[z];
1753 Int32 old_parent_lid = item->parentId(0); // depth==1 only !!
1754 item->setParent(0, old_to_new_lids[old_parent_lid]);
1755 }
1756 // If depth>1, it would be better to propagate the compaction by modifying the
1757 // oldToNewLocalIds of the current sub-mesh families and calling
1758 // DynamicMesh::_compactItems in cascade (starting from this sub-mesh)
1759}
1760
1761/*---------------------------------------------------------------------------*/
1762/*---------------------------------------------------------------------------*/
1763
1765internalRemoveItems(Int32ConstArrayView local_ids, bool keep_ghost)
1766{
1767 ARCANE_UNUSED(local_ids);
1768 ARCANE_UNUSED(keep_ghost);
1769 ARCANE_THROW(NotSupportedException, "this kind of family doesn't support this operation");
1770}
1771
1772/*---------------------------------------------------------------------------*/
1773/*---------------------------------------------------------------------------*/
1774
1775void ItemFamily::
1776_checkValid()
1777{
1778 // Checks that the part number is the same as the mesh's part number
1779 {
1780 Int32 part_rank = m_mesh->meshPartInfo().partRank();
1781 if (m_sub_domain_id != part_rank)
1782 ARCANE_FATAL("Family {0} Bad value for partRank ({1}) expected={2}",
1783 fullName(), m_sub_domain_id, part_rank);
1784 }
1785}
1786
1787/*---------------------------------------------------------------------------*/
1788/*---------------------------------------------------------------------------*/
1789
1790void ItemFamily::
1791_reserveInfosMemory(Integer memory)
1792{
1793 ARCANE_UNUSED(memory);
1794}
1795
1796/*---------------------------------------------------------------------------*/
1797/*---------------------------------------------------------------------------*/
1798
1799void ItemFamily::
1800_resizeInfos(Integer new_size)
1801{
1802 ARCANE_UNUSED(new_size);
1803}
1804
1805/*---------------------------------------------------------------------------*/
1806/*---------------------------------------------------------------------------*/
1807
1808Integer ItemFamily::
1809_allocMany(Integer memory)
1810{
1811 ARCANE_UNUSED(memory);
1812 return 0;
1813}
1814
1815/*---------------------------------------------------------------------------*/
1816/*---------------------------------------------------------------------------*/
1817
1818ItemSharedInfoWithType* ItemFamily::
1819_findSharedInfo(ItemTypeInfo* type)
1820{
1821 return m_item_shared_infos->findSharedInfo(type);
1822}
1823
1824/*---------------------------------------------------------------------------*/
1825/*---------------------------------------------------------------------------*/
1826
1827void ItemFamily::
1828_updateSharedInfo()
1829{
1830 //TODO: Check if this is still useful
1831 m_need_prepare_dump = true;
1832}
1833
1834/*---------------------------------------------------------------------------*/
1835/*---------------------------------------------------------------------------*/
1836
1837void ItemFamily::
1838_allocateInfos(ItemInternal* item, Int64 uid, ItemTypeInfo* type)
1839{
1840 ItemSharedInfoWithType* isi = _findSharedInfo(type);
1841 _allocateInfos(item, uid, isi);
1842}
1843
1844/*---------------------------------------------------------------------------*/
1845/*---------------------------------------------------------------------------*/
1846
1847void ItemFamily::
1848_resizeItemVariables(Int32 new_size, bool force_resize)
1849{
1850 bool is_resize = MeshUtils::checkResizeArray(*m_items_unique_id, new_size + 1, force_resize);
1851 is_resize |= MeshUtils::checkResizeArray(*m_items_owner, new_size + 1, force_resize);
1852 is_resize |= MeshUtils::checkResizeArray(*m_items_flags, new_size + 1, force_resize);
1853 is_resize |= MeshUtils::checkResizeArray(*m_items_type_id, new_size + 1, force_resize);
1854 if (m_parent_family_depth > 0)
1855 is_resize |= MeshUtils::checkResizeArray(*m_items_nb_parent, new_size, force_resize);
1856 if (is_resize)
1857 _updateItemViews();
1858
1859 // Positions the values for the null entity.
1860 // NOTE: check if this should be done at initialization.
1861 (*m_items_unique_id)[0] = NULL_ITEM_UNIQUE_ID;
1862 (*m_items_flags)[0] = 0;
1863 (*m_items_owner)[0] = A_NULL_RANK;
1864 (*m_items_type_id)[0] = IT_NullType;
1865}
1866
1867/*---------------------------------------------------------------------------*/
1868/*---------------------------------------------------------------------------*/
1869
1870void ItemFamily::
1871_allocateInfos(ItemInternal* item, Int64 uid, ItemSharedInfoWithType* isi)
1872{
1873 // TODO: do simultaneously with the realloc of the uniqueId() variable
1874 // the realloc of the m_source_incremental_item_connectivities.
1875 Int32 local_id = item->localId();
1876 _resizeItemVariables(local_id + 1, false);
1877
1878 // TODO: check if still useful because ItemInternal::reinitialize() must do it
1879 //(*m_items_unique_id)[local_id] = uid;
1880
1881 ItemTypeId iti = isi->itemTypeId();
1882 item->_setSharedInfo(isi->sharedInfo(), iti);
1883
1884 item->reinitialize(uid, m_default_sub_domain_owner, m_sub_domain_id);
1885 ++m_nb_allocate_info;
1886 // Notify the incremental connectivities that we added an item to the source
1887 for (auto& c : m_source_incremental_item_connectivities)
1888 c->notifySourceItemAdded(ItemLocalId(local_id));
1889}
1890
1891/*---------------------------------------------------------------------------*/
1892/*---------------------------------------------------------------------------*/
1893
1894void ItemFamily::
1895_preAllocate(Int32 nb_item, bool pre_alloc_connectivity)
1896{
1897 if (nb_item > 1000)
1898 m_infos->itemsMap().resize(nb_item, true);
1899 _resizeItemVariables(nb_item, false);
1900 for (auto& c : m_source_incremental_item_connectivities)
1901 c->reserveMemoryForNbSourceItems(nb_item, pre_alloc_connectivity);
1902}
1903
1904/*---------------------------------------------------------------------------*/
1905/*---------------------------------------------------------------------------*/
1906
1907void ItemFamily::
1908_notifyDataIndexChanged()
1909{
1910 _updateItemViews();
1911}
1912
1913/*---------------------------------------------------------------------------*/
1914/*---------------------------------------------------------------------------*/
1915
1917getCommunicatingSubDomains(Int32Array& sub_domains) const
1918{
1919 Int32ConstArrayView ranks = m_variable_synchronizer->communicatingRanks();
1920 Integer s = ranks.size();
1921 sub_domains.resize(s);
1922 sub_domains.copy(ranks);
1923}
1924
1925/*---------------------------------------------------------------------------*/
1926/*---------------------------------------------------------------------------*/
1927
1930{
1931 // Only calculate synchronization info if we are in parallel
1932 // and the number of parts equals the number of ranks of the parallelMng(),
1933 // which is not the case during recovery after a change in the number of
1934 // sub-domains.
1935 if (m_is_parallel && m_mesh->meshPartInfo().nbPart() == parallelMng()->commSize()) {
1936 m_variable_synchronizer->compute();
1938 }
1939}
1940
1941/*---------------------------------------------------------------------------*/
1942/*---------------------------------------------------------------------------*/
1943// TODO move this method outside of ItemFamily
1946{
1947 if (!v)
1948 return;
1949 if (v->itemFamily() != this && v->itemGroup().itemFamily() != this)
1950 throw ArgumentException(A_FUNCINFO, "Variable not in this family");
1952 op.setItemFamily(this);
1953 op.addVariable(v);
1954 op.applyOperation(operation);
1955}
1956
1957/*---------------------------------------------------------------------------*/
1958/*---------------------------------------------------------------------------*/
1959// TODO move this method outside of ItemFamily
1962{
1964 operation = v->dataFactoryMng()->createDataOperation(reduction);
1965 reduceFromGhostItems(v, operation.get());
1966}
1967
1968/*---------------------------------------------------------------------------*/
1969/*---------------------------------------------------------------------------*/
1970
1971Int64ArrayView* ItemFamily::
1972uniqueIds()
1973{
1974 return &m_items_unique_id_view;
1975}
1976
1977/*---------------------------------------------------------------------------*/
1978/*---------------------------------------------------------------------------*/
1979
1981findVariable(const String& var_name, bool throw_exception)
1982{
1984 StringBuilder vname = mesh()->name();
1985 vname += "_";
1986 vname += name();
1987 vname += "_";
1988 vname += var_name;
1989 IVariable* var = vm->findVariableFullyQualified(vname.toString());
1990 if (!var && throw_exception) {
1991 ARCANE_FATAL("No variable named '{0}' in family '{1}'", var_name, name());
1992 }
1993 return var;
1994}
1995
1996/*---------------------------------------------------------------------------*/
1997/*---------------------------------------------------------------------------*/
1998
2000clearItems()
2001{
2002 m_infos->clear();
2003
2004 endUpdate();
2005}
2006
2007/*---------------------------------------------------------------------------*/
2008/*---------------------------------------------------------------------------*/
2009
2012{
2013 Integer nb_item = unique_ids.size();
2014 Int64UniqueArray all_unique_ids;
2015 IParallelMng* pm = m_mesh->parallelMng();
2016 pm->allGatherVariable(unique_ids, all_unique_ids);
2017 HashTableMapT<Int64, Integer> items_map(nb_item * 2, true);
2018 info() << "ItemFamily::checkUniqueIds name=" << name() << " n=" << nb_item
2019 << " total=" << all_unique_ids.size();
2020 for (Integer i = 0; i < nb_item; ++i)
2021 items_map.add(unique_ids[i], 0);
2022 for (Integer i = 0, is = all_unique_ids.size(); i < is; ++i) {
2023 HashTableMapT<Int64, Integer>::Data* data = items_map.lookup(all_unique_ids[i]);
2024 if (data)
2025 ++data->value();
2026 }
2027 for (Integer i = 0; i < nb_item; ++i) {
2028 Integer nb_ref = items_map[unique_ids[i]];
2029 if (nb_ref != 1) {
2030 fatal() << "Duplicate unique_id=" << unique_ids[i];
2031 }
2032 }
2033}
2034
2035/*---------------------------------------------------------------------------*/
2036/*---------------------------------------------------------------------------*/
2037
2039findAdjencyItems(const ItemGroup& group, const ItemGroup& sub_group,
2040 eItemKind link_kind, Integer layer)
2041{
2042 return findAdjacencyItems(group, sub_group, link_kind, layer);
2043}
2044
2046findAdjacencyItems(const ItemGroup& group, const ItemGroup& sub_group,
2047 eItemKind link_kind, Integer layer)
2048{
2049 AdjacencyInfo at(group, sub_group, link_kind, layer);
2050 auto i = m_adjacency_groups.find(at);
2051
2052 if (i == m_adjacency_groups.end()) {
2053 debug() << "** BUILD ADJENCY_ITEMS : " << group.name() << " x "
2054 << sub_group.name() << " link=" << link_kind << " nblayer=" << layer;
2055 ItemPairGroup v(new ItemPairGroupImpl(group, sub_group));
2056 mesh()->utilities()->computeAdjacency(v, link_kind, layer);
2057 m_adjacency_groups.insert(std::make_pair(at, v));
2058 return v;
2059 }
2060 debug() << "** FOUND KNOWN ADJENCY_ITEMS! : " << group.name() << " x "
2061 << sub_group.name() << " link=" << link_kind << " nblayer=" << layer;
2062 return i->second;
2063}
2064
2065/*---------------------------------------------------------------------------*/
2066/*---------------------------------------------------------------------------*/
2067
2070{
2071 return m_local_connectivity_info;
2072}
2073
2074/*---------------------------------------------------------------------------*/
2075/*---------------------------------------------------------------------------*/
2076
2079{
2080 return m_global_connectivity_info;
2081}
2082
2083/*---------------------------------------------------------------------------*/
2084/*---------------------------------------------------------------------------*/
2085
2087setHasUniqueIdMap(bool v)
2088{
2089 ARCANE_UNUSED(v);
2090 throw NotSupportedException(A_FUNCINFO, "this kind of family doesn't support this function");
2091}
2092
2093/*---------------------------------------------------------------------------*/
2094/*---------------------------------------------------------------------------*/
2095
2097hasUniqueIdMap() const
2098{
2099 return true;
2100}
2101
2102/*---------------------------------------------------------------------------*/
2103/*---------------------------------------------------------------------------*/
2104
2106view(Int32ConstArrayView local_ids)
2107{
2108 return ItemVectorView(itemInfoListView(), local_ids);
2109}
2110
2111/*---------------------------------------------------------------------------*/
2112/*---------------------------------------------------------------------------*/
2113
2115view()
2116{
2117 return allItems().view();
2118}
2119
2120/*---------------------------------------------------------------------------*/
2121/*---------------------------------------------------------------------------*/
2122
2123void ItemFamily::
2124_addVariable(IVariable* var)
2125{
2126 //info() << "Add var=" << var->fullName() << " to family=" << name();
2127 if (var->itemFamily() != this)
2128 ARCANE_FATAL("Can not add a variable to a different family");
2129
2130 if (var->property() & IVariable::PInShMem)
2131 m_used_shmem_variables.insert(var);
2132 else
2133 m_used_variables.insert(var);
2134}
2135
2136/*---------------------------------------------------------------------------*/
2137/*---------------------------------------------------------------------------*/
2138
2139void ItemFamily::
2140_removeVariable(IVariable* var)
2141{
2142 //info() << "Remove var=" << var->fullName() << " to family=" << name();
2143 if (var->property() & IVariable::PInShMem)
2144 m_used_shmem_variables.erase(var);
2145 else
2146 m_used_variables.erase(var);
2147}
2148
2149/*---------------------------------------------------------------------------*/
2150/*---------------------------------------------------------------------------*/
2151
2154{
2155 for (IVariable* var : m_used_variables) {
2156 collection.add(var);
2157 }
2158 for (IVariable* var : m_used_shmem_variables) {
2159 collection.add(var);
2160 }
2161}
2162
2163/*---------------------------------------------------------------------------*/
2164/*---------------------------------------------------------------------------*/
2165
2168{
2169 return m_variable_synchronizer.get();
2170}
2171
2172/*---------------------------------------------------------------------------*/
2173/*---------------------------------------------------------------------------*/
2174
2177{
2178 if (m_item_sort_function == sort_function)
2179 return;
2180 delete m_item_sort_function;
2181 m_item_sort_function = sort_function;
2182 if (!m_item_sort_function)
2183 m_item_sort_function = _defaultItemSortFunction();
2184}
2185
2186/*---------------------------------------------------------------------------*/
2187/*---------------------------------------------------------------------------*/
2188
2190itemSortFunction() const
2191{
2192 return m_item_sort_function;
2193}
2194
2195/*---------------------------------------------------------------------------*/
2196/*---------------------------------------------------------------------------*/
2197
2200{
2201 m_variable_synchronizer->synchronize(variables);
2202}
2203
2204/*---------------------------------------------------------------------------*/
2205/*---------------------------------------------------------------------------*/
2206
2209{
2210 m_variable_synchronizer->synchronize(variables, local_ids);
2211}
2212
2213/*---------------------------------------------------------------------------*/
2214/*---------------------------------------------------------------------------*/
2215
2218{
2219 ARCANE_UNUSED(unique_ids);
2220 ARCANE_UNUSED(items);
2221 ARCANE_UNUSED(owners);
2222 ARCANE_THROW(NotImplementedException, "this kind of family doesn't support this operation yet. Only DoF at present.");
2223}
2224
2225/*---------------------------------------------------------------------------*/
2226/*---------------------------------------------------------------------------*/
2227
2229removeItems2(ItemDataList& item_data_list)
2230{
2231 if (!m_mesh->itemFamilyNetwork())
2232 ARCANE_FATAL("Family name='{0}': IMesh::itemFamilyNetwork() is null", name());
2233
2234 ItemData& item_data = item_data_list[itemKind()];
2235 // 1-Prepare : Get child connectivities and families
2236 SharedArray<IIncrementalItemConnectivity*> child_connectivities = m_mesh->itemFamilyNetwork()->getChildDependencies(this); // TODO : change return type ? (List to Array ?)
2237 UniqueArray<IItemFamily*> child_families;
2238 UniqueArray<IIncrementalItemConnectivity*> child_families_to_current_family;
2239 UniqueArray<ItemScalarProperty<bool>> child_families_has_extra_parent_properties; // To indicate wheter child items have other parents.
2240 Integer index = 0;
2241 for (auto child_connectivity : child_connectivities) {
2242 child_families.add(child_connectivity->targetFamily());
2243 child_families_to_current_family.add(m_mesh->itemFamilyNetwork()->getConnectivity(child_families.back(), this, connectivityName(child_families.back(), this)));
2244 if (child_families_to_current_family.back() == nullptr)
2245 fatal() << "removeItems2 needs reverse connectivity. Missing Connectivity " << connectivityName(child_families.back(), this);
2246 child_families_has_extra_parent_properties.add(ItemScalarProperty<bool>());
2247 child_families_has_extra_parent_properties.back().resize(child_families.back(), false);
2248 for (auto parent_connectivity : m_mesh->itemFamilyNetwork()->getParentDependencies(child_families.back())) { // exclure parent actuel
2249 if (parent_connectivity == child_connectivity)
2250 continue;
2251 ItemVector connected_items;
2252 _getConnectedItems(parent_connectivity, connected_items);
2253 _fillHasExtraParentProperty(child_families_has_extra_parent_properties[index], connected_items);
2254 }
2255 index++;
2256 }
2257 // 2-Propagates item removal to child families
2258 Int64ArrayView removed_item_lids = item_data.itemInfos().view(); // Todo change ItemData to store removed item lids in Int32
2259 for (auto removed_item_lid_int64 : removed_item_lids) {
2260 Int32 removed_item_lid = CheckedConvert::toInt32(removed_item_lid_int64);
2261 index = 0;
2262 for (auto child_connectivity : child_connectivities) {
2263 ConnectivityItemVector child_con_accessor(child_connectivity);
2264 ENUMERATE_ITEM (connected_item, child_con_accessor.connectedItems(ItemLocalId(removed_item_lid))) {
2265 if (!this->itemsInternal()[removed_item_lid]->isDetached()) { // test necessary when doing removeDetached (the relations are already deleted).
2266 child_families_to_current_family[index]->removeConnectedItem(ItemLocalId(connected_item), ItemLocalId(removed_item_lid));
2267 }
2268 // Check if connected item is to remove
2269 if (!child_families_has_extra_parent_properties[index][connected_item] && child_families_to_current_family[index]->nbConnectedItem(ItemLocalId(connected_item)) == 0) {
2270 item_data_list[child_connectivity->targetFamily()->itemKind()].itemInfos().add((Int64)connected_item.localId());
2271 }
2272 }
2273 index++;
2274 }
2275 }
2276 // => merge this loop with previous one ?
2277 // 3-1 Remove relations for child relations
2278 for (auto removed_item_lid_int64 : removed_item_lids) {
2279 Int32 removed_item_lid = CheckedConvert::toInt32(removed_item_lid_int64);
2280 for (auto child_relation : m_mesh->itemFamilyNetwork()->getChildRelations(this)) {
2281 ConnectivityItemVector connectivity_accessor(child_relation);
2282 ENUMERATE_ITEM (connected_item, connectivity_accessor.connectedItems(ItemLocalId(removed_item_lid))) {
2283 child_relation->removeConnectedItem(ItemLocalId(removed_item_lid), ItemLocalId(connected_item));
2284 }
2285 }
2286 }
2287 // 3-2 Remove relations for parent relations
2288 ItemScalarProperty<bool> is_removed_item;
2289 is_removed_item.resize(this, false);
2290 for (auto removed_item_lid_int64 : removed_item_lids) {
2291 Int32 removed_item_lid = CheckedConvert::toInt32(removed_item_lid_int64);
2292 is_removed_item[*(this->itemsInternal()[removed_item_lid])] = true;
2293 }
2294 for (auto parent_relation : m_mesh->itemFamilyNetwork()->getParentRelations(this)) {
2295 for (auto source_item : parent_relation->sourceFamily()->itemsInternal()) {
2296 if (source_item->isSuppressed())
2297 continue;
2298 ConnectivityItemVector connectivity_accessor(parent_relation);
2299 ENUMERATE_ITEM (connected_item, connectivity_accessor.connectedItems(ItemLocalId(source_item))) {
2300 if (is_removed_item[connected_item])
2301 parent_relation->removeConnectedItem(ItemLocalId(source_item), connected_item);
2302 }
2303 }
2304 }
2305 // 4-Remove items. Child items will be removed by an automatic call of removeItems2 on their family...
2306 for (auto removed_item_lid_int64 : removed_item_lids) {
2307 Int32 removed_item_lid = CheckedConvert::toInt32(removed_item_lid_int64);
2308 ItemInternal* removed_item = m_infos->itemInternal(removed_item_lid);
2309 if (removed_item->isDetached()) {
2310 m_infos->removeDetachedOne(removed_item);
2311 }
2312 else {
2313 m_infos->removeOne(removed_item);
2314 }
2315 }
2316 this->endUpdate(); // endUpdate is needed since we then go deeper in the dependency graph and will need to enumerate this changed family.
2317}
2318
2319/*---------------------------------------------------------------------------*/
2320/*---------------------------------------------------------------------------*/
2321
2322void ItemFamily::
2323_getConnectedItems(IIncrementalItemConnectivity* parent_connectivity, ItemVector& target_family_connected_items)
2324{
2325 ConnectivityItemVector connectivity_accessor(parent_connectivity);
2326 for (auto source_item : parent_connectivity->sourceFamily()->itemsInternal()) {
2327 if (source_item->isSuppressed())
2328 continue;
2329 target_family_connected_items.add(connectivity_accessor.connectedItems(ItemLocalId(source_item)).localIds());
2330 }
2331}
2332
2333/*---------------------------------------------------------------------------*/
2334/*---------------------------------------------------------------------------*/
2335
2336void ItemFamily::
2337_fillHasExtraParentProperty(ItemScalarProperty<bool>& child_families_has_extra_parent, ItemVectorView connected_items)
2338{
2339 ENUMERATE_ITEM (connected_item, connected_items) {
2340 child_families_has_extra_parent[connected_item] = true;
2341 }
2342}
2343
2344/*---------------------------------------------------------------------------*/
2345/*---------------------------------------------------------------------------*/
2346
2347void ItemFamily::
2348_detachCells2(Int32ConstArrayView local_ids)
2349{
2350 //- Only cells are detached, i.e., no parent dependencies are to be found
2351 ARCANE_ASSERT((m_mesh->itemFamilyNetwork()->getParentDependencies(this).empty()), ("Only cells are detached, no parent dependencies are to be found."))
2352 // Remove all parent and child relations. Keep child dependencies => used when removing detached cells. No parent dependencies
2353 // 1 Remove relations for child relations
2354 for (auto removed_item_lid : local_ids) {
2355 for (auto child_relation : m_mesh->itemFamilyNetwork()->getChildRelations(this)) {
2356 ConnectivityItemVector connectivity_accessor(child_relation);
2357 ENUMERATE_ITEM (connected_item, connectivity_accessor.connectedItems(ItemLocalId(removed_item_lid))) {
2358 child_relation->removeConnectedItem(ItemLocalId(removed_item_lid), ItemLocalId(connected_item));
2359 }
2360 }
2361 }
2362 // 2 Remove relations for parent relations
2363 ItemScalarProperty<bool> is_detached_item;
2364 is_detached_item.resize(this, false);
2365 for (auto detached_item_lid : local_ids) {
2366 is_detached_item[*(this->itemsInternal()[detached_item_lid])] = true;
2367 }
2368 for (auto parent_relation : m_mesh->itemFamilyNetwork()->getParentRelations(this)) {
2369 for (auto source_item : parent_relation->sourceFamily()->itemsInternal()) {
2370 if (source_item->isSuppressed())
2371 continue;
2372 ConnectivityItemVector connectivity_accessor(parent_relation);
2373 ENUMERATE_ITEM (connected_item, connectivity_accessor.connectedItems(ItemLocalId(source_item))) {
2374 if (is_detached_item[connected_item]) {
2375 parent_relation->removeConnectedItem(ItemLocalId(source_item), connected_item);
2376 }
2377 }
2378 }
2379 }
2380 // 4-Detach items.
2381 for (auto detached_item_lid : local_ids) {
2382 m_infos->detachOne(m_infos->itemInternal(detached_item_lid)); // when family/mesh endUpdate is done? needed?
2383 }
2384}
2385
2386/*---------------------------------------------------------------------------*/
2387/*---------------------------------------------------------------------------*/
2388
2389void ItemFamily::
2390removeNeedRemoveMarkedItems()
2391{
2392 ItemInternalMap& item_map = itemsMap();
2393 if (item_map.count() == 0)
2394 return;
2395
2396 if (!m_mesh->itemFamilyNetwork())
2397 ARCANE_FATAL("Family name='{0}': IMesh::itemFamilyNetwork() is null", name());
2398 if (!IItemFamilyNetwork::plug_serializer)
2399 ARCANE_FATAL("family name='{0}': removeNeedMarkedItems() cannot be called if ItemFamilyNetwork is unplugged.", name());
2400
2401 UniqueArray<ItemInternal*> items_to_remove;
2402 UniqueArray<Int32> items_to_remove_lids;
2403 items_to_remove.reserve(1000);
2404 items_to_remove_lids.reserve(1000);
2405
2406 item_map.eachItem([&](impl::ItemBase item) {
2407 Integer f = item.flags();
2408 if (f & ItemFlags::II_NeedRemove) {
2409 f &= ~ItemFlags::II_NeedRemove & ItemFlags::II_Suppressed;
2410 item.toMutable().setFlags(f);
2411 items_to_remove.add(item._itemInternal());
2412 items_to_remove_lids.add(item.localId());
2413 }
2414 });
2415 info() << "Number of " << itemKind() << " of family " << name() << " to remove: " << items_to_remove.size();
2416 if (items_to_remove.size() == 0)
2417 return;
2418
2419 // Update connectivities => remove all con pointing on the removed items
2420 // TODO the nearly same procedure is done in _detachCells2: mutualize in a method (watch out the connectivities used are parentConnectivities or parentRelations...)
2421 ItemScalarProperty<bool> is_removed_item;
2422 is_removed_item.resize(this, false);
2423 for (auto removed_item : items_to_remove) {
2424 is_removed_item[*removed_item] = true;
2425 }
2426 //for (auto parent_connectivity : m_mesh->itemFamilyNetwork()->getParentConnectivities(this)) {
2427 for (auto parent_connectivity : m_mesh->itemFamilyNetwork()->getParentRelations(this)) {
2428 for (auto source_item : parent_connectivity->sourceFamily()->itemsInternal()) {
2429 if (source_item->isSuppressed())
2430 continue;
2431 ConnectivityItemVector connectivity_accessor(parent_connectivity);
2432 ENUMERATE_ITEM (connected_item, connectivity_accessor.connectedItems(ItemLocalId(source_item))) {
2433 if (is_removed_item[connected_item]) {
2434 parent_connectivity->removeConnectedItem(ItemLocalId(source_item), connected_item);
2435 }
2436 }
2437 }
2438 }
2439 // Remove items
2440 m_infos->removeMany(items_to_remove_lids);
2441}
2442
2443/*---------------------------------------------------------------------------*/
2444/*---------------------------------------------------------------------------*/
2445
2447{
2448 public:
2449
2450 bool operator()(const ItemInternal* item1, const ItemInternal* item2) const
2451 {
2452 // Destroyed entities must be placed at the end of the list.
2453 //cout << "Compare: " << item1->uniqueId() << " " << item2->uniqueId() << '\n';
2454 bool s1 = item1->isSuppressed();
2455 bool s2 = item2->isSuppressed();
2456 if (s1 && !s2)
2457 return false;
2458 if (!s1 && s2)
2459 return true;
2460 return item1->uniqueId() < item2->uniqueId();
2461 }
2462};
2463
2464/*---------------------------------------------------------------------------*/
2465/*---------------------------------------------------------------------------*/
2466
2467IItemInternalSortFunction* ItemFamily::
2468_defaultItemSortFunction()
2469{
2471}
2472
2473/*---------------------------------------------------------------------------*/
2474/*---------------------------------------------------------------------------*/
2475
2476void ItemFamily::
2477setPolicyMng(IItemFamilyPolicyMng* policy_mng)
2478{
2479 if (m_policy_mng == policy_mng)
2480 return;
2481 if (m_policy_mng)
2482 ARCANE_FATAL("PolicyMng already set");
2483 m_policy_mng = policy_mng;
2484}
2485
2486/*---------------------------------------------------------------------------*/
2487/*---------------------------------------------------------------------------*/
2488
2489void ItemFamily::
2490addSourceConnectivity(IItemConnectivity* connectivity)
2491{
2492 m_source_item_connectivities.insert(connectivity);
2493}
2494
2495/*---------------------------------------------------------------------------*/
2496/*---------------------------------------------------------------------------*/
2497
2498void ItemFamily::
2499addTargetConnectivity(IItemConnectivity* connectivity)
2500{
2501 m_target_item_connectivities.insert(connectivity);
2502}
2503
2504/*---------------------------------------------------------------------------*/
2505/*---------------------------------------------------------------------------*/
2506
2507void ItemFamily::
2508removeSourceConnectivity(IItemConnectivity* connectivity)
2509{
2510 m_source_item_connectivities.erase(m_source_item_connectivities.find(connectivity));
2511}
2512
2513/*---------------------------------------------------------------------------*/
2514/*---------------------------------------------------------------------------*/
2515
2516void ItemFamily::
2517removeTargetConnectivity(IItemConnectivity* connectivity)
2518{
2519 m_target_item_connectivities.erase(m_target_item_connectivities.find(connectivity));
2520}
2521
2522/*---------------------------------------------------------------------------*/
2523/*---------------------------------------------------------------------------*/
2524
2525void ItemFamily::
2526setConnectivityMng(IItemConnectivityMng* connectivity_mng)
2527{
2528 ARCANE_ASSERT((m_connectivity_mng == NULL || m_connectivity_mng == connectivity_mng),
2529 ("Connectivity Manager must be unique"))
2530 m_connectivity_mng = connectivity_mng;
2531}
2532
2533/*---------------------------------------------------------------------------*/
2534/*---------------------------------------------------------------------------*/
2535
2538{
2539 return m_infos->itemListChangedEvent();
2540}
2541
2542/*---------------------------------------------------------------------------*/
2543/*---------------------------------------------------------------------------*/
2544
2545void ItemFamily::
2546experimentalChangeUniqueId(ItemLocalId local_id, ItemUniqueId unique_id)
2547{
2548 ItemInternal* iitem = _itemInternal(local_id);
2549 Int64 old_uid = iitem->uniqueId();
2550 if (old_uid == unique_id)
2551 return;
2552 //MutableItemBase item_base(local_id,m_common_item_shared_info);
2553 iitem->setUniqueId(unique_id);
2554
2555 if (m_infos->hasUniqueIdMap()) {
2556 ItemInternalMap& item_map = itemsMap();
2557 item_map.remove(old_uid);
2558 item_map.add(unique_id, iitem);
2559 }
2560}
2561
2562/*---------------------------------------------------------------------------*/
2563/*---------------------------------------------------------------------------*/
2564
2565void ItemFamily::
2566_addSourceConnectivity(IIncrementalItemSourceConnectivity* c)
2567{
2568 m_source_incremental_item_connectivities.add(c->toSourceReference());
2569}
2570
2571/*---------------------------------------------------------------------------*/
2572/*---------------------------------------------------------------------------*/
2573
2574void ItemFamily::
2575_addTargetConnectivity(IIncrementalItemTargetConnectivity* c)
2576{
2577 m_target_incremental_item_connectivities.add(c->toTargetReference());
2578}
2579
2580/*---------------------------------------------------------------------------*/
2581/*---------------------------------------------------------------------------*/
2582
2583void ItemFamily::
2584_checkValidConnectivity()
2585{
2586 {
2587 // Checks that there are no null entities.
2588 ENUMERATE_ITEM (i, allItems()) {
2589 Item item = *i;
2590 if (item.null())
2591 ARCANE_FATAL("family={0}: local item lid={1} is null", fullName(), item);
2592 }
2593 }
2594 {
2595 // Checks the consistency of the internal part
2596 ENUMERATE_ITEM (i, allItems()) {
2597 Item item = *i;
2598 Item i1 = item;
2599 Item i2 = m_common_item_shared_info->m_items_internal[item.localId()];
2600 if (i1 != i2)
2601 ARCANE_FATAL("family={0}: incoherent item internal lid={1} i1={2} i2={3}",
2602 fullName(), item.localId(), ItemPrinter(i1), ItemPrinter(i2));
2603 }
2604 }
2605 constexpr Int32 MAX_KIND = ItemInternalConnectivityList::MAX_ITEM_KIND;
2606 std::array<Int32, MAX_KIND> computed_max;
2607 computed_max.fill(0);
2608
2609 for (Integer i = 0; i < MAX_KIND; ++i) {
2610 eItemKind target_kind = static_cast<eItemKind>(i);
2611 IndexedItemConnectivityViewBase con_view{ m_item_connectivity_list.containerView(i), itemKind(), target_kind };
2612 Int32 stored_max_nb = m_item_connectivity_list.maxNbConnectedItem(i);
2613 const Int32 con_nb_item_size = con_view.nbSourceItem();
2614
2615 info(4) << "Family name=" << fullName() << " I=" << i << " nb_item_size=" << con_nb_item_size;
2616
2617 Int32 max_nb = 0;
2618 if (con_nb_item_size != 0) {
2619 // It is necessary to iterate over all entities and not over \a con_nb_item
2620 // because some values may not be valid if there are
2621 // gaps in the numbering.
2622 ENUMERATE_ITEM (i, allItems()) {
2623 Int32 x = con_view.nbItem(i);
2624 if (x > max_nb)
2625 max_nb = x;
2626 }
2627 if (stored_max_nb < max_nb)
2628 ARCANE_FATAL("Bad value for max connected item family={0} kind={1} stored={2} computed={3}",
2629 name(), i, stored_max_nb, max_nb);
2630 computed_max[i] = max_nb;
2631 }
2632 }
2633 // Checks that the value returned by m_local_connectivity_info
2634 // is at least greater than 'computed_max'
2635 {
2636 std::array<Int32, MAX_KIND> stored_max;
2637 stored_max.fill(0);
2638 auto* ci = m_local_connectivity_info;
2639 stored_max[ItemInternalConnectivityList::NODE_IDX] = ci->maxNodePerItem();
2640 stored_max[ItemInternalConnectivityList::EDGE_IDX] = ci->maxEdgePerItem();
2641 stored_max[ItemInternalConnectivityList::FACE_IDX] = ci->maxFacePerItem();
2642 stored_max[ItemInternalConnectivityList::CELL_IDX] = ci->maxCellPerItem();
2643 // For the following two, there is no equivalent in 'ItemConnectivityInfo' so
2644 // we put the calculated values to avoid generating an error.
2645 stored_max[ItemInternalConnectivityList::HPARENT_IDX] = computed_max[ItemInternalConnectivityList::HPARENT_IDX];
2646 stored_max[ItemInternalConnectivityList::HCHILD_IDX] = computed_max[ItemInternalConnectivityList::HCHILD_IDX];
2647 for (Integer i = 0; i < MAX_KIND; ++i)
2648 if (stored_max[i] < computed_max[i])
2649 ARCANE_FATAL("Bad value for local_connectivity_info family={0} kind={1} stored={2} computed={3}",
2650 name(), i, stored_max[i], computed_max[i]);
2651 }
2652 for (auto ics : m_connectivity_selector_list)
2653 ics->checkValidConnectivityList();
2654}
2655
2656/*---------------------------------------------------------------------------*/
2657/*---------------------------------------------------------------------------*/
2658
2659void ItemFamily::
2660_addConnectivitySelector(ItemConnectivitySelector* selector)
2661{
2662 m_connectivity_selector_list.add(selector);
2663}
2664
2665/*---------------------------------------------------------------------------*/
2666/*---------------------------------------------------------------------------*/
2667
2668void ItemFamily::
2669_buildConnectivitySelectors()
2670{
2671 m_connectivity_selector_list_by_item_kind.clear();
2672 m_connectivity_selector_list_by_item_kind.resize(ItemInternalConnectivityList::MAX_ITEM_KIND);
2673 m_connectivity_selector_list_by_item_kind.fill(nullptr);
2674
2675 for (ItemConnectivitySelector* ics : m_connectivity_selector_list) {
2676 ics->build();
2677 Int32 i = ics->itemConnectivityIndex();
2678 if (i >= 0) {
2679 if (m_connectivity_selector_list_by_item_kind[i])
2680 ARCANE_FATAL("Can not have two connectivity selector for same item kind");
2681 m_connectivity_selector_list_by_item_kind[i] = ics;
2682 }
2683 }
2684}
2685
2686/*---------------------------------------------------------------------------*/
2687/*---------------------------------------------------------------------------*/
2688
2689void ItemFamily::
2690_setTopologyModifier(IItemFamilyTopologyModifier* tm)
2691{
2692 delete m_topology_modifier;
2693 m_topology_modifier = tm;
2694}
2695
2696/*---------------------------------------------------------------------------*/
2697/*---------------------------------------------------------------------------*/
2705void ItemFamily::
2706_updateItemsSharedFlag()
2707{
2708 ItemInternalList items(_itemsInternal());
2709 for (Integer i = 0, n = items.size(); i < n; ++i)
2710 items[i]->removeFlags(ItemFlags::II_Shared);
2711 Int32ConstArrayView comm_ranks = m_variable_synchronizer->communicatingRanks();
2712 Integer nb_rank = comm_ranks.size();
2713 // Iterates through the synchronizer's sharedItems() and sets the flag
2714 // II_Shared for the entities in the list.
2715 for (Integer i = 0; i < nb_rank; ++i) {
2716 Int32ConstArrayView shared_ids = m_variable_synchronizer->sharedItems(i);
2717 for (auto id : shared_ids)
2718 items[id]->addFlags(ItemFlags::II_Shared);
2719 }
2720}
2721
2722/*---------------------------------------------------------------------------*/
2723/*---------------------------------------------------------------------------*/
2724
2725void ItemFamily::
2726_computeConnectivityInfo(ItemConnectivityInfo* ici)
2727{
2728 ici->fill(itemInternalConnectivityList());
2729 info(5) << "COMPUTE CONNECTIVITY INFO family=" << name() << " v=" << ici
2730 << " node=" << ici->maxNodePerItem() << " face=" << ici->maxFacePerItem()
2731 << " edge=" << ici->maxEdgePerItem() << " cell=" << ici->maxCellPerItem();
2732}
2733
2734/*---------------------------------------------------------------------------*/
2735/*---------------------------------------------------------------------------*/
2736
2737void ItemFamily::
2738_handleOldCheckpoint()
2739{
2740 // No need to manage 'm_items_type_id' because it is not present in
2741 // the old protections.
2742 _offsetArrayByOne(m_items_unique_id);
2743 _offsetArrayByOne(m_items_flags);
2744 _offsetArrayByOne(m_items_owner);
2745 (*m_items_unique_id)[0] = NULL_ITEM_UNIQUE_ID;
2746 (*m_items_flags)[0] = 0;
2747 (*m_items_owner)[0] = A_NULL_RANK;
2748}
2749
2750/*---------------------------------------------------------------------------*/
2751/*---------------------------------------------------------------------------*/
2752
2753namespace
2754{
2755
2756 // Returns a view that starts on the second element of the array.
2757 template <typename DataType>
2758 ArrayView<DataType> _getView(Array<DataType>* v)
2759 {
2760 Int32 n = v->size();
2761 return v->subView(1, n - 1);
2762 }
2763
2764} // namespace
2765
2766void ItemFamily::
2767_updateItemViews()
2768{
2769 m_common_item_shared_info->m_unique_ids = _getView(m_items_unique_id);
2770 m_common_item_shared_info->m_flags = _getView(m_items_flags);
2771 m_common_item_shared_info->m_type_ids = _getView(m_items_type_id);
2772 m_common_item_shared_info->m_owners = _getView(m_items_owner);
2773 m_common_item_shared_info->m_parent_item_ids = m_items_nb_parent->view();
2774
2775 m_items_unique_id_view = _getView(m_items_unique_id);
2776}
2777
2778/*---------------------------------------------------------------------------*/
2779/*---------------------------------------------------------------------------*/
2780
2781void ItemFamily::
2782_addOnSizeChangedObservable(VariableRef& var_ref)
2783{
2784 m_observers.addObserver(this, &ItemFamily::_updateItemViews,
2785 var_ref.variable()->onSizeChangedObservable());
2786}
2787
2788/*---------------------------------------------------------------------------*/
2789/*---------------------------------------------------------------------------*/
2790
2792_internalApi()
2793{
2794 return m_internal_api;
2795}
2796
2797/*---------------------------------------------------------------------------*/
2798/*---------------------------------------------------------------------------*/
2799
2800} // End namespace Arcane::mesh
2801
2802/*---------------------------------------------------------------------------*/
2803/*---------------------------------------------------------------------------*/
#define ARCANE_CHECK_POINTER(ptr)
Macro returning the pointer ptr if it is not null or throwing an exception if it is null.
#define ARCANE_THROW(exception_class,...)
Macro for throwing an exception with formatting.
#define ARCANE_FATAL(...)
Macro throwing a FatalErrorException.
#define ENUMERATE_ITEM(name, group)
Generic enumerator for a node group.
bool checkResizeArray(Array< DataType > &array, Int64 new_size, bool force_resize)
Resizes an array that is indexed by 'ItemLocalId'.
Definition MeshUtils.h:401
Integer size() const
Number of elements in the vector.
constexpr Integer size() const noexcept
Returns the size of the array.
void resize(Int64 s)
Changes the number of elements in the array to s.
void copy(Span< const T > rhs)
Copies the values from rhs into the instance.
void add(ConstReferenceType val)
Adds element val to the end of the array.
T & back()
Last element of the array.
void reserve(Int64 new_capacity)
Reserves memory for new_capacity elements.
ArrayView< T > view() const
Mutable view of this array.
Manages the retrieval of connectivity information.
ItemVectorView connectedItems(ItemLocalId item)
Returns the entities connected to item.
Constant view of an array of type T.
constexpr Integer size() const noexcept
Number of elements in the array.
constexpr bool empty() const noexcept
true if the array is empty (size()==0)
static std::optional< Int32 > tryParseFromEnvironment(StringView s, bool throw_if_invalid)
Class managing observers associated with an event.
Hash table for associative arrays.
Data * lookup(KeyTypeConstRef id)
Searches for the value corresponding to key id.
bool add(KeyTypeConstRef id, const ValueType &value)
Adds the value value corresponding to key id.
virtual IDataOperation * createDataOperation(Parallel::eReduceType rt)=0
Creates an operation performing a reduction of type rt.
Interface of an operation on a data.
Interface for managing an incremental connectivity.
virtual void removeConnectedItem(ItemLocalId source_item, ItemLocalId target_local_id)=0
Removes the entity with localId() target_local_id from the connectivity of source_item.
Interface for the source of an incremental connectivity.
virtual IItemFamily * sourceFamily() const =0
Source family.
virtual Ref< IIncrementalItemSourceConnectivity > toSourceReference()=0
Returns a reference to the instance.
Interface for the target of an incremental connectivity.
virtual Ref< IIncrementalItemTargetConnectivity > toTargetReference()=0
Returns a reference to the instance.
Interface for connectivity information by entity type.
virtual void notifyLocalIdChanged(IItemFamily *item_family, Int32ConstArrayView old_to_new_ids, Integer nb_item)=0
Update of modified items, possibly compacted.
Interface to manage connectivity.
Internal part of IItemFamily.
Interface for entity family policies.
Interface for modifying the topology of entities within a family.
Interface of an entity family.
Definition IItemFamily.h:83
virtual Integer parentFamilyDepth() const =0
Gives the nesting depth of the current mesh.
virtual ItemInternalArrayView itemsInternal()=0
Internal array of entities.
virtual void notifyItemsOwnerChanged()=0
Notifies that the entities specific to the family's subdomain have been modified.
Interface of an entity sorting function.
virtual String name() const =0
Mesh name.
virtual IItemFamily * findItemFamily(eItemKind ik, const String &name, bool create_if_needed=false, bool register_modifier_if_created=false)=0
Returns the family named name.
Interface for managing the compaction of mesh families.
virtual void endCompact()=0
Signals that the compaction is finished.
virtual IMeshCompacter * beginCompact()=0
Starts a compaction on all families of the mesh.
Management of mesh family compaction.
virtual void setSorted(bool v)=0
Indicates whether entities should be sorted during compaction.
virtual void doAllActions()=0
Executes all compaction actions successively.
Mesh manager interface.
Definition IMeshMng.h:41
virtual MeshHandle * findMeshHandle(const String &name, bool throw_exception)=0
Searches for the mesh with name name.
virtual void computeAdjacency(const ItemPairGroup &adjacency_array, eItemKind link_kind, Integer nb_layer)
Calculates adjacencies, stored in adjacency_array.
virtual IMeshUtilities * utilities()=0
Associated utility functions interface.
virtual ItemTypeMng * itemTypeMng() const =0
Associated entity type manager.
virtual IMeshCompactMng * _compactMng()=0
virtual const MeshPartInfo & meshPartInfo() const =0
Mesh part information.
Interface of the parallelism manager for a subdomain.
virtual void allGatherVariable(ConstArrayView< char > send_buf, Array< char > &recv_buf)=0
Performs an all-gather operation across all processors.
virtual char reduce(eReduceType rt, char v)=0
Performs a reduction of type rt on the real v and returns the value.
Interface of the subdomain manager.
Definition ISubDomain.h:75
virtual IVariableMng * variableMng()=0
Returns the variable manager.
Variable manager interface.
virtual IVariable * findVariableFullyQualified(const String &name)=0
Returns the fully qualified variable named name or 0 if no such name exists.
Interface of a variable synchronization service.
virtual void changeLocalIds(Int32ConstArrayView old_to_new_ids)=0
Called when the local IDs of the entities are modified.
Interface of a variable.
Definition IVariable.h:40
virtual String fullName() const =0
Full variable name (with family prefix).
@ PSubDomainDepend
Indicates that the variable value is dependent on the subdomain.
Definition IVariable.h:81
@ PTemporary
Indicates that the variable is temporary.
Definition IVariable.h:114
@ PInShMem
Indicates that the variable must be allocated in shared memory.
Definition IVariable.h:156
@ PExecutionDepend
Indicates that the variable value is dependent on the execution.
Definition IVariable.h:96
@ PPrivate
Indicates that the variable is private.
Definition IVariable.h:103
@ PNoRestore
Indicates that the variable should not be restored.
Definition IVariable.h:120
@ PNoDump
Indicates that the variable should not be saved.
Definition IVariable.h:62
virtual int property() const =0
Returns the properties of the variable.
virtual IDataFactoryMng * dataFactoryMng() const =0
Data factory associated with the variable.
virtual void resizeFromGroup()=0
Sets the number of elements for a mesh variable.
virtual ItemGroup itemGroup() const =0
Associated mesh group.
virtual void compact(Int32ConstArrayView new_to_old_ids)=0
Compresses the variable's values.
virtual void copyItemsMeanValues(Int32ConstArrayView first_source, Int32ConstArrayView second_source, Int32ConstArrayView destination)=0
Copies the mean values of entities numbered first_source and second_source into entities numbered des...
virtual IItemFamily * itemFamily() const =0
Associated entity family.
virtual String name() const =0
Variable name.
virtual void copyItemsValues(Int32ConstArrayView source, Int32ConstArrayView destination)=0
Copies the values of entities numbered source into entities numbered destination.
Base class for a view on unstructured connectivity.
bool isSuppressed() const
True if the entity is suppressed.
ItemUniqueId uniqueId() const
Unique number of the entity.
MutableItemBase toMutable()
Mutable interface of this entity.
Int32 flags() const
Flags of the entity.
bool isDetached() const
True if the entity is detached.
ItemTypeInfo * typeInfo() const
Type of the entity.
Int32 localId() const
Local number (in the subdomain) of the entity.
Information to manage the compaction of entities of a family.
Int32ConstArrayView newToOldLocalIds() const
Conversion between new and old local IDs.
Int32ConstArrayView oldToNewLocalIds() const
Conversion between old and new local IDs.
Event arguments for entity addition or deletion.
Flags for entity characteristics.
Definition ItemFlags.h:39
@ II_NeedRemove
The entity must be removed.
Definition ItemFlags.h:63
@ II_Shared
The entity is shared by another subdomain.
Definition ItemFlags.h:59
@ II_Suppressed
The entity has just been suppressed.
Definition ItemFlags.h:58
Brief: Implementation of a mesh entity group.
bool checkNeedUpdate()
Updates the group if necessary.
void destroy()
Destroys the group. After this call, the group becomes a null group.
void removeSuppressedItems()
Removes entities from the group whose isSuppressed() flag is true.
bool hasComputeFunctor() const
Indicates if the group is calculated.
ItemGroup parentGroup()
Parent group.
void changeIds(Int32ConstArrayView old_to_new_ids)
Changes the indices of the group entities.
Mesh entity group.
Definition ItemGroup.h:51
ItemGroupImpl * internal() const
Returns the group implementation.
Definition ItemGroup.h:125
IVariableSynchronizer * synchronizer() const
Group synchronizer.
Definition ItemGroup.cc:616
const String & name() const
Group name.
Definition ItemGroup.h:81
bool isLocalToSubDomain() const
True if the group is local to the subdomain.
Definition ItemGroup.h:230
void invalidate(bool force_recompute=false)
Invalidates the group.
Definition ItemGroup.h:257
ItemVectorView view() const
View of the group entities.
Definition ItemGroup.cc:580
Integer size() const
Number of elements in the group.
Definition ItemGroup.h:93
IItemFamily * itemFamily() const
Entity family to which this group belongs (0 for the null group).
Definition ItemGroup.h:128
void setItems(Int32ConstArrayView items_local_id)
Sets the entities of the group.
Definition ItemGroup.cc:484
eItemKind itemKind() const
Group kind. This is the kind of its elements.
Definition ItemGroup.h:114
bool hasSynchronizer() const
Indicates if the group has an active synchronizer.
Definition ItemGroup.cc:634
bool isAllItems() const
Indicates if the group is that of all entities.
Definition ItemGroup.cc:607
void checkValid()
Internal check of group validity.
Definition ItemGroup.cc:519
bool null() const
true means the group is the null group
Definition ItemGroup.h:75
void setOwn(bool v)
Sets whether the group property is local or not.
Definition ItemGroup.cc:161
View of a list to obtain information about entities.
Connectivity information, for an entity family, allowing transition between old and new connectivity ...
Interface for an entity sorting function.
Internal structure of a mesh entity.
Index of an Item in a variable.
Definition ItemLocalId.h:42
Implementation of an array of lists of entities.
Table of entity lists.
Utility class for printing information about an entity.
Definition ItemPrinter.h:35
Internal shared structure of a mesh entity.
Type of an entity (Item).
Definition ItemTypeId.h:33
Mesh entity type manager.
Definition ItemTypeMng.h:66
ItemTypeInfo * typeFromId(Integer id) const
Type corresponding to the number id.
Unique identifier of an entity.
View on a vector of entities.
Entity vector.
Definition ItemVector.h:60
void add(Int32 local_id)
Adds an entity with local ID local_id to the end of the vector.
Definition ItemVector.h:94
Base class for a mesh element.
Definition Item.h:84
Int32 owner() const
Owner subdomain number of the entity.
Definition Item.h:252
ItemUniqueId uniqueId() const
Unique identifier across all domains.
Definition Item.h:239
Implementation of a collection of elements in vector form.
IMesh * mesh() const
Associated mesh.
Information about a partitioned mesh.
void setOwner(Integer suid, Int32 current_sub_domain)
Sets the sub-domain number of the entity owner.
void setFlags(Int32 f)
Sets the entity flags.
void setParent(Int32 aindex, Int32 parent_local_id)
Sets the i-th parent (currently aindex must be 0).
void applyOperation(IDataOperation *operation) override
Applies the operation.
void addVariable(IVariable *variable) override
Adds a variable to the list of variables concerned by the operation.
void setItemFamily(IItemFamily *family) override
Positions the entity family on which the operation is to be performed.
List of properties.
Definition Properties.h:65
T * get() const
Returns the object referenced by the instance.
Definition Ptr.h:122
Encapsulation of an automatically destructing pointer.
Definition ScopedPtr.h:44
1D vector of data with reference semantics.
Unicode character string constructor.
String toString() const
Returns the constructed character string.
const char * localstr() const
Returns the conversion of the instance into UTF-8 encoding.
Definition String.cc:229
TraceMessageDbg debug(Trace::eDebugLevel=Trace::Medium) const
Flow for a debug message.
TraceMessage fatal() const
Flow for a fatal error message.
TraceMessage info() const
Flow for an information message.
ITraceMng * traceMng() const
Trace manager.
1D data vector with value semantics (STL style).
Parameters necessary for building a variable.
Reference to a variable.
Definition VariableRef.h:56
IVariable * variable() const
Associated variable.
Mesh information for a given entity kind.
Information on connectivity by entity type.
Integer maxNodePerItem() const override
Maximum number of nodes per entity.
Integer maxCellPerItem() const override
Maximum number of cells per entity.
Integer maxFacePerItem() const override
Maximum number of faces per entity.
Integer maxEdgePerItem() const override
Maximum number of edges per entity.
void resizeVariables(bool force_resize) override
Resizes the variables of this family.
void removeVariable(IVariable *var) override
Removes a variable from this family.
void notifyEndUpdateFromMesh() override
Indicates the end of modification by the mesh.
ItemInternalConnectivityList * unstructuredItemInternalConnectivityList() override
Information on unstructured connectivities.
void addVariable(IVariable *var) override
Adds a variable to this family.
void endAllocate() override
Indicates the end of allocation.
ItemSharedInfo * commonItemSharedInfo() override
Instance of ItemSharedInfo for the family entities.
IItemFamilyTopologyModifier * topologyModifier() override
Topology modifier interface.
VariableArrayInt64 m_items_unique_id
Contains the uniqueIds() of the entities in this family.
VariableArrayInteger m_items_shared_data_index
Index in the ItemSharedInfo array for each entity.
VariableArrayInt32 m_items_flags
Contains the flags() of the entities in this family.
VariableArrayInt16 m_items_type_id
Contains the typeId() of the entities in this family.
VariableArrayInt32 m_items_owner
Contains the owner() of the entities in this family.
VariableItemInt32 m_items_new_owner
Contains the owning sub-domain of the entity.
VariableArrayInt32 m_items_nb_parent
Contains the parent() of the entities in this family.
bool hasUniqueIdMap() const override
Indicates if the family has a uniqueId to localId conversion table.
IMesh * mesh() const override
Associated mesh.
void partialEndUpdateVariable(IVariable *variable) override
Updates a variable.
void _compactItems(bool do_sort)
Compresses the entities.
void partialEndUpdate() override
Partial update.
String fullName() const override
Full family name (with the mesh's name).
Definition ItemFamily.h:141
void _compactFromParentFamily(const ItemFamilyCompactInfos &compact_infos)
Compresses the connectivities.
void _checkComputeSynchronizeInfos(Int32 changed)
Test collectif permettant de savoir s'il faut mettre à jour les infos de synchro.
void _compactOnlyItems(bool do_sort)
Compresses the entities without updating references.
EventObservableView< const ItemFamilyItemListChangedEventArgs & > itemListChangedEvent() override
Event for entity addition and deletion.
void clearItems() override
Deletes all entities in the family.
ItemPairGroup findAdjencyItems(const ItemGroup &group, const ItemGroup &sub_group, eItemKind link_kind, Integer layer) override
Searches for an adjacency list.
void destroyGroups() override
Deletes all groups in this family.
void prepareForDump() override
Prepares data for dumping.
ItemInternalConnectivityList m_item_connectivity_list
Accessor for connectivities via Item and ItemInternal.
Definition ItemFamily.h:453
void addChildFamily(IItemFamily *family) override
Adds a family as a dependency.
void checkValid() override
Check the validity of internal structures (internal).
ItemInternal * findOneItem(Int64 uid) override
Unique ID entity unique_id.
IParallelMng * parallelMng() const override
Associated parallelism manager.
void endUpdate() override
Notifies the end of modification of the entity list.
void compactVariablesAndGroups(const ItemFamilyCompactInfos &compact_infos)
Compresses the variables and groups.
void usedVariables(VariableCollection collection) override
Adds the list of variables used by this family to the collection.
ITraceMng * traceMng() const override
Associated trace manager.
ItemGroup createGroup(const String &name, Int32ConstArrayView elements, bool do_override=false) override
Creates an entity group named name containing the entities local_ids.
eItemKind itemKind() const override
Entity kind.
Integer m_current_id
Family identifier.
Definition ItemFamily.h:439
VariableItemInt32 & itemsNewOwner() override
Variable containing the number of the new subdomain owning the entity.
void copyItemsValues(Int32ConstArrayView source, Int32ConstArrayView destination) override
void copyItemsMeanValues(Int32ConstArrayView first_source, Int32ConstArrayView second_source, Int32ConstArrayView destination) override
ItemGroup allItems() const override
Group of all entities.
void internalRemoveItems(Int32ConstArrayView local_ids, bool keep_ghost=false) override
Removes the entities given by local_ids.
void addGhostItems(Int64ConstArrayView unique_ids, Int32ArrayView items, Int32ConstArrayView owners) override
Allocates ghost entities.
void getCommunicatingSubDomains(Int32Array &sub_domains) const override
List of communicating sub-domains for the entities.
void reduceFromGhostItems(IVariable *v, IDataOperation *operation) override
Applies a reduction operation from ghost items.
ItemConnectivitySet m_target_item_connectivities
connectivite ou ItemFamily == SourceFamily
Definition ItemFamily.h:368
IItemFamily * parentFamily() const override
IItemFamily parent.
void setHasUniqueIdMap(bool v) override
Indicates whether the family has a conversion table from uniqueId to localId.
ItemInfoListView itemInfoListView() override
View on the entity information list.
static bool _cmpIVariablePtr(const IVariable *a, const IVariable *b)
Function to compare two variable names (strcmp).
void removeItems2(ItemDataList &item_data_list) override
Removes entities.
void setParentFamily(IItemFamily *parent) override
Positions the parent IItemFamily.
void compactItems(bool do_sort) override
Compresses the entities.
Integer nbItem() const override
Number of entities.
void notifyItemsUniqueIdChanged() override
Notifies that the unique IDs of the entities have been modified.
ItemVectorView view() override
View on all entities in the family.
void synchronize(VariableCollection variables) override
Synchronizes the variables variables.
ItemPairGroup findAdjacencyItems(const ItemGroup &group, const ItemGroup &sub_group, eItemKind link_kind, Integer layer) override
Searches for an adjacency list.
ItemInternalList itemsInternal() override
Internal array of entities.
void computeSynchronizeInfos() override
Constructs the structures necessary for synchronization.
void checkValidConnectivity() override
Verification of the validity of internal structures concerning connectivity.
void _updateItemsSharedFlag()
Positions Item::isShared() info for the entities of the family.
IVariable * findVariable(const String &name, bool throw_exception) override
Searches for the variable name name associated with this family.
void _readGroups()
Relit les groupes depuis une protection et les recréer si besoin.
Int32 maxLocalId() const override
void setItemSortFunction(IItemInternalSortFunction *sort_function) override
Positions the entity sorting function.
IItemInternalSortFunction * itemSortFunction() const override
Entity sorting function.
ISubDomain * subDomain() const override
Associated sub-domain.
virtual void _notifyEndUpdateFromMesh()
IVariableSynchronizer * allItemsSynchronizer() override
Synchronizer on all entities of the family.
void notifyItemsOwnerChanged() override
Notifies that the entities specific to the family's subdomain have been modified.
Integer parentFamilyDepth() const override
Gives the nesting depth of the current mesh.
ItemGroupCollection groups() const override
Collection of groups in this family.
IItemConnectivityMng * m_connectivity_mng
connectivite ou ItemFamily == TargetFamily
Definition ItemFamily.h:369
IItemConnectivityInfo * localConnectivityInfos() const override
Information on local connectivity within the subdomain for this family.
IItemFamilyCollection childFamilies() override
Child families of this family.
void partialEndUpdateGroup(const ItemGroup &group) override
Updates a group.
IItemConnectivityInfo * globalConnectivityInfos() const override
Information on global connectivity across all subdomains.
void checkUniqueIds(Int64ConstArrayView unique_ids) override
Checks that the unique_ids are truly unique for all subdomains.
ItemGroup findGroup(const String &name) const override
Searches for a group.
void readFromDump() override
Reads data from a dump.
String name() const override
Family name.
Definition ItemFamily.h:140
Associative array of ItemInternal.
void remove(Int64 key)
Removes the value associated with the key key.
void eachItem(const Lambda &lambda)
Template function to iterate over the instance's entities.
bool add(Int64 key, ItemInternal *v)
Adds the value v corresponding to the key key.
Int32 count() const
Number of elements in the table.
Mesh info for a given entity type.
Temporary class to hold an ItemSharedInfo and an entity type.
VariableRefArrayT< Int32 > VariableArrayInt32
Array variable of 32-bit integer type.
VariableRefArrayT< Int64 > VariableArrayInt64
Array variable of 64-bit integer type.
VariableRefArrayT< Int16 > VariableArrayInt16
Array variable of 16-bit integer type.
VariableRefScalarT< String > VariableScalarString
Scalar variable of character string type.
VariableRefArrayT< Integer > VariableArrayInteger
Array variable of integer type.
VariableRefArrayT< String > VariableArrayString
Array variable of character string type.
ItemVariableScalarRefT< Int32 > VariableItemInt32
32-bit integer type quantity
VariableRefScalarT< Integer > VariableScalarInteger
Scalar variable of integer type.
bool isLess(const char *s1, const char *s2)
Returns true if s1 is less than (alphabetical order) s2 , false otherwise.
eReduceType
Supported reduction types.
@ ReduceMax
Maximum of values.
Ref< IVariableSynchronizer > createSynchronizerRef(IParallelMng *pm, IItemFamily *family)
Returns an interface to synchronize variables on the group of the family family.
double getMemoryUsed()
Memory used in bytes.
String getEnvironmentVariable(const String &name)
Environment variable named name.
ArrayView< Int64 > Int64ArrayView
C equivalent of a 1D array of 64-bit integers.
Definition UtilsTypes.h:451
bool arcaneIsCheck()
True if running in check mode.
Definition Misc.cc:66
UniqueArray< Int64 > Int64UniqueArray
Dynamic 1D array of 64-bit integers.
Definition UtilsTypes.h:339
Collection< ItemGroup > ItemGroupCollection
Collection of mesh item groups.
std::int64_t Int64
Signed integer type of 64 bits.
Int32 Integer
Type representing an integer.
ConstArrayView< Int32 > Int32ConstArrayView
C equivalent of a 1D array of 32-bit integers.
Definition UtilsTypes.h:482
List< ItemGroup > ItemGroupList
Array of mesh item groups.
ArrayView< Integer > IntegerArrayView
C equivalent of a 1D array of integers.
Definition UtilsTypes.h:457
ConstArrayView< ItemInternal * > ItemInternalList
Type of the internal list of entities.
Definition ItemTypes.h:466
Collection< IItemFamily * > IItemFamilyCollection
Collection of item families.
ConstArrayView< Int64 > Int64ConstArrayView
C equivalent of a 1D array of 64-bit integers.
Definition UtilsTypes.h:480
ArrayView< Int32 > Int32ArrayView
C equivalent of a 1D array of 32-bit integers.
Definition UtilsTypes.h:453
eItemKind
Mesh entity type.
Array< Int32 > Int32Array
Dynamic one-dimensional array of 32-bit integers.
Definition UtilsTypes.h:127
std::int32_t Int32
Signed integer type of 32 bits.