From 4d794b79dc1b1dadfc6bc5da814cd084311d90d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Tue, 21 May 2013 09:29:51 +0200 Subject: [PATCH] Added Selector class. Used to choose element-by-element between two (potentially AD) vectors, depending on signs of elements of a third vector. Simple and not optimized. --- opm/autodiff/AutoDiffHelpers.hpp | 58 ++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/opm/autodiff/AutoDiffHelpers.hpp b/opm/autodiff/AutoDiffHelpers.hpp index 1927ad283..f8e71cb17 100644 --- a/opm/autodiff/AutoDiffHelpers.hpp +++ b/opm/autodiff/AutoDiffHelpers.hpp @@ -305,4 +305,62 @@ spdiag(const AutoDiff::ForwardBlock::V& d) return mat; } + + + + /// Selection. Choose first of two elements if selection basis element is nonnegative. + template + class Selector { + public: + typedef AutoDiff::ForwardBlock ADB; + + Selector(const typename ADB::V& selection_basis) + { + // Define selector structure. + const int n = selection_basis.size(); + // Over-reserving so we do not have to count. + left_elems_.reserve(n); + right_elems_.reserve(n); + for (int i = 0; i < n; ++i) { + if (selection_basis[i] < 0.0) { + right_elems_.push_back(i); + } else { + left_elems_.push_back(i); + } + } + } + + /// Apply selector to ADB quantities. + ADB select(const ADB& x1, const ADB& x2) const + { + if (right_elems_.empty()) { + return x1; + } else if (left_elems_.empty()) { + return x2; + } else { + return superset(subset(x1, left_elems_), left_elems_, x1.size()) + + superset(subset(x2, right_elems_), right_elems_, x2.size()); + } + } + + /// Apply selector to ADB quantities. + typename ADB::V select(const typename ADB::V& x1, const typename ADB::V& x2) const + { + if (right_elems_.empty()) { + return x1; + } else if (left_elems_.empty()) { + return x2; + } else { + return superset(subset(x1, left_elems_), left_elems_, x1.size()) + + superset(subset(x2, right_elems_), right_elems_, x2.size()); + } + } + + private: + std::vector left_elems_; + std::vector right_elems_; + }; + + + #endif // OPM_AUTODIFFHELPERS_HEADER_INCLUDED