Task: Implement WaveBinary.c for CactusWave/WaveBinarySource thorn

thorn_name: CactusWave/WaveBinarySource
src_filename: WaveBinary.c
interface: # Interface definition for thorn IDBinarySourceC
# $Header$

implements: binarysource
inherits: wavetoy grid

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

schedule WaveBinaryC at EVOL after WaveToy_Evolution
{  
  STORAGE: wavetoy::scalarevolve[1]
  LANG:    C
} "Provide binary source during evolution (C)"

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

private:

KEYWORD binary_verbose "Rotating binary source verbose"
{
  "yes"  :: "Info on charge location/extension on first iteration"
  "debug":: "Info on charge location/extension on all iterations"
  "no"   :: "no output"
} "no"

REAL binary_size "Radial extension of the binary source" STEERABLE = ALWAYS
{
  0.0: :: "Some positive value"
} 0.5

REAL binary_omega "Frequency of the circular binary orbit" STEERABLE = ALWAYS
{
 0.0: :: "Some positive value"
} 2.0

REAL binary_charge "Charge of source" STEERABLE = ALWAYS
{
 : :: "No restriction"
} 0.1

REAL binary_radius "Radius of the circular binary orbit" STEERABLE = ALWAYS
{
 0.0: :: "Some positive value"
} 2.0


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

# Source files in this directory
SRCS = WaveBinary.c

# Subdirectories containing source files
SUBDIRS = 


```

CoordinateStuff.c:
```

```


combined_doc_context: ## README (README):
```
Cactus Code Thorn WaveBinarySource
Author(s)    : Gerd Lanfermann
Maintainer(s): Cactus team
Licence      : LGPL
--------------------------------------------------------------------------

1. Purpose

Provides a source term to the scalar field evolution
for two rotating binary charges.

```

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

```tex
=== documentation.tex ===
% 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{Gabrielle Allen} 

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

% the date your document was last changed, if your document is in CVS, 
% please us:
\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}

This thorn provides a source term to the scalar field evolution
for two rotating binary charges.


\section{Physical System}

The 3D scalar wave equation with a source term $\rho(t,x,y,z)$ is written
$$
\nabla \phi = 4 \pi \rho
$$

Each scalar source with charge $Q$ and radius $R$ contributes 
$$
\rho = \frac{3Q}{4\pi R^3}
$$

\section{Numerical Implementation}

The only involved part of this thorn arise in working out where the
sources are located (if at all) on each local grid for a multiprocessor
run. The source terms are not numerically evolved, but are calculated 
exactly, based on the physical time and their orbital velocity.

A routine is scheduled to run {\it after} the homogeneous equation
for the scalar field has been evolved, and simply updates the value
of the scalar field by adding on the source contribution.

% Do not delete next line
% END CACTUS THORNGUIDE

\end{document}

```



Reference answer:
src_code:  /*@@
   @file      WaveBinary.c
   @date      
   @author    Cactus Maintainers
   @desc 
   Add a binary source term to the 3D scalar wave equation
   @enddesc 
   @version $Header$
 @@*/

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

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

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

CCTK_FILEVERSION(CactusWave_WaveBinarySource_WaveBinary_c)

/********************************************************************
 *********************     Local Data Types   ***********************
 ********************************************************************/


/********************************************************************
 ********************* Local Routine Prototypes *********************
 ********************************************************************/


/********************************************************************
 *********************     Local Data   *****************************
 ********************************************************************/


/********************************************************************
 *****************   External Routines Prototype ********************
 ********************************************************************/

void WaveBinaryC(CCTK_ARGUMENTS);


/********************************************************************
 **********************   External Routines  ************************
 ********************************************************************/

void WaveBinaryC(CCTK_ARGUMENTS)
{
  
  DECLARE_CCTK_ARGUMENTS;
  DECLARE_CCTK_PARAMETERS;

  static int firstcall=1;

  const CCTK_REAL binary_pi=3.141592653589793;
  CCTK_REAL charge_factor;
  CCTK_REAL xsm,ysm,zsm,rad2m;
  CCTK_REAL xsp,ysp,zsp,rad2p;

  int i,j,k,vindex;

  charge_factor = 3.0*binary_charge/(4.0*binary_pi*pow(binary_size,3));

  /* Calculate the centers of the binary sources  */
  xsm = - binary_radius * cos(binary_omega*cctk_time);
  ysm = - binary_radius * sin(binary_omega*cctk_time);
  zsm = 0;
  xsp = + binary_radius * cos(binary_omega*cctk_time);
  ysp = + binary_radius * sin(binary_omega*cctk_time);
  zsp = 0;

  if ((CCTK_EQUALS(binary_verbose, "yes") && firstcall) ||
      CCTK_EQUALS(binary_verbose, "debug"))
  {
    CCTK_VInfo(CCTK_THORNSTRING,
               "Charge factor: %g\n",(double)charge_factor);
    CCTK_VInfo(CCTK_THORNSTRING,
               "Charge center (-): %g %g %g\n",
               (double)xsm,(double)ysm,(double)zsm);
    CCTK_VInfo(CCTK_THORNSTRING,
               "Charge center (+): %g %g %g\n",
               (double)xsp,(double)ysp,(double)zsp);
    CCTK_VInfo(CCTK_THORNSTRING,
               "Charge extent: %g\n",(double)binary_size);
  }
  firstcall=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++)
      {
        vindex = CCTK_GFINDEX3D(cctkGH,i,j,k);

        rad2m =
          pow(x[vindex]-xsm,2) + pow(y[vindex]-ysm,2) + pow(z[vindex]-zsm,2);
        rad2p =
          pow(x[vindex]-xsp,2) + pow(y[vindex]-ysp,2) + pow(z[vindex]-zsp,2);

        /* Note that both sources are positive, leading to a net
           monopole moment  */
        if (rad2m<pow(binary_size,2))
        {
          phi[vindex] += 0.5*pow(CCTK_DELTA_TIME,2)*charge_factor;
        }
        if (rad2p<pow(binary_size,2))
        {
          phi[vindex] += 0.5*pow(CCTK_DELTA_TIME,2)*charge_factor;
        }
      }
    }
  }

  /* Note that we do not need to sync anything, since each grid patch
     has filled out its ghostzones  */
}