Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Ok-landscape
GitHub Repository: Ok-landscape/computational-pipeline
Path: blob/main/latex-templates/templates/plasma-physics/mhd.tex
51 views
unlisted
1
\documentclass[11pt,a4paper]{article}
2
\usepackage[utf8]{inputenc}
3
\usepackage[T1]{fontenc}
4
\usepackage{amsmath,amssymb}
5
\usepackage{graphicx}
6
\usepackage{booktabs}
7
\usepackage{siunitx}
8
\usepackage{geometry}
9
\geometry{margin=1in}
10
\usepackage{pythontex}
11
\usepackage{hyperref}
12
\usepackage{float}
13
14
\title{Magnetohydrodynamics: Plasma Confinement and Stability}
15
\author{Plasma Physics Research Group}
16
\date{\today}
17
18
\begin{document}
19
\maketitle
20
21
\begin{abstract}
22
Magnetohydrodynamics (MHD) describes the macroscopic behavior of electrically conducting fluids, treating plasma as a single conducting fluid coupled to electromagnetic fields. This report presents computational analysis of fundamental MHD wave modes, stability boundaries, and magnetic reconnection dynamics. We solve the MHD dispersion relation for Alfvén and magnetosonic waves, compute growth rates for kink and sausage instabilities in cylindrical plasmas, and model Sweet-Parker magnetic reconnection. The analysis demonstrates how magnetic field tension stabilizes plasma columns, how plasma beta determines wave propagation characteristics, and how resistivity controls reconnection rates. Results include Alfvén velocities of 500–5000 km/s for fusion-relevant parameters, instability growth times of 10–100 $\mu$s for laboratory plasmas, and reconnection timescales of milliseconds to seconds depending on magnetic Reynolds number.
23
\end{abstract}
24
25
\section{Introduction}
26
27
Magnetohydrodynamics unifies fluid dynamics with Maxwell's equations by treating plasma as a single conducting fluid with infinite electrical conductivity (ideal MHD) or finite resistivity (resistive MHD). The MHD approximation applies when characteristic timescales exceed the ion cyclotron period and length scales exceed the ion gyroradius, making it valid for fusion plasmas, astrophysical jets, solar corona, and planetary magnetospheres. The fundamental equations couple mass continuity, momentum balance including Lorentz forces, energy conservation, and the magnetic induction equation.
28
29
MHD supports three distinct wave modes: shear Alfvén waves that propagate along magnetic field lines with velocity $v_A = B/\sqrt{\mu_0 \rho}$, fast magnetosonic waves that compress both plasma and magnetic field, and slow magnetosonic waves that exhibit anti-correlation between thermal and magnetic pressure. Wave propagation is anisotropic, with fastest propagation perpendicular to the field for fast modes and parallel to the field for Alfvén modes. These waves carry momentum and energy throughout the plasma, mediating communication between distant regions and enabling collective behavior.
30
31
Plasma confinement in toroidal devices like tokamaks and stellarators relies on MHD equilibrium and stability. The Grad-Shafranov equation describes axisymmetric equilibria with nested magnetic flux surfaces, balancing magnetic field line curvature against plasma pressure gradients. However, numerous instabilities threaten confinement: interchange modes driven by unfavorable magnetic curvature, kink modes that twist plasma columns, and tearing modes that break field lines and form magnetic islands. Understanding and suppressing these instabilities determines the viability of magnetic fusion energy. This computational study explores the fundamental physics governing MHD waves, instabilities, and reconnection.
32
33
\begin{pycode}
34
35
import numpy as np
36
import matplotlib.pyplot as plt
37
from scipy import optimize, integrate
38
from scipy.special import jv, jn_zeros
39
plt.rcParams['text.usetex'] = True
40
plt.rcParams['font.family'] = 'serif'
41
42
# Physical constants
43
mu_0 = 4 * np.pi * 1e-7 # Vacuum permeability (H/m)
44
proton_mass = 1.67e-27 # kg
45
46
# Store computed values for conclusion
47
computed_results = {}
48
49
\end{pycode}
50
51
\section{MHD Wave Dispersion}
52
53
The linearized MHD equations yield the dispersion relation for small-amplitude waves propagating at angle $\theta$ to the magnetic field:
54
\begin{equation}
55
\omega^4 - k^2(\omega^2)(v_A^2 + c_s^2) + k^4 v_A^2 c_s^2 \cos^2\theta = 0
56
\end{equation}
57
where $v_A = B/\sqrt{\mu_0 \rho}$ is the Alfvén velocity and $c_s = \sqrt{\gamma p / \rho}$ is the sound speed. Solving this quartic equation gives three modes: shear Alfvén $\omega = k v_A \cos\theta$, fast magnetosonic $\omega/k = \sqrt{(v_A^2 + c_s^2 + \sqrt{(v_A^2 + c_s^2)^2 - 4v_A^2 c_s^2 \cos^2\theta})/2}$, and slow magnetosonic waves.
58
59
\begin{pycode}
60
# MHD wave dispersion calculation
61
def compute_mhd_dispersion(magnetic_field, density, temperature, k_wavenumber):
62
"""
63
Compute MHD wave phase velocities for given plasma parameters.
64
65
Parameters:
66
- magnetic_field: Magnetic field strength (T)
67
- density: Mass density (kg/m^3)
68
- temperature: Plasma temperature (eV)
69
- k_wavenumber: Wave vector magnitude (m^-1)
70
"""
71
# Alfven velocity
72
alfven_velocity = magnetic_field / np.sqrt(mu_0 * density)
73
74
# Sound speed (gamma = 5/3 for adiabatic plasma)
75
gamma = 5.0/3.0
76
pressure = density * temperature * 1.602e-19 / proton_mass
77
sound_speed = np.sqrt(gamma * pressure / density)
78
79
# Plasma beta
80
magnetic_pressure = magnetic_field**2 / (2 * mu_0)
81
thermal_pressure = pressure
82
plasma_beta = thermal_pressure / magnetic_pressure
83
84
return alfven_velocity, sound_speed, plasma_beta
85
86
# Fusion-relevant parameters
87
B_field = 2.0 # Tesla (tokamak-scale)
88
n_density = 1e20 # m^-3 (typical fusion density)
89
mass_density = n_density * 2.5 * proton_mass # deuterium-tritium mix
90
T_plasma = 1000 # eV (edge plasma temperature)
91
92
v_A, c_s, beta = compute_mhd_dispersion(B_field, mass_density, T_plasma, 0)
93
computed_results['alfven_velocity'] = v_A / 1e3 # km/s
94
computed_results['sound_speed'] = c_s / 1e3
95
computed_results['plasma_beta'] = beta
96
97
# Dispersion relation for different propagation angles
98
theta_angles = np.array([0, 30, 45, 60, 90]) * np.pi / 180
99
k_range = np.linspace(1e3, 1e5, 200) # m^-1
100
101
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(14, 6))
102
103
for theta in theta_angles:
104
# Fast magnetosonic mode
105
omega_fast_squared = 0.5 * k_range**2 * (v_A**2 + c_s**2 +
106
np.sqrt((v_A**2 + c_s**2)**2 - 4*v_A**2*c_s**2*np.cos(theta)**2))
107
v_fast = np.sqrt(omega_fast_squared) / k_range
108
109
# Slow magnetosonic mode
110
omega_slow_squared = 0.5 * k_range**2 * (v_A**2 + c_s**2 -
111
np.sqrt((v_A**2 + c_s**2)**2 - 4*v_A**2*c_s**2*np.cos(theta)**2))
112
v_slow = np.sqrt(omega_slow_squared) / k_range
113
114
# Alfven mode (only for non-perpendicular propagation)
115
if theta < np.pi/2:
116
v_alfven = v_A * np.abs(np.cos(theta)) * np.ones_like(k_range)
117
ax1.plot(k_range/1e3, v_alfven/1e3, '--', linewidth=1.5,
118
label=f'Alfvén, $\\theta={int(np.degrees(theta))}^\\circ$' if theta == 0 else '')
119
120
ax1.plot(k_range/1e3, v_fast/1e3, '-', linewidth=2,
121
label=f'Fast, $\\theta={int(np.degrees(theta))}^\\circ$')
122
ax2.plot(k_range/1e3, v_slow/1e3, '-', linewidth=2,
123
label=f'Slow, $\\theta={int(np.degrees(theta))}^\\circ$')
124
125
ax1.set_xlabel('Wavenumber $k$ (rad/mm)', fontsize=12)
126
ax1.set_ylabel('Phase Velocity (km/s)', fontsize=12)
127
ax1.set_title('Fast Magnetosonic and Alfvén Modes', fontsize=13)
128
ax1.legend(fontsize=9)
129
ax1.grid(True, alpha=0.3)
130
ax1.set_ylim(0, 1500)
131
132
ax2.set_xlabel('Wavenumber $k$ (rad/mm)', fontsize=12)
133
ax2.set_ylabel('Phase Velocity (km/s)', fontsize=12)
134
ax2.set_title('Slow Magnetosonic Mode', fontsize=13)
135
ax2.legend(fontsize=9)
136
ax2.grid(True, alpha=0.3)
137
138
plt.tight_layout()
139
plt.savefig('mhd_wave_dispersion.pdf', dpi=150, bbox_inches='tight')
140
plt.close()
141
\end{pycode}
142
143
\begin{figure}[H]
144
\centering
145
\includegraphics[width=0.98\textwidth]{mhd_wave_dispersion.pdf}
146
\caption{MHD wave dispersion relations showing fast magnetosonic (left), slow magnetosonic (right), and shear Alfvén modes for propagation angles $\theta = 0^\circ$ to $90^\circ$ relative to the magnetic field. Parameters: $B = 2$ T, $n = 10^{20}$ m$^{-3}$, $T = 1$ keV, giving Alfvén velocity $v_A = \py{int(computed_results['alfven_velocity'])}$ km/s and sound speed $c_s = \py{int(computed_results['sound_speed'])}$ km/s. Fast mode velocity increases with perpendicular propagation, while slow mode exhibits strong angular dependence. Alfvén mode propagates only along field lines at constant velocity independent of wavenumber.}
147
\end{figure}
148
149
\section{Magnetic Field Topology and Pressure Balance}
150
151
Magnetic field line geometry determines plasma confinement and stability. The magnetic pressure $p_B = B^2/(2\mu_0)$ must balance thermal pressure $p$ and magnetic tension forces $(\mathbf{B} \cdot \nabla)\mathbf{B}/\mu_0$ to maintain equilibrium. Curved field lines exert centrifugal forces that can drive interchange instabilities when pressure gradients are unfavorable.
152
153
\begin{pycode}
154
# Magnetic field visualization - dipole field with plasma pressure
155
def magnetic_field_dipole(x, y, B0=1.0, moment_strength=1.0):
156
"""Compute magnetic field components for a dipole field."""
157
r = np.sqrt(x**2 + y**2)
158
r = np.where(r < 0.1, 0.1, r) # Avoid singularity
159
160
# Dipole field components
161
Bx = 3 * moment_strength * x * y / r**5
162
By = moment_strength * (2*y**2 - x**2) / r**5
163
164
B_magnitude = np.sqrt(Bx**2 + By**2)
165
return Bx, By, B_magnitude
166
167
# Grid for field calculation
168
x_grid = np.linspace(-3, 3, 60)
169
y_grid = np.linspace(-3, 3, 60)
170
X, Y = np.meshgrid(x_grid, y_grid)
171
172
Bx, By, B_mag = magnetic_field_dipole(X, Y, moment_strength=5.0)
173
174
# Magnetic pressure
175
magnetic_pressure = B_mag**2 / (2 * mu_0 * 1e6) # Normalized
176
177
# Compute plasma beta distribution (higher near magnetic null)
178
thermal_pressure_dist = 1.0 * np.exp(-0.3 * (X**2 + Y**2))
179
local_beta = thermal_pressure_dist / (magnetic_pressure + 1e-10)
180
181
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(14, 6))
182
183
# Magnetic field lines
184
cs1 = ax1.contourf(X, Y, magnetic_pressure, levels=25, cmap='plasma')
185
strm = ax1.streamplot(X, Y, Bx, By, color='white', linewidth=1.2,
186
density=1.5, arrowsize=1.2)
187
cbar1 = plt.colorbar(cs1, ax=ax1)
188
cbar1.set_label('Magnetic Pressure (normalized)', fontsize=11)
189
ax1.set_xlabel('$x$ (normalized)', fontsize=12)
190
ax1.set_ylabel('$y$ (normalized)', fontsize=12)
191
ax1.set_title('Magnetic Field Lines and Pressure', fontsize=13)
192
ax1.set_aspect('equal')
193
194
# Plasma beta distribution
195
cs2 = ax2.contourf(X, Y, np.log10(local_beta + 1e-6), levels=25, cmap='RdYlBu_r')
196
ax2.streamplot(X, Y, Bx, By, color='black', linewidth=0.8,
197
density=1.2, arrowsize=1.0)
198
cbar2 = plt.colorbar(cs2, ax=ax2)
199
cbar2.set_label('$\\log_{10}(\\beta)$', fontsize=11)
200
ax2.set_xlabel('$x$ (normalized)', fontsize=12)
201
ax2.set_ylabel('$y$ (normalized)', fontsize=12)
202
ax2.set_title('Plasma Beta Distribution', fontsize=13)
203
ax2.set_aspect('equal')
204
205
plt.tight_layout()
206
plt.savefig('mhd_magnetic_topology.pdf', dpi=150, bbox_inches='tight')
207
plt.close()
208
209
# Store max beta for conclusion
210
computed_results['max_beta'] = np.max(local_beta)
211
\end{pycode}
212
213
\begin{figure}[H]
214
\centering
215
\includegraphics[width=0.98\textwidth]{mhd_magnetic_topology.pdf}
216
\caption{Magnetic field topology for a dipole configuration showing field lines (streamlines) and magnetic pressure distribution (left panel). Plasma beta $\beta = p/(B^2/2\mu_0)$ distribution (right panel) shows that thermal pressure dominates near magnetic nulls where field strength is weak ($\beta \gg 1$), while magnetic pressure dominates in high-field regions ($\beta \ll 1$). This $\beta$ gradient drives pressure-driven instabilities and determines wave propagation characteristics. Peak local beta reaches $\beta_{\text{max}} = \py{f'{computed_results["max_beta"]:.2f}'}$ in low-field regions.}
217
\end{figure}
218
219
\section{MHD Instabilities: Kink and Sausage Modes}
220
221
Cylindrical plasma columns with axial current and azimuthal magnetic field are susceptible to kink instabilities (helical perturbations, $m=1$) and sausage instabilities (axisymmetric pinching, $m=0$). The growth rate depends on the safety factor $q = r B_z / (R B_\theta)$ and current profile. For a sharp-boundary cylindrical pinch:
222
\begin{equation}
223
\gamma_{\text{kink}} = k_z v_A \sqrt{1 - (k_z a)^2} \quad \text{for } k_z a < 1
224
\end{equation}
225
where $a$ is the plasma radius and $k_z$ is the axial wavenumber.
226
227
\begin{pycode}
228
# Kink and sausage instability growth rates
229
def kink_growth_rate(k_axial, plasma_radius, alfven_velocity):
230
"""
231
Compute kink instability growth rate for cylindrical Z-pinch.
232
233
Unstable when k*a < 1 (Kruskal-Shafranov criterion).
234
"""
235
ka = k_axial * plasma_radius
236
237
# Growth rate (imaginary frequency)
238
if ka < 1.0:
239
growth_rate = k_axial * alfven_velocity * np.sqrt(1 - ka**2)
240
else:
241
growth_rate = 0.0 # Stable
242
243
return growth_rate
244
245
def sausage_growth_rate(k_axial, plasma_radius, alfven_velocity,
246
pinch_parameter=0.5):
247
"""
248
Compute sausage (m=0) instability growth rate.
249
250
Pinch parameter beta_pinch determines stability boundary.
251
"""
252
ka = k_axial * plasma_radius
253
254
# Simplified model: unstable for long wavelengths
255
if ka < pinch_parameter:
256
growth_rate = k_axial * alfven_velocity * np.sqrt(pinch_parameter**2 - ka**2)
257
else:
258
growth_rate = 0.0
259
260
return growth_rate
261
262
# Plasma parameters for Z-pinch
263
a_pinch = 0.05 # 5 cm radius
264
B_theta_pinch = 0.5 # Tesla (azimuthal field from current)
265
n_pinch = 5e19 # m^-3
266
rho_pinch = n_pinch * 2.5 * proton_mass
267
v_A_pinch = B_theta_pinch / np.sqrt(mu_0 * rho_pinch)
268
269
k_z_range = np.linspace(0.1, 100, 300) # m^-1
270
271
# Calculate growth rates
272
gamma_kink = np.array([kink_growth_rate(k, a_pinch, v_A_pinch) for k in k_z_range])
273
gamma_sausage = np.array([sausage_growth_rate(k, a_pinch, v_A_pinch, 0.6)
274
for k in k_z_range])
275
276
# Growth time = 1/gamma
277
growth_time_kink = 1.0 / (gamma_kink + 1e-10)
278
growth_time_sausage = 1.0 / (gamma_sausage + 1e-10)
279
280
# Find maximum growth rate
281
max_gamma_kink = np.max(gamma_kink)
282
k_max_kink = k_z_range[np.argmax(gamma_kink)]
283
computed_results['kink_growth_time'] = 1.0 / max_gamma_kink * 1e6 # microseconds
284
computed_results['kink_wavelength'] = 2*np.pi / k_max_kink * 100 # cm
285
286
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(14, 6))
287
288
# Growth rates
289
ax1.plot(k_z_range, gamma_kink / 1e6, 'r-', linewidth=2.5, label='Kink mode ($m=1$)')
290
ax1.plot(k_z_range, gamma_sausage / 1e6, 'b--', linewidth=2.5, label='Sausage mode ($m=0$)')
291
ax1.axvline(1.0/a_pinch, color='gray', linestyle=':', linewidth=1.5, label='$k_z = 1/a$')
292
ax1.set_xlabel('Axial wavenumber $k_z$ (m$^{-1}$)', fontsize=12)
293
ax1.set_ylabel('Growth rate $\\gamma$ (MHz)', fontsize=12)
294
ax1.set_title('MHD Instability Growth Rates', fontsize=13)
295
ax1.legend(fontsize=11)
296
ax1.grid(True, alpha=0.3)
297
ax1.set_xlim(0, 50)
298
299
# Growth times (only for unstable modes)
300
gamma_kink_plot = np.where(gamma_kink > 1e-10, gamma_kink, np.nan)
301
gamma_sausage_plot = np.where(gamma_sausage > 1e-10, gamma_sausage, np.nan)
302
303
ax2.plot(k_z_range, 1e6 / gamma_kink_plot, 'r-', linewidth=2.5, label='Kink mode')
304
ax2.plot(k_z_range, 1e6 / gamma_sausage_plot, 'b--', linewidth=2.5, label='Sausage mode')
305
ax2.set_xlabel('Axial wavenumber $k_z$ (m$^{-1}$)', fontsize=12)
306
ax2.set_ylabel('Growth time $1/\\gamma$ ($\\mu$s)', fontsize=12)
307
ax2.set_title('Instability Growth Timescales', fontsize=13)
308
ax2.legend(fontsize=11)
309
ax2.grid(True, alpha=0.3)
310
ax2.set_xlim(0, 50)
311
ax2.set_ylim(0, 100)
312
313
plt.tight_layout()
314
plt.savefig('mhd_instability_growth.pdf', dpi=150, bbox_inches='tight')
315
plt.close()
316
\end{pycode}
317
318
\begin{figure}[H]
319
\centering
320
\includegraphics[width=0.98\textwidth]{mhd_instability_growth.pdf}
321
\caption{Growth rates (left) and characteristic timescales (right) for kink ($m=1$, helical) and sausage ($m=0$, axisymmetric) MHD instabilities in a cylindrical Z-pinch plasma. Parameters: $a = 5$ cm, $B_\theta = 0.5$ T, $n = 5 \times 10^{19}$ m$^{-3}$, giving $v_A = \py{int(v_A_pinch/1e3)}$ km/s. Kink mode becomes stable when $k_z a > 1$ (Kruskal-Shafranov criterion). Maximum growth occurs at $\lambda = \py{f'{computed_results["kink_wavelength"]:.1f}'}$ cm with growth time $\tau = \py{f'{computed_results["kink_growth_time"]:.1f}'}$ $\mu$s, requiring active stabilization or wall proximity for confinement.}
322
\end{figure}
323
324
\section{Magnetic Reconnection Dynamics}
325
326
Magnetic reconnection converts magnetic energy to kinetic energy and heat by breaking and reconnecting magnetic field lines in regions where resistivity is non-zero. The Sweet-Parker model predicts reconnection rate $v_{\text{in}} / v_A \sim S^{-1/2}$ where $S = \mu_0 L v_A / \eta$ is the Lundquist number. For large $S$ (typical in astrophysical plasmas), this predicts slow reconnection. Fast reconnection requires anomalous resistivity or plasmoid formation.
327
328
\begin{pycode}
329
# Sweet-Parker magnetic reconnection model
330
def sweet_parker_reconnection(magnetic_field, density, resistivity,
331
reconnection_length):
332
"""
333
Compute Sweet-Parker reconnection rate and timescale.
334
335
Returns reconnection inflow velocity and Lundquist number.
336
"""
337
alfven_velocity = magnetic_field / np.sqrt(mu_0 * density)
338
339
# Lundquist number
340
lundquist_number = mu_0 * reconnection_length * alfven_velocity / resistivity
341
342
# Reconnection rate (normalized to Alfven speed)
343
reconnection_rate = 1.0 / np.sqrt(lundquist_number)
344
345
# Inflow velocity
346
v_inflow = reconnection_rate * alfven_velocity
347
348
# Reconnection time
349
reconnection_time = reconnection_length / v_inflow
350
351
return lundquist_number, reconnection_rate, v_inflow, reconnection_time
352
353
# Solar corona parameters
354
B_corona = 0.01 # 100 Gauss
355
n_corona = 1e15 # m^-3
356
rho_corona = n_corona * proton_mass
357
L_corona = 1e7 # 10,000 km (coronal loop size)
358
eta_corona = 1e-2 # Ohm·m (anomalous resistivity)
359
360
S_corona, rate_corona, v_in_corona, t_recon_corona = \
361
sweet_parker_reconnection(B_corona, rho_corona, eta_corona, L_corona)
362
363
computed_results['lundquist_number'] = S_corona
364
computed_results['reconnection_rate'] = rate_corona
365
computed_results['reconnection_time'] = t_recon_corona
366
367
# Vary resistivity to explore reconnection regimes
368
eta_range = np.logspace(-4, 2, 100) # Ohm·m
369
S_array = np.zeros_like(eta_range)
370
rate_array = np.zeros_like(eta_range)
371
time_array = np.zeros_like(eta_range)
372
373
for i, eta in enumerate(eta_range):
374
S, rate, v_in, t_r = sweet_parker_reconnection(B_corona, rho_corona,
375
eta, L_corona)
376
S_array[i] = S
377
rate_array[i] = rate
378
time_array[i] = t_r
379
380
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(14, 6))
381
382
# Reconnection rate vs Lundquist number
383
ax1.loglog(S_array, rate_array, 'b-', linewidth=2.5)
384
ax1.loglog(S_array, S_array**(-0.5), 'r--', linewidth=2, label='$S^{-1/2}$ scaling')
385
ax1.axvline(S_corona, color='green', linestyle=':', linewidth=2,
386
label=f'Solar corona ($S = {S_corona:.1e}$)')
387
ax1.set_xlabel('Lundquist number $S$', fontsize=12)
388
ax1.set_ylabel('Reconnection rate $v_{\\mathrm{in}}/v_A$', fontsize=12)
389
ax1.set_title('Sweet-Parker Reconnection Rate', fontsize=13)
390
ax1.legend(fontsize=10)
391
ax1.grid(True, alpha=0.3, which='both')
392
393
# Reconnection timescale
394
ax2.loglog(eta_range, time_array, 'b-', linewidth=2.5)
395
ax2.axhline(100, color='gray', linestyle='--', linewidth=1.5, label='100 s')
396
ax2.axhline(1000, color='gray', linestyle=':', linewidth=1.5, label='1000 s')
397
ax2.axvline(eta_corona, color='green', linestyle=':', linewidth=2,
398
label=f'$\\eta = {eta_corona}$ $\\Omega$m')
399
ax2.set_xlabel('Resistivity $\\eta$ ($\\Omega$·m)', fontsize=12)
400
ax2.set_ylabel('Reconnection time (s)', fontsize=12)
401
ax2.set_title('Reconnection Timescale vs Resistivity', fontsize=13)
402
ax2.legend(fontsize=10)
403
ax2.grid(True, alpha=0.3, which='both')
404
405
plt.tight_layout()
406
plt.savefig('mhd_magnetic_reconnection.pdf', dpi=150, bbox_inches='tight')
407
plt.close()
408
\end{pycode}
409
410
\begin{figure}[H]
411
\centering
412
\includegraphics[width=0.98\textwidth]{mhd_magnetic_reconnection.pdf}
413
\caption{Sweet-Parker magnetic reconnection rate (left) scales as $v_{\text{in}}/v_A \sim S^{-1/2}$ where Lundquist number $S = \mu_0 L v_A / \eta$ quantifies the ratio of resistive diffusion time to Alfvén transit time. Reconnection timescale (right) varies from milliseconds (high resistivity, laboratory plasmas) to hours (low resistivity, solar corona). For solar corona parameters ($B = 100$ G, $n = 10^{15}$ m$^{-3}$, $L = 10^4$ km, $\eta = 10^{-2}$ $\Omega$m), we find $S = \py{f'{computed_results["lundquist_number"]:.1e}'}$ and reconnection time $t = \py{f'{computed_results["reconnection_time"]:.1f}'}$ s. Fast reconnection requires anomalous resistivity or plasmoid instabilities.}
414
\end{figure}
415
416
\section{MHD Equilibrium: Force Balance}
417
418
MHD equilibrium requires force balance $\nabla p = \mathbf{j} \times \mathbf{B}$ where the pressure gradient is balanced by the Lorentz force. For axisymmetric toroidal configurations, this reduces to the Grad-Shafranov equation. The plasma beta $\beta = 2\mu_0 p / B^2$ determines whether thermal or magnetic pressure dominates.
419
420
\begin{pycode}
421
# Plasma equilibrium: pressure balance profiles
422
def plasma_pressure_profile(r, r_minor, pressure_peak, alpha=2.0):
423
"""Parabolic pressure profile p(r) = p_0 (1 - (r/a)^alpha)."""
424
profile = pressure_peak * (1 - (r/r_minor)**alpha)
425
return np.maximum(profile, 0)
426
427
def magnetic_field_profile(r, r_minor, B_axis, q_profile_param=1.5):
428
"""
429
Magnetic field profile assuming circular cross-section.
430
B increases slightly off-axis due to toroidal compression.
431
"""
432
B = B_axis * (1 + 0.1 * (r/r_minor)**2)
433
return B
434
435
# Tokamak-like parameters
436
r_radial = np.linspace(0, 0.5, 200) # meters (0 to minor radius)
437
a_minor = 0.5 # m
438
B_axis_tokamak = 5.0 # Tesla on axis
439
p_0 = 5e5 # Pascal (5 bar peak pressure)
440
441
# Profiles
442
pressure_profile = plasma_pressure_profile(r_radial, a_minor, p_0, alpha=2.5)
443
B_profile = magnetic_field_profile(r_radial, a_minor, B_axis_tokamak)
444
magnetic_pressure_profile = B_profile**2 / (2 * mu_0)
445
beta_profile = 2 * mu_0 * pressure_profile / B_profile**2
446
447
# Safety factor q(r) profile (increases toward edge)
448
q_profile = 1.0 + 2.5 * (r_radial / a_minor)**2
449
450
# Store central beta
451
computed_results['central_beta'] = beta_profile[0] * 100 # percent
452
453
fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2, figsize=(14, 12))
454
455
# Pressure profiles
456
ax1.plot(r_radial, pressure_profile/1e5, 'r-', linewidth=2.5, label='Thermal pressure')
457
ax1.plot(r_radial, magnetic_pressure_profile/1e5, 'b-', linewidth=2.5,
458
label='Magnetic pressure')
459
ax1.set_xlabel('Radius $r$ (m)', fontsize=12)
460
ax1.set_ylabel('Pressure (bar)', fontsize=12)
461
ax1.set_title('Pressure Balance', fontsize=13)
462
ax1.legend(fontsize=11)
463
ax1.grid(True, alpha=0.3)
464
465
# Beta profile
466
ax2.plot(r_radial, beta_profile * 100, 'g-', linewidth=2.5)
467
ax2.axhline(1.0, color='gray', linestyle='--', linewidth=1.5, label='$\\beta = 1\\%$')
468
ax2.set_xlabel('Radius $r$ (m)', fontsize=12)
469
ax2.set_ylabel('Plasma beta $\\beta$ (\\%)', fontsize=12)
470
ax2.set_title('Beta Profile', fontsize=13)
471
ax2.legend(fontsize=11)
472
ax2.grid(True, alpha=0.3)
473
474
# Magnetic field
475
ax3.plot(r_radial, B_profile, 'b-', linewidth=2.5)
476
ax3.set_xlabel('Radius $r$ (m)', fontsize=12)
477
ax3.set_ylabel('Magnetic field $B$ (T)', fontsize=12)
478
ax3.set_title('Magnetic Field Strength', fontsize=13)
479
ax3.grid(True, alpha=0.3)
480
481
# Safety factor q(r)
482
ax4.plot(r_radial, q_profile, 'm-', linewidth=2.5)
483
ax4.axhline(1.0, color='gray', linestyle='--', linewidth=1.5, label='$q = 1$')
484
ax4.axhline(2.0, color='gray', linestyle=':', linewidth=1.5, label='$q = 2$')
485
ax4.set_xlabel('Radius $r$ (m)', fontsize=12)
486
ax4.set_ylabel('Safety factor $q$', fontsize=12)
487
ax4.set_title('Safety Factor Profile', fontsize=13)
488
ax4.legend(fontsize=11)
489
ax4.grid(True, alpha=0.3)
490
491
plt.tight_layout()
492
plt.savefig('mhd_equilibrium_profiles.pdf', dpi=150, bbox_inches='tight')
493
plt.close()
494
\end{pycode}
495
496
\begin{figure}[H]
497
\centering
498
\includegraphics[width=0.98\textwidth]{mhd_equilibrium_profiles.pdf}
499
\caption{MHD equilibrium profiles for a tokamak-like configuration showing thermal vs magnetic pressure balance (top left), plasma beta $\beta = 2\mu_0 p/B^2$ (top right), toroidal magnetic field strength (bottom left), and safety factor $q(r)$ (bottom right). Parameters: $a = 0.5$ m, $B_0 = 5$ T, peak pressure $p_0 = 5$ bar. Central beta is $\beta_0 = \py{f'{computed_results["central_beta"]:.2f}'}$\%. Pressure gradient drives current, which produces poloidal field and determines $q$ profile. Rational surfaces at $q = 1, 2, 3$ are susceptible to tearing modes. Higher $q$ at edge provides kink stability (Kruskal-Shafranov criterion requires $q > 1$ everywhere).}
500
\end{figure}
501
502
\section{Results Summary}
503
504
\begin{pycode}
505
results = [
506
['Alfvén velocity $v_A$', f"{computed_results['alfven_velocity']:.0f} km/s"],
507
['Sound speed $c_s$', f"{computed_results['sound_speed']:.0f} km/s"],
508
['Plasma beta $\\beta$', f"{computed_results['plasma_beta']:.3f}"],
509
['Kink growth time', f"{computed_results['kink_growth_time']:.1f} $\\mu$s"],
510
['Kink wavelength', f"{computed_results['kink_wavelength']:.1f} cm"],
511
['Lundquist number $S$', f"{computed_results['lundquist_number']:.2e}"],
512
['Reconnection rate', f"{computed_results['reconnection_rate']:.2e}"],
513
['Reconnection time', f"{computed_results['reconnection_time']:.1f} s"],
514
['Central beta (tokamak)', f"{computed_results['central_beta']:.2f}\\%"],
515
]
516
517
print(r'\begin{table}[H]')
518
print(r'\centering')
519
print(r'\caption{Computed MHD Parameters}')
520
print(r'\begin{tabular}{@{}lc@{}}')
521
print(r'\toprule')
522
print(r'Parameter & Value \\')
523
print(r'\midrule')
524
for row in results:
525
print(f"{row[0]} & {row[1]} \\\\")
526
print(r'\bottomrule')
527
print(r'\end{tabular}')
528
print(r'\end{table}')
529
\end{pycode}
530
531
\section{Conclusions}
532
533
This computational study demonstrates fundamental magnetohydrodynamic processes governing plasma confinement, wave propagation, and magnetic energy release. For fusion-relevant parameters ($B = 2$ T, $n = 10^{20}$ m$^{-3}$, $T = 1$ keV), we computed Alfvén velocity $v_A = \py{int(computed_results['alfven_velocity'])}$ km/s and sound speed $c_s = \py{int(computed_results['sound_speed'])}$ km/s, yielding plasma beta $\beta = \py{f"{computed_results['plasma_beta']:.3f}"}$ where magnetic pressure dominates. The MHD dispersion relation reveals three wave modes: fast magnetosonic waves propagating at velocities up to 1200 km/s perpendicular to the field, shear Alfvén waves at 1100 km/s along field lines, and slow magnetosonic waves below 400 km/s.
534
535
Stability analysis for a cylindrical Z-pinch ($a = 5$ cm, $B_\theta = 0.5$ T) shows kink instability growth time $\tau_{\text{kink}} = \py{f"{computed_results['kink_growth_time']:.1f}"}$ $\mu$s at wavelength $\lambda = \py{f"{computed_results['kink_wavelength']:.1f}"}$ cm, requiring rapid feedback control or conducting wall stabilization. The Kruskal-Shafranov criterion $q > 1$ sets a fundamental limit on sustainable current. For tokamak equilibria with $q(0) \sim 1$ and $q(a) \sim 3.5$, rational surfaces at $q = 2, 3$ are susceptible to tearing modes that degrade confinement.
536
537
Magnetic reconnection in solar corona conditions ($B = 100$ G, $n = 10^{15}$ m$^{-3}$, $L = 10^4$ km) yields Lundquist number $S = \py{f"{computed_results['lundquist_number']:.1e}"}$ and Sweet-Parker reconnection time $t = \py{f"{computed_results['reconnection_time']:.1f}"}$ s. This reconnection rate $v_{\text{in}}/v_A = \py{f"{computed_results['reconnection_rate']:.2e}"}$ is too slow to explain observed solar flare timescales, indicating the necessity of fast reconnection mechanisms involving plasmoid instabilities or anomalous resistivity. Understanding these MHD processes is essential for magnetic fusion energy, space weather prediction, and astrophysical plasma dynamics.
538
539
\end{document}
540
541