Task: Implement make.code.defn for CactusNumerical/TestLocalReduce thorn

thorn_name: CactusNumerical/TestLocalReduce
src_filename: make.code.defn
interface: # Interface definition for thorn TestLocalReduce
# $Header$

implements: TestLocalReduce

public:
real real_vals type=scalar
{
  real_max_3D
  real_max_2D
  real_max_1D

  real_sum_3D
  real_sum_2D
  real_sum_1D

  real_avg_3D
  real_avg_2D
  real_avg_1D
  
} "results from real reduction"

int int_vals type=scalar
{
  int_max_3D
  int_max_2D
  int_max_1D

  int_sum_3D
  int_sum_2D
  int_sum_1D

  int_avg_3D
  int_avg_2D
  int_avg_1D

} "results from int reduction"

schedule: # Schedule definitions for thorn TestLocalReduce
# $Header$


STORAGE: real_vals int_vals

schedule TestLocalReduceC_Maximum at CCTK_POSTINITIAL
{
  LANG: C
} "Test out maximum reductions from C"

schedule TestLocalReduceC_Sum at CCTK_POSTINITIAL
{
  LANG: C
} "Test out sum reductions from C"

schedule TestLocalReduceC_Avg at CCTK_POSTINITIAL
{
  LANG: C
} "Test out avg reductions from C"


param: # Parameter definitions for thorn TestLocalReduce
# $Header$

INT array_nx "Size of arrays in x direction"
{
  0:* :: ""
} 4

INT array_ny "Size of arrays in y direction"
{
  0:* :: ""
} 5

INT array_nz "Size of arrays in z direction"
{
  0:* :: ""
} 10

context: Reduce_Maximum.c:
```
 /*@@
   @file      Reduce_Maximum.c
   @date      Tues Sep  7 16:00:29 2004
   @author    Yaakoub El Khamra
   @desc
              Test the new local maximum reduction implementation
   @enddesc
   @version   $Id$
 @@*/

#include <stdlib.h>

#include "cctk.h"
#include "util_Table.h"

#include "cctk_Arguments.h"
#include "cctk_Parameters.h"

static const char *rcsid = "$Header$";

CCTK_FILEVERSION(CactusTest_TestLocalReduce_Reduce_Maximum_c)

/********************************************************************
 *********************  Scheduled Routine Prototypes  ***************
 ********************************************************************/

void TestLocalReduceC_Maximum(CCTK_ARGUMENTS);

/********************************************************************
 *********************  Scheduled Routines  *************************
 ********************************************************************/

/*@@
   @routine TestLocalReduceC_Maximum
   @author     Yaakoub Y El Khamra
   @date       Tues Sep  7 16:00:29 2004
   @desc
               Tests local maximum reduction
   @enddesc
   @calls      CCTK_LocalArrayReductionHandle
               CCTK_ReduceLocalArrays

   @returntype void
 @@*/
void TestLocalReduceC_Maximum(CCTK_ARGUMENTS)
{
  DECLARE_CCTK_ARGUMENTS
  DECLARE_CCTK_PARAMETERS

  int handle,ierr;
  int i,j,k, index1, index2;

  /* input array void * pointers */
  const void* input_array[2];

  /* arrays containing data */
  CCTK_REAL * real_3D_array;
  CCTK_INT  * int_3D_array;

  CCTK_REAL * real_2D_array;
  CCTK_INT  * int_2D_array;
  
  CCTK_REAL * real_1D_array;
  CCTK_INT  * int_1D_array;

  /* arrays containing dimensions of data */
  CCTK_INT input_array_dims3D[3];
  CCTK_INT input_array_dims2D[2];
  CCTK_INT input_array_dims1D[1];

  /* array containing types of data */
  CCTK_INT input_array_type_codes[2];

  /* output data */
  void*  reduction_3D_value[2];
  void*  reduction_2D_value[2];
  void*  reduction_1D_value[2];
  
  /* allocate memory to arrays */
  real_3D_array = (CCTK_REAL *) malloc (array_nx*array_ny*array_nz* sizeof(CCTK_REAL));
  int_3D_array = (CCTK_INT *) malloc (array_nx*array_ny*array_nz* sizeof(CCTK_REAL));

  real_2D_array = (CCTK_REAL *) malloc (array_nx*array_ny* sizeof(CCTK_REAL));
  int_2D_array = (CCTK_INT *) malloc (array_nx*array_ny* sizeof(CCTK_REAL));

  real_1D_array = (CCTK_REAL *) malloc (array_nx* sizeof(CCTK_REAL));
  int_1D_array = (CCTK_INT *) malloc (array_nx* sizeof(CCTK_REAL));

  /* setting dimensions */
  input_array_dims3D[0] = array_nx;
  input_array_dims3D[1] = array_ny;
  input_array_dims3D[2] = array_nz;

  input_array_dims2D[0] = array_nx;
  input_array_dims2D[1] = array_ny;

  input_array_dims1D[0] = array_nx;

  /* filling in values in 3,2 and 1D arrays */
  for (i=0;i<array_nx;i++)
  {
    real_1D_array[i] = (CCTK_REAL)(i+1);
    int_1D_array[i]  = (CCTK_INT)(i+2);
    for(j=0;j<array_ny;j++)
    {
      index1 = i + array_nx*j;
      real_2D_array[index1] = (CCTK_REAL)((i+1)*(j+1));
      int_2D_array[index1]  = (CCTK_INT)((i+2)*(j+2));
      for(k=0;k<array_nz;k++)
      {
        index2 = i + array_nx*(j+array_ny*k);
        real_3D_array[index2] = (CCTK_REAL)((i+1)*(j+1)*(k+1));
        int_3D_array[index2]  = (CCTK_INT)((i+2)*(j+2)*(k+2));
      }
    }
  }
      
  /* make sure all pointers point to valid memory locations */  
  reduction_3D_value[0] = real_max_3D;
  reduction_3D_value[1] = int_max_3D;
  reduction_2D_value[0] = real_max_2D;
  reduction_2D_value[1] = int_max_2D;
  reduction_1D_value[0] = real_max_1D;
  reduction_1D_value[1] = int_max_1D;
  

  input_array_type_codes[0]  = CCTK_VARIABLE_REAL;
  input_array_type_codes[1]  = CCTK_VARIABLE_INT;

  /* 3D Array */
  handle = CCTK_LocalArrayReductionHandle("maximum");
  input_array[0] = real_3D_array;
  input_array[1] = int_3D_array;

  if (handle >= 0)
  {
    ierr =  CCTK_ReduceLocalArrays (3, handle, 0, 2, input_array_dims3D, input_array_type_codes,input_array , 2, input_array_type_codes, reduction_3D_value);
  }
  else
  {
    CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
                "TestLocalReduce: Invalid reduction operator '%s' with handle '%d'", 
                "maximum", handle);
  }

  /* 2D Array */
  handle = CCTK_LocalArrayReductionHandle("maximum");
  input_array[0] = real_2D_array;
  input_array[1] = int_2D_array;

  if (handle >= 0)
  {
    ierr =  CCTK_ReduceLocalArrays (2, handle, 0, 2, input_array_dims3D, input_array_type_codes,input_array , 2, input_array_type_codes, reduction_2D_value);
  }
  else
  {
    CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
                "TestLocalReduce: Invalid reduction operator '%s' with handle '%d'", 
                "maximum", handle);
  }

  /* 1D Array */
  handle = CCTK_LocalArrayReductionHandle("maximum");
  input_array[0] = real_1D_array;
  input_array[1] = int_1D_array;

  if (handle >= 0)
  {
    ierr =  CCTK_ReduceLocalArrays (1, handle, 0, 2, input_array_dims3D, input_array_type_codes,input_array , 2, input_array_type_codes, reduction_1D_value);
  }
  else
  {
    CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
                "TestLocalReduce: Invalid reduction operator '%s' with handle '%d'", 
                "maximum", handle);
  }

  /* freeing memory */
  free (real_3D_array );
  free (int_3D_array );
  free (real_2D_array );
  free (int_2D_array );
  free (real_1D_array );
  free (int_1D_array );

  return;

}

```

Reduce_Avg.c:
```
 /*@@
   @file      Reduce_Avg.c
   @date      Tue Aug 31 12:48:07 2004
   @author    Yaakoub Y El-Khamra
   @desc 
   Test the local reduction interface and operators.
   @enddesc 
   @version $Header$
 @@*/

#include <stdlib.h>

#include "cctk.h"
#include "cctk_Arguments.h"
#include "cctk_Parameters.h"

static const char *rcsid = "$Header$";

CCTK_FILEVERSION(CactusTest_TestLocalReduce_Reduce_avg_c);

/********************************************************************
 *********************  Scheduled Routine Prototypes  ***************
 ********************************************************************/

void TestLocalReduceC_Avg(CCTK_ARGUMENTS);

/********************************************************************
 *********************  Scheduled Routines  *************************
 ********************************************************************/

/*@@
   @routine TestLocalReduceC_Avg
   @author     Yaakoub Y El Khamra
   @date       Tues Sep  7 16:00:29 2004
   @desc
               Tests local average (mean) reduction
   @enddesc
   @calls      CCTK_LocalArrayReductionHandle
               CCTK_ReduceLocalArrays

   @returntype void
 @@*/
void TestLocalReduceC_Avg(CCTK_ARGUMENTS)
{
  DECLARE_CCTK_ARGUMENTS;
  DECLARE_CCTK_PARAMETERS;

  int handle,ierr;
  int i,j,k, index1, index2;

  /* input array void * pointers */
  const void* input_array[2];

  /* arrays containing data */
  CCTK_REAL * real_3D_array;
  CCTK_INT  * int_3D_array;

  CCTK_REAL * real_2D_array;
  CCTK_INT  * int_2D_array;
  
  CCTK_REAL * real_1D_array;
  CCTK_INT  * int_1D_array;

  /* arrays containing dimensions of data */
  CCTK_INT input_array_dims3D[3];
  CCTK_INT input_array_dims2D[2];
  CCTK_INT input_array_dims1D[1];

  /* array containing types of data */
  CCTK_INT input_array_type_codes[2];

  /* output data */
  void*  reduction_3D_value[2];
  void*  reduction_2D_value[2];
  void*  reduction_1D_value[2];
  
  /* allocate memory to arrays */
  real_3D_array = (CCTK_REAL *) malloc (array_nx*array_ny*array_nz* sizeof(CCTK_REAL));
  int_3D_array = (CCTK_INT *) malloc (array_nx*array_ny*array_nz* sizeof(CCTK_REAL));

  real_2D_array = (CCTK_REAL *) malloc (array_nx*array_ny* sizeof(CCTK_REAL));
  int_2D_array = (CCTK_INT *) malloc (array_nx*array_ny* sizeof(CCTK_REAL));

  real_1D_array = (CCTK_REAL *) malloc (array_nx* sizeof(CCTK_REAL));
  int_1D_array = (CCTK_INT *) malloc (array_nx* sizeof(CCTK_REAL));

  /* setting dimensions */
  input_array_dims3D[0] = array_nx;
  input_array_dims3D[1] = array_ny;
  input_array_dims3D[2] = array_nz;

  input_array_dims2D[0] = array_nx;
  input_array_dims2D[1] = array_ny;

  input_array_dims1D[0] = array_nx;

  /* filling in values in 3,2 and 1D arrays */
  for (i=0;i<array_nx;i++)
  {
    real_1D_array[i] = (CCTK_REAL)(i+1);
    int_1D_array[i]  = (CCTK_INT)(i+2);
    for(j=0;j<array_ny;j++)
    {
      index1 = i + array_nx*j;
      real_2D_array[index1] = (CCTK_REAL)((i+1)*(j+1));
      int_2D_array[index1]  = (CCTK_INT)((i+2)*(j+2));
      for(k=0;k<array_nz;k++)
      {
        index2 = i + array_nx*(j+array_ny*k);
        real_3D_array[index2] = (CCTK_REAL)((i+1)*(j+1)*(k+1));
        int_3D_array[index2]  = (CCTK_INT)((i+2)*(j+2)*(k+2));
      }
    }
  }
      
  /* make sure all pointers point to valid memory locations */  
  reduction_3D_value[0] = real_avg_3D;
  reduction_3D_value[1] = int_avg_3D;
  reduction_2D_value[0] = real_avg_2D;
  reduction_2D_value[1] = int_avg_2D;
  reduction_1D_value[0] = real_avg_1D;
  reduction_1D_value[1] = int_avg_1D;
  

  input_array_type_codes[0]  = CCTK_VARIABLE_REAL;
  input_array_type_codes[1]  = CCTK_VARIABLE_INT;

  /* 3D Array */
  handle = CCTK_LocalArrayReductionHandle("mean");
  input_array[0] = real_3D_array;
  input_array[1] = int_3D_array;

  if (handle >= 0)
  {
    ierr =  CCTK_ReduceLocalArrays (3, handle, 0, 2, input_array_dims3D, input_array_type_codes,input_array , 2, input_array_type_codes, reduction_3D_value);
  }
  else
  {
    CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
                "TestLocalReduce: Invalid reduction operator '%s' with handle '%d'", 
                "sum", handle);
  }

  /* 2D Array */
  handle = CCTK_LocalArrayReductionHandle("mean");
  input_array[0] = real_2D_array;
  input_array[1] = int_2D_array;

  if (handle >= 0)
  {
    ierr =  CCTK_ReduceLocalArrays (2, handle, 0, 2, input_array_dims3D, input_array_type_codes,input_array , 2, input_array_type_codes, reduction_2D_value);

  }
  else
  {
    CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
                "TestLocalReduce: Invalid reduction operator '%s' with handle '%d'", 
                "sum", handle);
  }

  /* 1D Array */
  handle = CCTK_LocalArrayReductionHandle("mean");
  input_array[0] = real_1D_array;
  input_array[1] = int_1D_array;

  if (handle >= 0)
  {
    ierr =  CCTK_ReduceLocalArrays (1, handle, 0, 2, input_array_dims3D, input_array_type_codes,input_array , 2, input_array_type_codes, reduction_1D_value);

  }
  else
  {
    CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
                "TestLocalReduce: Invalid reduction operator '%s' with handle '%d'", 
                "sum", handle);
  }
  
  /* freeing memory */
  free (real_3D_array );
  free (int_3D_array );
  free (real_2D_array );
  free (int_2D_array );
  free (real_1D_array );
  free (int_1D_array );

  return;

}

```

Reduce_Sum.c:
```
 /*@@
   @file      Reduce_Sum.c
   @date      Tues Sep  7 16:00:29 2004
   @author    Yaakoub El Khamra
   @desc
              Test the new local sum reduction implementation
   @enddesc
   @version   $Id$
 @@*/

#include <stdlib.h>

#include "cctk.h"
#include "cctk_Arguments.h"
#include "cctk_Parameters.h"

static const char *rcsid = "$Header$";

CCTK_FILEVERSION(CactusTest_TestLocalReduce_Reduce_sum_c)

/********************************************************************
 *********************  Scheduled Routine Prototypes  ***************
 ********************************************************************/

void TestLocalReduceC_Sum(CCTK_ARGUMENTS);

/********************************************************************
 *********************  Scheduled Routines  *************************
 ********************************************************************/

/*@@
   @routine TestLocalReduceC_Sum
   @author     Yaakoub Y El Khamra
   @date       Tues Sep  7 16:00:29 2004
   @desc
               Tests local sum reduction
   @enddesc
   @calls      CCTK_LocalArrayReductionHandle
               CCTK_ReduceLocalArrays

   @returntype void
 @@*/
void TestLocalReduceC_Sum(CCTK_ARGUMENTS)
{
  DECLARE_CCTK_ARGUMENTS
  DECLARE_CCTK_PARAMETERS

  int handle,ierr;
  int i,j,k,index1,index2;

  /* input array void * pointers */
  const void* input_array[2];
  /* arrays containing data */
  CCTK_REAL * real_3D_array;
  CCTK_INT  * int_3D_array;

  CCTK_REAL * real_2D_array;
  CCTK_INT  * int_2D_array;
  
  CCTK_REAL * real_1D_array;
  CCTK_INT  * int_1D_array;

  /* arrays containing dimensions of data */
  CCTK_INT input_array_dims3D[3];
  CCTK_INT input_array_dims2D[2];
  CCTK_INT input_array_dims1D[1];

  /* array containing types of data */
  CCTK_INT input_array_type_codes[2];

  /* output data */
  void*  reduction_3D_value[2];
  void*  reduction_2D_value[2];
  void*  reduction_1D_value[2];
  
  /* allocate memory to arrays */
  real_3D_array = (CCTK_REAL *) malloc (array_nx*array_ny*array_nz* sizeof(CCTK_REAL));
  int_3D_array = (CCTK_INT *) malloc (array_nx*array_ny*array_nz* sizeof(CCTK_REAL));

  real_2D_array = (CCTK_REAL *) malloc (array_nx*array_ny* sizeof(CCTK_REAL));
  int_2D_array = (CCTK_INT *) malloc (array_nx*array_ny* sizeof(CCTK_REAL));

  real_1D_array = (CCTK_REAL *) malloc (array_nx* sizeof(CCTK_REAL));
  int_1D_array = (CCTK_INT *) malloc (array_nx* sizeof(CCTK_REAL));

  /* setting dimensions */

  input_array_dims3D[0] = array_nx;
  input_array_dims3D[1] = array_ny;
  input_array_dims3D[2] = array_nz;

  input_array_dims2D[0] = array_nx;
  input_array_dims2D[1] = array_ny;

  input_array_dims1D[0] = array_nx;

  /* filling in values in 3,2 and 1D arrays */
  for (i=0;i<array_nx;i++)
  {
    real_1D_array[i] = (CCTK_REAL)(i+1);
    int_1D_array[i]  = (CCTK_INT)(i+2);
    for(j=0;j<array_ny;j++)
    {
      index1 = i + array_nx*j;
      real_2D_array[index1] = (CCTK_REAL)((i+1)*(j+1));
      int_2D_array[index1]  = (CCTK_INT)((i+2)*(j+2));
      for(k=0;k<array_nz;k++)
      {
        index2 = i + array_nx*(j+array_ny*k);
        real_3D_array[index2] = (CCTK_REAL)((i+1)*(j+1)*(k+1));
        int_3D_array[index2]  = (CCTK_INT)((i+2)*(j+2)*(k+2));
      }
    }
  }
      
  /* make sure all pointers point to valid memory locations */  
  reduction_3D_value[0] = real_sum_3D;
  reduction_3D_value[1] = int_sum_3D;
  reduction_2D_value[0] = real_sum_2D;
  reduction_2D_value[1] = int_sum_2D;
  reduction_1D_value[0] = real_sum_1D;
  reduction_1D_value[1] = int_sum_1D;
  

  input_array_type_codes[0]  = CCTK_VARIABLE_REAL;
  input_array_type_codes[1]  = CCTK_VARIABLE_INT;

  /* 3D Array */
  handle = CCTK_LocalArrayReductionHandle("sum");
  input_array[0] = real_3D_array;
  input_array[1] = int_3D_array;

  if (handle >= 0)
  {
    ierr =  CCTK_ReduceLocalArrays (3, handle, 0, 2, input_array_dims3D, input_array_type_codes,input_array , 2, input_array_type_codes, reduction_3D_value);
  }
  else
  {
    CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
                "TestLocalReduce: Invalid reduction operator '%s' with handle '%d'", 
                "sum", handle);
  }

  /* 2D Array */
  handle = CCTK_LocalArrayReductionHandle("sum");
  input_array[0] = real_2D_array;
  input_array[1] = int_2D_array;

  if (handle >= 0)
  {
    ierr =  CCTK_ReduceLocalArrays (2, handle, 0, 2, input_array_dims3D, input_array_type_codes,input_array , 2, input_array_type_codes, reduction_2D_value);

  }
  else
  {
    CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
                "TestLocalReduce: Invalid reduction operator '%s' with handle '%d'", 
                "sum", handle);
  }

  /* 1D Array */
  handle = CCTK_LocalArrayReductionHandle("sum");
  input_array[0] = real_1D_array;
  input_array[1] = int_1D_array;

  if (handle >= 0)
  {
    ierr =  CCTK_ReduceLocalArrays (1, handle, 0, 2, input_array_dims3D, input_array_type_codes,input_array , 2, input_array_type_codes, reduction_1D_value);

  }
  else
  {
    CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
                "TestLocalReduce: Invalid reduction operator '%s' with handle '%d'", 
                "sum", handle);
  }

  /* freeing memory */
  free (real_3D_array );
  free (int_3D_array );
  free (real_2D_array );
  free (int_2D_array );
  free (real_1D_array );
  free (int_1D_array );

  return;

}

```


combined_doc_context: ## README (README):
```
Cactus Code Thorn TestLocalReduce
Author(s)    : unknown
Maintainer(s): Cactus team
Licence      : LGPL
--------------------------------------------------------------------------

1. Purpose

not documented

```

## Documentation (.tex files):
Files: documentation.tex

```tex
=== documentation.tex ===
% *======================================================================*
%  Cactus Thorn template for ThornGuide documentation
%  Author: Ian Kelley
%  Date: Sun Jun 02, 2002
%  $Header$                                                             
%
%  Thorn documentation in the latex file doc/documentation.tex 
%  will be included in ThornGuides built with the Cactus make system.
%  The scripts employed by the make system automatically include 
%  pages about variables, parameters and scheduling parsed from the 
%  relevent thorn CCL files.
%  
%  This template contains guidelines which help to assure that your     
%  documentation will be correctly added to ThornGuides. More 
%  information is available in the Cactus UsersGuide.
%                                                    
%  Guidelines:
%   - Do not change anything before the line
%       % BEGIN CACTUS THORNGUIDE",
%     except for filling in the title, author, date etc. fields.
%   - You can define your own macros are OK, but they must appear after
%     the BEGIN CACTUS THORNGUIDE line, and do not redefine standard 
%     latex commands.
%   - To avoid name clashes with other thorns, 'labels', 'citations', 
%     'references', and 'image' names should conform to the following 
%     convention:          
%       ARRANGEMENT_THORN_LABEL
%     For example, an image wave.eps in the arrangement CactusWave and 
%     thorn WaveToyC should be renamed to CactusWave_WaveToyC_wave.eps
%   - Graphics should only be included using the graphix package. 
%     More specifically, with the "includegraphics" command. Do
%     not specify any graphic file extensions in your .tex file. This 
%     will allow us (later) to create a PDF version of the ThornGuide
%     via pdflatex. |
%   - References should be included with the latex "bibitem" command.  
%   - For the benefit of our Perl scripts, and for future extensions, 
%     please use simple latex.     
%
% *======================================================================* 
% 
% Example of including a graphic image:
%    \begin{figure}[ht]
% 	\begin{center}
%    	   \includegraphics[width=6cm]{MyArrangement_MyThorn_MyFigure}
% 	\end{center}
% 	\caption{Illustration of this and that}
% 	\label{MyArrangement_MyThorn_MyLabel}
%    \end{figure}
%
% Example of using a label:
%   \label{MyArrangement_MyThorn_MyLabel}
%
% Example of a citation:
%    \cite{MyArrangement_MyThorn_Author99}
%
% Example of including a reference
%   \bibitem{MyArrangement_MyThorn_Author99}
%   {J. Author, {\em The Title of the Book, Journal, or periodical}, 1 (1999), 
%   1--16. {\tt http://www.nowhere.com/}}
%
% *======================================================================* 

% If you are using CVS use this line to give version information
% $Header$

\documentclass{article}

% Use the Cactus ThornGuide style file
% (Automatically used from Cactus distribution, if you have a 
%  thorn without the Cactus Flesh download this from the Cactus
%  homepage at www.cactuscode.org)
\usepackage{../../../../doc/latex/cactus}

\begin{document}

% The author of the documentation
\author{} 

% The title of the document (not necessarily the name of the Thorn)
\title{}

% the date your document was last changed, if your document is in CVS, 
% please us:
%    \date{$ $Date$ $}
\date{}

\maketitle

% Do not delete next line
% START CACTUS THORNGUIDE

% Add all definitions used in this documentation here 
%   \def\mydef etc

% Add an abstract for this thorn's documentation
\begin{abstract}

\end{abstract}

% The following sections are suggestive only.
% Remove them or add your own.

\section{Introduction}

\section{Physical System}

\section{Numerical Implementation}

\section{Using This Thorn}

\subsection{Obtaining This Thorn}

\subsection{Basic Usage}

\subsection{Special Behaviour}

\subsection{Interaction With Other Thorns}

\subsection{Support and Feedback}

\section{History}

\subsection{Thorn Source Code}

\subsection{Thorn Documentation}

\subsection{Acknowledgements}


\begin{thebibliography}{9}

\end{thebibliography}

% Do not delete next line
% END CACTUS THORNGUIDE

\end{document}

```



Reference solution:
src_code: # Main make.code.defn file for thorn TestReduce
# $Header$

# Source files in this directory
SRCS = Reduce_Maximum.c Reduce_Sum.c Reduce_Avg.c

# Subdirectories containing source files
SUBDIRS =