aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
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 =