24#ifndef BLOCK_STRUCTURE_H
25#define BLOCK_STRUCTURE_H
46template <
typename T,
unsigned D>
63 static_assert(D == 2 || D == 3,
"Only D=2 and D=3 are supported");
67 _size(size + 2*padding),
70 if constexpr (D == 3) {
76 if (
getNcells()-1 > std::numeric_limits<CellID>::max()) {
77 throw std::invalid_argument(
"Cell count must not exceed cell index space");
98 static_assert(D == 3,
"z-component only available in 3D");
116 if constexpr (D == 3) {
121 __builtin_unreachable();
131 template <
typename... L>
132 std::enable_if_t<
sizeof...(L) == D,
CellID>
153 return latticeR >= 0 && latticeR <
_core;
159 return isInside(latticeR) && !(latticeR >= 0 && latticeR <
_core);
162 template <
typename... L>
163 std::enable_if_t<
sizeof...(L) == D,
bool>
173 auto upper =
LatticeR<D>([&](
unsigned iDim) ->
int {
174 int x = lower[iDim] -
_size[iDim] + 1;
175 return x < 0 ? -x : 0;
177 auto y = std::min(*std::min_element(lower.data(), lower.data() + D),
178 *std::min_element(upper.data(), upper.data() + D));
182 template <
typename F>
188 if constexpr (D == 3) {
190 if constexpr (std::is_invocable_v<F, LatticeR<D>>) {
197 if constexpr (std::is_invocable_v<F, LatticeR<D>>) {
207 template <
typename F>
211 #ifdef PARALLEL_MODE_OMP
212 #pragma omp parallel for schedule(dynamic,1)
216 if constexpr (D == 3) {
218 if constexpr (std::is_invocable_v<F, LatticeR<D>>) {
225 if constexpr (std::is_invocable_v<F, LatticeR<D>>) {
235 template <
typename F>
241 if constexpr (D == 3) {
243 if constexpr (std::is_invocable_v<F, LatticeR<D>>) {
250 if constexpr (std::is_invocable_v<F, LatticeR<D>>) {
260 template <
typename F>
264 for (loc iX=0; iX <
_core[0]; ++iX) {
265 for (loc iY=0; iY <
_core[1]; ++iY) {
266 if constexpr (D == 3) {
267 for (loc iZ=0; iZ <
_core[2]; ++iZ) {
268 if constexpr (std::is_invocable_v<F, LatticeR<D>>) {
275 if constexpr (std::is_invocable_v<F, LatticeR<D>>) {
285 template <
typename F>
295template <
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)
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.
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.
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
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.
#define OLB_PRECONDITION(COND)
efficient implementation of a vector class