def make_L1(pcmobj, r_vdw, ylm_1sph, fi): # See JCTC, 9, 3637, Eq (18) mol = pcmobj.mol natm = mol.natm lmax = pcmobj.lmax eta = pcmobj.eta nlm = (lmax + 1)**2 coords_1sph, weights_1sph = ddcosmo.make_grids_one_sphere( pcmobj.lebedev_order) ngrid_1sph = weights_1sph.size atom_coords = mol.atom_coords() ylm_1sph = ylm_1sph.reshape(nlm, ngrid_1sph) Lmat = numpy.zeros((natm, 3, natm, nlm, natm, nlm)) fi1 = make_fi1(pcmobj, pcmobj.get_atomic_radii()) for ja in range(natm): part_weights = weights_1sph.copy() part_weights[fi[ja] > 1] /= fi[ja, fi[ja] > 1] part_weights1 = numpy.zeros((natm, 3, ngrid_1sph)) tmp = part_weights[fi[ja] > 1] / fi[ja, fi[ja] > 1] part_weights1[:, :, fi[ja] > 1] = -tmp * fi1[:, :, ja, fi[ja] > 1] for ka in ddcosmo.atoms_with_vdw_overlap(ja, atom_coords, r_vdw): vjk = r_vdw[ja] * coords_1sph + atom_coords[ja] - atom_coords[ka] rv = lib.norm(vjk, axis=1) tjk = rv / r_vdw[ka] wjk0 = pcmobj.regularize_xt(tjk, eta, r_vdw[ka]) wjk1 = regularize_xt1(tjk, eta * r_vdw[ka]) sjk = vjk.T / rv wjk1 = 1. / r_vdw[ka] * wjk1 * sjk wjk01 = wjk0 * part_weights1 wjk0 *= part_weights wjk1 *= part_weights pol0 = sph.multipoles(vjk, lmax) pol1 = multipoles1(vjk, lmax) p1 = 0 for l in range(lmax + 1): fac = 4 * numpy.pi / (l * 2 + 1) / r_vdw[ka]**(l + 1) p0, p1 = p1, p1 + (l * 2 + 1) a = numpy.einsum('xn,zn,mn->zxm', ylm_1sph, wjk1, pol0[l]) a += numpy.einsum('xn,n,zmn->zxm', ylm_1sph, wjk0, pol1[l]) Lmat[ja, :, ja, :, ka, p0:p1] += -fac * a Lmat[ka, :, ja, :, ka, p0:p1] -= -fac * a a = numpy.einsum('xn,azn,mn->azxm', ylm_1sph, wjk01, pol0[l]) Lmat[:, :, ja, :, ka, p0:p1] += -fac * a return Lmat
def make_L1(pcmobj, r_vdw, ylm_1sph, fi): # See JCTC, 9, 3637, Eq (18) mol = pcmobj.mol natm = mol.natm lmax = pcmobj.lmax eta = pcmobj.eta nlm = (lmax+1)**2 coords_1sph, weights_1sph = ddcosmo.make_grids_one_sphere(pcmobj.lebedev_order) ngrid_1sph = weights_1sph.size atom_coords = mol.atom_coords() ylm_1sph = ylm_1sph.reshape(nlm,ngrid_1sph) Lmat = numpy.zeros((natm,3,natm,nlm,natm,nlm)) fi1 = make_fi1(pcmobj, pcmobj.get_atomic_radii()) for ja in range(natm): part_weights = weights_1sph.copy() part_weights[fi[ja]>1] /= fi[ja,fi[ja]>1] part_weights1 = numpy.zeros((natm,3,ngrid_1sph)) tmp = part_weights[fi[ja]>1] / fi[ja,fi[ja]>1] part_weights1[:,:,fi[ja]>1] = -tmp * fi1[:,:,ja,fi[ja]>1] for ka in ddcosmo.atoms_with_vdw_overlap(ja, atom_coords, r_vdw): vjk = r_vdw[ja] * coords_1sph + atom_coords[ja] - atom_coords[ka] rv = lib.norm(vjk, axis=1) tjk = rv / r_vdw[ka] wjk0 = pcmobj.regularize_xt(tjk, eta, r_vdw[ka]) wjk1 = regularize_xt1(tjk, eta*r_vdw[ka]) sjk = vjk.T / rv wjk1 = 1./r_vdw[ka] * wjk1 * sjk wjk01 = wjk0 * part_weights1 wjk0 *= part_weights wjk1 *= part_weights pol0 = sph.multipoles(vjk, lmax) pol1 = multipoles1(vjk, lmax) p1 = 0 for l in range(lmax+1): fac = 4*numpy.pi/(l*2+1) / r_vdw[ka]**(l+1) p0, p1 = p1, p1 + (l*2+1) a = numpy.einsum('xn,zn,mn->zxm', ylm_1sph, wjk1, pol0[l]) a+= numpy.einsum('xn,n,zmn->zxm', ylm_1sph, wjk0, pol1[l]) Lmat[ja,:,ja,:,ka,p0:p1] += -fac * a Lmat[ka,:,ja,:,ka,p0:p1] -= -fac * a a = numpy.einsum('xn,azn,mn->azxm', ylm_1sph, wjk01, pol0[l]) Lmat[:,:,ja,:,ka,p0:p1] += -fac * a return Lmat
def make_fi1(pcmobj, r_vdw): coords_1sph, weights_1sph = ddcosmo.make_grids_one_sphere(pcmobj.lebedev_order) mol = pcmobj.mol eta = pcmobj.eta natm = mol.natm atom_coords = mol.atom_coords() ngrid_1sph = coords_1sph.shape[0] fi1 = numpy.zeros((natm,3,natm,ngrid_1sph)) for ia in range(natm): for ja in ddcosmo.atoms_with_vdw_overlap(ia, atom_coords, r_vdw): v = r_vdw[ia]*coords_1sph + atom_coords[ia] - atom_coords[ja] rv = lib.norm(v, axis=1) t = rv / r_vdw[ja] xt1 = regularize_xt1(t, eta*r_vdw[ja]) s_ij = v.T / rv xt1 = 1./r_vdw[ja] * xt1 * s_ij fi1[ia,:,ia] += xt1 fi1[ja,:,ia] -= xt1 fi = ddcosmo.make_fi(pcmobj, r_vdw) fi1[:,:,fi<1e-20] = 0 return fi1
def make_A(pcmobj, r_vdw, ylm_1sph, ui): # Part of A matrix defined in JCP, 144, 054101, Eq (43), (44) mol = pcmobj.mol natm = mol.natm lmax = pcmobj.lmax eta = pcmobj.eta nlm = (lmax + 1)**2 coords_1sph, weights_1sph = ddcosmo.make_grids_one_sphere( pcmobj.lebedev_order) ngrid_1sph = weights_1sph.size atom_coords = mol.atom_coords() ylm_1sph = ylm_1sph.reshape(nlm, ngrid_1sph) Amat = numpy.zeros((natm, nlm, natm, nlm)) for ja in range(natm): # w_u = precontract w_n U_j w_u = weights_1sph * ui[ja] p1 = 0 for l in range(lmax + 1): fac = 2 * numpy.pi / (l * 2 + 1) p0, p1 = p1, p1 + (l * 2 + 1) a = numpy.einsum('xn,n,mn->xm', ylm_1sph, w_u, ylm_1sph[p0:p1]) Amat[ja, :, ja, p0:p1] += -fac * a for ka in ddcosmo.atoms_with_vdw_overlap(ja, atom_coords, r_vdw): vjk = r_vdw[ja] * coords_1sph + atom_coords[ja] - atom_coords[ka] rjk = lib.norm(vjk, axis=1) pol = sph.multipoles(vjk, lmax) p1 = 0 weights = w_u / rjk**(l * 2 + 1) for l in range(lmax + 1): fac = 4 * numpy.pi * l / (l * 2 + 1) * r_vdw[ka]**(l + 1) p0, p1 = p1, p1 + (l * 2 + 1) a = numpy.einsum('xn,n,mn->xm', ylm_1sph, weights, pol[l]) Amat[ja, :, ka, p0:p1] += -fac * a return Amat
def make_A(pcmobj, r_vdw, ylm_1sph, ui): # Part of A matrix defined in JCP, 144, 054101, Eq (43), (44) mol = pcmobj.mol natm = mol.natm lmax = pcmobj.lmax eta = pcmobj.eta nlm = (lmax+1)**2 coords_1sph, weights_1sph = ddcosmo.make_grids_one_sphere(pcmobj.lebedev_order) ngrid_1sph = weights_1sph.size atom_coords = mol.atom_coords() ylm_1sph = ylm_1sph.reshape(nlm,ngrid_1sph) Amat = numpy.zeros((natm,nlm,natm,nlm)) for ja in range(natm): # w_u = precontract w_n U_j w_u = weights_1sph * ui[ja] p1 = 0 for l in range(lmax+1): fac = 2*numpy.pi/(l*2+1) p0, p1 = p1, p1 + (l*2+1) a = numpy.einsum('xn,n,mn->xm', ylm_1sph, w_u, ylm_1sph[p0:p1]) Amat[ja,:,ja,p0:p1] += -fac * a for ka in ddcosmo.atoms_with_vdw_overlap(ja, atom_coords, r_vdw): vjk = r_vdw[ja] * coords_1sph + atom_coords[ja] - atom_coords[ka] rjk = lib.norm(vjk, axis=1) pol = sph.multipoles(vjk, lmax) p1 = 0 weights = w_u / rjk**(l*2+1) for l in range(lmax+1): fac = 4*numpy.pi*l/(l*2+1) * r_vdw[ka]**(l+1) p0, p1 = p1, p1 + (l*2+1) a = numpy.einsum('xn,n,mn->xm', ylm_1sph, weights, pol[l]) Amat[ja,:,ka,p0:p1] += -fac * a return Amat