Пример #1
0
    def test_nC_residual(self):

        # x-direction
        cs, ncx, ncz, npad = 1.0, 10.0, 10.0, 20
        hx = [(cs, ncx), (cs, npad, 1.3)]

        # z direction
        npad = 12
        temp = np.logspace(np.log10(1.0), np.log10(12.0), 19)
        temp_pad = temp[-1] * 1.3**np.arange(npad)
        hz = np.r_[temp_pad[::-1], temp[::-1], temp, temp_pad]
        mesh = discretize.CylMesh([hx, 1, hz], "00C")
        active = mesh.vectorCCz < 0.0

        active = mesh.vectorCCz < 0.0
        actMap = maps.InjectActiveCells(mesh,
                                        active,
                                        np.log(1e-8),
                                        nC=mesh.nCz)
        mapping = maps.ExpMap(mesh) * maps.SurjectVertical1D(mesh) * actMap

        regMesh = discretize.TensorMesh([mesh.hz[mapping.maps[-1].indActive]])
        reg = regularization.Simple(regMesh)

        self.assertTrue(reg._nC_residual == regMesh.nC)
        self.assertTrue(
            all([fct._nC_residual == regMesh.nC for fct in reg.objfcts]))
Пример #2
0
    def plot(self, ax=None):
        if ax is None:
            fig, ax = plt.subplots(1, 2, figsize=(12, 4))

        # generate a 2D mesh for plotting slices
        mesh2D = discretize.CylMesh(
            [self.mesh.hx, 1., self.mesh.hz], x0=self.mesh.x0
        )

        # plot Sigma
        sigmaplt = self.sigma.reshape(self.mesh.vnC, order='F')
        ax[0].set_title('$\sigma$')
        plt.colorbar(
            mesh2D.plotImage(
                discretize.utils.mkvc(sigmaplt[:, 0, :]), ax=ax[0],
                mirror=True, pcolorOpts={'norm': LogNorm()}
            )[0], ax=ax[0],

        )

        # Plot mu
        murplt = self.mur.reshape(self.mesh.vnC, order='F')
        ax[1].set_title('$\mu_r$')
        plt.colorbar(mesh2D.plotImage(
            discretize.utils.mkvc(murplt[:, 0, :]), ax=ax[1], mirror=True)[0],
            ax=ax[1]
        )

        plt.tight_layout()
        return ax
Пример #3
0
    def test_getInterpMatCartMesh_Faces(self):

        Mr = discretize.TensorMesh([100, 100, 2], x0="CC0")
        Mc = discretize.CylMesh(
            [np.ones(10) / 5, 1, 10], x0="0C0", cartesianOrigin=[-0.2, -0.2, 0]
        )

        Pf = Mc.getInterpolationMatCartMesh(Mr, "F")
        mf = np.ones(Mc.nF)

        frect = Pf * mf

        fxcc = Mr.aveFx2CC * Mr.r(frect, "F", "Fx")
        fycc = Mr.aveFy2CC * Mr.r(frect, "F", "Fy")
        fzcc = Mr.r(frect, "F", "Fz")

        indX = utils.closestPoints(Mr, [0.45, -0.2, 0.5])
        indY = utils.closestPoints(Mr, [-0.2, 0.45, 0.5])

        TOL = 1e-2
        assert np.abs(float(fxcc[indX]) - 1) < TOL
        assert np.abs(float(fxcc[indY]) - 0) < TOL
        assert np.abs(float(fycc[indX]) - 0) < TOL
        assert np.abs(float(fycc[indY]) - 1) < TOL
        assert np.abs((fzcc - 1).sum()) < TOL

        mag = (fxcc ** 2 + fycc ** 2) ** 0.5
        dist = ((Mr.gridCC[:, 0] + 0.2) ** 2 + (Mr.gridCC[:, 1] + 0.2) ** 2) ** 0.5

        assert np.abs(mag[dist > 0.1].max() - 1) < TOL
        assert np.abs(mag[dist > 0.1].min() - 1) < TOL
Пример #4
0
    def setUp(self):

        maps2test2D = [M for M in dir(maps) if M not in MAPS_TO_EXCLUDE_2D]
        maps2test3D = [M for M in dir(maps) if M not in MAPS_TO_EXCLUDE_3D]

        self.maps2test2D = [
            getattr(maps, M) for M in maps2test2D
            if (inspect.isclass(getattr(maps, M))
                and issubclass(getattr(maps, M), maps.IdentityMap))
        ]

        self.maps2test3D = [
            getattr(maps, M) for M in maps2test3D
            if inspect.isclass(getattr(maps, M))
            and issubclass(getattr(maps, M), maps.IdentityMap)
        ]

        a = np.array([1, 1, 1])
        b = np.array([1, 2])

        self.mesh2 = discretize.TensorMesh([a, b], x0=np.array([3, 5]))
        self.mesh3 = discretize.TensorMesh([a, b, [3, 4]],
                                           x0=np.array([3, 5, 2]))
        self.mesh22 = discretize.TensorMesh([b, a], x0=np.array([3, 5]))
        self.meshCyl = discretize.CylMesh([10.0, 1.0, 10.0], x0="00C")
Пример #5
0
    def test_getInterpMatCartMesh_Edges2Faces(self):

        Mr = discretize.TensorMesh([100, 100, 2], x0="CC0")
        Mc = discretize.CylMesh(
            [np.ones(10) / 5, 1, 10], x0="0C0", cartesianOrigin=[-0.2, -0.2, 0]
        )

        Pe2f = Mc.getInterpolationMatCartMesh(Mr, "E", locTypeTo="F")
        me = np.ones(Mc.nE)

        frect = Pe2f * me

        excc = Mr.aveFx2CC * Mr.r(frect, "F", "Fx")
        eycc = Mr.aveFy2CC * Mr.r(frect, "F", "Fy")
        ezcc = Mr.r(frect, "F", "Fz")

        indX = utils.closestPoints(Mr, [0.45, -0.2, 0.5])
        indY = utils.closestPoints(Mr, [-0.2, 0.45, 0.5])

        TOL = 1e-2
        assert np.abs(float(excc[indX]) - 0) < TOL
        assert np.abs(float(excc[indY]) + 1) < TOL
        assert np.abs(float(eycc[indX]) - 1) < TOL
        assert np.abs(float(eycc[indY]) - 0) < TOL
        assert np.abs(ezcc.sum()) < TOL

        mag = (excc ** 2 + eycc ** 2) ** 0.5
        dist = ((Mr.gridCC[:, 0] + 0.2) ** 2 + (Mr.gridCC[:, 1] + 0.2) ** 2) ** 0.5

        assert np.abs(mag[dist > 0.1].max() - 1) < TOL
        assert np.abs(mag[dist > 0.1].min() - 1) < TOL
Пример #6
0
 def test_simpleInter(self):
     M = discretize.CylMesh([4, 1, 1])
     locs = np.r_[0, 0, 0.5]
     fx = np.array([[1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]])
     self.assertTrue(np.all(fx == M.getInterpolationMat(locs, "Fx").todense()))
     fz = np.array([[0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0]])
     self.assertTrue(np.all(fz == M.getInterpolationMat(locs, "Fz").todense()))
 def setUp(self):
     n = 2
     self.mesh = discretize.CylMesh([n, 1, n])
     self.face_vec = np.random.rand(self.mesh.nF)
     self.edge_vec = np.random.rand(self.mesh.nE)
     # make up a smooth function
     self.x0 = 2 * self.mesh.gridCC[:, 0]**2 + self.mesh.gridCC[:, 2]**4
    def test_errors(self):
        h1 = np.random.rand(16)
        h1 /= h1.sum()
        h2 = np.random.rand(16)
        h2 /= h2.sum()
        mesh1D = discretize.TensorMesh([h1])
        mesh2D = discretize.TensorMesh([h1, h1])
        mesh3D = discretize.TensorMesh([h1, h1, h1])

        hr = np.r_[1, 1, 0.5]
        hz = np.r_[2, 1]
        meshCyl = discretize.CylMesh([hr, 1, hz], np.r_[0.0, 0.0, 0.0])
        mesh2 = discretize.TreeMesh([h2, h2])
        mesh2.insert_cells([0.75, 0.75], [4])

        with self.assertRaises(TypeError):
            # Gives a wrong typed object to the function
            volume_average(mesh1D, h1)
        with self.assertRaises(NotImplementedError):
            # Gives a wrong typed mesh
            volume_average(meshCyl, mesh2)
        with self.assertRaises(ValueError):
            # Gives mismatching mesh dimensions
            volume_average(mesh2D, mesh3D)

        model1 = np.random.randn(mesh2D.nC)
        bad_model1 = np.random.randn(3)
        bad_model2 = np.random.rand(1)
        # gives input values with incorrect lengths
        with self.assertRaises(ValueError):
            volume_average(mesh2D, mesh2, bad_model1)
        with self.assertRaises(ValueError):
            volume_average(mesh2D, mesh2, model1, bad_model2)
Пример #9
0
    def test_getInterpMatCartMesh_Faces2Edges(self):

        Mr = discretize.TensorMesh([100, 100, 2], x0="CC0")
        Mc = discretize.CylMesh(
            [np.ones(10) / 5, 1, 10], x0="0C0", cartesianOrigin=[-0.2, -0.2, 0]
        )

        self.assertTrue((Mc.cartesianOrigin == [-0.2, -0.2, 0]).all())

        Pf2e = Mc.getInterpolationMatCartMesh(Mr, "F", locTypeTo="E")
        mf = np.ones(Mc.nF)

        ecart = Pf2e * mf

        excc = Mr.aveEx2CC * Mr.r(ecart, "E", "Ex")
        eycc = Mr.aveEy2CC * Mr.r(ecart, "E", "Ey")
        ezcc = Mr.r(ecart, "E", "Ez")

        indX = utils.closestPoints(Mr, [0.45, -0.2, 0.5])
        indY = utils.closestPoints(Mr, [-0.2, 0.45, 0.5])

        TOL = 1e-2
        assert np.abs(float(excc[indX]) - 1) < TOL
        assert np.abs(float(excc[indY]) - 0) < TOL
        assert np.abs(float(eycc[indX]) - 0) < TOL
        assert np.abs(float(eycc[indY]) - 1) < TOL
        assert np.abs((ezcc - 1).sum()) < TOL

        mag = (excc ** 2 + eycc ** 2) ** 0.5
        dist = ((Mr.gridCC[:, 0] + 0.2) ** 2 + (Mr.gridCC[:, 1] + 0.2) ** 2) ** 0.5

        assert np.abs(mag[dist > 0.1].max() - 1) < TOL
        assert np.abs(mag[dist > 0.1].min() - 1) < TOL
Пример #10
0
    def test_cartesianGrid(self):
        mesh = discretize.CylMesh([1, 4, 1])

        root2over2 = np.sqrt(2.0) / 2.0

        # cell centers
        cartCC = mesh.cartesianGrid("CC")
        self.assertTrue(
            np.allclose(cartCC[:, 0],
                        0.5 * root2over2 * np.r_[1.0, -1.0, -1.0, 1.0]))
        self.assertTrue(
            np.allclose(cartCC[:, 1],
                        0.5 * root2over2 * np.r_[1.0, 1.0, -1.0, -1.0]))
        self.assertTrue(np.allclose(cartCC[:, 2], 0.5 * np.ones(4)))

        # nodes
        cartN = mesh.cartesianGrid("N")
        self.assertTrue(
            np.allclose(cartN[:, 0],
                        np.hstack(2 * [0.0, 1.0, 0.0, -1.0, 0.0])))
        self.assertTrue(
            np.allclose(cartN[:, 1],
                        np.hstack(2 * [0.0, 0.0, 1.0, 0.0, -1.0])))
        self.assertTrue(
            np.allclose(cartN[:, 2], np.hstack(5 * [0.0] + 5 * [1.0])))
Пример #11
0
 def setUp(self):
     n = 10
     hx = np.random.rand(n)
     hy = np.random.rand(n)
     hy = hy * 2 * np.pi / hy.sum()
     hz = np.random.rand(n)
     self.mesh = discretize.CylMesh([hx, hy, hz])
Пример #12
0
    def setUp(self):
        hx = utils.meshTensor([(1, 1)])
        htheta = utils.meshTensor([(1.0, 4)])
        htheta = htheta * 2 * np.pi / htheta.sum()
        hz = hx

        self.mesh = discretize.CylMesh([hx, htheta, hz])
Пример #13
0
    def test_getInterpMatCartMesh_Edges(self):

        Mr = discretize.TensorMesh([100, 100, 2], x0='CC0')
        Mc = discretize.CylMesh([np.ones(10) / 5, 1, 10],
                                x0='0C0',
                                cartesianOrigin=[-0.2, -0.2, 0])

        Pe = Mc.getInterpolationMatCartMesh(Mr, 'E')
        me = np.ones(Mc.nE)

        ecart = Pe * me

        excc = Mr.aveEx2CC * Mr.r(ecart, 'E', 'Ex')
        eycc = Mr.aveEy2CC * Mr.r(ecart, 'E', 'Ey')
        ezcc = Mr.aveEz2CC * Mr.r(ecart, 'E', 'Ez')

        indX = utils.closestPoints(Mr, [0.45, -0.2, 0.5])
        indY = utils.closestPoints(Mr, [-0.2, 0.45, 0.5])

        TOL = 1e-2
        assert np.abs(float(excc[indX]) - 0) < TOL
        assert np.abs(float(excc[indY]) + 1) < TOL
        assert np.abs(float(eycc[indX]) - 1) < TOL
        assert np.abs(float(eycc[indY]) - 0) < TOL
        assert np.abs(ezcc.sum()) < TOL

        mag = (excc**2 + eycc**2)**0.5
        dist = ((Mr.gridCC[:, 0] + 0.2)**2 + (Mr.gridCC[:, 1] + 0.2)**2)**0.5

        assert np.abs(mag[dist > 0.1].max() - 1) < TOL
        assert np.abs(mag[dist > 0.1].min() - 1) < TOL
Пример #14
0
def plot_slice(mesh,
               v,
               ax=None,
               clim=None,
               pcolorOpts=None,
               theta_ind=0,
               cb_extend=None,
               show_cb=True):
    """
    Plot a cell centered property

    :param numpy.array prop: cell centered property to plot
    :param matplotlib.axes ax: axis
    :param numpy.array clim: colorbar limits
    :param dict pcolorOpts: dictionary of pcolor options
    """

    if ax is None:
        fig, ax = plt.subplots(1, 1, figsize=(6, 4))

    if pcolorOpts is None:
        pcolorOpts = {}

    # generate a 2D mesh for plotting slices
    mesh2D = discretize.CylMesh([mesh.hx, 1., mesh.hz], x0=mesh.x0)

    vplt = v.reshape(mesh.vnC, order='F')
    plotme = discretize.utils.mkvc(vplt[:, theta_ind, :])
    if not mesh.isSymmetric:
        theta_ind_mirror = (theta_ind + int(mesh.vnC[1] / 2) if
                            theta_ind < int(mesh.vnC[1] / 2) else theta_ind -
                            int(mesh.vnC[1] / 2))
        mirror_data = discretize.utils.mkvc(vplt[:, theta_ind_mirror, :])
    else:
        mirror_data = plotme

    out = mesh2D.plotImage(plotme,
                           ax=ax,
                           mirror=True,
                           mirror_data=mirror_data,
                           pcolorOpts=pcolorOpts,
                           clim=clim)

    out += (ax, )

    if show_cb:
        cb = plt.colorbar(
            out[0],
            ax=ax,
            extend=cb_extend if cb_extend is not None else "neither")
        out += (cb, )

        if clim is not None:
            cb.set_clim(clim)
            cb.update_ticks()

    return out
Пример #15
0
def setupMeshModel():
    cs = 10.0
    nc = 20.0
    npad = 15.0
    hx = [(cs, nc), (cs, npad, 1.3)]
    hz = [(cs, npad, -1.3), (cs, nc), (cs, npad, 1.3)]

    mesh = discretize.CylMesh([hx, 1.0, hz], "0CC")
    muMod = 1 + MuMax * np.random.randn(mesh.nC)
    sigmaMod = np.random.randn(mesh.nC)

    return mesh, muMod, sigmaMod
Пример #16
0
def plotLinesFx(mesh,
                field,
                pltType='semilogy',
                ax=None,
                theta_ind=0,
                xlim=[0., 2500.],
                zloc=0.,
                real_or_imag='real',
                color_ind=0,
                color=None,
                label=None,
                linestyle='-',
                alpha=None):

    mesh2D = discretize.CylMesh([mesh.hx, 1., mesh.hz], x0=mesh.x0)

    if ax is None:
        fig, ax = plt.subplots(1, 1, figsize=(8, 6))

    fplt = face3DthetaSlice(mesh, field, theta_ind=theta_ind)

    fx = discretize.utils.mkvc(fplt[:mesh2D.vnF[0]].reshape(
        [mesh2D.vnFx[0], mesh2D.vnFx[2]], order='F'))

    xind = ((mesh2D.gridFx[:, 0] > xlim[0]) & (mesh2D.gridFx[:, 0] < xlim[1]))
    zind = ((mesh2D.gridFx[:, 2] > -mesh2D.hz.min() + zloc) &
            (mesh2D.gridFx[:, 2] < zloc))
    pltind = xind & zind

    fx = getattr(fx[pltind], real_or_imag)
    x = mesh2D.gridFx[pltind, 0]

    if pltType in ['semilogy', 'loglog']:
        getattr(ax, pltType)(
            x,
            -fx,
            '--',
            color=color if color is not None else 'C{}'.format(color_ind))

    getattr(ax, pltType)(
        x,
        fx.real,
        linestyle,
        color=color if color is not None else 'C{}'.format(color_ind),
        label=label,
        alpha=alpha)

    ax.grid('both', linestyle=linestyle, linewidth=0.4, color=[0.8, 0.8, 0.8])
    ax.set_xlabel('distance from well (m)')

    plt.tight_layout()

    return ax
Пример #17
0
    def test_areas(self):
        mesh = discretize.CylMesh([1, 2, 1])

        areas = np.hstack([[np.pi]*2, [1]*2, [np.pi/2]*4])
        self.assertTrue(np.all(mesh.area == areas))

        edges = np.hstack([[1]*4, [np.pi]*4, [1]*3])
        self.assertTrue(np.all(mesh.edge == edges))

        mesh = discretize.CylMesh([2, 5, 3])

        hangingF = np.hstack([
            getattr(mesh, '_ishangingF{}'.format(dim))
            for dim in ['x', 'y', 'z']
        ])
        self.assertTrue(np.all(mesh._areaFull[~hangingF] == mesh.area))
        hangingE = np.hstack([
            getattr(mesh, '_ishangingE{}'.format(dim))
            for dim in ['x', 'y', 'z']
        ])
        self.assertTrue(np.all(mesh._edgeFull[~hangingE] == mesh.edge))
Пример #18
0
    def test_areas(self):
        mesh = discretize.CylMesh([1, 2, 1])

        areas = np.hstack([[np.pi] * 2, [1] * 2, [np.pi / 2] * 4])
        self.assertTrue(np.all(mesh.area == areas))

        edges = np.hstack([[1] * 4, [np.pi] * 4, [1] * 3])
        self.assertTrue(np.all(mesh.edge == edges))

        mesh = discretize.CylMesh([2, 5, 3])

        hangingF = np.hstack([
            getattr(mesh, "_ishanging_faces_{}".format(dim))
            for dim in ["x", "y", "z"]
        ])
        self.assertTrue(np.all(mesh._face_areas_full[~hangingF] == mesh.area))
        hangingE = np.hstack([
            getattr(mesh, "_ishanging_edges_{}".format(dim))
            for dim in ["x", "y", "z"]
        ])
        self.assertTrue(
            np.all(mesh._edge_lengths_full[~hangingE] == mesh.edge))
Пример #19
0
    def test_indActive_nc_residual(self):
        # x-direction
        cs, ncx, ncz, npad = 1.0, 10.0, 10.0, 20
        hx = [(cs, ncx), (cs, npad, 1.3)]

        # z direction
        npad = 12
        temp = np.logspace(np.log10(1.0), np.log10(12.0), 19)
        temp_pad = temp[-1] * 1.3**np.arange(npad)
        hz = np.r_[temp_pad[::-1], temp[::-1], temp, temp_pad]
        mesh = discretize.CylMesh([hx, 1, hz], "00C")
        active = mesh.vectorCCz < 0.0

        reg = regularization.Simple(mesh, indActive=active)
        self.assertTrue(reg._nC_residual == len(active.nonzero()[0]))
Пример #20
0
def run(plotIt=True):

    sig_halfspace = 1e-6
    sig_sphere = 1e0
    sig_air = 1e-8

    sphere_z = -50.
    sphere_radius = 30.

    # x-direction
    cs = 1
    nc = np.ceil(2.5*(- (sphere_z-sphere_radius))/cs)

    # define a mesh
    mesh = discretize.CylMesh([[(cs, nc)], 1, [(cs, nc)]], x0='00C')

    # Put the model on the mesh
    sigma = sig_air*np.ones(mesh.nC)  # start with air cells
    sigma[mesh.gridCC[:, 2] < 0.] = sig_halfspace  # cells below the earth

    # indices of the sphere
    sphere_ind = (
        (mesh.gridCC[:, 0]**2 + (mesh.gridCC[:, 2] - sphere_z)**2) <=
        sphere_radius**2
    )
    sigma[sphere_ind] = sig_sphere  # sphere

    if plotIt is False:
        return

    # Plot a cross section through the mesh
    fig, ax = plt.subplots(2, 1)
    # Set a nice colormap!
    plt.set_cmap(plt.get_cmap('viridis'))
    plt.colorbar(mesh.plotImage(np.log10(sigma), ax=ax[0])[0], ax=ax[0])
    ax[0].set_title('mirror = False')
    ax[0].axis('equal')
    ax[0].set_xlim([-200., 200.])

    plt.colorbar(
        mesh.plotImage(np.log10(sigma), ax=ax[1], mirror=True)[0], ax=ax[1]
    )
    ax[1].set_title('mirror = True')
    ax[1].axis('equal')
    ax[1].set_xlim([-200., 200.])

    plt.tight_layout()
Пример #21
0
    def test_getInterpMatCartMesh_Cells2Nodes(self):

        Mr = discretize.TensorMesh([100, 100, 2], x0="CC0")
        Mc = discretize.CylMesh(
            [np.ones(10) / 5, 1, 10], x0="0C0", cartesianOrigin=[-0.2, -0.2, 0]
        )

        mc = np.arange(Mc.nC)
        xr = np.linspace(0, 0.4, 50)
        xc = np.linspace(0, 0.4, 50) + 0.2
        Pr = Mr.getInterpolationMat(
            np.c_[xr, np.ones(50) * -0.2, np.ones(50) * 0.5], "N"
        )
        Pc = Mc.getInterpolationMat(np.c_[xc, np.zeros(50), np.ones(50) * 0.5], "CC")
        Pc2r = Mc.getInterpolationMatCartMesh(Mr, "CC", locTypeTo="N")

        assert np.abs(Pr * (Pc2r * mc) - Pc * mc).max() < 1e-3
Пример #22
0
    def setUp(self):
        cs = 10
        nc = 20
        npad = 10
        mesh = discretize.CylMesh([
            [(cs, nc), (cs, npad, 1.3)],
            np.r_[2 * np.pi],
            [(cs, npad, -1.3), (cs, nc), (cs, npad, 1.3)],
        ])

        mesh.x0 = np.r_[0.0, 0.0, -mesh.hz[:npad + nc].sum()]

        # receivers
        rx_x = np.linspace(10, 200, 20)
        rx_z = np.r_[-5]
        rx_locs = utils.ndgrid([rx_x, np.r_[0], rx_z])
        rx_list = [
            dc.receivers.BaseRx(rx_locs, projField="e", orientation="x")
        ]

        # sources
        src_a = np.r_[0.0, 0.0, -5.0]
        src_b = np.r_[55.0, 0.0, -5.0]

        src_list = [
            dc.sources.Dipole(rx_list, locationA=src_a, locationB=src_b)
        ]

        self.mesh = mesh
        self.survey = dc.survey.Survey(src_list)
        self.sigma_map = maps.ExpMap(mesh) * maps.InjectActiveCells(
            mesh, mesh.gridCC[:, 2] <= 0, np.log(1e-8))
        self.prob = dc.simulation.Simulation3DCellCentered(
            mesh=mesh,
            survey=self.survey,
            sigmaMap=self.sigma_map,
            Solver=Pardiso,
            bc_type="Dirichlet",
        )
    def setUp(self):
        target_mur = [1, 50, 100, 200]
        target_l = 500
        target_r = 50
        sigma_back = 1e-5
        radius_loop = 100

        model_names = ["target_{}".format(mur) for mur in target_mur]

        # Set up a Cyl mesh
        csx = 5.0  # cell size in the x-direction
        csz = 5.0  # cell size in the z-direction
        domainx = 100  # go out 500m from the well

        # padding parameters
        npadx, npadz = 15, 15  # number of padding cells
        pfx = 1.4  # expansion factor for the padding to infinity
        pfz = 1.4

        ncz = int(target_l / csz)
        mesh = discretize.CylMesh([
            [(csx, int(domainx / csx)), (csx, npadx, pfx)],
            1,
            [(csz, npadz, -pfz), (csz, ncz), (csz, npadz, pfz)],
        ])
        mesh.x0 = [0, 0, -mesh.hz[:npadz + ncz].sum()]

        # Plot the mesh
        if plotIt:
            mesh.plotGrid()
            plt.show()

        self.radius_loop = radius_loop
        self.target_mur = target_mur
        self.target_l = target_l
        self.target_r = target_r
        self.sigma_back = sigma_back
        self.model_names = model_names
        self.mesh = mesh
Пример #24
0
# receivers
rx_x = np.linspace(-175.0, 175.0, 8)
rx_y = rx_x.copy()
rx_z = np.r_[175.0]
rx_locs = utils.ndgrid(rx_x, rx_y, rx_z)

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

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

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

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

mapping = (
    maps.ExpMap(meshs) * maps.ParametricBlockInLayer(meshs) *
    maps.Projection(nP=8, index=np.hstack([np.r_[0], np.arange(0, 8)])))

primaryMap2Meshs = (maps.ExpMap(meshs) * maps.SurjectFull(meshs) *
                    maps.Projection(nP=8, index=[0]))
Пример #25
0
csx = 5.  # core cell size in the x-direction
csz = 5.  # core cell size in the z-direction
domainx = 100  # use a uniform cell size out to a radius of 100m

# padding parameters
npadx, npadz = 15, 15  # number of padding cells
pfx = 1.4  # expansion factor for the padding to infinity in the x-direction
pfz = 1.4  # expansion factor for the padding to infinity in the z-direction

ncz = int(target_l/csz)  # number of z cells in the core region

# create the cyl mesh
mesh = discretize.CylMesh([
    [(csx, int(domainx/csx)), (csx, npadx, pfx)],
    1,
    [(csz, npadz, -pfz), (csz, ncz), (csz, npadz, pfz)]
])

# put the origin at the top of the target
mesh.x0 = [0, 0, -mesh.hz[:npadz + ncz].sum()]

# plot the mesh
mesh.plotGrid()


###############################################################################
# Assign physical properties on the mesh

mur_model = np.ones(mesh.nC)
Пример #26
0
    def test_active_from_xyz(self):

        # Create 3D topo
        [xx, yy] = np.meshgrid(np.linspace(-200, 200, 50),
                               np.linspace(-200, 200, 50))
        b = 50
        A = 50
        zz = A * np.exp(-0.5 * ((xx / b)**2.0 + (yy / b)**2.0))

        h = [5.0, 5.0, 5.0]

        # Test 1D Mesh
        topo1D = zz[25, :].ravel()
        mesh1D = discretize.TensorMesh([np.ones(10) * 20], x0="C")

        indtopoCC = active_from_xyz(mesh1D,
                                    topo1D,
                                    grid_reference="CC",
                                    method="nearest")
        indtopoN = active_from_xyz(mesh1D,
                                   topo1D,
                                   grid_reference="N",
                                   method="nearest")

        self.assertEqual(indtopoCC.sum(), 3)
        self.assertEqual(indtopoN.sum(), 2)

        # Test 2D Tensor mesh
        topo2D = np.c_[xx[25, :].ravel(), zz[25, :].ravel()]

        mesh_tensor = discretize.TensorMesh([[(h[0], 24)], [(h[1], 20)]],
                                            x0="CC")

        indtopoCC = active_from_xyz(mesh_tensor,
                                    topo2D,
                                    grid_reference="CC",
                                    method="nearest")
        indtopoN = active_from_xyz(mesh_tensor,
                                   topo2D,
                                   grid_reference="N",
                                   method="nearest")

        self.assertEqual(indtopoCC.sum(), 434)
        self.assertEqual(indtopoN.sum(), 412)

        # test 2D Curvilinear mesh
        nodes_x = mesh_tensor.gridN[:, 0].reshape(mesh_tensor.vnN, order="F")
        nodes_y = mesh_tensor.gridN[:, 1].reshape(mesh_tensor.vnN, order="F")
        mesh_curvi = discretize.CurvilinearMesh([nodes_x, nodes_y])

        indtopoCC = active_from_xyz(mesh_curvi,
                                    topo2D,
                                    grid_reference="CC",
                                    method="nearest")
        indtopoN = active_from_xyz(mesh_curvi,
                                   topo2D,
                                   grid_reference="N",
                                   method="nearest")

        self.assertEqual(indtopoCC.sum(), 434)
        self.assertEqual(indtopoN.sum(), 412)

        # Test 2D Tree mesh
        mesh_tree = mesh_builder_xyz(topo2D, h[:2], mesh_type="TREE")
        mesh_tree = refine_tree_xyz(
            mesh_tree,
            topo2D,
            method="surface",
            octree_levels=[1],
            octree_levels_padding=None,
            finalize=True,
        )
        indtopoCC = active_from_xyz(mesh_tree,
                                    topo2D,
                                    grid_reference="CC",
                                    method="nearest")
        indtopoN = active_from_xyz(mesh_tree,
                                   topo2D,
                                   grid_reference="N",
                                   method="nearest")

        self.assertEqual(indtopoCC.sum(), 167)
        self.assertEqual(indtopoN.sum(), 119)

        # Test 3D Tensor meshes
        topo3D = np.c_[xx.ravel(), yy.ravel(), zz.ravel()]

        mesh_tensor = discretize.TensorMesh(
            [[(h[0], 24)], [(h[1], 20)], [(h[2], 30)]], x0="CCC")

        indtopoCC = active_from_xyz(mesh_tensor,
                                    topo3D,
                                    grid_reference="CC",
                                    method="nearest")
        indtopoN = active_from_xyz(mesh_tensor,
                                   topo3D,
                                   grid_reference="N",
                                   method="nearest")

        self.assertEqual(indtopoCC.sum(), 10496)
        self.assertEqual(indtopoN.sum(), 10084)

        # test 3D Curvilinear mesh
        nodes_x = mesh_tensor.gridN[:, 0].reshape(mesh_tensor.vnN, order="F")
        nodes_y = mesh_tensor.gridN[:, 1].reshape(mesh_tensor.vnN, order="F")
        nodes_z = mesh_tensor.gridN[:, 2].reshape(mesh_tensor.vnN, order="F")
        mesh_curvi = discretize.CurvilinearMesh([nodes_x, nodes_y, nodes_z])

        indtopoCC = active_from_xyz(mesh_curvi,
                                    topo3D,
                                    grid_reference="CC",
                                    method="nearest")
        indtopoN = active_from_xyz(mesh_curvi,
                                   topo3D,
                                   grid_reference="N",
                                   method="nearest")

        self.assertEqual(indtopoCC.sum(), 10496)
        self.assertEqual(indtopoN.sum(), 10084)

        # Test 3D Tree mesh
        mesh_tree = mesh_builder_xyz(topo3D, h, mesh_type="TREE")
        mesh_tree = refine_tree_xyz(
            mesh_tree,
            topo3D,
            method="surface",
            octree_levels=[1],
            octree_levels_padding=None,
            finalize=True,
        )
        indtopoCC = active_from_xyz(mesh_tree,
                                    topo3D,
                                    grid_reference="CC",
                                    method="nearest")
        indtopoN = active_from_xyz(mesh_tree,
                                   topo3D,
                                   grid_reference="N",
                                   method="nearest")

        self.assertIn(indtopoCC.sum(), [6292, 6299])
        self.assertIn(indtopoN.sum(), [4632, 4639])

        # Test 3D CYL Mesh
        ncr = 10  # number of mesh cells in r
        ncz = 15  # number of mesh cells in z
        dr = 15  # cell width r
        dz = 10  # cell width z
        npad_r = 4  # number of padding cells in r
        npad_z = 4  # number of padding cells in z
        exp_r = 1.25  # expansion rate of padding cells in r
        exp_z = 1.25  # expansion rate of padding cells in z

        hr = [(dr, ncr), (dr, npad_r, exp_r)]
        hz = [(dz, npad_z, -exp_z), (dz, ncz), (dz, npad_z, exp_z)]

        # A value of 1 is used to define the discretization in phi for this case.
        mesh_cyl = discretize.CylMesh([hr, 1, hz], x0="00C")

        indtopoCC = active_from_xyz(mesh_cyl,
                                    topo3D,
                                    grid_reference="CC",
                                    method="nearest")
        indtopoN = active_from_xyz(mesh_cyl,
                                   topo3D,
                                   grid_reference="N",
                                   method="nearest")

        self.assertEqual(indtopoCC.sum(), 183)
        self.assertEqual(indtopoN.sum(), 171)

        htheta = meshTensor([(1.0, 4)])
        htheta = htheta * 2 * np.pi / htheta.sum()

        mesh_cyl2 = discretize.CylMesh([hr, htheta, hz], x0="00C")
        with self.assertRaises(NotImplementedError):
            indtopoCC = active_from_xyz(mesh_cyl2,
                                        topo3D,
                                        grid_reference="CC",
                                        method="nearest")
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"][()]  # River path
    nSounding = resolve["data"].shape[0]  # the # of soundings

    # Bird height from surface
    b_height_resolve = resolve["src_elevation"][()]

    # 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"][()]

    # build a mesh
    cs, ncx, ncz, npad = 1.0, 10.0, 10.0, 20
    hx = [(cs, ncx), (cs, npad, 1.3)]
    npad = 12
    temp = np.logspace(np.log10(1.0), np.log10(12.0), 19)
    temp_pad = temp[-1] * 1.3**np.arange(npad)
    hz = np.r_[temp_pad[::-1], temp[::-1], temp, temp_pad]
    mesh = discretize.CylMesh([hx, 1, hz], "00C")
    active = mesh.vectorCCz < 0.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
        relative = 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,
                relative=relative,
                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"][()]
    dobs_re = resolve["dobs"][()]
    dpred_re = resolve["dpred"][()]

    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.0 / (d + 100.0)**2.0
    w = utils.sdiag(1.0 / 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": 1e-2,
            "vmax": 1e1
        },
        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)
    inf = temp_dobs / abs(bp) * 1e6
    print(inf.min(), inf.max())
    out = utils.plot2Ddata(
        resolve["xy"][()],
        temp_dobs / abs(bp) * 1e6,
        ncontour=100,
        scale="log",
        dataloc=False,
        ax=ax1,
        contourOpts={"cmap": "viridis"},
    )
    vmin, vmax = out[0].get_clim()
    print(vmin, vmax)
    cb = plt.colorbar(
        out[0],
        ticks=np.logspace(np.log10(vmin), np.log10(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"][()],
        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.logspace(np.log10(vmin), np.log10(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)

    resolve.close()
    if cleanup:
        os.remove(downloads)
        shutil.rmtree(directory)
def run(plotIt=True, saveFig=False):

    # Set up cylindrically symmeric mesh
    cs, ncx, ncz, npad = 10.0, 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 = discretize.CylMesh([hx, 1, hz], "00C")

    # Conductivity model
    layerz = np.r_[-200.0, -100.0]
    layer = (mesh.vectorCCz >= layerz[0]) & (mesh.vectorCCz <= layerz[1])
    active = mesh.vectorCCz < 0.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.0], np.r_[0], np.r_[0.0]])
    bzr = FDEM.Rx.PointMagneticFluxDensitySecondary(rxlocs, "z", "real")
    bzi = FDEM.Rx.PointMagneticFluxDensitySecondary(rxlocs, "z", "imag")

    freqs = np.logspace(2, 3, 5)
    srcLoc = np.array([0.0, 0.0, 0.0])

    print(
        "min skin depth = ",
        500.0 / np.sqrt(freqs.max() * sig_half),
        "max skin depth = ",
        500.0 / np.sqrt(freqs.min() * sig_half),
    )
    print(
        "max x ",
        mesh.vectorCCx.max(),
        "min z ",
        mesh.vectorCCz.min(),
        "max z ",
        mesh.vectorCCz.max(),
    )

    source_list = [
        FDEM.Src.MagDipole([bzr, bzi], freq, srcLoc, orientation="Z") for freq in freqs
    ]

    surveyFD = FDEM.Survey(source_list)
    prbFD = FDEM.Simulation3DMagneticFluxDensity(
        mesh, survey=surveyFD, sigmaMap=mapping, solver=Solver
    )
    rel_err = 0.03
    dataFD = prbFD.make_synthetic_data(mtrue, relative_error=rel_err, add_noise=True)
    dataFD.noise_floor = np.linalg.norm(dataFD.dclean) * 1e-5

    # FDEM inversion
    np.random.seed(1)
    dmisfit = data_misfit.L2DataMisfit(simulation=prbFD, data=dataFD)
    regMesh = discretize.TensorMesh([mesh.hz[mapping.maps[-1].indActive]])
    reg = regularization.Simple(regMesh)
    opt = optimization.InexactGaussNewton(maxIterCG=10)
    invProb = inverse_problem.BaseInvProblem(dmisfit, reg, opt)

    # Inversion Directives
    beta = directives.BetaSchedule(coolingFactor=4, coolingRate=3)
    betaest = directives.BetaEstimate_ByEig(beta0_ratio=1.0, seed=518936)
    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.0
    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.PointMagneticFluxDensity(rxlocs, times, "z")
    src = TDEM.Src.MagDipole(
        [rx],
        waveform=TDEM.Src.StepOffWaveform(),
        location=srcLoc,  # same src location as FDEM problem
    )

    surveyTD = TDEM.Survey([src])
    prbTD = TDEM.Simulation3DMagneticFluxDensity(
        mesh, survey=surveyTD, sigmaMap=mapping, solver=Solver
    )
    prbTD.time_steps = [(5e-5, 10), (1e-4, 10), (5e-4, 10)]

    rel_err = 0.03
    dataTD = prbTD.make_synthetic_data(mtrue, relative_error=rel_err, add_noise=True)
    dataTD.noise_floor = np.linalg.norm(dataTD.dclean) * 1e-5

    # TDEM inversion
    dmisfit = data_misfit.L2DataMisfit(simulation=prbTD, data=dataTD)
    regMesh = discretize.TensorMesh([mesh.hz[mapping.maps[-1].indActive]])
    reg = regularization.Simple(regMesh)
    opt = optimization.InexactGaussNewton(maxIterCG=10)
    invProb = inverse_problem.BaseInvProblem(dmisfit, reg, opt)

    # directives
    beta = directives.BetaSchedule(coolingFactor=4, coolingRate=3)
    betaest = directives.BetaEstimate_ByEig(beta0_ratio=1.0, seed=518936)
    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.0
    prbTD.counter = opt.counter = utils.Counter()
    opt.remember("xc")
    moptTD = inv.run(m0)

    # Plot the results
    if plotIt:
        plt.figure(figsize=(10, 8))
        ax0 = plt.subplot2grid((2, 2), (0, 0), rowspan=2)
        ax1 = plt.subplot2grid((2, 2), (0, 1))
        ax2 = plt.subplot2grid((2, 2), (1, 1))

        fs = 13  # fontsize
        matplotlib.rcParams["font.size"] = fs

        # Plot the model
        # z_true = np.repeat(mesh.vectorCCz[active][1:], 2, axis=0)
        # z_true = np.r_[mesh.vectorCCz[active][0], z_true, mesh.vectorCCz[active][-1]]
        activeN = mesh.vectorNz <= 0.0 + cs / 2.0
        z_true = np.repeat(mesh.vectorNz[activeN][1:-1], 2, axis=0)
        z_true = np.r_[mesh.vectorNz[activeN][0], z_true, mesh.vectorNz[activeN][-1]]
        sigma_true = np.repeat(sigma[active], 2, axis=0)

        ax0.semilogx(sigma_true, z_true, "k-", lw=2, label="True")

        ax0.semilogx(
            np.exp(moptFD),
            mesh.vectorCCz[active],
            "bo",
            ms=6,
            markeredgecolor="k",
            markeredgewidth=0.5,
            label="FDEM",
        )
        ax0.semilogx(
            np.exp(moptTD),
            mesh.vectorCCz[active],
            "r*",
            ms=10,
            markeredgecolor="k",
            markeredgewidth=0.5,
            label="TDEM",
        )
        ax0.set_ylim(-700, 0)
        ax0.set_xlim(5e-3, 1e-1)

        ax0.set_xlabel("Conductivity (S/m)", fontsize=fs)
        ax0.set_ylabel("Depth (m)", fontsize=fs)
        ax0.grid(which="both", color="k", alpha=0.5, linestyle="-", linewidth=0.2)
        ax0.legend(fontsize=fs, loc=4)

        # plot the data misfits - negative b/c we choose positive to be in the
        # direction of primary

        ax1.plot(freqs, -dataFD.dobs[::2], "k-", lw=2, label="Obs (real)")
        ax1.plot(freqs, -dataFD.dobs[1::2], "k--", lw=2, label="Obs (imag)")

        dpredFD = prbFD.dpred(moptTD)
        ax1.loglog(
            freqs,
            -dpredFD[::2],
            "bo",
            ms=6,
            markeredgecolor="k",
            markeredgewidth=0.5,
            label="Pred (real)",
        )
        ax1.loglog(
            freqs, -dpredFD[1::2], "b+", ms=10, markeredgewidth=2.0, label="Pred (imag)"
        )

        ax2.loglog(times, dataTD.dobs, "k-", lw=2, label="Obs")
        ax2.loglog(
            times,
            prbTD.dpred(moptTD),
            "r*",
            ms=10,
            markeredgecolor="k",
            markeredgewidth=0.5,
            label="Pred",
        )
        ax2.set_xlim(times.min() - 1e-5, times.max() + 1e-4)

        # Labels, gridlines, etc
        ax2.grid(which="both", alpha=0.5, linestyle="-", linewidth=0.2)
        ax1.grid(which="both", alpha=0.5, linestyle="-", linewidth=0.2)

        ax1.set_xlabel("Frequency (Hz)", fontsize=fs)
        ax1.set_ylabel("Vertical magnetic field (-T)", fontsize=fs)

        ax2.set_xlabel("Time (s)", fontsize=fs)
        ax2.set_ylabel("Vertical magnetic field (T)", fontsize=fs)

        ax2.legend(fontsize=fs, loc=3)
        ax1.legend(fontsize=fs, loc=3)
        ax1.set_xlim(freqs.max() + 1e2, freqs.min() - 1e1)

        ax0.set_title("(a) Recovered Models", fontsize=fs)
        ax1.set_title("(b) FDEM observed vs. predicted", fontsize=fs)
        ax2.set_title("(c) TDEM observed vs. predicted", fontsize=fs)

        plt.tight_layout(pad=1.5)

        if saveFig is True:
            plt.savefig("example1.png", dpi=600)
def run(plotIt=True):

    # ------------------ MODEL ------------------
    sigmaair = 1e-8  # air
    sigmaback = 1e-2  # background
    sigmacasing = 1e6  # casing
    sigmainside = sigmaback  # inside the casing

    casing_t = 0.006  # 1cm thickness
    casing_l = 300  # length of the casing

    casing_r = 0.1
    casing_a = casing_r - casing_t / 2.0  # inner radius
    casing_b = casing_r + casing_t / 2.0  # outer radius
    casing_z = np.r_[-casing_l, 0.0]

    # ------------------ SURVEY PARAMETERS ------------------
    freqs = np.r_[1e-6]  # [1e-1, 1, 5] # frequencies
    dsz = -300  # down-hole z source location
    src_loc = np.r_[0.0, 0.0, dsz]
    inf_loc = np.r_[0.0, 0.0, 1e4]

    print("Skin Depth: ", [(500.0 / np.sqrt(sigmaback * _)) for _ in freqs])

    # ------------------ MESH ------------------
    # fine cells near well bore
    csx1, csx2 = 2e-3, 60.0
    pfx1, pfx2 = 1.3, 1.3
    ncx1 = np.ceil(casing_b / csx1 + 2)

    # pad nicely to second cell size
    npadx1 = np.floor(np.log(csx2 / csx1) / np.log(pfx1))
    hx1a = utils.meshTensor([(csx1, ncx1)])
    hx1b = utils.meshTensor([(csx1, npadx1, pfx1)])
    dx1 = sum(hx1a) + sum(hx1b)
    dx1 = np.floor(dx1 / csx2)
    hx1b *= (dx1 * csx2 - sum(hx1a)) / sum(hx1b)

    # second chunk of mesh
    dx2 = 300.0  # uniform mesh out to here
    ncx2 = np.ceil((dx2 - dx1) / csx2)
    npadx2 = 45
    hx2a = utils.meshTensor([(csx2, ncx2)])
    hx2b = utils.meshTensor([(csx2, npadx2, pfx2)])
    hx = np.hstack([hx1a, hx1b, hx2a, hx2b])

    # z-direction
    csz = 0.05
    nza = 10
    # cell size, number of core cells, number of padding cells in the
    # x-direction
    ncz, npadzu, npadzd = np.int(np.ceil(np.diff(casing_z)[0] / csz)) + 10, 68, 68
    # vector of cell widths in the z-direction
    hz = utils.meshTensor([(csz, npadzd, -1.3), (csz, ncz), (csz, npadzu, 1.3)])

    # Mesh
    mesh = discretize.CylMesh(
        [hx, 1.0, hz], [0.0, 0.0, -np.sum(hz[: npadzu + ncz - nza])]
    )

    print(
        "Mesh Extent xmax: {0:f},: zmin: {1:f}, zmax: {2:f}".format(
            mesh.vectorCCx.max(), mesh.vectorCCz.min(), mesh.vectorCCz.max()
        )
    )
    print("Number of cells", mesh.nC)

    if plotIt is True:
        fig, ax = plt.subplots(1, 1, figsize=(6, 4))
        ax.set_title("Simulation Mesh")
        mesh.plotGrid(ax=ax)

    # Put the model on the mesh
    sigWholespace = sigmaback * np.ones((mesh.nC))

    sigBack = sigWholespace.copy()
    sigBack[mesh.gridCC[:, 2] > 0.0] = sigmaair

    sigCasing = sigBack.copy()
    iCasingZ = (mesh.gridCC[:, 2] <= casing_z[1]) & (mesh.gridCC[:, 2] >= casing_z[0])
    iCasingX = (mesh.gridCC[:, 0] >= casing_a) & (mesh.gridCC[:, 0] <= casing_b)
    iCasing = iCasingX & iCasingZ
    sigCasing[iCasing] = sigmacasing

    if plotIt is True:
        # plotting parameters
        xlim = np.r_[0.0, 0.2]
        zlim = np.r_[-350.0, 10.0]
        clim_sig = np.r_[-8, 6]

        # plot models
        fig, ax = plt.subplots(1, 1, figsize=(4, 4))

        im = mesh.plotImage(np.log10(sigCasing), ax=ax)[0]
        im.set_clim(clim_sig)
        plt.colorbar(im, ax=ax)
        ax.grid(which="both")
        ax.set_title("Log_10 (Sigma)")
        ax.set_xlim(xlim)
        ax.set_ylim(zlim)

    # -------------- Sources --------------------
    # Define Custom Current Sources

    # surface source
    sg_x = np.zeros(mesh.vnF[0], dtype=complex)
    sg_y = np.zeros(mesh.vnF[1], dtype=complex)
    sg_z = np.zeros(mesh.vnF[2], dtype=complex)

    nza = 2  # put the wire two cells above the surface

    # vertically directed wire
    # hook it up to casing at the surface
    sgv_indx = (mesh.gridFz[:, 0] > casing_a) & (mesh.gridFz[:, 0] < casing_a + csx1)
    sgv_indz = (mesh.gridFz[:, 2] <= +csz * nza) & (mesh.gridFz[:, 2] >= -csz * 2)
    sgv_ind = sgv_indx & sgv_indz
    sg_z[sgv_ind] = -1.0

    # horizontally directed wire
    sgh_indx = (mesh.gridFx[:, 0] > casing_a) & (mesh.gridFx[:, 0] <= inf_loc[2])
    sgh_indz = (mesh.gridFx[:, 2] > csz * (nza - 0.5)) & (
        mesh.gridFx[:, 2] < csz * (nza + 0.5)
    )
    sgh_ind = sgh_indx & sgh_indz
    sg_x[sgh_ind] = -1.0

    # hook it up to casing at the surface
    sgv2_indx = (mesh.gridFz[:, 0] >= mesh.gridFx[sgh_ind, 0].max()) & (
        mesh.gridFz[:, 0] <= inf_loc[2] * 1.2
    )
    sgv2_indz = (mesh.gridFz[:, 2] <= +csz * nza) & (mesh.gridFz[:, 2] >= -csz * 2)
    sgv2_ind = sgv2_indx & sgv2_indz
    sg_z[sgv2_ind] = 1.0

    # assemble the source
    sg = np.hstack([sg_x, sg_y, sg_z])
    sg_p = [FDEM.Src.RawVec_e([], _, sg / mesh.area) for _ in freqs]

    # downhole source
    dg_x = np.zeros(mesh.vnF[0], dtype=complex)
    dg_y = np.zeros(mesh.vnF[1], dtype=complex)
    dg_z = np.zeros(mesh.vnF[2], dtype=complex)

    # vertically directed wire
    dgv_indx = mesh.gridFz[:, 0] < csx1  # go through the center of the well
    dgv_indz = (mesh.gridFz[:, 2] <= +csz * nza) & (mesh.gridFz[:, 2] > dsz + csz / 2.0)
    dgv_ind = dgv_indx & dgv_indz
    dg_z[dgv_ind] = -1.0

    # couple to the casing downhole
    dgh_indx = mesh.gridFx[:, 0] < casing_a + csx1
    dgh_indz = (mesh.gridFx[:, 2] < dsz + csz) & (mesh.gridFx[:, 2] >= dsz)
    dgh_ind = dgh_indx & dgh_indz
    dg_x[dgh_ind] = 1.0

    # horizontal part at surface
    dgh2_indx = mesh.gridFx[:, 0] <= inf_loc[2] * 1.2
    dgh2_indz = sgh_indz.copy()
    dgh2_ind = dgh2_indx & dgh2_indz
    dg_x[dgh2_ind] = -1.0

    # vertical part at surface
    dgv2_ind = sgv2_ind.copy()
    dg_z[dgv2_ind] = 1.0

    # assemble the source
    dg = np.hstack([dg_x, dg_y, dg_z])
    dg_p = [FDEM.Src.RawVec_e([], _, dg / mesh.area) for _ in freqs]

    # ------------ Problem and Survey ---------------
    survey = FDEM.Survey(sg_p + dg_p)
    problem = FDEM.Simulation3DMagneticField(
        mesh, survey=survey, sigmaMap=maps.IdentityMap(mesh), solver=Solver
    )

    # ------------- Solve ---------------------------
    t0 = time.time()
    fieldsCasing = problem.fields(sigCasing)
    print("Time to solve 2 sources", time.time() - t0)

    # Plot current

    # current density
    jn0 = fieldsCasing[dg_p, "j"]
    jn1 = fieldsCasing[sg_p, "j"]

    # current
    in0 = [mesh.area * fieldsCasing[dg_p, "j"][:, i] for i in range(len(freqs))]
    in1 = [mesh.area * fieldsCasing[sg_p, "j"][:, i] for i in range(len(freqs))]

    in0 = np.vstack(in0).T
    in1 = np.vstack(in1).T

    # integrate to get z-current inside casing
    inds_inx = (mesh.gridFz[:, 0] >= casing_a) & (mesh.gridFz[:, 0] <= casing_b)
    inds_inz = (mesh.gridFz[:, 2] >= dsz) & (mesh.gridFz[:, 2] <= 0)
    inds_fz = inds_inx & inds_inz

    indsx = [False] * mesh.nFx
    inds = list(indsx) + list(inds_fz)

    in0_in = in0[np.r_[inds]]
    in1_in = in1[np.r_[inds]]
    z_in = mesh.gridFz[inds_fz, 2]

    in0_in = in0_in.reshape([in0_in.shape[0] // 3, 3])
    in1_in = in1_in.reshape([in1_in.shape[0] // 3, 3])
    z_in = z_in.reshape([z_in.shape[0] // 3, 3])

    I0 = in0_in.sum(1).real
    I1 = in1_in.sum(1).real
    z_in = z_in[:, 0]

    if plotIt is True:
        fig, ax = plt.subplots(1, 2, figsize=(12, 4))

        ax[0].plot(z_in, np.absolute(I0), z_in, np.absolute(I1))
        ax[0].legend(["top casing", "bottom casing"], loc="best")
        ax[0].set_title("Magnitude of Vertical Current in Casing")

        ax[1].semilogy(z_in, np.absolute(I0), z_in, np.absolute(I1))
        ax[1].legend(["top casing", "bottom casing"], loc="best")
        ax[1].set_title("Magnitude of Vertical Current in Casing")
        ax[1].set_ylim([1e-2, 1.0])
Пример #30
0
def plotLinesFx(mesh,
                srcList,
                fields3D=None,
                fieldsDC=None,
                fieldType='e',
                pltType='semilogy',
                ax=None,
                theta_ind=0,
                xlim=[0., 2500.],
                zloc=0.):

    mesh2D = discretize.CylMesh([mesh.hx, 1., mesh.hz], x0=mesh.x0)

    if ax is None:
        fig, ax = plt.subplots(1, 2, figsize=(15, 6))
        ax = discretize.utils.mkvc(ax)

    for i, src in enumerate(srcList):
        if fields3D is not None:
            field = fields3D[src, fieldType]
            fplt = utils.face3DthetaSlice(mesh, field, theta_ind=theta_ind)

            fx = discretize.utils.mkvc(fplt[:mesh2D.vnF[0]].reshape(
                [mesh2D.vnFx[0], mesh2D.vnFx[2]], order='F'))

        xind = ((mesh2D.gridFx[:, 0] > xlim[0]) &
                (mesh2D.gridFx[:, 0] < xlim[1]))
        zind = ((mesh2D.gridFx[:, 2] > -mesh2D.hz.min()) &
                (mesh2D.gridFx[:, 2] < 0.))
        pltind = xind & zind

        fx = fx[pltind]
        x = mesh2D.gridFx[pltind, 0]

        label = '{} Hz'.format(src.freq)

        getattr(ax[0], pltType)(x, -fx.real, '--', color='C{}'.format(i))
        getattr(ax[1], pltType)(x, -fx.imag, '--', color='C{}'.format(i))

        getattr(ax[0], pltType)(x,
                                fx.real,
                                '-',
                                color='C{}'.format(i),
                                label='{} Hz'.format(src.freq))
        getattr(ax[1], pltType)(x,
                                fx.imag,
                                '-',
                                color='C{}'.format(i),
                                label='{} Hz'.format(src.freq))

    # plot the DC solution
    fxDC = utils.face3DthetaSlice(mesh,
                                  fieldsDC[:, fieldType],
                                  theta_ind=theta_ind)
    fxDC = discretize.utils.mkvc(fxDC[:mesh2D.vnF[0]].reshape(
        [mesh2D.vnFx[0], mesh2D.vnFx[2]], order='F'))
    fxDC = fxDC[pltind]

    getattr(ax[0], pltType)(x, -fxDC, '--', color='k')
    getattr(ax[0], pltType)(x, fxDC, '-', color='k', label='DC')

    ax[0].legend()
    ax[1].legend()

    ax[0].set_title('${}_r$ real'.format(fieldType))
    ax[1].set_title('${}_r$ imag'.format(fieldType))
    # [a.set_xlim([2., 1000.]) for a in ax]
    [
        a.grid('both', linestyle='-', linewidth=0.4, color=[0.8, 0.8, 0.8])
        for a in ax
    ]
    [a.set_xlabel('distance from well (m)') for a in ax]

    plt.tight_layout()

    return ax