Nonlinear Dynamics and Solitons¶
da PowerShell -- jupyter nbconvert --to html notebook.ipynb
Esercizio del libro - statico¶
Utilizzo della soluzione analitica della equazione Korteweg-de Vries (KdV)¶
In [16]:
import numpy as np
from scipy.integrate import solve_ivp
def nonlinear_wave_equation(phi, x, t, c, f):
'''
Nonlinear wave equation.
:param phi: Scalar field.
:param x: Spatial domain.
:param t: Time.
:param c: Wave speed.
:param f: Nonlinear interaction function.
:return:
Wave equation in terms of phi.
'''
return np.gradient(np.gradient(phi, t), t) - c**2 * np.gradient(np.gradient(phi, x), x) + f(phi)
def hamiltonian_density(phi, phi_t, c, V):
'''
Hamiltonian density calculation.
:param phi: Scalar field.
:param phi_t: Time derivative of phi.
:param c: Wave speed.
:param V: External potential V(x) as array.
:return:
Hamiltonian density.
'''
def hamiltonian_density_a(phi, phi_t, c):
dphi_dx = np.gradient(phi, x)
return (
0.5 * phi_t**2
+ 0.5 * c**2 * dphi_dx**2
+ potential_energy(phi)
)
def potential_energy(phi):
'''
Potential energy density function V.
:param phi: Scalar field.
:return:
Potential energy density.
'''
# Example: V(phi) = phi ^4
return phi**4
def soliton_solution(x, t, A, v, x0):
'''
Soliton solution for the KdV equation.
:param x: Spatial coordinate.
:param t: Time.
:param A: Amplitude.
:param v: Velocity.
:param xO: Initial position.
:return:
Solitary wave profile.
'''
return A * np.cosh(np.sqrt(A)/2 * (x - v * t - x0))**-2
def symplectic_integrator(phi, phi_t, dt, steps):
dx = x[1] - x[0]
for _ in range(steps):
# half step for phi
phi += 0.5 * dt * phi_t
# force = - δH / δphi
laplacian = np.gradient(np.gradient(phi, x), x)
force = c**2 * laplacian - 4 * phi**3
# full step for momentum
phi_t += dt * force
# second half step
phi += 0.5 * dt * phi_t
return phi, phi_t
# ---- Dominio e parametri ----
steps = 1000
x = np.linspace(-15, 15, steps)
c = 1.0
v = 0.7
# ---- Stato iniziale: solitone gaussiano piccolo ----
A = 0.1 # ampiezza
sigma = 0.2 # larghezza
phi_init = A * np.exp(-(x / sigma)**2)
phi_t = -v * np.gradient(phi_init, x)
dt = 0.01
phi_evolved, phi_t_evolved = symplectic_integrator(
phi_init.copy(),
phi_t.copy(),
dt,
steps
)
import matplotlib.pyplot as plt
plt.figure(figsize=(8, 4))
plt.ylim([-0.2, 0.2])
plt.plot(x, phi_init, label="φ iniziale", linestyle="--")
plt.plot(x, phi_evolved, label="φ finale")
plt.xlabel("x")
plt.ylabel("φ(x)")
plt.title("Evoluzione della forma d'onda")
plt.legend()
plt.grid(True)
plt.show()
Animazione dinamica da chatGPT¶
In [6]:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
from IPython.display import HTML
%matplotlib inline
# ---- Dominio e parametri ----
x = np.linspace(-7, 7, 400)
c = 1.0
v = 0.01
dt = 0.02
steps = 300
# ---- Stato iniziale: solitone gaussiano piccolo ----
A = 0.1 # ampiezza
sigma = 0.2 # larghezza
phi = A * np.exp(-(x / sigma)**2)
phi_t = -v * np.gradient(phi, x)
# ---- Funzione evolutiva simplettica ----
def step(phi, phi_t):
lap = np.gradient(np.gradient(phi, x), x)
force = c**2 * lap - 4 * phi**3
phi_t = phi_t + dt * force
phi = phi + dt * phi_t
return phi, phi_t
# ---- Setup figura ----
fig, ax = plt.subplots(figsize=(6, 3))
line, = ax.plot(x, phi, lw=2)
ax.set_ylim(-0.2, 0.2) # <- ridotto per evidenziare piccole oscillazioni
ax.set_xlabel("x")
ax.set_ylabel("φ(x)")
ax.set_title("Solitone piccolo in movimento")
# ---- Funzione di aggiornamento ----
def update(frame):
global phi, phi_t
phi, phi_t = step(phi, phi_t)
line.set_ydata(phi)
return line,
# ---- Animazione ----
ani = FuncAnimation(fig, update, frames=steps, interval=30)
HTML(ani.to_jshtml())
Out[6]:
In [ ]: