64 lines
2.1 KiB
Python
64 lines
2.1 KiB
Python
import datetime
|
|
from time import sleep, time
|
|
from pennylane import numpy as np
|
|
import pennylane as qml
|
|
import os
|
|
from multiprocessing import Process, Queue
|
|
os.environ["OMP_NUM_THREADS"] = '16'
|
|
|
|
|
|
def run_vqe(q: Queue, symbols, coordinates, active_electrons, active_orbitals, max_iterations, conv_tol, step_size):
|
|
molecule = qml.qchem.Molecule(symbols, coordinates, load_data=True)
|
|
H, qubits = qml.qchem.molecular_hamiltonian(molecule, active_electrons=active_electrons,
|
|
active_orbitals=active_orbitals)
|
|
dev = qml.device("lightning.qubit", wires=qubits)
|
|
|
|
|
|
|
|
singles, doubles = qml.qchem.excitations(active_electrons, qubits)
|
|
params = np.array(np.zeros(len(singles) + len(doubles)), requires_grad=True)
|
|
@qml.qnode(dev)
|
|
def circuit(param, wires):
|
|
# Map excitations to the wires the UCCSD circuit will act on
|
|
s_wires, d_wires = qml.qchem.excitations_to_wires(singles, doubles)
|
|
qml.UCCSD(param, wires, s_wires=s_wires, d_wires=d_wires, init_state=qml.qchem.hf_state(active_electrons, qubits))
|
|
return qml.expval(H)
|
|
|
|
def cost_fn(param):
|
|
return circuit(param, wires=range(qubits))
|
|
|
|
opt = qml.GradientDescentOptimizer(stepsize=step_size)
|
|
|
|
for n in range(max_iterations):
|
|
# Take step
|
|
params, prev_energy = opt.step_and_cost(cost_fn, params)
|
|
|
|
energy = cost_fn(params)
|
|
|
|
# Calculate difference between new and old energies
|
|
conv = np.abs(energy - prev_energy)
|
|
|
|
q.put([n, energy,params])
|
|
|
|
if conv <= conv_tol:
|
|
break
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
symbols, coordinates = qml.qchem.read_structure("methane.xyz")
|
|
active_electrons=2
|
|
active_orbitals=2
|
|
max_iterations = 500
|
|
conv_tol = 1e-04
|
|
step_size = 0.05
|
|
q = Queue()
|
|
p = Process(target=run_vqe, args=(q, symbols, coordinates, active_electrons, active_orbitals, max_iterations, conv_tol, step_size))
|
|
p.start()
|
|
while p.is_alive():
|
|
try:
|
|
print(q.get_nowait(), datetime.datetime.now())
|
|
except Exception as e:
|
|
print("no_data_to_get", e)
|
|
sleep(0.1) |