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 <mutex>
8 : #include <string>
9 : #include <unordered_map>
10 : #include <vector>
11 :
12 : #include "DataStructures/DataBox/DataBox.hpp"
13 : #include "IO/H5/AccessType.hpp"
14 : #include "IO/H5/Cce.hpp"
15 : #include "IO/H5/File.hpp"
16 : #include "IO/Observer/Helpers.hpp"
17 : #include "IO/Observer/Tags.hpp"
18 : #include "Parallel/GlobalCache.hpp"
19 : #include "Parallel/NodeLock.hpp"
20 : #include "Utilities/Algorithm.hpp"
21 : #include "Utilities/ConstantExpressions.hpp"
22 : #include "Utilities/ErrorHandling/Assert.hpp"
23 : #include "Utilities/Gsl.hpp"
24 :
25 : namespace Cce::Actions {
26 : /*!
27 : * \brief Write a single row of data into an `h5::Cce` subfile within an H5
28 : * file.
29 : *
30 : * \details This action can be called as either a threaded action or a local
31 : * synchronous action. In both cases, invoke this action on the
32 : * `observers::ObserverWriter` component on node 0. You must pass the following
33 : * arguments when invoking this action
34 : *
35 : * - `subfile_name`: the name of the `h5::Cce` subfile in the HDF5 file.
36 : * - `l_max`: the number of spherical harmonics of the data
37 : * - `data`: a `std::unordered_map<std::string, std::vector<double>>` where the
38 : * keys are the names of all the bondi quantities to write and the data are
39 : * the spherical harmonic coefficients. See `h5::Cce` for exactly what names
40 : * need to be used and the layout of the data.
41 : *
42 : * \note If you want to write data into an `h5::Dat` file, use
43 : * `observers::ThreadedActions::WriteReductionDataRow`.
44 : */
45 1 : struct WriteScriBondiQuantities {
46 : /// \brief The apply call for the threaded action
47 : template <typename ParallelComponent, typename DbTagsList,
48 : typename Metavariables, typename ArrayIndex>
49 1 : static void apply(db::DataBox<DbTagsList>& box,
50 : Parallel::GlobalCache<Metavariables>& cache,
51 : const ArrayIndex& /*array_index*/,
52 : const gsl::not_null<Parallel::NodeLock*> node_lock,
53 : const std::string& subfile_name, const size_t l_max,
54 : std::unordered_map<std::string, std::vector<double>> data) {
55 : apply<ParallelComponent>(box, node_lock, cache, subfile_name, l_max,
56 : std::move(data));
57 : }
58 :
59 : // The local synchronous action
60 0 : using return_type = void;
61 :
62 : /// \brief The apply call for the local synchronous action
63 : template <typename ParallelComponent, typename DbTagList,
64 : typename Metavariables>
65 1 : static return_type apply(
66 : db::DataBox<DbTagList>& box,
67 : const gsl::not_null<Parallel::NodeLock*> /*node_lock*/,
68 : Parallel::GlobalCache<Metavariables>& cache,
69 : const std::string& subfile_name, const size_t l_max,
70 : std::unordered_map<std::string, std::vector<double>> data) {
71 : auto& reduction_file_lock =
72 : db::get_mutable_reference<observers::Tags::H5FileLock>(
73 : make_not_null(&box));
74 : const std::lock_guard hold_lock(reduction_file_lock);
75 :
76 : // Make sure all data is the proper size
77 : ASSERT(
78 : alg::all_of(data,
79 : [&l_max](const auto& name_and_data) {
80 : return name_and_data.second.size() ==
81 : 2 * square(l_max + 1) + 1;
82 : }),
83 : "Some data sent to WriteScriBondiQuantities is not of the proper size "
84 : << 2 * square(l_max + 1) + 1);
85 :
86 : const std::string input_source = observers::input_source_from_cache(cache);
87 : const std::string& reduction_file_prefix =
88 : Parallel::get<observers::Tags::ReductionFileName>(cache);
89 : h5::H5File<h5::AccessType::ReadWrite> h5file(reduction_file_prefix + ".h5",
90 : true, input_source);
91 : constexpr size_t version_number = 0;
92 : auto& cce_file =
93 : h5file.try_insert<h5::Cce>(subfile_name, l_max, version_number);
94 : cce_file.append(data);
95 : }
96 : };
97 : } // namespace Cce::Actions
|