Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
287 views
ubuntu2404
1
#!/usr/bin/env python3
2
"""
3
Quantum Mechanics Simulations for Computational Physics
4
========================================================
5
6
This module contains implementations of fundamental quantum mechanics simulations:
7
- Time-dependent Schrödinger equation solver
8
- Quantum harmonic oscillator eigenstates
9
- Particle in a box solutions
10
- Quantum tunneling demonstrations
11
12
Keywords: quantum mechanics python, schrodinger equation solver, quantum harmonic oscillator,
13
particle in a box simulation, quantum tunneling python code
14
15
Author: CoCalc Scientific Templates
16
License: MIT
17
"""
18
19
import numpy as np
20
import matplotlib.pyplot as plt
21
from scipy.sparse import diags
22
from scipy.linalg import expm
23
from scipy.special import hermite, factorial
24
25
# Set reproducible random seed
26
np.random.seed(42)
27
28
class SchrodingerSolver:
29
"""
30
Time-dependent Schrödinger equation solver using finite difference method.
31
32
Solves: iℏ ∂ψ/∂t = Ĥ ψ where Ĥ = T̂ + V̂
33
"""
34
35
def __init__(self, L=10.0, N=1000, hbar=1.0, m=1.0):
36
"""
37
Initialize the solver.
38
39
Parameters:
40
-----------
41
L : float
42
Length of simulation box
43
N : int
44
Number of grid points
45
hbar : float
46
Reduced Planck constant (natural units)
47
m : float
48
Particle mass (natural units)
49
"""
50
self.L = L
51
self.N = N
52
self.hbar = hbar
53
self.m = m
54
self.dx = L / N
55
self.x = np.linspace(0, L, N)
56
57
# Kinetic energy operator (finite difference)
58
kinetic_diag = -2 * np.ones(N)
59
kinetic_off = np.ones(N-1)
60
self.T_matrix = -(hbar**2 / (2*m*self.dx**2)) * (
61
diags([kinetic_off, kinetic_diag, kinetic_off], [-1, 0, 1], shape=(N, N))
62
)
63
64
def set_potential(self, V):
65
"""Set the potential energy function V(x)."""
66
self.V = V
67
self.H = self.T_matrix + diags(V, 0)
68
69
def gaussian_wavepacket(self, x0, sigma, k0):
70
"""
71
Create a Gaussian wave packet initial condition.
72
73
Parameters:
74
-----------
75
x0 : float
76
Initial position
77
sigma : float
78
Wave packet width
79
k0 : float
80
Initial momentum
81
"""
82
psi = np.exp(-(self.x - x0)**2 / (2*sigma**2)) * np.exp(1j * k0 * self.x)
83
return psi / np.sqrt(np.trapezoid(np.abs(psi)**2, self.x))
84
85
def evolve(self, psi_initial, dt, t_final):
86
"""
87
Time evolution using matrix exponentiation.
88
89
Returns:
90
--------
91
times : array
92
Time points
93
psi_evolution : list
94
Wavefunction at each time step
95
"""
96
times = np.arange(0, t_final, dt)
97
U = expm(-1j * self.H.toarray() * dt / self.hbar)
98
99
psi = psi_initial.copy()
100
psi_evolution = [psi.copy()]
101
102
for t in times[1:]:
103
psi = U @ psi
104
psi_evolution.append(psi.copy())
105
106
return times, psi_evolution
107
108
class HarmonicOscillator:
109
"""
110
Quantum harmonic oscillator analytical solutions.
111
112
Energy eigenvalues: E_n = ℏω(n + 1/2)
113
Wavefunctions: ψ_n(x) = N_n * exp(-ξ²/2) * H_n(ξ)
114
where ξ = x/x₀ and x₀ = √(ℏ/mω)
115
"""
116
117
def __init__(self, omega=1.0, m=1.0, hbar=1.0):
118
"""
119
Parameters:
120
-----------
121
omega : float
122
Angular frequency
123
m : float
124
Mass
125
hbar : float
126
Reduced Planck constant
127
"""
128
self.omega = omega
129
self.m = m
130
self.hbar = hbar
131
self.x0 = np.sqrt(hbar / (m * omega)) # Length scale
132
133
def energy_level(self, n):
134
"""Energy eigenvalue for quantum number n."""
135
return self.hbar * self.omega * (n + 0.5)
136
137
def wavefunction(self, x, n):
138
"""
139
Harmonic oscillator wavefunction for quantum number n.
140
141
Parameters:
142
-----------
143
x : array
144
Position grid
145
n : int
146
Quantum number
147
"""
148
# Normalization factor
149
norm = 1.0 / np.sqrt(2**n * factorial(n)) * (self.m*self.omega/(np.pi*self.hbar))**(1/4)
150
151
# Dimensionless coordinate
152
xi = x / self.x0
153
154
# Hermite polynomial
155
H_n = hermite(n)
156
157
# Wavefunction
158
psi_n = norm * np.exp(-xi**2 / 2) * H_n(xi)
159
return psi_n
160
161
def calculate_eigenstates(self, x_range, n_max=5):
162
"""
163
Calculate first n_max energy eigenstates.
164
165
Returns:
166
--------
167
x : array
168
Position grid
169
energies : list
170
Energy eigenvalues
171
wavefunctions : list
172
Corresponding wavefunctions
173
"""
174
x = np.linspace(-x_range, x_range, 1000)
175
176
energies = []
177
wavefunctions = []
178
179
for n in range(n_max):
180
E_n = self.energy_level(n)
181
psi_n = self.wavefunction(x, n)
182
183
energies.append(E_n)
184
wavefunctions.append(psi_n)
185
186
return x, energies, wavefunctions
187
188
class ParticleInBox:
189
"""
190
Infinite square well (particle in a box) exact solutions.
191
192
Energy eigenvalues: E_n = n²π²ℏ²/(2mL²)
193
Wavefunctions: ψ_n(x) = √(2/L) * sin(nπx/L)
194
"""
195
196
def __init__(self, L=1.0, m=1.0, hbar=1.0):
197
"""
198
Parameters:
199
-----------
200
L : float
201
Box length
202
m : float
203
Particle mass
204
hbar : float
205
Reduced Planck constant
206
"""
207
self.L = L
208
self.m = m
209
self.hbar = hbar
210
211
def energy_level(self, n):
212
"""Energy eigenvalue for quantum number n (n ≥ 1)."""
213
return (n**2 * np.pi**2 * self.hbar**2) / (2 * self.m * self.L**2)
214
215
def wavefunction(self, x, n):
216
"""
217
Particle in box wavefunction for quantum number n.
218
219
Parameters:
220
-----------
221
x : array
222
Position grid (0 ≤ x ≤ L)
223
n : int
224
Quantum number (n ≥ 1)
225
"""
226
return np.sqrt(2/self.L) * np.sin(n * np.pi * x / self.L)
227
228
def superposition_state(self, x, coefficients, quantum_numbers):
229
"""
230
Create superposition of energy eigenstates.
231
232
ψ(x) = Σ c_n ψ_n(x)
233
234
Parameters:
235
-----------
236
x : array
237
Position grid
238
coefficients : array
239
Complex amplitudes
240
quantum_numbers : array
241
Corresponding quantum numbers
242
"""
243
psi = np.zeros_like(x, dtype=complex)
244
245
for c, n in zip(coefficients, quantum_numbers):
246
psi += c * self.wavefunction(x, n)
247
248
return psi
249
250
def calculate_eigenstates(self, n_max=5):
251
"""
252
Calculate first n_max energy eigenstates.
253
254
Returns:
255
--------
256
x : array
257
Position grid
258
energies : list
259
Energy eigenvalues
260
wavefunctions : list
261
Corresponding wavefunctions
262
"""
263
x = np.linspace(0, self.L, 1000)
264
265
energies = []
266
wavefunctions = []
267
268
for n in range(1, n_max + 1):
269
E_n = self.energy_level(n)
270
psi_n = self.wavefunction(x, n)
271
272
energies.append(E_n)
273
wavefunctions.append(psi_n)
274
275
return x, energies, wavefunctions
276
277
def demo_quantum_tunneling():
278
"""
279
Demonstrate quantum tunneling through a potential barrier.
280
"""
281
print("=== Quantum Tunneling Demo ===")
282
283
# Setup solver
284
solver = SchrodingerSolver(L=10.0, N=1000)
285
286
# Define potential: harmonic well + Gaussian barrier
287
omega = 1.0
288
V = 0.5 * solver.m * omega**2 * (solver.x - solver.L/2)**2
289
V += 2.0 * np.exp(-((solver.x - solver.L/3)/(solver.L/20))**2)
290
291
solver.set_potential(V)
292
293
# Initial Gaussian wave packet
294
psi_initial = solver.gaussian_wavepacket(x0=solver.L/4, sigma=solver.L/20, k0=5.0)
295
296
# Time evolution
297
times, psi_evolution = solver.evolve(psi_initial, dt=0.001, t_final=5.0)
298
299
print(f"Simulation completed: {len(times)} time steps")
300
print(f"Final norm: {np.trapezoid(np.abs(psi_evolution[-1])**2, solver.x):.6f}")
301
302
return solver.x, V, times, psi_evolution
303
304
def demo_harmonic_oscillator():
305
"""
306
Demonstrate quantum harmonic oscillator eigenstates.
307
"""
308
print("=== Harmonic Oscillator Demo ===")
309
310
oscillator = HarmonicOscillator(omega=1.0, m=1.0, hbar=1.0)
311
x, energies, wavefunctions = oscillator.calculate_eigenstates(x_range=4*oscillator.x0, n_max=6)
312
313
print(f"Calculated {len(energies)} eigenstates")
314
print(f"Energy levels (in units of ℏω): {[E/oscillator.hbar/oscillator.omega for E in energies[:4]]}")
315
316
return x, energies, wavefunctions, oscillator
317
318
def demo_particle_in_box():
319
"""
320
Demonstrate particle in a box solutions.
321
"""
322
print("=== Particle in Box Demo ===")
323
324
box = ParticleInBox(L=1.0, m=1.0, hbar=1.0)
325
x, energies, wavefunctions = box.calculate_eigenstates(n_max=5)
326
327
# Create superposition state
328
coefficients = [1/np.sqrt(2), 1/np.sqrt(2)]
329
quantum_numbers = [1, 2]
330
psi_superposition = box.superposition_state(x, coefficients, quantum_numbers)
331
332
print(f"Calculated {len(energies)} eigenstates")
333
print(f"Energy ratios E_n/E_1: {[E/energies[0] for E in energies]}")
334
335
return x, energies, wavefunctions, psi_superposition
336
337
if __name__ == "__main__":
338
# Run demonstrations
339
demo_quantum_tunneling()
340
demo_harmonic_oscillator()
341
demo_particle_in_box()
342