def make_modchg_basis(auxcell, smooth_eta): # * chgcell defines smooth gaussian functions for each angular momentum for # auxcell. The smooth functions may be used to carry the charge chgcell = copy.copy( auxcell) # smooth model density for coulomb integral to carry charge half_sph_norm = .5 / numpy.sqrt(numpy.pi) chg_bas = [] chg_env = [smooth_eta] ptr_eta = auxcell._env.size ptr = ptr_eta + 1 l_max = auxcell._bas[:, gto.ANG_OF].max() # gaussian_int(l*2+2) for multipole integral: # \int (r^l e^{-ar^2} * Y_{lm}) (r^l Y_{lm}) r^2 dr d\Omega norms = [ half_sph_norm / gto.gaussian_int(l * 2 + 2, smooth_eta) for l in range(l_max + 1) ] for ia in range(auxcell.natm): for l in set(auxcell._bas[auxcell._bas[:, gto.ATOM_OF] == ia, gto.ANG_OF]): chg_bas.append([ia, l, 1, 1, 0, ptr_eta, ptr, 0]) chg_env.append(norms[l]) ptr += 1 chgcell._atm = auxcell._atm chgcell._bas = numpy.asarray(chg_bas, dtype=numpy.int32).reshape(-1, gto.BAS_SLOTS) chgcell._env = numpy.hstack((auxcell._env, chg_env)) chgcell.rcut = _estimate_rcut(smooth_eta, l_max, 1., auxcell.precision) logger.debug1(auxcell, 'make compensating basis, num shells = %d, num cGTOs = %d', chgcell.nbas, chgcell.nao_nr()) logger.debug1(auxcell, 'chgcell.rcut %s', chgcell.rcut) return chgcell
def make_modchg_basis(auxcell, smooth_eta): # * chgcell defines smooth gaussian functions for each angular momentum for # auxcell. The smooth functions may be used to carry the charge chgcell = copy.copy(auxcell) # smooth model density for coulomb integral to carry charge half_sph_norm = .5/numpy.sqrt(numpy.pi) chg_bas = [] chg_env = [smooth_eta] ptr_eta = auxcell._env.size ptr = ptr_eta + 1 l_max = auxcell._bas[:,gto.ANG_OF].max() # gaussian_int(l*2+2) for multipole integral: # \int (r^l e^{-ar^2} * Y_{lm}) (r^l Y_{lm}) r^2 dr d\Omega norms = [half_sph_norm/gto.gaussian_int(l*2+2, smooth_eta) for l in range(l_max+1)] for ia in range(auxcell.natm): for l in set(auxcell._bas[auxcell._bas[:,gto.ATOM_OF]==ia, gto.ANG_OF]): chg_bas.append([ia, l, 1, 1, 0, ptr_eta, ptr, 0]) chg_env.append(norms[l]) ptr += 1 chgcell._atm = auxcell._atm chgcell._bas = numpy.asarray(chg_bas, dtype=numpy.int32).reshape(-1,gto.BAS_SLOTS) chgcell._env = numpy.hstack((auxcell._env, chg_env)) chgcell.rcut = _estimate_rcut(smooth_eta, l_max, 1., auxcell.precision) logger.debug1(auxcell, 'make compensating basis, num shells = %d, num cGTOs = %d', chgcell.nbas, chgcell.nao_nr()) logger.debug1(auxcell, 'chgcell.rcut %s', chgcell.rcut) return chgcell
def make_modrho_basis(cell, auxbasis=None, drop_eta=1.): auxcell = copy.copy(cell) if auxbasis is None: auxbasis = 'weigend+etb' if isinstance(auxbasis, str): uniq_atoms = set([a[0] for a in cell._atom]) _basis = auxcell.format_basis(dict([(a, auxbasis) for a in uniq_atoms])) else: _basis = auxcell.format_basis(auxbasis) auxcell._basis = _basis auxcell._atm, auxcell._bas, auxcell._env = \ auxcell.make_env(cell._atom, auxcell._basis, cell._env[:gto.PTR_ENV_START]) # Note libcint library will multiply the norm of the integration over spheric # part sqrt(4pi) to the basis. half_sph_norm = numpy.sqrt(.25 / numpy.pi) steep_shls = [] ndrop = 0 rcut = [] for ib in range(len(auxcell._bas)): l = auxcell.bas_angular(ib) np = auxcell.bas_nprim(ib) nc = auxcell.bas_nctr(ib) es = auxcell.bas_exp(ib) ptr = auxcell._bas[ib, gto.PTR_COEFF] cs = auxcell._env[ptr:ptr + np * nc].reshape(nc, np).T if numpy.any(es < drop_eta): cs = cs[es >= drop_eta] es = es[es >= drop_eta] np, ndrop = len(es), ndrop + np - len(es) pe = auxcell._bas[ib, gto.PTR_EXP] auxcell._bas[ib, gto.NPRIM_OF] = np auxcell._env[pe:pe + np] = es if np > 0: # int1 is the multipole value. l*2+2 is due to the radial part integral # \int (r^l e^{-ar^2} * Y_{lm}) (r^l Y_{lm}) r^2 dr d\Omega int1 = gto.mole._gaussian_int(l * 2 + 2, es) s = numpy.einsum('pi,p->i', cs, int1) # The auxiliary basis normalization factor is not a must for density expansion. # half_sph_norm here to normalize the monopole (charge). This convention can # simplify the formulism of \int \bar{\rho}, see function auxbar. cs = numpy.einsum('pi,i->pi', cs, half_sph_norm / s) auxcell._env[ptr:ptr + np * nc] = cs.T.reshape(-1) steep_shls.append(ib) rcut.append(_estimate_rcut(es.min(), l, 1., 20, cell.precision)) auxcell.rcut = max(rcut) auxcell._bas = numpy.asarray(auxcell._bas[steep_shls], order='C') auxcell._built = True logger.debug(cell, 'Drop %d primitive fitting functions', ndrop) logger.debug(cell, 'make aux basis, num shells = %d, num cGTOs = %d', auxcell.nbas, auxcell.nao_nr()) logger.debug(cell, 'auxcell.rcut %s', auxcell.rcut) return auxcell
def make_modrho_basis(cell, auxbasis=None, drop_eta=None): auxcell = addons.make_auxmol(cell, auxbasis) # Note libcint library will multiply the norm of the integration over spheric # part sqrt(4pi) to the basis. half_sph_norm = numpy.sqrt(.25 / numpy.pi) steep_shls = [] ndrop = 0 rcut = [] _env = auxcell._env.copy() for ib in range(len(auxcell._bas)): l = auxcell.bas_angular(ib) np = auxcell.bas_nprim(ib) nc = auxcell.bas_nctr(ib) es = auxcell.bas_exp(ib) ptr = auxcell._bas[ib, gto.PTR_COEFF] cs = auxcell._env[ptr:ptr + np * nc].reshape(nc, np).T if drop_eta is not None and numpy.any(es < drop_eta): cs = cs[es >= drop_eta] es = es[es >= drop_eta] np, ndrop = len(es), ndrop + np - len(es) if np > 0: pe = auxcell._bas[ib, gto.PTR_EXP] auxcell._bas[ib, gto.NPRIM_OF] = np _env[pe:pe + np] = es # int1 is the multipole value. l*2+2 is due to the radial part integral # \int (r^l e^{-ar^2} * Y_{lm}) (r^l Y_{lm}) r^2 dr d\Omega int1 = gto.gaussian_int(l * 2 + 2, es) s = numpy.einsum('pi,p->i', cs, int1) # The auxiliary basis normalization factor is not a must for density expansion. # half_sph_norm here to normalize the monopole (charge). This convention can # simplify the formulism of \int \bar{\rho}, see function auxbar. cs = numpy.einsum('pi,i->pi', cs, half_sph_norm / s) _env[ptr:ptr + np * nc] = cs.T.reshape(-1) steep_shls.append(ib) r = _estimate_rcut(es, l, abs(cs).max(axis=1), cell.precision) rcut.append(r.max()) auxcell._env = _env auxcell.rcut = max(rcut) auxcell._bas = numpy.asarray(auxcell._bas[steep_shls], order='C') logger.info(cell, 'Drop %d primitive fitting functions', ndrop) logger.info(cell, 'make aux basis, num shells = %d, num cGTOs = %d', auxcell.nbas, auxcell.nao_nr()) logger.info(cell, 'auxcell.rcut %s', auxcell.rcut) return auxcell
def make_modrho_basis(cell, auxbasis=None, drop_eta=None): auxcell = addons.make_auxmol(cell, auxbasis) # Note libcint library will multiply the norm of the integration over spheric # part sqrt(4pi) to the basis. half_sph_norm = numpy.sqrt(.25/numpy.pi) steep_shls = [] ndrop = 0 rcut = [] for ib in range(len(auxcell._bas)): l = auxcell.bas_angular(ib) np = auxcell.bas_nprim(ib) nc = auxcell.bas_nctr(ib) es = auxcell.bas_exp(ib) ptr = auxcell._bas[ib,gto.PTR_COEFF] cs = auxcell._env[ptr:ptr+np*nc].reshape(nc,np).T if drop_eta is not None and numpy.any(es < drop_eta): cs = cs[es>=drop_eta] es = es[es>=drop_eta] np, ndrop = len(es), ndrop+np-len(es) if np > 0: pe = auxcell._bas[ib,gto.PTR_EXP] auxcell._bas[ib,gto.NPRIM_OF] = np auxcell._env[pe:pe+np] = es # int1 is the multipole value. l*2+2 is due to the radial part integral # \int (r^l e^{-ar^2} * Y_{lm}) (r^l Y_{lm}) r^2 dr d\Omega int1 = gto.gaussian_int(l*2+2, es) s = numpy.einsum('pi,p->i', cs, int1) # The auxiliary basis normalization factor is not a must for density expansion. # half_sph_norm here to normalize the monopole (charge). This convention can # simplify the formulism of \int \bar{\rho}, see function auxbar. cs = numpy.einsum('pi,i->pi', cs, half_sph_norm/s) auxcell._env[ptr:ptr+np*nc] = cs.T.reshape(-1) steep_shls.append(ib) r = _estimate_rcut(es, l, abs(cs).max(axis=1), cell.precision) rcut.append(r.max()) auxcell.rcut = max(rcut) auxcell._bas = numpy.asarray(auxcell._bas[steep_shls], order='C') logger.info(cell, 'Drop %d primitive fitting functions', ndrop) logger.info(cell, 'make aux basis, num shells = %d, num cGTOs = %d', auxcell.nbas, auxcell.nao_nr()) logger.info(cell, 'auxcell.rcut %s', auxcell.rcut) return auxcell