magnus.matter

matter.py

Contains helper functions to compute the oscillation probability in matter.

This module contains routines to common matter density profiles (e.g., constant, exponentially decreasing), electron number density, and coherent forward scattering potential.

Routine listings

  • density_matter_func_const - Returns the density for a constant

    matter density profile

  • density_matter_func_exp - Returns the density for an exponentially

    decreasing matter density profile

  • exp_density_profile - Builds an exponential density-profile

    callable tagged for the fast interaction-picture integrator

  • num_density_e_func - Converts a matter density to an electron

    number density

  • VCC_func - Returns the potential for coherent forward electron

    scattering

  • vcc_func_from_rho_func - Builds a VCC function (or constant) from

    a density profile, handling neutrino/antineutrino sign and unit conversion

Attributes

IMPLAUSIBLE_DENSITY_G_PER_CM3

Module-level constant

IMPLAUSIBLE_DENSITY_NATURAL_UNITS

Module-level constant

Exceptions

DensityUnitWarning

Warns that a matter density declared to be in

Functions

density_matter_func_const(→ float)

Returns the matter density as a function of position, assuming a

density_matter_func_exp(→ float)

Returns the matter density as a function of position, assuming

exp_density_profile(→ Callable)

Builds an exponential density-profile callable tagged for the fast interaction-picture

num_density_e_func(→ float)

Converts matter density [\(\text{g cm}^{-3}\)] to electron number density

VCC_func(→ float)

Computes and returns the coherent forward electron potential,

vcc_func_from_rho_func(→ Union[int, float, Callable])

Builds a V_CC function (or constant) from a density profile.

Module Contents

exception magnus.matter.DensityUnitWarning[source]

Bases: UserWarning

Warns that a matter density declared to be in \(\text{g cm}^{-3}\) is too large to be one, and was most likely already converted to natural units.

The conversion factor is \(4.3 \times 10^{18}\), so converting a second time inflates the matter potential far beyond anything physical. What makes it worth a warning is that the result does not look wrong: the matter term dominates every other scale, \(\nu_e\) becomes an exact eigenstate of the Hamiltonian, and the calculation returns a perfectly self-consistent \(P_{ee} = 1\). That reads as a broken formula rather than as a bad input.

Added in version 1.0.0.

magnus.matter.density_matter_func_const(l: float, density_matter_const: float | None = gd.DENSITY_MATTER_CRUST_G_PER_CM3) float[source]

Returns the matter density as a function of position, assuming a constant density. Used for testing purposes.

Returns the matter density as a function of position, assuming a constant density. Used for testing purposes.

Added in version 1.0.0.

Parameters:
  • l (float) – Position at which the density profile is evaluated (in this case, the profile is uniform, so any value of l returns the same constant density).

  • density_matter_const (float) – Matter density [\(\text{g cm}^{-3}\)]

Returns:

Matter density [\(\text{g cm}^{-3}\)]

Return type:

float

magnus.matter.density_matter_func_exp(l: float, density_matter_central: float, l_scale: float) float[source]

Returns the matter density as a function of position, assuming an exponentially decreasing density profile.

Returns the matter density as a function of position, assuming an exponentially decreasing density profile of the form

\[\rho(l) = \rho_0\, e^{-l/l_\text{scale}} ,\]

for given values of the central density \(\rho_0\) (density_matter_central) and the length scale \(l_\text{scale}\) (l_scale).

Added in version 1.0.0.

Parameters:
  • l (float) – Position at which the density profile is evaluated.

  • density_matter_central (float) – Matter density at the center of the profile (l = 0) [\(\text{g cm}^{-3}\)]

  • l_scale (float) – Length scale of the exponential density decrease.

Returns:

Matter density [\(\text{g cm}^{-3}\)]

Return type:

float

magnus.matter.exp_density_profile(density_matter_central: float, l_scale: float) Callable[source]

Builds an exponential density-profile callable tagged for the fast interaction-picture integrator.

Same functional form as density_matter_func_exp() (curried over density_matter_central and l_scale so it can be passed directly as rho_func), but the returned callable also carries an l_scale attribute and an is_exp_density_profile marker set to True. magnus.oscprob.osc_prob_matter_std_potential(), magnus.oscprob.osc_prob_matter_nsi(), and magnus.oscprob.osc_prob_liv() look for this marker (propagated through vcc_func_from_rho_func()) to detect a genuine exponential profile and automatically switch to the much faster interaction-picture Magnus integrator (see _osc_prob_ip_exp_dispatch), with a transparent fallback to the general slab-refinement method whenever the fast method does not converge (e.g., near an MSW resonance). A plain lambda with the same functional form would work numerically but, lacking the marker, would silently skip the fast path – always build exponential profiles through this function (or osc_prob_*_exp_density/osc_prob_*_sun*, which already do) to get the speed-up.

Added in version 1.0.0.

Parameters:
  • density_matter_central (float) – Matter density (or electron number density) at the center of the profile (l = 0).

  • l_scale (float) – Length scale of the exponential density decrease.

Returns:

Function of position, l, tagged with is_exp_density_profile = True and l_scale = l_scale.

Return type:

Callable

Examples

import magnus.globaldefs as gd
from magnus import matter

profile = matter.exp_density_profile(gd.NUM_DENSITY_E_SUN_CENTRAL,
                                     gd.L_SCALE_SUN)

for frac in (0.0, 0.1, 0.5):
    print('l = %.1f R_sun -> n_e = %.3e eV^3'
          % (frac, profile(frac*gd.SUN_RADIUS*gd.UNIT_KM)))
l = 0.0 R_sun -> n_e = 1.134e+12 eV^3
l = 0.1 R_sun -> n_e = 3.951e+11 eV^3
l = 0.5 R_sun -> n_e = 5.831e+09 eV^3
magnus.matter.IMPLAUSIBLE_DENSITY_G_PER_CM3 = 1e+16[source]

Module-level constant

Matter density [\(\text{g cm}^{-3}\)] above which a value declared to be in g cm^-3 is almost certainly already in natural units, and about to be converted a second time.

The two scales do not overlap. The densest matter anyone models is a neutron star interior at some \(10^{15}\ \text{g cm}^{-3}\), while any density from water upwards becomes \(4.3 \times 10^{18}\) or more once multiplied by gd.UNIT_G_PER_CM3 – so a converted value re-declared as g cm^-3 lands at least three orders of magnitude above anything physical.

Double conversion is silent and its consequences do not look like a unit mistake: it inflates the matter potential by ~18 orders of magnitude, which makes \(\nu_e\) an exact eigenstate everywhere and returns a perfectly self-consistent \(P_{ee} = 1\). That reads as a broken formula, not as a bad input, so it is worth catching where it happens.

Added in version 1.0.0.

Type:

float

magnus.matter.IMPLAUSIBLE_DENSITY_NATURAL_UNITS = 10000000000.0[source]

Module-level constant

Matter density in natural units below which a value declared not to be in g cm^-3 is almost certainly a g cm^-3 number whose density_matter_is_in_g_per_cm3 flag was left at its default of False.

This is the mirror of IMPLAUSIBLE_DENSITY_G_PER_CM3, and it guards the commoner mistake. The flag defaults to False, so a density read straight off a table – 2.848 for the Earth’s crust, 13 for its core, 150 for the Sun’s centre – is taken as already converted unless the caller says otherwise. Anything physical is \(4.3 \times 10^{18}\) or more in natural units, so a table value lands nine orders of magnitude below this threshold, which itself sits at \(2 \times 10^{-9}\ \text{g cm}^{-3}\) – six orders more tenuous than air, and far below any medium in which anyone computes oscillations.

Under-conversion is quieter than double conversion. It does not inflate anything; it makes the matter potential vanish, and the call returns exactly the vacuum probability. That is a perfectly ordinary-looking number, in the right range, of the right shape, and nothing about it suggests matter was left out – which is why it is worth catching where it happens.

Deliberate vacuum is not caught: a density of exactly zero is left alone.

Added in version 1.0.0.

Type:

float

magnus.matter.num_density_e_func(l: float, density_matter_func: Callable, ratio_number_neutrons_to_protons: float | None = 1.0, electron_fraction: float | None = 0.5, density_matter_is_in_g_per_cm3: bool | None = False) float[source]

Converts matter density [\(\text{g cm}^{-3}\)] to electron number density [\(\text{eV}^{3}\)], for a given matter density profile and position.

Converts the matter density [\(\text{g cm}^{-3}\)] to electron number density [\(\text{eV}^{3}\)], for a given matter density profile, density_matter_func, and position, l. Matter is assumed to be isoscalar, with the fraction of electrons given by electron_fraction.

Added in version 1.0.0.

Parameters:
  • l (float) – Position at which the density profile is evaluated.

  • density_matter_func (Callable) – Matter density as a function of l [\(\text{g cm}^{-3}\)] (or, if density_matter_is_in_g_per_cm3 is False, already in natural units).

  • ratio_number_neutrons_to_protons (float, optional) – Ratio of the number of neutrons to protons in matter, used to compute the average nucleon mass. Default: 1.0.

  • electron_fraction (float, optional) – Electron fraction. Default: 0.5.

  • density_matter_is_in_g_per_cm3 (bool, optional) – If True, density_matter_func returns the density in \(\text{g cm}^{-3}\) and it is converted to natural units internally; if False, it is assumed to already be in natural units. Default: False.

Returns:

Number density of electrons [\(\text{eV}^{3}\)]

Return type:

float

magnus.matter.VCC_func(l: float, num_density_e_func: Callable) float[source]

Computes and returns the coherent forward electron potential, V_CC, at position l, for a given electron number density, num_density_e_func.

Computes and returns the coherent forward electron potential, V_CC, at position l, for a given electron number density profile, num_density_e_func.

Added in version 1.0.0.

Parameters:
  • l (float) – Position at which the density profile is evaluated.

  • num_density_e_func (Callable) – Electron number density as a function of l [\(\text{eV}^{3}\)].

Returns:

Coherent forward electron potntial, V_CC [eV]

Return type:

float

Examples

import magnus.globaldefs as gd
from magnus import matter

profile = matter.exp_density_profile(gd.NUM_DENSITY_E_SUN_CENTRAL,
                                     gd.L_SCALE_SUN)
print('V_CC at the centre of the Sun: %.3e eV'
      % matter.VCC_func(0.0, profile))
V_CC at the centre of the Sun: 1.870e-11 eV
magnus.matter.vcc_func_from_rho_func(rho_func: Callable | int | float, L0: int | float | None = 0.0, ratio_number_neutrons_to_protons: int | float | None = 1.0, electron_fraction: int | float | None = 0.5, nubar: bool | None = False, density_matter_is_in_g_per_cm3: bool | None = False, density_is_of_number_of_electrons: bool | None = False) int | float | Callable[source]

Builds a V_CC function (or constant) from a density profile.

Builds the coherent forward-scattering potential, V_CC, from a matter- or electron-density profile, handling the neutrino/antineutrino sign of V_CC and the unit conversion in one place. This is the function that magnus.oscprob.osc_prob_matter_std_potential() and its NSI/LIV counterparts call to turn a user- or environment-supplied density (e.g., a constant, an exponential profile, or the Earth’s PREM profile) into the VCC_func consumed by the hamiltonian_*nu_matter_td/hamiltonian_*nu_nsi_td functions.

Added in version 1.0.0.

Parameters:
  • rho_func (Callable or int or float) – Matter density (or, if density_is_of_number_of_electrons is True, electron number density directly), either as a function of position, l, or as a single constant value.

  • L0 (int or float, optional) – Reference position at which to evaluate a constant rho_func (irrelevant when rho_func is a genuine constant, since the returned V_CC is then position-independent by construction). Default: 0.0.

  • ratio_number_neutrons_to_protons (int or float, optional) – Ratio of the number of neutrons to protons in matter. Default: 1.0.

  • electron_fraction (int or float, optional) – Electron fraction. Default: 0.5.

  • nubar (bool, optional) – If True, flip the sign of \(V_\text{CC}\) (electrons couple to \(\nu_e\) and \(\bar{\nu}_e\) with opposite-sign weak charge). Default: False.

  • density_matter_is_in_g_per_cm3 (bool, optional) – If True, rho_func returns the matter density in \(\text{g cm}^{-3}\); if False, it is assumed to already be in natural units. Ignored if density_is_of_number_of_electrons is True. Default: False.

  • density_is_of_number_of_electrons (bool, optional) – If True, rho_func directly returns the electron number density [\(\text{eV}^{3}\)], skipping the matter-density-to-electron-density conversion. Default: False.

Returns:

V_CC [eV], as a function of position if rho_func is a function, or as a constant (evaluated once, at L0) if rho_func is a constant.

Return type:

int, float, or Callable