aboutsummaryrefslogtreecommitdiff
path: root/src/GeneralizedPolynomial-Uniform/InterpLocalUniform.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/GeneralizedPolynomial-Uniform/InterpLocalUniform.c')
-rw-r--r--src/GeneralizedPolynomial-Uniform/InterpLocalUniform.c293
1 files changed, 198 insertions, 95 deletions
diff --git a/src/GeneralizedPolynomial-Uniform/InterpLocalUniform.c b/src/GeneralizedPolynomial-Uniform/InterpLocalUniform.c
index 56f386a..1f63a03 100644
--- a/src/GeneralizedPolynomial-Uniform/InterpLocalUniform.c
+++ b/src/GeneralizedPolynomial-Uniform/InterpLocalUniform.c
@@ -38,7 +38,7 @@
#include "Hermite/all_prototypes.h"
/* the rcs ID and its dummy function to use it */
-static const char *rcsid = "$Header$";
+static const char* rcsid = "$Header$";
CCTK_FILEVERSION(CactusBase_LocalInterp_src_GeneralizedPolynomialUniform_InterpLocalUniform_c)
/******************************************************************************/
@@ -231,8 +231,20 @@ return LocalInterp_InterpLocalUniform(interp_operator_Hermite,
and calls the appropriate subfunction to do the actual
interpolation, then finally stores some results back in
the parameter table.
+
+ FIXME:
+ This function is huge, and should be split up into
+ reasonable-sized subfunctions.
@enddesc
+ @hdate 28.Jan.2003
+ @hauthor Jonathan Thornburg <jthorn@aei.mpg.de>
+ @hdesc Support parameter-table entries
+ @var N_boundary_points_to_omit,
+ @var boundary_off_centering_tolerance, and
+ @var boundary_extrapolation_tolerance.
+ @endhdesc
+
***** misc arguments *****
@var interp_operator
@@ -349,26 +361,43 @@ return LocalInterp_InterpLocalUniform(interp_operator_Hermite,
@vtype CCTK_INT order
@endvar
- @var out_of_range_tolerance
- @vdesc Specifies how out-of-range interpolation points should
- be handled. The array elements are matched up with
- the axes and minimum/maximum ends of the grid in the
+ @var N_boundary_points_to_omit
+ @vdesc If this key is present, then this array specifies how many
+ input grid points to omit (not use for the interpolation)
+ on each grid boundary. The array elements are matched up
+ with the axes and minimum/maximum ends of the grid in the
order [x_min, x_max, y_min, y_max, z_min, z_max, ...].
- An array value TOL is interpreted as follows:
- If TOL >= 0.0,
- then an interpolation point is considered to be
- "out of range" if and only if the interpolation
- point is > TOL * coord_delta[axis]
- outside the grid in this coordinate direction.
- If TOL == -1.0,
- then an interpolation point is considered to be
- "out of range" if and only if a centered molecule
- (or more generally, a molecule whose centering
- is chosen pretending that the grid is of infinite
- extent), would require data from outside the grid
- in this direction.
- Other values of TOL are illegal.
- @vtype const CCTK_REAL out_of_range_tolerance[2*N_dims]
+ If this key isn't present, it defaults to all zeros, i.e.
+ to use all the input grid points in the interpolation.
+ @vtype const CCTK_INT N_boundary_points_to_omit[2*N_dims]
+ @endvar
+
+ @var boundary_off_centering_tolerance
+ @vdesc If this key is present, then the interpolator allows
+ interpolation points to be up to (<=) this many grid
+ spacings outside the default-centering region on each
+ grid boundary, off-centering the interpolation molecules
+ as necessary.
+ The array elements are matched up with the axes and
+ minimum/maximum ends of the grid in the order
+ [x_min, x_max, y_min, y_max, z_min, z_max, ...].
+ If this key isn't present, it defaults to all infinities,
+ i.e. to place no restriction on the interpolation point.
+ @vtype const CCTK_REAL boundary_off_centering_tolerance[2*N_dims]
+ @endvar
+
+ @var boundary_extrapolation_tolerance
+ @vdesc If this key is present, then the interpolator allows
+ interpolation points to be up to (<=) this many grid
+ spacings outside the valid-data region on each grid
+ boundary, doing extrapolation instead of interpolation
+ as necessary.
+ The array elements are matched up with the axes and
+ minimum/maximum ends of the grid in the order
+ [x_min, x_max, y_min, y_max, z_min, z_max, ...].
+ If this key isn't present, it defaults to all 1.0e-10,
+ i.e. to allow up to 1e-10 grid spacings of extrapolation.
+ @vtype const CCTK_REAL boundary_extrapolation_tolerance[2*N_dims]
@endvar
@var input_array_offsets
@@ -625,7 +654,7 @@ static
* would falsely detect as an out-of-memory condition.
*
* As a workaround, we pad all our malloc request sizes, i.e.
- * CCTK_INT *const p = malloc((N+1) * sizeof(CCTK_INT));
+ * CCTK_INT* const p = (CCTK_INT*) malloc((N+1) * sizeof(CCTK_INT));
* if (p == NULL)
* then return UTIL_ERROR_NO_MEMORY
* This is a kludge, but so are the other plausible solutions. :( :(
@@ -657,7 +686,7 @@ if ( (N_dims <= 0)
then {
CCTK_VWarn(ERROR_MSG_SEVERITY_LEVEL,
__LINE__, __FILE__, CCTK_THORNSTRING,
-"InterpLocalUniform(): invalid arguments\n"
+"CCTK_InterpLocalUniform(): invalid arguments\n"
" (N_dims <= 0, param_table_handle < 0, N_input_arrays < 0,\n"
" N_output_arrays < 0, and/or NULL pointers-that-shouldn't-be-NULL)!");
return UTIL_ERROR_BAD_INPUT; /*** ERROR RETURN ***/
@@ -684,14 +713,14 @@ if (N_dims > MAX_N_DIMS)
CCTK_INT order;
status = Util_TableGetInt(param_table_handle, &order, "order");
if (status == 1)
- then { } /* ok ==> no-op here */
+ then { } /* value set from table ==> no-op here */
else {
/* n.b. order is a mandatory parameter (no default)!*/
CCTK_VWarn(ERROR_MSG_SEVERITY_LEVEL,
__LINE__, __FILE__, CCTK_THORNSTRING,
"\n"
-" CCTK_InterpLocalUniform(): bad or missing table entry\n"
-" for \"order\" parameter!\n"
+" CCTK_InterpLocalUniform(): bad or missing table entry for\n"
+" \"order\" parameter!\n"
" (this is a mandatory parameter)\n"
" error status=%d",
status);
@@ -708,59 +737,122 @@ if ((order < 1) || (order > MAX_ORDER))
MAX_ORDER);
return UTIL_ERROR_BAD_INPUT; /*** ERROR RETURN ***/
}
-
+
+/******************************************************************************/
/*
* out-of-range interpolation-point handling
*/
{
-CCTK_REAL out_of_range_tolerance[2*MAX_N_DIMS];
-const int N_tolerances = 2*N_dims;
-status = Util_TableGetRealArray(param_table_handle,
- N_tolerances, out_of_range_tolerance,
- "out_of_range_tolerance");
+CCTK_INT N_boundary_points_to_omit[MAX_N_BOUNDARIES];
+CCTK_REAL boundary_off_centering_tolerance[MAX_N_BOUNDARIES];
+CCTK_REAL boundary_extrapolation_tolerance[MAX_N_BOUNDARIES];
+const int N_boundaries = 2*N_dims;
+
+status = Util_TableGetIntArray(param_table_handle,
+ N_boundaries, N_boundary_points_to_omit,
+ "N_boundary_points_to_omit");
if (status == UTIL_ERROR_TABLE_NO_SUCH_KEY)
then {
- /* default */
- int tol_index;
- for (tol_index = 0 ; tol_index < N_tolerances ; ++tol_index)
+ /* set the default value */
+ int ibndry;
+ for (ibndry = 0 ; ibndry < N_boundaries ; ++ibndry)
{
- out_of_range_tolerance[tol_index]
- = OUT_OF_RANGE_TOLERANCE_DEFAULT;
+ N_boundary_points_to_omit[ibndry] = 0;
}
}
-else if (status == N_tolerances)
+else if (status == N_boundaries)
+ then { } /* value set from table ==> no-op here */
+else {
+ CCTK_VWarn(ERROR_MSG_SEVERITY_LEVEL,
+ __LINE__, __FILE__, CCTK_THORNSTRING,
+"\n"
+" CCTK_InterpLocalUniform(): bad table entry for\n"
+" \"N_boundary_points_to_omit\" parameter!\n"
+" error status=%d",
+ status);
+ return status; /*** ERROR RETURN ***/
+ }
+
+/**************************************/
+
+status = Util_TableGetRealArray(param_table_handle,
+ N_boundaries, boundary_off_centering_tolerance,
+ "boundary_off_centering_tolerance");
+if (status == UTIL_ERROR_TABLE_NO_SUCH_KEY)
then {
- /* check that all values are valid */
- int tol_index;
- for (tol_index = 0 ; tol_index < N_tolerances ; ++tol_index)
+ /* set the default value */
+ int ibndry;
+ for (ibndry = 0 ; ibndry < N_boundaries ; ++ibndry)
{
- if (! ( (out_of_range_tolerance[tol_index] >= 0.0)
- || (out_of_range_tolerance[tol_index] == -1.0) ) )
- then {
- CCTK_VWarn(ERROR_MSG_SEVERITY_LEVEL,
- __LINE__, __FILE__, CCTK_THORNSTRING,
+ boundary_off_centering_tolerance[ibndry]
+ = BOUNDARY_OFF_CENTER_TOL_DEFAULT;
+ }
+ }
+else if (status == N_boundaries)
+ then { } /* value set from table ==> no-op here */
+else {
+ CCTK_VWarn(ERROR_MSG_SEVERITY_LEVEL,
+ __LINE__, __FILE__, CCTK_THORNSTRING,
"\n"
-" CCTK_InterpLocalUniform():\n"
-" invalid out_of_range_tolerance[tol_index=%d] = %g!\n"
-" (valid values are -1.0 or >= 0.0)",
- tol_index,
- out_of_range_tolerance[tol_index]);
- return UTIL_ERROR_BAD_INPUT; /*** ERROR RETURN ***/
- }
+" CCTK_InterpLocalUniform(): bad table entry for\n"
+" \"boundary_off_centering_tolerance\" parameter!\n"
+" error status=%d",
+ status);
+ return status; /*** ERROR RETURN ***/
+ }
+
+/**************************************/
+
+status = Util_TableGetRealArray(param_table_handle,
+ N_boundaries, boundary_extrapolation_tolerance,
+ "boundary_extrapolation_tolerance");
+if (status == UTIL_ERROR_TABLE_NO_SUCH_KEY)
+ then {
+ /* set the default value */
+ int ibndry;
+ for (ibndry = 0 ; ibndry < N_boundaries ; ++ibndry)
+ {
+ boundary_extrapolation_tolerance[ibndry]
+ = BOUNDARY_EXTRAP_TOL_DEFAULT;
}
}
+else if (status == N_boundaries)
+ then { } /* value set from table ==> no-op here */
else {
CCTK_VWarn(ERROR_MSG_SEVERITY_LEVEL,
__LINE__, __FILE__, CCTK_THORNSTRING,
"\n"
-" CCTK_InterpLocalUniform(): bad table entry\n"
-" for \"out_of_range_tolerance\" parameter!\n"
+" CCTK_InterpLocalUniform(): bad table entry for\n"
+" \"boundary_extrapolation_tolerance\" parameter!\n"
" error status=%d",
status);
return status; /*** ERROR RETURN ***/
}
+/* check for almost-always-a-mistake settings, warn if found */
+ {
+int ibndry;
+ for (ibndry = 0 ; ibndry < N_boundaries ; ++ibndry)
+ {
+ if ( (boundary_off_centering_tolerance[ibndry] == 0.0)
+ && (boundary_extrapolation_tolerance[ibndry] > 0.0) )
+ then CCTK_VWarn(WARNING_MSG_SEVERITY_LEVEL,
+ __LINE__, __FILE__, CCTK_THORNSTRING,
+"\n"
+" CCTK_InterpLocalUniform(): warning: setting\n"
+" boundary_off_centering_tolerance[%d] == 0.0\n"
+" and\n"
+" boundary_extrapolation_tolerance[%d] > 0.0\n"
+" is almost certainly a mistake\n"
+" (the boundary_extrapolation_tolerance[%d]\n"
+" setting will have no effect because of the\n"
+" boundary_off_centering_tolerance[%d] setting)"
+ ,
+ ibndry, ibndry, ibndry, ibndry);
+ }
+ }
+
/******************************************************************************/
/*
@@ -768,23 +860,23 @@ else {
*/
{
#define MOLECULE_FAMILY_BUFSIZ (MAX_MOLECULE_FAMILY_STRLEN+1)
-char molecule_family_string[MOLECULE_FAMILY_BUFSIZ];
+char molecule_family_strbuf[MOLECULE_FAMILY_BUFSIZ];
+char* molecule_family_str = molecule_family_strbuf;
enum molecule_family molecule_family;
status = Util_TableGetString(param_table_handle,
- MOLECULE_FAMILY_BUFSIZ, molecule_family_string,
+ MOLECULE_FAMILY_BUFSIZ, molecule_family_strbuf,
"molecule_family");
if (status == UTIL_ERROR_TABLE_NO_SUCH_KEY)
then {
- /* default */
+ /* set the default value for code here*/
/* (need enum for main code, string for error messages) */
- strcpy(molecule_family_string, "cube");
- molecule_family = molecule_family_cube;
- }
-else if (status == 0)
- then {
- /* this is a query of our default molecule family */
+ molecule_family = molecule_family_cube;
+ molecule_family_str = "cube";
+
+ /* set this key in the parameter table */
+ /* to give the (default) molecule family we're going to use */
status = Util_TableSetString(param_table_handle,
- "cube",
+ molecule_family_str,
"molecule_family");
if (status < 0)
then {
@@ -801,13 +893,13 @@ else if (status == 0)
else if (status > 0)
then {
/* decode molecule family string */
- if (strcmp(molecule_family_string, "cube") == 0)
+ if (strcmp(molecule_family_strbuf, "cube") == 0)
then molecule_family = molecule_family_cube;
else {
CCTK_VWarn(ERROR_MSG_SEVERITY_LEVEL,
__LINE__, __FILE__, CCTK_THORNSTRING,
-"InterpLocalUniform(): unknown molecule_family=\"%s\"!",
- molecule_family_string);
+"CCTK_InterpLocalUniform(): unknown molecule_family=\"%s\"!",
+ molecule_family_strbuf);
return UTIL_ERROR_BAD_INPUT; /*** ERROR RETURN ***/
}
}
@@ -815,13 +907,15 @@ else {
CCTK_VWarn(ERROR_MSG_SEVERITY_LEVEL,
__LINE__, __FILE__, CCTK_THORNSTRING,
"\n"
-" CCTK_InterpLocalUniform(): bad table entry\n"
-" for \"molecule_family\" parameter!\n"
+" CCTK_InterpLocalUniform(): bad table entry for\n"
+" \"molecule_family\" parameter!\n"
" error status=%d",
status);
return status; /*** ERROR RETURN ***/
}
+/**************************************/
+
/*
* smoothing
*/
@@ -829,14 +923,15 @@ else {
CCTK_INT smoothing;
status = Util_TableGetInt(param_table_handle, &smoothing, "smoothing");
if (status == UTIL_ERROR_TABLE_NO_SUCH_KEY)
- then smoothing = 0; /* default */
+ then smoothing = 0; /* set default value */
else if (status == 1)
then { } /* value set from table ==> no-op here */
else {
CCTK_VWarn(ERROR_MSG_SEVERITY_LEVEL,
__LINE__, __FILE__, CCTK_THORNSTRING,
"\n"
-" CCTK_InterpLocalUniform(): bad table entry for \"smoothing\" parameter!\n"
+" CCTK_InterpLocalUniform(): bad table entry for\n"
+" \"smoothing\" parameter!\n"
" error status=%d",
status);
return status; /*** ERROR RETURN ***/
@@ -850,8 +945,8 @@ if ((smoothing < 0) || (smoothing > MAX_SMOOTHING))
* input array offsets
*/
{
-CCTK_INT *const input_array_offsets
- = malloc(N_input_arrays1 * sizeof(CCTK_INT));
+CCTK_INT* const input_array_offsets
+ = (CCTK_INT*) malloc(N_input_arrays1 * sizeof(CCTK_INT));
if (input_array_offsets == NULL)
then return UTIL_ERROR_NO_MEMORY; /*** ERROR RETURN ***/
status = Util_TableGetIntArray(param_table_handle,
@@ -869,13 +964,15 @@ else {
CCTK_VWarn(ERROR_MSG_SEVERITY_LEVEL,
__LINE__, __FILE__, CCTK_THORNSTRING,
"\n"
-" CCTK_InterpLocalUniform(): bad table entry\n"
-" for \"input_array_offsets\" parameter!\n"
+" CCTK_InterpLocalUniform(): bad table entry for\n"
+" \"input_array_offsets\" parameter!\n"
" error status=%d",
status);
return status; /*** ERROR RETURN ***/
}
+/**************************************/
+
/*
* input array strides
*/
@@ -915,13 +1012,15 @@ else {
CCTK_VWarn(ERROR_MSG_SEVERITY_LEVEL,
__LINE__, __FILE__, CCTK_THORNSTRING,
"\n"
-" CCTK_InterpLocalUniform(): bad table entry\n"
-" for \"input_array_offsets\" parameter!\n"
+" CCTK_InterpLocalUniform(): bad table entry for\n"
+" \"input_array_offsets\" parameter!\n"
" error status=%d",
status);
return status; /*** ERROR RETURN ***/
}
+/**************************************/
+
/*
* input array min/max subscripts
*/
@@ -942,8 +1041,8 @@ else {
CCTK_VWarn(ERROR_MSG_SEVERITY_LEVEL,
__LINE__, __FILE__, CCTK_THORNSTRING,
"\n"
-" CCTK_InterpLocalUniform(): bad table entry\n"
-" for \"input_array_min_subscripts\" parameter!\n"
+" CCTK_InterpLocalUniform(): bad table entry for\n"
+" \"input_array_min_subscripts\" parameter!\n"
" error status=%d",
status);
return status; /*** ERROR RETURN ***/
@@ -981,8 +1080,8 @@ else {
CCTK_VWarn(ERROR_MSG_SEVERITY_LEVEL,
__LINE__, __FILE__, CCTK_THORNSTRING,
"\n"
-" CCTK_InterpLocalUniform(): bad table entry\n"
-" for \"input_array_max_subscripts\" parameter!\n"
+" CCTK_InterpLocalUniform(): bad table entry for\n"
+" \"input_array_max_subscripts\" parameter!\n"
" error status=%d",
status);
return status; /*** ERROR RETURN ***/
@@ -994,8 +1093,8 @@ else {
* operand indices
*/
{
-CCTK_INT *const operand_indices
- = malloc(N_output_arrays1 * sizeof(CCTK_INT));
+CCTK_INT* const operand_indices
+ = (CCTK_INT*) malloc(N_output_arrays1 * sizeof(CCTK_INT));
if (operand_indices == NULL)
then {
free(input_array_offsets);
@@ -1059,19 +1158,21 @@ else {
CCTK_VWarn(ERROR_MSG_SEVERITY_LEVEL,
__LINE__, __FILE__, CCTK_THORNSTRING,
"\n"
-" CCTK_InterpLocalUniform(): bad table entry\n"
-" for \"operand_indices\" parameter!\n"
+" CCTK_InterpLocalUniform(): bad table entry for\n"
+" \"operand_indices\" parameter!\n"
" error status=%d",
status);
return status; /*** ERROR RETURN ***/
}
+/**************************************/
+
/*
* operation_codes
*/
{
-CCTK_INT *const operation_codes
- = malloc(N_output_arrays1 * sizeof(CCTK_INT));
+CCTK_INT* const operation_codes
+ = (CCTK_INT*) malloc(N_output_arrays1 * sizeof(CCTK_INT));
if (operation_codes == NULL)
then {
free(operand_indices);
@@ -1110,8 +1211,8 @@ else {
CCTK_VWarn(ERROR_MSG_SEVERITY_LEVEL,
__LINE__, __FILE__, CCTK_THORNSTRING,
"\n"
-" CCTK_InterpLocalUniform(): bad table entry\n"
-" for \"operation_codes\" parameter!\n"
+" CCTK_InterpLocalUniform(): bad table entry for\n"
+" \"operation_codes\" parameter!\n"
" error status=%d",
status);
return status; /*** ERROR RETURN ***/
@@ -1223,7 +1324,7 @@ if (status)
then {
/* yes, we're doing Jacobian queries */
Jacobian_info.Jacobian_pointer
- = (CCTK_REAL **) malloc(N_output_arrays1 * sizeof(CCTK_REAL *));
+ = (CCTK_REAL**) malloc(N_output_arrays1 * sizeof(CCTK_REAL *));
if (Jacobian_info.Jacobian_pointer == NULL)
then {
free(operation_codes);
@@ -1232,8 +1333,8 @@ if (status)
return UTIL_ERROR_NO_MEMORY; /*** ERROR RETURN ***/
}
{
- CCTK_POINTER *Jacobian_pointer_temp
- = (CCTK_POINTER *) malloc(N_output_arrays1 * sizeof(CCTK_POINTER));
+ CCTK_POINTER* Jacobian_pointer_temp
+ = (CCTK_POINTER*) malloc(N_output_arrays1 * sizeof(CCTK_POINTER));
if (Jacobian_pointer_temp == NULL)
then {
free(operation_codes);
@@ -1276,7 +1377,7 @@ if (status)
}
Jacobian_info.Jacobian_offset
- = (CCTK_INT *) malloc(N_output_arrays1 * sizeof(CCTK_INT));
+ = (CCTK_INT*) malloc(N_output_arrays1 * sizeof(CCTK_INT));
if (Jacobian_info.Jacobian_offset == NULL)
then {
free(operation_codes);
@@ -1550,7 +1651,7 @@ if (p_interp_fn == NULL_INTERP_FN_PTR)
" interp_operator=\"%s\", N_dims=%d\n"
" molecule_family=\"%s\", order=%d, smoothing=%d",
interp_operator_string, N_dims,
- molecule_family_string, order, smoothing);
+ molecule_family_str, order, smoothing);
return UTIL_ERROR_BAD_INPUT; /*** ERROR RETURN ***/
}
@@ -1564,7 +1665,9 @@ const int return_code
= (*p_interp_fn)(coord_origin, coord_delta,
N_interp_points,
interp_coords_type_code, interp_coords,
- out_of_range_tolerance,
+ N_boundary_points_to_omit,
+ boundary_off_centering_tolerance,
+ boundary_extrapolation_tolerance,
N_input_arrays,
input_array_offsets, input_array_strides,
input_array_min_subscripts,