def generate_hom_world_with_inclusion(world_dim: list, incl_start: list,
                                      incl_dim: list):
    """ Creates a homogeneous world with inclusion.

    Utility function to create a homogeneous world with an inclusion. Region markers are set to 1 for the background
    world and 2 for the inclusion.

    Parameter:
        world_dim: World dimensions as [x,z].
        incl_start: Inclusion upper left corner as [x,z].
        incl_dim: Inclusion dimension as [x,z].

    Returns:
        The created world.
    """
    # Create geometric objects
    world = mt.createWorld(start=[0, 0], end=[world_dim[0], -world_dim[1]])
    inclusion = mt.createRectangle(
        start=incl_start,
        end=[incl_start[0] + incl_dim[0], incl_start[1] - incl_dim[1]],
        marker=2,
        boundaryMarker=10)
    # Merge geometries
    geom = mt.mergePLC([world, inclusion])
    return geom
Exemplo n.º 2
0
def createSynthModel():
    """Return the modelling mesh, the porosity distribution and the
       parametric mesh for inversion.
    """
    # Create the synthetic model
    world = mt.createCircle(boundaryMarker=-1, nSegments=64)
    tri = mt.createPolygon([[-0.8, -0], [-0.5, -0.7], [0.7, 0.5]],
                           isClosed=True, area=0.0015)
    c1 = mt.createCircle(radius=0.2, pos=[-0.2, 0.5], nSegments=32,
                         area=0.0025, marker=3)
    c2 = mt.createCircle(radius=0.2, pos=[0.32, -0.3], nSegments=32,
                         area=0.0025, marker=3)

    poly = mt.mergePLC([world, tri, c1, c2])

    poly.addRegionMarker([0.0, 0, 0], 1, area=0.0015)
    poly.addRegionMarker([-0.9, 0, 0], 2, area=0.0015)

    c = mt.createCircle(radius=0.99, nSegments=16, start=np.pi, end=np.pi*3)
    [poly.createNode(p.pos(), -99) for p in c.nodes()]
    mesh = pg.meshtools.createMesh(poly, q=34.4, smooth=[1, 10])
    mesh.scale(1.0/5.0)
    mesh.rotate([0., 0., 3.1415/3])
    mesh.rotate([0., 0., 3.1415])

    petro = pg.solver.parseArgToArray([[1, 0.9], [2, 0.6], [3, 0.3]],
                                      mesh.cellCount(), mesh)

    # Create the parametric mesh that only reflect the domain geometry
    world = mt.createCircle(boundaryMarker=-1, nSegments=32, area=0.0051)
    paraMesh = pg.meshtools.createMesh(world, q=34.0, smooth=[1, 10])
    paraMesh.scale(1.0/5.0)

    return mesh, paraMesh, petro
Exemplo n.º 3
0
def createSynthModel():
    """Return the modeling mesh, the porosity distribution and the
       parametric mesh for inversion.
    """
    # Create the synthetic model
    world = mt.createCircle(boundaryMarker=-1, segments=64)
    tri = mt.createPolygon([[-0.8, -0], [-0.5, -0.7], [0.7, 0.5]],
                           isClosed=True, area=0.0015)
    c1 = mt.createCircle(radius=0.2, pos=[-0.2, 0.5], segments=32,
                         area=0.0025, marker=3)
    c2 = mt.createCircle(radius=0.2, pos=[0.32, -0.3], segments=32,
                         area=0.0025, marker=3)

    poly = mt.mergePLC([world, tri, c1, c2])

    poly.addRegionMarker([0.0, 0, 0], 1, area=0.0015)
    poly.addRegionMarker([-0.9, 0, 0], 2, area=0.0015)

    c = mt.createCircle(radius=0.99, segments=16, start=np.pi, end=np.pi*3)
    [poly.createNode(p.pos(), -99) for p in c.nodes()]
    mesh = pg.meshtools.createMesh(poly, q=34.4, smooth=[1, 10])
    mesh.scale(1.0/5.0)
    mesh.rotate([0., 0., 3.1415/3])
    mesh.rotate([0., 0., 3.1415])

    petro = pg.solver.parseArgToArray([[1, 0.9], [2, 0.6], [3, 0.3]],
                                      mesh.cellCount(), mesh)

    # Create the parametric mesh that only reflects the domain geometry
    world = mt.createCircle(boundaryMarker=-1, segments=32, area=0.0051)
    paraMesh = pg.meshtools.createMesh(world, q=34.0, smooth=[1, 10])
    paraMesh.scale(1.0/5.0)

    return mesh, paraMesh, petro
def get_fwd_mesh():
    """Generate the forward mesh (with embedded anomalies)"""
    scheme = get_scheme()

    # Mesh generation
    world = mt.createWorld(
        start=[-55, 0], end=[105, -80], worldMarker=True)

    conductive_anomaly = mt.createCircle(
        pos=[10, -7], radius=5, marker=2
    )

    polarizable_anomaly = mt.createCircle(
        pos=[40, -7], radius=5, marker=3
    )

    plc = mt.mergePLC((world, conductive_anomaly, polarizable_anomaly))

    # local refinement of mesh near electrodes
    for s in scheme.sensors():
        plc.createNode(s + [0.0, -0.2])

    mesh_coarse = mt.createMesh(plc, quality=33)
    mesh = mesh_coarse.createH2()
    return mesh
Exemplo n.º 5
0
def simulateSynth(model, tMax=5000, satSteps=150, ertSteps=10, area=0.1,
                  synthPath='synth/'):
    """Create synthetic example."""

    if not os.path.exists('synth/'):
        os.mkdir(synthPath)

    world = mt.createWorld(start=[-20, 0], end=[20, -16], layers=[-2, -8],
                           worldMarker=False)
    for i, b in enumerate(world.boundaries()):
        b.setMarker(i + 1)

    block = mt.createRectangle(start=[-6, -3.5], end=[6, -6.0], marker=4,
                               boundaryMarker=11, area=area)
    geom = mt.mergePLC([world, block])
    geom.save(synthPath + 'synthGeom')
    # pg.show(geom, boundaryMarker=1)

    paraMesh = pg.meshtools.createMesh(geom, quality=32, area=area,
                                       smooth=[1, 10])

    # translate 1 2 3 4 - > 0 1 2 3
    mapMarker = np.array([0, 0, 1, 2, 3], 'float')
    paraMesh.setCellMarkers(mapMarker[np.array(paraMesh.cellMarkers())])
    paraMesh.save(synthPath + 'synth.bms')

    fop = HydroGeophysicalModelling(mesh=paraMesh, tMax=tMax,
                                    satSteps=satSteps,
                                    ertSteps=ertSteps,
                                    verbose=1)

    # openblas have some problems with to high thread count ..
    # we need to dig into
    print("ThreadCount:", pg.threadCount())
    pg.setThreadCount(4)

    print('##### Simulate synthetic data ' + '#'*50)
    pg.tic()
    rhoaR = fop.response(pg.RVector(model)[paraMesh.cellMarkers()])
    pg.toc()
    print('#'*100)

    # add some noise here
    rand = pg.RVector(len(rhoaR))
    pg.randn(rand)

    rhoaR *= (1.0 + rand * fop.ws.derr.flatten())
    fop.ws.rhoaR = rhoaR.reshape(fop.ws.derr.shape)

    # fop.ws.mesh.save(synthPath + 'synth.bms')
    np.save(synthPath + 'synthK', fop.ws.k)
    np.save(synthPath + 'synthVel', fop.ws.vel)
    np.save(synthPath + 'synthSat', fop.ws.sat)

    fop.ws.scheme.save(synthPath + 'synth.shm', 'a b m n')
    np.save(synthPath + 'synthRhoaRatio', fop.ws.rhoaR)
    np.save(synthPath + 'synthRhoa', fop.ws.rhoa)
    np.save(synthPath + 'synthErr', fop.ws.derr)
Exemplo n.º 6
0
def testCBarLevels():
    """
    Expectations
    ------------
    axs[0, 0]: show regions with plc
        Show needs to deliver the regions with Set3 colormap. Each tick on the
        colobar should be in the middle of the related color section.

    axs[1, 0]: show regions with mesh
        really the same thing as on axs[0, 0] but with mesh.

    ax[0, 1]: show mesh with cell data
        if nLevs is given i would expect that the colormap then is levelled.
        currently that is not the fact. but at least its the full range. labels
        need to be at begin/end of each color section.

    ax[1, 1]: show mesh with node data
        the colorbar range misses parts of its full range. labels need to be
        at begin/end of each color section.
    """
    # create a geometry
    world = mt.createWorld(start=[-10, 0],
                           end=[10, -16],
                           layers=[-8],
                           worldMarker=False)

    block = mt.createRectangle(start=[-6, -3.5],
                               end=[6, -6.0],
                               marker=4,
                               boundaryMarker=10,
                               area=0.1)

    circ = mt.createCircle(pos=[0, -11], marker=5, radius=2, boundaryMarker=11)

    poly = mt.mergePLC([world, block, circ])
    mesh = mt.createMesh(poly, quality=34)

    # create random data
    rhomap = [[1, 10], [2, 4], [4, 20], [5, 8]]
    # map data to cell/node count
    cell_data = pg.solver.parseArgToArray(rhomap, mesh.cellCount(), mesh)
    node_data = mt.cellDataToNodeData(mesh, cell_data)

    # plot everything
    fig, axs = pg.plt.subplots(2, 2, figsize=(20, 10))

    pg.show(poly, ax=axs[0, 0])

    pg.show(mesh, ax=axs[1, 0], markers=True)

    pg.show(mesh, cell_data, ax=axs[0, 1], colorBar=True, nLevs=7)

    pg.show(mesh, node_data, ax=axs[1, 1], colorBar=True, nLevs=7)
def plot_fwd_model(axes):
    """This function plots the forward model used to generate the data

    """
    # Mesh generation
    world = mt.createWorld(
        start=[-55, 0], end=[105, -80], worldMarker=True)

    conductive_anomaly = mt.createCircle(
        pos=[10, -7], radius=5, marker=2
    )

    polarizable_anomaly = mt.createCircle(
        pos=[40, -7], radius=5, marker=3
    )

    plc = mt.mergePLC((world, conductive_anomaly, polarizable_anomaly))

    # local refinement of mesh near electrodes
    for s in scheme.sensors():
        plc.createNode(s + [0.0, -0.2])

    mesh_coarse = mt.createMesh(plc, quality=33)
    mesh = mesh_coarse.createH2()

    rhomap = [
        [1, pg.utils.complex.toComplex(100, 0 / 1000)],
        # Magnitude: 50 ohm m, Phase: -50 mrad
        [2, pg.utils.complex.toComplex(50, 0 / 1000)],
        [3, pg.utils.complex.toComplex(100, -50 / 1000)],
    ]

    rho = pg.solver.parseArgToArray(rhomap, mesh.cellCount(), mesh)
    pg.show(
        mesh,
        data=np.log(np.abs(rho)),
        ax=axes[0],
        label=r"$log_{10}(|\rho|~[\Omega m])$"
    )
    pg.show(mesh, data=np.abs(rho), ax=axes[1], label=r"$|\rho|~[\Omega m]$")
    pg.show(
        mesh, data=np.arctan2(np.imag(rho), np.real(rho)) * 1000,
        ax=axes[2],
        label=r"$\phi$ [mrad]",
        cMap='jet_r'
    )
    fig.tight_layout()
    fig.show()
def generate_layered_world_with_inclusion(world_dim: list, layer_heights: list,
                                          incl_start: list, incl_dim: list):
    """ Creates a layered world with inclusion.

    Utility function to create a layered world with an inclusion. Region markers are starting at 1 and increasing with
    depth. The inclusion has the highest marker number.

    Parameter:
        world_dim: World dimensions as [x,z].
        layer_heights: Heights of the single layers.
        incl_start: Inclusion upper left corner as [x,z].
        incl_dim: Inclusion dimension as [x,z].

    Returns:
        The created world.
    """
    # Check parameter integrity
    if sum(layer_heights) > world_dim[1]:
        return None
    # Create geometric objects
    world = mt.createWorld(start=[0, 0], end=[world_dim[0], -world_dim[1]])
    current_depth = 0
    layers = []
    for i in range(len(layer_heights)):
        layer = mt.createRectangle(
            start=[0, -current_depth],
            end=[world_dim[0], -(current_depth + layer_heights[i])],
            marker=i + 1,
            boundaryMarker=10)
        current_depth += layer_heights[i]
        layers.append(layer)
    if current_depth != world_dim[1]:
        layer = mt.createRectangle(start=[0, -current_depth],
                                   end=[world_dim[0], -world_dim[1]],
                                   marker=i + 2,
                                   boundaryMarker=10)
        layers.append(layer)
    inclusion = mt.createRectangle(
        start=incl_start,
        end=[incl_start[0] + incl_dim[0], incl_start[1] - incl_dim[1]],
        marker=len(layers) + 1,
        boundaryMarker=10)
    # Merge geometries
    geom = mt.mergePLC([world, inclusion] + layers)
    return geom
Exemplo n.º 9
0
def create_geometry(position=0, depth=3, radius=4):
    elecs = np.linspace(-25, 25, 15)  # x coordinate of the electrodes
    # Create geometry definition for the modelling domain.
    # worldMarker=True indicates the default boundary conditions for the ERT
    world = mt.createWorld(start=[-50, 0], end=[50, -50], worldMarker=True)

    # Create a circular heterogeneous body
    block = mt.createCircle(pos=[position, -depth],
                            radius=radius,
                            marker=2,
                            boundaryMarker=0,
                            area=5)

    # Merge geometry definition into a Piecewise Linear Complex (PLC)
    geom = mt.mergePLC([world, block])
    fig, ax = plt.subplots(figsize=(10, 6))
    pg.show(geom, ax=ax, hold=True)
    ax.plot(elecs, np.zeros_like(elecs), "kv")
    ax.set_ylim(-20, 0)
    return geom
def generate_tiled_world(world_dim: list, tile_size: list):
    """ Creates a tiled layered world.

    Utility function to create a tiled layered world. Region marker 1 is upper left corner.

    Parameter:
        world_dim: World dimensions as [x,z].
        tile_size: Tile dimensions as [x,z].

    Returns:
        The created world.
    """
    # Create world
    world = mt.createWorld(start=[0, 0], end=[world_dim[0], -world_dim[1]])
    # Create tile counts
    n_tiles_x = int(np.ceil(world_dim[0] / tile_size[0]))
    n_tiles_y = int(np.ceil(world_dim[1] / tile_size[1]))
    # Create and merge tiles
    for j in range(n_tiles_y):
        for i in range(n_tiles_x):
            x_start = int(i * tile_size[0])
            x_end = int((i + 1) * tile_size[0])
            y_start = int(-j * tile_size[1])
            y_end = int(-(j + 1) * tile_size[1])
            if x_end > world_dim[0]:
                x_end = world_dim[0]
            if y_end < -world_dim[1]:
                y_end = -world_dim[1]
            marker = 1
            if ((-1)**i) * ((-1)**j) < 0:
                marker = 2
            tile = mt.createRectangle(start=[x_start, y_start],
                                      end=[x_end, y_end],
                                      marker=marker,
                                      boundaryMarker=10)
            world = mt.mergePLC([world, tile])
    return world
def generate_layered_world(world_dim: list, layer_heights: list):
    """ Creates a layered world.

    Utility function to create a layered world. Region markers are starting at 1 and increasing with depth.

    Parameter:
        world_dim: World dimensions as [x,z].
        layer_heights: Heights of the single layers.

    Returns:
        The created world.
    """
    # Check parameter integrity
    if sum(layer_heights) > world_dim[1]:
        return None
    # Create geometric objects
    world = mt.createWorld(start=[0, 0], end=[world_dim[0], -world_dim[1]])
    current_depth = 0
    layers = []
    for i in range(len(layer_heights)):
        layer = mt.createRectangle(
            start=[0, -current_depth],
            end=[world_dim[0], -(current_depth + layer_heights[i])],
            marker=i + 1,
            boundaryMarker=10)
        current_depth += layer_heights[i]
        layers.append(layer)
    if current_depth != world_dim[1]:
        layer = mt.createRectangle(start=[0, -current_depth],
                                   end=[world_dim[0], -world_dim[1]],
                                   marker=i + 2,
                                   boundaryMarker=10)
        layers.append(layer)
    # Merge geometries
    geom = mt.mergePLC([world] + layers)
    return geom
Exemplo n.º 12
0
import pygimli as pg
import pygimli.meshtools as mt

# Create geometry definition for the modelling domain
world = mt.createWorld(start=[-20, 0],
                       end=[20, -16],
                       layers=[-2, -8],
                       worldMarker=False)
# Create a heterogeneous block
block = mt.createRectangle(start=[-6, -3.5],
                           end=[6, -6.0],
                           marker=4,
                           boundaryMarker=10,
                           area=0.1)
# Merge geometrical entities
geom = mt.mergePLC([world, block])
pg.show(geom, boundaryMarker=True, savefig='geometry.pdf')

# Create a mesh from the geometry definition
mesh = mt.createMesh(geom, quality=33, area=0.2, smooth=[1, 10])
pg.show(mesh, savefig='mesh.pdf')

# $\diverg(a\grad T)=0$ with $T(bottom)=1$, $T(top)=0$
T = pg.solver.solveFiniteElements(mesh,
                                  a=[[1, 1.0], [2, 2.0], [3, 3.0], [4, 0.1]],
                                  uB=[[8, 1.0], [4, 0.0]],
                                  verbose=True)

ax, _ = pg.show(mesh,
                data=T,
                label='Temperature $T$',
rhomap = [[0, 500], [1, 50], [2, 100], [3, 2000]]
#CREACION MODELO GENERAL

background = mt.createWorld(start=[-10, 0], end=[81, -20], area=1, marker=0)

pol0 = mt.createPolygon([[-10, -2.5], [27.5, -2.5], [30, 0], [-10, 0]],
                        isClosed=True,
                        marker=1)
pol1 = mt.createPolygon([[-10, -20], [10, -20], [27.5, -2.5], [-10, -2.5]],
                        isClosed=True,
                        marker=2)
pol2 = mt.createPolygon([[60, 0], [65, 0], [45, -20], [40, -20]],
                        isClosed=True,
                        marker=3)

world = mt.mergePLC([background, pol0, pol1, pol2])
mesh = mt.createMesh(world, quality=33, area=0.1, smooth=[1, 2])

#EXPORTACION DATOS DE RESISTIVIDAD DEL MODELO (VECTOR)

res_model = pg.solver.parseArgToArray(rhomap, mesh.cellCount(), mesh)

pg.show(mesh, res_model)

#INTERPOLACION DATOS MODELO A MESH INVERSION

nan = 99.9
model_vector = []
for pos in grid.cellCenters():
    cell = mesh.findCell(pos)
    if cell:
Exemplo n.º 14
0
def simulateSynth(model,
                  tMax=5000,
                  satSteps=150,
                  ertSteps=10,
                  area=0.1,
                  synthPath='synth/'):
    """Create synthetic example."""

    if not os.path.exists('synth/'):
        os.mkdir(synthPath)

    world = mt.createWorld(start=[-20, 0],
                           end=[20, -16],
                           layers=[-2, -8],
                           worldMarker=False)
    for i, b in enumerate(world.boundaries()):
        b.setMarker(i + 1)

    block = mt.createRectangle(start=[-6, -3.5],
                               end=[6, -6.0],
                               marker=4,
                               boundaryMarker=11,
                               area=area)
    geom = mt.mergePLC([world, block])
    geom.save(synthPath + 'synthGeom')
    # pg.show(geom, boundaryMarker=1)

    paraMesh = pg.meshtools.createMesh(geom,
                                       quality=32,
                                       area=area,
                                       smooth=[1, 10])

    # translate 1 2 3 4 - > 0 1 2 3
    mapMarker = np.array([0, 0, 1, 2, 3], 'float')
    paraMesh.setCellMarkers(mapMarker[np.array(paraMesh.cellMarkers())])
    paraMesh.save(synthPath + 'synth.bms')

    fop = HydroGeophysicalModelling(mesh=paraMesh,
                                    tMax=tMax,
                                    satSteps=satSteps,
                                    ertSteps=ertSteps,
                                    verbose=1)

    # openblas have some problems with to high thread count ..
    # we need to dig into
    print("TC", pg.threadCount())
    pg.setThreadCount(4)

    print('##### Simulate synthetic data ' + '#' * 50)
    pg.tic()
    rhoaR = fop.response(pg.RVector(model)[paraMesh.cellMarkers()])
    pg.toc()
    print('#' * 100)

    # add some noise here
    rand = pg.RVector(len(rhoaR))
    pg.randn(rand)

    rhoaR *= (1.0 + rand * fop.ws.derr.flatten())
    fop.ws.rhoaR = rhoaR.reshape(fop.ws.derr.shape)

    # fop.ws.mesh.save(synthPath + 'synth.bms')
    np.save(synthPath + 'synthK', fop.ws.k)
    np.save(synthPath + 'synthVel', fop.ws.vel)
    np.save(synthPath + 'synthSat', fop.ws.sat)

    fop.ws.scheme.save(synthPath + 'synth.shm', 'a b m n')
    np.save(synthPath + 'synthRhoaRatio', fop.ws.rhoaR)
    np.save(synthPath + 'synthRhoa', fop.ws.rhoa)
    np.save(synthPath + 'synthErr', fop.ws.derr)
Exemplo n.º 15
0
gz_p = solveGravimetry(circ, dRho, pnts, complete=False)

###############################################################################
# Integration for complete 2D mesh after :cite:`WonBev1987`
world = createWorld(start=[-20, 0], end=[20, -10], marker=1)
mesh = createMesh([world, circ])
dRhoC = pg.solver.parseMapToCellArray([[1, 0.0], [2, dRho]], mesh)
gc_m = solveGravimetry(mesh, dRhoC, pnts)

###############################################################################
# Finite Element solution for :math:`u`
world = createWorld(start=[-200, 200], end=[200, -200], marker=1)

# Add some nodes to the measurement points to increase the accuracy a bit
[world.createNode(x_, 0.0,  1) for x_ in x]
plc = mergePLC([world, circ])
mesh = createMesh(plc, quality=34)
mesh = mesh.createP2()

density = pg.solver.parseMapToCellArray([[1, 0.0], [2, dRho]], mesh)
u = pg.solver.solve(mesh, a=1, f=density, uB=[[-2, 0], [-1, 0]])

###############################################################################
# Calculate gradient of gravimetric potential
# :math:`\frac{\partial u}{\partial (x,z)}`
dudz = np.zeros(len(pnts))

for i, p in enumerate(pnts):
    c = mesh.findCell(p)
    g = c.grad(p, u)
    dudz[i] = -g[1] * 4. * np.pi * pg.physics.constants.GmGal  # why 4 pi here?
Exemplo n.º 16
0
depth = -np.arange(sensor_spacing, bh_length + sensor_spacing, sensor_spacing)

sensors = np.zeros((len(depth) * 2, 2))  # two boreholes
sensors[len(depth):, 0] = bh_spacing  # x
sensors[:, 1] = np.hstack([depth] * 2)  # y

################################################################################
# Traveltime calculations work on unstructured meshes and structured grids. We
# demonstrate this here by simulating the synthetic data on an unstructured mesh
# and inverting it on a simple structured grid.

# Create forward model and mesh
c0 = mt.createCircle(pos=(7.0, -10.0), radius=3, segments=25, marker=1)
c1 = mt.createCircle(pos=(12.0, -18.0), radius=4, segments=25, marker=2)
geom = mt.mergePLC([world, c0, c1])
for sen in sensors:
    geom.createNode(sen)

mesh_fwd = mt.createMesh(geom, quality=34, area=.25)
model = np.array([2000., 2300, 1700])[mesh_fwd.cellMarkers()]
pg.show(mesh_fwd, model, label="Velocity (m/s)", nLevs=3, logScale=False)

################################################################################
# Create inversion mesh
refinement = 0.25
x = np.arange(0, bh_spacing + refinement, sensor_spacing * refinement)
y = -np.arange(0.0, bh_length + 3, sensor_spacing * refinement)
mesh = pg.createMesh2D(x, y)

ax, _ = pg.show(mesh, hold=True)
Exemplo n.º 17
0
import pybert as pb
from pybert.sip import SIPdata

# Create geometry definition for the modelling domain
world = plc.createWorld(start=[-50, 0],
                        end=[50, -50],
                        layers=[-1, -5],
                        worldMarker=True)
# Create some heterogeneous circle
block = plc.createCircle(pos=[0, -3.],
                         radius=1,
                         marker=4,
                         boundaryMarker=10,
                         area=0.1)
# Merge geometry definition
geom = plc.mergePLC([world, block])
# create measuring scheme (data container without data)
scheme = pb.createData(elecs=np.linspace(-10, 10, 21), schemeName='dd')
for pos in scheme.sensorPositions():  # put all electrodes (sensors) into geom
    geom.createNode(pos, marker=-99)  # just a historic convention
    geom.createNode(pos + pg.RVector3(0, -0.1))  # refine with 10cm

# pg.show(geom, boundaryMarker=1)
mesh = plc.createMesh(geom)
# pg.show(mesh)

scheme = pb.createData(elecs=np.linspace(-10, 10, 21), schemeName='dd')
#        dumm,  1.S   2.S   3.S    Body
rhovec = np.array([0, 100.0, 50.0, 10.0, 100])  # ohm m
tauvec = np.array([0, 1e-3, 1e-3, 0.1, 1.0])  # s
mvec = np.array([0.001, 0.01, 0.001, 0.5, 0.5])  # - [0-1]
                       area=1,
                       marker=2)
sup2 = mt.createPolygon([[40, 0], [81, 0], [81, -1.5], [38.8, -1.5]],
                        isClosed=True,
                        area=1,
                        marker=4)
sup3 = mt.createPolygon([[30, 0], [40, 0], [39.6, -0.5], [30.4, -0.5]],
                        isClosed=True,
                        area=1,
                        marker=4)
pol = mt.createPolygon([[30, 0], [40, 0], [38, -2.5], [32, -2.5]],
                       isClosed=True,
                       area=1,
                       marker=0)
square = mt.createRectangle(start=[34, -0.5], end=[36, -2.5], area=1, marker=3)
world = mt.mergePLC([background, pol, square, sup, sup2, sup3])
mesh = mt.createMesh(world, quality=33, area=0.1, smooth=[1, 2])

res_model = pg.solver.parseArgToArray(rhomap, mesh.cellCount(), mesh)

#INTERPOLACIÓN MODELO A GRID

nan = 99.9
model_vector_nn = []
for pos in grid.cellCenters():
    cell = mesh.findCell(pos)
    if cell:
        model_vector_nn.append(res_model[cell.id()])
    else:
        model_vector_nn.append(nan)
Exemplo n.º 19
0
world = mt.createWorld(start=[-10, 0],
                       end=[10, -16],
                       layers=[-8],
                       worldMarker=False)

# Create a heterogeneous block
block = mt.createRectangle(start=[-6, -3.5],
                           end=[6, -6.0],
                           marker=4,
                           boundaryMarker=10,
                           area=0.1)

circ = mt.createCircle(pos=[0, -11], radius=2, boundaryMarker=11, isHole=True)

# Merge geometrical entities
geom = mt.mergePLC([world, block, circ])
mesh = mt.createMesh(geom)

fig, axs = plt.subplots(3, 5)

pg.show(geom, ax=axs[0][0])
axs[0][0].set_title('plc, (default)')
pg.show(geom, fillRegion=False, ax=axs[0][1])
axs[0][1].set_title('plc, fillRegion=False')
pg.show(geom, showBoundary=False, ax=axs[0][2])
axs[0][2].set_title('plc, showBoundary=False')
pg.show(geom, markers=True, ax=axs[0][3])
axs[0][3].set_title('plc, markers=True')
pg.show(mesh, ax=axs[0][4], showBoundary=False)
axs[0][4].set_title('mesh, showBoundary=False')
#creación grid para comparación

grid = pg.createGrid(x=pg.utils.grange(start=0.20, end=0.5, n=500),
                     y=-pg.utils.grange(0, 0.12, n=250, log=False))

grid2 = pg.createGrid(x=pg.utils.grange(start=0.33, end=0.35, n=500),
                      y=-pg.utils.grange(0.04, 0.06, n=250, log=False))

square = mt.createRectangle(start=[0.33, -0.04], end=[0.35, -0.06])

#MODELO

rhomap = [[1, 150], [0, 3000]]
background = mt.createWorld(start=[-1, 0], end=[1, -1], area=1, marker=1)
circle = mt.createCircle(pos=[0.34, -0.05], radius=0.01, marker=0)
world = mt.mergePLC([background, circle])
mesh = mt.createMesh(world, quality=33, area=0.1, smooth=[1, 2])

res_model = pg.solver.parseArgToArray(rhomap, mesh.cellCount(), mesh)

#INTERPOLACIÓN MODELO A GRID

nan = 99.9
model_vector_nn = []
for pos in grid.cellCenters():
    cell = mesh.findCell(pos)
    if cell:
        model_vector_nn.append(res_model[cell.id()])
    else:
        model_vector_nn.append(nan)
Exemplo n.º 21
0
                      pos=[width / 2, width / 2, -depth / 2],
                      marker=1,
                      area=75)  #, boundaryMarker=0)

for i, b in enumerate(world.boundaries()):
    # if worldMarker is True:
    if b.norm()[2] == 1.0:
        b.setMarker(pg.core.MARKER_BOUND_HOMOGEN_NEUMANN)
    else:
        b.setMarker(pg.core.MARKER_BOUND_MIXED)

ano = mt.createCube(size=[widthAno, lengthAno, HAno],
                    pos=[width / 2 + shift / 2, width / 2, depthAno],
                    marker=4,
                    area=0.01)
plc = mt.mergePLC([world, ano])

# pg.show(plc)
# pg.show(world)

# plc.exportVTK('plc.vtk')
maxA = np.array(ano.boundaryCenters()).max(axis=0)
minA = np.array(ano.boundaryCenters()).min(axis=0)

#%%
n_sensors_surf = 16 * 16
sensors_surf = np.zeros((n_sensors_surf, 3))
# area = [-10.1,10.1,-10.1,10.1]

area = [
    minA[0] - widthAno * 2, maxA[0] + widthAno * 2, minA[0] - widthAno * 2,
Exemplo n.º 22
0
import pygimli.meshtools as mt
from pygimli.physics import Refraction

###############################################################################
# We start by creating a three-layered slope (The model is taken from the BSc
# thesis of Constanze Reinken (University of Bonn).
layer1 = mt.createPolygon([[0.0, 137], [117.5, 164], [117.5, 162], [0.0, 135]],
                          isClosed=True, marker=1, area=1)
layer2 = mt.createPolygon([[0.0, 126], [0.0, 135], [117.5, 162], [117.5, 153]],
                          isClosed=True, marker=2)
layer3 = mt.createPolygon([[0.0, 110], [0.0, 126], [117.5, 153], [117.5, 110]],
                          isClosed=True, marker=3)

slope = (164 - 137) / 117.5

geom = mt.mergePLC([layer1, layer2, layer3])
mesh = mt.createMesh(geom, quality=34.3, area=3, smooth=[1, 10])
pg.show(mesh)

###############################################################################
# Next we define geophone positions and a measurement scheme, which consists of
# shot and receiver indices.

numberGeophones = 48
sensors = np.linspace(0., 117.5, numberGeophones)
scheme = pg.physics.traveltime.createRAData(sensors)

# Adapt sensor positions to slope
pos = np.array(scheme.sensorPositions())
for x in pos[:, 0]:
    i = np.where(pos[:, 0] == x)
Exemplo n.º 23
0
depth = -np.arange(sensor_spacing, bh_length + sensor_spacing, sensor_spacing)

sensors = np.zeros((len(depth) * 2, 2))  # two boreholes
sensors[len(depth):, 0] = bh_spacing  # x
sensors[:, 1] = np.hstack([depth] * 2)  # y

################################################################################
# Traveltime calculations work on unstructured meshes and structured grids. We
# demonstrate this here by simulating the synthetic data on an unstructured mesh
# and inverting it on a simple structured grid.

# Create forward model and mesh
c0 = mt.createCircle(pos=(7.0, -10.0), radius=3, segments=25, marker=1)
c1 = mt.createCircle(pos=(12.0, -18.0), radius=4, segments=25, marker=2)
geom = mt.mergePLC([world, c0, c1])
for sen in sensors:
    geom.createNode(sen)

mesh_fwd = mt.createMesh(geom, quality=34, area=.25)
model = np.array([2000., 2300, 1700])[mesh_fwd.cellMarkers()]
pg.show(mesh_fwd, model, label="Velocity (m/s)", nLevs=3, logScale=False)

################################################################################
# Create inversion mesh
refinement = 0.25
x = np.arange(0, bh_spacing + refinement, sensor_spacing * refinement)
y = -np.arange(0.0, bh_length + 3, sensor_spacing * refinement)
mesh = pg.createMesh2D(x, y)

ax, _ = pg.show(mesh, hold=True)
def generate_dipped_layered_world(world_dim: list, layer_borders: list,
                                  dipping_angle: float):
    """ Creates a dipped layered world.

    Utility function to create a dipped layered world. Region markers are increasing with depth.

    Parameter:
        world_dim: World dimensions as [x,z].
        layer_borders: List of layer borders at world X = 0.
        dipping_angle: Angle at which the layers are dipping. Value describing counter-clockwise angle.

    Returns:
        The created world.
    """

    # Nested function to find the index to add a specific node
    def get_insert_index(nodes, node):
        i = 0
        # Get edge starting index
        while (i < len(nodes)) and (nodes[i][3] < node[3]):
            i = i + 1
        edge_start = i
        # Get edge ending index
        while (i < len(nodes)) and (nodes[i][3] <= node[3]):
            i = i + 1
        edge_end = i
        # Check for input error
        if (node[3] == 0) or (node[3] == 2) or (node[3] == 4) or (node[3]
                                                                  == 6):
            print('Function can only be used for non-default edges (1,3,5,7)')
            return -1
        # Find index based on specific edge
        i = edge_start
        if node[3] == 1:
            while (i < edge_end) and (node[1] > nodes[i][1]):
                i = i + 1
        if node[3] == 3:
            while (i < edge_end) and (node[2] < nodes[i][2]):
                i = i + 1
        if node[3] == 5:
            while (i < edge_end) and (node[1] < nodes[i][1]):
                i = i + 1
        if node[3] == 7:
            while (i < edge_end) and (node[2] > nodes[i][2]):
                i = i + 1
        return i

    # Nested function to find the connecting node of a given node
    def get_connecting_node(nodes_list, node, node_connections_list):
        for i in range(len(node_connections_list)):
            if node_connections_list[i][0] == nodes_list[node][0]:
                for j in range(len(nodes_list)):
                    if node_connections_list[i][1] == nodes_list[j][0]:
                        return j
        return -1

    # Nested function to find the next node on the world border
    def get_next_node(nodes_list, current_node):
        if current_node >= len(nodes_list) - 1:
            return 0
        else:
            return current_node + 1

    # Nested function to create a polygon from a set of nodes
    def get_polygon_from_nodes(node_set):
        vertices = []
        for i in range(len(node_set)):
            vertices.append([node_set[i][1], node_set[i][2]])
        return vertices

    # Correct angle
    while dipping_angle > 180:
        dipping_angle -= 360
    while dipping_angle < -180:
        dipping_angle += 360
    # Create background world
    world = mt.createWorld(start=[0, 0],
                           end=[world_dim[0], -world_dim[1]],
                           worldMarker=True)
    # Remove layers out of world scope
    removed_indices = 0
    for i in range(len(layer_borders)):
        if (dipping_angle >= 0 and layer_borders[i - removed_indices] > 0) or (
                dipping_angle <= 0
                and layer_borders[i - removed_indices] < -world_dim[1]):
            layer_borders.pop(i - removed_indices)
            removed_indices = removed_indices + 1
    # Compute layer height difference based on dipping angle
    dipping_diff = world_dim[0] * math.tan(dipping_angle / 180 * math.pi)
    # Compute nodes on world border (id,x,y,edge)
    nodes = [[0, 0, 0, 0], [1, world_dim[0], 0, 2],
             [2, world_dim[0], -world_dim[1], 4], [3, 0, -world_dim[1], 6]]
    node_connections = []
    next_id = 4
    for i in range(len(layer_borders)):
        # Find starting node
        if layer_borders[i] <= 0 and layer_borders[i] >= -world_dim[1]:
            # Layer starts at left world border (default case)
            start_node = [next_id, 0, layer_borders[i], 7]
        else:
            if layer_borders[i] > 0:
                # Layer starts above world
                x = layer_borders[i] * math.tan(
                    (90 + dipping_angle) * math.pi / 180)
                start_node = [next_id, x, 0, 1]
            else:
                # Layer starts below world
                x = -(layer_borders[i] + world_dim[1]) * math.tan(
                    (90 - dipping_angle) * math.pi / 180)
                start_node = [next_id, x, -world_dim[1], 5]
        nodes.insert(get_insert_index(nodes, start_node), start_node)
        next_id = next_id + 1
        # Find ending node
        if layer_borders[i] + dipping_diff <= 0 and layer_borders[
                i] + dipping_diff >= -world_dim[1]:
            # Layer ends at right world border (default case)
            end_node = [
                next_id, world_dim[0], layer_borders[i] + dipping_diff, 3
            ]
        else:
            if layer_borders[i] + dipping_diff > 0:
                # Layer ends above world
                x = -layer_borders[i] / math.tan(dipping_angle / 180 * math.pi)
                end_node = [next_id, x, 0, 1]
            else:
                # Layer ends below world
                x = world_dim[0] - (layer_borders[i] + dipping_diff +
                                    world_dim[1]) / math.tan(
                                        dipping_angle / 180 * math.pi)
                end_node = [next_id, x, -world_dim[1], 5]
        nodes.insert(get_insert_index(nodes, end_node), end_node)
        next_id = next_id + 1
        # Save node connections
        node_connections.append([start_node[0], end_node[0]])
        node_connections.append([end_node[0], start_node[0]])
    # Compute polygons from nodes
    polygons = []
    first_node = 0
    edge_to_finish = 4
    if dipping_angle < 0:
        for i in range(len(nodes)):
            if nodes[i][3] == 2:
                break
        first_node = i
        edge_to_finish = 6
    while edge_to_finish != -1:
        polygon = []
        last_node_was_connected = False
        has_connected_nodes = False
        current_node_index = first_node
        polygon.append(nodes[first_node])
        while (len(polygon) == 1) or (polygon[len(polygon) - 1] != polygon[0]):
            if (last_node_was_connected
                    == False) and (len(polygon) != 1) and (get_connecting_node(
                        nodes, current_node_index, node_connections) != -1):
                current_node_index = get_connecting_node(
                    nodes, current_node_index, node_connections)
                polygon.append(nodes[current_node_index])
                last_node_was_connected = True
                has_connected_nodes = True
                if nodes[current_node_index][3] == edge_to_finish:
                    edge_to_finish = -1
                continue
            current_node_index = get_next_node(nodes, current_node_index)
            polygon.append(nodes[current_node_index])
            if not has_connected_nodes:
                first_node = current_node_index
            last_node_was_connected = False
            if nodes[current_node_index][3] == edge_to_finish:
                edge_to_finish = -1
        polygons.append(polygon[:-1])
    # Merge geometries
    for i in range(len(polygons)):
        poly = mt.createPolygon(get_polygon_from_nodes(polygons[i]),
                                marker=i + 1,
                                isClosed=True)
        world = mt.mergePLC([world, poly])
    return world
Exemplo n.º 25
0
# In this first part we naively combine objects and assign markers to them,
# expecting two regions of concentric rings with markers 1 and 2. Note how the
# outer ring is assigned the marker 0 in the figure, although we specified
# marker=1 for the larger circle? A marker value of 0 is assigned to a region
# if no region marker is found, indicating that the marker for the outer ring
# was overwritten/ignored by the inner circle, which was added later.
circle_outer = mt.createCircle(pos=[0.0, 0.0], radius=3.0, marker=1)

circle_inner = mt.createCircle(
    pos=[0.0, 0.0],
    radius=1.0,
    # area=.3,
    boundaryMarker=0,
    marker=2)

plc = mt.mergePLC([circle_outer, circle_inner])

ax, cb = pg.show(plc, markers=True)

###############################################################################
# The solution to this problem is the region marker, which defines the marker
# value of the region that it is placed in. By default all region markers are
# assigned the position (0,0,0), thereby overwriting each other (see black dots
# in figure below). If no region marker is present in a region, a marker value
# of 0 is assigned.

fig = ax.get_figure()
for nr, marker in enumerate(plc.regionMarker()):
    print('Position marker number {}:'.format(nr + 1), marker.x(), marker.y(),
          marker.z())
    ax.scatter(marker.x(), marker.y(), s=(2 - nr) * 30, color='k')
Exemplo n.º 26
0
#PARAMETROS MODELADO

noise=0
rhomap= [[0,100],[1,100],[2,200],[3,1000]]

#CREACION MODELO GENERAL

background=mt.createWorld(start=[-10,0],end=[81,-20], area=1,marker=0)

pol0=mt.createPolygon([[-10,-2.5],[81,-2.5],[81,0],[-10,0]], isClosed=True,marker=1)
pol1=mt.createPolygon([[-10,-15],[81,-15],[81,-2.5],[-10,-2.5]], isClosed=True,marker=2)
circle1=mt.createCircle(pos=[25.5,-7.5],radius=2,isClosed=True, marker=3)
circle2=mt.createCircle(pos=[45.5,-7.5],radius=2,isClosed=True, marker=3)
circle3=mt.createCircle(pos=[35.5,-7.5],radius=2,isClosed=True,area=1, marker=3)

world = mt.mergePLC([background,circle1,circle2,pol0,pol1])
mesh= mt.createMesh(world, quality=33, area=0.1,smooth=[1,2])

#EXPORTACION DATOS DE RESISTIVIDAD DEL MODELO (VECTOR)

res_model=pg.solver.parseArgToArray(rhomap, mesh.cellCount(), mesh)

pg.show(mesh,res_model)

#INTERPOLACION DATOS MODELO A MESH INVERSION 

nan=99.9
model_vector = []
for pos in grid.cellCenters():
    cell = mesh.findCell(pos)
    if cell:
Exemplo n.º 27
0
# We start by creating a three-layered slope (The model is taken from the BSc
# thesis of Constanze Reinken (University of Bonn).
layer1 = mt.createPolygon([[0.0, 137], [117.5, 164], [117.5, 162], [0.0, 135]],
                          isClosed=True,
                          marker=1,
                          area=1)
layer2 = mt.createPolygon([[0.0, 126], [0.0, 135], [117.5, 162], [117.5, 153]],
                          isClosed=True,
                          marker=2)
layer3 = mt.createPolygon([[0.0, 110], [0.0, 126], [117.5, 153], [117.5, 110]],
                          isClosed=True,
                          marker=3)

slope = (164 - 137) / 117.5

geom = mt.mergePLC([layer1, layer2, layer3])
mesh = mt.createMesh(geom, quality=34.3, area=3, smooth=[1, 10])
pg.show(mesh)

###############################################################################
# Next we define geophone positions and a measurement scheme, which consists of
# shot and receiver indices.

numberGeophones = 48
sensors = np.linspace(0., 117.5, numberGeophones)
scheme = pg.physics.traveltime.createRAData(sensors)

# Adapt sensor positions to slope
pos = np.array(scheme.sensorPositions())
for x in pos[:, 0]:
    i = np.where(pos[:, 0] == x)
Exemplo n.º 28
0
if not os.path.exists(path_Data):
    os.makedirs(path_Data)

# Create geometry definition for the modelling domain
world = mt.createWorld(start=[-20, 0], end=[20, -16], worldMarker=False)
# Create a heterogeneous block
block = mt.createRectangle(start=[-5, -2.5],
                           end=[5, -5.0],
                           marker=4,
                           boundaryMarker=10,
                           area=0.1)
# block = mt.createRectangle(start=[-5, -5], end=[5, -7.5],
#                             marker=4,  boundaryMarker=10, area=0.1)
# Merge geometrical entities
# geom = mt.mergePLC([world, block])
geom = mt.mergePLC([world, block])

pg.show(geom, boundaryMarker=True, savefig='geometry.pdf')

# Create a mesh from the geometry definition
mesh = mt.createMesh(geom, quality=32, area=0.2, smooth=[1, 10])
# pg.show(mesh, savefig='mesh.pdf')

rMap = [[1, SoilR], [4, AnoR]]

# Map conductivity value per region to each cell in the given mesh
R = pg.solver.parseMapToCellArray(rMap, mesh)
# Dirichlet conditions for hydraulic potential

# Create survey measurement scheme
# ertScheme = ert.createERTData(pg.utils.grange(-20, 20, dx=1.0),
Exemplo n.º 29
0
# -*- coding: utf-8 -*-
"""
Minimal example of using pygimli to simulate the steady heat equation.
"""

import pygimli as pg
import pygimli.meshtools as mt

# Create geometry definition for the modelling domain
world = mt.createWorld(start=[-20, 0], end=[20, -16], layers=[-2, -8],
                       worldMarker=False)
# Create a heterogeneous block
block = mt.createRectangle(start=[-6, -3.5], end=[6, -6.0],
                           marker=4,  boundaryMarker=10, area=0.1)
# Merge geometrical entities
geom = mt.mergePLC([world, block])
pg.show(geom, boundaryMarker=True, savefig='geometry.pdf')

# Create a mesh from the geometry definition
mesh = mt.createMesh(geom, quality=33, area=0.2, smooth=[1, 10])
pg.show(mesh, savefig='mesh.pdf')

# $\diverg(a\grad T)=0$ with $T(bottom)=1$, $T(top)=0$
T = pg.solver.solveFiniteElements(mesh,
                                  a=[[1, 1.0], [2, 2.0], [3, 3.0], [4, 0.1]],
                                  uB=[[8, 1.0], [4, 0.0]], verbose=True)

ax, _ = pg.show(mesh, data=T, label='Temperature $T$', cmap="hot_r",
                showBoundary=True, savefig='T_field.pdf')

#ax, _ = pg.show(mesh, data=T, label='Temperature $T$', cmap="hot_r")
                           boundary=0,
                           paraBoundary=2)

if case == 1:
    for depth in (5, 15):
        start = plc.createNode(mesh.xmin(), -depth, 0.0)
        end = plc.createNode(mesh.xmax(), -depth, 0.0)
        plc.createEdge(start, end, marker=1)

for sensor in ertData.sensorPositions():
    plc.createNode([sensor.x(), sensor.y() - 0.1])

rect = mt.createRectangle([mesh.xmin(), mesh.ymin()],
                          [mesh.xmax(), mesh.ymax()],
                          boundaryMarker=0)
geom = mt.mergePLC([plc, rect])

meshRST = mt.createMesh(geom, quality=34, area=1, smooth=[1, 2])

for cell in meshRST.cells():
    cell.setMarker(2)
for boundary in meshRST.boundaries():
    boundary.setMarker(0)

pg.show(meshRST)
print(meshRST)
# %%
meshRST.save("paraDomain_%d.bms" % case)

meshERT = mt.appendTriangleBoundary(meshRST,
                                    xbound=500,
Exemplo n.º 31
0
m = scheme['m']
n = scheme['n']
scheme['m'] = n
scheme['n'] = m

scheme.set('k', [1 for x in range(scheme.size())])

###############################################################################
# Mesh generation
world = mt.createWorld(start=[-55, 0], end=[105, -80], worldMarker=True)

conductive_anomaly = mt.createCircle(pos=[10, -7], radius=5, marker=2)

polarizable_anomaly = mt.createCircle(pos=[40, -7], radius=5, marker=3)

plc = mt.mergePLC((world, conductive_anomaly, polarizable_anomaly))

# local refinement of mesh near electrodes
for s in scheme.sensors():
    plc.createNode(s + [0.0, -0.2])

mesh_coarse = mt.createMesh(plc, quality=33)
# additional refinements
mesh = mesh_coarse.createH2()

pg.show(plc, marker=True)
pg.show(plc, markers=True)
pg.show(mesh)
###############################################################################
# Prepare the model parameterization
# We have two markers here: 1: background 2: circle anomaly
Exemplo n.º 32
0
# In this first part we naively combine objects and assign markers to them,
# expecting two regions of concentric rings with markers 1 and 2. Note how the
# outer ring is assigned the marker 0 in the figure, although we specified
# marker=1 for the larger circle? A marker value of 0 is assigned to a region
# if no region marker is found, indicating that the marker for the outer ring
# was overwritten/ignored by the inner circle, which was added later.
circle_outer = mt.createCircle(pos=[0.0, 0.0], radius=3.0, marker=1)

circle_inner = mt.createCircle(
    pos=[0.0, 0.0],
    radius=1.0,
    # area=.3,
    boundaryMarker=0,
    marker=2)

plc = mt.mergePLC([circle_outer, circle_inner])

ax, cb = pg.show(plc, markers=True)

###############################################################################
# The solution to this problem is the region marker, which defines the marker
# value of the region that it is placed in. By default all region markers are
# assigned the position (0,0,0), thereby overwriting each other (see black dots
# in figure below). If no region marker is present in a region, a marker value
# of 0 is assigned.

fig = ax.get_figure()
for nr, marker in enumerate(plc.regionMarker()):
    print('Position marker number {}:'.format(nr + 1), marker.x(), marker.y(),
          marker.z())
    ax.scatter(marker.x(), marker.y(), s=(2 - nr) * 30, color='k')