00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169 #include <lal/LALStdio.h>
00170 #include <lal/LALStdlib.h>
00171 #include <lal/LALConstants.h>
00172 #include <lal/Units.h>
00173 #include <lal/AVFactories.h>
00174 #include <lal/SeqFactories.h>
00175 #include <lal/SimulateCoherentGW.h>
00176 #include <lal/GenerateSpinOrbitCW.h>
00177
00178 NRCSID( GENERATEHYPERBOLICSPINORBITCWC, "$Id: GenerateHyperbolicSpinOrbitCW.c,v 1.4 2007/06/08 14:41:47 bema Exp $" );
00179
00180
00181 void
00182 LALGenerateHyperbolicSpinOrbitCW( LALStatus *stat,
00183 CoherentGW *output,
00184 SpinOrbitCWParamStruc *params )
00185 {
00186 UINT4 n, i;
00187 UINT4 nSpin = 0, j;
00188 REAL8 t, dt, tPow;
00189 REAL8 phi0, f0, twopif0;
00190 REAL8 f, fPrev;
00191 REAL4 df = 0.0;
00192 REAL8 phi;
00193 REAL8 vDotAvg;
00194 REAL8 vp;
00195 REAL8 upsilon, argument;
00196 REAL8 eCosOmega;
00197 REAL8 tPeriObs;
00198 REAL8 spinOff;
00199 REAL8 x;
00200 REAL8 xPlus, xMinus;
00201 REAL8 dx, dxMax;
00202 REAL8 a, b;
00203 REAL8 ecc;
00204 REAL8 eccMinusOne, eccPlusOne;
00205 REAL8 e;
00206 REAL8 sinhe, coshe;
00207 REAL8 *fSpin = NULL;
00208 REAL4 *fData;
00209 REAL8 *phiData;
00210
00211 INITSTATUS( stat, "LALGenerateHyperbolicSpinOrbitCW",
00212 GENERATEHYPERBOLICSPINORBITCWC );
00213 ATTATCHSTATUSPTR( stat );
00214
00215
00216 ASSERT( params, stat, GENERATESPINORBITCWH_ENUL,
00217 GENERATESPINORBITCWH_MSGENUL );
00218 ASSERT( output, stat, GENERATESPINORBITCWH_ENUL,
00219 GENERATESPINORBITCWH_MSGENUL );
00220
00221
00222 ASSERT( !( output->a ), stat, GENERATESPINORBITCWH_EOUT,
00223 GENERATESPINORBITCWH_MSGEOUT );
00224 ASSERT( !( output->f ), stat, GENERATESPINORBITCWH_EOUT,
00225 GENERATESPINORBITCWH_MSGEOUT );
00226 ASSERT( !( output->phi ), stat, GENERATESPINORBITCWH_EOUT,
00227 GENERATESPINORBITCWH_MSGEOUT );
00228 ASSERT( !( output->shift ), stat, GENERATESPINORBITCWH_EOUT,
00229 GENERATESPINORBITCWH_MSGEOUT );
00230
00231
00232 if ( params->f ) {
00233 ASSERT( params->f->data, stat, GENERATESPINORBITCWH_ENUL,
00234 GENERATESPINORBITCWH_MSGENUL );
00235 nSpin = params->f->length;
00236 fSpin = params->f->data;
00237 }
00238
00239
00240
00241 eccMinusOne = -params->oneMinusEcc;
00242 ecc = 1.0 + eccMinusOne;
00243 eccPlusOne = 2.0 + eccMinusOne;
00244 if ( eccMinusOne <= 0.0 ) {
00245 ABORT( stat, GENERATESPINORBITCWH_EECC,
00246 GENERATESPINORBITCWH_MSGEECC );
00247 }
00248 vp = params->rPeriNorm*params->angularSpeed;
00249 vDotAvg = params->angularSpeed
00250 *sqrt( eccMinusOne*eccMinusOne*eccMinusOne/eccPlusOne );
00251 n = params->length;
00252 dt = params->deltaT;
00253 f0 = fPrev = params->f0;
00254 if ( vp >= 1.0 ) {
00255 ABORT( stat, GENERATESPINORBITCWH_EFTL,
00256 GENERATESPINORBITCWH_MSGEFTL );
00257 }
00258 if ( vp <= 0.0 || dt <= 0.0 || f0 <= 0.0 || vDotAvg <= 0.0 ||
00259 n == 0 ) {
00260 ABORT( stat, GENERATESPINORBITCWH_ESGN,
00261 GENERATESPINORBITCWH_MSGESGN );
00262 }
00263
00264
00265 twopif0 = f0*LAL_TWOPI;
00266 phi0 = params->phi0;
00267 argument = params->omega;
00268 a = vp*eccMinusOne*cos( argument ) + ecc;
00269 b = -vp*sqrt( eccMinusOne/eccPlusOne )*sin( argument );
00270 eCosOmega = ecc*cos( argument );
00271 if ( n*dt*vDotAvg > LAL_TWOPI )
00272 dxMax = 0.01/( f0*n*dt );
00273 else
00274 dxMax = 0.01/( f0*LAL_TWOPI/vDotAvg );
00275 if ( dxMax < 1.0e-15 ) {
00276 dxMax = 1.0e-15;
00277 #ifndef NDEBUG
00278 LALWarning( stat, "REAL8 arithmetic may not have sufficient"
00279 " precision for this orbit" );
00280 #endif
00281 }
00282 #ifndef NDEBUG
00283 if ( lalDebugLevel & LALWARNING ) {
00284 REAL8 tau = n*dt;
00285 if ( tau > LAL_TWOPI/vDotAvg )
00286 tau = LAL_TWOPI/vDotAvg;
00287 if ( f0*tau*vp*vp*ecc/eccPlusOne > 0.25 )
00288 LALWarning( stat, "Orbit may have significant relativistic"
00289 " effects that are not included" );
00290 }
00291 #endif
00292
00293
00294
00295 tPeriObs = (REAL8)( params->orbitEpoch.gpsSeconds -
00296 params->epoch.gpsSeconds );
00297 tPeriObs += 1.0e-9 * (REAL8)( params->orbitEpoch.gpsNanoSeconds -
00298 params->epoch.gpsNanoSeconds );
00299 tPeriObs += params->rPeriNorm*sin( params->omega );
00300 spinOff = (REAL8)( params->orbitEpoch.gpsSeconds -
00301 params->spinEpoch.gpsSeconds );
00302 spinOff += 1.0e-9 * (REAL8)( params->orbitEpoch.gpsNanoSeconds -
00303 params->spinEpoch.gpsNanoSeconds );
00304
00305
00306
00307 xMinus = 1.0 + a*sinh( -1.0 ) + b*cosh( -1.0 ) - b;
00308 xPlus = -1.0 + a*sinh( 1.0 ) + b*cosh( 1.0 ) - b;
00309 x = -vDotAvg*tPeriObs;
00310 if ( x < xMinus )
00311 e = -log( -2.0*( x - xMinus )/( a - b ) - exp( 1.0 ) );
00312 else if ( x <= 0 )
00313 e = x/xMinus;
00314 else if ( x <= xPlus )
00315 e = x/xPlus;
00316 else
00317 e = log( 2.0*( x - xPlus )/( a + b ) - exp( 1.0 ) );
00318 sinhe = sinh( e );
00319 coshe = cosh( e ) - 1.0;
00320
00321
00322 if ( ( output->a = (REAL4TimeVectorSeries *)
00323 LALMalloc( sizeof(REAL4TimeVectorSeries) ) ) == NULL ) {
00324 ABORT( stat, GENERATESPINORBITCWH_EMEM,
00325 GENERATESPINORBITCWH_MSGEMEM );
00326 }
00327 memset( output->a, 0, sizeof(REAL4TimeVectorSeries) );
00328 if ( ( output->f = (REAL4TimeSeries *)
00329 LALMalloc( sizeof(REAL4TimeSeries) ) ) == NULL ) {
00330 LALFree( output->a ); output->a = NULL;
00331 ABORT( stat, GENERATESPINORBITCWH_EMEM,
00332 GENERATESPINORBITCWH_MSGEMEM );
00333 }
00334 memset( output->f, 0, sizeof(REAL4TimeSeries) );
00335 if ( ( output->phi = (REAL8TimeSeries *)
00336 LALMalloc( sizeof(REAL8TimeSeries) ) ) == NULL ) {
00337 LALFree( output->a ); output->a = NULL;
00338 LALFree( output->f ); output->f = NULL;
00339 ABORT( stat, GENERATESPINORBITCWH_EMEM,
00340 GENERATESPINORBITCWH_MSGEMEM );
00341 }
00342 memset( output->phi, 0, sizeof(REAL8TimeSeries) );
00343
00344
00345 output->position = params->position;
00346 output->psi = params->psi;
00347 output->a->epoch = output->f->epoch = output->phi->epoch
00348 = params->epoch;
00349 output->a->deltaT = n*params->deltaT;
00350 output->f->deltaT = output->phi->deltaT = params->deltaT;
00351 output->a->sampleUnits = lalStrainUnit;
00352 output->f->sampleUnits = lalHertzUnit;
00353 output->phi->sampleUnits = lalDimensionlessUnit;
00354 LALSnprintf( output->a->name, LALNameLength, "CW amplitudes" );
00355 LALSnprintf( output->f->name, LALNameLength, "CW frequency" );
00356 LALSnprintf( output->phi->name, LALNameLength, "CW phase" );
00357
00358
00359 LALSCreateVector( stat->statusPtr, &( output->f->data ), n );
00360 BEGINFAIL( stat ) {
00361 LALFree( output->a ); output->a = NULL;
00362 LALFree( output->f ); output->f = NULL;
00363 LALFree( output->phi ); output->phi = NULL;
00364 } ENDFAIL( stat );
00365 LALDCreateVector( stat->statusPtr, &( output->phi->data ), n );
00366 BEGINFAIL( stat ) {
00367 TRY( LALSDestroyVector( stat->statusPtr, &( output->f->data ) ),
00368 stat );
00369 LALFree( output->a ); output->a = NULL;
00370 LALFree( output->f ); output->f = NULL;
00371 LALFree( output->phi ); output->phi = NULL;
00372 } ENDFAIL( stat );
00373
00374
00375 {
00376 CreateVectorSequenceIn in;
00377 in.length = 2;
00378 in.vectorLength = 2;
00379 LALSCreateVectorSequence( stat->statusPtr, &(output->a->data), &in );
00380 BEGINFAIL( stat ) {
00381 TRY( LALSDestroyVector( stat->statusPtr, &( output->f->data ) ),
00382 stat );
00383 TRY( LALDDestroyVector( stat->statusPtr, &( output->phi->data ) ),
00384 stat );
00385 LALFree( output->a ); output->a = NULL;
00386 LALFree( output->f ); output->f = NULL;
00387 LALFree( output->phi ); output->phi = NULL;
00388 } ENDFAIL( stat );
00389 output->a->data->data[0] = output->a->data->data[2] = params->aPlus;
00390 output->a->data->data[1] = output->a->data->data[3] = params->aCross;
00391 }
00392
00393
00394 fData = output->f->data->data;
00395 phiData = output->phi->data->data;
00396 for ( i = 0; i < n; i++ ) {
00397
00398 x = vDotAvg*( i*dt - tPeriObs );
00399
00400
00401 if ( x < xMinus ) {
00402 x = log( -x );
00403 while ( fabs( dx = log( e - a*sinhe - b*coshe ) - x ) > dxMax ) {
00404 e += dx;
00405 sinhe = sinh( e );
00406 coshe = cosh( e ) - 1.0;
00407 }
00408 }
00409 else if ( x > xPlus ) {
00410 x = log( x );
00411 while ( fabs( dx = log( -e + a*sinhe + b*coshe ) - x ) > dxMax ) {
00412 e -= dx;
00413 sinhe = sinh( e );
00414 coshe = cosh( e ) - 1.0;
00415 }
00416 }
00417
00418
00419 else {
00420 while ( fabs( dx = -e + a*sinhe + b*coshe - x ) > dxMax ) {
00421 e -= dx/( -1.0 + a*coshe + a + b*sinhe );
00422 if ( e < -1.0 )
00423 e = -1.0;
00424 else if ( e > 1.0 )
00425 e = 1.0;
00426 sinhe = sinh( e );
00427 coshe = cosh( e ) - 1.0;
00428 }
00429 }
00430
00431
00432 phi = t = tPow =
00433 ( ecc*sinhe - e )/vDotAvg + spinOff;
00434 f = 1.0;
00435 for ( j = 0; j < nSpin; j++ ) {
00436 f += fSpin[j]*tPow;
00437 phi += fSpin[j]*( tPow*=t )/( j + 2.0 );
00438 }
00439
00440
00441 upsilon = 2.0*atan2( sqrt( eccPlusOne*coshe ),
00442 sqrt( eccMinusOne*( coshe + 2.0 ) ) );
00443 f *= f0 / ( 1.0 + vp*( cos( argument + upsilon ) + eCosOmega )
00444 /eccPlusOne );
00445 phi *= twopif0;
00446 if ( fabs( f - fPrev ) > df )
00447 df = fabs( f - fPrev );
00448 *(fData++) = fPrev = f;
00449 *(phiData++) = phi + phi0;
00450 }
00451
00452
00453 params->dfdt = df*dt;
00454 DETATCHSTATUSPTR( stat );
00455 RETURN( stat );
00456 }