WarpX
Loading...
Searching...
No Matches
VelocityCoincidenceThinning.H
Go to the documentation of this file.
1/* Copyright 2024 The WarpX Community
2 *
3 * This file is part of WarpX.
4 *
5 * Authors: Roelof Groenewald (TAE Technologies)
6 *
7 * License: BSD-3-Clause-LBNL
8 */
9#ifndef WARPX_VELOCITY_COINCIDENCE_THINNING_H_
10#define WARPX_VELOCITY_COINCIDENCE_THINNING_H_
11
13#include "Resampling.H"
15#include "Utils/ParticleUtils.H"
16
17#include <AMReX_Algorithm.H>
18#include <AMReX_Geometry.H>
19
20
28public:
29
34
40 VelocityCoincidenceThinning (const std::string& species_name);
41
42 enum struct VelocityGridType {
45 };
46
55 void operator() (
56 const amrex::Geometry& geom_lev, WarpXParIter& pti,
57 int lev, WarpXParticleContainer* pc) const final;
58
74 struct HeapSort {
75
77 void operator() (int index_array[], const int bin_array[], const int start, const int n) const
78 {
79 // sort index_array into a max heap structure
80 for (int i = 1; i < n; i++)
81 {
82 auto j = i;
83 // move child through heap if it is bigger than its parent
84 while (j > 0 && bin_array[index_array[j+start]] > bin_array[index_array[(j - 1)/2 + start]]) {
85 // swap child and parent until branch is properly ordered
86 amrex::Swap(index_array[j+start], index_array[(j - 1)/2 + start]);
87 j = (j - 1) / 2;
88 }
89 }
90
91 for (int i = n - 1; i > 0; i--)
92 {
93 // swap value of first (now the largest value) to the new end point
94 amrex::Swap(index_array[start], index_array[i+start]);
95
96 // remake the max heap
97 int j = 0, index;
98 while (j < i) {
99 index = 2 * j + 1;
100
101 // if left child is smaller than right child, point index variable to right child
102 if (index + 1 < i && bin_array[index_array[index+start]] < bin_array[index_array[index+1+start]]) {
103 index++;
104 }
105 // if parent is smaller than child, swap parent with child having higher value
106 if (index < i && bin_array[index_array[j+start]] < bin_array[index_array[index+start]]) {
107 amrex::Swap(index_array[j+start], index_array[index+start]);
108 }
109 j = index;
110 }
111 }
112 }
113 };
114
120
122 void labelOnSphericalVelocityGrid (const amrex::ParticleReal ux[],
123 const amrex::ParticleReal uy[],
124 const amrex::ParticleReal uz[],
125 const int indices[],
126 int bin_array[], int index_array[],
127 const int cell_start, const int cell_stop ) const
128 {
129 for (int i = cell_start; i < cell_stop; ++i)
130 {
131 // get polar components of the velocity vector
132 auto u_mag = std::sqrt(
133 ux[indices[i]]*ux[indices[i]] +
134 uy[indices[i]]*uy[indices[i]] +
135 uz[indices[i]]*uz[indices[i]]
136 );
137 auto u_theta = std::atan2(uy[indices[i]], ux[indices[i]]) + MathConst::pi;
138 auto u_phi = std::acos(uz[indices[i]]/u_mag);
139
140 const int ii = static_cast<int>(u_theta / dutheta);
141 const int jj = static_cast<int>(u_phi / duphi);
142 const int kk = static_cast<int>(u_mag / dur);
143
144 bin_array[i] = ii + jj * n1 + kk * n1 * n2;
145 index_array[i] = i;
146 }
147 }
148
150 void labelOnCartesianVelocityGrid (const amrex::ParticleReal ux[],
151 const amrex::ParticleReal uy[],
152 const amrex::ParticleReal uz[],
153 const int indices[],
154 int bin_array[], int index_array[],
155 const int cell_start, const int cell_stop ) const
156 {
157 for (int i = cell_start; i < cell_stop; ++i)
158 {
159 const int ii = static_cast<int>((ux[indices[i]] - ux_min) / dux);
160 const int jj = static_cast<int>((uy[indices[i]] - uy_min) / duy);
161 const int kk = static_cast<int>((uz[indices[i]] - uz_min) / duz);
162
163 bin_array[i] = ii + jj * n1 + kk * n1 * n2;
164 index_array[i] = i;
165 }
166 }
167
169 void operator() (const amrex::ParticleReal ux[], const amrex::ParticleReal uy[],
170 const amrex::ParticleReal uz[], const int indices[],
171 int bin_array[], int index_array[],
172 const int cell_start, const int cell_stop) const
173 {
176 ux, uy, uz, indices, bin_array, index_array, cell_start,
177 cell_stop
178 );
179 }
182 ux, uy, uz, indices, bin_array, index_array, cell_start,
183 cell_stop
184 );
185 }
186 }
187
189 int n1, n2;
190 amrex::ParticleReal dur, dutheta, duphi;
191 amrex::ParticleReal dux, duy, duz;
192 amrex::ParticleReal ux_min, uy_min, uz_min, ux_max, uy_max;
193 };
194
195private:
197
198 int m_min_ppc = 1;
200 amrex::ParticleReal m_delta_ur;
202 amrex::ParticleReal m_cluster_weight = std::numeric_limits<amrex::ParticleReal>::max();
203};
204#endif // WARPX_VELOCITY_COINCIDENCE_THINNING_H_
#define AMREX_FORCE_INLINE
#define AMREX_GPU_HOST_DEVICE
VelocityGridType m_velocity_grid_type
Definition VelocityCoincidenceThinning.H:196
amrex::ParticleReal m_delta_ur
Definition VelocityCoincidenceThinning.H:200
VelocityCoincidenceThinning()=default
Default constructor of the VelocityCoincidenceThinning class.
amrex::Vector< amrex::ParticleReal > m_delta_u
Definition VelocityCoincidenceThinning.H:201
int m_nphi
Definition VelocityCoincidenceThinning.H:199
int m_min_ppc
Definition VelocityCoincidenceThinning.H:198
VelocityGridType
Definition VelocityCoincidenceThinning.H:42
@ Spherical
Definition VelocityCoincidenceThinning.H:43
@ Cartesian
Definition VelocityCoincidenceThinning.H:44
amrex::ParticleReal m_cluster_weight
Definition VelocityCoincidenceThinning.H:202
void operator()(const amrex::Geometry &geom_lev, WarpXParIter &pti, int lev, WarpXParticleContainer *pc) const final
A method that performs merging for the considered species.
Definition VelocityCoincidenceThinning.cpp:64
int m_ntheta
Definition VelocityCoincidenceThinning.H:199
Definition WarpXParticleContainer.H:112
Definition WarpXParticleContainer.H:195
constexpr auto pi
ratio of a circle's circumference to its diameter
Definition constant.H:29
__host__ __device__ void Swap(T &t1, T &t2) noexcept
ResamplingAlgorithm()=default
This merging routine requires functionality to sort a GPU vector based on another GPU vector's values...
Definition VelocityCoincidenceThinning.H:74
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void operator()(int index_array[], const int bin_array[], const int start, const int n) const
Definition VelocityCoincidenceThinning.H:77
Struct used to assign velocity space bin numbers to a given set of particles.
Definition VelocityCoincidenceThinning.H:119
amrex::ParticleReal ux_min
Definition VelocityCoincidenceThinning.H:192
amrex::ParticleReal uz_min
Definition VelocityCoincidenceThinning.H:192
amrex::ParticleReal uy_min
Definition VelocityCoincidenceThinning.H:192
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void labelOnCartesianVelocityGrid(const amrex::ParticleReal ux[], const amrex::ParticleReal uy[], const amrex::ParticleReal uz[], const int indices[], int bin_array[], int index_array[], const int cell_start, const int cell_stop) const
Definition VelocityCoincidenceThinning.H:150
amrex::ParticleReal dutheta
Definition VelocityCoincidenceThinning.H:190
amrex::ParticleReal duphi
Definition VelocityCoincidenceThinning.H:190
amrex::ParticleReal duy
Definition VelocityCoincidenceThinning.H:191
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void operator()(const amrex::ParticleReal ux[], const amrex::ParticleReal uy[], const amrex::ParticleReal uz[], const int indices[], int bin_array[], int index_array[], const int cell_start, const int cell_stop) const
Definition VelocityCoincidenceThinning.H:169
amrex::ParticleReal duz
Definition VelocityCoincidenceThinning.H:191
amrex::ParticleReal dur
Definition VelocityCoincidenceThinning.H:190
amrex::ParticleReal uy_max
Definition VelocityCoincidenceThinning.H:192
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void labelOnSphericalVelocityGrid(const amrex::ParticleReal ux[], const amrex::ParticleReal uy[], const amrex::ParticleReal uz[], const int indices[], int bin_array[], int index_array[], const int cell_start, const int cell_stop) const
Definition VelocityCoincidenceThinning.H:122
int n2
Definition VelocityCoincidenceThinning.H:189
amrex::ParticleReal dux
Definition VelocityCoincidenceThinning.H:191
VelocityGridType velocity_grid_type
Definition VelocityCoincidenceThinning.H:188
amrex::ParticleReal ux_max
Definition VelocityCoincidenceThinning.H:192
int n1
Definition VelocityCoincidenceThinning.H:189