Back

Grid Generation

Overview

The grid module provides structured grid classes for 2D and 3D domains. Grids are defined by an origin, spacing, and number of divisions along each axis. They support per-point attributes and provide efficient index conversion between grid coordinates and linear indices. The from_dims utility generates a Serie of point positions from grid dimensions.

Grid2D

Grid2D Class

class Grid2D {
public:
    // Constructor
    Grid2D(const Vector<2> &origin,
           const Vector<2> &spacing,
           const std::array<size_t, 2> &dimensions);

    // Grid properties
    const Vector<2> &origin() const;
    const Vector<2> &spacing() const;
    const std::array<size_t, 2> &dimensions() const;
    size_t total_points() const;  // nx * ny

    // Point access
    Vector<2> point_at(size_t i, size_t j) const;
    Vector<2> point_at(size_t linear_index) const;

    // Index conversion
    size_t linear_index(size_t i, size_t j) const;
    std::array<size_t, 2> grid_indices(size_t linear_index) const;

    // Attributes
    Dataframe &attributes();
    const Dataframe &attributes() const;
};
Grid2D Example

// Create a 10x10 grid starting at origin (0,0) with spacing 0.1
df::Grid2D grid({0.0, 0.0}, {0.1, 0.1}, {10, 10});

std::cout << "Total points: " << grid.total_points() << std::endl;  // 100

// Access a specific grid point
auto pt = grid.point_at(5, 3);  // {0.5, 0.3}

// Convert between linear and grid indices
size_t idx = grid.linear_index(5, 3);       // 35
auto [i, j] = grid.grid_indices(35);        // {5, 3}

// Iterate over all grid points
for (size_t idx = 0; idx < grid.total_points(); ++idx) {
    auto p = grid.point_at(idx);
    // process point p...
}

Grid3D

Grid3D Class

class Grid3D {
public:
    // Constructor
    Grid3D(const Vector<3> &origin,
           const Vector<3> &spacing,
           const std::array<size_t, 3> &dimensions);

    // Grid properties
    const Vector<3> &origin() const;
    const Vector<3> &spacing() const;
    const std::array<size_t, 3> &dimensions() const;
    size_t total_points() const;  // nx * ny * nz

    // Point access
    Vector<3> point_at(size_t i, size_t j, size_t k) const;
    Vector<3> point_at(size_t linear_index) const;

    // Index conversion
    size_t linear_index(size_t i, size_t j, size_t k) const;
    std::array<size_t, 3> grid_indices(size_t linear_index) const;

    // Attributes
    Dataframe &attributes();
    const Dataframe &attributes() const;
};
Grid3D Example

// Create a 20x20x10 grid for a 3D domain
df::Grid3D grid(
    {-1.0, -1.0, 0.0},      // origin
    {0.1, 0.1, 0.1},         // spacing
    {20, 20, 10}              // dimensions
);

std::cout << "Total points: " << grid.total_points() << std::endl;  // 4000

auto pt = grid.point_at(10, 10, 5);  // {0.0, 0.0, 0.5}
auto [i, j, k] = grid.grid_indices(grid.linear_index(10, 10, 5));

from_dims

from_dims - Generate Grid Points from Dimensions

namespace df::grid::cartesian {

// Generate a Serie of N-dimensional points on a regular grid
// centered at `center` with total extent `dimensions`
template <size_t N>
Serie<Vector<N>> from_dims(
    const std::array<size_t, N> &npts,        // Number of points per axis
    const Vector<N>             &center,      // Center of the grid
    const Vector<N>             &dimensions   // Total extent per axis
);

} // namespace df::grid::cartesian
from_dims Example

// Generate a 50x50 grid of 2D points centered at (5, 5) spanning 10x10
auto points2d = df::grid::cartesian::from_dims<2>(
    {50, 50},         // 50 points in x and y
    {5.0, 5.0},       // center
    {10.0, 10.0}      // total extent: x in [0, 10], y in [0, 10]
);

std::cout << "Generated " << points2d.size() << " points" << std::endl;  // 2500

// Generate a 3D grid
auto points3d = df::grid::cartesian::from_dims<3>(
    {20, 20, 10},
    {0.0, 0.0, -5.0},
    {100.0, 100.0, 50.0}
);

// Use as interpolation targets
auto interp_values = df::geo::idw<double, 2>(
    source_pts, source_vals, points2d
);

Complete Example

Grid with Interpolation Example

#include <dataframe/Serie.h>
#include <dataframe/geo/grid/grid2d.h>
#include <dataframe/geo/grid/from_dims.h>
#include <dataframe/geo/interpolation/idw.h>
#include <iostream>

int main() {
    // Scattered observation points
    df::Serie<Vector<2>> obs_pts{
        {1.0, 1.0}, {3.0, 2.0}, {7.0, 8.0},
        {9.0, 1.0}, {5.0, 5.0}
    };
    df::Serie<double> obs_vals{10.0, 25.0, 18.0, 30.0, 22.0};

    // Create a regular grid for interpolation
    auto grid_pts = df::grid::cartesian::from_dims<2>(
        {50, 50}, {5.0, 5.0}, {10.0, 10.0}
    );

    // Interpolate to grid
    auto grid_vals = df::geo::idw<double, 2>(obs_pts, obs_vals, grid_pts);

    // Also usable via the Grid2D class
    df::Grid2D grid({0.0, 0.0}, {0.2, 0.2}, {50, 50});

    std::cout << "Grid total: " << grid.total_points() << " points\n";
    std::cout << "Interpolated " << grid_vals.size() << " values\n";

    return 0;
}