def prob(self): if getattr(self, '_prob', None) is None: self._prob = getattr( TDEM, 'Problem3D_{}'.format(self.formulation) )( self.meshGenerator.mesh, timeSteps=self.modelParameters.timeSteps, sigmaMap=self.physprops.wires.sigma, mu=self.physprops. mu, # right now the TDEM code doesn't support mu inversions Solver=Solver, verbose=self.verbose) self._survey = TDEM.Survey(self.srcList.srcList) self._prob.pair(self._survey) return self._prob
def __init__(self, **kwargs): super(SimulationTDEM, self).__init__(**kwargs) self._prob = getattr( TDEM, 'Problem3D_{}'.format(self.formulation) )( self.meshGenerator.mesh, timeSteps=self.cp.timeSteps, sigmaMap=self.physprops.wires.sigma, mu=self.physprops.mu, # right now the TDEM code doesn't support mu inversions Solver=Pardiso ) if getattr(self.src, "physics", None) is None: self.src.physics = "TDEM" self._survey = TDEM.Survey(self.src.srcList) self._prob.pair(self._survey)
def run_simulation(fname="tdem_gs_half.h5", sigma_block=0.01, sigma_halfspace=0.01): from SimPEG.EM import TDEM, Analytics, mu_0 import numpy as np from SimPEG import Mesh, Maps, Utils, EM, Survey from pymatsolver import Pardiso cs = 20 ncx, ncy, ncz = 20, 20, 20 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)] mesh = Mesh.TensorMesh([hx, hy, hz], "CCC") sigma = np.ones(mesh.nC) * sigma_halfspace blk_ind = Utils.ModelBuilder.getIndicesBlock(np.r_[-40, -40, -160], np.r_[40, 40, -80], mesh.gridCC) sigma[mesh.gridCC[:, 2] > 0.0] = 1e-8 sigma[blk_ind] = sigma_block xmin, xmax = -200.0, 200.0 ymin, ymax = -200.0, 200.0 x = mesh.vectorCCx[np.logical_and(mesh.vectorCCx > xmin, mesh.vectorCCx < xmax)] y = mesh.vectorCCy[np.logical_and(mesh.vectorCCy > ymin, mesh.vectorCCy < ymax)] xyz = Utils.ndgrid(x, y, np.r_[-1.0]) px = np.r_[-200.0, 200.0] py = np.r_[0.0, 0.0] pz = np.r_[0.0, 0.0] srcLoc = np.c_[px, py, pz] from scipy.interpolate import interp1d prb = TDEM.Problem3D_b(mesh, sigma=sigma, verbose=True) prb.Solver = Pardiso prb.solverOpts = {"is_symmetric": False} prb.timeSteps = [(1e-3, 10), (2e-5, 10), (1e-4, 10), (5e-4, 10), (1e-3, 10)] t0 = 0.01 + 1e-4 out = EM.Utils.VTEMFun(prb.times, 0.01, t0, 200) wavefun = interp1d(prb.times, out) waveform = EM.TDEM.Src.RawWaveform(offTime=t0, waveFct=wavefun) input_currents = wavefun(prb.times) times = np.logspace(-4, -2, 21) rx_ex = TDEM.Rx.Point_e(xyz, times + t0, orientation="x") rx_ey = TDEM.Rx.Point_e(xyz, times + t0, orientation="y") rx_by = TDEM.Rx.Point_e(xyz, times + t0, orientation="y") rxList = [rx_ex, rx_ey, rx_by] src = TDEM.Src.LineCurrent(rxList, loc=srcLoc, waveform=waveform) survey = TDEM.Survey([src]) survey.pair(prb) f = prb.fields(sigma) xyzlim = np.array([[xmin, xmax], [ymin, ymax], [-400, 0.0]]) actinds, meshCore = Utils.ExtractCoreMesh(xyzlim, mesh) Pex = mesh.getInterpolationMat(meshCore.gridCC, locType="Ex") Pey = mesh.getInterpolationMat(meshCore.gridCC, locType="Ey") Pez = mesh.getInterpolationMat(meshCore.gridCC, locType="Ez") Pfx = mesh.getInterpolationMat(meshCore.gridCC, locType="Fx") Pfy = mesh.getInterpolationMat(meshCore.gridCC, locType="Fy") Pfz = mesh.getInterpolationMat(meshCore.gridCC, locType="Fz") sigma_core = sigma[actinds] def getEBJcore(src0): B0 = np.r_[Pfx * f[src0, "b"], Pfy * f[src0, "b"], Pfz * f[src0, "b"]] E0 = np.r_[Pex * f[src0, "e"], Pey * f[src0, "e"], Pez * f[src0, "e"]] J0 = Utils.sdiag(np.r_[sigma_core, sigma_core, sigma_core]) * E0 return E0, B0, J0 E, B, J = getEBJcore(src) tdem_gs = { "E": E, "B": B, "J": J, "sigma": sigma_core, "mesh": meshCore.serialize(), "time": prb.times - t0, "input_currents": input_currents, } dd.io.save(fname, tdem_gs)
[], loc=np.r_[0., 0., 0.], orientation="z", radius=100, waveform=quarter_sine ) src_list_magnetostatic = [src_magnetostatic] src_list_ramp_on = [src_ramp_on] ############################################################################### # Create the simulations # ---------------------- # # To simulate magnetic flux data, we use the b-formulation of Maxwell's # equations prob_magnetostatic = TDEM.Problem3D_b( mesh=mesh, sigmaMap=Maps.IdentityMap(mesh), timeSteps=ramp, Solver=Pardiso ) prob_ramp_on = TDEM.Problem3D_b( mesh=mesh, sigmaMap=Maps.IdentityMap(mesh), timeSteps=ramp, Solver=Pardiso ) survey_magnetostatic = TDEM.Survey(srcList=src_list_magnetostatic) survey_ramp_on = TDEM.Survey(src_list_ramp_on) prob_magnetostatic.pair(survey_magnetostatic) prob_ramp_on.pair(survey_ramp_on) ############################################################################### # Run the long on-time simulation # -------------------------------
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 test_permeable_sources(self): target_mur = self.target_mur target_l = self.target_l target_r = self.target_r sigma_back = self.sigma_back model_names = self.model_names mesh = self.mesh radius_loop = self.radius_loop # Assign physical properties on the mesh def populate_target(mur): mu_model = np.ones(mesh.nC) x_inds = mesh.gridCC[:, 0] < target_r z_inds = ( (mesh.gridCC[:, 2] <= 0) & (mesh.gridCC[:, 2] >= -target_l) ) mu_model[x_inds & z_inds] = mur return mu_0 * mu_model mu_dict = { key: populate_target(mu) for key, mu in zip(model_names, target_mur) } sigma = np.ones(mesh.nC) * sigma_back # Plot the models if plotIt: xlim = np.r_[-200, 200] # x-limits in meters zlim = np.r_[-1.5*target_l, 10.] # z-limits in meters. (z-positive up) fig, ax = plt.subplots( 1, len(model_names), figsize=(6*len(model_names), 5) ) if len(model_names) == 1: ax = [ax] for a, key in zip(ax, model_names): plt.colorbar(mesh.plotImage( mu_dict[key], ax=a, pcolorOpts={'norm': LogNorm()}, # plot on a log-scale mirror=True )[0], ax=a) a.set_title('{}'.format(key), fontsize=13) # cylMeshGen.mesh.plotGrid(ax=a, slice='theta') # uncomment to plot the mesh on top of this a.set_xlim(xlim) a.set_ylim(zlim) plt.tight_layout() plt.show() ramp = [ (1e-5, 20), (1e-4, 20), (3e-4, 20), (1e-3, 20), (3e-3, 20), (1e-2, 20), (3e-2, 20), (1e-1, 20), (3e-1, 20), (1, 50) ] timeSteps = ramp time_mesh = discretize.TensorMesh([ramp]) offTime = 10000 waveform = TDEM.Src.QuarterSineRampOnWaveform( ramp_on=np.r_[1e-4, 20], ramp_off=offTime - np.r_[1e-4, 0] ) if plotIt: wave = np.r_[[waveform.eval(t) for t in time_mesh.gridN]] plt.plot(time_mesh.gridN, wave) plt.plot(time_mesh.gridN, np.zeros(time_mesh.nN), '-|', color='k') plt.show() src_magnetostatic = TDEM.Src.CircularLoop( [], loc=np.r_[0., 0., 0.], orientation="z", radius=100, ) src_ramp_on = TDEM.Src.CircularLoop( [], loc=np.r_[0., 0., 0.], orientation="z", radius=100, waveform=waveform ) src_list = [src_magnetostatic] src_list_late_ontime = [src_ramp_on] prob = TDEM.Problem3D_b( mesh=mesh, timeSteps=timeSteps, sigmaMap=Maps.IdentityMap(mesh), Solver=Pardiso ) prob_late_ontime = TDEM.Problem3D_b( mesh=mesh, timeSteps=timeSteps, sigmaMap=Maps.IdentityMap(mesh), Solver=Pardiso ) survey = TDEM.Survey(srcList=src_list) survey_late_ontime = TDEM.Survey(src_list_late_ontime) prob.pair(survey) prob_late_ontime.pair(survey_late_ontime) fields_dict = {} for key in model_names: t = time.time() print('--- Running {} ---'.format(key)) prob_late_ontime.mu = mu_dict[key] fields_dict[key] = prob_late_ontime.fields(sigma) print(" ... done. Elapsed time {}".format(time.time() - t)) print('\n') b_magnetostatic = {} b_late_ontime = {} for key in model_names: prob.mu = mu_dict[key] prob.sigma = sigma b_magnetostatic[key] = src_magnetostatic.bInitial(prob) prob_late_ontime.mu = mu_dict[key] b_late_ontime[key] = utils.mkvc( fields_dict[key][:, 'b', -1] ) if plotIt: fig, ax = plt.subplots( len(model_names), 2, figsize=(3*len(model_names), 5) ) for i, key in enumerate(model_names): ax[i][0].semilogy( np.absolute(b_magnetostatic[key]), label='magnetostatic' ) ax[i][0].semilogy( np.absolute(b_late_ontime[key]), label='late on-time' ) ax[i][0].legend() ax[i][1].semilogy( np.absolute(b_magnetostatic[key] - b_late_ontime[key]) ) plt.tight_layout() plt.show() print("Testing TDEM with permeable targets") passed = [] for key in model_names: norm_magneotstatic = np.linalg.norm(b_magnetostatic[key]) norm_late_ontime = np.linalg.norm(b_late_ontime[key]) norm_diff = np.linalg.norm( b_magnetostatic[key] - b_late_ontime[key] ) passed_test = ( norm_diff / (0.5*(norm_late_ontime + norm_magneotstatic)) < TOL ) print("\n{}".format(key)) print( "||magnetostatic||: {:1.2e}, " "||late on-time||: {:1.2e}, " "||difference||: {:1.2e} passed?: {}".format( norm_magneotstatic, norm_late_ontime, norm_diff, passed_test ) ) passed += [passed_test] assert all(passed) prob.sigma = 1e-4*np.ones(mesh.nC) v = utils.mkvc(np.random.rand(mesh.nE)) w = utils.mkvc(np.random.rand(mesh.nF)) assert( np.all( mesh.getEdgeInnerProduct(1e-4*np.ones(mesh.nC))*v == prob.MeSigma*v ) ) assert( np.all( mesh.getEdgeInnerProduct( 1e-4*np.ones(mesh.nC), invMat=True )*v == prob.MeSigmaI*v ) ) assert( np.all( mesh.getFaceInnerProduct(1./1e-4*np.ones(mesh.nC))*w == prob.MfRho*w ) ) assert( np.all( mesh.getFaceInnerProduct( 1./1e-4*np.ones(mesh.nC), invMat=True )*w == prob.MfRhoI*w ) ) prob.rho = 1./1e-3*np.ones(mesh.nC) v = utils.mkvc(np.random.rand(mesh.nE)) w = utils.mkvc(np.random.rand(mesh.nF)) assert( np.all( mesh.getEdgeInnerProduct(1e-3*np.ones(mesh.nC))*v == prob.MeSigma*v ) ) assert( np.all( mesh.getEdgeInnerProduct( 1e-3*np.ones(mesh.nC), invMat=True )*v == prob.MeSigmaI*v ) ) assert( np.all( mesh.getFaceInnerProduct(1./1e-3*np.ones(mesh.nC))*w == prob.MfRho*w ) ) assert( np.all( mesh.getFaceInnerProduct( 1./1e-3*np.ones(mesh.nC), invMat=True )*w == prob.MfRhoI*w ) )
def setUpClass(self): # mesh cs = 10 npad = 4 ncore = 5 h = [(cs, npad, -1.5), (cs, ncore), (cs, npad, 1.5)] mesh = discretize.TensorMesh([h, h, h], x0="CCC") # source src_a = np.r_[-cs*2, 0., 0.] src_b = np.r_[cs*2, 0., 0.] s_e = np.zeros(mesh.nFx) src_inds = ( (mesh.gridFx[:, 0] >= src_a[0]) & (mesh.gridFx[:, 0] <= src_b[0]) & (mesh.gridFx[:, 1] >= src_a[1]) & (mesh.gridFx[:, 1] <= src_b[1]) & (mesh.gridFx[:, 2] >= src_a[2]) & (mesh.gridFx[:, 2] <= src_b[2]) ) s_e[src_inds] = 1. s_e = np.hstack([s_e, np.zeros(mesh.nFy + mesh.nFz)]) # define a model with a conductive, permeable target sigma0 = 1e-1 sigma1 = 1 mu0 = mu_0 mu1 = 100*mu_0 h_target = np.r_[-30, 30] target_inds = ( (mesh.gridCC[:, 0] >= h_target[0]) & (mesh.gridCC[:, 0] <= h_target[1]) & (mesh.gridCC[:, 1] >= h_target[0]) & (mesh.gridCC[:, 1] <= h_target[1]) & (mesh.gridCC[:, 2] >= h_target[0]) & (mesh.gridCC[:, 2] <= h_target[1]) ) sigma = sigma0 * np.ones(mesh.nC) sigma[target_inds] = sigma1 mu = mu0 * np.ones(mesh.nC) mu[target_inds] = mu1 src = TDEM.Src.RawVec_Grounded([], s_e=s_e) timeSteps = [ (1e-6, 20), (1e-5, 30), (3e-5, 30), (1e-4, 40), (3e-4, 30), (1e-3, 20), (1e-2, 17) ] prob = getattr(TDEM, "Problem3D_{}".format(self.prob_type))( mesh, timeSteps=timeSteps, mu=mu, sigmaMap=Maps.ExpMap(mesh), Solver=Pardiso ) survey = TDEM.Survey([src]) prob.model = sigma self.mesh = mesh self.prob = prob self.survey = survey self.src = src self.sigma = sigma self.mu = mu print("Testing problem {} \n\n".format(self.prob_type))