use crate::{ model::{Model, Settings}, solver::Solver, utils::*, }; use nalgebra::ComplexField; use std::{collections::HashMap, marker::PhantomData}; #[derive(Clone)] pub struct Point { pub pos: Vect, pub diffusion: Vect, } #[derive(Clone)] pub struct Source { pub amplitude: T, pub fonction: fn(T) -> Vect, pub freq: T, pub phase: T, } pub struct Space, V: Solver, const D: usize> { pub model: M, pub old_points: Vec>, pub points: Vec>, pub size: (usize, usize), pub solver: V, pub sources: HashMap>, pub time: T, pub _p: PhantomData, } impl< T: Copy + ComplexField, S: Settings, M: Model, V: Solver, const D: usize, > Space { pub fn simulate(&mut self, delta_time: T) { std::mem::swap(&mut self.old_points, &mut self.points); for (i, (point, old_point)) in self .points .iter_mut() .zip(self.old_points.iter()) .enumerate() { if let Some(source) = self.sources.get(&i) { let t = self.time * source.freq + source.phase; //Point{pos:t.sin()*source.amplitude, speed: t.cos()*source.amplitude} point.pos = (source.fonction)(t) * source.amplitude; } else { *point = old_point.clone() }; point.pos = self.solver.f(&self.model, point.pos); } let mut i = 0usize; for y in 0..self.size.1 { for x in 0..self.size.0 { let old_point = self.old_points[i].clone(); let point = &mut self.points[i]; if y > 0 { point.pos += (self.old_points[i - self.size.0].pos - old_point.pos) .component_mul(&point.diffusion) * delta_time; } if y < self.size.1 - 1 { point.pos += (self.old_points[i + self.size.0].pos - old_point.pos) .component_mul(&point.diffusion) * delta_time; } if x > 0 { point.pos += (self.old_points[i - 1].pos - old_point.pos) .component_mul(&point.diffusion) * delta_time; } if x < self.size.0 - 1 { point.pos += (self.old_points[i + 1].pos - old_point.pos) .component_mul(&point.diffusion) * delta_time; } i += 1; } } self.time += delta_time; } }