ESPResSo
Extensible Simulation Package for Research on Soft Matter Systems
Loading...
Searching...
No Matches
h5md_core.hpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2010-2022 The ESPResSo project
3 * Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010
4 * Max-Planck-Institute for Polymer Research, Theory Group
5 *
6 * This file is part of ESPResSo.
7 *
8 * ESPResSo is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * ESPResSo is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22#ifndef CORE_IO_WRITER_H5MD_CORE_HPP
23#define CORE_IO_WRITER_H5MD_CORE_HPP
24
25#include "BoxGeometry.hpp"
26#include "ParticleRange.hpp"
28
29#include <utils/Vector.hpp>
30
31#include <boost/filesystem.hpp>
32#include <boost/mpi/communicator.hpp>
33
34#include <h5xx/h5xx.hpp>
35
36#include <cstddef>
37#include <stdexcept>
38#include <string>
39#include <type_traits>
40#include <unordered_map>
41#include <utility>
42
43namespace h5xx {
44template <typename T, std::size_t size>
45struct is_array<Utils::Vector<T, size>> : std::true_type {};
46} // namespace h5xx
47
48namespace Writer {
49namespace H5md {
50
51/**
52 * @brief Constants which indicate what to output.
53 * To indicate the output of multiple fields, OR the
54 * corresponding values.
55 */
72
73static std::unordered_map<std::string, H5MDOutputFields> const fields_map = {
74 {"all", H5MD_OUT_ALL},
75 {"particle.type", H5MD_OUT_TYPE},
76 {"particle.position", H5MD_OUT_POS},
77 {"particle.image", H5MD_OUT_IMG},
78 {"particle.velocity", H5MD_OUT_VEL},
79 {"particle.force", H5MD_OUT_FORCE},
80 {"particle.bonds", H5MD_OUT_BONDS},
81 {"particle.charge", H5MD_OUT_CHARGE},
82 {"particle.mass", H5MD_OUT_MASS},
83 {"box.length", H5MD_OUT_BOX_L},
84 {"lees_edwards.offset", H5MD_OUT_LE_OFF},
85 {"lees_edwards.direction", H5MD_OUT_LE_DIR},
86 {"lees_edwards.normal", H5MD_OUT_LE_NORMAL},
87};
88
89inline auto fields_list_to_bitfield(std::vector<std::string> const &fields) {
90 unsigned int bitfield = H5MD_OUT_NONE;
91 for (auto const &field_name : fields) {
92 if (fields_map.count(field_name) == 0) {
93 throw std::invalid_argument("Unknown field '" + field_name + "'");
94 }
95 bitfield |= fields_map.at(field_name);
96 }
97 return bitfield;
98}
99
100/**
101 * @brief Class for writing H5MD files.
102 */
103class File {
104public:
105 /**
106 * @brief Constructor.
107 * @param file_path Name for the hdf5 file on disk.
108 * @param script_path Path to the simulation script.
109 * @param output_fields Properties to write to disk.
110 * @param mass_unit The unit for mass.
111 * @param length_unit The unit for length.
112 * @param time_unit The unit for time.
113 * @param force_unit The unit for force.
114 * @param velocity_unit The unit for velocity.
115 * @param charge_unit The unit for charge.
116 * @param comm The MPI communicator.
117 */
118 File(std::string file_path, std::string script_path,
119 std::vector<std::string> const &output_fields, std::string mass_unit,
120 std::string length_unit, std::string time_unit, std::string force_unit,
121 std::string velocity_unit, std::string charge_unit,
122 boost::mpi::communicator comm = boost::mpi::communicator())
123 : m_script_path(std::move(script_path)),
124 m_mass_unit(std::move(mass_unit)),
125 m_length_unit(std::move(length_unit)),
126 m_time_unit(std::move(time_unit)), m_force_unit(std::move(force_unit)),
127 m_velocity_unit(std::move(velocity_unit)),
128 m_charge_unit(std::move(charge_unit)), m_comm(std::move(comm)),
129 m_fields(fields_list_to_bitfield(output_fields)),
130 m_h5md_specification(m_fields) {
131 init_file(file_path);
132 }
133 ~File() = default;
134
135 /**
136 * @brief Method to perform the renaming of the temporary file from
137 * "filename" + ".bak" to "filename".
138 */
139 void close();
140
141 /**
142 * @brief Write data to the hdf5 file.
143 * @param particles Particle range for which to write data.
144 * @param time Simulation time.
145 * @param step Simulation step (monotonically increasing).
146 * @param geometry The box dimensions.
147 */
148 void write(const ParticleRange &particles, double time, int step,
149 BoxGeometry const &geometry);
150
151 /**
152 * @brief Retrieve the path to the hdf5 file.
153 * @return The path as a string.
154 */
155 auto file_path() const { return m_h5md_file.name(); }
156
157 /**
158 * @brief Retrieve the path to the simulation script.
159 * @return The path as a string.
160 */
161 auto const &script_path() const { return m_script_path; }
162
163 /**
164 * @brief Retrieve the set mass unit.
165 * @return The unit as a string.
166 */
167 auto const &mass_unit() const { return m_mass_unit; }
168
169 /**
170 * @brief Retrieve the set length unit.
171 * @return The unit as a string.
172 */
173 auto const &length_unit() const { return m_length_unit; }
174
175 /**
176 * @brief Retrieve the set time unit.
177 * @return The unit as a string.
178 */
179 auto const &time_unit() const { return m_time_unit; }
180
181 /**
182 * @brief Retrieve the set force unit.
183 * @return The unit as a string.
184 */
185 auto const &force_unit() const { return m_force_unit; }
186
187 /**
188 * @brief Retrieve the set velocity unit.
189 * @return The unit as a string.
190 */
191 auto const &velocity_unit() const { return m_velocity_unit; }
192
193 /**
194 * @brief Retrieve the set charge unit.
195 * @return The unit as a string.
196 */
197 auto const &charge_unit() const { return m_charge_unit; }
198
199 /**
200 * @brief Build the list of valid output fields.
201 * @return The list as a vector of strings.
202 */
203 auto valid_fields() const {
204 std::vector<std::string> out = {};
205 for (auto const &kv : fields_map) {
206 out.push_back(kv.first);
207 }
208 return out;
209 }
210
211 /**
212 * @brief Method to enforce flushing the buffer to disk.
213 */
214 void flush();
215
216private:
217 /**
218 * @brief Initialize the File object.
219 */
220 void init_file(std::string const &file_path);
221
222 /**
223 * @brief Creates a new H5MD file.
224 * @param file_path The filename.
225 */
226 void create_file(const std::string &file_path);
227
228 /**
229 * @brief Loads an existing H5MD file.
230 * @param file_path The filename.
231 */
232 void load_file(const std::string &file_path);
233
234 /**
235 * @brief Create the HDF5 groups according to the H5MD specification.
236 */
237 void create_groups();
238
239 /**
240 * @brief Creates the necessary HDF5 datasets according to the H5MD
241 * specification.
242 */
243 void create_datasets();
244
245 /**
246 * @brief Load datasets of the file.
247 */
248 void load_datasets();
249
250 /**
251 * @brief Write the particle bonds (currently only pairs).
252 * @param particles Particle range for which to write bonds.
253 */
254 void write_connectivity(const ParticleRange &particles);
255 /**
256 * @brief Write the unit attributes.
257 */
258 void write_units();
259 /**
260 * @brief Create hard links for the time and step entries of time-dependent
261 * datasets.
262 */
263 void create_hard_links();
264
265 std::string m_script_path;
266 std::string m_mass_unit;
267 std::string m_length_unit;
268 std::string m_time_unit;
269 std::string m_force_unit;
270 std::string m_velocity_unit;
271 std::string m_charge_unit;
272 boost::mpi::communicator m_comm;
273 unsigned int m_fields;
274 std::string m_backup_filename;
275 boost::filesystem::path m_absolute_script_path;
276 h5xx::file m_h5md_file;
277 std::unordered_map<std::string, h5xx::dataset> datasets;
278 H5MD_Specification m_h5md_specification;
279};
280
281struct incompatible_h5mdfile : public std::exception {
282 const char *what() const noexcept override {
283 return "The given .h5 file does not match the specifications in 'fields'.";
284 }
285};
286
287struct left_backupfile : public std::exception {
288 const char *what() const noexcept override {
289 return "A backup of the .h5 file exists. This usually means that either "
290 "you forgot to call the 'close' method or your simulation crashed.";
291 }
292};
293
294} /* namespace H5md */
295} /* namespace Writer */
296#endif
Vector implementation and trait types for boost qvm interoperability.
A range of particles.
Class for writing H5MD files.
void write(const ParticleRange &particles, double time, int step, BoxGeometry const &geometry)
Write data to the hdf5 file.
auto const & length_unit() const
Retrieve the set length unit.
auto const & time_unit() const
Retrieve the set time unit.
auto file_path() const
Retrieve the path to the hdf5 file.
void close()
Method to perform the renaming of the temporary file from "filename" + ".bak" to "filename".
auto const & force_unit() const
Retrieve the set force unit.
File(std::string file_path, std::string script_path, std::vector< std::string > const &output_fields, std::string mass_unit, std::string length_unit, std::string time_unit, std::string force_unit, std::string velocity_unit, std::string charge_unit, boost::mpi::communicator comm=boost::mpi::communicator())
Constructor.
auto const & mass_unit() const
Retrieve the set mass unit.
auto const & charge_unit() const
Retrieve the set charge unit.
auto const & velocity_unit() const
Retrieve the set velocity unit.
auto valid_fields() const
Build the list of valid output fields.
auto const & script_path() const
Retrieve the path to the simulation script.
void flush()
Method to enforce flushing the buffer to disk.
auto fields_list_to_bitfield(std::vector< std::string > const &fields)
Definition h5md_core.hpp:89
H5MDOutputFields
Constants which indicate what to output.
Definition h5md_core.hpp:56
static std::unordered_map< std::string, H5MDOutputFields > const fields_map
Definition h5md_core.hpp:73
Layout information for H5MD files.
const char * what() const noexcept override
const char * what() const noexcept override