TwoPuncturesX

Marcus Ansorg <marcus.ansorg@aei.mpg.de>
Erik Schnetter <schnetter@cct.lsu.edu>

May 12 2026

Abstract

TwoPuncturesX generates binary black hole initial data using the puncture method with the Bowen-York extrinsic curvature ansatz. It implements exactly the same spectral algorithm as the companion thorn TwoPunctures [3] but targets the CarpetX (AMReX-based) infrastructure: it inherits from ADMBaseX and CoordinatesX rather than from ADMBase and StaticConformal, and the setup computation is protected by an OpenMP critical section so that it executes correctly when called from within a threaded CarpetX loop. TwoPunctures (EinsteinInitialData/TwoPunctures) must be present in the same build because TwoPuncturesX reuses the solver source files from that thorn.

1 Introduction

TwoPuncturesX is the CarpetX port of TwoPunctures. It provides identical physics and parameters; the differences are entirely in the Cactus infrastructure layer:

For full details of the underlying physics and algorithm, see the TwoPunctures documentation and [3].

2 Physical System

The physics is identical to TwoPunctures. The conformal decomposition

\begin {equation} \psi = 1 + \frac {m_+}{2 r_+} + \frac {m_-}{2 r_-} + u \end {equation}

is used, where \(m_\pm \) are the bare masses of the two punctures at \((\pm b, 0, 0)\), \(r_\pm \) are distances from the respective punctures, and \(u\) is a smooth correction solved spectrally. The Bowen-York extrinsic curvature [1] encodes linear momenta and spins.

The output metric is the physical metric \(\gamma _{ij} = \psi ^4 f_{ij}\) (conformally flat), not the conformal metric.

3 Numerical Implementation

3.1 Shared Solver

TwoPuncturesX reuses the spectral solver from TwoPunctures by including the header TP_Guts.h directly into the scheduling function body. This header contains the full solve-and-interpolate logic. Because TwoPunctures must be present in the same build, the compiler sees both thorns’ object files and can share the Newton solver and spectral machinery.

3.2 Thread Safety

Under CarpetX, the scheduled function TwoPuncturesX may be invoked from within an OpenMP parallel region. The expensive spectral solve must run exactly once. This is guaranteed by a static boolean flag did_setup and a named OpenMP critical section:

#pragma omp critical(TwoPunctures_setup)
  if (!did_setup) {
    // ... perform spectral solve ...
    did_setup = true;
  }

Using a named critical section avoids interference with the unnamed critical section inside Newton’s parallel reduction loop in Newton.cc.

3.3 Grid Fill

After the spectral solve the 3D grid is filled point-by-point using the same interpolation path as TwoPunctures (grid_setup_method = "Taylor expansion" or "evaluation"). The inner loop is parallelized with #pragma omp parallel for.

3.4 Scalar Grid Functions

CarpetX resets grid scalars at the start of each scheduled call. TwoPuncturesX therefore saves the computed scalars (mp, mm, mp_adm, mm_adm, E, J1, J2, J3) into static variables during setup and restores them on every call so that they remain available to other thorns.

4 Using This Thorn

4.1 Requirements

4.2 Basic Usage

Add both EinsteinInitialData/TwoPunctures and EinsteinInitialData/TwoPuncturesX to your thorn list, then set:

ADMBaseX::initial_data  = "twopunctures"
ADMBaseX::initial_lapse = "twopunctures-antisymmetric"

TwoPuncturesX::par_b       = 3.0   # half separation (M)
TwoPuncturesX::par_m_plus  = 0.5
TwoPuncturesX::par_m_minus = 0.5
TwoPuncturesX::par_P_plus[1]  =  0.084
TwoPuncturesX::par_P_minus[1] = -0.084
TwoPuncturesX::npoints_A   = 30
TwoPuncturesX::npoints_B   = 30
TwoPuncturesX::npoints_phi = 16

The parameter names and semantics are the same as in TwoPunctures (see that thorn’s documentation for a full description of each parameter).

4.3 Lapse Options

The same lapse choices are available as in TwoPunctures: twopunctures-antisymmetric, twopunctures-averaged, psiˆn, W, and brownsville. See the TwoPunctures documentation for details. Note that the conformal-factor-based lapse options (psiˆn, brownsville) compute \(\psi \) locally during the grid fill; no separate conformal storage thorn is required.

4.4 ADM Mass Iteration

Setting give_bare_mass = no enables iterative determination of bare masses to match target ADM masses target_M_plus and target_M_minus, exactly as in TwoPunctures.

4.5 Interaction With Other Thorns

TwoPuncturesX writes to the ADMBaseX grid functions gxx, gyy, gzz, gxy, gxz, gyz, kxx, kyy, kzz, kxy, kxz, kyz, and alp. It also populates the scalar grid functions mp, mm, mp_adm, mm_adm, E, J1, J2, and J3.

Matter sources can be supplied via the same optional function interfaces Set_Rho_ADM and Set_Initial_Guess_for_u as in TwoPunctures; however, rescale_sources = yes with use_sources = yes is not yet supported and will trigger a run-time error.

5 History

TwoPuncturesX was derived from TwoPunctures to support the CarpetX AMR framework. The underlying spectral algorithm is unchanged from Ansorg, Brügmann & Tichy (2004) [3].

References

[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.

6 Parameters




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






out_dir
Scope: shared from IOSTRING



7 Interfaces

General

Implements:

twopuncturesx

Inherits:

admbasex

coordinatesx

Grid Variables

7.0.1 PRIVATE GROUPS





  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




7.0.2 PUBLIC GROUPS





  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




Uses header:

TwoPunctures.h

TP_utilities.h

TP_params.h

TP_Guts.h

8 Schedule

This section lists all the variables which are assigned storage by thorn EinsteinInitialData/TwoPuncturesX. 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.

Storage

 

  Conditional:
  energy angular_momentum puncture_adm_mass bare_mass
  puncture_u
   

Scheduled Functions

CCTK_PARAMCHECK (conditional)

  twopuncturesx_paramcheck

  check parameters and thorn needs

 

  Language: c
  Type: function

ADMBaseX_InitialData (conditional)

  twopuncturesx_group

  twopuncturesx initial data group

 

  Type: group

CCTK_INITIAL (conditional)

  twopuncturesx_group

  twopuncturesx initial data group

 

  After: admbasex_initialdata
    hydrobase_initial
  Before: admbasex_postinitial
    settmunu
    hydrobase_prim2coninitial
  Type: group

TwoPuncturesX_Group (conditional)

  twopuncturesx

  create puncture black hole initial data

 

  Language: c
  Reads: coordinatesx::vertex_coords(everywhere)
  Storage: puncture_u
  Type: function
  Writes: twopuncturesx::mp(everywhere)
    twopuncturesx::mm(everywhere)
    twopuncturesx::mp_adm(everywhere)
    twopuncturesx::mm_adm(everywhere)
    twopuncturesx::e(everywhere)
    twopuncturesx::j1(everywhere)
    twopuncturesx::j2(everywhere)
    twopuncturesx::j3(everywhere)
    twopuncturesx::puncture_u(everywhere)
    admbasex::alp(everywhere)
    admbasex::metric(everywhere)
    admbasex::curv(everywhere)

TwoPuncturesX_Group (conditional)

  twopuncturesx_metadata

  output twopuncturesx metadata

 

  After: twopuncturesx
  Language: c
  Options: global
  Type: function