MPQC  3.0.0-alpha
get_ints_impl.h
1 //
2 // get_ints_impl.h
3 //
4 // Copyright (C) 2014 David Hollman
5 //
6 // Author: David Hollman
7 // Maintainer: DSH
8 // Created: Apr 18, 2014
9 //
10 // This file is part of the SC Toolkit.
11 //
12 // The SC Toolkit is free software; you can redistribute it and/or modify
13 // it under the terms of the GNU Library General Public License as published by
14 // the Free Software Foundation; either version 2, or (at your option)
15 // any later version.
16 //
17 // The SC Toolkit is distributed in the hope that it will be useful,
18 // but WITHOUT ANY WARRANTY; without even the implied warranty of
19 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 // GNU Library General Public License for more details.
21 //
22 // You should have received a copy of the GNU Library General Public License
23 // along with the SC Toolkit; see the file COPYING.LIB. If not, write to
24 // the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
25 //
26 // The U.S. Government is granted a limited license as per AL 91-7.
27 //
28 
29 #ifndef _chemistry_qc_scf_get_ints_impl_h
30 #define _chemistry_qc_scf_get_ints_impl_h
31 
32 #include "cadfclhf.h" // for the benefit of the parser
33 
34 namespace sc {
35 
36 template <typename ShellRange>
37 CADFCLHF::TwoCenterIntContainerPtr
38 CADFCLHF::ints_to_eigen(
39  const ShellBlockData<ShellRange>& iblk,
40  const ShellBlockData<ShellRange>& jblk,
41  Ref<TwoBodyTwoCenterInt>& ints,
42  TwoBodyOper::type int_type
43 ){
44  auto rv = std::make_shared<TwoCenterIntContainer>(iblk.nbf, jblk.nbf);
45  int block_offset_i = 0;
46  for(auto ish : shell_range(iblk)) {
47  int block_offset_j = 0;
48  for(auto jsh : shell_range(jblk)) {
49  const auto& ints_ptr = ints_to_eigen(ish, jsh, ints, int_type, ish.basis, jsh.basis);
50  rv->block(block_offset_i, block_offset_j, ish.nbf, jsh.nbf) = *ints_ptr;
51  block_offset_j += jsh.nbf;
52  }
53  block_offset_i += ish.nbf;
54  }
55  return rv;
56 }
57 
58 template <typename ShellRange>
59 CADFCLHF::TwoCenterIntContainerPtr
60 CADFCLHF::ints_to_eigen_threaded(
61  const ShellBlockData<ShellRange>& iblk,
62  const ShellBlockData<ShellRange>& jblk,
63  std::vector<Ref<TwoBodyTwoCenterInt>>& ints_for_thread,
64  TwoBodyOper::type int_type
65 ){
66  auto rv = std::make_shared<TwoCenterIntContainer>(iblk.nbf, jblk.nbf);
67  // non-contiguous form not implemented yet
68  assert(iblk.is_contiguous());
69  assert(jblk.is_contiguous());
70  do_threaded(nthread_, [&](int ithr){
71  ShellData ish, jsh;
72  for(auto&& pair : threaded_shell_block_pair_range(iblk, jblk, ithr, nthread_)){
73  boost::tie(ish, jsh) = pair;
74  const auto& ints_ptr = ints_to_eigen(ish, jsh, ints_for_thread[ithr], int_type, ish.basis, jsh.basis);
75  rv->block(
76  ish.bfoff - iblk.bfoff, jsh.bfoff - jblk.bfoff,
77  ish.nbf, jsh.nbf
78  ) = *ints_ptr;
79  }
80  });
81  return rv;
82 }
83 
84 template <typename ShellRange>
85 Eigen::Map<CADFCLHF::TwoCenterIntContainer>
86 CADFCLHF::ints_to_eigen_map_threaded(
87  const ShellBlockData<ShellRange>& iblk,
88  const ShellBlockData<ShellRange>& jblk,
89  std::vector<Ref<TwoBodyTwoCenterInt>>& ints_for_thread,
90  TwoBodyOper::type int_type,
91  double* buffer
92 ){
93  auto rv = Eigen::Map<TwoCenterIntContainer>(buffer, iblk.nbf, jblk.nbf);
94  // non-contiguous form not implemented yet
95  assert(iblk.is_contiguous());
96  assert(jblk.is_contiguous());
97  do_threaded(nthread_, [&](int ithr){
98  ShellData ish, jsh;
99  for(auto&& pair : threaded_shell_block_pair_range(iblk, jblk, ithr, nthread_)){
100  boost::tie(ish, jsh) = pair;
101  const auto& ints_ptr = ints_to_eigen(ish, jsh, ints_for_thread[ithr], int_type, ish.basis, jsh.basis);
102  rv.block(
103  ish.bfoff - iblk.bfoff, jsh.bfoff - jblk.bfoff,
104  ish.nbf, jsh.nbf
105  ) = *ints_ptr;
106  }
107  });
108  return rv;
109 }
110 
111 
112 template <typename ShellRange>
113 CADFCLHF::ThreeCenterIntContainerPtr
114 CADFCLHF::ints_to_eigen(
115  const ShellBlockData<ShellRange>& iblk,
116  const ShellData& jsh,
117  Ref<TwoBodyTwoCenterInt>& ints,
118  TwoBodyOper::type int_type
119 ){
120  auto rv = std::make_shared<ThreeCenterIntContainer>((const int)iblk.nbf, (const int)jsh.nbf);
121  for(auto ish : shell_range(iblk)) {
122  const auto& ints_ptr = ints_to_eigen(ish, jsh, ints, int_type);
123  rv->block(ish.bfoff - iblk.bfoff, 0, ish.nbf, jsh.nbf) = *ints_ptr;
124  }
125  return rv;
126 }
127 
128 template <typename ShellRange>
129 CADFCLHF::ThreeCenterIntContainerPtr
130 CADFCLHF::ints_to_eigen(
131  const ShellData& ish, const ShellData& jsh,
132  const ShellBlockData<ShellRange>& Xblk,
133  Ref<TwoBodyThreeCenterInt>& ints,
134  TwoBodyOper::type int_type
135 ){
136  auto rv = std::make_shared<ThreeCenterIntContainer>(
137  ish.nbf * jsh.nbf,
138  Xblk.nbf
139  );
140  for(auto Xsh : shell_range(Xblk)) {
141  const auto& ints_ptr = ints_to_eigen(ish, jsh, Xsh, ints, int_type, ish.basis, jsh.basis, Xblk.basis);
142  rv->middleCols(Xsh.bfoff - Xblk.bfoff, Xsh.nbf) = *ints_ptr;
143  }
144  return rv;
145 }
146 
147 template <typename ShellRange1, typename ShellRange2>
148 CADFCLHF::ThreeCenterIntContainerPtr
149 CADFCLHF::ints_to_eigen(
150  const ShellBlockData<ShellRange1>& iblk,
151  const ShellData& jsh,
152  const ShellBlockData<ShellRange2>& Xblk,
153  Ref<TwoBodyThreeCenterInt>& ints,
154  TwoBodyOper::type int_type
155 ){
156  auto rv = std::make_shared<ThreeCenterIntContainer>(
157  iblk.nbf * jsh.nbf,
158  Xblk.nbf
159  );
160  for(auto ish: shell_range(iblk)) {
161  for(auto Xsh : shell_range(Xblk)) {
162  const auto& ints_ptr = ints_to_eigen(ish, jsh, Xsh, ints, int_type, ish.basis, jsh.basis, Xsh.basis);
163  rv->block(
164  (ish.bfoff - iblk.bfoff) * jsh.nbf, Xsh.bfoff - Xblk.bfoff,
165  ish.nbf*jsh.nbf, Xsh.nbf
166  ) = *ints_ptr;
167  }
168  }
169  return rv;
170 }
171 
172 template <typename ShellRange>
173 CADFCLHF::ThreeCenterIntContainerPtr
174 CADFCLHF::ints_to_eigen(
175  const ShellBlockData<ShellRange>& iblk,
176  const ShellData& jsh,
177  const ShellData& Xsh,
178  Ref<TwoBodyThreeCenterInt>& ints,
179  TwoBodyOper::type int_type
180 ){
181  auto rv = std::make_shared<ThreeCenterIntContainer>(
182  iblk.nbf * jsh.nbf, Xsh.nbf
183  );
184  int block_offset = 0;
185  for(auto ish: shell_range(iblk)) {
186  const auto& ints_ptr = ints_to_eigen(ish, jsh, Xsh, ints, int_type, ish.basis, jsh.basis, Xsh.basis);
187  rv->block(
188  block_offset * jsh.nbf, 0,
189  ish.nbf*jsh.nbf, Xsh.nbf
190  ) = *ints_ptr;
191  block_offset += ish.nbf;
192  }
193  return rv;
194 }
195 
196 template <typename ShellRange>
197 Eigen::Map<CADFCLHF::ThreeCenterIntContainer>
198 CADFCLHF::ints_to_eigen_map(
199  const ShellData& ish,
200  const ShellData& jsh,
201  const ShellBlockData<ShellRange>& Xblk,
202  Ref<TwoBodyThreeCenterInt>& ints,
203  TwoBodyOper::type int_type,
204  double* __restrict__ buffer
205 ){
206  //
207  Eigen::Map<ThreeCenterIntContainer> rv(
208  buffer, ish.nbf * jsh.nbf, Xblk.nbf
209  );
210  int block_offset = 0;
211  typedef Eigen::Map<RowMatrix, Eigen::Default, Eigen::OuterStride<>> SkipMap;
212  SkipMap tmp(buffer, 0, 0, Eigen::OuterStride<>(1));
213  for(auto Xsh : shell_range(Xblk)) {
214  new (&tmp) SkipMap(buffer + block_offset,
215  ish.nbf*jsh.nbf, Xsh.nbf, Eigen::OuterStride<>(Xblk.nbf)
216  );
217  ints_to_eigen_map(
218  ish, jsh, Xsh,
219  ints, int_type,
220  tmp
221  );
222  block_offset += Xsh.nbf;
223  }
224  return rv;
225 }
226 
227 template <typename MapType>
228 void
229 CADFCLHF::ints_to_eigen_map(
230  const ShellData& ish,
231  const ShellData& jsh,
232  const ShellData& Xsh,
233  Ref<TwoBodyThreeCenterInt>& ints,
234  TwoBodyOper::type int_type,
235  MapType& out_map
236 ){
237  int block_offset = 0;
238  const Eigen::Map<const RowMatrix> buffmap(ints->buffer(int_type), ish.nbf*jsh.nbf, Xsh.nbf);
239  ints->compute_shell(ish, jsh, Xsh);
240  out_map = buffmap;
241  ints_computed_locally_ += ish.nbf * jsh.nbf * Xsh.nbf;
242 }
243 
244 
245 template <typename ShellRange>
246 Eigen::Map<CADFCLHF::ThreeCenterIntContainer>
247 CADFCLHF::ints_to_eigen_map(
248  const ShellBlockData<ShellRange>& iblk,
249  const ShellData& jsh,
250  const ShellData& Xsh,
251  Ref<TwoBodyThreeCenterInt>& ints,
252  TwoBodyOper::type int_type,
253  double* buffer
254 ){
255  Eigen::Map<ThreeCenterIntContainer> rv(
256  buffer,
257  iblk.nbf * jsh.nbf, Xsh.nbf
258  );
259  int block_offset = 0;
260  for(auto ish : shell_range(iblk)) {
261  ints_to_buffer(
262  ish, jsh, Xsh,
263  ish.nbf, jsh.nbf, Xsh.nbf,
264  ints, int_type,
265  buffer + block_offset * jsh.nbf * Xsh.nbf
266  );
267  block_offset += ish.nbf;
268  }
269  return rv;
270 }
271 
272 template <typename ShellRange1, typename ShellRange2>
273 Eigen::Map<CADFCLHF::ThreeCenterIntContainer>
274 CADFCLHF::ints_to_eigen_map(
275  const ShellBlockData<ShellRange1>& iblk,
276  const ShellData& jsh,
277  const ShellBlockData<ShellRange2>& Xblk,
278  Ref<TwoBodyThreeCenterInt>& ints,
279  TwoBodyOper::type int_type,
280  double* buffer
281 ){
282  Eigen::Map<ThreeCenterIntContainer> rv(
283  buffer,
284  iblk.nbf * jsh.nbf, Xblk.nbf
285  );
286  if(Xblk.nshell == 1) {
287  const auto& Xsh = Xblk.first_shell;
288  int block_offset = 0;
289  for(auto&& ish : shell_range(iblk)) {
290  ints_to_buffer(
291  ish, jsh, Xsh,
292  ish.nbf, jsh.nbf, Xsh.nbf,
293  ints, int_type,
294  buffer + block_offset * jsh.nbf * Xsh.nbf
295  );
296  block_offset += ish.nbf;
297  }
298  return rv;
299  }
300  else {
301  int block_offset = 0;
302  for(auto&& ish : shell_range(iblk)) {
303  int Xblk_offset = 0;
304  for(auto&& Xsh : shell_range(Xblk)) {
305  ints_to_buffer(
306  ish, jsh, Xsh,
307  ish.nbf, jsh.nbf, Xsh.nbf,
308  ints, int_type,
309  buffer + block_offset * jsh.nbf * Xblk.nbf + Xblk_offset,
310  // stride (from first element of one row to first element of next)
311  Xblk.nbf
312  );
313  Xblk_offset += Xsh.nbf;
314  }
315  block_offset += ish.nbf;
316  }
317  return rv;
318  }
319 }
320 
321 template <typename ShellRange>
322 CADFCLHF::ThreeCenterIntContainerPtr
323 CADFCLHF::ints_to_eigen(
324  const ShellData& ish,
325  const ShellBlockData<ShellRange>& jblk,
326  const ShellData& Xsh,
327  Ref<TwoBodyThreeCenterInt>& ints,
328  TwoBodyOper::type int_type
329 ){
330  auto rv = std::make_shared<ThreeCenterIntContainer>(
331  ish.nbf * jblk.nbf, Xsh.nbf
332  );
333  int block_offset = 0;
334  for(auto jsh : shell_range(jblk)) {
335  const auto& ints_ptr = ints_to_eigen(ish, jsh, Xsh, ints, int_type);
336  for(auto mu : function_range(ish)){
337  rv->block(
338  mu.bfoff_in_shell*jblk.nbf + block_offset, 0,
339  jsh.nbf, Xsh.nbf
340  ) = ints_ptr->block(mu.bfoff_in_shell*jsh.nbf, 0, jsh.nbf, Xsh.nbf);
341  }
342  block_offset += jsh.nbf;
343  }
344  return rv;
345 }
346 
347 
348 
349 
350 } // end namespace sc
351 
352 #endif /* _chemistry_qc_scf_get_ints_impl_h */
ShellBlockIterator
Definition: cadf_attic.h:479
ShellData
Definition: cadf_attic.h:100
shell_iterable
Definition: cadf_attic.h:330
sc::TwoBodyOper::type
type
types of known two-body operators
Definition: operator.h:318
function_iterable
Definition: cadf_attic.h:375
sc
Contains all MPQC code up to version 3.
Definition: mpqcin.h:14

Generated at Sun Jan 26 2020 23:23:59 for MPQC 3.0.0-alpha using the documentation package Doxygen 1.8.16.