00001
00005 #include <math.h>
00006 #include <libpsio/psio.h>
00007 #include <libdpd/dpd.h>
00008 #include "MOInfo.h"
00009 #include "Params.h"
00010 #define EXTERN
00011 #include "globals.h"
00012
00013 namespace psi { namespace ccsort {
00014
00015 void b_sort(void)
00016 {
00017 dpdbuf4 B, B_s, B_a;
00018 int h, m, ab, cd, a, b, c, d, AB, CD, DC, Gc, C, cc;
00019 int rows_per_bucket, rows_left, nbuckets, row_start, nvirt;
00020 double **B_diag, abcd, abdc;
00021 psio_address next;
00022
00023
00024
00025 if(params.ref == 0) {
00026 dpd_buf4_init(&B, CC_BINTS, 0, 5, 5, 5, 5, 0, "B <ab|cd>");
00027 dpd_buf4_init(&B_s, CC_BINTS, 0, 8, 8, 8, 8, 0, "B(+) <ab|cd> + <ab|dc>");
00028 dpd_buf4_init(&B_a, CC_BINTS, 0, 9, 9, 9, 9, 0, "B(-) <ab|cd> - <ab|dc>");
00029 dpd_buf4_scm(&B_s, 0);
00030 dpd_buf4_scm(&B_a, 0);
00031 for(h=0; h < moinfo.nirreps; h++) {
00032 dpd_buf4_mat_irrep_row_init(&B, h);
00033 rows_per_bucket = 0;
00034 if(B_s.params->coltot[h])
00035 rows_per_bucket = dpd_memfree()/(2 * B_s.params->coltot[h]);
00036 if(rows_per_bucket > B_s.params->rowtot[h]) rows_per_bucket = B_s.params->rowtot[h];
00037 nbuckets = (int) ceil((double) B_s.params->rowtot[h]/(double) rows_per_bucket);
00038 rows_left = 0;
00039 if(rows_per_bucket)
00040 rows_left = B_s.params->rowtot[h] % rows_per_bucket;
00041
00042 dpd_buf4_mat_irrep_init_block(&B_s, h, rows_per_bucket);
00043 dpd_buf4_mat_irrep_init_block(&B_a, h, rows_per_bucket);
00044
00045 for(m=0; m < (rows_left ? nbuckets-1:nbuckets); m++) {
00046 row_start = m * rows_per_bucket;
00047
00048 for(ab=0; ab < rows_per_bucket; ab++) {
00049 a = B_s.params->roworb[h][ab+row_start][0];
00050 b = B_s.params->roworb[h][ab+row_start][1];
00051 AB = B.params->rowidx[a][b];
00052 dpd_buf4_mat_irrep_row_rd(&B, h, AB);
00053 for(cd=0; cd < B_s.params->coltot[h]; cd++) {
00054 c = B_s.params->colorb[h][cd][0];
00055 d = B_s.params->colorb[h][cd][1];
00056 CD = B.params->colidx[c][d];
00057 DC = B.params->colidx[d][c];
00058 abcd = B.matrix[h][0][CD];
00059 abdc = B.matrix[h][0][DC];
00060
00061 B_s.matrix[h][ab][cd] = abcd + abdc;
00062 B_a.matrix[h][ab][cd] = abcd - abdc;
00063 }
00064 }
00065
00066 dpd_buf4_mat_irrep_wrt_block(&B_s, h, row_start, rows_per_bucket);
00067 dpd_buf4_mat_irrep_wrt_block(&B_a, h, row_start, rows_per_bucket);
00068 }
00069 if(rows_left) {
00070 row_start = m * rows_per_bucket;
00071
00072 for(ab=0; ab < rows_left; ab++) {
00073 a = B_s.params->roworb[h][ab+row_start][0];
00074 b = B_s.params->roworb[h][ab+row_start][1];
00075 AB = B.params->rowidx[a][b];
00076 dpd_buf4_mat_irrep_row_rd(&B, h, AB);
00077 for(cd=0; cd < B_s.params->coltot[h]; cd++) {
00078 c = B_s.params->colorb[h][cd][0];
00079 d = B_s.params->colorb[h][cd][1];
00080 CD = B.params->colidx[c][d];
00081 DC = B.params->colidx[d][c];
00082 abcd = B.matrix[h][0][CD];
00083 abdc = B.matrix[h][0][DC];
00084
00085 B_s.matrix[h][ab][cd] = abcd + abdc;
00086 B_a.matrix[h][ab][cd] = abcd - abdc;
00087 }
00088 }
00089
00090 dpd_buf4_mat_irrep_wrt_block(&B_s, h, row_start, rows_left);
00091 dpd_buf4_mat_irrep_wrt_block(&B_a, h, row_start, rows_left);
00092 }
00093
00094 dpd_buf4_mat_irrep_close_block(&B_s, h, rows_per_bucket);
00095 dpd_buf4_mat_irrep_close_block(&B_a, h, rows_per_bucket);
00096 dpd_buf4_mat_irrep_row_close(&B, h);
00097 }
00098 dpd_buf4_close(&B_a);
00099 dpd_buf4_close(&B_s);
00100 dpd_buf4_close(&B);
00101
00102
00103 for(h=0,nvirt=0; h < moinfo.nirreps; h++) nvirt += moinfo.virtpi[h];
00104 dpd_buf4_init(&B_s, CC_BINTS, 0, 8, 8, 8, 8, 0, "B(+) <ab|cd> + <ab|dc>");
00105
00106 rows_per_bucket = dpd_memfree()/(B_s.params->coltot[0] + nvirt);
00107 if(rows_per_bucket > B_s.params->rowtot[0]) rows_per_bucket = B_s.params->rowtot[0];
00108 nbuckets = (int) ceil((double) B_s.params->rowtot[0]/(double) rows_per_bucket);
00109 rows_left = B_s.params->rowtot[0] % rows_per_bucket;
00110
00111 dpd_buf4_mat_irrep_init_block(&B_s, 0, rows_per_bucket);
00112 B_diag = dpd_block_matrix(rows_per_bucket, nvirt);
00113
00114 next = PSIO_ZERO;
00115 for(m=0; m < (rows_left ? nbuckets-1:nbuckets); m++) {
00116 row_start = m * rows_per_bucket;
00117 dpd_buf4_mat_irrep_rd_block(&B_s, 0, row_start, rows_per_bucket);
00118 for(ab=0; ab < rows_per_bucket; ab++)
00119 for(Gc=0; Gc < moinfo.nirreps; Gc++)
00120 for(C=0; C < moinfo.virtpi[Gc]; C++) {
00121 c = moinfo.vir_off[Gc] + C;
00122 cc = B_s.params->colidx[c][c];
00123 B_diag[ab][c] = B_s.matrix[0][ab][cc];
00124 }
00125 psio_write(CC_BINTS, "B(+) <ab|cc>", (char *) B_diag[0], rows_per_bucket*nvirt*sizeof(double), next, &next);
00126 }
00127 if(rows_left) {
00128 row_start = m * rows_per_bucket;
00129 dpd_buf4_mat_irrep_rd_block(&B_s, 0, row_start, rows_left);
00130 for(ab=0; ab < rows_left; ab++)
00131 for(Gc=0; Gc < moinfo.nirreps; Gc++)
00132 for(C=0; C < moinfo.virtpi[Gc]; C++) {
00133 c = moinfo.vir_off[Gc] + C;
00134 cc = B_s.params->colidx[c][c];
00135 B_diag[ab][c] = B_s.matrix[0][ab][cc];
00136 }
00137 psio_write(CC_BINTS, "B(+) <ab|cc>", (char *) B_diag[0], rows_left*nvirt*sizeof(double), next, &next);
00138 }
00139 dpd_free_block(B_diag, rows_per_bucket, nvirt);
00140 dpd_buf4_mat_irrep_close_block(&B_s, 0, rows_per_bucket);
00141 dpd_buf4_close(&B_s);
00142 }
00143 }
00144
00145 }}