29 #ifndef _chemistry_qc_scf_cadf_iters_impl_h
30 #define _chemistry_qc_scf_cadf_iters_impl_h
32 #include <util/misc/scexception.h>
36 template<
typename Range>
38 const ShellBlockSkeleton<Range>& sk
51 GaussianBasisSet* basis,
52 int ish, GaussianBasisSet* dfbasis
58 inline const BasisFunctionData
60 const Ref<GaussianBasisSet>& basis,
61 int ish,
const Ref<GaussianBasisSet>& dfbasis
64 return BasisFunctionData(ish, basis, dfbasis);
69 template<
typename Range>
73 bfoff = first_shell.bfoff;
74 last_function = last_shell.last_function;
75 if(restrictions & SameCenter) {
76 center = first_shell.center;
77 atom_bfoff = first_shell.atom_bfoff;
78 atom_shoff = first_shell.atom_shoff;
79 atom_nsh = first_shell.atom_nsh;
80 atom_nbf = first_shell.atom_nbf;
81 bfoff_in_atom = first_shell.bfoff_in_atom;
82 shoff_in_atom = first_shell.shoff_in_atom;
83 atom_last_function = last_shell.atom_last_function;
84 atom_last_shell = last_shell.atom_last_function;
86 atom_dfshoff = first_shell.atom_dfshoff;
87 atom_dfbfoff = first_shell.atom_dfbfoff;
88 atom_dfnbf = first_shell.atom_dfnbf;
89 atom_dfnsh = first_shell.atom_dfnsh;
90 atom_df_last_function = last_shell.atom_df_last_function;
91 atom_df_last_shell = last_shell.atom_df_last_shell;
96 template<
typename ShellIterator,
typename ShellRange>
98 shell_block_iterator<ShellIterator, ShellRange>::init_from_spot(
99 const decltype(all_shells.begin())& start_spot
103 if(start_spot == all_shells.end()){
104 const auto& begin = all_shells.begin();
105 const auto& end = all_shells.end();
106 current_skeleton = ShellBlockSkeleton<ShellRange>::end_skeleton();
110 const auto& first_shell = *start_spot;
111 int first_center = first_shell.center;
112 auto first_am = basis->shell(first_shell).am();
114 int block_nshell = 0;
115 int prev_index = first_shell.index - 1;
116 auto ish_iter = start_spot;
118 for(; ish_iter != all_shells.end(); ++ish_iter){
119 auto ish = *ish_iter;
120 out_assert(ish.center, !=, NotAssigned);
123 ((restrictions & SameCenter) and ish.center != first_center)
126 ((restrictions & SameAngularMomentum) and
127 basis->shell(ish).am() != first_am)
130 (target_size != NoMaximumBlockSize and block_nbf >= target_size)
133 ((restrictions & Contiguous) and ish.index != prev_index + 1)
140 block_nbf += ish.nbf;
141 if(ish.index != prev_index + 1){
144 prev_index = ish.index;
148 current_skeleton = ShellBlockSkeleton<ShellRange>(
150 block_nshell, block_nbf, restrictions
155 template<
typename ShellIterator,
typename ShellRange>
157 shell_block_iterator<ShellIterator, ShellRange>::init()
159 init_from_spot(all_shells.begin());
165 template<
typename Range>
169 ) ->
const decltype(block.shell_range)&
171 return block.shell_range;
174 template<
typename Range>
177 const ShellBlockSkeleton<Range>& skeleton
180 return skeleton.shell_range;
183 template<
typename ShellRange>
184 inline range_of<BasisFunctionData>
189 throw FeatureNotImplemented(
"function iteration over arbitrary shell block ranges", __FILE__, __LINE__);
193 inline range_of<BasisFunctionData>
198 return function_range(block.basis, block.dfbasis, block.bfoff, block.last_function, block.bfoff);
203 template <
typename ShellRange1,
typename ShellRange2>
204 auto threaded_shell_block_pair_range(
208 ) -> decltype(thread_over_range(product_range(iblk.shell_range, jblk.shell_range), ithr, nthr))
210 return thread_over_range(
211 product_range(iblk.shell_range, jblk.shell_range),