aboutsummaryrefslogtreecommitdiff
path: root/src/apply.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/apply.c')
-rw-r--r--src/apply.c627
1 files changed, 627 insertions, 0 deletions
diff --git a/src/apply.c b/src/apply.c
new file mode 100644
index 0000000..114c1f7
--- /dev/null
+++ b/src/apply.c
@@ -0,0 +1,627 @@
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "cctk.h"
+#include "cctk_Arguments.h"
+#include "cctk_Parameters.h"
+
+#include "util_ErrorCodes.h"
+#include "util_Table.h"
+
+#include "reflection.h"
+
+
+
+static const char rcsid[] = "$Header$";
+CCTK_FILEVERSION(AEIDevelopment_ReflectionSymmetry_apply_c);
+
+
+
+#define COPY(VARTYPE) \
+ static void \
+ copy_##VARTYPE (VARTYPE const * restrict const srcvar, \
+ VARTYPE * restrict const dstvar, \
+ int const ni, int const nj, int const nk, \
+ int const imin, int const jmin, int const kmin, \
+ int const imax, int const jmax, int const kmax, \
+ int const ioff, int const joff, int const koff, \
+ int const idir, int const jdir, int const kdir, \
+ int const parity) \
+ { \
+ int i, j, k; \
+ \
+ for (k=kmin; k<kmax; ++k) \
+ { \
+ for (j=jmin; j<jmax; ++j) \
+ { \
+ for (i=imin; j<imax; ++i) \
+ { \
+ int const dstind = i + ni * (j + nj * k); \
+ int const ii = ioff + idir * i; \
+ int const jj = joff + jdir * j; \
+ int const kk = koff + kdir * k; \
+ int const srcind = ii + ni * (jj + nj * kk); \
+ REAL(dstvar[dstind] RE = parity * srcvar[srcind] RE;) \
+ IMAG(dstvar[dstind] IM = parity * srcvar[srcind] IM;) \
+ } \
+ } \
+ } \
+ }
+
+#define REAL(x) x
+#define IMAG(x) /* nothing */
+#define RE /* nothing */
+#define IM /* nothing */
+
+#ifdef CCTK_INT1
+COPY(CCTK_INT1)
+#endif
+
+#ifdef CCTK_INT2
+ COPY(CCTK_INT2)
+#endif
+
+#ifdef CCTK_INT4
+ COPY(CCTK_INT4)
+#endif
+
+#ifdef CCTK_INT8
+ COPY(CCTK_INT8)
+#endif
+
+#ifdef CCTK_REAL4
+ COPY(CCTK_REAL4)
+#endif
+
+#ifdef CCTK_REAL8
+ COPY(CCTK_REAL8)
+#endif
+
+#ifdef CCTK_REAL16
+ COPY(CCTK_REAL16)
+#endif
+
+#undef REAL
+#undef IMAG
+#undef RE
+#undef IM
+
+#define REAL(x) x
+#define IMAG(x) x
+#define RE .Re
+#define IM .Im
+
+#ifdef CCTK_REAL4
+ COPY(CCTK_COMPLEX8)
+#endif
+
+#ifdef CCTK_REAL8
+ COPY(CCTK_COMPLEX16)
+#endif
+
+#ifdef CCTK_REAL16
+ COPY(CCTK_COMPLEX32)
+#endif
+
+#undef REAL
+#undef IMAG
+#undef RE
+#undef IM
+
+#undef COPY
+
+
+
+static int
+BndReflectVI (cGH const * restrict const cctkGH,
+ int const * restrict const stencil,
+ int const vi)
+{
+ DECLARE_CCTK_PARAMETERS;
+
+ int gi;
+ cGroup group;
+ cGroupDynamicData data;
+ int firstvar, numvars;
+ char * restrict fullname;
+ char * restrict groupname;
+
+ void * restrict varptr;
+
+ int table;
+ char tensortypealias[1000];
+ enum tensortype { UNKNOWN, SCALAR, VECTOR, TENSOR };
+ enum tensortype ttype;
+ int tcomponent;
+
+ int do_reflection[6];
+ int do_stagger[6];
+
+ int dir, face;
+
+ int lsh[3], imin[3], imax[3], ioff[3], idir[3];
+
+ int parity;
+
+ int d;
+
+ int ierr;
+
+
+
+ /* Check arguments */
+ if (! cctkGH)
+ {
+ CCTK_WARN (0, "Argument cctkGH is NULL");
+ }
+ if (! stencil)
+ {
+ CCTK_WARN (0, "Argument stencil is NULL");
+ }
+ if (vi < 0 || vi >= CCTK_NumVars())
+ {
+ CCTK_WARN (0, "Illegal variable index");
+ }
+
+ if (verbose)
+ {
+ fullname = CCTK_FullName (vi);
+ if (! fullname)
+ {
+ CCTK_WARN (0, "Internal error in CCTK_FullName");
+ }
+ CCTK_VInfo (CCTK_THORNSTRING,
+ "Applying reflection boundary conditions to \"%s\"",
+ fullname);
+ free (fullname);
+ }
+
+
+
+ /* Get and check group information */
+ gi = CCTK_GroupIndexFromVarI (vi);
+ if (gi < 0 || gi > CCTK_NumGroups())
+ {
+ CCTK_WARN (0, "Internal error in CCTK_GroupIndexFromVarI");
+ }
+
+ ierr = CCTK_GroupData (gi, &group);
+ assert (!ierr);
+ assert (group.grouptype == CCTK_GF);
+ assert (group.disttype == CCTK_DISTRIB_DEFAULT);
+ assert (group.stagtype == 0);
+
+ firstvar = CCTK_FirstVarIndexI (gi);
+ assert (firstvar>=0 && firstvar<CCTK_NumVars());
+ numvars = CCTK_NumVarsInGroupI (gi);
+ assert (numvars>=0);
+
+ ierr = CCTK_GroupDynamicData (cctkGH, gi, &data);
+ assert (!ierr);
+
+ table = CCTK_GroupTagsTableI(gi);
+ assert (table>=0);
+
+ varptr = CCTK_VarDataPtrI (cctkGH, 0, vi);
+ assert (varptr);
+
+
+
+ /* Get and check tensor type information */
+ ierr = Util_TableGetString
+ (table, sizeof tensortypealias, tensortypealias, "tensortypealias");
+ if (ierr == UTIL_ERROR_TABLE_NO_SUCH_KEY) {
+ groupname = CCTK_GroupName(gi);
+ assert (groupname);
+ CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "Tensor type alias not declared for group \"%s\" -- assuming a scalar",
+ groupname);
+ free (groupname);
+ strcpy (tensortypealias, "scalar");
+ } else if (ierr<0) {
+ groupname = CCTK_GroupName(gi);
+ assert (groupname);
+ CCTK_VWarn (0, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "Error in tensor type alias declaration for group \"%s\"",
+ groupname);
+ free (groupname);
+ }
+
+ ttype = UNKNOWN;
+ tcomponent = 0;
+ if (CCTK_EQUALS (tensortypealias, "scalar"))
+ {
+ /* scalar */
+ if (numvars != 1) {
+ groupname = CCTK_GroupName(gi);
+ assert (groupname);
+ CCTK_VWarn (2, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "Group \"%s\" has the tensor type alias \"scalar\", but contains more than 1 element",
+ groupname);
+ free (groupname);
+ }
+ ttype = SCALAR;
+ tcomponent = 0;
+ }
+ else if (CCTK_EQUALS (tensortypealias, "u"))
+ {
+ /* vector */
+ assert (numvars == 3);
+ ttype = VECTOR;
+ tcomponent = vi - firstvar;
+ } else if (CCTK_EQUALS (tensortypealias, "dd_sym")) {
+ /* symmetric tensor */
+ assert (numvars == 6);
+ ttype = TENSOR;
+ tcomponent = vi - firstvar;
+ } else {
+ char * groupname = CCTK_GroupName(gi);
+ assert (groupname);
+ CCTK_VWarn (0, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "Illegal tensor type alias for group \"%s\"",
+ groupname);
+ free (groupname);
+ }
+
+ switch (ttype)
+ {
+ case SCALAR:
+ assert (tcomponent>=0 && tcomponent<1);
+ break;
+ case VECTOR:
+ assert (tcomponent>=0 && tcomponent<3);
+ break;
+ case TENSOR:
+ assert (tcomponent>=0 && tcomponent<6);
+ break;
+ default:
+ assert (0);
+ }
+
+
+
+ /* Reflection symmetry information */
+ do_reflection[0] = reflection_x;
+ do_reflection[1] = reflection_upper_x;
+ do_reflection[2] = reflection_y;
+ do_reflection[3] = reflection_upper_y;
+ do_reflection[4] = reflection_z;
+ do_reflection[5] = reflection_upper_z;
+
+ do_stagger[0] = avoid_origin_x;
+ do_stagger[1] = avoid_origin_upper_x;
+ do_stagger[2] = avoid_origin_y;
+ do_stagger[3] = avoid_origin_upper_y;
+ do_stagger[4] = avoid_origin_z;
+ do_stagger[5] = avoid_origin_upper_z;
+
+
+
+ /* Loop over all directions and faces */
+ for (dir=0; dir<3; ++dir)
+ {
+ for (face=0; face<2; ++face)
+ {
+ /* If there is a reflection symmetry on that face */
+ if (do_reflection[2*dir+face])
+ {
+ /* If we have the outer boundary of that face */
+ if (cctkGH->cctk_bbox[2*dir+face])
+ {
+
+ /* Find parity */
+ switch (ttype)
+ {
+ case SCALAR:
+ parity = +1;
+ break;
+ case VECTOR:
+ parity = dir == tcomponent ? -1 : +1;
+ break;
+ case TENSOR:
+ switch (tcomponent)
+ {
+ case 0: parity = +1; break;
+ case 1: parity = (dir == 0 || dir == 1) ? -1 : +1; break;
+ case 2: parity = (dir == 0 || dir == 2) ? -1 : +1; break;
+ case 3: parity = +1; break;
+ case 4: parity = (dir == 1 || dir == 2) ? -1 : +1; break;
+ case 5: parity = +1; break;
+ default: assert (0);
+ }
+ break;
+ default:
+ assert (0);
+ }
+
+ /* Find region extent */
+ for (d=0; d<3; ++d)
+ {
+ lsh[d] = cctkGH->cctk_lsh[d];
+ imin[d] = 0;
+ imax[d] = cctkGH->cctk_lsh[d];
+ ioff[d] = 0;
+ }
+ if (face == 0)
+ {
+ imax[d] = cctkGH->cctk_nghostzones[d];
+ ioff[d] = (+ cctkGH->cctk_nghostzones[d]
+ + (do_stagger[2*d+face] ? 0 : 1));
+ }
+ else
+ {
+ imin[d] = cctkGH->cctk_lsh[d] - cctkGH->cctk_nghostzones[d];
+ ioff[d] = (- cctkGH->cctk_nghostzones[d]
+ - (do_stagger[2*d+face] ? 0 : 1));
+ }
+
+ /* Copy region */
+ switch (group.vartype)
+ {
+
+#ifdef CCTK_INT1
+ case CCTK_VARIABLE_INT1:
+#ifdef CCTK_INTER_PRECISION_1
+ case CCTK_VARIABLE_INT:
+#endif
+ copy_CCTK_INT1 (varptr, varptr,
+ lsh[0], lsh[1], lsh[2],
+ imin[0], imin[1], imin[2],
+ imax[0], imax[1], imax[2],
+ ioff[0], ioff[1], ioff[2],
+ idir[0], idir[1], idir[2],
+ parity);
+ break;
+#endif
+
+#ifdef CCTK_INT2
+ case CCTK_VARIABLE_INT2:
+#ifdef CCTK_INTER_PRECISION_2
+ case CCTK_VARIABLE_INT:
+#endif
+ copy_CCTK_INT2 (varptr, varptr,
+ lsh[0], lsh[1], lsh[2],
+ imin[0], imin[1], imin[2],
+ imax[0], imax[1], imax[2],
+ ioff[0], ioff[1], ioff[2],
+ idir[0], idir[1], idir[2],
+ parity);
+ break;
+#endif
+
+#ifdef CCTK_INT4
+ case CCTK_VARIABLE_INT4:
+#ifdef CCTK_INTER_PRECISION_4
+ case CCTK_VARIABLE_INT:
+#endif
+ copy_CCTK_INT4 (varptr, varptr,
+ lsh[0], lsh[1], lsh[2],
+ imin[0], imin[1], imin[2],
+ imax[0], imax[1], imax[2],
+ ioff[0], ioff[1], ioff[2],
+ idir[0], idir[1], idir[2],
+ parity);
+ break;
+#endif
+
+#ifdef CCTK_INT8
+ case CCTK_VARIABLE_INT8:
+#ifdef CCTK_INTER_PRECISION_8
+ case CCTK_VARIABLE_INT:
+#endif
+ copy_CCTK_INT8 (varptr, varptr,
+ lsh[0], lsh[1], lsh[2],
+ imin[0], imin[1], imin[2],
+ imax[0], imax[1], imax[2],
+ ioff[0], ioff[1], ioff[2],
+ idir[0], idir[1], idir[2],
+ parity);
+ break;
+#endif
+
+#ifdef CCTK_REAL4
+ case CCTK_VARIABLE_REAL4:
+#ifdef CCTK_REAL_PRECISION_4
+ case CCTK_VARIABLE_REAL:
+#endif
+ copy_CCTK_REAL4 (varptr, varptr,
+ lsh[0], lsh[1], lsh[2],
+ imin[0], imin[1], imin[2],
+ imax[0], imax[1], imax[2],
+ ioff[0], ioff[1], ioff[2],
+ idir[0], idir[1], idir[2],
+ parity);
+ break;
+#endif
+
+#ifdef CCTK_REAL8
+ case CCTK_VARIABLE_REAL8:
+#ifdef CCTK_REAL_PRECISION_8
+ case CCTK_VARIABLE_REAL:
+#endif
+ copy_CCTK_REAL8 (varptr, varptr,
+ lsh[0], lsh[1], lsh[2],
+ imin[0], imin[1], imin[2],
+ imax[0], imax[1], imax[2],
+ ioff[0], ioff[1], ioff[2],
+ idir[0], idir[1], idir[2],
+ parity);
+ break;
+#endif
+
+#ifdef CCTK_REAL16
+ case CCTK_VARIABLE_REAL16:
+#ifdef CCTK_REAL_PRECISION_16
+ case CCTK_VARIABLE_REAL:
+#endif
+ copy_CCTK_REAL16 (varptr, varptr,
+ lsh[0], lsh[1], lsh[2],
+ imin[0], imin[1], imin[2],
+ imax[0], imax[1], imax[2],
+ ioff[0], ioff[1], ioff[2],
+ idir[0], idir[1], idir[2],
+ parity);
+ break;
+#endif
+
+#ifdef CCTK_REAL4
+ case CCTK_VARIABLE_COMPLEX8:
+#ifdef CCTK_COMPLEX_PRECISION_8
+ case CCTK_VARIABLE_COMPLEX:
+#endif
+ copy_CCTK_COMPLEX8 (varptr, varptr,
+ lsh[0], lsh[1], lsh[2],
+ imin[0], imin[1], imin[2],
+ imax[0], imax[1], imax[2],
+ ioff[0], ioff[1], ioff[2],
+ idir[0], idir[1], idir[2],
+ parity);
+ break;
+#endif
+
+#ifdef CCTK_REAL8
+ case CCTK_VARIABLE_COMPLEX16:
+#ifdef CCTK_COMPLEX_PRECISION_16
+ case CCTK_VARIABLE_COMPLEX:
+#endif
+ copy_CCTK_COMPLEX16 (varptr, varptr,
+ lsh[0], lsh[1], lsh[2],
+ imin[0], imin[1], imin[2],
+ imax[0], imax[1], imax[2],
+ ioff[0], ioff[1], ioff[2],
+ idir[0], idir[1], idir[2],
+ parity);
+ break;
+#endif
+
+#ifdef CCTK_REAL16
+ case CCTK_VARIABLE_COMPLEX32:
+#ifdef CCTK_COMPLEX_PRECISION_32
+ case CCTK_VARIABLE_COMPLEX:
+#endif
+ copy_CCTK_COMPLEX32 (varptr, varptr,
+ lsh[0], lsh[1], lsh[2],
+ imin[0], imin[1], imin[2],
+ imax[0], imax[1], imax[2],
+ ioff[0], ioff[1], ioff[2],
+ idir[0], idir[1], idir[2],
+ parity);
+ break;
+#endif
+
+ default:
+ CCTK_WARN (0, "Unsupported variable type");
+ }
+
+ } /* if cctk_bbox */
+ } /* if do_reflection */
+ } /* for face */
+ } /* for dir */
+
+ /* Success */
+ return 0;
+}
+
+
+
+void
+ReflectionSymmetry_Apply (CCTK_ARGUMENTS)
+{
+ DECLARE_CCTK_ARGUMENTS;
+
+ int nvars;
+ CCTK_INT * restrict indices;
+ CCTK_INT * restrict faces;
+ CCTK_INT * restrict widths;
+ CCTK_INT * restrict tables;
+ int vi;
+ int dim;
+ int * restrict stencil;
+ int i;
+ int istat;
+ int ierr;
+
+ if (! cctkGH)
+ {
+ CCTK_WARN (0, "Argument cctkGH is NULL");
+ }
+
+ nvars = Boundary_SelectedGVs (cctkGH, 0, NULL, NULL, NULL, NULL, NULL);
+ if (nvars < 0)
+ {
+ CCTK_WARN (0, "Internal error in Boundary_SelectedGVs");
+ }
+
+ indices = malloc (nvars * sizeof *indices);
+ if (! indices)
+ {
+ CCTK_WARN (0, "Out of memory");
+ }
+ faces = malloc (nvars * sizeof *faces);
+ if (! faces)
+ {
+ CCTK_WARN (0, "Out of memory");
+ }
+ widths = malloc (nvars * sizeof *widths);
+ if (! widths)
+ {
+ CCTK_WARN (0, "Out of memory");
+ }
+ tables = malloc (nvars * sizeof *tables);
+ if (! tables)
+ {
+ CCTK_WARN (0, "Out of memory");
+ }
+
+ istat = Boundary_SelectedGVs
+ (cctkGH, nvars, indices, faces, widths, tables, 0);
+ if (istat != nvars)
+ {
+ CCTK_WARN (0, "Internal error in Boundary_SelectedGVs");
+ }
+
+ for (i=0; i<nvars; ++i)
+ {
+ vi = indices[i];
+ if (vi < 0 || vi >= CCTK_NumVars())
+ {
+ CCTK_WARN (0, "Illegal variable index");
+ }
+
+ if (widths[i] < 0)
+ {
+ CCTK_WARN (0, "Illegal boundary width");
+ }
+
+ dim = CCTK_GroupDimFromVarI (vi);
+ if (dim < 0)
+ {
+ CCTK_WARN (0, "Illegal dimension");
+ }
+
+ stencil = malloc (dim * sizeof *stencil);
+ if (! stencil)
+ {
+ CCTK_WARN (0, "Out of memory");
+ }
+ ierr = CCTK_GroupnghostzonesVI (cctkGH, dim, stencil, vi);
+ if (ierr)
+ {
+ CCTK_WARN (0, "Internal error in CCTK_GroupnghostzonesVI");
+ }
+
+ ierr = BndReflectVI (cctkGH, stencil, vi);
+ if (ierr)
+ {
+ CCTK_WARN (0, "Internal error in BndReflectVI");
+ }
+
+ free (stencil);
+ }
+
+ free (indices);
+ free (faces);
+ free (widths);
+ free (tables);
+}