25#ifndef INDICATOR_BASE_H
26#define INDICATOR_BASE_H
35template <
typename S,
unsigned D,
typename F1,
typename F2>
37 S precision, S pitch, F1 isInside, F2 isInsideBoundingBox)
40 bool isInsideDistance;
41 bool isInsideOppDistance;
42 Vector<S,D> currentPoint = origin + 10*precision*direction;
43 isInside(&isInsideDistance, currentPoint.
data());
44 currentPoint = origin - 10*precision*direction;
45 isInside(&isInsideOppDistance, currentPoint.
data());
46 if (isInsideDistance == !isInsideOppDistance) {
54 isInside(&originValue, origin.
data());
57 currentPoint = origin;
58 currentValue = originValue;
60 while (currentValue == originValue && isInsideBoundingBox(currentPoint)) {
61 currentPoint += direction;
63 isInside(¤tValue, currentPoint.
data());
67 if (!isInsideBoundingBox(currentPoint) && !originValue) {
72 while (pitch >= precision) {
73 if (!isInsideBoundingBox(currentPoint) && originValue) {
74 currentPoint -= pitch * direction;
78 isInside(¤tValue, currentPoint.
data());
79 if (currentValue == originValue) {
80 currentPoint += pitch * direction;
84 currentPoint -= pitch * direction;
94template <
typename S,
unsigned D,
typename F1,
typename F2>
96 S precision, F1 sdf, F2 isInsideBoundingBox,
const unsigned maxIt = 1e6)
98 S signedDistance{sdf(origin)};
102 if (
util::fabs(signedDistance) <= precision) {
108 for(
unsigned i=0;
util::fabs(signedDistance) > precision && i<maxIt; ++i) {
110 currPos += signedDistance * dir;
111 signedDistance = sdf(currPos);
112 if (!isInsideBoundingBox(currPos)) {
122template <
typename S,
unsigned D,
bool normalizeDirection = true>
124 S precision, std::function<S(
const Vector<S,D>&)> sdf, S maxDistance,
const unsigned maxIt = 1e6)
126 S signedDistance{sdf(origin)};
129 if constexpr(normalizeDirection) {
136 if (
util::fabs(signedDistance) <= precision) {
142 for(
unsigned i=0;
util::fabs(signedDistance) > precision && i<maxIt; ++i) {
144 currPos += signedDistance * dir;
145 signedDistance = sdf(currPos);
146 if (signedDistance > maxDistance) {
167template <
typename S,
unsigned D,
typename F1,
typename F2>
169 S pitch, S precision, F1 isInside, F2 isInsideBoundingBox)
175 bool isInsideDistance = isInside(origin + 5*precision*dir);
176 bool isInsideOppDistance = isInside(origin - 5*precision*dir);
177 if (isInsideDistance == !isInsideOppDistance) {
182 S fixedDistance = S(0);
184 std::function<Vector<S,D>()> calcCurrPoint = [&startPoint, &pitch, &dir]() {
185 return startPoint + pitch * dir;
189 bool originValue = isInside(startPoint);
190 bool currentValue = isInside(currPoint);
193 while (originValue == currentValue) {
195 currPoint = calcCurrPoint();
196 currentValue = isInside(currPoint);
199 if (!currentValue && !isInsideBoundingBox(startPoint) && !isInsideBoundingBox(currPoint)) {
204 for (
unsigned iD=0; iD<D; ++iD) {
205 if (!std::isfinite(currPoint[iD])) {
214 currPoint = calcCurrPoint();
221 currentValue = isInside(currPoint);
222 if (currentValue == originValue) {
223 startPoint = currPoint;
235template <
typename S,
unsigned D,
typename F1>
240 for (
unsigned iD=0; iD<D; ++iD) {
242 delta[iD] = meshSize;
243 normal[iD] = (sdf(pos+delta) - sdf(pos-delta)) / (2*meshSize);
constexpr const T * data() const any_platform
ADf< T, DIM > abs(const ADf< T, DIM > &a)
bool distance(S &distance, const Vector< S, D > &origin, const Vector< S, D > &direction, S precision, S pitch, F1 isInside, F2 isInsideBoundingBox)
bool bisectDistance(S &distance, const Vector< S, D > &origin, const Vector< S, D > &direction, S pitch, S precision, F1 isInside, F2 isInsideBoundingBox)
Using a bisect to find the unsigned distance (false if distance was not found, true if distance was f...
Vector< S, D > surfaceNormal(const Vector< S, D > &pos, const S meshSize, F1 sdf)
T norm(const std::vector< T > &a)
l2 norm of a vector of arbitrary length
cpu::simd::Pack< T > fabs(cpu::simd::Pack< T > value)
Vector< T, D > normalize(const Vector< T, D > &a)
Top level namespace for all of OpenLB.
Set of functions commonly used in LB computations – header file.