diff --git a/apps/gpu/LBM/ActuatorLine/ActuatorLine.cpp b/apps/gpu/LBM/ActuatorLine/ActuatorLine.cpp index 58e5aede18b9c4197b4d21b129c6347023b9390e..a6583214d3dbfa9109e869f680a112b81e43a0b2 100644 --- a/apps/gpu/LBM/ActuatorLine/ActuatorLine.cpp +++ b/apps/gpu/LBM/ActuatorLine/ActuatorLine.cpp @@ -45,6 +45,7 @@ #include "VirtualFluids_GPU/Parameter/Parameter.h" #include "VirtualFluids_GPU/Output/FileWriter.h" #include "VirtualFluids_GPU/PreCollisionInteractor/ActuatorLine.h" +#include "VirtualFluids_GPU/PreCollisionInteractor/ActuatorFarm.h" #include "VirtualFluids_GPU/PreCollisionInteractor/Probes/PointProbe.h" #include "VirtualFluids_GPU/PreCollisionInteractor/Probes/PlaneProbe.h" #include "VirtualFluids_GPU/Factories/BoundaryConditionFactory.h" @@ -65,9 +66,9 @@ LbmOrGks lbmOrGks = LBM; const real reference_diameter = 126.0; // diameter in m -const real L_x = 10*reference_diameter; -const real L_y = 6*reference_diameter; -const real L_z = 6*reference_diameter; +const real L_x = 30*reference_diameter; +const real L_y = 10*reference_diameter; +const real L_z = 10*reference_diameter; const real viscosity = 1.56e-5; @@ -75,7 +76,7 @@ const real velocity = 9.0; const real mach = 0.1; -const uint nodes_per_diameter = 16; +const uint nodes_per_diameter = 32; std::string path("."); @@ -182,25 +183,30 @@ void multipleLevel(const std::string& configPath) int level = 0; uint nBlades = 3; uint nBladeNodes = 32; - - SPtr<ActuatorLine> actuator_line =SPtr<ActuatorLine>( new ActuatorLine(nBlades, density, nBladeNodes, epsilon, turbPos[0], turbPos[1], turbPos[2], reference_diameter, level, dt, dx) ); - para->addActuator( actuator_line ); - - SPtr<PointProbe> pointProbe = SPtr<PointProbe>( new PointProbe("pointProbe", para->getOutputPath(), 100, 1, 500, 100) ); - std::vector<real> probeCoordsX = {reference_diameter,2*reference_diameter,5*reference_diameter}; - std::vector<real> probeCoordsY = {3*reference_diameter,3*reference_diameter,3*reference_diameter}; - std::vector<real> probeCoordsZ = {3*reference_diameter,3*reference_diameter,3*reference_diameter}; - pointProbe->addProbePointsFromList(probeCoordsX, probeCoordsY, probeCoordsZ); - // pointProbe->addProbePointsFromXNormalPlane(2*D, 0.0, 0.0, L_y, L_z, (uint)L_y/dx, (uint)L_z/dx); - - pointProbe->addStatistic(Statistic::Means); - pointProbe->addStatistic(Statistic::Variances); - para->addProbe( pointProbe ); - - SPtr<PlaneProbe> planeProbe = SPtr<PlaneProbe>( new PlaneProbe("planeProbe", para->getOutputPath(), 100, 500, 100, 100) ); - planeProbe->setProbePlane(5*reference_diameter, 0, 0, dx, L_y, L_z); - planeProbe->addStatistic(Statistic::Means); - para->addProbe( planeProbe ); + real omega = 1.0f; + // SPtr<ActuatorLine> actuator_line =SPtr<ActuatorLine>( new ActuatorLine(nBlades, density, nBladeNodes, epsilon, turbPos[0], turbPos[1], turbPos[2], reference_diameter, level, dt, dx) ); + SPtr<ActuatorFarm> actuator_farm = std::make_shared<ActuatorFarm>(nBlades, density, nBladeNodes, epsilon, level, dt, dx, false); + std::vector<real> bladeRadii; + real dr = reference_diameter/nBladeNodes; + for(uint node=0; node<nBladeNodes; node++){bladeRadii.emplace_back(dr*(node+1));} + actuator_farm->addTurbine(turbPos[0], turbPos[1], turbPos[2], reference_diameter, omega, 0, 0, bladeRadii); + para->addActuator( actuator_farm ); + + // SPtr<PointProbe> pointProbe = SPtr<PointProbe>( new PointProbe("pointProbe", para->getOutputPath(), 100, 1, 500, 100) ); + // std::vector<real> probeCoordsX = {reference_diameter,2*reference_diameter,5*reference_diameter}; + // std::vector<real> probeCoordsY = {3*reference_diameter,3*reference_diameter,3*reference_diameter}; + // std::vector<real> probeCoordsZ = {3*reference_diameter,3*reference_diameter,3*reference_diameter}; + // pointProbe->addProbePointsFromList(probeCoordsX, probeCoordsY, probeCoordsZ); + // // pointProbe->addProbePointsFromXNormalPlane(2*D, 0.0, 0.0, L_y, L_z, (uint)L_y/dx, (uint)L_z/dx); + + // pointProbe->addStatistic(Statistic::Means); + // pointProbe->addStatistic(Statistic::Variances); + // para->addProbe( pointProbe ); + + // SPtr<PlaneProbe> planeProbe = SPtr<PlaneProbe>( new PlaneProbe("planeProbe", para->getOutputPath(), 100, 500, 100, 100) ); + // planeProbe->setProbePlane(5*reference_diameter, 0, 0, dx, L_y, L_z); + // planeProbe->addStatistic(Statistic::Means); + // para->addProbe( planeProbe ); auto cudaMemoryManager = std::make_shared<CudaMemoryManager>(para); diff --git a/src/gpu/VirtualFluids_GPU/GPU/CudaMemoryManager.cpp b/src/gpu/VirtualFluids_GPU/GPU/CudaMemoryManager.cpp index 22192216927f91c33fafc23c54c3fae334abdd34..f3d46757a128e30c7983ba3f842d27c4c14588a8 100644 --- a/src/gpu/VirtualFluids_GPU/GPU/CudaMemoryManager.cpp +++ b/src/gpu/VirtualFluids_GPU/GPU/CudaMemoryManager.cpp @@ -7,6 +7,7 @@ #include <Parameter/Parameter.h> #include "Parameter/CudaStreamManager.h" #include "PreCollisionInteractor/ActuatorLine.h" +#include "PreCollisionInteractor/ActuatorFarm.h" #include "PreCollisionInteractor/Probes/Probe.h" #include "Calculation/PorousMedia.h" @@ -3147,6 +3148,253 @@ void CudaMemoryManager::cudaFreeSphereIndices(ActuatorLine* actuatorLine) checkCudaErrors( cudaFreeHost(actuatorLine->boundingSphereIndicesH) ); checkCudaErrors( cudaFree(actuatorLine->boundingSphereIndicesD) ); } +//////////////////////////////////////////////////////////////////////////////////// +// ActuatorFarm +/////////////////////////////////////////////////////////////////////////////// +void CudaMemoryManager::cudaAllocBladeGeometries(ActuatorFarm* actuatorFarm) +{ + uint sizeRealTurbine = sizeof(real)*actuatorFarm->getNTurbines(); + checkCudaErrors( cudaMallocHost((void**) &actuatorFarm->bladeRadiiH, sizeRealTurbine*actuatorFarm->getNBladeNodes()) ); + checkCudaErrors( cudaMallocHost((void**) &actuatorFarm->diametersH, sizeRealTurbine) ); + checkCudaErrors( cudaMallocHost((void**) &actuatorFarm->turbinePosXH, sizeRealTurbine) ); + checkCudaErrors( cudaMallocHost((void**) &actuatorFarm->turbinePosYH, sizeRealTurbine) ); + checkCudaErrors( cudaMallocHost((void**) &actuatorFarm->turbinePosZH, sizeRealTurbine) ); + + checkCudaErrors( cudaMalloc((void**) &actuatorFarm->bladeRadiiD, sizeRealTurbine*actuatorFarm->getNBladeNodes()) ); + checkCudaErrors( cudaMalloc((void**) &actuatorFarm->diametersD, sizeRealTurbine) ); + checkCudaErrors( cudaMalloc((void**) &actuatorFarm->turbinePosXD, sizeRealTurbine) ); + checkCudaErrors( cudaMalloc((void**) &actuatorFarm->turbinePosYD, sizeRealTurbine) ); + checkCudaErrors( cudaMalloc((void**) &actuatorFarm->turbinePosZD, sizeRealTurbine) ); + setMemsizeGPU(sizeof(real)*(actuatorFarm->getNBladeNodes()+4)*actuatorFarm->getNTurbines(), false); + +} +void CudaMemoryManager::cudaCopyBladeGeometriesHtoD(ActuatorFarm* actuatorFarm) +{ + uint sizeRealTurbine = sizeof(real)*actuatorFarm->getNTurbines(); + checkCudaErrors( cudaMemcpy(actuatorFarm->bladeRadiiD, actuatorFarm->bladeRadiiH, sizeRealTurbine*actuatorFarm->getNBladeNodes(), cudaMemcpyHostToDevice) ); + checkCudaErrors( cudaMemcpy(actuatorFarm->diametersD, actuatorFarm->diametersH, sizeRealTurbine, cudaMemcpyHostToDevice) ); + checkCudaErrors( cudaMemcpy(actuatorFarm->turbinePosXD, actuatorFarm->turbinePosXH, sizeRealTurbine, cudaMemcpyHostToDevice) ); + checkCudaErrors( cudaMemcpy(actuatorFarm->turbinePosYD, actuatorFarm->turbinePosYH, sizeRealTurbine, cudaMemcpyHostToDevice) ); + checkCudaErrors( cudaMemcpy(actuatorFarm->turbinePosZD, actuatorFarm->turbinePosZH, sizeRealTurbine, cudaMemcpyHostToDevice) ); + +} +void CudaMemoryManager::cudaCopyBladeGeometriesDtoH(ActuatorFarm* actuatorFarm) +{ + uint sizeRealTurbine = sizeof(real)*actuatorFarm->getNTurbines(); + checkCudaErrors( cudaMemcpy(actuatorFarm->bladeRadiiH, actuatorFarm->bladeRadiiD, sizeRealTurbine*actuatorFarm->getNBladeNodes(), cudaMemcpyDeviceToHost) ); + checkCudaErrors( cudaMemcpy(actuatorFarm->diametersH, actuatorFarm->diametersD, sizeRealTurbine, cudaMemcpyDeviceToHost) ); + checkCudaErrors( cudaMemcpy(actuatorFarm->turbinePosXH, actuatorFarm->turbinePosXD, sizeRealTurbine, cudaMemcpyDeviceToHost) ); + checkCudaErrors( cudaMemcpy(actuatorFarm->turbinePosYH, actuatorFarm->turbinePosYD, sizeRealTurbine, cudaMemcpyDeviceToHost) ); + checkCudaErrors( cudaMemcpy(actuatorFarm->turbinePosZH, actuatorFarm->turbinePosZD, sizeRealTurbine, cudaMemcpyDeviceToHost) ); + +} +void CudaMemoryManager::cudaFreeBladeGeometries(ActuatorFarm* actuatorFarm) +{ + checkCudaErrors( cudaFree(actuatorFarm->bladeRadiiD) ); + checkCudaErrors( cudaFree(actuatorFarm->diametersD) ); + checkCudaErrors( cudaFree(actuatorFarm->turbinePosXD) ); + checkCudaErrors( cudaFree(actuatorFarm->turbinePosYD) ); + checkCudaErrors( cudaFree(actuatorFarm->turbinePosZD) ); + + checkCudaErrors( cudaFreeHost(actuatorFarm->bladeRadiiH) ); + checkCudaErrors( cudaFreeHost(actuatorFarm->diametersH) ); + checkCudaErrors( cudaFreeHost(actuatorFarm->turbinePosXH) ); + checkCudaErrors( cudaFreeHost(actuatorFarm->turbinePosYH) ); + checkCudaErrors( cudaFreeHost(actuatorFarm->turbinePosZH) ); +} + +void CudaMemoryManager::cudaAllocBladeOrientations(ActuatorFarm* actuatorFarm) +{ + uint sizeRealTurbine = sizeof(real)*actuatorFarm->getNTurbines(); + checkCudaErrors( cudaMallocHost((void**) &actuatorFarm->omegasH, sizeRealTurbine) ); + checkCudaErrors( cudaMallocHost((void**) &actuatorFarm->azimuthsH, sizeRealTurbine) ); + checkCudaErrors( cudaMallocHost((void**) &actuatorFarm->yawsH, sizeRealTurbine) ); + + checkCudaErrors( cudaMalloc((void**) &actuatorFarm->omegasD, sizeRealTurbine) ); + checkCudaErrors( cudaMalloc((void**) &actuatorFarm->azimuthsD, sizeRealTurbine) ); + checkCudaErrors( cudaMalloc((void**) &actuatorFarm->yawsD, sizeRealTurbine) ); + + setMemsizeGPU(3*sizeRealTurbine, false); + +} +void CudaMemoryManager::cudaCopyBladeOrientationsHtoD(ActuatorFarm* actuatorFarm) +{ + uint sizeRealTurbine = sizeof(real)*actuatorFarm->getNTurbines(); + checkCudaErrors( cudaMemcpy(actuatorFarm->omegasD, actuatorFarm->omegasH, sizeRealTurbine, cudaMemcpyHostToDevice) ); + checkCudaErrors( cudaMemcpy(actuatorFarm->azimuthsD, actuatorFarm->azimuthsH, sizeRealTurbine, cudaMemcpyHostToDevice) ); + checkCudaErrors( cudaMemcpy(actuatorFarm->yawsD, actuatorFarm->yawsH, sizeRealTurbine, cudaMemcpyHostToDevice) ); + +} +void CudaMemoryManager::cudaCopyBladeOrientationsDtoH(ActuatorFarm* actuatorFarm) +{ + uint sizeRealTurbine = sizeof(real)*actuatorFarm->getNTurbines(); + checkCudaErrors( cudaMemcpy(actuatorFarm->omegasH, actuatorFarm->omegasD, sizeRealTurbine, cudaMemcpyDeviceToHost) ); + checkCudaErrors( cudaMemcpy(actuatorFarm->azimuthsH, actuatorFarm->azimuthsD, sizeRealTurbine, cudaMemcpyDeviceToHost) ); + checkCudaErrors( cudaMemcpy(actuatorFarm->yawsH, actuatorFarm->yawsD, sizeRealTurbine, cudaMemcpyDeviceToHost) ); +} +void CudaMemoryManager::cudaFreeBladeOrientations(ActuatorFarm* actuatorFarm) +{ + checkCudaErrors( cudaFree((void**) &actuatorFarm->omegasD) ); + checkCudaErrors( cudaFree((void**) &actuatorFarm->azimuthsD) ); + checkCudaErrors( cudaFree((void**) &actuatorFarm->yawsD) ); + + checkCudaErrors( cudaFreeHost((void**) &actuatorFarm->omegasH) ); + checkCudaErrors( cudaFreeHost((void**) &actuatorFarm->azimuthsH) ); + checkCudaErrors( cudaFreeHost((void**) &actuatorFarm->yawsH) ); +} + +void CudaMemoryManager::cudaAllocBladeCoords(ActuatorFarm* actuatorFarm) +{ + checkCudaErrors( cudaMallocHost((void**) &actuatorFarm->bladeCoordsXH, sizeof(real)*actuatorFarm->getNumberOfNodes()) ); + checkCudaErrors( cudaMallocHost((void**) &actuatorFarm->bladeCoordsYH, sizeof(real)*actuatorFarm->getNumberOfNodes()) ); + checkCudaErrors( cudaMallocHost((void**) &actuatorFarm->bladeCoordsZH, sizeof(real)*actuatorFarm->getNumberOfNodes()) ); + + checkCudaErrors( cudaMalloc((void**) &actuatorFarm->bladeCoordsXD, sizeof(real)*actuatorFarm->getNumberOfNodes()) ); + checkCudaErrors( cudaMalloc((void**) &actuatorFarm->bladeCoordsYD, sizeof(real)*actuatorFarm->getNumberOfNodes()) ); + checkCudaErrors( cudaMalloc((void**) &actuatorFarm->bladeCoordsZD, sizeof(real)*actuatorFarm->getNumberOfNodes()) ); + + setMemsizeGPU(3.f*actuatorFarm->getNumberOfNodes(), false); +} + +void CudaMemoryManager::cudaCopyBladeCoordsHtoD(ActuatorFarm* actuatorFarm) +{ + checkCudaErrors( cudaMemcpy(actuatorFarm->bladeCoordsXD, actuatorFarm->bladeCoordsXH, sizeof(real)*actuatorFarm->getNumberOfNodes(), cudaMemcpyHostToDevice) ); + checkCudaErrors( cudaMemcpy(actuatorFarm->bladeCoordsYD, actuatorFarm->bladeCoordsYH, sizeof(real)*actuatorFarm->getNumberOfNodes(), cudaMemcpyHostToDevice) ); + checkCudaErrors( cudaMemcpy(actuatorFarm->bladeCoordsZD, actuatorFarm->bladeCoordsZH, sizeof(real)*actuatorFarm->getNumberOfNodes(), cudaMemcpyHostToDevice) ); +} + +void CudaMemoryManager::cudaCopyBladeCoordsDtoH(ActuatorFarm* actuatorFarm) +{ + checkCudaErrors( cudaMemcpy(actuatorFarm->bladeCoordsXH, actuatorFarm->bladeCoordsXD, sizeof(real)*actuatorFarm->getNumberOfNodes(), cudaMemcpyDeviceToHost) ); + checkCudaErrors( cudaMemcpy(actuatorFarm->bladeCoordsYH, actuatorFarm->bladeCoordsYD, sizeof(real)*actuatorFarm->getNumberOfNodes(), cudaMemcpyDeviceToHost) ); + checkCudaErrors( cudaMemcpy(actuatorFarm->bladeCoordsZH, actuatorFarm->bladeCoordsZD, sizeof(real)*actuatorFarm->getNumberOfNodes(), cudaMemcpyDeviceToHost) ); +} + +void CudaMemoryManager::cudaFreeBladeCoords(ActuatorFarm* actuatorFarm) +{ + checkCudaErrors( cudaFree(actuatorFarm->bladeCoordsXD) ); + checkCudaErrors( cudaFree(actuatorFarm->bladeCoordsYD) ); + checkCudaErrors( cudaFree(actuatorFarm->bladeCoordsZD) ); + + checkCudaErrors( cudaFreeHost(actuatorFarm->bladeCoordsXH) ); + checkCudaErrors( cudaFreeHost(actuatorFarm->bladeCoordsYH) ); + checkCudaErrors( cudaFreeHost(actuatorFarm->bladeCoordsZH) ); +} + +void CudaMemoryManager::cudaAllocBladeIndices(ActuatorFarm* actuatorFarm) +{ + checkCudaErrors( cudaMallocHost((void**) &actuatorFarm->bladeIndicesH, sizeof(uint)*actuatorFarm->getNumberOfNodes()) ); + + checkCudaErrors( cudaMalloc((void**) &actuatorFarm->bladeIndicesD, sizeof(uint)*actuatorFarm->getNumberOfNodes()) ); + + setMemsizeGPU(sizeof(uint)*actuatorFarm->getNumberOfNodes(), false); +} + +void CudaMemoryManager::cudaCopyBladeIndicesHtoD(ActuatorFarm* actuatorFarm) +{ + checkCudaErrors( cudaMemcpy(actuatorFarm->bladeIndicesD, actuatorFarm->bladeIndicesH, sizeof(uint)*actuatorFarm->getNumberOfNodes(), cudaMemcpyHostToDevice) ); +} + +void CudaMemoryManager::cudaFreeBladeIndices(ActuatorFarm* actuatorFarm) +{ + checkCudaErrors( cudaFree(actuatorFarm->bladeIndicesD) ); + + checkCudaErrors( cudaFreeHost(actuatorFarm->bladeIndicesH) ); +} + +void CudaMemoryManager::cudaAllocBladeVelocities(ActuatorFarm* actuatorFarm) +{ + checkCudaErrors( cudaMallocHost((void**) &actuatorFarm->bladeVelocitiesXH, sizeof(real)*actuatorFarm->getNumberOfNodes()) ); + checkCudaErrors( cudaMallocHost((void**) &actuatorFarm->bladeVelocitiesYH, sizeof(real)*actuatorFarm->getNumberOfNodes()) ); + checkCudaErrors( cudaMallocHost((void**) &actuatorFarm->bladeVelocitiesZH, sizeof(real)*actuatorFarm->getNumberOfNodes()) ); + + checkCudaErrors( cudaMalloc((void**) &actuatorFarm->bladeVelocitiesXD, sizeof(real)*actuatorFarm->getNumberOfNodes()) ); + checkCudaErrors( cudaMalloc((void**) &actuatorFarm->bladeVelocitiesYD, sizeof(real)*actuatorFarm->getNumberOfNodes()) ); + checkCudaErrors( cudaMalloc((void**) &actuatorFarm->bladeVelocitiesZD, sizeof(real)*actuatorFarm->getNumberOfNodes()) ); + + setMemsizeGPU(3.*sizeof(real)*actuatorFarm->getNumberOfNodes(), false); +} + +void CudaMemoryManager::cudaCopyBladeVelocitiesHtoD(ActuatorFarm* actuatorFarm) +{ + checkCudaErrors( cudaMemcpy(actuatorFarm->bladeVelocitiesXD, actuatorFarm->bladeVelocitiesXH, sizeof(real)*actuatorFarm->getNumberOfNodes(), cudaMemcpyHostToDevice) ); + checkCudaErrors( cudaMemcpy(actuatorFarm->bladeVelocitiesYD, actuatorFarm->bladeVelocitiesYH, sizeof(real)*actuatorFarm->getNumberOfNodes(), cudaMemcpyHostToDevice) ); + checkCudaErrors( cudaMemcpy(actuatorFarm->bladeVelocitiesZD, actuatorFarm->bladeVelocitiesZH, sizeof(real)*actuatorFarm->getNumberOfNodes(), cudaMemcpyHostToDevice) ); +} + +void CudaMemoryManager::cudaCopyBladeVelocitiesDtoH(ActuatorFarm* actuatorFarm) +{ + checkCudaErrors( cudaMemcpy(actuatorFarm->bladeVelocitiesXH, actuatorFarm->bladeVelocitiesXD, sizeof(real)*actuatorFarm->getNumberOfNodes(), cudaMemcpyDeviceToHost) ); + checkCudaErrors( cudaMemcpy(actuatorFarm->bladeVelocitiesYH, actuatorFarm->bladeVelocitiesYD, sizeof(real)*actuatorFarm->getNumberOfNodes(), cudaMemcpyDeviceToHost) ); + checkCudaErrors( cudaMemcpy(actuatorFarm->bladeVelocitiesZH, actuatorFarm->bladeVelocitiesZD, sizeof(real)*actuatorFarm->getNumberOfNodes(), cudaMemcpyDeviceToHost) ); +} + +void CudaMemoryManager::cudaFreeBladeVelocities(ActuatorFarm* actuatorFarm) +{ + checkCudaErrors( cudaFree(actuatorFarm->bladeVelocitiesXD) ); + checkCudaErrors( cudaFree(actuatorFarm->bladeVelocitiesYD) ); + checkCudaErrors( cudaFree(actuatorFarm->bladeVelocitiesZD) ); + + checkCudaErrors( cudaFreeHost(actuatorFarm->bladeVelocitiesXH) ); + checkCudaErrors( cudaFreeHost(actuatorFarm->bladeVelocitiesYH) ); + checkCudaErrors( cudaFreeHost(actuatorFarm->bladeVelocitiesZH) ); +} + +void CudaMemoryManager::cudaAllocBladeForces(ActuatorFarm* actuatorFarm) +{ + checkCudaErrors( cudaMallocHost((void**) &actuatorFarm->bladeForcesXH, sizeof(real)*actuatorFarm->getNumberOfNodes()) ); + checkCudaErrors( cudaMallocHost((void**) &actuatorFarm->bladeForcesYH, sizeof(real)*actuatorFarm->getNumberOfNodes()) ); + checkCudaErrors( cudaMallocHost((void**) &actuatorFarm->bladeForcesZH, sizeof(real)*actuatorFarm->getNumberOfNodes()) ); + + checkCudaErrors( cudaMalloc((void**) &actuatorFarm->bladeForcesXD, sizeof(real)*actuatorFarm->getNumberOfNodes()) ); + checkCudaErrors( cudaMalloc((void**) &actuatorFarm->bladeForcesYD, sizeof(real)*actuatorFarm->getNumberOfNodes()) ); + checkCudaErrors( cudaMalloc((void**) &actuatorFarm->bladeForcesZD, sizeof(real)*actuatorFarm->getNumberOfNodes()) ); + + setMemsizeGPU(3.*sizeof(real)*actuatorFarm->getNumberOfNodes(), false); +} + +void CudaMemoryManager::cudaCopyBladeForcesHtoD(ActuatorFarm* actuatorFarm) +{ + checkCudaErrors( cudaMemcpy(actuatorFarm->bladeForcesXD, actuatorFarm->bladeForcesXH, sizeof(real)*actuatorFarm->getNumberOfNodes(), cudaMemcpyHostToDevice) ); + checkCudaErrors( cudaMemcpy(actuatorFarm->bladeForcesYD, actuatorFarm->bladeForcesYH, sizeof(real)*actuatorFarm->getNumberOfNodes(), cudaMemcpyHostToDevice) ); + checkCudaErrors( cudaMemcpy(actuatorFarm->bladeForcesZD, actuatorFarm->bladeForcesZH, sizeof(real)*actuatorFarm->getNumberOfNodes(), cudaMemcpyHostToDevice) ); +} + +void CudaMemoryManager::cudaCopyBladeForcesDtoH(ActuatorFarm* actuatorFarm) +{ + checkCudaErrors( cudaMemcpy(actuatorFarm->bladeForcesXH, actuatorFarm->bladeForcesXD, sizeof(real)*actuatorFarm->getNumberOfNodes(), cudaMemcpyDeviceToHost) ); + checkCudaErrors( cudaMemcpy(actuatorFarm->bladeForcesYH, actuatorFarm->bladeForcesYD, sizeof(real)*actuatorFarm->getNumberOfNodes(), cudaMemcpyDeviceToHost) ); + checkCudaErrors( cudaMemcpy(actuatorFarm->bladeForcesZH, actuatorFarm->bladeForcesZD, sizeof(real)*actuatorFarm->getNumberOfNodes(), cudaMemcpyDeviceToHost) ); +} + +void CudaMemoryManager::cudaFreeBladeForces(ActuatorFarm* actuatorFarm) +{ + checkCudaErrors( cudaFree(actuatorFarm->bladeForcesXD) ); + checkCudaErrors( cudaFree(actuatorFarm->bladeForcesYD) ); + checkCudaErrors( cudaFree(actuatorFarm->bladeForcesZD) ); + + checkCudaErrors( cudaFreeHost(actuatorFarm->bladeForcesXH) ); + checkCudaErrors( cudaFreeHost(actuatorFarm->bladeForcesYH) ); + checkCudaErrors( cudaFreeHost(actuatorFarm->bladeForcesZH) ); +} + +void CudaMemoryManager::cudaAllocSphereIndices(ActuatorFarm* actuatorFarm) +{ + checkCudaErrors( cudaMallocHost((void**) &(actuatorFarm->boundingSphereIndicesH), sizeof(int)*actuatorFarm->getNumberOfIndices())); + checkCudaErrors( cudaMalloc((void**) &(actuatorFarm->boundingSphereIndicesD), sizeof(int)*actuatorFarm->getNumberOfIndices())); + setMemsizeGPU(sizeof(int)*actuatorFarm->getNumberOfIndices(), false); +} + +void CudaMemoryManager::cudaCopySphereIndicesHtoD(ActuatorFarm* actuatorFarm) +{ + checkCudaErrors( cudaMemcpy(actuatorFarm->boundingSphereIndicesD, actuatorFarm->boundingSphereIndicesH, sizeof(int)*actuatorFarm->getNumberOfIndices(), cudaMemcpyHostToDevice) ); +} + +void CudaMemoryManager::cudaFreeSphereIndices(ActuatorFarm* actuatorFarm) +{ + checkCudaErrors( cudaFreeHost(actuatorFarm->boundingSphereIndicesH) ); + checkCudaErrors( cudaFree(actuatorFarm->boundingSphereIndicesD) ); +} //////////////////////////////////////////////////////////////////////////////////// // Probe diff --git a/src/gpu/VirtualFluids_GPU/GPU/CudaMemoryManager.h b/src/gpu/VirtualFluids_GPU/GPU/CudaMemoryManager.h index 8df1b412c760ef3298f4426c206777d5c1db1b54..beb87ba639e160cc6be6e036f615dabe80d0b865 100644 --- a/src/gpu/VirtualFluids_GPU/GPU/CudaMemoryManager.h +++ b/src/gpu/VirtualFluids_GPU/GPU/CudaMemoryManager.h @@ -19,6 +19,7 @@ class Parameter; class PorousMedia; class ActuatorLine; +class ActuatorFarm; class Probe; class VIRTUALFLUIDS_GPU_EXPORT CudaMemoryManager @@ -381,6 +382,40 @@ public: void cudaCopySphereIndicesHtoD(ActuatorLine* actuatorLine); void cudaFreeSphereIndices(ActuatorLine* actuatorLine); + // ActuatorFarm + void cudaAllocBladeGeometries(ActuatorFarm* actuatorFarm); + void cudaCopyBladeGeometriesHtoD(ActuatorFarm* actuatorFarm); + void cudaCopyBladeGeometriesDtoH(ActuatorFarm* actuatorFarm); + void cudaFreeBladeGeometries(ActuatorFarm* actuatorFarm); + + void cudaAllocBladeOrientations(ActuatorFarm* actuatorFarm); + void cudaCopyBladeOrientationsHtoD(ActuatorFarm* actuatorFarm); + void cudaCopyBladeOrientationsDtoH(ActuatorFarm* actuatorFarm); + void cudaFreeBladeOrientations(ActuatorFarm* actuatorFarm); + + void cudaAllocBladeCoords(ActuatorFarm* actuatorFarm); + void cudaCopyBladeCoordsHtoD(ActuatorFarm* actuatorFarm); + void cudaCopyBladeCoordsDtoH(ActuatorFarm* actuatorFarm); + void cudaFreeBladeCoords(ActuatorFarm* actuatorFarm); + + void cudaAllocBladeIndices(ActuatorFarm* actuatorFarm); + void cudaCopyBladeIndicesHtoD(ActuatorFarm* actuatorFarm); + void cudaFreeBladeIndices(ActuatorFarm* actuatorFarm); + + void cudaAllocBladeVelocities(ActuatorFarm* actuatorFarm); + void cudaCopyBladeVelocitiesHtoD(ActuatorFarm* actuatorFarm); + void cudaCopyBladeVelocitiesDtoH(ActuatorFarm* actuatorFarm); + void cudaFreeBladeVelocities(ActuatorFarm* actuatorFarm); + + void cudaAllocBladeForces(ActuatorFarm* actuatorFarm); + void cudaCopyBladeForcesHtoD(ActuatorFarm* actuatorFarm); + void cudaCopyBladeForcesDtoH(ActuatorFarm* actuatorFarm); + void cudaFreeBladeForces(ActuatorFarm* actuatorFarm); + + void cudaAllocSphereIndices(ActuatorFarm* actuatorFarm); + void cudaCopySphereIndicesHtoD(ActuatorFarm* actuatorFarm); + void cudaFreeSphereIndices(ActuatorFarm* actuatorFarm); + // Probes void cudaAllocProbeDistances(Probe* probe, int level); void cudaCopyProbeDistancesHtoD(Probe* probe, int level); void cudaCopyProbeDistancesDtoH(Probe* probe, int level); diff --git a/src/gpu/VirtualFluids_GPU/PreCollisionInteractor/ActuatorFarm.cu b/src/gpu/VirtualFluids_GPU/PreCollisionInteractor/ActuatorFarm.cu new file mode 100644 index 0000000000000000000000000000000000000000..c5e1926d05027a709386632efa4c6bf0bdd85167 --- /dev/null +++ b/src/gpu/VirtualFluids_GPU/PreCollisionInteractor/ActuatorFarm.cu @@ -0,0 +1,551 @@ +#include "ActuatorFarm.h" + +#include <cuda.h> +#include <cuda_runtime.h> +#include <helper_cuda.h> + +#include <cuda/CudaGrid.h> +#include "VirtualFluids_GPU/GPU/GeometryUtils.h" +#include "VirtualFluids_GPU/Kernel/Utilities/DistributionHelper.cuh" + +#include "Parameter/Parameter.h" +#include "DataStructureInitializer/GridProvider.h" +#include "GPU/CudaMemoryManager.h" +#include "lbm/constants/NumericConstants.h" + +using namespace vf::lbm::constant; + + +__host__ __device__ __inline__ uint calcNode(uint bladeNode, uint nBladeNodes, uint blade, uint nBlades, uint turbine, uint nTurbines) +{ + + return bladeNode+nBladeNodes*(blade+turbine*nBlades); +} + +__host__ __device__ __inline__ void calcTurbineBladeAndBladeNode(uint node, uint& bladeNode, uint nBladeNodes, uint& blade, uint nBlades, uint& turbine, uint nTurbines) +{ + turbine = node/(nBladeNodes*nBlades); + uint x_off = turbine*nBladeNodes*nBlades; + blade = (node - x_off)/nBlades; + uint y_off = nBladeNodes*blade+x_off; + bladeNode = (node - y_off)/nBladeNodes; +} + +__host__ __device__ __forceinline__ real distSqrd(real distX, real distY, real distZ) +{ + return distX*distX+distY*distY+distZ*distZ; +} + +__host__ __device__ __inline__ void rotateFromBladeToGlobal( + real& bladeCoordX_BF, real& bladeCoordY_BF, real& bladeCoordZ_BF, + real& bladeCoordX_GF, real& bladeCoordY_GF, real& bladeCoordZ_GF, + real& azimuth, real& yaw) +{ + real tmpX, tmpY, tmpZ; + + rotateAboutX3D(azimuth, bladeCoordX_BF, bladeCoordY_BF, bladeCoordZ_BF, tmpX, tmpY, tmpZ); + rotateAboutZ3D(yaw, tmpX, tmpY, tmpZ, bladeCoordX_GF, bladeCoordY_GF, bladeCoordZ_GF); + +} + +__host__ __device__ __inline__ void rotateFromGlobalToBlade( + real& bladeCoordX_BF, real& bladeCoordY_BF, real& bladeCoordZ_BF, + real& bladeCoordX_GF, real& bladeCoordY_GF, real& bladeCoordZ_GF, + real& azimuth, real& yaw) +{ + real tmpX, tmpY, tmpZ; + + invRotateAboutZ3D(yaw, bladeCoordX_GF, bladeCoordY_GF, bladeCoordZ_GF, tmpX, tmpY, tmpZ); + invRotateAboutX3D(azimuth, tmpX, tmpY, tmpZ, bladeCoordX_BF, bladeCoordY_BF, bladeCoordZ_BF); +} + +__global__ void interpolateVelocities(real* gridCoordsX, real* gridCoordsY, real* gridCoordsZ, + uint* neighborsX, uint* neighborsY, uint* neighborsZ, uint* neighborsWSB, + real* vx, real* vy, real* vz, + real* bladeCoordsX, real* bladeCoordsY, real* bladeCoordsZ, + real* bladeVelocitiesX, real* bladeVelocitiesY, real* bladeVelocitiesZ, + uint nTurbines, uint nBlades, uint nBladeNodes, + real* azimuths, real* yaws, real* omegas, + real* turbPosX, real* turbPosY, real* turbPosZ, + uint* bladeIndices, real velocityRatio, real invDeltaX) +{ + + const uint node = vf::gpu::getNodeIndex(); + + if(node>=nBladeNodes*nBlades*nTurbines) return; + + uint turbine, bladeNode, blade; + + calcTurbineBladeAndBladeNode(node, bladeNode, nBladeNodes, blade, nBlades, turbine, nTurbines); + + real bladeCoordX_BF = bladeCoordsX[node]; + real bladeCoordY_BF = bladeCoordsY[node]; + real bladeCoordZ_BF = bladeCoordsZ[node]; + + real bladeCoordX_GF, bladeCoordY_GF, bladeCoordZ_GF; + + real localAzimuth = azimuths[turbine]+blade*c2Pi/nBlades; + real yaw = yaws[turbine]; + + + rotateFromBladeToGlobal(bladeCoordX_BF, bladeCoordY_BF, bladeCoordZ_BF, + bladeCoordX_GF, bladeCoordY_GF, bladeCoordZ_GF, + localAzimuth, yaw); + + bladeCoordX_GF += turbPosX[turbine]; + bladeCoordY_GF += turbPosY[turbine]; + bladeCoordZ_GF += turbPosZ[turbine]; + + uint k, ke, kn, kt; + uint kne, kte, ktn, ktne; + + k = findNearestCellBSW(bladeIndices[node], + gridCoordsX, gridCoordsY, gridCoordsZ, + bladeCoordX_GF, bladeCoordY_GF, bladeCoordZ_GF, + neighborsX, neighborsY, neighborsZ, neighborsWSB); + + bladeIndices[node] = k; + + getNeighborIndicesOfBSW(k, ke, kn, kt, kne, kte, ktn, ktne, neighborsX, neighborsY, neighborsZ); + + real dW, dE, dN, dS, dT, dB; + + real distX = invDeltaX*(bladeCoordX_GF-gridCoordsX[k]); + real distY = invDeltaX*(bladeCoordY_GF-gridCoordsY[k]); + real distZ = invDeltaX*(bladeCoordZ_GF-gridCoordsZ[k]); + + getInterpolationWeights(dW, dE, dN, dS, dT, dB, distX, distY, distZ); + + real bladeVelX_GF = trilinearInterpolation(dW, dE, dN, dS, dT, dB, k, ke, kn, kt, kne, kte, ktn, ktne, vx)*velocityRatio; + real bladeVelY_GF = trilinearInterpolation(dW, dE, dN, dS, dT, dB, k, ke, kn, kt, kne, kte, ktn, ktne, vy)*velocityRatio; + real bladeVelZ_GF = trilinearInterpolation(dW, dE, dN, dS, dT, dB, k, ke, kn, kt, kne, kte, ktn, ktne, vz)*velocityRatio; + + real bladeVelX_BF, bladeVelY_BF, bladeVelZ_BF; + + + rotateFromGlobalToBlade(bladeVelX_BF, bladeVelY_BF, bladeVelZ_BF, + bladeVelX_GF, bladeVelY_GF, bladeVelZ_GF, + localAzimuth, yaw); + + bladeVelocitiesX[node] = bladeVelX_BF; + bladeVelocitiesY[node] = bladeVelY_BF+omegas[turbine]*bladeCoordZ_BF; + bladeVelocitiesZ[node] = bladeVelZ_BF; +} + + +__global__ void applyBodyForces(real* gridCoordsX, real* gridCoordsY, real* gridCoordsZ, + real* gridForcesX, real* gridForcesY, real* gridForcesZ, + real* bladeCoordsX, real* bladeCoordsY, real* bladeCoordsZ, + real* bladeForcesX, real* bladeForcesY,real* bladeForcesZ, + uint nTurbines, uint nBlades, uint nBladeNodes, + real* azimuths, real* yaws, real* diameters, + real* turbPosX, real* turbPosY, real* turbPosZ, + uint* gridIndices, uint nIndices, + real invEpsilonSqrd, real factorGaussian) +{ + const uint x = threadIdx.x; + const uint y = blockIdx.x; + const uint z = blockIdx.y; + + const uint nx = blockDim.x; + const uint ny = gridDim.x; + + const uint index = nx*(ny*z + y) + x; + + if(index>=nIndices) return; + + + uint gridIndex = gridIndices[index]; + + real gridCoordX_GF = gridCoordsX[gridIndex]; + real gridCoordY_GF = gridCoordsY[gridIndex]; + real gridCoordZ_GF = gridCoordsZ[gridIndex]; + + real gridForceX_RF = c0o1; + real gridForceY_RF = c0o1; + real gridForceZ_RF = c0o1; + + real dAzimuth = c2Pi/nBlades; + + for(uint turbine = 0; turbine<nTurbines; turbine++) + { + real radius = c1o2*diameters[turbine]; + real gridCoordX_RF = gridCoordX_GF - turbPosX[turbine]; + real gridCoordY_RF = gridCoordY_GF - turbPosY[turbine]; + real gridCoordZ_RF = gridCoordZ_GF - turbPosZ[turbine]; + + if(distSqrd(gridCoordX_RF, gridCoordY_RF, gridCoordZ_RF)*invEpsilonSqrd< radius*radius*invEpsilonSqrd+c7o1) + continue; + + real azimuth = azimuths[turbine]; + real yaw = yaws[turbine]; + + for( uint blade=0; blade<nBlades; blade++) + { + real localAzimuth = azimuth+blade*dAzimuth; + + + real gridCoordX_BF, gridCoordY_BF, gridCoordZ_BF; + + rotateFromGlobalToBlade(gridCoordX_BF, gridCoordY_BF, gridCoordZ_BF, + gridCoordX_RF, gridCoordY_RF, gridCoordZ_RF, + localAzimuth, yaw); + + //Handle first and last node separately + + uint node = calcNode(0, nBladeNodes, blade, nBlades, turbine, nTurbines); + uint nextNode = calcNode(1, nBladeNodes, blade, nBlades, turbine, nTurbines); + + real last_z = c0o1; + real current_z = c0o1; + real next_z = bladeCoordsZ[node]; + + real x, y, dz; + + x = bladeCoordsX[node]; + y = bladeCoordsY[node]; + last_z = current_z; + current_z = next_z; + next_z = bladeCoordsZ[nextNode]; + + dz = c1o2*(next_z+current_z); + + real eta = dz*factorGaussian*exp(-distSqrd(x-gridCoordX_BF, y-gridCoordY_BF, current_z-gridCoordZ_BF)*invEpsilonSqrd); + + real forceX_RF, forceY_RF, forceZ_RF; + + rotateFromBladeToGlobal(bladeForcesX[node], bladeForcesY[node], bladeForcesZ[node], + forceX_RF, forceY_RF, forceZ_RF, + localAzimuth, yaw); + + gridForceX_RF += forceX_RF*eta; + gridForceY_RF += forceY_RF*eta; + gridForceZ_RF += forceZ_RF*eta; + + for( uint bladeNode=1; bladeNode<nBladeNodes-1; bladeNode++) + { + node = nextNode; + nextNode = calcNode(bladeNode+1, nBladeNodes, blade, nBlades, turbine, nTurbines); + + x = bladeCoordsX[node]; + y = bladeCoordsY[node]; + last_z = current_z; + current_z = next_z; + next_z = bladeCoordsZ[node+1]; + + dz = c1o2*(next_z-last_z); + + eta = dz*factorGaussian*exp(-distSqrd(x-gridCoordX_BF, y-gridCoordY_BF, current_z-gridCoordZ_BF)*invEpsilonSqrd); + + rotateFromBladeToGlobal(bladeForcesX[node], bladeForcesY[node], bladeForcesZ[node], + forceX_RF, forceY_RF, forceZ_RF, + localAzimuth, yaw); + + gridForceX_RF += forceX_RF*eta; + gridForceY_RF += forceY_RF*eta; + gridForceZ_RF += forceZ_RF*eta; + } + + node = calcNode(nBladeNodes-1, nBladeNodes, blade, nBlades, turbine, nTurbines); + + x = bladeCoordsX[node]; + y = bladeCoordsY[node]; + last_z = current_z; + current_z = next_z; + + dz = radius-c1o2*(current_z+last_z); + + eta = dz*factorGaussian*exp(-distSqrd(x-gridCoordX_BF, y-gridCoordY_BF, current_z-gridCoordZ_BF)*invEpsilonSqrd); + + rotateFromBladeToGlobal(bladeForcesX[node], bladeForcesY[node], bladeForcesZ[node], + forceX_RF, forceY_RF, forceZ_RF, + localAzimuth, yaw); + + gridForceX_RF += forceX_RF*eta; + gridForceY_RF += forceY_RF*eta; + gridForceZ_RF += forceZ_RF*eta; + } + + gridForcesX[gridIndex] = gridForceX_RF; + gridForcesY[gridIndex] = gridForceY_RF; + gridForcesZ[gridIndex] = gridForceZ_RF; + } +} + +void ActuatorFarm::addTurbine(real posX, real posY, real posZ, real diameter, real omega, real azimuth, real yaw, std::vector<real> bladeRadii) +{ + preInitPosX.push_back(posX); + preInitPosY.push_back(posY); + preInitPosZ.push_back(posZ); + preInitOmegas.push_back(omega); + preInitAzimuths.push_back(azimuth); + preInitYaws.push_back(yaw); + preInitDiameters.push_back(diameter); + preInitBladeRadii.push_back(bladeRadii); +} + +void ActuatorFarm::init(Parameter* para, GridProvider* gridProvider, CudaMemoryManager* cudaMemoryManager) +{ + if(!para->getIsBodyForce()) throw std::runtime_error("try to allocate ActuatorFarm but BodyForce is not set in Parameter."); + this->initTurbineGeometries(cudaMemoryManager); + this->initBladeCoords(cudaMemoryManager); + this->initBladeIndices(para, cudaMemoryManager); + this->initBladeVelocities(cudaMemoryManager); + this->initBladeForces(cudaMemoryManager); + this->initBoundingSphere(para, cudaMemoryManager); +} + + +void ActuatorFarm::interact(Parameter* para, CudaMemoryManager* cudaMemoryManager, int level, unsigned int t) +{ + if (level != this->level) return; + + if(useHostArrays) cudaMemoryManager->cudaCopyBladeCoordsHtoD(this); + + vf::cuda::CudaGrid bladeGrid = vf::cuda::CudaGrid(para->getParH(level)->numberofthreads, this->numberOfNodes); + + interpolateVelocities<<< bladeGrid.grid, bladeGrid.threads >>>( + para->getParD(this->level)->coordinateX, para->getParD(this->level)->coordinateY, para->getParD(this->level)->coordinateZ, + para->getParD(this->level)->neighborX, para->getParD(this->level)->neighborY, para->getParD(this->level)->neighborZ, para->getParD(this->level)->neighborInverse, + para->getParD(this->level)->velocityX, para->getParD(this->level)->velocityY, para->getParD(this->level)->velocityZ, + this->bladeCoordsXD, this->bladeCoordsYD, this->bladeCoordsZD, + this->bladeVelocitiesXD, this->bladeVelocitiesYD, this->bladeVelocitiesZD, + this->nTurbines, this->nBlades, this->nBladeNodes, + this->azimuthsD, this->yawsD, this->omegasD, + this->turbinePosXD, this->turbinePosYD, this->turbinePosZD, + this->bladeIndicesD, para->getVelocityRatio(), this->invDeltaX); + + if(useHostArrays) cudaMemoryManager->cudaCopyBladeVelocitiesDtoH(this); + + this->calcBladeForces(); + + if(useHostArrays) cudaMemoryManager->cudaCopyBladeForcesHtoD(this); + + vf::cuda::CudaGrid sphereGrid = vf::cuda::CudaGrid(para->getParH(level)->numberofthreads, this->numberOfIndices); + + applyBodyForces<<<sphereGrid.grid, sphereGrid.threads>>>( + para->getParD(this->level)->coordinateX, para->getParD(this->level)->coordinateY, para->getParD(this->level)->coordinateZ, + para->getParD(this->level)->forceX_SP, para->getParD(this->level)->forceY_SP, para->getParD(this->level)->forceZ_SP, + this->bladeCoordsXD, this->bladeCoordsYD, this->bladeCoordsZD, + this->bladeForcesXD, this->bladeForcesYD, this->bladeForcesZD, + this->nTurbines, this->nBlades, this->nBladeNodes, + this->azimuthsD, this->yawsD, this->diametersD, + this->turbinePosXD, this->turbinePosYD, this->turbinePosZD, + this->boundingSphereIndicesD, this->numberOfIndices, + this->invEpsilonSqrd, this->factorGaussian); + + for(uint turbine=0; turbine<this->nTurbines; turbine++) + this->azimuthsH[turbine] = fmod(this->azimuthsH[turbine]+this->omegasH[turbine]*this->deltaT, c2Pi); + + cudaMemoryManager->cudaCopyBladeOrientationsHtoD(this); +} + + +void ActuatorFarm::free(Parameter* para, CudaMemoryManager* cudaMemoryManager) +{ + cudaMemoryManager->cudaFreeBladeGeometries(this); + cudaMemoryManager->cudaFreeBladeOrientations(this); + cudaMemoryManager->cudaFreeBladeCoords(this); + cudaMemoryManager->cudaFreeBladeVelocities(this); + cudaMemoryManager->cudaFreeBladeForces(this); + cudaMemoryManager->cudaFreeBladeIndices(this); + cudaMemoryManager->cudaFreeSphereIndices(this); +} + + +void ActuatorFarm::calcForcesEllipticWing() +{ + real u_rel, v_rel, u_rel_sq; + real phi; + real Cl = c1o1; + real Cd = c0o1; + real c0 = c1o1; + + real c, Cn, Ct; + for(uint turbine=0; turbine<this->nTurbines; turbine++) + { + real diameter = this->diametersH[turbine]; + for( uint blade=0; blade<this->nBlades; blade++) + { + for( uint bladeNode=0; bladeNode<this->nBladeNodes; bladeNode++) + { + uint node = calcNode(bladeNode, this->nBladeNodes, blade, this->nBlades, turbine, this->nTurbines); + + u_rel = this->bladeVelocitiesXH[node]; + v_rel = this->bladeVelocitiesYH[node]; + u_rel_sq = u_rel*u_rel+v_rel*v_rel; + phi = atan2(u_rel, v_rel); + + real tmp = c4o1*this->bladeRadiiH[bladeNode]/diameter-c1o1; + c = c0 * sqrt( c1o1- tmp*tmp ); + Cn = Cl*cos(phi)+Cd*sin(phi); + Ct = Cl*sin(phi)-Cd*cos(phi); + + this->bladeForcesXH[node] = -c1o2*u_rel_sq*c*this->density*Cn; + this->bladeForcesYH[node] = -c1o2*u_rel_sq*c*this->density*Ct; + this->bladeForcesZH[node] = c0o1; + } + } + } +} + +void ActuatorFarm::calcBladeForces() +{ + // this->calcForcesEllipticWing(); +} +void ActuatorFarm::initTurbineGeometries(CudaMemoryManager* cudaMemoryManager) +{ + this->nTurbines = this->preInitDiameters.size(); + this->numberOfNodes = nTurbines*nBladeNodes*nBlades; + + cudaMemoryManager->cudaAllocBladeGeometries(this); + cudaMemoryManager->cudaAllocBladeOrientations(this); + + for(uint turbine=0; turbine<this->nTurbines; turbine++) + { + for(uint node=0; node<this->nBladeNodes; node++) + { + this->bladeRadiiH[calcNode(node, nBladeNodes, 0, 1, turbine, nTurbines)] = this->preInitBladeRadii[turbine][node]; + } + + } + std::copy(preInitPosX.begin(), preInitPosX.end(), turbinePosXH); + std::copy(preInitPosY.begin(), preInitPosY.end(), turbinePosYH); + std::copy(preInitPosZ.begin(), preInitPosZ.end(), turbinePosZH); + std::copy(preInitDiameters.begin(), preInitDiameters.end(), diametersH); + + cudaMemoryManager->cudaCopyBladeGeometriesHtoD(this); + std::copy(preInitAzimuths.begin(), preInitAzimuths.end(), this->azimuthsH); + std::copy(preInitOmegas.begin(), preInitOmegas.end(), this->omegasH); + std::copy(preInitYaws.begin(), preInitYaws.end(), this->yawsH); + + cudaMemoryManager->cudaCopyBladeOrientationsHtoD(this); + real dxOPiSqrtEps = pow(this->deltaX/(this->epsilon*sqrt(cPi)),c3o1); + this->factorGaussian = dxOPiSqrtEps/this->forceRatio; +} + +void ActuatorFarm::initBladeCoords(CudaMemoryManager* cudaMemoryManager) +{ + cudaMemoryManager->cudaAllocBladeCoords(this); + + for(uint turbine=0; turbine<nTurbines; turbine++) + { + for(uint blade=0; blade<this->nBlades; blade++) + { + for(uint bladeNode=0; bladeNode<this->nBladeNodes; bladeNode++) + { + uint node = calcNode(bladeNode, this->nBladeNodes, blade, this->nBlades, turbine, this->nTurbines); + + this->bladeCoordsXH[node] = c0o1; + this->bladeCoordsYH[node] = c0o1; + this->bladeCoordsZH[node] = this->bladeRadiiH[calcNode(bladeNode, nBladeNodes, 0, 1, turbine, nTurbines)]; + } + } + } + cudaMemoryManager->cudaCopyBladeCoordsHtoD(this); +} + +void ActuatorFarm::initBladeVelocities(CudaMemoryManager* cudaMemoryManager) +{ + cudaMemoryManager->cudaAllocBladeVelocities(this); + + std::fill_n(this->bladeVelocitiesXH, this->numberOfNodes, c0o1); + std::fill_n(this->bladeVelocitiesYH, this->numberOfNodes, c0o1); + std::fill_n(this->bladeVelocitiesZH, this->numberOfNodes, c0o1); + + cudaMemoryManager->cudaCopyBladeVelocitiesHtoD(this); +} + +void ActuatorFarm::initBladeForces(CudaMemoryManager* cudaMemoryManager) +{ + cudaMemoryManager->cudaAllocBladeForces(this); + + std::fill_n(this->bladeForcesXH, this->numberOfNodes, c0o1); + std::fill_n(this->bladeForcesYH, this->numberOfNodes, c0o1); + std::fill_n(this->bladeForcesZH, this->numberOfNodes, c0o1); + + cudaMemoryManager->cudaCopyBladeForcesHtoD(this); +} + +void ActuatorFarm::initBladeIndices(Parameter* para, CudaMemoryManager* cudaMemoryManager) +{ + cudaMemoryManager->cudaAllocBladeIndices(this); + + std::fill_n(this->bladeIndicesH, this->numberOfNodes, 1); + + cudaMemoryManager->cudaCopyBladeIndicesHtoD(this); +} + +void ActuatorFarm::initBoundingSphere(Parameter* para, CudaMemoryManager* cudaMemoryManager) +{ + // Actuator line exists only on 1 level + std::vector<int> nodesInSphere; + + for(uint turbine=0; turbine<this->nTurbines; turbine++) + { + real sphereRadius = c1o2*this->diametersH[turbine]+c4o1*this->epsilon; + + real posX = this->turbinePosXH[level]; + real posY = this->turbinePosYH[level]; + real posZ = this->turbinePosZH[level]; + + real sphereRadiusSqrd = sphereRadius*sphereRadius; + + for (uint j = 1; j <= para->getParH(this->level)->numberOfNodes; j++) + { + const real distX = para->getParH(this->level)->coordinateX[j]-posX; + const real distY = para->getParH(this->level)->coordinateY[j]-posY; + const real distZ = para->getParH(this->level)->coordinateZ[j]-posZ; + if(distSqrd(distX,distY,distZ) < sphereRadiusSqrd) nodesInSphere.push_back(j); + } + } + + this->numberOfIndices = uint(nodesInSphere.size()); + + cudaMemoryManager->cudaAllocSphereIndices(this); + std::copy(nodesInSphere.begin(), nodesInSphere.end(), this->boundingSphereIndicesH); + cudaMemoryManager->cudaCopySphereIndicesHtoD(this); +} + +void ActuatorFarm::setAllBladeCoords(real* _bladeCoordsX, real* _bladeCoordsY, real* _bladeCoordsZ) +{ + std::copy_n(this->bladeCoordsXH, this->numberOfNodes, _bladeCoordsX); + std::copy_n(this->bladeCoordsYH, this->numberOfNodes, _bladeCoordsY); + std::copy_n(this->bladeCoordsZH, this->numberOfNodes, _bladeCoordsZ); + +} + +void ActuatorFarm::setAllBladeVelocities(real* _bladeVelocitiesX, real* _bladeVelocitiesY, real* _bladeVelocitiesZ) +{ + std::copy_n(this->bladeVelocitiesXH, this->numberOfNodes, _bladeVelocitiesX); + std::copy_n(this->bladeVelocitiesYH, this->numberOfNodes, _bladeVelocitiesY); + std::copy_n(this->bladeVelocitiesZH, this->numberOfNodes, _bladeVelocitiesZ); + +} + +void ActuatorFarm::setAllBladeForces(real* _bladeForcesX, real* _bladeForcesY, real* _bladeForcesZ) +{ + std::copy_n(this->bladeForcesXH, this->numberOfNodes, _bladeForcesX); + std::copy_n(this->bladeForcesYH, this->numberOfNodes, _bladeForcesY); + std::copy_n(this->bladeForcesZH, this->numberOfNodes, _bladeForcesZ); + +}void ActuatorFarm::setTurbineBladeCoords(uint turbine, real* _bladeCoordsX, real* _bladeCoordsY, real* _bladeCoordsZ) +{ + std::copy_n(&this->bladeCoordsXH[turbine*nBladeNodes*nBlades], nBladeNodes*nBlades, _bladeCoordsX); + std::copy_n(&this->bladeCoordsYH[turbine*nBladeNodes*nBlades], nBladeNodes*nBlades, _bladeCoordsY); + std::copy_n(&this->bladeCoordsZH[turbine*nBladeNodes*nBlades], nBladeNodes*nBlades, _bladeCoordsZ); +} + +void ActuatorFarm::setTurbineBladeVelocities(uint turbine, real* _bladeVelocitiesX, real* _bladeVelocitiesY, real* _bladeVelocitiesZ) +{ + std::copy_n(&this->bladeVelocitiesXH[turbine*nBladeNodes*nBlades], nBladeNodes*nBlades, _bladeVelocitiesX); + std::copy_n(&this->bladeVelocitiesYH[turbine*nBladeNodes*nBlades], nBladeNodes*nBlades, _bladeVelocitiesY); + std::copy_n(&this->bladeVelocitiesZH[turbine*nBladeNodes*nBlades], nBladeNodes*nBlades, _bladeVelocitiesZ); +} + +void ActuatorFarm::setTurbineBladeForces(uint turbine, real* _bladeForcesX, real* _bladeForcesY, real* _bladeForcesZ) +{ + std::copy_n(&this->bladeForcesXH[turbine*nBladeNodes*nBlades], nBladeNodes*nBlades, _bladeForcesX); + std::copy_n(&this->bladeForcesYH[turbine*nBladeNodes*nBlades], nBladeNodes*nBlades, _bladeForcesY); + std::copy_n(&this->bladeForcesZH[turbine*nBladeNodes*nBlades], nBladeNodes*nBlades, _bladeForcesZ); +} diff --git a/src/gpu/VirtualFluids_GPU/PreCollisionInteractor/ActuatorFarm.h b/src/gpu/VirtualFluids_GPU/PreCollisionInteractor/ActuatorFarm.h new file mode 100644 index 0000000000000000000000000000000000000000..4e7fc220e848ebf24bcb7b7713b0c2d4c3998873 --- /dev/null +++ b/src/gpu/VirtualFluids_GPU/PreCollisionInteractor/ActuatorFarm.h @@ -0,0 +1,168 @@ +#ifndef ActuatorFarm_H +#define ActuatorFarm_H + +#include "PreCollisionInteractor.h" +#include "PointerDefinitions.h" + +class Parameter; +class GridProvider; + +class ActuatorFarm : public PreCollisionInteractor +{ +public: + ActuatorFarm( + const uint _nBlades, + const real _density, + const uint _nBladeNodes, + const real _epsilon, + int _level, + const real _deltaT, + const real _deltaX, + const bool _useHostArrays + ) : + nBlades(_nBlades), + density(_density), + nBladeNodes(_nBladeNodes), + epsilon(_epsilon), + level(_level), + useHostArrays(_useHostArrays), + nTurbines(0), + numberOfNodes(0), + PreCollisionInteractor() + { + this->deltaT = _deltaX/pow(2,this->level); + this->deltaX = _deltaX/pow(2,this->level); + } + + virtual ~ActuatorFarm() + { + + } + void addTurbine(real turbinePosX, real turbinePosY, real turbinePosZ, real diameter, real omega, real azimuth, real yaw, std::vector<real> bladeRadii); + void init(Parameter* para, GridProvider* gridProvider, CudaMemoryManager* cudaManager); + void interact(Parameter* para, CudaMemoryManager* cudaManager, int level, uint t); + void free(Parameter* para, CudaMemoryManager* cudaManager); + void write(uint t); + + uint getNTurbines(){return this->nTurbines; }; + uint getNBladeNodes(){return this->nBladeNodes;}; + uint getNBlades(){return this->nBlades;}; + + real* getAllAzimuths(){ return azimuthsH; }; + real* getAllOmegas(){ return omegasH; }; + real* getAllYaws(){ return yawsH; }; + + real* getAllTurbinePosX(){ return turbinePosXH; }; + real* getAllTurbinePosY(){ return turbinePosYH; }; + real* getAllTurbinePosZ(){ return turbinePosZH; }; + + real getTurbineAzimuth(uint turbine){ return azimuthsH[turbine]; }; + real getTurbineOmega (uint turbine){ return omegasH[turbine]; }; + real getTurbineYaw (uint turbine){ return yawsH[turbine]; }; + + real getTurbinePosX(uint turbine){ return turbinePosXH[turbine]; }; + real getTurbinePosY(uint turbine){ return turbinePosYH[turbine]; }; + real getTurbinePosZ(uint turbine){ return turbinePosZH[turbine]; }; + + uint getNumberOfIndices(){return this->numberOfIndices;}; + uint getNumberOfNodes(){return this->numberOfNodes;}; + real* getAllBladeCoordsX(){return this->bladeCoordsXH;}; + real* getAllBladeCoordsY(){return this->bladeCoordsYH;}; + real* getAllBladeCoordsZ(){return this->bladeCoordsZH;}; + real* getAllBladeVelocitiesX(){return this->bladeVelocitiesXH;}; + real* getAllBladeVelocitiesY(){return this->bladeVelocitiesYH;}; + real* getAllBladeVelocitiesZ(){return this->bladeVelocitiesZH;}; + real* getAllBladeForcesX(){return this->bladeForcesXH;}; + real* getAllBladeForcesY(){return this->bladeForcesYH;}; + real* getAllBladeForcesZ(){return this->bladeForcesZH;}; + + real* getTurbineBladeCoordsX(uint turbine){return &this->bladeCoordsXH[turbine*nBladeNodes*nBlades];}; + real* getTurbineBladeCoordsY(uint turbine){return &this->bladeCoordsYH[turbine*nBladeNodes*nBlades];}; + real* getTurbineBladeCoordsZ(uint turbine){return &this->bladeCoordsZH[turbine*nBladeNodes*nBlades];}; + real* getTurbineBladeVelocitiesX(uint turbine){return &this->bladeVelocitiesXH[turbine*nBladeNodes*nBlades];}; + real* getTurbineBladeVelocitiesY(uint turbine){return &this->bladeVelocitiesYH[turbine*nBladeNodes*nBlades];}; + real* getTurbineBladeVelocitiesZ(uint turbine){return &this->bladeVelocitiesZH[turbine*nBladeNodes*nBlades];}; + real* getTurbineBladeForcesX(uint turbine){return &this->bladeForcesXH[turbine*nBladeNodes*nBlades];}; + real* getTurbineBladeForcesY(uint turbine){return &this->bladeForcesYH[turbine*nBladeNodes*nBlades];}; + real* getTurbineBladeForcesZ(uint turbine){return &this->bladeForcesZH[turbine*nBladeNodes*nBlades];}; + + real* getAllBladeCoordsXDevice(){return this->bladeCoordsXD;}; + real* getAllBladeCoordsYDevice(){return this->bladeCoordsYD;}; + real* getAllBladeCoordsZDevice(){return this->bladeCoordsZD;}; + real* getAllBladeVelocitiesXDevice(){return this->bladeVelocitiesXD;}; + real* getAllBladeVelocitiesYDevice(){return this->bladeVelocitiesYD;}; + real* getAllBladeVelocitiesZDevice(){return this->bladeVelocitiesZD;}; + real* getAllBladeForcesXDevice(){return this->bladeForcesXD;}; + real* getAllBladeForcesYDevice(){return this->bladeForcesYD;}; + real* getAllBladeForcesZDevice(){return this->bladeForcesZD;}; + + real* getTurbineBladeCoordsXDevice(uint turbine){return &this->bladeCoordsXD[turbine*nBladeNodes*nBlades];}; + real* getTurbineBladeCoordsYDevice(uint turbine){return &this->bladeCoordsYD[turbine*nBladeNodes*nBlades];}; + real* getTurbineBladeCoordsZDevice(uint turbine){return &this->bladeCoordsZD[turbine*nBladeNodes*nBlades];}; + real* getTurbineBladeVelocitiesXDevice(uint turbine){return &this->bladeVelocitiesXD[turbine*nBladeNodes*nBlades];}; + real* getTurbineBladeVelocitiesYDevice(uint turbine){return &this->bladeVelocitiesYD[turbine*nBladeNodes*nBlades];}; + real* getTurbineBladeVelocitiesZDevice(uint turbine){return &this->bladeVelocitiesZD[turbine*nBladeNodes*nBlades];}; + real* getTurbineBladeForcesXDevice(uint turbine){return &this->bladeForcesXD[turbine*nBladeNodes*nBlades];}; + real* getTurbineBladeForcesYDevice(uint turbine){return &this->bladeForcesYD[turbine*nBladeNodes*nBlades];}; + real* getTurbineBladeForcesZDevice(uint turbine){return &this->bladeForcesZD[turbine*nBladeNodes*nBlades];}; + + void setAllBladeCoords(real* _bladeCoordsX, real* _bladeCoordsY, real* _bladeCoordsZ); + void setAllBladeVelocities(real* _bladeVelocitiesX, real* _bladeVelocitiesY, real* _bladeVelocitiesZ); + void setAllBladeForces(real* _bladeForcesX, real* _bladeForcesY, real* _bladeForcesZ); + + void setTurbineBladeCoords(uint turbine, real* _bladeCoordsX, real* _bladeCoordsY, real* _bladeCoordsZ); + void setTurbineBladeVelocities(uint turbine, real* _bladeVelocitiesX, real* _bladeVelocitiesY, real* _bladeVelocitiesZ); + void setTurbineBladeForces(uint turbine, real* _bladeForcesX, real* _bladeForcesY, real* _bladeForcesZ); + + +private: + void initTurbineGeometries(CudaMemoryManager* cudaManager); + void initBoundingSphere(Parameter* para, CudaMemoryManager* cudaManager); + void initBladeCoords(CudaMemoryManager* cudaManager); + void initBladeVelocities(CudaMemoryManager* cudaManager); + void initBladeForces(CudaMemoryManager* cudaManager); + void initBladeIndices(Parameter* para, CudaMemoryManager* cudaManager); + + void calcForcesEllipticWing(); + void calcBladeForces(); + void rotateBlades(real angle, uint turbineID); + + void writeBladeCoords(uint t); + void writeBladeForces(uint t); + void writeBladeVelocities(uint t); + + + + +public: + real* bladeRadiiH; + real* bladeRadiiD; + real* bladeCoordsXH, * bladeCoordsYH, * bladeCoordsZH; + real* bladeCoordsXD, * bladeCoordsYD, * bladeCoordsZD; + real* bladeVelocitiesXH, * bladeVelocitiesYH, * bladeVelocitiesZH; + real* bladeVelocitiesXD, * bladeVelocitiesYD, * bladeVelocitiesZD; + real* bladeForcesXH, * bladeForcesYH, * bladeForcesZH; + real* bladeForcesXD, * bladeForcesYD, * bladeForcesZD; + uint* bladeIndicesH; + uint* bladeIndicesD; + uint* boundingSphereIndicesH; + uint* boundingSphereIndicesD; + real* turbinePosXH, *turbinePosYH, *turbinePosZH, *omegasH, *azimuthsH, *yawsH, *diametersH; + real* turbinePosXD, *turbinePosYD, *turbinePosZD, *omegasD, *azimuthsD, *yawsD, *diametersD; + +private: + std::vector<real> preInitPosX, preInitPosY, preInitPosZ, preInitDiameters, preInitOmegas, preInitAzimuths, preInitYaws; + std::vector<std::vector<real>> preInitBladeRadii; + const bool useHostArrays; + const real density; + real deltaT, deltaX; + const uint nBladeNodes, nBlades; + uint nTurbines; + const real epsilon; // in m + const int level; + uint numberOfIndices; + uint numberOfNodes; + real forceRatio, factorGaussian, invEpsilonSqrd, invDeltaX; +}; + +#endif \ No newline at end of file