Proposal for formalising the use of CactusEinstein/SpaceMask ------------------------------------------------------------ (Denis Pollney pollney@aei.mpg.de, 9 Oct 2002) The Spacemask thorn, and the associated spacemask::emask grid function were created to provide a grid function whose value could be used to classify points on the grid. The following text outlines a proposal for formalising the use of the mask as a collection of bits which can be set to represent given states. Possible states are registered at program initialisation. Mask states are set and checked using functions provided by the SpaceMask thorn. * Current use of SpaceMask: The spacemask::emask is currently only used by various excision-related thorns at the AEI. In particular, once the CactusEinstein/AHFinder determines a region to excise based on the apparent horizon location, it sets the mask to 1.0 at regular grid points 0.0 at points which are to be excised The Excision/LegoExcision thorn can also set the emask to 0.5 at boundary points of the excised region (The AEIDevelopment/MaskIso thorn can be used in place of the AHFinder to set the mask according to the same convention.) * Requirements of the mask: Though this convention is in place for historical reasons, the specific usage of values of emask has not been fixed in any global way. It would be desirable if there was a mechanism for thorn developers to use the mask to classify grid points according to their needs. One can imagine defining different boundary conditions on different faces of the grid, or on regions located within the grid, based on mask values. Regions of the grid requiring different evolution equations (eg. interior vs exterior of stars) or difference techniques could be identified using the mask. Etc. This could be accomplished using seperate masks for each type of classification, though it would by quite inefficient (currently, emask is a CCTK_REAL which keeps track of only three possible states). Better would be to develop a method to pack more information into a single global mask, which was the original intention behind the creation of the CactusEinstein/SpaceMask thorn and spacemask::emask grid function. This will require a mechanism which allows individual thorns to set and evaluate values of the mask without interfering with values set by other thorns. Similarly, there needs to be methods for reading mask information at a point unambiguously and quickly. * Proposed mechanism: The basic mechanism could be to register certain bits in the emask value to represent individual states, and provide routines for setting and checking these states. For instance, if the emask were 8 bits long (00000000), then the first two bits (xx000000) could be registered as bits corresponding to excision at startup, and the three particular excision states registered as 00000000=normal, 01000000=boundary, and 10000000=excised. Later in the code, routines needing to determine the excision state of a point would check the value of the appropriate excision bits of the mask. The following functions would do the job: int SpaceMask_RegisterType (char* type_name, int nstates, **state_list) - type_name: a string identifying the type, eg. "excision" - nstates: the number of states needed for the given type - state_list: a list of states for the given type, eg. {"normal", "boundary", "excised"} This function will set aside the number of bits of emask required to hold the required number of states. Returns an error flag. int SpaceMask_SetState (int* mask, int ijk, char* type_name, char* state, int point) - mask: pointer to the mask data - ijk: the particular index of mask to be set - type_name: the identifier of the type to set, eg. "excision" - state: the state to set, eg. "excised" - point: the point on the grid to be set, eg. ijk Returns an error flag. int SpaceMask_CheckState (int* mask, int ijk, char* type_name, char* state, int npoint) (as above) Returns TRUE if npoint is set to the specified state * Example: At some point in startup, the excision thorn would claim some bits in emask using a function such as: void Excise_SetupMask(void) { char* excision_states[3] = {"standard", "boundary", "excised"}; int ierr; ierr = SpaceMask_RegisterType("excision", 3, excision_states); if (ierr<0) CCTK_WARN(0, "Couldn't allocate excision mask!") } The mask could later be set by the horizon finder (or whatever) using: ... for (ijk=0; ijk