29 #ifndef _chemistry_qc_scf_cadf_ordered_shells_h
30 #define _chemistry_qc_scf_cadf_ordered_shells_h
35 #include <Eigen/Dense>
45 typedef std::vector<ShellIndexWithValue> index_list;
46 typedef std::unordered_set<
52 typedef index_list::const_iterator index_iterator;
59 mutable std::mutex insert_mtx_;
60 mutable std::mutex aux_vector_mtx_;
65 bool sort_by_value_ =
true;
70 double aux_value_ = 0.0;
80 : sort_by_value_(sort_by_value)
86 template<
typename Iterable>
88 const Iterable& indices_in,
92 : sort_by_value_(
false),
93 basis_(basis), dfbasis_(dfbasis)
95 std::copy(indices_in.begin(), indices_in.end(), std::back_inserter(indices_));
102 : indices_(
other.indices_),
103 idx_set_(
other.idx_set_),
104 sorted_(
other.sorted_),
105 sort_by_value_(
other.sort_by_value_),
112 void add_to_aux_value(
const double add_val) {
113 std::lock_guard<std::mutex> lg(aux_vector_mtx_);
114 aux_value_ += add_val;
144 double get_aux_value()
const {
156 if(dfbasis) dfbasis_ = dfbasis;
159 void insert(
const ShellData& ish,
double value = 0,
int nbf_in = 0) {
161 assert(basis_ == 0 || ish.basis == basis_);
162 if(basis_ == 0) basis_ = ish.basis;
163 assert(dfbasis_ == 0 || ish.dfbasis == dfbasis_);
164 if(dfbasis_ == 0) dfbasis_ = ish.dfbasis;
166 std::lock_guard<std::mutex> lg(insert_mtx_);
169 const auto& found = idx_set_.find(insert_val);
170 if(found != idx_set_.end()) {
171 const double old_val = found->value;
172 if(value > old_val) found->value = value;
175 idx_set_.insert(insert_val);
180 size_t size()
const {
181 if(sorted_)
return indices_.size();
182 else return idx_set_.size();
185 void set_sort_by_value(
bool new_srt=
true) {
186 if(new_srt != sort_by_value_) {
187 sort_by_value_ = new_srt;
192 double value_for_index(
int index) {
193 if(idx_set_.size() < indices_.size()) {
195 for(
auto&& idx : indices_) {
196 idx_set_.insert(idx);
199 std::lock_guard<std::mutex> lg(insert_mtx_);
201 const auto& found = idx_set_.find(find_val);
202 if(found != idx_set_.end()) {
210 void sort(
bool transfer_idx_set =
true) {
211 std::lock_guard<std::mutex> lg(insert_mtx_);
212 if(transfer_idx_set) {
213 assert(idx_set_.size() >= indices_.size());
215 std::copy(idx_set_.begin(), idx_set_.end(), std::back_inserter(indices_));
218 std::sort(indices_.begin(), indices_.end(),
220 return a.value > b.value or (a.value == b.value and a.index < b.index);
225 std::sort(indices_.begin(), indices_.end(),
227 return a.index < b.index;
234 void acquire_and_sort(
240 std::copy(new_data, new_data + n_new_data, std::back_inserter(indices_));
244 template <
typename ValueIterable>
245 void acquire_and_sort(
246 const ValueIterable& val_iter,
255 for(
auto&& val : val_iter) {
257 indices_.emplace_back(index++, val);
263 void acquire_and_sort(
267 bool sort_by_val =
true
273 for(
size_t idx = 0; idx < n_vals; ++idx) {
274 if(vals[idx] > cutoff) {
275 indices_.emplace_back(idx, vals[idx]);
278 set_sort_by_value(sort_by_val);
282 template<
typename IndexIterable>
283 void acquire_and_sort(
284 const IndexIterable& idxs_in,
285 const double* vals_in,
287 bool sort_by_val =
true
292 typename IndexIterable::iterator idxiter = idxs_in.begin();
294 for(; idxiter != idxs_in.end(); ++idxiter, ++val_off) {
295 if(vals_in[val_off] > cutoff) {
296 indices_.emplace_back(*idxiter, vals_in[val_off]);
299 set_sort_by_value(sort_by_val);
303 template <
typename IndexIterable>
305 intersection_with(
const IndexIterable& other_indices) {
310 std::copy(indices_.begin(), indices_.end(), std::back_inserter(rv.indices_));
314 IndexIterable other_copy;
315 std::copy(other_indices.begin(), other_indices.end(), std::back_inserter(other_copy));
316 std::sort(other_copy.begin(), other_copy.end(), std::less<int>());
319 std::vector<ShellIndexWithValue>
intersect;
320 std::set_intersection(
321 rv.indices_.begin(), rv.indices_.end(),
322 other_copy.begin(), other_copy.end(),
323 std::back_inserter(
intersect), std::less<int>()
330 rv.sort_by_value_ =
true;
336 rv.dfbasis_ = dfbasis_;
360 index_iterator index_begin()
const
363 return indices_.cbegin();
384 index_iterator index_end()
const
387 return indices_.cend();
390 const index_list& unsorted_indices() {
391 std::lock_guard<std::mutex> lg(insert_mtx_);
393 if(indices_.size() != idx_set_.size()) {
395 std::copy(idx_set_.begin(), idx_set_.end(), std::back_inserter(indices_));
423 std::array<OrderedShellList, 5> lists_;
433 inline range_of_shell_blocks<typename OrderedShellList::index_iterator>
436 int requirements=SameCenter,
437 int target_size=DEFAULT_TARGET_BLOCK_SIZE
440 return boost::make_iterator_range(
442 shlist.index_begin(), shlist.index_end(),
443 shlist.basis_, shlist.dfbasis_, requirements, target_size
446 shlist.index_end(), shlist.index_end(),
447 shlist.basis_, shlist.dfbasis_, requirements, target_size