GenerateHyperbolicSpinOrbitCW.c

Go to the documentation of this file.
00001 /*
00002 *  Copyright (C) 2007 Teviet Creighton
00003 *
00004 *  This program is free software; you can redistribute it and/or modify
00005 *  it under the terms of the GNU General Public License as published by
00006 *  the Free Software Foundation; either version 2 of the License, or
00007 *  (at your option) any later version.
00008 *
00009 *  This program is distributed in the hope that it will be useful,
00010 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 *  GNU General Public License for more details.
00013 *
00014 *  You should have received a copy of the GNU General Public License
00015 *  along with with program; see the file COPYING. If not, write to the
00016 *  Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
00017 *  MA  02111-1307  USA
00018 */
00019 
00020 /**************** <lalVerbatim file="GenerateHyperbolicSpinOrbitCWCV">
00021 Author: Creighton, T. D.
00022 $Id: GenerateHyperbolicSpinOrbitCW.c,v 1.4 2007/06/08 14:41:47 bema Exp $
00023 **************************************************** </lalVerbatim> */
00024 
00025 /********************************************************** <lalLaTeX>
00026 
00027 \subsection{Module \texttt{GenerateHyperbolicSpinOrbitCW.c}}
00028 \label{ss:GenerateHyperbolicSpinOrbitCW.c}
00029 
00030 Computes a continuous waveform with frequency drift and Doppler
00031 modulation from a hyperbolic orbital trajectory.
00032 
00033 \subsubsection*{Prototypes}
00034 \vspace{0.1in}
00035 \input{GenerateHyperbolicSpinOrbitCWCP}
00036 \idx{LALGenerateHyperbolicSpinOrbitCW()}
00037 
00038 \subsubsection*{Description}
00039 
00040 This function computes a quaiperiodic waveform using the spindown and
00041 orbital parameters in \verb@*params@, storing the result in
00042 \verb@*output@.
00043 
00044 In the \verb@*params@ structure, the routine uses all the ``input''
00045 fields specified in \verb@GenerateSpinOrbitCW.h@, and sets all of the
00046 ``output'' fields.  If \verb@params->f@=\verb@NULL@, no spindown
00047 modulation is performed.  If \verb@params->oneMinusEcc@$\not<0$ (a
00048 non-hyperbolic orbit), or if
00049 \verb@params->rPeriNorm@$\times$\verb@params->angularSpeed@$\geq1$
00050 (faster-than-light speed at periapsis), an error is returned.
00051 
00052 In the \verb@*output@ structure, the field \verb@output->h@ is
00053 ignored, but all other pointer fields must be set to \verb@NULL@.  The
00054 function will create and allocate space for \verb@output->a@,
00055 \verb@output->f@, and \verb@output->phi@ as necessary.  The
00056 \verb@output->shift@ field will remain set to \verb@NULL@.
00057 
00058 \subsubsection*{Algorithm}
00059 
00060 For hyperbolic orbits, we combine Eqs.~(\ref{eq:spinorbit-tr}),
00061 (\ref{eq:spinorbit-t}), and~(\ref{eq:spinorbit-upsilon}) to get $t_r$
00062 directly as a function of $E$:
00063 \begin{eqnarray}
00064 t_r = t_p & + & \left(\frac{r_p \sin i}{c}\right)\sin\omega \nonumber\\
00065 \label{eq:tr-e3}
00066         & + & \frac{1}{n} \left( -E +
00067                 \left[v_p(e-1)\cos\omega + e\right]\sinh E
00068                 - \left[v_p\sqrt{\frac{e-1}{e+1}}\sin\omega\right]
00069                         [\cosh E - 1]\right) \;,
00070 \end{eqnarray}
00071 where $v_p=r_p\dot{\upsilon}_p\sin i/c$ is a normalized velocity at
00072 periapsis and $n=\dot{\upsilon}_p\sqrt{(1-e)^3/(1+e)}$ is a normalized
00073 angular speed for the orbit (the hyperbolic analogue of the mean
00074 angular speed for closed orbits).  For simplicity we write this as:
00075 \begin{equation}
00076 \label{eq:tr-e4}
00077 t_r = T_p + \frac{1}{n}\left( E + A\sinh E + B[\cosh E - 1] \right) \;,
00078 \end{equation}
00079 \begin{wrapfigure}{r}{0.28\textwidth}
00080 \vspace{-5ex}
00081 \begin{center}
00082 \resizebox{0.23\textwidth}{!}{\includegraphics{inject_hanomaly}} \\
00083 %\parbox{0.23\textwidth}{\caption{\label{fig:binary-orbit} Function to
00084 %be inverted to find eccentric anomaly.}}
00085 \end{center}
00086 \vspace{-5ex}
00087 \end{wrapfigure}
00088 where $T_p$ is the \emph{observed} time of periapsis passage.  Thus
00089 the key numerical procedure in this routine is to invert the
00090 expression $x=E+A\sinh E+B(\cosh E - 1)$ to get $E(x)$.  This function
00091 is sketched to the right (solid line), along with an approximation
00092 used for making an initial guess (dotted line), as described later.
00093 
00094 We note that $A^2-B^2<1$, although it approaches 1 when
00095 $e\rightarrow1$, or when $v_p\rightarrow1$ and either $e=0$ or
00096 $\omega=\pi$.  Except in this limit, Newton-Raphson methods will
00097 converge rapidly for any initial guess.  In this limit, though, the
00098 slope $dx/dE$ approaches zero at $E=0$, and an initial guess or
00099 iteration landing near this point will send the next iteration off to
00100 unacceptably large or small values.  A hybrid root-finding strategy is
00101 used to deal with this, and with the exponential behaviour of $x$ at
00102 large $E$.
00103 
00104 First, we compute $x=x_{\pm1}$ at $E=\pm1$.  If the desired $x$ lies
00105 in this range, we use a straightforward Newton-Raphson root finder,
00106 with the constraint that all guesses of $E$ are restricted to the
00107 domain $[-1,1]$.  This guarantees that the scheme will eventually find
00108 itself on a uniformly-convergent trajectory.
00109 
00110 Second, for $E$ outside of this range, $x$ is dominated by the
00111 exponential terms: $x\approx\frac{1}{2}(A+B)\exp(E)$ for $E\gg1$, and
00112 $x\approx-\frac{1}{2}(A-B)\exp(-E)$ for $E\ll-1$.  We therefore do an
00113 \emph{approximate} Newton-Raphson iteration on the function $\ln|x|$,
00114 where the approximation is that we take $d\ln|x|/d|E|\approx1$.  This
00115 involves computing an extra logarithm inside the loop, but gives very
00116 rapid convergence to high precision, since $\ln|x|$ is very nearly
00117 linear in these regions.
00118 
00119 At the start of the algorithm, we use an initial guess of
00120 $E=-\ln[-2(x-x_{-1})/(A-B)-\exp(1)]$ for $x<x_{-1}$, $E=x/x_{-1}$ for
00121 $x_{-1}\leq x\leq0$, $E=x/x_{+1}$ for $0\leq x\leq x_{+1}$, or
00122 $E=\ln[2(x-x_{+1})/(A+B)-\exp(1)]$ for $x>x_{+1}$.  We refine this
00123 guess until we get agreement to within 0.01 parts in part in
00124 $N_\mathrm{cyc}$ (where $N_\mathrm{cyc}$ is the larger of the number
00125 of wave cycles in a time $2\pi/n$, or the number of wave cycles in the
00126 entire waveform being generated), or one part in $10^{15}$ (an order
00127 of magnitude off the best precision possible with \verb@REAL8@
00128 numbers).  The latter case indicates that \verb@REAL8@ precision may
00129 fail to give accurate phasing, and one should consider modeling the
00130 orbit as a set of Taylor frequency coefficients \'{a} la
00131 \verb@LALGenerateTaylorCW()@.  On subsequent timesteps, we use the
00132 previous timestep as an initial guess, which is good so long as the
00133 timesteps are much smaller than $1/n$.
00134 
00135 Once a value of $E$ is found for a given timestep in the output
00136 series, we compute the system time $t$ via Eq.~(\ref{eq:spinorbit-t}),
00137 and use it to determine the wave phase and (non-Doppler-shifted)
00138 frequency via Eqs.~(\ref{eq:taylorcw-freq})
00139 and~(\ref{eq:taylorcw-phi}).  The Doppler shift on the frequency is
00140 then computed using Eqs.~(\ref{eq:spinorbit-upsilon})
00141 and~(\ref{eq:orbit-rdot}).  We use $\upsilon$ as an intermediate in
00142 the Doppler shift calculations, since expressing $\dot{R}$ directly in
00143 terms of $E$ results in expression of the form $(e-1)/(e\cosh E-1)$,
00144 which are difficult to simplify and face precision losses when
00145 $E\sim0$ and $e\rightarrow1$.  By contrast, solving for $\upsilon$ is
00146 numerically stable provided that the system \verb@atan2()@ function is
00147 well-designed.
00148 
00149 This routine does not account for relativistic timing variations, and
00150 issues warnings or errors based on the criterea of
00151 Eq.~(\ref{eq:relativistic-orbit}) in
00152 \verb@GenerateEllipticSpinOrbitCW.c@.
00153 
00154 \subsubsection*{Uses}
00155 \begin{verbatim}
00156 LALMalloc()                   LALFree()
00157 LALSCreateVectorSequence()    LALSDestroyVectorSequence()
00158 LALSCreateVector()            LALSDestroyVector()
00159 LALDCreateVector()            LALDDestroyVector()
00160 LALSnprintf()                 LALWarning()
00161 \end{verbatim}
00162 
00163 \subsubsection*{Notes}
00164 
00165 \vfill{\footnotesize\input{GenerateHyperbolicSpinOrbitCWCV}}
00166 
00167 ******************************************************* </lalLaTeX> */
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 /* <lalVerbatim file="GenerateHyperbolicSpinOrbitCWCP"> */
00181 void
00182 LALGenerateHyperbolicSpinOrbitCW( LALStatus             *stat,
00183                                   CoherentGW            *output,
00184                                   SpinOrbitCWParamStruc *params )
00185 { /* </lalVerbatim> */
00186   UINT4 n, i;              /* number of and index over samples */
00187   UINT4 nSpin = 0, j;      /* number of and index over spindown terms */
00188   REAL8 t, dt, tPow;       /* time, interval, and t raised to a power */
00189   REAL8 phi0, f0, twopif0; /* initial phase, frequency, and 2*pi*f0 */
00190   REAL8 f, fPrev;          /* current and previous values of frequency */
00191   REAL4 df = 0.0;          /* maximum difference between f and fPrev */
00192   REAL8 phi;               /* current value of phase */
00193   REAL8 vDotAvg;           /* nomalized orbital angular speed */
00194   REAL8 vp;                /* projected speed at periapsis */
00195   REAL8 upsilon, argument; /* true anomaly, and argument of periapsis */
00196   REAL8 eCosOmega;         /* eccentricity * cosine of argument */
00197   REAL8 tPeriObs;          /* time of observed periapsis */
00198   REAL8 spinOff;           /* spin epoch - orbit epoch */
00199   REAL8 x;                 /* observed ``mean anomaly'' */
00200   REAL8 xPlus, xMinus;     /* limits where exponentials dominate */
00201   REAL8 dx, dxMax;         /* current and target errors in x */
00202   REAL8 a, b;              /* constants in equation for x */
00203   REAL8 ecc;               /* orbital eccentricity */
00204   REAL8 eccMinusOne, eccPlusOne; /* ecc - 1 and ecc + 1 */
00205   REAL8 e;                       /* hyperbolic anomaly */
00206   REAL8 sinhe, coshe;            /* sinh of e, and cosh of e minus 1 */
00207   REAL8 *fSpin = NULL;           /* pointer to Taylor coefficients */
00208   REAL4 *fData;                  /* pointer to frequency data */
00209   REAL8 *phiData;                /* pointer to phase data */
00210 
00211   INITSTATUS( stat, "LALGenerateHyperbolicSpinOrbitCW",
00212               GENERATEHYPERBOLICSPINORBITCWC );
00213   ATTATCHSTATUSPTR( stat );
00214 
00215   /* Make sure parameter and output structures exist. */
00216   ASSERT( params, stat, GENERATESPINORBITCWH_ENUL,
00217           GENERATESPINORBITCWH_MSGENUL );
00218   ASSERT( output, stat, GENERATESPINORBITCWH_ENUL,
00219           GENERATESPINORBITCWH_MSGENUL );
00220 
00221   /* Make sure output fields don't exist. */
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   /* If Taylor coeficients are specified, make sure they exist. */
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   /* Set up some constants (to avoid repeated calculation or
00240      dereferencing), and make sure they have acceptable values. */
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   /* Set up some other constants. */
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   /* Compute offset between time series epoch and observed periapsis,
00294      and betweem true periapsis and spindown reference epoch. */
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   /* Determine bounds of hybrid root-finding algorithm, and initial
00306      guess for e. */
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   /* Allocate output structures. */
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   /* Set output structure metadata fields. */
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   /* Allocate phase and frequency arrays. */
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   /* Allocate and fill amplitude array. */
00375   {
00376     CreateVectorSequenceIn in; /* input to create output->a */
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   /* Fill frequency and phase arrays. */
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     /* Use approximate Newton-Raphson method on ln|x| if |x| > 1. */
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     /* Use ordinary Newton-Raphson method on x if |x| <= 1. */
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     /* Compute source emission time, phase, and frequency. */
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     /* Appy frequency Doppler shift. */
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   /* Set output field and return. */
00453   params->dfdt = df*dt;
00454   DETATCHSTATUSPTR( stat );
00455   RETURN( stat );
00456 }

Generated on Mon Oct 13 02:31:40 2008 for LAL by  doxygen 1.5.2