aboutsummaryrefslogtreecommitdiff
path: root/src/interpolate.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/interpolate.c')
-rw-r--r--src/interpolate.c79
1 files changed, 69 insertions, 10 deletions
diff --git a/src/interpolate.c b/src/interpolate.c
index 1d774a2..e207cb2 100644
--- a/src/interpolate.c
+++ b/src/interpolate.c
@@ -23,11 +23,13 @@
CCTK_REAL interpolate_local(int order, CCTK_REAL x0, CCTK_REAL dx,
CCTK_REAL y[],
- CCTK_REAL x);
+ 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_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,
@@ -75,14 +77,70 @@ static CCTK_REAL interpolate_local_order5(CCTK_REAL x0, CCTK_REAL dx,
CCTK_REAL interpolate_local(int order,
CCTK_REAL x0, CCTK_REAL dx,
CCTK_REAL y[],
- CCTK_REAL x)
+ CCTK_REAL x,
+ CCTK_INT excised_points[])
{
- 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);
+
+ /*
+ 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");
}
}
@@ -218,7 +276,8 @@ 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_REAL x,
+ CCTK_INT excised_points[])
{
/* CCTK_REAL diff[4]; */