Ejemplo n.º 1
0
    def setUp(self):
        url = 'https://storage.googleapis.com/simpeg/tests/dc_utils/'
        cloudfiles = [
            'mesh3d.msh', '2spheres_conmodel.npy',
            'rhoA_GIF_dd.txt', 'rhoA_GIF_dp.txt',
            'rhoA_GIF_pd.txt', 'rhoA_GIF_pp.txt'
        ]

        self.basePath = os.path.expanduser('~/Downloads/TestDCUtilsHalfSpace')
        self.files = io_utils.download(
            [url+f for f in cloudfiles],
            folder=self.basePath,
            overwrite=True
        )

        # Load Mesh
        mesh_file = os.path.sep.join([self.basePath, 'mesh3d.msh'])
        mesh = Mesh.load_mesh(mesh_file)
        self.mesh = mesh

        # Load Model
        model_file = os.path.sep.join([self.basePath, '2spheres_conmodel.npy'])
        model = np.load(model_file)
        self.model = model

        xmin, xmax = -15., 15.
        ymin, ymax = 0., 0.
        zmin, zmax = -0.25, -0.25
        xyz = np.array([[xmin, ymin, zmin], [xmax, ymax, zmax]])
        self.xyz = xyz
        self.survey_a = 1.
        self.survey_b = 1.
        self.survey_n = 10
        self.plotIt = False
Ejemplo n.º 2
0
    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 = 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)
        self.survey = createMagSurvey(np.c_[xyz, np.ones(self.mesh.nC)], B)
        self.prob = problem()

        self.prob.prism = self.prism
        self.prob.survey = self.survey
        self.prob.susc = kappa
        self.prob.uType, self.prob.mType = uType, "induced"

        self.data = self.prob.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]
Ejemplo n.º 3
0
# receivers
rx_x = np.linspace(-175., 175., 8)
rx_y = rx_x.copy()
rx_z = np.r_[175.]
rx_locs = Utils.ndgrid(rx_x, rx_y, rx_z)

# mesh
csx, ncx, npadx = 25., 16, 10
csz, ncz, npadz = 25., 8, 10
pf = 1.5

# primary mesh
hx = [(csx, ncx), (csx, npadx, pf)]
hz = [(csz, npadz, -pf), (csz, ncz), (csz, npadz, pf)]
meshp = Mesh.CylMesh([hx, 1., hz], x0='0CC')

# secondary mesh
h = [(csz, npadz-4, -pf), (csz, ncz), (csz, npadz-4, pf)]
meshs = Mesh.TensorMesh(3*[h], x0 = 'CCC')

# mappings
primaryMapping = (
    Maps.ExpMap(meshp) *
    Maps.SurjectFull(meshp) *
    Maps.Projection(nP=8, index=[0])
)

mapping = (
    Maps.ExpMap(meshs) *
    Maps.ParametrizedBlockInLayer(meshs) *
#    scale = Utils.mkvc(homogMap.P.sum(axis=0))
#    for ii in range(nC):
#        wr[ii] *= scale[ii]
    wr = (wr / np.max(wr))
    wr = wr

else:
    wr = Mesh.TensorMesh.readModelUBC(mesh, work_dir + dsep + wgtfile)
    wr = wr[actv]
    wr = wr**2.

Mesh.TensorMesh.writeModelUBC(mesh, work_dir + out_dir + 'SensWeights.den',
                              actvMap * (homogMap.P * wr))

idenMap = Maps.IdentityMap(nP=nC)
regMesh = Mesh.TensorMesh([nC])

# Create a regularization
reg = Regularization.Sparse(regMesh, mapping=idenMap)
reg.norms = driver.lpnorms

if driver.eps is not None:
    reg.eps_p = driver.eps[0]
    reg.eps_q = driver.eps[1]

reg.cell_weights = wr  #driver.cell_weights*mesh.vol**0.5
reg.mref = mstart

dmis = DataMisfit.l2_DataMisfit(survey)
dmis.W = 1. / survey.std
Ejemplo n.º 5
0
def readSeepageModel(fname, mesh=None, xsurf=None, ysurf=None):

    fluiddata = pd.read_csv(fname)
    header = fluiddata.keys()
    xyz = np.c_[fluiddata['X (m)'].values, fluiddata['Y (m)'].values]
    h = fluiddata['Total Head (m)'].values
    Ux = fluiddata['X-Velocity Magnitude (m/sec)'].values
    Uy = fluiddata['Y-Velocity Magnitude (m/sec)'].values
    Gradx = fluiddata['X-Gradient'].values
    Grady = fluiddata['Y-Gradient'].values

    Pressure = fluiddata['Pressure Head (m)'].values
    Sw = fluiddata[fluiddata.keys()[17]].values
    Kx = fluiddata["X-Conductivity (m/sec)"]
    Ky = fluiddata["Y-Conductivity (m/sec)"]

    if mesh is None:
        # TODO: this is a specific set up ...
        xmin, ymin = xyz[:, 0].min(), xyz[:, 1].min()
        cs = 0.5
        ncx = 152 * 2
        ncy = 36 * 2
        npad = 5
        hx = [(cs, npad, -1.3), (cs, ncx), (cs, npad, 1.3)]
        hy = [(cs, npad, -1.3), (cs, ncy)]
        mesh = Mesh.TensorMesh([hx, hy], x0=[xmin, ymin])
        mesh._x0 = np.r_[xmin - mesh.hx[:10].sum(), xmin - mesh.hy[:10].sum()]
        # ...
        xsurf = np.r_[-1e10, 55, 90, 94, 109, 112, 126.5, +1e10]
        ysurf = np.r_[27.5, 27.5, 43.2, 43.2, 35, 35, 27.5, 27.5]
        yup = np.ones_like(ysurf) * 45
        actind = Utils.surface2ind_topo(mesh, np.c_[xsurf, ysurf])
        waterheight = 40.
        waterind = ((np.logical_and(~actind, mesh.gridCC[:, 1] < 40.)) &
                    (mesh.gridCC[:, 0] < 90.))

    F_hlin = LinearNDInterpolator(xyz, h)
    hccIn = F_hlin(mesh.gridCC[actind, :])
    F_hnear = NearestNDInterpolator(mesh.gridCC[actind, :], hccIn)
    hcc = F_hnear(mesh.gridCC)
    fluiddata = {
        "xyz": xyz,
        "h": h,
        "Sw": Sw,
        "Kx": Kx,
        "Ky": Ky,
        "P": Pressure,
        "Ux": Ux,
        "Uy": Uy,
        "Gradx": Gradx,
        "Grady": Grady,
        "hcc": hcc,
        "mesh": mesh,
        "actind": actind,
        "waterind": waterind,
        "xsurf": xsurf,
        "ysurf": ysurf,
        "yup": yup
    }

    return fluiddata
Ejemplo n.º 6
0
def run(plotIt=True):
    """
        EM: FDEM: 1D: Inversion
        =======================

        Here we will create and run a FDEM 1D inversion.

    """

    cs, ncx, ncz, npad = 5., 25, 15, 15
    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')

    layerz = -100.

    active = mesh.vectorCCz < 0.
    layer = (mesh.vectorCCz < 0.) & (mesh.vectorCCz >= layerz)
    actMap = Maps.InjectActiveCells(mesh, active, np.log(1e-8), nC=mesh.nCz)
    mapping = Maps.ExpMap(mesh) * Maps.SurjectVertical1D(mesh) * actMap
    sig_half = 2e-2
    sig_air = 1e-8
    sig_layer = 1e-2
    sigma = np.ones(mesh.nCz) * sig_air
    sigma[active] = sig_half
    sigma[layer] = sig_layer
    mtrue = np.log(sigma[active])

    if plotIt:
        fig, ax = plt.subplots(1, 1, figsize=(3, 6))
        plt.semilogx(sigma[active], mesh.vectorCCz[active])
        ax.set_ylim(-500, 0)
        ax.set_xlim(1e-3, 1e-1)
        ax.set_xlabel('Conductivity (S/m)', fontsize=14)
        ax.set_ylabel('Depth (m)', fontsize=14)
        ax.grid(color='k', alpha=0.5, linestyle='dashed', linewidth=0.5)

    rxOffset = 10.
    bzi = EM.FDEM.Rx.Point_b(np.array([[rxOffset, 0., 1e-3]]),
                             orientation='z',
                             component='imag')

    freqs = np.logspace(1, 3, 10)
    srcLoc = np.array([0., 0., 10.])

    srcList = [
        EM.FDEM.Src.MagDipole([bzi], freq, srcLoc, orientation='Z')
        for freq in freqs
    ]

    survey = EM.FDEM.Survey(srcList)
    prb = EM.FDEM.Problem3D_b(mesh, sigmaMap=mapping, Solver=Solver)
    prb.pair(survey)

    std = 0.05
    survey.makeSyntheticData(mtrue, std)

    survey.std = std
    survey.eps = np.linalg.norm(survey.dtrue) * 1e-5

    if plotIt:
        fig, ax = plt.subplots(1, 1, figsize=(6, 6))
        ax.semilogx(freqs, survey.dtrue[:freqs.size], 'b.-')
        ax.semilogx(freqs, survey.dobs[:freqs.size], 'r.-')
        ax.legend(('Noisefree', '$d^{obs}$'), fontsize=16)
        ax.set_xlabel('Time (s)', fontsize=14)
        ax.set_ylabel('$B_z$ (T)', fontsize=16)
        ax.set_xlabel('Time (s)', fontsize=14)
        ax.grid(color='k', alpha=0.5, linestyle='dashed', linewidth=0.5)

    dmisfit = DataMisfit.l2_DataMisfit(survey)
    regMesh = Mesh.TensorMesh([mesh.hz[mapping.maps[-1].indActive]])
    reg = Regularization.Tikhonov(regMesh)
    opt = Optimization.InexactGaussNewton(maxIter=6)
    invProb = InvProblem.BaseInvProblem(dmisfit, reg, opt)

    # Create an inversion object
    beta = Directives.BetaSchedule(coolingFactor=5, coolingRate=2)
    betaest = Directives.BetaEstimate_ByEig(beta0_ratio=1e0)
    inv = Inversion.BaseInversion(invProb, directiveList=[beta, betaest])
    m0 = np.log(np.ones(mtrue.size) * sig_half)
    reg.alpha_s = 1e-3
    reg.alpha_x = 1.
    prb.counter = opt.counter = Utils.Counter()
    opt.LSshorten = 0.5
    opt.remember('xc')

    mopt = inv.run(m0)

    if plotIt:
        fig, ax = plt.subplots(1, 1, figsize=(3, 6))
        plt.semilogx(sigma[active], mesh.vectorCCz[active])
        plt.semilogx(np.exp(mopt), mesh.vectorCCz[active])
        ax.set_ylim(-500, 0)
        ax.set_xlim(1e-3, 1e-1)
        ax.set_xlabel('Conductivity (S/m)', fontsize=14)
        ax.set_ylabel('Depth (m)', fontsize=14)
        ax.grid(color='k', alpha=0.5, linestyle='dashed', linewidth=0.5)
        plt.legend(['$\sigma_{true}$', '$\sigma_{pred}$'], loc='best')
Ejemplo n.º 7
0
def run(N=100, plotIt=True):

    np.random.seed(1)

    std_noise = 1e-2

    mesh = Mesh.TensorMesh([N])

    m0 = np.ones(mesh.nC) * 1e-4
    mref = np.zeros(mesh.nC)

    nk = 20
    jk = np.linspace(1., 60., nk)
    p = -0.25
    q = 0.25

    def g(k):
        return (np.exp(p * jk[k] * mesh.vectorCCx) *
                np.cos(np.pi * q * jk[k] * mesh.vectorCCx))

    G = np.empty((nk, mesh.nC))

    for i in range(nk):
        G[i, :] = g(i)

    mtrue = np.zeros(mesh.nC)
    mtrue[mesh.vectorCCx > 0.3] = 1.
    mtrue[mesh.vectorCCx > 0.45] = -0.5
    mtrue[mesh.vectorCCx > 0.6] = 0

    prob = Problem.LinearProblem(mesh, G=G)
    survey = Survey.LinearSurvey()
    survey.pair(prob)
    survey.dobs = prob.fields(mtrue) + std_noise * np.random.randn(nk)

    wd = np.ones(nk) * std_noise

    # Distance weighting
    wr = np.sum(prob.G**2., axis=0)**0.5
    wr = wr / np.max(wr)

    dmis = DataMisfit.l2_DataMisfit(survey)
    dmis.Wd = 1. / wd

    betaest = Directives.BetaEstimate_ByEig(beta0_ratio=1e-2)

    reg = Regularization.Sparse(mesh)
    reg.mref = mref
    reg.cell_weights = wr

    reg.mref = np.zeros(mesh.nC)

    opt = Optimization.ProjectedGNCG(maxIter=100,
                                     lower=-2.,
                                     upper=2.,
                                     maxIterLS=20,
                                     maxIterCG=10,
                                     tolCG=1e-3)
    invProb = InvProblem.BaseInvProblem(dmis, reg, opt)
    update_Jacobi = Directives.Update_lin_PreCond()

    # Set the IRLS directive, penalize the lowest 25 percentile of model values
    # Start with an l2-l2, then switch to lp-norms
    norms = [0., 0., 2., 2.]
    IRLS = Directives.Update_IRLS(norms=norms,
                                  prctile=25,
                                  maxIRLSiter=15,
                                  minGNiter=3)

    inv = Inversion.BaseInversion(invProb,
                                  directiveList=[IRLS, betaest, update_Jacobi])

    # Run inversion
    mrec = inv.run(m0)

    print("Final misfit:" + str(invProb.dmisfit.eval(mrec)))

    if plotIt:
        fig, axes = plt.subplots(1, 2, figsize=(12 * 1.2, 4 * 1.2))
        for i in range(prob.G.shape[0]):
            axes[0].plot(prob.G[i, :])
        axes[0].set_title('Columns of matrix G')

        axes[1].plot(mesh.vectorCCx, mtrue, 'b-')
        axes[1].plot(mesh.vectorCCx, reg.l2model, 'r-')
        # axes[1].legend(('True Model', 'Recovered Model'))
        axes[1].set_ylim(-1.0, 1.25)

        axes[1].plot(mesh.vectorCCx, mrec, 'k-', lw=2)
        axes[1].legend(('True Model', 'Smooth l2-l2',
                        'Sparse lp: {0}, lqx: {1}'.format(*reg.norms)),
                       fontsize=12)

    return prob, survey, mesh, mrec
Ejemplo n.º 8
0
from sklearn.mixture import GaussianMixture
from SimPEG import DataMisfit, Regularization, Optimization, InvProblem, Directives, Inversion
import SimPEG
import scipy.sparse as sp

#2D model
csx, csy, csz = 0.25, 0.25, 0.25
# Number of core cells in each directiPon s
ncx, ncz = 2**7 - 24, 2**7 - 12
# Number of padding cells to add in each direction
npad = 12
# Vectors of cell lengthts in each direction
hx = [(csx, npad, -1.5), (csx, ncx), (csx, npad, 1.5)]
hz = [(csz, npad, -1.5), (csz, ncz)]
# Create mesh
mesh = Mesh.TensorMesh([hx, hz], x0="CN")
# Map mesh coordinates from local to UTM coordiantes
#mesh.x0[2] = mesh.x0[2]-mesh.vectorCCz[-npad-1]
mesh.x0[1] = mesh.x0[1] + csz / 2.
#mesh.x0[0] = mesh.x0[0]+csx/2.
#mesh.plotImage(np.ones(mesh.nC)*np.nan, grid=True)
#mesh.plotImage(np.ones(mesh.nC)*np.nan, grid=True)
#plt.gca().set_xlim([-20,20])
#plt.gca().set_ylim([-15,0])
#mesh.plotGrid()
#plt.gca().set_aspect('equal')
#plt.show()

print "Mesh Size: ", mesh.nC

#Model Creation
Ejemplo n.º 9
0
    def setUp(self):

        cs = 0.5
        npad = 11
        hx = [(cs, npad, -1.5), (cs, 15), (cs, npad, 1.5)]
        hy = [(cs, npad, -1.5), (cs, 15), (cs, npad, 1.5)]
        hz = [(cs, npad, -1.5), (cs, 15), (cs, npad, 1.5)]
        mesh = Mesh.TensorMesh([hx, hy, hz], x0="CCC")
        sigma = np.ones(mesh.nC)*1e-2

        # Set up survey parameters for numeric solution
        x = mesh.vectorNx[(mesh.vectorNx > -75.) & (mesh.vectorNx < 75.)]
        y = mesh.vectorNy[(mesh.vectorNy > -75.) & (mesh.vectorNy < 75.)]

        Aloc = np.r_[1.25, 0., 0.]
        Bloc = np.r_[-1.25, 0., 0.]
        M = Utils.ndgrid(x-25., y, np.r_[0.])
        N = Utils.ndgrid(x+25., y, np.r_[0.])

        rx = DC.Rx.Dipole(M, N)
        src = DC.Src.Dipole([rx], Aloc, Bloc)
        survey = DC.Survey([src])

        # Create Dipole Obj for Analytic Solution
        edipole = fdem.ElectricDipoleWholeSpace(
            sigma=1e-2,  # conductivity of 1 S/m
            mu=mu_0,  # permeability of free space (this is the default)
            epsilon=epsilon_0,  # permittivity of free space (this is the default)
            location=np.r_[0., 0., 0.],  # location of the dipole
            orientation='X',  # horizontal dipole (can also be a unit-vector)
            quasistatic=True,  # don't use the quasistatic assumption
            frequency=0.0,  # DC
            length=2.5  # length of dipole
        )

        # evaluate the electric field and current density
        Ex_analytic = np.zeros_like([mesh.nEx,1])
        Ey_analytic = np.zeros_like([mesh.nEy,1])
        Ez_analytic = np.zeros_like([mesh.nEz,1])
        Ex_analytic = np.real(edipole.electric_field(mesh.gridEx))[:,0]
        Ey_analytic = np.real(edipole.electric_field(mesh.gridEy))[:,1]
        Ez_analytic = np.real(edipole.electric_field(mesh.gridEz))[:,2]
        E_analytic = np.hstack([Ex_analytic,Ey_analytic,Ez_analytic])

        Jx_analytic = np.zeros_like([mesh.nEx,1])
        Jy_analytic = np.zeros_like([mesh.nEy,1])
        Jz_analytic = np.zeros_like([mesh.nEz,1])
        Jx_analytic = np.real(edipole.current_density(mesh.gridEx))[:,0]
        Jy_analytic = np.real(edipole.current_density(mesh.gridEy))[:,1]
        Jz_analytic = np.real(edipole.current_density(mesh.gridEz))[:,2]
        J_analytic = np.hstack([Jx_analytic,Jy_analytic,Jz_analytic])

        # Find edges at which to compare solutions
        edgeGrid = np.vstack([mesh.gridEx,mesh.gridEy,mesh.gridEz])
        # print(faceGrid.shape)

        ROI_large_BNW = np.array([-75,75,-75])
        ROI_large_TSE = np.array([75,-75,75])
        ROI_largeInds = Utils.ModelBuilder.getIndicesBlock(ROI_large_BNW,ROI_large_TSE,edgeGrid)[0]
        # print(ROI_largeInds.shape)

        ROI_small_BNW = np.array([-4,4,-4])
        ROI_small_TSE = np.array([4,-4,4])
        ROI_smallInds = Utils.ModelBuilder.getIndicesBlock(ROI_small_BNW,ROI_small_TSE,edgeGrid)[0]
        # print(ROI_smallInds.shape)

        ROIedgeInds = np.setdiff1d(ROI_largeInds,ROI_smallInds)
        # print(ROIedgeInds.shape)
        # print(len(ROI_largeInds) - len(ROI_smallInds))

        self.survey = survey
        self.mesh = mesh
        self.sigma = sigma
        self.E_analytic = E_analytic
        self.J_analytic = J_analytic
        self.ROIedgeInds = ROIedgeInds
Ejemplo n.º 10
0
            else:
                raise ValueError('Invalid component')

        if nSrc == 1:
            return A.flatten()
        return A

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 = 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')
Ejemplo n.º 11
0
    def setUp(self):

        cs = 25.
        hx = [(cs, 0, -1.3), (cs, 21), (cs, 0, 1.3)]
        hy = [(cs, 0, -1.3), (cs, 21), (cs, 0, 1.3)]
        hz = [(cs, 0, -1.3), (cs, 20), (cs, 0, 1.3)]
        mesh = Mesh.TensorMesh([hx, hy, hz], x0="CCC")
        blkind0 = Utils.ModelBuilder.getIndicesSphere(
            np.r_[-100., -100., -200.], 75., mesh.gridCC
        )
        blkind1 = Utils.ModelBuilder.getIndicesSphere(
            np.r_[100., 100., -200.], 75., mesh.gridCC
        )
        sigma = np.ones(mesh.nC)*1e-2
        airind = mesh.gridCC[:, 2] > 0.
        sigma[airind] = 1e-8
        eta = np.zeros(mesh.nC)
        tau = np.ones_like(sigma) * 1.
        eta[blkind0] = 0.1
        eta[blkind1] = 0.1
        tau[blkind0] = 0.1
        tau[blkind1] = 0.01

        actmapeta = Maps.InjectActiveCells(mesh, ~airind, 0.)
        actmaptau = Maps.InjectActiveCells(mesh, ~airind, 1.)

        x = mesh.vectorCCx[(mesh.vectorCCx > -155.) & (mesh.vectorCCx < 155.)]
        y = mesh.vectorCCx[(mesh.vectorCCy > -155.) & (mesh.vectorCCy < 155.)]
        Aloc = np.r_[-200., 0., 0.]
        Bloc = np.r_[200., 0., 0.]
        M = Utils.ndgrid(x-25., y, np.r_[0.])
        N = Utils.ndgrid(x+25., y, np.r_[0.])

        times = np.arange(10)*1e-3 + 1e-3
        rx = SIP.Rx.Dipole(M, N, times)
        src = SIP.Src.Dipole([rx], Aloc, Bloc)
        survey = SIP.Survey([src])

        wires = Maps.Wires(('eta', actmapeta.nP), ('taui', actmaptau.nP))
        problem = SIP.Problem3D_N(
            mesh,
            sigma=sigma,
            etaMap=actmapeta*wires.eta,
            tauiMap=actmapeta*wires.taui
        )

        problem.Solver = Solver
        problem.pair(survey)
        mSynth = np.r_[eta[~airind], 1./tau[~airind]]
        survey.makeSyntheticData(mSynth)
        # Now set up the problem to do some minimization
        dmis = DataMisfit.l2_DataMisfit(survey)
        regmap = Maps.IdentityMap(nP=int(mSynth[~airind].size*2))
        reg = SIP.MultiRegularization(
            mesh,
            mapping=regmap,
            nModels=2,
            indActive=~airind
        )
        opt = Optimization.InexactGaussNewton(
            maxIterLS=20, maxIter=10, tolF=1e-6,
            tolX=1e-6, tolG=1e-6, maxIterCG=6
        )
        invProb = InvProblem.BaseInvProblem(dmis, reg, opt, beta=1e4)
        inv = Inversion.BaseInversion(invProb)

        self.inv = inv
        self.reg = reg
        self.p = problem
        self.mesh = mesh
        self.m0 = mSynth
        self.survey = survey
        self.dmis = dmis
Ejemplo n.º 12
0
    def setUp(self):

        cs = 25.
        hx = [(cs, 0, -1.3), (cs, 21), (cs, 0, 1.3)]
        hy = [(cs, 0, -1.3), (cs, 21), (cs, 0, 1.3)]
        hz = [(cs, 0, -1.3), (cs, 20)]
        mesh = Mesh.TensorMesh([hx, hy, hz], x0="CCN")
        blkind0 = Utils.ModelBuilder.getIndicesSphere(
            np.r_[-100., -100., -200.], 75., mesh.gridCC
        )
        blkind1 = Utils.ModelBuilder.getIndicesSphere(
            np.r_[100., 100., -200.], 75., mesh.gridCC
        )
        sigma = np.ones(mesh.nC) * 1e-2
        eta = np.zeros(mesh.nC)
        tau = np.ones_like(sigma) * 1.
        eta[blkind0] = 0.1
        eta[blkind1] = 0.1
        tau[blkind0] = 0.1
        tau[blkind1] = 0.01

        x = mesh.vectorCCx[(mesh.vectorCCx > -155.) & (mesh.vectorCCx < 155.)]
        y = mesh.vectorCCx[(mesh.vectorCCy > -155.) & (mesh.vectorCCy < 155.)]
        Aloc = np.r_[-200., 0., 0.]
        Bloc = np.r_[200., 0., 0.]
        M = Utils.ndgrid(x-25., y, np.r_[0.])
        N = Utils.ndgrid(x+25., y, np.r_[0.])

        times = np.arange(10)*1e-3 + 1e-3
        rx = SIP.Rx.Dipole(M, N, times)
        src = SIP.Src.Dipole([rx], Aloc, Bloc)
        survey = SIP.Survey([src])
        wires = Maps.Wires(('eta', mesh.nC), ('taui', mesh.nC))
        problem = SIP.Problem3D_CC(
            mesh,
            rho=1./sigma,
            etaMap=wires.eta,
            tauiMap=wires.taui
        )
        problem.Solver = Solver
        problem.pair(survey)
        mSynth = np.r_[eta, 1./tau]
        problem.model = mSynth
        survey.makeSyntheticData(mSynth)
        # Now set up the problem to do some minimization
        dmis = DataMisfit.l2_DataMisfit(survey)
        reg = Regularization.Tikhonov(mesh)
        opt = Optimization.InexactGaussNewton(
            maxIterLS=20, maxIter=10, tolF=1e-6,
            tolX=1e-6, tolG=1e-6, maxIterCG=6
        )
        invProb = InvProblem.BaseInvProblem(dmis, reg, opt, beta=1e4)
        inv = Inversion.BaseInversion(invProb)

        self.inv = inv
        self.reg = reg
        self.p = problem
        self.mesh = mesh
        self.m0 = mSynth
        self.survey = survey
        self.dmis = dmis
Ejemplo n.º 13
0
    def plotSecondarySource(self, primaryFields, saveFig=False):
        # get source term
        secondaryProblem = self.setupSecondaryProblem(mapping=self.mapping)
        secondaryProblem.solver = Solver
        self.primaryProblem.solver = Solver
        secondaryProblem.model = self.mtrue
        secondarySurvey = self.setupSecondarySurvey(
            self.primaryProblem, self.primarySurvey, self.primaryMap2meshs
        )
        src = secondarySurvey.srcList[0]
        s_e = src.s_e(secondaryProblem, f=primaryFields)

        # Mesh to interpolate onto for stream plots
        cs = 5.
        csz = 0.5
        xmin, xmax = -600., 600.
        ymin, ymax = -600., 600.
        zmin, zmax = -950.-csz/2., -950.+csz/2.

        ncx = np.ceil((xmax-xmin)/cs)
        ncy = np.ceil((ymax-ymin)/cs)
        ncz = np.ceil((zmax-zmin)/cs)

        meshs_plt = Mesh.TensorMesh(
            [[(cs, ncx)], [(cs, ncy)], [(cs, ncz)]],
            [xmin+(xmin+xmax)/2., ymin+(ymin+ymax)/2., zmin+(zmin+zmax)/2.]
        )

        # Construct interpolation matrices
        Px = self.meshs.getInterpolationMat(meshs_plt.gridEx, locType='Ex')
        Py = self.meshs.getInterpolationMat(meshs_plt.gridEy, locType='Ey')
        Pz = self.meshs.getInterpolationMat(meshs_plt.gridEz, locType='Ez')
        P = sp.vstack([Px, Py, Pz])

        # for regions outside of the anomalous block, the source current
        # density is identically zero. For plotting, we do not want to
        # interpolate into this region, so we build up masked arrays.
        maskme_ex = (
            (self.meshs.gridEx[:, 0] <= self.block_x[0]) |
            (self.meshs.gridEx[:, 0] >= self.block_x[1]) |
            (self.meshs.gridEx[:, 1] <= self.block_y[0]) |
            (self.meshs.gridEx[:, 1] >= self.block_y[1])
        )

        maskme_ey = (
            (self.meshs.gridEy[:, 0] <= self.block_x[0]) |
            (self.meshs.gridEy[:, 0] >= self.block_x[1]) |
            (self.meshs.gridEy[:, 1] <= self.block_y[0]) |
            (self.meshs.gridEy[:, 1] >= self.block_y[1])
        )

        maskme_ez = (
            (self.meshs.gridEz[:, 0] <= self.block_x[0]) |
            (self.meshs.gridEz[:, 0] >= self.block_x[1]) |
            (self.meshs.gridEz[:, 1] <= self.block_y[0]) |
            (self.meshs.gridEz[:, 1] >= self.block_y[1])
        )

        maskme_e = np.hstack([maskme_ex, maskme_ey, maskme_ez])

        # interpolate down a layer
        s_e_interp = s_e.real.copy()
        s_e_interp[maskme_e] = np.nan
        s_e_plt = P * s_e_interp

        # keep masked array for stream plots
        s_e_stream_cc = (meshs_plt.aveE2CCV * s_e_plt)

        # re-assign zero for amplitude of the real current density
        s_e_abs_cc = s_e_stream_cc.reshape(meshs_plt.nC, 3, order='F')
        s_e_abs_cc = np.sqrt((s_e_abs_cc**2.).sum(axis=1))
        s_e_abs_cc[np.isnan(s_e_abs_cc)] = 0.
        s_e_stream_cc = np.ma.masked_where(
            np.isnan(s_e_stream_cc), s_e_stream_cc
        )

        # plot
        fig, ax = plt.subplots(1, 1, figsize=(7.5, 6))

        # f = meshs_plt.plotSlice(
        #     np.ma.masked_where(maskme_e, s_e_plt.real),
        #     normal='Z',
        #     vType='CCv',
        #     view='abs',
        #     pcolorOpts={'cmap':plt.get_cmap('viridis')}, ax=ax
        # )

        f = ax.pcolormesh(
                meshs_plt.vectorCCx, meshs_plt.vectorCCy,
                (s_e_abs_cc).reshape(meshs_plt.vnC[:2], order='F').T,
                cmap=plt.get_cmap('viridis')
        )

        if saveFig is True:
            ax.streamplot(
                meshs_plt.vectorCCx, meshs_plt.vectorCCy,
                s_e_stream_cc[:meshs_plt.nC].reshape(meshs_plt.vnC[:2]),
                s_e_stream_cc[meshs_plt.nC:meshs_plt.nC*2].reshape(
                    meshs_plt.vnC[:2]),
                density=1.5, color='k', arrowsize=8
            )
        elif saveFig is False:
            ax.streamplot(
                meshs_plt.vectorCCx, meshs_plt.vectorCCy,
                s_e_stream_cc[:meshs_plt.nC].reshape(meshs_plt.vnC[:2]),
                s_e_stream_cc[meshs_plt.nC:meshs_plt.nC*2].reshape(
                    meshs_plt.vnC[:2]
                ),
                color='k', density=1.5
            )

        ax.set_xlabel('x (m)', fontsize=fontsize)
        ax.set_ylabel('y (m)', fontsize=fontsize)

        cb = plt.colorbar(f, label='real current density (A/m$^2$)')
        cb.formatter.set_powerlimits((0, 0))
        cb.update_ticks()

        ax.axis('equal', adjustable='box')
        ax.axis([-600, 600, -600, 600])
        ax.set_title('(a) -950m Depth Slice', fontsize=fontsize)
        # interact(plotMe, ind=[0, meshs_plt.vnC[2]-1])

        if saveFig is True:
            fig.savefig('secondarySource', dpi=300)

        return ax
Ejemplo n.º 14
0
def dc_resistivity(
    log_sigma_background=1.,  # Conductivity of the background, S/m
    log_sigma_block=2,  # Conductivity of the block, S/m
    plot_type='potential'  # "conductivity", "potential", or "current"
):
    from pylab import rcParams
    rcParams['figure.figsize'] = 10, 10

    # Define a unit-cell mesh
    mesh = Mesh.TensorMesh([100, 100])  # setup a mesh on which to solve

    # model parameters
    sigma_background = 10**log_sigma_background
    sigma_block = 10**log_sigma_block

    # add a block to our model
    x_block = np.r_[0.4, 0.6]
    y_block = np.r_[0.4, 0.6]

    # assign them on the mesh
    # create a physical property model
    sigma = sigma_background * np.ones(mesh.nC)

    block_indices = ((mesh.gridCC[:, 0] >= x_block[0]) &  # left boundary
                     (mesh.gridCC[:, 0] <= x_block[1]) &  # right boundary
                     (mesh.gridCC[:, 1] >= y_block[0]) &  # bottom boundary
                     (mesh.gridCC[:, 1] <= y_block[1]))  # top boundary

    # add the block to the physical property model
    sigma[block_indices] = sigma_block

    # Define a source
    a_loc, b_loc = np.r_[0.2, 0.5], np.r_[0.8, 0.5]
    source_locs = [a_loc, b_loc]

    # locate it on the mesh
    source_loc_inds = Utils.closestPoints(mesh, source_locs)
    a_loc_mesh = mesh.gridCC[source_loc_inds[0], :]
    b_loc_mesh = mesh.gridCC[source_loc_inds[1], :]

    if plot_type == 'conductivity':
        plt.colorbar(mesh.plotImage(sigma)[0])
        plt.plot(a_loc_mesh[0], a_loc_mesh[1], 'wv', markersize=8)
        plt.plot(b_loc_mesh[0], b_loc_mesh[1], 'w^', markersize=8)
        plt.title('electrical conductivity, $\sigma$')
        return

    # Assemble and solve the DC resistivity problem
    Div = mesh.faceDiv
    Sigma = mesh.getFaceInnerProduct(sigma, invProp=True, invMat=True)
    Vol = Utils.sdiag(mesh.vol)

    # assemble the system matrix
    A = Vol * Div * Sigma * Div.T * Vol

    # right hand side
    q = np.zeros(mesh.nC)
    q[source_loc_inds] = np.r_[+1, -1]

    # solve the DC resistivity problem
    Ainv = Solver(A)  # create a matrix that behaves like A inverse
    phi = Ainv * q

    if plot_type == 'potential':
        plt.colorbar(mesh.plotImage(phi)[0])
        plt.title('Electric Potential, $\phi$')
        return

    if plot_type == 'current':
        j = Sigma * mesh.faceDiv.T * Utils.sdiag(mesh.vol) * phi
        plt.colorbar(
            mesh.plotImage(j, vType='F', view='vec', streamOpts={'color':
                                                                 'w'})[0])
        plt.title('Current, $j$')
        return
def resolve_1Dinversions(mesh,
                         dobs,
                         src_height,
                         freqs,
                         m0,
                         mref,
                         mapping,
                         std=0.08,
                         floor=1e-14,
                         rxOffset=7.86):
    """
    Perform a single 1D inversion for a RESOLVE sounding for Horizontal
    Coplanar Coil data (both real and imaginary).

    :param discretize.CylMesh mesh: mesh used for the forward simulation
    :param numpy.array dobs: observed data
    :param float src_height: height of the source above the ground
    :param numpy.array freqs: frequencies
    :param numpy.array m0: starting model
    :param numpy.array mref: reference model
    :param Maps.IdentityMap mapping: mapping that maps the model to electrical conductivity
    :param float std: percent error used to construct the data misfit term
    :param float floor: noise floor used to construct the data misfit term
    :param float rxOffset: offset between source and receiver.
    """

    # ------------------- Forward Simulation ------------------- #
    # set up the receivers
    bzr = EM.FDEM.Rx.Point_bSecondary(np.array([[rxOffset, 0., src_height]]),
                                      orientation='z',
                                      component='real')

    bzi = EM.FDEM.Rx.Point_b(np.array([[rxOffset, 0., src_height]]),
                             orientation='z',
                             component='imag')

    # source location
    srcLoc = np.array([0., 0., src_height])
    srcList = [
        EM.FDEM.Src.MagDipole([bzr, bzi], freq, srcLoc, orientation='Z')
        for freq in freqs
    ]

    # construct a forward simulation
    survey = EM.FDEM.Survey(srcList)
    prb = EM.FDEM.Problem3D_b(mesh, sigmaMap=mapping, Solver=PardisoSolver)
    prb.pair(survey)

    # ------------------- Inversion ------------------- #
    # data misfit term
    survey.dobs = dobs
    dmisfit = DataMisfit.l2_DataMisfit(survey)
    uncert = abs(dobs) * std + floor
    dmisfit.W = 1. / uncert

    # regularization
    regMesh = Mesh.TensorMesh([mesh.hz[mapping.maps[-1].indActive]])
    reg = Regularization.Simple(regMesh)
    reg.mref = mref

    # optimization
    opt = Optimization.InexactGaussNewton(maxIter=10)

    # statement of the inverse problem
    invProb = InvProblem.BaseInvProblem(dmisfit, reg, opt)

    # Inversion directives and parameters
    target = Directives.TargetMisfit()
    inv = Inversion.BaseInversion(invProb, directiveList=[target])

    invProb.beta = 2.  # Fix beta in the nonlinear iterations
    reg.alpha_s = 1e-3
    reg.alpha_x = 1.
    prb.counter = opt.counter = Utils.Counter()
    opt.LSshorten = 0.5
    opt.remember('xc')

    # run the inversion
    mopt = inv.run(m0)
    return mopt, invProb.dpred, survey.dobs
Ejemplo n.º 16
0
    padding_widths = cs * padding_fact**(np.arange(npad) + 1)
    return padding_widths.sum()


# keep adding padding until we are beyond the desired extent
padding_z = padding_extent(npad)
while padding_z < domain_extent:
    npad += 1
    padding_z = padding_extent(npad)

print("{:1.0f} padding cells extends {:1.2e}m > {:1.2e}m "
      "(2 skin depths)".format(npad, padding_extent(npad), domain_extent))

ncz = np.ceil(core_extent / cs)  # number of cells in the core domain
hz = [(cs, npad, -1.3), (cs, ncz)]  # define how to construct the cell widths
mesh = Mesh.TensorMesh([hz], x0='N')  # construct a 1D Tensor Mesh

print("There are {:1.0f} cells in the mesh. The mest extends {:1.2e}m".format(
    ncz, mesh.hx.sum()))

# plot the mesh
fig, ax = plt.subplots(1, 1, figsize=(8, 3))
mesh.plotGrid(centers=True, faces=True, ax=ax)
ax.legend(["centers", "faces"])
ax.grid(which="both", linewidth=0.5)
ax.invert_xaxis()  # so that the surface is on our left hand side
ax.set_xlabel('z (m)')

# Set up a model

rho_target = 10.  # resistivity in Ohm-m
Ejemplo n.º 17
0
def gettopoCC(mesh, actind, option="top"):
    """
        Get topography from active indices of mesh.

    """

    if mesh._meshType == "TENSOR":

        if mesh.dim == 3:

            mesh2D = Mesh.TensorMesh([mesh.hx, mesh.hy], mesh.x0[:2])
            zc = mesh.gridCC[:, 2]
            ACTIND = actind.reshape((mesh.vnC[0] * mesh.vnC[1], mesh.vnC[2]),
                                    order='F')
            ZC = zc.reshape((mesh.vnC[0] * mesh.vnC[1], mesh.vnC[2]),
                            order='F')
            topoCC = np.zeros(ZC.shape[0])

            for i in range(ZC.shape[0]):
                ind = np.argmax(ZC[i, :][ACTIND[i, :]])
                if option == "top":
                    dz = mesh.hz[ACTIND[i, :]][ind] * 0.5
                elif option == "center":
                    dz = 0.
                else:
                    raise Exception()
                topoCC[i] = (ZC[i, :][ACTIND[i, :]].max() + dz)
            return mesh2D, topoCC

        elif mesh.dim == 2:

            mesh1D = Mesh.TensorMesh([mesh.hx], [mesh.x0[0]])
            yc = mesh.gridCC[:, 1]
            ACTIND = actind.reshape((mesh.vnC[0], mesh.vnC[1]), order='F')
            YC = yc.reshape((mesh.vnC[0], mesh.vnC[1]), order='F')
            topoCC = np.zeros(YC.shape[0])
            for i in range(YC.shape[0]):
                ind = np.argmax(YC[i, :][ACTIND[i, :]])
                if option == "top":
                    dy = mesh.hy[ACTIND[i, :]][ind] * 0.5
                elif option == "center":
                    dy = 0.
                else:
                    raise Exception()
                topoCC[i] = (YC[i, :][ACTIND[i, :]].max() + dy)
            return mesh1D, topoCC

    elif mesh._meshType == "TREE":
        if mesh.dim == 3:
            uniqXY = uniqueRows(mesh.gridCC[:, :2])
            npts = uniqXY[0].shape[0]
            ZC = mesh.gridCC[:, 2]
            topoCC = np.zeros(npts)
            if option == "top":
                # TODO: this assume same hz, need to be modified
                dz = mesh.hz.min() * 0.5
            elif option == "center":
                dz = 0.
            for i in range(npts):
                inds = uniqXY[2] == i
                actind_z = actind[inds]
                if actind_z.sum() > 0.:
                    topoCC[i] = (ZC[inds][actind_z]).max() + dz
                else:
                    topoCC[i] = (ZC[inds]).max() + dz
            return uniqXY[0], topoCC
        else:
            raise NotImplementedError(
                "gettopoCC is not implemented for Quad tree mesh")
Ejemplo n.º 18
0
def set_mesh_1d(hz):
    return Mesh.TensorMesh([hz], x0=[0])
def run(plotIt=True):

    # 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.]])
    bzi = FDEM.Rx.Point_bSecondary(rxlocs, 'z', 'real')
    bzr = 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)

    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)

    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)
        ax0.semilogx(np.exp(moptFD), mesh.vectorCCz[active], 'bo', ms=6)
        ax0.semilogx(np.exp(moptTD), mesh.vectorCCz[active], 'r*', ms=10)
        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(['True', 'FDEM', 'TDEM'], 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)
        ax1.plot(freqs, -surveyFD.dobs[1::2], 'k--', lw=2)

        dpredFD = surveyFD.dpred(moptTD)
        ax1.loglog(freqs, -dpredFD[::2], 'bo', ms=6)
        ax1.loglog(freqs, -dpredFD[1::2], 'b+', markeredgewidth=2., ms=10)

        ax2.loglog(times, surveyTD.dobs, 'k-', lw=2)
        ax2.loglog(times, surveyTD.dpred(moptTD), 'r*', ms=10)
        ax2.set_xlim(times.min(), times.max())

        # 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(("Obs", "Pred"), fontsize=fs)
        ax1.legend(("Obs (real)", "Obs (imag)", "Pred (real)", "Pred (imag)"),
                   fontsize=fs)
        ax1.set_xlim(freqs.max(), freqs.min())

        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)
Ejemplo n.º 20
0
    def setUp(self):

        np.random.seed(0)

        # Define the inducing field parameter
        H0 = (50000, 90, 0)

        # Create a mesh
        dx = 5.

        hxind = [(dx, 5, -1.3), (dx, 5), (dx, 5, 1.3)]
        hyind = [(dx, 5, -1.3), (dx, 5), (dx, 5, 1.3)]
        hzind = [(dx, 5, -1.3), (dx, 6)]

        mesh = Mesh.TensorMesh([hxind, hyind, hzind], 'CCC')

        # Get index of the center
        midx = int(mesh.nCx / 2)
        midy = int(mesh.nCy / 2)

        # Lets create a simple Gaussian topo and set the active cells
        [xx, yy] = np.meshgrid(mesh.vectorNx, mesh.vectorNy)
        zz = -np.exp((xx**2 + yy**2) / 75**2) + mesh.vectorNz[-1]

        # Go from topo to actv cells
        topo = np.c_[Utils.mkvc(xx), Utils.mkvc(yy), Utils.mkvc(zz)]
        actv = Utils.surface2ind_topo(mesh, topo, 'N')
        actv = np.asarray([inds for inds, elem in enumerate(actv, 1) if elem],
                          dtype=int) - 1

        # Create active map to go from reduce space to full
        actvMap = Maps.InjectActiveCells(mesh, actv, -100)
        nC = len(actv)

        # Create and array of observation points
        xr = np.linspace(-20., 20., 20)
        yr = np.linspace(-20., 20., 20)
        X, Y = np.meshgrid(xr, yr)

        # Move the observation points 5m above the topo
        Z = -np.exp((X**2 + Y**2) / 75**2) + mesh.vectorNz[-1] + 5.

        # Create a MAGsurvey
        rxLoc = np.c_[Utils.mkvc(X.T), Utils.mkvc(Y.T), Utils.mkvc(Z.T)]
        rxLoc = PF.BaseMag.RxObs(rxLoc)
        srcField = PF.BaseMag.SrcField([rxLoc], param=H0)
        survey = PF.BaseMag.LinearSurvey(srcField)

        # We can now create a susceptibility model and generate data
        # Here a simple block in half-space
        model = np.zeros((mesh.nCx, mesh.nCy, mesh.nCz))
        model[(midx - 2):(midx + 2), (midy - 2):(midy + 2), -6:-2] = 0.02
        model = Utils.mkvc(model)
        self.model = model[actv]

        # Create active map to go from reduce set to full
        actvMap = Maps.InjectActiveCells(mesh, actv, -100)

        # Creat reduced identity map
        idenMap = Maps.IdentityMap(nP=nC)

        # Create the forward model operator
        prob = PF.Magnetics.MagneticIntegral(mesh, chiMap=idenMap, actInd=actv)

        # Pair the survey and problem
        survey.pair(prob)

        # Compute linear forward operator and compute some data
        d = prob.fields(self.model)

        # Add noise and uncertainties (1nT)
        data = d + np.random.randn(len(d))
        wd = np.ones(len(data)) * 1.

        survey.dobs = data
        survey.std = wd

        # Create sensitivity weights from our linear forward operator
        wr = np.sum(prob.G**2., axis=0)**0.5
        wr = (wr / np.max(wr))

        # Create a regularization
        reg = Regularization.Sparse(mesh, indActive=actv, mapping=idenMap)
        reg.cell_weights = wr
        reg.norms = [0, 1, 1, 1]
        reg.eps_p, reg.eps_q = 1e-3, 1e-3

        # Data misfit function
        dmis = DataMisfit.l2_DataMisfit(survey)
        dmis.W = 1 / wd

        # Add directives to the inversion
        opt = Optimization.ProjectedGNCG(maxIter=100,
                                         lower=0.,
                                         upper=1.,
                                         maxIterLS=20,
                                         maxIterCG=10,
                                         tolCG=1e-3)

        invProb = InvProblem.BaseInvProblem(dmis, reg, opt)
        betaest = Directives.BetaEstimate_ByEig()

        # Here is where the norms are applied
        IRLS = Directives.Update_IRLS(f_min_change=1e-3, minGNiter=3)
        update_Jacobi = Directives.UpdatePreconditioner()
        self.inv = Inversion.BaseInversion(
            invProb, directiveList=[IRLS, betaest, update_Jacobi])
from SimPEG.EM.Static import DC
import numpy as np
import matplotlib.pyplot as plt

###############################################################################
# Step 1
# ------
#
# Generate mesh

cs = 25.
npad = 11
hx = [(cs, npad, -1.3), (cs, 41), (cs, npad, 1.3)]
hy = [(cs, npad, -1.3), (cs, 17), (cs, npad, 1.3)]
hz = [(cs, npad, -1.3), (cs, 20)]
mesh = Mesh.TensorMesh([hx, hy, hz], 'CCN')

###############################################################################
# Step 2
# ------
#
# Generating model and mapping (1D to 3D)

mapping = Maps.ExpMap(mesh) * Maps.SurjectVertical1D(mesh)
siglay1 = 1. / (100.)
siglay2 = 1. / (500.)
sighalf = 1. / (100.)
sigma = np.ones(mesh.nCz) * siglay1
sigma[mesh.vectorCCz <= -100.] = siglay2
sigma[mesh.vectorCCz < -150.] = sighalf
mtrue = np.log(sigma)
Ejemplo n.º 22
0
def run(plotIt=True):
    """
        EM: TDEM: 1D: Inversion
        =======================

        Here we will create and run a TDEM 1D inversion.

    """

    cs, ncx, ncz, npad = 5., 25, 15, 15
    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')

    active = mesh.vectorCCz < 0.
    layer = (mesh.vectorCCz < 0.) & (mesh.vectorCCz >= -100.)
    actMap = Maps.InjectActiveCells(mesh, active, np.log(1e-8), nC=mesh.nCz)
    mapping = Maps.ExpMap(mesh) * Maps.SurjectVertical1D(mesh) * actMap
    sig_half = 2e-3
    sig_air = 1e-8
    sig_layer = 1e-3
    sigma = np.ones(mesh.nCz) * sig_air
    sigma[active] = sig_half
    sigma[layer] = sig_layer
    mtrue = np.log(sigma[active])

    if plotIt is True:
        import matplotlib.pyplot as plt
        fig, ax = plt.subplots(1, 1, figsize=(3, 6))
        plt.semilogx(sigma[active], mesh.vectorCCz[active])
        ax.set_ylim(-600, 0)
        ax.set_xlim(1e-4, 1e-2)
        ax.set_xlabel('Conductivity (S/m)', fontsize=14)
        ax.set_ylabel('Depth (m)', fontsize=14)
        ax.grid(color='k', alpha=0.5, linestyle='dashed', linewidth=0.5)

    rxOffset = 1e-3
    rx = EM.TDEM.RxTDEM(np.array([[rxOffset, 0., 30]]),
                        np.logspace(-5, -3, 31), 'bz')
    src = EM.TDEM.SrcTDEM_VMD_MVP([rx], np.array([0., 0., 80]))
    survey = EM.TDEM.SurveyTDEM([src])
    prb = EM.TDEM.ProblemTDEM_b(mesh, mapping=mapping)

    prb.Solver = SolverLU
    prb.timeSteps = [(1e-06, 20), (1e-05, 20), (0.0001, 20)]
    prb.pair(survey)

    # create observed data
    std = 0.05

    survey.dobs = survey.makeSyntheticData(mtrue, std)
    survey.std = std
    survey.eps = 1e-5 * np.linalg.norm(survey.dobs)

    if plotIt:
        import matplotlib.pyplot as plt
        fig, ax = plt.subplots(1, 1, figsize=(10, 6))
        ax.loglog(rx.times, survey.dtrue, 'b.-')
        ax.loglog(rx.times, survey.dobs, 'r.-')
        ax.legend(('Noisefree', '$d^{obs}$'), fontsize=16)
        ax.set_xlabel('Time (s)', fontsize=14)
        ax.set_ylabel('$B_z$ (T)', fontsize=16)
        ax.set_xlabel('Time (s)', fontsize=14)
        ax.grid(color='k', alpha=0.5, linestyle='dashed', linewidth=0.5)

    dmisfit = DataMisfit.l2_DataMisfit(survey)
    regMesh = Mesh.TensorMesh([mesh.hz[mapping.maps[-1].indActive]])
    reg = Regularization.Tikhonov(regMesh)
    opt = Optimization.InexactGaussNewton(maxIter=5)
    invProb = InvProblem.BaseInvProblem(dmisfit, reg, opt)

    # Create an inversion object
    beta = Directives.BetaSchedule(coolingFactor=5, coolingRate=2)
    betaest = Directives.BetaEstimate_ByEig(beta0_ratio=1e0)
    inv = Inversion.BaseInversion(invProb, directiveList=[beta, betaest])
    m0 = np.log(np.ones(mtrue.size) * sig_half)
    reg.alpha_s = 1e-2
    reg.alpha_x = 1.
    prb.counter = opt.counter = Utils.Counter()
    opt.LSshorten = 0.5
    opt.remember('xc')

    mopt = inv.run(m0)

    if plotIt:
        import matplotlib.pyplot as plt
        fig, ax = plt.subplots(1, 1, figsize=(3, 6))
        plt.semilogx(sigma[active], mesh.vectorCCz[active])
        plt.semilogx(np.exp(mopt), mesh.vectorCCz[active])
        ax.set_ylim(-600, 0)
        ax.set_xlim(1e-4, 1e-2)
        ax.set_xlabel('Conductivity (S/m)', fontsize=14)
        ax.set_ylabel('Depth (m)', fontsize=14)
        ax.grid(color='k', alpha=0.5, linestyle='dashed', linewidth=0.5)
        plt.legend(['$\sigma_{true}$', '$\sigma_{pred}$'])
        plt.show()
Ejemplo n.º 23
0
 def get_mesh(self):
     mesh = Mesh.TensorMesh([np.ones(20)])
     mesh.setCellGradBC('dirichlet')
     return mesh
Ejemplo n.º 24
0
    @property
    def Pafz(self):
        """
        diagonal matrix that nulls out inactive z-faces
        to full modelling space (ie. nFz x nindActive_Fz )

        :rtype: scipy.sparse.csr_matrix
        :return: active face-z diagonal matrix
        """
        if getattr(self, "_Pafz", None) is None:
            if self.indActive is None:
                self._Pafz = Utils.speye(self.mesh.nFz)
            else:
                indActive_Fz = (self.mesh.aveFz2CC.T * self.indActive) >= 1
                e = np.zeros(self.mesh.nFz)
                e[indActive_Fz] = 1.0
                self._Pafz = Utils.sdiag(e)
        return self._Pafz


if __name__ == "__main__":
    from SimPEG import Mesh, np

    mesh = Mesh.TensorMesh([10, 10])
    L = np.ones(mesh.nC)
    src = StreamingCurrents([], L=L, mesh=mesh)
    thing = src.MfLiI
    if thing is not None:
        pass
Ejemplo n.º 25
0
 def get_mesh(self):
     mesh = Mesh.TensorMesh([np.ones(8), np.ones(20), np.ones(10)])
     mesh.setCellGradBC(['neumann', 'neumann', 'dirichlet'])
     return mesh
Ejemplo n.º 26
0
    def set_mesh(self, topo=None,
                dx=None, dy=None, dz=None,
                n_spacing=None, corezlength=None,
                npad_x=7, npad_y=7, npad_z=7,
                pad_rate_x=1.3, pad_rate_y=1.3, pad_rate_z=1.3,
                ncell_per_dipole=4, mesh_type='TensorMesh',
                dimension=2,
                method='nearest'
                ):
        """
        Set up a mesh for a given DC survey
        """
        if mesh_type == 'TreeMesh':
            raise NotImplementedError()

        # 2D or 3D mesh
        if dimension in [2, 3]:
            if dimension == 2:
                z_ind = 1
            else:
                z_ind = 2
            a = abs(np.diff(np.sort(self.electrode_locations[:, 0]))).min()
            lineLength = abs(
                self.electrode_locations[:, 0].max() -
                self.electrode_locations[:, 0].min()
            )
            dx_ideal = a/ncell_per_dipole
            if dx is None:
                dx = dx_ideal
                warnings.warn(
                    "dx is set to {} m (samllest electrode spacing ({}) / {})".format(dx, a, ncell_per_dipole)
                )
            if dz is None:
                dz = dx*0.5
                warnings.warn(
                    "dz ({} m) is set to dx ({} m) / {}".format(dz, dx, 2)
                )
            x0 = self.electrode_locations[:, 0].min()
            if topo is None:
                locs = self.electrode_locations
            else:
                locs = np.vstack((topo, self.electrode_locations))

            if dx > dx_ideal:
                # warnings.warn(
                #     "Input dx ({}) is greater than expected \n We recommend using {:0.1e} m cells, that is, {} cells per {0.1e} m dipole length".format(dx, dx_ideal, ncell_per_dipole, a)
                # )
                pass
            self.dx = dx
            self.dz = dz
            self.npad_x = npad_x
            self.npad_z = npad_z
            self.pad_rate_x = pad_rate_x
            self.pad_rate_z = pad_rate_z
            self.ncell_per_dipole = ncell_per_dipole
            zmax = locs[:, z_ind].max()
            zmin = locs[:, z_ind].min()

            # 3 cells each for buffer
            corexlength = lineLength + dx * 6
            if corezlength is None:
                corezlength = self.grids[:, z_ind].max()

            ncx = np.round(corexlength/dx)
            ncz = np.round(corezlength/dz)
            hx = [
                (dx, npad_x, -pad_rate_x), (dx, ncx), (dx, npad_x, pad_rate_x)
            ]
            hz = [(dz, npad_z, -pad_rate_z), (dz, ncz)]
            x0_mesh = -(
                (dx * pad_rate_x ** (np.arange(npad_x)+1)).sum() + dx * 3 - x0
            )
            z0_mesh = -((dz * pad_rate_z ** (np.arange(npad_z)+1)).sum() + dz * ncz) + zmax

            # For 2D mesh
            if dimension == 2:
                h = [hx, hz]
                x0_for_mesh = [x0_mesh, z0_mesh]
                self.xyzlim = np.vstack((
                    np.r_[x0, x0+lineLength],
                    np.r_[zmax-corezlength, zmax]
                ))

            # For 3D mesh
            else:
                if dy is None:
                    raise Exception("You must input dy (m)")

                self.dy = dy
                self.npad_y = npad_y
                self.pad_rate_y = pad_rate_y

                ylocs = np.unique(self.electrode_locations[:, 1])
                ymin, ymax = ylocs.min(), ylocs.max()
                # 3 cells each for buffer in y-direction
                coreylength = ymax-ymin+dy*6
                ncy = np.round(coreylength/dy)
                hy = [
                    (dy, npad_y, -pad_rate_y),
                    (dy, ncy),
                    (dy, npad_y, pad_rate_y)
                ]
                y0 = ylocs.min()-dy/2.
                y0_mesh = -(
                    (dy * pad_rate_y ** (np.arange(npad_y)+1)).sum()
                    + dy*3 - y0
                )

                h = [hx, hy, hz]
                x0_for_mesh = [x0_mesh, y0_mesh, z0_mesh]
                self.xyzlim = np.vstack((
                    np.r_[x0, x0+lineLength],
                    np.r_[ymin-dy*3, ymax+dy*3],
                    np.r_[zmax-corezlength, zmax]
                ))
            mesh = Mesh.TensorMesh(h, x0=x0_for_mesh)
            actind = Utils.surface2ind_topo(mesh, locs, method=method)
        else:
            raise NotImplementedError()

        return mesh, actind
Ejemplo n.º 27
0
    def setUp(self):

        ndv = -100
        # Create a self.mesh
        dx = 5.

        hxind = [(dx, 5, -1.3), (dx, 5), (dx, 5, 1.3)]
        hyind = [(dx, 5, -1.3), (dx, 5), (dx, 5, 1.3)]
        hzind = [(dx, 5, -1.3), (dx, 6)]

        self.mesh = Mesh.TensorMesh([hxind, hyind, hzind], 'CCC')

        # Get index of the center
        midx = int(self.mesh.nCx / 2)
        midy = int(self.mesh.nCy / 2)

        # Lets create a simple Gaussian topo and set the active cells
        [xx, yy] = np.meshgrid(self.mesh.vectorNx, self.mesh.vectorNy)
        zz = -np.exp((xx**2 + yy**2) / 75**2) + self.mesh.vectorNz[-1]

        # Go from topo to actv cells
        topo = np.c_[Utils.mkvc(xx), Utils.mkvc(yy), Utils.mkvc(zz)]
        actv = Utils.surface2ind_topo(self.mesh, topo, 'N')
        actv = np.where(actv)[0]

        # Create active map to go from reduce space to full
        self.actvMap = Maps.InjectActiveCells(self.mesh, actv, -100)
        nC = len(actv)

        # Create and array of observation points
        xr = np.linspace(-20., 20., 20)
        yr = np.linspace(-20., 20., 20)
        X, Y = np.meshgrid(xr, yr)

        # Move the observation points 5m above the topo
        Z = -np.exp((X**2 + Y**2) / 75**2) + self.mesh.vectorNz[-1] + 5.

        # Create a MAGsurvey
        locXYZ = np.c_[Utils.mkvc(X.T), Utils.mkvc(Y.T), Utils.mkvc(Z.T)]
        rxLoc = PF.BaseGrav.RxObs(locXYZ)
        srcField = PF.BaseGrav.SrcField([rxLoc])
        survey = PF.BaseGrav.LinearSurvey(srcField)

        # We can now create a density model and generate data
        # Here a simple block in half-space
        model = np.zeros((self.mesh.nCx, self.mesh.nCy, self.mesh.nCz))
        model[(midx - 2):(midx + 2), (midy - 2):(midy + 2), -6:-2] = 0.5
        model = Utils.mkvc(model)
        self.model = model[actv]

        # Create active map to go from reduce set to full
        actvMap = Maps.InjectActiveCells(self.mesh, actv, ndv)

        # Create reduced identity map
        idenMap = Maps.IdentityMap(nP=nC)

        # Create the forward model operator
        prob = PF.Gravity.GravityIntegral(self.mesh,
                                          rhoMap=idenMap,
                                          actInd=actv)

        # Pair the survey and problem
        survey.pair(prob)

        # Compute linear forward operator and compute some data
        d = prob.fields(self.model)

        # Add noise and uncertainties (1nT)
        data = d + np.random.randn(len(d)) * 0.001
        wd = np.ones(len(data)) * .001

        survey.dobs = data
        survey.std = wd

        # PF.Gravity.plot_obs_2D(survey.srcField.rxList[0].locs, d=data)

        # Create sensitivity weights from our linear forward operator
        wr = PF.Magnetics.get_dist_wgt(self.mesh, locXYZ, actv, 2., 2.)
        wr = wr**2.

        # Create a regularization
        reg = Regularization.Sparse(self.mesh, indActive=actv, mapping=idenMap)
        reg.cell_weights = wr
        reg.norms = np.c_[0, 0, 0, 0]
        reg.gradientType = 'component'
        # reg.eps_p, reg.eps_q = 5e-2, 1e-2

        # Data misfit function
        dmis = DataMisfit.l2_DataMisfit(survey)
        dmis.W = 1 / wd

        # Add directives to the inversion
        opt = Optimization.ProjectedGNCG(maxIter=100,
                                         lower=-1.,
                                         upper=1.,
                                         maxIterLS=20,
                                         maxIterCG=10,
                                         tolCG=1e-3)
        invProb = InvProblem.BaseInvProblem(dmis, reg, opt, beta=1e+8)

        # Here is where the norms are applied
        IRLS = Directives.Update_IRLS(f_min_change=1e-4, minGNiter=1)
        update_Jacobi = Directives.UpdatePreconditioner()

        self.inv = Inversion.BaseInversion(invProb,
                                           directiveList=[IRLS, update_Jacobi])
Ejemplo n.º 28
0
xlim = 150

# First we need to create a mesh and a model.
# This is our mesh
dx = 2.
nC = 30
npad = 12

# Floor uncertainties for e3D inversion
floor = 100

hxind = [(dx,npad,-1.3),(dx, 2*nC),(dx,npad,1.3)]
hyind = [(dx, 2*nC)]
hzind = [(dx, 3*nC)]

mesh = Mesh.TensorMesh([hxind, hyind, hzind], 'CC0')
mesh._x0[2] = -np.sum(mesh.hz[:(2*nC)])

# Set background conductivity
model = np.ones(mesh.nC) * sig[0]

# Sphere anomaly
ind = Utils.ModelBuilder.getIndicesSphere(loc, radi, mesh.gridCC)
model[ind] = sig[1]

# Create quick topo
xtopo, ytopo = np.meshgrid(mesh.vectorNx,mesh.vectorNy)
ztopo = np.zeros_like(xtopo)

topo = np.c_[mkvc(xtopo),mkvc(ytopo),mkvc(ztopo)]
Ejemplo n.º 29
0
from matplotlib.path import Path
import matplotlib.patches as patches
from scipy.constants import epsilon_0
import copy

from ipywidgets import interact, IntSlider, FloatSlider, FloatText, ToggleButtons

from .Base import widgetify

# Mesh, sigmaMap can be globals global
npad = 15
growrate = 2.
cs = 0.5
hx = [(cs, npad, -growrate), (cs, 200), (cs, npad, growrate)]
hy = [(cs, npad, -growrate), (cs, 100)]
mesh = Mesh.TensorMesh([hx, hy], "CN")
idmap = Maps.IdentityMap(mesh)
sigmaMap = idmap
dx = 5
xr = np.arange(-40, 41, dx)
dxr = np.diff(xr)
xmin = -40.
xmax = 40.
ymin = -40.
ymax = 5.
xylim = np.c_[[xmin, ymin], [xmax, ymax]]
indCC, meshcore = ExtractCoreMesh(xylim, mesh)
indx = (mesh.gridFx[:,0]>=xmin) & (mesh.gridFx[:,0]<=xmax) \
    & (mesh.gridFx[:,1]>=ymin) & (mesh.gridFx[:,1]<=ymax)
indy = (mesh.gridFy[:,0]>=xmin) & (mesh.gridFy[:,0]<=xmax) \
    & (mesh.gridFy[:,1]>=ymin) & (mesh.gridFy[:,1]<=ymax)
Ejemplo n.º 30
0
    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 = 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 run(runIt=False, plotIt=True, saveIt=False, saveFig=False, cleanup=True):
    """
    Run the bookpurnong 1D stitched RESOLVE inversions.

    :param bool runIt: re-run the inversions? Default downloads and plots saved results
    :param bool plotIt: show the plots?
    :param bool saveIt: save the re-inverted results?
    :param bool saveFig: save the figure
    :param bool cleanup: remove the downloaded results
    """

    # download the data
    downloads, directory = download_and_unzip_data()

    # Load resolve data
    resolve = h5py.File(os.path.sep.join([directory, "booky_resolve.hdf5"]),
                        "r")

    river_path = resolve["river_path"].value  # River path
    nSounding = resolve["data"].shape[0]  # the # of soundings

    # Bird height from surface
    b_height_resolve = resolve["src_elevation"].value

    # fetch the frequencies we are considering
    cpi_inds = [0, 2, 6, 8, 10]  # Indices for HCP in-phase
    cpq_inds = [1, 3, 7, 9, 11]  # Indices for HCP quadrature
    frequency_cp = resolve["frequency_cp"].value

    # build a mesh
    cs, ncx, ncz, npad = 1., 10., 10., 20
    hx = [(cs, ncx), (cs, npad, 1.3)]
    npad = 12
    temp = np.logspace(np.log10(1.), np.log10(12.), 19)
    temp_pad = temp[-1] * 1.3**np.arange(npad)
    hz = np.r_[temp_pad[::-1], temp[::-1], temp, temp_pad]
    mesh = Mesh.CylMesh([hx, 1, hz], '00C')
    active = mesh.vectorCCz < 0.

    # survey parameters
    rxOffset = 7.86  # tx-rx separation
    bp = -mu_0 / (4 * np.pi * rxOffset**3)  # primary magnetic field

    # re-run the inversion
    if runIt:

        # set up the mappings - we are inverting for 1D log conductivity
        # below the earth's surface.
        actMap = Maps.InjectActiveCells(mesh,
                                        active,
                                        np.log(1e-8),
                                        nC=mesh.nCz)
        mapping = Maps.ExpMap(mesh) * Maps.SurjectVertical1D(mesh) * actMap

        # build starting and reference model
        sig_half = 1e-1
        sig_air = 1e-8
        sigma = np.ones(mesh.nCz) * sig_air
        sigma[active] = sig_half
        m0 = np.log(1e-1) * np.ones(active.sum())  # starting model
        mref = np.log(1e-1) * np.ones(active.sum())  # reference model

        # initalize empty lists for storing inversion results
        mopt_re = []  # recovered model
        dpred_re = []  # predicted data
        dobs_re = []  # observed data

        # downsample the data for the inversion
        nskip = 40

        # set up a noise model
        # 10% for the 3 lowest frequencies, 15% for the two highest
        std = np.repeat(np.r_[np.ones(3) * 0.1, np.ones(2) * 0.15], 2)
        floor = abs(20 * bp * 1e-6)  # floor of 20ppm

        # loop over the soundings and invert each
        for rxind in range(nSounding):

            # convert data from ppm to magnetic field (A/m^2)
            dobs = np.c_[resolve["data"][rxind, :][cpi_inds].astype(float),
                         resolve["data"][rxind, :][cpq_inds].
                         astype(float)].flatten() * bp * 1e-6

            # perform the inversion
            src_height = b_height_resolve[rxind].astype(float)
            mopt, dpred, dobs = resolve_1Dinversions(mesh,
                                                     dobs,
                                                     src_height,
                                                     frequency_cp,
                                                     m0,
                                                     mref,
                                                     mapping,
                                                     std=std,
                                                     floor=floor)

            # add results to our list
            mopt_re.append(mopt)
            dpred_re.append(dpred)
            dobs_re.append(dobs)

        # save results
        mopt_re = np.vstack(mopt_re)
        dpred_re = np.vstack(dpred_re)
        dobs_re = np.vstack(dobs_re)

        if saveIt:
            np.save("mopt_re_final", mopt_re)
            np.save("dobs_re_final", dobs_re)
            np.save("dpred_re_final", dpred_re)

    mopt_re = resolve["mopt"].value
    dobs_re = resolve["dobs"].value
    dpred_re = resolve["dpred"].value

    sigma = np.exp(mopt_re)
    indz = -7  # depth index

    # so that we can visually compare with literature (eg Viezzoli, 2010)
    cmap = "jet"

    # dummy figure for colobar
    fig = plt.figure()
    out = plt.scatter(np.ones(3),
                      np.ones(3),
                      c=np.linspace(-2, 1, 3),
                      cmap=cmap)
    plt.close(fig)

    # plot from the paper
    fs = 13  # fontsize
    # matplotlib.rcParams['font.size'] = fs
    plt.figure(figsize=(13, 7))
    ax0 = plt.subplot2grid((2, 3), (0, 0), rowspan=2, colspan=2)
    ax1 = plt.subplot2grid((2, 3), (0, 2))
    ax2 = plt.subplot2grid((2, 3), (1, 2))

    # titles of plots
    title = [("(a) Recovered model, %.1f m depth") %
             (-mesh.vectorCCz[active][indz]), "(b) Obs (Real 400 Hz)",
             "(c) Pred (Real 400 Hz)"]

    temp = sigma[:, indz]
    tree = cKDTree(list(zip(resolve["xy"][:, 0], resolve["xy"][:, 1])))
    d, d_inds = tree.query(list(zip(resolve["xy"][:, 0], resolve["xy"][:, 1])),
                           k=20)
    w = 1. / (d + 100.)**2.
    w = Utils.sdiag(1. / np.sum(w, axis=1)) * (w)
    xy = resolve["xy"]
    temp = (temp.flatten()[d_inds] * w).sum(axis=1)
    Utils.plot2Ddata(xy,
                     temp,
                     ncontour=100,
                     scale="log",
                     dataloc=False,
                     contourOpts={
                         "cmap": cmap,
                         "vmin": -2,
                         "vmax": 1.
                     },
                     ax=ax0)
    ax0.plot(resolve["xy"][:, 0], resolve["xy"][:, 1], 'k.', alpha=0.02, ms=1)

    cb = plt.colorbar(out,
                      ax=ax0,
                      ticks=np.linspace(-2, 1, 4),
                      format="$10^{%.1f}$")
    cb.set_ticklabels(["0.01", "0.1", "1", "10"])
    cb.set_label("Conductivity (S/m)")
    ax0.plot(river_path[:, 0], river_path[:, 1], 'k-', lw=0.5)

    # plot observed and predicted data
    freq_ind = 0
    axs = [ax1, ax2]
    temp_dobs = dobs_re[:, freq_ind].copy()
    ax1.plot(river_path[:, 0], river_path[:, 1], 'k-', lw=0.5)
    out = Utils.plot2Ddata(resolve["xy"].value,
                           temp_dobs / abs(bp) * 1e6,
                           ncontour=100,
                           scale="log",
                           dataloc=False,
                           ax=ax1,
                           contourOpts={"cmap": "viridis"})
    vmin, vmax = out[0].get_clim()
    cb = plt.colorbar(out[0],
                      ticks=np.linspace(vmin, vmax, 3),
                      ax=ax1,
                      format="%.1e",
                      fraction=0.046,
                      pad=0.04)
    cb.set_label("Bz (ppm)")
    temp_dpred = dpred_re[:, freq_ind].copy()
    # temp_dpred[mask_:_data] = np.nan
    ax2.plot(river_path[:, 0], river_path[:, 1], 'k-', lw=0.5)
    Utils.plot2Ddata(resolve["xy"].value,
                     temp_dpred / abs(bp) * 1e6,
                     ncontour=100,
                     scale="log",
                     dataloc=False,
                     contourOpts={
                         "vmin": vmin,
                         "vmax": vmax,
                         "cmap": "viridis"
                     },
                     ax=ax2)
    cb = plt.colorbar(out[0],
                      ticks=np.linspace(vmin, vmax, 3),
                      ax=ax2,
                      format="%.1e",
                      fraction=0.046,
                      pad=0.04)
    cb.set_label("Bz (ppm)")

    for i, ax in enumerate([ax0, ax1, ax2]):
        xticks = [460000, 463000]
        yticks = [6195000, 6198000, 6201000]
        xloc, yloc = 462100.0, 6196500.0
        ax.set_xticks(xticks)
        ax.set_yticks(yticks)
        # ax.plot(xloc, yloc, 'wo')
        ax.plot(river_path[:, 0], river_path[:, 1], 'k', lw=0.5)

        ax.set_aspect("equal")
        ax.plot(resolve["xy"][:, 0],
                resolve["xy"][:, 1],
                'k.',
                alpha=0.02,
                ms=1)

        ax.set_yticklabels([str(f) for f in yticks])
        ax.set_ylabel("Northing (m)")
        ax.set_xlabel("Easting (m)")
        ax.set_title(title[i])

    plt.tight_layout()

    if plotIt:
        plt.show()

    if saveFig is True:
        fig.savefig("obspred_resolve.png", dpi=200)

    if cleanup:
        os.remove(downloads)
        shutil.rmtree(directory)