VIATEUR-AI commited on
Commit
7c5acc4
·
verified ·
1 Parent(s): 96b3b62

# ===== Ultimate Quantum Chemistry Platform (Starter) ===== # Python 3.11 + Qiskit stable + Gradio + Plotly import numpy as np import plotly.graph_objects as go import gradio as gr from qiskit_nature.second_q.drivers import PySCFDriver from qiskit_nature.second_q.problems import ElectronicStructureProblem from qiskit_nature.second_q.mappers import JordanWignerMapper from qiskit.algorithms.minimum_eigensolvers import VQE from qiskit.algorithms.optimizers import COBYLA from qiskit.circuit.library import TwoLocal from qiskit.primitives import Estimator # stable Qiskit 1.12 # ---------------------------- # Molecules Library # ---------------------------- molecules = { "H2": {"atoms": ["H", "H"], "coords": [(0,0,0), (0,0,0.74)]}, "LiH": {"atoms": ["Li", "H"], "coords": [(0,0,0), (0,0,1.6)]}, "BeH2": {"atoms": ["Be","H","H"], "coords": [(0,0,0), (0,0,1.3), (0,0,-1.3)]} } # ---------------------------- # Quantum ground state energy # ---------------------------- def compute_ground_state_energy(mol_name, bond_length): bond_length = float(bond_length) if mol_name == "H2": atom_str = f"H 0 0 0; H 0 0 {bond_length}" elif mol_name == "LiH": atom_str = f"Li 0 0 0; H 0 0 {bond_length}" elif mol_name == "BeH2": # symmetrically along z-axis atom_str = f"Be 0 0 0; H 0 0 {bond_length}; H 0 0 {-bond_length}" else: raise ValueError("Molecule not supported") driver = PySCFDriver(atom=atom_str, basis="sto3g") problem = ElectronicStructureProblem(driver) hamiltonian = problem.second_q_ops()[0] qubit_op = JordanWignerMapper().map(hamiltonian) ansatz = TwoLocal(qubit_op.num_qubits, "ry", "cz", reps=2) vqe = VQE(estimator=Estimator(), ansatz=ansatz, optimizer=COBYLA(maxiter=80)) result = vqe.compute_minimum_eigenvalue(qubit_op) energy = result.eigenvalue.real return energy # ---------------------------- # 3D molecule plot # ---------------------------- def molecule_3d_plot(mol_name, bond_length): bond_length = float(bond_length) if mol_name == "H2": coords = [(0,0,0),(0,0,bond_length)] elif mol_name == "LiH": coords = [(0,0,0),(0,0,bond_length)] elif mol_name == "BeH2": coords = [(0,0,0),(0,0,bond_length),(0,0,-bond_length)] else: coords = [] x, y, z = zip(*coords) fig = go.Figure() fig.add_trace(go.Scatter3d( x=x, y=y, z=z, mode="markers", marker=dict(size=8, color="red") )) fig.add_trace(go.Scatter3d( x=x, y=y, z=z, mode="lines", line=dict(color="blue", width=5) )) fig.update_layout(scene=dict(aspectmode="data")) return fig # ---------------------------- # Energy curve precompute (for 0.4 - 2.0 Å) # ---------------------------- bond_grid = np.linspace(0.4, 2.0, 12) energy_curves = {} for mol in molecules: energy_curves[mol] = [compute_ground_state_energy(mol, bl) for bl in bond_grid] # ---------------------------- # Update UI # ---------------------------- def update_ui(mol_name, bond_length): bond_length = float(bond_length) energy = compute_ground_state_energy(mol_name, bond_length) mol_fig = molecule_3d_plot(mol_name, bond_length) curve_fig = go.Figure() curve_fig.add_trace(go.Scatter( x=bond_grid, y=energy_curves[mol_name], mode="lines+markers", name="Energy Curve" )) curve_fig.add_trace(go.Scatter( x=[bond_length], y=[energy], mode="markers", marker=dict(size=12, color="green"), name="Current Energy" )) min_idx = int(np.argmin(energy_curves[mol_name])) curve_fig.add_trace(go.Scatter( x=[bond_grid[min_idx]], y=[energy_curves[mol_name][min_idx]], mode="markers", marker=dict(size=14, color="orange"), name="Equilibrium" )) curve_fig.update_layout( xaxis_title="Bond Length (Å)", yaxis_title="Energy (Hartree)" ) text = f"Ground state energy: {energy:.6f} Hartree\nEquilibrium bond length ≈ {bond_grid[min_idx]:.2f} Å" return text, mol_fig, curve_fig # ---------------------------- # Gradio App # ---------------------------- with gr.Blocks() as demo: gr.Markdown("# 🧬 Ultimate Quantum Chemistry Platform") mol_dropdown = gr.Dropdown(list(molecules.keys()), value="H2", label="Select Molecule") bond_slider = gr.Slider(0.4, 2.0, value=0.74, step=0.01, label="Bond Length (Å)") energy_box = gr.Textbox(label="Energy", lines=2) mol_plot = gr.Plot(label="3D Molecule") curve_plot = gr.Plot(label="Energy Curve") mol_dropdown.change(update_ui, [mol_dropdown, bond_slider], [energy_box, mol_plot, curve_plot]) bond_slider.change(update_ui, [mol_dropdown, bond_slider], [energy_box, mol_plot, curve_plot]) demo.launch()

Browse files
Files changed (1) hide show
  1. app.py +99 -130
app.py CHANGED
@@ -1,172 +1,141 @@
1
- # ===== app.py =====
2
- # Full interactive H2 Quantum Simulator + 3D molecule (modern Qiskit)
3
-
4
- # --- Standard math ---
5
  import numpy as np
6
-
7
- # --- Graphing & UI ---
8
  import plotly.graph_objects as go
9
  import gradio as gr
10
 
11
- # --- Qiskit Nature (modern second_q API) ---
12
  from qiskit_nature.second_q.drivers import PySCFDriver
13
  from qiskit_nature.second_q.problems import ElectronicStructureProblem
14
  from qiskit_nature.second_q.mappers import JordanWignerMapper
15
-
16
- # --- Qiskit Algorithms (modern primitives API) ---
17
- from qiskit_algorithms.minimum_eigensolvers import VQE
18
- from qiskit_algorithms.optimizers import COBYLA
19
  from qiskit.circuit.library import TwoLocal
20
- from qiskit.primitives import Estimator
21
 
 
 
 
 
 
 
 
 
22
 
23
  # ----------------------------
24
- # Compute H2 ground state energy using VQE
25
  # ----------------------------
26
- def h2_ground_state_energy(bond_length):
27
  bond_length = float(bond_length)
28
-
29
- # Electronic structure driver
30
- driver = PySCFDriver(
31
- atom=f"H 0 0 0; H 0 0 {bond_length}",
32
- basis="sto3g"
33
- )
34
-
 
 
 
 
 
35
  problem = ElectronicStructureProblem(driver)
36
-
37
- # Get second-quantized Hamiltonian
38
- second_q_ops = problem.second_q_ops()
39
- hamiltonian = second_q_ops[0]
40
-
41
- # Map fermions -> qubits
42
- mapper = JordanWignerMapper()
43
- qubit_op = mapper.map(hamiltonian)
44
-
45
- # Ansatz
46
- ansatz = TwoLocal(
47
- num_qubits=qubit_op.num_qubits,
48
- rotation_blocks="ry",
49
- entanglement_blocks="cz",
50
- reps=2
51
- )
52
-
53
- # Optimizer + estimator
54
- optimizer = COBYLA(maxiter=100)
55
- estimator = Estimator()
56
-
57
- # VQE
58
- vqe = VQE(
59
- estimator=estimator,
60
- ansatz=ansatz,
61
- optimizer=optimizer
62
- )
63
-
64
  result = vqe.compute_minimum_eigenvalue(qubit_op)
65
- return result.eigenvalue.real
66
-
67
 
68
  # ----------------------------
69
- # Create 3D molecule plot
70
  # ----------------------------
71
- def h2_3d_plot(bond_length):
72
  bond_length = float(bond_length)
73
-
74
- x = [0, 0]
75
- y = [0, 0]
76
- z = [0, bond_length]
77
-
 
 
 
 
 
78
  fig = go.Figure()
79
-
80
- # Atoms
81
  fig.add_trace(go.Scatter3d(
82
  x=x, y=y, z=z,
83
  mode="markers",
84
- marker=dict(size=10, color="red"),
85
- name="Hydrogen atoms"
86
  ))
87
-
88
- # Bond
89
  fig.add_trace(go.Scatter3d(
90
  x=x, y=y, z=z,
91
  mode="lines",
92
- line=dict(color="blue", width=5),
93
- name="Bond"
94
  ))
95
-
96
- fig.update_layout(
97
- scene=dict(
98
- xaxis_title="X (Å)",
99
- yaxis_title="Y (Å)",
100
- zaxis_title="Z (Å)",
101
- aspectmode="data"
102
- ),
103
- margin=dict(l=0, r=0, b=0, t=0)
104
- )
105
-
106
  return fig
107
 
108
-
109
  # ----------------------------
110
- # Generate energy curve over bond lengths
111
  # ----------------------------
112
- def h2_energy_curve(dummy):
113
- bond_lengths = np.linspace(0.4, 2.0, 10)
114
- energies = [h2_ground_state_energy(bl) for bl in bond_lengths]
 
115
 
116
- fig = go.Figure()
117
- fig.add_trace(go.Scatter(
118
- x=bond_lengths,
119
- y=energies,
120
- mode="lines+markers"
 
 
 
 
 
 
 
 
121
  ))
122
-
123
- fig.update_layout(
124
- title="H₂ Ground State Energy vs Bond Length",
 
 
 
 
 
 
 
 
 
 
 
125
  xaxis_title="Bond Length (Å)",
126
  yaxis_title="Energy (Hartree)"
127
  )
128
-
129
- return fig
130
-
131
 
132
  # ----------------------------
133
- # Full interface: single bond length + 3D molecule
134
  # ----------------------------
135
- def full_interface(bond_length):
136
- bond_length = float(bond_length)
137
- energy = h2_ground_state_energy(bond_length)
138
- mol_fig = h2_3d_plot(bond_length)
139
-
140
- return f"Ground state energy: {energy:.6f} Hartree", mol_fig
141
-
142
-
143
- # --- Gradio interfaces ---
144
- iface = gr.Interface(
145
- fn=full_interface,
146
- inputs=gr.Textbox(
147
- label="Bond Length (Å)",
148
- placeholder="Enter e.g. 0.74"
149
- ),
150
- outputs=[
151
- gr.Textbox(label="Ground State Energy"),
152
- gr.Plot(label="3D Molecule")
153
- ],
154
- title="H₂ Quantum Simulator",
155
- description="Interactive VQE simulation + 3D visualization of the H₂ molecule."
156
- )
157
-
158
- energy_curve_iface = gr.Interface(
159
- fn=h2_energy_curve,
160
- inputs=gr.Textbox(label="Dummy Input", placeholder="Press submit"),
161
- outputs=gr.Plot(label="Energy Curve"),
162
- title="H₂ Energy Curve",
163
- description="Ground state energy of H₂ for bond lengths 0.4–2.0 Å."
164
- )
165
-
166
- demo = gr.TabbedInterface(
167
- [iface, energy_curve_iface],
168
- ["Single Bond Length", "Energy Curve"]
169
- )
170
 
171
- # Launch app
172
  demo.launch()
 
1
+ # ===== Ultimate Quantum Chemistry Platform (Starter) =====
2
+ # Python 3.11 + Qiskit stable + Gradio + Plotly
 
 
3
  import numpy as np
 
 
4
  import plotly.graph_objects as go
5
  import gradio as gr
6
 
 
7
  from qiskit_nature.second_q.drivers import PySCFDriver
8
  from qiskit_nature.second_q.problems import ElectronicStructureProblem
9
  from qiskit_nature.second_q.mappers import JordanWignerMapper
10
+ from qiskit.algorithms.minimum_eigensolvers import VQE
11
+ from qiskit.algorithms.optimizers import COBYLA
 
 
12
  from qiskit.circuit.library import TwoLocal
13
+ from qiskit.primitives import Estimator # stable Qiskit 1.12
14
 
15
+ # ----------------------------
16
+ # Molecules Library
17
+ # ----------------------------
18
+ molecules = {
19
+ "H2": {"atoms": ["H", "H"], "coords": [(0,0,0), (0,0,0.74)]},
20
+ "LiH": {"atoms": ["Li", "H"], "coords": [(0,0,0), (0,0,1.6)]},
21
+ "BeH2": {"atoms": ["Be","H","H"], "coords": [(0,0,0), (0,0,1.3), (0,0,-1.3)]}
22
+ }
23
 
24
  # ----------------------------
25
+ # Quantum ground state energy
26
  # ----------------------------
27
+ def compute_ground_state_energy(mol_name, bond_length):
28
  bond_length = float(bond_length)
29
+
30
+ if mol_name == "H2":
31
+ atom_str = f"H 0 0 0; H 0 0 {bond_length}"
32
+ elif mol_name == "LiH":
33
+ atom_str = f"Li 0 0 0; H 0 0 {bond_length}"
34
+ elif mol_name == "BeH2":
35
+ # symmetrically along z-axis
36
+ atom_str = f"Be 0 0 0; H 0 0 {bond_length}; H 0 0 {-bond_length}"
37
+ else:
38
+ raise ValueError("Molecule not supported")
39
+
40
+ driver = PySCFDriver(atom=atom_str, basis="sto3g")
41
  problem = ElectronicStructureProblem(driver)
42
+ hamiltonian = problem.second_q_ops()[0]
43
+
44
+ qubit_op = JordanWignerMapper().map(hamiltonian)
45
+
46
+ ansatz = TwoLocal(qubit_op.num_qubits, "ry", "cz", reps=2)
47
+ vqe = VQE(estimator=Estimator(), ansatz=ansatz, optimizer=COBYLA(maxiter=80))
48
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
49
  result = vqe.compute_minimum_eigenvalue(qubit_op)
50
+ energy = result.eigenvalue.real
51
+ return energy
52
 
53
  # ----------------------------
54
+ # 3D molecule plot
55
  # ----------------------------
56
+ def molecule_3d_plot(mol_name, bond_length):
57
  bond_length = float(bond_length)
58
+ if mol_name == "H2":
59
+ coords = [(0,0,0),(0,0,bond_length)]
60
+ elif mol_name == "LiH":
61
+ coords = [(0,0,0),(0,0,bond_length)]
62
+ elif mol_name == "BeH2":
63
+ coords = [(0,0,0),(0,0,bond_length),(0,0,-bond_length)]
64
+ else:
65
+ coords = []
66
+
67
+ x, y, z = zip(*coords)
68
  fig = go.Figure()
 
 
69
  fig.add_trace(go.Scatter3d(
70
  x=x, y=y, z=z,
71
  mode="markers",
72
+ marker=dict(size=8, color="red")
 
73
  ))
 
 
74
  fig.add_trace(go.Scatter3d(
75
  x=x, y=y, z=z,
76
  mode="lines",
77
+ line=dict(color="blue", width=5)
 
78
  ))
79
+ fig.update_layout(scene=dict(aspectmode="data"))
 
 
 
 
 
 
 
 
 
 
80
  return fig
81
 
 
82
  # ----------------------------
83
+ # Energy curve precompute (for 0.4 - 2.0 Å)
84
  # ----------------------------
85
+ bond_grid = np.linspace(0.4, 2.0, 12)
86
+ energy_curves = {}
87
+ for mol in molecules:
88
+ energy_curves[mol] = [compute_ground_state_energy(mol, bl) for bl in bond_grid]
89
 
90
+ # ----------------------------
91
+ # Update UI
92
+ # ----------------------------
93
+ def update_ui(mol_name, bond_length):
94
+ bond_length = float(bond_length)
95
+ energy = compute_ground_state_energy(mol_name, bond_length)
96
+ mol_fig = molecule_3d_plot(mol_name, bond_length)
97
+
98
+ curve_fig = go.Figure()
99
+ curve_fig.add_trace(go.Scatter(
100
+ x=bond_grid, y=energy_curves[mol_name],
101
+ mode="lines+markers",
102
+ name="Energy Curve"
103
  ))
104
+ curve_fig.add_trace(go.Scatter(
105
+ x=[bond_length], y=[energy],
106
+ mode="markers",
107
+ marker=dict(size=12, color="green"),
108
+ name="Current Energy"
109
+ ))
110
+ min_idx = int(np.argmin(energy_curves[mol_name]))
111
+ curve_fig.add_trace(go.Scatter(
112
+ x=[bond_grid[min_idx]], y=[energy_curves[mol_name][min_idx]],
113
+ mode="markers",
114
+ marker=dict(size=14, color="orange"),
115
+ name="Equilibrium"
116
+ ))
117
+ curve_fig.update_layout(
118
  xaxis_title="Bond Length (Å)",
119
  yaxis_title="Energy (Hartree)"
120
  )
121
+
122
+ text = f"Ground state energy: {energy:.6f} Hartree\nEquilibrium bond length ≈ {bond_grid[min_idx]:.2f} Å"
123
+ return text, mol_fig, curve_fig
124
 
125
  # ----------------------------
126
+ # Gradio App
127
  # ----------------------------
128
+ with gr.Blocks() as demo:
129
+ gr.Markdown("# 🧬 Ultimate Quantum Chemistry Platform")
130
+
131
+ mol_dropdown = gr.Dropdown(list(molecules.keys()), value="H2", label="Select Molecule")
132
+ bond_slider = gr.Slider(0.4, 2.0, value=0.74, step=0.01, label="Bond Length (Å)")
133
+
134
+ energy_box = gr.Textbox(label="Energy", lines=2)
135
+ mol_plot = gr.Plot(label="3D Molecule")
136
+ curve_plot = gr.Plot(label="Energy Curve")
137
+
138
+ mol_dropdown.change(update_ui, [mol_dropdown, bond_slider], [energy_box, mol_plot, curve_plot])
139
+ bond_slider.change(update_ui, [mol_dropdown, bond_slider], [energy_box, mol_plot, curve_plot])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
140
 
 
141
  demo.launch()