#coding: utf8
import plask


class BesselCyl(plask.Solver):
    """
    BesselCyl(name="")
    
    Optical Solver using Bessel expansion in cylindrical coordinates.
    
    It calculates optical modes and optical field distribution using Bessel slab method
    and reflection transfer in two-dimensional cylindrical space.
    """
    class Eigenmodes(object):
        """
        Layer eignemodes
        
        This is an advanced class allowing to extract eignemodes in each layer.
        """
        class Eigenmode(object):
            """
            Single eignemode. You can access object of this class by indexing
            :class:`~optical.slab.BesselCyl.Eigenmodes` object.
            """
            flux = None
            """
            Vertical flux for the eigenmode.
            
            This is equal to the vertical component of the Pointing vector integrated over
            the numerical domain.
            """

            kvert = None
            """
            Vertical propagation constant for the eigenmode.
            """

            raw_E = None
            """
            Electric field coefficients for the eigenmode.
            """

            raw_H = None
            """
            Magnetic field coefficients for the eigenmode.
            """


        outLightE = None
        """
        Provider of the computed electric field [V/m].
        
        
        outLightE(n=0, mesh, interpolation='default')
        
        :param int n: Number of the mode found with :meth:`find_mode`.:param mesh mesh: Target mesh to get the field at.
        :param str interpolation: Requested interpolation method.
        
        :return: Data with the electric field on the specified mesh **[V/m]**.
        
        You may obtain the number of different values this provider can return by
        testing its length.
        
        Example:
           Connect the provider to a receiver in some other solver:
        
           >>> other_solver.inLightE = solver.outLightE
        
           Obtain the provided field:
        
           >>> solver.outLightE(0, mesh)
           <plask.Data at 0x1234567>
        
           Test the number of provided values:
        
           >>> len(solver.outLightE)
           3
        
        See also:
        
           Provider class: :class:`plask.flow.LightEProviderCyl`
        
           Receciver class: :class:`plask.flow.LightEReceiverCyl`
        """

        outLightH = None
        """
        Provider of the computed electric field [A/m].
        
        
        outLightH(n=0, mesh, interpolation='default')
        
        :param int n: Number of the mode found with :meth:`find_mode`.:param mesh mesh: Target mesh to get the field at.
        :param str interpolation: Requested interpolation method.
        
        :return: Data with the electric field on the specified mesh **[A/m]**.
        
        You may obtain the number of different values this provider can return by
        testing its length.
        
        Example:
           Connect the provider to a receiver in some other solver:
        
           >>> other_solver.inLightH = solver.outLightH
        
           Obtain the provided field:
        
           >>> solver.outLightH(0, mesh)
           <plask.Data at 0x1234567>
        
           Test the number of provided values:
        
           >>> len(solver.outLightH)
           3
        
        See also:
        
           Provider class: :class:`plask.flow.LightHProviderCyl`
        
           Receciver class: :class:`plask.flow.LightHReceiverCyl`
        """

        outLightMagnitude = None
        """
        Provider of the computed light intensity [W/m²].
        
        
        outLightMagnitude(n=0, mesh, interpolation='default')
        
        :param int n: Number of the mode found with :meth:`find_mode`.:param mesh mesh: Target mesh to get the field at.
        :param str interpolation: Requested interpolation method.
        
        :return: Data with the light intensity on the specified mesh **[W/m²]**.
        
        You may obtain the number of different values this provider can return by
        testing its length.
        
        Example:
           Connect the provider to a receiver in some other solver:
        
           >>> other_solver.inLightMagnitude = solver.outLightMagnitude
        
           Obtain the provided field:
        
           >>> solver.outLightMagnitude(0, mesh)
           <plask.Data at 0x1234567>
        
           Test the number of provided values:
        
           >>> len(solver.outLightMagnitude)
           3
        
        See also:
        
           Provider class: :class:`plask.flow.LightMagnitudeProviderCyl`
        
           Receciver class: :class:`plask.flow.LightMagnitudeReceiverCyl`
        """


    class Mode(object):
        """
        Detailed information about the mode.
        """
        k0 = None
        """
        Mode normalized frequency [1/µm].
        """

        lam = None
        """
        Mode wavelength [nm].
        """

        loss = None
        """
        Mode loss [1/cm].
        """

        m = None
        """
        Angular mode order.
        """

        power = None
        """
        Total power emitted into the mode.
        """

        wavelength = None
        """
        Mode wavelength [nm].
        """


    def compute_reflectivity(*args, **kwargs):
        """
        compute_reflectivity(self, lam, side, index)
        compute_reflectivity(self, lam, side, coeffs)
        
            Compute reflection coefficient on planar incidence [%].
            
            Args:
                lam (float or array of floats): Incident light wavelength.
                side (`top` or `bottom`): Side of the structure where the incident light is
                    present.
                index: Eigenmode number.
                coeffs: expansion coefficients of the incident vector.
        """

    def compute_transmittivity(*args, **kwargs):
        """
        compute_transmittivity(self, lam, side, index)
        compute_transmittivity(self, lam, side, coeffs)
        
            Compute transmission coefficient on planar incidence [%].
            
            Args:
                lam (float or array of floats): Incident light wavelength.
                side (`top` or `bottom`): Side of the structure where the incident light is
                    present.
                index: Eigenmode number.
                coeffs: expansion coefficients of the incident vector.
        """

    domain = None
    """
    Computational domain ('finite' or 'infinite').
    """

    emission = None
    """
    Direction of the useful light emission.
    
    Necessary for the over-threshold model to correctly compute the output power.
    Currently the fields are normalized only if this parameter is set to
    ``top`` or ``bottom``. Otherwise, it is ``undefined`` (default) and the fields
    are not normalized.
    """

    def find_mode(self, lam, m=None):
        """
        find_mode(self, lam, m=None)
        
            Compute the mode near the specified effective index.
            
            Only one of the following arguments can be given through a keyword.
            It is the starting point for search of the specified parameter.
            
            Args:
                lam (complex): Starting wavelength.
                m (int): HE/EH Mode angular number. If ``None``, use :attr:`m` attribute.
        """

    geometry = None
    """
    Geometry provided to the solver
    """

    def get_determinant(*args, **kwargs):
        """
        object get_determinant(tuple args, dict kwds) :
            Compute discontinuity matrix determinant.
            
            Arguments can be given through keywords only.
            
            Args:
                lam (complex): Wavelength.
                k0 (complex): Normalized frequency.
                m (int): HE/EH Mode angular number.
        """

    def get_raw_E(self, num, level):
        """
        get_raw_E(self, num, level)
        
            Get Bessel expansion coefficients for the electric field.
            
            This is a low-level function returning :math:`E_s` and :math:`E_p` Bessel
            expansion coefficients. Please refer to the detailed solver description for their
            interpretation.
            
            Args:
                num (int): Computed mode number.
                level (float): Vertical lever at which the coefficients are computed.
            
            :rtype: numpy.ndarray
        """

    def get_raw_H(self, num, level):
        """
        get_raw_H(self, num, level)
        
            Get Bessel expansion coefficients for the magnetic field.
            
            This is a low-level function returning :math:`H_s` and :math:`H_p` Bessel
            expansion coefficients. Please refer to the detailed solver description for their
            interpretation.
            
            Args:
                num (int): Computed mode number.
                level (float): Vertical lever at which the coefficients are computed.
            
            :rtype: numpy.ndarray
        """

    group_layers = None
    """
    Layer grouping switch.
    
    If this property is ``True``, similar layers are grouped for efficiency.
    """

    id = None
    """
    Id of the solver object. (read only)
    
    Example:
        >>> mysolver.id
        mysolver:category.type
    """

    inGain = None
    """
    Receiver of the material gain required for computations [1/cm].
    
    
    You will find usage details in the documentation of the receiver class
    :class:`~plask.flow.GainReceiverCyl`.
    
    Example:
       Connect the reveiver to a provider from some other solver:
    
       >>> solver.inGain = other_solver.outGain
    
    See also:
    
       Receciver class: :class:`plask.flow.GainReceiverCyl`
    
       Provider class: :class:`plask.flow.GainProviderCyl`
    
       Data filter: :class:`plask.filter.GainFilterCyl`
    """

    inTemperature = None
    """
    Receiver of the temperature required for computations [K].
    
    
    You will find usage details in the documentation of the receiver class
    :class:`~plask.flow.TemperatureReceiverCyl`.
    
    Example:
       Connect the reveiver to a provider from some other solver:
    
       >>> solver.inTemperature = other_solver.outTemperature
    
    See also:
    
       Receciver class: :class:`plask.flow.TemperatureReceiverCyl`
    
       Provider class: :class:`plask.flow.TemperatureProviderCyl`
    
       Data filter: :class:`plask.filter.TemperatureFilterCyl`
    """

    def initialize(self):
        """
        initialize(self)
        
            Initialize solver.
            
            This method manually initialized the solver and sets :attr:`initialized` to
            *True*. Normally calling it is not necessary, as each solver automatically
            initializes itself when needed.
            
            Returns:
                bool: solver :attr:`initialized` state prior to this method call.
        """

    initialized = None
    """
    True if the solver has been initialized. (read only)
    
    Solvers usually get initialized at the beginning of the computations.
    You can clean the initialization state and free the memory by calling
    the :meth:`invalidate` method.
    """

    def integrateEE(*args, **kwargs):
        """
        integrateEE(self, z1, z2)
        integrateEE(self, num, z1, z2)
        
            Get average integral of the squared electric field:
            
            \\[\\frac 1 2 \\int_{z_1}^{z_2} \|E\|^2.\\]
            
            In the lateral direction integration is performed over the whole domain.
            
            Args:
                num (int): Computed mode number.
                z1 (float): Lower vertical bound of the integral.
                z2 (float): Upper vertical bound of the integral.
            
            Returns:
                float: Computed integral [V\ :sup:`2` / m\ :sup:`2`].
            Warning:
                This method may return incorrect results for layers with gain,
                due to the strong non-Hemiticity!
        """

    def integrateHH(*args, **kwargs):
        """
        integrateHH(self, z1, z2)
        integrateHH(self, num, z1, z2)
        
            Get average integral of the squared magnetic field:
            
            \\[\\frac 1 2 \\int_{z_1}^{z_2} \|H\|^2.\\]
            
            In the lateral direction integration is performed over the whole domain.
            
            Args:
                num (int): Computed mode number.
                z1 (float): Lower vertical bound of the integral.
                z2 (float): Upper vertical bound of the integral.
            Returns:
                float: Computed integral [A\ :sup:`2` / m\ :sup:`2`].
            Warning:
                This method may return incorrect results for layers with gain,
                due to the strong non-Hemiticity!
        """

    interface = None
    """
    Matching interface position.
    """

    def invalidate(self):
        """
        invalidate(self)
        
            Set the solver back to uninitialized state.
            
            This method frees the memory allocated by the solver and sets
            :attr:`initialized` to *False*.
        """

    k0 = None
    """
    Normalized frequency of the light [1/µm].
    """

    klist = None
    """
    A list of wavevectors ranges. If no weights are given, the actual wavevectors
    used in the computations are the avrages of each two adjacent values specified
    here and the integration weights are the sizes of each interval.
    """

    kmax = None
    """
    Maximum wavevector used in infinite domain relative to the wavelength.
    """

    kmethod = None
    """
    Method of selecting wavevectors for numerical Hankel transform in infinite
    domain.
    """

    kscale = None
    """
    Scale factor for wavevectors used in infinite domain.
    """

    kweights = None
    """
    An optional list of relative wavevector weights. The numbers should be relative
    to the inverse of the structure width.
    """

    lam = None
    """
    Wavelength of the light [nm].
    """

    lam0 = None
    """
    Reference wavelength.
    
    This is a wavelength at which refractive index is retrieved from the structure.
    If this parameter is None, material parameters are computed each time,
    the wavelenght changes even slightly (this is most accurate, but can be very
    inefficient.
    """

    layer_centers = None
    """
    Vertical posiotions of centers of each layer.
    
    At these positions materials and temperatures are probed.
    """

    layer_edges = None
    """
    Vertical posiotions of egges of each layer.
    """

    def layer_eigenmodes(self, level):
        """
        layer_eigenmodes(self, level)
        
            Get eigenmodes for a layer at specified level.
            
            This is a low-level function to access diagonalized eigenmodes for a specific
            layer. Please refer to the detailed solver description for the interpretation
            of the returned values.
            
            Args:
                level (float): Vertical level at which the coefficients are computed.
            
            :rtype: :class:`~optical.slab.BesselCyl.Eigenmodes`
        """

    def load_xpl(self, xpl, manager):
        """
        load_xpl(self, xpl, manager)
        
            Load configuration from XPL reader.
            
            This method should be overriden in custom Python solvers.
            
            Example:
              .. code-block:: python
            
                 def load_xpl(self, xpl, manager):
                     for tag in xpl:
                         if tag == 'config':
                             self.a = tag['a']
                             self.b = tag.get('b', 0)
                             if 'c' in tag:
                                 self.c = tag['c']
                         if tag == 'combined':
                             for subtag in tag:
                                 if subtag == 'withtext':
                                     self.data = subtag.attrs
                                     # Text must be read last
                                     self.text = subtag.text
                         elif tag == 'geometry':
                             self.geometry = tag.getitem(manager.geo, 'ref')
        """

    m = None
    """
    Angular dependence parameter.
    """

    mesh = None
    """
    Mesh provided to the solver
    """

    modes = None
    """
    Computed modes.
    """

    outLightE = None
    """
    Provider of the computed electric field [V/m].
    
    
    outLightE(n=0, mesh, interpolation='default')
    
    :param int n: Number of the mode found with :meth:`find_mode`.
    :param mesh mesh: Target mesh to get the field at.
    :param str interpolation: Requested interpolation method.
    
    :return: Data with the electric field on the specified mesh **[V/m]**.
    
    You may obtain the number of different values this provider can return by
    testing its length.
    
    Example:
       Connect the provider to a receiver in some other solver:
    
       >>> other_solver.inModeLightE = solver.outLightE
    
       Obtain the provided field:
    
       >>> solver.outLightE(0, mesh)
       <plask.Data at 0x1234567>
    
       Test the number of provided values:
    
       >>> len(solver.outLightE)
       3
    
    See also:
    
       Provider class: :class:`plask.flow.ModeLightEProviderCyl`
    
       Receciver class: :class:`plask.flow.ModeLightEReceiverCyl`
    """

    outLightH = None
    """
    Provider of the computed magnetic field [A/m].
    
    
    outLightH(n=0, mesh, interpolation='default')
    
    :param int n: Number of the mode found with :meth:`find_mode`.
    :param mesh mesh: Target mesh to get the field at.
    :param str interpolation: Requested interpolation method.
    
    :return: Data with the magnetic field on the specified mesh **[A/m]**.
    
    You may obtain the number of different values this provider can return by
    testing its length.
    
    Example:
       Connect the provider to a receiver in some other solver:
    
       >>> other_solver.inModeLightH = solver.outLightH
    
       Obtain the provided field:
    
       >>> solver.outLightH(0, mesh)
       <plask.Data at 0x1234567>
    
       Test the number of provided values:
    
       >>> len(solver.outLightH)
       3
    
    See also:
    
       Provider class: :class:`plask.flow.ModeLightHProviderCyl`
    
       Receciver class: :class:`plask.flow.ModeLightHReceiverCyl`
    """

    outLightMagnitude = None
    """
    Provider of the computed optical field magnitude [W/m²].
    
    
    outLightMagnitude(n=0, mesh, interpolation='default')
    
    :param int n: Number of the mode found with :meth:`find_mode`.
    :param mesh mesh: Target mesh to get the field at.
    :param str interpolation: Requested interpolation method.
    
    :return: Data with the optical field magnitude on the specified mesh **[W/m²]**.
    
    You may obtain the number of different values this provider can return by
    testing its length.
    
    Example:
       Connect the provider to a receiver in some other solver:
    
       >>> other_solver.inModeLightMagnitude = solver.outLightMagnitude
    
       Obtain the provided field:
    
       >>> solver.outLightMagnitude(0, mesh)
       <plask.Data at 0x1234567>
    
       Test the number of provided values:
    
       >>> len(solver.outLightMagnitude)
       3
    
    See also:
    
       Provider class: :class:`plask.flow.ModeLightMagnitudeProviderCyl`
    
       Receciver class: :class:`plask.flow.ModeLightMagnitudeReceiverCyl`
    """

    outLoss = None
    """
    Provider of the computed modal extinction [1/cm].
    
    
    outLoss(n=0)
    
    :param int n: Value number.
    
    :return: Value of the modal extinction **[1/cm]**.
    
    You may obtain the number of different values this provider can return by
    testing its length.
    
    Example:
       Connect the provider to a receiver in some other solver:
    
       >>> other_solver.inModeLoss = solver.outLoss
    
       Obtain the provided value:
    
       >>> solver.outLoss(n=0)
       1000
    
       Test the number of provided values:
    
       >>> len(solver.outLoss)
       3
    
    See also:
    
       Provider class: :class:`plask.flow.ModeLossProvider`
    
       Receciver class: :class:`plask.flow.ModeLossReceiver`
    """

    outRefractiveIndex = None
    """
    Provider of the computed refractive index [-].
    
    
    outRefractiveIndex(mesh, interpolation='default')
    
    :param mesh mesh: Target mesh to get the field at.
    :param str interpolation: Requested interpolation method.
    
    :return: Data with the refractive index on the specified mesh **[-]**.
    
    Example:
       Connect the provider to a receiver in some other solver:
    
       >>> other_solver.inRefractiveIndex = solver.outRefractiveIndex
    
       Obtain the provided field:
    
       >>> solver.outRefractiveIndex(mesh)
       <plask.Data at 0x1234567>
    
    See also:
    
       Provider class: :class:`plask.flow.RefractiveIndexProviderCyl`
    
       Receciver class: :class:`plask.flow.RefractiveIndexReceiverCyl`
    """

    outWavelength = None
    """
    Provider of the computed wavelength [nm].
    
    
    outWavelength(n=0)
    
    :param int n: Value number.
    
    :return: Value of the wavelength **[nm]**.
    
    You may obtain the number of different values this provider can return by
    testing its length.
    
    Example:
       Connect the provider to a receiver in some other solver:
    
       >>> other_solver.inModeWavelength = solver.outWavelength
    
       Obtain the provided value:
    
       >>> solver.outWavelength(n=0)
       1000
    
       Test the number of provided values:
    
       >>> len(solver.outWavelength)
       3
    
    See also:
    
       Provider class: :class:`plask.flow.ModeWavelengthProvider`
    
       Receciver class: :class:`plask.flow.ModeWavelengthReceiver`
    """

    @property
    def pml():
        """
        Side Perfectly Matched Layers boundary conditions.
        
        .. rubric:: Attributes:
        
        .. autosummary::
        
           ~optical.slab.PML.factor
           ~optical.slab.PML.shape
           ~optical.slab.PML.dist
           ~optical.slab.PML.size
        
        :rtype: PML
        """

    @property
    def root():
        """
        Configuration of the root searching algorithm.
        
        .. rubric:: Attributes:
        
        .. autosummary::
        
           ~optical.slab.RootParams.alpha
           ~optical.slab.RootParams.lambd
           ~optical.slab.RootParams.initial_range
           ~optical.slab.RootParams.maxiter
           ~optical.slab.RootParams.maxstep
           ~optical.slab.RootParams.method
           ~optical.slab.RootParams.tolf_max
           ~optical.slab.RootParams.tolf_min
           ~optical.slab.RootParams.tolx
        
        :rtype: RootParams
        """

    rule = None
    """
    Expansion rule for coefficients matrix. Can be 'direct', 'semi-inverse'
    or 'inverse'. Inverse rule is proven to provide the best convergence and
    should be used in almost every case.
    """

    def scattering(*args, **kwargs):
        """
        scattering(self, side, idx)
        scattering(self, side, coeffs)
        
            Access to the reflected field.
            
            Args:
                side (`top` or `bottom`): Side of the structure where the incident light is
                    present.
                polarization: Specification of the incident light polarization.
                    It should be a string of the form 'E\ *#*\ ', where *#* is the axis name
                    of the non-vanishing electric field component.
                idx: Eigenmode number.
                coeffs: expansion coefficients of the incident vector.
            
            :rtype: Fourier2D.Scattering
        """

    def set_interface(*args, **kwargs):
        """
        set_interface(self, object, path=None)
        set_interface(self, pos)
        
            Set interface at the bottom of the specified object.
            
            Args:
                object (geometry object): object to set the interface at.
                path (path): Optional path specifying an instance of the object.
        
            Set interface as close as possible to the specified position.
            
            Args:
                pos (float): Position, near which the interface will be located.
        """

    def set_mode(self, arg2, arg3):
        """
        set_mode(self, arg2, arg3)
        
            Set the mode for specified parameters.
            
            This method should be used if you have found a mode manually and want to insert
            it into the solver in order to determine the fields. Calling this will raise an
            exception if the determinant for the specified parameters is too large.
            
            Arguments can be given through keywords only.
            
            Args:
                lam (complex): Wavelength.
                m (int): HE/EH Mode angular number.
        """

    size = None
    """
    Orthogonal expansion size.
    """

    smooth = None
    """
    Smoothing parameter for material boundaries (increases convergence).
    """

    stack = None
    """
    Stack of distinct layers.
    """

    temp_diff = None
    """
    Maximum temperature difference between the layers in one group.
    
    If a temperature in a single layer varies vertically more than this value,
    the layer is split into two and put into separate groups. If this is empty,
    temperature gradient is ignored in layers grouping.
    """

    temp_dist = None
    """
    Temperature probing step.
    
    If :attr:`temp_diff` is not ``None``, the temperature is laterally probed
    in points approximately separated by this distance.
    """

    temp_layer = None
    """
    Temperature probing step.
    
    If :attr:`temp_diff` is not ``None``, this is the minimum thickness of sublayers
    resulting from temperature-gradient division.
    """

    transfer = None
    """
    Preferred transfer method.
    
    Can take on of the following values:
    
    ============ ====================================
    *auto*       Automatically choose the best method
    *reflection* Reflection Transfer Method
    *admittance* Admittance Transfer Method
    *impedance*  Impedance Transfer Method
    ============ ====================================
    
    Reflection transfer can have optional suffix ``-admittance`` (default)
    or ``-impedance``, in which case the admittance/impedance matching is done
    at interface (for eigenmode search). You should prefer admittance if electric
    field is expected to have significant horizontal components (particularly
    at the interface) i.e. for TE-like modes and impedance for TM-like modes.
    """

    update_gain = None
    """
    Always update gain.
    
    If this attribute is set to True, material parameters are always recomputed for
    layers with gains. This allows to set py:attr:`lam0` for better efficiency and
    still update gain for slight changes of wavelength.
    """

    vpml = None
    """
    Vertical Perfectly Matched Layers boundary conditions.
    
    .. rubric:: Attributes
    
    .. autosummary::
    
       ~optical.slab.PML.factor
       ~optical.slab.PML.dist
       ~optical.slab.PML.size
    
    Attribute ``shape`` is ignored for vertical PML (it is always 0).
    """

    wavelength = None
    """
    Alias for :attr:`lam`
    """



class Fourier2D(plask.Solver):
    """
    Fourier2D(name="")
    
    Optical Solver using Fourier expansion in 2D.
    
    It calculates optical modes and optical field distribution using Fourier slab method
    and reflection transfer in two-dimensional Cartesian space.
    """
    class Eigenmodes(object):
        """
        Layer eignemodes
        
        This is an advanced class allowing to extract eignemodes in each layer.
        """
        class Eigenmode(object):
            """
            Single eignemode. You can access object of this class by indexing
            :class:`~optical.slab.Fourier2D.Eigenmodes` object.
            """
            flux = None
            """
            Vertical flux for the eigenmode.
            
            This is equal to the vertical component of the Pointing vector integrated over
            the numerical domain.
            """

            kvert = None
            """
            Vertical propagation constant for the eigenmode.
            """

            raw_E = None
            """
            Electric field coefficients for the eigenmode.
            """

            raw_H = None
            """
            Magnetic field coefficients for the eigenmode.
            """


        outLightE = None
        """
        Provider of the computed electric field [V/m].
        
        
        outLightE(n=0, mesh, interpolation='default')
        
        :param int n: Number of the mode found with :meth:`find_mode`.:param mesh mesh: Target mesh to get the field at.
        :param str interpolation: Requested interpolation method.
        
        :return: Data with the electric field on the specified mesh **[V/m]**.
        
        You may obtain the number of different values this provider can return by
        testing its length.
        
        Example:
           Connect the provider to a receiver in some other solver:
        
           >>> other_solver.inLightE = solver.outLightE
        
           Obtain the provided field:
        
           >>> solver.outLightE(0, mesh)
           <plask.Data at 0x1234567>
        
           Test the number of provided values:
        
           >>> len(solver.outLightE)
           3
        
        See also:
        
           Provider class: :class:`plask.flow.LightEProvider2D`
        
           Receciver class: :class:`plask.flow.LightEReceiver2D`
        """

        outLightH = None
        """
        Provider of the computed electric field [A/m].
        
        
        outLightH(n=0, mesh, interpolation='default')
        
        :param int n: Number of the mode found with :meth:`find_mode`.:param mesh mesh: Target mesh to get the field at.
        :param str interpolation: Requested interpolation method.
        
        :return: Data with the electric field on the specified mesh **[A/m]**.
        
        You may obtain the number of different values this provider can return by
        testing its length.
        
        Example:
           Connect the provider to a receiver in some other solver:
        
           >>> other_solver.inLightH = solver.outLightH
        
           Obtain the provided field:
        
           >>> solver.outLightH(0, mesh)
           <plask.Data at 0x1234567>
        
           Test the number of provided values:
        
           >>> len(solver.outLightH)
           3
        
        See also:
        
           Provider class: :class:`plask.flow.LightHProvider2D`
        
           Receciver class: :class:`plask.flow.LightHReceiver2D`
        """

        outLightMagnitude = None
        """
        Provider of the computed light intensity [W/m²].
        
        
        outLightMagnitude(n=0, mesh, interpolation='default')
        
        :param int n: Number of the mode found with :meth:`find_mode`.:param mesh mesh: Target mesh to get the field at.
        :param str interpolation: Requested interpolation method.
        
        :return: Data with the light intensity on the specified mesh **[W/m²]**.
        
        You may obtain the number of different values this provider can return by
        testing its length.
        
        Example:
           Connect the provider to a receiver in some other solver:
        
           >>> other_solver.inLightMagnitude = solver.outLightMagnitude
        
           Obtain the provided field:
        
           >>> solver.outLightMagnitude(0, mesh)
           <plask.Data at 0x1234567>
        
           Test the number of provided values:
        
           >>> len(solver.outLightMagnitude)
           3
        
        See also:
        
           Provider class: :class:`plask.flow.LightMagnitudeProvider2D`
        
           Receciver class: :class:`plask.flow.LightMagnitudeReceiver2D`
        """


    class Mode(object):
        """
        Detailed information about the mode.
        """
        beta = None
        """
        Mode longitudinal wavevector [1/µm].
        """

        k0 = None
        """
        Mode normalized frequency [1/µm].
        """

        ktran = None
        """
        Mode transverse wavevector [1/µm].
        """

        lam = None
        """
        Mode wavelength [nm].
        """

        neff = None
        """
        Mode longitudinal effective index [-].
        """

        polarization = None
        """
        Mode polarization.
        """

        power = None
        """
        Total power emitted into the mode [mW].
        """

        symmetry = None
        """
        Mode horizontal symmetry.
        """

        wavelength = None
        """
        Mode wavelength [nm].
        """


    class Scattering(object):
        """
        Reflected mode proxy.
        
        This class contains providers for the scattered field.
        """
        class Incident(object):
            """
            Incident field details
            """
            coeffs = None
            """
            Raw incident ceofficients for modes.
            """

            eigenmodes = None
            """
            Incident eigenmodes.
            
            :rtype: :class:`~optical.slab.Fourier2D.Eigenmodes`
            """

            fluxes = None
            """
            Perpendicular fluxes for incident modes.
            """


        R = None
        """
        Total reflection coefficient [-].
        """

        class Reflected(object):
            """
            Reflected field details
            """
            coeffs = None
            """
            Raw reflection ceofficients for modes.
            """

            eigenmodes = None
            """
            Reflected eigenmodes.
            
            :rtype: :class:`~optical.slab.Fourier2D.Eigenmodes`
            """

            fluxes = None
            """
            Perpendicular fluxes for reflected modes.
            """


        T = None
        """
        Total transmission coefficient [-].
        """

        class Transmitted(object):
            """
            Transmitted field details
            """
            coeffs = None
            """
            Raw transmission ceofficients for modes.
            """

            eigenmodes = None
            """
            Transmitted eigenmodes.
            
            :rtype: :class:`~optical.slab.Fourier2D.Eigenmodes`
            """

            fluxes = None
            """
            Perpendicular fluxes for transmitted modes.
            """


        @property
        def incident():
            """
            Incident field details.
            
            :rtype: Incident
            """

        def integrateEE(self, z1, z2):
            """
            integrateEE(self, z1, z2)
            
                Get average integral of the squared electric field:
                
                \\[\\frac 1 2 \\int_{z_1}^{z_2} \|E\|^2.\\]
                
                In the lateral direction integration is performed over the whole domain.
                
                Args:
                    z1 (float): Lower vertical bound of the integral.
                    z2 (float): Upper vertical bound of the integral.
                
                Returns:
                    float: Computed integral [V\ :sup:`2` / m\ :sup:`2`].
                
                Warning:
                    This method may return incorrect results for layers with gain,
                    due to the strong non-Hemiticity!
            """

        def integrateHH(self, z1, z2):
            """
            integrateHH(self, z1, z2)
            
                Get average integral of the squared magnetic field:
                
                \\[\\frac 1 2 \\int_{z_1}^{z_2} \|H\|^2.\\]
                
                In the lateral direction integration is performed over the whole domain.
                
                Args:
                    z1 (float): Lower vertical bound of the integral.
                    z2 (float): Upper vertical bound of the integral.
                Returns:
                    float: Computed integral [A\ :sup:`2` / m\ :sup:`2`].
                Warning:
                    This method may return incorrect results for layers with gain,
                    due to the strong non-Hemiticity!
            """

        outLightE = None
        """
        Provider of the computed electric field [V/m].
        
        
        outLightE(mesh, interpolation='default')
        
        :param mesh mesh: Target mesh to get the field at.
        :param str interpolation: Requested interpolation method.
        
        :return: Data with the electric field on the specified mesh **[V/m]**.
        
        Example:
           Connect the provider to a receiver in some other solver:
        
           >>> other_solver.inLightE = solver.outLightE
        
           Obtain the provided field:
        
           >>> solver.outLightE(mesh)
           <plask.Data at 0x1234567>
        
        See also:
        
           Provider class: :class:`plask.flow.LightEProvider2D`
        
           Receciver class: :class:`plask.flow.LightEReceiver2D`
        """

        outLightH = None
        """
        Provider of the computed magnetic field [A/m].
        
        
        outLightH(mesh, interpolation='default')
        
        :param mesh mesh: Target mesh to get the field at.
        :param str interpolation: Requested interpolation method.
        
        :return: Data with the magnetic field on the specified mesh **[A/m]**.
        
        Example:
           Connect the provider to a receiver in some other solver:
        
           >>> other_solver.inLightH = solver.outLightH
        
           Obtain the provided field:
        
           >>> solver.outLightH(mesh)
           <plask.Data at 0x1234567>
        
        See also:
        
           Provider class: :class:`plask.flow.LightHProvider2D`
        
           Receciver class: :class:`plask.flow.LightHReceiver2D`
        """

        outLightMagnitude = None
        """
        Provider of the computed light intensity [W/m²].
        
        
        outLightMagnitude(mesh, interpolation='default')
        
        :param mesh mesh: Target mesh to get the field at.
        :param str interpolation: Requested interpolation method.
        
        :return: Data with the light intensity on the specified mesh **[W/m²]**.
        
        Example:
           Connect the provider to a receiver in some other solver:
        
           >>> other_solver.inLightMagnitude = solver.outLightMagnitude
        
           Obtain the provided field:
        
           >>> solver.outLightMagnitude(mesh)
           <plask.Data at 0x1234567>
        
        See also:
        
           Provider class: :class:`plask.flow.LightMagnitudeProvider2D`
        
           Receciver class: :class:`plask.flow.LightMagnitudeReceiver2D`
        """

        @property
        def reflected():
            """
            Reflected field details.
            
            :rtype: Reflected
            """

        reflectivity = None
        """
        Total reflection coefficient [%].
        
        This differs from :attr:`Scattering.R` by unit.
        """

        @property
        def transmitted():
            """
            Transmitted field details.
            
            :rtype: Transmitted
            """

        transmittivity = None
        """
        Total transmission coefficient [%].
        
        This differs from :attr:`Scattering.T` by unit.
        """


    def compute_reflectivity(*args, **kwargs):
        """
        compute_reflectivity(self, lam, side, polarization)
        compute_reflectivity(self, lam, side, index)
        compute_reflectivity(self, lam, side, coffs)
        
            Compute reflection coefficient on planar incidence [%].
            
            Args:
                lam (float or array of floats): Incident light wavelength.
                side (`top` or `bottom`): Side of the structure where the incident light is
                    present.
                polarization: Specification of the incident light polarization.
                    It should be a string of the form 'E\ *#*\ ', where *#* is the axis
                    name of the non-vanishing electric field component.
                idx: Eigenmode number.
                coeffs: expansion coefficients of the incident vector.
        """

    def compute_transmittivity(*args, **kwargs):
        """
        compute_transmittivity(self, lam, side, polarization)
        compute_transmittivity(self, lam, side, index)
        compute_transmittivity(self, lam, side, coffs)
        
            Compute transmission coefficient on planar incidence [%].
            
            Args:
                lam (float or array of floats): Incident light wavelength.
                side (`top` or `bottom`): Side of the structure where the incident light is
                    present.
                polarization: Specification of the incident light polarization.
                    It should be a string of the form 'E\ *#*\ ', where *#* is the axis name
                    of the non-vanishing electric field component.
                idx: Eigenmode number.
                coeffs: expansion coefficients of the incident vector.
        """

    dct = None
    """
    Type of discrete cosine transform for symmetric expansion.
    """

    emission = None
    """
    Direction of the useful light emission.
    
    Necessary for the over-threshold model to correctly compute the output power.
    Currently the fields are normalized only if this parameter is set to
    ``top`` or ``bottom``. Otherwise, it is ``undefined`` (default) and the fields
    are not normalized.
    """

    def find_mode(*args, **kwargs):
        """
        object find_mode(tuple args, dict kwds) :
            Compute the mode near the specified effective index.
            
            Only one of the following arguments can be given through a keyword.
            It is the starting point for search of the specified parameter.
            
            Args:
                lam (complex): Wavelength.
                k0 (complex): Normalized frequency.
                neff (complex): Longitudinal effective index.
                ktran (complex): Transverse wavevector.
        """

    ft = None
    """
    Type of the Fourier transform. Analytic transform is faster and more precise,
    however it ignores temperature and gain distributions.
    """

    def gaussian(self, side, polarization, sigma, center=0):
        """
        gaussian(self, side, polarization, sigma, center=0)
        
            Create coefficients vector with Gaussian profile.
            
            This method is intended to use for :py:meth:`scattering` method.
            
            Args:
                side (`top` or `bottom`): Side of the structure where the incident light is
                    present.
                polarization: Specification of the incident light polarization.
                    It should be a string of the form 'E\ *#*\ ', where *#* is the axis name
                    of the non-vanishing electric field component.
                sigma (float): Gaussian standard deviation [µm].
                center (float): Position of the beam center [µm].
            
            Example:
               >>> scattered = fourier.scattering('top', 
               ...     fourier.gaussian('top', 'Ex', 0.2))
        """

    geometry = None
    """
    Geometry provided to the solver
    """

    def get_determinant(*args, **kwargs):
        """
        object get_determinant(tuple args, dict kwds) :
            Compute discontinuity matrix determinant.
            
            Arguments can be given through keywords only.
            
            Args:
                lam (complex): Wavelength.
                k0 (complex): Normalized frequency.
                neff (complex): Longitudinal effective index.
                ktran (complex): Transverse wavevector.
        """

    def get_raw_E(self, num, level):
        """
        get_raw_E(self, num, level)
        
            Get Fourier expansion coefficients for the electric field.
            
            This is a low-level function returning :math:`E_l` and/or :math:`E_t` Fourier
            expansion coefficients. Please refer to the detailed solver description for their
            interpretation.
            
            Args:
                num (int): Computed mode number.
                level (float): Vertical level at which the coefficients are computed.
            
            :rtype: numpy.ndarray
        """

    def get_raw_H(self, num, level):
        """
        get_raw_H(self, num, level)
        
            Get Fourier expansion coefficients for the magnetic field.
            
            This is a low-level function returning :math:`H_l` and/or :math:`H_t` Fourier
            expansion coefficients. Please refer to the detailed solver description for their
            interpretation.
            
            Args:
                num (int): Computed mode number.
                level (float): Vertical level at which the coefficients are computed.
            
            :rtype: numpy.ndarray
        """

    group_layers = None
    """
    Layer grouping switch.
    
    If this property is ``True``, similar layers are grouped for efficiency.
    """

    id = None
    """
    Id of the solver object. (read only)
    
    Example:
        >>> mysolver.id
        mysolver:category.type
    """

    inGain = None
    """
    Receiver of the material gain required for computations [1/cm].
    
    
    You will find usage details in the documentation of the receiver class
    :class:`~plask.flow.GainReceiver2D`.
    
    Example:
       Connect the reveiver to a provider from some other solver:
    
       >>> solver.inGain = other_solver.outGain
    
    See also:
    
       Receciver class: :class:`plask.flow.GainReceiver2D`
    
       Provider class: :class:`plask.flow.GainProvider2D`
    
       Data filter: :class:`plask.filter.GainFilter2D`
    """

    inTemperature = None
    """
    Receiver of the temperature required for computations [K].
    
    
    You will find usage details in the documentation of the receiver class
    :class:`~plask.flow.TemperatureReceiver2D`.
    
    Example:
       Connect the reveiver to a provider from some other solver:
    
       >>> solver.inTemperature = other_solver.outTemperature
    
    See also:
    
       Receciver class: :class:`plask.flow.TemperatureReceiver2D`
    
       Provider class: :class:`plask.flow.TemperatureProvider2D`
    
       Data filter: :class:`plask.filter.TemperatureFilter2D`
    """

    def initialize(self):
        """
        initialize(self)
        
            Initialize solver.
            
            This method manually initialized the solver and sets :attr:`initialized` to
            *True*. Normally calling it is not necessary, as each solver automatically
            initializes itself when needed.
            
            Returns:
                bool: solver :attr:`initialized` state prior to this method call.
        """

    initialized = None
    """
    True if the solver has been initialized. (read only)
    
    Solvers usually get initialized at the beginning of the computations.
    You can clean the initialization state and free the memory by calling
    the :meth:`invalidate` method.
    """

    def integrateEE(*args, **kwargs):
        """
        integrateEE(self, z1, z2)
        integrateEE(self, num, z1, z2)
        
            Get average integral of the squared electric field:
            
            \\[\\frac 1 2 \\int_{z_1}^{z_2} \|E\|^2.\\]
            
            In the lateral direction integration is performed over the whole domain.
            
            Args:
                num (int): Computed mode number.
                z1 (float): Lower vertical bound of the integral.
                z2 (float): Upper vertical bound of the integral.
            
            Returns:
                float: Computed integral [V\ :sup:`2` / m\ :sup:`2`].
            Warning:
                This method may return incorrect results for layers with gain,
                due to the strong non-Hemiticity!
        """

    def integrateHH(*args, **kwargs):
        """
        integrateHH(self, z1, z2)
        integrateHH(self, num, z1, z2)
        
            Get average integral of the squared magnetic field:
            
            \\[\\frac 1 2 \\int_{z_1}^{z_2} \|H\|^2.\\]
            
            In the lateral direction integration is performed over the whole domain.
            
            Args:
                num (int): Computed mode number.
                z1 (float): Lower vertical bound of the integral.
                z2 (float): Upper vertical bound of the integral.
            Returns:
                float: Computed integral [A\ :sup:`2` / m\ :sup:`2`].
            Warning:
                This method may return incorrect results for layers with gain,
                due to the strong non-Hemiticity!
        """

    interface = None
    """
    Matching interface position.
    """

    def invalidate(self):
        """
        invalidate(self)
        
            Set the solver back to uninitialized state.
            
            This method frees the memory allocated by the solver and sets
            :attr:`initialized` to *False*.
        """

    k0 = None
    """
    Normalized frequency of the light [1/µm].
    
    Use this property only if you are looking for anything else than
    the wavelength,e.g. the effective index of lateral wavevector.
    """

    klong = None
    """
    Longitudinal propagation constant of the light [1/µm].
    
    Use this property only if you are looking for anything else than
    the longitudinal component of the propagation vector and the effective index.
    """

    ktran = None
    """
    Transverse propagation constant of the light [1/µm].
    
    Use this property only  if you are looking for anything else than
    the transverse component of the propagation vector.
    """

    lam = None
    """
    Wavelength of the light [nm].
    
    Use this property only if you are looking for anything else than
    the wavelength, e.g. the effective index of lateral wavevector.
    """

    lam0 = None
    """
    Reference wavelength.
    
    This is a wavelength at which refractive index is retrieved from the structure.
    If this parameter is None, material parameters are computed each time,
    the wavelenght changes even slightly (this is most accurate, but can be very
    inefficient.
    """

    layer_centers = None
    """
    Vertical posiotions of centers of each layer.
    
    At these positions materials and temperatures are probed.
    """

    layer_edges = None
    """
    Vertical posiotions of egges of each layer.
    """

    def layer_eigenmodes(self, level):
        """
        layer_eigenmodes(self, level)
        
            Get eignemodes for a layer at specified level.
            
            This is a low-level function to access diagonalized eigenmodes for a specific
            layer. Please refer to the detailed solver description for the interpretation
            of the returned values.
            
            Args:
                level (float): Vertical level at which the coefficients are computed.
            
            :rtype: :class:`~optical.slab.Fourier2D.Eigenmodes`
        """

    def load_xpl(self, xpl, manager):
        """
        load_xpl(self, xpl, manager)
        
            Load configuration from XPL reader.
            
            This method should be overriden in custom Python solvers.
            
            Example:
              .. code-block:: python
            
                 def load_xpl(self, xpl, manager):
                     for tag in xpl:
                         if tag == 'config':
                             self.a = tag['a']
                             self.b = tag.get('b', 0)
                             if 'c' in tag:
                                 self.c = tag['c']
                         if tag == 'combined':
                             for subtag in tag:
                                 if subtag == 'withtext':
                                     self.data = subtag.attrs
                                     # Text must be read last
                                     self.text = subtag.text
                         elif tag == 'geometry':
                             self.geometry = tag.getitem(manager.geo, 'ref')
        """

    mesh = None
    """
    Mesh provided to the solver
    """

    mirrors = None
    """
    Mirror reflectivities. If None then they are automatically estimated from the
    Fresnel equations.
    """

    modes = None
    """
    Computed modes.
    """

    outLightE = None
    """
    Provider of the computed electric field [V/m].
    
    
    outLightE(n=0, mesh, interpolation='default')
    
    :param int n: Number of the mode found with :meth:`find_mode`.
    :param mesh mesh: Target mesh to get the field at.
    :param str interpolation: Requested interpolation method.
    
    :return: Data with the electric field on the specified mesh **[V/m]**.
    
    You may obtain the number of different values this provider can return by
    testing its length.
    
    Example:
       Connect the provider to a receiver in some other solver:
    
       >>> other_solver.inModeLightE = solver.outLightE
    
       Obtain the provided field:
    
       >>> solver.outLightE(0, mesh)
       <plask.Data at 0x1234567>
    
       Test the number of provided values:
    
       >>> len(solver.outLightE)
       3
    
    See also:
    
       Provider class: :class:`plask.flow.ModeLightEProvider2D`
    
       Receciver class: :class:`plask.flow.ModeLightEReceiver2D`
    """

    outLightH = None
    """
    Provider of the computed magnetic field [A/m].
    
    
    outLightH(n=0, mesh, interpolation='default')
    
    :param int n: Number of the mode found with :meth:`find_mode`.
    :param mesh mesh: Target mesh to get the field at.
    :param str interpolation: Requested interpolation method.
    
    :return: Data with the magnetic field on the specified mesh **[A/m]**.
    
    You may obtain the number of different values this provider can return by
    testing its length.
    
    Example:
       Connect the provider to a receiver in some other solver:
    
       >>> other_solver.inModeLightH = solver.outLightH
    
       Obtain the provided field:
    
       >>> solver.outLightH(0, mesh)
       <plask.Data at 0x1234567>
    
       Test the number of provided values:
    
       >>> len(solver.outLightH)
       3
    
    See also:
    
       Provider class: :class:`plask.flow.ModeLightHProvider2D`
    
       Receciver class: :class:`plask.flow.ModeLightHReceiver2D`
    """

    outLightMagnitude = None
    """
    Provider of the computed optical field magnitude [W/m²].
    
    
    outLightMagnitude(n=0, mesh, interpolation='default')
    
    :param int n: Number of the mode found with :meth:`find_mode`.
    :param mesh mesh: Target mesh to get the field at.
    :param str interpolation: Requested interpolation method.
    
    :return: Data with the optical field magnitude on the specified mesh **[W/m²]**.
    
    You may obtain the number of different values this provider can return by
    testing its length.
    
    Example:
       Connect the provider to a receiver in some other solver:
    
       >>> other_solver.inModeLightMagnitude = solver.outLightMagnitude
    
       Obtain the provided field:
    
       >>> solver.outLightMagnitude(0, mesh)
       <plask.Data at 0x1234567>
    
       Test the number of provided values:
    
       >>> len(solver.outLightMagnitude)
       3
    
    See also:
    
       Provider class: :class:`plask.flow.ModeLightMagnitudeProvider2D`
    
       Receciver class: :class:`plask.flow.ModeLightMagnitudeReceiver2D`
    """

    outNeff = None
    """
    Provider of the computed effective index [-].
    Effective index of the last computed mode.
    
    outNeff(n=0)
    
    :param int n: Value number.
    
    :return: Value of the effective index **[-]**.
    
    You may obtain the number of different values this provider can return by
    testing its length.
    
    Example:
       Connect the provider to a receiver in some other solver:
    
       >>> other_solver.inModeEffectiveIndex = solver.outNeff
    
       Obtain the provided value:
    
       >>> solver.outNeff(n=0)
       1000
    
       Test the number of provided values:
    
       >>> len(solver.outNeff)
       3
    
    See also:
    
       Provider class: :class:`plask.flow.ModeEffectiveIndexProvider`
    
       Receciver class: :class:`plask.flow.ModeEffectiveIndexReceiver`
    """

    outRefractiveIndex = None
    """
    Provider of the computed refractive index [-].
    
    
    outRefractiveIndex(mesh, interpolation='default')
    
    :param mesh mesh: Target mesh to get the field at.
    :param str interpolation: Requested interpolation method.
    
    :return: Data with the refractive index on the specified mesh **[-]**.
    
    Example:
       Connect the provider to a receiver in some other solver:
    
       >>> other_solver.inRefractiveIndex = solver.outRefractiveIndex
    
       Obtain the provided field:
    
       >>> solver.outRefractiveIndex(mesh)
       <plask.Data at 0x1234567>
    
    See also:
    
       Provider class: :class:`plask.flow.RefractiveIndexProvider2D`
    
       Receciver class: :class:`plask.flow.RefractiveIndexReceiver2D`
    """

    outWavelength = None
    """
    Provider of the computed wavelength [nm].
    
    
    outWavelength(n=0)
    
    :param int n: Value number.
    
    :return: Value of the wavelength **[nm]**.
    
    You may obtain the number of different values this provider can return by
    testing its length.
    
    Example:
       Connect the provider to a receiver in some other solver:
    
       >>> other_solver.inModeWavelength = solver.outWavelength
    
       Obtain the provided value:
    
       >>> solver.outWavelength(n=0)
       1000
    
       Test the number of provided values:
    
       >>> len(solver.outWavelength)
       3
    
    See also:
    
       Provider class: :class:`plask.flow.ModeWavelengthProvider`
    
       Receciver class: :class:`plask.flow.ModeWavelengthReceiver`
    """

    @property
    def pml():
        """
        Side Perfectly Matched Layers boundary conditions.
        
        .. rubric:: Attributes:
        
        .. autosummary::
        
           ~optical.slab.PML.factor
           ~optical.slab.PML.shape
           ~optical.slab.PML.dist
           ~optical.slab.PML.size
        
        :rtype: PML
        """

    polarization = None
    """
    Mode polarization.
    """

    refine = None
    """
    Number of refinement points for refractive index averaging.
    """

    @property
    def root():
        """
        Configuration of the root searching algorithm.
        
        .. rubric:: Attributes:
        
        .. autosummary::
        
           ~optical.slab.RootParams.alpha
           ~optical.slab.RootParams.lambd
           ~optical.slab.RootParams.initial_range
           ~optical.slab.RootParams.maxiter
           ~optical.slab.RootParams.maxstep
           ~optical.slab.RootParams.method
           ~optical.slab.RootParams.tolf_max
           ~optical.slab.RootParams.tolf_min
           ~optical.slab.RootParams.tolx
        
        :rtype: RootParams
        """

    def scattering(*args, **kwargs):
        """
        scattering(self, side, polarization)
        scattering(self, side, idx)
        scattering(self, side, coeffs)
        
            Access to the reflected field.
            
            Args:
                side (`top` or `bottom`): Side of the structure where the incident light is
                    present.
                polarization: Specification of the incident light polarization.
                    It should be a string of the form 'E\ *#*\ ', where *#* is the axis name
                    of the non-vanishing electric field component.
                idx: Eigenmode number.
                coeffs: expansion coefficients of the incident vector.
            
            :rtype: Fourier2D.Scattering
        """

    def scattering_gaussian(self, side, polarization, sigma, center=0):
        """
        scattering_gaussian(self, side, polarization, sigma, center=0)
        
            Helper function to Access reflected fields for access incidence.
            
            This method is equivalent to calling:
            
               >>> fourier.scattering(side,
               ...     fourier.gaussian(side, polarization, sigma, center))
            
            Args:
                side (`top` or `bottom`): Side of the structure where the incident light is
                    present.
                polarization: Specification of the incident light polarization.
                    It should be a string of the form 'E\ *#*\ ', where *#* is the axis name
                    of the non-vanishing electric field component.
                sigma (float): Gaussian standard deviation [µm].
                center (float): Position of the beam center [µm].
        """

    def set_interface(*args, **kwargs):
        """
        set_interface(self, object, path=None)
        set_interface(self, pos)
        
            Set interface at the bottom of the specified object.
            
            Args:
                object (geometry object): object to set the interface at.
                path (path): Optional path specifying an instance of the object.
        
            Set interface as close as possible to the specified position.
            
            Args:
                pos (float): Position, near which the interface will be located.
        """

    def set_mode(*args, **kwargs):
        """
        object set_mode(tuple args, dict kwds) :
            Set the mode for specified parameters.
            
            This method should be used if you have found a mode manually and want to insert
            it into the solver in order to determine the fields. Calling this will raise an
            exception if the determinant for the specified parameters is too large.
            
            Arguments can be given through keywords only.
            
            Args:
                lam (complex): Wavelength.
                k0 (complex): Normalized frequency.
                neff (complex): Longitudinal effective index.
                ktran (complex): Transverse wavevector.
        """

    size = None
    """
    Orthogonal expansion size.
    """

    smooth = None
    """
    Smoothing parameter for material boundaries (increases convergence).
    """

    stack = None
    """
    Stack of distinct layers.
    """

    symmetry = None
    """
    Mode symmetry.
    """

    temp_diff = None
    """
    Maximum temperature difference between the layers in one group.
    
    If a temperature in a single layer varies vertically more than this value,
    the layer is split into two and put into separate groups. If this is empty,
    temperature gradient is ignored in layers grouping.
    """

    temp_dist = None
    """
    Temperature probing step.
    
    If :attr:`temp_diff` is not ``None``, the temperature is laterally probed
    in points approximately separated by this distance.
    """

    temp_layer = None
    """
    Temperature probing step.
    
    If :attr:`temp_diff` is not ``None``, this is the minimum thickness of sublayers
    resulting from temperature-gradient division.
    """

    transfer = None
    """
    Preferred transfer method.
    
    Can take on of the following values:
    
    ============ ====================================
    *auto*       Automatically choose the best method
    *reflection* Reflection Transfer Method
    *admittance* Admittance Transfer Method
    *impedance*  Impedance Transfer Method
    ============ ====================================
    
    Reflection transfer can have optional suffix ``-admittance`` (default)
    or ``-impedance``, in which case the admittance/impedance matching is done
    at interface (for eigenmode search). You should prefer admittance if electric
    field is expected to have significant horizontal components (particularly
    at the interface) i.e. for TE-like modes and impedance for TM-like modes.
    """

    update_gain = None
    """
    Always update gain.
    
    If this attribute is set to True, material parameters are always recomputed for
    layers with gains. This allows to set py:attr:`lam0` for better efficiency and
    still update gain for slight changes of wavelength.
    """

    vpml = None
    """
    Vertical Perfectly Matched Layers boundary conditions.
    
    .. rubric:: Attributes
    
    .. autosummary::
    
       ~optical.slab.PML.factor
       ~optical.slab.PML.dist
       ~optical.slab.PML.size
    
    Attribute ``shape`` is ignored for vertical PML (it is always 0).
    """

    wavelength = None
    """
    Alias for :attr:`lam`
    """



class Fourier3D(plask.Solver):
    """
    Fourier3D(name="")
    
    Optical Solver using Fourier expansion in 3D.
    
    It calculates optical modes and optical field distribution using Fourier slab method
    and reflection transfer in three-dimensional Cartesian space.
    """
    class Eigenmodes(object):
        """
        Layer eignemodes
        
        This is an advanced class allowing to extract eignemodes in each layer.
        """
        class Eigenmode(object):
            """
            Single eignemode. You can access object of this class by indexing
            :class:`~optical.slab.Fourier3D.Eigenmodes` object.
            """
            flux = None
            """
            Vertical flux for the eigenmode.
            
            This is equal to the vertical component of the Pointing vector integrated over
            the numerical domain.
            """

            kvert = None
            """
            Vertical propagation constant for the eigenmode.
            """

            raw_E = None
            """
            Electric field coefficients for the eigenmode.
            """

            raw_H = None
            """
            Magnetic field coefficients for the eigenmode.
            """


        outLightE = None
        """
        Provider of the computed electric field [V/m].
        
        
        outLightE(n=0, mesh, interpolation='default')
        
        :param int n: Number of the mode found with :meth:`find_mode`.:param mesh mesh: Target mesh to get the field at.
        :param str interpolation: Requested interpolation method.
        
        :return: Data with the electric field on the specified mesh **[V/m]**.
        
        You may obtain the number of different values this provider can return by
        testing its length.
        
        Example:
           Connect the provider to a receiver in some other solver:
        
           >>> other_solver.inLightE = solver.outLightE
        
           Obtain the provided field:
        
           >>> solver.outLightE(0, mesh)
           <plask.Data at 0x1234567>
        
           Test the number of provided values:
        
           >>> len(solver.outLightE)
           3
        
        See also:
        
           Provider class: :class:`plask.flow.LightEProvider3D`
        
           Receciver class: :class:`plask.flow.LightEReceiver3D`
        """

        outLightH = None
        """
        Provider of the computed electric field [A/m].
        
        
        outLightH(n=0, mesh, interpolation='default')
        
        :param int n: Number of the mode found with :meth:`find_mode`.:param mesh mesh: Target mesh to get the field at.
        :param str interpolation: Requested interpolation method.
        
        :return: Data with the electric field on the specified mesh **[A/m]**.
        
        You may obtain the number of different values this provider can return by
        testing its length.
        
        Example:
           Connect the provider to a receiver in some other solver:
        
           >>> other_solver.inLightH = solver.outLightH
        
           Obtain the provided field:
        
           >>> solver.outLightH(0, mesh)
           <plask.Data at 0x1234567>
        
           Test the number of provided values:
        
           >>> len(solver.outLightH)
           3
        
        See also:
        
           Provider class: :class:`plask.flow.LightHProvider3D`
        
           Receciver class: :class:`plask.flow.LightHReceiver3D`
        """

        outLightMagnitude = None
        """
        Provider of the computed light intensity [W/m²].
        
        
        outLightMagnitude(n=0, mesh, interpolation='default')
        
        :param int n: Number of the mode found with :meth:`find_mode`.:param mesh mesh: Target mesh to get the field at.
        :param str interpolation: Requested interpolation method.
        
        :return: Data with the light intensity on the specified mesh **[W/m²]**.
        
        You may obtain the number of different values this provider can return by
        testing its length.
        
        Example:
           Connect the provider to a receiver in some other solver:
        
           >>> other_solver.inLightMagnitude = solver.outLightMagnitude
        
           Obtain the provided field:
        
           >>> solver.outLightMagnitude(0, mesh)
           <plask.Data at 0x1234567>
        
           Test the number of provided values:
        
           >>> len(solver.outLightMagnitude)
           3
        
        See also:
        
           Provider class: :class:`plask.flow.LightMagnitudeProvider3D`
        
           Receciver class: :class:`plask.flow.LightMagnitudeReceiver3D`
        """


    class Mode(object):
        """
        Detailed information about the mode.
        """
        k0 = None
        """
        Mode normalized frequency [1/µm].
        """

        klong = None
        """
        Mode longitudinal wavevector [1/µm].
        """

        ktran = None
        """
        Mode transverse wavevector [1/µm].
        """

        lam = None
        """
        Mode wavelength [nm].
        """

        power = None
        """
        Total power emitted into the mode [mW].
        """

        symmetry = None
        """
        Mode horizontal symmetry.
        """

        wavelength = None
        """
        Mode wavelength [nm].
        """


    class Oversampling(object):
        """
        Access wrapper for parameter along long/tran axis
        """

    class PMLs(object):
        """
        Access wrapper for parameter along long/tran axis
        """

    class Scattering(object):
        """
        Reflected mode proxy.
        
        This class contains providers for the scattered field.
        """
        class Incident(object):
            """
            Incident field details
            """
            coeffs = None
            """
            Raw incident ceofficients for modes.
            """

            eigenmodes = None
            """
            Incident eigenmodes.
            
            :rtype: :class:`~optical.slab.Fourier3D.Eigenmodes`
            """

            fluxes = None
            """
            Perpendicular fluxes for incident modes.
            """


        R = None
        """
        Total reflection coefficient [-].
        """

        class Reflected(object):
            """
            Reflected field details
            """
            coeffs = None
            """
            Raw reflection ceofficients for modes.
            """

            eigenmodes = None
            """
            Reflected eigenmodes.
            
            :rtype: :class:`~optical.slab.Fourier3D.Eigenmodes`
            """

            fluxes = None
            """
            Perpendicular fluxes for reflected modes.
            """


        T = None
        """
        Total transmission coefficient [-].
        """

        class Transmitted(object):
            """
            Transmitted field details
            """
            coeffs = None
            """
            Raw transmission ceofficients for modes.
            """

            eigenmodes = None
            """
            Transmitted eigenmodes.
            
            :rtype: :class:`~optical.slab.Fourier3D.Eigenmodes`
            """

            fluxes = None
            """
            Perpendicular fluxes for transmitted modes.
            """


        @property
        def incident():
            """
            Incident field details.
            
            :rtype: Incident
            """

        def integrateEE(self, z1, z2):
            """
            integrateEE(self, z1, z2)
            
                Get average integral of the squared electric field:
                
                \\[\\frac 1 2 \\int_{z_1}^{z_2} \|E\|^2.\\]
                
                In the lateral direction integration is performed over the whole domain.
                
                Args:
                    z1 (float): Lower vertical bound of the integral.
                    z2 (float): Upper vertical bound of the integral.
                
                Returns:
                    float: Computed integral [V\ :sup:`2` / m\ :sup:`2`].
                
                Warning:
                    This method may return incorrect results for layers with gain,
                    due to the strong non-Hemiticity!
            """

        def integrateHH(self, z1, z2):
            """
            integrateHH(self, z1, z2)
            
                Get average integral of the squared magnetic field:
                
                \\[\\frac 1 2 \\int_{z_1}^{z_2} \|H\|^2.\\]
                
                In the lateral direction integration is performed over the whole domain.
                
                Args:
                    z1 (float): Lower vertical bound of the integral.
                    z2 (float): Upper vertical bound of the integral.
                Returns:
                    float: Computed integral [A\ :sup:`2` / m\ :sup:`2`].
                Warning:
                    This method may return incorrect results for layers with gain,
                    due to the strong non-Hemiticity!
            """

        outLightE = None
        """
        Provider of the computed electric field [V/m].
        
        
        outLightE(mesh, interpolation='default')
        
        :param mesh mesh: Target mesh to get the field at.
        :param str interpolation: Requested interpolation method.
        
        :return: Data with the electric field on the specified mesh **[V/m]**.
        
        Example:
           Connect the provider to a receiver in some other solver:
        
           >>> other_solver.inLightE = solver.outLightE
        
           Obtain the provided field:
        
           >>> solver.outLightE(mesh)
           <plask.Data at 0x1234567>
        
        See also:
        
           Provider class: :class:`plask.flow.LightEProvider3D`
        
           Receciver class: :class:`plask.flow.LightEReceiver3D`
        """

        outLightH = None
        """
        Provider of the computed magnetic field [A/m].
        
        
        outLightH(mesh, interpolation='default')
        
        :param mesh mesh: Target mesh to get the field at.
        :param str interpolation: Requested interpolation method.
        
        :return: Data with the magnetic field on the specified mesh **[A/m]**.
        
        Example:
           Connect the provider to a receiver in some other solver:
        
           >>> other_solver.inLightH = solver.outLightH
        
           Obtain the provided field:
        
           >>> solver.outLightH(mesh)
           <plask.Data at 0x1234567>
        
        See also:
        
           Provider class: :class:`plask.flow.LightHProvider3D`
        
           Receciver class: :class:`plask.flow.LightHReceiver3D`
        """

        outLightMagnitude = None
        """
        Provider of the computed light intensity [W/m²].
        
        
        outLightMagnitude(mesh, interpolation='default')
        
        :param mesh mesh: Target mesh to get the field at.
        :param str interpolation: Requested interpolation method.
        
        :return: Data with the light intensity on the specified mesh **[W/m²]**.
        
        Example:
           Connect the provider to a receiver in some other solver:
        
           >>> other_solver.inLightMagnitude = solver.outLightMagnitude
        
           Obtain the provided field:
        
           >>> solver.outLightMagnitude(mesh)
           <plask.Data at 0x1234567>
        
        See also:
        
           Provider class: :class:`plask.flow.LightMagnitudeProvider3D`
        
           Receciver class: :class:`plask.flow.LightMagnitudeReceiver3D`
        """

        @property
        def reflected():
            """
            Reflected field details.
            
            :rtype: Reflected
            """

        reflectivity = None
        """
        Total reflection coefficient [%].
        
        This differs from :attr:`Scattering.R` by unit.
        """

        @property
        def transmitted():
            """
            Transmitted field details.
            
            :rtype: Transmitted
            """

        transmittivity = None
        """
        Total transmission coefficient [%].
        
        This differs from :attr:`Scattering.T` by unit.
        """


    class Sizes(object):
        """
        Access wrapper for parameter along long/tran axis
        """

    class Symmetries(object):
        """
        Access wrapper for parameter along long/tran axis
        """

    def compute_reflectivity(*args, **kwargs):
        """
        compute_reflectivity(self, lam, side, polarization)
        compute_reflectivity(self, lam, side, index)
        compute_reflectivity(self, lam, side, coffs)
        
            Compute reflection coefficient on planar incidence [%].
            
            Args:
                lam (float or array of floats): Incident light wavelength.
                side (`top` or `bottom`): Side of the structure where the incident light is
                    present.
                polarization: Specification of the incident light polarization.
                    It should be a string of the form 'E\ *#*\ ', where *#* is the axis
                    name of the non-vanishing electric field component.
                idx: Eigenmode number.
                coeffs: expansion coefficients of the incident vector.
        """

    def compute_transmittivity(*args, **kwargs):
        """
        compute_transmittivity(self, lam, side, polarization)
        compute_transmittivity(self, lam, side, index)
        compute_transmittivity(self, lam, side, coffs)
        
            Compute transmission coefficient on planar incidence [%].
            
            Args:
                lam (float or array of floats): Incident light wavelength.
                side (`top` or `bottom`): Side of the structure where the incident light is
                    present.
                polarization: Specification of the incident light polarization.
                    It should be a string of the form 'E\ *#*\ ', where *#* is the axis name
                    of the non-vanishing electric field component.
                idx: Eigenmode number.
                coeffs: expansion coefficients of the incident vector.
        """

    dct = None
    """
    Type of discrete cosine transform for symmetric expansion.
    """

    emission = None
    """
    Direction of the useful light emission.
    
    Necessary for the over-threshold model to correctly compute the output power.
    Currently the fields are normalized only if this parameter is set to
    ``top`` or ``bottom``. Otherwise, it is ``undefined`` (default) and the fields
    are not normalized.
    """

    def find_mode(*args, **kwargs):
        """
        object find_mode(tuple args, dict kwds) :
            Compute the mode near the specified effective index.
            
            Only one of the following arguments can be given through a keyword.
            It is the starting point for search of the specified parameter.
            
            Args:
                lam (complex): Wavelength.
                k0 (complex): Normalized frequency.
                klong (complex): Longitudinal wavevector.
                ktran (complex): Transverse wavevector.
        """

    def gaussian(self, side, polarization, sigma, center):
        """
        gaussian(self, side, polarization, sigma, center)
        
            Create coefficients vector with Gaussian profile.
            
            This method is intended to use for :py:meth:`scattering` method.
            
            Args:
                side (`top` or `bottom`): Side of the structure where the incident light is
                    present.
                polarization: Specification of the incident light polarization.
                    It should be a string of the form 'E\ *#*\ ', where *#* is the axis name
                    of the non-vanishing electric field component.
                sigma (float or tuple): Gaussian standard deviation in longitudinal and
                                        transverse directions [µm, µm].
                center (tuple): Position of the beam center [µm, µm].
            
            Example:
               >>> scattered = fourier.scattering('top', 
               ...     fourier.gaussian('top', 'Ex', 0.2))
        """

    geometry = None
    """
    Geometry provided to the solver
    """

    def get_determinant(*args, **kwargs):
        """
        object get_determinant(tuple args, dict kwds) :
            Compute discontinuity matrix determinant.
            
            Arguments can be given through keywords only.
            
            Args:
                lam (complex): Wavelength.
                k0 (complex): Normalized frequency.
                klong (complex): Longitudinal wavevector.
                ktran (complex): Transverse wavevector.
        """

    def get_raw_E(self, num, level):
        """
        get_raw_E(self, num, level)
        
            Get Fourier expansion coefficients for the electric field.
            
            This is a low-level function returning :math:`E_l` and/or :math:`E_t` Fourier
            expansion coefficients. Please refer to the detailed solver description for their
            interpretation.
            
            Args:
                num (int): Computed mode number.
                level (float): Vertical level at which the coefficients are computed.
            
            :rtype: numpy.ndarray
        """

    def get_raw_H(self, num, level):
        """
        get_raw_H(self, num, level)
        
            Get Fourier expansion coefficients for the magnetic field.
            
            This is a low-level function returning :math:`H_l` and/or :math:`H_t` Fourier
            expansion coefficients. Please refer to the detailed solver description for their
            interpretation.
            
            Args:
                num (int): Computed mode number.
                level (float): Vertical level at which the coefficients are computed.
            
            :rtype: numpy.ndarray
        """

    group_layers = None
    """
    Layer grouping switch.
    
    If this property is ``True``, similar layers are grouped for efficiency.
    """

    id = None
    """
    Id of the solver object. (read only)
    
    Example:
        >>> mysolver.id
        mysolver:category.type
    """

    inGain = None
    """
    Receiver of the material gain required for computations [1/cm].
    
    
    You will find usage details in the documentation of the receiver class
    :class:`~plask.flow.GainReceiver3D`.
    
    Example:
       Connect the reveiver to a provider from some other solver:
    
       >>> solver.inGain = other_solver.outGain
    
    See also:
    
       Receciver class: :class:`plask.flow.GainReceiver3D`
    
       Provider class: :class:`plask.flow.GainProvider3D`
    
       Data filter: :class:`plask.filter.GainFilter3D`
    """

    inTemperature = None
    """
    Receiver of the temperature required for computations [K].
    
    
    You will find usage details in the documentation of the receiver class
    :class:`~plask.flow.TemperatureReceiver3D`.
    
    Example:
       Connect the reveiver to a provider from some other solver:
    
       >>> solver.inTemperature = other_solver.outTemperature
    
    See also:
    
       Receciver class: :class:`plask.flow.TemperatureReceiver3D`
    
       Provider class: :class:`plask.flow.TemperatureProvider3D`
    
       Data filter: :class:`plask.filter.TemperatureFilter3D`
    """

    def initialize(self):
        """
        initialize(self)
        
            Initialize solver.
            
            This method manually initialized the solver and sets :attr:`initialized` to
            *True*. Normally calling it is not necessary, as each solver automatically
            initializes itself when needed.
            
            Returns:
                bool: solver :attr:`initialized` state prior to this method call.
        """

    initialized = None
    """
    True if the solver has been initialized. (read only)
    
    Solvers usually get initialized at the beginning of the computations.
    You can clean the initialization state and free the memory by calling
    the :meth:`invalidate` method.
    """

    def integrateEE(*args, **kwargs):
        """
        integrateEE(self, z1, z2)
        integrateEE(self, num, z1, z2)
        
            Get average integral of the squared electric field:
            
            \\[\\frac 1 2 \\int_{z_1}^{z_2} \|E\|^2.\\]
            
            In the lateral direction integration is performed over the whole domain.
            
            Args:
                num (int): Computed mode number.
                z1 (float): Lower vertical bound of the integral.
                z2 (float): Upper vertical bound of the integral.
            
            Returns:
                float: Computed integral [V\ :sup:`2` / m\ :sup:`2`].
            Warning:
                This method may return incorrect results for layers with gain,
                due to the strong non-Hemiticity!
        """

    def integrateHH(*args, **kwargs):
        """
        integrateHH(self, z1, z2)
        integrateHH(self, num, z1, z2)
        
            Get average integral of the squared magnetic field:
            
            \\[\\frac 1 2 \\int_{z_1}^{z_2} \|H\|^2.\\]
            
            In the lateral direction integration is performed over the whole domain.
            
            Args:
                num (int): Computed mode number.
                z1 (float): Lower vertical bound of the integral.
                z2 (float): Upper vertical bound of the integral.
            Returns:
                float: Computed integral [A\ :sup:`2` / m\ :sup:`2`].
            Warning:
                This method may return incorrect results for layers with gain,
                due to the strong non-Hemiticity!
        """

    interface = None
    """
    Matching interface position.
    """

    def invalidate(self):
        """
        invalidate(self)
        
            Set the solver back to uninitialized state.
            
            This method frees the memory allocated by the solver and sets
            :attr:`initialized` to *False*.
        """

    k0 = None
    """
    Normalized frequency of the light [1/µm].
    
    Use this property only if you are looking for anything else than
    the wavelength,e.g. the effective index of lateral wavevector.
    """

    klong = None
    """
    Longitudinal propagation constant of the light [1/µm].
    
    Use this property only if you are looking for anything else than
    the longitudinal component of the propagation vector and the effective index.
    """

    ktran = None
    """
    Transverse propagation constant of the light [1/µm].
    
    Use this property only  if you are looking for anything else than
    the transverse component of the propagation vector.
    """

    lam = None
    """
    Wavelength of the light [nm].
    
    Use this property only if you are looking for anything else than
    the wavelength, e.g. the effective index of lateral wavevector.
    """

    lam0 = None
    """
    Reference wavelength.
    
    This is a wavelength at which refractive index is retrieved from the structure.
    If this parameter is None, material parameters are computed each time,
    the wavelenght changes even slightly (this is most accurate, but can be very
    inefficient.
    """

    layer_centers = None
    """
    Vertical posiotions of centers of each layer.
    
    At these positions materials and temperatures are probed.
    """

    layer_edges = None
    """
    Vertical posiotions of egges of each layer.
    """

    def layer_eigenmodes(self, level):
        """
        layer_eigenmodes(self, level)
        
            Get eignemodes for a layer at specified level.
            
            This is a low-level function to access diagonalized eigenmodes for a specific
            layer. Please refer to the detailed solver description for the interpretation
            of the returned values.
            
            Args:
                level (float): Vertical level at which the coefficients are computed.
            
            :rtype: :class:`~optical.slab.Fourier3D.Eigenmodes`
        """

    def load_xpl(self, xpl, manager):
        """
        load_xpl(self, xpl, manager)
        
            Load configuration from XPL reader.
            
            This method should be overriden in custom Python solvers.
            
            Example:
              .. code-block:: python
            
                 def load_xpl(self, xpl, manager):
                     for tag in xpl:
                         if tag == 'config':
                             self.a = tag['a']
                             self.b = tag.get('b', 0)
                             if 'c' in tag:
                                 self.c = tag['c']
                         if tag == 'combined':
                             for subtag in tag:
                                 if subtag == 'withtext':
                                     self.data = subtag.attrs
                                     # Text must be read last
                                     self.text = subtag.text
                         elif tag == 'geometry':
                             self.geometry = tag.getitem(manager.geo, 'ref')
        """

    modes = None
    """
    Computed modes.
    """

    outLightE = None
    """
    Provider of the computed electric field [V/m].
    
    
    outLightE(n=0, mesh, interpolation='default')
    
    :param int n: Number of the mode found with :meth:`find_mode`.
    :param mesh mesh: Target mesh to get the field at.
    :param str interpolation: Requested interpolation method.
    
    :return: Data with the electric field on the specified mesh **[V/m]**.
    
    You may obtain the number of different values this provider can return by
    testing its length.
    
    Example:
       Connect the provider to a receiver in some other solver:
    
       >>> other_solver.inModeLightE = solver.outLightE
    
       Obtain the provided field:
    
       >>> solver.outLightE(0, mesh)
       <plask.Data at 0x1234567>
    
       Test the number of provided values:
    
       >>> len(solver.outLightE)
       3
    
    See also:
    
       Provider class: :class:`plask.flow.ModeLightEProvider3D`
    
       Receciver class: :class:`plask.flow.ModeLightEReceiver3D`
    """

    outLightH = None
    """
    Provider of the computed magnetic field [A/m].
    
    
    outLightH(n=0, mesh, interpolation='default')
    
    :param int n: Number of the mode found with :meth:`find_mode`.
    :param mesh mesh: Target mesh to get the field at.
    :param str interpolation: Requested interpolation method.
    
    :return: Data with the magnetic field on the specified mesh **[A/m]**.
    
    You may obtain the number of different values this provider can return by
    testing its length.
    
    Example:
       Connect the provider to a receiver in some other solver:
    
       >>> other_solver.inModeLightH = solver.outLightH
    
       Obtain the provided field:
    
       >>> solver.outLightH(0, mesh)
       <plask.Data at 0x1234567>
    
       Test the number of provided values:
    
       >>> len(solver.outLightH)
       3
    
    See also:
    
       Provider class: :class:`plask.flow.ModeLightHProvider3D`
    
       Receciver class: :class:`plask.flow.ModeLightHReceiver3D`
    """

    outLightMagnitude = None
    """
    Provider of the computed optical field magnitude [W/m²].
    
    
    outLightMagnitude(n=0, mesh, interpolation='default')
    
    :param int n: Number of the mode found with :meth:`find_mode`.
    :param mesh mesh: Target mesh to get the field at.
    :param str interpolation: Requested interpolation method.
    
    :return: Data with the optical field magnitude on the specified mesh **[W/m²]**.
    
    You may obtain the number of different values this provider can return by
    testing its length.
    
    Example:
       Connect the provider to a receiver in some other solver:
    
       >>> other_solver.inModeLightMagnitude = solver.outLightMagnitude
    
       Obtain the provided field:
    
       >>> solver.outLightMagnitude(0, mesh)
       <plask.Data at 0x1234567>
    
       Test the number of provided values:
    
       >>> len(solver.outLightMagnitude)
       3
    
    See also:
    
       Provider class: :class:`plask.flow.ModeLightMagnitudeProvider3D`
    
       Receciver class: :class:`plask.flow.ModeLightMagnitudeReceiver3D`
    """

    outRefractiveIndex = None
    """
    Provider of the computed refractive index [-].
    
    
    outRefractiveIndex(mesh, interpolation='default')
    
    :param mesh mesh: Target mesh to get the field at.
    :param str interpolation: Requested interpolation method.
    
    :return: Data with the refractive index on the specified mesh **[-]**.
    
    Example:
       Connect the provider to a receiver in some other solver:
    
       >>> other_solver.inRefractiveIndex = solver.outRefractiveIndex
    
       Obtain the provided field:
    
       >>> solver.outRefractiveIndex(mesh)
       <plask.Data at 0x1234567>
    
    See also:
    
       Provider class: :class:`plask.flow.RefractiveIndexProvider3D`
    
       Receciver class: :class:`plask.flow.RefractiveIndexReceiver3D`
    """

    outWavelength = None
    """
    Provider of the computed wavelength [nm].
    
    
    outWavelength(n=0)
    
    :param int n: Value number.
    
    :return: Value of the wavelength **[nm]**.
    
    You may obtain the number of different values this provider can return by
    testing its length.
    
    Example:
       Connect the provider to a receiver in some other solver:
    
       >>> other_solver.inModeWavelength = solver.outWavelength
    
       Obtain the provided value:
    
       >>> solver.outWavelength(n=0)
       1000
    
       Test the number of provided values:
    
       >>> len(solver.outWavelength)
       3
    
    See also:
    
       Provider class: :class:`plask.flow.ModeWavelengthProvider`
    
       Receciver class: :class:`plask.flow.ModeWavelengthReceiver`
    """

    oversampling = None
    """
    Factor by which the number of coefficients is increased for FFT.
    """

    @property
    def pmls():
        """
        Longitudinal and transverse edge Perfectly Matched Layers boundary conditions.
        
        .. rubric:: Attributes:
        
        .. autosummary::
        
           ~optical.slab.PML.factor
           ~optical.slab.PML.shape
           ~optical.slab.PML.dist
           ~optical.slab.PML.size
        
        :rtype: PML
        """

    refine = None
    """
    Number of refinement points for refractive index averaging in longitudinal and transverse directions.
    """

    @property
    def root():
        """
        Configuration of the root searching algorithm.
        
        .. rubric:: Attributes:
        
        .. autosummary::
        
           ~optical.slab.RootParams.alpha
           ~optical.slab.RootParams.lambd
           ~optical.slab.RootParams.initial_range
           ~optical.slab.RootParams.maxiter
           ~optical.slab.RootParams.maxstep
           ~optical.slab.RootParams.method
           ~optical.slab.RootParams.tolf_max
           ~optical.slab.RootParams.tolf_min
           ~optical.slab.RootParams.tolx
        
        :rtype: RootParams
        """

    def scattering(*args, **kwargs):
        """
        scattering(self, side, polarization)
        scattering(self, side, idx)
        scattering(self, side, coeffs)
        
            Access to the reflected field.
            
            Args:
                side (`top` or `bottom`): Side of the structure where the incident light is
                    present.
                polarization: Specification of the incident light polarization.
                    It should be a string of the form 'E\ *#*\ ', where *#* is the axis name
                    of the non-vanishing electric field component.
                idx: Eigenmode number.
                coeffs: expansion coefficients of the incident vector.
            
            :rtype: Fourier3D.Scattering
        """

    def scattering_gaussian(self, side, polarization, sigma, center):
        """
        scattering_gaussian(self, side, polarization, sigma, center)
        
            Helper function to Access reflected fields for access incidence.
            
            This method is equivalent to calling:
            
               >>> fourier.scattering(side,
               ...     fourier.gaussian(side, polarization, sigma, center))
            
            Args:
                side (`top` or `bottom`): Side of the structure where the incident light is
                    present.
                polarization: Specification of the incident light polarization.
                    It should be a string of the form 'E\ *#*\ ', where *#* is the axis name
                    of the non-vanishing electric field component.
                sigma (float): Gaussian standard deviation [µm].
                center (float): Position of the beam center [µm].
        """

    def set_interface(*args, **kwargs):
        """
        set_interface(self, object, path=None)
        set_interface(self, pos)
        
            Set interface at the bottom of the specified object.
            
            Args:
                object (geometry object): object to set the interface at.
                path (path): Optional path specifying an instance of the object.
        
            Set interface as close as possible to the specified position.
            
            Args:
                pos (float): Position, near which the interface will be located.
        """

    def set_mode(*args, **kwargs):
        """
        object set_mode(tuple args, dict kwds) :
            Set the mode for specified parameters.
            
            This method should be used if you have found a mode manually and want to insert
            it into the solver in order to determine the fields. Calling this will raise an
            exception if the determinant for the specified parameters is too large.
            
            Arguments can be given through keywords only.
            
            Args:
                lam (complex): Wavelength.
                k0 (complex): Normalized frequency.
                klong (complex): Longitudinal wavevector.
                ktran (complex): Transverse wavevector.
        """

    size = None
    """
    Orthogonal expansion sizes in longitudinal and transverse directions.
    """

    smooth = None
    """
    Smoothing parameter for material boundaries (increases convergence).
    """

    stack = None
    """
    Stack of distinct layers.
    """

    symmetry = None
    """
    Longitudinal and transverse mode symmetries.
    """

    temp_diff = None
    """
    Maximum temperature difference between the layers in one group.
    
    If a temperature in a single layer varies vertically more than this value,
    the layer is split into two and put into separate groups. If this is empty,
    temperature gradient is ignored in layers grouping.
    """

    temp_dist = None
    """
    Temperature probing step.
    
    If :attr:`temp_diff` is not ``None``, the temperature is laterally probed
    in points approximately separated by this distance.
    """

    temp_layer = None
    """
    Temperature probing step.
    
    If :attr:`temp_diff` is not ``None``, this is the minimum thickness of sublayers
    resulting from temperature-gradient division.
    """

    transfer = None
    """
    Preferred transfer method.
    
    Can take on of the following values:
    
    ============ ====================================
    *auto*       Automatically choose the best method
    *reflection* Reflection Transfer Method
    *admittance* Admittance Transfer Method
    *impedance*  Impedance Transfer Method
    ============ ====================================
    
    Reflection transfer can have optional suffix ``-admittance`` (default)
    or ``-impedance``, in which case the admittance/impedance matching is done
    at interface (for eigenmode search). You should prefer admittance if electric
    field is expected to have significant horizontal components (particularly
    at the interface) i.e. for TE-like modes and impedance for TM-like modes.
    """

    update_gain = None
    """
    Always update gain.
    
    If this attribute is set to True, material parameters are always recomputed for
    layers with gains. This allows to set py:attr:`lam0` for better efficiency and
    still update gain for slight changes of wavelength.
    """

    vpml = None
    """
    Vertical Perfectly Matched Layers boundary conditions.
    
    .. rubric:: Attributes
    
    .. autosummary::
    
       ~optical.slab.PML.factor
       ~optical.slab.PML.dist
       ~optical.slab.PML.size
    
    Attribute ``shape`` is ignored for vertical PML (it is always 0).
    """

    wavelength = None
    """
    Alias for :attr:`lam`
    """



class OldBesselCyl(plask.Solver):
    """
    OldBesselCyl(name="")
    
    Optical Solver using Bessel expansion in cylindrical coordinates.
    
    It calculates optical modes and optical field distribution using Bessel slab method
    and reflection transfer in two-dimensional cylindrical space.
    """
    class Eigenmodes(object):
        """
        Layer eignemodes
        
        This is an advanced class allowing to extract eignemodes in each layer.
        """
        class Eigenmode(object):
            """
            Single eignemode. You can access object of this class by indexing
            :class:`~optical.slab.OldBesselCyl.Eigenmodes` object.
            """
            flux = None
            """
            Vertical flux for the eigenmode.
            
            This is equal to the vertical component of the Pointing vector integrated over
            the numerical domain.
            """

            kvert = None
            """
            Vertical propagation constant for the eigenmode.
            """

            raw_E = None
            """
            Electric field coefficients for the eigenmode.
            """

            raw_H = None
            """
            Magnetic field coefficients for the eigenmode.
            """


        outLightE = None
        """
        Provider of the computed electric field [V/m].
        
        
        outLightE(n=0, mesh, interpolation='default')
        
        :param int n: Number of the mode found with :meth:`find_mode`.:param mesh mesh: Target mesh to get the field at.
        :param str interpolation: Requested interpolation method.
        
        :return: Data with the electric field on the specified mesh **[V/m]**.
        
        You may obtain the number of different values this provider can return by
        testing its length.
        
        Example:
           Connect the provider to a receiver in some other solver:
        
           >>> other_solver.inLightE = solver.outLightE
        
           Obtain the provided field:
        
           >>> solver.outLightE(0, mesh)
           <plask.Data at 0x1234567>
        
           Test the number of provided values:
        
           >>> len(solver.outLightE)
           3
        
        See also:
        
           Provider class: :class:`plask.flow.LightEProviderCyl`
        
           Receciver class: :class:`plask.flow.LightEReceiverCyl`
        """

        outLightH = None
        """
        Provider of the computed electric field [A/m].
        
        
        outLightH(n=0, mesh, interpolation='default')
        
        :param int n: Number of the mode found with :meth:`find_mode`.:param mesh mesh: Target mesh to get the field at.
        :param str interpolation: Requested interpolation method.
        
        :return: Data with the electric field on the specified mesh **[A/m]**.
        
        You may obtain the number of different values this provider can return by
        testing its length.
        
        Example:
           Connect the provider to a receiver in some other solver:
        
           >>> other_solver.inLightH = solver.outLightH
        
           Obtain the provided field:
        
           >>> solver.outLightH(0, mesh)
           <plask.Data at 0x1234567>
        
           Test the number of provided values:
        
           >>> len(solver.outLightH)
           3
        
        See also:
        
           Provider class: :class:`plask.flow.LightHProviderCyl`
        
           Receciver class: :class:`plask.flow.LightHReceiverCyl`
        """

        outLightMagnitude = None
        """
        Provider of the computed light intensity [W/m²].
        
        
        outLightMagnitude(n=0, mesh, interpolation='default')
        
        :param int n: Number of the mode found with :meth:`find_mode`.:param mesh mesh: Target mesh to get the field at.
        :param str interpolation: Requested interpolation method.
        
        :return: Data with the light intensity on the specified mesh **[W/m²]**.
        
        You may obtain the number of different values this provider can return by
        testing its length.
        
        Example:
           Connect the provider to a receiver in some other solver:
        
           >>> other_solver.inLightMagnitude = solver.outLightMagnitude
        
           Obtain the provided field:
        
           >>> solver.outLightMagnitude(0, mesh)
           <plask.Data at 0x1234567>
        
           Test the number of provided values:
        
           >>> len(solver.outLightMagnitude)
           3
        
        See also:
        
           Provider class: :class:`plask.flow.LightMagnitudeProviderCyl`
        
           Receciver class: :class:`plask.flow.LightMagnitudeReceiverCyl`
        """


    class Mode(object):
        """
        Detailed information about the mode.
        """
        k0 = None
        """
        Mode normalized frequency [1/µm].
        """

        lam = None
        """
        Mode wavelength [nm].
        """

        loss = None
        """
        Mode loss [1/cm].
        """

        m = None
        """
        Angular mode order.
        """

        power = None
        """
        Total power emitted into the mode.
        """

        wavelength = None
        """
        Mode wavelength [nm].
        """


    def compute_reflectivity(*args, **kwargs):
        """
        compute_reflectivity(self, lam, side, index)
        compute_reflectivity(self, lam, side, coffs)
        
            Compute reflection coefficient on planar incidence [%].
            
            Args:
                lam (float or array of floats): Incident light wavelength.
                side (`top` or `bottom`): Side of the structure where the incident light is
                    present.
                idx: Eigenmode number.
                coeffs: expansion coefficients of the incident vector.
        """

    def compute_transmittivity(*args, **kwargs):
        """
        compute_transmittivity(self, lam, side, index)
        compute_transmittivity(self, lam, side, coffs)
        
            Compute transmission coefficient on planar incidence [%].
            
            Args:
                lam (float or array of floats): Incident light wavelength.
                side (`top` or `bottom`): Side of the structure where the incident light is
                    present.
                idx: Eigenmode number.
                coeffs: expansion coefficients of the incident vector.
        """

    domain = None
    """
    Computational domain ('finite' or 'infinite').
    """

    emission = None
    """
    Direction of the useful light emission.
    
    Necessary for the over-threshold model to correctly compute the output power.
    Currently the fields are normalized only if this parameter is set to
    ``top`` or ``bottom``. Otherwise, it is ``undefined`` (default) and the fields
    are not normalized.
    """

    def find_mode(self, lam, m=None):
        """
        find_mode(self, lam, m=None)
        
            Compute the mode near the specified effective index.
            
            Only one of the following arguments can be given through a keyword.
            It is the starting point for search of the specified parameter.
            
            Args:
                lam (complex): Starting wavelength.
                m (int): HE/EH Mode angular number. If ``None``, use :attr:`m` attribute.
        """

    geometry = None
    """
    Geometry provided to the solver
    """

    def get_determinant(*args, **kwargs):
        """
        object get_determinant(tuple args, dict kwds) :
            Compute discontinuity matrix determinant.
            
            Arguments can be given through keywords only.
            
            Args:
                lam (complex): Wavelength.
                k0 (complex): Normalized frequency.
                m (int): HE/EH Mode angular number.
        """

    def get_raw_E(self, num, level):
        """
        get_raw_E(self, num, level)
        
            Get Bessel expansion coefficients for the electric field.
            
            This is a low-level function returning :math:`E_s` and :math:`E_p` Bessel
            expansion coefficients. Please refer to the detailed solver description for their
            interpretation.
            
            Args:
                num (int): Computed mode number.
                level (float): Vertical lever at which the coefficients are computed.
            
            :rtype: numpy.ndarray
        """

    def get_raw_H(self, num, level):
        """
        get_raw_H(self, num, level)
        
            Get Bessel expansion coefficients for the magnetic field.
            
            This is a low-level function returning :math:`H_s` and :math:`H_p` Bessel
            expansion coefficients. Please refer to the detailed solver description for their
            interpretation.
            
            Args:
                num (int): Computed mode number.
                level (float): Vertical lever at which the coefficients are computed.
            
            :rtype: numpy.ndarray
        """

    group_layers = None
    """
    Layer grouping switch.
    
    If this property is ``True``, similar layers are grouped for efficiency.
    """

    id = None
    """
    Id of the solver object. (read only)
    
    Example:
        >>> mysolver.id
        mysolver:category.type
    """

    inGain = None
    """
    Receiver of the material gain required for computations [1/cm].
    
    
    You will find usage details in the documentation of the receiver class
    :class:`~plask.flow.GainReceiverCyl`.
    
    Example:
       Connect the reveiver to a provider from some other solver:
    
       >>> solver.inGain = other_solver.outGain
    
    See also:
    
       Receciver class: :class:`plask.flow.GainReceiverCyl`
    
       Provider class: :class:`plask.flow.GainProviderCyl`
    
       Data filter: :class:`plask.filter.GainFilterCyl`
    """

    inTemperature = None
    """
    Receiver of the temperature required for computations [K].
    
    
    You will find usage details in the documentation of the receiver class
    :class:`~plask.flow.TemperatureReceiverCyl`.
    
    Example:
       Connect the reveiver to a provider from some other solver:
    
       >>> solver.inTemperature = other_solver.outTemperature
    
    See also:
    
       Receciver class: :class:`plask.flow.TemperatureReceiverCyl`
    
       Provider class: :class:`plask.flow.TemperatureProviderCyl`
    
       Data filter: :class:`plask.filter.TemperatureFilterCyl`
    """

    def initialize(self):
        """
        initialize(self)
        
            Initialize solver.
            
            This method manually initialized the solver and sets :attr:`initialized` to
            *True*. Normally calling it is not necessary, as each solver automatically
            initializes itself when needed.
            
            Returns:
                bool: solver :attr:`initialized` state prior to this method call.
        """

    initialized = None
    """
    True if the solver has been initialized. (read only)
    
    Solvers usually get initialized at the beginning of the computations.
    You can clean the initialization state and free the memory by calling
    the :meth:`invalidate` method.
    """

    def integrateEE(*args, **kwargs):
        """
        integrateEE(self, z1, z2)
        integrateEE(self, num, z1, z2)
        
            Get average integral of the squared electric field:
            
            \\[\\frac 1 2 \\int_{z_1}^{z_2} \|E\|^2.\\]
            
            In the lateral direction integration is performed over the whole domain.
            
            Args:
                num (int): Computed mode number.
                z1 (float): Lower vertical bound of the integral.
                z2 (float): Upper vertical bound of the integral.
            
            Returns:
                float: Computed integral [V\ :sup:`2` / m\ :sup:`2`].
            Warning:
                This method may return incorrect results for layers with gain,
                due to the strong non-Hemiticity!
        """

    def integrateHH(*args, **kwargs):
        """
        integrateHH(self, z1, z2)
        integrateHH(self, num, z1, z2)
        
            Get average integral of the squared magnetic field:
            
            \\[\\frac 1 2 \\int_{z_1}^{z_2} \|H\|^2.\\]
            
            In the lateral direction integration is performed over the whole domain.
            
            Args:
                num (int): Computed mode number.
                z1 (float): Lower vertical bound of the integral.
                z2 (float): Upper vertical bound of the integral.
            Returns:
                float: Computed integral [A\ :sup:`2` / m\ :sup:`2`].
            Warning:
                This method may return incorrect results for layers with gain,
                due to the strong non-Hemiticity!
        """

    interface = None
    """
    Matching interface position.
    """

    def invalidate(self):
        """
        invalidate(self)
        
            Set the solver back to uninitialized state.
            
            This method frees the memory allocated by the solver and sets
            :attr:`initialized` to *False*.
        """

    k0 = None
    """
    Normalized frequency of the light [1/µm].
    """

    klist = None
    """
    A list of relative wavevetors ranges. The numbers should be relative to
    the inverse of the structure width. The actual wavevectors used in
    the computations are the avrages of each two adjacent values specified here
    and the integration weights are the sizes of each interval.
    """

    kmethod = None
    """
    Method of selecting wavevectors for numerical Hankel transform in infinite
    domain.
    """

    kscale = None
    """
    Scale factor for wavevectors used in infinite domain. Multiplied by the expansions
    size and divided by the geometry width it is a maximum considered wavevector.
    """

    lam = None
    """
    Wavelength of the light [nm].
    """

    lam0 = None
    """
    Reference wavelength.
    
    This is a wavelength at which refractive index is retrieved from the structure.
    If this parameter is None, material parameters are computed each time,
    the wavelenght changes even slightly (this is most accurate, but can be very
    inefficient.
    """

    layer_centers = None
    """
    Vertical posiotions of centers of each layer.
    
    At these positions materials and temperatures are probed.
    """

    layer_edges = None
    """
    Vertical posiotions of egges of each layer.
    """

    def layer_eigenmodes(self, level):
        """
        layer_eigenmodes(self, level)
        
            Get eignemodes for a layer at specified level.
            
            This is a low-level function to access diagonalized eigenmodes for a specific
            layer. Please refer to the detailed solver description for the interpretation
            of the returned values.
            
            Args:
                level (float): Vertical level at which the coefficients are computed.
            
            :rtype: :class:`~optical.slab.OldBesselCyl.Eigenmodes`
        """

    def load_xpl(self, xpl, manager):
        """
        load_xpl(self, xpl, manager)
        
            Load configuration from XPL reader.
            
            This method should be overriden in custom Python solvers.
            
            Example:
              .. code-block:: python
            
                 def load_xpl(self, xpl, manager):
                     for tag in xpl:
                         if tag == 'config':
                             self.a = tag['a']
                             self.b = tag.get('b', 0)
                             if 'c' in tag:
                                 self.c = tag['c']
                         if tag == 'combined':
                             for subtag in tag:
                                 if subtag == 'withtext':
                                     self.data = subtag.attrs
                                     # Text must be read last
                                     self.text = subtag.text
                         elif tag == 'geometry':
                             self.geometry = tag.getitem(manager.geo, 'ref')
        """

    m = None
    """
    Angular dependence parameter.
    """

    mesh = None
    """
    Mesh provided to the solver
    """

    modes = None
    """
    Computed modes.
    """

    outLightE = None
    """
    Provider of the computed electric field [V/m].
    
    
    outLightE(n=0, mesh, interpolation='default')
    
    :param int n: Number of the mode found with :meth:`find_mode`.
    :param mesh mesh: Target mesh to get the field at.
    :param str interpolation: Requested interpolation method.
    
    :return: Data with the electric field on the specified mesh **[V/m]**.
    
    You may obtain the number of different values this provider can return by
    testing its length.
    
    Example:
       Connect the provider to a receiver in some other solver:
    
       >>> other_solver.inModeLightE = solver.outLightE
    
       Obtain the provided field:
    
       >>> solver.outLightE(0, mesh)
       <plask.Data at 0x1234567>
    
       Test the number of provided values:
    
       >>> len(solver.outLightE)
       3
    
    See also:
    
       Provider class: :class:`plask.flow.ModeLightEProviderCyl`
    
       Receciver class: :class:`plask.flow.ModeLightEReceiverCyl`
    """

    outLightH = None
    """
    Provider of the computed magnetic field [A/m].
    
    
    outLightH(n=0, mesh, interpolation='default')
    
    :param int n: Number of the mode found with :meth:`find_mode`.
    :param mesh mesh: Target mesh to get the field at.
    :param str interpolation: Requested interpolation method.
    
    :return: Data with the magnetic field on the specified mesh **[A/m]**.
    
    You may obtain the number of different values this provider can return by
    testing its length.
    
    Example:
       Connect the provider to a receiver in some other solver:
    
       >>> other_solver.inModeLightH = solver.outLightH
    
       Obtain the provided field:
    
       >>> solver.outLightH(0, mesh)
       <plask.Data at 0x1234567>
    
       Test the number of provided values:
    
       >>> len(solver.outLightH)
       3
    
    See also:
    
       Provider class: :class:`plask.flow.ModeLightHProviderCyl`
    
       Receciver class: :class:`plask.flow.ModeLightHReceiverCyl`
    """

    outLightMagnitude = None
    """
    Provider of the computed optical field magnitude [W/m²].
    
    
    outLightMagnitude(n=0, mesh, interpolation='default')
    
    :param int n: Number of the mode found with :meth:`find_mode`.
    :param mesh mesh: Target mesh to get the field at.
    :param str interpolation: Requested interpolation method.
    
    :return: Data with the optical field magnitude on the specified mesh **[W/m²]**.
    
    You may obtain the number of different values this provider can return by
    testing its length.
    
    Example:
       Connect the provider to a receiver in some other solver:
    
       >>> other_solver.inModeLightMagnitude = solver.outLightMagnitude
    
       Obtain the provided field:
    
       >>> solver.outLightMagnitude(0, mesh)
       <plask.Data at 0x1234567>
    
       Test the number of provided values:
    
       >>> len(solver.outLightMagnitude)
       3
    
    See also:
    
       Provider class: :class:`plask.flow.ModeLightMagnitudeProviderCyl`
    
       Receciver class: :class:`plask.flow.ModeLightMagnitudeReceiverCyl`
    """

    outLoss = None
    """
    Provider of the computed modal extinction [1/cm].
    
    
    outLoss(n=0)
    
    :param int n: Value number.
    
    :return: Value of the modal extinction **[1/cm]**.
    
    You may obtain the number of different values this provider can return by
    testing its length.
    
    Example:
       Connect the provider to a receiver in some other solver:
    
       >>> other_solver.inModeLoss = solver.outLoss
    
       Obtain the provided value:
    
       >>> solver.outLoss(n=0)
       1000
    
       Test the number of provided values:
    
       >>> len(solver.outLoss)
       3
    
    See also:
    
       Provider class: :class:`plask.flow.ModeLossProvider`
    
       Receciver class: :class:`plask.flow.ModeLossReceiver`
    """

    outRefractiveIndex = None
    """
    Provider of the computed refractive index [-].
    
    
    outRefractiveIndex(mesh, interpolation='default')
    
    :param mesh mesh: Target mesh to get the field at.
    :param str interpolation: Requested interpolation method.
    
    :return: Data with the refractive index on the specified mesh **[-]**.
    
    Example:
       Connect the provider to a receiver in some other solver:
    
       >>> other_solver.inRefractiveIndex = solver.outRefractiveIndex
    
       Obtain the provided field:
    
       >>> solver.outRefractiveIndex(mesh)
       <plask.Data at 0x1234567>
    
    See also:
    
       Provider class: :class:`plask.flow.RefractiveIndexProviderCyl`
    
       Receciver class: :class:`plask.flow.RefractiveIndexReceiverCyl`
    """

    outWavelength = None
    """
    Provider of the computed wavelength [nm].
    
    
    outWavelength(n=0)
    
    :param int n: Value number.
    
    :return: Value of the wavelength **[nm]**.
    
    You may obtain the number of different values this provider can return by
    testing its length.
    
    Example:
       Connect the provider to a receiver in some other solver:
    
       >>> other_solver.inModeWavelength = solver.outWavelength
    
       Obtain the provided value:
    
       >>> solver.outWavelength(n=0)
       1000
    
       Test the number of provided values:
    
       >>> len(solver.outWavelength)
       3
    
    See also:
    
       Provider class: :class:`plask.flow.ModeWavelengthProvider`
    
       Receciver class: :class:`plask.flow.ModeWavelengthReceiver`
    """

    @property
    def pml():
        """
        Side Perfectly Matched Layers boundary conditions.
        
        .. rubric:: Attributes:
        
        .. autosummary::
        
           ~optical.slab.PML.factor
           ~optical.slab.PML.shape
           ~optical.slab.PML.dist
           ~optical.slab.PML.size
        
        :rtype: PML
        """

    @property
    def root():
        """
        Configuration of the root searching algorithm.
        
        .. rubric:: Attributes:
        
        .. autosummary::
        
           ~optical.slab.RootParams.alpha
           ~optical.slab.RootParams.lambd
           ~optical.slab.RootParams.initial_range
           ~optical.slab.RootParams.maxiter
           ~optical.slab.RootParams.maxstep
           ~optical.slab.RootParams.method
           ~optical.slab.RootParams.tolf_max
           ~optical.slab.RootParams.tolf_min
           ~optical.slab.RootParams.tolx
        
        :rtype: RootParams
        """

    def scattering(*args, **kwargs):
        """
        scattering(self, side, idx)
        scattering(self, side, coeffs)
        
            Access to the reflected field.
            
            Args:
                side (`top` or `bottom`): Side of the structure where the incident light is
                    present.
                polarization: Specification of the incident light polarization.
                    It should be a string of the form 'E\ *#*\ ', where *#* is the axis name
                    of the non-vanishing electric field component.
                idx: Eigenmode number.
                coeffs: expansion coefficients of the incident vector.
            
            :rtype: Fourier2D.Scattering
        """

    def set_interface(*args, **kwargs):
        """
        set_interface(self, object, path=None)
        set_interface(self, pos)
        
            Set interface at the bottom of the specified object.
            
            Args:
                object (geometry object): object to set the interface at.
                path (path): Optional path specifying an instance of the object.
        
            Set interface as close as possible to the specified position.
            
            Args:
                pos (float): Position, near which the interface will be located.
        """

    def set_mode(self, arg2, arg3):
        """
        set_mode(self, arg2, arg3)
        
            Set the mode for specified parameters.
            
            This method should be used if you have found a mode manually and want to insert
            it into the solver in order to determine the fields. Calling this will raise an
            exception if the determinant for the specified parameters is too large.
            
            Arguments can be given through keywords only.
            
            Args:
                lam (complex): Wavelength.
                m (int): HE/EH Mode angular number.
        """

    size = None
    """
    Orthogonal expansion size.
    """

    smooth = None
    """
    Smoothing parameter for material boundaries (increases convergence).
    """

    stack = None
    """
    Stack of distinct layers.
    """

    temp_diff = None
    """
    Maximum temperature difference between the layers in one group.
    
    If a temperature in a single layer varies vertically more than this value,
    the layer is split into two and put into separate groups. If this is empty,
    temperature gradient is ignored in layers grouping.
    """

    temp_dist = None
    """
    Temperature probing step.
    
    If :attr:`temp_diff` is not ``None``, the temperature is laterally probed
    in points approximately separated by this distance.
    """

    temp_layer = None
    """
    Temperature probing step.
    
    If :attr:`temp_diff` is not ``None``, this is the minimum thickness of sublayers
    resulting from temperature-gradient division.
    """

    transfer = None
    """
    Preferred transfer method.
    
    Can take on of the following values:
    
    ============ ====================================
    *auto*       Automatically choose the best method
    *reflection* Reflection Transfer Method
    *admittance* Admittance Transfer Method
    *impedance*  Impedance Transfer Method
    ============ ====================================
    
    Reflection transfer can have optional suffix ``-admittance`` (default)
    or ``-impedance``, in which case the admittance/impedance matching is done
    at interface (for eigenmode search). You should prefer admittance if electric
    field is expected to have significant horizontal components (particularly
    at the interface) i.e. for TE-like modes and impedance for TM-like modes.
    """

    update_gain = None
    """
    Always update gain.
    
    If this attribute is set to True, material parameters are always recomputed for
    layers with gains. This allows to set py:attr:`lam0` for better efficiency and
    still update gain for slight changes of wavelength.
    """

    vpml = None
    """
    Vertical Perfectly Matched Layers boundary conditions.
    
    .. rubric:: Attributes
    
    .. autosummary::
    
       ~optical.slab.PML.factor
       ~optical.slab.PML.dist
       ~optical.slab.PML.size
    
    Attribute ``shape`` is ignored for vertical PML (it is always 0).
    """

    wavelength = None
    """
    Alias for :attr:`lam`
    """



class PML(object):
    """
    Perfectly matched layer details.
    """
    dist = None
    """
    PML distance from the structure.
    """

    factor = None
    """
    PML scaling factor.
    """

    shape = None
    """
    PML shape order (0 → flat, 1 → linearly increasing, 2 → quadratic, etc.).
    """

    size = None
    """
    PML size.
    """



class RootParams(object):
    """
    Configuration of the root finding algorithm.
    """
    alpha = None
    """
    Parameter ensuring sufficient decrease of determinant in each step
    (Broyden method only).
    """

    initial_range = None
    """
    Initial range size (Muller and Brent methods only).
    """

    lambd = None
    """
    Minimum decrease ratio of one step (Broyden method only).
    """

    maxiter = None
    """
    Maximum number of iterations.
    """

    maxstep = None
    """
    Maximum step in one iteration (Broyden method only).
    """

    method = None
    """
    Root finding method ('muller', 'broyden',  or 'brent')
    """

    tolf_max = None
    """
    Required tolerance on the function value.
    """

    tolf_min = None
    """
    Sufficient tolerance on the function value.
    """

    tolx = None
    """
    Absolute tolerance on the argument.
    """

