Task: Implement Hydro_InitExcision.c for EinsteinInitialData/Hydro_InitExcision thorn

thorn_name: EinsteinInitialData/Hydro_InitExcision
src_filename: Hydro_InitExcision.c
interface: # Interface definition for thorn Hydro_InitExcision

implements: Hydro_InitExcision
inherits: HydroBase, Grid, SpaceMask


schedule: # Schedule definitions for thorn Hydro_InitExcision

#########################################
### Sets up the excision mask         ###
#########################################
schedule Hydro_InitExcisionMask AT CCTK_Initial AFTER MaskOne
{
   LANG: C
} "Sets up the excision mask"

schedule Hydro_InitExcisionMask AT CCTK_POST_RECOVER_VARIABLES AFTER MaskOne
{
   LANG: C
} "Sets up the excision mask"

schedule Hydro_InitExcisionMask AT POSTREGRID AFTER MaskOne
{
   LANG: C
} "Sets up the excision mask"

schedule Hydro_InitExcisionMask_poststep AT POSTSTEP BEFORE setup_epsdis
{
   LANG: C
} "Sets up the excision mask"


param: # Parameter definitions for thorn Hydro_InitExcision

shares: grid

USES keyword domain

restricted:

boolean hydro_initexcision "Sets up an excision zone"
{
} "no"

boolean hydro_initexcision_poststep "Schedule also at poststep" STEERABLE=always
{
} "no"

CCTK_INT hydro_initexcision_old_mask "Also set the old 'emask'?"
{
  0:1 :: "0 (default) for no, 1 for yes"
} 0

keyword hydro_initexcision_type "Type of excision to apply"
{
  "box"	     :: "Box excised region"
  "x-axis"   :: "X axis excision"
  "y-axis"   :: "Y axis excision"
  "z-axis"   :: "Z axis excision"
  "diagonal" :: "diagonal excision"
  "sphere"   :: "sphere excision"
} "x-axis"

CCTK_INT hydro_initexcision_flip "Exchange excised and normal region"
{
  0:1 :: "0 (default) for no, 1 for yes"
} 0

CCTK_REAL hydro_initexcision_fraction "Fraction of excised region"
{
  0:1      :: "Represents the fraction of excised region (0..1)"
} 0.25

CCTK_REAL hydro_initexcision_coordinate_length "Length of excised region" STEERABLE=always
{
  0:  :: "Length of excised region, has different meanings for the types"
} 0

CCTK_REAL hydro_initexcision_position_x "x-coordinate"
{
  : :: "anything real is ok"
} 0.0

CCTK_REAL hydro_initexcision_position_y "y-coordinate"
{
  : :: "anything real is ok"
} 0.0

CCTK_REAL hydro_initexcision_position_z "z-coordinate"
{
  : :: "anything real is ok"
} 0.0

CCTK_INT hydro_initexcision_min_points "minimal number of points of excision"
{
 0: :: "minimal number of points of excision, currently only partly implemented"
} 0


context: make.code.defn:
```
# Source files in this directory
SRCS = 	Hydro_InitExcision.c

# Subdirectories containing source files
SUBDIRS = 


```


combined_doc_context: ## README (README):
```
Cactus Code Thorn Hydro_InitExcision
Author(s)    : Andrea Nerozzi
               Frank Löffler
Maintainer(s): Frank Löffler
Licence      : GPLv2+
--------------------------------------------------------------------------

1. Purpose

Setup initial excision masks specified by parameters for testing.

2. History

This thorn was developed within the Whisky code under the name
Whisky_InitExcision, was made public by the group of Whisky
developers and was then included in the EinsteinToolkit using its
present name, because it is independend of any hydro evolution code,
as long as that uses HydroBase.


```

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

```tex
=== documentation.tex ===
\documentclass{article}
\usepackage{../../../../doc/latex/cactus}
\begin{document}

% The title of the document (not necessarily the name of the Thorn)
\title{Hydro\_InitExcision - Initial Excision for Hydro Evolutions}

% The author of the documentation - on one line, otherwise it does not work
\author{Andrea Nerozzi, Frank L\"offler}

\maketitle

% 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)

% Do not delete next line
% START CACTUS THORNGUIDE

%\newcommand{\eqref}[1]{(\ref{#1})}

% Add an abstract for this thorn's documentation
\begin{abstract}
  This thorn initialises the excision-spacemask for GRHydro to
  specified forms. It is based on a similar version used to initialise
  the excision-mask for Whisky code.
\end{abstract}

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

\section{Using This Thorn}

Using this thorn is quite easy:
You have to activate it in your parameter file and specify at least the
following:

\begin{verbatim}
hydro_initexcision::hydro_initexcision = "yes"
\end{verbatim}

In addition to that you may want to specify the type of excision zone
you want to have. You can do this by

\begin{verbatim}
hydro_initexcision::hydro_initexcision_type = <TYPE>
\end{verbatim}

where \begin{verbatim}<TYPE>\end{verbatim} is one of the following list:
\begin{itemize}
 \item "x-axis"
 \item "y-axis"
 \item "z-axis"
 \item "box"
 \item "sphere"
\end{itemize}

\section{Thorn Source Code}

This was initially written by Andrea Nerozzi and later changed
by Frank L\"offler.

\section{Thorn Documentation}

This documentation was largely written by Frank L\"offler.

% Do not delete next line
% END CACTUS THORNGUIDE

\end{document}

```



Reference answer:
src_code:  /*@@
   @file      Hydro_InitExcisionMask.c
   @date      Wed Mar 13 14:18:38 2002
   @author    Andrea Nerozzi, Frank Loeffler
   @desc 
   Creates the mask for an excision region 
   @enddesc 
 @@*/

#include "cctk.h"
#include "cctk_Parameters.h"
#include "cctk_Arguments.h"
#include <stdio.h>
#include <math.h>
#include <assert.h>

 /*@@
   @routine    Excision Mask 
   @date       Mon Apr 7 14:18:38 2003
   @author     Andrea Nerozzi
   @desc 
   Sets up the excision region
   @enddesc 
   @calls     
   @calledby   
   @history    added 'sphere' and rewrote to be multi-processor-safe
 
   @endhistory 

@@*/

void Hydro_InitExcisionMask(CCTK_ARGUMENTS)
{

  DECLARE_CCTK_ARGUMENTS;
  DECLARE_CCTK_PARAMETERS;

  enum domain_vals {full = 0, octant, n_domain_vals};
  enum hydro_initexcision_type_vals {
    box = 0, xaxis, yaxis, zaxis, diagonal, sphere, 
    n_hydro_initexcision_type_vals
  };
  const char * domain_val_keywords[n_domain_vals] = {"full", "octant"};
  const char * hydro_initexcision_type_val_keywords[n_hydro_initexcision_type_vals] = {
    "box", "x-axis", "y-axis", "z-axis", "diagonal", "sphere"
  };

  CCTK_INT  i,j,k, nx, ny, nz, point;
  CCTK_INT excised, normal;
  CCTK_REAL emask_excised, emask_normal;
  CCTK_REAL x_min, x_max, y_min, y_max, z_min, z_max;
  CCTK_REAL x_size, y_size, z_size;
  CCTK_REAL x_frac, y_frac, z_frac;
  enum domain_vals domain_val;
  enum hydro_initexcision_type_vals hydro_initexcision_type_val;

  if (hydro_initexcision)
  {
    CCTK_INFO("Setting up Hydro Initial Excision region.");
  }

  /* decode keyword parameters */
  for (domain_val = 0 ; domain_val < n_domain_vals ; domain_val++)
  {
    if (CCTK_Equals(domain, domain_val_keywords[domain_val]))
      break;
  }
  assert(domain_val < n_domain_vals);
  for (hydro_initexcision_type_val = 0 ; 
       hydro_initexcision_type_val < n_hydro_initexcision_type_vals ; 
       hydro_initexcision_type_val++)
  {
    if (CCTK_Equals(hydro_initexcision_type, 
          hydro_initexcision_type_val_keywords[hydro_initexcision_type_val]))
      break;
  }
  assert(hydro_initexcision_type_val < n_hydro_initexcision_type_vals);

  nx = cctk_lsh[0];
  ny = cctk_lsh[1];
  nz = cctk_lsh[2];

  CCTK_CoordRange(cctkGH, &x_min, &x_max, 1, NULL, "cart3d");
  CCTK_CoordRange(cctkGH, &y_min, &y_max, 2, NULL, "cart3d");
  CCTK_CoordRange(cctkGH, &z_min, &z_max, 3, NULL, "cart3d");
  x_size = x_max - x_min;
  y_size = y_max - y_min;
  z_size = z_max - z_min;

  excised=1;
  normal =0;
  emask_excised=0.0;
  emask_normal=1.0;
  if (hydro_initexcision_flip)
  {
    excised=0;
    normal =1;
    emask_excised=1.0;
    emask_normal=0.0;
  }

  for (k=0 ; k<nz ; k++)
  {
    for (j=0 ; j<ny ; j++)
    {
      for (i=0 ; i<nx; i++)
      { 
        point = CCTK_GFINDEX3D(cctkGH,i,j,k);
        x_frac = (x[point]-x_min) / x_size + 1.e-10;
        y_frac = (y[point]-y_min) / y_size + 1.e-10;
        z_frac = (z[point]-z_min) / z_size + 1.e-10;

        if (hydro_initexcision)
        {
          if (hydro_initexcision_old_mask)
            emask[point]=emask_normal;
          if (hydro_initexcision_type_val == box)
          {
              if (domain_val == full)
              {
                 if ( ( (hydro_initexcision_coordinate_length <= 0.0) &&
                        ( x_frac > 0.5 - hydro_initexcision_fraction) &&
                        ( x_frac < 0.5 + hydro_initexcision_fraction) &&
                        ( y_frac > 0.5 - hydro_initexcision_fraction) &&
                        ( y_frac < 0.5 + hydro_initexcision_fraction) &&
                        ( z_frac > 0.5 - hydro_initexcision_fraction) &&
                        ( z_frac < 0.5 + hydro_initexcision_fraction)
                      ) ||
                      ( (hydro_initexcision_coordinate_length > 0.0) &&
                        ( fabs(x[point]-hydro_initexcision_position_x) <=
                          hydro_initexcision_coordinate_length*0.5) &&
                        ( fabs(y[point]-hydro_initexcision_position_y) <=
                          hydro_initexcision_coordinate_length*0.5) &&
                        ( fabs(z[point]-hydro_initexcision_position_z) <=
                          hydro_initexcision_coordinate_length*0.5)
                      )
                    )
                 {
                    hydro_excision_mask[point] = excised;
                    if (hydro_initexcision_old_mask)
                      emask[point]=emask_excised;
                 }
                 else
                 {
                    hydro_excision_mask[point] = normal;
                 }
              }
              else if (domain_val == octant)
              {
                 if ( ( (hydro_initexcision_coordinate_length <= 0.0) &&
                        ( x_frac < hydro_initexcision_fraction) &&
                        ( y_frac < hydro_initexcision_fraction) &&
                        ( z_frac < hydro_initexcision_fraction)
                      ) || 
                      ( (hydro_initexcision_coordinate_length > 0.0) &&
                        ( fabs(x[point]-hydro_initexcision_position_x) <=
                          hydro_initexcision_coordinate_length*0.5) &&
                        ( fabs(y[point]-hydro_initexcision_position_y) <=
                          hydro_initexcision_coordinate_length*0.5) &&
                        ( fabs(z[point]-hydro_initexcision_position_z) <=
                          hydro_initexcision_coordinate_length*0.5)
                      )
                    )
                 {
                    hydro_excision_mask[point] = excised;
                    if (hydro_initexcision_old_mask)
                      emask[point]=emask_excised;
                 }
                 else
                 {
                    hydro_excision_mask[point] = normal;
                 }
              }
          }
          else if (hydro_initexcision_type_val == xaxis)
          {
            if ( x_frac < 1.0-hydro_initexcision_fraction )
            {
              hydro_excision_mask[point] = normal;
            }
            else 
            {
              hydro_excision_mask[point] = excised;
              if (hydro_initexcision_old_mask)
                emask[point]=emask_excised;
            }
          }
          else if (hydro_initexcision_type_val == yaxis)
          {
            if ( y_frac < 1.0-hydro_initexcision_fraction )
            {
              hydro_excision_mask[point] = normal;
            }
            else 
            {
              hydro_excision_mask[point] = excised;
              if (hydro_initexcision_old_mask)
                emask[point]=emask_excised;
            }
          }
          else if (hydro_initexcision_type_val == zaxis)
          {
            if ( z_frac < 1.0-hydro_initexcision_fraction )
            {
              hydro_excision_mask[point] = normal;
            }
            else 
            {
              hydro_excision_mask[point] = excised;
              if (hydro_initexcision_old_mask)
                emask[point]=emask_excised;
            }
          }
          else if (hydro_initexcision_type_val == diagonal)
          {
            if ( x_frac + y_frac + z_frac <
                 3.0*(1.0-hydro_initexcision_fraction) )
            {
              hydro_excision_mask[point] = normal;
            }
            else 
            {
              hydro_excision_mask[point] = excised;
              if (hydro_initexcision_old_mask)
                emask[point]=emask_excised;
            }
          }
          else if (hydro_initexcision_type_val == sphere)
          {
            if ( ( (hydro_initexcision_coordinate_length <= 0.0) &&
                   ( (x[point]-hydro_initexcision_position_x) *
                     (x[point]-hydro_initexcision_position_x) +
                     (y[point]-hydro_initexcision_position_y) *
                     (y[point]-hydro_initexcision_position_y) +
                     (z[point]-hydro_initexcision_position_z) *
                     (z[point]-hydro_initexcision_position_z) ) * 4.0
                   > (hydro_initexcision_fraction * x_size *
                      hydro_initexcision_fraction * x_size) ) ||
                 ( (hydro_initexcision_coordinate_length > 0) &&
                   ( (hydro_initexcision_coordinate_length < 
                      cctkGH->cctk_delta_space[0]*
                      hydro_initexcision_min_points) ||
                       ( (x[point]-hydro_initexcision_position_x) *
                         (x[point]-hydro_initexcision_position_x) +
                         (y[point]-hydro_initexcision_position_y) *
                         (y[point]-hydro_initexcision_position_y) +
                         (z[point]-hydro_initexcision_position_z) *
                         (z[point]-hydro_initexcision_position_z)
                     > hydro_initexcision_coordinate_length*
                       hydro_initexcision_coordinate_length) ) ) )
            {
              hydro_excision_mask[point] = normal;
            }
            else 
            {
              hydro_excision_mask[point] = excised;
              if (hydro_initexcision_old_mask)
              {
                emask[point]=emask_excised;
              }
            }
          }
        }
        else
        {
          hydro_excision_mask[point] = normal;
          if (hydro_initexcision_old_mask)
            emask[point]=emask_normal;
        }
      }
    }
  }
  return;
}

void Hydro_InitExcisionMask_poststep(CCTK_ARGUMENTS)
{
  DECLARE_CCTK_ARGUMENTS;
  DECLARE_CCTK_PARAMETERS;
  if (hydro_initexcision_poststep)
      Hydro_InitExcisionMask(CCTK_PASS_CTOC);
}