aboutsummaryrefslogtreecommitdiff
path: root/Carpet/CarpetInterp/src/interp.cc
diff options
context:
space:
mode:
Diffstat (limited to 'Carpet/CarpetInterp/src/interp.cc')
-rw-r--r--Carpet/CarpetInterp/src/interp.cc147
1 files changed, 118 insertions, 29 deletions
diff --git a/Carpet/CarpetInterp/src/interp.cc b/Carpet/CarpetInterp/src/interp.cc
index 75ae5675d..b018768dc 100644
--- a/Carpet/CarpetInterp/src/interp.cc
+++ b/Carpet/CarpetInterp/src/interp.cc
@@ -1,4 +1,4 @@
-// $Header: /home/eschnett/C/carpet/Carpet/Carpet/CarpetInterp/src/interp.cc,v 1.13 2003/10/14 16:39:16 schnetter Exp $
+// $Header: /home/eschnett/C/carpet/Carpet/Carpet/CarpetInterp/src/interp.cc,v 1.14 2003/11/05 16:18:38 schnetter Exp $
#include <assert.h>
#include <math.h>
@@ -12,6 +12,8 @@
#include "bbox.hh"
#include "data.hh"
+#include "defs.hh"
+#include "ggf.hh"
#include "vect.hh"
#include "carpet.hh"
@@ -19,7 +21,7 @@
#include "interp.hh"
extern "C" {
- static char const * const rcsid = "$Header: /home/eschnett/C/carpet/Carpet/Carpet/CarpetInterp/src/interp.cc,v 1.13 2003/10/14 16:39:16 schnetter Exp $";
+ static char const * const rcsid = "$Header: /home/eschnett/C/carpet/Carpet/Carpet/CarpetInterp/src/interp.cc,v 1.14 2003/11/05 16:18:38 schnetter Exp $";
CCTK_FILEVERSION(Carpet_CarpetInterp_interp_cc);
}
@@ -112,9 +114,10 @@ namespace CarpetInterp {
delta[d] = (upper[d] - lower[d]) / (hh->baseextent.shape()[d] - hh->baseextent.stride()[d]);
}
+ assert (N_interp_points >= 0);
assert (interp_coords);
for (int d=0; d<dim; ++d) {
- assert (interp_coords[d]);
+ assert (N_interp_points==0 || interp_coords[d]);
}
@@ -135,6 +138,7 @@ namespace CarpetInterp {
+#if 0
// Assert that all refinement levels have the same time
// TODO: interpolate in time
{
@@ -152,13 +156,21 @@ namespace CarpetInterp {
"Cannot interpolate in global mode at iteration %d (time %g), because not all refinement levels exist at this time. Interpolation in time is not yet implemented.",
cgh->cctk_iteration, (double)cgh->cctk_time);
} else {
- CCTK_VWarn (0, __LINE__, __FILE__, CCTK_THORNSTRING,
- "Cannot interpolate in level mode at iteration %d (time %g), because refinement level %d does not exist at this time. Interpolation in time is not yet implemented.",
- cgh->cctk_iteration, (double)cgh->cctk_time, reflevel);
+ // called in level mode at a time where the level does not
+ // exist
+ CCTK_WARN (0, "internal error");
}
assert (0);
}
}
+#endif
+
+ // Find the time interpolation order
+ int partype;
+ void const * const parptr = CCTK_ParameterGet ("prolongation_order_time", "Carpet", &partype);
+ assert (parptr);
+ assert (partype == PARAMETER_INTEGER);
+ int const prolongation_order_time = * (CCTK_INT const *) parptr;
@@ -181,8 +193,10 @@ namespace CarpetInterp {
home[n] = -1;
for (int rl=maxrl-1; rl>=minrl; --rl) {
+ const int fact = maxreflevelfact / ipow(reffact,rl);
CCTK_REAL (* const rfloor) (CCTK_REAL const) = floor;
- ivect const ipos = ivect(map(rfloor, (pos - lower) / delta + 0.5));
+ ivect const ipos = ivect(map(rfloor, (pos - lower) / (delta * fact) + 0.5)) * fact;
+ assert (all(ipos % hh->bases[rl][ml].stride() == 0));
// TODO: use something faster than a linear search
for (int c=0; c<hh->components(rl); ++c) {
@@ -251,10 +265,13 @@ namespace CarpetInterp {
}
// Transfer coordinate patches
- for (int p=0; p<nprocs; ++p) {
- for (int rl=minrl; rl<maxrl; ++rl) {
- for (int c=0; c<hh->components(rl); ++c) {
- allcoords[ind_prc(p,rl,c)].change_processor (hh->processors[rl][c]);
+ for (comm_state<dim> state; !state.done(); state.step()) {
+ for (int p=0; p<nprocs; ++p) {
+ for (int rl=minrl; rl<maxrl; ++rl) {
+ for (int c=0; c<hh->components(rl); ++c) {
+ allcoords[ind_prc(p,rl,c)].change_processor
+ (state, hh->processors[rl][c]);
+ }
}
}
}
@@ -298,6 +315,15 @@ namespace CarpetInterp {
if (reflevel>=minrl && reflevel<maxrl) {
BEGIN_MGLEVEL_LOOP(cgh) {
+ // Number of necessary time levels
+ int const tl = 0;
+ CCTK_REAL const time1 = tt->time (tl, reflevel, mglevel);
+ CCTK_REAL const time2 = cgh->cctk_time / cgh->cctk_delta_time;
+ bool const need_time_interp
+ = fabs((time1 - time2) / (fabs(time1) + fabs(time2) + fabs(cgh->cctk_delta_time))) > 1e-12;
+ int const num_tl
+ = need_time_interp ? prolongation_order_time + 1 : 1;
+
BEGIN_LOCAL_COMPONENT_LOOP(cgh, CCTK_GF) {
// Find out about the local geometry
@@ -313,13 +339,13 @@ namespace CarpetInterp {
// Find out about the grid functions
vector<CCTK_INT> input_array_type_codes(N_input_arrays);
- vector<const void *> input_arrays(N_input_arrays);
+ vector<const void *> input_arrays(N_input_arrays * num_tl);
for (int n=0; n<N_input_arrays; ++n) {
if (input_array_variable_indices[n] == -1) {
// Ignore this entry
- input_array_type_codes[n] = -1;
- input_arrays[n] = 0;
+ input_array_type_codes[tl+n*num_tl] = -1;
+ input_arrays[tl+n*num_tl] = 0;
} else {
@@ -337,8 +363,12 @@ namespace CarpetInterp {
assert (group.disttype == CCTK_DISTRIB_DEFAULT);
assert (group.stagtype == 0); // not staggered
- input_array_type_codes[n] = group.vartype;
- input_arrays[n] = CCTK_VarDataPtrI (cgh, 0, vi);
+ assert (group.numtimelevels >= num_tl);
+
+ for (int tl=0; tl<num_tl; ++tl) {
+ input_array_type_codes[tl+n*num_tl] = group.vartype;
+ input_arrays[tl+n*num_tl] = CCTK_VarDataPtrI (cgh, tl, vi);
+ }
}
} // for input arrays
@@ -353,30 +383,85 @@ namespace CarpetInterp {
assert (allhomecnts[ind_prc(p,reflevel,component)]
== alloutputs[ind_prc(p,reflevel,component)].shape()[0]);
+ int const npoints = allhomecnts[ind_prc(p,reflevel,component)];
+
// Do the processor-local interpolation
vector<const void *> tmp_interp_coords (dim);
for (int d=0; d<dim; ++d) {
tmp_interp_coords[d]
= &allcoords[ind_prc(p,reflevel,component)][ivect(0,d,0)];
}
- vector<void *> tmp_output_arrays (N_output_arrays);
- for (int m=0; m<N_output_arrays; ++m) {
- assert (output_array_type_codes[m] == CCTK_VARIABLE_REAL);
- tmp_output_arrays[m]
- = &alloutputs[ind_prc(p,reflevel,component)][ivect(0,m,0)];
+ vector<void *> tmp_output_arrays (N_output_arrays * num_tl);
+ if (need_time_interp) {
+ for (int m=0; m<N_output_arrays; ++m) {
+ assert (output_array_type_codes[m] == CCTK_VARIABLE_REAL);
+ for (int tl=0; tl<num_tl; ++tl) {
+ tmp_output_arrays[tl+m*num_tl] = new CCTK_REAL [npoints];
+ }
+ }
+ } else {
+ for (int m=0; m<N_output_arrays; ++m) {
+ assert (output_array_type_codes[m] == CCTK_VARIABLE_REAL);
+ tmp_output_arrays[m]
+ = &alloutputs[ind_prc(p,reflevel,component)][ivect(0,m,0)];
+ }
}
ierr = CCTK_InterpLocalUniform
(N_dims, local_interp_handle, param_table_handle,
&coord_origin[0], &coord_delta[0],
- allhomecnts[ind_prc(p,reflevel,component)],
+ npoints,
interp_coords_type_code, &tmp_interp_coords[0],
- N_input_arrays, &lsh[0],
+ N_input_arrays * num_tl, &lsh[0],
&input_array_type_codes[0], &input_arrays[0],
- N_output_arrays,
+ N_output_arrays * num_tl,
output_array_type_codes, &tmp_output_arrays[0]);
assert (!ierr);
+ // Interpolate in time, if necessary
+ if (need_time_interp) {
+ CCTK_REAL const time = cgh->cctk_time / cgh->cctk_delta_time;
+ CCTK_REAL times[num_tl];
+ for (int tl=0; tl<num_tl; ++tl) {
+ times[tl] = tt->time (tl, reflevel, mglevel);
+ }
+ CCTK_REAL tfacs[num_tl];
+ switch (num_tl) {
+ case 1:
+ // no interpolation
+ assert (fabs((time - times[0]) / fabs(time + times[0] + cgh->cctk_delta_time)) < 1e-12);
+ tfacs[0] = 1.0;
+ break;
+ case 2:
+ // linear (2-point) interpolation
+ tfacs[0] = (time - times[1]) / (times[0] - times[1]);
+ tfacs[1] = (time - times[0]) / (times[1] - times[0]);
+ break;
+ case 3:
+ // quadratic (3-point) interpolation
+ tfacs[0] = (time - times[1]) * (time - times[2]) / ((times[0] - times[1]) * (times[0] - times[2]));
+ tfacs[1] = (time - times[0]) * (time - times[2]) / ((times[1] - times[0]) * (times[1] - times[2]));
+ tfacs[2] = (time - times[0]) * (time - times[1]) / ((times[2] - times[0]) * (times[2] - times[1]));
+ break;
+ default:
+ assert (0);
+ }
+ for (int m=0; m<N_output_arrays; ++m) {
+ assert (output_array_type_codes[m] == CCTK_VARIABLE_REAL);
+ for (int k=0; k<npoints; ++k) {
+ CCTK_REAL & dest = alloutputs[ind_prc(p,reflevel,component)][ivect(k,m,0)];
+ dest = 0;
+ for (int tl=0; tl<num_tl; ++tl) {
+ CCTK_REAL const src = ((CCTK_REAL const *)tmp_output_arrays[tl+m*num_tl])[k];
+ dest += tfacs[tl] * src;
+ }
+ }
+ for (int tl=0; tl<num_tl; ++tl) {
+ delete [] (CCTK_REAL *)tmp_output_arrays[tl+m*num_tl];
+ }
+ }
+ }
+
} // for processors
} END_LOCAL_COMPONENT_LOOP;
@@ -396,14 +481,18 @@ namespace CarpetInterp {
// Transfer output patches back
- for (int p=0; p<nprocs; ++p) {
- for (int rl=0; rl<minrl; ++rl) {
- for (int c=0; c<hh->components(rl); ++c) {
- alloutputs[ind_prc(p,rl,c)].change_processor (p);
+ for (comm_state<dim> state; !state.done(); state.step()) {
+ for (int p=0; p<nprocs; ++p) {
+ for (int rl=minrl; rl<maxrl; ++rl) {
+ for (int c=0; c<hh->components(rl); ++c) {
+ alloutputs[ind_prc(p,rl,c)].change_processor (state, p);
+ }
}
}
}
+
+
// Read out local output patches
{
vector<int> tmpcnts ((maxrl-minrl) * maxncomps);
@@ -412,7 +501,7 @@ namespace CarpetInterp {
int const c = home[n];
for (int m=0; m<N_output_arrays; ++m) {
assert (interp_coords_type_code == CCTK_VARIABLE_REAL);
- assert (dim==3);
+ assert (alloutputs[ind_prc(myproc,rl,c)].owns_storage());
static_cast<CCTK_REAL *>(output_arrays[m])[n] =
alloutputs[ind_prc(myproc,rl,c)][ivect(tmpcnts[ind_rc(rl,c)],m,0)];
}