Coarse and fine plasma¶
Concept¶
In order to increase stability and combat transverse grid noise, LCODE 3D utilises a dual plasma appoach.
Coarse particles are the ones that get tracked throughout the program, and pushed by the pusher. There coarse plasma grid is many times more sparse than the fields grid, think \(\frac{1}{9}\) particles per cell.
-
config_example.
plasma_coarseness
= 3¶ Square root of the amount of cells per coarse particle
Fine particles only exist inside the deposition phase. There are several fine particles per cell, think \(4\) or more. Their characteristic values are neither stored or evolved; instead they are intepolated from the coarse particle grid as a part of the the deposition process (and they don’t ‘exist’ in any form outside of it).
-
config_example.
plasma_fineness
= 2¶ Square root of the amount of fine particles per cell
Initialization¶
-
lcode.
make_coarse_plasma_grid
(steps, step_size, coarseness=3)[source]¶ Create initial coarse plasma particles coordinates (a single 1D grid for both x and y).
-
lcode.
make_fine_plasma_grid
(steps, step_size, fineness=2)[source]¶ Create initial fine plasma particles coordinates (a single 1D grid for both x and y).
Avoids positioning particles at the cell edges and boundaries.
fineness=3
(andcoarseness=2
):+-----------+-----------+-----------+-----------+ | . . . | . . . | . . . | . . . | | | | | | . - fine particle | . . . | . * . | . . . | . * . | | | | | | * - coarse+fine particle | . . . | . . . | . . . | . . . | +-----------+-----------+-----------+-----------+
fineness=2
(andcoarseness=2
):+-------+-------+-------+-------+-------+ | . . | . . | . . | . . | . . | . - fine particle | | * | | * | | | . . | . . | . . | . . | . . | * - coarse particle +-------+-------+-------+-------+-------+
-
lcode.
make_plasma
(steps, cell_size, coarseness=3, fineness=2)[source]¶ Make coarse plasma initial state arrays and the arrays needed to intepolate coarse plasma into fine plasma (
virt_params
).Coarse is the one that will evolve and fine is the one to be bilinearly interpolated from the coarse one based on the initial positions (using 1 to 4 coarse plasma particles that initially were the closest).
Initializing coarse particles is pretty simple:
coarse_x_init
andcoarse_y_init
are broadcasted output ofmake_coarse_plasma_grid()
.coarse_x_offt
andcoarse_y_offt
are zeros and so arecoarse_px
,coarse_py
andcoarse_pz
.coarse_m
andcoarse_q
are constants divided by the factor of coarseness by fineness squared because fine particles represent smaller macroparticles.Initializing fine particle boils down to calculating the interpolation coefficients (
influence_prev
andinfluence_next
) and the indices of the coarse particles (indices_prev
,indices_next
) that the characteristics will be intepolated from.influence_prev
andinfluence_next
are linear interpolation coefficients based on the initial closest coarse particle positioning. Note that these are constant and do not change in \(\xi\). The edges get special treatment later.indices_next
happens to be pretty much equal tonp.searchsorted(coarse_grid, fine_grid)
andindices_prev
is basicallyindices_next - 1
, except for the edges, where a fine particle can have less than four ‘parent’ coarse particles. For such ‘outer’ particles, existing coarse particles are used instead, so clipping the indices and fixinginfluence
-arrays is carried out.Note that these arrays are 1D for memory considerations [Memory considerations].
The function returns the coarse particles and
virtparams
: aGPUArrays
instance that conveniently groups the fine-particle related arrays, which only matter during deposition, under a single name.
Coarse-to-fine interpolation¶
-
lcode.
mix
(coarse, A, B, C, D, pi, ni, pj, nj)[source]¶ Bilinearly interpolate fine plasma properties from four historically-neighbouring plasma particle property values:
B D # y ^ A - bottom-left neighbour, indices: pi, pj . # | B - top-left neighbour, indices: pi, nj # +----> C - bottom-right neighbour, indices: ni, pj A C # x D - top-right neighbour, indices: ni, nj
See the rest of the deposition and plasma creation for more info.
This is just a shorthand for the characteristic value mixing for internal use in
coarse_to_fine
.
-
lcode.
coarse_to_fine
(fi, fj, c_x_offt, c_y_offt, c_m, c_q, c_px, c_py, c_pz, virtplasma_smallness_factor, fine_grid, influence_prev, influence_next, indices_prev, indices_next)[source]¶ Bilinearly interpolate fine plasma properties from four historically-neighbouring plasma particle property values.
The internals are pretty straightforward once you wrap your head around the indexing.
A single fine particle with the indices
[fi, fj]
(in fine particlesvirt_params
1D arrays) is interpolated from four particles with indices[pi, pj]
,[pi, nj]
,[ni, pj]
,[ni, nj]
(in coarse particlesc_*
arrays) and four weightsA
,B
,C
,D
respectively. The weights are, in turn, composed as a products of values frominfluence_prev
andinfluence_next
arrays, indiced, once again, with[fi, fj]
. It would be convenient to calculate them beforehand, but they are recalculated instead as a result of time-memory tradeoff [Memory considerations].Finally, momenta, charge and mass are scaled according to the coarse-to-fine macrosity coefficient discussed above.