Esempio n. 1
0
    def __call__(self, *args):
        r"""Compute the gain coefficient.

        Parameters
        ----------
        omega :
            The angular frequency. :math:`[rad\cdot ps^{-1}]`
        order :
            The derivative order of the Taylor series expansion.

        Returns
        -------
        :
            The value of the gain coefficient. :math:`[km^{-1}]`

        """
        omega = args[0]
        fct = CallableContainer(DopedFiberGain.calc_doped_fiber_gain,
                                [self._sigma, self._overlap, self._N])

        if (len(args) == 1):  # No order
            res = np.zeros_like(omega)
            res = fct(omega)
        else:
            order = args[1]
            res = np.zeros((order + 1, len(omega)))
            for i in range(order + 1):
                res[i] = util.deriv(fct, omega, i)

        return res
Esempio n. 2
0
    def __call__(self, omega):
        r"""Compute the derivatives of the absorption cross sections.

        Parameters
        ----------
        omega :
            The angular frequency. :math:`[rad\cdot ps^{-1}]`

        Returns
        -------
        :
            The nth derivative of the propagation constant.
            :math:`[ps^{i}\cdot km^{-1}]`

        """
        if (self._sigma_e is None):

            return AbsorptionSection.calc_sigma(omega, self._coefficients,
                                                self._lambda_range)
        else:
            mc = McCumber(dopant=self._dopant, medium=self._medium)
            fct = CallableContainer(mc.cross_section_absorption,
                                    [omega, self._sigma_e, self._T])

            return fct(omega)
Esempio n. 3
0
    def __call__(self, omega):
        r"""Compute the asymmetry coefficient.

        Parameters
        ----------
        omega :
            The angular frequency. :math:`[rad\cdot ps^{-1}]`

        Returns
        -------
        :
            The value of the asymmetry coefficient. :math:`[km^{-1}]`

        """
        fct = CallableContainer(AsymmetryCoeff.calc_delta,
                                [self._beta_1, self._beta_2])

        return fct(omega)
Esempio n. 4
0
    def __call__(self, omega):
        r"""Compute the effective area.

        Parameters
        ----------
        omega :
            The angular frequency. :math:`[rad\cdot ps^{-1}]`

        Returns
        -------
        :
            Value of the effective area. :math:`[\mu m^2]`

        """
        fct = CallableContainer(EffectiveArea.calc_effective_area,
                                [self._v_nbr, self._core_radius])

        return fct(omega)
Esempio n. 5
0
    def __call__(self, omega):
        r"""Calculate the overlap factor.

        Parameters
        ----------
        omega :
            The angular frequency.  :math:`[rad\cdot ps^{-1}]`

        Returns
        -------
        :
            Value of the overlap factor.

        """
        fct = CallableContainer(OverlapFactor.calc_overlap_factor,
                                [self._eff_area, self._doped_area])

        return fct(omega)
Esempio n. 6
0
    def __call__(self, omega):
        r"""Compute the coupling coefficient.

        Parameters
        ----------
        omega :
            The angular frequency. :math:`[rad\cdot ps^{-1}]`

        Returns
        -------
        :
            The value of the coupling coefficient. :math:`[km^{-1}]`

        """
        fct = CallableContainer(
            CouplingCoeff.calc_kappa,
            [omega, self._v_nbr, self._a, self._d, self._ref_index])

        return fct(omega)
Esempio n. 7
0
    def __call__(self, omega):
        r"""Compute the energy saturation.

        Parameters
        ----------
        omega :
            The angular frequency. :math:`[rad\cdot ps^{-1}]`

        Returns
        -------
        :
            The value of the energy saturation. :math:`[J]`

        """
        fct = CallableContainer(EnergySaturation.calc_energy_saturation, [
            omega, self._eff_area, self._sigma_a, self._sigma_e, self._overlap
        ])

        return fct(omega)
Esempio n. 8
0
    def __call__(self, omega):
        r"""Compute the non-linear phase shift.

        Parameters
        ----------
        omega :
            The angular frequency. :math:`[rad\cdot ps^{-1}]`

        Returns
        -------
        :
            The value of the non-linear phase shift.

        """
        fct = CallableContainer(NLPhaseShift.calc_nl_phase_shift,
                                [omega, self._nl_index, self._eff_area,
                                 self._power, self._dz])

        return fct(omega)
Esempio n. 9
0
    def __call__(self, omega):
        r"""Compute the effective area.

        Parameters
        ----------
        omega :
            The angular frequency.  :math:`[rad\cdot ps^{-1}]`


        Returns
        -------
        :
            The numerical aperture.

        """
        fct = CallableContainer(NumericalAperture.calc_NA,
                                [self._n_core, self._n_clad])

        return fct(omega)
Esempio n. 10
0
    def __call__(self, omega):
        r"""Compute the recovery time.

        Parameters
        ----------
        omega :
            The angular frequency. :math:`[rad\cdot ps^{-1}]`

        Returns
        -------
        :
            The value of the recovery time. :math:`[\mu s]`

        """
        fct = CallableContainer(FiberRecoveryTime.calc_recovery_time, [
            omega, self._core_area, self._sigma_a, self._sigma_e,
            self._overlap, self._power, self._tau
        ])

        return fct(omega)
Esempio n. 11
0
    def __call__(self, omega):
        r"""Calculate the non linear parameter.

        Parameters
        ----------
        omega :
            The angular frequency.  :math:`[rad\cdot ps^{-1}]`


        Returns
        -------
        :
            Value of the non linear parameter.
            :math:`[rad\cdot W^{-1}\cdot km^{-1}]`

        """
        fct = CallableContainer(NLCoefficient.calc_nl_coefficient,
                                [omega, self._nl_index, self._eff_area])

        return fct(omega)
Esempio n. 12
0
    def __call__(self, omega):
        r"""Compute the resonant index.

        Parameters
        ----------
        omega :
            The angular frequency. :math:`[rad\cdot ps^{-1}]`

        Returns
        -------
        :
            Value of the resonant index.

        """
        #print(self._N)
        fct = CallableContainer(ResonantIndex.calc_res_index,
                                [omega, self._n_0, self._N, self._main_trans,
                                 self._gs, self._esa, self._gsa])

        return fct(omega)
Esempio n. 13
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)