Exemplo n.º 1
0
def createLocalMesh(rxLoc, ind_t):
    """
    Function to generate a mesh based on receiver locations
    """

    # Create new survey
    if input_dict["inversion_type"] == 'grav':
        rxLoc_t = PF.BaseGrav.RxObs(rxLoc[ind_t, :])
        srcField = PF.BaseGrav.SrcField([rxLoc_t])
        local_survey = PF.BaseGrav.LinearSurvey(srcField)
        local_survey.dobs = survey.dobs[ind_t]
        local_survey.std = survey.std[ind_t]
        local_survey.ind = ind_t

    elif input_dict["inversion_type"] in ['mag', 'mvi', 'mvis']:
        rxLoc_t = PF.BaseMag.RxObs(rxLoc[ind_t, :])
        srcField = PF.BaseMag.SrcField([rxLoc_t], param=survey.srcField.param)
        local_survey = PF.BaseMag.LinearSurvey(
            srcField, components=survey.components
        )

        dataInd = np.kron(ind_t, np.ones(len(survey.components))).astype('bool')

        local_survey.dobs = survey.dobs[dataInd]
        local_survey.std = survey.std[dataInd]
        local_survey.ind = ind_t

    meshLocal = meshutils.mesh_builder_xyz(
        topo_elevations_at_data_locs,
        core_cell_size,
        padding_distance=padding_distance,
        mesh_type=inversion_mesh_type,
        base_mesh=input_mesh,
        depth_core=depth_core
    )

    if shift_mesh_z0 is not None:
        print("In mesh z0")
        meshLocal.x0 = np.r_[meshLocal.x0[0], meshLocal.x0[1], shift_mesh_z0]

    if inversion_mesh_type.upper() == 'TREE':
        if topo is not None:
            meshLocal = meshutils.refine_tree_xyz(
                meshLocal, topo, method='surface',
                octree_levels=octree_levels_topo, finalize=False
            )

        meshLocal = meshutils.refine_tree_xyz(
            meshLocal, topo_elevations_at_data_locs[ind_t, :],
            method='surface',
            max_distance=max_distance,
            octree_levels=octree_levels_obs,
            octree_levels_padding=octree_levels_padding,
            finalize=True,
        )

    # Create combo misfit function
    return meshLocal, local_survey
Exemplo n.º 2
0
def createLocalMesh(rxLoc, ind_t):
    """
    Function to generate a mesh based on receiver locations
    """

    # Create new survey
    if input_dict["inversion_type"].lower() == 'grav':
        rxLoc_t = PF.BaseGrav.RxObs(rxLoc[ind_t, :])
        srcField = PF.BaseGrav.SrcField([rxLoc_t])
        local_survey = PF.BaseGrav.LinearSurvey(srcField)
        local_survey.dobs = survey.dobs[ind_t]
        local_survey.std = survey.std[ind_t]
        local_survey.ind = ind_t

        # Utils.io_utils.writeUBCgravityObservations(outDir + "Tile" + str(ind) + '.dat', local_survey, local_survey.dobs)

    elif input_dict["inversion_type"].lower() in ['mag', 'mvi', 'mvis']:
        rxLoc_t = PF.BaseMag.RxObs(rxLoc[ind_t, :])
        srcField = PF.BaseMag.SrcField([rxLoc_t], param=survey.srcField.param)
        local_survey = PF.BaseMag.LinearSurvey(srcField,
                                               components=survey.components)

        dataInd = np.kron(ind_t,
                          np.ones(len(survey.components))).astype('bool')

        local_survey.dobs = survey.dobs[dataInd]
        local_survey.std = survey.std[dataInd]
        local_survey.ind = ind_t

        # Utils.io_utils.writeUBCmagneticsObservations(outDir + "Tile" + str(ind) + '.dat', local_survey, local_survey.dobs)

    meshLocal = meshutils.mesh_builder_xyz(newTopo,
                                           core_cell_size,
                                           padding_distance=padding_distance,
                                           mesh_type='TREE',
                                           base_mesh=meshInput,
                                           depth_core=depth_core)

    if topo is not None:
        meshLocal = meshutils.refine_tree_xyz(meshLocal,
                                              topo,
                                              method='surface',
                                              octree_levels=octree_levels_topo,
                                              finalize=False)

    meshLocal = meshutils.refine_tree_xyz(
        meshLocal,
        rxLoc[ind_t, :],
        method='surface',
        max_distance=max_distance,
        octree_levels=octree_levels_obs,
        octree_levels_padding=octree_levels_padding,
        finalize=True,
    )

    # Create combo misfit function
    return meshLocal, local_survey
Exemplo n.º 3
0
    def test_box(self):
        dx = 0.25
        dl = 10

        # Create a box 2*dl in width
        X, Y, Z = np.meshgrid(np.c_[-dl, dl], np.c_[-dl, dl], np.c_[-dl, dl])
        xyz = np.c_[np.ravel(X), np.ravel(Y), np.ravel(Z)]
        mesh = meshutils.mesh_builder_xyz(
            np.c_[0.01, 0.01, 0.01], [dx, dx, dx],
            depth_core=0,
            padding_distance=[[0, 20], [0, 20], [0, 20]],
            mesh_type='TREE',
        )

        mesh = meshutils.refine_tree_xyz(
            mesh, xyz, octree_levels=[1], method='box', finalize=True
        )

        # Volume of box
        vol = (2*dl)**3

        residual = np.abs(
            vol -
            mesh.vol[
                mesh._cell_levels_by_indexes(range(mesh.nC)) == mesh.max_level
            ].sum()
        )/vol * 100

        self.assertTrue(residual < 0.5)
Exemplo n.º 4
0
    def test_surface(self):
        dx = 0.1
        dl = 20

        # Define triangle
        xyz = np.r_[
            np.c_[-dl/2, -dl/2, 0],
            np.c_[dl/2, -dl/2, 0],
            np.c_[dl/2, dl/2, 0]
        ]
        mesh = meshutils.mesh_builder_xyz(
            np.c_[0.01, 0.01, 0.01], [dx, dx, dx],
            depth_core=0,
            padding_distance=[[0, 20], [0, 20], [0, 20]],
            mesh_type='TREE',
        )

        mesh = meshutils.refine_tree_xyz(
            mesh, xyz, octree_levels=[1], method='surface', finalize=True
        )

        # Volume of triangle
        vol = dl*dl*dx/2

        residual = np.abs(
            vol -
            mesh.vol[
                mesh._cell_levels_by_indexes(range(mesh.nC)) == mesh.max_level
            ].sum()/2
        )/vol * 100

        self.assertTrue(residual < 5)
Exemplo n.º 5
0
    def test_radial(self):
        dx = 0.25
        rad = 10
        mesh = meshutils.mesh_builder_xyz(
            np.c_[0.01, 0.01, 0.01], [dx, dx, dx],
            depth_core=0,
            padding_distance=[[0, 20], [0, 20], [0, 20]],
            mesh_type='TREE',
        )

        radCell = int(np.ceil(rad/dx))
        mesh = meshutils.refine_tree_xyz(
            mesh, np.c_[0, 0, 0],
            octree_levels=[radCell], method='radial',
            finalize=True
        )

        # Volume of sphere
        vol = 4.*np.pi/3.*rad**3.

        residual = np.abs(
            vol -
            mesh.vol[
                mesh._cell_levels_by_indexes(range(mesh.nC)) == mesh.max_level
            ].sum()
        )/vol * 100

        self.assertTrue(residual < 3)
Exemplo n.º 6
0
def refine_box(mesh):

    # Refine for sphere
    xp, yp, zp = np.meshgrid([-55.0, 50.0], [-50.0, 50.0], [-40.0, 20.0])
    xyz = np.c_[mkvc(xp), mkvc(yp), mkvc(zp)]

    mesh = refine_tree_xyz(mesh,
                           xyz,
                           octree_levels=[2],
                           method="box",
                           finalize=False)

    return mesh
Exemplo n.º 7
0
def refine_topography(mesh):

    # Define topography and refine
    [xx, yy] = np.meshgrid(mesh.vectorNx, mesh.vectorNy)
    zz = -3 * np.exp((xx**2 + yy**2) / 60**2) + 45.0
    topo = np.c_[mkvc(xx), mkvc(yy), mkvc(zz)]

    mesh = refine_tree_xyz(mesh,
                           topo,
                           octree_levels=[3, 2],
                           method="surface",
                           finalize=False)

    return mesh
Exemplo n.º 8
0
def refine_octree_surface(mesh, f):
    """
    Refine an octree mesh around the given surface
    :param mesh: TreeMesh instance to refine
    :param f: function giving z(x,y) in physical units
    :return: TreeMesh instance
    """
    xx, yy = np.meshgrid(mesh.vectorNx, mesh.vectorNy)
    zz = f(xx, yy)
    idx_valid = ~np.isnan(zz)
    xx, yy, zz = xx[idx_valid], yy[idx_valid], zz[idx_valid]
    surf = np.c_[mkvc(xx), mkvc(yy), mkvc(zz)]
    # Play with different octree_levels=[lx,ly,lz] settings below
    return refine_tree_xyz(
        mesh, surf, octree_levels=[1,1,1], method="surface", finalize=False
    )
Exemplo n.º 9
0
# Compute number of base mesh cells required in x and y
nbcx = 2**int(np.round(np.log(x_length / dx) / np.log(2.)))
nbcy = 2**int(np.round(np.log(y_length / dy) / np.log(2.)))

# Define the base mesh
hx = [(dx, nbcx)]
hy = [(dy, nbcy)]
M = TreeMesh([hx, hy], x0=['C', -15000])

# definir camada
xx = M.vectorNx
yy = np.zeros(nbcx + 1)  #vetor linha(poderia ser uma função ou pontos)
pts = np.c_[matutils.mkvc(xx), matutils.mkvc(yy)]
M = meshutils.refine_tree_xyz(M,
                              pts,
                              octree_levels=[1, 1],
                              method='box',
                              finalize=False)

#definir um ponto(xc,yc) a ser refinado.
Raio_length = 500
xc = -5000
yc = 2200

xx = M.vectorNx
yy = np.zeros(nbcx + 1)  #vetor linha(poderia ser uma função ou pontos)
pts = np.c_[matutils.mkvc(xx), matutils.mkvc(yy)]


def refine(cell):
    if np.sqrt(((np.r_[cell.center] + [xc, yc])**2).sum()) < Raio_length:
Exemplo n.º 10
0
        ind_t = tileIDs == tile_numbers[indMax]

        # Create the mesh and refine the same as the global mesh
        meshLocal = meshutils.mesh_builder_xyz(
            newTopo,
            core_cell_size,
            padding_distance=padding_distance,
            mesh_type='TREE',
            base_mesh=meshInput,
            depth_core=depth_core)

        if topo is not None:
            meshLocal = meshutils.refine_tree_xyz(
                meshLocal,
                topo,
                method='surface',
                octree_levels=octree_levels_topo,
                finalize=False)

        meshLocal = meshutils.refine_tree_xyz(
            meshLocal,
            rxLoc[ind_t, :],
            method='surface',
            max_distance=max_distance,
            octree_levels=octree_levels_obs,
            octree_levels_padding=octree_levels_padding,
            finalize=True,
        )

        tileLayer = Utils.surface2ind_topo(meshLocal, topo)
Exemplo n.º 11
0
def run(plotIt=True):

    nFreq = 13
    freqs = np.logspace(2, -2, nFreq)

    # x and y grid parameters
    #    dh = 10   # minimum cell width (base mesh cell width)

    dx = 15  # minimum cell width (base mesh cell width) in x
    dy = 15
    dz = 10

    x_length = 10000.  # domain width in x
    y_length = 10000.
    z_length = 40000.

    # Compute number of base mesh cells required in x and y
    nbcx = 2**int(np.round(np.log(x_length / dx) / np.log(2.)))
    nbcy = 2**int(np.round(np.log(y_length / dy) / np.log(2.)))
    nbcz = 2**int(np.round(np.log(z_length / dz) / np.log(2.)))

    # Define the base mesh
    hx = [(dx, nbcx)]
    hy = [(dy, nbcy)]
    hz = [(dz, nbcz)]

    M = Mesh.TreeMesh([hx, hy, hz], x0=['C', 'C', -15000])

    # camadas

    xx = M.vectorNx
    yy = M.vectorNy
    zz = np.zeros(nbcx + 1)  #vetor linha(poderia ser uma função ou pontos)
    pts = np.c_[matutils.mkvc(xx), matutils.mkvc(yy), matutils.mkvc(zz)]
    M = meshutils.refine_tree_xyz(M,
                                  pts,
                                  octree_levels=[1, 1, 1],
                                  method='surface',
                                  finalize=False)

    xx = M.vectorNx
    yy = M.vectorNy
    zz = np.zeros(nbcx +
                  1) - 150  #vetor linha(poderia ser uma função ou pontos)
    pts = np.c_[matutils.mkvc(xx), matutils.mkvc(yy), matutils.mkvc(zz)]
    M = meshutils.refine_tree_xyz(M,
                                  pts,
                                  octree_levels=[1, 1, 1],
                                  method='surface',
                                  finalize=False)

    xx = M.vectorNx
    yy = M.vectorNy
    zz = np.zeros(nbcx +
                  1) - 350  #vetor linha(poderia ser uma função ou pontos)
    pts = np.c_[matutils.mkvc(xx), matutils.mkvc(yy), matutils.mkvc(zz)]
    M = meshutils.refine_tree_xyz(M,
                                  pts,
                                  octree_levels=[1, 1, 1],
                                  method='surface',
                                  finalize=False)

    #
    M.finalize()
    print("\n the mesh has {} cells".format(M))

    ccMesh = M.gridCC
    print('indices:', np.size(ccMesh))
    ###

    conds = [1e-2, 1]
    sig = simpeg.Utils.ModelBuilder.defineBlock(M.gridCC,
                                                [-15000, 15000, -350],
                                                [15000, 1500, -150], conds)

    sig[M.gridCC[:, 2] > 0] = 1e-8
    sigBG = np.zeros(M.nC) + conds[1]
    sigBG[M.gridCC[:, 2] > 0] = 1e-8

    fig = plt.figure('slice: malha + modelo')
    ax = fig.add_subplot()
    collect_obj, = M.plotSlice(np.log(sig), normal='x', ax=ax, grid=True)
Exemplo n.º 12
0
    def setUp(self):

        np.random.seed(0)

        # First we need to define the direction of the inducing field
        # As a simple case, we pick a vertical inducing field of magnitude
        # 50,000nT.
        # From old convention, field orientation is given as an
        # azimuth from North (positive clockwise)
        # and dip from the horizontal (positive downward).
        H0 = (50000., 90., 0.)

        # Create a mesh
        h = [5, 5, 5]
        padDist = np.ones((3, 2)) * 100
        nCpad = [2, 4, 2]

        # Create grid of points for topography
        # Lets create a simple Gaussian topo and set the active cells
        [xx, yy] = np.meshgrid(np.linspace(-200., 200., 50),
                               np.linspace(-200., 200., 50))

        b = 100
        A = 50
        zz = A * np.exp(-0.5 * ((xx / b)**2. + (yy / b)**2.))

        # We would usually load a topofile
        topo = np.c_[Utils.mkvc(xx), Utils.mkvc(yy), Utils.mkvc(zz)]

        # Create and array of observation points
        xr = np.linspace(-100., 100., 20)
        yr = np.linspace(-100., 100., 20)
        X, Y = np.meshgrid(xr, yr)
        Z = A * np.exp(-0.5 * ((X / b)**2. + (Y / b)**2.)) + 5

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

        # self.mesh.finalize()
        self.mesh = meshutils.mesh_builder_xyz(
            xyzLoc,
            h,
            padding_distance=padDist,
            mesh_type='TREE',
        )

        self.mesh = meshutils.refine_tree_xyz(
            self.mesh,
            topo,
            method='surface',
            octree_levels=nCpad,
            octree_levels_padding=nCpad,
            finalize=True,
        )

        # Define an active cells from topo
        actv = Utils.surface2ind_topo(self.mesh, topo)
        nC = int(actv.sum())

        # We can now create a susceptibility model and generate data
        # Lets start with a simple block in half-space
        self.model = Utils.ModelBuilder.addBlock(self.mesh.gridCC,
                                                 np.zeros(self.mesh.nC),
                                                 np.r_[-20, -20, -15],
                                                 np.r_[20, 20, 20], 0.05)[actv]

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

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

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

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

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

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

        survey.dobs = data
        survey.std = wd

        # Create sensitivity weights from our linear forward operator
        rxLoc = survey.srcField.rxList[0].locs
        wr = prob.getJtJdiag(self.model)**0.5
        wr /= np.max(wr)

        # Create a regularization
        reg = Regularization.Sparse(self.mesh, indActive=actv, mapping=idenMap)
        reg.norms = np.c_[0, 0, 0, 0]
        reg.cell_weights = wr

        reg.mref = np.zeros(nC)

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

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

        invProb = InvProblem.BaseInvProblem(dmis, reg, opt, beta=1e+6)

        # Here is where the norms are applied
        # Use pick a treshold parameter empirically based on the distribution of
        #  model parameters
        IRLS = Directives.Update_IRLS(f_min_change=1e-3,
                                      maxIRLSiter=20,
                                      beta_tol=1e-1,
                                      betaSearch=False)
        update_Jacobi = Directives.UpdatePreconditioner()

        # saveOuput = Directives.SaveOutputEveryIteration()
        # saveModel.fileName = work_dir + out_dir + 'ModelSus'
        self.inv = Inversion.BaseInversion(invProb,
                                           directiveList=[IRLS, update_Jacobi])
Exemplo n.º 13
0
def createLocalProb(rxLoc, wrGlobal, ind_t, ind):
    # createLocalProb(rxLoc, wrGlobal, lims, ind)
    # Generate a problem, calculate/store sensitivities for
    # given data points

    # Grab the data for current tile
    # ind_t = np.all([rxLoc[:, 0] >= lims[0], rxLoc[:, 0] <= lims[1],
    #                 rxLoc[:, 1] >= lims[2], rxLoc[:, 1] <= lims[3],
    #                 surveyMask], axis=0)

    # Remember selected data in case of tile overlap
    surveyMask[ind_t] = False

    # Create new survey
    if input_dict["inversion_type"].lower() == 'grav':
        rxLoc_t = PF.BaseGrav.RxObs(rxLoc[ind_t, :])
        srcField = PF.BaseGrav.SrcField([rxLoc_t])
        survey_t = PF.BaseGrav.LinearSurvey(srcField)
        survey_t.dobs = survey.dobs[ind_t]
        survey_t.std = survey.std[ind_t]
        survey_t.ind = ind_t

        Utils.io_utils.writeUBCgravityObservations(outDir + "Tile" + str(ind) + '.dat', survey_t, survey_t.dobs)

    elif input_dict["inversion_type"].lower() in ['mag', 'mvi']:
        rxLoc_t = PF.BaseMag.RxObs(rxLoc[ind_t, :])
        srcField = PF.BaseMag.SrcField([rxLoc_t], param=survey.srcField.param)
        survey_t = PF.BaseMag.LinearSurvey(srcField)
        survey_t.dobs = survey.dobs[ind_t]
        survey_t.std = survey.std[ind_t]
        survey_t.ind = ind_t

        Utils.io_utils.writeUBCmagneticsObservations(outDir + "Tile" + str(ind) + '.dat', survey_t, survey_t.dobs)

    meshLocal = meshutils.mesh_builder_xyz(
        newTopo, core_cell_size, padding_distance=padding_distance, mesh_type='TREE', base_mesh=meshInput,
        depth_core=depth_core
    )

    if topo is not None:
        meshLocal = meshutils.refine_tree_xyz(
            meshLocal, topo, method='surface',
            octree_levels=octree_levels_topo, finalize=False
        )

    meshLocal = meshutils.refine_tree_xyz(
        meshLocal, rxLoc[ind_t, :], method='surface',
        max_distance=max_distance,
        octree_levels=octree_levels_obs,
        octree_levels_padding=octree_levels_padding,
        finalize=True,
    )

    # Need to find a way to compute sensitivities only for intersecting cells
    activeCells_t = np.ones(meshLocal.nC, dtype='bool')  # meshUtils.modelutils.activeTopoLayer(meshLocal, topo)

    # Create reduced identity map
    if input_dict["inversion_type"].lower() == 'mvi':
        nBlock = 3
    else:
        nBlock = 1

    tileMap = Maps.Tile((mesh, activeCells), (meshLocal, activeCells_t), nBlock=nBlock)

    activeCells_t = tileMap.activeLocal

    print(activeCells_t.sum(), meshLocal.nC)
    if input_dict["inversion_type"].lower() == 'grav':
        prob = PF.Gravity.GravityIntegral(
            meshLocal, rhoMap=tileMap, actInd=activeCells_t,
            parallelized=parallelized,
            Jpath=outDir + "Tile" + str(ind) + ".zarr",
            maxRAM=max_ram,
            n_cpu=n_cpu,
            )

    elif input_dict["inversion_type"].lower() == 'mag':
        prob = PF.Magnetics.MagneticIntegral(
            meshLocal, chiMap=tileMap, actInd=activeCells_t,
            parallelized=parallelized,
            Jpath=outDir + "Tile" + str(ind) + ".zarr",
            maxRAM=max_ram,
            n_cpu=n_cpu,
            )

    elif input_dict["inversion_type"].lower() == 'mvi':
        prob = PF.Magnetics.MagneticIntegral(
            meshLocal, chiMap=tileMap, actInd=activeCells_t,
            parallelized=parallelized,
            Jpath=outDir + "Tile" + str(ind) + ".zarr",
            maxRAM=max_ram,
            modelType='vector',
            n_cpu=n_cpu
        )

    survey_t.pair(prob)

    # Write out local active and obs for validation
    Mesh.TreeMesh.writeUBC(
      meshLocal, outDir + 'Octree_Tile' + str(ind) + '.msh',
      models={outDir + 'ActiveGlobal_Tile' + str(ind) + ' .act': activeCells_t}
    )

    # Data misfit function
    dmis = DataMisfit.l2_DataMisfit(survey_t)
    dmis.W = 1./survey_t.std

    wr = prob.getJtJdiag(np.ones(tileMap.shape[1]), W=dmis.W)

    wrGlobal += wr

    del meshLocal

    # Create combo misfit function
    return dmis
h = [40, 40, 20]
pads = [[0, 0], [0, 0],[2000, 0]]
octreeTopo = [0,5,10,10]
octreeObs = [5, 5]
maxDist = 100
depth_core = 2500

mesh = meshutils.mesh_builder_xyz(
    topo, h,
    padding_distance=pads,
    mesh_type='TREE',
    depth_core=depth_core,
)

mesh = meshutils.refine_tree_xyz(mesh, topo,
                                 octree_levels=octreeTopo,
                                 method='surface', finalize=False)

mesh = meshutils.refine_tree_xyz(mesh, xyz,
                                 octree_levels=octreeObs,
                                 method='surface',
                                 max_distance=maxDist,
                                 finalize=True)

actv = modelutils.surface2ind_topo(mesh, topo, gridLoc='N')

###############################################################################

def plot_pyvista(mesh, model, actv, interactive=False, use_panel=True, clim=None):
    # Convert TreeMesh to VTK
    dataset = mesh.toVTK()
Exemplo n.º 15
0
    def createLocalProb(rxLoc, wrGlobal, lims, ind):
        # createLocalProb(rxLoc, wrGlobal, lims, ind)
        # Generate a problem, calculate/store sensitivities for
        # given data points

        # Grab the data for current tile
        ind_t = np.all([
            rxLoc[:, 0] >= lims[0], rxLoc[:, 0] <= lims[1],
            rxLoc[:, 1] >= lims[2], rxLoc[:, 1] <= lims[3], surveyMask
        ],
                       axis=0)

        # Remember selected data in case of tile overlap
        surveyMask[ind_t] = False

        # Create new survey
        if driver["dataFile"][0] == 'GRAV':
            rxLoc_t = PF.BaseGrav.RxObs(rxLoc[ind_t, :])
            srcField = PF.BaseGrav.SrcField([rxLoc_t])
            survey_t = PF.BaseGrav.LinearSurvey(srcField)
            survey_t.dobs = survey.dobs[ind_t]
            survey_t.std = survey.std[ind_t]
            survey_t.ind = ind_t

            Utils.io_utils.writeUBCgravityObservations(
                workDir + dsep + outDir + "Tile" + str(ind) + '.dat', survey_t,
                survey_t.dobs)

        elif driver["dataFile"][0] == 'MAG':
            rxLoc_t = PF.BaseMag.RxObs(rxLoc[ind_t, :])
            srcField = PF.BaseMag.SrcField([rxLoc_t],
                                           param=survey.srcField.param)
            survey_t = PF.BaseMag.LinearSurvey(srcField)
            survey_t.dobs = survey.dobs[ind_t]
            survey_t.std = survey.std[ind_t]
            survey_t.ind = ind_t

            Utils.io_utils.writeUBCmagneticsObservations(
                workDir + dsep + outDir + "Tile" + str(ind) + '.dat', survey_t,
                survey_t.dobs)

        meshLocal = meshutils.mesh_builder_xyz(
            newTopo,
            h,
            padDist,
            mesh_type='TREE',
            depth_core=depth_core,
            base_mesh=meshInput,
        )

        if topo is not None:
            meshLocal = meshutils.refine_tree_xyz(meshLocal,
                                                  topo,
                                                  method='surface',
                                                  octree_levels=octreeTopo,
                                                  finalize=False)

        # Refine the mesh around loc
        meshLocal = meshutils.refine_tree_xyz(
            meshLocal,
            newTopo[ind_t, :],
            method='surface',
            octree_levels=octreeObs,
            octree_levels_padding=octree_levels_padding,
            finalize=True)

        # Need to find a way to compute sensitivities only for intersecting cells
        activeCells_t = np.ones(
            meshLocal.nC,
            dtype='bool')  # meshmeshutils.activeTopoLayer(meshLocal, topo)

        # Create reduced identity map
        tileMap = Maps.Tile((mesh, activeCells), (meshLocal, activeCells_t))

        activeCells_t = tileMap.activeLocal

        print(activeCells_t.sum(), meshLocal.nC)
        if driver["dataFile"][0] == 'GRAV':
            prob = PF.Gravity.GravityIntegral(meshLocal,
                                              rhoMap=tileMap,
                                              actInd=activeCells_t,
                                              parallelized=parallelized,
                                              Jpath=workDir + dsep + outDir +
                                              "Tile" + str(ind) + ".zarr",
                                              maxRAM=maxRAM / n_cpu,
                                              n_cpu=n_cpu,
                                              n_chunks=n_chunks)

        elif driver["dataFile"][0] == 'MAG':
            prob = PF.Magnetics.MagneticIntegral(
                meshLocal,
                chiMap=tileMap,
                actInd=activeCells_t,
                parallelized=parallelized,
                Jpath=workDir + dsep + outDir + "Tile" + str(ind) + ".zarr",
                maxRAM=maxRAM / n_cpu,
                n_cpu=n_cpu,
                n_chunks=n_chunks)

        survey_t.pair(prob)

        # Write out local active and obs for validation
        Mesh.TreeMesh.writeUBC(
            meshLocal,
            workDir + dsep + outDir + dsep + 'Octree_Tile' + str(ind) + '.msh',
            models={
                workDir + dsep + outDir + dsep + 'ActiveGlobal_Tile' + str(ind) + ' .act':
                activeCells_t
            })

        if driver["dataFile"][0] == 'GRAV':

            Utils.io_utils.writeUBCgravityObservations(
                workDir + dsep + outDir + dsep + 'Tile' + str(ind) + '.dat',
                survey_t, survey_t.dobs)

        elif driver["dataFile"][0] == 'MAG':

            Utils.io_utils.writeUBCmagneticsObservations(
                workDir + dsep + outDir + dsep + 'Tile' + str(ind) + '.dat',
                survey_t, survey_t.dobs)

        # Data misfit function
        dmis = DataMisfit.l2_DataMisfit(survey_t)
        dmis.W = 1. / survey_t.std

        wr = prob.getJtJdiag(np.ones(tileMap.P.shape[1]), W=dmis.W)

        wrGlobal += wr

        del meshLocal

        # Create combo misfit function
        return dmis
Exemplo n.º 16
0
padDist = np.r_[np.c_[padLen, padLen], np.c_[padLen, padLen], np.c_[padLen, 0]]

print("Creating Global Octree")
mesh = meshutils.mesh_builder_xyz(
    newTopo,
    h,
    padDist,
    mesh_type='TREE',
    depth_core=depth_core,
    base_mesh=meshInput,
)

if topo is not None:
    mesh = meshutils.refine_tree_xyz(mesh,
                                     topo,
                                     method='surface',
                                     octree_levels=octreeTopo,
                                     finalize=False)

mesh = meshutils.refine_tree_xyz(mesh,
                                 newTopo,
                                 method='surface',
                                 octree_levels=octreeObs,
                                 octree_levels_padding=octree_levels_padding,
                                 finalize=True)

# Compute active cells
activeCells = Utils.surface2ind_topo(mesh, topo, gridLoc='CC')

#    activeCells = meshutils.activeTopoLayer(mesh, topo)
Exemplo n.º 17
0
    def setUp(self):

        np.random.seed(0)

        # First we need to define the direction of the inducing field
        # As a simple case, we pick a vertical inducing field of magnitude
        # 50,000nT.
        # From old convention, field orientation is given as an
        # azimuth from North (positive clockwise)
        # and dip from the horizontal (positive downward).
        H0 = (50000.0, 90.0, 0.0)

        # Create a mesh
        h = [5, 5, 5]
        padDist = np.ones((3, 2)) * 100
        nCpad = [2, 4, 2]

        # Create grid of points for topography
        # Lets create a simple Gaussian topo and set the active cells
        [xx, yy] = np.meshgrid(np.linspace(-200.0, 200.0, 50),
                               np.linspace(-200.0, 200.0, 50))

        b = 100
        A = 50
        zz = A * np.exp(-0.5 * ((xx / b)**2.0 + (yy / b)**2.0))

        # We would usually load a topofile
        topo = np.c_[utils.mkvc(xx), utils.mkvc(yy), utils.mkvc(zz)]

        # Create and array of observation points
        xr = np.linspace(-100.0, 100.0, 20)
        yr = np.linspace(-100.0, 100.0, 20)
        X, Y = np.meshgrid(xr, yr)
        Z = A * np.exp(-0.5 * ((X / b)**2.0 + (Y / b)**2.0)) + 5

        # Create a MAGsurvey
        xyzLoc = np.c_[utils.mkvc(X.T), utils.mkvc(Y.T), utils.mkvc(Z.T)]
        rxLoc = mag.Point(xyzLoc)
        srcField = mag.SourceField([rxLoc], parameters=H0)
        survey = mag.Survey(srcField)

        # self.mesh.finalize()
        self.mesh = meshutils.mesh_builder_xyz(
            xyzLoc,
            h,
            padding_distance=padDist,
            mesh_type="TREE",
        )

        self.mesh = meshutils.refine_tree_xyz(
            self.mesh,
            topo,
            method="surface",
            octree_levels=nCpad,
            octree_levels_padding=nCpad,
            finalize=True,
        )

        # Define an active cells from topo
        actv = utils.surface2ind_topo(self.mesh, topo)
        nC = int(actv.sum())

        # We can now create a susceptibility model and generate data
        # Lets start with a simple block in half-space
        self.model = utils.model_builder.addBlock(
            self.mesh.gridCC,
            np.zeros(self.mesh.nC),
            np.r_[-20, -20, -15],
            np.r_[20, 20, 20],
            0.05,
        )[actv]

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

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

        # Create the forward model operator
        sim = mag.Simulation3DIntegral(
            self.mesh,
            survey=survey,
            chiMap=idenMap,
            actInd=actv,
            store_sensitivities="ram",
        )
        self.sim = sim
        data = sim.make_synthetic_data(self.model,
                                       relative_error=0.0,
                                       noise_floor=1.0,
                                       add_noise=True)

        # Create a regularization
        reg = regularization.Sparse(self.mesh, indActive=actv, mapping=idenMap)
        reg.norms = np.c_[0, 0, 0, 0]

        reg.mref = np.zeros(nC)

        # Data misfit function
        dmis = data_misfit.L2DataMisfit(simulation=sim, data=data)

        # Add directives to the inversion
        opt = optimization.ProjectedGNCG(
            maxIter=10,
            lower=0.0,
            upper=10.0,
            maxIterLS=5,
            maxIterCG=5,
            tolCG=1e-4,
            stepOffBoundsFact=1e-4,
        )

        invProb = inverse_problem.BaseInvProblem(dmis, reg, opt, beta=1e6)

        # Here is where the norms are applied
        # Use pick a treshold parameter empirically based on the distribution of
        #  model parameters
        IRLS = directives.Update_IRLS(f_min_change=1e-3,
                                      max_irls_iterations=20,
                                      beta_tol=1e-1,
                                      beta_search=False)
        update_Jacobi = directives.UpdatePreconditioner()
        sensitivity_weights = directives.UpdateSensitivityWeights()
        self.inv = inversion.BaseInversion(
            invProb, directiveList=[IRLS, sensitivity_weights, update_Jacobi])
Exemplo n.º 18
0
if add_data_padding or decimate_to_mesh:
    # Scipy.interpolate flags divide-by-zero and invalid value errors when making
    # the mesh. They don't affect the result, so we suppress them temporarily.
    old_settings = np.seterr(divide='ignore', invalid='ignore')
    # Create a quadtree mesh using the same params as the full mesh
    decimate_mesh = meshutils.mesh_builder_xyz(
        survey.rxLoc[:, :2],
        core_cell_size[:2],
        padding_distance=padding_distance[:2],
        mesh_type='tree'
    )

    decimate_mesh = meshutils.refine_tree_xyz(
        decimate_mesh, survey.rxLoc[:, :2], method='surface',
        max_distance=max_distance,
        octree_levels=octree_levels_obs,
        octree_levels_padding=octree_levels_padding,
        finalize=True,
    )
    np.seterr(**old_settings)

    if decimate_to_mesh:
        print("Decimating the whole survey to the mesh")
        survey, data_trend = decimate_survey_to_mesh(decimate_mesh,
                                                     data_trend, survey)
    elif add_data_padding:
        print("Decimating the padding points to the mesh")
        survey, data_trend = decimate_survey_to_mesh(decimate_mesh,
                                                     data_trend, survey,
                                                     survey)
    def setUp(self):
        # We will assume a vertical inducing field
        H0 = (50000., 90., 0.)

        # The magnetization is set along a different direction (induced + remanence)
        M = np.array([90., 0.])

        # Block with an effective susceptibility
        chi_e = 0.05

        # Create grid of points for topography
        # Lets create a simple Gaussian topo and set the active cells
        [xx, yy] = np.meshgrid(np.linspace(-200, 200, 50),
                               np.linspace(-200, 200, 50))
        b = 100
        A = 50
        zz = A * np.exp(-0.5 * ((xx / b)**2. + (yy / b)**2.))
        topo = np.c_[Utils.mkvc(xx), Utils.mkvc(yy), Utils.mkvc(zz)]

        # Create and array of observation points
        xr = np.linspace(-100., 100., 20)
        yr = np.linspace(-100., 100., 20)
        X, Y = np.meshgrid(xr, yr)
        Z = A * np.exp(-0.5 * ((X / b)**2. + (Y / b)**2.)) + 5

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

        # Create a mesh
        h = [5, 5, 5]
        padDist = np.ones((3, 2)) * 100
        nCpad = [4, 4, 2]

        self.mesh = meshutils.mesh_builder_xyz(
            xyzLoc,
            h,
            padding_distance=padDist,
            mesh_type='TREE',
        )

        self.mesh = meshutils.refine_tree_xyz(
            self.mesh,
            topo,
            method='surface',
            octree_levels=nCpad,
            octree_levels_padding=nCpad,
            finalize=True,
        )
        # Define an active cells from topo
        actv = Utils.surface2ind_topo(self.mesh, topo)
        nC = int(actv.sum())

        # Convert the inclination declination to vector in Cartesian
        M_xyz = Utils.matutils.dip_azimuth2cartesian(
            np.ones(nC) * M[0],
            np.ones(nC) * M[1])

        # Get the indicies of the magnetized block
        ind = Utils.ModelBuilder.getIndicesBlock(
            np.r_[-20, -20, -15],
            np.r_[20, 20, 20],
            self.mesh.gridCC,
        )[0]

        # Assign magnetization value, inducing field strength will
        # be applied in by the :class:`SimPEG.PF.Magnetics` problem
        model = np.zeros(self.mesh.nC)
        model[ind] = chi_e

        # Remove air cells
        self.model = model[actv]

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

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

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

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

        # Compute some data and add some random noise
        data = prob.fields(self.model)

        # Split the data in components
        nD = xyzLoc.shape[0]

        std = 5  # nT
        data += np.random.randn(nD) * std
        wd = np.ones(nD) * std

        # Assigne data and uncertainties to the survey
        survey.dobs = data
        survey.std = wd

        ######################################################################
        # Equivalent Source

        # Get the active cells for equivalent source is the top only
        surf = Utils.modelutils.surface_layer_index(self.mesh, topo)

        # Get the layer of cells directyl below topo
        nC = np.count_nonzero(surf)  # Number of active cells

        # Create active map to go from reduce set to full
        surfMap = Maps.InjectActiveCells(self.mesh, surf, np.nan)

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

        # Create static map
        prob = PF.Magnetics.MagneticIntegral(self.mesh,
                                             chiMap=idenMap,
                                             actInd=surf,
                                             parallelized=False,
                                             equiSourceLayer=True)

        prob.solverOpts['accuracyTol'] = 1e-4

        # Pair the survey and problem
        if survey.ispaired:
            survey.unpair()
        survey.pair(prob)

        # Create a regularization function, in this case l2l2
        reg = Regularization.Sparse(self.mesh,
                                    indActive=surf,
                                    mapping=Maps.IdentityMap(nP=nC),
                                    scaledIRLS=False)
        reg.mref = np.zeros(nC)

        # Specify how the optimization will proceed,
        # set susceptibility bounds to inf
        opt = Optimization.ProjectedGNCG(maxIter=20,
                                         lower=-np.inf,
                                         upper=np.inf,
                                         maxIterLS=20,
                                         maxIterCG=20,
                                         tolCG=1e-3)

        # Define misfit function (obs-calc)
        dmis = DataMisfit.l2_DataMisfit(survey)
        dmis.W = 1. / survey.std

        # Create the default L2 inverse problem from the above objects
        invProb = InvProblem.BaseInvProblem(dmis, reg, opt)

        # Specify how the initial beta is found
        betaest = Directives.BetaEstimate_ByEig()

        # Target misfit to stop the inversion,
        # try to fit as much as possible of the signal,
        # we don't want to lose anything
        IRLS = Directives.Update_IRLS(f_min_change=1e-3,
                                      minGNiter=1,
                                      beta_tol=1e-1)
        update_Jacobi = Directives.UpdatePreconditioner()
        # Put all the parts together
        inv = Inversion.BaseInversion(
            invProb, directiveList=[betaest, IRLS, update_Jacobi])

        # Run the equivalent source inversion
        mstart = np.ones(nC) * 1e-4
        mrec = inv.run(mstart)

        # Won't store the sensitivity and output 'xyz' data.
        prob.forwardOnly = True
        prob.rx_type = 'xyz'
        prob._G = None
        prob.modelType = 'amplitude'
        prob.model = mrec
        pred = prob.fields(mrec)

        bx = pred[:nD]
        by = pred[nD:2 * nD]
        bz = pred[2 * nD:]

        bAmp = (bx**2. + by**2. + bz**2.)**0.5

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

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

        self.mstart = np.ones(nC) * 1e-4

        # Create the forward model operator
        prob = PF.Magnetics.MagneticIntegral(self.mesh,
                                             chiMap=idenMap,
                                             actInd=actv,
                                             modelType='amplitude',
                                             rx_type='xyz')
        prob.model = self.mstart
        # Change the survey to xyz components
        surveyAmp = PF.BaseMag.LinearSurvey(survey.srcField)

        # Pair the survey and problem
        surveyAmp.pair(prob)
        # Create a regularization function, in this case l2l2
        wr = np.sum(prob.G**2., axis=0)**0.5
        wr /= np.max(wr)
        # Re-set the observations to |B|
        surveyAmp.dobs = bAmp
        surveyAmp.std = wd

        # Create a sparse regularization
        reg = Regularization.Sparse(self.mesh, indActive=actv, mapping=idenMap)
        reg.norms = np.c_[0, 0, 0, 0]
        reg.mref = np.zeros(nC)
        reg.cell_weights = wr
        # Data misfit function
        dmis = DataMisfit.l2_DataMisfit(surveyAmp)
        dmis.W = 1. / surveyAmp.std

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

        invProb = InvProblem.BaseInvProblem(dmis, reg, opt)

        # Here is the list of directives
        betaest = Directives.BetaEstimate_ByEig()

        # Specify the sparse norms
        IRLS = Directives.Update_IRLS(f_min_change=1e-3,
                                      minGNiter=1,
                                      coolingRate=1,
                                      betaSearch=False)

        # The sensitivity weights are update between each iteration.
        update_SensWeight = Directives.UpdateSensitivityWeights()
        update_Jacobi = Directives.UpdatePreconditioner()

        # Put all together
        self.inv = Inversion.BaseInversion(
            invProb,
            directiveList=[betaest, IRLS, update_SensWeight, update_Jacobi])
Exemplo n.º 20
0
    def createLocalProb(rxLoc, wrGlobal, lims, ind):

        # Grab the data for current tile
        ind_t = np.all([
            rxLoc[:, 0] >= lims[0], rxLoc[:, 0] <= lims[1],
            rxLoc[:, 1] >= lims[2], rxLoc[:, 1] <= lims[3], surveyMask
        ],
                       axis=0)

        # Remember selected data in case of tile overlap
        surveyMask[ind_t] = False

        # Create new survey
        rxLoc_t = PF.BaseMag.RxObs(rxLoc[ind_t, :])
        srcField = PF.BaseMag.SrcField([rxLoc_t], param=survey.srcField.param)
        survey_t = PF.BaseMag.LinearSurvey(srcField)
        survey_t.dobs = survey.dobs[ind_t]
        survey_t.std = survey.std[ind_t]
        survey_t.ind = ind_t

        meshLocal = meshutils.mesh_builder_xyz(topo,
                                               h,
                                               padding_distance=padDist,
                                               mesh_type='TREE',
                                               base_mesh=meshInput,
                                               depth_core=depth_core)

        if topo is not None:
            meshLocal = meshutils.refine_tree_xyz(meshLocal,
                                                  topo,
                                                  method='surface',
                                                  octree_levels=octreeTopo,
                                                  finalize=False)

        meshLocal = meshutils.refine_tree_xyz(
            meshLocal,
            rxLoc[ind_t, :],
            method='surface',
            max_distance=maxDist,
            octree_levels=octreeObs,
            octree_levels_padding=octreeObs_XY,
            finalize=True,
        )

        actv_t = np.ones(meshLocal.nC, dtype='bool')

        # Create reduced identity map
        tileMap = Maps.Tile((mesh, actv), (meshLocal, actv_t))

        actv_t = tileMap.activeLocal

        print(actv_t.sum(), meshLocal.nC)
        # Create the forward model operator
        prob = PF.Magnetics.MagneticIntegral(meshLocal,
                                             chiMap=tileMap,
                                             actInd=actv_t,
                                             parallelized='dask',
                                             Jpath=work_dir + out_dir +
                                             "Tile" + str(ind) + ".zarr",
                                             store_zarr=True)

        survey_t.pair(prob)

        # Data misfit function
        dmis = DataMisfit.l2_DataMisfit(survey_t)
        dmis.W = 1. / survey_t.std

        wr = prob.getJtJdiag(np.ones(tileMap.P.shape[1]), W=dmis.W)
        localMap = Maps.InjectActiveCells(meshLocal, actv_t, 1e-8)
        Mesh.TreeMesh.writeUBC(
            mesh,
            work_dir + out_dir + 'OctreeMesh' + str(tt) + '.msh',
            models={
                work_dir + out_dir + 'Wr_' + str(tt) + '.act': actvMap * wr
            })

        Mesh.TreeMesh.writeUBC(
            meshLocal,
            work_dir + out_dir + 'OctreeMesh' + str(tt) + '.msh',
            models={
                work_dir + out_dir + 'Wr_' + str(tt) + '.act':
                localMap * tileMap * wr
            })
        #    localMap = Maps.InjectActiveCells(meshLocal, actv_t, 1e-8)
        #    Mesh.TreeMesh.writeUBC(
        #                      meshLocal, work_dir + out_dir + 'OctreeMesh' + str(tt) + '.msh',
        #                      models={work_dir + out_dir + 'Wr_' + str(tt) + '.act': localMap*wr}
        #                    )
        #
        wrGlobal += wr

        del meshLocal

        # Create combo misfit function
        return dmis, wrGlobal