Skip to content

Commit

Permalink
Merge pull request #1858 from kerrm/derived
Browse files Browse the repository at this point in the history
Provide physical formulas for magnetic field calculations.
  • Loading branch information
abhisrkckl authored Nov 21, 2024
2 parents 725400d + 3ad5f9b commit 10cfbdb
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 22 deletions.
3 changes: 3 additions & 0 deletions src/pint/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,9 @@
"hourangle_second": hourangle_second,
}

# define a units equivalency for gauss in cgs
gauss_equiv = [u.Gauss, u.Hz * (u.g / u.cm) ** (1 / 2), lambda x: x, lambda x: x]

import astropy.version

if astropy.version.major < 4:
Expand Down
57 changes: 37 additions & 20 deletions src/pint/derived_quantities.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,14 @@ def pferrs(
return (forp, forperr, fdorpd, fdorpderr)


def _to_gauss(B: u.Quantity) -> u.G:
"""Convert quantity with mass, length, and time units to Gauss.
In cgs units, magnetic field is has units (mass/length)^(1/2) / time.
"""
return B.to(u.Gauss, equivalencies=[pint.gauss_equiv])


@u.quantity_input(f=u.Hz, fdot=u.Hz / u.s, fo=u.Hz)
def pulsar_age(
f: u.Quantity, fdot: u.Quantity, n: int = 3, fo: u.Quantity = 1e99 * u.Hz
Expand Down Expand Up @@ -219,19 +227,27 @@ def pulsar_edot(
return (-4.0 * np.pi**2 * I * f * fdot).to(u.erg / u.s)


@u.quantity_input(f=u.Hz, fdot=u.Hz / u.s)
def pulsar_B(f: u.Quantity, fdot: u.Quantity) -> u.G:
@u.quantity_input(f=u.Hz, fdot=u.Hz / u.s, I=u.g * u.cm**2, R=u.km)
def pulsar_B(
f: u.Quantity,
fdot: u.Quantity,
I: u.Quantity = 1.0e45 * u.g * u.cm**2,
R: u.Quantity = 10 * u.km,
) -> u.G:
r"""Compute pulsar surface magnetic field
Return the estimated pulsar surface magnetic field strength
given the spin frequency and frequency derivative.
Return the pulsar surface magnetic field strength given the spin frequency `f` and frequency derivative `fdot`.
Parameters
----------
f : astropy.units.Quantity
pulsar frequency
fdot : astropy.units.Quantity
frequency derivative :math:`\dot f`
I : astropy.units.Quantity, optional
pulsar moment of inertia, default of 1e45 g*cm**2
R : astropy.units.Quantity, optional
pulsar radius, default of 10 km
Returns
-------
Expand All @@ -247,15 +263,19 @@ def pulsar_B(f: u.Quantity, fdot: u.Quantity) -> u.G:
Notes
-----
Calculates :math:`B=3.2\times 10^{19}\,{\rm G}\sqrt{ f \dot f^{-3}}`
Calculates :math:`B=\sqrt{\frac{3\,I\,c^3}{8\pi^2\,R^6}\times\frac{-\dot{f}}{f^3}}`
"""
# This is a hack to use the traditional formula by stripping the units.
# It would be nice to improve this to a proper formula with units
return 3.2e19 * u.G * np.sqrt(-fdot.to_value(u.Hz / u.s) / f.to_value(u.Hz) ** 3.0)
factor = (3.0 * I * const.c**3) / (8.0 * np.pi**2 * R**6)
return _to_gauss((factor * (-fdot) / f**3) ** 0.5)


@u.quantity_input(f=u.Hz, fdot=u.Hz / u.s)
def pulsar_B_lightcyl(f: u.Quantity, fdot: u.Quantity) -> u.G:
@u.quantity_input(f=u.Hz, fdot=u.Hz / u.s, I=u.g * u.cm**2, R=u.km)
def pulsar_B_lightcyl(
f: u.Quantity,
fdot: u.Quantity,
I: u.Quantity = 1.0e45 * u.g * u.cm**2,
R=10 * u.km,
) -> u.G:
r"""Compute pulsar magnetic field at the light cylinder
Return the estimated pulsar magnetic field strength at the
Expand All @@ -268,6 +288,10 @@ def pulsar_B_lightcyl(f: u.Quantity, fdot: u.Quantity) -> u.G:
pulsar frequency
fdot : astropy.units.Quantity
frequency derivative :math:`\dot f`
I : astropy.units.Quantity, optional
pulsar moment of inertia, default of 1e45 g*cm**2
R : astropy.units.Quantity, optional
pulsar radius, default of 10 km
Returns
-------
Expand All @@ -283,17 +307,10 @@ def pulsar_B_lightcyl(f: u.Quantity, fdot: u.Quantity) -> u.G:
Notes
-----
Calculates :math:`B_{LC} = 2.9\times 10^8\,{\rm G} P^{-5/2} \dot P^{1/2}`
Calculates :math:`B_{LC} = \sqrt{\frac{-24\pi^4\,I}{c^3}\dot{f}f^3}`
"""
p, pd = p_to_f(f, fdot)
# This is a hack to use the traditional formula by stripping the units.
# It would be nice to improve this to a proper formula with units
return (
2.9e8
* u.G
* p.to_value(u.s) ** (-5.0 / 2.0)
* np.sqrt(pd.to(u.dimensionless_unscaled).value)
)
factor = 24.0 * np.pi**4.0 * I / const.c**3.0
return _to_gauss((factor * (-fdot) * f**3.0) ** 0.5)


@u.quantity_input(pb=u.d, x=u.cm)
Expand Down
4 changes: 2 additions & 2 deletions tests/test_derived_quantities.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,15 +67,15 @@ def test_Edot():
def test_Bfield():
# B
assert np.isclose(
pulsar_B(0.033 * u.Hz, -2.0e-15 * u.Hz / u.s), 238722891596281.66 * u.G
pulsar_B(0.033 * u.Hz, -2.0e-15 * u.Hz / u.s), 238693670891966.22 * u.G
)


def test_Blc():
# B_lc
assert np.isclose(
pulsar_B_lightcyl(0.033 * u.Hz, -2.0e-15 * u.Hz / u.s),
0.07774704753236616 * u.G,
0.07896965114785195 * u.G,
)


Expand Down

0 comments on commit 10cfbdb

Please sign in to comment.