diff --git a/advection/src/AdvectionKernel.h b/advection/src/AdvectionKernel.h index dc6bd9f..87208bf 100644 --- a/advection/src/AdvectionKernel.h +++ b/advection/src/AdvectionKernel.h @@ -7,8 +7,19 @@ #define DT 50 +/* + * Implement this class for every integration method. + */ class AdvectionKernel { public: + /** + * 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 DT time as defined above. + * @param time Time since the beginning of the data + * @param latitude Latitude of particle + * @param longitude Longitude of particle + * @return A pair of latitude and longitude of particle. + */ virtual std::pair advect(int time, double latitude, double longitude) const = 0; }; diff --git a/advection/src/EulerAdvectionKernel.h b/advection/src/EulerAdvectionKernel.h index f8570f0..e98297f 100644 --- a/advection/src/EulerAdvectionKernel.h +++ b/advection/src/EulerAdvectionKernel.h @@ -4,6 +4,14 @@ #include "AdvectionKernel.h" #include "UVGrid.h" +/** + * Implementation of AdvectionKernel. + * The basic equation is: + * new_latitude = latitude + u*DT + * new_longitude = longitude + v*DT + * + * Uses bilinear interpolation as implemented in interpolate.h + */ class EulerAdvectionKernel: public AdvectionKernel { private: std::shared_ptr grid; diff --git a/advection/src/RK4AdvectionKernel.h b/advection/src/RK4AdvectionKernel.h index 617dbfc..6719030 100644 --- a/advection/src/RK4AdvectionKernel.h +++ b/advection/src/RK4AdvectionKernel.h @@ -5,6 +5,11 @@ #include "AdvectionKernel.h" #include "UVGrid.h" +/** + * Implementation of Advection kernel using RK4 integration + * See https://en.wikipedia.org/wiki/Runge%E2%80%93Kutta_methods for more details. + * Uses bilinear interpolation as implemented in interpolate.h + */ class RK4AdvectionKernel: public AdvectionKernel { private: std::shared_ptr grid; diff --git a/advection/src/UVGrid.h b/advection/src/UVGrid.h index 229f5ca..691d0df 100644 --- a/advection/src/UVGrid.h +++ b/advection/src/UVGrid.h @@ -13,6 +13,9 @@ private: public: UVGrid(); + /** + * The matrix has shape (timeSize, latSize, lonSize) + */ size_t timeSize; size_t latSize; size_t lonSize; @@ -35,6 +38,12 @@ public: */ int timeStep() const; + /** + * times, lats, lons are vector of length timeSize, latSize, lonSize respectively. + * The maintain the following invariant: + * grid[timeIndex,latIndex,lonIndex] gives the u,v at the point with latitude at lats[latIndex], + * with longitude at lons[lonIndex], and with time at times[timeIndex]. + */ std::vector times; std::vector lats; std::vector lons; @@ -45,6 +54,11 @@ public: */ const Vel& operator[](size_t timeIndex, size_t latIndex, size_t lonIndex) const; + /** + * Streams a slice at timeIndex t of the matrix to the outstream given by os + * @param os outstream + * @param t index with which to slice matrix + */ void streamSlice(std::ostream &os, size_t t); }; diff --git a/advection/src/main.cpp b/advection/src/main.cpp index f7e2e52..7331def 100644 --- a/advection/src/main.cpp +++ b/advection/src/main.cpp @@ -11,7 +11,10 @@ using namespace std; template void advectForSomeTime(const UVGrid &uvGrid, const AdvectionKernelImpl &kernel, double latstart, double lonstart) { + + // Require at compile time that kernel derives from the abstract class AdvectionKernel static_assert(std::is_base_of::value, NotAKernelError); + double lat1 = latstart, lon1 = lonstart; for(int time = 100; time <= 10000; time += DT) { cout << "lat = " << lat1 << " lon = " << lon1 << endl; @@ -24,7 +27,6 @@ void advectForSomeTime(const UVGrid &uvGrid, const AdvectionKernelImpl &kernel, int main() { std::shared_ptr uvGrid = std::make_shared(); -// uvGrid->streamSlice(cout, 100); EulerAdvectionKernel kernelEuler = EulerAdvectionKernel(uvGrid);