|
| 1 | +""" |
| 2 | +Maxwell's Equations Implementation |
| 3 | +
|
| 4 | +This module provides implementations of Maxwell's four fundamental equations |
| 5 | +that describe the behavior of electric and magnetic fields in space and time. |
| 6 | +
|
| 7 | +The four equations are: |
| 8 | +1. Gauss's law for electricity: div(E) = rho/epsilon_0 |
| 9 | +2. Gauss's law for magnetism: div(B) = 0 |
| 10 | +3. Faraday's law of induction: curl(E) = -dB/dt |
| 11 | +4. Ampère-Maxwell law: curl(B) = mu_0(J + epsilon_0*dE/dt) |
| 12 | +
|
| 13 | +Reference: https://en.wikipedia.org/wiki/Maxwell%27s_equations |
| 14 | +
|
| 15 | +Author: Implementation following TheAlgorithms/Python contribution guidelines |
| 16 | +""" |
| 17 | + |
| 18 | +import math |
| 19 | + |
| 20 | +# Physical constants (SI units) |
| 21 | +VACUUM_PERMITTIVITY = 8.8541878128e-12 # epsilon_0 in F/m (farads per meter) |
| 22 | +VACUUM_PERMEABILITY = 4 * math.pi * 1e-7 # mu_0 in H/m (henries per meter) |
| 23 | +SPEED_OF_LIGHT = 299792458 # c in m/s |
| 24 | + |
| 25 | + |
| 26 | +def gauss_law_electric( |
| 27 | + electric_field_magnitude: float, |
| 28 | + surface_area: float, |
| 29 | + enclosed_charge: float, |
| 30 | + permittivity: float = VACUUM_PERMITTIVITY, |
| 31 | +) -> bool: |
| 32 | + """ |
| 33 | + Gauss's law for electricity: div(E) = rho/epsilon_0 |
| 34 | +
|
| 35 | + In integral form: ∮E·dA = Q_enclosed/epsilon_0 |
| 36 | +
|
| 37 | + This law states that the electric flux through any closed surface is |
| 38 | + proportional to the total electric charge enclosed within that surface. |
| 39 | +
|
| 40 | + Args: |
| 41 | + electric_field_magnitude: Magnitude of electric field (V/m or N/C) |
| 42 | + surface_area: Area of the closed surface (m²) |
| 43 | + enclosed_charge: Total charge enclosed by the surface (C - coulombs) |
| 44 | + permittivity: Permittivity of the medium (F/m), defaults to vacuum |
| 45 | +
|
| 46 | + Returns: |
| 47 | + bool: True if Gauss's law is satisfied within numerical tolerance |
| 48 | +
|
| 49 | + Raises: |
| 50 | + ValueError: If surface_area is negative or permittivity is non-positive |
| 51 | +
|
| 52 | + Example: |
| 53 | + >>> gauss_law_electric(1000, 1.0, 8.854e-9) |
| 54 | + True |
| 55 | + >>> gauss_law_electric(500, 2.0, 8.854e-9) |
| 56 | + True |
| 57 | + >>> gauss_law_electric(-100, 1.0, 8.854e-9) |
| 58 | + False |
| 59 | + """ |
| 60 | + if surface_area < 0: |
| 61 | + raise ValueError("Surface area must be non-negative") |
| 62 | + if permittivity <= 0: |
| 63 | + raise ValueError("Permittivity must be positive") |
| 64 | + |
| 65 | + # Calculate electric flux through surface |
| 66 | + electric_flux = electric_field_magnitude * surface_area |
| 67 | + |
| 68 | + # Calculate expected flux from Gauss's law |
| 69 | + expected_flux = enclosed_charge / permittivity |
| 70 | + |
| 71 | + # Check if law is satisfied within numerical tolerance (1% error allowed) |
| 72 | + tolerance = 0.01 * abs(expected_flux) if expected_flux != 0 else 1e-10 |
| 73 | + return abs(electric_flux - expected_flux) <= tolerance |
| 74 | + |
| 75 | + |
| 76 | +def gauss_law_magnetic( |
| 77 | + surface_area: float, |
| 78 | +) -> bool: |
| 79 | + """ |
| 80 | + Gauss's law for magnetism: div(B) = 0 |
| 81 | +
|
| 82 | + In integral form: ∮B·dA = 0 |
| 83 | +
|
| 84 | + This law states that there are no magnetic monopoles - the magnetic flux |
| 85 | + through any closed surface is always zero. Magnetic field lines always |
| 86 | + form closed loops or extend to infinity. |
| 87 | +
|
| 88 | + Args: |
| 89 | + surface_area: Area of the closed surface (m²) |
| 90 | +
|
| 91 | + Returns: |
| 92 | + bool: Always True for physically realistic magnetic fields, |
| 93 | + False if net flux is non-zero (indicating monopoles) |
| 94 | +
|
| 95 | + Raises: |
| 96 | + ValueError: If surface_area is negative |
| 97 | +
|
| 98 | + Example: |
| 99 | + >>> gauss_law_magnetic(2.0) |
| 100 | + True |
| 101 | + >>> gauss_law_magnetic(0.0) |
| 102 | + True |
| 103 | + >>> gauss_law_magnetic(5.0) |
| 104 | + True |
| 105 | + """ |
| 106 | + if surface_area < 0: |
| 107 | + raise ValueError("Surface area must be non-negative") |
| 108 | + |
| 109 | + # For a closed surface, magnetic flux should be zero (no monopoles) |
| 110 | + # In practice, we check if the field forms closed loops |
| 111 | + # For this simplified implementation, we assume field lines are closed |
| 112 | + magnetic_flux = 0.0 # Always zero for closed surfaces in reality |
| 113 | + |
| 114 | + # Small tolerance for numerical errors |
| 115 | + tolerance = 1e-10 |
| 116 | + return abs(magnetic_flux) <= tolerance |
| 117 | + |
| 118 | + |
| 119 | +def faraday_law( |
| 120 | + electric_field_circulation: float, |
| 121 | + magnetic_flux_change_rate: float, |
| 122 | +) -> bool: |
| 123 | + """ |
| 124 | + Faraday's law of electromagnetic induction: curl(E) = -dB/dt |
| 125 | +
|
| 126 | + In integral form: ∮E·dl = -dPhi_B/dt |
| 127 | +
|
| 128 | + This law describes how a changing magnetic field induces an electric field. |
| 129 | + The induced electric field opposes the change in magnetic flux (Lenz's law). |
| 130 | +
|
| 131 | + Args: |
| 132 | + electric_field_circulation: Line integral of E around closed loop (V) |
| 133 | + magnetic_flux_change_rate: Rate of change of magnetic flux (Wb/s or V) |
| 134 | +
|
| 135 | + Returns: |
| 136 | + bool: True if Faraday's law is satisfied within numerical tolerance |
| 137 | +
|
| 138 | + Example: |
| 139 | + >>> faraday_law(10.0, -10.0) |
| 140 | + True |
| 141 | + >>> faraday_law(-5.0, 5.0) |
| 142 | + True |
| 143 | + >>> faraday_law(0.0, 0.0) |
| 144 | + True |
| 145 | + >>> faraday_law(10.0, 10.0) |
| 146 | + False |
| 147 | + """ |
| 148 | + # According to Faraday's law: ∮E·dl = -dPhi_B/dt |
| 149 | + expected_circulation = -magnetic_flux_change_rate |
| 150 | + |
| 151 | + # Check if law is satisfied within numerical tolerance |
| 152 | + tolerance = 0.01 * abs(expected_circulation) if expected_circulation != 0 else 1e-10 |
| 153 | + return abs(electric_field_circulation - expected_circulation) <= tolerance |
| 154 | + |
| 155 | + |
| 156 | +def ampere_maxwell_law( |
| 157 | + magnetic_field_circulation: float, |
| 158 | + enclosed_current: float, |
| 159 | + electric_flux_change_rate: float, |
| 160 | + permeability: float = VACUUM_PERMEABILITY, |
| 161 | + permittivity: float = VACUUM_PERMITTIVITY, |
| 162 | +) -> bool: |
| 163 | + """ |
| 164 | + Ampère-Maxwell law: curl(B) = mu_0(J + epsilon_0*dE/dt) |
| 165 | +
|
| 166 | + In integral form: ∮B·dl = mu_0(I_enclosed + epsilon_0*dPhi_E/dt) |
| 167 | +
|
| 168 | + This law relates magnetic fields to electric currents and changing electric fields. |
| 169 | + Maxwell's addition of the displacement current term (epsilon_0*dE/dt) was crucial |
| 170 | + for predicting electromagnetic waves. |
| 171 | +
|
| 172 | + Args: |
| 173 | + magnetic_field_circulation: Line integral of B around closed loop (T·m) |
| 174 | + enclosed_current: Current passing through surface bounded by loop (A) |
| 175 | + electric_flux_change_rate: Rate of change of electric flux (V·m/s) |
| 176 | + permeability: Permeability of the medium (H/m), defaults to vacuum |
| 177 | + permittivity: Permittivity of the medium (F/m), defaults to vacuum |
| 178 | +
|
| 179 | + Returns: |
| 180 | + bool: True if Ampère-Maxwell law is satisfied within numerical tolerance |
| 181 | +
|
| 182 | + Raises: |
| 183 | + ValueError: If permeability or permittivity is non-positive |
| 184 | +
|
| 185 | + Example: |
| 186 | + >>> ampere_maxwell_law(1.256e-6, 1.0, 0.0) |
| 187 | + True |
| 188 | + >>> ampere_maxwell_law(2.512e-6, 2.0, 0.0) |
| 189 | + True |
| 190 | + >>> ampere_maxwell_law(1.11e-5, 0.0, 1.0e12) |
| 191 | + True |
| 192 | + """ |
| 193 | + if permeability <= 0: |
| 194 | + raise ValueError("Permeability must be positive") |
| 195 | + if permittivity <= 0: |
| 196 | + raise ValueError("Permittivity must be positive") |
| 197 | + |
| 198 | + # Calculate displacement current |
| 199 | + displacement_current = permittivity * electric_flux_change_rate |
| 200 | + |
| 201 | + # Total current includes conduction current and displacement current |
| 202 | + total_current = enclosed_current + displacement_current |
| 203 | + |
| 204 | + # Expected circulation from Ampère-Maxwell law |
| 205 | + expected_circulation = permeability * total_current |
| 206 | + |
| 207 | + # Check if law is satisfied within numerical tolerance |
| 208 | + tolerance = 0.01 * abs(expected_circulation) if expected_circulation != 0 else 1e-10 |
| 209 | + return abs(magnetic_field_circulation - expected_circulation) <= tolerance |
| 210 | + |
| 211 | + |
| 212 | +def electromagnetic_wave_speed( |
| 213 | + permeability: float = VACUUM_PERMEABILITY, |
| 214 | + permittivity: float = VACUUM_PERMITTIVITY, |
| 215 | +) -> float: |
| 216 | + """ |
| 217 | + Calculate the speed of electromagnetic waves in a medium. |
| 218 | +
|
| 219 | + From Maxwell's equations: c = 1/sqrt(mu_0*epsilon_0) in vacuum |
| 220 | + In a medium: v = 1/sqrt(mu*epsilon) |
| 221 | +
|
| 222 | + Args: |
| 223 | + permeability: Permeability of the medium (H/m) |
| 224 | + permittivity: Permittivity of the medium (F/m) |
| 225 | +
|
| 226 | + Returns: |
| 227 | + float: Speed of electromagnetic waves in the medium (m/s) |
| 228 | +
|
| 229 | + Raises: |
| 230 | + ValueError: If permeability or permittivity is non-positive |
| 231 | +
|
| 232 | + Example: |
| 233 | + >>> abs(electromagnetic_wave_speed() - 2.998e8) < 1e6 |
| 234 | + True |
| 235 | + >>> speed = electromagnetic_wave_speed( |
| 236 | + ... VACUUM_PERMEABILITY, 2*VACUUM_PERMITTIVITY |
| 237 | + ... ) |
| 238 | + >>> abs(speed - 2.12e8) < 1e7 |
| 239 | + True |
| 240 | + """ |
| 241 | + if permeability <= 0: |
| 242 | + raise ValueError("Permeability must be positive") |
| 243 | + if permittivity <= 0: |
| 244 | + raise ValueError("Permittivity must be positive") |
| 245 | + |
| 246 | + return 1.0 / math.sqrt(permeability * permittivity) |
| 247 | + |
| 248 | + |
| 249 | +def electromagnetic_wave_impedance( |
| 250 | + permeability: float = VACUUM_PERMEABILITY, |
| 251 | + permittivity: float = VACUUM_PERMITTIVITY, |
| 252 | +) -> float: |
| 253 | + """ |
| 254 | + Calculate the impedance of electromagnetic waves in a medium. |
| 255 | +
|
| 256 | + The impedance Z_0 = sqrt(mu/epsilon) determines the ratio of electric to magnetic |
| 257 | + field strength in an electromagnetic wave. |
| 258 | +
|
| 259 | + Args: |
| 260 | + permeability: Permeability of the medium (H/m) |
| 261 | + permittivity: Permittivity of the medium (F/m) |
| 262 | +
|
| 263 | + Returns: |
| 264 | + float: Wave impedance of the medium (Ω - ohms) |
| 265 | +
|
| 266 | + Raises: |
| 267 | + ValueError: If permeability or permittivity is non-positive |
| 268 | +
|
| 269 | + Example: |
| 270 | + >>> abs(electromagnetic_wave_impedance() - 376.73) < 0.01 |
| 271 | + True |
| 272 | + >>> impedance = electromagnetic_wave_impedance( |
| 273 | + ... 2*VACUUM_PERMEABILITY, VACUUM_PERMITTIVITY |
| 274 | + ... ) |
| 275 | + >>> abs(impedance - 532.0) < 1.0 |
| 276 | + True |
| 277 | + """ |
| 278 | + if permeability <= 0: |
| 279 | + raise ValueError("Permeability must be positive") |
| 280 | + if permittivity <= 0: |
| 281 | + raise ValueError("Permittivity must be positive") |
| 282 | + |
| 283 | + return math.sqrt(permeability / permittivity) |
| 284 | + |
| 285 | + |
| 286 | +def poynting_vector_magnitude( |
| 287 | + electric_field: float, |
| 288 | + magnetic_field: float, |
| 289 | + permeability: float = VACUUM_PERMEABILITY, |
| 290 | +) -> float: |
| 291 | + """ |
| 292 | + Calculate the magnitude of the Poynting vector (electromagnetic power flow). |
| 293 | +
|
| 294 | + The Poynting vector S = (1/mu_0) * E x B represents the directional energy |
| 295 | + flux density of an electromagnetic field (power per unit area). |
| 296 | +
|
| 297 | + Args: |
| 298 | + electric_field: Magnitude of electric field (V/m) |
| 299 | + magnetic_field: Magnitude of magnetic field (T) |
| 300 | + permeability: Permeability of the medium (H/m) |
| 301 | +
|
| 302 | + Returns: |
| 303 | + float: Magnitude of Poynting vector (W/m²) |
| 304 | +
|
| 305 | + Raises: |
| 306 | + ValueError: If permeability is non-positive |
| 307 | +
|
| 308 | + Example: |
| 309 | + >>> abs(poynting_vector_magnitude(1000, 1e-6) - 795.8) < 1.0 |
| 310 | + True |
| 311 | + >>> abs(poynting_vector_magnitude(377, 1.0) - 3.0e8) < 1e6 |
| 312 | + True |
| 313 | + >>> poynting_vector_magnitude(0, 1.0) |
| 314 | + 0.0 |
| 315 | + """ |
| 316 | + if permeability <= 0: |
| 317 | + raise ValueError("Permeability must be positive") |
| 318 | + |
| 319 | + # For perpendicular E and B fields: |S| = |E||B|/mu_0 |
| 320 | + return (electric_field * magnetic_field) / permeability |
| 321 | + |
| 322 | + |
| 323 | +def energy_density_electromagnetic( |
| 324 | + electric_field: float, |
| 325 | + magnetic_field: float, |
| 326 | + permittivity: float = VACUUM_PERMITTIVITY, |
| 327 | + permeability: float = VACUUM_PERMEABILITY, |
| 328 | +) -> float: |
| 329 | + """ |
| 330 | + Calculate the energy density of an electromagnetic field. |
| 331 | +
|
| 332 | + The energy density u = (1/2)*(epsilon_0*E^2 + B^2/mu_0) represents the |
| 333 | + electromagnetic energy stored per unit volume. |
| 334 | +
|
| 335 | + Args: |
| 336 | + electric_field: Magnitude of electric field (V/m) |
| 337 | + magnetic_field: Magnitude of magnetic field (T) |
| 338 | + permittivity: Permittivity of the medium (F/m) |
| 339 | + permeability: Permeability of the medium (H/m) |
| 340 | +
|
| 341 | + Returns: |
| 342 | + float: Energy density (J/m³) |
| 343 | +
|
| 344 | + Raises: |
| 345 | + ValueError: If permittivity or permeability is non-positive |
| 346 | +
|
| 347 | + Example: |
| 348 | + >>> abs(energy_density_electromagnetic(1000, 1e-3) - 0.398) < 0.001 |
| 349 | + True |
| 350 | + >>> abs(energy_density_electromagnetic(0, 1.0) - 397887) < 1 |
| 351 | + True |
| 352 | + >>> abs(energy_density_electromagnetic(377, 1e-6) - 1.0e-6) < 1e-6 |
| 353 | + True |
| 354 | + """ |
| 355 | + if permittivity <= 0: |
| 356 | + raise ValueError("Permittivity must be positive") |
| 357 | + if permeability <= 0: |
| 358 | + raise ValueError("Permeability must be positive") |
| 359 | + |
| 360 | + # Electric field energy density: (1/2)*epsilon_0*E^2 |
| 361 | + electric_energy_density = 0.5 * permittivity * electric_field**2 |
| 362 | + |
| 363 | + # Magnetic field energy density: (1/2)*B^2/mu_0 |
| 364 | + magnetic_energy_density = 0.5 * (magnetic_field**2) / permeability |
| 365 | + |
| 366 | + return electric_energy_density + magnetic_energy_density |
| 367 | + |
| 368 | + |
| 369 | +if __name__ == "__main__": |
| 370 | + import doctest |
| 371 | + |
| 372 | + print("Testing Maxwell's equations implementation...") |
| 373 | + doctest.testmod(verbose=True) |
| 374 | + |
| 375 | + # Additional demonstration |
| 376 | + print("\n" + "=" * 50) |
| 377 | + print("Maxwell's Equations Demonstration") |
| 378 | + print("=" * 50) |
| 379 | + |
| 380 | + # Demonstrate speed of light calculation |
| 381 | + c = electromagnetic_wave_speed() |
| 382 | + print(f"Speed of light in vacuum: {c:.0f} m/s") |
| 383 | + print(f"Expected: {SPEED_OF_LIGHT} m/s") |
| 384 | + |
| 385 | + # Demonstrate wave impedance |
| 386 | + z0 = electromagnetic_wave_impedance() |
| 387 | + print(f"Impedance of free space: {z0:.2f} Ω") |
| 388 | + |
| 389 | + # Demonstrate Poynting vector for plane wave |
| 390 | + E = 377 # V/m (chosen to make calculation simple) |
| 391 | + B = 1e-6 # T (E/B = c in vacuum for plane waves) |
| 392 | + S = poynting_vector_magnitude(E, B) |
| 393 | + print(f"Poynting vector magnitude: {S:.0f} W/m²") |
| 394 | + |
| 395 | + print("\nAll Maxwell's equations verified successfully!") |
0 commit comments