Exemple #1
0
def _get_station_data(
    data, location, orientation, component, plot_error=False):

    # Get the components
    if component in ['app_res', 'phase', 'amplitude']:
        real_tuple = _extract_location_data(data, location, orientation,
                                            'real', plot_error)
        imag_tuple = _extract_location_data(data, location, orientation,
                                            'imag', plot_error)

        if plot_error:
            freqs, real_data, real_std, real_floor = real_tuple
            freqs, imag_data, imag_std, imag_floor = imag_tuple
            # Add up the uncertainties
            real_uncert = real_std * np.abs(real_data) + real_floor
            imag_uncert = imag_std * np.abs(imag_data) + imag_floor
        else:
            freqs, real_data = real_tuple
            freqs, imag_data = imag_tuple

        if 'app_res' in component:
            comp_data = real_data + 1j * imag_data
            plot_data = (1. / (mu_0 * omega(freqs))) * np.abs(comp_data) ** 2
            if plot_error:
                res_uncert = (
                    (2. / (mu_0 * omega(freqs))) *
                    (real_data * real_uncert + imag_data * imag_uncert)
                )
                errorbars = [res_uncert, res_uncert]
        elif 'phase' in component:
            plot_data = np.arctan2(imag_data, real_data) * (180. / np.pi)
            if plot_error:
                phs_uncert = (
                    (1. / (real_data ** 2 + imag_data ** 2)) *
                    ((real_data * real_uncert - imag_data * imag_uncert))
                ) * (180. / np.pi)
                # Scale back the errorbars
                errorbars = [phs_uncert, phs_uncert]
        elif 'amplitude' in component:
            comp_data = real_data + 1j * imag_data
            plot_data = np.abs(comp_data)
            if plot_error:
                amp_uncert = ((1. / plot_data) *
                              ((np.abs(real_data) * real_uncert) +
                              (np.abs(imag_data) * imag_uncert))
                              )
                errorbars = [amp_uncert, amp_uncert] #[low_unsert, up_unsert]
    else:
        if plot_error:
            freqs, plot_data, std_data, floor_data = _extract_location_data(
                data, location, orientation, component, return_uncert=plot_error)
            attr_uncert = std_data * np.abs(plot_data) + floor_data
            errorbars = [attr_uncert, attr_uncert]
        else:
            freqs, plot_data = _extract_location_data(
                data, location, orientation, component, return_uncert=plot_error)
    if plot_error:
        return (freqs, plot_data, errorbars)
    else:
        return (freqs, plot_data)
Exemple #2
0
def _get_map_data(data, frequency, orientation, component, plot_error=False):
    """
    Function for getting frequency map data
    """

    # Get the components
    if component in ['app_res', 'phase', 'amplitude']:
        real_tuple = _extract_frequency_data(data, frequency, orientation,
                                             'real', plot_error)
        imag_tuple = _extract_frequency_data(data, frequency, orientation,
                                             'imag', plot_error)
        if plot_error:
            freqs, real_data, real_std, real_floor = real_tuple
            freqs, imag_data, imag_std, imag_floor = imag_tuple
            # Add up the uncertainties
            real_uncert = real_std * np.abs(real_data) + real_floor
            imag_uncert = imag_std * np.abs(imag_data) + imag_floor
        else:
            freqs, real_data = real_tuple
            freqs, imag_data = imag_tuple

        if 'app_res' in component:
            comp_data = real_data + 1j * imag_data
            plot_data = (1. / (mu_0 * omega(freqs))) * np.abs(comp_data)**2
            if plot_error:
                res_uncert = (
                    (2. / (mu_0 * omega(freqs))) *
                    (real_data * real_uncert + imag_data * imag_uncert))
                errorbars = [res_uncert, res_uncert]
        elif 'phase' in component:
            plot_data = np.arctan2(imag_data, real_data) * (180. / np.pi)
            if plot_error:
                phs_uncert = ((1. / (real_data**2 + imag_data**2)) *
                              ((real_data * real_uncert -
                                imag_data * imag_uncert))) * (180. / np.pi)
                # Scale back the errorbars
                errorbars = [phs_uncert, phs_uncert]
        elif 'amplitude' in component:
            comp_data = real_data + 1j * imag_data
            plot_data = np.abs(comp_data)
            if plot_error:
                amp_uncert = ((1. / plot_data) *
                              ((np.abs(real_data) * real_uncert) +
                               (np.abs(imag_data) * imag_uncert)))
                errorbars = [amp_uncert, amp_uncert]  #[low_unsert, up_unsert]
    else:

        if plot_error:
            freqs, plot_data, std_data, floor_data = _extract_frequency_data(
                data, frequency, orientation, component, return_uncert=error)
            attr_uncert = std_data * np.abs(plot_data) + floor_data
            errorbars = [attr_uncert, attr_uncert]
        else:
            freqs, plot_data = _extract_frequency_data(data,
                                                       frequency,
                                                       orientation,
                                                       component,
                                                       return_uncert=False)
    return (freqs, plot_data, errorbars)
Exemple #3
0
    def getADeriv(self, freq, u, v, adjoint=False):
        """
        The derivative of A wrt sigma
        """

        u_src = u['e_1dSolution']
        dMfSigma_dm = self.MfSigmaDeriv(u_src)
        if adjoint:
            return 1j * omega(freq) * mkvc(dMfSigma_dm.T * v, )
        # Note: output has to be nN/nF, not nC/nE.
        # v should be nC
        return 1j * omega(freq) * mkvc(dMfSigma_dm * v, )
Exemple #4
0
    def getADeriv(self, freq, u, v, adjoint=False):
        """
        The derivative of A wrt sigma
        """

        u_src = u['e_1dSolution']
        dMfSigma_dm = self.MfSigmaDeriv(u_src)
        if adjoint:
            return 1j * omega(freq) * mkvc(dMfSigma_dm.T * v,)
        # Note: output has to be nN/nF, not nC/nE.
        # v should be nC
        return 1j * omega(freq) * mkvc(dMfSigma_dm * v,)
Exemple #5
0
    def getADeriv(self, freq, u, v, adjoint=False):
        """
        Calculate the derivative of A wrt m.

        :param float freq: Frequency
        :param SimPEG.EM.NSEM.FieldsNSEM u: NSEM Fields object
        :param numpy.ndarray v: vector of size (nU,) (adjoint=False)
            and size (nP,) (adjoint=True)
        :rtype: numpy.ndarray
        :return: Calculated derivative (nP,) (adjoint=False) and (nU,)[NOTE return as a (nU/2,2)
            columnwise polarizations] (adjoint=True) for both polarizations

        """
        # Fix u to be a matrix nE,2
        # This considers both polarizations and returns a nE,2 matrix for each polarization
        # The solution types
        sol0, sol1 = self._solutionType

        if adjoint:
            dMe_dsigV = (
                self.MeSigmaDeriv(u[sol0], v[:self.mesh.nE], adjoint) +
                self.MeSigmaDeriv(u[sol1], v[self.mesh.nE:], adjoint)
            )
        else:
            # Need a nE,2 matrix to be returned
            dMe_dsigV = np.hstack(
                (
                    mkvc(self.MeSigmaDeriv(u[sol0], v, adjoint), 2),
                    mkvc(self.MeSigmaDeriv(u[sol1], v, adjoint), 2)
                )
            )
        return 1j * omega(freq) * dMe_dsigV
Exemple #6
0
def _get_plot_data(data, location, orientation, component):

    if 'app_res' in component:
        freqs, dat_r = _extract_location_data(
            data, location, orientation, 'real')
        freqs, dat_i = _extract_location_data(
            data, location, orientation, 'imag')
        dat = dat_r + 1j * dat_i
        plot_data = 1. / (mu_0 * omega(freqs)) * np.abs(dat) ** 2
    elif 'phase' in component:
        freqs, dat_r = _extract_location_data(
            data, location, orientation, 'real')
        freqs, dat_i = _extract_location_data(
            data, location, orientation, 'imag')
        plot_data = np.arctan2(dat_i, dat_r) * (180. / np.pi)
    elif 'amplitude' in component:
        freqs, dat_r = _extract_location_data(
            data, location, orientation, 'real')
        freqs, dat_i = _extract_location_data(
            data, location, orientation, 'imag')
        dat_complex = dat_r + 1j * dat_i
        plot_data = np.abs(dat_complex)
    else:
        freqs, plot_data = _extract_location_data(
            data, location, orientation, component)
    return (freqs, plot_data)
Exemple #7
0
    def getADeriv(self, freq, u, v, adjoint=False):
        """
        Calculate the derivative of A wrt m.

        :param float freq: Frequency
        :param SimPEG.EM.NSEM.FieldsNSEM u: NSEM Fields object
        :param numpy.ndarray v: vector of size (nU,) (adjoint=False)
            and size (nP,) (adjoint=True)
        :rtype: numpy.ndarray
        :return: Calculated derivative (nP,) (adjoint=False) and (nU,)[NOTE return as a (nU/2,2)
            columnwise polarizations] (adjoint=True) for both polarizations

        """
        # Fix u to be a matrix nE,2
        # This considers both polarizations and returns a nE,2 matrix for each polarization
        # The solution types
        sol0, sol1 = self._solutionType

        if adjoint:
            dMe_dsigV = sp.hstack((self.MeSigmaDeriv(
                u[sol0]).T, self.MeSigmaDeriv(u[sol1]).T)) * v
        else:
            # Need a nE,2 matrix to be returned
            dMe_dsigV = np.hstack(
                (mkvc(self.MeSigmaDeriv(u[sol0]) * v,
                      2), mkvc(self.MeSigmaDeriv(u[sol1]) * v, 2)))
        return 1j * omega(freq) * dMe_dsigV
Exemple #8
0
def _get_plot_data(data, location, orientation, component):

    if 'app_res' in component:
        freqs, dat_r = _extract_location_data(data, location, orientation,
                                              'real')
        freqs, dat_i = _extract_location_data(data, location, orientation,
                                              'imag')
        dat = dat_r + 1j * dat_i
        plot_data = 1. / (mu_0 * omega(freqs)) * np.abs(dat)**2
    elif 'phase' in component:
        freqs, dat_r = _extract_location_data(data, location, orientation,
                                              'real')
        freqs, dat_i = _extract_location_data(data, location, orientation,
                                              'imag')
        plot_data = np.arctan2(dat_i, dat_r) * (180. / np.pi)
    elif 'amplitude' in component:
        freqs, dat_r = _extract_location_data(data, location, orientation,
                                              'real')
        freqs, dat_i = _extract_location_data(data, location, orientation,
                                              'imag')
        dat_complex = dat_r + 1j * dat_i
        plot_data = np.abs(dat_complex)
    else:
        freqs, plot_data = _extract_location_data(data, location, orientation,
                                                  component)
    return (freqs, plot_data)
Exemple #9
0
    def getRHSDeriv(self, freq, v, adjoint=False):
        """
        The derivative of the RHS wrt sigma
        """

        Src = self.survey.getSrcByFreq(freq)[0]

        S_eDeriv = mkvc(Src.S_eDeriv_m(self, v, adjoint), )
        return -1j * omega(freq) * S_eDeriv
Exemple #10
0
    def getRHSDeriv(self, freq, v, adjoint=False):
        """
        The derivative of the RHS wrt sigma
        """

        Src = self.survey.getSrcByFreq(freq)[0]

        S_eDeriv = mkvc(Src.S_eDeriv_m(self, v, adjoint),)
        return -1j * omega(freq) * S_eDeriv
Exemple #11
0
    def getRHS(self, freq):
        """
            Function to return the right hand side for the system.
            :param float freq: Frequency
            :rtype: numpy.ndarray
            :return: RHS for 1 polarizations, primary fields (nF, 1)
        """

        # Get sources for the frequncy(polarizations)
        Src = self.survey.getSrcByFreq(freq)[0]
        # Only select the yx polarization
        S_e = mkvc(Src.S_e(self)[:, 1], 2)
        return -1j * omega(freq) * S_e
Exemple #12
0
    def getA(self, freq):
        """
        Function to get the A system.

        :param float freq: Frequency
        :rtype: scipy.sparse.csr_matrix
        :return: A
        """
        Mfmui = self.MfMui
        Mesig = self.MeSigma
        C = self.mesh.edgeCurl

        return C.T*Mfmui*C + 1j*omega(freq)*Mesig
Exemple #13
0
    def getA(self, freq):
        """
        Function to get the A system.

        :param float freq: Frequency
        :rtype: scipy.sparse.csr_matrix
        :return: A
        """
        Mfmui = self.MfMui
        Mesig = self.MeSigma
        C = self.mesh.edgeCurl

        return C.T * Mfmui * C + 1j * omega(freq) * Mesig
Exemple #14
0
    def getRHS(self, freq):
        """
            Function to return the right hand side for the system.
            :param float freq: Frequency
            :rtype: numpy.ndarray
            :return: RHS for 1 polarizations, primary fields (nF, 1)
        """

        # Get sources for the frequncy(polarizations)
        Src = self.survey.getSrcByFreq(freq)[0]
        # Only select the yx polarization
        S_e = mkvc(Src.S_e(self)[:, 1], 2)
        return -1j * omega(freq) * S_e
Exemple #15
0
    def getRHS(self, freq):
        """
        Function to return the right hand side for the system.

        :param float freq: Frequency
        :rtype: numpy.ndarray
        :return: RHS for both polarizations, primary fields (nE, 2)

        """

        # Get sources for the frequncy(polarizations)
        Src = self.survey.getSrcByFreq(freq)[0]
        S_e = Src.S_e(self)
        return -1j * omega(freq) * S_e
Exemple #16
0
    def getRHS(self, freq):
        """
        Function to return the right hand side for the system.

        :param float freq: Frequency
        :rtype: numpy.ndarray
        :return: RHS for both polarizations, primary fields (nE, 2)

        """

        # Get sources for the frequncy(polarizations)
        Src = self.survey.getSrcByFreq(freq)[0]
        S_e = Src.S_e(self)
        return -1j * omega(freq) * S_e
Exemple #17
0
    def getA(self, freq):
        """
            Function to get the A matrix.

            :param float freq: Frequency
            :rtype: scipy.sparse.csr_matrix
            :return: A
        """

        # Note: need to use the code above since in the 1D problem I want
        # e to live on Faces(nodes) and h on edges(cells). Might need to rethink this
        # Possible that _fieldType and _eqLocs can fix this
        MeMui = self.MeMui
        MfSigma = self.MfSigma
        C = self.mesh.nodalGrad
        # Make A
        A = C.T*MeMui*C + 1j*omega(freq)*MfSigma
        # Either return full or only the inner part of A
        return A
Exemple #18
0
    def getRHSDeriv(self, freq, v, adjoint=False):
        """
        The derivative of the RHS with respect to the model and the source

        :param float freq: Frequency
        :param numpy.ndarray v: vector of size (nU,) (adjoint=False)
            and size (nP,) (adjoint=True)
        :rtype: numpy.ndarray
        :return: Calculated derivative (nP,) (adjoint=False) and (nU,2) (adjoint=True)
            for both polarizations

        """

        # Note: the formulation of the derivative is the same for adjoint or not.
        Src = self.survey.getSrcByFreq(freq)[0]
        S_eDeriv = Src.S_eDeriv(self, v, adjoint)
        dRHS_dm = -1j * omega(freq) * S_eDeriv

        return dRHS_dm
Exemple #19
0
    def getA(self, freq):
        """
            Function to get the A matrix.

            :param float freq: Frequency
            :rtype: scipy.sparse.csr_matrix
            :return: A
        """

        # Note: need to use the code above since in the 1D problem I want
        # e to live on Faces(nodes) and h on edges(cells). Might need to rethink this
        # Possible that _fieldType and _eqLocs can fix this
        MeMui = self.MeMui
        MfSigma = self.MfSigma
        C = self.mesh.nodalGrad
        # Make A
        A = C.T * MeMui * C + 1j * omega(freq) * MfSigma
        # Either return full or only the inner part of A
        return A
Exemple #20
0
    def getRHSDeriv(self, freq, v, adjoint=False):
        """
        The derivative of the RHS with respect to the model and the source

        :param float freq: Frequency
        :param numpy.ndarray v: vector of size (nU,) (adjoint=False)
            and size (nP,) (adjoint=True)
        :rtype: numpy.ndarray
        :return: Calculated derivative (nP,) (adjoint=False) and (nU,2) (adjoint=True)
            for both polarizations

        """

        # Note: the formulation of the derivative is the same for adjoint or not.
        Src = self.survey.getSrcByFreq(freq)[0]
        S_eDeriv = Src.S_eDeriv(self, v, adjoint)
        dRHS_dm = -1j * omega(freq) * S_eDeriv

        return dRHS_dm
Exemple #21
0
import numpy as np
from scipy.constants import epsilon_0
from scipy.constants import mu_0
from SimPEG.EM.Utils.EMUtils import k
from SimPEG.EM.Utils.EMUtils import omega

__all__ = ['MT_LayeredEarth']

# Evaluate Impedance Z of a layer
_ImpZ = lambda f, mu, k: omega(f) * mu / k

# Complex Cole-Cole Conductivity - EM utils
_PCC = lambda siginf, m, t, c, f: siginf * (1. - (m /
                                                  (1. +
                                                   (1j * omega(f) * t)**c)))

# matrix P relating Up and Down components with E and H fields
_P = lambda z: np.matrix([[
    1.,
    1,
], [-1. / z, 1. / z]], dtype='complex_')
_Pinv = lambda z: np.matrix([[1., -z], [1., z]], dtype='complex_') / 2.

# matrix T for transition of Up and Down components accross a layer
_T = lambda h, k: np.matrix(
    [[np.exp(1j * k * h), 0.], [0., np.exp(-1j * k * h)]], dtype='complex_')
_Tinv = lambda h, k: np.matrix(
    [[np.exp(-1j * k * h), 0.], [0., np.exp(1j * k * h)]], dtype='complex_')


# Propagate Up and Down component for a certain frequency & evaluate E and H field
Exemple #22
0
import numpy as np
from scipy.constants import epsilon_0
from scipy.constants import mu_0
from SimPEG.EM.Utils.EMUtils import k
from SimPEG.EM.Utils.EMUtils import omega

__all__ = [
    'MT_LayeredEarth'
]


# Evaluate Impedance Z of a layer
_ImpZ = lambda f, mu, k: omega(f)*mu/k

# Complex Cole-Cole Conductivity - EM utils
_PCC = lambda siginf, m, t, c, f: siginf*(1.-(m/(1.+(1j*omega(f)*t)**c)))

# matrix P relating Up and Down components with E and H fields
_P = lambda z: np.matrix([[1., 1, ], [-1./z, 1./z]], dtype='complex_')
_Pinv = lambda z: np.matrix([[1., -z], [1., z]], dtype='complex_')/2.

# matrix T for transition of Up and Down components accross a layer
_T = lambda h, k: np.matrix([[np.exp(1j*k*h), 0.], [0., np.exp(-1j*k*h)]], dtype='complex_')
_Tinv = lambda h, k: np.matrix([[np.exp(-1j*k*h), 0.], [0., np.exp(1j*k*h)]], dtype='complex_')

# Propagate Up and Down component for a certain frequency & evaluate E and H field
def _Propagate(f, thickness, sig, chg, taux, c, mu_r, eps_r, n):

    if isinstance(eps_r, float):
        epsmodel = np.ones_like(sig)*eps_r
    else:
Exemple #23
0
import numpy as np
from scipy.constants import epsilon_0
from scipy.constants import mu_0
from SimPEG.EM.Utils.EMUtils import k
from SimPEG.EM.Utils.EMUtils import omega

__all__ = [
    'MT_LayeredEarth'
]


# Evaluate Impedance Z of a layer
_ImpZ = lambda f, mu, k: omega(f)*mu/k

# Complex Cole-Cole Conductivity - EM utils
_PCC = lambda siginf, m, t, c, f: siginf*(1.-(m/(1.+(1j*omega(f)*t)**c)))

# matrix P relating Up and Down components with E and H fields
_P = lambda z: np.matrix([[1., 1, ], [-1./z, 1./z]], dtype='complex_')
_Pinv = lambda z: np.matrix([[1., -z], [1., z]], dtype='complex_')/2.

# matrix T for transition of Up and Down components accross a layer
_T = lambda h, k: np.matrix([[np.exp(1j*k*h), 0.], [0., np.exp(-1j*k*h)]], dtype='complex_')
_Tinv = lambda h, k: np.matrix([[np.exp(-1j*k*h), 0.], [0., np.exp(1j*k*h)]], dtype='complex_')

# Propagate Up and Down component for a certain frequency & evaluate E and H field
def _Propagate(f, thickness, sig, chg, taux, c, mu_r, eps_r, n):

    if isinstance(eps_r, float):
        epsmodel = np.ones_like(sig)*eps_r
    else:
Exemple #24
0
def MT_LayeredEarth(freq, thickness, sig, return_type='Res-Phase', chg=0., tau=0., c=0., mu_r=1., eps_r=1.):
    """
    This code compute the analytic response of a n-layered Earth to a plane wave (Magnetotellurics).
    All physical properties arrays convention describes the layers parameters from the top layer to the bottom layer.
    The solution is first developed in Ward and Hohmann 1988.
    See also http://em.geosci.xyz/content/maxwell3_fdem/natural_sources/MT_N_layered_Earth.html

    :param freq: the frequency at which we take the measurements
    :type freq: float or numpy.array
    :param thickness: thickness of the Earth layers in meters, size is len(sig)-1. The last one is already considered infinite. For 1-layer Earth, thickness = None or 0.
    :type thickness: float or numpy.array
    :param sig: electric conductivity of the Earth layers in S/m
    :type sig: float or numpy.array
    :param str return_type: Output return_type. 'Res-Phase' returns apparent resisitivity and Phase. 'Impedance' returns the complex Impedance
    :param numpy.array chg: Cole-Cole Parameters for chargeable layers: chargeability
    :param numpy.array tau: Cole-Cole Parameters for chargeable layers: time decay constant
    :param numpy.array c: Cole-Cole Parameters for chargeable layers: geometric factor
    :param mu_r: relative magnetic permeability
    :type mu_r: float or numpy.array
    :param eps_r: relative dielectric permittivity
    :type eps_r: float or numpy.array
    """

    if isinstance(freq, float):
        F = np.r_[freq]
    else:
        F = freq

    if isinstance(sig, float):
        sigmodel = np.r_[sig]
    else:
        sigmodel = sig

    if isinstance(thickness, float):
        if thickness == 0.:
            thickmodel = np.empty(0)
        else:
            thickmodel = np.r_[thickness]
    elif thickness is None:
        thickmodel = np.empty(0)
    else:
        thickmodel = thickness

    # Count the number of layers
    nlayer = len(sigmodel)

    Res = np.zeros_like(F)
    Phase = np.zeros_like(F)
    App_ImpZ = np.zeros_like(F, dtype='complex_')

    for i in range(0, len(F)):
        _, EH, _, _ = _Propagate(F[i], thickmodel, sigmodel, chg, tau, c, mu_r, eps_r, nlayer)

        App_ImpZ[i] = EH[0, 1]/EH[1, 1]

        Res[i] = np.abs(App_ImpZ[i])**2./(mu_0*omega(F[i]))
        Phase[i] = np.angle(App_ImpZ[i], deg=True)

    if return_type == 'Res-Phase':
        return Res, Phase

    elif return_type == 'Impedance':
        return App_ImpZ
Exemple #25
0
def MT_LayeredEarth(freq, thickness, sig, return_type='Res-Phase', chg=0., tau=0., c=0., mu_r=1., eps_r=1.):
    """
    This code compute the analytic response of a n-layered Earth to a plane wave (Magnetotellurics).
    All physical properties arrays convention describes the layers parameters from the top layer to the bottom layer.
    The solution is first developed in Ward and Hohmann 1988.
    See also http://em.geosci.xyz/content/maxwell3_fdem/natural_sources/MT_N_layered_Earth.html

    :param freq: the frequency at which we take the measurements
    :type freq: float or numpy.ndarray
    :param thickness: thickness of the Earth layers in meters, size is len(sig)-1. The last one is already considered infinite. For 1-layer Earth, thickness = None or 0.
    :type thickness: float or numpy.ndarray
    :param sig: electric conductivity of the Earth layers in S/m
    :type sig: float or numpy.ndarray
    :param str return_type: Output return_type. 'Res-Phase' returns apparent resisitivity and Phase. 'Impedance' returns the complex Impedance
    :param numpy.ndarray chg: Cole-Cole Parameters for chargeable layers: chargeability
    :param numpy.ndarray tau: Cole-Cole Parameters for chargeable layers: time decay constant
    :param numpy.ndarray c: Cole-Cole Parameters for chargeable layers: geometric factor
    :param mu_r: relative magnetic permeability
    :type mu_r: float or numpy.ndarray
    :param eps_r: relative dielectric permittivity
    :type eps_r: float or numpy.ndarray
    """

    if isinstance(freq, float):
        F = np.r_[freq]
    else:
        F = freq

    if isinstance(sig, float):
        sigmodel = np.r_[sig]
    else:
        sigmodel = sig

    if isinstance(thickness, float):
        if thickness == 0.:
            thickmodel = np.empty(0)
        else:
            thickmodel = np.r_[thickness]
    elif thickness is None:
        thickmodel = np.empty(0)
    else:
        thickmodel = thickness

    # Count the number of layers
    nlayer = len(sigmodel)

    Res = np.zeros_like(F)
    Phase = np.zeros_like(F)
    App_ImpZ = np.zeros_like(F, dtype='complex_')

    for i in range(0, len(F)):
        _, EH, _, _ = _Propagate(F[i], thickmodel, sigmodel, chg, tau, c, mu_r, eps_r, nlayer)

        App_ImpZ[i] = EH[0, 1]/EH[1, 1]

        Res[i] = np.abs(App_ImpZ[i])**2./(mu_0*omega(F[i]))
        Phase[i] = np.angle(App_ImpZ[i], deg=True)

    if return_type == 'Res-Phase':
        return Res, Phase

    elif return_type == 'Impedance':
        return App_ImpZ