LALSimulation  5.4.0.1-89842e6
bh_qnmode.c
Go to the documentation of this file.
1 /*
2 * Copyright (C) 2007 Jolien Creighton
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with with program; see the file COPYING. If not, write to the
16 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17 * MA 02110-1301 USA
18 */
19 
20 /**
21  * @defgroup lalsim_bh_qnmode lalsim-bh-qnmode
22  * @ingroup lalsimulation_programs
23  *
24  * @brief Computes the quasi-normal modes of a black hole
25  *
26  * ### Synopsis
27  *
28  * lalsim-bh-qnmode [-h] [-L] [-M Msolar] [-a a] -l l -m m -s s
29  *
30  * ### Description
31  *
32  * The `lalsim-bh-qnmode` utility prints the eigenvalues of a black hole
33  * quasinormal mode with spin weight @p s (use -2 for gravitational quasinormal
34  * modes) and mode numbers @p l and @p m for given black hole dimensionless
35  * spin if the spin @p a is specified using the argument `-a`; or prints a
36  * table of mode eigenvalues if @p a is not specified; or prints frequency and
37  * quality factor if mass @p Msolar is specified.
38  *
39  * The utility uses Leaver's conventions (G = c = 2M = 1) if the option
40  * `--leaver` is used
41  *
42  * ### Options
43  *
44  * <DL>
45  * <DT>`-h`, `--help`</DT>
46  * <DD>print a help message and exit</DD>
47  * <DT>`-L, --leaver`</DT>
48  * <DD>use Leaver's conventions: G = c = 2M = 1</DD>
49  * <DT>`-M` Msolar</DT>
50  * <DD>(optional) set black hole mass (solar masses)</DD>
51  * <DT>`-a` a</DT>
52  * <DD>(optional) set value of dimensionless spin parameter a/M, |a/M|<1 (Leaver: |a/M|<0.5)</DD>
53  * <DT>`-l` l</DT>
54  * <DD>(required) set value of mode number l, l>=0</DD>
55  * <DT>`-m` m</DT>
56  * <DD>(required) set value of mode number m, abs(m)<=l</DD>
57  * <DT>`-s` s</DT>
58  * <DD>(required) set value of spin weight s, s<=0</DD>
59  * </DL>
60  *
61  * ### Environment
62  *
63  * The `LAL_DEBUG_LEVEL` can used to control the error and warning reporting of
64  * `lalsim-bh-qnmode`. Common values are: `LAL_DEBUG_LEVEL=0` which suppresses
65  * error messages, `LAL_DEBUG_LEVEL=1` which prints error messages alone,
66  * `LAL_DEBUG_LEVEL=3` which prints both error messages and warning messages,
67  * and `LAL_DEBUG_LEVEL=7` which additionally prints informational messages.
68  *
69  * ### Exit Status
70  *
71  * The `lalsim-bh-qnmode` utility exits 0 on success, and >0 if an error
72  * occurs.
73  *
74  * ### Example
75  *
76  * The command:
77  *
78  * lalsim-bh-qnmode -a 0.97 -M 10 -l 2 -m 2 -s -2
79  *
80  * outputs the freqeuency and quality factor for black hole ringdown
81  * gravitational radiation in the l = m = 2 quasinormal mode for a
82  * M = 10 solar mass hole with Kerr spin parameter a = 0.97 M.
83  *
84  * The command:
85  *
86  * lalsim-bh-qnmode -L -l 2 -m 0 -s -2
87  *
88  * prints a table of Kerr quasinormal frequencies and angular separation
89  * constants for the fundamental mode corresponding to l = 2 and m = 1
90  * for gravitational perturbations (s = -2) in Leaver's conventions:
91  *
92 @verbatim
93 # quasinormal mode table for l=2 m=0 s=-2 (Leaver's conventions)
94 # a A omega
95 0.0000 (4.00000,+0.00000) (+0.747343,-0.177925)
96 0.1000 (3.99722,+0.00139) (+0.750248,-0.177401)
97 0.2000 (3.98856,+0.00560) (+0.759363,-0.175653)
98 0.3000 (3.97297,+0.01262) (+0.776108,-0.171989)
99 0.4000 (3.94800,+0.02226) (+0.803835,-0.164313)
100 0.4500 (3.93038,+0.02763) (+0.824009,-0.156965)
101 0.4900 (3.91269,+0.03152) (+0.844509,-0.147065)
102 0.4999 (3.90770,+0.03227) (+0.850231,-0.143650)
103 
104 0.0000 (4.00000,-0.00000) (-0.747343,-0.177925)
105 0.1000 (3.99722,-0.00139) (-0.750248,-0.177401)
106 0.2000 (3.98856,-0.00560) (-0.759363,-0.175653)
107 0.3000 (3.97297,-0.01262) (-0.776108,-0.171989)
108 0.4000 (3.94800,-0.02226) (-0.803835,-0.164313)
109 0.4500 (3.93038,-0.02763) (-0.824009,-0.156965)
110 0.4900 (3.91269,-0.03152) (-0.844509,-0.147065)
111 0.4999 (3.90770,-0.03227) (-0.850231,-0.143650)
112 @endverbatim
113  *
114  * Compare with Table 3 of E. W. Leaver, "An analytic representation of
115  * quasi-normal modes of Kerr black holes", Proc. R. Soc. Lond. A @b 402 285
116  * (1985).
117  */
118 
119 #include <limits.h>
120 #include <math.h>
121 #include <stdio.h>
122 #include <stdlib.h>
123 
124 #include <lal/LALStdlib.h>
125 #include <lal/LALgetopt.h>
126 #include <lal/LALConstants.h>
127 #include <lal/LALSimBlackHoleRingdown.h>
128 
129 #define a_invalid -100.0 /* invalid */
130 #define l_invalid (INT_MIN + 1) /* invalid */
131 #define m_invalid (INT_MAX) /* invalid */
132 #define s_invalid (INT_MAX) /* invalid */
133 REAL8 M = 0.0;
135 int l = l_invalid;
136 int m = m_invalid;
137 int s = s_invalid;
138 int leaver = 0;
139 
140 int usage(const char *program);
141 int parseargs(int argc, char **argv);
142 int output_mode_table(void);
143 int output_mode(void);
144 
145 
147 {
148  double avec[] = {0.0,0.1,0.2,0.3,0.4,0.45,0.49,0.4999};
149  int asign;
150  size_t numa = XLAL_NUM_ELEM(avec);
151  size_t i;
152 
153  fprintf(stdout, "# quasinormal mode table for l=%d m=%d s=%d ", l, m, s);
154  if (leaver)
155  fprintf(stdout, "(Leaver's conventions)\n");
156  else
157  fprintf(stdout, "(standard conventions)\n");
158  if (M == 0.0)
159  fprintf(stdout, "# a \t %s \t omega\n", leaver ? "A" : "E");
160  else
161  fprintf(stdout, "# a \t frequency (Hz) \t quality \n");
162 
163  /* do positive spins first, then do negative spins */
164  for (asign = 1; abs(asign) == 1; asign -= 2) {
165  for (i = 0; i < numa; ++i) {
166  COMPLEX16 A, omega;
167  a = avec[i];
168  XLALSimBlackHoleRingdownModeEigenvaluesLeaver(&A, &omega, asign*a, l, m, s);
169  if (!leaver) { /* convert to standard conventions */
170  a *= 2.0;
171  omega *= 0.5;
172  A += s*(s+1);
173  }
174  if (M == 0.0)
175  fprintf(stdout, "%.4f \t(%.5f,%+.5f)\t(%+.6f,%.6f)\n", a, creal(A), cimag(A), creal(omega), cimag(omega));
176  else {
177  double f, Q;
178  f = fabs(creal(omega) / (LAL_TWOPI * M * LAL_MTSUN_SI));
179  Q = fabs(creal(omega)) / (-2.0 * cimag(omega));
180  fprintf(stdout, "%.4f \t %12.3f \t\t %8.3f\n", a, f, Q);
181  }
182  }
183  if (asign == 1)
184  fprintf(stdout, "\n");
185  }
186  return 0;
187 }
188 
189 int output_mode(void)
190 {
191  COMPLEX16 A, omega;
192 
193  if (!leaver) /* spin was not specified in Leaver conventions */
194  a *= 0.5; /* change to Leaver conventions */
195 
197 
198  if (!leaver) { /* change from Leaver conventions */
199  omega *= 0.5;
200  a *= 2.0;
201  }
202 
203  /*
204  * if mass has been specified, return f and Q
205  * otherwise return omega in either leaver or standard conventions
206  */
207 
208  fprintf(stdout, "using %s conventions\n", leaver ? "Leaver's" : "standard");
209  fprintf(stdout, "mode l = %d, m = %d, s = %d\n", l, m, s);
210  fprintf(stdout, "spin a = %g (dimensionless)\n", a);
211  fprintf(stdout, "M * omega = (%+.6f,%+.6f)\n", creal(omega), cimag(omega));
212  if (M != 0.0) {
213  double f, Q;
214  f = fabs(creal(omega) / (LAL_TWOPI * M * LAL_MTSUN_SI));
215  Q = fabs(creal(omega)) / (-2.0 * cimag(omega));
216 
217  fprintf(stdout, "mass M = %g solar masses\n", M);
218  fprintf(stdout, "frequency f = %g Hz\n", f);
219  fprintf(stdout, "quality Q = %g\n", Q);
220  }
221 
222  return 0;
223 }
224 
225 
226 int main(int argc, char *argv[])
227 {
229 
230  parseargs(argc, argv);
231 
232  if (a == a_invalid)
234  else
235  output_mode();
236 
238  return 0;
239 }
240 
241 int parseargs( int argc, char **argv )
242 {
243  struct LALoption long_options[] = {
244  { "help", no_argument, 0, 'h' },
245  { "leaver", no_argument, 0, 'L' },
246  { "mass", required_argument, 0, 'M' },
247  { "spin", required_argument, 0, 'a' },
248  { "l", required_argument, 0, 'l' },
249  { "m", required_argument, 0, 'm' },
250  { "s", required_argument, 0, 's' },
251  { 0, 0, 0, 0 }
252  };
253  char args[] = "hLM:a:l:m:s:";
254  while (1) {
255  int option_index = 0;
256  int c;
257 
258  c = LALgetopt_long_only(argc, argv, args, long_options, &option_index);
259  if (c == -1) /* end of options */
260  break;
261 
262  switch (c) {
263  case 0: /* if option set a flag, nothing else to do */
264  if (long_options[option_index].flag)
265  break;
266  else {
267  fprintf(stderr, "error parsing option %s with argument %s\n", long_options[option_index].name, LALoptarg);
268  exit(1);
269  }
270  case 'h': /* help */
271  usage(argv[0]);
272  exit(0);
273  case 'L': /* leaver */
274  leaver = 1;
275  break;
276  case 'M': /* mass */
277  M = atof(LALoptarg);
278  break;
279  case 'a': /* spin */
280  a = atof(LALoptarg);
281  break;
282  case 'l':
283  l = atoi(LALoptarg);
284  break;
285  case 'm':
286  m = atoi(LALoptarg);
287  break;
288  case 's':
289  s = atoi(LALoptarg);
290  break;
291  case '?':
292  default:
293  fprintf(stderr, "unknown error while parsing options\n");
294  exit(1);
295  }
296  }
297 
298  if (LALoptind < argc) {
299  fprintf(stderr, "extraneous command line arguments:\n");
300  while (LALoptind < argc)
301  fprintf(stderr, "%s\n", argv[LALoptind++]);
302  exit(1);
303  }
304 
305  if (l == l_invalid || m == m_invalid || s == s_invalid) {
306  fprintf(stderr, "must specify l, m, and s\n");
307  usage(argv[0]);
308  exit(1);
309  }
310 
311  if (!(a == a_invalid || (leaver && fabs(a) < 0.5) || (!leaver && fabs(a) < 1.0))) {
312  fprintf(stderr, "must specify |a| < 1 (or |a| < 0.5 with Leaver's conventions)\n");
313  exit(1);
314  }
315 
316  if (leaver && M != 0.0) {
317  fprintf(stderr, "do not use both --leaver and --mass options\n");
318  usage(argv[0]);
319  exit(1);
320  }
321 
322  return 0;
323 }
324 
325 int usage(const char *program)
326 {
327  fprintf(stderr, "usage: %s [options]\n", program);
328  fprintf(stderr, "options:\n");
329  fprintf(stderr, "\t-h, --help \tprint this message and exit\n");
330  fprintf(stderr, "\t-L, --leaver \tuse Leaver's conventions\n");
331  fprintf(stderr, "\t-M Msolar \t(optional) set black hole mass (solar masses)\n");
332  fprintf(stderr, "\t-a a \t(optional) set value of a, |a|<1 (Leaver: |a|<0.5)\n");
333  fprintf(stderr, "\t-l l \t(required) set value of l, l>=0\n");
334  fprintf(stderr, "\t-m m \t(required) set value of m, abs(m)<=l\n");
335  fprintf(stderr, "\t-s s \t(required) set value of s, s<=0\n");
336  fprintf(stderr, "description:\n");
337  fprintf(stderr, "\tprints the eigenvalues for given a if a is specified\n");
338  fprintf(stderr, "\tprints a table of mode eigenvalues if a is not specified\n");
339  fprintf(stderr, "\tprints frequency and quality factor if mass is specified\n");
340  fprintf(stderr, "\tuses Leaver's conventions (G = c = 2M = 1) if --leaver is used\n");
341  return 0;
342 }
void LALCheckMemoryLeaks(void)
#define c
const char * name
int LALgetopt_long_only(int argc, char *const *argv, const char *options, const struct LALoption *long_options, int *opt_index)
int LALoptind
char * LALoptarg
#define no_argument
#define required_argument
#define fprintf
int leaver
Definition: bh_qnmode.c:138
int main(int argc, char *argv[])
Definition: bh_qnmode.c:226
int usage(const char *program)
Definition: bh_qnmode.c:325
int s
Definition: bh_qnmode.c:137
#define l_invalid
Definition: bh_qnmode.c:130
int parseargs(int argc, char **argv)
Definition: bh_qnmode.c:241
#define s_invalid
Definition: bh_qnmode.c:132
int output_mode(void)
Definition: bh_qnmode.c:189
REAL8 a
Definition: bh_qnmode.c:134
int m
Definition: bh_qnmode.c:136
int l
Definition: bh_qnmode.c:135
int output_mode_table(void)
Definition: bh_qnmode.c:146
#define m_invalid
Definition: bh_qnmode.c:131
REAL8 M
Definition: bh_qnmode.c:133
#define a_invalid
Definition: bh_qnmode.c:129
double i
Definition: bh_ringdown.c:118
const double Q
#define LAL_TWOPI
#define LAL_MTSUN_SI
#define XLAL_NUM_ELEM(x)
double complex COMPLEX16
double REAL8
int XLALSimBlackHoleRingdownModeEigenvaluesLeaver(COMPLEX16 *A, COMPLEX16 *omega, double a, int l, int m, int s)
Low-level routine that computes the black hole quasinormal mode eigenefrequency, omega,...
void XLALBacktraceErrorHandler(const char *func, const char *file, int line, int errnum)
XLALErrorHandlerType * XLALSetErrorHandler(XLALErrorHandlerType *newHandler)
char * program
Definition: inject.c:87
int * flag