+/********************************************************************
+ * ExclusionsHelper
+ */
+
+class ExclusionsHelper
+{
+ public:
+ static void markExcludedPairs(RefPairList *refPairs, int testIndex,
+ const t_blocka *excls);
+
+ ExclusionsHelper(int refPosCount, int testPosCount);
+
+ void generateExclusions();
+
+ const t_blocka *exclusions() const { return &excls_; }
+
+ gmx::ConstArrayRef<int> refPosIds() const
+ {
+ return gmx::ConstArrayRef<int>(exclusionIds_.begin(),
+ exclusionIds_.begin() + refPosCount_);
+ }
+ gmx::ConstArrayRef<int> testPosIds() const
+ {
+ return gmx::ConstArrayRef<int>(exclusionIds_.begin(),
+ exclusionIds_.begin() + testPosCount_);
+ }
+
+ private:
+ int refPosCount_;
+ int testPosCount_;
+ std::vector<int> exclusionIds_;
+ std::vector<int> exclsIndex_;
+ std::vector<int> exclsAtoms_;
+ t_blocka excls_;
+};
+
+// static
+void ExclusionsHelper::markExcludedPairs(RefPairList *refPairs, int testIndex,
+ const t_blocka *excls)
+{
+ int count = 0;
+ for (int i = excls->index[testIndex]; i < excls->index[testIndex + 1]; ++i)
+ {
+ const int excludedIndex = excls->a[i];
+ NeighborhoodSearchTestData::RefPair searchPair(excludedIndex, 0.0);
+ RefPairList::iterator excludedRefPair
+ = std::lower_bound(refPairs->begin(), refPairs->end(), searchPair);
+ if (excludedRefPair != refPairs->end()
+ && excludedRefPair->refIndex == excludedIndex)
+ {
+ excludedRefPair->bFound = true;
+ excludedRefPair->bExcluded = true;
+ ++count;
+ }
+ }
+}
+
+ExclusionsHelper::ExclusionsHelper(int refPosCount, int testPosCount)
+ : refPosCount_(refPosCount), testPosCount_(testPosCount)
+{
+ // Generate an array of 0, 1, 2, ...
+ // TODO: Make the tests work also with non-trivial exclusion IDs,
+ // and test that.
+ exclusionIds_.resize(std::max(refPosCount, testPosCount), 1);
+ exclusionIds_[0] = 0;
+ std::partial_sum(exclusionIds_.begin(), exclusionIds_.end(),
+ exclusionIds_.begin());
+
+ excls_.nr = 0;
+ excls_.index = NULL;
+ excls_.nra = 0;
+ excls_.a = NULL;
+ excls_.nalloc_index = 0;
+ excls_.nalloc_a = 0;
+}
+
+void ExclusionsHelper::generateExclusions()
+{
+ // TODO: Consider a better set of test data, where the density of the
+ // particles would be higher, or where the exclusions would not be random,
+ // to make a higher percentage of the exclusions to actually be within the
+ // cutoff.
+ exclsIndex_.reserve(testPosCount_ + 1);
+ exclsAtoms_.reserve(testPosCount_ * 20);
+ exclsIndex_.push_back(0);
+ for (int i = 0; i < testPosCount_; ++i)
+ {
+ for (int j = 0; j < 20; ++j)
+ {
+ exclsAtoms_.push_back(i + j*3);
+ }
+ exclsIndex_.push_back(exclsAtoms_.size());
+ }
+ excls_.nr = exclsIndex_.size();
+ excls_.index = &exclsIndex_[0];
+ excls_.nra = exclsAtoms_.size();
+ excls_.a = &exclsAtoms_[0];
+}
+