Task: Implement TestGlobalReduce.c for CactusTest/TestGlobalReduce thorn

thorn_name: CactusTest/TestGlobalReduce
src_filename: TestGlobalReduce.c
interface: # Interface definition for thorn TestGlobalReduce
# $Header$

implements:testglobalreduce
inherits: grid

public:
cctk_real real_3d dim=3 type=ARRAY size=array_nx,array_ny,array_nz
{
  grid_real
} "grid array to be reduced of type real"

cctk_int int_3d dim=3 type=ARRAY size=array_nx,array_ny,array_nz
{
  grid_int
} "grid array to be reduced of type int"

cctk_real real_gf type=GF Timelevels=1
{
  real_test_gf, real_sum_gf
} "a real gf to test for gaussian initial data"

cctk_real weight_group type=ARRAY size=array_nx,array_ny,array_nz
{
  weight
} "a weight variable to be used in reduction"

cctk_int int_vals type=scalar
{
  int_max_3D, int_sum_3D, int_avg_3D, int_min_3D
} "results from weighted int reduction"

cctk_real real_vals type=scalar
{
  real_max_3D, real_sum_3D, real_avg_3D, real_min_3D
} "results from real reduction"

cctk_int weighted_int_vals type=scalar
{
  weighted_int_max, weighted_int_sum, weighted_int_avg, weighted_int_min
} "results from int reduction"

cctk_real weighted_real_vals type=scalar
{
  weighted_real_max, weighted_real_sum, weighted_real_avg, weighted_real_min
} "results from weighted real reduction"

cctk_real gf_vals type=scalar
{
  gf_max, gf_sum, gf_norm1, gf_norm2, gf_norm3, gf_norm4
} "results from gf reduction"

cctk_real scalar_reduction type=scalar
{
  num_to_reduce, sum_value, max_value  
} "scalar reduction variables"

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

STORAGE: real_3d int_3d real_vals int_vals weighted_real_vals weighted_int_vals real_gf[1] gf_vals[1] scalar_reduction weight_group

schedule TestGlobalReduce_Initial at CCTK_INITIAL
{
  LANG:C
} "Initialize the input arrays to values"

schedule TestGlobalReduceC_Avg at CCTK_POSTINITIAL
{
  LANG: C
} "Test out GF reduction"

schedule TestGlobalReduceC_Maximum at CCTK_POSTINITIAL after TestGlobalReduceC_Avg
{
  LANG: C
} "Test out maximum reduction"

schedule TestGlobalReduceC_Minimum at CCTK_POSTINITIAL after TestGlobalReduceC_Maximum
{
  LANG: C
} "Test out minimum reduction"
  
schedule TestGlobalReduceC_Sum at CCTK_POSTINITIAL after TestGlobalReduceC_Minimum
{
  LANG: C
} "Test out sum reduction"
  
schedule TestGlobalReduceC_GF at CCTK_POSTINITIAL after TestGlobalReduceC_Sum
{
  LANG: C
} "Test out GF reduction"

schedule TestGlobalReduceC_Norms at CCTK_POSTINITIAL after TestGlobalReduceC_GF
{
  LANG: C
} "Test out GF reduction"


schedule TestGlobalReduceC_Scalar at CCTK_POSTINITIAL after TestGlobalReduceC_Norms
{
  LANG: C
} "Test out GF reduction"

schedule TestGlobalReduceC_Weighted_Avg at CCTK_POSTINITIAL after TestGlobalReduceC_Scalar
{
  LANG: C
} "Test weighted global average reduction"

schedule TestGlobalReduceC_Weighted_Maximum at CCTK_POSTINITIAL after TestGlobalReduceC_Weighted_Avg
{
  LANG: C
} "Test weighted global maximum reduction"

schedule TestGlobalReduceC_Weighted_Minimum at CCTK_POSTINITIAL after TestGlobalReduceC_Weighted_Maximum
{
  LANG: C
} "Test weighted global minimum reduction"
  
schedule TestGlobalReduceC_Weighted_Sum at CCTK_POSTINITIAL after TestGlobalReduceC_Weighted_Minimum
{
  LANG: C
} "Test weighted global Sum reduction"


param: # Parameter definitions for thorn TestGlobalReduce
# $Header$
INT array_nx "Size of arrays in x direction"
{
  0:* :: ""
} 5

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

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

INT dest_proc "processor to which reduction is to be made"
{
  *:* :: "number can be any valid integer"
} 0

INT map_x "number of original points to map to in x-direction"
{
  0:* :: "has to be positive"
} 10

INT map_y "number of original points to map to in y-direction"
{
  0:* :: "has to be positive"
} 10

INT map_z "number of original points to map to in z-direction"
{
  0:* :: "has to be positive"
} 10
  
REAL radius "The radius of the gaussian wave"
{
 0:* :: "Positive"
} 0.1

REAL sigma "The sigma for the gaussian wave"
{
 0:* :: "Positive"
} 0.1

REAL amplitude "The amplitude of the waves"
{
  *:* :: "No restriction"
} 1.0

REAL uniform_weight_value "The uniform value of the weight"
{
  *:*  :: "Can be anything"
} 0.5

context: Initial.c:
```
 /*@@
   @file      Initial.c
   @date      Tues Sep  7 16:00:29 2004
   @author    Yaakoub El Khamra
   @desc
              Setup the grid arrays we want to test reduction with
   @enddesc
   @version   $Id$
 @@*/

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

#include <math.h>

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

CCTK_FILEVERSION(CactusTest_TestGlobalReduce_Initial_c)

#define SQR(x) ((x) * (x))

/********************************************************************
 *********************  Scheduled Routine Prototypes  ***************
 ********************************************************************/
void TestGlobalReduce_Initial(CCTK_ARGUMENTS);

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

/*@@
   @routine TestGlobalReduce_Initial
   @author     Yaakoub Y El Khamra
   @date       Tues Sep  7 16:00:29 2004
   @desc
               Sets up the grid arrays and fills them with values
   @enddesc
   @calls      CCTK_GroupubndVI
               CCTK_GrouplbndVI

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

  int sum_index;
  int i,j,k;
  int ierr;
  int lsh[3];
  int min[3]; 

  CCTK_REAL dx,dy,dz;
  CCTK_REAL X,Y,Z;
  CCTK_REAL R;

  /* Set up shorthands */
  dx = CCTK_DELTA_SPACE(0);
  dy = CCTK_DELTA_SPACE(1);
  dz = CCTK_DELTA_SPACE(2);
  
  ierr = CCTK_GrouplshVN(cctkGH, 3, lsh, "TestGlobalReduce::grid_real");
  if (ierr < 0)
    CCTK_WARN(0, "Error reading group lsh");
  ierr = CCTK_GrouplbndVN(cctkGH, 3, min, "TestGlobalReduce::grid_real");
  if (ierr < 0)
    CCTK_WARN(0, "Error reading group lbnd");

  for(k=0; k<lsh[2]; k++)
  {
    for(j=0; j<lsh[1]; j++)
    {
      for(i=0; i<lsh[0]; i++)
      {      
        sum_index = i+ lsh[0]*(j + lsh[1]*k);
        grid_real[sum_index] = ((i+min[0]+1)*(j+min[1]+1)*(k+min[2]+1));
        grid_int [sum_index] = ((i+min[0]+2)*(j+min[1]+2)*(k+min[2]+2));
        weight   [sum_index] = uniform_weight_value;
      }
    }
  }

  for(k=0; k<cctk_lsh[2]; k++)
  {
    for(j=0; j<cctk_lsh[1]; j++)
    {
      for(i=0; i<cctk_lsh[0]; i++)
      {      
        sum_index = CCTK_GFINDEX3D(cctkGH,i,j,k);
        X = x[sum_index];
	Y = y[sum_index];
	Z = z[sum_index];
        R = sqrt( X*X + Y*Y + Z*Z );
        real_test_gf[sum_index] = (amplitude*exp( -SQR( (R - radius) / sigma ) ));
        real_sum_gf[sum_index] = 0.0;
      }
    }
  }

  for(k=0; k<cctk_lsh[2]; k++)
  {
    for(j=0; j<cctk_lsh[1]; j++)
    {
      for(i=0; i<cctk_lsh[0]; i++)
      {      
        sum_index = CCTK_GFINDEX3D(cctkGH,i,j,k);
        X = x[sum_index];
	Y = y[sum_index];
	Z = z[sum_index];

        if (fabs(Z-1.0)<1e-14)
          continue;
        if (fabs(Y-1.0)<1e-14)
          continue;
        if (fabs(X-1.0)<1e-14)
          continue;
        
        real_sum_gf[sum_index] = (dx*dy*dz*(X+Y+Z+dx/2+dy/2+dz/2));
      }
    }
  }
  
  /* set the value of the scalar to reduce to an arbitrary value */
  num_to_reduce[0]=3.14159;
  
  return;
}

```

make.code.defn:
```
# Main make.code.defn file for thorn TestGlobalReduce
# $Header$

# Source files in this directory
SRCS = Initial.c TestGlobalReduce.c

# Subdirectories containing source files
SUBDIRS = 

```


combined_doc_context: ## README (README):
```
Cactus Code Thorn TestGlobalReduce
Author(s)    : Yaakoub Y El Khamra
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
%  relevant 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
%       % START CACTUS THORNGUIDE",
%     except for filling in the title, author, date, etc. fields.
%        - Each of these fields should only be on ONE line.
%        - Author names should be separated with a \\ or a comma.
%   - You can define your own macros, but they must appear after
%     the START CACTUS THORNGUIDE line, and must 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 graphicx package.
%     More specifically, with the "\includegraphics" command.  Do
%     not specify any graphic file extensions in your .tex file. This
%     will allow us to create a PDF version of the ThornGuide
%     via pdflatex.
%   - References should be included with the latex "\bibitem" command.
%   - Use \begin{abstract}...\end{abstract} instead of \abstract{...}
%   - Do not use \appendix, instead include any appendices you need as
%     standard sections.
%   - 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{Yaakoub Y El Khamra \textless yye00@cct.lsu.edu\textgreater}

% 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 use:
%    \date{$ $Date$ $}
\date{August 27 2004}

\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{Examples}

\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:  /*@@
   @file      TestGlobalReduce.c
   @date      Tues Sep  7 16:00:29 2004
   @author    Yaakoub El Khamra
   @desc
              Test the global reduction implementation
   @enddesc
   @version   $Header$
 @@*/

#include <stdio.h>

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

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

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

CCTK_FILEVERSION(CactusTest_TestGlobalReduce_TestGlobalReduce_c);


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


void TestGlobalReduceC_Maximum(CCTK_ARGUMENTS);

void TestGlobalReduceC_Minimum(CCTK_ARGUMENTS);

void TestGlobalReduceC_Sum(CCTK_ARGUMENTS);

void TestGlobalReduceC_Avg(CCTK_ARGUMENTS);

void TestGlobalReduceC_GF(CCTK_ARGUMENTS);

void TestGlobalReduceC_Weighted_Maximum(CCTK_ARGUMENTS);

void TestGlobalReduceC_Weighted_Minimum(CCTK_ARGUMENTS);

void TestGlobalReduceC_Weighted_Sum(CCTK_ARGUMENTS);

void TestGlobalReduceC_Weighted_Avg(CCTK_ARGUMENTS);


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

/*@@
   @routine TestGlobalReduceC_Maximum
   @author     Yaakoub Y El Khamra
   @date       Tues Sep  7 16:00:29 2004
   @desc
               Tests global maximum reduction
   @enddesc
   @calls      CCTK_LocalArrayReductionHandle
               CCTK_ReduceGridArrays
               CCTK_VarIndex

   @returntype int
   @returndesc
                  return error code from CCTK_ReduceGridArrays
                  else return 0
   @endreturndesc
 @@*/
void TestGlobalReduceC_Maximum(CCTK_ARGUMENTS)
{
  DECLARE_CCTK_ARGUMENTS;
  DECLARE_CCTK_PARAMETERS;

  int handle, ierr;

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

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

  /* output data */
  void*  reduction_3D_value[2];
  
  /* print what we are testing for */
  CCTK_Info("TestGlobalReduce", "Testing for maximum value");

  /* make sure all pointers point to valid memory locations */  
  reduction_3D_value[0] = real_max_3D;
  reduction_3D_value[1] = int_max_3D; 

  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] = CCTK_VarIndex("TestGlobalReduce::grid_real");
  input_array[1] = CCTK_VarIndex("TestGlobalReduce::grid_int");

if (handle >= 0)
  {
    ierr =  CCTK_ReduceGridArrays (cctkGH, dest_proc, handle, -1, 2, input_array , 2, input_array_type_codes, reduction_3D_value);
  }
  else
  {
    CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
                "TestGlobalReduce: Invalid reduction operator '%s' with handle '%d'", 
                "maximum", handle);
  }
}

/*@@
   @routine TestGlobalReduceC_Minimum
   @author     Yaakoub Y El Khamra
   @date       Tues Sep  7 16:00:29 2004
   @desc
               Tests global minimum reduction
   @enddesc
   @calls      CCTK_LocalArrayReductionHandle
               CCTK_ReduceGridArrays
               CCTK_VarIndex

   @returntype int
   @returndesc
                  return error code from CCTK_ReduceGridArrays
                  else return 0
   @endreturndesc
 @@*/
void TestGlobalReduceC_Minimum(CCTK_ARGUMENTS)
{
  DECLARE_CCTK_ARGUMENTS;
  DECLARE_CCTK_PARAMETERS;

  int handle, ierr;

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

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

  /* output data */
  void*  reduction_3D_value[2];
  
  /* print what we are testing for */
  CCTK_Info("TestGlobalReduce", "Testing for minimum value");
  
  /* make sure all pointers point to valid memory locations */  
  reduction_3D_value[0] = real_min_3D;
  reduction_3D_value[1] = int_min_3D; 

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

  /* 3D Array */
  handle = CCTK_LocalArrayReductionHandle("minimum");
  input_array[0] = CCTK_VarIndex("TestGlobalReduce::grid_real");
  input_array[1] = CCTK_VarIndex("TestGlobalReduce::grid_int");

if (handle >= 0)
  {
    ierr =  CCTK_ReduceGridArrays (cctkGH, dest_proc, handle, -1, 2, input_array , 2, input_array_type_codes, reduction_3D_value);
  }
  else
  {
    CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
                "TestGlobalReduce: Invalid reduction operator '%s' with handle '%d'", 
                "minimum", handle);
  }
}

/*@@
   @routine TestGlobalReduceC_Sum
   @author     Yaakoub Y El Khamra
   @date       Tues Sep  7 16:00:29 2004
   @desc
               Tests global sum reduction
   @enddesc
   @calls      CCTK_LocalArrayReductionHandle
               CCTK_ReduceGridArrays
               CCTK_VarIndex

   @returntype int
   @returndesc
                  return error code from CCTK_ReduceGridArrays
                  else return 0
   @endreturndesc
 @@*/
void TestGlobalReduceC_Sum(CCTK_ARGUMENTS)
{
  DECLARE_CCTK_ARGUMENTS;
  DECLARE_CCTK_PARAMETERS;

  int handle, ierr;

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

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

  /* output data */
  void*  reduction_3D_value[2];
  
  /* print what we are testing for */
  CCTK_Info("TestGlobalReduce", "Testing for sum");
  
  /* make sure all pointers point to valid memory locations */  
  reduction_3D_value[0] = real_sum_3D;
  reduction_3D_value[1] = int_sum_3D; 

  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] = CCTK_VarIndex("TestGlobalReduce::grid_real");
  input_array[1] = CCTK_VarIndex("TestGlobalReduce::grid_int");

  if (handle >= 0)
  {
    ierr =  CCTK_ReduceGridArrays (cctkGH, dest_proc, handle, -1, 2, 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);
  }
}

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

   @returntype int
   @returndesc
                  return error code from CCTK_ReduceGridArrays
                  else return 0
   @endreturndesc
 @@*/
void TestGlobalReduceC_Avg(CCTK_ARGUMENTS)
{
  DECLARE_CCTK_ARGUMENTS;
  DECLARE_CCTK_PARAMETERS;

  int handle, ierr;

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

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

  /* output data */
  void*  reduction_3D_value[2];
  
  /* print what we are testing for */
  CCTK_Info("TestGlobalReduce", "Testing for Average ");

  /* make sure all pointers point to valid memory locations */  
  reduction_3D_value[0] = real_avg_3D;
  reduction_3D_value[1] = int_avg_3D; 

  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] = CCTK_VarIndex("TestGlobalReduce::grid_real");
  input_array[1] = CCTK_VarIndex("TestGlobalReduce::grid_int");

  if (handle >= 0)
  {
    ierr =  CCTK_ReduceGridArrays (cctkGH, dest_proc, handle, -1, 2, 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);
  }
}


/*@@
   @routine TestGlobalReduceC_GF
   @author     Yaakoub Y El Khamra
   @date       Tues Sep  7 16:00:29 2004
   @desc
               Tests grid function reduction (sum and max)
   @enddesc
   @calls      CCTK_LocalArrayReductionHandle
               CCTK_ReduceGridArrays
               CCTK_VarIndex

   @returntype int
   @returndesc
                  return error code from CCTK_ReduceGridArrays
                  else return 0
   @endreturndesc
 @@*/
void TestGlobalReduceC_GF(CCTK_ARGUMENTS)
{
  DECLARE_CCTK_ARGUMENTS;
  DECLARE_CCTK_PARAMETERS;

  int handle, ierr;

  /* input array void * pointers */
  CCTK_INT input_array[1];

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

  /* output data */
  void*  reduction_3D_value[1];

  input_array_type_codes[0]  = CCTK_VARIABLE_REAL;
  input_array[0] = CCTK_VarIndex("TestGlobalReduce::real_test_gf");

  CCTK_Info("TestGlobalReduce", "Testing for maximum value of GF");
  /* make sure all pointers point to valid memory locations */  
  reduction_3D_value[0] = gf_max;

  /* Max reduction */
  handle = CCTK_LocalArrayReductionHandle("maximum");

  if (handle >= 0)
  {
    ierr =  CCTK_ReduceGridArrays (cctkGH, dest_proc, handle, -1, 1, input_array , 1, input_array_type_codes, reduction_3D_value);
  }
  else
  {
    CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
                "TestLocalReduce: Invalid reduction operator '%s' with handle '%d'", 
                "max", handle);
  }

  CCTK_Info("TestGlobalReduce", "Testing for sum value of GF");
  /* make sure all pointers point to valid memory locations */  
  reduction_3D_value[0] = gf_sum;

  /* Sum reduction */

  input_array[0] = CCTK_VarIndex("TestGlobalReduce::real_sum_gf");
  handle = CCTK_LocalArrayReductionHandle("sum");

  if (handle >= 0)
  {
    ierr =  CCTK_ReduceGridArrays (cctkGH, dest_proc, handle, -1, 1, input_array , 1, 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);
  }
}

/*@@
   @routine TestGlobalReduceC_Norms
   @author     Yaakoub Y El Khamra
   @date       
   @desc
               Tests norm 1-4 reductions
   @enddesc
   @calls      CCTK_LocalArrayReductionHandle
               CCTK_ReduceGridArrays
               CCTK_VarIndex

   @returntype int
   @returndesc
                  return error code from CCTK_ReduceGridArrays
                  else return 0
   @endreturndesc
 @@*/
void TestGlobalReduceC_Norms(CCTK_ARGUMENTS)
{
  DECLARE_CCTK_ARGUMENTS;
  DECLARE_CCTK_PARAMETERS;

  int handle, ierr;

  /* input array void * pointers */
  CCTK_INT input_array[1];

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

  /* output data */
  void*  reduction_3D_value[1];

  input_array_type_codes[0]  = CCTK_VARIABLE_REAL;
  input_array[0] = CCTK_VarIndex("TestGlobalReduce::grid_real");
  
  CCTK_Info("TestGlobalReduce", "Testing norm1, norm2, norm3, norm4 and norminf value of GF");

  /* Nrom1 reduction */
  handle = CCTK_LocalArrayReductionHandle("norm1");
  reduction_3D_value[0] = gf_norm1;
  
  if (handle >= 0)
  {
    ierr =  CCTK_ReduceGridArrays (cctkGH, dest_proc, handle, -1, 1, input_array , 1, input_array_type_codes, reduction_3D_value);
  }
  else
  {
    CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
                "TestLocalReduce: Invalid reduction operator '%s' with handle '%d'", 
                "norm1", handle);
  }

  /* Nrom2 reduction */
  handle = CCTK_LocalArrayReductionHandle("norm2");
  reduction_3D_value[0] = gf_norm2;
  
  if (handle >= 0)
  {
    ierr =  CCTK_ReduceGridArrays (cctkGH, dest_proc, handle, -1, 1, input_array , 1, input_array_type_codes, reduction_3D_value);
  }
  else
  {
    CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
                "TestLocalReduce: Invalid reduction operator '%s' with handle '%d'", 
                "norm2", handle);
  }
  
  /* Nrom3 reduction */
  handle = CCTK_LocalArrayReductionHandle("norm3");
  reduction_3D_value[0] = gf_norm3;
  
  if (handle >= 0)
  {
    ierr =  CCTK_ReduceGridArrays (cctkGH, dest_proc, handle, -1, 1, input_array , 1, input_array_type_codes, reduction_3D_value);
  }
  else
  {
    CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
                "TestLocalReduce: Invalid reduction operator '%s' with handle '%d'", 
                "norm3", handle);
  }

  /* Nrom4 reduction */
  handle = CCTK_LocalArrayReductionHandle("norm4");
  reduction_3D_value[0] = gf_norm4;
  
  if (handle >= 0)
  {
    ierr =  CCTK_ReduceGridArrays (cctkGH, dest_proc, handle, -1, 1, input_array , 1, input_array_type_codes, reduction_3D_value);
  }
  else
  {
    CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
                "TestLocalReduce: Invalid reduction operator '%s' with handle '%d'", 
                "norm4", handle);
  }
}


/*@@
   @routine TestGlobalReduceC_Scalar
   @author     Yaakoub Y El Khamra
   @date       
   @desc
               Tests scalar reduction
   @enddesc
   @calls      CCTK_LocalArrayReductionHandle
               CCTK_ReduceGridArrays
               CCTK_VarIndex

   @returntype int
   @returndesc
                  return error code from CCTK_ReduceGridArrays
                  else return 0
   @endreturndesc
 @@*/
void TestGlobalReduceC_Scalar(CCTK_ARGUMENTS)
{
  DECLARE_CCTK_ARGUMENTS;
  DECLARE_CCTK_PARAMETERS;

  int handle, ierr;
  int nprocs = 1;
  
  /* input array void * pointers */
  CCTK_INT input_array[1];

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

  /* output data */
  void*  value[1];

  input_array_type_codes[0]  = CCTK_VARIABLE_REAL;
  input_array[0] = CCTK_VarIndex("TestGlobalReduce::num_to_reduce");

  CCTK_Info("TestGlobalReduce", "Testing for maximum scalar reduction");
  /* make sure all pointers point to valid memory locations */  
  value[0] = max_value;

  /* Max reduction */
  handle = CCTK_LocalArrayReductionHandle("maximum");

  if (handle >= 0)
  {
    ierr =  CCTK_ReduceGridArrays (cctkGH, dest_proc, handle, -1, 1, input_array , 1, input_array_type_codes, value);
  }
  else
  {
    CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
                "TestLocalReduce: Invalid reduction operator '%s' with handle '%d'", 
                "max", handle);
  }
  
  CCTK_Info("TestGlobalReduce", "Testing for sum scalar reduction");
  /* make sure all pointers point to valid memory locations */  
  value[0] = sum_value;
  nprocs = CCTK_nProcs(cctkGH);
  
  /* Max reduction */
  handle = CCTK_LocalArrayReductionHandle("sum");

  if (handle >= 0)
  {
    ierr =  CCTK_ReduceGridArrays (cctkGH, dest_proc, handle, -1, 1, input_array , 1, input_array_type_codes, value);
  }
  else
  {
    CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
                "TestLocalReduce: Invalid reduction operator '%s' with handle '%d'", 
                "sum", handle);
  }
  
  *sum_value = *sum_value / nprocs;
}

/*@@
   @routine TestGlobalReduceC_Weighted_Maximum
   @author     Yaakoub Y El Khamra
   @date       Tues Sep  7 16:00:29 2004
   @desc
               Tests global maximum reduction
   @enddesc
   @calls      CCTK_LocalArrayReductionHandle
               CCTK_ReduceGridArrays
               CCTK_VarIndex

   @returntype int
   @returndesc
                  return error code from CCTK_ReduceGridArrays
                  else return 0
   @endreturndesc
 @@*/
void TestGlobalReduceC_Weighted_Maximum(CCTK_ARGUMENTS)
{
  DECLARE_CCTK_ARGUMENTS;
  DECLARE_CCTK_PARAMETERS;

  int handle, ierr, weight_index, par_handle;

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

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

  /* output data */
  void*  reduction_3D_value[2];
  
  /* print what we are testing for */
  CCTK_Info("TestGlobalReduce", "Testing for maximum value");

  /* Create parameter table and store weight */
  par_handle = Util_TableCreate (UTIL_TABLE_FLAGS_DEFAULT);
  weight_index = CCTK_VarIndex("TestGlobalReduce::weight");
  ierr = Util_TableSetInt(par_handle, 1, "weight_on");
  ierr = Util_TableSetInt(par_handle, weight_index, "weight_variable_index");

  /* make sure all pointers point to valid memory locations */  
  reduction_3D_value[0] = weighted_real_max;
  reduction_3D_value[1] = weighted_int_max; 

  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] = CCTK_VarIndex("TestGlobalReduce::grid_real");
  input_array[1] = CCTK_VarIndex("TestGlobalReduce::grid_int");

if (handle >= 0)
  {
    ierr =  CCTK_ReduceGridArrays (cctkGH, dest_proc, handle, weight_index, 2, input_array , 2, input_array_type_codes, reduction_3D_value);
  }
  else
  {
    CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
                "TestGlobalReduce: Invalid reduction operator '%s' with handle '%d'", 
                "maximum", handle);
  }
}

/*@@
   @routine TestGlobalReduceC_Weighted_Minimum
   @author     Yaakoub Y El Khamra
   @date       Tues Sep  7 16:00:29 2004
   @desc
               Tests global minimum reduction
   @enddesc
   @calls      CCTK_LocalArrayReductionHandle
               CCTK_ReduceGridArrays
               CCTK_VarIndex

   @returntype int
   @returndesc
                  return error code from CCTK_ReduceGridArrays
                  else return 0
   @endreturndesc
 @@*/
void TestGlobalReduceC_Weighted_Minimum(CCTK_ARGUMENTS)
{
  DECLARE_CCTK_ARGUMENTS;
  DECLARE_CCTK_PARAMETERS;

  int handle, ierr, weight_index, par_handle;

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

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

  /* output data */
  void*  reduction_3D_value[2];
  
  /* print what we are testing for */
  CCTK_Info("TestGlobalReduce", "Testing for minimum value");

  /* Create parameter table and store weight */
  par_handle = Util_TableCreate (UTIL_TABLE_FLAGS_DEFAULT);
  weight_index = CCTK_VarIndex("TestGlobalReduce::weight");
  ierr = Util_TableSetInt(par_handle, 1, "weight_on");
  ierr = Util_TableSetInt(par_handle, weight_index, "weight_variable_index");

  /* make sure all pointers point to valid memory locations */  
  reduction_3D_value[0] = weighted_real_min;
  reduction_3D_value[1] = weighted_int_min; 

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

  /* 3D Array */
  handle = CCTK_LocalArrayReductionHandle("minimum");
  input_array[0] = CCTK_VarIndex("TestGlobalReduce::grid_real");
  input_array[1] = CCTK_VarIndex("TestGlobalReduce::grid_int");

if (handle >= 0)
  {
    ierr =  CCTK_ReduceGridArrays (cctkGH, dest_proc, handle, par_handle, 2, input_array , 2, input_array_type_codes, reduction_3D_value);
  }
  else
  {
    CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
                "TestGlobalReduce: Invalid reduction operator '%s' with handle '%d'", 
                "minimum", handle);
  }
}

/*@@
   @routine TestGlobalReduceC_Weighted_Sum
   @author     Yaakoub Y El Khamra
   @date       Tues Sep  7 16:00:29 2004
   @desc
               Tests global sum reduction
   @enddesc
   @calls      CCTK_LocalArrayReductionHandle
               CCTK_ReduceGridArrays
               CCTK_VarIndex

   @returntype int
   @returndesc
                  return error code from CCTK_ReduceGridArrays
                  else return 0
   @endreturndesc
 @@*/
void TestGlobalReduceC_Weighted_Sum(CCTK_ARGUMENTS)
{
  DECLARE_CCTK_ARGUMENTS;
  DECLARE_CCTK_PARAMETERS;

  int handle, ierr, weight_index, par_handle;

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

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

  /* output data */
  void*  reduction_3D_value[2];
  
  /* print what we are testing for */
  CCTK_Info("TestGlobalReduce", "Testing for sum");
 
  /* Create parameter table and store weight */
  par_handle = Util_TableCreate (UTIL_TABLE_FLAGS_DEFAULT);
  weight_index = CCTK_VarIndex("TestGlobalReduce::weight");
  ierr = Util_TableSetInt(par_handle, 1, "weight_on");
  ierr = Util_TableSetInt(par_handle, weight_index, "weight_variable_index");

  /* make sure all pointers point to valid memory locations */  
  reduction_3D_value[0] = weighted_real_sum;
  reduction_3D_value[1] = weighted_int_sum; 

  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] = CCTK_VarIndex("TestGlobalReduce::grid_real");
  input_array[1] = CCTK_VarIndex("TestGlobalReduce::grid_int");

  if (handle >= 0)
  {
    ierr =  CCTK_ReduceGridArrays (cctkGH, dest_proc, handle, par_handle, 2, 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);
  }
}

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

   @returntype int
   @returndesc
                  return error code from CCTK_ReduceGridArrays
                  else return 0
   @endreturndesc
 @@*/
void TestGlobalReduceC_Weighted_Avg(CCTK_ARGUMENTS)
{
  DECLARE_CCTK_ARGUMENTS;
  DECLARE_CCTK_PARAMETERS;

  int handle, ierr, weight_index, par_handle;

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

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

  /* output data */
  void*  reduction_3D_value[2];
  
  /* print what we are testing for */
  CCTK_Info("TestGlobalReduce", "Testing for Average ");

  /* Create parameter table and store weight */
  par_handle = Util_TableCreate (UTIL_TABLE_FLAGS_DEFAULT);
  weight_index = CCTK_VarIndex("TestGlobalReduce::weight");
  ierr = Util_TableSetInt(par_handle, 1, "weight_on");
  ierr = Util_TableSetInt(par_handle, weight_index, "weight_variable_index");

  /* make sure all pointers point to valid memory locations */  
  reduction_3D_value[0] = weighted_real_avg;
  reduction_3D_value[1] = weighted_int_avg;

  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] = CCTK_VarIndex("TestGlobalReduce::grid_real");
  input_array[1] = CCTK_VarIndex("TestGlobalReduce::grid_int");

  if (handle >= 0)
  {
    ierr =  CCTK_ReduceGridArrays (cctkGH, dest_proc, handle, par_handle, 2, 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);
  }
}