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
LALSimIMRSpinPrecEOBEulerAngles.c
Go to the documentation of this file.
1#ifndef _LALSIMIMRSPINPRECEOBEULERANGLES_C
2#define _LALSIMIMRSPINPRECEOBEULERANGLES_C
3
4
5/**
6 * Computes the Euler angles in the (z,y,z) convention corresponding to a given 3*3 active rotation matrix
7 * R has to be 3*3
8 */
10{
11 /* Matrix element (i,j) at location 3*i + j */
12 REAL8 a = atan2(R->data[3*1 + 2], R->data[3*0 + 2]);
13 REAL8 b = acos(R->data[3*2 + 2]);
14 REAL8 c = atan2(R->data[3*2 + 1], -R->data[3*2 + 0]);
15 *alpha = a;
16 *beta = b;
17 *gamma = c;
18 return XLAL_SUCCESS;
19}
20/**
21 * Active rotation matrix from orthonormal basis (e1, e2, e3) to (e1', e2', e3')
22 * Input are e1', e2', e3' decomposed on (e1, e2, e3)
23 * All vectors are 3-vectors, R matrix 3*3 has to be already allocated
24 */
25static UNUSED int RotationMatrixActiveFromBasisVectors(REAL8Array* R, const REAL8 e1p[], const REAL8 e2p[], const REAL8 e3p[])
26{
27 R->data[3*0 + 0] = e1p[0];
28 R->data[3*1 + 0] = e1p[1];
29 R->data[3*2 + 0] = e1p[2];
30 R->data[3*0 + 1] = e2p[0];
31 R->data[3*1 + 1] = e2p[1];
32 R->data[3*2 + 1] = e2p[2];
33 R->data[3*0 + 2] = e3p[0];
34 R->data[3*1 + 2] = e3p[1];
35 R->data[3*2 + 2] = e3p[2];
36 return XLAL_SUCCESS;
37}
38
39/**
40 * Computes RHS of ODE for gamma. Eq. 10 of PRD 89, 084006 (2014)
41 */
42static double f_alphadotcosi( double x, void * inparams )
43{
45
46 REAL8 alphadot = gsl_spline_eval_deriv( params->alpha_spline, x, params->alpha_acc );
47 REAL8 beta = gsl_spline_eval( params->beta_spline, x, params->beta_acc );
48
49 return -1. * alphadot * cos(beta);
50
51}
52/**
53 * Given the trajectory in an inertial frame, this computes Euler angles
54 * of the roation from the inertial frame to the minimal-rotation frame
55 * that co-precesses with LN(t) = rvec(t) x rdotvec(t)
56 */
57static UNUSED int EulerAnglesI2P(REAL8Vector *Alpha, /**<< output: alpha Euler angle */
58 REAL8Vector *Beta, /**<< output: beta Euler angle */
59 REAL8Vector *Gamma, /**<< output: gamma Euler angle */
60 INT4 *phaseCounterA, /**<< output: counter for unwrapping of alpha */
61 INT4 *phaseCounterB, /**<< output: counter for unwrapping of beta */
62 const REAL8Vector tVec, /**<< time series */
63 const REAL8Vector posVecx, /**<< x time series */
64 const REAL8Vector posVecy, /**<< y time series */
65 const REAL8Vector posVecz, /**<< z time series */
66 const UINT4 retLenLow, /**<< Array length of the trajectory */
67 const REAL8 InitialAlpha, /**<< Initial alpha (used only if flag_highSR=1) */
68 const REAL8 InitialGamma, /**<< Initial gamma */
69 UINT4 flag_highSR, /**<< Flag to indicate whether one is analyzing the high SR trajectory */
70 const UINT4 use_optimized /**<< Flag to indicate whether one is using SEOBNRv3_opt */) {
71 UINT4 i = 0;
72 REAL8Vector *LN_x = NULL, *LN_y = NULL, *LN_z = NULL;
73 REAL8 tmpR[3], tmpRdot[3], magLN;
74 PrecEulerAnglesIntegration precEulerparams;
75 REAL8 inGamma = InitialGamma;
76
77 LN_x = XLALCreateREAL8Vector( retLenLow );
78 LN_y = XLALCreateREAL8Vector( retLenLow );
79 LN_z = XLALCreateREAL8Vector( retLenLow );
80
81 gsl_spline *x_spline = gsl_spline_alloc( gsl_interp_cspline, retLenLow );
82 gsl_spline *y_spline = gsl_spline_alloc( gsl_interp_cspline, retLenLow );
83 gsl_spline *z_spline = gsl_spline_alloc( gsl_interp_cspline, retLenLow );
84
85 gsl_interp_accel *x_acc = gsl_interp_accel_alloc();
86 gsl_interp_accel *y_acc = gsl_interp_accel_alloc();
87 gsl_interp_accel *z_acc = gsl_interp_accel_alloc();
88
89 gsl_spline_init( x_spline, tVec.data, posVecx.data, retLenLow );
90 gsl_spline_init( y_spline, tVec.data, posVecy.data, retLenLow );
91 gsl_spline_init( z_spline, tVec.data, posVecz.data, retLenLow );
92
93 for( i=0; i < retLenLow; i++ )
94 {
95 tmpR[0] = posVecx.data[i]; tmpR[1] = posVecy.data[i]; tmpR[2] = posVecz.data[i];
96 tmpRdot[0] = gsl_spline_eval_deriv( x_spline, tVec.data[i], x_acc );
97 tmpRdot[1] = gsl_spline_eval_deriv( y_spline, tVec.data[i], y_acc );
98 tmpRdot[2] = gsl_spline_eval_deriv( z_spline, tVec.data[i], z_acc );
99
100 LN_x->data[i] = tmpR[1] * tmpRdot[2] - tmpR[2] * tmpRdot[1];
101 LN_y->data[i] = tmpR[2] * tmpRdot[0] - tmpR[0] * tmpRdot[2];
102 LN_z->data[i] = tmpR[0] * tmpRdot[1] - tmpR[1] * tmpRdot[0];
103
104 magLN = sqrt(LN_x->data[i] * LN_x->data[i] + LN_y->data[i] * LN_y->data[i]
105 + LN_z->data[i] * LN_z->data[i]);
106 LN_x->data[i] /= magLN; LN_y->data[i] /= magLN; LN_z->data[i] /= magLN;
107
108 /* Eq. 19 of PRD 89, 084006 (2014) */
109 /* Also unwrap the two angles */
110 if (fabs(LN_x->data[i]) <= 1.e-10 && fabs(LN_y->data[i]) <=1.e-10){
111 Alpha->data[i] = 0.0;
112 inGamma = 0.0;
113 } else {
114 Alpha->data[i] = atan2( LN_y->data[i], LN_x->data[i] )
115 + *phaseCounterA * LAL_TWOPI;
116 if (i==0 && flag_highSR != 1){
117 inGamma = -Alpha->data[i];
118 }
119 }
120
121 while( i>0 && Alpha->data[i] - Alpha->data[i-1] > 5. ) {
122 *phaseCounterA = *phaseCounterA - 1;
123 Alpha->data[i] -= LAL_TWOPI;
124 }
125 while( i && Alpha->data[i] - Alpha->data[i-1] < -5. ) {
126 *phaseCounterA = *phaseCounterA + 1;
127 Alpha->data[i] += LAL_TWOPI;
128 }
129 if (LN_z->data[i] >1.) {
130 LN_z->data[i] = 1.;
131 }
132 if (LN_z->data[i] <-1.) {
133 LN_z->data[i] = -1.;
134 }
135 if ( flag_highSR == 1) {
136 Alpha->data[i] -= (Alpha->data[0] - InitialAlpha);
137 }
138
139 if (fabs(1.0 - LN_z->data[i]) < 1.e-12){
140 REAL8 LN_xy;
141 LN_xy = sqrt(LN_x->data[i]*LN_x->data[i] +
142 LN_y->data[i]*LN_y->data[i]);
143 //LN_z->data[i] = sqrt(1.0 - LN_xy*LN_xy);
144 Beta->data[i] = atan2(LN_xy, LN_z->data[i]);
145 //printf("here ");
146 }else{
147 Beta->data[i] = acos( LN_z->data[i] );
148 }
149 if( i>0 && Beta->data[i] > Beta->data[i-1] ) {
150 *phaseCounterB = *phaseCounterB - 1;
151 }
152 }
153 // Integrate \dot{\alpha} \cos{\beta} to get the final Euler angle
154 // Eq. 20 of PRD 89, 084006 (2014)
155 gsl_spline_init( x_spline, tVec.data, Alpha->data, retLenLow );
156 gsl_spline_init( y_spline, tVec.data, Beta->data, retLenLow );
157
158 precEulerparams.alpha_spline = x_spline;
159 precEulerparams.alpha_acc = x_acc;
160 precEulerparams.beta_spline = y_spline;
161 precEulerparams.beta_acc = y_acc;
162
163 Gamma->data[0] = inGamma;
164 if(use_optimized){
165 for( i = 1; i < retLenLow; i++ ){
166 double t1 = tVec.data[i-1];
167 double t2 = tVec.data[i];
168 Gamma->data[i] = Gamma->data[i-1] + (1.0/90.0)*(t2 - t1)*(7.0*f_alphadotcosi(t1,&precEulerparams)
169 + 32.0*f_alphadotcosi((t1+3.0*t2)/4.0,&precEulerparams)
170 + 12.0*f_alphadotcosi((t1+t2)/2.0,&precEulerparams)
171 + 32.0*f_alphadotcosi((3.0*t1+t2)/4.0,&precEulerparams)
172 + 7.0*f_alphadotcosi(t2,&precEulerparams));/* Boole's Rule */
173 }
174 }else{
175 gsl_integration_workspace * precEulerw = gsl_integration_workspace_alloc (1000);
176 gsl_function precEulerF;
177 REAL8 precEulerresult = 0, precEulererror = 0;
178 precEulerF.function = &f_alphadotcosi;
179 precEulerF.params = &precEulerparams;
180 for( i = 1; i < retLenLow; i++ ) {
181 gsl_integration_qags (&precEulerF, tVec.data[i-1], tVec.data[i], 1e-9, 1e-9, 1000, precEulerw, &precEulerresult, &precEulererror);
182 Gamma->data[i] = Gamma->data[i-1] + precEulerresult;
183 }
184 gsl_integration_workspace_free( precEulerw );
185 }
186
187 gsl_spline_free( x_spline );
188 gsl_spline_free( y_spline );
189 gsl_spline_free( z_spline );
190 gsl_interp_accel_free( x_acc );
191 gsl_interp_accel_free( y_acc );
192 gsl_interp_accel_free( z_acc );
196 return XLAL_SUCCESS;
197}
198
199/**
200 * Given Euler angles to go from initial inertial frame to precessing frama
201 * and the LNhat vector, this functions computes the Euler angles to
202 * go from the precessing frame to the frame of the total angular
203 * momentum
204 */
205static UNUSED void EulerAnglesP2J(
206 REAL8 *aP2J, /**<< alpha Euler angle from precessing to final-J frame */
207 REAL8 *bP2J, /**<< beta Euler angle from precessing to final-J frame */
208 REAL8 *gP2J, /**<< gamma Euler angle from precessing to final-J frame */
209 const REAL8 aI2P, /**<< alpha Euler angle from inertial to precessing frame */
210 const REAL8 bI2P, /**<< beta Euler angle from inertial to precessing frame */
211 const REAL8 gI2P, /**<< gamma Euler angle from inertial to precessing frame */
212 const REAL8 LNhx, /**<< x component of LNhat */
213 const REAL8 LNhy, /**<< y component of LNhat */
214 const REAL8 LNhz, /**<< z component of LNhat */
215 const REAL8 JframeEx[], /**<< x-axis of the total-angular-momentum frame */
216 const REAL8 JframeEy[], /**<< y-axis of the total-angular-momentum frame */
217 const REAL8 JframeEz[] /**<< z-axis of the total-angular-momentum frame */
218) {
219 REAL8 LframeEx[3] = {0,0,0}, LframeEy[3] = {0,0,0}, LframeEz[3] = {0,0,0};
220 LframeEx[0] = cos(aI2P)*cos(bI2P)*cos(gI2P) - sin(aI2P)*sin(gI2P);
221 LframeEx[1] = sin(aI2P)*cos(bI2P)*cos(gI2P) + cos(aI2P)*sin(gI2P);
222 LframeEx[2] = -sin(bI2P)*cos(gI2P);
223 LframeEy[0] = -cos(aI2P)*cos(bI2P)*sin(gI2P) - sin(aI2P)*cos(gI2P);
224 LframeEy[1] = -sin(aI2P)*cos(bI2P)*sin(gI2P) + cos(aI2P)*cos(gI2P);
225 LframeEy[2] = sin(bI2P)*sin(gI2P);
226 LframeEz[0] = LNhx;
227 LframeEz[1] = LNhy;
228 LframeEz[2] = LNhz;
229 REAL8 normJ, normLz;
230 normJ = JframeEz[0]*JframeEz[0]+JframeEz[1]*JframeEz[1]+JframeEz[2]*JframeEz[2];
231 normLz = LframeEz[0]*LframeEz[0]+LframeEz[1]*LframeEz[1]+LframeEz[2]*LframeEz[2];
232 *aP2J = atan2(JframeEz[0]*LframeEy[0]+JframeEz[1]*LframeEy[1]+JframeEz[2]*LframeEy[2],
233 JframeEz[0]*LframeEx[0]+JframeEz[1]*LframeEx[1]+JframeEz[2]*LframeEx[2]);
234 REAL8 cosarg = JframeEz[0]*LframeEz[0]+JframeEz[1]*LframeEz[1]+JframeEz[2]*LframeEz[2];
235 if ( cosarg >= 1. && cosarg < 1. + 1.e-10 ) {
236 cosarg = 1.;
237 }
238 if ( cosarg <= -1. && cosarg > -1. - 1.e-10 ) {
239 cosarg = -1.;
240 }
241 *bP2J = acos( cosarg );
242 if (*bP2J < 1.e-4){
243 cosarg = (JframeEz[0]*LframeEz[0]+JframeEz[1]*LframeEz[1]+JframeEz[2]*LframeEz[2])/sqrt(normJ*normLz);
244 if ( cosarg >= 1. && cosarg < 1. + 1.e-10 ) {
245 cosarg = 1.;
246 }
247 if ( cosarg <= -1. && cosarg > -1. - 1.e-10 ) {
248 cosarg = -1.;
249 }
250 *bP2J = acos( cosarg );
251 }
252 *gP2J = atan2( JframeEy[0]*LframeEz[0]+JframeEy[1]*LframeEz[1]+JframeEy[2]*LframeEz[2],
253 -(JframeEx[0]*LframeEz[0]+JframeEx[1]*LframeEz[1]+JframeEx[2]*LframeEz[2]));
254
255 /* I2P Euler angles are stored only for debugging purposes */
256 if ( fabs(*bP2J-LAL_PI) < 1.e-10){
257 *gP2J = 0.0;
258 *aP2J = atan2( JframeEx[1], JframeEx[0]);
259 }
260
261 if ( fabs(*bP2J) < 1.e-10){
262 *gP2J = 0.0;
263 *aP2J = atan2( JframeEx[1], JframeEx[0]);
264 }
265}
266
267#endif // _LALSIMIMRSPINPRECEOBEULERANGLES_C
static double f_alphadotcosi(double x, void *inparams)
Computes RHS of ODE for gamma.
static UNUSED void EulerAnglesP2J(REAL8 *aP2J, REAL8 *bP2J, REAL8 *gP2J, const REAL8 aI2P, const REAL8 bI2P, const REAL8 gI2P, const REAL8 LNhx, const REAL8 LNhy, const REAL8 LNhz, const REAL8 JframeEx[], const REAL8 JframeEy[], const REAL8 JframeEz[])
Given Euler angles to go from initial inertial frame to precessing frama and the LNhat vector,...
static UNUSED int RotationMatrixActiveFromBasisVectors(REAL8Array *R, const REAL8 e1p[], const REAL8 e2p[], const REAL8 e3p[])
Active rotation matrix from orthonormal basis (e1, e2, e3) to (e1', e2', e3') Input are e1',...
static UNUSED int EulerAnglesI2P(REAL8Vector *Alpha, REAL8Vector *Beta, REAL8Vector *Gamma, INT4 *phaseCounterA, INT4 *phaseCounterB, const REAL8Vector tVec, const REAL8Vector posVecx, const REAL8Vector posVecy, const REAL8Vector posVecz, const UINT4 retLenLow, const REAL8 InitialAlpha, const REAL8 InitialGamma, UINT4 flag_highSR, const UINT4 use_optimized)
Given the trajectory in an inertial frame, this computes Euler angles of the roation from the inertia...
static UNUSED int EulerAnglesZYZFromRotationMatrixActive(REAL8 *alpha, REAL8 *beta, REAL8 *gamma, REAL8Array *R)
Computes the Euler angles in the (z,y,z) convention corresponding to a given 3*3 active rotation matr...
static double beta(const double a, const double b, const sysq *system)
Internal function that computes the spin-orbit couplings.
#define c
double i
Definition: bh_ringdown.c:118
double e
Definition: bh_ringdown.c:117
#define LAL_PI
#define LAL_TWOPI
double REAL8
uint32_t UINT4
int32_t INT4
static const INT4 a
REAL8Vector * XLALCreateREAL8Vector(UINT4 length)
void XLALDestroyREAL8Vector(REAL8Vector *vector)
XLAL_SUCCESS
x
double alpha
Definition: sgwb.c:106
gsl_interp_accel * alpha_acc
gsl_interp_accel * beta_acc
REAL8 * data
REAL8 * data
Definition: burst.c:245