aboutsummaryrefslogtreecommitdiff
path: root/src/gr
diff options
context:
space:
mode:
authorjthorn <jthorn@f88db872-0e4f-0410-b76b-b9085cfa78c5>2003-02-15 18:43:08 +0000
committerjthorn <jthorn@f88db872-0e4f-0410-b76b-b9085cfa78c5>2003-02-15 18:43:08 +0000
commit04ed769ddfacb1d6f5faedb66d3ff8d512ede7d4 (patch)
tree46da01705f245a4b7118b7e78be42c2b5ddb4ebc /src/gr
parent644e9be13cfc020e7bc3777b4c71c5f535943716 (diff)
* major changes to driver routines to find multiple horizons in parallel
across multiple processors -- see src/driver/README.parallel for details * drop convergence checks on ||Delta_h|| in param.ccl because they don't fit well with parallelization changes ==> With this changes, AHFinderDirect is now (I think) multiprocessor-ready!! git-svn-id: http://svn.einsteintoolkit.org/cactus/EinsteinAnalysis/AHFinderDirect/trunk@946 f88db872-0e4f-0410-b76b-b9085cfa78c5
Diffstat (limited to 'src/gr')
-rw-r--r--src/gr/expansion.cc271
-rw-r--r--src/gr/expansion_Jacobian.cc137
-rw-r--r--src/gr/gr.hh13
-rw-r--r--src/gr/misc.cc4
4 files changed, 262 insertions, 163 deletions
diff --git a/src/gr/expansion.cc b/src/gr/expansion.cc
index 0ca256e..490ff99 100644
--- a/src/gr/expansion.cc
+++ b/src/gr/expansion.cc
@@ -56,7 +56,7 @@ using jtutil::pow4;
namespace {
void setup_xyz_posns(patch_system& ps, bool print_msg_flag);
-bool interpolate_geometry(patch_system& ps,
+bool interpolate_geometry(patch_system* ps_ptr,
const struct cactus_grid_info& cgi,
const struct geometry_info& gi,
bool print_msg_flag);
@@ -81,9 +81,12 @@ bool compute_Theta(patch_system& ps,
//******************************************************************************
//
-// This function computes the LHS function Theta(h), and optionally also
-// its Jacobian coefficients (from which the Jacobian matrix may be
-// computed later).
+// If ps_ptr != NULL, this function computes the LHS function Theta(h),
+// and optionally also its Jacobian coefficients (from which the Jacobian
+// matrix may be computed later).
+//
+// If ps_ptr == NULL, this function does a dummy computation, described
+// below.
//
// Inputs (angular gridfns, on ghosted grid):
// ... defined on ghosted grid
@@ -114,6 +117,11 @@ bool compute_Theta(patch_system& ps,
// Theta # $\Theta = \Theta(h)$
//
// Arguments:
+// ps_ptr --> The patch system, or == NULL to do (only) a dummy computation
+// in which only the parameter-table setup and a dummy geometry
+// interpolator call are done, the latter with the number of
+// interpolation points is set to 0 and all the output array
+// pointers set to NULL.
// Jacobian_flag = true to compute the Jacobian coefficients,
// false to skip this.
// print_msg_flag = true to print status messages,
@@ -124,64 +132,88 @@ bool compute_Theta(patch_system& ps,
// to compute various (gridwise) norms of Theta.
//
// Results:
-// This function returns true for a successful computation, or false
-// if the computation failed for any of the following reasons:
-// - the geometry interpolation would need data outside the Cactus grid,
-// or from an excised region
-// FIXME: excision isn't implemented yet :(
-// - NaNs are found in h or in the interpolate geometry variables
-// - Theta_D <= 0 (this means the interpolated g_ij aren't positive definite)
+// This function returns
+// * true for a successful computation
+// * true for a dummy computation (ps_ptr == NULL)
+// * false if the computation failed for any of the following reasons:
+// - the geometry interpolation would need data outside the Cactus grid,
+// or from an excised region
+// FIXME: excision isn't implemented yet :(
+// - NaNs are found in h or in the interpolate geometry variables
+// - Theta_D <= 0 (this means the interpolated g_ij aren't positive definite)
//
-bool expansion(patch_system& ps,
+bool expansion(patch_system* ps_ptr,
const struct cactus_grid_info& cgi,
const struct geometry_info& gi,
bool Jacobian_flag /* = false */,
bool print_msg_flag /* = false */,
jtutil::norm<fp>* Theta_norms_ptr /* = NULL */)
{
+const bool active_flag = (ps_ptr != NULL);
if (print_msg_flag)
- then CCTK_VInfo(CCTK_THORNSTRING, " expansion");
+ then CCTK_VInfo(CCTK_THORNSTRING,
+ " %sexpansion",
+ active_flag ? "" : "dummy ");
-// fill in values of all ghosted gridfns in ghost zones
-ps.synchronize();
+if (active_flag)
+ then {
+ //
+ // normal computation
+ //
+
+ // fill in values of all ghosted gridfns in ghost zones
+ ps_ptr->synchronize();
-if (gi.check_that_h_is_finite && !h_is_finite(ps, print_msg_flag))
- then return false; // *** ERROR RETURN ***
+ if (gi.check_that_h_is_finite
+ && !h_is_finite(*ps_ptr, print_msg_flag))
+ then return false; // *** ERROR RETURN ***
-// set up xyz positions of grid points
-setup_xyz_posns(ps, print_msg_flag);
+ // set up xyz positions of grid points
+ setup_xyz_posns(*ps_ptr, print_msg_flag);
+ }
// compute the "geometry" g_ij, K_ij, and partial_k g_ij
switch (gi.geometry_method)
{
case geometry__global_interp_from_Cactus_grid:
case geometry__local_interp_from_Cactus_grid:
- if (!interpolate_geometry(ps, cgi, gi, print_msg_flag))
+ // this is the only function we call unconditionally; it looks at
+ // ps_ptr (non-NULL vs NULL) to choose a normal vs dummy computation
+ if (!interpolate_geometry(ps_ptr,
+ cgi, gi,
+ print_msg_flag))
then return false; // *** ERROR RETURN ***
- if (cgi.Cactus_conformal_metric)
- then convert_conformal_to_physical(ps, print_msg_flag);
+ if (active_flag && cgi.Cactus_conformal_metric)
+ then convert_conformal_to_physical(*ps_ptr, print_msg_flag);
break;
case geometry__Schwarzschild_EF:
- Schwarzschild_EF_geometry(ps, gi, print_msg_flag);
+ if (active_flag)
+ then Schwarzschild_EF_geometry(*ps_ptr, gi, print_msg_flag);
break;
+
default:
error_exit(PANIC_EXIT,
"***** expansion(): unknown gi.geometry_method=(int)%d!\n"
-" (this should never happen!)\n"
-,
+" (this should never happen!)\n"
+ ,
int(gi.geometry_method)); /*NOTREACHED*/
}
-if (gi.check_that_geometry_is_finite
- && !geometry_is_finite(ps, print_msg_flag))
- then return false; // *** ERROR RETURN ***
+if (active_flag)
+ then {
+ if (gi.check_that_geometry_is_finite
+ && !geometry_is_finite(*ps_ptr, print_msg_flag))
+ then return false; // *** ERROR RETURN ***
-// compute remaining gridfns --> $\Theta$
-// and optionally also the Jacobian coefficients
-// by algebraic ops and angular finite differencing
-if (!compute_Theta(ps, Jacobian_flag, Theta_norms_ptr, print_msg_flag))
- then return false; // *** ERROR RETURN ***
+ // compute remaining gridfns --> $\Theta$
+ // and optionally also the Jacobian coefficients
+ // by algebraic ops and angular finite differencing
+ if (!compute_Theta(*ps_ptr,
+ Jacobian_flag, Theta_norms_ptr,
+ print_msg_flag))
+ then return false; // *** ERROR RETURN ***
+ }
return true; // *** NORMAL RETURN ***
}
@@ -234,7 +266,7 @@ if (print_msg_flag)
//******************************************************************************
//
-// This function interpolates the Cactus gridfns
+// If ps_ptr != NULL, this function interpolates the Cactus gridfns
// gxx...gzz
// kxx...kzz
// psi # optional
@@ -245,13 +277,18 @@ if (print_msg_flag)
// psi # optional
// partial_d_psi_k # optional
// at the nominal-grid trial horizon surface positions given by the
-// global_(x,y,z) angular gridfns. The psi interpolation is done if and
-// only if the cgi.Cactus_conformal_metric flag is set. Note that this
-// function ignores the physical-vs-conformal semantics of the gridfns;
-// it just interpolates and takes derivatives of the stored gridfn values.
+// global_(x,y,z) angular gridfns in the patch system *ps_ptr. The psi
+// interpolation is only done if the cgi.Cactus_conformal_metric flag
+// is set. Note that this function ignores the physical-vs-conformal
+// semantics of the gridfns; it just interpolates and takes derivatives
+// of the stored gridfn values.
+//
+// If ps_ptr == NULL, this function does (only) the parameter-table
+// setup and a a dummy interpolator call, as described in the comments
+// to expansion() above.
//
-// The interpolation may be either via CCTK_InterpGridArrays() or via
-// CCTK_InterpLocalUniform() , according to gi.geometry_method.
+// The interpolation may be either via CCTK_InterpGridArrays() or via
+// CCTK_InterpLocalUniform() , according to gi.geometry_method.
//
// Inputs (angular gridfns, all on the nominal grid):
// global_[xyz] # xyz positions of grid points
@@ -272,18 +309,23 @@ if (print_msg_flag)
// This function may also modify the interpolator parameter table.
//
// Results:
-// This function returns true for a successful computation, or false
-// if the computation failed because the geometry interpolation would
-// need data outside the Cactus grid, or data from an excised region.
-//
-// FIXME: excision isn't implemented yet :(
+// This function returns
+// * true for a successful computation
+// * true for a dummy computation (ps_ptr == NULL)
+// * false if the computation failed for any of the following reasons:
+// - the geometry interpolation would need data outside the Cactus grid,
+// or from an excised region
+// FIXME: excision isn't implemented yet :(
+// Any other interpolator error return codes are treated as a fatal error.
//
namespace {
-bool interpolate_geometry(patch_system& ps,
+bool interpolate_geometry(patch_system* ps_ptr,
const struct cactus_grid_info& cgi,
const struct geometry_info& gi,
bool print_msg_flag)
{
+const bool active_flag = (ps_ptr != NULL);
+
//
// Implementation Notes:
//
@@ -293,8 +335,8 @@ bool interpolate_geometry(patch_system& ps,
// to either include or exclude the psi entries as appropriate.
//
// We remember whether or not psi was interpolated on the previous call,
-// and only modify the interpolator parameter table if this changes (and
-// on our first call).
+// and only modify the interpolator parameter table if this changes (or
+// if this is our first call).
//
const char* const global_local_str
@@ -311,17 +353,20 @@ if (print_msg_flag)
int status;
+#define CAST_PTR_OR_NULL(type_,ptr_) \
+ (ps_ptr == NULL) ? NULL : static_cast<type_>(ptr_)
+
//
// ***** interpolation points *****
//
-const int N_interp_points = ps.N_grid_points();
+const int N_interp_points = (ps_ptr == NULL) ? 0 : ps_ptr->N_grid_points();
const int interp_coords_type_code = CCTK_VARIABLE_REAL;
const void* const interp_coords[N_GRID_DIMS]
= {
- static_cast<const void*>(ps.gridfn_data(gfns::gfn__global_x)),
- static_cast<const void*>(ps.gridfn_data(gfns::gfn__global_y)),
- static_cast<const void*>(ps.gridfn_data(gfns::gfn__global_z)),
+ CAST_PTR_OR_NULL(const void*, ps_ptr->gridfn_data(gfns::gfn__global_x)),
+ CAST_PTR_OR_NULL(const void*, ps_ptr->gridfn_data(gfns::gfn__global_y)),
+ CAST_PTR_OR_NULL(const void*, ps_ptr->gridfn_data(gfns::gfn__global_z)),
};
@@ -424,45 +469,45 @@ const CCTK_INT operation_codes[]
void* const output_arrays[]
= {
- static_cast<void*>(ps.gridfn_data(gfns::gfn__g_dd_11)),
- static_cast<void*>(ps.gridfn_data(gfns::gfn__partial_d_g_dd_111)),
- static_cast<void*>(ps.gridfn_data(gfns::gfn__partial_d_g_dd_211)),
- static_cast<void*>(ps.gridfn_data(gfns::gfn__partial_d_g_dd_311)),
- static_cast<void*>(ps.gridfn_data(gfns::gfn__g_dd_12)),
- static_cast<void*>(ps.gridfn_data(gfns::gfn__partial_d_g_dd_112)),
- static_cast<void*>(ps.gridfn_data(gfns::gfn__partial_d_g_dd_212)),
- static_cast<void*>(ps.gridfn_data(gfns::gfn__partial_d_g_dd_312)),
- static_cast<void*>(ps.gridfn_data(gfns::gfn__g_dd_13)),
- static_cast<void*>(ps.gridfn_data(gfns::gfn__partial_d_g_dd_113)),
- static_cast<void*>(ps.gridfn_data(gfns::gfn__partial_d_g_dd_213)),
- static_cast<void*>(ps.gridfn_data(gfns::gfn__partial_d_g_dd_313)),
- static_cast<void*>(ps.gridfn_data(gfns::gfn__g_dd_22)),
- static_cast<void*>(ps.gridfn_data(gfns::gfn__partial_d_g_dd_122)),
- static_cast<void*>(ps.gridfn_data(gfns::gfn__partial_d_g_dd_222)),
- static_cast<void*>(ps.gridfn_data(gfns::gfn__partial_d_g_dd_322)),
- static_cast<void*>(ps.gridfn_data(gfns::gfn__g_dd_23)),
- static_cast<void*>(ps.gridfn_data(gfns::gfn__partial_d_g_dd_123)),
- static_cast<void*>(ps.gridfn_data(gfns::gfn__partial_d_g_dd_223)),
- static_cast<void*>(ps.gridfn_data(gfns::gfn__partial_d_g_dd_323)),
- static_cast<void*>(ps.gridfn_data(gfns::gfn__g_dd_33)),
- static_cast<void*>(ps.gridfn_data(gfns::gfn__partial_d_g_dd_133)),
- static_cast<void*>(ps.gridfn_data(gfns::gfn__partial_d_g_dd_233)),
- static_cast<void*>(ps.gridfn_data(gfns::gfn__partial_d_g_dd_333)),
- static_cast<void*>(ps.gridfn_data(gfns::gfn__K_dd_11)),
- static_cast<void*>(ps.gridfn_data(gfns::gfn__K_dd_12)),
- static_cast<void*>(ps.gridfn_data(gfns::gfn__K_dd_13)),
- static_cast<void*>(ps.gridfn_data(gfns::gfn__K_dd_22)),
- static_cast<void*>(ps.gridfn_data(gfns::gfn__K_dd_23)),
- static_cast<void*>(ps.gridfn_data(gfns::gfn__K_dd_33)),
- static_cast<void*>(ps.gridfn_data(gfns::gfn__psi)),
- static_cast<void*>(ps.gridfn_data(gfns::gfn__partial_d_psi_1)),
- static_cast<void*>(ps.gridfn_data(gfns::gfn__partial_d_psi_2)),
- static_cast<void*>(ps.gridfn_data(gfns::gfn__partial_d_psi_3)),
+ CAST_PTR_OR_NULL(void*, ps_ptr->gridfn_data(gfns::gfn__g_dd_11)),
+ CAST_PTR_OR_NULL(void*, ps_ptr->gridfn_data(gfns::gfn__partial_d_g_dd_111)),
+ CAST_PTR_OR_NULL(void*, ps_ptr->gridfn_data(gfns::gfn__partial_d_g_dd_211)),
+ CAST_PTR_OR_NULL(void*, ps_ptr->gridfn_data(gfns::gfn__partial_d_g_dd_311)),
+ CAST_PTR_OR_NULL(void*, ps_ptr->gridfn_data(gfns::gfn__g_dd_12)),
+ CAST_PTR_OR_NULL(void*, ps_ptr->gridfn_data(gfns::gfn__partial_d_g_dd_112)),
+ CAST_PTR_OR_NULL(void*, ps_ptr->gridfn_data(gfns::gfn__partial_d_g_dd_212)),
+ CAST_PTR_OR_NULL(void*, ps_ptr->gridfn_data(gfns::gfn__partial_d_g_dd_312)),
+ CAST_PTR_OR_NULL(void*, ps_ptr->gridfn_data(gfns::gfn__g_dd_13)),
+ CAST_PTR_OR_NULL(void*, ps_ptr->gridfn_data(gfns::gfn__partial_d_g_dd_113)),
+ CAST_PTR_OR_NULL(void*, ps_ptr->gridfn_data(gfns::gfn__partial_d_g_dd_213)),
+ CAST_PTR_OR_NULL(void*, ps_ptr->gridfn_data(gfns::gfn__partial_d_g_dd_313)),
+ CAST_PTR_OR_NULL(void*, ps_ptr->gridfn_data(gfns::gfn__g_dd_22)),
+ CAST_PTR_OR_NULL(void*, ps_ptr->gridfn_data(gfns::gfn__partial_d_g_dd_122)),
+ CAST_PTR_OR_NULL(void*, ps_ptr->gridfn_data(gfns::gfn__partial_d_g_dd_222)),
+ CAST_PTR_OR_NULL(void*, ps_ptr->gridfn_data(gfns::gfn__partial_d_g_dd_322)),
+ CAST_PTR_OR_NULL(void*, ps_ptr->gridfn_data(gfns::gfn__g_dd_23)),
+ CAST_PTR_OR_NULL(void*, ps_ptr->gridfn_data(gfns::gfn__partial_d_g_dd_123)),
+ CAST_PTR_OR_NULL(void*, ps_ptr->gridfn_data(gfns::gfn__partial_d_g_dd_223)),
+ CAST_PTR_OR_NULL(void*, ps_ptr->gridfn_data(gfns::gfn__partial_d_g_dd_323)),
+ CAST_PTR_OR_NULL(void*, ps_ptr->gridfn_data(gfns::gfn__g_dd_33)),
+ CAST_PTR_OR_NULL(void*, ps_ptr->gridfn_data(gfns::gfn__partial_d_g_dd_133)),
+ CAST_PTR_OR_NULL(void*, ps_ptr->gridfn_data(gfns::gfn__partial_d_g_dd_233)),
+ CAST_PTR_OR_NULL(void*, ps_ptr->gridfn_data(gfns::gfn__partial_d_g_dd_333)),
+ CAST_PTR_OR_NULL(void*, ps_ptr->gridfn_data(gfns::gfn__K_dd_11)),
+ CAST_PTR_OR_NULL(void*, ps_ptr->gridfn_data(gfns::gfn__K_dd_12)),
+ CAST_PTR_OR_NULL(void*, ps_ptr->gridfn_data(gfns::gfn__K_dd_13)),
+ CAST_PTR_OR_NULL(void*, ps_ptr->gridfn_data(gfns::gfn__K_dd_22)),
+ CAST_PTR_OR_NULL(void*, ps_ptr->gridfn_data(gfns::gfn__K_dd_23)),
+ CAST_PTR_OR_NULL(void*, ps_ptr->gridfn_data(gfns::gfn__K_dd_33)),
+ CAST_PTR_OR_NULL(void*, ps_ptr->gridfn_data(gfns::gfn__psi)),
+ CAST_PTR_OR_NULL(void*, ps_ptr->gridfn_data(gfns::gfn__partial_d_psi_1)),
+ CAST_PTR_OR_NULL(void*, ps_ptr->gridfn_data(gfns::gfn__partial_d_psi_2)),
+ CAST_PTR_OR_NULL(void*, ps_ptr->gridfn_data(gfns::gfn__partial_d_psi_3)),
};
const int N_output_arrays_for_psi = 4;
-const int N_output_arrays_dim = sizeof(output_arrays)
- / sizeof(output_arrays[0]);
+const int N_output_arrays_dim
+ = sizeof(output_arrays) / sizeof(output_arrays[0]);
const int N_output_arrays_use
= psi_flag ? N_output_arrays_dim
: N_output_arrays_dim - N_output_arrays_for_psi;
@@ -526,15 +571,12 @@ if (par_table_setup && (psi_flag == par_table_psi_flag))
//
if (print_msg_flag)
then CCTK_VInfo(CCTK_THORNSTRING,
- " calling %s interpolator (%d points)",
- global_local_str, N_interp_points);
+ " calling %s interpolator (%s%d points)",
+ global_local_str,
+ (active_flag ? "" : "dummy: "), N_interp_points);
switch (gi.geometry_method)
{
case geometry__global_interp_from_Cactus_grid:
- if (print_msg_flag)
- then CCTK_VInfo(CCTK_THORNSTRING,
- " calling CCTK_InterpGridArrays() (%d points)",
- N_interp_points);
status = CCTK_InterpGridArrays(cgi.GH, N_GRID_DIMS,
gi.operator_handle,
gi.param_table_handle,
@@ -549,10 +591,6 @@ case geometry__global_interp_from_Cactus_grid:
output_arrays);
break;
case geometry__local_interp_from_Cactus_grid:
- if (print_msg_flag)
- then CCTK_VInfo(CCTK_THORNSTRING,
- " calling CCTK_InterpLocalUniform() (%d points)",
- N_interp_points);
status = CCTK_InterpLocalUniform(N_GRID_DIMS,
gi.operator_handle,
gi.param_table_handle,
@@ -581,39 +619,39 @@ if (status == CCTK_ERROR_INTERP_POINT_OUTSIDE)
then {
// look in interpolator output table entries
// to see *which* point is out-of-range
- CCTK_INT out_of_range_pt, out_of_range_axis, out_of_range_end;
+ CCTK_INT error_pt, error_axis, error_direction;
if ( (Util_TableGetInt(gi.param_table_handle,
- &out_of_range_pt,
- "out_of_range_pt") < 0)
+ &error_pt,
+ "error_pt") < 0)
|| (Util_TableGetInt(gi.param_table_handle,
- &out_of_range_axis,
- "out_of_range_axis") < 0)
+ &error_axis,
+ "error_axis") < 0)
|| (Util_TableGetInt(gi.param_table_handle,
- &out_of_range_end,
- "out_of_range_end") < 0) )
+ &error_direction,
+ "error_direction") < 0) )
then error_exit(ERROR_EXIT,
"***** interpolate_geometry():\n"
" point out of range when interpolating geometry info from 3-D grid!\n"
" (one or more points on the trial horizon surface\n"
" are outside the grid or too close to the boundary),\n"
-" but we can't get info about the out-of-range point!\n"
+" but we can't get info about the bad point(s)!\n"
" ==> maybe an interpolator problem?\n"); /*NOTREACHED*/
- assert(out_of_range_pt >= 0);
- assert(out_of_range_pt < ps.N_grid_points());
+ assert(error_pt >= 0);
+ assert(error_pt < ps_ptr->N_grid_points());
const double global_x
- = ps.gridfn_data(gfns::gfn__global_x)[out_of_range_pt];
+ = ps_ptr->gridfn_data(gfns::gfn__global_x)[error_pt];
const double global_y
- = ps.gridfn_data(gfns::gfn__global_y)[out_of_range_pt];
+ = ps_ptr->gridfn_data(gfns::gfn__global_y)[error_pt];
const double global_z
- = ps.gridfn_data(gfns::gfn__global_z)[out_of_range_pt];
+ = ps_ptr->gridfn_data(gfns::gfn__global_z)[error_pt];
- assert(out_of_range_axis >= 0);
- assert(out_of_range_axis < N_GRID_DIMS);
- const char axis = "xyz"[out_of_range_axis];
+ assert(error_axis >= 0);
+ assert(error_axis < N_GRID_DIMS);
+ const char axis = "xyz"[error_axis];
- assert((out_of_range_end == -1) || (out_of_range_end == +1));
- const char end = (out_of_range_end == -1) ? '-' : '+';
+ assert((error_direction == -1) || (error_direction == +1));
+ const char end = (error_direction == -1) ? '-' : '+';
if (print_msg_flag)
then {
@@ -636,7 +674,6 @@ if (status < 0)
,
status); /*NOTREACHED*/
-
return true; // *** NORMAL RETURN ***
}
}
diff --git a/src/gr/expansion_Jacobian.cc b/src/gr/expansion_Jacobian.cc
index 082387b..805ed97 100644
--- a/src/gr/expansion_Jacobian.cc
+++ b/src/gr/expansion_Jacobian.cc
@@ -67,8 +67,8 @@ void add_ghost_zone_Jacobian(const patch_system& ps,
const patch& xp, const ghost_zone& xmgz,
int x_II,
int xm_irho, int xm_isigma);
-bool expansion_Jacobian_dr_FD(patch_system& ps,
- Jacobian& Jac,
+bool expansion_Jacobian_dr_FD(patch_system* ps_ptr,
+ Jacobian* Jac_ptr,
const struct cactus_grid_info& cgi,
const struct geometry_info& gi,
const struct Jacobian_info& Jacobian_info,
@@ -78,32 +78,57 @@ bool expansion_Jacobian_dr_FD(patch_system& ps,
//******************************************************************************
//
-// This function is a top-level driver to compute the Jacobian matrix
-// J[Theta(h)] of the expansion Theta(h). It just decodes the
-// Jacobian_compute_method parameter and calls the appropriate subfunction.
+// If ps_ptr != NULL and Jac_ptr != NULL, this function computes the
+// Jacobian matrix J[Theta(h)] of the expansion Theta(h). We assume
+// that Theta(h) has already been computed.
//
-// We assume that Theta(h) has already been computed.
+// If ps_ptr == NULL and Jac_ptr == NULL, this function does a dummy
+// computation, in which only any expansion() (and hence geometry
+// interpolator) calls are done, these with the number of interpolation
+// points set to 0 and all the output array pointers set to NULL.
+//
+// It's illegal for one but not both of ps_ptr and Jac_ptr to be NULL.
+//
+// Only some values of Jacobian_info.Jacobian_compute_method support
+// the dummy computation.
+//
+// Arguments:
+// ps_ptr --> The patch system, or == NULL to do (only) a dummy computation.
+// Jac_ptr --> The Jacobian, or == NULL to do (only) a dummy computation.
//
// Results:
-// This function returns true for a successful computation, or false
-// for failure. See expansion() (in "expansion.cc")
-// for details of the various ways the computation may fail.
+// This function returns
+// * true for a successful computation
+// * true for a dummy computation (ps_ptr == NULL)
+// * false if the computation failed for any of the following reasons
+// documented for expansion() (in "expansion.cc").
//
-bool expansion_Jacobian(patch_system& ps,
- Jacobian& Jac,
+bool expansion_Jacobian(patch_system* ps_ptr,
+ Jacobian* Jac_ptr,
const struct cactus_grid_info& cgi,
const struct geometry_info& gi,
const struct Jacobian_info& Jacobian_info,
bool print_msg_flag /* = false */)
{
+const bool active_flag = (ps_ptr != NULL) && (Jac_ptr != NULL);
+
switch (Jacobian_info.Jacobian_compute_method)
{
case Jacobian__numerical_perturbation:
- if (! expansion_Jacobian_NP(ps, Jac,
- cgi, gi, Jacobian_info,
- print_msg_flag))
- then return false; // *** ERROR RETURN ***
- break;
+ if (active_flag)
+ then {
+ if (! expansion_Jacobian_NP(*ps_ptr, *Jac_ptr,
+ cgi, gi, Jacobian_info,
+ print_msg_flag))
+ then return false; // *** ERROR RETURN ***
+ break;
+ }
+ else CCTK_VWarn(1, __LINE__, __FILE__, CCTK_THORNSTRING,
+"\n"
+" expansion_Jacobian():\n"
+" dummy computation isn't supported for\n"
+" Jacobian_compute_method = \"numerical perturbation\"!");/*NOTREACHED*/
+
case Jacobian__symbolic_diff:
CCTK_VWarn(1, __LINE__, __FILE__, CCTK_THORNSTRING,
"\n"
@@ -112,15 +137,20 @@ case Jacobian__symbolic_diff:
" isn't implemented (yet); reverting to\n"
" \"symbolic differentiation with finite diff d/dr\"");
// fall through
+
case Jacobian__symbolic_diff_with_FD_dr:
- expansion_Jacobian_partial_SD(ps, Jac,
- cgi, gi, Jacobian_info,
- print_msg_flag);
- if (! expansion_Jacobian_dr_FD(ps, Jac,
+ if (active_flag)
+ then expansion_Jacobian_partial_SD(*ps_ptr, *Jac_ptr,
+ cgi, gi, Jacobian_info,
+ print_msg_flag);
+ // this function looks at ps_ptr and Jac_ptr (non-NULL vs NULL)
+ // to choose a normal vs dummy computation
+ if (! expansion_Jacobian_dr_FD(ps_ptr, Jac_ptr,
cgi, gi, Jacobian_info,
print_msg_flag))
then return false; // *** ERROR RETURN ***
break;
+
default:
error_exit(PANIC_EXIT,
"***** expansion_Jacobian():\n"
@@ -129,6 +159,7 @@ default:
,
int(Jacobian_info.Jacobian_compute_method)); /*NOTREACHED*/
}
+
return true; // *** NORMAL RETURN ***
}
@@ -203,8 +234,9 @@ ps.gridfn_copy(gfns::gfn__Theta, gfns::gfn__save_Theta);
const fp save_h_y = yp.ghosted_gridfn(gfns::gfn__h, y_irho,y_isigma);
yp.ghosted_gridfn(gfns::gfn__h, y_irho,y_isigma) += epsilon;
- if (! expansion(ps, cgi, ii))
+ if (! expansion(&ps, cgi, ii))
then return false; // *** ERROR RETURN ***
+
for (int xpn = 0 ; xpn < ps.N_patches() ; ++xpn)
{
patch& xp = ps.ith_patch(xpn);
@@ -226,6 +258,7 @@ ps.gridfn_copy(gfns::gfn__Theta, gfns::gfn__save_Theta);
}
}
}
+
yp.ghosted_gridfn(gfns::gfn__h, y_irho,y_isigma) = save_h_y;
}
}
@@ -459,8 +492,16 @@ patch& yp = ye.my_patch();
//******************************************************************************
//
-// This function sums the d/dr terms into the Jacobian matrix of the
-// expansion Theta(h), computing those terms by finite differencing.
+// If ps_ptr != NULL and Jac_ptr != NULL, this function sums the d/dr
+// terms into the Jacobian matrix of the expansion Theta(h), computing
+// those terms by finite differencing.
+//
+// If ps_ptr == NULL and Jac_ptr == NULL, this function does a dummy
+// computation, in which only any expansion() (and hence geometry
+// interpolator) calls are done, these with the number of interpolation
+// points set to 0 and all the output array pointers set to NULL.
+//
+// It's illegal for one but not both of ps_ptr and Jac_ptr to be NULL.
//
// The basic algorithm is that
// Jac += diag[ (Theta(h+epsilon) - Theta(h)) / epsilon ]
@@ -473,53 +514,65 @@ patch& yp = ye.my_patch();
// Jac += d/dr terms
//
// Results:
-// This function returns true for a successful computation, or false
-// if the computation failed because the geometry interpolation would
-// need data outside the Cactus grid, or data from an excised region.
-// FIXME: excision isn't implemented yet :(
+// This function returns
+// * true for a successful computation
+// * true for a dummy computation (ps_ptr == NULL)
+// * false if the computation failed for any of the following reasons:
+// - the geometry interpolation would need data outside the Cactus grid,
+// or from an excised region
+// FIXME: excision isn't implemented yet :(
//
namespace {
-bool expansion_Jacobian_dr_FD(patch_system& ps,
- Jacobian& Jac,
+bool expansion_Jacobian_dr_FD(patch_system* ps_ptr,
+ Jacobian* Jac_ptr,
const struct cactus_grid_info& cgi,
const struct geometry_info& gi,
const struct Jacobian_info& Jacobian_info,
bool print_msg_flag)
{
+const bool active_flag = (ps_ptr != NULL) && (Jac_ptr != NULL);
if (print_msg_flag)
then CCTK_VInfo(CCTK_THORNSTRING,
- " horizon Jacobian: d/dr terms (finite diff)");
+ " horizon Jacobian: %sd/dr terms (finite diff)",
+ active_flag ? "" : "dummy ");
const fp epsilon = Jacobian_info.perturbation_amplitude;
// compute Theta(h+epsilon)
-ps.gridfn_copy(gfns::gfn__Theta, gfns::gfn__save_Theta);
-ps.add_to_ghosted_gridfn(epsilon, gfns::gfn__h);
-if (! expansion(ps, cgi, gi))
+if (active_flag)
+ then {
+ ps_ptr->gridfn_copy(gfns::gfn__Theta, gfns::gfn__save_Theta);
+ ps_ptr->add_to_ghosted_gridfn(epsilon, gfns::gfn__h);
+ }
+if (! expansion(ps_ptr, cgi, gi))
then return false; // *** ERROR RETURN ***
- for (int pn = 0 ; pn < ps.N_patches() ; ++pn)
- {
- patch& p = ps.ith_patch(pn);
+if (active_flag)
+ then {
+ for (int pn = 0 ; pn < ps_ptr->N_patches() ; ++pn)
+ {
+ patch& p = ps_ptr->ith_patch(pn);
for (int irho = p.min_irho() ; irho <= p.max_irho() ; ++irho)
{
for (int isigma = p.min_isigma() ;
isigma <= p.max_isigma() ;
++isigma)
{
- const int II = ps.gpn_of_patch_irho_isigma(p, irho,isigma);
+ const int II = ps_ptr->gpn_of_patch_irho_isigma(p, irho,isigma);
const fp old_Theta = p.gridfn(gfns::gfn__save_Theta,
irho,isigma);
const fp new_Theta = p.gridfn(gfns::gfn__Theta,
irho,isigma);
- Jac.sum_into_element(II,II, (new_Theta - old_Theta) / epsilon);
+ const fp d_dr_term = (new_Theta - old_Theta) / epsilon;
+ Jac_ptr->sum_into_element(II,II, d_dr_term);
}
}
- }
+ }
-// restore h and Theta
-ps.add_to_ghosted_gridfn(-epsilon, gfns::gfn__h);
-ps.gridfn_copy(gfns::gfn__save_Theta, gfns::gfn__Theta);
+ // restore h and Theta
+ ps_ptr->add_to_ghosted_gridfn(-epsilon, gfns::gfn__h);
+ ps_ptr->gridfn_copy(gfns::gfn__save_Theta, gfns::gfn__Theta);
+ }
return true; // *** NORMAL RETURN ***
}
diff --git a/src/gr/gr.hh b/src/gr/gr.hh
index c20a720..3014cd7 100644
--- a/src/gr/gr.hh
+++ b/src/gr/gr.hh
@@ -144,6 +144,7 @@ struct Jacobian_info
// expansion.cc
// ... returns true for successful computation,
+// ... returns true for dummy computation (ps_ptr == NULL)
// ... returns false for failure (eg horizon outside grid);
// if (print_msg_flag) then also reports CCTK_VWarn() at the
// appropriate warning level
@@ -156,7 +157,7 @@ namespace expansion_warning_levels
// ==> skipping nonfinite check
};
}
-bool expansion(patch_system& ps,
+bool expansion(patch_system* ps_ptr,
const struct cactus_grid_info& cgi,
const struct geometry_info& gi,
bool Jacobian_flag = false,
@@ -164,9 +165,11 @@ bool expansion(patch_system& ps,
jtutil::norm<fp>* H_norms_ptr = NULL);
// expansion_Jacobian.cc
-// ... returns true for successful computation, false for failure
-bool expansion_Jacobian(patch_system& ps,
- Jacobian& Jac,
+// ... returns true for successful computation
+// ... returns true for dummy computation (ps_ptr == NULL && Jac_ptr == NULL)
+// ... returns false for failure
+bool expansion_Jacobian(patch_system* ps_ptr,
+ Jacobian* Jac_ptr,
const struct cactus_grid_info& cgi,
const struct geometry_info& gi,
const struct Jacobian_info& Jacobian_info,
@@ -180,6 +183,8 @@ void Schwarzschild_EF_geometry(patch_system& ps,
// misc.cc
enum geometry_method
decode_geometry_method(const char geometry_method_string[]);
+#ifdef NOT_USED
bool geometry_method_is_interp(enum geometry_method geometry_method);
+#endif
enum Jacobian_compute_method
decode_Jacobian_compute_method(const char Jacobian_compute_method_string[]);
diff --git a/src/gr/misc.cc b/src/gr/misc.cc
index 7cdc018..8a0ced4 100644
--- a/src/gr/misc.cc
+++ b/src/gr/misc.cc
@@ -2,7 +2,9 @@
// $Header$
//
// decode_geometry_method - decode the geometry_method parameter
+#ifdef NOT_USED
// geomery_method_is_interp - does enum geometry_method specify interpolation?
+#endif
// decode_geometry_method - decode the geometry_method parameter
//
@@ -61,6 +63,7 @@ else CCTK_VWarn(-1, __LINE__, __FILE__, CCTK_THORNSTRING,
//******************************************************************************
+#ifdef NOT_USED
//
// This function determines whether or not an enum geometry_method
// value specifies an interpolation.
@@ -80,6 +83,7 @@ default:
geometry_method); /*NOTREACHED*/
}
}
+#endif
//******************************************************************************