LALRungeKutta4.c

Go to the documentation of this file.
00001 /*
00002 *  Copyright (C) 2007 Duncan Brown, Gareth Jones, Jolien Creighton, B.S. Sathyaprakash, Craig Robinson
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="LALRungeKutta4CV">
00021 Author: Robinson, C. A.
00022 $Id: LALRungeKutta4.c,v 1.16 2007/06/08 14:41:49 bema Exp $
00023 </lalVerbatim>  */
00024 
00025 /*  <lalLaTeX>
00026 
00027 \subsection{Module \texttt{LALRungeKutta4.c}}
00028 \subsubsection*{Prototypes}
00029 \vspace{0.1in}
00030 \input{LALRungeKutta4CP}
00031 \idx{LALRungeKutta4()}
00032 
00033 \begin{itemize}
00034 \item {\tt n:} The number of coupled equations being integrated.
00035 \item {\tt yout:} The output values for the system after the time-step.
00036 \item {\tt input:} The input for the system
00037 \item {\tt integrator} Required for the GSL integratior. Created using {\tt XLALRungeKutta4Init()}.
00038 \item {\tt params} Parameters to be passed to the derivative function
00039 \end{itemize}
00040 
00041 \subsubsection*{Description}
00042 The code \texttt{LALRungeKutta4.c} solves a system of $n$ coupled first--order differential equations.
00043 Internally, it uses the gsl routines for performing adaptive step evolution of the system, but to the outside
00044 user, it returns results for a fixed step size.
00045 
00046 Prior to evolving a system using {\tt LALRungeKutta4()}, it is necessary to create the GSL integrator using
00047 {\tt XLALRungeKutta4Init()}. Once the evolution of the system has finished, this integrator should then
00048 be freed using {\tt XLALRungeKutta4Free()}.
00049 \subsubsection*{Algorithm}
00050 
00051 
00052 \subsubsection*{Uses}
00053 None.
00054 
00055 \subsubsection*{Notes}
00056 
00057 \vfill{\footnotesize\input{LALRungeKutta4CV}}
00058 
00059 </lalLaTeX>  */
00060 
00061 
00062 #include <lal/LALInspiral.h>
00063 
00064 struct RungeGSLParams {
00065   rk4In *input;
00066   void  *params;
00067 };
00068 
00069 static int derivativeGSLWrapper(
00070                                 REAL8 t,
00071                                 const REAL8 y[],
00072                                 REAL8 dydx[],
00073                                 void *params);
00074 
00075 
00076 
00077 NRCSID (LALRUNGEKUTTA4C, "$Id: LALRungeKutta4.c,v 1.16 2007/06/08 14:41:49 bema Exp $");
00078 
00079 /* Function for allocating memory and setting up the GSL integrator */
00080 /* <lalVerbatim file="LALRungeKutta4CP"> */
00081 rk4GSLIntegrator * XLALRungeKutta4Init( INT4 n,
00082                                         rk4In *input
00083                                       )
00084 { /* </lalVerbatim>  */
00085  
00086   static const char *func = "XLALRungeKutta4Init"; 
00087   rk4GSLIntegrator  *integrator = NULL;
00088   
00089   /* Check we have an input */
00090   if (!input)
00091     XLAL_ERROR_NULL(func, XLAL_EFAULT);
00092 
00093   /* Allocate memory for the integrator structure */
00094   if (!(integrator = (rk4GSLIntegrator *) LALCalloc(1, sizeof(rk4GSLIntegrator))))
00095   {
00096     XLAL_ERROR_NULL(func, XLAL_ENOMEM);
00097   }
00098 
00099   integrator->input = input;
00100 
00101   /* Set the algorithm to 4th-order Runge-Kutta */
00102   integrator->type = gsl_odeiv_step_rkf45;
00103 
00104   /* Allocate memory for data values */
00105   if (!(integrator->y = (REAL8 *) LALMalloc(n * sizeof(REAL8))))
00106   {
00107     LALFree(integrator);
00108     XLAL_ERROR_NULL(func, XLAL_ENOMEM);
00109   }
00110 
00111   /* Initialise GSL integrator */
00112   XLAL_CALLGSL( integrator->step    = gsl_odeiv_step_alloc(integrator->type, n) );
00113   XLAL_CALLGSL( integrator->control = gsl_odeiv_control_standard_new(1.0e-2, 1.0e-2, 1.0, 1.0) );
00114   XLAL_CALLGSL( integrator->evolve  = gsl_odeiv_evolve_alloc(n) );
00115 
00116   /* Check the integrator is allocated correctly */
00117   if (!(integrator->step) || !(integrator->control) || !(integrator->evolve))
00118   {
00119     XLALRungeKutta4Free( integrator );
00120     XLAL_ERROR_NULL(func, XLAL_ENOMEM);
00121   }
00122 
00123   return integrator;
00124 }  
00125 
00126 
00127 /*  <lalVerbatim file="LALRungeKutta4CP"> */
00128 void 
00129 LALRungeKutta4(
00130    LALStatus        *status,
00131    REAL8Vector      *yout,
00132    rk4GSLIntegrator *integrator,
00133    void             *params
00134    )
00135 { /* </lalVerbatim>  */
00136 
00137    INT4 i;
00138    REAL8 t = 0.0;
00139    struct RungeGSLParams gslParams;
00140    rk4In *input = NULL;
00141    REAL8 h;
00142    gsl_odeiv_system sys; 
00143   
00144    INITSTATUS(status, "LALRungeKutta4", LALRUNGEKUTTA4C);
00145    ATTATCHSTATUSPTR(status);
00146 
00147    ASSERT (yout, status, LALINSPIRALH_ENULL, LALINSPIRALH_MSGENULL);
00148    ASSERT (yout->data, status, LALINSPIRALH_ENULL, LALINSPIRALH_MSGENULL);
00149    ASSERT (integrator, status, LALINSPIRALH_ENULL, LALINSPIRALH_MSGENULL);
00150    ASSERT (integrator->input, status, LALINSPIRALH_ENULL, LALINSPIRALH_MSGENULL);
00151    ASSERT (params, status, LALINSPIRALH_ENULL, LALINSPIRALH_MSGENULL);
00152 
00153   /* Initialise GSL integrator */
00154 
00155   input = integrator->input;
00156   h     = input->h;  
00157 
00158   gslParams.input = input;
00159   gslParams.params = params;
00160 
00161   sys.function = derivativeGSLWrapper;
00162   sys.jacobian =  NULL;
00163   sys.dimension = input->n; 
00164   sys.params    = &gslParams;
00165 
00166 
00167   memcpy( integrator->y, input->y->data, input->n * sizeof(REAL8));
00168 
00169    /* Evolve the system */
00170   while (t < input->h)
00171   {
00172     REAL8 tOld = t;
00173     CALLGSL( gsl_odeiv_evolve_apply(integrator->evolve, integrator->control,
00174                  integrator->step, &sys,
00175                                 &t, input->h, &h, integrator->y), status );
00176     /*printf("h = %e, t = %e\n", h, t);*/
00177     BEGINFAIL(status)
00178     {  
00179         ABORT(status, LALINSPIRALH_ESTOPPED, LALINSPIRALH_MSGESTOPPED);
00180     }
00181     ENDFAIL(status);
00182 
00183     /* In case integration becomes degenerate */
00184     if (t == tOld)
00185     {
00186          for (i=0; i<input->n; i++)
00187            yout->data[i] = 0.0;
00188 
00189          ABORT(status, LALINSPIRALH_ESTOPPED, LALINSPIRALH_MSGESTOPPED);
00190     } 
00191   }
00192 
00193   memcpy( yout->data, integrator->y, input->n * sizeof(REAL8));
00194 
00195   DETATCHSTATUSPTR(status);
00196   RETURN (status);
00197 }
00198 
00199 
00200 /* Function for freeing up memory for the GSL integrator */
00201 /*  <lalVerbatim file="LALRungeKutta4CP"> */
00202 void XLALRungeKutta4Free( rk4GSLIntegrator *integrator )
00203 { /* </lalVerbatim> */
00204 
00205   static const char *func = "XLALRungeKutta4Free";
00206 
00207   if (!integrator) XLAL_ERROR_VOID(func, XLAL_EFAULT);
00208 
00209   /* Free the GSL integrator controls etc */
00210   if (integrator->evolve)  XLAL_CALLGSL( gsl_odeiv_evolve_free(integrator->evolve) );
00211   if (integrator->control) XLAL_CALLGSL( gsl_odeiv_control_free(integrator->control) );
00212   if (integrator->step)    XLAL_CALLGSL( gsl_odeiv_step_free(integrator->step) );
00213   LALFree( integrator->y );
00214   LALFree( integrator );
00215   return;
00216 }
00217 
00218 
00219 /* A simple wrapper function to allow GSL to use the LAL
00220    derivative functions */
00221 static int derivativeGSLWrapper(
00222                                 REAL8 t, 
00223                                 const REAL8 y[], 
00224                                 REAL8 dydx[],
00225                                 void *params)
00226 {
00227   struct RungeGSLParams *in = (struct RungeGSLParams *)params;
00228   REAL8Vector dyVect;
00229   REAL8Vector *yVect = in->input->yt;
00230 
00231   memcpy(yVect->data, y, in->input->n * sizeof(REAL8));
00232 
00233   dyVect.length = in->input->n;
00234   dyVect.data = dydx;
00235   in->input->function(yVect, &dyVect, in->params);
00236   return GSL_SUCCESS;
00237 }

Generated on Sun Sep 7 03:06:56 2008 for LAL by  doxygen 1.5.2