Dune-Fufem 2.11-git
Loading...
Searching...
No Matches
singletonwriter.hh
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright © DUNE-FUFEM Project contributors, see file AUTHORS.md
2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception OR LGPL-3.0-or-later
3
4#ifndef DUNE_FUFEM_HDF5_SINGLETONWRITER_HH
5#define DUNE_FUFEM_HDF5_SINGLETONWRITER_HH
6
7#include <numeric>
8
9#if __has_include(<hdf5.h>)
10
11#include <hdf5.h>
12
15#include <dune/istl/bvector.hh>
16#include <dune/istl/matrix.hh>
17
18#include "file.hh"
19#include "tobuffer.hh"
20#include "typetraits.hh"
21
22namespace HDF5 {
23template <int spatialDimensions, typename ctype = double, typename T = hsize_t>
24class SingletonWriter {
25private:
26 int static const dimensions = spatialDimensions;
27
28public:
29 template <typename... Args>
30 SingletonWriter(Grouplike &file, std::string datasetname, Args... args)
31 : file_(file), capacity_{{T(args)...}} {
32 static_assert(sizeof...(args) == spatialDimensions,
33 "wrong number of arguments");
34 if (file_.isReadOnly())
35 DUNE_THROW(Dune::Exception, "Cannot handle read-only file");
36
37 if (file_.hasDataset(datasetname)) {
38 dset_ = file_.openDataset(datasetname);
39 checkDimensions();
40 checkDatatype();
41 checkLayout();
42 } else {
43 auto const initial_dims = maxExtent();
44 auto const max_dims = maxExtent();
45 hid_t file_space =
46 H5Screate_simple(dimensions, initial_dims.data(), max_dims.data());
47
48 hid_t plist = H5Pcreate(H5P_DATASET_CREATE);
49 H5Pset_layout(plist, H5D_CONTIGUOUS);
50 dset_ = file_.createDataset(datasetname, file_space, plist,
51 TypeTraits<ctype>::getType());
52
53 H5Pclose(plist);
54 H5Sclose(file_space);
55 }
56 }
57
58 ~SingletonWriter() { H5Dclose(dset_); }
59
60 void set(std::vector<ctype> const &buffer) {
61 if (buffer.size() != entrySize())
62 DUNE_THROW(Dune::Exception, "Buffer size incorrect");
63
64 hid_t file_space = H5Dget_space(dset_);
65 auto const start = minExtent();
66 auto const count = maxExtent();
67 H5Sselect_hyperslab(file_space, H5S_SELECT_SET, start.data(), NULL,
68 count.data(), NULL);
69
70 hid_t mem_space = H5Screate_simple(dimensions, count.data(), NULL);
71 H5Dwrite(dset_, TypeTraits<ctype>::getType(), mem_space, file_space,
72 H5P_DEFAULT, buffer.data());
73 H5Sclose(mem_space);
74 H5Sclose(file_space);
75 }
76
77private:
78 size_t entrySize() {
79 return std::accumulate(capacity_.begin(), capacity_.end(), 1,
81 }
82
83 void checkLayout() {
84 hid_t plist = H5Dget_create_plist(dset_);
85 H5D_layout_t layout = H5Pget_layout(plist);
86 if (layout != H5D_CONTIGUOUS)
87 DUNE_THROW(Dune::Exception, "Layout not contiguous");
88
89 H5Pclose(plist);
90 }
91
92 void checkDimensions() {
93 hid_t file_space = H5Dget_space(dset_);
95 int const rank = H5Sget_simple_extent_dims(file_space, dims.data(), NULL);
96
97 if (rank != dimensions)
98 DUNE_THROW(Dune::Exception, "Unexpected dataset rank");
99 if (capacity_ != dims)
100 DUNE_THROW(Dune::Exception, "unexpected dataset dimensions");
101
102 H5Sclose(file_space);
103 }
104
105 void checkDatatype() {
106 if (!H5Tequal(H5Dget_type(dset_), TypeTraits<ctype>::getType()))
107 DUNE_THROW(Dune::Exception, "Unexpected data type");
108 }
109
110 std::array<T, dimensions> minExtent() {
112 std::fill(ret.begin(), ret.end(), 0);
113 return ret;
114 }
115
116 std::array<T, dimensions> maxExtent() { return capacity_; }
117
118 Grouplike &file_;
119 std::array<T, spatialDimensions> const capacity_;
120
121 hid_t dset_;
122};
123
124template <int spatialDimensions, typename ctype, typename T, class Data>
125void setEntry(SingletonWriter<spatialDimensions, ctype, T> &writer,
126 Data const &data) {
127 std::vector<ctype> buffer;
128 toBuffer(data, buffer);
129 writer.set(buffer);
130}
131}
132
133#else
134 #warning Including the hdf5/singletonwriter.hh but hdf5.h is missing.
135#endif // __has_include(<hdf5.h>)
136
137#endif
void toBuffer(Dune::Matrix< Dune::FieldVector< ctype, k > > const &data, std::vector< ctype > &buffer)
Definition tobuffer.hh:12
#define DUNE_THROW(E,...)
void start()
Start embedded python interpreter.
Definition common.hh:130
T accumulate(T... args)
T begin(T... args)
T count(T... args)
T data(T... args)
T end(T... args)
T fill(T... args)
T size(T... args)