3
\brief Enter brief description of file here
12
#include<libipv1/ip_lib.h>
13
#include<libciomr/libciomr.h>
14
#include<libpsio/psio.h>
15
#include<libint/libint.h>
22
#include"quartet_data.h" /* From Default_Ints */
23
#include"norm_quartet.h"
26
#include"read_scf_opdm.h"
28
#include"taylor_fm_eval.h"
34
#include"shell_block_matrix.h"
38
extern pthread_mutex_t fock_mutex; /* Used to lock Fock matrices during update */
44
extern double ****Gskel, ****Gskel_o; /* Global skeleton Fock matrices, updated in critical sections */
45
void *hf_fock_thread(void *tnum_ptr)
47
const long int thread_num = (long int) tnum_ptr;
48
/*--- Various data structures ---*/
49
struct tebuf *tot_data; /* buffer for non-zero integrals */
50
struct shell_pair *sp_ij, *sp_kl, *sp_ik, *sp_il, *sp_jk, *sp_jl;
51
Libint_t Libint; /* Integrals library object */
52
htable_t htable; /* hashing table */
54
double_array_t fjt_table; /* table of auxiliary function F_m(u) for each primitive combination */
57
int total_te_count = 0;
58
int ij, kl, ik, jl, ijkl;
59
int ioffset, joffset, koffset, loffset;
65
int pkblock_end_index = -1;
66
int g, i, j, k, l, m, ii, jj, kk, ll;
68
int si; /* GCC compiler screwes up if static is left out */
69
int sj, sk, sl, si_g, sj_g;
70
int sii, sjj, skk, sll , slll;
74
int pii, pjj, pkk, pll;
75
int upk, num_unique_pk;
76
int usi_arr[3], usj_arr[3], usk_arr[3], usl_arr[3];
77
int *si_arr, *sj_arr, *sk_arr, *sl_arr, *key_arr;
78
int usii,usjj,uskk,usll,usi,usj,usk,usl;
79
int usi_eq_usj, usi_eq_usk, usi_eq_usl, usj_eq_usl, usk_eq_usj, usk_eq_usl;
80
int usij_eq_uskl, usik_eq_usjl, usil_eq_uskj;
81
int stab_i,stab_j,stab_k,stab_l,stab_ij,stab_kl;
82
int *R_list, *S_list, *T_list;
84
int dcr_ij, dcr_kl, dcr_ijkl;
85
int num_unique_quartets;
87
int max_num_unique_quartets;
88
int max_num_prim_comb;
91
int max_cart_class_size;
93
int bf_i, bf_j, bf_k, bf_l, so_i, so_j, so_k, so_l, s;
94
int np_i, np_j, np_k, np_l;
95
int ni, nj, nk, nl, li, lj;
98
int iimax, jjmax, kkmax, llmax;
99
int irrep, npi_ij, npi_kl, npi_ik, npi_jl, ind_offset;
101
int num_prim_comb, p;
102
PSI_INT_LEAST64 key, key1, key2, key3;
103
int new_quartet, htable_ptr, nstri;
104
PSI_INT_LEAST64 quartet_index;
107
double lambda_T = 0.5/Symmetry.nirreps;
110
double pkblock_end_value = 0.0;
113
double *qijkl_arr, *qikjl_arr, *qiljk_arr;
115
double fac1, fac2, fac3;
116
double ffac1, ffac2, ffac3;
117
double c1, c2, c3, c4;
119
double ****G, ****G_o; /* Shell-blocked skeleton G matrices from this thread */
122
init hashing table to store and retrieve quartet data
125
if (Symmetry.nirreps > 1)
126
init_htable( &htable, Symmetry.max_stab_index );
128
#ifndef USE_TAYLOR_FM
129
init_fjt_table(&fjt_table);
132
max_cart_class_size = (ioff[BasisSet.max_am])*
133
(ioff[BasisSet.max_am])*
134
(ioff[BasisSet.max_am])*
135
(ioff[BasisSet.max_am]);
136
max_num_unique_quartets = Symmetry.max_stab_index*
137
Symmetry.max_stab_index*
138
Symmetry.max_stab_index;
139
max_num_prim_comb = (BasisSet.max_num_prims*BasisSet.max_num_prims)*
140
(BasisSet.max_num_prims*BasisSet.max_num_prims);
141
/*--- init a LIBINT object ---*/
142
pthread_mutex_lock(&fock_mutex);
143
UserOptions.memory -= init_libint(&Libint,BasisSet.max_am-1,max_num_prim_comb);
144
pthread_mutex_unlock(&fock_mutex);
146
/*--- Allocate this thread's shell-blocked skeleton G's ---*/
147
G = init_shell_block_matrix();
148
if (UserOptions.reftype == rohf || UserOptions.reftype == uhf)
149
G_o = init_shell_block_matrix();
151
tot_data = (struct tebuf*) malloc(max_cart_class_size*sizeof(struct tebuf));
152
if (Symmetry.nirreps == 1) {
153
si_arr = (int *)malloc(sizeof(int)*3*max_num_unique_quartets);
154
sj_arr = (int *)malloc(sizeof(int)*3*max_num_unique_quartets);
155
sk_arr = (int *)malloc(sizeof(int)*3*max_num_unique_quartets);
156
sl_arr = (int *)malloc(sizeof(int)*3*max_num_unique_quartets);
158
key_arr = (int *)malloc(sizeof(int)*3*max_num_unique_quartets);
160
c1 = 1.0 - 0.5*UserOptions.hf_exch;
161
c2 = 1.0 - 0.25*UserOptions.hf_exch;
162
c3 = -0.5*UserOptions.hf_exch;
163
c4 = -0.25*UserOptions.hf_exch;
165
/*-------------------------------------------------
166
generate all unique shell quartets with ordering
167
suitable for building the PK-matrix
168
-------------------------------------------------*/
170
for (usii=0; usii<Symmetry.num_unique_shells; usii++)
171
for (usjj=0; usjj<=usii; usjj++)
172
for (uskk=0; uskk<=usjj; uskk++)
173
for (usll=0; usll<=uskk; usll++, quartet_index++){
175
/*--- Decide if this thread will do this ---*/
176
if ( quartet_index%UserOptions.num_threads != thread_num )
179
/*--- Decide what unique shell quartets out of (ij|kl), (ik|jl), and (il|jk) are unique
180
with respect to permutations ---*/
181
usi_arr[0] = usii; usj_arr[0] = usjj; usk_arr[0] = uskk; usl_arr[0] = usll;
182
if (usii == usjj && usii == uskk || usjj == uskk && usjj == usll)
184
else if (usii == uskk || usjj == usll) {
186
usi_arr[1] = usii; usj_arr[1] = uskk; usk_arr[1] = usjj; usl_arr[1] = usll;
188
else if (usjj == uskk) {
190
usi_arr[1] = usii; usj_arr[1] = usll; usk_arr[1] = usjj; usl_arr[1] = uskk;
192
else if (usii == usjj || uskk == usll) {
194
usi_arr[1] = usii; usj_arr[1] = uskk; usk_arr[1] = usjj; usl_arr[1] = usll;
198
usi_arr[1] = usii; usj_arr[1] = uskk; usk_arr[1] = usjj; usl_arr[1] = usll;
199
usi_arr[2] = usii; usj_arr[2] = usll; usk_arr[2] = usjj; usl_arr[2] = uskk;
203
for(upk=0;upk<num_unique_pk;upk++) {
204
/*--- For each combination of unique shells generate "petit list" of shells ---*/
205
usi = usi_arr[upk]; usj = usj_arr[upk]; usk = usk_arr[upk]; usl = usl_arr[upk];
207
si = Symmetry.us2s[usi];
208
sjj = Symmetry.us2s[usj];
209
skk = Symmetry.us2s[usk];
210
sll = Symmetry.us2s[usl];
211
total_am = BasisSet.shells[si].am+BasisSet.shells[sjj].am+BasisSet.shells[skk].am+BasisSet.shells[sll].am;
213
if (Symmetry.nirreps > 1) { /*--- Non-C1 symmetry case ---*/
214
/*--- Generate the petite list of shell quadruplets using DCD approach of Davidson ---*/
215
stab_i = Symmetry.atom_positions[BasisSet.shells[si].center-1];
216
stab_j = Symmetry.atom_positions[BasisSet.shells[sjj].center-1];
217
stab_k = Symmetry.atom_positions[BasisSet.shells[skk].center-1];
218
stab_l = Symmetry.atom_positions[BasisSet.shells[sll].center-1];
219
stab_ij = Symmetry.GnG[stab_i][stab_j];
220
stab_kl = Symmetry.GnG[stab_k][stab_l];
221
R_list = Symmetry.dcr[stab_i][stab_j];
222
S_list = Symmetry.dcr[stab_k][stab_l];
223
T_list = Symmetry.dcr[stab_ij][stab_kl];
224
fac1 = Symmetry.nirreps/
225
Symmetry.dcr_deg[Symmetry.GnG[stab_i][stab_j]][Symmetry.GnG[stab_k][stab_l]];
226
usi_eq_usj = (usi == usj);
227
usi_eq_usk = (usi == usk);
228
usi_eq_usl = (usi == usl);
229
usj_eq_usl = (usj == usl);
230
usk_eq_usj = (usk == usj);
231
usk_eq_usl = (usk == usl);
232
usij_eq_uskl = (INDEX(usi,usj) == INDEX(usk,usl));
233
usik_eq_usjl = (INDEX(usi,usk) == INDEX(usj,usl));
234
usil_eq_uskj = (INDEX(usi,usl) == INDEX(usk,usj));
243
for(dcr_ij=0;dcr_ij<Symmetry.dcr_dim[stab_i][stab_j];dcr_ij++){
245
sj = BasisSet.shells[sjj].trans_vec[R]-1;
246
for(dcr_ijkl=0;dcr_ijkl<Symmetry.dcr_dim[stab_ij][stab_kl];dcr_ijkl++){
247
T = T_list[dcr_ijkl];
248
sk = BasisSet.shells[skk].trans_vec[T]-1;
249
slll = BasisSet.shells[sll].trans_vec[T]-1;
250
for(dcr_kl=0;dcr_kl<Symmetry.dcr_dim[stab_k][stab_l];dcr_kl++) {
252
sl = BasisSet.shells[slll].trans_vec[S]-1;
254
/*----------------------------------------------------------
255
Obviously redundant or zero cases are be eliminated here!
256
Redundancies arise in DCD approach when usk == usl etc.
257
-------------------------------------------------------------*/
260
(BasisSet.shells[si].center!=BasisSet.shells[sj].center)||
261
(BasisSet.shells[sj].center!=BasisSet.shells[sk].center)||
262
(BasisSet.shells[sk].center!=BasisSet.shells[sl].center)) {
266
key1 = compute_key(si,sj,sk,sl);
267
key2 = compute_key(si,sk,sj,sl);
268
key3 = compute_key(si,sl,sk,sj);
269
new_quartet = put_entry(&htable,key1,si,sj,sk,sl,q4ijkl,0,0);
270
if (new_quartet > -1) {
271
key_arr[count] = new_quartet;
275
if ( (key1 == key3 && key3 != key2) ||
276
(key2 == key3 && key3 != key1) ||
277
(key2 != key3 && key1 != key3 && key2 != key1)) {
278
new_quartet = put_entry(&htable,key2,si,sk,sj,sl,0,q4ijkl,0);
279
if (new_quartet > -1) {
280
key_arr[count] = new_quartet;
285
if ( (key1 == key2 && key3 != key1) ||
286
(key2 != key3 && key1 != key3 && key1 != key2)) {
287
new_quartet = put_entry(&htable,key3,si,sl,sk,sj,0,0,q4ijkl);
288
if (new_quartet > -1) {
289
key_arr[count] = new_quartet;
296
} /* petite list is ready to be used */
300
(BasisSet.shells[si].center!=BasisSet.shells[sjj].center)||
301
(BasisSet.shells[sjj].center!=BasisSet.shells[skk].center)||
302
(BasisSet.shells[skk].center!=BasisSet.shells[sll].center)) {
311
num_unique_quartets = count;
312
if (count > 3*max_num_unique_quartets)
313
throw std::domain_error("Problem with hashing?");
315
/*----------------------------------
316
Compute the nonredundant quartets
317
----------------------------------*/
318
for(plquartet=0;plquartet<num_unique_quartets;plquartet++) {
319
if (Symmetry.nirreps == 1) {
320
si = si_arr[plquartet];
321
sj = sj_arr[plquartet];
322
sk = sk_arr[plquartet];
323
sl = sl_arr[plquartet];
324
dmax = MAX(BasisSet.shell_pairs[si][sj].Dmax, BasisSet.shell_pairs[sk][sl].Dmax);
325
dmax = MAX(dmax, 0.25*BasisSet.shell_pairs[si][sk].Dmax);
326
dmax = MAX(dmax, 0.25*BasisSet.shell_pairs[si][sl].Dmax);
327
dmax = MAX(dmax, 0.25*BasisSet.shell_pairs[sj][sk].Dmax);
328
dmax = MAX(dmax, 0.25*BasisSet.shell_pairs[sj][sl].Dmax);
329
if (BasisSet.schwartz_eri[si][sj]*BasisSet.schwartz_eri[sk][sl]*dmax < UserOptions.cutoff)
332
fac1 = fac2 = fac3 = 1.0;
345
if (INDEX(si,sj) == INDEX(sk,sl))
347
if (INDEX(si,sk) == INDEX(sj,sl))
349
if (INDEX(si,sl) == INDEX(sj,sk))
353
htable_ptr = key_arr[plquartet];
354
if (htable_ptr >= htable.size || htable_ptr < 0)
355
throw std::domain_error("Problem with hashing?");
356
htable.table[htable_ptr].key = EMPTY_KEY;
357
si = htable.table[htable_ptr].si;
358
sj = htable.table[htable_ptr].sj;
359
sk = htable.table[htable_ptr].sk;
360
sl = htable.table[htable_ptr].sl;
361
dmax = MAX(BasisSet.shell_pairs[si][sj].Dmax, BasisSet.shell_pairs[sk][sl].Dmax);
362
dmax = MAX(dmax, 0.25*BasisSet.shell_pairs[si][sk].Dmax);
363
dmax = MAX(dmax, 0.25*BasisSet.shell_pairs[si][sl].Dmax);
364
dmax = MAX(dmax, 0.25*BasisSet.shell_pairs[sj][sk].Dmax);
365
dmax = MAX(dmax, 0.25*BasisSet.shell_pairs[sj][sl].Dmax);
366
if (BasisSet.schwartz_eri[si][sj]*BasisSet.schwartz_eri[sk][sl]*dmax < UserOptions.cutoff)
369
fac1 = htable.table[htable_ptr].q4ijkl;
370
fac2 = htable.table[htable_ptr].q4ikjl;
371
fac3 = htable.table[htable_ptr].q4ilkj;
372
if (si == sj && si == sk ||
373
sj == sk && sj == sl ||
374
si == sj && si == sl ||
375
si == sk && si == sl) {
378
else if (si == sk || sj == sl) {
379
fac1 = fac3 = (fac1 + fac3);
381
else if (sj == sk || si == sl) {
382
fac1 = fac2 = (fac1 + fac2);
384
else if (si == sj || sk == sl) {
385
fac3 = fac2 = (fac3 + fac2);
390
if (si < 0 || si >= BasisSet.num_shells)
391
throw std::domain_error("Problem with shell indices");
392
if (sj < 0 || sj >= BasisSet.num_shells)
393
throw std::domain_error("Problem with shell indices");
394
if (sk < 0 || sk >= BasisSet.num_shells)
395
throw std::domain_error("Problem with shell indices");
396
if (sl < 0 || sl >= BasisSet.num_shells)
397
throw std::domain_error("Problem with shell indices");
400
/* place in "ascending" angular mom-
401
my simple way of optimizing PHG recursion (VRR) */
402
/* these first two are good for the HRR */
403
if(BasisSet.shells[si].am < BasisSet.shells[sj].am){
411
if(BasisSet.shells[sk].am < BasisSet.shells[sl].am){
419
/* this should be /good/ for the VRR */
420
if(BasisSet.shells[si].am + BasisSet.shells[sj].am >
421
BasisSet.shells[sk].am + BasisSet.shells[sl].am){
429
ioffset = BasisSet.shells[si].fao - 1;
430
joffset = BasisSet.shells[sj].fao - 1;
431
koffset = BasisSet.shells[sk].fao - 1;
432
loffset = BasisSet.shells[sl].fao - 1;
433
ni = ioff[BasisSet.shells[si].am];
434
nj = ioff[BasisSet.shells[sj].am];
435
nk = ioff[BasisSet.shells[sk].am];
436
nl = ioff[BasisSet.shells[sl].am];
437
np_i = BasisSet.shells[si].n_prims;
438
np_j = BasisSet.shells[sj].n_prims;
439
np_k = BasisSet.shells[sk].n_prims;
440
np_l = BasisSet.shells[sl].n_prims;
441
orig_am[0] = BasisSet.shells[si].am-1;
442
orig_am[1] = BasisSet.shells[sj].am-1;
443
orig_am[2] = BasisSet.shells[sk].am-1;
444
orig_am[3] = BasisSet.shells[sl].am-1;
445
am = orig_am[0] + orig_am[1] + orig_am[2] + orig_am[3];
447
sp_ij = &(BasisSet.shell_pairs[si][sj]);
448
sp_kl = &(BasisSet.shell_pairs[sk][sl]);
449
sp_ik = &(BasisSet.shell_pairs[si][sk]);
450
sp_il = &(BasisSet.shell_pairs[si][sl]);
451
sp_jk = &(BasisSet.shell_pairs[sj][sk]);
452
sp_jl = &(BasisSet.shell_pairs[sj][sl]);
453
Libint.AB[0] = sp_ij->AB[0];
454
Libint.AB[1] = sp_ij->AB[1];
455
Libint.AB[2] = sp_ij->AB[2];
456
Libint.CD[0] = sp_kl->AB[0];
457
Libint.CD[1] = sp_kl->AB[1];
458
Libint.CD[2] = sp_kl->AB[2];
460
AB2 = Libint.AB[0]*Libint.AB[0]+
461
Libint.AB[1]*Libint.AB[1]+
462
Libint.AB[2]*Libint.AB[2];
463
CD2 = Libint.CD[0]*Libint.CD[0]+
464
Libint.CD[1]*Libint.CD[1]+
465
Libint.CD[2]*Libint.CD[2];
467
/*--- Compute data for primitive quartets here ---*/
469
for (pi = 0; pi < np_i; pi++) {
470
max_pj = (si == sj) ? pi+1 : np_j;
471
for (pj = 0; pj < max_pj; pj++) {
472
m = (1 + (si == sj && pi != pj));
473
for (pk = 0; pk < np_k; pk++) {
474
max_pl = (sk == sl) ? pk+1 : np_l;
475
for (pl = 0; pl < max_pl; pl++){
476
n = m * (1 + (sk == sl && pk != pl));
478
quartet_data(&(Libint.PrimQuartet[num_prim_comb++]), NULL, AB2, CD2,
479
sp_ij, sp_kl, am, pi, pj, pk, pl, n*lambda_T);
481
quartet_data(&(Libint.PrimQuartet[num_prim_comb++]), &fjt_table, AB2, CD2,
482
sp_ij, sp_kl, am, pi, pj, pk, pl, n*lambda_T);
489
/*-----------------------------------------------------
490
Compute the quartet and compute its contributions to
491
appropriate blocks of Gsh and Gsh_o
492
-----------------------------------------------------*/
494
data = build_eri[orig_am[0]][orig_am[1]][orig_am[2]][orig_am[3]](&Libint,num_prim_comb);
495
/* zero here means no transformation to puream basis */
497
data = norm_quartet(data, NULL, orig_am, 0);
499
/*--- Here just put non-redundant integrals to tot_data ---*/
501
if(si==sj && sk==sl && si==sk) {
503
for(ii=0; ii <= iimax; ii++){
505
for(jj=0; jj <= jjmax; jj++){
507
for(kk=0; kk <= kkmax; kk++){
508
llmax = (kk==ii)? jj : kk ;
509
for(ll=0; ll <= llmax; ll++){
510
ijkl = ll+nl*(kk+nk*(jj+nj*ii));
511
/* if (fabs(data[ijkl])>UserOptions.cutoff) {*/
512
tot_data[num].i = (short int) ii;
513
tot_data[num].j = (short int) jj;
514
tot_data[num].k = (short int) kk;
515
tot_data[num].l = (short int) ll;
516
tot_data[num].val = data[ijkl];
524
else if(si==sk && sj==sl){
526
for(ii=0; ii <= iimax; ii++){
528
for(jj=0; jj <= jjmax; jj++){
530
for(kk=0; kk <= kkmax; kk++){
531
llmax = (kk==ii)? jj : nl - 1;
532
for(ll=0; ll <= llmax; ll++){
533
ijkl = ll+nl*(kk+nk*(jj+nj*ii));
534
/* if(fabs(data[ijkl])>UserOptions.cutoff){*/
535
tot_data[num].i = (short int) ii;
536
tot_data[num].j = (short int) jj;
537
tot_data[num].k = (short int) kk;
538
tot_data[num].l = (short int) ll;
539
tot_data[num].val = data[ijkl];
550
for(ii=0; ii <= iimax; ii++){
551
jjmax = (si == sj) ? ii : nj - 1;
552
for(jj=0; jj <= jjmax; jj++){
553
for(kk=0; kk <= kkmax; kk++){
554
llmax = (sk == sl) ? kk : nl - 1;
555
for(ll=0; ll <= llmax; ll++){
556
ijkl = ll+nl*(kk+nk*(jj+nj*ii));
557
/* if(fabs(data[ijkl])>UserOptions.cutoff){*/
558
tot_data[num].i = (short int) ii;
559
tot_data[num].j = (short int) jj;
560
tot_data[num].k = (short int) kk;
561
tot_data[num].l = (short int) ll;
562
tot_data[num].val = data[ijkl];
574
for(p=0;p<num_prim_comb;p++)
575
temp += Libint.PrimQuartet[p].F[0];
577
tot_data[0].i = tot_data[0].j = tot_data[0].k = tot_data[0].l = 0;
578
tot_data[0].val = temp;
580
/* if (fabs(temp) > UserOptions.cutoff)*/
585
total_te_count += num;
587
if (UserOptions.reftype == rhf) {
597
temp = tot_data[n].val;
602
if (ii != jj && si == sj)
604
if (kk != ll && sk == sl)
606
if (ii != kk && si == sk)
608
if (jj != ll && sj == sl)
610
if (ii != ll && si == sl)
612
if (jj != kk && sj == sk)
614
if (INDEX(ii,jj) != INDEX(kk,ll) &&
615
INDEX(si,sj) == INDEX(sk,sl))
617
if (INDEX(ii,kk) != INDEX(jj,ll) &&
618
INDEX(si,sk) == INDEX(sj,sl))
620
if (INDEX(ii,ll) != INDEX(jj,kk) &&
621
INDEX(si,sl) == INDEX(sj,sk))
624
if (ii == jj && ii == kk ||
625
jj == kk && jj == ll ||
626
ii == jj && ii == ll ||
627
ii == kk && ii == ll) {
628
G[si][sj][i][j] += sp_kl->dmat[k][l]*(c1*ffac1);
629
G[sk][sl][k][l] += sp_ij->dmat[i][j]*(c1*ffac1);
631
else if (ii == kk || jj == ll) {
632
G[si][sj][i][j] += sp_kl->dmat[k][l]*(c2*ffac1);
633
G[sk][sl][k][l] += sp_ij->dmat[i][j]*(c2*ffac1);
634
G[si][sk][i][k] += sp_jl->dmat[j][l]*(c3*ffac2);
635
G[sj][sl][j][l] += sp_ik->dmat[i][k]*(c3*ffac2);
637
else if (jj == kk || ii == ll) {
638
G[si][sj][i][j] += sp_kl->dmat[k][l]*(c2*ffac1);
639
G[sk][sl][k][l] += sp_ij->dmat[i][j]*(c2*ffac1);
640
G[si][sl][i][l] += sp_jk->dmat[j][k]*(c3*ffac3);
641
G[sj][sk][j][k] += sp_il->dmat[i][l]*(c3*ffac3);
643
else if (ii == jj || kk == ll) {
644
G[si][sj][i][j] += sp_kl->dmat[k][l]*(ffac1);
645
G[sk][sl][k][l] += sp_ij->dmat[i][j]*(ffac1);
646
G[si][sk][i][k] += sp_jl->dmat[j][l]*(c4*ffac2);
647
G[sj][sl][j][l] += sp_ik->dmat[i][k]*(c4*ffac2);
650
G[si][sj][i][j] += sp_kl->dmat[k][l]*(ffac1);
651
G[sk][sl][k][l] += sp_ij->dmat[i][j]*(ffac1);
652
G[si][sk][i][k] += sp_jl->dmat[j][l]*(c4*ffac2);
653
G[sj][sl][j][l] += sp_ik->dmat[i][k]*(c4*ffac2);
654
G[si][sl][i][l] += sp_jk->dmat[j][k]*(c4*ffac3);
655
G[sj][sk][j][k] += sp_il->dmat[i][l]*(c4*ffac3);
659
else if (UserOptions.reftype == uhf || UserOptions.reftype == rohf) {
669
temp = tot_data[n].val;
674
if (ii != jj && si == sj)
676
if (kk != ll && sk == sl)
678
if (ii != kk && si == sk)
680
if (jj != ll && sj == sl)
682
if (ii != ll && si == sl)
684
if (jj != kk && sj == sk)
686
if (INDEX(ii,jj) != INDEX(kk,ll) &&
687
INDEX(si,sj) == INDEX(sk,sl))
689
if (INDEX(ii,kk) != INDEX(jj,ll) &&
690
INDEX(si,sk) == INDEX(sj,sl))
692
if (INDEX(ii,ll) != INDEX(jj,kk) &&
693
INDEX(si,sl) == INDEX(sj,sk))
696
if (ii == jj && ii == kk ||
697
jj == kk && jj == ll ||
698
ii == jj && ii == ll ||
699
ii == kk && ii == ll) {
700
G[si][sj][i][j] += sp_kl->dmat[k][l]*(c1*ffac1);
701
G[sk][sl][k][l] += sp_ij->dmat[i][j]*(c1*ffac1);
702
G_o[si][sj][i][j] -= sp_kl->dmato[k][l]*(c3*ffac1);
703
G_o[sk][sl][k][l] -= sp_ij->dmato[i][j]*(c3*ffac1);
705
else if (ii == kk || jj == ll) {
706
G[si][sj][i][j] += sp_kl->dmat[k][l]*(c2*ffac1);
707
G[sk][sl][k][l] += sp_ij->dmat[i][j]*(c2*ffac1);
708
G[si][sk][i][k] += sp_jl->dmat[j][l]*(c3*ffac2);
709
G[sj][sl][j][l] += sp_ik->dmat[i][k]*(c3*ffac2);
710
G_o[si][sj][i][j] -= sp_kl->dmato[k][l]*(c4*ffac1);
711
G_o[sk][sl][k][l] -= sp_ij->dmato[i][j]*(c4*ffac1);
712
G_o[si][sk][i][k] -= sp_jl->dmato[j][l]*(c3*ffac2);
713
G_o[sj][sl][j][l] -= sp_ik->dmato[i][k]*(c3*ffac2);
715
else if (jj == kk || ii == ll) {
716
G[si][sj][i][j] += sp_kl->dmat[k][l]*(c2*ffac1);
717
G[sk][sl][k][l] += sp_ij->dmat[i][j]*(c2*ffac1);
718
G[si][sl][i][l] += sp_jk->dmat[j][k]*(c3*ffac3);
719
G[sj][sk][j][k] += sp_il->dmat[i][l]*(c3*ffac3);
720
G_o[si][sj][i][j] -= sp_kl->dmato[k][l]*(c4*ffac1);
721
G_o[sk][sl][k][l] -= sp_ij->dmato[i][j]*(c4*ffac1);
722
G_o[si][sl][i][l] -= sp_jk->dmato[j][k]*(c3*ffac3);
723
G_o[sj][sk][j][k] -= sp_il->dmato[i][l]*(c3*ffac3);
725
else if (ii == jj || kk == ll) {
726
G[si][sj][i][j] += sp_kl->dmat[k][l]*ffac1;
727
G[sk][sl][k][l] += sp_ij->dmat[i][j]*ffac1;
728
G[si][sk][i][k] += sp_jl->dmat[j][l]*(c4*ffac2);
729
G[sj][sl][j][l] += sp_ik->dmat[i][k]*(c4*ffac2);
730
G_o[si][sk][i][k] -= sp_jl->dmato[j][l]*(c4*ffac2);
731
G_o[sj][sl][j][l] -= sp_ik->dmato[i][k]*(c4*ffac2);
734
G[si][sj][i][j] += sp_kl->dmat[k][l]*ffac1;
735
G[sk][sl][k][l] += sp_ij->dmat[i][j]*ffac1;
736
G[si][sk][i][k] += sp_jl->dmat[j][l]*(c4*ffac2);
737
G[sj][sl][j][l] += sp_ik->dmat[i][k]*(c4*ffac2);
738
G[si][sl][i][l] += sp_jk->dmat[j][k]*(c4*ffac3);
739
G[sj][sk][j][k] += sp_il->dmat[i][l]*(c4*ffac3);
740
G_o[si][sk][i][k] -= sp_jl->dmato[j][l]*(c4*ffac2);
741
G_o[sj][sl][j][l] -= sp_ik->dmato[i][k]*(c4*ffac2);
742
G_o[si][sl][i][l] -= sp_jk->dmato[j][k]*(c4*ffac3);
743
G_o[sj][sk][j][k] -= sp_il->dmato[i][l]*(c4*ffac3);
748
} /* end of computing "petit" list */
749
} /* end getting unique shell combination */
751
pthread_mutex_lock(&fock_mutex);
753
for(si=0;si<BasisSet.num_shells;si++) {
754
ni = ioff[BasisSet.shells[si].am];
755
for(sj=0;sj<BasisSet.num_shells;sj++) {
756
nj = ioff[BasisSet.shells[sj].am];
759
Gskel[si][sj][i][j] += G[si][sj][i][j];
762
if (UserOptions.reftype == rohf || UserOptions.reftype == uhf)
763
for(si=0;si<BasisSet.num_shells;si++) {
764
ni = ioff[BasisSet.shells[si].am];
765
for(sj=0;sj<BasisSet.num_shells;sj++) {
766
nj = ioff[BasisSet.shells[sj].am];
769
Gskel_o[si][sj][i][j] += G_o[si][sj][i][j];
773
pthread_mutex_unlock(&fock_mutex);
779
free_shell_block_matrix(G);
780
if (UserOptions.reftype == rohf || UserOptions.reftype == uhf) {
781
free_shell_block_matrix(G_o);
783
if (Symmetry.nirreps > 1) {
784
free_htable(&htable);
786
free_libint(&Libint);
788
if (Symmetry.nirreps == 1) {
796
#ifndef USE_TAYLOR_FM
797
free_fjt_table(&fjt_table);