From d8e0de29602a3ef8f69daf63e7c02c98867b47d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Santiago=20Ospina=20De=20Los=20R=C3=ADos?= Date: Mon, 6 Oct 2025 13:04:54 +0200 Subject: [PATCH 1/2] Generalize initial value retrieval of reduction operators The initial value retrieval in the reduction operator is generalized to allow the return from a template argument. The reason behind this is that binary operators in the standard like deprecated (C++17) and removed (C++20) the return type from its traits, meaning that the return type cannot be inferred by purely looking at them. --- .../linalg/ParallelIstlInformation.cpp | 5 ++- .../linalg/ParallelIstlInformation.hpp | 43 +++++++------------ 2 files changed, 18 insertions(+), 30 deletions(-) diff --git a/opm/simulators/linalg/ParallelIstlInformation.cpp b/opm/simulators/linalg/ParallelIstlInformation.cpp index 79ac900e09..910489be5f 100644 --- a/opm/simulators/linalg/ParallelIstlInformation.cpp +++ b/opm/simulators/linalg/ParallelIstlInformation.cpp @@ -130,8 +130,9 @@ computeLocalReduction(const std::tuple& containers, // in this regard in the future. //auto newVal = container.begin(); auto mask = ownerMask.begin(); - auto& value = std::get(values); - value = reduceOperator.getInitialValue(); + using ValueType = std::tuple_element_t >; + ValueType& value = std::get(values); + value = reduceOperator.template getInitialValue(); for (auto endVal = ownerMask.end(); mask != endVal; /*++newVal,*/ ++mask ) { diff --git a/opm/simulators/linalg/ParallelIstlInformation.hpp b/opm/simulators/linalg/ParallelIstlInformation.hpp index 0c0ce15e0b..ca14dbbbfe 100644 --- a/opm/simulators/linalg/ParallelIstlInformation.hpp +++ b/opm/simulators/linalg/ParallelIstlInformation.hpp @@ -156,11 +156,6 @@ private: template struct MaskIDOperator { - // This is a real nice one: numeric limits needs a type without const - // or reference qualifier. Otherwise we get complete nonesense. - typedef typename std::remove_cv< - typename std::remove_reference::type - >::type Result; /// \brief Apply the underlying binary operator according to the mask. /// /// The BinaryOperator will be called with t1, and mask*t2. @@ -181,9 +176,10 @@ private: { return b_; } - Result getInitialValue() + template + T getInitialValue() { - return Result(); + return T{}; } private: BinaryOperator b_; @@ -214,9 +210,10 @@ private: { return std::plus(); } - T getInitialValue() + template, int> = 0> + V getInitialValue() { - return T(); + return T{}; } }; @@ -228,12 +225,6 @@ private: template struct MaskToMinOperator { - // This is a real nice one: numeric limits has to a type without const - // or reference. Otherwise we get complete nonesense. - typedef typename std::remove_reference< - typename std::remove_const::type - >::type Result; - explicit MaskToMinOperator(BinaryOperator b) : b_(b) {} @@ -257,21 +248,22 @@ private: } else { - return getInitialValue(); + return getInitialValue(); } } - Result getInitialValue() + template + T getInitialValue() { //g++-4.4 does not support std::numeric_limits::lowest(); // we rely on IEE 754 for floating point values and use min() // for integral types. - if( std::is_integral::value ) + if( std::is_integral::value ) { - return std::numeric_limits::min(); + return std::numeric_limits::min(); } else { - return -std::numeric_limits::max(); + return -std::numeric_limits::max(); } } /// \brief Get the underlying binary operator. @@ -292,12 +284,6 @@ private: template struct MaskToMaxOperator { - // This is a real nice one: numeric limits has to a type without const - // or reference. Otherwise we get complete nonesense. - typedef typename std::remove_cv< - typename std::remove_reference::type - >::type Result; - explicit MaskToMaxOperator(BinaryOperator b) : b_(b) {} @@ -328,9 +314,10 @@ private: { return b_; } - Result getInitialValue() + template + T getInitialValue() { - return std::numeric_limits::max(); + return std::numeric_limits::max(); } private: BinaryOperator b_; From ee1eb83d270a87dcd5a382e632ea2d1e33b23559 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Santiago=20Ospina=20De=20Los=20R=C3=ADos?= Date: Mon, 6 Oct 2025 20:15:23 +0200 Subject: [PATCH 2/2] Uses lowest() instead of min/max for initial value Replaces the custom handling (post g++-4.4) of minimum and maximum values for integral and floating-point types with std::numeric_limits::lowest(). --- opm/simulators/linalg/ParallelIstlInformation.hpp | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/opm/simulators/linalg/ParallelIstlInformation.hpp b/opm/simulators/linalg/ParallelIstlInformation.hpp index ca14dbbbfe..4037c10af6 100644 --- a/opm/simulators/linalg/ParallelIstlInformation.hpp +++ b/opm/simulators/linalg/ParallelIstlInformation.hpp @@ -254,17 +254,7 @@ private: template T getInitialValue() { - //g++-4.4 does not support std::numeric_limits::lowest(); - // we rely on IEE 754 for floating point values and use min() - // for integral types. - if( std::is_integral::value ) - { - return std::numeric_limits::min(); - } - else - { - return -std::numeric_limits::max(); - } + return std::numeric_limits::lowest(); } /// \brief Get the underlying binary operator. ///