diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/MaskInit.c | 94 | ||||
-rw-r--r-- | src/MaskUtils.c | 496 | ||||
-rw-r--r-- | src/SpaceMask.h | 113 | ||||
-rw-r--r-- | src/make.code.defn | 2 |
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 = |