OpenLB 1.7
Loading...
Searching...
No Matches
indicatorF2D.hh
Go to the documentation of this file.
1/* This file is part of the OpenLB library
2 *
3 * Copyright (C) 2016 Thomas Henn, Cyril Masquelier, Jan Marquardt, Mathias J. Krause
4 * E-mail contact: info@openlb.net
5 * The most recent release of OpenLB can be downloaded at
6 * <http://www.openlb.net/>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public
19 * License along with this program; if not, write to the Free
20 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 * Boston, MA 02110-1301, USA.
22*/
23
24#ifndef INDICATOR_F_2D_HH
25#define INDICATOR_F_2D_HH
26
27#include "utilities/omath.h"
28
29#include "indicatorF2D.h"
31
32#ifndef M_PI
33#define M_PI 3.14159265358979323846
34#endif
35#define M_PI2 1.57079632679489661923
36
37namespace olb {
38
39// Warning : the cuboid is only defined parallel to the plans x=0 and y=0 !!!
40// For other cuboids, please use the parallelepiped version
41template <typename S>
43 : _indicator3D(indicator3D)
44{
45 this->_myMin[0] = _indicator3D.getMin()[0];
46 this->_myMin[1] = _indicator3D.getMin()[1];
47 this->_myMax[0] = _indicator3D.getMax()[0];
48 this->_myMax[1] = _indicator3D.getMax()[1];
49}
50
51template <typename S>
52bool IndicatorF2DfromIndicatorF3D<S>::operator()(bool output[], const S input[])
53{
54 S input3D[3];
55 input3D[0] = input[0];
56 input3D[1] = input[1];
57 input3D[2] = (_indicator3D.getMax()[2] - _indicator3D.getMin()[2]) * 0.5 + _indicator3D.getMin()[2];
58 _indicator3D(output, input3D);
59 return true;
60}
61
62
63
64// Warning : the cuboid is only defined parallel to the plans x=0 and y=0 !!!
65// For other cuboids, please use the parallelepiped version
66template <typename S>
68 : _center(origin + S(.5)*extend), _xLength(extend[0]), _yLength(extend[1]), _theta(theta)
69
70{
71 this->_myMin = origin;
72 this->_myMax = origin + extend;
73}
74
75template <typename S>
76IndicatorCuboid2D<S>::IndicatorCuboid2D(S xLength, S yLength, Vector<S,2> center, S theta )
77 : _center(center), _xLength(xLength), _yLength(yLength), _theta(-theta)
78{
79 this->_myMin = {_center[0] - _xLength/S(2), _center[1] - _yLength/S(2)};
80 this->_myMax = {_center[0] + _xLength/S(2), _center[1] + _yLength/S(2)};
81}
82
83
84// returns true if x is inside the cuboid
85template <typename S>
86bool IndicatorCuboid2D<S>::operator()(bool output[], const S input[])
87{
88 S x, y;
89 if ( !util::nearZero(_theta) ) {
90 x = _center[0] + (input[0] - _center[0])*util::cos(_theta) - (input[1] - _center[1])*util::sin(_theta);
91 y = _center[1] + (input[0] - _center[0])*util::sin(_theta) + (input[1] - _center[1])*util::cos(_theta);
92 }
93 else {
94 x = input[0];
95 y = input[1];
96 }
97
98 output[0] = ( (util::fabs(_center[0] - x) < _xLength/S(2) || util::approxEqual(util::fabs(_center[0] - x),_xLength/S(2)) )
99 && (util::fabs(_center[1] - y) < _yLength/S(2) || util::approxEqual(util::fabs(_center[1] - y), _yLength/S(2)) ) );
100 return true;
101}
102
103template <typename S>
105{
106 return _center;
107}
108
109template <typename S>
111{
112 return _xLength;
113}
114
115template <typename S>
117{
118 return _yLength;
119}
120
121template <typename S>
123{
124 // TODO: Implementation should be analogous to other indicators.
125
126 Vector<S,2> ptransl = {input[0]-_center[0], input[1]-_center[1]};
127 Vector<S,2> prot = {util::cos(-_theta)*ptransl[0]+util::sin(-_theta)*ptransl[1], util::cos(-_theta)*ptransl[1]-util::sin(-_theta)*ptransl[0]};
128
129 return sdf::box(prot, Vector<S,2>(S(.5)*_xLength, S(.5)*_yLength));
130}
131
132
133// creator function
134template <typename S>
136{
137 OstreamManager clout(std::cout,"createIndicatorCuboid2D");
138 params.setWarningsOn(verbose);
139
140 Vector<S,2> center;
141 S xLength;
142 S yLength;
143
144 std::stringstream xmlCenter( params.getAttribute("center") );
145 xmlCenter >> center[0] >> center[1];
146 std::stringstream xmlRadius( params.getAttribute("length") );
147 xmlRadius >> xLength >> yLength;
148
149 return new IndicatorCuboid2D<S>(xLength, yLength, center);
150}
151
152
153template <typename S>
155 : _center(center),
156 _radius(radius),
157 _radius2(radius*radius)
158{
159 this->_myMin = _center - radius;
160 this->_myMax = _center + radius;
161}
162
163template <typename S>
165{
166 return _center;
167}
168
169template <typename S>
171{
172 return _radius;
173}
174
175// returns true if x is inside the circle
176template <typename S>
177bool IndicatorCircle2D<S>::operator()(bool output[], const S input[])
178{
179 output[0] = ( util::pow(_center[0] - input[0],2) + util::pow(_center[1] - input[1], 2) <= _radius2 );
180 return output[0];
181}
182
183
184template <typename S>
185bool IndicatorCircle2D<S>::distance(S& distance, const Vector<S,2>& origin, const Vector<S,2>& direction, int iC)
186{
187 S a = direction[0]*direction[0] + direction[1]*direction[1];
188
189 // returns 0 if point is at the boundary of the sphere
190 if ( util::approxEqual(a,_radius2) ) {
191 distance = S(0);
192 return true;
193 }
194 // norm of direction
195 a = util::sqrt(a);
196
197 S b = 2.*((origin[0] - _center[0])*direction[0] +
198 (origin[1] - _center[1])*direction[1])/a;
199 S c = -_radius2 + (origin[0] - _center[0])*(origin[0] - _center[0])
200 + (origin[1] - _center[1])*(origin[1] - _center[1]);
201
202 // discriminant
203 S d = b*b - 4.*c;
204 if (d < 0) {
205 return false;
206 }
207
208 S x1 = (- b + util::sqrt(d)) *0.5;
209 S x2 = (- b - util::sqrt(d)) *0.5;
210
211 // case if origin is inside the sphere
212 if ((x1<0.) || (x2<0.)) {
213 if (x1>0.) {
214 distance = x1;
215 return true;
216 }
217 if (x2>0.) {
218 distance = x2;
219 return true;
220 }
221 }
222 // case if origin is ouside the sphere
223 else {
224 distance = util::min(x1,x2);
225 return true;
226 }
227
228 return false;
229}
230
231
232template <typename S>
233bool IndicatorCircle2D<S>::normal(Vector<S,2>& normal, const Vector<S,2>& origin, const Vector<S,2>& direction, int iC)
234{
235 S dist;
236 if (!(distance(dist, origin, direction, iC)) ) {
237 return false;
238 }
239
240 Vector<S,2> intresection(origin + dist*direction);
241
242 normal = intresection - _center;
243
244 return true;
245}
246
247template <typename S>
249{
250 Vector<S,2> p = input - _center;
251 return sdf::sphere(p, _radius);
252}
253
254template <typename S>
256{
257 OstreamManager clout(std::cout,"createIndicatorCircle2D");
258 params.setWarningsOn(verbose);
259
260 Vector<S,2> center;
261 S radius = 1;
262
263 std::stringstream xmlCenter( params.getAttribute("center") );
264 xmlCenter >> center[0] >> center[1];
265 std::stringstream xmlRadius( params.getAttribute("radius") );
266 xmlRadius >> radius;
267
268 return new IndicatorCircle2D<S>(center, radius);
269}
270
271template <typename S>
273 : _a(a),
274 _b(b),
275 _c(c)
276{
277
278 this->_myMin = {util::min(_a[0], util::min(_b[0], _c[0])), util::min(_a[1], util::min(_b[1], _c[1]))};
279 this->_myMax = {util::max(_a[0], util::max(_b[0], _c[0])), util::max(_a[1], util::max(_b[1], _c[1]))};
280}
281
282
283template <typename S>
285{
286 return _a;
287}
288
289template <typename S>
291{
292 return _b;
293}
294
295template <typename S>
297{
298 return _c;
299}
300
301// returns true if x is inside the triangle
302template <typename S>
303bool IndicatorTriangle2D<S>::operator()(bool output[], const S input[])
304{
305 output[0] = ( sdf::triangle({input[0], input[1]}, _a, _b, _c) <= 0 );
306 return output[0];
307}
308
309template <typename S>
311{
312
313 return sdf::triangle(input, _a, _b, _c);
314}
315
316template <typename S>
318{
319 OstreamManager clout(std::cout,"createIndicatorTriangle2D");
320 params.setWarningsOn(verbose);
321
322 Vector<S,2> a;
323 Vector<S,2> b;
324 Vector<S,2> c;
325
326 std::stringstream xmla( params.getAttribute("a") );
327 xmla>> a[0] >> a[1];
328 std::stringstream xmlb( params.getAttribute("b") );
329 xmlb >> b[0] >> b[1];
330 std::stringstream xmlc( params.getAttribute("c") );
331 xmlc >> c[0] >> c[1];
332
333 return new IndicatorTriangle2D<S>(a, b, c);
334}
335
336template <typename S>
338 : _center(center),
339 _radius(radius),
340 _a({center[0], center[1]+radius}),
341_b({center[0]-util::sqrt(3)/S(2)*radius, center[1]-S(0.5)*radius}),
342_c({center[0]+util::sqrt(3)/S(2)*radius, center[1]-S(0.5)*radius})
343{
344
345 this->_myMin = {util::min(_a[0], util::min(_b[0], _c[0])), util::min(_a[1], util::min(_b[1], _c[1]))};
346 this->_myMax = {util::max(_a[0], util::max(_b[0], _c[0])), util::max(_a[1], util::max(_b[1], _c[1]))};
347}
348
349
350template <typename S>
352{
353 return _a;
354}
355
356template <typename S>
358{
359 return _b;
360}
361
362template <typename S>
364{
365 return _c;
366}
367
368template <typename S>
370{
371 return _center;
372}
373
374template <typename S>
376{
377 return _radius;
378}
379
380// returns true if x is inside the triangle
381template <typename S>
382bool IndicatorEquiTriangle2D<S>::operator()(bool output[], const S input[])
383{
384 output[0] = ( sdf::triangle({input[0], input[1]}, _a, _b, _c) <= 0 );
385 return output[0];
386}
387
388template <typename S>
390{
391
392 return sdf::triangle( input, _a, _b, _c);
393}
394
395template <typename S>
397{
398 OstreamManager clout(std::cout,"createIndicatorEquiTriangle2D");
399 params.setWarningsOn(verbose);
400
401 Vector<S,2> center;
402 S radius = 1;
403
404 std::stringstream xmlCenter( params.getAttribute("center") );
405 xmlCenter>> center[0] >> center[1];
406 std::stringstream xmlRadius( params.getAttribute("radius") );
407 xmlRadius >> radius;
408
409 return new IndicatorEquiTriangle2D<S>(center, radius);
410}
411
412
413template <typename S>
415 Vector<S,3> extend, Vector<S,3> origin, S deltaR, bool invert)
416 : _blockData(blockData), _deltaR(deltaR), _invert(invert)
417{
418 this->_myMin = Vector<S,2>(origin[0], origin[1]);
419 this->_myMax = Vector<S,2>(origin[0] + extend[0], origin[1] + extend[1]);
420
421 OLB_ASSERT(extend[2]-origin[2] == 1, "extend[2]-origin[2] must be 1.")
422}
423
424template <typename S>
426{
427 // Translation
428 S xDist = input[0] - this->_myMin[0];
429 S yDist = input[1] - this->_myMin[1];
430
431 int x = ((this->_myMin[0] + xDist)/_deltaR)+0.5;
432 int y = ((this->_myMin[1] + yDist)/_deltaR)+0.5;
433
434 if (x >= 0 && x < _blockData.getNx() && y >= 0 && y < _blockData.getNy()) {
435 LatticeR<3> input(x,y,0);
436 if (_blockData.get(input) > std::numeric_limits<S>::epsilon()) {
437 if (!_invert){
438 return 1.;
439 } else {
440 return -1.;
441 }
442 }
443 else {
444 if (!_invert){
445 return -1.;
446 } else {
447 return 1.;
448 }
449
450 }
451 }
452
453 if (!_invert){
454 return 1.;
455 } else {
456 return -1.;
457 }
458
459}
460
461template <typename S>
463 : _indicatorF(indicatorF), _layerSize(layerSize)
464{
465 this->_myMin = indicatorF.getMin() - layerSize;
466 this->_myMax = indicatorF.getMax() + layerSize;
467 OLB_ASSERT( (this->_myMax[0]-this->_myMin[0]) > std::numeric_limits<S>::epsilon(),"Indicator reduced to zero-set in x direction");
468 OLB_ASSERT( (this->_myMax[1]-this->_myMin[1]) > std::numeric_limits<S>::epsilon(),"Indicator reduced to zero-set in y direction");
469 _isPositive = std::signbit(layerSize);
470}
471
472// returns true if x is inside the layer
473template <typename S>
474bool IndicatorLayer2D<S>::operator()(bool output[], const S input[])
475{
476 output[0] = !_isPositive;
477 S r[2];
478 for (int iX =- 1; iX < 2; ++iX) {
479 for (int iY =- 1; iY < 2; ++iY) {
480 r[0] = input[0] + iX*_layerSize;
481 r[1] = input[1] + iY*_layerSize;
482 _indicatorF(output,r);
483 if (output[0] == !_isPositive) {
484 return true;
485 }
486 }
487 }
488 return true;
489}
490
491
492template <typename T>
494 : _f(f)
495{}
496
497template <typename T>
498bool IndicatorSDF2D<T>::operator()(bool output[], const T input[])
499{
500 output[0] = _f(input) <= 0.0;
501 return true;
502}
503
504} // namespace olb
505
506#endif
IndicatorBlockData2D(BlockData< 3, S, S > &blockData, Vector< S, 3 > extend, Vector< S, 3 > origin, S deltaR, bool invert)
S signedDistance(const Vector< S, 2 > &input) override
Returns signed distance to the nearest point on the indicator surface.
indicator function for a 2D circle
bool normal(Vector< S, 2 > &normal, const Vector< S, 2 > &origin, const Vector< S, 2 > &direction, int iC=-1) override
returns true and the normal if there was one found for an given origin and direction
IndicatorCircle2D(Vector< S, 2 > center, S radius)
S signedDistance(const Vector< S, 2 > &input) override
Returns signed distance to the nearest point on the indicator surface.
S const getRadius() const
bool distance(S &distance, const Vector< S, 2 > &origin, const Vector< S, 2 > &direction, int iC=-1) override
bool operator()(bool output[], const S input[]) override
has to be implemented for 'every' derived class
Vector< S, 2 > const & getCenter() const
indicator function for a 2D-cuboid, parallel to the planes x=0, y=0; theta rotates cuboid around its ...
bool operator()(bool output[], const S input[]) override
returns true if input is inside, otherwise false
S const getxLength() const
S const getyLength() const
Vector< S, 2 > const & getCenter() const
IndicatorCuboid2D(Vector< S, 2 > extend, Vector< S, 2 > origin, S theta=0)
constructs an cuboid with x axis dimension 0 to extend[0], ...
S signedDistance(const Vector< S, 2 > &input) override
Returns signed distance to the nearest point on the indicator surface.
indicator function for a 2D equilateral triangle
Vector< S, 2 > const & getCenter() const
S signedDistance(const Vector< S, 2 > &input) override
Returns signed distance to the nearest point on the indicator surface.
bool operator()(bool output[], const S input[]) override
has to be implemented for 'every' derived class
Vector< S, 2 > const & getVertexA() const
IndicatorEquiTriangle2D(Vector< S, 2 > center, S radius)
Vector< S, 2 > const & getVertexB() const
Vector< S, 2 > const & getVertexC() const
IndicatorF2D is an application from .
Vector< S, 2 > _myMin
Vector< S, 2 > _myMax
virtual Vector< S, 2 > & getMin()
virtual Vector< S, 2 > & getMax()
bool operator()(bool output[], const S input[]) override
has to be implemented for 'every' derived class
IndicatorF2DfromIndicatorF3D(IndicatorF3D< S > &indicator3D)
IndicatorF3D is an application from .
bool operator()(bool output[], const S input[]) override
has to be implemented for 'every' derived class
IndicatorLayer2D(IndicatorF2D< S > &indicatorF, S layerSize)
IndicatorSDF2D(std::function< T(Vector< T, 2 >)> f)
bool operator()(bool output[], const T input[]) override
indicator function for a 2D triangle
bool operator()(bool output[], const S input[]) override
has to be implemented for 'every' derived class
Vector< S, 2 > const & getVertexC() const
IndicatorTriangle2D(Vector< S, 2 > a, Vector< S, 2 > b, Vector< S, 2 > c)
Vector< S, 2 > const & getVertexA() const
Vector< S, 2 > const & getVertexB() const
S signedDistance(const Vector< S, 2 > &input) override
Returns signed distance to the nearest point on the indicator surface.
class for marking output with some text
Plain old scalar vector.
Definition vector.h:47
std::string getAttribute(const std::string &aName) const
Definition xmlReader.h:541
void setWarningsOn(bool warnings) const
switch warnings on/off
Definition xmlReader.h:412
This file contains indicator functions.
T triangle(Vector< T, 2 > p, Vector< T, 2 > a, Vector< T, 2 > b, Vector< T, 2 > c) any_platform
Exact signed distance to the surface of two-dimensional triangle.
Definition sdf.h:143
T sphere(Vector< T, D > p, T r) any_platform
Exact signed distance to the surface of circle (in 2D) or sphere (in 3D).
Definition sdf.h:104
T box(Vector< T, 2 > p, Vector< T, 2 > b) any_platform
Exact signed distance to the surface of two-dimensional cuboid.
Definition sdf.h:115
cpu::simd::Pack< T > sqrt(cpu::simd::Pack< T > value)
Definition pack.h:100
cpu::simd::Pack< T > min(cpu::simd::Pack< T > rhs, cpu::simd::Pack< T > lhs)
Definition pack.h:124
bool approxEqual(T a, U b, W epsilon)
cpu::simd::Pack< T > max(cpu::simd::Pack< T > rhs, cpu::simd::Pack< T > lhs)
Definition pack.h:130
ADf< T, DIM > sin(const ADf< T, DIM > &a)
Definition aDiff.h:569
cpu::simd::Pack< T > pow(cpu::simd::Pack< T > base, cpu::simd::Pack< T > exp)
Definition pack.h:112
cpu::simd::Pack< T > fabs(cpu::simd::Pack< T > value)
Definition pack.h:106
bool nearZero(const ADf< T, DIM > &a)
Definition aDiff.h:1087
ADf< T, DIM > cos(const ADf< T, DIM > &a)
Definition aDiff.h:578
Top level namespace for all of OpenLB.
IndicatorCuboid2D< S > * createIndicatorCuboid2D(XMLreader const &params, bool verbose=false)
IndicatorEquiTriangle2D< S > * createIndicatorEquiTriangle2D(XMLreader const &params, bool verbose)
IndicatorCircle2D< S > * createIndicatorCircle2D(XMLreader const &params, bool verbose=false)
IndicatorTriangle2D< S > * createIndicatorTriangle2D(XMLreader const &params, bool verbose)
#define OLB_ASSERT(COND, MESSAGE)
Definition olbDebug.h:45