Particles#
A solver for modelling particles.
particles.particles
implementation and use#
We import the basic particles module functionality as:
import particles.particles as particles
The particles solver is made up of two classes:
Particle
, which holds the data about a single particle (its position and velocity);Particles
, which holds the data about a collection of particles.
The particles are stored as a dictionary, and their positions are updated
based on the velocity on the grid. The keys are tuples of the particles’
initial positions (however the values of the keys themselves are never used
in the module, so this could be altered using e.g. a custom particle_generator
function without otherwise affecting the behaviour of the module).
The particles can be initialized in a number of ways:
randomly_generate_particles
, which randomly generatesn_particles
within the domain.grid_generate_particles
, which will generate approximatelyn_particles
equally spaced in the x-direction and y-direction (note that it uses the same number of particles in each direction, so the spacing will be different in each direction if the domain is not square). The number of particles will be increased/decreased in order to fill the whole domain.array_generate_particles
, which generates particles based on array of particle positions passed to the constructor.The user can define their own
particle_generator
function and pass this into theParticles
constructor. This function takes the number of particles to be generated and returns a dictionary ofParticle
objects.
We can turn on/off the particles solver using the following runtime parameters:
|
|
---|---|
|
do we want to model particles? (0=no, 1=yes) |
|
number of particles to be modelled |
|
how do we initialize the particles? “random”
randomly generates particles throughout the domain,
“grid” generates equally spaced particles, “array”
generates particles at positions given in an array
passed to the constructor. This option can be
overridden by passing a custom generator function to
the |
Using these runtime parameters, we can initialize particles in a problem using
the following code in the solver’s Simulation.initialize
function:
if self.rp.get_param("particles.do_particles") == 1:
n_particles = self.rp.get_param("particles.n_particles")
particle_generator = self.rp.get_param("particles.particle_generator")
self.particles = particles.Particles(self.cc_data, bc, n_particles, particle_generator)
The particles can then be advanced by inserting the following code after the
update of the other variables in the solver’s Simulation.evolve
function:
if self.particles is not None:
self.particles.update_particles(self.dt)
This will both update the positions of the particles and enforce the boundary conditions.
For some problems (e.g. advection), the x- and y- velocities must also be passed
in as arguments to this function as they cannot be accessed using the standard
get_var("velocity")
command. In this case, we would instead use
if self.particles is not None:
self.particles.update_particles(self.dt, u, v)
Plotting particles#
Given the Particles
object particles
, we can plot the particles by getting
their positions using
particle_positions = particles.get_positions()
In order to track the movement of particles over time, it’s useful to ‘dye’ the particles based on their initial positions. Assuming that the keys of the particles dictionary were set as the particles’ initial positions, this can be done by calling
colors = particles.get_init_positions()
For example, if we color the particles from white to black based on their initial
x-position, we can plot them on the figure axis ax
using the following code:
particle_positions = particles.get_positions()
# dye particles based on initial x-position
colors = particles.get_init_positions()[:, 0]
# plot particles
ax.scatter(particle_positions[:, 0],
particle_positions[:, 1], s=5, c=colors, alpha=0.8, cmap="Greys")
ax.set_xlim([myg.xmin, myg.xmax])
ax.set_ylim([myg.ymin, myg.ymax])
Applying this to the Kelvin-Helmholtz problem with the compressible
solver,
we can produce a plot such as the one below, where the particles have been
plotted on top of the fluid density.