예제 #1
0
    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
예제 #2
0
    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)
예제 #3
0
    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
예제 #4
0
    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)