Formula reference: green
Generated from the docstrings of vaft.formula.green:
16 public functions. Each entry is what
vaft.formula.describe("green.<name>") prints.
All formula categories
Overview
This module provides functions for calculating various Green’s function integrals used in plasma physics calculations.
| Symbol | Meaning | Unit |
|---|---|---|
| G | Green's function | - |
| K | complete elliptic integral of first kind | - |
| E | complete elliptic integral of second kind | - |
Every flux these functions return is full weber, psi = mu0 G per
ampere – the physical flux through the toroidal circle, which grows toward
a positive current – not the per-radian g-file family. Hand such a flux to
vaft.formula.equilibrium.vertical_magnetic_field_from_psi and the
other field helpers with cocos=13 ($k = -1/2\pi$, the factor
psi_per_radian=False gives
vaft.formula.equilibrium.poloidal_field_factor). Their default is
$2\pi$ too large, and cocos=11 has the right size but the opposite
sign: IMAS flux grows away from a positive current (#354).
Functions
calculate_distance | Euclidean distance between $(r_1, z_1)$ and $(r_2, z_2)$ in the poloidal plane. |
complete_elliptic_integral_e | Complete elliptic integral of the second kind $E(m)$. Convention |
complete_elliptic_integral_k | Complete elliptic integral of the first kind $K(m)$. Convention |
elliptic_integral | Polynomial approximations of $K$ and $E$ for a ring source and observer points. |
green_br_bz | Field of a unit-current ring, $(B_r, B_z)$ at observer points (legacy elliptic path). Convention |
green_br_bz_exact | $(B_r, B_z)$ per unit ring current, exact elliptic integrals, broadcasting. Convention |
green_psi_exact | Poloidal flux per unit ring current, exact elliptic integrals. Convention |
green_r | Poloidal flux per unit ring current at observer points (legacy elliptic path). Convention |
greens_function_2d | Axisymmetric kernel $\sqrt{RR_0}\,K(m)$ between a field point and a ring source. Convention |
greens_function_3d | Toroidal-angle-resolved variant of the $\sqrt{RR_0}\,K(m)$ kernel. |
greens_function_exact | Exact free-space axisymmetric Green’s function and its derivatives. Convention |
greens_integral_2d | Line integral along $R$ of the 2-D kernel times a source density. |
greens_integral_3d | Line integral along $R$ of the 3-D kernel times a source density. |
mutual_inductance | Mutual inductance between two rectangular-cross-section ring coils. |
self_inductance | Self-inductance of a rectangular-cross-section ring coil. |
trapz_integral | Trapezoidal integral $\int y\,dx$, local copy for the Green kernels. |
No function matches.
calculate_distance
source
calculate_distance(r1, r2, z1, z2)
Show source vaft/formula/green.py, lines 70–97
def calculate_distance(r1: Union[np.ndarray, float], r2: Union[np.ndarray, float],
z1: Union[np.ndarray, float], z2: Union[np.ndarray, float]) -> Union[np.ndarray, float]:
r"""Euclidean distance between $(r_1, z_1)$ and $(r_2, z_2)$ in the poloidal plane.
$$d = \sqrt{(r_2 - r_1)^2 + (z_2 - z_1)^2}$$
Parameters
----------
r1 : float or np.ndarray
Radius of the first point(s) [m].
r2 : float or np.ndarray
Radius of the second point(s) [m].
z1 : float or np.ndarray
Height of the first point(s) [m].
z2 : float or np.ndarray
Height of the second point(s) [m].
Returns
-------
float or np.ndarray
Distance, broadcast over the inputs [m].
Notes
-----
A distance in the $(R, Z)$ half-plane, not the 3-D distance between points
on two current loops.
"""
return np.sqrt((r2 - r1) ** 2 + (z2 - z1) ** 2)Euclidean distance between $(r_1, z_1)$ and $(r_2, z_2)$ in the poloidal plane.
\[d = \sqrt{(r_2 - r_1)^2 + (z_2 - z_1)^2}\]| Name | Type | Unit | Description |
|---|---|---|---|
r1 | float or np.ndarray | m | Radius of the first point(s). |
r2 | float or np.ndarray | m | Radius of the second point(s). |
z1 | float or np.ndarray | m | Height of the first point(s). |
z2 | float or np.ndarray | m | Height of the second point(s). |
| Returns | |||
| — | float or np.ndarray | m | Distance, broadcast over the inputs. |
Notes
Notes
A distance in the $(R, Z)$ half-plane, not the 3-D distance between points on two current loops.
complete_elliptic_integral_e
Convention-sensitive
source
complete_elliptic_integral_e(m)
Show source vaft/formula/green.py, lines 160–186
def complete_elliptic_integral_e(m: Union[float, np.ndarray]) -> Union[float, np.ndarray]:
r"""Complete elliptic integral of the second kind $E(m)$.
$$E(m) = \int_0^{\pi/2}\sqrt{1 - m\sin^2\theta}\,d\theta$$
Parameters
----------
m : float or np.ndarray
Parameter $m = k^2$, in $[0, 1]$ [-].
Returns
-------
float or np.ndarray
$E(m)$, from $\pi/2$ at $m = 0$ to 1 at $m = 1$ [-].
Convention
----------
Takes the parameter $m = k^2$, as ``scipy.special.ellipe`` does.
References
----------
.. [1] NIST Digital Library of Mathematical Functions, Sec. 19.2(ii),
https://dlmf.nist.gov/19.2.
.. [2] M. Abramowitz and I. A. Stegun, *Handbook of Mathematical Functions*,
Dover (1972), Sec. 17.3.
"""
return ellipe(m)Complete elliptic integral of the second kind $E(m)$.
\[E(m) = \int_0^{\pi/2}\sqrt{1 - m\sin^2\theta}\,d\theta\]| Name | Type | Unit | Description |
|---|---|---|---|
m | float or np.ndarray | - | Parameter $m = k^2$, in $[0, 1]$. |
| Returns | |||
| — | float or np.ndarray | - | $E(m)$, from $\pi/2$ at $m = 0$ to 1 at $m = 1$. |
Convention
Takes the parameter $m = k^2$, as scipy.special.ellipe does.
References
References
- NIST Digital Library of Mathematical Functions, Sec. 19.2(ii), https://dlmf.nist.gov/19.2.
- M. Abramowitz and I. A. Stegun, Handbook of Mathematical Functions, Dover (1972), Sec. 17.3.
complete_elliptic_integral_k
Convention-sensitive
source
complete_elliptic_integral_k(m)
Show source vaft/formula/green.py, lines 130–157
def complete_elliptic_integral_k(m: Union[float, np.ndarray]) -> Union[float, np.ndarray]:
r"""Complete elliptic integral of the first kind $K(m)$.
$$K(m) = \int_0^{\pi/2}\frac{d\theta}{\sqrt{1 - m\sin^2\theta}}$$
Parameters
----------
m : float or np.ndarray
Parameter $m = k^2$, in $[0, 1)$ [-].
Returns
-------
float or np.ndarray
$K(m)$ [-].
Convention
----------
Takes the *parameter* $m = k^2$, as ``scipy.special.ellipk`` does, not the
modulus $k$; $K \to \infty$ logarithmically as $m \to 1$.
References
----------
.. [1] NIST Digital Library of Mathematical Functions, Sec. 19.2(ii),
https://dlmf.nist.gov/19.2.
.. [2] M. Abramowitz and I. A. Stegun, *Handbook of Mathematical Functions*,
Dover (1972), Sec. 17.3.
"""
return ellipk(m)Complete elliptic integral of the first kind $K(m)$.
\[K(m) = \int_0^{\pi/2}\frac{d\theta}{\sqrt{1 - m\sin^2\theta}}\]| Name | Type | Unit | Description |
|---|---|---|---|
m | float or np.ndarray | - | Parameter $m = k^2$, in $[0, 1)$. |
| Returns | |||
| — | float or np.ndarray | - | $K(m)$. |
Convention
Takes the parameter $m = k^2$, as scipy.special.ellipk does, not the
modulus $k$; $K \to \infty$ logarithmically as $m \to 1$.
References
References
- NIST Digital Library of Mathematical Functions, Sec. 19.2(ii), https://dlmf.nist.gov/19.2.
- M. Abramowitz and I. A. Stegun, Handbook of Mathematical Functions, Dover (1972), Sec. 17.3.
elliptic_integral
source
elliptic_integral(r_obs, z_obs, r_src, z_src)
Polynomial approximations of $K$ and $E$ for a ring source and observer points.
\[m = \frac{4r_{obs}r_{src}}{(r_{obs} + r_{src})^2 + (z_{obs} - z_{src})^2}, \qquad m_1 = 1 - m\]then the Hastings polynomials $K \approx \sum a_km_1^k + \ln(1/m_1)\sum b_km_1^k$ and $E \approx \sum c_km_1^k + \ln(1/m_1)\sum d_km_1^k$ to fourth order.
| Name | Type | Unit | Description |
|---|---|---|---|
r_obs | np.ndarray | m | Radius of the observation points. |
z_obs | np.ndarray | m | Height of the observation points. |
r_src | float | m | Radius of the ring source. |
z_src | float | m | Height of the ring source. |
| Returns | |||
ek | np.ndarray | - | Approximate $K(m)$. |
ee | np.ndarray | - | Approximate $E(m)$. |
Validity · Limitations · References
Validity
Abramowitz and Stegun 17.3.34 and 17.3.36, absolute error below
$2\times10^{-8}$ for $0 \le m < 1$; the legacy path of green_r and
green_br_bz, retained so their numbers do not change.
Limitations
$\ln(1/m_1)$ diverges at a coincident observer and source and a warning is
emitted with a bare print rather than warnings.warn (tracked in
#356); greens_function_exact uses scipy’s exact integrals instead.
References
- M. Abramowitz and I. A. Stegun, Handbook of Mathematical Functions, Dover (1972), Eqs. 17.3.34 and 17.3.36.
- C. Hastings, Approximations for Digital Computers, Princeton University Press (1955).
green_br_bz
Convention-sensitive
source
green_br_bz(r_obs, z_obs, r_src, z_src)
Field of a unit-current ring, $(B_r, B_z)$ at observer points (legacy elliptic path).
\[B_r = \frac{\mu_0}{2\pi r}\,\frac{z - z_0}{\sqrt{(r + r_0)^2 + (z - z_0)^2}} \left[\frac{r^2 + r_0^2 + (z - z_0)^2}{(r - r_0)^2 + (z - z_0)^2}E - K\right], \quad B_z = \frac{\mu_0}{2\pi}\,\frac{1}{\sqrt{(r + r_0)^2 + (z - z_0)^2}} \left[K - \frac{r^2 - r_0^2 + (z - z_0)^2}{(r - r_0)^2 + (z - z_0)^2}E\right]\]| Name | Type | Unit | Description |
|---|---|---|---|
r_obs | np.ndarray | m | Radius of the observation points. |
z_obs | np.ndarray | m | Height of the observation points. |
r_src | float | m | Radius of the current ring. |
z_src | float | m | Height of the current ring. |
| Returns | |||
br | np.ndarray | T/A | Radial field per ampere. |
bz | np.ndarray | T/A | Vertical field per ampere. |
Convention
Right-handed $(r, \varphi, z)$ with the current flowing in $+\varphi$; $B_z$
is positive inside the ring. SI throughout; no $2\pi$ flux ambiguity
arises for fields. Uses the approximate elliptic_integral; the
exact, broadcasting counterpart is green_br_bz_exact.
Limitations · References
Limitations
Divides by $(r - r_0)^2 + (z - z_0)^2$ and by $r_{obs}$ without guards, so
a coincident point or an on-axis observer gives inf/nan (the
callers’ shifted-evaluation scheme avoids exact coincidence). Tracked in
#356.
References
- W. R. Smythe, Static and Dynamic Electricity, 3rd ed., McGraw-Hill (1968), Sec. 7.10 (field of a circular loop).
- J. D. Jackson, Classical Electrodynamics, 3rd ed., Wiley (1999), Sec. 5.5.
green_br_bz_exact
Convention-sensitive
source
green_br_bz_exact(r_obs, z_obs, r_src, z_src)
Show source vaft/formula/green.py, lines 856–913
def green_br_bz_exact(r_obs, z_obs, r_src, z_src) -> Tuple[np.ndarray, np.ndarray]:
r"""$(B_r, B_z)$ per unit ring current, exact elliptic integrals, broadcasting.
$$B_r = -\frac{\mu_0}{2\pi r}\,\frac{\partial G}{\partial z}, \qquad
B_z = +\frac{\mu_0}{2\pi r}\,\frac{\partial G}{\partial r}$$
Parameters
----------
r_obs : array-like
Observation major radius [m].
z_obs : array-like
Observation height [m].
r_src : array-like
Source major radius [m].
z_src : array-like
Source height [m].
Returns
-------
br : np.ndarray
Radial field per ampere [T/A].
bz : np.ndarray
Vertical field per ampere [T/A].
Convention
----------
Right-handed $(r, \varphi, z)$, current in $+\varphi$; consistent with
:func:`green_psi_exact` through $B_z = (1/r)\,\partial\psi/\partial r
\times 1/2\pi$ for a full-weber $\psi$.
Limitations
-----------
Observation points on the geometric axis ($r_{obs} = 0$) return the analytic
limits $B_r = 0$, $B_z = \mu_0 r_0^2/(2(r_0^2 + (z - z_0)^2)^{3/2})$; the
coincident-point caveat of :func:`greens_function_exact` applies.
References
----------
.. [1] W. R. Smythe, *Static and Dynamic Electricity*, 3rd ed., McGraw-Hill
(1968), Sec. 7.10.
"""
r_obs, z_obs, r_src, z_src = np.broadcast_arrays(
np.asarray(r_obs, dtype=float),
np.asarray(z_obs, dtype=float),
np.asarray(r_src, dtype=float),
np.asarray(z_src, dtype=float),
)
on_axis = r_obs == 0.0
r_safe = np.where(on_axis, 1.0, r_obs)
coeff = MU0 / (2.0 * np.pi * r_safe)
br = -coeff * greens_function_exact(r_obs, z_obs, r_src, z_src, "dpsi_dz")
bz = coeff * greens_function_exact(r_obs, z_obs, r_src, z_src, "dpsi_dr")
if np.any(on_axis):
dz2 = (z_obs - z_src) ** 2
bz_axis = MU0 * r_src**2 / (2.0 * (r_src**2 + dz2) ** 1.5)
bz = np.where(on_axis, bz_axis, bz)
br = np.where(on_axis, 0.0, br)
return br, bz$(B_r, B_z)$ per unit ring current, exact elliptic integrals, broadcasting.
\[B_r = -\frac{\mu_0}{2\pi r}\,\frac{\partial G}{\partial z}, \qquad B_z = +\frac{\mu_0}{2\pi r}\,\frac{\partial G}{\partial r}\]| Name | Type | Unit | Description |
|---|---|---|---|
r_obs | array-like | m | Observation major radius. |
z_obs | array-like | m | Observation height. |
r_src | array-like | m | Source major radius. |
z_src | array-like | m | Source height. |
| Returns | |||
br | np.ndarray | T/A | Radial field per ampere. |
bz | np.ndarray | T/A | Vertical field per ampere. |
Convention
Right-handed $(r, \varphi, z)$, current in $+\varphi$; consistent with
green_psi_exact through $B_z = (1/r)\,\partial\psi/\partial r
\times 1/2\pi$ for a full-weber $\psi$.
Limitations · References
Limitations
Observation points on the geometric axis ($r_{obs} = 0$) return the analytic
limits $B_r = 0$, $B_z = \mu_0 r_0^2/(2(r_0^2 + (z - z_0)^2)^{3/2})$; the
coincident-point caveat of greens_function_exact applies.
References
- W. R. Smythe, Static and Dynamic Electricity, 3rd ed., McGraw-Hill (1968), Sec. 7.10.
green_psi_exact
Convention-sensitive
source
green_psi_exact(r_obs, z_obs, r_src, z_src)
Show source vaft/formula/green.py, lines 817–853
def green_psi_exact(r_obs, z_obs, r_src, z_src) -> np.ndarray:
r"""Poloidal flux per unit ring current, exact elliptic integrals.
$$\psi = \mu_0\,G(r, z; r_0, z_0)$$
with $G$ from :func:`greens_function_exact`.
Parameters
----------
r_obs : array-like
Observation major radius [m].
z_obs : array-like
Observation height [m].
r_src : array-like
Source major radius [m].
z_src : array-like
Source height [m].
Returns
-------
np.ndarray
Flux per ampere, broadcast over observation and source arrays [Wb/A].
Convention
----------
Full weber, the IMAS Data Dictionary storage (COCOS 11-18), same as
:func:`green_r`. The per-radian flux of an EFIT g-file or of
:func:`vaft.formula.equilibrium.poloidal_field_factor` with ``cocos=None``
is this divided by $2\pi$; mixing the two silently mis-scales fields by
$2\pi$. Tracked in #354.
References
----------
.. [1] J. D. Jackson, *Classical Electrodynamics*, 3rd ed., Wiley (1999),
Sec. 5.5.
"""
return MU0 * greens_function_exact(r_obs, z_obs, r_src, z_src, "psi")Poloidal flux per unit ring current, exact elliptic integrals.
\[\psi = \mu_0\,G(r, z; r_0, z_0)\]with $G$ from greens_function_exact.
| Name | Type | Unit | Description |
|---|---|---|---|
r_obs | array-like | m | Observation major radius. |
z_obs | array-like | m | Observation height. |
r_src | array-like | m | Source major radius. |
z_src | array-like | m | Source height. |
| Returns | |||
| — | np.ndarray | Wb/A | Flux per ampere, broadcast over observation and source arrays. |
Convention
Full weber, the IMAS Data Dictionary storage (COCOS 11-18), same as
green_r. The per-radian flux of an EFIT g-file or of
vaft.formula.equilibrium.poloidal_field_factor with cocos=None
is this divided by $2\pi$; mixing the two silently mis-scales fields by
$2\pi$. Tracked in #354.
References
References
- J. D. Jackson, Classical Electrodynamics, 3rd ed., Wiley (1999), Sec. 5.5.
green_r
Convention-sensitive
source
green_r(r_obs, z_obs, r_src, z_src)
Poloidal flux per unit ring current at observer points (legacy elliptic path).
\[\psi = 2\mu_0\,\frac{\sqrt{r r_0}}{k}\left[\left(1 - \frac{k^2}{2}\right)K - E\right], \qquad k^2 = \frac{4rr_0}{(r + r_0)^2 + (z - z_0)^2}\]| Name | Type | Unit | Description |
|---|---|---|---|
r_obs | np.ndarray | m | Radius of the observation points. |
z_obs | np.ndarray | m | Height of the observation points. |
r_src | float | m | Radius of the current ring. |
z_src | float | m | Height of the current ring. |
| Returns | |||
| — | np.ndarray | Wb/A | Flux per ampere at each observation point. |
Convention
Full weber ($\psi = \mu_0 G$, identical to green_psi_exact up to
the elliptic-integral approximation); divide by $2\pi$ before combining
with the per-radian equilibrium helpers. Tracked in #354.
Limitations · References
Limitations
Uses the Hastings polynomials of elliptic_integral; returns 0 on
the axis ($r_{obs} = 0$ or $r_{src} = 0$) and clips $k^2$ into $[0, 1]$.
References
- J. D. Jackson, Classical Electrodynamics, 3rd ed., Wiley (1999), Sec. 5.5, Eq. (5.37).
greens_function_2d
Convention-sensitive
source
greens_function_2d(R, Z, R0, Z0)
Show source vaft/formula/green.py, lines 193–236
def greens_function_2d(R: np.ndarray,
Z: np.ndarray,
R0: float,
Z0: float) -> np.ndarray:
r"""Axisymmetric kernel $\sqrt{RR_0}\,K(m)$ between a field point and a ring source.
$$G_{2D} = \sqrt{R R_0}\;K(m), \qquad
m = \frac{4RR_0}{(R + R_0)^2 + (Z - Z_0)^2}$$
Parameters
----------
R : np.ndarray
Major radius of the field points [m].
Z : np.ndarray
Height of the field points [m].
R0 : float
Major radius of the ring source [m].
Z0 : float
Height of the ring source [m].
Returns
-------
np.ndarray
Kernel value at each field point [m].
Convention
----------
This is the leading term of the ring-current flux function, *not* the flux
Green's function itself: the poloidal flux per unit current is
$\mu_0\sqrt{RR_0}\,[(2 - m)K(m) - 2E(m)]/\sqrt{m}$
(:func:`greens_function_exact`, :func:`green_psi_exact`). Use those for
any physical field; this kernel is kept for the legacy integrals below.
Limitations
-----------
Diverges logarithmically at the source point; no guard.
References
----------
.. [1] J. D. Jackson, *Classical Electrodynamics*, 3rd ed., Wiley (1999),
Sec. 5.5 (vector potential of a circular loop).
"""
k2 = 4 * R * R0 / ((R + R0)**2 + (Z - Z0)**2)
return np.sqrt(R * R0) * complete_elliptic_integral_k(k2)Axisymmetric kernel $\sqrt{RR_0}\,K(m)$ between a field point and a ring source.
\[G_{2D} = \sqrt{R R_0}\;K(m), \qquad m = \frac{4RR_0}{(R + R_0)^2 + (Z - Z_0)^2}\]| Name | Type | Unit | Description |
|---|---|---|---|
R | np.ndarray | m | Major radius of the field points. |
Z | np.ndarray | m | Height of the field points. |
R0 | float | m | Major radius of the ring source. |
Z0 | float | m | Height of the ring source. |
| Returns | |||
| — | np.ndarray | m | Kernel value at each field point. |
Convention
This is the leading term of the ring-current flux function, not the flux
Green’s function itself: the poloidal flux per unit current is
$\mu_0\sqrt{RR_0}\,[(2 - m)K(m) - 2E(m)]/\sqrt{m}$
(greens_function_exact, green_psi_exact). Use those for
any physical field; this kernel is kept for the legacy integrals below.
Limitations · References
Limitations
Diverges logarithmically at the source point; no guard.
References
- J. D. Jackson, Classical Electrodynamics, 3rd ed., Wiley (1999), Sec. 5.5 (vector potential of a circular loop).
greens_function_3d
source
greens_function_3d(R, Z, phi, R0, Z0, phi0)
Show source vaft/formula/green.py, lines 239–297
def greens_function_3d(R: np.ndarray,
Z: np.ndarray,
phi: np.ndarray,
R0: float,
Z0: float,
phi0: float) -> np.ndarray:
r"""Toroidal-angle-resolved variant of the $\sqrt{RR_0}\,K(m)$ kernel.
$$G_{3D} = \sqrt{R R_0}\;K(m), \qquad
m = \frac{4RR_0}{(R + R_0)^2 + (Z - Z_0)^2 + 4RR_0\sin^2\!\big(\tfrac{\varphi - \varphi_0}{2}\big)}$$
Parameters
----------
R : np.ndarray
Major radius of the field points [m].
Z : np.ndarray
Height of the field points [m].
phi : np.ndarray
Toroidal angle of the field points [rad].
R0 : float
Major radius of the source [m].
Z0 : float
Height of the source [m].
phi0 : float
Toroidal angle of the source [rad].
Returns
-------
np.ndarray
Kernel value at each field point [m].
Limitations
-----------
Not the Biot-Savart kernel of a point source, and the difference is exact
rather than vague. The chord between two points in a torus is
$$d^2 = (R - R_0)^2 + (Z - Z_0)^2
+ 4RR_0\sin^2\!\big(\tfrac{\varphi - \varphi_0}{2}\big),$$
while the ring kernel's denominator is
$(R + R_0)^2 + (Z - Z_0)^2 = (R - R_0)^2 + (Z - Z_0)^2 + 4RR_0$. A point
source therefore *replaces* the $4RR_0$ with
$4RR_0\sin^2(\Delta\varphi/2)$; this expression **adds** the second term to
the first, so the two coincide only at $\Delta\varphi = 0$, where the
$\sin^2$ vanishes and the ring result is recovered.
That $\Delta\varphi = 0$ reduction is the one property worth relying on.
Away from it the expression decays with toroidal separation in a way that
has no recorded derivation, so it should not be read as a field. Tracked in
#356: it needs either a derivation or a replacement, and it has no
production caller today.
References
----------
.. [1] J. D. Jackson, *Classical Electrodynamics*, 3rd ed., Wiley (1999),
Sec. 5.5.
"""
k2 = 4 * R * R0 / ((R + R0)**2 + (Z - Z0)**2 + 4 * R * R0 * np.sin((phi - phi0)/2)**2)
return np.sqrt(R * R0) * complete_elliptic_integral_k(k2)Toroidal-angle-resolved variant of the $\sqrt{RR_0}\,K(m)$ kernel.
\[G_{3D} = \sqrt{R R_0}\;K(m), \qquad m = \frac{4RR_0}{(R + R_0)^2 + (Z - Z_0)^2 + 4RR_0\sin^2\!\big(\tfrac{\varphi - \varphi_0}{2}\big)}\]| Name | Type | Unit | Description |
|---|---|---|---|
R | np.ndarray | m | Major radius of the field points. |
Z | np.ndarray | m | Height of the field points. |
phi | np.ndarray | rad | Toroidal angle of the field points. |
R0 | float | m | Major radius of the source. |
Z0 | float | m | Height of the source. |
phi0 | float | rad | Toroidal angle of the source. |
| Returns | |||
| — | np.ndarray | m | Kernel value at each field point. |
Limitations · References
Limitations
Not the Biot-Savart kernel of a point source, and the difference is exact rather than vague. The chord between two points in a torus is
\[d^2 = (R - R_0)^2 + (Z - Z_0)^2 + 4RR_0\sin^2\!\big(\tfrac{\varphi - \varphi_0}{2}\big),\]while the ring kernel’s denominator is $(R + R_0)^2 + (Z - Z_0)^2 = (R - R_0)^2 + (Z - Z_0)^2 + 4RR_0$. A point source therefore replaces the $4RR_0$ with $4RR_0\sin^2(\Delta\varphi/2)$; this expression adds the second term to the first, so the two coincide only at $\Delta\varphi = 0$, where the $\sin^2$ vanishes and the ring result is recovered.
That $\Delta\varphi = 0$ reduction is the one property worth relying on. Away from it the expression decays with toroidal separation in a way that has no recorded derivation, so it should not be read as a field. Tracked in #356: it needs either a derivation or a replacement, and it has no production caller today.
References
- J. D. Jackson, Classical Electrodynamics, 3rd ed., Wiley (1999), Sec. 5.5.
greens_function_exact
Convention-sensitive
source
greens_function_exact(r, z, r0, z0, mode='psi')
Exact free-space axisymmetric Green’s function and its derivatives.
\[G(r, z; r_0, z_0) = \frac{\sqrt{rr_0}}{k}\left[(2 - k^2)K(k^2) - 2E(k^2)\right], \qquad k^2 = m = \frac{4rr_0}{(r + r_0)^2 + (z - z_0)^2}\]so that $\psi = \mu_0 I\,G$ is the poloidal flux of a ring current $I$;
mode selects $G$, $\partial G/\partial r$, $\partial G/\partial z$,
$\partial^2G/\partial r\partial z$, $\partial^2G/\partial r^2$, or the raw
$K$ and $E$.
| Name | Type | Unit | Description |
|---|---|---|---|
r | array-like | m | Observation major radius. |
z | array-like | m | Observation height. |
r0 | array-like | m | Source major radius. |
z0 | array-like | m | Source height. |
mode | str, optional | str | One of |
| Returns | |||
| — | np.ndarray | any | Requested quantity, broadcast over all four coordinates. $G$ is in m, its derivatives in m per m, $K$ and $E$ dimensionless. |
Convention
Full weber: $\psi = \mu_0 G$ per ampere (same as green_r), and
$B_z = +\mu_0/(2\pi r)\,\partial G/\partial r$, $B_r = -\mu_0/(2\pi r)\,
\partial G/\partial z$. The equilibrium helpers assume flux per radian by
default, so divide by $2\pi$ (or pass cocos) before feeding this flux to
vaft.formula.equilibrium.vertical_magnetic_field_from_psi.
Raises
ValueErrorUnknownmodeor coordinates giving $m$ outside $[0, 1]$.
Limitations · Numerical notes · References
Limitations
Points with $rr_0 = 0$ return their analytic limits (0 for every mode except
d2psi_dr2, whose on-axis limit is $\pi r_0^2/(r_0^2 + (z - z_0)^2)^{3/2}$).
The elliptic parameter is clamped just below 1, so a coincident observer and
source return finite numbers, but those are artifacts of the clamp, not
physical limits (the ideal-filament self term diverges): handle genuinely
coincident pairs yourself, e.g. with self_inductance or a
shifted-evaluation scheme such as compute_br_bz_phi.
Numerical notes
scipy.special.ellipk/ellipe on the parameter $m$; every $1/k$,
$1/m$ and $1/r$ is guarded and overwritten on axis. The d2psi_dr2
branch corrects a sign error in the legacy VFIT getGreenFunction.m
case 7 ($-2(r + r_0)A$, from $d(1/D)/dr = -D’/D^2$) and is validated
against finite differences of dpsi_dr.
References
- J. D. Jackson, Classical Electrodynamics, 3rd ed., Wiley (1999), Sec. 5.5, Eq. (5.37).
- Legacy VFIT
getGreenFunction.m(modes 1-7), the reference algorithm.
greens_integral_2d
source
greens_integral_2d(R, Z, R0, Z0, f)
Show source vaft/formula/green.py, lines 304–341
def greens_integral_2d(R: np.ndarray,
Z: np.ndarray,
R0: float,
Z0: float,
f: np.ndarray) -> float:
r"""Line integral along $R$ of the 2-D kernel times a source density.
$$I = \int G_{2D}(R, Z; R_0, Z_0)\,f(R)\,dR$$
Parameters
----------
R : np.ndarray
Major radius of the samples, monotonic [m].
Z : np.ndarray
Height of the samples [m].
R0 : float
Major radius of the source [m].
Z0 : float
Height of the source [m].
f : np.ndarray
Source density at the samples [any].
Returns
-------
float
Integral in units of ``f`` times m^2 [any].
Limitations
-----------
Integrates along the single supplied ``R`` array (a line, not an area) with
the kernel of :func:`greens_function_2d`; not a flux or field.
Numerical notes
---------------
Trapezoidal rule.
"""
G = greens_function_2d(R, Z, R0, Z0)
return trapz_integral(R, G * f)Line integral along $R$ of the 2-D kernel times a source density.
\[I = \int G_{2D}(R, Z; R_0, Z_0)\,f(R)\,dR\]| Name | Type | Unit | Description |
|---|---|---|---|
R | np.ndarray | m | Major radius of the samples, monotonic. |
Z | np.ndarray | m | Height of the samples. |
R0 | float | m | Major radius of the source. |
Z0 | float | m | Height of the source. |
f | np.ndarray | any | Source density at the samples. |
| Returns | |||
| — | float | any | Integral in units of |
Limitations · Numerical notes
Limitations
Integrates along the single supplied R array (a line, not an area) with
the kernel of greens_function_2d; not a flux or field.
Numerical notes
Trapezoidal rule.
greens_integral_3d
source
greens_integral_3d(R, Z, phi, R0, Z0, phi0, f)
Show source vaft/formula/green.py, lines 344–386
def greens_integral_3d(R: np.ndarray,
Z: np.ndarray,
phi: np.ndarray,
R0: float,
Z0: float,
phi0: float,
f: np.ndarray) -> float:
r"""Line integral along $R$ of the 3-D kernel times a source density.
$$I = \int G_{3D}(R, Z, \varphi; R_0, Z_0, \varphi_0)\,f(R)\,dR$$
Parameters
----------
R : np.ndarray
Major radius of the samples, monotonic [m].
Z : np.ndarray
Height of the samples [m].
phi : np.ndarray
Toroidal angle of the samples [rad].
R0 : float
Major radius of the source [m].
Z0 : float
Height of the source [m].
phi0 : float
Toroidal angle of the source [rad].
f : np.ndarray
Source density at the samples [any].
Returns
-------
float
Integral in units of ``f`` times m^2 [any].
Limitations
-----------
Same caveats as :func:`greens_integral_2d` and :func:`greens_function_3d`.
Numerical notes
---------------
Trapezoidal rule along ``R`` only.
"""
G = greens_function_3d(R, Z, phi, R0, Z0, phi0)
return trapz_integral(R, G * f)Line integral along $R$ of the 3-D kernel times a source density.
\[I = \int G_{3D}(R, Z, \varphi; R_0, Z_0, \varphi_0)\,f(R)\,dR\]| Name | Type | Unit | Description |
|---|---|---|---|
R | np.ndarray | m | Major radius of the samples, monotonic. |
Z | np.ndarray | m | Height of the samples. |
phi | np.ndarray | rad | Toroidal angle of the samples. |
R0 | float | m | Major radius of the source. |
Z0 | float | m | Height of the source. |
phi0 | float | rad | Toroidal angle of the source. |
f | np.ndarray | any | Source density at the samples. |
| Returns | |||
| — | float | any | Integral in units of |
Limitations · Numerical notes
Limitations
Same caveats as greens_integral_2d and greens_function_3d.
Numerical notes
Trapezoidal rule along R only.
mutual_inductance
source
mutual_inductance(r1, z1, dr1, dz1, r2, z2, dr2, dz2, *, tilt1=0.0, tilt2=0.0, turns1=1.0, turns2=1.0, mu_r=1.0, n_div=5)
Mutual inductance between two rectangular-cross-section ring coils.
\[M = N_1N_2\,\mu_r\mu_0\,\big\langle G(r_i, z_i; r_j, z_j)\big\rangle_{i \in 1,\ j \in 2}\]the Neumann formula evaluated as the mean flux linkage between midpoint filaments laid over each cross-section.
| Name | Type | Unit | Description |
|---|---|---|---|
r1 | float | m | Centre radius of coil 1. |
z1 | float | m | Centre height of coil 1. |
dr1 | float | m | Radial width of coil 1; 0 degenerates to a filament. |
dz1 | float | m | Height of coil 1; 0 degenerates to a filament. |
r2 | float | m | Centre radius of coil 2. |
z2 | float | m | Centre height of coil 2. |
dr2 | float | m | Radial width of coil 2. |
dz2 | float | m | Height of coil 2. |
tilt1 | float, optional | rad | Tilt of cross-section 1 about its centre; default 0. |
tilt2 | float, optional | rad | Tilt of cross-section 2; default 0. |
turns1 | float, optional | - | Turns of coil 1; default 1. |
turns2 | float, optional | - | Turns of coil 2; default 1. |
mu_r | float, optional | - | Relative permeability of the medium, e.g. 1.04 for SUS304; default 1. |
n_div | int, optional | - | Subdivision refinement; default 5. The cell size is half the pair’s characteristic scale over |
| Returns | |||
| — | float | H | Mutual inductance. |
Assumptions · Numerical notes · References
Assumptions
Axisymmetric coils with uniform current density over the cross-section; the toroidal curvature correction $r \to r\,(1 + (\cos\theta\,\Delta r/r)^2/24)$ is applied to each cell.
Numerical notes
Midpoint rule over both cross-sections (reference: legacy VFIT
getMutualInductanceCoil.m). The cell size uses the $z$-separation
$\sqrt{(r_1 + r_2)^2 + (z_1 - z_2)^2}$; the legacy code used $z_1 + z_2$,
which is not invariant under a rigid vertical translation. Legacy
material codes are intentionally not reproduced: pass mu_r explicitly.
References
- W. R. Smythe, Static and Dynamic Electricity, 3rd ed., McGraw-Hill (1968), Sec. 8.06 (mutual inductance of coaxial circles).
- Legacy VFIT
getMutualInductanceCoil.m.
self_inductance
source
self_inductance(r, dr, dz, *, tilt=0.0, turns=1.0, mu_r=1.0, n_div=5)
Self-inductance of a rectangular-cross-section ring coil.
\[L = \frac{N^2}{n^2}\left[\sum_{i \ne j}\mu_r\mu_0\,G(r_i, z_i; r_j, z_j) + \sum_i \mu_r\mu_0\,r_i\left(\ln\frac{8r_i}{s} - \frac{7}{4}\right)\right], \qquad s = \sqrt{\Delta r\,\Delta z/\pi}\]midpoint subdivision into $n$ cells with the analytic self-term of a circular filament of equivalent radius $s$ on the diagonal.
| Name | Type | Unit | Description |
|---|---|---|---|
r | float | m | Centre radius, positive. |
dr | float | m | Radial width, positive. |
dz | float | m | Height, positive. |
tilt | float, optional | rad | Tilt of the cross-section; default 0. |
turns | float, optional | - | Number of turns; default 1. |
mu_r | float, optional | - | Relative permeability; default 1. |
n_div | int, optional | - | Cells per centre radius; default 5. |
| Returns | |||
| — | float | H | Self-inductance. |
Raises
ValueErrorFor non-positiver,drordz.
Assumptions · Numerical notes · References
Assumptions
Uniform current density; the self-cell term is the low-frequency inductance of a thin ring of wire radius $s$ (internal inductance included, hence $7/4$ rather than 2).
Numerical notes
Reference: legacy VFIT getSelfInductanceCoil.m; nz is forced even.
Convergence in n_div is first order because of the self-cell
approximation.
References
- W. R. Smythe, Static and Dynamic Electricity, 3rd ed., McGraw-Hill (1968), Sec. 8.10 (self-inductance of a circular ring).
- Legacy VFIT
getSelfInductanceCoil.m.
trapz_integral
source
trapz_integral(x, y)
Show source vaft/formula/green.py, lines 40–66
def trapz_integral(x: np.ndarray, y: np.ndarray) -> float:
r"""Trapezoidal integral $\int y\,dx$, local copy for the Green kernels.
$$\int y\,dx \approx \sum_i \frac{y_i + y_{i+1}}{2}\,(x_{i+1} - x_i)$$
Parameters
----------
x : np.ndarray
Sample abscissae, monotonic [any].
y : np.ndarray
Integrand at the samples [any].
Returns
-------
float
Integral over the sampled range, in units of ``y`` times ``x`` [any].
Numerical notes
---------------
Identical to :func:`vaft.formula.utils.trapz_integral` (``numpy.trapezoid``
via :func:`vaft.compat.trapz_compat`); this copy is the one
``vaft.formula.trapz_integral`` resolves to, and it is kept because
``test_formula_lazy_namespace`` pins that shadowing. The reason it was
written -- that importing ``utils`` dragged in scikit-learn -- is gone
since #426.
"""
return float(trapz_compat(y, x=x))Trapezoidal integral $\int y\,dx$, local copy for the Green kernels.
\[\int y\,dx \approx \sum_i \frac{y_i + y_{i+1}}{2}\,(x_{i+1} - x_i)\]| Name | Type | Unit | Description |
|---|---|---|---|
x | np.ndarray | any | Sample abscissae, monotonic. |
y | np.ndarray | any | Integrand at the samples. |
| Returns | |||
| — | float | any | Integral over the sampled range, in units of |
Numerical notes
Numerical notes
Identical to vaft.formula.utils.trapz_integral (numpy.trapezoid
via vaft.compat.trapz_compat); this copy is the one
vaft.formula.trapz_integral resolves to, and it is kept because
test_formula_lazy_namespace pins that shadowing. The reason it was
written – that importing utils dragged in scikit-learn – is gone
since #426.