TwoPunctures generates binary black hole initial data using the puncture method with the Bowen-York extrinsic curvature ansatz. The Hamiltonian constraint is solved spectrally on a single computational domain that covers the two asymptotically flat ends as a compactified radial coordinate, an angular coordinate, and an azimuthal coordinate. The resulting 3D metric, extrinsic curvature, and lapse are stored in the ADMBase grid functions and are ready for use by any evolution thorn that reads from ADMBase. This thorn targets the traditional Carpet AMR infrastructure. A companion thorn, TwoPuncturesX, provides the same functionality for the CarpetX (AMReX-based) infrastructure.
TwoPunctures computes conformally flat initial data for two non-spinning or spinning, non-moving or moving black holes using the moving puncture approach [2]. The central task is to solve the Hamiltonian constraint for the conformal factor \(\psi \), which is decomposed as \begin {equation} \psi = 1 + \frac {m_+}{2 r_+} + \frac {m_-}{2 r_-} + u, \end {equation} where \(m_\pm \) are the bare masses of the two punctures located at \((\pm b, 0, 0)\) (or offset by center_offset), \(r_\pm \) are the coordinate distances from each puncture, and \(u\) is a smooth correction function that satisfies a nonlinear elliptic equation derived from the full Hamiltonian constraint. The Bowen-York extrinsic curvature [1] is used to incorporate linear momenta and spins.
The nonlinear elliptic equation for \(u\) is solved with a spectral method described in Ansorg, Brügmann & Tichy (2004) [3]. Newton iteration is used to handle the nonlinear terms. Once \(u\) is known, all ADMBase metric and extrinsic-curvature components are filled on the 3D Cactus grid by interpolation from the spectral solution.
The spatial metric is assumed to be conformally flat: \begin {equation} \gamma _{ij} = \psi ^4 f_{ij}, \end {equation} where \(f_{ij}\) is the flat metric. The extrinsic curvature is decomposed into a trace-free part \(A_{ij}\) and trace \(K\): \begin {equation} K_{ij} = \psi ^{-2}\,A_{ij} + \tfrac {1}{3}\,\gamma _{ij}\,K. \end {equation} For the time-symmetric slice (\(A_{ij}=0\) and \(K=0\)) the Hamiltonian constraint reduces to a flat Laplace equation for \(\psi \). For the general Bowen-York case (\(K=0\) is still enforced on the slice but \(A_{ij}\neq 0\)), the Hamiltonian constraint becomes a nonlinear equation for \(u\).
The Bowen-York extrinsic curvature for a single puncture with linear momentum \(P^i\) and spin \(S^i\) is \begin {equation} A_{ij}^{\rm BY} = \frac {3}{2r^2}\left [ P_i n_j + P_j n_i - (f_{ij} - n_i n_j) P^k n_k + \frac {2}{r}\left (\epsilon _{kli} S^k n^l n_j + \epsilon _{klj} S^k n^l n_i\right ) \right ], \end {equation} where \(n^i\) is the unit outward normal to a sphere of radius \(r\) centered on the puncture. The total extrinsic curvature is the sum of the contributions from both punctures.
The thorn distinguishes between bare masses \(m_\pm \) (the parameters \(\texttt {par\_m\_plus}\) and \(\texttt {par\_m\_minus}\)) and ADM masses \(M_\pm \) measured at the respective asymptotic infinities. When give_bare_mass = yes the user sets bare masses directly. When give_bare_mass = no the thorn iterates to find the bare masses that reproduce the requested target ADM masses target_M_plus and target_M_minus to within the tolerance adm_tol.
The equation for \(u\) is solved on a spectral grid parameterized by coordinates \((A, B, \phi )\), where \(A \in [0,1]\) is a compactified radial coordinate covering both punctures and spatial infinity, \(B \in [-1,1]\) is an angular coordinate, and \(\phi \in [0, 2\pi )\) is the azimuthal angle. The number of spectral coefficients in each direction is set by npoints_A, npoints_B, and npoints_phi, respectively.
Newton’s method is applied to the nonlinear equation for \(u\) with tolerance Newton_tol and at most Newton_maxit iterations. The linear system at each Newton step is solved by a banded direct solver. OpenMP parallelism is used within the Newton solver to accelerate the construction and application of the Jacobian.
Once the spectral coefficients are known, the solution is transferred to the Cactus 3D grid in one of two ways controlled by grid_setup_method:
Taylor expansion (default): the solution is Taylor-expanded about the nearest spectral collocation point. This is fast but may be slightly less accurate far from collocation points.
evaluation: each grid point is evaluated using all spectral coefficients. More accurate but significantly slower for large grids.
The interpolation loop is parallelized with OpenMP.
Two small parameters help avoid numerical issues near the punctures:
TP_epsilon: replaces \(r_\pm \) with \((r_\pm ^4 + \epsilon ^4)^{1/4}\), smoothing the singularity.
TP_Tiny: a floor applied to \(r_\pm \) after the above regularization.
TP_Extend_Radius: inside this radius around each puncture the singular \(1/r\) term is replaced by a smooth polynomial extension, useful when the puncture lies inside the computational domain.
TwoPunctures is part of the EinsteinInitialData arrangement, which can be checked out via the Einstein Toolkit release mechanism or directly from the repository. The thorn requires ADMBase, StaticConformal, and the Cactus flesh.
Add EinsteinInitialData/TwoPunctures to your thorn list and set the following parameters in your parameter file:
ADMBase::initial_data = "twopunctures" ADMBase::initial_lapse = "twopunctures-antisymmetric" TwoPunctures::par_b = 3.0 # half separation (M) TwoPunctures::par_m_plus = 0.5 TwoPunctures::par_m_minus = 0.5 TwoPunctures::par_P_plus[1] = 0.084 TwoPunctures::par_P_minus[1] = -0.084 TwoPunctures::npoints_A = 30 TwoPunctures::npoints_B = 30 TwoPunctures::npoints_phi = 16
The punctures are placed at \((+b, 0, 0)\) and \((-b, 0, 0)\) unless center_offset shifts the center of mass. To separate the holes along the \(z\)-axis instead, set swap_xz = yes.
The initial lapse is selected via ADMBase::initial_lapse:
twopunctures-antisymmetric: \(\alpha = (1 - \psi _{\rm sing}/\psi ) / (1 + \psi _{\rm sing}/\psi )\), ranges in \([-1, +1]\).
twopunctures-averaged: average of the antisymmetric lapse and unity, ranges in \([0, +1]\).
psiˆn: \(\alpha = \psi ^n\) where \(n\) is set by initial_lapse_psi_exponent (typically \(-2\)).
W: \(\alpha = \psi ^{-2}\), suitable as a slow-start lapse for the W-formulation [5].
brownsville: \(\alpha = 2/(1 + \psi ^n)\) [4].
When ADMBase::metric_type = "static conformal", the thorn populates the StaticConformal grid functions (psi, psix, etc.) in addition to the physical metric, with the level of detail controlled by StaticConformal::conformal_storage.
Setting give_bare_mass = no enables an outer iteration that finds bare masses \(m_\pm \) such that the resulting ADM masses match target_M_plus and target_M_minus to within adm_tol. The iteration uses the analytic inversion of the ADM mass relation.
TwoPunctures writes to the ADMBase grid functions gxx, gyy, gzz, gxy, gxz, gyz, kxx, kyy, kzz, kxy, kxz, kyz, and alp. It exposes the scalar grid functions mp, mm, mp_adm, mm_adm, E, J1, J2, and J3 for use by other thorns (e.g., Multipole, QuasiLocalMeasures).
Matter source terms can be supplied via the optional function interfaces Set_Rho_ADM and Set_Initial_Guess_for_u, enabling neutron star or BH-NS initial data when use_sources = yes.
The spectral algorithm implemented in this thorn was developed by Marcus Ansorg and is described in [3]. The thorn was originally written for the Cactus framework by Marcus Ansorg and Erik Schnetter. It has since been maintained and extended by the Einstein Toolkit community.
[1] J. M. Bowen and J. W. York, Time-asymmetric initial data for black holes and black-hole collisions, Phys. Rev. D 21, 2047 (1980).
[2] S. Brandt and B. Brügmann, A simple construction of initial data for multiple black holes, Phys. Rev. Lett. 78, 3606 (1997), gr-qc/9703066.
[3] M. Ansorg, B. Brügmann, and W. Tichy, Single-domain spectral method for black hole puncture data, Phys. Rev. D 70, 064011 (2004), gr-qc/0404056.
[4] M. Campanelli, C. O. Lousto, and Y. Zlochower, Spinning-black-hole binary evolutions, recoil velocities, and spin-orbit effects, Phys. Rev. D 74, 041501 (2006), gr-qc/0604012.
[5] D. Alic et al., Constraint-preserving boundary treatment for a harmonic formulation of the Einstein equations, Phys. Rev. D 110, 064045 (2024), arXiv:2404.01137.
| adm_tol | Scope: restricted | REAL |
| Description: Tolerance of ADM masses when give_bare_mass=no
| ||
| Range | Default: 1.0e-10 | |
| (0:*) | ||
| center_offset | Scope: restricted | REAL |
| Description: offset b=0 to position (x,y,z)
| ||
| Range | Default: 0.0 | |
| (*:*) | ||
| do_initial_debug_output | Scope: restricted | BOOLEAN |
| Description: Output debug information about initial guess
| ||
| Default: no | ||
| do_residuum_debug_output | Scope: restricted | BOOLEAN |
| Description: Output debug information about the residuum
| ||
| Default: no | ||
| give_bare_mass | Scope: restricted | BOOLEAN |
| Description: User provides bare masses rather than target ADM masses
| ||
| Default: yes | ||
| grid_setup_method | Scope: restricted | KEYWORD |
| Description: How to fill the 3D grid from the spectral grid
| ||
| Range | Default: Taylor expansion | |
| Taylor expansion
| use a Taylor expansion about the nearest collocation point (fast, but
might be inaccurate)
| |
| evaluation | evaluate using all spectral coefficients (slow)
| |
| initial_lapse_psi_exponent | Scope: restricted | REAL |
| Description: Exponent n for psi
n initial lapse profile | ||
| Range | Default: -2.0 | |
| (*:*) | Should be negative
| |
| keep_u_around | Scope: restricted | BOOLEAN |
| Description: Keep the variable u around after solving
| ||
| Default: no | ||
| multiply_old_lapse | Scope: restricted | BOOLEAN |
| Description: Multiply the old lapse with the new one
| ||
| Default: no | ||
| newton_maxit | Scope: restricted | INT |
| Description: Maximum number of Newton iterations
| ||
| Range | Default: 5 | |
| 0:* | ||
| newton_tol | Scope: restricted | REAL |
| Description: Tolerance for Newton solver
| ||
| Range | Default: 1.0e-10 | |
| (0:*) | ||
| npoints_a | Scope: restricted | INT |
| Description: Number of coefficients in the compactified radial direction
| ||
| Range | Default: 30 | |
| 4:* | ||
| npoints_b | Scope: restricted | INT |
| Description: Number of coefficients in the angular direction
| ||
| Range | Default: 30 | |
| 4:* | ||
| npoints_phi | Scope: restricted | INT |
| Description: Number of coefficients in the phi direction
| ||
| Range | Default: 16 | |
| 4:*:2 | ||
| par_b | Scope: restricted | REAL |
| Description: x coordinate of the m+ puncture
| ||
| Range | Default: 1.0 | |
| (0.0:*) | ||
| par_m_minus | Scope: restricted | REAL |
| Description: mass of the m- puncture
| ||
| Range | Default: 1.0 | |
| 0.0:*) | ||
| par_m_plus | Scope: restricted | REAL |
| Description: mass of the m+ puncture
| ||
| Range | Default: 1.0 | |
| 0.0:*) | ||
| par_p_minus | Scope: restricted | REAL |
| Description: momentum of the m- puncture
| ||
| Range | Default: 0.0 | |
| (*:*) | ||
| par_p_plus | Scope: restricted | REAL |
| Description: momentum of the m+ puncture
| ||
| Range | Default: 0.0 | |
| (*:*) | ||
| par_s_minus | Scope: restricted | REAL |
| Description: spin of the m- puncture
| ||
| Range | Default: 0.0 | |
| (*:*) | ||
| par_s_plus | Scope: restricted | REAL |
| Description: spin of the m+ puncture
| ||
| Range | Default: 0.0 | |
| (*:*) | ||
| rescale_sources | Scope: restricted | BOOLEAN |
| Description: If sources are used - rescale them after solving?
| ||
| Default: yes | ||
| schedule_in_admbase_initialdata | Scope: restricted | BOOLEAN |
| Description: Schedule in (instead of after) ADMBase_InitialData
| ||
| Default: yes | ||
| solve_momentum_constraint | Scope: restricted | BOOLEAN |
| Description: Solve for momentum constraint?
| ||
| Default: no | ||
| swap_xz | Scope: restricted | BOOLEAN |
| Description: Swap x and z coordinates when interpolating, so that the black holes are separated
in the z direction
| ||
| Default: no | ||
| target_m_minus | Scope: restricted | REAL |
| Description: target ADM mass for m-
| ||
| Range | Default: 0.5 | |
| 0.0:*) | ||
| target_m_plus | Scope: restricted | REAL |
| Description: target ADM mass for m+
| ||
| Range | Default: 0.5 | |
| 0.0:*) | ||
| tp_epsilon | Scope: restricted | REAL |
| Description: A small number to smooth out singularities at the puncture locations
| ||
| Range | Default: 0.0 | |
| 0:* | ||
| tp_extend_radius | Scope: restricted | REAL |
| Description: Radius of an extended spacetime instead of the puncture
| ||
| Range | Default: 0.0 | |
| 0:* | anything positive, should be smaller than the horizon
| |
| tp_tiny | Scope: restricted | REAL |
| Description: Tiny number to avoid nans near or at the puncture locations
| ||
| Range | Default: 0.0 | |
| 0:* | anything positive, usually very small
| |
| use_external_initial_guess | Scope: restricted | BOOLEAN |
| Description: Set initial guess by external function?
| ||
| Default: no | ||
| use_sources | Scope: restricted | BOOLEAN |
| Description: Use sources?
| ||
| Default: no | ||
| verbose | Scope: restricted | BOOLEAN |
| Description: Print screen output while solving
| ||
| Default: no | ||
| conformal_storage | Scope: shared from STATICCONFORMAL | KEYWORD |
Implements:
twopunctures
Inherits:
admbase
staticconformal
grid
| Group Names | Variable Names | Details | |
| puncture_u | puncture_u | compact | 0 |
| dimensions | 3 | ||
| distribution | DEFAULT | ||
| group type | GF | ||
| tags | prolongation=”none” | ||
| timelevels | 1 | ||
| variable type | REAL | ||
| energy | compact | 0 | |
| E | description | ADM energy of the Bowen-York spacetime | |
| dimensions | 0 | ||
| distribution | CONSTANT | ||
| group type | SCALAR | ||
| timelevels | 1 | ||
| variable type | REAL | ||
| angular_momentum | compact | 0 | |
| J1 | description | Angular momentum of the Bowen-York spacetime | |
| J2 | dimensions | 0 | |
| J3 | distribution | CONSTANT | |
| group type | SCALAR | ||
| timelevels | 1 | ||
| variable type | REAL | ||
| Group Names | Variable Names | Details | |
| bare_mass | compact | 0 | |
| mp | description | Bare masses of the punctures | |
| mm | dimensions | 0 | |
| distribution | CONSTANT | ||
| group type | SCALAR | ||
| timelevels | 1 | ||
| variable type | REAL | ||
| puncture_adm_mass | compact | 0 | |
| mp_adm | description | ADM masses of the punctures (measured at the other spatial infinities) | |
| mm_adm | dimensions | 0 | |
| distribution | CONSTANT | ||
| group type | SCALAR | ||
| timelevels | 1 | ||
| variable type | REAL | ||
Adds header:
TwoPunctures.h
TP_utilities.h
TP_params.h
TP_Guts.h
This section lists all the variables which are assigned storage by thorn EinsteinInitialData/TwoPunctures. Storage can either last for the duration of the run (Always means that if this thorn is activated storage will be assigned, Conditional means that if this thorn is activated storage will be assigned for the duration of the run if some condition is met), or can be turned on for the duration of a schedule function.
| Conditional: | |
| energy angular_momentum puncture_adm_mass bare_mass | |
| puncture_u | |
CCTK_PARAMCHECK (conditional)
twopunctures_paramcheck
check parameters and thorn needs
| Language: | c | |
| Type: | function | |
ADMBase_InitialData (conditional)
twopunctures_group
twopunctures initial data group
| Type: | group | |
CCTK_INITIAL (conditional)
twopunctures_group
twopunctures initial data group
| After: | admbase_initialdata | |
| hydrobase_initial | ||
| Before: | admbase_postinitial | |
| settmunu | ||
| hydrobase_prim2coninitial | ||
| Type: | group | |
TwoPunctures_Group (conditional)
twopunctures
create puncture black hole initial data
| Language: | c | |
| Reads: | grid::coordinates(everywhere) | |
| Storage: | puncture_u | |
| Type: | function | |
| Writes: | twopunctures::mp(everywhere) | |
| twopunctures::mm(everywhere) | ||
| twopunctures::mp_adm(everywhere) | ||
| twopunctures::mm_adm(everywhere) | ||
| twopunctures::e(everywhere) | ||
| twopunctures::j1(everywhere) | ||
| twopunctures::j2(everywhere) | ||
| twopunctures::j3(everywhere) | ||
| twopunctures::puncture_u(everywhere) | ||
| staticconformal::conformal_state(everywhere) | ||
| staticconformal::confac_2derivs(everywhere) | ||
| staticconformal::confac_1derivs(everywhere) | ||
| staticconformal::confac(everywhere) | ||
| admbase::alp(everywhere) | ||
| admbase::metric(everywhere) | ||
| admbase::curv(everywhere) | ||
TwoPunctures_Group (conditional)
twopunctures_metadata
output twopunctures metadata
| After: | twopunctures | |
| Language: | c | |
| Options: | global | |
| Type: | function | |