Two sets of particles

If the computation involves two sets of particles, a similar interface is available. The only difference is that the coordinates of the two sets must be provided to the ParticleSystem constructor as the xpositions and ypositions arrays.

Minimum-distance example

We will illustrate this interface by computing the minimum distance between two sets of particles, which allows us to showcase further the definition of custom type interfaces:

using CellListMap, StaticArrays

First, we define a variable type that will carry the indexes and the distance of the closest pair of particles:

struct MinimumDistance
    i::Int
    j::Int
    d::Float64
end

The function that, given two particles, retains the minimum distance, is:

function minimum_distance(pair, md)
    (; i, j, d) = pair
    if d < md.d
        md = MinimumDistance(i, j, d)
    end
    return md
end
minimum_distance (generic function with 1 method)

We overload copy, reset, and reducer functions, accordingly:

import CellListMap: copy_output, reset_output!, reducer!
copy_output(md::MinimumDistance) = md
copy_output (generic function with 6 methods)
reset_output!(md::MinimumDistance) = MinimumDistance(0, 0, +Inf)
reset_output! (generic function with 7 methods)
reducer!(md1::MinimumDistance, md2::MinimumDistance) = md1.d < md2.d ? md1 : md2
reducer! (generic function with 4 methods)

Note that since MinimumDistance is immutable, copying it is the same as returning the value. Also, resetting the minimum distance consists of setting its d field to +Inf. And, finally, reducing the threaded distances consists of keeping the pair with the shortest distance.

Cross-interactions with two cell lists

Next, we build the system. Here we choose to provide both sets of particles to the ParticleSystem constructor, which means that cell lists will be built for both sets:

xpositions = rand(SVector{3,Float64},1000);
ypositions = rand(SVector{3,Float64},1000);
system = ParticleSystem(
   xpositions = xpositions,
   ypositions = ypositions,
   unitcell=[1.0,1.0,1.0],
   cutoff = 0.1,
   output = MinimumDistance(0,0,+Inf),
   output_name = :minimum_distance,
)
ParticleSystem2{minimum_distance} of dimension 3, composed of:
    Box{CellListMap.OrthorhombicCell, 3}
      unit cell matrix = [ 1.0 0.0 0.0; 0.0 1.0 0.0; 0.0 0.0 1.0 ]
      cutoff = 0.1
      number of computing cells on each dimension = [13, 13, 13]
      computing cell sizes = [0.1, 0.1, 0.1] (lcell: 1)
      Total number of cells = 2197
    CellListMap.CellListPair{3, Float64}
       620 cells with real particles in reference set.
       624 cells with real particles in target set.
    Parallelization auxiliary data set for 10 batch(es).
    Type of output variable (minimum_distance): Main.MinimumDistance

And finally we can obtain the minimum distance between the sets:

pairwise!(minimum_distance, system)
Main.MinimumDistance(390, 363, 0.0029345821016581214)