2018-08-08 13:54:33 -05:00
|
|
|
#ifndef OPENMC_HDF5_INTERFACE_H
|
|
|
|
|
#define OPENMC_HDF5_INTERFACE_H
|
2018-01-19 18:12:57 -05:00
|
|
|
|
2018-10-09 11:01:30 -05:00
|
|
|
#include <algorithm> // for min
|
2018-07-09 09:17:26 -05:00
|
|
|
#include <complex>
|
2018-07-06 06:36:05 -05:00
|
|
|
#include <cstddef>
|
2018-10-09 11:01:30 -05:00
|
|
|
#include <cstring> // for strlen
|
2018-04-16 15:58:03 -05:00
|
|
|
#include <sstream>
|
|
|
|
|
#include <string>
|
2018-10-11 09:35:51 -05:00
|
|
|
#include <type_traits>
|
2018-01-23 12:37:28 -05:00
|
|
|
|
2018-07-09 09:27:02 -05:00
|
|
|
#include "hdf5.h"
|
|
|
|
|
#include "hdf5_hl.h"
|
2026-02-17 09:50:38 -06:00
|
|
|
#include "openmc/tensor.h"
|
2018-06-26 14:03:54 -05:00
|
|
|
|
2021-04-22 16:46:23 -04:00
|
|
|
#include "openmc/array.h"
|
2018-09-08 06:44:49 -04:00
|
|
|
#include "openmc/error.h"
|
2021-04-22 16:46:23 -04:00
|
|
|
#include "openmc/position.h"
|
|
|
|
|
#include "openmc/vector.h"
|
2018-01-23 12:37:28 -05:00
|
|
|
|
2018-01-31 15:28:36 -05:00
|
|
|
namespace openmc {
|
|
|
|
|
|
2018-07-06 06:36:05 -05:00
|
|
|
//==============================================================================
|
|
|
|
|
// Low-level internal functions
|
|
|
|
|
//==============================================================================
|
2018-01-23 12:37:28 -05:00
|
|
|
|
2018-04-18 22:54:51 -05:00
|
|
|
void read_attr(hid_t obj_id, const char* name, hid_t mem_type_id, void* buffer);
|
2019-12-12 17:24:03 -05:00
|
|
|
|
2018-07-06 06:36:05 -05:00
|
|
|
void write_attr(hid_t obj_id, int ndim, const hsize_t* dims, const char* name,
|
2019-12-12 17:24:03 -05:00
|
|
|
hid_t mem_type_id, const void* buffer);
|
|
|
|
|
|
|
|
|
|
void read_dataset_lowlevel(hid_t obj_id, const char* name, hid_t mem_type_id,
|
2019-12-13 11:51:22 -05:00
|
|
|
hid_t mem_space_id, bool indep, void* buffer);
|
2019-12-12 17:24:03 -05:00
|
|
|
|
|
|
|
|
void write_dataset_lowlevel(hid_t group_id, int ndim, const hsize_t* dims,
|
2019-12-13 11:51:22 -05:00
|
|
|
const char* name, hid_t mem_type_id, hid_t mem_space_id, bool indep,
|
|
|
|
|
const void* buffer);
|
2019-12-12 17:24:03 -05:00
|
|
|
|
2018-07-06 06:36:05 -05:00
|
|
|
bool using_mpio_device(hid_t obj_id);
|
|
|
|
|
|
|
|
|
|
//==============================================================================
|
|
|
|
|
// Normal functions that are used to read/write files
|
|
|
|
|
//==============================================================================
|
|
|
|
|
|
|
|
|
|
hid_t create_group(hid_t parent_id, const std::string& name);
|
2018-08-21 12:10:01 -04:00
|
|
|
|
|
|
|
|
inline hid_t create_group(hid_t parent_id, const std::stringstream& name)
|
|
|
|
|
{
|
|
|
|
|
return create_group(parent_id, name.str());
|
|
|
|
|
}
|
|
|
|
|
|
2018-07-06 06:36:05 -05:00
|
|
|
hid_t file_open(const std::string& filename, char mode, bool parallel = false);
|
2021-06-23 10:23:32 +07:00
|
|
|
hid_t open_group(hid_t group_id, const std::string& name);
|
2018-07-06 06:36:05 -05:00
|
|
|
void write_string(
|
|
|
|
|
hid_t group_id, const char* name, const std::string& buffer, bool indep);
|
2018-04-17 22:55:07 -05:00
|
|
|
|
2021-04-22 16:46:23 -04:00
|
|
|
vector<hsize_t> attribute_shape(hid_t obj_id, const char* name);
|
|
|
|
|
vector<std::string> dataset_names(hid_t group_id);
|
2018-10-17 06:34:12 -05:00
|
|
|
void ensure_exists(hid_t obj_id, const char* name, bool attribute = false);
|
2021-04-22 16:46:23 -04:00
|
|
|
vector<std::string> group_names(hid_t group_id);
|
|
|
|
|
vector<hsize_t> object_shape(hid_t obj_id);
|
2018-07-12 14:13:45 -05:00
|
|
|
std::string object_name(hid_t obj_id);
|
2021-10-13 07:27:56 -05:00
|
|
|
hid_t open_object(hid_t group_id, const std::string& name);
|
|
|
|
|
void close_object(hid_t obj_id);
|
2018-07-09 09:18:37 -05:00
|
|
|
|
2018-07-06 06:36:05 -05:00
|
|
|
//==============================================================================
|
|
|
|
|
// Fortran compatibility functions
|
|
|
|
|
//==============================================================================
|
|
|
|
|
|
|
|
|
|
extern "C" {
|
|
|
|
|
bool attribute_exists(hid_t obj_id, const char* name);
|
|
|
|
|
size_t attribute_typesize(hid_t obj_id, const char* name);
|
|
|
|
|
hid_t create_group(hid_t parent_id, const char* name);
|
|
|
|
|
void close_dataset(hid_t dataset_id);
|
|
|
|
|
void close_group(hid_t group_id);
|
|
|
|
|
int dataset_ndims(hid_t dset);
|
2019-02-21 14:45:59 -06:00
|
|
|
size_t dataset_typesize(hid_t obj_id, const char* name);
|
2018-07-06 06:36:05 -05:00
|
|
|
hid_t file_open(const char* filename, char mode, bool parallel);
|
|
|
|
|
void file_close(hid_t file_id);
|
2022-01-19 11:25:04 -06:00
|
|
|
void get_name(hid_t obj_id, std::string& name);
|
2018-07-06 06:36:05 -05:00
|
|
|
int get_num_datasets(hid_t group_id);
|
|
|
|
|
int get_num_groups(hid_t group_id);
|
|
|
|
|
void get_datasets(hid_t group_id, char* name[]);
|
|
|
|
|
void get_groups(hid_t group_id, char* name[]);
|
|
|
|
|
void get_shape(hid_t obj_id, hsize_t* dims);
|
|
|
|
|
void get_shape_attr(hid_t obj_id, const char* name, hsize_t* dims);
|
|
|
|
|
bool object_exists(hid_t object_id, const char* name);
|
|
|
|
|
hid_t open_dataset(hid_t group_id, const char* name);
|
|
|
|
|
hid_t open_group(hid_t group_id, const char* name);
|
|
|
|
|
void read_attr_double(hid_t obj_id, const char* name, double* buffer);
|
|
|
|
|
void read_attr_int(hid_t obj_id, const char* name, int* buffer);
|
|
|
|
|
void read_attr_string(
|
|
|
|
|
hid_t obj_id, const char* name, size_t slen, char* buffer);
|
|
|
|
|
void read_complex(
|
2019-12-12 17:24:03 -05:00
|
|
|
hid_t obj_id, const char* name, std::complex<double>* buffer, bool indep);
|
|
|
|
|
void read_double(hid_t obj_id, const char* name, double* buffer, bool indep);
|
|
|
|
|
void read_int(hid_t obj_id, const char* name, int* buffer, bool indep);
|
2018-07-06 06:36:05 -05:00
|
|
|
void read_llong(hid_t obj_id, const char* name, long long* buffer, bool indep);
|
2019-12-12 17:24:03 -05:00
|
|
|
void read_string(
|
|
|
|
|
hid_t obj_id, const char* name, size_t slen, char* buffer, bool indep);
|
2021-08-11 11:41:49 -05:00
|
|
|
|
2025-11-12 11:41:37 -05:00
|
|
|
void read_tally_results(hid_t group_id, hsize_t n_filter, hsize_t n_score,
|
|
|
|
|
hsize_t n_results, double* results);
|
2018-07-06 06:36:05 -05:00
|
|
|
void write_attr_double(hid_t obj_id, int ndim, const hsize_t* dims,
|
2019-12-12 17:24:03 -05:00
|
|
|
const char* name, const double* buffer);
|
2018-07-06 06:36:05 -05:00
|
|
|
void write_attr_int(hid_t obj_id, int ndim, const hsize_t* dims,
|
2019-12-12 17:24:03 -05:00
|
|
|
const char* name, const int* buffer);
|
2018-07-06 06:36:05 -05:00
|
|
|
void write_attr_string(hid_t obj_id, const char* name, const char* buffer);
|
|
|
|
|
void write_double(hid_t group_id, int ndim, const hsize_t* dims,
|
2019-12-12 17:24:03 -05:00
|
|
|
const char* name, const double* buffer, bool indep);
|
2018-07-06 06:36:05 -05:00
|
|
|
void write_int(hid_t group_id, int ndim, const hsize_t* dims, const char* name,
|
2019-12-12 17:24:03 -05:00
|
|
|
const int* buffer, bool indep);
|
2018-07-06 06:36:05 -05:00
|
|
|
void write_llong(hid_t group_id, int ndim, const hsize_t* dims,
|
2019-12-12 17:24:03 -05:00
|
|
|
const char* name, const long long* buffer, bool indep);
|
2018-07-06 06:36:05 -05:00
|
|
|
void write_string(hid_t group_id, int ndim, const hsize_t* dims, size_t slen,
|
2025-11-12 11:41:37 -05:00
|
|
|
const char* name, const char* buffer, bool indep);
|
|
|
|
|
void write_tally_results(hid_t group_id, hsize_t n_filter, hsize_t n_score,
|
|
|
|
|
hsize_t n_results, const double* results);
|
2018-07-06 06:36:05 -05:00
|
|
|
} // extern "C"
|
2018-01-23 12:37:28 -05:00
|
|
|
|
2018-07-06 06:36:05 -05:00
|
|
|
//==============================================================================
|
|
|
|
|
// Template struct used to map types to HDF5 datatype IDs, which are stored
|
|
|
|
|
// using the type hid_t. By having a single static data member, the template can
|
|
|
|
|
// be specialized for each type we know of. The specializations appear in the
|
|
|
|
|
// .cpp file since they are definitions.
|
|
|
|
|
//==============================================================================
|
2018-04-19 14:44:10 -05:00
|
|
|
|
2018-07-06 06:36:05 -05:00
|
|
|
template<typename T>
|
|
|
|
|
struct H5TypeMap {
|
|
|
|
|
static const hid_t type_id;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
//==============================================================================
|
2018-08-08 21:51:24 -05:00
|
|
|
// Templates/overloads for read_attribute
|
2018-07-06 06:36:05 -05:00
|
|
|
//==============================================================================
|
2018-04-19 14:44:10 -05:00
|
|
|
|
2018-07-09 09:27:02 -05:00
|
|
|
// Scalar version
|
|
|
|
|
template<typename T>
|
|
|
|
|
void read_attribute(hid_t obj_id, const char* name, T& buffer)
|
|
|
|
|
{
|
2018-07-09 14:46:20 -05:00
|
|
|
read_attr(obj_id, name, H5TypeMap<T>::type_id, &buffer);
|
2018-07-09 09:27:02 -05:00
|
|
|
}
|
|
|
|
|
|
2019-01-24 07:26:44 -06:00
|
|
|
// array version
|
2021-04-22 16:46:23 -04:00
|
|
|
template<typename T, std::size_t N>
|
|
|
|
|
inline void read_attribute(hid_t obj_id, const char* name, array<T, N>& buffer)
|
2019-01-24 07:26:44 -06:00
|
|
|
{
|
|
|
|
|
read_attr(obj_id, name, H5TypeMap<T>::type_id, buffer.data());
|
|
|
|
|
}
|
|
|
|
|
|
2018-07-09 09:27:02 -05:00
|
|
|
// vector version
|
|
|
|
|
template<typename T>
|
2021-04-22 16:46:23 -04:00
|
|
|
void read_attribute(hid_t obj_id, const char* name, vector<T>& vec)
|
2018-07-09 09:27:02 -05:00
|
|
|
{
|
|
|
|
|
// Get shape of attribute array
|
|
|
|
|
auto shape = attribute_shape(obj_id, name);
|
|
|
|
|
|
|
|
|
|
// Allocate new array to read data into
|
|
|
|
|
std::size_t size = 1;
|
|
|
|
|
for (const auto x : shape)
|
|
|
|
|
size *= x;
|
|
|
|
|
vec.resize(size);
|
|
|
|
|
|
|
|
|
|
// Read data from attribute
|
|
|
|
|
read_attr(obj_id, name, H5TypeMap<T>::type_id, vec.data());
|
|
|
|
|
}
|
|
|
|
|
|
2026-02-17 09:50:38 -06:00
|
|
|
// Tensor version
|
2018-07-09 09:27:02 -05:00
|
|
|
template<typename T>
|
2026-02-17 09:50:38 -06:00
|
|
|
void read_attribute(hid_t obj_id, const char* name, tensor::Tensor<T>& tensor)
|
2018-07-09 09:27:02 -05:00
|
|
|
{
|
2026-02-17 09:50:38 -06:00
|
|
|
// Get shape of attribute
|
2018-07-09 09:27:02 -05:00
|
|
|
auto shape = attribute_shape(obj_id, name);
|
|
|
|
|
|
2026-02-17 09:50:38 -06:00
|
|
|
// Resize tensor and read data directly
|
|
|
|
|
vector<size_t> tshape(shape.begin(), shape.end());
|
|
|
|
|
tensor.resize(tshape);
|
2018-07-09 09:27:02 -05:00
|
|
|
|
|
|
|
|
// Read data from attribute
|
2026-02-17 09:50:38 -06:00
|
|
|
read_attr(obj_id, name, H5TypeMap<T>::type_id, tensor.data());
|
2018-07-09 09:27:02 -05:00
|
|
|
}
|
|
|
|
|
|
2018-08-08 21:51:24 -05:00
|
|
|
// overload for std::string
|
|
|
|
|
inline void read_attribute(hid_t obj_id, const char* name, std::string& str)
|
2018-07-09 23:00:51 -05:00
|
|
|
{
|
|
|
|
|
// Create buffer to read data into
|
|
|
|
|
auto n = attribute_typesize(obj_id, name);
|
2019-06-05 11:26:39 -04:00
|
|
|
char* buffer = new char[n];
|
2018-07-09 23:00:51 -05:00
|
|
|
|
|
|
|
|
// Read attribute and set string
|
|
|
|
|
read_attr_string(obj_id, name, n, buffer);
|
|
|
|
|
str = std::string {buffer, n};
|
2019-06-05 11:26:39 -04:00
|
|
|
delete[] buffer;
|
2018-07-09 23:00:51 -05:00
|
|
|
}
|
|
|
|
|
|
2021-04-22 16:46:23 -04:00
|
|
|
// overload for vector<std::string>
|
|
|
|
|
inline void read_attribute(
|
|
|
|
|
hid_t obj_id, const char* name, vector<std::string>& vec)
|
2018-08-13 16:11:48 -05:00
|
|
|
{
|
|
|
|
|
auto dims = attribute_shape(obj_id, name);
|
|
|
|
|
auto m = dims[0];
|
|
|
|
|
|
|
|
|
|
// Allocate a C char array to get strings
|
|
|
|
|
auto n = attribute_typesize(obj_id, name);
|
2019-06-06 17:20:14 +00:00
|
|
|
char* buffer = new char[m * n];
|
2018-08-13 16:11:48 -05:00
|
|
|
|
|
|
|
|
// Read char data in attribute
|
2019-06-06 17:20:14 +00:00
|
|
|
read_attr_string(obj_id, name, n, buffer);
|
2018-08-13 16:11:48 -05:00
|
|
|
|
2021-02-19 10:53:10 -06:00
|
|
|
for (decltype(m) i = 0; i < m; ++i) {
|
2018-10-25 17:42:09 -05:00
|
|
|
// Determine proper length of string -- strlen doesn't work because
|
|
|
|
|
// buffer[i] might not have any null characters
|
|
|
|
|
std::size_t k = 0;
|
2019-06-06 17:20:14 +00:00
|
|
|
for (; k < n; ++k)
|
|
|
|
|
if (buffer[i * n + k] == '\0')
|
|
|
|
|
break;
|
2018-10-25 17:42:09 -05:00
|
|
|
|
|
|
|
|
// Create string based on (char*, size_t) constructor
|
2019-06-06 17:20:14 +00:00
|
|
|
vec.emplace_back(&buffer[i * n], k);
|
2018-08-13 16:11:48 -05:00
|
|
|
}
|
2019-06-05 11:26:39 -04:00
|
|
|
delete[] buffer;
|
2018-08-13 16:11:48 -05:00
|
|
|
}
|
|
|
|
|
|
2018-08-08 21:51:24 -05:00
|
|
|
//==============================================================================
|
2018-09-08 06:44:49 -04:00
|
|
|
// Templates/overloads for read_dataset and related methods
|
2018-08-08 21:51:24 -05:00
|
|
|
//==============================================================================
|
|
|
|
|
|
2019-02-19 21:48:20 -06:00
|
|
|
// Template for scalars. We need to be careful that the compiler does not use
|
|
|
|
|
// this version of read_dataset for vectors, arrays, or other non-scalar types.
|
|
|
|
|
// enable_if_t allows us to conditionally remove the function from overload
|
|
|
|
|
// resolution when the type T doesn't meet a certain criterion.
|
2019-02-14 12:43:05 -06:00
|
|
|
template<typename T>
|
|
|
|
|
inline std::enable_if_t<std::is_scalar<std::decay_t<T>>::value> read_dataset(
|
|
|
|
|
hid_t obj_id, const char* name, T& buffer, bool indep = false)
|
2018-07-09 09:27:02 -05:00
|
|
|
{
|
2019-12-13 11:51:22 -05:00
|
|
|
read_dataset_lowlevel(
|
|
|
|
|
obj_id, name, H5TypeMap<T>::type_id, H5S_ALL, indep, &buffer);
|
2018-07-09 09:27:02 -05:00
|
|
|
}
|
|
|
|
|
|
2019-02-05 23:39:22 -06:00
|
|
|
// overload for std::string
|
|
|
|
|
inline void read_dataset(
|
|
|
|
|
hid_t obj_id, const char* name, std::string& str, bool indep = false)
|
|
|
|
|
{
|
|
|
|
|
// Create buffer to read data into
|
2019-02-21 14:45:59 -06:00
|
|
|
auto n = dataset_typesize(obj_id, name);
|
2022-01-13 09:22:21 +01:00
|
|
|
std::vector<std::string::value_type> buffer(n, '\0');
|
2019-02-05 23:39:22 -06:00
|
|
|
|
|
|
|
|
// Read attribute and set string
|
2022-01-13 09:22:21 +01:00
|
|
|
read_string(obj_id, name, n, buffer.data(), indep);
|
2022-01-16 19:29:29 +00:00
|
|
|
str = std::string {buffer.begin(), buffer.end()};
|
2019-02-05 23:39:22 -06:00
|
|
|
}
|
|
|
|
|
|
2019-02-14 12:43:05 -06:00
|
|
|
// array version
|
2021-04-22 16:46:23 -04:00
|
|
|
template<typename T, std::size_t N>
|
|
|
|
|
inline void read_dataset(
|
|
|
|
|
hid_t dset, const char* name, array<T, N>& buffer, bool indep = false)
|
2019-02-14 12:43:05 -06:00
|
|
|
{
|
2019-12-13 11:51:22 -05:00
|
|
|
read_dataset_lowlevel(
|
|
|
|
|
dset, name, H5TypeMap<T>::type_id, H5S_ALL, indep, buffer.data());
|
2019-02-14 12:43:05 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// vector version
|
2021-04-22 16:46:23 -04:00
|
|
|
template<typename T>
|
|
|
|
|
void read_dataset(hid_t dset, vector<T>& vec, bool indep = false)
|
2018-07-09 09:27:02 -05:00
|
|
|
{
|
|
|
|
|
// Get shape of dataset
|
2021-04-22 16:46:23 -04:00
|
|
|
vector<hsize_t> shape = object_shape(dset);
|
2018-07-09 09:27:02 -05:00
|
|
|
|
|
|
|
|
// Resize vector to appropriate size
|
|
|
|
|
vec.resize(shape[0]);
|
|
|
|
|
|
|
|
|
|
// Read data into vector
|
2019-12-13 11:51:22 -05:00
|
|
|
read_dataset_lowlevel(
|
|
|
|
|
dset, nullptr, H5TypeMap<T>::type_id, H5S_ALL, indep, vec.data());
|
2018-07-09 09:27:02 -05:00
|
|
|
}
|
|
|
|
|
|
2021-04-22 16:46:23 -04:00
|
|
|
template<typename T>
|
|
|
|
|
void read_dataset(
|
|
|
|
|
hid_t obj_id, const char* name, vector<T>& vec, bool indep = false)
|
2018-07-09 09:27:02 -05:00
|
|
|
{
|
|
|
|
|
hid_t dset = open_dataset(obj_id, name);
|
|
|
|
|
read_dataset(dset, vec, indep);
|
|
|
|
|
close_dataset(dset);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename T>
|
2026-02-17 09:50:38 -06:00
|
|
|
void read_dataset(hid_t dset, tensor::Tensor<T>& tensor, bool indep = false)
|
2018-07-09 09:27:02 -05:00
|
|
|
{
|
|
|
|
|
// Get shape of dataset
|
2021-04-22 16:46:23 -04:00
|
|
|
vector<hsize_t> shape = object_shape(dset);
|
2018-07-09 09:27:02 -05:00
|
|
|
|
2026-02-17 09:50:38 -06:00
|
|
|
// Resize tensor and read data directly
|
|
|
|
|
vector<size_t> tshape(shape.begin(), shape.end());
|
|
|
|
|
tensor.resize(tshape);
|
2018-07-09 09:27:02 -05:00
|
|
|
|
2026-02-17 09:50:38 -06:00
|
|
|
// Read data from dataset
|
2019-12-13 11:51:22 -05:00
|
|
|
read_dataset_lowlevel(
|
2026-02-17 09:50:38 -06:00
|
|
|
dset, nullptr, H5TypeMap<T>::type_id, H5S_ALL, indep, tensor.data());
|
2018-07-09 09:27:02 -05:00
|
|
|
}
|
|
|
|
|
|
2018-12-26 07:24:21 -06:00
|
|
|
template<>
|
2019-12-12 17:24:03 -05:00
|
|
|
void read_dataset(
|
2026-02-17 09:50:38 -06:00
|
|
|
hid_t dset, tensor::Tensor<std::complex<double>>& tensor, bool indep);
|
2018-12-26 07:24:21 -06:00
|
|
|
|
2018-07-09 09:27:02 -05:00
|
|
|
template<typename T>
|
2019-12-12 17:24:03 -05:00
|
|
|
void read_dataset(
|
2026-02-17 09:50:38 -06:00
|
|
|
hid_t obj_id, const char* name, tensor::Tensor<T>& tensor, bool indep = false)
|
2018-12-10 20:01:03 -05:00
|
|
|
{
|
2026-02-17 09:50:38 -06:00
|
|
|
// Open dataset and read tensor
|
2018-12-10 20:01:03 -05:00
|
|
|
hid_t dset = open_dataset(obj_id, name);
|
2026-02-17 09:50:38 -06:00
|
|
|
read_dataset(dset, tensor, indep);
|
2018-12-10 20:01:03 -05:00
|
|
|
close_dataset(dset);
|
2019-03-01 14:46:21 -06:00
|
|
|
}
|
2018-12-10 20:01:03 -05:00
|
|
|
|
2019-03-01 14:46:21 -06:00
|
|
|
// overload for Position
|
|
|
|
|
inline void read_dataset(
|
|
|
|
|
hid_t obj_id, const char* name, Position& r, bool indep = false)
|
|
|
|
|
{
|
2021-04-22 16:46:23 -04:00
|
|
|
array<double, 3> x;
|
2019-03-01 14:46:21 -06:00
|
|
|
read_dataset(obj_id, name, x, indep);
|
|
|
|
|
r.x = x[0];
|
|
|
|
|
r.y = x[1];
|
|
|
|
|
r.z = x[2];
|
2018-12-10 20:01:03 -05:00
|
|
|
}
|
|
|
|
|
|
2026-02-17 09:50:38 -06:00
|
|
|
template<typename T>
|
2019-11-07 13:27:16 -05:00
|
|
|
inline void read_dataset_as_shape(
|
2026-02-17 09:50:38 -06:00
|
|
|
hid_t obj_id, const char* name, tensor::Tensor<T>& tensor, bool indep = false)
|
2018-09-08 06:44:49 -04:00
|
|
|
{
|
|
|
|
|
hid_t dset = open_dataset(obj_id, name);
|
|
|
|
|
|
2026-02-17 09:50:38 -06:00
|
|
|
// Read data directly into pre-shaped tensor
|
2019-12-13 11:51:22 -05:00
|
|
|
read_dataset_lowlevel(
|
2026-02-17 09:50:38 -06:00
|
|
|
dset, nullptr, H5TypeMap<T>::type_id, H5S_ALL, indep, tensor.data());
|
2018-09-08 06:44:49 -04:00
|
|
|
|
|
|
|
|
close_dataset(dset);
|
|
|
|
|
}
|
|
|
|
|
|
2026-02-17 09:50:38 -06:00
|
|
|
template<typename T>
|
|
|
|
|
inline void read_nd_tensor(hid_t obj_id, const char* name,
|
|
|
|
|
tensor::Tensor<T>& result, bool must_have = false)
|
2018-09-08 06:44:49 -04:00
|
|
|
{
|
|
|
|
|
if (object_exists(obj_id, name)) {
|
|
|
|
|
read_dataset_as_shape(obj_id, name, result, true);
|
|
|
|
|
} else if (must_have) {
|
|
|
|
|
fatal_error(std::string("Must provide " + std::string(name) + "!"));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-08-08 21:51:24 -05:00
|
|
|
//==============================================================================
|
|
|
|
|
// Templates/overloads for write_attribute
|
|
|
|
|
//==============================================================================
|
|
|
|
|
|
2018-08-06 21:31:30 -05:00
|
|
|
template<typename T>
|
|
|
|
|
inline void write_attribute(hid_t obj_id, const char* name, T buffer)
|
2018-05-10 00:12:22 -04:00
|
|
|
{
|
2018-08-24 19:06:04 -04:00
|
|
|
write_attr(obj_id, 0, nullptr, name, H5TypeMap<T>::type_id, &buffer);
|
2018-05-10 00:12:22 -04:00
|
|
|
}
|
|
|
|
|
|
2018-08-08 21:51:24 -05:00
|
|
|
inline void write_attribute(hid_t obj_id, const char* name, const char* buffer)
|
2018-07-06 06:36:05 -05:00
|
|
|
{
|
|
|
|
|
write_attr_string(obj_id, name, buffer);
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-25 07:53:27 -06:00
|
|
|
inline void write_attribute(
|
|
|
|
|
hid_t obj_id, const char* name, const std::string& buffer)
|
|
|
|
|
{
|
|
|
|
|
write_attr_string(obj_id, name, buffer.c_str());
|
|
|
|
|
}
|
|
|
|
|
|
2021-04-22 16:46:23 -04:00
|
|
|
template<typename T, std::size_t N>
|
|
|
|
|
inline void write_attribute(
|
|
|
|
|
hid_t obj_id, const char* name, const array<T, N>& buffer)
|
2018-07-06 06:36:05 -05:00
|
|
|
{
|
|
|
|
|
hsize_t dims[] {N};
|
|
|
|
|
write_attr(obj_id, 1, dims, name, H5TypeMap<T>::type_id, buffer.data());
|
|
|
|
|
}
|
|
|
|
|
|
2021-04-22 16:46:23 -04:00
|
|
|
template<typename T>
|
|
|
|
|
inline void write_attribute(
|
|
|
|
|
hid_t obj_id, const char* name, const vector<T>& buffer)
|
2018-08-30 14:22:55 -05:00
|
|
|
{
|
|
|
|
|
hsize_t dims[] {buffer.size()};
|
|
|
|
|
write_attr(obj_id, 1, dims, name, H5TypeMap<T>::type_id, buffer.data());
|
|
|
|
|
}
|
|
|
|
|
|
2019-02-06 21:47:08 -06:00
|
|
|
inline void write_attribute(hid_t obj_id, const char* name, Position r)
|
|
|
|
|
{
|
2021-04-22 16:46:23 -04:00
|
|
|
array<double, 3> buffer {r.x, r.y, r.z};
|
2019-02-06 21:47:08 -06:00
|
|
|
write_attribute(obj_id, name, buffer);
|
|
|
|
|
}
|
|
|
|
|
|
2018-08-08 21:51:24 -05:00
|
|
|
//==============================================================================
|
|
|
|
|
// Templates/overloads for write_dataset
|
|
|
|
|
//==============================================================================
|
|
|
|
|
|
2018-10-11 09:35:51 -05:00
|
|
|
// Template for scalars (ensured by SFINAE)
|
|
|
|
|
template<typename T>
|
|
|
|
|
inline std::enable_if_t<std::is_scalar<std::decay_t<T>>::value> write_dataset(
|
2018-07-06 06:36:05 -05:00
|
|
|
hid_t obj_id, const char* name, T buffer)
|
|
|
|
|
{
|
2019-12-12 17:24:03 -05:00
|
|
|
write_dataset_lowlevel(
|
|
|
|
|
obj_id, 0, nullptr, name, H5TypeMap<T>::type_id, H5S_ALL, false, &buffer);
|
2018-07-06 06:36:05 -05:00
|
|
|
}
|
|
|
|
|
|
2018-08-08 21:51:24 -05:00
|
|
|
inline void write_dataset(hid_t obj_id, const char* name, const char* buffer)
|
2018-07-06 06:36:05 -05:00
|
|
|
{
|
|
|
|
|
write_string(obj_id, name, buffer, false);
|
|
|
|
|
}
|
2018-02-03 21:19:46 -05:00
|
|
|
|
2021-04-22 16:46:23 -04:00
|
|
|
template<typename T, std::size_t N>
|
|
|
|
|
inline void write_dataset(
|
|
|
|
|
hid_t obj_id, const char* name, const array<T, N>& buffer)
|
2018-04-29 19:09:22 -05:00
|
|
|
{
|
2018-07-06 06:36:05 -05:00
|
|
|
hsize_t dims[] {N};
|
2019-12-12 17:24:03 -05:00
|
|
|
write_dataset_lowlevel(obj_id, 1, dims, name, H5TypeMap<T>::type_id, H5S_ALL,
|
2019-12-13 11:51:22 -05:00
|
|
|
false, buffer.data());
|
2018-04-29 19:09:22 -05:00
|
|
|
}
|
|
|
|
|
|
2021-04-22 16:46:23 -04:00
|
|
|
inline void write_dataset(
|
|
|
|
|
hid_t obj_id, const char* name, const vector<std::string>& buffer)
|
2019-01-25 07:53:27 -06:00
|
|
|
{
|
|
|
|
|
auto n {buffer.size()};
|
|
|
|
|
hsize_t dims[] {n};
|
|
|
|
|
|
|
|
|
|
// Determine length of longest string, including \0
|
|
|
|
|
size_t m = 1;
|
|
|
|
|
for (const auto& s : buffer) {
|
|
|
|
|
m = std::max(m, s.size() + 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Copy data into contiguous buffer
|
2019-06-06 10:36:15 -04:00
|
|
|
char* temp = new char[n * m];
|
|
|
|
|
std::fill(temp, temp + n * m, '\0');
|
2021-02-19 10:53:10 -06:00
|
|
|
for (decltype(n) i = 0; i < n; ++i) {
|
2019-06-06 10:36:15 -04:00
|
|
|
std::copy(buffer[i].begin(), buffer[i].end(), temp + i * m);
|
2019-01-25 07:53:27 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Write 2D data
|
2019-06-06 10:36:15 -04:00
|
|
|
write_string(obj_id, 1, dims, m, name, temp, false);
|
2019-06-05 11:26:39 -04:00
|
|
|
|
|
|
|
|
// Free temp array
|
|
|
|
|
delete[] temp;
|
2019-01-25 07:53:27 -06:00
|
|
|
}
|
|
|
|
|
|
2021-04-22 16:46:23 -04:00
|
|
|
template<typename T>
|
|
|
|
|
inline void write_dataset(
|
|
|
|
|
hid_t obj_id, const char* name, const vector<T>& buffer)
|
2018-08-21 12:10:01 -04:00
|
|
|
{
|
|
|
|
|
hsize_t dims[] {buffer.size()};
|
2019-12-12 17:24:03 -05:00
|
|
|
write_dataset_lowlevel(obj_id, 1, dims, name, H5TypeMap<T>::type_id, H5S_ALL,
|
2019-12-13 11:51:22 -05:00
|
|
|
false, buffer.data());
|
2018-08-21 12:10:01 -04:00
|
|
|
}
|
|
|
|
|
|
2026-02-17 09:50:38 -06:00
|
|
|
// Template for Tensor and StaticTensor2D. A SFINAE guard is used here to
|
|
|
|
|
// prevent this template from matching vector/string types that have their own
|
|
|
|
|
// overloads above. A generic Container parameter avoids duplicating the body
|
|
|
|
|
// for both Tensor<T> and StaticTensor2D<T,R,C>.
|
|
|
|
|
template<typename Container,
|
|
|
|
|
typename =
|
|
|
|
|
std::enable_if_t<tensor::is_tensor<std::decay_t<Container>>::value>>
|
|
|
|
|
inline void write_dataset(hid_t obj_id, const char* name, const Container& arr)
|
2018-10-10 13:23:16 -05:00
|
|
|
{
|
2026-02-17 09:50:38 -06:00
|
|
|
using T = typename std::decay_t<Container>::value_type;
|
2018-10-10 13:23:16 -05:00
|
|
|
auto s = arr.shape();
|
2021-04-22 16:46:23 -04:00
|
|
|
vector<hsize_t> dims {s.cbegin(), s.cend()};
|
2019-12-12 17:24:03 -05:00
|
|
|
write_dataset_lowlevel(obj_id, dims.size(), dims.data(), name,
|
2019-12-13 11:51:22 -05:00
|
|
|
H5TypeMap<T>::type_id, H5S_ALL, false, arr.data());
|
2018-10-10 13:23:16 -05:00
|
|
|
}
|
|
|
|
|
|
2018-08-08 13:46:53 -05:00
|
|
|
inline void write_dataset(hid_t obj_id, const char* name, Position r)
|
2018-06-26 14:03:54 -05:00
|
|
|
{
|
2021-04-22 16:46:23 -04:00
|
|
|
array<double, 3> buffer {r.x, r.y, r.z};
|
2018-06-26 14:03:54 -05:00
|
|
|
write_dataset(obj_id, name, buffer);
|
|
|
|
|
}
|
|
|
|
|
|
2018-10-11 23:06:47 -04:00
|
|
|
inline void write_dataset(hid_t obj_id, const char* name, std::string buffer)
|
|
|
|
|
{
|
|
|
|
|
write_string(obj_id, name, buffer.c_str(), false);
|
|
|
|
|
}
|
|
|
|
|
|
2018-01-31 15:28:36 -05:00
|
|
|
} // namespace openmc
|
2018-08-08 13:54:33 -05:00
|
|
|
#endif // OPENMC_HDF5_INTERFACE_H
|