1//=======================================================================================
2// ____ ____ __ ______ __________ __ __ __ __
3// \ \ | | | | | _ \ |___ ___| | | | | / \ | |
4// \ \ | | | | | |_) | | | | | | | / \ | |
5// \ \ | | | | | _ / | | | | | | / /\ \ | |
6// \ \ | | | | | | \ \ | | | \__/ | / ____ \ | |____
7// \ \ | | |__| |__| \__\ |__| \________/ /__/ \__\ |_______|
8// \ \ | | ________________________________________________________________
9// \ \ | | | ______________________________________________________________|
10// \ \| | | | __ __ __ __ ______ _______
11// \ | | |_____ | | | | | | | | | _ \ / _____)
12// \ | | _____| | | | | | | | | | | \ \ \_______
13// \ | | | | |_____ | \_/ | | | | |_/ / _____ |
14// \ _____| |__| |________| \_______/ |__| |______/ (_______/
16// This file is part of VirtualFluids. VirtualFluids is free software: you can
17// redistribute it and/or modify it under the terms of the GNU General Public
18// License as published by the Free Software Foundation, either version 3 of
19// the License, or (at your option) any later version.
21// VirtualFluids is distributed in the hope that it will be useful, but WITHOUT
22// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
23// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
26// SPDX-License-Identifier: GPL-3.0-or-later
27// SPDX-FileCopyrightText: Copyright © VirtualFluids Project contributors, see AUTHORS.md in root folder
29//! \addtogroup gpu_BoundaryConditions BoundaryConditions
30//! \ingroup gpu_core core
32//! \author Martin Schoenherr
33//=======================================================================================
34#ifndef Stress_Device_H
35#define Stress_Device_H
37#include <basics/DataTypes.h>
38#include <basics/constants/NumericConstants.h>
40#include <cuda_helper/CudaIndexCalculation.h>
42#include <lbm/MacroscopicQuantities.h>
43#include <lbm/collision/TurbulentViscosity.h>
45#include "BoundaryConditions/BoundaryConditionFactory.h"
46#include "Calculation/Calculation.h"
47#include "Utilities/KernelUtilities.h"
50#include "inverseMomentumExchange.cuh"
51#include "lbm/constants/D3Q27.h"
52#include "wallModelMoninObukhov.h"
56template <BoundaryConditionFactory::StressBC stressBCType, bool delayed>
57__global__ void StressDevice27(GridParameter gridParams, QforBoundaryConditions boundaryParams,
58 WallModelParameters wallModelParams)
60 using namespace vf::basics::constant;
61 using namespace vf::lbm::dir;
62 using StressBC = BoundaryConditionFactory::StressBC;
64 const real filterFrequency = 1e-3F;
66 const uint nodeIndex = vf::cuda::get1DIndexFrom2DBlock();
68 if (nodeIndex >= boundaryParams.numberOfBCnodes)
71 //////////////////////////////////////////////////////////////////////////
73 //////////////////////////////////////////////////////////////////////////
75 Distributions27 populationReferences =
76 getDistributionReferences27(gridParams.distributions, gridParams.numberOfNodes, gridParams.isEvenTimestep);
78 SubgridDistances27 subgridDistances;
79 getPointersToSubgridDistances(subgridDistances, boundaryParams.q27[0], boundaryParams.numberOfBCnodes);
81 const uint k_000 = boundaryParams.k[nodeIndex];
82 const ListIndices listIndices(k_000, gridParams.neighborX, gridParams.neighborY, gridParams.neighborZ);
84 real populations[NUMBER_Of_DIRECTIONS];
85 getPostCollisionDistribution(populations, populationReferences, listIndices);
87 const real drho = vf::lbm::getDensity(populations);
88 const real3 velocityNode = { vf::lbm::getCompressibleVelocityX1(populations, drho),
89 vf::lbm::getCompressibleVelocityX2(populations, drho),
90 vf::lbm::getCompressibleVelocityX3(populations, drho) };
91 const real density = c1o1;
93 const real3 wallNormal { boundaryParams.normalX[nodeIndex], boundaryParams.normalY[nodeIndex],
94 boundaryParams.normalZ[nodeIndex] };
96 const real3 velocityNodeTangential = computeTangentialVector(velocityNode, wallNormal);
98 const real velocityNodeMeanTangentialMagnitude = smoothAndSaveMean(computeMagnitude(velocityNodeTangential), filterFrequency,
99 wallModelParams.velocityMagnitudeNode[nodeIndex]);
101 const uint samplingIndex = wallModelParams.samplingIndices[nodeIndex];
102 const real3 velocitySample { gridParams.velocityX[samplingIndex], gridParams.velocityY[samplingIndex],
103 gridParams.velocityZ[samplingIndex] };
105 const real velocitySampleTangentialMagnitude = computeMagnitude(computeTangentialVector(velocitySample, wallNormal));
107 const real velocitySampleMeanTangentialMagnitude = smoothAndSaveMean(velocitySampleTangentialMagnitude, filterFrequency,
108 wallModelParams.velocityMagnitudeSample[nodeIndex]);
110 //////////////////////////////////////////////////////////////////////////
111 // load wall model parameters and compute wall shear stress
112 //////////////////////////////////////////////////////////////////////////
114 const real samplingDistance = wallModelParams.samplingDistance[nodeIndex];
115 const real roughnessLength = wallModelParams.roughnessLength[nodeIndex];
116 const real vonKarmanConstant = wallModelParams.vonKarmanConstant[nodeIndex];
117 const real frictionVelocity = computeFrictionVelocity(velocitySampleMeanTangentialMagnitude, vonKarmanConstant,
118 samplingDistance, roughnessLength, c0o1);
119 const real3 wallShearStress =
120 computeWallShearStress(frictionVelocity, velocityNodeTangential, velocityNodeMeanTangentialMagnitude, density);
122 //////////////////////////////////////////////////////////////////////////
123 // apply inverse Momentum exchange
124 //////////////////////////////////////////////////////////////////////////
126 real populationsBouncedBack[NUMBER_Of_DIRECTIONS];
127 bool linkIsCut[NUMBER_Of_DIRECTIONS];
129 switch (stressBCType) {
130 case StressBC::StressBounceBackCompressible:
131 computeBouncedBackDistributionsBB(subgridDistances, populations, linkIsCut, populationsBouncedBack, nodeIndex);
133 case StressBC::StressBounceBackWithPressureCompressible:
134 computeBouncedBackDistributionsBBPressure(subgridDistances, drho, populations, linkIsCut, populationsBouncedBack,
137 case StressBC::StressInterpolatedCompressible: {
138 const real relaxationFrequency = vf::lbm::calculateOmegaWithTurbulentViscosity(
139 gridParams.relaxationFrequency, gridParams.turbulentViscosity[k_000]);
140 computeBouncedBackDistributionsInterpolated(subgridDistances, velocityNode, drho, relaxationFrequency,
141 populations, linkIsCut, populationsBouncedBack, nodeIndex);
145 real3 wallMomentum = computeWallMomentumBounceBack(linkIsCut, populationsBouncedBack, populations);
147 const real wallArea = c1o1;
148 const real subgridDistance = (subgridDistances.q[d00M])[nodeIndex];
149 const real interpolationFactor =
150 stressBCType == StressBC::StressInterpolatedCompressible ? c1o1 + subgridDistance : c1o1;
152 const real3 fakeWallVelocity = computeFakeWallVelocity(wallNormal, velocitySample, wallShearStress, density,
153 interpolationFactor, wallArea, wallMomentum);
155 populationReferences = getDistributionReferences27(gridParams.distributions, gridParams.numberOfNodes,
156 !gridParams.isEvenTimestep);
159 if (stressBCType == StressBC::StressInterpolatedCompressible)
161 writeDistributionsInterpolatedBB(populationReferences, linkIsCut, populationsBouncedBack, fakeWallVelocity,
162 density, subgridDistances, listIndices, nodeIndex);
164 wallMomentum += writeDistributionsBB(populationReferences, linkIsCut, populationsBouncedBack, fakeWallVelocity,
165 density, listIndices);
167 wallModelParams.frictionVelocity[nodeIndex] = frictionVelocity;
168 wallModelParams.forceX[nodeIndex] = wallMomentum.x;
169 wallModelParams.forceY[nodeIndex] = wallMomentum.y;
170 wallModelParams.forceZ[nodeIndex] = wallMomentum.z;