24#ifndef BLOCK_STRUCTURE_H
25#define BLOCK_STRUCTURE_H
46template <
typename T,
unsigned D>
63 static_assert(D >= 1 && D <= 3,
"Only D={1,2,3} are supported");
67 _size(size + 2*padding),
70 if constexpr (D == 3) {
72 }
else if constexpr (D == 2) {
74 }
else if constexpr (D == 1) {
77 static_assert(D >= 1 && D <= 3,
"Invalid D");
81 throw std::invalid_argument(
"Cell count must not exceed cell index space");
93 if constexpr (D == 3) {
95 }
else if constexpr (D == 2) {
97 }
else if constexpr (D == 1) {
115 static_assert(D >= 2,
"y-component only available in 2D or higher");
121 static_assert(D >= 3,
"z-component only available in 3D or higher");
139 if constexpr (D == 3) {
141 }
else if constexpr (D == 2) {
143 }
else if constexpr (D == 1) {
146 __builtin_unreachable();
156 template <
typename... L>
157 std::enable_if_t<
sizeof...(L) == D,
CellID>
165 if constexpr (D == 3) {
167 const std::int32_t remainder = iCell %
_projection[0];
168 const std::int32_t iY = remainder /
_projection[1];
169 const std::int32_t iZ = remainder %
_projection[1];
193 return latticeR >= 0 && latticeR <
_core;
199 return isInside(latticeR) && !(latticeR >= 0 && latticeR <
_core);
206 && latticeR >= -overlap
207 && latticeR <
_core+overlap;
215 template <
typename... L>
216 std::enable_if_t<
sizeof...(L) == D,
bool>
226 auto upper =
LatticeR<D>([&](
unsigned iDim) ->
int {
227 int x = lower[iDim] -
_size[iDim] + 1;
228 return x < 0 ? -x : 0;
230 auto y = std::min(*std::min_element(lower.data(), lower.data() + D),
231 *std::min_element(upper.data(), upper.data() + D));
235 template <
typename F>
240 if constexpr (D > 1) {
242 if constexpr (D == 3) {
244 if constexpr (std::is_invocable_v<F, LatticeR<D>>) {
251 if constexpr (std::is_invocable_v<F, LatticeR<D>>) {
259 if constexpr (std::is_invocable_v<F, LatticeR<D>>) {
268 template <
typename F>
272 if constexpr (D > 1) {
273 #ifdef PARALLEL_MODE_OMP
274 #pragma omp parallel for schedule(dynamic,1)
278 if constexpr (D == 3) {
280 if constexpr (std::is_invocable_v<F, LatticeR<D>>) {
287 if constexpr (std::is_invocable_v<F, LatticeR<D>>) {
296 #ifdef PARALLEL_MODE_OMP
297 #pragma omp parallel for schedule(static)
300 if constexpr (std::is_invocable_v<F, LatticeR<D>>) {
309 template <
typename F>
314 if constexpr (D > 1) {
316 if constexpr (D == 3) {
318 if constexpr (std::is_invocable_v<F, LatticeR<D>>) {
325 if constexpr (std::is_invocable_v<F, LatticeR<D>>) {
333 if constexpr (std::is_invocable_v<F, LatticeR<D>>) {
342 template <
typename F>
346 for (loc iX=0; iX <
_core[0]; ++iX) {
347 if constexpr (D > 1) {
348 for (loc iY=0; iY <
_core[1]; ++iY) {
349 if constexpr (D == 3) {
350 for (loc iZ=0; iZ <
_core[2]; ++iZ) {
351 if constexpr (std::is_invocable_v<F, LatticeR<D>>) {
358 if constexpr (std::is_invocable_v<F, LatticeR<D>>) {
366 if constexpr (std::is_invocable_v<F, LatticeR<D>>) {
375 template <
typename F>
385template <
typename DESCRIPTOR>
CellDistance getNeighborDistance(LatticeR< D > dir) const
Get 1D neighbor distance.
void forCellIndices(F f) const
std::size_t getNcells() const
Get number of cells.
bool isInsideCore(LatticeR< D > latticeR) const
Return whether location is inside core.
BlockStructureD(Vector< int, D > size, int padding=0)
bool isPadding(CellID iCell) const
int getNy() const
Read only access to block height.
void forSpatialLocations(F f) const
void forSpatialLocationsParallel(F f) const
CellDistance getNeighborhoodRadius(LatticeR< D > latticeR) const
Return maximum valid neighborhood sphere radius w.r.t. latticeR.
LatticeR< D > getLatticeR(CellID iCell) const
int getPadding() const
Read only access to padding.
void forCoreSpatialLocations(F f) const
LatticeR< D > _projection
bool isPadding(LatticeR< D > latticeR) const
Return whether location is valid.
int getNx() const
Read only access to block width.
CellID getCellId(LatticeR< D > latticeR) const
Get 1D cell ID.
int getNz() const
Read only access to block height.
bool isPadding(LatticeR< D > latticeR, int overlap) const
void forSpatialLocations(LatticeR< D > min, LatticeR< D > max, F f) const
bool isInside(LatticeR< D > latticeR) const
Return whether location is valid.
std::enable_if_t< sizeof...(L)==D, bool > isInside(L... latticeR) const
void resize(Vector< int, D > size)
std::enable_if_t< sizeof...(L)==D, CellID > getCellId(L... latticeR) const
LatticeR< D > getExtent() const
Top level namespace for all of OpenLB.
std::uint32_t CellID
Type for sequential block-local cell indices.
std::int64_t CellDistance
Type for in-memory distance of block-local cell indices.
Vector< std::int32_t, D > LatticeR
Type for spatial block-local lattice coordinates.
#define OLB_PRECONDITION(COND)
efficient implementation of a vector class