use specs::DispatcherBuilder;
use crate::laser::LaserPlugin;
use crate::{constant, simulation::Plugin};
use crate::laser::index::LaserIndex;
use serde::{Deserialize, Serialize};
use specs::prelude::*;
pub mod force;
#[derive(Deserialize, Serialize, Clone, Copy)]
pub struct DipoleLight {
pub wavelength: f64,
}
impl Component for DipoleLight {
type Storage = HashMapStorage<Self>;
}
impl DipoleLight {
pub fn frequency(&self) -> f64 {
constant::C / self.wavelength
}
pub fn wavenumber(&self) -> f64 {
2.0 * constant::PI / self.wavelength
}
}
#[derive(Deserialize, Serialize, Clone, Copy)]
pub struct Polarizability {
pub prefactor: f64,
}
impl Component for Polarizability {
type Storage = VecStorage<Self>;
}
impl Polarizability {
pub fn calculate_for(
dipole_beam_wavelength: f64,
optical_transition_wavelength: f64,
optical_transition_linewidth: f64,
) -> Polarizability {
let transition_f = constant::C / optical_transition_wavelength;
let dipole_f = constant::C / dipole_beam_wavelength;
let prefactor = -3. * constant::PI * constant::C.powf(2.0)
/ (2. * (2. * constant::PI * transition_f).powf(3.0))
* optical_transition_linewidth
* -(1. / (transition_f - dipole_f) + 1. / (transition_f + dipole_f));
Polarizability { prefactor }
}
}
pub struct AttachIndexToDipoleLightSystem;
impl<'a> System<'a> for AttachIndexToDipoleLightSystem {
type SystemData = (
Entities<'a>,
ReadStorage<'a, DipoleLight>,
ReadStorage<'a, LaserIndex>,
Read<'a, LazyUpdate>,
);
fn run(&mut self, (ent, dipole_light, indices, updater): Self::SystemData) {
for (ent, _, _) in (&ent, &dipole_light, !&indices).join() {
updater.insert(ent, LaserIndex::default());
}
}
}
pub struct DipolePlugin<const N : usize>;
impl<const N: usize> Plugin for DipolePlugin<N> {
fn build(&self, builder: &mut crate::simulation::SimulationBuilder) {
add_systems_to_dispatch::<N>(&mut builder.dispatcher_builder, &[]);
register_components(&mut builder.world);
}
fn deps(&self) -> Vec::<Box<dyn Plugin>> {
vec![Box::new(LaserPlugin::<{N}>)]
}
}
fn add_systems_to_dispatch<const N: usize>(
builder: &mut DispatcherBuilder<'static, 'static>,
deps: &[&str],
) {
builder.add(
force::ApplyDipoleForceSystem::<N>,
"apply_dipole_force",
&["sample_intensity_gradient"],
);
builder.add(
crate::dipole::AttachIndexToDipoleLightSystem,
"attach_dipole_index",
deps,
);
}
fn register_components(world: &mut World) {
world.register::<DipoleLight>();
}