OpenLB 1.7
Loading...
Searching...
No Matches
smoothIndicatorBaseF3D.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, Albert Mink, 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_3D_HH
25#define SMOOTH_INDICATOR_BASE_F_3D_HH
26
27#include "utilities/omath.h"
28
31
32namespace olb {
33
34
35template <typename T, typename S>
37 : AnalyticalF3D<T,S>(1),
38 _myMin(S()), _myMax(S()), _pos(S()), _rotMat(S()), _circumRadius(S()),
39 _theta(S()), _epsilon(S())
40{ }
41
42template <typename T, typename S>
44{
45 _rotMat = util::calculateInverseRotationMatrix<T,3>( this->_theta );
46}
47
48template <typename T, typename S>
50{
51 return _myMin;
52}
53
54template <typename T, typename S>
56{
57 return _myMax;
58}
59
60template <typename T, typename S>
62{
63 return _pos;
64}
65
66template <typename T, typename S>
68{
69 return _circumRadius;
70}
71
72template <typename T, typename S>
74{
75 return _rotMat;
76}
77
78template <typename T, typename S>
80{
81 return _theta;
82}
83
84template <typename T, typename S>
86{
87 return _epsilon;
88}
89
90template <typename T, typename S>
92{
93 return _name;
94}
95
96template <typename T, typename S>
98{
99 _pos = pos;
100}
101
102template <typename T, typename S>
104{
105 _theta = theta;
106 init();
107}
108
109template <typename T, typename S>
111{
112 _epsilon = epsilon;
113}
114
115template <typename T, typename S>
117{
118 // TODO: Fallback
119 assert(false);
120 return S(std::numeric_limits<BaseType<S>>::quiet_NaN());
121}
122
123template <typename T, typename S>
125{
126 // TODO: Fallback
127 assert(false);
128 return Vector<S,4>(std::numeric_limits<BaseType<S>>::quiet_NaN());
129}
130
131template <typename T, typename S>
133{
134 // TODO: Fallback
135 assert(false);
136 return Vector<S,3>(std::numeric_limits<BaseType<S>>::quiet_NaN());
137}
138
139template <typename T, typename S>
140bool SmoothIndicatorF3D<T, S, false>::operator()( T output[], const S input[] )
141{
142 T const signedDist = this->signedDistance(input);
143 return sdf::evalSolidVolumeFraction(output, signedDist, this->getEpsilon());
144}
145
146template <typename T, typename S>
148{
149 return norm(input-this->getPos()) <= this->getCircumRadius();
150}
151
152template <typename T, typename S>
154{
155 return surfaceNormal(pos, meshSize, [&](const Vector<S,3>& pos) {
156 return pos;
157 });
158}
159
160template <typename T, typename S>
162 std::function<Vector<S,3>(const Vector<S,3>&)> transformPos )
163{
164 return util::surfaceNormal(pos, meshSize, [&](const Vector<S,3>& pos) {
165 return this->signedDistance( transformPos(pos) );
166 });
167}
168
169template <typename T, typename S>
171{
172 // TODO: Raymarching as fallback
173 assert(false);
174 return std::numeric_limits<double>::quiet_NaN();
175}
176
177template <typename T, typename S>
178bool SmoothIndicatorF3D<T, S, false>::distance(S& distance, const Vector<S,3>& origin, const Vector<S,3>& direction, S precision, S pitch)
179{
180 S const halfEps = this->getEpsilon() * 0.5;
181 bool originValue;
182 bool currentValue;
183
184 // start at origin and move into given direction
185 PhysR<S,3> currentPoint(origin);
186
187 originValue = this->signedDistance(origin) <= halfEps;
188 currentValue = this->signedDistance(currentPoint) <= halfEps;
189
190 while (currentValue == originValue && this->isInsideCircumRadius(currentPoint)) {
191 currentPoint += direction;
192 // update currentValue until the first point on the other side (inside/outside) is found
193 currentValue = this->signedDistance(currentPoint) <= halfEps;
194 }
195
196 // return false if no point was found in given direction
197 if (!this->isInsideCircumRadius(currentPoint) && !originValue) {
198 return false;
199 }
200
201
202 while (pitch >= precision) {
203 if (!this->isInsideCircumRadius(currentPoint) && originValue) {
204 currentPoint -= pitch * direction;
205 pitch /= 2.;
206 }
207 else {
208 currentValue = this->signedDistance(currentPoint) <= halfEps;
209 if (currentValue == originValue) {
210 currentPoint += pitch * direction;
211 pitch /= 2.;
212 }
213 else {
214 currentPoint -= pitch * direction;
215 pitch /= 2.;
216 }
217 }
218 }
219
220 distance = norm(currentPoint - origin);
221 return true;
222}
223
224
225// identity to "store results"
226template <typename T, typename S>
228 : _f(f)
229{
230 this->_myMin = _f.getMin();
231 this->_myMax = _f.getMax();
232 std::swap( _f._ptrCalcC, this->_ptrCalcC );
233}
234
235template <typename T, typename S>
236bool SmoothIndicatorIdentity3D<T,S>::operator() (T output[], const S input[])
237{
238 _f(output, input);
239 return true;
240}
241
243
244template <typename T, typename S>
246 : AnalyticalF3D<T,S>(1),
247 _circumRadius(S()), _epsilon(S())
248{ }
249
250template <typename T, typename S>
251bool SmoothIndicatorF3D<T, S, true>::operator()( T output[], const S input[] )
252{
253#ifdef OLB_DEBUG
254 OstreamManager clout(std::cout, "SmoothIndicator3D");
255 clout << "WARNING: SmoothIndicatorF3D::operator() a particle (= true) SmoothIndicator does not consider the current position of the particle. Please use the evalSolidVolumeFraction method for this." << std::endl;
256#endif
257 T const signedDist = this->signedDistance(input);
258 return sdf::evalSolidVolumeFraction(output, signedDist, this->getEpsilon());
259}
260
261template <typename T, typename S>
263{
264 return norm(input) <= this->getCircumRadius();
265}
266
267template <typename T, typename S>
269{
270 return surfaceNormal(pos, meshSize, [&](const Vector<S,3>& pos) {
271 return pos;
272 });
273}
274
275template <typename T, typename S>
277 std::function<Vector<S,3>(const Vector<S,3>&)> transformPos )
278{
279 return util::surfaceNormal(pos, meshSize, [&](const Vector<S,3>& pos) {
280 return this->signedDistance( transformPos(pos) );
281 });
282}
283
284template <typename T, typename S>
286{
287 // TODO: Raymarching as fallback
288 assert(false);
289 return std::numeric_limits<double>::quiet_NaN();
290}
291
292template <typename T, typename S>
293bool SmoothIndicatorF3D<T, S, true>::distance(S& distance, const Vector<S,3>& origin, const Vector<S,3>& direction, S precision, S pitch)
294{
295 S const halfEps = this->getEpsilon() * 0.5;
296 bool originValue;
297 bool currentValue;
298
299 // start at origin and move into given direction
300 PhysR<S,3> currentPoint(origin);
301
302 originValue = this->signedDistance(origin) <= halfEps;
303 currentValue = this->signedDistance(currentPoint) <= halfEps;
304
305 while (currentValue == originValue && this->isInsideCircumRadius(currentPoint)) {
306 currentPoint += direction;
307 // update currentValue until the first point on the other side (inside/outside) is found
308 currentValue = this->signedDistance(currentPoint) <= halfEps;
309 }
310
311 // return false if no point was found in given direction
312 if (!this->isInsideCircumRadius(currentPoint) && !originValue) {
313 return false;
314 }
315
316
317 while (pitch >= precision) {
318 if (!this->isInsideCircumRadius(currentPoint) && originValue) {
319 currentPoint -= pitch * direction;
320 pitch /= 2.;
321 }
322 else {
323 currentValue = this->signedDistance(currentPoint) <= halfEps;
324 if (currentValue == originValue) {
325 currentPoint += pitch * direction;
326 pitch /= 2.;
327 }
328 else {
329 currentPoint -= pitch * direction;
330 pitch /= 2.;
331 }
332 }
333 }
334
335 distance = norm(currentPoint - origin);
336 return true;
337}
338
339template <typename T, typename S>
341{
342 return _circumRadius;
343}
344
345template <typename T, typename S>
347{
348 return _epsilon;
349}
350
351template <typename T, typename S>
353{
354 return _name;
355}
356
357template <typename T, typename S>
359{
360 _epsilon = epsilon;
361}
362
363template <typename T, typename S>
365{
366 // TODO: Fallback
367 assert(false);
368 return std::numeric_limits<double>::quiet_NaN();
369}
370
371template <typename T, typename S>
373{
374 // TODO: Fallback
375 assert(false);
376 return S(std::numeric_limits<BaseType<S>>::quiet_NaN());
377}
378
379template <typename T, typename S>
381{
382 // TODO: Fallback
383 assert(false);
384 return S(std::numeric_limits<BaseType<S>>::quiet_NaN());
385}
386
387} // namespace olb
388
389
390#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
bool operator()(T output[], const S input[]) override
has to be implemented for 'every' derived class
SmoothIndicatorF3D< T, S, false > & _f
SmoothIndicatorIdentity3D(SmoothIndicatorF3D< T, S, false > &f)
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.