Пример #1
0
/*
 * the intermediate determinants ~ (norb,neleca+1;norb,nelecb-1)
 * Annihilating one alpha electron and creating one beta electron lead
 * to the input ground state CI |0>
 * stra_id is the ID of the intermediate determinants.  t1 is a buffer
 * of size [nstrb_or_fillcnt,norb*norb].  fillcnt is the dim of beta
 * strings for intermediate determinants
 */
static double ades_bcre_t1(double *ci0, double *t1, int fillcnt, int stra_id,
                           int norb, int nstrb, int neleca, int nelecb,
                           int *ades_index, int *bcre_index)
{
        const int nnorb = norb * norb;
        const int inelec = neleca + 1;
        const int invir  = norb - nelecb + 1;
        int ic, id, i, j, k, str1, sign, signa;
        const int *tab;
        double *pt1, *pci;
        double csum = 0;

        ades_index = ades_index + stra_id * inelec * 4;
        for (id = 0; id < inelec; id++) {
                j     = EXTRACT_DES (ades_index, id);
                str1  = EXTRACT_ADDR(ades_index, id);
                signa = EXTRACT_SIGN(ades_index, id);
                pci = ci0 + str1 * (size_t)nstrb;
                pt1 = t1 + j*norb;
                for (k = 0; k < fillcnt; k++) {
                        tab = bcre_index + k * invir * 4;
                        for (ic = 0; ic < invir; ic++) {
                                i    = EXTRACT_CRE (tab, ic);
                                str1 = EXTRACT_ADDR(tab, ic);
                                sign = EXTRACT_SIGN(tab, ic) * signa;
                                pt1[i] += pci[str1] * sign;
                                csum += pci[str1] * pci[str1];
                        }
                        pt1 += nnorb;
                }
        }
        return csum;
}
Пример #2
0
/*
 * the intermediate determinants ~ (norb,neleca-1;norb,nelecb+1)
 * Annihilating one beta electron and creating one alpha electron lead
 * to the input ground state CI |0>
 * stra_id is the ID of the intermediate determinants.  t1 is a buffer
 * of size [nstrb_or_fillcnt,norb*norb].  fillcnt is the dim of beta
 * strings for intermediate determinants
 */
static double acre_bdes_t1(double *ci0, double *t1, int fillcnt, int stra_id,
                           int norb, int nstrb, int neleca, int nelecb,
                           int *acre_index, int *bdes_index)
{
        const int nnorb = norb * norb;
        const int inelec = nelecb + 1;
        const int invir  = norb - neleca + 1;
        int ic, id, i, j, str0, str1, sign, signa;
        const int *tab;
        double *pci, *pt1;
        double csum = 0;

        acre_index = acre_index + stra_id * invir * 4;
        for (ic = 0; ic < invir; ic++) {
                i     = EXTRACT_CRE (acre_index, ic);
                str1  = EXTRACT_ADDR(acre_index, ic);
                signa = EXTRACT_SIGN(acre_index, ic);
                pci = ci0 + str1 * (size_t)nstrb;
                pt1 = t1 + i;
                tab = bdes_index;
                for (str0 = 0; str0 < fillcnt; str0++) {
                        for (id = 0; id < inelec; id++) {
                                j    = EXTRACT_DES (tab, id);
                                str1 = EXTRACT_ADDR(tab, id);
                                sign = EXTRACT_SIGN(tab, id) * signa;
                                pt1[j*norb] += sign * pci[str1];
                                csum += pci[str1] * pci[str1];
                        }
                        tab += inelec * 4;
                        pt1 += nnorb;
                }
        }
        return csum;
}
Пример #3
0
static void spread_a_t1(double *ci1, double *t1,
                        int bcount, int stra_id, int strb_id,
                        int norb, int nstrb, int nlinka, _LinkT *clink_indexa)
{
        ci1 += strb_id;
        const int nnorb = norb * norb;
        int j, k, i, a, str1, sign;
        const _LinkT *tab = clink_indexa + stra_id * nlinka;
        double *cp0, *cp1;

        for (j = 0; j < nlinka; j++) {
                a    = EXTRACT_CRE (tab[j]);
                i    = EXTRACT_DES (tab[j]);
                str1 = EXTRACT_ADDR(tab[j]);
                sign = EXTRACT_SIGN(tab[j]);
                cp0 = t1 + a*norb+i; // propagate from t1 to bra, through a^+ i
                cp1 = ci1 + str1*(size_t)nstrb;
                if (sign > 0) {
                        for (k = 0; k < bcount; k++) {
                                cp1[k] += cp0[k*nnorb];
                        }
                } else {
                        for (k = 0; k < bcount; k++) {
                                cp1[k] -= cp0[k*nnorb];
                        }
                }
        }
}
Пример #4
0
void FCIcontract_b_1e_nosym(double *h1e, double *ci0, double *ci1,
                            int norb, int nstra, int nstrb, int nlinka, int nlinkb,
                            int *link_indexa, int *link_indexb)
{
        int j, k, i, a, sign;
        size_t str0, str1;
        double *pci1;
        double tmp;
        _LinkT *tab;
        _LinkT *clink = malloc(sizeof(_LinkT) * nlinkb * nstrb);
        FCIcompress_link(clink, link_indexb, norb, nstrb, nlinkb);

        for (str0 = 0; str0 < nstra; str0++) {
                pci1 = ci1 + str0 * nstrb;
                for (k = 0; k < nstrb; k++) {
                        tab = clink + k * nlinkb;
                        tmp = ci0[str0*nstrb+k];
                        for (j = 0; j < nlinkb; j++) {
                                a    = EXTRACT_CRE (tab[j]);
                                i    = EXTRACT_DES (tab[j]);
                                str1 = EXTRACT_ADDR(tab[j]);
                                sign = EXTRACT_SIGN(tab[j]);
                                pci1[str1] += sign * tmp * h1e[a*norb+i];
                        }
                }
        }
        free(clink);
}
Пример #5
0
double FCIrdm2_0b_t1ci(double *ci0, double *t1,
                       int bcount, int stra_id, int strb_id,
                       int norb, int nstrb, int nlinkb, _LinkT *clink_indexb)
{
        const int nnorb = norb * norb;
        int i, j, a, str0, str1, sign;
        const _LinkT *tab = clink_indexb + strb_id * nlinkb;
        double *pci = ci0 + stra_id*(size_t)nstrb;
        double csum = 0;

        for (str0 = 0; str0 < bcount; str0++) {
                memset(t1, 0, sizeof(double) * nnorb);
                for (j = 0; j < nlinkb; j++) {
                        a    = EXTRACT_CRE (tab[j]);
                        i    = EXTRACT_DES (tab[j]);
                        str1 = EXTRACT_ADDR(tab[j]);
                        sign = EXTRACT_SIGN(tab[j]);
                        t1[i*norb+a] += sign * pci[str1];
                        csum += pci[str1] * pci[str1];
                }
                t1 += nnorb;
                tab += nlinkb;
        }
        return csum;
}
Пример #6
0
/*
 * f1e_tril is the 1e hamiltonian for spin beta
 */
void FCIcontract_b_1e(double *f1e_tril, double *ci0, double *ci1,
                      int norb, int nstra, int nstrb, int nlinka, int nlinkb,
                      int *link_indexa, int *link_indexb)
{
        int j, k, ia, str0, str1, sign;
        double *pci1;
        double tmp;
        _LinkT *tab;
        _LinkT *clink = malloc(sizeof(_LinkT) * nlinkb * nstrb);
        compress_link(clink, link_indexb, nstrb, nlinkb);

        for (str0 = 0; str0 < nstra; str0++) {
                pci1 = ci1 + str0 * (uint64_t)nstrb;
                for (k = 0; k < nstrb; k++) {
                        tab = clink + k * nlinkb;
                        tmp = ci0[str0*(uint64_t)nstrb+k];
                        for (j = 0; j < nlinkb; j++) {
                                ia   = EXTRACT_IA  (tab[j]);
                                str1 = EXTRACT_ADDR(tab[j]);
                                sign = EXTRACT_SIGN(tab[j]);
                                if (sign > 0) {
                                        pci1[str1] += tmp * f1e_tril[ia];
                                } else {
                                        pci1[str1] -= tmp * f1e_tril[ia];
                                }
                        }
                }
        }
        free(clink);
}
Пример #7
0
/* 
 * For given stra_id, spread alpah-strings (which can propagate to stra_id)
 * into t1[:nstrb,nnorb] 
 *    str1-of-alpha -> create/annihilate -> str0-of-alpha
 * ci0[:nstra,:nstrb] is contiguous in beta-strings
 * bcount control the number of beta strings to be calculated.
 * for spin=0 system, only lower triangle of the intermediate ci vector
 * needs to be calculated
 */
static double prog_a_t1(double *ci0, double *t1,
                        int bcount, int stra_id, int strb_id,
                        int norb, int nstrb, int nlinka, _LinkT *clink_indexa)
{
        ci0 += strb_id;
        const int nnorb = norb * (norb+1)/2;
        int j, k, ia, str1, sign;
        const _LinkT *tab = clink_indexa + stra_id * nlinka;
        double *pt1, *pci;
        double csum = 0;

        for (j = 0; j < nlinka; j++) {
                ia   = EXTRACT_IA  (tab[j]);
                str1 = EXTRACT_ADDR(tab[j]);
                sign = EXTRACT_SIGN(tab[j]);
                pt1 = t1 + ia;
                pci = ci0 + str1*(uint64_t)nstrb;
                if (sign > 0) {
                        for (k = 0; k < bcount; k++) {
                                pt1[k*nnorb] += pci[k];
                                csum += pci[k] * pci[k];
                        }
                } else {
                        for (k = 0; k < bcount; k++) {
                                pt1[k*nnorb] -= pci[k];
                                csum += pci[k] * pci[k];
                        }
                }
        }
        return csum;
}
Пример #8
0
void FCIcontract_a_1e_nosym(double *h1e, double *ci0, double *ci1,
                            int norb, int nstra, int nstrb, int nlinka, int nlinkb,
                            int *link_indexa, int *link_indexb)
{
        int j, k, i, a, sign;
        size_t str0, str1;
        double *pci0, *pci1;
        double tmp;
        _LinkT *tab;
        _LinkT *clink = malloc(sizeof(_LinkT) * nlinka * nstra);
        FCIcompress_link(clink, link_indexa, norb, nstra, nlinka);

        for (str0 = 0; str0 < nstra; str0++) {
                tab = clink + str0 * nlinka;
                for (j = 0; j < nlinka; j++) {
                        a    = EXTRACT_CRE (tab[j]); // propagate from t1 to bra, through a^+ i
                        i    = EXTRACT_DES (tab[j]);
                        str1 = EXTRACT_ADDR(tab[j]);
                        sign = EXTRACT_SIGN(tab[j]);
                        pci0 = ci0 + str0 * nstrb;
                        pci1 = ci1 + str1 * nstrb;
                        tmp = sign * h1e[a*norb+i];
                        for (k = 0; k < nstrb; k++) {
                                pci1[k] += tmp * pci0[k];
                        }
                }
        }
        free(clink);
}
Пример #9
0
/*
 * f1e_tril is the 1e hamiltonian for spin alpha
 */
void FCIcontract_a_1e(double *f1e_tril, double *ci0, double *ci1,
                      int norb, int nstra, int nstrb, int nlinka, int nlinkb,
                      int *link_indexa, int *link_indexb)
{
        int j, k, ia, str0, str1, sign;
        double *pci0, *pci1;
        double tmp;
        _LinkT *tab;
        _LinkT *clink = malloc(sizeof(_LinkT) * nlinka * nstra);
        compress_link(clink, link_indexa, nstra, nlinka);

        for (str0 = 0; str0 < nstra; str0++) {
                tab = clink + str0 * nlinka;
                for (j = 0; j < nlinka; j++) {
                        ia   = EXTRACT_IA  (tab[j]);
                        str1 = EXTRACT_ADDR(tab[j]);
                        sign = EXTRACT_SIGN(tab[j]);
                        pci0 = ci0 + str0 * (uint64_t)nstrb;
                        pci1 = ci1 + str1 * (uint64_t)nstrb;
                        tmp = sign * f1e_tril[ia];
                        for (k = 0; k < nstrb; k++) {
                                pci1[k] += tmp * pci0[k];
                        }
                }
        }
        free(clink);
}
Пример #10
0
/*
 * spread t1 into ci1
 */
static void spread_a_t1(double *ci1, double *t1,
                        int bcount, int stra_id, int strb_id,
                        int norb, int nstrb, int nlinka, _LinkT *clink_indexa)
{
        ci1 += strb_id;
        const int nnorb = norb * (norb+1)/2;
        int j, k, ia, str1, sign;
        const _LinkT *tab = clink_indexa + stra_id * nlinka;
        double *cp0, *cp1;

        for (j = 0; j < nlinka; j++) {
                ia   = EXTRACT_IA  (tab[j]);
                str1 = EXTRACT_ADDR(tab[j]);
                sign = EXTRACT_SIGN(tab[j]);
                cp0 = t1 + ia;
                cp1 = ci1 + str1*(uint64_t)nstrb;
                if (sign > 0) {
                        for (k = 0; k < bcount; k++) {
                                cp1[k] += cp0[k*nnorb];
                        }
                } else {
                        for (k = 0; k < bcount; k++) {
                                cp1[k] -= cp0[k*nnorb];
                        }
                }
        }
}
Пример #11
0
void FCItrans_rdm1b(double *rdm1, double *bra, double *ket,
                    int norb, int na, int nb, int nlinka, int nlinkb,
                    int *link_indexa, int *link_indexb)
{
        int i, a, j, k, str0, str1, sign;
        double *pket, *pbra;
        double tmp;
        _LinkT *tab;
        _LinkT *clink = malloc(sizeof(_LinkT) * nlinkb * nb);
        FCIcompress_link(clink, link_indexb, norb, nb, nlinkb);

        memset(rdm1, 0, sizeof(double) * norb*norb);

        for (str0 = 0; str0 < na; str0++) {
                pbra = bra + str0 * nb;
                pket = ket + str0 * nb;
                for (k = 0; k < nb; k++) {
                        tab = clink + k * nlinkb;
                        tmp = pket[k];
                        for (j = 0; j < nlinkb; j++) {
                                a    = EXTRACT_CRE (tab[j]);
                                i    = EXTRACT_DES (tab[j]);
                                str1 = EXTRACT_ADDR(tab[j]);
                                sign = EXTRACT_SIGN(tab[j]);
                                if (sign == 0) {
                                        break;
                                } else {
                                        rdm1[a*norb+i] += sign*pbra[str1]*tmp;
                                }
                        }
                }
        }
        free(clink);
}
Пример #12
0
double FCIrdm2_a_t1ci(double *ci0, double *t1,
                      int bcount, int stra_id, int strb_id,
                      int norb, int nstrb, int nlinka, _LinkT *clink_indexa)
{
        ci0 += strb_id;
        const int nnorb = norb * norb;
        int i, j, k, a, sign;
        size_t str1;
        const _LinkT *tab = clink_indexa + stra_id * nlinka;
        double *pt1, *pci;
        double csum = 0;

        for (j = 0; j < nlinka; j++) {
                a    = EXTRACT_CRE (tab[j]);
                i    = EXTRACT_DES (tab[j]);
                str1 = EXTRACT_ADDR(tab[j]);
                sign = EXTRACT_SIGN(tab[j]);
                pci = ci0 + str1*nstrb;
                pt1 = t1 + i*norb+a;
                if (sign == 0) {
                        break;
                } else if (sign > 0) {
                        for (k = 0; k < bcount; k++) {
                                pt1[k*nnorb] += pci[k];
                                csum += pci[k] * pci[k];
                        }
                } else {
                        for (k = 0; k < bcount; k++) {
                                pt1[k*nnorb] -= pci[k];
                                csum += pci[k] * pci[k];
                        }
                }
        }
        return csum;
}
Пример #13
0
/*
 * t2[:,i,j,k,l] = E^i_j E^k_l|ci0>
 */
static void rdm4_0b_t2(double *ci0, double *t2,
                       int bcount, int stra_id, int strb_id,
                       int norb, int na, int nb, int nlinka, int nlinkb,
                       _LinkT *clink_indexa, _LinkT *clink_indexb)
{
        const int nnorb = norb * norb;
        const int n4 = nnorb * nnorb;
        int i, j, k, l, a, sign, str1;
        double *t1 = malloc(sizeof(double) * nb * nnorb);
        double *pt1, *pt2;
        _LinkT *tab;

        // form t1 which has beta^+ beta |t1> => target stra_id
        FCI_t1ci_sf(ci0, t1, nb, stra_id, 0,
                    norb, na, nb, nlinka, nlinkb, clink_indexa, clink_indexb);

#pragma omp parallel default(none) \
        shared(t1, t2, bcount, strb_id, norb, nlinkb, clink_indexb), \
        private(i, j, k, l, a, str1, sign, pt1, pt2, tab)
{
#pragma omp for schedule(static, 1) nowait
        for (k = 0; k < bcount; k++) {
                memset(t2+k*n4, 0, sizeof(double)*n4);
                tab = clink_indexb + (strb_id+k) * nlinkb;
                for (j = 0; j < nlinkb; j++) {
                        a    = EXTRACT_CRE (tab[j]);
                        i    = EXTRACT_DES (tab[j]);
                        str1 = EXTRACT_ADDR(tab[j]);
                        sign = EXTRACT_SIGN(tab[j]);

                        pt1 = t1 + str1 * nnorb;
                        pt2 = t2 + k * n4 + (i*norb+a)*nnorb;
                        if (sign > 0) {
                                for (l = 0; l < nnorb; l++) {
                                        pt2[l] += pt1[l];
                                }
                        } else {
                                for (l = 0; l < nnorb; l++) {
                                        pt2[l] -= pt1[l];
                                }
                        }
                }
        }
}
        free(t1);
}
Пример #14
0
/*
 * t2[:,i,j,k,l] = E^i_j E^k_l|ci0>
 */
static void rdm4_a_t2(double *ci0, double *t2,
                      int bcount, int stra_id, int strb_id,
                      int norb, int na, int nb, int nlinka, int nlinkb,
                      _LinkT *clink_indexa, _LinkT *clink_indexb)
{
        const int nnorb = norb * norb;
        const int n4 = nnorb * nnorb;
        int i, j, k, l, a, sign, str1;
        double *pt1, *pt2;
        _LinkT *tab = clink_indexa + stra_id * nlinka;

#pragma omp parallel default(none) \
        shared(ci0, t2, bcount, strb_id, norb, na, nb, nlinka, nlinkb, \
               clink_indexa, clink_indexb, tab), \
        private(i, j, k, l, a, str1, sign, pt1, pt2)
{
        double *t1 = malloc(sizeof(double) * bcount * nnorb);
#pragma omp for schedule(static, 40)
        for (j = 0; j < nlinka; j++) {
                a    = EXTRACT_CRE (tab[j]);
                i    = EXTRACT_DES (tab[j]);
                str1 = EXTRACT_ADDR(tab[j]);
                sign = EXTRACT_SIGN(tab[j]);

                // form t1 which has alpha^+ alpha |t1> => target stra_id (through str1)
                FCI_t1ci_sf(ci0, t1, bcount, str1, strb_id,
                            norb, na, nb, nlinka, nlinkb,
                            clink_indexa, clink_indexb);

                for (k = 0; k < bcount; k++) {
                        pt1 = t1 + k * nnorb;
                        pt2 = t2 + k * n4 + (i*norb+a)*nnorb;
                        if (sign > 0) {
                                for (l = 0; l < nnorb; l++) {
                                        pt2[l] += pt1[l];
                                }
                        } else {
                                for (l = 0; l < nnorb; l++) {
                                        pt2[l] -= pt1[l];
                                }
                        }
                }
        }
        free(t1);
}
}
Пример #15
0
/*
 * make_rdm1 assumed the hermitian of density matrix
 */
void FCImake_rdm1a(double *rdm1, double *cibra, double *ciket,
                   int norb, int na, int nb, int nlinka, int nlinkb,
                   int *link_indexa, int *link_indexb)
{
        int i, a, j, k, str0, str1, sign;
        double *pci0, *pci1;
        double *ci0 = ciket;
        _LinkT *tab;
        _LinkT *clink = malloc(sizeof(_LinkT) * nlinka * na);
        FCIcompress_link(clink, link_indexa, norb, na, nlinka);

        memset(rdm1, 0, sizeof(double) * norb*norb);

        for (str0 = 0; str0 < na; str0++) {
                tab = clink + str0 * nlinka;
                pci0 = ci0 + str0 * nb;
                for (j = 0; j < nlinka; j++) {
                        a    = EXTRACT_CRE (tab[j]);
                        i    = EXTRACT_DES (tab[j]);
                        str1 = EXTRACT_ADDR(tab[j]);
                        sign = EXTRACT_SIGN(tab[j]);
                        pci1 = ci0 + str1 * nb;
                        if (a >= i) {
                                if (sign == 0) {
                                        break;
                                } else if (sign > 0) {
                                        for (k = 0; k < nb; k++) {
                                                rdm1[a*norb+i] += pci0[k]*pci1[k];
                                        }
                                } else {
                                        for (k = 0; k < nb; k++) {
                                                rdm1[a*norb+i] -= pci0[k]*pci1[k];
                                        }
                                }
                        }
                }
        }
        for (j = 0; j < norb; j++) {
                for (k = 0; k < j; k++) {
                        rdm1[k*norb+j] = rdm1[j*norb+k];
                }
        }
        free(clink);
}
Пример #16
0
static void spread_b_t1(double *ci1, double *t1,
                        int bcount, int stra_id, int strb_id,
                        int norb, int nstrb, int nlinkb, _LinkT *clink_indexb)
{
        const int nnorb = norb * (norb+1)/2;
        int j, ia, str0, str1, sign;
        const _LinkT *tab = clink_indexb + strb_id * nlinkb;
        double *pci = ci1 + stra_id * (uint64_t)nstrb;

        for (str0 = 0; str0 < bcount; str0++) {
                for (j = 0; j < nlinkb; j++) {
                        ia   = EXTRACT_IA  (tab[j]);
                        str1 = EXTRACT_ADDR(tab[j]);
                        sign = EXTRACT_SIGN(tab[j]);
                        pci[str1] += sign * t1[ia];
                }
                t1 += nnorb;
                tab += nlinkb;
        }
}
Пример #17
0
static void spread_b_t1(double *ci1, double *t1,
                        int bcount, int stra_id, int strb_id,
                        int norb, int nstrb, int nlinkb, _LinkT *clink_indexb)
{
        const int nnorb = norb * norb;
        int j, i, a, str0, str1, sign;
        const _LinkT *tab = clink_indexb + strb_id * nlinkb;
        double *pci = ci1 + stra_id * (size_t)nstrb;

        for (str0 = 0; str0 < bcount; str0++) {
                for (j = 0; j < nlinkb; j++) {
                        a    = EXTRACT_CRE (tab[j]);
                        i    = EXTRACT_DES (tab[j]);
                        str1 = EXTRACT_ADDR(tab[j]);
                        sign = EXTRACT_SIGN(tab[j]);
                        // propagate from t1 to bra, through a^+ i
                        pci[str1] += sign * t1[a*norb+i];
                }
                t1 += nnorb;
                tab += nlinkb;
        }
}
Пример #18
0
/*
 * prog0_b_t1 is the same to prog_b_t1, except that prog0_b_t1
 * initializes t1 with 0, to reduce data transfer between CPU
 * cache and memory
 */
static double prog0_b_t1(double *ci0, double *t1,
                         int bcount, int stra_id, int strb_id,
                         int norb, int nstrb, int nlinkb, _LinkT *clink_indexb)
{
        const int nnorb = norb * (norb+1)/2;
        int j, ia, str0, str1, sign;
        const _LinkT *tab = clink_indexb + strb_id * nlinkb;
        double *pci = ci0 + stra_id*(uint64_t)nstrb;
        double csum = 0;

        for (str0 = 0; str0 < bcount; str0++) {
                memset(t1, 0, sizeof(double)*nnorb);
                for (j = 0; j < nlinkb; j++) {
                        ia   = EXTRACT_IA  (tab[j]);
                        str1 = EXTRACT_ADDR(tab[j]);
                        sign = EXTRACT_SIGN(tab[j]);
                        t1[ia] += sign * pci[str1];
                        csum += pci[str1] * pci[str1];
                }
                t1 += nnorb;
                tab += nlinkb;
        }
        return csum;
}