def generateSurvey(rx, tx, min_dipole_size, max_dipole_size): """ Generates a survey to through into a forward model INPUT: rx_dx = array of Rx x spacings rx_dy = array of Rx y spacings Tx_dx = array of Tx x spacings Tx_dy = array of Tx y spacings """ SrcList = [] rx_length = rx.shape[0] for idk in range(tx.shape[0]): rx1 = [] rx2 = [] for idx in range(rx_length): node1 = rx[idx, :] for idj in range(idx, rx_length): node2 = rx[idj, :] dist = np.sqrt(np.sum((node1 - node2)**2)) distE = np.abs(node1[0] - tx[idk, 0]) if distE < 350: if (min_dipole_size) < dist < (max_dipole_size): rx1.append(node1) rx2.append(node2) # print(dist) rx1 = np.asarray(rx1) rx2 = np.asarray(rx2) rxClass = DC.Rx.Dipole(rx1, rx2) srcClass = DC.Src.Pole([rxClass], tx[idk, :]) SrcList.append(srcClass) survey = DC.Survey(SrcList) return survey
def run(plotIt=True, survey_type="dipole-dipole"): np.random.seed(1) # Initiate I/O class for DC IO = DC.IO() # Obtain ABMN locations xmin, xmax = 0., 200. ymin, ymax = 0., 0. zmin, zmax = 0, 0 endl = np.array([[xmin, ymin, zmin], [xmax, ymax, zmax]]) # Generate DC survey object survey = DC.Utils.gen_DCIPsurvey(endl, survey_type=survey_type, dim=2, a=10, b=10, n=10) survey.getABMN_locations() survey = IO.from_ambn_locations_to_survey(survey.a_locations, survey.b_locations, survey.m_locations, survey.n_locations, survey_type, data_dc_type='volt') # Obtain 2D TensorMesh mesh, actind = IO.set_mesh() topo, mesh1D = DC.Utils.genTopography(mesh, -10, 0, its=100) print(topo)
def setUp(self): self.plotIt = False np.random.seed(1) # Initiate I/O class for DC self.IO = DC.IO() # Obtain ABMN locations xmin, xmax = 0., 200. ymin, ymax = 0., 0. zmin, zmax = 0, 0 self.endl = np.array([[xmin, ymin, zmin], [xmax, ymax, zmax]])
def run(plotIt=True, survey_type="dipole-dipole", p=0., qx=2., qz=2.): np.random.seed(1) # Initiate I/O class for DC IO = DC.IO() # Obtain ABMN locations xmin, xmax = 0., 200. ymin, ymax = 0., 0. zmin, zmax = 0, 0 endl = np.array([[xmin, ymin, zmin], [xmax, ymax, zmax]]) # Generate DC survey object survey = DC.Utils.gen_DCIPsurvey(endl, survey_type=survey_type, dim=2, a=10, b=10, n=10) survey.getABMN_locations() survey = IO.from_ambn_locations_to_survey(survey.a_locations, survey.b_locations, survey.m_locations, survey.n_locations, survey_type, data_dc_type='volt') # Obtain 2D TensorMesh mesh, actind = IO.set_mesh() topo, mesh1D = DC.Utils.genTopography(mesh, -10, 0, its=100) actind = Utils.surface2ind_topo(mesh, np.c_[mesh1D.vectorCCx, topo]) survey.drapeTopo(mesh, actind, option="top") # Build a conductivity model blk_inds_c = Utils.ModelBuilder.getIndicesSphere(np.r_[60., -25.], 12.5, mesh.gridCC) blk_inds_r = Utils.ModelBuilder.getIndicesSphere(np.r_[140., -25.], 12.5, mesh.gridCC) layer_inds = mesh.gridCC[:, 1] > -5. sigma = np.ones(mesh.nC) * 1. / 100. sigma[blk_inds_c] = 1. / 10. sigma[blk_inds_r] = 1. / 1000. sigma[~actind] = 1. / 1e8 rho = 1. / sigma # Show the true conductivity model if plotIt: fig = plt.figure(figsize=(12, 3)) ax = plt.subplot(111) temp = rho.copy() temp[~actind] = np.nan out = mesh.plotImage(temp, grid=True, ax=ax, gridOpts={'alpha': 0.2}, clim=(10, 1000), pcolorOpts={ "cmap": "viridis", "norm": colors.LogNorm() }) ax.plot(survey.electrode_locations[:, 0], survey.electrode_locations[:, 1], 'k.') ax.set_xlim(IO.grids[:, 0].min(), IO.grids[:, 0].max()) ax.set_ylim(-IO.grids[:, 1].max(), IO.grids[:, 1].min()) cb = plt.colorbar(out[0]) cb.set_label("Resistivity (ohm-m)") ax.set_aspect('equal') plt.show() # Use Exponential Map: m = log(rho) actmap = Maps.InjectActiveCells(mesh, indActive=actind, valInactive=np.log(1e8)) mapping = Maps.ExpMap(mesh) * actmap # Generate mtrue mtrue = np.log(rho[actind]) # Generate 2.5D DC problem # "N" means potential is defined at nodes prb = DC.Problem2D_N(mesh, rhoMap=mapping, storeJ=True, Solver=Solver, verbose=True) # Pair problem with survey try: prb.pair(survey) except: survey.unpair() prb.pair(survey) # Make synthetic DC data with 5% Gaussian noise dtrue = survey.makeSyntheticData(mtrue, std=0.05, force=True) IO.data_dc = dtrue # Show apparent resisitivty pseudo-section if plotIt: IO.plotPseudoSection(data=survey.dobs / IO.G, data_type='apparent_resistivity') # Show apparent resisitivty histogram if plotIt: fig = plt.figure() out = hist(survey.dobs / IO.G, bins=20) plt.xlabel("Apparent Resisitivty ($\Omega$m)") plt.show() # Set initial model based upon histogram m0 = np.ones(actmap.nP) * np.log(100.) # Set uncertainty # floor eps = 10**(-3.2) # percentage std = 0.05 dmisfit = DataMisfit.l2_DataMisfit(survey) uncert = abs(survey.dobs) * std + eps dmisfit.W = 1. / uncert # Map for a regularization regmap = Maps.IdentityMap(nP=int(actind.sum())) # Related to inversion reg = Regularization.Sparse(mesh, indActive=actind, mapping=regmap, gradientType='components') # gradientType = 'components' reg.norms = np.c_[p, qx, qz, 0.] IRLS = Directives.Update_IRLS(maxIRLSiter=20, minGNiter=1, betaSearch=False, fix_Jmatrix=True) opt = Optimization.InexactGaussNewton(maxIter=40) invProb = InvProblem.BaseInvProblem(dmisfit, reg, opt) beta = Directives.BetaSchedule(coolingFactor=5, coolingRate=2) betaest = Directives.BetaEstimate_ByEig(beta0_ratio=1e0) target = Directives.TargetMisfit() update_Jacobi = Directives.UpdatePreconditioner() inv = Inversion.BaseInversion(invProb, directiveList=[betaest, IRLS]) prb.counter = opt.counter = Utils.Counter() opt.LSshorten = 0.5 opt.remember('xc') # Run inversion mopt = inv.run(m0) rho_est = mapping * mopt rho_est_l2 = mapping * invProb.l2model rho_est[~actind] = np.nan rho_est_l2[~actind] = np.nan rho_true = rho.copy() rho_true[~actind] = np.nan # show recovered conductivity if plotIt: vmin, vmax = rho.min(), rho.max() fig, ax = plt.subplots(3, 1, figsize=(20, 9)) out1 = mesh.plotImage(rho_true, clim=(10, 1000), pcolorOpts={ "cmap": "viridis", "norm": colors.LogNorm() }, ax=ax[0]) out2 = mesh.plotImage(rho_est_l2, clim=(10, 1000), pcolorOpts={ "cmap": "viridis", "norm": colors.LogNorm() }, ax=ax[1]) out3 = mesh.plotImage(rho_est, clim=(10, 1000), pcolorOpts={ "cmap": "viridis", "norm": colors.LogNorm() }, ax=ax[2]) out = [out1, out2, out3] titles = ["True", "L2", ("L%d, Lx%d, Lz%d") % (p, qx, qz)] for i in range(3): ax[i].plot(survey.electrode_locations[:, 0], survey.electrode_locations[:, 1], 'kv') ax[i].set_xlim(IO.grids[:, 0].min(), IO.grids[:, 0].max()) ax[i].set_ylim(-IO.grids[:, 1].max(), IO.grids[:, 1].min()) cb = plt.colorbar(out[i][0], ax=ax[i]) cb.set_label("Resistivity ($\Omega$m)") ax[i].set_xlabel("Northing (m)") ax[i].set_ylabel("Elevation (m)") ax[i].set_aspect('equal') ax[i].set_title(titles[i]) plt.tight_layout() plt.show()
def run(plotIt=True, survey_type="dipole-dipole"): np.random.seed(1) # Initiate I/O class for DC IO = DC.IO() # Obtain ABMN locations xmin, xmax = 0., 200. ymin, ymax = 0., 0. zmin, zmax = 0, 0 endl = np.array([[xmin, ymin, zmin], [xmax, ymax, zmax]]) # Generate DC survey object survey_dc = DC.Utils.gen_DCIPsurvey(endl, survey_type=survey_type, dim=2, a=10, b=10, n=10) survey_dc.getABMN_locations() survey_dc = IO.from_ambn_locations_to_survey(survey_dc.a_locations, survey_dc.b_locations, survey_dc.m_locations, survey_dc.n_locations, survey_type, data_dc_type='volt', data_ip_type='volt') # Obtain 2D TensorMesh mesh, actind = IO.set_mesh() topo, mesh1D = DC.Utils.genTopography(mesh, -10, 0, its=100) actind = Utils.surface2ind_topo(mesh, np.c_[mesh1D.vectorCCx, topo]) survey_dc.drapeTopo(mesh, actind, option="top") # Build conductivity and chargeability model blk_inds_c = Utils.ModelBuilder.getIndicesSphere(np.r_[60., -25.], 12.5, mesh.gridCC) blk_inds_r = Utils.ModelBuilder.getIndicesSphere(np.r_[140., -25.], 12.5, mesh.gridCC) blk_inds_charg = Utils.ModelBuilder.getIndicesSphere( np.r_[100., -25], 12.5, mesh.gridCC) sigma = np.ones(mesh.nC) * 1. / 100. sigma[blk_inds_c] = 1. / 10. sigma[blk_inds_r] = 1. / 1000. sigma[~actind] = 1. / 1e8 rho = 1. / sigma charg = np.zeros(mesh.nC) charg[blk_inds_charg] = 0.1 # Show the true conductivity model if plotIt: fig, axs = plt.subplots(2, 1, figsize=(12, 6)) temp_rho = rho.copy() temp_rho[~actind] = np.nan temp_charg = charg.copy() temp_charg[~actind] = np.nan out1 = mesh.plotImage(temp_rho, grid=True, ax=axs[0], gridOpts={'alpha': 0.2}, clim=(10, 1000), pcolorOpts={ "cmap": "viridis", "norm": colors.LogNorm() }) out2 = mesh.plotImage(temp_charg, grid=True, ax=axs[1], gridOpts={'alpha': 0.2}, clim=(0, 0.1), pcolorOpts={"cmap": "magma"}) for i in range(2): axs[i].plot(survey_dc.electrode_locations[:, 0], survey_dc.electrode_locations[:, 1], 'kv') axs[i].set_xlim(IO.grids[:, 0].min(), IO.grids[:, 0].max()) axs[i].set_ylim(-IO.grids[:, 1].max(), IO.grids[:, 1].min()) axs[i].set_aspect('equal') cb = plt.colorbar(out1[0], ax=axs[0]) cb.set_label("Resistivity (ohm-m)") cb = plt.colorbar(out2[0], ax=axs[1]) cb.set_label("Chargeability") plt.show() # Use Exponential Map: m = log(rho) actmap = Maps.InjectActiveCells(mesh, indActive=actind, valInactive=np.log(1e8)) mapping = Maps.ExpMap(mesh) * actmap # Generate mtrue_dc for resistivity mtrue_dc = np.log(rho[actind]) # Generate 2.5D DC problem # "N" means potential is defined at nodes prb = DC.Problem2D_N(mesh, rhoMap=mapping, storeJ=True, Solver=Solver) # Pair problem with survey try: prb.pair(survey_dc) except: survey_dc.unpair() prb.pair(survey_dc) # Make synthetic DC data with 5% Gaussian noise dtrue_dc = survey_dc.makeSyntheticData(mtrue_dc, std=0.05, force=True) IO.data_dc = dtrue_dc # Generate mtrue_ip for chargability mtrue_ip = charg[actind] # Generate 2.5D DC problem # "N" means potential is defined at nodes prb_ip = IP.Problem2D_N(mesh, etaMap=actmap, storeJ=True, rho=rho, Solver=Solver) survey_ip = IP.from_dc_to_ip_survey(survey_dc, dim="2.5D") prb_ip.pair(survey_ip) dtrue_ip = survey_ip.makeSyntheticData(mtrue_ip, std=0.05) IO.data_ip = dtrue_ip # Show apparent resisitivty pseudo-section if plotIt: IO.plotPseudoSection(data_type='apparent_resistivity', scale='log', cmap='viridis') plt.show() # Show apparent chargeability pseudo-section if plotIt: IO.plotPseudoSection(data_type='apparent_chargeability', scale='linear', cmap='magma') plt.show() # Show apparent resisitivty histogram if plotIt: fig = plt.figure(figsize=(10, 4)) ax1 = plt.subplot(121) out = hist(np.log10(abs(IO.voltages)), bins=20) ax1.set_xlabel("log10 DC voltage (V)") ax2 = plt.subplot(122) out = hist(IO.apparent_resistivity, bins=20) ax2.set_xlabel("Apparent Resistivity ($\Omega$m)") plt.tight_layout() plt.show() # Set initial model based upon histogram m0_dc = np.ones(actmap.nP) * np.log(100.) # Set uncertainty # floor eps_dc = 10**(-3.2) # percentage std_dc = 0.05 mopt_dc, pred_dc = DC.run_inversion(m0_dc, survey_dc, actind, mesh, std_dc, eps_dc, beta0_ratio=1e0, use_sensitivity_weight=True) # Convert obtained inversion model to resistivity # rho = M(m), where M(.) is a mapping rho_est = mapping * mopt_dc rho_est[~actind] = np.nan rho_true = rho.copy() rho_true[~actind] = np.nan # show recovered conductivity if plotIt: vmin, vmax = rho.min(), rho.max() fig, ax = plt.subplots(2, 1, figsize=(20, 6)) out1 = mesh.plotImage(rho_true, clim=(10, 1000), pcolorOpts={ "cmap": "viridis", "norm": colors.LogNorm() }, ax=ax[0]) out2 = mesh.plotImage(rho_est, clim=(10, 1000), pcolorOpts={ "cmap": "viridis", "norm": colors.LogNorm() }, ax=ax[1]) out = [out1, out2] for i in range(2): ax[i].plot(survey_dc.electrode_locations[:, 0], survey_dc.electrode_locations[:, 1], 'kv') ax[i].set_xlim(IO.grids[:, 0].min(), IO.grids[:, 0].max()) ax[i].set_ylim(-IO.grids[:, 1].max(), IO.grids[:, 1].min()) cb = plt.colorbar(out[i][0], ax=ax[i]) cb.set_label("Resistivity ($\Omega$m)") ax[i].set_xlabel("Northing (m)") ax[i].set_ylabel("Elevation (m)") ax[i].set_aspect('equal') plt.tight_layout() plt.show() # Show apparent resisitivty histogram if plotIt: fig = plt.figure(figsize=(10, 4)) ax1 = plt.subplot(121) out = hist(np.log10(abs(IO.voltages_ip)), bins=20) ax1.set_xlabel("log10 IP voltage (V)") ax2 = plt.subplot(122) out = hist(IO.apparent_chargeability, bins=20) ax2.set_xlabel("Apparent Chargeability (V/V)") plt.tight_layout() plt.show() # Set initial model based upon histogram m0_ip = np.ones(actmap.nP) * 1e-10 # Set uncertainty # floor eps_ip = 10**(-4) # percentage std_ip = 0.05 # Clean sensitivity function formed with true resistivity prb_ip._Jmatrix = None # Input obtained resistivity to form sensitivity prb_ip.rho = mapping * mopt_dc mopt_ip, _ = IP.run_inversion(m0_ip, survey_ip, actind, mesh, std_ip, eps_ip, upper=np.Inf, lower=0., beta0_ratio=1e0, use_sensitivity_weight=True) # Convert obtained inversion model to chargeability # charg = M(m), where M(.) is a mapping for cells below topography charg_est = actmap * mopt_ip charg_est[~actind] = np.nan charg_true = charg.copy() charg_true[~actind] = np.nan # show recovered chargeability if plotIt: fig, ax = plt.subplots(2, 1, figsize=(20, 6)) out1 = mesh.plotImage(charg_true, clim=(0, 0.1), pcolorOpts={"cmap": "magma"}, ax=ax[0]) out2 = mesh.plotImage(charg_est, clim=(0, 0.1), pcolorOpts={"cmap": "magma"}, ax=ax[1]) out = [out1, out2] for i in range(2): ax[i].plot(survey_dc.electrode_locations[:, 0], survey_dc.electrode_locations[:, 1], 'rv') ax[i].set_xlim(IO.grids[:, 0].min(), IO.grids[:, 0].max()) ax[i].set_ylim(-IO.grids[:, 1].max(), IO.grids[:, 1].min()) cb = plt.colorbar(out[i][0], ax=ax[i]) cb.set_label("Resistivity ($\Omega$m)") ax[i].set_xlabel("Northing (m)") ax[i].set_ylabel("Elevation (m)") ax[i].set_aspect('equal') plt.tight_layout() plt.show()
def run(plotIt=True, survey_type="dipole-dipole", rho_background=1e3, rho_block=1e2, block_x0=100, block_dx=10, block_y0=-10, block_dy=5): np.random.seed(1) # Initiate I/O class for DC IO = DC.IO() # Obtain ABMN locations xmin, xmax = 0., 200. ymin, ymax = 0., 0. zmin, zmax = 0, 0 endl = np.array([[xmin, ymin, zmin], [xmax, ymax, zmax]]) # Generate DC survey object survey = DC.Utils.gen_DCIPsurvey(endl, survey_type=survey_type, dim=2, a=10, b=10, n=10) survey.getABMN_locations() survey = IO.from_ambn_locations_to_survey(survey.a_locations, survey.b_locations, survey.m_locations, survey.n_locations, survey_type, data_dc_type='volt') # Obtain 2D TensorMesh mesh, actind = IO.set_mesh() # Flat topography actind = Utils.surface2ind_topo(mesh, np.c_[mesh.vectorCCx, mesh.vectorCCx * 0.]) survey.drapeTopo(mesh, actind, option="top") # Use Exponential Map: m = log(rho) actmap = Maps.InjectActiveCells(mesh, indActive=actind, valInactive=np.log(1e8)) parametric_block = Maps.ParametricBlock(mesh, slopeFact=1e2) mapping = Maps.ExpMap(mesh) * parametric_block # Set true model # val_background,val_block, block_x0, block_dx, block_y0, block_dy mtrue = np.r_[np.log(1e3), np.log(10), 100, 10, -20, 10] # Set initial model m0 = np.r_[np.log(rho_background), np.log(rho_block), block_x0, block_dx, block_y0, block_dy] rho = mapping * mtrue rho0 = mapping * m0 # Show the true conductivity model fig = plt.figure(figsize=(12, 3)) ax = plt.subplot(111) temp = rho.copy() temp[~actind] = np.nan out = mesh.plotImage(temp, grid=False, ax=ax, gridOpts={'alpha': 0.2}, clim=(10, 1000), pcolorOpts={ "cmap": "viridis", "norm": colors.LogNorm() }) ax.plot(survey.electrode_locations[:, 0], survey.electrode_locations[:, 1], 'k.') ax.set_xlim(IO.grids[:, 0].min(), IO.grids[:, 0].max()) ax.set_ylim(-IO.grids[:, 1].max(), IO.grids[:, 1].min()) cb = plt.colorbar(out[0]) cb.set_label("Resistivity (ohm-m)") ax.set_aspect('equal') ax.set_title("True resistivity model") plt.show() # Show the true conductivity model fig = plt.figure(figsize=(12, 3)) ax = plt.subplot(111) temp = rho0.copy() temp[~actind] = np.nan out = mesh.plotImage(temp, grid=False, ax=ax, gridOpts={'alpha': 0.2}, clim=(10, 1000), pcolorOpts={ "cmap": "viridis", "norm": colors.LogNorm() }) ax.plot(survey.electrode_locations[:, 0], survey.electrode_locations[:, 1], 'k.') ax.set_xlim(IO.grids[:, 0].min(), IO.grids[:, 0].max()) ax.set_ylim(-IO.grids[:, 1].max(), IO.grids[:, 1].min()) cb = plt.colorbar(out[0]) cb.set_label("Resistivity (ohm-m)") ax.set_aspect('equal') ax.set_title("Initial resistivity model") plt.show() # Generate 2.5D DC problem # "N" means potential is defined at nodes prb = DC.Problem2D_N(mesh, rhoMap=mapping, storeJ=True, Solver=Solver) # Pair problem with survey try: prb.pair(survey) except: survey.unpair() prb.pair(survey) # Make synthetic DC data with 5% Gaussian noise dtrue = survey.makeSyntheticData(mtrue, std=0.05, force=True) # Show apparent resisitivty pseudo-section IO.plotPseudoSection(data=survey.dobs / IO.G, data_type='apparent_resistivity') # Show apparent resisitivty histogram fig = plt.figure() out = hist(survey.dobs / IO.G, bins=20) plt.show() # Set uncertainty # floor eps = 10**(-3.2) # percentage std = 0.05 dmisfit = DataMisfit.l2_DataMisfit(survey) uncert = abs(survey.dobs) * std + eps dmisfit.W = 1. / uncert # Map for a regularization mesh_1d = Mesh.TensorMesh([parametric_block.nP]) # Related to inversion reg = Regularization.Simple(mesh_1d, alpha_x=0.) opt = Optimization.InexactGaussNewton(maxIter=10) invProb = InvProblem.BaseInvProblem(dmisfit, reg, opt) beta = Directives.BetaSchedule(coolingFactor=5, coolingRate=2) betaest = Directives.BetaEstimate_ByEig(beta0_ratio=1e0) target = Directives.TargetMisfit() updateSensW = Directives.UpdateSensitivityWeights() update_Jacobi = Directives.UpdatePreconditioner() invProb.beta = 0. inv = Inversion.BaseInversion(invProb, directiveList=[target]) prb.counter = opt.counter = Utils.Counter() opt.LSshorten = 0.5 opt.remember('xc') # Run inversion mopt = inv.run(m0) # Convert obtained inversion model to resistivity # rho = M(m), where M(.) is a mapping rho_est = mapping * mopt rho_true = rho.copy() # show recovered conductivity vmin, vmax = rho.min(), rho.max() fig, ax = plt.subplots(2, 1, figsize=(20, 6)) out1 = mesh.plotImage(rho_true, clim=(10, 1000), pcolorOpts={ "cmap": "viridis", "norm": colors.LogNorm() }, ax=ax[0]) out2 = mesh.plotImage(rho_est, clim=(10, 1000), pcolorOpts={ "cmap": "viridis", "norm": colors.LogNorm() }, ax=ax[1]) out = [out1, out2] for i in range(2): ax[i].plot(survey.electrode_locations[:, 0], survey.electrode_locations[:, 1], 'kv') ax[i].set_xlim(IO.grids[:, 0].min(), IO.grids[:, 0].max()) ax[i].set_ylim(-IO.grids[:, 1].max(), IO.grids[:, 1].min()) cb = plt.colorbar(out[i][0], ax=ax[i]) cb.set_label("Resistivity ($\Omega$m)") ax[i].set_xlabel("Northing (m)") ax[i].set_ylabel("Elevation (m)") ax[i].set_aspect('equal') ax[0].set_title("True resistivity model") ax[1].set_title("Recovered resistivity model") plt.tight_layout() plt.show()
def run(plotIt=True, survey_type="pole-dipole"): np.random.seed(1) # Initiate I/O class for DC IO = DC.IO() # Obtain ABMN locations fileName1 = "C:/Users/johnk/Projects/Seabridge/fmdataDC.con" # output mod fileName1_ = "C:/Users/johnk/Projects/Seabridge/fmdataIP.chg" # output mod fileName2 = "C:/Users/johnk/Projects/Seabridge/forwardmodel.msh" # in mesh mesh = Mesh.TensorMesh._readUBC_3DMesh(fileName2) # Read in/create mesh print("Starting forward modeling") start = clock() # Define model Background rx = getRxData() # rx locations tx = getTxData() # tx locations survey_dc = generateSurvey(rx, tx, 45, 65) # create survey object survey_dc.getABMN_locations() # get locations # survey_dc = IO.from_ambn_locations_to_survey( # survey_dc.a_locations, survey_dc.b_locations, # survey_dc.m_locations, survey_dc.n_locations, # survey_type, data_dc_type='volt', data_ip_type='volt' # ) uniq = Utils.uniqueRows(np.vstack((survey_dc.a_locations, survey_dc.b_locations, survey_dc.m_locations, survey_dc.n_locations))) electrode_locations = uniq[0] # assign actinds = Utils.surface2ind_topo(mesh, electrode_locations, method='cubic') # active indicies survey_dc.drapeTopo(mesh, actinds) # drape topo # ============================================================================= # create sphere for ice representation x0 = (np.max(mesh.gridCC[:, 0]) + np.min(mesh.gridCC[:, 0])) / 2. + 50 # x0 center point of sphere y0 = (np.max(mesh.gridCC[:, 1]) + np.min(mesh.gridCC[:, 1])) / 2. - 50 # y0 center point of sphere z0 = 2350 # x0 center point of sphere # (np.max(mesh.gridCC[:, 2]) + np.min(mesh.gridCC[:, 2])) / 2. r0 = 500 # radius of sphere print(x0, y0, z0) csph = (np.sqrt((mesh.gridCC[:, 0] - x0)**2. + (mesh.gridCC[:, 1] - y0)**2. + (mesh.gridCC[:, 2] - z0)**2.)) < r0 # indicies of sphere # sphere done ================================================================= # ============================================================================ # Create model mx = np.ones(mesh.nC) * 0.020 # chargeability sigma = np.ones(mesh.nC) * 1. / 15000. # create dipping structure parameters theta = 45. * np.pi / 180. # dipping angle x0_d = 374700. x1_d = 375000. y0_d = 6275850. y0_1d = 500. * np.sin(theta) + y0_d y1_d = 6275900. y1_1d = 500. * np.sin(theta) + y1_d z0_d = 1860. z1_d = z0_d - (500. * np.cos(theta)) m_ = (z0_d - z1_d) / (y0_1d - y0_d) # slope of dip # loop through mesh and assign dipping structure conductivity for idx in range(mesh.nC): if z1_d <= mesh.gridCC[idx, 2] <= z0_d: if (x0_d <= mesh.gridCC[idx, 0] <= x1_d): yslope1 = y0_d + (1. / m_) * (mesh.gridCC[idx, 2] - z0_d) yslope2 = y1_d + (1. / m_) * (mesh.gridCC[idx, 2] - z0_d) if yslope1 <= mesh.gridCC[idx, 1] <= yslope2: mx[idx] = 0.03 sigma[idx] = 1. / 300. # mx[csph] = ((0.025) * # np.ones_like(mx[csph])) # set sphere values mx[~actinds] = 1. / 1e8 # flag air values # sigma[csph] = ((5000.) * # np.ones_like(sigma[csph])) # set sphere values sigma[~actinds] = 1. / 1e8 # flag air values rho = 1. / sigma stop = clock() print(stop) # plot results # Show the true conductivity model if plotIt: ncy = mesh.nCy ncz = mesh.nCz ncx = mesh.nCx mtrue = mx print(mtrue.min(), mtrue.max()) clim = [0, 0.04] fig, ax = plt.subplots(2, 2, figsize=(12, 6)) ax = Utils.mkvc(ax) dat = mesh.plotSlice(((mx)), ax=ax[0], normal='Z', clim=clim, ind=int(ncz / 2), pcolorOpts={"cmap": "jet"}) ax[0].plot(rx[:, 0], rx[:, 1], 'or') ax[0].plot(tx[:, 0], tx[:, 1], 'dk') mesh.plotSlice(((mx)), ax=ax[1], normal='Y', clim=clim, ind=int(ncy / 2 + 2), pcolorOpts={"cmap": "jet"}) mesh.plotSlice(((mx)), ax=ax[2], normal='X', clim=clim, ind=int(ncx / 2 + 4), pcolorOpts={"cmap": "jet"}) mesh.plotSlice(((mx)), ax=ax[3], normal='X', clim=clim, ind=int(ncx / 2 + 8), pcolorOpts={"cmap": "jet"}) cbar_ax = fig.add_axes([0.82, 0.15, 0.05, 0.7]) cb = plt.colorbar(dat[0], ax=cbar_ax) fig.subplots_adjust(right=0.85) cb.set_label('V/V') cbar_ax.axis('off') plt.show() mtrue = 1. / sigma print(mtrue.min(), mtrue.max()) clim = [0, 20000] fig, ax = plt.subplots(2, 2, figsize=(12, 6)) ax = Utils.mkvc(ax) dat = mesh.plotSlice(((mtrue)), ax=ax[0], normal='Z', clim=clim, ind=int(ncz / 2 - 4), pcolorOpts={"cmap": "jet"}) ax[0].plot(rx[:, 0], rx[:, 1], 'or') ax[0].plot(tx[:, 0], tx[:, 1], 'dk') mesh.plotSlice(((mtrue)), ax=ax[1], normal='Y', clim=clim, ind=int(ncy / 2), pcolorOpts={"cmap": "jet"}) mesh.plotSlice(((mtrue)), ax=ax[2], normal='X', clim=clim, ind=int(ncx / 2 + 4), pcolorOpts={"cmap": "jet"}) mesh.plotSlice(((mtrue)), ax=ax[3], normal='X', clim=clim, ind=int(ncx / 2 + 8), pcolorOpts={"cmap": "jet"}) cbar_ax = fig.add_axes([0.82, 0.15, 0.05, 0.7]) cb = plt.colorbar(dat[0], ax=cbar_ax) fig.subplots_adjust(right=0.85) cb.set_label('rho') cbar_ax.axis('off') plt.show() # Use Exponential Map: m = log(rho) actmap = Maps.InjectActiveCells( mesh, indActive=actinds, valInactive=np.log(1e8) ) mapping = Maps.ExpMap(mesh) * actmap # Generate mtrue_dc for resistivity mtrue_dc = np.log(rho[actinds]) # Generate 3D DC problem # "CC" means potential is defined at center prb = DC.Problem3D_CC( mesh, rhoMap=mapping, storeJ=False, Solver=Solver ) # Pair problem with survey try: prb.pair(survey_dc) except: survey_dc.unpair() prb.pair(survey_dc) # Make synthetic DC data with 5% Gaussian noise dtrue_dc = survey_dc.makeSyntheticData(mtrue_dc, std=0.05, force=True) IO.data_dc = dtrue_dc # Generate mtrue_ip for chargability mtrue_ip = mx[actinds] # Generate 3D DC problem # "CC" means potential is defined at center prb_ip = IP.Problem3D_CC( mesh, etaMap=actmap, storeJ=False, rho=rho, Solver=Solver ) survey_ip = IP.from_dc_to_ip_survey(survey_dc, dim="3D") prb_ip.pair(survey_ip) dtrue_ip = survey_ip.makeSyntheticData(mtrue_ip, std=0.05) IO.data_ip = dtrue_ip # Show apparent resisitivty histogram # if plotIt: # fig = plt.figure(figsize=(10, 4)) # ax1 = plt.subplot(121) # out = hist(np.log10(abs(IO.voltages)), bins=20) # ax1.set_xlabel("log10 DC voltage (V)") # ax2 = plt.subplot(122) # out = hist(IO.apparent_resistivity, bins=20) # ax2.set_xlabel("Apparent Resistivity ($\Omega$m)") # plt.tight_layout() # plt.show() # Set initial model based upon histogram m0_dc = np.ones(actmap.nP) * np.log(10000.) # Set uncertainty # floor eps_dc = 10**(-3.2) # percentage std_dc = 0.05 mopt_dc, pred_dc = DC.run_inversion( m0_dc, survey_dc, actinds, mesh, std_dc, eps_dc, use_sensitivity_weight=False) # Convert obtained inversion model to resistivity # rho = M(m), where M(.) is a mapping rho_est = mapping * mopt_dc # rho_est[~actinds] = np.nan rho_true = rho.copy() rho_true[~actinds] = np.nan # write data to file out_file = open(fileName1, "w") for i in range(rho_est.size): out_file.write("%0.5e\n" % rho_est[i]) # Set initial model based upon histogram m0_ip = np.ones(actmap.nP) * 1e-10 # Set uncertainty # floor eps_ip = 10**(-4) # percentage std_ip = 0.05 # Clean sensitivity function formed with true resistivity prb_ip._Jmatrix = None # Input obtained resistivity to form sensitivity prb_ip.rho = mapping * mopt_dc mopt_ip, _ = IP.run_inversion( m0_ip, survey_ip, actinds, mesh, std_ip, eps_ip, upper=np.Inf, lower=0., use_sensitivity_weight=False) # Convert obtained inversion model to chargeability # charg = M(m), where M(.) is a mapping for cells below topography charg_est = actmap * mopt_ip # charg_est[~actinds] = np.nan charg_true = charg.copy() charg_true[~actinds] = np.nan # write IP data to file out_file = open(fileName1_, "w") for i in range(charg_est.size): out_file.write("%0.5e\n" % charg_est[i])
def run(plotIt=True, survey_type="pole-dipole"): np.random.seed(1) # Initiate I/O class for DC IO = DC.IO() # Obtain ABMN locations fileName1 = "/Users/juan/Documents/testData/fmdata-daf.con" # output mod fileName2 = "/Users/juan/Documents/testData/forwardmodel.msh" # input mesh mesh = Mesh.TensorMesh._readUBC_3DMesh(fileName2) # Read in/create mesh print("Starting forward modeling") start = clock() # Define model Background rx = getRxData() # rx locations tx = getTxData() # tx locations survey_dc = generateSurvey(rx, tx, 45, 55) # create survey object survey_dc.survey_type = "pole-dipole" survey_dc.getABMN_locations() # get locations # survey_dc = IO.from_ambn_locations_to_survey( # survey_dc.a_locations, survey_dc.b_locations, # survey_dc.m_locations, survey_dc.n_locations, # survey_type, data_dc_type='volt', data_ip_type='volt' # ) uniq = Utils.uniqueRows( np.vstack((survey_dc.a_locations, survey_dc.b_locations, survey_dc.m_locations, survey_dc.n_locations))) electrode_locations = uniq[0] # assign actinds = Utils.surface2ind_topo(mesh, electrode_locations, method='cubic') # active indicies # survey_dc.drapeTopo(mesh, actinds) IO.a_locations = survey_dc.a_locations.copy() IO.b_locations = survey_dc.b_locations.copy() IO.m_locations = survey_dc.m_locations.copy() IO.n_locations = survey_dc.n_locations.copy() # drape topo IO.data_dc_type = 'volt' IO.G = IO.geometric_factor(survey_dc) # ============================================================================= # create sphere for ice representation x0 = (np.max(mesh.gridCC[:, 0]) + np.min(mesh.gridCC[:, 0])) / 2. + 50 # x0 center point of sphere y0 = (np.max(mesh.gridCC[:, 1]) + np.min(mesh.gridCC[:, 1])) / 2. - 50 # y0 center point of sphere z0 = 2350 # x0 center point of sphere # (np.max(mesh.gridCC[:, 2]) + np.min(mesh.gridCC[:, 2])) / 2. r0 = 500 # radius of sphere print(x0, y0, z0) csph = (np.sqrt((mesh.gridCC[:, 0] - x0)**2. + (mesh.gridCC[:, 1] - y0)**2. + (mesh.gridCC[:, 2] - z0)**2.)) < r0 # indicies of sphere # sphere done ================================================================= # ============================================================================ # Create model mx = np.ones(mesh.nC) * 0.018 # chargeability sigma = np.ones(mesh.nC) * 1. / 15000. # create dipping structure parameters theta = 45. * np.pi / 180. # dipping angle x0_d = 374700. x1_d = 375000. y0_d = 6275850. y0_1d = 900. * np.sin(theta) + y0_d y1_d = 6275900. y1_1d = 900. * np.sin(theta) + y1_d z0_d = 1900. z1_d = z0_d - (900. * np.cos(theta)) m_ = (z0_d - z1_d) / (y0_1d - y0_d) # slope of dip # loop through mesh and assign dipping structure conductivity for idx in range(mesh.nC): if z1_d <= mesh.gridCC[idx, 2] <= z0_d: if (x0_d <= mesh.gridCC[idx, 0] <= x1_d): yslope1 = y0_d + (1. / m_) * (mesh.gridCC[idx, 2] - z0_d) yslope2 = y1_d + (1. / m_) * (mesh.gridCC[idx, 2] - z0_d) if yslope1 <= mesh.gridCC[idx, 1] <= yslope2: mx[idx] = 0.035 sigma[idx] = 1. / 300. # mx[csph] = ((0.025) * # np.ones_like(mx[csph])) # set sphere values mx[~actinds] = 1. / 1e8 # flag air values # sigma[csph] = ((5000.) * # np.ones_like(sigma[csph])) # set sphere values sigma[~actinds] = 1. / 1e8 # flag air values rho = 1. / sigma stop = clock() print(stop) # plot results # Show the true conductivity model if plotIt: ncy = mesh.nCy ncz = mesh.nCz ncx = mesh.nCx print(mesh.nC) clim = [0, 0.04] fig, ax = plt.subplots(2, 2, figsize=(12, 6)) ax = Utils.mkvc(ax) dat = mesh.plotSlice(((mx)), ax=ax[0], normal='Z', clim=clim, ind=int(ncz / 2 - 14), pcolorOpts={"cmap": "jet"}) ax[0].plot(rx[:, 0], rx[:, 1], 'or') ax[0].plot(tx[:, 0], tx[:, 1], 'dk') mesh.plotSlice(((mx)), ax=ax[1], normal='Y', clim=clim, ind=int(ncy / 2 + 2), pcolorOpts={"cmap": "jet"}) mesh.plotSlice(((mx)), ax=ax[2], normal='X', clim=clim, ind=int(ncx / 2 + 4), pcolorOpts={"cmap": "jet"}) mesh.plotSlice(((mx)), ax=ax[3], normal='X', clim=clim, ind=int(ncx / 2 + 8), pcolorOpts={"cmap": "jet"}) cbar_ax = fig.add_axes([0.82, 0.15, 0.05, 0.7]) cb = plt.colorbar(dat[0], ax=cbar_ax) fig.subplots_adjust(right=0.85) cb.set_label('V/V') cbar_ax.axis('off') plt.show() # print(mtrue.min(), mtrue.max()) # clim = [0, 20000] # fig, ax = plt.subplots(2, 2, figsize=(12, 6)) # ax = Utils.mkvc(ax) # dat = mesh.plotSlice(((mtrue)), ax=ax[0], normal='Z', clim=clim, # ind=int(ncz / 2 - 4), pcolorOpts={"cmap": "jet"}) # ax[0].plot(rx[:, 0], rx[:, 1], 'or') # mesh.plotSlice(((mtrue)), ax=ax[1], normal='Y', clim=clim, # ind=int(ncy / 2), pcolorOpts={"cmap": "jet"}) # mesh.plotSlice(((mtrue)), ax=ax[2], normal='X', clim=clim, # ind=int(ncx / 2 + 4), pcolorOpts={"cmap": "jet"}) # mesh.plotSlice(((mtrue)), ax=ax[3], normal='X', clim=clim, # ind=int(ncx / 2 + 8), pcolorOpts={"cmap": "jet"}) # cbar_ax = fig.add_axes([0.82, 0.15, 0.05, 0.7]) # cb = plt.colorbar(dat[0], ax=cbar_ax) # fig.subplots_adjust(right=0.85) # cb.set_label('rho') # cbar_ax.axis('off') # plt.show() # print(error.size, survey_ip.obs.size) # error = np.asarray(survey_ip.dobs) * (np.random.randint(-1, 2, survey_ip.dobs) / 20.) # survey_ip.dobs = survey_ip.dobs + error # Use Exponential Map: m = log(rho) actmap = Maps.InjectActiveCells(mesh, indActive=actinds, valInactive=np.log(1e8)) mapping = Maps.ExpMap(mesh) * actmap # Generate mtrue_dc for resistivity mtrue_dc = np.log(rho[actinds]) # Generate 3D DC problem # "CC" means potential is defined at center prb = DC.Problem3D_CC(mesh, rhoMap=mapping, storeJ=False, Solver=Solver) # Pair problem with survey # try: prb.pair(survey_dc) # except: # survey_dc.unpair() # prb.pair(survey_dc) survey_dc.dpred(mtrue_dc) # Make synthetic DC data with 5% Gaussian noise dtrue_dc = survey_dc.makeSyntheticData(mtrue_dc, std=0.05, force=True) IO.data_dc = dtrue_dc # Generate mtrue_ip for chargability mtrue_ip = mx[actinds] # Generate 3D DC problem # "CC" means potential is defined at center prb_ip = IP.Problem3D_CC(mesh, etaMap=actmap, storeJ=False, rho=rho, Solver=Solver) survey_ip = IP.from_dc_to_ip_survey(survey_dc, dim="3D") survey_ip.survey_type = "pole-dipole" survey_ip.getABMN_locations() prb_ip.pair(survey_ip) survey_ip.dpred(mtrue_ip) dtrue_ip = survey_ip.makeSyntheticData(mtrue_ip, std=0.05) survey_ip.std = np.ones_like(dtrue_ip) * 0.05 survey_ip.eps = np.ones_like(dtrue_ip) * 10**(-4) IO.data_ip = dtrue_ip DC.Utils.writeUBC_DCobs("fmip.obs", survey_ip, 3, 'GENERAL', 'pole-dipole')
# Convert file to DC.IO object # ---------------------------- # # Number of the data ndata = df[header_loc[0]].values.size # ABMN locations a = np.c_[df[header_loc[0]].values, np.zeros(ndata)] b = np.c_[df[header_loc[1]].values, np.zeros(ndata)] m = np.c_[df[header_loc[2]].values, np.zeros(ndata)] n = np.c_[df[header_loc[3]].values, np.zeros(ndata)] # Apparent resistivity apprho = df[header_apprho].values # Create DC.IO survey Object object IO = DC.IO() # Generate DC survey using IO object dc_survey = IO.from_ambn_locations_to_survey( a, b, m, n, survey_type='dipole-dipole', data_dc=apprho, data_dc_type='apparent_resistivity') ############################################################################### # # Plot # ---- #
def run(plotIt=True, survey_type="dipole-dipole"): np.random.seed(1) # Initiate I/O class for DC IO = DC.IO() # Obtain ABMN locations xmin, xmax = 0., 200. ymin, ymax = 0., 0. zmin, zmax = 0, 0 endl = np.array([[xmin, ymin, zmin], [xmax, ymax, zmax]]) # Generate DC survey object survey = DC.Utils.gen_DCIPsurvey(endl, survey_type=survey_type, dim=2, a=10, b=10, n=10) survey.getABMN_locations() survey = IO.from_ambn_locations_to_survey( survey.a_locations, survey.b_locations, survey.m_locations, survey.n_locations, survey_type, data_dc_type='volt' ) # Obtain 2D TensorMesh mesh, actind = IO.set_mesh() topo, mesh1D = DC.Utils.genTopography(mesh, -10, 0, its=100) actind = Utils.surface2ind_topo(mesh, np.c_[mesh1D.vectorCCx, topo]) survey.drapeTopo(mesh, actind, option="top") # Build a conductivity model blk_inds_c = Utils.ModelBuilder.getIndicesSphere( np.r_[60., -25.], 12.5, mesh.gridCC ) blk_inds_r = Utils.ModelBuilder.getIndicesSphere( np.r_[140., -25.], 12.5, mesh.gridCC ) layer_inds = mesh.gridCC[:, 1] > -5. sigma = np.ones(mesh.nC)*1./100. sigma[blk_inds_c] = 1./10. sigma[blk_inds_r] = 1./1000. sigma[~actind] = 1./1e8 rho = 1./sigma # Show the true conductivity model if plotIt: fig = plt.figure(figsize=(12, 3)) ax = plt.subplot(111) temp = rho.copy() temp[~actind] = np.nan out = mesh.plotImage( temp, grid=True, ax=ax, gridOpts={'alpha': 0.2}, clim=(10, 1000), pcolorOpts={"cmap": "viridis", "norm": colors.LogNorm()} ) ax.plot( survey.electrode_locations[:, 0], survey.electrode_locations[:, 1], 'k.' ) ax.set_xlim(IO.grids[:, 0].min(), IO.grids[:, 0].max()) ax.set_ylim(-IO.grids[:, 1].max(), IO.grids[:, 1].min()) cb = plt.colorbar(out[0]) cb.set_label("Resistivity (ohm-m)") ax.set_aspect('equal') plt.show() # Use Exponential Map: m = log(rho) actmap = Maps.InjectActiveCells( mesh, indActive=actind, valInactive=np.log(1e8) ) mapping = Maps.ExpMap(mesh) * actmap # Generate mtrue mtrue = np.log(rho[actind]) # Generate 2.5D DC problem # "N" means potential is defined at nodes prb = DC.Problem2D_N( mesh, rhoMap=mapping, storeJ=True, Solver=Solver ) # Pair problem with survey try: prb.pair(survey) except: survey.unpair() prb.pair(survey) geometric_factor = survey.set_geometric_factor( data_type="apparent_resistivity", survey_type='dipole-dipole', space_type='half-space' ) # Make synthetic DC data with 5% Gaussian noise dtrue = survey.makeSyntheticData(mtrue, std=0.05, force=True) IO.data_dc = dtrue # Show apparent resisitivty pseudo-section if plotIt: IO.plotPseudoSection( data=survey.dobs, data_type='apparent_resistivity' ) # Show apparent resisitivty histogram if plotIt: fig = plt.figure() out = hist(survey.dobs, bins=20) plt.xlabel("Apparent Resisitivty ($\Omega$m)") plt.show() # Set initial model based upon histogram m0 = np.ones(actmap.nP)*np.log(100.) # Set uncertainty # floor (10 ohm-m) eps = 1. # percentage std = 0.05 dmisfit = DataMisfit.l2_DataMisfit(survey) uncert = abs(survey.dobs) * std + eps dmisfit.W = 1./uncert # Map for a regularization regmap = Maps.IdentityMap(nP=int(actind.sum())) # Related to inversion reg = Regularization.Sparse(mesh, indActive=actind, mapping=regmap) opt = Optimization.InexactGaussNewton(maxIter=15) invProb = InvProblem.BaseInvProblem(dmisfit, reg, opt) beta = Directives.BetaSchedule(coolingFactor=5, coolingRate=2) betaest = Directives.BetaEstimate_ByEig(beta0_ratio=1e0) target = Directives.TargetMisfit() updateSensW = Directives.UpdateSensitivityWeights() update_Jacobi = Directives.UpdatePreconditioner() inv = Inversion.BaseInversion( invProb, directiveList=[ beta, betaest, target, updateSensW, update_Jacobi ] ) prb.counter = opt.counter = Utils.Counter() opt.LSshorten = 0.5 opt.remember('xc') # Run inversion mopt = inv.run(m0) # Get diag(JtJ) mask_inds = np.ones(mesh.nC, dtype=bool) jtj = np.sqrt(updateSensW.JtJdiag[0]) jtj /= jtj.max() temp = np.ones_like(jtj, dtype=bool) temp[jtj > 0.005] = False mask_inds[actind] = temp actind_final = np.logical_and(actind, ~mask_inds) jtj_cc = np.ones(mesh.nC)*np.nan jtj_cc[actind] = jtj # Show the sensitivity if plotIt: fig = plt.figure(figsize=(12, 3)) ax = plt.subplot(111) temp = rho.copy() temp[~actind] = np.nan out = mesh.plotImage( jtj_cc, grid=True, ax=ax, gridOpts={'alpha': 0.2}, clim=(0.005, 0.5), pcolorOpts={"cmap": "viridis", "norm": colors.LogNorm()} ) ax.plot( survey.electrode_locations[:, 0], survey.electrode_locations[:, 1], 'k.' ) ax.set_xlim(IO.grids[:, 0].min(), IO.grids[:, 0].max()) ax.set_ylim(-IO.grids[:, 1].max(), IO.grids[:, 1].min()) cb = plt.colorbar(out[0]) cb.set_label("Sensitivity") ax.set_aspect('equal') plt.show() # Convert obtained inversion model to resistivity # rho = M(m), where M(.) is a mapping rho_est = mapping*mopt rho_est[~actind_final] = np.nan rho_true = rho.copy() rho_true[~actind_final] = np.nan # show recovered conductivity if plotIt: vmin, vmax = rho.min(), rho.max() fig, ax = plt.subplots(2, 1, figsize=(20, 6)) out1 = mesh.plotImage( rho_true, clim=(10, 1000), pcolorOpts={"cmap": "viridis", "norm": colors.LogNorm()}, ax=ax[0] ) out2 = mesh.plotImage( rho_est, clim=(10, 1000), pcolorOpts={"cmap": "viridis", "norm": colors.LogNorm()}, ax=ax[1] ) out = [out1, out2] for i in range(2): ax[i].plot( survey.electrode_locations[:, 0], survey.electrode_locations[:, 1], 'kv' ) ax[i].set_xlim(IO.grids[:, 0].min(), IO.grids[:, 0].max()) ax[i].set_ylim(-IO.grids[:, 1].max(), IO.grids[:, 1].min()) cb = plt.colorbar(out[i][0], ax=ax[i]) cb.set_label("Resistivity ($\Omega$m)") ax[i].set_xlabel("Northing (m)") ax[i].set_ylabel("Elevation (m)") ax[i].set_aspect('equal') plt.tight_layout() plt.show()
def run(plotIt=True, survey_type="dipole-dipole"): np.random.seed(1) # Initiate I/O class for DC IO = DC.IO() # Obtain ABMN locations xmin, xmax = 0., 200. ymin, ymax = 0., 0. zmin, zmax = 0, 0 endl = np.array([[xmin, ymin, zmin], [xmax, ymax, zmax]]) # Generate DC survey object survey_dc = DC.Utils.gen_DCIPsurvey(endl, survey_type=survey_type, dim=2, a=10, b=10, n=10) survey_dc.getABMN_locations() survey_dc = IO.from_ambn_locations_to_survey( survey_dc.a_locations, survey_dc.b_locations, survey_dc.m_locations, survey_dc.n_locations, survey_type, data_dc_type='volt', data_ip_type='volt' ) # Obtain 2D TensorMesh mesh, actind = IO.set_mesh() topo, mesh1D = DC.Utils.genTopography(mesh, -10, 0, its=100) actind = Utils.surface2ind_topo(mesh, np.c_[mesh1D.vectorCCx, topo]) survey_dc.drapeTopo(mesh, actind, option="top") # Build conductivity and chargeability model blk_inds_c = Utils.ModelBuilder.getIndicesSphere( np.r_[60., -25.], 12.5, mesh.gridCC ) blk_inds_r = Utils.ModelBuilder.getIndicesSphere( np.r_[140., -25.], 12.5, mesh.gridCC ) blk_inds_charg = Utils.ModelBuilder.getIndicesSphere( np.r_[100., -25], 12.5, mesh.gridCC ) sigma = np.ones(mesh.nC)*1./100. sigma[blk_inds_c] = 1./10. sigma[blk_inds_r] = 1./1000. sigma[~actind] = 1./1e8 rho = 1./sigma charg = np.zeros(mesh.nC) charg[blk_inds_charg] = 0.1 # Show the true conductivity model if plotIt: fig, axs = plt.subplots(2,1, figsize=(12, 6)) temp_rho = rho.copy() temp_rho[~actind] = np.nan temp_charg = charg.copy() temp_charg[~actind] = np.nan out1 = mesh.plotImage( temp_rho, grid=True, ax=axs[0], gridOpts={'alpha': 0.2}, clim=(10, 1000), pcolorOpts={"cmap": "viridis", "norm": colors.LogNorm()} ) out2 = mesh.plotImage( temp_charg, grid=True, ax=axs[1], gridOpts={'alpha': 0.2}, clim=(0, 0.1), pcolorOpts={"cmap": "magma"} ) for i in range(2): axs[i].plot( survey_dc.electrode_locations[:, 0], survey_dc.electrode_locations[:, 1], 'kv' ) axs[i].set_xlim(IO.grids[:, 0].min(), IO.grids[:, 0].max()) axs[i].set_ylim(-IO.grids[:, 1].max(), IO.grids[:, 1].min()) axs[i].set_aspect('equal') cb = plt.colorbar(out1[0], ax=axs[0]) cb.set_label("Resistivity (ohm-m)") cb = plt.colorbar(out2[0], ax=axs[1]) cb.set_label("Chargeability") plt.show() # Use Exponential Map: m = log(rho) actmap = Maps.InjectActiveCells( mesh, indActive=actind, valInactive=np.log(1e8) ) mapping = Maps.ExpMap(mesh) * actmap # Generate mtrue_dc for resistivity mtrue_dc = np.log(rho[actind]) # Generate 2.5D DC problem # "N" means potential is defined at nodes prb = DC.Problem2D_N( mesh, rhoMap=mapping, storeJ=True, Solver=Solver ) # Pair problem with survey try: prb.pair(survey_dc) except: survey_dc.unpair() prb.pair(survey_dc) # Make synthetic DC data with 5% Gaussian noise dtrue_dc = survey_dc.makeSyntheticData(mtrue_dc, std=0.05, force=True) IO.data_dc = dtrue_dc # Generate mtrue_ip for chargability mtrue_ip = charg[actind] # Generate 2.5D DC problem # "N" means potential is defined at nodes prb_ip = IP.Problem2D_N( mesh, etaMap=actmap, storeJ=True, rho=rho, Solver=Solver ) survey_ip = IP.from_dc_to_ip_survey(survey_dc, dim="2.5D") prb_ip.pair(survey_ip) dtrue_ip = survey_ip.makeSyntheticData(mtrue_ip, std=0.05) IO.data_ip = dtrue_ip # Show apparent resisitivty pseudo-section if plotIt: IO.plotPseudoSection( data_type='apparent_resistivity', scale='log', cmap='viridis' ) plt.show() # Show apparent chargeability pseudo-section if plotIt: IO.plotPseudoSection( data_type='apparent_chargeability', scale='linear', cmap='magma' ) plt.show() # Show apparent resisitivty histogram if plotIt: fig = plt.figure(figsize=(10, 4)) ax1 = plt.subplot(121) out = hist(np.log10(abs(IO.voltages)), bins=20) ax1.set_xlabel("log10 DC voltage (V)") ax2 = plt.subplot(122) out = hist(IO.apparent_resistivity, bins=20) ax2.set_xlabel("Apparent Resistivity ($\Omega$m)") plt.tight_layout() plt.show() # Set initial model based upon histogram m0_dc = np.ones(actmap.nP)*np.log(100.) # Set uncertainty # floor eps_dc = 10**(-3.2) # percentage std_dc = 0.05 mopt_dc, pred_dc = DC.run_inversion( m0_dc, survey_dc, actind, mesh, std_dc, eps_dc, beta0_ratio=1e0, use_sensitivity_weight=True ) # Convert obtained inversion model to resistivity # rho = M(m), where M(.) is a mapping rho_est = mapping*mopt_dc rho_est[~actind] = np.nan rho_true = rho.copy() rho_true[~actind] = np.nan # show recovered conductivity if plotIt: vmin, vmax = rho.min(), rho.max() fig, ax = plt.subplots(2, 1, figsize=(20, 6)) out1 = mesh.plotImage( rho_true, clim=(10, 1000), pcolorOpts={"cmap": "viridis", "norm": colors.LogNorm()}, ax=ax[0] ) out2 = mesh.plotImage( rho_est, clim=(10, 1000), pcolorOpts={"cmap": "viridis", "norm": colors.LogNorm()}, ax=ax[1] ) out = [out1, out2] for i in range(2): ax[i].plot( survey_dc.electrode_locations[:, 0], survey_dc.electrode_locations[:, 1], 'kv' ) ax[i].set_xlim(IO.grids[:, 0].min(), IO.grids[:, 0].max()) ax[i].set_ylim(-IO.grids[:, 1].max(), IO.grids[:, 1].min()) cb = plt.colorbar(out[i][0], ax=ax[i]) cb.set_label("Resistivity ($\Omega$m)") ax[i].set_xlabel("Northing (m)") ax[i].set_ylabel("Elevation (m)") ax[i].set_aspect('equal') plt.tight_layout() plt.show() # Show apparent resisitivty histogram if plotIt: fig = plt.figure(figsize=(10, 4)) ax1 = plt.subplot(121) out = hist(np.log10(abs(IO.voltages_ip)), bins=20) ax1.set_xlabel("log10 IP voltage (V)") ax2 = plt.subplot(122) out = hist(IO.apparent_chargeability, bins=20) ax2.set_xlabel("Apparent Chargeability (V/V)") plt.tight_layout() plt.show() # Set initial model based upon histogram m0_ip = np.ones(actmap.nP)*1e-10 # Set uncertainty # floor eps_ip = 10**(-4) # percentage std_ip = 0.05 # Clean sensitivity function formed with true resistivity prb_ip._Jmatrix = None # Input obtained resistivity to form sensitivity prb_ip.rho = mapping*mopt_dc mopt_ip, _ = IP.run_inversion( m0_ip, survey_ip, actind, mesh, std_ip, eps_ip, upper=np.Inf, lower=0., beta0_ratio=1e0, use_sensitivity_weight=True ) # Convert obtained inversion model to chargeability # charg = M(m), where M(.) is a mapping for cells below topography charg_est = actmap*mopt_ip charg_est[~actind] = np.nan charg_true = charg.copy() charg_true[~actind] = np.nan # show recovered chargeability if plotIt: fig, ax = plt.subplots(2, 1, figsize=(20, 6)) out1 = mesh.plotImage( charg_true, clim=(0, 0.1), pcolorOpts={"cmap": "magma"}, ax=ax[0] ) out2 = mesh.plotImage( charg_est, clim=(0, 0.1), pcolorOpts={"cmap": "magma"}, ax=ax[1] ) out = [out1, out2] for i in range(2): ax[i].plot( survey_dc.electrode_locations[:, 0], survey_dc.electrode_locations[:, 1], 'rv' ) ax[i].set_xlim(IO.grids[:, 0].min(), IO.grids[:, 0].max()) ax[i].set_ylim(-IO.grids[:, 1].max(), IO.grids[:, 1].min()) cb = plt.colorbar(out[i][0], ax=ax[i]) cb.set_label("Resistivity ($\Omega$m)") ax[i].set_xlabel("Northing (m)") ax[i].set_ylabel("Elevation (m)") ax[i].set_aspect('equal') plt.tight_layout() plt.show()