gstlal-inspiral  0.4.2
 All Classes Namespaces Files Functions Variables Pages
chirptime.py
1 # Copyright (C) 2015 Jolien Creighton
2 #
3 # This program is free software; you can redistribute it and/or modify it
4 # under the terms of the GNU General Public License as published by the
5 # Free Software Foundation; either version 2 of the License, or (at your
6 # option) any later version.
7 #
8 # This program is distributed in the hope that it will be useful, but
9 # WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
11 # Public License for more details.
12 #
13 # You should have received a copy of the GNU General Public License along
14 # with this program; if not, write to the Free Software Foundation, Inc.,
15 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 
17 import sys
18 from math import pi
19 import numpy
20 import lalsimulation as lalsim
21 import warnings
22 
23 def tmplttime(f0, m1, m2, j1, j2, approx):
24  dt = 1.0 / 16384.0
25  approximant = lalsim.GetApproximantFromString(approx)
26  hp, hc = lalsim.SimInspiralChooseTDWaveform(
27  phiRef=0,
28  deltaT=dt,
29  m1=m1,
30  m2=m2,
31  s1x=0,
32  s1y=0,
33  s1z=j1,
34  s2x=0,
35  s2y=0,
36  s2z=j2,
37  f_min=f0,
38  f_ref=0,
39  r=1,
40  i=0,
41  lambda1=0,
42  lambda2=0,
43  waveFlags=None,
44  nonGRparams=None,
45  amplitudeO=0,
46  phaseO=0,
47  approximant=approximant)
48  h = numpy.array(hp.data.data, dtype=complex)
49  h += 1j * numpy.array(hc.data.data, dtype=complex)
50  try:
51  n = list(abs(h)).index(0)
52  except ValueError:
53  n = len(h)
54  return n * hp.deltaT
55 
56 
57 GMsun = 1.32712442099e20 # heliocentric gravitational constant, m^2 s^-2
58 G = 6.67384e-11 # Newtonian constant of gravitation, m^3 kg^-1 s^-2
59 c = 299792458 # speed of light in vacuum (exact), m s^-1
60 Msun = GMsun / G # solar mass, kg
61 
62 def velocity(f, M):
63  """
64  Finds the orbital "velocity" corresponding to a gravitational
65  wave frequency.
66  """
67  return (pi * G * M * f)**(1.0/3.0) / c
68 
69 def chirptime(f, M, nu, chi):
70  """
71  Over-estimates the chirp time in seconds from a certain frequency.
72  Uses 2 pN chirp time from some starting frequency f in Hz
73  where all negative contributions are dropped.
74  """
75  v = velocity(f, M)
76  tchirp = 1.0
77  tchirp += ((743.0/252.0) + (11.0/3.0)*nu) * v**2
78  tchirp += (226.0/15.0) * chi * v**3
79  tchirp += ((3058673.0/508032.0) + (5429.0/504.0)*nu + (617.0/72.0)*nu**2) * v**4
80  tchirp *= (5.0/(256.0*nu)) * (G*M/c**3) / v**8
81  return tchirp
82 
83 def ringf(M, j):
84  """
85  Computes the approximate ringdown frequency in Hz.
86  Here j is the reduced Kerr spin parameter, j = c^2 a / G M.
87  """
88  return (1.5251 - 1.1568 * (1 - j)**0.1292) * (c**3 / (2.0 * pi * G * M))
89 
90 def ringtime(M, j):
91  """
92  Computes the black hole ringdown time in seconds.
93  Here j is the reduced Kerr spin parameter, j = c^2 a / G M.
94  """
95  efolds = 11
96  # these are approximate expressions...
97  f = ringf(M, j)
98  Q = 0.700 + 1.4187 * (1 - j)**-0.4990
99  T = Q / (pi * f)
100  return efolds * T
101 
102 def mergetime(M):
103  """
104  Over-estimates the time from ISCO to merger in seconds.
105  Assumes one last orbit at the maximum ISCO radius.
106  """
107  # The maximum ISCO is for orbits about a Kerr hole with
108  # maximal counter rotation. This corresponds to a radius
109  # of 9GM/c^2 and a orbital speed of ~ c/3. Assume the plunge
110  # and merger takes one orbit from this point.
111  norbits = 1.0
112  v = c / 3.0
113  r = 9.0 * G * M / c**2
114  return norbits * (2.0 * pi * r / v)
115 
116 def overestimate_j_from_chi(chi):
117  """
118  Overestimate final black hole spin
119  """
120  return min(max(lalsim.SimIMREOBFinalMassSpin(1, 1, [0, 0, chi], [0, 0, chi], lalsim.GetApproximantFromString('SEOBNRv2'))[2], abs(chi)), 0.998)
121 
122 def imr_time(f, m1, m2, j1, j2, f_max = None):
123  """
124  Returns an overestimate of the inspiral time and the
125  merger-ringdown time, both in seconds. Here, m1 and m2
126  are the component masses in kg, j1 and j2 are the dimensionless
127  spin parameters of the components.
128  """
129 
130  if f_max is not None and f_max < f:
131  raise ValueError("f_max must either be None or greater than f")
132 
133  # compute total mass and symmetric mass ratio
134  M = m1 + m2
135  nu = m1 * m2 / M**2
136 
137  # compute spin parameters
138  #chi_s = 0.5 * (j1 + j2)
139  #chi_a = 0.5 * (j1 - j2)
140  #chi = (1.0 - (76.0/113.0)) * chi_s + ((m1 - m2) / M) * chi_a
141  # overestimate chi:
142  chi = max(j1, j2)
143 
144  j = overestimate_j_from_chi(chi)
145 
146  if f > ringf(M, j):
147  warnings.warn("f is greater than the ringdown frequency. This might not be what you intend to compute")
148 
149  if f_max is None or f_max > ringf(M, j):
150  return chirptime(f, M, nu, chi) + mergetime(M) + ringtime(M, j)
151  else:
152  # Always be conservative and allow a merger time to be added to
153  # the end in case your frequency is above the last stable orbit
154  # but below the ringdown.
155  return imr_time(f, m1, m2, j1, j2) - imr_time(f_max, m1, m2, j1, j2)