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()
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()
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()
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
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
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
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
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
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)
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
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
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
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