def multipoles1(r, lmax, reorder_dipole=True): ngrid = r.shape[0] xs = numpy.ones((lmax+1,ngrid)) ys = numpy.ones((lmax+1,ngrid)) zs = numpy.ones((lmax+1,ngrid)) for i in range(1,lmax+1): xs[i] = xs[i-1] * r[:,0] ys[i] = ys[i-1] * r[:,1] zs[i] = zs[i-1] * r[:,2] ylms = [] for l in range(lmax+1): nd = (l+1)*(l+2)//2 c = numpy.empty((nd,3,ngrid)) k = 0 for lx in reversed(range(0, l+1)): for ly in reversed(range(0, l-lx+1)): lz = l - lx - ly c[k,0] = lx * xs[lx-1] * ys[ly] * zs[lz] c[k,1] = ly * xs[lx] * ys[ly-1] * zs[lz] c[k,2] = lz * xs[lx] * ys[ly] * zs[lz-1] k += 1 ylm = gto.cart2sph(l, c.reshape(nd,3*ngrid).T) ylm = ylm.reshape(3,ngrid,l*2+1).transpose(0,2,1) ylms.append(ylm) # when call libcint, p functions are ordered as px,py,pz # reorder px,py,pz to p(-1),p(0),p(1) if (not reorder_dipole) and lmax >= 1: ylms[1] = ylms[1][:,[1,2,0]] return ylms
def write_mo(fout, mol, mo_coeff, mo_energy=None, mo_occ=None): nmo = mo_coeff.shape[1] mo_cart = [] centers = [] types = [] exps = [] p0 = 0 for ib in range(mol.nbas): ia = mol.bas_atom(ib) l = mol.bas_angular(ib) es = mol.bas_exp(ib) c = mol.bas_ctr_coeff(ib) np, nc = c.shape nd = nc * (2 * l + 1) mosub = mo_coeff[p0:p0 + nd].reshape(-1, nc, nmo) c2s = gto.cart2sph(l) mosub = numpy.einsum('yki,cy,pk->pci', mosub, c2s, c) mo_cart.append(mosub.reshape(-1, nmo)) for t in TYPE_MAP[l]: types.append([t] * np) ncart = gto.len_cart(l) exps.extend([es] * ncart) centers.extend([ia + 1] * (np * ncart)) p0 += nd mo_cart = numpy.vstack(mo_cart) centers = numpy.hstack(centers) types = numpy.hstack(types) exps = numpy.hstack(exps) nprim, nmo = mo_cart.shape fout.write('title line\n') fout.write( 'GAUSSIAN %3d MOL ORBITALS %3d PRIMITIVES %3d NUCLEI\n' % (mo_cart.shape[1], mo_cart.shape[0], mol.natm)) for ia in range(mol.natm): x, y, z = mol.atom_coord(ia) fout.write( '%-4s %-4d (CENTRE%3d) %12.8f %12.8f %12.8f CHARGE = %.1f\n' % (mol.atom_pure_symbol(ia), ia, ia, x, y, z, mol.atom_charge(ia))) for i0, i1 in lib.prange(0, nprim, 20): fout.write('CENTRE ASSIGNMENTS %s\n' % ''.join('%3d' % x for x in centers[i0:i1])) for i0, i1 in lib.prange(0, nprim, 20): fout.write('TYPE ASSIGNMENTS %s\n' % ''.join('%3d' % x for x in types[i0:i1])) for i0, i1 in lib.prange(0, nprim, 5): fout.write('EXPONENTS %s\n' % ' '.join('%14.7E' % x for x in exps[i0:i1])) for k in range(nmo): mo = mo_cart[:, k] if mo_energy is None or mo_occ is None: fout.write('CANMO %d\n' (k, mo_occ[k], mo_energy[k])) else: fout.write( 'MO %-4d OCC NO = %12.8f ORB. ENERGY = %12.8f\n' % (k, mo_occ[k], mo_energy[k])) for i0, i1 in lib.prange(0, nprim, 5): fout.write('%s\n' % ' '.join('%15.8E' % x for x in mo[i0:i1]))
def write_mo(fout, mol, mo_coeff, mo_energy=None, mo_occ=None): nmo = mo_coeff.shape[1] mo_cart = [] centers = [] types = [] exps = [] p0 = 0 for ib in range(mol.nbas): ia = mol.bas_atom(ib) l = mol.bas_angular(ib) es = mol.bas_exp(ib) c = mol.bas_ctr_coeff(ib) np, nc = c.shape nd = nc*(2*l+1) mosub = mo_coeff[p0:p0+nd].reshape(-1,nc,nmo) c2s = gto.cart2sph(l) mosub = numpy.einsum('yki,cy,pk->pci', mosub, c2s, c) mo_cart.append(mosub.reshape(-1,nmo)) for t in TYPE_MAP[l]: types.append([t]*np) ncart = gto.len_cart(l) exps.extend([es]*ncart) centers.extend([ia+1]*(np*ncart)) p0 += nd mo_cart = numpy.vstack(mo_cart) centers = numpy.hstack(centers) types = numpy.hstack(types) exps = numpy.hstack(exps) nprim, nmo = mo_cart.shape fout.write('title line\n') fout.write('GAUSSIAN %3d MOL ORBITALS %3d PRIMITIVES %3d NUCLEI\n' % (mo_cart.shape[1], mo_cart.shape[0], mol.natm)) for ia in range(mol.natm): x, y, z = mol.atom_coord(ia) fout.write('%-4s %-4d (CENTRE%3d) %12.8f %12.8f %12.8f CHARGE = %.1f\n' % (mol.atom_pure_symbol(ia), ia, ia, x, y, z, mol.atom_charge(ia))) for i0, i1 in lib.prange(0, nprim, 20): fout.write('CENTRE ASSIGNMENTS %s\n' % ''.join('%3d'%x for x in centers[i0:i1])) for i0, i1 in lib.prange(0, nprim, 20): fout.write('TYPE ASSIGNMENTS %s\n' % ''.join('%3d'%x for x in types[i0:i1])) for i0, i1 in lib.prange(0, nprim, 5): fout.write('EXPONENTS %s\n' % ' '.join('%14.7E'%x for x in exps[i0:i1])) for k in range(nmo): mo = mo_cart[:,k] if mo_energy is None or mo_occ is None: fout.write('CANMO %d\n' (k, mo_occ[k], mo_energy[k])) else: fout.write('MO %-4d OCC NO = %12.8f ORB. ENERGY = %12.8f\n' % (k, mo_occ[k], mo_energy[k])) for i0, i1 in lib.prange(0, nprim, 5): fout.write('%s\n' % ' '.join('%15.8E'%x for x in mo[i0:i1]))
def multipoles(r, lmax, reorder_dipole=True): ''' Compute all multipoles upto lmax rad = numpy.linalg.norm(r, axis=1) ylms = real_ylm(r/rad.reshape(-1,1), lmax) pol = [rad**l*y for l, y in enumerate(ylms)] Kwargs: reorder_p : bool sort dipole to the order (x,y,z) ''' from pyscf import gto # libcint cart2sph transformation provide the capability to compute # multipole directly. cart2sph function is fast for low angular moment. ngrid = r.shape[0] xs = numpy.ones((lmax + 1, ngrid)) ys = numpy.ones((lmax + 1, ngrid)) zs = numpy.ones((lmax + 1, ngrid)) for i in range(1, lmax + 1): xs[i] = xs[i - 1] * r[:, 0] ys[i] = ys[i - 1] * r[:, 1] zs[i] = zs[i - 1] * r[:, 2] ylms = [] for l in range(lmax + 1): nd = (l + 1) * (l + 2) // 2 c = numpy.empty((nd, ngrid)) k = 0 for lx in reversed(range(0, l + 1)): for ly in reversed(range(0, l - lx + 1)): lz = l - lx - ly c[k] = xs[lx] * ys[ly] * zs[lz] k += 1 ylm = gto.cart2sph(l, c.T).T ylms.append(ylm) # when call libcint, p functions are ordered as px,py,pz # reorder px,py,pz to p(-1),p(0),p(1) if (not reorder_dipole) and lmax >= 1: ylms[1] = ylms[1][[1, 2, 0]] return ylms
def write_coeff(fout, mol, mo_coeff): #fout.write('ALDET\n') nmo = mo_coeff.shape[1] mo_cart = [] centers = [] types = [] exps = [] p0 = 0 for ib in range(mol.nbas): ia = mol.bas_atom(ib) l = mol.bas_angular(ib) es = mol.bas_exp(ib) c = mol._libcint_ctr_coeff(ib) #c = mol.bas_ctr_coeff(ib) np, nc = c.shape nd = nc*(2*l+1) mosub = mo_coeff[p0:p0+nd].reshape(-1,nc,nmo) c2s = gto.cart2sph(l) mosub = numpy.einsum('yki,cy,pk->pci', mosub, c2s, c) mo_cart.append(mosub.transpose(1,0,2).reshape(-1,nmo)) for t in TYPE_MAP[l]: types.append([t]*np) ncart = gto.len_cart(l) exps.extend([es]*ncart) centers.extend([ia+1]*(np*ncart)) p0 += nd mo_cart = numpy.vstack(mo_cart) centers = numpy.hstack(centers) types = numpy.hstack(types) exps = numpy.hstack(exps) nprim, nmo = mo_cart.shape fout.write('From PySCF\n') for k in range(nmo): mo = mo_cart[:,k] fout.write('CANMO %d\n' % (k+1)) for i0, i1 in lib.prange(0, nprim, 5): fout.write(' %s\n' % ' '.join('%15.8E'%x for x in mo[i0:i1])) fout.write('END DATA\n')
def mo_comps(test, mol, mo_coeff, cart=False, orth_method='meta_lowdin'): '''Pick particular AOs based on the given test function compute the AO components ''' if cart: s = mol.intor_symmetric('cint1e_ovlp_cart') preao = lo.orth.pre_orth_ao(mol) tc2s = [] for ib in range(mol.nbas): l = mol.bas_angular(ib) tc2s.append(gto.cart2sph(l)) tc2s = scipy.linalg.block_diag(*tc2s) lao = lo.orth.orth_ao(mol, orth_method) lao = numpy.dot(tc2s, lao) else: s = mol.intor_symmetric('cint1e_ovlp_sph') lao = lo.orth.orth_ao(mol, orth_method) idx = [i for i,x in enumerate(mol.spheric_labels(1)) if test(x)] idx = numpy.array(idx) mo1 = reduce(numpy.dot, (lao[:,idx].T, s, mo_coeff)) s1 = numpy.einsum('ki,ki->i', mo1, mo1) return s1
def write_mo(fout, mol, mo_coeff, mo_energy=None, mo_occ=None): if mol.cart: raise NotImplementedError('Cartesian basis not available') #FIXME: Duplicated primitives may lead to problems. x2c._uncontract_mol # is the workaround at the moment to remove duplicated primitives. from pyscf.x2c import x2c mol, ctr = x2c._uncontract_mol(mol, True, 0.) mo_coeff = numpy.dot(ctr, mo_coeff) nmo = mo_coeff.shape[1] mo_cart = [] centers = [] types = [] exps = [] p0 = 0 for ib in range(mol.nbas): ia = mol.bas_atom(ib) l = mol.bas_angular(ib) es = mol.bas_exp(ib) c = mol._libcint_ctr_coeff(ib) np, nc = c.shape nd = nc*(2*l+1) mosub = mo_coeff[p0:p0+nd].reshape(-1,nc,nmo) c2s = gto.cart2sph(l) mosub = numpy.einsum('yki,cy,pk->pci', mosub, c2s, c) mo_cart.append(mosub.transpose(1,0,2).reshape(-1,nmo)) for t in TYPE_MAP[l]: types.append([t]*np) ncart = mol.bas_len_cart(ib) exps.extend([es]*ncart) centers.extend([ia+1]*(np*ncart)) p0 += nd mo_cart = numpy.vstack(mo_cart) centers = numpy.hstack(centers) types = numpy.hstack(types) exps = numpy.hstack(exps) nprim, nmo = mo_cart.shape fout.write('From PySCF\n') fout.write('GAUSSIAN %3d MOL ORBITALS %3d PRIMITIVES %3d NUCLEI\n' % (mo_cart.shape[1], mo_cart.shape[0], mol.natm)) for ia in range(mol.natm): x, y, z = mol.atom_coord(ia) fout.write(' %-4s %-4d (CENTRE%3d) %11.8f %11.8f %11.8f CHARGE = %.1f\n' % (mol.atom_pure_symbol(ia), ia+1, ia+1, x, y, z, mol.atom_charge(ia))) for i0, i1 in lib.prange(0, nprim, 20): fout.write('CENTRE ASSIGNMENTS %s\n' % ''.join('%3d'%x for x in centers[i0:i1])) for i0, i1 in lib.prange(0, nprim, 20): fout.write('TYPE ASSIGNMENTS %s\n' % ''.join('%3d'%x for x in types[i0:i1])) for i0, i1 in lib.prange(0, nprim, 5): fout.write('EXPONENTS %s\n' % ' '.join('%13.7E'%x for x in exps[i0:i1])) for k in range(nmo): mo = mo_cart[:,k] if mo_energy is None and mo_occ is None: fout.write('CANMO %d\n' % (k+1)) elif mo_energy is None: fout.write('MO %-4d OCC NO = %12.8f ORB. ENERGY = 0.0000\n' % (k+1, mo_occ[k])) else: fout.write('MO %-4d OCC NO = %12.8f ORB. ENERGY = %12.8f\n' % (k+1, mo_occ[k], mo_energy[k])) for i0, i1 in lib.prange(0, nprim, 5): fout.write(' %s\n' % ' '.join('%15.8E'%x for x in mo[i0:i1])) fout.write('END DATA\n') if mo_energy is None or mo_occ is None: fout.write('ALDET ENERGY = 0.0000000000 VIRIAL(-V/T) = 0.00000000\n') elif mo_energy is None and mo_occ is None: pass else : fout.write('RHF ENERGY = 0.0000000000 VIRIAL(-V/T) = 0.00000000\n')
def write_wfn(fout, mol, mo_coeff, mo_energy, mo_occ, tot_ener): from pyscf.x2c import x2c mol, ctr = x2c._uncontract_mol(mol, True, 0.) mo_coeff = numpy.dot(ctr, mo_coeff) nmo = mo_coeff.shape[1] mo_cart = [] from pyscf import gto centers = [] types = [] exps = [] p0 = 0 for ib in range(mol.nbas): ia = mol.bas_atom(ib) l = mol.bas_angular(ib) es = mol.bas_exp(ib) c = mol._libcint_ctr_coeff(ib) np, nc = c.shape nd = nc * (2 * l + 1) mosub = mo_coeff[p0:p0 + nd].reshape(-1, nc, nmo) c2s = gto.cart2sph(l) mosub = numpy.einsum('yki,cy,pk->pci', mosub, c2s, c) mo_cart.append(mosub.transpose(1, 0, 2).reshape(-1, nmo)) for t in TYPE_MAP[l]: types.append([t] * np) ncart = mol.bas_len_cart(ib) exps.extend([es] * ncart) centers.extend([ia + 1] * (np * ncart)) p0 += nd mo_cart = numpy.vstack(mo_cart) centers = numpy.hstack(centers) types = numpy.hstack(types) exps = numpy.hstack(exps) nprim, nmo = mo_cart.shape fout.write('From PySCF\\n') fout.write('GAUSSIAN %14d MOL ORBITALS %6d PRIMITIVES %8d NUCLEI\\n' % (mo_cart.shape[1], mo_cart.shape[0], mol.natm)) for ia in range(mol.natm): x, y, z = mol.atom_coord(ia) fout.write('%3s%8d (CENTRE%3d) %12.8f%12.8f%12.8f CHARGE = %4.1f\\n' % (mol.atom_pure_symbol(ia), ia + 1, ia + 1, x, y, z, mol.atom_charge(ia))) for i0, i1 in lib.prange(0, nprim, 20): fout.write('CENTRE ASSIGNMENTS %s\\n' % ''.join('%3d' % x for x in centers[i0:i1])) for i0, i1 in lib.prange(0, nprim, 20): fout.write('TYPE ASSIGNMENTS %s\\n' % ''.join('%3d' % x for x in types[i0:i1])) for i0, i1 in lib.prange(0, nprim, 5): fout.write('EXPONENTS %s\\n' % ' '.join('%13.7E' % x for x in exps[i0:i1])) for k in range(nmo): mo = mo_cart[:, k] fout.write( 'MO %-12d OCC NO = %12.8f ORB. ENERGY = %12.8f\\n' % (k + 1, mo_occ[k], mo_energy[k])) for i0, i1 in lib.prange(0, nprim, 5): fout.write(' %s\\n' % ' '.join('%15.8E' % x for x in mo[i0:i1])) fout.write('END DATA\\n') fout.write(' THE SCF ENERGY =%20.12f THE VIRIAL(-V/T)= 0.00000000\\n' % tot_ener)
def mo_comps(test_or_idx, mol, mo_coeff, cart=False, orth_method='meta_lowdin'): '''Pick particular AOs based on the given test function to compute the AO contributions for each MO Args: test_or_idx : filter function or list If test_or_idx is a list, it is considered as the AO indices. If it's a function, the AO indices are the items for which the function value is true. Kwargs: cart : bool whether the orbital coefficients are based on cartesian basis. orth_method : str The localization method to generated orthogonal AO upon which the AO contribution are computed. It can be one of 'meta_lowdin', 'lowdin' or 'nao'. Returns: A list of float to indicate the total contributions (normalized to 1) of localized AOs Examples: >>> from pyscf import gto, scf >>> from pyscf.tools import mo_mapping >>> mol = gto.M(atom='H 0 0 0; F 0 0 1', basis='6-31g') >>> mf = scf.RHF(mol).run() >>> comp = mo_mapping.mo_comps(lambda x: 'F 2s' in x, mol, mf.mo_coeff) >>> print('MO-id components') >>> for i in enumerate(comp): ... print('%-3d %.10f' % (i, comp[i])) MO-id components 0 0.0000066344 1 0.8796915532 2 0.0590259826 3 0.0000000000 4 0.0000000000 5 0.0435028851 6 0.0155889103 7 0.0000000000 8 0.0000000000 9 0.0000822361 10 0.0021017982 ''' if cart: s = mol.intor_symmetric('cint1e_ovlp_cart') preao = lo.orth.pre_orth_ao(mol) tc2s = [] for ib in range(mol.nbas): l = mol.bas_angular(ib) t = gto.cart2sph(l) for i in range(mol.bas_nctr(ib)): tc2s.append(t) tc2s = scipy.linalg.block_diag(*tc2s) lao = lo.orth.orth_ao(mol, orth_method) lao = numpy.dot(tc2s, lao) else: s = mol.intor_symmetric('cint1e_ovlp_sph') lao = lo.orth.orth_ao(mol, orth_method) if callable(test_or_idx): idx = [ i for i, x in enumerate(mol.spheric_labels(1)) if test_or_idx(x) ] else: idx = numpy.asarray(test_or_idx, dtype=int) if len(idx) == 0: logger.warn(mol, 'Required orbitals are not found') mo1 = reduce(numpy.dot, (lao[:, idx].T, s, mo_coeff)) s1 = numpy.einsum('ki,ki->i', mo1, mo1) return s1
def mo_comps(test_or_idx, mol, mo_coeff, cart=False, orth_method='meta_lowdin'): '''Pick particular AOs based on the given test function to compute the AO contributions for each MO Args: test_or_idx : filter function or 1D array If test_or_idx is a list, it is considered as the AO indices. If it's a function, the AO indices are the items for which the function value is true. Kwargs: cart : bool whether the orbital coefficients are based on cartesian basis. orth_method : str The localization method to generated orthogonal AO upon which the AO contribution are computed. It can be one of 'meta_lowdin', 'lowdin' or 'nao'. Returns: A list of float to indicate the total contributions (normalized to 1) of localized AOs Examples: >>> from pyscf import gto, scf >>> from pyscf.tools import mo_mapping >>> mol = gto.M(atom='H 0 0 0; F 0 0 1', basis='6-31g') >>> mf = scf.RHF(mol).run() >>> comp = mo_mapping.mo_comps(lambda x: 'F 2s' in x, mol, mf.mo_coeff) >>> print('MO-id components') >>> for i in enumerate(comp): ... print('%-3d %.10f' % (i, comp[i])) MO-id components 0 0.0000066344 1 0.8796915532 2 0.0590259826 3 0.0000000000 4 0.0000000000 5 0.0435028851 6 0.0155889103 7 0.0000000000 8 0.0000000000 9 0.0000822361 10 0.0021017982 ''' if cart: s = mol.intor_symmetric('cint1e_ovlp_cart') preao = lo.orth.pre_orth_ao(mol) tc2s = [] for ib in range(mol.nbas): l = mol.bas_angular(ib) tc2s.append(gto.cart2sph(l)) tc2s = scipy.linalg.block_diag(*tc2s) lao = lo.orth.orth_ao(mol, orth_method) lao = numpy.dot(tc2s, lao) else: s = mol.intor_symmetric('cint1e_ovlp_sph') lao = lo.orth.orth_ao(mol, orth_method) if callable(test): idx = [i for i,x in enumerate(mol.spheric_labels(1)) if test(x)] else: idx = test idx = numpy.asarray(idx) mo1 = reduce(numpy.dot, (lao[:,idx].T, s, mo_coeff)) s1 = numpy.einsum('ki,ki->i', mo1, mo1) return s1