In the following, names given with a monospaced font such as counts_s0 refer to variable names within the actual code. If a variable is a member of an object or a structure, it is given together with the name of its parent object: simu_fields->counts_s0 .

For a solid description of the moments of a distribution function: https://farside.ph.utexas.edu/teaching/plasma/lectures/node29.html

Densities

The density of species \(s\) is defined as

\[n_s = \int f_s({\bf r}, {\bf u}, t) d^3u\]

In Menura, when mapping the particles on the grid, we calculate the quantity stored in the variables simu_fields->counts_s0 and simu_fields->counts_s1 as

\[counts_s = \sum_p W(\mathbf{r}^p) \ ,\]

with \(W\) the shape factor, triangular for the current version of Menura, and not to be confused with the weight of the macro-particles. This humble expression, together with the fluxes mapping given below, takes most of (almost all really) the run time. It is done in the kernel part2grid_counts_flux_num_k within the file kernels_particles_to_grid.cuh. A separate file was created for this fundamental kernel because of its actual size in terms of lines of code, and because of it being the absolute bottle neck of the code, the very first target for future performance-enhancing efforts.

To convert from numerical counts to physical (normalised) densities:

\[n_s = w_s \cdot counts_s \ ,\]

with \(w_s\) the weight of the macro-particle of species \(s\), constant for all particles of a same species. For instance, the weight of the solar wind proton (species \(s0\)) is simply defined as

\[w_{s0} = 1/ppn \ ,\]

\(ppn\) being the number of particles per node or cell, nb_part_node_cst. These weights can be found in the simulation parameters, simu_param->w_s0 and simu_param->w_s1 . The total plasma density is then the simple sum of all species densities. The products of a simulation run should contain exactly their definition and the right naming, defined in this document.

Velocities

The flow velocity of species \(s\) is defined as

\[\mathbf{v}_s = 1/n_s \int \mathbf{u} f_s({\bf r}, {\bf u}, t) d^3u\]

The code variables equivalent to simu_fields->counts_s0 and simu_fields->counts_s1 are now simu_fields->flux_s0 and simu_fields->flux_s1, calculated as

\[flux_{s, i} = \sum_p u^p_i W(\mathbf{r}^p) \ .\]

Just as for the densities, the physical normalised ion flux of species \(s\) is simply obtained by multiplying the numerical fluxes by the macro-particle weights:

\[Ji_s = w_s \cdot flux_s \ .\]

Note: \(n_s\) and \(Ji_s\), the density and current of a species, do not exist as variables in the code, only the total density and the total ion current do exist, as simu_fields->density and simu_fields->Ji. These two variables are computed within src/kernels_fields.cuh in the kernels add_counts_k and add_curr_k. A version of these variables and kernels also exist with the additional subscript b, i.e. simu_fields->density_b, and are used for the time stepping of the leap-frog algorithm, when for instance both densities at the two different times are needed to calculate the average density at half-time.

Pressures

The pressure tensor is given by:

\[P_{s,ij} = \int m_{s}u_i u_j f_{s}({\bf r}, {\bf u}, t) d^3u - m_{s} n_{s} v_{s,i} v_{s,j}\]

where \(m_{s}\) is the particle mass, \(f_{s}\) is the particle distribution function, \(n_{s}\) is the particle number density, and \({\bf v}\) is the mean velocity. The following equation holds for \(f_{s}\)

\[\int f_{s}({\bf r}, {\bf u}, t) d^3r d^3u = N(t),\]

where \(N(t)\) is the total number of particles at time \(t\). In Menura the following quantities are stored in the variables simu_fields->stress_s0 and simu_fields->stress_s1, the two tensors:

\[stress_{s, ij} = \sum_p u^p_i u^p_j W(\mathbf{r}^p) \ .\]

In the continuous limit the last expression reads

\[\int u_i u_j f_{s}({\bf r}, {\bf u}, t) d^3u = stress_{s, ij} .\]

It is also easy to show that:

\[m_{s}n_{s}v_iv_j = m_s\frac{J_{s,i}J_{s,j}}{q_{s}^2n_{s}},\]

since \(q_s=1\) (implementation choice, i.e. no double charged species possibility), the latter reduces to

\[m_{s}n_{s}v_iv_j = m_s\frac{J_{s,i}J_{s,j}}{n_s},\]

where \(n_{s}\) is the number density. We arrive to the following expression for the true pressure tensor in Menura units:

\[P_{ij, s} = m_s\left(stress_{s, ij} -\frac{J_{s, i}J_{s, j}}{n_s}\right) \ .\]

Since this pressure is not used in the algorithm, it does not exist in memory, and should be computed from the stresses during post-processing.