#include #include #include #include #include #include #include "rotatingsymmetry90.h" #include #include #include #include /* This is pretty hard coded into all the tensor types and cannot be changed easily. */ #define DIM 3 /* spatial dimension */ static int convert_index (int const step, int const index, int const * restrict const alldirs, int * restrict const parity) { int srcindex; assert (index>=0 && index=0 && alldirs[0]=0 && alldirs[1]=0 && vis[var]0); gis = malloc (nvars * sizeof *gis); assert (nvars==0 || gis); varptrs = malloc (nvars * sizeof *varptrs); assert (nvars==0 || varptrs); vartypes = malloc (nvars * sizeof *vartypes); assert (nvars==0 || vartypes); vectorlengths = malloc (nvars * sizeof *vectorlengths); assert (nvars==0 || vectorlengths); for (var=0; var=0 && gis[var]= 0); vectorlengths[var] = group.vectorlength; assert (vectorlengths[var]>=0); assert (vectorlengths[var]==1 || group.vectorgroup); } for (d=0; d0); firstvar = CCTK_FirstVarIndexI(gis[var]); assert (firstvar>=0); index = vis[var] - firstvar; assert (index>=0 && index=0); ierr = Util_TableGetString (table, sizeof tensortypealias, tensortypealias, "tensortypealias"); if (ierr == UTIL_ERROR_TABLE_NO_SUCH_KEY) { /* assume a scalar */ if (numvars != 1) { static int * restrict didwarn = 0; if (! didwarn) { didwarn = calloc (CCTK_NumGroups(), sizeof *didwarn); } if (! didwarn[gis[var]]) { char * groupname = CCTK_GroupName(gis[var]); assert (groupname); CCTK_VWarn (2, __LINE__, __FILE__, CCTK_THORNSTRING, "Group \"%s\" has no tensor type and contains more than one element -- treating these as \"scalar\"", groupname); free (groupname); didwarn[gis[var]] = 1; } } strcpy (tensortypealias, "scalar"); } else if (ierr<0) { char * groupname = CCTK_GroupName(gis[var]); assert (groupname); CCTK_VWarn (0, __LINE__, __FILE__, CCTK_THORNSTRING, "Error in tensor type alias declaration for group \"%s\"", groupname); free (groupname); } if (CCTK_EQUALS (tensortypealias, "scalar")) { /* scalar */ } else if (CCTK_EQUALS (tensortypealias, "4scalar")) { /* 4-scalar */ } else if (CCTK_EQUALS (tensortypealias, "u") || CCTK_EQUALS (tensortypealias, "d")) { /* vector */ assert ((numvars == DIM*vectorlength) || (numvars == DIM && vectorlength == DIM)); } else if (CCTK_EQUALS (tensortypealias, "4u") || CCTK_EQUALS (tensortypealias, "4d")) { /* 4-vector */ assert (numvars == (DIM+1)*vectorlength); } else if (CCTK_EQUALS (tensortypealias, "uu") || CCTK_EQUALS (tensortypealias, "ud") || CCTK_EQUALS (tensortypealias, "du") || CCTK_EQUALS (tensortypealias, "dd")) { /* tensor */ assert (numvars == DIM*DIM*vectorlength); } else if (CCTK_EQUALS (tensortypealias, "uu_sym") || CCTK_EQUALS (tensortypealias, "dd_sym")) { /* symmetric tensor */ assert (numvars == DIM*(DIM+1)/2*vectorlength); } else if (CCTK_EQUALS (tensortypealias, "ddd_sym")) { /* 3rd rank tensor, symmetric in last 2 indices */ assert (numvars == DIM*DIM*(DIM+1)/2*vectorlength); } else if (CCTK_EQUALS (tensortypealias, "4uu_sym") || CCTK_EQUALS (tensortypealias, "4dd_sym")) { /* symmetric 4-tensor */ assert (numvars == (DIM+1)*(DIM+2)/2*vectorlength); } else if (CCTK_EQUALS (tensortypealias, "weylscalars_real")) { /* Weyl scalars, stored as 10 real numbers */ assert (numvars == 10*vectorlength); } else { char * groupname = CCTK_GroupName(gis[var]); assert (groupname); CCTK_VWarn (0, __LINE__, __FILE__, CCTK_THORNSTRING, "Illegal tensor type alias for group \"%s\"", groupname); free (groupname); } } parities[var] = +1; if (CCTK_EQUALS (tensortypealias, "scalar")) { /* scalar */ srcvi = vis[var]; /* do nothing */ } else if (CCTK_EQUALS (tensortypealias, "4scalar")) { /* 4-scalar */ srcvi = vis[var]; /* do nothing */ } else if (CCTK_EQUALS (tensortypealias, "u") || CCTK_EQUALS (tensortypealias, "d")) { /* vector */ int srcindex; /* special case for vel[i] */ assert (index>=0 && index=0 && index<(DIM+1)*vectorlength); if (index/vectorlength==0) { /* temporal component */ srcvi = firstvar; } else { /* spatial components */ int srcindex; int const off = 1; srcindex = index % vectorlength + vectorlength * (off + convert_index (step, index/vectorlength-off, alldirs, &parities[var])); srcvi = firstvar + srcindex; } } else if (CCTK_EQUALS (tensortypealias, "uu") || CCTK_EQUALS (tensortypealias, "ud") || CCTK_EQUALS (tensortypealias, "du") || CCTK_EQUALS (tensortypealias, "dd")) { /* tensor */ assert (numvars == DIM*DIM); int index1, index2; int srcindex1, srcindex2; int srcindex; assert (index>=0 && index=0 && index=0 && index=0 && index<(DIM+1)*(DIM+2)/2*vectorlength); if (index/vectorlength==0) { /* temporal-temporal component */ srcvi = firstvar; } else if (index<(DIM+1)*vectorlength) { /* temporal-spatial components */ int srcindex; int const off = 1; srcindex = index % vectorlength + vectorlength * (off + convert_index (step, index/vectorlength-off, alldirs, &parities[var])); srcvi = firstvar + srcindex; } else { /* spatial-spatial components */ int index1, index2; int srcindex1, srcindex2; int srcindex; int const off = DIM+1; { int const expand1[DIM*(DIM+1)/2] = { 0,0,0,1,1,2 }; int const expand2[DIM*(DIM+1)/2] = { 0,1,2,1,2,2 }; index1 = expand1[index/vectorlength-off]; index2 = expand2[index/vectorlength-off]; } srcindex1 = convert_index (step, index1, alldirs, &parities[var]); srcindex2 = convert_index (step, index2, alldirs, &parities[var]); { int const compact[DIM][DIM] = { { 0,1,2 }, { 1,3,4 }, { 2,4,5 } }; srcindex = index % vectorlength + vectorlength * (off + compact[srcindex1][srcindex2]); } srcvi = firstvar + srcindex; } } else if (CCTK_EQUALS (tensortypealias, "weylscalars_real")) { /* Weyl scalars, stored as 10 reals */ assert (index>=0 && index<10*vectorlength); srcvi = vis[var]; } else { assert (0); } srcptrs[var] = CCTK_VarDataPtrI (cctkGH, 0, srcvi); assert (srcptrs[var]); } /* for var */ have_global_bbox = 1; for (q=0; q= 0); if (data.gsh[otherdir[q]] < data.nghostzones[dir[q]] + data.nghostzones[otherdir[q]] + offset[otherdir[q]]) { assert (nvars > 0); var = 0; CCTK_VWarn (0, __LINE__, __FILE__, CCTK_THORNSTRING, "The group \"%s\" has in the %c-direction only %d grid points. " "This is not large enough for a 90 degree rotating symmetry boundary that is %d grid points wide in the %c-direction. " "The group needs to have at least %d grid points in the %c-direction.", CCTK_GroupNameFromVarI(vis[var]), "xyz"[dir[q]], data.gsh[dir[q]], data.nghostzones[dir[q]], "xyz"[otherdir[q]], data.nghostzones[dir[q]] + data.nghostzones[otherdir[q]] + offset[otherdir[q]], "xyz"[dir[q]]); } } if (poison_boundaries) { /* poison destination grid points */ int have_bnd = 1; for (q=0; qcctk_bbox[2*dir[q]]; } if (have_bnd) { int imin[3], imax[3]; int i, j, k; for (d=0; d<3; ++d) { imin[d] = 0; imax[d] = cctk_lsh[d]; } for (q=0; q 1) { CCTK_WARN (CCTK_WARN_ABORT, "TAT/Slab can only be used if there is a single local component per MPI process"); } } options = Util_TableCreateFromString ("useghosts=1"); assert (options>=0); /* Can we use the more efficient interface? */ if (CCTK_IsFunctionAliased ("GetRegriddingEpoch")) { static int epoch = -1; static struct slabsetup *restrict *restrict slab_setups[3] = { NULL, NULL, NULL}; static int num_reflevels = 0; int const new_epoch = GetRegriddingEpoch (cctkGH); if (new_epoch > epoch) { epoch = new_epoch; /* Delete old slabbing setups */ for (int s=0; s<3; ++s) { for (int rl=0; rl=0 && reflevelcctk_bbox[2*dir[q]]; } if (have_bnd) { int imin[3], imax[3]; int i, j, k; for (d=0; d<3; ++d) { imin[d] = 0; imax[d] = cctk_lsh[d]; } for (q=0; q= cctk_lsh[d]) imax[d] = cctk_lsh[d]; } assert (group.dim == DIM); switch (group.vartype) { case CCTK_VARIABLE_INT: { CCTK_INT * restrict const varptr = varptrs[var]; for (k=imin[2]; k=0); if (nvars==0) return; { int max_handle; int d; /* 0..group.dim-1 */ int ierr; CCTK_INT local[4*DIM], global[4*DIM]; max_handle = CCTK_ReductionArrayHandle ("maximum"); if (max_handle<0) CCTK_WARN (0, "Could not obtain reduction handle"); for (d=0; d<2*DIM; ++d) local[ d] = cctkGH->cctk_bbox[d]; for (d=0; d< DIM; ++d) local[2*DIM+d] = -cctkGH->cctk_lbnd[d]; for (d=0; d< DIM; ++d) local[3*DIM+d] = cctkGH->cctk_ubnd[d]; ierr = CCTK_ReduceLocArrayToArray1D (cctkGH, -1, max_handle, local, global, 4*DIM, CCTK_VARIABLE_INT); assert(!ierr); for (d=0; d<2*DIM; ++d) global_bbox[d] = global[ d]; for (d=0; d< DIM; ++d) global_lbnd[d] = -global[2*DIM+d]; for (d=0; d< DIM; ++d) global_ubnd[d] = global[3*DIM+d]; /* record when we ran to have some sanity check against using old data in * global variables */ extent_valid_for_iteration = cctk_iteration; } } void Rot90_ApplyBC (CCTK_ARGUMENTS) { DECLARE_CCTK_ARGUMENTS; int nvars; CCTK_INT * restrict indices; CCTK_INT * restrict faces; CCTK_INT * restrict widths; CCTK_INT * restrict tables; int var; int ierr; assert (cctkGH); nvars = Boundary_SelectedGVs (cctkGH, 0, 0, 0, 0, 0, 0); assert (nvars>=0); if (nvars==0) return; indices = malloc (nvars * sizeof *indices); assert (indices); faces = malloc (nvars * sizeof *faces); assert (faces); widths = malloc (nvars * sizeof *widths); assert (widths); tables = malloc (nvars * sizeof *tables); assert (tables); ierr = Boundary_SelectedGVs (cctkGH, nvars, indices, faces, widths, tables, 0); assert (ierr == nvars); for (var=0; var=0 && indices[var]=0); } ierr = BndRot90VI (cctkGH, nvars, indices); assert (!ierr); free (indices); free (faces); free (widths); free (tables); }