def solve_2D_potentials(rho1, rho2, h, A, B): """ Here we solve the 2D DC problem for potentials (using SimPEG Mesg Class) """ sigma = 1.0 / rho2 * np.ones(mesh.nC) sigma[mesh.gridCC[:, 1] >= -h] = 1.0 / rho1 # since the model is 2D q = np.zeros(mesh.nC) a = utils.closestPoints(mesh, A[:2]) b = utils.closestPoints(mesh, B[:2]) q[a] = 1.0 / mesh.vol[a] q[b] = -1.0 / mesh.vol[b] # q = q * 1./mesh.vol A = ( mesh.cellGrad.T * utils.sdiag(1.0 / (mesh.dim * mesh.aveF2CC.T * (1.0 / sigma))) * mesh.cellGrad ) Ainv = Pardiso(A) V = Ainv * q return V
def solve_2D_potentials(rho1, rho2, h, A, B): """ Here we solve the 2D DC problem for potentials (using SimPEG Mesh Class) """ sigma = 1.0 / rho2 * np.ones(mesh.nC) sigma[mesh.gridCC[:, 1] >= -h] = 1.0 / rho1 # since the model is 2D q = np.zeros(mesh.nC) a = utils.closestPoints(mesh, A[:2]) q[a] = 1.0 / mesh.vol[a] if B is not None: b = utils.closestPoints(mesh, B[:2]) q[b] = -1.0 / mesh.vol[b] # Use a Neumann Boundary Condition (so pole source is reasonable) fxm, fxp, fym, fyp = mesh.faceBoundaryInd n_xm = fxm.sum() n_xp = fxp.sum() n_ym = fym.sum() n_yp = fyp.sum() xBC_xm = np.zeros(n_xm) # 0.5*a_xm xBC_xp = np.zeros(n_xp) # 0.5*a_xp/b_xp yBC_xm = np.ones(n_xm) # 0.5*(1.-b_xm) yBC_xp = np.ones(n_xp) # 0.5*(1.-1./b_xp) xBC_ym = np.zeros(n_ym) # 0.5*a_ym xBC_yp = np.zeros(n_yp) # 0.5*a_yp/b_yp yBC_ym = np.ones(n_ym) # 0.5*(1.-b_ym) yBC_yp = np.ones(n_yp) # 0.5*(1.-1./b_yp) sortindsfx = np.argsort(np.r_[np.arange(mesh.nFx)[fxm], np.arange(mesh.nFx)[fxp]]) sortindsfy = np.argsort(np.r_[np.arange(mesh.nFy)[fym], np.arange(mesh.nFy)[fyp]]) xBC_x = np.r_[xBC_xm, xBC_xp][sortindsfx] xBC_y = np.r_[xBC_ym, xBC_yp][sortindsfy] yBC_x = np.r_[yBC_xm, yBC_xp][sortindsfx] yBC_y = np.r_[yBC_ym, yBC_yp][sortindsfy] x_BC = np.r_[xBC_x, xBC_y] y_BC = np.r_[yBC_x, yBC_y] V = utils.sdiag(mesh.vol) Div = V * mesh.faceDiv P_BC, B = mesh.getBCProjWF_simple() M = B * mesh.aveCC2F Grad = Div.T - P_BC * utils.sdiag(y_BC) * M A = (Div * utils.sdiag(1.0 / (mesh.dim * mesh.aveF2CC.T * (1.0 / sigma))) * Grad) A[0, 0] = A[0, 0] + 1. # Because Neumann Ainv = Pardiso(A) V = Ainv * q return V
def get_Surface_Potentials(survey, src, field_obj): phi = field_obj[src, "phi"] CCLoc = mesh.gridCC zsurfaceLoc = np.max(CCLoc[:, 1]) surfaceInd = np.where(CCLoc[:, 1] == zsurfaceLoc) xSurface = CCLoc[surfaceInd, 0].T phiSurface = phi[surfaceInd, 0].T phiScale = 0.0 if survey == "Pole-Dipole" or survey == "Pole-Pole": refInd = utils.closestPoints(mesh, [xmax + 60.0, 0.0], gridLoc="CC") phiScale = phi[refInd] phiSurface = phiSurface - phiScale return xSurface, phiSurface, phiScale
def get_Surface_Potentials(mtrue, survey, src, field_obj): phi = field_obj["phi"] # CCLoc = mesh.gridCC XLoc = np.unique(mesh.gridCC[:, 0]) surfaceInd, zsurfaceLoc = get_Surface(mtrue, XLoc) phiSurface = phi[surfaceInd] phiScale = 0.0 if survey == "Pole-Dipole" or survey == "Pole-Pole": refInd = utils.closestPoints(mesh, [xmax + 60.0, 0.0], gridLoc="CC") # refPoint = CCLoc[refInd] # refSurfaceInd = np.where(xSurface == refPoint[0]) # phiScale = np.median(phiSurface) phiScale = phi[refInd] phiSurface = phiSurface - phiScale return XLoc, phiSurface, phiScale
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 simulate_dipole( self, component, target, inclination, declination, length, dx, moment, depth, profile, fixed_scale, show_halfwidth, ): self.component = component self.target = target self.inclination = inclination self.declination = declination self.length = length self.dx = dx self.moment = moment self.depth = depth self.profile = profile self.fixed_scale = fixed_scale self.show_halfwidth = show_halfwidth nT = 1e9 nx = ny = int(length / dx) hx = np.ones(nx) * dx hy = np.ones(ny) * dx self.mesh = TensorMesh((hx, hy), "CC") z = np.r_[1.0] orientation = self.id_to_cartesian(inclination, declination) if self.target == "Dipole": md = em.static.MagneticDipoleWholeSpace(location=np.r_[0, 0, -depth], orientation=orientation, moment=moment) xyz = utils.ndgrid(self.mesh.vectorCCx, self.mesh.vectorCCy, z) b_vec = md.magnetic_flux_density(xyz) elif self.target == "Monopole (+)": md = em.static.MagneticPoleWholeSpace(location=np.r_[0, 0, -depth], orientation=orientation, moment=moment) xyz = utils.ndgrid(self.mesh.vectorCCx, self.mesh.vectorCCy, z) b_vec = md.magnetic_flux_density(xyz) elif self.target == "Monopole (-)": md = em.static.MagneticPoleWholeSpace(location=np.r_[0, 0, -depth], orientation=orientation, moment=moment) xyz = utils.ndgrid(self.mesh.vectorCCx, self.mesh.vectorCCy, z) b_vec = -md.magnetic_flux_density(xyz) # Project to the direction of earth field if component == "Bt": rx_orientation = orientation.copy() elif component == "Bg": rx_orientation = orientation.copy() xyz_up = utils.ndgrid(self.mesh.vectorCCx, self.mesh.vectorCCy, z + 1.0) b_vec -= md.magnetic_flux_density(xyz_up) elif component == "Bx": rx_orientation = self.id_to_cartesian(0, 0) elif component == "By": rx_orientation = self.id_to_cartesian(0, 90) elif component == "Bz": rx_orientation = self.id_to_cartesian(90, 0) self.data = self.dot_product(b_vec, rx_orientation) * nT # Compute profile if (profile == "North") or (profile == "None"): self.xy_profile = np.c_[np.zeros(self.mesh.nCx), self.mesh.vectorCCx] elif profile == "East": self.xy_profile = np.c_[self.mesh.vectorCCx, np.zeros(self.mesh.nCx)] self.inds_profile = utils.closestPoints(self.mesh, self.xy_profile) self.data_profile = self.data[self.inds_profile]
def simulate_prism( self, component, inclination, declination, length, dx, B0, kappa, depth, profile, fixed_scale, show_halfwidth, prism_dx, prism_dy, prism_dz, prism_inclination, prism_declination, ): self.component = component self.inclination = -inclination # -ve accounts for LH modeling in SimPEG self.declination = declination self.length = length self.dx = dx self.B0 = B0 self.kappa = kappa self.depth = depth self.profile = profile self.fixed_scale = fixed_scale self.show_halfwidth = show_halfwidth # prism parameter self.prism = self.get_prism( prism_dx, prism_dy, prism_dz, 0, 0, -depth, prism_inclination, prism_declination, ) nx = ny = int(length / dx) hx = np.ones(nx) * dx hy = np.ones(ny) * dx self.mesh = TensorMesh((hx, hy), "CC") z = np.r_[1.0] B = np.r_[B0, -inclination, declination] # -ve accounts for LH modeling in SimPEG # Project to the direction of earth field if component == "Bt": uType = "tf" elif component == "Bx": uType = "bx" elif component == "By": uType = "by" elif component == "Bz": uType = "bz" xyz = utils.ndgrid(self.mesh.vectorCCx, self.mesh.vectorCCy, z) out = createMagSurvey(np.c_[xyz, np.ones(self.mesh.nC)], B) self.survey = out[0] self.dobs = out[1] self.sim = Simulation() self.sim.prism = self.prism self.sim.survey = self.survey self.sim.susc = kappa self.sim.uType, self.sim.mType = uType, "induced" self.data = self.sim.fields()[0] # Compute profile if (profile == "North") or (profile == "None"): self.xy_profile = np.c_[np.zeros(self.mesh.nCx), self.mesh.vectorCCx] elif profile == "East": self.xy_profile = np.c_[self.mesh.vectorCCx, np.zeros(self.mesh.nCx)] self.inds_profile = utils.closestPoints(self.mesh, self.xy_profile) self.data_profile = self.data[self.inds_profile]
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 setupProblem( mesh, muMod, sigmaMod, prbtype="ElectricField", invertMui=False, sigmaInInversion=False, freq=1.0, ): rxcomp = ["real", "imag"] loc = utils.ndgrid([mesh.vectorCCx, np.r_[0.0], mesh.vectorCCz]) if prbtype in ["ElectricField", "MagneticFluxDensity"]: rxfields_y = ["ElectricField", "CurrentDensity"] rxfields_xz = ["MagneticFluxDensity", "MagneticField"] elif prbtype in ["MagneticField", "CurrentDensity"]: rxfields_y = ["MagneticFluxDensity", "MagneticField"] rxfields_xz = ["ElectricField", "CurrentDensity"] receiver_list_edge = [ getattr(fdem.receivers, "Point{f}".format(f=f))(loc, component=comp, orientation=orient) for f in rxfields_y for comp in rxcomp for orient in ["y"] ] receiver_list_face = [ getattr(fdem.receivers, "Point{f}".format(f=f))(loc, component=comp, orientation=orient) for f in rxfields_xz for comp in rxcomp for orient in ["x", "z"] ] receiver_list = receiver_list_edge + receiver_list_face src_loc = np.r_[0.0, 0.0, 0.0] if prbtype in ["ElectricField", "MagneticFluxDensity"]: src = fdem.sources.MagDipole(receiver_list=receiver_list, location=src_loc, frequency=freq) elif prbtype in ["MagneticField", "CurrentDensity"]: ind = utils.closestPoints(mesh, src_loc, "Fz") + mesh.vnF[0] vec = np.zeros(mesh.nF) vec[ind] = 1.0 src = fdem.sources.RawVec_e(receiver_list=receiver_list, frequency=freq, s_e=vec) survey = fdem.Survey([src]) if sigmaInInversion: wires = maps.Wires(("mu", mesh.nC), ("sigma", mesh.nC)) muMap = maps.MuRelative(mesh) * wires.mu sigmaMap = maps.ExpMap(mesh) * wires.sigma if invertMui: muiMap = maps.ReciprocalMap(mesh) * muMap prob = getattr(fdem, "Simulation3D{}".format(prbtype))(mesh, muiMap=muiMap, sigmaMap=sigmaMap) # m0 = np.hstack([1./muMod, sigmaMod]) else: prob = getattr(fdem, "Simulation3D{}".format(prbtype))(mesh, muMap=muMap, sigmaMap=sigmaMap) m0 = np.hstack([muMod, sigmaMod]) else: muMap = maps.MuRelative(mesh) if invertMui: muiMap = maps.ReciprocalMap(mesh) * muMap prob = getattr(fdem, "Simulation3D{}".format(prbtype))(mesh, sigma=sigmaMod, muiMap=muiMap) # m0 = 1./muMod else: prob = getattr(fdem, "Simulation3D{}".format(prbtype))(mesh, sigma=sigmaMod, muMap=muMap) m0 = muMod prob.survey = survey return m0, prob, survey