def setUp(self): cs = 10.0 ncx, ncy, ncz = 30.0, 30.0, 30.0 npad = 10.0 hx = [(cs, npad, -1.5), (cs, ncx), (cs, npad, 1.5)] hy = [(cs, npad, -1.5), (cs, ncy), (cs, npad, 1.5)] hz = [(cs, npad, -1.5), (cs, ncz), (cs, npad, 1.5)] self.mesh = discretize.TensorMesh([hx, hy, hz], "CCC") mapping = maps.ExpMap(self.mesh) self.frequency = 1.0 self.prob_e = fdem.Simulation3DElectricField(self.mesh, sigmaMap=mapping) self.prob_b = fdem.Simulation3DMagneticFluxDensity(self.mesh, sigmaMap=mapping) self.prob_h = fdem.Simulation3DMagneticField(self.mesh, sigmaMap=mapping) self.prob_j = fdem.Simulation3DCurrentDensity(self.mesh, sigmaMap=mapping) loc = np.r_[0.0, 0.0, 0.0] self.location = utils.mkvc( self.mesh.gridCC[utils.closestPoints(self.mesh, loc, "CC"), :])
def setUpClass(self): print("\n------- Testing Primary Secondary Source HJ -> EB --------\n") # receivers self.rxlist = [] for rxtype in ["MagneticFluxDensity", "ElectricField"]: rx = getattr(fdem.Rx, "Point{}".format(rxtype)) for orientation in ["x", "y", "z"]: for comp in ["real", "imag"]: self.rxlist.append( rx(rx_locs, component=comp, orientation=orientation)) # primary self.primarySimulation = fdem.Simulation3DCurrentDensity( meshp, sigmaMap=primaryMapping) self.primarySimulation.solver = Solver s_e = np.zeros(meshp.nF) inds = meshp.nFx + utils.closestPoints(meshp, src_loc, gridLoc="Fz") s_e[inds] = 1.0 / csz primarySrc = fdem.Src.RawVec_e(self.rxlist, freq=freq, s_e=s_e / meshp.area) self.primarySurvey = fdem.Survey([primarySrc]) # Secondary Problem self.secondarySimulation = fdem.Simulation3DElectricField( meshs, sigmaMap=mapping) self.secondarySimulation.Solver = Solver self.secondarySrc = fdem.Src.PrimSecMappedSigma( self.rxlist, freq, self.primarySimulation, self.primarySurvey, primaryMap2Meshs, ) self.secondarySurvey = fdem.Survey([self.secondarySrc]) self.secondarySimulation.pair(self.secondarySurvey) # Full 3D problem to compare with self.simulation3D = fdem.Simulation3DElectricField(meshs, sigmaMap=mapping) self.simulation3D.Solver = Solver s_e3D = np.zeros(meshs.nE) inds = meshs.nEx + meshs.nEy + utils.closestPoints( meshs, src_loc, gridLoc="Ez") s_e3D[inds] = [1.0 / (len(inds))] * len(inds) self.simulation3D.model = model src3D = fdem.Src.RawVec_e(self.rxlist, freq=freq, s_e=s_e3D) self.survey3D = fdem.Survey([src3D]) self.simulation3D.pair(self.survey3D) # solve and store fields print(" solving primary - secondary") self.fields_primsec = self.secondarySimulation.fields(model) print(" ... done") self.fields_primsec = self.secondarySimulation.fields(model) print(" solving 3D") self.fields_3D = self.simulation3D.fields(model) print(" ... done") return None
def test_CylMeshEBDipoles(self, plotIt=plotIt): print("Testing CylMesh Electric and Magnetic Dipoles in a wholespace-" " Analytic: J-formulation") sigmaback = 1.0 mur = 2.0 freq = 1.0 skdpth = 500.0 / np.sqrt(sigmaback * freq) csx, ncx, npadx = 5, 50, 25 csz, ncz, npadz = 5, 50, 25 hx = utils.meshTensor([(csx, ncx), (csx, npadx, 1.3)]) hz = utils.meshTensor([(csz, npadz, -1.3), (csz, ncz), (csz, npadz, 1.3)]) # define the cylindrical mesh mesh = discretize.CylMesh([hx, 1, hz], [0.0, 0.0, -hz.sum() / 2]) if plotIt: mesh.plotGrid() # make sure mesh is big enough self.assertTrue(mesh.hz.sum() > skdpth * 2.0) self.assertTrue(mesh.hx.sum() > skdpth * 2.0) # set up source # test electric dipole src_loc = np.r_[0.0, 0.0, 0.0] s_ind = utils.closestPoints(mesh, src_loc, "Fz") + mesh.nFx de = np.zeros(mesh.nF, dtype=complex) de[s_ind] = 1.0 / csz de_p = [fdem.Src.RawVec_e([], freq, de / mesh.area)] dm_p = [fdem.Src.MagDipole([], freq, src_loc)] # Pair the problem and survey surveye = fdem.Survey(de_p) surveym = fdem.Survey(dm_p) prbe = fdem.Simulation3DMagneticField(mesh, survey=surveye, sigma=sigmaback, mu=mur * mu_0) prbm = fdem.Simulation3DElectricField(mesh, survey=surveym, sigma=sigmaback, mu=mur * mu_0) # solve fieldsBackE = prbe.fields() fieldsBackM = prbm.fields() rlim = [20.0, 500.0] # lookAtTx = de_p r = mesh.vectorCCx[np.argmin(np.abs(mesh.vectorCCx - rlim[0])):np. argmin(np.abs(mesh.vectorCCx - rlim[1]))] z = 100.0 # where we choose to measure XYZ = utils.ndgrid(r, np.r_[0.0], np.r_[z]) Pf = mesh.getInterpolationMat(XYZ, "CC") Zero = sp.csr_matrix(Pf.shape) Pfx, Pfz = sp.hstack([Pf, Zero]), sp.hstack([Zero, Pf]) jn = fieldsBackE[de_p, "j"] bn = fieldsBackM[dm_p, "b"] SigmaBack = sigmaback * np.ones((mesh.nC)) Rho = utils.sdiag(1.0 / SigmaBack) Rho = sp.block_diag([Rho, Rho]) en = Rho * mesh.aveF2CCV * jn bn = mesh.aveF2CCV * bn ex, ez = Pfx * en, Pfz * en bx, bz = Pfx * bn, Pfz * bn # get analytic solution exa, eya, eza = analytics.FDEM.ElectricDipoleWholeSpace(XYZ, src_loc, sigmaback, freq, "Z", mu_r=mur) exa = utils.mkvc(exa, 2) eya = utils.mkvc(eya, 2) eza = utils.mkvc(eza, 2) bxa, bya, bza = analytics.FDEM.MagneticDipoleWholeSpace(XYZ, src_loc, sigmaback, freq, "Z", mu_r=mur) bxa = utils.mkvc(bxa, 2) bya = utils.mkvc(bya, 2) bza = utils.mkvc(bza, 2) print( " comp, anayltic, numeric, num - ana, (num - ana)/ana" ) print( " ex:", np.linalg.norm(exa), np.linalg.norm(ex), np.linalg.norm(exa - ex), np.linalg.norm(exa - ex) / np.linalg.norm(exa), ) print( " ez:", np.linalg.norm(eza), np.linalg.norm(ez), np.linalg.norm(eza - ez), np.linalg.norm(eza - ez) / np.linalg.norm(eza), ) print( " bx:", np.linalg.norm(bxa), np.linalg.norm(bx), np.linalg.norm(bxa - bx), np.linalg.norm(bxa - bx) / np.linalg.norm(bxa), ) print( " bz:", np.linalg.norm(bza), np.linalg.norm(bz), np.linalg.norm(bza - bz), np.linalg.norm(bza - bz) / np.linalg.norm(bza), ) if plotIt is True: # Edipole plt.subplot(221) plt.plot(r, ex.real, "o", r, exa.real, linewidth=2) plt.grid(which="both") plt.title("Ex Real") plt.xlabel("r (m)") plt.subplot(222) plt.plot(r, ex.imag, "o", r, exa.imag, linewidth=2) plt.grid(which="both") plt.title("Ex Imag") plt.legend(["Num", "Ana"], bbox_to_anchor=(1.5, 0.5)) plt.xlabel("r (m)") plt.subplot(223) plt.plot(r, ez.real, "o", r, eza.real, linewidth=2) plt.grid(which="both") plt.title("Ez Real") plt.xlabel("r (m)") plt.subplot(224) plt.plot(r, ez.imag, "o", r, eza.imag, linewidth=2) plt.grid(which="both") plt.title("Ez Imag") plt.xlabel("r (m)") plt.tight_layout() # Bdipole plt.subplot(221) plt.plot(r, bx.real, "o", r, bxa.real, linewidth=2) plt.grid(which="both") plt.title("Bx Real") plt.xlabel("r (m)") plt.subplot(222) plt.plot(r, bx.imag, "o", r, bxa.imag, linewidth=2) plt.grid(which="both") plt.title("Bx Imag") plt.legend(["Num", "Ana"], bbox_to_anchor=(1.5, 0.5)) plt.xlabel("r (m)") plt.subplot(223) plt.plot(r, bz.real, "o", r, bza.real, linewidth=2) plt.grid(which="both") plt.title("Bz Real") plt.xlabel("r (m)") plt.subplot(224) plt.plot(r, bz.imag, "o", r, bza.imag, linewidth=2) plt.grid(which="both") plt.title("Bz Imag") plt.xlabel("r (m)") plt.tight_layout() self.assertTrue( np.linalg.norm(exa - ex) / np.linalg.norm(exa) < tol_EBdipole) self.assertTrue( np.linalg.norm(eza - ez) / np.linalg.norm(eza) < tol_EBdipole) self.assertTrue( np.linalg.norm(bxa - bx) / np.linalg.norm(bxa) < tol_EBdipole) self.assertTrue( np.linalg.norm(bza - bz) / np.linalg.norm(bza) < tol_EBdipole)
def getFDEMProblem(fdemType, comp, SrcList, freq, useMu=False, verbose=False): cs = 10.0 ncx, ncy, ncz = 0, 0, 0 npad = 8 hx = [(cs, npad, -1.3), (cs, ncx), (cs, npad, 1.3)] hy = [(cs, npad, -1.3), (cs, ncy), (cs, npad, 1.3)] hz = [(cs, npad, -1.3), (cs, ncz), (cs, npad, 1.3)] mesh = TensorMesh([hx, hy, hz], ["C", "C", "C"]) if useMu is True: mapping = [("sigma", maps.ExpMap(mesh)), ("mu", maps.IdentityMap(mesh))] else: mapping = maps.ExpMap(mesh) x = ( np.array([ np.linspace(-5.0 * cs, -2.0 * cs, 3), np.linspace(5.0 * cs, 2.0 * cs, 3) ]) + cs / 4.0 ) # don't sample right by the source, slightly off alignment from either staggered grid XYZ = utils.ndgrid(x, x, np.linspace(-2.0 * cs, 2.0 * cs, 5)) Rx0 = getattr(fdem.Rx, "Point" + comp[0]) if comp[-1] == "r": real_or_imag = "real" elif comp[-1] == "i": real_or_imag = "imag" rx0 = Rx0(XYZ, comp[1], real_or_imag) Src = [] for SrcType in SrcList: if SrcType == "MagDipole": Src.append( fdem.Src.MagDipole([rx0], frequency=freq, location=np.r_[0.0, 0.0, 0.0])) elif SrcType == "MagDipole_Bfield": Src.append( fdem.Src.MagDipole_Bfield([rx0], frequency=freq, location=np.r_[0.0, 0.0, 0.0])) elif SrcType == "CircularLoop": Src.append( fdem.Src.CircularLoop([rx0], frequency=freq, location=np.r_[0.0, 0.0, 0.0])) elif SrcType == "LineCurrent": Src.append( fdem.Src.LineCurrent( [rx0], frequency=freq, location=np.array([[0.0, 0.0, 0.0], [20.0, 0.0, 0.0]]), )) elif SrcType == "RawVec": if fdemType == "e" or fdemType == "b": S_m = np.zeros(mesh.nF) S_e = np.zeros(mesh.nE) S_m[utils.closestPoints(mesh, [0.0, 0.0, 0.0], "Fz") + np.sum(mesh.vnF[:1])] = 1e-3 S_e[utils.closestPoints(mesh, [0.0, 0.0, 0.0], "Ez") + np.sum(mesh.vnE[:1])] = 1e-3 Src.append( fdem.Src.RawVec([rx0], freq, S_m, mesh.getEdgeInnerProduct() * S_e)) elif fdemType == "h" or fdemType == "j": S_m = np.zeros(mesh.nE) S_e = np.zeros(mesh.nF) S_m[utils.closestPoints(mesh, [0.0, 0.0, 0.0], "Ez") + np.sum(mesh.vnE[:1])] = 1e-3 S_e[utils.closestPoints(mesh, [0.0, 0.0, 0.0], "Fz") + np.sum(mesh.vnF[:1])] = 1e-3 Src.append( fdem.Src.RawVec([rx0], freq, mesh.getEdgeInnerProduct() * S_m, S_e)) if verbose: print(" Fetching {0!s} problem".format((fdemType))) if fdemType == "e": survey = fdem.Survey(Src) prb = fdem.Simulation3DElectricField(mesh, sigmaMap=mapping) elif fdemType == "b": survey = fdem.Survey(Src) prb = fdem.Simulation3DMagneticFluxDensity(mesh, sigmaMap=mapping) elif fdemType == "j": survey = fdem.Survey(Src) prb = fdem.Simulation3DCurrentDensity(mesh, sigmaMap=mapping) elif fdemType == "h": survey = fdem.Survey(Src) prb = fdem.Simulation3DMagneticField(mesh, sigmaMap=mapping) else: raise NotImplementedError() prb.pair(survey) try: from pymatsolver import Pardiso prb.solver = Pardiso except ImportError: prb.solver = SolverLU # prb.solver_opts = dict(check_accuracy=True) return prb