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

        dh = 1.0
        nx = 16
        ny = 16
        nz = 16

        hx = [(dh, nx)]
        hy = [(dh, ny)]
        hz = [(dh, nz)]
        mesh = TreeMesh([hx, hy, hz], "CNN")
        mesh.insert_cells([5, 5, 5], [4])

        # reg
        actv = np.ones(len(mesh), dtype=bool)

        # maps
        wires = maps.Wires(("m1", mesh.nC), ("m2", mesh.nC))

        cross_grad = regularization.CrossGradient(mesh,
                                                  wire_map=wires,
                                                  indActive=actv)

        self.mesh = mesh
        self.cross_grad = cross_grad
Пример #2
0
    def setUp(self):

        dh = 1.0
        nx = 16
        ny = 16
        nz = 16

        hx = [(dh, nx)]
        hy = [(dh, ny)]
        hz = [(dh, nz)]
        mesh = TreeMesh([hx, hy, hz], "CNN")
        mesh.insert_cells([5, 5, 5], [4])

        # reg
        actv = np.ones(len(mesh), dtype=bool)

        # maps
        wires = maps.Wires(("m1", mesh.nC), ("m2", mesh.nC))

        jtv = regularization.JointTotalVariation(mesh,
                                                 wire_map=wires,
                                                 indActive=actv)

        self.mesh = mesh
        self.jtv = jtv
        self.x0 = np.random.rand(len(mesh) * 2)
Пример #3
0
def baseline_octree_mesh(N, delta):
    """
    Set up a basic regular Cartesian octree mesh as a default; this can then
    be refined once we specify model features or voxelizations, so it is NOT
    currently finalized
    :param N: length of one edge of a cubical volume in cells
    :param delta: length of one edge of a mesh cube
    :return: TreeMesh instance
    """
    h = delta * np.ones(N)
    mesh = TreeMesh([h, h, h], x0="CCC")
    mesh.refine(3, finalize=False)
    return mesh
Пример #4
0
def make_example_mesh():

    # Base mesh parameters
    dh = 5.0  # base cell size
    nbc = 32  # total width of mesh in terms of number of base mesh cells
    h = dh * np.ones(nbc)

    mesh = TreeMesh([h, h, h], x0="CCC")

    # Refine to largest possible cell size
    mesh.refine(3, finalize=False)

    return mesh
Пример #5
0
def create_octree_mesh(domain, cellwidth, points, method='surface'):
    """Creates an octree mesh and refines at specified points.

        Parameters
        ----------
        domain : tuple
            ((xmin, xmax),(ymin, ymax),(zmin, zmax)) coordinates of the domain
        cellwidth : int
            width of smallest cell in the mesh
        points : np.ndarray
            array of points that will be refined in the mesh
        method : string
            the discretize method that will be used for refinement. Available are 'surface',
            'radial' and 'box'


        Returns
        -------
        discretize.mesh
            a mesh where the points are refined
    """

    # domain dimensions
    x_length = np.abs(domain[0][0] - domain[0][1])
    y_length = np.abs(domain[1][0] - domain[1][1])
    z_length = np.abs(domain[2][0] - domain[2][1])

    # number of cells needed in each dimension
    nbx = 2**int(np.ceil(np.log(x_length / cellwidth) / np.log(2.0)))
    nby = 2**int(np.ceil(np.log(y_length / cellwidth) / np.log(2.0)))
    nbz = 2**int(np.ceil(np.log(z_length / cellwidth) / np.log(2.0)))

    # define base mesh
    hx = cellwidth * np.ones(nbx)
    hy = cellwidth * np.ones(nby)
    hz = cellwidth * np.ones(nbz)
    mesh = TreeMesh([hx, hy, hz],
                    origin=[domain[0][0], domain[1][0], domain[2][0]])

    # refine mesh around the given surface points
    mesh = refine_tree_xyz(mesh,
                           points,
                           octree_levels=[1, 1, 1],
                           method=method,
                           max_distance=1,
                           finalize=False)

    return mesh
Пример #6
0
# 

# Defining domain side and minimum cell size
dh = 25.0  # base cell width
dom_width_x = 6000.0  # domain width x
dom_width_y = 6000.0  # domain width y
dom_width_z = 4000.0  # domain width z
nbcx = 2 ** int(np.round(np.log(dom_width_x / dh) / np.log(2.0)))  # num. base cells x
nbcy = 2 ** int(np.round(np.log(dom_width_y / dh) / np.log(2.0)))  # num. base cells y
nbcz = 2 ** int(np.round(np.log(dom_width_z / dh) / np.log(2.0)))  # num. base cells z

# Define the base mesh
hx = [(dh, nbcx)]
hy = [(dh, nbcy)]
hz = [(dh, nbcz)]
mesh = TreeMesh([hx, hy, hz], x0="CCN")

# Mesh refinement based on topography
k = np.sqrt(np.sum(topo_xyz[:, 0:2]**2, axis=1)) < 1200
mesh = refine_tree_xyz(
    mesh, topo_xyz[k, :], octree_levels=[0, 6, 8], method="surface", finalize=False
)

# Mesh refinement near sources and receivers. 
electrode_locations = np.r_[
    dc_survey.locations_a, dc_survey.locations_b, dc_survey.locations_m, dc_survey.locations_n
]
unique_locations = np.unique(electrode_locations, axis=0)
mesh = refine_tree_xyz(
    mesh, unique_locations, octree_levels=[4, 6, 4], method="radial", finalize=False
)
Пример #7
0
import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle
from SimPEG.Utils import mkvc, modelutils, PlotUtils, plot2Ddata
import pyvista

###############################################################################
# Load the Data
# +++++++++++++
#
# Load the mesh and data from the previous example

grav_data = pyvista.read(gdc19.get_gravity_path('grav_obs.vtk'))
xyz = grav_data.points
survey = pyvista.PolyData(xyz)

mesh = TreeMesh.readUBC(gdc19.get_gravity_path('mesh.msh'))
actv = mesh.readModelUBC(gdc19.get_gravity_path('actv.mod'))

###############################################################################
# Tile the Problem
# ++++++++++++++++
rxLoc = xyz
tiles, binCount, labels = modelutils.tileSurveyPoints(rxLoc, 14)

# Grab the smallest bin and generate a temporary mesh
indMin = np.argmin(binCount)

X1, Y1 = tiles[0][:, 0], tiles[0][:, 1]
X2, Y2 = tiles[1][:, 0], tiles[1][:, 1]

nTiles = X1.shape[0]
Пример #8
0
# ------------------
#
# Here, we create the OcTree mesh that will be used to predict both DC
# resistivity and IP data.
#

dh = 10.0  # base cell width
dom_width_x = 2400.0  # domain width x
dom_width_z = 1200.0  # domain width z
nbcx = 2 ** int(np.round(np.log(dom_width_x / dh) / np.log(2.0)))  # num. base cells x
nbcz = 2 ** int(np.round(np.log(dom_width_z / dh) / np.log(2.0)))  # num. base cells z

# Define the base mesh
hx = [(dh, nbcx)]
hz = [(dh, nbcz)]
mesh = TreeMesh([hx, hz], x0="CN")

# Mesh refinement based on topography
mesh = refine_tree_xyz(
    mesh, topo_xyz[:, [0, 2]], octree_levels=[1], method="surface", finalize=False
)

# Mesh refinement near transmitters and receivers
electrode_locations = np.r_[
    survey.locations_a, survey.locations_b, survey.locations_m, survey.locations_n
]

unique_locations = np.unique(electrode_locations, axis=0)

mesh = refine_tree_xyz(
    mesh, unique_locations, octree_levels=[2, 4], method="radial", finalize=False
Пример #9
0
# Here, we create the Tree mesh that will be used to predict both DC
# resistivity and IP data.
#

dh = 10.0  # base cell width
dom_width_x = 2400.0  # domain width x
dom_width_z = 1200.0  # domain width z
nbcx = 2**int(np.round(np.log(dom_width_x / dh) /
                       np.log(2.0)))  # num. base cells x
nbcz = 2**int(np.round(np.log(dom_width_z / dh) /
                       np.log(2.0)))  # num. base cells z

# Define the base mesh
hx = [(dh, nbcx)]
hz = [(dh, nbcz)]
mesh = TreeMesh([hx, hz], x0="CN")

# Mesh refinement based on topography
mesh = refine_tree_xyz(mesh,
                       topo_xyz[:, [0, 2]],
                       octree_levels=[1],
                       method="surface",
                       finalize=False)

# Mesh refinement near transmitters and receivers
electrode_locations = np.r_[survey.locations_a, survey.locations_b,
                            survey.locations_m, survey.locations_n]

unique_locations = np.unique(electrode_locations, axis=0)

mesh = refine_tree_xyz(mesh,
Пример #10
0
dz = 5  # minimum cell width (base mesh cell width) in z

x_length = 240.0  # domain width in x
y_length = 240.0  # domain width in y
z_length = 120.0  # domain width in y

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

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

# Refine based on surface topography
mesh = refine_tree_xyz(mesh,
                       xyz_topo,
                       octree_levels=[2, 2],
                       method="surface",
                       finalize=False)

# Refine box base on region of interest
xp, yp, zp = np.meshgrid([-100.0, 100.0], [-100.0, 100.0], [-80.0, 0.0])
xyz = np.c_[mkvc(xp), mkvc(yp), mkvc(zp)]

mesh = refine_tree_xyz(mesh,
                       xyz,
                       octree_levels=[2, 2],
Пример #11
0
dh = 40.0  # base cell width
dom_width_x = 10000.0  # domain width x
dom_width_y = 10000.0  # domain width y
dom_width_z = 2000.0  # domain width z
nbcx = 2**int(np.round(np.log(dom_width_x / dh) /
                       np.log(2.0)))  # num. base cells x
nbcy = 2**int(np.round(np.log(dom_width_y / dh) /
                       np.log(2.0)))  # num. base cells y
nbcz = 2**int(np.round(np.log(dom_width_z / dh) /
                       np.log(2.0)))  # num. base cells z

# Define the base mesh
hx = [(dh, nbcx)]
hy = [(dh, nbcy)]
hz = [(dh, nbcz)]
mesh = TreeMesh([hx, hy, hz], x0="CCN")

# Mesh refinement based on topography
mesh = refine_tree_xyz(mesh,
                       xyz_topo,
                       octree_levels=[0, 0, 1],
                       method="surface",
                       finalize=False)

# Mesh refinement near sources and receivers. First we need to obtain the
# set of unique electrode locations.
electrode_locations = np.r_[survey.locations_a, survey.locations_b,
                            survey.locations_m, survey.locations_n]

unique_locations = np.unique(electrode_locations, axis=0)
Пример #12
0
# Here, we create the OcTree mesh that will be used to predict both DC
# resistivity and IP data.
#

dh = 4  # base cell width
dom_width_x = 3200.0  # domain width x
dom_width_z = 2400.0  # domain width z
nbcx = 2**int(np.round(np.log(dom_width_x / dh) /
                       np.log(2.0)))  # num. base cells x
nbcz = 2**int(np.round(np.log(dom_width_z / dh) /
                       np.log(2.0)))  # num. base cells z

# Define the base mesh
hx = [(dh, nbcx)]
hz = [(dh, nbcz)]
mesh = TreeMesh([hx, hz], x0="CN")

# Mesh refinement based on topography
mesh = refine_tree_xyz(
    mesh,
    topo_xyz[:, [0, 2]],
    octree_levels=[0, 0, 4, 4],
    method="surface",
    finalize=False,
)

# Mesh refinement near transmitters and receivers. First we need to obtain the
# set of unique electrode locations.
electrode_locations = np.c_[dc_survey.locations_a, dc_survey.locations_b,
                            dc_survey.locations_m, dc_survey.locations_n, ]
Пример #13
0
# We chose to design a coarser mesh to decrease the run time.
# When designing a mesh to solve practical frequency domain problems:
#
#     - Your smallest cell size should be 10%-20% the size of your smallest skin depth
#     - The thickness of your padding needs to be 2-3 times biggest than your largest skin depth
#     - The skin depth is ~500*np.sqrt(rho/f)
#
#

dh = 25.0  # base cell width
dom_width = 3000.0  # domain width
nbc = 2**int(np.round(np.log(dom_width / dh) / np.log(2.0)))  # num. base cells

# Define the base mesh
h = [(dh, nbc)]
mesh = TreeMesh([h, h, h], x0="CCC")

# Mesh refinement based on topography
mesh = refine_tree_xyz(mesh,
                       xyz_topo,
                       octree_levels=[0, 0, 0, 1],
                       method="surface",
                       finalize=False)

# Mesh refinement near transmitters and receivers
mesh = refine_tree_xyz(mesh,
                       receiver_locations,
                       octree_levels=[2, 4],
                       method="radial",
                       finalize=False)
Пример #14
0
# Here, we create the Tree mesh that will be used to predict both DC
# resistivity and IP data.
#

dh = 10.0  # base cell width
dom_width_x = 2400.0  # domain width x
dom_width_z = 1200.0  # domain width z
nbcx = 2**int(np.round(np.log(dom_width_x / dh) /
                       np.log(2.0)))  # num. base cells x
nbcz = 2**int(np.round(np.log(dom_width_z / dh) /
                       np.log(2.0)))  # num. base cells z

# Define the base mesh
hx = [(dh, nbcx)]
hz = [(dh, nbcz)]
mesh = TreeMesh([hx, hz], x0="CN")

# Mesh refinement based on topography
mesh = refine_tree_xyz(mesh,
                       topo_xyz[:, [0, 2]],
                       octree_levels=[1],
                       method="surface",
                       finalize=False)

# Mesh refinement near transmitters and receivers
electrode_locations = np.r_[dc_survey.locations_a, dc_survey.locations_b,
                            dc_survey.locations_m, dc_survey.locations_n, ]

unique_locations = np.unique(electrode_locations, axis=0)

mesh = refine_tree_xyz(mesh,
Пример #15
0
# We chose to design a coarser mesh to decrease the run time.
# When designing a mesh to solve practical frequency domain problems:
#
#     - Your smallest cell size should be 10%-20% the size of your smallest skin depth
#     - The thickness of your padding needs to be 2-3 times biggest than your largest skin depth
#     - The skin depth is ~500*np.sqrt(rho/f)
#
#

dh = 25.0  # base cell width
dom_width = 3000.0  # domain width
nbc = 2**int(np.round(np.log(dom_width / dh) / np.log(2.0)))  # num. base cells

# Define the base mesh
h = [(dh, nbc)]
mesh = TreeMesh([h, h, h], x0="CCC")

# Mesh refinement based on topography
mesh = refine_tree_xyz(mesh,
                       topo_xyz,
                       octree_levels=[0, 0, 0, 1],
                       method="surface",
                       finalize=False)

# Mesh refinement near transmitters and receivers
mesh = refine_tree_xyz(mesh,
                       receiver_locations,
                       octree_levels=[2, 4],
                       method="radial",
                       finalize=False)
Пример #16
0
# We chose to design a coarser mesh to decrease the run time.
# When designing a mesh to solve practical time domain problems:
#
#     - Your smallest cell size should be 10%-20% the size of your smallest diffusion distance
#     - The thickness of your padding needs to be 2-3 times biggest than your largest diffusion distance
#     - The diffusion distance is ~1260*np.sqrt(rho*t)
#
#

dh = 25.0  # base cell width
dom_width = 1600.0  # domain width
nbc = 2**int(np.round(np.log(dom_width / dh) / np.log(2.0)))  # num. base cells

# Define the base mesh
h = [(dh, nbc)]
mesh = TreeMesh([h, h, h], x0="CCC")

# Mesh refinement based on topography
mesh = refine_tree_xyz(mesh,
                       topo_xyz,
                       octree_levels=[0, 0, 0, 1],
                       method="surface",
                       finalize=False)

# Mesh refinement near transmitters and receivers
mesh = refine_tree_xyz(mesh,
                       receiver_locations,
                       octree_levels=[2, 4],
                       method="radial",
                       finalize=False)
Пример #17
0
# sphinx_gallery_thumbnail_number = 4
dx = 10  # minimum cell width (base mesh cell width) in x
dy = 10  # minimum cell width (base mesh cell width) in y

x_length = 40000.  # domain width in x
y_length = 40000.  # domain width in y

# 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
Пример #18
0
# ----------------
#
# Here, we create the Tree mesh that will be used to invert both DC
# resistivity and IP data.
#

dh = 4  # base cell width
dom_width_x = 3200.0  # domain width x
dom_width_z = 2400.0  # domain width z
nbcx = 2 ** int(np.round(np.log(dom_width_x / dh) / np.log(2.0)))  # num. base cells x
nbcz = 2 ** int(np.round(np.log(dom_width_z / dh) / np.log(2.0)))  # num. base cells z

# Define the base mesh
hx = [(dh, nbcx)]
hz = [(dh, nbcz)]
mesh = TreeMesh([hx, hz], x0="CN")

# Mesh refinement based on topography
mesh = refine_tree_xyz(
    mesh,
    topo_xyz[:, [0, 2]],
    octree_levels=[0, 0, 4, 4],
    method="surface",
    finalize=False,
)

# Mesh refinement near transmitters and receivers. First we need to obtain the
# set of unique electrode locations.
electrode_locations = np.c_[
    dc_data.survey.locations_a,
    dc_data.survey.locations_b,
Пример #19
0
plt.close('all')
dx = 50  # minimum cell width (base mesh cell width) in x
dy = 50  # minimum cell width (base mesh cell width) in y

x_length = 30000.  # domain width in x
y_length = 30000.  # domain width in y

# 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='CC')

# Refine mesh near points
xx = np.linspace(-10000, 10000, 3000)
yy = 400 * np.sin((2 * xx * np.pi) / 1000)
pts = np.c_[mkvc(xx), mkvc(yy)]
M = refine_tree_xyz(M,
                    pts,
                    octree_levels=[2, 2],
                    method='radial',
                    finalize=False)

M.finalize()
print("\n the mesh has {} cells".format(M))
ccMesh = M.gridCC
print('indices:', np.size(ccMesh))
Пример #20
0
 def setUp(self):
     mesh = TreeMesh([32, 32])
     mesh.refine_box([0.2, 0.2], [0.5, 0.8], 5)
     self.mesh = mesh
Пример #21
0
dz = 50  # tamanho minimo da celula em z

x_length = 5000  # tamanho do dominio em x
y_length = 5000  # tamanho do dominio em y
z_length = 50000  # tamanho do dominio em z

# 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 = TreeMesh([hx, hy, hz], x0='CCC')

# # Refine surface topography
#[xx, yy] = np.meshgrid(M.vectorNx, M.vectorNy)
#[xx, yy,zz] = np.meshgrid([-5000,5000], [-5000,5000],[-100,100])
#zz = 0.*(xx**2 + yy**2)  - 1000.
##zz = np.zeros([300,300])
#pts = np.c_[mkvc(xx), mkvc(yy), mkvc(zz)]
#M = refine_tree_xyz(
#     M, pts, octree_levels=[1, 1], method='surface', finalize=False
#                   )

# Refine box
xp, yp, zp = np.meshgrid([-600., 600.], [-1000., 1000.], [300., -4000.])
xyz = np.c_[mkvc(xp), mkvc(yp), mkvc(zp)]
Пример #22
0
# Create Tree Mesh
# ------------------
#
# Here, we create the Tree mesh that will be used invert the DC data
#

dh = 4  # base cell width
dom_width_x = 3200.0  # domain width x
dom_width_z = 2400.0  # domain width z
nbcx = 2 ** int(np.round(np.log(dom_width_x / dh) / np.log(2.0)))  # num. base cells x
nbcz = 2 ** int(np.round(np.log(dom_width_z / dh) / np.log(2.0)))  # num. base cells z

# Define the base mesh
hx = [(dh, nbcx)]
hz = [(dh, nbcz)]
mesh = TreeMesh([hx, hz], x0="CN")

# Mesh refinement based on topography
mesh = refine_tree_xyz(
    mesh,
    topo_xyz[:, [0, 2]],
    octree_levels=[0, 0, 4, 4],
    method="surface",
    finalize=False,
)

# Mesh refinement near transmitters and receivers. First we need to obtain the
# set of unique electrode locations.
electrode_locations = np.c_[
    dc_data.survey.locations_a,
    dc_data.survey.locations_b,
Пример #23
0
###############################################
# Basic Example
# -------------
#
# Here we demonstrate the basic two step process for creating a 2D tree mesh
# (QuadTree mesh). The region of highest discretization if defined within a
# rectangular box. We use the keyword argument *octree_levels* to define the
# rate of cell width increase outside the box.
#

dh = 5  # minimum cell width (base mesh cell width)
nbc = 64  # number of base mesh cells in x

# Define base mesh (domain and finest discretization)
h = dh * np.ones(nbc)
mesh = TreeMesh([h, h])

# Define corner points for rectangular box
xp, yp = np.meshgrid([120., 240.], [80., 160.])
xy = np.c_[mkvc(xp), mkvc(yp)]  # mkvc creates vectors

# Discretize to finest cell size within rectangular box
mesh = refine_tree_xyz(mesh,
                       xy,
                       octree_levels=[2, 2],
                       method='box',
                       finalize=False)

mesh.finalize()  # Must finalize tree mesh before use

mesh.plotGrid(show_it=True)
Пример #24
0
fig.show()

#########################################################
# Tree Mesh Divergence
# --------------------
#
# For a tree mesh, there needs to be special attention taken for the hanging
# faces to achieve second order convergence for the divergence operator.
# Although the divergence cannot be constructed through Kronecker product
# operations, the initial steps are exactly the same for calculating the
# stencil, volumes, and areas. This yields a divergence defined for every
# cell in the mesh using all faces. There is, however, redundant information
# when hanging faces are included.
#

mesh = TreeMesh([[(1, 16)], [(1, 16)]], levels=4)
mesh.insert_cells(np.array([5.0, 5.0]), np.array([3]))
mesh.number()

fig = plt.figure(figsize=(10, 10))

ax1 = fig.add_subplot(211)

mesh.plotGrid(centers=True, nodes=False, ax=ax1)
ax1.axis("off")
ax1.set_title("Simple QuadTree Mesh")
ax1.set_xlim([-1, 17])
ax1.set_ylim([-1, 17])

for ii, loc in zip(range(mesh.nC), mesh.gridCC):
    ax1.text(loc[0] + 0.2, loc[1], "{0:d}".format(ii), color="r")
Пример #25
0
# Create Tree Mesh
# ------------------
#
# Here, we create the Tree mesh that will be used to predict DC data.
#

dh = 4  # base cell width
dom_width_x = 3200.0  # domain width x
dom_width_z = 2400.0  # domain width z
nbcx = 2 ** int(np.round(np.log(dom_width_x / dh) / np.log(2.0)))  # num. base cells x
nbcz = 2 ** int(np.round(np.log(dom_width_z / dh) / np.log(2.0)))  # num. base cells z

# Define the base mesh
hx = [(dh, nbcx)]
hz = [(dh, nbcz)]
mesh = TreeMesh([hx, hz], x0="CN")

# Mesh refinement based on topography
mesh = refine_tree_xyz(
    mesh,
    topo_xyz[:, [0, 2]],
    octree_levels=[0, 0, 4, 4],
    method="surface",
    finalize=False,
)

# Mesh refinement near transmitters and receivers. First we need to obtain the
# set of unique electrode locations.
electrode_locations = np.c_[
    survey.locations_a, survey.locations_b, survey.locations_m, survey.locations_n,
]
Пример #26
0
# Here, we create the Tree mesh that will be used to predict both DC
# resistivity and IP data.
#

dh = 10.0  # base cell width
dom_width_x = 2400.0  # domain width x
dom_width_z = 1200.0  # domain width z
nbcx = 2**int(np.round(np.log(dom_width_x / dh) /
                       np.log(2.0)))  # num. base cells x
nbcz = 2**int(np.round(np.log(dom_width_z / dh) /
                       np.log(2.0)))  # num. base cells z

# Define the base mesh
hx = [(dh, nbcx)]
hz = [(dh, nbcz)]
mesh = TreeMesh([hx, hz], x0="CN")

# Mesh refinement based on topography
mesh = refine_tree_xyz(mesh,
                       xyz_topo[:, [0, 2]],
                       octree_levels=[1],
                       method="surface",
                       finalize=False)

# Mesh refinement near transmitters and receivers. First we need to obtain the
# set of unique electrode locations.
electrode_locations = np.c_[survey.locations_a, survey.locations_b,
                            survey.locations_m, survey.locations_n]

unique_locations = np.unique(np.reshape(electrode_locations,
                                        (4 * survey.nD, 2)),
Пример #27
0
    def set_mesh(
        self,
        topo=None,
        dx=None,
        dy=None,
        dz=None,
        corezlength=None,
        npad_x=None,
        npad_y=None,
        npad_z=None,
        pad_rate_x=None,
        pad_rate_y=None,
        pad_rate_z=None,
        ncell_per_dipole=None,
        mesh_type="TensorMesh",
        dimension=2,
        method="nearest",
    ):
        """
        Set up a mesh for a given DC survey
        """

        # Update properties
        if npad_x is None:
            npad_x = self.npad_x
        self.npad_x = npad_x

        if npad_z is None:
            npad_z = self.npad_z
        self.npad_z = npad_z

        if pad_rate_x is None:
            pad_rate_x = self.pad_rate_x
        self.pad_rate_x = pad_rate_x

        if pad_rate_z is None:
            pad_rate_z = self.pad_rate_z
        self.pad_rate_z = pad_rate_z

        if ncell_per_dipole is None:
            ncell_per_dipole = self.ncell_per_dipole
        self.ncell_per_dipole = ncell_per_dipole

        # 2D or 3D mesh
        if dimension not in [2, 3]:
            raise NotImplementedError(
                "Set mesh has not been implemented for a 1D system")

        if dimension == 2:
            z_ind = 1
        else:
            z_ind = 2
        a = abs(np.diff(np.sort(self.electrode_locations[:, 0]))).min()
        lineLength = abs(self.electrode_locations[:, 0].max() -
                         self.electrode_locations[:, 0].min())
        dx_ideal = a / ncell_per_dipole
        if dx is None:
            dx = dx_ideal
            print("dx is set to {} m (samllest electrode spacing ({}) / {})".
                  format(dx, a, ncell_per_dipole))
        if dz is None:
            dz = dx * 0.5
            print("dz ({} m) is set to dx ({} m) / {}".format(dz, dx, 2))
        if dimension == 3:
            if dy is None:
                print("dy is set equal to dx")
                dy = dx
            self.dy = dy

            if npad_y is None:
                npad_y = self.npad_y
            self.npad_y = npad_y

            if pad_rate_y is None:
                pad_rate_y = self.pad_rate_y
            self.pad_rate_y = pad_rate_y

        x0 = self.electrode_locations[:, 0].min()
        if topo is None:
            # For 2D mesh
            if dimension == 2:
                # sort by x
                row_idx = np.lexsort((self.electrode_locations[:, 0], ))
            # For 3D mesh
            else:
                # sort by x, then by y
                row_idx = np.lexsort(
                    (self.electrode_locations[:,
                                              1], self.electrode_locations[:,
                                                                           0]))
            locs = self.electrode_locations[row_idx, :]
        else:
            # For 2D mesh
            if dimension == 2:
                mask = np.isin(self.electrode_locations[:, 0], topo[:, 0])
                if np.any(mask):
                    warnings.warn(
                        "Because the x coordinates of some topo and electrodes are the same,"
                        " we excluded electrodes with the same coordinates.",
                        RuntimeWarning,
                    )
                locs_tmp = np.vstack(
                    (topo, self.electrode_locations[~mask, :]))
                row_idx = np.lexsort((locs_tmp[:, 0], ))
            else:
                dtype = [("x", np.float64), ("y", np.float64)]
                mask = np.isin(
                    self.electrode_locations[:, [0, 1]].copy().view(dtype),
                    topo[:, [0, 1]].copy().view(dtype),
                ).flatten()
                if np.any(mask):
                    warnings.warn(
                        "Because the x and y coordinates of some topo and electrodes are the same,"
                        " we excluded electrodes with the same coordinates.",
                        RuntimeWarning,
                    )
                locs_tmp = np.vstack(
                    (topo, self.electrode_locations[~mask, :]))
                row_idx = np.lexsort((locs_tmp[:, 1], locs_tmp[:, 0]))
            locs = locs_tmp[row_idx, :]

        if dx > dx_ideal:
            # warnings.warn(
            #     "Input dx ({}) is greater than expected \n We recommend using {:0.1e} m cells, that is, {} cells per {0.1e} m dipole length".format(dx, dx_ideal, ncell_per_dipole, a)
            # )
            pass

        # Set mesh properties to class instance
        self.dx = dx
        self.dz = dz

        zmax = locs[:, z_ind].max()
        zmin = locs[:, z_ind].min()

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

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

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

            # For 3D mesh
            else:

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

                h = [hx, hy, hz]
                x0_for_mesh = [x0_mesh, y0_mesh, z0_mesh]
                self.xyzlim = np.vstack((
                    np.r_[x0, x0 + lineLength],
                    np.r_[ymin - dy * 3, ymax + dy * 3],
                    np.r_[zmax - corezlength, zmax],
                ))
            mesh = TensorMesh(h, x0=x0_for_mesh)

        elif mesh_type == "TREE":
            # Quadtree mesh
            if dimension == 2:

                pad_length_x = np.sum(meshTensor([(dx, npad_x, pad_rate_x)]))
                pad_length_z = np.sum(meshTensor([(dz, npad_z, pad_rate_z)]))

                dom_width_x = lineLength + 2 * pad_length_x  # domain width x
                dom_width_z = corezlength + pad_length_z  # domain width z

                nbcx = 2**int(np.ceil(np.log(dom_width_x / dx) /
                                      np.log(2.0)))  # num. base cells x
                nbcz = 2**int(np.ceil(np.log(dom_width_z / dz) /
                                      np.log(2.0)))  # num. base cells z

                length = 0.0
                dz_tmp = dz
                octree_levels = []
                while length < corezlength:
                    length += 5 * dz_tmp
                    octree_levels.append(5)
                    dz_tmp *= 2

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

                mesh_width = np.sum(meshTensor(hx))
                mesh_height = np.sum(meshTensor(hz))

                array_midpoint = 0.5 * (self.electrode_locations[:, 0].min() +
                                        self.electrode_locations[:, 0].max())
                mesh = TreeMesh(
                    [hx, hz],
                    x0=[array_midpoint - mesh_width / 2, zmax - mesh_height])
                # mesh = TreeMesh([hx, hz], x0='CN')

                # Mesh refinement based on topography
                mesh = refine_tree_xyz(
                    mesh,
                    self.electrode_locations,
                    octree_levels=octree_levels,
                    method="radial",
                    finalize=False,
                )
                mesh.finalize()

                self.xyzlim = np.vstack((
                    np.r_[self.electrode_locations[:, 0].min(),
                          self.electrode_locations[:, 0].max(), ],
                    np.r_[zmax - corezlength, zmax],
                ))

            # Octree mesh
            elif dimension == 3:
                raise NotImplementedError(
                    "set_mesh has not implemented 3D TreeMesh (yet)")

        else:
            raise NotImplementedError(
                "set_mesh currently generates TensorMesh or TreeMesh")

        actind = surface2ind_topo(mesh, locs, method=method, fill_value=np.nan)

        return mesh, actind
def plotVectorSectionsOctree(
    mesh,
    m,
    normal="X",
    ind=0,
    vmin=None,
    vmax=None,
    scale=1.0,
    vec="k",
    axs=None,
    actvMap=None,
    fill=True,
):
    """
    Plot section through a 3D tensor model
    """
    # plot recovered model
    normalInd = {"X": 0, "Y": 1, "Z": 2}[normal]
    antiNormalInd = {"X": [1, 2], "Y": [0, 2], "Z": [0, 1]}[normal]

    h2d = (mesh.h[antiNormalInd[0]], mesh.h[antiNormalInd[1]])
    x2d = (mesh.x0[antiNormalInd[0]], mesh.x0[antiNormalInd[1]])

    #: Size of the sliced dimension
    szSliceDim = len(mesh.h[normalInd])
    if ind is None:
        ind = int(szSliceDim // 2)

    cc_tensor = [None, None, None]
    for i in range(3):
        cc_tensor[i] = np.cumsum(np.r_[mesh.x0[i], mesh.h[i]])
        cc_tensor[i] = (cc_tensor[i][1:] + cc_tensor[i][:-1]) * 0.5
    slice_loc = cc_tensor[normalInd][ind]

    # Create a temporary TreeMesh with the slice through
    temp_mesh = TreeMesh(h2d, x2d)
    level_diff = mesh.max_level - temp_mesh.max_level

    XS = [None, None, None]
    XS[antiNormalInd[0]], XS[antiNormalInd[1]] = np.meshgrid(
        cc_tensor[antiNormalInd[0]], cc_tensor[antiNormalInd[1]])
    XS[normalInd] = np.ones_like(XS[antiNormalInd[0]]) * slice_loc
    loc_grid = np.c_[XS[0].reshape(-1), XS[1].reshape(-1), XS[2].reshape(-1)]
    inds = np.unique(mesh._get_containing_cell_indexes(loc_grid))

    grid2d = mesh.gridCC[inds][:, antiNormalInd]
    levels = mesh._cell_levels_by_indexes(inds) - level_diff
    temp_mesh.insert_cells(grid2d, levels)
    tm_gridboost = np.empty((temp_mesh.nC, 3))
    tm_gridboost[:, antiNormalInd] = temp_mesh.gridCC
    tm_gridboost[:, normalInd] = slice_loc

    # Interpolate values to mesh.gridCC if not 'CC'
    mx = actvMap * m[:, 0]
    my = actvMap * m[:, 1]
    mz = actvMap * m[:, 2]

    m = np.c_[mx, my, mz]

    # Interpolate values from mesh.gridCC to grid2d
    ind_3d_to_2d = mesh._get_containing_cell_indexes(tm_gridboost)
    v2d = m[ind_3d_to_2d, :]
    amp = np.sum(v2d**2.0, axis=1)**0.5

    if axs is None:
        axs = plt.subplot(111)

    if fill:
        temp_mesh.plotImage(amp, ax=axs, clim=[vmin, vmax], grid=True)

    axs.quiver(
        temp_mesh.gridCC[:, 0],
        temp_mesh.gridCC[:, 1],
        v2d[:, antiNormalInd[0]],
        v2d[:, antiNormalInd[1]],
        pivot="mid",
        scale_units="inches",
        scale=scale,
        linewidths=(1, ),
        edgecolors=(vec),
        headaxislength=0.1,
        headwidth=10,
        headlength=30,
    )
Пример #29
0
dh = 25.0  # base cell width
dom_width_x = 6000.0  # domain width x
dom_width_y = 6000.0  # domain width y
dom_width_z = 4000.0  # domain width z
nbcx = 2**int(np.round(np.log(dom_width_x / dh) /
                       np.log(2.0)))  # num. base cells x
nbcy = 2**int(np.round(np.log(dom_width_y / dh) /
                       np.log(2.0)))  # num. base cells y
nbcz = 2**int(np.round(np.log(dom_width_z / dh) /
                       np.log(2.0)))  # num. base cells z

# Define the base mesh
hx = [(dh, nbcx)]
hy = [(dh, nbcy)]
hz = [(dh, nbcz)]
mesh = TreeMesh([hx, hy, hz], x0="CCN")

# Mesh refinement based on topography
k = np.sqrt(np.sum(topo_xyz[:, 0:2]**2, axis=1)) < 1200
mesh = refine_tree_xyz(mesh,
                       topo_xyz[k, :],
                       octree_levels=[0, 6, 8],
                       method="surface",
                       finalize=False)

# Mesh refinement near sources and receivers.
electrode_locations = np.r_[dc_data.survey.locations_a,
                            dc_data.survey.locations_b,
                            dc_data.survey.locations_m,
                            dc_data.survey.locations_n, ]
unique_locations = np.unique(electrode_locations, axis=0)
dz = 5  # minimum cell width (base mesh cell width) in z

x_length = 240.0  # domain width in x
y_length = 240.0  # domain width in y
z_length = 120.0  # domain width in y

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

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

# Refine based on surface topography
mesh = refine_tree_xyz(mesh,
                       xyz_topo,
                       octree_levels=[2, 2],
                       method="surface",
                       finalize=False)

# Refine box based on region of interest
xp, yp, zp = np.meshgrid([-100.0, 100.0], [-100.0, 100.0], [-80.0, 0.0])
xyz = np.c_[mkvc(xp), mkvc(yp), mkvc(zp)]

mesh = refine_tree_xyz(mesh,
                       xyz,
                       octree_levels=[2, 2],