From 94d3e79a8617f88dc0219cfdeedfa3147833719d Mon Sep 17 00:00:00 2001 From: Adrian Kummerlaender Date: Mon, 24 Jun 2019 14:43:36 +0200 Subject: Initialize at openlb-1-3 --- src/utilities/vectorHelpers.h | 276 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 276 insertions(+) create mode 100644 src/utilities/vectorHelpers.h (limited to 'src/utilities/vectorHelpers.h') diff --git a/src/utilities/vectorHelpers.h b/src/utilities/vectorHelpers.h new file mode 100644 index 0000000..17453dd --- /dev/null +++ b/src/utilities/vectorHelpers.h @@ -0,0 +1,276 @@ +/* This file is part of the OpenLB library + * + * Copyright (C) 2013, 2014 Lukas Baron, Mathias J. Krause + * E-mail contact: info@openlb.net + * The most recent release of OpenLB can be downloaded at + * + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the Free + * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef VECTOR_HELPERS_H +#define VECTOR_HELPERS_H + +#include +#include +#include +#include +#include +#include + +#include "io/ostreamManager.h" +#include "core/vector.h" + +namespace olb { + +template class Vector; + +namespace util { + + +/// return true if a is close to zero +template +inline bool nearZero(const T& a) +{ + if (a==T()) return true; + T EPSILON = std::numeric_limits::epsilon(); + if (a > -EPSILON && a < EPSILON) { + return true; + } else { + return false; + } +} + +template +inline bool nearZero(const T& a, const T& epsilon) +{ + if (a > -epsilon && a < epsilon) { + return true; + } else { + return false; + } +} + +template +inline bool approxEqual(const T& a, const T& b, const T& epsilon) +{ + if (a==b) return true; + return nearZero(a - b, epsilon); +} + +template +inline bool approxEqual(const T& a, const T& b) +{ + if (a==b) return true; + if (nearZero(a) && nearZero(b)) return true; + T EPSILON = std::numeric_limits::epsilon()*4.*fabs(a); + return approxEqual(a,b,EPSILON); +} + +template +inline void copyN(T c[], const T a[], const unsigned dim) +{ + for (unsigned i=0; i +inline void copy3(T c[], const T a[]) +{ + for (unsigned i=0; i<3; i++) { + c[i] = a[i]; + } +} + + +template +std::vector fromVector3(const Vector& vec) +{ + std::vector v; + v.push_back(vec[0]); + v.push_back(vec[1]); + v.push_back(vec[2]); + return v; +} +template +std::vector fromVector2(const Vector& vec) +{ + std::vector v; + v.push_back(vec[0]); + v.push_back(vec[1]); + return v; +} + + +/// l2 norm of a vector of arbitrary length +template +T norm(const std::vector& a) +{ + T v(0); + for (unsigned iD=0; iD +T norm2(const std::vector& a) +{ + T v = T(); + for (unsigned iD=0; iD +T dotProduct3D(const Vector& a, const Vector& b) +{ + return a[0]*b[0] + a[1]*b[1] + a[2]*b[2]; +} + +/// dot product, only valid in 2d +template +T dotProduct2D(const Vector& a, const Vector& b) +{ + return a[0]*b[0] + a[1]*b[1]; +} + +/// returns a normalized vector, works for arbitrary lengths +template +std::vector normalize(const std::vector& a) +{ + std::vector out(a); + T scale = norm(a); + assert(scale>0); + for (unsigned int iDim=0; iDim +Vector floor(const Vector& a) +{ + Vector out; + for (unsigned int iDim=0; iDim < Size; ++iDim) { + out[iDim] = std::floor(a[iDim]); + } + return out; +} + +/// applies ceil to each component of a vector +template +Vector ceil(const Vector& a) +{ + Vector out; + for (unsigned int iDim=0; iDim < Size; ++iDim) { + out[iDim] = std::ceil(a[iDim]); + } + return out; +} + +/* +/// algorithm by Möller–Trumbore (TODO add ref), implemented by Lucas Cruz and Mathias J. Krause +/// returns true if there is an intersection of a triangle given by (point0, point1, point1) and a ray given by its origin and direction and computes the distance +template +bool triangleIntersectionWithNormalDirection(const std::vector& point0, + const std::vector& point1, const std::vector& point2, + const std::vector& origin, const std::vector& normalDirection, + T& distance) +{ + T EPSILON = std::numeric_limits::epsilon(); + std::vector e1, e2; + std::vector P, Q, TT; + T det, inv_det; + T t, u, v; + e1 = point1 - point0; + e2 = point2 - point0; + P = crossProduct3D(normalDirection, e2); + det = dotProduct3D(P, e1); + if (det > -EPSILON && det < EPSILON) { + return false; + } + inv_det = T(1) / det; + TT = origin - point0; + u = dotProduct3D(TT, P)*inv_det; + if (u < T() || u > T(1)) { + return false; + } + Q = crossProduct3D(TT, e1); + v = dotProduct3D(normalDirection, Q) * inv_det; + if (v < T() || u + v > T(1)) { + return false; + } + t = dotProduct3D(e2, Q)*inv_det; + if (t > EPSILON) { + distance = t; + return true; + } + return false; +} + +template +bool triangleIntersection(const std::vector& point0, const std::vector& point1, const std::vector& point2, const std::vector& origin, const std::vector& direction, T& distance) +{ + std::vector normalDirection(normalize(direction) ); + return triangleIntersectionWithNormalDirection(point0, point1, point2, origin, normalDirection, distance ); +} +*/ +template +std::vector assign(T a, T b) +{ + std::vector v1; + v1.push_back(a); + v1.push_back(b); + return v1; +} + +template +std::vector assign(T a, T b, T c) +{ + std::vector v1; + v1.push_back(a); + v1.push_back(b); + v1.push_back(c); + return v1; +} + + +template +void print(U data, const std::string& name="", OstreamManager clout = OstreamManager(std::cout,"print"), + const char delimiter=',') +{ + static_assert(!std::is_integral::value && !std::is_floating_point::value, "passed integral or floating_point value to function print()"); + if (name != "") { + clout << name << " = "; + } + for( auto& element : data ) { + clout << std::fixed << element << delimiter << ' '; + } + clout << std::endl; +} + + +} // namespace util +} // namespace olb + +#endif -- cgit v1.2.3