2This contains utility functions and definitions used in calc_tilts_prec_avg_regularized.py and
3hybrid_spin_evolution.py
5N. K. Johnson-McDaniel, 2021
10from lal
import G_SI, C_SI, MSUN_SI
13from warnings
import warn
23class Error(Exception):
24 """Base class for exceptions in this module"""
28 """Exception raised when the evolution finds that the system is nonprecessing to numerical accuracy."""
35class Warn(UserWarning):
36 """Base class for warnings in this module"""
39class ValueWarning(Warn):
40 """Warning raised when an input is dubious"""
46 return '%s: %s\n'%(category.__name__, message)
48warnings.formatwarning = warning_formatter
54 return "%s: %s"%(type(err).__name__, err)
58 if m1 <= 0.
or m2 <= 0.:
60 "The input masses must both be positive, while they are m1, m2 = %e, %e kg" % (m1, m2))
62 if m1 < 0.09*MSUN_SI
or m2 < 0.09*MSUN_SI:
63 warn(
"One or both of the masses is rather small: m1 = %e kg = %e Msun, m2 = %e kg = %e Msun. "
64 "The masses must be input in kg." % (m1, m1/MSUN_SI, m2, m2/MSUN_SI), ValueWarning)
71 "Cannot compute tilts at infinity for exactly equal-mass binaries, as those quantities are not well "
72 "defined in this case.")
75 "The computation of the bounds and average value of the tilts is not yet implemented for exactly "
76 "equal-mass binaries.")
80 if chi1 < 0.
or chi1 > 1.
or chi2 < 0.
or chi2 > 1.:
82 "The magnitudes of the spins must both be between 0 and 1, while they are chi1, chi2 = %f, %f" % (chi1, chi2))
86 if tilt1 < 0.
or tilt1 > np.pi
or tilt2 < 0.
or tilt2 > np.pi:
88 "The tilt angles must both be between 0 and pi, while they are tilt1, tilt2 = %f, %f" % (tilt1, tilt2))
94 "The reference frequency must be positive, while it is fref = %f Hz" % fref)
96 f_ISCO = 6.**(-1.5)/(np.pi*(m1 + m2)*kg_to_s)
99 warn(
"The reference frequency should not be close to merger, where the %s evolution is highly inaccurate, "
100 "while it is fref = %f Hz, which is greater than the Schwarzschild ISCO frequency associated "
101 "with the binary's total mass of %f Hz"%(evol_type, fref, f_ISCO), ValueWarning)
107 Lf
is None or not. Also swaps the tilts
if necessary. Only works
in the case when Lf
is not None when the
108 min, max,
and average values are all the same.
113 Lf: Final orbital angular momentum (here just acts
as a switch depending on whether it
is None or not)
114 swap: Whether to swap tilt1
and tilt2 before returning (
True)
or not (
False)
116 Output: dictionary
with entries
'tilt1_inf',
'tilt2_inf' for evolution to infinity--Lf
is None--
and entries
117 'tilt1_sep_min',
'tilt1_sep_max',
'tilt1_sep_avg',
'tilt2_sep_min',
'tilt2_sep_max',
'tilt2_sep_avg'
118 for evolution to a finite separation (i.e., a finite orbital angular momentum), when Lf
is not None
122 tilt1, tilt2 = tilt2, tilt1
125 return {
'tilt1_inf': tilt1,
'tilt2_inf': tilt2}
127 return {
'tilt1_sep_min': tilt1,
'tilt1_sep_max': tilt1,
'tilt1_sep_avg': tilt1,
'tilt2_sep_min': tilt2,
128 'tilt2_sep_max': tilt2,
'tilt2_sep_avg': tilt2}
131def evolution_error_handling(failure_mode, failure_message, failure_output, failure_output_string, Lf, swap, hybrid_evol=False):
133 Take care of the error message or warning
and returning something
for the tilts when the
134 precession-averaged evolution fails. Append entries
for tilts at transition
in the case where hybrid evolution fails.
137 failure_mode: The failure mode (either
"Error",
"NAN",
or "None")
138 failure_message: The message to
print in the error
or warning
139 failure output: What to output
for the tilts
in the event of a failure
140 failure_output_string: The string associated
with the failure output
141 Lf: Final orbital angular momentum (here just acts
as a switch depending on whether it
is None or not)
142 swap: Whether to swap tilt1
and tilt2 before returning (
True)
or not (
False)
143 hybrid_evol: Flag to invoke error handling
in the hybrid evolution code. Default:
False
145 Output: dictionary
with entries
'tilt1_inf',
'tilt2_inf' for evolution to infinity--Lf
is None--
and entries
146 'tilt1_sep_min',
'tilt1_sep_max',
'tilt1_sep_avg',
'tilt2_sep_min',
'tilt2_sep_max',
'tilt2_sep_avg'
147 for evolution to a finite separation (i.e., a finite orbital angular momentum), when Lf
is not None.
148 The entries of the dictionary are failure_output
149 If hybrid_evol
is set to
True, entries
'tilt1_transition',
'tilt2_transition',
'phi12_transition',
and 'f_transition' set
as failure_output are appended to match the output of the hybrid evolution code.
152 if failure_mode ==
'Error':
153 raise RuntimeError(failure_message)
155 failure_message +=
" Returning %s for the tilts."%failure_output_string
157 warn(failure_message, RuntimeWarning)
160 hybrid_output_tilts =
package_tilts(failure_output, failure_output, Lf, swap)
161 hybrid_output_tilts[
"tilt1_transition"] = failure_output
162 hybrid_output_tilts[
"tilt2_transition"] = failure_output
163 hybrid_output_tilts[
"phi12_transition"] = failure_output
164 hybrid_output_tilts[
"f_transition"] = failure_output
165 return hybrid_output_tilts
167 return package_tilts(failure_output, failure_output, Lf, swap)
Base class for exceptions in this module.
Exception raised when the evolution finds that the system is nonprecessing to numerical accuracy.
def __init__(self, message)
Base class for warnings in this module.
def prec_avg_tilt_comp(m1, m2, chi1, chi2, tilt1, tilt2, phi12, fref, Lf=None, **kwargs)
Compute tilt angles at infinite separation or bounds and average value of tilt angles at finite separ...
def prec_avg_tilt_comp_vec_inputs(m1, m2, chi1_vec, chi2_vec, fref, L0_vec=None, Lf=None, du=1.e-3, ode_atol_base=1.e-8, ode_atol_inplane_spin_scaling=True, ode_atol_floor=1.e-13, ode_rtol=-1, method="lsoda", use_solve_ivp=False, solve_ivp_lsoda_min_step=0., use_fallback=True, du_fallback=1.e-5, ode_atol_fallback=1.e-13, ode_rtol_fallback=-1, method_fallback="lsoda", use_mpmath_fallback=True, mpmath_dps=30, ode_tol_mpmath=1.e-15, odefun_degree=None, polyroots_maxsteps=50, polyroots_extraprec=50, LPNorder=2, LPNspins=True, imag_tol=1.e-6, root_tol=1.e-6, lin_tol=-1, lin_tol_fallback=-1, root_tol_raise_err=False, failure_mode='None', version='v1')
Compute tilt angles at infinite separation or bounds and average value of tilt angles at finite separ...
def evolution_error_handling(failure_mode, failure_message, failure_output, failure_output_string, Lf, swap, hybrid_evol=False)
Take care of the error message or warning and returning something for the tilts when the precession-a...
def warning_formatter(message, category, filename, lineno, file=None, line=None)
def package_tilts(tilt1, tilt2, Lf, swap)
Package tilts to be returned by prec_avg_tilt_comp_vec_inputs() or prec_avg_tilt_comp() depending on ...
def check_tilts(tilt1, tilt2)
def check_fref(fref, m1, m2, evol_type)
def eq_mass_check(m1, m2, Lf)
def check_spin_mags(chi1, chi2)