Skip to content

Instantly share code, notes, and snippets.

@Luthaf
Created March 2, 2016 16:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Luthaf/12fc5e0cbbeae3cf31e4 to your computer and use it in GitHub Desktop.
Save Luthaf/12fc5e0cbbeae3cf31e4 to your computer and use it in GitHub Desktop.
Iterate over particles in a molecule with a pointer
use std::slice;
pub struct Vector3d([f64; 3]);
pub struct Atom {
pub position: Vector3d,
pub velocity: Vector3d,
pub name: String
}
impl Atom {
pub fn new(name: &str) -> Atom {
Atom {
position: Vector3d([0.0; 3]),
velocity: Vector3d([0.0; 3]),
name: String::from(name)
}
}
}
pub struct Molecule {
start: usize,
end: usize,
first: *mut Atom,
bonds: Vec<(usize, usize)>
}
impl Molecule {
pub fn new(atom: *mut Atom, index: usize) -> Molecule {
Molecule {
start: index,
end: index,
first: atom,
bonds: Vec::new()
}
}
pub fn size(&self) -> usize {
self.end - self.start + 1
}
pub fn atoms(&self) -> &[Atom] {
unsafe {
slice::from_raw_parts(self.first, self.size())
}
}
pub fn atoms_mut(&mut self) -> &mut [Atom] {
unsafe {
slice::from_raw_parts_mut(self.first, self.size())
}
}
pub fn merge(&mut self, other: Molecule) {
assert!(self.end + 1 == other.start);
self.end = other.end;
self.bonds.extend_from_slice(&other.bonds);
}
pub fn add_bond(&mut self, i: usize, j: usize) {
assert!(self.contains(i));
assert!(self.contains(j));
self.bonds.push((i, j));
}
pub fn contains(&self, i: usize) -> bool {
return self.start <= i && i <= self.end;
}
}
pub struct System {
atoms: Vec<Atom>,
molecules: Vec<Molecule>
}
impl System {
pub fn new() -> System {
System {
atoms: Vec::new(),
molecules: Vec::new(),
}
}
pub fn add_atom(&mut self, atom: Atom) {
self.atoms.push(atom);
let last_idx = self.atoms.len() - 1;
let last = &mut self.atoms[last_idx];
self.molecules.push(Molecule::new(last, last_idx))
}
pub fn molecules(&self) -> &[Molecule] {
&self.molecules
}
fn molecule_containing(&self, i: usize) -> usize {
for (j, mol) in self.molecules.iter().enumerate() {
if mol.contains(i) {
return j;
}
}
unreachable!()
}
pub fn add_bond(&mut self, i: usize, j: usize) {
let mol_i = self.molecule_containing(i);
let mol_j = self.molecule_containing(j);
if mol_i == mol_j {
self.molecules[mol_i].add_bond(i, j);
} else {
let (new_mol, _) = self.merge_molecules(mol_i, mol_j);
self.molecules[new_mol].add_bond(i, j);
}
}
fn merge_molecules(&mut self, _: usize, _: usize) -> (usize, usize) {
unimplemented!()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment