51template<
typename T> T
norm(
const std::vector<T>& a);
56 return (0 < val) - (val < 0);
62 return (vec[0]!=0 and vec[1]==0 and vec[2]==0);
68 return (vec[0]==0 and vec[1]!=0 and vec[2]==0);
74 return (vec[0]==0 and vec[1]==0 and vec[2]!=0);
80 return (aligned_to_x<T>(vec) or
81 aligned_to_y<T>(vec) or
82 aligned_to_z<T>(vec));
90 int x0,
int x1,
int y0,
int y1,
91 int x0_,
int x1_,
int y0_,
int y1_,
92 int& newX0,
int& newX1,
int& newY0,
int& newY1 )
100 return newX1>=newX0 && newY1>=newY0;
104 int x0,
int x1,
int y0,
int y1,
int z0,
int z1,
105 int x0_,
int x1_,
int y0_,
int y1_,
int z0_,
int z1_,
106 int& newX0,
int& newX1,
int& newY0,
int& newY1,
int& newZ0,
int& newZ1 )
116 return newX1>=newX0 && newY1>=newY0 && newZ1>=newZ0;
120 int x0,
int x1,
int y0,
int y1)
122 return x>=x0 && x<=x1 &&
127 int x0,
int x1,
int y0,
int y1,
int z0,
int z1)
129 return x>=x0 && x<=x1 &&
142template<
typename ARRAY_LIKE,
unsigned D>
145 auto uSqr =
decltype(u[0]){};
146 for (
unsigned iD=0; iD < D; ++iD) {
152template<
unsigned D,
typename ARRAY_LIKE>
155 return sqrt(normSqr<ARRAY_LIKE,D>(u));
158template<
typename T,
unsigned D>
162 for (
unsigned iD=0; iD < D; ++iD) {
171 return std::inner_product(data.begin(), data.end(), data.begin(), T(0));
176template<
typename T,
unsigned D,
typename IMPL>
180 for (
unsigned iD=0; iD < D; ++iD) {
186template<
typename T,
int d>
190 for (
int iD=0; iD<d; ++iD) {
191 prod += u1[iD]*u2[iD];
200 if (u1.size() == u2.size()) {
201 for (
int iD=0; iD<u1.size(); ++iD) {
202 prod += u1[iD]*u2[iD];
209template <
typename DESCRIPTORBASE>
211 static constexpr int n = (DESCRIPTORBASE::d*(DESCRIPTORBASE::d+1))/2;
215template <
typename DESCRIPTOR,
unsigned iVel,
int value>
217 constexpr auto velocity_matches_value = [](
unsigned iPop) ->
bool {
218 return descriptors::c<DESCRIPTOR>(iPop,iVel) == value;
221 descriptors::filter_population_indices<DESCRIPTOR>(velocity_matches_value));
225template <
typename DESCRIPTOR,
int... NORMAL>
227 constexpr auto velocity_matches_direction = [](
unsigned iPop) ->
bool {
229 return x != 0 && x == descriptors::c<DESCRIPTOR>(iPop,iD);
233 descriptors::filter_population_indices<DESCRIPTOR>(velocity_matches_direction));
236template <
typename DESCRIPTORBASE>
239 for (
int iPop=0; iPop<DESCRIPTORBASE::q; ++iPop) {
241 for (
int iD=0; iD<DESCRIPTORBASE::d; ++iD) {
242 if (descriptors::c<DESCRIPTORBASE>(iPop,iD) != v[iD]) {
251 return DESCRIPTORBASE::q;
255template <
typename DESCRIPTOR,
int direction,
int orientation>
260 constexpr auto velocity_matches_value = [](
unsigned iPop) {
261 return descriptors::c<DESCRIPTOR>(iPop,direction) == orientation;
263 constexpr auto opposite_population = [](
unsigned iPop) {
264 return descriptors::opposite<DESCRIPTOR>(iPop);
268 descriptors::filter_population_indices<DESCRIPTOR>(velocity_matches_value)));
271template <
typename DESCRIPTOR,
int direction,
int orientation>
273 constexpr auto velocity_matches = [](
unsigned iPop) {
274 for (
unsigned jPop : subIndexOutgoing<DESCRIPTOR,direction,orientation>()) {
282 descriptors::filter_population_indices<DESCRIPTOR>(velocity_matches));
285template <
typename DESCRIPTOR,
int plane,
int normal1,
int normal2>
287 constexpr auto velocity_matches = [](
unsigned iPop) {
288 if constexpr (plane == 0) {
289 return ( descriptors::c<DESCRIPTOR>(iPop,0) * 0
290 + descriptors::c<DESCRIPTOR>(iPop,1) * (normal1 == 1 ? 1 : -1)
291 + descriptors::c<DESCRIPTOR>(iPop,2) * (normal2 == 1 ? 1 : -1)) < 0;
292 }
else if constexpr (plane == 1) {
293 return ( descriptors::c<DESCRIPTOR>(iPop,0) * (normal1 == 1 ? 1 : -1)
294 + descriptors::c<DESCRIPTOR>(iPop,1) * 0
295 + descriptors::c<DESCRIPTOR>(iPop,2) * (normal2 == 1 ? 1 : -1)) < 0;
296 }
else if constexpr (plane == 2) {
297 return ( descriptors::c<DESCRIPTOR>(iPop,0) * (normal1 == 1 ? 1 : -1)
298 + descriptors::c<DESCRIPTOR>(iPop,1) * (normal2 == 1 ? 1 : -1)
299 + descriptors::c<DESCRIPTOR>(iPop,2) * 0) < 0;
305 descriptors::filter_population_indices<DESCRIPTOR>(velocity_matches));
309template <
typename DESCRIPTOR,
int normalX,
int normalY>
311 constexpr auto velocity_matches = [](
unsigned iPop) {
312 return ( descriptors::c<DESCRIPTOR>(iPop,0) * normalX
313 + descriptors::c<DESCRIPTOR>(iPop,1) * normalY) < 0;
316 descriptors::filter_population_indices<DESCRIPTOR>(velocity_matches));
320template <
typename DESCRIPTOR,
int normalX,
int normalY,
int normalZ>
322 constexpr auto velocity_matches = [](
unsigned iPop) {
323 return ( descriptors::c<DESCRIPTOR>(iPop,0) * normalX
324 + descriptors::c<DESCRIPTOR>(iPop,1) * normalY
325 + descriptors::c<DESCRIPTOR>(iPop,2) * normalZ) < 0;
328 descriptors::filter_population_indices<DESCRIPTOR>(velocity_matches));
332template <
typename DESCRIPTORBASE>
335 std::vector<int> remaining;
336 for (
int iPop = 0; iPop < DESCRIPTORBASE::q; ++iPop) {
338 for (
unsigned jPop = 0; jPop < indices.size(); ++jPop) {
339 if (indices[jPop] == iPop) {
344 remaining.push_back(iPop);
353template <
typename T,
typename DESCRIPTOR>
358 for (
int iQ=1; iQ<DESCRIPTOR::q; ++iQ) {
359 std::vector<T> c_i(DESCRIPTOR::c[iQ], DESCRIPTOR::c[iQ]+3);
360 T tmp = util::scalarProduct<T>(c_i, vec)/
util::norm(c_i);
369namespace tensorIndices2D {
373namespace tensorIndices3D {
378template <
typename T,
typename DESCRIPTOR>
382 return latticePressure * descriptors::invCs2<T,DESCRIPTOR>() + 1.0;
386template <
typename T,
typename DESCRIPTOR>
390 return (latticeDensity - 1.0) / descriptors::invCs2<T,DESCRIPTOR>();
396std::enable_if_t<std::is_arithmetic<T>::type::value, T>
abs(T x)
std::vector< int > remainingIndexes(const std::vector< int > &indices)
finds all the remaining indexes of a lattice given some other indexes
cpu::simd::Pack< T > sqrt(cpu::simd::Pack< T > value)
constexpr auto subIndexOutgoingRemaining() any_platform
bool aligned_to_grid(const std::vector< T > &vec)
T densityFromPressure(T latticePressure)
compute lattice density from lattice pressure
cpu::simd::Pack< T > min(cpu::simd::Pack< T > rhs, cpu::simd::Pack< T > lhs)
constexpr auto populationsContributingToVelocity() any_platform
Return array of population indices where c[iVel] == value.
constexpr auto subIndexOutgoing2DonCorners() any_platform
constexpr auto subIndexOutgoing3DonEdges() any_platform
bool contained(int x, int y, int x0, int x1, int y0, int y1)
constexpr auto subIndexOutgoing() any_platform
Compute opposites of wall-incoming population indices.
cpu::simd::Pack< T > max(cpu::simd::Pack< T > rhs, cpu::simd::Pack< T > lhs)
T pressureFromDensity(T latticeDensity)
compute lattice pressure from lattice density
auto normSqr(const ARRAY_LIKE &u) any_platform
Compute norm square of a d-dimensional vector.
T norm(const std::vector< T > &a)
l2 norm of a vector of arbitrary length
bool aligned_to_y(const std::vector< T > &vec)
T scalarProduct(const T u1[d], const T u2[d])
bool intersect(int x0, int x1, int y0, int y1, int x0_, int x1_, int y0_, int y1_, int &newX0, int &newX1, int &newY0, int &newY1)
bool aligned_to_z(const std::vector< T > &vec)
int get_nearest_link(const std::vector< T > &vec)
Util Function for Wall Model of Malaspinas get link with smallest angle to a vector.
cpu::simd::Pack< T > fabs(cpu::simd::Pack< T > value)
constexpr auto subIndexOutgoing3DonCorners() any_platform
int findVelocity(const int v[DESCRIPTORBASE::d]) any_platform
bool aligned_to_x(const std::vector< T > &vec)
constexpr auto populationsContributingToDirection() any_platform
Return array of population indices where c[iPop][iD] == NORMAL[iD].
Top level namespace for all of OpenLB.
std::enable_if_t< std::is_arithmetic< T >::type::value, T > abs(T x)
Compute number of elements of a symmetric d-dimensional tensor.
static constexpr int n
result stored in n
efficient implementation of a vector class