aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorpollney <pollney@a491c6a4-70bf-4b89-8b36-d6c0cb1f094e>2002-11-14 13:19:55 +0000
committerpollney <pollney@a491c6a4-70bf-4b89-8b36-d6c0cb1f094e>2002-11-14 13:19:55 +0000
commitad38e65250a779b827586e44f7963969a182db65 (patch)
tree09b290fde34d8ef8d38da6acc96e2b82b1ec22be /src
parentacf684447216dd5f57dc52c3e55f5e943df25463 (diff)
Implementation of the recently discussed spacemask spec. See the
doc/documentation.tex for details. The existing mask grid-function (emask) has been retained for the time being, until the excision related thorns can be brought up to date with the new interface. These thorns should see no change in their behaviour. In the meantime, the space_mask GF can be used simultaneously via the new interfaces. git-svn-id: http://svn.cactuscode.org/arrangements/CactusNumerical/SpaceMask/trunk@15 a491c6a4-70bf-4b89-8b36-d6c0cb1f094e
Diffstat (limited to 'src')
-rw-r--r--src/MaskInit.c94
-rw-r--r--src/MaskUtils.c496
-rw-r--r--src/SpaceMask.h113
-rw-r--r--src/make.code.defn2
4 files changed, 697 insertions, 8 deletions
diff --git a/src/MaskInit.c b/src/MaskInit.c
index 50760dc..9436404 100644
--- a/src/MaskInit.c
+++ b/src/MaskInit.c
@@ -14,6 +14,7 @@
#include "cctk_Arguments.h"
#include "Symmetry.h"
+#include "SpaceMask.h"
static const char *rcsid = "$Header$";
@@ -46,8 +47,61 @@ void MaskOne(CCTK_ARGUMENTS);
********************* External Routines **********************
********************************************************************/
- /*@@
+/*@@
+ @routine SetupSpaceMaskRegistry
+ @date November 2002
+ @author Denis Pollney
+ @desc
+ Allocate and initialise the global spacemask registry.
+ @enddesc
+@@*/
+void SetupSpaceMaskRegistry (void)
+{
+ SpaceMask_Registry* spacemask_registry;
+
+ spacemask_registry = (SpaceMask_Registry*) malloc
+ (sizeof(SpaceMask_Registry));
+
+ spacemask_registry->ntypes=0;
+ spacemask_registry->type_list = NULL;
+
+ return;
+}
+
+/*@@
@routine MaskSym
+ @date October 2002
+ @author Denis Pollney
+ @desc
+ Scheduled routine to set symmetries for mask
+ @enddesc
+ @calls
+ @calledby
+ @history
+
+ @endhistory
+
+@@*/
+void MaskSym(CCTK_ARGUMENTS)
+{
+ DECLARE_CCTK_ARGUMENTS
+
+ int one;
+ int sym[3];
+
+ one = 1;
+
+ sym[0] = one;
+ sym[1] = one;
+ sym[2] = one;
+
+ SetCartSymVN(cctkGH, sym, "spacemask::space_mask");
+
+ return;
+}
+
+/*@@
+ @routine MaskSym_emask
@date Fri 3 May 2002
@author Gabrielle Allen
@desc
@@ -60,7 +114,7 @@ void MaskOne(CCTK_ARGUMENTS);
@endhistory
@@*/
-void MaskSym(CCTK_ARGUMENTS)
+void MaskSym_emask(CCTK_ARGUMENTS)
{
DECLARE_CCTK_ARGUMENTS
@@ -69,16 +123,16 @@ void MaskSym(CCTK_ARGUMENTS)
one = 1;
- sym[0] = one;
- sym[1] = one;
- sym[2] = one;
+ sym[0] = one;
+ sym[1] = one;
+ sym[2] = one;
- SetCartSymVN(cctkGH, sym,"spacemask::emask");
+ SetCartSymVN(cctkGH, sym, "spacemask::emask");
return;
}
- /*@@
+/*@@
@routine MaskOne
@date
@author Miguel Alcubierre
@@ -105,6 +159,32 @@ void MaskOne(CCTK_ARGUMENTS)
return;
}
+/*@@
+ @routine MaskZero
+ @date
+ @author Denis Pollney
+ @desc
+ Initialise the mask to zero.
+ @enddesc
+ @calls
+ @calledby
+ @history
+
+ @endhistory
+
+@@*/
+void MaskZero(CCTK_ARGUMENTS)
+{
+ DECLARE_CCTK_ARGUMENTS
+
+ int i;
+
+ for(i = 0; i < cctk_lsh[0]*cctk_lsh[1]*cctk_lsh[2]; i++)
+ space_mask[i] = 0;
+
+ return;
+}
+
/********************************************************************
********************* Local Routines *************************
********************************************************************/
diff --git a/src/MaskUtils.c b/src/MaskUtils.c
new file mode 100644
index 0000000..f8c5a75
--- /dev/null
+++ b/src/MaskUtils.c
@@ -0,0 +1,496 @@
+/*@@
+ @file MaskUtils.c
+ @date October 2002
+ @author Denis Pollney
+ @desc
+ Utilities for registering/setting/checking the mask.
+ @desc
+ @version $Header$
+@@*/
+
+#include <stdio.h>
+
+#include "cctk.h"
+#include "cctk_FortranString.h"
+
+#include "SpaceMask.h"
+
+static const char* rcsid = "$Header$";
+
+CCTK_FILEVERSION(CACTUSEINSTEIN_SPACEMASK_MaskUtils_c);
+
+SpaceMask_Registry* spacemask_registry = NULL;
+
+/*@@
+ @routine SpaceMask_get_bit_nbr
+ @author Denis Pollney
+ @date 15 October 2002
+ @desc
+ Return the number of bits required to represent a given number.
+ Cheesy divide-by-two method, maybe something else is quicker.
+ @enddesc
+@@*/
+
+int
+SpaceMask_get_bit_nbr(int nstates)
+{
+ int bstates;
+ int bit_nbr;
+
+ bstates = nstates-1;
+
+ for (bit_nbr=0; bstates>0; ++bit_nbr)
+ bstates /= 2;
+
+ return bit_nbr;
+}
+
+/*@@
+ @routine SpaceMask_get_free_bits
+ @author Denis Pollney
+ @date 15 October 2002
+ @desc
+ Determine the mask bits which have not yet been allocated.
+ The return value is a bitmask with the requested number of
+ free bits set to 1. If there are not enough free bits left
+ to satisfy the request, stop with an error.
+ @enddesc
+@@*/
+
+CCTK_INT8
+SpaceMask_get_free_bits(int nbits)
+{
+ CCTK_INT8 used_bits;
+ CCTK_INT8 new_bits;
+ int i;
+ int j;
+ int n;
+
+ used_bits = 0;
+ if (spacemask_registry != NULL)
+ {
+ for (i=0; i<spacemask_registry->ntypes; ++i)
+ used_bits |= spacemask_registry->type_list[i]->bitmask;
+ }
+
+ n=1;
+ new_bits = 0;
+ j = 0;
+ for (i=0; i<sizeof(CCTK_INT8)*8 & j<nbits; ++i)
+ {
+ if (!(n & used_bits))
+ {
+ ++j;
+ new_bits |= n;
+ }
+ n *= 2;
+ }
+
+ if (j<nbits)
+ CCTK_WARN (0, "Cannot allocate mask: Not enough free bits.");
+
+ return new_bits;
+}
+
+/*@@
+ @routine SpaceMask_determine_state_mask
+ @author Denis Pollney
+ @date 15 October 2002
+ @desc
+ Determine appropriate bitmasks to represent a number of
+ states, using the allocated bit mask.
+ That is, if allocated_bits is set to 00111000, then
+ the returned list of states are permutations of the three
+ non-zero (active) bits.
+ @enddesc
+@@*/
+
+CCTK_INT8*
+SpaceMask_determine_state_mask(CCTK_INT8 allocated_bits, int nstates)
+{
+ CCTK_INT8* state_mask;
+ int n;
+ int bit;
+ int i;
+ int j;
+
+ state_mask =
+ (CCTK_INT8*) malloc (nstates*sizeof(CCTK_INT8));
+
+ for (j=0; j<nstates; ++j)
+ state_mask[j] = 0;
+
+ n=1;
+ bit=1;
+
+ for (i=0; i<sizeof(CCTK_INT8)*8; ++i)
+ {
+ if (n & allocated_bits)
+ {
+ for (j=0; j<nstates; ++j)
+ {
+ if (bit & j)
+ state_mask[j] += n;
+ }
+ bit *= 2;
+ }
+ n *= 2;
+ }
+
+ return state_mask;
+}
+
+/*@@
+ @routine SpaceMask_setup_new_state
+ @author Denis Pollney
+ @date 15 October 2002
+ @desc
+ Allocate a new SpaceMask_State, giving it a name and
+ a bit mask.
+ @enddesc
+@@*/
+
+SpaceMask_State*
+SpaceMask_setup_new_state(CCTK_INT8 state_mask, char* name)
+{
+ SpaceMask_State* new_state;
+
+ new_state = (SpaceMask_State*) malloc (sizeof(SpaceMask_State));
+ new_state->name = name;
+ new_state->bitmask = state_mask;
+
+ return new_state;
+}
+
+/*@@
+ @routine SpaceMask_setup_new_type
+ @author Denis Pollney
+ @date 15 October 2002
+ @desc
+ Allocate a new SpaceMask_Type. This involves allocating
+ a set of bits within the mask to the new type, and creating
+ appropriate bitmasks (using the allocated bits) for each of
+ the requested states.
+ @enddesc
+@@*/
+
+SpaceMask_Type*
+SpaceMask_setup_new_type(CCTK_INT8 new_bits, char* type_name,
+ int nstates, char** state_list,
+ CCTK_INT8* state_mask)
+{
+ SpaceMask_Type* new_type;
+ int j;
+
+ new_type = (SpaceMask_Type*) malloc (sizeof(SpaceMask_Type));
+ new_type->bitmask = new_bits;
+ new_type->nstates = nstates;
+ new_type->name = type_name;
+ new_type->state_list =
+ (SpaceMask_State**) malloc (nstates*sizeof(SpaceMask_State*));
+
+ for (j=0; j<nstates; ++j)
+ new_type->state_list[j] = SpaceMask_setup_new_state(state_mask[j],
+ state_list[j]);
+ return new_type;
+}
+
+/*@@
+ @routine SpaceMask_append_type_to_registry
+ @author Denis Pollney
+ @date 15 October 2002
+ @desc
+ Adds a new type to the spacemask_registry.
+ @enddesc
+@@*/
+
+void
+SpaceMask_append_type_to_registry(SpaceMask_Type* new_type)
+{
+ SpaceMask_Type** new_type_list;
+ int ntypes;
+ int i;
+
+ if (spacemask_registry == NULL)
+ {
+ spacemask_registry =
+ (SpaceMask_Registry*) malloc (sizeof(SpaceMask_Registry));
+ ntypes = 1;
+ new_type_list = (SpaceMask_Type**) malloc (sizeof(SpaceMask_Type*));
+ new_type_list[0] = new_type;
+ }
+ else
+ {
+ ntypes = spacemask_registry->ntypes + 1;
+ new_type_list =
+ (SpaceMask_Type**) malloc (ntypes*sizeof(SpaceMask_Type*));
+ for (i=0; i<ntypes-1; ++i)
+ new_type_list[i] = spacemask_registry->type_list[i];
+ new_type_list[ntypes-1] = new_type;
+ free(spacemask_registry->type_list);
+ }
+
+ spacemask_registry->ntypes = ntypes;
+ spacemask_registry->type_list = new_type_list;
+}
+
+/*@@
+ @routine SpaceMask_RegisterType
+ @author Denis Pollney
+ @date 15 October 2002
+ @desc
+ Allocates a set of bits of the SpaceMask to represent
+ a set of states of the named type.
+ @enddesc
+@@*/
+
+int
+SpaceMask_RegisterType(char* type_name, int nstates, char** state_list)
+{
+ SpaceMask_Type* new_type;
+ CCTK_INT8 new_bits;
+ CCTK_INT8* state_mask;
+ int bit_nbr;
+
+ bit_nbr = SpaceMask_get_bit_nbr(nstates);
+ new_bits = SpaceMask_get_free_bits(bit_nbr);
+ state_mask = SpaceMask_determine_state_mask(new_bits, nstates);
+
+ new_type = SpaceMask_setup_new_type(new_bits, type_name, nstates,
+ state_list, state_mask);
+
+ SpaceMask_append_type_to_registry (new_type);
+
+ return 0;
+}
+
+/*@@
+ @routine SpaceMask_AppendStatesToType
+ @author Denis Pollney
+ @date 15 October 2002
+ @desc
+ Adds a new set of possible states to an already existing
+ type. If required, new bits of the mask are allocated to the
+ given state. If bits are not available for this, then an
+ error is returned.
+ @enddesc
+@@*/
+
+int
+SpaceMask_AppendStatesToType(char* type_name, int nstates, char** state_list)
+{
+ CCTK_INT8 new_bits;
+ CCTK_INT8 allocated_bits;
+ CCTK_INT8* state_mask;
+ SpaceMask_Type* old_type;
+ SpaceMask_Type* new_type;
+ char** new_state_list;
+ int i;
+ int j;
+ int old_type_idx;
+ int new_bit_nbr;
+ int total_nstates;
+
+ old_type = NULL;
+ for (i=0; i<spacemask_registry->ntypes; ++i)
+ {
+ if (!strcmp(spacemask_registry->type_list[i]->name, type_name))
+ {
+ old_type = spacemask_registry->type_list[i];
+ old_type_idx = i;
+ }
+ }
+
+ if (old_type == NULL)
+ {
+ CCTK_VWarn(0, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "Mask type \"%s\" has not been registered", type_name);
+ return -1;
+ }
+
+ total_nstates = old_type->nstates + nstates;
+ new_bit_nbr = SpaceMask_get_bit_nbr(total_nstates) -
+ SpaceMask_get_bit_nbr(old_type->nstates);
+
+ new_bits = SpaceMask_get_free_bits(new_bit_nbr);
+ allocated_bits = old_type->bitmask | new_bits;
+
+ state_mask = SpaceMask_determine_state_mask(allocated_bits, total_nstates);
+
+ new_state_list = (char**) malloc (total_nstates*sizeof(char*));
+
+ i = 0;
+ for (j=0; j<old_type->nstates; ++j, ++i)
+ new_state_list[i] = old_type->state_list[j]->name;
+ for (j=0; j<nstates; ++j, ++i)
+ new_state_list[i] = state_list[j];
+
+ new_type = SpaceMask_setup_new_type(allocated_bits, type_name, total_nstates,
+ new_state_list, state_mask);
+ free(old_type);
+
+ spacemask_registry->type_list[old_type_idx] = new_type;
+
+ return 0;
+}
+
+/*@@
+ @routine SpaceMask_GetTypeBits
+ @author Denis Pollney
+ @date 15 October 2002
+ @desc
+ Returns the bitmask corresponding to the given type. Bits
+ which are allocated to the given type are set to 1, all other
+ bits are 0.
+ @enddesc
+@@*/
+
+CCTK_INT8
+SpaceMask_GetTypeBits(char* type_name)
+{
+ int i;
+
+ for (i=0; i<spacemask_registry->ntypes; ++i)
+ {
+ if (!strcmp(spacemask_registry->type_list[i]->name, type_name))
+ return spacemask_registry->type_list[i]->bitmask;
+ }
+
+ CCTK_VInfo (CCTK_THORNSTRING, "Type \"%s\" has not been registered.\n",
+ type_name);
+
+ return 0;
+}
+
+/*@@
+ @routine SpaceMask_GetStateBits
+ @author Denis Pollney
+ @date 15 October 2002
+ @desc
+ Returns the bitmask corresponding to the given state.
+ @enddesc
+@@*/
+
+CCTK_INT8
+SpaceMask_GetStateBits(char* type_name, char* state_name)
+{
+ SpaceMask_Type* type;
+ int i, j;
+
+ for (i=0; i<spacemask_registry->ntypes; ++i)
+ {
+ if (!strcmp(spacemask_registry->type_list[i]->name, type_name))
+ {
+ type = spacemask_registry->type_list[i];
+ for (j=0; j<type->nstates; ++j)
+ {
+ if (!strcmp(type->state_list[j]->name, state_name))
+ return type->state_list[j]->bitmask;
+ }
+ }
+ }
+
+ CCTK_VInfo (CCTK_THORNSTRING,
+ "Requested state \"%s\" could not be found in type \"%s\"\n",
+ state_name, type_name);
+
+ return 0;
+}
+
+/*@@
+ @routine SpaceMask_SetState
+ @author Denis Pollney
+ @date 15 October 2002
+ @desc
+ Sets the mask at a point to the given state.
+ @enddesc
+@@*/
+
+void
+SpaceMask_SetState(CCTK_INT8* mask, int point, char* type_name, char* state)
+{
+ CCTK_INT8 type_bits;
+ CCTK_INT8 state_bits;
+
+ type_bits = SpaceMask_GetTypeBits(type_name);
+ state_bits = SpaceMask_GetStateBits(type_name, state);
+
+ SpaceMask_SetStateBits(mask, point, type_bits, state_bits);
+}
+
+/*@@
+ @routine SpaceMask_CheckState
+ @author Denis Pollney
+ @date 15 October 2002
+ @desc
+ Checks that the mask at a point has the given state, in which
+ case return 1, otherwise return 0.
+ @enddesc
+@@*/
+
+int
+SpaceMask_CheckState(CCTK_INT8* mask, int point, char* type_name, char* state)
+{
+ CCTK_INT8 type_bits;
+ CCTK_INT8 state_bits;
+
+ type_bits = SpaceMask_GetTypeBits(type_name);
+ state_bits = SpaceMask_GetStateBits(type_name, state);
+
+ return SpaceMask_CheckStateBits(mask, point, type_bits, state_bits);
+}
+
+
+/********************************************************************
+ ********************* Fortran Wrappers ***************************
+ ********************************************************************/
+
+/* How do you pass the char** state list from fortran???
+void
+CCTK_FCALL CCTK_FNAME(SpaceMask_RegisterType)(int* ierr, char* type_name,
+ int* nstates, char** state_list)
+{
+ *ierr = SpaceMask_RegisterType(type_name, *nstates, state_list);
+}
+*/
+
+void
+CCTK_FCALL CCTK_FNAME(SpaceMask_GetTypeBits)(CCTK_INT8* type_bits,
+ ONE_FORTSTRING_ARG)
+{
+ ONE_FORTSTRING_CREATE(type_name)
+
+ *type_bits = SpaceMask_GetTypeBits(type_name);
+
+ free(type_name);
+}
+
+void
+CCTK_FCALL CCTK_FNAME(SpaceMask_GetStateBits)(CCTK_INT8* state_bits,
+ TWO_FORTSTRING_ARG)
+{
+
+ TWO_FORTSTRING_CREATE(type_name, state_name)
+
+ *state_bits = SpaceMask_GetStateBits(type_name, state_name);
+}
+
+void
+CCTK_FCALL CCTK_FNAME(SpaceMask_SetState)(CCTK_INT8* mask,
+ CCTK_INT* point, TWO_FORTSTRING_ARG)
+{
+ TWO_FORTSTRING_CREATE(type_name, state)
+
+ SpaceMask_SetState(mask, *point, type_name, state);
+}
+
+void
+CCTK_FCALL CCTK_FNAME(SpaceMask_CheckState)(int* retval,
+ CCTK_INT8* mask,
+ CCTK_INT* point,
+ TWO_FORTSTRING_ARG)
+{
+ TWO_FORTSTRING_CREATE(type_name, state)
+
+ *retval = SpaceMask_CheckState(mask, *point, type_name, state);
+}
diff --git a/src/SpaceMask.h b/src/SpaceMask.h
new file mode 100644
index 0000000..bbcecdf
--- /dev/null
+++ b/src/SpaceMask.h
@@ -0,0 +1,113 @@
+/*@@
+ @file MaskUtils.c
+ @date October 2002
+ @author Denis Pollney
+ @desc
+ Function prototypes and macros mask utilities.
+ @desc
+ @version $Header$
+@@*/
+
+#ifndef __CACTUSEINSTEIN_SPACEMASK_H__
+#define __CACTUSEINSTEIN_SPACEMASK_H__
+
+#define DEBUG 0
+
+/********************************************************************
+ ********************* Routine Prototypes *************************
+ ********************************************************************/
+#ifdef CCODE
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+int SpaceMask_RegisterType(char*, int, char**);
+int SpaceMask_AppendStatesToType(char*, int, char**);
+void SpaceMask_SetState(CCTK_INT8*, int, char*, char*);
+int SpaceMask_CheckState(CCTK_INT8*, int, char*, char*);
+CCTK_INT8 SpaceMask_GetTypeBits(char*);
+CCTK_INT8 SpaceMask_GetStateBits(char*, char*);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/********************************************************************
+ ********************* Local Data Types **********************
+ ********************************************************************/
+
+#ifdef CCODE
+
+typedef struct
+{
+ char* name;
+ CCTK_INT8 bitmask;
+} SpaceMask_State;
+
+typedef struct
+{
+ char* name;
+ int nstates;
+ CCTK_INT8 bitmask;
+ SpaceMask_State** state_list;
+} SpaceMask_Type;
+
+typedef struct
+{
+ int ntypes;
+ SpaceMask_Type** type_list;
+} SpaceMask_Registry;
+
+extern SpaceMask_Registry* spacemask_Registry;
+
+#endif
+
+/********************************************************************
+ ********************* Macros ******************************
+ ********************************************************************/
+
+/*@@
+ @routine SpaceMask_SetStateBits
+ @author Denis Pollney
+ @date 15 October 2002
+ @desc
+ Sets the mask at a point to the given state, as specified
+ using a bitmask.
+ @enddesc
+@@*/
+
+#ifdef FCODE
+#define SpaceMask_SetStateBitsF90(mask, i, j, k, type_bits, state_bits) \
+ mask(i,j,k) = ior(iand(mask(i,j,k), not(type_bits)), state_bits)
+#endif
+
+#ifdef CCODE
+#define SpaceMask_SetStateBits(mask, ijk, type_bits, state_bits) \
+ mask[ijk] = (mask[ijk] & ~type_bits) | state_bits;
+#endif
+
+/*@@
+ @routine SpaceMask_CheckStateBits
+ @author Denis Pollney
+ @date 15 October 2002
+ @desc
+ Checks that the mask at a point has the specified state,
+ in which case return 1, otherwise return 0.
+ @enddesc
+@@*/
+
+#ifdef FCODE
+#define SpaceMask_CheckStateBitsF90(mask, i, j, k, type_bits, state_bits) \
+ (iand(mask(i,j,k), type_bits) .eq. state_bits)
+#endif
+
+#ifdef CCODE
+#define SpaceMask_CheckStateBits(mask, ijk, type_bits, state_bits) \
+ (mask[ijk] & type_bits) == state_bits
+#endif
+
+#endif /* __CACTUSEINSTEIN_SPACEMASK_H__ */
diff --git a/src/make.code.defn b/src/make.code.defn
index 4a62d46..ed19aad 100644
--- a/src/make.code.defn
+++ b/src/make.code.defn
@@ -2,7 +2,7 @@
# $Header$
# Source files in this directory
-SRCS = MaskInit.c
+SRCS = MaskInit.c MaskUtils.c
# Subdirectories containing source files
SUBDIRS =