14
18
#include"taylor_fm_eval.h"
16
20
#include"int_fjt.h"
18
23
#include "quartet_data.h"
19
24
#include "symmetrize.h"
20
25
#include "small_fns.h"
23
static void inline switch_ij(int& a, int& b) {int dum = a; a = b; b = dum;};
25
extern "C" int compute_eri(double* target,
26
Libint_t* Libint, int& si, int& sj, int& sk, int& sl,
27
int& inc1, int& inc2, int& inc3, int& inc4, const bool do_not_permute)
30
static void inline switch_ij(int& a, int& b) {int dum = a; a = b; b = dum;};
32
int compute_eri(double* target,
33
Libint_t* Libint, int& si, int& sj, int& sk, int& sl,
34
int& inc1, int& inc2, int& inc3, int& inc4, const bool do_not_permute)
30
37
#ifndef USE_TAYLOR_FM
31
static double_array_t fjt_table;
32
init_fjt_table(&fjt_table);
38
static double_array_t fjt_table;
39
init_fjt_table(&fjt_table);
35
/* place in "ascending" angular mom-
36
my simple way of optimizing PHG recursion (VRR) */
38
bool switch_bra_ket = false;
39
/* this should be /good/ for the VRR */
40
if ( BasisSet.shells[si].am + BasisSet.shells[sj].am + inc1 + inc2 >
41
BasisSet.shells[sk].am + BasisSet.shells[sl].am + inc3 + inc4 ) {
42
switch_bra_ket = true;
45
switch_ij(inc1, inc3);
46
switch_ij(inc2, inc4);
49
/* these two are good for the HRR */
50
bool switch_bra = false;
51
if(BasisSet.shells[si].am + inc1 < BasisSet.shells[sj].am + inc2){
56
bool switch_ket = false;
57
if(BasisSet.shells[sk].am + inc3 < BasisSet.shells[sl].am + inc4){
63
int am1 = BasisSet.shells[si].am - 1 + inc1;
64
int am2 = BasisSet.shells[sj].am - 1 + inc2;
65
int am3 = BasisSet.shells[sk].am - 1 + inc3;
66
int am4 = BasisSet.shells[sl].am - 1 + inc4;
67
int am = am1 + am2 + am3 + am4;
69
int c1 = BasisSet.shells[si].center - 1;
70
int c2 = BasisSet.shells[sj].center - 1;
71
int c3 = BasisSet.shells[sk].center - 1;
72
int c4 = BasisSet.shells[sl].center - 1;
74
// If all centers are the same and angular momentum of functions is odd -- the ERI will be 0 by AM selection
75
if ( (c1 == c2) && (c1 == c3) && (c1 == c4) && (am%2 == 1)) {
79
struct shell_pair* sp_ij = &(BasisSet.shell_pairs[si][sj]);
80
struct shell_pair* sp_kl = &(BasisSet.shell_pairs[sk][sl]);
82
Libint->AB[0] = sp_ij->AB[0];
83
Libint->AB[1] = sp_ij->AB[1];
84
Libint->AB[2] = sp_ij->AB[2];
85
Libint->CD[0] = sp_kl->AB[0];
86
Libint->CD[1] = sp_kl->AB[1];
87
Libint->CD[2] = sp_kl->AB[2];
89
double AB2 = Libint->AB[0]*Libint->AB[0]+
90
Libint->AB[1]*Libint->AB[1]+
91
Libint->AB[2]*Libint->AB[2];
92
double CD2 = Libint->CD[0]*Libint->CD[0]+
93
Libint->CD[1]*Libint->CD[1]+
94
Libint->CD[2]*Libint->CD[2];
96
/*--- Compute data for primitive quartets here ---*/
97
int np1 = BasisSet.shells[si].n_prims;
98
int np2 = BasisSet.shells[sj].n_prims;
99
int np3 = BasisSet.shells[sk].n_prims;
100
int np4 = BasisSet.shells[sl].n_prims;
102
/*--- Compute data for primitive quartets here ---*/
103
int num_prim_comb = 0;
104
// bool si_eq_sj = (si == sj && am1 == am2);
105
// bool sk_eq_sl = (sk == sl && am3 == am4);
106
bool si_eq_sj = false;
107
bool sk_eq_sl = false;
108
for (int p1 = 0; p1 < np1; p1++) {
109
int max_p2 = si_eq_sj ? p1+1 : np2;
110
for (int p2 = 0; p2 < max_p2; p2++) {
111
int m = (1 + (si_eq_sj && p1 != p2));
112
for (int p3 = 0; p3 < np3; p3++) {
113
int max_p4 = sk_eq_sl ? p3+1 : np4;
114
for (int p4 = 0; p4 < max_p4; p4++){
115
int n = m * (1 + (sk_eq_sl && p3 != p4));
42
/* place in "ascending" angular mom-
43
my simple way of optimizing PHG recursion (VRR) */
45
bool switch_bra_ket = false;
46
/* this should be /good/ for the VRR */
47
if ( BasisSet.shells[si].am + BasisSet.shells[sj].am + inc1 + inc2 >
48
BasisSet.shells[sk].am + BasisSet.shells[sl].am + inc3 + inc4 ) {
49
switch_bra_ket = true;
52
switch_ij(inc1, inc3);
53
switch_ij(inc2, inc4);
56
/* these two are good for the HRR */
57
bool switch_bra = false;
58
if(BasisSet.shells[si].am + inc1 < BasisSet.shells[sj].am + inc2){
63
bool switch_ket = false;
64
if(BasisSet.shells[sk].am + inc3 < BasisSet.shells[sl].am + inc4){
70
int am1 = BasisSet.shells[si].am - 1 + inc1;
71
int am2 = BasisSet.shells[sj].am - 1 + inc2;
72
int am3 = BasisSet.shells[sk].am - 1 + inc3;
73
int am4 = BasisSet.shells[sl].am - 1 + inc4;
74
int am = am1 + am2 + am3 + am4;
76
int c1 = BasisSet.shells[si].center - 1;
77
int c2 = BasisSet.shells[sj].center - 1;
78
int c3 = BasisSet.shells[sk].center - 1;
79
int c4 = BasisSet.shells[sl].center - 1;
81
// If all centers are the same and angular momentum of functions is odd -- the ERI will be 0 by AM selection
82
if ( (c1 == c2) && (c1 == c3) && (c1 == c4) && (am%2 == 1)) {
86
struct shell_pair* sp_ij = &(BasisSet.shell_pairs[si][sj]);
87
struct shell_pair* sp_kl = &(BasisSet.shell_pairs[sk][sl]);
89
Libint->AB[0] = sp_ij->AB[0];
90
Libint->AB[1] = sp_ij->AB[1];
91
Libint->AB[2] = sp_ij->AB[2];
92
Libint->CD[0] = sp_kl->AB[0];
93
Libint->CD[1] = sp_kl->AB[1];
94
Libint->CD[2] = sp_kl->AB[2];
97
Libint->AB[0]*Libint->AB[0]+
98
Libint->AB[1]*Libint->AB[1]+
99
Libint->AB[2]*Libint->AB[2];
101
Libint->CD[0]*Libint->CD[0]+
102
Libint->CD[1]*Libint->CD[1]+
103
Libint->CD[2]*Libint->CD[2];
105
/*--- Compute data for primitive quartets here ---*/
106
int np1 = BasisSet.shells[si].n_prims;
107
int np2 = BasisSet.shells[sj].n_prims;
108
int np3 = BasisSet.shells[sk].n_prims;
109
int np4 = BasisSet.shells[sl].n_prims;
111
/*--- Compute data for primitive quartets here ---*/
112
int num_prim_comb = 0;
113
// bool si_eq_sj = (si == sj && am1 == am2);
114
// bool sk_eq_sl = (sk == sl && am3 == am4);
115
bool si_eq_sj = false;
116
bool sk_eq_sl = false;
117
for (int p1 = 0; p1 < np1; p1++) {
118
int max_p2 = si_eq_sj ? p1+1 : np2;
119
for (int p2 = 0; p2 < max_p2; p2++) {
120
int m = (1 + (si_eq_sj && p1 != p2));
121
for (int p3 = 0; p3 < np3; p3++) {
122
int max_p4 = sk_eq_sl ? p3+1 : np4;
123
for (int p4 = 0; p4 < max_p4; p4++){
124
int n = m * (1 + (sk_eq_sl && p3 != p4));
116
125
#ifdef USE_TAYLOR_FM
117
quartet_data(&(Libint->PrimQuartet[num_prim_comb++]), NULL, AB2, CD2,
118
sp_ij, sp_kl, am, p1, p2, p3, p4, n);
120
quartet_data(&(Libint->PrimQuartet[num_prim_comb++]), &fjt_table, AB2, CD2,
121
sp_ij, sp_kl, am, p1, p2, p3, p4, n);
129
nao[0] = ioff[am1+1];
130
nao[1] = ioff[am2+1];
131
nao[2] = ioff[am3+1];
132
nao[3] = ioff[am4+1];
133
int nbra = nao[0] * nao[1];
134
int nket = nao[2] * nao[3];
135
int size = nbra * nket;
137
// In general we need a couple extra buffers to be able to copy and permute integrals
138
static int max_size = ioff[BasisSet.max_am]*ioff[BasisSet.max_am]*ioff[BasisSet.max_am]*ioff[BasisSet.max_am];
139
static double* perm_buf = new double[max_size];
140
static double* copy_buf = new double[max_size];
141
if (size > max_size) {
144
perm_buf = new double[size];
145
copy_buf = new double[size];
148
#ifdef NONDOUBLE_INTS
149
double* raw_data = copy_buf;
153
#ifdef NONDOUBLE_INTS
154
REALTYPE* target_ptr = build_eri[am1][am2][am3][am4](Libint,num_prim_comb);
156
raw_data[i] = (double) target_ptr[i];
158
double* raw_data = build_eri[am1][am2][am3][am4](Libint,num_prim_comb);
162
// Permute shells back, if necessary
163
if (!do_not_permute) {
164
int num_perm = (int) switch_bra_ket + (int) switch_bra + (int) switch_ket;
166
double *sbuf1, *sbuf2, *sbuf3;
167
double *tbuf1, *tbuf2, *tbuf3;
168
// in general, permutations will require careful orchestration of
169
// the utilization of the buffers. If no permutations are necessary -- just copy the data
171
for(int i=0; i<size; i++)
172
target[i] = raw_data[i];
174
// otherwise -- do the dance
175
else if (num_perm == 1) {
176
sbuf1 = sbuf2 = sbuf3 = raw_data;
177
tbuf1 = tbuf2 = tbuf3 = target;
179
else if (num_perm == 2) {
180
if (!switch_bra_ket) {
182
tbuf1 = sbuf2 = perm_buf;
185
else if (!switch_ket) {
187
tbuf1 = sbuf3 = perm_buf;
190
else if (!switch_bra) {
192
tbuf2 = sbuf3 = perm_buf;
196
else if (num_perm == 3) {
198
tbuf1 = sbuf2 = perm_buf;
199
tbuf2 = sbuf3 = raw_data;
203
// Note that the order of permutations is opposite to the order of shell index permutations
204
// at the beginning of this function
206
ijkl_to_jikl(sbuf1, tbuf1, nao[0], nao[1], nket);
208
switch_ij(inc1,inc2);
211
ijkl_to_ijlk(sbuf2, tbuf2, nbra, nao[2], nao[3]);
213
switch_ij(inc3,inc4);
215
if (switch_bra_ket) {
216
ijkl_to_klij(sbuf3, tbuf3, nbra, nket);
219
switch_ij(inc1, inc3);
220
switch_ij(inc2, inc4);
226
prim_data* prim_quartet = Libint->PrimQuartet;
227
for(int p=0;p<num_prim_comb;p++,prim_quartet++) {
228
temp += prim_quartet->F[0];
230
target[0] = (double) temp;
126
quartet_data(&(Libint->PrimQuartet[num_prim_comb++]), NULL, AB2, CD2,
127
sp_ij, sp_kl, am, p1, p2, p3, p4, n);
129
quartet_data(&(Libint->PrimQuartet[num_prim_comb++]), &fjt_table, AB2, CD2,
130
sp_ij, sp_kl, am, p1, p2, p3, p4, n);
138
nao[0] = ioff[am1+1];
139
nao[1] = ioff[am2+1];
140
nao[2] = ioff[am3+1];
141
nao[3] = ioff[am4+1];
142
int nbra = nao[0] * nao[1];
143
int nket = nao[2] * nao[3];
144
int size = nbra * nket;
146
// In general we need a couple extra buffers to be able to copy and permute integrals
147
static int max_size = ioff[BasisSet.max_am]*ioff[BasisSet.max_am]*ioff[BasisSet.max_am]*ioff[BasisSet.max_am];
148
static double* perm_buf = new double[max_size];
149
static double* copy_buf = new double[max_size];
150
if (size > max_size) {
153
perm_buf = new double[size];
154
copy_buf = new double[size];
157
#ifdef NONDOUBLE_INTS
158
double* raw_data = copy_buf;
162
#ifdef NONDOUBLE_INTS
163
REALTYPE* target_ptr = build_eri[am1][am2][am3][am4](Libint,num_prim_comb);
165
raw_data[i] = (double) target_ptr[i];
167
double* raw_data = build_eri[am1][am2][am3][am4](Libint,num_prim_comb);
171
// Permute shells back, if necessary
172
if (!do_not_permute) {
173
int num_perm = (int) switch_bra_ket + (int) switch_bra + (int) switch_ket;
175
double *sbuf1, *sbuf2, *sbuf3;
176
double *tbuf1, *tbuf2, *tbuf3;
177
// in general, permutations will require careful orchestration of
178
// the utilization of the buffers. If no permutations are necessary -- just copy the data
180
for(int i=0; i<size; i++)
181
target[i] = raw_data[i];
183
// otherwise -- do the dance
184
else if (num_perm == 1) {
185
sbuf1 = sbuf2 = sbuf3 = raw_data;
186
tbuf1 = tbuf2 = tbuf3 = target;
188
else if (num_perm == 2) {
189
if (!switch_bra_ket) {
191
tbuf1 = sbuf2 = perm_buf;
194
else if (!switch_ket) {
196
tbuf1 = sbuf3 = perm_buf;
199
else if (!switch_bra) {
201
tbuf2 = sbuf3 = perm_buf;
205
else if (num_perm == 3) {
207
tbuf1 = sbuf2 = perm_buf;
208
tbuf2 = sbuf3 = raw_data;
212
// Note that the order of permutations is opposite to the order of shell index permutations
213
// at the beginning of this function
215
ijkl_to_jikl(sbuf1, tbuf1, nao[0], nao[1], nket);
217
switch_ij(inc1,inc2);
220
ijkl_to_ijlk(sbuf2, tbuf2, nbra, nao[2], nao[3]);
222
switch_ij(inc3,inc4);
224
if (switch_bra_ket) {
225
ijkl_to_klij(sbuf3, tbuf3, nbra, nket);
228
switch_ij(inc1, inc3);
229
switch_ij(inc2, inc4);
235
prim_data* prim_quartet = Libint->PrimQuartet;
236
for(int p=0;p<num_prim_comb;p++,prim_quartet++) {
237
temp += prim_quartet->F[0];
239
target[0] = (double) temp;