aboutsummaryrefslogtreecommitdiff
path: root/Carpet/CarpetInterp
diff options
context:
space:
mode:
authorThomas Radke <tradke@aei.mpg.de>2005-11-01 17:46:00 +0000
committerThomas Radke <tradke@aei.mpg.de>2005-11-01 17:46:00 +0000
commitb136dd7e9054a924670fa5c05d3159e91c8194ab (patch)
tree90879e9f641e0f74f97e2e74d0606f77c82f0c97 /Carpet/CarpetInterp
parent3201393e7f81028786471e2a366ccc5dfbe08817 (diff)
CarpetInterp: generalisation of interpolation functionality
This patch adds support for input arrays of - type CCTK_ARRAY - arbitrary dimensions - arbitrary datatypes darcs-hash:20051101174650-776a0-56ce1ef019084cb89dce62f0c626282ba298c47f.gz
Diffstat (limited to 'Carpet/CarpetInterp')
-rw-r--r--Carpet/CarpetInterp/src/interp.cc367
1 files changed, 235 insertions, 132 deletions
diff --git a/Carpet/CarpetInterp/src/interp.cc b/Carpet/CarpetInterp/src/interp.cc
index 56855b9a0..f1ed7a1cd 100644
--- a/Carpet/CarpetInterp/src/interp.cc
+++ b/Carpet/CarpetInterp/src/interp.cc
@@ -72,10 +72,13 @@ namespace CarpetInterp {
static void
map_points (cGH const * const cctkGH,
+ int const coord_system_handle,
+ int const coord_group,
int const ml,
int const minrl,
int const maxrl,
int const maxncomps,
+ int const N_dims,
int const npoints,
vector<CCTK_INT> const& source_map,
void const * const coords_list[],
@@ -88,6 +91,8 @@ namespace CarpetInterp {
static void
interpolate_components (cGH const * const cctkGH,
+ int const coord_system_handle,
+ int const coord_group,
int const minrl,
int const maxrl,
int const maxncomps,
@@ -96,7 +101,7 @@ namespace CarpetInterp {
int const N_dims,
vector<int> & homecnts,
vector<CCTK_REAL*> & coords,
- vector<CCTK_REAL*> & outputs,
+ vector<char*> & outputs,
CCTK_INT* const per_proc_statuses,
CCTK_INT* const per_proc_retvals,
vector<CCTK_INT> & operand_indices,
@@ -106,7 +111,6 @@ namespace CarpetInterp {
CCTK_INT const param_table_handle,
CCTK_REAL const current_time,
CCTK_REAL const delta_time,
- int const interp_coords_type_code,
int const N_input_arrays,
int const N_output_arrays,
CCTK_INT const output_array_type_codes [],
@@ -114,13 +118,15 @@ namespace CarpetInterp {
static void
interpolate_single_component (cGH const * const cctkGH,
+ int const coord_system_handle,
+ int const coord_group,
int const minrl,
int const maxrl,
int const maxncomps,
int const N_dims,
int const npoints,
CCTK_REAL const* const coords,
- CCTK_REAL* const outputs,
+ char* const outputs,
CCTK_INT& overall_status,
CCTK_INT& overall_retval,
vector<CCTK_INT> & operand_indices,
@@ -134,7 +140,6 @@ namespace CarpetInterp {
CCTK_REAL const delta_time,
int const N_input_arrays,
int const N_output_arrays,
- int const interp_coords_type_code,
CCTK_INT const output_array_type_codes [],
CCTK_INT const input_array_variable_indices []);
@@ -197,8 +202,70 @@ namespace CarpetInterp {
{
cGH const * const cctkGH = static_cast<cGH const *> (cctkGH_);
assert (cctkGH);
- assert (N_dims == dim);
+ assert (1 <= N_dims and N_dims <= dim);
+ // check input arrays
+ int coord_group = -1;
+ cGroupDynamicData coord_group_data;
+ for (int n = 0; n < N_input_arrays; n++) {
+
+ // negative indices are ignored
+ const int vindex = input_array_variable_indices[n];
+ if (vindex < 0) {
+ continue;
+ }
+
+ const int group = CCTK_GroupIndexFromVarI (vindex);
+ if (group < 0) {
+ CCTK_VWarn (CCTK_WARN_ABORT, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "input array variable %d = %d is not a valid "
+ "variable index", n, vindex);
+ }
+ const int gtype = CCTK_GroupTypeI (group);
+ if (gtype != CCTK_GF and gtype != CCTK_ARRAY) {
+ CCTK_VWarn (CCTK_WARN_ABORT, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "input array variable %d is not of type CCTK_GF or "
+ "CCTK_ARRY", n);
+ }
+ if (CCTK_GroupStaggerIndexGI (group) != 0) {
+ CCTK_VWarn (CCTK_WARN_ABORT, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "interpolation of staggered input array variable %d "
+ "is not supported", n);
+ }
+ if (coord_group < 0) {
+ coord_group = group;
+ CCTK_GroupDynamicData (cctkGH, coord_group, &coord_group_data);
+ } else {
+ // check that group and coord_group have the same layout
+ cGroupDynamicData gdata;
+ CCTK_GroupDynamicData (cctkGH, group, &gdata);
+ const int size = gdata.dim * sizeof (int);
+ if (gdata.dim != coord_group_data.dim or
+ memcmp (gdata.lsh, coord_group_data.lsh, size) or
+ memcmp (gdata.lbnd, coord_group_data.lbnd, size) or
+ memcmp (gdata.ubnd, coord_group_data.ubnd, size) or
+ memcmp (gdata.bbox, coord_group_data.bbox, 2*size) or
+ memcmp (gdata.nghostzones, coord_group_data.nghostzones, size)) {
+ CCTK_VWarn (CCTK_WARN_ABORT, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "input array variable %d has different layout than "
+ "the underlying coordinate system", n);
+ }
+ }
+ }
+ assert (coord_group >= 0);
+
+ // check output arrays
+ assert (N_output_arrays > 0);
+ const int output_array_type = output_array_type_codes[0];
+ for (int n = 1; n < N_output_arrays; n++) {
+ if (output_array_type != output_array_type_codes[n]) {
+ CCTK_VWarn (CCTK_WARN_ABORT, __LINE__, __FILE__, CCTK_THORNSTRING,
+ "Currently all output arrays have have the same datatype. "
+ "Array 0 has type '%s' but array %d has type '%s'",
+ CCTK_VarTypeName (output_array_type), n,
+ CCTK_VarTypeName (output_array_type_codes[n]));
+ }
+ }
if (is_meta_mode()) {
@@ -215,11 +282,14 @@ namespace CarpetInterp {
assert (N_interp_points >= 0);
assert (coords_list);
- for (int d=0; d<dim; ++d) {
+ for (int d = 0; d < N_dims; ++d) {
assert (N_interp_points == 0 or coords_list[d]);
}
- assert (interp_coords_type_code == CCTK_VARIABLE_REAL);
+ if (interp_coords_type_code != CCTK_VARIABLE_REAL) {
+ CCTK_WARN (CCTK_WARN_ABORT, "CarpetInterp does not support interpolation "
+ "coordinates other than datatype CCTK_VARIABLE_REAL");
+ }
assert (N_output_arrays >= 0);
if (N_interp_points > 0) {
@@ -236,16 +306,18 @@ namespace CarpetInterp {
// Find range of refinement levels
assert (maps > 0);
for (int m=1; m<maps; ++m) {
- assert (vhh.at(0)->reflevels() == vhh.at(m)->reflevels());
+ assert (arrdata.at(coord_group).at(0).hh->reflevels() ==
+ arrdata.at(coord_group).at(m).hh->reflevels());
}
- int const minrl = want_global_mode ? 0 : reflevel;
- int const maxrl = want_global_mode ? vhh.at(0)->reflevels() : reflevel+1;
+ int const minrl = want_global_mode ? 0 : reflevel;
+ int const maxrl = want_global_mode ?
+ arrdata[coord_group][0].hh->reflevels() : reflevel+1;
// Find maximum number of components over all levels and maps
int maxncomps = 0;
for (int rl=minrl; rl<maxrl; ++rl) {
for (int m=0; m<maps; ++m) {
- maxncomps = max(maxncomps, vhh.at(m)->components(rl));
+ maxncomps = max(maxncomps, arrdata[coord_group][m].hh->components(rl));
}
}
@@ -282,13 +354,13 @@ namespace CarpetInterp {
vector<int> dstprocs (N_interp_points); // which processor owns point n
vector<int> allhomecnts ((maxrl-minrl) * maps * maxncomps * dist::size());
// number of points in component c
- vector<CCTK_REAL> coords_buffer (dim * N_interp_points);
+ vector<CCTK_REAL> coords_buffer (N_dims * N_interp_points);
// each point from coord_list is mapped onto the processor
// that owns it (dstprocs)
// also accumulate the number of points per processor (N_points_to)
- map_points (cctkGH,
- ml, minrl, maxrl, maxncomps, N_interp_points,
+ map_points (cctkGH, coord_system_handle, coord_group,
+ ml, minrl, maxrl, maxncomps, N_dims, N_interp_points,
source_map,
coords_list, coords_buffer,
dstprocs, N_points_to,
@@ -314,28 +386,28 @@ namespace CarpetInterp {
vector<int> recvdispl (dist::size());
// set up counts and displacements for MPI_Alltoallv()
- sendcnt[0] = dim * N_points_to[0];
- recvcnt[0] = dim * N_points_from[0];
+ sendcnt[0] = N_dims * N_points_to[0];
+ recvcnt[0] = N_dims * N_points_from[0];
senddispl[0] = recvdispl[0] = 0;
int N_points_local = recvcnt[0];
for (int p = 1; p < dist::size(); p++) {
- sendcnt[p] = dim * N_points_to[p];
- recvcnt[p] = dim * N_points_from[p];
+ sendcnt[p] = N_dims * N_points_to[p];
+ recvcnt[p] = N_dims * N_points_from[p];
N_points_local += recvcnt[p];
senddispl[p] = senddispl[p-1] + sendcnt[p-1];
recvdispl[p] = recvdispl[p-1] + recvcnt[p-1];
}
- assert (N_points_local % dim == 0);
+ assert (N_points_local % N_dims == 0);
// N_points_local is the total number of points to receive
// and thus the total number of points to interpolate on this processor
- N_points_local /= dim;
+ N_points_local /= N_dims;
// set up the per-component coordinates
// as offset into the single communication send buffer
vector<CCTK_REAL*> coords (allhomecnts.size());
int offset = 0;
for (int c = 0; c < allhomecnts.size(); c++) {
- coords[c] = &coords_buffer.front() + dim*offset;
+ coords[c] = &coords_buffer.front() + N_dims*offset;
offset += allhomecnts[c];
}
assert (offset == N_interp_points);
@@ -354,8 +426,8 @@ namespace CarpetInterp {
for (int n = 0; n < N_interp_points; n++) {
int const idx = component_idx (dstprocs[n], source_map[n], rlev[n],
home[n]);
- for (int d = 0; d < dim; d++) {
- coords[idx][d + dim*tmpcnts[idx]] =
+ for (int d = 0; d < N_dims; d++) {
+ coords[idx][d + N_dims*tmpcnts[idx]] =
static_cast<CCTK_REAL const *>(coords_list[d])[n];
}
indices[n] = totalhomecnts[idx] + tmpcnts[idx];
@@ -367,7 +439,7 @@ namespace CarpetInterp {
// send this processor's points to owning processors,
// receive other processors' points for interpolation on this processor
{
- vector<CCTK_REAL> tmp (dim * N_points_local);
+ vector<CCTK_REAL> tmp (N_dims * N_points_local);
MPI_Datatype const datatype = dist::datatype (tmp[0]);
MPI_Alltoallv (&coords_buffer[0], &sendcnt[0], &senddispl[0], datatype,
&tmp[0], &recvcnt[0], &recvdispl[0], datatype,
@@ -450,8 +522,8 @@ namespace CarpetInterp {
// (One could argue though that the per-point status codes as returned
// by the local interpolator could be used to determine the global
// interpolator return value instead.)
- map_points (cctkGH,
- ml, minrl, maxrl, maxncomps, N_points_local,
+ map_points (cctkGH, coord_system_handle, coord_group,
+ ml, minrl, maxrl, maxncomps, N_dims, N_points_local,
source_map,
NULL, coords_buffer,
srcprocs, N_points_to,
@@ -461,29 +533,32 @@ namespace CarpetInterp {
source_map.clear();
srcprocs.clear();
- // reorder the coordinates from <dim>-tupels into <dim> vectors
+ // reorder the coordinates from <N_dims>-tupels into <N_dims> vectors
// as expected by CCTK_InterpLocalUniform()
{
int offset = 0;
vector<CCTK_REAL> tmp (coords_buffer.size());
for (int c = 0; c < homecnts.size(); c++) {
for (int n = 0; n < homecnts[c]; n++) {
- for (int d = 0; d < dim; d++) {
- tmp[d*homecnts[c] + n + offset] = coords_buffer[n*dim + d + offset];
+ for (int d = 0; d < N_dims; d++) {
+ tmp[d*homecnts[c] + n + offset] = coords_buffer[n*N_dims + d + offset];
}
}
- offset += dim * homecnts[c];
+ offset += N_dims * homecnts[c];
}
- assert (offset == dim * N_points_local);
+ assert (offset == N_dims * N_points_local);
coords_buffer.swap (tmp);
}
//////////////////////////////////////////////////////////////////////
// Do the local interpolation on individual components
//////////////////////////////////////////////////////////////////////
- vector<CCTK_REAL> outputs_buffer (N_points_local * N_output_arrays);
- vector<CCTK_REAL*> outputs (homecnts.size());
- vector<CCTK_INT> status_and_retval_buffer (2 * dist::size());
+ const int vtype = output_array_type_codes[0];
+ const int vtypesize = CCTK_VarTypeSize (vtype);
+ assert (vtypesize > 0);
+ vector<char> outputs_buffer (N_points_local * N_output_arrays * vtypesize);
+ vector<char*> outputs (homecnts.size());
+ vector<CCTK_INT> status_and_retval_buffer (2 * dist::size());
CCTK_INT* per_proc_statuses = &status_and_retval_buffer.front();
CCTK_INT* per_proc_retvals = per_proc_statuses + dist::size();
@@ -491,14 +566,14 @@ namespace CarpetInterp {
// into the single communication buffers
offset = 0;
for (int c = 0; c < homecnts.size(); c++) {
- coords[c] = &coords_buffer.front() + dim*offset;
- outputs[c] = &outputs_buffer.front() + N_output_arrays*offset;
+ coords[c] = &coords_buffer.front() + N_dims*offset;
+ outputs[c] = &outputs_buffer.front() + N_output_arrays*offset*vtypesize;
offset += homecnts[c];
}
assert (offset == N_points_local);
interpolate_components
- (cctkGH,
+ (cctkGH, coord_system_handle, coord_group,
minrl, maxrl,
maxncomps,
want_global_mode,
@@ -509,7 +584,6 @@ namespace CarpetInterp {
operand_indices, time_deriv_order, have_time_derivs,
local_interp_handle, param_table_handle,
current_time, delta_time,
- interp_coords_type_code,
N_input_arrays, N_output_arrays,
output_array_type_codes, input_array_variable_indices);
@@ -534,8 +608,16 @@ namespace CarpetInterp {
}
{
- vector<CCTK_REAL> tmp (N_output_arrays * N_interp_points);
- MPI_Datatype const datatype = dist::datatype (tmp[0]);
+ MPI_Datatype datatype;
+ switch (vtype) {
+#define TYPECASE(N,T) \
+ case N: { T dummy; datatype = dist::datatype(dummy); } break;
+#include "carpet_typecase.hh"
+#undef TYPECASE
+ default: assert (0 and "invalid datatype");
+ }
+
+ vector<char> tmp (N_interp_points * N_output_arrays * vtypesize);
MPI_Alltoallv (&outputs_buffer[0], &sendcnt[0], &senddispl[0], datatype,
&tmp[0], &recvcnt[0], &recvdispl[0], datatype,
dist::comm);
@@ -568,11 +650,15 @@ namespace CarpetInterp {
}
for (int d = 0; d < N_output_arrays; d++) {
+ char* output_array = static_cast<char*>(output_arrays[d]);
for (int c = 0, i = 0, offset = 0; c < allhomecnts.size(); c++) {
- assert (allhomecnts[c]*(d+1) + offset <= outputs_buffer.size());
+ assert (allhomecnts[c]*(d+1) + offset <=
+ N_output_arrays*N_interp_points);
for (int n = 0; n < allhomecnts[c]; n++, i++) {
- static_cast<CCTK_REAL *>(output_arrays[d])[reverse_indices[i]] =
- outputs_buffer[allhomecnts[c]*d + offset + n];
+ memcpy (output_array + reverse_indices[i]*vtypesize,
+ &outputs_buffer.front() +
+ (allhomecnts[c]*d + offset + n) * vtypesize,
+ vtypesize);
}
offset += N_output_arrays * allhomecnts[c];
}
@@ -677,10 +763,13 @@ namespace CarpetInterp {
static void
map_points (cGH const* const cctkGH,
+ int const coord_system_handle,
+ int const coord_group,
int const ml,
int const minrl,
int const maxrl,
int const maxncomps,
+ int const N_dims,
int const npoints,
vector<CCTK_INT> const& source_map,
void const* const coords_list[],
@@ -694,7 +783,7 @@ namespace CarpetInterp {
bool const map_onto_processors = coords_list != NULL;
if (not map_onto_processors) {
- assert (coords.size() == dim * npoints);
+ assert (coords.size() == N_dims * npoints);
}
assert (procs.size() == npoints);
assert (N_points_to.size() == dist::size());
@@ -703,31 +792,29 @@ namespace CarpetInterp {
assert (source_map.size() == npoints);
- // Find out about the coordinates: origin and delta for the Carpet
- // grid indices
-#if 0
- const char * coord_system_name
- = CCTK_CoordSystemName (coord_system_handle);
- assert (coord_system_name);
- rvect lower, upper, delta;
- for (int d=0; d<dim; ++d) {
- ierr = CCTK_CoordRange
- (cctkGH, &lower[d], &upper[d], d+1, 0, coord_system_name);
- assert (!ierr);
- const ibbox & baseext = vhh.at(m)->baseextent;
- delta[d]
- = (upper[d] - lower[d]) / (baseext.upper()[d] - baseext.lower()[d]);
- }
-#else
+ // Find out about the coordinates: origin and delta
+ // for the Carpet grid indices
vector<rvect> lower (maps);
vector<rvect> delta (maps);
vector<rvect> upper (maps);
- for (int m=0; m<maps; ++m) {
- lower.at(m) = rvect::ref(cctkGH->cctk_origin_space);
- delta.at(m) = rvect::ref(cctkGH->cctk_delta_space) / maxspacereflevelfact;
- upper.at(m) = lower.at(m) + delta.at(m) * (vhh.at(m)->baseextent.upper() - vhh.at(m)->baseextent.lower());
+ rvect coord_lower, coord_upper;
+ const char* coord_system_name = CCTK_CoordSystemName (coord_system_handle);
+
+ for (int d = 0; d < N_dims; d++) {
+ const int iret = CCTK_CoordRange (cctkGH, &coord_lower[d],
+ &coord_upper[d], d+1,
+ NULL, coord_system_name);
+ assert (iret == 0);
+ }
+
+ for (int m = 0; m < maps; ++m) {
+ const ibbox& baseextent = arrdata.at(coord_group).at(m).hh->baseextent;
+ lower.at(m) = coord_lower;
+ delta.at(m) = (coord_upper - coord_lower) /
+ (baseextent.upper() * maxspacereflevelfact);
+ upper.at(m) = lower.at(m) +
+ delta.at(m) * (baseextent.upper() - baseextent.lower());
}
-#endif
// Assign interpolation points to processors/components
for (int n = 0; n < npoints; ++n) {
@@ -736,11 +823,11 @@ namespace CarpetInterp {
// Find the grid point closest to the interpolation point
rvect pos;
- for (int d = 0; d < dim; ++d) {
+ for (int d = 0; d < N_dims; ++d) {
if (map_onto_processors) {
pos[d] = static_cast<CCTK_REAL const *>(coords_list[d])[n];
} else {
- pos[d] = coords[dim*n + d];
+ pos[d] = coords[N_dims*n + d];
}
}
@@ -753,11 +840,12 @@ namespace CarpetInterp {
ipow(mgfact, mglevel);
ivect const ipos = ivect(floor((pos - lower.at(m)) / (delta.at(m) *
fact) + 0.5)) * fact;
- assert (all (ipos % vhh.at(m)->bases().at(ml).at(rl).stride() == 0));
+ const gh* hh = arrdata[coord_group][m].hh;
+ assert (all (ipos % hh->bases().at(ml).at(rl).stride() == 0));
// TODO: use something faster than a linear search
- for (c = 0; c < vhh.at(m)->components(rl); ++c) {
- if (vhh.at(m)->extents().at(ml).at(rl).at(c).contains(ipos)) {
+ for (c = 0; c < hh->components(rl); ++c) {
+ if (hh->extents().at(ml).at(rl).at(c).contains(ipos)) {
goto found;
}
}
@@ -776,10 +864,10 @@ namespace CarpetInterp {
}
found:
assert (rl >= minrl and rl < maxrl);
- assert (c >= 0 and c < vhh.at(m)->components(rl));
+ assert (c >= 0 and c < arrdata[coord_group][m].hh->components(rl));
if (map_onto_processors) {
- procs[n] = vhh.at(m)->proc(rl, c);
+ procs[n] = arrdata[coord_group][m].hh->proc(rl, c);
++ N_points_to[procs[n]];
}
rlev[n] = rl;
@@ -792,6 +880,8 @@ namespace CarpetInterp {
static void
interpolate_components (cGH const* const cctkGH,
+ int const coord_system_handle,
+ int const coord_group,
int const minrl,
int const maxrl,
int const maxncomps,
@@ -800,7 +890,7 @@ namespace CarpetInterp {
int const N_dims,
vector<int> & homecnts,
vector<CCTK_REAL*>& coords,
- vector<CCTK_REAL*>& outputs,
+ vector<char*>& outputs,
CCTK_INT* const per_proc_statuses,
CCTK_INT* const per_proc_retvals,
vector<CCTK_INT>& operand_indices,
@@ -810,7 +900,6 @@ namespace CarpetInterp {
CCTK_INT const param_table_handle,
CCTK_REAL const current_time,
CCTK_REAL const delta_time,
- int const interp_coords_type_code,
int const N_input_arrays,
int const N_output_arrays,
CCTK_INT const output_array_type_codes [],
@@ -855,7 +944,7 @@ namespace CarpetInterp {
int const idx = component_idx (p, Carpet::map,reflevel,component);
if (homecnts[idx] > 0) {
interpolate_single_component
- (cctkGH,
+ (cctkGH, coord_system_handle, coord_group,
minrl, maxrl, maxncomps, N_dims,
homecnts[idx], coords[idx], outputs[idx],
per_proc_statuses[p], per_proc_retvals[p],
@@ -863,7 +952,7 @@ namespace CarpetInterp {
local_interp_handle, param_table_handle,
num_tl, need_time_interp, current_time, delta_time,
N_input_arrays, N_output_arrays,
- interp_coords_type_code, output_array_type_codes,
+ output_array_type_codes,
input_array_variable_indices);
}
}
@@ -1025,13 +1114,15 @@ namespace CarpetInterp {
static void
interpolate_single_component (cGH const* const cctkGH,
+ int const coord_system_handle,
+ int const coord_group,
int const minrl,
int const maxrl,
int const maxncomps,
int const N_dims,
int const npoints,
CCTK_REAL const* const coords,
- CCTK_REAL* const outputs,
+ char* const outputs,
CCTK_INT& overall_status,
CCTK_INT& overall_retval,
vector<CCTK_INT>& operand_indices,
@@ -1045,54 +1136,58 @@ namespace CarpetInterp {
CCTK_REAL const delta_time,
int const N_input_arrays,
int const N_output_arrays,
- int const interp_coords_type_code,
CCTK_INT const output_array_type_codes [],
CCTK_INT const input_array_variable_indices [])
{
- // Find out about the local geometry
- ivect lsh;
- rvect coord_origin, coord_delta;
- for (int d=0; d<dim; ++d) {
- lsh[d] = cctkGH->cctk_lsh[d];
- coord_delta[d] = cctkGH->cctk_delta_space[d] / cctkGH->cctk_levfac[d];
- coord_origin[d] = cctkGH->cctk_origin_space[d] + (cctkGH->cctk_lbnd[d] + 1.0 * cctkGH->cctk_levoff[d] / cctkGH->cctk_levoffdenom[d]) * coord_delta[d];
- }
-
- // Find out about the grid functions
- vector<CCTK_INT> input_array_type_codes(N_input_arrays);
+ // Find out the datatypes of all input grid arrays
+ vector<CCTK_INT> input_array_type_codes(N_input_arrays, -1);
vector<const void *> input_arrays(N_input_arrays);
- for (int n=0; n<N_input_arrays; ++n) {
- if (input_array_variable_indices[n] == -1) {
-
- // Ignore this entry
- input_array_type_codes.at(n) = -1;
-
- } else {
-
- int const vi = input_array_variable_indices[n];
- assert (vi>=0 and vi<CCTK_NumVars());
-
- int const gi = CCTK_GroupIndexFromVarI (vi);
- assert (gi>=0 and gi<CCTK_NumGroups());
-
- cGroup group;
- int ierr = CCTK_GroupData (gi, &group);
- assert (!ierr);
- assert (group.grouptype == CCTK_GF);
- assert (group.dim == dim);
- assert (group.disttype == CCTK_DISTRIB_DEFAULT);
- assert (group.stagtype == 0); // not staggered
-
- input_array_type_codes.at(n) = group.vartype;
-
+ for (int n = 0; n < N_input_arrays; ++n) {
+ if (input_array_variable_indices[n] >= 0) {
+ input_array_type_codes[n] =
+ CCTK_VarTypeI (input_array_variable_indices[n]);
}
- } // for input arrays
+ }
+
+ // Do the processor-local interpolation
+ // Find out about the local geometry
+ rvect coord_origin, coord_delta;
+ // get global origin and spacing of the underlying coordinate system
+#ifdef NEW_COORD_API
+ const iret1 = Util_TableGetRealArray (coord_system_handle, N_dims,
+ &coord_origin[0], "COMPMIN");
+ const iret2 = Util_TableGetRealArray (coord_system_handle, N_dims,
+ &coord_delta[0], "DELTA");
+ assert (iret1 == N_dims and iret2 == N_dims);
+#else
+ const char* coord_system_name = CCTK_CoordSystemName(coord_system_handle);
+ assert (CCTK_CoordSystemDim (coord_system_name) >= N_dims);
+
+ rvect lower, upper;
+ for (int d = 0; d < N_dims; d++) {
+ const int iret = CCTK_CoordRange (cctkGH, &lower[d], &upper[d], d+1,
+ NULL, coord_system_name);
+ assert (iret == 0);
+ }
+ const ibbox& baseextent =
+ arrdata.at(coord_group).at(Carpet::map).hh->baseextent;
+ coord_origin = lower;
+ coord_delta = (upper - lower) / baseextent.upper();
+#endif
+ // get processor-local origin and spacing
+ cGroupDynamicData coord_group_data;
+ CCTK_GroupDynamicData (cctkGH, coord_group, &coord_group_data);
+ for (int d = 0; d < N_dims; ++d) {
+ coord_delta[d] /= cctkGH->cctk_levfac[d];
+ coord_origin[d] += (coord_group_data.lbnd[d] +
+ cctkGH->cctk_levoff[d] / cctkGH->cctk_levoffdenom[d])
+ * coord_delta[d];
+ }
- // Do the processor-local interpolation
void const* tmp_coords[dim];
- for (int d = 0; d < dim; ++d) {
+ for (int d = 0; d < N_dims; ++d) {
tmp_coords[d] = coords + d*npoints;
}
@@ -1106,7 +1201,7 @@ namespace CarpetInterp {
assert (vi >= 0 and vi < CCTK_NumVars());
if (vi == -1) {
- input_arrays.at(n) = NULL;
+ input_arrays[n] = NULL;
} else {
int const interp_num_tl = interp_num_time_levels[n] > 0 ?
interp_num_time_levels[n] : num_tl;
@@ -1115,24 +1210,29 @@ namespace CarpetInterp {
// if the desired timelevel does not exist
int const my_tl = tl >= interp_num_tl ? 0 : tl;
#if 0
- input_arrays.at(n) = CCTK_VarDataPtrI (cctkGH, my_tl, vi);
+ input_arrays[n] = CCTK_VarDataPtrI (cctkGH, my_tl, vi);
#else
int const gi = CCTK_GroupIndexFromVarI (vi);
int const vi0 = CCTK_FirstVarIndexI (gi);
- input_arrays.at(n)
+ input_arrays[n]
= ((*arrdata.at(gi).at(Carpet::map).data.at(vi-vi0))
(my_tl, reflevel, component, mglevel)->storage());
#endif
}
} // for input arrays
- tmp_output_arrays.at(tl).resize (N_output_arrays);
+ tmp_output_arrays[tl].resize (N_output_arrays);
for (int j=0; j<N_output_arrays; ++j) {
- assert (output_array_type_codes[j] == CCTK_VARIABLE_REAL);
if (need_time_interp) {
- tmp_output_arrays.at(tl).at(j) = new CCTK_REAL [npoints];
+ if (output_array_type_codes[j] != CCTK_VARIABLE_REAL) {
+ CCTK_WARN (CCTK_WARN_ABORT,
+ "time interpolation into output arrays of datatype "
+ "other than CCTK_VARIABLE_REAL is not supported");
+ }
+ tmp_output_arrays[tl][j] = new CCTK_REAL [npoints];
} else {
- tmp_output_arrays.at(tl).at(j) = outputs + j*npoints;
+ const int vartypesize = CCTK_VarTypeSize (output_array_type_codes[j]);
+ tmp_output_arrays[tl][j] = outputs + j*npoints*vartypesize;
}
}
@@ -1141,15 +1241,15 @@ namespace CarpetInterp {
(param_table_handle, &per_point_status.front(), "per_point_status");
assert (ierr >= 0);
- int retval = CCTK_InterpLocalUniform
+ const int retval = CCTK_InterpLocalUniform
(N_dims, local_interp_handle, param_table_handle,
&coord_origin[0], &coord_delta[0],
npoints,
- interp_coords_type_code, tmp_coords,
- N_input_arrays, &lsh[0],
- &input_array_type_codes[0], &input_arrays[0],
+ CCTK_VARIABLE_REAL, tmp_coords,
+ N_input_arrays, coord_group_data.lsh,
+ &input_array_type_codes.front(), &input_arrays.front(),
N_output_arrays,
- output_array_type_codes, &tmp_output_arrays.at(tl)[0]);
+ output_array_type_codes, &tmp_output_arrays[tl].front());
if (retval) {
CCTK_VWarn (CCTK_WARN_DEBUG, __LINE__, __FILE__, CCTK_THORNSTRING,
"The local interpolator returned the error code %d",retval);
@@ -1176,15 +1276,18 @@ namespace CarpetInterp {
int const interp_num_tl = interp_num_time_levels.at(n) > 0 ?
interp_num_time_levels.at(n) : num_tl;
const InterpolationTimes times (interp_num_tl);
- const InterpolationWeights tfacs (deriv_order, times, current_time, delta_time);
+ const InterpolationWeights tfacs (deriv_order, times, current_time,
+ delta_time);
// Interpolate
assert (output_array_type_codes[j] == CCTK_VARIABLE_REAL);
for (int k=0; k<npoints; ++k) {
- CCTK_REAL & dest = outputs[k + j*npoints];
+ CCTK_REAL& dest =
+ static_cast<CCTK_REAL*>(static_cast<void*>(outputs))[k + j*npoints];
dest = 0;
for (int tl = 0; tl < interp_num_tl; ++tl) {
- CCTK_REAL const src = ((CCTK_REAL const *)tmp_output_arrays.at(tl).at(j))[k];
+ CCTK_REAL const src =
+ ((CCTK_REAL const *)tmp_output_arrays[tl][j])[k];
dest += tfacs[tl] * src;
}
}
@@ -1193,7 +1296,7 @@ namespace CarpetInterp {
for (int tl=0; tl<num_tl; ++tl) {
for (int j=0; j<N_output_arrays; ++j) {
- delete [] (CCTK_REAL *)tmp_output_arrays.at(tl).at(j);
+ delete [] (CCTK_REAL *)tmp_output_arrays[tl][j];
}
}