OpenLB 1.7
Loading...
Searching...
No Matches
boundaryHandling.h
Go to the documentation of this file.
1/* This file is part of the OpenLB library
2 *
3 * Copyright (C) 2022 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
25
26#ifndef PARTICLE_BOUNDARY_HANDLING_H
27#define PARTICLE_BOUNDARY_HANDLING_H
28
29
30namespace olb {
31
32namespace particles {
33
34namespace boundaries {
35
36
37//Return normal on closest surface specified by solid boundary
38//-referenceLength: For particles, use circumRadius etc.
39template<typename T, unsigned D>
41 Vector<T,D>& position, T referenceLength )
42{
43 T delXofCentralDifference = 1.e-8*referenceLength;
44 return solidBoundary.getIndicator()->surfaceNormal(position, delXofCentralDifference);
45}
46
47template<typename T, typename PARTICLETYPE>
49 Particle<T,PARTICLETYPE>& particle )
50{
51 auto position = access::getPosition( particle );
52 auto radius = access::getRadius( particle );
53 return getNormalOnClosestSurface( solidBoundary, position, radius );
54}
55
64template<bool useCubicBounds=false, typename T, typename PARTICLETYPE, typename F>
68 F f )
69{
70 using namespace descriptors;
71 //Retrieve quantities
72 auto position = access::getPosition( particle );
73 T radius = access::getRadius( particle );
74 //VERSION A: Use signed distance functions of indicator
75 if constexpr (!useCubicBounds){
76 T distToWall = solidBoundary.getIndicator()->signedDistance(position)-radius;
77 if (distToWall<=0){
78
79 if constexpr (std::is_invocable_v<F,Particle<T,PARTICLETYPE>&,Vector<T,PARTICLETYPE::d>&,T>){
80 auto normal = getNormalOnClosestSurface( solidBoundary, position, radius );
81 T penetrationDepth = -distToWall;
82 f( particle, normal, penetrationDepth );
83 } else if constexpr (std::is_invocable_v<F,Particle<T,PARTICLETYPE>&,Vector<T,PARTICLETYPE::d>&>){
84 auto normal = getNormalOnClosestSurface( solidBoundary, position, radius );
85 f( particle, normal );
86 } else {
87 f( particle );
88 }
89
90 }
91 }
92 //VERSION B: Use origin and end of cubic indicator bounds (min, max)
93 else {
94 auto origin = solidBoundary.getIndicator()->getMin();
95 auto end = solidBoundary.getIndicator()->getMax();
96 for (int iDim=0; iDim<PARTICLETYPE::d; ++iDim){
97 T posParticleStart = position[iDim] - radius;
98 T posParticleEnd = position[iDim] + radius;
99 //Retrieve distance for lower and upper limit
100 T distToWallOrig = posParticleStart - origin[iDim];
101 T distToWallEnd = end[iDim] - posParticleEnd;
102 //Set up normal
103 Vector<T,PARTICLETYPE::d> normal(0.);
104 //Evaluate distances
105 if (distToWallOrig<=0){
106 normal[iDim] = 1;
107 if constexpr (std::is_invocable_v<F,Particle<T,PARTICLETYPE>&,Vector<T,PARTICLETYPE::d>&,T>){
108 T penetrationDepth = -distToWallOrig;
109 f( particle, normal, penetrationDepth );
110 } else if constexpr (std::is_invocable_v<F,Particle<T,PARTICLETYPE>&,Vector<T,PARTICLETYPE::d>&>){
111 f( particle, normal );
112 } else {
113 f( particle );
114 }
115 } else if (distToWallEnd<=0){
116 normal[iDim] = -1;
117 if constexpr (std::is_invocable_v<F,Particle<T,PARTICLETYPE>&,Vector<T,PARTICLETYPE::d>&,T>){
118 T penetrationDepth = -distToWallEnd;
119 f( particle, normal, penetrationDepth );
120 } else if constexpr (std::is_invocable_v<F,Particle<T,PARTICLETYPE>&,Vector<T,PARTICLETYPE::d>&>){
121 f( particle, normal );
122 } else {
123 f( particle );
124 }
125 }
126 }
127 } //constexpr if (!useCubicBounds)
128}
129
130
131//Orientation between given normal and closest surface of solid boundary
132// - usable for quantifying tilting of surface attached particles
133template<typename T, unsigned D>
135 SolidBoundary<T,D>& solidBoundary, Vector<T,D>& position,
136 Vector<T,D>& normalToBeComparedTo, T referenceLength )
137{
138 auto normalWall = getNormalOnClosestSurface( solidBoundary, position, referenceLength );
139 auto orientation = util::angleBetweenVectors( normalWall, normalToBeComparedTo );
140 return orientation;
141}
142
143} //namespace boundaries
144
145} //namespace particles
146
147} //namespace olb
148
149
150#endif
Plain old scalar vector.
Definition vector.h:47
T getRadius(Particle< T, PARTICLETYPE > &particle)
Vector< T, PARTICLETYPE::d > getPosition(Particle< T, PARTICLETYPE > particle)
Vector< T, D > getNormalOnClosestSurface(SolidBoundary< T, D > &solidBoundary, Vector< T, D > &position, T referenceLength)
Vector< T, utilities::dimensions::convert< D >::rotation > getRelativeSurfaceOrientation(SolidBoundary< T, D > &solidBoundary, Vector< T, D > &position, Vector< T, D > &normalToBeComparedTo, T referenceLength)
void doAtParticleWallContact(Particle< T, PARTICLETYPE > &particle, SolidBoundary< T, PARTICLETYPE::d > &solidBoundary, F f)
Generic treatment of particle wall contact.
T angleBetweenVectors(const Vector< T, 2 > &a, const Vector< T, 2 > &b)
Calculates angles between two 2D vectors.
Top level namespace for all of OpenLB.
IndicatorF< T, D > * getIndicator()
Definition wall.hh:42