# The total number of cells nC = mesh.nC # An (nC, 2) array containing the cell-center locations cc = mesh.gridCC # A boolean array specifying which cells lie on the boundary bInd = mesh.cellBoundaryInd # Plot the cell areas (2D "volume") s = mesh.vol fig = plt.figure(figsize=(6, 6)) ax = fig.add_subplot(111) mesh.plotImage(s, grid=True, ax=ax) ax.set_xbound(mesh.x0[0], mesh.x0[0] + np.sum(mesh.hx)) ax.set_ybound(mesh.x0[1], mesh.x0[1] + np.sum(mesh.hy)) ax.set_title("Cell Areas") ############################################### # 3D Example # ---------- # # Here we show how the same approach can be used to create and extract # properties from a 3D tensor mesh. # nc = 10 # number of core mesh cells in x, y and z dh = 10 # base cell width in x, y and z
class TDEMHorizontalLoopCylWidget(object): """TDEMCylWidgete""" survey = None srcList = None mesh = None f = None activeCC = None srcLoc = None mesh2D = None mu = None counter = 0 def __init__(self): self.genMesh() self.getCoreDomain() # url = "http://em.geosci.xyz/_images/disc_dipole.png" # response = requests.get(url) # self.im = Image.open(StringIO(response.content)) self.time = np.logspace(-5, -2, 41) def mirrorArray(self, x, direction="x"): X = x.reshape((self.nx_core, self.ny_core), order="F") if direction == "x" or direction == "y": X2 = np.vstack((-np.flipud(X), X)) else: X2 = np.vstack((np.flipud(X), X)) return X2 def genMesh(self, h=0.0, cs=3.0, ncx=15, ncz=30, npad=20): """ Generate cylindrically symmetric mesh """ # TODO: Make it adaptive due to z location hx = [(cs, ncx), (cs, npad, 1.3)] hz = [(cs, npad, -1.3), (cs, ncz), (cs, npad, 1.3)] self.mesh = CylMesh([hx, 1, hz], "00C") def getCoreDomain(self, mirror=False, xmax=200, zmin=-200, zmax=200.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 getCoreModel(self, Type): if Type == "Layer": active = self.mesh2D.vectorCCy < self.z0 ind1 = (self.mesh2D.vectorCCy < self.z0) & (self.mesh2D.vectorCCy >= self.z1) ind2 = (self.mesh2D.vectorCCy < self.z1) & (self.mesh2D.vectorCCy >= self.z2) mapping2D = maps.SurjectVertical1D( self.mesh2D) * maps.InjectActiveCells( self.mesh2D, active, self.sig0, nC=self.mesh2D.nCy) model2D = np.ones(self.mesh2D.nCy) * self.sig3 model2D[ind1] = self.sig1 model2D[ind2] = self.sig2 model2D = model2D[active] elif Type == "Sphere": active = self.mesh2D.gridCC[:, 1] < self.z0 ind1 = (self.mesh2D.gridCC[:, 1] < self.z1) & (self.mesh2D.gridCC[:, 1] >= self.z1 - self.h) ind2 = (np.sqrt((self.mesh2D.gridCC[:, 0])**2 + (self.mesh2D.gridCC[:, 1] - self.z2)**2) <= self.R) mapping2D = maps.InjectActiveCells(self.mesh2D, active, self.sig0, nC=self.mesh2D.nC) model2D = np.ones(self.mesh2D.nC) * self.sigb model2D[ind1] = self.sig1 model2D[ind2] = self.sig2 model2D = model2D[active] return model2D, mapping2D def getBiotSavrt(self, rxLoc): """ Compute Biot-Savart operator: Gz and Gx """ self.Gz = BiotSavartFun(self.mesh, rxLoc, component="z") self.Gx = BiotSavartFun(self.mesh, rxLoc, component="x") def setThreeLayerParam(self, h1=12, h2=12, sig0=1e-8, sig1=1e-2, sig2=1e-2, sig3=1e-2, chi=0.0): self.h1 = h1 # 1st layer thickness self.h2 = h2 # 2nd layer thickness self.z0 = 0.0 self.z1 = self.z0 - h1 self.z2 = self.z0 - h1 - h2 self.sig0 = sig0 # 0th layer \sigma (assumed to be air) self.sig1 = sig1 # 1st layer \sigma self.sig2 = sig2 # 2nd layer \sigma self.sig3 = sig3 # 3rd layer \sigma active = self.mesh.vectorCCz < self.z0 ind1 = (self.mesh.vectorCCz < self.z0) & (self.mesh.vectorCCz >= self.z1) ind2 = (self.mesh.vectorCCz < self.z1) & (self.mesh.vectorCCz >= self.z2) self.mapping = maps.SurjectVertical1D( self.mesh) * maps.InjectActiveCells( self.mesh, active, sig0, nC=self.mesh.nCz) model = np.ones(self.mesh.nCz) * sig3 model[ind1] = sig1 model[ind2] = sig2 self.m = model[active] self.mu = np.ones(self.mesh.nC) * mu_0 self.mu[self.mesh.gridCC[:, 2] < 0.0] = (1.0 + chi) * mu_0 return self.m def setLayerSphereParam(self, d1=6, h=6, d2=16, R=4, sig0=1e-8, sigb=1e-2, sig1=1e-1, sig2=1.0, chi=0.0): self.z0 = 0.0 # Surface elevation self.z1 = self.z0 - d1 # Depth to layer self.h = h # Thickness of layer self.z2 = self.z0 - d2 # Depth to center of sphere self.R = R # Radius of sphere self.sig0 = sig0 # Air conductivity self.sigb = sigb # Background conductivity self.sig1 = sig1 # Layer conductivity self.sig2 = sig2 # Sphere conductivity active = self.mesh.gridCC[:, 2] < self.z0 ind1 = (self.mesh.gridCC[:, 2] < self.z1) & (self.mesh.gridCC[:, 2] >= self.z1 - self.h) ind2 = (np.sqrt((self.mesh.gridCC[:, 0])**2 + (self.mesh.gridCC[:, 2] - self.z2)**2) <= self.R) self.mapping = maps.InjectActiveCells(self.mesh, active, sig0, nC=self.mesh.nC) model = np.ones(self.mesh.nC) * sigb model[ind1] = sig1 model[ind2] = sig2 self.m = model[active] self.mu = np.ones(self.mesh.nC) * mu_0 self.mu[self.mesh.gridCC[:, 2] < 0.0] = (1.0 + chi) * mu_0 return self.m def simulate(self, srcLoc, rxLoc, time, radius=1.0): bz = tdem.receivers.PointMagneticFluxDensity(rxLoc, time, orientation="z") # dbzdt = EM.TDEM.Rx.Point_dbdt(rxLoc, time, orientation="z") src = tdem.sources.CircularLoop( [bz], waveform=tdem.sources.StepOffWaveform(), location=srcLoc, radius=radius) self.srcList = [src] survey = tdem.survey.Survey(self.srcList) sim = tdem.Simulation3DMagneticFluxDensity(self.mesh, survey=survey, sigmaMap=self.mapping) sim.time_steps = [ (1e-06, 10), (5e-06, 10), (1e-05, 10), (5e-5, 10), (1e-4, 10), (5e-4, 10), (1e-3, 10), ] self.f = sim.fields(self.m) self.sim = sim dpred = sim.dpred(self.m, f=self.f) return dpred @property def Pfx(self): if getattr(self, "_Pfx", None) is None: self._Pfx = self.mesh.getInterpolationMat( self.mesh.gridCC[self.activeCC, :], locType="Fx") return self._Pfx @property def Pfz(self): if getattr(self, "_Pfz", None) is None: self._Pfz = self.mesh.getInterpolationMat( self.mesh.gridCC[self.activeCC, :], locType="Fz") return self._Pfz def getFields(self, itime): src = self.srcList[0] Ey = self.mesh.aveE2CC * self.f[src, "e", itime] Jy = utils.sdiag(self.sim.sigma) * Ey self.Ey = utils.mkvc(self.mirrorArray(Ey[self.activeCC], direction="y")) self.Jy = utils.mkvc(self.mirrorArray(Jy[self.activeCC], direction="y")) self.Bx = utils.mkvc( self.mirrorArray(self.Pfx * self.f[src, "b", itime], direction="x")) self.Bz = utils.mkvc( self.mirrorArray(self.Pfz * self.f[src, "b", itime], direction="z")) self.dBxdt = utils.mkvc( self.mirrorArray(-self.Pfx * self.mesh.edgeCurl * self.f[src, "e", itime], direction="x")) self.dBzdt = utils.mkvc( self.mirrorArray(-self.Pfz * self.mesh.edgeCurl * self.f[src, "e", itime], direction="z")) def getData(self): src = self.srcList[0] Pfx = self.mesh.getInterpolationMat(self.rxLoc, locType="Fx") Pfz = self.mesh.getInterpolationMat(self.rxLoc, locType="Fz") Pey = self.mesh.getInterpolationMat(self.rxLoc, locType="Ey") self.Ey = (Pey * self.f[src, "e", :]).flatten() self.Bx = (Pfx * self.f[src, "b", :]).flatten() self.Bz = (Pfz * self.f[src, "b", :]).flatten() self.dBxdt = (-Pfx * self.mesh.edgeCurl * self.f[src, "e", :]).flatten() self.dBzdt = (-Pfz * self.mesh.edgeCurl * self.f[src, "e", :]).flatten() def plotField( self, Field="B", view="vec", scale="linear", itime=0, Geometry=True, Scenario=None, Fixed=False, vmin=None, vmax=None, ): # Printout for null cases if (Field == "B") & (view == "y"): print( "Think about the problem geometry. There is NO By in this case." ) elif (Field == "dBdt") & (view == "y"): print( "Think about the problem geometry. There is NO dBy/dt in this case." ) elif (Field == "E") & (view == "x") | (Field == "E") & (view == "z"): print( "Think about the problem geometry. There is NO Ex or Ez in this case. Only Ey." ) elif (Field == "J") & (view == "x") | (Field == "J") & (view == "z"): print( "Think about the problem geometry. There is NO Jx or Jz in this case. Only Jy." ) elif (Field == "E") & (view == "vec"): print( "Think about the problem geometry. E only has components along y. Vector plot not possible" ) elif (Field == "J") & (view == "vec"): print( "Think about the problem geometry. J only has components along y. Vector plot not possible" ) elif Field == "Model": plt.figure(figsize=(7, 6)) ax = plt.subplot(111) if Scenario == "Sphere": model2D, mapping2D = self.getCoreModel("Sphere") elif Scenario == "Layer": model2D, mapping2D = self.getCoreModel("Layer") if Fixed: clim = (np.log10(vmin), np.log10(vmax)) else: clim = None out = self.mesh2D.plotImage(np.log10(mapping2D * model2D), ax=ax, clim=clim) cb = plt.colorbar(out[0], ax=ax, format="$10^{%.1f}$") cb.set_label("$\sigma$ (S/m)") ax.set_xlabel("Distance (m)") ax.set_ylabel("Depth (m)") ax.set_title("Conductivity Model") plt.show() else: plt.figure(figsize=(10, 6)) ax = plt.subplot(111) vec = False if view == "vec": tname = "Vector " title = tname + Field + "-field" elif view == "amp": tname = "|" title = tname + Field + "|-field" else: title = Field + view + "-field" if Field == "B": label = "Magnetic field (T)" if view == "vec": vec = True val = np.c_[self.Bx, self.Bz] elif view == "x": val = self.Bx elif view == "z": val = self.Bz else: return elif Field == "dBdt": label = "Time derivative of magnetic field (T/s)" if view == "vec": vec = True val = np.c_[self.dBxdt, self.dBzdt] elif view == "x": val = self.dBxdt elif view == "z": val = self.dBzdt else: return elif Field == "E": label = "Electric field (V/m)" if view == "y": val = self.Ey else: return elif Field == "J": label = "Current density (A/m$^2$)" if view == "y": val = self.Jy else: return if Fixed: if scale == "log": vmin, vmax = (np.log10(vmin), np.log10(vmax)) out = ax.scatter(np.zeros(3) - 1000, np.zeros(3), c=np.linspace(vmin, vmax, 3)) utils.plot2Ddata( self.mesh2D.gridCC, val, vec=vec, ax=ax, contourOpts={ "cmap": "viridis", "vmin": vmin, "vmax": vmax }, ncontour=200, scale=scale, ) else: out = utils.plot2Ddata( self.mesh2D.gridCC, val, vec=vec, ax=ax, contourOpts={"cmap": "viridis"}, ncontour=200, scale=scale, )[0] if scale == "linear": cb = plt.colorbar(out, ax=ax, format="%.2e") elif scale == "log": cb = plt.colorbar(out, ax=ax, format="$10^{%.1f}$") else: raise Exception("We consdier only linear and log scale!") cb.set_label(label) xmax = self.mesh2D.gridCC[:, 0].max() if Geometry: if Scenario == "Layer": ax.plot(np.r_[-xmax, xmax], np.ones(2) * self.srcLoc[2], "w-", lw=1) ax.plot(np.r_[-xmax, xmax], np.ones(2) * self.z0, "w--", lw=1) ax.plot(np.r_[-xmax, xmax], np.ones(2) * self.z1, "w--", lw=1) ax.plot(np.r_[-xmax, xmax], np.ones(2) * self.z2, "w--", lw=1) ax.plot(0, self.srcLoc[2], "ko", ms=4) ax.plot(self.rxLoc[0, 0], self.srcLoc[2], "ro", ms=4) elif Scenario == "Sphere": ax.plot(np.r_[-xmax, xmax], np.ones(2) * self.srcLoc[2], "k-", lw=1) ax.plot(np.r_[-xmax, xmax], np.ones(2) * self.z0, "w--", lw=1) ax.plot(np.r_[-xmax, xmax], np.ones(2) * self.z1, "w--", lw=1) ax.plot(np.r_[-xmax, xmax], np.ones(2) * (self.z1 - self.h), "w--", lw=1) Phi = np.linspace(0, 2 * np.pi, 41) ax.plot( self.R * np.cos(Phi), self.z2 + self.R * np.sin(Phi), "w--", lw=1, ) ax.plot(0, self.srcLoc[2], "ko", ms=4) ax.plot(self.rxLoc[0, 0], self.srcLoc[2], "ro", ms=4) ax.set_xlabel("Distance (m)") ax.set_ylabel("Depth (m)") title = (title + "\nt = " + "{:.2e}".format(self.sim.times[itime] * 1e3) + " ms") ax.set_title(title) ax.set_xlim(-190, 190) ax.set_ylim(-190, 190) plt.show() ###################################################### # LAYER WIDGET ###################################################### def InteractivePlane_Layer(self, scale="log", fieldvalue="E", compvalue="y"): def foo( Update, Field, AmpDir, Component, Sigma0, Sigma1, Sigma2, Sigma3, Sus, h1, h2, Scale, rxOffset, z, radius, itime, Geometry=True, Fixed=False, vmin=None, vmax=None, ): if AmpDir == "Direction (B or dBdt)": Component = "vec" self.setThreeLayerParam( h1=h1, h2=h2, sig0=Sigma0, sig1=Sigma1, sig2=Sigma2, sig3=Sigma3, chi=Sus, ) self.srcLoc = np.array([0.0, 0.0, z]) self.rxLoc = np.array([[rxOffset, 0.0, z]]) self.radius = radius if Update: self.simulate(self.srcLoc, self.rxLoc, self.time, self.radius) self.getFields(itime) return self.plotField( Field=Field, view=Component, scale=Scale, Geometry=Geometry, itime=itime, Scenario="Layer", Fixed=Fixed, vmin=vmin, vmax=vmax, ) out = widgetify( foo, Update=widgets.widget_bool.Checkbox(value=True, description="Update"), Field=widgets.ToggleButtons( options=["E", "B", "dBdt", "J", "Model"], value=fieldvalue), AmpDir=widgets.ToggleButtons( options=["None", "Direction (B or dBdt)"], value="None"), Component=widgets.ToggleButtons(options=["x", "y", "z"], value=compvalue, description="Comp."), Sigma0=widgets.FloatText(value=1e-8, continuous_update=False, description="$\sigma_0$ (S/m)"), Sigma1=widgets.FloatText(value=0.01, continuous_update=False, description="$\sigma_1$ (S/m)"), Sigma2=widgets.FloatText(value=0.01, continuous_update=False, description="$\sigma_2$ (S/m)"), Sigma3=widgets.FloatText(value=0.01, continuous_update=False, description="$\sigma_3$ (S/m)"), Sus=widgets.FloatText(value=0.0, continuous_update=False, description="$\chi$"), h1=widgets.FloatSlider( min=2.0, max=50.0, step=2.0, value=20.0, continuous_update=False, description="$h_1$ (m)", ), h2=widgets.FloatSlider( min=2.0, max=50.0, step=2.0, value=20.0, continuous_update=False, description="$h_2$ (m)", ), Scale=widgets.ToggleButtons(options=["log", "linear"], value="linear"), rxOffset=widgets.FloatSlider( min=0.0, max=50.0, step=2.0, value=10.0, continuous_update=False, description="$\Delta x$(m)", ), z=widgets.FloatSlider( min=0.0, max=50.0, step=2.0, value=0.0, continuous_update=False, description="$\Delta z$ (m)", ), itime=widgets.IntSlider( min=1, max=70, step=1, value=1, continuous_update=False, description="Time index", ), radius=widgets.FloatSlider( min=2.0, max=50.0, step=2.0, value=2.0, continuous_update=False, description="Tx radius (m)", ), Fixed=widgets.widget_bool.Checkbox(value=False, description="Fixed"), vmin=FloatText(value=None, description="vmin"), vmax=FloatText(value=None, description="vmax"), ) return out def InteractiveData_Layer(self, fieldvalue="B", compvalue="z"): def foo(Field, Component, Scale): if (Field == "B") & (Component == "y") | (Field == "dBdt") & ( Component == "y"): print( "Think about the problem geometry. There is NO By in this case." ) elif (Field == "E") & (Component == "x") | (Field == "E") & ( Component == "z"): print( "Think about the problem geometry. There is NO Ex or Ez in this case. Only Ey." ) else: plt.figure() ax = plt.subplot(111) # bType = "b" self.getData() if Field == "B": label = "Magnetic field (T)" if Component == "x": title = "Bx" val = self.Bx elif Component == "z": title = "Bz" val = self.Bz else: # ax.imshow(self.im) ax.set_xticks([]) ax.set_yticks([]) plt.show() print( "Think about the problem geometry. There is NO By in this case." ) elif Field == "dBdt": label = "Time dervative of magnetic field (T/s)" if Component == "x": title = "dBx/dt" val = self.dBxdt elif Component == "z": title = "dBz/dt" val = self.dBzdt else: # ax.imshow(self.im) ax.set_xticks([]) ax.set_yticks([]) plt.show() print( "Think about the problem geometry. There is NO dBy/dt in this case." ) elif Field == "E": label = "Electric field (V/m)" title = "Ey" if Component == "y": val = self.Ey else: # ax.imshow(self.im) ax.set_xticks([]) ax.set_yticks([]) plt.show() print( "Think about the problem geometry. There is NO Ex or Ez in this case." ) elif Field == "J": print( "The conductivity at the location is 0. Therefore there is no electrical current here." ) if Scale == "log": val_p, val_n = DisPosNegvalues(val) ax.plot(self.sim.times[10:] * 1e3, val_p[10:], "k-") ax.plot(self.sim.times[10:] * 1e3, val_n[10:], "k--") ax.legend(("(+)", "(-)"), loc=1, fontsize=10) else: ax.plot(self.sim.times[10:] * 1e3, val[10:], "k.-") ax.set_xscale("log") ax.set_yscale(Scale) ax.set_xlabel("Time (ms)") ax.set_ylabel(label) ax.set_title(title) ax.grid(True) plt.show() out = widgetify( foo, Field=widgets.ToggleButtons(options=["E", "B", "dBdt"], value=fieldvalue), Component=widgets.ToggleButtons(options=["x", "y", "z"], value=compvalue, description="Comp."), Scale=widgets.ToggleButtons(options=["log", "linear"], value="log"), ) return out ###################################################### # SPHERE WIDGET ###################################################### def InteractivePlane_Sphere(self, scale="log", fieldvalue="E", compvalue="y"): def foo( Update, Field, AmpDir, Component, Sigma0, Sigmab, Sigma1, Sigma2, Sus, d1, h, d2, R, Scale, rxOffset, z, radius, itime, Geometry=True, Fixed=False, vmin=None, vmax=None, ): if AmpDir == "Direction (B or dBdt)": Component = "vec" self.setLayerSphereParam( d1=d1, h=h, d2=d2, R=R, sig0=Sigma0, sigb=Sigmab, sig1=Sigma1, sig2=Sigma2, chi=Sus, ) self.srcLoc = np.array([0.0, 0.0, z]) self.rxLoc = np.array([[rxOffset, 0.0, z]]) self.radius = radius if Update: self.simulate(self.srcLoc, self.rxLoc, self.time, self.radius) self.getFields(itime) return self.plotField( Field=Field, view=Component, scale=Scale, Geometry=Geometry, itime=itime, Scenario="Sphere", Fixed=Fixed, vmin=vmin, vmax=vmax, ) out = widgetify( foo, Update=widgets.widget_bool.Checkbox(value=True, description="Update"), Field=widgets.ToggleButtons( options=["E", "B", "dBdt", "J", "Model"], value=fieldvalue), AmpDir=widgets.ToggleButtons( options=["None", "Direction (B or dBdt)"], value="None"), Component=widgets.ToggleButtons(options=["x", "y", "z"], value=compvalue, description="Comp."), Sigma0=widgets.FloatText(value=1e-8, continuous_update=False, description="$\sigma_0$ (S/m)"), Sigmab=widgets.FloatText(value=0.01, continuous_update=False, description="$\sigma_b$ (S/m)"), Sigma1=widgets.FloatText(value=0.01, continuous_update=False, description="$\sigma_1$ (S/m)"), Sigma2=widgets.FloatText(value=1.0, continuous_update=False, description="$\sigma_2$ (S/m)"), Sus=widgets.FloatText(value=0.0, continuous_update=False, description="$\chi$"), d1=widgets.FloatSlider( min=0.0, max=50.0, step=2.0, value=0.0, continuous_update=False, description="$d_1$ (m)", ), h=widgets.FloatSlider( min=2.0, max=40.0, step=2.0, value=20.0, continuous_update=False, description="$h$ (m)", ), d2=widgets.FloatSlider( min=20.0, max=80.0, step=2.0, value=60.0, continuous_update=False, description="$d_2$ (m)", ), R=widgets.FloatSlider( min=2.0, max=40.0, step=2.0, value=30.0, continuous_update=False, description="$R$ (m)", ), Scale=widgets.ToggleButtons(options=["log", "linear"], value="linear"), rxOffset=widgets.FloatSlider( min=0.0, max=50.0, step=2.0, value=10.0, continuous_update=False, description="$\Delta x$(m)", ), z=widgets.FloatSlider( min=0.0, max=50.0, step=2.0, value=0.0, continuous_update=False, description="$\Delta z$ (m)", ), radius=widgets.FloatSlider( min=2.0, max=50.0, step=2.0, value=2.0, continuous_update=False, description="Tx radius (m)", ), itime=widgets.IntSlider( min=1, max=70, step=1, value=1, continuous_update=False, description="Time index", ), Fixed=widgets.widget_bool.Checkbox(value=False, description="Fixed"), vmin=FloatText(value=None, description="vmin"), vmax=FloatText(value=None, description="vmax"), ) return out def InteractiveData_Sphere(self, fieldvalue="B", compvalue="z"): def foo(Field, Component, Scale): if (Field == "B") & (Component == "y") | (Field == "dBdt") & ( Component == "y"): print( "Think about the problem geometry. There is NO By in this case." ) elif (Field == "E") & (Component == "x") | (Field == "E") & ( Component == "z"): print( "Think about the problem geometry. There is NO Ex or Ez in this case. Only Ey." ) else: plt.figure() ax = plt.subplot(111) # bType = "b" self.getData() if Field == "B": label = "Magnetic field (T)" if Component == "x": title = "Bx" val = self.Bx elif Component == "z": title = "Bz" val = self.Bz else: # ax.imshow(self.im) ax.set_xticks([]) ax.set_yticks([]) plt.show() print( "Think about the problem geometry. There is NO By in this case." ) elif Field == "dBdt": label = "Time dervative of magnetic field (T/s)" if Component == "x": title = "dBx/dt" val = self.dBxdt elif Component == "z": title = "dBz/dt" val = self.dBzdt else: # ax.imshow(self.im) ax.set_xticks([]) ax.set_yticks([]) plt.show() print( "Think about the problem geometry. There is NO dBy/dt in this case." ) elif Field == "E": label = "Electric field (V/m)" title = "Ey" if Component == "y": val = self.Ey else: # ax.imshow(self.im) ax.set_xticks([]) ax.set_yticks([]) plt.show() print( "Think about the problem geometry. There is NO Ex or Ez in this case." ) elif Field == "J": print( "The conductivity at the location is 0. Therefore there is no electrical current here." ) if Scale == "log": val_p, val_n = DisPosNegvalues(val) ax.plot(self.sim.times[10:] * 1e3, val_p[10:], "k-") ax.plot(self.sim.times[10:] * 1e3, val_n[10:], "k--") ax.legend(("(+)", "(-)"), loc=1, fontsize=10) else: ax.plot(self.sim.times[10:] * 1e3, val[10:], "k.-") ax.set_xscale("log") ax.set_yscale(Scale) ax.set_xlabel("Time (ms)") ax.set_ylabel(label) ax.set_title(title) ax.grid(True) plt.show() out = widgetify( foo, Field=widgets.ToggleButtons(options=["E", "B", "dBdt"], value=fieldvalue), Component=widgets.ToggleButtons(options=["x", "y", "z"], value=compvalue, description="Comp."), Scale=widgets.ToggleButtons(options=["log", "linear"], value="log"), ) return out
edges_y = mesh.gridEy wx = (-edges_x[:, 1] / np.sqrt(np.sum(edges_x**2, axis=1))) * np.exp( -(edges_x[:, 0]**2 + edges_x[:, 1]**2) / 6**2) wy = (edges_y[:, 0] / np.sqrt(np.sum(edges_y**2, axis=1))) * np.exp( -(edges_y[:, 0]**2 + edges_y[:, 1]**2) / 6**2) w = np.r_[wx, wy] curl_w = CURL * w # Plot Gradient of u fig = plt.figure(figsize=(10, 5)) ax1 = fig.add_subplot(121) mesh.plotImage(u, ax=ax1, v_type="N") ax1.set_title("u at cell centers") ax2 = fig.add_subplot(122) mesh.plotImage(grad_u, ax=ax2, v_type="E", view="vec", stream_opts={ "color": "w", "density": 1.0 }) ax2.set_title("gradient of u on edges") fig.show()
# Run inversion recovered_model = inv.run(starting_model) ############################################################ # Plotting True Model and Recovered Model # --------------------------------------- # # Load the true model true_model = np.loadtxt(str(model_filename)) # Plot True Model fig = plt.figure(figsize=(6, 5.5)) ax1 = fig.add_axes([0.15, 0.15, 0.65, 0.75]) mesh.plotImage(true_model, ax=ax1, grid=True, pcolorOpts={"cmap": "viridis"}) ax1.set_title("True Model") ax2 = fig.add_axes([0.82, 0.15, 0.05, 0.75]) norm = mpl.colors.Normalize(vmin=np.min(true_model), vmax=np.max(true_model)) cbar = mpl.colorbar.ColorbarBase(ax2, norm=norm, orientation="vertical", cmap=mpl.cm.viridis) cbar.set_label("Velocity (m/s)", rotation=270, labelpad=15, size=12) plt.show() # Plot Recovered Model fig = plt.figure(figsize=(6, 5.5))
M = TensorMesh(h, x0) ccMesh = M.gridCC # ------------------- Test conductivities! -------------------------- print('Testing 1 block conductivity') p0 = np.array([0.5, 0.5, 0.5])[:testDim] p1 = np.array([1.0, 1.0, 1.0])[:testDim] vals = np.array([100, 1e-6]) sigma = defineBlockConductivity(ccMesh, p0, p1, vals) # Plot sigma model print(sigma.shape) M.plotImage(sigma) print('Done with block! :)') plt.show() # ----------------------------------------- print('Testing the two layered model') vals = np.array([100, 1e-5]) depth = 1.0 sigma = defineTwoLayeredConductivity(ccMesh, depth, vals) M.plotImage(sigma) print(sigma) print('layer model!') plt.show()
v = np.r_[vx, vy] Mf = mesh.getFaceInnerProduct() # Edge inner product matrix ipf = np.dot(v, Mf * v) # The analytic solution of (v, v) ipt = np.pi * sig**2 # Plot the vector function fig = plt.figure(figsize=(5, 5)) ax = fig.add_subplot(111) mesh.plotImage(v, ax=ax, vType='F', view='vec', streamOpts={ 'color': 'w', 'density': 1.0 }) ax.set_title('v at cell faces') fig.show() # Verify accuracy print('ACCURACY') print('Analytic solution: ', ipt) print('Edge variable approx.:', ipe) print('Face variable approx.:', ipf) ############################################## # Inverse of Inner Product Matricies
I = sdiag(np.ones(mesh.nC)) # Identity matrix B = I + dt * M s = Mc_inv * q Binv = SolverLU(B) # Plot the vector field fig = plt.figure(figsize=(15, 15)) ax = 9 * [None] ax[0] = fig.add_subplot(332) mesh.plotImage(u, ax=ax[0], vType='F', view='vec', streamOpts={ 'color': 'w', 'density': 1.0 }, clim=[0., 10.]) ax[0].set_title('Divergence free vector field') ax[1] = fig.add_subplot(333) ax[1].set_aspect(10, anchor='W') cbar = mpl.colorbar.ColorbarBase(ax[1], orientation='vertical') cbar.set_label('Velocity (m/s)', rotation=270, labelpad=5) # Perform backward Euler and plot n = 3
from SimPEG import Mesh import matplotlib.pyplot as plt cs = 20 ncx, ncy, ncz = 41, 41, 40 hx = np.ones(ncx)*cs hy = np.ones(ncy)*cs hz = np.ones(ncz)*cs mesh = TensorMesh([hx, hy, hz], 'CCC') srcLoc = np.r_[0., 0., 0.] Ax = MagneticLoopVectorPotential(srcLoc, mesh.gridEx, 'x', 200) Ay = MagneticLoopVectorPotential(srcLoc, mesh.gridEy, 'y', 200) Az = MagneticLoopVectorPotential(srcLoc, mesh.gridEz, 'z', 200) A = np.r_[Ax, Ay, Az] B0 = mesh.edgeCurl*A J0 = mesh.edgeCurl.T*B0 # mesh.plotImage(A, vType = 'Ex') # mesh.plotImage(A, vType = 'Ey') mesh.plotImage(B0, vType = 'Fx') mesh.plotImage(B0, vType = 'Fy') mesh.plotImage(B0, vType = 'Fz') # # mesh.plotImage(J0, vType = 'Ex') # mesh.plotImage(J0, vType = 'Ey') # mesh.plotImage(J0, vType = 'Ez') plt.show()
if __name__ == '__main__': from SimPEG import Mesh import matplotlib.pyplot as plt cs = 20 ncx, ncy, ncz = 41, 41, 40 hx = np.ones(ncx) * cs hy = np.ones(ncy) * cs hz = np.ones(ncz) * cs mesh = TensorMesh([hx, hy, hz], 'CCC') srcLoc = np.r_[0., 0., 0.] Ax = MagneticLoopVectorPotential(srcLoc, mesh.gridEx, 'x', 200) Ay = MagneticLoopVectorPotential(srcLoc, mesh.gridEy, 'y', 200) Az = MagneticLoopVectorPotential(srcLoc, mesh.gridEz, 'z', 200) A = np.r_[Ax, Ay, Az] B0 = mesh.edgeCurl * A J0 = mesh.edgeCurl.T * B0 # mesh.plotImage(A, vType = 'Ex') # mesh.plotImage(A, vType = 'Ey') mesh.plotImage(B0, vType='Fx') mesh.plotImage(B0, vType='Fy') mesh.plotImage(B0, vType='Fz') # # mesh.plotImage(J0, vType = 'Ex') # mesh.plotImage(J0, vType = 'Ey') # mesh.plotImage(J0, vType = 'Ez') plt.show()
h = 2 * np.ones(50) mesh = TensorMesh([h, h], x0="CC") A2 = mesh.aveCC2F # cell centers to faces A3 = mesh.aveN2CC # nodes to cell centers A4 = mesh.aveF2CC # faces to cell centers # Create a variable on cell centers v = 100.0 * np.ones(mesh.nC) xy = mesh.gridCC v[(xy[:, 1] > 0)] = 0.0 v[(xy[:, 1] < -10.0) & (xy[:, 0] > -10.0) & (xy[:, 0] < 10.0)] = 50.0 fig = plt.figure(figsize=(10, 10)) ax1 = fig.add_subplot(221) mesh.plotImage(v, ax=ax1) ax1.set_title("Variable at cell centers") # Apply cell centers to faces averaging ax2 = fig.add_subplot(222) mesh.plotImage(A2 * v, ax=ax2, v_type="F") ax2.set_title("Cell centers to faces") # Use the transpose to go from cell centers to nodes ax3 = fig.add_subplot(223) mesh.plotImage(A3.T * v, ax=ax3, v_type="N") ax3.set_title("Cell centers to nodes using transpose") # Use the transpose to go from cell centers to faces ax4 = fig.add_subplot(224) mesh.plotImage(A4.T * v, ax=ax4, v_type="F")
v = np.r_[vx, vy] Mf = mesh.getFaceInnerProduct() # Edge inner product matrix ipf = np.dot(v, Mf * v) # The analytic solution of (v, v) ipt = np.pi * sig**2 # Plot the vector function fig = plt.figure(figsize=(5, 5)) ax = fig.add_subplot(111) mesh.plotImage(v, ax=ax, v_type="F", view="vec", stream_opts={ "color": "w", "density": 1.0 }) ax.set_title("v at cell faces") fig.show() # Verify accuracy print("ACCURACY") print("Analytic solution: ", ipt) print("Edge variable approx.:", ipe) print("Face variable approx.:", ipf) ############################################## # Inverse of Inner Product Matricies
h = 2 * np.ones(50) mesh = TensorMesh([h, h], x0='CC') A2 = mesh.aveCC2F # cell centers to faces A3 = mesh.aveN2CC # nodes to cell centers A4 = mesh.aveF2CC # faces to cell centers # Create a variable on cell centers v = 100. * np.ones(mesh.nC) xy = mesh.gridCC v[(xy[:, 1] > 0)] = 0. v[(xy[:, 1] < -10.) & (xy[:, 0] > -10.) & (xy[:, 0] < 10.)] = 50. fig = plt.figure(figsize=(10, 10)) ax1 = fig.add_subplot(221) mesh.plotImage(v, ax=ax1) ax1.set_title('Variable at cell centers') # Apply cell centers to faces averaging ax2 = fig.add_subplot(222) mesh.plotImage(A2 * v, ax=ax2, v_type='F') ax2.set_title('Cell centers to faces') # Use the transpose to go from cell centers to nodes ax3 = fig.add_subplot(223) mesh.plotImage(A3.T * v, ax=ax3, v_type='N') ax3.set_title('Cell centers to nodes using transpose') # Use the transpose to go from cell centers to faces ax4 = fig.add_subplot(224) mesh.plotImage(A4.T * v, ax=ax4, v_type='F')
# Define the model. Models in SimPEG are vector arrays. model = background_velocity * np.ones(mesh.nC) ind_block = model_builder.getIndicesBlock(np.r_[-50, 20], np.r_[50, -20], mesh.gridCC) model[ind_block] = block_velocity # Define a mapping from the model (velocity) to the slowness. If your model # consists of slowness values, you can use *maps.IdentityMap*. model_mapping = maps.ReciprocalMap() # Plot Velocity Model fig = plt.figure(figsize=(6, 5.5)) ax1 = fig.add_axes([0.15, 0.15, 0.65, 0.75]) mesh.plotImage(model, ax=ax1, grid=True, pcolorOpts={"cmap": "viridis"}) ax1.set_xlabel("x (m)") ax1.set_ylabel("y (m)") ax1.plot(x, y_sources, "ro") # source locations ax1.plot(x, y_receivers, "ko") # receiver locations ax2 = fig.add_axes([0.82, 0.15, 0.05, 0.75]) norm = mpl.colors.Normalize(vmin=np.min(model), vmax=np.max(model)) cbar = mpl.colorbar.ColorbarBase(ax2, norm=norm, orientation="vertical", cmap=mpl.cm.viridis) cbar.set_label("$Velocity (m/s)$", rotation=270, labelpad=15, size=12) ####################################################### # Simulation: Arrival Time
rho = np.zeros(mesh.nC) rho[kneg] = -1 rho[kpos] = 1 # LU factorization and solve AinvM = SolverLU(A) phi = AinvM * rho # Compute electric fields E = Mf_inv * DIV.T * Mc * phi # Plotting fig = plt.figure(figsize=(14, 4)) ax1 = fig.add_subplot(131) mesh.plotImage(rho, vType='CC', ax=ax1) ax1.set_title('Charge Density') ax2 = fig.add_subplot(132) mesh.plotImage(phi, vType='CC', ax=ax2) ax2.set_title('Electric Potential') ax3 = fig.add_subplot(133) mesh.plotImage(E, ax=ax3, vType='F', view='vec', streamOpts={ 'color': 'w', 'density': 1.0 })
I = sdiag(np.ones(mesh.nC)) # Identity matrix B = I + dt * M s = Mc_inv * q Binv = SolverLU(B) # Plot the vector field fig = plt.figure(figsize=(15, 15)) ax = 9 * [None] ax[0] = fig.add_subplot(332) mesh.plotImage( u, ax=ax[0], v_type="F", view="vec", stream_opts={"color": "w", "density": 1.0}, clim=[0.0, 10.0], ) ax[0].set_title("Divergence free vector field") ax[1] = fig.add_subplot(333) ax[1].set_aspect(10, anchor="W") cbar = mpl.colorbar.ColorbarBase(ax[1], orientation="vertical") cbar.set_label("Velocity (m/s)", rotation=270, labelpad=5) # Perform backward Euler and plot n = 3 for ii in range(300):
class HarmonicVMDCylWidget(object): """FDEMCylWidgete""" survey = None srcList = None mesh = None f = None activeCC = None srcLoc = None mesh2D = None mu = None def __init__(self): self.genMesh() self.getCoreDomain() # url = "http://em.geosci.xyz/_images/disc_dipole.png" # response = requests.get(url) # self.im = Image.open(StringIO(response.content)) def mirrorArray(self, x, direction="x"): X = x.reshape((self.nx_core, self.ny_core), order="F") if direction == "x" or direction == "y": X2 = np.vstack((-np.flipud(X), X)) else: X2 = np.vstack((np.flipud(X), X)) return X2 def genMesh(self, h=0.0, cs=3.0, ncx=15, ncz=30, npad=20): """ Generate cylindrically symmetric mesh """ # TODO: Make it adaptive due to z location hx = [(cs, ncx), (cs, npad, 1.3)] hz = [(cs, npad, -1.3), (cs, ncz), (cs, npad, 1.3)] self.mesh = CylMesh([hx, 1, hz], "00C") 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 getCoreModel(self, Type): if Type == "Layer": active = self.mesh2D.vectorCCy < self.z0 ind1 = (self.mesh2D.vectorCCy < self.z0) & (self.mesh2D.vectorCCy >= self.z1) ind2 = (self.mesh2D.vectorCCy < self.z1) & (self.mesh2D.vectorCCy >= self.z2) mapping2D = maps.SurjectVertical1D( self.mesh2D) * maps.InjectActiveCells( self.mesh2D, active, self.sig0, nC=self.mesh2D.nCy) model2D = np.ones(self.mesh2D.nCy) * self.sig3 model2D[ind1] = self.sig1 model2D[ind2] = self.sig2 model2D = model2D[active] elif Type == "Sphere": active = self.mesh2D.gridCC[:, 1] < self.z0 ind1 = (self.mesh2D.gridCC[:, 1] < self.z1) & (self.mesh2D.gridCC[:, 1] >= self.z1 - self.h) ind2 = (np.sqrt((self.mesh2D.gridCC[:, 0])**2 + (self.mesh2D.gridCC[:, 1] - self.z2)**2) <= self.R) mapping2D = maps.InjectActiveCells(self.mesh2D, active, self.sig0, nC=self.mesh2D.nC) model2D = np.ones(self.mesh2D.nC) * self.sigb model2D[ind1] = self.sig1 model2D[ind2] = self.sig2 model2D = model2D[active] return model2D, mapping2D def getBiotSavrt(self, rxLoc): """ Compute Biot-Savart operator: Gz and Gx """ self.Gz = BiotSavartFun(self.mesh, rxLoc, component="z") self.Gx = BiotSavartFun(self.mesh, rxLoc, component="x") def setThreeLayerParam(self, h1=12, h2=12, sig0=1e-8, sig1=1e-1, sig2=1e-2, sig3=1e-2, chi=0.0): self.h1 = h1 # 1st layer thickness self.h2 = h2 # 2nd layer thickness self.z0 = 0.0 self.z1 = self.z0 - h1 self.z2 = self.z0 - h1 - h2 self.sig0 = sig0 # 0th layer \sigma (assumed to be air) self.sig1 = sig1 # 1st layer \sigma self.sig2 = sig2 # 2nd layer \sigma self.sig3 = sig3 # 3rd layer \sigma active = self.mesh.vectorCCz < self.z0 ind1 = (self.mesh.vectorCCz < self.z0) & (self.mesh.vectorCCz >= self.z1) ind2 = (self.mesh.vectorCCz < self.z1) & (self.mesh.vectorCCz >= self.z2) self.mapping = maps.SurjectVertical1D( self.mesh) * maps.InjectActiveCells( self.mesh, active, sig0, nC=self.mesh.nCz) model = np.ones(self.mesh.nCz) * sig3 model[ind1] = sig1 model[ind2] = sig2 self.m = model[active] self.mu = np.ones(self.mesh.nC) * mu_0 self.mu[self.mesh.gridCC[:, 2] < 0.0] = (1.0 + chi) * mu_0 return self.m def setLayerSphereParam(self, d1=6, h=6, d2=16, R=4, sig0=1e-8, sigb=1e-2, sig1=1e-1, sig2=1.0, chi=0.0): self.z0 = 0.0 # Surface elevation self.z1 = self.z0 - d1 # Depth to layer self.h = h # Thickness of layer self.z2 = self.z0 - d2 # Depth to center of sphere self.R = R # Radius of sphere self.sig0 = sig0 # Air conductivity self.sigb = sigb # Background conductivity self.sig1 = sig1 # Layer conductivity self.sig2 = sig2 # Sphere conductivity active = self.mesh.gridCC[:, 2] < self.z0 ind1 = (self.mesh.gridCC[:, 2] < self.z1) & (self.mesh.gridCC[:, 2] >= self.z1 - self.h) ind2 = (np.sqrt((self.mesh.gridCC[:, 0])**2 + (self.mesh.gridCC[:, 2] - self.z2)**2) <= self.R) self.mapping = maps.InjectActiveCells(self.mesh, active, sig0, nC=self.mesh.nC) model = np.ones(self.mesh.nC) * sigb model[ind1] = sig1 model[ind2] = sig2 self.m = model[active] self.mu = np.ones(self.mesh.nC) * mu_0 self.mu[self.mesh.gridCC[:, 2] < 0.0] = (1.0 + chi) * mu_0 return self.m def simulate(self, srcLoc, rxLoc, freqs): bzr = fdem.receivers.PointMagneticFluxDensitySecondary( rxLoc, orientation="z", component="real") bzi = fdem.receivers.PointMagneticFluxDensitySecondary( rxLoc, orientation="z", component="imag") self.srcList = [ fdem.sources.MagDipole([bzr, bzi], frequency=freq, location=srcLoc, orientation="Z") for freq in freqs ] survey = fdem.survey.Survey(self.srcList) sim = fdem.Simulation3DMagneticFluxDensity(self.mesh, survey=survey, sigmaMap=self.mapping, mu=self.mu, solver=Pardiso) self.f = sim.fields(self.m) self.sim = sim dpred = sim.dpred(self.m, f=self.f) self.srcLoc = srcLoc self.rxLoc = rxLoc return dpred def getFields(self, bType="b", ifreq=0): src = self.srcList[ifreq] Pfx = self.mesh.getInterpolationMat(self.mesh.gridCC[self.activeCC, :], locType="Fx") Pfz = self.mesh.getInterpolationMat(self.mesh.gridCC[self.activeCC, :], locType="Fz") Ey = self.mesh.aveE2CC * self.f[src, "e"] Jy = utils.sdiag(self.sim.sigma) * Ey self.Ey = utils.mkvc(self.mirrorArray(Ey[self.activeCC], direction="y")) self.Jy = utils.mkvc(self.mirrorArray(Jy[self.activeCC], direction="y")) self.Bx = utils.mkvc( self.mirrorArray(Pfx * self.f[src, bType], direction="x")) self.Bz = utils.mkvc( self.mirrorArray(Pfz * self.f[src, bType], direction="z")) def getData(self, bType="b"): Pfx = self.mesh.getInterpolationMat(self.rxLoc, locType="Fx") Pfz = self.mesh.getInterpolationMat(self.rxLoc, locType="Fz") Pey = self.mesh.getInterpolationMat(self.rxLoc, locType="Ey") self.Ey = (Pey * self.f[:, "e"]).flatten() self.Bx = (Pfx * self.f[:, bType]).flatten() self.Bz = (Pfz * self.f[:, bType]).flatten() def plotField( self, Field="B", ComplexNumber="real", view="vec", scale="linear", Frequency=100, Geometry=True, Scenario=None, ): # Printout for null cases if (Field == "B") & (view == "y"): print( "Think about the problem geometry. There is NO By in this case." ) elif (Field == "E") & (view == "x") | (Field == "E") & (view == "z"): print( "Think about the problem geometry. There is NO Ex or Ez in this case. Only Ey." ) elif (Field == "J") & (view == "x") | (Field == "J") & (view == "z"): print( "Think about the problem geometry. There is NO Jx or Jz in this case. Only Jy." ) elif (Field == "E") & (view == "vec"): print( "Think about the problem geometry. E only has components along y. Vector plot not possible" ) elif (Field == "J") & (view == "vec"): print( "Think about the problem geometry. J only has components along y. Vector plot not possible" ) elif (view == "vec") & (ComplexNumber == "Amp") | (view == "vec") & ( ComplexNumber == "Phase"): print( "Cannot show amplitude or phase when vector plot selected. Set 'AmpDir=None' to see amplitude or phase." ) elif Field == "Model": plt.figure(figsize=(7, 6)) ax = plt.subplot(111) if Scenario == "Sphere": model2D, mapping2D = self.getCoreModel("Sphere") elif Scenario == "Layer": model2D, mapping2D = self.getCoreModel("Layer") out = self.mesh2D.plotImage(np.log10(mapping2D * model2D), ax=ax) cb = plt.colorbar(out[0], ax=ax, format="$10^{%.1f}$") cb.set_label("$\sigma$ (S/m)") ax.set_xlabel("Distance (m)") ax.set_ylabel("Depth (m)") ax.set_title("Conductivity Model") plt.show() else: plt.figure(figsize=(10, 6)) ax = plt.subplot(111) vec = False if view == "vec": tname = "Vector " title = tname + Field + "-field" elif view == "amp": tname = "|" title = tname + Field + "|-field" else: if ComplexNumber == "real": tname = "Re(" elif ComplexNumber == "imag": tname = "Im(" elif ComplexNumber == "amplitude": tname = "Amp(" elif ComplexNumber == "phase": tname = "Phase(" title = tname + Field + view + ")-field" if Field == "B": label = "Magnetic field (T)" if view == "vec": vec = True if ComplexNumber == "real": val = np.c_[self.Bx.real, self.Bz.real] elif ComplexNumber == "imag": val = np.c_[self.Bx.imag, self.Bz.imag] else: return elif view == "x": if ComplexNumber == "real": val = self.Bx.real elif ComplexNumber == "imag": val = self.Bx.imag elif ComplexNumber == "amplitude": val = abs(self.Bx) elif ComplexNumber == "phase": val = np.angle(self.Bx) elif view == "z": if ComplexNumber == "real": val = self.Bz.real elif ComplexNumber == "imag": val = self.Bz.imag elif ComplexNumber == "amplitude": val = abs(self.Bz) elif ComplexNumber == "phase": val = np.angle(self.Bz) else: return elif Field == "E": label = "Electric field (V/m)" if view == "y": if ComplexNumber == "real": val = self.Ey.real elif ComplexNumber == "imag": val = self.Ey.imag elif ComplexNumber == "amplitude": val = abs(self.Ey) elif ComplexNumber == "phase": val = np.angle(self.Ey) else: return elif Field == "J": label = "Current density (A/m$^2$)" if view == "y": if ComplexNumber == "real": val = self.Jy.real elif ComplexNumber == "imag": val = self.Jy.imag elif ComplexNumber == "amplitude": val = abs(self.Jy) elif ComplexNumber == "phase": val = np.angle(self.Jy) else: return out = utils.plot2Ddata( self.mesh2D.gridCC, val, vec=vec, ax=ax, contourOpts={"cmap": "viridis"}, ncontour=200, scale=scale, ) cb = plt.colorbar(out[0], ax=ax, format="%.2e") cb.set_label(label) xmax = self.mesh2D.gridCC[:, 0].max() if Geometry: if Scenario == "Layer": ax.plot(np.r_[-xmax, xmax], np.ones(2) * self.srcLoc[2], "w-", lw=1) ax.plot(np.r_[-xmax, xmax], np.ones(2) * self.z0, "w--", lw=1) ax.plot(np.r_[-xmax, xmax], np.ones(2) * self.z1, "w--", lw=1) ax.plot(np.r_[-xmax, xmax], np.ones(2) * self.z2, "w--", lw=1) ax.plot(0, self.srcLoc[2], "ko", ms=4) ax.plot(self.rxLoc[0, 0], self.srcLoc[2], "ro", ms=4) elif Scenario == "Sphere": ax.plot(np.r_[-xmax, xmax], np.ones(2) * self.srcLoc[2], "k-", lw=1) ax.plot(np.r_[-xmax, xmax], np.ones(2) * self.z0, "w--", lw=1) ax.plot(np.r_[-xmax, xmax], np.ones(2) * self.z1, "w--", lw=1) ax.plot(np.r_[-xmax, xmax], np.ones(2) * (self.z1 - self.h), "w--", lw=1) Phi = np.linspace(0, 2 * np.pi, 41) ax.plot( self.R * np.cos(Phi), self.z2 + self.R * np.sin(Phi), "w--", lw=1, ) ax.plot(0, self.srcLoc[2], "ko", ms=4) ax.plot(self.rxLoc[0, 0], self.srcLoc[2], "ro", ms=4) ax.set_xlabel("Distance (m)") ax.set_ylabel("Depth (m)") title = title + "\nf = " + "{:.2e}".format(Frequency) + " Hz" ax.set_title(title) plt.show() ###################################################### # LAYER WIDGET ###################################################### def InteractivePlane_Layer(self, scale="log", fieldvalue="B", compvalue="z"): def foo( Field, AmpDir, Component, ComplexNumber, Sigma0, Sigma1, Sigma2, Sigma3, Sus, h1, h2, Scale, rxOffset, z, ifreq, Geometry=True, ): Frequency = 10**((ifreq - 1.0) / 3.0 - 2.0) if ComplexNumber == "Re": ComplexNumber = "real" elif ComplexNumber == "Im": ComplexNumber = "imag" elif ComplexNumber == "Amp": ComplexNumber = "amplitude" elif ComplexNumber == "Phase": ComplexNumber = "phase" if AmpDir == "Direction (B or Bsec)": # ComplexNumber = "real" Component = "vec" if Field == "Bsec": bType = "bSecondary" Field = "B" else: bType = "b" self.setThreeLayerParam( h1=h1, h2=h2, sig0=Sigma0, sig1=Sigma1, sig2=Sigma2, sig3=Sigma3, chi=Sus, ) srcLoc = np.array([0.0, 0.0, z]) rxLoc = np.array([[rxOffset, 0.0, z]]) self.simulate(srcLoc, rxLoc, np.r_[Frequency]) if Field != "Model": self.getFields(bType=bType) return self.plotField( Field=Field, ComplexNumber=ComplexNumber, view=Component, scale=Scale, Frequency=Frequency, Geometry=Geometry, Scenario="Layer", ) out = widgetify( foo, Field=widgets.ToggleButtons( options=["E", "B", "Bsec", "J", "Model"], value="E"), AmpDir=widgets.ToggleButtons( options=["None", "Direction (B or Bsec)"], value="None"), Component=widgets.ToggleButtons(options=["x", "y", "z"], value="y", description="Comp."), ComplexNumber=widgets.ToggleButtons( options=["Re", "Im", "Amp", "Phase"], value="Re", description="Re/Im"), Sigma0=widgets.FloatText(value=1e-8, continuous_update=False, description="$\sigma_0$ (S/m)"), Sigma1=widgets.FloatText(value=0.01, continuous_update=False, description="$\sigma_1$ (S/m)"), Sigma2=widgets.FloatText(value=0.01, continuous_update=False, description="$\sigma_2$ (S/m)"), Sigma3=widgets.FloatText(value=0.01, continuous_update=False, description="$\sigma_3$ (S/m)"), Sus=widgets.FloatText(value=0.0, continuous_update=False, description="$\chi$"), h1=widgets.FloatSlider( min=2.0, max=40.0, step=2.0, value=10.0, continuous_update=False, description="$h_1$ (m)", ), h2=widgets.FloatSlider( min=2.0, max=40.0, step=2.0, value=10.0, continuous_update=False, description="$h_2$ (m)", ), Scale=widgets.ToggleButtons(options=["log", "linear"], value="linear"), rxOffset=widgets.FloatSlider( min=0.0, max=50.0, step=2.0, value=10.0, continuous_update=False, description="$\Delta x$(m)", ), z=widgets.FloatSlider( min=0.0, max=50.0, step=2.0, value=0.0, continuous_update=False, description="$\Delta z$ (m)", ), ifreq=widgets.IntSlider( min=1, max=31, step=1, value=16, continuous_update=False, description="f index", ), ) return out def InteractiveData_Layer(self, fieldvalue="B", compvalue="z", z=0.0): frequency = np.logspace(2, 5, 31) self.simulate(self.srcLoc, self.rxLoc, frequency) def foo(Field, Component, Scale): # Printout for null cases if (Field == "B") & (Component == "y") | (Field == "Bsec") & ( Component == "y"): print( "Think about the problem geometry. There is NO By in this case." ) elif (Field == "E") & (Component == "x") | (Field == "E") & ( Component == "z"): print( "Think about the problem geometry. There is NO Ex or Ez in this case. Only Ey." ) else: plt.figure() ax = plt.subplot(111) bType = "b" if (Field == "Bsec") or (Field == "B"): if Field == "Bsec": bType = "bSecondary" Field = "B" self.getData(bType=bType) label = "Magnetic field (T)" if Component == "x": title = "Bx" valr = self.Bx.real vali = self.Bx.imag elif Component == "z": title = "Bz" valr = self.Bz.real vali = self.Bz.imag else: # ax.imshow(self.im) ax.set_xticks([]) ax.set_yticks([]) print( "Think about the problem geometry. There is NO By in this case." ) elif Field == "E": self.getData(bType=bType) label = "Electric field (V/m)" title = "Ey" if Component == "y": valr = self.Ey.real vali = self.Ey.imag else: # ax.imshow(self.im) ax.set_xticks([]) ax.set_yticks([]) print( "Think about the problem geometry. There is NO Ex or Ez in this case." ) elif Field == "J": print( "The conductivity at the location is 0. Therefore there is no electrical current here." ) if Scale == "log": valr_p, valr_n = DisPosNegvalues(valr) vali_p, vali_n = DisPosNegvalues(vali) ax.plot(frequency, valr_p, "k-") ax.plot(frequency, valr_n, "k--") ax.plot(frequency, vali_p, "r-") ax.plot(frequency, vali_n, "r--") ax.legend(("Re (+)", "Re (-)", "Im (+)", "Im (-)"), loc=4, fontsize=10) else: ax.plot(frequency, valr, "k.-") ax.plot(frequency, vali, "r.-") ax.legend(("Re", "Im"), loc=4, fontsize=10) ax.set_xscale("log") ax.set_yscale(Scale) ax.set_xlabel("Frequency (Hz)") ax.set_ylabel(label) ax.set_title(title) ax.grid(True) plt.show() out = widgetify( foo, Field=widgets.ToggleButtons(options=["E", "B", "Bsec"], value=fieldvalue), Component=widgets.ToggleButtons(options=["x", "y", "z"], value=compvalue, description="Comp."), Scale=widgets.ToggleButtons(options=["log", "linear"], value="log"), ) return out ###################################################### # SPHERE WIDGET ###################################################### def InteractivePlane_Sphere(self, scale="log", fieldvalue="B", compvalue="z"): def foo( Field, AmpDir, Component, ComplexNumber, Sigma0, Sigmab, Sigma1, Sigma2, Sus, d1, h, d2, R, Scale, rxOffset, z, ifreq, Geometry=True, ): Frequency = 10**((ifreq - 1.0) / 3.0 - 2.0) if ComplexNumber == "Re": ComplexNumber = "real" elif ComplexNumber == "Im": ComplexNumber = "imag" elif ComplexNumber == "Amp": ComplexNumber = "amplitude" elif ComplexNumber == "Phase": ComplexNumber = "phase" if AmpDir == "Direction (B or Bsec)": # ComplexNumber = "real" Component = "vec" if Field == "Bsec": bType = "bSecondary" Field = "B" else: bType = "b" self.setLayerSphereParam( d1=d1, h=h, d2=d2, R=R, sig0=Sigma0, sigb=Sigmab, sig1=Sigma1, sig2=Sigma2, chi=Sus, ) srcLoc = np.array([0.0, 0.0, z]) rxLoc = np.array([[rxOffset, 0.0, z]]) self.simulate(srcLoc, rxLoc, np.r_[Frequency]) if Field != "Model": self.getFields(bType=bType) return self.plotField( Field=Field, ComplexNumber=ComplexNumber, Frequency=Frequency, view=Component, scale=Scale, Geometry=Geometry, Scenario="Sphere", ) out = widgetify( foo, Field=widgets.ToggleButtons( options=["E", "B", "Bsec", "J", "Model"], value="E"), AmpDir=widgets.ToggleButtons( options=["None", "Direction (B or Bsec)"], value="None"), Component=widgets.ToggleButtons(options=["x", "y", "z"], value="y", description="Comp."), ComplexNumber=widgets.ToggleButtons( options=["Re", "Im", "Amp", "Phase"], value="Re", description="Re/Im"), Sigma0=widgets.FloatText(value=1e-8, continuous_update=False, description="$\sigma_0$ (S/m)"), Sigmab=widgets.FloatText(value=0.01, continuous_update=False, description="$\sigma_b$ (S/m)"), Sigma1=widgets.FloatText(value=0.01, continuous_update=False, description="$\sigma_1$ (S/m)"), Sigma2=widgets.FloatText(value=0.01, continuous_update=False, description="$\sigma_2$ (S/m)"), Sus=widgets.FloatText(value=0.0, continuous_update=False, description="$\chi$"), d1=widgets.FloatSlider( min=0.0, max=50.0, step=2.0, value=0.0, continuous_update=False, description="$d_1$ (m)", ), h=widgets.FloatSlider( min=2.0, max=20.0, step=2.0, value=10.0, continuous_update=False, description="$h$ (m)", ), d2=widgets.FloatSlider( min=10.0, max=50.0, step=2.0, value=30.0, continuous_update=False, description="$d_2$ (m)", ), R=widgets.FloatSlider( min=2.0, max=20.0, step=2.0, value=10.0, continuous_update=False, description="$R$ (m)", ), Scale=widgets.ToggleButtons(options=["log", "linear"], value="linear"), rxOffset=widgets.FloatSlider( min=0.0, max=50.0, step=2.0, value=10.0, continuous_update=False, description="$\Delta x$(m)", ), z=widgets.FloatSlider( min=0.0, max=50.0, step=2.0, value=0.0, continuous_update=False, description="$\Delta z$ (m)", ), ifreq=widgets.IntSlider( min=1, max=31, step=1, value=16, continuous_update=False, description="f index", ), ) return out def InteractiveData_Sphere(self, fieldvalue="B", compvalue="z", z=0.0): frequency = np.logspace(2, 5, 31) self.simulate(self.srcLoc, self.rxLoc, frequency) def foo(Field, Component, Scale): # Printout for null cases if (Field == "B") & (Component == "y") | (Field == "Bsec") & ( Component == "y"): print( "Think about the problem geometry. There is NO By in this case." ) elif (Field == "E") & (Component == "x") | (Field == "E") & ( Component == "z"): print( "Think about the problem geometry. There is NO Ex or Ez in this case. Only Ey." ) else: plt.figure() ax = plt.subplot(111) bType = "b" if (Field == "Bsec") or (Field == "B"): if Field == "Bsec": bType = "bSecondary" Field = "B" self.getData(bType=bType) label = "Magnetic field (T)" if Component == "x": title = "Bx" valr = self.Bx.real vali = self.Bx.imag elif Component == "z": title = "Bz" valr = self.Bz.real vali = self.Bz.imag else: # ax.imshow(self.im) ax.set_xticks([]) ax.set_yticks([]) print( "Think about the problem geometry. There is NO By in this case." ) elif Field == "E": self.getData(bType=bType) label = "Electric field (V/m)" title = "Ey" if Component == "y": valr = self.Ey.real vali = self.Ey.imag else: # ax.imshow(self.im) ax.set_xticks([]) ax.set_yticks([]) print( "Think about the problem geometry. There is NO Ex or Ez in this case." ) elif Field == "J": print( "The conductivity at the location is 0. Therefore there is no electrical current here." ) if Scale == "log": valr_p, valr_n = DisPosNegvalues(valr) vali_p, vali_n = DisPosNegvalues(vali) ax.plot(frequency, valr_p, "k-") ax.plot(frequency, valr_n, "k--") ax.plot(frequency, vali_p, "r-") ax.plot(frequency, vali_n, "r--") ax.legend(("Re (+)", "Re (-)", "Im (+)", "Im (-)"), loc=4, fontsize=10) else: ax.plot(frequency, valr, "k.-") ax.plot(frequency, vali, "r.-") ax.legend(("Re", "Im"), loc=4, fontsize=10) ax.set_xscale("log") ax.set_yscale(Scale) ax.set_xlabel("Frequency (Hz)") ax.set_ylabel(label) ax.set_title(title) ax.grid(True) plt.show() out = widgetify( foo, Field=widgets.ToggleButtons(options=["E", "B", "Bsec"], value=fieldvalue), Component=widgets.ToggleButtons(options=["x", "y", "z"], value=compvalue, description="Comp."), Scale=widgets.ToggleButtons(options=["log", "linear"], value="log"), ) return out
kneg = (xycc[:, 0] == -10) & (xycc[:, 1] == 0) # -ve charge distr. at (-10, 0) kpos = (xycc[:, 0] == 10) & (xycc[:, 1] == 0) # +ve charge distr. at (10, 0) rho = np.zeros(mesh.nC) rho[kneg] = -1 rho[kpos] = 1 # LU factorization and solve AinvM = SolverLU(A) phi = AinvM * rho # Compute electric fields E = Mf_inv * DIV.T * Mc * phi # Plotting fig = plt.figure(figsize=(14, 4)) ax1 = fig.add_subplot(131) mesh.plotImage(rho, v_type="CC", ax=ax1) ax1.set_title("Charge Density") ax2 = fig.add_subplot(132) mesh.plotImage(phi, v_type="CC", ax=ax2) ax2.set_title("Electric Potential") ax3 = fig.add_subplot(133) mesh.plotImage( E, ax=ax3, v_type="F", view="vec", stream_opts={"color": "w", "density": 1.0} ) ax3.set_title("Electric Fields")
class MagneticDipoleApp(object): """docstring for MagneticDipoleApp""" mesh = None component = None z = None inclination = None declination = None length = None dx = None moment = None depth = None data = None profile = None xy_profile = None clim = None def __init__(self): super(MagneticDipoleApp, self).__init__() def id_to_cartesian(self, inclination, declination): ux = np.cos(inclination / 180.0 * np.pi) * np.sin( declination / 180.0 * np.pi) uy = np.cos(inclination / 180.0 * np.pi) * np.cos( declination / 180.0 * np.pi) uz = -np.sin(inclination / 180.0 * np.pi) return np.r_[ux, uy, uz] def dot_product(self, b_vec, orientation): b_tmi = np.dot(b_vec, orientation) return b_tmi def simulate_dipole( self, component, target, inclination, declination, length, dx, moment, depth, profile, fixed_scale, show_halfwidth, ): self.component = component self.target = target self.inclination = inclination self.declination = declination self.length = length self.dx = dx self.moment = moment self.depth = depth self.profile = profile self.fixed_scale = fixed_scale self.show_halfwidth = show_halfwidth nT = 1e9 nx = ny = int(length / dx) hx = np.ones(nx) * dx hy = np.ones(ny) * dx self.mesh = TensorMesh((hx, hy), "CC") z = np.r_[1.0] orientation = self.id_to_cartesian(inclination, declination) if self.target == "Dipole": md = em.static.MagneticDipoleWholeSpace(location=np.r_[0, 0, -depth], orientation=orientation, moment=moment) xyz = utils.ndgrid(self.mesh.vectorCCx, self.mesh.vectorCCy, z) b_vec = md.magnetic_flux_density(xyz) elif self.target == "Monopole (+)": md = em.static.MagneticPoleWholeSpace(location=np.r_[0, 0, -depth], orientation=orientation, moment=moment) xyz = utils.ndgrid(self.mesh.vectorCCx, self.mesh.vectorCCy, z) b_vec = md.magnetic_flux_density(xyz) elif self.target == "Monopole (-)": md = em.static.MagneticPoleWholeSpace(location=np.r_[0, 0, -depth], orientation=orientation, moment=moment) xyz = utils.ndgrid(self.mesh.vectorCCx, self.mesh.vectorCCy, z) b_vec = -md.magnetic_flux_density(xyz) # Project to the direction of earth field if component == "Bt": rx_orientation = orientation.copy() elif component == "Bg": rx_orientation = orientation.copy() xyz_up = utils.ndgrid(self.mesh.vectorCCx, self.mesh.vectorCCy, z + 1.0) b_vec -= md.magnetic_flux_density(xyz_up) elif component == "Bx": rx_orientation = self.id_to_cartesian(0, 0) elif component == "By": rx_orientation = self.id_to_cartesian(0, 90) elif component == "Bz": rx_orientation = self.id_to_cartesian(90, 0) self.data = self.dot_product(b_vec, rx_orientation) * nT # Compute profile if (profile == "North") or (profile == "None"): self.xy_profile = np.c_[np.zeros(self.mesh.nCx), self.mesh.vectorCCx] elif profile == "East": self.xy_profile = np.c_[self.mesh.vectorCCx, np.zeros(self.mesh.nCx)] self.inds_profile = utils.closestPoints(self.mesh, self.xy_profile) self.data_profile = self.data[self.inds_profile] def simulate_two_monopole( self, component, inclination, declination, length, dx, moment, depth_n, depth_p, profile, fixed_scale, show_halfwidth, ): self.component = component self.inclination = inclination self.declination = declination self.length = length self.dx = dx self.moment = moment self.depth = depth_n self.depth = depth_p self.profile = profile self.fixed_scale = fixed_scale self.show_halfwidth = show_halfwidth nT = 1e9 nx = ny = int(length / dx) hx = np.ones(nx) * dx hy = np.ones(ny) * dx self.mesh = TensorMesh((hx, hy), "CC") z = np.r_[1.0] orientation = self.id_to_cartesian(inclination, declination) md_n = em.static.MagneticPoleWholeSpace(location=np.r_[0, 0, -depth_n], orientation=orientation, moment=moment) md_p = em.static.MagneticPoleWholeSpace(location=np.r_[0, 0, -depth_p], orientation=orientation, moment=moment) xyz = utils.ndgrid(self.mesh.vectorCCx, self.mesh.vectorCCy, z) b_vec = -md_n.magnetic_flux_density(xyz) + md_p.magnetic_flux_density( xyz) # Project to the direction of earth field if component == "Bt": rx_orientation = orientation.copy() elif component == "Bx": rx_orientation = self.id_to_cartesian(0, 0) elif component == "By": rx_orientation = self.id_to_cartesian(0, 90) elif component == "Bz": rx_orientation = self.id_to_cartesian(90, 0) elif component == "Bg": rx_orientation = orientation.copy() xyz_up = utils.ndgrid(self.mesh.vectorCCx, self.mesh.vectorCCy, z + 1.0) b_vec -= -md_n.magnetic_flux_density(xyz_up) b_vec -= md_p.magnetic_flux_density(xyz_up) self.data = self.dot_product(b_vec, rx_orientation) * nT # Compute profile if (profile == "North") or (profile == "None"): self.xy_profile = np.c_[np.zeros(self.mesh.nCx), self.mesh.vectorCCx] elif profile == "East": self.xy_profile = np.c_[self.mesh.vectorCCx, np.zeros(self.mesh.nCx)] self.inds_profile = utils.closestPoints(self.mesh, self.xy_profile) self.data_profile = self.data[self.inds_profile] def get_prism(self, dx, dy, dz, x0, y0, elev, prism_inc, prism_dec): prism = definePrism() prism.dx, prism.dy, prism.dz, prism.z0 = dy, dx, dz, elev prism.x0, prism.y0 = x0, y0 prism.pinc, prism.pdec = prism_inc, prism_dec return prism def plot_prism(self, prism, dip=30, azim=310): return plotObj3D(prism, self.survey, dip, azim, self.mesh.vectorCCx.max()) def simulate_prism( self, component, inclination, declination, length, dx, B0, kappa, depth, profile, fixed_scale, show_halfwidth, prism_dx, prism_dy, prism_dz, prism_inclination, prism_declination, ): self.component = component self.inclination = -inclination # -ve accounts for LH modeling in SimPEG self.declination = declination self.length = length self.dx = dx self.B0 = B0 self.kappa = kappa self.depth = depth self.profile = profile self.fixed_scale = fixed_scale self.show_halfwidth = show_halfwidth # prism parameter self.prism = self.get_prism( prism_dx, prism_dy, prism_dz, 0, 0, -depth, prism_inclination, prism_declination, ) nx = ny = int(length / dx) hx = np.ones(nx) * dx hy = np.ones(ny) * dx self.mesh = TensorMesh((hx, hy), "CC") z = np.r_[1.0] B = np.r_[B0, -inclination, declination] # -ve accounts for LH modeling in SimPEG # Project to the direction of earth field if component == "Bt": uType = "tf" elif component == "Bx": uType = "bx" elif component == "By": uType = "by" elif component == "Bz": uType = "bz" xyz = utils.ndgrid(self.mesh.vectorCCx, self.mesh.vectorCCy, z) out = createMagSurvey(np.c_[xyz, np.ones(self.mesh.nC)], B) self.survey = out[0] self.dobs = out[1] self.sim = Simulation() self.sim.prism = self.prism self.sim.survey = self.survey self.sim.susc = kappa self.sim.uType, self.sim.mType = uType, "induced" self.data = self.sim.fields()[0] # Compute profile if (profile == "North") or (profile == "None"): self.xy_profile = np.c_[np.zeros(self.mesh.nCx), self.mesh.vectorCCx] elif profile == "East": self.xy_profile = np.c_[self.mesh.vectorCCx, np.zeros(self.mesh.nCx)] self.inds_profile = utils.closestPoints(self.mesh, self.xy_profile) self.data_profile = self.data[self.inds_profile] def plot_map(self): length = self.length data = self.data profile = self.profile fig = plt.figure(figsize=(5, 6)) ax1 = plt.subplot2grid((8, 4), (0, 0), rowspan=5, colspan=3) ax2 = plt.subplot2grid((8, 4), (6, 0), rowspan=2, colspan=3) if (self.clim is None) or (not self.fixed_scale): self.clim = data.min(), data.max() out = self.mesh.plotImage(self.data, pcolorOpts={"cmap": "jet"}, ax=ax1, clim=self.clim) cax = fig.add_axes([0.75, 0.45, 0.02, 0.5]) ratio = abs(self.clim[0] / self.clim[1]) if ratio < 0.05: ticks = [self.clim[0], self.clim[1]] else: ticks = [self.clim[0], 0, self.clim[1]] cb = plt.colorbar(out[0], ticks=ticks, format="%.3f", cax=cax) cb.set_label("nT", labelpad=-40, y=-0.05, rotation=0) ax1.set_aspect(1) ax1.set_ylabel("Northing") ax1.set_xlabel("Easting") if profile == "North": # xy_profile = np.c_[np.zeros(self.mesh.nCx), self.mesh.vectorCCx] ax1.text(1, length / 2 - length / 2 * 0.1, "B", color="w") ax1.text(1, -length / 2, "A", color="w") elif profile == "East": # xy_profile = np.c_[self.mesh.vectorCCx, np.zeros(self.mesh.nCx)] ax1.text(length / 2 - length / 2 * 0.1, 1, "B", color="w") ax1.text(-length / 2, 1, "A", color="w") ax1.set_xticks([]) ax1.set_yticks([]) ax2.yaxis.tick_right() ax2.plot(self.mesh.vectorCCx, self.data_profile, "k", lw=2) ax2.plot(self.mesh.vectorCCx, np.zeros(self.mesh.nCx), "k--", color="grey", lw=1) ax2.set_xlim(-self.length / 2.0, self.length / 2.0) ymin, ymax = ax2.get_ylim() ax2.text(-self.length / 2.0, ymax, "A") ax2.text(self.length / 2.0 - self.length / 2 * 0.05, ymax, "B") ax2.set_yticks([self.clim[0], self.clim[1]]) if self.show_halfwidth: x_half, data_half = self.get_half_width() ax2.plot(x_half, data_half, "bo--") ax2.set_xlabel(("Halfwidth: %.1fm") % (abs(np.diff(x_half)))) else: ax2.set_xlabel(" ") # plt.tight_layout() if profile == "None": ax2.remove() else: ax1.plot(self.xy_profile[:, 0], self.xy_profile[:, 1], "w") def get_half_width(self, n_points=200): ind_max = np.argmax(abs(self.data_profile)) A_half = self.data_profile[ind_max] / 2.0 if self.profile == "North": x = self.xy_profile[:, 1] else: x = self.xy_profile[:, 0] f = interp1d(x, self.data_profile) x_int = np.linspace(x.min(), x.max(), n_points) data_profile_int = f(x_int) inds = np.argsort(abs(data_profile_int - A_half)) ind_first = inds[0] for ind in inds: dx = abs(x_int[ind_first] - x_int[ind]) if dx > self.dx: ind_second = ind break inds = [ind_first, ind_second] return x_int[inds], data_profile_int[inds] def magnetic_dipole_applet( self, component, target, inclination, declination, length, dx, moment, depth, profile, fixed_scale, show_halfwidth, ): self.simulate_dipole( component, target, inclination, declination, length, dx, moment, depth, profile, fixed_scale, show_halfwidth, ) self.plot_map() def magnetic_two_monopole_applet( self, component, inclination, declination, length, dx, moment, depth_n, depth_p, profile, fixed_scale, show_halfwidth, ): self.simulate_two_monopole( component, inclination, declination, length, dx, moment, depth_n, depth_p, profile, fixed_scale, show_halfwidth, ) self.plot_map() def magnetic_prism_applet( self, plot, component, inclination, declination, length, dx, B0, kappa, depth, profile, fixed_scale, show_halfwidth, prism_dx, prism_dy, prism_dz, prism_inclination, prism_declination, ): if plot == "field": self.simulate_prism( component, inclination, declination, length, dx, B0, kappa, depth, profile, fixed_scale, show_halfwidth, prism_dx, prism_dy, prism_dz, prism_inclination, prism_declination, ) self.plot_map() elif plot == "model": self.prism = self.get_prism( prism_dx, prism_dy, prism_dz, 0, 0, -depth, prism_inclination, prism_declination, ) self.plot_prism(self.prism) def interact_plot_model_dipole(self): component = widgets.RadioButtons( options=["Bt", "Bx", "By", "Bz", "Bg"], value="Bt", description="field", disabled=False, ) target = widgets.RadioButtons( options=["Dipole", "Monopole (+)", "Monopole (-)"], value="Dipole", description="target", disabled=False, ) inclination = widgets.FloatSlider(description="I", continuous_update=False, min=-90, max=90, step=1, value=90) declination = widgets.FloatSlider(description="D", continuous_update=False, min=-180, max=180, step=1, value=0) length = widgets.FloatSlider( description="length", continuous_update=False, min=2, max=200, step=1, value=72, ) dx = widgets.FloatSlider( description="data spacing", continuous_update=False, min=0.1, max=15, step=0.1, value=2, ) moment = widgets.FloatText(description="M", value=30) depth = widgets.FloatSlider( description="depth", continuous_update=False, min=0, max=50, step=1, value=10, ) profile = widgets.RadioButtons( options=["East", "North", "None"], value="East", description="profile", disabled=False, ) fixed_scale = widgets.Checkbox(value=False, description="fixed scale", disabled=False) show_halfwidth = widgets.Checkbox(value=False, description="half width", disabled=False) out = widgets.interactive_output( self.magnetic_dipole_applet, { "component": component, "target": target, "inclination": inclination, "declination": declination, "length": length, "dx": dx, "moment": moment, "depth": depth, "profile": profile, "fixed_scale": fixed_scale, "show_halfwidth": show_halfwidth, }, ) left = widgets.VBox( [component, profile], layout=Layout(width="20%", height="400px", margin="60px 0px 0px 0px"), ) right = widgets.VBox( [ target, inclination, declination, length, dx, moment, depth, fixed_scale, show_halfwidth, ], layout=Layout(width="50%", height="400px", margin="20px 0px 0px 0px"), ) widgets.VBox([out], layout=Layout(width="70%", height="400px", margin="0px 0px 0px 0px")) return widgets.HBox([left, out, right]) def interact_plot_model_two_monopole(self): component = widgets.RadioButtons( options=["Bt", "Bx", "By", "Bz", "Bg"], value="Bt", description="field", disabled=False, ) inclination = widgets.FloatSlider(description="I", continuous_update=False, min=-90, max=90, step=1, value=90) declination = widgets.FloatSlider(description="D", continuous_update=False, min=-180, max=180, step=1, value=0) length = widgets.FloatSlider( description="length", continuous_update=False, min=2, max=200, step=1, value=10, ) dx = widgets.FloatSlider( description="data spacing", continuous_update=False, min=0.1, max=15, step=0.1, value=0.1, ) moment = widgets.FloatText(description="M", value=30) depth_n = widgets.FloatSlider( description="depth$_{-Q}$", continuous_update=False, min=0, max=200, step=1, value=0, ) depth_p = widgets.FloatSlider( description="depth$_{+Q}$", continuous_update=False, min=0, max=200, step=1, value=1, ) profile = widgets.RadioButtons( options=["East", "North", "None"], value="East", description="profile", disabled=False, ) fixed_scale = widgets.Checkbox(value=False, description="fixed scale", disabled=False) show_halfwidth = widgets.Checkbox(value=False, description="half width", disabled=False) out = widgets.interactive_output( self.magnetic_two_monopole_applet, { "component": component, "inclination": inclination, "declination": declination, "length": length, "dx": dx, "moment": moment, "depth_n": depth_n, "depth_p": depth_p, "profile": profile, "fixed_scale": fixed_scale, "show_halfwidth": show_halfwidth, }, ) left = widgets.VBox( [component, profile], layout=Layout(width="20%", height="400px", margin="60px 0px 0px 0px"), ) right = widgets.VBox( [ inclination, declination, length, dx, moment, depth_n, depth_p, fixed_scale, show_halfwidth, ], layout=Layout(width="50%", height="400px", margin="20px 0px 0px 0px"), ) widgets.VBox([out], layout=Layout(width="70%", height="400px", margin="0px 0px 0px 0px")) return widgets.HBox([left, out, right]) def interact_plot_model_prism(self): plot = widgets.RadioButtons( options=["field", "model"], value="field", description="plot", disabled=False, ) component = widgets.RadioButtons( options=["Bt", "Bx", "By", "Bz"], value="Bt", description="field", disabled=False, ) inclination = widgets.FloatSlider(description="I", continuous_update=False, min=-90, max=90, step=1, value=90) declination = widgets.FloatSlider(description="D", continuous_update=False, min=-180, max=180, step=1, value=0) length = widgets.FloatSlider( description="length", continuous_update=False, min=2, max=200, step=1, value=72, ) dx = widgets.FloatSlider( description="data spacing", continuous_update=False, min=0.1, max=15, step=0.1, value=2, ) kappa = widgets.FloatText(description="$\kappa$", value=0.1) B0 = widgets.FloatText(description="B$_0$", value=56000) depth = widgets.FloatSlider( description="depth", continuous_update=False, min=0, max=50, step=1, value=10, ) profile = widgets.RadioButtons( options=["East", "North", "None"], value="East", description="profile", disabled=False, ) fixed_scale = widgets.Checkbox(value=False, description="fixed scale", disabled=False) show_halfwidth = widgets.Checkbox(value=False, description="half width", disabled=False) prism_dx = widgets.FloatText(description="$\\triangle x$", value=1) prism_dy = widgets.FloatText(description="$\\triangle y$", value=1) prism_dz = widgets.FloatText(description="$\\triangle z$", value=1) prism_inclination = widgets.FloatSlider( description="I$_{prism}$", continuous_update=False, min=-90, max=90, step=1, value=0, ) prism_declination = widgets.FloatSlider( description="D$_{prism}$", continuous_update=False, min=0, max=180, step=1, value=0, ) out = widgets.interactive_output( self.magnetic_prism_applet, { "plot": plot, "component": component, "inclination": inclination, "declination": declination, "length": length, "dx": dx, "kappa": kappa, "B0": B0, "depth": depth, "profile": profile, "fixed_scale": fixed_scale, "show_halfwidth": show_halfwidth, "prism_dx": prism_dx, "prism_dy": prism_dy, "prism_dz": prism_dz, "prism_inclination": prism_inclination, "prism_declination": prism_declination, }, ) left = widgets.VBox( [plot, component, profile], layout=Layout(width="20%", height="400px", margin="60px 0px 0px 0px"), ) right = widgets.VBox( [ inclination, declination, length, dx, B0, kappa, depth, prism_dx, prism_dy, prism_dz, prism_inclination, prism_declination, fixed_scale, show_halfwidth, ], layout=Layout(width="50%", height="400px", margin="20px 0px 0px 0px"), ) widgets.VBox([out], layout=Layout(width="70%", height="400px", margin="0px 0px 0px 0px")) return widgets.HBox([left, out, right])
edges_y = mesh.gridEy wx = ((-edges_x[:, 1] / np.sqrt(np.sum(edges_x**2, axis=1))) * np.exp(-(edges_x[:, 0]**2 + edges_x[:, 1]**2) / 6**2)) wy = ((edges_y[:, 0] / np.sqrt(np.sum(edges_y**2, axis=1))) * np.exp(-(edges_y[:, 0]**2 + edges_y[:, 1]**2) / 6**2)) w = np.r_[wx, wy] curl_w = CURL * w # Plot Gradient of u fig = plt.figure(figsize=(10, 5)) ax1 = fig.add_subplot(121) mesh.plotImage(u, ax=ax1, v_type='N') ax1.set_title('u at cell centers') ax2 = fig.add_subplot(122) mesh.plotImage(grad_u, ax=ax2, v_type='E', view='vec', stream_opts={ 'color': 'w', 'density': 1.0 }) ax2.set_title('gradient of u on edges') fig.show()