deep_causality_physics/photonics/
diffraction.rs1use crate::PhysicsError;
7use crate::dynamics::quantities::Length;
8use crate::photonics::quantities::{RayAngle, Wavelength};
9use std::f64::consts::PI;
10
11pub fn single_slit_irradiance_kernel(
26 i0: f64,
27 slit_width: Length,
28 theta: RayAngle,
29 wavelength: Wavelength,
30) -> Result<f64, PhysicsError> {
31 if i0 < 0.0 {
32 return Err(PhysicsError::PhysicalInvariantBroken(
33 "Irradiance i0 cannot be negative".into(),
34 ));
35 }
36
37 let a = slit_width.value();
38 let lambda = wavelength.value();
39 let angle = theta.value();
40
41 if lambda == 0.0 {
42 return Err(PhysicsError::Singularity("Wavelength is zero".into()));
43 }
44
45 let beta = (PI * a * angle.sin()) / lambda;
46
47 if beta.abs() < 1e-9 {
49 return Ok(i0);
50 }
51
52 let sinc = beta.sin() / beta;
53 let i = i0 * sinc * sinc;
54
55 Ok(i)
56}
57
58pub fn grating_equation_kernel(
73 pitch: Length,
74 order: i32,
75 incidence: RayAngle,
76 wavelength: Wavelength,
77) -> Result<RayAngle, PhysicsError> {
78 let d = pitch.value();
79 let m = order as f64;
80 let lambda = wavelength.value();
81 let theta_i = incidence.value();
82
83 if d <= 0.0 {
84 return Err(PhysicsError::PhysicalInvariantBroken(
85 "Grating pitch must be positive".into(),
86 ));
87 }
88
89 let sin_theta_m = (m * lambda / d) + theta_i.sin();
91
92 if sin_theta_m.abs() > 1.0 {
93 return Err(PhysicsError::PhysicalInvariantBroken(format!(
94 "Diffraction order {} does not exist for this configuration (sin_theta = {})",
95 order, sin_theta_m
96 )));
97 }
98
99 let theta_m = sin_theta_m.asin();
100 RayAngle::new(theta_m)
101}