use crate::initiate::DeflagNewAtomsSystem;
use crate::integrator::AddOldForceToNewAtomsSystem;
use crate::output::file::BinaryConversion;
use crate::output::file::XYZPosition;
use crate::ramp::Lerp;
use crate::simulation::Plugin;
use nalgebra::Vector3;
use specs::prelude::*;
use serde::{Deserialize, Serialize};
use specs::{Component, NullStorage, System, VecStorage, World, WriteStorage};
use std::fmt;
#[derive(Deserialize, Serialize, Clone, Lerp)]
pub struct Position {
pub pos: Vector3<f64>,
}
impl Default for Position {
fn default() -> Self {
Self::new()
}
}
impl Position {
pub fn new() -> Self {
Position {
pos: Vector3::new(0.0, 0.0, 0.0),
}
}
}
impl Component for Position {
type Storage = VecStorage<Self>;
}
impl fmt::Display for Position {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "({:?},{:?},{:?})", self.pos[0], self.pos[1], self.pos[2])
}
}
impl BinaryConversion for Position {
fn data(&self) -> Vec<f64> {
vec![self.pos[0], self.pos[1], self.pos[2]]
}
}
impl XYZPosition for Position {
fn pos(&self) -> Vector3<f64> {
self.pos
}
}
#[derive(Clone, Copy, Serialize)]
pub struct Velocity {
pub vel: Vector3<f64>,
}
impl fmt::Display for Velocity {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "({:?},{:?},{:?})", self.vel[0], self.vel[1], self.vel[2])
}
}
impl BinaryConversion for Velocity {
fn data(&self) -> Vec<f64> {
vec![self.vel[0], self.vel[1], self.vel[2]]
}
}
impl Component for Velocity {
type Storage = VecStorage<Self>;
}
pub struct InitialVelocity {
pub vel: Vector3<f64>,
}
impl Component for InitialVelocity {
type Storage = VecStorage<Self>;
}
#[derive(Copy, Clone, Serialize)]
pub struct Force {
pub force: Vector3<f64>,
}
impl Component for Force {
type Storage = VecStorage<Self>;
}
impl Default for Force {
fn default() -> Self {
Self::new()
}
}
impl Force {
pub fn new() -> Self {
Force {
force: Vector3::new(0.0, 0.0, 0.0),
}
}
}
#[derive(Deserialize, Serialize, Clone)]
pub struct Mass {
pub value: f64,
}
impl Component for Mass {
type Storage = VecStorage<Self>;
}
#[derive(Default)]
pub struct Atom;
impl Component for Atom {
type Storage = NullStorage<Self>;
}
pub struct ClearForceSystem;
impl<'a> System<'a> for ClearForceSystem {
type SystemData = WriteStorage<'a, Force>;
fn run(&mut self, mut force: Self::SystemData) {
use rayon::prelude::*;
(&mut force).par_join().for_each(|force| {
force.force = Vector3::new(0.0, 0.0, 0.0);
});
}
}
pub struct AtomPlugin;
impl Plugin for AtomPlugin {
fn build(&self, builder: &mut crate::simulation::SimulationBuilder) {
register_components(&mut builder.world);
builder.dispatcher_builder.add(DeflagNewAtomsSystem, "deflag", &[]);
builder.dispatcher_builder.add(AddOldForceToNewAtomsSystem, "", &[]);
}
fn deps(&self) -> Vec::<Box<dyn Plugin>> {
Vec::new()
}
}
fn register_components(world: &mut World) {
world.register::<Position>();
world.register::<Mass>();
world.register::<Force>();
world.register::<Atom>();
world.register::<InitialVelocity>();
world.register::<Velocity>();
}