41 const uint celli = blockIdx.x;
42 const uint stride = gridDim.y;
43 const uint strideOffset = blockIdx.y;
44 const uint
ti = threadIdx.z*blockDim.x*blockDim.y + threadIdx.y*blockDim.x + threadIdx.x;
45 const int i = threadIdx.x;
46 const int j = threadIdx.y;
47 const int k = threadIdx.z;
48 const int blockSize = blockDim.x*blockDim.y*blockDim.z;
50 extern __shared__
Real smom[];
54 if (blockContainer==0) {
57 const uint thisVBCSize = blockContainer->size();
61 const Realf* __restrict__ data = blockContainer->getData();
65 for (uint blockIndex = strideOffset; blockIndex < thisVBCSize; blockIndex += stride) {
73 const Real DV3 = paramX*paramY*paramZ;
80 const Real fDV3 = f * DV3;
83 myMom[1] += fDV3 *
VX;
84 myMom[2] += fDV3 *
VY;
85 myMom[3] += fDV3 *
VZ;
92 for (
int offset =
GPUTHREADS/2; offset > 0; offset /= 2) {
93 for (uint imom=0; imom<
nMom1; imom++) {
98 if (indexInsideWarp == 0) {
99 for (uint imom=0; imom<
nMom1; imom++) {
100 smom[warpIndex*
nMom1+imom] = myMom[imom];
108 for (uint imom=warpIndex; imom<
nMom1; imom +=warpsPerBlock ) {
109 myMom[imom] = (indexInsideWarp < warpsPerBlock) ? smom[indexInsideWarp*
nMom1+imom] : 0.0;
110 for (
int offset = (warpsPerBlock)/2; offset > 0; offset /= 2) {
114 if (indexInsideWarp == 0) {
115 if (gridDim.y == 1) {
116 dev_moments1[celli*
nMom1 + imom] = myMom[imom];
118 atomicAdd(&dev_moments1[celli*
nMom1 + imom],myMom[imom]);
130 const Real* __restrict__ dev_moments1,
132 const uint nAllCells)
134 const uint celli = blockIdx.x;
135 const uint stride = gridDim.y;
136 const uint strideOffset = blockIdx.y;
137 const uint ti = threadIdx.z*blockDim.x*blockDim.y + threadIdx.y*blockDim.x + threadIdx.x;
138 const int i = threadIdx.x;
139 const int j = threadIdx.y;
140 const int k = threadIdx.z;
141 const int blockSize = blockDim.x*blockDim.y*blockDim.z;
144 extern __shared__
Real smom[];
147 if (blockContainer==0) {
150 const uint thisVBCSize = blockContainer->size();
151 if (thisVBCSize==0) {
154 const Realf* __restrict__ data = blockContainer->getData();
161 const Real averageVX = dev_moments1[celli*
nMom1 + 1];
162 const Real averageVY = dev_moments1[celli*
nMom1 + 2];
163 const Real averageVZ = dev_moments1[celli*
nMom1 + 3];
165 for (uint blockIndex = strideOffset; blockIndex < thisVBCSize; blockIndex += stride) {
173 const Real DV3 = paramX*paramY*paramZ;
179 const Real VXDifference =
VX - averageVX;
180 const Real VYDifference =
VY - averageVY;
181 const Real VZDifference =
VZ - averageVZ;
184 const Real fDV3 =
f * DV3;
186 const Real fDV3VXDifference = fDV3 * VXDifference;
187 const Real fDV3VYDifference = fDV3 * VYDifference;
189 myMom[0] += fDV3VXDifference * VXDifference;
190 myMom[1] += fDV3VYDifference * VYDifference;
191 myMom[2] += fDV3 * VZDifference * VZDifference;
192 myMom[3] += fDV3VYDifference * VZDifference;
193 myMom[4] += fDV3VXDifference * VZDifference;
194 myMom[5] += fDV3VXDifference * VYDifference;
202 for (uint imom=0; imom<
nMom2; imom++) {
207 if (indexInsideWarp == 0) {
208 for (uint imom=0; imom<
nMom2; imom++) {
209 smom[warpIndex*
nMom2+imom] = myMom[imom];
217 for (uint imom=warpIndex; imom<
nMom2; imom +=warpsPerBlock ) {
218 myMom[imom] = (indexInsideWarp < warpsPerBlock) ? smom[indexInsideWarp*
nMom2+imom] : 0.0;
219 for (
int offset = (warpsPerBlock)/2;
offset > 0;
offset /= 2) {
223 if (indexInsideWarp == 0) {
224 if (gridDim.y == 1) {
225 dev_moments2[celli*
nMom2 + imom] = myMom[imom];
227 atomicAdd(&dev_moments2[celli*
nMom2 + imom],myMom[imom]);
250 dccrg::Dccrg<SpatialCell,dccrg::Cartesian_Geometry>& mpiGrid,
251 const std::vector<CellID>& cells_in,
252 const bool computeSecond,
253 const bool initialCompute) {
255 phiprof::Timer computeMomentsTimer {
"Compute _R moments"};
258 std::vector<CellID> cells = cells_in;
259 std::sort( cells.begin(), cells.end() );
260 cells.erase( std::unique( cells.begin(), cells.end() ), cells.end() );
262 const uint nAllCells = cells.size();
283 std::vector<vmesh::LocalID> maxVmeshSizes;
287 maxVmeshSizes.push_back(0);
291 #pragma omp for schedule(static)
292 for(uint celli = 0; celli < nAllCells; celli++){
306 threadMaxVmeshSize = meshSize > threadMaxVmeshSize ? meshSize : threadMaxVmeshSize;
325 maxVmeshSizes.at(popID) = maxVmeshSizes.at(popID) > threadMaxVmeshSize ? maxVmeshSizes.at(popID) : threadMaxVmeshSize;
328 if (maxVmeshSizes.at(popID) == 0) {
333 maxVmeshLaunch = maxVmeshLaunch < 1 ? 1 : maxVmeshLaunch;
339 dim3 gridSize(nAllCells,maxVmeshLaunch,1);
341 first_moments_kernel<<<gridSize, blockSize, sharedMemorySizeFirstMoments, 0>>> (
352 #pragma omp parallel for schedule(static)
353 for (uint celli = 0; celli < nAllCells; celli++){
378 #pragma omp parallel for schedule(static)
379 for (
size_t celli=0; celli<nAllCells; ++celli) {
400 if (computeSecond ==
false) {
408 if (maxVmeshSizes.at(popID) == 0) {
414 maxVmeshLaunch = maxVmeshLaunch < 1 ? 1 : maxVmeshLaunch;
417 dim3 gridSize(nAllCells,maxVmeshLaunch,1);
419 second_moments_kernel<<<gridSize, blockSize, sharedMemorySizeSecondMoments, 0>>> (
430 #pragma omp parallel for schedule(static)
431 for (uint celli = 0; celli < nAllCells; celli++){
443 for (
size_t i = 0;
i <
nMom2; ++
i) {
444 pop.
P_R[
i] = mass*host_moments2[
nMom2*celli +
i];
470 dccrg::Dccrg<SpatialCell,dccrg::Cartesian_Geometry>& mpiGrid,
471 const std::vector<CellID>& cells_in,
472 const bool computeSecond,
473 const bool initialCompute) {
475 phiprof::Timer computeMomentsTimer {
"Compute _V moments"};
478 std::vector<CellID> cells = cells_in;
479 std::sort( cells.begin(), cells.end() );
480 cells.erase( std::unique( cells.begin(), cells.end() ), cells.end() );
482 const uint nAllCells = cells.size();
503 std::vector<vmesh::LocalID> maxVmeshSizes;
507 maxVmeshSizes.push_back(0);
511 #pragma omp for schedule(static)
512 for(uint celli = 0; celli < nAllCells; celli++){
526 threadMaxVmeshSize = meshSize > threadMaxVmeshSize ? meshSize : threadMaxVmeshSize;
545 maxVmeshSizes.at(popID) = maxVmeshSizes.at(popID) > threadMaxVmeshSize ? maxVmeshSizes.at(popID) : threadMaxVmeshSize;
548 if (maxVmeshSizes.at(popID) == 0) {
553 maxVmeshLaunch = maxVmeshLaunch < 1 ? 1 : maxVmeshLaunch;
559 dim3 gridSize(nAllCells,maxVmeshLaunch,1);
561 first_moments_kernel<<<gridSize, blockSize, sharedMemorySizeFirstMoments, 0>>> (
572 #pragma omp parallel for schedule(static)
573 for (uint celli = 0; celli < nAllCells; celli++){
598 #pragma omp parallel for schedule(static)
599 for (
size_t celli=0; celli<nAllCells; ++celli) {
620 if (computeSecond ==
false) {
628 if (maxVmeshSizes.at(popID) == 0) {
633 maxVmeshLaunch = maxVmeshLaunch < 1 ? 1 : maxVmeshLaunch;
636 dim3 gridSize(nAllCells,maxVmeshLaunch,1);
638 second_moments_kernel<<<gridSize, blockSize, sharedMemorySizeSecondMoments, 0>>> (
649 #pragma omp parallel for schedule(static)
650 for (uint celli = 0; celli < nAllCells; celli++){
662 for (
size_t i = 0;
i <
nMom2; ++
i) {
663 pop.
P_V[
i] = mass*host_moments2[
nMom2*celli +
i];
#define gpuPeekAtLastError
#define gpuMemcpyHostToDevice
#define gpuMemcpyDeviceToHost
#define gpuKernelShflDown(val, offset)
#define gpuDeviceSynchronize
vmesh::VelocityMesh * get_velocity_mesh(const size_t &popID)
Population & get_population(const uint popID)
std::array< Real, CellParams::N_SPATIAL_CELL_PARAMS > parameters
vmesh::VelocityBlockContainer * dev_get_velocity_blocks(const size_t &popID)
size_t size(bool dummy=0) const
Real divideIfNonZero(creal numerator, creal denominator)
Helper function.
GPUMemoryManager gpuMemoryManager
int gpuMultiProcessorCount
#define SESSION_HOST_ALLOCATE(object, type, member, bytes)
#define SESSION_ALLOCATE(object, type, member, bytes)
#define GET_SESSION_POINTER(object, type, member)
#define GET_SESSION_HOST_POINTER(object, type, member)
void gpu_calculateMoments_V(dccrg::Dccrg< SpatialCell, dccrg::Cartesian_Geometry > &mpiGrid, const std::vector< CellID > &cells_in, const bool computeSecond, const bool initialCompute)
void gpu_calculateMoments_R(dccrg::Dccrg< SpatialCell, dccrg::Cartesian_Geometry > &mpiGrid, const std::vector< CellID > &cells_in, const bool computeSecond, const bool initialCompute)
const Real *__restrict__ blockParameters
ObjectWrapper & getObjectWrapper()
@ N_VELOCITY_BLOCK_PARAMS
static __global__ void __launch_bounds__(WID3, 4) population_scale_kernel(vmesh
std::vector< species::Species > particleSpecies
static ARCH_HOSTDEV VecSimple< T > min(VecSimple< T > const &l, VecSimple< T > const &r)