diff options
Diffstat (limited to 'src/SymmetryWrappers.c')
-rw-r--r-- | src/SymmetryWrappers.c | 363 |
1 files changed, 363 insertions, 0 deletions
diff --git a/src/SymmetryWrappers.c b/src/SymmetryWrappers.c new file mode 100644 index 0000000..c24dc33 --- /dev/null +++ b/src/SymmetryWrappers.c @@ -0,0 +1,363 @@ +#include <stdio.h> +#include <assert.h> +#include <stdlib.h> +#include <ctype.h> +#include <stdarg.h> +#include <string.h> + +#include "cctk.h" +#include "cctk_Parameters.h" +#include "cctk_FortranString.h" +#include "Symmetry.h" + +int CartApplySym3Di(cGH *GH, + int gdim, + int *doSym, + int *lssh, + int *ghostz, + int *sym, + CCTK_REAL *var); + +int CartApplySym2Di(cGH *GH, + int gdim, + int *doSym, + int *lssh, + int *ghostz, + int *sym, + CCTK_REAL *var); + +int CartApplySym1Di(cGH *GH, + int gdim, + int *doSym, + int *lssh, + int *ghostz, + int *sym, + CCTK_REAL *var); + + +/*$#define SYM_DEBUG$*/ + +int CartSymGI(cGH *GH, int gi) +{ + DECLARE_CCTK_PARAMETERS + + int numvars, vi, first_vi; + int idim, gdim; + int berr=-1,ierr=-1; + int time; + int *doSym, *dstag, *lssh; + SymmetryGHex *sGHex; + + /* Get out if we are sure no symmetries should be applied */ + /* FIXME: There has to be a better way early bailout! */ + /*$if (CCTK_Equals(domain,"full")) return 0;$*/ + + first_vi = CCTK_FirstVarIndexI(gi); + numvars = CCTK_NumVarsInGroupI(gi); + gdim = CCTK_GroupDimI(gi); + if (first_vi<0) + { + char mess[256]; + sprintf(mess,"Cannot find group %s (grp.index: %d) in CartSymGN", + CCTK_GroupName(gi),first_vi); + CCTK_WARN(1,mess); + return(-1); + } + + sGHex = (SymmetryGHex*)GH->extensions[CCTK_GHExtensionHandle("Symmetry")]; + doSym = (int *)malloc((2*gdim)*sizeof(int)); + dstag = (int *)malloc(gdim*sizeof(int)); + lssh = (int *)malloc(gdim*sizeof(int)); + + /* get the directional staggering of the group */ + ierr = CCTK_GroupStaggerDirArrayGI(dstag, gdim, gi); + + /* Use next time level, if present */ + time = CCTK_NumTimeLevelsFromVarI(first_vi) - 1; + if (time < 0) + { + time = 0; + } + + for (vi=first_vi; vi<first_vi+numvars; vi++) + { + /* Apply Symmetries to lower sides [0,2,4] if: + + if the Symmetrie is activated (== NOT NOSYM) + + if the Symmetrie is set (== NOT UNSET) + + if the lenght in the direction is more than 1 grid point + + if the processor has a lower physical boundary. + Whether a grid allows a symmetry along a direction (e.g. octant=all) + is part if the Symmetrie Setup process. + + No Symmetries for "upper" sides : [1,3,5] + */ + for (idim=0; idim<gdim; idim++) + { + if ((sGHex->GFSym[vi][idim*2] ==GFSYM_UNSET)) + + { + char mess[128]; + sprintf(mess, + "You apply a symmetry to a grid functions but have not specified the symmetries.\nVariable name: %s", CCTK_FullName(vi)); + CCTK_WARN(0,mess); + } + + lssh[idim] = GH->cctk_lssh[CCTK_LSSH_IDX(dstag[idim],idim)]; + + doSym[idim*2] = (((sGHex->GFSym[vi][idim*2]!=GFSYM_NOSYM) && + (sGHex->GFSym[vi][idim*2]!=GFSYM_UNSET)) && + lssh[idim]>1 && GH->cctk_bbox[idim*2]==1); + doSym[idim*2+1] = 0; + + } + +#ifdef SYM_DEBUG + printf(" DOSYM: %s [%d,%d] [%d,%d] [%d,%d] --- %d %d %d \n", + CCTK_VarName(vi), + doSym[0],doSym[1], + doSym[2],doSym[3], + doSym[4],doSym[5], + sGHex->GFSym[vi][0], + sGHex->GFSym[vi][2], + sGHex->GFSym[vi][4]); +#endif + + switch (gdim) + { + case 1: berr = CartApplySym1Di(GH, + gdim, + doSym, + lssh, + GH->cctk_nghostzones, + sGHex->GFSym[vi], + GH->data[vi][time]); break; + case 2: berr = CartApplySym2Di(GH, + gdim, + doSym, + lssh, + GH->cctk_nghostzones, + sGHex->GFSym[vi], + GH->data[vi][time]); break; + case 3: berr = CartApplySym3Di(GH, + gdim, + doSym, + lssh, + GH->cctk_nghostzones, + sGHex->GFSym[vi], + GH->data[vi][time]); break; + default: berr = -1; CCTK_WARN(1, "No Symmetries for GF of dim>3"); + } + berr=(berr>-1)?0:-1; + } + + free(dstag); + free(doSym); + + return(ierr); +} + +void FMODIFIER FORTRAN_NAME(CartSymGI) + (int *ierr, cGH *GH, int *gi) +{ + *ierr = CartSymGI(GH, *gi); +} + +int CartSymGN(cGH *GH, const char *gn) +{ + int gi; + char mess[128]; + gi = CCTK_GroupIndex(gn); + + if (gi>-1) + return(CartSymGI(GH,gi)); + else + { + sprintf(mess,"Cannot find group %s in CartSymGN",gn); + CCTK_WARN(1,mess); + return(-1); + } +} + +void FMODIFIER FORTRAN_NAME(CartSymGN) + (int *ierr, cGH *GH, ONE_FORTSTRING_ARG) +{ + ONE_FORTSTRING_CREATE(gn) + int gi; + char mess[128]; + + gi = CCTK_GroupIndex(gn); + + if (gi>-1) + *ierr = CartSymGI(GH, gi); + else + { + sprintf(mess,"Cannot find group %s in CartSymGN",gn); + CCTK_WARN(1,mess); + *ierr = -1; + } + free(gn); +} + + +int CartSymVI(cGH *GH, int vi) +{ + DECLARE_CCTK_PARAMETERS + + int gi; + int idim, gdim; + int berr=-1, ierr=-1; + int time; + int *doSym, *dstag, *lssh; + SymmetryGHex *sGHex; + + /* Get out if we are sure no symmetries should be applied */ + /* FIXME: There has to be a better way early bailout! */ + if (CCTK_Equals(domain,"full")) return 0; + + /* get the dimension/directional staggering of the + group that vi belongs to */ + gi = CCTK_GroupIndexFromVarI(vi); + if (gi<0) + { + char mess[256]; + sprintf(mess,"Cannot find variable %s (var.index: %d) in CartSymGN",CCTK_FullName(vi),vi); + CCTK_WARN(1,mess); + return(-1); + } + + gdim = CCTK_GroupDimI(gi); + + sGHex = (SymmetryGHex*)GH->extensions[CCTK_GHExtensionHandle("Symmetry")]; + doSym = (int *)malloc((2*gdim)*sizeof(int)); + dstag = (int *)malloc(gdim*sizeof(int)); + lssh = (int *)malloc(gdim*sizeof(int)); + + /* get the directional staggering of the group */ + ierr = CCTK_GroupStaggerDirArrayGI(dstag, gdim, gi); + + /* Use next time level, if present */ + time = CCTK_NumTimeLevelsFromVarI(vi) - 1; + if (time < 0) + { + time = 0; + } + + + /* Apply Symmetries to lower sides [0,2,4] if: + + if the Symmetrie is activated (== NOT NOSYM) + + if the Symmetrie is set (== NOT UNSET) + + if the lenght in the direction is more than 1 grid point + + if the processor has a lower physical boundary. + Whether a grid allows a symmetry along a direction (e.g. octant=all) + is part if the Symmetrie Setup process. + + No Symmetries for "upper" sides : [1,3,5] + */ + for (idim=0; idim<gdim; idim++) + { + if (sGHex->GFSym[vi][idim*2]==GFSYM_UNSET) + { + char mess[128]; + sprintf(mess, + "You apply a symmetry to a grid functions but have not specified the symmetries.\nVariable name: %s", CCTK_FullName(vi)); + CCTK_WARN(0,mess); + } + + lssh[idim] = GH->cctk_lssh[CCTK_LSSH_IDX(dstag[idim],idim)]; + + doSym[idim*2] = (((sGHex->GFSym[vi][idim*2]!=GFSYM_NOSYM) && + (sGHex->GFSym[vi][idim*2]!=GFSYM_UNSET)) && + lssh[idim]>1 && GH->cctk_bbox[idim*2]); + doSym[idim*2+1] = 0; + } + +#ifdef SYM_DEBUG + printf(" DOSYM: %s [%d,%d] [%d,%d] [%d,%d] --- %d %d %d \n", + CCTK_VarName(vi), + doSym[0],doSym[1], + doSym[2],doSym[3], + doSym[4],doSym[5], + sGHex->GFSym[vi][0], + sGHex->GFSym[vi][2], + sGHex->GFSym[vi][4]); +#endif + + + + switch (gdim) + { + case 1: berr = CartApplySym1Di(GH, + gdim, + doSym, + lssh, + GH->cctk_nghostzones, + sGHex->GFSym[vi], + GH->data[vi][time]); break; + case 2: berr = CartApplySym2Di(GH, + gdim, + doSym, + lssh, + GH->cctk_nghostzones, + sGHex->GFSym[vi], + GH->data[vi][time]); break; + case 3: berr = CartApplySym3Di(GH, + gdim, + doSym, + lssh, + GH->cctk_nghostzones, + sGHex->GFSym[vi], + GH->data[vi][time]); break; + default: berr = -1; CCTK_WARN(1, "No Symmetries for GF dim>3"); + } + + free(dstag); + free(doSym); + + return(berr); +} + +void FMODIFIER FORTRAN_NAME(CartSymVI) + (int *ierr, cGH *GH, int *vi) +{ + *ierr = CartSymVI(GH, *vi); +} + +int CartSymVN(cGH *GH, const char *vn) +{ + int vi; + char mess[128]; + + vi = CCTK_VarIndex(vn); + + if (vi>-1) + return(CartSymVI(GH, vi)); + else + { + sprintf(mess,"Cannot find variable %s in BndFlatVN",vn); + CCTK_WARN(1,mess); + return(-1); + } +} + +void FMODIFIER FORTRAN_NAME(CartSymVN) + (int *ierr, cGH *GH, ONE_FORTSTRING_ARG) +{ + ONE_FORTSTRING_CREATE(vn) + int vi; + char mess[128]; + + vi = CCTK_VarIndex(vn); + + if (vi>-1) + { + *ierr = CartSymVI(GH, vi); + } + else + { + sprintf(mess,"Cannot find variable %s in FlatBndVN",vn); + CCTK_WARN(1,mess); + *ierr=-1; + } + free(vn); +} + |