diff --git a/arcane/src/arcane/core/ArcaneTypes.h b/arcane/src/arcane/core/ArcaneTypes.h index 28b549251..8fc048212 100644 --- a/arcane/src/arcane/core/ArcaneTypes.h +++ b/arcane/src/arcane/core/ArcaneTypes.h @@ -118,6 +118,8 @@ class MeshBuildInfo; class MeshKind; class IPrimaryMesh; class IMeshInitialAllocator; +class ItemFamilyCompactInfos; +class ItemFamilyItemListChangedEventArgs; class ItemPairEnumerator; class ItemInfoListView; class ItemGenericInfoListView; @@ -147,6 +149,14 @@ class IParallelMngInternal; class IIOMng; class ITimerMng; class IThreadMng; +class ItemUniqueId; +class IItemConnectivityInfo; +class IItemConnectivity; +class IItemInternalSortFunction; +class IItemConnectivityMng; +class Properties; +class IItemFamilyTopologyModifier; +class IItemFamilyPolicyMng; enum class eMeshStructure; enum class eMeshAMRKind; @@ -549,6 +559,18 @@ class AcceleratorRuntimeInitialisationInfo; using Accelerator::IAcceleratorMng; using Accelerator::AcceleratorRuntimeInitialisationInfo; +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ +// Déclarations de types utilisés pour les classes 'friend'. +namespace mesh +{ +class DynamicMesh; +class ItemFamily; +class ItemSharedInfoWithType; +class DynamicMeshKindInfos; +class ItemDataList; +} + /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ diff --git a/arcane/src/arcane/core/IItemFamily.h b/arcane/src/arcane/core/IItemFamily.h index b1d5b8674..73df6431b 100644 --- a/arcane/src/arcane/core/IItemFamily.h +++ b/arcane/src/arcane/core/IItemFamily.h @@ -1,23 +1,23 @@ // -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*- //----------------------------------------------------------------------------- -// Copyright 2000-2023 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com) +// Copyright 2000-2025 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com) // See the top-level COPYRIGHT file for details. // SPDX-License-Identifier: Apache-2.0 //----------------------------------------------------------------------------- /*---------------------------------------------------------------------------*/ -/* IItemFamily.h (C) 2000-2024 */ +/* IItemFamily.h (C) 2000-2025 */ /* */ /* Interface d'une famille d'entités. */ /*---------------------------------------------------------------------------*/ -#ifndef ARCANE_IITEMFAMILY_H -#define ARCANE_IITEMFAMILY_H +#ifndef ARCANE_CORE_IITEMFAMILY_H +#define ARCANE_CORE_IITEMFAMILY_H /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ -#include "arcane/ArcaneTypes.h" -#include "arcane/ItemTypes.h" -#include "arcane/VariableTypedef.h" -#include "arcane/Parallel.h" +#include "arcane/core/ArcaneTypes.h" +#include "arcane/core/ItemTypes.h" +#include "arcane/core/VariableTypedef.h" +#include "arcane/core/Parallel.h" /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ @@ -25,33 +25,6 @@ namespace Arcane { -/*---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ - -class IParallelMng; -class IDataOperation; -class ItemUniqueId; -class IItemInternalSortFunction; -class IVariableSynchronizer; -class IParticleFamily; -class GroupIndexTable; -class IItemConnectivityInfo; -class IItemConnectivityMng; -class IItemConnectivity; -class IExtraGhostItemsBuilder; -class IIncrementalItemConnectivity; -class IItemFamilyPolicyMng; -class IItemFamilyTopologyModifier; -class ItemInternalConnectivityList; -class Properties; - -namespace mesh -{ - class ItemDataList; - class DynamicMesh; - class ItemFamily; -} - /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ /*! @@ -109,8 +82,8 @@ namespace mesh */ class ARCANE_CORE_EXPORT IItemFamily { - friend class mesh::DynamicMesh; - friend class mesh::ItemFamily; + friend mesh::DynamicMesh; + friend mesh::ItemFamily; public: @@ -706,6 +679,11 @@ class ARCANE_CORE_EXPORT IItemFamily //! Propriétés associées à cette famille. virtual Properties* properties() =0; + public: + + //! Evènement pour l'ajout et la suppression d'entité + virtual EventObservableView itemListChangedEvent() = 0; + public: /*! diff --git a/arcane/src/arcane/core/ItemFamilyItemListChangedEventArgs.h b/arcane/src/arcane/core/ItemFamilyItemListChangedEventArgs.h new file mode 100644 index 000000000..fe4990b06 --- /dev/null +++ b/arcane/src/arcane/core/ItemFamilyItemListChangedEventArgs.h @@ -0,0 +1,73 @@ +// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*- +//----------------------------------------------------------------------------- +// Copyright 2000-2025 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com) +// See the top-level COPYRIGHT file for details. +// SPDX-License-Identifier: Apache-2.0 +//----------------------------------------------------------------------------- +/*---------------------------------------------------------------------------*/ +/* ItemFamilyItemListChangedEventArgs.h (C) 2000-2025 */ +/* */ +/* Arguments de l'évènement pour l'ajout ou la supression d'entités. */ +/*---------------------------------------------------------------------------*/ +#ifndef ARCANE_CORE_ITEMFAMILYITEMLISTCHANGEDARGS_H +#define ARCANE_CORE_ITEMFAMILYITEMLISTCHANGEDARGS_H +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +#include "arcane/utils/ArrayView.h" +#include "arcane/utils/UtilsTypes.h" + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +namespace Arcane +{ + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ +/*! + * \ingroup Mesh + * \brief Arguments de l'évènement pour l'ajout ou la supression d'entités. + */ +class ARCANE_CORE_EXPORT ItemFamilyItemListChangedEventArgs +{ + friend mesh::DynamicMeshKindInfos; + + private: + + //! Constructeur. Uniquement pour DynamicMeshKindInfos. + ItemFamilyItemListChangedEventArgs() = default; + ItemFamilyItemListChangedEventArgs(IItemFamily* item_family, Int32 local_id, Int64 unique_id) + : m_item_family(item_family) + , m_local_id(local_id) + , m_unique_id(unique_id) + {} + + public: + + IItemFamily* itemFamily() const { return m_item_family; } + Int32 localId() const { return m_local_id; } + Int64 uniqueId() const { return m_unique_id; } + bool isAdd() const { return m_is_add; } + + public: + + void setIsAdd(bool v) { m_is_add = v; } + + private: + + IItemFamily* m_item_family = nullptr; + Int32 m_local_id = NULL_ITEM_LOCAL_ID; + Int64 m_unique_id = NULL_ITEM_UNIQUE_ID; + bool m_is_add = false; +}; + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +} // namespace Arcane + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +#endif diff --git a/arcane/src/arcane/core/srcs.cmake b/arcane/src/arcane/core/srcs.cmake index e6be7e031..7b3cceb9a 100644 --- a/arcane/src/arcane/core/srcs.cmake +++ b/arcane/src/arcane/core/srcs.cmake @@ -307,6 +307,7 @@ set(ARCANE_ORIGINAL_SOURCES ItemEnumerator.h ItemEnumeratorBase.h ItemFamilyCompactInfos.h + ItemFamilyItemListChangedEventArgs.h ItemFamilySerializeArgs.h ItemFlags.h ItemFunctor.cc diff --git a/arcane/src/arcane/mesh/DynamicMeshKindInfos.cc b/arcane/src/arcane/mesh/DynamicMeshKindInfos.cc index 28ee66b12..c1902a99e 100644 --- a/arcane/src/arcane/mesh/DynamicMeshKindInfos.cc +++ b/arcane/src/arcane/mesh/DynamicMeshKindInfos.cc @@ -1,11 +1,11 @@ // -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*- //----------------------------------------------------------------------------- -// Copyright 2000-2024 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com) +// Copyright 2000-2025 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com) // See the top-level COPYRIGHT file for details. // SPDX-License-Identifier: Apache-2.0 //----------------------------------------------------------------------------- /*---------------------------------------------------------------------------*/ -/* DynamicMeshKindInfos.cc (C) 2000-2024 */ +/* DynamicMeshKindInfos.cc (C) 2000-2025 */ /* */ /* Infos de maillage pour un genre d'entité donnée. */ /*---------------------------------------------------------------------------*/ @@ -27,6 +27,7 @@ #include "arcane/core/ItemFamilyCompactInfos.h" #include "arcane/core/IMeshCompacter.h" #include "arcane/core/MeshPartInfo.h" +#include "arcane/core/ItemFamilyItemListChangedEventArgs.h" #include "arcane/mesh/DynamicMeshKindInfos.h" #include "arcane/mesh/ItemFamily.h" @@ -916,6 +917,37 @@ _updateItemSharedInfoInternalView() /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ +EventObservableView DynamicMeshKindInfos:: +itemListChangedEvent() +{ + return EventObservableView(m_item_list_change_event); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +void DynamicMeshKindInfos:: +_notifyRemove2(ItemInternal* item) +{ + ItemFamilyItemListChangedEventArgs args(m_item_family,item->localId(),item->uniqueId()); + m_item_list_change_event.notify(args); + args.setIsAdd(false); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +void DynamicMeshKindInfos:: +_notifyAdd2(ItemInternal* item,Int64 uid) +{ + ItemFamilyItemListChangedEventArgs args(m_item_family,item->localId(),uid); + args.setIsAdd(true); + m_item_list_change_event.notify(args); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + } // End namespace Arcane::mesh /*---------------------------------------------------------------------------*/ diff --git a/arcane/src/arcane/mesh/DynamicMeshKindInfos.h b/arcane/src/arcane/mesh/DynamicMeshKindInfos.h index 66816c939..ae9fc3bab 100644 --- a/arcane/src/arcane/mesh/DynamicMeshKindInfos.h +++ b/arcane/src/arcane/mesh/DynamicMeshKindInfos.h @@ -1,11 +1,11 @@ // -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*- //----------------------------------------------------------------------------- -// Copyright 2000-2024 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com) +// Copyright 2000-2025 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com) // See the top-level COPYRIGHT file for details. // SPDX-License-Identifier: Apache-2.0 //----------------------------------------------------------------------------- /*---------------------------------------------------------------------------*/ -/* DynamicMeshKindInfos.h (C) 2000-2024 */ +/* DynamicMeshKindInfos.h (C) 2000-2025 */ /* */ /* Infos de maillage pour un genre d'entité donnée. */ /*---------------------------------------------------------------------------*/ @@ -18,6 +18,7 @@ #include "arcane/utils/String.h" #include "arcane/utils/HashTableMap.h" #include "arcane/utils/TraceAccessor.h" +#include "arcane/utils/Event.h" #include "arcane/core/ItemGroup.h" #include "arcane/core/ItemInternal.h" @@ -28,17 +29,15 @@ /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ -namespace Arcane -{ -class ItemFamilyCompactInfos; -} +// Define pour désactiver les évènements si on souhaite tester +// l'influence sur les performances (a priori il n'y en a pas). +#define ARCANE_ENABLE_EVENT_FOR_DYNAMICMESHKINDINFO /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ namespace Arcane::mesh { -class ItemFamily; /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ @@ -108,6 +107,9 @@ class ARCANE_MESH_EXPORT DynamicMeshKindInfos { bool need_alloc = false; ItemInternal* next = _allocOne(need_alloc); +#ifdef ARCANE_ENABLE_EVENT_FOR_DYNAMICMESHKINDINFO + _notifyAdd(next,unique_id); +#endif if (m_has_unique_id_map) if (!m_items_map.add(unique_id,next)) _badSameUniqueId(unique_id); @@ -118,6 +120,9 @@ class ARCANE_MESH_EXPORT DynamicMeshKindInfos ItemInternal* allocOne(Int64 unique_id,bool& need_alloc) { ItemInternal* next = _allocOne(need_alloc); +#ifdef ARCANE_ENABLE_EVENT_FOR_DYNAMICMESHKINDINFO + _notifyAdd(next,unique_id); +#endif if (m_has_unique_id_map) if (!m_items_map.add(unique_id,next)) _badSameUniqueId(unique_id); @@ -138,6 +143,9 @@ class ARCANE_MESH_EXPORT DynamicMeshKindInfos } m_free_internals.add(item->localId()); m_removed_items.add(item->localId()); +#ifdef ARCANE_ENABLE_EVENT_FOR_DYNAMICMESHKINDINFO + _notifyRemove(item); +#endif --m_nb_item; } @@ -154,6 +162,9 @@ class ARCANE_MESH_EXPORT DynamicMeshKindInfos #endif m_free_internals.add(item->localId()); m_removed_items.add(item->localId()); +#ifdef ARCANE_ENABLE_EVENT_FOR_DYNAMICMESHKINDINFO + _notifyRemove(item); +#endif --m_nb_item; } @@ -191,6 +202,9 @@ class ARCANE_MESH_EXPORT DynamicMeshKindInfos if (is_alloc){ bool need_alloc; item_data.setValue(_allocOne(need_alloc)); +#ifdef ARCANE_ENABLE_EVENT_FOR_DYNAMICMESHKINDINFO + _notifyAdd(item_data.value(),uid); +#endif } return item_data.value(); } @@ -266,6 +280,10 @@ class ARCANE_MESH_EXPORT DynamicMeshKindInfos void printFreeInternals(Integer max_print); + public: + + EventObservableView itemListChangedEvent(); + private: /*! \brief Ajoute une entité. @@ -320,6 +338,7 @@ class ARCANE_MESH_EXPORT DynamicMeshKindInfos //! Temporaire tant que oldToNewLocalIds() et newToOldLocalIds() existent ItemFamilyCompactInfos* m_compact_infos; ItemSharedInfo* m_common_item_shared_info = nullptr; + EventObservable m_item_list_change_event; public: @@ -360,6 +379,18 @@ class ARCANE_MESH_EXPORT DynamicMeshKindInfos void _badSameUniqueId(Int64 unique_id) const; void _badUniqueIdMap() const; void _updateItemSharedInfoInternalView(); + void _notifyRemove(ItemInternal* item) + { + if (m_item_list_change_event.hasObservers()) + _notifyRemove2(item); + } + void _notifyAdd(ItemInternal* item,Int64 uid) + { + if (m_item_list_change_event.hasObservers()) + _notifyAdd2(item,uid); + } + void _notifyRemove2(ItemInternal* item); + void _notifyAdd2(ItemInternal* item,Int64 uid); }; /*---------------------------------------------------------------------------*/ diff --git a/arcane/src/arcane/mesh/ItemFamily.cc b/arcane/src/arcane/mesh/ItemFamily.cc index 0deb3cca5..11380d199 100644 --- a/arcane/src/arcane/mesh/ItemFamily.cc +++ b/arcane/src/arcane/mesh/ItemFamily.cc @@ -2474,6 +2474,15 @@ setConnectivityMng(IItemConnectivityMng* connectivity_mng) /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ +EventObservableView ItemFamily:: +itemListChangedEvent() +{ + return m_infos->itemListChangedEvent(); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + void ItemFamily:: _addSourceConnectivity(IIncrementalItemSourceConnectivity* c) { diff --git a/arcane/src/arcane/mesh/ItemFamily.h b/arcane/src/arcane/mesh/ItemFamily.h index f50bcb42e..140e1abd2 100644 --- a/arcane/src/arcane/mesh/ItemFamily.h +++ b/arcane/src/arcane/mesh/ItemFamily.h @@ -268,6 +268,8 @@ class ARCANE_MESH_EXPORT ItemFamily void setConnectivityMng(IItemConnectivityMng* connectivity_mng) override; void addGhostItems(Int64ConstArrayView unique_ids, Int32ArrayView items, Int32ConstArrayView owners) override; + EventObservableView itemListChangedEvent() override; + IItemFamilyPolicyMng* policyMng() override { return m_policy_mng; } Properties* properties() override { return m_properties; } IItemFamilyInternal* _internalApi() override; diff --git a/arcane/src/arcane/tests/CMakeLists.txt b/arcane/src/arcane/tests/CMakeLists.txt index 85ed06e6d..9679df775 100644 --- a/arcane/src/arcane/tests/CMakeLists.txt +++ b/arcane/src/arcane/tests/CMakeLists.txt @@ -662,6 +662,8 @@ if(PARTITIONER_FOUND) # ARCANE_ADD_TEST_PARALLEL(mesh_merge_nodes_2d testMeshMergeNodes-2D.arc 4) endif() +arcane_add_test_sequential(mesh_modification-1D testMeshModificationTester-1D.arc) +arcane_add_test_sequential(mesh_modification-3D testMeshModificationTester-3D.arc) arcane_add_test(mesh2 testMesh-2.arc "-We,ARCANE_METIS_INPUT_OUTPUT_DIGEST,1") if (Parmetis_FOUND) arcane_add_test_parallel_thread(mesh2_face_unique_id_v5 testMesh-2-face-unique-id-v5.arc 4) diff --git a/arcane/src/arcane/tests/MeshModificationTester.cc b/arcane/src/arcane/tests/MeshModificationTester.cc index c077ad0ae..0d21a4223 100644 --- a/arcane/src/arcane/tests/MeshModificationTester.cc +++ b/arcane/src/arcane/tests/MeshModificationTester.cc @@ -1,24 +1,27 @@ // -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*- //----------------------------------------------------------------------------- -// Copyright 2000-2023 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com) +// Copyright 2000-2025 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com) // See the top-level COPYRIGHT file for details. // SPDX-License-Identifier: Apache-2.0 //----------------------------------------------------------------------------- /*---------------------------------------------------------------------------*/ -/* MeshModificationTester.cc (C) 2000-2023 */ +/* MeshModificationTester.cc (C) 2000-2025 */ /* */ /* Service du test de la modification du maillage. */ /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ #include "arcane/tests/ArcaneTestGlobal.h" -#include "arcane/BasicUnitTest.h" -#include "arcane/tests/MeshModificationTester_axl.h" +#include "arcane/utils/Event.h" + +#include "arcane/core/BasicUnitTest.h" +#include "arcane/core/IMesh.h" +#include "arcane/core/IMeshModifier.h" +#include "arcane/core/IItemFamily.h" +#include "arcane/core/ItemFamilyItemListChangedEventArgs.h" -#include "arcane/IMesh.h" -#include "arcane/IMeshModifier.h" -#include "arcane/IItemFamily.h" +#include "arcane/tests/MeshModificationTester_axl.h" /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ @@ -38,35 +41,61 @@ class MeshModificationTester : public ArcaneMeshModificationTesterObject { -public: + public: - MeshModificationTester(const ServiceBuildInfo& sb) - : ArcaneMeshModificationTesterObject(sb) {} - - ~MeshModificationTester() {} + explicit MeshModificationTester(const ServiceBuildInfo& sb) + : ArcaneMeshModificationTesterObject(sb) + {} public: - virtual void initializeTest(); - virtual void executeTest(); - + void buildInitializeTest() override; + void initializeTest() override; + void executeTest() override; + + private: + + EventObserverPool m_event_observer_pool; + Int32 m_nb_node_from_notify_event = 0; + private: + void _refineCells(); + void _addRemoveCells(); Int64 _searchMaxUniqueId(ItemGroup group); - + void _checkValidNbNode(); }; /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ -ARCANE_REGISTER_SERVICE_MESHMODIFICATIONTESTER(MeshModificationTester,MeshModificationTester); +ARCANE_REGISTER_SERVICE_MESHMODIFICATIONTESTER(MeshModificationTester, MeshModificationTester); + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +void MeshModificationTester:: +buildInitializeTest() +{ + auto family_changed_event = [&](const ItemFamilyItemListChangedEventArgs& args) { + if (args.isAdd()) { + info() << "NodeAdd lid=" << args.localId() << " " << args.uniqueId(); + ++m_nb_node_from_notify_event; + } + else { + info() << "NodeRemove lid=" << args.localId() << " " << args.uniqueId(); + --m_nb_node_from_notify_event; + } + }; + mesh()->nodeFamily()->itemListChangedEvent().attach(m_event_observer_pool, family_changed_event); +} /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ void MeshModificationTester:: initializeTest() -{ +{ info() << "init test"; } @@ -77,13 +106,24 @@ void MeshModificationTester:: executeTest() { info() << "execute test"; - - _refineCells(); // copied from MeshModifications.cs C# for easier debug + if (mesh()->dimension() == 3) + _refineCells(); // copied from MeshModifications.cs C# for easier debug + if (mesh()->dimension() == 2) + _addRemoveCells(); +} + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +void MeshModificationTester:: +_addRemoveCells() +{ + // Uniquement valide pour les maillages 1D. Int32UniqueArray lids(allCells().size()); - ENUMERATE_CELL(icell,allCells()) { - info() << "cell[" << icell->localId() << "," << icell->uniqueId() << "] type=" - << icell->type() << ", nb nodes=" << icell->nbNode(); + ENUMERATE_CELL (icell, allCells()) { + info() << "cell[" << icell->localId() << "," << icell->uniqueId() << "] type=" + << icell->type() << ", nb nodes=" << icell->nbNode(); lids[icell.index()] = icell->localId(); } @@ -93,40 +133,42 @@ executeTest() modifier->removeCells(lids); modifier->endUpdate(); + _checkValidNbNode(); info() << "===================== THE MESH IS EMPTY"; // On ajoute des noeuds Int64UniqueArray nodes_uid(5); - for(Integer i = 0; i < 5; ++i) - nodes_uid[i] = i+10; - + for (Integer i = 0; i < 5; ++i) + nodes_uid[i] = i + 10; + modifier->addNodes(nodes_uid); - + info() << "===================== THE NODES ARE ADDED"; - Int64UniqueArray cells_infos(4*4); + Int64UniqueArray cells_infos(4 * 4); Integer j = 0; - for(Integer i = 0; i < 4; ++i) { + for (Integer i = 0; i < 4; ++i) { cells_infos[j++] = IT_CellLine2; - cells_infos[j++] = i+5; - cells_infos[j++] = i+10; - cells_infos[j++] = i+11; + cells_infos[j++] = i + 5; + cells_infos[j++] = i + 10; + cells_infos[j++] = i + 11; } - + IntegerUniqueArray cells_lid; modifier->addCells(4, cells_infos, cells_lid); info() << "===================== THE CELLS ARE ADDED"; modifier->endUpdate(); + _checkValidNbNode(); - ENUMERATE_CELL(icell,allCells()) { - info() << "cell[" << icell->localId() << "," << icell->uniqueId() << "] type=" - << icell->type() << ", nb nodes=" << icell->nbNode(); + ENUMERATE_CELL (icell, allCells()) { + info() << "cell[" << icell->localId() << "," << icell->uniqueId() << "] type=" + << icell->type() << ", nb nodes=" << icell->nbNode(); //lids[icell.index()] = icell->localId(); } - + info() << "===================== DELETING OF ONLY ONE CELL"; lids.resize(1); @@ -134,10 +176,11 @@ executeTest() modifier->removeCells(lids); modifier->endUpdate(); - - ENUMERATE_CELL(icell,allCells()) { - info() << "cell[" << icell->localId() << "," << icell->uniqueId() << "] type=" - << icell->type() << ", nb nodes=" << icell->nbNode(); + _checkValidNbNode(); + + ENUMERATE_CELL (icell, allCells()) { + info() << "cell[" << icell->localId() << "," << icell->uniqueId() << "] type=" + << icell->type() << ", nb nodes=" << icell->nbNode(); } info() << "===================== ADDING ONLY ONE CELL"; @@ -152,26 +195,27 @@ executeTest() modifier->addCells(1, cells_infos, cells_lid); modifier->endUpdate(); + _checkValidNbNode(); - ENUMERATE_CELL(icell,allCells()) { - info() << "cell[" << icell->localId() << "," << icell->uniqueId() << "] type=" - << icell->type() << ", nb nodes=" << icell->nbNode(); + ENUMERATE_CELL (icell, allCells()) { + info() << "cell[" << icell->localId() << "," << icell->uniqueId() << "] type=" + << icell->type() << ", nb nodes=" << icell->nbNode(); } info() << "===================== DELETE THEN ADD ONE CELL ONLY"; - + lids.resize(1); lids[0] = 1; CellGroup group = mesh()->cellFamily()->createGroup("Test"); group.addItems(lids); - - ENUMERATE_CELL(icell,group) { + + ENUMERATE_CELL (icell, group) { info() << "before add/remove cell[" << icell->localId() << "," << icell->uniqueId() << "] in group " << group.name(); } modifier->removeCells(lids); - + cells_infos.resize(4); cells_infos[0] = IT_CellLine2; cells_infos[1] = 17; @@ -182,28 +226,30 @@ executeTest() modifier->addCells(1, cells_infos, cells_lid); modifier->endUpdate(); - + _checkValidNbNode(); + info() << "after add/remove cell[" << "group " << group.name() << " size = " << group.size(); - ENUMERATE_CELL(icell,group) { + ENUMERATE_CELL (icell, group) { info() << "after add/remove cell[" << icell->localId() << "," << icell->uniqueId() << "] in group " << group.name(); } - if(group.size() != 0) - fatal() << "Error after in mesh update, group is not empty..."; + if (group.size() != 0) + ARCANE_FATAL("Error after in mesh update, group is not empty..."); - ENUMERATE_CELL(icell,allCells()) { - info() << "cell[" << icell->localId() << "," << icell->uniqueId() << "] type=" - << icell->type() << ", nb nodes=" << icell->nbNode(); + ENUMERATE_CELL (icell, allCells()) { + info() << "cell[" << icell->localId() << "," << icell->uniqueId() << "] type=" + << icell->type() << ", nb nodes=" << icell->nbNode(); } // Detach cells Int32UniqueArray detached_cells; - ENUMERATE_CELL(icell,allCells()) { + ENUMERATE_CELL (icell, allCells()) { detached_cells.add(icell->localId()); - } + } modifier->detachCells(detached_cells); modifier->removeDetachedCells(detached_cells); modifier->endUpdate(); + _checkValidNbNode(); } /*---------------------------------------------------------------------------*/ @@ -212,100 +258,119 @@ executeTest() void MeshModificationTester:: _refineCells() { - Int64 max_node_uid = _searchMaxUniqueId(mesh()->allNodes()); - Int64 max_cell_uid = _searchMaxUniqueId(mesh()->allCells()); - info() << String::format("MAX UID NODE={0} CELL={1}",max_node_uid,max_cell_uid); - - CellGroup all_cells = mesh()->allCells(); - int index = 0; - Integer nb_cell_to_add = 0; - UniqueArray cells_to_detach; - UniqueArray to_add_cells; - UniqueArray nodes_to_add; - UniqueArray nodes_to_add_coords; - VariableNodeReal3& nodes_coords = mesh()->nodesCoordinates(); - ENUMERATE_CELL(cell, all_cells) { - //TODO: tester si la maille est un hexaedre - //if (c. - ++index; - if ((index % 3) == 0){ - cells_to_detach.add(cell.localId()); - - to_add_cells.add(8); // Pour une pyramide - //to_add_cells.Add(max_cell_uid + index); // Pour le uid - to_add_cells.add(cell->uniqueId().asInt64() + max_cell_uid); // Pour le uid, reutilise celui de la maille supprimée - //to_add_cells.Add(c.UniqueId); // Pour le uid, reutilise celui de la maille supprimée - to_add_cells.add(cell->node(0).uniqueId().asInt64()); - to_add_cells.add(cell->node(1).uniqueId().asInt64()); - to_add_cells.add(cell->node(2).uniqueId().asInt64()); - to_add_cells.add(cell->node(3).uniqueId().asInt64()); - Real3 center; - for( NodeLocalId inode : cell->nodeIds()) { - center += nodes_coords[inode]; - info() << String::format("ADD CENTER {0}",nodes_coords[inode]); - } - center /= (Real)cell->nbNode(); - Int64 node_uid = max_node_uid + index; - Int64 cell_uid = max_cell_uid + index; - nodes_to_add.add(node_uid); - nodes_to_add_coords.add(center); - to_add_cells.add(node_uid); - info() << String::format("WANT ADD NODE UID={0} COORD={1} CELL_UID={2}",node_uid,center,cell_uid); - ++nb_cell_to_add; + Int64 max_node_uid = _searchMaxUniqueId(mesh()->allNodes()); + Int64 max_cell_uid = _searchMaxUniqueId(mesh()->allCells()); + info() << String::format("MAX UID NODE={0} CELL={1}", max_node_uid, max_cell_uid); + + _checkValidNbNode(); + + CellGroup all_cells = mesh()->allCells(); + int index = 0; + Integer nb_cell_to_add = 0; + UniqueArray cells_to_detach; + UniqueArray to_add_cells; + UniqueArray nodes_to_add; + UniqueArray nodes_to_add_coords; + VariableNodeReal3& nodes_coords = mesh()->nodesCoordinates(); + ENUMERATE_CELL (cell, all_cells) { + //TODO: tester si la maille est un hexaedre + //if (c. + ++index; + if ((index % 3) == 0) { + cells_to_detach.add(cell.localId()); + + to_add_cells.add(8); // Pour une pyramide + //to_add_cells.Add(max_cell_uid + index); // Pour le uid + to_add_cells.add(cell->uniqueId().asInt64() + max_cell_uid); // Pour le uid, reutilise celui de la maille supprimée + //to_add_cells.Add(c.UniqueId); // Pour le uid, reutilise celui de la maille supprimée + to_add_cells.add(cell->node(0).uniqueId().asInt64()); + to_add_cells.add(cell->node(1).uniqueId().asInt64()); + to_add_cells.add(cell->node(2).uniqueId().asInt64()); + to_add_cells.add(cell->node(3).uniqueId().asInt64()); + Real3 center; + for (NodeLocalId inode : cell->nodeIds()) { + center += nodes_coords[inode]; + info() << String::format("ADD CENTER {0}", nodes_coords[inode]); } + center /= (Real)cell->nbNode(); + Int64 node_uid = max_node_uid + index; + Int64 cell_uid = max_cell_uid + index; + nodes_to_add.add(node_uid); + nodes_to_add_coords.add(center); + to_add_cells.add(node_uid); + info() << String::format("WANT ADD NODE UID={0} COORD={1} CELL_UID={2}", node_uid, center, cell_uid); + ++nb_cell_to_add; } + } - IMeshModifier* modifier = mesh()->modifier(); - Integer nb_node_added = nodes_to_add.size(); - UniqueArray new_nodes_local_id(nb_node_added); - - modifier->addNodes(nodes_to_add.constView(),new_nodes_local_id.view()); - mesh()->nodeFamily()->endUpdate(); - info() << String::format("NODES ADDED = {0}",nb_node_added); - NodeInfoListView new_nodes(mesh()->nodeFamily()); - for(int i=0; imodifier(); + Integer nb_node_added = nodes_to_add.size(); + UniqueArray new_nodes_local_id(nb_node_added); + + modifier->addNodes(nodes_to_add.constView(), new_nodes_local_id.view()); + mesh()->nodeFamily()->endUpdate(); + info() << String::format("NODES ADDED = {0}", nb_node_added); + _checkValidNbNode(); + NodeInfoListView new_nodes(mesh()->nodeFamily()); + for (int i = 0; i < nb_node_added; ++i) { + Int32 new_local_id = new_nodes_local_id[i]; + Item new_node = new_nodes[new_local_id]; + info() << String::format("NEW LOCAL ID={0} Coord={1} UID={2}", new_local_id, nodes_to_add_coords[i], new_node.uniqueId()); + nodes_coords[new_nodes[new_local_id]] = nodes_to_add_coords[i]; + } - info() << String::format("NB CELL TO ADD = {0}",nb_cell_to_add); - warning() << "TEST WARNING"; - Int64ConstArrayView uid_view = to_add_cells.constView(); - for( Integer i=0; idetachCells(cells_to_detach.constView()); - modifier->addCells(nb_cell_to_add,to_add_cells.constView()); - modifier->removeDetachedCells(cells_to_detach.constView()); - modifier->endUpdate(); + Int64ConstArrayView uid_view = to_add_cells.constView(); + for (Integer i = 0; i < uid_view.size(); ++i) { + info() << " "; + info() << uid_view[i]; } + info() << "."; + + // Avant d'ajouter les nouvelles mailles, il faut détacher les anciennes + modifier->detachCells(cells_to_detach.constView()); + modifier->addCells(nb_cell_to_add, to_add_cells.constView()); + modifier->removeDetachedCells(cells_to_detach.constView()); + modifier->endUpdate(); + _checkValidNbNode(); +} + /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ - Int64 MeshModificationTester:: _searchMaxUniqueId(ItemGroup group) - { +{ Int64 max_uid = 0; - ENUMERATE_ITEM(item, group) { + ENUMERATE_ITEM (item, group) { //Console.WriteLine("IT IS MY TEST! {0} {1} ",i.UniqueId,MyClass.NB); Int64 uid = item->uniqueId(); //Console.WriteLine("IT IS MY TEST! {0} {1}",uid,MyClass.NB); - max_uid = (uid>max_uid) ? uid : max_uid; + max_uid = (uid > max_uid) ? uid : max_uid; } return max_uid; - } +} /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ +void MeshModificationTester:: +_checkValidNbNode() +{ + // Vérifie que le nombre de noeuds correspond à celui géré + // via l'évènement IItemFamily::itemListChangedEvent. + Int32 nb_expected_node = mesh()->nbNode(); + Int32 nb_node = m_nb_node_from_notify_event; + info() << "NbNode from event=" << nb_node << " expected=" << nb_expected_node; + if (nb_node != nb_expected_node) + ARCANE_FATAL("Bad number of node v={0} expected={1}", nb_node, nb_expected_node); } /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ + +} // namespace ArcaneTest + +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ diff --git a/arcane/src/arcane/utils/Event.h b/arcane/src/arcane/utils/Event.h index 3faf3763d..be4185925 100644 --- a/arcane/src/arcane/utils/Event.h +++ b/arcane/src/arcane/utils/Event.h @@ -25,11 +25,6 @@ namespace Arcane { -/*---------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------*/ - -class EventObserverBase; - /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ /*! @@ -38,7 +33,7 @@ class EventObserverBase; */ class ARCANE_UTILS_EXPORT EventObservableBase { - friend class EventObserverBase; + friend EventObserverBase; class Impl; public: @@ -241,6 +236,56 @@ class EventObservable } }; +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ +/*! + * \ingroup Utils + * \brief Classe gérant les observateurs associés à un évènement. + * \sa EventObservable + */ +template +class EventObservableView +{ + public: + + typedef EventObserver ObserverType; + + public: + + explicit EventObservableView(EventObservable& v) + : m_observable_ref(v) + {} + + public: + + /*! + * \brief Attache l'observateur \a o à cet observable. + * + * Une exception est levée si l'observateur est déjà attaché à un observable. + */ + void attach(ObserverType* o) { m_observable_ref.attach(o); } + /*! + * \brief Détache l'observateur \a o de cet observable. + * + * Une exception est levée si l'observateur n'est pas attaché à cet observable. + */ + void detach(ObserverType* o) { m_observable_ref.detach(o); } + + /*! + * \brief Ajoute un observateur utilisant la lambda \a lambda + * et conserve une référence dans \a pool. + */ + template + void attach(EventObserverPool& pool, const Lambda& lambda) + { + m_observable_ref.attach(pool, lambda); + } + + private: + + EventObservable& m_observable_ref; +}; + /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ @@ -249,4 +294,4 @@ class EventObservable /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ -#endif +#endif diff --git a/arcane/src/arcane/utils/UtilsTypes.h b/arcane/src/arcane/utils/UtilsTypes.h index c99d8234a..165aeda02 100644 --- a/arcane/src/arcane/utils/UtilsTypes.h +++ b/arcane/src/arcane/utils/UtilsTypes.h @@ -51,8 +51,11 @@ template class ListEnumeratorT; template class Collection; template class List; +class EventObservableBase; +class EventObserverBase; template class EventObservable; template class EventObserver; +template class EventObservableView; /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ diff --git a/arcane/tests/addRemoveBug.arc b/arcane/tests/testMeshModificationTester-1D.arc similarity index 100% rename from arcane/tests/addRemoveBug.arc rename to arcane/tests/testMeshModificationTester-1D.arc diff --git a/arcane/tests/testMeshModificationTester-3D.arc b/arcane/tests/testMeshModificationTester-3D.arc new file mode 100644 index 000000000..d2a73f2e0 --- /dev/null +++ b/arcane/tests/testMeshModificationTester-3D.arc @@ -0,0 +1,17 @@ + + + + Test Maillage 1 + Test Maillage 1D + UnitTest + + + + 1044 + + + + + + +