connected kind of
This commit is contained in:
1 parent
d7201962a5
commit
1643157fe8
21 files changed
+100
-139
No files matched your search
@@ -1,42 +0,0 @@
|
|||||||
cmake_minimum_required (VERSION 3.28)
|
|
||||||
project (Advection)
|
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 23)
|
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
|
||||||
|
|
||||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
|
||||||
|
|
||||||
find_package(netCDF REQUIRED)
|
|
||||||
|
|
||||||
add_executable(Advection main.cpp
|
|
||||||
readdata.cpp
|
|
||||||
readdata.h
|
|
||||||
interpolate.cpp
|
|
||||||
interpolate.h
|
|
||||||
UVGrid.cpp
|
|
||||||
UVGrid.h
|
|
||||||
Vel.h
|
|
||||||
Vel.cpp
|
|
||||||
AdvectionKernel.h
|
|
||||||
EulerAdvectionKernel.cpp
|
|
||||||
EulerAdvectionKernel.h
|
|
||||||
RK4AdvectionKernel.cpp
|
|
||||||
RK4AdvectionKernel.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(Advection PUBLIC ${netCDF_INCLUDE_DIR})
|
|
||||||
|
|
||||||
find_library(NETCDF_LIB NAMES netcdf-cxx4 netcdf_c++4 PATHS ${NETCDFCXX_LIB_DIR} NO_DEFAULT_PATH)
|
|
||||||
target_link_libraries(Advection ${NETCDF_LIB})
|
|
||||||
@@ -1,66 +0,0 @@
|
|||||||
#include <ranges>
|
|
||||||
|
|
||||||
#include "UVGrid.h"
|
|
||||||
#include "readdata.h"
|
|
||||||
|
|
||||||
#define sizeError2 "The sizes of the hydrodynamic data files are different"
|
|
||||||
#define sizeError "The sizes of the hydrodynamicU or -V files does not correspond with the sizes of the grid file"
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
UVGrid::UVGrid() {
|
|
||||||
auto us = readHydrodynamicU();
|
|
||||||
auto vs = readHydrodynamicV();
|
|
||||||
if (us.size() != vs.size()) {
|
|
||||||
throw domain_error(sizeError2);
|
|
||||||
}
|
|
||||||
|
|
||||||
tie(times, lats, lons) = readGrid();
|
|
||||||
|
|
||||||
timeSize = times.size();
|
|
||||||
latSize = lats.size();
|
|
||||||
lonSize = lons.size();
|
|
||||||
|
|
||||||
size_t gridSize = timeSize * latSize * lonSize;
|
|
||||||
if (gridSize != us.size()) {
|
|
||||||
throw domain_error(sizeError);
|
|
||||||
}
|
|
||||||
|
|
||||||
uvData.reserve(gridSize);
|
|
||||||
|
|
||||||
for (auto vel: views::zip(us, vs)) {
|
|
||||||
uvData.push_back(Vel(vel));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const Vel &UVGrid::operator[](size_t timeIndex, size_t latIndex, size_t lonIndex) const {
|
|
||||||
if(timeIndex < 0 or timeIndex >= timeSize
|
|
||||||
or latIndex < 0 or latIndex >= latSize
|
|
||||||
or lonIndex < 0 or lonIndex >= lonSize) {
|
|
||||||
throw std::out_of_range("Index out of bounds");
|
|
||||||
}
|
|
||||||
size_t index = timeIndex * (latSize * lonSize) + latIndex * lonSize + lonIndex;
|
|
||||||
return uvData[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
double UVGrid::lonStep() const {
|
|
||||||
return lons[1] - lons[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
double UVGrid::latStep() const {
|
|
||||||
return lats[1] - lats[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
int UVGrid::timeStep() const {
|
|
||||||
return times[1] - times[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
void UVGrid::streamSlice(ostream &os, size_t t) {
|
|
||||||
for (int x = 0; x < latSize; x++) {
|
|
||||||
for (int y = 0; y < lonSize; y++) {
|
|
||||||
auto vel = (*this)[t,x,y];
|
|
||||||
os << vel << " ";
|
|
||||||
}
|
|
||||||
os << endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -2,6 +2,9 @@ cmake_minimum_required(VERSION 3.12 FATAL_ERROR)
|
|||||||
|
|
||||||
project(VtkBase)
|
project(VtkBase)
|
||||||
|
|
||||||
|
set(CMAKE_CXX_STANDARD 23)
|
||||||
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
|
||||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||||
|
|
||||||
find_package(VTK COMPONENTS
|
find_package(VTK COMPONENTS
|
||||||
@@ -47,6 +50,19 @@ add_executable(VtkBase MACOSX_BUNDLE main.cpp
|
|||||||
commands/SpawnPointCallback.h
|
commands/SpawnPointCallback.h
|
||||||
commands/SpawnPointCallback.cpp
|
commands/SpawnPointCallback.cpp
|
||||||
CartographicTransformation.cpp
|
CartographicTransformation.cpp
|
||||||
|
advection/AdvectionKernel.h
|
||||||
|
advection/EulerAdvectionKernel.cpp
|
||||||
|
advection/EulerAdvectionKernel.h
|
||||||
|
advection/interpolate.cpp
|
||||||
|
advection/interpolate.h
|
||||||
|
advection/readdata.cpp
|
||||||
|
advection/readdata.h
|
||||||
|
advection/RK4AdvectionKernel.cpp
|
||||||
|
advection/RK4AdvectionKernel.h
|
||||||
|
advection/UVGrid.cpp
|
||||||
|
advection/UVGrid.h
|
||||||
|
advection/Vel.cpp
|
||||||
|
advection/Vel.h
|
||||||
)
|
)
|
||||||
|
|
||||||
execute_process(
|
execute_process(
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
*/
|
*/
|
||||||
class AdvectionKernel {
|
class AdvectionKernel {
|
||||||
public:
|
public:
|
||||||
const static int DT = 60 * 15; // 60 sec/min * 15 mins
|
const static int DT = 15 * 60 * 15; // 60 sec/min * 15 mins
|
||||||
/**
|
/**
|
||||||
* This function must take a time, latitude and longitude of a particle and must output
|
* This function must take a time, latitude and longitude of a particle and must output
|
||||||
* a new latitude and longitude after being advected once for AdvectionKernel::DT time as defined above.
|
* a new latitude and longitude after being advected once for AdvectionKernel::DT time as defined above.
|
||||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,67 @@
|
|||||||
|
#include <ranges>
|
||||||
|
|
||||||
|
#include "UVGrid.h"
|
||||||
|
#include "readdata.h"
|
||||||
|
|
||||||
|
#define sizeError2 "The sizes of the hydrodynamic data files are different"
|
||||||
|
#define sizeError "The sizes of the hydrodynamicU or -V files does not correspond with the sizes of the grid file"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
UVGrid::UVGrid() {
|
||||||
|
auto us = readHydrodynamicU();
|
||||||
|
auto vs = readHydrodynamicV();
|
||||||
|
if (us.size() != vs.size()) {
|
||||||
|
throw domain_error(sizeError2);
|
||||||
|
}
|
||||||
|
|
||||||
|
tie(times, lats, lons) = readGrid();
|
||||||
|
|
||||||
|
timeSize = times.size();
|
||||||
|
latSize = lats.size();
|
||||||
|
lonSize = lons.size();
|
||||||
|
|
||||||
|
size_t gridSize = timeSize * latSize * lonSize;
|
||||||
|
if (gridSize != us.size()) {
|
||||||
|
throw domain_error(sizeError);
|
||||||
|
}
|
||||||
|
|
||||||
|
uvData.reserve(gridSize);
|
||||||
|
|
||||||
|
for (auto vel: views::zip(us, vs)) {
|
||||||
|
uvData.push_back(Vel(vel));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const Vel &UVGrid::operator[](size_t timeIndex, size_t latIndex, size_t lonIndex) const {
|
||||||
|
cout << "t=" << timeIndex << "latIndex=" << latIndex << "lonIndex=" << lonIndex << endl;
|
||||||
|
if (timeIndex < 0 or timeIndex >= timeSize
|
||||||
|
or latIndex < 0 or latIndex >= latSize
|
||||||
|
or lonIndex < 0 or lonIndex >= lonSize) {
|
||||||
|
throw std::out_of_range("Index out of bounds");
|
||||||
|
}
|
||||||
|
size_t index = timeIndex * (latSize * lonSize) + latIndex * lonSize + lonIndex;
|
||||||
|
return uvData[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
double UVGrid::lonStep() const {
|
||||||
|
return lons[1] - lons[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
double UVGrid::latStep() const {
|
||||||
|
return lats[1] - lats[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
int UVGrid::timeStep() const {
|
||||||
|
return times[1] - times[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
void UVGrid::streamSlice(ostream &os, size_t t) {
|
||||||
|
for (int x = 0; x < latSize; x++) {
|
||||||
|
for (int y = 0; y < lonSize; y++) {
|
||||||
|
auto vel = (*this)[t, x, y];
|
||||||
|
os << vel << " ";
|
||||||
|
}
|
||||||
|
os << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -11,36 +11,12 @@
|
|||||||
#include <vtkProperty.h>
|
#include <vtkProperty.h>
|
||||||
#include <vtkProperty2D.h>
|
#include <vtkProperty2D.h>
|
||||||
#include <vtkVertexGlyphFilter.h>
|
#include <vtkVertexGlyphFilter.h>
|
||||||
#include <netcdf>
|
|
||||||
#include <vtkArrowSource.h>
|
#include <vtkArrowSource.h>
|
||||||
#include "../CartographicTransformation.h"
|
#include "../CartographicTransformation.h"
|
||||||
|
#include "../advection/readdata.h"
|
||||||
|
|
||||||
using namespace netCDF;
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
tuple<vector<int>, vector<double>, vector<double>> readGrid() {
|
|
||||||
netCDF::NcFile data("../../../../data/grid.h5", netCDF::NcFile::read);
|
|
||||||
multimap< string, NcVar > vars = data.getVars();
|
|
||||||
vector<int> time = getVarVector<int>(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};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
EGlyphLayer::EGlyphLayer() {
|
EGlyphLayer::EGlyphLayer() {
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ vtkSmartPointer<SpawnPointCallback> LGlyphLayer::createSpawnPointCallback() {
|
|||||||
//
|
//
|
||||||
// TODO: modelling all this in vtkClasses is workable, but ideally i would want to work with a native C++ class. See if this is doable and feasible.
|
// TODO: modelling all this in vtkClasses is workable, but ideally i would want to work with a native C++ class. See if this is doable and feasible.
|
||||||
|
|
||||||
LGlyphLayer::LGlyphLayer() {
|
LGlyphLayer::LGlyphLayer(std::unique_ptr<AdvectionKernel> advectionKernel) {
|
||||||
this->ren = vtkSmartPointer<vtkRenderer>::New();
|
this->ren = vtkSmartPointer<vtkRenderer>::New();
|
||||||
this->ren->SetLayer(2);
|
this->ren->SetLayer(2);
|
||||||
|
|
||||||
@@ -39,6 +39,8 @@ LGlyphLayer::LGlyphLayer() {
|
|||||||
this->data = vtkSmartPointer<vtkPolyData>::New();
|
this->data = vtkSmartPointer<vtkPolyData>::New();
|
||||||
this->data->SetPoints(this->points);
|
this->data->SetPoints(this->points);
|
||||||
|
|
||||||
|
advector = std::move(advectionKernel);
|
||||||
|
|
||||||
auto camera = createNormalisedCamera();
|
auto camera = createNormalisedCamera();
|
||||||
ren->SetActiveCamera(camera);
|
ren->SetActiveCamera(camera);
|
||||||
|
|
||||||
@@ -88,7 +90,7 @@ void LGlyphLayer::updateData(int t) {
|
|||||||
double point[3];
|
double point[3];
|
||||||
for (vtkIdType n = 0; n < this->points->GetNumberOfPoints(); n++) {
|
for (vtkIdType n = 0; n < this->points->GetNumberOfPoints(); n++) {
|
||||||
this->points->GetPoint(n, point);
|
this->points->GetPoint(n, point);
|
||||||
auto [xNew, yNew] = advect(n, point[0], point[1]);
|
auto [yNew, xNew] = advector->advect(t, point[1], point[0]);
|
||||||
this->points->SetPoint(n, xNew, yNew, 0);
|
this->points->SetPoint(n, xNew, yNew, 0);
|
||||||
}
|
}
|
||||||
this->points->Modified();
|
this->points->Modified();
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
#define LGLYPHLAYER_H
|
#define LGLYPHLAYER_H
|
||||||
|
|
||||||
#include "Layer.h"
|
#include "Layer.h"
|
||||||
|
#include "../advection/AdvectionKernel.h"
|
||||||
#include "../commands/SpawnPointCallback.h"
|
#include "../commands/SpawnPointCallback.h"
|
||||||
#include <vtkPolyData.h>
|
#include <vtkPolyData.h>
|
||||||
#include <vtkInteractorStyle.h>
|
#include <vtkInteractorStyle.h>
|
||||||
@@ -13,13 +14,14 @@ class LGlyphLayer : public Layer {
|
|||||||
private:
|
private:
|
||||||
vtkSmartPointer<vtkPoints> points;
|
vtkSmartPointer<vtkPoints> points;
|
||||||
vtkSmartPointer<vtkPolyData> data;
|
vtkSmartPointer<vtkPolyData> data;
|
||||||
|
std::unique_ptr<AdvectionKernel> advector;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/** Constructor.
|
/** Constructor.
|
||||||
*/
|
*/
|
||||||
LGlyphLayer();
|
LGlyphLayer(std::unique_ptr<AdvectionKernel> advectionKernel);
|
||||||
|
|
||||||
/** This function spoofs a few points in the dataset. Mostly used for testing.
|
/** This function spoofs a few points in the dataset. Mostly used for testing.
|
||||||
*/
|
*/
|
||||||
|
|||||||
+8
-2
@@ -7,18 +7,24 @@
|
|||||||
#include <vtkProperty2D.h>
|
#include <vtkProperty2D.h>
|
||||||
#include <vtkRenderer.h>
|
#include <vtkRenderer.h>
|
||||||
#include <vtkVertexGlyphFilter.h>
|
#include <vtkVertexGlyphFilter.h>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
#include "layers/BackgroundImage.h"
|
#include "layers/BackgroundImage.h"
|
||||||
#include "layers/EGlyphLayer.h"
|
#include "layers/EGlyphLayer.h"
|
||||||
#include "layers/LGlyphLayer.h"
|
#include "layers/LGlyphLayer.h"
|
||||||
#include "Program.h"
|
#include "Program.h"
|
||||||
|
#include "advection/UVGrid.h"
|
||||||
|
#include "advection/RK4AdvectionKernel.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
auto l = new LGlyphLayer();
|
shared_ptr<UVGrid> uvGrid = std::make_shared<UVGrid>();
|
||||||
l->spoofPoints();
|
auto kernelRK4 = make_unique<RK4AdvectionKernel>(uvGrid);
|
||||||
|
|
||||||
|
auto l = new LGlyphLayer(move(kernelRK4));
|
||||||
|
// l->spoofPoints();
|
||||||
|
|
||||||
Program *program = new Program();
|
Program *program = new Program();
|
||||||
program->addLayer(new BackgroundImage("../../../../data/map_661-661.png"));
|
program->addLayer(new BackgroundImage("../../../../data/map_661-661.png"));
|
||||||
|
|||||||