include/pops/mesh/layout/box_array.hpp Source FileΒΆ

adc_cpp: include/pops/mesh/layout/box_array.hpp Source File
adc_cpp 0.3.0
Model-free C++23 core for coupled hyperbolic-elliptic systems on adaptive (AMR) meshes, with MPI and GPU (Kokkos) backends
box_array.hpp
Go to the documentation of this file.
1
8
9#pragma once
10
12
13#include <cstdint>
14#include <utility>
15#include <vector>
16
17namespace pops {
18
22class BoxArray {
23 public:
24 BoxArray() = default;
26 explicit BoxArray(std::vector<Box2D> boxes) : boxes_(std::move(boxes)) {}
27
30 static BoxArray from_domain(const Box2D& domain, int max_grid_size) {
31 auto sx = split_range(domain.lo[0], domain.hi[0], max_grid_size);
32 auto sy = split_range(domain.lo[1], domain.hi[1], max_grid_size);
33 std::vector<Box2D> boxes;
34 boxes.reserve(sx.size() * sy.size());
35 for (auto [ylo, yhi] : sy)
36 for (auto [xlo, xhi] : sx)
37 boxes.push_back(Box2D{{xlo, ylo}, {xhi, yhi}});
38 return BoxArray{std::move(boxes)};
39 }
40
42 int size() const { return static_cast<int>(boxes_.size()); }
44 const Box2D& operator[](int i) const { return boxes_[i]; }
46 const std::vector<Box2D>& boxes() const { return boxes_; }
47
49 std::int64_t num_cells() const {
50 std::int64_t n = 0;
51 for (const auto& b : boxes_)
52 n += b.num_cells();
53 return n;
54 }
55
58 if (boxes_.empty())
59 return Box2D{};
60 Box2D b = boxes_[0];
61 for (const auto& o : boxes_) {
62 b.lo[0] = std::min(b.lo[0], o.lo[0]);
63 b.lo[1] = std::min(b.lo[1], o.lo[1]);
64 b.hi[0] = std::max(b.hi[0], o.hi[0]);
65 b.hi[1] = std::max(b.hi[1], o.hi[1]);
66 }
67 return b;
68 }
69
70 private:
71 // Split [lo, hi] into segments of length <= m, distributed evenly:
72 // n = ceil(len/m) segments, the first `rem` of them one notch longer.
73 static std::vector<std::pair<int, int>> split_range(int lo, int hi, int m) {
74 std::vector<std::pair<int, int>> segs;
75 int len = hi - lo + 1;
76 if (len <= 0 || m <= 0)
77 return segs;
78 int n = (len + m - 1) / m;
79 int base = len / n, rem = len % n;
80 int cur = lo;
81 for (int k = 0; k < n; ++k) {
82 int l = base + (k < rem ? 1 : 0);
83 segs.push_back({cur, cur + l - 1});
84 cur += l;
85 }
86 return segs;
87 }
88
89 std::vector<Box2D> boxes_{};
90};
91
92} // namespace pops
Box2D: the integer index space of a 2D cell-centered Cartesian grid.
Ordered list of boxes tiling a level.
Definition box_array.hpp:22
const Box2D & operator[](int i) const
Box at global index i (0 <= i < size()); the index is the box identity throughout the code.
Definition box_array.hpp:44
BoxArray(std::vector< Box2D > boxes)
Build from an already-computed list of boxes (move). The order is kept as is.
Definition box_array.hpp:26
std::int64_t num_cells() const
Total number of valid cells (sum of num_cells over all boxes).
Definition box_array.hpp:49
int size() const
Number of boxes in the tiling.
Definition box_array.hpp:42
Box2D bounding_box() const
Smallest box enclosing all boxes (empty box if the tiling is empty).
Definition box_array.hpp:57
const std::vector< Box2D > & boxes() const
View on the underlying vector (element-by-element equality = same boxes AND same order).
Definition box_array.hpp:46
BoxArray()=default
static BoxArray from_domain(const Box2D &domain, int max_grid_size)
Tile the domain into tiles of at most max_grid_size per direction, distributed evenly.
Definition box_array.hpp:30
Definition amr_hierarchy.hpp:29
2D integer index space, cell-centered.
Definition box2d.hpp:37
int hi[2]
Definition box2d.hpp:39
int lo[2]
Definition box2d.hpp:38