Loading [MathJax]/extensions/TeX/AMSsymbols.js
LALSimulation 6.2.0.1-b246709
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
LALSimIMRSpinEOBInitialConditions.c
Go to the documentation of this file.
1#include <lal/LALSimInspiral.h>
2#include <lal/LALSimIMR.h>
3
4#include <gsl/gsl_vector.h>
5#include <gsl/gsl_matrix.h>
6#include <gsl/gsl_blas.h>
7
8#include <gsl/gsl_multiroots.h>
9#include <gsl/gsl_deriv.h>
10
11#include "LALSimIMRSpinEOB.h"
14/* OPTIMIZED */
17/* END OPTIMIZED */
19
20#ifndef _LALSIMIMRSPINEOBINITIALCONDITIONS_C
21#define _LALSIMIMRSPINEOBINITIALCONDITIONS_C
22
23/**
24 * Structure consisting SEOBNR parameters that can be used by gsl root finders
25 */
26typedef
27struct tagSEOBRootParams
28{
29 REAL8 values[12]; /**<< Dynamical variables, x, y, z, px, py, pz, S1x, S1y, S1z, S2x, S2y and S2z */
30 SpinEOBParams *params; /**<< Spin EOB parameters -- physical, pre-computed, etc. */
31 REAL8 omega; /**<< Orbital frequency */
33}
35
36/**
37 * Calculates the dot product of two vectors
38 */
39static inline
41CalculateDotProduct( const REAL8 a[], const REAL8 b[] )
42{
43 return a[0]*b[0] + a[1]*b[1] + a[2]*b[2];
44}
45
46
47/**
48 * calculates the ith component of the cross product of two vectors,
49 * where i is in the range 0-2.
50 */
51static inline
53CalculateCrossProduct( const INT4 i, const REAL8 a[], const REAL8 b[] )
54{
55 return a[(i+1)%3]*b[(i+2)%3] - a[(i+2)%3]*b[(i+1)%3];
56}
57
58
59/**
60 * Normalizes the given vector
61 */
62static inline
63int
65{
66 REAL8 norm = sqrt( a[0]*a[0] + a[1]*a[1] + a[2]*a[2] );
67
68 a[0] /= norm;
69 a[1] /= norm;
70 a[2] /= norm;
71
72 return XLAL_SUCCESS;
73}
74
75/**
76 * Calculate the rotation matrix and its inverse.
77 * Rotate the ex-ey-ez frame to the r-v-L frame.
78 * This static function is called only by XLALSimIMRSpinEOBInitialConditions
79 */
80static int
82 gsl_matrix *rotMatrix, /**< OUTPUT, rotation matrix */
83 gsl_matrix *rotInverse, /**< OUTPUT, rotation matrix inversed */
84 REAL8 r[], /**< position vector */
85 REAL8 v[], /**< velocity vector */
86 REAL8 L[] /**< orbital angular momentum */
87 )
88{
89
90 /** a, b, g are the angles alpha, beta and gamma */
91 /* Use a, b and g to avoid shadowing gamma and getting a warning */
92 REAL8 a, b, g;
93 REAL8 cosa, sina, cosb, sinb, cosg, sing;
94
95 /* Calculate the Euclidean Euler angles */
96
97 /* We need to avoid a singularity if L is along z axis */
98 if ( L[2] > 0.9999 )
99 {
100 a = b = g = 0.0;
101 }
102 else
103 {
104 a = atan2( L[0], -L[1] );
105 b = atan2( sqrt( L[0]*L[0] + L[1]*L[1] ), L[2] );
106 g = atan2( r[2], v[2] );
107 }
108
109 if ( ( cosa = cos( a ) ) < 1.0e-16 ) cosa = 0.0;
110 if ( ( sina = sin( a ) ) < 1.0e-16 ) sina = 0.0;
111 if ( ( cosb = cos( b ) ) < 1.0e-16 ) cosb = 0.0;
112 if ( ( sinb = sin( b ) ) < 1.0e-16 ) sinb = 0.0;
113 if ( ( cosg = cos( g ) ) < 1.0e-16 ) cosg = 0.0;
114 if ( ( sing = sin( g ) ) < 1.0e-16 ) sing = 0.0;
115
116/**
117 * Implement the Rotation Matrix following the "x-convention"
118 * 1. rotate about the z-axis by an angle a, rotation matrix Rz(a);
119 * 2. rotate about the former x-axis (now x') by an angle b, rotation matrix Rx(b);
120 * 3. rotate about the former z-axis (now z') by an algle g, rotation matrix Rz(g);
121 */
122 /* populate the matrix */
123 gsl_matrix_set( rotMatrix, 0, 0, cosg*cosa - cosb*sina*sing );
124 gsl_matrix_set( rotMatrix, 0, 1, cosg*sina + cosb*cosa*sing );
125 gsl_matrix_set( rotMatrix, 0, 2, sing*sinb );
126 gsl_matrix_set( rotMatrix, 1, 0, -sing*cosa - cosb*sina*cosg );
127 gsl_matrix_set( rotMatrix, 1, 1, -sing*sina + cosb*cosa*cosg );
128 gsl_matrix_set( rotMatrix, 1, 2, cosg*sinb );
129 gsl_matrix_set( rotMatrix, 2, 0, sinb*sina );
130 gsl_matrix_set( rotMatrix, 2, 1, -sinb*cosa );
131 gsl_matrix_set( rotMatrix, 2, 2, cosb );
132
133 /* Now populate the transpose (which should be the inverse) */
134 gsl_matrix_transpose_memcpy( rotInverse, rotMatrix );
135
136 /* Test that the code does what it should do */
137 /* gsl_matrix *ab = gsl_matrix_alloc( 3, 3 );
138 gsl_blas_dgemm( CblasNoTrans, CblasNoTrans, 1., rotMatrix, rotInverse, 0., ab );
139 */
140
141 /*printf( "The generated rotation matrix:?\n" );
142 for ( int i = 0; i < 3; i++ )
143 {
144 for ( int j = 0; j < 3; j++ )
145 {
146 printf( "%.16e\t", gsl_matrix_get( rotMatrix, i, j ) );
147 }
148 printf( "\n" );
149 }*/
150
151 /*printf( "Is the transpose of the rotation matrix the inverse?\n" );
152 for ( int i = 0; i < 3; i++ )
153 {
154 for ( int j = 0; j < 3; j++ )
155 {
156 printf( "%.16e\t", gsl_matrix_get( ab, i, j ) );
157 }
158 printf( "\n" );
159 }*/
160 /*gsl_matrix_free( ab );*/
161
162 return XLAL_SUCCESS;
163}
164
165
166/**
167 * Applies a rotation matrix to a given vector
168 */
169static int
171 gsl_matrix *rotMatrix, /**< rotation matrix */
172 REAL8 a[] /**< OUTPUT, vector rotated */
173 )
174{
175
176 gsl_vector *tmpVec1 = gsl_vector_alloc( 3 );
177 gsl_vector *tmpVec2 = gsl_vector_calloc( 3 );
178
179 gsl_vector_set( tmpVec1, 0, a[0] );
180 gsl_vector_set( tmpVec1, 1, a[1] );
181 gsl_vector_set( tmpVec1, 2, a[2] );
182
183 gsl_blas_dgemv( CblasNoTrans, 1.0, rotMatrix, tmpVec1, 0.0, tmpVec2 );
184
185 a[0] = gsl_vector_get( tmpVec2, 0 );
186 a[1] = gsl_vector_get( tmpVec2, 1 );
187 a[2] = gsl_vector_get( tmpVec2, 2 );
188
189 gsl_vector_free( tmpVec1 );
190 gsl_vector_free( tmpVec2 );
191
192 return XLAL_SUCCESS;
193}
194
195/**
196 * Performs a co-ordinate transformation from spherical to Cartesian co-ordinates.
197 * In the code from Tyson Littenberg, this was only applicable to the special theta=pi/2, phi=0 case.
198 * This special transformation is a static function called only by
199 * GSLSpinHamiltonianDerivWrapper and XLALSimIMRSpinEOBInitialConditions
200 */
202 REAL8 qCart[], /**<< OUTPUT, position vector in Cartesean coordinates */
203 REAL8 pCart[], /**<< OUTPUT, momentum vector in Cartesean coordinates */
204 const REAL8 qSph[], /**<< position vector in spherical coordinates */
205 const REAL8 pSph[] /**<< momentum vector in spherical coordinates */
206 )
207{
208
209 REAL8 r;
210 REAL8 pr, pTheta, pPhi;
211
212 REAL8 x, y, z;
213 REAL8 pX, pY, pZ;
214
215 r = qSph[0];
216 pr = pSph[0];
217 pTheta = pSph[1];
218 pPhi = pSph[2];
219
220 x = r;
221 y = 0.0;
222 z = 0.0;
223
224 pX = pr;
225 pY = pPhi / r;
226 pZ = - pTheta / r;
227
228 /* Copy these values to the output vectors */
229 qCart[0] = x;
230 qCart[1] = y;
231 qCart[2] = z;
232 pCart[0] = pX;
233 pCart[1] = pY;
234 pCart[2] = pZ;
235
236 return XLAL_SUCCESS;
237}
238
239
240/**
241 * Perform a co-ordinate transformation from Cartesian to spherical co-ordinates.
242 * In the code from Tyson Littenberg, this was only applicable to the special theta=pi/2, phi=0 case.
243 * This special transformation is a static function called only by XLALSimIMRSpinEOBInitialConditions
244 */
246 REAL8 qSph[], /**<< OUTPUT, position vector in spherical coordinates */
247 REAL8 pSph[], /**<< OUTPUT, momentum vector in Cartesean coordinates */
248 const REAL8 qCart[], /**<< position vector in spherical coordinates */
249 const REAL8 pCart[] /**<< momentum vector in Cartesean coordinates */
250 )
251{
252
253 REAL8 r;
254 REAL8 pr, pTheta, pPhi;
255
256 REAL8 x; //, y, z;
257 REAL8 pX, pY, pZ;
258
259 x = qCart[0];
260 //y = qCart[1];
261 //z = qCart[2];
262 pX = pCart[0];
263 pY = pCart[1];
264 pZ = pCart[2];
265
266 r = x;
267 pr = pX;
268 pTheta = - r * pZ;
269 pPhi = r * pY;
270
271 /* Fill the output vectors */
272 qSph[0] = r;
273 qSph[1] = LAL_PI_2;
274 qSph[2] = 0.0;
275 pSph[0] = pr;
276 pSph[1] = pTheta;
277 pSph[2] = pPhi;
278
279 return XLAL_SUCCESS;
280}
281
282/**
283 * Root function for gsl root finders.
284 * The gsl root finder with look for gsl_vector *x position in parameter space
285 * where the returned values in gsl_vector *f are zero.
286 * The functions on which we search for roots are:
287 * dH/dr, dH/dptheta and dH/dpphi-omega,
288 * namely, Eqs. 4.8 and 4.9 of Buonanno et al. PRD 74, 104005 (2006).
289 */
290static int
291XLALFindSphericalOrbit( const gsl_vector *x, /**<< Parameters requested by gsl root finder */
292 void *params, /**<< Spin EOB parameters */
293 gsl_vector *f /**<< Function values for the given parameters */
294 )
295{
296 SEOBRootParams *rootParams = (SEOBRootParams *) params;
297
298 REAL8 py, pz, r, ptheta, pphi;
299
300 /* Numerical derivative of Hamiltonian wrt given value */
301 REAL8 dHdx, dHdpy, dHdpz;
302 REAL8 dHdr, dHdptheta, dHdpphi;
303
304 /* Populate the appropriate values */
305 /* In the special theta=pi/2 phi=0 case, r is x */
306 rootParams->values[0] = r = gsl_vector_get( x, 0 );
307 rootParams->values[4] = py = gsl_vector_get( x, 1 );
308 rootParams->values[5] = pz = gsl_vector_get( x, 2 );
309
310 // printf( "Values r = %.16e, py = %.16e, pz = %.16e\n", r, py, pz );
311
312 ptheta = - r * pz;
313 pphi = r * py;
314
315 /* dHdR */
316 dHdx = XLALSpinHcapNumDerivWRTParam( 0, rootParams->values, rootParams->params );
317 if ( XLAL_IS_REAL8_FAIL_NAN( dHdx ) )
318 {
320 }
321 //printf( "dHdx = %.16e\n", dHdx );
322
323 /* dHdPphi (I think we can use dHdPy in this coord system) */
324 /* TODO: Check this is okay */
325 dHdpy = XLALSpinHcapNumDerivWRTParam( 4, rootParams->values, rootParams->params );
326 if ( XLAL_IS_REAL8_FAIL_NAN( dHdpy ) )
327 {
329 }
330
331 /* dHdPtheta (I think we can use dHdPz in this coord system) */
332 /* TODO: Check this is okay */
333 dHdpz = XLALSpinHcapNumDerivWRTParam( 5, rootParams->values, rootParams->params );
334 if ( XLAL_IS_REAL8_FAIL_NAN( dHdpz ) )
335 {
337 }
338
339 /* Now convert to spherical polars */
340 dHdr = dHdx - dHdpy * pphi / (r*r) + dHdpz * ptheta / (r*r);
341 dHdptheta = - dHdpz / r;
342 dHdpphi = dHdpy / r;
343
344 /* populate the function vector */
345 gsl_vector_set( f, 0, dHdr );
346 gsl_vector_set( f, 1, dHdptheta );
347 gsl_vector_set( f, 2, dHdpphi - rootParams->omega );
348
349 //printf( "Current funcvals = %.16e %.16e %.16e\n", gsl_vector_get( f, 0 ), gsl_vector_get( f, 1 ),
350 // gsl_vector_get( f, 2 )/*dHdpphi*/ );
351
352 return XLAL_SUCCESS;
353}
354
355/**
356 * Wrapper for calculating specific derivative of the Hamiltonian in spherical co-ordinates,
357 * dH/dr, dH/dptheta and dH/dpphi.
358 * It only works for the specific co-ord system we use here
359 */
360static double GSLSpinHamiltonianDerivWrapperHybrid( double x, /**<< Derivative at x */
361 void *params /**<< Function parameters */)
362{
363
365 REAL8 sphValues[12];
366 REAL8 cartValues[12];
367
368 REAL8 dHdr, dHdx, dHdpy, dHdpz;
369 REAL8 r, ptheta, pphi;
370
371 memcpy( sphValues, dParams->sphValues, sizeof( sphValues ) );
372 sphValues[dParams->varyParam1] = x;
373
374 SphericalToCartesian( cartValues, cartValues+3, sphValues, sphValues+3 );
375 memcpy( cartValues+6, sphValues+6, 6*sizeof(REAL8) );
376
377 r = sphValues[0];
378 ptheta = sphValues[4];
379 pphi = sphValues[5];
380
381 /* Return the appropriate derivative according to varyParam2 */
382
383 switch ( dParams->varyParam2 )
384 {
385 case 0:
386 /* dHdr */
387 dHdx = XLALSpinHcapHybDerivWRTParam( 0, cartValues, dParams->params );
388 dHdpy = XLALSpinHcapHybDerivWRTParam( 4, cartValues, dParams->params );
389 dHdpz = XLALSpinHcapHybDerivWRTParam( 5, cartValues, dParams->params );
390
391 dHdr = dHdx - dHdpy * pphi / (r*r) + dHdpz * ptheta / (r*r);
392 //printf( "dHdr = %.16e\n", dHdr );
393 return dHdr;
394
395 break;
396 case 4:
397 /* dHdptheta */
398 dHdpz = XLALSpinHcapHybDerivWRTParam( 5, cartValues, dParams->params );
399 return - dHdpz / r;
400 break;
401 case 5:
402 /* dHdpphi */
403 dHdpy = XLALSpinHcapHybDerivWRTParam( 4, cartValues, dParams->params );
404 return dHdpy / r;
405 break;
406 default:
407 XLALPrintError( "This option is not supported in the second derivative function!\n" );
409 break;
410 }
411}
412
413
414/**
415 * Wrapper for calculating specific derivative of the Hamiltonian in spherical co-ordinates,
416 * dH/dr, dH/dptheta and dH/dpphi.
417 * It only works for the specific co-ord system we use here
418 */
419static double GSLSpinHamiltonianDerivWrapper( double x, /**<< Derivative at x */
420 void *params /**<< Function parameters */)
421{
422
424
425 REAL8 sphValues[12];
426 REAL8 cartValues[12];
427
428 REAL8 dHdr, dHdx, dHdpy, dHdpz;
429 REAL8 r, ptheta, pphi;
430
431 memcpy( sphValues, dParams->sphValues, sizeof( sphValues ) );
432 sphValues[dParams->varyParam1] = x;
433
434 SphericalToCartesian( cartValues, cartValues+3, sphValues, sphValues+3 );
435 memcpy( cartValues+6, sphValues+6, 6*sizeof(REAL8) );
436
437 r = sphValues[0];
438 ptheta = sphValues[4];
439 pphi = sphValues[5];
440
441 /* Return the appropriate derivative according to varyParam2 */
442 switch ( dParams->varyParam2 )
443 {
444 case 0:
445 /* dHdr */
446 dHdx = XLALSpinHcapNumDerivWRTParam( 0, cartValues, dParams->params );
447 dHdpy = XLALSpinHcapNumDerivWRTParam( 4, cartValues, dParams->params );
448 dHdpz = XLALSpinHcapNumDerivWRTParam( 5, cartValues, dParams->params );
449
450 dHdr = dHdx - dHdpy * pphi / (r*r) + dHdpz * ptheta / (r*r);
451 //printf( "dHdr = %.16e\n", dHdr );
452 return dHdr;
453
454 break;
455 case 4:
456 /* dHdptheta */
457 dHdpz = XLALSpinHcapNumDerivWRTParam( 5, cartValues, dParams->params );
458 return - dHdpz / r;
459 break;
460 case 5:
461 /* dHdpphi */
462 dHdpy = XLALSpinHcapNumDerivWRTParam( 4, cartValues, dParams->params );
463 return dHdpy / r;
464 break;
465 default:
466 XLALPrintError( "This option is not supported in the second derivative function!\n" );
468 break;
469 }
470}
471
472static REAL8 XLALCalculateSphHamiltonianDeriv2Hybrid( const int idx1, /**<< Derivative w.r.t. index 1 */
473 const int idx2, /**<< Derivative w.r.t. index 2 */
474 const REAL8 values[], /**<< Dynamical variables in spherical coordinates */
475 SpinEOBParams *params /**<< Spin EOB Parameters */
476 )
477{
478 static const REAL8 STEP_SIZE = 1.0e-4;
479
480 REAL8 result;
481 REAL8 UNUSED absErr;
482
483 HcapSphDeriv2Params dParams;
484
485 gsl_function F;
486 INT4 UNUSED gslStatus;
487
488 dParams.sphValues = values;
489 dParams.varyParam1 = idx1;
490 dParams.varyParam2 = idx2;
491 dParams.params = params;
492
494 F.params = &dParams;
495 XLAL_CALLGSL( gslStatus = gsl_deriv_central( &F, values[idx1],
496 STEP_SIZE, &result, &absErr ) );
497
498 if ( gslStatus != GSL_SUCCESS )
499 {
500 XLALPrintError( "XLAL Error %s - Failure in GSL function\n", __func__ );
502 }
503 return result;
504}
505
506
507/* Function to calculate the second derivative of the Hamiltonian. */
508/* The derivatives are taken with respect to indices idx1, idx2 */
510 const int idx1, /**<< Derivative w.r.t. index 1 */
511 const int idx2, /**<< Derivative w.r.t. index 2 */
512 const REAL8 values[], /**<< Dynamical variables in spherical coordinates */
513 SpinEOBParams *params /**<< Spin EOB Parameters */
514 )
515{
516
517 static const REAL8 STEP_SIZE = 1.0e-4;
518
519 REAL8 result;
520 REAL8 UNUSED absErr;
521
522 HcapSphDeriv2Params dParams;
523
524 gsl_function F;
525 INT4 UNUSED gslStatus;
526
527 dParams.sphValues = values;
528 dParams.varyParam1 = idx1;
529 dParams.varyParam2 = idx2;
530 dParams.params = params;
531
532 /*printf( " In second deriv function: values\n" );
533 for ( int i = 0; i < 12; i++ )
534 {
535 printf( "%.16e ", values[i] );
536 }
537 printf( "\n" );
538*/
540 F.params = &dParams;
541
542 /* GSL seemed to give weird answers - try my own code */
543 /*result = GSLSpinHamiltonianDerivWrapper( values[idx1] + STEP_SIZE, &dParams )
544 - GSLSpinHamiltonianDerivWrapper( values[idx1] - STEP_SIZE, &dParams );
545 printf( "%.16e - %.16e / 2h\n", GSLSpinHamiltonianDerivWrapper( values[idx1] + STEP_SIZE, &dParams ), GSLSpinHamiltonianDerivWrapper( values[idx1] - STEP_SIZE, &dParams ) );
546
547 result = result / ( 2.*STEP_SIZE );
548*/
549
550 XLAL_CALLGSL( gslStatus = gsl_deriv_central( &F, values[idx1],
551 STEP_SIZE, &result, &absErr ) );
552
553 if ( gslStatus != GSL_SUCCESS )
554 {
555 XLALPrintError( "XLAL Error %s - Failure in GSL function\n", __func__ );
557 }
558
559 //printf( "Second deriv abs err = %.16e\n", absErr );
560
561 //printf( "RESULT = %.16e\n", result );
562 return result;
563}
564
565/**
566 * Main function for calculating the spinning EOB initial conditions, following the
567 * quasi-spherical initial conditions described in Sec. IV A of
568 * Buonanno, Chen & Damour PRD 74, 104005 (2006).
569 * All equation numbers in the comments of this function refer to this paper.
570 * Inputs are binary parameters (masses, spin vectors and inclination),
571 * EOB model parameters and initial frequency.
572 * Outputs are initial dynamical variables in a vector
573 * (x, y, z, px, py, pz, S1x, S1y, S1z, S2x, S2y, S2z).
574 * In the paper, the initial conditions are solved for a given initial radius,
575 * while in this function, they are solved for a given inital orbital frequency.
576 * This difference is reflected in solving Eq. (4.8).
577 * The calculation is done in 5 steps:
578 * STEP 1) Rotate to LNhat0 along z-axis and N0 along x-axis frame, where
579 * LNhat0 and N0 are initial normal to orbital plane and initial orbital separation;
580 * STEP 2) After rotation in STEP 1, in spherical coordinates,
581 * phi0 and theta0 are given directly in Eq. (4.7),
582 * r0, pr0, ptheta0 and pphi0 are obtained by solving Eqs. (4.8) and (4.9)
583 * (using gsl_multiroot_fsolver).
584 * At this step, we find initial conditions for a spherical orbit without
585 * radiation reaction.
586 * STEP 3) Rotate to L0 along z-axis and N0 along x-axis frame, where
587 * L0 is the initial orbital angular momentum and
588 * L0 is calculated using initial position and linear momentum obtained in STEP 2.
589 * STEP 4) In the L0-N0 frame, we calculate (dE/dr)|sph using Eq. (4.14),
590 * then initial dr/dt using Eq. (4.10), and finally pr0 using Eq. (4.15).
591 * STEP 5) Rotate back to the original inertial frame by inverting the rotation of STEP 3 and
592 * then inverting the rotation of STEP 1.
593 */
594
596 REAL8Vector *initConds, /**<< OUTPUT, Initial dynamical variables */
597 const REAL8 mass1, /**<< mass 1 */
598 const REAL8 mass2, /**<< mass 2 */
599 const REAL8 fMin, /**<< Initial frequency (given) */
600 const REAL8 inc, /**<< Inclination */
601 const REAL8 spin1[], /**<< Initial spin vector 1 */
602 const REAL8 spin2[], /**<< Initial spin vector 2 */
603 SpinEOBParams *params, /**<< Spin EOB parameters */
604 INT4 use_optimized_v2 /**<< Use optimized v2? */
605 )
606{
607
608 if ( !initConds )
609 {
611 }
612
613
614 static const int UNUSED lMax = 8;
615
616 int i;
617
618 /* Variable to keep track of whether the user requested the tortoise */
619 int tmpTortoise;
620
621 UINT4 SpinAlignedEOBversion;
622
623 REAL8 mTotal;
624 REAL8 eta;
625 REAL8 omega, v0; /* Initial velocity and angular frequency */
626
627 REAL8 ham; /* Hamiltonian */
628
629 REAL8 LnHat[3]; /* Initial orientation of angular momentum */
630 REAL8 rHat[3]; /* Initial orientation of radial vector */
631 REAL8 vHat[3]; /* Initial orientation of velocity vector */
632 REAL8 Lhat[3]; /* Direction of relativistic ang mom */
633 REAL8 qHat[3];
634 REAL8 pHat[3];
635
636 /* q and p vectors in Cartesian and spherical coords */
637 REAL8 qCart[3], pCart[3];
638 REAL8 qSph[3], pSph[3];
639
640 /* We will need to manipulate the spin vectors */
641 /* We will use temporary vectors to do this */
642 REAL8 tmpS1[3];
643 REAL8 tmpS2[3];
644 REAL8 tmpS1Norm[3];
645 REAL8 tmpS2Norm[3];
646
647 REAL8Vector qCartVec, pCartVec;
648 REAL8Vector s1Vec, s2Vec, s1VecNorm, s2VecNorm;
649 REAL8Vector sKerr, sStar;
650 REAL8 sKerrData[3], sStarData[3];
651 REAL8 a = 0.; //, chiS, chiA;
652 //REAL8 chi1, chi2;
653
654 /* We will need a full values vector for calculating derivs of Hamiltonian */
655 REAL8 sphValues[12];
656 REAL8 cartValues[12];
657
658 /* Matrices for rotating to the new basis set. */
659 /* It is more convenient to calculate the ICs in a simpler basis */
660 gsl_matrix *rotMatrix = NULL;
661 gsl_matrix *invMatrix = NULL;
662 gsl_matrix *rotMatrix2 = NULL;
663 gsl_matrix *invMatrix2 = NULL;
664
665 /* Root finding stuff for finding the spherical orbit */
666 SEOBRootParams rootParams;
667 const gsl_multiroot_fsolver_type *T = gsl_multiroot_fsolver_hybrids;
668 gsl_multiroot_fsolver *rootSolver = NULL;
669
670 gsl_multiroot_function rootFunction;
671 gsl_vector *initValues = NULL;
672 gsl_vector *finalValues = NULL;
673 int gslStatus;
674 const int maxIter = 100;
675
676 memset( &rootParams, 0, sizeof( rootParams ) );
677
678 mTotal = mass1 + mass2;
679 eta = mass1 * mass2 / (mTotal * mTotal);
680 memcpy( tmpS1, spin1, sizeof(tmpS1) );
681 memcpy( tmpS2, spin2, sizeof(tmpS2) );
682 memcpy( tmpS1Norm, spin1, sizeof(tmpS1Norm) );
683 memcpy( tmpS2Norm, spin2, sizeof(tmpS2Norm) );
684 for ( i = 0; i < 3; i++ )
685 {
686 tmpS1Norm[i] /= mTotal * mTotal;
687 tmpS2Norm[i] /= mTotal * mTotal;
688 }
689 SpinAlignedEOBversion = params->seobCoeffs->SpinAlignedEOBversion;
690 /* We compute the ICs for the non-tortoise p, and convert at the end */
691 tmpTortoise = params->tortoise;
692 params->tortoise = 0;
693
694 EOBNonQCCoeffs *nqcCoeffs = NULL;
695 nqcCoeffs = params->nqcCoeffs;
696
697 /* STEP 1) Rotate to LNhat0 along z-axis and N0 along x-axis frame, where LNhat0 and N0 are initial normal to
698 * orbital plane and initial orbital separation;
699 */
700
701 /* Set the initial orbital ang mom direction. Taken from STPN code */
702 LnHat[0] = sin(inc);
703 LnHat[1] = 0.;
704 LnHat[2] = cos(inc);
705
706 /* Set the radial direction - need to take care to avoid singularity if L is along z axis */
707 if ( LnHat[2] > 0.9999 )
708 {
709 rHat[0] = 1.;
710 rHat[1] = rHat[2] = 0.;
711 }
712 else
713 {
714 REAL8 theta0 = atan( - LnHat[2] / LnHat[0] ); /* theta0 is between 0 and Pi */
715 rHat[0] = sin( theta0 );
716 rHat[1] = 0;
717 rHat[2] = cos( theta0 );
718 }
719
720 /* Now we can complete the triad */
721 vHat[0] = CalculateCrossProduct( 0, LnHat, rHat );
722 vHat[1] = CalculateCrossProduct( 1, LnHat, rHat );
723 vHat[2] = CalculateCrossProduct( 2, LnHat, rHat );
724
725 NormalizeVector( vHat );
726
727 /* XXX Test code XXX */
728 /*for ( i = 0; i < 3; i++ )
729 {
730 printf ( " LnHat[%d] = %.16e, rHat[%d] = %.16e, vHat[%d] = %.16e\n", i, LnHat[i], i, rHat[i], i, vHat[i] );
731 }
732
733 printf("\n\n" );
734 for ( i = 0; i < 3; i++ )
735 {
736 printf ( " s1[%d] = %.16e, s2[%d] = %.16e\n", i, tmpS1[i], i, tmpS2[i] );
737 }*/
738
739 /* Allocate and compute the rotation matrices */
740 XLAL_CALLGSL( rotMatrix = gsl_matrix_alloc( 3, 3 ) );
741 XLAL_CALLGSL( invMatrix = gsl_matrix_alloc( 3, 3 ) );
742 if ( !rotMatrix || !invMatrix )
743 {
744 if ( rotMatrix ) gsl_matrix_free( rotMatrix );
745 if ( invMatrix ) gsl_matrix_free( invMatrix );
747 }
748
749 if ( CalculateRotationMatrix( rotMatrix, invMatrix, rHat, vHat, LnHat ) == XLAL_FAILURE )
750 {
751 gsl_matrix_free( rotMatrix );
752 gsl_matrix_free( invMatrix );
754 }
755
756 /* Rotate the orbital vectors and spins */
757 ApplyRotationMatrix( rotMatrix, rHat );
758 ApplyRotationMatrix( rotMatrix, vHat );
759 ApplyRotationMatrix( rotMatrix, LnHat );
760 ApplyRotationMatrix( rotMatrix, tmpS1 );
761 ApplyRotationMatrix( rotMatrix, tmpS2 );
762 ApplyRotationMatrix( rotMatrix, tmpS1Norm );
763 ApplyRotationMatrix( rotMatrix, tmpS2Norm );
764
765 /* XXX Test code XXX */
766 /*printf( "\nAfter applying rotation matrix:\n\n" );
767 for ( i = 0; i < 3; i++ )
768 {
769 printf ( " LnHat[%d] = %.16e, rHat[%d] = %.16e, vHat[%d] = %.16e\n", i, LnHat[i], i, rHat[i], i, vHat[i] );
770 }
771
772 printf("\n\n" );
773 for ( i = 0; i < 3; i++ )
774 {
775 printf ( " s1[%d] = %.16e, s2[%d] = %.16e\n", i, tmpS1[i], i, tmpS2[i] );
776 }*/
777
778 /* STEP 2) After rotation in STEP 1, in spherical coordinates, phi0 and theta0 are given directly in Eq. (4.7),
779 * r0, pr0, ptheta0 and pphi0 are obtained by solving Eqs. (4.8) and (4.9) (using gsl_multiroot_fsolver).
780 * At this step, we find initial conditions for a spherical orbit without radiation reaction.
781 */
782
783 /* Calculate the initial velocity from the given initial frequency */
784 omega = LAL_PI * mTotal * LAL_MTSUN_SI * fMin;
785 v0 = cbrt( omega );
786
787 /* Given this, we can start to calculate the initial conditions */
788 /* for spherical coords in the new basis */
789 rootParams.omega = omega;
790 rootParams.params = params;
791
792 /* To start with, we will just assign Newtonian-ish ICs to the system */
793 rootParams.values[0] = 1./(v0*v0); /* Initial r */
794 rootParams.values[4] = v0; /* Initial p */
795 memcpy( rootParams.values+6, tmpS1, sizeof( tmpS1 ) );
796 memcpy( rootParams.values+9, tmpS2, sizeof( tmpS2 ) );
797
798 //printf( "ICs guess: r = %.16e, p = %.16e\n", rootParams.values[0], rootParams.values[4] );
799
800 /* Initialise the gsl stuff */
801 XLAL_CALLGSL( rootSolver = gsl_multiroot_fsolver_alloc( T, 3 ) );
802 if ( !rootSolver )
803 {
804 gsl_matrix_free( rotMatrix );
805 gsl_matrix_free( invMatrix );
807 }
808
809 XLAL_CALLGSL( initValues = gsl_vector_calloc( 3 ) );
810 if ( !initValues )
811 {
812 gsl_multiroot_fsolver_free( rootSolver );
813 gsl_matrix_free( rotMatrix );
814 gsl_matrix_free( invMatrix );
816 }
817
818 gsl_vector_set( initValues, 0, rootParams.values[0] );
819 gsl_vector_set( initValues, 1, rootParams.values[4] );
820
821 rootFunction.f = XLALFindSphericalOrbit;
822 rootFunction.n = 3;
823 rootFunction.params = &rootParams;
824
825 gsl_multiroot_fsolver_set( rootSolver, &rootFunction, initValues );
826
827 /* We are now ready to iterate to find the solution */
828 i = 0;
829
830 do
831 {
832 XLAL_CALLGSL( gslStatus = gsl_multiroot_fsolver_iterate( rootSolver ) );
833 if ( gslStatus != GSL_SUCCESS )
834 {
835 XLALPrintError( "Error in GSL iteration function!\n" );
836 gsl_multiroot_fsolver_free( rootSolver );
837 gsl_vector_free( initValues );
838 gsl_matrix_free( rotMatrix );
839 gsl_matrix_free( invMatrix );
841 }
842
843 XLAL_CALLGSL( gslStatus = gsl_multiroot_test_residual( rootSolver->f, 1.0e-10 ) );
844 i++;
845 }
846 while ( gslStatus == GSL_CONTINUE && i <= maxIter );
847
848 if ( i > maxIter && gslStatus != GSL_SUCCESS )
849 {
850 gsl_multiroot_fsolver_free( rootSolver );
851 gsl_vector_free( initValues );
852 gsl_matrix_free( rotMatrix );
853 gsl_matrix_free( invMatrix );
855 }
856
857 finalValues = gsl_multiroot_fsolver_root( rootSolver );
858
859 /*printf( "Spherical orbit conditions here given by the following:\n" );
860 printf( " x = %.16e, py = %.16e, pz = %.16e\n", gsl_vector_get( finalValues, 0 ),
861 gsl_vector_get( finalValues, 1 ), gsl_vector_get( finalValues, 2 ) );*/
862
863 memset( qCart, 0, sizeof(qCart) );
864 memset( pCart, 0, sizeof(pCart) );
865
866 qCart[0] = gsl_vector_get( finalValues, 0 );
867 pCart[1] = gsl_vector_get( finalValues, 1 );
868 pCart[2] = gsl_vector_get( finalValues, 2 );
869
870 /* Free the GSL root finder, since we're done with it */
871 gsl_multiroot_fsolver_free( rootSolver );
872 gsl_vector_free( initValues );
873
874 /* STEP 3) Rotate to L0 along z-axis and N0 along x-axis frame, where L0 is the initial orbital angular momentum
875 * and L0 is calculated using initial position and linear momentum obtained in STEP 2.
876 */
877
878 /* Now we can calculate the relativistic L and rotate to a new basis */
879 memcpy( qHat, qCart, sizeof(qCart) );
880 memcpy( pHat, pCart, sizeof(pCart) );
881
882 NormalizeVector( qHat );
883 NormalizeVector( pHat );
884
885 Lhat[0] = CalculateCrossProduct( 0, qHat, pHat );
886 Lhat[1] = CalculateCrossProduct( 1, qHat, pHat );
887 Lhat[2] = CalculateCrossProduct( 2, qHat, pHat );
888
889 NormalizeVector( Lhat );
890
891 XLAL_CALLGSL( rotMatrix2 = gsl_matrix_alloc( 3, 3 ) );
892 XLAL_CALLGSL( invMatrix2 = gsl_matrix_alloc( 3, 3 ) );
893
894 if ( CalculateRotationMatrix( rotMatrix2, invMatrix2, qHat, pHat, Lhat ) == XLAL_FAILURE )
895 {
896 gsl_matrix_free( rotMatrix );
897 gsl_matrix_free( invMatrix );
899 }
900
901 ApplyRotationMatrix( rotMatrix2, rHat );
902 ApplyRotationMatrix( rotMatrix2, vHat );
903 ApplyRotationMatrix( rotMatrix2, LnHat );
904 ApplyRotationMatrix( rotMatrix2, tmpS1 );
905 ApplyRotationMatrix( rotMatrix2, tmpS2 );
906 ApplyRotationMatrix( rotMatrix2, tmpS1Norm );
907 ApplyRotationMatrix( rotMatrix2, tmpS2Norm );
908 ApplyRotationMatrix( rotMatrix2, qCart );
909 ApplyRotationMatrix( rotMatrix2, pCart );
910
911 /* STEP 4) In the L0-N0 frame, we calculate (dE/dr)|sph using Eq. (4.14), then initial dr/dt using Eq. (4.10),
912 * and finally pr0 using Eq. (4.15).
913 */
914
915 /* Now we can calculate the flux. Change to spherical co-ords */
916 CartesianToSpherical( qSph, pSph, qCart, pCart );
917 memcpy( sphValues, qSph, sizeof( qSph ) );
918 memcpy( sphValues+3, pSph, sizeof( pSph ) );
919 memcpy( sphValues+6, tmpS1, sizeof(tmpS1) );
920 memcpy( sphValues+9, tmpS2, sizeof(tmpS2) );
921
922 memcpy( cartValues, qCart, sizeof(qCart) );
923 memcpy( cartValues+3, pCart, sizeof(pCart) );
924 memcpy( cartValues+6, tmpS1, sizeof(tmpS1) );
925 memcpy( cartValues+9, tmpS2, sizeof(tmpS2) );
926
927 REAL8 dHdpphi, d2Hdr2, d2Hdrdpphi;
928 REAL8 rDot, dHdpr, flux, dEdr;
929
930 if(use_optimized_v2) {
931 /* TODO: Full, analytic derivatives have not been computed yet for d2Hdr2 or d2Hdrdpphi,
932 * so we use hybrid version. */
933 d2Hdr2 = XLALCalculateSphHamiltonianDeriv2Hybrid( 0, 0, sphValues, params );
934 d2Hdrdpphi = XLALCalculateSphHamiltonianDeriv2Hybrid( 0, 5, sphValues, params );
935 /* Full analytical version of dHdpphi. */
936 dHdpphi = XLALSpinHcapExactDerivWRTParam( 4, cartValues, params ) / sphValues[0];
937 } else {
938 d2Hdr2 = XLALCalculateSphHamiltonianDeriv2( 0, 0, sphValues, params );
939 d2Hdrdpphi = XLALCalculateSphHamiltonianDeriv2( 0, 5, sphValues, params );
940 dHdpphi = XLALSpinHcapNumDerivWRTParam( 4, cartValues, params ) / sphValues[0];
941 }
942 dEdr = - dHdpphi * d2Hdr2 / d2Hdrdpphi;
943
944 //printf( "d2Hdr2 = %.16e d2Hdrdpphi = %.16e dHdpphi = %.16e\n", d2Hdr2, d2Hdrdpphi, dHdpphi );
945
946 if ( d2Hdr2 != 0.0 )
947 {
948 /* We will need to calculate the Hamiltonian to get the flux */
949 s1Vec.length = s2Vec.length = s1VecNorm.length = s2VecNorm.length = sKerr.length = sStar.length = 3;
950 s1Vec.data = tmpS1;
951 s2Vec.data = tmpS2;
952 s1VecNorm.data = tmpS1Norm;
953 s2VecNorm.data = tmpS2Norm;
954 sKerr.data = sKerrData;
955 sStar.data = sStarData;
956
957 qCartVec.length = pCartVec.length = 3;
958 qCartVec.data = qCart;
959 pCartVec.data = pCart;
960
961 //chi1 = tmpS1[0]*LnHat[0] + tmpS1[1]*LnHat[1] + tmpS1[2]*LnHat[2];
962 //chi2 = tmpS2[0]*LnHat[0] + tmpS2[1]*LnHat[1] + tmpS2[2]*LnHat[2];
963
964 //printf( "magS1 = %.16e, magS2 = %.16e\n", chi1, chi2 );
965
966 //chiS = 0.5 * ( chi1 / (mass1*mass1) + chi2 / (mass2*mass2) );
967 //chiA = 0.5 * ( chi1 / (mass1*mass1) - chi2 / (mass2*mass2) );
968
969 XLALSimIMRSpinEOBCalculateSigmaKerr( &sKerr, mass1, mass2, &s1Vec, &s2Vec );
970 XLALSimIMRSpinEOBCalculateSigmaStar( &sStar, mass1, mass2, &s1Vec, &s2Vec );
971
972 /* The a in the flux has been set to zero, but not in the Hamiltonian */
973 a = sqrt(sKerr.data[0]*sKerr.data[0] + sKerr.data[1]*sKerr.data[1] + sKerr.data[2]*sKerr.data[2]);
974 //XLALSimIMREOBCalcSpinFacWaveformCoefficients( params->eobParams->hCoeffs, mass1, mass2, eta, /*a*/0.0, chiS, chiA );
975 //XLALSimIMRCalculateSpinEOBHCoeffs( params->seobCoeffs, eta, a );
976 if(use_optimized_v2) {
977 ham = XLALSimIMRSpinEOBHamiltonianOptimized( eta, &qCartVec, &pCartVec, &s1VecNorm, &s2VecNorm, &sKerr, &sStar, params->tortoise, params->seobCoeffs );
978 } else {
979 ham = XLALSimIMRSpinEOBHamiltonian( eta, &qCartVec, &pCartVec, &s1VecNorm, &s2VecNorm, &sKerr, &sStar, params->tortoise, params->seobCoeffs );
980 }
981 //printf( "hamiltonian at this point is %.16e\n", ham );
982
983 /* And now, finally, the flux */
984 REAL8Vector polarDynamics;
985 REAL8 polarData[4];
986
987 polarDynamics.length = 4;
988 polarDynamics.data = polarData;
989
990 polarData[0] = qSph[0];
991 polarData[1] = 0.;
992 polarData[2] = pSph[0];
993 polarData[3] = pSph[2];
994
995 flux = XLALInspiralSpinFactorizedFlux( &polarDynamics, nqcCoeffs, omega, params, ham, lMax, SpinAlignedEOBversion );
996 flux = flux / eta;
997
998 rDot = - flux / dEdr;
999
1000 /* We now need dHdpr - we take it that it is safely linear up to a pr of 1.0e-3 */
1001 cartValues[3] = 1.0e-3;
1002 if(use_optimized_v2) {
1003 dHdpr = XLALSpinHcapExactDerivWRTParam( 3, cartValues, params );
1004 } else {
1005 dHdpr = XLALSpinHcapNumDerivWRTParam( 3, cartValues, params );
1006 }
1007 /*printf( "Ingredients going into prDot:\n" );
1008 printf( "flux = %.16e, dEdr = %.16e, dHdpr = %.16e\n", flux, dEdr, dHdpr );*/
1009
1010 /* We can now calculate what pr should be taking into account the flux */
1011 pSph[0] = rDot / (dHdpr / cartValues[3] );
1012 }
1013 else
1014 {
1015 /* Since d2Hdr2 has evaluated to zero, we cannot do the above. Just set pr to zero */
1016 //printf( "d2Hdr2 is zero!\n" );
1017 pSph[0] = 0;
1018 }
1019
1020 /* Now we are done - convert back to cartesian coordinates ) */
1021 SphericalToCartesian( qCart, pCart, qSph, pSph );
1022
1023 /* STEP 5) Rotate back to the original inertial frame by inverting the rotation of STEP 3 and then
1024 * inverting the rotation of STEP 1.
1025 */
1026
1027 /* Undo rotations to get back to the original basis */
1028 /* Second rotation */
1029 ApplyRotationMatrix( invMatrix2, rHat );
1030 ApplyRotationMatrix( invMatrix2, vHat );
1031 ApplyRotationMatrix( invMatrix2, LnHat );
1032 ApplyRotationMatrix( invMatrix2, tmpS1 );
1033 ApplyRotationMatrix( invMatrix2, tmpS2 );
1034 ApplyRotationMatrix( invMatrix2, tmpS1Norm );
1035 ApplyRotationMatrix( invMatrix2, tmpS2Norm );
1036 ApplyRotationMatrix( invMatrix2, qCart );
1037 ApplyRotationMatrix( invMatrix2, pCart );
1038
1039 /* First rotation */
1040 ApplyRotationMatrix( invMatrix, rHat );
1041 ApplyRotationMatrix( invMatrix, vHat );
1042 ApplyRotationMatrix( invMatrix, LnHat );
1043 ApplyRotationMatrix( invMatrix, tmpS1 );
1044 ApplyRotationMatrix( invMatrix, tmpS2 );
1045 ApplyRotationMatrix( invMatrix, tmpS1Norm );
1046 ApplyRotationMatrix( invMatrix, tmpS2Norm );
1047 ApplyRotationMatrix( invMatrix, qCart );
1048 ApplyRotationMatrix( invMatrix, pCart );
1049
1050 /* If required, apply the tortoise transform */
1051 if ( tmpTortoise )
1052 {
1053 REAL8 r = sqrt(qCart[0]*qCart[0] + qCart[1]*qCart[1] + qCart[2]*qCart[2] );
1054 REAL8 deltaR = XLALSimIMRSpinEOBHamiltonianDeltaR( params->seobCoeffs, r, eta, a );
1055 REAL8 deltaT = XLALSimIMRSpinEOBHamiltonianDeltaT( params->seobCoeffs, r, eta, a );
1056 REAL8 csi = sqrt( deltaT * deltaR )/(r*r + a*a);
1057
1058 REAL8 pr = (qCart[0]*pCart[0] + qCart[1]*pCart[1] + qCart[2]*pCart[2])/r;
1059
1060 params->tortoise = tmpTortoise;
1061
1062 //printf( "Applying the tortoise to p (csi = %.26e)\n", csi );
1063
1064 for ( i = 0; i < 3; i++ )
1065 {
1066 pCart[i] = pCart[i] + qCart[i] * pr * (csi - 1.) / r;
1067 }
1068 }
1069
1070 /* Now copy the initial conditions back to the return vector */
1071 memcpy( initConds->data, qCart, sizeof(qCart) );
1072 memcpy( initConds->data+3, pCart, sizeof(pCart) );
1073 memcpy( initConds->data+6, tmpS1Norm, sizeof(tmpS1Norm) );
1074 memcpy( initConds->data+9, tmpS2Norm, sizeof(tmpS2Norm) );
1075
1076 gsl_matrix_free(rotMatrix2);
1077 gsl_matrix_free(invMatrix2);
1078
1079 gsl_matrix_free(rotMatrix);
1080 gsl_matrix_free(invMatrix);
1081
1082 //printf( "THE FINAL INITIAL CONDITIONS:\n");
1083 /*printf( " %.16e %.16e %.16e\n%.16e %.16e %.16e\n%.16e %.16e %.16e\n%.16e %.16e %.16e\n", initConds->data[0], initConds->data[1], initConds->data[2],
1084 initConds->data[3], initConds->data[4], initConds->data[5], initConds->data[6], initConds->data[7], initConds->data[8],
1085 initConds->data[9], initConds->data[10], initConds->data[11] );*/
1086
1087 return XLAL_SUCCESS;
1088}
1089
1090#endif /*_LALSIMIMRSPINEOBINITIALCONDITIONS_C*/
static int XLALSimIMRSpinEOBCalculateSigmaKerr(REAL8Vector *sigmaKerr, REAL8 mass1, REAL8 mass2, REAL8Vector *s1, REAL8Vector *s2)
Function to calculate normalized spin of the deformed-Kerr background in SEOBNRv1.
static int XLALSimIMRSpinEOBCalculateSigmaStar(REAL8Vector *sigmaStar, REAL8 mass1, REAL8 mass2, REAL8Vector *s1, REAL8Vector *s2)
Function to calculate normalized spin of the test particle in SEOBNRv1.
static REAL8 XLALInspiralSpinFactorizedFlux(REAL8Vector *values, EOBNonQCCoeffs *nqcCoeffs, const REAL8 omega, SpinEOBParams *ak, const REAL8 H, const UINT4 lMax, const UINT4 SpinAlignedEOBversion)
static REAL8 XLALSimIMRSpinEOBHamiltonianDeltaR(SpinEOBHCoeffs *coeffs, const REAL8 r, const REAL8 eta, const REAL8 a)
This function calculates the DeltaR potential function in the spin EOB Hamiltonian.
static REAL8 XLALSimIMRSpinEOBHamiltonian(const REAL8 eta, REAL8Vector *restrict x, REAL8Vector *restrict p, REAL8Vector *restrict s1Vec, REAL8Vector *restrict s2Vec, REAL8Vector *restrict sigmaKerr, REAL8Vector *restrict sigmaStar, int tortoise, SpinEOBHCoeffs *coeffs)
static REAL8 XLALSimIMRSpinEOBHamiltonianDeltaT(SpinEOBHCoeffs *coeffs, const REAL8 r, const REAL8 eta, const REAL8 a)
This function calculates the function which appears in the spinning EOB potential function.
UNUSED REAL8 XLALSimIMRSpinEOBHamiltonianOptimized(const REAL8 eta, REAL8Vector *restrict x, REAL8Vector *restrict p, REAL8Vector *restrict s1Vec, REAL8Vector *restrict s2Vec, REAL8Vector *restrict sigmaKerr, REAL8Vector *restrict sigmaStar, INT4 tortoise, SpinEOBHCoeffs *coeffs)
Function to calculate the value of the spinning Hamiltonian for given values of the dynamical variabl...
static REAL8 XLALSpinHcapExactDerivWRTParam(const INT4 paramIdx, const REAL8 values[], SpinEOBParams *params)
Calculate the derivative of the Hamiltonian w.r.t.
static REAL8 XLALSpinHcapHybDerivWRTParam(const INT4 paramIdx, const REAL8 values[], SpinEOBParams *funcParams)
static REAL8 XLALSpinHcapNumDerivWRTParam(const INT4 paramIdx, const REAL8 values[], SpinEOBParams *params)
Calculate the derivative of the Hamiltonian w.r.t.
static int ApplyRotationMatrix(gsl_matrix *rotMatrix, REAL8 a[])
Applies a rotation matrix to a given vector.
static REAL8 XLALCalculateSphHamiltonianDeriv2(const int idx1, const int idx2, const REAL8 values[], SpinEOBParams *params)
static double GSLSpinHamiltonianDerivWrapperHybrid(double x, void *params)
Wrapper for calculating specific derivative of the Hamiltonian in spherical co-ordinates,...
static int CartesianToSpherical(REAL8 qSph[], REAL8 pSph[], const REAL8 qCart[], const REAL8 pCart[])
Perform a co-ordinate transformation from Cartesian to spherical co-ordinates.
static REAL8 CalculateCrossProduct(const INT4 i, const REAL8 a[], const REAL8 b[])
calculates the ith component of the cross product of two vectors, where i is in the range 0-2.
static int XLALSimIMRSpinEOBInitialConditions(REAL8Vector *initConds, const REAL8 mass1, const REAL8 mass2, const REAL8 fMin, const REAL8 inc, const REAL8 spin1[], const REAL8 spin2[], SpinEOBParams *params, INT4 use_optimized_v2)
Main function for calculating the spinning EOB initial conditions, following the quasi-spherical init...
static int NormalizeVector(REAL8 a[])
Normalizes the given vector.
static REAL8 XLALCalculateSphHamiltonianDeriv2Hybrid(const int idx1, const int idx2, const REAL8 values[], SpinEOBParams *params)
static REAL8 CalculateDotProduct(const REAL8 a[], const REAL8 b[])
Calculates the dot product of two vectors.
static int CalculateRotationMatrix(gsl_matrix *rotMatrix, gsl_matrix *rotInverse, REAL8 r[], REAL8 v[], REAL8 L[])
Calculate the rotation matrix and its inverse.
static int XLALFindSphericalOrbit(const gsl_vector *x, void *params, gsl_vector *f)
Root function for gsl root finders.
static double GSLSpinHamiltonianDerivWrapper(double x, void *params)
Wrapper for calculating specific derivative of the Hamiltonian in spherical co-ordinates,...
static int SphericalToCartesian(REAL8 qCart[], REAL8 pCart[], const REAL8 qSph[], const REAL8 pSph[])
Performs a co-ordinate transformation from spherical to Cartesian co-ordinates.
#define XLAL_CALLGSL(statement)
double i
Definition: bh_ringdown.c:118
const double pr
const double deltaR
const double csi
#define LAL_PI_2
#define LAL_PI
#define LAL_MTSUN_SI
double REAL8
uint32_t UINT4
int32_t INT4
static const INT4 r
static const INT4 a
#define XLAL_ERROR_REAL8(...)
#define XLAL_ERROR(...)
int XLALPrintError(const char *fmt,...) _LAL_GCC_PRINTF_FORMAT_(1
#define XLAL_IS_REAL8_FAIL_NAN(val)
XLAL_ENOMEM
XLAL_SUCCESS
XLAL_EMAXITER
XLAL_EDOM
XLAL_EINVAL
XLAL_FAILURE
list y
x
The coefficients which are used in calculating the non-quasicircular correction to the EOBNRv2 model.
const REAL8 * sphValues
SpinEOBParams * params
REAL8 * data
Structure consisting SEOBNR parameters that can be used by gsl root finders.
REAL8 omega
< Orbital frequency
REAL8 values[12]
< Dynamical variables, x, y, z, px, py, pz, S1x, S1y, S1z, S2x, S2y and S2z
SpinEOBParams * params
< Spin EOB parameters – physical, pre-computed, etc.
Parameters for the spinning EOB model.
Definition: burst.c:245
double deltaT
Definition: unicorn.c:24