def e_field_from_sheet_current(XYZ,
                               srcLoc,
                               sig,
                               t,
                               E0=1.0,
                               orientation="X",
                               kappa=0.0,
                               epsr=1.0):
    """
        Computing Analytic Electric fields from Plane wave in a Wholespace
        TODO:
            Add description of parameters
    """

    XYZ = utils.asArray_N_x_Dim(XYZ, 3)
    # Check
    if XYZ.shape[0] > 1 & t.shape[0] > 1:
        raise Exception(
            "I/O type error: For multiple field locations only a single frequency can be specified."
        )

    mu = mu_0 * (1 + kappa)

    if orientation == "X":
        z = XYZ[:, 2]
        bunja = -E0 * (mu * sig)**0.5 * z * np.exp(-(mu * sig * z**2) /
                                                   (4 * t))
        bunmo = 2 * np.pi**0.5 * t**1.5
        Ex = bunja / bunmo
        Ey = np.zeros_like(z)
        Ez = np.zeros_like(z)
        return Ex, Ey, Ez
    else:
        raise NotImplementedError()
def h_field_from_sheet_current(XYZ,
                               srcLoc,
                               sig,
                               t,
                               E0=1.0,
                               orientation="X",
                               kappa=0.0,
                               epsr=1.0):
    """
        Plane wave propagating downward (negative z (depth))
    """

    XYZ = utils.asArray_N_x_Dim(XYZ, 3)
    # Check
    if XYZ.shape[0] > 1 & t.shape[0] > 1:
        raise Exception(
            "I/O type error: For multiple field locations only a single frequency can be specified."
        )

    mu = mu_0 * (1 + kappa)
    if orientation == "X":
        z = XYZ[:, 2]
        Hx = np.zeros_like(z)
        Hy = (E0 * np.sqrt(sig / (np.pi * mu * t)) *
              np.exp(-(mu * sig * z**2) / (4 * t)))
        Hz = np.zeros_like(z)
        return Hx, Hy, Hz
    else:
        raise NotImplementedError()
Beispiel #3
0
def h_field_from_sheet_current(
    XYZ, srcLoc, sig, f, E0=1.0, orientation="X", kappa=0.0, epsr=1.0, t=0.0
):
    """
        Plane wave propagating downward (negative z (depth))
    """

    XYZ = utils.asArray_N_x_Dim(XYZ, 3)
    # Check
    if XYZ.shape[0] > 1 & f.shape[0] > 1:
        raise Exception(
            "I/O type error: For multiple field locations only a single frequency can be specified."
        )

    mu = mu_0 * (1 + kappa)
    epsilon = epsilon_0 * epsr
    # sig_hat = sig + 1j * omega(f) * epsilon
    k = np.sqrt(omega(f) ** 2.0 * mu * epsilon - 1j * omega(f) * mu * sig)
    Z = omega(f) * mu / k
    if orientation == "X":
        z = XYZ[:, 2]
        Hx = np.zeros_like(z)
        Hy = E0 / Z * np.exp(1j * (k * (z - srcLoc) + omega(f) * t))
        Hz = np.zeros_like(z)
        return Hx, Hy, Hz
    else:
        raise NotImplementedError()
Beispiel #4
0
def e_field_from_sheet_current(
    XYZ, srcLoc, sig, f, E0=1.0, orientation="X", kappa=0.0, epsr=1.0, t=0.0
):
    """
        Computing Analytic Electric fields from Plane wave in a Wholespace
        TODO:
            Add description of parameters
    """

    XYZ = utils.asArray_N_x_Dim(XYZ, 3)
    # Check
    if XYZ.shape[0] > 1 & f.shape[0] > 1:
        raise Exception(
            "I/O type error: For multiple field locations only a single frequency can be specified."
        )

    mu = mu_0 * (1 + kappa)
    epsilon = epsilon_0 * epsr
    # sig_hat = sig + 1j * omega(f) * epsilon
    k = np.sqrt(omega(f) ** 2.0 * mu * epsilon - 1j * omega(f) * mu * sig)
    # print t
    if orientation == "X":
        z = XYZ[:, 2]
        Ex = E0 * np.exp(1j * (k * (z - srcLoc) + omega(f) * t))
        Ey = np.zeros_like(z)
        Ez = np.zeros_like(z)
        return Ex, Ey, Ez
    else:
        raise NotImplementedError()
Beispiel #5
0
def E_galvanic_from_ElectricDipoleWholeSpace(
    XYZ,
    srcLoc,
    sig,
    f,
    current=1.0,
    length=1.0,
    orientation="X",
    kappa=1.0,
    epsr=1.0,
    t=0.0,
):
    """
        Computing Galvanic portion of Electric fields from Electrical Dipole in a Wholespace
        TODO:
            Add description of parameters
    """
    mu = mu_0 * (1 + kappa)
    epsilon = epsilon_0 * epsr
    sig_hat = sig + 1j * omega(f) * epsilon

    XYZ = utils.asArray_N_x_Dim(XYZ, 3)
    # Check
    if XYZ.shape[0] > 1 & f.shape[0] > 1:
        raise Exception(
            "I/O type error: For multiple field locations only a single frequency can be specified."
        )

    dx = XYZ[:, 0] - srcLoc[0]
    dy = XYZ[:, 1] - srcLoc[1]
    dz = XYZ[:, 2] - srcLoc[2]

    r = np.sqrt(dx**2.0 + dy**2.0 + dz**2.0)
    # k  = np.sqrt( -1j*2.*np.pi*f*mu*sig )
    k = np.sqrt(omega(f)**2.0 * mu * epsilon - 1j * omega(f) * mu * sig)

    front = current * length / (4.0 * np.pi * sig_hat * r**3) * np.exp(
        -1j * k * r)
    mid = -(k**2) * r**2 + 3 * 1j * k * r + 3

    if orientation.upper() == "X":
        Ex_galvanic = front * ((dx**2 / r**2) * mid + (-1j * k * r - 1.0))
        Ey_galvanic = front * (dx * dy / r**2) * mid
        Ez_galvanic = front * (dx * dz / r**2) * mid
        return Ex_galvanic, Ey_galvanic, Ez_galvanic

    elif orientation.upper() == "Y":
        #  x--> y, y--> z, z-->x
        Ey_galvanic = front * ((dy**2 / r**2) * mid + (-1j * k * r - 1.0))
        Ez_galvanic = front * (dy * dz / r**2) * mid
        Ex_galvanic = front * (dy * dx / r**2) * mid
        return Ex_galvanic, Ey_galvanic, Ez_galvanic

    elif orientation.upper() == "Z":
        # x --> z, y --> x, z --> y
        Ez_galvanic = front * ((dz**2 / r**2) * mid + (-1j * k * r - 1.0))
        Ex_galvanic = front * (dz * dx / r**2) * mid
        Ey_galvanic = front * (dz * dy / r**2) * mid
        return Ex_galvanic, Ey_galvanic, Ez_galvanic
Beispiel #6
0
def H_from_MagneticDipoleWholeSpace(
    XYZ,
    srcLoc,
    sig,
    f,
    current=1.0,
    loopArea=1.0,
    orientation="X",
    kappa=1.0,
    epsr=1.0,
    t=0.0,
):
    """
        Computing magnetic fields from Magnetic Dipole in a Wholespace
        TODO:
            Add description of parameters
    """
    mu = mu_0 * (1 + kappa)
    epsilon = epsilon_0 * epsr
    m = current * loopArea

    XYZ = utils.asArray_N_x_Dim(XYZ, 3)
    # Check
    if XYZ.shape[0] > 1 & f.shape[0] > 1:
        raise Exception(
            "I/O type error: For multiple field locations only a single frequency can be specified."
        )

    dx = XYZ[:, 0] - srcLoc[0]
    dy = XYZ[:, 1] - srcLoc[1]
    dz = XYZ[:, 2] - srcLoc[2]

    r = np.sqrt(dx**2.0 + dy**2.0 + dz**2.0)
    # k  = np.sqrt( -1j*2.*np.pi*f*mu*sig )
    k = np.sqrt(omega(f)**2.0 * mu * epsilon - 1j * omega(f) * mu * sig)

    front = m / (4.0 * np.pi * (r)**3) * np.exp(-1j * k * r)
    mid = -(k**2) * r**2 + 3 * 1j * k * r + 3

    if orientation.upper() == "X":
        Hx = front * ((dx**2 / r**2) * mid + (k**2 * r**2 - 1j * k * r - 1.0))
        Hy = front * (dx * dy / r**2) * mid
        Hz = front * (dx * dz / r**2) * mid
        return Hx, Hy, Hz

    elif orientation.upper() == "Y":
        #  x--> y, y--> z, z-->x
        Hy = front * ((dy**2 / r**2) * mid + (k**2 * r**2 - 1j * k * r - 1.0))
        Hz = front * (dy * dz / r**2) * mid
        Hx = front * (dy * dx / r**2) * mid
        return Hx, Hy, Hz

    elif orientation.upper() == "Z":
        # x --> z, y --> x, z --> y
        Hz = front * ((dz**2 / r**2) * mid + (k**2 * r**2 - 1j * k * r - 1.0))
        Hx = front * (dz * dx / r**2) * mid
        Hy = front * (dz * dy / r**2) * mid
        return Hx, Hy, Hz
Beispiel #7
0
def E_from_MagneticDipoleWholeSpace(
    XYZ,
    srcLoc,
    sig,
    f,
    current=1.0,
    loopArea=1.0,
    orientation="X",
    kappa=0.0,
    epsr=1.0,
    t=0.0,
):
    """
        Computing analytic electric fields from Magnetic Dipole in a Wholespace
        TODO:
            Add description of parameters
    """
    mu = mu_0 * (1 + kappa)
    epsilon = epsilon_0 * epsr
    m = current * loopArea

    XYZ = utils.asArray_N_x_Dim(XYZ, 3)
    # Check
    if XYZ.shape[0] > 1 & f.shape[0] > 1:
        raise Exception(
            "I/O type error: For multiple field locations only a single frequency can be specified."
        )

    dx = XYZ[:, 0] - srcLoc[0]
    dy = XYZ[:, 1] - srcLoc[1]
    dz = XYZ[:, 2] - srcLoc[2]

    r = np.sqrt(dx**2.0 + dy**2.0 + dz**2.0)
    # k  = np.sqrt( -1j*2.*np.pi*f*mu*sig )
    k = np.sqrt(omega(f)**2.0 * mu * epsilon - 1j * omega(f) * mu * sig)

    front = (((1j * omega(f) * mu * m) / (4.0 * np.pi * r**2)) *
             (1j * k * r + 1) * np.exp(-1j * k * r))

    if orientation.upper() == "X":
        Ey = front * (dz / r)
        Ez = front * (-dy / r)
        Ex = np.zeros_like(Ey)
        return Ex, Ey, Ez

    elif orientation.upper() == "Y":
        Ex = front * (-dz / r)
        Ez = front * (dx / r)
        Ey = np.zeros_like(Ex)
        return Ex, Ey, Ez

    elif orientation.upper() == "Z":
        Ex = front * (dy / r)
        Ey = front * (-dx / r)
        Ez = np.zeros_like(Ex)
        return Ex, Ey, Ez
Beispiel #8
0
def E_inductive_from_ElectricDipoleWholeSpace(XYZ,
                                              srcLoc,
                                              sig,
                                              f,
                                              current=1.0,
                                              length=1.0,
                                              orientation="X",
                                              kappa=1.0,
                                              epsr=1.0):
    """
        Computing Inductive portion of Electric fields from Electrical Dipole in a Wholespace
        TODO:
            Add description of parameters
    """
    mu = mu_0 * (1 + kappa)
    epsilon = epsilon_0 * epsr
    sig_hat = sig + 1j * omega(f) * epsilon

    XYZ = utils.asArray_N_x_Dim(XYZ, 3)
    # Check
    if XYZ.shape[0] > 1 & f.shape[0] > 1:
        raise Exception(
            "I/O type error: For multiple field locations only a single frequency can be specified."
        )

    dx = XYZ[:, 0] - srcLoc[0]
    dy = XYZ[:, 1] - srcLoc[1]
    dz = XYZ[:, 2] - srcLoc[2]

    r = np.sqrt(dx**2.0 + dy**2.0 + dz**2.0)
    # k  = np.sqrt( -1j*2.*np.pi*f*mu*sig )
    k = np.sqrt(omega(f)**2.0 * mu * epsilon - 1j * omega(f) * mu * sig)

    front = current * length / (4.0 * np.pi * sig_hat * r**3) * np.exp(
        -1j * k * r)

    if orientation.upper() == "X":
        Ex_inductive = front * (k**2 * r**2)
        Ey_inductive = np.zeros_like(Ex_inductive)
        Ez_inductive = np.zeros_like(Ex_inductive)
        return Ex_inductive, Ey_inductive, Ez_inductive

    elif orientation.upper() == "Y":
        #  x--> y, y--> z, z-->x
        Ey_inductive = front * (k**2 * r**2)
        Ez_inductive = np.zeros_like(Ey_inductive)
        Ex_inductive = np.zeros_like(Ey_inductive)
        return Ex_inductive, Ey_inductive, Ez_inductive

    elif orientation.upper() == "Z":
        # x --> z, y --> x, z --> y
        Ez_inductive = front * (k**2 * r**2)
        Ex_inductive = np.zeros_like(Ez_inductive)
        Ey_inductive = np.zeros_like(Ez_inductive)
        return Ex_inductive, Ey_inductive, Ez_inductive
Beispiel #9
0
def F_from_MagneticDipoleWholeSpace(
    XYZ,
    srcLoc,
    sig,
    f,
    current=1.0,
    loopArea=1.0,
    orientation="X",
    kappa=1.0,
    epsr=1.0,
    t=0.0,
):
    """
        Computing magnetic vector potentials from Magnetic Dipole in a Wholespace
        TODO:
            Add description of parameters
    """
    mu = mu_0 * (1 + kappa)
    epsilon = epsilon_0 * epsr
    m = current * loopArea

    XYZ = utils.asArray_N_x_Dim(XYZ, 3)
    # Check
    if XYZ.shape[0] > 1 & f.shape[0] > 1:
        raise Exception(
            "I/O type error: For multiple field locations only a single frequency can be specified."
        )

    dx = XYZ[:, 0] - srcLoc[0]
    dy = XYZ[:, 1] - srcLoc[1]
    dz = XYZ[:, 2] - srcLoc[2]

    r = np.sqrt(dx**2.0 + dy**2.0 + dz**2.0)
    k = np.sqrt(omega(f)**2.0 * mu * epsilon - 1j * omega(f) * mu * sig)

    front = (1j * omega(f) * mu * m) / (4.0 * np.pi * r)

    if orientation.upper() == "X":
        Fx = front * np.exp(-1j * k * r)
        Fy = np.zeros_like(Fx)
        Fz = np.zeros_like(Fx)
        return Fx, Fy, Fz

    elif orientation.upper() == "Y":
        Fy = front * np.exp(-1j * k * r)
        Fx = np.zeros_like(Fy)
        Fz = np.zeros_like(Fy)
        return Fx, Fy, Fz

    elif orientation.upper() == "Z":
        Fz = front * np.exp(-1j * k * r)
        Fx = np.zeros_like(Fy)
        Fy = np.zeros_like(Fy)
        return Fx, Fy, Fz
Beispiel #10
0
    def test_asArray_N_x_Dim(self):

        true = np.array([[1, 2, 3]])

        listArray = asArray_N_x_Dim([1, 2, 3], 3)
        self.assertTrue(np.all(true == listArray))
        self.assertTrue(true.shape == listArray.shape)

        listArray = asArray_N_x_Dim(np.r_[1, 2, 3], 3)
        self.assertTrue(np.all(true == listArray))
        self.assertTrue(true.shape == listArray.shape)

        listArray = asArray_N_x_Dim(np.array([[1, 2, 3.0]]), 3)
        self.assertTrue(np.all(true == listArray))
        self.assertTrue(true.shape == listArray.shape)

        true = np.array([[1, 2], [4, 5]])

        listArray = asArray_N_x_Dim([[1, 2], [4, 5]], 2)
        self.assertTrue(np.all(true == listArray))
        self.assertTrue(true.shape == listArray.shape)
Beispiel #11
0
def A_from_ElectricDipoleWholeSpace(
    XYZ,
    srcLoc,
    sig,
    f,
    current=1.0,
    length=1.0,
    orientation="X",
    kappa=1.0,
    epsr=1.0,
    t=0.0,
):
    """
        Computing Electric vector potentials from Electrical Dipole in a Wholespace
        TODO:
            Add description of parameters
    """
    mu = mu_0 * (1 + kappa)
    epsilon = epsilon_0 * epsr
    XYZ = utils.asArray_N_x_Dim(XYZ, 3)
    # Check
    if XYZ.shape[0] > 1 & f.shape[0] > 1:
        raise Exception(
            "I/O type error: For multiple field locations only a single frequency can be specified."
        )

    dx = XYZ[:, 0] - srcLoc[0]
    dy = XYZ[:, 1] - srcLoc[1]
    dz = XYZ[:, 2] - srcLoc[2]

    r = np.sqrt(dx**2.0 + dy**2.0 + dz**2.0)
    k = np.sqrt(omega(f)**2.0 * mu * epsilon - 1j * omega(f) * mu * sig)

    front = current * length / (4.0 * np.pi * r)

    if orientation.upper() == "X":
        Ax = front * np.exp(-1j * k * r)
        Ay = np.zeros_like(Ax)
        Az = np.zeros_like(Ax)
        return Ax, Ay, Az

    elif orientation.upper() == "Y":
        Ay = front * np.exp(-1j * k * r)
        Ax = np.zeros_like(Ay)
        Az = np.zeros_like(Ay)
        return Ax, Ay, Az

    elif orientation.upper() == "Z":
        Az = front * np.exp(-1j * k * r)
        Ax = np.zeros_like(Ay)
        Ay = np.zeros_like(Ay)
        return Ax, Ay, Az
Beispiel #12
0
def H_from_ElectricDipoleWholeSpace(XYZ,
                                    srcLoc,
                                    sig,
                                    f,
                                    current=1.0,
                                    length=1.0,
                                    orientation="X",
                                    kappa=1.0,
                                    epsr=1.0):
    """
        Computing Magnetic fields from Electrical Dipole in a Wholespace
        TODO:
            Add description of parameters
    """
    mu = mu_0 * (1 + kappa)
    epsilon = epsilon_0 * epsr
    XYZ = utils.asArray_N_x_Dim(XYZ, 3)
    # Check
    if XYZ.shape[0] > 1 & f.shape[0] > 1:
        raise Exception(
            "I/O type error: For multiple field locations only a single frequency can be specified."
        )

    dx = XYZ[:, 0] - srcLoc[0]
    dy = XYZ[:, 1] - srcLoc[1]
    dz = XYZ[:, 2] - srcLoc[2]

    r = np.sqrt(dx**2.0 + dy**2.0 + dz**2.0)
    # k  = np.sqrt( -1j*2.*np.pi*f*mu*sig )
    k = np.sqrt(omega(f)**2.0 * mu * epsilon - 1j * omega(f) * mu * sig)

    front = (current * length / (4.0 * np.pi * r**2) * (-1j * k * r + 1) *
             np.exp(-1j * k * r))

    if orientation.upper() == "X":
        Hy = front * (-dz / r)
        Hz = front * (dy / r)
        Hx = np.zeros_like(Hy)
        return Hx, Hy, Hz

    elif orientation.upper() == "Y":
        Hx = front * (dz / r)
        Hz = front * (-dx / r)
        Hy = np.zeros_like(Hx)
        return Hx, Hy, Hz

    elif orientation.upper() == "Z":
        Hx = front * (-dy / r)
        Hy = front * (dx / r)
        Hz = np.zeros_like(Hx)
        return Hx, Hy, Hz
Beispiel #13
0
def MagneticDipoleWholeSpace(
    XYZ, srcLoc, sig, f, moment, fieldType="b", mu_r=1, eps_r=1, **kwargs
):
    """
    Analytical solution for a dipole in a whole-space.

    The analytical expression is given in Equation 2.57 in Ward and Hohmann,
    1988, and the example reproduces their Figure 2.2.

    TODOs:
        - set it up to instead take a mesh & survey
        - add divide by zero safety


    .. plot::

        import numpy as np
        from SimPEG import electromagnetics as EM
        import matplotlib.pyplot as plt
        from scipy.constants import mu_0
        freqs = np.logspace(-2, 5, 301)
        Bx, By, Bz = EM.analytics.FDEM.MagneticDipoleWholeSpace(
                [0, 100, 0], [0, 0, 0], 1e-2, freqs, moment='Z')
        plt.figure()
        plt.loglog(freqs, Bz.real/mu_0, 'C0', label='Real')
        plt.loglog(freqs, -Bz.real/mu_0, 'C0--')
        plt.loglog(freqs, Bz.imag/mu_0, 'C1', label='Imaginary')
        plt.loglog(freqs, -Bz.imag/mu_0, 'C1--')
        plt.legend()
        plt.xlim([1e-2, 1e5])
        plt.ylim([1e-13, 1e-6])
        plt.show()

    **Reference**

    - Ward, S. H., and G. W. Hohmann, 1988, Electromagnetic theory for
      geophysical applications, Chapter 4 of Electromagnetic Methods in Applied
      Geophysics: SEG, Investigations in Geophysics No. 3, 130--311; DOI:
      `10.1190/1.9781560802631.ch4
      <https://doi.org/10.1190/1.9781560802631.ch4>`_.

    """

    orient = kwargs.pop("orientation", None)
    if orient is not None:
        raise TypeError(
            "orientation kwarg has been removed, please use the moment argument",
        )
        magnitude = moment
        moment = orient
    else:
        magnitude = 1
    mu = kwargs.pop("mu", None)
    if mu is not None:
        raise TypeError("mu kwarg has been removed, please use the mu_r argument.")
        mu_r = mu / mu_0

    mu = mu_0 * mu_r
    eps = epsilon_0 * eps_r
    w = 2 * np.pi * f

    if isinstance(moment, str):
        if moment == "X":
            mx, my, mz = 1.0, 0.0, 0.0
        elif moment == "Y":
            mx, my, mz = 0.0, 1.0, 0.0
        elif moment == "Z":
            mx, my, mz = 0.0, 0.0, 1.0
        else:
            raise NotImplementedError("String type for moment not recognized")
        mx, my, mz = mx * magnitude, my * magnitude, mz * magnitude
    else:
        mx, my, mz = moment[0], moment[1], moment[2]

    XYZ = utils.asArray_N_x_Dim(XYZ, 3)

    dx = XYZ[:, 0] - srcLoc[0]
    dy = XYZ[:, 1] - srcLoc[1]
    dz = XYZ[:, 2] - srcLoc[2]

    r = np.sqrt(dx ** 2.0 + dy ** 2.0 + dz ** 2.0)
    k = np.sqrt(-1j * w * mu * sig + w ** 2 * mu * eps)
    kr = k * r

    if fieldType in ["h", "b"]:
        front = 1 / (4.0 * pi * r ** 3.0) * np.exp(-1j * kr)
        mid = -(kr ** 2.0) + 3.0 * 1j * kr + 3.0

        Fx = front * (
            mx * ((dx / r) ** 2.0 * mid + (kr ** 2.0 - 1j * kr - 1.0))
            + my * ((dy * dx / r ** 2.0) * mid)
            + mz * ((dx * dz / r ** 2.0) * mid)
        )

        Fy = front * (
            mx * ((dx * dy / r ** 2.0) * mid)
            + my * ((dy / r) ** 2.0 * mid + (kr ** 2.0 - 1j * kr - 1.0))
            + mz * ((dy * dz / r ** 2.0) * mid)
        )

        Fz = front * (
            mx * ((dx * dz / r ** 2.0) * mid)
            + my * ((dy * dz / r ** 2.0) * mid)
            + mz * ((dz / r) ** 2.0 * mid + (kr ** 2.0 - 1j * kr - 1.0))
        )

        if fieldType == "b":
            Fx, Fy, Fz = mu * Fx, mu * Fy, mu * Fz

    elif fieldType == "e":

        front = 1j * w * mu * (1 + 1j * kr) / (4.0 * pi * r ** 3.0) * np.exp(-1j * kr)

        Fx = front * (my * (dz / r) + mz * (-dy / r))

        Fy = front * (mx * (-dz / r) + mz * (dx / r))

        Fz = front * (mx * (dy / r) + my * (-dx / r))

    return Fx, Fy, Fz
Beispiel #14
0
def ElectricDipoleWholeSpace(
    XYZ, srcLoc, sig, f, moment="X", fieldType="e", mu_r=1, eps_r=1, **kwargs
):

    orient = kwargs.pop("orientation", None)
    if orient is not None:
        raise TypeError(
            "orientation kwarg has been removed, please use the moment argument."
        )
    mu = kwargs.pop("mu", None)
    if mu is not None:
        raise TypeError("mu kwarg has been removed, please use the mu_r argument.")
    cur = kwargs.pop("current", None)
    if cur is not None:
        raise TypeError(
            "current kwarg has been removed, please use the moment argument.",
        )
    else:
        magnitude = 1
    length = kwargs.pop("length", None)
    if length is not None:
        raise TypeError(
            "length kwarg has been removed, please use the moment argument."
        )

    mu = mu_0 * mu_r
    eps = epsilon_0 * eps_r
    w = 2 * np.pi * f

    if isinstance(moment, str):
        if moment.upper() == "X":
            mx, my, mz = 1.0, 0.0, 0.0
        elif moment.upper() == "Y":
            mx, my, mz = 0.0, 1.0, 0.0
        elif moment.upper() == "Z":
            mx, my, mz = 0.0, 0.0, 1.0
        else:
            raise NotImplementedError("String type for moment not recognized")
        mx, my, mz = mx * magnitude, my * magnitude, mz * magnitude

    else:
        mx, my, mz = moment[0], moment[1], moment[2]

    XYZ = utils.asArray_N_x_Dim(XYZ, 3)

    dx = XYZ[:, 0] - srcLoc[0]
    dy = XYZ[:, 1] - srcLoc[1]
    dz = XYZ[:, 2] - srcLoc[2]

    r = np.sqrt(dx ** 2.0 + dy ** 2.0 + dz ** 2.0)
    k = np.sqrt(-1j * w * mu * sig + w ** 2 * mu * eps)
    kr = k * r

    if fieldType == "e":

        front = 1 / (4.0 * np.pi * sig * r ** 3) * np.exp(-1j * k * r)
        mid = -(k ** 2) * r ** 2 + 3 * 1j * k * r + 3

        Fx = front * (
            mx * ((dx ** 2 / r ** 2) * mid + (k ** 2 * r ** 2 - 1j * k * r - 1.0))
            + my * (dy * dx / r ** 2) * mid
            + mz * (dz * dx / r ** 2) * mid
        )

        Fy = front * (
            mx * (dx * dy / r ** 2) * mid
            + my * ((dy ** 2 / r ** 2) * mid + (k ** 2 * r ** 2 - 1j * k * r - 1.0))
            + mz * (dz * dy / r ** 2) * mid
        )

        Fz = front * (
            mx * (dx * dz / r ** 2) * mid
            + my * (dy * dz / r ** 2) * mid
            + mz * ((dz ** 2 / r ** 2) * mid + (k ** 2 * r ** 2 - 1j * k * r - 1.0))
        )

    elif fieldType in ["h", "b"]:

        front = (1 + 1j * kr) / (4.0 * np.pi * r ** 2) * np.exp(-1j * k * r)

        Fx = front * (my * (dz / r) + mz * (-dy / r))

        Fy = front * (mx * (-dz / r) + mz * (dx / r))

        Fz = front * (mx * (dy / r) + my * (-dx / r))

        if fieldType == "b":
            Fx, Fy, Fz = mu * Fx, mu * Fy, mu * Fz

    return Fx, Fy, Fz
def dHdt_from_MagneticDipoleWholeSpace(XYZ,
                                       srcLoc,
                                       sig,
                                       t,
                                       current=1.0,
                                       length=1.0,
                                       orientation="X",
                                       kappa=1.0,
                                       epsr=1.0):
    """
        Computing the analytic timd derivative of magnetic fields (dH/dt) from an magnetic dipole in a wholespace
        - You have the option of computing H for multiple times at a single reciever location
          or a single time at multiple locations

        :param numpy.array XYZ: reciever locations at which to evaluate H
        :param numpy.array srcLoc: [x,y,z] triplet defining the location of the electric dipole source
        :param float sig: value specifying the conductivity (S/m) of the wholespace
        :param numpy.array t: array of times at which to measure
        :param float current: size of the injected current (A), default is 1.0 A
        :param float length: length of the dipole (m), default is 1.0 m
        :param str orientation: orientation of dipole: 'X', 'Y', or 'Z'
        :param float kappa: magnetic susceptiblity value (unitless), default is 0.
        :param float epsr: relative permitivitty value (unitless),  default is 1.0
        :rtype: numpy.array
        :return: dHx/dt, dHy/dt, dHz/dt: arrays containing all 3 components of H evaluated at the specified locations and times.
    """

    mu = mu_0 * (1 + kappa)
    # epsilon = epsilon_0 * epsr

    XYZ = utils.asArray_N_x_Dim(XYZ, 3)
    # Check
    if XYZ.shape[0] > 1 & t.shape[0] > 1:
        raise Exception(
            "I/O type error: For multiple field locations only a single time can be specified."
        )

    dx = XYZ[:, 0] - srcLoc[0]
    dy = XYZ[:, 1] - srcLoc[1]
    dz = XYZ[:, 2] - srcLoc[2]

    r = np.sqrt(dx**2.0 + dy**2.0 + dz**2.0)
    theta = np.sqrt((mu * sig) / (4 * t))

    front = -4 * (current * length) * theta**5 * np.exp(-((theta)**2) * (r)**2)
    front *= 1.0 / (np.pi**1.5 * mu * sig)
    mid = (theta)**2 * (r)**2
    extra = 1 - (theta)**2 * (r)**2

    if orientation.upper() == "X":
        Hx = front * (dx**2 / r**2) * mid + front * extra
        Hy = front * (dx * dy / r**2) * mid
        Hz = front * (dx * dz / r**2) * mid
        return Hx, Hy, Hz

    elif orientation.upper() == "Y":
        #  x--> y, y--> z, z-->x
        Hy = front * (dy**2 / r**2) * mid + front * extra
        Hz = front * (dy * dz / r**2) * mid
        Hx = front * (dy * dx / r**2) * mid
        return Hx, Hy, Hz

    elif orientation.upper() == "Z":
        # x --> z, y --> x, z --> y
        Hz = front * (dz**2 / r**2) * mid + front * extra
        Hx = front * (dz * dx / r**2) * mid
        Hy = front * (dz * dy / r**2) * mid
        return Hx, Hy, Hz
def E_from_MagneticDipoleWholeSpace(XYZ,
                                    srcLoc,
                                    sig,
                                    t,
                                    current=1.0,
                                    length=1.0,
                                    orientation="X",
                                    kappa=0.0,
                                    epsr=1.0):
    """
        Computing the analytic electric fields (E) from an magnetic dipole in a wholespace
        - You have the option of computing E for multiple times at a single reciever location
          or a single time at multiple locations

        :param numpy.array XYZ: reciever locations at which to evaluate E
        :param numpy.array srcLoc: [x,y,z] triplet defining the location of the electric dipole source
        :param float sig: value specifying the conductivity (S/m) of the wholespace
        :param numpy.array t: array of times at which to measure
        :param float current: size of the injected current (A), default is 1.0 A
        :param float length: length of the dipole (m), default is 1.0 m
        :param str orientation: orientation of dipole: 'X', 'Y', or 'Z'
        :param float kappa: magnetic susceptiblity value (unitless), default is 0.
        :param float epsr: relative permitivitty value (unitless),  default is 1.0
        :rtype: numpy.array
        :return: Ex, Ey, Ez: arrays containing all 3 components of E evaluated at the specified locations and times.
    """

    mu = mu_0 * (1 + kappa)
    # epsilon = epsilon_0 * epsr
    XYZ = utils.asArray_N_x_Dim(XYZ, 3)
    # Check
    if XYZ.shape[0] > 1 & t.shape[0] > 1:
        raise Exception(
            "I/O type error: For multiple field locations only a single time can be specified."
        )

    dx = XYZ[:, 0] - srcLoc[0]
    dy = XYZ[:, 1] - srcLoc[1]
    dz = XYZ[:, 2] - srcLoc[2]

    r = np.sqrt(dx**2.0 + dy**2.0 + dz**2.0)
    theta = np.sqrt((mu * sig) / (4 * t))

    front = 2.0 * (current * length) * theta**5 * np.exp(-((theta)**2) *
                                                         (r)**2)
    mid = 1.0 / (np.pi**1.5 * sig)

    if orientation.upper() == "X":
        Ey = front * mid * -dz
        Ez = front * mid * dy
        Ex = np.zeros_like(Ey)
        return Ex, Ey, Ez

    elif orientation.upper() == "Y":
        Ex = front * mid * dz
        Ez = front * mid * -dx
        Ey = np.zeros_like(Ex)
        return Ex, Ey, Ez

    elif orientation.upper() == "Z":
        Ex = front * mid * -dy
        Ey = front * mid * dx
        Ez = np.zeros_like(Ex)
        return Ex, Ey, Ez