diff --git a/src/gpu/VirtualFluids_GPU/GPU/BoundaryConditions/QVelDevPlainBB27.cu b/src/gpu/VirtualFluids_GPU/GPU/BoundaryConditions/QVelDevPlainBB27.cu new file mode 100644 index 0000000000000000000000000000000000000000..aa35fe96096cfc4082c36079ac64900114afa789 --- /dev/null +++ b/src/gpu/VirtualFluids_GPU/GPU/BoundaryConditions/QVelDevPlainBB27.cu @@ -0,0 +1,340 @@ +//======================================================================================= +// ____ ____ __ ______ __________ __ __ __ __ +// \ \ | | | | | _ \ |___ ___| | | | | / \ | | +// \ \ | | | | | |_) | | | | | | | / \ | | +// \ \ | | | | | _ / | | | | | | / /\ \ | | +// \ \ | | | | | | \ \ | | | \__/ | / ____ \ | |____ +// \ \ | | |__| |__| \__\ |__| \________/ /__/ \__\ |_______| +// \ \ | | ________________________________________________________________ +// \ \ | | | ______________________________________________________________| +// \ \| | | | __ __ __ __ ______ _______ +// \ | | |_____ | | | | | | | | | _ \ / _____) +// \ | | _____| | | | | | | | | | | \ \ \_______ +// \ | | | | |_____ | \_/ | | | | |_/ / _____ | +// \ _____| |__| |________| \_______/ |__| |______/ (_______/ +// +// This file is part of VirtualFluids. VirtualFluids 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 3 of +// the License, or (at your option) any later version. +// +// VirtualFluids 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 VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>. +// +//! \file QVelDevPlainBB27.cu +//! \ingroup BoundaryConditions +//! \author Martin Schoenherr +//======================================================================================= +/* Device code */ +#include "LBM/LB.h" +#include "LBM/D3Q27.h" +#include <lbm/constants/NumericConstants.h> + +using namespace vf::lbm::constant; +////////////////////////////////////////////////////////////////////////////// +extern "C" __global__ void QVelDevPlainBB27( + real* vx, + real* vy, + real* vz, + real* distributions, + int* k_Q, + real* subgridDistances, + uint sizeQ, + int kQ, + uint* neighborX, + uint* neighborY, + uint* neighborZ, + uint size_Mat, + bool isEvenTimestep) +{ + ////////////////////////////////////////////////////////////////////////// + //! The velocity boundary condition is executed in the following steps + //! + //////////////////////////////////////////////////////////////////////////////// + //! - Get node index coordinates from thredIdx, blockIdx, blockDim and gridDim. + //! + const unsigned x = threadIdx.x; // global x-index + const unsigned y = blockIdx.x; // global y-index + const unsigned z = blockIdx.y; // global z-index + + const unsigned nx = blockDim.x; + const unsigned ny = gridDim.x; + + const unsigned k = nx*(ny*z + y) + x; + + ////////////////////////////////////////////////////////////////////////// + // run for all indices in size of boundary condition (kQ) + if(k<kQ) + { + ////////////////////////////////////////////////////////////////////////// + //! - Read distributions: style of reading and writing the distributions from/to stored arrays dependent on timestep is based on the esoteric twist algorithm \ref + //! <a href="https://doi.org/10.3390/computation5020019"><b>[ M. Geier et al. (2017), DOI:10.3390/computation5020019 ]</b></a> + //! + Distributions27 dist; + if (isEvenTimestep) + { + dist.f[dirE ] = &distributions[dirE *size_Mat]; + dist.f[dirW ] = &distributions[dirW *size_Mat]; + dist.f[dirN ] = &distributions[dirN *size_Mat]; + dist.f[dirS ] = &distributions[dirS *size_Mat]; + dist.f[dirT ] = &distributions[dirT *size_Mat]; + dist.f[dirB ] = &distributions[dirB *size_Mat]; + dist.f[dirNE ] = &distributions[dirNE *size_Mat]; + dist.f[dirSW ] = &distributions[dirSW *size_Mat]; + dist.f[dirSE ] = &distributions[dirSE *size_Mat]; + dist.f[dirNW ] = &distributions[dirNW *size_Mat]; + dist.f[dirTE ] = &distributions[dirTE *size_Mat]; + dist.f[dirBW ] = &distributions[dirBW *size_Mat]; + dist.f[dirBE ] = &distributions[dirBE *size_Mat]; + dist.f[dirTW ] = &distributions[dirTW *size_Mat]; + dist.f[dirTN ] = &distributions[dirTN *size_Mat]; + dist.f[dirBS ] = &distributions[dirBS *size_Mat]; + dist.f[dirBN ] = &distributions[dirBN *size_Mat]; + dist.f[dirTS ] = &distributions[dirTS *size_Mat]; + dist.f[dirREST] = &distributions[dirREST*size_Mat]; + dist.f[dirTNE ] = &distributions[dirTNE *size_Mat]; + dist.f[dirTSW ] = &distributions[dirTSW *size_Mat]; + dist.f[dirTSE ] = &distributions[dirTSE *size_Mat]; + dist.f[dirTNW ] = &distributions[dirTNW *size_Mat]; + dist.f[dirBNE ] = &distributions[dirBNE *size_Mat]; + dist.f[dirBSW ] = &distributions[dirBSW *size_Mat]; + dist.f[dirBSE ] = &distributions[dirBSE *size_Mat]; + dist.f[dirBNW ] = &distributions[dirBNW *size_Mat]; + } + else + { + dist.f[dirW ] = &distributions[dirE *size_Mat]; + dist.f[dirE ] = &distributions[dirW *size_Mat]; + dist.f[dirS ] = &distributions[dirN *size_Mat]; + dist.f[dirN ] = &distributions[dirS *size_Mat]; + dist.f[dirB ] = &distributions[dirT *size_Mat]; + dist.f[dirT ] = &distributions[dirB *size_Mat]; + dist.f[dirSW ] = &distributions[dirNE *size_Mat]; + dist.f[dirNE ] = &distributions[dirSW *size_Mat]; + dist.f[dirNW ] = &distributions[dirSE *size_Mat]; + dist.f[dirSE ] = &distributions[dirNW *size_Mat]; + dist.f[dirBW ] = &distributions[dirTE *size_Mat]; + dist.f[dirTE ] = &distributions[dirBW *size_Mat]; + dist.f[dirTW ] = &distributions[dirBE *size_Mat]; + dist.f[dirBE ] = &distributions[dirTW *size_Mat]; + dist.f[dirBS ] = &distributions[dirTN *size_Mat]; + dist.f[dirTN ] = &distributions[dirBS *size_Mat]; + dist.f[dirTS ] = &distributions[dirBN *size_Mat]; + dist.f[dirBN ] = &distributions[dirTS *size_Mat]; + dist.f[dirREST] = &distributions[dirREST*size_Mat]; + dist.f[dirTNE ] = &distributions[dirBSW *size_Mat]; + dist.f[dirTSW ] = &distributions[dirBNE *size_Mat]; + dist.f[dirTSE ] = &distributions[dirBNW *size_Mat]; + dist.f[dirTNW ] = &distributions[dirBSE *size_Mat]; + dist.f[dirBNE ] = &distributions[dirTSW *size_Mat]; + dist.f[dirBSW ] = &distributions[dirTNE *size_Mat]; + dist.f[dirBSE ] = &distributions[dirTNW *size_Mat]; + dist.f[dirBNW ] = &distributions[dirTSE *size_Mat]; + } + + + //////////////////////////////////////////////////////////////////////////////// + //! - Set local velocities + //! + real VeloX = vx[k]; + real VeloY = vy[k]; + real VeloZ = vz[k]; + //////////////////////////////////////////////////////////////////////////////// + //! - Set local subgrid distances (q's) + //! + real *q_dirE, *q_dirW, *q_dirN, *q_dirS, *q_dirT, *q_dirB, + *q_dirNE, *q_dirSW, *q_dirSE, *q_dirNW, *q_dirTE, *q_dirBW, + *q_dirBE, *q_dirTW, *q_dirTN, *q_dirBS, *q_dirBN, *q_dirTS, + *q_dirTNE, *q_dirTSW, *q_dirTSE, *q_dirTNW, *q_dirBNE, *q_dirBSW, + *q_dirBSE, *q_dirBNW; + q_dirE = &subgridDistances[dirE *sizeQ]; + q_dirW = &subgridDistances[dirW *sizeQ]; + q_dirN = &subgridDistances[dirN *sizeQ]; + q_dirS = &subgridDistances[dirS *sizeQ]; + q_dirT = &subgridDistances[dirT *sizeQ]; + q_dirB = &subgridDistances[dirB *sizeQ]; + q_dirNE = &subgridDistances[dirNE *sizeQ]; + q_dirSW = &subgridDistances[dirSW *sizeQ]; + q_dirSE = &subgridDistances[dirSE *sizeQ]; + q_dirNW = &subgridDistances[dirNW *sizeQ]; + q_dirTE = &subgridDistances[dirTE *sizeQ]; + q_dirBW = &subgridDistances[dirBW *sizeQ]; + q_dirBE = &subgridDistances[dirBE *sizeQ]; + q_dirTW = &subgridDistances[dirTW *sizeQ]; + q_dirTN = &subgridDistances[dirTN *sizeQ]; + q_dirBS = &subgridDistances[dirBS *sizeQ]; + q_dirBN = &subgridDistances[dirBN *sizeQ]; + q_dirTS = &subgridDistances[dirTS *sizeQ]; + q_dirTNE = &subgridDistances[dirTNE *sizeQ]; + q_dirTSW = &subgridDistances[dirTSW *sizeQ]; + q_dirTSE = &subgridDistances[dirTSE *sizeQ]; + q_dirTNW = &subgridDistances[dirTNW *sizeQ]; + q_dirBNE = &subgridDistances[dirBNE *sizeQ]; + q_dirBSW = &subgridDistances[dirBSW *sizeQ]; + q_dirBSE = &subgridDistances[dirBSE *sizeQ]; + q_dirBNW = &subgridDistances[dirBNW *sizeQ]; + //////////////////////////////////////////////////////////////////////////////// + //! - Set neighbor indices (necessary for indirect addressing) + //! + uint KQK = k_Q[k]; + uint ke = KQK; + uint kw = neighborX[KQK]; + uint kn = KQK; + uint ks = neighborY[KQK]; + uint kt = KQK; + uint kb = neighborZ[KQK]; + uint ksw = neighborY[kw]; + uint kne = KQK; + uint kse = ks; + uint knw = kw; + uint kbw = neighborZ[kw]; + uint kte = KQK; + uint kbe = kb; + uint ktw = kw; + uint kbs = neighborZ[ks]; + uint ktn = KQK; + uint kbn = kb; + uint kts = ks; + uint ktse = ks; + uint kbnw = kbw; + uint ktnw = kw; + uint kbse = kbs; + uint ktsw = ksw; + uint kbne = kb; + uint ktne = KQK; + uint kbsw = neighborZ[ksw]; + //////////////////////////////////////////////////////////////////////////////// + + //////////////////////////////////////////////////////////////////////////////// + //! - Set local distributions + //! + real f_W = (dist.f[dirE ])[ke ]; + real f_E = (dist.f[dirW ])[kw ]; + real f_S = (dist.f[dirN ])[kn ]; + real f_N = (dist.f[dirS ])[ks ]; + real f_B = (dist.f[dirT ])[kt ]; + real f_T = (dist.f[dirB ])[kb ]; + real f_SW = (dist.f[dirNE ])[kne ]; + real f_NE = (dist.f[dirSW ])[ksw ]; + real f_NW = (dist.f[dirSE ])[kse ]; + real f_SE = (dist.f[dirNW ])[knw ]; + real f_BW = (dist.f[dirTE ])[kte ]; + real f_TE = (dist.f[dirBW ])[kbw ]; + real f_TW = (dist.f[dirBE ])[kbe ]; + real f_BE = (dist.f[dirTW ])[ktw ]; + real f_BS = (dist.f[dirTN ])[ktn ]; + real f_TN = (dist.f[dirBS ])[kbs ]; + real f_TS = (dist.f[dirBN ])[kbn ]; + real f_BN = (dist.f[dirTS ])[kts ]; + real f_BSW = (dist.f[dirTNE ])[ktne ]; + real f_BNE = (dist.f[dirTSW ])[ktsw ]; + real f_BNW = (dist.f[dirTSE ])[ktse ]; + real f_BSE = (dist.f[dirTNW ])[ktnw ]; + real f_TSW = (dist.f[dirBNE ])[kbne ]; + real f_TNE = (dist.f[dirBSW ])[kbsw ]; + real f_TNW = (dist.f[dirBSE ])[kbse ]; + real f_TSE = (dist.f[dirBNW ])[kbnw ]; + //////////////////////////////////////////////////////////////////////////////// + + //////////////////////////////////////////////////////////////////////////////// + //! - change the pointer to write the results in the correct array + //! + if (!isEvenTimestep) + { + dist.f[dirE ] = &distributions[dirE *size_Mat]; + dist.f[dirW ] = &distributions[dirW *size_Mat]; + dist.f[dirN ] = &distributions[dirN *size_Mat]; + dist.f[dirS ] = &distributions[dirS *size_Mat]; + dist.f[dirT ] = &distributions[dirT *size_Mat]; + dist.f[dirB ] = &distributions[dirB *size_Mat]; + dist.f[dirNE ] = &distributions[dirNE *size_Mat]; + dist.f[dirSW ] = &distributions[dirSW *size_Mat]; + dist.f[dirSE ] = &distributions[dirSE *size_Mat]; + dist.f[dirNW ] = &distributions[dirNW *size_Mat]; + dist.f[dirTE ] = &distributions[dirTE *size_Mat]; + dist.f[dirBW ] = &distributions[dirBW *size_Mat]; + dist.f[dirBE ] = &distributions[dirBE *size_Mat]; + dist.f[dirTW ] = &distributions[dirTW *size_Mat]; + dist.f[dirTN ] = &distributions[dirTN *size_Mat]; + dist.f[dirBS ] = &distributions[dirBS *size_Mat]; + dist.f[dirBN ] = &distributions[dirBN *size_Mat]; + dist.f[dirTS ] = &distributions[dirTS *size_Mat]; + dist.f[dirREST] = &distributions[dirREST*size_Mat]; + dist.f[dirTNE ] = &distributions[dirTNE *size_Mat]; + dist.f[dirTSW ] = &distributions[dirTSW *size_Mat]; + dist.f[dirTSE ] = &distributions[dirTSE *size_Mat]; + dist.f[dirTNW ] = &distributions[dirTNW *size_Mat]; + dist.f[dirBNE ] = &distributions[dirBNE *size_Mat]; + dist.f[dirBSW ] = &distributions[dirBSW *size_Mat]; + dist.f[dirBSE ] = &distributions[dirBSE *size_Mat]; + dist.f[dirBNW ] = &distributions[dirBNW *size_Mat]; + } + else + { + dist.f[dirW ] = &distributions[dirE *size_Mat]; + dist.f[dirE ] = &distributions[dirW *size_Mat]; + dist.f[dirS ] = &distributions[dirN *size_Mat]; + dist.f[dirN ] = &distributions[dirS *size_Mat]; + dist.f[dirB ] = &distributions[dirT *size_Mat]; + dist.f[dirT ] = &distributions[dirB *size_Mat]; + dist.f[dirSW ] = &distributions[dirNE *size_Mat]; + dist.f[dirNE ] = &distributions[dirSW *size_Mat]; + dist.f[dirNW ] = &distributions[dirSE *size_Mat]; + dist.f[dirSE ] = &distributions[dirNW *size_Mat]; + dist.f[dirBW ] = &distributions[dirTE *size_Mat]; + dist.f[dirTE ] = &distributions[dirBW *size_Mat]; + dist.f[dirTW ] = &distributions[dirBE *size_Mat]; + dist.f[dirBE ] = &distributions[dirTW *size_Mat]; + dist.f[dirBS ] = &distributions[dirTN *size_Mat]; + dist.f[dirTN ] = &distributions[dirBS *size_Mat]; + dist.f[dirTS ] = &distributions[dirBN *size_Mat]; + dist.f[dirBN ] = &distributions[dirTS *size_Mat]; + dist.f[dirREST] = &distributions[dirREST*size_Mat]; + dist.f[dirTNE ] = &distributions[dirBSW *size_Mat]; + dist.f[dirTSW ] = &distributions[dirBNE *size_Mat]; + dist.f[dirTSE ] = &distributions[dirBNW *size_Mat]; + dist.f[dirTNW ] = &distributions[dirBSE *size_Mat]; + dist.f[dirBNE ] = &distributions[dirTSW *size_Mat]; + dist.f[dirBSW ] = &distributions[dirTNE *size_Mat]; + dist.f[dirBSE ] = &distributions[dirTNW *size_Mat]; + dist.f[dirBNW ] = &distributions[dirTSE *size_Mat]; + } + //////////////////////////////////////////////////////////////////////////////// + //! - rewrite distributions if there is a sub-grid distance (q) in same direction + real q; + q = q_dirE[k]; if (q>=c0o1 && q<=c1o1) (dist.f[dirW ])[kw ]=f_E + c4o9 * (-VeloX); + q = q_dirW[k]; if (q>=c0o1 && q<=c1o1) (dist.f[dirE ])[ke ]=f_W + c4o9 * ( VeloX); + q = q_dirN[k]; if (q>=c0o1 && q<=c1o1) (dist.f[dirS ])[ks ]=f_N + c4o9 * (-VeloY); + q = q_dirS[k]; if (q>=c0o1 && q<=c1o1) (dist.f[dirN ])[kn ]=f_S + c4o9 * ( VeloY); + q = q_dirT[k]; if (q>=c0o1 && q<=c1o1) (dist.f[dirB ])[kb ]=f_T + c4o9 * (-VeloZ); + q = q_dirB[k]; if (q>=c0o1 && q<=c1o1) (dist.f[dirT ])[kt ]=f_B + c4o9 * ( VeloZ); + q = q_dirNE[k]; if (q>=c0o1 && q<=c1o1) (dist.f[dirSW ])[ksw ]=f_NE + c1o9 * (-VeloX - VeloY); + q = q_dirSW[k]; if (q>=c0o1 && q<=c1o1) (dist.f[dirNE ])[kne ]=f_SW + c1o9 * ( VeloX + VeloY); + q = q_dirSE[k]; if (q>=c0o1 && q<=c1o1) (dist.f[dirNW ])[knw ]=f_SE + c1o9 * (-VeloX + VeloY); + q = q_dirNW[k]; if (q>=c0o1 && q<=c1o1) (dist.f[dirSE ])[kse ]=f_NW + c1o9 * ( VeloX - VeloY); + q = q_dirTE[k]; if (q>=c0o1 && q<=c1o1) (dist.f[dirBW ])[kbw ]=f_TE + c1o9 * (-VeloX - VeloZ); + q = q_dirBW[k]; if (q>=c0o1 && q<=c1o1) (dist.f[dirTE ])[kte ]=f_BW + c1o9 * ( VeloX + VeloZ); + q = q_dirBE[k]; if (q>=c0o1 && q<=c1o1) (dist.f[dirTW ])[ktw ]=f_BE + c1o9 * (-VeloX + VeloZ); + q = q_dirTW[k]; if (q>=c0o1 && q<=c1o1) (dist.f[dirBE ])[kbe ]=f_TW + c1o9 * ( VeloX - VeloZ); + q = q_dirTN[k]; if (q>=c0o1 && q<=c1o1) (dist.f[dirBS ])[kbs ]=f_TN + c1o9 * (-VeloY - VeloZ); + q = q_dirBS[k]; if (q>=c0o1 && q<=c1o1) (dist.f[dirTN ])[ktn ]=f_BS + c1o9 * ( VeloY + VeloZ); + q = q_dirBN[k]; if (q>=c0o1 && q<=c1o1) (dist.f[dirTS ])[kts ]=f_BN + c1o9 * (-VeloY + VeloZ); + q = q_dirTS[k]; if (q>=c0o1 && q<=c1o1) (dist.f[dirBN ])[kbn ]=f_TS + c1o9 * ( VeloY - VeloZ); + q = q_dirTNE[k]; if (q>=c0o1 && q<=c1o1) (dist.f[dirBSW])[kbsw]=f_TNE + c1o36 * (-VeloX - VeloY - VeloZ); + q = q_dirBSW[k]; if (q>=c0o1 && q<=c1o1) (dist.f[dirTNE])[ktne]=f_BSW + c1o36 * ( VeloX + VeloY + VeloZ); + q = q_dirBNE[k]; if (q>=c0o1 && q<=c1o1) (dist.f[dirTSW])[ktsw]=f_BNE + c1o36 * (-VeloX - VeloY + VeloZ); + q = q_dirTSW[k]; if (q>=c0o1 && q<=c1o1) (dist.f[dirBNE])[kbne]=f_TSW + c1o36 * ( VeloX + VeloY - VeloZ); + q = q_dirTSE[k]; if (q>=c0o1 && q<=c1o1) (dist.f[dirBNW])[kbnw]=f_TSE + c1o36 * (-VeloX + VeloY - VeloZ); + q = q_dirBNW[k]; if (q>=c0o1 && q<=c1o1) (dist.f[dirTSE])[ktse]=f_BNW + c1o36 * ( VeloX - VeloY + VeloZ); + q = q_dirBSE[k]; if (q>=c0o1 && q<=c1o1) (dist.f[dirTNW])[ktnw]=f_BSE + c1o36 * (-VeloX + VeloY + VeloZ); + q = q_dirTNW[k]; if (q>=c0o1 && q<=c1o1) (dist.f[dirBSE])[kbse]=f_TNW + c1o36 * ( VeloX - VeloY - VeloZ); + } +} + + + diff --git a/src/gpu/VirtualFluids_GPU/GPU/VelocityBCs27.cu b/src/gpu/VirtualFluids_GPU/GPU/VelocityBCs27.cu deleted file mode 100644 index 8bc893a1276d16046a8b673ec1ba674fcaf014dd..0000000000000000000000000000000000000000 --- a/src/gpu/VirtualFluids_GPU/GPU/VelocityBCs27.cu +++ /dev/null @@ -1,340 +0,0 @@ -//======================================================================================= -// ____ ____ __ ______ __________ __ __ __ __ -// \ \ | | | | | _ \ |___ ___| | | | | / \ | | -// \ \ | | | | | |_) | | | | | | | / \ | | -// \ \ | | | | | _ / | | | | | | / /\ \ | | -// \ \ | | | | | | \ \ | | | \__/ | / ____ \ | |____ -// \ \ | | |__| |__| \__\ |__| \________/ /__/ \__\ |_______| -// \ \ | | ________________________________________________________________ -// \ \ | | | ______________________________________________________________| -// \ \| | | | __ __ __ __ ______ _______ -// \ | | |_____ | | | | | | | | | _ \ / _____) -// \ | | _____| | | | | | | | | | | \ \ \_______ -// \ | | | | |_____ | \_/ | | | | |_/ / _____ | -// \ _____| |__| |________| \_______/ |__| |______/ (_______/ -// -// This file is part of VirtualFluids. VirtualFluids 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 3 of -// the License, or (at your option) any later version. -// -// VirtualFluids 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 VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>. -// -//! \file VelocityBCs27.cu -//! \ingroup GPU -//! \author Martin Schoenherr -//======================================================================================= -/* Device code */ -#include "LBM/LB.h" -#include "LBM/D3Q27.h" -#include <lbm/constants/NumericConstants.h> - -using namespace vf::lbm::constant; -////////////////////////////////////////////////////////////////////////////// -extern "C" __global__ void QVelDevPlainBB27( - real* vx, - real* vy, - real* vz, - real* distributions, - int* k_Q, - real* QQ, - uint sizeQ, - int kQ, - uint* neighborX, - uint* neighborY, - uint* neighborZ, - uint size_Mat, - bool isEvenTimestep) -{ - ////////////////////////////////////////////////////////////////////////// - //! The velocity boundary condition is executed in the following steps - //! - //////////////////////////////////////////////////////////////////////////////// - //! - Get node index coordinates from thredIdx, blockIdx, blockDim and gridDim. - //! - const unsigned x = threadIdx.x; // Globaler x-Index - const unsigned y = blockIdx.x; // Globaler y-Index - const unsigned z = blockIdx.y; // Globaler z-Index - - const unsigned nx = blockDim.x; - const unsigned ny = gridDim.x; - - const unsigned k = nx*(ny*z + y) + x; - - ////////////////////////////////////////////////////////////////////////// - // run for all indices in size of boundary condition (kQ) - if(k<kQ) - { - ////////////////////////////////////////////////////////////////////////// - //! - Read distributions: style of reading and writing the distributions from/to stored arrays dependent on timestep is based on the esoteric twist algorithm \ref - //! <a href="https://doi.org/10.3390/computation5020019"><b>[ M. Geier et al. (2017), DOI:10.3390/computation5020019 ]</b></a> - //! - Distributions27 dist; - if (isEvenTimestep) - { - dist.f[dirE ] = &distributions[dirE *size_Mat]; - dist.f[dirW ] = &distributions[dirW *size_Mat]; - dist.f[dirN ] = &distributions[dirN *size_Mat]; - dist.f[dirS ] = &distributions[dirS *size_Mat]; - dist.f[dirT ] = &distributions[dirT *size_Mat]; - dist.f[dirB ] = &distributions[dirB *size_Mat]; - dist.f[dirNE ] = &distributions[dirNE *size_Mat]; - dist.f[dirSW ] = &distributions[dirSW *size_Mat]; - dist.f[dirSE ] = &distributions[dirSE *size_Mat]; - dist.f[dirNW ] = &distributions[dirNW *size_Mat]; - dist.f[dirTE ] = &distributions[dirTE *size_Mat]; - dist.f[dirBW ] = &distributions[dirBW *size_Mat]; - dist.f[dirBE ] = &distributions[dirBE *size_Mat]; - dist.f[dirTW ] = &distributions[dirTW *size_Mat]; - dist.f[dirTN ] = &distributions[dirTN *size_Mat]; - dist.f[dirBS ] = &distributions[dirBS *size_Mat]; - dist.f[dirBN ] = &distributions[dirBN *size_Mat]; - dist.f[dirTS ] = &distributions[dirTS *size_Mat]; - dist.f[dirREST] = &distributions[dirREST*size_Mat]; - dist.f[dirTNE ] = &distributions[dirTNE *size_Mat]; - dist.f[dirTSW ] = &distributions[dirTSW *size_Mat]; - dist.f[dirTSE ] = &distributions[dirTSE *size_Mat]; - dist.f[dirTNW ] = &distributions[dirTNW *size_Mat]; - dist.f[dirBNE ] = &distributions[dirBNE *size_Mat]; - dist.f[dirBSW ] = &distributions[dirBSW *size_Mat]; - dist.f[dirBSE ] = &distributions[dirBSE *size_Mat]; - dist.f[dirBNW ] = &distributions[dirBNW *size_Mat]; - } - else - { - dist.f[dirW ] = &distributions[dirE *size_Mat]; - dist.f[dirE ] = &distributions[dirW *size_Mat]; - dist.f[dirS ] = &distributions[dirN *size_Mat]; - dist.f[dirN ] = &distributions[dirS *size_Mat]; - dist.f[dirB ] = &distributions[dirT *size_Mat]; - dist.f[dirT ] = &distributions[dirB *size_Mat]; - dist.f[dirSW ] = &distributions[dirNE *size_Mat]; - dist.f[dirNE ] = &distributions[dirSW *size_Mat]; - dist.f[dirNW ] = &distributions[dirSE *size_Mat]; - dist.f[dirSE ] = &distributions[dirNW *size_Mat]; - dist.f[dirBW ] = &distributions[dirTE *size_Mat]; - dist.f[dirTE ] = &distributions[dirBW *size_Mat]; - dist.f[dirTW ] = &distributions[dirBE *size_Mat]; - dist.f[dirBE ] = &distributions[dirTW *size_Mat]; - dist.f[dirBS ] = &distributions[dirTN *size_Mat]; - dist.f[dirTN ] = &distributions[dirBS *size_Mat]; - dist.f[dirTS ] = &distributions[dirBN *size_Mat]; - dist.f[dirBN ] = &distributions[dirTS *size_Mat]; - dist.f[dirREST] = &distributions[dirREST*size_Mat]; - dist.f[dirTNE ] = &distributions[dirBSW *size_Mat]; - dist.f[dirTSW ] = &distributions[dirBNE *size_Mat]; - dist.f[dirTSE ] = &distributions[dirBNW *size_Mat]; - dist.f[dirTNW ] = &distributions[dirBSE *size_Mat]; - dist.f[dirBNE ] = &distributions[dirTSW *size_Mat]; - dist.f[dirBSW ] = &distributions[dirTNE *size_Mat]; - dist.f[dirBSE ] = &distributions[dirTNW *size_Mat]; - dist.f[dirBNW ] = &distributions[dirTSE *size_Mat]; - } - - - //////////////////////////////////////////////////////////////////////////////// - //! - Set local velocities - //! - real VeloX = vx[k]; - real VeloY = vy[k]; - real VeloZ = vz[k]; - //////////////////////////////////////////////////////////////////////////////// - //! - Set local subgrid distances (q's) - //! - real *q_dirE, *q_dirW, *q_dirN, *q_dirS, *q_dirT, *q_dirB, - *q_dirNE, *q_dirSW, *q_dirSE, *q_dirNW, *q_dirTE, *q_dirBW, - *q_dirBE, *q_dirTW, *q_dirTN, *q_dirBS, *q_dirBN, *q_dirTS, - *q_dirTNE, *q_dirTSW, *q_dirTSE, *q_dirTNW, *q_dirBNE, *q_dirBSW, - *q_dirBSE, *q_dirBNW; - q_dirE = &QQ[dirE *sizeQ]; - q_dirW = &QQ[dirW *sizeQ]; - q_dirN = &QQ[dirN *sizeQ]; - q_dirS = &QQ[dirS *sizeQ]; - q_dirT = &QQ[dirT *sizeQ]; - q_dirB = &QQ[dirB *sizeQ]; - q_dirNE = &QQ[dirNE *sizeQ]; - q_dirSW = &QQ[dirSW *sizeQ]; - q_dirSE = &QQ[dirSE *sizeQ]; - q_dirNW = &QQ[dirNW *sizeQ]; - q_dirTE = &QQ[dirTE *sizeQ]; - q_dirBW = &QQ[dirBW *sizeQ]; - q_dirBE = &QQ[dirBE *sizeQ]; - q_dirTW = &QQ[dirTW *sizeQ]; - q_dirTN = &QQ[dirTN *sizeQ]; - q_dirBS = &QQ[dirBS *sizeQ]; - q_dirBN = &QQ[dirBN *sizeQ]; - q_dirTS = &QQ[dirTS *sizeQ]; - q_dirTNE = &QQ[dirTNE *sizeQ]; - q_dirTSW = &QQ[dirTSW *sizeQ]; - q_dirTSE = &QQ[dirTSE *sizeQ]; - q_dirTNW = &QQ[dirTNW *sizeQ]; - q_dirBNE = &QQ[dirBNE *sizeQ]; - q_dirBSW = &QQ[dirBSW *sizeQ]; - q_dirBSE = &QQ[dirBSE *sizeQ]; - q_dirBNW = &QQ[dirBNW *sizeQ]; - //////////////////////////////////////////////////////////////////////////////// - //! - Set neighbor indices (necessary for indirect addressing) - //! - uint KQK = k_Q[k]; - uint ke = KQK; - uint kw = neighborX[KQK]; - uint kn = KQK; - uint ks = neighborY[KQK]; - uint kt = KQK; - uint kb = neighborZ[KQK]; - uint ksw = neighborY[kw]; - uint kne = KQK; - uint kse = ks; - uint knw = kw; - uint kbw = neighborZ[kw]; - uint kte = KQK; - uint kbe = kb; - uint ktw = kw; - uint kbs = neighborZ[ks]; - uint ktn = KQK; - uint kbn = kb; - uint kts = ks; - uint ktse = ks; - uint kbnw = kbw; - uint ktnw = kw; - uint kbse = kbs; - uint ktsw = ksw; - uint kbne = kb; - uint ktne = KQK; - uint kbsw = neighborZ[ksw]; - //////////////////////////////////////////////////////////////////////////////// - - //////////////////////////////////////////////////////////////////////////////// - //! - Set local distributions - //! - real f_W = (dist.f[dirE])[ke]; - real f_E = (dist.f[dirW ])[kw ]; - real f_S = (dist.f[dirN ])[kn ]; - real f_N = (dist.f[dirS ])[ks ]; - real f_B = (dist.f[dirT ])[kt ]; - real f_T = (dist.f[dirB ])[kb ]; - real f_SW = (dist.f[dirNE ])[kne ]; - real f_NE = (dist.f[dirSW ])[ksw ]; - real f_NW = (dist.f[dirSE ])[kse ]; - real f_SE = (dist.f[dirNW ])[knw ]; - real f_BW = (dist.f[dirTE ])[kte ]; - real f_TE = (dist.f[dirBW ])[kbw ]; - real f_TW = (dist.f[dirBE ])[kbe ]; - real f_BE = (dist.f[dirTW ])[ktw ]; - real f_BS = (dist.f[dirTN ])[ktn ]; - real f_TN = (dist.f[dirBS ])[kbs ]; - real f_TS = (dist.f[dirBN ])[kbn ]; - real f_BN = (dist.f[dirTS ])[kts ]; - real f_BSW = (dist.f[dirTNE ])[ktne ]; - real f_BNE = (dist.f[dirTSW ])[ktsw ]; - real f_BNW = (dist.f[dirTSE ])[ktse ]; - real f_BSE = (dist.f[dirTNW ])[ktnw ]; - real f_TSW = (dist.f[dirBNE ])[kbne ]; - real f_TNE = (dist.f[dirBSW ])[kbsw ]; - real f_TNW = (dist.f[dirBSE ])[kbse ]; - real f_TSE = (dist.f[dirBNW ])[kbnw ]; - //////////////////////////////////////////////////////////////////////////////// - - //////////////////////////////////////////////////////////////////////////////// - //! - change the pointer to write the results in the correct array - //! - if (!isEvenTimestep) - { - dist.f[dirE ] = &distributions[dirE *size_Mat]; - dist.f[dirW ] = &distributions[dirW *size_Mat]; - dist.f[dirN ] = &distributions[dirN *size_Mat]; - dist.f[dirS ] = &distributions[dirS *size_Mat]; - dist.f[dirT ] = &distributions[dirT *size_Mat]; - dist.f[dirB ] = &distributions[dirB *size_Mat]; - dist.f[dirNE ] = &distributions[dirNE *size_Mat]; - dist.f[dirSW ] = &distributions[dirSW *size_Mat]; - dist.f[dirSE ] = &distributions[dirSE *size_Mat]; - dist.f[dirNW ] = &distributions[dirNW *size_Mat]; - dist.f[dirTE ] = &distributions[dirTE *size_Mat]; - dist.f[dirBW ] = &distributions[dirBW *size_Mat]; - dist.f[dirBE ] = &distributions[dirBE *size_Mat]; - dist.f[dirTW ] = &distributions[dirTW *size_Mat]; - dist.f[dirTN ] = &distributions[dirTN *size_Mat]; - dist.f[dirBS ] = &distributions[dirBS *size_Mat]; - dist.f[dirBN ] = &distributions[dirBN *size_Mat]; - dist.f[dirTS ] = &distributions[dirTS *size_Mat]; - dist.f[dirREST] = &distributions[dirREST*size_Mat]; - dist.f[dirTNE ] = &distributions[dirTNE *size_Mat]; - dist.f[dirTSW ] = &distributions[dirTSW *size_Mat]; - dist.f[dirTSE ] = &distributions[dirTSE *size_Mat]; - dist.f[dirTNW ] = &distributions[dirTNW *size_Mat]; - dist.f[dirBNE ] = &distributions[dirBNE *size_Mat]; - dist.f[dirBSW ] = &distributions[dirBSW *size_Mat]; - dist.f[dirBSE ] = &distributions[dirBSE *size_Mat]; - dist.f[dirBNW ] = &distributions[dirBNW *size_Mat]; - } - else - { - dist.f[dirW ] = &distributions[dirE *size_Mat]; - dist.f[dirE ] = &distributions[dirW *size_Mat]; - dist.f[dirS ] = &distributions[dirN *size_Mat]; - dist.f[dirN ] = &distributions[dirS *size_Mat]; - dist.f[dirB ] = &distributions[dirT *size_Mat]; - dist.f[dirT ] = &distributions[dirB *size_Mat]; - dist.f[dirSW ] = &distributions[dirNE *size_Mat]; - dist.f[dirNE ] = &distributions[dirSW *size_Mat]; - dist.f[dirNW ] = &distributions[dirSE *size_Mat]; - dist.f[dirSE ] = &distributions[dirNW *size_Mat]; - dist.f[dirBW ] = &distributions[dirTE *size_Mat]; - dist.f[dirTE ] = &distributions[dirBW *size_Mat]; - dist.f[dirTW ] = &distributions[dirBE *size_Mat]; - dist.f[dirBE ] = &distributions[dirTW *size_Mat]; - dist.f[dirBS ] = &distributions[dirTN *size_Mat]; - dist.f[dirTN ] = &distributions[dirBS *size_Mat]; - dist.f[dirTS ] = &distributions[dirBN *size_Mat]; - dist.f[dirBN ] = &distributions[dirTS *size_Mat]; - dist.f[dirREST] = &distributions[dirREST*size_Mat]; - dist.f[dirTNE ] = &distributions[dirBSW *size_Mat]; - dist.f[dirTSW ] = &distributions[dirBNE *size_Mat]; - dist.f[dirTSE ] = &distributions[dirBNW *size_Mat]; - dist.f[dirTNW ] = &distributions[dirBSE *size_Mat]; - dist.f[dirBNE ] = &distributions[dirTSW *size_Mat]; - dist.f[dirBSW ] = &distributions[dirTNE *size_Mat]; - dist.f[dirBSE ] = &distributions[dirTNW *size_Mat]; - dist.f[dirBNW ] = &distributions[dirTSE *size_Mat]; - } - //////////////////////////////////////////////////////////////////////////////// - //! - rewrite distributions if there is a sub-grid distance (q) in same direction - real q; - q = q_dirE[k]; if (q>=c0o1 && q<=c1o1) (dist.f[dirW ])[kw ]=f_E + c4o9 * (-VeloX); - q = q_dirW[k]; if (q>=c0o1 && q<=c1o1) (dist.f[dirE ])[ke ]=f_W + c4o9 * ( VeloX); - q = q_dirN[k]; if (q>=c0o1 && q<=c1o1) (dist.f[dirS ])[ks ]=f_N + c4o9 * (-VeloY); - q = q_dirS[k]; if (q>=c0o1 && q<=c1o1) (dist.f[dirN ])[kn ]=f_S + c4o9 * ( VeloY); - q = q_dirT[k]; if (q>=c0o1 && q<=c1o1) (dist.f[dirB ])[kb ]=f_T + c4o9 * (-VeloZ); - q = q_dirB[k]; if (q>=c0o1 && q<=c1o1) (dist.f[dirT ])[kt ]=f_B + c4o9 * ( VeloZ); - q = q_dirNE[k]; if (q>=c0o1 && q<=c1o1) (dist.f[dirSW ])[ksw ]=f_NE + c1o9 * (-VeloX - VeloY); - q = q_dirSW[k]; if (q>=c0o1 && q<=c1o1) (dist.f[dirNE ])[kne ]=f_SW + c1o9 * ( VeloX + VeloY); - q = q_dirSE[k]; if (q>=c0o1 && q<=c1o1) (dist.f[dirNW ])[knw ]=f_SE + c1o9 * (-VeloX + VeloY); - q = q_dirNW[k]; if (q>=c0o1 && q<=c1o1) (dist.f[dirSE ])[kse ]=f_NW + c1o9 * ( VeloX - VeloY); - q = q_dirTE[k]; if (q>=c0o1 && q<=c1o1) (dist.f[dirBW ])[kbw ]=f_TE + c1o9 * (-VeloX - VeloZ); - q = q_dirBW[k]; if (q>=c0o1 && q<=c1o1) (dist.f[dirTE ])[kte ]=f_BW + c1o9 * ( VeloX + VeloZ); - q = q_dirBE[k]; if (q>=c0o1 && q<=c1o1) (dist.f[dirTW ])[ktw ]=f_BE + c1o9 * (-VeloX + VeloZ); - q = q_dirTW[k]; if (q>=c0o1 && q<=c1o1) (dist.f[dirBE ])[kbe ]=f_TW + c1o9 * ( VeloX - VeloZ); - q = q_dirTN[k]; if (q>=c0o1 && q<=c1o1) (dist.f[dirBS ])[kbs ]=f_TN + c1o9 * (-VeloY - VeloZ); - q = q_dirBS[k]; if (q>=c0o1 && q<=c1o1) (dist.f[dirTN ])[ktn ]=f_BS + c1o9 * ( VeloY + VeloZ); - q = q_dirBN[k]; if (q>=c0o1 && q<=c1o1) (dist.f[dirTS ])[kts ]=f_BN + c1o9 * (-VeloY + VeloZ); - q = q_dirTS[k]; if (q>=c0o1 && q<=c1o1) (dist.f[dirBN ])[kbn ]=f_TS + c1o9 * ( VeloY - VeloZ); - q = q_dirTNE[k]; if (q>=c0o1 && q<=c1o1) (dist.f[dirBSW])[kbsw]=f_TNE + c1o36 * (-VeloX - VeloY - VeloZ); - q = q_dirBSW[k]; if (q>=c0o1 && q<=c1o1) (dist.f[dirTNE])[ktne]=f_BSW + c1o36 * ( VeloX + VeloY + VeloZ); - q = q_dirBNE[k]; if (q>=c0o1 && q<=c1o1) (dist.f[dirTSW])[ktsw]=f_BNE + c1o36 * (-VeloX - VeloY + VeloZ); - q = q_dirTSW[k]; if (q>=c0o1 && q<=c1o1) (dist.f[dirBNE])[kbne]=f_TSW + c1o36 * ( VeloX + VeloY - VeloZ); - q = q_dirTSE[k]; if (q>=c0o1 && q<=c1o1) (dist.f[dirBNW])[kbnw]=f_TSE + c1o36 * (-VeloX + VeloY - VeloZ); - q = q_dirBNW[k]; if (q>=c0o1 && q<=c1o1) (dist.f[dirTSE])[ktse]=f_BNW + c1o36 * ( VeloX - VeloY + VeloZ); - q = q_dirBSE[k]; if (q>=c0o1 && q<=c1o1) (dist.f[dirTNW])[ktnw]=f_BSE + c1o36 * (-VeloX + VeloY + VeloZ); - q = q_dirTNW[k]; if (q>=c0o1 && q<=c1o1) (dist.f[dirBSE])[kbse]=f_TNW + c1o36 * ( VeloX - VeloY - VeloZ); - } -} - - -