|
SpECTRE
v2026.09.05
|
There are a couple different ways to acquire the CCE module/executable.
Starting from late May 2024, in every Release of SpECTRE we offer a tarball that contains everything needed to run CCE on a large number of different systems. This will be under the Assets section towards the bottom of the release (there may be a lot of text detailing what's been updated in this release). Inside this tarball is
See Running the CCE executable for how to run CCE.
We have tested that this executable works natively on the following machines:
We have also tested that this executable works inside our dev Docker container on the following machines (in addition to the ones above):
You can download a docker image sxscollaboration/spectre:deploy which has a few pre-built executables within, including the ones listed above in the release section. See the containerized releases section of our Installation instructions for how start the container.
The input files can be found within the container at /sxscollaboration/spectre/tests/InputFiles/.
You can clone the spectre repo and follow the instructions on the Installation page to obtain an environment to configure and build SpECTRE. Once you have a configured build directory, build the CCE executable with
In order to run the CCE executable, the worldtube data must be represented as Bondi-Sachs variables decomposed as a subset of spin-weighted spherical harmonic modes on a sphere of constant coordinate radius. We have chosen this format because it is far more space-efficient to store on disk than other formats. This section will detail the required data format, provide options for converting worldtube data from other NR codes into our format, and give insights into what the worldtube data should look like.
Within the H5 file that holds the worldtube data, there must be the following datasets with these exact names (including the .dat suffix):
Each dataset in the file must also have an attribute named Legend which is an ASCII-encoded null-terminated variable-length string. That is, the HDF5 type is:
This can be checked for a dataset by running
For the ordering of the data, we use spherical harmonic conventions documented by the ylm::Spherepack class. Each row must start with the time stamp, and the remaining values are the complex modes in m-varies-fastest format. For spin-weight zero Bondi variables (Beta, R, DuR, W), we omit the redundant negative-m modes and imaginary parts of the m=0 modes to save space on disk. Here is an example of a legend for the spin-weight zero variables:
For non-zero spin-weight Bondi variables (J, DrJ, H, Q, U) we must store all complex m-modes. Here is an example of a legend for variables where all complex m-modes must be specified:
We don't have strict requirement on the name of the H5 file that holds the worldtube data. However, it is recommended to name the H5 file ...CceRXXXX.h5, where the XXXX is to be replaced by the zero-padded integer for which the extraction radius is equal to XXXXM. For instance, a 100M extraction should have filename ...CceR0100.h5. If you do not adhere to this naming convention, you will need to specify the extraction radius in your YAML input file.
Unless you are using worldtube data that was generated from SpECTRE (or SpEC), it's possible that your worldtube data is not in the correct format. We allow conversion into our data format from a few other data formats using the `PreprocessCceWorldtube` executable provided. These are
Requirements for these data formats are listed below.
When we refer to a "modal" data format, we mean that the worldtube data are stored as spherical harmonic coefficients (a.k.a. modes). We use spherical harmonic conventions documented by the ylm::Spherepack class. For each dataset, each row must start with the time stamp, and the remaining values are the complex modes in m-varies-fastest format. That is,
Each dataset in the H5 file must also have an attribute named Legend which is an ASCII-encoded null-terminated variable-length string.
When we refer to a "nodal" data format, we mean that the worldtube data are stored as values at specially chosen collocation points (a.k.a. grid points or nodes). This allows SpECTRE to perform integrals, derivatives, and interpolation exactly on the input data. These grid points are Gauss-Legendre in \(cos(\theta)\) and equally spaced in \(\phi\).
Below is a routine for computing the spherical harmonic \(\theta\) and \(\phi\) values. These can be used to compute the Cartesian locations for a given radius using the standard transformation. The routine supports \(\ell\in[4, 32]\).
Alternatively, if your code can read in grid points from a text file, you can run the WriteCceWorldtubeCoordsToFile executable like so to get a text file with three columns for the x,y,z coordinates of each point.
Each dataset holds 1 + (l_max + 1) * (2 * l_max + 1) columns, with the first one being the time. The columns must be in \(\theta\)-varies-fastest ordering. That is,
Each dataset in the H5 file must also have an attribute named Legend which is an ASCII-encoded null-terminated variable-length string.
For worldtube data stored in an H5 file in the "ADM metric nodal" format, there must be the following datasets with these exact names (including the .dat suffix):
Here g represents the spacetime metric, but we only require the spatial components (e.g. gxx.dat, gxy.dat, etc...) so in practice, those are the tensor components of the spatial metric. The temporal components of the spacetime metric are stored separately in the lapse and shift. Each of the spatial metric, lapse, and shift must also have their cartesian derivatives. K is the extrinsic curvature, AuxiliaryShift is the auxiliary shift vector used in the first-order form of the Gamma-driver condition, and ConformalChristoffel is the trace of the conformal second_order symbols.
We will compute the time derivative of the spatial metric using Eq. (2.134) of [14],
\begin{equation}\partial_t \gamma_{ij} = -2\alpha K_{ij} + D_i\beta_j + D_j\beta_i. \end{equation}
The time derivative of the lapse is computed using the 1+log slicing condition from Eq. (4.87) of [14]
\begin{equation}\partial_t \alpha = -2\alpha K + \beta^j\partial_j\alpha, \end{equation}
and the time derivative of the shift is computed using either the first order reduction form of the Gamma-driver condition from Eq. (4.89) of [14]
\begin{equation}\partial_t \beta^i = \eta B^i + \beta^j\partial_j\beta^i, \end{equation}
where you can choose \(\eta\) (typically \(\eta=0.75\)) or using the integrated Gamma-driver condition from Eq. (12) of [105]
\begin{equation}\partial_t \beta^i = \tilde{\Gamma}^i - \eta\beta^i + \beta^j\partial_j\beta^i, \end{equation}
again, where you can choose \(\eta\) (typically \(\eta=2/M_{\textrm{ADM}}\)).
The layout of each of these datasets must be spherical harmonic nodes.
For worldtube data stored in an H5 file in either the "metric nodal" or "metric modal" formats, there must be the following datasets with these exact names (including the .dat suffix):
Here g represents the spacetime metric, but we only require the spatial components (e.g. gxx.dat, gxy.dat, etc...) so in practice, those are the tensor components of the spatial metric. The temporal components of the spacetime metric are stored separately in the lapse and shift. The layout of each of these datasets must be in either spherical harmonic modes or spherical harmonic nodes.
In the "bondi nodal" format, you must have the same Bondi variables as the required format, but each variable layout must be the spherical harmonic nodal layout with complex values interleaved as Re, Im, Re, Im, ...
If you already have data in the required "bondi modal" format, then nothing needs to be done.
The PreprocessCceWorldtube executable should be run on any of the allowed input formats, and will produce a corresponding Bondi-Sachs worldtube file that can be read in by CCE. This executable works similarly to our other executables by accepting a YAML input file:
with a YAML file
In addition to converting worldtube data formats, PreprocessCceWorldtube also accepts multiple input worldtube H5 files that have sequential times (e.g. from different checkpoints) and will combine the times from all H5 files alongside converting the worldtube data format. If there are duplicate or overlapping times, the last/latest of the times are chosen. If you pass multiple input worldtube H5 files, it is assumed that they are ordered increasing in time.
Here are some notes about the different options in the YAML input file:
While no two simulations will look exactly the same, there are some general trends in the worldtube data to look for. Here is a plot of some modes of the Bondi variable J from the Bondi-Sachs worldtube format.
The 2,2 modes are oscillatory and capture the orbits of the two objects. The real part of the 2,0 mode contains the gravitational memory of the system. Then for this system, all the other modes are subdominant.
If you are using the cartesian metric or adm cartesian metric worldtube format, here is a plot of the imaginary part of the 2,2 mode of the lapse and its radial and time derivative during inspiral.
One thing to keep in mind with this plot is that it was produced using the Generalized Harmonic formulation of Einstein's equations using the damped harmonic gauge. Therefore, if you are using a different formulation and gauge (like BSSN + moving punctures), the lapse may look different than this. One way to sanity check your data (regardless of what type it is or where you got it from) is to look and how the mode amplitude for a given quantity decays as you increase (l,m). Here is a plot of the amplitude of the modes for the lapse in the above plot.
You'll notice that most modes are around machine precision and only the first few have any real impact. This is expected.
Input files for CCE are commonly named CharacteristicExtract.yaml. An example input file with comments explaining some of the options can be found in $SPECTRE_HOME/tests/InputFiles/Cce/CharacteristicExtract.yaml. Here we expand a bit on why we chose some of those parameters.
CauchySecondOrder, described below, is the best method to choose the initial data on the null hypersurface, and the example input file uses it. If it fails for your worldtube data, the following methods are available as fallbacks, in order of preference:
CCE works in the compactified radial coordinate \(\tilde y = 1 - 2R/r\), where \(R\) is the worldtube radius, so that the worldtube \(\Gamma\) is at \(\tilde y = -1\) and \(\mathscr{I}^+\) is at \(\tilde y = 1\). Here \(\tilde J\) denotes \(J\) in the Cauchy coordinates, built on the worldtube from the Cauchy angular coordinates, and \(\breve J\) its counterpart in the partially flat coordinates used for the evolution. \(\tilde J^{(n)}\) and \(\breve J^{(n)}\) are their coefficients of \((1 - \tilde y)^n\). The initial data must satisfy the partially flat conditions \(\breve J^{(0)} = 0\) and \(\breve J^{(2)} = 0\). Both coefficients then remain zero throughout the evolution, which in the partially flat gauge prevents logarithmic terms from arising.
CauchySecondOrder matches the initial \(\tilde J\) on the initial null hypersurface \(\Sigma_0\) to the worldtube value \(\tilde J|_\Gamma\) and its first two radial derivatives in the Cauchy gauge, using the ansatz
\begin{align*} \tilde J(\tilde y; x) = \tilde J^{(0)}(x) + \tilde J^{(1)}(x)\,(1 - \tilde y) + x\,(1 - \tilde y)^2 + \tilde J^{(3)}(x)\,(1 - \tilde y)^3 . \end{align*}
The three matching conditions determine \(\tilde J^{(0)}\), \(\tilde J^{(1)}\) and \(\tilde J^{(3)}\) as functions of \(x = \tilde J^{(2)}\), which is left to be determined by the remaining partially flat condition \(\breve J^{(2)} = 0\). Expressed in Cauchy-gauge quantities, this condition is a nonlinear equation \(x = \Phi(x)\). It is solved by iterating \(x_{k+1} = \Phi(x_k)\) from \(x_0 = 0\) until the largest change in \(x\) over the angular collocation points falls below J2Tolerance.
Of the required radial derivatives, the Cauchy simulation supplies only \(\partial_r J|_\Gamma\), or equivalently \(\partial_{\tilde y}\tilde J|_\Gamma = (R/2)\,\partial_r J|_\Gamma\). The second derivative \(\partial_{\tilde y}^2\tilde J|_\Gamma\) is obtained by inverting the characteristic \(H\)-hypersurface equation at the worldtube, which uses only quantities already stored in the worldtube data, together with the time derivative \(\partial_{\tilde u}\partial_r J|_\Gamma\). This time derivative is computed by interpolating the stored time series of \(\partial_r J|_\Gamma\) and differentiating the interpolant.
With these, the construction consists of three steps:
The transformed profile preserves the worldtube matching and satisfies both partially flat conditions: \(\breve J^{(0)} = 0\) through the angular map and \(\breve J^{(2)} = 0\) through the root \(x\).
In step 2, the condition \(\breve J^{(0)} = 0\) is solved in closed form at each angular point, which specifies the target angular Jacobian of the map at every point of the sphere. The map is then recovered iteratively. A potential-based solve generates each displacement of the map from a single spin-weight-1 potential, determined by the difference between the current and the target Jacobian, and reaches its minimum residual within a few iterations. If that does not bring \(\max|\breve J^{(0)}|\) below MaxPartiallyFlatJ0, linearized iterations continue from its map until \(\max|\breve J^{(0)}|\) stops improving.
The options of CauchySecondOrder are:
After building the initial data, CauchySecondOrder prints a summary of steps 1 and 2 and of \(\max|\breve J^{(0)}|\) and \(\max|\breve J^{(2)}|\) over the angular grid. In it, the Cauchy-gauge \(J^{(2)}\) is \(x\), and the partially flat \(J^{(0)}\) and \(J^{(2)}\) are \(\breve J^{(0)}\) and \(\breve J^{(2)}\). For a binary black hole worldtube at \(R = 100M\) with LMax: 20 it reads, for example (long lines wrapped):
Initialization stops if \(\max|\breve J^{(0)}|\) exceeds MaxPartiallyFlatJ0 or \(\max|\breve J^{(2)}|\) exceeds MaxPartiallyFlatJ2. The angular solve can bring \(\breve J^{(0)}\) only down to a floor, which rises with the size of \(\tilde J^{(0)}\), so it is mostly a concern for worldtubes at small extraction radii. When \(\max|\breve J^{(0)}|\) cannot reach MaxPartiallyFlatJ0, the worldtube data are usually the cause: the spherical-harmonic modes of \(J\) do not decay with \(\ell\). Raising the CCE LMax lowers the floor only if the modes still decay beyond the current LMax. If the error reports that \(\max|\breve J^{(0)}|\) had stopped improving, raising J0MaxIterations does not help either. Instead, use a worldtube at a larger extraction radius, or raise MaxPartiallyFlatJ0 to sit just above the reported \(\max|\breve J^{(0)}|\).
CCE will run faster if the input worldtube hdf5 file is chunked in small numbers of complete rows. This is relevant because by default, SpEC and SpECTRE write their worldtube files chunked along full time-series columns, which is efficient for writing and compression, but not for reading in to CCE. In that case, you can rechunk the input file before running CCE for maximum performance. This can be done, for instance, using h5py (you will need to fill in filenames appropriate to your case in place of "BondiCceR0050.h5" and "RechunkBondiCceR0050.h5"):
The rechunked data will still be in the same format as before, but will just have a different underlying structure in the H5 file that makes it faster to read in.
Once you have acquired an executable, running CCE in a supported environment is a simple command:
The initial data are built first. CauchySecondOrder prints a summary of them and stops if they do not meet its tolerances.
After this, you'll likely see some output like
which tells you that the simulation is proceeding as expected. When the run finished, you'll see something like
In terms of runtime, we've found that for a ~5000M long cauchy simulation, CCE takes about 6 hours to run. This will vary based on a number of factors like how long the cauchy evolution actually is, the desired error tolerance of your characteristic timestepper, and also how much data you output at future null infinity. Therefore, take these numbers with a grain of salt and only use them as a rough estimate for how long a job will take.
Once you have the reduction data output file from a successful CCE run, you can confirm the integrity of the h5 file and its contents by running
For the reduction file produced by a successful run, the output of the h5ls should resemble
Notice that the worldtube radius will be encoded into the subfile name.
No matter the spin weight of the quantity, the \(\ell = 0,1\) modes will always be output by CCE. Also, the /SpectreR0100.cce group will have a legend attribute that specifies the columns.
The Strain represents the asymptotic transverse-traceless contribution to the metric scaled by the Bondi radius (to give the asymptotically leading part), the News represents the first time derivative of the strain, and each of the Psi... datasets represent the Weyl scalars, each scaled by the appropriate factor of the Bondi-Sachs radius to retrieve the asymptotically leading contribution.
The EthInertialRetardedTime is a diagnostic dataset that represents the angular derivative of the inertial retarded time, which determines the coordinate transformation that is performed at future null infinity.
If you'd like to visualize the output of a CCE run, we offer a CLI that will produce a plot of all of quantities except EthInertialRetardedTime. To see how to use this CLI, run
If you'd like to do something more complicated than just make a quick plot, you'll have to load in the output data yourself using h5py or our spectre.IO.H5 bindings.
You may notice some odd features in some of the output quantities if you try and plot them. This is not a bug in CCE (not that we know of at least). This occurs because the data at future null infinity is in the wrong Bondi-Metzner-Sachs (BMS) frame. In order to put this data into the correct BMS frame, the SXS Collaboration offers a python/numba code called scri to do these transformations. See their documentation for how to install/run/plot a waveform at future null infinity in the correct BMS frame.
Below is a plot of the imaginary part of the 2,2 component for the strain when plotted using the raw output from SpECTRE CCE and BMS frame-fixing with scri. You'll notice that there is a non-zero offset, and this component of the strain doesn't decay back down to zero during the ringdown. This is because of the improper BMS frame that the SpECTRE CCE waveform is in. A supertranslation must be applied to transform the waveform into the correct BMS frame. See [152] for a review of BMS transformations and gravitational memory. To perform the frame fixing, see this tutorial in scri.
The discrepancy is even more apparent if you plot the amplitude of the two waveforms. It's pretty clear which waveform is the more "physical" one.
Notice that there are still some oscillations in the strain output by scri towards the beginning of the waveform (up to ~1500M). This is caused by CCE junk radiation from imperfect initial data on the null hypersurface. In order to use this waveform in analysis, the CCE junk must be cut off from the beginning.
You are also able to see gravitational memory effects with SpECTRE CCE! This shows up in the real part of the 2,0 mode of the strain. Though you can see the memory effects in the SpECTRE CCE waveform, in order to do any analysis, you must also transform the waveform to a more physically motivated BMS frame.
If you use the SpECTRE CCE module to extract your waveforms at future null infinity, please cite the following:
If you used scri to perform any frame-fixing, please also consult the scri GitHub for how you should cite it.
You can also consult our Publication policies page for further questions or contact spectre-devel@black-holes.org.