27#ifndef SET_BOUZIDI_VELOCITY_BOUNDARY_2D_HH
28#define SET_BOUZIDI_VELOCITY_BOUNDARY_2D_HH
40template<
typename T,
typename DESCRIPTOR,
class MixinDynamics>
42 std::vector<int> bulkMaterials)
45 setBouzidiVelocityBoundary<T,DESCRIPTOR,MixinDynamics>(sLattice, superGeometry.
getMaterialIndicator(material),
51template<
typename T,
typename DESCRIPTOR,
class MixinDynamics>
56 T _epsFraction = 0.0001;
66 clout <<
"epsFraction=" << _epsFraction << std::endl;
68 for (
int iCloc = 0; iCloc < sLattice.
getLoadBalancer().size(); ++iCloc) {
70 <<
" starts to read distances for Velocity Boundary..." << std::endl;
71 setBouzidiVelocityBoundary<T,DESCRIPTOR,MixinDynamics>(sLattice.
getBlock(iCloc),boundaryIndicator->getBlockIndicatorF(iCloc),
72 bulkIndicator->getBlockIndicatorF(iCloc),
75 <<
" finished reading distances for Velocity Boundary." << std::endl;
79 addPoints2CommBC<T,DESCRIPTOR>(sLattice, std::forward<
decltype(boundaryIndicator)>(boundaryIndicator), _overlap);
86template<
typename T,
typename DESCRIPTOR,
class MixinDynamics>
90 if (boundaryIndicator(iX,iY)) {
91 setBouzidiVelocityBoundary<T,DESCRIPTOR,MixinDynamics>(block,
100template<
typename T,
typename DESCRIPTOR,
class MixinDynamics>
103 T _epsFraction = 0.0001;
105 T distances[DESCRIPTOR::q];
106 for (
int iPop = 1; iPop < DESCRIPTOR::q ; ++iPop) {
107 distances[iPop] = -1;
110 for (
int iPop = 1; iPop < DESCRIPTOR::q ; ++iPop) {
111 const int iXn = iX + descriptors::c<DESCRIPTOR >(iPop,0);
112 const int iYn = iY + descriptors::c<DESCRIPTOR >(iPop,1);
113 if (blockGeometryStructure.
isInside(iXn,iYn) && bulkIndicator(iXn,iYn)) {
116 blockGeometryStructure.
getPhysR(physR,{iXn,iYn});
117 T voxelSize=blockGeometryStructure.
getDeltaR();
120 Vector<T,2> direction(-voxelSize*descriptors::c<DESCRIPTOR >(iPop,0),-voxelSize*descriptors::c<DESCRIPTOR >(iPop,1));
121 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));
123 if (!geometryIndicator.
distance(dist,physC,direction,blockGeometryStructure.
getIcGlob() ) ) {
124 T epsX = voxelSize*descriptors::c<DESCRIPTOR >(iPop,0)*_epsFraction;
125 T epsY = voxelSize*descriptors::c<DESCRIPTOR >(iPop,1)*_epsFraction;
131 direction2[0] -= 2.*epsX;
132 direction2[1] -= 2.*epsY;
134 if ( !geometryIndicator.
distance(dist,physC2,direction2,blockGeometryStructure.
getIcGlob())) {
135 clout <<
"ERROR: no boundary found at (" << iXn <<
"," << iYn <<
") ~ ("
136 << physR[0] <<
"," << physR[1] <<
"), "
137 <<
"in direction " << descriptors::opposite<DESCRIPTOR >(iPop)
140 T distNew = (dist -
util::sqrt(epsX*epsX+epsY*epsY))/cPhysNorm;
145 dist = 0.5 * cPhysNorm;
146 clout <<
"WARNING: distance at (" << iXn <<
"," << iYn <<
") ~ ("
147 << physR[0] <<
"," << physR[1] <<
"), "
148 <<
"in direction " << descriptors::opposite<DESCRIPTOR >(iPop) <<
": "
155 distances[descriptors::opposite<DESCRIPTOR >(iPop)] = dist/cPhysNorm;
158 setBouzidiVelocityBoundary<T,DESCRIPTOR,MixinDynamics>(block, blockGeometryStructure, iX, iY, distances);
162template<
typename T,
typename DESCRIPTOR,
class MixinDynamics>
165 typedef DESCRIPTOR L;
166 T location[DESCRIPTOR::d];
167 blockGeometryStructure.
getPhysR(location, {x,y});
169 T distancesCopy[L::q];
170 T spacing = blockGeometryStructure.
getDeltaR();
171 for (
int iPop = 1; iPop < L::q ; ++iPop) {
172 distancesCopy[iPop] = spacing*(1.-distances[iPop]);
174 distancesCopy[iPop] = -1;
178 setOffDynamics<T,DESCRIPTOR,MixinDynamics>(block, x, y, location, distancesCopy);
180 for (
int iPop = 1; iPop < L::q ; ++iPop) {
182 setBouzidiVelocityBoundary<T,DESCRIPTOR,MixinDynamics>(block, blockGeometryStructure, x-descriptors::c<L>(iPop,0), y-descriptors::c<L>(iPop,1), iPop, distances[iPop]);
189template<
typename T,
typename DESCRIPTOR,
class MixinDynamics>
193 if (blockGeometryStructure.
getMaterial({x-descriptors::c<DESCRIPTOR >(iPop,0), y-descriptors::c<DESCRIPTOR >(iPop,1)}) != 1) {
203 if (postProcessor && !block.
isPadding({x,y})) {
209template<
typename T,
typename DESCRIPTOR,
class MixinDynamics>
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 defineDynamics(LatticeR< DESCRIPTOR::d > latticeR, DynamicsPromise< T, DESCRIPTOR > &&promise)
Assign promised DYNAMICS to latticeR.
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.
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.
Dynamics for offLattice boundary conditions OffDynamics are basically NoLatticeDynamics with the addi...
void setOffDynamics(BlockLattice< T, DESCRIPTOR > &block, int x, int y, T location[DESCRIPTOR::d], T distances[DESCRIPTOR::q])
void setBouzidiVelocityBoundary(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)
bool nearZero(const ADf< T, DIM > &a)
Top level namespace for all of OpenLB.
Interface for per-cell dynamics.