/home/runner/work/DiFfRG_current/DiFfRG_current/DiFfRG/include/DiFfRG/discretization/data/fe_output.hh Source File#

DiFfRG: /home/runner/work/DiFfRG_current/DiFfRG_current/DiFfRG/include/DiFfRG/discretization/data/fe_output.hh Source File
DiFfRG
Discretization Framework for functional Renormalization Group flows
fe_output.hh
Go to the documentation of this file.
1#pragma once
2
3// DiFfRG
11
12// external libraries
13#include <deal.II/dofs/dof_handler.h>
14#include <deal.II/lac/vector_memory.h>
15#include <deal.II/numerics/data_out.h>
16
17#include <hdf5lib/hdf5.hh>
18
19// standard library
20#include <condition_variable>
21#include <exception>
22#include <list>
23#include <mutex>
24#include <thread>
25
26namespace DiFfRG
27{
28 using namespace dealii;
29
36 template <uint dim, typename VectorType> class FEOutput
37 {
50 std::conditional_t<is_distributed_la<VectorType>, dealii::Vector<get_type::NumberType<VectorType>>, VectorType>;
51
52 public:
62 FEOutput(std::string top_folder, std::string output_name, std::string output_folder,
63 const Config::OutputSettings &settings, bool active = true);
64 [[deprecated(
65 "Use FEOutput(top_folder, output_name, output_folder, Config::OutputSettings(config), active) instead")]]
66 FEOutput(std::string top_folder, std::string output_name, std::string output_folder, const ConfigTree &config,
67 bool active = true)
68 : FEOutput(std::move(top_folder), std::move(output_name), std::move(output_folder),
69 Config::OutputSettings(config), active)
70 {
71 }
72
74 ~FEOutput() noexcept;
75
77 void drain();
78
80 void finish();
81
91 void set_hdf5_output(HDF5Output *output, bool session_closes_file = false, std::string group_name = "FE");
92
94 bool will_discard() const { return !save_vtk && hdf5_output == nullptr; }
95
97 std::size_t pending_workers() const { return output_threads.size(); }
98
106 void attach(const DoFHandler<dim> &dof_handler, const VectorType &solution, const std::string &name);
107
115 void attach(const DoFHandler<dim> &dof_handler, const VectorType &solution, const std::vector<std::string> &names);
116
122 void flush(double time);
123
126 {
127 const FrameTimings taken = frame_timings;
129 return taken;
130 }
131
132 private:
133 const std::string top_folder;
134 const std::string output_name;
135 const std::string output_folder;
136 const std::string filename_pvd;
138 const std::size_t max_pending_bytes;
139
141 std::vector<std::pair<double, std::string>> time_series;
142
143 constexpr static uint safe_dim = dim == 0 ? 1 : dim;
144 std::vector<DataOut<safe_dim>> data_outs;
145 std::list<std::thread> output_threads;
146 // series number each worker thread is responsible for, kept in lockstep with output_threads so
147 // the main thread can clear() the corresponding DataOut once the worker has been joined. Clearing
148 // a DataOut frees its Kokkos-backed vectors, which (with deal.II's Kokkos host backend) must not
149 // happen on a worker thread concurrently with the main thread's own Kokkos work.
150 std::list<uint> output_thread_series;
151 // Owned outright rather than drawn from a GrowingVectorMemory pool. A pooled vector is not
152 // destroyed when the frame retires, it is handed back to a process-wide pool that lives until
153 // InitFinalize::finalize() tears it down -- i.e. these buffers would be freed during MPI/Kokkos
154 // shutdown, concurrently with whatever else is being finalised. That showed up as an
155 // intermittent segfault in GrowingVectorMemory::release_unused_memory() after the run had
156 // already printed its final line. Owning them means they die in retire_oldest()/drain(), on the
157 // main thread, while the run is still up.
158 std::list<std::list<std::unique_ptr<OutputVectorType>>> attached_solutions;
159 std::list<std::size_t> attached_bytes;
160 std::size_t pending_bytes = 0;
161
162 // serializes worker-thread access to time_series and the shared .pvd file
163 std::mutex output_mutex;
164 std::condition_variable output_condition;
166 bool publication_failed = false;
167 // captures any exception thrown inside a worker thread so it can be re-raised on the
168 // main thread at the next flush() (or at destruction, if no other throw is unwinding)
169 std::mutex exception_mutex;
170 std::exception_ptr stored_exception;
171 bool finished = false;
172
183 std::unique_ptr<DoFHandler<safe_dim>> dof_handler;
184 std::vector<types::global_dof_index> to_mirror;
185 boost::signals2::scoped_connection connection;
186 bool stale = true;
187 };
189
191 const DoFHandler<safe_dim> &prepare_output_vector(const DoFHandler<dim> &dof_handler, const VectorType &solution,
192 OutputVectorType &target);
193
196 void reserve_bytes(std::size_t bytes);
197
200 std::string hdf5_group_name = "FE";
201
203
205 };
206
207 template <typename VectorType> class FEOutput<0, VectorType>
208 {
209 public:
219 FEOutput(std::string top_folder, std::string output_name, std::string output_folder,
220 const Config::OutputSettings &settings, bool active = true);
221 [[deprecated(
222 "Use FEOutput(top_folder, output_name, output_folder, Config::OutputSettings(config), active) instead")]]
223 FEOutput(std::string top_folder, std::string output_name, std::string output_folder, const ConfigTree &config,
224 bool active = true)
225 : FEOutput(std::move(top_folder), std::move(output_name), std::move(output_folder),
226 Config::OutputSettings(config), active)
227 {
228 }
229 void drain() {}
230 void finish() {}
232 };
233
234} // namespace DiFfRG
A hierarchical configuration tree, readable from JSON and TOML files.
Definition config_tree.hh:32
FEOutput(std::string top_folder, std::string output_name, std::string output_folder, const Config::OutputSettings &settings, bool active=true)
Construct a new FEOutput object.
void finish()
Definition fe_output.hh:230
void drain()
Definition fe_output.hh:229
FEOutput(std::string top_folder, std::string output_name, std::string output_folder, const ConfigTree &config, bool active=true)
Definition fe_output.hh:223
FrameTimings take_frame_timings()
Definition fe_output.hh:231
A class to output finite element data to disk as .vtu files and .pvd time series.
Definition fe_output.hh:37
std::vector< DataOut< safe_dim > > data_outs
Definition fe_output.hh:144
HDF5Output * hdf5_output
Definition fe_output.hh:198
FEOutput(std::string top_folder, std::string output_name, std::string output_folder, const ConfigTree &config, bool active=true)
Definition fe_output.hh:66
void attach(const DoFHandler< dim > &dof_handler, const VectorType &solution, const std::vector< std::string > &names)
Attach a solution to the output.
std::list< std::thread > output_threads
Definition fe_output.hh:145
std::list< std::size_t > attached_bytes
Definition fe_output.hh:159
FEOutput(std::string top_folder, std::string output_name, std::string output_folder, const Config::OutputSettings &settings, bool active=true)
Construct a new FEOutput object.
uint next_published_series
Definition fe_output.hh:165
bool hdf5_closed_by_session
Definition fe_output.hh:199
uint series_number
Definition fe_output.hh:140
FrameTimings take_frame_timings()
Definition fe_output.hh:125
std::string hdf5_group_name
Definition fe_output.hh:200
std::conditional_t< is_distributed_la< VectorType >, dealii::Vector< get_type::NumberType< VectorType > >, VectorType > OutputVectorType
What the DataOut actually gets handed.
Definition fe_output.hh:49
const std::string output_name
Definition fe_output.hh:134
std::condition_variable output_condition
Definition fe_output.hh:164
const std::string output_folder
Definition fe_output.hh:135
std::mutex output_mutex
Definition fe_output.hh:163
bool finished
Definition fe_output.hh:171
uint subdivisions
Definition fe_output.hh:140
const uint buffer_size
Definition fe_output.hh:137
void reserve_bytes(std::size_t bytes)
const std::string top_folder
Definition fe_output.hh:133
const std::string filename_pvd
Definition fe_output.hh:136
void flush(double time)
Flush all attached solutions to disk.
std::vector< std::pair< double, std::string > > time_series
Definition fe_output.hh:141
void set_hdf5_output(HDF5Output *output, bool session_closes_file=false, std::string group_name="FE")
Route the finite-element frame data into an HDF5 file owned by someone else.
bool publication_failed
Definition fe_output.hh:166
FrameTimings frame_timings
Definition fe_output.hh:204
bool save_vtk
Definition fe_output.hh:202
std::size_t pending_bytes
Definition fe_output.hh:160
void attach(const DoFHandler< dim > &dof_handler, const VectorType &solution, const std::string &name)
Attach a solution to the output.
std::list< uint > output_thread_series
Definition fe_output.hh:150
const DoFHandler< safe_dim > & prepare_output_vector(const DoFHandler< dim > &dof_handler, const VectorType &solution, OutputVectorType &target)
static constexpr uint safe_dim
Definition fe_output.hh:143
std::size_t pending_workers() const
Definition fe_output.hh:97
~FEOutput() noexcept
std::mutex exception_mutex
Definition fe_output.hh:169
const std::size_t max_pending_bytes
Definition fe_output.hh:138
std::list< std::list< std::unique_ptr< OutputVectorType > > > attached_solutions
Definition fe_output.hh:158
std::exception_ptr stored_exception
Definition fe_output.hh:170
SerialMirrorDoFs mirror_dofs
Definition fe_output.hh:188
bool will_discard() const
Definition fe_output.hh:94
A class to output data to a CSV file.
Definition hdf5_output.hh:42
All compile-time knowledge about which linear algebra types DiFfRG uses.
Definition complex_math.hh:10
@ config
/discretization/threads.
unsigned int uint
Definition utils.hh:24
Definition output_settings.hh:15
Serial mirror of the solution DoFHandler, plus the map from its dof numbering to ours.
Definition fe_output.hh:182
boost::signals2::scoped_connection connection
Definition fe_output.hh:185
std::vector< types::global_dof_index > to_mirror
Definition fe_output.hh:184
bool stale
Definition fe_output.hh:186
std::unique_ptr< DoFHandler< safe_dim > > dof_handler
Definition fe_output.hh:183
Wall-clock cost of producing one output frame, split by where the time went.
Definition output_timings.hh:33