def __init__(self, delta: Optional[float] = None, beta_01: Optional[Union[float, Callable]] = None, beta_02: Optional[Union[float, Callable]] = None, medium: str = 'SiO2') -> None: r""" Parameters ---------- delta : The asymmetry measure coefficient. If a callable is provided, variable must be angular frequency. :math:`[ps^{-1}]` beta_01 : The zeroth order Taylor series dispersion coefficient of first waveguide. :math:`[km^{-1}]` beta_02 : The zeroth order Taylor series dispersion coefficient of second waveguide. :math:`[km^{-1}]` medium : The medium in which the dispersion is considered. """ super().__init__() self._medium: str = medium self._delta: float self._predict: Optional[Callable] = None if ((delta is None) and (beta_01 is not None) and (beta_02 is not None)): if (not callable(beta_01) and not callable(beta_02)): self._delta = Asymmetry.calc_delta(beta_01, beta_02) #else: # self._predict = lambda om1, om2: Asymmetry.calc_beta( # beta_01(om1, 0)[0], beta_02(om2, 0)[0]) elif (delta is None): beta = lambda omega: Dispersion.calc_beta_coeffs( omega, 0, Sellmeier(medium))[0] self._predict = lambda om1, om2: Asymmetry.calc_delta( beta(om1), beta(om2)) else: self._delta = delta
def __init__(self, alpha: Optional[Union[List[float], Callable]], alpha_order: int, beta: Optional[Union[List[float], Callable]], beta_order: int, gamma: Optional[Union[float, Callable]], core_radius: float, NA: Union[float, Callable], ATT: bool, DISP: bool, medium: str) -> None: r""" Parameters ---------- alpha : The derivatives of the attenuation coefficients. :math:`[km^{-1}, ps\cdot km^{-1}, ps^2\cdot km^{-1}, ps^3\cdot km^{-1}, \ldots]` If a callable is provided, variable must be angular frequency. :math:`[ps^{-1}]` alpha_order : The order of alpha coefficients to take into account. (will be ignored if alpha values are provided - no file) beta : The derivatives of the propagation constant. :math:`[km^{-1}, ps\cdot km^{-1}, ps^2\cdot km^{-1}, ps^3\cdot km^{-1}, \ldots]` If a callable is provided, variable must be angular frequency. :math:`[ps^{-1}]` beta_order : The order of beta coefficients to take into account. (will be ignored if beta values are provided - no file) gamma : The non linear coefficient. :math:`[rad\cdot W^{-1}\cdot km^{-1}]` If a callable is provided, variable must be angular frequency. :math:`[ps^{-1}]` core_radius : The radius of the core. :math:`[\mu m]` NA : The numerical aperture. ATT : If True, trigger the attenuation. DISP : If True, trigger the dispersion. medium : The main medium of the fiber. """ super().__init__() self._medium: str = medium self._disp_ind: int = -1 self._delays_effects: List[AbstractEffect] = [] if (ATT): self._effects_lin.append( Attenuation(alpha, alpha_order, skip_taylor=[1])) self._delays_effects.append(self._effects_lin[-1]) if (DISP): self._effects_lin.append( Dispersion(beta, beta_order, start_taylor=2)) self._disp_ind = len(self._effects_lin) - 1 self._delays_effects.append(self._effects_lin[-1]) self._gamma: Array[float] self._predict_gamma: Optional[Callable] = None if (gamma is not None): if (callable(gamma)): self._predict_gamma = gamma else: self._gamma = np.asarray(util.make_list(gamma)) else: nl_index = NLIndex(medium) eff_area = EffectiveArea(core_radius, NA) self._predict_gamma = NLCoefficient(nl_index, eff_area)
def __init__(self, re: REFiber, alpha: Optional[Union[List[float], Callable]], alpha_order: int, beta: Optional[Union[List[float], Callable]], beta_order: int, gamma: Optional[Union[float, Callable]], gain_order: int, R_0: float, R_L: float, nl_index: Optional[Union[float, Callable]], ATT: bool, DISP: bool, GS: bool, medium: str, dopant: str) -> None: r""" Parameters ---------- re : A fiber rate equation object. alpha : The derivatives of the attenuation coefficients. :math:`[km^{-1}, ps\cdot km^{-1}, ps^2\cdot km^{-1}, ps^3\cdot km^{-1}, \ldots]` If a callable is provided, variable must be angular frequency. :math:`[ps^{-1}]` alpha_order : The order of alpha coefficients to take into account. (will be ignored if alpha values are provided - no file) beta : The derivatives of the propagation constant. :math:`[km^{-1}, ps\cdot km^{-1}, ps^2\cdot km^{-1}, ps^3\cdot km^{-1}, \ldots]` If a callable is provided, variable must be angular frequency. :math:`[ps^{-1}]` beta_order : The order of beta coefficients to take into account. (will be ignored if beta values are provided - no file) gamma : The non linear coefficient. :math:`[rad\cdot W^{-1}\cdot km^{-1}]` If a callable is provided, variable must be angular frequency. :math:`[ps^{-1}]` gain_order : The order of the gain coefficients to take into account. (from the Rate Equations resolution) R_0 : The reflectivity at the fiber start. R_L : The reflectivity at the fiber end. nl_index : The non linear index. Used to calculate the non linear parameter. :math:`[m^2\cdot W^{-1}]` ATT : If True, trigger the attenuation. DISP : If True, trigger the dispersion. GS : If True, trigger the gain saturation. medium : The main medium of the fiber amplifier. dopant : The doped medium of the fiber amplifier. """ # keep all methods from NLSE but bypass constructor AbstractEquation.__init__(self) # grand parent constructor self._medium: str = medium self._dopant: str = dopant self._re: REFiber = re self._R_L: float = R_L self._R_0: float = R_0 self._delay_time: Array[float] self._coprop: bool # Effects ------------------------------------------------------ self._att_ind: int = -1 self._disp_ind: int = -1 self._gs_ind: int = -1 self._gain_ind: int = -1 self._gain_order: int = gain_order self._beta_order: int = beta_order if (ATT): self._effects_lin.append(Attenuation(alpha, alpha_order)) self._att_ind = len(self._effects_lin) - 1 if (DISP): self._effects_lin.append(Dispersion(beta, beta_order)) self._disp_ind = len(self._effects_lin) - 1 if (GS): start_taylor_gain = 1 self._effects_lin.append(GainSaturation(re, [0.0])) self._gs_ind = len(self._effects_lin) - 1 else: start_taylor_gain = 0 alpha_temp = [0.0 for i in range(self._gain_order + 1)] self._effects_lin.append( Attenuation(alpha_temp, start_taylor=start_taylor_gain)) self._gain_ind = len(self._effects_lin) - 1 # Gamma -------------------------------------------------------- self._nl_index: Union[float, Callable] = NLIndex(medium=medium) if\ (nl_index is None) else nl_index self._gamma: Array[float] self._predict_gamma: Optional[Callable] = None self._custom_gamma: bool = False if (gamma is not None): if (callable(gamma)): self._custom_gamma = True self._predict_gamma = gamma else: self._gamma = np.asarray(util.make_list(gamma)) else: self._predict_gamma = NLCoefficient.calc_nl_coefficient
def __init__(self, alpha: Optional[Union[List[float], Callable]], alpha_order: int, beta: Optional[Union[List[float], Callable]], beta_order: int, gamma: Optional[Union[float, Callable]], core_radius: float, clad_radius: float, n_core: Optional[Union[float, Callable]], n_clad: Optional[Union[float, Callable]], NA: Optional[Union[float, Callable]], v_nbr: Optional[Union[float, Callable]], eff_area: Optional[Union[float, Callable]], nl_index: Optional[Union[float, Callable]], medium_core: str, medium_clad: str, temperature: float, ATT: bool, DISP: bool, NOISE: bool, UNI_OMEGA: bool, STEP_UPDATE: bool, INTRA_COMP_DELAY: bool, INTRA_PORT_DELAY: bool, INTER_PORT_DELAY: bool) -> None: r""" Parameters ---------- alpha : The derivatives of the attenuation coefficients. :math:`[km^{-1}, ps\cdot km^{-1}, ps^2\cdot km^{-1}, ps^3\cdot km^{-1}, \ldots]` If a callable is provided, variable must be angular frequency. :math:`[ps^{-1}]` alpha_order : The order of alpha coefficients to take into account. (will be ignored if alpha values are provided - no file) beta : The derivatives of the propagation constant. :math:`[km^{-1}, ps\cdot km^{-1}, ps^2\cdot km^{-1}, ps^3\cdot km^{-1}, \ldots]` If a callable is provided, variable must be angular frequency. :math:`[ps^{-1}]` beta_order : The order of beta coefficients to take into account. (will be ignored if beta values are provided - no file) gamma : The non linear coefficient. :math:`[rad\cdot W^{-1}\cdot km^{-1}]` If a callable is provided, variable must be angular frequency. :math:`[ps^{-1}]` core_radius : The radius of the core. :math:`[\mu m]` clad_radius : The radius of the cladding. :math:`[\mu m]` n_core : The refractive index of the core. If a callable is provided, variable must be angular frequency. :math:`[ps^{-1}]` n_clad : The refractive index of the clading. If a callable is provided, variable must be angular frequency. :math:`[ps^{-1}]` NA : The numerical aperture. If a callable is provided, variable must be angular frequency. :math:`[ps^{-1}]` v_nbr : The V number. If a callable is provided, variable must be angular frequency. :math:`[ps^{-1}]` eff_area : The effective area. If a callable is provided, variable must be angular frequency. :math:`[ps^{-1}]` nl_index : The non-linear coefficient. If a callable is provided, variable must be angular frequency. :math:`[ps^{-1}]` medium_core : The medium of the fiber core. medium_clad : The medium of the fiber cladding. temperature : The temperature of the medium. :math:`[K]` ATT : If True, trigger the attenuation. DISP : If True, trigger the dispersion. NOISE : If True, trigger the noise calculation. UNI_OMEGA : If True, consider only the center omega for computation. Otherwise, considered omega discretization. STEP_UPDATE : If True, update component parameters at each spatial space step by calling the _update_variables method. INTRA_COMP_DELAY : If True, take into account the relative time difference, between all waves, that is acquired while propagating in the component. INTRA_PORT_DELAY : If True, take into account the initial relative time difference between channels of all fields but for each port. INTER_PORT_DELAY : If True, take into account the initial relative time difference between channels of all fields of all ports. """ super().__init__(nbr_eqs=1, SHARE_WAVES=False, prop_dir=[True], NOISE=NOISE, STEP_UPDATE=STEP_UPDATE, INTRA_COMP_DELAY=INTRA_COMP_DELAY, INTRA_PORT_DELAY=INTRA_PORT_DELAY, INTER_PORT_DELAY=INTER_PORT_DELAY) # media -------------------------------------------------------- self._medium_core: str = medium_core self._medium_clad: str = medium_clad # Refractive indices and numerical aperture -------------------- self._n_core: Union[float, Callable] self._n_clad: Union[float, Callable] self._NA: Union[float, Callable] fct_calc_n_core = NumericalAperture.calc_n_core fct_calc_n_clad = NumericalAperture.calc_n_core if (n_core is not None and n_clad is not None and NA is not None): self._n_core = n_core self._n_clad = n_clad self._NA = NA elif (n_core is not None and n_clad is not None): self._n_core = n_core self._n_clad = n_clad self._NA = NumericalAperture(self._n_core, self._n_clad) elif (n_core is not None and NA is not None): self._n_core = n_core self._NA = NA self._n_clad = CallableContainer(fct_calc_n_clad, [self._NA, self._n_core]) elif (n_clad is not None and NA is not None): self._n_clad = n_clad self._NA = NA self._n_core = CallableContainer(fct_calc_n_core, [self._NA, self._n_clad]) elif (n_core is not None): self._n_core = n_core self._n_clad = Sellmeier(medium_clad, cst.FIBER_CLAD_DOPANT, cst.CLAD_DOPANT_CONCENT) self._NA = NumericalAperture(self._n_core, self._n_clad) elif (n_clad is not None): self._n_clad = n_clad self._n_core = Sellmeier(medium_core, cst.FIBER_CORE_DOPANT, cst.CORE_DOPANT_CONCENT) self._NA = NumericalAperture(self._n_core, self._n_clad) elif (NA is not None): self._NA = NA self._n_core = Sellmeier(medium_core, cst.FIBER_CORE_DOPANT, cst.CORE_DOPANT_CONCENT) self._n_clad = CallableContainer(fct_calc_n_clad, [self._NA, self._n_core]) else: # all None self._n_core = Sellmeier(medium_core, cst.FIBER_CORE_DOPANT, cst.CORE_DOPANT_CONCENT) self._n_clad = Sellmeier(medium_clad, cst.FIBER_CLAD_DOPANT, cst.CLAD_DOPANT_CONCENT) self._NA = NumericalAperture(self._n_core, self._n_clad) # V number ----------------------------------------------------- self._v_nbr: Union[float, Callable] if (v_nbr is not None): self._v_nbr = v_nbr else: self._v_nbr = VNumber(self._NA, core_radius) # Effective Area ----------------------------------------------- self._eff_area: Union[float, Callable] if (eff_area is not None): self._eff_area = eff_area else: self._eff_area = EffectiveArea(self._v_nbr, core_radius) # Non-linear index --------------------------------------------- self._nl_index: Union[float, Callable] if (nl_index is not None): self._nl_index = nl_index else: self._nl_index = NLIndex(medium_core) # Non-linear coefficient --------------------------------------- self._predict_gamma: Optional[Callable] = None self._gamma: np.ndarray if (gamma is not None): if (callable(gamma)): self._predict_gamma = gamma else: self._gamma = np.asarray(util.make_list(gamma)) else: self._predict_gamma = NLCoefficient(self._nl_index, self._eff_area) # Effects ------------------------------------------------------ self._att: Optional[AbstractEffectTaylor] = None self._disp: Optional[AbstractEffectTaylor] = None if (ATT): if (alpha is not None): self._att = Attenuation(alpha, alpha_order, UNI_OMEGA=UNI_OMEGA) self._add_lin_effect(self._att, 0, 0) self._add_delay_effect(self._att) else: util.warning_terminal("Currently no method to calculate " "attenuation as a function of the medium. Must provide " "attenuation coefficient alpha, otherwise attenuation " "effect will be ignored.") # Even if DISP==False, need _beta in CNLSE self._beta: Union[List[float], Callable] if (beta is None): self._beta = ChromaticDisp(self._n_core) else: self._beta = beta if (DISP): self._disp = Dispersion(self._beta, beta_order, start_taylor=2, UNI_OMEGA=UNI_OMEGA) self._add_lin_effect(self._disp, 0, 0) self._add_delay_effect(self._disp)