Line data Source code
1 0 : // Distributed under the MIT License.
2 : // See LICENSE.txt for details.
3 :
4 : #pragma once
5 :
6 : #include <cstddef>
7 : #include <limits>
8 : #include <string>
9 : #include <type_traits>
10 :
11 : #include "DataStructures/DataBox/DataBox.hpp"
12 : #include "DataStructures/DataVector.hpp"
13 : #include "DataStructures/Tensor/Tensor.hpp"
14 : #include "DataStructures/Tensor/TypeAliases.hpp"
15 : #include "Evolution/Systems/Cce/BoundaryData.hpp"
16 : #include "Evolution/Systems/Cce/OptionTags.hpp"
17 : #include "Evolution/Systems/Cce/Tags.hpp"
18 : #include "Evolution/Systems/GeneralizedHarmonic/TagsDeclarations.hpp"
19 : #include "IO/Observer/Actions/GetLockPointer.hpp"
20 : #include "IO/Observer/ObserverComponent.hpp"
21 : #include "Parallel/GlobalCache.hpp"
22 : #include "Parallel/Invoke.hpp"
23 : #include "ParallelAlgorithms/Interpolation/InterpolationTargetDetail.hpp"
24 : #include "ParallelAlgorithms/Interpolation/Protocols/PostInterpolationCallback.hpp"
25 : #include "PointwiseFunctions/GeneralRelativity/TagsDeclarations.hpp"
26 : #include "Utilities/Gsl.hpp"
27 : #include "Utilities/ProtocolHelpers.hpp"
28 : #include "Utilities/TMPL.hpp"
29 :
30 : /// \cond
31 : namespace CurvedScalarWave::Tags {
32 : struct Psi;
33 : struct Pi;
34 : template <size_t SpatialDim>
35 : struct Phi;
36 : } // namespace CurvedScalarWave::Tags
37 : namespace Parallel {
38 : class NodeLock;
39 : } // namespace Parallel
40 : namespace intrp::OptionHolders {
41 : struct Sphere;
42 : } // namespace intrp::OptionHolders
43 : namespace intrp::Tags {
44 : template <typename InterpolationTargetTag>
45 : struct Sphere;
46 : } // namespace intrp::Tags
47 : namespace intrp::TargetPoints {
48 : template <typename InterpolationTargetTag, typename Frame>
49 : struct Sphere;
50 : } // namespace intrp::TargetPoints
51 : namespace observers::Tags {
52 : struct H5FileLock;
53 : } // namespace observers::Tags
54 : /// \endcond
55 :
56 1 : namespace intrp::callbacks {
57 : namespace DumpBondiSachsOnWorldtube_detail {
58 : template <bool IncludeKleinGordon>
59 : void apply_impl(
60 : gsl::not_null<Parallel::NodeLock*> hdf5_lock, double time,
61 : const OptionHolders::Sphere& sphere, const std::string& filename_prefix,
62 : const tnsr::aa<DataVector, 3, ::Frame::Inertial>& all_spacetime_metric,
63 : const tnsr::aa<DataVector, 3, ::Frame::Inertial>& all_pi,
64 : const tnsr::iaa<DataVector, 3, ::Frame::Inertial>& all_phi,
65 : const Scalar<DataVector>& all_csw_psi = {},
66 : const Scalar<DataVector>& all_csw_pi = {},
67 : const tnsr::i<DataVector, 3, ::Frame::Inertial>& all_csw_phi = {},
68 : const Scalar<DataVector>& all_lapse = {},
69 : const tnsr::I<DataVector, 3, ::Frame::Inertial>& all_shift = {});
70 : } // namespace DumpBondiSachsOnWorldtube_detail
71 :
72 : /*!
73 : * \brief Post interpolation callback that dumps metric data in Bondi-Sachs form
74 : * on a number of extraction radii given by the `intrp::TargetPoints::Sphere`
75 : * target.
76 : *
77 : * To use this callback, the target must be the `intrp::TargetPoints::Sphere`
78 : * target in the inertial frame. This callback also expects that the GH source
79 : * vars on each of the target spheres are:
80 : *
81 : * - `gr::Tags::SpacetimeMetric`
82 : * - `gh::Tags::Pi`
83 : * - `gh::Tags::Phi`
84 : *
85 : * If IncludeKleinGordon is true, also expect:
86 : * - `CurvedScalarWave::Tags::Psi`
87 : * - `CurvedScalarWave::Tags::Pi`
88 : * - `CurvedScalarWave::Tags::Phi`
89 : * - `gr::Tags::Lapse`
90 : * - `gr::Tags::Shift`
91 : *
92 : * This callback will write a new `H5` file for each extraction radius in the
93 : * Sphere target. The name of this file will be a file prefix specified by the
94 : * Cce::Tags::FilePrefix prepended onto `CceRXXXX.h5` where the XXXX is the
95 : * zero-padded extraction radius rounded to the nearest integer. The quantities
96 : * that will be written are
97 : *
98 : * - `Cce::Tags::BondiBeta`
99 : * - `Cce::Tags::Dr<Cce::Tags::BondiJ>`
100 : * - `Cce::Tags::Du<Cce::Tags::BondiR>`
101 : * - `Cce::Tags::BondiH`
102 : * - `Cce::Tags::BondiJ`
103 : * - `Cce::Tags::BondiQ`
104 : * - `Cce::Tags::BondiR`
105 : * - `Cce::Tags::BondiU`
106 : * - `Cce::Tags::BondiW`
107 : *
108 : * If IncludeKleinGordon is true, also writes:
109 : * - `Cce::Tags::KleinGordonPsi`
110 : * - `Cce::Tags::KleinGordonPi`
111 : *
112 : * \note For all real quantities (Beta, DuR, R, W) (as well as the Klein-Gordon
113 : * Psi an Pi if included) we omit writing the negative m modes, and the
114 : * imaginary part of the m = 0 mode.
115 : */
116 : template <typename InterpolationTargetTag, bool IncludeKleinGordon = false>
117 1 : struct DumpBondiSachsOnWorldtube
118 : : tt::ConformsTo<intrp::protocols::PostInterpolationCallback> {
119 0 : static constexpr bool include_klein_gordon = IncludeKleinGordon;
120 0 : static constexpr double fill_invalid_points_with =
121 : std::numeric_limits<double>::quiet_NaN();
122 :
123 0 : using const_global_cache_tags = tmpl::list<Cce::Tags::FilePrefix>;
124 :
125 0 : using cce_boundary_tags = Cce::Tags::characteristic_worldtube_boundary_tags<
126 : Cce::Tags::BoundaryValue, include_klein_gordon>;
127 :
128 0 : using extra_klein_gordon_cce_tags =
129 : tmpl::list<CurvedScalarWave::Tags::Psi, CurvedScalarWave::Tags::Pi,
130 : CurvedScalarWave::Tags::Phi<3>, gr::Tags::Lapse<DataVector>,
131 : gr::Tags::Shift<DataVector, 3>>;
132 :
133 0 : using gh_source_vars_for_cce = tmpl::append<
134 : tmpl::list<gr::Tags::SpacetimeMetric<DataVector, 3>,
135 : gh::Tags::Pi<DataVector, 3>, gh::Tags::Phi<DataVector, 3>>,
136 : tmpl::conditional_t<include_klein_gordon, extra_klein_gordon_cce_tags,
137 : tmpl::list<>>>;
138 :
139 0 : using gh_source_vars_from_interpolation =
140 : typename InterpolationTargetTag::vars_to_interpolate_to_target;
141 :
142 : static_assert(
143 : tmpl::and_<
144 : std::is_same<tmpl::list_difference<gh_source_vars_from_interpolation,
145 : gh_source_vars_for_cce>,
146 : tmpl::list<>>,
147 : std::is_same<tmpl::list_difference<gh_source_vars_for_cce,
148 : gh_source_vars_from_interpolation>,
149 : tmpl::list<>>>::type::value,
150 : "To use DumpBondiSachsOnWorldtube, the GH source variables must be the "
151 : "spacetime metric, pi, and phi. If Klein Gordon variables are included, "
152 : "the source variables must also include the CurvedScalarWave Psi and Pi, "
153 : "as well as Lapse and shift.");
154 :
155 : static_assert(
156 : std::is_same_v<typename InterpolationTargetTag::compute_target_points,
157 : intrp::TargetPoints::Sphere<InterpolationTargetTag,
158 : ::Frame::Inertial>>,
159 : "To use the DumpBondiSachsOnWorldtube post interpolation callback, you "
160 : "must use the intrp::TargetPoints::Sphere target in the inertial "
161 : "frame");
162 :
163 : template <typename DbTags, typename Metavariables, typename TemporalId>
164 0 : static void apply(const db::DataBox<DbTags>& box,
165 : Parallel::GlobalCache<Metavariables>& cache,
166 : const TemporalId& temporal_id) {
167 : // Even though no other cores should be writing to this file, we
168 : // still need to get the h5 file lock so the system hdf5 doesn't get
169 : // upset
170 : auto* hdf5_lock = Parallel::local_synchronous_action<
171 : observers::Actions::GetLockPointer<observers::Tags::H5FileLock>>(
172 : Parallel::get_parallel_component<
173 : observers::ObserverWriter<Metavariables>>(cache));
174 :
175 : const double time =
176 : intrp::InterpolationTarget_detail::get_temporal_id_value(temporal_id);
177 : const auto& sphere =
178 : Parallel::get<Tags::Sphere<InterpolationTargetTag>>(cache);
179 : const auto& filename_prefix = Parallel::get<Cce::Tags::FilePrefix>(cache);
180 : const auto& all_spacetime_metric =
181 : get<gr::Tags::SpacetimeMetric<DataVector, 3>>(box);
182 : const auto& all_pi = get<gh::Tags::Pi<DataVector, 3>>(box);
183 : const auto& all_phi = get<gh::Tags::Phi<DataVector, 3>>(box);
184 : if constexpr (IncludeKleinGordon) {
185 : const auto& all_csw_psi = get<CurvedScalarWave::Tags::Psi>(box);
186 : const auto& all_csw_pi = get<CurvedScalarWave::Tags::Pi>(box);
187 : const auto& all_csw_phi = get<CurvedScalarWave::Tags::Phi<3>>(box);
188 : const auto& all_lapse = get<gr::Tags::Lapse<DataVector>>(box);
189 : const auto& all_shift = get<gr::Tags::Shift<DataVector, 3>>(box);
190 : DumpBondiSachsOnWorldtube_detail::apply_impl<IncludeKleinGordon>(
191 : hdf5_lock, time, sphere, filename_prefix, all_spacetime_metric,
192 : all_pi, all_phi, all_csw_psi, all_csw_pi, all_csw_phi, all_lapse,
193 : all_shift);
194 : } else {
195 : DumpBondiSachsOnWorldtube_detail::apply_impl<IncludeKleinGordon>(
196 : hdf5_lock, time, sphere, filename_prefix, all_spacetime_metric,
197 : all_pi, all_phi);
198 : }
199 : }
200 : };
201 : } // namespace intrp::callbacks
|