aboutsummaryrefslogtreecommitdiff
path: root/src/interpolate.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/interpolate.c')
-rw-r--r--src/interpolate.c186
1 files changed, 150 insertions, 36 deletions
diff --git a/src/interpolate.c b/src/interpolate.c
index d990cf5..1d774a2 100644
--- a/src/interpolate.c
+++ b/src/interpolate.c
@@ -17,6 +17,7 @@
*/
#include <math.h>
+#include <stdio.h>
#include "cctk.h"
@@ -24,7 +25,7 @@ CCTK_REAL interpolate_local(int order, CCTK_REAL x0, CCTK_REAL dx,
CCTK_REAL y[],
CCTK_REAL x);
-CCTK_REAL interpolate_eno(CCTK_REAL x0, CCTK_REAL dx,
+CCTK_REAL interpolate_eno(CCTK_INT order, CCTK_REAL x0, CCTK_REAL dx,
CCTK_REAL y[],
CCTK_REAL x);
@@ -214,58 +215,171 @@ return( c0 + xr*(c1 + xr*(c2 + xr*(c3 + xr*(c4 + xr*c5)))) );
/*****************************************************************************/
-CCTK_REAL interpolate_eno(CCTK_REAL x0, CCTK_REAL dx,
+CCTK_REAL interpolate_eno(CCTK_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 diff[4]; */
+/* CCTK_INT seed = 0; */
+/* CCTK_INT j,r; */
- CCTK_REAL c0;
- CCTK_REAL c1;
- CCTK_REAL c2;
+/* CCTK_REAL c0; */
+/* CCTK_REAL c1; */
+/* CCTK_REAL c2; */
- CCTK_REAL xc;
- CCTK_REAL xr;
+/* 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++;
+/* while (x > x0 + dx * ((CCTK_REAL)seed+0.5)) seed++; */
- if (seed!=2) {
+/* 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);
- }
+/* 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];
+/* 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;
- }
+/* 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];
+/* 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;
+/* xc = x0 + dx * (CCTK_REAL)(r+1); */
+/* xr = (x - xc) / dx; */
+/* result = ( c0 + xr*(c1 + xr*c2) ); */
- return( 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];
+ }
+
+ 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;
+ }
+
+ 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];
+
+ 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;
+ }
+
+/* #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]);
+ }
+ 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;
}