/* This file is part of the OpenLB library * * Copyright (C) 2018 Marc Haussmann * E-mail contact: info@openlb.net * The most recent release of OpenLB can be downloaded at * * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program; if not, write to the Free * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef WALLFUNCTION_BOUNDARY_POST_PROCESSORS_3D_H #define WALLFUNCTION_BOUNDARY_POST_PROCESSORS_3D_H #include "core/postProcessing.h" #include "momentaOnBoundaries.h" #include "core/blockLattice3D.h" namespace olb { template struct wallFunctionParam { /* Used method for density reconstruction * 0: Zou-He * 1: extrapolation * 2: constant */ int rhoMethod = 1; /* Used method for non-equilibrium particle distribution reconstruction * 0: regularized NEBB (Latt) * 1: extrapolation NEQ (Guo Zhaoli) * 2: regularized second order finite Differnce * 3: equilibrium scheme */ int fneqMethod = 1; /* Used wall profile * 0: Musker profile * 1: power law profile */ int wallProfile = 0; /// check if descriptor with body force is used bool bodyForce; /// special formulation for straight boundaries bool curved = true; /// use van Driest damping function in boundary cell bool useVanDriest = true; /// von Karman constant for van Driest model T vonKarman = 0.375; /// wall distance in lattice units T latticeWalldistance = 0.5; }; /// Musker profile template class Musker : public AnalyticalF1D { private: T _nu; T _y; T _rho; public: Musker(T nu, T y, T rho); bool operator() (T output[], const S tau_w[]); }; /// PowerLaw profile template class PowerLawProfile : public AnalyticalF1D { private: T _nu; T _u2; T _y2; T _y1; T _rho; public: PowerLawProfile(T nu, T u2, T y2, T y1, T rho); bool operator() (T output[], const S tau_w[]); }; template class WallFunctionBoundaryProcessor3D : public LocalPostProcessor3D { public: WallFunctionBoundaryProcessor3D(int x0, int x1, int y0, int y1, int z0, int z1, BlockGeometryStructure3D& blockGeometryStructure, std::vector discreteNormal, std::vector missingIndices, UnitConverter const& converter, wallFunctionParam const& wallFunctionParam, IndicatorF3D* geoIndicator); virtual int extent() const { return 2; } virtual int extent(int whichDirection) const { return 2; } virtual void process(BlockLattice3D& blockLattice); virtual void processSubDomain ( BlockLattice3D& blockLattice, int x0_, int x1_, int y0_, int y1_, int z0_, int z1_ ); virtual void ComputeWallFunction(BlockLattice3D& blockLattice, int x, int y, int z); private: void getIndices(int index, int value, std::vector& indices); void calculateWallDistances(IndicatorF3D* indicator); // FD Difference Methods void VelGradFromSecondOrderFD(bool NormalGradient, T Vel_BC[DESCRIPTOR::d], T Vel_1[DESCRIPTOR::d], T Vel_2[DESCRIPTOR::d], T VelGrad[DESCRIPTOR::d]); void computeNeighborsU(BlockLattice3D& blockLattice, int x, int y, int z, T u_x1[DESCRIPTOR::d], T u_x2[DESCRIPTOR::d], T u_y1[DESCRIPTOR::d], T u_y2[DESCRIPTOR::d], T u_z1[DESCRIPTOR::d], T u_z2[DESCRIPTOR::d]); void computeVelocityGradientTensor(T u_bc[DESCRIPTOR::d], T u_x1[DESCRIPTOR::d], T u_x2[DESCRIPTOR::d], T u_y1[DESCRIPTOR::d], T u_y2[DESCRIPTOR::d], T u_z1[DESCRIPTOR::d], T u_z2[DESCRIPTOR::d], T VelGrad[DESCRIPTOR::d][DESCRIPTOR::d]); void computeVelocityGradient(BlockLattice3D& blockLattice, int x, int y, int z, T u_BC[DESCRIPTOR::d], T VelGrad[DESCRIPTOR::d][DESCRIPTOR::d]); void ComputeUWallNeighbor(BlockLattice3D& blockLattice, int x, int y, int z, T (&u)[DESCRIPTOR::d]); void computeNeighborsRho(BlockLattice3D& blockLattice, int x, int y, int z, T u_x1[DESCRIPTOR::d], T u_x2[DESCRIPTOR::d], T u_y1[DESCRIPTOR::d], T u_y2[DESCRIPTOR::d], T u_z1[DESCRIPTOR::d], T u_z2[DESCRIPTOR::d], T& rho_x1, T& rho_x2, T& rho_y1, T& rho_y2, T& rho_z1, T& rho_z2); void computeNeighborsRhoU(BlockLattice3D& blockLattice, int x, int y, int z, T u_x1[DESCRIPTOR::d], T u_x2[DESCRIPTOR::d], T u_y1[DESCRIPTOR::d], T u_y2[DESCRIPTOR::d], T u_z1[DESCRIPTOR::d], T u_z2[DESCRIPTOR::d], T& rho_x1, T& rho_x2, T& rho_y1, T& rho_y2, T& rho_z1, T& rho_z2); // Van Driest Method void computeVanDriestTauEff(T y_bc, T tau_w, T u_bc, T u_1, T u_2, T& tau_eff); // void ComputeUWall(BlockLattice3D& blockLattice, int x, int y, int z, T u[DESCRIPTOR::d]); void ComputeTauEff(BlockLattice3D& blockLattice, Cell& cell, int x, int y, int z, T u_bc[DESCRIPTOR::d]); void ComputeRhoWall(BlockLattice3D& blockLattice, Cell& cell, int x, int y, int z, T u_bc[DESCRIPTOR::d], T& rho_bc); // Methods FneqWall void computeRFneqfromFneq(T fneq_bc[DESCRIPTOR::q]); void computeFneqRNEBB(Cell& cell, T u_bc[DESCRIPTOR::d], T rho_bc, T fneq_bc[DESCRIPTOR::q]); void computeFneqENeq(BlockLattice3D& blockLattice, Cell& cell, int x, int y, int z, T u_bc[DESCRIPTOR::d], T rho_bc, T fneq_bc[DESCRIPTOR::q]); void computeFneqRSOFD(BlockLattice3D& blockLattice, Cell& cell, int x, int y, int z, T u_bc[DESCRIPTOR::d], T rho_bc, T fneq_bc[DESCRIPTOR::q]); void ComputeFneqWall(BlockLattice3D& blockLattice, Cell& cell, int x, int y, int z, T u_bc[DESCRIPTOR::d], T rho_bc, T fneq_bc[DESCRIPTOR::q]); int x0, x1, y0, y1, z0, z1; BlockGeometryStructure3D& _blockGeometryStructure; std::vector _discreteNormal; std::vector _missingIndices; UnitConverter const& _converter; wallFunctionParam const& _wallFunctionParam; T y_1; T y_2; int discreteNormalX; int discreteNormalY; int discreteNormalZ; int direction; int orientation; T unit_normal[3]; std::vector onWallIndices; std::vector normalIndices; std::vector normalInwardsIndices; }; template class WallFunctionBoundaryProcessorGenerator3D : public PostProcessorGenerator3D { public: WallFunctionBoundaryProcessorGenerator3D(int x0, int x1, int y0, int y1, int z0, int z1, BlockGeometryStructure3D& blockGeometryStructure, std::vector discreteNormal, std::vector missingIndices, UnitConverter const& converter, wallFunctionParam const& wallFunctionParam, IndicatorF3D* geoIndicator); virtual PostProcessor3D* generate() const override; virtual PostProcessorGenerator3D* clone() const override; private: BlockGeometryStructure3D& _blockGeometryStructure; std::vector _discreteNormal; std::vector _missingIndices; UnitConverter const& _converter; wallFunctionParam const& _wallFunctionParam; IndicatorF3D* _geoIndicator; }; } #endif