示例#1
0
文件: optimizer.c 项目: sunqm/libcint
void CINTOpt_setij(CINTOpt *opt, FINT *ng,
                   FINT *atm, FINT natm,
                   FINT *bas, FINT nbas, double *env)
{
        FINT i, j, ip, jp, io, jo, off;
        if (opt->prim_offset == NULL) {
                opt->prim_offset = (FINT *)malloc(sizeof(FINT) * nbas);
                opt->tot_prim = 0;
                for (i = 0; i < nbas; i++) {
                        opt->prim_offset[i] = opt->tot_prim;
                        opt->tot_prim += bas(NPRIM_OF, i);
                }
        }

        FINT ijkl_inc;
        if ((ng[IINC]+ng[JINC]) > (ng[KINC]+ng[LINC])) {
                ijkl_inc = ng[IINC] + ng[JINC];
        } else {
                ijkl_inc = ng[KINC] + ng[LINC];
        }

        FINT iprim, ictr, jprim, jctr, il, jl;
        double eij, aij, rr, maxci, maxcj, rirj_g4d;
        double *ai, *aj, *ri, *rj, *ci, *cj;
        double *expij, *rij;
        FINT *cceij;
        opt->expij = (double **)malloc(sizeof(double *) * opt->tot_prim);
        opt->rij = (double **)malloc(sizeof(double *) * opt->tot_prim);
        opt->cceij = (FINT **)malloc(sizeof(FINT *) * opt->tot_prim);
        for (i = 0; i < nbas; i++) {
                ri = env + atm(PTR_COORD,bas(ATOM_OF,i));
                ai = env + bas(PTR_EXP,i);
                io = opt->prim_offset[i];
                iprim = bas(NPRIM_OF,i);
                ictr = bas(NCTR_OF,i);
                ci = env + bas(PTR_COEFF,i);
// For derivative/dipole operator, the l-value in g2e is virtually increased
                il = bas(ANG_OF,i);
                for (ip = 0; ip < bas(NPRIM_OF,i); ip++) {
                        maxci = max_pgto_coeff(ci, iprim, ictr, ip);
                        maxci = maxci / CINTgto_norm(bas(ANG_OF,i), ai[ip]);
                        expij = (double *)malloc(sizeof(double)*opt->tot_prim);
                        rij = (double *)malloc(sizeof(double)*opt->tot_prim*3);
                        cceij = (FINT *)malloc(sizeof(FINT) * opt->tot_prim);
                        opt->expij[io+ip] = expij;
                        opt->rij[io+ip] = rij;
                        opt->cceij[io+ip] = cceij;

                        for (j = 0; j < nbas; j++) {
                                rj = env + atm(PTR_COORD,bas(ATOM_OF,j));
                                aj = env + bas(PTR_EXP,j);
                                jo = opt->prim_offset[j];
                                jprim = bas(NPRIM_OF,j);
                                jctr = bas(NCTR_OF,j);
                                cj = env + bas(PTR_COEFF,j);
                                jl = bas(ANG_OF,j);
                                rr = (ri[0]-rj[0])*(ri[0]-rj[0])
                                   + (ri[1]-rj[1])*(ri[1]-rj[1])
                                   + (ri[2]-rj[2])*(ri[2]-rj[2]);
                                for (jp = 0; jp < bas(NPRIM_OF,j); jp++) {
                                        maxcj = max_pgto_coeff(cj, jprim, jctr, jp);
                                        maxcj = maxcj / CINTgto_norm(bas(ANG_OF,j), aj[jp]);
                                        aij = ai[ip] + aj[jp];
                                        off = jo + jp;
                                        eij = rr * ai[ip] * aj[jp] / aij;
                                        expij[off] = exp(-eij);
                                        rij[off*3+0] = (ai[ip]*ri[0] + aj[jp]*rj[0]) / aij;
                                        rij[off*3+1] = (ai[ip]*ri[1] + aj[jp]*rj[1]) / aij;
                                        rij[off*3+2] = (ai[ip]*ri[2] + aj[jp]*rj[2]) / aij;

        if (maxci*maxcj == 0) {
                cceij[off] = 750;
        } else if (rr > 1e-12) {
/* value estimation based on g0_2e_2d and g0_xx2d_4d,
 * value/exp(-eij) ~< (il+jl+2)!*(aij/2)^(il+jl)*(ri_or_rj-rij)^(ij+jl)*rirj^max(il,jl)
 *                 ~< (il+jl+2)!*(aij/2)^(il+jl)*|rirj|^((il+jl)+max(il,jl))
 * But in practice, |rirj|^((il+jl)/2) is large enough to cover all other factors */
                rirj_g4d = pow(rr+0.5, (il+jl+ijkl_inc+1)/2);
                cceij[off] = eij - log(maxci*maxcj*rirj_g4d);
        } else {
/* If basis on the same center, include the (ss|ss)^{1/2} contribution
 * (ss|ss) = 2\sqrt{aij/pi} */
                cceij[off] = -log(maxci*maxcj) - log(aij)/4;
        }
                                }
                        }
                }
        }
}
示例#2
0
void CINTOpt_setij(CINTOpt *opt, FINT *ng,
                   const FINT *atm, const FINT natm,
                   const FINT *bas, const FINT nbas, const double *env)
{
        FINT i, j, ip, jp, io, jo, off;
        if (!opt->prim_offset) {
                opt->prim_offset = (FINT *)malloc(sizeof(FINT) * nbas);
                opt->tot_prim = 0;
                for (i = 0; i < nbas; i++) {
                        opt->prim_offset[i] = opt->tot_prim;
                        opt->tot_prim += bas(NPRIM_OF, i);
                }
        }

        FINT ik_inc, jl_inc;
        if ((ng[IINC]+ng[JINC]) > (ng[KINC]+ng[LINC])) {
                ik_inc = ng[IINC];
                jl_inc = ng[JINC];
        } else {
                ik_inc = ng[KINC];
                jl_inc = ng[LINC];
        }

        FINT iprim, ictr, jprim, jctr, il, jl;
        double eij, aij, rr, maxci, maxcj, rirj_g4d;
        const double *ai, *aj, *ri, *rj, *ci, *cj;
        double *expij, *rij;
        FINT *cceij;
        opt->expij = (double **)malloc(sizeof(double *) * opt->tot_prim);
        opt->rij = (double **)malloc(sizeof(double *) * opt->tot_prim);
        opt->cceij = (FINT **)malloc(sizeof(FINT *) * opt->tot_prim);
        for (i = 0; i < nbas; i++) {
                ri = env + atm(PTR_COORD,bas(ATOM_OF,i));
                ai = env + bas(PTR_EXP,i);
                io = opt->prim_offset[i];
                iprim = bas(NPRIM_OF,i);
                ictr = bas(NCTR_OF,i);
                ci = env + bas(PTR_COEFF,i);
// For derivative/dipole operator, the l-value in g2e is virtually increased
                il = bas(ANG_OF,i) + ik_inc;
                for (ip = 0; ip < bas(NPRIM_OF,i); ip++) {
                        maxci = max_pgto_coeff(ci, iprim, ictr, ip);
                        maxci = maxci / CINTgto_norm(il, ai[ip]);
                        expij = (double *)malloc(sizeof(double)*opt->tot_prim);
                        rij = (double *)malloc(sizeof(double)*opt->tot_prim*3);
                        cceij = (FINT *)malloc(sizeof(FINT) * opt->tot_prim);
                        opt->expij[io+ip] = expij;
                        opt->rij[io+ip] = rij;
                        opt->cceij[io+ip] = cceij;

                        for (j = 0; j < nbas; j++) {
                                rj = env + atm(PTR_COORD,bas(ATOM_OF,j));
                                aj = env + bas(PTR_EXP,j);
                                jo = opt->prim_offset[j];
                                jprim = bas(NPRIM_OF,j);
                                jctr = bas(NCTR_OF,j);
                                cj = env + bas(PTR_COEFF,j);
                                jl = bas(ANG_OF,j) + jl_inc;
                                rr = (ri[0]-rj[0])*(ri[0]-rj[0])
                                   + (ri[1]-rj[1])*(ri[1]-rj[1])
                                   + (ri[2]-rj[2])*(ri[2]-rj[2]);
                                for (jp = 0; jp < bas(NPRIM_OF,j); jp++) {
                                        maxcj = max_pgto_coeff(cj, jprim, jctr, jp);
                                        maxcj = maxcj/CINTgto_norm(jl, aj[jp]);
                                        aij = ai[ip] + aj[jp];
                                        off = jo + jp;
                                        eij = rr * ai[ip] * aj[jp] / aij;
                                        expij[off] = exp(-eij);
                                        rij[off*3+0] = (ai[ip]*ri[0] + aj[jp]*rj[0]) / aij;
                                        rij[off*3+1] = (ai[ip]*ri[1] + aj[jp]*rj[1]) / aij;
                                        rij[off*3+2] = (ai[ip]*ri[2] + aj[jp]*rj[2]) / aij;
/* estimation of the value, based on g0_2e_2d and g0_xx2d_4d,
 * value ~< exp(-eij)*(il+jl+2)!*(aij/2)^(il+jl)*(ri_or_rj-rij)^(ij+jl)*rirj^max(il,jl)
 *       ~< *       exp(-eij)*(il+jl+2)!*(aij/2)^(il+jl)*rirj^((il+jl)+max(il,jl))
 * But in practice, rirj^((il+jl)/2) is usually large enough to cover all other factors */
/* rr+1 to prevent log() diverge when i,j on same center */
                                        rirj_g4d = pow((rr+1), (il+jl+1)/2);
/*cceij[off] =-log(expij[off]*maxci*maxcj*rirj_g4d);
  when eij is big, expij == 0, singular value in cceij */
                                        cceij[off] = eij - log(maxci*maxcj*rirj_g4d);
                                }
                        }
                }
        }
}