3
\brief Enter brief description of file here
9
#include <libciomr/libciomr.h>
14
namespace psi { namespace detci {
16
extern int calc_orb_diff(int cnt, unsigned char *I, unsigned char *J,
17
int *I_alpha_diff, int *J_alpha_diff, int *sign, int *same, int extended);
20
/* C "GLOBAL" VARIABLES FOR THIS MODULE */
21
extern struct stringwr **alplist;
22
extern struct stringwr **betlist;
25
#define MIN0(a,b) (((a)<(b)) ? (a) : (b))
26
#define MAX0(a,b) (((a)>(b)) ? (a) : (b))
30
** calc_hd_block(): Function calculates a block of H0, the diagonal elements of
31
** the Hamiltonian matrix.
34
** alplist_local = list of alpha strings with replacements (used to get occs)
35
** betlist_local = list of beta strings with replacements
36
** nas = number of alpha strings in list
37
** nbs = number of beta strings in list
38
** H0 = matrix to hold results (stored as H0[alpidx][betidx])
39
** oei = one-electron integrals
40
** tei = two-electron integrals
41
** na = number of explicit alpha electrons
42
** nb = number of explicit beta electrons
43
** nbf = number of orbitals in CI
44
** efzc = frozen core energy
47
void calc_hd_block(struct stringwr *alplist_local, struct stringwr *betlist_local,
48
double **H0, double *oei, double *tei, double efzc,
49
int nas, int nbs, int na, int nb, int nbf)
53
int i,j, ii, iii, jj, ij, iijj, ijij;
55
struct stringwr *betlist0;
57
betlist0 = betlist_local;
59
for (acnt=0; acnt<nas; acnt++) {
61
for (bcnt=0, betlist_local=betlist0; bcnt<nbs; bcnt++) {
63
/* add frozen core energy first */
64
/************************************************/
67
/* loop over alpha occs */
68
for (a1=0; a1<na; a1++) {
69
i = (int) alplist_local->occs[a1];
72
/* fprintf(outfile,"oei[%d] = %lf\n",ii,oei[ii]); */
75
for (a2=0; a2<a1; a2++) {
76
j = (int) alplist_local->occs[a2];
81
value += tei[iijj] - tei[ijij];
84
for (b1=0; b1<nb; b1++) {
85
j = (int) betlist_local->occs[b1];
87
iijj = ioff[MAX0(ii,jj)] + MIN0(ii,jj);
92
for (b1=0; b1<nb; b1++) {
93
i = (int) betlist_local->occs[b1];
98
for (b2=0; b2<b1; b2++) {
99
j = (int) betlist_local->occs[b2];
103
ijij = ioff[ij] + ij;
104
value += tei[iijj] - tei[ijij];
108
H0[acnt][bcnt] = value;
110
fprintf(outfile,"H0[%d][%d] = %lf\n",acnt,bcnt,value);
113
} /* end loop over bcnt */
120
** calc_hd_block_ave(): Function calculates a block of H0 and the diagonal elements
121
** of the Hamiltonian matrix averaged over spin-coupling sets to correct any
122
** spin contamination of the c and sigma vectors.
125
** alplist_local = list of alpha strings with replacements (used to get occs)
126
** betlist_local = list of beta strings with replacements
127
** nas = number of alpha strings in list
128
** nbs = number of beta strings in list
129
** H0 = matrix to hold results (stored as H0[alpidx][betidx])
130
** oei = one-electron integrals
131
** tei = two-electron integrals
132
** na = number of explicit alpha electrons
133
** nb = number of explicit beta electrons
134
** nbf = number of orbitals in CI
135
** efzc = frozen core energy
138
void calc_hd_block_ave(struct stringwr *alplist_local, struct stringwr *betlist_local,
139
double **H0, double *tf_oei, double *tei, double efzc,
140
int nas, int nbs, int na, int nb, int nbf)
143
int a1, a2, a3, b1, b2, b3;
144
int i,j, ii, iii, jj, ij, iijj, ijij;
145
double value, tval, tval2, Kave;
146
struct stringwr *betlist0;
147
double k_total; /* total number of K ints in energy expression */
148
int k_combo; /* total combination of unique K ints over spin-coupling set */
149
int *unique_occs; /* the uniquely occupied orbitals for a given determinant */
150
int num_el; /* total number of electrons explicitly treated */
151
int num_unique; /* number of unique orbitals */
152
betlist0 = betlist_local;
155
k_total = combinations(na,2) + combinations(nb,2);
158
unique_occs = init_int_array(num_el);
160
for (acnt=0; acnt<nas; acnt++) {
162
for (bcnt=0, betlist_local=betlist0; bcnt<nbs; bcnt++) {
164
/* add frozen core energy first */
167
/* loop over alpha occs */
168
for (a1=0; a1<na; a1++) {
169
i = (int) alplist_local->occs[a1];
171
/* h_ii bar alpha alpha */
173
/* fprintf(outfile,"tf_oei[%d] = %lf\n",ii,tf_oei[ii]); */
176
/* loop over alpha occs */
177
for (a2=0; a2<a1; a2++) {
178
j = (int) alplist_local->occs[a2];
185
/* loop over beta occs */
186
for (b1=0; b1<nb; b1++) {
187
j = (int) betlist_local->occs[b1];
189
iijj = ioff[MAX0(ii,jj)] + MIN0(ii,jj);
194
/* loop over beta occs */
195
for (b1=0; b1<nb; b1++) {
196
i = (int) betlist_local->occs[b1];
199
/* fprintf(outfile,"tf_oei[%d] = %lf\n",ii,tf_oei[ii]); */
202
/* loop over beta occs */
203
for (b2=0; b2<b1; b2++) {
204
j = (int) betlist_local->occs[b2];
208
ijij = ioff[ij] + ij;
213
/* determine average K over spin-coupling set */
215
for (a1=0; a1<na; a1++) unique_occs[num_unique++] = (int) alplist_local->occs[a1];
216
/* for (j=0; j<num_unique; j++)
217
fprintf(outfile,"unique_occs[%d] = %d\n",j,unique_occs[j]); */
218
for (b1=0; b1<nb; b1++) {
219
j = (int) betlist_local->occs[b1];
220
for (a1=0; a1<na; a1++) {
221
if (j==unique_occs[a1]) break;
222
if (a1==(na-1)) unique_occs[num_unique++] = j;
225
/* fprintf(outfile,"num_unique = %d\n",num_unique);
226
fprintf(outfile,"num_el = %d\n",num_el);
228
if (num_unique>num_el) fprintf(outfile,"WARNING: The number of explicit electrons" \
233
fprintf(outfile,"alp_occs[%d] = %d\n",j,(int)alplist_local->occs[j]);
235
fprintf(outfile,"bet_occs[%d] = %d\n",j,(int)betlist_local->occs[j]);
236
for (j=0; j<num_unique; j++)
237
fprintf(outfile,"unique_occs[%d] = %d\n",j,unique_occs[j]);
241
for (a1=0; a1<num_unique; a1++) {
243
for (b1=0; b1<a1; b1++) {
245
ij = ioff[MAX0(i,j)] + MIN0(i,j);
246
ijij = ioff[ij] + ij;
248
/* fprintf(outfile,"tei[%d] = %lf\n",ijij,tei[ijij]); */
252
/* fprintf(outfile,"num_unique = %d\n",num_unique);
253
fprintf(outfile,"ioff[num_unique-1] = %d\n",ioff[num_unique]);
254
fprintf(outfile,"k_total = %d\n",k_total);
257
if (num_unique > 1) Kave /= ioff[num_unique-1];
258
value -= 0.5 * Kave * k_total;
259
/* fprintf(outfile,"Kave = %lf\n",Kave); */
261
if (Parameters.print_lvl > 5) {
262
fprintf(outfile,"acnt = %d\t bcnt = %d\n",acnt,bcnt);
263
fprintf(outfile,"tval = %lf\n",tval);
264
for(a1=0; a1<na; a1++)
265
fprintf(outfile," %d",alplist_local->occs[a1]);
266
fprintf(outfile," \n");
267
for(b1=0; b1<nb; b1++)
268
fprintf(outfile," %d",betlist_local->occs[b1]);
269
fprintf(outfile," \n");
272
H0[acnt][bcnt] = value;
273
/* fprintf(outfile,"H0[%d][%d] = %lf\n",acnt,bcnt,value); */
275
} /* end loop over bcnt */
283
** calc_hd_block_orbenergy(): Function calculates a block of H0 and the diagonal elements
284
** of the Hamiltonian matrix as the sum of orbital energies.
287
** alplist_local = list of alpha strings with replacements (used to get occs)
288
** betlist_local = list of beta strings with replacements
289
** nas = number of alpha strings in list
290
** nbs = number of beta strings in list
291
** H0 = matrix to hold results (stored as H0[alpidx][betidx])
292
** oei = one-electron integrals
293
** tei = two-electron integrals
294
** na = number of explicit alpha electrons
295
** nb = number of explicit beta electrons
296
** nbf = number of orbitals in CI
297
** efzc = frozen core energy
300
void calc_hd_block_orbenergy(struct stringwr *alplist_local,
301
struct stringwr *betlist_local, double **H0, double *oei,
302
double *tei, double efzc, int nas, int nbs, int na, int nb, int nbf)
307
struct stringwr *betlist0, *alplist0;
308
double *orb_e_diff_alp, *orb_e_diff_bet;
309
double sum_orb_energies = 0.0;
311
betlist0 = betlist_local;
312
alplist0 = alplist_local;
314
orb_e_diff_alp = init_array(nas);
315
orb_e_diff_bet = init_array(nbs);
316
/* if (Parameters.Ms0) orb_e_diff_bet = &orb_e_diff_alp;
317
else orb_e_diff_bet = init_array(CalcInfo.num_bet_str);
320
for (acnt=0; acnt<nas; acnt++) {
321
orb_e_diff_alp[acnt] = 0.0;
322
for (a1=0; a1<na; a1++) {
323
i = (int) alplist_local->occs[a1];
324
i += CalcInfo.num_fzc_orbs;
326
orb_e_diff_alp[acnt] += CalcInfo.scfeigvala[i];
328
orb_e_diff_alp[acnt] += CalcInfo.scfeigval[i];
333
for (bcnt=0; bcnt<nbs; bcnt++) {
334
orb_e_diff_bet[bcnt] = 0.0;
335
for (b1=0; b1<nb; b1++) {
336
j = (int) betlist_local->occs[b1];
337
j += CalcInfo.num_fzc_orbs;
339
orb_e_diff_bet[bcnt] += CalcInfo.scfeigvalb[j];
341
orb_e_diff_bet[bcnt] += CalcInfo.scfeigval[j];
346
alplist_local = alplist0;
347
betlist_local = betlist0;
349
for (acnt=0; acnt<nas; acnt++) {
350
tval = efzc + orb_e_diff_alp[acnt];
351
for (bcnt=0; bcnt<nbs; bcnt++) {
352
value = orb_e_diff_bet[bcnt] + tval;
353
H0[acnt][bcnt] = value;
355
fprintf(outfile,"H0[%d][%d] = %lf\n",acnt,bcnt,value);
358
} /* end loop over bcnt */
363
free(orb_e_diff_alp);
364
free(orb_e_diff_bet);
370
** calc_hd_block_evangelisti(): Function calculates a block of H0 and the diagonal elements
371
** of the Hamiltonian matrix averaged over spin-coupling sets to correct any
372
** spin contamination of the c and sigma vectors.
375
** alplist_local = list of alpha strings with replacements (used to get occs)
376
** betlist_local = list of beta strings with replacements
377
** nas = number of alpha strings in list
378
** nbs = number of beta strings in list
379
** H0 = matrix to hold results (stored as H0[alpidx][betidx])
380
** oei = one-electron integrals
381
** tei = two-electron integrals
382
** na = number of explicit alpha electrons
383
** nb = number of explicit beta electrons
384
** nbf = number of orbitals in CI
385
** efzc = frozen core energy
388
void calc_hd_block_evangelisti(struct stringwr *alplist_local, struct stringwr *betlist_local,
389
double **H0, double *tf_oei, double *tei, double efzc,
390
int nas, int nbs, int na, int nb, int nbf)
395
struct stringwr *betlist0, *alplist0;
396
double *orb_e_diff_alp, *orb_e_diff_bet;
397
int num_alp_diff, num_bet_diff;
398
int **orb_diff, *jnk;
401
betlist0 = betlist_local;
402
alplist0 = alplist_local;
404
orb_diff = init_int_matrix(2,na);
405
jnk = init_int_array(na);
406
orb_e_diff_alp = init_array(nas);
407
orb_e_diff_bet = init_array(nbs);
409
for (acnt=0; acnt<nas; acnt++) {
410
orb_e_diff_alp[acnt] = 0.0;
411
num_alp_diff = calc_orb_diff(na,
412
alplist[CalcInfo.ref_alp_list][CalcInfo.ref_alp_rel].occs,
413
alplist_local->occs, orb_diff[0], orb_diff[1], &sign,
415
for (a1=0; a1<num_alp_diff; a1++) {
418
i += CalcInfo.num_fzc_orbs;
419
j += CalcInfo.num_fzc_orbs;
420
orb_e_diff_alp[acnt] += CalcInfo.scfeigval[j]
421
- CalcInfo.scfeigval[i];
426
for (bcnt=0; bcnt<nbs; bcnt++) {
427
orb_e_diff_bet[bcnt] = 0.0;
428
num_bet_diff = calc_orb_diff(nb,
429
betlist[CalcInfo.ref_bet_list][CalcInfo.ref_bet_rel].occs,
430
betlist_local->occs, orb_diff[0], orb_diff[1], &sign,
432
for (b1=0; b1<num_bet_diff; b1++) {
435
i += CalcInfo.num_fzc_orbs;
436
j += CalcInfo.num_fzc_orbs;
437
orb_e_diff_bet[bcnt] += CalcInfo.scfeigval[j]
438
- CalcInfo.scfeigval[i];
443
alplist_local = alplist0;
444
betlist_local = betlist0;
446
for (acnt=0; acnt<nas; acnt++) {
447
/* add frozen core energy first */
448
tval = CalcInfo.escf - CalcInfo.enuc;
449
tval += orb_e_diff_alp[acnt];
450
for (bcnt=0; bcnt<nbs; bcnt++) {
452
value = orb_e_diff_bet[bcnt] + tval;
453
H0[acnt][bcnt] = value;
454
/* fprintf(outfile,"H0[%d][%d] = %lf\n",acnt,bcnt,value); */
456
} /* end loop over bcnt */
463
free(orb_e_diff_alp);
464
free(orb_e_diff_bet);
473
** calc_hd_block_mll(): Function calculates a block of H0 and the diagonal elements
474
** of the Hamiltonian matrix as the sum of orbital energies.
477
** alplist_local = list of alpha strings with replacements (used to get occs)
478
** betlist_local = list of beta strings with replacements
479
** nas = number of alpha strings in list
480
** nbs = number of beta strings in list
481
** H0 = matrix to hold results (stored as H0[alpidx][betidx])
482
** oei = one-electron integrals
483
** tei = two-electron integrals
484
** na = number of explicit alpha electrons
485
** nb = number of explicit beta electrons
486
** nbf = number of orbitals in CI
487
** efzc = frozen core energy
490
void calc_hd_block_mll(struct stringwr *alplist_local,
491
struct stringwr *betlist_local, double **H0, double *oei,
492
double *tei, double efzc, int nas, int nbs, int na, int nb, int nbf)
495
int a1, b1, i,j, i_offset, j_offset, ii, jj;
497
struct stringwr *betlist0, *alplist0;
498
double *orb_e_diff_alp, *orb_e_diff_bet;
499
double *oei_alp, *oei_bet, *eigval;
501
betlist0 = betlist_local;
502
alplist0 = alplist_local;
504
oei_alp = init_array(nas);
505
oei_bet = init_array(nbs);
506
orb_e_diff_alp = init_array(nas);
507
orb_e_diff_bet = init_array(nbs);
508
/* if (Parameters.Ms0) orb_e_diff_bet = &orb_e_diff_alp;
509
else orb_e_diff_bet = init_array(nbs);
512
for (acnt=0; acnt<nas; acnt++) {
513
orb_e_diff_alp[acnt] = oei_alp[acnt] = 0.0;
514
for (a1=0; a1<na; a1++) {
515
i = (int) alplist_local->occs[a1];
517
i_offset = i + CalcInfo.num_fzc_orbs;
518
oei_alp[acnt] += oei[ii];
519
orb_e_diff_alp[acnt] += CalcInfo.scfeigval[i_offset] - oei[ii];
524
for (bcnt=0; bcnt<nbs; bcnt++) {
525
orb_e_diff_bet[bcnt] = oei_bet[bcnt] = 0.0;
526
for (b1=0; b1<nb; b1++) {
527
j = (int) betlist_local->occs[b1];
529
j_offset = j + CalcInfo.num_fzc_orbs;
530
oei_bet[bcnt] += oei[jj];
531
orb_e_diff_bet[bcnt] += CalcInfo.scfeigval[j_offset] - oei[jj];
536
alplist_local = alplist0;
537
betlist_local = betlist0;
539
for (acnt=0; acnt<nas; acnt++) {
540
tval = efzc + 0.5 * orb_e_diff_alp[acnt] + oei_alp[acnt];
541
for (bcnt=0; bcnt<nbs; bcnt++) {
542
value = 0.5 * orb_e_diff_bet[bcnt] + oei_bet[bcnt] + tval;
543
H0[acnt][bcnt] = value;
545
} /* end loop over bcnt */
551
free(orb_e_diff_alp);
552
free(orb_e_diff_bet);
555
** calc_hd_block_z_ave(): Function calculates a block of H0 and the diagonal elements
556
** of the Hamiltonian matrix averaged over spin-coupling sets to correct any
557
** spin contamination of the c and sigma vectors.
560
** alplist_local = list of alpha strings with replacements (used to get occs)
561
** betlist_local = list of beta strings with replacements
562
** nas = number of alpha strings in list
563
** nbs = number of beta strings in list
564
** H0 = matrix to hold results (stored as H0[alpidx][betidx])
565
** oei = one-electron integrals
566
** tei = two-electron integrals
567
** na = number of explicit alpha electrons
568
** nb = number of explicit beta electrons
569
** nbf = number of orbitals in CI
570
** efzc = frozen core energy
573
void calc_hd_block_z_ave(struct stringwr *alplist_local, struct stringwr *betlist_local,
574
double **H0, double pert_param, double *tei, double efzc, int nas, int nbs, int na,
578
int a1, a2, a3, b1, b2, b3;
579
int i,j, ii, iii, jj, ij, iijj, ijij;
580
double value, tval, tval2, Kave;
581
struct stringwr *betlist0;
582
double k_total; /* total number of K ints in energy expression */
583
int k_combo; /* total combination of unique K ints over spin-coupling set */
584
int *unique_occs; /* the uniquely occupied orbitals for a given determinant */
585
int num_el; /* total number of electrons explicitly treated */
586
int num_unique; /* number of unique orbitals */
587
betlist0 = betlist_local;
590
k_total = combinations(na,2) + combinations(nb,2);
592
unique_occs = init_int_array(num_el);
594
for (acnt=0; acnt<nas; acnt++) {
596
for (bcnt=0, betlist_local=betlist0; bcnt<nbs; bcnt++) {
598
/* add frozen core energy first */
601
/* loop over alpha occs */
602
for (a1=0; a1<na; a1++) {
603
i = (int) alplist_local->occs[a1];
604
value += CalcInfo.scfeigval[i+CalcInfo.num_fzc_orbs];
606
/* h_ii bar alpha alpha */
609
/* loop over alpha occs */
610
for (a2=0; a2<a1; a2++) {
611
j = (int) alplist_local->occs[a2];
615
value -= pert_param * tei[iijj];
618
/* loop over beta occs */
619
for (b1=0; b1<nb; b1++) {
620
j = (int) betlist_local->occs[b1];
622
iijj = ioff[MAX0(ii,jj)] + MIN0(ii,jj);
623
value -= pert_param * tei[iijj];
627
/* loop over beta occs */
628
for (b1=0; b1<nb; b1++) {
629
i = (int) betlist_local->occs[b1];
630
value += CalcInfo.scfeigval[i+CalcInfo.num_fzc_orbs];
634
/* loop over beta occs */
635
for (b2=0; b2<b1; b2++) {
636
j = (int) betlist_local->occs[b2];
640
ijij = ioff[ij] + ij;
641
value -= pert_param * tei[iijj];
645
/* determine average K over spin-coupling set */
647
for (a1=0; a1<na; a1++) unique_occs[num_unique++] = (int) alplist_local->occs[a1];
648
/* for (j=0; j<num_unique; j++)
649
fprintf(outfile,"unique_occs[%d] = %d\n",j,unique_occs[j]); */
650
for (b1=0; b1<nb; b1++) {
651
j = (int) betlist_local->occs[b1];
652
for (a1=0; a1<na; a1++) {
653
if (j==unique_occs[a1]) break;
654
if (a1==(na-1)) unique_occs[num_unique++] = j;
657
/* fprintf(outfile,"num_unique = %d\n",num_unique);
658
fprintf(outfile,"num_el = %d\n",num_el);
660
if (num_unique>num_el) fprintf(outfile,"WARNING: The number of explicit electrons" \
665
fprintf(outfile,"alp_occs[%d] = %d\n",j,(int)alplist_local->occs[j]);
667
fprintf(outfile,"bet_occs[%d] = %d\n",j,(int)betlist_local->occs[j]);
668
for (j=0; j<num_unique; j++)
669
fprintf(outfile,"unique_occs[%d] = %d\n",j,unique_occs[j]);
673
for (a1=0; a1<num_unique; a1++) {
675
for (b1=0; b1<a1; b1++) {
677
ij = ioff[MAX0(i,j)] + MIN0(i,j);
678
ijij = ioff[ij] + ij;
680
/* fprintf(outfile,"tei[%d] = %lf\n",ijij,tei[ijij]); */
684
/* fprintf(outfile,"num_unique = %d\n",num_unique);
685
fprintf(outfile,"ioff[num_unique-1] = %d\n",ioff[num_unique]);
686
fprintf(outfile,"k_total = %d\n",k_total);
688
if (num_unique > 1) Kave /= ioff[num_unique-1];
689
value += 0.5 * Kave * k_total * pert_param;
690
/* fprintf(outfile,"Kave = %lf\n",Kave); */
692
if (Parameters.print_lvl > 5) {
693
fprintf(outfile,"acnt = %d\t bcnt = %d\n",acnt,bcnt);
694
fprintf(outfile,"tval = %lf\n",tval);
695
for(a1=0; a1<na; a1++)
696
fprintf(outfile," %d",alplist_local->occs[a1]);
697
fprintf(outfile," \n");
698
for(b1=0; b1<nb; b1++)
699
fprintf(outfile," %d",betlist_local->occs[b1]);
700
fprintf(outfile," \n");
702
H0[acnt][bcnt] = value;
704
fprintf(outfile,"H0[%d][%d] = %lf\n",acnt,bcnt,value);
707
} /* end loop over bcnt */
714
}} // namespace psi::detci