725 lines
28 KiB
C
725 lines
28 KiB
C
#include <stdio.h>
|
|
#include <assert.h>
|
|
#include <math.h>
|
|
|
|
#include "util_Table.h"
|
|
#include "cctk.h"
|
|
|
|
#include "config.h"
|
|
#include "stdc.h"
|
|
#include "util.h"
|
|
#include "array.h"
|
|
#include "cpm_map.h"
|
|
#include "linear_map.h"
|
|
|
|
#include "coords.h"
|
|
#include "tgrid.h"
|
|
#include "fd_grid.h"
|
|
#include "patch.h"
|
|
#include "patch_edge.h"
|
|
#include "patch_interp.h"
|
|
#include "ghost_zone.h"
|
|
#include "patch_system.h"
|
|
|
|
#include "Jacobian.h"
|
|
|
|
#include "gfns.h"
|
|
#include "gr.h"
|
|
#include "myglobal.h"
|
|
|
|
#include "horizon_sequence.h"
|
|
#include "BH_diagnostics.h"
|
|
#include "driver.h"
|
|
|
|
namespace AHFinderDirect
|
|
{
|
|
using jtutil::error_exit;
|
|
|
|
BH_diagnostics::BH_diagnostics()
|
|
: centroid_x(0.0), centroid_y(0.0), centroid_z(0.0),
|
|
quadrupole_xx(0.0), quadrupole_xy(0.0), quadrupole_xz(0.0),
|
|
quadrupole_yy(0.0), quadrupole_yz(0.0),
|
|
quadrupole_zz(0.0),
|
|
min_radius(0.0), max_radius(0.0),
|
|
mean_radius(0.0),
|
|
min_x(0.0), max_x(0.0),
|
|
min_y(0.0), max_y(0.0),
|
|
min_z(0.0), max_z(0.0),
|
|
circumference_xy(0.0), circumference_xz(0.0), circumference_yz(0.0),
|
|
area(0.0), irreducible_mass(0.0), areal_radius(0.0) // no comma
|
|
{
|
|
}
|
|
|
|
void BH_diagnostics::copy_to_buffer(double buffer[N_buffer])
|
|
const
|
|
{
|
|
buffer[posn__centroid_x] = centroid_x;
|
|
buffer[posn__centroid_y] = centroid_y;
|
|
buffer[posn__centroid_z] = centroid_z;
|
|
|
|
buffer[posn__quadrupole_xx] = quadrupole_xx;
|
|
buffer[posn__quadrupole_xy] = quadrupole_xy;
|
|
buffer[posn__quadrupole_xz] = quadrupole_xz;
|
|
buffer[posn__quadrupole_yy] = quadrupole_yy;
|
|
buffer[posn__quadrupole_xz] = quadrupole_yz;
|
|
buffer[posn__quadrupole_zz] = quadrupole_zz;
|
|
|
|
buffer[posn__min_radius] = min_radius;
|
|
buffer[posn__max_radius] = max_radius;
|
|
buffer[posn__mean_radius] = mean_radius;
|
|
|
|
buffer[posn__min_x] = min_x;
|
|
buffer[posn__max_x] = max_x;
|
|
buffer[posn__min_y] = min_y;
|
|
buffer[posn__max_y] = max_y;
|
|
buffer[posn__min_z] = min_z;
|
|
buffer[posn__max_z] = max_z;
|
|
|
|
buffer[posn__circumference_xy] = circumference_xy;
|
|
buffer[posn__circumference_xz] = circumference_xz;
|
|
buffer[posn__circumference_yz] = circumference_yz;
|
|
|
|
buffer[posn__area] = area;
|
|
buffer[posn__irreducible_mass] = irreducible_mass;
|
|
buffer[posn__areal_radius] = areal_radius;
|
|
}
|
|
|
|
void BH_diagnostics::copy_from_buffer(const double buffer[N_buffer])
|
|
{
|
|
centroid_x = buffer[posn__centroid_x];
|
|
centroid_y = buffer[posn__centroid_y];
|
|
centroid_z = buffer[posn__centroid_z];
|
|
|
|
quadrupole_xx = buffer[posn__quadrupole_xx];
|
|
quadrupole_xy = buffer[posn__quadrupole_xy];
|
|
quadrupole_xz = buffer[posn__quadrupole_xz];
|
|
quadrupole_yy = buffer[posn__quadrupole_yy];
|
|
quadrupole_yz = buffer[posn__quadrupole_yz];
|
|
quadrupole_zz = buffer[posn__quadrupole_zz];
|
|
|
|
min_radius = buffer[posn__min_radius];
|
|
max_radius = buffer[posn__max_radius];
|
|
mean_radius = buffer[posn__mean_radius];
|
|
|
|
min_x = buffer[posn__min_x];
|
|
max_x = buffer[posn__max_x];
|
|
min_y = buffer[posn__min_y];
|
|
max_y = buffer[posn__max_y];
|
|
min_z = buffer[posn__min_z];
|
|
max_z = buffer[posn__max_z];
|
|
|
|
circumference_xy = buffer[posn__circumference_xy];
|
|
circumference_xz = buffer[posn__circumference_xz];
|
|
circumference_yz = buffer[posn__circumference_yz];
|
|
|
|
area = buffer[posn__area];
|
|
irreducible_mass = buffer[posn__irreducible_mass];
|
|
areal_radius = buffer[posn__areal_radius];
|
|
}
|
|
void BH_diagnostics::compute(patch_system &ps)
|
|
{
|
|
jtutil::norm<fp> h_norms;
|
|
ps.ghosted_gridfn_norms(gfns::gfn__h, h_norms);
|
|
min_radius = h_norms.min_abs_value();
|
|
max_radius = h_norms.max_abs_value();
|
|
|
|
jtutil::norm<fp> x_norms;
|
|
jtutil::norm<fp> y_norms;
|
|
jtutil::norm<fp> z_norms;
|
|
|
|
ps.gridfn_norms(gfns::gfn__global_x, x_norms);
|
|
ps.gridfn_norms(gfns::gfn__global_y, y_norms);
|
|
ps.gridfn_norms(gfns::gfn__global_z, z_norms);
|
|
|
|
min_x = x_norms.min_value();
|
|
max_x = x_norms.max_value();
|
|
min_y = y_norms.min_value();
|
|
max_y = y_norms.max_value();
|
|
min_z = z_norms.min_value();
|
|
max_z = z_norms.max_value();
|
|
|
|
// adjust the bounding box for the symmetries
|
|
#define REFLECT(origin_, max_) (origin_ - (max_ - origin_))
|
|
switch (ps.type())
|
|
{
|
|
case patch_system::patch_system__full_sphere:
|
|
break;
|
|
case patch_system::patch_system__plus_z_hemisphere:
|
|
min_z = REFLECT(ps.origin_z(), max_z);
|
|
break;
|
|
case patch_system::patch_system__plus_xy_quadrant_mirrored:
|
|
case patch_system::patch_system__plus_xy_quadrant_rotating:
|
|
min_x = REFLECT(ps.origin_x(), max_x);
|
|
min_y = REFLECT(ps.origin_y(), max_y);
|
|
break;
|
|
case patch_system::patch_system__plus_xz_quadrant_mirrored:
|
|
case patch_system::patch_system__plus_xz_quadrant_rotating:
|
|
min_x = REFLECT(ps.origin_x(), max_x);
|
|
min_z = REFLECT(ps.origin_z(), max_z);
|
|
break;
|
|
case patch_system::patch_system__plus_xyz_octant_mirrored:
|
|
case patch_system::patch_system__plus_xyz_octant_rotating:
|
|
min_x = REFLECT(ps.origin_x(), max_x);
|
|
min_y = REFLECT(ps.origin_y(), max_y);
|
|
min_z = REFLECT(ps.origin_z(), max_z);
|
|
break;
|
|
default:
|
|
error_exit(PANIC_EXIT,
|
|
"***** BH_diagnostics::compute(): unknown patch system type()=(int)%d!\n"
|
|
" (this should never happen!)\n",
|
|
int(ps.type())); /*NOTREACHED*/
|
|
}
|
|
|
|
//
|
|
// surface integrals
|
|
//
|
|
const fp integral_one = surface_integral(ps,
|
|
gfns::gfn__one, true, true, true,
|
|
patch::integration_method__automatic_choice);
|
|
const fp integral_h = surface_integral(ps,
|
|
gfns::gfn__h, true, true, true,
|
|
patch::integration_method__automatic_choice);
|
|
const fp integral_x = surface_integral(ps,
|
|
gfns::gfn__global_x, true, true, false,
|
|
patch::integration_method__automatic_choice);
|
|
const fp integral_y = surface_integral(ps,
|
|
gfns::gfn__global_y, true, false, true,
|
|
patch::integration_method__automatic_choice);
|
|
const fp integral_z = surface_integral(ps,
|
|
gfns::gfn__global_z, false, true, true,
|
|
patch::integration_method__automatic_choice);
|
|
const fp integral_xx = surface_integral(ps,
|
|
gfns::gfn__global_xx, true, true, true,
|
|
patch::integration_method__automatic_choice);
|
|
const fp integral_xy = surface_integral(ps,
|
|
gfns::gfn__global_xy, true, false, false,
|
|
patch::integration_method__automatic_choice);
|
|
const fp integral_xz = surface_integral(ps,
|
|
gfns::gfn__global_xz, false, true, false,
|
|
patch::integration_method__automatic_choice);
|
|
const fp integral_yy = surface_integral(ps,
|
|
gfns::gfn__global_yy, true, true, true,
|
|
patch::integration_method__automatic_choice);
|
|
const fp integral_yz = surface_integral(ps,
|
|
gfns::gfn__global_yz, false, false, true,
|
|
patch::integration_method__automatic_choice);
|
|
const fp integral_zz = surface_integral(ps,
|
|
gfns::gfn__global_zz, true, true, true,
|
|
patch::integration_method__automatic_choice);
|
|
|
|
//
|
|
// centroids
|
|
//
|
|
centroid_x = integral_x / integral_one;
|
|
centroid_y = integral_y / integral_one;
|
|
centroid_z = integral_z / integral_one;
|
|
|
|
//
|
|
// quadrupoles (taken about centroid position)
|
|
//
|
|
quadrupole_xx = integral_xx / integral_one - centroid_x * centroid_x;
|
|
quadrupole_xy = integral_xy / integral_one - centroid_x * centroid_y;
|
|
quadrupole_xz = integral_xz / integral_one - centroid_x * centroid_z;
|
|
quadrupole_yy = integral_yy / integral_one - centroid_y * centroid_y;
|
|
quadrupole_yz = integral_yz / integral_one - centroid_y * centroid_z;
|
|
quadrupole_zz = integral_zz / integral_one - centroid_z * centroid_z;
|
|
|
|
//
|
|
// mean radius of horizon
|
|
//
|
|
mean_radius = integral_h / integral_one;
|
|
|
|
//
|
|
// surface area and quantities derived from it
|
|
//
|
|
area = integral_one;
|
|
irreducible_mass = sqrt(area / (16.0 * PI));
|
|
areal_radius = sqrt(area / (4.0 * PI));
|
|
|
|
//
|
|
// proper circumferences
|
|
//
|
|
circumference_xy = ps.circumference("xy", 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);
|
|
circumference_xz = ps.circumference("xz", 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);
|
|
circumference_yz = ps.circumference("yz", 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);
|
|
|
|
// prepare P^i,S^i in xx,xy,xz and yy,yz,zz
|
|
{
|
|
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)
|
|
{
|
|
const fp g_xx = p.gridfn(gfns::gfn__g_dd_11, irho, isigma);
|
|
const fp g_xy = p.gridfn(gfns::gfn__g_dd_12, irho, isigma);
|
|
const fp g_xz = p.gridfn(gfns::gfn__g_dd_13, irho, isigma);
|
|
const fp g_yy = p.gridfn(gfns::gfn__g_dd_22, irho, isigma);
|
|
const fp g_yz = p.gridfn(gfns::gfn__g_dd_23, irho, isigma);
|
|
const fp g_zz = p.gridfn(gfns::gfn__g_dd_33, irho, isigma);
|
|
|
|
const fp k_xx = p.gridfn(gfns::gfn__K_dd_11, irho, isigma);
|
|
const fp k_xy = p.gridfn(gfns::gfn__K_dd_12, irho, isigma);
|
|
const fp k_xz = p.gridfn(gfns::gfn__K_dd_13, irho, isigma);
|
|
const fp k_yy = p.gridfn(gfns::gfn__K_dd_22, irho, isigma);
|
|
const fp k_yz = p.gridfn(gfns::gfn__K_dd_23, irho, isigma);
|
|
const fp k_zz = p.gridfn(gfns::gfn__K_dd_33, irho, isigma);
|
|
const fp trk = p.gridfn(gfns::gfn__trK, 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 xx, yy, zz; // local Cardesian coordinate
|
|
p.xyz_of_r_rho_sigma(r, rho, sigma, xx, yy, zz);
|
|
const fp X_ud_11 = p.partial_rho_wrt_x(xx, yy, zz);
|
|
const fp X_ud_12 = p.partial_rho_wrt_y(xx, yy, zz);
|
|
const fp X_ud_13 = p.partial_rho_wrt_z(xx, yy, zz);
|
|
const fp X_ud_21 = p.partial_sigma_wrt_x(xx, yy, zz);
|
|
const fp X_ud_22 = p.partial_sigma_wrt_y(xx, yy, zz);
|
|
const fp X_ud_23 = p.partial_sigma_wrt_z(xx, yy, zz);
|
|
#if 0 // for P^i and S^i
|
|
// F,i = x^i/r-X_ud_1i(dh/drho)-X_ud_2i(dh/dsigma)
|
|
double nx,ny,nz;
|
|
nx = xx/r-X_ud_11*p.partial_rho(gfns::gfn__h, irho,isigma)-X_ud_21*p.partial_sigma(gfns::gfn__h, irho,isigma);
|
|
ny = yy/r-X_ud_12*p.partial_rho(gfns::gfn__h, irho,isigma)-X_ud_22*p.partial_sigma(gfns::gfn__h, irho,isigma);
|
|
nz = zz/r-X_ud_13*p.partial_rho(gfns::gfn__h, irho,isigma)-X_ud_23*p.partial_sigma(gfns::gfn__h, irho,isigma);
|
|
double eps; // volume element
|
|
fp g_uu_11, g_uu_12, g_uu_13, g_uu_22, g_uu_23, g_uu_33;
|
|
double pxx,pxy,pxz,pyy,pyz,pzz;
|
|
{
|
|
fp t1, t2, t4, t5, t7, t8, t11, t12, t14, t15;
|
|
fp t18, t21;
|
|
t1 = g_yy;
|
|
t2 = g_zz;
|
|
t4 = g_yz;
|
|
t5 = t4*t4;
|
|
t7 = g_xx;
|
|
t8 = t7*t1;
|
|
t11 = g_xy;
|
|
t12 = t11*t11;
|
|
t14 = g_xz;
|
|
t15 = t11*t14;
|
|
t18 = t14*t14;
|
|
eps = t8*t2-t7*t5-t12*t2+2.0*t15*t4-t18*t1;
|
|
t21 = 1/eps;
|
|
eps = sqrt(eps);
|
|
g_uu_11 = (t1*t2-t5)*t21;
|
|
g_uu_12 = -(t11*t2-t14*t4)*t21;
|
|
g_uu_13 = -(-t11*t4+t14*t1)*t21;
|
|
g_uu_22 = (t7*t2-t18)*t21;
|
|
g_uu_23 = -(t7*t4-t15)*t21;
|
|
g_uu_33 = (t8-t12)*t21;
|
|
|
|
t5 = g_uu_11*nx*nx+g_uu_22*ny*ny+g_uu_33*nz*nz+2*(g_uu_12*nx*ny+g_uu_13*nx*nz+g_uu_23*ny*nz);
|
|
t5 = sqrt(t5);
|
|
nx = nx/t5; // lower index
|
|
ny = ny/t5;
|
|
nz = nz/t5;
|
|
|
|
pxx= g_uu_11*(g_uu_11*k_xx+g_uu_12*k_xy+g_uu_13*k_xz)
|
|
+g_uu_12*(g_uu_11*k_xy+g_uu_12*k_yy+g_uu_13*k_yz)
|
|
+g_uu_13*(g_uu_11*k_xz+g_uu_12*k_yz+g_uu_13*k_zz); //k^xx
|
|
pxy= g_uu_11*(g_uu_12*k_xx+g_uu_22*k_xy+g_uu_23*k_xz)
|
|
+g_uu_12*(g_uu_12*k_xy+g_uu_22*k_yy+g_uu_23*k_yz)
|
|
+g_uu_13*(g_uu_12*k_xz+g_uu_22*k_yz+g_uu_23*k_zz); //k^xy
|
|
pxz= g_uu_11*(g_uu_13*k_xx+g_uu_23*k_xy+g_uu_33*k_xz)
|
|
+g_uu_12*(g_uu_13*k_xy+g_uu_23*k_yy+g_uu_33*k_yz)
|
|
+g_uu_13*(g_uu_13*k_xz+g_uu_23*k_yz+g_uu_33*k_zz); //k^xz
|
|
pyy= g_uu_12*(g_uu_12*k_xx+g_uu_22*k_xy+g_uu_23*k_xz)
|
|
+g_uu_22*(g_uu_12*k_xy+g_uu_22*k_yy+g_uu_23*k_yz)
|
|
+g_uu_23*(g_uu_12*k_xz+g_uu_22*k_yz+g_uu_23*k_zz); //k^yy
|
|
pyz= g_uu_12*(g_uu_13*k_xx+g_uu_23*k_xy+g_uu_33*k_xz)
|
|
+g_uu_22*(g_uu_13*k_xy+g_uu_23*k_yy+g_uu_33*k_yz)
|
|
+g_uu_23*(g_uu_13*k_xz+g_uu_23*k_yz+g_uu_33*k_zz); //k^yz
|
|
pzz= g_uu_13*(g_uu_13*k_xx+g_uu_23*k_xy+g_uu_33*k_xz)
|
|
+g_uu_23*(g_uu_13*k_xy+g_uu_23*k_yy+g_uu_33*k_yz)
|
|
+g_uu_33*(g_uu_13*k_xz+g_uu_23*k_yz+g_uu_33*k_zz); //k^zz
|
|
}
|
|
|
|
pxx = pxx-g_uu_11*trk; // tracefree
|
|
pyy = pyy-g_uu_22*trk;
|
|
pzz = pzz-g_uu_33*trk;
|
|
double tx,ty,tz;
|
|
double sxx,sxy,sxz,syx,syy,syz,szx,szy,szz;
|
|
tx = nx*pxx + ny*pxy + nz*pxz;
|
|
ty = nx*pxy + ny*pyy + nz*pyz;
|
|
tz = nx*pxz + ny*pyz + nz*pzz;
|
|
sxx = xx*tx;
|
|
sxy = xx*ty;
|
|
sxz = xx*tz;
|
|
syx = yy*tx;
|
|
syy = yy*ty;
|
|
syz = yy*tz;
|
|
szx = zz*tx;
|
|
szy = zz*ty;
|
|
szz = zz*tz;
|
|
p.gridfn(gfns::gfn__global_xx, irho,isigma) = tx; //p^x
|
|
p.gridfn(gfns::gfn__global_xy, irho,isigma) = ty; //p^y
|
|
p.gridfn(gfns::gfn__global_xz, irho,isigma) = tz; //p^z
|
|
tx = eps*(syz-szy); //s_x
|
|
ty = eps*(szx-sxz);
|
|
tz = eps*(sxy-syx);
|
|
p.gridfn(gfns::gfn__global_yy, irho,isigma) = g_uu_11*tx+g_uu_12*ty+g_uu_13*tz; //s^x
|
|
p.gridfn(gfns::gfn__global_yz, irho,isigma) = g_uu_12*tx+g_uu_22*ty+g_uu_23*tz; //s^y
|
|
p.gridfn(gfns::gfn__global_zz, irho,isigma) = g_uu_13*tx+g_uu_23*ty+g_uu_33*tz; //s^z
|
|
#endif
|
|
#if 1 // for P_i and S_i
|
|
// F,i = x^i/r-X_ud_1i(dh/drho)-X_ud_2i(dh/dsigma)
|
|
double nx, ny, nz;
|
|
nx = xx / r - X_ud_11 * p.partial_rho(gfns::gfn__h, irho, isigma) - X_ud_21 * p.partial_sigma(gfns::gfn__h, irho, isigma);
|
|
ny = yy / r - X_ud_12 * p.partial_rho(gfns::gfn__h, irho, isigma) - X_ud_22 * p.partial_sigma(gfns::gfn__h, irho, isigma);
|
|
nz = zz / r - X_ud_13 * p.partial_rho(gfns::gfn__h, irho, isigma) - X_ud_23 * p.partial_sigma(gfns::gfn__h, irho, isigma);
|
|
{
|
|
fp g_uu_11, g_uu_12, g_uu_13, g_uu_22, g_uu_23, g_uu_33;
|
|
fp t1, t2, t4, t5, t7, t8, t11, t12, t14, t15;
|
|
fp t18, t21;
|
|
t1 = g_yy;
|
|
t2 = g_zz;
|
|
t4 = g_yz;
|
|
t5 = t4 * t4;
|
|
t7 = g_xx;
|
|
t8 = t7 * t1;
|
|
t11 = g_xy;
|
|
t12 = t11 * t11;
|
|
t14 = g_xz;
|
|
t15 = t11 * t14;
|
|
t18 = t14 * t14;
|
|
t21 = 1 / (t8 * t2 - t7 * t5 - t12 * t2 + 2.0 * t15 * t4 - t18 * t1);
|
|
g_uu_11 = (t1 * t2 - t5) * t21;
|
|
g_uu_12 = -(t11 * t2 - t14 * t4) * t21;
|
|
g_uu_13 = -(-t11 * t4 + t14 * t1) * t21;
|
|
g_uu_22 = (t7 * t2 - t18) * t21;
|
|
g_uu_23 = -(t7 * t4 - t15) * t21;
|
|
g_uu_33 = (t8 - t12) * t21;
|
|
|
|
t1 = g_uu_11 * nx + g_uu_12 * ny + g_uu_13 * nz;
|
|
t2 = g_uu_12 * nx + g_uu_22 * ny + g_uu_23 * nz;
|
|
t4 = g_uu_13 * nx + g_uu_23 * ny + g_uu_33 * nz;
|
|
t5 = g_uu_11 * nx * nx + g_uu_22 * ny * ny + g_uu_33 * nz * nz + 2 * (g_uu_12 * nx * ny + g_uu_13 * nx * nz + g_uu_23 * ny * nz);
|
|
t5 = sqrt(t5);
|
|
nx = t1 / t5; // uper index
|
|
ny = t2 / t5;
|
|
nz = t4 / t5;
|
|
}
|
|
|
|
double pxx, pxy, pxz, pyy, pyz, pzz;
|
|
double sxx, sxy, sxz, syx, syy, syz, szx, szy, szz;
|
|
// these tensor components are same for local Cardisean and global Cardisean
|
|
pxx = k_xx - g_xx * trk; // lower index
|
|
pxy = k_xy;
|
|
pxz = k_xz;
|
|
pyy = k_yy - g_yy * trk;
|
|
pyz = k_yz;
|
|
pzz = k_zz - g_zz * trk;
|
|
/*
|
|
sxx = yy*pxy - zz*pxz;
|
|
sxy = yy*pyy - zz*pyz;
|
|
sxz = yy*pyz - zz*pzz;
|
|
syx = zz*pxy - yy*pxz;
|
|
syy = zz*pyy - yy*pyz;
|
|
syz = zz*pyz - yy*pzz;
|
|
szx = xx*pxy - yy*pxx;
|
|
szy = xx*pyy - yy*pxy;
|
|
szz = xx*pyz - yy*pxz;
|
|
*/
|
|
// we need Cardisean coordinate whose original point coincide with centroid_x^i
|
|
xx = p.gridfn(gfns::gfn__global_x, irho, isigma) - centroid_x;
|
|
yy = p.gridfn(gfns::gfn__global_y, irho, isigma) - centroid_y;
|
|
zz = p.gridfn(gfns::gfn__global_z, irho, isigma) - centroid_z;
|
|
sxx = yy * pxz - zz * pxy;
|
|
sxy = zz * pxx - xx * pxz;
|
|
sxz = xx * pxy - yy * pxx;
|
|
syx = yy * pyz - zz * pyy;
|
|
syy = zz * pxy - xx * pyz;
|
|
syz = xx * pyy - yy * pxy;
|
|
szx = yy * pzz - zz * pyz;
|
|
szy = zz * pxz - xx * pzz;
|
|
szz = xx * pyz - yy * pxz;
|
|
|
|
p.gridfn(gfns::gfn__global_xx, irho, isigma) = nx * pxx + ny * pxy + nz * pxz; // p_x
|
|
p.gridfn(gfns::gfn__global_xy, irho, isigma) = nx * pxy + ny * pyy + nz * pyz; // p_y
|
|
p.gridfn(gfns::gfn__global_xz, irho, isigma) = nx * pxz + ny * pyz + nz * pzz; // p_z
|
|
p.gridfn(gfns::gfn__global_yy, irho, isigma) = nx * sxx + ny * syx + nz * szx; // s_x
|
|
p.gridfn(gfns::gfn__global_yz, irho, isigma) = nx * sxy + ny * syy + nz * szy; // s_y
|
|
p.gridfn(gfns::gfn__global_zz, irho, isigma) = nx * sxz + ny * syz + nz * szz; // s_z
|
|
#endif
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Px = surface_integral(ps,
|
|
gfns::gfn__global_xx, true, true, false, // z,y,x direction, even or odd function
|
|
patch::integration_method__automatic_choice);
|
|
Py = surface_integral(ps,
|
|
gfns::gfn__global_xy, true, false, true,
|
|
patch::integration_method__automatic_choice);
|
|
Pz = surface_integral(ps,
|
|
gfns::gfn__global_xz, false, true, true,
|
|
patch::integration_method__automatic_choice);
|
|
Sx = surface_integral(ps,
|
|
gfns::gfn__global_yy, false, false, true,
|
|
patch::integration_method__automatic_choice);
|
|
Sy = surface_integral(ps,
|
|
gfns::gfn__global_yz, false, true, false,
|
|
patch::integration_method__automatic_choice);
|
|
Sz = surface_integral(ps,
|
|
gfns::gfn__global_zz, true, false, false,
|
|
patch::integration_method__automatic_choice);
|
|
const double F1o8pi = 1.0 / 8 / PI;
|
|
Px = Px * F1o8pi;
|
|
Py = Py * F1o8pi;
|
|
Pz = Pz * F1o8pi;
|
|
Sx = Sx * F1o8pi;
|
|
Sy = Sy * F1o8pi;
|
|
Sz = Sz * F1o8pi;
|
|
}
|
|
|
|
//******************************************************************************
|
|
|
|
//
|
|
// This function computes the surface integral of a gridfn over the
|
|
// horizon.
|
|
//
|
|
fp BH_diagnostics::surface_integral(const patch_system &ps,
|
|
int src_gfn, bool src_gfn_is_even_across_xy_plane,
|
|
bool src_gfn_is_even_across_xz_plane,
|
|
bool src_gfn_is_even_across_yz_plane,
|
|
enum patch::integration_method method)
|
|
{
|
|
return ps.integrate_gridfn(src_gfn, src_gfn_is_even_across_xy_plane,
|
|
src_gfn_is_even_across_xz_plane,
|
|
src_gfn_is_even_across_yz_plane,
|
|
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,
|
|
method);
|
|
}
|
|
// with triad theta and phi
|
|
// since Thornburg uses vertex center, we will meet nan at pole points
|
|
void BH_diagnostics::compute_signature(patch_system &ps, const double dT)
|
|
{
|
|
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)
|
|
{
|
|
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 xx, yy, zz;
|
|
p.xyz_of_r_rho_sigma(r, rho, sigma, xx, yy, zz);
|
|
|
|
const fp sintheta = sqrt(1 - zz * zz / r / r);
|
|
|
|
const fp X_ud_11 = xx * zz / r / r / sqrt(xx * xx + yy * yy);
|
|
const fp X_ud_12 = yy * zz / r / r / sqrt(xx * xx + yy * yy);
|
|
const fp X_ud_13 = -sqrt(xx * xx + yy * yy) / r / r;
|
|
const fp X_ud_21 = -yy / (xx * xx + yy * yy);
|
|
const fp X_ud_22 = xx / (xx * xx + yy * yy);
|
|
const fp X_ud_23 = 0;
|
|
|
|
const fp g_dd_11 = p.gridfn(gfns::gfn__g_dd_11, irho, isigma);
|
|
const fp g_dd_12 = p.gridfn(gfns::gfn__g_dd_12, irho, isigma);
|
|
const fp g_dd_13 = p.gridfn(gfns::gfn__g_dd_13, irho, isigma);
|
|
const fp g_dd_22 = p.gridfn(gfns::gfn__g_dd_22, irho, isigma);
|
|
const fp g_dd_23 = p.gridfn(gfns::gfn__g_dd_23, irho, isigma);
|
|
const fp g_dd_33 = p.gridfn(gfns::gfn__g_dd_33, irho, isigma);
|
|
|
|
const fp Lap = 1.0 + p.gridfn(gfns::gfn__global_xx, irho, isigma);
|
|
const fp Sfx = p.gridfn(gfns::gfn__global_xy, irho, isigma);
|
|
const fp Sfy = p.gridfn(gfns::gfn__global_xz, irho, isigma);
|
|
const fp Sfz = p.gridfn(gfns::gfn__global_yy, irho, isigma);
|
|
|
|
const fp dfdt = (r - p.gridfn(gfns::gfn__oldh, irho, isigma)) / dT;
|
|
|
|
double Br = Sfx * xx / r + Sfy * yy / r + Sfz * zz / r;
|
|
double Brho = Sfx * X_ud_11 + Sfy * X_ud_12 + Sfz * X_ud_13;
|
|
double Bsigma = Sfx * X_ud_21 + Sfy * X_ud_22 + Sfz * X_ud_23;
|
|
|
|
double g_uu_11, g_uu_12, g_uu_13, g_uu_22, g_uu_23, g_uu_33;
|
|
double g11, g12, g13, g22, g23, g33;
|
|
{
|
|
// g^uu
|
|
fp t1, t2, t4, t5, t7, t8, t11, t12, t14, t15;
|
|
fp t18, t21;
|
|
t1 = g_dd_22;
|
|
t2 = g_dd_33;
|
|
t4 = g_dd_23;
|
|
t5 = t4 * t4;
|
|
t7 = g_dd_11;
|
|
t8 = t7 * t1;
|
|
t11 = g_dd_12;
|
|
t12 = t11 * t11;
|
|
t14 = g_dd_13;
|
|
t15 = t11 * t14;
|
|
t18 = t14 * t14;
|
|
t21 = 1 / (t8 * t2 - t7 * t5 - t12 * t2 + 2.0 * t15 * t4 - t18 * t1);
|
|
g11 = (t1 * t2 - t5) * t21;
|
|
g12 = -(t11 * t2 - t14 * t4) * t21;
|
|
g13 = -(-t11 * t4 + t14 * t1) * t21;
|
|
g22 = (t7 * t2 - t18) * t21;
|
|
g23 = -(t7 * t4 - t15) * t21;
|
|
g33 = (t8 - t12) * t21;
|
|
}
|
|
// 1 r;2 rho; 3 sigma
|
|
g_uu_22 = (g11 * X_ud_11 + g12 * X_ud_12 + g13 * X_ud_13) * X_ud_11 + (g12 * X_ud_11 + g22 * X_ud_12 + g23 * X_ud_13) * X_ud_12 + (g13 * X_ud_11 + g23 * X_ud_12 + g33 * X_ud_13) * X_ud_13;
|
|
g_uu_23 = (g11 * X_ud_11 + g12 * X_ud_12 + g13 * X_ud_13) * X_ud_21 + (g12 * X_ud_11 + g22 * X_ud_12 + g23 * X_ud_13) * X_ud_22 + (g13 * X_ud_11 + g23 * X_ud_12 + g33 * X_ud_13) * X_ud_23;
|
|
g_uu_12 = (g11 * X_ud_11 + g12 * X_ud_12 + g13 * X_ud_13) * xx / r + (g12 * X_ud_11 + g22 * X_ud_12 + g23 * X_ud_13) * yy / r + (g13 * X_ud_11 + g23 * X_ud_12 + g33 * X_ud_13) * zz / r;
|
|
g_uu_33 = (g11 * X_ud_21 + g12 * X_ud_22 + g13 * X_ud_23) * X_ud_21 + (g12 * X_ud_21 + g22 * X_ud_22 + g23 * X_ud_23) * X_ud_22 + (g13 * X_ud_21 + g23 * X_ud_22 + g33 * X_ud_23) * X_ud_23;
|
|
g_uu_13 = (g11 * X_ud_21 + g12 * X_ud_22 + g13 * X_ud_23) * xx / r + (g12 * X_ud_21 + g22 * X_ud_22 + g23 * X_ud_23) * yy / r + (g13 * X_ud_21 + g23 * X_ud_22 + g33 * X_ud_23) * zz / r;
|
|
g_uu_11 = (g11 * xx / r + g12 * yy / r + g13 * zz / r) * xx / r + (g12 * xx / r + g22 * yy / r + g23 * zz / r) * yy / r + (g13 * xx / r + g23 * yy / r + g33 * zz / r) * zz / r;
|
|
{
|
|
// g_uu
|
|
fp t1, t2, t4, t5, t7, t8, t11, t12, t14, t15;
|
|
fp t18, t21;
|
|
t1 = g_uu_22;
|
|
t2 = g_uu_33;
|
|
t4 = g_uu_23;
|
|
t5 = t4 * t4;
|
|
t7 = g_uu_11;
|
|
t8 = t7 * t1;
|
|
t11 = g_uu_12;
|
|
t12 = t11 * t11;
|
|
t14 = g_uu_13;
|
|
t15 = t11 * t14;
|
|
t18 = t14 * t14;
|
|
t21 = 1 / (t8 * t2 - t7 * t5 - t12 * t2 + 2.0 * t15 * t4 - t18 * t1);
|
|
g11 = (t1 * t2 - t5) * t21;
|
|
g12 = -(t11 * t2 - t14 * t4) * t21;
|
|
g13 = -(-t11 * t4 + t14 * t1) * t21;
|
|
g22 = (t7 * t2 - t18) * t21;
|
|
g23 = -(t7 * t4 - t15) * t21;
|
|
g33 = (t8 - t12) * t21;
|
|
}
|
|
|
|
double q11 = g22, q12 = g23, q13 = Br + dfdt * g12;
|
|
double q22 = g33, q23 = Bsigma + dfdt * g13;
|
|
double q33 = (-Lap * Lap + g11 * Br * Br + g22 * Brho * Brho + g33 * Bsigma * Bsigma +
|
|
2 * (g12 * Br * Brho + g13 * Br * Bsigma + g23 * Brho * Bsigma)) +
|
|
2 * dfdt * Br + dfdt * dfdt * g11;
|
|
q12 = q12 / sintheta;
|
|
q22 = q22 / sintheta / sintheta;
|
|
q23 = q23 / sintheta;
|
|
// we use gfns::gfn__global_zz to store determinant
|
|
p.gridfn(gfns::gfn__global_zz, irho, isigma) = q11 * q22 * q33 + q12 * q23 * q13 + q13 * q12 * q23 - q13 * q22 * q13 - q12 * q12 * q33 - q11 * q23 * q23;
|
|
} // end for irho isigma
|
|
}
|
|
}
|
|
FILE *BH_diagnostics::setup_output_file(int N_horizons, int hn)
|
|
const
|
|
{
|
|
char file_name_buffer[50];
|
|
sprintf(file_name_buffer, "infoah%02d.dat", hn);
|
|
const char *const file_open_mode = "w";
|
|
|
|
FILE *fileptr = fopen(file_name_buffer, file_open_mode);
|
|
if (fileptr == NULL)
|
|
printf("\n"
|
|
" BH_diagnostics::setup_output_file():\n"
|
|
" can't open BH-diagnostics output file\n"
|
|
" \"%s\"!",
|
|
file_name_buffer);
|
|
/*
|
|
fprintf(fileptr, "# apparent horizon %d/%d\n", hn, N_horizons);
|
|
fprintf(fileptr, "#\n");
|
|
fprintf(fileptr, "# column 1 = cctk_time\n");
|
|
fprintf(fileptr, "# column 2 = centroid_x\n");
|
|
fprintf(fileptr, "# column 3 = centroid_y\n");
|
|
fprintf(fileptr, "# column 4 = centroid_z\n");
|
|
fprintf(fileptr, "# column 5 = min radius\n");
|
|
fprintf(fileptr, "# column 6 = max radius\n");
|
|
fprintf(fileptr, "# column 7 = mean radius\n");
|
|
fprintf(fileptr, "# column 8 = quadrupole_xx\n");
|
|
fprintf(fileptr, "# column 9 = quadrupole_xy\n");
|
|
fprintf(fileptr, "# column 10 = quadrupole_xz\n");
|
|
fprintf(fileptr, "# column 11 = quadrupole_yy\n");
|
|
fprintf(fileptr, "# column 12 = quadrupole_yz\n");
|
|
fprintf(fileptr, "# column 13 = quadrupole_zz\n");
|
|
fprintf(fileptr, "# column 14 = min x\n");
|
|
fprintf(fileptr, "# column 15 = max x\n");
|
|
fprintf(fileptr, "# column 16 = min y\n");
|
|
fprintf(fileptr, "# column 17 = max y\n");
|
|
fprintf(fileptr, "# column 18 = min z\n");
|
|
fprintf(fileptr, "# column 19 = max z\n");
|
|
fprintf(fileptr, "# column 20 = xy-plane circumference\n");
|
|
fprintf(fileptr, "# column 21 = xz-plane circumference\n");
|
|
fprintf(fileptr, "# column 22 = yz-plane circumference\n");
|
|
fprintf(fileptr, "# column 23 = ratio of xz/xy-plane circumferences\n");
|
|
fprintf(fileptr, "# column 24 = ratio of yz/xy-plane circumferences\n");
|
|
fprintf(fileptr, "# column 25 = area\n");
|
|
fprintf(fileptr, "# column 26 = irreducible mass\n");
|
|
fprintf(fileptr, "# column 27 = areal radius\n");
|
|
*/
|
|
|
|
fprintf(fileptr, "#time Mass x y z Px Py Pz Sx Sy Sz\n");
|
|
fflush(fileptr);
|
|
|
|
return fileptr;
|
|
}
|
|
void BH_diagnostics::output(FILE *fileptr, double time)
|
|
const
|
|
{
|
|
assert(fileptr != NULL);
|
|
/*
|
|
fprintf(fileptr,
|
|
"%f\t%f\t%f\t%f\t%#.10g\t%#.10g\t%#.10g\t",
|
|
double(time),
|
|
double(centroid_x), double(centroid_y), double(centroid_z),
|
|
double(min_radius), double(max_radius), double(mean_radius));
|
|
|
|
fprintf(fileptr,
|
|
"%#.10g\t%#.10g\t%#.10g\t%#.10g\t%#.10g\t%#.10g\t",
|
|
double(quadrupole_xx), double(quadrupole_xy), double(quadrupole_xz),
|
|
double(quadrupole_yy), double(quadrupole_yz),
|
|
double(quadrupole_zz));
|
|
|
|
fprintf(fileptr,
|
|
"%#.10g\t%#.10g\t%#.10g\t%#.10g\t%#.10g\t%#.10g\t",
|
|
double(min_x), double(max_x),
|
|
double(min_y), double(max_y),
|
|
double(min_z), double(max_z));
|
|
|
|
fprintf(fileptr,
|
|
"%#.10g\t%#.10g\t%#.10g\t%#.10g\t%#.10g\t",
|
|
double(circumference_xy),
|
|
double(circumference_xz),
|
|
double(circumference_yz),
|
|
double(circumference_xz / circumference_xy),
|
|
double(circumference_yz / circumference_xy));
|
|
|
|
fprintf(fileptr,
|
|
"%#.10g\t%#.10g\t%#.10g\n",
|
|
double(area), double(irreducible_mass), double(areal_radius));
|
|
*/
|
|
|
|
fprintf(fileptr,
|
|
"%#.10g\t%#.10g\t%#.10g\t%#.10g\t%#.10g\t%#.10g\t%#.10g\t%#.10g\t%#.10g\t%#.10g\t%#.10g\n",
|
|
double(time), double(irreducible_mass),
|
|
double(centroid_x), double(centroid_y), double(centroid_z),
|
|
double(Px), double(Py), double(Pz), double(Sx), double(Sy), double(Sz));
|
|
|
|
fflush(fileptr);
|
|
}
|
|
|
|
} // namespace AHFinderDirect
|