def test_getInterpMatCartMesh_Faces(self): Mr = Mesh.TensorMesh([100, 100, 2], x0='CC0') Mc = Mesh.CylMesh([np.ones(10) / 5, 1, 10], x0='0C0', cartesianOrigin=[-0.2, -0.2, 0]) Pf = Mc.getInterpolationMatCartMesh(Mr, 'F') mf = np.ones(Mc.nF) frect = Pf * mf fxcc = Mr.aveFx2CC * Mr.r(frect, 'F', 'Fx') fycc = Mr.aveFy2CC * Mr.r(frect, 'F', 'Fy') fzcc = Mr.r(frect, 'F', 'Fz') indX = Utils.closestPoints(Mr, [0.45, -0.2, 0.5]) indY = Utils.closestPoints(Mr, [-0.2, 0.45, 0.5]) TOL = 1e-2 assert np.abs(float(fxcc[indX]) - 1) < TOL assert np.abs(float(fxcc[indY]) - 0) < TOL assert np.abs(float(fycc[indX]) - 0) < TOL assert np.abs(float(fycc[indY]) - 1) < TOL assert np.abs((fzcc - 1).sum()) < TOL mag = (fxcc**2 + fycc**2)**0.5 dist = ((Mr.gridCC[:, 0] + 0.2)**2 + (Mr.gridCC[:, 1] + 0.2)**2)**0.5 assert np.abs(mag[dist > 0.1].max() - 1) < TOL assert np.abs(mag[dist > 0.1].min() - 1) < TOL
def test_getInterpMatCartMesh_Edges2Faces(self): Mr = Mesh.TensorMesh([100,100,2], x0='CC0') Mc = Mesh.CylMesh([np.ones(10)/5,1,10],x0='0C0',cartesianOrigin=[-0.2,-0.2,0]) Pe2f = Mc.getInterpolationMatCartMesh(Mr, 'E', locTypeTo='F') me = np.ones(Mc.nE) frect = Pe2f * me excc = Mr.aveFx2CC*Mr.r(frect, 'F', 'Fx') eycc = Mr.aveFy2CC*Mr.r(frect, 'F', 'Fy') ezcc = Mr.r(frect, 'F', 'Fz') indX = Utils.closestPoints(Mr, [0.45, -0.2, 0.5]) indY = Utils.closestPoints(Mr, [-0.2, 0.45, 0.5]) TOL = 1e-2 assert np.abs(float(excc[indX]) - 0) < TOL assert np.abs(float(excc[indY]) + 1) < TOL assert np.abs(float(eycc[indX]) - 1) < TOL assert np.abs(float(eycc[indY]) - 0) < TOL assert np.abs(ezcc.sum()) < TOL mag = (excc**2 + eycc**2)**0.5 dist = ((Mr.gridCC[:,0] + 0.2)**2 + (Mr.gridCC[:,1] + 0.2)**2)**0.5 assert np.abs(mag[dist > 0.1].max() - 1) < TOL assert np.abs(mag[dist > 0.1].min() - 1) < TOL
def test_getInterpMatCartMesh_Faces2Edges(self): Mr = Mesh.TensorMesh([100, 100, 2], x0='CC0') Mc = Mesh.CylMesh([np.ones(10) / 5, 1, 10], x0='0C0', cartesianOrigin=[-0.2, -0.2, 0]) Pf2e = Mc.getInterpolationMatCartMesh(Mr, 'F', locTypeTo='E') mf = np.ones(Mc.nF) ecart = Pf2e * mf excc = Mr.aveEx2CC * Mr.r(ecart, 'E', 'Ex') eycc = Mr.aveEy2CC * Mr.r(ecart, 'E', 'Ey') ezcc = Mr.r(ecart, 'E', 'Ez') indX = Utils.closestPoints(Mr, [0.45, -0.2, 0.5]) indY = Utils.closestPoints(Mr, [-0.2, 0.45, 0.5]) TOL = 1e-2 assert np.abs(float(excc[indX]) - 1) < TOL assert np.abs(float(excc[indY]) - 0) < TOL assert np.abs(float(eycc[indX]) - 0) < TOL assert np.abs(float(eycc[indY]) - 1) < TOL assert np.abs((ezcc - 1).sum()) < TOL mag = (excc**2 + eycc**2)**0.5 dist = ((Mr.gridCC[:, 0] + 0.2)**2 + (Mr.gridCC[:, 1] + 0.2)**2)**0.5 assert np.abs(mag[dist > 0.1].max() - 1) < TOL assert np.abs(mag[dist > 0.1].min() - 1) < TOL
def test_getInterpMatCartMesh_Edges2Faces(self): Mr = Mesh.TensorMesh([100, 100, 2], x0='CC0') Mc = Mesh.CylMesh([np.ones(10) / 5, 1, 10], x0='0C0', cartesianOrigin=[-0.2, -0.2, 0]) Pe2f = Mc.getInterpolationMatCartMesh(Mr, 'E', locTypeTo='F') me = np.ones(Mc.nE) frect = Pe2f * me excc = Mr.aveFx2CC * Mr.r(frect, 'F', 'Fx') eycc = Mr.aveFy2CC * Mr.r(frect, 'F', 'Fy') ezcc = Mr.r(frect, 'F', 'Fz') indX = Utils.closestPoints(Mr, [0.45, -0.2, 0.5]) indY = Utils.closestPoints(Mr, [-0.2, 0.45, 0.5]) TOL = 1e-2 assert np.abs(float(excc[indX]) - 0) < TOL assert np.abs(float(excc[indY]) + 1) < TOL assert np.abs(float(eycc[indX]) - 1) < TOL assert np.abs(float(eycc[indY]) - 0) < TOL assert np.abs(ezcc.sum()) < TOL mag = (excc**2 + eycc**2)**0.5 dist = ((Mr.gridCC[:, 0] + 0.2)**2 + (Mr.gridCC[:, 1] + 0.2)**2)**0.5 assert np.abs(mag[dist > 0.1].max() - 1) < TOL assert np.abs(mag[dist > 0.1].min() - 1) < TOL
def test_getInterpMatCartMesh_Faces2Edges(self): Mr = Mesh.TensorMesh([100,100,2], x0='CC0') Mc = Mesh.CylMesh([np.ones(10)/5,1,10],x0='0C0',cartesianOrigin=[-0.2,-0.2,0]) Pf2e = Mc.getInterpolationMatCartMesh(Mr, 'F', locTypeTo='E') mf = np.ones(Mc.nF) ecart = Pf2e * mf excc = Mr.aveEx2CC*Mr.r(ecart, 'E', 'Ex') eycc = Mr.aveEy2CC*Mr.r(ecart, 'E', 'Ey') ezcc = Mr.r(ecart, 'E', 'Ez') indX = Utils.closestPoints(Mr, [0.45, -0.2, 0.5]) indY = Utils.closestPoints(Mr, [-0.2, 0.45, 0.5]) TOL = 1e-2 assert np.abs(float(excc[indX]) - 1) < TOL assert np.abs(float(excc[indY]) - 0) < TOL assert np.abs(float(eycc[indX]) - 0) < TOL assert np.abs(float(eycc[indY]) - 1) < TOL assert np.abs((ezcc - 1).sum()) < TOL mag = (excc**2 + eycc**2)**0.5 dist = ((Mr.gridCC[:,0] + 0.2)**2 + (Mr.gridCC[:,1] + 0.2)**2)**0.5 assert np.abs(mag[dist > 0.1].max() - 1) < TOL assert np.abs(mag[dist > 0.1].min() - 1) < TOL
def test_getInterpMatCartMesh_Faces(self): Mr = Mesh.TensorMesh([100,100,2], x0='CC0') Mc = Mesh.CylMesh([np.ones(10)/5,1,10],x0='0C0',cartesianOrigin=[-0.2,-0.2,0]) Pf = Mc.getInterpolationMatCartMesh(Mr, 'F') mf = np.ones(Mc.nF) frect = Pf * mf fxcc = Mr.aveFx2CC*Mr.r(frect, 'F', 'Fx') fycc = Mr.aveFy2CC*Mr.r(frect, 'F', 'Fy') fzcc = Mr.r(frect, 'F', 'Fz') indX = Utils.closestPoints(Mr, [0.45, -0.2, 0.5]) indY = Utils.closestPoints(Mr, [-0.2, 0.45, 0.5]) TOL = 1e-2 assert np.abs(float(fxcc[indX]) - 1) < TOL assert np.abs(float(fxcc[indY]) - 0) < TOL assert np.abs(float(fycc[indX]) - 0) < TOL assert np.abs(float(fycc[indY]) - 1) < TOL assert np.abs((fzcc - 1).sum()) < TOL mag = (fxcc**2 + fycc**2)**0.5 dist = ((Mr.gridCC[:,0] + 0.2)**2 + (Mr.gridCC[:,1] + 0.2)**2)**0.5 assert np.abs(mag[dist > 0.1].max() - 1) < TOL assert np.abs(mag[dist > 0.1].min() - 1) < TOL
def setUpClass(self): print('\n------- Testing Primary Secondary Source HJ -> EB --------\n') # receivers self.rxlist = [] for rxtype in ['b', 'e']: 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.primaryProblem = FDEM.Problem3D_j(meshp, sigmaMap=primaryMapping) self.primaryProblem.solver = Solver s_e = np.zeros(meshp.nF) inds = meshp.nFx + Utils.closestPoints(meshp, src_loc, gridLoc='Fz') s_e[inds] = 1./csz primarySrc = FDEM.Src.RawVec_e( self.rxlist, freq=freq, s_e=s_e/meshp.area ) self.primarySurvey = FDEM.Survey([primarySrc]) # Secondary Problem self.secondaryProblem = FDEM.Problem3D_e(meshs, sigmaMap=mapping) self.secondaryProblem.Solver = Solver self.secondarySrc = FDEM.Src.PrimSecMappedSigma( self.rxlist, freq, self.primaryProblem, self.primarySurvey, primaryMap2Meshs ) self.secondarySurvey = FDEM.Survey([self.secondarySrc]) self.secondaryProblem.pair(self.secondarySurvey) # Full 3D problem to compare with self.problem3D = FDEM.Problem3D_e(meshs, sigmaMap=mapping) self.problem3D.Solver = Solver s_e3D = np.zeros(meshs.nE) inds = (meshs.nEx + meshs.nEy + Utils.closestPoints(meshs, src_loc, gridLoc='Ez')) s_e3D[inds] = [1./(len(inds))] * len(inds) self.problem3D.model = model src3D = FDEM.Src.RawVec_e(self.rxlist, freq=freq, s_e=s_e3D) self.survey3D = FDEM.Survey([src3D]) self.problem3D.pair(self.survey3D) # solve and store fields print(' solving primary - secondary') self.fields_primsec = self.secondaryProblem.fields(model) print(' ... done') self.fields_primsec = self.secondaryProblem.fields(model) print(' solving 3D') self.fields_3D = self.problem3D.fields(model) print(' ... done') return None
def setUp(self): mesh = Mesh.TensorMesh([20, 20, 20], "CCN") sigma = np.ones(mesh.nC) * 1. / 100. actind = mesh.gridCC[:, 2] < -0.2 # actMap = Maps.InjectActiveCells(mesh, actind, 0.) xyzM = Utils.ndgrid( np.ones_like(mesh.vectorCCx[:-1]) * -0.4, np.ones_like(mesh.vectorCCy) * -0.4, np.r_[-0.3]) xyzN = Utils.ndgrid(mesh.vectorCCx[1:], mesh.vectorCCy, np.r_[-0.3]) problem = SP.Problem_CC(mesh, sigma=sigma, qMap=Maps.IdentityMap(mesh), Solver=PardisoSolver) rx = SP.Rx.Dipole(xyzN, xyzM) src = SP.Src.StreamingCurrents([rx], L=np.ones(mesh.nC), mesh=mesh, modelType="CurrentSource") survey = SP.Survey([src]) survey.pair(problem) q = np.zeros(mesh.nC) inda = Utils.closestPoints(mesh, np.r_[-0.5, 0., -0.8]) indb = Utils.closestPoints(mesh, np.r_[0.5, 0., -0.8]) q[inda] = 1. q[indb] = -1. mSynth = q.copy() survey.makeSyntheticData(mSynth) # Now set up the problem to do some minimization dmis = DataMisfit.l2_DataMisfit(survey) reg = Regularization.Simple(mesh) opt = Optimization.InexactGaussNewton(maxIterLS=20, maxIter=10, tolF=1e-6, tolX=1e-6, tolG=1e-6, maxIterCG=6) invProb = InvProblem.BaseInvProblem(dmis, reg, opt, beta=1e-2) inv = Inversion.BaseInversion(invProb) self.inv = inv self.reg = reg self.p = problem self.mesh = mesh self.m0 = mSynth self.survey = survey self.dmis = dmis
def drapeTopotoLoc(mesh, pts, actind=None, option="top", topo=None): """ Drape location right below (cell center) the topography """ if mesh.dim == 2: if pts.ndim > 1: raise Exception("pts should be 1d array") elif mesh.dim == 3: if pts.shape[1] == 3: raise Exception("shape of pts should be (x,3)") else: raise NotImplementedError() if actind is None: actind = Utils.surface2ind_topo(mesh, topo) if mesh._meshType == "TENSOR": meshtemp, topoCC = gettopoCC(mesh, actind, option=option) inds = Utils.closestPoints(meshtemp, pts) elif mesh._meshType == "TREE": if mesh.dim == 3: uniqXYlocs, topoCC = gettopoCC(mesh, actind, option=option) inds = closestPointsGrid(uniqXYlocs, pts) else: raise NotImplementedError() else: raise NotImplementedError() out = np.c_[pts, topoCC[inds]] return out
def setUp(self): mesh = Mesh.TensorMesh([20, 20, 20], "CCN") sigma = np.ones(mesh.nC)*1./100. actind = mesh.gridCC[:, 2] < -0.2 # actMap = Maps.InjectActiveCells(mesh, actind, 0.) xyzM = Utils.ndgrid(np.ones_like(mesh.vectorCCx[:-1])*-0.4, np.ones_like(mesh.vectorCCy)*-0.4, np.r_[-0.3]) xyzN = Utils.ndgrid(mesh.vectorCCx[1:], mesh.vectorCCy, np.r_[-0.3]) problem = SP.Problem_CC(mesh, sigma=sigma, qMap=Maps.IdentityMap(mesh), Solver=PardisoSolver) rx = SP.Rx.Dipole(xyzN, xyzM) src = SP.Src.StreamingCurrents([rx], L=np.ones(mesh.nC), mesh=mesh, modelType="CurrentSource") survey = SP.Survey([src]) survey.pair(problem) q = np.zeros(mesh.nC) inda = Utils.closestPoints(mesh, np.r_[-0.5, 0., -0.8]) indb = Utils.closestPoints(mesh, np.r_[0.5, 0., -0.8]) q[inda] = 1. q[indb] = -1. mSynth = q.copy() survey.makeSyntheticData(mSynth) # Now set up the problem to do some minimization dmis = DataMisfit.l2_DataMisfit(survey) reg = Regularization.Simple(mesh) opt = Optimization.InexactGaussNewton( maxIterLS=20, maxIter=10, tolF=1e-6, tolX=1e-6, tolG=1e-6, maxIterCG=6 ) invProb = InvProblem.BaseInvProblem(dmis, reg, opt, beta=1e-2) inv = Inversion.BaseInversion(invProb) self.inv = inv self.reg = reg self.p = problem self.mesh = mesh self.m0 = mSynth self.survey = survey self.dmis = dmis
def solve_2D_potentials(rho1, rho2, h, A, B): """ Here we solve the 2D DC problem for potentials (using SimPEG Mesg Class) """ sigma = 1. / rho2 * np.ones(mesh.nC) sigma[mesh.gridCC[:, 1] >= -h] = 1. / 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. / mesh.vol[a] q[b] = -1. / mesh.vol[b] # q = q * 1./mesh.vol A = (mesh.cellGrad.T * Utils.sdiag(1. / (mesh.dim * mesh.aveF2CC.T * (1. / sigma))) * mesh.cellGrad) Ainv = SolverLU(A) V = Ainv * q return V
def drapeTopotoLoc(mesh, topo, pts): """ Drape """ if mesh.dim ==2: if pts.ndim > 1: raise Exception("pts should be 1d array") elif mesh.dim ==3: if pts.shape[1] == 3: raise Exception("shape of pts should be (x,3)") else: raise NotImplementedError() airind = Utils.surface2ind_topo(mesh, topo) meshtemp, topoCC = gettopoCC(mesh, ~airind) inds = Utils.closestPoints(meshtemp, pts) return np.c_[pts, topoCC[inds]]
def drapeTopotoLoc(mesh, topo, pts): """ Drape """ if mesh.dim == 2: if pts.ndim > 1: raise Exception("pts should be 1d array") elif mesh.dim == 3: if pts.shape[1] == 3: raise Exception("shape of pts should be (x,3)") else: raise NotImplementedError() airind = Utils.surface2ind_topo(mesh, topo) meshtemp, topoCC = gettopoCC(mesh, ~airind) inds = Utils.closestPoints(meshtemp, pts) return np.c_[pts, topoCC[inds]]
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 get_Surface_Potentials(survey, src, field_obj): phi = field_obj['phi'] CCLoc = mesh.gridCC zsurfaceLoc = np.max(CCLoc[:, 1]) surfaceInd = np.where(CCLoc[:, 1] == zsurfaceLoc) xSurface = CCLoc[surfaceInd, 0].T phiSurface = phi[surfaceInd] phiScale = 0. if (survey == "Pole-Dipole" or survey == "Pole-Pole"): refInd = Utils.closestPoints(mesh, [xmax + 60., 0.], gridLoc='CC') # refPoint = CCLoc[refInd] # refSurfaceInd = np.where(xSurface == refPoint[0]) # phiScale = np.median(phiSurface) phiScale = phi[refInd] phiSurface = phiSurface - phiScale return xSurface, phiSurface, phiScale
def setUp(self): cs = 10. ncx, ncy, ncz = 30., 30., 30. npad = 10. 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 = Mesh.TensorMesh([hx, hy, hz], 'CCC') mapping = Maps.ExpMap(self.mesh) self.freq = 1. self.prob_e = FDEM.Problem3D_e(self.mesh, mapping=mapping) self.prob_b = FDEM.Problem3D_b(self.mesh, mapping=mapping) self.prob_h = FDEM.Problem3D_h(self.mesh, mapping=mapping) self.prob_j = FDEM.Problem3D_j(self.mesh, mapping=mapping) loc = np.r_[0., 0., 0.] self.loc = Utils.mkvc( self.mesh.gridCC[Utils.closestPoints(self.mesh, loc, 'CC'), :])
def setUp(self): cs = 10. ncx, ncy, ncz = 30., 30., 30. npad = 10. 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 = Mesh.TensorMesh([hx, hy, hz], 'CCC') mapping = Maps.ExpMap(self.mesh) self.freq = 1. self.prob_e = FDEM.Problem3D_e(self.mesh, sigmaMap=mapping) self.prob_b = FDEM.Problem3D_b(self.mesh, sigmaMap=mapping) self.prob_h = FDEM.Problem3D_h(self.mesh, sigmaMap=mapping) self.prob_j = FDEM.Problem3D_j(self.mesh, sigmaMap=mapping) loc = np.r_[0., 0., 0.] self.loc = Utils.mkvc( self.mesh.gridCC[Utils.closestPoints(self.mesh, loc, 'CC'), :] )
def getFDEMProblem(fdemType, comp, SrcList, freq, useMu=False, verbose=False): cs = 10. 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 = 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. * cs, -2. * cs, 3), np.linspace(5. * cs, 2. * cs, 3)] ) + cs / 4. #don't sample right by the source, slightly off alignment from either staggered grid XYZ = Utils.ndgrid(x, x, np.linspace(-2. * cs, 2. * cs, 5)) Rx0 = getattr(EM.FDEM.Rx, 'Point_' + comp[0]) if comp[2] == 'r': real_or_imag = 'real' elif comp[2] == 'i': real_or_imag = 'imag' rx0 = Rx0(XYZ, comp[1], 'imag') Src = [] for SrcType in SrcList: if SrcType is 'MagDipole': Src.append( EM.FDEM.Src.MagDipole([rx0], freq=freq, loc=np.r_[0., 0., 0.])) elif SrcType is 'MagDipole_Bfield': Src.append( EM.FDEM.Src.MagDipole_Bfield([rx0], freq=freq, loc=np.r_[0., 0., 0.])) elif SrcType is 'CircularLoop': Src.append( EM.FDEM.Src.CircularLoop([rx0], freq=freq, loc=np.r_[0., 0., 0.])) elif SrcType is 'RawVec': if fdemType is 'e' or fdemType is 'b': S_m = np.zeros(mesh.nF) S_e = np.zeros(mesh.nE) S_m[Utils.closestPoints(mesh, [0., 0., 0.], 'Fz') + np.sum(mesh.vnF[:1])] = 1e-3 S_e[Utils.closestPoints(mesh, [0., 0., 0.], 'Ez') + np.sum(mesh.vnE[:1])] = 1e-3 Src.append( EM.FDEM.Src.RawVec([rx0], freq, S_m, mesh.getEdgeInnerProduct() * S_e)) elif fdemType is 'h' or fdemType is 'j': S_m = np.zeros(mesh.nE) S_e = np.zeros(mesh.nF) S_m[Utils.closestPoints(mesh, [0., 0., 0.], 'Ez') + np.sum(mesh.vnE[:1])] = 1e-3 S_e[Utils.closestPoints(mesh, [0., 0., 0.], 'Fz') + np.sum(mesh.vnF[:1])] = 1e-3 Src.append( EM.FDEM.Src.RawVec([rx0], freq, mesh.getEdgeInnerProduct() * S_m, S_e)) if verbose: print(' Fetching {0!s} problem'.format((fdemType))) if fdemType == 'e': survey = EM.FDEM.Survey(Src) prb = EM.FDEM.Problem3D_e(mesh, mapping=mapping) elif fdemType == 'b': survey = EM.FDEM.Survey(Src) prb = EM.FDEM.Problem3D_b(mesh, mapping=mapping) elif fdemType == 'j': survey = EM.FDEM.Survey(Src) prb = EM.FDEM.Problem3D_j(mesh, mapping=mapping) elif fdemType == 'h': survey = EM.FDEM.Survey(Src) prb = EM.FDEM.Problem3D_h(mesh, mapping=mapping) else: raise NotImplementedError() prb.pair(survey) try: from pymatsolver import PardisoSolver prb.Solver = PardisoSolver except ImportError: prb.Solver = SolverLU # prb.solverOpts = dict(check_accuracy=True) return prb
ndata = rxLoc.shape[0] #%% Subdivide the forward data locations into tiles PF.Magnetics.plot_obs_2D(rxLoc) xmin = np.min(rxLoc[:, 0]) xmax = np.max(rxLoc[:, 0]) ymin = np.min(rxLoc[:, 1]) ymax = np.max(rxLoc[:, 1]) var = np.c_[np.r_[xmin, ymin], np.r_[xmax, ymin], np.r_[xmin, ymax]] var = np.c_[var.T, np.ones(3) * mesh.vectorCCz[-1]] # First put a tile on both corners of the mesh indx = Utils.closestPoints(mesh, var) endl = np.c_[mesh.gridCC[indx, 0], mesh.gridCC[indx, 1]] dx = np.median(mesh.hx) # Add intermediate tiles until the min_Olap is respected # First in the x-direction lx = np.floor((max_mcell / mesh.nCz)**0.5) ntile = 2 Olap = -1 while Olap < min_Olap: ntile += 1 # Set location of SW corners
def run(loc=None, sig=None, radi=None, param=None, stype='dpdp', plotIt=True): """ DC Forward Simulation ===================== Forward model conductive spheres in a half-space and plot a pseudo-section Created by @fourndo on Mon Feb 01 19:28:06 2016 """ assert stype in ['pdp', 'dpdp'], "Source type (stype) must be pdp or dpdp (pole dipole or dipole dipole)" if loc is None: loc = np.c_[[-50.,0.,-50.],[50.,0.,-50.]] if sig is None: sig = np.r_[1e-2,1e-1,1e-3] if radi is None: radi = np.r_[25.,25.] if param is None: param = np.r_[30.,30.,5] # First we need to create a mesh and a model. # This is our mesh dx = 5. hxind = [(dx,15,-1.3), (dx, 75), (dx,15,1.3)] hyind = [(dx,15,-1.3), (dx, 10), (dx,15,1.3)] hzind = [(dx,15,-1.3),(dx, 15)] mesh = Mesh.TensorMesh([hxind, hyind, hzind], 'CCN') # Set background conductivity model = np.ones(mesh.nC) * sig[0] # First anomaly ind = Utils.ModelBuilder.getIndicesSphere(loc[:,0],radi[0],mesh.gridCC) model[ind] = sig[1] # Second anomaly ind = Utils.ModelBuilder.getIndicesSphere(loc[:,1],radi[1],mesh.gridCC) model[ind] = sig[2] # Get index of the center indy = int(mesh.nCy/2) # Plot the model for reference # Define core mesh extent xlim = 200 zlim = 125 # Specify the survey type: "pdp" | "dpdp" # Then specify the end points of the survey. Let's keep it simple for now and survey above the anomalies, top of the mesh ends = [(-175,0),(175,0)] ends = np.c_[np.asarray(ends),np.ones(2).T*mesh.vectorNz[-1]] # Snap the endpoints to the grid. Easier to create 2D section. indx = Utils.closestPoints(mesh, ends ) locs = np.c_[mesh.gridCC[indx,0],mesh.gridCC[indx,1],np.ones(2).T*mesh.vectorNz[-1]] # We will handle the geometry of the survey for you and create all the combination of tx-rx along line # [Tx, Rx] = DC.gen_DCIPsurvey(locs, mesh, stype, param[0], param[1], param[2]) survey, Tx, Rx = DC.gen_DCIPsurvey(locs, mesh, stype, param[0], param[1], param[2]) # Define some global geometry dl_len = np.sqrt( np.sum((locs[0,:] - locs[1,:])**2) ) dl_x = ( Tx[-1][0,1] - Tx[0][0,0] ) / dl_len dl_y = ( Tx[-1][1,1] - Tx[0][1,0] ) / dl_len azm = np.arctan(dl_y/dl_x) #Set boundary conditions mesh.setCellGradBC('neumann') # Define the differential operators needed for the DC problem Div = mesh.faceDiv Grad = mesh.cellGrad Msig = Utils.sdiag(1./(mesh.aveF2CC.T*(1./model))) A = Div*Msig*Grad # Change one corner to deal with nullspace A[0,0] = 1 A = sp.csc_matrix(A) # We will solve the system iteratively, so a pre-conditioner is helpful # This is simply a Jacobi preconditioner (inverse of the main diagonal) dA = A.diagonal() P = sp.spdiags(1/dA,0,A.shape[0],A.shape[0]) # Now we can solve the system for all the transmitters # We want to store the data data = [] # There is probably a more elegant way to do this, but we can just for-loop through the transmitters for ii in range(len(Tx)): start_time = time.time() # Let's time the calculations #print("Transmitter %i / %i\r" % (ii+1,len(Tx))) # Select dipole locations for receiver rxloc_M = np.asarray(Rx[ii][:,0:3]) rxloc_N = np.asarray(Rx[ii][:,3:]) # For usual cases "dpdp" or "gradient" if stype == 'pdp': # Create an "inifinity" pole tx = np.squeeze(Tx[ii][:,0:1]) tinf = tx + np.array([dl_x,dl_y,0])*dl_len*2 inds = Utils.closestPoints(mesh, np.c_[tx,tinf].T) RHS = mesh.getInterpolationMat(np.asarray(Tx[ii]).T, 'CC').T*( [-1] / mesh.vol[inds] ) else: inds = Utils.closestPoints(mesh, np.asarray(Tx[ii]).T ) RHS = mesh.getInterpolationMat(np.asarray(Tx[ii]).T, 'CC').T*( [-1,1] / mesh.vol[inds] ) # Iterative Solve Ainvb = sp.linalg.bicgstab(P*A,P*RHS, tol=1e-5) # We now have the potential everywhere phi = Utils.mkvc(Ainvb[0]) # Solve for phi on pole locations P1 = mesh.getInterpolationMat(rxloc_M, 'CC') P2 = mesh.getInterpolationMat(rxloc_N, 'CC') # Compute the potential difference dtemp = (P1*phi - P2*phi)*np.pi data.append( dtemp ) print '\rTransmitter {0} of {1} -> Time:{2} sec'.format(ii,len(Tx),time.time()- start_time), print 'Transmitter {0} of {1}'.format(ii,len(Tx)) print 'Forward completed' # Let's just convert the 3D format into 2D (distance along line) and plot # [Tx2d, Rx2d] = DC.convertObs_DC3D_to_2D(survey, np.ones(survey.nSrc)) survey2D = DC.convertObs_DC3D_to_2D(survey, np.ones(survey.nSrc)) survey2D.dobs =np.hstack(data) # Here is an example for the first tx-rx array if plotIt: import matplotlib.pyplot as plt fig = plt.figure() ax = plt.subplot(2,1,1, aspect='equal') mesh.plotSlice(np.log10(model), ax =ax, normal = 'Y', ind = indy,grid=True) ax.set_title('E-W section at '+str(mesh.vectorCCy[indy])+' m') plt.gca().set_aspect('equal', adjustable='box') plt.scatter(Tx[0][0,:],Tx[0][2,:],s=40,c='g', marker='v') plt.scatter(Rx[0][:,0::3],Rx[0][:,2::3],s=40,c='y') plt.xlim([-xlim,xlim]) plt.ylim([-zlim,mesh.vectorNz[-1]+dx]) ax = plt.subplot(2,1,2, aspect='equal') # Plot the location of the spheres for reference circle1=plt.Circle((loc[0,0]-Tx[0][0,0],loc[2,0]),radi[0],color='w',fill=False, lw=3) circle2=plt.Circle((loc[0,1]-Tx[0][0,0],loc[2,1]),radi[1],color='k',fill=False, lw=3) ax.add_artist(circle1) ax.add_artist(circle2) # Add the speudo section DC.plot_pseudoSection(survey2D,ax,stype) # plt.scatter(Tx2d[0][:],Tx[0][2,:],s=40,c='g', marker='v') # plt.scatter(Rx2d[0][:],Rx[0][:,2::3],s=40,c='y') # plt.plot(np.r_[Tx2d[0][0],Rx2d[-1][-1,-1]],np.ones(2)*mesh.vectorNz[-1], color='k') plt.ylim([-zlim,mesh.vectorNz[-1]+dx]) plt.show() return fig, ax
# Autogenerated at 2018-01-31T11:25:30.354645 on version 0.0.4 import casingSimulations import numpy as np # Set up the simulation sim = casingSimulations.run.SimulationTDEM( modelParameters='ModelParameters.json', meshGenerator='MeshParameters.json', src='Source.json', fields_filename='fields.npy') # run the simulation fields = sim.run() # where we are going to evaluate the fields from SimPEG import Utils x_locs = np.r_[5, 11, 51, 101, 151, 201, 251, 301] y_locs = np.r_[np.pi / 2.] z_locs = np.r_[sim.src.src_a[2]] points = Utils.closestPoints(sim.meshGenerator.mesh, Utils.ndgrid(x_locs, y_locs, z_locs), 'Fx') j_compare = fields[:, 'j', :] e_compare = sim.prob.MfI * sim.prob.MfRho * j_compare jx_compare = j_compare[points, :] ex_compare = e_compare[points, :] np.save('jx_compare.npy', jx_compare) np.save('ex_compare.npy', ex_compare)
if stype == 'dipole-dipole': axs.scatter(tx[0, 0], tx[0, 2], c='r', s=75, marker='v') axs.scatter(tx[0, 1], tx[1, 2], c='b', s=75, marker='v') else: axs.scatter(tx[0], tx[2], c='r', s=75, marker='v') #cfm1=get_current_fig_manager().window #%% # Add z coordinate to all survey... assume flat nz = mesh.vectorNz var = np.c_[np.asarray(srvy_end), np.ones(2).T * nz[-1]] # Snap the endpoints to the grid. Easier to create 2D section. indx = Utils.closestPoints(mesh, var) endl = np.c_[mesh.gridCC[indx, 0], mesh.gridCC[indx, 1], np.ones(2).T * nz[-1]] survey = StaticUtils.gen_DCIPsurvey(endl, mesh, stype, a, b, n) #survey = DC.SurveyDC.Survey(srcList) Tx = StaticUtils.getSrc_locs(survey) dl_len = np.sqrt(np.sum((endl[0, :] - endl[1, :])**2)) dl_x = (Tx[-1][0] - Tx[0][0]) / dl_len dl_y = (Tx[-1][1] - Tx[0][1]) / dl_len azm = np.arctan(dl_y / dl_x) # Plot stations along line if stype == 'gradient': Rx = survey.srcList[0].rxList[0].locs
def setupProblem( mesh, muMod, sigmaMod, prbtype='e', invertMui=False, sigmaInInversion=False, freq=1. ): rxcomp = ['real', 'imag'] loc = Utils.ndgrid( [mesh.vectorCCx, np.r_[0.], mesh.vectorCCz] ) if prbtype in ['e', 'b']: rxfields_y = ['e', 'j'] rxfields_xz = ['b', 'h'] elif prbtype in ['h', 'j']: rxfields_y = ['b', 'h'] rxfields_xz = ['e', 'j'] rxList_edge = [ getattr(FDEM.Rx, 'Point_{f}'.format(f=f))( loc, component=comp, orientation=orient ) for f in rxfields_y for comp in rxcomp for orient in ['y'] ] rxList_face = [ getattr(FDEM.Rx, 'Point_{f}'.format(f=f))( loc, component=comp, orientation=orient ) for f in rxfields_xz for comp in rxcomp for orient in ['x', 'z'] ] rxList = rxList_edge + rxList_face src_loc = np.r_[0., 0., 0.] if prbtype in ['e', 'b']: src = FDEM.Src.MagDipole( rxList=rxList, loc=src_loc, freq=freq ) elif prbtype in ['h', 'j']: ind = Utils.closestPoints(mesh, src_loc, 'Fz') + mesh.vnF[0] vec = np.zeros(mesh.nF) vec[ind] = 1. src = FDEM.Src.RawVec_e(rxList=rxList, freq=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, 'Problem3D_{}'.format(prbtype))( mesh, muiMap=muiMap, sigmaMap=sigmaMap ) # m0 = np.hstack([1./muMod, sigmaMod]) else: prob = getattr(FDEM, 'Problem3D_{}'.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, 'Problem3D_{}'.format(prbtype))( mesh, sigma=sigmaMod, muiMap=muiMap ) # m0 = 1./muMod else: prob = getattr(FDEM, 'Problem3D_{}'.format(prbtype))( mesh, sigma=sigmaMod, muMap=muMap ) m0 = muMod prob.pair(survey) return m0, prob, survey
def getFDEMProblem(fdemType, comp, SrcList, freq, useMu=False, verbose=False): cs = 10. 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 = 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.*cs,-2.*cs,3),np.linspace(5.*cs,2.*cs,3)]) + cs/4. #don't sample right by the source, slightly off alignment from either staggered grid XYZ = Utils.ndgrid(x,x,np.linspace(-2.*cs,2.*cs,5)) Rx0 = getattr(EM.FDEM.Rx, 'Point_' + comp[0]) if comp[2] == 'r': real_or_imag = 'real' elif comp[2] == 'i': real_or_imag = 'imag' rx0 = Rx0(XYZ, comp[1], 'imag') Src = [] for SrcType in SrcList: if SrcType is 'MagDipole': Src.append(EM.FDEM.Src.MagDipole([rx0], freq=freq, loc=np.r_[0.,0.,0.])) elif SrcType is 'MagDipole_Bfield': Src.append(EM.FDEM.Src.MagDipole_Bfield([rx0], freq=freq, loc=np.r_[0.,0.,0.])) elif SrcType is 'CircularLoop': Src.append(EM.FDEM.Src.CircularLoop([rx0], freq=freq, loc=np.r_[0.,0.,0.])) elif SrcType is 'RawVec': if fdemType is 'e' or fdemType is 'b': S_m = np.zeros(mesh.nF) S_e = np.zeros(mesh.nE) S_m[Utils.closestPoints(mesh,[0.,0.,0.],'Fz') + np.sum(mesh.vnF[:1])] = 1e-3 S_e[Utils.closestPoints(mesh,[0.,0.,0.],'Ez') + np.sum(mesh.vnE[:1])] = 1e-3 Src.append(EM.FDEM.Src.RawVec([rx0], freq, S_m, mesh.getEdgeInnerProduct()*S_e)) elif fdemType is 'h' or fdemType is 'j': S_m = np.zeros(mesh.nE) S_e = np.zeros(mesh.nF) S_m[Utils.closestPoints(mesh,[0.,0.,0.],'Ez') + np.sum(mesh.vnE[:1])] = 1e-3 S_e[Utils.closestPoints(mesh,[0.,0.,0.],'Fz') + np.sum(mesh.vnF[:1])] = 1e-3 Src.append(EM.FDEM.Src.RawVec([rx0], freq, mesh.getEdgeInnerProduct()*S_m, S_e)) if verbose: print(' Fetching {0!s} problem'.format((fdemType))) if fdemType == 'e': survey = EM.FDEM.Survey(Src) prb = EM.FDEM.Problem3D_e(mesh, mapping=mapping) elif fdemType == 'b': survey = EM.FDEM.Survey(Src) prb = EM.FDEM.Problem3D_b(mesh, mapping=mapping) elif fdemType == 'j': survey = EM.FDEM.Survey(Src) prb = EM.FDEM.Problem3D_j(mesh, mapping=mapping) elif fdemType == 'h': survey = EM.FDEM.Survey(Src) prb = EM.FDEM.Problem3D_h(mesh, mapping=mapping) else: raise NotImplementedError() prb.pair(survey) try: from pymatsolver import PardisoSolver prb.Solver = PardisoSolver except ImportError: prb.Solver = SolverLU # prb.solverOpts = dict(check_accuracy=True) return prb
def run(loc=None, sig=None, radi=None, param=None, surveyType='dipole-dipole', unitType='appConductivity', plotIt=True): assert surveyType in ['pole-dipole', 'dipole-dipole'], ( "Source type (surveyType) must be pdp or dpdp " "(pole dipole or dipole dipole)" ) assert unitType in ['appResistivity', 'appConductivity', 'volt'], ( "Unit type (unitType) must be appResistivity or " "appConductivity or volt (potential)" ) if loc is None: loc = np.c_[[-50., 0., -50.], [50., 0., -50.]] if sig is None: sig = np.r_[1e-2, 1e-1, 1e-3] if radi is None: radi = np.r_[25., 25.] if param is None: param = np.r_[30., 30., 5] if surveyType == "pole-dipole": surveyType = "pole-dipole" elif surveyType == "dipole-dipole": surveyType = "dipole-dipole" else: raise NotImplementedError() # First we need to create a mesh and a model. # This is our mesh dx = 5. hxind = [(dx, 15, -1.3), (dx, 75), (dx, 15, 1.3)] hyind = [(dx, 15, -1.3), (dx, 10), (dx, 15, 1.3)] hzind = [(dx, 15, -1.3), (dx, 15)] mesh = Mesh.TensorMesh([hxind, hyind, hzind], 'CCN') # Set background conductivity model = np.ones(mesh.nC) * sig[0] # First anomaly ind = Utils.ModelBuilder.getIndicesSphere(loc[:, 0], radi[0], mesh.gridCC) model[ind] = sig[1] # Second anomaly ind = Utils.ModelBuilder.getIndicesSphere(loc[:, 1], radi[1], mesh.gridCC) model[ind] = sig[2] # Get index of the center indy = int(mesh.nCy/2) # Plot the model for reference # Define core mesh extent xlim = 200 zlim = 100 # Then specify the end points of the survey. Let's keep it simple for now # and survey above the anomalies, top of the mesh ends = [(-175, 0), (175, 0)] ends = np.c_[np.asarray(ends), np.ones(2).T*mesh.vectorNz[-1]] # Snap the endpoints to the grid. Easier to create 2D section. indx = Utils.closestPoints(mesh, ends) locs = np.c_[ mesh.gridCC[indx, 0], mesh.gridCC[indx, 1], np.ones(2).T*mesh.vectorNz[-1] ] # We will handle the geometry of the survey for you and create all the # combination of tx-rx along line survey = gen_DCIPsurvey( locs, mesh, surveyType, param[0], param[1], param[2] ) Tx = survey.srcList Rx = [src.rxList[0] for src in Tx] # Define some global geometry dl_len = np.sqrt(np.sum((locs[0, :] - locs[1, :])**2)) dl_x = (Tx[-1].loc[0][1] - Tx[0].loc[0][0]) / dl_len dl_y = (Tx[-1].loc[1][1] - Tx[0].loc[1][0]) / dl_len # Set boundary conditions mesh.setCellGradBC('neumann') # Define the linear system needed for the DC problem. We assume an infitite # line source for simplicity. Div = mesh.faceDiv Grad = mesh.cellGrad Msig = Utils.sdiag(1./(mesh.aveF2CC.T*(1./model))) A = Div*Msig*Grad # Change one corner to deal with nullspace A[0, 0] = 1 A = sp.csc_matrix(A) # We will solve the system iteratively, so a pre-conditioner is helpful # This is simply a Jacobi preconditioner (inverse of the main diagonal) dA = A.diagonal() P = sp.spdiags(1/dA, 0, A.shape[0], A.shape[0]) # Now we can solve the system for all the transmitters # We want to store the data data = [] # There is probably a more elegant way to do this, # but we can just for-loop through the transmitters for ii in range(len(Tx)): start_time = time.time() # Let's time the calculations # print("Transmitter %i / %i\r" % (ii+1, len(Tx))) # Select dipole locations for receiver rxloc_M = np.asarray(Rx[ii].locs[0]) rxloc_N = np.asarray(Rx[ii].locs[1]) # For usual cases 'dipole-dipole' or "gradient" if surveyType == 'pole-dipole': # Create an "inifinity" pole tx = np.squeeze(Tx[ii].loc[:, 0:1]) tinf = tx + np.array([dl_x, dl_y, 0])*dl_len*2 inds = Utils.closestPoints(mesh, np.c_[tx, tinf].T) RHS = ( mesh.getInterpolationMat(np.asarray(Tx[ii]).T, 'CC').T * ([-1] / mesh.vol[inds]) ) else: inds = Utils.closestPoints(mesh, np.asarray(Tx[ii].loc)) RHS = ( mesh.getInterpolationMat(np.asarray(Tx[ii].loc), 'CC').T * ([-1, 1] / mesh.vol[inds]) ) # Iterative Solve Ainvb = sp.linalg.bicgstab(P*A, P*RHS, tol=1e-5) # We now have the potential everywhere phi = Utils.mkvc(Ainvb[0]) # Solve for phi on pole locations P1 = mesh.getInterpolationMat(rxloc_M, 'CC') P2 = mesh.getInterpolationMat(rxloc_N, 'CC') # Compute the potential difference dtemp = (P1*phi - P2*phi)*np.pi data.append(dtemp) print ('\rTransmitter {0} of {1} -> Time:{2} sec'.format( ii, len(Tx), time.time() - start_time) ) print ('Transmitter {0} of {1}'.format(ii, len(Tx))) print ('Forward completed') # Let's just convert the 3D format into 2D (distance along line) and plot survey2D = convertObs_DC3D_to_2D(survey, np.ones(survey.nSrc), 'Xloc') survey2D.dobs = np.hstack(data) if not plotIt: return fig = plt.figure(figsize=(7, 7)) ax = plt.subplot(2, 1, 1, aspect='equal') # Plot the location of the spheres for reference circle1 = plt.Circle( (loc[0, 0], loc[2, 0]), radi[0], color='w', fill=False, lw=3 ) circle2 = plt.Circle( (loc[0, 1], loc[2, 1]), radi[1], color='k', fill=False, lw=3 ) ax.add_artist(circle1) ax.add_artist(circle2) dat = mesh.plotSlice( np.log10(model), ax=ax, normal='Y', ind=indy, grid=True, clim=np.log10([sig.min(), sig.max()]) ) ax.set_title('3-D model') plt.gca().set_aspect('equal', adjustable='box') plt.scatter(Tx[0].loc[0][0], Tx[0].loc[0][2], s=40, c='g', marker='v') plt.scatter(Rx[0].locs[0][:, 0], Rx[0].locs[0][:, 1], s=40, c='y') plt.xlim([-xlim, xlim]) plt.ylim([-zlim, mesh.vectorNz[-1]+dx]) pos = ax.get_position() ax.set_position([pos.x0, pos.y0 + 0.025, pos.width, pos.height]) pos = ax.get_position() # the parameters are the specified position you set cbarax = fig.add_axes( [pos.x0, pos.y0 + 0.025, pos.width, pos.height * 0.04] ) cb = fig.colorbar( dat[0], cax=cbarax, orientation="horizontal", ax=ax, ticks=np.linspace(np.log10(sig.min()), np.log10(sig.max()), 3), format="$10^{%.1f}$" ) cb.set_label("Conductivity (S/m)", size=12) cb.ax.tick_params(labelsize=12) # Second plot for the predicted apparent resistivity data ax2 = plt.subplot(2, 1, 2, aspect='equal') # Plot the location of the spheres for reference circle1 = plt.Circle( (loc[0, 0], loc[2, 0]), radi[0], color='w', fill=False, lw=3 ) circle2 = plt.Circle( (loc[0, 1], loc[2, 1]), radi[1], color='k', fill=False, lw=3 ) ax2.add_artist(circle1) ax2.add_artist(circle2) # Add the pseudo section dat = plot_pseudoSection( survey2D, ax2, surveyType=surveyType, dataType=unitType ) ax2.set_title('Apparent Conductivity data') plt.ylim([-zlim, mesh.vectorNz[-1]+dx]) return fig, ax
def dc_resistivity( log_sigma_background=1., # Conductivity of the background, S/m log_sigma_block=2, # Conductivity of the block, S/m plot_type='potential' # "conductivity", "potential", or "current" ): from pylab import rcParams rcParams['figure.figsize'] = 10, 10 # Define a unit-cell mesh mesh = Mesh.TensorMesh([100, 100]) # setup a mesh on which to solve # model parameters sigma_background = 10**log_sigma_background sigma_block = 10**log_sigma_block # add a block to our model x_block = np.r_[0.4, 0.6] y_block = np.r_[0.4, 0.6] # assign them on the mesh # create a physical property model sigma = sigma_background * np.ones(mesh.nC) block_indices = ((mesh.gridCC[:, 0] >= x_block[0]) & # left boundary (mesh.gridCC[:, 0] <= x_block[1]) & # right boundary (mesh.gridCC[:, 1] >= y_block[0]) & # bottom boundary (mesh.gridCC[:, 1] <= y_block[1])) # top boundary # add the block to the physical property model sigma[block_indices] = sigma_block # Define a source a_loc, b_loc = np.r_[0.2, 0.5], np.r_[0.8, 0.5] source_locs = [a_loc, b_loc] # locate it on the mesh source_loc_inds = Utils.closestPoints(mesh, source_locs) a_loc_mesh = mesh.gridCC[source_loc_inds[0], :] b_loc_mesh = mesh.gridCC[source_loc_inds[1], :] if plot_type == 'conductivity': plt.colorbar(mesh.plotImage(sigma)[0]) plt.plot(a_loc_mesh[0], a_loc_mesh[1], 'wv', markersize=8) plt.plot(b_loc_mesh[0], b_loc_mesh[1], 'w^', markersize=8) plt.title('electrical conductivity, $\sigma$') return # Assemble and solve the DC resistivity problem Div = mesh.faceDiv Sigma = mesh.getFaceInnerProduct(sigma, invProp=True, invMat=True) Vol = Utils.sdiag(mesh.vol) # assemble the system matrix A = Vol * Div * Sigma * Div.T * Vol # right hand side q = np.zeros(mesh.nC) q[source_loc_inds] = np.r_[+1, -1] # solve the DC resistivity problem Ainv = Solver(A) # create a matrix that behaves like A inverse phi = Ainv * q if plot_type == 'potential': plt.colorbar(mesh.plotImage(phi)[0]) plt.title('Electric Potential, $\phi$') return if plot_type == 'current': j = Sigma * mesh.faceDiv.T * Utils.sdiag(mesh.vol) * phi plt.colorbar( mesh.plotImage(j, vType='F', view='vec', streamOpts={'color': 'w'})[0]) plt.title('Current, $j$') return
#gin = plt.ginput(2, timeout = 0) #============================================================================== # if not gin: # print 'SimPED - Simulation has ended with return' # break #============================================================================== # Add z coordinate to all survey... assume flat nz = mesh.vectorNz var = np.c_[np.asarray(gin),np.ones(2).T*nz[-1]] # Snap the endpoints to the grid. Easier to create 2D section. indx = Utils.closestPoints(mesh, var ) endl = np.c_[mesh.gridCC[indx,0],mesh.gridCC[indx,1],np.ones(2).T*nz[-1]] [Tx, Rx] = DC.gen_DCIPsurvey(endl, mesh, stype, a, b, n) dl_len = np.sqrt( np.sum((endl[0,:] - endl[1,:])**2) ) dl_x = ( Tx[-1][0,1] - Tx[0][0,0] ) / dl_len dl_y = ( Tx[-1][1,1] - Tx[0][1,0] ) / dl_len azm = np.arctan(dl_y/dl_x) # Plot stations along line plt.scatter(Tx[0][0,:],Tx[0][1,:],s=20,c='g') plt.scatter(Rx[0][:,0::3],Rx[0][:,1::3],s=20,c='y') #%% Forward model data data = []#np.zeros( nstn*nrx )
def test_CylMeshEBDipoles(self): print ("Testing CylMesh Electric and Magnetic Dipoles in a wholespace-" " Analytic: J-formulation") sigmaback = 1. mur = 2. freq = 1. skdpth = 500./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)]) mesh = Mesh.CylMesh([hx, 1, hz], [0., 0., -hz.sum()/2]) # define the cylindrical mesh if plotIt: mesh.plotGrid() # make sure mesh is big enough self.assertTrue(mesh.hz.sum() > skdpth*2.) self.assertTrue(mesh.hx.sum() > skdpth*2.) SigmaBack = sigmaback*np.ones((mesh.nC)) MuBack = mur*mu_0*np.ones((mesh.nC)) # set up source # test electric dipole src_loc = np.r_[0., 0., 0.] s_ind = Utils.closestPoints(mesh, src_loc, 'Fz') + mesh.nFx de = np.zeros(mesh.nF, dtype=complex) de[s_ind] = 1./csz de_p = [EM.FDEM.Src.RawVec_e([], freq, de/mesh.area)] dm_p = [EM.FDEM.Src.MagDipole([], freq, src_loc)] # Pair the problem and survey surveye = EM.FDEM.Survey(de_p) surveym = EM.FDEM.Survey(dm_p) mapping = [('sigma', Maps.IdentityMap(mesh)), ('mu', Maps.IdentityMap(mesh))] prbe = EM.FDEM.Problem3D_h(mesh, mapping=mapping) prbm = EM.FDEM.Problem3D_e(mesh, mapping=mapping) prbe.pair(surveye) # pair problem and survey prbm.pair(surveym) # solve fieldsBackE = prbe.fields(np.r_[SigmaBack, MuBack]) # Done fieldsBackM = prbm.fields(np.r_[SigmaBack, MuBack]) # Done rlim = [20., 500.] lookAtTx = de_p r = mesh.vectorCCx[np.argmin(np.abs(mesh.vectorCCx-rlim[0])) : np.argmin(np.abs(mesh.vectorCCx-rlim[1]))] z = 100. # where we choose to measure XYZ = Utils.ndgrid(r, np.r_[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'] Rho = Utils.sdiag(1./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 = EM.Analytics.FDEM.ElectricDipoleWholeSpace(XYZ, src_loc, sigmaback, freq,orientation='Z',mu= mur*mu_0) exa, eya, eza = Utils.mkvc(exa, 2), Utils.mkvc(eya, 2), Utils.mkvc(eza, 2) bxa, bya, bza = EM.Analytics.FDEM.MagneticDipoleWholeSpace(XYZ, src_loc, sigmaback, freq,orientation='Z',mu= mur*mu_0) bxa, bya, bza = Utils.mkvc(bxa, 2), Utils.mkvc(bya, 2), 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 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 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 = Mesh.TensorMesh((hx, hy), "CC") z = np.r_[1.0] B = np.r_[B0, inclination, declination] # 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) self.survey = createMagSurvey(np.c_[xyz, np.ones(self.mesh.nC)], B) self.prob = problem() self.prob.prism = self.prism self.prob.survey = self.survey self.prob.susc = kappa self.prob.uType, self.prob.mType = uType, "induced" self.data = self.prob.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 test_CylMeshEBDipoles(self): print( "Testing CylMesh Electric and Magnetic Dipoles in a wholespace-" " Analytic: J-formulation") sigmaback = 1. mur = 2. freq = 1. skdpth = 500. / 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)]) mesh = Mesh.CylMesh( [hx, 1, hz], [0., 0., -hz.sum() / 2]) # define the cylindrical mesh if plotIt: mesh.plotGrid() # make sure mesh is big enough self.assertTrue(mesh.hz.sum() > skdpth * 2.) self.assertTrue(mesh.hx.sum() > skdpth * 2.) SigmaBack = sigmaback * np.ones((mesh.nC)) MuBack = mur * mu_0 * np.ones((mesh.nC)) # set up source # test electric dipole src_loc = np.r_[0., 0., 0.] s_ind = Utils.closestPoints(mesh, src_loc, 'Fz') + mesh.nFx de = np.zeros(mesh.nF, dtype=complex) de[s_ind] = 1. / csz de_p = [EM.FDEM.Src.RawVec_e([], freq, de / mesh.area)] dm_p = [EM.FDEM.Src.MagDipole([], freq, src_loc)] # Pair the problem and survey surveye = EM.FDEM.Survey(de_p) surveym = EM.FDEM.Survey(dm_p) mapping = [('sigma', Maps.IdentityMap(mesh)), ('mu', Maps.IdentityMap(mesh))] prbe = EM.FDEM.Problem3D_h(mesh, mapping=mapping) prbm = EM.FDEM.Problem3D_e(mesh, mapping=mapping) prbe.pair(surveye) # pair problem and survey prbm.pair(surveym) # solve fieldsBackE = prbe.fields(np.r_[SigmaBack, MuBack]) # Done fieldsBackM = prbm.fields(np.r_[SigmaBack, MuBack]) # Done rlim = [20., 500.] lookAtTx = de_p r = mesh.vectorCCx[np.argmin(np.abs(mesh.vectorCCx - rlim[0])):np. argmin(np.abs(mesh.vectorCCx - rlim[1]))] z = 100. # where we choose to measure XYZ = Utils.ndgrid(r, np.r_[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'] Rho = Utils.sdiag(1. / 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 = EM.Analytics.FDEM.ElectricDipoleWholeSpace( XYZ, src_loc, sigmaback, freq, orientation='Z', mu=mur * mu_0) exa, eya, eza = Utils.mkvc(exa, 2), Utils.mkvc(eya, 2), Utils.mkvc(eza, 2) bxa, bya, bza = EM.Analytics.FDEM.MagneticDipoleWholeSpace( XYZ, src_loc, sigmaback, freq, orientation='Z', mu=mur * mu_0) bxa, bya, bza = Utils.mkvc(bxa, 2), Utils.mkvc(bya, 2), 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 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 = 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 run(loc=None, sig=None, radi=None, param=None, surveyType='dipole-dipole', unitType='appConductivity', plotIt=True): assert surveyType in ['pole-dipole', 'dipole-dipole' ], ("Source type (surveyType) must be pdp or dpdp " "(pole dipole or dipole dipole)") assert unitType in ['appResistivity', 'appConductivity', 'volt' ], ("Unit type (unitType) must be appResistivity or " "appConductivity or volt (potential)") if loc is None: loc = np.c_[[-50., 0., -50.], [50., 0., -50.]] if sig is None: sig = np.r_[1e-2, 1e-1, 1e-3] if radi is None: radi = np.r_[25., 25.] if param is None: param = np.r_[30., 30., 5] if surveyType == "pole-dipole": surveyType = "pole-dipole" elif surveyType == "dipole-dipole": surveyType = "dipole-dipole" else: raise NotImplementedError() # First we need to create a mesh and a model. # This is our mesh dx = 5. hxind = [(dx, 15, -1.3), (dx, 75), (dx, 15, 1.3)] hyind = [(dx, 15, -1.3), (dx, 10), (dx, 15, 1.3)] hzind = [(dx, 15, -1.3), (dx, 15)] mesh = Mesh.TensorMesh([hxind, hyind, hzind], 'CCN') # Set background conductivity model = np.ones(mesh.nC) * sig[0] # First anomaly ind = Utils.ModelBuilder.getIndicesSphere(loc[:, 0], radi[0], mesh.gridCC) model[ind] = sig[1] # Second anomaly ind = Utils.ModelBuilder.getIndicesSphere(loc[:, 1], radi[1], mesh.gridCC) model[ind] = sig[2] # Get index of the center indy = int(mesh.nCy / 2) # Plot the model for reference # Define core mesh extent xlim = 200 zlim = 100 # Then specify the end points of the survey. Let's keep it simple for now # and survey above the anomalies, top of the mesh ends = [(-175, 0), (175, 0)] ends = np.c_[np.asarray(ends), np.ones(2).T * mesh.vectorNz[-1]] # Snap the endpoints to the grid. Easier to create 2D section. indx = Utils.closestPoints(mesh, ends) locs = np.c_[mesh.gridCC[indx, 0], mesh.gridCC[indx, 1], np.ones(2).T * mesh.vectorNz[-1]] # We will handle the geometry of the survey for you and create all the # combination of tx-rx along line survey = gen_DCIPsurvey(locs, mesh, surveyType, param[0], param[1], param[2]) Tx = survey.srcList Rx = [src.rxList[0] for src in Tx] # Define some global geometry dl_len = np.sqrt(np.sum((locs[0, :] - locs[1, :])**2)) dl_x = (Tx[-1].loc[0][1] - Tx[0].loc[0][0]) / dl_len dl_y = (Tx[-1].loc[1][1] - Tx[0].loc[1][0]) / dl_len # Set boundary conditions mesh.setCellGradBC('neumann') # Define the linear system needed for the DC problem. We assume an infitite # line source for simplicity. Div = mesh.faceDiv Grad = mesh.cellGrad Msig = Utils.sdiag(1. / (mesh.aveF2CC.T * (1. / model))) A = Div * Msig * Grad # Change one corner to deal with nullspace A[0, 0] = 1 A = sp.csc_matrix(A) # We will solve the system iteratively, so a pre-conditioner is helpful # This is simply a Jacobi preconditioner (inverse of the main diagonal) dA = A.diagonal() P = sp.spdiags(1 / dA, 0, A.shape[0], A.shape[0]) # Now we can solve the system for all the transmitters # We want to store the data data = [] # There is probably a more elegant way to do this, # but we can just for-loop through the transmitters for ii in range(len(Tx)): start_time = time.time() # Let's time the calculations # print("Transmitter %i / %i\r" % (ii+1, len(Tx))) # Select dipole locations for receiver rxloc_M = np.asarray(Rx[ii].locs[0]) rxloc_N = np.asarray(Rx[ii].locs[1]) # For usual cases 'dipole-dipole' or "gradient" if surveyType == 'pole-dipole': # Create an "inifinity" pole tx = np.squeeze(Tx[ii].loc[:, 0:1]) tinf = tx + np.array([dl_x, dl_y, 0]) * dl_len * 2 inds = Utils.closestPoints(mesh, np.c_[tx, tinf].T) RHS = (mesh.getInterpolationMat(np.asarray(Tx[ii]).T, 'CC').T * ([-1] / mesh.vol[inds])) else: inds = Utils.closestPoints(mesh, np.asarray(Tx[ii].loc)) RHS = (mesh.getInterpolationMat(np.asarray(Tx[ii].loc), 'CC').T * ([-1, 1] / mesh.vol[inds])) # Iterative Solve Ainvb = sp.linalg.bicgstab(P * A, P * RHS, tol=1e-5) # We now have the potential everywhere phi = Utils.mkvc(Ainvb[0]) # Solve for phi on pole locations P1 = mesh.getInterpolationMat(rxloc_M, 'CC') P2 = mesh.getInterpolationMat(rxloc_N, 'CC') # Compute the potential difference dtemp = (P1 * phi - P2 * phi) * np.pi data.append(dtemp) print('\rTransmitter {0} of {1} -> Time:{2} sec'.format( ii, len(Tx), time.time() - start_time)) print('Transmitter {0} of {1}'.format(ii, len(Tx))) print('Forward completed') # Let's just convert the 3D format into 2D (distance along line) and plot survey2D = convertObs_DC3D_to_2D(survey, np.ones(survey.nSrc), 'Xloc') survey2D.dobs = np.hstack(data) if not plotIt: return fig = plt.figure(figsize=(7, 7)) ax = plt.subplot(2, 1, 1, aspect='equal') # Plot the location of the spheres for reference circle1 = plt.Circle((loc[0, 0], loc[2, 0]), radi[0], color='w', fill=False, lw=3) circle2 = plt.Circle((loc[0, 1], loc[2, 1]), radi[1], color='k', fill=False, lw=3) ax.add_artist(circle1) ax.add_artist(circle2) dat = mesh.plotSlice(np.log10(model), ax=ax, normal='Y', ind=indy, grid=True, clim=np.log10([sig.min(), sig.max()])) ax.set_title('3-D model') plt.gca().set_aspect('equal', adjustable='box') plt.scatter(Tx[0].loc[0][0], Tx[0].loc[0][2], s=40, c='g', marker='v') plt.scatter(Rx[0].locs[0][:, 0], Rx[0].locs[0][:, 1], s=40, c='y') plt.xlim([-xlim, xlim]) plt.ylim([-zlim, mesh.vectorNz[-1] + dx]) pos = ax.get_position() ax.set_position([pos.x0, pos.y0 + 0.025, pos.width, pos.height]) pos = ax.get_position() # the parameters are the specified position you set cbarax = fig.add_axes( [pos.x0, pos.y0 + 0.025, pos.width, pos.height * 0.04]) cb = fig.colorbar(dat[0], cax=cbarax, orientation="horizontal", ax=ax, ticks=np.linspace(np.log10(sig.min()), np.log10(sig.max()), 3), format="$10^{%.1f}$") cb.set_label("Conductivity (S/m)", size=12) cb.ax.tick_params(labelsize=12) # Second plot for the predicted apparent resistivity data ax2 = plt.subplot(2, 1, 2, aspect='equal') # Plot the location of the spheres for reference circle1 = plt.Circle((loc[0, 0], loc[2, 0]), radi[0], color='w', fill=False, lw=3) circle2 = plt.Circle((loc[0, 1], loc[2, 1]), radi[1], color='k', fill=False, lw=3) ax2.add_artist(circle1) ax2.add_artist(circle2) # Add the pseudo section dat = plot_pseudoSection(survey2D, ax2, surveyType=surveyType, dataType=unitType) ax2.set_title('Apparent Conductivity data') plt.ylim([-zlim, mesh.vectorNz[-1] + dx]) return fig, ax
def run(loc=None, sig=None, radi=None, param=None, stype='dpdp', plotIt=True): """ DC Forward Simulation ===================== Forward model conductive spheres in a half-space and plot a pseudo-section Created by @fourndo on Mon Feb 01 19:28:06 2016 """ assert stype in [ 'pdp', 'dpdp' ], "Source type (stype) must be pdp or dpdp (pole dipole or dipole dipole)" if loc is None: loc = np.c_[[-50., 0., -50.], [50., 0., -50.]] if sig is None: sig = np.r_[1e-2, 1e-1, 1e-3] if radi is None: radi = np.r_[25., 25.] if param is None: param = np.r_[30., 30., 5] # First we need to create a mesh and a model. # This is our mesh dx = 5. hxind = [(dx, 15, -1.3), (dx, 75), (dx, 15, 1.3)] hyind = [(dx, 15, -1.3), (dx, 10), (dx, 15, 1.3)] hzind = [(dx, 15, -1.3), (dx, 15)] mesh = Mesh.TensorMesh([hxind, hyind, hzind], 'CCN') # Set background conductivity model = np.ones(mesh.nC) * sig[0] # First anomaly ind = Utils.ModelBuilder.getIndicesSphere(loc[:, 0], radi[0], mesh.gridCC) model[ind] = sig[1] # Second anomaly ind = Utils.ModelBuilder.getIndicesSphere(loc[:, 1], radi[1], mesh.gridCC) model[ind] = sig[2] # Get index of the center indy = int(mesh.nCy / 2) # Plot the model for reference # Define core mesh extent xlim = 200 zlim = 125 # Specify the survey type: "pdp" | "dpdp" # Then specify the end points of the survey. Let's keep it simple for now and survey above the anomalies, top of the mesh ends = [(-175, 0), (175, 0)] ends = np.c_[np.asarray(ends), np.ones(2).T * mesh.vectorNz[-1]] # Snap the endpoints to the grid. Easier to create 2D section. indx = Utils.closestPoints(mesh, ends) locs = np.c_[mesh.gridCC[indx, 0], mesh.gridCC[indx, 1], np.ones(2).T * mesh.vectorNz[-1]] # We will handle the geometry of the survey for you and create all the combination of tx-rx along line # [Tx, Rx] = DC.gen_DCIPsurvey(locs, mesh, stype, param[0], param[1], param[2]) survey, Tx, Rx = DC.gen_DCIPsurvey(locs, mesh, stype, param[0], param[1], param[2]) # Define some global geometry dl_len = np.sqrt(np.sum((locs[0, :] - locs[1, :])**2)) dl_x = (Tx[-1][0, 1] - Tx[0][0, 0]) / dl_len dl_y = (Tx[-1][1, 1] - Tx[0][1, 0]) / dl_len azm = np.arctan(dl_y / dl_x) #Set boundary conditions mesh.setCellGradBC('neumann') # Define the differential operators needed for the DC problem Div = mesh.faceDiv Grad = mesh.cellGrad Msig = Utils.sdiag(1. / (mesh.aveF2CC.T * (1. / model))) A = Div * Msig * Grad # Change one corner to deal with nullspace A[0, 0] = 1 A = sp.csc_matrix(A) # We will solve the system iteratively, so a pre-conditioner is helpful # This is simply a Jacobi preconditioner (inverse of the main diagonal) dA = A.diagonal() P = sp.spdiags(1 / dA, 0, A.shape[0], A.shape[0]) # Now we can solve the system for all the transmitters # We want to store the data data = [] # There is probably a more elegant way to do this, but we can just for-loop through the transmitters for ii in range(len(Tx)): start_time = time.time() # Let's time the calculations #print("Transmitter %i / %i\r" % (ii+1,len(Tx))) # Select dipole locations for receiver rxloc_M = np.asarray(Rx[ii][:, 0:3]) rxloc_N = np.asarray(Rx[ii][:, 3:]) # For usual cases "dpdp" or "gradient" if stype == 'pdp': # Create an "inifinity" pole tx = np.squeeze(Tx[ii][:, 0:1]) tinf = tx + np.array([dl_x, dl_y, 0]) * dl_len * 2 inds = Utils.closestPoints(mesh, np.c_[tx, tinf].T) RHS = mesh.getInterpolationMat(np.asarray(Tx[ii]).T, 'CC').T * ([-1] / mesh.vol[inds]) else: inds = Utils.closestPoints(mesh, np.asarray(Tx[ii]).T) RHS = mesh.getInterpolationMat(np.asarray(Tx[ii]).T, 'CC').T * ([-1, 1] / mesh.vol[inds]) # Iterative Solve Ainvb = sp.linalg.bicgstab(P * A, P * RHS, tol=1e-5) # We now have the potential everywhere phi = Utils.mkvc(Ainvb[0]) # Solve for phi on pole locations P1 = mesh.getInterpolationMat(rxloc_M, 'CC') P2 = mesh.getInterpolationMat(rxloc_N, 'CC') # Compute the potential difference dtemp = (P1 * phi - P2 * phi) * np.pi data.append(dtemp) print '\rTransmitter {0} of {1} -> Time:{2} sec'.format( ii, len(Tx), time.time() - start_time), print 'Transmitter {0} of {1}'.format(ii, len(Tx)) print 'Forward completed' # Let's just convert the 3D format into 2D (distance along line) and plot # [Tx2d, Rx2d] = DC.convertObs_DC3D_to_2D(survey, np.ones(survey.nSrc)) survey2D = DC.convertObs_DC3D_to_2D(survey, np.ones(survey.nSrc)) survey2D.dobs = np.hstack(data) # Here is an example for the first tx-rx array if plotIt: import matplotlib.pyplot as plt fig = plt.figure() ax = plt.subplot(2, 1, 1, aspect='equal') mesh.plotSlice(np.log10(model), ax=ax, normal='Y', ind=indy, grid=True) ax.set_title('E-W section at ' + str(mesh.vectorCCy[indy]) + ' m') plt.gca().set_aspect('equal', adjustable='box') plt.scatter(Tx[0][0, :], Tx[0][2, :], s=40, c='g', marker='v') plt.scatter(Rx[0][:, 0::3], Rx[0][:, 2::3], s=40, c='y') plt.xlim([-xlim, xlim]) plt.ylim([-zlim, mesh.vectorNz[-1] + dx]) ax = plt.subplot(2, 1, 2, aspect='equal') # Plot the location of the spheres for reference circle1 = plt.Circle((loc[0, 0] - Tx[0][0, 0], loc[2, 0]), radi[0], color='w', fill=False, lw=3) circle2 = plt.Circle((loc[0, 1] - Tx[0][0, 0], loc[2, 1]), radi[1], color='k', fill=False, lw=3) ax.add_artist(circle1) ax.add_artist(circle2) # Add the speudo section DC.plot_pseudoSection(survey2D, ax, stype) # plt.scatter(Tx2d[0][:],Tx[0][2,:],s=40,c='g', marker='v') # plt.scatter(Rx2d[0][:],Rx[0][:,2::3],s=40,c='y') # plt.plot(np.r_[Tx2d[0][0],Rx2d[-1][-1,-1]],np.ones(2)*mesh.vectorNz[-1], color='k') plt.ylim([-zlim, mesh.vectorNz[-1] + dx]) plt.show() return fig, ax
def dc_resistivity( log_sigma_background=1., # Conductivity of the background, S/m log_sigma_block=2, # Conductivity of the block, S/m plot_type='potential' # "conductivity", "potential", or "current" ): from pylab import rcParams rcParams['figure.figsize'] = 10, 10 # Define a unit-cell mesh mesh = Mesh.TensorMesh([100, 100]) # setup a mesh on which to solve # model parameters sigma_background = 10**log_sigma_background sigma_block = 10**log_sigma_block # add a block to our model x_block = np.r_[0.4, 0.6] y_block = np.r_[0.4, 0.6] # assign them on the mesh # create a physical property model sigma = sigma_background * np.ones(mesh.nC) block_indices = ((mesh.gridCC[:, 0] >= x_block[0]) & # left boundary (mesh.gridCC[:, 0] <= x_block[1]) & # right boundary (mesh.gridCC[:, 1] >= y_block[0]) & # bottom boundary (mesh.gridCC[:, 1] <= y_block[1])) # top boundary # add the block to the physical property model sigma[block_indices] = sigma_block # Define a source a_loc, b_loc = np.r_[0.2, 0.5], np.r_[0.8, 0.5] source_locs = [a_loc, b_loc] # locate it on the mesh source_loc_inds = Utils.closestPoints(mesh, source_locs) a_loc_mesh = mesh.gridCC[source_loc_inds[0], :] b_loc_mesh = mesh.gridCC[source_loc_inds[1], :] if plot_type == 'conductivity': plt.colorbar(mesh.plotImage(sigma)[0]) plt.plot(a_loc_mesh[0], a_loc_mesh[1], 'wv', markersize=8) plt.plot(b_loc_mesh[0], b_loc_mesh[1], 'w^', markersize=8) plt.title('electrical conductivity, $\sigma$') return # Assemble and solve the DC resistivity problem Div = mesh.faceDiv Sigma = mesh.getFaceInnerProduct(sigma, invProp=True, invMat=True) Vol = Utils.sdiag(mesh.vol) # assemble the system matrix A = Vol * Div * Sigma * Div.T * Vol # right hand side q = np.zeros(mesh.nC) q[source_loc_inds] = np.r_[+1, -1] # solve the DC resistivity problem Ainv = Solver(A) # create a matrix that behaves like A inverse phi = Ainv * q if plot_type == 'potential': plt.colorbar(mesh.plotImage(phi)[0]) plt.title('Electric Potential, $\phi$') return if plot_type == 'current': j = Sigma * mesh.faceDiv.T * Utils.sdiag(mesh.vol) * phi plt.colorbar(mesh.plotImage( j, vType='F', view='vec', streamOpts={'color': 'w'} )[0]) plt.title('Current, $j$') return
def simulate_two_monopole(self, component, inclination, declination, length, dx, moment, depth_n, depth_p, profile, fixed_scale, show_halfwidth): self.component = component self.inclination = inclination self.declination = declination self.length = length self.dx = dx self.moment = moment self.depth = depth_n self.depth = depth_p 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 = Mesh.TensorMesh((hx, hy), 'CC') z = np.r_[1.] orientation = self.id_to_cartesian(inclination, declination) md_n = em.static.MagneticPoleWholeSpace(location=np.r_[0, 0, -depth_n], orientation=orientation, moment=moment) md_p = em.static.MagneticPoleWholeSpace(location=np.r_[0, 0, -depth_p], orientation=orientation, moment=moment) xyz = Utils.ndgrid(self.mesh.vectorCCx, self.mesh.vectorCCy, z) b_vec = -md_n.magnetic_flux_density(xyz) + md_p.magnetic_flux_density( xyz) # Project to the direction of earth field if component == 'Bt': rx_orientation = orientation.copy() 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) elif component == 'Bg': rx_orientation = orientation.copy() xyz_up = Utils.ndgrid(self.mesh.vectorCCx, self.mesh.vectorCCy, z + 1.) b_vec -= -md_n.magnetic_flux_density(xyz_up) b_vec -= md_p.magnetic_flux_density(xyz_up) 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]