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