Skip to content

Commit 7c2be3f

Browse files
committed
Replace 'neighbors' with 'selection'
1 parent 61ff5b6 commit 7c2be3f

File tree

8 files changed

+73
-139
lines changed

8 files changed

+73
-139
lines changed

crates/velvet-core/src/lib.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ extern crate strum_macros;
1818
pub mod config;
1919
pub mod integrators;
2020
mod internal;
21-
pub mod neighbors;
2221
pub mod outputs;
2322
pub mod potentials;
2423
pub mod propagators;

crates/velvet-core/src/neighbors.rs

Lines changed: 0 additions & 70 deletions
This file was deleted.

crates/velvet-core/src/potentials/pair.rs

Lines changed: 42 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
//! Potentials which describe pairwise nonbonded interactions..
22
33
use crate::internal::Float;
4-
use crate::neighbors::NeighborList;
54
use crate::potentials::functions::{Buckingham, Harmonic, LennardJones, Mie, Morse};
65
use crate::potentials::Potential;
6+
use crate::selection::{setup_pairs_by_particle_type, update_pairs_by_cutoff_radius, Selection};
77
use crate::system::particle::ParticleType;
88
use crate::system::System;
99

@@ -93,89 +93,98 @@ impl PairPotential for Morse {
9393
}
9494
}
9595

96+
type PairSetupFn = fn(&System, (ParticleType, ParticleType)) -> Vec<[usize; 2]>;
97+
98+
type PairUpdateFn = fn(&System, &[[usize; 2]], Float) -> Vec<[usize; 2]>;
99+
100+
type PairSelection = Selection<PairSetupFn, (ParticleType, ParticleType), PairUpdateFn, Float, 2>;
101+
96102
pub(crate) struct PairPotentials {
97103
pub potentials: Vec<Box<dyn PairPotential>>,
98-
pub neighbor_lists: Vec<NeighborList>,
104+
pub selections: Vec<PairSelection>,
105+
pub particle_types: Vec<(ParticleType, ParticleType)>,
99106
pub cutoffs: Vec<Float>,
107+
pub thicknesses: Vec<Float>,
100108
pub update_frequency: usize,
101109
}
102110

103111
impl PairPotentials {
104112
pub fn setup(&mut self, system: &System) {
105-
self.neighbor_lists
113+
self.selections
106114
.iter_mut()
107-
.for_each(|nl| nl.setup(system));
115+
.zip(self.particle_types.iter().copied())
116+
.for_each(|(selection, particle_types)| selection.setup(system, particle_types))
108117
}
109118

110119
pub fn update(&mut self, system: &System) {
111-
// update neighbor lists
112-
self.neighbor_lists
120+
self.selections
113121
.iter_mut()
114-
.for_each(|nl| nl.update(system));
122+
.zip(self.cutoffs.iter())
123+
.zip(self.thicknesses.iter())
124+
.for_each(|((selection, cutoff), thickness)| {
125+
selection.update(system, cutoff + thickness)
126+
})
115127
}
116128
}
117129

118-
/// Convenient constructor for [`PairPotentials`].
119130
pub(crate) struct PairPotentialsBuilder {
120131
potentials: Vec<Box<dyn PairPotential>>,
121-
neighbor_lists: Vec<NeighborList>,
132+
selections: Vec<PairSelection>,
133+
particle_types: Vec<(ParticleType, ParticleType)>,
122134
cutoffs: Vec<Float>,
135+
thicknesses: Vec<Float>,
123136
update_frequency: usize,
124137
}
125138

126139
impl PairPotentialsBuilder {
127-
/// Returns a new `PairPotentialsBuilder`.
128140
pub fn new() -> PairPotentialsBuilder {
129141
PairPotentialsBuilder {
130142
potentials: Vec::new(),
131-
neighbor_lists: Vec::new(),
143+
selections: Vec::new(),
144+
particle_types: Vec::new(),
132145
cutoffs: Vec::new(),
146+
thicknesses: Vec::new(),
133147
update_frequency: 1,
134148
}
135149
}
136150

137-
/// Adds a new potential to the collection.
138-
pub fn pair<P>(
151+
pub fn update_frequency(mut self, freq: usize) -> PairPotentialsBuilder {
152+
self.update_frequency = freq;
153+
self
154+
}
155+
156+
pub fn pair<P: PairPotential + 'static>(
139157
mut self,
140158
potential: P,
141159
particle_types: (ParticleType, ParticleType),
142160
cutoff: Float,
143161
thickness: Float,
144-
) -> PairPotentialsBuilder
145-
where
146-
P: PairPotential + 'static,
147-
{
162+
) -> PairPotentialsBuilder {
148163
let potential = Box::new(potential);
149164
self.potentials.push(potential);
150-
let neighbor_list = NeighborList::new(cutoff + thickness, Some(particle_types));
151-
self.neighbor_lists.push(neighbor_list);
165+
let selection = Selection::new(
166+
setup_pairs_by_particle_type as PairSetupFn,
167+
update_pairs_by_cutoff_radius as PairUpdateFn,
168+
);
169+
self.selections.push(selection);
170+
self.particle_types.push(particle_types);
152171
self.cutoffs.push(cutoff);
172+
self.thicknesses.push(thickness);
153173
self
154174
}
155175

156-
/// Sets the number of iterations between each call to `update`.
157-
pub fn update_frequency(mut self, freq: usize) -> PairPotentialsBuilder {
158-
self.update_frequency = freq;
159-
self
160-
}
161-
162-
/// Consumes the builder and returns a new [`PairPotentials`] object.
163176
pub fn build(self) -> PairPotentials {
164177
PairPotentials {
165178
potentials: self.potentials,
166-
neighbor_lists: self.neighbor_lists,
179+
selections: self.selections,
180+
particle_types: self.particle_types,
167181
cutoffs: self.cutoffs,
182+
thicknesses: self.thicknesses,
168183
update_frequency: self.update_frequency,
169184
}
170185
}
171186
}
172187

173-
impl Default for PairPotentialsBuilder {
174-
fn default() -> Self {
175-
Self::new()
176-
}
177-
}
178-
179188
#[cfg(test)]
180189
mod tests {
181190
use super::{Buckingham, Harmonic, LennardJones, Mie, Morse, PairPotential};

crates/velvet-core/src/properties/energy.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,17 @@ impl Property for PairEnergy {
1818
#[cfg(not(feature = "rayon"))]
1919
fn calculate(&self, system: &System, potentials: &Potentials) -> Self::Res {
2020
let pair_potentials = &potentials.pair_potentials.potentials;
21-
let neighbor_lists = &potentials.pair_potentials.neighbor_lists;
21+
let selections = &potentials.pair_potentials.selections;
2222
let cutoffs = &potentials.pair_potentials.cutoffs;
2323

2424
pair_potentials
2525
.iter()
26-
.zip(neighbor_lists.iter())
26+
.zip(selections.iter())
2727
.zip(cutoffs.iter())
28-
.map(|((pot, nl), &cut)| -> Float {
29-
nl.indices()
30-
.iter()
31-
.map(|(i, j)| {
28+
.map(|((pot, select), &cut)| -> Float {
29+
select
30+
.indices()
31+
.map(|[i, j]| {
3232
let pos_i = &system.positions[*i];
3333
let pos_j = &system.positions[*j];
3434
let r = system.cell.distance(&pos_i, &pos_j);

crates/velvet-core/src/properties/forces.rs

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -20,29 +20,31 @@ impl Property for PairForces {
2020
// TODO: implement rayon version
2121
fn calculate(&self, system: &System, potentials: &Potentials) -> Self::Res {
2222
let pair_potentials = &potentials.pair_potentials.potentials;
23-
let neighbor_lists = &potentials.pair_potentials.neighbor_lists;
23+
let selections = &potentials.pair_potentials.selections;
2424
let cutoffs = &potentials.pair_potentials.cutoffs;
2525

2626
pair_potentials
2727
.iter()
28-
.zip(neighbor_lists.iter())
28+
.zip(selections.iter())
2929
.zip(cutoffs.iter())
30-
.map(|((pot, nl), &cut)| -> Vec<(Vector3<Float>, usize, usize)> {
31-
nl.indices()
32-
.iter()
33-
.map(move |(i, j)| {
34-
let pos_i = &system.positions[*i];
35-
let pos_j = &system.positions[*j];
36-
let r = system.cell.distance(&pos_i, &pos_j);
37-
if r < cut {
38-
let dir = system.cell.direction(&pos_i, &pos_j);
39-
(pot.force(r) * dir, *i, *j)
40-
} else {
41-
(Vector3::zeros(), *i, *j)
42-
}
43-
})
44-
.collect()
45-
})
30+
.map(
31+
|((pot, select), &cut)| -> Vec<(Vector3<Float>, usize, usize)> {
32+
select
33+
.indices()
34+
.map(move |[i, j]| {
35+
let pos_i = &system.positions[*i];
36+
let pos_j = &system.positions[*j];
37+
let r = system.cell.distance(&pos_i, &pos_j);
38+
if r < cut {
39+
let dir = system.cell.direction(&pos_i, &pos_j);
40+
(pot.force(r) * dir, *i, *j)
41+
} else {
42+
(Vector3::zeros(), *i, *j)
43+
}
44+
})
45+
.collect()
46+
},
47+
)
4648
.fold(
4749
vec![Vector3::zeros(); system.size],
4850
|mut accumulator, forces_metadata| {

crates/velvet-core/src/selection.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,7 @@ use crate::system::particle::ParticleType;
77
use crate::system::System;
88

99
/// Generic representation of a query of the system's indices.
10-
pub struct Selection<SFn, SArgs, UFn, UArgs, const N: usize>
11-
where
12-
SFn: Fn(&System, SArgs) -> Vec<[usize; N]>,
13-
UFn: Fn(&System, &[[usize; N]], UArgs) -> Vec<[usize; N]>,
14-
{
10+
pub struct Selection<SFn, SArgs, UFn, UArgs, const N: usize> {
1511
possible_indices: Vec<[usize; N]>,
1612
current_indices: Vec<[usize; N]>,
1713
setup_func: SFn,

crates/velvet-core/tests/selection.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,9 @@ fn setup_pairs_by_particle_type_update_pairs_by_cutoff_radius() {
1515
let mut selection = Selection::new(setup_pairs_by_particle_type, update_pairs_by_cutoff_radius);
1616
selection.setup(&system, particle_types);
1717
selection.update(&system, cutoff);
18-
for pairs in selection.indices() {
19-
let i = pairs[0];
20-
let j = pairs[1];
21-
assert_eq!(system.particle_types[system.particle_type_map[i]], argon);
22-
assert_eq!(system.particle_types[system.particle_type_map[j]], xenon);
18+
for [i, j] in selection.indices() {
19+
assert_eq!(system.particle_types[system.particle_type_map[*i]], argon);
20+
assert_eq!(system.particle_types[system.particle_type_map[*j]], xenon);
2321
}
2422
}
2523

src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//! Velvet is a classical atomistic simulation engine with a focus on user-friendliness and extensibility.
22
//!
33
//! This project is largely a learning exercise, but as development continues I hope to accomplish the following goals:
4-
//!
4+
//!
55
//! * Extensibility via user-defined plugin modules
66
//! * Optimized single CPU performace with multithreading and SIMD support
77
//! * Implement a wide variety of interatomic potentials

0 commit comments

Comments
 (0)