aboutsummaryrefslogtreecommitdiff
path: root/src/bc_noise.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/bc_noise.c')
-rw-r--r--src/bc_noise.c270
1 files changed, 270 insertions, 0 deletions
diff --git a/src/bc_noise.c b/src/bc_noise.c
new file mode 100644
index 0000000..0336cd8
--- /dev/null
+++ b/src/bc_noise.c
@@ -0,0 +1,270 @@
+
+#include "noise.h"
+
+#include "cctk_Parameters.h"
+#include "cctk_Arguments.h"
+#include "cctk_FortranString.h"
+
+#include "Symmetry.h"
+
+
+
+static int ApplyBndNoise (const cGH *GH,
+ int stencil_dir,
+ const int *stencil_alldirs,
+ int dir,
+ int first_var,
+ int num_vars);
+
+int
+BndNoiseGI (const cGH *GH, const int *stencil, int gi)
+{
+ int first_vi, retval;
+
+ first_vi = CCTK_FirstVarIndexI (gi);
+ if (first_vi >= 0)
+ {
+ retval = ApplyBndNoise (GH, -1, stencil, 0, first_vi,
+ CCTK_NumVarsInGroupI (gi));
+ }
+ else
+ {
+ CCTK_VWarn (2, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "Invalid group index %d in BndNoiseGI", gi);
+ retval = -1;
+ }
+
+ return (retval);
+}
+
+void
+CCTK_FCALL CCTK_FNAME (BndNoiseGI) (int *ierr, const cGH *GH,
+ const int *stencil, const int *gi)
+{
+ *ierr = BndNoiseGI (GH, stencil, *gi);
+}
+
+
+int
+BndNoiseGN (const cGH *GH, const int *stencil, const char *gn)
+{
+ int gi, retval;
+
+ gi = CCTK_GroupIndex (gn);
+ if (gi >= 0)
+ {
+ retval = BndNoiseGI (GH, stencil, gi);
+ }
+ else
+ {
+ CCTK_VWarn (2, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "Invalid group name '%s' in BndNoiseGN", gn);
+ retval = -1;
+ }
+
+ return (retval);
+}
+
+void CCTK_FCALL CCTK_FNAME (BndNoiseGN)
+ (int *ierr,
+ const cGH *GH,
+ const int *stencil,
+ ONE_FORTSTRING_ARG)
+{
+ ONE_FORTSTRING_CREATE (gn)
+ *ierr = BndNoiseGN (GH, stencil, gn);
+ free (gn);
+}
+
+
+
+
+
+static int ApplyBndNoise (const cGH *GH,
+ int stencil_dir,
+ const int *stencil_alldirs,
+ int dir,
+ int first_var,
+ int num_vars)
+{
+ int i, j, k;
+ int var, vtypesize, gindex, gdim, timelvl;
+ int doBC[2*MAXDIM], dstag[MAXDIM], lsh[MAXDIM], lssh[MAXDIM],
+ stencil[MAXDIM];
+ SymmetryGHex *sGHex;
+ CCTK_REAL amplitude;
+ CCTK_REAL offset;
+ int type;
+
+ stencil[0] = 1; stencil[1] = 1; stencil[2] = 1;
+
+ /* get the group index of the variables */
+ gindex = CCTK_GroupIndexFromVarI (first_var);
+
+ amplitude = *((CCTK_REAL*) CCTK_ParameterGet("amplitude", "Noise", &type))
+ / RAND_MAX;
+ offset = 0.5 * amplitude;
+
+ /* get the number of dimensions and the size of the variables' type */
+ gdim = CCTK_GroupDimI (gindex);
+ vtypesize = CCTK_VarTypeSize (CCTK_VarTypeI (first_var));
+
+ /* make sure we can deal with this number of dimensions */
+ if (gdim > MAXDIM)
+ {
+ CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "ApplyBndNoise: Variable dimension of %d not supported", gdim);
+ return (-1);
+ }
+
+ /* check the direction parameter */
+ if (abs (dir) > gdim)
+ {
+ CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "ApplyBndNoise: direction %d greater than dimension %d",
+ dir, gdim);
+ return (-2);
+ }
+
+ /* initialize arrays for variables with less dimensions than MAXDIM
+ so that we can use the INDEX_3D macro later on */
+ for (i = gdim; i < MAXDIM; i++)
+ {
+ lsh[i] = 0;
+ lssh[i] = 1;
+ }
+
+ /* get the directional staggering of the group */
+ CCTK_GroupStaggerDirArrayGI (dstag, gdim, gindex);
+
+ /* get the current timelevel */
+ timelvl = 0;
+
+ /* see if we have a symmetry array */
+ sGHex = (SymmetryGHex *) CCTK_GHExtension (GH, "Symmetry");
+
+
+ /* now loop over all variables */
+ for (var = first_var; var < first_var + num_vars; var++)
+ {
+ /* Apply condition if:
+ + boundary is not a symmetry boundary (no symmetry or unset(=unsed))
+ + boundary is a physical boundary
+ + have enough grid points
+ */
+ memset (doBC, 1, sizeof (doBC));
+ if (sGHex)
+ {
+ for (i = 0; i < 2 * gdim; i++)
+ {
+ doBC[i] = sGHex->GFSym[var][i] == GFSYM_NOSYM ||
+ sGHex->GFSym[var][i] == GFSYM_UNSET;
+ }
+ }
+ for (i = 0; i < gdim; i++)
+ {
+ lsh[i] = GH->cctk_lsh[i];
+ lssh[i] = GH->cctk_lssh[CCTK_LSSH_IDX (dstag[i], i)];
+ doBC[i*2] &= GH->cctk_lsh[i] > 1 && GH->cctk_bbox[i*2];
+ doBC[i*2+1] &= GH->cctk_lsh[i] > 1 && GH->cctk_bbox[i*2+1];
+ if (dir != 0)
+ {
+ doBC[i*2] &= (dir < 0 && (i + 1 == abs (dir)));
+ doBC[i*2+1] &= (dir > 0 && (i + 1 == abs (dir)));
+ }
+ }
+
+ /* now apply the boundaries face by face */
+ if (gdim > 0)
+ {
+#ifdef DEBUG_BOUNDARY
+ if (doBC[0])
+ {
+ printf("Boundary: Applying lower x noise to boundary\n");
+ }
+ if (doBC[1])
+ {
+ printf("Boundary: Applying upper x noise to boundary\n");
+ }
+#endif /* DEBUG_BOUNDARY */
+ /* lower x */
+ NOISY_BOUNDARY (doBC[0], stencil[0], lssh[1], lssh[2],
+ i, j, k, rand);
+ /* upper x */
+ NOISY_BOUNDARY (doBC[1], stencil[0], lssh[1], lssh[2],
+ lssh[0]-i-1, j, k, rand);
+
+ }
+ if (gdim > 1)
+
+ {
+#ifdef DEBUG_BOUNDARY
+ if (doBC[2])
+ {
+ printf("Boundary: Applying lower y noise to boundary\n");
+ }
+ if (doBC[3])
+ {
+ printf("Boundary: Applying upper y noise to boundary\n");
+ }
+#endif /* DEBUG_BOUNDARY */
+ /* lower y */
+ NOISY_BOUNDARY (doBC[2], lssh[0], stencil[1], lssh[2],
+ i, j, k, rand);
+ /* upper y */
+ NOISY_BOUNDARY (doBC[3], lssh[0], stencil[1], lssh[2],
+ i, lssh[1]-j-1, k, rand);
+ }
+ if (gdim > 2)
+ {
+#ifdef DEBUG_BOUNDARY
+ if (doBC[4])
+ {
+ printf("Boundary: Applying lower z noise to boundary\n");
+ }
+ if (doBC[5])
+ {
+ printf("Boundary: Applying upper z noise to boundary\n");
+ }
+#endif /* DEBUG_BOUNDARY */
+ /* lower z */
+ NOISY_BOUNDARY (doBC[4], lssh[0], lssh[1], stencil[2],
+ i, j, k, rand);
+ /* upper z */
+ NOISY_BOUNDARY (doBC[5], lssh[0], lssh[1], stencil[2],
+ i, j, lssh[2]-k-1, rand);
+ }
+ }
+
+ return(0);
+}
+
+
+void
+add_bc_noise_to_group (int idx, const char* optstring, void* cctkGH)
+{
+ int i, j, k, ijk;
+ CCTK_REAL* data;
+ cGH* GH = cctkGH;
+ int sw[3];
+
+ sw[0] = 1;
+ sw[1] = 1;
+ sw[2] = 1;
+
+ BndNoiseGI(GH, sw, idx);
+}
+
+
+void
+bc_noise(CCTK_ARGUMENTS)
+{
+ DECLARE_CCTK_ARGUMENTS
+ DECLARE_CCTK_PARAMETERS
+
+ if (CCTK_TraverseString(noisy_bc_vars, add_bc_noise_to_group, cctkGH,
+ CCTK_GROUP_OR_VAR) < 0)
+ {
+ CCTK_WARN (1, "Failed to parse 'Noise::noisy_bc_vars' parameter");
+ }
+}