Merzbild.jl public API reference
Particles
Merzbild.Particle — TypeParticleA structure to store information about a single particle.
Fields
w: the computational weight of the particlev: the 3-dimensional velocity vector of the particlex: the 3-dimensional position of the particle
Merzbild.ParticleVector — TypeParticleVectorThe 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.
Accessing ParticleVector[i] will return a Particle, with the actual particle returned being ParticleVector.particles[ParticleVector.index[i]].
Fields
particles: the vector of particles of a single speciesindex: 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 particlesnbuffer: the number of elements in the buffer
Merzbild.ParticleVector — MethodParticleVector(np)Create an empty ParticleVector 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 theParticleVectorinstance to create
Base.getindex — MethodBase.getindex(pv::ParticleVector, i)Returns the underlying particle in a ParticleVector instance with index i.
Is usually called as ParticleVector[i].
Positional arguments
pv:ParticleVectorinstancei: the index of the particle to be selected
Base.setindex! — MethodBase.setindex!(pv::ParticleVector, p::Particle, i::Integer)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:ParticleVectorinstancep: theParticleinstance to writei: the index of the particle to be written to
Base.length — MethodBase.length(pv::ParticleVector)Returns the length of a ParticleVector instance.
Is usually called as length(ParticleVector).
Positional arguments
pv:ParticleVectorinstance
Base.resize! — MethodBase.resize!(pv::ParticleVector, n::Integer)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:ParticleVectorinstancen: the new length of theParticleVectorinstance (i.e. the length of all the vector fields of the instance)
Particle indexing
Merzbild.ParticleIndexer — TypeParticleIndexerThe 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 cellstart1: the first index in the first group of particle indicesend1: the last index in the first group of particle indicesn_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 <= 0end2: the last index in the second group of particle indicesn_group2: the number of particles in the second group (n_group2 = end2 - start2 + 1, unless no particles are present in the second group)
Merzbild.ParticleIndexer — MethodParticleIndexer()Create an empty ParticleIndexer. end1 and end2 are set to -1, the other fields are set to 0.
Merzbild.ParticleIndexer — MethodParticleIndexer(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.ParticleIndexerArray — TypeParticleIndexerArrayA 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 - 1pia.indexer[n_cells,species].end1 + 1 == pia.indexer[1,species].start2pia.indexer[cell,species].end2 + 1 == pia.indexer[cell+1,species].start2,cell = 1,...,n_cells - 1
Fields
indexer: the array of size(n_cells, n_species)(number of grid cells * number of species in the simulation) storing theParticleIndexerinstancesn_total: vector of lengthn_speciesstoring the total number of particles of each speciescontiguous: vector of lengthn_speciesstoring a boolean flag whether the ParticleIndexer instances for a species are "contiguous"
Merzbild.ParticleIndexerArray — MethodParticleIndexerArray(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 ofParticleIndexerinstancesn_total: the vector of the total number of particles of each species
Merzbild.ParticleIndexerArray — MethodParticleIndexerArray(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 cellsn_species: the number of species
Merzbild.ParticleIndexerArray — MethodParticleIndexerArray(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.ParticleIndexerArray — MethodParticleIndexerArray(n_particles::T) where T<:AbstractVectorCreate 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.ParticleIndexerArray — MethodParticleIndexerArray(grid, species_data::Array{Species}) where T<:AbstractVectorCreate an empty multi-species/multi-cell ParticleIndexerArray.
Positional arguments
grid: the simulation gridspecies_data: array ofSpeciesdata for all of the species in the simulation
Merzbild.squash_pia! — Functionsquash_pia!(pv, pia, species)Restore the continuity of indices in a ParticleVector and associatedParticleIndexerArrayinstance for a specific species. If for this species the instance hascontiguous == true`, nothing will be done.
Positional arguments
pv: theParticleVectorpia: theParticleIndexerArrayinstancespecies: 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 ofParticleVectors for all species in the flowpia: theParticleIndexerArrayinstance
Merzbild.count_disordered_particles — Functioncount_disordered_particles(pv, pia, species)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: theParticleVectorinstance for which to compute the metricpia: theParticleIndexerArrayinstancespecies: 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_index — Functioncheck_unique_index(pv, pia, species)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: theParticleVectorinstance for which to check indexingpia: theParticleIndexerArrayinstancespecies: 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_correct — Functioncheck_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_group1 == 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])
Positional arguments
pia: theParticleIndexerArrayinstance for which to check consistencyspecies: 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 indexing is correct, returns (true, 0).
Merzbild.pretty_print_pia — Functionpretty_print_pia(pia)Display a ParticleIndexerArray instance by showing the starting/ending indices of the groups over all cells for a specific species.
Positional arguments
pia: theParticleIndexerArrayinstancespecies: the index of the species for which the indices are displayed
Loading species and interaction data
Merzbild.Species — TypeSpeciesA structure to store information about a chemical species.
Fields
name: the name of the speciesmass: the molecular mass of the speciescharge: 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.Interaction — TypeInteractionStructure 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})}$.
Fields
m_r: collision-reduced massμ1: relative mass of the first speciesμ2: relative mass of the second speciesvhs_d: diameter for the VHS potentialvhs_o: exponent for the VHS potentialvhs_Tref: reference temperature for the VHS potentialvhs_muref: reference viscosity for the VHS potentialvhs_factor: pre-computed factor for calculation of the VHS cross-section
Merzbild.load_species_data — Functionload_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 dataspecies_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 dataspecies_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_data — Functionload_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.
Positional arguments
interactions_filename: the path to the TOML file containing the dataspecies_data: list ofSpeciesinstances for which to search for the interaction data
Returns
- 2-dimensional array of
Interactioninstances 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].
Positional arguments
interactions_filename: the path to the TOML file containing the dataspecies_data: list ofSpeciesinstances for which to search for the interaction datadummy_vhs_d: value to use for the VHS diameter if no interaction data found in the filedummy_vhs_o: value to use for the VHS exponent if no interaction data found in the filedummy_vhs_Tref: value to use for the VHS reference temperature if no interaction data found in the file
Returns
- 2-dimensional array of
Interactioninstances of size(n_species, n_species)
Merzbild.load_interaction_data_with_dummy — Functionload_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 dataspecies_data: list ofSpeciesinstances for which to search for the interaction data
Returns
- 2-dimensional array of
Interactioninstances of size(n_species, n_species)
Merzbild.load_species_and_interaction_data — Functionload_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' datainteractions_filename: the path to the TOML file containing the interaction dataspecies_name: the name of the species for which to load the data
Keyword arguments
fill_dummy: iftrue, fill interaction data with computed dummy values if no entry found for a species pair in the interaction file
Returns
VectorofSpeciesinstances- 2-dimensional array of
Interactioninstances of size(n_species, n_species)
Merzbild.load_electron_neutral_interactions — Functionload_electron_neutral_interactions(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.
Positional arguments
species_data: vector ofSpeciesdata for the neutral speciesfilename: path to XML filedatabases: 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 ofScatteringLawinstances to use for each speciesenergy_splits: vector ofElectronEnergySplitinstances 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.
Sampling
Merzbild.maxwellian — Functionmaxwellian(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 velocityvy: y velocityvz: z velocitym: species' massT: temperature
Merzbild.bkw — Functionbkw(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 velocityvy: y velocityvz: z velocitym: species' massT: temperaturescaled_time: the scaled_time
Merzbild.sample_on_grid! — Functionsample_on_grid!(rng, vdf_func, particles, 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 generatorvdf_func: the distribution function to be evaluated which takes the x, y, and z velocities as parametersparticles: theVector-like structure holding the particlesnv: the number of grid nodes in each directionm: the molecular mass of the speciesT: the temperature used to compute the thermal velocityn_total: the total computational weight (number of physical particles) to be sampledxlo: the lower bound of the x coordinates of the particlesxhi: the upper bound of the x coordinates of the particlesylo: the lower bound of the y coordinates of the particlesyhi: the upper bound of the y coordinates of the particleszlo: the lower bound of the z coordinates of the particleszhi: 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 gridcutoff_mult: the value by which the thermal velocity is multiplied to compute the radius for the sphere used to cut-off the higher velocitiesnoise: controls the amount of noise added to the particle velocities (the noise is uniformly distributed on the interval[-noise*dv, noise*dv], wheredvis 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! — Functionsample_maxwellian_on_grid!(rng, particles, 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 generatorparticles: theVector-like structure holding the particlesnv: the number of grid nodes in each directionm: the molecular mass of the speciesT: the temperature used to compute the thermal velocityn_total: the total computational weight (number of physical particles) to be sampledxlo: the lower bound of the x coordinates of the particlesxhi: the upper bound of the x coordinates of the particlesylo: the lower bound of the y coordinates of the particlesyhi: the upper bound of the y coordinates of the particleszlo: the lower bound of the z coordinates of the particleszhi: 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 gridcutoff_mult: the value by which the thermal velocity is multiplied to compute the radius for the sphere used to cut-off the higher velocitiesnoise: controls the amount of noise added to the particle velocities (the noise is uniformly distributed on the interval[-noise*dv, noise*dv], wheredvis 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! — Functionsample_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 generatorparticles: theVector-like structure holding the particlespia: theParticleIndexerArraycell: the cell indexspecies: the species indexnparticles: the number of particles to samplem: species' massT: temperatureFnum: the computational weight of the particlesxlo: the lower bound of the x coordinates of the particlesxhi: the upper bound of the x coordinates of the particlesylo: the lower bound of the y coordinates of the particlesyhi: the upper bound of the y coordinates of the particleszlo: the lower bound of the z coordinates of the particleszhi: the upper bound of the z coordinates of the particles
Keyword arguments
distribution: the distribution to sample from (either:Maxwellianor:BKW)vx0: the x-velocity offset to add to the particle velocitiesvy0: the y-velocity offset to add to the particle velocitiesvz0: 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 generatorgrid1duniform: the 1-D uniform gridparticles: theParticleVectorof particlespia: theParticleIndexerArrayspecies: the index of the species to be sampled forspecies_data:VectorofSpeciesdatappc: number of particles per cell to be sampledT: the temperatureFnum: 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 generatorgrid1duniform: the 1-D uniform gridparticles: theParticleVectorof particlespia: theParticleIndexerArrayspecies: the index of the species to be sampled forspecies_data:VectorofSpeciesdatappc: number of particles per cell to be sampledT: the temperatureFnum: the computational weight of the particlescell_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 generatorgrid1duniform: the 1-D uniform gridparticles: theParticleVectorof particlespia: theParticleIndexerArrayspecies: the index of the species to be sampled forspecies_data:VectorofSpeciesdatandens: target number densityT: the temperatureFnum: the computational weight of the particles
sample_particles_equal_weight!(rng, grid1duniform, particles, pia, species, species_data, ndens::Float64, T, Fnum)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 generatorgrid1duniform: the 1-D uniform gridparticles: theParticleVectorof particlespia: theParticleIndexerArrayspecies: the index of the species to be sampled forspecies_data:VectorofSpeciesdatandens: target number densityT: the temperatureFnum: the computational weight of the particlescell_chunk: the list of cell indices or range in which to sample particles, should be ordered in increasing order
Computing grid and surface macroscopic properties
Merzbild.PhysProps — TypePhysPropsStructure to store computed physical properties in a physical cell.
Fields
ndens_not_Np: whether thenfield stores number density (iftrue) and not the number of physical particles in a cell (iffalse)n_cells: number of physical cellsn_species: number of speciesn_moments: number of total moments computedlpa: length of the particle array (vector of lengthn_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))moment_powers: powers of the total moments computed (vector of lengthn_moments)moments: values of the total moments computed (array of shape(n_moments, n_cells, n_species))Tref: reference temperature used to scale moments
Merzbild.PhysProps — MethodPhysProps(n_cells, n_species, moments_list; ndens_not_Np=false, Tref=300.0)Construct physical properties given the number of cells and species, as well as the list of the orders of total moments to compute. The total moment of order $M$ is defined as $\int \sqrt{v_x^2+v_y^2+v_z^2}^M f(v_x,v_y,v_z)dv_x dv_y dv_z$.
Positional arguments
n_cells: number of cellsn_species: number of species
Keyword arguments
ndens_not_Np: whether thenfield stores number density (iftrue) and not the number of physical particles in a cell (iffalse)Tref: reference temperature used to compute the total moments of a Maxwellian distribution which are used to scale the total moments
Merzbild.PhysProps — MethodPhysProps(pia, moments_list; ndens_not_Np=false, Tref=300.0)Construct physical properties given a ParticleIndexerArray instance, as well as the list of the orders of total moments to compute. The total moment of order $M$ is defined as $\int \sqrt{v_x^2+v_y^2+v_z^2}^M f(v_x,v_y,v_z)dv_x dv_y dv_z$.
Positional arguments
pia: theParticleIndexerArrayinstancen_species: number of species
Keyword arguments
ndens_not_Np: whether thenfield stores number density (iftrue) and not the number of physical particles in a cell (iffalse)Tref: reference temperature used to compute the total moments of a Maxwellian distribution which are used to scale the total moments
Merzbild.PhysProps — MethodPhysProps(pia; ndens_not_Np=false)Construct physical properties given a ParticleIndexerArray instance, with no computation of the total moments.
Positional arguments
pia: theParticleIndexerArrayinstance
Keyword arguments
ndens_not_Np: whether thenfield stores number density (iftrue) and not the number of physical particles in a cell (iffalse)
Merzbild.SurfProps — TypeSurfPropsStructure to store computed surface properties.
Fields
n_elements: number of physical cellsn_species: number of speciesareas: the vector of surface element areasinv_areas: the vector of the inverse surface element areasnormals: 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.SurfProps — MethodSurfProps(n_elements, n_species, area, normals)Positional arguments
n_elementsn_speciesareasnormals
Merzbild.SurfProps — MethodSurfProps(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: theParticleIndexerArrayinstancegrid: theGrid1DUniformgrid
Merzbild.FluxProps — TypeFluxPropsStructure 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 cellsn_species: number of specieskinetic_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.FluxProps — MethodFluxProps(n_cells, n_species)Construct a FluxProps instance given the number of cells and species.
Positional arguments
n_cells: number of cellsn_species: number of species
Merzbild.FluxProps — MethodFluxProps(pia)Construct a FluxProps instance given a ParticleIndexerArray instance.
Positional arguments
pia: theParticleIndexerArrayinstance
Merzbild.compute_props! — Functioncompute_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: theVectorofParticleVectors containing all the particles in a simulationpia: theParticleIndexerArrayinstancespecies_data: theVectorofSpeciesDataphys_props: thePhysPropsinstance in which the computed physical properties are stored
Merzbild.compute_props_with_total_moments! — Functioncompute_props_with_total_moments!(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 computes the total moments.
Positional arguments
particles: theVectorofParticleVectors containing all the particles in a simulationpia: theParticleIndexerArrayinstancespecies_data: theVectorofSpeciesDataphys_props: thePhysPropsinstance in which the computed physical properties are stored
Merzbild.compute_props_sorted! — Functioncompute_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: theVectorofParticleVectors containing all the particles in a simulationpia: theParticleIndexerArrayinstancespecies_data: theVectorofSpeciesDataphys_props: thePhysPropsinstance in which the computed physical properties are storedcell_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: theVectorofParticleVectors containing all the particles in a simulationpia: theParticleIndexerArrayinstancespecies_data: theVectorofSpeciesDataphys_props: thePhysPropsinstance in which the computed physical properties are stored
compute_props_sorted!(particles, pia, species_data, phys_props, grid::G, cell_chunk) where {G<:AbstractGrid}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: theVectorofParticleVectors containing all the particles in a simulationpia: theParticleIndexerArrayinstancespecies_data: theVectorofSpeciesDataphys_props: thePhysPropsinstance in which the computed physical properties are storedgrid: the physical gridcell_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, grid::AbstractGrid) where {G<:AbstractGrid}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: theVectorofParticleVectors containing all the particles in a simulationpia: theParticleIndexerArrayinstancespecies_data: theVectorofSpeciesDataphys_props: thePhysPropsinstance in which the computed physical properties are storedgrid: the physical grid
Merzbild.compute_flux_props! — Functioncompute_flux_props!(particles, pia, species_data, phys_props::PhysProps, flux_props::FluxProps, grid::G) where {G<:AbstractGrid}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: theVectorofParticleVectors containing all the particles in a simulationpia: theParticleIndexerArrayinstancespecies_data: theVectorofSpeciesDataphys_props: thePhysPropsinstance computed at the same timestepflux_props: theFluxPropsinstance in which the computed fluxes are storedgrid: the physical grid
Merzbild.compute_flux_props_sorted! — Functioncompute_flux_props_sorted!(particles, pia, species_data, phys_props, flux_props, grid::G, cell_chunk) where {G<:AbstractGrid}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: theVectorofParticleVectors containing all the particles in a simulationpia: theParticleIndexerArrayinstancespecies_data: theVectorofSpeciesDataphys_props: thePhysPropsinstance computed at the same timestep for the same subset of cellsflux_props: theFluxPropsinstance in which the computed fluxes are storedgrid: the physical gridcell_chunk: the list of cell indices or range of cell indices in which to compute the properties
compute_flux_props_sorted!(particles, pia, species_data, phys_props, flux_props, grid::G) where {G<:AbstractGrid}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: theVectorofParticleVectors containing all the particles in a simulationpia: theParticleIndexerArrayinstancespecies_data: theVectorofSpeciesDataphys_props: thePhysPropsinstance computed at the same timestepflux_props: theFluxPropsinstance in which the computed fluxes are storedgrid: the physical grid
Merzbild.avg_props! — Functionavg_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: thePhysPropsinstance used to store the time-averaged propertiesphys_props: thePhysPropsinstance holding the current values of the properties to be used for the averaging at the current timestepn_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: theFluxPropsinstance used to store the time-averaged propertiesflux_props: theFluxPropsinstance holding the current values of the properties to be used for the averaging at the current timestepn_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: theSurfPropsinstance used to store the time-averaged propertiessurf_props: theSurfPropsinstance holding the current values of the properties to be used for the averaging at the current timestepn_avg_timesteps: the number of timesteps over which the averaging is performed
Merzbild.clear_props! — Functionclear_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: thePhysPropsinstance 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: theFluxPropsinstance 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: theSurfPropsinstance to be cleared
Collisional properties
Merzbild.mean_free_path — Functionmean_free_path(interaction, species, n, T)Compute elastic VHS mean free path for single-species collisions.
Positional arguments
interactions: the 2-dimensional array ofInteractioninstances (of shape(n_species, n_species)) of all the pair-wise interactionsspecies: the species for which to compute the mean free pathn: the number densityT: 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_frequency — Functionmean_collision_frequency(interaction, species_data, species, n, T)Compute elastic VHS mean collision frequency for single-species collisions.
Positional arguments
interactions: the 2-dimensional array ofInteractioninstances (of shape(n_species, n_species)) of all the pair-wise interactionsspecies_data: the vector ofSpeciesinstances of the species in the flowspecies: the species for which to compute the mean free pathn: the number densityT: the temperature
Returns
Mean collision frequency.
References
- Eqn. (4.64) in "Molecular Gas Dynamics and the Direct Simulation of Gas Flows"
Collision computations
Merzbild.CollisionData — TypeCollisionDataStructure 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 velocityg: magnitude of relative velocityE_coll: relative translational energy of the colliding particlesE_coll_eV: relative translational energy of the colliding particles in electron-voltE_coll_electron_eV: collisional energy of the an electron in electron-volt for electron-neutral collisionsg_vec: vector of pre-collisional relative velocityg_vec_new: vector of post-collisional relative velocityg_new_1: magnitude of post-collisional relative velocity of the first particle in the collision pairg_new_2: magnitude of post-collisional relative velocity of the second particle in the collision pair
Merzbild.CollisionData — MethodCollisionData()Create an empty CollisionData instance.
Merzbild.CollisionFactors — TypeCollisionFactorsStructure 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 celln2: the number of particles of the second species in the cellsigma_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 testedn_coll_performed: number of collisions actually performedn_eq_w_coll_performed: number of collisions between particles with equal weights actually performed
Merzbild.CollisionFactors — MethodCollisionFactors()Create an empty CollisionFactors instance (all values set to 0).
Merzbild.CollisionFactorsSWPM — TypeCollisionFactorsSWPMStructure 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 celln2: the number of particles of the second species in the cellsigma_g_max: estimate of the $(\sigma g)_{max}$ ($\sigma$ is the total collision cross-section, $g$ is the relative collision velocityn_coll: number of collisions to be testedn_coll_performed: number of collisions actually performed
Merzbild.CollisionFactorsSWPM — MethodCollisionFactorsSWPM()Create an empty CollisionFactorsSWPM instance (all values set to 0).
Merzbild.CollisionDataFP — TypeCollisionDataStructure to store temporary collision data for the particle Fokker-Planck approach.
Fields
vel_ave: average velocity of the particles in the cellmean: mean value of the sampled velocitiesstddev: standard deviation of the sampled velocitiesxvel_rand: pre-allocated storage for sampled x-velocity componentsyvel_rand: pre-allocated storage for sampled y-velocity componentszvel_rand: pre-allocated storage for sampled z-velocity components
Merzbild.CollisionDataFP — MethodCollisionDataFP()Create an empty CollisionDataFP instance.
Merzbild.CollisionDataFP — MethodCollisionDataFP(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_array — Functioncreate_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 flown_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 instanceinteractions: the 2-dimensional array ofInteractioninstances (of shape(n_species, n_species)) of all the pair-wise interactionsspecies_data: the vector ofSpeciesinstances of the species in the flowT_list: the list of temperatures of the speciesFnum: 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 instanceinteractions: the 2-dimensional array ofInteractioninstances (of shape(n_species, n_species)) of all the pair-wise interactionsspecies_data: the vector ofSpeciesinstances of the species in the flowT: the temperatures of the flowFnum: 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_array — Functioncreate_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 flown_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 instanceinteractions: the 2-dimensional array ofInteractioninstances (of shape(n_species, n_species)) of all the pair-wise interactionsspecies_data: the vector ofSpeciesinstances of the species in the flowT_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 instanceinteractions: the 2-dimensional array ofInteractioninstances (of shape(n_species, n_species)) of all the pair-wise interactionsspecies_data: the vector ofSpeciesinstances of the species in the flowT: 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_crosssections — Functioncreate_computed_crosssections(electron_neutral_interactions)Create a vector of ComputedCrossSection instances for the electron-neutral interactions.
Positional arguments
electron_neutral_interactions: theElectronNeutralInteractionsinstance for which the cross-sections will be computed
Returns
Vector of ComputedCrossSection of length electron_neutral_interactions.n_neutrals.
Merzbild.estimate_sigma_g_w_max — Functionestimate_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.
Positional arguments
interaction: theInteractioninstance for the interacting speciesspecies1: theSpeciesinstance of the first interacting speciesspecies2: theSpeciesinstance of the second interacting speciesT1: the temperature of the first interacting speciesT2: the temperature of the second interacting speciesFnum: 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: theInteractioninstance for the interacting speciesspecies: theSpeciesinstance of the interacting speciesT: the temperature of the interacting speciesFnum: 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! — Functionestimate_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 ofCollisionFactorsof shape(n_species, n_species, n_cells)interactions: the 2-dimensional array ofInteractioninstances (of shape(n_species, n_species)) of all the pair-wise interactionsspecies_data: the vector ofSpeciesinstances of the species in the flowT_list: the list of temperatures of the speciesFnum: 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 ofCollisionFactorsof shape(n_species, n_species, n_cells)interactions: the 2-dimensional array ofInteractioninstances (of shape(n_species, n_species)) of all the pair-wise interactionsspecies_data: the vector ofSpeciesinstances of the species in the flowT_list: the list of temperatures of the speciesFnum: 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! — Functionestimate_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 generatorcollision_factors: theCollisionFactorsfor the species in question in the cellcollision_data:CollisionDatainstance used for storing collisional quantitiesinteraction: 2-dimensional array ofInteractioninstances for all possible species pairsn_e_interactions: theElectronNeutralInteractionsinstancen_e_cs: theComputedCrossSectionsinstanceparticles_n:ParticleVectorof the particles of neutral speciesparticles_e:ParticleVectorof the particles of the electron speciespia: theParticleIndexerArraycell: the index of the cell in which collisions are performedspecies_n: the index of the neutral speciesspecies_e: the index of the electron speciesΔt: timestepV: cell volume
Keyword arguments:
min_coll: the minimum number of pairs to testn_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 ofCSExtendtype that sets how out-of-range energy values are treated when computing cross-sections
Merzbild.estimate_sigma_g_max! — Functionestimate_sigma_g_max!(collision_factors::Array{CollisionFactorsSWPM}, interactions, species_data, T_list, Fnum; 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 ofCollisionFactorsSWPMof shape(n_species, n_species, n_cells)interactions: the 2-dimensional array ofInteractioninstances (of shape(n_species, n_species)) of all the pair-wise interactionsspecies_data: the vector ofSpeciesinstances of the species in the flowT_list: the list of temperatures of the speciesFnum: the constant computational weight of the particles
Keyword arguments
mult_factor: a factor by which to multiply the result (default value is 1.0)
Merzbild.ntc! — Functionntc!(rng, collision_factors, collision_data, interaction, particles, pia,
cell, species, Δt, V)Perform elastic collisions between particles of same species using the NTC algorithm and the VHS cross-section model.
Positional arguments
rng: the random number generatorcollision_factors: theCollisionFactorsfor the species in question in the cellcollision_data:CollisionDatainstance used for storing collisional quantitiesinteraction: 2-dimensional array ofInteractioninstances for all possible species pairsparticles:ParticleVectorof the particles being collidedpia: theParticleIndexerArraycell: the index of the cell in which collisions are performedspecies: the index of the species for which collisions are performedΔt: timestepV: cell volume
References
- D.P. Schmidt, C.J. Rutland, A New Droplet Collision Algorithm. J. Comput. Phys, 2000.
ntc!(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 and the VHS cross-section model.
Positional arguments
rng: the random number generatorcollision_factors: theCollisionFactorsfor the species in question in the cellcollision_data:CollisionDatainstance used for storing collisional quantitiesinteraction: 2-dimensional array ofInteractioninstances for all possible species pairsparticles_1:ParticleVectorof the particles of the first species being collidedparticles_2:ParticleVectorof the particles of the second species being collidedpia: theParticleIndexerArraycell: the index of the cell in which collisions are performedspecies1: the index of the first species for which collisions are performedspecies1: the index of the second species for which collisions are performedΔt: timestepV: cell volume
References
- D.P. Schmidt, C.J. Rutland, A New Droplet Collision Algorithm. J. Comput. Phys, 2000.
Merzbild.ntc_n_e! — Functionntc_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)Perform electron-neutral elastic scattering and electron-impact ionization collisions.
Positional arguments
rng: the random number generatorcollision_factors: theCollisionFactorsfor the species in question in the cellcollision_data:CollisionDatainstance used for storing collisional quantitiesinteraction: 2-dimensional array ofInteractioninstances for all possible species pairsn_e_interactions: theElectronNeutralInteractionsinstancen_e_cs: theComputedCrossSectionsinstanceparticles_n:ParticleVectorof the particles of neutral speciesparticles_e:ParticleVectorof the particles of the electron speciesparticles_ion:ParticleVectorof the particles of the ion speciespia: theParticleIndexerArraycell: the index of the cell in which collisions are performedspecies_n: the index of the neutral speciesspecies_e: the index of the electron speciesspecies_ion: the index of the ion speciesΔt: timestepV: cell volume
Keyword arguments
extend: enum ofCSExtendtype that sets how out-of-range energy values are treated when computing cross-sections
References
- D.P. Schmidt, C.J. Rutland, A New Droplet Collision Algorithm. J. Comput. Phys, 2000.
Merzbild.ntc_n_e_es! — Functionntc_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)Perform electron-neutral elastic scattering and electron-impact ionization collisions using the event splitting method.
Positional arguments
rng: the random number generatorcollision_factors: theCollisionFactorsfor the species in question in the cellcollision_data:CollisionDatainstance used for storing collisional quantitiesinteraction: 2-dimensional array ofInteractioninstances for all possible species pairsn_e_interactions: theElectronNeutralInteractionsinstancen_e_cs: theComputedCrossSectionsinstanceparticles_n:ParticleVectorof the particles of neutral speciesparticles_e:ParticleVectorof the particles of the electron speciesparticles_ion:ParticleVectorof the particles of the ion speciespia: theParticleIndexerArraycell: the index of the cell in which collisions are performedspecies_n: the index of the neutral speciesspecies_e: the index of the electron speciesspecies_ion: the index of the ion speciesΔt: timestepV: cell volume
Keyword arguments
extend: enum ofCSExtendtype that sets how out-of-range energy values are treated when computing cross-sections
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! — Functionswpm!(rng, collision_factors_swpm, collision_data, interaction, particles, pia,
cell, species, G, Δt, V)Perform elastic collisions between variable-weight particles of same species using the SWPM algorithm and the VHS cross-section model. 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 generatorcollision_factors_swpm: theCollisionFactorsSWPMfor the species in question in the cellcollision_data:CollisionDatainstance used for storing collisional quantitiesinteraction: 2-dimensional array ofInteractioninstances for all possible species pairsparticles:ParticleVectorof the particles being collidedpia: theParticleIndexerArraycell: the index of the cell in which collisions are performedspecies: the index of the species for which collisions are performedG: non-negative value defining the weight transfer functionΔt: timestepV: cell volume
References
- S. Rjasanow, W.Wagner, Stochastic numerics for the Boltzmann equation. Springer Berlin, Heidelberg, 2005.
Fokker-Planck computations
Merzbild.fp_linear! — Functionfp_linear!(rng, collision_data_fp, interaction, species_data, particles, pia, cell, species, Δt, V)Model single-species elastic collisions using a linear Fokker-Planck approximation.
Positional arguments
rng: the random number generatorcollision_data_fp:CollisionDataFPinstance used for storing collisional quantitiesinteraction: 2-dimensional array ofInteractioninstances for all possible species pairsspecies_data: the vector ofSpeciesDataparticles:ParticleVectorof the particles being collidedpia: theParticleIndexerArraycell: the index of the cell in which collisions are performedspecies: the index of the species for which collisions are performedΔt: timestepV: 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.ElectronNeutralInteractions — TypeElectronNeutralInteractionsStructure 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 loadedneutral_indexer: array that maps indices of neutral species in the full list of species to local indices in theElectronNeutralInteractionsstructureelastic: an array ofElasticScatteringinstances (of lengthn_neutrals) holding the cross-section data on elastic scattering for each neutral speciesionization: an array ofIonizationinstances (of lengthn_neutrals) holding the cross-section data on electron-impact ionization for each neutral speciesexcitation_sink: an array ofExcitationSinkinstances (of lengthn_neutrals) holding the cross-section data on electron-impact electronic excitation for each neutral species
Merzbild.ComputedCrossSections — TypeComputedCrossSectionsStructure to hold data on computed cross-sections of electron-neutral interactions for a specific neutral species.
Fields
n_excitations: number of electron-impact excitation reactionscs_total: the computed total cross-section (sum of cross-sections of all processes)cs_elastic: the computed elastic scattering cross-sectioncs_ionization: the computed electron-impact ionization cross-sectioncs_excitation: the computed electron-impact electronic excitation cross-sectionprob_vec: a vector of probabilities of the processes (of length2+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 thcdf_prob_vec: a vector of cumulative probabilities of the processes (of length3+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.ElectronEnergySplit — TypeElectronEnergySplit ElectronEnergySplitEqual=1 ElectronEnergySplitZeroE=2Enum 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.ScatteringLaw — TypeScatteringLaw ScatteringIsotropic=1 ScatteringOkhrimovskyy=2Enum 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.CSExtend — TypeCSExtend CSExtendConstant=1 CSExtendZero=2Enum defining how to extend cross-sections in case energy is outside of tabulated range.
Possible values:
CSContinueConstant: continue with closest value in arrayCSContinueZero: continue with zero
Merging
Grid merging
Merzbild.GridN2Merge — TypeGridN2MergeStruct for merging 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 directionNy: number of grid cells in y velocity directionNz: number of grid cells in z velocity directionNyNz: product ofNyandNzNtotal: total number of grid cells (equal toNx*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 directionextent_v_lower: the lower bounds of the velocity grid in each velocity directionextent_v_upper: the upper bounds of the velocity grid in each velocity directionextent_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 directiondirection_vec: used to store randomly sampled direction signscells: vector ofGridCellinstances for each grid cell, as well as the external octants
Merzbild.GridN2Merge — MethodGridN2Merge(Nx::Int, Ny::Int, Nz::Int, extent_multiplier::T) where T <: AbstractArrayCreate velocity grid-based merging.
Positional arguments
Nx: number of cells in vx directionNy: number of cells in vy directionNz: number of cells in vz directionextent_multiplier: the vector of factors by which to multiply the thermal velocity to determine the grid bounds
in each velocity direction
Merzbild.GridN2Merge — MethodGridN2Merge(N::Int, extent_multiplier::T) where T <: AbstractArrayCreate velocity grid-based merging with equal number of cells in each direction.
Positional arguments
N: number of cells in each velocity directionextent_multiplier: the vector of factors by which to multiply the thermal velocity to determine the grid bounds
in each velocity direction
Merzbild.GridN2Merge — MethodGridN2Merge(Nx::Int, Ny::Int, Nz::Int, extent_multiplier::Float64)Create velocity grid-based merging with equal multipliers in each direction.
Positional arguments
Nx: number of cells in vx directionNy: number of cells in vy directionNz: number of cells in vz directionextent_multiplier: the factor by which to multiply the thermal velocity to determine the grid bounds
in each velocity direction
Merzbild.GridN2Merge — MethodGridN2Merge(Nx::Int, Ny::Int, Nz::Int,
extent_multiplier_x::Float64,
extent_multiplier_y::Float64,
extent_multiplier_z::Float64)Create velocity grid-based merging
Nx: number of cells in vx directionNy: number of cells in vy directionNz: number of cells in vz directionextent_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.GridN2Merge — MethodGridN2Merge(N::Int, extent_multiplier::Float64)Create velocity grid-based merging with equal number of cells in each direction and equal multipliers in each direction.
Positional arguments
N: number of cells in each velocity directionextent_multiplier: the factor by which to multiply the thermal velocity to determine the grid bounds
in each velocity direction
Merzbild.merge_grid_based! — Functionmerge_grid_based!(rng, merging_grid, particles, pia, cell, species, species_data, phys_props)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 instancemerging_grid: the grid merging (GridN2Merge) instance defining the velocity space gridparticles: theParticleVectorinstance of the particles to be mergedpia: theParticleIndexerArrayinstancecell: the cell indexspecies: the species indexspecies_data: the array ofSpeciesdataphys_props: thePhysPropsinstance 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.
NNLS merging
Merzbild.NNLSMerge — TypeNNLSMergeStruct for keeping track of merging-related quantities for NNLS-based merging.
Fields
v0: vector of the mean velocity of the particlesx0: vector of the mean position of the particlesvref: reference velocity magnitude for scalinginv_vref: inverse of reference velocity magnitude for scalingEx: standard deviation of x velocity of particlesEy: standard deviation of y velocity of particlesEz: standard deviation of z velocity of particlesEpx: standard deviation of x position of particlesEpy: standard deviation of y position of particlesEpz: standard deviation of z position of particlesw_total: total computational of the particlesminvx: minimum x velocity of the particlesmaxvx: maximum x velocity of the particlesminvy: minimum y velocity of the particlesmaxvy: maximum y velocity of the particlesminvz: minimum z velocity of the particlesmaxvz: maximum z velocity of the particlesscalevx: value used to scale the x velocity of particlesscalevy: value used to scale the y velocity of particlesscalevz: value used to scale the z velocity of particlesscalex: value used to scale the x position of particlesscaley: value used to scale the y position of particlesscalez: value used to scale the z position of particlesn_total_conserved: total number of moments conservedn_moments_vel: number of velocity moments to preserverhs_vector: vector of computed momentsresidual: residual of solutionmim: vector of 3-tuples of multi-indices for the velocity moments to preservetot_order: vector of total orders of the velocity moments to preserven_moments_pos: number of spatial moments to preservemim_pos: vector of 3-tuples of multi-indices for the spatial moments to preservetot_order_pos: vector of total orders of the spatial moments to preservepos_i_x: index of the spatial moment corresponding to preservation of the center of mass in the x directionpos_i_y: index of the spatial moment corresponding to preservation of the center of mass in the y directionpos_i_z: index of the spatial moment corresponding to preservation of the center of mass in the z directionlhs_matrices: Vector of matrices for the LHS of the NNLS systemlhs_matrix_ncols_start: the number of columns in the first matrix inlhs_matriceslhs_matrix_ncols_end: the number of columns in the last matrix inlhs_matricescolumn_norms: vector of vectors of the column-wise inverse norms of the LHS matricesvel_pos_matrices: vector of matrices of size6xNpthat store the velocities and positions of the particleswork: Vector ofNNLSWorkspaceinstances
Merzbild.NNLSMerge — MethodNNLSMerge(multi_index_moments, init_np; rate_preserving=false, multi_index_moments_pos=[], matrix_ncol_nprealloc=0)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, and no LHS matrices are pre-allocated. 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 matrices and corresponding workspaces with a fixed number of columns spanning [init_np, init_np+matrix_ncol_nprealloc]. In this case, matrix_ncol_nprealloc+1 NNLSWorkspace instances are pre-allocated, with the last one being used in case the number of columns is not in the range (and the LHS matrix is constructed on the fly). A vector column_norms is also then pre-allocated, which is a vector of vectors, each containing the inverses of the column-wise norms of the LHS matrices, used for their scaling.
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 ratesmulti_index_moments_pos: list of spatial moments to preservematrix_ncol_nprealloc: number of LHS matrices and NNLS workspaces with a fixed number of columns to pre-allocate
Merzbild.compute_multi_index_moments — Functioncompute_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! — Functionmerge_nnls_based!(rng, nnls_merging, particles, pia, cell, species, vref; n_rand_pairs=0, max_err=1e-11,
centered_at_mean=true, v_multipliers=[0.5, 1.0], iteration_mult=2)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.
To improve stability, additional fictitious particles can be created by randomly choosing particle pairs and creating new particles with a velocity and position that is a mean of the velocity and position of the randomly chosen pair; these particles are added as additional columns to the matrix. An additional fictitious particle can be created at the local mean velocity via the centered_at_mean parameter. Additionally, particles can be created with velocities that are a multiple of the computed velocity variance of the system of pre-merge particles in each direction. For a given variance multiplier (an entry in the v_multipliers parameter, which is a vector of multipliers), 8 particles are added, one in each octant. Each of the particles velocity components is given either by the value of the multiplier times the velocity variance of that component (times +1 or -1 depending on the octant), or, if this value is outside of the bounding box, the closest bounding value of the velocity component in that direction is used instead and also multiplied by the variance multiplier.
Positional arguments
rng: the random number generator instancennls_merging: theNNLSMergeinstanceparticles: theParticleVectorinstance containing the particles to be mergedpia: theParticleIndexerArrayinstancecell: the index of the grid cell in which particles are being mergedspecies: the index of the species being merged
Keyword arguments
vref: the reference velocity used to scale the velocitiesscaling: how to scale entries in the LHS and RHS of the NNLS system - either based on the reference velocityvref(scaling=:vref) or on the computed variances in each direction (scaling=:variance)n_rand_pairs: the number of additional random pairs to sample to create additional entries in the matrix to potentially improve the stability of the algorithmmax_err: maximum allowed value of the residual of the NNLS systemcentered_at_mean: whether to add a particle centered at the mean velocity of the system of particlesv_multipliers: the multipliers for the velocity variances of the particles to add aditional particles to the systemiteration_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 algorithmw_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, A Non-Negative Least Squares-based Approach for Moment-Preserving Particle Merging. arXiv preprint, 2025.
Merzbild.merge_nnls_based_rate_preserving! — Functionmerge_nnls_based_rate_preserving!(rng, nnls_merging,
interaction, electron_neutral_interactions, computed_cs,
particles, pia, cell, species, neutral_species_index,
ref_cs_elatic, ref_cs_ion; scaling=:variance,
vref=1.0, n_rand_pairs=0, max_err=1e-11,
centered_at_mean=true, v_multipliers=[0.5, 1.0], iteration_mult=2,
extend::CSExtend=CSExtendConstant)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.
To improve stability, additional fictitious particles can be created by randomly choosing particle pairs and creating new particles with a velocity and position that is a mean of the velocity and position of the randomly chosen pair; these particles are added as additional columns to the matrix. An additional fictitious particle can be created at the local mean velocity via the centered_at_mean parameter. Additionally, particles can be created with velocities that are a multiple of the computed velocity variance of the system of pre-merge particles in each direction. For a given variance multiplier (an entry in the v_multipliers parameter, which is a vector of multipliers), 8 particles are added, one in each octant. Each of the particles velocity components is given either by the value of the multiplier times the velocity variance of that component (times +1 or -1 depending on the octant), or, if this value is outside of the bounding box, the closest bounding value of the velocity component in that direction is used instead and also multiplied by the variance multiplier. 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.
Positional arguments
rng: the random number generator instancennls_merging: theNNLSMergeinstanceinteraction: theInteractioninstance describing the electron-neutral interaction being consideredelectron_neutral_interactions: theElectronNeutralInteractionsinstance storing the tabulated cross-section data used to compute the ratescomputed_cs: the vector ofComputedCrossSectioninstances in which the computed values will be storedparticles: theParticleVectorinstance containing the particles to be mergedpia: theParticleIndexerArrayinstancecell: the index of the grid cell in which particles are being mergedspecies: the index of the species being mergedneutral_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_elatic: the reference elastic scattering cross-section used to scale the rates (currently not used)ref_cs_ion: the reference electron-impact ionization cross-section used to scale the rates (currently not used)
Keyword arguments
vref: the reference velocity used to scale the velocities in the case ofscaling=:vrefscaling: how to scale entries in the LHS and RHS of the NNLS system - either based on the reference velocityvref(scaling=:vref) or on the computed variances in each direction (scaling=:variance)n_rand_pairs: the number of additional random pairs to sample to create additional entries in the matrix to potentially improve the stability of the algorithmmax_err: maximum allowed value of the residual of the NNLS systemcentered_at_mean: whether to add a particle centered at the mean velocity of the system of particlesv_multipliers: the multipliers for the velocity variances of the particles to add aditional particles to the systemiteration_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 algorithmw_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 ofCSExtendtype 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, A Non-Negative Least Squares-based Approach for Moment-Preserving Particle Merging. arXiv preprint, 2025.
Octree merging
Merzbild.OctreeBinSplit — TypeOctreeBinSplit OctreeBinMidSplit=1 OctreeBinMeanSplit=2 OctreeBinMedianSplit=3Enum defining how the velocity along which the bin is split is chosen.
Possible values:
OctreeBinMidSplit: the bin is split along the middle velocityOctreeBinMeanSplit: the bin is split along the mean velocity of the particles in the binOctreeBinMedianSplit: the bin is split along the median velocity of the particles in the bin
Merzbild.OctreeInitBin — TypeOctreeInitBin OctreeInitBinMinMaxVel=1 OctreeInitBinMinMaxVelSym=2 OctreeInitBinC=3Enum 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 boundsOctreeInitBinMinMaxVelSym: 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.OctreeBinBounds — TypeOctreeBinBounds OctreeBinBoundsInherit=1 OctreeBinBoundsRecompute=2Enum 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 inheritedOctreeBinBoundsRecompute: the bounds are recomputed based on the particles in the bin
Merzbild.OctreeN2Merge — TypeOctreeN2MergeStruct for N:2 Octree merging.
Fields
max_Nbins: maximum possible number of binsNbins: number of bins currently usedbins: Vector ofOctreeCellinstances used to compute the properties required for bin refinementfull_bins: Vector ofOctreeFullCellinstances used to compute the post-merge particles in each binn_particles: total number of particles being mergedbin_start: denotes start of indices of particles in biniin theparticle_indexes_sortedarraybin_end: denotes end of indices of particles in biniin theparticle_indexes_sortedarrayparticle_indexes_sorted: Vector of particle indices of the particles being mergedparticle_octants: Vector of particle octants for each particle used during radix sortparticles_sort_output: Vector of integer indices used to store particle indices during radix sortparticle_in_bin_counter:MVectorof size 8, stores the number of particles in each binnonempty_counter:MVectorof size 8, stores the number of particles in each non-empty bin (the octants to which these bins correspond to are innonempty_bins)nonempty_bins:MVectorof size 8, a sequential list of non-empty octantsndens_counter:MVectorof size 8, used in bin splitting, stores number density in each (non-empty) binbin_bounds_compute: enum ofOctreeBinBoundstype 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 binsplit: enum ofOctreeBinSplittype defining how bins are splitvel_middle: used to store the velocity along which a bin is split into octantsv_min_parent: used in bin splitting to store the vector of the per-component lower bounds of the velocities in the cellv_max_parent: used in bin splitting to store the vector of the per-component upper bounds of the velocities in the celldirection_vec: used to store randomly sampled direction signsinit_bin_bounds: enum ofOctreeInitBintype defining how the bounds of the top-level bin are setmax_depth: maximum allowed depth of a bintotal_post_merge_np: used to keep track of number of post-merge particles
Merzbild.OctreeN2Merge — MethodOctreeN2Merge(split::OctreeBinSplit; init_bin_bounds=OctreeInitBinMinMaxVel, bin_bounds_compute=OctreeBinBoundsInherit,
max_Nbins=4096, max_depth=10)Create an Octree N:2 merging instance.
Positional arguments:
split: a enum ofOctreeBinSplittype which tells how to split a bin into sub-bins
Keyword arguments:
init_bin_bounds: a enum ofOctreeInitBintype which defines how the bounds of the top-level bin are setbin_bounds_compute: a enum ofOctreeBinBoundstype 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 splitmax_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: OctreeN2Merge instance with everything set to 0.
Merzbild.merge_octree_N2_based! — Functionmerge_octree_N2_based!(rng, octree, particles, pia, cell, species, target_np)Perform octree N:2 merging without checking whether particle positions end up outside of the simulation domain.
Positional arguments
rng: the random number generator instanceoctree: theOctreeN2Mergeinstanceparticles: theParticleVectorinstance containing the particles to be mergedpia: theParticleIndexerArrayinstancecell: the index of the grid cell in which particles are being mergedspecies: the index of the species being mergedtarget_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
- R.S. Martin, J.-L. Cambier, Octree particle management for DSMC and PIC simulations. J. Comput. Phys., 2016.
merge_octree_N2_based!(rng, octree, particles, pia, cell, species, target_np, grid)Perform octree N:2 merging, checking whether particle positions end up outside of the simulation domain, and pushing them back into the domain if needed.
Positional arguments
rng: the random number generator instanceoctree: theOctreeN2Mergeinstanceparticles: theParticleVectorinstance containing the particles to be mergedpia: theParticleIndexerArrayinstancecell: the index of the grid cell in which particles are being mergedspecies: the index of the species being mergedtarget_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 itgrid: theGrid1DUniformgridR.S. Martin, J.-L. Cambier, Octree particle management for DSMC and PIC simulations. J. Comput. Phys., 2016.
Roulette merging
Merzbild.merge_roulette! — Functionmerge_roulette!(rng, particles, pia, cell, species, target_np)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 instanceparticles: theParticleVectorinstance containing the particles to be mergedpia: theParticleIndexerArrayinstancecell: the index of the grid cell in which particles are being mergedspecies: the index of the species being mergedtarget_np: the target post-merge number of particles
Keyword arguments
conservative: iftrue, 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.AbstractGrid — TypeAbstractGridAbstract grid type
Merzbild.Grid1DUniform — TypeGrid1DUniform1-D Uniform grid for a domain $[0,L]$
Fields
L: length of the domainnx: number of cellsΔx: cell sizeinv_Δx: inverse of cell sizecells:VectorofCell1Delementsmin_x: minimum allowedxcoordinate for particles (slightly larger than $0$)max_x: maximum allowedxcoordinate for particles (slightly smaller than $L$)
Merzbild.Grid1DUniform — MethodGrid1DUniform(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 domainnx: 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 the1:nxrange. The offset is computed asΔx * wall_offset, whereΔxis the cell size.
Merzbild.GridSortInPlace — TypeGridSortInPlaceStruct for in-place sorting of particles.
Fields
cell_counts: vector to store the number of particles in each cell + number of particles in all previous cellssorted_indices: vector to store sorted particle indices
Merzbild.GridSortInPlace — MethodGridSortInPlace(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 cellsn_particles: the (expected) number of particles in the simulation (to pre-allocate thesorted_indicesvector) - 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.GridSortInPlace — MethodGridSortInPlace(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 particlesn_particles: the (expected) number of particles in the simulation (to pre-allocate thesorted_indicesvector) - 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! — Functionsort_particles!(gridsort::GridSortInPlace, grid, 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).
Positional arguments
gridsort: theGridSortInPlacestructuregrid: the grid (should have ann_cellsfield, and aget_cellfunction has to be defined for the grid type)particles: theParticleVectorof particles to be sortedpia: theParticleIndexerArrayinstancespecies: the index of the species being sorted
Particle movement
Merzbild.convect_particles! — Functionconvect_particles!(rng, grid::Grid1DUniform, boundaries::MaxwellWalls1D, particles, pia, species, species_data, Δt)Convect particles on a 1-D uniform grid.
Positional arguments
rng: the random number generatorgrid: the grid on which the convection is performedboundaries: theMaxwellWalls1Dstruct describing the boundaries (it is assumed that the wall with index 1 is the left wall and the wall with index 2 is the right wall)particles: theParticleVectorof particles to be convectedpia: theParticleIndexerArrayinstancespecies: the index of the species being convectedspecies_data: the vector ofSpeciesdataΔt: the convection timestep
convect_particles!(rng, grid::Grid1DUniform, boundaries::MaxwellWalls1D, surf_props::SurfProps, particles, pia, species, species_data, Δt)Convect particles on a 1-D uniform grid, computing surface properties if particles hit a surface.
Positional arguments
rng: the random number generatorgrid: the grid on which the convection is performedboundaries: theMaxwellWalls1Dstruct describing the boundaries (it is assumed that the wall with index 1 is the left wall and the wall with index 2 is the right wall)particles: theParticleVectorof particles to be convectedpia: theParticleIndexerArrayinstancespecies: the index of the species being convectedspecies_data: the vector ofSpeciesdatasurf_props: theSurfPropsstruct where the computed surface properties will be storedΔt: the convection timestep
Particle-surface interactions
Merzbild.MaxwellWallBC — TypeMaxwellWallBCA struct to hold information about a diffuse reflecting wall.
Fields
T: temperaturev: wall velocity vectoraccommodation: accommodation coefficient (a value of 0 corresponds to specular reflection, a value of 1 corresponds to purely diffuse reflection)
Merzbild.MaxwellWalls1D — TypeMaxwellWalls1DA struct to hold information about all diffuse reflecting walls in the simulation.
Fields
boundaries: a vector ofMaxwellWallBCwallsreflection_velocities_sq: array of pre-computed squared thermal reflection velocities (nwalls x nspecies)
Merzbild.MaxwellWalls1D — MethodMaxwellWalls1D(species_data, T_l::Float64, T_r::Float64, vy_l::Float64, vy_r::Float64, accomodation_l::Float64, accomodation_r::Float64)Create a MaxwellWalls1D struct for a 1-D simulation with 2 walls ("left" and "right") with a velocity in the y-direction only.
Positional arguments
species_data: vector ofSpeciesdataT_l: temperature of left wallT_r: temperature of right wallvy_l: y-velocity of left wallvy_r: y-velocity of right wallaccomodation_l: accommodation coefficient of left wallaccomodation_r: accommodation coefficient of right wall
I/O
Merzbild.write_grid — Functionwrite_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 filegrid: 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.IOSkipList — TypeIOSkipListStruct 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 skippedskip_moments: whether the output of the total moments should be skippedskip_number_of_particles: whether the output of the number of particles should be skippedskip_number_density: whether the output of the number density/number of physical particles should be skippedskip_velocity: whether the output of the velocity should be skippedskip_temperature: whether the output of the temperature should be skipped
Merzbild.IOSkipList — MethodIOSkipList(list_of_variables_to_skip)Construct an IOSkipList from a list of variable names. The possible names are: length_particle_array, moments, np or nparticles, ndens, v, T.
Positional arguments
list_of_variables_to_skip: list of variable names to skip
Merzbild.IOSkipList — MethodIOSkipList()Construct an empty IOSkipList.
Merzbild.IOSkipListSurf — TypeIOSkipListSurfStruct 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 skippedskip_fluxes: whether the output of the incident/reflected fluxes should be skippedskip_force: whether the output of the force should be skippedskip_normal_pressure: whether the output of the normal pressure should be skippedskip_shear_pressure: whether the output of the shear pressure should be skippedskip_kinetic_energy_flux: whether the output of the kinetic energy flux should be skipped
Merzbild.IOSkipListSurf — MethodIOSkipListSurf(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.IOSkipListSurf — MethodIOSkipListSurf()Construct an empty IOSkipListSurf
Merzbild.IOSkipListFlux — TypeIOSkipListFluxStruct 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 skippedskip_diagonal_momentum_flux: whether the output of the diagonal components of the momentum flux tensor should be skippedskip_off_diagonal_momentum_flux: whether the output of the off-diagonal components of the momentum flux tensor should be skipped
Merzbild.IOSkipListFlux — MethodIOSkipListFlux(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.IOSkipListFlux — MethodIOSkipListFlux()Construct an empty IOSkipListFlux
Merzbild.NCDataHolder — TypeNCDataHolder <: AbstractNCDataHolderStruct that holds NetCDF-output related data for physical properties (grid properties) I/O.
Fields
filehandle: handle to the open NetCDF filendens_not_Np: whether the number density or the number of physical particles is being outputtimestep_dim: timestep dimension that used to keep track of the number of output stepsv_spn: variable to hold species' names (dimensionn_species)v_timestep: variable to hold the simulation timestep number (dimensiontime)v_lpa: variable to hold lengths of particle arrays (dimensionn_species x time)v_mompows: variable to hold list of total moment powers (dimensionn_moments)v_moments: variable to hold total moments (dimensionn_moments x n_cells x n_species x time)v_np: variable to hold number of particles (dimensionn_cells x n_species x time)v_ndens: variable to hold number density or the number of physical particles (dimensionn_cells x n_species x time)v_v: variable to hold velocity (dimension3 x n_cells x n_species x time)v_T: variable to hold temperature (dimensionn_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], wheren_t_outputis 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], wheren_t_outputis 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], wheren_t_outputis 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], wheren_t_outputis 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 timestepskip_list:IOSkipListinstance of variables to skip during output
Merzbild.NCDataHolder — MethodNCDataHolder(nc_filename, names_skip_list, species_data, phys_props; global_attributes=Dict{Any,Any}())Construct a NCDataHolder instance with a list of variables to skip.
Positional arguments
nc_filename: filename to write output tonames_skip_list: list of variable names to skip, seeIOSkipListfor more detailsspecies_data: the vector ofSpeciesdata for the species in the simulationphys_props: thePhysPropsinstance 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
Merzbild.NCDataHolder — MethodNCDataHolder(nc_filename, species_data, phys_props; global_attributes=Dict{Any,Any}())Construct a NCDataHolder instance with an empty list of variable to skip,
Positional arguments
nc_filename: filename to write output tospecies_data: the vector ofSpeciesdata for the species in the simulationphys_props: thePhysPropsinstance 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
Merzbild.NCDataHolderSurf — TypeNCDataHolderSurfStruct that holds NetCDF-output related data for surface properties I/O.
Fields
filehandle: handle to the open NetCDF filetimestep_dim: timestep dimension that used to keep track of the number of output stepsv_spn: variable to hold species' names (dimensionn_species)v_timestep: variable to hold the simulation timestep number (dimensiontime)v_np: variable to hold number of particles that hit the surface (dimensionn_elements x n_species x time)v_flux_incident: variable to hold incident mass flux (dimensionn_elements x n_species x time)v_flux_reflected: variable to hold reflected mass flux (dimensionn_elements x n_species x time)v_force: variable to hold force (dimension3 x n_elements x n_species x time)v_normal_pressure: variable to hold normal pressure (dimensionn_elements x n_species x time)v_shear_pressure: variable to hold shear pressure (dimension3 x n_elements x n_species x time)v_kinetic_energy_flux: variable to hold kinetic energy flux (dimensionn_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], wheren_t_outputis 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], wheren_t_outputis 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], wheren_t_outputis 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], wheren_t_outputis 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 timestepskip_list:IOSkipListSurfinstance of variables to skip during output
Merzbild.NCDataHolderSurf — MethodNCDataHolderSurf(nc_filename, names_skip_list, species_data, surf_props; global_attributes=Dict{Any,Any}())Construct a NCDataHolderSurf instance with a list of variables to skip.
Positional arguments
nc_filename: filename to write output tonames_skip_list: list of variable names to skip, seeIOSkipListSurffor more detailsspecies_data: the vector ofSpeciesdata for the species in the simulationsurf_props: theSurfPropsinstance 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
Merzbild.NCDataHolderSurf — MethodNCDataHolderSurf(nc_filename, species_data, surf_props; global_attributes=Dict{Any,Any}())Construct a NCDataHolderSurf instance with an empty list of variable to skip.
Positional arguments
Positional arguments
nc_filename: filename to write output tospecies_data: the vector ofSpeciesdata for the species in the simulationsurf_props: theSurfPropsinstance 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
Merzbild.NCDataHolderFlux — TypeNCDataHolderFluxStruct that holds NetCDF-output related data for fluxes I/O.
Fields
filehandle: handle to the open NetCDF filetimestep_dim: timestep dimension that used to keep track of the number of output stepsv_spn: variable to hold species' names (dimensionn_species)v_timestep: variable to hold the simulation timestep number (dimensiontime)v_kinetic_energy_flux: variable to hold kinetic energy flux (dimension3 x n_elements x n_species x time)v_diagonal_momentum_flux: variable to the diagonal components of the momentum flux tensor (dimension3 x n_elements x n_species x time)v_off_diagonal_momentum_flux: variable to the off-diagonal components of the momentum flux tensor (dimension3 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], wheren_t_outputis 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], wheren_t_outputis 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 timestepskip_list:IOSkipListFluxinstance of variables to skip during output
Merzbild.NCDataHolderFlux — MethodNCDataHolderFlux(nc_filename, names_skip_list, species_data, flux_props; global_attributes=Dict{Any,Any}())Construct a NCDataHolderFlux instance with a list of variables to skip.
Positional arguments
nc_filename: filename to write output tonames_skip_list: list of variable names to skip, seeIOSkipListSurffor more detailsspecies_data: the vector ofSpeciesdata for the species in the simulationflux_props: theFluxPropsinstance 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
Merzbild.NCDataHolderFlux — MethodNCDataHolderFlux(nc_filename, species_data, flux_props; global_attributes=Dict{Any,Any}())Construct a NCDataHolderFlux instance with an empty list of variable to skip.
Positional arguments
Positional arguments
nc_filename: filename to write output tospecies_data: the vector ofSpeciesdata for the species in the simulationflux_props: theFluxPropsinstance 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
Merzbild.write_netcdf — Function 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: theNCDataHolderfor the file to which the output will be writtenphys_props: thePhysPropsinstance containing the computed propertiestimestep: the simulation timestep
Keyword arguments
sync_freq: if larger than 0 and if the number of timesteps output is proportional tosync_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: theNCDataHolderSurffor the file to which the output will be writtensurf_props: theSurfPropsinstance containing the computed propertiestimestep: the simulation timestep
Keyword arguments
sync_freq: if larger than 0 and if the number of timesteps output is proportional tosync_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: theNCDataHolderFluxfor the file to which the output will be writtenflux_props: theFluxPropsinstance containing the computed propertiestimestep: the simulation timestep
Keyword arguments
sync_freq: if larger than 0 and if the number of timesteps output is proportional tosync_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, pv::ParticleVector, pia, species, species_data; global_attributes=Dict{Any,Any}())Write particles of a single species 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.
Positional arguments
nc_filename: filename to write output topv: theParticleVectorinstances of particles to be writtenpia: theParticleIndexerArrayinstancespecies: the index of the species being writtenspecies_data: the vector ofSpeciesdata for the species in the simulation
Keyword arguments
global_attributes: dictionary of any additional attributes to write to the netCDF file as a global attribute
write_netcdf(nc_filename, particles::Vector{ParticleVector}, pia, species_data; global_attributes=Dict{Any,Any}())Write particles of all species 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.
Positional arguments
nc_filename: filename to write output topv: theParticleVectorinstances of particles to be writtenpia: theParticleIndexerArrayinstancespecies: the index of the species being writtenspecies_data: the vector ofSpeciesdata for the species in the simulation
Keyword arguments
global_attributes: dictionary of any additional attributes to write to the netCDF file as a global attribute
Merzbild.close_netcdf — Functionclose_netcdf(ds::AbstractNCDataHolder)Close NetCDF file.
Positional arguments
ds: anAbstractNCDataHolderinstance to close.
Parallel computations
Merzbild.ChunkExchanger — TypeChunkExchangerStruct 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 n_local field of ParticleIndexer is left unused.
Group 1 of ParticleIndexer[chunk_id,cell] holds the range of particles that belong to cell cell that came from a particle chunk chunk_id via swapping.
Group 2 of ParticleIndexer[chunk_id,cell] holds the range of particles that belong to cell cell that came from a particle chunk chunk_id via pushing, i.e. they have been added to the end of the particle array.
Fields
n_chunks: number of chunks used in the simulationn_cells: number of grid cells in the simulationindexer: array ofParticleIndexerinstances of shape(n_chunks, n_cells)
Merzbild.ChunkExchanger — MethodChunkExchanger(chunks, n_cells)Create a ChunkExchanger for length(chunks) chunks and n_cells cell.
Positional arguments
chunks: list of cell chunksn_cells: total number of cells in the simulation
Merzbild.exchange_particles! — Functionexchange_particles!(chunk_exchanger, particles_chunks, pia_chunks, cell_chunks, species)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: theChunkExchangerinstance to track post-swap and post-push indicesparticles_chunks: Vector of Vector ofParticleVector(per chunk and per species, i.e.particles_chunks[chunk_id][species]is the correct order of access)pia_chunks: Vector ofParticleIndexerArrayinstances for each chunkcell_chunks: cell ownership list for each chunk, i.e.cell_chunks[chunk_id]is a list of cells belonging to chunkchunk_id; the cells withincell_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] + 1species: the particle species being redistributed
Merzbild.sort_particles_after_exchange! — Functionsort_particles_after_exchange!(chunk_exchanger, gridsort, particles, pia, cell_chunk, species)Restore indexing of a ParticleVector and the associated ParticleIndexerArray after particles have been swapped and pushed between chunks.
Positional arguments
chunk_exchanger: theChunkExchangerinstance used to track post-swap and post-push indicesgridsort: TheGridSortInPlaceassociated with the chunkparticles_chunks: theParticleVectorfor which to restore the indexingpia: theParticleIndexerArrayinstances associated with the chunkcell_chunk: list or range of cells belonging to the chunkspecies: the particle species being for which the indexing is being restored
Merzbild.reset! — Functionreset!(chunk_exchanger, chunk_id)Reset all indexing of chunk_exchanger.indexer[chunk_id,:].
Positional arguments
chunk_exchanger: theChunkExchangerinstancechunk_id: the chunk for which to reset indexing
Merzbild.reduce_surf_props! — Functionreduce_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: theSurfPropsinstance which will hold the reduced valuessurf_props_chunks: the listSurfPropsinstances to use for the reduction operation
Particle-in-Cell
Merzbild.accelerate_constant_field_x! — Functionaccelerate_constant_field_x!(particles, pia, cell, species, species_data, E, Δt)Accelerate particles with a constant electric field in the X direction
Positional arguments
particles: vector-like structure of particles to be acceleratedpia: ParticleIndexerArray instancecell: index of the cell in which particles are being acceleratedspecies: index of the species of the particles being acceleratedspecies_data: aVector{Species}instance with the species' dataE: value of the electric field in V/mΔt: timestep for which the acceleration is performed
Constants
Merzbild.k_B — ConstantBoltzmann constant, J/K
Misc
Merzbild.DataMissingException — TypeDataMissingExceptionException for the case of missing tabulated cross-section data
Fields
msg: error message