// Data models and configuration structs for simulation parameters.
///|
/// Optical pulse initial shape enumeration
pub enum PulseShape {
Gaussian
Sech
SuperGaussian(power~ : Int)
ChirpedGaussian(chirp~ : Double)
ChirpedSech(chirp~ : Double)
DualPulse(delay~ : Double, ratio~ : Double)
CustomWaveform
} derive(Debug, Eq)
///|
/// PulseShape constructor functions
pub fn PulseShape::gaussian() -> PulseShape {
Gaussian
}
///|
pub fn PulseShape::sech() -> PulseShape {
Sech
}
///|
pub fn PulseShape::super_gaussian(power : Int) -> PulseShape {
SuperGaussian(power~)
}
///|
pub fn PulseShape::chirped_gaussian(chirp : Double) -> PulseShape {
ChirpedGaussian(chirp~)
}
///|
pub fn PulseShape::chirped_sech(chirp : Double) -> PulseShape {
ChirpedSech(chirp~)
}
///|
pub fn PulseShape::dual_pulse(delay : Double, ratio : Double) -> PulseShape {
DualPulse(delay~, ratio~)
}
///|
pub fn PulseShape::custom_waveform() -> PulseShape {
CustomWaveform
}
///|
/// Show implementation for PulseShape
pub impl Show for PulseShape with fn output(self, logger) {
match self {
Gaussian => logger.write_string("Gaussian")
Sech => logger.write_string("Sech")
SuperGaussian(power=p) =>
logger.write_string("SuperGaussian(power=" + p.to_string() + ")")
ChirpedGaussian(chirp=c) =>
logger.write_string("ChirpedGaussian(chirp=" + c.to_string() + ")")
ChirpedSech(chirp=c) =>
logger.write_string("ChirpedSech(chirp=" + c.to_string() + ")")
DualPulse(delay=d, ratio=r) =>
logger.write_string(
"DualPulse(delay=" + d.to_string() + ", ratio=" + r.to_string() + ")",
)
CustomWaveform => logger.write_string("CustomWaveform")
}
}
///|
/// Pulse specifications
pub struct PulseConfig {
shape : PulseShape
peak_power : Double // W
fwhm_duration : Double // s
central_wavelength : Double // m
chirp : Double
order : Double // Soliton order N
phase_offset : Double // rad
time_window : Double // s (full temporal window width)
num_points : Int // N_t grid points (power of 2)
} derive(Debug, Eq)
///|
/// Constructor for PulseConfig
pub fn PulseConfig::new(
shape? : PulseShape = Sech,
peak_power? : Double = 100.0,
fwhm_duration? : Double = 1.0e-12,
central_wavelength? : Double = WAVELENGTH_1550NM,
chirp? : Double = 0.0,
order? : Double = 1.0,
phase_offset? : Double = 0.0,
time_window? : Double = 100.0e-12,
num_points? : Int = 2048,
) -> PulseConfig {
{
shape,
peak_power,
fwhm_duration,
central_wavelength,
chirp,
order,
phase_offset,
time_window,
num_points,
}
}
///|
/// Default pulse parameters
pub fn PulseConfig::default() -> PulseConfig {
PulseConfig::new()
}
///|
/// Fiber dispersion profile up to 10th order
pub struct DispersionProfile {
alpha_db_per_km : Double // Attenuation in dB/km
beta2 : Double // s^2/m (GVD)
beta3 : Double // s^3/m (TOD)
beta4 : Double // s^4/m (FOD)
beta5 : Double // s^5/m
beta6 : Double // s^6/m
beta7 : Double // s^7/m
beta8 : Double // s^8/m
beta9 : Double // s^9/m
beta10 : Double // s^10/m
} derive(Debug, Eq)
///|
/// Constructor for DispersionProfile
pub fn DispersionProfile::new(
alpha_db_per_km? : Double = 0.2,
beta2? : Double = -2.17e-26,
beta3? : Double = 1.0e-40,
beta4? : Double = 0.0,
beta5? : Double = 0.0,
beta6? : Double = 0.0,
beta7? : Double = 0.0,
beta8? : Double = 0.0,
beta9? : Double = 0.0,
beta10? : Double = 0.0,
) -> DispersionProfile {
{
alpha_db_per_km,
beta2,
beta3,
beta4,
beta5,
beta6,
beta7,
beta8,
beta9,
beta10,
}
}
///|
/// Default dispersion profile (SMF-28 at 1550 nm)
pub fn DispersionProfile::smf28() -> DispersionProfile {
DispersionProfile::new()
}
///|
/// Fiber nonlinear parameters and Raman model choices
pub struct NonlinearProfile {
gamma : Double // 1/(W*m)
self_steepening : Bool // Include s = 1/omega0 * d/dt
tau_s : Double // Self-steepening timescale (s)
enable_raman : Bool
fr : Double // Raman fractional response (typically 0.18 for silica)
tau1 : Double // Raman parameter tau1 (fs)
tau2 : Double // Raman parameter tau2 (fs)
} derive(Debug, Eq)
///|
/// Constructor for NonlinearProfile
pub fn NonlinearProfile::new(
gamma? : Double = 0.0013,
self_steepening? : Bool = true,
tau_s? : Double = 0.0,
enable_raman? : Bool = true,
fr? : Double = 0.18,
tau1? : Double = 12.2e-15,
tau2? : Double = 32.0e-15,
) -> NonlinearProfile {
{ gamma, self_steepening, tau_s, enable_raman, fr, tau1, tau2 }
}
///|
/// Default silica fiber nonlinear properties
pub fn NonlinearProfile::default_silica() -> NonlinearProfile {
NonlinearProfile::new()
}
///|
/// Fiber segment configuration
pub struct FiberSegment {
name : String
length : Double // m
dispersion : DispersionProfile
nonlinearity : NonlinearProfile
gain_db_per_m : Double // Small-signal gain (dB/m) for active fiber
saturation_energy : Double // Gain saturation energy Esat (J)
} derive(Debug, Eq)
///|
/// Create standard fiber segment
pub fn FiberSegment::new(
name : String,
length : Double,
dispersion : DispersionProfile,
nonlinearity : NonlinearProfile,
gain_db_per_m? : Double = 0.0,
saturation_energy? : Double = 1.0e-9,
) -> FiberSegment {
{ name, length, dispersion, nonlinearity, gain_db_per_m, saturation_energy }
}
///|
/// SSFM algorithm solver options
pub enum SolverMethod {
StandardSSFM
SymmetricSSFM
RK4IP
} derive(Debug, Eq)
///|
/// SolverMethod constructors
pub fn SolverMethod::standard_ssfm() -> SolverMethod {
StandardSSFM
}
///|
pub fn SolverMethod::symmetric_ssfm() -> SolverMethod {
SymmetricSSFM
}
///|
pub fn SolverMethod::rk4ip() -> SolverMethod {
RK4IP
}
///|
/// Show implementation for SolverMethod
pub impl Show for SolverMethod with fn output(self, logger) {
match self {
StandardSSFM => logger.write_string("StandardSSFM")
SymmetricSSFM => logger.write_string("SymmetricSSFM")
RK4IP => logger.write_string("RK4IP")
}
}
///|
/// Simulation numerical settings
pub struct SimulationConfig {
solver_method : SolverMethod
total_length : Double // m
num_steps : Int // Fixed step count
adaptive_step : Bool
tolerance : Double // Local truncation error tolerance
max_step_size : Double // m
min_step_size : Double // m
save_history_steps : Int // Save field slice every N steps
} derive(Debug, Eq)
///|
/// Constructor for SimulationConfig
pub fn SimulationConfig::new(
solver_method? : SolverMethod = RK4IP,
total_length? : Double = 100.0,
num_steps? : Int = 1000,
adaptive_step? : Bool = true,
tolerance? : Double = 1.0e-6,
max_step_size? : Double = 1.0,
min_step_size? : Double = 1.0e-6,
save_history_steps? : Int = 10,
) -> SimulationConfig {
{
solver_method,
total_length,
num_steps,
adaptive_step,
tolerance,
max_step_size,
min_step_size,
save_history_steps,
}
}
///|
/// Default simulation options
pub fn SimulationConfig::default() -> SimulationConfig {
SimulationConfig::new()
}