deleted opening-hdf5

This commit is contained in:
robin 2024-05-05 19:00:14 +02:00
parent 3f7de8fdce
commit eb74a777fe
4 changed files with 0 additions and 177 deletions

View File

@ -1,6 +0,0 @@
.DS_Store
src/.DS_Store
src/.cache
src/build
.idea
src/cmake-build-debug

View File

@ -1,39 +0,0 @@
## Location of data
The data path is hardcoded such that the following tree structure is assumed:
```
data/
grid.h5
hydrodynamic_U.h5
hydrodynamic_V.h5
interactive-track-and-trace/
opening-hdf5/
...
```
## Compiling
Let the current directory be the `src` directory. Run:
```shell
mkdir build
cd build
cmake ..
make
```
### Building with Linux
Makes use of `mdspan` which is not supported by glibc++ at time of writing. See [compiler support](https://en.cppreference.com/w/cpp/compiler_support/23) for `mdspan`. The solution to this is to use Clang and libc++; this is configured in our CMake setup, however the default installation of the `netcdf-cxx` package on at least Arch linux (and suspectedly Debian derivatives as well) specifically builds for the glibc implementation. To get the netcdf C++ bindings functional with the libc++ implementation, one needs to build from source. On Linux, this requires a few changes to the CMake file included with the netcdf-cxx source code, which are detailed below.
Step-by-step to build the program using clang++ and libc++ on linux:
1. Download the source code of netcdf-cxx, found at 'https://github.com/Unidata/netcdf-cxx4/releases/tag/v4.3.1' (make sure to download the release source code, as the master branch contains non-compilable code).
2. Edit the CMakeLists.txt file, by appending '-stdlib=libc++' to the `CMAKE_CXX_FLAGS` variable in line 430. This means line 430 should read:
```cmake
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -Wall -Wno-unused-variable -Wno-unused-parameter -stdlib=libc++")
```
2. Build the source code with the following:
```sh
mkdir build && cd build
cmake .. -DCMAKE_CXX_COMPILER=/usr/bin/clang++
make
ctest
sudo make install
```
3. Now the code should compile through the standard steps described in the Compiling section.

View File

@ -1,32 +0,0 @@
cmake_minimum_required (VERSION 3.28)
project (ReadHDF5)
set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# Force use of libc++ for mdspan support
set(CMAKE_CXX_COMPILER "clang++")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++ ")
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
find_package(netCDF REQUIRED)
add_executable(ReadHDF5 main.cpp)
execute_process(
COMMAND nc-config --includedir
OUTPUT_VARIABLE NETCDF_INCLUDE_DIR
OUTPUT_STRIP_TRAILING_WHITESPACE
)
execute_process(
COMMAND ncxx4-config --libdir
OUTPUT_VARIABLE NETCDFCXX_LIB_DIR
OUTPUT_STRIP_TRAILING_WHITESPACE
)
target_include_directories(ReadHDF5 PUBLIC ${netCDF_INCLUDE_DIR})
find_library(NETCDF_LIB NAMES netcdf-cxx4 netcdf_c++4 PATHS ${NETCDFCXX_LIB_DIR} NO_DEFAULT_PATH)
target_link_libraries(ReadHDF5 ${NETCDF_LIB})

View File

@ -1,100 +0,0 @@
#include <iostream>
#include <mdspan>
#include <print>
#include <stdexcept>
#include <netcdf>
using namespace std;
using namespace netCDF;
template <typename T>
void printContentsOfVec(const std::vector<T>& vec) {
for (const auto& element : vec) {
cout << element << " ";
}
cout << std::endl;
}
template <typename T>
vector<T> getVarVector(NcVar var) {
int length = 1;
for (NcDim dim : var.getDims()) {
length *= dim.getSize();
}
vector<T> vec(length);
var.getVar(vec.data());
return vec;
}
template <typename T>
using arr3d = std::mdspan<
T,
std::dextents<
std::size_t,
3
>
>;
template <typename T>
void print3DMatrixSlice(arr3d<T> arr, int t) {
for (int x = 0; x < arr.extent(1); x++) {
for (int y = 0; y < arr.extent(2); y++) {
print("{} ", arr[t,x,y]);
}
println("");
}
}
void print3DMatrixSlice(arr3d<double> arr, int t) {
for (int x = 0; x < arr.extent(1); x++) {
for (int y = 0; y < arr.extent(2); y++) {
print("{:>10.4f} ", arr[t,x,y]);
}
println("");
}
}
/**
* Read a 3D matrix from a NetCDF variable.
* Reads data into a contiguous 1D data vector.
* Returns a pair of the size of the matrix (in the form of an extent) with the data vector.
*
* Inteded usage of this function involves using the two returned values
* to create an mdspan:
*
* auto arr = mdspan(vec.data(), size);
*/
template <typename T>
pair<vector<T>, std::dextents<std::size_t, 3>> get3DMat(NcVar var) {
if(var.getDimCount() != 3) {
throw invalid_argument("Variable is not 3D");
}
int timeLength = var.getDim(0).getSize();
int latLength = var.getDim(1).getSize();
int longLength = var.getDim(2).getSize();
vector<T> vec(timeLength*latLength*longLength);
var.getVar(vec.data());
auto arr = std::mdspan(vec.data(), timeLength, latLength, longLength);
return {vec, arr.extents()};
}
int main () {
netCDF::NcFile data("../../../../data/hydrodynamic_U.h5", netCDF::NcFile::read);
multimap< string, NcVar > vars = data.getVars();
auto [vec, size] = get3DMat<double>(vars.find("uo")->second);
auto arr = std::mdspan(vec.data(), size);
print3DMatrixSlice(arr, 100);
return 0;
}