From ab23b59effd74cfd6408986217b44598f022c215 Mon Sep 17 00:00:00 2001 From: sunethwarna Date: Fri, 8 Nov 2024 09:03:07 +0100 Subject: [PATCH 01/13] fix operators --- kratos/containers/pointer_vector_set.h | 50 +++++--------------------- 1 file changed, 9 insertions(+), 41 deletions(-) diff --git a/kratos/containers/pointer_vector_set.h b/kratos/containers/pointer_vector_set.h index 7eccc0b0fc7..ef5e9709704 100644 --- a/kratos/containers/pointer_vector_set.h +++ b/kratos/containers/pointer_vector_set.h @@ -178,29 +178,12 @@ class PointerVectorSet final */ TDataType& operator[](const key_type& Key) { - ptr_iterator sorted_part_end; - - if (mData.size() - mSortedPartSize >= mMaxBufferSize) { - Sort(); - sorted_part_end = mData.end(); + ptr_iterator i(std::lower_bound(mData.begin(), mData.end(), Key, CompareKey())); + if (EqualKeyTo(Key)(*i)) { + return **i; } else { - sorted_part_end = mData.begin() + mSortedPartSize; + return **mData.insert(i, TPointerType(new TDataType(Key))); } - - ptr_iterator i(std::lower_bound(mData.begin(), sorted_part_end, Key, CompareKey())); - if (i == sorted_part_end) { - mSortedPartSize++; - return **mData.insert(sorted_part_end, TPointerType(new TDataType(Key))); - } - - if (!EqualKeyTo(Key)(*i)) { - if ((i = std::find_if(sorted_part_end, mData.end(), EqualKeyTo(Key))) == mData.end()) { - mData.push_back(TPointerType(new TDataType(Key))); - return **(mData.end() - 1); - } - } - - return **i; } /** @@ -213,27 +196,12 @@ class PointerVectorSet final */ pointer& operator()(const key_type& Key) { - ptr_iterator sorted_part_end; - - if (mData.size() - mSortedPartSize >= mMaxBufferSize) { - Sort(); - sorted_part_end = mData.end(); - } else - sorted_part_end = mData.begin() + mSortedPartSize; - - ptr_iterator i(std::lower_bound(mData.begin(), sorted_part_end, Key, CompareKey())); - if (i == sorted_part_end) { - mSortedPartSize++; - return *mData.insert(sorted_part_end, TPointerType(new TDataType(Key))); + ptr_iterator i(std::lower_bound(mData.begin(), mData.end(), Key, CompareKey())); + if (EqualKeyTo(Key)(*i)) { + return *i; + } else { + return *mData.insert(i, TPointerType(new TDataType(Key))); } - - if (!EqualKeyTo(Key)(*i)) - if ((i = std::find_if(sorted_part_end, mData.end(), EqualKeyTo(Key))) == mData.end()) { - mData.push_back(TPointerType(new TDataType(Key))); - return *(mData.end() - 1); - } - - return *i; } /** From 32d9d48eba7102c5ec2f16ce0ead99d6d35f6294 Mon Sep 17 00:00:00 2001 From: sunethwarna Date: Fri, 8 Nov 2024 09:59:35 +0100 Subject: [PATCH 02/13] add static assert --- kratos/containers/pointer_vector_set.h | 33 ++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/kratos/containers/pointer_vector_set.h b/kratos/containers/pointer_vector_set.h index ef5e9709704..3b2660a4d4d 100644 --- a/kratos/containers/pointer_vector_set.h +++ b/kratos/containers/pointer_vector_set.h @@ -20,6 +20,7 @@ #include #include #include +#include // External includes #include @@ -71,6 +72,36 @@ template, "Raw pointers are not supported."); return **mData.insert(i, TPointerType(new TDataType(Key))); } } @@ -200,6 +232,7 @@ class PointerVectorSet final if (EqualKeyTo(Key)(*i)) { return *i; } else { + static_assert(!std::is_same_v, "Raw pointers are not supported."); return *mData.insert(i, TPointerType(new TDataType(Key))); } } From 0fb1461fa40685f1256f4dd9f99b453585d282a4 Mon Sep 17 00:00:00 2001 From: sunethwarna Date: Fri, 8 Nov 2024 10:12:16 +0100 Subject: [PATCH 03/13] revert changes --- kratos/containers/pointer_vector_set.h | 30 -------------------------- 1 file changed, 30 deletions(-) diff --git a/kratos/containers/pointer_vector_set.h b/kratos/containers/pointer_vector_set.h index 3b2660a4d4d..3190c123698 100644 --- a/kratos/containers/pointer_vector_set.h +++ b/kratos/containers/pointer_vector_set.h @@ -72,36 +72,6 @@ template Date: Sat, 9 Nov 2024 15:24:57 +0100 Subject: [PATCH 04/13] add MutablePass --- kratos/containers/pointer_vector_set.h | 153 +++++++++++++++++++++---- 1 file changed, 128 insertions(+), 25 deletions(-) diff --git a/kratos/containers/pointer_vector_set.h b/kratos/containers/pointer_vector_set.h index ef5e9709704..cdd0a67831c 100644 --- a/kratos/containers/pointer_vector_set.h +++ b/kratos/containers/pointer_vector_set.h @@ -20,6 +20,7 @@ #include #include #include +#include // External includes #include @@ -71,6 +72,88 @@ template, "Raw pointers are not supported."); return **mData.insert(i, TPointerType(new TDataType(Key))); } } @@ -196,10 +281,12 @@ class PointerVectorSet final */ pointer& operator()(const key_type& Key) { + KRATOS_ERROR_IF(mHasMutablePass) << "A mutable pass is active. Hence, use of this function prohibited."; ptr_iterator i(std::lower_bound(mData.begin(), mData.end(), Key, CompareKey())); - if (EqualKeyTo(Key)(*i)) { + if (i != mData.end() && EqualKeyTo(Key)(*i)) { return *i; } else { + static_assert(!std::is_pointer_v, "Raw pointers are not supported."); return *mData.insert(i, TPointerType(new TDataType(Key))); } } @@ -536,6 +623,7 @@ class PointerVectorSet final */ iterator insert(const TPointerType& value) { + KRATOS_ERROR_IF(mHasMutablePass) << "A mutable pass is active. Hence, use of this function prohibited."; auto itr_pos = std::lower_bound(mData.begin(), mData.end(), KeyOf(*value), CompareKey()); if (itr_pos == mData.end()) { // the position to insert is at the end. @@ -564,6 +652,7 @@ class PointerVectorSet final */ iterator insert(const_iterator position_hint, const TPointerType& value) { + KRATOS_ERROR_IF(mHasMutablePass) << "A mutable pass is active. Hence, use of this function prohibited."; if (empty()) { // the dataset is empty. So use push back. mData.push_back(value); @@ -615,6 +704,7 @@ class PointerVectorSet final template void insert(InputIterator first, InputIterator last) { + KRATOS_ERROR_IF(mHasMutablePass) << "A mutable pass is active. Hence, use of this function prohibited."; // first sorts the input iterators and make the input unique. std::sort(first, last, CompareKey()); auto new_last = std::unique(first, last, EqualKeyTo()); @@ -709,20 +799,13 @@ class PointerVectorSet final */ iterator find(const key_type& Key) { - ptr_iterator sorted_part_end; - - if (mData.size() - mSortedPartSize >= mMaxBufferSize) { - Sort(); - sorted_part_end = mData.end(); - } else - sorted_part_end = mData.begin() + mSortedPartSize; - - ptr_iterator i(std::lower_bound(mData.begin(), sorted_part_end, Key, CompareKey())); - if (i == sorted_part_end || (!EqualKeyTo(Key)(*i))) - if ((i = std::find_if(sorted_part_end, mData.end(), EqualKeyTo(Key))) == mData.end()) - return mData.end(); - - return i; + KRATOS_ERROR_IF(mHasMutablePass) << "A mutable pass is active. Hence, use of this function prohibited."; + ptr_iterator i(std::lower_bound(mData.begin(), mData.end(), Key, CompareKey())); + if (i != mData.end() && EqualKeyTo(Key)(*i)) { + return i; + } else { + return mData.end(); + } } /** @@ -735,14 +818,13 @@ class PointerVectorSet final */ const_iterator find(const key_type& Key) const { - ptr_const_iterator sorted_part_end(mData.begin() + mSortedPartSize); - - ptr_const_iterator i(std::lower_bound(mData.begin(), sorted_part_end, Key, CompareKey())); - if (i == sorted_part_end || (!EqualKeyTo(Key)(*i))) - if ((i = std::find_if(sorted_part_end, mData.end(), EqualKeyTo(Key))) == mData.end()) - return mData.end(); - - return const_iterator(i); + KRATOS_ERROR_IF(mHasMutablePass) << "A mutable pass is active. Hence, use of this function prohibited."; + ptr_const_iterator i(std::lower_bound(mData.begin(), mData.end(), Key, CompareKey())); + if (i != mData.end() && EqualKeyTo(Key)(*i)) { + return const_iterator(i); + } else { + return mData.end(); + } } /** @@ -806,6 +888,12 @@ class PointerVectorSet final ///@name Access ///@{ + MutablePass GetMutablePass() + { + + return MutablePass(*this); + } + /** Gives a reference to underly normal container. */ TContainerType& GetContainer() { @@ -1030,6 +1118,8 @@ class PointerVectorSet final /// The maximum buffer size for data storage. size_type mMaxBufferSize; + std::atomic mHasMutablePass = false; + ///@} ///@name Private Operators ///@{ @@ -1181,7 +1271,7 @@ class PointerVectorSet final } ///@} - ///@name Serialization + ///@name Friend classes ///@{ /** @@ -1190,6 +1280,19 @@ class PointerVectorSet final */ friend class Serializer; + /** + * @class MutablePass + * @brief A friend class responsible for giving a pass to mutate which may destroy the sorted state + * of PointerVectorSet. All methods which relies on the sorted state will be frozen when this is + * active, and they will be unfrozen and PointerVectorSet will be sorted at the destruction on the + * MutablePass. + */ + friend class MutablePass; + + ///@} + ///@name Serialization + ///@{ + /** * @brief Extract the object's state and uses the Serializer to store it. * @param rSerializer Serializer instance to be used for saving. From 6510609cb174e07a34454312a3452d3953afacb2 Mon Sep 17 00:00:00 2001 From: sunethwarna Date: Sat, 9 Nov 2024 15:55:26 +0100 Subject: [PATCH 05/13] minor error message change --- kratos/containers/pointer_vector_set.h | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/kratos/containers/pointer_vector_set.h b/kratos/containers/pointer_vector_set.h index 7fdec4b5d41..61eb721a964 100644 --- a/kratos/containers/pointer_vector_set.h +++ b/kratos/containers/pointer_vector_set.h @@ -93,7 +93,8 @@ class PointerVectorSet final : mrContainer(rContainer) { KRATOS_CRITICAL_SECTION - KRATOS_ERROR_IF(mrContainer.mHasMutablePass) << "A mutable pass is active. Hence, use of this function prohibited."; + KRATOS_ERROR_IF(mrContainer.mHasMutablePass) + << "A mutable pass is active. Hence, creation of an another MutablePass is prohibited."; mrContainer.mHasMutablePass = true; } @@ -262,7 +263,8 @@ class PointerVectorSet final */ TDataType& operator[](const key_type& Key) { - KRATOS_ERROR_IF(mHasMutablePass) << "A mutable pass is active. Hence, use of this function prohibited."; + KRATOS_ERROR_IF(mHasMutablePass) + << "A mutable pass is active. Hence, use of PointerVectorSet::operator[] is prohibited."; ptr_iterator i(std::lower_bound(mData.begin(), mData.end(), Key, CompareKey())); if (i != mData.end() && EqualKeyTo(Key)(*i)) { return **i; @@ -282,7 +284,8 @@ class PointerVectorSet final */ pointer& operator()(const key_type& Key) { - KRATOS_ERROR_IF(mHasMutablePass) << "A mutable pass is active. Hence, use of this function prohibited."; + KRATOS_ERROR_IF(mHasMutablePass) + << "A mutable pass is active. Hence, use of PointerVectorSet::operator() is prohibited."; ptr_iterator i(std::lower_bound(mData.begin(), mData.end(), Key, CompareKey())); if (i != mData.end() && EqualKeyTo(Key)(*i)) { return *i; @@ -624,7 +627,8 @@ class PointerVectorSet final */ iterator insert(const TPointerType& value) { - KRATOS_ERROR_IF(mHasMutablePass) << "A mutable pass is active. Hence, use of this function prohibited."; + KRATOS_ERROR_IF(mHasMutablePass) + << "A mutable pass is active. Hence, use of PointerVectorSet::insert(value) is prohibited."; auto itr_pos = std::lower_bound(mData.begin(), mData.end(), KeyOf(*value), CompareKey()); if (itr_pos == mData.end()) { // the position to insert is at the end. @@ -653,7 +657,8 @@ class PointerVectorSet final */ iterator insert(const_iterator position_hint, const TPointerType& value) { - KRATOS_ERROR_IF(mHasMutablePass) << "A mutable pass is active. Hence, use of this function prohibited."; + KRATOS_ERROR_IF(mHasMutablePass) + << "A mutable pass is active. Hence, use of PointerVectorSet::insert(position_hint, value) is prohibited."; if (empty()) { // the dataset is empty. So use push back. mData.push_back(value); @@ -705,7 +710,8 @@ class PointerVectorSet final template void insert(InputIterator first, InputIterator last) { - KRATOS_ERROR_IF(mHasMutablePass) << "A mutable pass is active. Hence, use of this function prohibited."; + KRATOS_ERROR_IF(mHasMutablePass) + << "A mutable pass is active. Hence, use of PointerVectorSet::insert(first, last) is prohibited."; // first sorts the input iterators and make the input unique. std::sort(first, last, CompareKey()); auto new_last = std::unique(first, last, EqualKeyTo()); @@ -800,7 +806,8 @@ class PointerVectorSet final */ iterator find(const key_type& Key) { - KRATOS_ERROR_IF(mHasMutablePass) << "A mutable pass is active. Hence, use of this function prohibited."; + KRATOS_ERROR_IF(mHasMutablePass) + << "A mutable pass is active. Hence, use of PointerVectorSet::find(key) is prohibited."; ptr_iterator i(std::lower_bound(mData.begin(), mData.end(), Key, CompareKey())); if (i != mData.end() && EqualKeyTo(Key)(*i)) { return i; @@ -819,7 +826,8 @@ class PointerVectorSet final */ const_iterator find(const key_type& Key) const { - KRATOS_ERROR_IF(mHasMutablePass) << "A mutable pass is active. Hence, use of this function prohibited."; + KRATOS_ERROR_IF(mHasMutablePass) + << "A mutable pass is active. Hence, use of PointerVectorSet::find(key) is prohibited."; ptr_const_iterator i(std::lower_bound(mData.begin(), mData.end(), Key, CompareKey())); if (i != mData.end() && EqualKeyTo(Key)(*i)) { return const_iterator(i); @@ -891,7 +899,6 @@ class PointerVectorSet final MutablePass GetMutablePass() { - return MutablePass(*this); } From 1ee6ca2c81ce707a1857d1a359e62a17d7b7f9c1 Mon Sep 17 00:00:00 2001 From: Suneth Warnakulasuriya Date: Mon, 11 Nov 2024 10:05:57 +0100 Subject: [PATCH 06/13] adding some additional methods --- kratos/containers/pointer_vector_set.h | 84 ++++++++++++++------------ 1 file changed, 47 insertions(+), 37 deletions(-) diff --git a/kratos/containers/pointer_vector_set.h b/kratos/containers/pointer_vector_set.h index 61eb721a964..9b03fff3a8e 100644 --- a/kratos/containers/pointer_vector_set.h +++ b/kratos/containers/pointer_vector_set.h @@ -73,6 +73,43 @@ template()(std::declval()))>::type; + + // Data type stored in this container. + using data_type = TDataType; + using value_type = TDataType; + using key_compare = TCompareType; + using pointer = TPointerType; + using reference = TDataType&; + using const_reference = const TDataType&; + using ContainerType = TContainerType; + + /// @} + /// @name Iterators + /// @{ + using iterator = boost::indirect_iterator; + using const_iterator = boost::indirect_iterator; + using reverse_iterator = boost::indirect_iterator; + using const_reverse_iterator = boost::indirect_iterator; + + /// @} + /// @name Other definitions + /// @{ + using size_type = typename TContainerType::size_type; + using ptr_iterator = typename TContainerType::iterator; + using ptr_const_iterator = typename TContainerType::const_iterator; + using ptr_reverse_iterator = typename TContainerType::reverse_iterator; + using ptr_const_reverse_iterator = typename TContainerType::const_reverse_iterator; + using difference_type = typename TContainerType::difference_type; + + ///@} ///@name Class definitions ///@{ @@ -133,6 +170,16 @@ class PointerVectorSet final ///@name Public methods ///@{ + void shrink_to_fit() + { + mrContainer.mData.shrink_to_fit(); + } + + void reserve(size_type NewCapacity) + { + mrContainer.mData.reserve(NewCapacity); + } + void push_back(TPointerType pValue) { mrContainer.mData.push_back(pValue); @@ -155,43 +202,6 @@ class PointerVectorSet final ///@} }; - ///@} - ///@name Type Definitions - ///@{ - - /// Pointer definition of PointerVectorSet - KRATOS_CLASS_POINTER_DEFINITION(PointerVectorSet); - - /// Key type for searching in this container. - using key_type = typename std::remove_reference()(std::declval()))>::type; - - // Data type stored in this container. - using data_type = TDataType; - using value_type = TDataType; - using key_compare = TCompareType; - using pointer = TPointerType; - using reference = TDataType&; - using const_reference = const TDataType&; - using ContainerType = TContainerType; - - /// @} - /// @name Iterators - /// @{ - using iterator = boost::indirect_iterator; - using const_iterator = boost::indirect_iterator; - using reverse_iterator = boost::indirect_iterator; - using const_reverse_iterator = boost::indirect_iterator; - - /// @} - /// @name Other definitions - /// @{ - using size_type = typename TContainerType::size_type; - using ptr_iterator = typename TContainerType::iterator; - using ptr_const_iterator = typename TContainerType::const_iterator; - using ptr_reverse_iterator = typename TContainerType::reverse_iterator; - using ptr_const_reverse_iterator = typename TContainerType::const_reverse_iterator; - using difference_type = typename TContainerType::difference_type; - ///@} ///@name Life Cycle ///@{ From 0b3d72aa8bad4019a5cd1f4c48a738cefa6de776 Mon Sep 17 00:00:00 2001 From: Suneth Warnakulasuriya Date: Mon, 11 Nov 2024 10:30:32 +0100 Subject: [PATCH 07/13] minor --- kratos/containers/pointer_vector_set.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kratos/containers/pointer_vector_set.h b/kratos/containers/pointer_vector_set.h index 9b03fff3a8e..725c5d15833 100644 --- a/kratos/containers/pointer_vector_set.h +++ b/kratos/containers/pointer_vector_set.h @@ -152,7 +152,7 @@ class PointerVectorSet final std::sort(mrContainer.mData.begin(), mrContainer.mData.end(), CompareKey()); // Make the entities unique - typename TContainerType::iterator new_end_it = std::unique(mrContainer.mData.begin(), mrContainer.mData.end(), EqualKeyTo()); + auto new_end_it = std::unique(mrContainer.mData.begin(), mrContainer.mData.end(), EqualKeyTo()); // remove the duplicated entities. mrContainer.mData.erase(new_end_it, mrContainer.mData.end()); From 78ac0ff45596e975b55e0a4e7e1611e875ca9372 Mon Sep 17 00:00:00 2001 From: Suneth Warnakulasuriya Date: Mon, 11 Nov 2024 10:37:09 +0100 Subject: [PATCH 08/13] fix hdf5 application --- .../custom_io/hdf5_connectivities_data.cpp | 10 ++++++---- .../HDF5Application/custom_io/hdf5_points_data.cpp | 6 ++++-- .../tests/test_hdf5_model_part_io_mpi.py | 4 ---- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/applications/HDF5Application/custom_io/hdf5_connectivities_data.cpp b/applications/HDF5Application/custom_io/hdf5_connectivities_data.cpp index 34336924755..ef370a396a6 100644 --- a/applications/HDF5Application/custom_io/hdf5_connectivities_data.cpp +++ b/applications/HDF5Application/custom_io/hdf5_connectivities_data.cpp @@ -78,7 +78,8 @@ void ConnectivitiesData::CreateEntities(NodesContainerType& rNodes, const unsigned geometry_size = r_elem.GetGeometry().size(); KRATOS_ERROR_IF(geometry_size != mConnectivities.size2()) << "Non-matching geometry and connectivity sizes." << std::endl; - rElements.reserve(rElements.size() + num_new_elems); + auto mutable_pass = rElements.GetMutablePass(); + mutable_pass.reserve(rElements.size() + num_new_elems); ElementType::NodesArrayType nodes(geometry_size); for (unsigned i = 0; i < num_new_elems; ++i) @@ -90,7 +91,7 @@ void ConnectivitiesData::CreateEntities(NodesContainerType& rNodes, } ElementType::Pointer p_elem = r_elem.Create(mIds[i], nodes, rProperties(mPropertiesIds[i])); - rElements.push_back(p_elem); + mutable_pass.push_back(p_elem); } KRATOS_CATCH(""); } @@ -107,7 +108,8 @@ void ConnectivitiesData::CreateEntities(NodesContainerType& rNodes, const unsigned geometry_size = r_cond.GetGeometry().size(); KRATOS_ERROR_IF(geometry_size != mConnectivities.size2()) << "Non-matching geometry and connectivity sizes." << std::endl; - rConditions.reserve(rConditions.size() + num_new_conds); + auto mutable_pass = rConditions.GetMutablePass(); + mutable_pass.reserve(rConditions.size() + num_new_conds); ConditionType::NodesArrayType nodes(geometry_size); for (unsigned i = 0; i < num_new_conds; ++i) @@ -119,7 +121,7 @@ void ConnectivitiesData::CreateEntities(NodesContainerType& rNodes, } Condition::Pointer p_cond = r_cond.Create(mIds[i], nodes, rProperties(mPropertiesIds[i])); - rConditions.push_back(p_cond); + mutable_pass.push_back(p_cond); } KRATOS_CATCH(""); } diff --git a/applications/HDF5Application/custom_io/hdf5_points_data.cpp b/applications/HDF5Application/custom_io/hdf5_points_data.cpp index 8e7c4fa5d5f..744bbfaf2ab 100644 --- a/applications/HDF5Application/custom_io/hdf5_points_data.cpp +++ b/applications/HDF5Application/custom_io/hdf5_points_data.cpp @@ -30,13 +30,15 @@ void PointsData::CreateNodes(NodesContainerType& rNodes) { KRATOS_TRY; const unsigned num_new_nodes = mIds.size(); - rNodes.reserve(rNodes.size() + num_new_nodes); + + auto mutable_pass = rNodes.GetMutablePass(); + mutable_pass.reserve(rNodes.size() + num_new_nodes); for (unsigned i = 0; i < num_new_nodes; ++i) { const array_1d& r_coord = mCoords[i]; NodeType::Pointer p_node = Kratos::make_intrusive( mIds[i], r_coord[0], r_coord[1], r_coord[2]); - rNodes.push_back(p_node); + mutable_pass.push_back(p_node); } KRATOS_CATCH(""); } diff --git a/applications/HDF5Application/tests/test_hdf5_model_part_io_mpi.py b/applications/HDF5Application/tests/test_hdf5_model_part_io_mpi.py index 17abc9ee08f..e371c9043c0 100644 --- a/applications/HDF5Application/tests/test_hdf5_model_part_io_mpi.py +++ b/applications/HDF5Application/tests/test_hdf5_model_part_io_mpi.py @@ -203,8 +203,6 @@ def test_HDF5ModelPartIO(self): self.assertEqual(read_node.Z, write_node.Z) # Check elements self.assertEqual(read_model_part.NumberOfElements(), write_model_part.NumberOfElements()) - first_elem_id = next(iter(read_model_part.Elements)).Id - read_model_part.GetElement(first_elem_id) # Force a sort since order is mixed by openmp. for read_elem, write_elem in zip(read_model_part.Elements, write_model_part.Elements): self.assertEqual(read_elem.Id, write_elem.Id) self.assertEqual(read_elem.Properties.Id, write_elem.Properties.Id) @@ -213,8 +211,6 @@ def test_HDF5ModelPartIO(self): self.assertEqual(read_elem_node.Id, write_elem_node.Id) # Check conditions self.assertEqual(read_model_part.NumberOfConditions(), write_model_part.NumberOfConditions()) - first_cond_id = next(iter(read_model_part.Conditions)).Id - read_model_part.GetCondition(first_cond_id) # Force a sort since order is mixed by openmp. for read_cond, write_cond in zip(read_model_part.Conditions, write_model_part.Conditions): self.assertEqual(read_cond.Id, write_cond.Id) self.assertEqual(read_cond.Properties.Id, write_cond.Properties.Id) From ed74f0dc44bd7911bf215ec0ab20a562371614df Mon Sep 17 00:00:00 2001 From: Suneth Warnakulasuriya Date: Mon, 11 Nov 2024 10:59:55 +0100 Subject: [PATCH 09/13] minor --- .../custom_io/hdf5_connectivities_data.cpp | 4 ++-- .../HDF5Application/custom_io/hdf5_points_data.cpp | 3 +-- kratos/containers/pointer_vector_set.h | 10 ---------- 3 files changed, 3 insertions(+), 14 deletions(-) diff --git a/applications/HDF5Application/custom_io/hdf5_connectivities_data.cpp b/applications/HDF5Application/custom_io/hdf5_connectivities_data.cpp index ef370a396a6..938885b66c6 100644 --- a/applications/HDF5Application/custom_io/hdf5_connectivities_data.cpp +++ b/applications/HDF5Application/custom_io/hdf5_connectivities_data.cpp @@ -78,8 +78,8 @@ void ConnectivitiesData::CreateEntities(NodesContainerType& rNodes, const unsigned geometry_size = r_elem.GetGeometry().size(); KRATOS_ERROR_IF(geometry_size != mConnectivities.size2()) << "Non-matching geometry and connectivity sizes." << std::endl; + rElements.reserve(rElements.size() + num_new_elems); auto mutable_pass = rElements.GetMutablePass(); - mutable_pass.reserve(rElements.size() + num_new_elems); ElementType::NodesArrayType nodes(geometry_size); for (unsigned i = 0; i < num_new_elems; ++i) @@ -108,8 +108,8 @@ void ConnectivitiesData::CreateEntities(NodesContainerType& rNodes, const unsigned geometry_size = r_cond.GetGeometry().size(); KRATOS_ERROR_IF(geometry_size != mConnectivities.size2()) << "Non-matching geometry and connectivity sizes." << std::endl; + rConditions.reserve(rConditions.size() + num_new_conds); auto mutable_pass = rConditions.GetMutablePass(); - mutable_pass.reserve(rConditions.size() + num_new_conds); ConditionType::NodesArrayType nodes(geometry_size); for (unsigned i = 0; i < num_new_conds; ++i) diff --git a/applications/HDF5Application/custom_io/hdf5_points_data.cpp b/applications/HDF5Application/custom_io/hdf5_points_data.cpp index 744bbfaf2ab..399288687e0 100644 --- a/applications/HDF5Application/custom_io/hdf5_points_data.cpp +++ b/applications/HDF5Application/custom_io/hdf5_points_data.cpp @@ -30,9 +30,8 @@ void PointsData::CreateNodes(NodesContainerType& rNodes) { KRATOS_TRY; const unsigned num_new_nodes = mIds.size(); - + rNodes.reserve(rNodes.size() + num_new_nodes); auto mutable_pass = rNodes.GetMutablePass(); - mutable_pass.reserve(rNodes.size() + num_new_nodes); for (unsigned i = 0; i < num_new_nodes; ++i) { const array_1d& r_coord = mCoords[i]; diff --git a/kratos/containers/pointer_vector_set.h b/kratos/containers/pointer_vector_set.h index 725c5d15833..485819a019d 100644 --- a/kratos/containers/pointer_vector_set.h +++ b/kratos/containers/pointer_vector_set.h @@ -170,16 +170,6 @@ class PointerVectorSet final ///@name Public methods ///@{ - void shrink_to_fit() - { - mrContainer.mData.shrink_to_fit(); - } - - void reserve(size_type NewCapacity) - { - mrContainer.mData.reserve(NewCapacity); - } - void push_back(TPointerType pValue) { mrContainer.mData.push_back(pValue); From d2ce1287221d4cc1aeeee6895077606edea9bf1f Mon Sep 17 00:00:00 2001 From: Suneth Warnakulasuriya Date: Mon, 11 Nov 2024 11:30:26 +0100 Subject: [PATCH 10/13] remove std::atomic --- kratos/containers/pointer_vector_set.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kratos/containers/pointer_vector_set.h b/kratos/containers/pointer_vector_set.h index 485819a019d..b5aac54e153 100644 --- a/kratos/containers/pointer_vector_set.h +++ b/kratos/containers/pointer_vector_set.h @@ -1126,7 +1126,7 @@ class PointerVectorSet final /// The maximum buffer size for data storage. size_type mMaxBufferSize; - std::atomic mHasMutablePass = false; + bool mHasMutablePass = false; ///@} ///@name Private Operators From c03c7b84dd5379391c96f06949b031e18430e5f6 Mon Sep 17 00:00:00 2001 From: Suneth Warnakulasuriya Date: Mon, 11 Nov 2024 12:24:34 +0100 Subject: [PATCH 11/13] include parallel_utils header --- kratos/containers/pointer_vector_set.h | 1 + 1 file changed, 1 insertion(+) diff --git a/kratos/containers/pointer_vector_set.h b/kratos/containers/pointer_vector_set.h index b5aac54e153..9c7bcc1901b 100644 --- a/kratos/containers/pointer_vector_set.h +++ b/kratos/containers/pointer_vector_set.h @@ -30,6 +30,7 @@ #include "includes/define.h" #include "includes/serializer.h" #include "containers/key_generator.h" +#include "utilities/parallel_utilities.h" namespace Kratos { From 0ca518b69f52c68ad1516756d10124a976366627 Mon Sep 17 00:00:00 2001 From: Suneth Warnakulasuriya Date: Tue, 12 Nov 2024 17:41:43 +0100 Subject: [PATCH 12/13] fix combine_model_part_modeler --- kratos/modeler/combine_model_part_modeler.cpp | 50 ++++++++----------- 1 file changed, 21 insertions(+), 29 deletions(-) diff --git a/kratos/modeler/combine_model_part_modeler.cpp b/kratos/modeler/combine_model_part_modeler.cpp index 9cb61a76e38..272d1fa63b1 100644 --- a/kratos/modeler/combine_model_part_modeler.cpp +++ b/kratos/modeler/combine_model_part_modeler.cpp @@ -42,7 +42,7 @@ void CombineModelPartModeler::SetupModelPart() KRATOS_TRY; const auto& r_new_model_part_name = mParameters["combined_model_part_name"].GetString(); - auto& r_combined_model_part = mpModel->HasModelPart(r_new_model_part_name) ? + auto& r_combined_model_part = mpModel->HasModelPart(r_new_model_part_name) ? mpModel->GetModelPart(r_new_model_part_name) : mpModel->CreateModelPart(r_new_model_part_name); this->ResetModelPart(r_combined_model_part); @@ -95,7 +95,7 @@ void CombineModelPartModeler::CheckOriginModelPartsAndAssignRoot() for (unsigned int i = 1; i < model_part_list.size(); i++) { ModelPart& r_origin_model_part = mpModel->GetModelPart(model_part_list[i]["origin_model_part"].GetString()); if (r_origin_model_part.GetRootModelPart().FullName() != mpOriginRootModelPart->FullName()) { - KRATOS_ERROR << "The origin model part \"" << r_origin_model_part.FullName() << + KRATOS_ERROR << "The origin model part \"" << r_origin_model_part.FullName() << "\" does not have the same root as the rest of origin model parts: \"" << mpOriginRootModelPart->FullName() << "\".\n"; } @@ -112,12 +112,12 @@ void CombineModelPartModeler::CopyCommonData( ModelPart& rCombinedModelPart) const { KRATOS_TRY; - + if (!rCombinedModelPart.IsSubModelPart()) { rCombinedModelPart.SetNodalSolutionStepVariablesList(mpOriginRootModelPart->pGetNodalSolutionStepVariablesList()); rCombinedModelPart.SetBufferSize( mpOriginRootModelPart->GetBufferSize() ); } - + rCombinedModelPart.SetProcessInfo( mpOriginRootModelPart->pGetProcessInfo() ); rCombinedModelPart.PropertiesArray() = mpOriginRootModelPart->PropertiesArray(); rCombinedModelPart.Tables() = mpOriginRootModelPart->Tables(); @@ -288,66 +288,58 @@ void CombineModelPartModeler::PopulateLocalMesh( ModelPart::NodesContainerType& rDestinationLocalNodes = rDestinationComm.LocalMesh().Nodes(); rDestinationLocalNodes.reserve(rReferenceComm.LocalMesh().NumberOfNodes()); + auto local_nodes_mutable_pass = rDestinationLocalNodes.GetMutablePass(); for (auto p_node = rReferenceComm.LocalMesh().Nodes().ptr_begin(); p_node != rReferenceComm.LocalMesh().Nodes().ptr_end(); ++p_node) { - if (!rDestinationModelPart.GetCommunicator().LocalMesh().HasNode((*p_node)->Id())) { - rDestinationLocalNodes.push_back(*p_node); - } + local_nodes_mutable_pass.push_back(*p_node); } ModelPart::NodesContainerType& rDestinationInterfaceNodes = rDestinationComm.InterfaceMesh().Nodes(); rDestinationInterfaceNodes.reserve(rReferenceComm.InterfaceMesh().NumberOfNodes()); + auto interface_nodes_mutable_pass = rDestinationInterfaceNodes.GetMutablePass(); for (auto p_node = rReferenceComm.InterfaceMesh().Nodes().ptr_begin(); p_node != rReferenceComm.InterfaceMesh().Nodes().ptr_end(); ++p_node) { - if (!rDestinationModelPart.GetCommunicator().InterfaceMesh().HasNode((*p_node)->Id())) { - rDestinationInterfaceNodes.push_back(*p_node); - } + interface_nodes_mutable_pass.push_back(*p_node); } ModelPart::NodesContainerType& rDestinationGhostNodes = rDestinationComm.GhostMesh().Nodes(); rDestinationGhostNodes.reserve(rReferenceComm.GhostMesh().NumberOfNodes()); + auto ghost_nodes_mutable_pass = rDestinationGhostNodes.GetMutablePass(); for (auto p_node = rReferenceComm.GhostMesh().Nodes().ptr_begin(); p_node != rReferenceComm.GhostMesh().Nodes().ptr_end(); ++p_node) { - if (!rDestinationModelPart.GetCommunicator().GhostMesh().HasNode((*p_node)->Id())) { - rDestinationGhostNodes.push_back(*p_node); - } + ghost_nodes_mutable_pass.push_back(*p_node); } ModelPart::ConditionsContainerType& rDestinationLocalConditions = rDestinationComm.LocalMesh().Conditions(); rDestinationLocalConditions.reserve(rDestinationModelPart.NumberOfConditions()); + auto conditions_mutable_pass = rDestinationLocalConditions.GetMutablePass(); for (auto p_cond = rDestinationModelPart.Conditions().ptr_begin(); p_cond != rDestinationModelPart.Conditions().ptr_end(); ++p_cond) { - if (!rDestinationModelPart.GetCommunicator().LocalMesh().HasCondition((*p_cond)->Id())) { - rDestinationLocalConditions.push_back(*p_cond); - } + conditions_mutable_pass.push_back(*p_cond); } ModelPart::ElementsContainerType& rDestinationLocalElements = rDestinationComm.LocalMesh().Elements(); rDestinationLocalElements.reserve(rDestinationModelPart.NumberOfElements()); + auto elements_mutable_pass = rDestinationLocalElements.GetMutablePass(); for (auto p_elem = rDestinationModelPart.Elements().ptr_begin(); p_elem != rDestinationModelPart.Elements().ptr_end(); ++p_elem) { - if (!rDestinationModelPart.GetCommunicator().LocalMesh().HasElement((*p_elem)->Id())) { - rDestinationLocalElements.push_back(*p_elem); - } + elements_mutable_pass.push_back(*p_elem); } } else { ModelPart::NodesContainerType& rDestinationLocalNodes = rDestinationComm.LocalMesh().Nodes(); rDestinationLocalNodes.reserve(rDestinationModelPart.NumberOfNodes()); + auto local_nodes_mutable_pass = rDestinationLocalNodes.GetMutablePass(); for (auto p_node = rDestinationModelPart.Nodes().ptr_begin(); p_node != rDestinationModelPart.Nodes().ptr_end(); ++p_node) { - if (!rDestinationModelPart.GetCommunicator().LocalMesh().HasNode((*p_node)->Id())) { - rDestinationLocalNodes.push_back(*p_node); - } + local_nodes_mutable_pass.push_back(*p_node); } ModelPart::ConditionsContainerType& rDestinationLocalConditions = rDestinationComm.LocalMesh().Conditions(); rDestinationLocalConditions.reserve(rDestinationModelPart.NumberOfConditions()); + auto conditions_mutable_pass = rDestinationLocalConditions.GetMutablePass(); for (auto p_cond = rDestinationModelPart.Conditions().ptr_begin(); p_cond != rDestinationModelPart.Conditions().ptr_end(); ++p_cond) { - if (!rDestinationModelPart.GetCommunicator().LocalMesh().HasCondition((*p_cond)->Id())) { - rDestinationLocalConditions.push_back(*p_cond); - } + conditions_mutable_pass.push_back(*p_cond); } ModelPart::ElementsContainerType& rDestinationLocalElements = rDestinationComm.LocalMesh().Elements(); rDestinationLocalElements.reserve(rDestinationModelPart.NumberOfElements()); + auto elements_mutable_pass = rDestinationLocalElements.GetMutablePass(); for (auto p_elem = rDestinationModelPart.Elements().ptr_begin(); p_elem != rDestinationModelPart.Elements().ptr_end(); ++p_elem) { - if (!rDestinationModelPart.GetCommunicator().LocalMesh().HasElement((*p_elem)->Id())) { - rDestinationLocalElements.push_back(*p_elem); - } + elements_mutable_pass.push_back(*p_elem); } } } @@ -443,7 +435,7 @@ void CombineModelPartModeler::DuplicateSubModelParts( /***********************************************************************************/ /***********************************************************************************/ -const Parameters CombineModelPartModeler::GetDefaultParameters() const +const Parameters CombineModelPartModeler::GetDefaultParameters() const { const Parameters default_parameters = Parameters(R"({ "combined_model_part_name" : "", From 2aee55f5230a7de881e24e4d165fbab6efb5b02c Mon Sep 17 00:00:00 2001 From: Suneth Warnakulasuriya <7856520+sunethwarna@users.noreply.github.com> Date: Thu, 21 Nov 2024 08:10:17 +0100 Subject: [PATCH 13/13] fix further cases which can break PVS --- kratos/containers/pointer_vector_set.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/kratos/containers/pointer_vector_set.h b/kratos/containers/pointer_vector_set.h index 9c7bcc1901b..215e1b0b97d 100644 --- a/kratos/containers/pointer_vector_set.h +++ b/kratos/containers/pointer_vector_set.h @@ -21,7 +21,6 @@ #include #include #include -#include // External includes #include @@ -593,6 +592,7 @@ class PointerVectorSet final { std::swap(mSortedPartSize, rOther.mSortedPartSize); std::swap(mMaxBufferSize, rOther.mMaxBufferSize); + std::swap(mHasMutablePass, rOther.mHasMutablePass); mData.swap(rOther.mData); } @@ -711,8 +711,6 @@ class PointerVectorSet final template void insert(InputIterator first, InputIterator last) { - KRATOS_ERROR_IF(mHasMutablePass) - << "A mutable pass is active. Hence, use of PointerVectorSet::insert(first, last) is prohibited."; // first sorts the input iterators and make the input unique. std::sort(first, last, CompareKey()); auto new_last = std::unique(first, last, EqualKeyTo()); @@ -1150,6 +1148,9 @@ class PointerVectorSet final mData.push_back(GetPointer(it)); } } else { + KRATOS_ERROR_IF(mHasMutablePass) + << "A mutable pass is active. Hence, use of PointerVectorSet::insert(first, last) is prohibited."; + if (KeyOf(GetReference(first)) > KeyOf(*(mData.back()))) { // all are pointing to the end of the vector, hence pushing back. mData.reserve(mData.size() + std::distance(first, last));