LALSimulation  5.4.0.1-fe68b98
LALSimIMRSpinAlignedEOBHcapDerivative.c
Go to the documentation of this file.
1 /*
2 * Copyright (C) 2010 Craig Robinson, Yi Pan
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 /**
22  * \author Craig Robinson, Yi Pan
23  *
24  * \brief In newer versions of the EOBNR approximant, we
25  * do not have an analytic expression for the derivative of the waveform.
26  * As such, it is necessary to calculate the derivatives numerically. This
27  * function provides the means to do that for the SEOBNRv1 Hamiltonian
28  * in the spin-aligned case, i.e. equatorial orbits with four dynamical variables:
29  * r, phi, pr and pphi. It then combines energy flux and numerical derivatives of
30  * the Hamiltonian to calculate the right hand side of the ODEs given by
31  * Eqs. 10a - 10d of Pan et al. PRD 84, 124052 (2011).
32  * Since SEOBNRv1 is a spin-aligned model, the ODEs are written
33  * in the same format as ODEs of a nonspinning model.
34  *
35  */
36 
37 #ifndef LALSIMIMRSPINALIGNEDEOBHCAPDERIVATIVE_C
38 #define LALSIMIMRSPINALIGNEDEOBHCAPDERIVATIVE_C
39 
40 #include <lal/LALSimInspiral.h>
41 #include <lal/LALSimIMR.h>
42 
43 #include "LALSimIMRSpinEOB.h"
46 
47 #include <gsl/gsl_deriv.h>
48 
49 /*------------------------------------------------------------------------------------------
50  *
51  * Prototypes of functions defined in this code.
52  *
53  *------------------------------------------------------------------------------------------
54  */
55 
57  double t,
58  const REAL8 values[],
59  REAL8 dvalues[],
60  void *funcParams
61  );
62 /*------------------------------------------------------------------------------------------
63  *
64  * Defintions of functions.
65  *
66  *------------------------------------------------------------------------------------------
67  */
68 
69 /**
70  * Function to calculate R.H.S. of the ODEs, given dyanmical variables,
71  * their derivatives and EOB parameters. Since SEOBNRv1 spin Hamiltonian
72  * was implemented for Cartesean coordinates while dynamical evolution was
73  * implemented in polar coordinates, we need to perform a transform.
74  * This is done in a particular transform in which
75  * x = r, y = z = 0, px = pr, py = pphi/r, pz = 0, and
76  * omega = v/r = (dy/dt)/r = (dH/dpy)/r, dr/dt = dx/dt = dH/dpx, etc.
77  */
79  double UNUSED t, /**< UNUSED */
80  const REAL8 values[], /**< dynamical varables */
81  REAL8 dvalues[], /**< time derivative of dynamical variables */
82  void *funcParams /**< EOB parameters */
83  )
84 {
85 
86  static const REAL8 STEP_SIZE = 1.0e-4;
87 
88  static const INT4 lMax = 8;
89 
91 
92  /* Since we take numerical derivatives wrt dynamical variables */
93  /* but we want them wrt time, we use this temporary vector in */
94  /* the conversion */
95  REAL8 tmpDValues[6];
96 
97  /* Cartesian values for calculating the Hamiltonian */
98  REAL8 cartValues[6];
99 
100  REAL8 H; //Hamiltonian
101  REAL8 flux;
102 
103  gsl_function F;
104  INT4 gslStatus;
105  UINT4 SpinAlignedEOBversion;
106  UINT4 i;
107 
108  REAL8Vector rVec, pVec;
109  REAL8 rData[3], pData[3];
110 
111  /* We need r, phi, pr, pPhi to calculate the flux */
112  REAL8 r;
113  REAL8Vector polarDynamics;
114  REAL8 polData[4];
115 
116  REAL8 mass1, mass2, eta;
117 
118  /* Spins */
119  REAL8Vector *s1Vec = NULL;
120  REAL8Vector *s2Vec = NULL;
121  REAL8Vector *sKerr = NULL;
122  REAL8Vector *sStar = NULL;
123 
124  REAL8 a;
125 
126  REAL8 omega;
127 
128  /* EOB potential functions */
129  REAL8 DeltaT, DeltaR;
130  REAL8 csi;
131 
132  /* The error in a derivative as measured by GSL */
133  REAL8 absErr;
134 
135  /* Declare NQC coefficients */
136  EOBNonQCCoeffs *nqcCoeffs = NULL;
137 
138  /* Set up pointers for GSL */
139  params.values = cartValues;
140  params.params = (SpinEOBParams *)funcParams;
141  nqcCoeffs = params.params->nqcCoeffs;
142 
143  s1Vec = params.params->s1Vec;
144  s2Vec = params.params->s2Vec;
145  sKerr = params.params->sigmaKerr;
146  sStar = params.params->sigmaStar;
147 
148  F.function = &GSLSpinAlignedHamiltonianWrapper;
149  F.params = &params;
150 
151  mass1 = params.params->eobParams->m1;
152  mass2 = params.params->eobParams->m2;
153  eta = params.params->eobParams->eta;
154 
155  SpinAlignedEOBversion = params.params->seobCoeffs->SpinAlignedEOBversion;
156 
157  r = values[0];
158 
159  /* Since this is spin aligned, I make the assumption */
160  /* that the spin vector is along the z-axis. */
161  a = sKerr->data[2];
162 
163  /* Calculate the potential functions and the tortoise coordinate factor csi,
164  given by Eq. 28 of Pan et al. PRD 81, 084041 (2010) */
165  DeltaT = XLALSimIMRSpinEOBHamiltonianDeltaT( params.params->seobCoeffs, r, eta, a );
166  DeltaR = XLALSimIMRSpinEOBHamiltonianDeltaR( params.params->seobCoeffs, r, eta, a );
167  csi = sqrt( DeltaT * DeltaR ) / (r*r + a*a);
168  //printf("DeltaT = %.16e, DeltaR = %.16e, a = %.16e\n",DeltaT,DeltaR,a);
169  //printf( "csi in derivatives function = %.16e\n", csi );
170 
171  /* Populate the Cartesian values vector, using polar coordinate values */
172  /* We can assume phi is zero wlog */
173  memset( cartValues, 0, sizeof( cartValues ) );
174  cartValues[0] = values[0];
175  cartValues[3] = values[2];
176  cartValues[4] = values[3] / values[0];
177 
178  /* Now calculate derivatives w.r.t. each Cartesian variable */
179  for ( i = 0; i < 6; i++ )
180  {
181  params.varyParam = i;
182  XLAL_CALLGSL( gslStatus = gsl_deriv_central( &F, cartValues[i],
183  STEP_SIZE, &tmpDValues[i], &absErr ) );
184 
185  if ( gslStatus != GSL_SUCCESS )
186  {
187  XLALPrintError( "XLAL Error - %s: Failure in GSL function\n", __func__ );
189  }
190  }
191 
192  /* Calculate the Cartesian vectors rVec and pVec */
193  polarDynamics.length = 4;
194  polarDynamics.data = polData;
195 
196  memcpy( polData, values, sizeof( polData ) );
197 
198  rVec.length = pVec.length = 3;
199  rVec.data = rData;
200  pVec.data = pData;
201 
202  memset( rData, 0, sizeof(rData) );
203  memset( pData, 0, sizeof(pData) );
204 
205  rData[0] = values[0];
206  pData[0] = values[2];
207  pData[1] = values[3] / values[0];
208  /* Calculate Hamiltonian using Cartesian vectors rVec and pVec */
209  H = XLALSimIMRSpinEOBHamiltonian( eta, &rVec, &pVec, s1Vec, s2Vec, sKerr, sStar, params.params->tortoise, params.params->seobCoeffs );
210 
211  //printf( "csi = %.16e, ham = %.16e ( tortoise = %d)\n", csi, H, params.params->tortoise );
212  //exit(1);
213  //if ( values[0] > 1.3 && values[0] < 3.9 ) printf( "r = %e\n", values[0] );
214  //if ( values[0] > 1.3 && values[0] < 3.9 ) printf( "Hamiltonian = %e\n", H );
215  H = H * (mass1 + mass2);
216 
217 
218  /*if ( values[0] > 1.3 && values[0] < 3.9 ) printf( "Cartesian derivatives:\n%f %f %f %f %f %f\n",
219  tmpDValues[3], tmpDValues[4], tmpDValues[5], -tmpDValues[0], -tmpDValues[1], -tmpDValues[2] );*/
220 
221  /* Now calculate omega, and hence the flux */
222  omega = tmpDValues[4] / r;
223  flux = XLALInspiralSpinFactorizedFlux( &polarDynamics, nqcCoeffs, omega, params.params, H/(mass1+mass2), lMax, SpinAlignedEOBversion );
224 
225  /* Looking at the non-spinning model, I think we need to divide the flux by eta */
226  flux = flux / eta;
227 
228  //printf( "Flux in derivatives function = %.16e\n", flux );
229 
230  /* Now we can calculate the final (spherical) derivatives */
231  /* csi is needed because we use the tortoise co-ordinate */
232  /* Right hand side of Eqs. 10a - 10d of Pan et al. PRD 84, 124052 (2011) */
233  dvalues[0] = csi * tmpDValues[3];
234  dvalues[1] = omega;
235  /* Note: in this special coordinate setting, namely y = z = 0, dpr/dt = dpx/dt + dy/dt * py/r, where py = pphi/r */
236  dvalues[2] = - tmpDValues[0] + tmpDValues[4] * values[3] / (r*r);
237  dvalues[2] = dvalues[2] * csi - ( values[2] / values[3] ) * flux / omega;
238  dvalues[3] = - flux / omega;
239 
240  //if ( values[0] > 1.3 && values[0] < 3.9 ) printf("Values:\n%f %f %f %f\n", values[0], values[1], values[2], values[3] );
241 
242  //if ( values[0] > 1.3 && values[0] < 3.9 ) printf("Derivatives:\n%f %f %f %f\n", dvalues[0], r*dvalues[1], dvalues[2], dvalues[3] );
243 
244  if ( isnan( dvalues[0] ) || isnan( dvalues[1] ) || isnan( dvalues[2] ) || isnan( dvalues[3] ) )
245  {
246  //printf( "Deriv is nan: %e %e %e %e\n", dvalues[0], dvalues[1], dvalues[2], dvalues[3] );
247  return 1;
248  }
249 
250  return XLAL_SUCCESS;
251 }
252 
253 #endif /* LALSIMIMRSPINALIGNEDEOBHCAPDERIVATIVE_C */
static int XLALSpinAlignedHcapDerivative(double t, const REAL8 values[], REAL8 dvalues[], void *funcParams)
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 double GSLSpinAlignedHamiltonianWrapper(double x, void *params)
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.
#define XLAL_CALLGSL(statement)
double i
Definition: bh_ringdown.c:118
const double H
const double csi
double REAL8
uint32_t UINT4
int32_t INT4
static const INT4 r
static const INT4 a
#define XLAL_ERROR(...)
int XLALPrintError(const char *fmt,...) _LAL_GCC_PRINTF_FORMAT_(1
XLAL_SUCCESS
XLAL_EFUNC
The coefficients which are used in calculating the non-quasicircular correction to the EOBNRv2 model.
REAL8 * data
Parameters for the spinning EOB model.
Definition: burst.c:245
LALDict * params
Definition: inspiral.c:248