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_Utilities Utilities
30//! \ingroup gpu_core core
32//! \author Martin Schoenherr
33//=======================================================================================
34#ifndef GPU_RUNCOLLISIONKERNEL_CUH
35#define GPU_RUNCOLLISIONKERNEL_CUH
37#include <cuda_runtime.h>
39#include <basics/DataTypes.h>
41#include <lbm/collision/CollisionParameter.h>
42#include <lbm/collision/TurbulentViscosity.h>
44#include "cuda_helper/CudaIndexCalculation.h"
45#include "KernelUtilities.h"
50struct GPUCollisionParameter
53 unsigned int* neighborX;
54 unsigned int* neighborY;
55 unsigned int* neighborZ;
61 real* turbulentViscosity;
69 real* quadricLimiters;
71 const uint* fluidNodeIndices;
72 uint numberOfFluidNodes;
75template <typename CollisionFunctor, vf::lbm::TurbulenceModel turbulenceModel, bool writeMacroscopicVariables, bool applyBodyForce>
76__global__ void runCollision(CollisionFunctor collision, GPUCollisionParameter collisionParameter)
78 const unsigned nodeIndex = vf::cuda::get1DIndexFrom2DBlock();
80 if (nodeIndex >= collisionParameter.numberOfFluidNodes)
83 const unsigned k_000 = collisionParameter.fluidNodeIndices[nodeIndex];
85 vf::lbm::CollisionParameter para;
86 para.omega = collisionParameter.omega;
87 para.quadricLimiter = collisionParameter.quadricLimiters;
89 para.forceX = collisionParameter.forces[0] * collisionParameter.forceFactor;
90 para.forceY = collisionParameter.forces[1] * collisionParameter.forceFactor;
91 para.forceZ = collisionParameter.forces[2] * collisionParameter.forceFactor;
94#ifndef VF_DOUBLE_ACCURACY
95 //atomic exchange significantly faster but only implemented for single precision
96 para.forceX += atomicExch(&collisionParameter.bodyForceX[k_000], basics::constant::c0o1);
97 para.forceY += atomicExch(&collisionParameter.bodyForceY[k_000], basics::constant::c0o1);
98 para.forceZ += atomicExch(&collisionParameter.bodyForceZ[k_000], basics::constant::c0o1);
100 para.forceX += collisionParameter.bodyForceX[k_000];
101 para.forceY += collisionParameter.bodyForceY[k_000];
102 para.forceZ += collisionParameter.bodyForceZ[k_000];
103 collisionParameter.bodyForceX[k_000] = basics::constant::c0o1;
104 collisionParameter.bodyForceY[k_000] = basics::constant::c0o1;
105 collisionParameter.bodyForceZ[k_000] = basics::constant::c0o1;
109 vf::lbm::TurbulentViscosity turbulentViscosity;
110 if (turbulenceModel != vf::lbm::TurbulenceModel::None) {
111 turbulentViscosity.value = collisionParameter.turbulentViscosity[k_000];
112 turbulentViscosity.SGSconstant = collisionParameter.SGSconstant;
115 Distributions27 dist;
116 getPointersToDistributions(dist, collisionParameter.distributions, collisionParameter.numberOfLBnodes,
117 collisionParameter.isEvenTimestep);
119 ListIndices listIndices(k_000, collisionParameter.neighborX, collisionParameter.neighborY, collisionParameter.neighborZ);
121 getPreCollisionDistribution(para.distribution, dist, listIndices);
123 vf::lbm::MacroscopicValues macroscopicValues;
124 collision(para, macroscopicValues, turbulentViscosity);
126 if (writeMacroscopicVariables || turbulenceModel == vf::lbm::TurbulenceModel::AMD) {
127 collisionParameter.vx[k_000] = macroscopicValues.vx;
128 collisionParameter.vy[k_000] = macroscopicValues.vy;
129 collisionParameter.vz[k_000] = macroscopicValues.vz;
130 collisionParameter.rho[k_000] = macroscopicValues.rho;
132 if (turbulenceModel != vf::lbm::TurbulenceModel::None)
133 collisionParameter.turbulentViscosity[k_000] = turbulentViscosity.value;
135 setPostCollisionDistribution(dist, listIndices, para.distribution);
138} // namespace vf::gpu