feat: modules

This commit is contained in:
robin
2024-04-21 14:20:23 +02:00
parent 4cd545c788
commit a123071fec
8 changed files with 244 additions and 0 deletions

View File

@@ -0,0 +1,36 @@
cmake_minimum_required (VERSION 3.28)
project (LinearInterpolate)
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(LinearInterpolate main.cpp
readdata.cpp
readdata.h
vecutils.cpp
vecutils.h)
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(LinearInterpolate PUBLIC ${netCDF_INCLUDE_DIR})
find_library(NETCDF_LIB NAMES netcdf-cxx4 netcdf_c++4 PATHS ${NETCDFCXX_LIB_DIR} NO_DEFAULT_PATH)
target_link_libraries(LinearInterpolate ${NETCDF_LIB})

View File

@@ -0,0 +1,18 @@
#include "readdata.h"
#include <vector>
using namespace std;
int main() {
auto [vec, size] = readHydrodynamicU();
auto arr = std::mdspan(vec.data(), size);
print3DMatrixSlice(arr, 100);
auto [times, lats, longs] = readGrid();
printContentsOfVec(lats);
return 0;
}

View File

@@ -0,0 +1,66 @@
#include <print>
#include <stdexcept>
#include <netcdf>
#include "readdata.h"
using namespace std;
using namespace netCDF;
template <typename T>
vector<T> getVarVector(const NcVar &var) {
int length = 1;
for (NcDim dim : var.getDims()) {
length *= dim.getSize();
}
vector<T> vec(length);
var.getVar(vec.data());
return vec;
}
/**
* 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(const 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()};
}
pair<vector<double>, std::dextents<std::size_t, 3>> readHydrodynamicU() {
netCDF::NcFile data("../../../../data/hydrodynamic_U.h5", netCDF::NcFile::read);
multimap< string, NcVar > vars = data.getVars();
return get3DMat<double>(vars.find("uo")->second);
}
tuple<vector<double>, vector<double>, vector<double>> readGrid() {
netCDF::NcFile data("../../../../data/grid.h5", netCDF::NcFile::read);
multimap< string, NcVar > vars = data.getVars();
vector<double> time = getVarVector<double>(vars.find("times")->second);
vector<double> longitude = getVarVector<double>(vars.find("longitude")->second);
vector<double> latitude = getVarVector<double>(vars.find("latitude")->second);
return {time, latitude, longitude};
}

View File

@@ -0,0 +1,18 @@
#ifndef LINEARINTERPOLATE_READDATA_H
#define LINEARINTERPOLATE_READDATA_H
#include "vecutils.h"
/**
* Reads the file hydrodynamic_U.h5
* @return a pair of the data vector of the contents and its dimensions to be used with mdspan
*/
std::pair<std::vector<double>, std::dextents<std::size_t, 3>> readHydrodynamicU();
/**
* Reads the file grid.h5
* @return a tuple of (times, latitude, longitude)
*/
std::tuple<std::vector<double>, std::vector<double>, std::vector<double>> readGrid();
#endif //LINEARINTERPOLATE_READDATA_H

View File

@@ -0,0 +1,14 @@
#include <print>
#include "vecutils.h"
using namespace std;
void print3DMatrixSlice(const 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("");
}
}

View File

@@ -0,0 +1,47 @@
#ifndef LINEARINTERPOLATE_VECUTILS_H
#define LINEARINTERPOLATE_VECUTILS_H
#include <mdspan>
#include <print>
template <typename T>
using arr3d = std::mdspan<
T,
std::dextents<
std::size_t,
3
>
>;
/**
* Print contents of vector
* @tparam T The type of the data inside the vector
* @param vec The vector to be printed
*/
template <typename T>
void printContentsOfVec(const std::vector<T>& vec) {
for (const auto& element : vec) {
std::print("{} ", element);
}
std::println("");
}
/**
* Print matrix [x,y] for all values arr[t,x,y]
* @param arr matrix to be printed
* @param t value to slice matrix with
*/
template <typename T>
void print3DMatrixSlice(const arr3d<T> &arr, int t) {
for (int x = 0; x < arr.extent(1); x++) {
for (int y = 0; y < arr.extent(2); y++) {
std::print("{} ", arr[t,x,y]);
}
std::println("");
}
}
void print3DMatrixSlice(const arr3d<double> &arr, int t);
#endif //LINEARINTERPOLATE_VECUTILS_H