MPQC  3.0.0-alpha
sr_r12intermediates_util.h
1 //
2 // sr_r12intermediates_util.h
3 //
4 // Copyright (C) 2013 Edward Valeev
5 //
6 // Author: Edward Valeev <evaleev@vt.edu>
7 // Maintainer: EV
8 //
9 // This file is part of the SC Toolkit.
10 //
11 // The SC Toolkit is free software; you can redistribute it and/or modify
12 // it under the terms of the GNU Library General Public License as published by
13 // the Free Software Foundation; either version 2, or (at your option)
14 // any later version.
15 //
16 // The SC Toolkit is distributed in the hope that it will be useful,
17 // but WITHOUT ANY WARRANTY; without even the implied warranty of
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 // GNU Library General Public License for more details.
20 //
21 // You should have received a copy of the GNU Library General Public License
22 // along with the SC Toolkit; see the file COPYING.LIB. If not, write to
23 // the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
24 //
25 // The U.S. Government is granted a limited license as per AL 91-7.
26 //
27 
28 // this should not be included directly, will be included by sr_r12intermediates.h
29 
30 #ifndef _mpqc_src_lib_chemistry_qc_mbptr12_srr12intermediatesutil_h
31 #define _mpqc_src_lib_chemistry_qc_mbptr12_srr12intermediatesutil_h
32 
33 #include <algorithm>
34 #include <numeric>
35 #include <TiledArray/bitset.h>
36 
37 namespace sc {
38 
39  template <typename T>
40  std::shared_ptr<typename SingleReference_R12Intermediates<T>::TArray22>
41  SingleReference_R12Intermediates<T>::ab_O_cd(const std::string& key,
42  const int te_type) {
43 
44  typedef typename TArray22::value_type value_type;
45 
46  Ref<TwoBodyMOIntsTransform> tform = r12world_->world()->moints_runtime4()->get(key);
47  tform->compute();
48  Ref<DistArray4> darray4 = tform->ints_distarray4();
49  darray4->activate();
50 
51  // this only works if all nodes can read integrals
52  std::vector<int> tasks_with_access;
53  const int ntasks_with_access = darray4->tasks_with_access(tasks_with_access);
54  MPQC_ASSERT(ntasks_with_access == world_.nproc());
55  MPQC_ASSERT(ntasks_with_access == r12world_->world()->msg()->n());
56 
57  const size_t n1 = darray4->ni();
58  const size_t n2 = darray4->nj();
59  const size_t n3 = darray4->nx();
60  const size_t n4 = darray4->ny();
61 
62  // make tiled ranges for occupied indices
63  // N.B. using little trickery using partial sum to create tilesize=1 range
64  std::vector<size_t> i1_hashmarks(n1+1, 1);
65  i1_hashmarks[0] = 0;
66  std::partial_sum(i1_hashmarks.begin(), i1_hashmarks.end(), i1_hashmarks.begin());
67  std::vector<size_t> i2_hashmarks(n2+1, 1);
68  i2_hashmarks[0] = 0;
69  std::partial_sum(i2_hashmarks.begin(), i2_hashmarks.end(), i2_hashmarks.begin());
70 
71  std::vector<TA::TiledRange1> hashmarks;
72  hashmarks.push_back(TiledArray::TiledRange1(i1_hashmarks.begin(), i1_hashmarks.end()));
73  hashmarks.push_back(TiledArray::TiledRange1(i2_hashmarks.begin(), i2_hashmarks.end()));
74 
75  TiledArray::TiledRange i1i2_trange(hashmarks.begin(), hashmarks.end());
76 
77  // make an empty tensor now
78  std::shared_ptr<TArray22> i1i2_g_p1p2(new TArray22(world_, i1i2_trange));
79 
80  // make ordinary ranges needed to make p1p2 tiles
81  std::vector<size_t> p1p2_start(2, 0);
82  std::vector<size_t> p1p2_finish(2); p1p2_finish[0] = n3; p1p2_finish[1] = n4;
83  TA::Range p1p2_range(p1p2_start, p1p2_finish);
84 
85  { // load all local tiles
86 
87  std::vector<double> p1p2_block(n3 * n4);
88 
89  std::vector<size_t> i1i2(2, 0);
90  for(i1i2[0] = 0; i1i2[0]<n1; ++i1i2[0]) {
91  for(i1i2[1] = 0; i1i2[1]<n2; ++i1i2[1]) {
92  if (i1i2_g_p1p2->is_local(i1i2)) {
93 
94  darray4->retrieve_pair_block(i1i2[0], i1i2[1], te_type, &p1p2_block[0]);
95 
96  madness::Future < value_type >
97  tile((value_type(i1i2_g_p1p2->trange().make_tile_range(i1i2),
98  (typename value_type::value_type(p1p2_range,
99  &p1p2_block[0])
100  )
101  )
102  ));
103 
104  // Insert the tile into the array
105  i1i2_g_p1p2->set(i1i2, tile);
106 
107  darray4->release_pair_block(i1i2[0], i1i2[1], te_type);
108 
109  }
110  }
111  }
112 
113  }
114 
115  return i1i2_g_p1p2;
116  }
117 
118  template <typename T>
120  SingleReference_R12Intermediates<T>::_(const std::string& key) {
121  auto v = tarray22_registry_.find(key);
122  if (tarray22_registry_.find(key) == tarray22_registry_.end()) {
123  ParsedTwoBodyFourCenterIntKey pkey(key);
124 
126  std::string operset_label;
127  const unsigned int oper_idx = 0;
128  if (pkey.oper() == "g") {
129  operset_label = "ERI";
130  }
131  else if (pkey.oper() == "gr") {
132  operset_label = "R12_m1_G12[0]";
133  }
134  else if (pkey.oper() == "r") {
135  operset_label = "R12_0_G12[0]";
136  }
137  else if (pkey.oper() == "r2") {
138  operset_label = "R12_0_G12[0,0]";
139  }
140  else if (pkey.oper() == "rTr") {
141  operset_label = "G12_T1_G12[0,0]";
142  }
143  else
144  throw ProgrammingError("SingleReference_R12Intermediates<T>::_ : invalid operator key",__FILE__,__LINE__);
145 
146  // canonicalize indices, may compute spaces if needed
147  auto bra1 = to_space(pkey.bra1());
148  auto bra2 = to_space(pkey.bra2());
149  auto ket1 = to_space(pkey.ket1());
150  auto ket2 = to_space(pkey.ket2());
151 
152  std::string tform_key = ParsedTwoBodyFourCenterIntKey::key(bra1, bra2, ket1, ket2,
153  operset_label, "");
154 
155  tarray22_registry_[key] = ab_O_cd(tform_key, oper_idx);
156  v = tarray22_registry_.find(key);
157  }
158 
159  return *(v->second);
160  }
161 
162  template <typename T>
165 
166  auto v = tarray4_registry_.find(key);
167  if (tarray4_registry_.find(key) == tarray4_registry_.end()) {
168 
170 
172  std::string operset_label;
173  bool rdm2 = false;
174  bool t2 = false;
175  bool l2 = false;
176  const unsigned int oper_idx = 0;
177  if (pkey.oper() == "g") {
178  operset_label = "ERI";
179  }
180  else if (pkey.oper() == "gr") {
181  operset_label = "R12_m1_G12[0]";
182  }
183  else if (pkey.oper() == "r") {
184  operset_label = "R12_0_G12[0]";
185  }
186  else if (pkey.oper() == "r2") {
187  operset_label = "R12_0_G12[0,0]";
188  }
189  else if (pkey.oper() == "rTr") {
190  operset_label = "G12_T1_G12[0,0]";
191  }
192  else if (pkey.oper() == "gamma") {
193  rdm2 = true;
194  }
195  else if (pkey.oper() == "T2") {
196  t2 = true;
197  }
198  else if (pkey.oper() == "L2") {
199  l2 = true;
200  }
201  else
202  throw ProgrammingError("SingleReference_R12Intermediates<T>::ijxy : invalid operator key",__FILE__,__LINE__);
203 
204  // canonicalize indices, may compute spaces if needed
205  auto bra1 = to_space(pkey.bra1());
206  auto bra2 = to_space(pkey.bra2());
207  auto ket1 = to_space(pkey.ket1());
208  auto ket2 = to_space(pkey.ket2());
209  auto oreg = r12world_->world()->tfactory()->orbital_registry();
210 
211  Ref<DistArray4> darray4;
212  if (rdm2) { // rdm2
213  if (rdm2_.null())
214  throw ProgrammingError("SingleReference_R12Intermediates<T>::ijxy: asked for rdm2, but it had not been given");
215  // if requested spaces don't match exactly, make a new DistArray4
216  auto bra1_space = oreg->value(bra1);
217  auto bra2_space = oreg->value(bra2);
218  auto ket1_space = oreg->value(ket1);
219  auto ket2_space = oreg->value(ket2);
220  const auto& rdm_space = rdm2_->orbs();
221 
222  darray4 = rdm2_->da4();
223  if (not (*bra1_space == *rdm_space &&
224  *bra2_space == *rdm_space &&
225  *ket1_space == *rdm_space &&
226  *ket2_space == *rdm_space )) {
227  DistArray4Dimensions dims(1, bra1_space->rank(), bra2_space->rank(), ket1_space->rank(), ket2_space->rank());
228  Ref<DistArray4> darray4_mapped = darray4->clone(dims);
229  std::vector<int> bra1_map = sc::map(*rdm_space, *bra1_space, true);
230  std::vector<int> bra2_map = sc::map(*rdm_space, *bra2_space, true);
231  std::vector<int> ket1_map = sc::map(*rdm_space, *ket1_space, true);
232  std::vector<int> ket2_map = sc::map(*rdm_space, *ket2_space, true);
233 
234  std::vector<double> buf(rdm_space->rank() * rdm_space->rank());
235  std::vector<double> map_buf(ket1_space->rank() * ket2_space->rank());
236 
237  darray4->activate();
238  darray4_mapped->activate();
239 
240  for(int b1=0; b1<bra1_space->rank(); ++b1) {
241  const int bb1 = bra1_map[b1];
242  for(int b2=0; b2<bra2_space->rank(); ++b2) {
243  const int bb2 = bra2_map[b2];
244 
245  darray4->retrieve_pair_block(bb1, bb2, 0, &buf[0]);
246 
247  const int nk1 = ket1_space->rank();
248  const int nk2 = ket2_space->rank();
249  for(int k1=0, k12=0; k1<nk1; ++k1) {
250  const int kk1 = ket1_map[k1];
251  const int kk1_offset = kk1 * rdm_space->rank();
252  for(int k2=0; k2<nk2; ++k2, ++k12) {
253  const int kk2 = ket2_map[k2];
254  map_buf[k12] = buf[kk1_offset + kk2];
255  }
256  }
257 
258  darray4_mapped->store_pair_block(b1, b2, 0, &map_buf[0]);
259  darray4->release_pair_block(bb1, bb2, 0);
260  }
261  }
262  if (darray4->data_persistent()) darray4->deactivate();
263  if (darray4_mapped->data_persistent()) darray4_mapped->deactivate();
264 
265  darray4 = darray4_mapped;
266  }
267  }
268  else if (t2) {
269  if (t2_[AlphaBeta].null())
270  throw ProgrammingError("SingleReference_R12Intermediates<T>::ijxy: asked for T2, but it had not been given");
271 
272 // auto oreg = r12world_->world()->tfactory()->orbital_registry();
273 // MPQC_ASSERT(oreg->value(bra1) == r12world_->refwfn()->occ_act(Alpha));
274 // MPQC_ASSERT(oreg->value(bra2) == r12world_->refwfn()->occ_act(Beta));
275 // MPQC_ASSERT(oreg->value(ket1) == r12world_->refwfn()->uocc_act(Alpha));
276 // MPQC_ASSERT(oreg->value(ket2) == r12world_->refwfn()->uocc_act(Beta));
277  darray4 = t2_[AlphaBeta];
278  }
279  else if (l2) {
280  if (l2_[AlphaBeta].null())
281  throw ProgrammingError("SingleReference_R12Intermediates<T>::ijxy: asked for L2, but it had not been given");
282 
283  darray4 = l2_[AlphaBeta];
284  }
285  else { // not rdm2 nor t2 nor l2
286  std::string tform_key = ParsedTwoBodyFourCenterIntKey::key(bra1, bra2, ket1, ket2,
287  operset_label, "");
288 
289  Ref<TwoBodyMOIntsTransform> tform = r12world_->world()->moints_runtime4()->get(tform_key);
290  tform->compute();
291  darray4 = tform->ints_distarray4();
292  }
293 
294  darray4->activate();
295 
296  const size_t n1 = darray4->ni();
297  const size_t n2 = darray4->nj();
298  const size_t n3 = darray4->nx();
299  const size_t n4 = darray4->ny();
300 
301  // this only works if all nodes can read integrals
302  std::vector<int> tasks_with_access;
303  const int ntasks_with_access = darray4->tasks_with_access(tasks_with_access);
304  MPQC_ASSERT(ntasks_with_access == world_.nproc());
305  MPQC_ASSERT(ntasks_with_access == r12world_->world()->msg()->n());
306 
307  // make tiled ranges
308  std::vector<size_t> i_hashmarks = space_hashmarks(bra1);
309  std::vector<size_t> j_hashmarks = space_hashmarks(bra2);
310  std::vector<size_t> x_hashmarks = space_hashmarks(ket1);
311  std::vector<size_t> y_hashmarks = space_hashmarks(ket2);
312 
313  std::vector<TA::TiledRange1> hashmarks;
314  hashmarks.push_back(TiledArray::TiledRange1(i_hashmarks.begin(), i_hashmarks.end()));
315  hashmarks.push_back(TiledArray::TiledRange1(j_hashmarks.begin(), j_hashmarks.end()));
316  hashmarks.push_back(TiledArray::TiledRange1(x_hashmarks.begin(), x_hashmarks.end()));
317  hashmarks.push_back(TiledArray::TiledRange1(y_hashmarks.begin(), y_hashmarks.end()));
318  TiledArray::TiledRange ijxy_trange(hashmarks.begin(), hashmarks.end());
319 
320  std::shared_ptr<TArray4d> result(new TArray4d(world_, ijxy_trange) );
321  // construct local tiles
322  for(auto t=ijxy_trange.tiles_range().begin();
323  t!=ijxy_trange.tiles_range().end();
324  ++t)
325  if (result->is_local(*t))
326  {
327  std::array<std::size_t, 4> index; std::copy(t->begin(), t->end(), index.begin());
328  madness::Future < typename TArray4d::value_type >
329  tile((DA4_Tile<T>(result.get(), index, darray4, oper_idx)
330  ));
331 
332  // Insert the tile into the array
333  result->set(*t, tile);
334  }
335 
336  tarray4_registry_[key] = result;
337  v = tarray4_registry_.find(key);
338  }
339 
340  return *(v->second);
341  }
342 
343  template <typename T>
346 
347  auto v = tarray22d_registry_.find(key);
348  if (tarray22d_registry_.find(key) == tarray22d_registry_.end()) {
349 
351 
353  std::string operset_label;
354  const unsigned int oper_idx = 0;
355  if (pkey.oper() == "g") {
356  operset_label = "ERI";
357  }
358  else if (pkey.oper() == "gr") {
359  operset_label = "R12_m1_G12[0]";
360  }
361  else if (pkey.oper() == "r") {
362  operset_label = "R12_0_G12[0]";
363  }
364  else if (pkey.oper() == "r2") {
365  operset_label = "R12_0_G12[0,0]";
366  }
367  else if (pkey.oper() == "rTr") {
368  operset_label = "G12_T1_G12[0,0]";
369  }
370  else
371  throw ProgrammingError("SingleReference_R12Intermediates<T>::ij_xy : invalid operator key",__FILE__,__LINE__);
372 
373  // canonicalize indices, may compute spaces if needed
374  auto bra1 = to_space(pkey.bra1());
375  auto bra2 = to_space(pkey.bra2());
376  auto ket1 = to_space(pkey.ket1());
377  auto ket2 = to_space(pkey.ket2());
378 
379  std::string tform_key = ParsedTwoBodyFourCenterIntKey::key(bra1, bra2, ket1, ket2,
380  operset_label, "");
381 
382  Ref<TwoBodyMOIntsTransform> tform = r12world_->world()->moints_runtime4()->get(tform_key);
383  tform->compute();
384  Ref<DistArray4> darray4 = tform->ints_distarray4();
385  darray4->activate();
386 
387  const size_t n1 = darray4->ni();
388  const size_t n2 = darray4->nj();
389  const size_t n3 = darray4->nx();
390  const size_t n4 = darray4->ny();
391 
392  // this only works if all nodes can read integrals
393  std::vector<int> tasks_with_access;
394  const int ntasks_with_access = darray4->tasks_with_access(tasks_with_access);
395  MPQC_ASSERT(ntasks_with_access == world_.nproc());
396  MPQC_ASSERT(ntasks_with_access == r12world_->world()->msg()->n());
397 
398  // make tiled ranges
399  // N.B. using little trickery using partial sum to create tilesize=1 range
400  std::vector<size_t> i_hashmarks(n1+1, 1);
401  i_hashmarks[0] = 0;
402  std::partial_sum(i_hashmarks.begin(), i_hashmarks.end(), i_hashmarks.begin());
403  std::vector<size_t> j_hashmarks(n2+1, 1);
404  j_hashmarks[0] = 0;
405  std::partial_sum(j_hashmarks.begin(), j_hashmarks.end(), j_hashmarks.begin());
406 
407  std::vector<TA::TiledRange1> hashmarks;
408  hashmarks.push_back(TiledArray::TiledRange1(i_hashmarks.begin(), i_hashmarks.end()));
409  hashmarks.push_back(TiledArray::TiledRange1(j_hashmarks.begin(), j_hashmarks.end()));
410  TiledArray::TiledRange ij_trange(hashmarks.begin(), hashmarks.end());
411 
412  std::shared_ptr<TArray22d> result(new TArray22d(world_, ij_trange) );
413  // construct local tiles
414  for(auto t=ij_trange.tiles_range().begin();
415  t!=ij_trange.tiles_range().end();
416  ++t)
417  if (result->is_local(*t))
418  {
419  std::array<std::size_t, 2> index; std::copy(t->begin(), t->end(), index.begin());
420  madness::Future < typename TArray22d::value_type >
421  tile((DA4_Tile34<T>(result.get(), index, darray4, oper_idx)
422  ));
423 
424  // Insert the tile into the array
425  result->set(*t, tile);
426  }
427 
428  tarray22d_registry_[key] = result;
429  v = tarray22d_registry_.find(key);
430  }
431 
432  return *(v->second);
433  }
434 
435  template <typename T>
437  SingleReference_R12Intermediates<T>::xy(const std::string& key) {
438 
439  auto v = tarray2_registry_.find(key);
440  if (v == tarray2_registry_.end()) {
441 
442  ParsedOneBodyIntKey pkey(key);
443 
444  // canonicalize indices, may compute spaces if needed
445  auto bra_id = to_space(pkey.bra());
446  auto ket_id = to_space(pkey.ket());
447 
448  auto oreg = r12world_->world()->tfactory()->orbital_registry();
449  auto freg = r12world_->world()->fockbuild_runtime();
450  auto bra = oreg->value(bra_id);
451  auto ket = oreg->value(ket_id);
452  auto nbra = bra->rank();
453  auto nket = ket->rank();
454 
455  // grab the matrix
456  RefSCMatrix operator_matrix;
457  if (pkey.oper() == "J")
458  operator_matrix = freg->get(ParsedOneBodyIntKey::key(bra_id, ket_id, "J"));
459  else if (pkey.oper() == "K")
460  operator_matrix = freg->get(ParsedOneBodyIntKey::key(bra_id, ket_id, "K"));
461  else if (pkey.oper() == "F")
462  operator_matrix = freg->get(ParsedOneBodyIntKey::key(bra_id, ket_id, "F"));
463  else if (pkey.oper() == "h")
464  operator_matrix = freg->get(ParsedOneBodyIntKey::key(bra_id, ket_id, "H"));
465  else if (pkey.oper() == "hJ")
466  operator_matrix = freg->get(ParsedOneBodyIntKey::key(bra_id, ket_id, "H"))
467  + freg->get(ParsedOneBodyIntKey::key(bra_id, ket_id, "J"));
468  else if (pkey.oper().find("mu_") == 0 || pkey.oper().find("q_") == 0 ||
469  pkey.oper().find("dphi_") == 0 || pkey.oper().find("ddphi_") == 0) {
470  operator_matrix = freg->get(ParsedOneBodyIntKey::key(bra_id, ket_id, pkey.oper()));
471  }
472  else if (pkey.oper() == "gamma")
473  operator_matrix = this->rdm1(bra, ket);
474  else if (pkey.oper() == "I") {
475  operator_matrix = bra->coefs()->kit()->matrix(bra->coefs().coldim(), ket->coefs().coldim());
476  if (bra == ket) {
477  operator_matrix.assign(0.0);
478  for(int i=0; i<nbra; ++i)
479  operator_matrix.set_element(i,i,1.0);
480  }
481  else {
482  operator_matrix = sc::overlap(*bra,*ket,operator_matrix->kit());
483  }
484  }
485  else if (pkey.oper() == "T1") {
486  if (ket_id == "a") { // if given t1_ explicitly (CC), make sure its size matches
487  if (t1_) {
488  if (t1_.ncol() != oreg->value(ket_id)->rank())
489  throw ProgrammingError("SingleReference_R12Intermediates::xy() -- T1.ncol() != nvir_act",
490  __FILE__, __LINE__);
491  operator_matrix = t1_;
492  }
493  else if (t1_cabs_) { // if t1_cabs given, this means extract the occ_act x vir_act block
494  if (t1_cabs_.ncol() == oreg->value("a'")->rank()) // doesn't make sense if T1 only include CABS
495  throw ProgrammingError("SingleReference_R12Intermediates::xy() -- asked for <i|T1|a> but T1_cabs does not include conv. virtuals",
496  __FILE__, __LINE__);
497  Ref<OrbitalSpace> vir_act = oreg->value("a");
498  Ref<OrbitalSpace> allvir = oreg->value("A'"); // should exist since t1_cabs_ spans more than just CABS
499  MPQC_ASSERT(t1_cabs_.ncol() == allvir->rank()); // this should be the only other possibility
500  RefSCMatrix t1_subblock = t1_cabs_.kit()->matrix(t1_cabs_.rowdim(),
501  vir_act->coefs()->coldim());
502  std::vector<int> vir_to_allvir = sc::map(*allvir, *vir_act, false);
503  const int nocc_act = t1_subblock.nrow();
504  const int nvir_act = vir_act->rank();
505  for(int i=0; i<nocc_act; ++i) {
506  for(int a=0; a<nvir_act; ++a) {
507  const int Ap = vir_to_allvir[a];
508  t1_subblock.set_element(i, a, t1_cabs_.get_element(i, Ap));
509  }
510  }
511  operator_matrix = t1_subblock;
512  }
513  }
514  else {
515  MPQC_ASSERT(ket_id == "a'" || ket_id == "A'");
516  MPQC_ASSERT(t1_cabs_);
517  MPQC_ASSERT(oreg->value(ket_id)->rank() == t1_cabs_.ncol());
518  operator_matrix = t1_cabs_;
519  }
520  }
521  else if (pkey.oper() == "L1") {
522  MPQC_ASSERT(l1_);
523  MPQC_ASSERT(oreg->value(bra_id)->rank() == l1_.nrow());
524  MPQC_ASSERT(oreg->value(ket_id)->rank() == l1_.ncol());
525  operator_matrix = l1_;
526  }
527  else {
528  std::ostringstream oss;
529  oss << "SingleReference_R12Intermediates<T>::xy -- operator " << pkey.oper() << " is not recognized";
530  throw ProgrammingError(oss.str().c_str(),
531  __FILE__, __LINE__);
532  }
533 
534  // make tiled ranges
535  std::vector<size_t> bra_hashmarks = space_hashmarks(bra_id);
536  std::vector<size_t> ket_hashmarks = space_hashmarks(ket_id);
537 
538  std::vector<TA::TiledRange1> hashmarks;
539  hashmarks.push_back(TiledArray::TiledRange1(bra_hashmarks.begin(), bra_hashmarks.end()));
540  hashmarks.push_back(TiledArray::TiledRange1(ket_hashmarks.begin(), ket_hashmarks.end()));
541  TiledArray::TiledRange braket_trange(hashmarks.begin(), hashmarks.end());
542 
543  std::shared_ptr<TArray2> result(new TArray2(world_, braket_trange) );
544  // construct local tiles
545  for(auto t=result->pmap()->begin();
546  t!=result->pmap()->end();
547  ++t)
548  {
549 
550  auto tile_range = result->trange().make_tile_range(*t);
551  std::vector<double> ptr_data(tile_range.volume());
552 
553  for(size_t r=tile_range.lobound()[0], rc=0;
554  r != tile_range.upbound()[0];
555  ++r) {
556  for(size_t c=tile_range.lobound()[1];
557  c != tile_range.upbound()[1];
558  ++c, ++rc) {
559  ptr_data[rc] = operator_matrix->get_element(r,c);
560  }
561  }
562 
563  madness::Future < typename TArray2::value_type >
564  tile(typename TArray2::value_type(tile_range, &ptr_data[0]));
565 
566  // Insert the tile into the array
567  result->set(*t, tile);
568  }
569 
570  tarray2_registry_[key] = result;
571  v = tarray2_registry_.find(key);
572  }
573 
574  return *(v->second);
575  }
576 
577  template <typename T>
578  TA::expressions::TsrExpr<const typename SingleReference_R12Intermediates<T>::TArray4d, true>
579  SingleReference_R12Intermediates<T>::_4(const std::string& key) {
580  const TArray4d& tarray4 = ijxy(key);
582 
583  std::array<std::string, 4> ind = {{pkey.bra1(), pkey.bra2(), pkey.ket1(), pkey.ket2()}};
584  for(auto v=ind.begin(); v!=ind.end(); ++v) {
585  if (ParsedTransformedOrbitalSpaceKey::valid_key(*v) ) {
587  *v = ptkey.label();
588  }
589  }
590 
591  const std::string annotation = ind[0] + "," + ind[1] + "," + ind[2] + "," + ind[3];
592  return tarray4(annotation);
593  }
594 
595  template <typename T>
596  TA::expressions::TsrExpr<const typename SingleReference_R12Intermediates<T>::TArray2, true>
597  SingleReference_R12Intermediates<T>::_2(const std::string& key) {
598  const TArray2& tarray2 = xy(key);
599  ParsedOneBodyIntKey pkey(key);
600 
601  std::array<std::string, 2> ind = {{pkey.bra(), pkey.ket()}};
602  for(auto v=ind.begin(); v!=ind.end(); ++v) {
603  if (ParsedTransformedOrbitalSpaceKey::valid_key(*v) ) {
605  *v = ptkey.label();
606  }
607  }
608 
609  const std::string annotation = ind[0] + "," + ind[1];
610  return tarray2(annotation);
611  }
612 
613  template <typename T>
615  template <typename T>
617 
618  template <typename T>
619  TA::expressions::TsrExpr<const typename SingleReference_R12Intermediates<T>::TArray4Tg, true>
621 
623 
624  auto v = tarray4tg_registry_.find(key);
625  if (v == tarray4tg_registry_.end()) {
626 
627  if (pkey.oper() != "Tg") {
628  std::ostringstream oss;
629  oss << "SingleReference_R12Intermediates<T>::_Tg : " << pkey.oper() << " is an invalid operator key";
630  throw ProgrammingError(oss.str().c_str(), __FILE__, __LINE__);
631  }
632 
633  // canonicalize indices, may compute spaces if needed
634  auto bra1 = to_space(pkey.bra1());
635  auto bra2 = to_space(pkey.bra2());
636  auto ket1 = to_space(pkey.ket1());
637  auto ket2 = to_space(pkey.ket2());
638 
639  if (not (bra1 == bra2 && bra1 == ket1 && bra1 == ket2)) {
640  throw ProgrammingError("SingleReference_R12Intermediates<T>::_Tg : all spaces must be the same", __FILE__, __LINE__);
641  }
642 
643  // make tiled ranges
644  std::vector<size_t> i_hashmarks = space_hashmarks(bra1);
645  std::vector<size_t> j_hashmarks = space_hashmarks(bra2);
646  std::vector<size_t> x_hashmarks = space_hashmarks(ket1);
647  std::vector<size_t> y_hashmarks = space_hashmarks(ket2);
648 
649  std::vector<TA::TiledRange1> hashmarks;
650  hashmarks.push_back(TiledArray::TiledRange1(i_hashmarks.begin(), i_hashmarks.end()));
651  hashmarks.push_back(TiledArray::TiledRange1(j_hashmarks.begin(), j_hashmarks.end()));
652  hashmarks.push_back(TiledArray::TiledRange1(x_hashmarks.begin(), x_hashmarks.end()));
653  hashmarks.push_back(TiledArray::TiledRange1(y_hashmarks.begin(), y_hashmarks.end()));
654  TiledArray::TiledRange ijxy_trange(hashmarks.begin(), hashmarks.end());
655 
656  std::shared_ptr<TArray4Tg> result(new TArray4Tg(world_, ijxy_trange) );
657  // construct local tiles
658  for(auto t=ijxy_trange.tiles_range().begin();
659  t!=ijxy_trange.tiles_range().end();
660  ++t)
661  if (result->is_local(*t))
662  {
663  std::array<std::size_t, 4> index; std::copy(t->begin(), t->end(), index.begin());
664  madness::Future < typename TArray4Tg::value_type >
665  tile((typename TArray4Tg::value_type(result.get(), index, &tg_s0_gen)
666  ));
667 
668  // Insert the tile into the array
669  result->set(*t, tile);
670  }
671 
672  tarray4tg_registry_[key] = result;
673  v = tarray4tg_registry_.find(key);
674  }
675  const TArray4Tg& tarray4 = *(v->second);
676 
677  std::array<std::string, 4> ind = {{pkey.bra1(), pkey.bra2(), pkey.ket1(), pkey.ket2()}};
678  for(auto v=ind.begin(); v!=ind.end(); ++v) {
679  if (ParsedTransformedOrbitalSpaceKey::valid_key(*v) ) {
681  *v = ptkey.label();
682  }
683  }
684 
685  const std::string annotation = ind[0] + "," + ind[1] + "," + ind[2] + "," + ind[3];
686  return tarray4(annotation);
687  }
688 
689  namespace expressions {
690 
691  template <typename ArgType, bool Transpose = false>
692  struct trace_tensor2_op : public std::binary_function<ArgType, ArgType, TA::Tensor<typename ArgType::numeric_type> > {
693  typedef typename ArgType::numeric_type numeric_type;
694  typedef TA::Tensor<typename ArgType::numeric_type> result_type;
695  typedef result_type value_type;
696 
697  static bool is_dense(bool first_dense, bool second_dense) {
698  return true;
699  }
700  static bool is_zero(const bool first_zero, const bool second_zero) {
701  return first_zero || second_zero;
702  }
703 
704  template <typename Left, typename Right>
705  static void shape(::TiledArray::detail::Bitset<>& result, const Left& left, const Right& right) {
706  result = ::TiledArray::detail::Bitset<>(0);
707  }
708 
709  // applies the scaling factor
710  void scale(numeric_type s) {
711  scale_ = s;
712  }
713 
714  result_type
715  operator()(const ArgType& arg1, const ArgType& arg2) const {
716  TA_ASSERT(arg1.size() == 1);
717  TA_ASSERT(arg2.size() == 1);
718  TA_ASSERT(arg1.data()->size() == arg2.data()->size());
719  TA_ASSERT(arg1.range() == arg2.range()); // structure of the arguments must be the same
720 
721  numeric_type dot_product;
722  if (not Transpose) // straight dot
723  dot_product = TA::math::dot(arg1.data()->size(), arg1.data()->data(), arg2.data()->data());
724  else { // transposed dot done as series of row*column products
725  const integer nrow1 = arg1.data()->range().size()[0];
726  const integer ncol1 = arg1.data()->range().size()[1];
727  TA_ASSERT(ncol1 == arg2.data()->range().size()[0]); // ncol1 == nrow2
728  const integer unit_stride = 1;
729  dot_product = 0;
730 
731  const numeric_type* ptr1 = arg1.data()->data();
732  const numeric_type* ptr2 = arg2.data()->data();
733  for(integer row1=0; row1<nrow1; ++row1, ptr1+=ncol1, ++ptr2) {
734  dot_product += TA::math::dot(ncol1, ptr1, unit_stride, ptr2, nrow1);
735  }
736  }
737  //std::cout << dot_product << std::endl;
738 
739  result_type result(arg1.range(), &dot_product);
740  return result * scale_;
741  }
742 
743  result_type operator()(const TiledArray::ZeroTensor&, const ArgType&) {
744  TA_ASSERT(false); // Should not be used.
745  return result_type();
746  }
747 
748  result_type operator()(const ArgType&, const TiledArray::ZeroTensor&) {
749  TA_ASSERT(false); // Should not be used.
750  return result_type();
751  }
752 
753  private:
754  numeric_type scale_;
755 
756  };
757 
758  template <typename ArgType, bool Transpose = false>
759  struct diag_tensor2_op : public std::unary_function<ArgType, TA::Tensor<typename ArgType::numeric_type> > {
760  typedef typename ArgType::numeric_type numeric_type;
761  typedef TA::Tensor<typename ArgType::numeric_type> result_type;
762  typedef result_type value_type;
763 
764  static bool is_dense(bool arg_dense) {
765  return true;
766  }
767  static bool is_zero(const bool arg_zero) {
768  return arg_zero;
769  }
770 
771  template <typename Arg>
772  static void shape(::TiledArray::detail::Bitset<>& result, const Arg& arg) {
773  result = ::TiledArray::detail::Bitset<>(0);
774  }
775 
776  // applies the scaling factor
777  void scale(numeric_type s) {
778  scale_ = s;
779  }
780 
781  result_type
782  operator()(const ArgType& arg) const {
783  TA_ASSERT(arg.size() == 1);
784 
785  numeric_type result_value = 0;
786  const auto& ij = arg.range().start();
787  const auto& pq_size = arg.data()->range().size();
788  if (not Transpose) { // extract i,j
789  result_value = arg.data()->data()[ij[0] * pq_size[1] + ij[1]];
790  }
791  else { // extract j,i
792  result_value = arg.data()->data()[ij[1] * pq_size[1] + ij[0]];
793  }
794 
795  result_type result(arg.range(), &result_value);
796  return result * scale_;
797  }
798 
799  result_type operator()(const TiledArray::ZeroTensor&) {
800  TA_ASSERT(false); // Should not be used.
801  return result_type();
802  }
803 
804  private:
805  numeric_type scale_;
806  };
807 
808  }; // end of namespace sc::expressions
809 
810  template <typename T>
811  std::string
812  SingleReference_R12Intermediates<T>::to_space(const std::string& index) {
813 
814  bool tformed_space = ParsedTransformedOrbitalSpaceKey::valid_key(index);
815  if (tformed_space) {
816  ParsedTransformedOrbitalSpaceKey pkey(index);
817 
818  // make sure this space exists
819  const std::string space_label = to_space(pkey.label());
820  std::string space_key = ParsedTransformedOrbitalSpaceKey::key(space_label, pkey.spin(),
821  pkey.support_label(), pkey.support_spin(),
822  pkey.transform_operator());
823  auto oreg = r12world_->world()->tfactory()->orbital_registry();
824  auto freg = r12world_->world()->fockbuild_runtime();
825 
826  if (not oreg->key_exists(space_key)) { // compute if needed
827  std::string support_key = ParsedOrbitalSpaceKey::key(to_space(pkey.support_label()), pkey.support_spin());
828  std::string target_key = ParsedOrbitalSpaceKey::key(space_label, pkey.spin());
829 
830  Ref<OrbitalSpace> target_space = oreg->value(target_key);
831  Ref<OrbitalSpace> support_space = oreg->value(support_key);
832  RefSCMatrix support_coefs = support_space->coefs();
833 
834  RefSCMatrix operator_matrix;
835  switch(pkey.transform_operator()) {
836  case OneBodyOper::J:
837  operator_matrix = freg->get(ParsedOneBodyIntKey::key(support_key, target_key, "J"));
838  break;
839  case OneBodyOper::K:
840  operator_matrix = freg->get(ParsedOneBodyIntKey::key(support_key, target_key, "K"));
841  break;
842  case OneBodyOper::F:
843  operator_matrix = freg->get(ParsedOneBodyIntKey::key(support_key, target_key, "F"));
844  break;
845  case OneBodyOper::hJ:
846  operator_matrix = freg->get(ParsedOneBodyIntKey::key(support_key, target_key, "H"))
847  + freg->get(ParsedOneBodyIntKey::key(support_key, target_key, "J"));
848  break;
849  case OneBodyOper::gamma:
850  operator_matrix = this->rdm1(support_space, target_space);
851  break;
852  default:
853  throw ProgrammingError("SingleReference_R12Intermediates<T>::to_space -- transformed spaces only with Fock-like operators are supported now",
854  __FILE__, __LINE__);
855  }
856 
857  Ref<OrbitalSpace> tformed_space = new OrbitalSpace(space_key, space_key,
858  target_space, support_coefs * operator_matrix,
859  support_space->basis());
860  operator_matrix = 0;
861  oreg->add(make_keyspace_pair(tformed_space));
862  }
863  return space_key;
864  }
865 
866  return to_space_(index);
867  }
868 
869  template <typename T>
870  RefSCMatrix SingleReference_R12Intermediates<T>::rdm1(const Ref<OrbitalSpace>& row_space,
871  const Ref<OrbitalSpace>& col_space) const {
872  // get the reference 1-RDM
873  RefSymmSCMatrix gamma_total = r12world_->refwfn()->ordm_occ_sb(Alpha) + r12world_->refwfn()->ordm_occ_sb(Beta);
874  Ref<OrbitalSpace> occ = r12world_->refwfn()->occ_sb(Alpha);
875  // map to the target space and support space
876  std::vector<int> col_to_occ;
877  std::vector<int> row_to_occ;
878  try {
879  const bool require_same_basis = true;
880  col_to_occ = map(*occ, *col_space, require_same_basis);
881  row_to_occ = map(*occ, *row_space, require_same_basis);
882  }
883  catch (sc::CannotConstructMap&) {
884  throw ProgrammingError("requested RDM1 in spaces x and y, but x and y are not supported by the same basis",
885  __FILE__, __LINE__);
886  }
887  RefSCMatrix result = gamma_total.kit()->matrix(row_space->dim(), col_space->dim());
888  result.assign(0.0);
889  const int nr = result.nrow();
890  const int nc = result.ncol();
891  for(int r=0; r<nr; ++r) {
892  const int rr = row_to_occ[r];
893  if (rr >= 0)
894  for(int c=0; c<nc; ++c) {
895  const int cc = col_to_occ[c];
896  if (cc >= 0)
897  result.set_element(r, c, gamma_total.get_element(rr, cc));
898  }
899  }
900 
901  return result;
902  }
903 
904  template<typename T>
905  std::string SingleReference_R12Intermediates<T>::to_space_(std::string index) {
906 
907  index.erase(std::remove_if(index.begin(), index.end(),
908  [](char c){
909  return c >= '0' && c<='9';
910  }
911  ), index.end());
912 
913  if (index == "i" || index == "j" || index == "k" || index == "l")
914  return "i";
915  if (index == "m" || index == "n")
916  return "m";
917  if (index == "i'" || index == "j'" || index == "k'" || index == "l'")
918  return "i'";
919  if (index == "a" || index == "b" || index == "c" || index == "d")
920  return "a";
921  if (index == "e" || index == "f")
922  return "e";
923  if (index == "a" || index == "b" || index == "c" || index == "d")
924  return "a";
925  if (index == "p" || index == "q" || index == "r" || index == "s")
926  return "p";
927  if (index == "p'" || index == "q'" || index == "r'" || index == "s'")
928  return "p'";
929  if (index == "a'" || index == "b'" || index == "c'" || index == "d'")
930  return "a'";
931  if (index == "A'" || index == "B'" || index == "C'" || index == "D'")
932  return "A'";
933 
934  std::ostringstream oss;
935  oss << "SingleReference_R12Intermediates::to_space(): index label " << index << " not in the current dictionary:";
936  throw ProgrammingError(oss.str().c_str(),
937  __FILE__, __LINE__);
938  }
939 
940  template <typename T>
941  std::vector<size_t>
942  SingleReference_R12Intermediates<T>::space_hashmarks(std::string space_label) const {
943 
944  const bool tformed_space = ParsedTransformedOrbitalSpaceKey::valid_key(space_label);
945  if (tformed_space) {
946  ParsedTransformedOrbitalSpaceKey ptkey(space_label);
947  space_label = ptkey.label();
948  }
949 
950  auto oreg = r12world_->world()->tfactory()->orbital_registry();
951  size_t rank = oreg->value(space_label)->rank();
952  std::vector<size_t> hashmarks(2,0); hashmarks[1] = rank; // all spaces have 1 tile, except
953  if (space_label == "i" || space_label == "m") { // occupied spaces, whose size is determined heuristically for now
954  // TODO create a central registry of space tilings?
955  const int nproc = r12world_->world()->msg()->n();
956  const size_t desired_tilesize = std::max(4 ,
957  std::min( (int)floor((double)rank / sqrt((double)nproc)), 10)
958  );
959  const size_t ntiles = (rank+desired_tilesize-1)/desired_tilesize;
960  const size_t tilesize = (rank + ntiles - 1)/ ntiles;
961  hashmarks.resize(ntiles+1);
962  hashmarks[0] = 0;
963  for(size_t i=1; i<ntiles; ++i)
964  hashmarks[i] = hashmarks[i-1] + tilesize;
965  hashmarks.back() = rank;
966  }
967 
968  return hashmarks;
969  }
970 
971 #if 0
972  namespace {
973  std::vector<std::string>
974  split(const std::string& key,
975  char separator) {
976 
977  std::stringstream ss(key);
978  std::string item;
979  std::vector<std::string> tokens;
980  while (std::getline(ss, item, separator)) {
981  tokens.push_back(item);
982  }
983 
984  return tokens;
985  }
986 
987  }
988 
989  template <typename T> template <size_t NDIM>
990  TA::TiledRange
991  SingleReference_R12Intermediates<T>::make_trange(const std::array<std::string, NDIM>& spaces) const {
992 
993  std::vector<TA::TiledRange1> hashmarks;
994  for(auto id=spaces.begin(); id!=spaces.end(); ++id) {
995  std::vector<size_t> hashmark = space_hashmarks(*id);
996  hashmarks.push_back(TiledArray::TiledRange1(hashmark.begin(), hashmark.end()));
997  }
998  return TA::TiledRange(hashmarks.begin(), hashmarks.end());
999  }
1000 
1001  namespace detail {
1002 
1003  template <typename T, typename Index>
1004  void
1005  sieve_tensor(TA::Array<T, 2>* result,
1006  Index t,
1007  madness::Future<typename TA::Array<T, 2>::value_type > source_tile,
1008  TA::Array<T, 2>* source,
1009  Index t_source,
1010  std::vector<int>* row_map,
1011  std::vector<int>* col_map) {
1012 
1013  typedef TA::Array<T, 2> TArray2;
1014 
1015  auto result_trange = result->trange().make_tile_range(t);
1016  auto source_trange = source->trange().make_tile_range(t_source);
1017 
1018  std::vector<T> ptr_result(result_trange.volume(), T(0.0));
1019 
1020  for(size_t r=source_trange.start()[0], rc=0;
1021  r != source_trange.finish()[0];
1022  ++r) {
1023  const int rr = row_map->operator[](r);
1024  if (rr != -1) {
1025  for(size_t c=source_trange.start()[1];
1026  c != source_trange.finish()[1];
1027  ++c, ++rc) {
1028 
1029  const int cc = col_map->operator[](c);
1030 
1031  if (cc != -1) {
1032 
1033  MPQC_ASSERT(false);
1034 
1035  }
1036  }
1037  }
1038  }
1039 
1040  madness::Future < typename TArray2::value_type >
1041  tile(typename TArray2::value_type(result_trange, &ptr_result[0]));
1042 
1043  // Insert the tile into the array
1044  result->set(*t, tile);
1045 
1046  }
1047  }
1048 
1049  template <typename T>
1051  SingleReference_R12Intermediates<T>::sieve(const TArray2& input,
1052  const std::string& output_annotation) {
1053 
1054  // find the input key
1055  std::string input_key;
1056  for(auto i = tarray2_registry_.begin();
1057  i!=tarray2_registry_.end(); ++i) {
1058  if (i->second.get() == &input) {
1059  input_key = i->first;
1060  break;
1061  }
1062  }
1063  MPQC_ASSERT(input_key.empty() == false);
1064 
1065  std::vector<std::string> output_space_keys = split(output_annotation, ',');
1066  MPQC_ASSERT(output_space_keys.size() == 2);
1067 
1068  ParsedOneBodyIntKey input_pkey(input_key);
1069  ParsedOneBodyIntKey output_pkey(ParsedOneBodyIntKey::key(output_space_keys[0],
1070  output_space_keys[1],
1071  input_pkey.oper()));
1072 
1073  auto v = tarray2_registry_.find(output_pkey.key());
1074  if (v == tarray2_registry_.end()) {
1075 
1076  // canonicalize indices, may compute spaces if needed
1077  auto ibra_id = to_space(input_pkey.bra());
1078  auto iket_id = to_space(input_pkey.ket());
1079  auto obra_id = to_space(output_pkey.bra());
1080  auto oket_id = to_space(output_pkey.ket());
1081 
1082  auto oreg = r12world_->world()->tfactory()->orbital_registry();
1083  auto freg = r12world_->world()->fockbuild_runtime();
1084  auto ibra = oreg->value(ibra_id);
1085  auto iket = oreg->value(iket_id);
1086  auto obra = oreg->value(obra_id);
1087  auto oket = oreg->value(oket_id);
1088 
1089  auto nbra = obra->rank();
1090  auto nket = oket->rank();
1091 
1092  std::vector<int> bra_map = map(*obra, *ibra);
1093  std::vector<int> ket_map = map(*oket, *iket);
1094 
1095  // construct the output array
1096  std::array<std::string, 2> ospaces = {{obra_id, oket_id}};
1097  TA::TiledRange output_trange = make_trange(ospaces);
1098  std::shared_ptr<TArray2> result(new TArray2(world_, output_trange) );
1099 
1100  // construct tasks to fill in local tiles
1101  for(auto t=result->pmap()->begin();
1102  t!=result->pmap()->end();
1103  ++t)
1104  {
1105 
1106  // map t to the index of the tile that contains the data needed for t
1107  auto t_input = *t;
1108  MPQC_ASSERT(false);
1109 
1110  world_.taskq.add(& detail::sieve_tensor,
1111  &result, *t, input.find(t_input), &bra_map, &ket_map);
1112  }
1113 
1114  tarray2_registry_[output_pkey.key()] = result;
1115  v = tarray2_registry_.find(output_pkey.key());
1116 
1117  }
1118 
1119  return *(v->second);
1120  }
1121 #endif
1122 
1123  template <typename T>
1124  std::ostream& operator<<(std::ostream& os, const DA4_Tile<T>& t) {
1125  os << typename DA4_Tile<T>::eval_type(t);
1126  return os;
1127  }
1128 
1129  template <typename T>
1130  std::ostream& operator<<(std::ostream& os, const DA4_Tile34<T>& t) {
1131  os << typename DA4_Tile34<T>::eval_type(t);
1132  return os;
1133  }
1134 
1135 
1136 }; // end of namespace sc
1137 
1138 #endif // end of header guard
1139 
1140 
1141 // Local Variables:
1142 // mode: c++
1143 // c-file-style: "CLJ-CONDENSED"
1144 // End:
sc::expressions::TGeminalGenerator
makes a geminal T tensor
Definition: sr_r12intermediates.h:186
sc::SingleReference_R12Intermediates::ijxy
TArray4d & ijxy(const std::string &key)
Definition: sr_r12intermediates_util.h:164
sc::SingleReference_R12Intermediates::xy
TArray2 & xy(const std::string &key)
Definition: sr_r12intermediates_util.h:437
sc::SingleReference_R12Intermediates::TArray22
TA::Array< TA::Tensor< T >, 2 > TArray22
2-index tensor with lazy tiles
Definition: sr_r12intermediates.h:232
sc::OneBodyOper::J
(electronic) Coulomb
Definition: operator.h:108
sc::DistArray4::clone
virtual Ref< DistArray4 > clone(const DistArray4Dimensions &dim=DistArray4Dimensions::default_dim())=0
how to clone.
sc::DistArray4::nj
int nj() const
Rank of index space j.
Definition: distarray4.h:116
sc::OneBodyOper::hJ
h+J
Definition: operator.h:111
sc::overlap
RefSCMatrix overlap(const OrbitalSpace &space2, const OrbitalSpace &space1, const Ref< SCMatrixKit > &kit=SCMatrixKit::default_matrixkit())
overlap(s2,s1) returns the overlap matrix between s2 and s1.
sc::DistArray4::tasks_with_access
int tasks_with_access(std::vector< int > &twa_map) const
Returns the total number of tasks with access to integrals.
sc::TwoBodyMOIntsTransform::compute
virtual void compute()=0
Computes transformed integrals.
sc::RefSCMatrix
The RefSCMatrix class is a smart pointer to an SCMatrix specialization.
Definition: matrix.h:135
sc::Ref
A template class that maintains references counts.
Definition: ref.h:361
sc::SingleReference_R12Intermediates::TArray4d
TA::Array< T, 4, DA4_Tile< T > > TArray4d
4-index tensor with lazy tiles
Definition: sr_r12intermediates.h:224
sc::OrbitalSpace::coefs
const RefSCMatrix & coefs() const
Returns the coefficient matrix.
sc::OneBodyOper::K
(electronic) exchange
Definition: operator.h:109
sc::SingleReference_R12Intermediates::_4
TA::expressions::TsrExpr< const TArray4d, true > _4(const std::string &key)
Given a descriptive key, creates a rank-4 Array of integrals, or other related quantities The syntax ...
Definition: sr_r12intermediates_util.h:579
sc::DistArray4::release_pair_block
virtual void release_pair_block(int i, int j, tbint_type oper_type) const =0
Releases the buffer that holds ij block of integrals. If it was allocated by DistArray4,...
sc::DistArray4::deactivate
virtual void deactivate()
call this after operations on this object are finished. May destroy data (see data_persistent()).
Definition: distarray4.h:131
sc::SingleReference_R12Intermediates::TArray2
TA::Array< T, 2 > TArray2
standard 2-index tensor
Definition: sr_r12intermediates.h:226
sc::DistArray4::ny
int ny() const
Rank of index space y.
Definition: distarray4.h:120
sc::ParsedTwoBodyFourCenterIntKey
Parsed representation of a string key that represents a set of 4-center 2-body integrals.
Definition: tbint_runtime.h:160
sc::CannotConstructMap
Definition: orbitalspace.h:532
sc::OrbitalSpace::rank
unsigned int rank() const
Returns the rank of the space.
sc::SingleReference_R12Intermediates
SingleReference_R12Intermediates computes R12/F12 intermediates using MPQC3 runtime.
Definition: sr_r12intermediates.h:218
sc::ParsedTransformedOrbitalSpaceKey
Parses keys of a "transformed" OrbitalSpace.
Definition: orbitalspace.h:635
sc::DistArray4::retrieve_pair_block
virtual const double * retrieve_pair_block(int i, int j, tbint_type oper_type, double *buf=0) const =0
Retrieves an ij block of integrals.
sc::operator<<
std::vector< unsigned int > operator<<(const GaussianBasisSet &B, const GaussianBasisSet &A)
computes a map from basis functions in A to the equivalent basis functions in B.
sc::ParsedOneBodyIntKey
Parsed representation of a string key that represents a set of one-body integrals.
Definition: fockbuild_runtime.h:219
sc::map
std::vector< int > map(const GaussianBasisSet &B, const GaussianBasisSet &A)
same as operator<<, except A does not have to be contained in B, map[a] = -1 if function a is not in ...
sc::TwoBodyMOIntsTransform::ints_distarray4
const Ref< DistArray4 > & ints_distarray4()
Returns the DistArray4 object that holds the integrals.
sc::SingleReference_R12Intermediates::_2
TA::expressions::TsrExpr< const TArray2, true > _2(const std::string &key)
Given a descriptive key, creates a rank-2 Array of integrals, or other related quantities The syntax ...
Definition: sr_r12intermediates_util.h:597
sc::OneBodyOper::gamma
1-body reduced density matrix
Definition: operator.h:104
sc::SingleReference_R12Intermediates::ij_xy
TArray22d & ij_xy(const std::string &key)
Definition: sr_r12intermediates_util.h:345
sc::SingleReference_R12Intermediates::TArray4Tg
TA::Array< T, 4, LazyTensor< T, 4, expressions::TGeminalGenerator< T > > > TArray4Tg
geminal T tensor
Definition: sr_r12intermediates.h:237
sc::OneBodyOper::F
Fock operator.
Definition: operator.h:110
sc::SingleReference_R12Intermediates::TArray22d
TA::Array< TA::Tensor< T >, 2, DA4_Tile34< T > > TArray22d
2-index tensor of lazy 2-index tensors
Definition: sr_r12intermediates.h:234
sc::DistArray4::data_persistent
virtual bool data_persistent() const =0
if this returns false, call to deactivate may destroy data
sc::DistArray4::ni
int ni() const
Rank of index space i.
Definition: distarray4.h:114
sc::ProgrammingError
This is thrown when a situations arises that should be impossible.
Definition: scexception.h:92
sc::DistArray4Dimensions
Definition: distarray4.h:43
sc::make_keyspace_pair
std::pair< std::string, Ref< OrbitalSpace > > make_keyspace_pair(const Ref< OrbitalSpace > &space, SpinCase1 spin=AnySpinCase1)
helper function to form a key/space pair from a OrbitalSpace
sc::SingleReference_R12Intermediates::sieve
TArray2 & sieve(const TArray2 &input, const std::string &output_annotation)
sieves x|o1|y -> x'|o1|y' does not throw only if each tile of the result depends only on 1 tile of th...
sc::SingleReference_R12Intermediates::_Tg
TA::expressions::TsrExpr< const TArray4Tg, true > _Tg(const std::string &key)
like _4, produces geminal T tensor
Definition: sr_r12intermediates_util.h:620
sc::DistArray4::nx
int nx() const
Rank of index space x.
Definition: distarray4.h:118
sc::DA4_Tile34
Tile of a <34> slice of <1234> that's "evaluated" when needed by reading from DistArray4 holding pqrs...
Definition: sr_r12intermediates.h:89
sc
Contains all MPQC code up to version 3.
Definition: mpqcin.h:14
sc::DA4_Tile
Tile of a 4-index tensor that's "evaluated" when needed by reading from DistArray4.
Definition: sr_r12intermediates.h:51
sc::DistArray4::activate
virtual void activate()
call this before operations on this object can begin
Definition: distarray4.h:129
sc::SingleReference_R12Intermediates::rdm1
TArray2 rdm1()
returns the 1-particle reduced density matrix
Definition: sr_r12intermediates_VXB_diag.h:6783

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