VirtualFluids 0.2.0
Parallel CFD LBM Solver
Loading...
Searching...
No Matches
DampingLayer.cu
Go to the documentation of this file.
1//=======================================================================================
2// ____ ____ __ ______ __________ __ __ __ __
3// \ \ | | | | | _ \ |___ ___| | | | | / \ | |
4// \ \ | | | | | |_) | | | | | | | / \ | |
5// \ \ | | | | | _ / | | | | | | / /\ \ | |
6// \ \ | | | | | | \ \ | | | \__/ | / ____ \ | |____
7// \ \ | | |__| |__| \__\ |__| \________/ /__/ \__\ |_______|
8// \ \ | | ________________________________________________________________
9// \ \ | | | ______________________________________________________________|
10// \ \| | | | __ __ __ __ ______ _______
11// \ | | |_____ | | | | | | | | | _ \ / _____)
12// \ | | _____| | | | | | | | | | | \ \ \_______
13// \ | | | | |_____ | \_/ | | | | |_/ / _____ |
14// \ _____| |__| |________| \_______/ |__| |______/ (_______/
15//
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.
20//
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
24// for more details.
25//
26// SPDX-License-Identifier: GPL-3.0-or-later
27// SPDX-FileCopyrightText: Copyright © VirtualFluids Project contributors, see AUTHORS.md in root folder
28//
29//! \author Henry Korb
30//=======================================================================================
31#include "Axis.h"
32#include "DampingLayer.h"
33
34#include <cmath>
35#include <stdexcept>
36
37#include <cuda.h>
38
39#include <basics/DataTypes.h>
40
41#include <cuda_helper/CudaIndexCalculation.h>
42
43#include "gpu/core/Cuda/CudaMemoryManager.h"
44#include "gpu/core/DataStructureInitializer/GridProvider.h"
45#include "gpu/core/Parameter/Parameter.h"
46#include "gpu/core/Utilities/KernelUtilities.h"
47#include "gpu/cuda_helper/CudaGrid.h"
48
49namespace vf::gpu {
50
51__global__ void rayleighDampingLayerKernel(const real* coefficients, const real* velocity, real* force, const uint* indices,
52 uint numberOfNodes)
53{
54 const uint localIndex = vf::cuda::get1DIndexFrom2DBlock();
55 if (localIndex >= numberOfNodes)
56 return;
57 const uint globalIndex = indices[localIndex];
58 force[globalIndex] -= velocity[globalIndex] * coefficients[localIndex];
59}
60
61void DampingLayer::init()
62{
63 if (dampingLayerType == DampingLayerType::Rayleigh && !para->getIsBodyForce()) {
64 throw std::runtime_error("Rayleigh damping requires body force to be enabled");
65 }
66 for (int level = 0; level <= para->getMaxLevel(); level++) {
67 makeDampingLayerData(level);
68 }
69}
70
71void DampingLayer::makeDampingLayerData(int level)
72{
73 DampingLayerData& data = dampingLayerData.emplace_back();
74 real* coordinate;
75 std::vector<uint> indices;
76 std::vector<real> dampingFactor, minimumValue;
77 switch (direction) {
78 case Axis::x:
79 coordinate = para->getParH(level)->coordinateX;
80 break;
81 case Axis::y:
82 coordinate = para->getParH(level)->coordinateY;
83 break;
84 case Axis::z:
85 coordinate = para->getParH(level)->coordinateZ;
86 break;
87 default:
88 throw std::runtime_error("Direction not implemented");
89 }
90
91 real start = startPosition, end = endPosition;
92
93 for (uint index = 1; index < para->getParH(level)->numberOfNodes; index++) {
94 const real coord = coordinate[index];
95 if (coord < endPosition && coord > startPosition) {
96 const real normalizedCoordinate = (coord - start) / (end - start);
97 indices.push_back(index);
98 dampingFactor.push_back(dampingFunction(normalizedCoordinate));
99 }
100 }
101
102 data.numberOfNodes = static_cast<uint>(indices.size());
103
104 cudaMemoryManager->cudaAllocDampingLayerData(this, level);
105 std::copy(indices.begin(), indices.end(), data.indicesH);
106 std::copy(dampingFactor.begin(), dampingFactor.end(), data.dampingCoefficientsH);
107 cudaMemoryManager->cudaCopyDampingLayerDataHtoD(this, level);
108}
109
110void DampingLayer::interact(int level, uint t)
111{
112 auto& data = getDampingLayerData(level);
113 if (data.numberOfNodes == 0)
114 return;
115
116 vf::cuda::CudaGrid grid(para->getParH(level)->numberofthreads, data.numberOfNodes);
117 switch (dampingLayerType) {
118 case DampingLayerType::Rayleigh:
119 rayleighDampingLayerKernel<<<grid.grid, grid.threads>>>(
120 data.dampingCoefficientsD, para->getParD(level)->velocityZ, para->getParD(level)->forceZ_SP, data.indicesD,
121 data.numberOfNodes);
122 break;
123 default:
124 throw std::runtime_error("DampingLayerType not implemented");
125 }
126}
127
128DampingLayer::~DampingLayer()
129{
130 for (int level = 0; level <= para->getMaxLevel(); level++) {
131 cudaMemoryManager->cudaFreeDampingLayerData(this, level);
132 }
133}
134
135void DampingLayer::getTaggedFluidNodes(GridProvider* gridProvider)
136{
137 for (int level = 0; level <= para->getMaxLevel(); level++) {
138 auto& data = getDampingLayerData(level);
139 std::vector<uint> dampingIndices(data.indicesH, data.indicesH + data.numberOfNodes);
140 gridProvider->tagFluidNodeIndices(dampingIndices, CollisionTemplate::WriteMacroVars, level);
141 }
142}
143
144}