OpenLB 1.7
Loading...
Searching...
No Matches
smoothIndicatorInteraction.h
Go to the documentation of this file.
1/* This file is part of the OpenLB library
2 *
3 * Copyright (C) 2021 Nicolas Hafen, 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/* This file contains functions used for the calculation of particle related dynamics.
25 *
26*/
27
28#ifndef SMOOTHINDICATOR_INTERACTION_H
29#define SMOOTHINDICATOR_INTERACTION_H
30
31#include "core/blockStructure.h"
36
37namespace olb {
38
39namespace particles {
40
41namespace resolved {
42
43template <typename T, typename S, typename PARTICLETYPE>
45 const PhysR<S, PARTICLETYPE::d>& input)
46{
47 using namespace descriptors;
48 constexpr unsigned D = PARTICLETYPE::d;
49
50 const PhysR<T, D> position = particle.template getField<GENERAL, POSITION>();
51 if constexpr (PARTICLETYPE::template providesNested<SURFACE, ROT_MATRIX>()) {
53 util::invertRotationMatrix<T, D>(
54 particle.template getField<SURFACE, ROT_MATRIX>());
55 return util::executeRotation<T, D, true>(input, rotationMatrix, position);
56 }
57 else {
58 return input - position;
59 }
60
61 __builtin_unreachable();
62}
63
64template <typename T, typename S, typename PARTICLETYPE>
67 const PhysR<S, PARTICLETYPE::d>& direction)
68{
69 constexpr unsigned D = PARTICLETYPE::d;
70 using namespace descriptors;
71
72 if constexpr (PARTICLETYPE::template providesNested<SURFACE, ROT_MATRIX>()) {
74 util::invertRotationMatrix<T, D>(
75 particle.template getField<SURFACE, ROT_MATRIX>());
76 return util::executeRotation<T, D>(direction, rotationMatrix);
77 }
78 else {
79 return direction;
80 }
81
82 __builtin_unreachable();
83}
84
85template <typename T, typename S, typename PARTICLETYPE>
87 const PhysR<S, PARTICLETYPE::d>& input)
88{
89 using namespace descriptors;
90 auto sIndicator = access::getSmoothIndicatorPtr(particle);
91 return norm(access::getPosition(particle) - input) <=
92 sIndicator->getCircumRadius();
93}
94
95template <typename T, typename S, typename PARTICLETYPE>
97 const PhysR<S, PARTICLETYPE::d>& input)
98{
99 using namespace descriptors;
100 auto sIndicator = access::getSmoothIndicatorPtr(particle);
101
102 if (!isInsideCircumRadius(particle, input)) {
103 return false;
104 }
105
106 PhysR<S, PARTICLETYPE::d> newInput = transformInput(particle, input);
107 return sIndicator->signedDistance(newInput) <= 0;
108}
109
110template <typename T, typename S, typename PARTICLETYPE>
112 const PhysR<S, PARTICLETYPE::d>& input)
113{
114 using namespace descriptors;
115 auto sIndicator = particle.template getField<SURFACE, SINDICATOR>();
116 PhysR<S, PARTICLETYPE::d> newInput = transformInput(particle, input);
117
118 //Check whether elongation provided
119 if constexpr (access::providesElongation<PARTICLETYPE>()) {
120 const unsigned D = PARTICLETYPE::d;
121 //Retrieve original sdf
122 std::function<S(const Vector<S, D>&)> sdf =
123 [&sIndicator](const Vector<S, D>& input) {
124 return sIndicator->signedDistance(input);
125 };
126 //Retrieve elongation
127 auto elongation = access::getElongation(particle);
128 //Return elongated whapper
129 constexpr bool symmetryCheck = false; //User responsibility here.
130 return sdf::elongation<T, symmetryCheck>(sdf, newInput, elongation);
131 }
132 else {
133 return sIndicator->signedDistance(newInput);
134 }
135}
136
137template <typename T, typename S, typename PARTICLETYPE>
139 const Vector<S, PARTICLETYPE::d>& origin,
140 const Vector<S, PARTICLETYPE::d>& direction,
141 S precision, S pitch)
142{
143 using namespace descriptors;
144 auto sIndicator = particle.template getField<SURFACE, SINDICATOR>();
145 PhysR<S, PARTICLETYPE::d> input = transformInput(particle, origin);
146 PhysR<S, PARTICLETYPE::d> dir = transformDirection(particle, direction);
147
148 T distance(T(0.));
149 if (util::distance(
150 distance, input, dir, precision, pitch,
151 [&](bool output[1], const T input[3]) {
152 output[0] = sIndicator->signedDistance(
153 PhysR<T, PARTICLETYPE::d>(input)) <= 0;
154 return output[0];
155 },
156 [&](const Vector<T, 3>& pos) {
157 // bigger bounding box is usually necessary
158 return norm(pos) <= 1.5 * sIndicator->getCircumRadius();
159 })) {
160 return distance;
161 }
162 else {
163#ifdef OLB_DEBUG
164 OstreamManager clout(std::cout, "distanceCalculation");
165 clout << "WARNING: Distance to particle in direction "
166 << normalize(direction) << " couldn't be calculated." << std::endl;
167#endif
168 return T(0.);
169 }
170
171 __builtin_unreachable();
172}
173
174template <typename T, typename S, typename PARTICLETYPE>
176 const Vector<S, PARTICLETYPE::d>& origin,
177 const Vector<S, PARTICLETYPE::d>& direction,
178 S precision)
179{
180 using namespace descriptors;
181 auto sIndicator = particle.template getField<SURFACE, SINDICATOR>();
182 PhysR<S, PARTICLETYPE::d> input = transformInput(particle, origin);
183 PhysR<S, PARTICLETYPE::d> dir = transformDirection(particle, direction);
184
185 T distance(T(0.));
186 if (util::distance(
187 distance, input, dir, precision,
188 [&](const Vector<T, PARTICLETYPE::d>& input) {
189 return sIndicator->signedDistance(input);
190 },
191 [&](const Vector<T, PARTICLETYPE::d>& pos) {
192 // bigger bounding box is usually necessary
193 return norm(pos) <= 1.5 * sIndicator->getCircumRadius();
194 })) {
195 return distance;
196 }
197 else {
198#ifdef OLB_DEBUG
199 OstreamManager clout(std::cout, "distanceCalculation");
200 clout << "WARNING: Distance to particle in direction "
201 << normalize(direction) << " couldn't be calculated." << std::endl;
202#endif
203 return T(0.);
204 }
205
206 __builtin_unreachable();
207}
208
209template <typename T, typename S, typename PARTICLETYPE>
212 const Vector<S, PARTICLETYPE::d>& pos, const T meshSize)
213{
214 using namespace descriptors;
215 constexpr unsigned D = PARTICLETYPE::d;
216 auto sIndicator = particle.template getField<SURFACE, SINDICATOR>();
217
218 // the following gives us the option to overload the calculation of the surface normal for different indicators
219 return sIndicator->surfaceNormal(pos, meshSize, [&](const Vector<S, D>& pos) {
220 return transformInput(particle, pos);
221 });
222}
223
224template <typename T, typename S, typename PARTICLETYPE>
225bool evalSolidVolumeFraction(T output[], const S input[],
227{
228 using namespace descriptors;
229 auto sIndicator = particle.template getField<SURFACE, SINDICATOR>();
230 T const signedDist =
232 return sdf::evalSolidVolumeFraction(output, signedDist,
233 sIndicator->getEpsilon());
234}
235
236} //namespace resolved
237
238} //namespace particles
239
240} //namespace olb
241
242#endif
class for marking output with some text
Plain old scalar vector.
Definition vector.h:47
Vector< T, PARTICLETYPE::d > getElongation(Particle< T, PARTICLETYPE > particle)
auto getSmoothIndicatorPtr(Particle< T, PARTICLETYPE > particle)
Vector< T, PARTICLETYPE::d > getPosition(Particle< T, PARTICLETYPE > particle)
PhysR< S, PARTICLETYPE::d > transformDirection(Particle< T, PARTICLETYPE > &particle, const PhysR< S, PARTICLETYPE::d > &direction)
const S distanceToParticle(Particle< T, PARTICLETYPE > &particle, const Vector< S, PARTICLETYPE::d > &origin, const Vector< S, PARTICLETYPE::d > &direction, S precision, S pitch)
bool isInsideCircumRadius(Particle< T, PARTICLETYPE > &particle, const PhysR< S, PARTICLETYPE::d > &input)
PhysR< S, PARTICLETYPE::d > transformInput(Particle< T, PARTICLETYPE > &particle, const PhysR< S, PARTICLETYPE::d > &input)
Vector< S, PARTICLETYPE::d > normalOnParticleSurface(Particle< T, PARTICLETYPE > &particle, const Vector< S, PARTICLETYPE::d > &pos, const T meshSize)
bool isInsideParticle(Particle< T, PARTICLETYPE > &particle, const PhysR< S, PARTICLETYPE::d > &input)
const S signedDistanceToParticle(Particle< T, PARTICLETYPE > &particle, const PhysR< S, PARTICLETYPE::d > &input)
bool evalSolidVolumeFraction(T output[], const S input[], Particle< T, PARTICLETYPE > &particle)
bool evalSolidVolumeFraction(T output[], T signedDist, T eps) any_platform
Definition sdf.h:453
bool distance(S &distance, const Vector< S, D > &origin, const Vector< S, D > &direction, S precision, S pitch, F1 isInside, F2 isInsideBoundingBox)
Top level namespace for all of OpenLB.
constexpr T norm(const ScalarVector< T, D, IMPL > &a)
Euclidean vector norm.
constexpr Vector< T, D > normalize(const ScalarVector< T, D, IMPL > &a, T scale=T{1})
Definition vector.h:245