diff options
author | Anton Khirnov <anton@khirnov.net> | 2018-03-22 16:24:06 +0100 |
---|---|---|
committer | Anton Khirnov <anton@khirnov.net> | 2018-03-22 16:24:06 +0100 |
commit | 4aa5abb50f24a539b77e6c66508125ec5f5f09df (patch) | |
tree | 8067aa838a48e1364ad299d1e4b29d7dffbf6d70 | |
parent | 334f7b637147e8b85b72265a4a84c34378652a13 (diff) |
Add a function for ADM mass estimation.
-rw-r--r-- | mass.py | 61 |
1 files changed, 61 insertions, 0 deletions
@@ -0,0 +1,61 @@ +import numpy as np +from numpy import pi as PI + +import scipy.integrate as integrate +import scipy.interpolate as interp + +def _sphere_area_int(theta, r, x_vals, z_vals, metric): + st = np.sin(theta) + ct = np.cos(theta) + + x = r * st + z = r * ct + + metric_val = np.empty((3, 3)) + for i in range(3): + for j in range(3): + metric_interp = interp.RectBivariateSpline(x_vals, z_vals, metric[i, j]) + metric_val[i, j] = metric_interp(x, z) + + transform = np.array([[st, r * ct, 0.0], + [0.0, 0.0, r * st], + [ct, -r * st, 0.0]]) + + ms = np.einsum('ki,lj,kl', transform, transform, metric_val) + return np.sqrt(ms[1, 1] * ms[2, 2]) + +def mass_adm_sphere(x, z, metric, r, dr = 0.1): + """ + Calculate an estimate of the ADM mass based on falloff of sphere area + (equation (A.26) in [1]). + + [1] Alcubierre (2008): Introduction to 3+1 Numerical Relativity + + :param array_like x: 1D array of x coordinates at which the values of the + metric are provided + :param array_like z: 1D array of z coordinates at which the values of the + metric are provided + :param array_like metric: 4D array of metric components at the grid defined by x + and z. metric[i, j, k, l] is the ij-th component + at spatial point (X=x[k], Z=z[l]). + :param float r: The radius at which the mass is to be evaluated. + :param float dr: optional step used for calculating dA/dr with finite + differences. + :return: Estimate of the ADM mass of the spacetime. + :rtype: float + """ + A = 2 * 2 * PI * integrate.quad(_sphere_area_int, 0, PI / 2, (r, x, z, metric))[0] + Am1 = 2 * 2 * PI * integrate.quad(_sphere_area_int, 0, PI / 2, (r - dr, x, z, metric))[0] + Ap1 = 2 * 2 * PI * integrate.quad(_sphere_area_int, 0, PI / 2, (r + dr, x, z, metric))[0] + dA_dr = (Ap1 - Am1) / (2.0 * dr) + + X, Z = np.meshgrid(x, z) + R = np.sqrt(X**2 + Z**2) + grr = ((X / R) ** 2) * metric[0, 0] + ((Z / R) ** 2) * metric[2, 2] + 2.0 * (X * Z / (R * R)) * metric[0, 2] + grr = np.where(np.isnan(grr), 0.0, grr) + + dst_theta = np.linspace(0, PI / 2, 128) + grr_vals = interp.RectBivariateSpline(x, z, grr)(r * np.sin(dst_theta), r * np.cos(dst_theta), grid = False) + + return (np.sqrt(A / (16.0 * PI)) * + (1.0 - (dA_dr ** 2) / (16 * PI * A * np.average(grr_vals)))) |