00001
00007 #define EXTERN
00008 #include <stdio.h>
00009 #include <stdlib.h>
00010 #include <libqt/qt.h>
00011 #include <libciomr/libciomr.h>
00012 #include "structs.h"
00013 #include "globals.h"
00014
00015 namespace psi { namespace detci {
00016
00017
00018 #define MAX_EL 30
00019 #define MIN0(a,b) (((a)<(b)) ? (a) : (b))
00020 #define MAX0(a,b) (((a)>(b)) ? (a) : (b))
00021
00022
00023 extern int subgr_lex_addr(struct level *head, int *occs, int nel, int norb);
00024
00025 void b2brepl(unsigned char **occs, int *Jcnt, int **Jij, int **Joij,
00026 int **Jridx, signed char **Jsgn, struct olsen_graph *Graph,
00027 int Ilist, int Jlist, int len);
00028 void b2bgen1(unsigned char **occs, int *Jcnt, int **Jij, int **Joij,
00029 int **Jridx, signed char **Jsgn, struct level *subgr_head,
00030 int len, int ijsym, int nel, int ras1_lvl, int ras3_lvl, int ras4_lvl);
00031 void b2bgen2(unsigned char **occs, int *Jcnt, int **Jij, int **Joij,
00032 int **Jridx, signed char **Jsgn, struct level *subgr_head,
00033 int up, int down, int len, int ijsym, int nel, int ras1_lvl, int ras3_lvl,
00034 int ras4_lvl);
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060 void b2brepl(unsigned char **occs, int *Jcnt, int **Jij, int **Joij,
00061 int **Jridx, signed char **Jsgn, struct olsen_graph *Graph,
00062 int Ilist, int Jlist, int len)
00063 {
00064 int I_n1, I_n2, I_n3, I_n4;
00065 int J_n1, J_n2, J_n3, J_n4;
00066 int D_n1, D_n2, D_n3, D_n4;
00067 int Ilist_ir, Jlist_ir;
00068 int nel,Icode,Jcode,ijsym,up,down;
00069 struct level *subgr_head;
00070
00071
00072 zero_int_array(Jcnt, len);
00073
00074
00075 Icode = Ilist % Graph->subgr_per_irrep;
00076 Jcode = Jlist % Graph->subgr_per_irrep;
00077 Ilist_ir = Ilist / Graph->subgr_per_irrep;
00078 Jlist_ir = Jlist / Graph->subgr_per_irrep;
00079 subgr_head = Graph->sg[Jlist_ir][Jcode].lvl;
00080
00081
00082
00083 nel = Graph->num_el_expl;
00084 I_n1 = Graph->encode[0][Icode];
00085 I_n3 = Graph->encode[1][Icode];
00086 I_n4 = Graph->encode[2][Icode];
00087 I_n2 = nel - I_n1 - I_n3 - I_n4;
00088 J_n1 = Graph->encode[0][Jcode];
00089 J_n3 = Graph->encode[1][Jcode];
00090 J_n4 = Graph->encode[2][Jcode];
00091 J_n2 = nel - J_n1 - J_n3 - J_n4;
00092 if (I_n1 < 0 || I_n2 < 0 || I_n3 < 0 || J_n1 < 0 || J_n2 < 0 || J_n3 < 0
00093 || I_n4 < 0 || J_n4 < 0) {
00094 printf("b2brepl: got less than 1 electron in a partition\n");
00095 return;
00096 }
00097
00098
00099 D_n1 = J_n1 - I_n1;
00100 D_n2 = J_n2 - I_n2;
00101 D_n3 = J_n3 - I_n3;
00102 D_n4 = J_n4 - I_n4;
00103
00104
00105 if (abs(D_n1) + abs(D_n2) + abs(D_n3) + abs(D_n4) > 2)
00106 return;
00107
00108
00109 ijsym = Ilist_ir ^ Jlist_ir;
00110
00111
00112 if (D_n1 == 0 && D_n2 == 0 && D_n3 == 0 && D_n4 == 0) {
00113 b2bgen1(occs,Jcnt,Jij,Joij,Jridx,Jsgn,subgr_head,len,ijsym,nel,
00114 Graph->ras1_lvl, Graph->ras3_lvl, Graph->ras4_lvl);
00115 }
00116 else {
00117 if (D_n1 == 1) up = 0;
00118 else if (D_n2 == 1) up = 1;
00119 else if (D_n3 == 1) up = 2;
00120 else if (D_n4 == 1) up = 3;
00121 if (D_n1 == -1) down = 0;
00122 else if (D_n2 == -1) down = 1;
00123 else if (D_n3 == -1) down = 2;
00124 else if (D_n4 == -1) down = 3;
00125 b2bgen2(occs,Jcnt,Jij,Joij,Jridx,Jsgn,subgr_head,up,down,len,ijsym,nel,
00126 Graph->ras1_lvl, Graph->ras3_lvl, Graph->ras4_lvl);
00127 }
00128 }
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138 void b2bgen1(unsigned char **occs, int *Jcnt, int **Jij, int **Joij,
00139 int **Jridx, signed char **Jsgn, struct level *subgr_head,
00140 int len, int ijsym, int nel, int ras1_lvl, int ras3_lvl, int ras4_lvl)
00141 {
00142 int I;
00143 int O[MAX_EL], T[MAX_EL], ras_occs[4][MAX_EL], ecnt[4];
00144 int i,j,k,l,m,ij,oij,orb,r1cnt,r2cnt,r3cnt,r4cnt;
00145 int isym,jsym;
00146 int cnt,ridx,norb;
00147 signed char sgn;
00148 int ras,hole,part,abshole,hops,iused;
00149 int **ras_orbs[4], **ras_opi;
00150
00151 for (i=0; i<4; i++) ras_orbs[i] = CalcInfo.ras_orbs[i];
00152 ras_opi = CalcInfo.ras_opi;
00153 norb = CalcInfo.num_ci_orbs;
00154
00155
00156 for (I=0; I<len; I++) {
00157
00158 cnt = 0;
00159
00160
00161 r1cnt = r2cnt = r3cnt = r4cnt = 0;
00162 for (i=0; i<nel; i++) {
00163 orb = (int) occs[I][i];
00164 O[i] = orb;
00165 if (orb <= ras1_lvl) ras_occs[0][r1cnt++] = orb;
00166 else if (orb >= ras3_lvl && orb < ras4_lvl) ras_occs[2][r3cnt++] = orb;
00167 else if (orb >= ras4_lvl) ras_occs[3][r4cnt++] = orb;
00168 else ras_occs[1][r2cnt++] = orb;
00169 }
00170
00171 ecnt[0] = r1cnt;
00172 ecnt[1] = r2cnt;
00173 ecnt[2] = r3cnt;
00174 ecnt[3] = r4cnt;
00175
00176
00177 if (ijsym == 0) {
00178 ridx = subgr_lex_addr(subgr_head, O, nel, norb);
00179 if (ridx < 0) {
00180 printf("b2bgen1: invalid string index = %d\n", ridx);
00181 continue;
00182 }
00183 for (k=0; k<nel; k++) {
00184 i = O[k];
00185 ij = ioff[i] + i;
00186 oij = i * norb + i;
00187 Jij[I][cnt] = ij;
00188 Joij[I][cnt] = oij;
00189 Jsgn[I][cnt] = 1;
00190 Jridx[I][cnt] = ridx;
00191 cnt++;
00192 }
00193 }
00194
00195
00196 for (ras=0; ras<4; ras++) {
00197
00198 for (hole=0; hole<ecnt[ras]; hole++) {
00199
00200 abshole = hole;
00201 for (k=0; k<ras; k++) abshole += ecnt[k];
00202
00203 j = ras_occs[ras][hole];
00204 if (j < CalcInfo.num_cor_orbs) continue;
00205 jsym = CalcInfo.orbsym[j + CalcInfo.num_fzc_orbs];
00206 isym = ijsym ^ jsym;
00207 for (part=0; part<ras_opi[ras][isym]; part++) {
00208 i = ras_orbs[ras][isym][part];
00209
00210
00211 for (k=0,l=0; k<ecnt[ras]; k++) {
00212 if (i == ras_occs[ras][k]) {l=1; break;}
00213 }
00214 if (l==1) continue;
00215
00216
00217 for (k=0,l=0; k<ras; k++) {
00218 for (m=0; m<ecnt[k]; m++) {
00219 T[l++] = ras_occs[k][m];
00220 }
00221 }
00222 for (k=0,iused=0; k<ecnt[ras]; k++) {
00223 if (!iused && i < ras_occs[ras][k]) {
00224 iused=1;
00225 hops = l;
00226 T[l++] = i;
00227 }
00228 if (k != hole) {
00229 T[l++] = ras_occs[ras][k];
00230 }
00231 }
00232 if (!iused) {
00233 hops = l;
00234 T[l++] = i;
00235 }
00236 for (k=ras+1; k<4; k++) {
00237 for (m=0; m<ecnt[k]; m++) {
00238 T[l++] = ras_occs[k][m];
00239 }
00240 }
00241 ridx = subgr_lex_addr(subgr_head, T, nel, norb);
00242
00243 if (ridx < 0) {
00244 printf("b2bgen1: invalid string index = %d\n", ridx);
00245 continue;
00246 }
00247
00248
00249 sgn = ((abshole + hops) % 2) ? -1 : 1;
00250 ij = ioff[MAX0(i,j)] + MIN0(i,j);
00251 oij = i * norb + j;
00252
00253
00254 Jij[I][cnt] = ij;
00255 Joij[I][cnt] = oij;
00256 Jsgn[I][cnt] = sgn;
00257 Jridx[I][cnt] = ridx;
00258 cnt++;
00259
00260 }
00261 }
00262 }
00263 Jcnt[I] = cnt;
00264 }
00265
00266 }
00267
00268
00269 void b2bgen2(unsigned char **occs, int *Jcnt, int **Jij, int **Joij,
00270 int **Jridx, signed char **Jsgn, struct level *subgr_head,
00271 int up, int down, int len, int ijsym, int nel, int ras1_lvl,
00272 int ras3_lvl, int ras4_lvl)
00273 {
00274 int I;
00275 int O[MAX_EL], T[MAX_EL], ras_occs[4][MAX_EL], ecnt[4];
00276 int i,j,k,l,ij,oij,orb,r1cnt,r2cnt,r3cnt,r4cnt;
00277 int isym,jsym;
00278 int cnt,ridx,norb;
00279 signed char sgn;
00280 int hole,part,abshole,hops,iused;
00281 int **ras_orbs, *ras_opi, *ras_occs_excite, *ras_occs_virt;
00282
00283 norb = CalcInfo.num_ci_orbs;
00284
00285
00286 for (I=0; I<len; I++) {
00287
00288 cnt = 0;
00289
00290
00291 r1cnt = r2cnt = r3cnt = r4cnt = 0;
00292 for (i=0; i<nel; i++) {
00293 orb = (int) occs[I][i];
00294 O[i] = orb;
00295 if (orb <= ras1_lvl) ras_occs[0][r1cnt++] = orb;
00296 else if (orb>=ras3_lvl && orb<ras4_lvl) ras_occs[2][r3cnt++] = orb;
00297 else if (orb >= ras4_lvl) ras_occs[3][r4cnt++] = orb;
00298 else ras_occs[1][r2cnt++] = orb;
00299 }
00300
00301 ecnt[0] = r1cnt;
00302 ecnt[1] = r2cnt;
00303 ecnt[2] = r3cnt;
00304 ecnt[3] = r4cnt;
00305 ras_occs_excite = ras_occs[down];
00306 ras_occs_virt = ras_occs[up];
00307 ras_opi = CalcInfo.ras_opi[up];
00308 ras_orbs = CalcInfo.ras_orbs[up];
00309
00310 for (hole=0; hole<ecnt[down]; hole++) {
00311
00312 abshole = hole;
00313 for (k=0; k<down; k++) abshole += ecnt[k];
00314
00315 j = ras_occs_excite[hole];
00316 if (j < CalcInfo.num_cor_orbs) continue;
00317 jsym = CalcInfo.orbsym[j + CalcInfo.num_fzc_orbs];
00318 isym = ijsym ^ jsym;
00319 for (part=0; part<ras_opi[isym]; part++) {
00320 i = ras_orbs[isym][part];
00321
00322
00323 for (k=0,l=0; k<ecnt[up]; k++) {
00324 if (i == ras_occs_virt[k]) {l=1; break;}
00325 }
00326 if (l==1) continue;
00327
00328
00329 for (k=0,iused=0,l=0; k<nel; k++) {
00330 if (!iused && i < O[k]) { iused=1; hops = l; T[l++] = i; }
00331 if (k != abshole) T[l++] = O[k];
00332 }
00333 if (!iused) { hops = l; T[l++] = i; }
00334
00335 ridx = subgr_lex_addr(subgr_head, T, nel, norb);
00336
00337 if (ridx < 0) {
00338 printf("b2bgen2: invalid string index = %d\n", ridx);
00339 continue;
00340 }
00341
00342
00343 sgn = ((abshole + hops) % 2) ? -1 : 1;
00344
00345 ij = ioff[MAX0(i,j)] + MIN0(i,j);
00346 oij = i * norb + j;
00347
00348
00349 Jij[I][cnt] = ij;
00350 Joij[I][cnt] = oij;
00351 Jsgn[I][cnt] = sgn;
00352 Jridx[I][cnt] = ridx;
00353 cnt++;
00354
00355 }
00356 }
00357
00358 Jcnt[I] = cnt;
00359 }
00360
00361 }
00362
00363
00364 void b2brepl_test(unsigned char ***occs, int *Jcnt, int **Jij, int **Joij,
00365 int **Jridx, signed char **Jsgn, struct olsen_graph *Graph)
00366 {
00367 int i, j, nirreps, ncodes;
00368 int Iirrep, Icode, Ilistnum;
00369 int Jirrep, Jcode, Jlistnum;
00370 struct stringgraph *Isubgraph, *Jsubgraph;
00371
00372 nirreps = Graph->nirreps;
00373 ncodes = Graph->subgr_per_irrep;
00374
00375 fprintf(outfile,"\nTesting block to block single-replacements b2brepl()\n");
00376 for (Iirrep=0,Ilistnum=0; Iirrep<nirreps; Iirrep++) {
00377 for (Icode=0; Icode<ncodes; Icode++,Ilistnum++) {
00378 Isubgraph = Graph->sg[Iirrep] + Icode;
00379 if (!Isubgraph->num_strings) continue;
00380 for (Jirrep=0,Jlistnum=0; Jirrep<nirreps; Jirrep++) {
00381 for (Jcode=0; Jcode<ncodes; Jcode++,Jlistnum++) {
00382 Jsubgraph = Graph->sg[Jirrep] + Jcode;
00383 if (!Jsubgraph->num_strings) continue;
00384
00385 b2brepl(occs[Ilistnum], Jcnt, Jij, Joij, Jridx, Jsgn,
00386 Graph, Ilistnum, Jlistnum, Isubgraph->num_strings);
00387
00388 for (i=0; i<Isubgraph->num_strings; i++) {
00389 fprintf(outfile, "\nString %4d (",i);
00390 for (j=0; j<Graph->num_el_expl; j++) {
00391 fprintf(outfile, "%2d ", (int) occs[Ilistnum][i][j]);
00392 }
00393 fprintf(outfile, ")\n Links:\n") ;
00394 for (j=0; j<Jcnt[i]; j++) {
00395 fprintf(outfile, " %3d [%3d] %c (%2d %3d)\n",
00396 Jij[i][j], Joij[i][j], (Jsgn[i][j]==1) ? '+' : '-',
00397 Jlistnum, Jridx[i][j]);
00398 }
00399 }
00400
00401 }
00402 }
00403 }
00404 }
00405 }
00406
00407 }}
00408