aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnton Khirnov <anton@khirnov.net>2016-02-26 17:15:35 +0100
committerAnton Khirnov <anton@khirnov.net>2016-02-26 17:15:35 +0100
commit140eaa74a9e30828636c5bedafbda6723db758de (patch)
treecedbd99a86b502626dbf50e279c98cbb3aa8d468
parent3a99f1362b3168a120a0ed5f37fceb2b036c3116 (diff)
Largely rewrite to work with mesh refinement.HEADmaster
As the actual work is now mostly done in the evolution code, this really only handles the symmetry condition on the x-axis.
-rw-r--r--interface.ccl10
-rw-r--r--schedule.ccl14
-rw-r--r--src/ApplyCartoon.c247
-rw-r--r--src/Cartoon2D.h2
-rw-r--r--src/Cartoon2DBC.c672
-rw-r--r--src/RegisterSym.c10
-rw-r--r--src/SetGrid.c28
-rw-r--r--src/interpolate.c454
8 files changed, 435 insertions, 1002 deletions
diff --git a/interface.ccl b/interface.ccl
index f1df4ec..da70202 100644
--- a/interface.ccl
+++ b/interface.ccl
@@ -2,6 +2,7 @@
# $Header$
implements: cartoon2d
+inherits: grid
INCLUDES HEADER: Cartoon2D_tensors.h in Cartoon2D_tensors.h
INCLUDES HEADER: Cartoon2D.h in Cartoon2D.h
@@ -81,6 +82,15 @@ REQUIRES FUNCTION Boundary_SelectedGVs
private:
+CCTK_REAL coord type=GF
+{
+ rho
+ zero
+ rxx, ryy, rxy, ryx
+ sxx, syy, sxy, syx
+}
+
+
int excision_variables type=SCALAR
{
excision_active
diff --git a/schedule.ccl b/schedule.ccl
index 0ca570f..47a06eb 100644
--- a/schedule.ccl
+++ b/schedule.ccl
@@ -5,6 +5,20 @@ if (cartoon_active)
{
STORAGE: excision_variables
+ STORAGE: coord
+
+ schedule Cartoon2D_setup_coord at CCTK_POSTREGRID {
+ LANG: C
+ } ""
+
+ schedule Cartoon2D_setup_coord at CCTK_POSTREGRIDINITIAL {
+ LANG: C
+ } ""
+
+ schedule Cartoon2D_setup_coord at CCTK_BASEGRID {
+ LANG: C
+ } ""
+
schedule Cartoon2D_CheckTensorTypes at CCTK_PARAMCHECK
{
LANG: C
diff --git a/src/ApplyCartoon.c b/src/ApplyCartoon.c
index b97c289..e5f3bc0 100644
--- a/src/ApplyCartoon.c
+++ b/src/ApplyCartoon.c
@@ -84,189 +84,86 @@ void Cartoon_ApplyBoundaries(CCTK_ARGUMENTS);
void Cartoon_ApplyBoundaries(CCTK_ARGUMENTS)
{
+ DECLARE_CCTK_ARGUMENTS;
+ DECLARE_CCTK_PARAMETERS;
- DECLARE_CCTK_ARGUMENTS;
- DECLARE_CCTK_PARAMETERS;
+ int num_vars, err, i;
+ CCTK_INT * vars;
- int num_vars, err, i, gi, group_tags_table;
- CCTK_INT * vars;
- char tensortype[TENSORTYPE_BUFF_SIZE];
- char prolongtype[PROLONG_BUFF_SIZE];
- int prolongmethod = -1;
+ //return;
- int whiskycartoon, len;
+ /* Allocate memory to hold selected bcs */
+ num_vars = Boundary_SelectedGVs(cctkGH, 0, NULL, NULL, NULL, NULL, NULL);
+ vars = malloc(num_vars*sizeof *vars);
-
-
-
- /* Check grid size */
- if(cctk_gsh[1] != 2*cctk_nghostzones[1]+1)
- {
- CCTK_WARN(0, "Grid size in y direction inappropriate.");
- }
-
- /* Allocate memory to hold selected bcs */
- num_vars = Boundary_SelectedGVs(cctkGH, 0, NULL, NULL, NULL, NULL, NULL);
-#ifdef DEBUG
- printf("Cartoon_ApplyBoundaries: num_vars is %d\n",num_vars);
-#endif
- vars = malloc(num_vars*sizeof *vars);
-
- /* get all selected vars */
- err = Boundary_SelectedGVs(cctkGH, num_vars, vars, NULL, NULL, NULL, NULL);
- if (err != num_vars)
- {
- CCTK_VWarn(1, __LINE__, __FILE__, CCTK_THORNSTRING,
- "Boundary_SelectedGVs returned %d selected variables, but %d "
- "expected", err, num_vars);
+ /* get all selected vars */
+ err = Boundary_SelectedGVs(cctkGH, num_vars, vars, NULL, NULL, NULL, NULL);
+ if (err != num_vars) {
+ CCTK_VWarn(1, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "Boundary_SelectedGVs returned %d selected variables, but %d "
+ "expected", err, num_vars);
}
- /* Apply CartoonBC to each of them. */
- /* One should probably check to see that the entire group has been
- * selected, since Cartoon operates on an entire group at a time.
- * For now I'll just skip a variable if it is not a 'group leader'.
- */
- for (i=0; i<num_vars; ++i) {
-#ifdef DEBUG
- printf("Cartoon_ApplyBoundaries: i=%d applying cartoon to vi %d\n",i,
- vars[i]);
-#endif
- gi = CCTK_GroupIndexFromVarI(vars[i]);
- if (gi<0) {
- CCTK_VWarn(1, __LINE__, __FILE__, CCTK_THORNSTRING,
- "Invalid variable index %d selected for a boundary "
- "condition", gi);
- }
- if (vars[i] != CCTK_FirstVarIndexI(gi))
- {
- /* not a group leader -- skip to next var index */
- continue;
- }
-
- /* Here one should check that the entire group is registered,
- * using CCTK_NumVarsInGroupI.
+ /* Apply CartoonBC to each of them. */
+ /* One should probably check to see that the entire group has been
+ * selected, since Cartoon operates on an entire group at a time.
+ * For now I'll just skip a variable if it is not a 'group leader'.
*/
+ for (i = 0; i < num_vars; i++) {
+ char tensortype[TENSORTYPE_BUFF_SIZE];
+ char prolongtype[PROLONG_BUFF_SIZE];
+ int group_tags_table, ret;
- /* Get table handle for group tags table */
- group_tags_table = CCTK_GroupTagsTableI(gi);
- if (group_tags_table<0) {
- CCTK_VWarn(1, __LINE__, __FILE__, CCTK_THORNSTRING,
- "Tags table for variable group %s is %d", CCTK_GroupName(gi),
- group_tags_table);
- }
-
-
- /* This lines are writen for Whisky2D to avoid to treat the hydrovariables with Cartoon */
-
- len = Util_TableGetString(group_tags_table,0,NULL,"whiskycartoon");
-
- whiskycartoon = 1; /* default is yes */
- if (len >= 0)
- {
- char* value = malloc (len + 1);
- Util_TableGetString (group_tags_table, len + 1, value, "whiskycartoon");
- if (CCTK_Equals(value, "yes"))
- {
- whiskycartoon = 1;
- }
- else if (CCTK_Equals(value, "no"))
- {
- whiskycartoon = 0;
- }
- else
- {
+ int gi = CCTK_GroupIndexFromVarI(vars[i]);
+ if (gi < 0) {
CCTK_VWarn(1, __LINE__, __FILE__, CCTK_THORNSTRING,
- "Tags table entry \"whiskycartoon\" for variable group %s should be either \"yes\" or \"no\", but is \"%s\"",
- CCTK_GroupName(gi), value);
- }
- free (value);
- }
-
- if (whiskycartoon)
- {
-
- /*###################################################################*/
-
-
- /* Get tensor type from group tags table */
- err = Util_TableGetString(group_tags_table, TENSORTYPE_BUFF_SIZE,
- tensortype, "tensortypealias");
- if (err<0)
- {
- CCTK_VWarn(1, __LINE__, __FILE__, CCTK_THORNSTRING,
- "Error in TAGS table for variable group %s",
- CCTK_GroupName(gi));
- }
-#ifdef DEBUG
- printf("Cartoon_ApplyBoundaries: tensor type is %s\n",tensortype);
-#endif
-
- /* Get prolongation type from group tags table */
-
- err = Util_TableGetString(group_tags_table, PROLONG_BUFF_SIZE,
- prolongtype, "Prolongation");
-
- if (err == UTIL_ERROR_TABLE_NO_SUCH_KEY)
- {
- /* Use the default */
-
- prolongmethod = PROLONG_LAGRANGE;
- }
- else if (err < 0)
- {
- CCTK_VWarn(0, __LINE__, __FILE__, CCTK_THORNSTRING,
- "Error (%d) in TAGS table for variable group %s", err,
- CCTK_GroupName(gi));
- }
- else
- {
- if (CCTK_Equals(prolongtype, "None"))
- {
- prolongmethod = PROLONG_NONE; /* But why? */
- }
- else if (CCTK_Equals(prolongtype, "Lagrange"))
- {
- prolongmethod = PROLONG_LAGRANGE;
- }
- else if (CCTK_Equals(prolongtype, "TVD"))
- {
- prolongmethod = PROLONG_ENO;
- }
- else if (CCTK_Equals(prolongtype, "ENO"))
- {
- prolongmethod = PROLONG_ENO;
- }
- else
- {
- CCTK_VWarn(0, __LINE__, __FILE__, CCTK_THORNSTRING,
- "Error in TAGS table for variable group %s",
- CCTK_GroupName(gi));
- }
- }
-
- /* Here one should check that the group's size is correct for the
- * specified tensortype.
- */
+ "Invalid variable index %d selected for a boundary "
+ "condition", gi);
+ }
+ if (vars[i] != CCTK_FirstVarIndexI(gi)) {
+ /* not a group leader -- skip to next var index */
+ continue;
+ }
+
+ /* Get table handle for group tags table */
+ group_tags_table = CCTK_GroupTagsTableI(gi);
+ if (group_tags_table < 0) {
+ CCTK_VWarn(1, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "Tags table for variable group %s is %d", CCTK_GroupName(gi),
+ group_tags_table);
+ }
+
+ /* Get tensor type from group tags table */
+ ret = Util_TableGetString(group_tags_table, TENSORTYPE_BUFF_SIZE,
+ tensortype, "tensortypealias");
+ if (ret < 0) {
+ CCTK_VWarn(1, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "Error in TAGS table for variable group %s",
+ CCTK_GroupName(gi));
+ }
+
+ /* Get prolongation type from group tags table */
+ ret = Util_TableGetString(group_tags_table, PROLONG_BUFF_SIZE,
+ prolongtype, "Prolongation");
+
+ if (!(ret == UTIL_ERROR_TABLE_NO_SUCH_KEY ||
+ (ret >= 0 && CCTK_Equals(prolongtype, "Lagrange"))))
+ continue;
+
+ /* Call BndCartoon2DVI, passing the appropriate tensor type integer
+ macro */
+ if (CCTK_Equals(tensortype, "scalar")) {
+ BndCartoon2DVI(cctkGH, TENSORTYPE_SCALAR, vars[i]);
+ } else if ((CCTK_Equals(tensortype, "u")) || (CCTK_Equals(tensortype, "d"))) {
+ BndCartoon2DVI(cctkGH, TENSORTYPE_U, vars[i]);
+ } else if (CCTK_Equals(tensortype, "dd_sym")) {
+ BndCartoon2DVI(cctkGH, TENSORTYPE_DDSYM, vars[i]);
+ } else {
+ CCTK_VWarn(0, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "invalid tensor type for group %s", CCTK_GroupName(gi));
+ }
+ }
- /* Call BndCartoon2DVI, passing the appropriate tensor type integer
- macro */
- if (CCTK_Equals(tensortype, "scalar"))
- {
- BndCartoon2DVI(cctkGH, TENSORTYPE_SCALAR, prolongmethod, vars[i]);
- } else if ((CCTK_Equals(tensortype, "u")) ||
- (CCTK_Equals(tensortype, "d")))
- {
- BndCartoon2DVI(cctkGH, TENSORTYPE_U, prolongmethod, vars[i]);
- } else if (CCTK_Equals(tensortype, "dd_sym"))
- {
- BndCartoon2DVI(cctkGH, TENSORTYPE_DDSYM, prolongmethod, vars[i]);
- } else
- {
- CCTK_VWarn(0, __LINE__, __FILE__, CCTK_THORNSTRING,
- "invalid tensor type for group %s", CCTK_GroupName(gi));
- }
- }
- }
- /* Free data */
- free(vars);
+ /* Free data */
+ free(vars);
}
diff --git a/src/Cartoon2D.h b/src/Cartoon2D.h
index b4fadc3..d371729 100644
--- a/src/Cartoon2D.h
+++ b/src/Cartoon2D.h
@@ -7,7 +7,7 @@
extern "C" {
#endif
-int BndCartoon2DVI(const cGH *GH, int tensortype, int prolongtype, int vi);
+int BndCartoon2DVI(const cGH *cctkGH, int tensortype, int vi);
CCTK_INT
Cartoon2D_SymmetryInterpolate (CCTK_POINTER_TO_CONST const cctkGH_,
diff --git a/src/Cartoon2DBC.c b/src/Cartoon2DBC.c
index 2dbca7f..40b3503 100644
--- a/src/Cartoon2DBC.c
+++ b/src/Cartoon2DBC.c
@@ -32,18 +32,9 @@ CCTK_FILEVERSION(BetaThorns_Cartoon2D_Cartoon2DBC_c);
int BndCartoon2DGN(const cGH *GH, int tensortype, const char *group);
int BndCartoon2DVN(const cGH *GH, int tensortype, const char *var);
-int BndCartoon2DVI(const cGH *GH, int tensortype, int prolongtype, int vi);
-static CCTK_REAL Cartoon2DInterp(const cGH *GH, CCTK_REAL *f, int i, int di,
- int ijk, CCTK_REAL x);
-static CCTK_REAL Cartoon2DInterp_ENO(const cGH *cctkGH,
- CCTK_REAL *f, int i, int di,
- int ijk, CCTK_REAL x);
+int BndCartoon2DVI(const cGH *GH, int tensortype, int vi);
CCTK_REAL interpolate_local(int order, CCTK_REAL x0, CCTK_REAL dx,
- CCTK_REAL y[], CCTK_REAL x,
- CCTK_INT excised_points[]);
-CCTK_REAL interpolate_eno(CCTK_INT order, CCTK_REAL x0, CCTK_REAL dx,
- CCTK_REAL y[], CCTK_REAL x,
- CCTK_INT excised_points[]);
+ CCTK_REAL y[], CCTK_REAL x);
void CCTK_FCALL CCTK_FNAME(BndCartoon2DVI)(int *retval, const cGH **GH,
int *tensortype, int *vi);
void CCTK_FCALL CCTK_FNAME(BndCartoon2DVN)(int *retval, const cGH **GH,
@@ -55,6 +46,46 @@ void CCTK_FCALL CCTK_FNAME(BndCartoon2DGN)
void Cartoon2D_InitExcisionVars(CCTK_ARGUMENTS);
void SetupExcisionVars(CCTK_ARGUMENTS);
+/* interpolation on x-axis */
+static CCTK_REAL cartoon2d_interp(const cGH *cctkGH, int order, CCTK_REAL *f,
+ int i, int ijk, CCTK_REAL x_val)
+{
+ CCTK_REAL x0;
+ CCTK_REAL lx0, dx0;
+ int lnx;
+ int n, offset;
+
+ lnx = cctkGH->cctk_lsh[0];
+
+ dx0 = cctkGH->cctk_delta_space[0] / cctkGH->cctk_levfac[0];
+ lx0 = cctkGH->cctk_origin_space[0] + cctkGH->cctk_delta_space[0] / cctkGH->cctk_levfac[0] * cctkGH->cctk_levoff[0] / cctkGH->cctk_levoffdenom[0] + dx0 * cctkGH->cctk_lbnd[0];
+
+
+ /* find i such that x(i) < x <= x(i+1)
+ for rotation on entry always x > x(i), but sometimes also x > x(i+1) */
+ while (x_val > lx0 + dx0 * (i+1)) {i++; ijk++;}
+
+ /* offset of stencil, note that rotation leads to x close to x0
+ for large x */
+ offset = order/2;
+
+ /* shift stencil at boundaries */
+ /* note that for simplicity we don't distinguish between true boundaries
+ and decomposition boundaries: the sync fixes that! */
+ if (i-offset < 0) offset = i;
+ while (lx0 + dx0 * (i - offset) < 0) offset--;
+
+ if (i-offset+order >= lnx) offset = i+order-lnx+1;
+
+ x0 = lx0 + dx0 * (i-offset);
+ if(x0 < 0)
+ fprintf(stderr, "x0 %g\n", x0);
+
+ /* call interpolator */
+ return interpolate_local(order, x0, dx0, f + ijk - offset, x_val);
+}
+
+
/* set boundaries of a grid tensor assuming axisymmetry
- handles lower boundary in x
- does not touch other boundaries
@@ -75,241 +106,175 @@ void SetupExcisionVars(CCTK_ARGUMENTS);
group, using the tensortype argument to determine how many there
are and how to treat them. */
-int BndCartoon2DVI(const cGH *cctkGH, int tensortype, int prolongtype, int vi)
+int BndCartoon2DVI(const cGH *cctkGH, int tensortype, int vi)
{
- DECLARE_CCTK_ARGUMENTS;
- DECLARE_CCTK_PARAMETERS;
-
- char * groupname;
-
- int i, j, k, di, dj, ijk;
- int jj, n, s;
- int lnx, lnz, ny;
- int gi, var0;
- int n_vars;
- int timelevel;
- CCTK_REAL x, y, rho;
- CCTK_REAL lx0, dx0, dy0;
- CCTK_REAL rxx, rxy, ryx, ryy;
- CCTK_REAL sxx, sxy, syx, syy;
- CCTK_REAL f[100], fx, fy, fz, fxx, fxy, fxz, fyy, fyz, fzz;
- CCTK_REAL *t, *tx, *ty, *tz, *txx, *txy, *txz, *tyy, *tyz, *tzz;
-
- gi = CCTK_GroupIndexFromVarI (vi);
- assert (gi >= 0);
- n_vars = CCTK_NumVarsInGroupI (gi);
- assert (n_vars > 0);
- var0 = CCTK_FirstVarIndexI (gi);
- assert (var0 >= 0);
-
- if (n_vars > 100)
- {
- groupname = CCTK_GroupName (gi);
- CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
- "Group \"%s\" has more than 100 variables -- cannot apply Cartoon boundary condition",
- groupname);
- free (groupname);
- return -1;
- }
-
- switch (tensortype) {
- case TENSORTYPE_SCALAR:
- break;
- case TENSORTYPE_U:
- if (n_vars != 3)
- {
- groupname = CCTK_GroupName (gi);
- CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
- "Group \"%s\" is declared with the tensor type U, but does not contain 3 variables -- cannot apply Cartoon boundary condition",
- groupname);
- free (groupname);
- return -1;
- }
- break;
- case TENSORTYPE_DDSYM:
- if (n_vars != 6)
- {
- groupname = CCTK_GroupName (gi);
- CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
- "Group \"%s\" is declared with the tensor type DDSYM, but does not contain 6 variables -- cannot apply Cartoon boundary condition",
- groupname);
- free (groupname);
- return -1;
+ DECLARE_CCTK_ARGUMENTS;
+ DECLARE_CCTK_PARAMETERS;
+
+ int i, s;
+ int y_idx;
+ int gi, var0;
+ int n_vars;
+ int timelevel;
+
+ gi = CCTK_GroupIndexFromVarI (vi);
+ n_vars = CCTK_NumVarsInGroupI (gi);
+ var0 = CCTK_FirstVarIndexI (gi);
+
+ if (n_vars > 100) {
+ char *groupname = CCTK_GroupName (gi);
+ CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "Group \"%s\" has more than 100 variables -- cannot apply Cartoon boundary condition",
+ groupname);
+ free (groupname);
+ return -1;
}
- break;
- default:
- CCTK_WARN(0,"Tensor type not recognized by Cartoon2D.");
- }
-
- s = cctkGH->cctk_nghostzones[0];
- lnx = cctkGH->cctk_lsh[0];
- lnz = cctkGH->cctk_lsh[2];
- ny = cctkGH->cctk_gsh[1];
-
- dx0 = CCTK_DELTA_SPACE(0);
- dy0 = CCTK_DELTA_SPACE(1);
- lx0 = CCTK_ORIGIN_SPACE(0) + dx0 * cctk_lbnd[0];
-
- timelevel = 0;
-
- /* Cactus loop in C: grid points with y = 0 */
- /* compare thorn_BAM_Elliptic */
- /* strides used in stencils, should be provided by cactus */
- di = 1;
- dj = lnx;
-
- /* y = 0 */
- assert (ny % 2 == 1);
- j = ny/2;
-
- /* make sure that the input data is synced */
- CCTK_SyncGroupI(cctkGH, gi);
-
- /* z-direction: include lower and upper boundary */
- for (k = 0; k < lnz; k++)
-
- /* y-direction: as many zombies as the evolution stencil needs */
-#if 0
- for (jj = 1, dj = jj*lnx; jj <= ny/2; jj++, dj = jj*lnx)
-#else
- for (jj = 0, dj = jj*lnx; jj <= ny/2; jj++, dj = jj*lnx)
-#endif
-
- /* x-direction: zombie for x < 0, including upper boundary for extrapol */
-#if 0
- for (i = -s; i < lnx; i++) {
-#else
- for (i = 0; i < lnx; i++)
- if (! (i >= s && jj == 0)) {
-#endif
-
- /* index into linear memory */
- ijk = CCTK_GFINDEX3D(cctkGH,i,j,k);
-
- /* what a neat way to hack in the zombie for x < 0, y = 0 */
- if (i < 0) {i += s; ijk += s; dj = 0;}
-
- /* compute coordinates (could also use Cactus grid function) */
- x = lx0 + dx0 * i;
-#if 0
- y = (dj) ? dy0 * jj : 0;
-#else
- y = dy0 * jj;
-#endif
- rho = sqrt(x*x + y*y);
-
- /* compute rotation matrix
- note that this also works for x <= 0 (at lower boundary in x)
- note that rho is nonzero by definition if cactus checks dy ...
- */
- rxx = x/rho;
- ryx = y/rho;
- rxy = -ryx;
- ryy = rxx;
-
- /* inverse rotation matrix, assuming detr = 1 */
- sxx = ryy;
- syx = -ryx;
- sxy = -rxy;
- syy = rxx;
-
- /* interpolate grid functions */
- switch (prolongtype)
- {
- case PROLONG_NONE:
- /* no-op */
- return (0);
+
+ switch (tensortype) {
+ case TENSORTYPE_SCALAR:
break;
- case PROLONG_LAGRANGE:
- for (n = 0; n < n_vars; n++)
- f[n] = Cartoon2DInterp(cctkGH, cctkGH->data[var0+n][timelevel],
- i, di, ijk, rho);
+ case TENSORTYPE_U:
+ if (n_vars != 3) {
+ char *groupname = CCTK_GroupName (gi);
+ CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "Group \"%s\" is declared with the tensor type U, but does not contain 3 variables -- cannot apply Cartoon boundary condition",
+ groupname);
+ free (groupname);
+ return -1;
+ }
break;
- case PROLONG_ENO:
- for (n = 0; n < n_vars; n++)
- f[n] = Cartoon2DInterp_ENO(cctkGH, cctkGH->data[var0+n][timelevel], i,
- di, ijk, rho);
+ case TENSORTYPE_DDSYM:
+ if (n_vars != 6) {
+ char *groupname = CCTK_GroupName (gi);
+ CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "Group \"%s\" is declared with the tensor type DDSYM, but does not contain 6 variables -- cannot apply Cartoon boundary condition",
+ groupname);
+ free (groupname);
+ return -1;
+ }
break;
- default:
- CCTK_WARN(0, "Prolongation type not recognized by Cartoon2D.");
- }
-
- /* rotate grid tensor by matrix multiplication */
- if (tensortype == TENSORTYPE_SCALAR) {
- /* Scalar groups can have arbitrary many components; these
- "components" are then all scalars. */
- for (n = 0; n < n_vars; n++)
- {
- t = cctkGH->data[var0 + n][timelevel];
- t[ijk+dj] = f[n];
- t[ijk-dj] = f[n];
- }
- }
- else if (tensortype == TENSORTYPE_U) {
- tx = cctkGH->data[vi][timelevel];
- ty = cctkGH->data[vi+1][timelevel];
- tz = cctkGH->data[vi+2][timelevel];
- fx = f[0];
- fy = f[1];
- fz = f[2];
-
- tx[ijk+dj] = rxx * fx + rxy * fy;
- ty[ijk+dj] = ryx * fx + ryy * fy;
- tz[ijk+dj] = fz;
-
- tx[ijk-dj] = sxx * fx + sxy * fy;
- ty[ijk-dj] = syx * fx + syy * fy;
- tz[ijk-dj] = fz;
- }
- else if (tensortype == TENSORTYPE_DDSYM) {
- txx = cctkGH->data[vi][timelevel];
- txy = cctkGH->data[vi+1][timelevel];
- txz = cctkGH->data[vi+2][timelevel];
- tyy = cctkGH->data[vi+3][timelevel];
- tyz = cctkGH->data[vi+4][timelevel];
- tzz = cctkGH->data[vi+5][timelevel];
- fxx = f[0];
- fxy = f[1];
- fxz = f[2];
- fyy = f[3];
- fyz = f[4];
- fzz = f[5];
-
- txx[ijk+dj] = fxx*sxx*sxx + 2*fxy*sxx*syx + fyy*syx*syx;
- tyy[ijk+dj] = fxx*sxy*sxy + 2*fxy*sxy*syy + fyy*syy*syy;
- txy[ijk+dj] = fxx*sxx*sxy + fxy*(sxy*syx+sxx*syy) + fyy*syx*syy;
- txz[ijk+dj] = fxz*sxx + fyz*syx;
- tyz[ijk+dj] = fxz*sxy + fyz*syy;
- tzz[ijk+dj] = fzz;
-
- txx[ijk-dj] = fxx*rxx*rxx + 2*fxy*rxx*ryx + fyy*ryx*ryx;
- tyy[ijk-dj] = fxx*rxy*rxy + 2*fxy*rxy*ryy + fyy*ryy*ryy;
- txy[ijk-dj] = fxx*rxx*rxy + fxy*(rxy*ryx+rxx*ryy) + fyy*ryx*ryy;
- txz[ijk-dj] = fxz*rxx + fyz*ryx;
- tyz[ijk-dj] = fxz*rxy + fyz*ryy;
- tzz[ijk-dj] = fzz;
- }
- else {
- return(-1);
+ default:
+ CCTK_WARN(0,"Tensor type not recognized by Cartoon2D.");
}
-#if 0
- /* what a neat way to hack out the zombies for x < 0, y = 0 */
- if (dj == 0) {i -= s; ijk -= s; dj = jj*lnx;}
-#endif
- }
+ s = cctkGH->cctk_nghostzones[0];
- /* syncs needed after interpolation (actually only for x direction) */
- CCTK_SyncGroupI(cctkGH, gi);
+ timelevel = 0;
- return(0);
+ /* find the index for which y == 0 */
+ for (i = 0; i < cctkGH->cctk_lsh[1]; i++) {
+ if (fabs(y[CCTK_GFINDEX3D(cctkGH, 0, i, 0)]) < 1e-12) {
+ y_idx = i;
+ break;
+ }
+ }
+ if (i == cctkGH->cctk_lsh[1])
+ CCTK_WARN(0, "y is not 0 anywhere");
+
+ /* make sure that the input data is synced */
+ CCTK_SyncGroupI(cctkGH, gi);
+
+#pragma omp parallel for
+ for (int k = 0; k < cctkGH->cctk_lsh[2]; k++)
+ for (int jj = 0; jj < cctkGH->cctk_lsh[1]; jj++)
+ for (int i = 0; i < cctkGH->cctk_lsh[0]; i++) {
+ CCTK_REAL f[100];
+ CCTK_REAL rho_val;
+ int idx_dst, ijk;
+
+ if (jj != y_idx || i >= s)
+ continue;
+ //if (jj == y_idx && i >= s)
+ // continue;
+
+ /* index into linear memory */
+ ijk = CCTK_GFINDEX3D(cctkGH, i, y_idx, k);
+ idx_dst = CCTK_GFINDEX3D(cctkGH, i, jj, k);
+
+ rho_val = rho[idx_dst];
+
+ /* interpolate grid functions */
+ for (int n = 0; n < n_vars; n++) {
+ f[n] = cartoon2d_interp(cctkGH, order, cctkGH->data[var0+n][timelevel],
+ i, ijk, rho_val);
+ }
+
+ /* rotate grid tensor by matrix multiplication */
+ if (tensortype == TENSORTYPE_SCALAR) {
+ /* Scalar groups can have arbitrary many components; these
+ "components" are then all scalars. */
+ for (int n = 0; n < n_vars; n++) {
+ CCTK_REAL *t = cctkGH->data[var0 + n][timelevel];
+ t[idx_dst] = f[n];
+ }
+ } else if (tensortype == TENSORTYPE_U) {
+ CCTK_REAL *tx = cctkGH->data[vi][timelevel];
+ CCTK_REAL *ty = cctkGH->data[vi+1][timelevel];
+ CCTK_REAL *tz = cctkGH->data[vi+2][timelevel];
+
+ CCTK_REAL rxx_val = rxx[idx_dst];
+ CCTK_REAL ryy_val = ryy[idx_dst];
+ CCTK_REAL rxy_val = rxy[idx_dst];
+ CCTK_REAL ryx_val = ryx[idx_dst];
+
+ CCTK_REAL fx = f[0];
+ CCTK_REAL fy = f[1];
+ CCTK_REAL fz = f[2];
+
+ tx[idx_dst] = rxx_val * fx + rxy_val * fy;
+ ty[idx_dst] = ryx_val * fx + ryy_val * fy;
+ tz[idx_dst] = fz;
+
+ //tx[ijk-dj] = sxx * fx + sxy * fy;
+ //ty[ijk-dj] = syx * fx + syy * fy;
+ //tz[ijk-dj] = fz;
+ } else if (tensortype == TENSORTYPE_DDSYM) {
+ CCTK_REAL *txx = cctkGH->data[vi][timelevel];
+ CCTK_REAL *txy = cctkGH->data[vi+1][timelevel];
+ CCTK_REAL *txz = cctkGH->data[vi+2][timelevel];
+ CCTK_REAL *tyy = cctkGH->data[vi+3][timelevel];
+ CCTK_REAL *tyz = cctkGH->data[vi+4][timelevel];
+ CCTK_REAL *tzz = cctkGH->data[vi+5][timelevel];
+
+ CCTK_REAL sxx_val = sxx[idx_dst];
+ CCTK_REAL syy_val = syy[idx_dst];
+ CCTK_REAL sxy_val = sxy[idx_dst];
+ CCTK_REAL syx_val = syx[idx_dst];
+
+ CCTK_REAL fxx = f[0];
+ CCTK_REAL fxy = f[1];
+ CCTK_REAL fxz = f[2];
+ CCTK_REAL fyy = f[3];
+ CCTK_REAL fyz = f[4];
+ CCTK_REAL fzz = f[5];
+
+ txx[idx_dst] = fxx * sxx_val * sxx_val + 2 * fxy * sxx_val * syx_val + fyy * syx_val * syx_val;
+ tyy[idx_dst] = fxx * sxy_val * sxy_val + 2 * fxy * sxy_val * syy_val + fyy * syy_val * syy_val;
+ txy[idx_dst] = fxx * sxx_val * sxy_val + fxy * (sxy_val * syx_val + sxx_val * syy_val) + fyy * syx_val * syy_val;
+ txz[idx_dst] = fxz * sxx_val + fyz * syx_val;
+ tyz[idx_dst] = fxz * sxy_val + fyz * syy_val;
+ tzz[idx_dst] = fzz;
+
+ //txx[ijk-dj] = fxx*rxx*rxx + 2*fxy*rxx*ryx + fyy*ryx*ryx;
+ //tyy[ijk-dj] = fxx*rxy*rxy + 2*fxy*rxy*ryy + fyy*ryy*ryy;
+ //txy[ijk-dj] = fxx*rxx*rxy + fxy*(rxy*ryx+rxx*ryy) + fyy*ryx*ryy;
+ //txz[ijk-dj] = fxz*rxx + fyz*ryx;
+ //tyz[ijk-dj] = fxz*rxy + fyz*ryy;
+ //tzz[ijk-dj] = fzz;
+ }
+ }
+
+ /* syncs needed after interpolation (actually only for x direction) */
+ CCTK_SyncGroupI(cctkGH, gi);
+
+ return 0;
}
void CCTK_FCALL CCTK_FNAME(BndCartoon2DVI)
(int *retval, const cGH **GH, int *tensortype, int *vi)
{
- *retval = BndCartoon2DVI(*GH, *tensortype, PROLONG_LAGRANGE, *vi);
+ *retval = BndCartoon2DVI(*GH, *tensortype, *vi);
}
int BndCartoon2DVN(const cGH *GH, int tensortype, const char *inpvarname)
@@ -321,7 +286,7 @@ int BndCartoon2DVN(const cGH *GH, int tensortype, const char *inpvarname)
if (verbose) printf("Cartoon2D called for %s\n", inpvarname);
vi = CCTK_VarIndex(inpvarname);
- return(BndCartoon2DVI(GH, tensortype, PROLONG_LAGRANGE, vi));
+ return(BndCartoon2DVI(GH, tensortype, vi));
}
void CCTK_FCALL CCTK_FNAME(BndCartoon2DVN)
@@ -338,8 +303,7 @@ int BndCartoon2DGN(const cGH *GH, int tensortype, const char *group)
if (verbose && GH->cctk_iteration==1) CCTK_VInfo(CCTK_THORNSTRING,"Cartoon2D called for %s (message appears only once)", group);
- return(BndCartoon2DVI(GH, tensortype, PROLONG_LAGRANGE,
- CCTK_FirstVarIndex(group)));
+ return(BndCartoon2DVI(GH, tensortype, CCTK_FirstVarIndex(group)));
}
void CCTK_FCALL CCTK_FNAME(BndCartoon2DGN)
@@ -350,246 +314,6 @@ void CCTK_FCALL CCTK_FNAME(BndCartoon2DGN)
free(group);
}
-/* interpolation on x-axis */
-static CCTK_REAL Cartoon2DInterp(const cGH *cctkGH, CCTK_REAL *f,
- int i, int di, int ijk, CCTK_REAL x)
-{
- DECLARE_CCTK_ARGUMENTS;
- DECLARE_CCTK_PARAMETERS;
-
- CCTK_REAL x0;
- CCTK_REAL lx0, dx0;
- CCTK_REAL y[6], r;
- int lnx;
- int n, offset;
-
- CCTK_REAL *old_mask;
- CCTK_INT *new_mask;
-
- CCTK_INT excised_points[6];
-
- if (*excision_active < 0)
- {
- SetupExcisionVars((cGH*)cctkGH);
- }
-
- if (old_excision)
- {
- old_mask = (CCTK_REAL*)CCTK_VarDataPtrI(cctkGH, 0, *old_mask_vi);
- }
- else
- {
- old_mask = NULL;
- }
-
- if (new_excision)
- {
- new_mask = (CCTK_INT*)CCTK_VarDataPtrI(cctkGH, 0, *new_mask_vi);
- }
- else
- {
- new_mask = NULL;
- }
-
- /*
- If this boundary point is excised then we return
- without doing anything
- */
-
- if (*excision_active)
- {
- if ((*excision_active == 1)||(*excision_active == 3))
- {
- if (old_mask[ijk] < 0.75)
- {
- return f[ijk];
- }
- }
- if ((*excision_active == 2)||(*excision_active == 3))
- {
- if (SpaceMask_CheckStateBits(new_mask, (ijk),
- *new_excision_field,
- *new_excision_descriptor))
- {
- return f[ijk];
- }
- }
- }
-
- lnx = cctkGH->cctk_lsh[0];
-
- dx0 = CCTK_DELTA_SPACE(0);
- lx0 = CCTK_ORIGIN_SPACE(0) + dx0 * cctk_lbnd[0];
-
- /* find i such that x(i) < x <= x(i+1)
- for rotation on entry always x > x(i), but sometimes also x > x(i+1) */
- while (x > lx0 + dx0 * (i+1)) {i++; ijk++;}
-
- /* first attempt to interface to JT's interpolator */
-
- /* offset of stencil, note that rotation leads to x close to x0
- for large x */
- offset = order/2;
-
- /* shift stencil at boundaries */
- /* note that for simplicity we don't distinguish between true boundaries
- and decomposition boundaries: the sync fixes that! */
- if (i-offset < 0) offset = i;
- if (i-offset+order >= lnx) offset = i+order-lnx+1;
-
- /* fill in info */
- /* fills in old data near axis, but as long as stencil at axis is
- centered, no interpolation happens anyway */
- x0 = lx0 + dx0 * (i-offset);
- for (n = 0; n <= order; n++) {
- y[n] = f[ijk-offset+n];
- excised_points[n] = 0;
- if (*excision_active)
- {
- if ((*excision_active == 1)||(*excision_active == 3))
- {
- excised_points[n] = (old_mask[ijk-offset+n] > 0.75) ? 0 : 1;
- }
- if ((*excision_active == 2)||(*excision_active == 3))
- {
- excised_points[n] |=
- (SpaceMask_CheckStateBits(new_mask, (ijk-offset+n),
- *new_excision_field,
- *new_excision_descriptor));
- }
- }
- }
-
- /* call interpolator */
- r = interpolate_local(order, x0, dx0, y, x, excised_points);
-
- return r;
-}
-
-static CCTK_REAL Cartoon2DInterp_ENO(const cGH *cctkGH,
- CCTK_REAL *f, int i, int di,
- int ijk, CCTK_REAL x)
-{
-
- DECLARE_CCTK_PARAMETERS;
- DECLARE_CCTK_ARGUMENTS;
-
- CCTK_REAL x0;
- CCTK_REAL lx0, dx0;
- CCTK_REAL y[11], r;
- int lnx;
- int n, offset;
- /* int tmp_order = 2; */
-
- CCTK_REAL *old_mask;
- CCTK_INT *new_mask;
-
- CCTK_INT excised_points[11];
-
- if (*excision_active < 0)
- {
- SetupExcisionVars((cGH*)cctkGH);
- }
-
- if (old_excision)
- {
- old_mask = (CCTK_REAL*)CCTK_VarDataPtrI(cctkGH, 0, *old_mask_vi);
- }
- else
- {
- old_mask = NULL;
- }
-
- if (new_excision)
- {
- new_mask = (CCTK_INT*)CCTK_VarDataPtrI(cctkGH, 0, *new_mask_vi);
- }
- else
- {
- new_mask = NULL;
- }
-
- /*
- If this boundary point is excised then we return
- without doing anything
- */
-
- if (*excision_active)
- {
- if ((*excision_active == 1)||(*excision_active == 3))
- {
- if (old_mask[ijk] < 0.75)
- {
- return f[ijk];
- }
- }
- if ((*excision_active == 2)||(*excision_active == 3))
- {
- if (SpaceMask_CheckStateBits(new_mask, (ijk),
- *new_excision_field,
- *new_excision_descriptor))
- {
- return f[ijk];
- }
- }
- }
-
- lnx = cctkGH->cctk_lsh[0];
-
- dx0 = CCTK_DELTA_SPACE(0);
- lx0 = CCTK_ORIGIN_SPACE(0) + dx0 * cctk_lbnd[0];
-
- /* find i such that x(i) < x <= x(i+1)
- for rotation on entry always x > x(i), but sometimes also x > x(i+1) */
- while (x > lx0 + dx0 * (i+1)) {i++; ijk++;}
-
- /* first attempt to interface to JT's interpolator */
-
- /* offset of stencil, note that rotation leads to x close to x0
- for large x */
- offset = eno_order;
-/* offset = tmp_order; */
-
- /* shift stencil at boundaries */
- /* note that for simplicity we don't distinguish between true boundaries
- and decomposition boundaries: the sync fixes that! */
- if (i-offset < 0) offset = i;
-/* if (i-offset+4 >= lnx) offset = i+5-lnx; */
-/* if (i-offset+2*tmp_order >= lnx) offset = i+2*tmp_order+1-lnx; */
- if (i-offset+2*eno_order >= lnx) offset = i+2*eno_order+1-lnx;
-
- /* fill in info */
- /* fills in old data near axis, but as long as stencil at axis is
- centered, no interpolation happens anyway */
- x0 = lx0 + dx0 * (i-offset);
-/* for (n = 0; n < 2 * tmp_order + 1; ++n) */
- for (n = 0; n < 2 * eno_order + 1; ++n)
- {
- y[n] = f[ijk-offset+n];
- excised_points[n] = 0;
- if (*excision_active)
- {
- if ((*excision_active == 1)||(*excision_active == 3))
- {
- excised_points[n] = (old_mask[ijk-offset+n] > 0.75) ? 1 : 0;
- }
- if ((*excision_active == 2)||(*excision_active == 3))
- {
- excised_points[n] |=
- (SpaceMask_CheckStateBits(new_mask, (ijk-offset+n),
- *new_excision_field,
- *new_excision_descriptor));
- }
- }
- }
-
- /* call interpolator */
-/* r = interpolate_eno(tmp_order, x0, dx0, y, x); */
- r = interpolate_eno(eno_order, x0, dx0, y, x, excised_points);
-
- return r;
-}
-
void Cartoon2D_InitExcisionVars(CCTK_ARGUMENTS)
{
DECLARE_CCTK_ARGUMENTS;
diff --git a/src/RegisterSym.c b/src/RegisterSym.c
index 2145df0..dbed7be 100644
--- a/src/RegisterSym.c
+++ b/src/RegisterSym.c
@@ -60,10 +60,10 @@ void Cartoon2D_RegisterSymmetries (CCTK_ARGUMENTS)
CCTK_WARN (0, "Could not register the Cartoon boundaries -- probably some other thorn has already registered the same boundary faces for a different symmetry");
}
- ierr = SymmetryRegisterGridInterpolator
- (cctkGH, handle, Cartoon2D_SymmetryInterpolate);
- if (ierr < 0) {
- CCTK_WARN (0, "Could not register the symmetry interpolator");
- }
+ //ierr = SymmetryRegisterGridInterpolator
+ // (cctkGH, handle, Cartoon2D_SymmetryInterpolate);
+ //if (ierr < 0) {
+ // CCTK_WARN (0, "Could not register the symmetry interpolator");
+ //}
}
diff --git a/src/SetGrid.c b/src/SetGrid.c
index 954d301..28ff2f7 100644
--- a/src/SetGrid.c
+++ b/src/SetGrid.c
@@ -9,10 +9,12 @@
@version $Id$
@@*/
+#include <math.h>
#include <stdio.h>
#include <string.h>
#include "cctk.h"
+#include "cctk_Arguments.h"
#include "cctk_Parameter.h"
#include "cctk_Parameters.h"
@@ -267,3 +269,29 @@ int Cartoon2D_SetGrid(void)
return 0;
}
+
+void Cartoon2D_setup_coord(CCTK_ARGUMENTS)
+{
+ DECLARE_CCTK_ARGUMENTS;
+ DECLARE_CCTK_PARAMETERS;
+
+#pragma omp parallel for
+ for (int k = 0; k < cctkGH->cctk_lsh[2]; k++)
+ for (int j = 0; j < cctkGH->cctk_lsh[1]; j++)
+ for (int i = 0; i < cctkGH->cctk_lsh[0]; i++) {
+ int idx = CCTK_GFINDEX3D(cctkGH, i, j, k);
+ CCTK_REAL x_val = x[idx], y_val = y[idx];
+ rho[idx] = sqrt(x_val * x_val + y_val * y_val);
+ zero[idx] = 0.0;
+
+ rxx[idx] = x_val / rho[idx];
+ ryx[idx] = y_val / rho[idx];
+ rxy[idx] = -ryx[idx];
+ ryy[idx] = rxx[idx];
+
+ sxx[idx] = ryy[idx];
+ syx[idx] = -ryx[idx];
+ sxy[idx] = -rxy[idx];
+ syy[idx] = rxx[idx];
+ }
+}
diff --git a/src/interpolate.c b/src/interpolate.c
index 3ae6b3f..151f08c 100644
--- a/src/interpolate.c
+++ b/src/interpolate.c
@@ -23,128 +23,7 @@
CCTK_REAL interpolate_local(int order, CCTK_REAL x0, CCTK_REAL dx,
CCTK_REAL y[],
- CCTK_REAL x,
- CCTK_INT excised_points[]);
-
-CCTK_REAL interpolate_eno(CCTK_INT order, CCTK_REAL x0, CCTK_REAL dx,
- CCTK_REAL y[],
- CCTK_REAL x,
- CCTK_INT excised_points[]);
-
-/* prototypes for private functions defined in this file */
-static CCTK_REAL interpolate_local_order1(CCTK_REAL x0, CCTK_REAL dx,
- CCTK_REAL y[],
- CCTK_REAL x);
-static CCTK_REAL interpolate_local_order2(CCTK_REAL x0, CCTK_REAL dx,
- CCTK_REAL y[],
- CCTK_REAL x);
-static CCTK_REAL interpolate_local_order3(CCTK_REAL x0, CCTK_REAL dx,
- CCTK_REAL y[],
- CCTK_REAL x);
-static CCTK_REAL interpolate_local_order4(CCTK_REAL x0, CCTK_REAL dx,
- CCTK_REAL y[],
- CCTK_REAL x);
-static CCTK_REAL interpolate_local_order5(CCTK_REAL x0, CCTK_REAL dx,
- CCTK_REAL y[],
- CCTK_REAL x);
-
-/*****************************************************************************/
-
-/*
- * This function does local Lagrange polynomial interpolation on a
- * uniform grid. That is, given order+1 uniformly spaced data points
- * (x0 + i*dx, y[i]) , i = 0...order, it interpolates a degree-(order)
- * (Lagrange) polynomial through them and evaluates this polynomial at
- * a specified x coordinate. In general the error in this computed
- * function value is O(h^(order+1)) .
- *
- * Except for possible end effects (see end_action (below)), the local
- * interpolation is internally centered to improve its conditioning. Even
- * so, the interpolation is highly ill-conditioned for small dx and/or
- * large order and/or x outside the domain of the data points.
- *
- * The interpolation formulas were (are) all derived via Maple, see
- * "./interpolate.in" and "./interpolate.out".
- *
- * Arguments:
- * order = (in) The order of the local interpolation, i.e. the degree
- * of the interpolated polynomial.
- * x0 = (in) The x coordinate corresponding to y[0].
- * dx = (in) The x spacing between the data points.
- * y[0...order] = (in) The y data array.
- * x = (in) The x coordinate for the interpolation.
- */
-CCTK_REAL interpolate_local(int order,
- CCTK_REAL x0, CCTK_REAL dx,
- CCTK_REAL y[],
- CCTK_REAL x,
- CCTK_INT excised_points[])
-{
-
- /*
- We assume that the excised region has one of the following 4 forms:
-
- o o o o o (No excision)
- x o o o o (left excision)
- o o o o x (right excision)
- x o o o x (left and right excision)
-
- Anything else (e.g., x o x o x) will go horribly wrong.
- */
-
- int start, end, available_order;
-
- start = 0;
- end = order;
-
- while ((start < order + 1)&&(excised_points[start]))
- {
- ++start;
- }
- while ((end > -1)&&(excised_points[end]))
- {
- --end;
- }
-
- if (end < start)
- {
- /* The whole block is excised */
- return y[0];
- }
-
- /* The possible interpolation order that can be used */
-
- available_order = end - start;
-
- if (available_order == 0)
- {
- /* There is only one non-excised point */
- return y[start];
- }
-
- if (dx * start + x0 > x)
- {
- /* We would have to extrapolate to the left */
- return y[start];
- }
-
- if (dx * end + x0 < x)
- {
- /* We would have to extrapolate to the right */
- return y[end];
- }
-
- switch (available_order)
- {
- case 1: return interpolate_local_order1(x0 + start * dx, dx, &y[start], x);
- case 2: return interpolate_local_order2(x0 + start * dx, dx, &y[start], x);
- case 3: return interpolate_local_order3(x0 + start * dx, dx, &y[start], x);
- case 4: return interpolate_local_order4(x0 + start * dx, dx, &y[start], x);
- case 5: return interpolate_local_order5(x0 + start * dx, dx, &y[start], x);
- default: CCTK_WARN(0, "Interpolation order not supported");
- return 0; /* Avoid warning */
- }
-}
+ CCTK_REAL x);
/*****************************************************************************/
@@ -156,13 +35,13 @@ static CCTK_REAL interpolate_local_order1(CCTK_REAL x0, CCTK_REAL dx,
CCTK_REAL y[],
CCTK_REAL x)
{
-CCTK_REAL c0 = (+1.0/2.0)*y[0] + (+1.0/2.0)*y[1];
-CCTK_REAL c1 = - y[0] + + y[1];
+ CCTK_REAL c0 = (+1.0/2.0)*y[0] + (+1.0/2.0)*y[1];
+ CCTK_REAL c1 = - y[0] + + y[1];
-CCTK_REAL xc = x0 + 0.5*dx;
-CCTK_REAL xr = (x - xc) / dx;
+ CCTK_REAL xc = x0 + 0.5*dx;
+ CCTK_REAL xr = (x - xc) / dx;
-return( c0 + xr*c1 );
+ return c0 + xr * c1;
}
/*****************************************************************************/
@@ -175,14 +54,14 @@ static CCTK_REAL interpolate_local_order2(CCTK_REAL x0, CCTK_REAL dx,
CCTK_REAL y[],
CCTK_REAL x)
{
-CCTK_REAL c0 = y[1];
-CCTK_REAL c1 = (-1.0/2.0)*y[0] + (+1.0/2.0)*y[2];
-CCTK_REAL c2 = (+1.0/2.0)*y[0] - y[1] + (+1.0/2.0)*y[2];
+ CCTK_REAL c0 = y[1];
+ CCTK_REAL c1 = (-1.0/2.0)*y[0] + (+1.0/2.0)*y[2];
+ CCTK_REAL c2 = (+1.0/2.0)*y[0] - y[1] + (+1.0/2.0)*y[2];
-CCTK_REAL xc = x0 + 1.0*dx;
-CCTK_REAL xr = (x - xc) / dx;
+ CCTK_REAL xc = x0 + 1.0*dx;
+ CCTK_REAL xr = (x - xc) / dx;
-return( c0 + xr*(c1 + xr*c2) );
+ return c0 + xr*(c1 + xr*c2);
}
/*****************************************************************************/
@@ -195,19 +74,19 @@ static CCTK_REAL interpolate_local_order3(CCTK_REAL x0, CCTK_REAL dx,
CCTK_REAL y[],
CCTK_REAL x)
{
-CCTK_REAL c0 = (-1.0/16.0)*y[0] + (+9.0/16.0)*y[1]
- + (+9.0/16.0)*y[2] + (-1.0/16.0)*y[3];
-CCTK_REAL c1 = (+1.0/24.0)*y[0] + (-9.0/ 8.0)*y[1]
- + (+9.0/ 8.0)*y[2] + (-1.0/24.0)*y[3];
-CCTK_REAL c2 = (+1.0/ 4.0)*y[0] + (-1.0/ 4.0)*y[1]
- + (-1.0/ 4.0)*y[2] + (+1.0/ 4.0)*y[3];
-CCTK_REAL c3 = (-1.0/ 6.0)*y[0] + (+1.0/ 2.0)*y[1]
- + (-1.0/ 2.0)*y[2] + ( 1.0/ 6.0)*y[3];
-
-CCTK_REAL xc = x0 + 1.5*dx;
-CCTK_REAL xr = (x - xc) / dx;
-
-return( c0 + xr*(c1 + xr*(c2 + xr*c3)) );
+ CCTK_REAL c0 = (-1.0/16.0)*y[0] + (+9.0/16.0)*y[1]
+ + (+9.0/16.0)*y[2] + (-1.0/16.0)*y[3];
+ CCTK_REAL c1 = (+1.0/24.0)*y[0] + (-9.0/ 8.0)*y[1]
+ + (+9.0/ 8.0)*y[2] + (-1.0/24.0)*y[3];
+ CCTK_REAL c2 = (+1.0/ 4.0)*y[0] + (-1.0/ 4.0)*y[1]
+ + (-1.0/ 4.0)*y[2] + (+1.0/ 4.0)*y[3];
+ CCTK_REAL c3 = (-1.0/ 6.0)*y[0] + (+1.0/ 2.0)*y[1]
+ + (-1.0/ 2.0)*y[2] + ( 1.0/ 6.0)*y[3];
+
+ CCTK_REAL xc = x0 + 1.5*dx;
+ CCTK_REAL xr = (x - xc) / dx;
+
+ return c0 + xr*(c1 + xr*(c2 + xr*c3));
}
/*****************************************************************************/
@@ -220,20 +99,20 @@ static CCTK_REAL interpolate_local_order4(CCTK_REAL x0, CCTK_REAL dx,
CCTK_REAL y[],
CCTK_REAL x)
{
-CCTK_REAL c0 = y[2];
-CCTK_REAL c1 = (+1.0/12.0)*y[0] + (-2.0/ 3.0)*y[1]
- + (+2.0/ 3.0)*y[3] + (-1.0/12.0)*y[4];
-CCTK_REAL c2 = + (-1.0/24.0)*y[0] + (+2.0/ 3.0)*y[1] + (-5.0/ 4.0)*y[2]
- + (+2.0/ 3.0)*y[3] + (-1.0/24.0)*y[4];
-CCTK_REAL c3 = + (-1.0/12.0)*y[0] + (+1.0/ 6.0)*y[1]
- + (-1.0/ 6.0)*y[3] + (+1.0/12.0)*y[4];
-CCTK_REAL c4 = + (+1.0/24.0)*y[0] + (-1.0/ 6.0)*y[1] + (+1.0/ 4.0)*y[2]
- + (-1.0/ 6.0)*y[3] + (+1.0/24.0)*y[4];
-
-CCTK_REAL xc = x0 + 2.0*dx;
-CCTK_REAL xr = (x - xc) / dx;
-
-return( c0 + xr*(c1 + xr*(c2 + xr*(c3 + xr*c4))) );
+ CCTK_REAL c0 = y[2];
+ CCTK_REAL c1 = (+1.0/12.0)*y[0] + (-2.0/ 3.0)*y[1]
+ + (+2.0/ 3.0)*y[3] + (-1.0/12.0)*y[4];
+ CCTK_REAL c2 = + (-1.0/24.0)*y[0] + (+2.0/ 3.0)*y[1] + (-5.0/ 4.0)*y[2]
+ + (+2.0/ 3.0)*y[3] + (-1.0/24.0)*y[4];
+ CCTK_REAL c3 = + (-1.0/12.0)*y[0] + (+1.0/ 6.0)*y[1]
+ + (-1.0/ 6.0)*y[3] + (+1.0/12.0)*y[4];
+ CCTK_REAL c4 = + (+1.0/24.0)*y[0] + (-1.0/ 6.0)*y[1] + (+1.0/ 4.0)*y[2]
+ + (-1.0/ 6.0)*y[3] + (+1.0/24.0)*y[4];
+
+ CCTK_REAL xc = x0 + 2.0*dx;
+ CCTK_REAL xr = (x - xc) / dx;
+
+ return c0 + xr*(c1 + xr*(c2 + xr*(c3 + xr*c4)));
}
/*****************************************************************************/
@@ -246,200 +125,81 @@ static CCTK_REAL interpolate_local_order5(CCTK_REAL x0, CCTK_REAL dx,
CCTK_REAL y[],
CCTK_REAL x)
{
-CCTK_REAL c0 = (+ 3.0/256.0)*y[0] + (-25.0/256.0)*y[1]
- + (+75.0/128.0)*y[2] + (+75.0/128.0)*y[3]
- + (-25.0/256.0)*y[4] + (+ 3.0/256.0)*y[5];
-CCTK_REAL c1 = (- 3.0/640.0)*y[0] + (+25.0/384.0)*y[1]
- + (-75.0/ 64.0)*y[2] + (+75.0/ 64.0)*y[3]
- + (-25.0/384.0)*y[4] + (+ 3.0/640.0)*y[5];
-CCTK_REAL c2 = (- 5.0/ 96.0)*y[0] + (+13.0/ 32.0)*y[1]
- + (-17.0/ 48.0)*y[2] + (-17.0/ 48.0)*y[3]
- + (+13.0/ 32.0)*y[4] + (- 5.0/ 96.0)*y[5];
-CCTK_REAL c3 = (+ 1.0/ 48.0)*y[0] + (-13.0/ 48.0)*y[1]
- + (+17.0/ 24.0)*y[2] + (-17.0/ 24.0)*y[3]
- + (+13.0/ 48.0)*y[4] + (- 1.0/ 48.0)*y[5];
-CCTK_REAL c4 = (+ 1.0/ 48.0)*y[0] + (- 1.0/ 16.0)*y[1]
- + (+ 1.0/ 24.0)*y[2] + (+ 1.0/ 24.0)*y[3]
- + (- 1.0/ 16.0)*y[4] + (+ 1.0/ 48.0)*y[5];
-CCTK_REAL c5 = (- 1.0/120.0)*y[0] + (+ 1.0/ 24.0)*y[1]
- + (- 1.0/ 12.0)*y[2] + (+ 1.0/ 12.0)*y[3]
- + (- 1.0/ 24.0)*y[4] + (+ 1.0/120.0)*y[5];
-
-CCTK_REAL xc = x0 + 2.5*dx;
-CCTK_REAL xr = (x - xc) / dx;
-
-return( c0 + xr*(c1 + xr*(c2 + xr*(c3 + xr*(c4 + xr*c5)))) );
+ CCTK_REAL c0 = (+ 3.0/256.0)*y[0] + (-25.0/256.0)*y[1]
+ + (+75.0/128.0)*y[2] + (+75.0/128.0)*y[3]
+ + (-25.0/256.0)*y[4] + (+ 3.0/256.0)*y[5];
+ CCTK_REAL c1 = (- 3.0/640.0)*y[0] + (+25.0/384.0)*y[1]
+ + (-75.0/ 64.0)*y[2] + (+75.0/ 64.0)*y[3]
+ + (-25.0/384.0)*y[4] + (+ 3.0/640.0)*y[5];
+ CCTK_REAL c2 = (- 5.0/ 96.0)*y[0] + (+13.0/ 32.0)*y[1]
+ + (-17.0/ 48.0)*y[2] + (-17.0/ 48.0)*y[3]
+ + (+13.0/ 32.0)*y[4] + (- 5.0/ 96.0)*y[5];
+ CCTK_REAL c3 = (+ 1.0/ 48.0)*y[0] + (-13.0/ 48.0)*y[1]
+ + (+17.0/ 24.0)*y[2] + (-17.0/ 24.0)*y[3]
+ + (+13.0/ 48.0)*y[4] + (- 1.0/ 48.0)*y[5];
+ CCTK_REAL c4 = (+ 1.0/ 48.0)*y[0] + (- 1.0/ 16.0)*y[1]
+ + (+ 1.0/ 24.0)*y[2] + (+ 1.0/ 24.0)*y[3]
+ + (- 1.0/ 16.0)*y[4] + (+ 1.0/ 48.0)*y[5];
+ CCTK_REAL c5 = (- 1.0/120.0)*y[0] + (+ 1.0/ 24.0)*y[1]
+ + (- 1.0/ 12.0)*y[2] + (+ 1.0/ 12.0)*y[3]
+ + (- 1.0/ 24.0)*y[4] + (+ 1.0/120.0)*y[5];
+
+ CCTK_REAL xc = x0 + 2.5*dx;
+ CCTK_REAL xr = (x - xc) / dx;
+
+ return c0 + xr*(c1 + xr*(c2 + xr*(c3 + xr*(c4 + xr*c5))));
}
-
-/*****************************************************************************/
-
-CCTK_REAL interpolate_eno(CCTK_INT order,
- CCTK_REAL x0, CCTK_REAL dx,
- CCTK_REAL y[],
- CCTK_REAL x,
- CCTK_INT excised_points[])
+/*
+ * This function does local Lagrange polynomial interpolation on a
+ * uniform grid. That is, given order+1 uniformly spaced data points
+ * (x0 + i*dx, y[i]) , i = 0...order, it interpolates a degree-(order)
+ * (Lagrange) polynomial through them and evaluates this polynomial at
+ * a specified x coordinate. In general the error in this computed
+ * function value is O(h^(order+1)) .
+ *
+ * Except for possible end effects (see end_action (below)), the local
+ * interpolation is internally centered to improve its conditioning. Even
+ * so, the interpolation is highly ill-conditioned for small dx and/or
+ * large order and/or x outside the domain of the data points.
+ *
+ * The interpolation formulas were (are) all derived via Maple, see
+ * "./interpolate.in" and "./interpolate.out".
+ *
+ * Arguments:
+ * order = (in) The order of the local interpolation, i.e. the degree
+ * of the interpolated polynomial.
+ * x0 = (in) The x coordinate corresponding to y[0].
+ * dx = (in) The x spacing between the data points.
+ * y[0...order] = (in) The y data array.
+ * x = (in) The x coordinate for the interpolation.
+ */
+CCTK_REAL interpolate_local(int order,
+ CCTK_REAL x0, CCTK_REAL dx,
+ CCTK_REAL y[],
+ CCTK_REAL x)
{
-/* CCTK_REAL diff[4]; */
-/* CCTK_INT seed = 0; */
-/* CCTK_INT j,r; */
-
-/* CCTK_REAL c0; */
-/* CCTK_REAL c1; */
-/* CCTK_REAL c2; */
-
-/* CCTK_REAL xc; */
-/* CCTK_REAL xr; */
-
- CCTK_REAL result;
- CCTK_REAL undiv_diff [13][6];
- CCTK_INT diff, i, ii, r;
- CCTK_REAL fp_i, fp_ii, x_rel;
-
- /* Find seed index */
-/* while (x > x0 + dx * ((CCTK_REAL)seed+0.5)) seed++; */
-
-/* if (seed!=2) { */
- /* Not enough stencil, only perform linear interpolation */
-/* seed = 0; */
-/* while (x > x0 + dx * ((CCTK_REAL)(seed+1))) seed++; */
-/* if (seed==4) seed=3; */
-/* return y[seed] + (y[seed+1]-y[seed])/dx * (x-x0-(CCTK_REAL)seed*dx); */
-/* } */
-
- /* Calculate the undivided differences */
-/* for (j=0; j<=3; j++) */
-/* diff[j] = y[j+1] - y[j]; */
-
- /* Find the stencil */
-/* if ( fabs(diff[1]) < fabs(diff[2]) ) { */
-/* if ( fabs(diff[1]-diff[0]) < fabs(diff[2]-diff[1]) ) */
-/* r = 0; */
-/* else */
-/* r = 1; */
-/* } else { */
-/* if ( fabs(diff[2]-diff[1]) < fabs(diff[3]-diff[2]) ) */
-/* r = 1; */
-/* else */
-/* r = 2; */
-/* } */
-
- /* Interpolate second order */
-/* c0 = y[r+1]; */
-/* c1 = (-1.0/2.0)*y[r] + (+1.0/2.0)*y[r+2]; */
-/* c2 = (+1.0/2.0)*y[r] - y[r+1] + (+1.0/2.0)*y[r+2]; */
-
-/* xc = x0 + dx * (CCTK_REAL)(r+1); */
-/* xr = (x - xc) / dx; */
-/* result = ( c0 + xr*(c1 + xr*c2) ); */
-
- for (i = 1; i < 2 * order + 2; ++i)
- {
- undiv_diff[i][0] = y[i-1];
- }
- for (i = 0; i < 6; ++i)
- {
- undiv_diff[0][i] = 1e10;
- undiv_diff[2 * order + 2][i] = 1e10;
- }
-
- for (diff = 1; diff < order + 1; ++diff)
- {
- for (i = 1; i < 2 * order + 2; ++i)
- {
- undiv_diff[i][diff] = undiv_diff[i][diff-1] - undiv_diff[i-1][diff-1];
- }
- undiv_diff[0][diff] = -10 * undiv_diff[1][diff];
- undiv_diff[2 * order + 2][diff]= -10 * undiv_diff[2 * order + 1][diff];
- }
+ int start, end;
- fp_i = (x - x0) / dx;
- fp_ii = floor(fp_i);
- x_rel = fp_i - fp_ii;
-
- ii = (CCTK_INT)(fp_ii) + 1;
-
- if (ii < 1)
- {
- ii = 1;
- x_rel = fp_i - (CCTK_REAL)(ii) + 1.0;
- }
- else if (ii > 2 * order + 1)
- {
- ii = 2 * order + 1;
- x_rel = fp_i - (CCTK_REAL)(ii) + 1.0;
- }
+ start = 0;
+ end = order;
- r = 0;
- for (diff = 1; diff < order + 1; ++diff)
- {
- if (fabs(undiv_diff[ii-r][diff]) < fabs(undiv_diff[ii-r+1][diff]) )
- {
- ++r;
- }
-
- if (ii - r < diff + 1)
- {
- --r;
- }
- else if (ii - r + diff > 2 * order + 1)
- {
- ++r;
- }
- }
-
- result = undiv_diff[ii-r][0];
+ /* The possible interpolation order that can be used */
- switch (order)
- {
- case 1:
- result += (x_rel + r - 0.0) / 1.0 * undiv_diff[ii-r+1][1];
- break;
- case 2:
- result += (x_rel + r - 0.0) / 1.0 * (undiv_diff[ii-r+1][1] +
- (x_rel + r - 1.0) / 2.0 * (undiv_diff[ii-r+2][2]));
- break;
- case 3:
- result += (x_rel + r - 0.0) / 1.0 * (undiv_diff[ii-r+1][1] +
- (x_rel + r - 1.0) / 2.0 * (undiv_diff[ii-r+2][2] +
- (x_rel + r - 2.0) / 3.0 * (undiv_diff[ii-r+3][3])));
- break;
- case 4:
- result += (x_rel + r - 0.0) / 1.0 * (undiv_diff[ii-r+1][1] +
- (x_rel + r - 1.0) / 2.0 * (undiv_diff[ii-r+2][2] +
- (x_rel + r - 2.0) / 3.0 * (undiv_diff[ii-r+3][3] +
- (x_rel + r - 3.0) / 4.0 * (undiv_diff[ii-r+4][4]))));
- break;
- case 5:
- result += (x_rel + r - 0.0) / 1.0 * (undiv_diff[ii-r+1][1] +
- (x_rel + r - 1.0) / 2.0 * (undiv_diff[ii-r+2][2] +
- (x_rel + r - 2.0) / 3.0 * (undiv_diff[ii-r+3][3] +
- (x_rel + r - 3.0) / 4.0 * (undiv_diff[ii-r+4][4] +
- (x_rel + r - 4.0) / 5.0 * (undiv_diff[ii-r+5][5])))));
- break;
- }
+ if (x0 > x)
+ return y[start];
-/* #define CARTOON_ENO_DBG 1 */
-#ifdef CARTOON_ENO_DBG
-
- printf("Cartoon ENO interpolation.\n"
- "Input: order %d x0 %g dx %g x %g.\n",
- order, x0, dx, x);
- printf("Data is\n");
- for (i = 0; i < 2 * order + 1; ++i)
- {
- printf(" %g", y[i]);
+ if (dx * end + x0 < x)
+ return y[end];
+
+ switch (order) {
+ case 1: return interpolate_local_order1(x0, dx, y, x);
+ case 2: return interpolate_local_order2(x0, dx, y, x);
+ case 3: return interpolate_local_order3(x0, dx, y, x);
+ case 4: return interpolate_local_order4(x0, dx, y, x);
+ case 5: return interpolate_local_order5(x0, dx, y, x);
+ default: CCTK_WARN(0, "Interpolation order not supported");
+ return 0; /* Avoid warning */
}
- printf("\nEntries used were\n");
- printf("0: %g 1: %g 2: %g\n",
- undiv_diff[ii-r][0], undiv_diff[ii-r+1][1], undiv_diff[ii-r+2][2]);
- printf("Parameters are fp_i %g fp_ii %g x_rel %g ii %d r %d\n",
- fp_i, fp_ii, x_rel, ii, r);
- printf("Result is %g\n", result);
-
-#endif
-
- return result;
-
}