Merzbild.jl public API reference

Particles

Merzbild.ParticleType
Particle{D}

A structure to store information about a single particle with a D-dimensional position vector.

Fields

  • w: the computational weight of the particle
  • v: the 3-dimensional velocity vector of the particle
  • x: the D-dimensional position of the particle
Merzbild.ParticleVectorType
ParticleVector{D}

The structure used to store particles, sort and keep track of particle indices, and keep track of unused particles. The lengths of the particles, index, cell, and buffer vectors are all the same (and stay the same during resizing of a ParticleVector instance). Only the first nbuffer elements of the buffer vector store indices of the actually unused particles. D determines the dimension of the particles' position vectors.

Accessing ParticleVector{D}[i] will return a Particle{D} instance, with the actual particle returned being ParticleVector.particles[ParticleVector.index[i]].

Fields

  • particles: the vector of particles of a single species
  • index: the vector of indices of the particles (these are sorted in grid sorting, not the particles themselves)
  • cell: the vector storing information in which cell a particle is located (used in grid sorting routines)
  • buffer: a last-in-first-out (LIFO) queue keeping track of pre-allocated but unused particles
  • nbuffer: the number of elements in the buffer
Merzbild.ParticleVectorMethod
ParticleVector{D}(np) where D

Create an empty ParticleVector{D} instance of length np (all vectors will have length np), filled with particles with weight 0, velocity 0, position 0.

Positional arguments

  • np: the length of the ParticleVector{D} instance to create
Base.getindexMethod
Base.getindex(pv::ParticleVector{D}, i) where D

Returns the underlying particle in a ParticleVector instance with index i.

Is usually called as ParticleVector[i].

Positional arguments

  • pv: ParticleVector instance
  • i: the index of the particle to be selected
Base.setindex!Method
Base.setindex!(pv::ParticleVector{D}, p::Particle{D}, i::Integer) where D

Set the underlying particle in a ParticleVector instance with index i to a new particle.

Is usually called as ParticleVector[i] = p.

Positional arguments

  • pv: ParticleVector instance
  • p: the Particle instance to write
  • i: the index of the particle to be written to
Base.lengthMethod
Base.length(pv::ParticleVector{D}) where D

Returns the length of a ParticleVector instance.

Is usually called as length(ParticleVector).

Positional arguments

  • pv: ParticleVector instance
Base.resize!Method
Base.resize!(pv::ParticleVector{D}, n::Integer) where D

Resize a ParticleVector instance, taking care of the indices, buffer, and creating placeholder new particles with weight 0, velocity 0, and position 0.

Positional arguments

  • pv: ParticleVector instance
  • n: the new length of the ParticleVector instance (i.e. the length of all the vector fields of the instance)

Particle indexing

Merzbild.ParticleIndexerType
ParticleIndexer

The structure used to index particles of a given species in a given cell. It is assumed that the particle indices are contiguous; they may be split across two groups of contiguous indices.

Fields

  • n_local: the number of particles in the cell
  • start1: the first index in the first group of particle indices
  • end1: the last index in the first group of particle indices
  • n_group1: the number of particles in the first group (n_group1 = end1 - start1 + 1)
  • start2: the first index in the second group of particle indices, if no particles are present in the group, it should be <= 0
  • end2: the last index in the second group of particle indices
  • n_group2: the number of particles in the second group (n_group2 = end2 - start2 + 1, unless no particles are present in the second group)
Merzbild.ParticleIndexerMethod
ParticleIndexer()

Create an empty ParticleIndexer. end1 and end2 are set to -1, the other fields are set to 0.

Merzbild.ParticleIndexerMethod
ParticleIndexer(n_particles)

Create a ParticleIndexer given a number of particles. All particles are in group 1, with indices starting from 1.

Positional arguments

  • n_particles: the number of particles
Merzbild.ParticleIndexerArrayType
ParticleIndexerArray

A structure to store an array of ParticleIndexer instances for each species in each cell. It also stores information about the whether the ParticleIndexer instances for each species are "contiguous". A set of ParticleIndexer instances (for a specific species) are "contiguous" if the following conditions are fulfilled (assuming all cells contain particles and in all cells have both n_group1>0 and n_group2>0, for a more detailed explanation, one is referred to the documentation on contiguous indexing):

  • pia.indexer[cell,species].end1 + 1 == pia.indexer[cell+1,species].start1, cell = 1,...,n_cells - 1
  • pia.indexer[n_cells,species].end1 + 1 == pia.indexer[1,species].start2
  • pia.indexer[cell,species].end2 + 1 == pia.indexer[cell+1,species].start2, cell = 1,...,n_cells - 1

Fields

  • n_cells: number of cells being indexed
  • n_species: number of species being indexed
  • indexer: the array of size (n_cells, n_species) (number of grid cells * number of species in the simulation) storing the ParticleIndexer instances
  • n_total: vector of length n_species storing the total number of particles of each species
  • contiguous: vector of length n_species storing a boolean flag whether the ParticleIndexer instances for a species are "contiguous"
  • index_last: vector of length n_species storing the last valid index in the particle array for each species (tracks the highest index used, allowing for non-contiguous indexing when particles are deleted from the middle)
Merzbild.ParticleIndexerArrayMethod
ParticleIndexerArray(indexer_arr::Array{ParticleIndexer,2}, n_total)

Creates a ParticleIndexerArray from a 2-D array of ParticleIndexer instances.

Positional arguments

  • indexer_arr: the 2-D array of ParticleIndexer instances
  • n_total: the vector of the total number of particles of each species
Merzbild.ParticleIndexerArrayMethod
ParticleIndexerArray(n_cells::Integer, n_species::Integer)

Create an empty ParticleIndexerArray given the number of cells and species

Positional arguments

  • n_cells: the number of grid cells
  • n_species: the number of species
Merzbild.ParticleIndexerArrayMethod
ParticleIndexerArray(n_particles::Integer)

Create a single-species/single-cell ParticleIndexerArray and set up the indexing for n_particles in group 1 in cell 1.

Positional arguments

  • n_particles: the number of particles (integer number)
Merzbild.ParticleIndexerArrayMethod
ParticleIndexerArray(n_particles::T) where T<:AbstractVector

Create a multi-species/single-cell ParticleIndexerArray and set up the indexing for n_particles[species] in group 1 in cell 1 for all species.

Positional arguments

  • n_particles: the number of particles of each species (vector-like)
Merzbild.ParticleIndexerArrayMethod
ParticleIndexerArray(grid, species_data::Array{Species})

Create an empty multi-species/multi-cell ParticleIndexerArray.

Positional arguments

  • grid: the simulation grid
  • species_data: array of Species data for all of the species in the simulation
Merzbild.squash_pia!Function
squash_pia!(pv::ParticleVector{D}, pia, species) where D

Restore the continuity of indices in a ParticleVector and associated ParticleIndexerArray instance for a specific species. If for this species the instance has contiguous == true, nothing will be done.

Positional arguments

  • pv: the ParticleVector
  • pia: the ParticleIndexerArray instance
  • species: the index of the species for which to restore continuity of indices
squash_pia!(particles, pia)

Restore the continuity of indices in a list of ParticleVectors and the associated ParticleIndexerArray instance for all species. If for a specific species the instance has contiguous == true, nothing will be done.

Positional arguments

  • particles: the list of ParticleVectors for all species in the flow
  • pia: the ParticleIndexerArray instance
Merzbild.restore_particle_ordering!Function
restore_particle_ordering!(pv::ParticleVector{D}, inv_map::Vector{Int64}) where D

Restore the ordering of particles in a ParticleVector so that pv.index[i] == i. This function ensures that:

  1. The index array is restored to identity mapping (pv.index[i] == i)
  2. The buffer contains only unused particle indices in descending order
  3. Used particles are placed in the first (length(pv.index) - pv.nbuffer) positions

Positional arguments

  • pv: ParticleVector instance to restore ordering for
  • inv_map: Vector of integers to store inverse map (inv_map[pv.index[i]] == i)
restore_particle_ordering!(pv::ParticleVector{D}, pia, species, inv_map::Vector{Int64}) where D

Restore the ordering of particles in a ParticleVector and update the associated ParticleIndexerArray. This function calls restore_particle_ordering! to restore the particle ordering and then updates pia.index_last[species] to reflect the new contiguous indexing.

Positional arguments

  • pv: ParticleVector instance to restore ordering for
  • pia: ParticleIndexerArray instance to update
  • species: the index of the species for which to update index_last
  • inv_map: Vector of integers to store inverse map (inv_map[pv.index[i]] == i)
Merzbild.count_disordered_particlesFunction
count_disordered_particles(pv::ParticleVector{D}, pia, species) where D

Count number of particles of species for which pv.index[i] != i + offset(cell). The larger this count, the less orderly the layout of particles in memory, which can potentially lead to decreased performance. This only considers particles present in the simulation, i.e. i<=pia.n_total[species], assumes contiguous indexing, and that particles are only pointed to by the first group of a ParticleIndexer, which is the case after particles have been sorted.

In case use_offset is false, the value of offset is always 0, so the function simply counts all particles where pv.index[i] != i. If use_offset is set to true, for each cell cell, the offset is whilst iterating over the particles in a cell. So in case the indexing in a cell is simply offset by a constant value, or a subset of indices are offset by a constant value, and particles are still laid out continuously in memory, this provides a more accurate measurement of the degree of fragmentation of the particle array.

Positional arguments

  • pv: the ParticleVector instance for which to compute the metric
  • pia: the ParticleIndexerArray instance
  • species: the index of the species for which the metric is computed

Keyword arguments

  • use_offset: whether to account for cell-specific offsets in the indexing

Returns

The number of particles where the index to the index array and the value of the index array do not coincide.

Merzbild.check_unique_indexFunction
check_unique_index(pv::ParticleVector{D}, pia, species) where D

Test that for all particles in a simulation, no two indices are the same, i.e. no two particles i and j, i!=j point to the same underlying particle. This function allocates a temporary array and is thus intended for debugging/verifying code and not for efficient simulations. It also checks that any particles present in the buffer are not pointed to by the indexing.

Positional arguments

  • pv: the ParticleVector instance for which to check indexing
  • pia: the ParticleIndexerArray instance
  • species: the species for which to check indexing

Returns

If a particle exists to which more than 1 index is pointing, and particles in the buffer ARE NOT pointed to by the indicies, returns (false, n_index), where n_index is the number of indices pointing to the same particle.

If a particle exists to which more than 1 index is pointing, and particles in the buffer ARE pointed to by the indicies, returns (false, -n_index), where n_index is the number of indices pointing to the same particle.

If no particles exist to which more than 1 index is pointing, but a particle in a buffer is pointed to by the indexing, returns (false, -1).

If indexing is correct, returns (true, 0).

Merzbild.check_pia_is_correctFunction
check_pia_is_correct(pia, species)

Check that a ParticleIndexerArray instance entries are correct. This means that for each cell for each species, the following should hold: * n_local == n_group1 + n_group2 * if n_group1 > 0, then n_group1 == end1 - start1 + 1 * if n_group1 == 0, then start1 == 0, end1 == -1 * if n_group2 > 0, then n_group2 == end2 - start2 + 1 * if n_group2 == 0, then start2 == 0, end2 == -1 * pia.n_total[species] == sum([pia.indexer[cell, species].n_local for cell in 1:n_cells]) and index_last[species] points to the last index used.

Positional arguments

  • pia: the ParticleIndexerArray instance for which to check consistency
  • species: the species for which to check indexing

Returns

If indexing is incorrect in a cell i, returns (false, i).

If the total number of particles as given by cell-wise particle indices is not equal to pia.n_total[species], returns (false, 0).

If index_last[species] < pia.n_total[species], returns (false, -1).

If index_last[species] is not the largest value of the indices pointed to by the groups, returns (false, -2).

If indexing is correct, returns (true, 0).

Merzbild.pretty_print_piaFunction
pretty_print_pia(pia, species)

Display a ParticleIndexerArray instance by showing the starting/ending indices of the groups over all cells for a specific species.

Positional arguments

  • pia: the ParticleIndexerArray instance
  • species: the index of the species for which the indices are displayed
Merzbild.check_unique_bufferFunction
check_unique_buffer(pv::ParticleVector{D}) where D

Test that the buffer elements in the active part of a buffer in a ParticleVector instance are unique (active part is pv.buffer[1:pv.nbuffer]). This function allocates a temporary dictionary and is thus intended for debugging/verifying code and not for efficient simulations.

Positional arguments

  • pv: the ParticleVector instance for which to check buffer

Returns

If a non-unique index is in the active part of the buffer, the function returns (false, i), where i is the first location at which the non-unique index is encountered for the second time (so if it is present at locations i1, i2, i3, etc., i2 will be returned).

If buffer is correct, returns (true, 0).

Loading species and interaction data

Merzbild.MERZBILD_DATA_PATHConstant
MERZBILD_DATA_PATH

Absolute path to the data directory bundled with Merzbild.jl, holding the built-in species (particles.toml) and interaction (vhs.toml, pseudo_maxwell.toml, vss.toml) data files. Use it to load bundled data independently of the current working directory, e.g. load_species_data(joinpath(MERZBILD_DATA_PATH, "particles.toml"), "Ar").

Merzbild.SpeciesType
Species

A structure to store information about a chemical species.

Fields

  • name: the name of the species
  • mass: the molecular mass of the species
  • charge: the charge of the species in terms of elementary charge (i.e. 1, -1, etc.)
  • charge_div_mass: the charge of the species divided by its mass, C/kg
Merzbild.InteractionType
Interaction

Structure to store interaction parameters for a 2-species interaction. The VHS model uses the following power law: $\sigma_{VHS} = C g^(1 - 2 \omega_{VHS})$, where $omega$ is the exponent of the VHS potential, and $C$ is the pre-computed factor: $C = \pi D_{VHS}^2 (2 T_{ref,VHS}/m_r)^{(\omega_{VHS} - 0.5)} \frac{1}{\Gamma(2.5 - \omega_{VHS})}$. The VSS model uses the same power law for the total cross-section, but a different scattering law.

The elastic scattering model is fixed for a species pair and is stored in the model field as a Merzbild.ScatteringModel enum value, so that the array of Interaction instances stays concretely typed.

Fields

  • m_r: collision-reduced mass
  • μ1: relative mass of the first species
  • μ2: relative mass of the second species
  • vhs_d: diameter for the VHS potential
  • vhs_o: exponent for the VHS potential (omega)
  • vhs_exp: pre-computed 1 - 2 vhs_o
  • vhs_Tref: reference temperature for the VHS potential
  • vhs_muref: reference viscosity for the VHS potential
  • vhs_factor: pre-computed factor for calculation of the VHS cross-section
  • vss_alpha: exponent of the VSS scattering law (equal to 1.0 for the models with isotropic scattering)
  • vss_inv_alpha: pre-computed 1 / vss_alpha
  • model: the ScatteringModel enum value of the elastic scattering model of the species pair
Merzbild.InteractionMethod
Interaction(m1::Float64, m2::Float64, vhs_d::Float64, vhs_o::Float64, vhs_Tref::Float64)

Construct an Interaction instance using the VHS model from the masses of the two species and the VHS parameters.

Positional arguments

  • m1: molecular mass of the first species
  • m2: molecular mass of the second species
  • vhs_d: VHS diameter
  • vhs_o: VHS exponent (omega)
  • vhs_Tref: reference VHS temperature
Merzbild.InteractionMethod
Interaction(::VHS, m1::Float64, m2::Float64, vhs_d::Float64, vhs_o::Float64, vhs_Tref::Float64)

Construct an Interaction instance using the VHS model from the masses of the two species and the VHS parameters.

Positional arguments

  • m1: molecular mass of the first species
  • m2: molecular mass of the second species
  • vhs_d: VHS diameter
  • vhs_o: VHS exponent (omega)
  • vhs_Tref: reference VHS temperature
Merzbild.InteractionMethod
Interaction(::VSS, m1::Float64, m2::Float64, vhs_d::Float64, vhs_o::Float64, vhs_Tref::Float64, vss_alpha::Float64)

Construct an Interaction instance using the VSS model from the masses of the two species, the VHS parameters (which define the total cross-section), and the VSS exponent (which defines the scattering law). The reference viscosity is corrected by the factor $(\alpha + 1)(\alpha + 2) / (6\alpha)$ accounting for the anisotropic scattering, see Merzbild.compute_vss_mu_ref_factor.

Positional arguments

  • m1: molecular mass of the first species
  • m2: molecular mass of the second species
  • vhs_d: VHS diameter
  • vhs_o: VHS exponent (omega)
  • vhs_Tref: reference VHS temperature
  • vss_alpha: VSS exponent (alpha)
Merzbild.load_species_dataFunction
load_species_data(species_filename, species_names)

Load a vector of species data (mass, charge, etc.) from a TOML file.

Positional arguments

  • species_filename: the path to the TOML file containing the data
  • species_names: a list of the names of the species for which to load the data

Returns

Vector of Species filled with data loaded from the file.

load_species_data(species_filename, species_name::String)

Load a vector of species data (mass, charge, etc.) from a TOML file for a single species.

Positional arguments

  • species_filename: the path to the TOML file containing the data
  • species_name: the name of the species for which to load the data

Returns

Vector of Species filled with data loaded from the file.

Merzbild.load_interaction_dataFunction
load_interaction_data(interactions_filename, species_data)

Load interaction data from a TOML file given a list of species' data (list of Species instances). It will load interaction data for all possible pair-wise interactions of the species in the list.

The resulting 2-D array has the interaction data for Species[i] with Species[k] in position [i,k]. It is not symmetric, as the relative collision masses μ1 and μ2 are swapped when comparing the Interaction instances in positions [i,k] and [k,i]. If no data is found, the function throws an error.

The elastic scattering model of a species pair is set by the optional model key of the pair's entry in the file, defaulting to the VHS model, see Merzbild.interaction_from_toml.

Positional arguments

  • interactions_filename: the path to the TOML file containing the data
  • species_data: list of Species instances for which to search for the interaction data

Returns

  • 2-dimensional array of Interaction instances of size (n_species, n_species)

Throws

KeyError if interaction data not found in the file.

load_interaction_data(interactions_filename, species_data)

Load interaction data from a TOML file given a list of species' data (list of Species instances), filling in dummy VHS data in case no entry is found in the TOML file. Useful for interactions where the VHS model doesn't make sense, for example electron-neutral interactions.

It will load interaction data for all possible pair-wise interactions of the species in the list. The resulting 2-D array has the interaction data for Species[i] with Species[k] in position [i,k]. It is not symmetric, as the relative collision masses μ1 and μ2 are swapped when comparing the Interaction instances in positions [i,k] and [k,i].

The elastic scattering model of a species pair is set by the optional model key of the pair's entry in the file, defaulting to the VHS model, see Merzbild.interaction_from_toml; the dummy data is always filled in using the VHS model.

Positional arguments

  • interactions_filename: the path to the TOML file containing the data
  • species_data: list of Species instances for which to search for the interaction data
  • dummy_vhs_d: value to use for the VHS diameter if no interaction data found in the file
  • dummy_vhs_o: value to use for the VHS exponent if no interaction data found in the file
  • dummy_vhs_Tref: value to use for the VHS reference temperature if no interaction data found in the file

Returns

  • 2-dimensional array of Interaction instances of size (n_species, n_species)
Merzbild.load_interaction_data_with_dummyFunction
load_interaction_data_with_dummy(interactions_filename, species_data)

Load interaction data from a TOML file given a list of species' data (list of Species instances), filling in dummy VHS data in case no entry is found in the TOML file. Useful for interactions where the VHS model doesn't make sense, for example electron-neutral interactions. Uses a value of 1e-10 for the dummy VHS diameter, 1.0 for the dummy VHS exponent, and 273.0 for the dummy VHS reference temperature.

It will load interaction data for all possible pair-wise interactions of the species in the list. The resulting 2-D array has the interaction data for Species[i] with Species[k] in position [i,k]. It is not symmetric, as the relative collision masses μ1 and μ2 are swapped when comparing the Interaction instances in positions [i,k] and [k,i].

Positional arguments

  • interactions_filename: the path to the TOML file containing the data
  • species_data: list of Species instances for which to search for the interaction data

Returns

  • 2-dimensional array of Interaction instances of size (n_species, n_species)
Merzbild.load_species_and_interaction_dataFunction
load_species_and_interaction_data(species_filename, interactions_filename, species_names; fill_dummy=true)

Given a list of species' names, load the species and interaction data (filling with dummy data if needed).

Positional arguments

  • species_filename: the path to the TOML file containing the species' data
  • interactions_filename: the path to the TOML file containing the interaction data
  • species_name: the name of the species for which to load the data

Keyword arguments

  • fill_dummy: if true, fill interaction data with computed dummy values if no entry found for a species pair in the interaction file

Returns

  • Vector of Species instances
  • 2-dimensional array of Interaction instances of size (n_species, n_species)

Elastic scattering models

Merzbild.AbstractScatteringModelType
AbstractScatteringModel

Abstract type for the elastic scattering models used by the DSMC/SWPM collision routines.

Each concrete model is a zero-field singleton type (VHS, VSS) that is used as a compile-time tag: the total cross-section Merzbild.sigma and the computation of the post-collision velocities Merzbild.scatter! are dispatched on it. As the tag is a zero-size value of a concrete type, it is not stored anywhere and the inner collision loops stay free of branching, dynamic dispatch, and allocations.

The model of a species pair is stored in the corresponding Interaction instance as a Merzbild.ScatteringModel enum value (so that the array of Interaction instances stays concretely typed); the collision routines convert it to the singleton tag exactly once per call, see Merzbild.@scattering_barrier.

Merzbild.VHSType
VHS

Singleton type tag for the Variable Hard Sphere model: the total cross-section follows the power law $\sigma = C g^{1 - 2\omega}$ and the scattering is isotropic.

Merzbild.VSSType
VSS

Singleton type tag for the Variable Soft Sphere model: the total cross-section is the same as for the VHS model, but the scattering is anisotropic, with the cosine of the deflection angle sampled as $\cos\chi = 2 R^{1/\alpha} - 1$, where $R$ is a uniformly distributed random number and $\alpha$ is the VSS exponent ($\alpha = 1$ recovers isotropic scattering).

References

  • K. Koura, H. Matsumoto, Variable soft sphere molecular model for inverse-power-law or Lennard-Jones potential. Phys. Fluids A, 1991.
Merzbild.ScatteringModelType
ScatteringModel ScatteringVHS=1 ScatteringVSS=2

Enum of the elastic scattering models, stored in an Interaction instance to define the model used for the species pair in question. ScatteringVHS corresponds to VHS, ScatteringVSS to VSS.

Sampling

Merzbild.maxwellianFunction
maxwellian(vx, vy, vz, m, T)

Evaluate the Maxwell distribution with temperature T for a species with mass m at a velocity (vx, vy, vz)

Positional arguments

  • vx: x velocity
  • vy: y velocity
  • vz: z velocity
  • m: species' mass
  • T: temperature
Merzbild.bkwFunction
bkw(vx, vy, vz, m, T, scaled_time)

Evaluate the Bobylev-Krook-Wu (BKW) distribution with temperature T for a species with mass m at a velocity (vx, vy, vz) and scaled time scaled_time

Positional arguments

  • vx: x velocity
  • vy: y velocity
  • vz: z velocity
  • m: species' mass
  • T: temperature
  • scaled_time: the scaled_time
Merzbild.sample_on_grid!Function
sample_on_grid!(rng, vdf_func, particles::ParticleVector{D}, nv, m, T, n_total,
                xlo, xhi, ylo, yhi, zlo, zhi; v_mult=3.5, cutoff_mult=3.5, noise=0.0,
                v_offset=[0.0, 0.0, 0.0])

Sample particles by evaluating a distribution on a discrete velocity grid, considering only points inside a sphere of a given radius (the value of the VDF at points outside of the sphere will be 0.0). The values of the VDF at the grid points will then be the computational weights of the particles, and the particles velocities are taken to be the velocities of the corresponding grid nodes (with additional uniformly distributed noise). Note: this can produce a large amount of particles for fine grids (as the number of grid nodes scales as nv^3.) The grid is assumed to have the same number of nodes nv in each direction, and the extent is computed as v_mult * v_thermal, where v_thermal is the thermal velocity $\sqrt(2kT/m)$, and v_mult is a user-defined parameter. The positions of the particles are assumed to be randomly distributed in a cuboid.

Positional arguments

  • rng: The random number generator
  • vdf_func: the distribution function to be evaluated which takes the x, y, and z velocities as parameters
  • particles: the Vector-like structure holding the particles
  • nv: the number of grid nodes in each direction
  • m: the molecular mass of the species
  • T: the temperature used to compute the thermal velocity
  • n_total: the total computational weight (number of physical particles) to be sampled
  • xlo: the lower bound of the x coordinates of the particles
  • xhi: the upper bound of the x coordinates of the particles
  • ylo: the lower bound of the y coordinates of the particles
  • yhi: the upper bound of the y coordinates of the particles
  • zlo: the lower bound of the z coordinates of the particles
  • zhi: the upper bound of the z coordinates of the particles

Keyword arguments

  • v_mult: the value by which the thermal velocity is multiplied to compute the extent of the velocity grid
  • cutoff_mult: the value by which the thermal velocity is multiplied to compute the radius for the sphere used to cut-off the higher velocities
  • noise: controls the amount of noise added to the particle velocities (the noise is uniformly distributed on the interval [-noise*dv, noise*dv], where dv is the grid spacing)
  • v_offset: the streaming velocity vector to be added to the particle velocities

Returns

  • The number of particles created
Merzbild.sample_maxwellian_on_grid!Function
sample_maxwellian_on_grid!(rng, particles::ParticleVector{D}, nv, m, T, n_total,
                           xlo, xhi, ylo, yhi, zlo, zhi; v_mult=3.5, cutoff_mult=3.5, noise=0.0,
                           v_offset=[0.0, 0.0, 0.0])

Sample particles by evaluating a Maxwellian on a discrete velocity grid, considering only points inside a sphere of a given radius (the value of the VDF at points outside of the sphere will be 0.0). The values of the VDF at the grid points will then be the computational weights of the particles, and the particles velocities are taken to be the velocities of the corresponding grid nodes (with additional uniformly distributed noise). Note: this can produce a large amount of particles for fine grids (as the number of grid nodes scales as nv^3.) The grid is assumed to have the same number of nodes nv in each direction, and the extent is computed as v_mult * v_thermal, where v_thermal is the thermal velocity $\sqrt(2kT/m)$, and v_mult is a user-defined parameter. The positions of the particles are assumed to be randomly distributed in a cuboid.

Positional arguments

  • rng: The random number generator
  • particles: the Vector-like structure holding the particles
  • nv: the number of grid nodes in each direction
  • m: the molecular mass of the species
  • T: the temperature used to compute the thermal velocity
  • n_total: the total computational weight (number of physical particles) to be sampled
  • xlo: the lower bound of the x coordinates of the particles
  • xhi: the upper bound of the x coordinates of the particles
  • ylo: the lower bound of the y coordinates of the particles
  • yhi: the upper bound of the y coordinates of the particles
  • zlo: the lower bound of the z coordinates of the particles
  • zhi: the upper bound of the z coordinates of the particles

Keyword arguments

  • v_mult: the value by which the thermal velocity is multiplied to compute the extent of the velocity grid
  • cutoff_mult: the value by which the thermal velocity is multiplied to compute the radius for the sphere used to cut-off the higher velocities
  • noise: controls the amount of noise added to the particle velocities (the noise is uniformly distributed on the interval [-noise*dv, noise*dv], where dv is the grid spacing)
  • v_offset: the streaming velocity vector to be added to the particle velocities

Returns

The function returns the number of particles created

Merzbild.sample_particles_equal_weight!Function
sample_particles_equal_weight!(rng, particles, pia, cell, species,
                                    nparticles, m, T, Fnum, xlo, xhi, ylo, yhi, zlo, zhi;
                                    distribution=:Maxwellian, vx0=0.0, vy0=0.0, vz0=0.0)

Sample equal-weight particles of a specific species in a specific cell from a distribution. The positions of the particles are assumed to be randomly distributed in a cuboid. Note: this does not work if applied twice in a row to the same cell.

Positional arguments

  • rng: the random number generator
  • particles: the Vector-like structure holding the particles
  • pia: the ParticleIndexerArray
  • cell: the cell index
  • species: the species index
  • nparticles: the number of particles to sample
  • m: species' mass
  • T: temperature
  • Fnum: the computational weight of the particles
  • xlo: the lower bound of the x coordinates of the particles
  • xhi: the upper bound of the x coordinates of the particles
  • ylo: the lower bound of the y coordinates of the particles
  • yhi: the upper bound of the y coordinates of the particles
  • zlo: the lower bound of the z coordinates of the particles
  • zhi: the upper bound of the z coordinates of the particles

Keyword arguments

  • distribution: the distribution to sample from (either :Maxwellian or :BKW)
  • vx0: the x-velocity offset to add to the particle velocities
  • vy0: the y-velocity offset to add to the particle velocities
  • vz0: the z-velocity offset to add to the particle velocities
sample_particles_equal_weight!(rng, grid1duniform, particles, pia, species, species_data, ppc::Integer, T, Fnum)

Sample particles from a Maxwellian distribution in each cell of a 1-D uniform grid given the number of particles per cell.

Positional arguments

  • rng: the random number generator
  • grid1duniform: the 1-D uniform grid
  • particles: the ParticleVector of particles
  • pia: the ParticleIndexerArray
  • species: the index of the species to be sampled for
  • species_data: Vector of Species data
  • ppc: number of particles per cell to be sampled
  • T: the temperature
  • Fnum: the computational weight of the particles
sample_particles_equal_weight!(rng, grid1duniform, particles, pia, species, species_data, ppc::Integer, T, Fnum, cell_chunk)

Sample particles from a Maxwellian distribution in a sequentially ordered subset of cells of a 1-D uniform grid given the number of particles per cell.

Positional arguments

  • rng: the random number generator
  • grid1duniform: the 1-D uniform grid
  • particles: the ParticleVector of particles
  • pia: the ParticleIndexerArray
  • species: the index of the species to be sampled for
  • species_data: Vector of Species data
  • ppc: number of particles per cell to be sampled
  • T: the temperature
  • Fnum: the computational weight of the particles
  • cell_chunk: the list of cell indices or range in which to sample particles, should be ordered in increasing order
sample_particles_equal_weight!(rng, grid1duniform, particles, pia, species, species_data, ndens::Float64, T, Fnum)

Sample particles from a Maxwellian distribution in each cell in a sequentially ordered subset of cells of a 1-D uniform grid given the target number density. If the computed number of particles is not an integer value, the fractional remainder is used to probabilistically sample an extra particle, so that on average, the expected number density is achieved.

Positional arguments

  • rng: the random number generator
  • grid1duniform: the 1-D uniform grid
  • particles: the ParticleVector of particles
  • pia: the ParticleIndexerArray
  • species: the index of the species to be sampled for
  • species_data: Vector of Species data
  • ndens: target number density
  • T: the temperature
  • Fnum: the computational weight of the particles
sample_particles_equal_weight!(rng, grid1duniform, particles, pia, species, species_data, ndens::Float64, T, Fnum, cell_chunk)

Sample particles from a Maxwellian distribution in each cell of 1-D uniform grid given the target number density. If the computed number of particles is not an integer value, the fractional remainder is used to probabilistically sample an extra particle, so that on average, the expected number density is achieved.

Positional arguments

  • rng: the random number generator
  • grid1duniform: the 1-D uniform grid
  • particles: the ParticleVector of particles
  • pia: the ParticleIndexerArray
  • species: the index of the species to be sampled for
  • species_data: Vector of Species data
  • ndens: target number density
  • T: the temperature
  • Fnum: the computational weight of the particles
  • cell_chunk: the list of cell indices or range in which to sample particles, should be ordered in increasing order
Merzbild.sample_particles_phase_box_weighted!Function
sample_particles_phase_box_weighted!(rng, particles::ParticleVector{D}, pia, cell, species,
                                     nparticles, m, T, n_total, xlo, xhi, ylo, yhi, zlo, zhi;
                                     v_mult=3.5, vx0=0.0, vy0=0.0, vz0=0.0)

Sample variable-weight particles of a specific species in a specific cell from a Maxwellian. The velocities are sampled in a uniform box in phase space with extent ±v_mult * v_thermal in each direction, where v_thermal is the thermal velocity $\sqrt(2kT/m)$, and v_mult is a user-defined parameter, and their weights are computed proportional to the value of a Maxwell distribution at temperature T at those velocities. A streaming velocity component can be added to all of the sampled particles' velocities. The positions of the particles are assumed to be randomly distributed in a cuboid.

Positional arguments

  • rng: the random number generator
  • particles: the Vector-like structure holding the particles
  • pia: the ParticleIndexerArray
  • cell: the cell index
  • species: the species index
  • nparticles: the number of particles to sample
  • m: species' mass
  • T: temperature
  • n_total: the total computational weight (number of physical particles) to be sampled
  • xlo: the lower bound of the x coordinates of the particles
  • xhi: the upper bound of the x coordinates of the particles
  • ylo: the lower bound of the y coordinates of the particles
  • yhi: the upper bound of the y coordinates of the particles
  • zlo: the lower bound of the z coordinates of the particles
  • zhi: the upper bound of the z coordinates of the particles

Keyword arguments

  • v_mult: the value by which the thermal velocity is multiplied to compute the extent of the velocity box
  • vx0: the x-velocity offset to add to the particle velocities
  • vy0: the y-velocity offset to add to the particle velocities
  • vz0: the z-velocity offset to add to the particle velocities

Computing grid and surface macroscopic properties

Merzbild.PhysPropsType
PhysProps

Structure to store computed physical properties in a physical cell.

Fields

  • ndens_not_Np: whether the n field stores number density (if true) and not the number of physical particles in a cell (if false)
  • n_cells: number of physical cells
  • n_species: number of species
  • lpa: length of the particle array (vector of length n_species)
  • np: number of particles (array of shape (n_cells, n_species))
  • n: number density or number of physical particles in a cell (array of shape (n_cells, n_species))
  • v: per-species flow velocity in a cell (array of shape (3, n_cells, n_species))
  • T: per-species temperature in a cell (array of shape (n_cells, n_species))
Merzbild.PhysPropsMethod
PhysProps(n_cells, n_species; ndens_not_Np=false)

Construct physical properties given the number of cells and species.

Positional arguments

  • n_cells: number of cells
  • n_species: number of species

Keyword arguments

  • ndens_not_Np: whether the n field stores number density (if true) and not the number of physical particles in a cell (if false)
Merzbild.PhysPropsMethod
PhysProps(pia::ParticleIndexerArray; ndens_not_Np=false)

Construct physical properties given a ParticleIndexerArray instance,.

Positional arguments

  • pia: the ParticleIndexerArray instance

Keyword arguments

  • ndens_not_Np: whether the n field stores number density (if true) and not the number of physical particles in a cell (if false)
Merzbild.SurfPropsType
SurfProps

Structure to store computed surface properties.

Fields

  • n_elements: number of surface elements
  • n_species: number of species
  • areas: the vector of surface element areas
  • inv_areas: the vector of the inverse surface element areas
  • normals: the array of surface element normals with shape (3, n_elements)
  • np: number of particles impacting the surface elements, array of shape (n_elements, n_species)
  • flux_incident: incident mass flux per surface element, array of shape (n_elements, n_species)
  • flux_reflected: reflected mass flux per surface element, array of shape (n_elements, n_species)
  • force: force acting per surface element, array of shape (3, n_elements, n_species)
  • normal_pressure: normal pressure per surface element, array of shape (n_elements, n_species)
  • shear_pressure: shear pressure per surface element, array of shape (3, n_elements, n_species)
  • kinetic_energy_flux: kinetic energy flux per surface element, array of shape (n_elements, n_species)
Merzbild.SurfPropsMethod
SurfProps(n_elements, n_species, areas, normals)

Construct a struct for holding computed surface properties for n_elements surface elements, n_species species. The surface elements' areas and normals are given by areas and normals, respectively.

Positional arguments

  • n_elements: number of surface elements
  • n_species: number of species
  • areas: vector of areas of surface elements
  • normals: vector of normals to surface elements
Merzbild.SurfPropsMethod
SurfProps(pia, grid::Grid1DUniform)

Create a SurfProps struct for a 1-D grid, with element 1 corresponding to the left wall and element 2 corresponding to the right wall. The areas of the wall are assumed to be equal to 1, the normals are parallel to the x axis.

Positional arguments

  • pia: the ParticleIndexerArray instance
  • grid: the Grid1DUniform grid
Merzbild.FluxPropsType
FluxProps

Structure to store computed flux densities in a physical cell. The kinetic energy flux density of a species is computed as $\frac{m}{2V} \sum_i w_i \mathbf{C}_i C_i^2$, where $\mathbf{C}_i$ is the peculiar velocity of a particle, $m$ is the molecular mass of the species, $V$ is the cell volume. The $k,l$ component of the the momentum flux density tensor is computed as $\frac{m}{2V} \sum_i w_i \C_{i,k} \C_{i,l}$. The $xx$, $yy$, $zz$ components thereof are stored in diagonal_momentum_flux. The $xy$, $xz$, $yz$ components thereof are stored in off_diagonal_momentum_flux.

Fields

  • n_cells: number of physical cells
  • n_species: number of species
  • kinetic_energy_flux: per-species kinetic energy flux in a cell (array of shape (3, n_cells, n_species))
  • diagonal_momentum_flux: diagonal components of the per-species momentum flux tensor in a cell (array of shape (3, n_cells, n_species))
  • off_diagonal_momentum_flux: off-diagonal components of the per-species momentum flux tensor in a cell (array of shape (3, n_cells, n_species))
Merzbild.FluxPropsMethod
FluxProps(n_cells, n_species)

Construct a FluxProps instance given the number of cells and species.

Positional arguments

  • n_cells: number of cells
  • n_species: number of species
Merzbild.FluxPropsMethod
FluxProps(pia)

Construct a FluxProps instance given a ParticleIndexerArray instance.

Positional arguments

  • pia: the ParticleIndexerArray instance
Merzbild.ElectrostaticFieldPropsType
ElectrostaticFieldProps

Structure to store the electrostatic field quantities on the nodes of a grid. The quantities are node-centered: for a 1D uniform grid with n_cells cells, the nodes are located at $x_j = (j-1) \Delta x$, $j = 1 \dots n_{\textrm{cells}}+1$, so all the vectors are of length n_cells + 1. For a periodic simulation, the last node is the periodic image of the first one, and the values stored in it are mirrored from the first node.

The structure is grid-independent: it stores no reference to a grid or to a Poisson solver.

Fields

  • n_nodes: number of nodes
  • charge_density: the charge density $\rho$ in the nodes, C/m³ (before a call to normalize_charge_density! this holds the deposited charge in C and not a density)
  • potential: the electrostatic potential $\phi$ in the nodes, V
  • electric_field: the x-component of the electric field $E_x$ in the nodes, V/m
  • net_charge_density: the mean charge density subtracted in the periodic case, 0.0 otherwise, C/m³
Merzbild.ElectrostaticFieldPropsMethod
ElectrostaticFieldProps(n_nodes::Integer)

Construct an ElectrostaticFieldProps instance given the number of nodes (and not the number of cells, in contrast to PhysProps(n_cells, n_species)). For a 1-D uniform grid with n_cells cells, the number of nodes is n_cells + 1.

Positional arguments

  • n_nodes: number of nodes
Merzbild.ElectrostaticFieldPropsMethod
ElectrostaticFieldProps(grid::Grid1DUniform)

Construct an ElectrostaticFieldProps instance for a 1-D uniform grid, using n_nodes = grid.n_cells + 1 nodes.

Positional arguments

  • grid: the Grid1DUniform grid
Merzbild.clear_charge_density!Function
clear_charge_density!(field_props::ElectrostaticFieldProps)

Clear the charge density stored in an ElectrostaticFieldProps instance, leaving the potential and the electric field computed at the previous timestep untouched. This is to be called before the charge of the particles is deposited on the nodes at a new timestep.

Positional arguments

  • field_props: the ElectrostaticFieldProps instance for which the charge density is cleared
Merzbild.compute_props!Function
compute_props!(particles, pia, species_data, phys_props)

Compute the physical properties of all species in all cells and store the result in a PhysProps instance. This function does not compute the total moments, even if phys_props.n_moments > 0.

Positional arguments

  • particles: the Vector of ParticleVectors containing all the particles in a simulation
  • pia: the ParticleIndexerArray instance
  • species_data: the Vector of SpeciesData
  • phys_props: the PhysProps instance in which the computed physical properties are stored
Merzbild.compute_props_sorted!Function
compute_props_sorted!(particles, pia, species_data, phys_props, cell_chunk)

Compute the physical properties of all species in a subset of cells and store the result in a PhysProps instance, assuming the particles are sorted. This function does not compute the total moments, even if phys_props.n_moments > 0. Currently this does not compute the length of the particle array.

Positional arguments

  • particles: the Vector of ParticleVectors containing all the particles in a simulation
  • pia: the ParticleIndexerArray instance
  • species_data: the Vector of SpeciesData
  • phys_props: the PhysProps instance in which the computed physical properties are stored
  • cell_chunk: the list of cell indices or range of cell indices in which to compute the properties
compute_props_sorted!(particles, pia, species_data, phys_props)

Compute the physical properties of all species in all cells and store the result in a PhysProps instance, assuming the particles are sorted. This function does not compute the total moments, even if phys_props.n_moments > 0. Currently this does not compute the length of the particle array.

Positional arguments

  • particles: the Vector of ParticleVectors containing all the particles in a simulation
  • pia: the ParticleIndexerArray instance
  • species_data: the Vector of SpeciesData
  • phys_props: the PhysProps instance in which the computed physical properties are stored
compute_props_sorted!(particles::Vector{ParticleVector{D}}, pia, species_data, phys_props, grid::G, cell_chunk) where {G<:AbstractGrid,D}

Compute the physical properties of all species in a subset of cells and store the result in a PhysProps instance, assuming the particles are sorted. This function does not compute the total moments, even if phys_props.n_moments > 0. If ndens_not_Np is true, the number density will be computed based on the volumes of the grid cells; otherwise, the number of physical particles in each cell will be computed. Currently this does not compute the length of the particle array.

Positional arguments

  • particles: the Vector of ParticleVectors containing all the particles in a simulation
  • pia: the ParticleIndexerArray instance
  • species_data: the Vector of SpeciesData
  • phys_props: the PhysProps instance in which the computed physical properties are stored
  • grid: the physical grid
  • cell_chunk: the list of cell indices or range of cell indices in which to compute the properties
compute_props_sorted!(particles::Vector{ParticleVector{D}}, pia, species_data, phys_props, grid::G) where {G<:AbstractGrid,D}

Compute the physical properties of all species in all cells and store the result in a PhysProps instance, assuming the particles are sorted. This function does not compute the total moments, even if phys_props.n_moments > 0. If ndens_not_Np is true, the number density will be computed based on the volumes of the grid cells; otherwise, the number of physical particles in each cell will be computed. Currently this does not compute the length of the particle array.

Positional arguments

  • particles: the Vector of ParticleVectors containing all the particles in a simulation
  • pia: the ParticleIndexerArray instance
  • species_data: the Vector of SpeciesData
  • phys_props: the PhysProps instance in which the computed physical properties are stored
  • grid: the physical grid
Merzbild.compute_flux_props!Function
compute_flux_props!(particles::Vector{ParticleVector{D}}, pia, species_data, phys_props::PhysProps, flux_props::FluxProps, grid::G) where {G<:AbstractGrid,D}

Compute the fluxes of all species in all cells and store the result in a FluxProps instance. This uses the pre-computed species-wise mean velocities from a PhysProps instance, which needs to be computed at the same timestep before calling this function. Particles of a cell can be distributed across group1 and group2 of indices pointed to by the ParticleIndexerArray instance, i.e. this function can be used to compute fluxes immediately after collisions (but before convection). In case particles are sorted, compute_flux_props_sorted! will be more efficient.

Positional arguments

  • particles: the Vector of ParticleVectors containing all the particles in a simulation
  • pia: the ParticleIndexerArray instance
  • species_data: the Vector of SpeciesData
  • phys_props: the PhysProps instance computed at the same timestep
  • flux_props: the FluxProps instance in which the computed fluxes are stored
  • grid: the physical grid
Merzbild.compute_flux_props_sorted!Function
compute_flux_props_sorted!(particles::Vector{ParticleVector{D}}, pia, species_data, phys_props, flux_props, grid::G, cell_chunk) where {G<:AbstractGrid, D}

Compute the flux densities of all species in a subset of cells and store the result in a FluxProps instance, assuming the particles are sorted. This uses the pre-computed species-wise mean velocities from a PhysProps instance, which needs to be computed at the same timestep before calling this function for the same subset of cells.

Positional arguments

  • particles: the Vector of ParticleVectors containing all the particles in a simulation
  • pia: the ParticleIndexerArray instance
  • species_data: the Vector of SpeciesData
  • phys_props: the PhysProps instance computed at the same timestep for the same subset of cells
  • flux_props: the FluxProps instance in which the computed fluxes are stored
  • grid: the physical grid
  • cell_chunk: the list of cell indices or range of cell indices in which to compute the properties
compute_flux_props_sorted!(particles::Vector{ParticleVector{D}}, pia, species_data, phys_props, flux_props, grid::G) where {G<:AbstractGrid,D}

Compute the flux densities of all species in all cells and store the result in a FluxProps instance, assuming the particles are sorted. This uses the pre-computed species-wise mean velocities from a PhysProps instance, which needs to be computed at the same timestep before calling this function.

Positional arguments

  • particles: the Vector of ParticleVectors containing all the particles in a simulation
  • pia: the ParticleIndexerArray instance
  • species_data: the Vector of SpeciesData
  • phys_props: the PhysProps instance computed at the same timestep
  • flux_props: the FluxProps instance in which the computed fluxes are stored
  • grid: the physical grid
Merzbild.avg_props!Function
avg_props!(phys_props_avg::PhysProps, phys_props::PhysProps, n_avg_timesteps)

Used to time-average computed physical properties, not including the total moments. For each instantaneous value of a property computed and stored in phys_props, it is divided by n_avg_timesteps and added to phys_props_avg.

Positional arguments

  • phys_props_avg: the PhysProps instance used to store the time-averaged properties
  • phys_props: the PhysProps instance holding the current values of the properties to be used for the averaging at the current timestep
  • n_avg_timesteps: the number of timesteps over which the averaging is performed

Throws

ErrorException if phys_props_avg computes number density and phys_props computes number of physical particles, or vice versa.

avg_props!(flux_props_avg::FluxProps, flux_props::FluxProps, n_avg_timesteps)

Used to time-average computed flux densities. For each instantaneous value of a property computed and stored in flux_props, it is divided by n_avg_timesteps and added to flux_props_avg.

Positional arguments

  • flux_props_avg: the FluxProps instance used to store the time-averaged properties
  • flux_props: the FluxProps instance holding the current values of the properties to be used for the averaging at the current timestep
  • n_avg_timesteps: the number of timesteps over which the averaging is performed
avg_props!(surf_props_avg::SurfProps, surf_props::SurfProps, n_avg_timesteps)

Used to time-average computed surface properties. For each instantaneous value of a property computed and stored in surf_props, it is divided by n_avg_timesteps and added to surf_props_avg.

Positional arguments

  • surf_props_avg: the SurfProps instance used to store the time-averaged properties
  • surf_props: the SurfProps instance holding the current values of the properties to be used for the averaging at the current timestep
  • n_avg_timesteps: the number of timesteps over which the averaging is performed
Merzbild.clear_props!Function
clear_props!(phys_props::PhysProps)

Clear all data from PhysProps, for use when physical properties are averaged over timesteps and averaging over a new set of timesteps needs to be started.

Positional arguments

  • phys_props: the PhysProps instance to be cleared
clear_props!(flux_props::FluxProps)

Clear all data from FluxProps, for use when flux densities are averaged over timesteps and averaging over a new set of timesteps needs to be started.

Positional arguments

  • flux_props: the FluxProps instance to be cleared
clear_props!(field_props::ElectrostaticFieldProps)

Clear all data from an ElectrostaticFieldProps instance (the charge density, the potential, and the electric field). For clearing only the charge density in a time loop, use clear_charge_density!.

Positional arguments

  • field_props: the ElectrostaticFieldProps instance to be cleared
clear_props!(surf_props::SurfProps)

Clear all data from a SurfProps instance, either at the start of a new convection step, or when physical properties are averaged over timesteps and averaging over a new set of timesteps needs to be started.

Positional arguments

  • surf_props: the SurfProps instance to be cleared
Merzbild.compute_moment_scaling!Function
compute_moment_scaling!(moment_scaling, moment_powers, species, species_data, Tref)

Fill the vector moment_scaling with the appropriate scaling based on the Maxwell-Boltzmann distribution for a specific species.

Positional arguments

  • moment_scaling: vector to be filled with the moment scaling factors (length n_moments)
  • moment_powers: vector of moment powers (length n_moments)
  • species: the species for which the mixed moment is being computed
  • species_data: the Vector of SpeciesData
  • Tref: reference temperature used to compute the total moments of a Maxwellian distribution which are used to scale the total moments
Merzbild.compute_moments!Function
compute_moments!(moment_values, moment_scaling, moment_powers, particles, pia, cell, species, species_data, phys_props)

Fill the vector moment_values with the computed scaled moment values for a single species in a single cell. The values of n (number density or number of physical particles) and v (mean velocity) are taken from phys_props. It's important that function compute_props! must be called before this function, so that the correct nandv`` values are available.

Positional arguments

  • moment_values: vector to be filled with the computed moment values (length n_moments)
  • moment_scaling: vector of precomputed moment scaling factors (length n_moments)
  • moment_powers: vector of moment powers (length n_moments)
  • particles: the Vector of ParticleVectors containing all the particles in a simulation
  • pia: the ParticleIndexerArray instance
  • cell: the cell in which the moment is being computed
  • species: the species for which the mixed moment is being computed
  • species_data: the Vector of SpeciesData
  • phys_props: the PhysProps instance in which the computed physical properties are stored

Collisional properties

Merzbild.mean_free_pathFunction
mean_free_path(interaction, species, n, T)

Compute elastic VHS mean free path for single-species collisions. This also holds for a VSS interaction, as the VSS model uses the same total cross-section as the VHS model.

Positional arguments

  • interaction: the 2-dimensional array of Interaction instances (of shape (n_species, n_species)) of all the pair-wise interactions
  • species: the species for which to compute the mean free path
  • n: the number density
  • T: the temperature

Returns

Mean free path.

References

  • Eqn. (4.65) in "Molecular Gas Dynamics and the Direct Simulation of Gas Flows" or (D.21) in "Nonequilibrium Gas Dynamics and Molecular Simulation".
Merzbild.mean_collision_frequencyFunction
mean_collision_frequency(interaction, species, species_data, n, T)

Compute elastic VHS mean collision frequency for single-species collisions. This also holds for a VSS interaction, as the VSS model uses the same total cross-section as the VHS model.

Positional arguments

  • interactions: the 2-dimensional array of Interaction instances (of shape (n_species, n_species)) of all the pair-wise interactions
  • species: the species for which to compute the mean free path
  • species_data: the vector of Species instances of the species in the flow
  • n: the number density
  • T: the temperature

Returns

Mean collision frequency.

References

  • Eqn. (4.64) in "Molecular Gas Dynamics and the Direct Simulation of Gas Flows"
Merzbild.debye_lengthFunction
debye_length(n, T)

Compute the Debye length $\lambda_D = \sqrt{\varepsilon_0 k_B T / (n q_e^2)}$ of a plasma with singly charged particles with density $n$ at a temperature $T$.

Positional arguments

  • n: the number density of the charged particles
  • T: the temperature of the charged particles

Returns

Debye length.

Merzbild.plasma_frequencyFunction
plasma_frequency(species, species_data, n)

Compute the plasma frequency $\omega_p = \sqrt{n q^2 / (\varepsilon_0 m)}$ of a species with charge $q$ and mass $m$ with a number density $n$.

Positional arguments

  • species: the species for which to compute the plasma frequency
  • species_data: the vector of Species instances of the species in the flow
  • n: the number density of the species

Returns

Plasma frequency in rad/s.

Collision computations

Merzbild.CollisionDataType
CollisionData

Structure to store temporary collision data for a specific collision (relative velocity, collision energy, post-collision velocities, etc.)

Fields

  • v_com: vector of center-of-mass velocity
  • g: magnitude of relative velocity
  • E_coll: relative translational energy of the colliding particles
  • E_coll_eV: relative translational energy of the colliding particles in electron-volt
  • g_vec: vector of pre-collisional relative velocity
  • g_vec_new: vector of post-collisional relative velocity
  • g_new_1: magnitude of post-collisional relative velocity of the first particle in the collision pair
  • g_new_2: magnitude of post-collisional relative velocity of the second particle in the collision pair
Merzbild.CollisionFactorsType
CollisionFactors

Structure to store NTC-related collision factors for collisions between particles of two species in a given cell.

Fields

  • n1: the number of particles of the first species in the cell
  • n2: the number of particles of the second species in the cell
  • sigma_g_w_max: estimate of the $(\sigma g w)_{max}$ ($\sigma$ is the total collision cross-section, $g$ is the relative collision velocity, $w$ is the computational weight of the particles)
  • n_coll: number of collisions to be tested
  • n_coll_performed: number of collisions actually performed
  • n_eq_w_coll_performed: number of collisions between particles with equal weights actually performed
Merzbild.CollisionFactorsSWPMType
CollisionFactorsSWPM

Structure to store SWPM-related collision factors for collisions between particles of two species in a given cell.

Fields

  • n1: the number of particles of the first species in the cell
  • n2: the number of particles of the second species in the cell
  • sigma_g_max: estimate of the $(\sigma g)_{max}$ ($\sigma$ is the total collision cross-section, $g$ is the relative collision velocity
  • n_coll: number of collisions to be tested
  • n_coll_performed: number of collisions actually performed
Merzbild.CollisionDataFPType
CollisionDataFP

Structure to store temporary collision data for the particle Fokker-Planck approach.

Fields

  • vel_ave: average velocity of the particles in the cell
  • mean: mean value of the sampled velocities
  • stddev: standard deviation of the sampled velocities
  • xvel_rand: pre-allocated storage for sampled x-velocity components
  • yvel_rand: pre-allocated storage for sampled y-velocity components
  • zvel_rand: pre-allocated storage for sampled z-velocity components
Merzbild.CollisionDataFPMethod
CollisionDataFP(n_particles_in_cell)

Create an empty CollisionDataFP instance, pre-allocating the arrays for sampled normal variables for n_particles_in_cell.

Positional arguments

  • n_particles_in_cell: estimate of expected maximum number of particles in cell
Merzbild.create_collision_factors_arrayFunction
create_collision_factors_array(n_species)

Create a 3-dimensional array of collision factors for all interaction pairs for a 0-D case (1 spatial cell), with shape (n_species,n_species,1).

Positional arguments

  • n_species: number of species in the flow

Returns

3-dimensional array of CollisionFactors instances with shape (n_species,n_species,1).

create_collision_factors_array(n_species, n_cells)

Create a 3-dimensional array of collision factors for all interaction pairs for all cells in the simulation, with shape (n_species,n_species,n_cells).

Positional arguments

  • n_species: number of species in the flow
  • n_cells: number of cells in the simulation

Returns

3-dimensional array of CollisionFactors instances with shape (n_species,n_species,n_cells).

create_collision_factors_array(pia)

Create a 3-dimensional array of collision factors for all interaction pairs for all cells in the simulation, with shape (n_species,n_species,n_cells).

Positional arguments

  • pia: the ParticleIndexerArray instance

Returns

3-dimensional array of CollisionFactors instances with shape (n_species,n_species,n_cells).

create_collision_factors_array(pia, interactions, species_data, T_list, Fnum::Real; mult_factor=1.0)

Create a 3-dimensional array of collision factors for all interaction pairs for all cells in the simulation, with shape (n_species,n_species,n_cells). This will fill the array with the estimates $(\sigma g w)_{max}$ for all species in all cells, assuming a constant particle computational weight Fnum, a VHS cross-section, and that the temperature of each species is constant across all cells.

Positional arguments

  • pia: the ParticleIndexerArray instance
  • interactions: the 2-dimensional array of Interaction instances (of shape (n_species, n_species)) of all the pair-wise interactions
  • species_data: the vector of Species instances of the species in the flow
  • T_list: the list of temperatures of the species
  • Fnum: the constant computational weight of the particles

Keyword arguments

  • mult_factor: a factor by which to multiply the result (default value is 1.0)

Returns

3-dimensional array of CollisionFactors instances with shape (n_species,n_species,n_cells) filled with estimated values of $(\sigma g w)_{max}$.

create_collision_factors_array(pia, interactions, species_data, T::Real, Fnum::Real; mult_factor=1.0)

Create a 3-dimensional array of collision factors for all interaction pairs for all cells in the simulation, with shape (n_species,n_species,n_cells). This will fill the array with the estimates $(\sigma g w)_{max}$ for all species in all cells, assuming a constant particle computational weight Fnum, a VHS cross-section, and that all species have a single temperature that is constant across all cells.

Positional arguments

  • pia: the ParticleIndexerArray instance
  • interactions: the 2-dimensional array of Interaction instances (of shape (n_species, n_species)) of all the pair-wise interactions
  • species_data: the vector of Species instances of the species in the flow
  • T: the temperatures of the flow
  • Fnum: the constant computational weight of the particles

Keyword arguments

  • mult_factor: a factor by which to multiply the result (default value is 1.0)

Returns

3-dimensional array of CollisionFactors instances with shape (n_species,n_species,n_cells) filled with estimated values of $(\sigma g w)_{max}$.

Merzbild.create_collision_factors_swpm_arrayFunction
create_collision_factors_swpm_array(n_species)

Create a 3-dimensional array of SWPM collision factors for all interaction pairs for a 0-D case (1 spatial cell), with shape (n_species,n_species,1).

Positional arguments

  • n_species: number of species in the flow

Returns

3-dimensional array of CollisionFactorsSWPM instances with shape (n_species,n_species,1).

create_collision_factors_swpm_array(n_species, n_cells)

Create a 3-dimensional array of SWPM collision factors for all interaction pairs for all cells in the simulation, with shape (n_species,n_species,n_cells).

Positional arguments

  • n_species: number of species in the flow
  • n_cells: number of cells in the simulation

Returns

3-dimensional array of CollisionFactorsSWPM instances with shape (n_species,n_species,n_cells).

create_collision_factors_swpm_array(pia)

Create a 3-dimensional array of SWPM collision factors for all interaction pairs for all cells in the simulation, with shape (n_species,n_species,n_cells).

Positional arguments

  • pia: the ParticleIndexerArray instance

Returns

3-dimensional array of CollisionFactorsSWPM instances with shape (n_species,n_species,n_cells).

create_collision_factors_swpm_array(pia, interactions, species_data, T_list; mult_factor=1.0)

Create a 3-dimensional array of SWPM collision factors for all interaction pairs for all cells in the simulation, with shape (n_species,n_species,n_cells). This will fill the array with the estimates $(\sigma g)_{max}$ for all species in all cells, assuming a VHS cross-section, and that the temperature of each species is constant across all cells.

Positional arguments

  • pia: the ParticleIndexerArray instance
  • interactions: the 2-dimensional array of Interaction instances (of shape (n_species, n_species)) of all the pair-wise interactions
  • species_data: the vector of Species instances of the species in the flow
  • T_list: the list of temperatures of the species

Keyword arguments

  • mult_factor: a factor by which to multiply the result (default value is 1.0)

Returns

3-dimensional array of CollisionFactorsSWPM instances with shape (n_species,n_species,n_cells) filled with estimated values of $(\sigma g)_{max}$.

create_collision_factors_swpm_array(pia, interactions, species_data, T::Real; mult_factor=1.0)

Create a 3-dimensional array of SWPM collision factors for all interaction pairs for all cells in the simulation, with shape (n_species,n_species,n_cells). This will fill the array with the estimates $(\sigma g)_{max}$ for all species in all cells, assuming a VHS cross-section, and that all species have a single temperature that is constant across all cells.

Positional arguments

  • pia: the ParticleIndexerArray instance
  • interactions: the 2-dimensional array of Interaction instances (of shape (n_species, n_species)) of all the pair-wise interactions
  • species_data: the vector of Species instances of the species in the flow
  • T: the temperatures of the flow

Keyword arguments

  • mult_factor: a factor by which to multiply the result (default value is 1.0)

Returns

3-dimensional array of CollisionFactorsSWPM instances with shape (n_species,n_species,n_cells) filled with estimated values of $(\sigma g)_{max}$.

Merzbild.create_computed_crosssectionsFunction
create_computed_crosssections(electron_neutral_interactions)

Create a vector of ComputedCrossSections instances for the electron-neutral interactions.

Positional arguments

  • electron_neutral_interactions: the ElectronNeutralInteractions instance for which the cross-sections will be computed

Returns

Vector of ComputedCrossSections of length electron_neutral_interactions.n_neutrals.

Merzbild.estimate_sigma_g_w_maxFunction
estimate_sigma_g_w_max(interaction, species1, species2, T1, T2, Fnum; mult_factor=1.0)

Estimate $(\sigma g w)_{max}$ for a two-species interaction, assuming a constant particle computational weight Fnum and a VHS cross-section. The relative velocity $g$ is estimated as $g = 0.5 (\sqrt{2T_1 k_B / m_1} + \sqrt{2T_2 k_B / m_2})$, where $T_1$ and $m_1$ are the temperature and mass of the first species (species1), and $T_2$ and $m_2$ are the temperature and mass of the second species (species2). This relative velocity estimate is then plugged into the VHS cross-section model to compute $\sigma$. The result is then multiplied by Fnum and an (optional) factor mult_factor. This is also the correct estimate for the VSS model, as it uses the same total cross-section as the VHS model.

Positional arguments

  • interaction: the Interaction instance for the interacting species
  • species1: the Species instance of the first interacting species
  • species2: the Species instance of the second interacting species
  • T1: the temperature of the first interacting species
  • T2: the temperature of the second interacting species
  • Fnum: the constant computational weight of the particles

Keyword arguments

  • mult_factor: a factor by which to multiply the result (default value is 1.0)

Returns

The estimate of $(\sigma g w)_{max}$.

estimate_sigma_g_w_max(interaction, species, T, Fnum; mult_factor=1.0)

Estimate $(\sigma g w)_{max}$ for a single-species interaction, assuming a constant particle computational weight Fnum and a VHS cross-section. Uses the same methodology as the estimate for a two-species interaction.

Positional arguments

  • interaction: the Interaction instance for the interacting species
  • species: the Species instance of the interacting species
  • T: the temperature of the interacting species
  • Fnum: the constant computational weight of the particles

Keyword arguments

  • mult_factor: a factor by which to multiply the result (default value is 1.0)

Returns

  • the estimate of $(\sigma g w)_{max}$
Merzbild.estimate_sigma_g_w_max!Function
estimate_sigma_g_w_max!(collision_factors, interactions, species_data, T_list, Fnum; mult_factor=1.0)

Estimate $(\sigma g w)_{max}$ for all species in all cells, assuming a constant particle computational weight Fnum, a VHS cross-section, and that each species' temperature is constant across all cells. Uses the same methodology as the estimate for a two-species interaction.

Positional arguments

  • collision_factors: 3-dimensional array of CollisionFactors of shape (n_species, n_species, n_cells)
  • interactions: the 2-dimensional array of Interaction instances (of shape (n_species, n_species)) of all the pair-wise interactions
  • species_data: the vector of Species instances of the species in the flow
  • T_list: the list of temperatures of the species
  • Fnum: the constant computational weight of the particles

Keyword arguments

  • mult_factor: a factor by which to multiply the result (default value is 1.0)
estimate_sigma_g_w_max!(collision_factors, interactions, species_data, T_list, Fnum; mult_factor=1.0)

Estimate $(\sigma g w)_{max}$ for all species in all cells, assuming species-specific computational weights Fnum, a VHS cross-section, and that each species' temperature is constant across all cells. Uses the same methodology as the estimate for a two-species interaction.

Positional arguments

  • collision_factors: 3-dimensional array of CollisionFactors of shape (n_species, n_species, n_cells)
  • interactions: the 2-dimensional array of Interaction instances (of shape (n_species, n_species)) of all the pair-wise interactions
  • species_data: the vector of Species instances of the species in the flow
  • T_list: the list of temperatures of the species
  • Fnum: a list of the computational weights of the species

Keyword arguments

  • mult_factor: a factor by which to multiply the result (default value is 1.0)
Merzbild.estimate_sigma_g_w_max_ntc_n_e!Function
estimate_sigma_g_w_max_ntc_n_e!(rng, collision_factors, collision_data, interaction,
                                n_e_interactions, n_e_cs, particles_n, particles_e,
                                pia, cell, species_n, species_e, Δt, V; min_coll=5, n_loops=3)

Estimate $(\sigma g w)_{max}$ for an electron-neutral interaction by stochastically choosing particle pairs multiple times and computing $(\sigma g w)$ for each pair. The number of collisions is computed using the standard variable-weight NTC formula, the value of min_coll is added to this number, and particles are randomly sampled. The whole procedure is repeated n_loops times, so that an increased value $(\sigma g w)_{max}$ can have an impact on the computed number of pairs to select during the next loop iteration.

Positional arguments

  • rng: the random number generator
  • collision_factors: the CollisionFactors for the species in question in the cell
  • collision_data: CollisionData instance used for storing collisional quantities
  • interaction: 2-dimensional array of Interaction instances for all possible species pairs
  • n_e_interactions: the ElectronNeutralInteractions instance
  • n_e_cs: a vector of ComputedCrossSections instances
  • particles_n: ParticleVector of the particles of neutral species
  • particles_e: ParticleVector of the particles of the electron species
  • pia: the ParticleIndexerArray
  • cell: the index of the cell in which collisions are performed
  • species_n: the index of the neutral species
  • species_e: the index of the electron species
  • Δt: timestep
  • V: cell volume

Keyword arguments:

  • min_coll: the minimum number of pairs to test
  • n_loops: the number of loops to perform (in each loop the number of collisions is computed using the estimated value of $(\sigma g w)_{max}$)
  • extend: enum of CSExtend type that sets how out-of-range energy values are treated when computing cross-sections
Merzbild.estimate_sigma_g_max!Function
estimate_sigma_g_max!(collision_factors::Array{CollisionFactorsSWPM}, interactions, species_data, T_list; mult_factor=1.0)

Estimate $(\sigma g)_{max}$ for all species in all cells, assuming a constant particle computational weight Fnum, a VHS cross-section, and that each species' temperature is constant across all cells. Uses the same methodology as the estimate for a two-species interaction.

Positional arguments

  • collision_factors: 3-dimensional array of CollisionFactorsSWPM of shape (n_species, n_species, n_cells)
  • interactions: the 2-dimensional array of Interaction instances (of shape (n_species, n_species)) of all the pair-wise interactions
  • species_data: the vector of Species instances of the species in the flow
  • T_list: the list of temperatures of the species

Keyword arguments

  • mult_factor: a factor by which to multiply the result (default value is 1.0)
Merzbild.ntc!Function
ntc!(rng, collision_factors, collision_data, interaction, particles::ParticleVector{D}, pia,
     cell, species, Δt, V; dw_tol=1e-16) where D

Perform elastic collisions between particles of same species using the NTC algorithm. The elastic scattering model is taken from the Interaction instance of the species pair.

Positional arguments

  • rng: the random number generator
  • collision_factors: the CollisionFactors for the species in question in the cell
  • collision_data: CollisionData instance used for storing collisional quantities
  • interaction: 2-dimensional array of Interaction instances for all possible species pairs
  • particles: ParticleVector of the particles being collided
  • pia: the ParticleIndexerArray
  • cell: the index of the cell in which collisions are performed
  • species: the index of the species for which collisions are performed
  • Δt: timestep
  • V: cell volume

Keyword arguments

  • dw_tol: if weights of particles differ by less than this amount, an equal-weight collision is assumed

and no particle splitting is performed

References

ntc!(rng, model::AbstractScatteringModel, collision_factors, collision_data, interaction,
     particles::ParticleVector{D}, pia, cell, species, Δt, V; dw_tol=1e-16) where D

Perform elastic collisions between particles of same species using the NTC algorithm and the elastic scattering model model, overriding the model stored in the Interaction instance of the species pair.

Positional arguments

  • rng: the random number generator
  • model: the AbstractScatteringModel singleton for the scattering model
  • collision_factors: the CollisionFactors for the species in question in the cell
  • collision_data: CollisionData instance used for storing collisional quantities
  • interaction: 2-dimensional array of Interaction instances for all possible species pairs
  • particles: ParticleVector of the particles being collided
  • pia: the ParticleIndexerArray
  • cell: the index of the cell in which collisions are performed
  • species: the index of the species for which collisions are performed
  • Δt: timestep
  • V: cell volume

Keyword arguments

  • dw_tol: if weights of particles differ by less than this amount, an equal-weight collision is assumed

and no particle splitting is performed

References

ntc!(rng, collision_factors, collision_data, interaction,
     particles_1::ParticleVector{D}, particles_2::ParticleVector{D}, pia,
     cell, species1, species2, Δt, V; dw_tol=1e-16) where D

Perform elastic collisions between particles of different species using the NTC algorithm. The elastic scattering model is taken from the Interaction instance of the species pair.

Positional arguments

  • rng: the random number generator
  • collision_factors: the CollisionFactors for the species in question in the cell
  • collision_data: CollisionData instance used for storing collisional quantities
  • interaction: 2-dimensional array of Interaction instances for all possible species pairs
  • particles_1: ParticleVector of the particles of the first species being collided
  • particles_2: ParticleVector of the particles of the second species being collided
  • pia: the ParticleIndexerArray
  • cell: the index of the cell in which collisions are performed
  • species1: the index of the first species for which collisions are performed
  • species2: the index of the second species for which collisions are performed
  • Δt: timestep
  • V: cell volume

Keyword arguments

  • dw_tol: if weights of particles differ by less than this amount, an equal-weight collision is assumed

and no particle splitting is performed

References

ntc!(rng, model::AbstractScatteringModel, collision_factors, collision_data, interaction,
     particles_1::ParticleVector{D}, particles_2::ParticleVector{D}, pia,
     cell, species1, species2, Δt, V; dw_tol=1e-16) where D

Perform elastic collisions between particles of different species using the NTC algorithm and the elastic scattering model model, overriding the model stored in the Interaction instance of the species pair.

Positional arguments

  • rng: the random number generator
  • model: the AbstractScatteringModel singleton for the scattering model
  • collision_factors: the CollisionFactors for the species in question in the cell
  • collision_data: CollisionData instance used for storing collisional quantities
  • interaction: 2-dimensional array of Interaction instances for all possible species pairs
  • particles_1: ParticleVector of the particles of the first species being collided
  • particles_2: ParticleVector of the particles of the second species being collided
  • pia: the ParticleIndexerArray
  • cell: the index of the cell in which collisions are performed
  • species1: the index of the first species for which collisions are performed
  • species2: the index of the second species for which collisions are performed
  • Δt: timestep
  • V: cell volume

Keyword arguments

  • dw_tol: if weights of particles differ by less than this amount, an equal-weight collision is assumed

and no particle splitting is performed

References

Merzbild.ntc_equal_weight!Function
ntc_equal_weight!(rng, collision_factors, collision_data, interaction, particles::ParticleVector{D}, pia,
                  cell, species, Δt, V) where D

Perform elastic collisions between particles of same species using the NTC algorithm. Particle weights are assumed to be equal, and no weight checks/splitting is performed. The elastic scattering model is taken from the Interaction instance of the species pair.

Positional arguments

  • rng: the random number generator
  • collision_factors: the CollisionFactors for the species in question in the cell
  • collision_data: CollisionData instance used for storing collisional quantities
  • interaction: 2-dimensional array of Interaction instances for all possible species pairs
  • particles: ParticleVector of the particles being collided
  • pia: the ParticleIndexerArray
  • cell: the index of the cell in which collisions are performed
  • species: the index of the species for which collisions are performed
  • Δt: timestep
  • V: cell volume

References

ntc_equal_weight!(rng, model::AbstractScatteringModel, collision_factors, collision_data, interaction,
                  particles::ParticleVector{D}, pia, cell, species, Δt, V) where D

Perform elastic collisions between particles of same species using the NTC algorithm and the elastic scattering model model, overriding the model stored in the Interaction instance of the species pair. Particle weights are assumed to be equal, and no weight checks/splitting is performed.

Positional arguments

  • rng: the random number generator
  • model: the AbstractScatteringModel singleton for the scattering model
  • collision_factors: the CollisionFactors for the species in question in the cell
  • collision_data: CollisionData instance used for storing collisional quantities
  • interaction: 2-dimensional array of Interaction instances for all possible species pairs
  • particles: ParticleVector of the particles being collided
  • pia: the ParticleIndexerArray
  • cell: the index of the cell in which collisions are performed
  • species: the index of the species for which collisions are performed
  • Δt: timestep
  • V: cell volume

References

ntc_equal_weight!(rng, collision_factors, collision_data, interaction,
                  particles_1, particles_2, pia,
                  cell, species1, species2, Δt, V)

Perform elastic collisions between particles of different species using the NTC algorithm. Particle weights are assumed to be equal, and no weight checks/splitting is performed. The elastic scattering model is taken from the Interaction instance of the species pair.

Positional arguments

  • rng: the random number generator
  • collision_factors: the CollisionFactors for the species in question in the cell
  • collision_data: CollisionData instance used for storing collisional quantities
  • interaction: 2-dimensional array of Interaction instances for all possible species pairs
  • particles_1: ParticleVector of the particles of the first species being collided
  • particles_2: ParticleVector of the particles of the second species being collided
  • pia: the ParticleIndexerArray
  • cell: the index of the cell in which collisions are performed
  • species1: the index of the first species for which collisions are performed
  • species2: the index of the second species for which collisions are performed
  • Δt: timestep
  • V: cell volume

References

ntc_equal_weight!(rng, model::AbstractScatteringModel, collision_factors, collision_data, interaction,
                  particles_1, particles_2, pia,
                  cell, species1, species2, Δt, V)

Perform elastic collisions between particles of different species using the NTC algorithm and the elastic scattering model model, overriding the model stored in the Interaction instance of the species pair. Particle weights are assumed to be equal, and no weight checks/splitting is performed.

Positional arguments

  • rng: the random number generator
  • model: the AbstractScatteringModel singleton for the scattering model
  • collision_factors: the CollisionFactors for the species in question in the cell
  • collision_data: CollisionData instance used for storing collisional quantities
  • interaction: 2-dimensional array of Interaction instances for all possible species pairs
  • particles_1: ParticleVector of the particles of the first species being collided
  • particles_2: ParticleVector of the particles of the second species being collided
  • pia: the ParticleIndexerArray
  • cell: the index of the cell in which collisions are performed
  • species1: the index of the first species for which collisions are performed
  • species2: the index of the second species for which collisions are performed
  • Δt: timestep
  • V: cell volume

References

Merzbild.ntc_n_e!Function
ntc_n_e!(rng, collision_factors, collision_data, interaction,
         n_e_interactions, n_e_cs, particles_n, particles_e, particles_ion,
         pia, cell, species_n, species_e, species_ion, Δt, V; extend::CSExtend=CSExtendConstant, dw_tol=1e-16)

Perform electron-neutral elastic scattering and electron-impact ionization collisions.

Positional arguments

  • rng: the random number generator
  • collision_factors: the CollisionFactors for the species in question in the cell
  • collision_data: CollisionData instance used for storing collisional quantities
  • interaction: 2-dimensional array of Interaction instances for all possible species pairs
  • n_e_interactions: the ElectronNeutralInteractions instance
  • n_e_cs: a vector of ComputedCrossSections instances
  • particles_n: ParticleVector of the particles of neutral species
  • particles_e: ParticleVector of the particles of the electron species
  • particles_ion: ParticleVector of the particles of the ion species
  • pia: the ParticleIndexerArray
  • cell: the index of the cell in which collisions are performed
  • species_n: the index of the neutral species
  • species_e: the index of the electron species
  • species_ion: the index of the ion species
  • Δt: timestep
  • V: cell volume

Keyword arguments

  • extend: enum of CSExtend type that sets how out-of-range energy values are treated when computing cross-sections
  • dw_tol: if weights of particles differ by less than this amount, an equal-weight collision is assumed

and no particle splitting is performed

References

Merzbild.ntc_n_e_es!Function
ntc_n_e_es!(rng, collision_factors, collision_data, interaction,
         n_e_interactions, n_e_cs, particles_n, particles_e, particles_ion,
         pia, cell, species_n, species_e, species_ion, Δt, V; extend::CSExtend=CSExtendConstant, dw_tol=1e-16)

Perform electron-neutral elastic scattering and electron-impact ionization collisions using the event splitting method.

Positional arguments

  • rng: the random number generator
  • collision_factors: the CollisionFactors for the species in question in the cell
  • collision_data: CollisionData instance used for storing collisional quantities
  • interaction: 2-dimensional array of Interaction instances for all possible species pairs
  • n_e_interactions: the ElectronNeutralInteractions instance
  • n_e_cs: a vector of ComputedCrossSections instances
  • particles_n: ParticleVector of the particles of neutral species
  • particles_e: ParticleVector of the particles of the electron species
  • particles_ion: ParticleVector of the particles of the ion species
  • pia: the ParticleIndexerArray
  • cell: the index of the cell in which collisions are performed
  • species_n: the index of the neutral species
  • species_e: the index of the electron species
  • species_ion: the index of the ion species
  • Δt: timestep
  • V: cell volume

Keyword arguments

  • extend: enum of CSExtend type that sets how out-of-range energy values are treated when computing cross-sections
  • dw_tol: if weights of particles differ by less than this amount, an equal-weight collision is assumed

and no particle splitting is performed

References

  • G. Oblapenko, D. Goldstein, P. Varghese, C. Moore, Hedging direct simulation Monte Carlo bets via event splitting. J. Comput. Phys, 2022.
  • D.P. Schmidt, C.J. Rutland, A New Droplet Collision Algorithm. J. Comput. Phys, 2000.
Merzbild.swpm!Function
swpm!(rng, collision_factors_swpm, collision_data, interaction, particles::ParticleVector{D}, pia,
      cell, species, G, Δt, V)

Perform elastic collisions between variable-weight particles of same species using the SWPM algorithm. The elastic scattering model is taken from the Interaction instance of the species pair. During a collision of particles with weights $w_i$, $w_j$, the weights are depleted by $\min(w_i, w_j) / (1+G)$, where $G \geq 0$ is a user-defined parameter.

Positional arguments

  • rng: the random number generator
  • collision_factors_swpm: the CollisionFactorsSWPM for the species in question in the cell
  • collision_data: CollisionData instance used for storing collisional quantities
  • interaction: 2-dimensional array of Interaction instances for all possible species pairs
  • particles: ParticleVector of the particles being collided
  • pia: the ParticleIndexerArray
  • cell: the index of the cell in which collisions are performed
  • species: the index of the species for which collisions are performed
  • G: non-negative value defining the weight transfer function
  • Δt: timestep
  • V: cell volume

References

swpm!(rng, model::AbstractScatteringModel, collision_factors_swpm, collision_data, interaction,
      particles::ParticleVector{D}, pia, cell, species, G, Δt, V)

Perform elastic collisions between variable-weight particles of same species using the SWPM algorithm and the elastic scattering model model, overriding the model stored in the Interaction instance of the species pair. During a collision of particles with weights $w_i$, $w_j$, the weights are depleted by $\min(w_i, w_j) / (1+G)$, where $G \geq 0$ is a user-defined parameter.

Positional arguments

  • rng: the random number generator
  • model: the AbstractScatteringModel singleton tag of the scattering model
  • collision_factors_swpm: the CollisionFactorsSWPM for the species in question in the cell
  • collision_data: CollisionData instance used for storing collisional quantities
  • interaction: 2-dimensional array of Interaction instances for all possible species pairs
  • particles: ParticleVector of the particles being collided
  • pia: the ParticleIndexerArray
  • cell: the index of the cell in which collisions are performed
  • species: the index of the species for which collisions are performed
  • G: non-negative value defining the weight transfer function
  • Δt: timestep
  • V: cell volume

References

Fokker-Planck computations

Merzbild.fp_linear!Function
fp_linear!(rng, collision_data_fp, interaction, particles::ParticleVector{D}, pia, cell, species, species_data, Δt, V) where D

Model single-species elastic collisions using a linear Fokker-Planck approximation.

Positional arguments

  • rng: the random number generator
  • collision_data_fp: CollisionDataFP instance used for storing collisional quantities
  • interaction: 2-dimensional array of Interaction instances for all possible species pairs
  • particles: ParticleVector of the particles being collided
  • pia: the ParticleIndexerArray
  • cell: the index of the cell in which collisions are performed
  • species: the index of the species for which collisions are performed
  • species_data: the vector of SpeciesData
  • Δt: timestep
  • V: cell volume

References

  • M.H. Gorji, M. Torrilhon, P. Jenny, Fokker-Planck model for computational studies of monatomic rarefied gas flows. J. Fluid Mech., 2011.

Electron-neutral interactions

Merzbild.ElectronNeutralInteractionsType
ElectronNeutralInteractions

Structure to hold data on electron-neutral interactions. The neutral_indexer field is used to obtain the index of the species inside the structure, given an index of the neutral species in the full list of species in the simulation. For example, if we have a following list of species in the simulation: [e-, He, Ar+, He+, Ar], n_neutrals=2, the ElectronNeutralInteractions instance stores data for interactions of electrons with [He, Ar], and neutral_indexer[2] = 1, neutral_indexer[5] = 2.

Fields

  • n_neutrals: number of neutral species for which the data has been loaded
  • mass_ratios: ratio of electron mass to mass of neutrals; this uses the electron mass as given in the Species instance, so heavy electrons are possible
  • neutral_indexer: array that maps indices of neutral species in the full list of species to local indices in the ElectronNeutralInteractions structure
  • elastic: an array of ElasticScattering instances (of length n_neutrals) holding the cross-section data on elastic scattering for each neutral species
  • ionization: an array of Ionization instances (of length n_neutrals) holding the cross-section data on electron-impact ionization for each neutral species
  • excitation_sink: an array of ExcitationSink instances (of length n_neutrals) holding the cross-section data on electron-impact electronic excitation for each neutral species
Merzbild.ElectronNeutralInteractionsMethod
ElectronNeutralInteractions(species_data, filename, databases, scattering_laws, energy_splits)

Load electron-neutral interaction data from an LXCAT format XML file for a set of given neutral species and instantiate a ElectronNeutralInteractions instance.

Positional arguments

  • species_data: vector of Species data for the neutral species
  • filename: path to XML file
  • databases: dictionary of (species.name => database) pairs, specifying the name

of the cross-section database in the XML file to use for the species

  • scattering_laws: vector of ScatteringLaw instances to use for each species
  • energy_splits: vector of ElectronEnergySplit instances to use for each species

Returns

ElectronNeutralInteractions structure containing the electron-neutral interaction data.

Throws

DataMissingException if data not found or not all required data present.

Merzbild.ComputedCrossSectionsType
ComputedCrossSections

Structure to hold data on computed cross-sections of electron-neutral interactions for a specific neutral species.

Fields

  • n_excitations: number of electron-impact excitation reactions
  • cs_total: the computed total cross-section (sum of cross-sections of all processes)
  • cs_elastic: the computed elastic scattering cross-section
  • cs_ionization: the computed electron-impact ionization cross-section
  • cs_excitation: the computed electron-impact electronic excitation cross-section
  • prob_vec: a vector of probabilities of the processes (of length 2+n_excitations). prob_vec[1] is the probability of elastic scattering, prob_vec[2] is the probability of electron-impact ionization, prob_vec[3:2+n_excitations] are the probabilities of the electron-impact electronic excitation processes
  • cdf_prob_vec: a vector of cumulative probabilities of the processes (of length 2+n_excitations), used for sampling a specific process: cfd_prob_vec[1] = 0.0, cfd_prob_vec[n] = cfd_prob_vec[n-1] + prob_vec[n-1], n>1
Merzbild.ElectronEnergySplitType
ElectronEnergySplit ElectronEnergySplitEqual=1 ElectronEnergySplitZeroE=2

Enum for various splittings of electron energy in electron-impact ionization reactions. ElectronEnergySplitEqual corresponds to energy being shared equally amongst the electrons, ElectronEnergySplitZeroE corresponds to the one-takes-all sharing model.

Merzbild.ScatteringLawType
ScatteringLaw ScatteringIsotropic=1 ScatteringOkhrimovskyy=2

Enum for various scattering laws in electron-neutral interactions. ScatteringIsotropic corresponds to isotropic scattering, ScatteringOkhrimovskyy to the scattering model of A. Okhrimovskyy et al., 2002.

Merzbild.CSExtendType
CSExtend CSExtendConstant=1 CSExtendZero=2

Enum defining how to extend cross-sections in case energy is outside of tabulated range.

Possible values:

  • CSExtendConstant: continue with closest value in array
  • CSExtendZero: continue with zero

Merging

Grid merging

Merzbild.GridN2MergeType
GridN2Merge{D}

Struct for merging particles with D-dimensional position vectors using a grid in velocity space. Particles in each cell are merged down. Particles outside of the grid are merged based on the octant they are in. So for an N:2 merge one would expect at most 2*(Nx*Ny*Nz+8) post-merge particles, where Nx, Ny, Nz are the number of grid cells in each velocity direction. The grid bounds in each direction can be computed using the mean thermal velocity of the particles and the mean streaming velocity: [v0-extent_multiplier*sqrt(2*k_B*T/m),v0+extent_multiplier*sqrt(2*k_B*T/m)]. Here T is the temperature of the species in question, m is the molecular mass, v0 is the mean velocity and extent_multiplier is a user-defined parameter (3.5 is a reasonable choice) defining the extent of the grid.

Fields

  • Nx: number of grid cells in x velocity direction
  • Ny: number of grid cells in y velocity direction
  • Nz: number of grid cells in z velocity direction
  • NyNz: product of Ny and Nz
  • Ntotal: total number of grid cells (equal to Nx*Ny*Nz+8, as we account for the external octants)
  • extent_multiplier: the vector of factors by which to multiply the thermal velocity to determine the grid bounds in each velocity direction
  • extent_v_lower: the lower bounds of the velocity grid in each velocity direction
  • extent_v_upper: the upper bounds of the velocity grid in each velocity direction
  • extent_v_mid: (extent_v_lower + extent_v_upper)/2
  • Δv: the grid cell size in each velocity direction
  • Δv_inv: the inverse grid cell size in each velocity direction
  • direction_vec: used to store randomly sampled direction signs
  • direction_vecD: used to store randomly sampled direction signs of length D
  • cells: vector of GridCell instances for each grid cell, as well as the external octants
Merzbild.GridN2MergeMethod
GridN2Merge{D}(Nx::Int, Ny::Int, Nz::Int, extent_multiplier::T) where {D, T <: AbstractArray}

Create velocity grid-based merging for particles with D-dimensional position vectors.

Positional arguments

  • Nx: number of cells in vx direction
  • Ny: number of cells in vy direction
  • Nz: number of cells in vz direction
  • extent_multiplier: the vector of factors by which to multiply the thermal velocity to determine the grid bounds

in each velocity direction

Merzbild.GridN2MergeMethod
GridN2Merge{D}(N::Int, extent_multiplier::T) where {D, T <: AbstractArray}

Create velocity grid-based merging for particles with D-dimensional position vectors with an equal number of cells in each direction.

Positional arguments

  • N: number of cells in each velocity direction
  • extent_multiplier: the vector of factors by which to multiply the thermal velocity to determine the grid bounds

in each velocity direction

Merzbild.GridN2MergeMethod
GridN2Merge{D}(Nx::Int, Ny::Int, Nz::Int, extent_multiplier::Float64) where D

Create velocity grid-based merging for particles with D-dimensional position vectors with equal extent multipliers in each direction.

Positional arguments

  • Nx: number of cells in vx direction
  • Ny: number of cells in vy direction
  • Nz: number of cells in vz direction
  • extent_multiplier: the factor by which to multiply the thermal velocity to determine the grid bounds

in each velocity direction

Merzbild.GridN2MergeMethod
GridN2Merge{D}(Nx::Int, Ny::Int, Nz::Int,
            extent_multiplier_x::Float64,
            extent_multiplier_y::Float64,
            extent_multiplier_z::Float64) where D

Create velocity grid-based for merging particles with D-dimensional position vectors

Positional arguments

  • Nx: number of cells in vx direction
  • Ny: number of cells in vy direction
  • Nz: number of cells in vz direction
  • extent_multiplier_x: the factor by which to multiply the thermal velocity to determine the grid bounds

in the x-velocity direction

  • extent_multiplier_y: the factor by which to multiply the thermal velocity to determine the grid bounds

in the y-velocity direction

  • extent_multiplier_z: the factor by which to multiply the thermal velocity to determine the grid bounds

in the z-velocity direction

Merzbild.GridN2MergeMethod
GridN2Merge{D}(N::Int, extent_multiplier::Float64) where D

Create velocity grid-based merging for particles with D-dimensional position vectors with an equal number of cells in each direction and equal extent multipliers in each direction.

Positional arguments

  • N: number of cells in each velocity direction
  • extent_multiplier: the factor by which to multiply the thermal velocity to determine the grid bounds

in each velocity direction

Merzbild.GridN2MergeMethod
GridN2Merge(N::Int, extent_multiplier::T) where T <: AbstractArray

Create velocity grid-based merging for particles with 3-dimensional position vectors with an equal number of cells in each direction.

Positional arguments

  • N: number of cells in each velocity direction
  • extent_multiplier: the vector of factors by which to multiply the thermal velocity to determine the grid bounds

in each velocity direction

Merzbild.GridN2MergeMethod
GridN2Merge(Nx::Int, Ny::Int, Nz::Int, extent_multiplier::Float64)

Create velocity grid-based merging for particles with 3-dimensional position vectors with equal extent multipliers in each direction.

Positional arguments

  • Nx: number of cells in vx direction
  • Ny: number of cells in vy direction
  • Nz: number of cells in vz direction
  • extent_multiplier: the factor by which to multiply the thermal velocity to determine the grid bounds

in each velocity direction

Merzbild.GridN2MergeMethod
GridN2Merge(Nx::Int, Ny::Int, Nz::Int,
            extent_multiplier_x::Float64,
            extent_multiplier_y::Float64,
            extent_multiplier_z::Float64)

Create velocity grid-based merging for particles with 3-dimensional position vectors.

Positional arguments

  • Nx: number of cells in vx direction
  • Ny: number of cells in vy direction
  • Nz: number of cells in vz direction
  • extent_multiplier_x: the factor by which to multiply the thermal velocity to determine the grid bounds

in the x-velocity direction

  • extent_multiplier_y: the factor by which to multiply the thermal velocity to determine the grid bounds

in the y-velocity direction

  • extent_multiplier_z: the factor by which to multiply the thermal velocity to determine the grid bounds

in the z-velocity direction

Merzbild.merge_grid_based!Function
merge_grid_based!(rng, merging_grid::GridN2Merge{D}, particles::ParticleVector{D}, pia, cell, species, species_data, phys_props::PhysProps) where D

Merge particles using a velocity grid-based merging approach. A Cartesian grid in velocity space is used to group particles together (particles outside of the grid are group by velocity octant), and in each cell/octant, particles are merged down to 2 particles. The extent of the grid is based on the temperature for the species in question in the physical grid cell being considered, as stored in the phys_props parameter.

Positional arguments:

  • rng: the random number generator instance
  • merging_grid: the grid merging (GridN2Merge) instance defining the velocity space grid
  • particles: the ParticleVector instance of the particles to be merged
  • pia: the ParticleIndexerArray instance
  • cell: the cell index
  • species: the species index
  • species_data: the array of Species data
  • phys_props: the PhysProps instance containing the computed temperature

References

  • M. Vranic, T. Grismayer, J.L. Martins, R.A. Fonseca, L.O. Silva, Particle merging algorithm for PIC codes. Comput. Phys. Comm., 2015.
  • G. Oblapenko, D. Goldstein, P. Varghese, C. Moore, A velocity space hybridization-based Boltzmann equation solver. J. Comput. Phys, 2020.
merge_grid_based!(rng, merging_grid::GridN2Merge{D}, particles::ParticleVector{D}, pia, cell, species, species_data, vx_extent, vy_extent, vz_extent)

Merge particles using a velocity grid-based merging approach. A Cartesian grid in velocity space is used to group particles together (particles outside of the grid are group by velocity octant), and in each cell/octant, particles are merged down to 2 particles. The extent of the grid is specified explicitly.

Positional arguments:

  • rng: the random number generator instance
  • merging_grid: the grid merging (GridN2Merge) instance defining the velocity space grid
  • particles: the ParticleVector instance of the particles to be merged
  • pia: the ParticleIndexerArray instance
  • cell: the cell index
  • species: the species index
  • species_data: the array of Species data
  • vx_extent: lower and upper bounds of the grid extent in the x velocity direction
  • vy_extent: lower and upper bounds of the grid extent in the y velocity direction
  • vz_extent: lower and upper bounds of the grid extent in the z velocity direction

References

  • M. Vranic, T. Grismayer, J.L. Martins, R.A. Fonseca, L.O. Silva, Particle merging algorithm for PIC codes. Comput. Phys. Comm., 2015.
  • G. Oblapenko, D. Goldstein, P. Varghese, C. Moore, A velocity space hybridization-based Boltzmann equation solver. J. Comput. Phys, 2020.
merge_grid_based!(rng, merging_grid::GridN2Merge{D}, particles::ParticleVector{D}, pia, cell, species, species_data, phys_props::PhysProps, grid::Grid1DUniform) where D

Merge particles using a velocity grid-based merging approach. A Cartesian grid in velocity space is used to group particles together (particles outside of the grid are group by velocity octant), and in each cell/octant, particles are merged down to 2 particles. The extent of the grid is based on the temperature for the species in question in the physical grid cell being considered, as stored in the phys_props parameter. If particle positions end up outside of the simulation domain, the particles are placed back into the domain.

Positional arguments:

  • rng: the random number generator instance
  • merging_grid: the grid merging (GridN2Merge) instance defining the velocity space grid
  • particles: the ParticleVector instance of the particles to be merged
  • pia: the ParticleIndexerArray instance
  • cell: the cell index
  • species: the species index
  • species_data: the array of Species data
  • phys_props: the PhysProps instance containing the computed temperature
  • grid: the Grid1DUniform grid

References

  • M. Vranic, T. Grismayer, J.L. Martins, R.A. Fonseca, L.O. Silva, Particle merging algorithm for PIC codes. Comput. Phys. Comm., 2015.
  • G. Oblapenko, D. Goldstein, P. Varghese, C. Moore, A velocity space hybridization-based Boltzmann equation solver. J. Comput. Phys, 2020.
merge_grid_based!(rng, merging_grid::GridN2Merge{D}, particles::ParticleVector{D}, pia, cell, species, species_data, vx_extent, vy_extent, vz_extent, grid::Grid1DUniform) where D

Merge particles using a velocity grid-based merging approach. A Cartesian grid in velocity space is used to group particles together (particles outside of the grid are group by velocity octant), and in each cell/octant, particles are merged down to 2 particles. The extent of the grid is specified explicitly. If particle positions end up outside of the simulation domain, the particles are placed back into the domain.

Positional arguments:

  • rng: the random number generator instance
  • merging_grid: the grid merging (GridN2Merge) instance defining the velocity space grid
  • particles: the ParticleVector instance of the particles to be merged
  • pia: the ParticleIndexerArray instance
  • cell: the cell index
  • species: the species index
  • species_data: the array of Species data
  • vx_extent: lower and upper bounds of the grid extent in the x velocity direction
  • vy_extent: lower and upper bounds of the grid extent in the y velocity direction
  • vz_extent: lower and upper bounds of the grid extent in the z velocity direction
  • grid: the Grid1DUniform grid

References

  • M. Vranic, T. Grismayer, J.L. Martins, R.A. Fonseca, L.O. Silva, Particle merging algorithm for PIC codes. Comput. Phys. Comm., 2015.
  • G. Oblapenko, D. Goldstein, P. Varghese, C. Moore, A velocity space hybridization-based Boltzmann equation solver. J. Comput. Phys, 2020.
Merzbild.GridN2MergeMethod
GridN2Merge(N::Int, extent_multiplier::Float64)

Create velocity grid-based merging for particles with 3-dimensional position vectors with an equal number of cells in each direction and equal extenr multipliers in each direction.

Positional arguments

  • N: number of cells in each velocity direction
  • extent_multiplier: the factor by which to multiply the thermal velocity to determine the grid bounds

in each velocity direction

NNLS merging

Merzbild.NNLSMergeType
NNLSMerge{D}

Struct for keeping track of merging-related quantities for NNLS-based merging of particles with D-dimensional position vectors.

Fields

  • v0: vector of the mean velocity of the particles
  • x0: D-dimensional vector of the mean position of the particles
  • vref: reference velocity magnitude for scaling
  • inv_vref: inverse of reference velocity magnitude for scaling
  • Ev: vector of standard deviation of velocities of particles
  • Ex: vector of standard deviation of positions of particles
  • w_total: total computational of the particles
  • scalev: vector of values used to scale the velocity of particles
  • scalex: vector of values used to scale the positions of particles
  • n_total_conserved: total number of moments conserved
  • n_moments_vel: number of velocity moments to preserve
  • rhs_vector: vector of computed moments
  • row_scale: scratch vector of the row-wise scaling factors applied to the LHS matrix
  • mim: vector of 3-tuples of multi-indices for the velocity moments to preserve
  • tot_order: vector of total orders of the velocity moments to preserve
  • vel_powers: scratch table of powers of the centered velocity components of a particle
  • n_moments_pos: number of spatial moments to preserve
  • mim_pos: vector of 3-tuples of multi-indices for the spatial moments to preserve
  • tot_order_pos: vector of total orders of the spatial moments to preserve
  • pos_powers: scratch table of powers of the centered position components of a particle
  • pos_i_x: index of the spatial moment corresponding to preservation of the center of mass in the x direction
  • pos_i_y: index of the spatial moment corresponding to preservation of the center of mass in the y direction
  • pos_i_z: index of the spatial moment corresponding to preservation of the center of mass in the z direction
  • lhs_matrix_ncols_start: the number of columns in the first pre-allocated matrix
  • lhs_matrix_ncols_end: the number of columns in the last pre-allocated matrix
  • column_norms: vector of vectors of the column-wise inverse norms of the LHS matrices
  • vel_pos_matrices: vector of matrices of size (3+D)xNp that store the velocities and positions of the particles
  • column_norms_scratch: column-wise inverse norms used when the number of columns is outside the pre-allocated range
  • vel_pos_matrix_scratch: velocities and positions used when the number of columns is outside the pre-allocated range
  • work: Vector of NNLSWorkspace instances
Merzbild.NNLSMergeMethod
NNLSMerge{D}(multi_index_moments, init_np; rate_preserving=false, multi_index_moments_pos=[], matrix_ncol_nprealloc=0) where D

Create NNLS-based merging. Mass, momentum, directional energy are always conserved: if not in the list multi_index_moments of moments to preserve, the corresponding moment multi-indices will be added automatically. These indices are (0,0,0) for mass, (1,0,0), (0,1,0), (0,0,1) for momentum, and (2,0,0), (0,2,0), (0,0,2) for directional energies. Spatial moments can be preserved by setting multi_index_moments_pos. If multi_index_moments_pos is non-empty, it is currently left to the user to include any relevant 1st order moments (corresponding center of mass conservation) i.e. (1, 0, 0), (0, 1, 0), (0, 0, 1); otherwise the corresponding spatial moments including higher-order ones will not be conserved. By default, a single NNLSWorkspace is pre-allocated for the system. The number of columns in the LHS matrix is the number of particles to be merged (+ any fictitious particles); so it cannot be fixed in advance. By setting matrix_ncol_nprealloc to a value larger than 0, one can pre-allocate a range of workspaces with a fixed number of columns spanning [init_np, init_np+matrix_ncol_nprealloc]. In this case, matrix_ncol_nprealloc+2 NNLSWorkspace instances are pre-allocated, with the last one being used in case the number of columns is not in the range (its LHS matrix is then re-allocated on the fly, but only when the number of columns differs from the previous call). Vectors column_norms and vel_pos_matrices are also then pre-allocated, holding respectively the inverses of the column-wise norms of the LHS matrices used for their scaling, and the particle velocities and positions. Outside the pre-allocated range the column_norms_scratch / vel_pos_matrix_scratch buffers are used instead; these grow as needed and are re-used across calls.

Positional arguments

  • multi_index_moments: vector of mixed moments to preserve of the form [(i1, j1, k1), (i2, j2, k2), ...]`
  • init_np: assumption on pre-merge number of particles to pre-allocate memory for

Keyword arguments:

  • rate_preserving: used for rate-preserving merging of electrons, preserves approximate elastic collision and ionization rates
  • multi_index_moments_pos: list of spatial moments to preserve
  • matrix_ncol_nprealloc: number of NNLS workspaces with a fixed number of columns to pre-allocate

Throws

  • ArgumentError: if any of moment powers is negative
Merzbild.NNLSMergeMethod
NNLSMerge(multi_index_moments, init_np; rate_preserving=false, multi_index_moments_pos=[], matrix_ncol_nprealloc=0)

Create NNLS-based merging for particles with a 3-dimensional position vector. Mass, momentum, directional energy are always conserved: if not in the list multi_index_moments of moments to preserve, the corresponding moment multi-indices will be added automatically. These indices are (0,0,0) for mass, (1,0,0), (0,1,0), (0,0,1) for momentum, and (2,0,0), (0,2,0), (0,0,2) for directional energies. Spatial moments can be preserved by setting multi_index_moments_pos. If multi_index_moments_pos is non-empty, it is currently left to the user to include any relevant 1st order moments (corresponding center of mass conservation) i.e. (1, 0, 0), (0, 1, 0), (0, 0, 1); otherwise the corresponding spatial moments including higher-order ones will not be conserved. By default, a single NNLSWorkspace is pre-allocated for the system. The number of columns in the LHS matrix is the number of particles to be merged (+ any fictitious particles); so it cannot be fixed in advance. By setting matrix_ncol_nprealloc to a value larger than 0, one can pre-allocate a range of workspaces with a fixed number of columns spanning [init_np, init_np+matrix_ncol_nprealloc]. In this case, matrix_ncol_nprealloc+2 NNLSWorkspace instances are pre-allocated, with the last one being used in case the number of columns is not in the range (its LHS matrix is then re-allocated on the fly, but only when the number of columns differs from the previous call). Vectors column_norms and vel_pos_matrices are also then pre-allocated, holding respectively the inverses of the column-wise norms of the LHS matrices used for their scaling, and the particle velocities and positions. Outside the pre-allocated range the column_norms_scratch / vel_pos_matrix_scratch buffers are used instead; these grow as needed and are re-used across calls.

Positional arguments

  • multi_index_moments: vector of mixed moments to preserve of the form [(i1, j1, k1), (i2, j2, k2), ...]`
  • init_np: assumption on pre-merge number of particles to pre-allocate memory for

Keyword arguments:

  • rate_preserving: used for rate-preserving merging of electrons, preserves approximate elastic collision and ionization rates
  • multi_index_moments_pos: list of spatial moments to preserve
  • matrix_ncol_nprealloc: number of NNLS workspaces with a fixed number of columns to pre-allocate

Throws

  • ArgumentError: if any of moment powers is negative
Merzbild.compute_multi_index_momentsFunction
compute_multi_index_moments(n)

Compute all mixed moment multi-indices of total order up to n, i.e. all 3-tuples (i,j,k)such thati+j+k <= n`.

Positional arguments

  • n: maximum total order

Returns

Vector of 3-tuples of moment multi-indices.

Merzbild.merge_nnls_based!Function
merge_nnls_based!(rng, nnls_merging::NNLSMerge{D}, particles::ParticleVector{D}, pia, cell, species;
                  vref=1.0, scaling=:variance,
                  max_err=1e-11, iteration_mult=2, w_threshold=0.0) where D

Perform NNLS-based merging. The NNLS system is scaled to improve numerical stability, the scaling algorithm is set by the scaling parameter. Even if scaling is done using the computed variances, vref might be used in case those variances are small.

Positional arguments

  • rng: the random number generator instance
  • nnls_merging: the NNLSMerge instance
  • particles: the ParticleVector instance containing the particles to be merged
  • pia: the ParticleIndexerArray instance
  • cell: the index of the grid cell in which particles are being merged
  • species: the index of the species being merged

Keyword arguments

  • vref: the reference velocity used to scale the velocities
  • scaling: how to scale entries in the LHS and RHS of the NNLS system - either based on the reference velocity vref (scaling=:vref) or on the computed variances in each direction (scaling=:variance)
  • max_err: maximum allowed value of the residual of the NNLS system
  • iteration_mult: the number by which the number of columns of the NNLS system matrix is multiplied, this gives the maximum number of iterations of the NNLS algorithm
  • w_threshold: any particles with a relative weight smaller than this value will be discarded (and the weight of the remaining particles re-scaled)

Returns

If the residual exceeds max_err or the number of non-zero (or smaller than w_threshold) elements in the solution vector is equal to the original number of particles, -1 is returned to signify a failure of the merging algorithm.

References

  • G. Oblapenko, M. Torrilhon, Moment-preserving particle merging via non-negative least squares. arXiv preprint, 2026.
Merzbild.merge_nnls_based_rate_preserving!Function
merge_nnls_based_rate_preserving!(rng, nnls_merging::NNLSMerge{D},
                                  interaction, electron_neutral_interactions, computed_cs,
                                  particles::ParticleVector{D}, pia, cell, species, neutral_species_index,
                                  ref_cs_elastic, ref_cs_ion; scaling=:variance,
                                  vref=1.0,  max_err=1e-11,
                                  iteration_mult=2,
                                  extend::CSExtend=CSExtendConstant) where D

Perform NNLS-based merging of electrons that conserves approximate elastic scattering and electron-impact ionization rates. The NNLS system is scaled to improve numerical stability, the scaling algorithm is set by the scaling parameter. Even if scaling is done using the computed variances, vref might be used in case those variances are small.

The reference velocity is also used in conjunction with the reference cross-sections to scale the parts of the NNLS matrix and RHS corresponding to conservation of electron-neutral collision rates. The reference rate is computed as $\sigma_{r,ref} v_{ref}$, where $\sigma_{r,ref}$ is the reference process cross-section. In case scaling==:variance, the reference velocity for the computation of reference rates is computed as $v_{ref} = \sqrt{E_x^2 + E_y^2 + E_z^2}$, where $E_x$, $E_y$, $E_z$ are the variances of the velocity in the corresponding directions.

Positional arguments

  • rng: the random number generator instance
  • nnls_merging: the NNLSMerge instance
  • interaction: the Interaction instance describing the electron-neutral interaction being considered
  • electron_neutral_interactions: the ElectronNeutralInteractions instance storing the tabulated cross-section data used to compute the rates
  • computed_cs: the vector of ComputedCrossSection instances in which the computed values will be stored
  • particles: the ParticleVector instance containing the particles to be merged
  • pia: the ParticleIndexerArray instance
  • cell: the index of the grid cell in which particles are being merged
  • species: the index of the species being merged
  • neutral_species_index: the index of the neutral species which is the collision partner in the electron-neutral collisions for which approximate rates are being preserved.
  • ref_cs_elastic: the reference elastic scattering cross-section used to scale the rates
  • ref_cs_ion: the reference electron-impact ionization cross-section used to scale the rates

Keyword arguments

  • vref: the reference velocity used to scale the velocities in the case of scaling=:vref
  • scaling: how to scale entries in the LHS and RHS of the NNLS system - either based on the reference velocity vref (scaling=:vref) or on the computed variances in each direction (scaling=:variance)
  • max_err: maximum allowed value of the residual of the NNLS system
  • iteration_mult: the number by which the number of columns of the NNLS system matrix is multiplied, this gives the maximum number of iterations of the NNLS algorithm
  • w_threshold: any particles with a relative weight smaller than this value will be discarded (and the weight of the remaining particles re-scaled)
  • extend: enum of CSExtend type that sets how out-of-range energy values are treated when computing cross-sections

Returns

If the residual exceeds max_err or the number of non-zero (or smaller than w_threshold) elements in the solution vector is equal to the original number of particles, -1 is returned to signify a failure of the merging algorithm.

References

  • G. Oblapenko, M. Torrilhon, Moment-preserving particle merging via non-negative least squares. arXiv preprint, 2026.
merge_nnls_based_rate_preserving!(rng, nnls_merging::NNLSMerge{D},
                                  interaction, electron_neutral_interactions, computed_cs,
                                  particles::ParticleVector{D}, particles_neutral::ParticleVector{D}, pia, cell, species, neutral_species_index,
                                  ref_cs_elastic, ref_cs_ion; vref=1.0, scaling=:variance,
                                  max_err=1e-11,
                                  iteration_mult=2, w_threshold=0.0,
                                  extend::CSExtend=CSExtendConstant) where D

Perform NNLS-based merging of electrons that conserves exact elastic scattering and electron-impact ionization rates for one specific neutral species. The NNLS system is scaled to improve numerical stability, the scaling algorithm is set by the scaling parameter. Even if scaling is done using the computed variances, vref might be used in case those variances are small.

The reference velocity is also used in conjunction with the reference cross-sections to scale the parts of the NNLS matrix and RHS corresponding to conservation of electron-neutral collision rates. The reference rate is computed as $\sigma_{r,ref} v_{ref}$, where $\sigma_{r,ref}$ is the reference process cross-section. In case scaling==:variance, the reference velocity for the computation of reference rates is computed as $v_{ref} = \sqrt{E_x^2 + E_y^2 + E_z^2}$, where $E_x$, $E_y$, $E_z$ are the variances of the velocity in the corresponding directions.

Positional arguments

  • rng: the random number generator instance
  • nnls_merging: the NNLSMerge instance
  • interaction: the Interaction instance describing the electron-neutral interaction being considered
  • electron_neutral_interactions: the ElectronNeutralInteractions instance storing the tabulated cross-section data used to compute the rates
  • computed_cs: the vector of ComputedCrossSection instances in which the computed values will be stored
  • particles: the ParticleVector instance containing the particles to be merged
  • particles_neutral: the ParticleVector instance containing the neutral collision partner particles (they are not affected by the merge)
  • pia: the ParticleIndexerArray instance
  • cell: the index of the grid cell in which particles are being merged
  • species: the index of the species being merged
  • neutral_species_index: the index of the neutral species which is the collision partner in the electron-neutral collisions for which approximate rates are being preserved.
  • ref_cs_elastic: the reference elastic scattering cross-section used to scale the rates
  • ref_cs_ion: the reference electron-impact ionization cross-section used to scale the rates

Keyword arguments

  • vref: the reference velocity used to scale the velocities in the case of scaling=:vref
  • scaling: how to scale entries in the LHS and RHS of the NNLS system - either based on the reference velocity vref (scaling=:vref) or on the computed variances in each direction (scaling=:variance)
  • max_err: maximum allowed value of the residual of the NNLS system
  • iteration_mult: the number by which the number of columns of the NNLS system matrix is multiplied, this gives the maximum number of iterations of the NNLS algorithm
  • w_threshold: any particles with a relative weight smaller than this value will be discarded (and the weight of the remaining particles re-scaled)
  • extend: enum of CSExtend type that sets how out-of-range energy values are treated when computing cross-sections

Returns

If the residual exceeds max_err or the number of non-zero (or smaller than w_threshold) elements in the solution vector is equal to the original number of particles, -1 is returned to signify a failure of the merging algorithm.

References

  • G. Oblapenko, M. Torrilhon, Moment-preserving particle merging via non-negative least squares. arXiv preprint, 2026.

Octree merging

Merzbild.OctreeBinSplitType
OctreeBinSplit OctreeBinMidSplit=1 OctreeBinMeanSplit=2 OctreeBinMedianSplit=3

Enum defining how the velocity along which the bin is split is chosen.

Possible values:

  • OctreeBinMidSplit: the bin is split along the middle velocity
  • OctreeBinMeanSplit: the bin is split along the mean velocity of the particles in the bin
  • OctreeBinMedianSplit: the bin is split along the median velocity of the particles in the bin
Merzbild.OctreeInitBinType
OctreeInitBin OctreeInitBinMinMaxVel=1 OctreeInitBinMinMaxVelSym=2 OctreeInitBinC=3

Enum defining how the bounds of the initial bin are computed.

Possible values:

  • OctreeInitBinMinMaxVel: the minimum and maximum velocities of the particles being merged are used to compute the bounds
  • OctreeInitBinMinMaxVelSym: the minimum and maximum velocities of the particles being merged are used to compute the bounds, but the bounds are then symmetrized in each velocity direction: [-max(abs(min_v), abs(max_v)), max(abs(min_v), abs(max_v))]
  • OctreeInitBinC: the initial bounds are set to [-c, c]in each direction, wherec`` speed of light
Merzbild.OctreeBinBoundsType
OctreeBinBounds OctreeBinBoundsInherit=1 OctreeBinBoundsRecompute=2

Enum defining how the bounds of a split sub-octant bin are computed.

Possible values:

  • OctreeBinBoundsInherit: the splitting velocity and the appropriate bounds of the parent bin are inherited
  • OctreeBinBoundsRecompute: the bounds are recomputed based on the particles in the bin
Merzbild.OctreeMergeType
OctreeMerge{D,M}

Struct for N:M Octree merging for particles with D-dimensional position vectors.

Fields

  • max_Nbins: maximum possible number of bins
  • Nbins: number of bins currently used
  • bins: Vector of OctreeCell instances used to compute the properties required for bin refinement
  • full_bins: Vector of OctreeFullCell{D,M} instances used to compute the post-merge particles in each bin
  • n_particles: total number of particles being merged
  • bin_start: denotes start of indices of particles in bin i in the particle_indexes_sorted array
  • bin_end: denotes end of indices of particles in bin i in the particle_indexes_sorted array
  • particle_indexes_sorted: Vector of particle indices of the particles being merged
  • particle_octants: Vector of particle octants for each particle used during radix sort
  • particles_sort_output: Vector of integer indices used to store particle indices during radix sort
  • particle_in_bin_counter: MVector of size 8, stores the number of particles in each bin
  • nonempty_counter: MVector of size 8, stores the number of particles in each non-empty bin (the octants to which these bins correspond to are in nonempty_bins)
  • nonempty_bins: MVector of size 8, a sequential list of non-empty octants
  • ndens_counter: MVector of size 8, used in bin splitting, stores number density in each (non-empty) bin
  • bin_bounds_compute: enum of OctreeBinBounds type defining whether bin bounds are fully defined by the parent bin and splitting velocity (vel_middle), or whether they are recomputed for each new sub-octant bin
  • split: enum of OctreeBinSplit type defining how bins are split
  • vel_middle: used to store the velocity along which a bin is split into octants
  • v_min_parent: used in bin splitting to store the vector of the per-component lower bounds of the velocities in the cell
  • v_max_parent: used in bin splitting to store the vector of the per-component upper bounds of the velocities in the cell
  • direction_vec3: used to store randomly sampled direction signs, of length 3
  • direction_vecD: used to store randomly sampled direction signs, of length D
  • init_bin_bounds: enum of OctreeInitBin type defining how the bounds of the top-level bin are set
  • max_depth: maximum allowed depth of a bin
  • total_post_merge_np: used to keep track of number of post-merge particles
  • v_mean: used to store mean velocity for conservative N:1 merging
  • x_mean: used to store mean position for conservative N:1 merging
  • v_var_before: used to store pre-merge variance of velocity for conservative N:1 merging
  • x_var_before: used to store pre-merge variance of position for conservative N:1 merging
  • v_mean_post: used to store post-merge mean velocity for conservative N:1 merging
  • x_mean_post: used to store post-merge mean position for conservative N:1 merging
  • v_var_post: used to store post-merge variance of velocity for conservative N:1 merging
  • x_var_post: used to store post-merge variance of position for conservative N:1 merging
Merzbild.OctreeMergeMethod
OctreeMerge{D,M}(split::OctreeBinSplit; init_bin_bounds=OctreeInitBinMinMaxVel, bin_bounds_compute=OctreeBinBoundsInherit,
          max_Nbins=4096, max_depth=10)

Create an Octree N:M merging instance for particles with D-dimensional position vectors.

Positional arguments:

  • split: a enum of OctreeBinSplit type which tells how to split a bin into sub-bins

Keyword arguments:

  • init_bin_bounds: a enum of OctreeInitBin type which defines how the bounds of the top-level bin are set
  • bin_bounds_compute: a enum of OctreeBinBounds type which defines whether the bounds of sub-bins are recomputed based on the minimum/maximum velocities of the particles in those sub-bins, or the bounds are inherited from the bin that was split
  • max_Nbins: maximum number of bins allowed (this only counts leaf-level bins)
  • max_depth: maximum depth of a sub-bin starting from the top-level bin containing all particles (which has a depth of 0)

Returns: OctreeMerge instance with everything set to 0.

Merzbild.OctreeMergeMethod
OctreeMerge(split::OctreeBinSplit; init_bin_bounds=OctreeInitBinMinMaxVel, bin_bounds_compute=OctreeBinBoundsInherit,
          max_Nbins=4096, max_depth=10)

Create an Octree N:2 merging instance for particles with 3-dimensional position vectors.

Positional arguments:

  • split: a enum of OctreeBinSplit type which tells how to split a bin into sub-bins

Keyword arguments:

  • init_bin_bounds: a enum of OctreeInitBin type which defines how the bounds of the top-level bin are set
  • bin_bounds_compute: a enum of OctreeBinBounds type which defines whether the bounds of sub-bins are recomputed based on the minimum/maximum velocities of the particles in those sub-bins, or the bounds are inherited from the bin that was split
  • max_Nbins: maximum number of bins allowed (this only counts leaf-level bins)
  • max_depth: maximum depth of a sub-bin starting from the top-level bin containing all particles (which has a depth of 0)

Returns: OctreeMerge instance with everything set to 0.

Merzbild.merge_octree!Function
merge_octree!(rng, octree::OctreeMerge{D,M}, particles::ParticleVector{D}, pia, cell, species, target_np) where {D,M}

Perform octree N:M merging without checking whether particle positions end up outside of the simulation domain.

Positional arguments

  • rng: the random number generator instance
  • octree: the OctreeMerge instance
  • particles: the ParticleVector instance containing the particles to be merged
  • pia: the ParticleIndexerArray instance
  • cell: the index of the grid cell in which particles are being merged
  • species: the index of the species being merged
  • target_np: the target post-merge number of particles; the post-merge number of particles will not exceed this value but may be not exactly equal to it

References

merge_octree!(rng, octree::OctreeMerge{D,M}, particles::ParticleVector{D}, pia, cell, species, target_np, grid::Grid1DUniform) where {D,M}

Perform octree N:M merging, checking whether particle positions end up outside of the simulation domain, and placing them back into the domain if needed.

Positional arguments

  • rng: the random number generator instance

  • octree: the OctreeMerge instance

  • particles: the ParticleVector instance containing the particles to be merged

  • pia: the ParticleIndexerArray instance

  • cell: the index of the grid cell in which particles are being merged

  • species: the index of the species being merged

  • target_np: the target post-merge number of particles; the post-merge number of particles will not exceed this value but may be not exactly equal to it

  • grid: the Grid1DUniform grid

  • R.S. Martin, J.-L. Cambier, Octree particle management for DSMC and PIC simulations. J. Comput. Phys., 2016.

Roulette merging

Merzbild.merge_roulette!Function
merge_roulette!(rng, particles::ParticleVector{D}, pia, cell, species, target_np) where D

Perform roulette merging - delete random particles until target number of particles is reached, and re-weight remaining particles to conserve number density.

Positional arguments

  • rng: the random number generator instance
  • particles: the ParticleVector instance containing the particles to be merged
  • pia: the ParticleIndexerArray instance
  • cell: the index of the grid cell in which particles are being merged
  • species: the index of the species being merged
  • target_np: the target post-merge number of particles

Keyword arguments

  • conservative: if true, the post-merge particles' velocities will be corrected to ensure conservation of momentum and energy

References

  • J. Watrous, D.B. Seidel, C.H. Moore, W. McDoniel, Improvements to Particle Merge Algorithms for Sandia National Laboratories Plasma Physics Modeling Code, EMPIRE. Presentation, 2023.

Grids and particle sorting

Merzbild.Grid1DUniformType
Grid1DUniform

1-D Uniform grid for a domain $[0,L]$

Fields

  • L: length of the domain
  • n_cells: number of cells
  • Δx: cell size
  • inv_Δx: inverse of cell size
  • cells: Vector of Cell1D elements
  • min_x: minimum allowed x coordinate for particles (slightly larger than $0$)
  • max_x: maximum allowed x coordinate for particles (slightly smaller than $L$)
  • surface_normals: vector of surface normals (1st element corresponds to the left wall, 2nd to the right wall)
Merzbild.Grid1DUniformMethod
Grid1DUniform(L, nx; wall_offset=1e-12)

Create 1-D uniform grid for a domain $[0, L]$ with nx cells

Positional arguments

  • L: length of the domain
  • nx: number of cells

Keyword arguments

  • wall_offset: specifies a small relative offset from the walls so that particles never end up with a coordinate of exactly $0$ or $L$, otherwise some sorting routines may produce cell indices outside of the 1:nx range. The offset is computed as Δx * wall_offset, where Δx is the cell size.
Merzbild.GridSortInPlaceType
GridSortInPlace

Struct for in-place sorting of particles.

The occ_lo/occ_hi fields record the first and last cell holding particles, as recorded by the most recent sorting call performed with this instance, to be used for multi-threaded simulations with particle exchange between threads. They describe that call only, and are meant to be consumed right after it, by update_occupancy_bounds!; a GridSortInPlace shared between species or ParticleIndexerArray instances therefore holds the bounds of whichever was sorted last. They are 1/n_cells before the first sort.

Fields

  • cell_counts: scratch vector used to count the number of particles in each cell and to compute the resulting offsets
  • sorted_indices: vector to store sorted particle indices
  • occ_lo: first cell holding particles during the last sort
  • occ_hi: last cell holding particles during the last sort
Merzbild.GridSortInPlaceMethod
GridSortInPlace(n_cells::Integer, n_particles::Integer)

Create a GridSortInPlace instance given a number of grid cells and number of particles.

Positional arguments

  • n_cells: the number of grid cells
  • n_particles: the (expected) number of particles in the simulation (to pre-allocate the sorted_indices vector) - it is recommended to set this to the maximum expected number of particles in the simulation to avoid resizing of arrays during a simulation
Merzbild.GridSortInPlaceMethod
GridSortInPlace(grid::G, n_particles::Integer) where {G<:AbstractGrid}

Create a GridSortInPlace instance given a grid and number of particles.

Positional arguments

  • grid: the grid on which to sort the particles
  • n_particles: the (expected) number of particles in the simulation (to pre-allocate the sorted_indices vector) - it is recommended to set this to the maximum expected number of particles in the simulation to avoid resizing of arrays during a simulation
Merzbild.sort_particles!Function
sort_particles!(gridsort::GridSortInPlace, grid, particles::ParticleVector{D}, pia, species) where D

Sort particles on a grid using an in-place sorting algorithm. The pia instance is allowed to have non-contiguous indices (arising for example from merging). This function assumes that at the start of the sorting, it is not known in which cell each particle is located, and therefore the cell for each particle has to be determined (by calling get_cell).

The first and last cell holding particles are recorded in the GridSortInPlace instance, for use in update_occupancy_bounds!.

Positional arguments

  • gridsort: the GridSortInPlace structure
  • grid: the grid (should have an n_cells field, and a get_cell function has to be defined for the grid type)
  • particles: the ParticleVector of particles to be sorted
  • pia: the ParticleIndexerArray instance
  • species: the index of the species being sorted
sort_particles!(gridsort::GridSortInPlace, particles, pia, species)

Sort particles on a grid using an in-place sorting algorithm. The pia instance is allowed to have non-contiguous indices (arising for example from merging). This function assumes that at the start of the sorting, it is known in which cell each particle is located.

The first and last cell holding particles are recorded in the GridSortInPlace instance, for use in update_occupancy_bounds!.

Positional arguments

  • gridsort: the GridSortInPlace structure
  • particles: the ParticleVector of particles to be sorted
  • pia: the ParticleIndexerArray instance
  • species: the index of the species being sorted

Particle movement

Merzbild.convect_particles!Function
convect_particles!(rng, grid::Grid1DUniform, bc_list, particles::ParticleVector{D}, pia, species, species_data, Δt) where D

Convect particles on a 1-D uniform grid.

Positional arguments

  • rng: the random number generator
  • grid: the grid on which the convection is performed
  • bc_list: the Tuple of boundary conditions (left and right wall)
  • particles: the ParticleVector of particles to be convected
  • pia: the ParticleIndexerArray instance
  • species: the index of the species being convected
  • species_data: the vector of Species data
  • Δt: the convection timestep
convect_particles!(rng, grid::Grid1DUniform, bc_list, surf_props::SurfProps, particles::ParticleVector{D}, pia, species, species_data, Δt) where D

Convect particles on a 1-D uniform grid, computing surface properties if particles hit a surface.

Positional arguments

  • rng: the random number generator
  • grid: the grid on which the convection is performed
  • bc_list: the Tuple of boundary conditions (left and right wall)
  • particles: the ParticleVector of particles to be convected
  • pia: the ParticleIndexerArray instance
  • species: the index of the species being convected
  • species_data: the vector of Species data
  • surf_props: the SurfProps struct where the computed surface properties will be stored
  • Δt: the convection timestep
Merzbild.convect_particles_periodic!Function
convect_particles_periodic!(grid::Grid1DUniform, particles::ParticleVector{D}, pia, species, Δt) where D

Convect particles on a 1-D uniform grid assuming a periodic grid.

Positional arguments

  • grid: the grid on which the convection is performed
  • particles: the ParticleVector of particles to be convected
  • pia: the ParticleIndexerArray instance
  • species: the index of the species being convected
  • Δt: the convection timestep
Merzbild.convect_particles_and_compute_cell!Function
convect_particles_and_compute_cell!(rng, grid::Grid1DUniform, bc_list, particles::ParticleVector{D}, pia, species, species_data, Δt) where D

Convect particles on a 1-D uniform grid and write post-convection cell index to particles.cell.

Positional arguments

  • rng: the random number generator
  • grid: the grid on which the convection is performed
  • bc_list: the Tuple of boundary conditions (left and right wall)
  • particles: the ParticleVector of particles to be convected
  • pia: the ParticleIndexerArray instance
  • species: the index of the species being convected
  • species_data: the vector of Species data
  • Δt: the convection timestep
convect_particles_and_compute_cell!(rng, grid::Grid1DUniform, bc_list, surf_props::SurfProps, particles::ParticleVector{D}, pia, species, species_data, Δt) where D

Convect particles on a 1-D uniform grid and write post-convection cell index to particles.cell, computing surface properties if particles hit a surface.

Positional arguments

  • rng: the random number generator
  • grid: the grid on which the convection is performed
  • bc_list: the Tuple of boundary conditions (left and right wall)
  • particles: the ParticleVector of particles to be convected
  • pia: the ParticleIndexerArray instance
  • species: the index of the species being convected
  • species_data: the vector of Species data
  • surf_props: the SurfProps struct where the computed surface properties will be stored
  • Δt: the convection timestep
Merzbild.convect_particles_and_compute_cell_periodic!Function
convect_particles_and_compute_cell_periodic!(grid::Grid1DUniform, particles::ParticleVector{D}, pia, species, Δt) where D

Convect particles on a 1-D uniform grid and write post-convection cell index to particles.cell assuming a periodic grid.

Positional arguments

  • grid: the grid on which the convection is performed
  • particles: the ParticleVector of particles to be convected
  • pia: the ParticleIndexerArray instance
  • species: the index of the species being convected
  • Δt: the convection timestep

Particle-surface interactions

Merzbild.MaxwellWallBC1DType
MaxwellWallBC1D <: AbstractBC

A struct to hold information about a Maxwell reflecting wall (mixture of specular and diffuse scattering) orthogonal to the x-axis. This is species-specific, as reflection_velocity_sq is dependent on the species' mass.

Fields

  • T: temperature
  • v: wall velocity vector
  • accommodation: accommodation coefficient (a value of 0 corresponds to specular reflection, a value of 1 corresponds to purely diffuse reflection) - these are implemented in separate more efficient functions as well
  • reflection_velocity_sq: pre-computed squared thermal reflection velocity
Merzbild.MaxwellWallBC1DMethod
MaxwellWallBC1D(species, species_data, T::Float64, v, accommodation::Float64)

Construct a MaxwellWallBC1D instance for a given species.

Positional arguments

  • species: index of the species for which to create the BC
  • species_data: the list of Species data
  • T: wall temperature
  • v: wall velocity vector
  • accommodation: accommodation coefficient
Merzbild.FullyDiffuseBC1DType
FullyDiffuseBC1D <: AbstractBC

A struct to hold information about a fully diffuse reflecting wall orthogonal to the x-axis. This is species-specific, as reflection_velocity_sq is dependent on the species' mass.

Fields

  • T: temperature
  • v: wall velocity vector
  • reflection_velocity_sq: pre-computed squared thermal reflection velocities
Merzbild.FullyDiffuseBC1DMethod
FullyDiffuseBC1D(species, species_data, T::Float64, v)

Construct a FullyDiffuseBC1D instance for a given species.

Positional arguments

  • species: index of the species for which to create the BC
  • species_data: the list of Species data
  • T: wall temperature
  • v: wall velocity vector
Merzbild.FullySpecularBC1DType
FullyDiffuseBC1D <: AbstractBC

A struct to hold information about a fully specularly reflecting wall orthogonal to the x-axis. Since such reflection simply flips the sign of the particle's x-velocity, no data is stored in the struct.

I/O

Merzbild.write_gridFunction
write_grid(nc_filename, grid::Grid1DUniform; global_attributes=Dict{Any,Any}())

Write grid info to a NetCDF file

Positional arguments

  • nc_filename: path to the NetCDF file
  • grid: the grid to be written out to a file

Keyword arguments

  • global_attributes: dictionary of additional global attributes to be written to the netCDF file
Merzbild.IOSkipListType
IOSkipList

Struct that holds track of which variables are not to be written to NetCDF file for physical properties computed on a grid. If the field value is true, the corresponding physical grid property will not be output to the file.

Fields

  • skip_length_particle_array: whether the length of the particle array should be skipped
  • skip_number_of_particles: whether the output of the number of particles should be skipped
  • skip_number_density: whether the output of the number density/number of physical particles should be skipped
  • skip_velocity: whether the output of the velocity should be skipped
  • skip_temperature: whether the output of the temperature should be skipped
Merzbild.IOSkipListMethod
IOSkipList(list_of_variables_to_skip)

Construct an IOSkipList from a list of variable names. The possible names are: length_particle_array, np or nparticles, ndens, v, T.

Positional arguments

  • list_of_variables_to_skip: list of variable names to skip
Merzbild.IOSkipListSurfType
IOSkipListSurf

Struct that holds track of which variables are not to be written to NetCDF file for computed surface properties. If the field value is true, the corresponding surface property will not be output to the file.

Fields

  • skip_number_of_particles: whether the output of the number of particles should be skipped
  • skip_fluxes: whether the output of the incident/reflected fluxes should be skipped
  • skip_force: whether the output of the force should be skipped
  • skip_normal_pressure: whether the output of the normal pressure should be skipped
  • skip_shear_pressure: whether the output of the shear pressure should be skipped
  • skip_kinetic_energy_flux: whether the output of the kinetic energy flux should be skipped
Merzbild.IOSkipListSurfMethod
IOSkipListSurf(list_of_variables_to_skip)

Construct an IOSkipListSurf from a list of variable names. The possible names are: np or nparticles, fluxes, force, normal_pressure, shear_pressure, kinetic_energy_flux.

Positional arguments

  • list_of_variables_to_skip: list of variable names to skip
Merzbild.IOSkipListFluxType
IOSkipListFlux

Struct that holds track of which variables are not to be written to NetCDF file for computed fluxes. If the field value is true, the corresponding flux will not be output to the file.

Fields

  • skip_kinetic_energy_flux: whether the output of the kinetic energy flux should be skipped
  • skip_diagonal_momentum_flux: whether the output of the diagonal components of the momentum flux tensor should be skipped
  • skip_off_diagonal_momentum_flux: whether the output of the off-diagonal components of the momentum flux tensor should be skipped
Merzbild.IOSkipListFluxMethod
IOSkipListFlux(list_of_variables_to_skip)

Construct an IOSkipListFlux from a list of variable names. The possible names are: kinetic_energy_flux, diagonal_momentum_flux, off_diagonal_momentum_flux.

Positional arguments

  • list_of_variables_to_skip: list of variable names to skip
Merzbild.IOSkipListFieldType
IOSkipListField

Struct that holds track of which variables are not to be written to NetCDF file for the electrostatic field quantities computed on the nodes of a grid. If the field value is true, the corresponding field quantity will not be output to the file.

Fields

  • skip_charge_density: whether the output of the charge density should be skipped
  • skip_potential: whether the output of the electrostatic potential should be skipped
  • skip_electric_field: whether the output of the electric field should be skipped
Merzbild.IOSkipListFieldMethod
IOSkipListField(list_of_variables_to_skip)

Construct an IOSkipListField from a list of variable names. The possible names are: rho or charge_density, phi or potential, E or electric_field.

Positional arguments

  • list_of_variables_to_skip: list of variable names to skip
Merzbild.NCDataHolderType
NCDataHolder <: AbstractNCDataHolder

Struct that holds NetCDF-output related data for physical properties (grid properties) I/O.

Fields

  • filehandle: handle to the open NetCDF file
  • ndens_not_Np: whether the number density or the number of physical particles is being output
  • timestep_dim: timestep dimension that used to keep track of the number of output steps
  • v_timestep: variable to hold the simulation timestep number (dimension time)
  • v_lpa: variable to hold lengths of particle arrays (dimension n_species x time)
  • v_np: variable to hold number of particles (dimension n_cells x n_species x time)
  • v_ndens: variable to hold number density or the number of physical particles (dimension n_cells x n_species x time)
  • v_v: variable to hold velocity (dimension 3 x n_cells x n_species x time)
  • v_T: variable to hold temperature (dimension n_cells x n_species x time)
  • n_species_1: constant vector [n_species, 1] (used for offsets during I/O)
  • n_cells_n_species_1: constant vector [n_cells, n_species, 1] (used for offsets during I/O)
  • n_v_n_cells_n_species_1: constant vector [3, n_cells, n_species, 1] (used for offsets during I/O)
  • currtimesteps: vector [n_t_output], where n_t_output is the current output timestep (i.e. how many times the properties have already been output, not the simulation timestep) (used for offsets during I/O)
  • currtimesteps_1: vector [1, n_t_output], where n_t_output is the current output timestep (i.e. how many times the properties have already been output, not the simulation timestep) (used for offsets during I/O)
  • currtimesteps_1_1: vector [1, 1, n_t_output], where n_t_output is the current output timestep (i.e. how many times the properties have already been output, not the simulation timestep) (used for offsets during I/O)
  • currtimesteps_1_1_1: vector [1, 1, 1, n_t_output], where n_t_output is the current output timestep (i.e. how many times the properties have already been output, not the simulation timestep) (used for offsets during I/O)
  • timestep: vector storing the current simulation timestep
  • skip_list: IOSkipList instance of variables to skip during output
Merzbild.NCDataHolderMethod
NCDataHolder(nc_filename, names_skip_list, species_data, phys_props; global_attributes=Dict{Any,Any}(), mode=NC_64BIT_OFFSET)

Construct a NCDataHolder instance with a list of variables to skip.

Positional arguments

  • nc_filename: filename to write output to
  • names_skip_list: list of variable names to skip, see IOSkipList for more details
  • species_data: the vector of Species data for the species in the simulation
  • phys_props: the PhysProps instance which will be used for the computation and output of physical properties

Keyword arguments

  • global_attributes: dictionary of any additional attributes to write to the netCDF file as a global attribute
  • mode: NetCDF file format mode (default: NC_64BIT_OFFSET for older and faster format, can use NC_NETCDF4 for NetCDF4 format)
Merzbild.NCDataHolderMethod
NCDataHolder(nc_filename, species_data, phys_props; global_attributes=Dict{Any,Any}(), mode=NC_64BIT_OFFSET)

Construct a NCDataHolder instance with an empty list of variable to skip,

Positional arguments

  • nc_filename: filename to write output to
  • species_data: the vector of Species data for the species in the simulation
  • phys_props: the PhysProps instance which will be used for the computation and output of physical properties

Keyword arguments

  • global_attributes: dictionary of any additional attributes to write to the netCDF file as a global attribute
  • mode: NetCDF file format mode (default: NC_64BIT_OFFSET for older and faster format, can use NC_NETCDF4 for NetCDF4 format)
Merzbild.NCDataHolderSurfType
NCDataHolderSurf

Struct that holds NetCDF-output related data for surface properties I/O.

Fields

  • filehandle: handle to the open NetCDF file
  • timestep_dim: timestep dimension that used to keep track of the number of output steps
  • v_timestep: variable to hold the simulation timestep number (dimension time)
  • v_np: variable to hold number of particles that hit the surface (dimension n_elements x n_species x time)
  • v_flux_incident: variable to hold incident mass flux (dimension n_elements x n_species x time)
  • v_flux_reflected: variable to hold reflected mass flux (dimension n_elements x n_species x time)
  • v_force: variable to hold force (dimension 3 x n_elements x n_species x time)
  • v_normal_pressure: variable to hold normal pressure (dimension n_elements x n_species x time)
  • v_shear_pressure: variable to hold shear pressure (dimension 3 x n_elements x n_species x time)
  • v_kinetic_energy_flux: variable to hold kinetic energy flux (dimension n_elements x n_species x time)
  • n_species_1: constant vector [n_species, 1] (used for offsets during I/O)
  • n_elements_n_species_1: constant vector [n_elements, n_species, 1] (used for offsets during I/O)
  • n_v_n_elements_n_species_1: constant vector [3, n_elements, n_species, 1] (used for offsets during I/O)
  • currtimesteps: vector [n_t_output], where n_t_output is the current output timestep (i.e. how many times the properties have already been output, not the simulation timestep) (used for offsets during I/O)
  • currtimesteps_1: vector [1, n_t_output], where n_t_output is the current output timestep (i.e. how many times the properties have already been output, not the simulation timestep) (used for offsets during I/O)
  • currtimesteps_1_1: vector [1, 1, n_t_output], where n_t_output is the current output timestep (i.e. how many times the properties have already been output, not the simulation timestep) (used for offsets during I/O)
  • currtimesteps_1_1_1: vector [1, 1, 1, n_t_output], where n_t_output is the current output timestep (i.e. how many times the properties have already been output, not the simulation timestep) (used for offsets during I/O)
  • timestep: vector storing the current simulation timestep
  • skip_list: IOSkipListSurf instance of variables to skip during output
Merzbild.NCDataHolderSurfMethod
NCDataHolderSurf(nc_filename, names_skip_list, species_data, surf_props; global_attributes=Dict{Any,Any}(), mode=NC_64BIT_OFFSET)

Construct a NCDataHolderSurf instance with a list of variables to skip.

Positional arguments

  • nc_filename: filename to write output to
  • names_skip_list: list of variable names to skip, see IOSkipListSurf for more details
  • species_data: the vector of Species data for the species in the simulation
  • surf_props: the SurfProps instance which will be used for the computation and output of surface properties

Keyword arguments

  • global_attributes: dictionary of any additional attributes to write to the netCDF file as a global attribute
  • mode: NetCDF file format mode (default: NC_64BIT_OFFSET for older and faster format, can use NC_NETCDF4 for NetCDF4 format)
Merzbild.NCDataHolderSurfMethod
NCDataHolderSurf(nc_filename, species_data, surf_props; global_attributes=Dict{Any,Any}(), mode=NC_64BIT_OFFSET)

Construct a NCDataHolderSurf instance with an empty list of variable to skip.

Positional arguments

Positional arguments

  • nc_filename: filename to write output to
  • species_data: the vector of Species data for the species in the simulation
  • surf_props: the SurfProps instance which will be used for the computation and output of surface properties

Keyword arguments

  • global_attributes: dictionary of any additional attributes to write to the netCDF file as a global attribute
  • mode: NetCDF file format mode (default: NC_64BIT_OFFSET for older and faster format, can use NC_NETCDF4 for NetCDF4 format)
Merzbild.NCDataHolderFluxType
NCDataHolderFlux

Struct that holds NetCDF-output related data for fluxes I/O.

Fields

  • filehandle: handle to the open NetCDF file
  • timestep_dim: timestep dimension that used to keep track of the number of output steps
  • v_timestep: variable to hold the simulation timestep number (dimension time)
  • v_kinetic_energy_flux: variable to hold kinetic energy flux (dimension 3 x n_elements x n_species x time)
  • v_diagonal_momentum_flux: variable to the diagonal components of the momentum flux tensor (dimension 3 x n_elements x n_species x time)
  • v_off_diagonal_momentum_flux: variable to the off-diagonal components of the momentum flux tensor (dimension 3 x n_elements x n_species x time)
  • n_v_n_elements_n_species_1: constant vector [3, n_elements, n_species, 1] (used for offsets during I/O)
  • currtimesteps: vector [n_t_output], where n_t_output is the current output timestep (i.e. how many times the properties have already been output, not the simulation timestep) (used for offsets during I/O)
  • currtimesteps_1_1_1: vector [1, 1, 1, n_t_output], where n_t_output is the current output timestep (i.e. how many times the properties have already been output, not the simulation timestep) (used for offsets during I/O)
  • timestep: vector storing the current simulation timestep
  • skip_list: IOSkipListFlux instance of variables to skip during output
Merzbild.NCDataHolderFluxMethod
NCDataHolderFlux(nc_filename, names_skip_list, species_data, flux_props; global_attributes=Dict{Any,Any}(), mode=NC_64BIT_OFFSET)

Construct a NCDataHolderFlux instance with a list of variables to skip.

Positional arguments

  • nc_filename: filename to write output to
  • names_skip_list: list of variable names to skip, see IOSkipListSurf for more details
  • species_data: the vector of Species data for the species in the simulation
  • flux_props: the FluxProps instance which will be used for the computation and output of fluxes

Keyword arguments

  • global_attributes: dictionary of any additional attributes to write to the netCDF file as a global attribute
  • mode: NetCDF file format mode (default: NC_64BIT_OFFSET for older and faster format, can use NC_NETCDF4 for NetCDF4 format)
Merzbild.NCDataHolderFluxMethod
NCDataHolderFlux(nc_filename, species_data, flux_props; global_attributes=Dict{Any,Any}(), mode=NC_64BIT_OFFSET)

Construct a NCDataHolderFlux instance with an empty list of variable to skip.

Positional arguments

Positional arguments

  • nc_filename: filename to write output to
  • species_data: the vector of Species data for the species in the simulation
  • flux_props: the FluxProps instance which will be used for the computation and output of fluxes

Keyword arguments

  • global_attributes: dictionary of any additional attributes to write to the netCDF file as a global attribute
  • mode: NetCDF file format mode (default: NC_64BIT_OFFSET for older and faster format, can use NC_NETCDF4 for NetCDF4 format)
Merzbild.NCDataHolderMomentsType
NCDataHolderMoments <: AbstractNCDataHolder

Struct that holds NetCDF-output related data for moments I/O.

Fields

  • filehandle: handle to the open NetCDF file
  • timestep_dim: timestep dimension that used to keep track of the number of output steps
  • v_timestep: variable to hold the simulation timestep number (dimension time)
  • v_mompows: variable to hold list of total moment powers (dimension n_moments)
  • v_moments: variable to hold total moments (dimension n_moments x n_cells x n_species x time)
  • n_moments: number of moments
  • n_cells: number of cells
  • n_species: number of species
  • n_moments_n_cells_n_species_1: constant vector [n_moments, n_cells, n_species, 1] (used for offsets during I/O)
  • currtimesteps: vector [n_t_output], where n_t_output is the current output timestep (i.e. how many times the properties have already been output, not the simulation timestep) (used for offsets during I/O)
  • currtimesteps_1_1_1: vector [1, 1, 1, n_t_output], where n_t_output is the current output timestep (i.e. how many times the properties have already been output, not the simulation timestep) (used for offsets during I/O)
  • timestep: vector storing the current simulation timestep
Merzbild.NCDataHolderMomentsMethod
NCDataHolderMoments(nc_filename, species_data, n_cells, n_species, moment_powers; global_attributes=Dict{Any,Any}(), mode=NC_64BIT_OFFSET)

Construct a NCDataHolderMoments instance.

Positional arguments

  • nc_filename: filename to write output to
  • species_data: the vector of Species data for the species in the simulation
  • n_cells: number of cells
  • n_species: number of species
  • moment_powers: vector of moment powers (e.g., Int8[2, 4, 6])

Keyword arguments

  • global_attributes: dictionary of any additional attributes to write to the netCDF file as a global attribute
  • mode: NetCDF file format mode (default: NC_64BIT_OFFSET for older and faster format, can use NC_NETCDF4 for NetCDF4 format)
Merzbild.NCDataHolderFieldType
NCDataHolderField <: AbstractNCDataHolder

Struct that holds NetCDF-output related data for the I/O of the electrostatic field quantities stored in the nodes of a grid.

Fields

  • filehandle: handle to the open NetCDF file
  • timestep_dim: timestep dimension that used to keep track of the number of output steps
  • v_timestep: variable to hold the simulation timestep number (dimension time)
  • v_charge_density: variable to hold the charge density (dimension n_nodes x time)
  • v_potential: variable to hold the electrostatic potential (dimension n_nodes x time)
  • v_electric_field: variable to hold the x-component of the electric field (dimension n_nodes x time)
  • n_nodes: number of nodes
  • n_nodes_1: constant vector [n_nodes, 1] (used for offsets during I/O)
  • currtimesteps: vector [n_t_output], where n_t_output is the current output timestep (i.e. how many times the properties have already been output, not the simulation timestep) (used for offsets during I/O)
  • currtimesteps_1: vector [1, n_t_output], where n_t_output is the current output timestep (i.e. how many times the properties have already been output, not the simulation timestep) (used for offsets during I/O)
  • timestep: vector storing the current simulation timestep
  • skip_list: IOSkipListField instance of variables to skip during output
Merzbild.NCDataHolderFieldMethod
NCDataHolderField(nc_filename, names_skip_list, field_props; global_attributes=Dict{Any,Any}(), mode=NC_64BIT_OFFSET)

Construct a NCDataHolderField instance with a list of variables to skip.

Positional arguments

  • nc_filename: filename to write output to
  • names_skip_list: list of variable names to skip, see IOSkipListField for more details
  • field_props: the ElectrostaticFieldProps instance which will be used for the output of the field quantities

Keyword arguments

  • global_attributes: dictionary of any additional attributes to write to the netCDF file as a global attribute
  • mode: NetCDF file format mode (default: NC_64BIT_OFFSET for older and faster format, NC_NETCDF4 for NetCDF4 format)
Merzbild.NCDataHolderFieldMethod
NCDataHolderField(nc_filename, field_props; global_attributes=Dict{Any,Any}(), mode=NC_64BIT_OFFSET)

Construct a NCDataHolderField instance with an empty list of variables to skip.

Positional arguments

  • nc_filename: filename to write output to
  • field_props: the ElectrostaticFieldProps instance which will be used for the output of the field quantities

Keyword arguments

  • global_attributes: dictionary of any additional attributes to write to the netCDF file as a global attribute
  • mode: NetCDF file format mode (default: NC_64BIT_OFFSET for older and faster format, NC_NETCDF4 for NetCDF4 format)
Merzbild.write_netcdfFunction
 write_netcdf(ds, phys_props::PhysProps, timestep; sync_freq=0)

Write computed PhysProps to NetCDF file and synchronize file to disk if necessary.

Positional arguments

  • ds: the NCDataHolder for the file to which the output will be written
  • phys_props: the PhysProps instance containing the computed properties
  • timestep: the simulation timestep

Keyword arguments

  • sync_freq: if larger than 0 and if the number of timesteps output is proportional to sync_freq, the data will be synchronized to disk. If set to 1, will sync data to disk at every timestep at which data is written to the file.

Throws

ErrorException if the NCDataHolder expects number density and the phys_props holds the number of physical particles, or vice versa.

write_netcdf(ds, surf_props::SurfProps, timestep; sync_freq=0)

Write SurfProps to a NetCDF file and synchronize file to disk if necessary.

Positional arguments

  • ds: the NCDataHolderSurf for the file to which the output will be written
  • surf_props: the SurfProps instance containing the computed properties
  • timestep: the simulation timestep

Keyword arguments

  • sync_freq: if larger than 0 and if the number of timesteps output is proportional to sync_freq, the data will be synchronized to disk. If set to 1, will sync data to disk at every timestep at which data is written to the file.
write_netcdf(ds, flux_props::FluxProps, timestep; sync_freq=0)

Write FluxProps to a NetCDF file and synchronize file to disk if necessary.

Positional arguments

  • ds: the NCDataHolderFlux for the file to which the output will be written
  • flux_props: the FluxProps instance containing the computed properties
  • timestep: the simulation timestep

Keyword arguments

  • sync_freq: if larger than 0 and if the number of timesteps output is proportional to sync_freq, the data will be synchronized to disk. If set to 1, will sync data to disk at every timestep at which data is written to the file.
write_netcdf(nc_filename, particles::Vector{ParticleVector{D}}, pia, species_data, species_ids; global_attributes=Dict{Any,Any}(), mode=NC_64BIT_OFFSET)

Write particles of species listed in species_ids to a NetCDF file. The particles are written cell-wise, so the ordering is not preserved in case particles are present in the set of indices pointed to by group2 indices. If D==0 (particle position is not tracked), neither the particle position nor the cell index is written to the file.

Positional arguments

  • nc_filename: filename to write output to
  • particles: the Vector of ParticleVector instances of particles to be written
  • pia: the ParticleIndexerArray instance
  • species_data: the vector of Species data for the species in the simulation
  • species_ids: list of species ids (in range 1:n_species) of species for which to write particle data

Keyword arguments

  • global_attributes: dictionary of any additional attributes to write to the netCDF file as a global attribute
write_netcdf(ds::NCDataHolderMoments, moments, timestep; sync_freq=0)

Write 'moments' to a NetCDF file and synchronize file to disk if necessary.

Positional arguments

  • ds: the NCDataHolderMoments for the file to which the output will be written
  • moments: the moments array (dimension n_moments x n_cells x n_species)
  • timestep: the simulation timestep

Keyword arguments

  • sync_freq: if larger than 0 and if the number of timesteps output is proportional to sync_freq, the data will be synchronized to disk. If set to 1, will sync data to disk at every timestep at which data is written to the file.
write_netcdf(ds, field_props::ElectrostaticFieldProps, timestep; sync_freq=0)

Write the electrostatic field quantities stored in an ElectrostaticFieldProps instance to a NetCDF file and synchronize file to disk if necessary.

Positional arguments

  • ds: the NCDataHolderField for the file to which the output will be written
  • field_props: the ElectrostaticFieldProps instance containing the field quantities
  • timestep: the simulation timestep

Keyword arguments

  • sync_freq: if larger than 0 and if the number of timesteps output is proportional to sync_freq, the data will be synchronized to disk. If set to 1, will sync data to disk at every timestep at which data is written to the file.
Merzbild.close_netcdfFunction
close_netcdf(ds::T) where {T<:AbstractNCDataHolder}

Close NetCDF file.

Positional arguments

  • ds: an AbstractNCDataHolder instance to close.

Parallel computations

Merzbild.ChunkExchangerType
ChunkExchanger

Struct used to organize exchange of particles between independent ParticleVector instances for chunked multi-threaded simulations. It is assumed that the cell indices within each chunk are contiguous, i.e. chunk[i+1] = chunk[i]+1.

The indexing for the exchanged groups is stored as arrays of shape (n_chunks, n_cells), and [chunk_id, cell] describes the particles that belong to cell cell and came from particle chunk chunk_id. Group 1 holds the particles that arrived via swapping, group 2 the particles that arrived via pushing, i.e. those added to the end of the particle array. The end of a group is not stored, as it is given by start + n_group - 1 (which is -1 for an empty group, matching the convention used by ParticleIndexer).

The table is self-clearing: every entry written during an exchange is read exactly once, in the same timestep, by the chunk owning the cell, and sort_particles_after_exchange! zeroes it as it reads it. It is therefore already empty at the start of each timestep and does not need to be reset! between timesteps.

The occ_lo/occ_hi fields hold, per chunk, the first and last cell in which the chunk holds any particles. They let exchange_particles! reject a pair of chunks that cannot have anything to exchange without scanning the cells of either chunk. They are updated by update_occupancy_bounds! and start out as the whole grid, i.e. a simulation that never calls it is still correct, just slower.

Fields

  • n_chunks: number of chunks used in the simulation
  • n_cells: number of grid cells in the simulation
  • start1: index of the first particle of group 1
  • n_group1: number of particles in group 1
  • start2: index of the first particle of group 2
  • n_group2: number of particles in group 2
  • occ_lo: first cell in which a chunk holds particles
  • occ_hi: last cell in which a chunk holds particles
Merzbild.ChunkExchangerMethod
ChunkExchanger(chunks, n_cells)

Create a ChunkExchanger for length(chunks) chunks and n_cells cell.

Positional arguments

  • chunks: list of cell chunks
  • n_cells: total number of cells in the simulation
Merzbild.update_occupancy_bounds!Function
update_occupancy_bounds!(chunk_exchanger, gridsort, pia, chunk_id, species)

Update the first and last cell in which chunk chunk_id holds particles of the given species, so that exchange_particles! can reject pairs of chunks with nothing to exchange without scanning any cells.

Must be called after sort_particles! and before exchange_particles!, as it simply copies over the bounds recorded by the sort. If not called, one should set occ_lo to 1 and occ_hi to n_cells in each chunk.

Positional arguments

  • chunk_exchanger: the ChunkExchanger instance in which to store the bounds
  • gridsort: the GridSortInPlace used to sort the chunk's particles
  • pia: the ParticleIndexerArray instance associated with the chunk
  • chunk_id: the chunk for which to update the bounds
  • species: the particle species for which the bounds are computed
Merzbild.exchange_particles!Function
exchange_particles!(chunk_exchanger, particles_chunks::Vector{Vector{ParticleVector{D}}}, pia_chunks, cell_chunks, species, i, j) where D

Redistribute particles between chunks i and j based on their spatial cell ownership.

This function ensures each particle resides in the chunk responsible for its current cell. It performs symmetric swaps when possible, and pushes remaining particles if needed. The indexing metadata (chunk_exchanger and pia_chunks) is updated accordingly, and particles pushed to another chunk (not swapped) are added to the buffer for future re-use. The particles before the start of the re-distribution need to be sorted, so that no particles are indexed by the start2:end2 part of a ParticleIndexer. After the operation, the n_total[species] value of pia_chunks[chunk_id] will not include particles that were pushed to another chunk (the appropriate n_group1, start1, end1 values will be set to 0, 0, -1). However indexing should not be relied on until particles are re-sorted, see (sort_particles_after_exchange!)[@ref].

Positional arguments

  • chunk_exchanger: the ChunkExchanger instance to track post-swap and post-push indices
  • particles_chunks: Vector of Vector of ParticleVector (per chunk and per species, i.e. particles_chunks[chunk_id][species] is the correct order of access)
  • pia_chunks: Vector of ParticleIndexerArray instances for each chunk
  • cell_chunks: cell ownership list for each chunk, i.e. cell_chunks[chunk_id] is a list of cells belonging to chunk chunk_id; the cells within cell_chunks[chunk_id] should be ordered in increasing order and be continuous: i.e. cell_chunks[chunk_id][i] == cell_chunks[chunk_id][i-1] + 1
  • species: the particle species being redistributed
  • i: index of first chunk
  • j: index of second chunk
exchange_particles!(chunk_exchanger, particles_chunks::Vector{Vector{ParticleVector{D}}}, pia_chunks, cell_chunks, species) where D

Redistribute particles between chunks based on their spatial cell ownership.

This function ensures each particle resides in the chunk responsible for its current cell. It performs symmetric swaps when possible, and pushes remaining particles if needed. The indexing metadata (chunk_exchanger and pia_chunks) is updated accordingly, and particles pushed to another chunk (not swapped) are added to the buffer for future re-use. The particles before the start of the re-distribution need to be sorted, so that no particles are indexed by the start2:end2 part of a ParticleIndexer. After the operation, the n_total[species] value of pia_chunks[chunk_id] will not include particles that were pushed to another chunk (the appropriate n_group1, start1, end1 values will be set to 0, 0, -1). However indexing should not be relied on until particles are re-sorted, see (sort_particles_after_exchange!)[@ref].

Positional arguments

  • chunk_exchanger: the ChunkExchanger instance to track post-swap and post-push indices
  • particles_chunks: Vector of Vector of ParticleVector (per chunk and per species, i.e. particles_chunks[chunk_id][species] is the correct order of access)
  • pia_chunks: Vector of ParticleIndexerArray instances for each chunk
  • cell_chunks: cell ownership list for each chunk, i.e. cell_chunks[chunk_id] is a list of cells belonging to chunk chunk_id; the cells within cell_chunks[chunk_id] should be ordered in increasing order and be continuous: i.e. cell_chunks[chunk_id][i] == cell_chunks[chunk_id][i-1] + 1
  • species: the particle species being redistributed
Merzbild.sort_particles_after_exchange!Function
sort_particles_after_exchange!(chunk_exchanger, gridsort, particles::ParticleVector{D}, pia, cell_chunk, species) where D

Restore indexing of a ParticleVector and the associated ParticleIndexerArray after particles have been swapped and pushed between chunks.

The first and last cell of the chunk holding particles are recorded in the GridSortInPlace instance, so that update_occupancy_bounds! can be called after this function as well as after sort_particles!.

Positional arguments

  • chunk_exchanger: the ChunkExchanger instance used to track post-swap and post-push indices
  • gridsort: The GridSortInPlace associated with the chunk
  • particles: the ParticleVector for which to restore the indexing
  • pia: the ParticleIndexerArray instances associated with the chunk
  • cell_chunk: list or range of cells belonging to the chunk
  • species: the particle species being for which the indexing is being restored
Merzbild.reset!Function
reset!(chunk_exchanger, chunk_id)

Reset all indexing of the entries [chunk_id,:] of a chunk_exchanger.

A newly constructed ChunkExchanger is already empty, and sort_particles_after_exchange! clears the entries it reads, so in a time loop that sorts every chunk after every exchange this does not need to be called at all. It is intended for re-using a ChunkExchanger whose indexing was left in an unknown state, e.g. after an exchange that was not followed by a re-sort.

Positional arguments

  • chunk_exchanger: the ChunkExchanger instance
  • chunk_id: the chunk for which to reset indexing
Merzbild.reduce_surf_props!Function
reduce_surf_props!(surf_props_target, surf_props_chunks)

Sum up the values of the computed surface properties for all SurfProps instances in a surf_props_chunks list and store the sums in surf_props_target.

Positional arguments

  • surf_props_target: the SurfProps instance which will hold the reduced values
  • surf_props_chunks: the list SurfProps instances to use for the reduction operation
Merzbild.reduce_field_props!Function
reduce_field_props!(field_props_target, field_props_chunks)

Sum the charge deposited in the ElectrostaticFieldProps instances of a field_props_chunks list into field_props_target, which is cleared first. This is used in a multi-threaded simulation, where each thread deposits the particles of the cells it owns into its own ElectrostaticFieldProps instance, since depositing into a shared instance is not thread-safe.

Only the charge density is reduced; the potential and the electric field of the target are left untouched, as they are computed by a single solve_poisson! call afterwards. The charge in the per-thread instances is expected to be the raw deposited charge, so normalize_charge_density! has to be called exactly once, on the target, after the reduction, in serial mode.

Positional arguments

  • field_props_target: the ElectrostaticFieldProps instance which will hold the reduced charge density
  • field_props_chunks: the list of ElectrostaticFieldProps instances to use for the reduction operation
Merzbild.generate_1_factorizationFunction
generate_1_factorization(N_chunks)

Construct a Vector{Vector{Tuple{Int,Int}}} with the following properties:

  • tuple elements i and j range from 1 to N_chunks
  • tuples (i,j) and (j,i) are considered equivalent
  • each tuple (i,j) (up to equivalency) appears in the result exactly once
  • in each Vector of tuples all numbers are unique
  • tuples (i,i) do not appear
  • the Vectors of tuples are as long as possible.

This corresponds to a 1-factorization of a complete graph; the resulting Vector of Vectors of Tuples can be iterated over, and particle exchange can be performed between chunks listed in the Tuples in a given Vector using multi-threaded, since each chunk appears at most once in a given vector. This allows to multi-thread the particle exchange step.

Positional arguments

  • N_chunks: number of chunks

Returns

A Vector of Vectors of Tuples corresponding to the 1-factorization of a complete graph with N_chunks vertices.

Merzbild.LoadBalancerCellQType
LoadBalancerCellQ

Used to perform load-balancing in multi-threaded simulations by tracking a per-cell quantity (i.e. number of collisions, number of particles, density, etc.) in a range of cells indexed by cell_start:cell_end and allowing to rebalance the assignment of cells to chunks based on the total quantity per chunk.

Fields

  • cell_start: index of first cell
  • cell_end: index of last cell
  • n_cells: number of cells
  • n_chunks: number of chunks
  • q: Vector of length n_cells of per-cell quantity on which balancing is based. Note that this array is 1-indexed.
  • q_total_per_chunk: Vector of length n_chunks holding the sums of q across all cells in a chunk
  • q_total: total sum of the per-cell quantity across all n_cells cells
  • chunked_indices: a Vector{UnitRange{Int64}} of length n_chunks holding the ranges of indices

assigned to each chunk

Merzbild.LoadBalancerCellQMethod
LoadBalancerCellQ(n_cells, n_chunks)

Create a per-cell indicator-based load balancer for n_cells cells and n_chunks chunks. Note: this uses index_chunks, i.e. it is assumed that cell indexing starts from 1 and is contiguous!

Positional arguments

  • n_cells: number of cells
  • n_chunks: number of chunks

Keyword arguments

  • cell_start: index of first cell indexed by the LoadBalancerCellQ instance
Merzbild.update_lb_cellq!Function
update_lb_cellq!(lb::LoadBalancerCellQ, chunk_id, cell, q; averaging_window=1.0)

Update the values of the load-balancing quantity being tracked in a single cell.

Positional arguments

  • lb: the LoadBalancerCellQ instance to update
  • chunk_id: the index of the chunk to which the cell belongs
  • cell: the index of the cell to update
  • q: the value of the load-balancing quantity in the cell

Keyword arguments

  • averaging_window: the time window over which the load-balancing quantity is averaged

(to potentially avoid round-off errors, overflow, or variable time-steps)

Merzbild.rebalance_lb!Function
rebalance_lb!(lb::LoadBalancerCellQ)

Compute new ranges of cell-indices so that each range holds approximately the same total sum of the load-balancing quantity.

Positional arguments

  • lb: the LoadBalancerCellQ instance on which to perform re-balancing
Merzbild.reset_lb!Function
reset_lb!(lb::LoadBalancerCellQ)

Set all values of the load balancer tracking a per-cell quantity to zero. Indexing is not reset.

Positional arguments

  • lb: the LoadBalancerCellQ instance to reset

Particle-in-Cell

Merzbild.accelerate_constant_field_x!Function
accelerate_constant_field_x!(particles, pia, cell, species, species_data, E, Δt)

Accelerate particles with a constant electric field in the X direction; no sorting of particles is required since the field is constant.

Positional arguments

  • particles: vector-like structure of particles to be accelerated
  • pia: ParticleIndexerArray instance
  • cell: index of the cell in which particles are being accelerated
  • species: index of the species of the particles being accelerated
  • species_data: a Vector{Species} instance with the species' data
  • E: value of the electric field in V/m
  • Δt: timestep for which the acceleration is performed
Merzbild.DirichletFieldBC1DType
DirichletFieldBC1D <: AbstractFieldBC1D

A boundary condition prescribing the value of the electrostatic potential at a boundary of a 1-D domain. The structure is mutable, so that the value can be changed from within a time loop (for example, to drive an RF electrode: bc_left.ϕ = V0 * sin(2π * f * t)).

Fields

  • ϕ: the prescribed value of the potential, V
Merzbild.NeumannFieldBC1DType
NeumannFieldBC1D <: AbstractFieldBC1D

A boundary condition prescribing the x-component of the electric field at a boundary of a 1-D domain (and not the derivative of the potential, given by $d\phi/dx = -E_x$). The structure is mutable, so that the value can be changed from within a time loop (for example, for a dielectric wall accumulating a surface charge $\sigma$: bc_right.E_x = σ / eps_0).

Fields

  • E_x: the prescribed value of the x-component of the electric field, V/m
Merzbild.PeriodicFieldBC1DType
PeriodicFieldBC1D <: AbstractFieldBC1D

A periodic boundary condition for the electrostatic field in a 1-D domain. It has to be used on both sides of the domain; as no values are prescribed, no data is stored in the struct.

Merzbild.PoissonSolver1DUniformType
PoissonSolver1DUniform

Structure holding data used to discretize and solve the 1-D Poisson equation $-\phi'' = \rho / \varepsilon_0$ via second-order finite differences using the Thomas algorithm for tridiagonal matrices.

The field quantities themselves are not stored here, but in an ElectrostaticFieldProps instance. The boundary conditions are type parameters, so that the assembly of the right-hand side is resolved at compile time.

The unknowns are the values of the potential in the nodes which are not prescribed by the boundary conditions; the potential in node node_offset + k is the k-th unknown. The number of unknowns and the node offset depend on the boundary conditions (N = n_nodes, n_cells = N - 1):

left BCright BCunknown nodesn_unknownsnode_offset
DirichletDirichlet2 … N-1n_cells - 11
NeumannDirichlet1 … N-1n_cells0
DirichletNeumann2 … Nn_cells1
NeumannNeumannrejected at construction
periodicperiodic1 … n_cells-1n_cells - 10

Fields

  • n_nodes: number of nodes
  • n_unknowns: number of unknowns of the tridiagonal system
  • node_offset: offset between the index of an unknown and the index of the corresponding node
  • Δx: cell size
  • inv_Δx: inverse of the cell size
  • inv_Δx2: inverse of the squared cell size, used for the Dirichlet right-hand side correction
  • inv_eps_0: inverse of the vacuum permittivity
  • bc_left: the AbstractFieldBC1D boundary condition on the left boundary
  • bc_right: the AbstractFieldBC1D boundary condition on the right boundary
  • a: sub-diagonal of the matrix, with a[1] = 0 as it lies outside of the matrix (not used in the solve)
  • b: main diagonal of the matrix (not used in the solve)
  • c: super-diagonal of the matrix, with c[n_unknowns] = 0 as it lies outside of the matrix (not used in the solve)
  • cp: pre-computed c[i] / m[i] factorization coefficients
  • inv_m: pre-computed 1 / (b[i] - cp[i-1] * a[i]) factorization coefficients
  • a_inv_m: pre-computed -a[i] / m[i] factorization coefficients
  • rhs: right-hand side of the tridiagonal system
  • dp: workspace of the forward sweep of the Thomas algorithm
  • x: solution of the tridiagonal system (values of the potential in the unknown nodes)
Merzbild.PoissonSolver1DUniformMethod
PoissonSolver1DUniform(grid::Grid1DUniform, bc_left::AbstractFieldBC1D, bc_right::AbstractFieldBC1D)

Construct a solver of the 1-D Poisson equation on a uniform grid for a given pair of boundary conditions and factorize the resulting tridiagonal matrix.

Neumann boundary conditions on both sides are rejected (the system is singular and no gauge is available), as is a periodic boundary condition paired with a non-periodic one.

Positional arguments

  • grid: the Grid1DUniform grid
  • bc_left: the AbstractFieldBC1D boundary condition on the left boundary
  • bc_right: the AbstractFieldBC1D boundary condition on the right boundary
Merzbild.deposit_charge!Function
deposit_charge!(grid::Grid1DUniform, particles::ParticleVector, pia, species, species_data, field_props)

Deposit the charge of the particles of a single species on the nodes of a 1-D uniform grid using first-order (cloud-in-cell) weighting. The deposited values are accumulated, so the charge density has to be cleared by a call to clear_charge_density! or clear_props! before the first species is deposited, and normalize_charge_density! has to be called exactly once after the last species has been deposited in order to turn the deposited charge into a charge density. Neutral species are skipped.

The particles are assumed to be sorted on the grid. This routine is serial; for a multi-threaded simulation, see the cell_chunk version of the routine and reduce_field_props!.

Positional arguments

  • grid: the Grid1DUniform grid
  • particles: the ParticleVector of the particles of the species being deposited
  • pia: the ParticleIndexerArray instance
  • species: the index of the species being deposited
  • species_data: the Vector of Species data
  • field_props: the ElectrostaticFieldProps instance in which the deposited charge is stored
deposit_charge!(grid::Grid1DUniform, particles::ParticleVector, pia, species, species_data, field_props, cell_chunk)

Deposit the charge of the particles of a single species located in a subset of the cells of a 1-D uniform grid on the nodes of the grid. Note: the particles are assumed to be sorted on the grid.

In a multi-threaded simulation, each thread should deposit the particles of the cells it owns into its own ElectrostaticFieldProps instance; the per-thread instances are then summed into the global one with reduce_field_props!.

Positional arguments

  • grid: the Grid1DUniform grid
  • particles: the ParticleVector of the particles of the species being deposited
  • pia: the ParticleIndexerArray instance
  • species: the index of the species being deposited
  • species_data: the Vector of Species data
  • field_props: the ElectrostaticFieldProps instance in which the deposited charge is stored
  • cell_chunk: the list of cell indices or range in which the charge of the particles is deposited
deposit_charge!(poisson_solver, grid::Grid1DUniform, particles, pia, species_data, field_props)

Clear the charge density, deposit the charge of the particles of all the species on the nodes of a 1-D uniform grid, and normalize the result to a charge density. This is the recommended way of computing the charge density, as it performs the clearing, the deposition, and the normalization in the correct order.

The particles are assumed to be sorted on the grid. This routine is serial.

Positional arguments

  • poisson_solver: the PoissonSolver1DUniform instance
  • grid: the Grid1DUniform grid
  • particles: the Vector of ParticleVectors containing all the particles in a simulation
  • pia: the ParticleIndexerArray instance
  • species_data: the Vector of Species data
  • field_props: the ElectrostaticFieldProps instance in which the charge density is stored
Merzbild.normalize_charge_density!Function
normalize_charge_density!(poisson_solver::PoissonSolver1DUniform, field_props)

Turn the charge deposited on the nodes of a 1D uniform grid by deposit_charge! into a charge density, by dividing it by the volume of the dual cell of each node. The dual cell of a boundary node is $\Delta x / 2$, so the deposited charge in the boundary nodes is multiplied by 2.

Note that this routine has to be called exactly once per timestep, after all the species have been deposited. The solver is used only to determine the types of the boundary conditions and the cell size.

Positional arguments

  • poisson_solver: the PoissonSolver1DUniform instance
  • field_props: the ElectrostaticFieldProps instance holding the deposited charge
normalize_charge_density!(poisson_solver::PoissonSolver1DUniform{PeriodicFieldBC1D, PeriodicFieldBC1D},
                          field_props)

Turn the charge deposited on the nodes of a 1D uniform grid by deposit_charge! into a charge density, by dividing it by the volume of the dual cell of each node; periodic boundary conditions. The charge deposited in the last node is folded into the first node and mirrored back, and the dual cell of every node is $\Delta x$.

Note that this routine has to be called exactly once per timestep, after all the species have been deposited.

Positional arguments

  • poisson_solver: the PoissonSolver1DUniform instance with periodic BCs
  • field_props: the ElectrostaticFieldProps instance holding the deposited charge
Merzbild.solve_poisson!Function
solve_poisson!(poisson_solver, field_props)

Compute the electrostatic potential and the electric field in the nodes from the charge density stored in field_props, by assembling and solving the discrete Poisson system. The charge density is not modified, so repeated calls do not change the result; it is however assumed that the charge density has already been normalized by a call to normalize_charge_density!.

Positional arguments

  • poisson_solver: the PoissonSolver1DUniform instance
  • field_props: the ElectrostaticFieldProps instance holding the charge density, the potential, and the electric field
Merzbild.accelerate_electric_field_x!Function
accelerate_electric_field_x!(grid::Grid1DUniform, particles, pia, cell, species, species_data, field_props, Δt)

Accelerate the particles of a species in a single cell of a 1-D uniform grid with the self-consistent electric field stored in the nodes, using first-order (cloud-in-cell) interpolation of the field to the position of a particle. The interpolation uses the same weights as deposit_charge!.

The particles are assumed to be sorted on the grid (so no particles are indexed by group2).

Positional arguments

  • grid: the Grid1DUniform grid
  • particles: the ParticleVector of the particles being accelerated
  • pia: the ParticleIndexerArray instance
  • cell: index of the cell in which particles are being accelerated
  • species: index of the species of the particles being accelerated
  • species_data: a Vector{Species} instance with the species' data
  • field_props: the ElectrostaticFieldProps instance holding the electric field
  • Δt: timestep for which the acceleration is performed
accelerate_electric_field_x!(grid::Grid1DUniform, particles, pia, species, species_data, field_props, Δt)

Accelerate the particles of a species in all cells of a 1-D uniform grid with the self-consistent electric field stored in the nodes.

The particles are assumed to be sorted on the grid.

Positional arguments

  • grid: the Grid1DUniform grid
  • particles: the ParticleVector of the particles being accelerated
  • pia: the ParticleIndexerArray instance
  • species: index of the species of the particles being accelerated
  • species_data: a Vector{Species} instance with the species' data
  • field_props: the ElectrostaticFieldProps instance holding the electric field
  • Δt: timestep for which the acceleration is performed

Constants

Misc

Merzbild.MERZBILD_SIMULATIONS_PATHConstant
MERZBILD_SIMULATIONS_PATH

Absolute path to the simulations directory bundled with Merzbild.jl, holding various simulation examples. Use it to run bundled simulations independently of the current working directory, e.g. include(joinpath(MERZBILD_SIMULATIONS_PATH, "0D/BKW/bkw.jl")).

Merzbild.MERZBILD_SCRIPTS_PATHConstant
MERZBILD_SCRIPTS_PATH

Absolute path to the scripts directory bundled with Merzbild.jl, holding various Python scripts for data post-processing and plotting.