def system_h4(): print('Running System Setup H4') basis = 'sto-3g' multiplicity = 1 charge = 0 r = 0.75 geometry = [('H', [0.0, 0.0, 0.0]), ('H', [0, 0, r]), ('H', [0, 0, 2 * r]), ('H', [0, 0, 3 * r])] molecule = MolecularData(geometry, basis, multiplicity, charge) # Run Psi4. molecule = run_psi4(molecule, run_scf=True, run_mp2=False, run_cisd=False, run_ccsd=False, run_fci=True, delete_input=False) op_mat = of.get_sparse_operator( molecule.get_molecular_hamiltonian()).toarray() w, v = np.linalg.eigh(op_mat) n_density = v[:, [0]] @ v[:, [0]].conj().T rdm_generator = AntiSymmOrbitalDensity(n_density, molecule.n_qubits) transform = jordan_wigner return n_density, rdm_generator, transform, molecule
def create_molecule(): geometry = make_geometry() basis = 'sto-3g' charge = 0 multiplicity = 1 moleculefilename = '/app/moleculefile.hdf5' molecule = MolecularData(geometry, basis, multiplicity, charge, description, filename=moleculefilename) # openfermion's run_psi4 molecule = run_psi4(molecule, run_scf=1, run_mp2=1, run_cisd=0, run_ccsd=0, run_fci=0, verbose=1, tolerate_error=1) molecule.save()
def test_energies(self): molecule = q_system.H2() molecule_data = openfermion.hamiltonians.MolecularData( geometry=molecule.get_geometry({'distance': 0.735}), basis='sto-3g', multiplicity=molecule.multiplicity, charge=molecule.charge) molecule_psi4 = openfermionpsi4.run_psi4(molecule_data) # Get a qubit representation of the molecule hamiltonian molecule_ham = molecule_psi4.get_molecular_hamiltonian() fermion_ham = openfermion.transforms.get_fermion_operator(molecule_ham) h = openfermion.transforms.jordan_wigner(fermion_ham) ansatz_elements = UCCSD(molecule.n_orbitals, molecule.n_electrons).get_excitations() var_parameters = numpy.zeros(len(ansatz_elements)) var_parameters[-1] = 0.11 energy_qiskit_sim = QiskitSimBackend.ham_expectation_value( h, ansatz_elements, var_parameters, molecule.n_orbitals, molecule.n_electrons)[0].real energy_matrix_mult = ExcStateSim.get_energy( h, ansatz_elements, var_parameters, molecule.n_orbitals, molecule.n_electrons)[0].real self.assertEqual(round(energy_qiskit_sim, 3), round(energy_matrix_mult, 3))
def h_n_linear_molecule(bond_distance: float, n_hydrogens: int, basis: str = 'sto-3g'): # coverage: ignore if n_hydrogens < 1 or n_hydrogens % 2 != 0: raise ValueError('Must specify a positive, even number of hydrogens.') molecule = of.MolecularData( geometry=_h_n_linear_geometry(bond_distance, n_hydrogens), charge=0, basis=basis, multiplicity=1, description=f"linear_r-{bond_distance}", ) if NO_OFPSI4: raise NOOFPsi4Error("openfermion-psi4 is not installed") molecule = run_psi4(molecule, run_fci=False, run_mp2=False, run_cisd=False, run_ccsd=False, delete_input=False, delete_output=False) return molecule
def __init__(self, molecule, wf_type='fci'): """Take a OpenFermion molecule object and return one with calcs""" if not isinstance(molecule, MolecularData): raise TypeError( "molecule must be an OpenFermion Molecular Data Object") # get the calculation type run_scf = 1 run_mp2 = 0 run_cisd = 0 run_ccsd = 0 run_fci = 1 molecule_psi4 = run_psi4(molecule, run_scf=run_scf, run_mp2=run_mp2, run_cisd=run_cisd, run_ccsd=run_ccsd, run_fci=run_fci) tpdm_index_exchange = np.einsum('ijkl->ijlk', molecule_psi4.fci_two_rdm) self.opdm = molecule_psi4.fci_one_rdm self.tpdm = tpdm_index_exchange self.oqdm = None self.tqdm = None self.phdm = None
def get_openfermion_molecule(geometry, basis, charge, multiplicity, calc_type='fci'): """ Get openfermion molecule objects :param geometry: list of tuples where first element of the tuple is the atom string, and next three coordinates are XYZ geom :param basis: (string) of basis set :param multiplicity: eigenvalue of S^{2} (2S + 1) :param charge: (int) charge on molecule :param calc_type: (string) valid calculation types are: ['scf', 'mp2', 'cisd', 'ccsd', 'fci']. default is 'fci' if 'fci' is selected the fci_one_rdm and fci_two_rdm fields are populated and can be used later. Conversion to particle and holes can occur with methods in the representability.purification.fermionic_marginal :return: """ valid_calc_types = ['scf', 'mp2', 'cisd', 'ccsd', 'fci'] if calc_type not in valid_calc_types: raise TypeError("Calculation type is not valid") molecule = MolecularData(geometry, basis, multiplicity, charge) # get the calculation type run_scf = 1 run_mp2 = 0 run_cisd = 0 run_ccsd = 0 run_fci = 1 # default to fci run molecule = run_psi4(molecule, run_scf=run_scf, run_mp2=run_mp2, run_cisd=run_cisd, run_ccsd=run_ccsd, run_fci=run_fci) return molecule
def runPsi4(geometry, kwargs): """ Returns an updated MolecularData object Parameters ---------- geometry: list A list of tuples giving the coordinates of each atom. An example is [('H', (0, 0, 0)), ('H', (0, 0, 0.7414))] Distances in angstrom. Use atomic symbols to specify atoms. kwargs: dict A dictionary to set up psi4 calculation keys: basis, multiplicity, charge, description, run_scf, run_mp2, run_cisd, run_ccsd, run_fci """ basis = kwargs.get('basis', 'sto-3g') multiplicity = kwargs.get('multiplicity', 1) charge = kwargs.get('charge', 0) description = kwargs.get('description', '') molecule = openfermion.hamiltonians.MolecularData(geometry, basis, multiplicity, charge, description) molecule = openfermionpsi4.run_psi4(molecule, run_scf=kwargs.get('run_scf', 1), run_mp2=kwargs.get('run_mp2', 0), run_cisd=kwargs.get('run_cisd', 0), run_ccsd=kwargs.get('run_ccsd', 0), run_fci=kwargs.get('run_fci', 0)) return molecule
def ucc(geometry, basis="sto-3g", multiplicity=1, charge=1, theta_thresh=1e-7, pool=operator_pools.singlet_GSD(), spin_adapt=True, psi4_filename="psi4_%12.12f" % random.random()): # {{{ molecule = openfermion.hamiltonians.MolecularData(geometry, basis, multiplicity) molecule.filename = psi4_filename molecule = openfermionpsi4.run_psi4(molecule, run_scf=1, run_mp2=1, run_cisd=0, run_ccsd=0, run_fci=1, delete_input=1) pool.init(molecule) print(" Basis: ", basis) print(' HF energy %20.16f au' % (molecule.hf_energy)) print(' MP2 energy %20.16f au' % (molecule.mp2_energy)) #print(' CISD energy %20.16f au' %(molecule.cisd_energy)) #print(' CCSD energy %20.16f au' %(molecule.ccsd_energy)) print(' FCI energy %20.16f au' % (molecule.fci_energy)) #Build p-h reference and map it to JW transform reference_ket = scipy.sparse.csc_matrix( openfermion.jw_configuration_state( list(range(0, molecule.n_electrons)), molecule.n_qubits)).transpose() reference_bra = reference_ket.transpose().conj() #JW transform Hamiltonian computed classically with OFPsi4 hamiltonian_op = molecule.get_molecular_hamiltonian() hamiltonian = openfermion.transforms.get_sparse_operator(hamiltonian_op) #Thetas parameters = [0] * pool.n_ops pool.generate_SparseMatrix() ucc = UCC(hamiltonian, pool.spmat_ops, reference_ket, parameters) opt_result = scipy.optimize.minimize(ucc.energy, parameters, options={ 'gtol': 1e-6, 'disp': True }, method='BFGS', callback=ucc.callback) print(" Finished: %20.12f" % ucc.curr_energy) parameters = opt_result['x'] for p in parameters: print(p)
def __init__(self, name, geometry, multiplicity, charge, n_orbitals, n_electrons, basis='sto-3g', frozen_els=None): self.name = name self.multiplicity = multiplicity self.charge = charge self.basis = basis self.geometry = geometry self.molecule_data = MolecularData(geometry=self.geometry, basis=basis, multiplicity=self.multiplicity, charge=self.charge) self.molecule_psi4 = run_psi4( self.molecule_data, run_fci=True) # old version of openfermion # Hamiltonian transforms self.molecule_ham = self.molecule_psi4.get_molecular_hamiltonian() self.hf_energy = self.molecule_psi4.hf_energy.item( ) # old version of openfermion self.fci_energy = self.molecule_psi4.fci_energy.item( ) # old version of openfermion # TODO: the code below corresponds to the most recent version in the opefermion documentation. # However it has problems with ray??? # calculate_molecule_psi4 = run_pyscf(self.molecule_data, run_scf=True, run_cisd=True, run_fci=True) # self.molecule_ham = calculate_molecule_psi4.get_molecular_hamiltonian() # self.hf_energy = calculate_molecule_psi4.hf_energy # self.fci_energy = float(calculate_molecule_psi4.fci_energy) # del calculate_molecule_psi4 self.energy_eigenvalues = None # use this only if calculating excited states if frozen_els is None: self.n_electrons = n_electrons self.n_orbitals = n_orbitals self.n_qubits = n_orbitals self.fermion_ham = get_fermion_operator(self.molecule_ham) else: self.n_electrons = n_electrons - len(frozen_els['occupied']) self.n_orbitals = n_orbitals - len(frozen_els['occupied']) - len( frozen_els['unoccupied']) self.n_qubits = self.n_orbitals self.fermion_ham = freeze_orbitals( get_fermion_operator(self.molecule_ham), occupied=frozen_els['occupied'], unoccupied=frozen_els['unoccupied'], prune=True) self.jw_qubit_ham = jordan_wigner(self.fermion_ham) # this is used only for calculating excited states. list of [term_index, term_state] self.H_lower_state_terms = None
def FCI_get_Energy(bond_length): #求めるハミルトニアンのデータ geometry = [["H", [0, 0, 0]], ["H", [0, 0, bond_length]]] basis = "sto-3g" multiplicity = 1 charge = 0 description = "test" #str() molecule = MolecularData(geometry, basis, multiplicity, charge, description) #求めるハミルトニアンのJW変換 molecule = run_psi4(molecule) jw_hamiltonian = jordan_wigner( get_fermion_operator(molecule.get_molecular_hamiltonian())) jw_matrix = get_sparse_operator(jw_hamiltonian) #FCI計算 molecule = run_psi4(molecule, run_scf=1, run_fci=1) eigenenergies, eigenvecs = eigs(jw_matrix) return molecule.fci_energy
def energy_levels(separation): g = [('H', (0., 0., 0.)), ('H', (0., 0., separation))] d = str(separation) m = MolecularData(g, basis, multiplicity, description=d, data_directory=data_directory) run_psi4(m, run_fci=True, delete_output=True) _, s = get_ground_state( get_sparse_operator( normal_ordered( get_fermion_operator( m.get_molecular_hamiltonian( active_indices=range(active_spatial_orbitals)))))) h = normal_ordered( get_fermion_operator( m.get_molecular_hamiltonian( active_indices=range(active_spatial_orbitals + virtual_spatial_orbitals)))) o = vqse_operators(s) return generalized_eigenvalues(h_matrix(h, o, s), s_matrix(o, s))
def get_h2_dimer(bond_length): # Set molecule parameters. basis = "sto-3g" multiplicity = 1 charge = 0 geometry = [("H", [0.0, 0.0, 0.0]), ("H", [0.0, 0.0, bond_length])] molecule = MolecularData(geometry, basis, multiplicity, charge) molecule.filename = "./" + molecule.filename.split("/")[-1] # Run Psi4. molecule = run_psi4( molecule, run_scf=True, run_mp2=False, run_cisd=False, run_ccsd=True, run_fci=True ) return molecule
def HF_get_Energy(bond_length): #求めるハミルトニアンのデータ geometry = [["H", [0, 0, 0]], ["H", [0, 0, bond_length]]] basis = "sto-3g" multiplicity = 1 charge = 0 description = "test" #str() molecule = MolecularData(geometry, basis, multiplicity, charge, description) molecule = run_psi4(molecule) return molecule.hf_energy
def _generate_molecule(self, p: IParameter) -> MolecularData: """Produce molecule that can be used by the hamiltonian. Using a singlet state with S = 0 to specify we are looking for the lowest singlet energy state. multiplicity = 2S + 1 """ geometry = [('H', (0., 0., 0.)), ('H', (0., 0., p['r0']))] basis = 'sto-3g' multiplicity = 1 charge = 0 description = str(p['r0']) # Change to whatever directory you want cwd = os.getcwd() data_directory = cwd+'/mol_data' if not os.path.exists(data_directory): os.mkdir(data_directory) filename = data_directory+'/H2_'+description run_scf = 1 run_mp2 = 1 run_cisd = 1 run_ccsd = 1 run_fci = 1 delete_input = False delete_output = False verbose = False molecule = MolecularData( geometry, basis, multiplicity, description=description, filename=filename) if os.path.exists('{}.hdf5'.format(filename)): molecule.load() else: molecule = run_psi4(molecule, verbose=verbose, run_scf=run_scf, run_mp2=run_mp2, run_cisd=run_cisd, run_ccsd=run_ccsd, run_fci=run_fci) # print(f'Reference (Full Configuration Energy: {molecule.fci_energy})') return molecule
def make_one_rdm(target_molecule): geometry, multiplicity, charge = generate_molecule_dict( ) #Returns the basic info of the molecule molecule = generate_molecule_hamiltonian( target_molecule, 'sto-3g') #Returns MolecularData object (OpenFermion Docs p41) molecule = run_psi4(molecule, run_scf=False, run_mp2=False, run_cisd=True, run_ccsd=False, run_fci=False) #Calculates energies, integrals one_RDM = molecule.cisd_one_rdm #Returns the 1-RDM as calculated in the CISD basis one_RDM = merge_spins(one_RDM) return one_RDM
def generate_figure_1(): singlet_glob = glob.glob('molecule_data/*sto-3g_singlet*.hdf5') singlet_glob = sorted(singlet_glob) triplet_glob = glob.glob('molecule_data/*sto-3g_triplet*.hdf5') triplet_glob = sorted(triplet_glob) singlet_fci = [ float(MolecularData(filename=fn).fci_energy) for fn in singlet_glob ] triplet_fci = [ MolecularData(filename=fn).fci_energy for fn in triplet_glob ] xx = [float(MolecularData(filename=fn).description) for fn in singlet_glob] #print(singlet_fci) #print(triplet_fci) #print(xx) geometry = [('H', (0., 0., 0.)), ('H', (0., 0., 1.))] basis = 'sto-3g' multiplicity = 3 description = '1.0' filename = 'test_test_test_H2' molecule = MolecularData(geometry, basis, multiplicity, description=description, filename=filename) molecule = run_psi4(molecule, run_mp2=False, run_cisd=False, run_ccsd=True, run_fci=True) #molecule = MolecularData(filename=triplet_glob[0]) print('filename: {}'.format(molecule.filename)) print('n_atoms: {}'.format(molecule.n_atoms)) print('n_electrons: {}'.format(molecule.n_electrons)) print('n_orbitals: {}'.format(molecule.n_orbitals)) #print('Canonical Orbitals: {}'.format(molecule.canonical_orbitals)) print('n_qubits: {}'.format(molecule.n_qubits)) print(molecule.ccsd_energy) print(molecule.description) print(molecule.two_body_integrals) print(molecule.multiplicity)
def generate(self, inputParams): geom = ast.literal_eval(inputParams['geometry']) if isinstance( inputParams['geometry'], str) else inputParams['geometry'] mdata = MolecularData(geom, inputParams['basis'], int(inputParams['multiplicity']), int(inputParams['charge'])) molecule = run_psi4(mdata, run_scf=1, run_fci=1) from openfermion.transforms import get_sparse_operator, jordan_wigner from openfermion.utils import sparse_eigenspectrum from scipy.sparse import find from scipy.optimize import minimize fermiOp = get_fermion_operator(molecule.get_molecular_hamiltonian()) qop = jordan_wigner(fermiOp) inputParams['fci'] = molecule.fci_energy inputParams['hf'] = molecule.hf_energy return xaccvqe.QubitOperator2XACC(qop)
def heh_system(): basis = 'sto-3g' multiplicity = 1 charge = 1 geometry = [('He', [0.0, 0.0, 0.0]), ('H', [0, 0, 0.75])] molecule = MolecularData(geometry, basis, multiplicity, charge) # Run Psi4. molecule = run_psi4(molecule, run_scf=True, run_mp2=False, run_cisd=False, run_ccsd=False, run_fci=True, delete_input=False) molecule, gs_wf, n_density, eigen_val = get_molecule_openfermion(molecule, eigen_index=2) rdm_generator = SpinOrbitalDensity(n_density, molecule.n_qubits) transform = jordan_wigner return n_density, rdm_generator, transform, molecule
def get_H2_info(R, basis='sto-3g', multiplicity=1, charge=0): geometry = [['H', [0, 0, 0]], ['H', [0, 0, R]]] h2_molecule = MolecularData(geometry, basis, multiplicity, charge) h2_molecule = run_psi4(h2_molecule, run_mp2=True, run_ccsd=True, run_fci=True) one_body = h2_molecule.one_body_integrals two_body = h2_molecule.two_body_integrals Enuc = h2_molecule.nuclear_repulsion energies = {} energies['fci'] = h2_molecule.fci_energy energies['hf'] = h2_molecule.hf_energy energies['ccsd'] = h2_molecule.ccsd_energy #print('electron:',h2_molecule.n_electrons) return one_body, two_body, Enuc, energies
def generate_and_save(geometry, basis, multiplicity, description, filename): # Initialize the molecule molecule = MolecularData(geometry, basis, multiplicity, description=description, filename=filename) print('Molecule filename: ', filename) #molecule.save() # Compute the active space integrals print('-computing integrals') molecule = run_psi4(molecule, run_mp2=False, run_cisd=False, run_ccsd=False, run_fci=True) #molecule = run_pyscf(molecule,run_mp2=True,run_cisd=True,run_ccsd=True,run_fci=True) print('Successful generation')
def expectation(p1, p2, p3, multi=1): """ Return UCC expectation value for a specified geometry * First runs a psi4 ccsd calculation to get single and double amplitudes to use as ansatz for UCC * Generates a Hamiltonian for the specified geometry * Obtains expectation value using VQE """ geometry = [['O', p1], ['H', p2], ['H', p3]] molecule = MolecularData(geometry, basis='sto-3g', multiplicity=multi, description=str(round(rad, 2)) + "_" + str(round(ang, 2))) # Run Psi4. molecule = run_psi4(molecule, run_ccsd=1, run_fci=1) # Print out some results of calculation. print('\nRAD: {}, ANG: {}\n'.format(rad, ang)) print('FCI energy: {} Hartree.'.format(molecule.fci_energy)) singles_initial = molecule.ccsd_single_amps.flatten() doubles_initial = molecule.ccsd_double_amps.flatten() amps = np.concatenate((singles_initial, doubles_initial), axis=0) print("Compiling the Hamiltonian...") hamiltonian = jordan_wigner( get_fermion_operator(molecule.get_molecular_hamiltonian())) hamiltonian.compress() hamiltonian = qubitop_to_pyquilpauli(hamiltonian) print("Hamiltonian complete") vqe = VQE(minimizer=minimize, minimizer_kwargs={ 'method': 'nelder-mead', 'options': { 'fatol': 1.5e-3 } }) result = vqe.expectation(ansatz(amps), hamiltonian, None, qvm) print("VQE Expectation Value: {} Hartree".format(result)) return result
def get_molecule_openfermion(molecule, eigen_index=0): # check if the molecule is in the molecules data directory if molecule.name + '.hdf5' in os.listdir(DATA_DIRECTORY): print("\tLoading File from {}".format(DATA_DIRECTORY)) molecule.load() else: # compute properties with run_psi4 molecule = run_psi4(molecule, run_fci=True) print("\tPsi4 Calculation Completed") print("\tSaved in {}".format(DATA_DIRECTORY)) molecule.save() fermion_hamiltonian = molecule.get_molecular_hamiltonian() qubitop_hamiltonian = jordan_wigner(fermion_hamiltonian) psum = qubitop_to_pyquilpauli(qubitop_hamiltonian) ham = tensor_up(psum, molecule.n_qubits) if isinstance(ham, (csc_matrix, csr_matrix)): ham = ham.toarray() w, v = np.linalg.eigh(ham) gs_wf = v[:, [eigen_index]] n_density = gs_wf.dot(np.conj(gs_wf).T) return molecule, v[:, [eigen_index]], n_density, w[eigen_index]
def generate_diatomic(element_names, basis='sto-3g', charge=0, multiplicity=1, spacings=None): if spacings is None: spacings = [0.1 * r for r in range(1, 25)] run_scf = 1 run_mp2 = 1 run_cisd = 1 run_ccsd = 1 run_fci = 1 verbose = 1 tolerate_error = 1 for spacing in spacings: description = '{:.4}'.format(spacing) geometry = [[element_names[0], [0, 0, 0]], [element_names[1], [0, 0, spacing]]] molecure_src = MolecularData( geometry, basis, multiplicity, charge, description, data_directory=os.path.abspath('./ising_solver/diatomic')) molecule = run_psi4(molecure_src, run_scf=run_scf, run_mp2=run_mp2, run_cisd=run_cisd, run_ccsd=run_ccsd, run_fci=run_fci, verbose=verbose, tolerate_error=tolerate_error) molecule.save()
def load_molecule(self): ''' This function is designed to initialize the molecule through the use of the OpenFermion and OpenFermion-Psi4 packages. In order for this function to perform properly, a molecule's parameters must be set through the use of the setter functions. The parameters required are: name, geometry, basis, multiplicity, and charge.''' # Generate and populate instance of MolecularData. if (self.description != ''): molecule = MolecularData(self.geometry, self.basis, self.multiplicity, self.charge, self.description) else: molecule = MolecularData(self.geometry, self.basis, self.multiplicity, self.charge) # Determine if integrals have been previously generated or not if not (os.path.exists(molecule.filename + '.hdf5')): # Set calculation parameters. run_scf, run_mp2, run_cisd, run_ccsd, run_fci = 1, 1, 1, 1, 1 molecule = run_psi4(molecule, run_scf=run_scf, run_mp2=run_mp2, run_cisd=run_cisd, run_ccsd=run_ccsd, run_fci=run_fci) # Save molecule for future, so that regeneration is not required molecule.save() molecule.load() else: molecule.load() self.molecule = molecule self.name = self.name.replace(" ", "_")
def system_h4(): print('Running System Setup H4') basis = 'sto-3g' multiplicity = 1 charge = 0 r = 0.75 geometry = [('H', [0.0, 0.0, 0.0]), ('H', [0, 0, r]), ('H', [0, 0, 2 * r]), ('H', [0, 0, 3 * r])] molecule = MolecularData(geometry, basis, multiplicity, charge) # Run Psi4. molecule = run_psi4(molecule, run_scf=True, run_mp2=False, run_cisd=False, run_ccsd=False, run_fci=True, delete_input=False) molecule, gs_wf, n_density, eigen_val = get_molecule_openfermion( molecule, eigen_index=0) rdm_generator = AntiSymmOrbitalDensity(n_density, molecule.n_qubits) transform = jordan_wigner return n_density, rdm_generator, transform, molecule
def generate_and_save(geometry, basis, multiplicity, charge, description, mfilename): # initialize the molecule molecule = MolecularData(geometry, basis, multiplicity, charge, description=description, filename=mfilename) molecule.save() # compute the active space integrals print('-computing integrals-') molecule = run_psi4(molecule, run_mp2=True, run_cisd=True, run_ccsd=True, run_fci=True) print(molecule.filename) print(molecule.two_body_integrals) print(molecule.canonical_orbitals) molecule.save() print('Successful generation')
spacings = [1.7698] # Add points for a full dissociation curve from 0.1 to 3.0 angstroms spacings += [0.1 * r for r in range(1, 30)] # Set run options run_scf = 1 run_mp2 = 1 run_cisd = 1 run_ccsd = 1 run_fci = 1 verbose = 1 tolerate_error = 1 # Run Diatomic Curve for spacing in spacings: description = "{:.2f}".format(spacing) geometry = [['Be', [0, 0, 0]], ['H', [0, 0, spacing]], ['H', [0, 0, -spacing]]] molecule = MolecularData(geometry, basis, multiplicity, charge, description) molecule = run_psi4(molecule, run_scf=run_scf, run_mp2=run_mp2, run_cisd=run_cisd, run_ccsd=run_ccsd, run_fci=run_fci, verbose=verbose, tolerate_error=tolerate_error) molecule.save()
def meanfield( name, geometry, charge=0, mult=1, basis="sto-3g", package="pyscf", outpath="." ): # pylint: disable=too-many-arguments r"""Generates a file from which the mean field electronic structure of the molecule can be retrieved. This function uses OpenFermion-PySCF and OpenFermion-Psi4 plugins to perform the Hartree-Fock (HF) calculation for the polyatomic system using the quantum chemistry packages ``PySCF`` and ``Psi4``, respectively. The mean field electronic structure is saved in an hdf5-formatted file in the directory ``os.path.join(outpath, package, basis)``. The charge of the molecule can be given to simulate cationic/anionic systems. Also, the spin multiplicity can be input to determine the number of unpaired electrons occupying the HF orbitals as illustrated in the figure below. | .. figure:: ../../_static/qchem/hf_references.png :align: center :width: 50% | Args: name (str): molecule label geometry (list): list containing the symbol and Cartesian coordinates for each atom charge (int): net charge of the system mult (int): Spin multiplicity :math:`\mathrm{mult}=N_\mathrm{unpaired} + 1` for :math:`N_\mathrm{unpaired}` unpaired electrons occupying the HF orbitals. Possible values for ``mult`` are :math:`1, 2, 3, \ldots`. If not specified, a closed-shell HF state is assumed. basis (str): Atomic basis set used to represent the HF orbitals. Basis set availability per element can be found `here <www.psicode.org/psi4manual/master/basissets_byelement.html#apdx-basiselement>`_ package (str): Quantum chemistry package used to solve the Hartree-Fock equations. Either ``'pyscf'`` or ``'psi4'`` can be used. outpath (str): path to output directory Returns: str: absolute path to the file containing the mean field electronic structure **Example** >>> name = 'h2' >>> geometry = [['H', (0.0, 0.0, -0.35)], ['H', (0.0, 0.0, 0.35)]] >>> meanfield(name, geometry) ./pyscf/sto-3g/h2 """ package = package.strip().lower() if package not in ("psi4", "pyscf"): error_message = ( "Integration with quantum chemistry package '{}' is not available. \n Please set" " 'package' to 'pyscf' or 'psi4'.".format(package) ) raise TypeError(error_message) package_dir = os.path.join(outpath.strip(), package) basis_dir = os.path.join(package_dir, basis.strip()) if not os.path.isdir(package_dir): os.mkdir(package_dir) os.mkdir(basis_dir) elif not os.path.isdir(basis_dir): os.mkdir(basis_dir) path_to_file = os.path.join(basis_dir, name.strip()) molecule = MolecularData(geometry, basis, mult, charge, filename=path_to_file) if package == "psi4": run_psi4(molecule, run_scf=1, verbose=0, tolerate_error=1) if package == "pyscf": run_pyscf(molecule, run_scf=1, verbose=0) return path_to_file
def get_Energy(bond_length): #パウリ演算子の準備 nqubits = 4 pI = np.array([[1 + 0.0j, 0 + 0.0j], [0 + 0.0j, 1 + 0.0j]]) pX = np.array([[0 + 0.0j, 1 + 0.0j], [1 + 0.0j, 0 + 0.0j]]) pZ = np.array([[1 + 0.0j, 0 + 0.0j], [0 + 0.0j, -1 + 0.0j]]) pY = np.array([[0 + 0.0j, -1.0j], [0.0 + 1.0j, 0.0 + 0.0j]]) pHad = (pX + pZ) / np.sqrt(2) pP0 = (pI + pZ) / 2 pP1 = (pI - pZ) / 2 #任意の状態に演算できるように準備 X = [1] * (nqubits) Y = [1] * (nqubits) Z = [1] * (nqubits) H = [1] * (nqubits) P0 = [1] * (nqubits) P1 = [1] * (nqubits) for i in range(nqubits): for j in range(nqubits): if (i != j): X[i] = np.kron(pI, X[i]) Y[i] = np.kron(pI, Y[i]) Z[i] = np.kron(pI, Z[i]) H[i] = np.kron(pI, H[i]) P0[i] = np.kron(pI, P0[i]) P1[i] = np.kron(pI, P1[i]) else: X[i] = np.kron(pX, X[i]) Y[i] = np.kron(pY, Y[i]) Z[i] = np.kron(pZ, Z[i]) H[i] = np.kron(pHad, H[i]) P0[i] = np.kron(pP0, P0[i]) P1[i] = np.kron(pP1, P1[i]) Ide = np.eye(2**nqubits) #2量子ゲートの準備 CZ = [[0 for i in range(nqubits)] for j in range(nqubits)] CX = [[0 for i in range(nqubits)] for j in range(nqubits)] for i in range(nqubits): for j in range(nqubits): CZ[i][j] = (P0[i] + np.dot(P1[i], Z[j])) CX[i][j] = (P0[i] + np.dot(P1[i], X[j])) #変分量子ゲートの準備 def iSWAP(target1, target2, angle): return expm(-0.5 * angle * 1.j * CX[target1][target2]) def iCPHASE(target1, target2, angle): return expm(-0.5 * angle * 1.j * CZ[target1][target2]) def RX(target, angle): return expm(-0.5 * angle * 1.j * X[target]) def RY(target, angle): return expm(-0.5 * angle * 1.j * Y[target]) def RZ(target, angle): return expm(-0.5 * angle * 1.j * Z[target]) #初期状態の準備 def StateZeros(nqubits): State = np.zeros(2**nqubits) State[9] = 1 return State #求めるハミルトニアンのデータ geometry = [["H", [0, 0, 0]], ["H", [0, 0, bond_length]]] basis = "sto-3g" multiplicity = 1 charge = 0 description = "test" #str() molecule = MolecularData(geometry, basis, multiplicity, charge, description) #求めるハミルトニアンのJW変換 molecule = run_psi4(molecule) jw_hamiltonian = jordan_wigner( get_fermion_operator(molecule.get_molecular_hamiltonian())) jw_matrix = get_sparse_operator(jw_hamiltonian) #量子回路 n_param = 12 def QubitPQC(phi): state = StateZeros(4) state = np.dot(iSWAP(0, 1, phi[0]), state) state = np.dot(iCPHASE(0, 1, phi[1]), state) state = np.dot(iSWAP(2, 3, phi[2]), state) state = np.dot(iCPHASE(2, 3, phi[3]), state) state = np.dot(iSWAP(1, 2, phi[4]), state) state = np.dot(iCPHASE(1, 2, phi[5]), state) state = np.dot(iSWAP(0, 1, phi[6]), state) state = np.dot(iCPHASE(0, 1, phi[7]), state) state = np.dot(iSWAP(2, 3, phi[8]), state) state = np.dot(iCPHASE(2, 3, phi[9]), state) state = np.dot(iSWAP(1, 2, phi[10]), state) state = np.dot(iCPHASE(1, 2, phi[11]), state) return state #エネルギーの期待値を求める関数 def ExpectVal(Operator, State): BraState = np.conjugate(State.T) #列ベクトルを行ベクトルへ変換 tmp = BraState.dot(Operator.dot(State)) #行列を列ベクトルと行ベクトルではさむ return np.real(tmp) #要素の実部を取り出す #VQEの実行 def cost(phi): return ExpectVal(jw_matrix, QubitPQC(phi)) init = np.random.rand(n_param) res = scipy.optimize.minimize(cost, init, method='Powell') molecule = run_psi4(molecule, run_scf=1, run_fci=1) eigenenergies, eigenvecs = eigs(jw_matrix) return cost(res.x)
def load_molecule(self, geometry=None, basis=None, multiplicity=None, charge=None, forceCalculation=False): ''' ARGS: Necessary: None Optional: geometry - Geometry of the molecule in the OpenFermion/Psi4 syntax basis - a string defining the chosen basis multiplicity - integer charge - integer forceCalculation - a boolean (preset to false) that will force the run_psi4 method when set to True instead of loading the saved integral calculations RETURNS: None This function is designed to handle the generation of a molecule primarily using the MolecularData.load() method of OpenFerimon. For this method to work properly, integral calculations must be made prior through the use of psi4 (and pyscf in later versions). The MolecularData object is then stored under the self.molecule parameter of this class. ''' self.set_parameters(geometry, basis, multiplicity, charge) self.check_parameters() # Generate and populate instance of MolecularData data structure if (self.description != ''): molecule = MolecularData(self.geometry, self.basis, self.multiplicity, self.charge, self.description) else: molecule = MolecularData(self.geometry, self.basis, self.multiplicity, self.charge) # Determine if integrals have been previously generated or not if (not (os.path.exists(molecule.filename + '.hdf5')) or (forceCalculation)): # Note, because of OpenFerimon and Psi4, a different molecular # geometry will not cause recalculation of the molecular integrals # on its own. Therefore, forceCalculation can be used. if (self.plugin == 'psi4'): # Run Psi4 calculation protocol run_scf, run_mp2, run_cisd, run_ccsd, run_fci = 1, 0, 0, 0, 0 molecule = run_psi4(molecule, run_scf=run_scf, run_mp2=run_mp2, run_cisd=run_cisd, run_ccsd=run_ccsd, run_fci=run_fci) else: # Run PySCF calculation protocol sys.exit('''\n\n --- OpenFermionWrapper Error ---\n Only Psi4 compatability is implemented''') # Save molecule for future, so that regeneration is not required molecule.save() molecule.load() else: molecule.load() self.molecule = molecule