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; } } } } } }
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); } } } } }