OpenLB 1.7
Loading...
Searching...
No Matches
indicatorF3D.hh
Go to the documentation of this file.
1/* This file is part of the OpenLB library
2 *
3 * Copyright (C) 2014-2016 Cyril Masquelier, Mathias J. Krause, Albert Mink, Berkay Oralalp
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_3D_HH
25#define INDICATOR_F_3D_HH
26
27#include <vector>
28#include "utilities/omath.h"
29#include <cassert>
30#include <sstream>
31
32#include "indicatorF3D.h"
33#include "indicComb3D.h"
35
36
37namespace olb {
38
39template <typename S>
41 : _translate(translate), _indicator(indicator), _myMin(indicator.getMin()), _myMax(indicator.getMax())
42{
43 this->_myMin[0] += this->_translate[0];
44 this->_myMin[1] += this->_translate[1];
45 this->_myMin[2] += this->_translate[2];
46
47 this->_myMax[0] += this->_translate[0];
48 this->_myMax[1] += this->_translate[1];
49 this->_myMax[2] += this->_translate[2];
50}
51
52template< typename S>
53bool IndicatorTranslate3D<S>::operator() (bool output[], const S input[] )
54{
55 const S inputTranslated[3] = {
56 input[0] - _translate[0],
57 input[1] - _translate[1],
58 input[2] - _translate[2]
59 };
60
61 _indicator.operator()(output, inputTranslated);
62 return output[0];
63}
64
65template <typename S>
67{
68 Vector<S,3> translate = sdf::translate(input, {_translate[0], _translate[1], _translate[2]});
69 return _indicator.signedDistance(translate);
70}
71
72template <typename S>
74{
75 return _myMin;
76}
77
78template <typename S>
80{
81 return _myMax;
82}
83
84
85
86template <typename S>
88 : _center(center), _normal(normal), _radius2(radius*radius),
89 _cylinder(center, normal, radius, 5.0*std::numeric_limits<S>::epsilon())
90{
91 _normal = normalize(_normal);
92 this->_myMin = _center - radius;
93 this->_myMax = _center + radius;
94}
95
96template <typename S>
97IndicatorCircle3D<S>::IndicatorCircle3D(S center0, S center1, S center2,
98 S normal0, S normal1, S normal2, S radius)
99 : IndicatorCircle3D(Vector<S,3>{center0, center1, center2},
100 Vector<S,3>{normal0, normal1, normal2}, radius)
101{ }
102
103// returns true if x is inside the circle
104template <typename S>
105bool IndicatorCircle3D<S>::operator()(bool output[], const S input[])
106{
107 return _cylinder(output,input);
108}
109
110template <typename S>
112{
113 return _center;
114}
115
116template <typename S>
118{
119 return _normal;
120}
121
122template <typename S>
124{
125 return util::sqrt(_radius2);
126}
127
128
129
130template <typename S>
132 : _center(center), _radius(radius), _radius2(_radius*_radius)
133{
134 this->_myMin = _center - radius;
135 this->_myMax = _center + radius;
136}
137
138template <typename S>
140{
141 this->_myMin = sphere._myMin;
142 this->_myMax = sphere._myMax;
143 _center = sphere._center;
144 _radius = sphere._radius;
145 _radius2 = sphere._radius2;
146}
147
148template <typename S>
150{
151 return _center;
152}
153
154template <typename S>
156{
157 return _radius;
158}
159
160template <typename S>
162{
163 Vector<S,3> p = input - _center;
164 return sdf::sphere(p, _radius);
165}
166
167template <typename S>
168bool IndicatorSphere3D<S>::distance(S& distance, const Vector<S,3>& origin,
169 const Vector<S,3>& direction, int iC)
170{
171 // computes pos. distance by solving quadratic equation by a-b-c-formula
172 S a = direction[0]*direction[0] + direction[1]*direction[1] + direction[2]*direction[2];
173
174 // returns 0 if point is at the boundary of the sphere
175 if ( util::approxEqual(a,_radius2) ) {
176 distance = S();
177 return true;
178 }
179 // norm of direction
180 a = util::sqrt(a);
181
182 S b = 2.*((origin[0] - _center[0])*direction[0] +
183 (origin[1] - _center[1])*direction[1] +
184 (origin[2] - _center[2])*direction[2])/a;
185 S c = -_radius2 + (origin[0] - _center[0])*(origin[0] - _center[0])
186 + (origin[1] - _center[1])*(origin[1] - _center[1])
187 + (origin[2] - _center[2])*(origin[2] - _center[2]);
188
189 // discriminant
190 S d = b*b - 4.*c;
191 if (d < 0) {
192 return false;
193 }
194
195 S x1 = (- b + util::sqrt(d)) *0.5;
196 S x2 = (- b - util::sqrt(d)) *0.5;
197
198 // case if origin is inside the sphere
199 if ((x1<0.) || (x2<0.)) {
200 if (x1>0.) {
201 distance = x1;
202 return true;
203 }
204 if (x2>0.) {
205 distance = x2;
206 return true;
207 }
208 }
209 // case if origin is outside the sphere
210 else {
211 distance = util::min(x1,x2);
212 return true;
213 }
214
215 return false;
216}
217
218
219template <typename S>
221 : _indicatorF(std::move(indicatorF)), _layerSize(layerSize)
222{
223 this->_myMin = indicatorF->getMin() - layerSize;
224 this->_myMax = indicatorF->getMax() + layerSize;
225}
226
227// returns true if x is inside the layer
228template <typename S>
229bool IndicatorLayer3D<S>::operator()(bool output[], const S input[])
230{
231 output[0] = false;
232 S r[3];
233 for (int iX =- 1; iX < 2; ++iX) {
234 for (int iY =- 1; iY < 2; ++iY) {
235 for (int iZ =- 1; iZ < 2; ++iZ) {
236 r[0] = input[0] + iX*_layerSize;
237 r[1] = input[1] + iY*_layerSize;
238 r[2] = input[2] + iZ*_layerSize;
239 _indicatorF(output,r);
240 if (output[0]) {
241 return true;
242 }
243 }
244 }
245 }
246 return true;
247}
248
249template <typename S>
251
252{
253
254// Rounding: Creates a Layer with a constant thickness --> edges are rounded
255 return sdf::rounding(_indicatorF->signedDistance(input), _layerSize);
256
257
258}
259
260template <typename S>
262 : _indicatorF(indicatorF), _layerSize(layerSize)
263{
264 this->_myMin = indicatorF.getMin() + layerSize;
265 this->_myMax = indicatorF.getMax() - layerSize;
266}
267
268// returns true if x is inside the layer
269template <typename S>
270bool IndicatorInternal3D<S>::operator()(bool output[], const S input[])
271{
272 output[0] = false;
273 _indicatorF(output,input);
274 if (!output[0]) {
275 return true;
276 }
277
278 S r[3];
279 for (int iX =- 1; iX < 2; ++iX) {
280 for (int iY =- 1; iY < 2; ++iY) {
281 for (int iZ =- 1; iZ < 2; ++iZ) {
282 r[0] = input[0] + iX*_layerSize;
283 r[1] = input[1] + iY*_layerSize;
284 r[2] = input[2] + iZ*_layerSize;
285 _indicatorF(output,r);
286 if (!output[0]) {
287 return true;
288 }
289 }
290 }
291 }
292 return true;
293}
294
295
297template <typename S>
299 Vector<S,3> center2, S radius)
300 : _center1(center1), _center2(center2),
301 _ba(_center2 - _center1),
302 _baba(_ba[0]*_ba[0] + _ba[1]*_ba[1] + _ba[2]*_ba[2]),
303 _radius2(radius*radius), _length(util::sqrt(_baba))
304{
305 // cylinder defined by the centers of the two extremities and the radius
306 // _I,_J,_K is the new base where _K is the axe of the cylinder0
307 init();
308}
309
311template <typename S>
313 Vector<S,3> normal, S radius, S eps)
314 : _center1(center1-.5*eps*normalize(normal)),
315 _center2(_center1 + eps*normalize(normal)),
316 _ba(_center2 - _center1),
317 _baba(_ba[0]*_ba[0] + _ba[1]*_ba[1] + _ba[2]*_ba[2]),
318 _radius2(radius*radius), _length(util::sqrt(_baba))
319{
320 // cylinder defined by the centers of the two extremities and the radius
321 // _I,_J,_K is the new base where _K is the axe of the cylinder0
322 init();
323}
324
326template <typename S>
328 : _center1(circleF.getCenter() - .5*eps*circleF.getNormal()),
329 _center2(_center1 + eps*circleF.getNormal()),
330 _ba(_center2 - _center1),
331 _baba(_ba[0]*_ba[0] + _ba[1]*_ba[1] + _ba[2]*_ba[2]),
332 _radius2(circleF.getRadius()*circleF.getRadius()), _length(util::sqrt(_baba))
333{
334 // cylinder defined by the centers of the two extremities and the radius
335 // _I,_J,_K is the new base where _K is the axe of the cylinder0
336 init();
337}
338
339// returns true if x is inside the cylinder
340template <typename S>
341bool IndicatorCylinder3D<S>::operator()(bool output[], const S input[])
342{
343 Vector<S,3> pa(Vector<S,3>(input) - _center1);
344
345 S X = _I[0]*pa[0] + _I[1]*pa[1] + _I[2]*pa[2];
346 S Y = _J[0]*pa[0] + _J[1]*pa[1] + _J[2]*pa[2];
347 S Z = _K[0]*pa[0] + _K[1]*pa[1] + _K[2]*pa[2];
348
349 // X^2 + Y^2 <= _radius2
350 output[0] = ( Z <= _length && Z >= 0 && X*X + Y*Y <= _radius2 );
351 return output[0];
352}
353
354template <typename S>
356{
357 _K = _ba / _length;
358
359 // _I and _J form an orthonormal base with _K
360 if ( util::approxEqual(_center2[1],_center1[1]) && util::approxEqual(_center2[0],_center1[0]) ) {
361 if ( util::approxEqual(_center2[2],_center1[2]) ) {
362 OstreamManager clout = OstreamManager(std::cout,"IndicatorCylinder3D");
363 clout << "Warning: in the cylinder, the two centers have the same coordinates" << std::endl;
364 clout << _center1 << std::endl;
365 clout << _center2 << std::endl;
366 }
367 _I = {1,0,0};
368 _J = {0,1,0};
369 }
370 else {
371 S normi = util::sqrt (_K[1]*_K[1]+_K[0]*_K[0]);
372 _I = {-_K[1]/normi, _K[0]/normi,0};
373 _J = {_K[1]*_I[2] - _K[2]*_I[1], _K[2]*_I[0] - _K[0]*_I[2], _K[0]*_I[1] - _K[1]*_I[0]};
374 }
375
376 double r = util::sqrt(_radius2);
377
378 S maxx= _center1[0] + util::sqrt(_I[0]*_I[0]+_J[0]*_J[0])*r + util::max(_K[0]*_length, 0.);
379 S minx= _center1[0] - util::sqrt(_I[0]*_I[0]+_J[0]*_J[0])*r + util::min(_K[0]*_length, 0.);
380
381 S maxy= _center1[1] + util::sqrt(_I[1]*_I[1]+_J[1]*_J[1])*r + util::max(_K[1]*_length, 0.);
382 S miny= _center1[1] - util::sqrt(_I[1]*_I[1]+_J[1]*_J[1])*r + util::min(_K[1]*_length, 0.);
383
384 S maxz= _center1[2] + util::sqrt(_I[2]*_I[2]+_J[2]*_J[2])*r + util::max(_K[2]*_length, 0.);
385 S minz= _center1[2] - util::sqrt(_I[2]*_I[2]+_J[2]*_J[2])*r + util::min(_K[2]*_length, 0.);
386
387 this->_myMin = {minx, miny, minz};
388 this->_myMax = {maxx, maxy, maxz};
389}
390
391
392
393template <typename S>
395{
396 return _center1;
397}
398
399template <typename S>
401{
402 return _center2;
403}
404
405template <typename S>
407{
408 return util::sqrt(_radius2);
409}
410
411template <typename S>
413{
414 return sdf::cylinder(input, _center1, _ba, _baba, util::sqrt(_radius2));
415}
416
417template <typename S>
418Vector<S,3> IndicatorCylinder3D<S>::getSample(const std::function<S()>& randomness) const
419{
420 // Select random point on center axis
421 auto axis = _center2 - _center1;
422 auto axisPoint = _center1 + (_center2 - _center1) * randomness();
423 // Compute cut at point on center axis
424 auto hyperplane = Hyperplane3D<S>().originAt(axisPoint)
425 .normalTo(axis);
426 // Select random point on 2D circle
427 const S r = util::sqrt(_radius2) * util::sqrt(randomness());
428 const S theta = randomness() * 2 * M_PI;
429 // Project random circle point to axis-orthogonal plane with axisPoint intersect
430 return hyperplane.project({r * util::cos(theta),
431 r * util::sin(theta)});
432}
433
434//TODO: Rename to IndicatorCappedCone3D and create a real IndicatorCone3D ??
435
436// cone defined by the centers of the two extremities and the radiuses of the two extremities
437// the 2nd radius is optional: if it is not defined, the 2nd center is the vertex of the cone
438template <typename S>
440 S radius1, S radius2)
441 : _center1(center1), _center2(center2),
442 _ba(center2 - center1), _baba(_ba*_ba),
443 _radius1(radius1), _radius2(radius2),
444 _length(util::sqrt((_center2 - _center1)*(_center2 - _center1)))
445{
446 // _I,_J,_K is the new base where _K is the axe of the cone
447 _K = (_center2 - _center1)/_length;
448
449 // _I and _J form an orthonormal base with _K
450 if ( util::approxEqual(_center2[1],_center1[1]) && util::approxEqual(_center2[0],_center1[0]) ) {
451 if ( util::approxEqual(_center2[2],_center1[2]) ) {
452 OstreamManager clout = OstreamManager(std::cout,"IndicatorCone3D");
453 clout << "Warning: in the cone, the two centers have the same coordinates" << std::endl;
454 clout << _center1 << std::endl;
455 clout << _center2 << std::endl;
456 }
457 _I = {1,0,0};
458 _J = {0,1,0};
459 }
460 else {
461 S normi = util::sqrt(_K[1]*_K[1] + _K[0]*_K[0]);
462 _I = {-_K[1]/normi, _K[0]/normi,0};
463 _J = {_K[1]*_I[2] - _K[2]*_I[1], _K[2]*_I[0] - _K[0]*_I[2], _K[0]*_I[1] - _K[1]*_I[0]};
464 }
465
466 S maxx= _center1[0] + util::max( util::sqrt(_I[0]*_I[0]+_J[0]*_J[0])*_radius1,
467 util::sqrt(_I[0]*_I[0]+_J[0]*_J[0])*_radius2 + _K[0]*_length);
468 S minx= _center1[0] + util::min(-util::sqrt(_I[0]*_I[0]+_J[0]*_J[0])*_radius1,
469 -util::sqrt(_I[0]*_I[0]+_J[0]*_J[0])*_radius2 + _K[0]*_length);
470
471 S maxy= _center1[1] + util::max( util::sqrt(_I[1]*_I[1]+_J[1]*_J[1])*_radius1,
472 util::sqrt(_I[1]*_I[1]+_J[1]*_J[1])*_radius2 + _K[1]*_length);
473 S miny= _center1[1] + util::min(-util::sqrt(_I[1]*_I[1]+_J[1]*_J[1])*_radius1,
474 -util::sqrt(_I[1]*_I[1]+_J[1]*_J[1])*_radius2 + _K[1]*_length);
475
476 S maxz= _center1[2] + util::max( util::sqrt(_I[2]*_I[2]+_J[2]*_J[2])*_radius1,
477 util::sqrt(_I[2]*_I[2]+_J[2]*_J[2])*_radius2 + _K[2]*_length);
478 S minz= _center1[2] + util::min(-util::sqrt(_I[2]*_I[2]+_J[2]*_J[2])*_radius1,
479 -util::sqrt(_I[2]*_I[2]+_J[2]*_J[2])*_radius2 + _K[2]*_length);
480
481 this->_myMin = {minx, miny, minz};
482 this->_myMax = {maxx, maxy, maxz};
483}
484
485// returns true if x is inside the cone(Vector<S,3> center1, Vector<S,3> center2, S radius1
486template <typename S>
487bool IndicatorCone3D<S>::operator()(bool output[], const S input[])
488{
489 // radius: the radius of the cone at the point x
490 Vector<S,3> pa(Vector<S,3>(input) - _center1);
491 S X = _I[0]*pa[0] + _I[1]*pa[1] + _I[2]*pa[2];
492 S Y = _J[0]*pa[0] + _J[1]*pa[1] + _J[2]*pa[2];
493 S Z = _K[0]*pa[0] + _K[1]*pa[1] + _K[2]*pa[2];
494 S radius = _radius1 + (_radius2 - _radius1)*Z / _length;
495
496 output[0] = ( Z <= _length && Z >= 0 && X*X + Y*Y <= radius*radius );
497 return true;
498}
499
500template <typename S>
502{
503 return _center1;
504}
505
506template <typename S>
508{
509 return _center2;
510}
511
512template <typename S>
514{
515 return _radius1;
516}
517
518template <typename S>
520{
521 return _radius2;
522}
523
524template <typename S>
526{
527 return sdf::cone(input, _center1, _ba, _baba, _radius1, _radius2);
528}
529
530template <typename S>
532 : _center(center), _radius(radius)
533{
534#ifdef OLB_DEBUG
535 OstreamManager clout(std::cout, "IndicatorEllipsoid3D");
536 clout << "WARNING: The indicator doesn't provide an exact signed distance function." << std::endl;
537#endif
538
539 assert(_radius[0]>0 && _radius[1]>0 && _radius[2]>0);
540
541 this->_myMin = center - radius;
542 this->_myMax = center + radius;
543}
544
545template <typename S>
547{
548 return _radius;
549}
550
551template <typename S>
553{
554 return _center;
555}
556
557template <typename S>
559{
560 Vector<S,3> p = input - _center;
561 return sdf::ellipsoid(p, _radius);
562}
563
564template <typename S>
565IndicatorSuperEllipsoid3D<S>::IndicatorSuperEllipsoid3D(Vector<S,3> center, S xHalfAxis, S yHalfAxis, S zHalfAxis, S exponent1, S exponent2)
566 : _center(center), _xHalfAxis(xHalfAxis), _yHalfAxis(yHalfAxis), _zHalfAxis(zHalfAxis), _exp1(exponent1), _exp2(exponent2)
567{
568 assert(_xHalfAxis>0 && _yHalfAxis>0 && _zHalfAxis>0);
569
570 S max_axis = util::max( xHalfAxis, util::max(yHalfAxis, zHalfAxis) );
571 this->_myMin = {
572 center[0] - util::sqrt(2.)*max_axis,
573 center[1] - util::sqrt(2.)*max_axis,
574 center[2] - util::sqrt(2.)*max_axis
575 };
576 this->_myMax = {
577 center[0] + util::sqrt(2.)*max_axis,
578 center[1] + util::sqrt(2.)*max_axis,
579 center[2] + util::sqrt(2.)*max_axis
580 };
581}
582
583template <typename S>
585{
586 return _center;
587}
588
589template <typename S>
591{
592 return _xHalfAxis;
593}
594
595template <typename S>
597{
598 return _yHalfAxis;
599}
600
601template <typename S>
603{
604 return _zHalfAxis;
605}
606
607template <typename S>
609{
610 return _exp1;
611}
612
613template <typename S>
615{
616 return _exp2;
617}
618
619template <typename S>
620bool IndicatorSuperEllipsoid3D<S>::operator()(bool output[], const S input[])
621{
622 S a = util::pow ( util::abs( (input[0] - _center[0]) / _xHalfAxis ), _exp1 );
623 S b = util::pow ( util::abs( (input[1] - _center[1]) / _yHalfAxis ), _exp1 );
624 S c = util::pow ( util::abs( (input[2] - _center[2]) / _zHalfAxis ), _exp2 );
625 S ab = util::pow( a+b, _exp2/_exp1 );
626
627 if ( (ab+c) <= 1. ) {
628 output[0] = 1.;
629 return true;
630 }
631
632 output[0] = 0.;
633 return false;
634}
635
636
637// Warning : the cuboid is only defined parallel to the plans x=0, y=0 and z=0 !!!
638// For other cuboids, please use the parallelepiped version
639template <typename S>
641 : _center(origin+.5*extend),_xLength(extend[0]), _yLength(extend[1]), _zLength(extend[2])
642{
643 assert(_xLength>0 && _yLength>0 && _zLength>0);
644
645 this->_myMin = origin;
646 this->_myMax = origin + extend;
647}
648
649template <typename S>
650IndicatorCuboid3D<S>::IndicatorCuboid3D(S xLength, S yLength, S zLength, Vector<S,3> center)
651 : _center(center), _xLength(xLength), _yLength(yLength), _zLength(zLength)
652{
653 assert(_xLength>0 && _yLength>0 && _zLength>0);
654
655 this->_myMin = {_center[0] - S{0.5}*_xLength, _center[1] - S{0.5}*_yLength, _center[2] - S{0.5}*_zLength};
656 this->_myMax = {_center[0] + S{0.5}*_xLength, _center[1] + S{0.5}*_yLength, _center[2] + S{0.5}*_zLength};
657}
658
659template <typename S>
661{
662 return _center;
663}
664
665template <typename S>
667{
668 return _xLength;
669}
670
671template <typename S>
673{
674 return _yLength;
675}
676
677template <typename S>
679{
680 return _zLength;
681}
682
683template <typename S>
684bool IndicatorCuboid3D<S>::operator()(bool output[], const S input[])
685{
686 // returns true if x is inside the cuboid
687 Vector<S,3> q = distanceXYZ(input);
688 Vector<S,3> eps = std::numeric_limits<BaseType<S>>::epsilon();
689 output[0] = ( q < eps );
690 return output[0];
691}
692
693template <typename S>
695{
696 return { S(util::abs(S(input[0] - _center[0])) - 0.5 * _xLength),
697 S(util::abs(S(input[1] - _center[1])) - 0.5 * _yLength),
698 S(util::abs(S(input[2] - _center[2])) - 0.5 * _zLength)
699 };
700}
701
702template <typename S>
704{
705 return sdf::box(input - _center, Vector<S,3>(.5*_xLength, .5*_yLength, .5*_zLength));
706}
707
708template <typename S>
709Vector<S,3> IndicatorCuboid3D<S>::getSample(const std::function<S()>& randomness) const
710{
711 // Select random point on center axis
712 Vector<S,3> v = {_xLength, _yLength, _zLength};
713 auto it = std::minmax_element(v.begin(), v.end());
714 int min_idx = std::distance(v.begin(), it.first);
715 Vector<S,3> axis{0, 0, 0};
716 axis[min_idx] = v[min_idx];
717 auto axisPoint = _center + axis * randomness();
718 // Compute cut at point on center axis
719 auto hyperplane = Hyperplane3D<S>().originAt(axisPoint)
720 .normalTo(axis);
721 // Select random point on 2D square
722 int max_idx = std::distance(v.begin(), it.second);
723 const S width = v[max_idx] * randomness();
724 int i = 3 - max_idx - min_idx;
725 const S height = v[i] * randomness();
726 // Project random square point to axis-orthogonal plane with axisPoint intersect
727 return hyperplane.project({width,height});
728}
729
730
731
732template <typename S>
734 : IndicatorCuboid3D<S>(extend, origin), _theta(theta), _plane(plane), _centerRotation(centerRotation)
735{
736 assert(plane==0 || plane==1 || plane==2);
737}
738
739template <typename S>
740IndicatorCuboidRotate3D<S>::IndicatorCuboidRotate3D(S xLength, S yLength, S zLength, Vector<S,3> origin, S theta, int plane, Vector<S,3> centerRotation)
741 : IndicatorCuboid3D<S>(xLength, yLength, zLength, origin), _theta(theta), _plane(plane), _centerRotation(centerRotation)
742{
743 assert(plane==0 || plane==1 || plane==2);
744}
745
746template <typename S>
747void IndicatorCuboidRotate3D<S>::transformInput(const S input[3], S newInput[3])
748{
749 //initialize for _plane == 2
750 int i=0;
751 int j=1;
752 if (_plane == 1) { // rotation around y axis
753 i=0;
754 j=2;
755 }
756 else if (_plane == 0) { // rotation around x axis
757 i=1;
758 j=2;
759 }
760 // translation to _centerRotation
761 S x = input[i] - _centerRotation[i];
762 S y = input[j] - _centerRotation[j];
763 // rotation of _theta in rad
764 S xx = x*util::cos(_theta) - y*util::sin(_theta);
765 S yy = x*util::sin(_theta) + y*util::cos(_theta);
766 // change back to standard coordinate system
767 x = xx + _centerRotation[i];
768 y = yy + _centerRotation[j];
769 newInput[_plane] = input[_plane];
770 newInput[i] = x;
771 newInput[j] = y;
772}
773
774// do transformation to axis aligned cuboid, then call operator() of basic cuboid.
775template <typename S>
776bool IndicatorCuboidRotate3D<S>::operator()(bool output[], const S input[])
777{
778 S newInput[3];
779 transformInput(input, newInput);
780 IndicatorCuboid3D<S>::operator()(output, newInput);
781 return output[0];
782}
783
784template <typename S>
786{
787 S newInput[3], tmp[3] = {input[0], input[1], input[2]};
788 transformInput(tmp, newInput);
790}
791
792
794template <typename S>
795std::shared_ptr<IndicatorF3D<S>> createIndicatorCircle3D(XMLreader const& params, bool verbose)
796{
797 OstreamManager clout(std::cout,"createIndicatorCircle3D");
798
799 Vector<S,3> center;
800 Vector<S,3> normal;
801 S radius = 1;
802
803 // params.setWarningsOn(false);
804 params.setWarningsOn(true);
805
806 std::stringstream xmlCenter1( params.getAttribute("center") );
807 xmlCenter1 >> center[0] >> center[1] >> center[2];
808 std::stringstream xmlCenter2( params.getAttribute("normal") );
809 xmlCenter2 >> normal[0] >> normal[1] >> normal[2];
810 std::stringstream xmlRadius( params.getAttribute("radius") );
811 xmlRadius >> radius;
812
813 return std::make_shared<IndicatorCircle3D<S>>(center, normal, radius);
814}
815
816template <typename S>
817std::shared_ptr<IndicatorF3D<S>> createIndicatorSphere3D(XMLreader const& params, bool verbose)
818{
819 OstreamManager clout(std::cout,"createIndicatorSphere3D");
820
821 Vector<S,3> center;
822 S radius = 1;
823
824 // params.setWarningsOn(false);
825 params.setWarningsOn(true);
826
827 std::stringstream xmlCenter1( params.getAttribute("center") );
828 xmlCenter1 >> center[0] >> center[1] >> center[2];
829 std::stringstream xmlRadius( params.getAttribute("radius") );
830 xmlRadius >> radius;
831
832 return std::make_shared<IndicatorSphere3D<S>>(center, radius);
833}
834
835// creator function for a cylinder3d
836template <typename S>
837std::shared_ptr<IndicatorF3D<S>> createIndicatorCylinder3D(XMLreader const& params, bool verbose)
838{
839 OstreamManager clout(std::cout,"createIndicatorCylinder3D");
840
841 Vector<S,3> center1;
842 Vector<S,3> center2(S(1),S(1),S(1));
843 S radius = 1;
844
845 // params.setWarningsOn(false);
846 // params.setWarningsOn(true);
847
848 std::stringstream xmlCenter1( (params).getAttribute("center1") );
849 xmlCenter1 >> center1[0] >> center1[1] >> center1[2];
850 std::stringstream xmlCenter2( (params).getAttribute("center2") );
851 xmlCenter2 >> center2[0] >> center2[1] >> center2[2];
852 std::stringstream xmlRadius( (params).getAttribute("radius") );
853 xmlRadius >> radius;
854
856// print(center1, "center1: ");
857// print(center2, "center2: ");
858// print(radius, "radius: ");
859
860 return std::make_shared<IndicatorCylinder3D<S>>(center1, center2, radius);
861}
862
863template <typename S>
864std::shared_ptr<IndicatorF3D<S>> createIndicatorCone3D(XMLreader const& params, bool verbose)
865{
866 OstreamManager clout(std::cout,"createIndicatorCone3D");
867
868 Vector<S,3> center1;
869 Vector<S,3> center2(S(1), S(1), S(1));
870 S radius1 = S(0);
871 S radius2 = S(1);
872
873 // params.setWarningsOn(false);
874 params.setWarningsOn(true);
875
876 std::stringstream xmlCenter1( params.getAttribute("center1") );
877 xmlCenter1 >> center1[0] >> center1[1] >> center1[2];
878 std::stringstream xmlCenter2( params.getAttribute("center2") );
879 xmlCenter2 >> center2[0] >> center2[1] >> center2[2];
880 std::stringstream xmlRadius1( params.getAttribute("radius1") );
881 xmlRadius1 >> radius1;
882 std::stringstream xmlRadius2( params.getAttribute("radius2") );
883 xmlRadius2 >> radius2;
884
885 return std::make_shared<IndicatorCone3D<S>>(center1, center2, radius1, radius2);
886}
887
888template <typename S>
889std::shared_ptr<IndicatorF3D<S>> createIndicatorCuboid3D(XMLreader const& params, bool verbose)
890{
891 OstreamManager clout(std::cout,"createIndicatorCuboid3D");
892
893 Vector<S,3> origin;
894 Vector<S,3> extend(S(1),S(1),S(1));
895
896 // params.setWarningsOn(false);
897 params.setWarningsOn(true);
898
899 std::stringstream xmlOrigin( params.getAttribute("origin") );
900 xmlOrigin >> origin[0] >> origin[1] >> origin[2];
901 std::stringstream xmlExtend( params.getAttribute("extend") );
902 xmlExtend >> extend[0] >> extend[1] >> extend[2];
903
904 return std::make_shared<IndicatorCuboid3D<S>>(extend, origin);
905}
906
907// Create Union with XML - file
908template <typename S>
909std::shared_ptr<IndicatorF3D<S>> createIndicatorUnion3D(XMLreader const& params, bool verbose)
910{
911 OstreamManager clout(std::cout,"createIndicatorUnion3D");
912
913 // clout << "xml position: " << params.getName() << std::endl;
914 // params.print(2);
915
916 std::shared_ptr<IndicatorF3D<S>> output = createIndicatorF3D<S>(**params.begin());
917 for (auto it = params.begin()+1; it != params.end(); ++it) {
918 output = output + createIndicatorF3D<S>(**it);
919 }
920 return output;
921}
922
923// Create Without with XML - file
924template <typename S>
925std::shared_ptr<IndicatorF3D<S>> createIndicatorWithout3D(XMLreader const& params, bool verbose)
926{
927 OstreamManager clout(std::cout,"createIndicatorWithout3D");
928
929 // clout << "xml position: " << params.getName() << std::endl;
930 // params.print(2);
931
932 std::shared_ptr<IndicatorF3D<S>> output = createIndicatorF3D<S>(**params.begin());
933 for (auto it = params.begin()+1; it != params.end(); ++it) {
934 output = output - createIndicatorF3D<S>(**it);
935 }
936 return output;
937}
938
939// Create Intersection with XML - file
940template <typename S>
941std::shared_ptr<IndicatorF3D<S>> createIndicatorIntersection3D(XMLreader const& params, bool verbose)
942{
943 OstreamManager clout(std::cout,"createIndicatorIntersection3D");
944
945 // clout << "xml position: " << params.getName() << std::endl;
946 // params.print(2);
947
948 std::shared_ptr<IndicatorF3D<S>> output = createIndicatorF3D<S>(**params.begin());
949 for (auto it = params.begin()+1; it != params.end(); ++it) {
950 output = output * createIndicatorF3D<S>(**it);
951 }
952 return output;
953}
954
955// Create Geometry
956template <typename S>
957std::shared_ptr<IndicatorF3D<S>> createIndicatorF3D(XMLreader const& params, bool verbose)
958{
959 OstreamManager clout(std::cout,"createIndicatorF3D");
960
961 // clout << "XML element: "<< params.getName() << std::endl;
962 // params.print(2);
963
964 std::string actualName = params.getName();
965 if ( actualName == "IndicatorCircle3D" ) {
966 return createIndicatorCircle3D<S>(params);
967 }
968 else if ( actualName == "IndicatorSphere3D" ) {
969 return createIndicatorSphere3D<S>(params);
970 }
971 else if ( actualName == "IndicatorCylinder3D" ) {
972 return createIndicatorCylinder3D<S>(params);
973 }
974 else if ( actualName == "IndicatorCone3D" ) {
975 return createIndicatorCone3D<S>(params);
976 }
977 else if ( actualName == "IndicatorCuboid3D" ) {
978 return createIndicatorCuboid3D<S>(params);
979 }
980 else if ( actualName == "IndicatorUnion3D" ) {
981 return createIndicatorUnion3D<S>(params);
982 }
983 else if ( actualName == "IndicatorWithout3D" ) {
984 return createIndicatorWithout3D<S>(params);
985 }
986 else if ( actualName == "IndicatorIntersection3D" ) {
987 return createIndicatorIntersection3D<S>(params);
988 }
989 else {
990 auto firstChild = params.begin(); // get iterator of childTree
991 return createIndicatorF3D<S>( **firstChild );
992 }
993}
994
995template <typename T>
997 : _f(f)
998{}
999
1000template <typename T>
1001bool IndicatorSDF3D<T>::operator()(bool output[], const T input[])
1002{
1003 output[0] = _f(input) <= 0.0;
1004 return true;
1005}
1006
1007
1008} // namespace olb
1009
1010#endif
#define M_PI
Smart pointer for managing the various ways of passing functors around.
Definition functorPtr.h:60
indicator function for a 3D circle
Vector< S, 3 > const & getCenter() const
IndicatorCircle3D(Vector< S, 3 > center, Vector< S, 3 > normal, S radius)
Vector< S, 3 > const & getNormal() const
bool operator()(bool output[], const S input[]) override
has to be implemented for 'every' derived class
Vector< S, 3 > const & getCenter1() const
IndicatorCone3D(Vector< S, 3 > center1, Vector< S, 3 > center2, S radius1, S radius2=0)
S signedDistance(const Vector< S, 3 > &input) override
Returns signed distance to the nearest point on the indicator surface.
Vector< S, 3 > const & getCenter2() const
bool operator()(bool output[], const S input[]) override
has to be implemented for 'every' derived class
indicator function for a 3d-cuboid, parallel to the planes x=0, y=0, z=0.
Vector< S, 3 > const & getCenter() const
S const getxLength() const
IndicatorCuboid3D(Vector< S, 3 > extend, Vector< S, 3 > origin)
constructs an cuboid with x axis from origin[0] to origin[0]+extend[0], ...
S const getyLength() const
S const getzLength() const
Vector< S, 3 > getSample(const std::function< S()> &randomness) const override
S signedDistance(const Vector< S, 3 > &input) override
Returns signed distance to the nearest point on the indicator surface.
bool operator()(bool output[], const S input[]) override
returns true if input is inside, otherwise false
indicator function for a 3d-cuboid, turned by an angle theta around an axis of rotation
S signedDistance(const Vector< S, 3 > &input) override
Returns signed distance to the nearest point on the indicator surface.
bool operator()(bool output[], const S input[])
returns true if input is inside, otherwise false
IndicatorCuboidRotate3D(Vector< S, 3 > extend, Vector< S, 3 > origin, S theta, int plane, Vector< S, 3 > centerRotation)
indicator function for a 3d-cylinder
IndicatorCylinder3D(Vector< S, 3 > center1, Vector< S, 3 > center2, S radius)
Indicator function for a cylinder.
Vector< S, 3 > const & getCenter1() const
bool operator()(bool output[], const S input[]) override
has to be implemented for 'every' derived class
Vector< S, 3 > getSample(const std::function< S()> &randomness) const override
S signedDistance(const Vector< S, 3 > &input) override
Returns signed distance to the nearest point on the indicator surface.
Vector< S, 3 > const & getCenter2() const
Vector< S, 3 > const & getCenter() const
Vector< S, 3 > const & getRadius() const
S signedDistance(const Vector< S, 3 > &input) override
Returns signed distance to the nearest point on the indicator surface.
IndicatorEllipsoid3D(Vector< S, 3 > center, Vector< S, 3 > radius)
IndicatorF3D is an application from .
virtual Vector< S, 3 > & getMax()
Vector< S, 3 > _myMin
virtual Vector< S, 3 > & getMin()
Vector< S, 3 > _myMax
IndicatorInternal3D(IndicatorF3D< S > &indicatorF, S layerSize)
bool operator()(bool output[], const S input[]) override
has to be implemented for 'every' derived class
S signedDistance(const Vector< S, 3 > &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
IndicatorLayer3D(FunctorPtr< IndicatorF3D< S > > &&indicatorF, S layerSize)
bool operator()(bool output[], const T input[]) override
IndicatorSDF3D(std::function< T(Vector< T, 3 >)> f)
indicator function for a 3D-sphere
Vector< S, 3 > const & getCenter() const
IndicatorSphere3D(Vector< S, 3 > center, S radius)
S signedDistance(const Vector< S, 3 > &input) override
Returns signed distance to the nearest point on the indicator surface.
S const getRadius() const
bool distance(S &distance, const Vector< S, 3 > &origin, const Vector< S, 3 > &direction, int iC=-1) override
Vector< S, 3 > const & getCenter() const
IndicatorSuperEllipsoid3D(Vector< S, 3 > center, S xHalfAxis, S yHalfAxis, S zHalfAxis, S exponent1, S exponent2)
bool operator()(bool output[], const S input[]) override
has to be implemented for 'every' derived class
Vector< S, 3 > & getMin() override
bool operator()(bool output[], const S input[]) override
has to be implemented for 'every' derived class
S signedDistance(const Vector< S, 3 > &input) override
Returns signed distance to the nearest point on the indicator surface.
IndicatorTranslate3D(std::array< S, 3 > translate, IndicatorF3D< S > &indicator)
Vector< S, 3 > & getMax() override
class for marking output with some text
Plain old scalar vector.
Definition vector.h:47
constexpr auto begin()
Definition vector.h:171
constexpr auto end()
Definition vector.h:176
std::string getAttribute(const std::string &aName) const
Definition xmlReader.h:541
std::vector< XMLreader * >::const_iterator begin() const
Returns an iterator.begin() of the child XMLreader This means an iterator to the next level on an XML...
Definition xmlReader.h:392
std::string getName() const
return the name of the element
Definition xmlReader.h:402
void setWarningsOn(bool warnings) const
switch warnings on/off
Definition xmlReader.h:412
std::vector< XMLreader * >::const_iterator end() const
Returns an iterator.end() of the child XMLreader This means an iterator to the next level on an XML t...
Definition xmlReader.h:397
This file contains indicator functions.
T rounding(T a, T r) any_platform
Computes a layer of a constant thickness around the surface.
Definition sdf.h:372
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
Vector< T, D > translate(Vector< T, D > p, Vector< T, D > origin) any_platform
Translation: The output of this function is used for the calculation of the signed distance to transl...
Definition sdf.h:299
T cone(Vector< T, 3 > p, Vector< T, 3 > a, Vector< T, 3 > ba, T baba, T ra, T rb) any_platform
Exact signed distance to the surface of three-dimensional (capped) cone.
Definition sdf.h:210
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
T ellipsoid(Vector< T, 3 > p, Vector< T, 3 > r) any_platform
Calculate the NOT EXACT (!) signed distance to the surface of three-dimensional ellipsoid.
Definition sdf.h:253
T cylinder(Vector< T, 3 > p, Vector< T, 3 > a, Vector< T, 3 > ba, T baba, T r) any_platform
Exact signed distance to the surface of three-dimensional cylinder.
Definition sdf.h:172
cpu::simd::Pack< T > sqrt(cpu::simd::Pack< T > value)
Definition pack.h:100
ADf< T, DIM > abs(const ADf< T, DIM > &a)
Definition aDiff.h:1019
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
ADf< T, DIM > cos(const ADf< T, DIM > &a)
Definition aDiff.h:578
Top level namespace for all of OpenLB.
std::shared_ptr< IndicatorF3D< S > > createIndicatorF3D(XMLreader const &params, bool verbose=false)
std::shared_ptr< IndicatorF3D< S > > createIndicatorIntersection3D(XMLreader const &params, bool verbose=false)
std::shared_ptr< IndicatorF3D< S > > createIndicatorCylinder3D(XMLreader const &params, bool verbose=false)
std::shared_ptr< IndicatorF3D< S > > createIndicatorUnion3D(XMLreader const &params, bool verbose=false)
std::shared_ptr< IndicatorF3D< S > > createIndicatorSphere3D(XMLreader const &params, bool verbose=false)
std::shared_ptr< IndicatorF3D< S > > createIndicatorCone3D(XMLreader const &params, bool verbose=false)
std::shared_ptr< IndicatorF3D< S > > createIndicatorCircle3D(XMLreader const &params, bool verbose=false)
std::shared_ptr< IndicatorF3D< S > > createIndicatorCuboid3D(XMLreader const &params, bool verbose=false)
std::shared_ptr< IndicatorF3D< S > > createIndicatorWithout3D(XMLreader const &params, bool verbose=false)
constexpr Vector< T, D > normalize(const ScalarVector< T, D, IMPL > &a, T scale=T{1})
Definition vector.h:245
Definition of a analytical 2D plane embedded in 3D space.
Hyperplane3D & normalTo(const Vector< T, 3 > &normal)
Calculate the spanning vectors of the hyperplane to be orthogonal to the given normal.
Hyperplane3D & originAt(const Vector< T, 3 > &origin)
Center the hyperplane at the given origin vector.