21 #include <lal/LALStdio.h>
22 #include <lal/LALStdlib.h>
23 #include <lal/LALConstants.h>
24 #include <lal/Units.h>
25 #include <lal/AVFactories.h>
26 #include <lal/SeqFactories.h>
27 #include <lal/PulsarSimulateCoherentGW.h>
28 #include <lal/GenerateSpinOrbitCW.h>
29 #include <gsl/gsl_roots.h>
182 REAL8 upsilon, argument;
190 REAL8 oneMinusEcc, onePlusEcc;
193 REAL8 sine = 0.0, cose = 0.0;
203 GENERATESPINORBITCWH_MSGENUL );
205 GENERATESPINORBITCWH_MSGENUL );
209 GENERATESPINORBITCWH_MSGEOUT );
211 GENERATESPINORBITCWH_MSGEOUT );
213 GENERATESPINORBITCWH_MSGEOUT );
215 GENERATESPINORBITCWH_MSGEOUT );
220 GENERATESPINORBITCWH_MSGENUL );
221 nSpin =
params->f->length;
227 oneMinusEcc =
params->oneMinusEcc;
228 ecc = 1.0 - oneMinusEcc;
229 onePlusEcc = 1.0 + ecc;
230 if ( ecc < 0.0 || oneMinusEcc <= 0.0 ) {
232 GENERATESPINORBITCWH_MSGEECC );
238 vDotAvg =
params->angularSpeed
239 * sqrt( oneMinusEcc * oneMinusEcc * oneMinusEcc / onePlusEcc );
242 GENERATESPINORBITCWH_MSGEFTL );
244 if ( vp <= 0.0 ||
dt <= 0.0 ||
f0 <= 0.0 || vDotAvg <= 0.0 ||
247 GENERATESPINORBITCWH_MSGESGN );
255 a = vp * oneMinusEcc * cos( argument ) + oneMinusEcc - 1.0;
256 b = vp * sqrt( oneMinusEcc / ( onePlusEcc ) ) * sin( argument );
257 eCosOmega = ecc * cos( argument );
259 dxMax = 0.01 / (
f0 *
n *
dt );
261 dxMax = 0.01 / (
f0 *
p );
263 if ( dxMax < 1.0e-15 ) {
266 " precision for this orbit" );
273 if (
f0 * tau * vp * vp * ecc / onePlusEcc > 0.25 )
275 " effects that are not included" );
280 tPeriObs = (
REAL8 )(
params->orbitEpoch.gpsSeconds -
282 tPeriObs += 1.0e-9 * (
REAL8 )(
params->orbitEpoch.gpsNanoSeconds -
285 spinOff = (
REAL8 )(
params->orbitEpoch.gpsSeconds -
286 params->spinEpoch.gpsSeconds );
287 spinOff += 1.0e-9 * (
REAL8 )(
params->orbitEpoch.gpsNanoSeconds -
288 params->spinEpoch.gpsNanoSeconds );
294 GENERATESPINORBITCWH_MSGEMEM );
302 GENERATESPINORBITCWH_MSGEMEM );
312 GENERATESPINORBITCWH_MSGEMEM );
378 fData =
output->f->data->data;
379 phiData =
output->phi->data->data;
380 for (
i = 0;
i <
n;
i++ ) {
384 x = vDotAvg * (
i *
dt - tPeriObs );
392 INT4 maxiter = 100, iter = 0;
393 while ( iter < maxiter && fabs( dx =
e +
a * sine +
b * cose -
x ) > dxMax ) {
396 de = dx / ( 1.0 +
a * cose +
a -
b * sine );
399 }
else if ( de < -
LAL_PI ) {
410 cose = cos(
e ) - 1.0;
413 if ( iter == maxiter && fabs( dx =
e +
a * sine +
b * cose -
x ) > dxMax ) {
415 const gsl_root_fsolver_type *
T = gsl_root_fsolver_bisection;
416 gsl_root_fsolver *
s = gsl_root_fsolver_alloc(
T );
423 if ( gsl_root_fsolver_set(
s, &F, e_lo, e_hi ) != 0 ) {
430 ABORT(
stat, -1,
"GSL failed to set initial points" );
435 INT4 root_status = keepgoing;
438 while ( root_status == keepgoing && iter < maxiter ) {
440 root_status = gsl_root_fsolver_iterate(
s );
441 if ( root_status != keepgoing && root_status != success ) {
448 ABORT(
stat, -1,
"gsl_root_fsolver_iterate() failed" );
450 e = gsl_root_fsolver_root(
s );
452 cose = cos(
e ) - 1.0;
453 if ( fabs( dx =
e +
a * sine +
b * cose -
x ) > dxMax ) {
454 root_status = keepgoing;
456 root_status = success;
460 if ( root_status != success ) {
467 gsl_root_fsolver_free(
s );
468 ABORT(
stat, -1,
"Could not converge using bisection algorithm" );
471 gsl_root_fsolver_free(
s );
476 (
e +
LAL_TWOPI * nOrb - ecc * sine ) / vDotAvg + spinOff;
478 for (
j = 0;
j < nSpin;
j++ ) {
479 f += fSpin[
j] * tPow;
480 phi += fSpin[
j] * ( tPow *=
t ) / (
j + 2.0 );
484 upsilon = 2.0 * atan2( sqrt( onePlusEcc / oneMinusEcc ) * sin( 0.5 *
e ), cos( 0.5 *
e ) );
485 f *=
f0 / ( 1.0 + vp * ( cos( argument + upsilon ) + eCosOmega ) / onePlusEcc );
487 if ( (
i > 0 ) && ( fabs(
f - fPrev ) >
df ) ) {
488 df = fabs(
f - fPrev );
490 *( fData++ ) = fPrev =
f;
491 *( phiData++ ) = phi +
phi0;
static REAL8 gsl_E_solver(REAL8 e, void *p)
#define ABORT(statusptr, code, mesg)
#define ENDFAIL(statusptr)
#define TRY(func, statusptr)
#define ATTATCHSTATUSPTR(statusptr)
#define ASSERT(assertion, statusptr, code, mesg)
#define DETATCHSTATUSPTR(statusptr)
#define INITSTATUS(statusptr)
#define RETURN(statusptr)
#define BEGINFAIL(statusptr)
void LALSCreateVectorSequence(LALStatus *status, REAL4VectorSequence **vectorSequence, CreateVectorSequenceIn *vSeqParams)
#define GENERATESPINORBITCWH_EECC
Eccentricity out of range.
#define GENERATESPINORBITCWH_ESGN
Sign error: positive parameter expected.
void LALGenerateEllipticSpinOrbitCW(LALStatus *stat, PulsarCoherentGW *output, SpinOrbitCWParamStruc *params)
Computes a continuous waveform with frequency drift and Doppler modulation from an elliptical orbital...
#define GENERATESPINORBITCWH_EMEM
Out of memory.
#define GENERATESPINORBITCWH_ENUL
Unexpected null pointer in arguments.
#define GENERATESPINORBITCWH_EOUT
Output field a, f, phi, or shift already exists.
#define GENERATESPINORBITCWH_EFTL
Periapsis motion is faster than light.
int LALWarning(LALStatus *status, const char *warning)
const LALUnit lalStrainUnit
const LALUnit lalHertzUnit
const LALUnit lalDimensionlessUnit
void LALDCreateVector(LALStatus *, REAL8Vector **, UINT4)
void LALDDestroyVector(LALStatus *, REAL8Vector **)
void LALSDestroyVector(LALStatus *, REAL4Vector **)
void LALSCreateVector(LALStatus *, REAL4Vector **, UINT4)
p
RUN ANALYSIS SCRIPT ###.
This structure stores a representation of a plane gravitational wave propagating from a particular po...
This structure stores the parameters for constructing a gravitational waveform with both a Taylor-pol...