def init_guess_by_chkfile(mol, chkfile_name, project=None): '''Read SCF chkfile and make the density matrix for UHF initial guess. Kwargs: project : None or bool Whether to project chkfile's orbitals to the new basis. Note when the geometry of the chkfile and the given molecule are very different, this projection can produce very poor initial guess. In PES scanning, it is recommended to swith off project. If project is set to None, the projection is only applied when the basis sets of the chkfile's molecule are different to the basis sets of the given molecule (regardless whether the geometry of the two molecules are different). Note the basis sets are considered to be different if the two molecules are derived from the same molecule with different ordering of atoms. ''' from pyscf.scf import addons chk_mol, scf_rec = chkfile.load_scf(chkfile_name) if project is None: project = not gto.same_basis_set(chk_mol, mol) # Check whether the two molecules are similar im1 = scipy.linalg.eigvalsh(mol.inertia_moment()) im2 = scipy.linalg.eigvalsh(chk_mol.inertia_moment()) # im1+1e-7 to avoid 'divide by zero' error if abs((im1 - im2) / (im1 + 1e-7)).max() > 0.01: logger.warn( mol, "Large deviations found between the input " "molecule and the molecule from chkfile\n" "Initial guess density matrix may have large error.") if project: s = hf.get_ovlp(mol) def fproj(mo): if project: mo = addons.project_mo_nr2nr(chk_mol, mo, mol) norm = numpy.einsum('pi,pi->i', mo.conj(), s.dot(mo)) mo /= numpy.sqrt(norm) return mo mo = scf_rec['mo_coeff'] mo_occ = scf_rec['mo_occ'] if getattr(mo[0], 'ndim', None) == 1: # RHF if numpy.iscomplexobj(mo): raise NotImplementedError( 'TODO: project DHF orbital to UHF orbital') mo_coeff = fproj(mo) mo_occa = (mo_occ > 1e-8).astype(numpy.double) mo_occb = mo_occ - mo_occa dm = make_rdm1([mo_coeff, mo_coeff], [mo_occa, mo_occb]) else: #UHF if getattr(mo[0][0], 'ndim', None) == 2: # KUHF logger.warn( mol, 'k-point UHF results are found. Density matrix ' 'at Gamma point is used for the molecular SCF initial guess') mo = mo[0] dm = make_rdm1([fproj(mo[0]), fproj(mo[1])], mo_occ) return dm
def mulliken_pop(mol, dm, s=None, verbose=logger.DEBUG): '''Mulliken population analysis ''' if s is None: s = hf.get_ovlp(mol) if isinstance(verbose, logger.Logger): log = verbose else: log = logger.Logger(mol.stdout, verbose) if isinstance(dm, numpy.ndarray) and dm.ndim == 2: dm = numpy.array((dm*.5, dm*.5)) pop_a = numpy.einsum('ij->i', dm[0]*s) pop_b = numpy.einsum('ij->i', dm[1]*s) label = mol.spheric_labels(False) log.note(' ** Mulliken pop alpha/beta **') for i, s in enumerate(label): log.note('pop of %s %10.5f / %10.5f', '%d%s %s%4s'%s, pop_a[i], pop_b[i]) log.note(' ** Mulliken atomic charges **') chg = numpy.zeros(mol.natm) for i, s in enumerate(label): chg[s[0]] += pop_a[i] + pop_b[i] for ia in range(mol.natm): symb = mol.atom_symbol(ia) chg[ia] = mol.atom_charge(ia) - chg[ia] log.note('charge of %d%s = %10.5f', ia, symb, chg[ia]) return (pop_a,pop_b), chg
def mulliken_pop(mol, dm, s=None, verbose=logger.DEBUG): '''Mulliken population analysis ''' if s is None: s = hf.get_ovlp(mol) log = logger.new_logger(mol, verbose) if isinstance(dm, numpy.ndarray) and dm.ndim == 2: dm = numpy.array((dm*.5, dm*.5)) pop_a = numpy.einsum('ij,ji->i', dm[0], s).real pop_b = numpy.einsum('ij,ji->i', dm[1], s).real log.info(' ** Mulliken pop alpha | beta **') for i, s in enumerate(mol.ao_labels()): log.info('pop of %s %10.5f | %-10.5f', s, pop_a[i], pop_b[i]) log.info('In total %10.5f | %-10.5f', sum(pop_a), sum(pop_b)) log.note(' ** Mulliken atomic charges ( Nelec_alpha | Nelec_beta ) **') nelec_a = numpy.zeros(mol.natm) nelec_b = numpy.zeros(mol.natm) for i, s in enumerate(mol.ao_labels(fmt=None)): nelec_a[s[0]] += pop_a[i] nelec_b[s[0]] += pop_b[i] chg = mol.atom_charges() - (nelec_a + nelec_b) for ia in range(mol.natm): symb = mol.atom_symbol(ia) log.note('charge of %d%s = %10.5f ( %10.5f %10.5f )', ia, symb, chg[ia], nelec_a[ia], nelec_b[ia]) return (pop_a,pop_b), chg
def init_guess_by_minao(mf, mol=None, ao2sub=None): if mol is None: mol = mf.mol if ao2sub is None: ao2sub = mf.ao2sub dm_ao = hf.init_guess_by_minao(mol) s = hf.get_ovlp(mol) dm_sub = tools.dm_ao2loc(dm_ao, s, ao2sub) return dm_sub
def mulliken_pop(mol, dm, s=None, verbose=logger.DEBUG): '''Mulliken population analysis ''' if s is None: s = hf.get_ovlp(mol) if isinstance(verbose, logger.Logger): log = verbose else: log = logger.Logger(mol.stdout, verbose) if isinstance(dm, numpy.ndarray) and dm.ndim == 2: dm = numpy.array((dm * .5, dm * .5)) pop_a = numpy.einsum('ij->i', dm[0] * s) pop_b = numpy.einsum('ij->i', dm[1] * s) label = mol.spheric_labels(False) log.note(' ** Mulliken pop alpha | beta **') for i, s in enumerate(label): log.note('pop of %s %10.5f | %-10.5f', '%d%s %s%4s' % s, pop_a[i], pop_b[i]) log.note(' ** Mulliken atomic charges **') chg = numpy.zeros(mol.natm) for i, s in enumerate(label): chg[s[0]] += pop_a[i] + pop_b[i] for ia in range(mol.natm): symb = mol.atom_symbol(ia) chg[ia] = mol.atom_charge(ia) - chg[ia] log.note('charge of %d%s = %10.5f', ia, symb, chg[ia]) return (pop_a, pop_b), chg
def mulliken_pop(mol, dm, ovlp=None, verbose=logger.DEBUG): '''Mulliken population analysis ''' if ovlp is None: ovlp = hf.get_ovlp(mol) if isinstance(verbose, logger.Logger): log = verbose else: log = logger.Logger(mol.stdout, verbose) pop_a = numpy.einsum('ij->i', dm[0]*ovlp) pop_b = numpy.einsum('ij->i', dm[1]*ovlp) label = mol.spheric_labels() log.info(' ** Mulliken pop alpha/beta **') for i, s in enumerate(label): log.info('pop of %s %10.5f / %10.5f', '%d%s %s%4s'%s, pop_a[i], pop_b[i]) log.info(' ** Mulliken atomic charges **') chg = numpy.zeros(mol.natm) for i, s in enumerate(label): chg[s[0]] += pop_a[i] + pop_b[i] for ia in range(mol.natm): symb = mol.atom_symbol(ia) nuc = mol.atom_charge(ia) chg[ia] = nuc - chg[ia] log.info('charge of %d%s = %10.5f', ia, symb, chg[ia]) return (pop_a,pop_b), chg
def init_guess_by_wolfsberg_helmholtz(mol): """Diagonal will be taken from core hamiltonian, the off diagonal elements are interpolated by wolfsberg helmholtz scheme. H_ji = k_ji (H_ii + H_ij) S_ij / 2, with k_ij =1.75 (Generalized Wolfsberg Helmholtz GWH). See here: http://www.q-chem.com/qchem-website/manual/qchem50_manual/sect-initialguess.html M. Wolfsberg and L. Helmholz, J. Chem. Phys. 20, 837 (1952). """ from pyscf.scf.hf import eig, get_hcore, get_ovlp, get_occ, make_rdm1, SCF import numpy H = numpy.diag(get_hcore(mol)) k = numpy.ones((len(H), len(H))) * 1.75 - \ numpy.diag(numpy.ones(H.shape)) * 0.75 S = get_ovlp(mol) H = k * numpy.add.outer(H, H) * S / 2 mo_energy, mo_coeff = eig(H, S) mo_occ = get_occ(SCF(mol), mo_energy, mo_coeff) return make_rdm1(mo_coeff, mo_occ)
def init_guess_by_chkfile(mol, chkfile_name, project=None): '''Read SCF chkfile and make the density matrix for UHF initial guess. Kwargs: project : None or bool Whether to project chkfile's orbitals to the new basis. Note when the geometry of the chkfile and the given molecule are very different, this projection can produce very poor initial guess. In PES scanning, it is recommended to swith off project. If project is set to None, the projection is only applied when the basis sets of the chkfile's molecule are different to the basis sets of the given molecule (regardless whether the geometry of the two molecules are different). Note the basis sets are considered to be different if the two molecules are derived from the same molecule with different ordering of atoms. ''' from pyscf.scf import addons chk_mol, scf_rec = chkfile.load_scf(chkfile_name) if project is None: project = not gto.same_basis_set(chk_mol, mol) # Check whether the two molecules are similar im1 = scipy.linalg.eigvalsh(mol.inertia_moment()) im2 = scipy.linalg.eigvalsh(chk_mol.inertia_moment()) # im1+1e-7 to avoid 'divide by zero' error if abs((im1-im2)/(im1+1e-7)).max() > 0.01: logger.warn(mol, "Large deviations found between the input " "molecule and the molecule from chkfile\n" "Initial guess density matrix may have large error.") if project: s = hf.get_ovlp(mol) def fproj(mo): if project: mo = addons.project_mo_nr2nr(chk_mol, mo, mol) norm = numpy.einsum('pi,pi->i', mo.conj(), s.dot(mo)) mo /= numpy.sqrt(norm) return mo mo = scf_rec['mo_coeff'] mo_occ = scf_rec['mo_occ'] if getattr(mo[0], 'ndim', None) == 1: # RHF if numpy.iscomplexobj(mo): raise NotImplementedError('TODO: project DHF orbital to UHF orbital') mo_coeff = fproj(mo) mo_occa = (mo_occ>1e-8).astype(numpy.double) mo_occb = mo_occ - mo_occa dm = make_rdm1([mo_coeff,mo_coeff], [mo_occa,mo_occb]) else: #UHF if getattr(mo[0][0], 'ndim', None) == 2: # KUHF logger.warn(mol, 'k-point UHF results are found. Density matrix ' 'at Gamma point is used for the molecular SCF initial guess') mo = mo[0] dm = make_rdm1([fproj(mo[0]),fproj(mo[1])], mo_occ) return dm
def get_ovlp(mf, mol=None): if mol is None: mol = mf.mol s = 0.0 if (isinstance(mf.ovlp, np.ndarray)): s = mf.ovlp elif (mf.ovlp == 1): s = np.eye(mf.Norb) else: s = hf.get_ovlp(mol) return s
def test_gwh_by_density(self): from SCFInitialGuess.construction.fock import gwh_scheme mol = self.molecule h = hf.get_hcore(mol) s = hf.get_ovlp(mol) f_gwh = gwh_scheme(np.diag(h), s) p_gwh = density_from_fock(f_gwh, s, mol) #TODO: use pyscf method p_ref = init_guess_by_wolfsberg_helmholtz(mol) np.testing.assert_allclose(p_gwh, p_ref)
def mulliken_meta_spin(mol, dm_ao, verbose=logger.DEBUG, pre_orth_method=PRE_ORTH_METHOD, s=None): '''Mulliken spin population analysis, based on meta-Lowdin AOs. ''' from pyscf.lo import orth if s is None: s = hf.get_ovlp(mol) log = logger.new_logger(mol, verbose) if isinstance(dm_ao, numpy.ndarray) and dm_ao.ndim == 2: dm_ao = numpy.array((dm_ao*.5, dm_ao*.5)) orth_coeff = orth.orth_ao(mol, 'meta_lowdin', pre_orth_method, s=s) c_inv = numpy.dot(orth_coeff.conj().T, s) dm_a = reduce(numpy.dot, (c_inv, dm_ao[0], c_inv.conj().T)) dm_b = reduce(numpy.dot, (c_inv, dm_ao[1], c_inv.conj().T)) log.note(' ** Mulliken spin pop alpha/beta on meta-lowdin orthogonal AOs **') return mulliken_spin_pop(mol, (dm_a,dm_b), numpy.eye(orth_coeff.shape[0]), log)
def mulliken_meta(mol, dm_ao, verbose=logger.DEBUG, pre_orth_method=PRE_ORTH_METHOD, s=None): '''Mulliken population analysis, based on meta-Lowdin AOs. ''' from pyscf.lo import orth if s is None: s = hf.get_ovlp(mol) log = logger.new_logger(mol, verbose) if isinstance(dm_ao, numpy.ndarray) and dm_ao.ndim == 2: dm_ao = numpy.array((dm_ao*.5, dm_ao*.5)) c = orth.restore_ao_character(mol, pre_orth_method) orth_coeff = orth.orth_ao(mol, 'meta_lowdin', pre_orth_ao=c, s=s) c_inv = numpy.dot(orth_coeff.T, s) dm_a = reduce(numpy.dot, (c_inv, dm_ao[0], c_inv.T.conj())) dm_b = reduce(numpy.dot, (c_inv, dm_ao[1], c_inv.T.conj())) log.note(' ** Mulliken pop alpha/beta on meta-lowdin orthogonal AOs **') return mulliken_pop(mol, (dm_a,dm_b), numpy.eye(orth_coeff.shape[0]), log)
def mulliken_spin_pop(mol, dm, s=None, verbose=logger.DEBUG): r'''Mulliken spin density analysis See Eq. 80 in https://arxiv.org/pdf/1206.2234.pdf and the surrounding text for more details. .. math:: M_{ij} = (D^a_{ij} - D^b_{ij}) S_{ji} Mulliken charges .. math:: \delta_i = \sum_j M_{ij} Returns: A list : spin_pop, Ms spin_pop : nparray Mulliken spin density on each atomic orbitals Ms : nparray Mulliken spin density on each atom ''' if s is None: s = hf.get_ovlp(mol) dma = dm[0] dmb = dm[1] M = dma - dmb # Spin density log = logger.new_logger(mol, verbose) spin_pop = numpy.einsum('ij,ji->i', M, s).real log.info(' ** Mulliken Spin Density (per AO) **') for i, s in enumerate(mol.ao_labels()): log.info('spin_pop of %s %10.5f', s, spin_pop[i]) log.note(' ** Mulliken Spin Density (per atom) **') Ms = numpy.zeros(mol.natm) # Spin density per atom for i, s in enumerate(mol.ao_labels(fmt=None)): Ms[s[0]] += spin_pop[i] for ia in range(mol.natm): symb = mol.atom_symbol(ia) log.note('spin density of %d %s = %10.5f', ia, symb, Ms[ia]) return spin_pop, Ms
def mulliken_meta(mol, dm_ao, verbose=logger.DEBUG, pre_orth_method='ANO', s=None): '''Mulliken population analysis, based on meta-Lowdin AOs. ''' from pyscf.lo import orth if s is None: s = hf.get_ovlp(mol) if isinstance(verbose, logger.Logger): log = verbose else: log = logger.Logger(mol.stdout, verbose) if isinstance(dm_ao, numpy.ndarray) and dm_ao.ndim == 2: dm_ao = numpy.array((dm_ao*.5, dm_ao*.5)) c = orth.pre_orth_ao(mol, pre_orth_method) orth_coeff = orth.orth_ao(mol, 'meta_lowdin', pre_orth_ao=c, s=s) c_inv = numpy.dot(orth_coeff.T, s) dm_a = reduce(numpy.dot, (c_inv, dm_ao[0], c_inv.T.conj())) dm_b = reduce(numpy.dot, (c_inv, dm_ao[1], c_inv.T.conj())) log.note(' ** Mulliken pop alpha/beta on meta-lowdin orthogonal AOs **') return mulliken_pop(mol, (dm_a,dm_b), numpy.eye(orth_coeff.shape[0]), log)
def mulliken_meta(mol, dm_ao, verbose=logger.DEBUG, pre_orth_method="ANO", s=None): """Mulliken population analysis, based on meta-Lowdin AOs. """ from pyscf.lo import orth if s is None: s = hf.get_ovlp(mol) if isinstance(verbose, logger.Logger): log = verbose else: log = logger.Logger(mol.stdout, verbose) if isinstance(dm_ao, numpy.ndarray) and dm_ao.ndim == 2: dm_ao = numpy.array((dm_ao * 0.5, dm_ao * 0.5)) c = orth.pre_orth_ao(mol, pre_orth_method) orth_coeff = orth.orth_ao(mol, "meta_lowdin", pre_orth_ao=c, s=s) c_inv = numpy.dot(orth_coeff.T, s) dm_a = reduce(numpy.dot, (c_inv, dm_ao[0], c_inv.T.conj())) dm_b = reduce(numpy.dot, (c_inv, dm_ao[1], c_inv.T.conj())) log.info(" ** Mulliken pop alpha/beta on meta-lowdin orthogonal AOs **") return mulliken_pop(mol, (dm_a, dm_b), numpy.eye(orth_coeff.shape[0]), log)
def mulliken_meta(mol, dm_ao, verbose=logger.DEBUG, pre_orth_method='ANO', s=None): '''Mulliken population analysis, based on meta-Lowdin AOs. ''' from pyscf.lo import orth if s is None: s = hf.get_ovlp(mol) log = logger.new_logger(mf, verbose) log.note('Analyze output for the gamma point') log.note("KUHF mulliken_meta") dm_ao_gamma = dm_ao[:, 0, :, :].real.copy() s_gamma = s[0, :, :].real.copy() c = orth.pre_orth_ao(mol, pre_orth_method) orth_coeff = orth.orth_ao(mol, 'meta_lowdin', pre_orth_ao=c, s=s_gamma) c_inv = np.dot(orth_coeff.T, s_gamma) dm_a = reduce(np.dot, (c_inv, dm_ao_gamma[0], c_inv.T.conj())) dm_b = reduce(np.dot, (c_inv, dm_ao_gamma[1], c_inv.T.conj())) log.note(' ** Mulliken pop alpha/beta on meta-lowdin orthogonal AOs **') return uhf.mulliken_pop(mol, (dm_a, dm_b), np.eye(orth_coeff.shape[0]), log)
def get_ovlp(self, mol=None): if mol is None: mol = self.mol s = hf.get_ovlp(mol) return scipy.linalg.block_diag(s, s)
def not_used(): msg.info("Netowrk Analysis!", 2) #--- fetching the molecules --- msg.info("Fetching the molecules", 2) def grep_molecule(input_file): import re with open(input_file) as f: molecule = re.search(r"\$molecule.*\$end", f.read(), re.DOTALL) if molecule is None: raise ValueError("No molecule found in " + f.name) else: molecule = molecule.group(0) # cut out geometries geometries = molecule.splitlines()[2:-1] # from geometries take the species and positions species, positions = [], [] for line in geometries: splits = line.split() species.append(splits[0]) positions.append(splits[1:]) return species, positions def fetch_molecules(folder): files = [file for file in listdir(folder) if ".inp" in file] for i, file in enumerate(files): msg.info("Fetching: " + str(i + 1) + "/" + str(len(files))) mol = Molecule(*grep_molecule(join(folder, file))) mol.basis = "sto-3g" yield mol molecules = list(fetch_molecules("butadien/data")) #--- #--- do scf --- msg.info("Running the SCF calculations", 2) iterations = [] for i, molecule in enumerate(molecules): mol = molecule.get_pyscf_molecule() msg.info("Calculating: " + str(i + 1) + "/200.") # assemble pyscf initial guesses P_1e = hf.init_guess_by_1e(mol) P_atom = hf.init_guess_by_atom(mol) P_minao = hf.init_guess_by_minao(mol) # nn guess S = hf.get_ovlp(mol).reshape(1, dim**2) P_NN = network.run(sess, S).reshape(dim, dim) iterations_molecule = [] for guess in [P_1e, P_atom, P_minao, P_NN]: #, P_NN]: mf = hf.RHF(mol) mf.verbose = 1 mf.kernel(dm0=guess) iterations_molecule.append(mf.iterations) iterations.append(iterations_molecule) iterations = np.array(iterations) #--- #--- statistics --- fig, axes = plt.subplots(2, 2) bins = 1 # todo hier kann man auch ein array angeben for i, name in enumerate(['1e', 'atom', 'P_minao']): hist, bins = np.histogram(iterations[:, i]) center = (bins[:-1] + bins[1:]) / 2 axes[i].bar(center, hist, label=name) plt.legend() plt.show()
def _calculate_integrals(mol, calc_type='rhf', atomic=False): """Function to calculate the one and two electron terms. Perform a Hartree-Fock calculation in the given basis. Args: mol : A PySCF gto.Mole object. calc_type: rhf, uhf, rohf Returns: ehf : Hartree-Fock energy enuke : Nuclear repulsion energy norbs : Number of orbitals mohij : One electron terms of the Hamiltonian. mohijkl : Two electron terms of the Hamiltonian. mo_coeff: Orbital coefficients orbs_energy: Orbitals energies x_dip_ints: x dipole moment integrals y_dip_ints: y dipole moment integrals z_dip_ints: z dipole moment integrals nucl_dipl : Nuclear dipole moment """ enuke = gto.mole.energy_nuc(mol) if calc_type == 'rhf': mf = scf.RHF(mol) elif calc_type == 'rohf': mf = scf.ROHF(mol) elif calc_type == 'uhf': mf = scf.UHF(mol) else: raise QiskitChemistryError('Invalid calc_type: {}'.format(calc_type)) ehf = mf.kernel() if type(mf.mo_coeff) is tuple: mo_coeff = mf.mo_coeff[0] mo_occ = mf.mo_occ[0] else: mo_coeff = mf.mo_coeff mo_occ = mf.mo_occ norbs = mo_coeff.shape[0] orbs_energy = mf.mo_energy # print(np.dot(mo_coeff,mo_coeff.T)) O = get_ovlp(mol) # print(np.dot(O,O.T)) mo_tr = np.dot(np.dot(O, mo_coeff), O.T) # print(np.dot(mo_tr,mo_tr.T)) # two_body_temp = QMolecule.twoe_to_spin(_q_.mo_eri_ints) # temp_int = np.einsum('ijkl->ljik', _q_.mo_eri_ints) # two_body_temp = QMolecule.twoe_to_spin(temp_int) # mol = gto.M(atom=mol.atom, basis='sto-3g') # X = np.kron(np.identity(2), np.linalg.inv(scipy.linalg.sqrtm(O))) ### for atomic basis if atomic: mo_coeff = np.identity(len(mo_coeff)) ### # print(mo_coeff) hij = mf.get_hcore() mohij = np.dot(np.dot(mo_coeff.T, hij), mo_coeff) # mohij = hij eri = ao2mo.incore.full(mf._eri, mo_coeff, compact=False) # eri_1 = mf._eri # print(np.shape(eri)) # print(np.shape(eri_1)) mohijkl = eri.reshape(norbs, norbs, norbs, norbs) # exit() # dipole integrals mol.set_common_orig((0, 0, 0)) ao_dip = mol.intor_symmetric('int1e_r', comp=3) x_dip_ints = QMolecule.oneeints2mo(ao_dip[0], mo_coeff) y_dip_ints = QMolecule.oneeints2mo(ao_dip[1], mo_coeff) z_dip_ints = QMolecule.oneeints2mo(ao_dip[2], mo_coeff) dm = mf.make_rdm1(mf.mo_coeff, mf.mo_occ) if calc_type == 'rohf' or calc_type == 'uhf': dm = dm[0] elec_dip = np.negative(np.einsum('xij,ji->x', ao_dip, dm).real) elec_dip = np.round(elec_dip, decimals=8) nucl_dip = np.einsum('i,ix->x', mol.atom_charges(), mol.atom_coords()) nucl_dip = np.round(nucl_dip, decimals=8) logger.info("HF Electronic dipole moment: {}".format(elec_dip)) logger.info("Nuclear dipole moment: {}".format(nucl_dip)) logger.info("Total dipole moment: {}".format(nucl_dip + elec_dip)) return ehf, enuke, norbs, mohij, mohijkl, mo_coeff, orbs_energy, x_dip_ints, y_dip_ints, z_dip_ints, nucl_dip
for i, molecule in enumerate(molecules): mol = molecule.get_pyscf_molecule() msg.info("Calculating: " + str(i + 1) + "/200.") # assemble pyscf initial guesses P_1e = hf.init_guess_by_1e(mol) P_atom = hf.init_guess_by_atom(mol) P_minao = hf.init_guess_by_minao(mol) print("die normalen sind fertig") # nn guess S = hf.get_ovlp(mol).reshape(1, dim**2) P_NN = network.run(sess, S).reshape(dim, dim).astype('float64') print("P_NN fertig") iterations_molecule = [] for guess in [P_1e, P_atom, P_minao, P_NN]:#, P_NN]: print("SCF") mf = hf.RHF(mol) mf.verbose = 1 mf.kernel(dm0=guess) iterations_molecule.append(mf.iterations) print("SCFs done")
def get_ovlp(self, mol=None): if mol is None: mol = self.mol hcore = hf.get_ovlp(mol) return scipy.linalg.block_diag(hcore, hcore)
mol = gto.Mole() mol.atom = atom mol.basis = 'sto-3g' # mol.basis = {'O': 'sto-3g', 'H': 'cc-pvdz', 'H@2': '6-31G'} is_atomic = False mol.build() _q_ = qmol_func(mol, atomic=is_atomic) if is_atomic: two_body_temp = QMolecule.twoe_to_spin(_q_.mo_eri_ints) temp_int = np.einsum('ijkl->ljik', _q_.mo_eri_ints) two_body_temp = QMolecule.twoe_to_spin(temp_int) mol = gto.M(atom=atom, basis='sto-3g') O = get_ovlp(mol) X = np.kron(np.identity(2), np.linalg.inv(scipy.linalg.sqrtm(O))) fer_op = FermionicOperator(h1=_q_.one_body_integrals, h2=two_body_temp) fer_op.transform(X) else: fer_op = FermionicOperator(h1=_q_.one_body_integrals, h2=_q_.two_body_integrals) # s = np.shape(fer_op.h1) # fer_op.h1 = np.zeros(s) # print(fer_op.h1) ref_op = fer_op.mapping('jordan_wigner') print(ref_op.print_operators()) ee = ExactEigensolver(ref_op, k=1)
def mol_r_matrices(MoleculeFlag,check_r_matrix_flag,is_atomic): mol = gto.Mole() #================================= # Hydrogen molecule #================================= if MoleculeFlag == 'H2': r_matrices=[] num_particles = 2 if is_atomic: try: data = np.load(MoleculeFlag+'ao.npz') data.files one_b = data['one_b'] two_b = data['two_b'] except IOError: mol.atom = [['H',(0, 0, -0.3707)], ['H',(0,0.0,0.3707)]] mol.build() _q_=int_func.qmol_func(mol, atomic=True) one_b=_q_.one_body_integrals two_b=_q_.two_body_integrals # np.savez(MoleculeFlag+'_ao.npz',one_b=_q_.one_body_integrals,two_b=_q_.two_body_integrals) two_body_temp = QMolecule.twoe_to_spin(_q_.mo_eri_ints) temp_int = np.einsum('ijkl->ljik', _q_.mo_eri_ints) two_body_temp = QMolecule.twoe_to_spin(temp_int) mol = gto.M(atom=mol.atom, basis='sto-3g') O = get_ovlp(mol) X = np.kron(np.identity(2), np.linalg.inv(scipy.linalg.sqrtm(O))) fer_op = FermionicOperator(h1=_q_.one_body_integrals, h2=two_body_temp) fer_op.transform(X) else: mol.atom = [['H',(0, 0, -0.3707)], ['H',(0,0.0,0.3707)]] mol.build() _q_=int_func.qmol_func(mol, atomic=is_atomic) one_b=_q_.one_body_integrals two_b=_q_.two_body_integrals fer_op = FermionicOperator(h1=_q_.one_body_integrals, h2=_q_.two_body_integrals) one_b = fer_op.h1 two_b = fer_op.h2 # Defining R-matrix --> r # Swapping the spatial orbitals. This involves swapping both the spin orbitals corresponding to a spatial orbital. # This could be treated as a reflection symmetry or rotational symmetry. r1 = np.zeros([4,4]) r1[0,1]=1 r1[1,0]=1 r1[2,3]=1 r1[3,2]=1 # Swapping the spin oritals. Spin symmetry. r2=np.zeros([4,4]) for i in range(4): if i<2: r2[i+2,i]=1. else: r2[i-2,i]=1. r_matrices.append(r1) r_matrices.append(r2) if check_r_matrix_flag: if bool(check_r_mat(r_matrices,fer_op,one_b,two_b)): print('All the above matrices work!') #================================= # Water molecule (with different basis sets) #================================= elif MoleculeFlag== 'H2O_L': r_matrices = [] print(MoleculeFlag) # Configuration from # mol.atom = [['O',(0.8638, 0.4573,0.0)], ['H',(0, 0, 0)], ['H',(1.7785,0.0,0.0)]] # mol.atom = [['O',(0.0, 0.0,0.0)],['H',(1, 0, 0)], ['H',(-1.0,0.0,0.0)]] #mol.atom = [['O',(0, 0, 0)], ['H',(0, 1, 0)], ['H@2',(0, 0, 1)]] #mol.basis = {'O': 'sto-3g', 'H': 'cc-pvdz', 'H@2': '6-31G'} num_particles=10 if is_atomic: try: data = np.load(MoleculeFlag+'ao.npz') data.files one_b = data['one_b'] two_b = data['two_b'] except IOError: mol.atom = [['O',(0.0, 0.0,0.0)],['H',(1, 0, 0)], ['H',(-1.0,0.0,0.0)]] mol.build() _q_=int_func.qmol_func(mol, atomic=True) one_b=_q_.one_body_integrals two_b=_q_.two_body_integrals # np.savez(MoleculeFlag+'_ao.npz',one_b=_q_.one_body_integrals,two_b=_q_.two_body_integrals) two_body_temp = QMolecule.twoe_to_spin(_q_.mo_eri_ints) temp_int = np.einsum('ijkl->ljik', _q_.mo_eri_ints) two_body_temp = QMolecule.twoe_to_spin(temp_int) mol = gto.M(atom=mol.atom, basis='sto-3g') O = get_ovlp(mol) X = np.kron(np.identity(2), np.linalg.inv(scipy.linalg.sqrtm(O))) fer_op = FermionicOperator(h1=_q_.one_body_integrals, h2=two_body_temp) fer_op.transform(X) else: mol.atom = [['O',(0.0, 0.0,0.0)],['H',(1, 0, 0)], ['H',(-1.0,0.0,0.0)]] mol.build() _q_=int_func.qmol_func(mol, atomic=is_atomic) one_b=_q_.one_body_integrals two_b=_q_.two_body_integrals fer_op = FermionicOperator(h1=_q_.one_body_integrals, h2=_q_.two_body_integrals) one_b = fer_op.h1 two_b = fer_op.h2 # R-matrix for plane of symmetry \sigma_{xy}. Everything remains the same, only pz-orbitals pick up negative sign. r1=np.zeros([14,14]) r1[0,0]=1 r1[1,1]=1 r1[2,2]=1 r1[3,3]=1 r1[4,4]=-1 r1[5,5]=1 r1[6,6]=1 r1[7,7]=1 r1[8,8]=1 r1[9,9]=1 r1[10,10]=1 r1[11,11]=-1 r1[12,12]=1 r1[13,13]=1 r_matrices.append(r1) # R-matrix for plane of symmetry \sigma_{xz}. Everything remains the same, only py-orbitals pick up negative sign. r2=np.eye(14) r2[3,3]=-1 r2[10,10]=-1 r_matrices.append(r2) # R-matrix for plane of symmetry \sigma_{yz}. Everything remains the same, only px-orbitals pick up negative sign and hydrogen atoms swap. r3=np.zeros([14,14]) r3[0,0]=1 r3[1,1]=1 r3[2,2]=-1 r3[3,3]=1 r3[4,4]=1 r3[5,6]=1 r3[6,5]=1 r3[7,7]=1 r3[8,8]=1 r3[9,9]=-1 r3[10,10]=1 r3[11,11]=1 r3[12,13]=1 r3[13,12]=1 r_matrices.append(r3) # R-matrix for symmetry-axis C_2. Linear water molecule has three axis of symmetry: # About z-axis r4=np.zeros([14,14]) r4[0,0]=1 r4[1,1]=1 r4[2,2]=-1 r4[3,3]=-1 r4[4,4]=1 r4[5,6]=1 r4[6,5]=1 r4[7,7]=1 r4[8,8]=1 r4[9,9]=-1 r4[10,10]=-1 r4[11,11]=1 r4[12,13]=1 r4[13,12]=1 r_matrices.append(r4) #About y-axis r5=np.zeros([14,14]) r5[0,0]=1 r5[1,1]=1 r5[2,2]=-1 r5[3,3]=1 r5[4,4]=-1 r5[5,6]=1 r5[6,5]=1 r5[7,7]=1 r5[8,8]=1 r5[9,9]=-1 r5[10,10]=1 r5[11,11]=-1 r5[12,13]=1 r5[13,12]=1 r_matrices.append(r5) #Symmetry about x-axis: r6=np.zeros([14,14]) r6[0,0]=1 r6[1,1]=1 r6[2,2]=1 r6[3,3]=-1 r6[4,4]=-1 r6[5,5]=1 r6[6,6]=1 r6[7,7]=1 r6[8,8]=1 r6[9,9]=1 r6[10,10]=-1 r6[11,11]=-1 r6[12,12]=1 r6[13,13]=1 r_matrices.append(r6) #Spin symmetry: r7=np.zeros([14,14]) for i in range(14): if i<7: r7[i+7,i]=1. else: r7[i-7,i]=1. r_matrices.append(r7) if check_r_matrix_flag: if bool(check_r_mat(r_matrices,fer_op,one_b,two_b)): print('All the above matrices work!') #================================= # Water molecule (with different basis sets) #================================= elif MoleculeFlag== 'H2O': r_matrices=[] print(MoleculeFlag) num_particles = 10 if is_atomic: try: data = np.load(MoleculeFlag+'ao.npz') data.files one_b = data['one_b'] two_b = data['two_b'] except IOError: mol.atom = [['O',(0.0000, 0.0000, 0.0000)], ['H',(0.757, 0.586, 0.0)], ['H',(-0.757, 0.586, 0.0)]] # mol.atom = [['N', (0.0000, 0.0000, 0.0000)], # ['H', (0.0000, -1.,-0.3816)], # ['H', (0.8, 0.6 ,-0.3816)], # ['H', (-0.8, 0.6 ,-0.3816)]] mol.build() _q_=int_func.qmol_func(mol, atomic=True) one_b=_q_.one_body_integrals two_b=_q_.two_body_integrals # np.savez(MoleculeFlag+'_ao.npz',one_b=_q_.one_body_integrals,two_b=_q_.two_body_integrals) two_body_temp = QMolecule.twoe_to_spin(_q_.mo_eri_ints) temp_int = np.einsum('ijkl->ljik', _q_.mo_eri_ints) two_body_temp = QMolecule.twoe_to_spin(temp_int) mol = gto.M(atom=mol.atom, basis='sto-3g') O = get_ovlp(mol) X = np.kron(np.identity(2), np.linalg.inv(scipy.linalg.sqrtm(O))) fer_op = FermionicOperator(h1=_q_.one_body_integrals, h2=two_body_temp) fer_op.transform(X) else: mol.atom = [['O',(0.0000, 0.0000, 0.0000)], ['H',(0.757, 0.586, 0.0)], ['H',(-0.757, 0.586, 0.0)]] mol.build() _q_=int_func.qmol_func(mol, atomic=is_atomic) one_b=_q_.one_body_integrals two_b=_q_.two_body_integrals fer_op = FermionicOperator(h1=_q_.one_body_integrals, h2=_q_.two_body_integrals) one_b = fer_op.h1 two_b = fer_op.h2 #Spin symmetry: r1=np.zeros([14,14]) for i in range(14): if i<7: r1[i+7,i]=1. else: r1[i-7,i]=1. # r_matrices.append(r1) # R-matrix for plane of symmetry \sigma_{xy}. Everything remains the same, only pz-orbitals pick up negative sign. r2=np.eye(14) r2[4,4]=-1 r2[11,11]=-1 r_matrices.append(r2) # R-matrix for plane of symmetry \sigma_{yz}. Everything remains the same, only px-orbitals pick up negative sign and the hydrogen atoms swap. r3=np.eye(14) r3[2,2]=-1 r3[9,9]=-1 r3[12,12]=0 r3[13,13]=0 r3[12,13]=1 r3[13,12]=1 r3[5,6]=1 r3[6,5]=1 r3[5,5]=0 r3[6,6]=0 # print(r) r_matrices.append(r3) #Axial symmetry about y-axis r4=np.zeros([14,14]) r4[0,0]=1 r4[1,1]=1 r4[2,2]=-1 r4[3,3]=1 r4[4,4]=-1 r4[5,6]=1 r4[6,5]=1 r4[7,7]=1 r4[8,8]=1 r4[9,9]=-1 r4[10,10]=1 r4[11,11]=-1 r4[12,13]=1 r4[13,12]=1 r_matrices.append(r4) if check_r_matrix_flag: if bool(check_r_mat(r_matrices,fer_op,one_b,two_b)): print('All the above matrices work!') #================================= # Ammonia molecule #================================= elif MoleculeFlag=='NH3': print(MoleculeFlag) num_particles = 10 if is_atomic: try: data = np.load(MoleculeFlag+'ao.npz') data.files one_b = data['one_b'] two_b = data['two_b'] except IOError: mol.atom = [['N' , ( 0.0000000, 0.0000000, 0.1493220)], ['H' , ( 0.0000000 , 0.9474830 , -0.3484190)], ['H' , ( 0.8205440 , -0.4737420 , -0.3484190)], ['H' , ( -0.8205440 , -0.4737420 , -0.3484190)]] mol.build() _q_=int_func.qmol_func(mol, atomic=True) one_b=_q_.one_body_integrals two_b=_q_.two_body_integrals # np.savez(MoleculeFlag+'_ao.npz',one_b=_q_.one_body_integrals,two_b=_q_.two_body_integrals) two_body_temp = QMolecule.twoe_to_spin(_q_.mo_eri_ints) temp_int = np.einsum('ijkl->ljik', _q_.mo_eri_ints) two_body_temp = QMolecule.twoe_to_spin(temp_int) mol = gto.M(atom=mol.atom, basis='sto-3g') O = get_ovlp(mol) X = np.kron(np.identity(2), np.linalg.inv(scipy.linalg.sqrtm(O))) fer_op = FermionicOperator(h1=_q_.one_body_integrals, h2=two_body_temp) fer_op.transform(X) else: mol.atom = [['N' , ( 0.0000000, 0.0000000, 0.1493220)], ['H' , ( 0.0000000 , 0.9474830 , -0.3484190)], ['H' , ( 0.8205440 , -0.4737420 , -0.3484190)], ['H' , ( -0.8205440 , -0.4737420 , -0.3484190)]] mol.build() _q_=int_func.qmol_func(mol, atomic=is_atomic) one_b=_q_.one_body_integrals two_b=_q_.two_body_integrals fer_op = FermionicOperator(h1=_q_.one_body_integrals, h2=_q_.two_body_integrals) one_b = fer_op.h1 two_b = fer_op.h2 r_matrices=[] #Spin symmetry: r1=np.zeros([16,16]) for i in range(16): if i<8: r1[i+8,i]=1. else: r1[i-8,i]=1. r_matrices.append(r1) # R-matrix for plane of symmetry \sigma_{yz}. Two hydrogen atoms are swapped and the px orbital picks up # a negative sign. r3=np.zeros([16,16]) r3[0,0]=1 r3[1,1]=1 r3[2,2]=-1 r3[3,3]=1 r3[4,4]=1 r3[5,5]=1 r3[6,7]=1 r3[7,6]=1 r3[8,8]=1 r3[9,9]=1 r3[10,10]=-1 r3[11,11]=1 r3[12,12]=1 r3[13,13]=1 r3[14,15]=1 r3[15,14]=1 r_matrices.append(r3) ###################################### # The following mtrices commute with Hamiltonian # and hence are symmetries, but these cannot be used # to taper off qubits. theta = -2*np.pi/3 r4 = np.eye(16) r4[5,5]=r4[6,6]=r4[7,7]=0 r4[13,13]=r4[14,14]=r4[15,15]=0 r4[5,6]=r4[6,7]=r4[7,5]=1 # r4[6,5]=r4[7,6]=r4[5,7]=1 r4[13,14]=r4[14,15]=r4[15,13]=1 # r4[14,13]=r4[15,14]=r4[13,15]=1 r4[2,2]=r4[3,3]=r4[10,10]=r4[11,11]=np.cos(theta) r4[2,3]= np.sin(theta) r4[3,2]= -np.sin(theta) r4[10,11]=np.sin(theta) r4[11,10]=-np.sin(theta) r5 = r4.copy() theta = np.pi/3 r4 = np.eye(16,dtype=complex) r4[5,5]=r4[6,6]=0 r4[13,13]=r4[14,14]=0 r4[5,6]=r4[6,5]=1 r4[13,14]=r4[14,13]=1 r4[2,2]=r4[10,10]=np.cos(theta) r4[3,3]=r4[11,11]=-np.cos(theta) r4[2,3]= np.sin(theta) r4[3,2]= np.sin(theta) r4[10,11]=np.sin(theta) r4[11,10]=np.sin(theta) if check_r_matrix_flag: if bool(check_r_mat(r_matrices,fer_op,one_b,two_b)): print('All the above matrices work!') #================================= # Methane molecule #================================= elif MoleculeFlag=='CH4': # print(MoleculeFlag) mol.atom=[['C', (0.0000 , 0.0000 , 0.0000 )], ['H', (0.6276 , 0.6276 , 0.6276 )], ['H', (0.6276 , -0.6276, -0.6276)], ['H', (-0.6276, 0.6276 , -0.6276)], ['H', (-0.6276, -0.6276, 0.6276 )]] mol.basis='sto-3g' mol.build() _q_=int_func.qmol_func(mol, atomic=True) fer_op = FermionicOperator(h1=_q_.one_body_integrals, h2=_q_.two_body_integrals) # Spin symmetry: r1=np.zeros([18,18]) for i in range(18): if i<8: r1[i+9,i]=1. else: r1[i-9,i]=1. if check_r_matrix_flag: if bool(check_r_mat(r_matrices,fer_op,one_b,two_b)): print('All the above matrices work!') #================================= # Carbon dioxide molecule #================================= elif MoleculeFlag=='CO2': r_matrices = [] # print(MoleculeFlag) mol.atom = [['C',(0., 0., 0.)], ['O',(-1.1621, 0., 0.)], ['O',(1.1621, 0., 0.)]] mol.basis='sto-3g' mol.build() _q_=int_func.qmol_func(mol, atomic=True) fer_op = FermionicOperator(h1=_q_.one_body_integrals, h2=_q_.two_body_integrals) # Spin symmetry: r1=np.zeros([30,30]) for i in range(30): if i<15: r1[i+15,i]=1. else: r1[i-15,i]=1. r_matrices.append(r1) # Permutation matrix for inversion. \sigma{yz} All the oxygen orbitals are swapped. # Oxygen px orbital picks up a negative sign and the px of carbon picks up a # negative sign. r2=np.zeros([30,30]) r2[0,0]=1 r2[1,1]=1 r2[3,3]=1 r2[2,2]=-1 r2[4,4]=r2[19,19]=1 r2[5,10]=r2[10,5]=1 r2[11,6]=r2[6,11]=1 r2[7,12]=r2[12,7]=-1 r2[8,13]=r2[13,8]=1 r2[14,9]=r2[9,14]=1 r2[15,15]=1 r2[16,16]=1 r2[17,17]=-1 r2[18,18]=1 r2[20,25]=r2[25,20]=1 r2[21,26]=r2[26,21]=1 r2[22,27]=r2[27,22]=-1 r2[23,28]=r2[28,23]=1 r2[24,29]=r2[29,24]=1 r_matrices.append(r2) # Permutation matrix for inversion. \sigma{xy} # pz orbitals of oxygen and carbon pick up negative sign r3=np.eye(30) r3[4,4]=-1 r3[19,19]=-1 r3[9,9]=-1 r3[14,14]=-1 r3[24,24]=-1 r3[29,29]=-1 r_matrices.append(r3) # Permutation matrix for inversion. \sigma{xz} # py orbitals of oxygen and carbon pick up negative sign r4=np.eye(30) r4[3,3]=-1 r4[18,18]=-1 r4[8,8]=-1 r4[13,13]=-1 r4[23,23]=-1 r4[28,28]=-1 r_matrices.append(r4) # Permutation matrix for axial symmetry. C_2{x} # pz and py orbitals of oxygen and carbon pick up negative sign r5=np.eye(30) r5[3,3]=-1 r5[18,18]=-1 r5[8,8]=-1 r5[13,13]=-1 r5[23,23]=-1 r5[28,28]=-1 r5[4,4]=-1 r5[19,19]=-1 r5[9,9]=-1 r5[14,14]=-1 r5[24,24]=-1 r5[29,29]=-1 r_matrices.append(r5) # Permutation matrix for axial symmetry. C_2{y} All the oxygen orbitals are swapped. # Oxygen px and pz orbital picks up a negative sign and the px and pz of carbon picks up a # negative sign. r6=np.zeros([30,30]) r6[0,0]=r6[1,1]=1 r6[3,3]=r6[18,18]=1 r6[17,17]=r6[2,2]=-1 r6[4,4]=r6[19,19]=-1 r6[5,10]=r6[10,5]=1 r6[11,6]=r6[6,11]=1 r6[7,12]=r6[12,7]=-1 r6[8,13]=r6[13,8]=1 r6[14,9]=r6[9,14]=-1 r6[15,15]=r6[16,16]=1 r6[20,25]=r6[25,20]=1 r6[21,26]=r6[26,21]=1 r6[22,27]=r6[27,22]=-1 r6[23,28]=r6[28,23]=1 r6[24,29]=r6[29,24]=-1 r_matrices.append(r6) # Permutation matrix for axial symmetry. C_2{z} All the oxygen orbitals are swapped. # Oxygen px and py orbital picks up a negative sign and the px and py of carbon picks up a # negative sign. r7=np.zeros([30,30]) r7[0,0]=r7[1,1]=1 r7[3,3]=r7[18,18]=-1 r7[17,17]=r7[2,2]=-1 r7[4,4]=r7[19,19]=1 r7[5,10]=r7[10,5]=1 r7[11,6]=r7[6,11]=1 r7[7,12]=r7[12,7]=-1 r7[8,13]=r7[13,8]=-1 r7[14,9]=r7[9,14]=1 r7[15,15]=r7[16,16]=1 r7[20,25]=r7[25,20]=1 r7[21,26]=r7[26,21]=1 r7[22,27]=r7[27,22]=-1 r7[23,28]=r7[28,23]=-1 r7[24,29]=r7[29,24]=1 r_matrices.append(r7) if check_r_matrix_flag: if bool(check_r_mat(r_matrices,fer_op,one_b,two_b)): print('All the above matrices work!') #================================= # Ethyne molecule #================================= elif MoleculeFlag=='C2H2': r_matrices =[] print(MoleculeFlag) num_particles = 14 if is_atomic: try: data = np.load(MoleculeFlag+'.npz') data.files one_b = data['one_b'] two_b = data['two_b'] except IOError: mol.atom = [['C',(-0.6000, 0.0000, 0.0000 )], ['C',(0.6000, 0.0000, 0.0000 )], ['H',(-1.6650,0.0000, 0.000 )], ['H',(1.6650,0.0000, 0.000 )]] mol.build() _q_=int_func.qmol_func(mol, atomic=True) one_b=_q_.one_body_integrals two_b=_q_.two_body_integrals # np.savez(MoleculeFlag+'_ao.npz',one_b=_q_.one_body_integrals,two_b=_q_.two_body_integrals) two_body_temp = QMolecule.twoe_to_spin(_q_.mo_eri_ints) temp_int = np.einsum('ijkl->ljik', _q_.mo_eri_ints) two_body_temp = QMolecule.twoe_to_spin(temp_int) mol = gto.M(atom=mol.atom, basis='sto-3g') O = get_ovlp(mol) X = np.kron(np.identity(2), np.linalg.inv(scipy.linalg.sqrtm(O))) fer_op = FermionicOperator(h1=_q_.one_body_integrals, h2=two_body_temp) fer_op.transform(X) else: mol.atom = [['C',(-0.6000, 0.0000, 0.0000 )], ['C',(0.6000, 0.0000, 0.0000 )], ['H',(-1.6650,0.0000, 0.000 )], ['H',(1.6650,0.0000, 0.000 )]] mol.build() _q_=int_func.qmol_func(mol, atomic=is_atomic) one_b=_q_.one_body_integrals two_b=_q_.two_body_integrals fer_op = FermionicOperator(h1=_q_.one_body_integrals, h2=_q_.two_body_integrals) one_b = fer_op.h1 two_b = fer_op.h2 # Spin symmetry: r1=np.zeros([24,24]) for i in range(24): if i<12: r1[i+12,i]=1. else: r1[i-12,i]=1. # r_matrices.append(r1) # R-matrix for plane of symmetry \sigma_{xy}. Everything remains the same, only pz-orbitals pick up negative sign. r2=np.eye(24) r2[4,4]=-1 r2[9,9]=-1 r2[16,16]=-1 r2[21,21]=-1 # R-matrix for plane of symmetry \sigma_{xz}. Everything remains the same, only py-orbitals pick up negative sign. r3=np.eye(24) r3[3,3]=-1 r3[8,8]=-1 r3[15,15]=-1 r3[20,20]=-1 # R-matrix for plane of symmetry \sigma_{yz}. r4=np.zeros([24,24]) #Swapping px picks up a negative sign r4[2,7]=r4[7,2]=-1 r4[14,19]=r4[19,14]=-1 #Swapping 1s, 2s, 2py and 2pz of Carbon r4[0,5]=r4[5,0]=1 r4[1,6]=r4[6,1]=1 r4[12,17]=r4[17,12]=1 r4[13,18]=r4[18,13]=1 r4[3,8]=r4[8,3]=1 r4[15,20]=r4[20,15]=1 r4[21,16]=r4[16,21]=1 r4[9,4]=r4[4,9]=1 #Swapping 1s of hydrogen r4[10,11]=r4[11,10]=1 r4[22,23]=r4[23,22]=1 # R-matrix for axis of symmetry C_2 around y axis. r5=np.zeros([24,24]) #Swapping px picks up a negative sign r5[2,7]=r5[7,2]=-1 r5[14,19]=r5[19,14]=-1 r5[21,16]=r5[16,21]=-1 r5[9,4]=r5[4,9]=-1 #Swapping 1s, 2s, 2py and 2pz of Carbon r5[0,5]=r5[5,0]=1 r5[1,6]=r5[6,1]=1 r5[12,17]=r5[17,12]=1 r5[13,18]=r5[18,13]=1 r5[3,8]=r5[8,3]=1 r5[15,20]=r5[20,15]=1 #Swapping 1s of hydrogen r5[10,11]=r5[11,10]=1 r5[22,23]=r5[23,22]=1 # R-matrix for axis of symmetry C_2 around z axis. r6=np.zeros([24,24]) #Swapping px picks up a negative sign r6[2,7]=r6[7,2]=-1 r6[14,19]=r6[19,14]=-1 r6[15,20]=r6[20,15]=-1 r6[3,8]=r6[8,3]=-1 #Swapping 1s, 2s, 2py and 2pz of Carbon r6[0,5]=r6[5,0]=1 r6[1,6]=r6[6,1]=1 r6[12,17]=r6[17,12]=1 r6[13,18]=r6[18,13]=1 r6[9,4]=r6[4,9]=1 r6[21,16]=r6[16,21]=1 #Swapping 1s of hydrogen r6[10,11]=r6[11,10]=1 r6[22,23]=r6[23,22]=1 # R-matrix for x-axis symmetry. pz and py orbitals of both the carbon atoms pick up a negative sign. r7=np.eye(24) r7[3,3]=-1 r7[4,4]=-1 r7[8,8]=-1 r7[9,9]=-1 r7[16,16]=-1 r7[15,15]=-1 r7[20,20]=-1 r7[21,21]=-1 r_matrices.append(r7) r_matrices.append(r6) r_matrices.append(r5) r_matrices.append(r2) r_matrices.append(r3) r_matrices.append(r4) r_matrices.append(r1) if check_r_matrix_flag: if bool(check_r_mat(r_matrices,fer_op,one_b,two_b)): print('All the above matrices work!') #================================= # Ethylene molecule #================================= elif MoleculeFlag=='C2H4': r_matrices =[] print(MoleculeFlag) try: data = np.load(MoleculeFlag+'.npz') data.files one_b = data['one_b'] two_b = data['two_b'] except IOError: mol.atom = [['C',( 0.6695, 0.0000 , 0.0000)], ['C',(-0.6695, 0.0000 , 0.0000)], ['H',( 1.2321, 0.9289 , 0.0000)], ['H',( 1.2321, -0.9289, 0.0000)], ['H',(-1.2321, 0.9289 , 0.0000)], ['H',(-1.2321, -0.9289, 0.0000)]] mol.build() _q_=int_func.qmol_func(mol, atomic=True) one_b=_q_.one_body_integrals two_b=_q_.two_body_integrals np.savez(MoleculeFlag+'.npz',one_b=_q_.one_body_integrals,two_b=_q_.two_body_integrals) fer_op = FermionicOperator(h1=one_b, h2=two_b) r_matrices = [] # Spin symmetry: r1=np.zeros([28,28]) for i in range(28): if i<14: r1[i+14,i]=1. else: r1[i-14,i]=1. # r_matrices.append(r1) # R-matrix for plane of symmetry \sigma_{xy}. Everything remains the same, only pz-orbitals pick up negative sign. r2=np.eye(28) r2[4,4]=-1 r2[9,9]=-1 r2[18,18]=-1 r2[23,23]=-1 # R-matrix for plane of symmetry \sigma_{xz}. r3=np.eye(28) r3[3,3]=-1 r3[8,8]=-1 r3[17,17]=-1 r3[22,22]=-1 r3[10,10]=r3[11,11]=r3[12,12]=r3[13,13]=0 r3[24,24]=r3[25,25]=r3[26,26]=r3[27,27]=0 r3[10,11]=r3[11,10]=r3[12,13]=r3[13,12]=1 r3[24,25]=r3[25,24]=r3[26,27]=r3[27,26]=1 # R-matrix for plane of symmetry \sigma_{yz}. r4=np.zeros([28,28]) # #Swapping px picks up a negative sign r4[2,7]=r4[7,2]=-1 r4[16,21]=r4[21,16]=-1 # #Swapping 1s, 2s, 2py and 2pz of Carbon r4[0,5]=r4[5,0]=1 r4[1,6]=r4[6,1]=1 r4[3,8]=r4[8,3]=1 r4[4,9]=r4[9,4]=1 r4[14,19]=r4[19,14]=1 r4[15,20]=r4[20,15]=1 r4[17,22]=r4[22,17]=1 r4[18,23]=r4[23,18]=1 # #Swapping 1s of hydrogen r4[10,12]=r4[12,10]=1 r4[24,26]=r4[26,24]=1 r4[11,13]=r4[13,11]=1 r4[25,27]=r4[27,25]=1 # R-matrix for axis of symmetry C_2 around y axis. r5=np.zeros([28,28]) #Swapping px picks up a negative sign r5[2,7]=r5[7,2]=-1 r5[4,9]=r5[9,4]=-1 r5[16,21]=r5[21,16]=-1 r5[18,23]=r5[23,18]=-1 #Swapping 1s, 2s, 2py and 2pz of Carbon r5[0,5]=r5[5,0]=1 r5[1,6]=r5[6,1]=1 r5[3,8]=r5[8,3]=1 r5[14,19]=r5[19,14]=1 r5[15,20]=r5[20,15]=1 r5[17,22]=r5[22,17]=1 #Swapping 1s of hydrogen r5[10,12]=r5[12,10]=1 r5[24,26]=r5[26,24]=1 r5[11,13]=r5[13,11]=1 r5[25,27]=r5[27,25]=1 # R-matrix for axis of symmetry C_2 around z axis. r6=np.zeros([28,28]) #Swapping px picks up a negative sign r6[2,7]=r6[7,2]=-1 r6[3,8]=r6[8,3]=-1 r6[16,21]=r6[21,16]=-1 r6[17,22]=r6[22,17]=-1 #Swapping 1s, 2s, 2py and 2pz of Carbon r6[0,5]=r6[5,0]=1 r6[1,6]=r6[6,1]=1 r6[4,9]=r6[9,4]=1 r6[14,19]=r6[19,14]=1 r6[15,20]=r6[20,15]=1 r6[18,23]=r6[23,18]=1 #Swapping 1s of hydrogen r6[10,13]=r6[13,10]=1 r6[24,27]=r6[27,24]=1 r6[11,12]=r6[12,11]=1 r6[25,26]=r6[26,25]=1 # # R-matrix for x-axis symmetry. pz and py orbitals of both the carbon atoms pick up a negative sign. r7=np.eye(28) r7[3,3]=-1 r7[4,4]=-1 r7[8,8]=-1 r7[9,9]=-1 r7[17,17]=-1 r7[18,18]=-1 r7[22,22]=-1 r7[23,23]=-1 r7[10,10]=r7[11,11]=r7[12,12]=r7[13,13]=0 r7[24,24]=r7[25,25]=r7[26,26]=r7[27,27]=0 r7[10,11]=r7[11,10]=r7[12,13]=r7[13,12]=1 r7[24,25]=r7[25,24]=r7[26,27]=r7[27,26]=1 r_matrices.append(r1) r_matrices.append(r2) r_matrices.append(r3) r_matrices.append(r4) r_matrices.append(r5) r_matrices.append(r6) r_matrices.append(r7) if check_r_matrix_flag: if bool(check_r_mat(r_matrices,fer_op,one_b,two_b)): print('All the above matrices work!') #================================= # Boron trifluoride molecule #================================= elif MoleculeFlag == 'BF3': r_matrices = [] try: data = np.load(MoleculeFlag+'.npz') one_b = data['one_b'] two_b = data['two_b'] except IOError: mol.atom = [['B',(0.0000 ,0.0000 ,0.000000 )], ['F',(0.0000 ,1.3070 ,0.00000 )], ['F',(1.1319 ,-0.6535, 0.000 )], ['F',(-1.1319 ,-0.6535, 0.00)]] mol.basis = 'sto-3g' mol.build() _q_=int_func.qmol_func(mol, atomic=True) one_b=_q_.one_body_integrals two_b=_q_.two_body_integrals np.savez(MoleculeFlag+'.npz',one_b=_q_.one_body_integrals,two_b=_q_.two_body_integrals) fer_op = FermionicOperator(h1=one_b, h2=two_b) # Spin symmetry: r1=np.zeros([40,40]) for i in range(40): if i<20: r1[i+20,i]=1. else: r1[i-20,i]=1. r_matrices.append(r1) # R-matrix for plane of symmetry \sigma_{xy}. r2=np.eye(40) r2[4,4]=-1 r2[9,9]=-1 r2[14,14]=-1 r2[19,19]=-1 r2[24,24]=-1 r2[29,29]=-1 r2[34,34]=-1 r2[39,39]=-1 r_matrices.append(r2) # R-matrix for plane of symmetry \sigma_{yz}. r3=np.eye(40) r3[2,2]=-1 r3[7,7]=-1 r3[22,22]=-1 r3[27,27]=-1 for i in range(5): r3[10+i,10+i]=0 r3[15+i,15+i]=0 r3[30+i,30+i]=0 r3[35+i,35+i]=0 r3[10+i,15+i]=1 r3[15+i,10+i]=1 r3[30+i,35+i]=1 r3[35+i,30+i]=1 r3[12,17]=-1 r3[17,12]=-1 r3[32,37]=-1 r3[37,32]=-1 r_matrices.append(r3) # R-matrix for axis of symmetry C_2 around y axis. r4=np.eye(40) r4[2,2]=-1 r4[4,4]=-1 r4[7,7]=-1 r4[9,9]=-1 r4[22,22]=-1 r4[24,24]=-1 r4[29,29]=-1 r4[27,27]=-1 for i in range(5): r4[10+i,10+i]=0 r4[15+i,15+i]=0 r4[30+i,30+i]=0 r4[35+i,35+i]=0 r4[10+i,15+i]=1 r4[15+i,10+i]=1 r4[30+i,35+i]=1 r4[35+i,30+i]=1 r4[12,17]=-1 r4[17,12]=-1 r4[14,19]=-1 r4[19,14]=-1 r4[32,37]=-1 r4[37,32]=-1 r4[34,39]=-1 r4[39,34]=-1 r_matrices.append(r4) # R-matrix for plane of symmetry \sigma_{yz}. # r4=np.zeros([24,24]) # #Swapping px picks up a negative sign # r4[2,7]=r4[7,2]=-1 # r4[14,19]=r4[19,14]=-1 # #Swapping 1s, 2s, 2py and 2pz of Carbon # r4[0,5]=r4[5,0]=1 # r4[1,6]=r4[6,1]=1 # r4[12,17]=r4[17,12]=1 # r4[13,18]=r4[18,13]=1 # r4[3,8]=r4[8,3]=1 # r4[15,20]=r4[20,15]=1 # r4[21,16]=r4[16,21]=1 # r4[9,4]=r4[4,9]=1 # #Swapping 1s of hydrogen # r4[10,11]=r4[11,10]=1 # r4[22,23]=r4[23,22]=1 # # R-matrix for axis of symmetry C_2 around z axis. # r6=np.zeros([24,24]) # #Swapping px picks up a negative sign # r6[2,7]=r6[7,2]=-1 # r6[14,19]=r6[19,14]=-1 # r6[15,20]=r6[20,15]=-1 # r6[3,8]=r6[8,3]=-1 # #Swapping 1s, 2s, 2py and 2pz of Carbon # r6[0,5]=r6[5,0]=1 # r6[1,6]=r6[6,1]=1 # r6[12,17]=r6[17,12]=1 # r6[13,18]=r6[18,13]=1 # r6[9,4]=r6[4,9]=1 # r6[21,16]=r6[16,21]=1 # #Swapping 1s of hydrogen # r6[10,11]=r6[11,10]=1 # r6[22,23]=r6[23,22]=1 # # R-matrix for x-axis symmetry. pz and py orbitals of both the carbon atoms pick up a negative sign. # r7=np.eye(24) # r7[3,3]=-1 # r7[4,4]=-1 # r7[8,8]=-1 # r7[9,9]=-1 # r7[16,16]=-1 # r7[15,15]=-1 # r7[20,20]=-1 # r7[21,21]=-1 # print(r4) # print(np.real(fer_op.h1[0:int(np.size(fer_op.h1,0)/2),0:int(np.size(fer_op.h1,0)/2)])) # fer_op.transform(r4) # # print(np.real(fer_op.h1[0:int(np.size(fer_op.h1,0)/2),0:int(np.size(fer_op.h1,0)/2)])) # # print(np.real(fer_op.h1[0:int(np.size(fer_op.h1,0)/2),0:int(np.size(fer_op.h1,0)/2)]-_q_.one_body_integrals[0:int(np.size(fer_op.h1,0)/2),0:int(np.size(fer_op.h1,0)/2)])) # # print(np.real(fer_op.h1[int(np.size(fer_op.h1,0)/2):int(np.size(fer_op.h1,0)),int(np.size(fer_op.h1,0)/2):int(np.size(fer_op.h1,0))]-_q_.one_body_integrals[int(np.size(fer_op.h1,0)/2):int(np.size(fer_op.h1,0)),int(np.size(fer_op.h1,0)/2):int(np.size(fer_op.h1,0))])) # print(MoleculeFlag) # # print(np.real(fer_op.h1[0:int(np.size(fer_op.h1,0)/2),0:int(np.size(fer_op.h1,0)/2)])) # # print(np.real(fer_op.h1[int(np.size(fer_op.h1,0)/2):int(np.size(fer_op.h1,0)),int(np.size(fer_op.h1,0)/2):int(np.size(fer_op.h1,0))])) # # print(np.real(fer_op.h1[0:int(np.size(fer_op.h1,0)/2),0:int(np.size(fer_op.h1,0)/2)])) # print(np.all(np.abs(fer_op.h1-_q_.one_body_integrals)<1.e-14)) # print(np.all(np.abs(fer_op.h2-_q_.two_body_integrals)<1.e-14)) # print(np.linalg.norm(fer_op.h2-_q_.two_body_integrals)) if check_r_matrix_flag: if bool(check_r_mat(r_matrices,fer_op,one_b,two_b)): print('All the above matrices work!') #================================= # Lithium hydride #================================= elif MoleculeFlag == "LiH": r_matrices =[] print(MoleculeFlag) if is_atomic: try: data = np.load(MoleculeFlag+'.npz') data.files one_b = data['one_b'] two_b = data['two_b'] except IOError: mol.atom = [['Li',(0.000, 0.0000, 0.0000 )], ['H',(1.5949,0.0000, 0.000 )]] mol.build() _q_=int_func.qmol_func(mol, atomic=is_atomic) one_b=_q_.one_body_integrals two_b=_q_.two_body_integrals np.savez(MoleculeFlag+'_ao.npz',one_b=_q_.one_body_integrals,two_b=_q_.two_body_integrals) two_body_temp = QMolecule.twoe_to_spin(_q_.mo_eri_ints) temp_int = np.einsum('ijkl->ljik', _q_.mo_eri_ints) two_body_temp = QMolecule.twoe_to_spin(temp_int) mol = gto.M(atom=mol.atom, basis='sto-3g') O = get_ovlp(mol) X = np.kron(np.identity(2), np.linalg.inv(scipy.linalg.sqrtm(O))) print(_q_.one_body_integrals) fer_op = FermionicOperator(h1=_q_.one_body_integrals, h2=two_body_temp) fer_op.transform(X) else: mol.atom = [['Li',(0.000, 0.0000, 0.0000 )], ['H',(1.5949,0.0000, 0.000 )]] mol.build() _q_=int_func.qmol_func(mol, atomic=is_atomic) one_b=_q_.one_body_integrals two_b=_q_.two_body_integrals fer_op = FermionicOperator(h1=_q_.one_body_integrals, h2=_q_.two_body_integrals) one_b = fer_op.h1 two_b = fer_op.h2 # Spin symmetry: r1=np.zeros([12,12]) for i in range(12): if i<6: r1[i+6,i]=1. else: r1[i-6,i]=1. r_matrices.append(r1) # sigma{xy} r2 = np.eye(12) r2[4,4]=-1 r2[10,10]=-1 r_matrices.append(r2) #sigma(yz) r3 = np.eye(12) r3[3,3]=-1 r3[9,9]=-1 r_matrices.append(r3) if bool(check_r_mat(r_matrices,fer_op,one_b,two_b)): print('All the above matrices work!') #================================= # Beryllium hydride #================================= elif MoleculeFlag == "BeH2": num_particles = 6 r_matrices =[] print(MoleculeFlag) if is_atomic: try: data = np.load(MoleculeFlag+'.npz') data.files one_b = data['one_b'] two_b = data['two_b'] except IOError: mol.atom = [['Be',(0.000, 0.0000, 0.0000 )], ['H',(1.291,0.0000, 0.000 )], ['H',(-1.291,0.0000, 0.000 )]] mol.build() _q_=int_func.qmol_func(mol, atomic=True) one_b=_q_.one_body_integrals two_b=_q_.two_body_integrals # np.savez(MoleculeFlag+'_ao.npz',one_b=_q_.one_body_integrals,two_b=_q_.two_body_integrals) two_body_temp = QMolecule.twoe_to_spin(_q_.mo_eri_ints) temp_int = np.einsum('ijkl->ljik', _q_.mo_eri_ints) two_body_temp = QMolecule.twoe_to_spin(temp_int) mol = gto.M(atom=mol.atom, basis='sto-3g') O = get_ovlp(mol) X = np.kron(np.identity(2), np.linalg.inv(scipy.linalg.sqrtm(O))) fer_op = FermionicOperator(h1=_q_.one_body_integrals, h2=two_body_temp) fer_op.transform(X) else: mol.atom = [['Be',(0.000, 0.0000, 0.0000 )], ['H',(1.291,0.0000, 0.000 )], ['H',(-1.291,0.0000, 0.000 )]] mol.build() _q_=int_func.qmol_func(mol, atomic=is_atomic) one_b=_q_.one_body_integrals two_b=_q_.two_body_integrals fer_op = FermionicOperator(h1=_q_.one_body_integrals, h2=_q_.two_body_integrals) one_b = fer_op.h1 two_b = fer_op.h2 # fer_op = FermionicOperator(h1=one_b, h2=two_b) # R-matrix for plane of symmetry \sigma_{xy}. Everything remains the same, only pz-orbitals pick up negative sign. r1=np.zeros([14,14]) r1[0,0]=1 r1[1,1]=1 r1[2,2]=1 r1[3,3]=1 r1[4,4]=-1 r1[5,5]=1 r1[6,6]=1 r1[7,7]=1 r1[8,8]=1 r1[9,9]=1 r1[10,10]=1 r1[11,11]=-1 r1[12,12]=1 r1[13,13]=1 r_matrices.append(r1) # R-matrix for plane of symmetry \sigma_{xz}. Everything remains the same, only py-orbitals pick up negative sign. r2=np.eye(14) r2[3,3]=-1 r2[10,10]=-1 r_matrices.append(r2) # R-matrix for plane of symmetry \sigma_{yz}. Everything remains the same, only px-orbitals pick up negative sign and hydrogen atoms swap. r3=np.zeros([14,14]) r3[0,0]=1 r3[1,1]=1 r3[2,2]=-1 r3[3,3]=1 r3[4,4]=1 r3[5,6]=1 r3[6,5]=1 r3[7,7]=1 r3[8,8]=1 r3[9,9]=-1 r3[10,10]=1 r3[11,11]=1 r3[12,13]=1 r3[13,12]=1 r_matrices.append(r3) # R-matrix for symmetry-axis C_2. Linear water molecule has three axis of symmetry: # About z-axis r4=np.zeros([14,14]) r4[0,0]=1 r4[1,1]=1 r4[2,2]=-1 r4[3,3]=-1 r4[4,4]=1 r4[5,6]=1 r4[6,5]=1 r4[7,7]=1 r4[8,8]=1 r4[9,9]=-1 r4[10,10]=-1 r4[11,11]=1 r4[12,13]=1 r4[13,12]=1 # r_matrices.append(r4) #About y-axis r5=np.zeros([14,14]) r5[0,0]=1 r5[1,1]=1 r5[2,2]=-1 r5[3,3]=1 r5[4,4]=-1 r5[5,6]=1 r5[6,5]=1 r5[7,7]=1 r5[8,8]=1 r5[9,9]=-1 r5[10,10]=1 r5[11,11]=-1 r5[12,13]=1 r5[13,12]=1 # r_matrices.append(r5) #Symmetry about x-axis: r6=np.zeros([14,14]) r6[0,0]=1 r6[1,1]=1 r6[2,2]=1 r6[3,3]=-1 r6[4,4]=-1 r6[5,5]=1 r6[6,6]=1 r6[7,7]=1 r6[8,8]=1 r6[9,9]=1 r6[10,10]=-1 r6[11,11]=-1 r6[12,12]=1 r6[13,13]=1 # r_matrices.append(r6) #Spin symmetry: r7=np.zeros([14,14]) for i in range(14): if i<7: r7[i+7,i]=1. else: r7[i-7,i]=1. r_matrices.append(r7) if check_r_matrix_flag and is_atomic: if bool(check_r_mat(r_matrices,fer_op,one_b,two_b)): print('All the above matrices work!') elif MoleculeFlag == "test": r_matrices =[] num_particles = 6 print(MoleculeFlag) # try: # data = np.load(MoleculeFlag+'.npz') # data.files # one_b = data['one_b'] # two_b = data['two_b'] # except IOError: mol.atom = [['Be',(0.000, 0.0000, 0.0000 )], ['H',(1.3264,0.0000, 0.000 )], ['H',(-1.3264,0.0000, 0.000 )]] mol.atom = [['Be',(0.000, 0.0000, 0.0000 )], ['H',(1.291,0.0000, 0.000 )], ['H',(-1.291,0.0000, 0.000 )]] mol.atom = [['Be',(0.000, 0.0000, 0.0000 )], ['H',(1.3,0.0000, 0.000 )], ['H',(-1.3,0.0000, 0.000 )]] mol.basis = 'sto-6g' # mol.symmetry=True # mol.atom = [['H',(0, 0, -0.3707)], ['H',(0,0.0,0.3707)]] mol.build() # is_atomic = _q_ = qmol_func(mol, atomic=is_atomic) if is_atomic: two_body_temp = QMolecule.twoe_to_spin(_q_.mo_eri_ints) temp_int = np.einsum('ijkl->ljik', _q_.mo_eri_ints) two_body_temp = QMolecule.twoe_to_spin(temp_int) mol = gto.M(atom=mol.atom, basis='sto-3g') O = get_ovlp(mol) X = np.kron(np.identity(2), np.linalg.inv(scipy.linalg.sqrtm(O))) fer_op = FermionicOperator(h1=_q_.one_body_integrals, h2=two_body_temp) fer_op.transform(X) else: fer_op = FermionicOperator(h1=_q_.one_body_integrals, h2=_q_.two_body_integrals) one_b = fer_op.h1 two_b = fer_op.h2 # np.savez(MoleculeFlag+'.npz',one_b=_q_.one_body_integrals,two_b=_q_.two_body_integrals) # fer_op = FermionicOperator(h1=one_b, h2=two_b) # print(fer_op.h1) # exit() # r_matrices.append(np.eye(14)) # R-matrix for plane of symmetry \sigma_{xy}. Everything remains the same, only pz-orbitals pick up negative sign. r1=np.zeros([14,14]) r1[0,0]=1 r1[1,1]=1 r1[2,2]=1 r1[3,3]=1 r1[4,4]=-1 r1[5,5]=1 r1[6,6]=1 r1[7,7]=1 r1[8,8]=1 r1[9,9]=1 r1[10,10]=1 r1[11,11]=-1 r1[12,12]=1 r1[13,13]=1 r_matrices.append(r1) # R-matrix for plane of symmetry \sigma_{xz}. Everything remains the same, only py-orbitals pick up negative sign. r2=np.eye(14) r2[3,3]=-1 r2[10,10]=-1 r_matrices.append(r2) # R-matrix for plane of symmetry \sigma_{yz}. Everything remains the same, only px-orbitals pick up negative sign and hydrogen atoms swap. r3=np.zeros([14,14]) r3[0,0]=1 r3[1,1]=1 r3[2,2]=-1 r3[3,3]=1 r3[4,4]=1 r3[5,6]=1 r3[6,5]=1 r3[7,7]=1 r3[8,8]=1 r3[9,9]=-1 r3[10,10]=1 r3[11,11]=1 r3[12,13]=1 r3[13,12]=1 r_matrices.append(r3) # R-matrix for symmetry-axis C_2. Linear water molecule has three axis of symmetry: # About z-axis r4=np.zeros([14,14]) r4[0,0]=1 r4[1,1]=1 r4[2,2]=-1 r4[3,3]=-1 r4[4,4]=1 r4[5,6]=1 r4[6,5]=1 r4[7,7]=1 r4[8,8]=1 r4[9,9]=-1 r4[10,10]=-1 r4[11,11]=1 r4[12,13]=1 r4[13,12]=1 # r_matrices.append(r4) #About y-axis r5=np.zeros([14,14]) r5[0,0]=1 r5[1,1]=1 r5[2,2]=-1 r5[3,3]=1 r5[4,4]=-1 r5[5,6]=1 r5[6,5]=1 r5[7,7]=1 r5[8,8]=1 r5[9,9]=-1 r5[10,10]=1 r5[11,11]=-1 r5[12,13]=1 r5[13,12]=1 # r_matrices.append(r5) #Symmetry about x-axis: r6=np.zeros([14,14]) r6[0,0]=1 r6[1,1]=1 r6[2,2]=1 r6[3,3]=-1 r6[4,4]=-1 r6[5,5]=1 r6[6,6]=1 r6[7,7]=1 r6[8,8]=1 r6[9,9]=1 r6[10,10]=-1 r6[11,11]=-1 r6[12,12]=1 r6[13,13]=1 # r_matrices.append(r6) #Spin symmetry: r7=np.zeros([14,14]) for i in range(14): if i<7: r7[i+7,i]=1. else: r7[i-7,i]=1. # r_matrices.append(r7) r8=np.zeros([14,14]) r8[0,0]=1 r8[1,1]=1 r8[2,2]=-1 r8[3,3]=-1 r8[4,4]=-1 r8[5,6]=1 r8[6,5]=1 r8[7,7]=1 r8[8,8]=1 r8[9,9]=-1 r8[10,10]=-1 r8[11,11]=-1 r8[12,13]=1 r8[13,12]=1 # r_matrices.append(r8) # r_matrices=[] # r_matrices.append(np.eye(fer_op.modes)) if check_r_matrix_flag: if bool(check_r_mat(r_matrices,fer_op,one_b,two_b)): print('All the above matrices work!') if is_atomic: return [r_matrices,fer_op,num_particles] else: r_matrices =[] r_matrices.append(np.eye(fer_op.modes)) return [r_matrices,fer_op, num_particles]
def init_guess_by_chkfile(mol, chkfile_name, project=None): '''Read SCF chkfile and make the density matrix for GHF initial guess. Kwargs: project : None or bool Whether to project chkfile's orbitals to the new basis. Note when the geometry of the chkfile and the given molecule are very different, this projection can produce very poor initial guess. In PES scanning, it is recommended to swith off project. If project is set to None, the projection is only applied when the basis sets of the chkfile's molecule are different to the basis sets of the given molecule (regardless whether the geometry of the two molecules are different). Note the basis sets are considered to be different if the two molecules are derived from the same molecule with different ordering of atoms. ''' from pyscf.scf import addons chk_mol, scf_rec = chkfile.load_scf(chkfile_name) if project is None: project = not gto.same_basis_set(chk_mol, mol) # Check whether the two molecules are similar enough def inertia_momentum(mol): im = gto.inertia_momentum(mol._atom, mol.atom_charges(), mol.atom_coords()) return scipy.linalg.eigh(im)[0] if abs(inertia_momentum(mol) - inertia_momentum(chk_mol)).sum() > 0.5: logger.warn( mol, "Large deviations found between the input " "molecule and the molecule from chkfile\n" "Initial guess density matrix may have large error.") if project: s = hf.get_ovlp(mol) def fproj(mo): if project: mo = addons.project_mo_nr2nr(chk_mol, mo, mol) norm = numpy.einsum('pi,pi->i', mo.conj(), s.dot(mo)) mo /= numpy.sqrt(norm) return mo nao = chk_mol.nao_nr() mo = scf_rec['mo_coeff'] mo_occ = scf_rec['mo_occ'] if hasattr(mo[0], 'ndim') and mo[0].ndim == 1: # RHF/GHF/DHF if nao * 2 == mo.shape[0]: # GHF or DHF if project: raise NotImplementedError('Project initial guess from ' 'different geometry') else: dm = hf.make_rdm1(mo, mo_occ) else: # RHF mo_coeff = fproj(mo) mo_occa = (mo_occ > 1e-8).astype(numpy.double) mo_occb = mo_occ - mo_occa dma, dmb = uhf.make_rdm1([mo_coeff] * 2, (mo_occa, mo_occb)) dm = scipy.linalg.block_diag(dma, dmb) else: #UHF if hasattr(mo[0][0], 'ndim') and mo[0][0].ndim == 2: # KUHF logger.warn( mol, 'k-point UHF results are found. Density matrix ' 'at Gamma point is used for the molecular SCF initial guess') mo = mo[0] dma, dmb = uhf.make_rdm1([fproj(mo[0]), fproj(mo[1])], mo_occ) dm = scipy.linalg.block_diag(dma, dmb) return dm