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#pragma once
23
24#include "BoxGeometry.hpp"
25#include "ParticleRange.hpp"
27
28#include <utils/Vector.hpp>
29
30#include <boost/filesystem.hpp>
31#include <boost/mpi/communicator.hpp>
32
33#include <cstddef>
34#include <memory>
35#include <stdexcept>
36#include <string>
37#include <type_traits>
38#include <unordered_map>
39#include <utility>
40
41namespace h5xx {
42class file;
43class dataset;
44} // namespace h5xx
45
46namespace Writer {
47namespace H5md {
48
49/**
50 * @brief Constants which indicate what to output.
51 * To indicate the output of multiple fields, OR the
52 * corresponding values.
53 */
70
71static std::unordered_map<std::string, H5MDOutputFields> const fields_map = {
72 {"all", H5MD_OUT_ALL},
73 {"particle.type", H5MD_OUT_TYPE},
74 {"particle.position", H5MD_OUT_POS},
75 {"particle.image", H5MD_OUT_IMG},
76 {"particle.velocity", H5MD_OUT_VEL},
77 {"particle.force", H5MD_OUT_FORCE},
78 {"particle.bonds", H5MD_OUT_BONDS},
79 {"particle.charge", H5MD_OUT_CHARGE},
80 {"particle.mass", H5MD_OUT_MASS},
81 {"box.length", H5MD_OUT_BOX_L},
82 {"lees_edwards.offset", H5MD_OUT_LE_OFF},
83 {"lees_edwards.direction", H5MD_OUT_LE_DIR},
84 {"lees_edwards.normal", H5MD_OUT_LE_NORMAL},
85};
86
87inline auto fields_list_to_bitfield(std::vector<std::string> const &fields) {
88 unsigned int bitfield = H5MD_OUT_NONE;
89 for (auto const &field_name : fields) {
90 if (not fields_map.contains(field_name)) {
91 throw std::invalid_argument("Unknown field '" + field_name + "'");
92 }
93 bitfield |= fields_map.at(field_name);
94 }
95 return bitfield;
96}
97
98/**
99 * @brief Class for writing H5MD files.
100 */
101class File {
102public:
103 /**
104 * @brief Constructor.
105 * @param file_path Name for the hdf5 file on disk.
106 * @param script_path Path to the simulation script.
107 * @param output_fields Properties to write to disk.
108 * @param mass_unit The unit for mass.
109 * @param length_unit The unit for length.
110 * @param time_unit The unit for time.
111 * @param force_unit The unit for force.
112 * @param velocity_unit The unit for velocity.
113 * @param charge_unit The unit for charge.
114 */
115 File(std::string file_path, std::string script_path,
116 std::vector<std::string> const &output_fields, std::string mass_unit,
117 std::string length_unit, std::string time_unit, std::string force_unit,
118 std::string velocity_unit, std::string charge_unit);
120
121 /**
122 * @brief Method to perform the renaming of the temporary file from
123 * "filename" + ".bak" to "filename".
124 */
125 void close();
126
127 /**
128 * @brief Write data to the hdf5 file.
129 * @param particles Particle range for which to write data.
130 * @param time Simulation time.
131 * @param step Simulation step (monotonically increasing).
132 * @param geometry The box dimensions.
133 */
134 void write(const ParticleRange &particles, double time, int step,
135 BoxGeometry const &geometry);
136
137 /**
138 * @brief Retrieve the path to the hdf5 file.
139 * @return The path as a string.
140 */
141 std::string file_path() const;
142
143 /**
144 * @brief Retrieve the path to the simulation script.
145 * @return The path as a string.
146 */
147 auto const &script_path() const { return m_script_path; }
148
149 /**
150 * @brief Retrieve the set mass unit.
151 * @return The unit as a string.
152 */
153 auto const &mass_unit() const { return m_mass_unit; }
154
155 /**
156 * @brief Retrieve the set length unit.
157 * @return The unit as a string.
158 */
159 auto const &length_unit() const { return m_length_unit; }
160
161 /**
162 * @brief Retrieve the set time unit.
163 * @return The unit as a string.
164 */
165 auto const &time_unit() const { return m_time_unit; }
166
167 /**
168 * @brief Retrieve the set force unit.
169 * @return The unit as a string.
170 */
171 auto const &force_unit() const { return m_force_unit; }
172
173 /**
174 * @brief Retrieve the set velocity unit.
175 * @return The unit as a string.
176 */
177 auto const &velocity_unit() const { return m_velocity_unit; }
178
179 /**
180 * @brief Retrieve the set charge unit.
181 * @return The unit as a string.
182 */
183 auto const &charge_unit() const { return m_charge_unit; }
184
185 /**
186 * @brief Build the list of valid output fields.
187 * @return The list as a vector of strings.
188 */
189 auto valid_fields() const {
190 std::vector<std::string> out = {};
191 for (auto const &kv : fields_map) {
192 out.push_back(kv.first);
193 }
194 return out;
195 }
196
197 /**
198 * @brief Method to enforce flushing the buffer to disk.
199 */
200 void flush();
201
202private:
203 /**
204 * @brief Initialize the File object.
205 */
206 void init_file(std::string const &file_path);
207
208 /**
209 * @brief Creates a new H5MD file.
210 * @param file_path The filename.
211 */
212 void create_file(const std::string &file_path);
213
214 /**
215 * @brief Loads an existing H5MD file.
216 * @param file_path The filename.
217 */
218 void load_file(const std::string &file_path);
219
220 /**
221 * @brief Create the HDF5 groups according to the H5MD specification.
222 */
223 void create_groups();
224
225 /**
226 * @brief Creates the necessary HDF5 datasets according to the H5MD
227 * specification.
228 */
229 void create_datasets();
230
231 /**
232 * @brief Load datasets of the file.
233 */
234 void load_datasets();
235
236 /**
237 * @brief Write the particle bonds (currently only pairs).
238 * @param particles Particle range for which to write bonds.
239 */
240 void write_connectivity(const ParticleRange &particles);
241 /**
242 * @brief Write the unit attributes.
243 */
244 void write_units();
245 /**
246 * @brief Create hard links for the time and step entries of time-dependent
247 * datasets.
248 */
249 void create_hard_links();
250
251 std::string m_script_path;
252 std::string m_mass_unit;
253 std::string m_length_unit;
254 std::string m_time_unit;
255 std::string m_force_unit;
256 std::string m_velocity_unit;
257 std::string m_charge_unit;
258 boost::mpi::communicator m_comm;
259 unsigned int m_fields;
260 std::string m_backup_filename;
261 boost::filesystem::path m_absolute_script_path;
262 std::unique_ptr<h5xx::file> m_h5md_file;
263 std::unique_ptr<std::unordered_map<std::string, h5xx::dataset>> m_datasets;
264 Specification m_h5md_specification;
265};
266
267struct incompatible_h5mdfile : public std::exception {
268 const char *what() const noexcept override {
269 return "The given .h5 file does not match the specifications in 'fields'.";
270 }
271};
272
273struct left_backupfile : public std::exception {
274 const char *what() const noexcept override {
275 return "A backup of the .h5 file exists. This usually means that either "
276 "you forgot to call the 'close' method or your simulation crashed.";
277 }
278};
279
280} /* namespace H5md */
281} /* namespace Writer */
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.
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.
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.
std::string file_path() const
Retrieve the path to the hdf5 file.
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:87
H5MDOutputFields
Constants which indicate what to output.
Definition h5md_core.hpp:54
static std::unordered_map< std::string, H5MDOutputFields > const fields_map
Definition h5md_core.hpp:71
Layout information for H5MD files.
const char * what() const noexcept override
const char * what() const noexcept override