14#include "arcane/utils/FatalErrorException.h"
15#include "arcane/utils/PlatformUtils.h"
16#include "arcane/utils/NotImplementedException.h"
17#include "arcane/utils/StringBuilder.h"
19#include "arcane/core/IMesh.h"
20#include "arcane/core/IItemFamily.h"
22#include "arcane/core/IParallelMng.h"
23#include "arcane/core/ItemPrinter.h"
24#include "arcane/core/VariableTypes.h"
25#include "arcane/core/Timer.h"
26#include "arcane/core/IItemInternalSortFunction.h"
27#include "arcane/core/ItemFamilyCompactInfos.h"
28#include "arcane/core/IMeshCompacter.h"
29#include "arcane/core/MeshPartInfo.h"
30#include "arcane/core/ItemFamilyItemListChangedEventArgs.h"
32#include "arcane/mesh/DynamicMeshKindInfos.h"
33#include "arcane/mesh/ItemFamily.h"
58, m_use_new_finalize(true)
59, m_is_first_finalize(true)
60, m_has_unique_id_map(true)
78void DynamicMeshKindInfos::
94 m_use_new_finalize =
false;
97 m_is_first_finalize =
true;
114 ARCANE_FATAL(
"allocMany() is only valid on a family holding no reusable localId");
116 m_added_items.reserve(m_added_items.size() + nb);
117 for (
Int32 i = 0; i < nb; ++i) {
119 if (!m_free_internals_in_multi_buffer.empty()) {
120 new_item = m_free_internals_in_multi_buffer.back();
121 m_free_internals_in_multi_buffer.popBack();
126 new_item->setLocalId(lid);
128 m_added_items.add(lid);
130#ifdef ARCANE_ENABLE_EVENT_FOR_DYNAMICMESHKINDINFO
133 _notifyAdd(new_item, uids[i]);
138 _updateItemSharedInfoInternalView();
139 if (m_has_unique_id_map) {
141 for (
Int32 i = 0; i < nb; ++i) {
143 _badSameUniqueId(uids[i]);
162 <<
" internal size= " << internal_size
165 for(
Integer i=0; i<internal_size; ++i ){
167 info() <<
"Item " << i <<
" lib=" << item->
localId()
175 Integer nb_added_items = m_added_items.size();
176 Integer nb_removed_items = m_removed_items.size();
177 bool test_mode = m_use_new_finalize;
181 <<
" internal size " << internal_size
182 <<
" nb_add=" << nb_added_items
183 <<
" nb_remove=" << nb_removed_items;
191 if (!pm->
isParallel() && nb_added_items != 0) {
193 for (
Integer i = 0; i < nb_added_items; ++i)
200 impl.beginTransaction();
201 if (nb_added_items == 0 && nb_removed_items != 0 && test_mode) {
202 impl.removeItems(m_removed_items,
true);
204 else if (nb_added_items != 0 && nb_removed_items == 0 && test_mode) {
205 impl.addItems(m_added_items,
true);
208 impl.removeAddItems(m_removed_items, m_added_items,
true);
210 impl.endTransaction();
213 impl.checkNeedUpdate();
215#if defined(ARCANE_DEBUG_MESH)
217 m_all_group.checkValid();
223#if defined(ARCANE_DEBUG_MESH)
228 m_removed_items.clear();
229 m_added_items.clear();
235void DynamicMeshKindInfos::
238 if (!m_has_unique_id_map)
243 Int64 unique_id = ids[i];
249 Int64 unique_id = ids[i];
257 Int64 unique_id = ids[i];
259 if ((ids[i] == NULL_ITEM_LOCAL_ID) && do_fatal) {
261 error() <<
"DynamicMeshKindInfos::itemsUniqueIdToLocalId() can't find "
263 << unique_id <<
" in the subdomain.";
278void DynamicMeshKindInfos::
282 if (!m_has_unique_id_map)
286 for (
Integer i = 0, s = unique_ids.size(); i < s; ++i) {
287 Int64 unique_id = unique_ids[i];
288 local_ids[i] = (unique_id == NULL_ITEM_UNIQUE_ID) ? NULL_ITEM_LOCAL_ID :
m_items_map.findLocalId(unique_id);
292 for (
Integer i = 0, s = unique_ids.size(); i < s; ++i) {
293 Int64 unique_id = unique_ids[i];
294 local_ids[i] =
m_items_map.tryFindLocalId(unique_id);
300 for (
Integer i = 0, s = unique_ids.size(); i < s; ++i) {
301 Int64 unique_id = unique_ids[i];
302 local_ids[i] =
m_items_map.tryFindLocalId(unique_id);
303 if ((local_ids[i] == NULL_ITEM_LOCAL_ID) && do_fatal && unique_id != NULL_ITEM_UNIQUE_ID) {
305 error() <<
"DynamicMeshKindInfos::itemsUniqueIdToLocalId() can't find "
307 << unique_id <<
" in the subdomain.";
322void DynamicMeshKindInfos::
324 ConstArrayView<ItemUniqueId> unique_ids,
bool do_fatal)
const
326 if (!m_has_unique_id_map)
330 for (
Integer i = 0, s = unique_ids.size(); i < s; ++i) {
331 Int64 unique_id = unique_ids[i];
336 for (
Integer i = 0, s = unique_ids.size(); i < s; ++i) {
337 Int64 unique_id = unique_ids[i];
338 local_ids[i] =
m_items_map.tryFindLocalId(unique_id);
344 for (
Integer i = 0, s = unique_ids.size(); i < s; ++i) {
345 Int64 unique_id = unique_ids[i];
346 local_ids[i] =
m_items_map.tryFindLocalId(unique_id);
347 if ((local_ids[i] == NULL_ITEM_LOCAL_ID) && do_fatal) {
349 error() <<
"DynamicMeshKindInfos::itemsUniqueIdToLocalId() can't find "
351 << unique_id <<
" in the subdomain.";
381 _updateItemSharedInfoInternalView();
386 m_free_internals_in_multi_buffer.clear();
405 for (
Integer i = 0; i < nb_internal; ++i) {
407 if (item->
localId() != i && nb_error < 10) {
408 error() <<
"The local id (" << item->
localId() <<
") of the entity "
410 <<
"consistent with its internal value (" << i <<
")";
417 if (item->
owner() == NULL_SUB_DOMAIN_ID && nb_error < 10) {
419 <<
":uid=" << item->
uniqueId() <<
" belongs to no subdomain";
423 if (item->
owner() != sid && item->
isOwn() && nb_error < 10) {
425 <<
":uid=" << item->
uniqueId() <<
" incoherence between isOwn() and owner()"
426 <<
" " << item->
owner() <<
' ' << sid;
431 if (nb_killed_item != nb_free) {
433 <<
": incoherence between killed and free entities"
434 <<
" free=" << nb_free
435 <<
" killed=" << nb_killed_item
436 <<
" internal=" << nb_internal
442 ARCANE_FATAL(
"Internal error in the mesh structure mesh={0} part={1}",
450class ItemParticleCompareWithSuppression
482 return item1.m_unique_id < item2.m_unique_id;
529 bool do_sort = compact_infos.compacter()->
isSorted();
535 info(4) <<
m_kind_name <<
" beginCompactItems() Family Internal Size=" << nb_internal
538 <<
" do_sort=" << do_sort;
540 if (nb_internal == 0)
547 old_to_new_local_ids.
fill(NULL_ITEM_LOCAL_ID);
549 new_to_old_local_ids.
fill(NULL_ITEM_LOCAL_ID);
557 const bool print_infos =
false;
563 for (
Integer i = 0, is = items.
size(); i < is; ++i) {
564 info() <<
"Before Sort: " << i <<
" uid=" << items[i]->uniqueId()
565 <<
" lid=" << items[i]->localId()
566 <<
" destroyed?=" << items[i]->isSuppressed();
575 <<
" sort_func_name=" << sort_func->
name();
578 for (
Integer i = 0, n = items.
size(); i < n; ++i) {
579 info() <<
"After Sort: " << i <<
" uid=" << items[i]->uniqueId()
580 <<
" lid=" << items[i]->localId()
581 <<
" destroyed?=" << items[i]->isSuppressed();
586#ifdef ARCANE_TEST_ADD_MESH
587 typedef std::set<ItemInternal*, ItemCompare> ItemSet;
592 ItemSet::const_iterator b = items_set.begin();
593 ItemSet::const_iterator e = items_set.end();
594 for (
Integer z = 0; b != e; ++b, ++z)
600 Integer current_local_id = items[i]->localId();
603 old_to_new_local_ids[current_local_id] = i;
604 new_to_old_local_ids[i] = current_local_id;
608 const bool use_old =
true;
610 info(4) <<
"USE_OLD_METHOD";
614 Integer current_local_id = existing_items[i];
615 old_to_new_local_ids[current_local_id] = i;
616 new_to_old_local_ids[i] = current_local_id;
624 for (
Integer i = 0, n = total_nb; i < n; ++i) {
626 if (old_to_new_local_ids[i] == NULL_ITEM_ID) {
628 old_to_new_local_ids[i] = old_index;
636 if (old_index != total_nb) {
637 ARCANE_FATAL(
"Family '{0}' bad indices: expected={1} found={2} (nb_internal={3})",
638 itemFamily()->name(), old_index, total_nb, nb_internal);
651 old_to_new_local_ids[i] = free_index;
656 old_to_new_local_ids[i] = new_index;
657 new_to_old_local_ids[new_index] = i;
665 ARCANE_FATAL(
"Family '{0}' bad indices: expected={1} found={2}",
666 itemFamily()->name(),
m_nb_item, new_index);
670 compact_infos.setOldToNewLocalIds(std::move(old_to_new_local_ids));
671 compact_infos.setNewToOldLocalIds(std::move(new_to_old_local_ids));
677void DynamicMeshKindInfos::
689 <<
" nb_internal=" << nb_internal
692 <<
" nb_free" << m_free_internals_in_multi_buffer.size();
694 if (nb_internal == 0)
708 info() <<
"DumpItemsBefore:";
722 new_uids[i] = old_item->
uniqueId().asInt64();
723 new_owners[i] = old_item->
owner();
724 new_flags[i] = old_item->
flags();
725 new_typeids[i] = old_item->
typeId();
726 new_items[i] = *old_item;
736 ii->setFlags(new_flags[i]);
737 ii->setOwner(new_owners[i], sid);
738 ii->setUniqueId(new_uids[i]);
739 ItemSharedInfo* isi = ItemInternalCompatibility::_getSharedInfo(ii);
740 ii->_setSharedInfo(isi, ItemTypeId(new_typeids[i]));
744 if (ii->isSuppressed()) {
746 error() <<
"Entity deleted from the list of created entities "
747 << ItemPrinter(ii) <<
" index=" << i;
762 m_free_internals_in_multi_buffer.add(removed_item);
767 _updateItemSharedInfoInternalView();
771 info() <<
"DumpItemsAfter:";
776 ARCANE_FATAL(
"Error in compacting nb_error={0}", nb_error);
778 debug() <<
"Compression: old=" << nb_internal <<
" new=" <<
m_nb_item
783 compact_infos.clear();
817 std::sort(std::begin(ids), std::end(ids), _Inverse());
826void DynamicMeshKindInfos::
827printFreeInternals(
Integer max_print)
830 max_print =
math::min(nb_free, max_print);
831 for (
Integer i = 0; i < max_print; ++i) {
832 Integer pos = (nb_free - 1) - i;
835 info() <<
"I=" << i <<
" pos=" << pos <<
" index=" << index
836 <<
" local_id=" << iitem->
localId();
849 if (m_has_unique_id_map) {
850 for (
Integer i = 0; i < nb_item; ++i) {
851 Int32 lid = local_ids[i];
854 _checkActiveItem(item);
856 _setSuppressed(item);
857 if (uids[lid] != NULL_ITEM_UNIQUE_ID)
862 for (
Integer i = 0; i < nb_item; ++i) {
863 Int32 lid = local_ids[i];
866 _checkActiveItem(item);
868 _setSuppressed(item);
873 Integer nb_removed = m_removed_items.size();
874 m_removed_items.resize(nb_removed + nb_item);
875 memcpy(m_removed_items.data() + nb_removed, local_ids.
data(),
sizeof(
Int32) * nb_item);
884void DynamicMeshKindInfos::
885setHasUniqueIdMap(
bool v)
889 m_has_unique_id_map = v;
895void DynamicMeshKindInfos::
899 ARCANE_FATAL(
"Attempting to remove an entity already deleted item={0}",
906void DynamicMeshKindInfos::
911 for (
Integer i = 0; i < nb_internal; ++i) {
916 info() <<
"Item: INDEX=" << i
917 <<
" LID=" << item->localId()
918 <<
" UID=" << item->uniqueId()
919 <<
" KILLED=" << is_suppressed;
921 info() <<
"EndOfDump: "
922 <<
" nb_internal=" << nb_internal
924 <<
" computed_nb_item= " << (nb_internal - computed_nb_item);
930void DynamicMeshKindInfos::
931_badSameUniqueId(
Int64 unique_id)
const
940void DynamicMeshKindInfos::
941_badUniqueIdMap()
const
943 if (m_has_unique_id_map)
952void DynamicMeshKindInfos::
956 m_common_item_shared_info = item_family->commonItemSharedInfo();
962void DynamicMeshKindInfos::
963_updateItemSharedInfoInternalView()
965 if (m_common_item_shared_info)
966 m_common_item_shared_info->m_items_internal =
m_internals.constView();
972EventObservableView<const ItemFamilyItemListChangedEventArgs&> DynamicMeshKindInfos::
973itemListChangedEvent()
975 return EventObservableView<const ItemFamilyItemListChangedEventArgs&>(m_item_list_change_event);
981void DynamicMeshKindInfos::
982_notifyRemove2(ItemInternal* item)
984 ItemFamilyItemListChangedEventArgs args(
m_item_family, item->localId(), item->uniqueId());
985 m_item_list_change_event.notify(args);
986 args.setIsAdd(
false);
992void DynamicMeshKindInfos::
993_notifyAdd2(ItemInternal* item,
Int64 uid)
995 ItemFamilyItemListChangedEventArgs args(
m_item_family, item->localId(), uid);
997 m_item_list_change_event.notify(args);
#define ARCANE_FATAL(...)
Macro throwing a FatalErrorException.
Integer size() const
Number of elements in the vector.
Modifiable view of an array of type T.
constexpr Integer size() const noexcept
Returns the size of the array.
void fill(ConstReferenceType value)
Fills the array with the value value.
const T * data() const
Access to the root of the array without any protection.
constexpr const_pointer data() const noexcept
Pointer to the allocated memory.
constexpr Integer size() const noexcept
Number of elements in the array.
Interface of an entity sorting function.
virtual void sortItems(ItemInternalMutableArrayView items)=0
Sorts the entities in the array items.
virtual const String & name() const =0
Name of the sorting function.
virtual bool isSorted() const =0
Indicates whether it wishes to sort the entities in addition to compacting them.
virtual const MeshPartInfo & meshPartInfo() const =0
Mesh part information.
Interface of the parallelism manager for a subdomain.
virtual Int32 commRank() const =0
Rank of this instance in the communicator.
virtual bool isParallel() const =0
Returns true if the execution is parallel.
Interface of a timer manager.
bool isSuppressed() const
True if the entity is suppressed.
ItemUniqueId uniqueId() const
Unique number of the entity.
Int32 owner() const
Number of the owning subdomain of the entity.
Int32 flags() const
Flags of the entity.
Int16 typeId() const
Type of the entity.
bool isOwn() const
True if the entity belongs to the subdomain.
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.
Brief: Implementation of a mesh entity group.
void setIsAllItems()
Indicates to this group that it is the group of all entities in the family.
void setLocalToSubDomain(bool v)
Sets the boolean indicating if the group is local to the subdomain.
ItemGroupImpl * internal() const
Returns the group implementation.
Internal structure of a mesh entity.
Utility class for printing information about an entity.
ItemUniqueId uniqueId() const
Unique identifier across all domains.
Buffer for multiple allocation.
Cell cell() const
Cell to which the particle belongs. You must call setCell() before calling this function....
Unicode character string constructor.
Unicode character string.
Sentinel for the timer. The sentinel associated with a timer allows it to be triggered upon its const...
@ TimerReal
Timer using real time.
Real lastActivationTime() const
Returns the time (in seconds) spent during the last activation of the timer.
TraceAccessor(ITraceMng *m)
Constructs an accessor via the trace manager m.
TraceMessageDbg debug(Trace::eDebugLevel=Trace::Medium) const
Flow for a debug message.
TraceMessage info() const
Flow for an information message.
TraceMessage error() const
Flow for an error message.
ITraceMng * traceMng() const
Trace manager.
TraceMessage pwarning() const
1D data vector with value semantics (STL style).
Integer m_nb_item
Group of all entities.
String m_kind_name
Name of the entity kind (Node, Cell, ...).
Integer maxUsedLocalId() const
Largest local ID used.
MultiBufferT< ItemInternal > * m_item_internals_buffer
Buffer to store an instance of ItemInternal.
void finalizeMeshChanged()
Reallocates and recalculates structures after mesh modification.
void removeMany(Int32ConstArrayView local_ids)
Removes a list of entities.
void prepareForDump()
Prepares variables for dumps.
void beginCompactItems(ItemFamilyCompactInfos &compact_infos)
Calculates the new local IDs of the entities so that they are consecutive.
ARCANE_DEPRECATED_240 Int32ConstArrayView oldToNewLocalIds() const
Conversion between old and new local IDs.
UniqueArray< ItemInternal * > m_internals
ItemInternals of the entities.
void readFromDump()
Restores info from dumps.
DynamicMeshKindInfos(IMesh *mesh, eItemKind kind, const String &kind_name)
Creates an instance for a given mesh and kind.
ARCANE_DEPRECATED_240 Int32ConstArrayView newToOldLocalIds() const
Conversion between new and old local IDs.
ItemFamilyCompactInfos * m_compact_infos
Temporary while oldToNewLocalIds() and newToOldLocalIds() exist.
void checkValid()
Checks if the internal structures of the instance are valid.
~DynamicMeshKindInfos()
Frees resources.
String m_all_group_name
Name of the group containing all entities.
ItemInternalMap m_items_map
Hash table for uniqueId() -> ItemInternal* conversion.
Int32UniqueArray m_free_internals
List of free ItemInternals from m_item_internals_buffer.
void allocMany(Int64ConstArrayView uids, Int32ArrayView lids)
Allocates every item of uids at once, returning their localIds.
void clear()
Removes all entities.
IMesh * m_mesh
Associated mesh.
eItemKind m_kind
Corresponding kind.
ItemFamily * m_item_family
Associated mesh family.
ItemGroup createGroup(const String &name, Int32ConstArrayView elements, bool do_override=false) override
Creates an entity group named name containing the entities local_ids.
Int32 tryFindLocalId(Int64 key) const
Returns the localId() associated with key if found, or none otherwise.
Int32 findLocalId(Int64 uid) const
Returns the local number of the unique ID entity uid.
void _changeLocalIds(ArrayView< ItemInternal * > items_internal, ConstArrayView< Int32 > old_to_new_local_ids)
Changes the values of localId().
__host__ __device__ Real2 min(Real2 a, Real2 b)
Returns the minimum of two Real2.
ArrayView< Int64 > Int64ArrayView
C equivalent of a 1D array of 64-bit integers.
bool arcaneIsCheck()
True if running in check mode.
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.
ConstArrayView< Int64 > Int64ConstArrayView
C equivalent of a 1D array of 64-bit integers.
UniqueArray< Int32 > Int32UniqueArray
Dynamic 1D array of 32-bit integers.
ArrayView< Int32 > Int32ArrayView
C equivalent of a 1D array of 32-bit integers.
eItemKind
Mesh entity type.
std::int32_t Int32
Signed integer type of 32 bits.