OpenLB 1.7
Loading...
Searching...
No Matches
smoothIndicatorBaseF2D.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, Benjamin Förster
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 SMOOTH_INDICATOR_BASE_F_2D_HH
25#define SMOOTH_INDICATOR_BASE_F_2D_HH
26
27#include "utilities/omath.h"
28
30
31namespace olb {
32
33
34template <typename T, typename S>
36 : AnalyticalF2D<T,S>(1),
37 _myMin(S()), _myMax(S()), _pos(S()), _rotMat(S()), _circumRadius(S()), _theta(S()), _epsilon(S())
38{ }
39
40template <typename T, typename S>
42{
43 _rotMat = util::calculateInverseRotationMatrix<T,2>( Vector<T,1>(this->_theta) );
44}
45
46template <typename T, typename S>
48{
49 return _myMin;
50}
51
52template <typename T, typename S>
54{
55 return _myMax;
56}
57
58template <typename T, typename S>
60{
61 return _pos;
62}
63
64template <typename T, typename S>
66{
67 return _rotMat;
68}
69
70template <typename T, typename S>
72{
73 return _circumRadius;
74}
75
76template <typename T, typename S>
78{
79 return _theta;
80}
81
82template <typename T, typename S>
84{
85 return _epsilon;
86}
87
88template <typename T, typename S>
90{
91 return _name;
92}
93
94template <typename T, typename S>
96{
97 _pos = pos;
98}
99
100template <typename T, typename S>
102{
103 _theta = theta;
104 init();
105}
106
107template <typename T, typename S>
109{
110 _epsilon = epsilon;
111}
112
113template <typename T, typename S>
115{
116 // TODO: Fallback
117 assert(false);
118 return S(std::numeric_limits<BaseType<S>>::quiet_NaN());
119}
120
121template <typename T, typename S>
123{
124 // TODO: Fallback
125 assert(false);
126 return Vector<S,2>(std::numeric_limits<BaseType<S>>::quiet_NaN());
127}
128
129template <typename T, typename S>
131{
132 return surfaceNormal(pos, meshSize, [&](const Vector<S,2>& pos) {
133 return pos;
134 });
135}
136
137template <typename T, typename S>
139 std::function<Vector<S,2>(const Vector<S,2>&)> transformPos )
140{
141 return util::surfaceNormal(pos, meshSize, [&](const Vector<S,2>& pos) {
142 return this->signedDistance( transformPos(pos) );
143 });
144}
145
146template <typename T, typename S>
148{
149 // TODO: Raymarching as fallback
150 assert(false);
151 return std::numeric_limits<double>::quiet_NaN();
152}
153
154template <typename T, typename S>
155bool SmoothIndicatorF2D<T, S, false>::distance(S& distance, const Vector<S,2>& origin, const Vector<S,2>& direction, S precision, S pitch)
156{
157 S const halfEps = this->getEpsilon() * 0.5;
158 bool originValue;
159 bool currentValue;
160
161 // start at origin and move into given direction
162 PhysR<S,2> currentPoint(origin);
163
164 originValue = this->signedDistance(origin) <= halfEps;
165 currentValue = this->signedDistance(currentPoint) <= halfEps;
166
167 while (currentValue == originValue && this->isInsideCircumRadius(currentPoint)) {
168 currentPoint += direction;
169 // update currentValue until the first point on the other side (inside/outside) is found
170 currentValue = this->signedDistance(currentPoint) <= halfEps;
171 }
172
173 // return false if no point was found in given direction
174 if (!this->isInsideCircumRadius(currentPoint) && !originValue) {
175 return false;
176 }
177
178
179 while (pitch >= precision) {
180 if (!this->isInsideCircumRadius(currentPoint) && originValue) {
181 currentPoint -= pitch * direction;
182 pitch /= 2.;
183 }
184 else {
185 currentValue = this->signedDistance(currentPoint) <= halfEps;
186 if (currentValue == originValue) {
187 currentPoint += pitch * direction;
188 pitch /= 2.;
189 }
190 else {
191 currentPoint -= pitch * direction;
192 pitch /= 2.;
193 }
194 }
195 }
196
197 distance = norm(currentPoint - origin);
198 return true;
199}
200
201template <typename T, typename S>
202bool SmoothIndicatorF2D<T, S, false>::operator()( T output[], const S input[] )
203{
204 T const signedDist = this->signedDistance(input);
205 return sdf::evalSolidVolumeFraction(output, signedDist, this->getEpsilon());
206}
207
208template <typename T, typename S>
210{
211 return norm(input) <= this->getCircumRadius();
212}
213
214
215// identity to "store results"
216template <typename T, typename S>
218 : _f(f)
219{
220 this->_myMin = _f.getMin();
221 this->_myMax = _f.getMax();
222 std::swap( _f._ptrCalcC, this->_ptrCalcC );
223}
224
225template <typename T, typename S>
226bool SmoothIndicatorIdentity2D<T,S>::operator() (T output[], const S input[])
227{
228 _f(output, input);
229 return true;
230}
231
233
234template <typename T, typename S>
236 : AnalyticalF2D<T,S>(1),
237 _circumRadius(S()), _epsilon(S())
238{ }
239
240template <typename T, typename S>
242{
243 return _circumRadius;
244}
245
246template <typename T, typename S>
248{
249 return _epsilon;
250}
251
252template <typename T, typename S>
254{
255 return _name;
256}
257
258template <typename T, typename S>
260{
261 _epsilon = epsilon;
262}
263
264template <typename T, typename S>
266{
267 // TODO: Fallback
268 assert(false);
269 return std::numeric_limits<double>::quiet_NaN();
270}
271
272template <typename T, typename S>
274{
275 // TODO: Fallback
276 assert(false);
277 return S(std::numeric_limits<BaseType<S>>::quiet_NaN());
278}
279
280template <typename T, typename S>
282{
283 return surfaceNormal(pos, meshSize, [&](const Vector<S,2>& pos) {
284 return pos;
285 });
286}
287
288template <typename T, typename S>
290 std::function<Vector<S,2>(const Vector<S,2>&)> transformPos )
291{
292 return util::surfaceNormal(pos, meshSize, [&](const Vector<S,2>& pos) {
293 return this->signedDistance( transformPos(pos) );
294 });
295}
296
297template <typename T, typename S>
299{
300 // TODO: Raymarching as fallback
301 assert(false);
302 return std::numeric_limits<double>::quiet_NaN();
303}
304
305template <typename T, typename S>
306bool SmoothIndicatorF2D<T, S, true>::distance(S& distance, const Vector<S,2>& origin, const Vector<S,2>& direction, S precision, S pitch)
307{
308 S const halfEps = this->getEpsilon() * 0.5;
309 bool originValue;
310 bool currentValue;
311
312 // start at origin and move into given direction
313 PhysR<S,2> currentPoint(origin);
314
315 originValue = this->signedDistance(origin) <= halfEps;
316 currentValue = this->signedDistance(currentPoint) <= halfEps;
317
318 while (currentValue == originValue && this->isInsideCircumRadius(currentPoint)) {
319 currentPoint += direction;
320 // update currentValue until the first point on the other side (inside/outside) is found
321 currentValue = this->signedDistance(currentPoint) <= halfEps;
322 }
323
324 // return false if no point was found in given direction
325 if (!this->isInsideCircumRadius(currentPoint) && !originValue) {
326 return false;
327 }
328
329
330 while (pitch >= precision) {
331 if (!this->isInsideCircumRadius(currentPoint) && originValue) {
332 currentPoint -= pitch * direction;
333 pitch /= 2.;
334 }
335 else {
336 currentValue = this->signedDistance(currentPoint) <= halfEps;
337 if (currentValue == originValue) {
338 currentPoint += pitch * direction;
339 pitch /= 2.;
340 }
341 else {
342 currentPoint -= pitch * direction;
343 pitch /= 2.;
344 }
345 }
346 }
347
348 distance = norm(currentPoint - origin);
349 return true;
350}
351
352template <typename T, typename S>
353bool SmoothIndicatorF2D<T, S, true>::operator()( T output[], const S input[] )
354{
355#ifdef OLB_DEBUG
356 OstreamManager clout(std::cout, "SmoothIndicator2D");
357 clout << "WARNING: SmoothIndicatorF2D::operator() a particle (= true) SmoothIndicator does not consider the current position of the particle. Please use the evalSolidVolumeFraction method for this." << std::endl;
358#endif
359 T const signedDist = this->signedDistance(input);
360 return sdf::evalSolidVolumeFraction(output, signedDist, this->getEpsilon());
361}
362
363template <typename T, typename S>
365{
366 return norm(input) <= this->getCircumRadius();
367}
368
369} // namespace olb
370
371#endif
AnalyticalF are applications from DD to XD, where X is set by the constructor.
std::shared_ptr< GenericF< T, S > > _ptrCalcC
memory management, frees resouces (calcClass)
Definition genericF.h:71
class for marking output with some text
SmoothIndicatorIdentity2D(SmoothIndicatorF2D< T, S, false > &f)
SmoothIndicatorF2D< T, S, false > & _f
bool operator()(T output[], const S input[]) override
has to be implemented for 'every' derived class
Plain old scalar vector.
Definition vector.h:47
bool evalSolidVolumeFraction(T output[], T signedDist, T eps) any_platform
Definition sdf.h:453
Vector< S, D > surfaceNormal(const Vector< S, D > &pos, const S meshSize, F1 sdf)
Top level namespace for all of OpenLB.
typename util::BaseTypeHelper< T >::type BaseType
Definition baseType.h:59
constexpr T norm(const ScalarVector< T, D, IMPL > &a)
Euclidean vector norm.