def dotest(MYSOLVER, multi=False, A=None, **solverOpts): if A is None: h1 = np.ones(10) * 100.0 h2 = np.ones(10) * 100.0 h3 = np.ones(10) * 100.0 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 = 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): # 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 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 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 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 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 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 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 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 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 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 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]
data_object = data.Data(survey, dobs=dobs, standard_deviation=uncertainties) ############################################# # Defining a Tensor Mesh # ---------------------- # # Here, we create the tensor mesh that will be used to invert gravity anomaly # data. If desired, we could define an OcTree 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, 5, -1.3), (dh, 15)] mesh = TensorMesh([hx, hy, hz], "CCN") ######################################################## # Starting/Reference Model and Mapping on Tensor Mesh # --------------------------------------------------- # # Here, we create starting and/or reference models for the inversion as # well as the mapping from the model space to the active cells. Starting and # reference models can be a constant background value or contain a-priori # structures. Here, the background is 1e-6 g/cc. # # Define density contrast values for each unit in g/cc. Don't make this 0! # Otherwise the gradient for the 1st iteration is zero and the inversion will # not converge. background_density = 1e-6
def set_mesh( self, topo=None, dx=None, dy=None, dz=None, corezlength=None, npad_x=None, npad_y=None, npad_z=None, pad_rate_x=None, pad_rate_y=None, pad_rate_z=None, ncell_per_dipole=None, mesh_type="TensorMesh", dimension=2, method="nearest", ): """ Set up a mesh for a given DC survey """ # Update properties if npad_x is None: npad_x = self.npad_x self.npad_x = npad_x if npad_z is None: npad_z = self.npad_z self.npad_z = npad_z if pad_rate_x is None: pad_rate_x = self.pad_rate_x self.pad_rate_x = pad_rate_x if pad_rate_z is None: pad_rate_z = self.pad_rate_z self.pad_rate_z = pad_rate_z if ncell_per_dipole is None: ncell_per_dipole = self.ncell_per_dipole self.ncell_per_dipole = ncell_per_dipole # 2D or 3D mesh if dimension not in [2, 3]: raise NotImplementedError( "Set mesh has not been implemented for a 1D system") if dimension == 2: z_ind = 1 else: z_ind = 2 a = abs(np.diff(np.sort(self.electrode_locations[:, 0]))).min() lineLength = abs(self.electrode_locations[:, 0].max() - self.electrode_locations[:, 0].min()) dx_ideal = a / ncell_per_dipole if dx is None: dx = dx_ideal print("dx is set to {} m (samllest electrode spacing ({}) / {})". format(dx, a, ncell_per_dipole)) if dz is None: dz = dx * 0.5 print("dz ({} m) is set to dx ({} m) / {}".format(dz, dx, 2)) if dimension == 3: if dy is None: print("dy is set equal to dx") dy = dx self.dy = dy if npad_y is None: npad_y = self.npad_y self.npad_y = npad_y if pad_rate_y is None: pad_rate_y = self.pad_rate_y self.pad_rate_y = pad_rate_y x0 = self.electrode_locations[:, 0].min() if topo is None: # For 2D mesh if dimension == 2: # sort by x row_idx = np.lexsort((self.electrode_locations[:, 0], )) # For 3D mesh else: # sort by x, then by y row_idx = np.lexsort( (self.electrode_locations[:, 1], self.electrode_locations[:, 0])) locs = self.electrode_locations[row_idx, :] else: # For 2D mesh if dimension == 2: mask = np.isin(self.electrode_locations[:, 0], topo[:, 0]) if np.any(mask): warnings.warn( "Because the x coordinates of some topo and electrodes are the same," " we excluded electrodes with the same coordinates.", RuntimeWarning, ) locs_tmp = np.vstack( (topo, self.electrode_locations[~mask, :])) row_idx = np.lexsort((locs_tmp[:, 0], )) else: dtype = [("x", np.float64), ("y", np.float64)] mask = np.isin( self.electrode_locations[:, [0, 1]].copy().view(dtype), topo[:, [0, 1]].copy().view(dtype), ).flatten() if np.any(mask): warnings.warn( "Because the x and y coordinates of some topo and electrodes are the same," " we excluded electrodes with the same coordinates.", RuntimeWarning, ) locs_tmp = np.vstack( (topo, self.electrode_locations[~mask, :])) row_idx = np.lexsort((locs_tmp[:, 1], locs_tmp[:, 0])) locs = locs_tmp[row_idx, :] if dx > dx_ideal: # warnings.warn( # "Input dx ({}) is greater than expected \n We recommend using {:0.1e} m cells, that is, {} cells per {0.1e} m dipole length".format(dx, dx_ideal, ncell_per_dipole, a) # ) pass # Set mesh properties to class instance self.dx = dx self.dz = dz zmax = locs[:, z_ind].max() zmin = locs[:, z_ind].min() # 3 cells each for buffer corexlength = lineLength + dx * 6 if corezlength is None: dz_topo = locs[:, 1].max() - locs[:, 1].min() corezlength = self.grids[:, z_ind].max() + dz_topo self.corezlength = corezlength if mesh_type == "TensorMesh": ncx = np.round(corexlength / dx) ncz = np.round(corezlength / dz) hx = [(dx, npad_x, -pad_rate_x), (dx, ncx), (dx, npad_x, pad_rate_x)] hz = [(dz, npad_z, -pad_rate_z), (dz, ncz)] x0_mesh = -( (dx * pad_rate_x**(np.arange(npad_x) + 1)).sum() + dx * 3 - x0) z0_mesh = (-( (dz * pad_rate_z**(np.arange(npad_z) + 1)).sum() + dz * ncz) + zmax) # For 2D mesh if dimension == 2: h = [hx, hz] x0_for_mesh = [x0_mesh, z0_mesh] self.xyzlim = np.vstack( (np.r_[x0, x0 + lineLength], np.r_[zmax - corezlength, zmax])) fill_value = "extrapolate" # For 3D mesh else: ylocs = np.unique(self.electrode_locations[:, 1]) ymin, ymax = ylocs.min(), ylocs.max() # 3 cells each for buffer in y-direction coreylength = ymax - ymin + dy * 6 ncy = np.round(coreylength / dy) hy = [(dy, npad_y, -pad_rate_y), (dy, ncy), (dy, npad_y, pad_rate_y)] y0 = ylocs.min() - dy / 2.0 y0_mesh = -((dy * pad_rate_y**(np.arange(npad_y) + 1)).sum() + dy * 3 - y0) h = [hx, hy, hz] x0_for_mesh = [x0_mesh, y0_mesh, z0_mesh] self.xyzlim = np.vstack(( np.r_[x0, x0 + lineLength], np.r_[ymin - dy * 3, ymax + dy * 3], np.r_[zmax - corezlength, zmax], )) mesh = TensorMesh(h, x0=x0_for_mesh) elif mesh_type == "TREE": # Quadtree mesh if dimension == 2: pad_length_x = np.sum(meshTensor([(dx, npad_x, pad_rate_x)])) pad_length_z = np.sum(meshTensor([(dz, npad_z, pad_rate_z)])) dom_width_x = lineLength + 2 * pad_length_x # domain width x dom_width_z = corezlength + pad_length_z # domain width z nbcx = 2**int(np.ceil(np.log(dom_width_x / dx) / np.log(2.0))) # num. base cells x nbcz = 2**int(np.ceil(np.log(dom_width_z / dz) / np.log(2.0))) # num. base cells z length = 0.0 dz_tmp = dz octree_levels = [] while length < corezlength: length += 5 * dz_tmp octree_levels.append(5) dz_tmp *= 2 # Define the base mesh hx = [(dx, nbcx)] hz = [(dz, nbcz)] mesh_width = np.sum(meshTensor(hx)) mesh_height = np.sum(meshTensor(hz)) array_midpoint = 0.5 * (self.electrode_locations[:, 0].min() + self.electrode_locations[:, 0].max()) mesh = TreeMesh( [hx, hz], x0=[array_midpoint - mesh_width / 2, zmax - mesh_height]) # mesh = TreeMesh([hx, hz], x0='CN') # Mesh refinement based on topography mesh = refine_tree_xyz( mesh, self.electrode_locations, octree_levels=octree_levels, method="radial", finalize=False, ) mesh.finalize() self.xyzlim = np.vstack(( np.r_[self.electrode_locations[:, 0].min(), self.electrode_locations[:, 0].max(), ], np.r_[zmax - corezlength, zmax], )) # Octree mesh elif dimension == 3: raise NotImplementedError( "set_mesh has not implemented 3D TreeMesh (yet)") else: raise NotImplementedError( "set_mesh currently generates TensorMesh or TreeMesh") actind = surface2ind_topo(mesh, locs, method=method, fill_value=np.nan) return mesh, actind
# Define layer resistivities. model = np.r_[1e3, 4e3, 2e2] # Define mapping from model to 1D layers. model_map = maps.IdentityMap(nP=len(model)) ############################################################### # Plot Resistivity Model # ---------------------- # # Here we plot the 1D resistivity model. # # Define a 1D mesh for plotting. Provide a maximum depth for the plot. max_depth = 500 mesh = TensorMesh( [np.r_[layer_thicknesses, max_depth - layer_thicknesses.sum()]]) # Plot the 1D model plot_layer(model_map * model, mesh) ####################################################################### # Define the Forward Simulation and Predict DC Resistivity Data # ------------------------------------------------------------- # # Here we predict DC resistivity data. If the keyword argument *rhoMap* is # defined, the simulation will expect a resistivity model. If the keyword # argument *sigmaMap* is defined, the simulation will expect a conductivity model. # simulation = dc.simulation_1d.Simulation1DLayers( survey=survey,
) # sphinx_gallery_thumbnail_number = 3 ############################################# # Defining the Model and Mapping # ------------------------------ # # Here we generate a synthetic model and a mappig which goes from the model # space to the row space of our linear operator. # nParam = 100 # Number of model paramters # A 1D mesh is used to define the row-space of the linear operator. mesh = TensorMesh([nParam]) # 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 # Mapping from the model space to the row space of the linear operator model_map = maps.IdentityMap(mesh) # Plotting the true model fig = plt.figure(figsize=(8, 5)) ax = fig.add_subplot(111) ax.plot(mesh.vectorCCx, true_model, "b-") ax.set_ylim([-2, 2])