Task: Implement WaveMoL.c for CactusExamples/WaveMoL thorn

thorn_name: CactusExamples/WaveMoL
src_filename: WaveMoL.c
interface: # Interface definition for thorn WaveMoL
# $Header$

implements: wavemol

USES INCLUDE: Symmetry.h

CCTK_INT FUNCTION MoLRegisterEvolvedGroup(CCTK_INT IN EvolvedIndex, \
                                          CCTK_INT IN RHSIndex)
CCTK_INT FUNCTION MoLRegisterConstrained(CCTK_INT IN ConstrainedIndex)

REQUIRES FUNCTION MoLRegisterEvolvedGroup
REQUIRES FUNCTION MoLRegisterConstrained

CCTK_INT FUNCTION Boundary_SelectGroupForBC(CCTK_POINTER_TO_CONST IN GH, \
  CCTK_INT IN faces, CCTK_INT IN boundary_width, CCTK_INT IN table_handle, \
  CCTK_STRING IN var_name, CCTK_STRING IN bc_name)
REQUIRES FUNCTION Boundary_SelectGroupForBC

public

cctk_real scalarevolvemol_scalar type = GF Timelevels = 3 tags='tensortypealias="Scalar"'
{
  phi
  phit
} "The scalar field and time derivative"

cctk_real scalarevolvemol_vector type = GF Timelevels = 3 tags='tensortypealias="U"'
{
  phix
  phiy
  phiz
} "The scalar field spatial derivatives"

cctk_real scalarrhsmol_scalar type = GF Timelevels = 1
{
  phirhs
  phitrhs
} "The right hand side for the scalar field"

cctk_real scalarrhsmol_vector type = GF Timelevels = 1
{
  phixrhs
  phiyrhs
  phizrhs
} "The right hand side for the scalar field derivatives"

cctk_real energy type = GF Timelevels = 1 "The energy of the field"


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

STORAGE: scalarevolvemol_scalar[3], scalarevolvemol_vector[3]
STORAGE: scalarrhsmol_scalar, scalarrhsmol_vector
STORAGE: energy

schedule WaveMoL_Startup at STARTUP
{
  LANG: C
} "Register Banner"

schedule WaveMoL_InitSymBound at BASEGRID
{
  LANG: C
  OPTIONS: META
} "Schedule symmetries"

schedule WaveMoL_RegisterVars in MoL_Register
{
  LANG: C
  OPTIONS: META
} "Register variables for MoL"

schedule WaveMoL_CalcRHS in MoL_CalcRHS
{
  LANG: C
} "Register RHS calculation for MoL"

schedule WaveMoL_Energy in MoL_PostStep
{
  LANG: C
} "Calculate the energy"

schedule WaveMoL_Energy at POSTINITIAL
{
  LANG: C
} "Calculate the energy"

schedule WaveMoL_Boundaries in MoL_PostStep
{
  LANG: C
  OPTIONS: LEVEL
  SYNC: scalarevolvemol_scalar
  SYNC: scalarevolvemol_vector
} "Register boundary enforcement in MoL"

schedule GROUP ApplyBCs as WaveMoL_ApplyBCs in MoL_PostStep after WaveMoL_Boundaries
{
} "Apply boundary conditions for WaveMoL"

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

shares: MethodOfLines

USES CCTK_INT MoL_Num_Evolved_Vars
USES CCTK_INT MoL_Num_Constrained_Vars
USES CCTK_INT MoL_Num_SaveAndRestore_Vars

restricted:

CCTK_INT WaveMoL_MaxNumEvolvedVars "The maximum number of evolved variables used by WaveMoL" ACCUMULATOR-BASE=MethodofLines::MoL_Num_Evolved_Vars
{
  5:5		:: "Just 5: phi and the four derivatives"
} 5

CCTK_INT WaveMoL_MaxNumConstrainedVars "The maximum number of constrained variables used by WaveMoL" ACCUMULATOR-BASE=MethodofLines::MoL_Num_Constrained_Vars
{
  1:1		:: "The energy"
} 1

private:

KEYWORD bound "Type of boundary condition to use"
{
  "none"      :: "No boundary condition"
  "flat"      :: "Flat boundary condition"
  "radiation" :: "Radiation boundary condition"
} "none"

configuration: # Configuration definition for thorn BSSN_MoL
# $Header$

REQUIRES CartGrid3D Boundary

context: WaveMoLRegister.c:
```
 /*@@
   @file      WaveMoLRegister.c
   @date      Fri Nov  9 13:47:07 2001
   @author    Ian Hawke
   @desc 
   Routine to register the variables with the MoL thorn.
   @enddesc 
 @@*/

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

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

CCTK_FILEVERSION(CactusExamples_WaveMoL_WaveMoLRegister_c)

/*
#ifndef DEBUG_MOL
#define DEBUG_MOL
#endif
*/

void WaveMoL_RegisterVars(CCTK_ARGUMENTS);

 /*@@
   @routine    WaveMoL_RegisterVars
   @date       Fri Nov  9 13:47:41 2001
   @author     Ian Hawke
   @desc 
   The registration routine.
   @enddesc 
   @calls     
   @calledby   
   @history 
 
   @endhistory 

@@*/

void WaveMoL_RegisterVars(CCTK_ARGUMENTS)
{

  DECLARE_CCTK_ARGUMENTS;
  DECLARE_CCTK_PARAMETERS;

  CCTK_INT ierr = 0, group, rhs, var;

  group = CCTK_GroupIndex("wavemol::scalarevolvemol_scalar");
  rhs = CCTK_GroupIndex("wavemol::scalarrhsmol_scalar");

  if (CCTK_IsFunctionAliased("MoLRegisterEvolvedGroup"))
  {
    ierr += MoLRegisterEvolvedGroup(group, rhs);
  }
  else
  {
    CCTK_WARN(0, "MoL function not aliased");
    ierr++;
  }

  group = CCTK_GroupIndex("wavemol::scalarevolvemol_vector");
  rhs = CCTK_GroupIndex("wavemol::scalarrhsmol_vector");

  if (CCTK_IsFunctionAliased("MoLRegisterEvolvedGroup"))
  {
    ierr += MoLRegisterEvolvedGroup(group, rhs);
  }
  else
  {
    CCTK_WARN(0, "MoL function MoLRegisterEvolvedGroup not aliased");
    ierr++;
  }

  var = CCTK_VarIndex("wavemol::energy");

  if (CCTK_IsFunctionAliased("MoLRegisterConstrained"))
  {
    ierr += MoLRegisterConstrained(var);
  }
  else
  {
    CCTK_WARN(0, "MoL function MoLRegisterConstrained not aliased");
    ierr++;
  }      
  
  if (ierr) CCTK_WARN(0,"Problems registering with MoL");

#ifdef DEBUG_MOL
  printf("If we've got this far, then we've done with wavetoy registration.\n");
#endif  

}

```

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

# Source files in this directory
SRCS = WaveMoL.c InitSymBound.c Startup.c WaveMoLRegister.c

# Subdirectories containing source files
SUBDIRS = 


```

InitSymBound.c:
```
 /*@@
   @file      InitSymBound.c
   @date      Fri Nov  9 13:29:53 2001
   @author    Ian Hawke
   @desc 
   Sets the symmetries for Wave Toy - again copies the standard.
   @enddesc 
 @@*/

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

#include "Symmetry.h"

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

CCTK_FILEVERSION(CactusExamples_WaveMoL_InitSymBound_c)

void WaveMoL_InitSymBound(CCTK_ARGUMENTS);
 /*@@
   @routine    WaveMoL_InitSymBound
   @date       Fri Nov  9 13:31:28 2001
   @author     Ian Hawke
   @desc 
   Another straight copy of a wave toy routine, however extended 
   for all the new GFs.
   @enddesc 
   @calls     
   @calledby   
   @history 
 
   @endhistory 

@@*/

void WaveMoL_InitSymBound(CCTK_ARGUMENTS)
{
  DECLARE_CCTK_ARGUMENTS;
      
  int sym[3];

  sym[0] = 1;
  sym[1] = 1;
  sym[2] = 1;

  SetCartSymVN(cctkGH, sym,"wavemol::phi");
  SetCartSymVN(cctkGH, sym,"wavemol::phit");

  sym[0] = -1;
  sym[1] = 1;
  sym[2] = 1;
  SetCartSymVN(cctkGH, sym,"wavemol::phix");

  sym[0] = 1;
  sym[1] = -1;
  sym[2] = 1;
  SetCartSymVN(cctkGH, sym,"wavemol::phiy");

  sym[0] = 1;
  sym[1] = 1;
  sym[2] = -1;
  SetCartSymVN(cctkGH, sym,"wavemol::phiz");

  return;
}

```

Startup.c:
```
 /*@@
   @file      Startup.c
   @date      Fri Nov  9 13:27:48 2001
   @author    Ian Hawke
   @desc 
   Register banner - a straight copy of WaveToy.
   @enddesc 
 @@*/


#include "cctk.h"

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

CCTK_FILEVERSION(CactusExamples_WaveMoL_Startup_c)

int WaveMoL_Startup(void);

 /*@@
   @routine    WaveMoL_Startup
   @date       Fri Nov  9 13:28:58 2001
   @author     Ian Hawke
   @desc 
   Again a straight copy of WaveToyC
   @enddesc 
   @calls     
   @calledby   
   @history 
 
   @endhistory 

@@*/

int WaveMoL_Startup(void)
{

   const char *banner = "WaveMoL: Evolutions of a Scalar Field";

   CCTK_RegisterBanner(banner);

   return 0;
}

```


combined_doc_context: ## README (README):
```
Cactus Code Thorn WaveMoL
Author(s)    : Ian Hawke
Maintainer(s): Cactus team
Licence      : LGPL
--------------------------------------------------------------------------

1. Purpose

This implements the wave equation in FOSH form for use with the Method
of Lines thorn. Intended as a basic test. 

```

## 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
%       % 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 sparated 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 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. 
%   - 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{Ian Hawke} 

% The title of the document (not necessarily the name of the Thorn)
\title{The scalar wave equation in Method of Lines form}

% the date your document was last changed, if your document is in CVS, 
% please use:
\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}
  WaveMoL is an example implementation of a thorn that uses the method
  of lines thorn MoL. The wave equation in first order form is
  implemented. 
\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}

\section{Purpose}
\label{sec:purpose}

WaveToy is the simple test thorn that comes with Cactus as
standard. This is written so that it solves the wave equation
\begin{equation}
  \label{eq:wave1}
  \partial_t^2 \phi = \partial_{x^i}^2 \phi^i
\end{equation}
directly using the leapfrog scheme. This form of the equations isn't
suitable for use with the method of lines.

The purpose of this thorn is to rewrite the equations in first order
form
\begin{eqnarray}
  \label{eq:wave2}
  \partial_t \Phi & = & \partial_{x^i} \Pi^i, \\
  \partial_t \Pi^j & = & \partial_{x^j} \Phi, \\
  \partial_t \phi & = & \Phi, \\
  \partial_{x^j} \phi & = & \Pi^j.
\end{eqnarray}
The first three equations (which expand to five separate PDEs) will be
evolved. The final equation is used to set the initial data and can be
thought of as a constraint.

This will be implemented using simple second order differencing in
space. Time evolution is performed by the method of lines thorn MoL.

\section{How it works}
\label{sec:details}

The equations are evolved entirely using the method of lines thorn. So
all we have to provide (for the evolution) is a method of calculating
the right hand side of equation~(\ref{eq:wave2}) and boundary
conditions. The boundary conditions are standard from wavetoy
itself. The right hand side is calculated using second order centred
finite differences.

To be compatible with the method of lines thorn we must let it know
that the GFs $(\phi, \Pi, \Phi^j)$ exist and where they are stored.
They should all have at least two time levels (although the addition
of extra time levels may not cause problems it's just wasting space).
The GFs corresponding to the right hand sides must also be registered
with the MoL thorn. These should only have one time level. MoL is
informed of the existence of these grid functions through the
accumulator parameters and the aliased functions.

% Do not delete next line
% END CACTUS THORNGUIDE

\end{document}

```



Reference solution:
src_code:  /*@@
   @file      WaveMoL.c
   @date      Fri Nov  9 13:33:25 2001
   @author    Ian Hawke
   @desc 
   The equivalent of WaveToy.c
   @enddesc 
 @@*/

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

/*
#ifndef DEBUG_MOL
#define DEBUG_MOL
#endif
*/

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

CCTK_FILEVERSION(CactusExamples_WaveMoL_WaveMoL_c)

void WaveMoL_Boundaries(CCTK_ARGUMENTS);
void WaveMoL_CalcRHS(CCTK_ARGUMENTS);
void WaveMoL_Energy(CCTK_ARGUMENTS);

 /*@@
   @routine    WaveMoL_Boundaries
   @date       Fri Nov  9 13:34:47 2001
   @author     Ian Hawke
   @desc 
   A slight alteration of the standard routine. Note that I 
   haven't set up the error checking correctly as yet.
   @enddesc 
   @calls     
   @calledby   
   @history 
 
   @endhistory 

@@*/

void WaveMoL_Boundaries(CCTK_ARGUMENTS)
{
  DECLARE_CCTK_ARGUMENTS;
  DECLARE_CCTK_PARAMETERS;

  int ierr=-1;

#ifdef DEBUG_MOL
  printf("We've reached the Boundary enforcement; step must be done!\n");
#endif

  /* Uses all default arguments, so invalid table handle -1 can be passed */
  ierr = Boundary_SelectGroupForBC
    (cctkGH, CCTK_ALL_FACES, 1, -1, "wavemol::scalarevolvemol_scalar", bound);

  if (ierr < 0) 
  {
    CCTK_WARN(0,"Boundary conditions not applied - giving up!");
  }

  ierr = Boundary_SelectGroupForBC
    (cctkGH, CCTK_ALL_FACES, 1, -1, "wavemol::scalarevolvemol_vector", bound);

  if (ierr < 0) 
  {
    CCTK_WARN(0,"Boundary conditions not applied - giving up!");
  }

  return;
}

 /*@@
   @routine    WaveMoL_CalcRHS
   @date       Fri Nov  9 13:37:27 2001
   @author     Ian Hawke
   @desc 
   The routine that calculates the RHS of the PDE for the MoL step.
   @enddesc 
   @calls     
   @calledby   
   @history 
 
   @endhistory 

@@*/

void  WaveMoL_CalcRHS(CCTK_ARGUMENTS)
{

  DECLARE_CCTK_ARGUMENTS;
      
  int i,j,k;
  int index;
  int istart, jstart, kstart, iend, jend, kend;
  CCTK_REAL dx,dy,dz;
  CCTK_REAL hdxi, hdyi, hdzi;

  /* Set up shorthands */
  dx = CCTK_DELTA_SPACE(0);
  dy = CCTK_DELTA_SPACE(1);
  dz = CCTK_DELTA_SPACE(2);

  hdxi = 0.5 / dx;
  hdyi = 0.5 / dy;
  hdzi = 0.5 / dz;
  
  istart = 1;
  jstart = 1;
  kstart = 1;
  
  iend = cctk_lsh[0]-1;
  jend = cctk_lsh[1]-1;
  kend = cctk_lsh[2]-1;

  /* Calculate the right hand sides. */

#ifdef DEBUG_MOL
  printf("About to loop.\n");
#endif

  for (k=0; k<cctk_lsh[2]; k++)
  {
    for (j=0; j<cctk_lsh[1]; j++)
    {
      for (i=0; i<cctk_lsh[0]; i++)
      {
        index = CCTK_GFINDEX3D(cctkGH,i,j,k);
        phirhs[index] = phit[index];
        phitrhs[index] = 0;
        phixrhs[index] = 0;
        phiyrhs[index] = 0;
        phizrhs[index] = 0;
      }
    }
  }  

  for (k=kstart; k<kend; k++)
  {
    for (j=jstart; j<jend; j++)
    {
      for (i=istart; i<iend; i++)
      {
        index = CCTK_GFINDEX3D(cctkGH,i,j,k);
        
        phitrhs[index] = 
            (phix[CCTK_GFINDEX3D(cctkGH, i+1, j, k)] -
             phix[CCTK_GFINDEX3D(cctkGH, i-1, j, k)]) *hdxi
          + (phiy[CCTK_GFINDEX3D(cctkGH, i, j+1, k)] -
             phiy[CCTK_GFINDEX3D(cctkGH, i, j-1, k)]) *hdyi
          + (phiz[CCTK_GFINDEX3D(cctkGH, i, j, k+1)] -
             phiz[CCTK_GFINDEX3D(cctkGH, i, j, k-1)]) *hdzi;
        phixrhs[index] = (phit[CCTK_GFINDEX3D(cctkGH, i+1, j, k)] -
                          phit[CCTK_GFINDEX3D(cctkGH, i-1, j, k)]) *hdxi;
        phiyrhs[index] = (phit[CCTK_GFINDEX3D(cctkGH, i, j+1, k)] -
                          phit[CCTK_GFINDEX3D(cctkGH, i, j-1, k)]) *hdyi;
        phizrhs[index] = (phit[CCTK_GFINDEX3D(cctkGH, i, j, k+1)] -
                          phit[CCTK_GFINDEX3D(cctkGH, i, j, k-1)]) *hdzi;

#ifdef DEBUG_MOL
        printf("ijk %i %i %i, phitrhs %f\n",i,j,k,phitrhs[index]);
#endif  
      } 
    }
  }

#ifdef DEBUG_MOL
  printf("Done with loop\n");
#endif

  return;
}

 /*@@
   @routine    WaveMoL_Energy
   @date       Sat Jun 26 15:39:18 2004
   @author     Ian Hawke
   @desc 
   Computes the energy d_t phi ^2 + d_x^i phi ^2.
   An illustration of using constrained MoL variables rather
   than anything useful.
   @enddesc 
   @calls     
   @calledby   
   @history 
 
   @endhistory 

@@*/


void WaveMoL_Energy(CCTK_ARGUMENTS)
{

  DECLARE_CCTK_ARGUMENTS;
      
  int i,j,k;
  int index;

  for (k=0; k<cctk_lsh[2]; k++)
  {
    for (j=0; j<cctk_lsh[1]; j++)
    {
      for (i=0; i<cctk_lsh[0]; i++)
      {
        index = CCTK_GFINDEX3D(cctkGH,i,j,k);
        energy[index] = phit[index]*phit[index] +
          phix[index]*phix[index] +
          phiy[index]*phiy[index] +
          phiz[index]*phiz[index];
      }
    }
  }
  
}