17#include <spdlog/fmt/bundled/core.h>
19#include <boost/algorithm/string/predicate.hpp>
20#include <boost/endian/conversion.hpp>
21#include <boost/interprocess/file_mapping.hpp>
22#include <boost/interprocess/mapped_region.hpp>
26#include <unordered_map>
44 return project_directory_is_set;
52 return std::filesystem::exists(std::filesystem::path(strFilename));
55std::tuple<std::string, std::string::size_type, std::string::size_type>
58 char const close_char,
59 std::string::size_type pos)
61 auto const pos_curly_brace_open = in.find_first_of(open_char, pos);
62 if (pos_curly_brace_open == std::string::npos)
64 return std::make_tuple(
"", std::string::npos, std::string::npos);
66 auto const pos_curly_brace_close =
67 in.find_first_of(close_char, pos_curly_brace_open);
68 if (pos_curly_brace_close == std::string::npos)
70 return std::make_tuple(
"", std::string::npos, std::string::npos);
72 return std::make_tuple(
73 in.substr(pos_curly_brace_open + 1,
74 pos_curly_brace_close - (pos_curly_brace_open + 1)),
75 pos_curly_brace_open, pos_curly_brace_close);
80 auto const position = str.find(keyword);
81 if (position != std::string::npos)
83 return str.substr(0, position);
90 std::string
const& parenthesized_string,
91 std::string::size_type
const begin,
92 std::string::size_type
const end,
93 std::string
const& keyword, T& data)
95 std::string precision_specification =
98 if (precision_specification.empty())
103 if constexpr (std::is_same_v<std::remove_cvref_t<T>,
bool>)
105 if (keyword ==
"converged")
107 std::string r = data ?
"" :
"_not_converged";
108 result.replace(begin, end - begin + 1, r);
113 std::unordered_map<std::type_index, char> type_specification;
114 type_specification[std::type_index(
typeid(
int))] =
'd';
115 type_specification[std::type_index(
typeid(
double))] =
'f';
116 type_specification[std::type_index(
typeid(std::string))] =
's';
118 auto const& b = precision_specification.back();
120 if (b ==
'e' || b ==
'E' || b ==
'f' || b ==
'F' || b ==
'g' || b ==
'G')
122 type_specification[std::type_index(
typeid(
double))] = b;
123 precision_specification.pop_back();
126 std::string
const generated_fmt_string =
127 "{" + precision_specification +
128 type_specification[std::type_index(
typeid(data))] +
"}";
130 begin, end - begin + 1,
131 fmt::vformat(generated_fmt_string, fmt::make_format_args(data)));
137 std::string
const& mesh_name,
141 bool const converged)
143 char const open_char =
'{';
144 char const close_char =
'}';
145 std::string::size_type begin = 0;
146 std::string::size_type end = std::string::npos;
147 std::string result = format_specification;
149 while (begin != std::string::npos)
151 auto length_before_substitution = result.length();
153 std::string str =
"";
154 std::tie(str, begin, end) =
164 begin = end - (length_before_substitution - result.length());
175 char c[
sizeof(double)];
179 for (
unsigned short i = 0; i <
sizeof(double) / 2; i++)
181 b.c[i] = a.c[
sizeof(double) / 2 - i - 1];
184 for (
unsigned short i =
sizeof(
double) / 2; i <
sizeof(double); i++)
186 b.c[i] = a.c[
sizeof(double) +
sizeof(
double) / 2 - i - 1];
194 auto const filename_path = std::filesystem::path(filename);
195 return (filename_path.parent_path() / filename_path.stem()).string();
200 return std::filesystem::path(pathname).filename().string();
211 return std::filesystem::path(path).extension().string();
221 return std::filesystem::path(pathname).parent_path().string();
224std::string
joinPaths(std::string
const& pathA, std::string
const& pathB)
226 return (std::filesystem::path(pathA) /= std::filesystem::path(pathB))
224std::string
joinPaths(std::string
const& pathA, std::string
const& pathB) {
…}
232 if (!project_directory_is_set)
234 OGS_FATAL(
"The project directory has not yet been set.");
236 return project_directory;
241 if (project_directory_is_set)
243 OGS_FATAL(
"The project directory has already been set.");
247 project_directory = dir;
248 project_directory_is_set =
true;
253 project_directory.clear();
254 project_directory_is_set =
false;
260 std::filesystem::remove(std::filesystem::path(filename));
263 DBUG(
"Removed '{:s}'", filename);
269 for (
auto const& file : files)
282 std::error_code mkdir_err;
283 if (std::filesystem::create_directories(dir, mkdir_err))
285 INFO(
"Output directory {:s} created.", dir);
287 else if (mkdir_err.value() != 0)
289 WARN(
"Could not create output directory {:s}. Error code {:d}, {:s}",
290 dir, mkdir_err.value(), mkdir_err.message());
301 if (file_extension !=
".bin")
304 "Currently only binary files with extension '.bin' supported. The "
305 "specified file has extension {:s}.",
315 in.read(
reinterpret_cast<char*
>(&v),
sizeof(T));
325 std::size_t
const start_element,
326 std::size_t
const num_elements)
330 OGS_FATAL(
"File {:s} not found", filename);
334 std::uintmax_t file_size = std::filesystem::file_size(filename);
335 std::size_t total_elements = file_size /
sizeof(T);
337 if (start_element >= total_elements)
339 OGS_FATAL(
"Start element is beyond file size");
343 std::size_t
const elements_to_read =
344 std::min(num_elements, total_elements - start_element);
347 std::size_t
const offset = start_element *
sizeof(T);
348 std::size_t
const size_to_map = elements_to_read *
sizeof(T);
351 boost::interprocess::file_mapping file(filename.c_str(),
352 boost::interprocess::read_only);
355 boost::interprocess::mapped_region region(
356 file, boost::interprocess::read_only, offset, size_to_map);
359 auto* addr = region.get_address();
362 std::vector<T> result(elements_to_read);
363 std::memcpy(result.data(), addr, size_to_map);
365 if constexpr (std::endian::native != std::endian::little)
367 boost::endian::endian_reverse_inplace(result);
384 out.write(
reinterpret_cast<const char*
>(&val),
sizeof(T));
void INFO(fmt::format_string< Args... > fmt, Args &&... args)
void DBUG(fmt::format_string< Args... > fmt, Args &&... args)
void WARN(fmt::format_string< Args... > fmt, Args &&... args)
std::string containsKeyword(std::string const &str, std::string const &keyword)
void removeFile(std::string const &filename)
std::vector< T > readBinaryVector(std::string const &filename, std::size_t const start_element, std::size_t const num_elements)
std::string constructFormattedFileName(std::string const &format_specification, std::string const &mesh_name, int const timestep, double const t, int const iteration, bool const converged)
std::string const & getProjectDirectory()
Returns the directory where the prj file resides.
std::string getFileExtension(const std::string &path)
void writeValueBinary(std::ostream &out, T const &val)
write value as binary into the given output stream
std::string extractPath(std::string const &pathname)
std::vector< double > readDoublesFromBinaryFile(const std::string &filename)
std::tuple< std::string, std::string::size_type, std::string::size_type > getParenthesizedString(std::string const &in, char const open_char, char const close_char, std::string::size_type pos)
T readBinaryValue(std::istream &in)
bool IsFileExisting(const std::string &strFilename)
Returns true if given file exists.
template void writeValueBinary< std::size_t >(std::ostream &, std::size_t const &)
template std::vector< double > readBinaryVector< double >(std::string const &, std::size_t const, std::size_t const)
template float readBinaryValue< float >(std::istream &)
std::string extractBaseNameWithoutExtension(std::string const &pathname)
std::string dropFileExtension(std::string const &filename)
bool isProjectDirectorySet()
Returns true if the project directory is set.
std::string joinPaths(std::string const &pathA, std::string const &pathB)
void unsetProjectDirectory()
Unsets the project directory.
template double readBinaryValue< double >(std::istream &)
std::string extractBaseName(std::string const &pathname)
double swapEndianness(double const &v)
bool createOutputDirectory(std::string const &dir)
bool substituteKeyword(std::string &result, std::string const &parenthesized_string, std::string::size_type const begin, std::string::size_type const end, std::string const &keyword, T &data)
void setProjectDirectory(std::string const &dir)
Sets the project directory.
bool hasFileExtension(std::string const &extension, std::string const &filename)
void removeFiles(std::vector< std::string > const &files)
template std::vector< float > readBinaryVector< float >(std::string const &, std::size_t const, std::size_t const)