dispersion rewrite
This commit is contained in:
@@ -461,11 +461,13 @@ default_rules: list[Rule] = [
|
||||
),
|
||||
Rule("w0", units.m_rads, ["wavelength"]),
|
||||
Rule("l", units.m_rads, ["w"]),
|
||||
Rule("w0_ind", math.argclosest, ["w_for_disp", "w0"]),
|
||||
Rule("w0_ind", math.argclosest, ["w", "w0"]),
|
||||
Rule("w_num", len, ["w"]),
|
||||
Rule("dw", lambda w: w[1] - w[0]),
|
||||
Rule(["fft", "ifft"], utils.fft_functions, priorities=1),
|
||||
Rule("wavelength_window", lambda dt: (max(100e-9, 2 * units.c * dt), 8e-6)),
|
||||
Rule("wavelength_window", fiber.valid_wavelength_window),
|
||||
Rule("dispersion_ind", fiber.dispersion_indices),
|
||||
# Pulse
|
||||
Rule("field_0", pulse.finalize_pulse),
|
||||
Rule(["input_time", "input_field"], pulse.load_custom_field),
|
||||
@@ -490,9 +492,8 @@ default_rules: list[Rule] = [
|
||||
Rule("soliton_length", pulse.soliton_length),
|
||||
Rule("c_to_a_factor", lambda: 1, priorities=-1),
|
||||
# Fiber Dispersion
|
||||
Rule("w_for_disp", units.m_rads, ["wl_for_disp"]),
|
||||
Rule("gas_info", materials.Gas),
|
||||
Rule("chi_gas", lambda gas_info, wl_for_disp: gas_info.sellmeier.chi(wl_for_disp)),
|
||||
Rule("chi_gas", lambda gas_info, l: gas_info.sellmeier.chi(l)),
|
||||
Rule("n_gas_2", materials.n_gas_2),
|
||||
Rule("n_eff", fiber.n_eff_hasan, conditions=dict(model="hasan")),
|
||||
Rule("n_eff", fiber.n_eff_marcatili, conditions=dict(model="marcatili")),
|
||||
@@ -511,7 +512,7 @@ default_rules: list[Rule] = [
|
||||
Rule("beta2_arr", fiber.beta2),
|
||||
Rule(
|
||||
"zero_dispersion_wavelength",
|
||||
lambda beta2_arr, wl_for_disp: wl_for_disp[math.argclosest(beta2_arr, 0)],
|
||||
lambda beta2_arr, l: l[math.argclosest(beta2_arr, 0)],
|
||||
),
|
||||
# Fiber nonlinearity
|
||||
Rule("effective_area", fiber.effective_area_pcf),
|
||||
@@ -560,15 +561,11 @@ envelope_rules = default_rules + [
|
||||
Rule("pre_field_0", pulse.initial_field_envelope, priorities=1),
|
||||
Rule("c_to_a_factor", pulse.c_to_a_factor),
|
||||
# Dispersion
|
||||
Rule(["wl_for_disp", "dispersion_ind"], fiber.lambda_for_envelope_dispersion),
|
||||
Rule("beta2_coefficients", fiber.dispersion_coefficients),
|
||||
Rule("beta2_coefficients", fiber.auto_dispersion_coefficients),
|
||||
Rule("beta2_arr", fiber.dispersion_from_coefficients),
|
||||
Rule("beta2", lambda beta2_coefficients: beta2_coefficients[0]),
|
||||
Rule(
|
||||
["wl_for_disp", "beta2_arr", "wavelength_window"],
|
||||
fiber.load_custom_dispersion,
|
||||
priorities=[2, 2, 2],
|
||||
),
|
||||
Rule("beta2", lambda beta2_arr, w0_ind: beta2_arr[w0_ind]),
|
||||
Rule(["beta2_arr", "dispersion_ind"], fiber.load_custom_dispersion, priorities=[2, 2, 2]),
|
||||
# Operators
|
||||
Rule("gamma_op", operators.variable_gamma, priorities=2),
|
||||
Rule("gamma_op", operators.constant_quantity, ["gamma_arr"], priorities=1),
|
||||
@@ -595,7 +592,6 @@ full_field_rules = default_rules + [
|
||||
Rule("pre_field_0", pulse.initial_full_field),
|
||||
Rule("spectrum_factor", pulse.spectrum_factor_fullfield, priorities=-1),
|
||||
# Dispersion
|
||||
Rule(["wl_for_disp", "dispersion_ind"], fiber.lambda_for_full_field_dispersion),
|
||||
Rule("frame_velocity", fiber.frame_velocity),
|
||||
Rule("beta2", lambda beta2_arr, w0_ind: beta2_arr[w0_ind]),
|
||||
# Nonlinearity
|
||||
|
||||
@@ -67,12 +67,12 @@ class ConstantGas:
|
||||
pressure: float,
|
||||
temperature: float,
|
||||
ideal_gas: bool,
|
||||
wl_for_disp: np.ndarray,
|
||||
l: np.ndarray,
|
||||
):
|
||||
self.gas = materials.Gas(gas_name)
|
||||
self.pressure_const = pressure
|
||||
self.number_density_const = self.gas.number_density(temperature, pressure, ideal_gas)
|
||||
self.n_gas_2_const = self.gas.sellmeier.n_gas_2(wl_for_disp, temperature, pressure)
|
||||
self.n_gas_2_const = self.gas.sellmeier.n_gas_2(l, temperature, pressure)
|
||||
self.n2_const = self.gas.n2(temperature, pressure)
|
||||
self.chi3_const = self.gas.chi3(temperature, pressure)
|
||||
|
||||
@@ -102,7 +102,7 @@ class PressureGradientGas:
|
||||
pressure_out: float,
|
||||
temperature: float,
|
||||
ideal_gas: bool,
|
||||
wl_for_disp: np.ndarray,
|
||||
l: np.ndarray,
|
||||
length: float,
|
||||
):
|
||||
self.p_in = pressure_in
|
||||
@@ -110,7 +110,7 @@ class PressureGradientGas:
|
||||
self.gas = materials.Gas(gas_name)
|
||||
self.temperature = temperature
|
||||
self.ideal_gas = ideal_gas
|
||||
self.wl_for_disp = wl_for_disp
|
||||
self.l = l
|
||||
self.z_max = length
|
||||
|
||||
def _pressure(self, z: float) -> float:
|
||||
@@ -120,7 +120,7 @@ class PressureGradientGas:
|
||||
return self.gas.number_density(self.temperature, self._pressure(z), self.ideal_gas)
|
||||
|
||||
def square_index(self, z: float) -> np.ndarray:
|
||||
return self.gas.sellmeier.n_gas_2(self.wl_for_disp, self.temperature, self._pressure(z))
|
||||
return self.gas.sellmeier.n_gas_2(self.l, self.temperature, self._pressure(z))
|
||||
|
||||
def n2(self, z: float) -> np.ndarray:
|
||||
return self.gas.n2(self.temperature, self._pressure(z))
|
||||
@@ -135,19 +135,19 @@ class PressureGradientGas:
|
||||
|
||||
|
||||
def marcatili_refractive_index(
|
||||
square_index: VariableQuantity, core_radius: float, wl_for_disp: np.ndarray
|
||||
square_index: VariableQuantity, core_radius: float, l: np.ndarray
|
||||
) -> VariableQuantity:
|
||||
def operate(z: float) -> np.ndarray:
|
||||
return fiber.n_eff_marcatili(wl_for_disp, square_index(z), core_radius)
|
||||
return fiber.n_eff_marcatili(l, square_index(z), core_radius)
|
||||
|
||||
return operate
|
||||
|
||||
|
||||
def marcatili_adjusted_refractive_index(
|
||||
square_index: VariableQuantity, core_radius: float, wl_for_disp: np.ndarray
|
||||
square_index: VariableQuantity, core_radius: float, l: np.ndarray
|
||||
) -> VariableQuantity:
|
||||
def operate(z: float) -> np.ndarray:
|
||||
return fiber.n_eff_marcatili_adjusted(wl_for_disp, square_index(z), core_radius)
|
||||
return fiber.n_eff_marcatili_adjusted(l, square_index(z), core_radius)
|
||||
|
||||
return operate
|
||||
|
||||
@@ -155,7 +155,7 @@ def marcatili_adjusted_refractive_index(
|
||||
def vincetti_refractive_index(
|
||||
square_index: VariableQuantity,
|
||||
core_radius: float,
|
||||
wl_for_disp: np.ndarray,
|
||||
l: np.ndarray,
|
||||
wavelength: float,
|
||||
wall_thickness: float,
|
||||
tube_radius: float,
|
||||
@@ -165,7 +165,7 @@ def vincetti_refractive_index(
|
||||
) -> VariableQuantity:
|
||||
def operate(z: float) -> np.ndarray:
|
||||
return fiber.n_eff_vincetti(
|
||||
wl_for_disp,
|
||||
l,
|
||||
wavelength,
|
||||
square_index(z),
|
||||
wall_thickness,
|
||||
@@ -200,7 +200,7 @@ def constant_polynomial_dispersion(
|
||||
|
||||
|
||||
def constant_direct_dispersion(
|
||||
w_for_disp: np.ndarray,
|
||||
w: np.ndarray,
|
||||
w0: np.ndarray,
|
||||
t_num: int,
|
||||
n_eff: np.ndarray,
|
||||
@@ -211,8 +211,8 @@ def constant_direct_dispersion(
|
||||
Direct dispersion for when the refractive index is known
|
||||
"""
|
||||
disp_arr = np.zeros(t_num, dtype=complex)
|
||||
w0_ind = math.argclosest(w_for_disp, w0)
|
||||
disp_arr[dispersion_ind] = fiber.fast_direct_dispersion(w_for_disp, w0, n_eff, w0_ind)[2:-2]
|
||||
w0_ind = math.argclosest(w, w0)
|
||||
disp_arr[dispersion_ind] = fiber.fast_direct_dispersion(w[dispersion_ind], w0, n_eff, w0_ind)
|
||||
left_ind, *_, right_ind = np.nonzero(disp_arr[w_order])[0]
|
||||
disp_arr[w_order] = math._polynom_extrapolation_in_place(
|
||||
disp_arr[w_order], left_ind, right_ind, 1
|
||||
@@ -222,19 +222,19 @@ def constant_direct_dispersion(
|
||||
|
||||
|
||||
def direct_dispersion(
|
||||
w_for_disp: np.ndarray,
|
||||
w: np.ndarray,
|
||||
w0: np.ndarray,
|
||||
t_num: int,
|
||||
n_eff_op: SpecOperator,
|
||||
dispersion_ind: np.ndarray,
|
||||
) -> VariableQuantity:
|
||||
disp_arr = np.zeros(t_num, dtype=complex)
|
||||
w0_ind = math.argclosest(w_for_disp, w0)
|
||||
w0_ind = math.argclosest(w, w0)
|
||||
|
||||
def operate(z: float) -> np.ndarray:
|
||||
disp_arr[dispersion_ind] = fiber.fast_direct_dispersion(
|
||||
w_for_disp, w0, n_eff_op(z), w0_ind
|
||||
)[2:-2]
|
||||
w[dispersion_ind], w0, n_eff_op(z), w0_ind
|
||||
)
|
||||
return disp_arr
|
||||
|
||||
return operate
|
||||
@@ -247,13 +247,13 @@ def direct_dispersion(
|
||||
|
||||
def constant_wave_vector(
|
||||
n_eff: np.ndarray,
|
||||
w_for_disp: np.ndarray,
|
||||
w: np.ndarray,
|
||||
w_num: int,
|
||||
dispersion_ind: np.ndarray,
|
||||
w_order: np.ndarray,
|
||||
):
|
||||
beta_arr = np.zeros(w_num, dtype=float)
|
||||
beta_arr[dispersion_ind] = fiber.beta(w_for_disp, n_eff)[2:-2]
|
||||
beta_arr[dispersion_ind] = fiber.beta(w[dispersion_ind], n_eff)
|
||||
left_ind, *_, right_ind = np.nonzero(beta_arr[w_order])[0]
|
||||
beta_arr[w_order] = math._polynom_extrapolation_in_place(
|
||||
beta_arr[w_order], left_ind, right_ind, 1.0
|
||||
@@ -267,7 +267,7 @@ def constant_wave_vector(
|
||||
##################################################
|
||||
|
||||
|
||||
def envelope_raman(hr_w: np.ndarra, raman_fraction: float) -> FieldOperator:
|
||||
def envelope_raman(hr_w: np.ndarray, raman_fraction: float) -> FieldOperator:
|
||||
def operate(field: np.ndarray, z: float) -> np.ndarray:
|
||||
return raman_fraction * np.fft.ifft(hr_w * np.fft.fft(math.abs2(field)))
|
||||
|
||||
|
||||
@@ -646,7 +646,6 @@ class Parameters:
|
||||
"t",
|
||||
"z_targets",
|
||||
"l",
|
||||
"wl_for_disp",
|
||||
"alpha",
|
||||
"gamma_arr",
|
||||
"effective_area_arr",
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
import warnings
|
||||
from io import BytesIO
|
||||
from typing import Iterable, TypeVar
|
||||
|
||||
import numpy as np
|
||||
from numpy import e
|
||||
from numpy.fft import fft
|
||||
from numpy.polynomial.chebyshev import Chebyshev, cheb2poly
|
||||
from scipy.interpolate import interp1d
|
||||
|
||||
from scgenerator import io
|
||||
from scgenerator.io import DataFile
|
||||
@@ -19,56 +17,12 @@ pipi = 2 * pi
|
||||
T = TypeVar("T")
|
||||
|
||||
|
||||
def lambda_for_envelope_dispersion(
|
||||
l: np.ndarray, wavelength_window: tuple[float, float]
|
||||
) -> tuple[np.ndarray, np.ndarray]:
|
||||
"""
|
||||
Returns a wl vector for dispersion calculation in envelope mode
|
||||
|
||||
Returns
|
||||
-------
|
||||
np.ndarray
|
||||
subset of l in the interpolation range with two extra values on each side
|
||||
to accomodate for taking gradients
|
||||
np.ndarray
|
||||
indices of the original l where the values are valid
|
||||
(i.e. without the two extra on each side)
|
||||
"""
|
||||
raw_indices = np.where((l >= wavelength_window[0]) & (l <= wavelength_window[1]))[0]
|
||||
if l[raw_indices].min() > 1.01 * wavelength_window[0]:
|
||||
raise ValueError(
|
||||
f"lower range of {1e9*wavelength_window[0]:.1f}nm is not reached by the grid. "
|
||||
f"Minimum of grid is {1e9*l[raw_indices].min():.1f}nm. Try a finer grid"
|
||||
)
|
||||
sorted_ind = raw_indices[np.argsort(l[raw_indices])]
|
||||
return l[sorted_ind], sorted_ind[2:-2]
|
||||
def valid_wavelength_window(l: np.ndarray, dispersion_ind: np.ndarray) -> tuple[float, float]:
|
||||
return l[dispersion_ind].min(), l[dispersion_ind].max()
|
||||
|
||||
|
||||
def lambda_for_full_field_dispersion(
|
||||
l: np.ndarray, wavelength_window: tuple[float, float]
|
||||
) -> tuple[np.ndarray, np.ndarray]:
|
||||
"""
|
||||
Returns a wl vector for dispersion calculation in full field mode
|
||||
|
||||
Returns
|
||||
-------
|
||||
np.ndarray
|
||||
subset of l in the interpolation range with two extra values on each side
|
||||
to accomodate for taking gradients
|
||||
np.ndarray
|
||||
indices of the original l where the values are valid
|
||||
(i.e. without the two extra on each side)
|
||||
"""
|
||||
su = np.where((l >= wavelength_window[0]) & (l <= wavelength_window[1]))[0]
|
||||
if l[su].min() > 1.01 * wavelength_window[0]:
|
||||
raise ValueError(
|
||||
f"lower range of {1e9*wavelength_window[0]:.1f}nm is not reached by the grid. "
|
||||
"try a finer grid"
|
||||
)
|
||||
fu = np.concatenate((su[:2] - 2, su, su[-2:] + 2))
|
||||
fu = np.where(fu < 0, 0, fu)
|
||||
fu = np.where(fu >= len(l), len(l) - 1, fu)
|
||||
return l[fu], su
|
||||
def dispersion_indices(l: np.ndarray, wavelength_window) -> np.ndarray:
|
||||
return np.where((l >= wavelength_window[0]) & (l <= wavelength_window[1]))[0]
|
||||
|
||||
|
||||
def is_dynamic_dispersion(pressure=None):
|
||||
@@ -92,45 +46,23 @@ def is_dynamic_dispersion(pressure=None):
|
||||
return out
|
||||
|
||||
|
||||
def gvd_from_n_eff(n_eff: np.ndarray, wl_for_disp: np.ndarray):
|
||||
"""
|
||||
computes the dispersion parameter D from an effective index of refraction n_eff
|
||||
Since computing gradients/derivatives of discrete arrays is not well defined on the boundary,
|
||||
it is advised to chop off the two values on either end of the returned array
|
||||
|
||||
Parameters
|
||||
----------
|
||||
n_eff : 1D array
|
||||
a wl-dependent index of refraction
|
||||
wl_for_disp : 1D array
|
||||
the wavelength array (len must match n_eff)
|
||||
|
||||
Returns
|
||||
-------
|
||||
D : 1D array
|
||||
wl-dependent dispersion parameter as function of wl_for_disp
|
||||
"""
|
||||
|
||||
return -wl_for_disp / c * (np.gradient(np.gradient(n_eff, wl_for_disp), wl_for_disp))
|
||||
def beta2_to_D(beta2, l):
|
||||
"""returns the D parameter corresponding to beta2(l)"""
|
||||
return -(pipi * c) / (l**2) * beta2
|
||||
|
||||
|
||||
def beta2_to_D(beta2, wl_for_disp):
|
||||
"""returns the D parameter corresponding to beta2(wl_for_disp)"""
|
||||
return -(pipi * c) / (wl_for_disp**2) * beta2
|
||||
def D_to_beta2(D, l):
|
||||
"""returns the beta2 parameters corresponding to D(l)"""
|
||||
return -(l**2) / (pipi * c) * D
|
||||
|
||||
|
||||
def D_to_beta2(D, wl_for_disp):
|
||||
"""returns the beta2 parameters corresponding to D(wl_for_disp)"""
|
||||
return -(wl_for_disp**2) / (pipi * c) * D
|
||||
|
||||
|
||||
def plasma_dispersion(wl_for_disp, number_density, simple=False):
|
||||
def plasma_dispersion(l, number_density, simple=False):
|
||||
"""
|
||||
computes dispersion (beta2) for constant plasma
|
||||
|
||||
Parameters
|
||||
----------
|
||||
wl_for_disp : array-like
|
||||
l : array-like
|
||||
wavelengths over which to calculate the dispersion
|
||||
number_density : number of ionized atoms /m^3
|
||||
|
||||
@@ -141,7 +73,7 @@ def plasma_dispersion(wl_for_disp, number_density, simple=False):
|
||||
"""
|
||||
|
||||
e2_me_e0 = 3182.60735 # e^2 /(m_e * epsilon_0)
|
||||
w = units.m_rads(wl_for_disp)
|
||||
w = units.m_rads(l)
|
||||
if simple:
|
||||
w_pl = number_density * e2_me_e0
|
||||
return -(w_pl**2) / (c * w**2)
|
||||
@@ -150,16 +82,16 @@ def plasma_dispersion(wl_for_disp, number_density, simple=False):
|
||||
return beta2_arr
|
||||
|
||||
|
||||
def n_eff_marcatili(wl_for_disp, n_gas_2, core_radius, he_mode=(1, 1)):
|
||||
def n_eff_marcatili(l, n_gas_2, core_radius, he_mode=(1, 1)):
|
||||
"""
|
||||
computes the effective refractive index according to the Marcatili model of a capillary
|
||||
|
||||
Parameters
|
||||
----------
|
||||
wl_for_disp : ndarray, shape (n, )
|
||||
l : ndarray, shape (n, )
|
||||
wavelengths array (m)
|
||||
n_gas_2 : ndarray, shape (n, )
|
||||
square of the refractive index of the gas as function of wl_for_disp
|
||||
square of the refractive index of the gas as function of l
|
||||
core_radius : float
|
||||
inner radius of the capillary (m)
|
||||
he_mode : tuple, shape (2, ), optional
|
||||
@@ -175,20 +107,20 @@ def n_eff_marcatili(wl_for_disp, n_gas_2, core_radius, he_mode=(1, 1)):
|
||||
"""
|
||||
u = u_nm(*he_mode)
|
||||
|
||||
return np.sqrt(n_gas_2 - (wl_for_disp * u / (pipi * core_radius)) ** 2)
|
||||
return np.sqrt(n_gas_2 - (l * u / (pipi * core_radius)) ** 2)
|
||||
|
||||
|
||||
def n_eff_marcatili_adjusted(wl_for_disp, n_gas_2, core_radius, he_mode=(1, 1), fit_parameters=()):
|
||||
def n_eff_marcatili_adjusted(l, n_gas_2, core_radius, he_mode=(1, 1), fit_parameters=()):
|
||||
"""
|
||||
computes the effective refractive index according to the Marcatili model of a capillary
|
||||
but adjusted at longer wavelengths
|
||||
|
||||
Parameters
|
||||
----------
|
||||
wl_for_disp : ndarray, shape (n, )
|
||||
l : ndarray, shape (n, )
|
||||
wavelengths array (m)
|
||||
n_gas_2 : ndarray, shape (n, )
|
||||
refractive index of the gas as function of wl_for_disp
|
||||
refractive index of the gas as function of l
|
||||
core_radius : float
|
||||
inner radius of the capillary (m)
|
||||
he_mode : tuple, shape (2, ), optional
|
||||
@@ -207,9 +139,9 @@ def n_eff_marcatili_adjusted(wl_for_disp, n_gas_2, core_radius, he_mode=(1, 1),
|
||||
"""
|
||||
u = u_nm(*he_mode)
|
||||
|
||||
corrected_radius = effective_core_radius(wl_for_disp, core_radius, *fit_parameters)
|
||||
corrected_radius = effective_core_radius(l, core_radius, *fit_parameters)
|
||||
|
||||
return np.sqrt(n_gas_2 - (wl_for_disp * u / (pipi * corrected_radius)) ** 2)
|
||||
return np.sqrt(n_gas_2 - (l * u / (pipi * corrected_radius)) ** 2)
|
||||
|
||||
|
||||
def effective_area_marcatili(core_radius: float) -> float:
|
||||
@@ -238,14 +170,14 @@ def capillary_spacing_hasan(
|
||||
|
||||
|
||||
def resonance_thickness(
|
||||
wl_for_disp: np.ndarray, order: int, n_gas_2: np.ndarray, core_radius: float
|
||||
l: np.ndarray, order: int, n_gas_2: np.ndarray, core_radius: float
|
||||
) -> float:
|
||||
"""
|
||||
computes at which wall thickness the specified wl is resonant
|
||||
|
||||
Parameters
|
||||
----------
|
||||
wl_for_disp : np.ndarray
|
||||
l : np.ndarray
|
||||
in m
|
||||
order : int
|
||||
0, 1, ...
|
||||
@@ -259,20 +191,20 @@ def resonance_thickness(
|
||||
float
|
||||
thickness in m
|
||||
"""
|
||||
n_si_2 = mat.n_gas_2(wl_for_disp, "silica", None, None)
|
||||
n_si_2 = mat.n_gas_2(l, "silica", None, None)
|
||||
return (
|
||||
wl_for_disp
|
||||
l
|
||||
/ (4 * np.sqrt(n_si_2))
|
||||
* (2 * order + 1)
|
||||
* (1 - n_gas_2 / n_si_2 + wl_for_disp**2 / (4 * n_si_2 * core_radius**2)) ** -0.5
|
||||
* (1 - n_gas_2 / n_si_2 + l**2 / (4 * n_si_2 * core_radius**2)) ** -0.5
|
||||
)
|
||||
|
||||
|
||||
def resonance_strength(
|
||||
wl_for_disp: np.ndarray, core_radius: float, capillary_thickness: float, order: int
|
||||
l: np.ndarray, core_radius: float, capillary_thickness: float, order: int
|
||||
) -> float:
|
||||
a = 1.83 + (2.3 * capillary_thickness / core_radius)
|
||||
n_si = np.sqrt(mat.n_gas_2(wl_for_disp, "silica", None, None))
|
||||
n_si = np.sqrt(mat.n_gas_2(l, "silica", None, None))
|
||||
return (
|
||||
capillary_thickness
|
||||
/ (n_si * core_radius) ** (2.303 * a / n_si)
|
||||
@@ -281,19 +213,19 @@ def resonance_strength(
|
||||
|
||||
|
||||
def capillary_resonance_strengths(
|
||||
wl_for_disp: np.ndarray,
|
||||
l: np.ndarray,
|
||||
core_radius: float,
|
||||
capillary_thickness: float,
|
||||
capillary_resonance_max_order: int,
|
||||
) -> list[float]:
|
||||
return [
|
||||
resonance_strength(wl_for_disp, core_radius, capillary_thickness, o)
|
||||
resonance_strength(l, core_radius, capillary_thickness, o)
|
||||
for o in range(1, capillary_resonance_max_order + 1)
|
||||
]
|
||||
|
||||
|
||||
def n_eff_hasan(
|
||||
wl_for_disp: np.ndarray,
|
||||
l: np.ndarray,
|
||||
n_gas_2: np.ndarray,
|
||||
core_radius: float,
|
||||
capillary_num: int,
|
||||
@@ -308,10 +240,10 @@ def n_eff_hasan(
|
||||
|
||||
Parameters
|
||||
----------
|
||||
wl_for_disp : np.ndarray, shape(n,)
|
||||
l : np.ndarray, shape(n,)
|
||||
wavelenghs array
|
||||
n_gas_2 : ndarray, shape (n, )
|
||||
squared refractive index of the gas as a function of wl_for_disp
|
||||
squared refractive index of the gas as a function of l
|
||||
core_radius : float
|
||||
radius of the core (from cented to edge of a capillary)
|
||||
capillary_num : int
|
||||
@@ -346,18 +278,18 @@ def n_eff_hasan(
|
||||
if capillary_nested > 0:
|
||||
f2 += 0.0045 * np.exp(-4.1589 / (capillary_nested * Rg))
|
||||
|
||||
R_eff = f1 * core_radius * (1 - f2 * wl_for_disp**2 / (core_radius * capillary_thickness))
|
||||
R_eff = f1 * core_radius * (1 - f2 * l**2 / (core_radius * capillary_thickness))
|
||||
|
||||
n_eff_2 = n_gas_2 - (u * wl_for_disp / (pipi * R_eff)) ** 2
|
||||
n_eff_2 = n_gas_2 - (u * l / (pipi * R_eff)) ** 2
|
||||
|
||||
chi_sil = mat.Sellmeier.load("silica").chi(wl_for_disp)
|
||||
chi_sil = mat.Sellmeier.load("silica").chi(l)
|
||||
|
||||
with np.errstate(divide="ignore", invalid="ignore"):
|
||||
for m, strength in enumerate(capillary_resonance_strengths):
|
||||
n_eff_2 += (
|
||||
strength
|
||||
* wl_for_disp**2
|
||||
/ (alpha + wl_for_disp**2 - chi_sil * (2 * capillary_thickness / (m + 1)) ** 2)
|
||||
* l**2
|
||||
/ (alpha + l**2 - chi_sil * (2 * capillary_thickness / (m + 1)) ** 2)
|
||||
)
|
||||
|
||||
return np.sqrt(n_eff_2)
|
||||
@@ -479,15 +411,15 @@ def effective_area_from_V(core_radius: float, V_eff: T) -> T:
|
||||
return out
|
||||
|
||||
|
||||
def beta(w_for_disp: np.ndarray, n_eff: np.ndarray) -> np.ndarray:
|
||||
return n_eff * w_for_disp / c
|
||||
def beta(w: np.ndarray, n_eff: np.ndarray) -> np.ndarray:
|
||||
return n_eff * w / c
|
||||
|
||||
|
||||
def beta1(w_for_disp: np.ndarray, n_eff: np.ndarray) -> np.ndarray:
|
||||
return np.gradient(beta(w_for_disp, n_eff), w_for_disp)
|
||||
def beta1(w: np.ndarray, n_eff: np.ndarray) -> np.ndarray:
|
||||
return np.gradient(beta(w, n_eff), w[1] - w[0])
|
||||
|
||||
|
||||
def beta2(w_for_disp: np.ndarray, n_eff: np.ndarray) -> np.ndarray:
|
||||
def beta2(w: np.ndarray, n_eff: np.ndarray) -> np.ndarray:
|
||||
"""
|
||||
computes the dispersion parameter beta2 according to the effective refractive
|
||||
index of the fiber and the frequency range
|
||||
@@ -503,7 +435,8 @@ def beta2(w_for_disp: np.ndarray, n_eff: np.ndarray) -> np.ndarray:
|
||||
-------
|
||||
beta2 : ndarray, shape (n, )
|
||||
"""
|
||||
return np.gradient(np.gradient(beta(w_for_disp, n_eff), w_for_disp), w_for_disp)
|
||||
dw = w[1] - w[0]
|
||||
return np.gradient(np.gradient(beta(w, n_eff), dw), dw)
|
||||
|
||||
|
||||
def frame_velocity(beta1_arr: np.ndarray, w0_ind: int) -> float:
|
||||
@@ -511,7 +444,7 @@ def frame_velocity(beta1_arr: np.ndarray, w0_ind: int) -> float:
|
||||
|
||||
|
||||
def HCPCF_dispersion(
|
||||
wl_for_disp,
|
||||
l,
|
||||
gas_name: str,
|
||||
model="marcatili",
|
||||
pressure=None,
|
||||
@@ -523,7 +456,7 @@ def HCPCF_dispersion(
|
||||
|
||||
Parameters
|
||||
----------
|
||||
wl_for_disp : ndarray, shape (n, )
|
||||
l : ndarray, shape (n, )
|
||||
wavelengths over which to calculate the dispersion
|
||||
gas_name : str
|
||||
name of the filling gas in lower case
|
||||
@@ -532,7 +465,7 @@ def HCPCF_dispersion(
|
||||
model_params : tuple
|
||||
to be passed on to the function in charge of computing the effective index of the fiber.
|
||||
Every n_eff_* function has a signature
|
||||
`n_eff_(wl_for_disp, n_gas_2, radius, *args)` and model_params corresponds to args
|
||||
`n_eff_(l, n_gas_2, radius, *args)` and model_params corresponds to args
|
||||
temperature : float
|
||||
Temperature of the material
|
||||
pressure : float
|
||||
@@ -544,13 +477,13 @@ def HCPCF_dispersion(
|
||||
beta2 as function of wavelength
|
||||
"""
|
||||
|
||||
w = units.m_rads(wl_for_disp)
|
||||
n_gas_2 = mat.Sellmeier.load(gas_name).n_gas_2(wl_for_disp, temperature, pressure)
|
||||
w = units.m_rads(l)
|
||||
n_gas_2 = mat.Sellmeier.load(gas_name).n_gas_2(l, temperature, pressure)
|
||||
|
||||
n_eff_func = dict(
|
||||
marcatili=n_eff_marcatili, marcatili_adjusted=n_eff_marcatili_adjusted, hasan=n_eff_hasan
|
||||
)[model]
|
||||
n_eff = n_eff_func(wl_for_disp, n_gas_2, **model_params)
|
||||
n_eff = n_eff_func(l, n_gas_2, **model_params)
|
||||
|
||||
return beta2(w, n_eff)
|
||||
|
||||
@@ -558,23 +491,27 @@ def HCPCF_dispersion(
|
||||
def gamma_parameter(n2: float, w0: float, effective_area: T) -> T:
|
||||
if isinstance(effective_area, np.ndarray):
|
||||
effective_area_term = np.sqrt(effective_area * effective_area[0])
|
||||
else:
|
||||
effective_area_term = effective_area
|
||||
return np.divide(
|
||||
n2 * w0,
|
||||
effective_area_term * c,
|
||||
where=effective_area_term != 0,
|
||||
out=effective_area_term,
|
||||
)
|
||||
|
||||
return n2 * w0 / (effective_area_term * c)
|
||||
return n2 * w0 / (effective_area * c)
|
||||
|
||||
|
||||
def constant_effective_area_arr(l: np.ndarray, effective_area: float) -> np.ndarray:
|
||||
return np.ones_like(l) * effective_area
|
||||
|
||||
|
||||
def n_eff_pcf(wl_for_disp: np.ndarray, pcf_pitch: float, pcf_pitch_ratio: float) -> np.ndarray:
|
||||
def n_eff_pcf(l: np.ndarray, pcf_pitch: float, pcf_pitch_ratio: float) -> np.ndarray:
|
||||
"""
|
||||
semi-analytical computation of the dispersion profile of a triangular Index-guiding PCF
|
||||
|
||||
Parameters
|
||||
----------
|
||||
wl_for_disp : np.ndarray, shape (n,)
|
||||
l : np.ndarray, shape (n,)
|
||||
wavelengths over which to calculate the dispersion
|
||||
pcf_pitch : float
|
||||
distance between air holes in m
|
||||
@@ -601,18 +538,18 @@ def n_eff_pcf(wl_for_disp: np.ndarray, pcf_pitch: float, pcf_pitch_ratio: float)
|
||||
r_eff = pcf_pitch / np.sqrt(3)
|
||||
pi2a = pipi * r_eff
|
||||
|
||||
ratio_l = wl_for_disp / pcf_pitch
|
||||
ratio_l = l / pcf_pitch
|
||||
|
||||
A, B = saitoh_paramters(pcf_pitch_ratio)
|
||||
|
||||
V = A[0] + A[1] / (1 + A[2] * np.exp(A[3] * ratio_l))
|
||||
W = B[0] + B[1] / (1 + B[2] * np.exp(B[3] * ratio_l))
|
||||
|
||||
n_FSM2 = 1.45**2 - (wl_for_disp * V / (pi2a)) ** 2
|
||||
n_eff2 = (wl_for_disp * W / (pi2a)) ** 2 + n_FSM2
|
||||
n_FSM2 = 1.45**2 - (l * V / (pi2a)) ** 2
|
||||
n_eff2 = (l * W / (pi2a)) ** 2 + n_FSM2
|
||||
n_eff = np.sqrt(n_eff2)
|
||||
|
||||
chi_mat = mat.Sellmeier.load("silica").chi(wl_for_disp)
|
||||
chi_mat = mat.Sellmeier.load("silica").chi(l)
|
||||
return n_eff + np.sqrt(chi_mat + 1)
|
||||
|
||||
|
||||
@@ -675,14 +612,21 @@ def load_custom_effective_area(effective_area_file: DataFile, l: np.ndarray) ->
|
||||
wl, effective_area = effective_area_file.load_arrays(
|
||||
("wavelength", "wl"), ("A_eff", "effective_area")
|
||||
)
|
||||
return interp1d(wl, effective_area, fill_value=1, bounds_error=False)(l)
|
||||
return np.interp(l, wl, effective_area, left=0, right=0)
|
||||
|
||||
|
||||
def load_custom_dispersion(dispersion_file: DataFile) -> tuple[np.ndarray, np.ndarray]:
|
||||
wl_for_disp, D = dispersion_file.load_arrays(("wavelength", "wl"), "dispersion")
|
||||
interp_range = (np.min(wl_for_disp), np.max(wl_for_disp))
|
||||
beta2 = D_to_beta2(D, wl_for_disp)
|
||||
return wl_for_disp, beta2, interp_range
|
||||
def load_custom_dispersion(
|
||||
l: np.ndarray, dispersion_file: DataFile
|
||||
) -> tuple[np.ndarray, np.ndarray]:
|
||||
"""loads a custom dispersion and returns beta2(l) where it is specified, as well as indices"""
|
||||
out = np.zeros_like(l)
|
||||
|
||||
wl_file, D = dispersion_file.load_arrays(("wavelength", "wl"), "dispersion")
|
||||
wl_file = units.normalize_wavelengths(wl_file)
|
||||
|
||||
ind = np.where((l >= wl_file.min()) & (l <= wl_file.max()))[0]
|
||||
out[ind] = np.interp(l[ind], wl_file, D_to_beta2(D, wl_file))
|
||||
return out, ind
|
||||
|
||||
|
||||
def load_custom_loss(l: np.ndarray, loss_file: DataFile) -> np.ndarray:
|
||||
@@ -702,13 +646,24 @@ def load_custom_loss(l: np.ndarray, loss_file: DataFile) -> np.ndarray:
|
||||
loss in 1/m units
|
||||
"""
|
||||
wl, loss = loss_file.load_arrays(("wavelength", "wl"), "loss")
|
||||
return interp1d(wl, loss, fill_value=0, bounds_error=False)(l)
|
||||
wl = units.normalize_wavelengths(wl)
|
||||
return np.interp(l, wl, loss, left=0, right=0)
|
||||
|
||||
|
||||
def auto_dispersion_coefficients(
|
||||
w_c: np.ndarray,
|
||||
dispersion_ind: np.ndarray,
|
||||
beta2_arr: np.ndarray,
|
||||
interpolation_degree: int,
|
||||
) -> np.ndarray:
|
||||
return dispersion_coefficients(
|
||||
w_c[dispersion_ind], beta2_arr[dispersion_ind], interpolation_degree
|
||||
)
|
||||
|
||||
|
||||
def dispersion_coefficients(
|
||||
w_for_disp: np.ndarray,
|
||||
w_c: np.ndarray,
|
||||
beta2_arr: np.ndarray,
|
||||
w0: float,
|
||||
interpolation_degree: int,
|
||||
):
|
||||
"""
|
||||
@@ -716,10 +671,10 @@ def dispersion_coefficients(
|
||||
|
||||
Parameters
|
||||
----------
|
||||
wl_for_disp : 1D array
|
||||
wavelength
|
||||
beta2 : 1D array
|
||||
beta2 as function of wl_for_disp
|
||||
w : np.ndarray, shape (n,)
|
||||
angular frequencies array
|
||||
beta2 : np.ndarray, shape (n,)
|
||||
beta2 as function of w
|
||||
w0 : float
|
||||
pump angular frequency
|
||||
interpolation_degree : int
|
||||
@@ -734,10 +689,7 @@ def dispersion_coefficients(
|
||||
# we get the beta2 Taylor coeffiecients by making a fit around w0
|
||||
if interpolation_degree < 2:
|
||||
raise ValueError(f"interpolation_degree must be at least 2, got {interpolation_degree}")
|
||||
w_c = w_for_disp - w0
|
||||
|
||||
w_c = w_c[2:-2]
|
||||
beta2_arr = beta2_arr[2:-2]
|
||||
fit = Chebyshev.fit(w_c, beta2_arr, interpolation_degree)
|
||||
poly_coef = cheb2poly(fit.convert().coef)
|
||||
beta2_coef = poly_coef * np.cumprod([1] + list(range(1, interpolation_degree + 1)))
|
||||
@@ -815,7 +767,7 @@ def delayed_raman_t(t: np.ndarray, raman_type: str) -> np.ndarray:
|
||||
print("Not able to find the measured Raman response function. Going with agrawal model")
|
||||
return delayed_raman_t(t, raman_type="agrawal")
|
||||
|
||||
hr_arr = interp1d(t_stored, hr_arr_stored, bounds_error=False, fill_value=0)(t)
|
||||
hr_arr = np.interp(t, t_stored, hr_arr_stored, left=0, right=0)
|
||||
else:
|
||||
print("invalid raman response function, aborting")
|
||||
quit()
|
||||
@@ -895,13 +847,13 @@ def fast_direct_dispersion(w: np.ndarray, w0: float, n_eff: np.ndarray, w0_ind:
|
||||
return -1j * (beta_arr - beta1_arr[w0_ind] * (w - w0) - beta_arr[w0_ind])
|
||||
|
||||
|
||||
def effective_core_radius(wl_for_disp, core_radius, s=0.08, h=200e-9):
|
||||
def effective_core_radius(l, core_radius, s=0.08, h=200e-9):
|
||||
"""
|
||||
return the variable core radius according to Eq. S2.2 from Köttig2017
|
||||
|
||||
Parameters
|
||||
----------
|
||||
wl_for_disp : ndarray, shape (n, )
|
||||
l : ndarray, shape (n, )
|
||||
array of wl over which to calculate the effective core radius
|
||||
core_radius : float
|
||||
physical core radius in m
|
||||
@@ -914,12 +866,12 @@ def effective_core_radius(wl_for_disp, core_radius, s=0.08, h=200e-9):
|
||||
-------
|
||||
effective_core_radius : ndarray, shape (n, )
|
||||
"""
|
||||
return core_radius / (1 + s * wl_for_disp**2 / (core_radius * h))
|
||||
return core_radius / (1 + s * l**2 / (core_radius * h))
|
||||
|
||||
|
||||
def effective_radius_HCARF(core_radius, t, f1, f2, wl_for_disp):
|
||||
def effective_radius_HCARF(core_radius, t, f1, f2, l):
|
||||
"""eq. 3 in Hasan 2018"""
|
||||
return f1 * core_radius * (1 - f2 * wl_for_disp**2 / (core_radius * t))
|
||||
return f1 * core_radius * (1 - f2 * l**2 / (core_radius * t))
|
||||
|
||||
|
||||
def scalar_loss(alpha: float, w_num: int) -> np.ndarray:
|
||||
@@ -952,15 +904,15 @@ def capillary_loss(wl: np.ndarray, he_mode: tuple[int, int], core_radius: float)
|
||||
|
||||
|
||||
def safe_capillary_loss(
|
||||
wl_for_disp: np.ndarray,
|
||||
l: np.ndarray,
|
||||
dispersion_ind: np.ndarray,
|
||||
w_num: int,
|
||||
core_radius: float,
|
||||
he_mode: tuple[int, int],
|
||||
) -> np.ndarray:
|
||||
alpha = capillary_loss(wl_for_disp, he_mode, core_radius)
|
||||
alpha = capillary_loss(l[dispersion_ind], he_mode, core_radius)
|
||||
loss_arr = np.zeros(w_num)
|
||||
loss_arr[dispersion_ind] = alpha[2:-2]
|
||||
loss_arr[dispersion_ind] = alpha
|
||||
return loss_arr
|
||||
|
||||
|
||||
@@ -1128,7 +1080,7 @@ def n_eff_correction_vincetti(
|
||||
|
||||
|
||||
def n_eff_vincetti(
|
||||
wl_for_disp: np.ndarray,
|
||||
l: np.ndarray,
|
||||
wavelength: float,
|
||||
n_gas_2: np.ndarray,
|
||||
thickness: float,
|
||||
@@ -1141,7 +1093,7 @@ def n_eff_vincetti(
|
||||
"""
|
||||
Parameters
|
||||
----------
|
||||
wl_for_disp : ndarray
|
||||
l : ndarray
|
||||
wavelength (m) array over which to compute the refractive index
|
||||
wavelength : float
|
||||
center wavelength / pump wavelength
|
||||
@@ -1182,18 +1134,16 @@ def n_eff_vincetti(
|
||||
"""
|
||||
|
||||
if n_clad_2 is None:
|
||||
n_clad_2 = mat.Sellmeier.load("silica").n_gas_2(wl_for_disp)
|
||||
n_clad_2 = mat.Sellmeier.load("silica").n_gas_2(l)
|
||||
|
||||
n_clad_0 = np.sqrt(n_clad_2[argclosest(wl_for_disp, wavelength)])
|
||||
n_clad_0 = np.sqrt(n_clad_2[argclosest(l, wavelength)])
|
||||
|
||||
f = normalized_frequency_vincetti(wl_for_disp, thickness, n_clad_2, n_gas_2)
|
||||
r_co_eff = effective_core_radius_vincetti(wl_for_disp, f, tube_radius, gap, n_tubes)
|
||||
f = normalized_frequency_vincetti(l, thickness, n_clad_2, n_gas_2)
|
||||
r_co_eff = effective_core_radius_vincetti(l, f, tube_radius, gap, n_tubes)
|
||||
r_co = core_radius_from_capillaries(tube_radius, gap, n_tubes)
|
||||
d_n_eff = n_eff_correction_vincetti(
|
||||
wl_for_disp, f, thickness / tube_radius, r_co, n_clad_0, n_terms
|
||||
)
|
||||
d_n_eff = n_eff_correction_vincetti(l, f, thickness / tube_radius, r_co, n_clad_0, n_terms)
|
||||
|
||||
n_gas = np.sqrt(n_gas_2)
|
||||
|
||||
# eq. (21) in [1]
|
||||
return n_gas - 0.125 / n_gas * (u_nm(1, 1) * wl_for_disp / (np.pi * r_co_eff)) ** 2 + d_n_eff
|
||||
return n_gas - 0.125 / n_gas * (u_nm(1, 1) * l / (np.pi * r_co_eff)) ** 2 + d_n_eff
|
||||
|
||||
@@ -321,9 +321,9 @@ class Gas:
|
||||
return f"{self.__class__.__name__}({self.name!r})"
|
||||
|
||||
|
||||
def n_gas_2(wl_for_disp: np.ndarray, gas_name: str, pressure: float, temperature: float):
|
||||
def n_gas_2(l: np.ndarray, gas_name: str, pressure: float, temperature: float):
|
||||
"""Returns the sqare of the index of refraction of the specified gas"""
|
||||
return Sellmeier.load(gas_name).n_gas_2(wl_for_disp, temperature, pressure)
|
||||
return Sellmeier.load(gas_name).n_gas_2(l, temperature, pressure)
|
||||
|
||||
|
||||
def pressure_from_gradient(ratio: float, p0: float, p1: float) -> float:
|
||||
|
||||
@@ -461,3 +461,12 @@ def sort_axis(
|
||||
out_ax = plt_range.unit.inv(cropped)
|
||||
|
||||
return out_ax, indices, (out_ax[0], out_ax[-1])
|
||||
|
||||
|
||||
def normalize_wavelengths(wl: np.ndarray) -> np.ndarray:
|
||||
"""attempts to guess the units of wl and return the same array in base SI units (m)"""
|
||||
if np.all((wl > 0.01) & (wl < 20)):
|
||||
return wl * 1e-6
|
||||
elif np.all(wl >= 20):
|
||||
return wl * 1e-9
|
||||
return wl
|
||||
|
||||
BIN
tests/data/PM1050NEG_aeff_slow.npz
Normal file
BIN
tests/data/PM1050NEG_aeff_slow.npz
Normal file
Binary file not shown.
BIN
tests/data/PM1050NEG_dispersion.npz
Normal file
BIN
tests/data/PM1050NEG_dispersion.npz
Normal file
Binary file not shown.
BIN
tests/data/PM1050NEG_loss.npz
Normal file
BIN
tests/data/PM1050NEG_loss.npz
Normal file
Binary file not shown.
75
tests/test_dispersion.py
Normal file
75
tests/test_dispersion.py
Normal file
@@ -0,0 +1,75 @@
|
||||
import pytest
|
||||
|
||||
import scgenerator as sc
|
||||
|
||||
PARAMS1 = sc.Parameters(
|
||||
name="Dudley2006",
|
||||
wavelength=835e-9,
|
||||
width=50e-15,
|
||||
peak_power=10e3,
|
||||
repetition_rate=20e6,
|
||||
shape="sech",
|
||||
# fiber
|
||||
length=15e-2,
|
||||
raman_type="measured",
|
||||
beta2_coefficients=[
|
||||
-11.830e-27,
|
||||
8.1038e-42,
|
||||
-9.5205e-57,
|
||||
2.0737e-71,
|
||||
-5.3943e-86,
|
||||
1.3486e-100,
|
||||
-2.5495e-115,
|
||||
3.0524e-130,
|
||||
-1.7140e-145,
|
||||
],
|
||||
gamma=0.11,
|
||||
# simulation
|
||||
tolerated_error=1e-6,
|
||||
wavelength_window=[400e-9, 1500e-9],
|
||||
t_num=8192,
|
||||
quantum_noise=False,
|
||||
z_num=128,
|
||||
)
|
||||
PARAMS2 = sc.Parameters(
|
||||
name="dual comb",
|
||||
wavelength=1056e-9,
|
||||
width=78e-15,
|
||||
peak_power=13e3,
|
||||
repetition_rate=20e6,
|
||||
shape="gaussian",
|
||||
# fiber
|
||||
length=20e-2,
|
||||
n2=2.2e-20,
|
||||
raman_type="measured",
|
||||
dispersion_file="tests/data/PM1050NEG_dispersion.npz",
|
||||
loss_file="tests/data/PM1050NEG_loss.npz",
|
||||
effective_area_file="tests/data/PM1050NEG_aeff_slow.npz",
|
||||
# simulation
|
||||
interpolation_degree=12,
|
||||
tolerated_error=1e-8,
|
||||
wavelength_window=[500e-9, 1500e-9],
|
||||
t_num=8192,
|
||||
quantum_noise=True,
|
||||
z_num=128,
|
||||
)
|
||||
|
||||
|
||||
def test_poly_dispersion_grid_size():
|
||||
|
||||
params = PARAMS1.compile()
|
||||
disp_ind = params.compute("dispersion_ind")
|
||||
|
||||
assert disp_ind is not None
|
||||
assert all((params.l[disp_ind] < 1500e-9) & (params.l[disp_ind] > 400e-9))
|
||||
assert len(params.compute("beta2_arr")) == params.t_num
|
||||
|
||||
|
||||
def test_custom_dispersion_grid_size():
|
||||
params = PARAMS2.compile()
|
||||
params.compute("t")
|
||||
disp_ind = params.compute("dispersion_ind")
|
||||
|
||||
assert disp_ind is not None
|
||||
assert all((params.l[disp_ind] < 1500e-9) & (params.l[disp_ind] > 400e-9))
|
||||
assert len(params.compute("beta2_arr")) == params.t_num
|
||||
@@ -14,12 +14,6 @@ def test_scaling():
|
||||
assert dt == pytest.approx(period / (nt - 1))
|
||||
|
||||
|
||||
def test_wl_dispersion():
|
||||
t = sc.tspace(t_num=1 << 15, dt=3.8e-15)
|
||||
w = sc.wspace(t)
|
||||
wl = sc.units.nm_rads(w + sc.units.nm_rads(1546)) * 1e-9
|
||||
wl_disp, ind_disp = sc.fiber.lambda_for_envelope_dispersion(wl, (950e-9, 4000e-9))
|
||||
assert all(np.diff(wl_disp) > 0)
|
||||
|
||||
|
||||
def test_iwspace():
|
||||
|
||||
Reference in New Issue
Block a user