more documentation
This commit is contained in:
parent
f69b8c9f11
commit
f9d90378b4
7 changed files with 266 additions and 4 deletions
|
|
@ -1,5 +1,35 @@
|
|||
"""
|
||||
Utilities for running finite-difference time-domain (FDTD) simulations
|
||||
|
||||
|
||||
Timestep
|
||||
========
|
||||
|
||||
From the discussion of "Plane waves and the Dispersion relation" in `meanas.fdmath`,
|
||||
we have
|
||||
|
||||
$$ c^2 \\Delta_t^2 = \\frac{\\Delta_t^2}{\\mu \\epsilon} < 1/(\\frac{1}{\\Delta_x^2} + \\frac{1}{\\Delta_y^2} + \\frac{1}{\\Delta_z^2}) $$
|
||||
|
||||
or, if \\( \\Delta_x = \\Delta_y = \\Delta_z \\), then \\( c \\Delta_t < \\frac{\\Delta_x}{\\sqrt{3}} \\).
|
||||
|
||||
Based on this, we can set
|
||||
|
||||
dt = sqrt(mu.min() * epsilon.min()) / sqrt(1/dx_min**2 + 1/dy_min**2 + 1/dz_min**2)
|
||||
|
||||
The `dx_min`, `dy_min`, `dz_min` should be the minimum value across both the base and derived grids.
|
||||
|
||||
|
||||
Poynting Vector
|
||||
===============
|
||||
# TODO
|
||||
|
||||
Energy conservation
|
||||
===================
|
||||
# TODO
|
||||
|
||||
Boundary conditions
|
||||
===================
|
||||
# TODO notes about boundaries / PMLs
|
||||
"""
|
||||
|
||||
from .base import maxwell_e, maxwell_h
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
"""
|
||||
Basic FDTD field updates
|
||||
|
||||
|
||||
"""
|
||||
from typing import List, Callable, Tuple, Dict
|
||||
import numpy
|
||||
|
|
@ -12,12 +14,51 @@ __author__ = 'Jan Petykiewicz'
|
|||
|
||||
|
||||
def maxwell_e(dt: float, dxes: dx_lists_t = None) -> fdfield_updater_t:
|
||||
"""
|
||||
Build a function which performs a portion the time-domain E-field update,
|
||||
|
||||
E += curl_back(H[t]) / epsilon
|
||||
|
||||
The full update should be
|
||||
|
||||
E += (curl_back(H[t]) + J) / epsilon
|
||||
|
||||
which requires an additional step of `E += J / epsilon` which is not performed
|
||||
by the generated function.
|
||||
|
||||
See `meanas.fdmath` for descriptions of
|
||||
|
||||
- This update step: "Maxwell's equations" section
|
||||
- `dxes`: "Datastructure: dx_lists_t" section
|
||||
- `epsilon`: "Permittivity and Permeability" section
|
||||
|
||||
Also see the "Timestep" section of `meanas.fdtd` for a discussion of
|
||||
the `dt` parameter.
|
||||
|
||||
Args:
|
||||
dt: Timestep. See `meanas.fdtd` for details.
|
||||
dxes: Grid description; see `meanas.fdmath`.
|
||||
|
||||
Returns:
|
||||
Function `f(E_old, H_old, epsilon) -> E_new`.
|
||||
"""
|
||||
if dxes is not None:
|
||||
curl_h_fun = curl_back(dxes[1])
|
||||
else:
|
||||
curl_h_fun = curl_back()
|
||||
|
||||
def me_fun(e: fdfield_t, h: fdfield_t, epsilon: fdfield_t):
|
||||
"""
|
||||
Update the E-field.
|
||||
|
||||
Args:
|
||||
e: E-field at time t=0
|
||||
h: H-field at time t=0.5
|
||||
epsilon: Dielectric constant distribution.
|
||||
|
||||
Returns:
|
||||
E-field at time t=1
|
||||
"""
|
||||
e += dt * curl_h_fun(h) / epsilon
|
||||
return e
|
||||
|
||||
|
|
@ -25,13 +66,57 @@ def maxwell_e(dt: float, dxes: dx_lists_t = None) -> fdfield_updater_t:
|
|||
|
||||
|
||||
def maxwell_h(dt: float, dxes: dx_lists_t = None) -> fdfield_updater_t:
|
||||
"""
|
||||
Build a function which performs part of the time-domain H-field update,
|
||||
|
||||
H -= curl_forward(E[t]) / mu
|
||||
|
||||
The full update should be
|
||||
|
||||
H -= (curl_forward(E[t]) - M) / mu
|
||||
|
||||
which requires an additional step of `H += M / mu` which is not performed
|
||||
by the generated function; this step can be omitted if there is no magnetic
|
||||
current `M`.
|
||||
|
||||
See `meanas.fdmath` for descriptions of
|
||||
|
||||
- This update step: "Maxwell's equations" section
|
||||
- `dxes`: "Datastructure: dx_lists_t" section
|
||||
- `mu`: "Permittivity and Permeability" section
|
||||
|
||||
Also see the "Timestep" section of `meanas.fdtd` for a discussion of
|
||||
the `dt` parameter.
|
||||
|
||||
Args:
|
||||
dt: Timestep. See `meanas.fdtd` for details.
|
||||
dxes: Grid description; see `meanas.fdmath`.
|
||||
|
||||
Returns:
|
||||
Function `f(E_old, H_old, epsilon) -> E_new`.
|
||||
"""
|
||||
if dxes is not None:
|
||||
curl_e_fun = curl_forward(dxes[0])
|
||||
else:
|
||||
curl_e_fun = curl_forward()
|
||||
|
||||
def mh_fun(e: fdfield_t, h: fdfield_t):
|
||||
h -= dt * curl_e_fun(e)
|
||||
def mh_fun(e: fdfield_t, h: fdfield_t, mu: fdfield_t = None):
|
||||
"""
|
||||
Update the H-field.
|
||||
|
||||
Args:
|
||||
e: E-field at time t=1
|
||||
h: H-field at time t=0.5
|
||||
mu: Magnetic permeability. Default is 1 everywhere.
|
||||
|
||||
Returns:
|
||||
H-field at time t=1.5
|
||||
"""
|
||||
if mu is not None:
|
||||
h -= dt * curl_e_fun(e) / mu
|
||||
else:
|
||||
h -= dt * curl_e_fun(e)
|
||||
|
||||
return h
|
||||
|
||||
return mh_fun
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
"""
|
||||
Boundary conditions
|
||||
|
||||
#TODO conducting boundary documentation
|
||||
"""
|
||||
|
||||
from typing import List, Callable, Tuple, Dict
|
||||
|
|
|
|||
|
|
@ -5,10 +5,14 @@ import numpy
|
|||
from ..fdmath import dx_lists_t, fdfield_t, fdfield_updater_t
|
||||
from ..fdmath.functional import deriv_back, deriv_forward
|
||||
|
||||
|
||||
def poynting(e: fdfield_t,
|
||||
h: fdfield_t,
|
||||
dxes: dx_lists_t = None,
|
||||
) -> fdfield_t:
|
||||
"""
|
||||
Calculate the poynting vector
|
||||
"""
|
||||
if dxes is None:
|
||||
dxes = tuple(tuple(numpy.ones(1) for _ in range(3)) for _ in range(2))
|
||||
|
||||
|
|
@ -32,6 +36,9 @@ def poynting_divergence(s: fdfield_t = None,
|
|||
h: fdfield_t = None,
|
||||
dxes: dx_lists_t = None,
|
||||
) -> fdfield_t:
|
||||
"""
|
||||
Calculate the divergence of the poynting vector
|
||||
"""
|
||||
if s is None:
|
||||
s = poynting(e, h, dxes=dxes)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,9 @@
|
|||
"""
|
||||
PML implementations
|
||||
|
||||
#TODO discussion of PMLs
|
||||
#TODO cpml documentation
|
||||
|
||||
"""
|
||||
# TODO retest pmls!
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue