aboutsummaryrefslogtreecommitdiff
path: root/src/gr/expansion.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/gr/expansion.cc')
-rw-r--r--src/gr/expansion.cc491
1 files changed, 437 insertions, 54 deletions
diff --git a/src/gr/expansion.cc b/src/gr/expansion.cc
index 5a03783..cdbd57c 100644
--- a/src/gr/expansion.cc
+++ b/src/gr/expansion.cc
@@ -37,9 +37,11 @@
#include <stdio.h>
#include <assert.h>
#include <math.h>
+#include <string.h>
#include "util_Table.h"
#include "cctk.h"
+#include "cctk_Arguments.h"
#include "config.h"
#include "stdc.h"
@@ -47,6 +49,10 @@
#include "../jtutil/array.hh"
#include "../jtutil/cpm_map.hh"
#include "../jtutil/linear_map.hh"
+using jtutil::error_exit;
+using jtutil::pow2;
+using jtutil::pow3;
+using jtutil::pow4;
#include "../patch/coords.hh"
#include "../patch/grid.hh"
@@ -65,9 +71,6 @@
// all the code in this file is inside this namespace
namespace AHFinderDirect
{
-using jtutil::error_exit;
-using jtutil::pow2;
-using jtutil::pow4;
//******************************************************************************
//******************************************************************************
@@ -99,8 +102,13 @@ bool geometry_is_finite(patch_system& ps,
const struct error_info& error_info, bool initial_flag,
bool print_msg_flag);
-bool compute_Theta(patch_system& ps, fp add_to_expansion,
- bool Jacobian_flag, jtutil::norm<fp>* Theta_norms_ptr,
+bool compute_Theta(patch_system& ps, const struct what_to_compute& comput_info,
+ bool Jacobian_flag,
+ jtutil::norm<fp>* Theta_norms_ptr,
+ jtutil::norm<fp>* expansion_Theta_norms_ptr,
+ jtutil::norm<fp>* inner_expansion_Theta_norms_ptr,
+ jtutil::norm<fp>* product_expansion_Theta_norms_ptr,
+ jtutil::norm<fp>* mean_curvature_Theta_norms_ptr,
const struct error_info& error_info, bool initial_flag,
bool print_msg_flag);
}
@@ -172,13 +180,18 @@ bool compute_Theta(patch_system& ps, fp add_to_expansion,
// succeeded or failed, and if the latter, what caused the failure.
//
enum expansion_status
- expansion(patch_system* ps_ptr, fp add_to_expansion,
+ expansion(patch_system* ps_ptr,
+ const struct what_to_compute& compute_info,
const struct cactus_grid_info& cgi,
const struct geometry_info& gi,
const struct error_info& error_info, bool initial_flag,
bool Jacobian_flag /* = false */,
bool print_msg_flag /* = false */,
- jtutil::norm<fp>* Theta_norms_ptr /* = NULL */)
+ jtutil::norm<fp>* Theta_norms_ptr /* = NULL */,
+ jtutil::norm<fp>* expansion_Theta_norms_ptr /* = NULL */,
+ jtutil::norm<fp>* inner_expansion_Theta_norms_ptr /* = NULL */,
+ jtutil::norm<fp>* product_expansion_Theta_norms_ptr /* = NULL */,
+ jtutil::norm<fp>* mean_curvature_Theta_norms_ptr /* = NULL */)
{
const bool active_flag = (ps_ptr != NULL);
if (print_msg_flag)
@@ -230,6 +243,8 @@ if (gi.hardwire_Schwarzschild_EF_geometry)
if (active_flag)
then {
+
+
if (gi.check_that_geometry_is_finite
&& !geometry_is_finite(*ps_ptr,
error_info, initial_flag,
@@ -237,15 +252,134 @@ if (active_flag)
then return expansion_failure__geometry_nonfinite;
// *** ERROR RETURN ***
+ // Ensure that there is a norm object
+ const bool want_norms = Theta_norms_ptr;
+ jtutil::norm<fp> norms;
+ if (compute_info.surface_selection != selection_definition)
+ then if (! Theta_norms_ptr) Theta_norms_ptr = &norms;
+
+
// compute remaining gridfns --> $\Theta$
// and optionally also the Jacobian coefficients
// by algebraic ops and angular finite differencing
- if (!compute_Theta(*ps_ptr, add_to_expansion,
+ what_to_compute this_compute_info (compute_info);
+ this_compute_info.surface_selection = selection_definition;
+ if (!compute_Theta(*ps_ptr, this_compute_info,
Jacobian_flag, Theta_norms_ptr,
+ expansion_Theta_norms_ptr,
+ inner_expansion_Theta_norms_ptr,
+ product_expansion_Theta_norms_ptr,
+ mean_curvature_Theta_norms_ptr,
error_info, initial_flag,
print_msg_flag))
then return expansion_failure__gij_not_positive_definite;
// *** ERROR RETURN ***
+
+ if (compute_info.surface_selection != selection_definition) {
+ //
+ // Apply correction to find a surface by its areal radius
+ //
+ // get mean expansion
+ fp mean_expansion;
+ fp areal_radius;
+ switch (compute_info.surface_selection) {
+ case selection_mean_coordinate_radius: {
+ const int np = ps_ptr->N_grid_points();
+ fp sum_expansion = 0;
+ fp sum_radius = 0;
+ 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) {
+ sum_expansion += p.gridfn(gfns::gfn__Theta, irho,isigma);
+ sum_radius += p.ghosted_gridfn(gfns::gfn__h, irho,isigma);
+ }
+ }
+ }
+ mean_expansion = sum_expansion / np;
+ areal_radius = sum_radius / np;
+ break;
+ }
+ case selection_areal_radius: {
+ // get surface area
+ const fp area = ps_ptr->integrate_gridfn
+ (gfns::gfn__one, true, true, true,
+ gfns::gfn__h,
+ gfns::gfn__g_dd_11, gfns::gfn__g_dd_12, gfns::gfn__g_dd_13,
+ gfns::gfn__g_dd_22, gfns::gfn__g_dd_23,
+ gfns::gfn__g_dd_33,
+ patch::integration_method__automatic_choice);
+ mean_expansion = Theta_norms_ptr->mean();
+ areal_radius = sqrt(area / (4.0*PI));
+ break;
+ }
+ case selection_expansion_mean_coordinate_radius: {
+ const int np = ps_ptr->N_grid_points();
+ fp sum_expansion = 0;
+ fp sum_radius = 0;
+ 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) {
+ sum_expansion += p.gridfn(gfns::gfn__Theta, irho,isigma);
+ sum_radius += p.ghosted_gridfn(gfns::gfn__h, irho,isigma);
+ }
+ }
+ }
+ mean_expansion = sum_expansion / np;
+ areal_radius = mean_expansion * sum_radius / np;
+ break;
+ }
+ case selection_expansion_areal_radius: {
+ // get surface area
+ const fp area = ps_ptr->integrate_gridfn
+ (gfns::gfn__one, true, true, true,
+ gfns::gfn__h,
+ gfns::gfn__g_dd_11, gfns::gfn__g_dd_12, gfns::gfn__g_dd_13,
+ gfns::gfn__g_dd_22, gfns::gfn__g_dd_23,
+ gfns::gfn__g_dd_33,
+ patch::integration_method__automatic_choice);
+ mean_expansion = Theta_norms_ptr->mean();
+ areal_radius = mean_expansion * sqrt(area / (4.0*PI));
+ break;
+ }
+ default:
+ assert (0);
+ } // switch areal_radius_definition
+
+ if (! ps_ptr->N_additional_points()) {
+ // calculate correction
+ const fp correction
+ = (- mean_expansion
+ + areal_radius - compute_info.desired_value);
+ // apply correction
+ ps_ptr->add_to_gridfn(-correction, gfns::gfn__Theta);
+ } else {
+ const int np = ps_ptr->N_grid_points();
+ const int gnp = ps_ptr->ghosted_N_grid_points();
+ // apply correction
+ const fp correction
+ = ps_ptr->ghosted_gridfn_data(gfns::gfn__h)[gnp];
+ ps_ptr->add_to_gridfn(-correction, gfns::gfn__Theta);
+ ps_ptr->gridfn_data(gfns::gfn__Theta)[np]
+ = (mean_expansion - correction
+ - areal_radius + compute_info.desired_value);
+ }
+ if (want_norms) {
+ // recalculate norms
+ ps_ptr->gridfn_norms (gfns::gfn__Theta, *Theta_norms_ptr);
+ } // if want_norms
+ } else {
+ //
+ // do not apply correction
+ //
+ if (ps_ptr->N_additional_points()) {
+ const int np = ps_ptr->N_grid_points();
+ const int gnp = ps_ptr->ghosted_N_grid_points();
+ ps_ptr->gridfn_data(gfns::gfn__Theta)[np]
+ = ps_ptr->ghosted_gridfn_data(gfns::gfn__h)[gnp];
+ }
+ } // if use-areal-radius
}
return expansion_success; // *** NORMAL RETURN ***
@@ -256,25 +390,19 @@ return expansion_success; // *** NORMAL RETURN ***
//******************************************************************************
//
-// This function sets up the xyz-position gridfns:
-// * global_[xyz] (used by interplate_geometry() )
-// * global_{xx,xy,xz,yy,yz,zz} (used by higher-level code to compute
-// quadrupole moments of horizons)
-//
-// Bugs:
-// * We initialize the global_{xx,xy,xz,yy,yz,zz} gridfns every time
-// this function is called, i.e. at each horizon-finding Newton
-// iteration, even though they're only needed at the end of the
-// horizon-finding process. In practice the extra cost is small,
-// though, so it's probably not worth fixing this...
+// This function sets up the global xyz positions of the grid points
+// in the gridfns global_[xyz]. These will be used by interplate_geometry().
//
namespace {
-void setup_xyz_posns(patch_system& ps, bool print_msg_flag)
+void setup_xyz_posns(patch_system& ps, const bool print_msg_flag)
{
if (print_msg_flag)
then CCTK_VInfo(CCTK_THORNSTRING,
" xyz positions and derivative coefficients");
+#ifdef GEOMETRY_INTERP_DEBUG2
+ printf ("AH exp\n");
+#endif
for (int pn = 0 ; pn < ps.N_patches() ; ++pn)
{
patch& p = ps.ith_patch(pn);
@@ -285,12 +413,15 @@ if (print_msg_flag)
isigma <= p.max_isigma() ;
++isigma)
{
- const fp r = p.ghosted_gridfn(gfns::gfn__h, irho,isigma);
+ const fp r = p.ghosted_gridfn(gfns::gfn__h, irho,isigma);
const fp rho = p.rho_of_irho(irho);
const fp sigma = p.sigma_of_isigma(isigma);
-
fp local_x, local_y, local_z;
p.xyz_of_r_rho_sigma(r,rho,sigma, local_x,local_y,local_z);
+#ifdef GEOMETRY_INTERP_DEBUG2
+ printf (" pn=%d irho=%d isigma=%d x=%g y=%g z=%g\n",
+ pn, irho, isigma, local_x, local_y, local_z);
+#endif
const fp global_x = ps.origin_x() + local_x;
const fp global_y = ps.origin_y() + local_y;
@@ -353,12 +484,15 @@ if (print_msg_flag)
// global_[xyz] # xyz positions of grid points
//
// Inputs (Cactus 3-D gridfns):
+// ahmask # excision mask
// gxx,gxy,gxz,gyy,gyz,gzz # 3-metric $g_{ij}$
// # (may be either physical or conformal)
// kxx,kxy,kxz,kyy,kyz,kzz # extrinsic curvature $K_{ij}$
// psi # optional conformal factor $\psi$
//
// Outputs (angular gridfns, all on the nominal grid):
+// mask # excision mask
+// partial_d_mask_[123] # derivatives of the mask
// g_dd_{11,12,13,22,23,33} # $\stored{g}_{ij}$
// K_dd_{11,12,13,22,23,33} # $K_{ij}$
// partial_d_g_dd_[123]{11,12,13,22,23,33} # $\partial_k \stored{g}_{ij}$
@@ -428,6 +562,7 @@ const void* const interp_coords[N_GRID_DIMS]
const CCTK_INT input_array_variable_indices[]
= {
+ cgi.mask_varindex,
cgi.g_dd_11_varindex, cgi.g_dd_12_varindex, cgi.g_dd_13_varindex,
cgi.g_dd_22_varindex, cgi.g_dd_23_varindex,
cgi.g_dd_33_varindex,
@@ -436,19 +571,6 @@ const CCTK_INT input_array_variable_indices[]
cgi.K_dd_33_varindex,
cgi.psi_varindex,
};
-const CCTK_INT input_array_type_codes[]
- = {
- // g_ij
- CCTK_VARIABLE_REAL, CCTK_VARIABLE_REAL, CCTK_VARIABLE_REAL,
- CCTK_VARIABLE_REAL, CCTK_VARIABLE_REAL,
- CCTK_VARIABLE_REAL,
- // K_ij
- CCTK_VARIABLE_REAL, CCTK_VARIABLE_REAL, CCTK_VARIABLE_REAL,
- CCTK_VARIABLE_REAL, CCTK_VARIABLE_REAL,
- CCTK_VARIABLE_REAL,
- // psi
- CCTK_VARIABLE_REAL,
- };
const int N_input_arrays_for_psi = 1;
const int N_input_arrays_dim = sizeof(input_array_variable_indices)
/ sizeof(input_array_variable_indices[0]);
@@ -463,6 +585,8 @@ const int N_input_arrays_use
const CCTK_INT output_array_type_codes[]
= {
+ // mask $\partial_x$ mask $\partial_y$ mask $\partial_z$ mask
+ CCTK_VARIABLE_REAL, CCTK_VARIABLE_REAL, CCTK_VARIABLE_REAL, CCTK_VARIABLE_REAL,
// $g_{ij}$ $\partial_x g_{ij}$ $\partial_y g_{ij}$ $\partial_z g_{ij}$
CCTK_VARIABLE_REAL, CCTK_VARIABLE_REAL, CCTK_VARIABLE_REAL, CCTK_VARIABLE_REAL,
CCTK_VARIABLE_REAL, CCTK_VARIABLE_REAL, CCTK_VARIABLE_REAL, CCTK_VARIABLE_REAL,
@@ -480,18 +604,20 @@ const CCTK_INT output_array_type_codes[]
const CCTK_INT operand_indices[]
= {
- 0, 0, 0, 0, // g_dd_11, partial_[xyz] g_dd_11
- 1, 1, 1, 1, // g_dd_12, partial_[xyz] g_dd_12
- 2, 2, 2, 2, // g_dd_13, partial_[xyz] g_dd_13
- 3, 3, 3, 3, // g_dd_22, partial_[xyz] g_dd_22
- 4, 4, 4, 4, // g_dd_23, partial_[xyz] g_dd_23
- 5, 5, 5, 5, // g_dd_33, partial_[xyz] g_dd_33
- 6, 7, 8, 9, 10, 11, // K_dd_{11,12,13,22,23,33}
- 12, 12, 12, 12, // psi, partial_[xyz] psi
+ 0, 0, 0, 0, // mask, partial_[xyz] mask
+ 1, 1, 1, 1, // g_dd_11, partial_[xyz] g_dd_11
+ 2, 2, 2, 2, // g_dd_12, partial_[xyz] g_dd_12
+ 3, 3, 3, 3, // g_dd_13, partial_[xyz] g_dd_13
+ 4, 4, 4, 4, // g_dd_22, partial_[xyz] g_dd_22
+ 5, 5, 5, 5, // g_dd_23, partial_[xyz] g_dd_23
+ 6, 6, 6, 6, // g_dd_33, partial_[xyz] g_dd_33
+ 7, 8, 9, 10, 11, 12, // K_dd_{11,12,13,22,23,33}
+ 13, 13, 13, 13, // psi, partial_[xyz] psi
};
#define DERIV(x) x
const CCTK_INT operation_codes[]
= {
+ DERIV(0), DERIV(1), DERIV(2), DERIV(3), // mask, partial_[xyz] mask
DERIV(0), DERIV(1), DERIV(2), DERIV(3), // g_dd_11, partial_[xyz] g_dd_11
DERIV(0), DERIV(1), DERIV(2), DERIV(3), // g_dd_12, partial_[xyz] g_dd_12
DERIV(0), DERIV(1), DERIV(2), DERIV(3), // g_dd_13, partial_[xyz] g_dd_13
@@ -505,6 +631,10 @@ const CCTK_INT operation_codes[]
void* const output_arrays[]
= {
+ CAST_PTR_OR_NULL(void*, ps_ptr->gridfn_data(gfns::gfn__mask)),
+ CAST_PTR_OR_NULL(void*, ps_ptr->gridfn_data(gfns::gfn__partial_d_mask_1)),
+ CAST_PTR_OR_NULL(void*, ps_ptr->gridfn_data(gfns::gfn__partial_d_mask_2)),
+ CAST_PTR_OR_NULL(void*, ps_ptr->gridfn_data(gfns::gfn__partial_d_mask_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)),
@@ -625,6 +755,21 @@ if (print_msg_flag)
" calling geometry interpolator (%s%d points)",
(active_flag ? "" : "dummy: "), N_interp_points);
+#ifdef GEOMETRY_INTERP_DEBUG2
+ {
+ printf("AHFinderDirect:: proc %d: CCTK_InterpGridArrays() coordinates are:\n",
+ int(CCTK_MyProc(cgi.GH)));
+ for (int pt = 0 ; pt < N_interp_points ; ++ pt)
+ {
+ printf(" pt=%d [x,y,z]=[%g,%g,%g]\n",
+ pt,
+ double(((const CCTK_REAL*)interp_coords[0])[pt]),
+ double(((const CCTK_REAL*)interp_coords[1])[pt]),
+ double(((const CCTK_REAL*)interp_coords[2])[pt]));
+ }
+ }
+#endif /* GEOMETRY_INTERP_DEBUG2 */
+
#ifdef GEOMETRY_INTERP_DEBUG
printf("AHFinderDirect:: proc %d: initializing interpolator outputs to 999.999\n",
int(CCTK_MyProc(cgi.GH)));
@@ -676,8 +821,11 @@ fflush(stdout);
{
for (int pt = 0 ; pt < N_interp_points ; pt = 2*pt + (pt == 0))
{
- printf("AHFinderDirect:: proc %d: CCTK_InterpGridArrays() results for pt=%d:\n",
- int(CCTK_MyProc(cgi.GH)), pt);
+ printf("AHFinderDirect:: proc %d: CCTK_InterpGridArrays() results for pt=%d at [x,y,z]=[%g,%g,%g]:\n",
+ int(CCTK_MyProc(cgi.GH)), pt,
+ double(((const CCTK_REAL*)interp_coords[0])[pt]),
+ double(((const CCTK_REAL*)interp_coords[1])[pt]),
+ double(((const CCTK_REAL*)interp_coords[2])[pt]));
for (int out = 0 ; out < N_output_arrays_use ; ++out)
{
const CCTK_REAL* const out_ptr
@@ -743,8 +891,8 @@ if (status == CCTK_ERROR_INTERP_POINT_OUTSIDE)
CCTK_VWarn(warn_level, __LINE__, __FILE__, CCTK_THORNSTRING,
"interpolate_geometry():\n"
-" one or more points on the trial horizon surface point"
-" is/are outside the grid (or too close to the grid boundary)"
+" one or more points on the trial horizon surface point\n"
+" is/are outside the grid (or too close to the grid boundary)\n"
" (in a single-processor run, this may also mean that\n"
" driver::ghost_size is too small for this geometry interpolator)\n");
}
@@ -763,6 +911,51 @@ else if (status < 0)
"***** interpolate_geometry(): error return %d from interpolator!\n",
status); /*NOTREACHED*/
+//
+// ***** check the interpolated excision mask *****
+//
+{
+bool did_use_excised_gridpoint = false;
+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 fp m = p.gridfn(gfns::gfn__mask, irho,isigma);
+ const fp m1 = p.gridfn(gfns::gfn__partial_d_mask_1, irho,isigma);
+ const fp m2 = p.gridfn(gfns::gfn__partial_d_mask_2, irho,isigma);
+ const fp m3 = p.gridfn(gfns::gfn__partial_d_mask_3, irho,isigma);
+ if (fabs(m) > 1.0e-12
+ || fabs(m1) > 1.0e-12 || fabs(m2) > 1.0e-12 || fabs(m3) > 1.0e-12)
+ then did_use_excised_gridpoint = true;
+ }
+ }
+ }
+if (did_use_excised_gridpoint)
+ then {
+ if (print_msg_flag)
+ then {
+ // see if we can get further info
+ const int warn_level
+ = initial_flag
+ ? error_info.warn_level__point_outside__initial
+ : error_info.warn_level__point_outside__subsequent;
+
+
+ CCTK_VWarn(warn_level, __LINE__, __FILE__, CCTK_THORNSTRING,
+"interpolate_geometry():\n"
+" one or more points on the trial horizon surface point\n"
+" is/are in an excised region (or too close to the excision boundary)\n");
+ }
+
+ return expansion_failure__surface_in_excised_region; // *** ERROR RETURN ***
+ }
+}
+
return expansion_success; // *** NORMAL RETURN ***
}
}
@@ -1166,14 +1359,59 @@ return true; // *** no check possible ***
// g_ij isn't positive definite).
//
namespace {
-bool compute_Theta(patch_system& ps, fp add_to_expansion,
- bool Jacobian_flag, jtutil::norm<fp>* Theta_norms_ptr,
+bool compute_Theta(patch_system& ps, const struct what_to_compute& compute_info,
+ bool Jacobian_flag,
+ jtutil::norm<fp>* Theta_norms_ptr,
+ jtutil::norm<fp>* expansion_Theta_norms_ptr,
+ jtutil::norm<fp>* inner_expansion_Theta_norms_ptr,
+ jtutil::norm<fp>* product_expansion_Theta_norms_ptr,
+ jtutil::norm<fp>* mean_curvature_Theta_norms_ptr,
const struct error_info& error_info, bool initial_flag,
bool print_msg_flag)
{
if (print_msg_flag)
then CCTK_VInfo(CCTK_THORNSTRING, " computing Theta(h)");
+#if 0
+ fp mean_radius, areal_radius;
+ switch (compute_info.surface_modification) {
+ case modification_none:
+ case modification_radius:
+ case modification_radius2:
+ // do nothing
+ break;
+ case modification_mean_radius: {
+ // get average coordinate radius
+ const int np = ps.N_grid_points();
+ fp sum_radius = 0;
+ for (int pn = 0; pn < ps.N_patches(); ++pn) {
+ patch& p = ps.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) {
+ sum_radius += p.ghosted_gridfn(gfns::gfn__h, irho,isigma);
+ }
+ }
+ }
+ mean_radius = sum_radius / np;
+ break;
+ }
+ case modification_areal_radius: {
+ // get surface area
+ const fp area = ps.integrate_gridfn
+ (gfns::gfn__one, true, true, true,
+ gfns::gfn__h,
+ gfns::gfn__g_dd_11, gfns::gfn__g_dd_12, gfns::gfn__g_dd_13,
+ gfns::gfn__g_dd_22, gfns::gfn__g_dd_23,
+ gfns::gfn__g_dd_33,
+ patch::integration_method__automatic_choice);
+ areal_radius = sqrt(area / (4.0*PI));
+ break;
+ }
+ default:
+ assert (0);
+ }
+#endif
+
for (int pn = 0 ; pn < ps.N_patches() ; ++pn)
{
patch& p = ps.ith_patch(pn);
@@ -1284,24 +1522,169 @@ CCTK_VWarn(warn_level, __LINE__, __FILE__, CCTK_THORNSTRING,
return false; // *** ERROR RETURN ***
}
+ assert (compute_info.surface_selection == selection_definition);
+
// compute H via equation (14) of my 1996 horizon finding paper
const fp sqrt_Theta_D = sqrt(Theta_D);
- Theta = + Theta_A/(Theta_D*sqrt_Theta_D)
- + Theta_B/sqrt_Theta_D
- + Theta_C/Theta_D
- - K
- + add_to_expansion;
+ const fp Theta_X = + Theta_A/(Theta_D*sqrt_Theta_D)
+ + Theta_B/sqrt_Theta_D;
+ const fp Theta_Y = + Theta_C/Theta_D
+ - K;
+
+#define mean_curvature p.gridfn(gfns::gfn__mean_curvature, irho,isigma)
+ mean_curvature = Theta_X;
+#undef mean_curvature
+
+ switch (compute_info.surface_definition) {
+ case definition_expansion:
+ Theta = + Theta_X + Theta_Y;
+ break;
+ case definition_inner_expansion:
+ Theta = - Theta_X + Theta_Y;
+ break;
+ case definition_mean_curvature:
+ Theta = + Theta_X;
+ break;
+ case definition_expansion_product:
+ Theta = (+ Theta_X + Theta_Y) * (- Theta_X + Theta_Y);
+ break;
+ default:
+ assert (0);
+ }
+
+ switch (compute_info.surface_modification) {
+ case modification_none:
+ // do nothing
+ break;
+ case modification_radius:
+ // multiply by radius
+ Theta *= r;
+ break;
+ case modification_radius2:
+ // multiply by radius^2
+ Theta *= pow2(r);
+ break;
+#if 0
+ case modification_mean_radius:
+ // multiply by average coordinate radius
+ Theta *= mean_radius;
+ break;
+ case modification_areal_radius:
+ // multiply by areal radius
+ Theta *= areal_radius;
+ break;
+#endif
+ default:
+ assert (0);
+ }
+
+ Theta -= compute_info.desired_value;
+
// update running norms of Theta(h) function
if (Theta_norms_ptr != NULL)
then Theta_norms_ptr->data(Theta);
+ if (expansion_Theta_norms_ptr != NULL)
+ then expansion_Theta_norms_ptr->data(+ Theta_X + Theta_Y);
+
+ if (inner_expansion_Theta_norms_ptr != NULL)
+ then inner_expansion_Theta_norms_ptr->data(- Theta_X + Theta_Y);
+
+ if (product_expansion_Theta_norms_ptr != NULL)
+ then product_expansion_Theta_norms_ptr->data((+ Theta_X + Theta_Y) * (- Theta_X + Theta_Y));
+
+ if (mean_curvature_Theta_norms_ptr != NULL)
+ then mean_curvature_Theta_norms_ptr->data(+ Theta_X);
+
+ fp partial_Theta_X_wrt_partial_d_h_1;
+ fp partial_Theta_X_wrt_partial_d_h_2;
+ fp partial_Theta_X_wrt_partial_dd_h_11;
+ fp partial_Theta_X_wrt_partial_dd_h_12;
+ fp partial_Theta_X_wrt_partial_dd_h_22;
+ fp partial_Theta_Y_wrt_partial_d_h_1;
+ fp partial_Theta_Y_wrt_partial_d_h_2;
+ fp partial_Theta_Y_wrt_partial_dd_h_11;
+ fp partial_Theta_Y_wrt_partial_dd_h_12;
+ fp partial_Theta_Y_wrt_partial_dd_h_22;
+
if (Jacobian_flag)
then {
// partial_Theta_wrt_partial_d_h,
// partial_Theta_wrt_partial_dd_h
#include "../gr.cg/expansion_Jacobian.c"
}
+
+ if (Jacobian_flag) {
+ switch (compute_info.surface_definition) {
+
+ case definition_expansion:
+ partial_Theta_wrt_partial_d_h_1
+ = (+ partial_Theta_X_wrt_partial_d_h_1
+ + partial_Theta_Y_wrt_partial_d_h_1);
+ partial_Theta_wrt_partial_d_h_2
+ = (+ partial_Theta_X_wrt_partial_d_h_2
+ + partial_Theta_Y_wrt_partial_d_h_2);
+ partial_Theta_wrt_partial_dd_h_11
+ = (+ partial_Theta_X_wrt_partial_dd_h_11
+ + partial_Theta_Y_wrt_partial_dd_h_11);
+ partial_Theta_wrt_partial_dd_h_12
+ = (+ partial_Theta_X_wrt_partial_dd_h_12
+ + partial_Theta_Y_wrt_partial_dd_h_12);
+ partial_Theta_wrt_partial_dd_h_22
+ = (+ partial_Theta_X_wrt_partial_dd_h_22
+ + partial_Theta_Y_wrt_partial_dd_h_22);
+ break;
+
+ case definition_inner_expansion:
+ partial_Theta_wrt_partial_d_h_1
+ = (- partial_Theta_X_wrt_partial_d_h_1
+ + partial_Theta_Y_wrt_partial_d_h_1);
+ partial_Theta_wrt_partial_d_h_2
+ = (- partial_Theta_X_wrt_partial_d_h_2
+ + partial_Theta_Y_wrt_partial_d_h_2);
+ partial_Theta_wrt_partial_dd_h_11
+ = (- partial_Theta_X_wrt_partial_dd_h_11
+ + partial_Theta_Y_wrt_partial_dd_h_11);
+ partial_Theta_wrt_partial_dd_h_12
+ = (- partial_Theta_X_wrt_partial_dd_h_12
+ + partial_Theta_Y_wrt_partial_dd_h_12);
+ partial_Theta_wrt_partial_dd_h_22
+ = (- partial_Theta_X_wrt_partial_dd_h_22
+ + partial_Theta_Y_wrt_partial_dd_h_22);
+ break;
+
+ case definition_mean_curvature:
+ partial_Theta_wrt_partial_d_h_1
+ = + partial_Theta_X_wrt_partial_d_h_1;
+ partial_Theta_wrt_partial_d_h_2
+ = + partial_Theta_X_wrt_partial_d_h_2;
+ partial_Theta_wrt_partial_dd_h_11
+ = + partial_Theta_X_wrt_partial_dd_h_11;
+ partial_Theta_wrt_partial_dd_h_12
+ = + partial_Theta_X_wrt_partial_dd_h_12;
+ partial_Theta_wrt_partial_dd_h_22
+ = + partial_Theta_X_wrt_partial_dd_h_22;
+ break;
+
+ case definition_expansion_product: {
+#define f(x,y,dx,dy) (- x*x + y*y)
+#define df(x,y,dx,dy) (- 2*x*dx + 2*y*dy)
+ partial_Theta_wrt_partial_d_h_1 = df(Theta_X, Theta_Y, partial_Theta_X_wrt_partial_d_h_1 , partial_Theta_Y_wrt_partial_d_h_1 );
+ partial_Theta_wrt_partial_d_h_2 = df(Theta_X, Theta_Y, partial_Theta_X_wrt_partial_d_h_2 , partial_Theta_Y_wrt_partial_d_h_2 );
+ partial_Theta_wrt_partial_dd_h_11 = df(Theta_X, Theta_Y, partial_Theta_X_wrt_partial_dd_h_11, partial_Theta_Y_wrt_partial_dd_h_11);
+ partial_Theta_wrt_partial_dd_h_12 = df(Theta_X, Theta_Y, partial_Theta_X_wrt_partial_dd_h_12, partial_Theta_Y_wrt_partial_dd_h_12);
+ partial_Theta_wrt_partial_dd_h_22 = df(Theta_X, Theta_Y, partial_Theta_X_wrt_partial_dd_h_22, partial_Theta_Y_wrt_partial_dd_h_22);
+#undef f
+#undef df
+ break;
+ }
+
+ default:
+ assert (0);
+ }
+ }
+
}
}
}