29 #ifndef _chemistry_qc_scf_cadf_iters_h
30 #define _chemistry_qc_scf_cadf_iters_h
34 #include <type_traits>
38 #include <unordered_set>
39 #include <unordered_map>
43 #include <boost/thread/thread.hpp>
44 #include <boost/functional/hash.hpp>
45 #include <boost/range.hpp>
46 #include <boost/range/irange.hpp>
47 #include <boost/range/join.hpp>
48 #include <boost/range/counting_range.hpp>
49 #include <boost/iterator/iterator_adaptor.hpp>
50 #include <boost/iterator/iterator_facade.hpp>
51 #include <boost/unordered_set.hpp>
54 #include <util/misc/thread_timer.h>
55 #include <util/misc/iterators.h>
56 #include <chemistry/qc/scf/clhf.h>
58 #include "iters_fwd.h"
61 #define DEFAULT_TARGET_BLOCK_SIZE 10000 // functions
62 #define DEFAULT_MAX_AM 7
69 NoMaximumBlockSize = -1001,
73 using int_range = decltype(boost::counting_range(1, 2));
87 operator T*()
const {
return p_; }
88 operator const T*()
const {
return p_; }
95 SameAngularMomentum = 2,
97 } BlockCompositionRequirement;
121 int index = NotAssigned;
125 return index !=
other.index;
130 int center = NotAssigned;
131 int bfoff_in_atom = NotAssigned;
144 int block_offset = NotAssigned
146 block_offset(NotAssigned)
151 template <
typename Iterator>
154 ) :
ShellData(deref.index, deref.basis, deref.dfbasis)
160 int bfoff = NotAssigned;
161 int nbf = NotAssigned;
162 int atom_bfoff = NotAssigned;
163 int atom_shoff = NotAssigned;
164 int atom_nsh = NotAssigned;
165 int atom_nbf = NotAssigned;
166 int shoff_in_atom = NotAssigned;
167 int atom_last_function = NotAssigned;
168 int atom_last_shell = NotAssigned;
169 int last_function = NotAssigned;
170 int am = NotAssigned;
171 int ncontraction = NotAssigned;
175 union {
int atom_dfshoff = NotAssigned;
int atom_obsshoff; };
176 union {
int atom_dfbfoff = NotAssigned;
int atom_obsbfoff; };
177 union {
int atom_dfnbf = NotAssigned;
int atom_obsnbf; };
178 union {
int atom_dfnsh = NotAssigned;
int atom_obsnsh; };
179 union {
int atom_df_last_function = NotAssigned;
int atom_obs_last_function; };
180 union {
int atom_df_last_shell = NotAssigned;
int atom_obs_last_shell; };
184 int block_offset = NotAssigned;
186 operator const int()
const {
187 out_assert(basis, !=, 0);
188 out_assert(index, <, basis->
nshell());
189 out_assert(index, >=, 0);
197 bool is_generally_contracted() {
198 return ncontraction > 1;
210 if(index == NotAssigned || index == basis->nshell())
return;
211 if(index >= basis->nshell() || index < 0)
return;
213 const auto& shell = basis->shell(index);
214 nbf = shell.nfunction();
216 ncontraction = shell.ncontraction();
217 bfoff = basis->shell_to_function(index);
218 center = basis->shell_to_center(index);
219 atom_shoff = basis->shell_on_center(center, 0);
220 atom_bfoff = basis->shell_to_function(atom_shoff);
221 atom_nsh = basis->nshell_on_center(center);
222 atom_nbf = basis->nbasis_on_center(center);
223 shoff_in_atom = index - atom_shoff;
224 bfoff_in_atom = bfoff - atom_bfoff;
225 atom_last_function = atom_bfoff + atom_nbf - 1;
226 last_function = bfoff + nbf - 1;
227 atom_last_shell = atom_shoff + atom_nsh - 1;
233 atom_df_last_function = atom_dfbfoff + atom_dfnbf - 1;
234 atom_df_last_shell = atom_dfshoff + atom_dfnsh - 1;
249 int block_offset = NotAssigned
251 block_offset(block_offset)
256 template <
typename Iterator>
259 ) :
BasisFunctionData(deref.index, deref.basis, deref.dfbasis, deref.block_offset)
266 int shell_index = NotAssigned;
267 int shell_bfoff = NotAssigned;
268 union {
int bfoff_in_shell = NotAssigned;
int off; };
269 int atom_nbf = NotAssigned;
270 int atom_shoff = NotAssigned;
271 int block_offset = NotAssigned;
272 int atom_bfoff = NotAssigned;
273 int bfoff_in_block = NotAssigned;
277 union {
int atom_dfnbf = NotAssigned;
int atom_obsnbf; };
278 union {
int atom_dfshoff = NotAssigned;
int atom_obsshoff; };
279 union {
int atom_dfbfoff = NotAssigned;
int atom_obsbfoff; };
281 operator const int()
const {
return index; }
291 if(index == NotAssigned || index == basis->
nbasis())
return;
293 out_assert(basis, !=, 0);
294 out_assert(index, <, basis->
nbasis());
295 out_assert(index, >=, 0);
300 bfoff_in_shell = index - shell_bfoff;
303 bfoff_in_atom = index - atom_bfoff;
310 if(block_offset != NotAssigned) {
311 bfoff_in_block = index - block_offset;
316 template <
typename DataContainer,
typename Iterator>
319 const Iterator iterator;
321 template<
typename... Args>
325 ) : DataContainer(std::forward<Args>(args)...), iterator(iter)
332 template <
typename DataContainer,
typename Iterator=
int_range::iterator>
334 :
public boost::iterator_adaptor<
335 basis_element_iterator<DataContainer, Iterator>,
338 boost::bidirectional_traversal_tag,
339 BasisElementIteratorDereference<DataContainer, Iterator>
346 typedef boost::iterator_adaptor<
347 self_t, Iterator, boost::use_default, boost::bidirectional_traversal_tag,
350 typedef typename DataContainer::template with_iterator<Iterator> reference;
351 typedef Iterator base_iterator;
358 int block_offset = NotAssigned;
360 friend class boost::iterator_core_access;
362 reference dereference()
const {
363 auto base_spot = super_t::base();
380 int block_offset = NotAssigned
381 ) : basis_element_iterator::iterator_adaptor_(iter),
384 block_offset(block_offset)
387 operator Iterator()
const {
388 return super_t::base();
393 template <
typename DataContainer,
typename Iterator=
int_range::iterator>
395 :
public boost::iterator_adaptor<
396 basis_element_with_value_iterator<DataContainer, Iterator>,
399 boost::bidirectional_traversal_tag,
400 BasisElementIteratorDereference<DataContainer, Iterator>
407 typedef boost::iterator_adaptor<
408 self_t, Iterator, boost::use_default, boost::bidirectional_traversal_tag,
419 int block_offset = NotAssigned
423 block_offset(block_offset)
429 return result_type(basis, dfbasis, super_t::base(), block_offset);
436 int block_offset = NotAssigned;
438 friend class boost::iterator_core_access;
441 auto base_spot = super_t::base();
452 template<
typename Iterator=
int_range::iterator>
455 template<
typename Iterator=
int_range::iterator>
461 template<
typename DataContainer,
typename Iterator=
int_range::iterator>
462 using range_of = decltype(boost::make_iterator_range(
467 template<
typename DataContainer,
typename Iterator=
int_range::iterator>
468 using valued_range_of = decltype(boost::make_iterator_range(
473 template <
typename DataContainer>
474 inline range_of<DataContainer>
480 int block_offset = NotAssigned
483 const int actual_last_index = last_index == NoLastIndex ?
484 DataContainer::max_index(basis) - 1 : last_index;
485 auto base_range = boost::counting_range(first_index, actual_last_index + 1);
486 return boost::make_iterator_range(
493 template <
typename DataContainer>
494 inline range_of<DataContainer>
496 GaussianBasisSet* basis,
500 return basis_element_range<DataContainer>(basis, 0, 0, last_index);
503 template <
typename DataContainer>
504 inline range_of<DataContainer>
506 GaussianBasisSet* basis,
507 GaussianBasisSet* dfbasis = 0,
508 int last_index = NoLastIndex
511 return basis_element_range<DataContainer>(basis, dfbasis, 0, last_index);
514 template <
typename DataContainer>
515 inline range_of<DataContainer>
517 GaussianBasisSet* basis,
522 return basis_element_range<DataContainer>(basis, 0, first_index, last_index);
525 template <
typename Iterable>
526 typename boost::enable_if<
527 boost::is_convertible<typename Iterable::value_type, int>,
528 range_of<ShellData, typename Iterable::iterator>
531 const Iterable& index_iterable,
532 GaussianBasisSet* basis,
533 GaussianBasisSet* dfbasis=0
536 return boost::make_iterator_range(
537 basis_element_iterator<ShellData, typename Iterable::iterator>(basis, dfbasis, index_iterable.begin()),
538 basis_element_iterator<ShellData, typename Iterable::iterator>(basis, dfbasis, index_iterable.end())
542 template <
typename Iterable>
543 typename boost::enable_if<
544 boost::is_convertible<typename Iterable::value_type, int>,
545 range_of<BasisFunctionData, typename Iterable::iterator const>
548 const Iterable& index_iterable,
549 GaussianBasisSet* basis,
550 GaussianBasisSet* dfbasis=0
553 return boost::make_iterator_range(
554 basis_element_iterator<BasisFunctionData, typename Iterable::iterator const>(basis, dfbasis, index_iterable.begin()),
555 basis_element_iterator<BasisFunctionData, typename Iterable::iterator const>(basis, dfbasis, index_iterable.end())
559 template <
typename Iterator>
560 inline range_of<ShellData, Iterator>
562 const ShellData::with_iterator<Iterator>& begin,
563 const ShellData::with_iterator<Iterator>& end
566 return boost::make_iterator_range(
567 basis_element_iterator<ShellData, Iterator>(begin.basis, begin.dfbasis, begin.iterator),
568 basis_element_iterator<ShellData, Iterator>(begin.basis, begin.dfbasis, end.iterator)
572 template <
typename Iterator,
typename Iterator2>
573 inline range_of<ShellData, Iterator>
575 const ShellData::with_iterator<Iterator>& begin,
579 return boost::make_iterator_range(
580 basis_element_iterator<ShellData, Iterator>(begin.basis, begin.dfbasis, begin.iterator),
581 basis_element_iterator<ShellData, Iterator>(begin.basis, begin.dfbasis, Iterator(end))
585 template <
typename Iterator>
586 inline range_of<ShellData, Iterator>
588 const Iterator& begin,
590 GaussianBasisSet* basis,
591 GaussianBasisSet* dfbasis
594 return boost::make_iterator_range(
595 basis_element_iterator<ShellData, Iterator>(basis, dfbasis, begin),
596 basis_element_iterator<ShellData, Iterator>(basis, dfbasis, end)
600 template <
typename Iterator>
601 inline range_of<BasisFunctionData, Iterator>
603 const BasisFunctionData::with_iterator<Iterator>& begin,
604 const BasisFunctionData::with_iterator<Iterator>& end
607 return boost::make_iterator_range(
608 basis_element_iterator<BasisFunctionData, Iterator>(begin.basis, begin.dfbasis, begin.iterator),
609 basis_element_iterator<BasisFunctionData, Iterator>(begin.basis, begin.dfbasis, end.iterator)
613 template <
typename... Args>
614 inline range_of<ShellData>
615 shell_range(GaussianBasisSet* basis, Args&&... args) {
616 return basis_element_range<ShellData>(basis, std::forward<Args>(args)...);
619 template <
typename... Args>
620 inline range_of<BasisFunctionData>
622 return basis_element_range<BasisFunctionData>(basis, std::forward<Args>(args)...);
625 inline range_of<BasisFunctionData>
627 return basis_element_range<BasisFunctionData>(
628 ish.basis, ish.dfbasis,
629 ish.bfoff, ish.last_function
637 template<
typename Range = range_of<ShellData>>
642 typedef Range shell_range_t;
650 bool contiguous_ =
false;
666 sc::shell_range(basis, dfbasis, 0, basis->
nshell() - 1),
670 { contiguous_ =
true; }
675 sc::shell_range(ish.basis, ish.dfbasis, ish, ish),
676 1, ish.nbf, SameCenter|SameAngularMomentum
689 basis(first_shell.basis),
690 dfbasis(first_shell.dfbasis),
691 nshell(nshell), nbf(nbf),
692 restrictions(requirements)
704 sc::shell_range(basis, dfbasis, atom_shoff, atom_shoff + atom_nsh-1),
705 atom_nsh, atom_nbf, SameCenter
709 template <
typename OtherRange>
713 typedef ShellBlockData<decltype(boost::join(this->shell_range,
other.shell_range))> result_t;
714 if(basis !=
other.basis) {
715 throw ProgrammingError(
"Can't combine blocks with different basis sets", __FILE__, __LINE__);
717 if(dfbasis !=
other.dfbasis) {
718 throw ProgrammingError(
"Can't combine blocks with different auxiliary basis sets", __FILE__, __LINE__);
720 int new_reqs = NoRestrictions;
722 (restrictions & SameCenter) and (
other.restrictions & SameCenter)
723 and this->center ==
other.center
725 new_reqs |= SameCenter;
728 (restrictions & SameAngularMomentum) and (
other.restrictions & SameAngularMomentum)
729 and basis->
shell(first_shell).
am() == basis->
shell(first_shell).
am()
731 new_reqs |= SameAngularMomentum;
734 (restrictions & Contiguous) and (
other.restrictions & Contiguous)
735 and (
int)last_shell + 1 == (int)
other.first_shell
737 new_reqs |= Contiguous;
741 boost::join(this->shell_range,
other.shell_range),
752 int center = NotAssigned;
753 int atom_bfoff = NotAssigned;
754 int atom_shoff = NotAssigned;
755 int atom_nsh = NotAssigned;
756 int atom_nbf = NotAssigned;
757 int bfoff_in_atom = NotAssigned;
758 int shoff_in_atom = NotAssigned;
759 int atom_last_function = NotAssigned;
760 int atom_last_shell = NotAssigned;
764 union {
int atom_dfshoff = NotAssigned;
int atom_obsshoff; };
765 union {
int atom_dfbfoff = NotAssigned;
int atom_obsbfoff; };
766 union {
int atom_dfnbf = NotAssigned;
int atom_obsnbf; };
767 union {
int atom_dfnsh = NotAssigned;
int atom_obsdfnsh; };
768 union {
int atom_df_last_function = NotAssigned;
int atom_obs_last_function; };
769 union {
int atom_df_last_shell = NotAssigned;
int atom_obs_last_shell; };
773 bool is_contiguous()
const {
return contiguous_; }
776 template<
typename Range = range_of<ShellData>>
795 static ShellBlockSkeleton<Range> end_skeleton() {
return ShellBlockSkeleton(); }
799 restrictions(shbd.restrictions),
803 ShellBlockSkeleton(Range range,
int nsh,
int nbas,
int restrictions)
805 restrictions(restrictions),
810 template<
typename OtherRange>
816 template<
typename OtherRange>
819 return first_index !=
other.first_index
820 or nshell !=
other.nshell
824 template<
typename OtherRange>
828 const int other_index = (*
other.shell_range.begin()).index;
829 if(my_index < other_index)
return true;
830 else if(my_index > other_index)
return false;
831 else if(nshell <
other.nshell)
return true;
832 else if(nshell >
other.nshell)
return false;
833 else if(nbf <
other.nbf)
return true;
839 template<
typename ShellIterator,
typename ShellRange=range_of<ShellData, ShellIterator>>
841 :
public boost::iterator_facade<
842 shell_block_iterator<ShellIterator, ShellRange>,
843 ShellBlockSkeleton<range_of<ShellData, ShellIterator>>,
844 boost::forward_traversal_tag,
845 ShellBlockData<range_of<ShellData, ShellIterator>>
858 ShellRange all_shells;
862 void init_from_spot(
const decltype(all_shells.begin())& start_spot);
864 bool contiguous_ =
false;
866 friend class boost::iterator_core_access;
872 rv.contiguous_ = contiguous_;
876 template <
typename OtherIterator>
879 return current_skeleton ==
other.current_skeleton;
885 assert(current_skeleton.first_index != NotAssigned);
886 auto&& new_begin = current_skeleton.shell_range.end();
887 auto&& new_end = all_shells.end();
888 all_shells = boost::make_iterator_range(new_begin, new_end);
900 const ShellRange& all_shells_in,
901 int requirements = SameCenter,
902 int target_size = DEFAULT_TARGET_BLOCK_SIZE
903 ) : basis(all_shells_in.begin()->basis),
904 dfbasis(all_shells_in.begin()->dfbasis),
905 restrictions(requirements),
906 target_size(target_size),
907 all_shells(all_shells_in)
913 const ShellIterator& index_begin,
914 const ShellIterator& index_end,
917 int requirements = SameCenter,
918 int target_size = DEFAULT_TARGET_BLOCK_SIZE
921 restrictions(requirements),
922 target_size(target_size),
923 all_shells(
shell_range(index_begin, index_end, basis, dfbasis))
932 int last_index = NoLastIndex,
933 int requirements = SameCenter,
934 int target_size = DEFAULT_TARGET_BLOCK_SIZE
937 restrictions(requirements),
938 target_size(target_size),
940 basis, dfbasis, first_index,
941 last_index == NoLastIndex ? ShellData::max_index(basis) - 1 : last_index
960 const ShellRange& all_shells_in,
961 int requirements = SameCenter,
962 int target_size = DEFAULT_TARGET_BLOCK_SIZE
966 boost::make_iterator_range(
970 requirements, target_size
975 restrictions = restr;
983 template<
typename Iterator=
int_range::iterator,
typename Range=range_of<ShellData, Iterator>>
984 using range_of_shell_blocks = decltype(boost::make_iterator_range(
989 inline range_of_shell_blocks<>
994 int last_index = NoLastIndex,
995 int reqs = SameCenter,
996 int target_size = DEFAULT_TARGET_BLOCK_SIZE
1000 const int actual_last_index = last_index == NoLastIndex ?
1001 basis->
nshell() - 1 : last_index;
1002 return boost::make_iterator_range(
1003 result_t(basis, dfbasis, first_index,
1004 actual_last_index, reqs, target_size
1006 result_t::end_with_last_index(actual_last_index, basis)
1011 inline range_of_shell_blocks<>
1012 shells_blocked_by_atoms(
1013 GaussianBasisSet* basis,
1014 OptionalRefParameter<GaussianBasisSet> dfbasis = 0
1017 return shell_block_range(basis, dfbasis, 0, NoLastIndex, SameCenter, NoMaximumBlockSize);
1020 inline std::ostream&
1023 out <<
"ShellData: {"
1024 <<
"index = " << ish.index <<
", ";
1026 if(ish.center == NotAssigned) out <<
"NotAssigned, ";
1027 else out << ish.center <<
", ";
1029 if(ish.bfoff == NotAssigned) out <<
"NotAssigned, ";
1030 else out << ish.bfoff <<
", ";
1032 if(ish.nbf == NotAssigned) out <<
"NotAssigned, ";
1033 else out << ish.nbf <<
", ";
1034 out <<
"last_function = ";
1035 if(ish.nbf == NotAssigned) out <<
"NotAssigned";
1036 else out << ish.last_function;
1041 template<
typename Range>
1045 auto write_if_assigned = [&](
int val) {
1046 if(val == NotAssigned) out <<
"NotAssigned";
1049 out <<
"\nShellBlockData: {"
1050 <<
"\n nshell: " << blk.nshell
1051 <<
", nbf: " << blk.nbf;
1052 out <<
"\n shoff: ";
1053 write_if_assigned(blk.first_shell.index);
1055 write_if_assigned(blk.bfoff);
1056 out <<
"\n (basis nshell = "
1062 write_if_assigned(blk.center);
1063 out <<
"\n shells:";
1067 out <<
"\n}" << std::endl;
1073 inline range_of<BasisFunctionData>
1074 iter_functions_on_center(
1075 const Ref<GaussianBasisSet>& basis,
1077 const OptionalRefParameter<GaussianBasisSet>& dfbasis = 0
1080 const int shoff = basis->shell_on_center(center, 0);
1081 const int bfoff = basis->shell_to_function(shoff);
1084 bfoff, bfoff + basis->nbasis_on_center(center) - 1
1088 inline range_of<ShellData>
1089 iter_shells_on_center(
1090 GaussianBasisSet* basis,
1092 const OptionalRefParameter<GaussianBasisSet>& dfbasis = 0
1095 const int shoff = basis->shell_on_center(center, 0);
1098 shoff, shoff + basis->nshell_on_center(center) - 1
1102 template<
typename DataContainer,
typename Iterator=
int_range::iterator>
1103 using joined_range_of = decltype(
1105 range_of<DataContainer, Iterator>(),
1106 range_of<DataContainer, Iterator>()
1110 inline joined_range_of<ShellData>
1111 iter_shells_on_centers(
1112 const Ref<GaussianBasisSet>& basis,
1115 const OptionalRefParameter<GaussianBasisSet>& dfbasis = 0
1118 const int shoff1 = basis->shell_on_center(center1, 0);
1119 const int shoff2 = basis->shell_on_center(center2, 0);
1120 if(center1 == center2) {
1124 shoff1, shoff1 + basis->nshell_on_center(center1) - 1
1137 shoff1, shoff1 + basis->nshell_on_center(center1) - 1
1141 shoff2, shoff2 + basis->nshell_on_center(center2) - 1
1147 inline range_of_shell_blocks<>
1148 iter_shell_blocks_on_center(
1149 const Ref<GaussianBasisSet>& basis,
1151 const OptionalRefParameter<GaussianBasisSet>& dfbasis = 0,
1152 int reqs = SameCenter,
1153 int target_size = DEFAULT_TARGET_BLOCK_SIZE
1156 const int shoff = basis->shell_on_center(center, 0);
1160 shoff + basis->nshell_on_center(center) - 1,
1180 int block_offset = NotAssigned
1181 ) :
ShellData(index, basis, dfbasis), value(value)
1192 template <
typename Iterator>
1193 inline valued_range_of<ShellDataWithValue, Iterator>
1199 return boost::make_iterator_range(
1205 template <
typename Iterator,
typename Iterator2>
1206 inline valued_range_of<ShellData, Iterator>
1208 const ShellDataWithValue::with_iterator<Iterator>& begin,
1209 const Iterator2& end
1212 return boost::make_iterator_range(
1213 basis_element_with_value_iterator<ShellDataWithValue, Iterator>(begin.basis, begin.dfbasis, begin.iterator),
1214 basis_element_with_value_iterator<ShellDataWithValue, Iterator>(begin.basis, begin.dfbasis, Iterator(end))
1218 template <
typename Iterator>
1219 inline valued_range_of<ShellData, Iterator>
1221 const basis_element_with_value_iterator<ShellData, Iterator>& begin,
1222 const basis_element_with_value_iterator<ShellData, Iterator>& end
1225 return boost::make_iterator_range(begin, end);
1232 mutable double value;
1237 : index(index), value(0.0)
1241 : index(index), value(value)
1245 return index ==
other.index;
1248 operator int()
const {
1254 template<
typename T>
1261 return std::hash<int>()(v.index);
1268 return a.index == b.index;
1274 template<
typename Iterable>
1275 range_of_shell_blocks<typename Iterable::const_iterator>
1278 int requirements=SameCenter,
1279 int target_size=DEFAULT_TARGET_BLOCK_SIZE
1282 return boost::make_iterator_range(
1284 shlist.begin(), shlist.end(),
1285 basis, dfbasis, requirements, target_size
1288 shlist.end(), shlist.end(),
1289 basis, dfbasis, requirements, target_size
1294 template <
typename ShellRange>
1295 inline range_of_shell_blocks<typename ShellRange::iterator::base_iterator, ShellRange>
1298 int requirements=SameCenter,
1299 int target_size=DEFAULT_TARGET_BLOCK_SIZE
1302 return boost::make_iterator_range(
1303 shell_block_iterator<typename ShellRange::iterator::base_iterator, ShellRange>(
1304 iblk.shell_range, requirements|iblk.restrictions, target_size
1306 shell_block_iterator<typename ShellRange::iterator::base_iterator, ShellRange>::end_of_range(
1307 iblk.shell_range, requirements|iblk.restrictions, target_size
1317 std::unordered_map<int, std::vector<skeleton_t>> lists_for_restrictions_;
1324 template<
typename Iterable>
1326 const Iterable& idxlist,
1329 std::set<int> restriction_sets
1332 for(
auto restrictions : restriction_sets) {
1333 lists_for_restrictions_.emplace(
1334 std::piecewise_construct,
1335 std::forward_as_tuple(restrictions),
1336 std::forward_as_tuple(0)
1338 for(
auto&& iblk :
shell_block_range(idxlist, basis, dfbasis, Contiguous|restrictions, NoMaximumBlockSize)) {
1339 lists_for_restrictions_[restrictions].emplace_back(
1340 shell_range(basis, dfbasis, (
int)iblk.first_shell, (
int)iblk.last_shell),
1341 iblk.nshell, iblk.nbf, restrictions
1348 const std::vector<ShellBlockSkeleton<>>&
1349 list_with_restrictions(
int restrictions)
const {
1350 assert(lists_for_restrictions_.find(restrictions) != lists_for_restrictions_.end());
1351 return lists_for_restrictions_.at(restrictions);
1354 const std::vector<ShellBlockSkeleton<>>&
1355 operator[](
int restrictions)
const {
1356 return list_with_restrictions(restrictions);
1365 #include "cadf_iters_impl.h"