def setUpClass(self): print('\n------- Testing Primary Secondary Source EB -> EB --------\n') # receivers self.rxlist = [] for rxtype in ['b', 'e']: rx = getattr(FDEM.Rx, 'Point_{}'.format(rxtype)) for orientation in ['x', 'y', 'z']: for comp in ['real', 'imag']: self.rxlist.append( rx(rx_locs, component=comp, orientation=orientation)) # primary self.primaryProblem = FDEM.Problem3D_b(meshp, sigmaMap=primaryMapping) self.primaryProblem.solver = Solver primarySrc = FDEM.Src.MagDipole(self.rxlist, freq=freq, loc=src_loc) self.primarySurvey = FDEM.Survey([primarySrc]) # Secondary Problem self.secondaryProblem = FDEM.Problem3D_b(meshs, sigmaMap=mapping) self.secondaryProblem.Solver = Solver self.secondarySrc = FDEM.Src.PrimSecMappedSigma( self.rxlist, freq, self.primaryProblem, self.primarySurvey, primaryMap2Meshs) self.secondarySurvey = FDEM.Survey([self.secondarySrc]) self.secondaryProblem.pair(self.secondarySurvey) # Full 3D problem to compare with self.problem3D = FDEM.Problem3D_b(meshs, sigmaMap=mapping) self.problem3D.Solver = Solver self.survey3D = FDEM.Survey([primarySrc]) self.problem3D.pair(self.survey3D) # solve and store fields print(' solving primary - secondary') self.fields_primsec = self.secondaryProblem.fields(model) print(' ... done') self.fields_primsec = self.secondaryProblem.fields(model) print(' solving 3D') self.fields_3D = self.problem3D.fields(model) print(' ... done') return None
def setUp(self): cs = 10. ncx, ncy, ncz = 30., 30., 30. npad = 10. hx = [(cs, npad, -1.5), (cs, ncx), (cs, npad, 1.5)] hy = [(cs, npad, -1.5), (cs, ncy), (cs, npad, 1.5)] hz = [(cs, npad, -1.5), (cs, ncz), (cs, npad, 1.5)] self.mesh = Mesh.TensorMesh([hx, hy, hz], 'CCC') mapping = Maps.ExpMap(self.mesh) self.freq = 1. self.prob_e = FDEM.Problem3D_e(self.mesh, mapping=mapping) self.prob_b = FDEM.Problem3D_b(self.mesh, mapping=mapping) self.prob_h = FDEM.Problem3D_h(self.mesh, mapping=mapping) self.prob_j = FDEM.Problem3D_j(self.mesh, mapping=mapping) loc = np.r_[0., 0., 0.] self.loc = Utils.mkvc( self.mesh.gridCC[Utils.closestPoints(self.mesh, loc, 'CC'), :])
def run(plotIt=True, saveFig=False): # Set up cylindrically symmeric mesh cs, ncx, ncz, npad = 10., 15, 25, 13 # padded cyl mesh hx = [(cs, ncx), (cs, npad, 1.3)] hz = [(cs, npad, -1.3), (cs, ncz), (cs, npad, 1.3)] mesh = Mesh.CylMesh([hx, 1, hz], '00C') # Conductivity model layerz = np.r_[-200., -100.] layer = (mesh.vectorCCz >= layerz[0]) & (mesh.vectorCCz <= layerz[1]) active = mesh.vectorCCz < 0. sig_half = 1e-2 # Half-space conductivity sig_air = 1e-8 # Air conductivity sig_layer = 5e-2 # Layer conductivity sigma = np.ones(mesh.nCz) * sig_air sigma[active] = sig_half sigma[layer] = sig_layer # Mapping actMap = Maps.InjectActiveCells(mesh, active, np.log(1e-8), nC=mesh.nCz) mapping = Maps.ExpMap(mesh) * Maps.SurjectVertical1D(mesh) * actMap mtrue = np.log(sigma[active]) # ----- FDEM problem & survey ----- # rxlocs = Utils.ndgrid([np.r_[50.], np.r_[0], np.r_[0.]]) bzr = FDEM.Rx.Point_bSecondary(rxlocs, 'z', 'real') bzi = FDEM.Rx.Point_bSecondary(rxlocs, 'z', 'imag') freqs = np.logspace(2, 3, 5) srcLoc = np.array([0., 0., 0.]) print('min skin depth = ', 500. / np.sqrt(freqs.max() * sig_half), 'max skin depth = ', 500. / np.sqrt(freqs.min() * sig_half)) print('max x ', mesh.vectorCCx.max(), 'min z ', mesh.vectorCCz.min(), 'max z ', mesh.vectorCCz.max()) srcList = [ FDEM.Src.MagDipole([bzr, bzi], freq, srcLoc, orientation='Z') for freq in freqs ] surveyFD = FDEM.Survey(srcList) prbFD = FDEM.Problem3D_b(mesh, sigmaMap=mapping, Solver=Solver) prbFD.pair(surveyFD) std = 0.03 surveyFD.makeSyntheticData(mtrue, std) surveyFD.eps = np.linalg.norm(surveyFD.dtrue) * 1e-5 # FDEM inversion np.random.seed(1) dmisfit = DataMisfit.l2_DataMisfit(surveyFD) regMesh = Mesh.TensorMesh([mesh.hz[mapping.maps[-1].indActive]]) reg = Regularization.Simple(regMesh) opt = Optimization.InexactGaussNewton(maxIterCG=10) invProb = InvProblem.BaseInvProblem(dmisfit, reg, opt) # Inversion Directives beta = Directives.BetaSchedule(coolingFactor=4, coolingRate=3) betaest = Directives.BetaEstimate_ByEig(beta0_ratio=2.) target = Directives.TargetMisfit() directiveList = [beta, betaest, target] inv = Inversion.BaseInversion(invProb, directiveList=directiveList) m0 = np.log(np.ones(mtrue.size) * sig_half) reg.alpha_s = 5e-1 reg.alpha_x = 1. prbFD.counter = opt.counter = Utils.Counter() opt.remember('xc') moptFD = inv.run(m0) # TDEM problem times = np.logspace(-4, np.log10(2e-3), 10) print('min diffusion distance ', 1.28 * np.sqrt(times.min() / (sig_half * mu_0)), 'max diffusion distance ', 1.28 * np.sqrt(times.max() / (sig_half * mu_0))) rx = TDEM.Rx.Point_b(rxlocs, times, 'z') src = TDEM.Src.MagDipole( [rx], waveform=TDEM.Src.StepOffWaveform(), loc=srcLoc # same src location as FDEM problem ) surveyTD = TDEM.Survey([src]) prbTD = TDEM.Problem3D_b(mesh, sigmaMap=mapping, Solver=Solver) prbTD.timeSteps = [(5e-5, 10), (1e-4, 10), (5e-4, 10)] prbTD.pair(surveyTD) std = 0.03 surveyTD.makeSyntheticData(mtrue, std) surveyTD.std = std surveyTD.eps = np.linalg.norm(surveyTD.dtrue) * 1e-5 # TDEM inversion dmisfit = DataMisfit.l2_DataMisfit(surveyTD) regMesh = Mesh.TensorMesh([mesh.hz[mapping.maps[-1].indActive]]) reg = Regularization.Simple(regMesh) opt = Optimization.InexactGaussNewton(maxIterCG=10) invProb = InvProblem.BaseInvProblem(dmisfit, reg, opt) # directives beta = Directives.BetaSchedule(coolingFactor=4, coolingRate=3) betaest = Directives.BetaEstimate_ByEig(beta0_ratio=2.) target = Directives.TargetMisfit() directiveList = [beta, betaest, target] inv = Inversion.BaseInversion(invProb, directiveList=directiveList) m0 = np.log(np.ones(mtrue.size) * sig_half) reg.alpha_s = 5e-1 reg.alpha_x = 1. prbTD.counter = opt.counter = Utils.Counter() opt.remember('xc') moptTD = inv.run(m0) # Plot the results if plotIt: plt.figure(figsize=(10, 8)) ax0 = plt.subplot2grid((2, 2), (0, 0), rowspan=2) ax1 = plt.subplot2grid((2, 2), (0, 1)) ax2 = plt.subplot2grid((2, 2), (1, 1)) fs = 13 # fontsize matplotlib.rcParams['font.size'] = fs # Plot the model ax0.semilogx(sigma[active], mesh.vectorCCz[active], 'k-', lw=2, label="True") ax0.semilogx(np.exp(moptFD), mesh.vectorCCz[active], 'bo', ms=6, markeredgecolor='k', markeredgewidth=0.5, label="FDEM") ax0.semilogx(np.exp(moptTD), mesh.vectorCCz[active], 'r*', ms=10, markeredgecolor='k', markeredgewidth=0.5, label="TDEM") ax0.set_ylim(-700, 0) ax0.set_xlim(5e-3, 1e-1) ax0.set_xlabel('Conductivity (S/m)', fontsize=fs) ax0.set_ylabel('Depth (m)', fontsize=fs) ax0.grid(which='both', color='k', alpha=0.5, linestyle='-', linewidth=0.2) ax0.legend(fontsize=fs, loc=4) # plot the data misfits - negative b/c we choose positive to be in the # direction of primary ax1.plot(freqs, -surveyFD.dobs[::2], 'k-', lw=2, label="Obs (real)") ax1.plot(freqs, -surveyFD.dobs[1::2], 'k--', lw=2, label="Obs (imag)") dpredFD = surveyFD.dpred(moptTD) ax1.loglog(freqs, -dpredFD[::2], 'bo', ms=6, markeredgecolor='k', markeredgewidth=0.5, label="Pred (real)") ax1.loglog(freqs, -dpredFD[1::2], 'b+', ms=10, markeredgewidth=2., label="Pred (imag)") ax2.loglog(times, surveyTD.dobs, 'k-', lw=2, label='Obs') ax2.loglog(times, surveyTD.dpred(moptTD), 'r*', ms=10, markeredgecolor='k', markeredgewidth=0.5, label='Pred') ax2.set_xlim(times.min() - 1e-5, times.max() + 1e-4) # Labels, gridlines, etc ax2.grid(which='both', alpha=0.5, linestyle='-', linewidth=0.2) ax1.grid(which='both', alpha=0.5, linestyle='-', linewidth=0.2) ax1.set_xlabel('Frequency (Hz)', fontsize=fs) ax1.set_ylabel('Vertical magnetic field (-T)', fontsize=fs) ax2.set_xlabel('Time (s)', fontsize=fs) ax2.set_ylabel('Vertical magnetic field (T)', fontsize=fs) ax2.legend(fontsize=fs, loc=3) ax1.legend(fontsize=fs, loc=3) ax1.set_xlim(freqs.max() + 1e2, freqs.min() - 1e1) ax0.set_title("(a) Recovered Models", fontsize=fs) ax1.set_title("(b) FDEM observed vs. predicted", fontsize=fs) ax2.set_title("(c) TDEM observed vs. predicted", fontsize=fs) plt.tight_layout(pad=1.5) if saveFig is True: plt.savefig('example1.png', dpi=600)
def run(plotIt=True): """ 1D FDEM Mu Inversion ==================== 1D inversion of Magnetic Susceptibility from FDEM data assuming a fixed electrical conductivity """ # Set up cylindrically symmeric mesh cs, ncx, ncz, npad = 10., 15, 25, 13 # padded cyl mesh hx = [(cs, ncx), (cs, npad, 1.3)] hz = [(cs, npad, -1.3), (cs, ncz), (cs, npad, 1.3)] mesh = Mesh.CylMesh([hx, 1, hz], '00C') # Geologic Parameters model layerz = np.r_[-100., -50.] layer = (mesh.vectorCCz >= layerz[0]) & (mesh.vectorCCz <= layerz[1]) active = mesh.vectorCCz < 0. # Electrical Conductivity sig_half = 1e-2 # Half-space conductivity sig_air = 1e-8 # Air conductivity sig_layer = 1e-2 # Layer conductivity sigma = np.ones(mesh.nCz) * sig_air sigma[active] = sig_half sigma[layer] = sig_layer # mur - relative magnetic permeability mur_half = 1. mur_air = 1. mur_layer = 2. mur = np.ones(mesh.nCz) * mur_air mur[active] = mur_half mur[layer] = mur_layer mtrue = mur[active] # Maps actMap = Maps.InjectActiveCells(mesh, active, mur_air, nC=mesh.nCz) surj1Dmap = Maps.SurjectVertical1D(mesh) murMap = Maps.MuRelative(mesh) # Mapping muMap = murMap * surj1Dmap * actMap # ----- FDEM problem & survey ----- rxlocs = Utils.ndgrid([np.r_[10.], np.r_[0], np.r_[30.]]) bzr = FDEM.Rx.Point_bSecondary(rxlocs, 'z', 'real') # bzi = FDEM.Rx.Point_bSecondary(rxlocs, 'z', 'imag') freqs = np.linspace(2000, 10000, 10) #np.logspace(3, 4, 10) srcLoc = np.array([0., 0., 30.]) print('min skin depth = ', 500. / np.sqrt(freqs.max() * sig_half), 'max skin depth = ', 500. / np.sqrt(freqs.min() * sig_half)) print('max x ', mesh.vectorCCx.max(), 'min z ', mesh.vectorCCz.min(), 'max z ', mesh.vectorCCz.max()) srcList = [ FDEM.Src.MagDipole([bzr], freq, srcLoc, orientation='Z') for freq in freqs ] surveyFD = FDEM.Survey(srcList) prbFD = FDEM.Problem3D_b(mesh, sigma=surj1Dmap * sigma, muMap=muMap, Solver=Solver) prbFD.pair(surveyFD) std = 0.03 surveyFD.makeSyntheticData(mtrue, std) surveyFD.eps = np.linalg.norm(surveyFD.dtrue) * 1e-6 # FDEM inversion np.random.seed(13472) dmisfit = DataMisfit.l2_DataMisfit(surveyFD) regMesh = Mesh.TensorMesh([mesh.hz[muMap.maps[-1].indActive]]) reg = Regularization.Simple(regMesh) opt = Optimization.InexactGaussNewton(maxIterCG=10) invProb = InvProblem.BaseInvProblem(dmisfit, reg, opt) # Inversion Directives betaest = Directives.BetaEstimate_ByEig(beta0_ratio=2.) beta = Directives.BetaSchedule(coolingFactor=4, coolingRate=3) betaest = Directives.BetaEstimate_ByEig(beta0_ratio=2.) target = Directives.TargetMisfit() directiveList = [beta, betaest, target] inv = Inversion.BaseInversion(invProb, directiveList=directiveList) m0 = mur_half * np.ones(mtrue.size) reg.alpha_s = 2e-2 reg.alpha_x = 1. prbFD.counter = opt.counter = Utils.Counter() opt.remember('xc') moptFD = inv.run(m0) dpredFD = surveyFD.dpred(moptFD) if plotIt: fig, ax = plt.subplots(1, 3, figsize=(10, 6)) fs = 13 # fontsize matplotlib.rcParams['font.size'] = fs # Plot the conductivity model ax[0].semilogx(sigma[active], mesh.vectorCCz[active], 'k-', lw=2) ax[0].set_ylim(-500, 0) ax[0].set_xlim(5e-3, 1e-1) ax[0].set_xlabel('Conductivity (S/m)', fontsize=fs) ax[0].set_ylabel('Depth (m)', fontsize=fs) ax[0].grid(which='both', color='k', alpha=0.5, linestyle='-', linewidth=0.2) ax[0].legend(['Conductivity Model'], fontsize=fs, loc=4) # Plot the permeability model ax[1].plot(mur[active], mesh.vectorCCz[active], 'k-', lw=2) ax[1].plot(moptFD, mesh.vectorCCz[active], 'b-', lw=2) ax[1].set_ylim(-500, 0) ax[1].set_xlim(0.5, 2.1) ax[1].set_xlabel('Relative Permeability', fontsize=fs) ax[1].set_ylabel('Depth (m)', fontsize=fs) ax[1].grid(which='both', color='k', alpha=0.5, linestyle='-', linewidth=0.2) ax[1].legend(['True', 'Predicted'], fontsize=fs, loc=4) # plot the data misfits - negative b/c we choose positive to be in the # direction of primary ax[2].plot(freqs, -surveyFD.dobs, 'k-', lw=2) # ax[2].plot(freqs, -surveyFD.dobs[1::2], 'k--', lw=2) ax[2].loglog(freqs, -dpredFD, 'bo', ms=6) # ax[2].loglog(freqs, -dpredFD[1::2], 'b+', markeredgewidth=2., ms=10) # Labels, gridlines, etc ax[2].grid(which='both', alpha=0.5, linestyle='-', linewidth=0.2) ax[2].grid(which='both', alpha=0.5, linestyle='-', linewidth=0.2) ax[2].set_xlabel('Frequency (Hz)', fontsize=fs) ax[2].set_ylabel('Vertical magnetic field (-T)', fontsize=fs) # ax[2].legend(("Obs", "Pred"), fontsize=fs) ax[2].legend(("z-Obs (real)", "z-Pred (real)"), fontsize=fs) ax[2].set_xlim(freqs.max(), freqs.min()) ax[0].set_title("(a) Conductivity Model", fontsize=fs) ax[1].set_title("(b) $\mu_r$ Model", fontsize=fs) ax[2].set_title("(c) FDEM observed vs. predicted", fontsize=fs) # ax[2].set_title("(c) TDEM observed vs. predicted", fontsize=fs) plt.tight_layout(pad=1.5)
# Get cells inside the sphere sph_ind = PF.MagAnalytics.spheremodel(mesh, 0., 0., 0., rad) # Adjust susceptibility for volume difference Vratio = (4. / 3. * np.pi * rad**3.) / (np.sum(sph_ind) * cs**3.) model = np.ones(mesh.nC) * 1e-8 model[sph_ind] = 0.01 rxLoc = np.asarray([np.r_[0, 0, 4.]]) bzi = FDEM.Rx.Point_bSecondary(rxLoc, 'z', 'real') bzr = FDEM.Rx.Point_bSecondary(rxLoc, 'z', 'imag') freqs = [400] #np.logspace(2, 3, 5) srcLoc = np.r_[0, 0, 4.] srcList = [ FDEM.Src.MagDipole([bzr, bzi], freq, srcLoc, orientation='Z') for freq in freqs ] mapping = Maps.IdentityMap(mesh) surveyFD = FDEM.Survey(srcList) prbFD = FDEM.Problem3D_b(mesh, sigmaMap=mapping, Solver=PardisoSolver) prbFD.pair(surveyFD) std = 0.03 surveyFD.makeSyntheticData(model, std) #Mesh.TensorMesh.writeUBC(mesh,'MeshGrav.msh') #Mesh.TensorMesh.writeModelUBC(mesh,'MeshGrav.den',model) #PF.Gravity.writeUBCobs("Obs.grv",survey,d)
orientation=orientation, component='real') rx_imag = FDEM.Rx.Point_bSecondary(locs=rx_locs, orientation=orientation, component='imag') src = FDEM.Src.MagDipole(rxList=[rx_real, rx_imag], loc=src_loc, orientation=orientation, freq=freq) srcList.append(src) # create the survey and problem objects for running the forward simulation survey = FDEM.Survey(srcList) prob = FDEM.Problem3D_b(mesh, sigmaMap=mapping, Solver=Solver) prob.pair(survey) ############################################################################### # Data # ---- # # Generate clean, synthetic data t = time.time() dclean = survey.dpred(m_true) print("Done forward simulation. Elapsed time = {:1.2f} s".format(time.time() - t))