def dotest(MYSOLVER, multi=False, A=None, **solverOpts): if A is None: h1 = np.ones(10) * 100. h2 = np.ones(10) * 100. h3 = np.ones(10) * 100. h = [h1, h2, h3] M = TensorMesh(h) D = M.faceDiv G = -M.faceDiv.T Msig = M.getFaceInnerProduct() A = D * Msig * G A[-1, -1] *= 1 / M.vol[ -1] # remove the constant null space from the matrix else: M = Mesh.TensorMesh([A.shape[0]]) Ainv = MYSOLVER(A, **solverOpts) if multi: e = np.ones(M.nC) else: e = np.ones((M.nC, numRHS)) rhs = A * e x = Ainv * rhs Ainv.clean() return np.linalg.norm(e - x, np.inf)
def dotest(MYSOLVER, multi=False, A=None, **solverOpts): if A is None: h1 = np.ones(10)*100. h2 = np.ones(10)*100. h3 = np.ones(10)*100. h = [h1,h2,h3] M = TensorMesh(h) D = M.faceDiv G = -M.faceDiv.T Msig = M.getFaceInnerProduct() A = D*Msig*G A[-1,-1] *= 1/M.vol[-1] # remove the constant null space from the matrix else: M = Mesh.TensorMesh([A.shape[0]]) Ainv = MYSOLVER(A, **solverOpts) if multi: e = np.ones(M.nC) else: e = np.ones((M.nC, numRHS)) rhs = A * e x = Ainv * rhs Ainv.clean() return np.linalg.norm(e-x,np.inf)
def setUp(self): a = np.array([1, 1, 1]) b = np.array([1, 2]) c = np.array([1, 4]) def gridIt(h): return [np.cumsum(np.r_[0, x]) for x in h] X, Y = ndgrid(gridIt([a, b]), vector=False) self.TM2 = TensorMesh([a, b]) self.Curv2 = CurvilinearMesh([X, Y]) X, Y, Z = ndgrid(gridIt([a, b, c]), vector=False) self.TM3 = TensorMesh([a, b, c]) self.Curv3 = CurvilinearMesh([X, Y, Z])
def setUp(self): cs = 12.5 hx = [(cs, 7, -1.3), (cs, 61), (cs, 7, 1.3)] hy = [(cs, 7, -1.3), (cs, 20)] mesh = TensorMesh([hx, hy], x0="CN") sighalf = 1e-2 sigma = np.ones(mesh.nC) * sighalf x = np.linspace(-135, 250.0, 20) M = utils.ndgrid(x - 12.5, np.r_[0.0]) N = utils.ndgrid(x + 12.5, np.r_[0.0]) A0loc = np.r_[-150, 0.0] # A1loc = np.r_[-130, 0.] rxloc = [np.c_[M, np.zeros(20)], np.c_[N, np.zeros(20)]] data_ana = analytics.DCAnalytic_Pole_Dipole(np.r_[A0loc, 0.0], rxloc, sighalf, earth_type="halfspace") rx = dc.receivers.Dipole(M, N) src0 = dc.sources.Pole([rx], A0loc) survey = dc.Survey([src0]) self.survey = survey self.mesh = mesh self.sigma = sigma self.data_ana = data_ana self.plotIt = False try: from pymatsolver import Pardiso self.Solver = Pardiso except ImportError: self.Solver = SolverLU
def setUp(self): # Note: Pole-Pole requires bigger boundary to obtain good accuracy. # One can use greater padding rate. Here 1.5 is used. cs = 12.5 hx = [(cs, 7, -1.5), (cs, 61), (cs, 7, 1.5)] hy = [(cs, 7, -1.5), (cs, 20)] mesh = TensorMesh([hx, hy], x0="CN") sighalf = 1e-2 sigma = np.ones(mesh.nC) * sighalf x = np.linspace(0, 250.0, 20) M = utils.ndgrid(x - 12.5, np.r_[0.0]) A0loc = np.r_[-150, 0.0] rxloc = np.c_[M, np.zeros(20)] data_ana = analytics.DCAnalytic_Pole_Pole(np.r_[A0loc, 0.0], rxloc, sighalf, earth_type="halfspace") rx = dc.receivers.Pole(M) src0 = dc.sources.Pole([rx], A0loc) survey = dc.survey.Survey([src0]) self.survey = survey self.mesh = mesh self.sigma = sigma self.data_ana = data_ana try: from pymatsolver import PardisoSolver self.Solver = PardisoSolver except ImportError: self.Solver = SolverLU
def setUp(self): dh = 1.0 nx = 12 ny = 12 nz = 12 hx = [(dh, nx)] hy = [(dh, ny)] hz = [(dh, nz)] mesh = TensorMesh([hx, hy, hz], "CNN") # reg actv = np.ones(len(mesh), dtype=bool) # maps wires = maps.Wires(("m1", mesh.nC), ("m2", mesh.nC)) jtv = regularization.JointTotalVariation( mesh, wire_map=wires, indActive=actv, ) self.mesh = mesh self.jtv = jtv self.x0 = np.random.rand(len(mesh) * 2)
def setUp(self): ntx = 31 xtemp_txP = np.logspace(1, 3, ntx) xtemp_txN = -xtemp_txP ytemp_tx = np.zeros(ntx) xtemp_rxP = -5 xtemp_rxN = 5 ytemp_rx = 0.0 abhalf = abs(xtemp_txP - xtemp_txN) * 0.5 a = xtemp_rxN - xtemp_rxP b = ((xtemp_txN - xtemp_txP) - a) * 0.5 # We generate tx and rx lists: srclist = [] for i in range(ntx): rx = dc.receivers.Dipole(np.r_[xtemp_rxP, ytemp_rx, -12.5], np.r_[xtemp_rxN, ytemp_rx, -12.5]) locA = np.r_[xtemp_txP[i], ytemp_tx[i], -12.5] locB = np.r_[xtemp_txN[i], ytemp_tx[i], -12.5] src = dc.sources.Dipole([rx], locA, locB) srclist.append(src) survey = dc.survey.Survey(srclist) rho = np.r_[10, 10, 10] dummy_hz = 100.0 hz = np.r_[10, 10, dummy_hz] mesh = TensorMesh([hz]) simulation = dc.simulation_1d.Simulation1DLayers( survey=survey, rhoMap=maps.ExpMap(mesh), thicknesses=hz[:-1], data_type="apparent_resistivity", ) simulation.dpred(np.log(rho)) mSynth = np.log(rho) dobs = simulation.make_synthetic_data(mSynth, add_noise=True) # Now set up the problem to do some minimization dmis = data_misfit.L2DataMisfit(simulation=simulation, data=dobs) reg = regularization.Tikhonov(mesh) opt = optimization.InexactGaussNewton(maxIterLS=20, maxIter=10, tolF=1e-6, tolX=1e-6, tolG=1e-6, maxIterCG=6) invProb = inverse_problem.BaseInvProblem(dmis, reg, opt, beta=0.0) inv = inversion.BaseInversion(invProb) self.inv = inv self.reg = reg self.p = simulation self.mesh = mesh self.m0 = mSynth self.survey = survey self.dmis = dmis self.dobs = dobs
def setUp(self): npad = 10 cs = 12.5 hx = [(cs, npad, -1.4), (cs, 61), (cs, npad, 1.4)] hy = [(cs, npad, -1.4), (cs, 20)] mesh = TensorMesh([hx, hy], x0="CN") sighalf = 1e-2 sigma = np.ones(mesh.nC) * sighalf x = mesh.cell_centers_x[ np.logical_and(mesh.cell_centers_x > -150, mesh.cell_centers_x < 250) ] M = utils.ndgrid(x, np.r_[0.0]) N = utils.ndgrid(x + 12.5 * 4, np.r_[0.0]) A0loc = np.r_[-200, 0.0] A1loc = np.r_[-250, 0.0] rx = dc.receivers.Dipole(M, N, data_type="apparent_resistivity") src0 = dc.sources.Dipole([rx], A0loc, A1loc) survey = dc.Survey([src0]) self.survey = survey self.mesh = mesh self.sigma = sigma self.sigma_half = sighalf self.plotIt = False try: from pymatsolver import Pardiso self.solver = Pardiso except ImportError: self.solver = SolverLU
def setUp(self): cs = 12.5 hx = [(cs, 7, -1.3), (cs, 61), (cs, 7, 1.3)] hy = [(cs, 7, -1.3), (cs, 20)] mesh = TensorMesh([hx, hy], x0="CN") sighalf = 1e-2 sigma = np.ones(mesh.nC) * sighalf x = np.linspace(-135, 250.0, 20) M = utils.ndgrid(x - 12.5, np.r_[0.0]) N = utils.ndgrid(x + 12.5, np.r_[0.0]) A0loc = np.r_[-150, 0.0] A1loc = np.r_[-130, 0.0] rx = dc.receivers.Dipole(M, N, data_type="apparent_resistivity") src0 = dc.sources.Dipole([rx], A0loc, A1loc) survey = dc.Survey([src0]) self.survey = survey self.mesh = mesh self.sigma = sigma self.sigma_half = sighalf self.plotIt = False try: from pymatsolver import Pardiso self.Solver = Pardiso except ImportError: self.Solver = SolverLU
def load_or_run_results(re_run=False, fname=None, sigma_block=0.01, sigma_halfspace=0.01): if re_run: run_simulation(fname=fname, sigma_block=sigma_block, sigma_halfspace=sigma_halfspace) else: downloads, directory = download_and_unzip_data() fname = os.path.sep.join([directory, fname]) simulation_results = dd.io.load(fname) mesh = TensorMesh(simulation_results["mesh"]["h"], x0=simulation_results["mesh"]["x0"]) sigma = simulation_results["sigma"] times = simulation_results["time"] input_currents = simulation_results["input_currents"] E = simulation_results["E"] B = simulation_results["B"] J = simulation_results["J"] output = { "mesh": mesh, "sigma": sigma, "times": times, "input_currents": input_currents, "E": E, "B": B, "J": J, } return output
def setUp(self): dh = 1.0 nx = 12 ny = 12 nz = 12 hx = [(dh, nx)] hy = [(dh, ny)] hz = [(dh, nz)] mesh = TensorMesh([hx, hy, hz], "CNN") # reg actv = np.ones(len(mesh), dtype=bool) # maps wires = maps.Wires(("m1", mesh.nC), ("m2", mesh.nC)) cros_grad = regularization.CrossGradient( mesh, wire_map=wires, indActive=actv, ) self.mesh = mesh self.cross_grad = cros_grad
def getCoreDomain(self, mirror=False, xmax=100, zmin=-100, zmax=100.0): self.activeCC = (self.mesh.gridCC[:, 0] <= xmax) & (np.logical_and( self.mesh.gridCC[:, 2] >= zmin, self.mesh.gridCC[:, 2] <= zmax)) self.gridCCactive = self.mesh.gridCC[self.activeCC, :][:, [0, 2]] xind = self.mesh.vectorCCx <= xmax yind = np.logical_and(self.mesh.vectorCCz >= zmin, self.mesh.vectorCCz <= zmax) self.nx_core = xind.sum() self.ny_core = yind.sum() # if self.mesh2D is None: hx = np.r_[self.mesh.hx[xind][::-1], self.mesh.hx[xind]] hz = self.mesh.hz[yind] self.mesh2D = TensorMesh([hx, hz], x0="CC")
def setUp(self): # Mesh N = 100 mesh = TensorMesh([N]) # Survey design parameters nk = 30 jk = np.linspace(1.0, 59.0, nk) p = -0.25 q = 0.25 # Physics def g(k): return np.exp(p * jk[k] * mesh.vectorCCx) * np.cos( np.pi * q * jk[k] * mesh.vectorCCx) G = np.empty((nk, mesh.nC)) for i in range(nk): G[i, :] = g(i) self.G = G # Creating the true model true_model = np.zeros(mesh.nC) true_model[mesh.vectorCCx > 0.3] = 1.0 true_model[mesh.vectorCCx > 0.45] = -0.5 true_model[mesh.vectorCCx > 0.6] = 0 self.true_model = true_model # Create a SimPEG simulation model_map = IdentityMap(mesh) sim = simulation.LinearSimulation(mesh, G=G, model_map=model_map) # Create a SimPEG data object relative_error = 0.1 noise_floor = 1e-4 data_obj = sim.make_synthetic_data(true_model, relative_error=relative_error, noise_floor=noise_floor, add_noise=True) dmis = data_misfit.L2DataMisfit(simulation=sim, data=data_obj) self.dmis = dmis # Test for joint misfits n_misfits = 5 multipliers = np.random.randn(n_misfits)**2 multipliers /= np.sum(multipliers) self.multipliers = multipliers dmiscombo = dmis for i, mult in enumerate(multipliers): dmiscombo += mult * dmis self.dmiscombo = dmiscombo # Test for a regularization term reg = Tikhonov(mesh=mesh) self.reg = reg # Test a mix combo self.beta = 10. self.mixcombo = self.dmis + self.beta * self.reg
def mref(self): if getattr(self, "_mref", None) is None: if isinstance(self._mrefInput, float): self._mref = np.ones(self.nC) * self._mrefInput else: self._mref = TensorMesh.readModelUBC( self.mesh, self.basePath + self._mrefInput) self._mref = self._mref[self.activeCells] return self._mref
def m0(self): if getattr(self, "_m0", None) is None: if isinstance(self.mstart, float): self._m0 = np.ones(self.nC) * self.mstart else: self._m0 = TensorMesh.readModelUBC(self.mesh, self.basePath + self.mstart) return self._m0
def make_example_mesh(): dh = 5.0 hx = [(dh, 5, -1.3), (dh, 20), (dh, 5, 1.3)] hy = [(dh, 5, -1.3), (dh, 20), (dh, 5, 1.3)] hz = [(dh, 5, -1.3), (dh, 20), (dh, 5, 1.3)] mesh = TensorMesh([hx, hy, hz], "CCC") return mesh
def baseline_tensor_mesh(N, delta, centering="CCC"): """ Set up a basic regular Cartesian tensor mesh other packages would use :param N: length of one edge of a cubical volume in cells :param delta: length of one edge of a mesh cube :param centering: a three-letter code specifying whether each axis is positive ('P'), negative ('N'), or centered ('C') :return: TensorMesh instance """ hx = hy = hz = [(delta, N),] return TensorMesh([hx, hy, hz], centering)
def activeModel(self): if getattr(self, "_activeModel", None) is None: if self._staticInput == "FILE": # Read from file active cells with 0:air, 1:dynamic, -1 static self._activeModel = TensorMesh.readModelUBC( self.mesh, self.basePath + self._staticInput) else: self._activeModel = np.ones(self._mesh.nC) return self._activeModel
def setUp(self): cs = 12.5 hx = [(cs, 7, -1.3), (cs, 61), (cs, 7, 1.3)] hy = [(cs, 7, -1.3), (cs, 20)] mesh = TensorMesh([hx, hy], x0="CN") sighalf = 1e-2 sigma = np.ones(mesh.nC) * sighalf A0loc = np.r_[-31.25, 0.0] A1loc = np.r_[31.25, 0.0] rxloc = np.c_[mesh.gridN, np.zeros(mesh.nN)] data_ana = analytics.DCAnalytic_Dipole_Pole( [np.r_[A0loc, 0.0], np.r_[A1loc, 0.0]], rxloc, sighalf, earth_type="halfspace", ) src0 = dc.sources.Dipole([], A0loc, A1loc) survey = dc.survey.Survey([src0]) # determine comparison locations ROI_large_BNW = np.array([-200, -100]) ROI_large_TSE = np.array([200, 0]) ROI_largeInds = utils.model_builder.getIndicesBlock( ROI_large_BNW, ROI_large_TSE, mesh.gridN )[0] # print(ROI_largeInds.shape) ROI_small_BNW = np.array([-50, -25]) ROI_small_TSE = np.array([50, 0]) ROI_smallInds = utils.model_builder.getIndicesBlock( ROI_small_BNW, ROI_small_TSE, mesh.gridN )[0] # print(ROI_smallInds.shape) ROI_inds = np.setdiff1d(ROI_largeInds, ROI_smallInds) self.data_ana = data_ana self.survey = survey self.mesh = mesh self.sigma = sigma self.plotIt = False self.ROI_inds = ROI_inds try: from pymatsolver import PardisoSolver self.solver = PardisoSolver except ImportError: self.solver = SolverLU
def get_problem_survey(self, nx=20, ny=20, dx=10, dy=20): hx = np.ones(nx) * dx hy = np.ones(ny) * dy self._mesh_prop = TensorMesh([hx, hy]) y = np.linspace(0, 400, 10) self._source_locations_prop = np.c_[y * 0 + self._mesh_prop.vectorCCx[0], y] self._receiver_locations_prop = np.c_[y * 0 + self._mesh_prop.vectorCCx[-1], y] rx = survey.BaseRx(self._receiver_locations_prop) srcList = [ survey.BaseSrc(location=self._source_locations_prop[i, :], receiver_list=[rx]) for i in range(y.size) ] self._survey_prop = seismic.survey.StraightRaySurvey(srcList) self._simulation_prop = seismic.simulation.Simulation2DIntegral( survey=self._survey_prop, mesh=self._mesh_prop, slownessMap=maps.IdentityMap(self._mesh_prop)) self._data_prop = data.Data(self._survey_prop)
def setUp(self): npad = 10 cs = 12.5 hx = [(cs, npad, -1.4), (cs, 61), (cs, npad, 1.4)] hy = [(cs, npad, -1.4), (cs, 20)] mesh = TensorMesh([hx, hy], x0="CN") sighalf = 1e-2 sigma = np.ones(mesh.nC) * sighalf x = mesh.cell_centers_x[ np.logical_and(mesh.cell_centers_x > -150, mesh.cell_centers_x < 250) ] M = utils.ndgrid(x, np.r_[0.0]) N = utils.ndgrid(x + 12.5 * 4, np.r_[0.0]) A0loc = np.r_[-200, 0.0] A1loc = np.r_[-250, 0.0] rxloc = [np.c_[M, np.zeros(x.size)], np.c_[N, np.zeros(x.size)]] data_ana_A = analytics.DCAnalytic_Pole_Dipole( np.r_[A0loc, 0.0], rxloc, sighalf, earth_type="halfspace" ) data_ana_b = analytics.DCAnalytic_Pole_Dipole( np.r_[A1loc, 0.0], rxloc, sighalf, earth_type="halfspace" ) data_ana = data_ana_A - data_ana_b rx = dc.receivers.Dipole(M, N) src0 = dc.sources.Dipole([rx], A0loc, A1loc) survey = dc.Survey([src0]) self.survey = survey self.mesh = mesh self.sigma = sigma self.data_ana = data_ana self.plotIt = False try: from pymatsolver import Pardiso self.solver = Pardiso except ImportError: self.solver = SolverLU
def plot_model_only(self, m_background=0.0, m1=1.0, m1_center=0.2, dm1=0.2, m2=2.0, m2_center=0.75, sigma_2=0.07, M=100): self.M = M self.m_background = m_background self.m1 = m1 self.m2 = m2 self.m1_center = m1_center self.dm1 = dm1 self.m2_center = m2_center self.sigma_2 = sigma_2 self._mesh_prop = TensorMesh([self.M]) m = self.set_model( m_background=m_background, m1=m1, m2=m2, m1_center=m1_center, dm1=dm1, m2_center=m2_center, sigma_2=sigma_2, ) fig = plt.figure() ax = plt.subplot(111) ax.plot(self.mesh_prop.vectorCCx, m) ax.set_ylim([-2.5, 2.5]) ax.set_title("Model") ax.set_xlabel("x") ax.set_ylabel("m(x)") plt.show() if self.return_axis: return ax
def set_G(self, N=20, M=100, p=-0.25, q=0.25, j1=1, jn=60): """ Parameters ---------- N: # of data M: # of model parameters ... """ self.N = N self.M = M self._mesh = TensorMesh([M]) jk = np.linspace(j1, jn, N) self._G = np.zeros((N, self.mesh.nC), dtype=float, order="C") def g(k): return np.exp(p * jk[k] * self.mesh.vectorCCx) * np.cos( np.pi * q * jk[k] * self.mesh.vectorCCx) for i in range(N): self._G[i, :] = g(i) * self.mesh.hx self._jk = jk
def test_depth_weighting_2D(self): # Mesh dh = 5.0 hx = [(dh, 5, -1.3), (dh, 40), (dh, 5, 1.3)] hz = [(dh, 15)] mesh = TensorMesh([hx, hz], "CN") actv = np.random.randint(0, 2, mesh.n_cells) == 1 r_loc = 0.1 # Depth weighting wz = utils.depth_weighting(mesh, r_loc, indActive=actv, exponent=5, threshold=0) reference_locs = ( np.random.rand(1000, 2) * (mesh.nodes.max(axis=0) - mesh.nodes.min(axis=0)) + mesh.origin ) reference_locs[:, -1] = r_loc wz2 = utils.depth_weighting( mesh, reference_locs, indActive=actv, exponent=5, threshold=0 ) np.testing.assert_allclose(wz, wz2)
def setUp(self): # Note: Pole-Pole requires bigger boundary to obtain good accuracy. # One can use greater padding rate. Here 2 is used. npad = 10 cs = 12.5 hx = [(cs, npad, -2), (cs, 61), (cs, npad, 2)] hy = [(cs, npad, -2), (cs, 20)] mesh = TensorMesh([hx, hy], x0="CN") sighalf = 1e-2 sigma = np.ones(mesh.nC) * sighalf x = mesh.cell_centers_x[ np.logical_and(mesh.cell_centers_x > -150, mesh.cell_centers_x < 250) ] M = utils.ndgrid(x, np.r_[0.0]) # N = utils.ndgrid(x + 12.5*4, np.r_[0.0]) A0loc = np.r_[-200, 0.0] # A1loc = np.r_[-250, 0.0] rxloc = np.c_[M, np.zeros(x.size)] data_ana = analytics.DCAnalytic_Pole_Pole( np.r_[A0loc, 0.0], rxloc, sighalf, earth_type="halfspace" ) rx = dc.receivers.Pole(M) src0 = dc.sources.Pole([rx], A0loc) survey = dc.survey.Survey([src0]) self.survey = survey self.mesh = mesh self.sigma = sigma self.data_ana = data_ana try: from pymatsolver import PardisoSolver self.solver = PardisoSolver except ImportError: self.solver = SolverLU
def setUp(self): dh = 1.0 nx = 12 ny = 12 hx = [(dh, nx)] hy = [(dh, ny)] mesh = TensorMesh([hx, hy], "CN") # reg actv = np.ones(len(mesh), dtype=bool) # maps wires = maps.Wires(("m1", mesh.nC), ("m2", mesh.nC)) corr = regularization.LinearCorrespondence( mesh, wire_map=wires, indActive=actv, ) self.mesh = mesh self.corr = corr
def test_depth_weighting_3D(self): # Mesh dh = 5.0 hx = [(dh, 5, -1.3), (dh, 40), (dh, 5, 1.3)] hy = [(dh, 5, -1.3), (dh, 40), (dh, 5, 1.3)] hz = [(dh, 15)] mesh = TensorMesh([hx, hy, hz], "CCN") actv = np.random.randint(0, 2, mesh.n_cells) == 1 r_loc = 0.1 # Depth weighting wz = utils.depth_weighting(mesh, r_loc, indActive=actv, exponent=5, threshold=0) reference_locs = ( np.random.rand(1000, 3) * (mesh.nodes.max(axis=0) - mesh.nodes.min(axis=0)) + mesh.origin ) reference_locs[:, -1] = r_loc wz2 = utils.depth_weighting( mesh, reference_locs, indActive=actv, exponent=5, threshold=0 ) np.testing.assert_allclose(wz, wz2) # testing default params all_active = np.ones(mesh.n_cells, dtype=bool) wz = utils.depth_weighting( mesh, r_loc, indActive=all_active, exponent=2, threshold=0.5 * dh ) wz2 = utils.depth_weighting(mesh, r_loc) np.testing.assert_allclose(wz, wz2) with self.assertRaises(ValueError): wz2 = utils.depth_weighting(mesh, np.random.rand(10, 3, 3))
def set_G(self, N=20, M=100, pmin=-0.25, pmax=-15, qmin=0.25, qmax=15): """ Parameters ---------- N: # of data M: # of model parameters ... """ self.N = N self.M = M self._mesh_prop = TensorMesh([M]) p_values = np.linspace(pmin, pmax, N) q_values = np.linspace(qmin, qmax, N) self._G = np.zeros((N, self.mesh_prop.nC), dtype=float, order="C") def g(k): return np.exp(p_values[k] * self.mesh_prop.vectorCCx) * np.cos( 2 * np.pi * q_values[k] * self.mesh_prop.vectorCCx) for i in range(N): self._G[i, :] = g(i) * self.mesh_prop.hx self._p_values = p_values self._q_values = q_values
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]
class MagneticDipoleApp(object): """docstring for MagneticDipoleApp""" mesh = None component = None z = None inclination = None declination = None length = None dx = None moment = None depth = None data = None profile = None xy_profile = None clim = None def __init__(self): super(MagneticDipoleApp, self).__init__() def id_to_cartesian(self, inclination, declination): ux = np.cos(inclination / 180.0 * np.pi) * np.sin( declination / 180.0 * np.pi) uy = np.cos(inclination / 180.0 * np.pi) * np.cos( declination / 180.0 * np.pi) uz = -np.sin(inclination / 180.0 * np.pi) return np.r_[ux, uy, uz] def dot_product(self, b_vec, orientation): b_tmi = np.dot(b_vec, orientation) return b_tmi 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_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 = TensorMesh((hx, hy), "CC") z = np.r_[1.0] 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.0) 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] def get_prism(self, dx, dy, dz, x0, y0, elev, prism_inc, prism_dec): prism = definePrism() prism.dx, prism.dy, prism.dz, prism.z0 = dy, dx, dz, elev prism.x0, prism.y0 = x0, y0 prism.pinc, prism.pdec = prism_inc, prism_dec return prism def plot_prism(self, prism, dip=30, azim=310): return plotObj3D(prism, self.survey, dip, azim, self.mesh.vectorCCx.max()) 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 plot_map(self): length = self.length data = self.data profile = self.profile fig = plt.figure(figsize=(5, 6)) ax1 = plt.subplot2grid((8, 4), (0, 0), rowspan=5, colspan=3) ax2 = plt.subplot2grid((8, 4), (6, 0), rowspan=2, colspan=3) if (self.clim is None) or (not self.fixed_scale): self.clim = data.min(), data.max() out = self.mesh.plotImage(self.data, pcolorOpts={"cmap": "jet"}, ax=ax1, clim=self.clim) cax = fig.add_axes([0.75, 0.45, 0.02, 0.5]) ratio = abs(self.clim[0] / self.clim[1]) if ratio < 0.05: ticks = [self.clim[0], self.clim[1]] else: ticks = [self.clim[0], 0, self.clim[1]] cb = plt.colorbar(out[0], ticks=ticks, format="%.3f", cax=cax) cb.set_label("nT", labelpad=-40, y=-0.05, rotation=0) ax1.set_aspect(1) ax1.set_ylabel("Northing") ax1.set_xlabel("Easting") if profile == "North": # xy_profile = np.c_[np.zeros(self.mesh.nCx), self.mesh.vectorCCx] ax1.text(1, length / 2 - length / 2 * 0.1, "B", color="w") ax1.text(1, -length / 2, "A", color="w") elif profile == "East": # xy_profile = np.c_[self.mesh.vectorCCx, np.zeros(self.mesh.nCx)] ax1.text(length / 2 - length / 2 * 0.1, 1, "B", color="w") ax1.text(-length / 2, 1, "A", color="w") ax1.set_xticks([]) ax1.set_yticks([]) ax2.yaxis.tick_right() ax2.plot(self.mesh.vectorCCx, self.data_profile, "k", lw=2) ax2.plot(self.mesh.vectorCCx, np.zeros(self.mesh.nCx), "k--", color="grey", lw=1) ax2.set_xlim(-self.length / 2.0, self.length / 2.0) ymin, ymax = ax2.get_ylim() ax2.text(-self.length / 2.0, ymax, "A") ax2.text(self.length / 2.0 - self.length / 2 * 0.05, ymax, "B") ax2.set_yticks([self.clim[0], self.clim[1]]) if self.show_halfwidth: x_half, data_half = self.get_half_width() ax2.plot(x_half, data_half, "bo--") ax2.set_xlabel(("Halfwidth: %.1fm") % (abs(np.diff(x_half)))) else: ax2.set_xlabel(" ") # plt.tight_layout() if profile == "None": ax2.remove() else: ax1.plot(self.xy_profile[:, 0], self.xy_profile[:, 1], "w") def get_half_width(self, n_points=200): ind_max = np.argmax(abs(self.data_profile)) A_half = self.data_profile[ind_max] / 2.0 if self.profile == "North": x = self.xy_profile[:, 1] else: x = self.xy_profile[:, 0] f = interp1d(x, self.data_profile) x_int = np.linspace(x.min(), x.max(), n_points) data_profile_int = f(x_int) inds = np.argsort(abs(data_profile_int - A_half)) ind_first = inds[0] for ind in inds: dx = abs(x_int[ind_first] - x_int[ind]) if dx > self.dx: ind_second = ind break inds = [ind_first, ind_second] return x_int[inds], data_profile_int[inds] def magnetic_dipole_applet( self, component, target, inclination, declination, length, dx, moment, depth, profile, fixed_scale, show_halfwidth, ): self.simulate_dipole( component, target, inclination, declination, length, dx, moment, depth, profile, fixed_scale, show_halfwidth, ) self.plot_map() def magnetic_two_monopole_applet( self, component, inclination, declination, length, dx, moment, depth_n, depth_p, profile, fixed_scale, show_halfwidth, ): self.simulate_two_monopole( component, inclination, declination, length, dx, moment, depth_n, depth_p, profile, fixed_scale, show_halfwidth, ) self.plot_map() def magnetic_prism_applet( self, plot, component, inclination, declination, length, dx, B0, kappa, depth, profile, fixed_scale, show_halfwidth, prism_dx, prism_dy, prism_dz, prism_inclination, prism_declination, ): if plot == "field": self.simulate_prism( component, inclination, declination, length, dx, B0, kappa, depth, profile, fixed_scale, show_halfwidth, prism_dx, prism_dy, prism_dz, prism_inclination, prism_declination, ) self.plot_map() elif plot == "model": self.prism = self.get_prism( prism_dx, prism_dy, prism_dz, 0, 0, -depth, prism_inclination, prism_declination, ) self.plot_prism(self.prism) def interact_plot_model_dipole(self): component = widgets.RadioButtons( options=["Bt", "Bx", "By", "Bz", "Bg"], value="Bt", description="field", disabled=False, ) target = widgets.RadioButtons( options=["Dipole", "Monopole (+)", "Monopole (-)"], value="Dipole", description="target", disabled=False, ) inclination = widgets.FloatSlider(description="I", continuous_update=False, min=-90, max=90, step=1, value=90) declination = widgets.FloatSlider(description="D", continuous_update=False, min=-180, max=180, step=1, value=0) length = widgets.FloatSlider( description="length", continuous_update=False, min=2, max=200, step=1, value=72, ) dx = widgets.FloatSlider( description="data spacing", continuous_update=False, min=0.1, max=15, step=0.1, value=2, ) moment = widgets.FloatText(description="M", value=30) depth = widgets.FloatSlider( description="depth", continuous_update=False, min=0, max=50, step=1, value=10, ) profile = widgets.RadioButtons( options=["East", "North", "None"], value="East", description="profile", disabled=False, ) fixed_scale = widgets.Checkbox(value=False, description="fixed scale", disabled=False) show_halfwidth = widgets.Checkbox(value=False, description="half width", disabled=False) out = widgets.interactive_output( self.magnetic_dipole_applet, { "component": component, "target": target, "inclination": inclination, "declination": declination, "length": length, "dx": dx, "moment": moment, "depth": depth, "profile": profile, "fixed_scale": fixed_scale, "show_halfwidth": show_halfwidth, }, ) left = widgets.VBox( [component, profile], layout=Layout(width="20%", height="400px", margin="60px 0px 0px 0px"), ) right = widgets.VBox( [ target, inclination, declination, length, dx, moment, depth, fixed_scale, show_halfwidth, ], layout=Layout(width="50%", height="400px", margin="20px 0px 0px 0px"), ) widgets.VBox([out], layout=Layout(width="70%", height="400px", margin="0px 0px 0px 0px")) return widgets.HBox([left, out, right]) def interact_plot_model_two_monopole(self): component = widgets.RadioButtons( options=["Bt", "Bx", "By", "Bz", "Bg"], value="Bt", description="field", disabled=False, ) inclination = widgets.FloatSlider(description="I", continuous_update=False, min=-90, max=90, step=1, value=90) declination = widgets.FloatSlider(description="D", continuous_update=False, min=-180, max=180, step=1, value=0) length = widgets.FloatSlider( description="length", continuous_update=False, min=2, max=200, step=1, value=10, ) dx = widgets.FloatSlider( description="data spacing", continuous_update=False, min=0.1, max=15, step=0.1, value=0.1, ) moment = widgets.FloatText(description="M", value=30) depth_n = widgets.FloatSlider( description="depth$_{-Q}$", continuous_update=False, min=0, max=200, step=1, value=0, ) depth_p = widgets.FloatSlider( description="depth$_{+Q}$", continuous_update=False, min=0, max=200, step=1, value=1, ) profile = widgets.RadioButtons( options=["East", "North", "None"], value="East", description="profile", disabled=False, ) fixed_scale = widgets.Checkbox(value=False, description="fixed scale", disabled=False) show_halfwidth = widgets.Checkbox(value=False, description="half width", disabled=False) out = widgets.interactive_output( self.magnetic_two_monopole_applet, { "component": component, "inclination": inclination, "declination": declination, "length": length, "dx": dx, "moment": moment, "depth_n": depth_n, "depth_p": depth_p, "profile": profile, "fixed_scale": fixed_scale, "show_halfwidth": show_halfwidth, }, ) left = widgets.VBox( [component, profile], layout=Layout(width="20%", height="400px", margin="60px 0px 0px 0px"), ) right = widgets.VBox( [ inclination, declination, length, dx, moment, depth_n, depth_p, fixed_scale, show_halfwidth, ], layout=Layout(width="50%", height="400px", margin="20px 0px 0px 0px"), ) widgets.VBox([out], layout=Layout(width="70%", height="400px", margin="0px 0px 0px 0px")) return widgets.HBox([left, out, right]) def interact_plot_model_prism(self): plot = widgets.RadioButtons( options=["field", "model"], value="field", description="plot", disabled=False, ) component = widgets.RadioButtons( options=["Bt", "Bx", "By", "Bz"], value="Bt", description="field", disabled=False, ) inclination = widgets.FloatSlider(description="I", continuous_update=False, min=-90, max=90, step=1, value=90) declination = widgets.FloatSlider(description="D", continuous_update=False, min=-180, max=180, step=1, value=0) length = widgets.FloatSlider( description="length", continuous_update=False, min=2, max=200, step=1, value=72, ) dx = widgets.FloatSlider( description="data spacing", continuous_update=False, min=0.1, max=15, step=0.1, value=2, ) kappa = widgets.FloatText(description="$\kappa$", value=0.1) B0 = widgets.FloatText(description="B$_0$", value=56000) depth = widgets.FloatSlider( description="depth", continuous_update=False, min=0, max=50, step=1, value=10, ) profile = widgets.RadioButtons( options=["East", "North", "None"], value="East", description="profile", disabled=False, ) fixed_scale = widgets.Checkbox(value=False, description="fixed scale", disabled=False) show_halfwidth = widgets.Checkbox(value=False, description="half width", disabled=False) prism_dx = widgets.FloatText(description="$\\triangle x$", value=1) prism_dy = widgets.FloatText(description="$\\triangle y$", value=1) prism_dz = widgets.FloatText(description="$\\triangle z$", value=1) prism_inclination = widgets.FloatSlider( description="I$_{prism}$", continuous_update=False, min=-90, max=90, step=1, value=0, ) prism_declination = widgets.FloatSlider( description="D$_{prism}$", continuous_update=False, min=0, max=180, step=1, value=0, ) out = widgets.interactive_output( self.magnetic_prism_applet, { "plot": plot, "component": component, "inclination": inclination, "declination": declination, "length": length, "dx": dx, "kappa": kappa, "B0": B0, "depth": depth, "profile": profile, "fixed_scale": fixed_scale, "show_halfwidth": show_halfwidth, "prism_dx": prism_dx, "prism_dy": prism_dy, "prism_dz": prism_dz, "prism_inclination": prism_inclination, "prism_declination": prism_declination, }, ) left = widgets.VBox( [plot, component, profile], layout=Layout(width="20%", height="400px", margin="60px 0px 0px 0px"), ) right = widgets.VBox( [ inclination, declination, length, dx, B0, kappa, depth, prism_dx, prism_dy, prism_dz, prism_inclination, prism_declination, fixed_scale, show_halfwidth, ], layout=Layout(width="50%", height="400px", margin="20px 0px 0px 0px"), ) widgets.VBox([out], layout=Layout(width="70%", height="400px", margin="0px 0px 0px 0px")) return widgets.HBox([left, out, right])
else: raise ValueError('Invalid component') if nSrc == 1: return A.flatten() return A if __name__ == '__main__': from SimPEG import Mesh import matplotlib.pyplot as plt cs = 20 ncx, ncy, ncz = 41, 41, 40 hx = np.ones(ncx)*cs hy = np.ones(ncy)*cs hz = np.ones(ncz)*cs mesh = TensorMesh([hx, hy, hz], 'CCC') srcLoc = np.r_[0., 0., 0.] Ax = MagneticLoopVectorPotential(srcLoc, mesh.gridEx, 'x', 200) Ay = MagneticLoopVectorPotential(srcLoc, mesh.gridEy, 'y', 200) Az = MagneticLoopVectorPotential(srcLoc, mesh.gridEz, 'z', 200) A = np.r_[Ax, Ay, Az] B0 = mesh.edgeCurl*A J0 = mesh.edgeCurl.T*B0 # mesh.plotImage(A, vType = 'Ex') # mesh.plotImage(A, vType = 'Ey') mesh.plotImage(B0, vType = 'Fx') mesh.plotImage(B0, vType = 'Fy') mesh.plotImage(B0, vType = 'Fz')