Help to find higher energy states of molecules

In this tutorial energy value of LiH , H2 is calculated . For this calculation molecule geometry is given there. If I want to run this for other materials like Be2, Be3 or B2 or others . Where can i get these geometry values of other molecules. Is there any data set for this?

Hey @Kaushik!

You’re in luck :sunglasses:. PennyLane has a datasets module: Quantum Data - PennyLane. There, you can find all sorts of molecular datasets. If there’s a molecule that PennyLane doesn’t have a dataset for, odds are you can get quick numbers from NIST (e.g., here: CCCBDB Experimental Geometry Data). Here’s the data for Be2: https://cccbdb.nist.gov/expgeom2x.asp

Let me know if that helps!

2 Likes

Here I am facing some problems. When I am running this program for Be2 it is showing different energy each time .

Hey @Kaushik,

This could be due to a few things, but it’s hard to say without seeing what code you’re running (if you could attach a minimal example that would be lovely). My guess is that you’re randomly initializing your ansatz parameters. Each time you run your code, your parameters are different, which will have a huge impact on the final result :slight_smile:. You can get around this by setting a random seed.

Let me know if this helps!

from pennylane import numpy as np
import networkx as nx
import matplotlib.pyplot as plt
from math import pi

import pennylane as qml
from pennylane.templates import RandomLayers
#from pennylane.init import random_layers_uniform # modified - commented
from pennylane import broadcast
from pennylane import expval, var, device

symbols = ["Be", "Be"]
coordinates = np.array([0.0, 0.0, -1.230, 0.0, 0.0, 1.230])

h, qubits =  qml.qchem.molecular_hamiltonian(
        symbols,
        coordinates,
        charge=0,
        mult=1,
        basis='sto-3g',
        active_electrons=2,
        active_orbitals=2
)

print("Number of qubits = ", qubits)
print("The Hamiltonian is ", h)



energies = np.zeros(2)


# Get the number of qubits in the Hamiltonian
num_qubits = len(h.wires)

# Initialize the device
dev = qml.device('default.qubit', wires=num_qubits)


# Ansatz
def ansatz(params, wires, state_idx=0):
    # Need to prepare a different orthogonal state each time
    qml.PauliX(wires=wires[state_idx])
    qml.templates.StronglyEntanglingLayers(params, wires=wires)
    
#single_cost = qml.ExpvalCost(ansatz, h, dev) # modified - commented

# modified - added
@qml.qnode(dev)
def single_cost(params, state_idx=0):
  ansatz(params,wires=range(num_qubits),state_idx=state_idx)
  return qml.expval(h)

w = np.arange(num_qubits, 0, -1)


# The full cost - computes single_cost for each starting state
def total_cost(params):
    cost = 0
    for state_idx in range(num_qubits):
        cost += w[state_idx] * single_cost(params, state_idx=state_idx)
    return cost


# Set up a cost function and optimizer, and run the SSVQE
opt = qml.AdamOptimizer(stepsize=0.05)
max_iterations = 20 # modified from 200
costs = []

# Initial parameters for the ansatz
num_layers = 8
params = np.random.uniform(low=0, high=2*np.pi, size=(num_layers, num_qubits, 3))


# Optimize!
H2_callback_energies = []
H2_callback_energies_single_0 = []
H2_callback_energies_single_1 = []

for _ in range(max_iterations):
    params, prev_energy = opt.step_and_cost(total_cost, params)
    energy = total_cost(params)
    energy_ground_state = single_cost(params, state_idx=0)
    energy_first_excited_state = single_cost(params, state_idx=1)
    H2_callback_energies_single_0.append(energy_ground_state)
    H2_callback_energies_single_1.append(energy_first_excited_state)
    H2_callback_energies.append(energy)
    
    
    
# After optimization, get the energies for the original starting states
for state_idx in range(2):
    energies[state_idx] = single_cost(params, state_idx=state_idx)
    
    
energies = ",".join([str(E) for E in energies])


energies

This is the code I am using and I am getting various energy each time i run it

Hey @Kaushik,

Indeed it’s the lack of a random seed. If you’re looking for the same result every time, you can do the following:

np.random.seed(1234)
params = np.random.uniform(low=0, high=2*np.pi, size=(num_layers, num_qubits, 3))

You can change the integer 1234 to something different and get different results :slight_smile:. If you want more information on how random seeds work, the wikipedia entry isn’t all that bad (quick read as well): Random seed - Wikipedia.

But, I’d say it’s not necessary to dig deep into this if you’re just after a deterministic result from your code :slight_smile:

Where can i find the number of active electrons and number of active orbitals and how to know if I use active space how much orbitals will take part in simulation?

Hi @Kaushik ,

The number of active electrons will depend on the molecule. For example the H2 molecule contains two hydrogen atoms with one electron each. The H3+ molecule contains only two electrons which are being shared amongst the three hydrogen atoms in the molecule, which is why this molecule has a charge. For some molecules that have many electrons many of them won’t really move (they will stay in the core orbitals). So by specifying the active electrons you can reduce the size of the computation to only those electrons that are likely to affect the properties of the molecule. Check out the docs for molecular_hamiltonian to see a nice picture of what core, active, and external orbitals mean.

If you’re using a molecule from one of our quantum datasets you can click on the “Configure” button to see the number of spin orbitals. I hope this helps!

1 Like

If I want to simulate the molecule on real hardware instead of local device, how should i change the code of SSVQE?

Hi @Kaushik ,

The answer depends on the type of device you want to use. Which one do you want to use?

May be some ibm machines or Amazon bracket.

If you’re using IBM machines you need to pip install pennylane-qiskit. Make sure you’re also using the latest PennyLane version with pip install pennylane --upgrade.

You can find the documentation for the pennylane-qiskit plugin here.

You can use the template below to run a simple example on their hardware. You can then modify it to run your SSVQE code.

Important note: IBM only gives you 10min of free use of their hardware. I STRONGLY recommend that you start by simulating your code on a 'qiskit.aer' simulator first. You will need to get the IBM API token from the IBM quantum website. NEVER share this token publicly.

import warnings
warnings.filterwarnings('ignore')

# Add your IBM API token here
# token = 

# Import the library that you need in order to use your IBM account
import qiskit_ibm_provider

# Import your favourite libraries
import pennylane as qml
import datetime as dt

# Get your IBM provider
try:
    provider = qiskit_ibm_provider.IBMProvider()
except:
    provider = qiskit_ibm_provider.IBMProvider.save_account(token=token, overwrite=True)

print(provider.backends())

# Define the backend that you will run on
b = "ibm_sherbrooke"

# Create your device
dev = qml.device(
    "qiskit.ibmq",
    wires=2,
    backend=b,
    shots = 1,
    ibmqx_token=token
)
#dev = qml.device('qiskit.aer', wires=2)

# Activate the device resource tracker
dev.tracker.active = True

# Create your qnode
@qml.qnode(dev)
def circuit():
    qml.Hadamard(wires=0)
    return qml.expval(qml.PauliZ(0))

# Run your circuit
circuit()

# Retrieve your current job
job = dev._current_job

# Print the summary of job time per step
print('Summary: \n',dev.tracker.history)

For AWS Braket you can follow one of our demos on Amazon Braket Hybrid Jobs, Computing adjoint gradients with Amazon Braket SV1, and Computing gradients in parallel with Amazon Braket.

You will need to pip install amazon-braket-pennylane-plugin. You can find the documentation for the plugin here.

Important note: when using Amazon Braket you MUST turn off the instances of the devices you’re using, otherwise your credit card will keep being charged. Please follow their instructions carefully to avoid paying for QPU time that you’re not actually using.

Alternatively you can also try using qBraid. You can buy credits to use different types of Hardware. You can write your program in PennyLane and then dispatch to a specific backend. You’ll need to go through their docs to figure out how to do this.

There are many other hardware providers and options, these are just some popular ones.

Final important note: not everything works on all hardware. Some functions, gates, setups, etc. only work on simulators. I don’t see anything obvious that wouldn’t work in the SSVQE code but it is possible that some functions will fail so it’s good to be aware of it.

1 Like