diff --git a/src/mesh/ItemValueUtils.hpp b/src/mesh/ItemValueUtils.hpp index 6e73e0abeb215107c0bbe542b54d5916479dbc3e..a1039fdbdc8933c27d6ce19ec978894b329520c1 100644 --- a/src/mesh/ItemValueUtils.hpp +++ b/src/mesh/ItemValueUtils.hpp @@ -14,42 +14,18 @@ template <typename DataType, ItemType item_type, typename ConnectivityPtr> std::remove_const_t<DataType> min(const ItemValue<DataType, item_type, ConnectivityPtr>& item_value) { - using ItemValueType = ItemValue<DataType, item_type, ConnectivityPtr>; - using data_type = std::remove_const_t<typename ItemValueType::data_type>; - using index_type = typename ItemValueType::index_type; - - const auto& is_owned = [&](const IConnectivity& connectivity) { - Assert((connectivity.dimension() > 0) and (connectivity.dimension() <= 3), "unexpected connectivity dimension"); - - switch (connectivity.dimension()) { - case 1: { - const auto& connectivity_1d = static_cast<const Connectivity1D&>(connectivity); - return connectivity_1d.isOwned<item_type>(); - break; - } - case 2: { - const auto& connectivity_2d = static_cast<const Connectivity2D&>(connectivity); - return connectivity_2d.isOwned<item_type>(); - break; - } - case 3: { - const auto& connectivity_3d = static_cast<const Connectivity3D&>(connectivity); - return connectivity_3d.isOwned<item_type>(); - break; - } - default: { - throw UnexpectedError("unexpected dimension"); - } - } - }(*item_value.connectivity_ptr()); + using ItemValueType = ItemValue<DataType, item_type, ConnectivityPtr>; + using ItemIsOwnedType = ItemValue<const bool, item_type>; + using data_type = std::remove_const_t<typename ItemValueType::data_type>; + using index_type = typename ItemValueType::index_type; - using IsOwnedType = std::remove_reference_t<decltype(is_owned)>; + static_assert(not std::is_same_v<data_type, bool>, "min cannot be called on boolean arrays"); class ItemValueMin { private: const ItemValueType& m_item_value; - const IsOwnedType& m_is_owned; + const ItemIsOwnedType m_is_owned; public: PUGS_INLINE @@ -86,8 +62,32 @@ min(const ItemValue<DataType, item_type, ConnectivityPtr>& item_value) } PUGS_INLINE - ItemValueMin(const ItemValueType& item_value, const IsOwnedType& is_owned) - : m_item_value(item_value), m_is_owned(is_owned) + ItemValueMin(const ItemValueType& item_value) + : m_item_value(item_value), m_is_owned([&](const IConnectivity& connectivity) { + Assert((connectivity.dimension() > 0) and (connectivity.dimension() <= 3), + "unexpected connectivity dimension"); + + switch (connectivity.dimension()) { + case 1: { + const auto& connectivity_1d = static_cast<const Connectivity1D&>(connectivity); + return connectivity_1d.isOwned<item_type>(); + break; + } + case 2: { + const auto& connectivity_2d = static_cast<const Connectivity2D&>(connectivity); + return connectivity_2d.isOwned<item_type>(); + break; + } + case 3: { + const auto& connectivity_3d = static_cast<const Connectivity3D&>(connectivity); + return connectivity_3d.isOwned<item_type>(); + break; + } + default: { + throw UnexpectedError("unexpected dimension"); + } + } + }(*item_value.connectivity_ptr())) { ; } @@ -96,7 +96,7 @@ min(const ItemValue<DataType, item_type, ConnectivityPtr>& item_value) ~ItemValueMin() = default; }; - const DataType local_min = ItemValueMin{item_value, is_owned}; + const DataType local_min = ItemValueMin{item_value}; return parallel::allReduceMin(local_min); } @@ -104,42 +104,17 @@ template <typename DataType, ItemType item_type, typename ConnectivityPtr> std::remove_const_t<DataType> max(const ItemValue<DataType, item_type, ConnectivityPtr>& item_value) { - using ItemValueType = ItemValue<DataType, item_type, ConnectivityPtr>; - using data_type = std::remove_const_t<typename ItemValueType::data_type>; - using index_type = typename ItemValueType::index_type; - - const auto& is_owned = [&](const IConnectivity& connectivity) { - Assert((connectivity.dimension() > 0) and (connectivity.dimension() <= 3), "unexpected connectivity dimension"); - - switch (connectivity.dimension()) { - case 1: { - const auto& connectivity_1d = static_cast<const Connectivity1D&>(connectivity); - return connectivity_1d.isOwned<item_type>(); - break; - } - case 2: { - const auto& connectivity_2d = static_cast<const Connectivity2D&>(connectivity); - return connectivity_2d.isOwned<item_type>(); - break; - } - case 3: { - const auto& connectivity_3d = static_cast<const Connectivity3D&>(connectivity); - return connectivity_3d.isOwned<item_type>(); - break; - } - default: { - throw UnexpectedError("unexpected dimension"); - } - } - }(*item_value.connectivity_ptr()); - - using IsOwnedType = std::remove_reference_t<decltype(is_owned)>; + using ItemValueType = ItemValue<DataType, item_type, ConnectivityPtr>; + using ItemIsOwnedType = ItemValue<const bool, item_type>; + using data_type = std::remove_const_t<typename ItemValueType::data_type>; + using index_type = typename ItemValueType::index_type; + static_assert(not std::is_same_v<data_type, bool>, "min cannot be called on boolean arrays"); class ItemValueMax { private: const ItemValueType& m_item_value; - const IsOwnedType& m_is_owned; + const ItemIsOwnedType m_is_owned; public: PUGS_INLINE @@ -176,8 +151,32 @@ max(const ItemValue<DataType, item_type, ConnectivityPtr>& item_value) } PUGS_INLINE - ItemValueMax(const ItemValueType& item_value, const IsOwnedType& is_owned) - : m_item_value(item_value), m_is_owned(is_owned) + ItemValueMax(const ItemValueType& item_value) + : m_item_value(item_value), m_is_owned([&](const IConnectivity& connectivity) { + Assert((connectivity.dimension() > 0) and (connectivity.dimension() <= 3), + "unexpected connectivity dimension"); + + switch (connectivity.dimension()) { + case 1: { + const auto& connectivity_1d = static_cast<const Connectivity1D&>(connectivity); + return connectivity_1d.isOwned<item_type>(); + break; + } + case 2: { + const auto& connectivity_2d = static_cast<const Connectivity2D&>(connectivity); + return connectivity_2d.isOwned<item_type>(); + break; + } + case 3: { + const auto& connectivity_3d = static_cast<const Connectivity3D&>(connectivity); + return connectivity_3d.isOwned<item_type>(); + break; + } + default: { + throw UnexpectedError("unexpected dimension"); + } + } + }(*item_value.connectivity_ptr())) { ; } @@ -194,42 +193,18 @@ template <typename DataType, ItemType item_type> std::remove_const_t<DataType> sum(const ItemValue<DataType, item_type>& item_value) { - using ItemValueType = ItemValue<DataType, item_type>; - using data_type = std::remove_const_t<typename ItemValueType::data_type>; - using index_type = typename ItemValueType::index_type; - - const auto& is_owned = [&](const IConnectivity& connectivity) { - Assert((connectivity.dimension() > 0) and (connectivity.dimension() <= 3), "unexpected connectivity dimension"); - - switch (connectivity.dimension()) { - case 1: { - const auto& connectivity_1d = static_cast<const Connectivity1D&>(connectivity); - return connectivity_1d.isOwned<item_type>(); - break; - } - case 2: { - const auto& connectivity_2d = static_cast<const Connectivity2D&>(connectivity); - return connectivity_2d.isOwned<item_type>(); - break; - } - case 3: { - const auto& connectivity_3d = static_cast<const Connectivity3D&>(connectivity); - return connectivity_3d.isOwned<item_type>(); - break; - } - default: { - throw UnexpectedError("unexpected dimension"); - } - } - }(*item_value.connectivity_ptr()); + using ItemValueType = ItemValue<DataType, item_type>; + using ItemIsOwnedType = ItemValue<const bool, item_type>; + using data_type = std::remove_const_t<typename ItemValueType::data_type>; + using index_type = typename ItemValueType::index_type; - using IsOwnedType = std::remove_reference_t<decltype(is_owned)>; + static_assert(not std::is_same_v<data_type, bool>, "sum cannot be called on boolean arrays"); class ItemValueSum { private: const ItemValueType& m_item_value; - const IsOwnedType& m_is_owned; + const ItemIsOwnedType m_is_owned; public: PUGS_INLINE @@ -268,7 +243,32 @@ sum(const ItemValue<DataType, item_type>& item_value) } PUGS_INLINE - ItemValueSum(const ItemValueType& item_value) : m_item_value(item_value), m_is_owned{is_owned(item_value)} + ItemValueSum(const ItemValueType& item_value) + : m_item_value(item_value), m_is_owned([&](const IConnectivity& connectivity) { + Assert((connectivity.dimension() > 0) and (connectivity.dimension() <= 3), + "unexpected connectivity dimension"); + + switch (connectivity.dimension()) { + case 1: { + const auto& connectivity_1d = static_cast<const Connectivity1D&>(connectivity); + return connectivity_1d.isOwned<item_type>(); + break; + } + case 2: { + const auto& connectivity_2d = static_cast<const Connectivity2D&>(connectivity); + return connectivity_2d.isOwned<item_type>(); + break; + } + case 3: { + const auto& connectivity_3d = static_cast<const Connectivity3D&>(connectivity); + return connectivity_3d.isOwned<item_type>(); + break; + } + default: { + throw UnexpectedError("unexpected dimension"); + } + } + }(*item_value.connectivity_ptr())) { ; } @@ -277,7 +277,7 @@ sum(const ItemValue<DataType, item_type>& item_value) ~ItemValueSum() = default; }; - const DataType local_sum = ItemValueSum{item_value, is_owned}; + const DataType local_sum = ItemValueSum{item_value}; return parallel::allReduceSum(local_sum); }