OpenLB 1.7
Loading...
Searching...
No Matches
setBouzidiZeroVelocityBoundary2D.hh
Go to the documentation of this file.
1/* This file is part of the OpenLB library
2 *
3 * Copyright (C) 2020 Alexander Schulz
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 the Bouzidi Zero Velocity Boundary
25//This is an offLattice Boundary
26//This is a new version of the Boundary, which only contains free floating functions
27#ifndef SET_BOUZIDI_ZERO_VELOCITY_BOUNDARY_2D_HH
28#define SET_BOUZIDI_ZERO_VELOCITY_BOUNDARY_2D_HH
29
31
32namespace olb {
33
34namespace legacy {
35
37
39template<typename T, typename DESCRIPTOR, class MixinDynamics>
41 IndicatorF2D<T>& geometryIndicator,
42 std::vector<int> bulkMaterials)
43{
44 setBouzidiZeroVelocityBoundary<T,DESCRIPTOR,MixinDynamics>(sLattice, superGeometry.getMaterialIndicator(material),
45 superGeometry.getMaterialIndicator(std::move(bulkMaterials)),
46 geometryIndicator);
47
48
49}
50
52template<typename T, typename DESCRIPTOR, class MixinDynamics>
54 FunctorPtr<SuperIndicatorF2D<T>>&& bulkIndicator,
55 IndicatorF2D<T>& geometryIndicator)
56{
57 //out of superOffBoundary2D
58 T _epsFraction = 0.0001;
59 OstreamManager clout(std::cout, "setBouzidiZeroVelocityBoundary");
60 int _overlap = 1;
61
62 clout << "epsFraction=" << _epsFraction << std::endl;
63 clout.setMultiOutput(true);
64 for (int iCloc = 0; iCloc < sLattice.getLoadBalancer().size(); ++iCloc) {
65 clout << "Cuboid globiC " << sLattice.getLoadBalancer().glob(iCloc)
66 << " starts to read distances for ZeroVelocity Boundary..." << std::endl;
67 setBouzidiZeroVelocityBoundary<T,DESCRIPTOR,MixinDynamics>(sLattice.getBlock(iCloc),
68 boundaryIndicator->getBlockIndicatorF(iCloc),
69 bulkIndicator->getBlockIndicatorF(iCloc),
70 geometryIndicator);
71 clout << "Cuboid globiC " << sLattice.getLoadBalancer().glob(iCloc)
72 << " finished reading distances for ZeroVelocity Boundary." << std::endl;
73 }
74 clout.setMultiOutput(false);
76 addPoints2CommBC<T,DESCRIPTOR>(sLattice, std::forward<decltype(boundaryIndicator)>(boundaryIndicator), _overlap);
77}
78
79
81//the functions below set the boundary on indicated cells inside the block domain
82
83template<typename T, typename DESCRIPTOR, class MixinDynamics>
85{
86 block.forSpatialLocations([&](auto iX, auto iY) {
87 if (boundaryIndicator(iX,iY)) {
88 setBouzidiZeroVelocityBoundary<T,DESCRIPTOR,MixinDynamics>(block,
89 bulkIndicator.getBlockGeometry(),
90 iX, iY,
91 bulkIndicator,
92 geometryIndicator);
93 }
94 });
95}
96
97
98template<typename T, typename DESCRIPTOR, class MixinDynamics>
99void setBouzidiZeroVelocityBoundary(BlockLattice<T,DESCRIPTOR>& block, BlockGeometry<T,2>& blockGeometryStructure, int iX, int iY, BlockIndicatorF2D<T>& bulkIndicator, IndicatorF2D<T>& geometryIndicator)
100{
101 OstreamManager clout(std::cout, "setBouzidiZeroVelocityBoundary");
102 T _epsFraction = 0.0001;
103 T distances[DESCRIPTOR::q];
104 std::fill(std::begin(distances), std::end(distances), -1);
105
106 for (int iPop = 1; iPop < DESCRIPTOR::q ; ++iPop) {
107 const Vector<int,2> c = descriptors::c<DESCRIPTOR>(iPop);
108 const int iXn = iX + c[0];
109 const int iYn = iY + c[1];
110 if (blockGeometryStructure.isInside(iXn,iYn)) {
111 if (bulkIndicator(iXn,iYn)) {
112 T dist = -1;
113 T physR[2];
114 blockGeometryStructure.getPhysR(physR,{iXn,iYn});
115 T voxelSize=blockGeometryStructure.getDeltaR();
116 Vector<T,2> physC(physR);
117
118 Vector<T,2> direction(-voxelSize*descriptors::c<DESCRIPTOR >(iPop,0),-voxelSize*descriptors::c<DESCRIPTOR >(iPop,1));
119 T cPhysNorm = voxelSize*util::sqrt(descriptors::c<DESCRIPTOR >(iPop,0)*descriptors::c<DESCRIPTOR >(iPop,0)+descriptors::c<DESCRIPTOR >(iPop,1)*descriptors::c<DESCRIPTOR >(iPop,1));
120
121 if (!geometryIndicator.distance(dist,physC,direction,blockGeometryStructure.getIcGlob() ) ) {
122 T epsX = voxelSize*descriptors::c<DESCRIPTOR >(iPop,0)*_epsFraction;
123 T epsY = voxelSize*descriptors::c<DESCRIPTOR >(iPop,1)*_epsFraction;
124
125 Vector<T,2> physC2(physC);
126 physC2[0] += epsX;
127 physC2[1] += epsY;
128 Vector<T,2> direction2(direction);
129 direction2[0] -= 2.*epsX;
130 direction2[1] -= 2.*epsY;
131
132 if ( !geometryIndicator.distance(dist,physC2,direction2,blockGeometryStructure.getIcGlob())) {
133 clout << "ERROR: no boundary found at (" << iXn << "," << iYn <<") ~ ("
134 << physR[0] << "," << physR[1] << "), "
135 << "in direction " << descriptors::opposite<DESCRIPTOR >(iPop)
136 << std::endl;
137 }
138 T distNew = (dist - util::sqrt(epsX*epsX+epsY*epsY))/cPhysNorm;
139 if (distNew < 0.5) {
140 dist = 0;
141 }
142 else {
143 dist = 0.5 * cPhysNorm;
144 clout << "WARNING: distance at (" << iXn << "," << iYn <<") ~ ("
145 << physR[0] << "," << physR[1] <<"), "
146 << "in direction " << descriptors::opposite<DESCRIPTOR >(iPop) << ": "
147 << distNew
148 << " rounded to "
149 << dist/cPhysNorm
150 << std::endl;
151 }
152 }
153 distances[descriptors::opposite<DESCRIPTOR >(iPop)] = dist/cPhysNorm;
154 }
155 else {
156 if (blockGeometryStructure.getMaterial({iXn,iYn}) != 0) {
157 auto postProcessor = std::unique_ptr<ZeroVelocityBounceBackPostProcessorGenerator2D<T,DESCRIPTOR>>{new ZeroVelocityBounceBackPostProcessorGenerator2D<T,DESCRIPTOR>(iXn, iYn, descriptors::opposite<DESCRIPTOR>(iPop), 0)};
158 block.addPostProcessor(*postProcessor);
159 }
160 }
161 } // bulk indicator
162 } // iPop loop
163 setBouzidiZeroVelocityBoundary<T,DESCRIPTOR,MixinDynamics>(block, blockGeometryStructure, iX, iY, distances);
164}
165
166
167template<typename T, typename DESCRIPTOR, class MixinDynamics>
168void setBouzidiZeroVelocityBoundary(BlockLattice<T,DESCRIPTOR>& block, BlockGeometry<T,2>& blockGeometryStructure, int x, int y, T distances[DESCRIPTOR::q])
169{
170 for (int iPop = 1; iPop < DESCRIPTOR::q ; ++iPop) {
171 if ( !util::nearZero(distances[iPop]+1) ) {
172 const Vector<int,2> c = descriptors::c<DESCRIPTOR>(iPop);
173 setBouzidiZeroVelocityBoundary<T,DESCRIPTOR,MixinDynamics>(block, blockGeometryStructure, x-c[0], y-c[1], iPop, distances[iPop]);
174 }
175 }
176}
177
178//set postProcessor on indicated cells
179template<typename T, typename DESCRIPTOR, class MixinDynamics>
180void setBouzidiZeroVelocityBoundary(BlockLattice<T,DESCRIPTOR>& block, BlockGeometry<T,2>& blockGeometryStructure, int x, int y, int iPop, T dist)
181{
182 auto postProcessor = std::unique_ptr<PostProcessorGenerator2D<T, DESCRIPTOR>>{ nullptr };
183 const Vector<int,2> c = descriptors::c<DESCRIPTOR>(iPop);
184
185 if (blockGeometryStructure.getMaterial({x-c[0], y-c[1]}) != 1) {
186 postProcessor.reset(new ZeroVelocityBounceBackPostProcessorGenerator2D<T,DESCRIPTOR>(x, y, iPop, dist));
187 }
188 else {
189 postProcessor.reset(new ZeroVelocityBouzidiLinearPostProcessorGenerator2D<T,DESCRIPTOR>(x, y, iPop, dist));
190 }
191
192 if (postProcessor && !block.isPadding({x,y})) {
193 block.addPostProcessor(*postProcessor);
194 }
195}
196
197}
198
199}//namespace olb
200
201#endif
Representation of a block geometry.
Vector< T, D > getPhysR(LatticeR< D > latticeR)
int getMaterial(LatticeR< D > latticeR) const
returns the (iX,iY) entry in the 2D scalar field
int getIcGlob() const
Read only access to the global iC number which is given !=-1 if the block geometries are part of a su...
T getDeltaR() const
Read only access to the voxel size given in SI units (meter)
Base block indicator functor (discrete)
BlockGeometry< T, 2 > & getBlockGeometry()
Get underlying block geometry structure.
Platform-abstracted block lattice for external access and inter-block interaction.
virtual void addPostProcessor(std::type_index stage, LatticeR< DESCRIPTOR::d > latticeR, PostProcessorPromise< T, DESCRIPTOR > &&promise)=0
Schedule post processor for application to latticeR in stage.
void forSpatialLocations(F f) const
bool isPadding(LatticeR< D > latticeR) const
Return whether location is valid.
bool isInside(LatticeR< D > latticeR) const
Return whether location is valid.
Smart pointer for managing the various ways of passing functors around.
Definition functorPtr.h:60
IndicatorF2D is an application from .
virtual bool distance(S &distance, const Vector< S, 2 > &origin, S precision, const Vector< S, 2 > &direction)
returns false or true and pos. distance if there was one found for an given origin and direction
class for marking output with some text
void setMultiOutput(bool b)
enable message output for all MPI processes, disabled by default
Representation of a statistic for a parallel 2D geometry.
std::unique_ptr< SuperIndicatorF< T, D > > getMaterialIndicator(std::vector< int > &&materials)
Returns a material indicator using the given vector of materials.
Super class maintaining block lattices for a cuboid decomposition.
BlockLattice< T, DESCRIPTOR > & getBlock(int locC)
Return BlockLattice with local index locC.
LoadBalancer< T > & getLoadBalancer()
Read and write access to the load balancer.
Plain old scalar vector.
Definition vector.h:47
void setBouzidiZeroVelocityBoundary(SuperLattice< T, DESCRIPTOR > &sLattice, SuperGeometry< T, 2 > &superGeometry, int material, IndicatorF2D< T > &geometryIndicator, std::vector< int > bulkMaterials=std::vector< int >(1, 1))
Set offDynamics with boundary links and post processors using indicators.
cpu::simd::Pack< T > sqrt(cpu::simd::Pack< T > value)
Definition pack.h:100
bool nearZero(const ADf< T, DIM > &a)
Definition aDiff.h:1087
Top level namespace for all of OpenLB.