SpECTRE
v2025.03.17
|
Event to observe fields/variables in a characteristic evolution. More...
#include <ObserveFields.hpp>
Classes | |
struct | SubgroupName |
The name of the subgroup inside the HDF5 file. More... | |
struct | VariablesToObserve |
Public Types | |
using | available_tags_to_observe = tmpl::push_back< spin_weighted_tags_to_observe, Tags::ComplexInertialRetardedTime, Tags::OneMinusY > |
using | options = tmpl::list< SubgroupName, VariablesToObserve > |
using | compute_tags_for_observation_box = tmpl::list< Tags::Psi0Compute, Tags::Psi1Compute > |
using | return_tags = tmpl::list<> |
using | argument_tags = tmpl::list<::Tags::ObservationBox > |
using | is_ready_argument_tags = tmpl::list<> |
Public Member Functions | |
ObserveFields (const std::string &subgroup_name, const std::vector< std::string > &variables_to_observe, const Options::Context &context={}) | |
template<typename DataBoxType , typename ComputeTagsList , typename Metavariables , typename ArrayIndex , typename ParallelComponent > | |
void | operator() (const ObservationBox< DataBoxType, ComputeTagsList > &box, Parallel::GlobalCache< Metavariables > &cache, const ArrayIndex &, const ParallelComponent *const, const ObservationValue &) const |
template<typename Metavariables , typename ArrayIndex , typename Component > | |
bool | is_ready (Parallel::GlobalCache< Metavariables > &, const ArrayIndex &, const Component *const) const |
bool | needs_evolved_variables () const override |
Whether the event uses anything depending on the evolved_variables. If this returns false, anything depending on the evolved variables may have an incorrect value when the event is run. More... | |
void | pup (PUP::er &p) override |
![]() | |
Event (CkMigrateMessage *msg) | |
WRAPPED_PUPable_abstract (Event) | |
template<typename ComputeTagsList , typename DataBoxType , typename Metavariables , typename ArrayIndex , typename ComponentPointer > | |
void | run (const gsl::not_null< ObservationBox< ComputeTagsList, DataBoxType > * > box, Parallel::GlobalCache< Metavariables > &cache, const ArrayIndex &array_index, const ComponentPointer, const ObservationValue &observation_value) const |
template<typename DbTags , typename Metavariables , typename ArrayIndex , typename ComponentPointer > | |
bool | is_ready (const db::DataBox< DbTags > &box, Parallel::GlobalCache< Metavariables > &cache, const ArrayIndex &array_index, const ComponentPointer) const |
virtual bool | needs_evolved_variables () const =0 |
Whether the event uses anything depending on the evolved_variables. If this returns false, anything depending on the evolved variables may have an incorrect value when the event is run. More... | |
Static Public Attributes | |
static constexpr Options::String | help |
Event to observe fields/variables in a characteristic evolution.
Similar to dg::Events::ObserveFields
, this event will write volume data from the characteristic domain to disk when triggered. However, there are several differences which are important to highlight.
First is the fields themselves. The DG event takes the fields to observe as template parameters because the event must work with many evolution systems. However, since this event is specific to the characteristic evolution system, we can hardcode the list of fields that are available to observe. The fields available to observe are the following tags along with their first and second Cce::Tags::Dy
derivatives (see Cce::Tags::Dy
for a definition of y
):
Cce::Tags::BondiBeta
Cce::Tags::BondiU
Cce::Tags::BondiQ
Cce::Tags::BondiW
Cce::Tags::BondiH
(no second derivative)Cce::Tags::BondiJ
Cce::Tags::Du<Cce::Tags::BondiJ>
Some more fields to observe are:
Cce::Tags::Psi0
Cce::Tags::Psi1
Cce::Tags::ComplexInertialRetardedTime
Cce::Tags::OneMinusY
Cce::Tags::BondiR
Cce::Tags::EthRDividedByR
Cce::Tags::DuRDividedByR
The main reason that this event is separate from the DG one is because this event writes modal data over the sphere for every radial grid point, while the DG event writes nodal data. Every tag above is a Scalar<SpinWeighted<ComplexDataVector, Spin>>
for some Spin
. While this data itself is in nodal form, it is more convenient to transform to modal data and decompose in spherical harmonics before writing. This means our typical way of writing/storing volume data won't work.
All data will be written into the observers::OptionTags::VolumeFileName
file. If CCE is run on a single core, then this will write the volume data immediately (synchronously) instead of sending it to the ObserverWriter to be written asynchronously. The option SubgroupName
controls the name of the H5 group where this volume data is written. For example, if SubgroupName
is "CceVolumeData", then the volume file will contain /CceVolumeData/VolumeData.vol
for most fields; it would contain /CceVolumeData/InertialRetardedTime.vol
for the inertial retarded time; and it would contain /CceVolumeData/OneMinusY.vol
for the compactified radial coordinate. The structure of the .vol subfiles is the same as that for DG volume data. However, the extents of the three different volume files are all different, and for modal directions, they take the values l_max in both of the two extent slots corresponding to angular modes. This also means that complex modal data (which has real/imag parts interleaved, as described below) has twice as much data as the products of the extents suggests.
The formats for Cce::Tags::ComplexInertialRetardedTime
and Cce::Tags::OneMinusY
are special and are described below. Every other field follows the same format. Each ObservationId contains one time slice. Within an ObservationId, each field is an unraveled vector of complex modal coefficients at compactified radial slices (the compactified coordinate is \(y = 1 - 2R/r\) where \(r\) is your coordinate radius and \(R\) is the coordinate radius of your worldtube; it is recommended to always dump the quantity Cce::Tags::OneMinusY
so the values of the compactified coordinates are available as well). The ordering of the coefficients for a field \(f\) at constant observation event are, for example: Re f_{0,0}(1-y_0), Im f_{0,0}(1-y_0), Re f_{1,-1}(1-y_0), Im f_{1,-1}(1-y_0), Re f_{1,0}(1-y_0), Im f_{1,0}(1-y_0), ... Re f_{l_{max},l_{max}}(1-y_0), Im f_{l_{max},l_{max}}(1-y_0), Re f_{0,0}(1-y_1), Im f_{0,0}(1-y_1), ... Re f_{l_{max},l_{max}}(1-y_{max)), Im f_{l_{max},l_{max}}(1-y_{max}). That is, the radial slice indexes the slowest, followed by the \(\ell\) number (always starting at 0, even for s≠0), followed by the azimuthal m number (from \(-\ell\) to \(+\ell\) inclusive), followed by interleaving real and imaginary parts of the complex field.
There are two notable exceptions to this format. One is Cce::Tags::ComplexInertialRetardedTime
. The quantity we are actually interested in is Cce::Tags::InertialRetardedTime
which is real and only defined once for every direction \(\theta,\phi\) (meaning it does not have different values at the different radial grid points). However, we use Cce::Tags::ComplexInertialRetardedTime
because it has the same data type as the other tags which makes the internals of the class simpler. This quantity is stored in /<SubgroupName>/InertialRetardedTime.vol
.
The second is Cce::Tags::OneMinusY
. Even though this quantity is stored as a Scalar<SpinWeighted<ComplexDataVector, 0>>
like the others, there is only one meaningful value per radial grid point. All angular grid points for a given radius are set to this value, namely \(1-y\). Thus we only need to write this value once for each radial grid point. We do this in a volume subfile /<SubgroupName>/OneMinusY.vol
with the elements in the same order as the radial index order for the spin weighted quantities above.
|
inlineoverridevirtual |
Whether the event uses anything depending on the evolved_variables. If this returns false, anything depending on the evolved variables may have an incorrect value when the event is run.
Implements Event.
|
staticconstexpr |