Loading [MathJax]/extensions/TeX/AMSsymbols.js
LALSimulation 6.2.0.1-5e288d3
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
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
950.0000 (4.00000,+0.00000) (+0.747343,-0.177925)
960.1000 (3.99722,+0.00139) (+0.750248,-0.177401)
970.2000 (3.98856,+0.00560) (+0.759363,-0.175653)
980.3000 (3.97297,+0.01262) (+0.776108,-0.171989)
990.4000 (3.94800,+0.02226) (+0.803835,-0.164313)
1000.4500 (3.93038,+0.02763) (+0.824009,-0.156965)
1010.4900 (3.91269,+0.03152) (+0.844509,-0.147065)
1020.4999 (3.90770,+0.03227) (+0.850231,-0.143650)
103
1040.0000 (4.00000,-0.00000) (-0.747343,-0.177925)
1050.1000 (3.99722,-0.00139) (-0.750248,-0.177401)
1060.2000 (3.98856,-0.00560) (-0.759363,-0.175653)
1070.3000 (3.97297,-0.01262) (-0.776108,-0.171989)
1080.4000 (3.94800,-0.02226) (-0.803835,-0.164313)
1090.4500 (3.93038,-0.02763) (-0.824009,-0.156965)
1100.4900 (3.91269,-0.03152) (-0.844509,-0.147065)
1110.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 */
133REAL8 M = 0.0;
138int leaver = 0;
139
140int usage(const char *program);
141int parseargs(int argc, char **argv);
142int output_mode_table(void);
143int 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];
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
189int 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
226int 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
241int 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
325int 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