Example #1
0
    def simulate(mesh, res, scheme, verbose=False, **kwargs):
        """Forward calculation vor given mesh, data and resistivity."""
        fop = ERTModelling(verbose=verbose)
        # fop = ERTManager.createFOP(verbose=verbose)

        fop.setData(scheme)
        fop.setMesh(mesh, ignoreRegionManager=True)

        if not scheme.allNonZero('k'):

            if min(pg.y(scheme)) != max(pg.y(scheme)) or min(pg.z(scheme)) != max(pg.z(scheme)):
                pg.info("Non flat earth topography found. "
                    "We will set geometric factors to -1 to emulate "
                    "electrical impedance tomography (EIT). If you want to "
                    "use ERT will full topography support. "
                    "Please consider the use of pyBERT.")

                scheme.set('k', pg.RVector(scheme.size(), -1))
            else:
                scheme.set('k', fop.calcGeometricFactors(scheme))

        rhoa = None
        isArrayData = None

        if hasattr(res[0], '__iter__'):
            isArrayData = True
            rhoa = np.zeros((len(res), scheme.size()))
            for i, r in enumerate(res):
                rhoa[i] = fop.response(r)
        else:
            rhoa = fop.response(res)

        pg.renameKwarg('noisify', 'noiseLevel', kwargs)

        noiseLevel = kwargs.pop('noiseLevel', 0.0)

        if noiseLevel > 0:
            noiseAbs = kwargs.pop('noiseAbs', 1e-4)
            err = noiseLevel + noiseAbs / rhoa
            scheme.set('err', err)
            if verbose:
                pg.info("Set noise (" + str(noiseLevel*100) + "% + " + str(noiseAbs) + " V) min:",
                      min(err), "max:", max(err))
            rhoa *= 1. + pg.randn(scheme.size()) * err

        if isArrayData is None:
            scheme.set('rhoa', rhoa)

        if kwargs.pop('returnArray', False):
            return rhoa
        return scheme
def create_mesh_and_data(n):
    nc = np.linspace(-2.0, 0.0, n)
    mesh = pg.createMesh2D(nc, nc)
    mcx = pg.x(mesh.cellCenter())
    mcy = pg.y(mesh.cellCenter())
    data = np.cos(1.5 * mcx) * np.sin(1.5 * mcy)
    return mesh, data
Example #3
0
    def checkData(self):
        """Check data

        w.r.t. shot/geophone identity and zero/negative
        traveltimes, plus check y/z sensor positions
        """
        oldsize = self.dataContainer.size()
        self.dataContainer.markInvalid(pg.abs(self.dataContainer('s') -
                                              self.dataContainer('g')) < 1)
        self.dataContainer.markInvalid(self.dataContainer('t') <= 0.)
        self.dataContainer.removeInvalid()
        newsize = self.dataContainer.size()

        if newsize < oldsize:
            if self.verbose:
                print('Removed ' + str(oldsize - newsize) + ' values.')

        maxyabs = max(pg.abs(pg.y(self.dataContainer.sensorPositions())))
        maxzabs = max(pg.abs(pg.z(self.dataContainer.sensorPositions())))

        if maxzabs > 0 and maxyabs == 0:
            for i in range(self.dataContainer.sensorCount()):
                pos = self.dataContainer.sensorPosition(i).rotateX(-pi / 2)
                self.dataContainer.setSensorPosition(i, pos)

        if self.verbose:
            print(self.dataContainer)
def cellDataToCellGrad(mesh, v, CtB):
    if len(v) != mesh.cellCount():
        print(len(v), mesh.cellCount())
        raise
    div = mesh.boundaryDataToCellGradient(CtB * v)
    return np.vstack([pg.x(div), pg.y(div), pg.z(div)]).T

    vF = cellDataToBoundaryData(mesh, v)
    gC = np.zeros((mesh.cellCount(), 3))

    for b in mesh.boundaries():

        leftCell = b.leftCell()
        rightCell = b.rightCell()
        vec = b.norm() * vF[b.id()] * b.size()

        if leftCell:
            gC[leftCell.id(), 0] += vec[0]
            gC[leftCell.id(), 1] += vec[1]
            gC[leftCell.id(), 2] += vec[2]
        if rightCell:
            gC[rightCell.id(), 0] -= vec[0]
            gC[rightCell.id(), 1] -= vec[1]
            gC[rightCell.id(), 2] -= vec[2]

    gC[:, 0] /= mesh.cellSizes()
    gC[:, 1] /= mesh.cellSizes()
    gC[:, 2] /= mesh.cellSizes()

    return gC
def cellDataToBoundaryGrad(mesh, v, vGrad):
    """
    """
    if len(v) != mesh.cellCount() or len(vGrad) != mesh.cellCount():
        raise
    gB = mesh.cellDataToBoundaryGradient(v, vGrad)
    return np.vstack([pg.x(gB), pg.y(gB), pg.z(gB)]).T

    gB = np.zeros((mesh.boundaryCount(), 3))

    for b in mesh.boundaries():
        leftCell = b.leftCell()
        rightCell = b.rightCell()
        gr = pg.RVector3(0.0, 0.0, 0.0)
        t = (b.node(1).pos() - b.node(0).pos()).norm()

        if leftCell and rightCell:
            df1 = b.center().distance(leftCell.center())
            df2 = b.center().distance(rightCell.center())

            gr = b.norm() * \
                (v[rightCell.id()] - v[leftCell.id()]) / (df1 + df2)

            grL = t * t.dot(vGrad[leftCell.id()])
            grR = t * t.dot(vGrad[rightCell.id()])

            gr += (grL + grR) * 0.5

        elif leftCell:
            gr = t * t.dot(vGrad[leftCell.id()])

        gB[b.id(), 0] = gr[0]
        gB[b.id(), 1] = gr[1]
        gB[b.id(), 2] = gr[2]
    return gB
Example #6
0
    def showVAold(self, vals=None, ax=None, usepos=True, name='va'):
        """show apparent velocity as image plot (old style)"""
        va = self.getVA(t=vals)
        data = self.dataContainer
        A = np.ones((data.sensorCount(), data.sensorCount())) * np.nan
        for i in range(data.size()):
            A[int(data('s')[i]), int(data('g')[i])] = va[i]

        if ax is None:
            fig, ax = plt.subplots()
            self.figs[name] = fig

        gci = ax.imshow(A, interpolation='nearest')
        ax.grid(True)
        if usepos:
            xt = np.linspace(0, data.sensorCount()-1, 7)
            xt.round()
            px = pg.abs(pg.y(self.dataContainer.sensorPositions()))
            ax.set_xticks(xt)
            ax.set_xticklabels([str(int(px[int(xti)])) for xti in xt])
            ax.set_yticks(xt)
            ax.set_yticklabels([str(int(px[int(xti)])) for xti in xt])

        plt.colorbar(gci, ax=ax)
        return va
Example #7
0
File: mesh.py Project: wk1984/gimli
def transform2DMeshTo3D(mesh, x, y, z=None):
    """
    Transform a 2D mesh into 3D coordinates using a point list (e.g. from GPS)

    Parameters
    ----------
    mesh: GIMLi::Mesh
    x,y: array of x/y positions along 2d profile
    z: optional height to add (topographical correction if computed flat earth)

    See Also
    --------

    References
    ----------
    """

    # get mesh node positions
    mt, mz = pg.x( mesh.positions() ), pg.y( mesh.positions() ) # mesh tape and z
    # compute length of reference points along tape
    pt = np.hstack( (0., np.cumsum( np.sqrt( np.diff( x )**2 + np.diff( y )**2 ) ) ) )
    #  interpolate node positions from tape to x/y using tape positions
    mx = np.interp( mt, pt, x )
    my = np.interp( mt, pt, y )
    # compute z offset by interpolating z
    if z is None:
        oz = np.zeros( len(mt) )
    else:
        oz = np.interp( mt, pt, z )

    # set the positions in the mesh
    for i, node in enumerate( mesh.nodes() ):
        node.setPos( pg.RVector3( mx[i], my[i], mz[i]+oz[i] ) )
Example #8
0
def createCoarsePoly( coarseData ):
    boundary = 1250.0
    mesh = g.Mesh()

    x = g.x( coarseData )
    y = g.y( coarseData )
    z = g.z( coarseData )

    xMin = min( x ); xMax = max( x )    
    yMin = min( y ); yMax = max( y )
    zMin = min( z ); zMax = max( z )        

    print(xMin, xMax, yMin, yMax)
    border = max( (xMax - xMin) * boundary / 100.0, (yMax - yMin) * boundary / 100.0);

    n1 = mesh.createNode( xMin - border, yMin - border, zMin, 1 )
    n2 = mesh.createNode( xMax + border, yMin - border, zMin, 2 )
    n3 = mesh.createNode( xMax + border, yMax + border, zMin, 3 )
    n4 = mesh.createNode( xMin - border, yMax + border, zMin, 4 )
  
    mesh.createEdge( n1, n2, 12 );
    mesh.createEdge( n2, n3, 23 );
    mesh.createEdge( n3, n4, 34 );
    mesh.createEdge( n4, n1, 41 );

    for p in coarseData:
        mesh.createNode( p )

    return mesh
Example #9
0
def cellDataToBoundaryGrad(mesh, v, vGrad):
    """TODO Documentme."""
    if len(v) != mesh.cellCount() or len(vGrad) != mesh.cellCount():
        raise BaseException("len(v) dismatch mesh.cellCount()")

    gB = mesh.cellDataToBoundaryGradient(v, vGrad)
    return np.vstack([pg.x(gB), pg.y(gB), pg.z(gB)]).T
Example #10
0
def cellDataToCellGrad(mesh, v, CtB):
    """TODO Documentme."""
    if len(v) != mesh.cellCount():
        print(len(v), mesh.cellCount())
        raise BaseException("len of v missmatch mesh.cellCount()")
    div = mesh.boundaryDataToCellGradient(CtB * v)
    return np.vstack([pg.x(div), pg.y(div), pg.z(div)]).T
Example #11
0
    def showVA(self, t=None, ax=None, usepos=True, name='va', squeeze=True):
        """show apparent velocity as image plot"""
        # va = self.getVA(vals=vals)
        xvec = self.dataContainer('g')
        yvec = self.dataContainer('s')
        if usepos:
            pz = pg.y(self.dataContainer.sensorPositions())
            if squeeze:
                xvec = pz[xvec]
                yvec = pz[yvec]
            else:
                pz = pg.y(self.dataContainer.sensorPositions())
                raise Exception('Implement ME')
                # xvec = px[xvec]*1000 + pz[xvec]
                # xvec = px[yvec]*1000 + pz[yvec]

        plotVecMatrix(xvec, yvec, vals=t, squeeze=squeeze, ax=ax, name=name)
Example #12
0
    def ani(i):
        axGra.clear()
        axGra.plot(pg.x(gravPoints), dz[i])
        axGra.plot(pg.x(gravPoints), pg.y(gravPoints), 'v', color='black')
        axGra.set_ylabel('Grav in mGal')
        axGra.set_xlim((-20, 20))
        axGra.set_ylim((0, 0.001))
        axGra.grid()

        pg.mplviewer.setMappableData(gciDDe, abs(dDens[i]),
                                     cMin=0, cMax=20,
                                     logScale=False)
Example #13
0
def createGradientModel2D(data, mesh, VTop, VBot):
    """
    Create 2D velocity gradient model.

    Creates a smooth, linear, starting model that takes the slope
    of the topography into account. This is done by fitting a straight line
    and using the distance to that as the depth value.
    Known as "The Marcus method"


    Parameters
    ----------
    data : pygimli DataContainer
        The topography list is in here.
    mesh : pygimli.Mesh
        The parametric mesh used for the inversion
    VTop : float
        The velocity at the surface of the mesh
    VBot : float
        The velocity at the bottom of the mesh

    Returns
    -------
    model : pygimli Vector, length M
        A numpy array with slowness values that can be used to start
        the inversion.
    """

    p = np.polyfit(pg.x(data.sensorPositions()), pg.y(data.sensorPositions()),
                   deg=1)  # slope-intercept form
    n = np.asarray([-p[0], 1.0])  # normal vector
    nLen = np.sqrt(np.dot(n, n))

    x = pg.x(mesh.cellCenters())
    z = pg.y(mesh.cellCenters())
    pos = np.column_stack((x, z))
    d = np.array([np.abs(np.dot(pos[i, :], n) - p[1]) / nLen
                  for i in range(pos.shape[0])])

    return np.interp(d, [min(d), max(d)], [1.0 / VTop, 1.0 / VBot])
Example #14
0
def createGradientModel2D(data, mesh, vTop, vBot):
    """Create 2D velocity gradient model.

    Creates a smooth, linear, starting model that takes the slope
    of the topography into account. This is done by fitting a straight line
    and using the distance to that as the depth value.
    Known as "The Marcus method"


    Parameters
    ----------
    data : pygimli DataContainer
        The topography list is in here.
    mesh : pygimli.Mesh
        The parametric mesh used for the inversion
    vTop : float
        The velocity at the surface of the mesh
    vBot : float
        The velocity at the bottom of the mesh

    Returns
    -------
    model : pygimli Vector, length M
        A numpy array with slowness values that can be used to start
        the inversion.
    """
    p = np.polyfit(pg.x(data.sensorPositions()), pg.y(data.sensorPositions()),
                   deg=1)  # slope-intercept form
    n = np.asarray([-p[0], 1.0])  # normal vector
    nLen = np.sqrt(np.dot(n, n))

    x = pg.x(mesh.cellCenters())
    z = pg.y(mesh.cellCenters())
    pos = np.column_stack((x, z))
    d = np.array([np.abs(np.dot(pos[i, :], n) - p[1]) / nLen
                  for i in range(pos.shape[0])])

    return 1. / np.interp(d, [min(d), max(d)], [vTop, vBot])
Example #15
0
    def ani(i):
        axGra.clear()
        axGra.plot(pg.x(gravPoints), dz[i])
        axGra.plot(pg.x(gravPoints), pg.y(gravPoints), 'v', color='black')
        axGra.set_ylabel('Grav in mGal')
        axGra.set_xlim((-20, 20))
        axGra.set_ylim((0, 0.001))
        axGra.grid()

        pg.mplviewer.setMappableData(gciDDe,
                                     abs(dDens[i]),
                                     cMin=0,
                                     cMax=20,
                                     logScale=False)
Example #16
0
def createTriangles(mesh, data=None):
    """
        What is this?
    """
    x = pg.x(mesh.positions())
#    x.round(1e-1)
    y = pg.y(mesh.positions())
#    y.round(1e-1)

    triCount = 0

    for c in mesh.cells():
        if c.shape().nodeCount() == 4:
            triCount = triCount + 2
        else:
            triCount = triCount + 1

    triangles = np.zeros((triCount, 3))
    dataIdx = list(range(triCount))

    triCount = 0
    for c in mesh.cells():
        if c.shape().nodeCount() == 4:
            triangles[triCount, 0] = c.node(0).id()
            triangles[triCount, 1] = c.node(1).id()
            triangles[triCount, 2] = c.node(2).id()
            dataIdx[triCount] = c.id()
            triCount = triCount + 1

            triangles[triCount, 0] = c.node(0).id()
            triangles[triCount, 1] = c.node(2).id()
            triangles[triCount, 2] = c.node(3).id()
            dataIdx[triCount] = c.id()
            triCount = triCount + 1
        else:
            triangles[triCount, 0] = c.node(0).id()
            triangles[triCount, 1] = c.node(1).id()
            triangles[triCount, 2] = c.node(2).id()
            dataIdx[triCount] = c.id()
            triCount = triCount + 1

    z = None
    if data is not None:
        if len(data) == mesh.cellCount():
            # strange behavior if we just use these slice
            z = np.array(data[dataIdx])
        else:
            z = np.array(data)

    return x, y, triangles, z, dataIdx
Example #17
0
def cellDataToBoundaryData(mesh, vec):
    """
        DOCUMENT_ME
    """
    if len(data) != mesh.cellCount():
        raise BaseException("Dimension mismatch, expecting cellCount(): " 
                            + str(mesh.cellCount()) 
                            + "got: " + str(len(vec)), str(len(vec[0])))
    
    CtB = mesh.cellToBoundaryInterpolation()
    
    if type(vec) == pg.R3Vector():
        return np.array([CtB*pg.x(vec), CtB*pg.y(vec), CtB*pg.z(vec)]).T
    else:
        return CtB*vec
Example #18
0
 def calcGeometricFactor(self, data):
     """Calculate geometry factors for a given dataset."""
     if pg.y(data.sensorPositions()) == pg.z(data.sensorPositions()):
         k = np.zeros(data.size())
         for i in range(data.size()):
             a = data.sensorPosition(data('a')[i])
             b = data.sensorPosition(data('b')[i])
             m = data.sensorPosition(data('m')[i])
             n = data.sensorPosition(data('n')[i])
             k[i] = 1. / (2. * np.pi) * (1. / a.dist(m) - 1. / a.dist(n) -
                                         1. / b.dist(m) + 1. / b.dist(n))
         return k
     else:
         raise BaseException("Please use BERT for non-standard "
                             "data sets" + str(data))
Example #19
0
def cellDataToBoundaryData(mesh, data):
    """ TODO DOCUMENT_ME """
    if len(data) != mesh.cellCount():
        raise BaseException(
            "Dimension mismatch, expecting cellCount(): " +
            str(mesh.cellCount()) + "got: " + str(len(data)),
            str(len(data[0])))

    CtB = mesh.cellToBoundaryInterpolation()

    if isinstance(data, pg.R3Vector()):
        return np.array([CtB * pg.x(data), CtB * pg.y(data),
                         CtB * pg.z(data)]).T
    else:
        return CtB * data
Example #20
0
def cellDataToBoundaryData(mesh, data):
    """ TODO DOCUMENT_ME """
    if len(data) != mesh.cellCount():
        raise BaseException("Dimension mismatch, expecting cellCount(): " +
                            str(mesh.cellCount()) +
                            "got: " + str(len(data)), str(len(data[0])))

    CtB = mesh.cellToBoundaryInterpolation()

    if isinstance(data, pg.R3Vector()):
        return np.array([CtB * pg.x(data),
                         CtB * pg.y(data),
                         CtB * pg.z(data)]).T
    else:
        return CtB * data
Example #21
0
def createTriangles(mesh, data=None):
    """TODO Documentme."""
    x = pg.x(mesh.positions())
    #    x.round(1e-1)
    y = pg.y(mesh.positions())
    #    y.round(1e-1)

    triCount = 0

    for c in mesh.cells():
        if c.shape().nodeCount() == 4:
            triCount = triCount + 2
        else:
            triCount = triCount + 1

    triangles = np.zeros((triCount, 3))
    dataIdx = list(range(triCount))

    triCount = 0
    for c in mesh.cells():
        if c.shape().nodeCount() == 4:
            triangles[triCount, 0] = c.node(0).id()
            triangles[triCount, 1] = c.node(1).id()
            triangles[triCount, 2] = c.node(2).id()
            dataIdx[triCount] = c.id()
            triCount = triCount + 1

            triangles[triCount, 0] = c.node(0).id()
            triangles[triCount, 1] = c.node(2).id()
            triangles[triCount, 2] = c.node(3).id()
            dataIdx[triCount] = c.id()
            triCount = triCount + 1
        else:
            triangles[triCount, 0] = c.node(0).id()
            triangles[triCount, 1] = c.node(1).id()
            triangles[triCount, 2] = c.node(2).id()
            dataIdx[triCount] = c.id()
            triCount = triCount + 1

    z = None
    if data is not None:
        if len(data) == mesh.cellCount():
            # strange behavior if we just use these slice
            z = np.array(data[dataIdx])
        else:
            z = np.array(data)

    return x, y, triangles, z, dataIdx
Example #22
0
    def calcGeometricFactors(self, data):
        """Calculate geometry factors for a given dataset."""
        if pg.y(data) == pg.z(data):
            k = np.zeros(data.size())

            for i in range(data.size()):
                a = data.sensorPosition(data('a')[i])
                b = data.sensorPosition(data('b')[i])
                m = data.sensorPosition(data('m')[i])
                n = data.sensorPosition(data('n')[i])
                k[i] = 2.*np.pi * 1./(1./a.dist(m) - 1./a.dist(n) - 
                                      1./b.dist(m) + 1./b.dist(n))
            return k
        else:
            raise BaseException("Please use BERT for non-standard "
                                "data sets" + str(data))
Example #23
0
def exportHDF5Mesh(mesh,
                   exportname,
                   group='mesh',
                   indices='cell_indices',
                   pos='coordinates',
                   cells='topology',
                   marker='values'):
    """Writes given :gimliapi:`GIMLI::Mesh` in a hdf5 format file.

    3D tetrahedron meshes only! Boundary markers are ignored.

    Keywords are explained in :py:mod:`pygimli.meshtools.readHDFS`
    """
    h5py = pg.optImport('h5py', requiredFor='export mesh in .h5 data format')

    if not isinstance(mesh, pg.Mesh):
        mesh = pg.Mesh(mesh)

    # prepare output for writing in hdf data container
    pg_pos = mesh.positions()
    mesh_pos = np.array((np.array(pg.x(pg_pos)), np.array(pg.y(pg_pos)),
                         np.array(pg.z(pg_pos)))).T

    mesh_cells = np.zeros((mesh.cellCount(), 4))  # hard coded for tetrahedrons
    for i, cell in enumerate(mesh.cells()):
        mesh_cells[i] = cell.ids()

    mesh_indices = np.arange(0, mesh.cellCount() + 1, 1, dtype=np.int64)
    mesh_markers = np.array(mesh.cellMarkers())

    with h5py.File(exportname, 'w') as out:
        for grp in np.atleast_1d(group):  # can use more than one group
            # writing indices
            idx_name = '{}/{}'.format(grp, indices)
            out.create_dataset(idx_name, data=mesh_indices, dtype=int)
            # writing node positions
            pos_name = '{}/{}'.format(grp, pos)
            out.create_dataset(pos_name, data=mesh_pos, dtype=float)
            # writing cells via indices
            cells_name = '{}/{}'.format(grp, cells)
            out.create_dataset(cells_name, data=mesh_cells, dtype=int)
            # writing marker
            marker_name = '{}/{}'.format(grp, marker)
            out.create_dataset(marker_name, data=mesh_markers, dtype=int)
            out[grp][cells].attrs['celltype'] = np.string_('tetrahedron')
            out[grp][cells].attrs.create('partition', [0])
    return True
Example #24
0
def solveDarcy(mesh, k=None, p0=1, verbose=False):
    """Darcy flow."""
    if verbose:
        print("Solve Darcy equation ...")

    uDir = [[2, p0],  # left aquiver
            [3, p0],  # left bedrock
            # [4, 0],  # bottom (paper)
            [5, 0],  # right bedrock
            [6, 0],  # right aquiver
            [7, 0],  # right top
            ]

    p = pg.solver.solve(mesh, a=k, bc={'Dirichlet': uDir}, verbose=True)
    vel = -pg.solver.grad(mesh, p) * np.asarray([k, k, k]).T
    mvel = mt.cellDataToNodeData(mesh, vel)
    return mesh, mvel, p, k, np.asarray([pg.x(vel), pg.y(vel)])
Example #25
0
def createFinePoly( coarseMesh, ePos ):
    paraBoundary = 10
    mesh = g.Mesh()
    
    n1 = None; n2 = None; n3 = None; n4 = None
    for n in coarseMesh.nodes():
        if n.marker() == 1:
            n1 = mesh.createNode( n.pos(), 1 )
        elif n.marker() == 2:
            n2 = mesh.createNode( n.pos(), 2 )
        elif n.marker() == 3:
            n3 = mesh.createNode( n.pos(), 3 )
        elif n.marker() == 4:
            n4 = mesh.createNode( n.pos(), 4 )

    mesh.createEdge( n1, n2, 12 );
    mesh.createEdge( n2, n3, 23 );
    mesh.createEdge( n3, n4, 34 );
    mesh.createEdge( n4, n1, 41 );

    x = g.x( ePos )
    y = g.y( ePos )
    z = g.z( ePos )

    xMin = min( x ); xMax = max( x )    
    yMin = min( y ); yMax = max( y )
    zMin = min( z ); zMax = max( z )

    maxSpan = max( xMax - xMin, yMax - yMin );
    borderPara = maxSpan * paraBoundary / 100.0;

    n5 = mesh.createNode( xMin - borderPara, yMin - borderPara , 0.0, 5 );
    n6 = mesh.createNode( xMax + borderPara, yMin - borderPara , 0.0, 6 );
    n7 = mesh.createNode( xMax + borderPara, yMax + borderPara , 0.0, 7 );
    n8 = mesh.createNode( xMin - borderPara, yMax + borderPara , 0.0, 8 );

    mesh.createEdge( n5, n6, 56 );
    mesh.createEdge( n6, n7, 67 );
    mesh.createEdge( n7, n8, 78 );
    mesh.createEdge( n8, n5, 85 );

    for p in ePos:
        mesh.createNode( p )

    return mesh;
Example #26
0
def exportHDF5Mesh(mesh,
                   exportname,
                   group='mesh',
                   indices='cell_indices',
                   pos='coordinates',
                   cells='topology',
                   marker='values'):
    '''
    3D tetrahedron meshes only! Boundary markers are ignored.

    Keywords are explained in "readH5"
    '''
    h5py = pg.io.opt_import('h5py',
                            requiredTo='export mesh in .h5 data format')
    if not isinstance(mesh, pg.Mesh):
        mesh = pg.Mesh(mesh)

    # prepare output for writing in hdf data container
    pg_pos = mesh.positions()
    mesh_pos = np.array((np.array(pg.x(pg_pos)), np.array(pg.y(pg_pos)),
                         np.array(pg.z(pg_pos)))).T

    mesh_cells = np.zeros((mesh.cellCount(), 4))  # hard coded for tetrahedrons
    for i, cell in enumerate(mesh.cells()):
        mesh_cells[i] = cell.ids()

    mesh_indices = np.arange(0, mesh.cellCount() + 1, 1, dtype=np.int64)
    mesh_markers = np.array(mesh.cellMarkers())

    with h5py.File(exportname, 'w') as out:
        # writing indices
        idx_name = '{}/{}'.format(group, indices)
        out.create_dataset(idx_name, data=mesh_indices, dtype=np.int64)
        # writing node positions
        pos_name = '{}/{}'.format(group, pos)
        out.create_dataset(pos_name, data=mesh_pos, dtype=float)
        # writing cells via indices
        cells_name = '{}/{}'.format(group, cells)
        out.create_dataset(cells_name, data=mesh_cells, dtype=np.int64)
        # writing marker
        marker_name = '{}/{}'.format(group, marker)
        out.create_dataset(marker_name, data=mesh_markers, dtype=np.uint64)
        out[group][cells].attrs['celltype'] = np.array(('tetrahedron'))
        out[group][cells].attrs['partition'] = np.array([0], dtype=np.uint64)
    return True
Example #27
0
def rst_cov(mesh, cov):
    """ Simplify refraction coverage with convex hull. """
    points_all = np.column_stack((
        pg.x(mesh.cellCenters()),
        pg.y(mesh.cellCenters()),
    ))

    points = points_all[np.nonzero(cov)[0]]
    hull = ConvexHull(points)
    hull_path = Path(points[hull.vertices])

    covs = []
    for cell in mesh.cells():
        if hull_path.contains_point(points_all[cell.id()]):
            covs.append(1)
        else:
            covs.append(0)
    return np.array(covs)
Example #28
0
    def checkData(self):
        """ check data w.r.t. shot/geophone identity and zero/negative
        traveltimes, plus check y/z sensor positions """
        oldsize = self.data.size()
        self.data.markInvalid(pg.abs(self.data("s") - self.data("g")) < 1)
        self.data.markInvalid(self.data("t") <= 0.0)
        self.data.removeInvalid()
        newsize = self.data.size()
        if newsize < oldsize:
            print("Removed " + str(oldsize - newsize) + " values.")
        maxyabs = max(pg.abs(pg.y(self.data.sensorPositions())))
        maxzabs = max(pg.abs(pg.z(self.data.sensorPositions())))
        if maxzabs > 0 and maxyabs == 0:
            for i in range(self.data.sensorCount()):
                pos = self.data.sensorPosition(i).rotateX(-pi / 2)
                self.data.setSensorPosition(i, pos)

        print(self.data)
Example #29
0
def solveDarcy(mesh, k=None, p0=1, verbose=False):
    """Darcy flow."""
    if verbose:
        print("Solve Darcy equation ...")

    uDir = [
        [2, p0],  # left aquiver
        [3, p0],  # left bedrock
        # [4, 0],  # bottom (paper)
        [5, 0],  # right bedrock
        [6, 0],  # right aquiver
        [7, 0],  # right top
    ]

    p = pg.solver.solve(mesh, a=k, uB=uDir)
    vel = -pg.solver.grad(mesh, p) * np.asarray([k, k, k]).T
    mvel = mt.cellDataToNodeData(mesh, vel)
    return mesh, mvel, p, k, np.asarray([pg.x(vel), pg.y(vel)])
Example #30
0
    def drawRayPaths(self, ax, model=None, **kwargs):
        """Draw the the ray paths for model or last model.

        If model is not specifies, the last calculated Jacobian is used.

        Parameters
        ----------
        model : array
            Velocity model for which to calculate and visualize ray paths (the
            default is model for last Jacobian calculation in self.velocity).
        ax : matplotlib.axes object
            To draw the model and the path into.
        **kwargs : type
            Additional arguments passed to LineCollection (alpha, linewidths,
            color, linestyles).

        Returns
        -------
        lc : matplotlib.LineCollection
        """
        if model is not None:
            if self.fop.jacobian().size() == 0 or model != self.model:
                self.fop.createJacobian(1/model)
        else:
            model = self.model

        _ = kwargs.setdefault("color", "w")
        _ = kwargs.setdefault("alpha", 0.5)
        _ = kwargs.setdefault("linewidths", 0.8)

        shots = self.fop.data.id("s")
        recei = self.fop.data.id("g")

        segs = []
        for s, g in zip(shots, recei):
            wi = self.fop.way(s, g)
            points = self.fop._core.mesh().positions(withSecNodes=True)[wi]
            segs.append(np.column_stack((pg.x(points), pg.y(points))))

        lc = LineCollection(segs, **kwargs)
        ax.add_collection(lc)

        return lc
Example #31
0
def exportHDF5Mesh(mesh, exportname, group='mesh', indices='cell_indices',
                   pos='coordinates', cells='topology', marker='values'):
    """Writes given :gimliapi:`GIMLI::Mesh` in a hdf5 format file.

    3D tetrahedron meshes only! Boundary markers are ignored.

    Keywords are explained in :py:mod:`pygimli.meshtools.readHDFS`
    """
    h5py = pg.optImport('h5py',
                        requiredFor='export mesh in .h5 data format')

    if not isinstance(mesh, pg.Mesh):
        mesh = pg.Mesh(mesh)

    # prepare output for writing in hdf data container
    pg_pos = mesh.positions()
    mesh_pos = np.array((np.array(pg.x(pg_pos)), np.array(pg.y(pg_pos)),
                         np.array(pg.z(pg_pos)))).T

    mesh_cells = np.zeros((mesh.cellCount(), 4))  # hard coded for tetrahedrons
    for i, cell in enumerate(mesh.cells()):
        mesh_cells[i] = cell.ids()

    mesh_indices = np.arange(0, mesh.cellCount() + 1, 1, dtype=np.int64)
    mesh_markers = np.array(mesh.cellMarkers())

    with h5py.File(exportname, 'w') as out:
        for grp in np.atleast_1d(group):  # can use more than one group
            # writing indices
            idx_name = '{}/{}'.format(grp, indices)
            out.create_dataset(idx_name, data=mesh_indices, dtype=int)
            # writing node positions
            pos_name = '{}/{}'.format(grp, pos)
            out.create_dataset(pos_name, data=mesh_pos, dtype=float)
            # writing cells via indices
            cells_name = '{}/{}'.format(grp, cells)
            out.create_dataset(cells_name, data=mesh_cells, dtype=int)
            # writing marker
            marker_name = '{}/{}'.format(grp, marker)
            out.create_dataset(marker_name, data=mesh_markers, dtype=int)
            out[grp][cells].attrs['celltype'] = np.string_('tetrahedron')
            out[grp][cells].attrs.create('partition', [0])
    return True
Example #32
0
    def createMesh(self, quality=34.6, maxarea=0.1, addpoints=None):
        """Create (inversion) mesh by circumventing PLC"""
        data = self.dataContainer
        sx = list(pg.x(data.sensorPositions()))
        sz = list(pg.y(data.sensorPositions()))

        if addpoints is not None:
            for po in addpoints:
                sx.append(po[0])
                sz.append(po[1])

        iS = np.argsort(np.arctan2(sx-np.mean(sx), sz-np.mean(sz)))
        plc = pg.Mesh(2)
        nodes = [plc.createNode(sx[i], sz[i], 0) for i in iS]
        for i in range(len(nodes)-1):
            plc.createEdge(nodes[i], nodes[i+1])

        plc.createEdge(nodes[-1], nodes[0])
        tri = pg.TriangleWrapper(plc)
        tri.setSwitches("-pzFq"+str(quality)+"a"+str(maxarea))
        self.setMesh(tri.generate())
Example #33
0
    def createMesh(self, quality=34.6, maxarea=0.1, addpoints=None):
        """Create (inversion) mesh by circumventing PLC"""
        data = self.dataContainer
        sx = list(pg.x(data.sensorPositions()))
        sz = list(pg.y(data.sensorPositions()))

        if addpoints is not None:
            for po in addpoints:
                sx.append(po[0])
                sz.append(po[1])

        iS = np.argsort(np.arctan2(sx - np.mean(sx), sz - np.mean(sz)))
        plc = pg.Mesh(2)
        nodes = [plc.createNode(sx[i], sz[i], 0) for i in iS]
        for i in range(len(nodes) - 1):
            plc.createEdge(nodes[i], nodes[i + 1])

        plc.createEdge(nodes[-1], nodes[0])
        tri = pg.TriangleWrapper(plc)
        tri.setSwitches("-pzFq" + str(quality) + "a" + str(maxarea))
        self.setMesh(tri.generate())
Example #34
0
    def showVA(self, data=None, t=None, name='va', pseudosection=False,
               squeeze=True, full=True, ax=None, cmap=None, **kwargs):
        """Show apparent velocity as image plot.

        TODO showXXX commands need to return ax and cbar .. if there is one
        """
        if data is None:
            data = self.dataContainer

        if ax is None:
            fig, ax = plt.subplots()
            self.figs[name] = fig

        self.axs[name] = ax
        if t is None:
            t = data('t')

        px = pg.x(data.sensorPositions())
        py = pg.y(data.sensorPositions())
        if len(np.unique(py)) > len(np.unique(px)):  # probably crosshole
            px = py

        gx = np.array([px[int(g)] for g in data("g")])
        sx = np.array([px[int(s)] for s in data("s")])
        offset = self.getOffset(data=data, full=full)
        kwargs.setdefault('vals', offset / t)

        if pseudosection:
            midpoint = (gx + sx) / 2
            _, cb = showVecMatrix(midpoint, offset, squeeze=True, ax=ax,
                                  label='Apparent slowness [s/m]', cmap=cmap,
                                  **kwargs)
        else:
            _, cb = showVecMatrix(gx, sx, squeeze=squeeze, ax=ax,
                                  label='Apparent velocity [m/s]', cmap=cmap,
                                  **kwargs)
        ax.figure.show()
        return ax, cb
Example #35
0
def transform2DMeshTo3D(mesh, x, y, z=None):
    """2D mesh into 3D coordinates.

    Transform a 2D mesh into 3D coordinates using a point list (e.g. from GPS)

    Parameters
    ----------
    mesh: :gimliapi:`GIMLI::Mesh`

    x,y: [float]
        array of x/y positions along 2d profile

    z: [float]
        optional height to add (topographical correction on top of flat earth)

    See Also
    --------

    References
    ----------
    """
    # get mesh node positions
    mt, mz = pg.x(mesh.positions()), pg.y(mesh.positions())  # mesh tape and z
    # compute length of reference points along tape
    pt = np.hstack((0., np.cumsum(np.sqrt(np.diff(x)**2 + np.diff(y)**2))))
    #  interpolate node positions from tape to x/y using tape positions
    mx = np.interp(mt, pt, x)
    my = np.interp(mt, pt, y)
    # compute z offset by interpolating z
    if z is None:
        oz = np.zeros(len(mt))
    else:
        oz = np.interp(mt, pt, z)

    # set the positions in the mesh
    for i, node in enumerate(mesh.nodes()):
        node.setPos(pg.RVector3(mx[i], my[i], mz[i] + oz[i]))
Example #36
0
    def checkData(self):
        """check data w.r.t. shot/geophone identity and zero/negative
        traveltimes, plus check y/z sensor positions """
        oldsize = self.dataContainer.size()
        self.dataContainer.markInvalid(
            pg.abs(self.dataContainer('s') - self.dataContainer('g')) < 1)
        self.dataContainer.markInvalid(self.dataContainer('t') <= 0.)
        self.dataContainer.removeInvalid()
        newsize = self.dataContainer.size()

        if newsize < oldsize:
            if self.verbose:
                print('Removed ' + str(oldsize - newsize) + ' values.')

        maxyabs = max(pg.abs(pg.y(self.dataContainer.sensorPositions())))
        maxzabs = max(pg.abs(pg.z(self.dataContainer.sensorPositions())))

        if maxzabs > 0 and maxyabs == 0:
            for i in range(self.dataContainer.sensorCount()):
                pos = self.dataContainer.sensorPosition(i).rotateX(-pi / 2)
                self.dataContainer.setSensorPosition(i, pos)

        if self.verbose:
            print(self.dataContainer)
Example #37
0
def testShowVariants():
    # Create geometry definition for the modelling domain
    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 = 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')

    pg.show(mesh, ax=axs[1][0])
    axs[1][0].set_title('mesh, (default)')
    pg.show(mesh, mesh.cellMarkers(), label='Cell markers', ax=axs[1][1])
    axs[1][1].set_title('mesh, cells, (default)')
    pg.show(mesh, markers=True, ax=axs[1][2])
    axs[1][2].set_title('mesh, cells, markers=True')
    pg.show(mesh,
            mesh.cellMarkers(),
            label='Cell markers',
            showMesh=True,
            ax=axs[1][3])
    axs[1][3].set_title('mesh, cells, showMesh=True')
    pg.show(mesh,
            mesh.cellMarkers(),
            label='Cell markers',
            showBoundary=False,
            ax=axs[1][4])
    axs[1][4].set_title('mesh, cells, showBoundary=False')

    pg.show(mesh, pg.x(mesh), label='Nodes (x)', ax=axs[2][0])
    axs[2][0].set_title('mesh, nodes, (default)')
    pg.show(mesh, pg.x(mesh), label='Nodes (x)', showMesh=True, ax=axs[2][1])
    axs[2][1].set_title('mesh, nodes, showMesh=True')
    pg.show(mesh,
            pg.x(mesh),
            label='Nodes (x)',
            showBoundary=True,
            ax=axs[2][2])
    axs[2][2].set_title('mesh, nodes, showBoundary=True')
    pg.show(mesh,
            pg.y(mesh.cellCenters()),
            label='Cell center (y)',
            tri=True,
            shading='flat',
            ax=axs[2][3])
    axs[2][3].set_title('mesh, cells, tri=True, shading=flat')
    pg.show(mesh,
            pg.y(mesh.cellCenters()),
            label='Cell center (y)',
            tri=True,
            shading='gouraud',
            ax=axs[2][4])
    axs[2][4].set_title('mesh, cells, tri=True, shading=gouraud')
    ##pg.show(mesh, mesh.cellMarker(), label(markers), axs[1][1])
    axs[2][4].figure.tight_layout()
    fig.tight_layout()
Example #38
0
def testCoverage():
    grid = pg.createGrid(10, 10)
    cov = pg.y(grid.cellCenters()).array()
    cov[-9:] = 0  # remove first row
    data = pg.Vector(grid.cellCount(), 1.0)
    pg.show(grid, data, coverage=cov)
Example #39
0
def createTriangles(mesh, data=None):
    """Generate triangle objects for later drawing.

    Parameters
    ----------
    mesh : :gimliapi:`GIMLI::Mesh`
        pyGimli mesh to plot
    data : iterable [None]
        cell-based values to plot

    Returns
    -------
    x : numpy array
        x position of nodes
    y : numpy array
        x position of nodes
    triangles : numpy array Cx3
        cell indices for each triangle
    z : numpy array
        data for given indices
    dataIdx : list of int
        list of indices into array to plot
    """
    x = pg.x(mesh.positions())
    #    x.round(1e-1)
    y = pg.y(mesh.positions())
    #    y.round(1e-1)

    triCount = 0

    for c in mesh.cells():
        if c.shape().nodeCount() == 4:
            triCount = triCount + 2
        else:
            triCount = triCount + 1

    triangles = np.zeros((triCount, 3))
    dataIdx = list(range(triCount))

    triCount = 0
    for c in mesh.cells():
        if c.shape().nodeCount() == 4:
            triangles[triCount, 0] = c.node(0).id()
            triangles[triCount, 1] = c.node(1).id()
            triangles[triCount, 2] = c.node(2).id()
            dataIdx[triCount] = c.id()
            triCount = triCount + 1

            triangles[triCount, 0] = c.node(0).id()
            triangles[triCount, 1] = c.node(2).id()
            triangles[triCount, 2] = c.node(3).id()
            dataIdx[triCount] = c.id()
            triCount = triCount + 1
        else:
            triangles[triCount, 0] = c.node(0).id()
            triangles[triCount, 1] = c.node(1).id()
            triangles[triCount, 2] = c.node(2).id()
            dataIdx[triCount] = c.id()
            triCount = triCount + 1

    z = None
    if data is not None:
        if len(data) == mesh.cellCount():
            # strange behavior if we just use these slice
            z = np.array(data[dataIdx])
        else:
            z = np.array(data)

    return x, y, triangles, z, dataIdx
Example #40
0
axs[1][3].set_title('mesh, cells, showMesh=True')
pg.show(mesh,
        mesh.cellMarkers(),
        label='Cell markers',
        showBoundary=False,
        ax=axs[1][4])
axs[1][4].set_title('mesh, cells, showBoundary=False')

pg.show(mesh, pg.x(mesh), label='Nodes (x)', ax=axs[2][0])
axs[2][0].set_title('mesh, nodes, (default)')
pg.show(mesh, pg.x(mesh), label='Nodes (x)', showMesh=True, ax=axs[2][1])
axs[2][1].set_title('mesh, nodes, showMesh=True')
pg.show(mesh, pg.x(mesh), label='Nodes (x)', showBoundary=True, ax=axs[2][2])
axs[2][2].set_title('mesh, nodes, showBoundary=True')
pg.show(mesh,
        pg.y(mesh.cellCenters()),
        label='Cell center (y)',
        tri=True,
        shading='flat',
        ax=axs[2][3])
axs[2][3].set_title('mesh, cells, tri=True, shading=flat')
pg.show(mesh,
        pg.y(mesh.cellCenters()),
        label='Cell center (y)',
        tri=True,
        shading='gouraud',
        ax=axs[2][4])
axs[2][4].set_title('mesh, cells, tri=True, shading=gouraud')
##pg.show(mesh, mesh.cellMarker(), label(markers), axs[1][1])

pg.wait()
Example #41
0
def covarianceMatrixPos(pos, **kwargs):
    """Position (R3Vector) based covariance matrix"""
    return covarianceMatrixVec(np.array(pg.x(pos)), np.array(pg.y(pos)),
                               np.array(pg.z(pos)), **kwargs)
Example #42
0
def test2d():
    mesh = pg.Mesh("mesh/world2d.bms")
    print (mesh)

    xMin = mesh.boundingBox().min()[0]
    yMax = mesh.boundingBox().max()[0]
    x = np.arange(xMin, yMax, 1.0)

    mesh.createNeighbourInfos()
    rho = pg.RVector(len(mesh.cellAttributes()), 1.0) * 2000.0
    rho.setVal(0.0, pg.find(mesh.cellAttributes() == 1.0))

    swatch = pg.Stopwatch(True)
    pnts = []
    spnts = pg.stdVectorRVector3()

    for i in x:
        pnts.append(pg.RVector3(i, 0.0001))
        spnts.append(pg.RVector3(i, 0.0001))

    #    gzC, GC = calcGCells(pnts, mesh, rho, 1)
    gzC = pg.calcGCells(spnts, mesh, rho, 1)
    print ("calcGCells", swatch.duration(True))
    #    gzB, GB = calcGBounds(pnts, mesh, rho)
    #    gzB = pg.calcGBounds(spnts, mesh, rho)
    #    print("calcGBounds", swatch.duration(True))

    gZ_Mesh = gzC

    ax1, ax2 = getaxes()

    # sphere analytical solution
    gAna = analyticalCircle2D(spnts, radius=2.0, pos=pg.RVector3(0.0, -5.0), dDensity=2000)
    gAna2 = analyticalCircle2D(spnts, radius=2.0, pos=pg.RVector3(5.0, -5.0), dDensity=2000)

    gAna = gAna + gAna2

    ax1.plot(x, gAna, "-x", label="analytical")
    ax1.plot(x, gZ_Mesh, label="WonBevis1987-mesh")

    print (gAna / gZ_Mesh)

    #    rho=GB[0]/mesh.cellSizes()

    drawModel(ax2, mesh, rho)
    for i in (0, 1):
        drawSelectedMeshBoundaries(ax2, mesh.findBoundaryByMarker(i), color=(1.0, 1.0, 1.0, 1.0), linewidth=0.3)

    # sphere polygone
    radius = 2.0
    depth = 5.0
    poly1 = pg.stdVectorRVector3()
    poly2 = pg.stdVectorRVector3()
    nSegment = 124
    for i in range(nSegment):
        xp = np.sin((i + 1) * (2.0 * np.pi) / nSegment)
        yp = np.cos((i + 1) * (2.0 * np.pi) / nSegment)
        poly1.append(pg.RVector3(xp * radius, yp * radius - depth))
        poly2.append(pg.RVector3(xp * radius + 5.0, yp * radius - depth))

    gZ_Poly = calcPolydgdz(spnts, poly1, 2000)
    gZ_Poly += calcPolydgdz(spnts, poly2, 2000)

    ax1.plot(x, gZ_Poly, label="WonBevis1987-Poly")
    ax2.plot(pg.x(poly1), pg.y(poly1), color="red")
    ax2.plot(pg.x(poly2), pg.y(poly2), color="red")

    ax2.plot(pg.x(spnts), pg.y(spnts), marker="x", color="black")

    # test some special case
    for i, p in enumerate(poly1):
        poly1[i] = pg.RVector3(poly1[i] - pg.RVector3(5.0, -6.0))

    ax2.plot(pg.x(poly1), pg.y(poly1), color="green")

    gz = calcPolydgdz(spnts, poly1, 2000)
    ax1.plot(x, gz, label="Special Case", color="green")
    ax1.set_ylabel("dg/dz [mGal]")
    ax2.set_ylabel("Tiefe [m]")

    ax1.legend()
    ax2.set_xlim([x[0], x[-1]])
    ax2.grid()
Example #43
0
def drawStreams(ax, mesh, data, startStream=3, **kwargs):
    """Draw streamlines based on an unstructured mesh.

    Every cell contains only one streamline and every new stream line
    starts in the center of a cell. You can alternatively provide a second mesh
    with coarser mesh to draw streams for.

    Parameters
    ----------

    ax : matplotlib.ax
        ax to draw into

    mesh : :gimliapi:`GIMLI::Mesh`
        2d Mesh to draw the streamline

    data : iterable float | [float, float] | pg.R3Vector
        If data is an array (per cell or node) gradients are calculated
        otherwise the data will be interpreted as vector field.

    startStream : int
        variate the start stream drawing, try values from 1 to 3 what every
        you like more.

    **kwargs: forward to drawStreamLine_

        * coarseMesh

            Instead of draw a stream for every cell in mesh, draw a streamline
            segment for each cell in coarseMesh.

        * quiver: bool

            Draw arrows instead of streamlines.

    Examples
    --------
    >>> import numpy as np
    >>> import matplotlib.pyplot as plt
    >>> import pygimli as pg
    >>> from pygimli.mplviewer import drawStreams
    >>> n = np.linspace(0, 1, 10)
    >>> mesh = pg.createGrid(x=n, y=n)
    >>> nx = pg.x(mesh.positions())
    >>> ny = pg.y(mesh.positions())
    >>> data = np.cos(1.5 * nx) * np.sin(1.5 * ny)
    >>> fig, ax = plt.subplots()
    >>> drawStreams(ax, mesh, data, color='red')
    >>> drawStreams(ax, mesh, data, dropTol=0.9)
    >>> drawStreams(ax, mesh, pg.solver.grad(mesh, data),
    ...             color='green', quiver=True)
    >>> ax.set_aspect('equal')
    >>> pg.wait()
    """
    viewMesh = None
    dataMesh = None

    quiver = kwargs.pop('quiver', False)

    if quiver:

        x = None
        y = None
        u = None
        v = None

        if len(data) == mesh.nodeCount():
            x = pg.x(mesh.positions())
            y = pg.y(mesh.positions())
        elif len(data) == mesh.cellCount():
            x = pg.x(mesh.cellCenters())
            y = pg.y(mesh.cellCenters())
        elif len(data) == mesh.boundaryCount():
            x = pg.x(mesh.boundaryCenters())
            y = pg.y(mesh.boundaryCenters())

        if isinstance(data, pg.R3Vector):
            u = pg.x(data)
            v = pg.y(data)
        else:
            u = data[:, 0]
            v = data[:, 1]

        ax.quiver(x, y, u, v, **kwargs)

        updateAxes_(ax)
        return

    if 'coarseMesh' in kwargs:
        viewMesh = kwargs['coarseMesh']
        dataMesh = mesh
        dataMesh.createNeighbourInfos()
        del kwargs['coarseMesh']
    else:
        viewMesh = mesh

    viewMesh.createNeighbourInfos()

    for c in viewMesh.cells():
        c.setValid(True)

    if startStream == 1:
        # start a stream from each boundary cell
        for y in np.linspace(viewMesh.ymin(), viewMesh.ymax(), 100):
            c = viewMesh.findCell(
                [(viewMesh.xmax() - viewMesh.xmax()) / 2.0, y])
            if c is not None:
                if c.valid():
                    drawStreamLine_(ax, viewMesh, c, data, dataMesh, **kwargs)

    elif startStream == 2:
        # start a stream from each boundary cell
        for x in np.linspace(viewMesh.xmin(), viewMesh.xmax(), 100):
            c = viewMesh.findCell(
                [x, (viewMesh.ymax() - viewMesh.ymax()) / 2.0])
            if c is not None:
                if c.valid():
                    drawStreamLine_(ax, viewMesh, c, data, dataMesh, **kwargs)

    elif startStream == 3:
        # start a stream from each boundary cell
        for b in viewMesh.findBoundaryByMarker(1, 99):
            c = b.leftCell()
            if c is None:
                c = b.rightCell()

            if c.valid():
                drawStreamLine_(ax, viewMesh, c, data, dataMesh, **kwargs)

    # start a stream from each unused cell
    for c in viewMesh.cells():
        if c.valid():
            drawStreamLine_(ax, viewMesh, c, data, dataMesh, **kwargs)

    for c in viewMesh.cells():
        c.setValid(True)

    updateAxes_(ax)
Example #44
0
def show(obj=None, data=None, **kwargs):
    """Mesh and model visualization.

    Syntactic sugar to show a obj with data. Forwards to
    a known visualization for obj. Typical is
    :py:mod:`pygimli.viewer.showMesh` or
    :py:mod:`pygimli.viewer.mayaview.showMesh3D` to show most of the typical 2D
    and 3D content.
    See tutorials and examples for usage hints. An empty show
    call creates an empty ax window.

    Parameters
    ----------
    obj: obj
        obj can be so far.
        * :gimliapi:`GIMLI::Mesh` or list of meshes
        * DataContainer
        * pg.core.Sparse[Map]Matrix

    data: iterable
        Optionally data to visualize. See appropriate show function.

    Keyword Arguments
    -----------------
    **kwargs
        Additional kwargs forward to appropriate show functions.

        * ax : axe [None]
            Matplotlib axes object. Create a new if necessary.
        * fitView : bool [True]
            Scale x and y limits to match the view.

    Returns
    -------
    Return the results from the showMesh* functions. Usually the axe object
    and a colorbar.

    See Also
    --------
    showMesh
    """
    if "axes" in kwargs:  # remove me in 1.2 #20200515
        print("Deprecation Warning: Please use keyword `ax` instead of `axes`")
        kwargs['ax'] = kwargs.pop('axes', None)

    ### Empty call just to create a axes
    if obj is None and not 'mesh' in kwargs.keys():
        ax = kwargs.pop('ax', None)

        if ax is None:
            ax = plt.subplots(figsize=kwargs.pop('figsize', None))[1]
        return ax, None

    ### try to interprete obj containes a mesh
    if hasattr(obj, 'mesh'):
        return pg.show(obj.mesh, obj, **kwargs)

    ### try to interprete obj as ERT Data
    if isinstance(obj, pg.DataContainerERT):
        from pygimli.physics.ert import showERTData
        return showERTData(obj, vals=kwargs.pop('vals', data), **kwargs)

    ### try to interprete obj as matrices
    if isinstance(obj, pg.core.MatrixBase) or \
        (isinstance(obj, np.ndarray) and obj.ndim == 2):
        return showMatrix(obj, **kwargs)

    try:
        from scipy.sparse import spmatrix
        if isinstance(obj, spmatrix):
            return showMatrix(obj, **kwargs)
    except ImportError:
        pass

    ### try to interprete obj as mesh or list of meshes
    mesh = kwargs.pop('mesh', obj)

    fitView = kwargs.get('fitView', True)

    if isinstance(mesh, list):
        ax = kwargs.pop('ax', None)

        ax, cBar = show(mesh[0],
                        data,
                        hold=1,
                        ax=ax,
                        fitView=fitView,
                        **kwargs)

        for m in mesh[1:]:
            ax, cBar = show(m, data, ax=ax, hold=1, fitView=False, **kwargs)

        if fitView is not False:
            ax.autoscale(enable=True, axis='both', tight=True)
            ax.set_aspect('equal')
        return ax, cBar

    if isinstance(mesh, pg.Mesh):
        if mesh.dim() == 2:
            if pg.zero(pg.y(mesh)):
                pg.info("swap z<->y coordinates for visualization.")
                meshSwap = pg.Mesh(mesh)
                for n in meshSwap.nodes():
                    n.pos()[1] = n.pos()[2]
                return showMesh(meshSwap, data, **kwargs)

            return showMesh(mesh, data, **kwargs)
        elif mesh.dim() == 3:

            from .vistaview import showMesh3D
            return showMesh3D(mesh, data, **kwargs)
        else:
            pg.error("ERROR: Mesh not valid.", mesh)

    pg.error("Can't interprete obj: {0} to show.".format(obj))
    return None, None
Example #45
0
def interpolateAlongCurve(curve, t, **kwargs):
    """Interpolate along curve.

    Return curve coordinates for a piecewise linear curve :math:`C(t) = {x_i,y_i,z_i}`
    at positions :math:`t`.
    Curve and :math:`t` values are expected to be sorted along distance from the
    origin of the curve.

    Parameters
    ----------
    curve : [[x,z]] | [[x,y,z]] | [:gimliapi:`GIMLI::RVector3`] | :gimliapi:`GIMLI::R3Vector`
        Discrete curve for 2D :math:`x,z` curve=[[x,z]], 3D :math:`x,y,z`

    t : 1D iterable
        Query positions along the curve in absolute distance

    kwargs :
        If kwargs are given an additional curve smoothing is applied using
        :py:mod:`pygimli.meshtools.interpolate`. The kwargs will be delegated.

    Returns
    -------

    p : np.array
        Curve positions at query points :math:`t`.
        Dimension of p match the size of curve the coordinates.

    Examples
    --------
    >>> # no need to import matplotlib. pygimli's show does
    >>> import numpy as np
    >>> import pygimli as pg
    >>> import pygimli.meshtools as mt
    >>> fig, axs = pg.plt.subplots(2,2)
    >>> topo = np.array([[-2., 0.], [-1., 0.], [0.5, 0.], [3., 2.], [4., 2.], [6., 1.], [10., 1.], [12., 1.]])
    >>> t = np.arange(15.0)
    >>> p = mt.interpolateAlongCurve(topo, t)
    >>> _= axs[0,0].plot(topo[:,0], topo[:,1], '-x', mew=2)
    >>> _= axs[0,1].plot(p[:,0], p[:,1], 'o', color='red') #doctest: +ELLIPSIS
    >>>
    >>> p = mt.interpolateAlongCurve(topo, t, method='spline')
    >>> _= axs[1,0].plot(p[:,0], p[:,1], '-o', color='black') #doctest: +ELLIPSIS
    >>>
    >>> p = mt.interpolateAlongCurve(topo, t, method='harmonic', nc=3)
    >>> _= axs[1,1].plot(p[:,0], p[:,1], '-o', color='green') #doctest: +ELLIPSIS
    >>>
    >>> pg.plt.show()
    >>> pg.wait()
    """
    xC = np.zeros(len(curve))
    yC = np.zeros(len(curve))
    zC = np.zeros(len(curve))

    tCurve = kwargs.pop('tCurve', None)
    if tCurve is None:
        tCurve = pg.utils.cumDist(curve)
    dim = 3

    ## extrapolate starting overlaps
    if min(t) < min(tCurve):
        d = pg.RVector3(curve[1]) - pg.RVector3(curve[0])
        #d[2] = 0.0
        d.normalise()
        curve = np.insert(curve, [0], [
            curve[0] - np.array(d * (min(tCurve) - min(t)))[0:curve.shape[1]]
        ],
                          axis=0)
        tCurve = np.insert(tCurve, 0, min(t), axis=0)

    ## extrapolate ending overlaps
    if max(t) > max(tCurve):
        d = pg.RVector3(curve[-2]) - pg.RVector3(curve[-1])
        #d[2] = 0.0
        d.normalise()
        curve = np.append(curve, [
            curve[-1] - np.array(d * (max(t) - max(tCurve)))[0:curve.shape[1]]
        ],
                          axis=0)
        tCurve = np.append(tCurve, max(t))

    if isinstance(curve, pg.R3Vector) or isinstance(curve,
                                                    pg.stdVectorRVector3):
        xC = pg.x(curve)
        yC = pg.y(curve)
        zC = pg.z(curve)
    else:
        if curve.shape[1] == 2:
            xC = curve[:, 0]
            zC = curve[:, 1]
            dim = 2
        else:
            xC = curve[:, 0]
            yC = curve[:, 1]
            zC = curve[:, 2]

    if len(kwargs.keys()) > 0:
        #interpolate more curve points to get a smooth line
        dTi = min(pg.utils.dist(pg.utils.diff(curve))) / 10.
        ti = np.arange(min(tCurve), max(tCurve) + dTi, dTi)
        xC = pg.interpolate(ti, tCurve, xC, **kwargs)
        zC = pg.interpolate(ti, tCurve, zC, **kwargs)

        if dim == 3:
            yC = pg.interpolate(ti, tCurve, yC, **kwargs)
        tCurve = ti

    xt = interpolate(t, tCurve, xC)
    zt = interpolate(t, tCurve, zC)

    if dim == 2:
        return np.vstack([xt, zt]).T

    yt = interpolate(t, tCurve, yC)

    return np.vstack([xt, yt, zt]).T
#ax, _ = pg.show(mesh, data=K, label='Hydraulic conductivity $K$ in m$/$s',
#cMin=1e-5, cMax=1e-2, nLevs=4, cmap='viridis')
#ax, _ = pg.show(mesh, data=pg.abs(vel), logScale=0, label='Velocity $v$ in m$/$s')
#ax, _ = pg.show(mesh, data=vel, ax=ax, color='black', linewidth=0.5, dropTol=1e-6)

print('Solve Advection-diffusion equation ...')
S = pg.RVector(mesh.cellCount(), 0.0)
# Fill injection source vector for a fixed injection position
sourceCell = mesh.findCell([-19.1, -4.6])
S[sourceCell.id()] = 1.0 / sourceCell.size()  #g/(l s)
# Choose 800 time steps for 6 days in seconds
t = pg.utils.grange(0, 6 * 24 * 3600, n=800)
# Create dispersitivity, depending on the absolute velocity
dispersion = pg.abs(vel) * 1e-2
# Solve for injection time, but we need velocities on cell nodes
vel = mt.cellDataToNodeData(mesh, np.asarray([pg.x(vel), pg.y(vel)]).T).T
c1 = pg.solver.solveFiniteVolume(mesh,
                                 a=dispersion,
                                 f=S,
                                 vel=vel,
                                 times=t,
                                 uB=[1, 0],
                                 scheme='PS',
                                 verbose=0)
# Solve without injection starting with last result
c2 = pg.solver.solveFiniteVolume(mesh,
                                 a=dispersion,
                                 f=0,
                                 vel=vel,
                                 u0=c1[-1],
                                 times=t,
Example #47
0
def drawStreams(ax, mesh, data, startStream=3, **kwargs):
    """Draw streamlines based on an unstructured mesh.

    Every cell contains only one streamline and every new stream line
    starts in the center of a cell. You can alternatively provide a second mesh
    with coarser mesh to draw streams for.

    Parameters
    ----------

    ax : matplotlib.ax
        ax to draw into

    mesh : :gimliapi:`GIMLI::Mesh`
        2d Mesh to draw the streamline

    data : iterable float | [float, float] | pg.R3Vector
        If data is an array (per cell or node) gradients are calculated
        otherwise the data will be interpreted as vector field.

    startStream : int
        variate the start stream drawing, try values from 1 to 3 what every
        you like more.

    **kwargs: forward to drawStreamLine_

        * coarseMesh

            Instead of draw a stream for every cell in mesh, draw a streamline
            segment for each cell in coarseMesh.

        * quiver: bool

            Draw arrows instead of streamlines.

    Examples
    --------
    >>> import numpy as np
    >>> import matplotlib.pyplot as plt
    >>> import pygimli as pg
    >>> from pygimli.mplviewer import drawStreams
    >>> n = np.linspace(0, 1, 10)
    >>> mesh = pg.createGrid(x=n, y=n)
    >>> nx = pg.x(mesh.positions())
    >>> ny = pg.y(mesh.positions())
    >>> data = np.cos(1.5 * nx) * np.sin(1.5 * ny)
    >>> fig, ax = plt.subplots()
    >>> drawStreams(ax, mesh, data, color='red')
    >>> drawStreams(ax, mesh, data, dropTol=0.9)
    >>> drawStreams(ax, mesh, pg.solver.grad(mesh, data),
    ...             color='green', quiver=True)
    >>> ax.set_aspect('equal')
    >>> pg.wait()
    """
    viewMesh = None
    dataMesh = None

    quiver = kwargs.pop('quiver', False)

    if quiver:

        x = None
        y = None
        u = None
        v = None

        if len(data) == mesh.nodeCount():
            x = pg.x(mesh.positions())
            y = pg.y(mesh.positions())
        elif len(data) == mesh.cellCount():
            x = pg.x(mesh.cellCenters())
            y = pg.y(mesh.cellCenters())
        elif len(data) == mesh.boundaryCount():
            x = pg.x(mesh.boundaryCenters())
            y = pg.y(mesh.boundaryCenters())

        if isinstance(data, pg.R3Vector):
            u = pg.x(data)
            v = pg.y(data)
        else:
            u = data[:, 0]
            v = data[:, 1]

        ax.quiver(x, y, u, v, **kwargs)

        updateAxes_(ax)
        return

    if 'coarseMesh' in kwargs:
        viewMesh = kwargs['coarseMesh']
        dataMesh = mesh
        dataMesh.createNeighbourInfos()
        del kwargs['coarseMesh']
    else:
        viewMesh = mesh

    viewMesh.createNeighbourInfos()

    for c in viewMesh.cells():
        c.setValid(True)

    if startStream == 1:
        # start a stream from each boundary cell
        for y in np.linspace(viewMesh.ymin(), viewMesh.ymax(), 100):
            c = viewMesh.findCell(
                [(viewMesh.xmax() - viewMesh.xmax()) / 2.0, y])
            if c is not None:
                if c.valid():
                    drawStreamLine_(ax, viewMesh, c, data, dataMesh, **kwargs)

    elif startStream == 2:
        # start a stream from each boundary cell
        for x in np.linspace(viewMesh.xmin(), viewMesh.xmax(), 100):
            c = viewMesh.findCell(
                [x, (viewMesh.ymax() - viewMesh.ymax()) / 2.0])
            if c is not None:
                if c.valid():
                    drawStreamLine_(ax, viewMesh, c, data, dataMesh, **kwargs)

    elif startStream == 3:
        # start a stream from each boundary cell
        for b in viewMesh.findBoundaryByMarker(1, 99):
            c = b.leftCell()
            if c is None:
                c = b.rightCell()

            if c.valid():
                drawStreamLine_(ax, viewMesh, c, data, dataMesh, **kwargs)

    # start a stream from each unused cell
    for c in viewMesh.cells():
        if c.valid():
            drawStreamLine_(ax, viewMesh, c, data, dataMesh, **kwargs)

    for c in viewMesh.cells():
        c.setValid(True)

    updateAxes_(ax)
drawField(ax, mesh, times, cmap='Spectral', fillContour=True)
drawStreamLines(ax, mesh, -times, nx=50, ny=50)

###############################################################################
# We compare the result with the analytical solution along the x axis
x = np.arange(0., 140., 0.5)
tFMM = pg.interpolate(mesh, times, x, x * 0., x * 0.)
tAna = analyticalSolution2Layer(x)
print("min(dt)={} ms  max(dt)={} ms".format(
    min(tFMM - tAna) * 1000,
    max(tFMM - tAna) * 1000))

###############################################################################
# In order to use the Dijkstra, we extract the surface positions >0
mx = pg.x(mesh.positions())
my = pg.y(mesh.positions())
fi = pg.find((my == 0.0) & (mx >= 0))
px = np.sort(mx(fi))

###############################################################################
# A data container with index arrays named s (shot) and g (geophones) is
# created and filled with the positions and shot/geophone indices.
data = pg.DataContainer()
data.registerSensorIndex('s')
data.registerSensorIndex('g')
for pxi in px:
    data.createSensor(pg.RVector3(pxi, 0.0))

ndata = len(px) - 1
data.resize(ndata)
data.set('s', pg.RVector(ndata, 0))  # only one shot at first sensor
Example #49
0
    pg.show(mesh, axes=a, data=l[0])

    cells = fwd.mesh().cells()
    active_cells = [cells[i] for i in range(mesh.cellCount()) if l[0][i]]
    #    active_cells.append(cells[2044])
    for c in active_cells:
        pos = c.center()
        gradient = 2000 * c.grad(pos, fwd.timefields[0])
        dx, dy = gradient.x(), gradient.y()
        a.text(pos.x(), pos.y(), str(c.id()))
        a.arrow(pos.x(), pos.y(), dx, dy)

    ray = fwd.poslist
    a.plot(
        pg.x(ray),
        pg.y(ray),
        'm-*',
    )
    plt.show()

    # look at if next gradient contradicts the previous
    # if so, then follow the interface instead (line segment to next node)
    # this will stop when the gradients are more aligned.

    #    drawMesh(a, mesh)
    #    drawField(a, mesh, fwd.timefields[0], True, 'Spectral')
    #    drawStreamLines(a, mesh, fwd.timefields[0], nx=50, ny=50)

    # some stats:
    delta_t = np.array(data("t")) - t_fmm
    diff_rms = np.sqrt(np.sum(delta_t**2) / len(delta_t))
Example #50
0
def covarianceMatrixPos(pos, **kwargs):
    """Position (R3Vector) based covariance matrix"""
    return covarianceMatrixVec(np.array(pg.x(pos)), np.array(pg.y(pos)),
                               np.array(pg.z(pos)), **kwargs)
Example #51
0
def show(mesh=None, data=None, **kwargs):
    """Mesh and model visualization.

    Syntactic sugar to show a mesh with data. Forwards to
    :py:mod:`pygimli.viewer.showMesh` or
    :py:mod:`pygimli.viewer.mayaview.showMesh3D` to show most of the typical 2D
    and 3D content. See tutorials and examples for usage hints. An empty show
    call create an empty ax window.

    Parameters
    ----------
    mesh : :gimliapi:`GIMLI::Mesh` or list of meshes
        2D or 3D GIMLi mesh

    **kwargs :
        * fitView : bool [True]
            Scale x and y limits to match the view.

        * ax : axe [None]
            Matplotlib axes object. Create a new if necessary.

        * Will be forwarded to the appropriate show functions.

    Returns
    -------
    Return the results from the showMesh* functions.

    See Also
    --------
    showMesh
    """
    if "axes" in kwargs:
        print("Deprecation Warning: Please use keyword `ax` instead of `axes`")
        kwargs['ax'] = kwargs.pop('axes', None)

    if isinstance(mesh, list):
        ax = kwargs.pop('ax', None)
        fitView = kwargs.pop('fitView', True)

        ax, cbar = show(mesh[0],
                        data,
                        hold=1,
                        ax=ax,
                        fitView=fitView,
                        **kwargs)
        xmin = mesh[0].xmin()
        xmax = mesh[0].xmax()
        ymin = mesh[0].ymin()
        ymax = mesh[0].ymax()

        for m in mesh[1:]:
            ax, cbar = show(m, data, ax=ax, hold=1, fitView=False, **kwargs)
            xmin = min(xmin, m.xmin())
            xmax = max(xmax, m.xmax())
            ymin = min(ymin, m.ymin())
            ymax = max(ymax, m.ymax())


#        ax.relim()
#        ax.autoscale_view(tight=True)
        if fitView is not False:
            ax.set_xlim([xmin, xmax])
            ax.set_ylim([ymin, ymax])
        #        print(ax.get_data_interval())
        return ax, cbar

    if isinstance(mesh, pg.Mesh):
        if mesh.dim() == 2:
            if pg.zero(pg.y(mesh)):
                pg.info("swap z<->y coordinates for visualization.")
                meshSwap = pg.Mesh(mesh)
                for n in meshSwap.nodes():
                    n.pos()[1] = n.pos()[2]
                return showMesh(meshSwap, data, **kwargs)

            return showMesh(mesh, data, **kwargs)
        elif mesh.dim() == 3:

            from .mayaview import showMesh3D

            return showMesh3D(mesh, data, **kwargs)
        else:
            pg.error("ERROR: Mesh not valid.", mesh)

    ax = kwargs.pop('ax', None)

    if ax is None:
        ax = plt.subplots()[1]

    return ax, None
Example #52
0
def maillage_SWMS2D(geometry):
    """Définition du maillage triangulaire pour SWMS_2D"""

    xmin=geometry.xmin
    xmax=geometry.xmax
    emin=geometry.emin
    emax=geometry.emax
    dtrou=geometry.dtrou
    etrou=geometry.etrou
    r=geometry.r
    dx=geometry.dx
    zaff=geometry.zaff
    eaff=geometry.eaff
    #waff=geometry.waff
    
    assert dtrou + zaff < emax

    xtrou_reg = np.arange(xmin, r + dx, dx, 'float')
#    xtrou_reg = np.arange(xmin, r + zaff, dx, 'float')
    etrou_reg = np.arange(etrou, emax +dx, dx, 'float')
    efin_reg = np.arange(eaff, etrou+dx, dx, 'float')
    
    #A présent on crée une zone grâce à un polygone

    poly = pg.Mesh(2)  # empty 2d mesh
    nStart = poly.createNode(0.0, 0.0, 0.0) # On crée un noeud de départ, on travaille en 2D donc le dernier terme vaut 0.0

    nA = nStart # noeud de départ

    for e in efin_reg[0:len(efin_reg)]: # On démarre de 1 et on se balade sur l'axe des x en créant un noeud à chaque fois
        nB = poly.createNode(0, e, 0.0)
        poly.createEdge(nA, nB) # On définit un côté entre le noeud précédemment créé et le nouveau
        nA = nB # On remplace le noeud de départ par le noeud nouvellement créé
    
    #Définir les noeuds au fond du trou    
    for x in xtrou_reg[1:len(xtrou_reg)]:
        nB = poly.createNode(x, etrou, 0.0)
        poly.createEdge(nA, nB) #On définit un côté entre le noeud précédemment crée et le nouveau
        nA = nB #On remplace le noeud de départ par le noeud nouvellement crée

    #Définir les noeuds le long du trou
    for f in etrou_reg[1:len(etrou_reg)]: # On démarre du haut et on se balade sur l'axe des z en créant un noeud à chaque fois
        nB = poly.createNode(r, f, 0.0)
        poly.createEdge(nA, nB) # On définit un côté entre le noeud précédemment créé et le nouveau
        nA = nB # On remplace le noeud de départ par le noeud nouvellement crée

    nC=nB
    nD = poly.createNode(xmax, emax, 0.0)
    poly.createEdge(nC, nD)
    nE = poly.createNode(xmax, emin, 0.0)
    poly.createEdge(nD, nE)
    poly.createEdge(nE, nStart) #On ferme le polygone!

    mesh=pg.meshtools.createMesh(poly, quality=geometry.quality, area=geometry.area, smooth=geometry.smooth)

    pg_pos = mesh.positions()
    mesh_pos = np.array((np.array(pg.x(pg_pos)), np.array(pg.y(pg_pos)), np.array(pg.z(pg_pos)))).T #On crée une matrice contenant la position des noeuds
    mesh_cells = np.zeros((mesh.cellCount(), 3)) #Matrice vide de la taille du nombre de cellules
    for i, cell in enumerate(mesh.cells()): #On rentre les cellules das une matrice
        mesh_cells[i] = cell.ids()
    
    return mesh, pg_pos, mesh_pos, mesh_cells
Example #53
0
def createTriangles(mesh, data=None):
    """Generate triangle objects for later drawing.

    Parameters
    ----------
    mesh : :gimliapi:`GIMLI::Mesh`
        pyGimli mesh to plot
    data : iterable [None]
        cell-based values to plot

    Returns
    -------
    x : numpy array
        x position of nodes
    y : numpy array
        x position of nodes
    triangles : numpy array Cx3
        cell indices for each triangle
    z : numpy array
        data for given indices
    dataIdx : list of int
        list of indices into array to plot
    """
    x = pg.x(mesh.positions())
    #    x.round(1e-1)
    y = pg.y(mesh.positions())
    #    y.round(1e-1)

    triCount = 0

    for c in mesh.cells():
        if c.shape().nodeCount() == 4:
            triCount = triCount + 2
        else:
            triCount = triCount + 1

    triangles = np.zeros((triCount, 3))
    dataIdx = list(range(triCount))

    triCount = 0
    for c in mesh.cells():
        if c.shape().nodeCount() == 4:
            triangles[triCount, 0] = c.node(0).id()
            triangles[triCount, 1] = c.node(1).id()
            triangles[triCount, 2] = c.node(2).id()
            dataIdx[triCount] = c.id()
            triCount = triCount + 1

            triangles[triCount, 0] = c.node(0).id()
            triangles[triCount, 1] = c.node(2).id()
            triangles[triCount, 2] = c.node(3).id()
            dataIdx[triCount] = c.id()
            triCount = triCount + 1
        else:
            triangles[triCount, 0] = c.node(0).id()
            triangles[triCount, 1] = c.node(1).id()
            triangles[triCount, 2] = c.node(2).id()
            dataIdx[triCount] = c.id()
            triCount = triCount + 1

    z = None
    if data is not None:
        if len(data) == mesh.cellCount():
            # strange behavior if we just use these slice
            z = np.array(data[dataIdx])
        else:
            z = np.array(data)

    return x, y, triangles, z, dataIdx
Example #54
0
def show(mesh=None, data=None, **kwargs):
    """Mesh and model visualization.

    Syntactic sugar to show a mesh with data. Forwards to
    :py:mod:`pygimli.viewer.showMesh` or
    :py:mod:`pygimli.viewer.mayaview.showMesh3D` to show most of the typical 2D
    and 3D content. See tutorials and examples for usage hints. An empty show
    call creates an empty ax window.

    Parameters
    ----------
    mesh : :gimliapi:`GIMLI::Mesh` or list of meshes
        2D or 3D GIMLi mesh

    **kwargs :
        * fitView : bool [True]
            Scale x and y limits to match the view.

        * ax : axe [None]
            Matplotlib axes object. Create a new if necessary.

        * Will be forwarded to the appropriate show functions.

    Returns
    -------
    Return the results from the showMesh* functions.

    See Also
    --------
    showMesh
    """
    if "axes" in kwargs:
        print("Deprecation Warning: Please use keyword `ax` instead of `axes`")
        kwargs['ax'] = kwargs.pop('axes', None)

    if isinstance(mesh, list):
        ax = kwargs.pop('ax', None)
        fitView = kwargs.pop('fitView', True)

        ax, cbar = show(mesh[0], data, hold=1, ax=ax, fitView=fitView, **kwargs)
        xmin = mesh[0].xmin()
        xmax = mesh[0].xmax()
        ymin = mesh[0].ymin()
        ymax = mesh[0].ymax()

        for m in mesh[1:]:
            ax, cbar = show(m, data, ax=ax, hold=1, fitView=False, **kwargs)
            xmin = min(xmin, m.xmin())
            xmax = max(xmax, m.xmax())
            ymin = min(ymin, m.ymin())
            ymax = max(ymax, m.ymax())

#        ax.relim()
#        ax.autoscale_view(tight=True)
        if fitView is not False:
            ax.set_xlim([xmin, xmax])
            ax.set_ylim([ymin, ymax])
        #        print(ax.get_data_interval())
        return ax, cbar

    if isinstance(mesh, pg.Mesh):
        if mesh.dim() == 2:
            if pg.zero(pg.y(mesh)):
                pg.info("swap z<->y coordinates for visualization.")
                meshSwap = pg.Mesh(mesh)
                for n in meshSwap.nodes():
                    n.pos()[1] = n.pos()[2]
                return showMesh(meshSwap, data, **kwargs)

            return showMesh(mesh, data, **kwargs)
        elif mesh.dim() == 3:

            from .mayaview import showMesh3D

            return showMesh3D(mesh, data, **kwargs)
        else:
            pg.error("ERROR: Mesh not valid.", mesh)

    ax = kwargs.pop('ax', None)

    if ax is None:
        ax = plt.subplots()[1]

    return ax, None
Example #55
0
def test2d():    
    mesh = g.Mesh( 'mesh/world2d.bms' )
    print mesh

    xMin = mesh.boundingBox( ).min()[0]
    yMax = mesh.boundingBox( ).max()[0]
    x = P.arange( xMin, yMax, 1. );

    mesh.createNeighbourInfos()
    rho = g.RVector( len( mesh.cellAttributes() ), 1. ) * 2000.0 
    rho.setVal( 0.0, g.find( mesh.cellAttributes() == 1.0 ) )

    swatch = g.Stopwatch( True )
    pnts = []
    spnts = g.stdVectorRVector3()
    
    for i in x:
        pnts.append( g.RVector3( i, 0.0001 ) )
        spnts.append( g.RVector3( i, 0.0001 ) )
    
    #gzC, GC = calcGCells( pnts, mesh, rho, 1 )
    gzC = g.calcGCells( spnts , mesh, rho, 1 )
    print "calcGCells",  swatch.duration( True )
    #gzB, GB = calcGBounds( pnts, mesh, rho )
    gzB = g.calcGBounds( spnts , mesh, rho )
    print "calcGBounds", swatch.duration( True )

    gZ_Mesh = gzC

    
    ax1, ax2 = getaxes()

    # sphere analytical solution
    gAna  = analyticalCircle2D( spnts, radius = 2.0, pos = g.RVector3( 0.0, -5.0 ), dDensity = 2000 )
    gAna2 = analyticalCircle2D( spnts, radius = 2.0, pos = g.RVector3( 5.0, -5.0 ), dDensity = 2000 )
    
    gAna = gAna + gAna2

    ax1.plot( x, gAna, '-x', label= 'Analytisch' )
    ax1.plot( x, gZ_Mesh, label= 'WonBevis1987-mesh' )

    print gAna / gZ_Mesh

    #rho=GB[0]/mesh.cellSizes()

    gci = drawModel( ax2, mesh, rho )

    drawSelectedMeshBoundaries( ax2, mesh.findBoundaryByMarker( 0 )
                                , color = ( 1.0, 1.0, 1.0, 1.0 )
                                , linewidth = 0.3 )
    drawSelectedMeshBoundaries( ax2, mesh.findBoundaryByMarker( 1 )
                                , color = ( 1.0, 1.0, 1.0, 1.0 )
                                , linewidth = 0.3 )
       
    # sphere polygone
    radius = 2.
    depth = 5.
    poly1 = g.stdVectorRVector3()
    poly2 = g.stdVectorRVector3()
    nSegment=124
    for i in range( nSegment ):
        xp = np.sin( (i+1) * ( 2. * np.pi ) / nSegment )
        yp = np.cos( (i+1) * ( 2. * np.pi ) / nSegment )
        poly1.append( g.RVector3( xp * radius, yp * radius - depth ) )
        poly2.append( g.RVector3( xp * radius + 5., yp * radius - depth ) )

    gZ_Poly  = calcPolydgdz( spnts, poly1, 2000 )
    gZ_Poly += calcPolydgdz( spnts, poly2, 2000 )

    ax1.plot( x, gZ_Poly, label= 'WonBevis1987-Poly' )
    ax2.plot( g.x( poly1 ), g.y( poly1 ), color = 'red' )
    ax2.plot( g.x( poly2 ), g.y( poly2 ), color = 'red' )

    ax2.plot( g.x( spnts ), g.y( spnts ), marker = 'x', color = 'black' )

    # test some special case
    for i, p in enumerate( poly1 ):
        poly1[i] = g.RVector3( poly1[i] - g.RVector3( 5.0, -6. ) )
    
    ax2.plot( g.x( poly1 ), g.y( poly1 ), color = 'green' )

    gz  = calcPolydgdz( spnts, poly1, 2000 )
    ax1.plot( x, gz, label= 'Special Case', color = 'green' )
    ax1.set_ylabel( 'dg/dz [mGal]' )
    ax2.set_ylabel( 'Tiefe [m]' )

    ax1.legend()
    ax2.set_xlim( [ x[0], x[-1] ] )
    ax2.grid()
Example #56
0
def show(obj=None, data=None, **kwargs):
    """Mesh and model visualization.

    Syntactic sugar to show a obj with data. Forwards to
    a known visualization for obj. Typical is
    :py:mod:`pygimli.viewer.showMesh` or
    :py:mod:`pygimli.viewer.mayaview.showMesh3D` to show most of the typical 2D
    and 3D content.
    See tutorials and examples for usage hints. An empty show
    call creates an empty ax window.

    Parameters
    ----------
    obj: obj
        obj can be so far.
        * :gimliapi:`GIMLI::Mesh` or list of meshes
        * DataContainer
        * pg.core.Sparse[Map]Matrix

    data: iterable
        Optionally data to visualize. See appropriate show function.

    Keyword Arguments
    -----------------
    **kwargs
        Additional kwargs forward to appropriate show functions.

        * ax : axe [None]
            Matplotlib axes object. Create a new if necessary.
        * fitView : bool [True]
            Scale x and y limits to match the view.

    Returns
    -------
    Return the results from the showMesh* functions. Usually the axe object
    and a colorbar.

    See Also
    --------
    showMesh
    """
    if "axes" in kwargs:
        print("Deprecation Warning: Please use keyword `ax` instead of `axes`")
        kwargs['ax'] = kwargs.pop('axes', None)

    if isinstance(obj, pg.DataContainerERT):
        from pygimli.physics.ert import showERTData
        return showERTData(obj, vals=kwargs.pop('vals', data), **kwargs)

    if isinstance(obj, pg.core.MatrixBase):
        ax, _ = pg.show()
        return drawMatrix(ax, obj, **kwargs)

    mesh = kwargs.pop('mesh', obj)

    if isinstance(mesh, list):
        ax = kwargs.pop('ax', None)
        fitView = kwargs.pop('fitView', ax is None)

        ax, cBar = show(mesh[0],
                        data,
                        hold=1,
                        ax=ax,
                        fitView=fitView,
                        **kwargs)
        xMin = mesh[0].xMin()
        xMax = mesh[0].xMax()
        yMin = mesh[0].yMin()
        yMax = mesh[0].yMax()

        for m in mesh[1:]:
            ax, cBar = show(m, data, ax=ax, hold=1, fitView=False, **kwargs)
            xMin = min(xMin, m.xMin())
            xMax = max(xMax, m.xMax())
            yMin = min(yMin, m.yMin())
            yMax = max(yMax, m.yMax())


#        ax.relim()
#        ax.autoscale_view(tight=True)
        if fitView is not False:
            ax.set_xlim([xMin, xMax])
            ax.set_ylim([yMin, yMax])
        #        print(ax.get_data_interval())
        return ax, cBar

    if isinstance(mesh, pg.Mesh):
        if mesh.dim() == 2:
            if pg.zero(pg.y(mesh)):
                pg.info("swap z<->y coordinates for visualization.")
                meshSwap = pg.Mesh(mesh)
                for n in meshSwap.nodes():
                    n.pos()[1] = n.pos()[2]
                return showMesh(meshSwap, data, **kwargs)

            return showMesh(mesh, data, **kwargs)
        elif mesh.dim() == 3:

            from .vistaview import showMesh3D
            return showMesh3D(mesh, data, **kwargs)
        else:
            pg.error("ERROR: Mesh not valid.", mesh)

    ax = kwargs.pop('ax', None)

    if ax is None:
        ax = plt.subplots()[1]

    return ax, None
Example #57
0
def interpolate(*args, **kwargs):
    r"""Interpolation convinience function.

    Convenience function to interpolate different kind of data.
    Currently supported interpolation schemes are:

    * Interpolate mesh based data from one mesh to another
     (syntactic sugar for the core based interpolate (see below))

      Parameters:
        args: :gimliapi:`GIMLI::Mesh`, :gimliapi:`GIMLI::Mesh`, iterable
            `outData = interpolate(outMesh, inMesh, vals)`
            Interpolate values based on inMesh to outMesh.
            Values can be of length inMesh.cellCount() interpolated to
            outMesh.cellCenters() or inMesh.nodeCount() which are interpolated tp
            outMesh.positions().

      Returns:
        Interpolated values.

    * Mesh based values to arbitrary points, based on finite element
      interpolation (from gimli core).

      Parameters:
        args: :gimliapi:`GIMLI::Mesh`, ...
            Arguments forwarded to :gimliapi:`GIMLI::interpolate`
        kwargs:
            Arguments forwarded to :gimliapi:`GIMLI::interpolate`

        `interpolate(srcMesh, destMesh)`
            All data from inMesh are interpolated to outMesh

      Returns:
        Interpolated values

    * Interpolate along curve.
      Forwarded to :py:mod:`pygimli.meshtools.interpolateAlongCurve`

      Parameters:
        args: curve, t

        kwargs:
            Arguments forwarded to
            :py:mod:`pygimli.meshtools.interpolateAlongCurve`

    * 1D point set :math:`u(x)` for ascending :math:`x`.
      Find interpolation function :math:`I = u(x)` and
      returns :math:`u_{\text{i}} = I(x_{\text{i}})`
      (interpolation methods are [**linear** via matplotlib,
      cubic **spline** via scipy, fit with **harmonic** functions' via pygimli])
      Note, for 'linear' and 'spline' the interpolate contains all original
      coordinates while 'harmonic' returns an approximate best fit.
      The amount of harmonic coefficients can be specfied with the 'nc' keyword.

      Parameters:
        args: xi, x, u
            * :math:`x_{\text{i}}` - target sample points
            * :math:`x` - function sample points
            * :math:`u` - function values
        kwargs:
            * method : string
                Specify interpolation method 'linear, 'spline', 'harmonic'
            * nc : int
                Number of harmonic coefficients for the 'harmonic' method.

      Returns:
        ui: array of length xi
            :math:`u_{\text{i}} = I(x_{\text{i}})`, with :math:`I = u(x)`


    To use the core functions :gimliapi:`GIMLI::interpolate` start with a
    mesh instance as first argument or use the appropriate keyword arguments.

    TODO

    * 2D parametric to points (method=['linear, 'spline', 'harmonic'])
    * 2D/3D point cloud to points/grids ('Delauney', 'linear, 'spline', 'harmonic')
    * Mesh to points based on nearest neighbour values (pg.core)

    Examples
    --------
    >>> # no need to import matplotlib. pygimli's show does
    >>> import numpy as np
    >>> import pygimli as pg
    >>> fig, ax = pg.plt.subplots(1, 1, figsize=(10, 5))
    >>> u = np.array([1.0, 12.0, 3.0, -4.0, 5.0, 6.0, -1.0])
    >>> xu = np.array(range(len(u)))
    >>> xi = np.linspace(xu[0], xu[-1], 1000)
    >>> _= ax.plot(xu, u, 'o')
    >>> _= ax.plot(xi, pg.interpolate(xi, xu, u, method='linear'),
    ...         color='blue', label='linear')
    >>> _= ax.plot(xi, pg.interpolate(xi, xu, u, method='spline'),
    ...            color='red', label='spline')
    >>> _= ax.plot(xi, pg.interpolate(xi, xu, u, method='harmonic'),
    ...         color='green', label='harmonic')
    >>> _= ax.legend()
    """
    pgcore = False
    if 'srcMesh' in kwargs:
        pgcore = True

    elif len(args) > 0:
        if isinstance(args[0], pg.Mesh):
            if len(args) == 2 and isinstance(args[1], pg.Mesh):
                return pg.core._pygimli_.interpolate(args[0], args[1],
                                                     **kwargs)

            if len(args) == 3 and isinstance(args[1], pg.Mesh):
                pgcore = False  # (outMesh, inMesh, vals)
            else:
                pgcore = True

    if pgcore:
        if len(args) == 3:  # args: outData = (inMesh, inData, outPos)

            if args[1].ndim == 2:  # outData = (inMesh, mat, vR3)

                outMat = pg.Matrix()
                pg.core._pygimli_.interpolate(args[0],
                                              inMat=np.array(args[1]),
                                              destPos=args[2],
                                              outMat=outMat,
                                              **kwargs)
                return np.array(outMat)

        if len(args) == 4:  # args: (inMesh, inData, outPos, outData)

            if args[1].ndim == 1 and args[2].ndim == 1 and args[3].ndim == 1:
                return pg.core._pygimli_.interpolate(args[0],
                                                     inVec=args[1],
                                                     x=args[2],
                                                     y=args[3],
                                                     **kwargs)

            if isinstance(args[1], pg.RMatrix) and \
               isinstance(args[3], pg.RMatrix):
                return pg.core._pygimli_.interpolate(args[0],
                                                     inMat=args[1],
                                                     destPos=args[2],
                                                     outMat=args[3],
                                                     **kwargs)
            if isinstance(args[1], pg.RVector) and \
               isinstance(args[3], pg.RVector):
                return pg.core._pygimli_.interpolate(args[0],
                                                     inVec=args[1],
                                                     destPos=args[2],
                                                     outVec=args[3],
                                                     **kwargs)

        if len(args) == 5:
            if args[1].ndim == 1 and args[2].ndim == 1 and \
               args[3].ndim == 1 and args[4].ndim == 1:
                return pg.core._pygimli_.interpolate(args[0],
                                                     inVec=args[1],
                                                     x=args[2],
                                                     y=args[3],
                                                     z=args[4],
                                                     **kwargs)

        return pg.core._pygimli_.interpolate(*args, **kwargs)
        # end if pg.core:

    if len(args) == 3:

        if isinstance(args[0], pg.Mesh):  # args: (outMesh, inMesh, data)
            outMesh = args[0]
            inMesh = args[1]
            data = args[2]

            if isinstance(data, pg.R3Vector) or isinstance(
                    data, pg.stdVectorRVector3):
                x = pg.interpolate(outMesh, inMesh, pg.x(data))
                y = pg.interpolate(outMesh, inMesh, pg.y(data))
                z = pg.interpolate(outMesh, inMesh, pg.z(data))
                return np.vstack([x, y, z]).T

            if isinstance(data, np.ndarray):
                if data.ndim == 2 and data.shape[1] == 3:
                    x = pg.interpolate(outMesh, inMesh, data[:, 0])
                    y = pg.interpolate(outMesh, inMesh, data[:, 1])
                    z = pg.interpolate(outMesh, inMesh, data[:, 2])
                    return np.vstack([x, y, z]).T

            if len(data) == inMesh.cellCount():
                return pg.interpolate(srcMesh=inMesh,
                                      inVec=data,
                                      destPos=outMesh.cellCenters())
            elif len(data) == inMesh.nodeCount():
                return pg.interpolate(srcMesh=inMesh,
                                      inVec=data,
                                      destPos=outMesh.positions())
            else:
                print(inMesh)
                print(outMesh)
                raise Exception("Don't know how to interpolate data of size",
                                str(len(data)))

            print("data: ", data)
            raise Exception("Cannot interpret data: ", str(len(data)))

        else:  #args: xi, x, u

            xi = args[0]
            x = args[1]
            u = args[2]

            method = kwargs.pop('method', 'linear')

            if 'linear' in method:
                return np.interp(xi, x, u)

            if 'harmonic' in method:
                coeff = kwargs.pop('nc', int(np.ceil(np.sqrt(len(x)))))
                from pygimli.frameworks import harmfitNative
                return harmfitNative(u, x=x, nc=coeff, xc=xi, err=None)[0]

            if 'spline' in method:
                if pg.optImport("scipy",
                                requiredFor="use interpolate splines."):
                    from scipy import interpolate
                    tck = interpolate.splrep(x, u, s=0)
                    return interpolate.splev(xi, tck, der=0)
                else:
                    return xi * 0.

    if len(args) == 2:  # args curve, t
        curve = args[0]
        t = args[1]
        return interpolateAlongCurve(curve, t, **kwargs)
Example #58
0
def midconfERT(data, ind=None, rnum=1, circular=False):
    """Return the midpoint and configuration key for ERT data.

    Return the midpoint and configuration key for ERT data.

    Parameters
    ----------
    data : DataContainerERT
        data container with sensorPositions and a/b/m/n fields

    ind : []
        Documentme

    rnum : []
        Documentme

    circular : bool
        Return midpoint in degree (rad) instead if meter.

    Returns
    -------
    mid : np.array of float
        representative midpoint (middle of MN, AM depending on array)
    conf : np.array of float
        configuration/array key consisting of
        1) array type (Wenner-alpha/beta, Schlumberger, PP, PD, DD, MG)
            00000: pole-pole
            10000: pole-dipole or dipole-pole
            30000: Wenner-alpha
            40000: Schlumberger or Gradient
            50000: dipole-dipole or Wenner-beta
        2) potential dipole length (in electrode spacings)
            .XX..: dipole length
        3) separation factor (current dipole length or (di)pole separation)
            ...XX: pole/dipole separation (PP,PD,DD,GR) or separation
    """
    #    xe = np.hstack((pg.x(data.sensorPositions()), np.nan))  # not used anymore
    x0 = data.sensorPosition(0).x()
    xe = pg.x(data.sensorPositions()) - x0
    ux = pg.unique(xe)

    if len(ux) * 2 > data.sensorCount():  # 2D with topography case
        dx = np.array(pg.utils.diff(pg.utils.cumDist(data.sensorPositions())))
        dxM = pg.mean(dx)
        if min(pg.y(data)) != max(pg.y(data)) or \
           min(pg.z(data)) != max(pg.z(data)):
            # Topography case
            if (max(abs(dx - dxM)) < dxM * 0.9):
                # if the maximum spacing < meanSpacing/2 we assume equidistant
                # spacing and no missing electrodes
                dx = np.ones(len(dx)) * dxM
            else:
                # topography with probably missing electrodes
                dx = np.floor(dx / np.round(dxM)) * dxM
                pass
        if max(dx) < 0.5:
            print("Detecting small distances, using mm accuracy")
            rnum = 3
        xe = np.hstack((0., np.cumsum(np.round(dx, rnum)), np.nan))

        de = np.median(np.diff(xe[:-1])).round(rnum)
        ne = np.round(xe / de)
    else:  # 3D (without topo) case => take positions directly
        de = np.median(np.diff(ux)).round(1)
        ne = np.array(xe / de, dtype=int)

    # a, b, m, n = data('a'), data('b'), data('m'), data('n')
    # check if xe[a]/a is better suited (has similar size)
    if circular:
        # for circle geometry
        center = np.mean(data.sensorPositions(), axis=0)
        r = data.sensors()[0].distance(center)
        s0 = data.sensors()[0] - center
        s1 = data.sensors()[1] - center
        p0 = np.arctan2(s0[1], s0[0])
        p1 = np.arctan2(s1[1], s1[0])
        if p1 > p0:
            # rotate left
            x = np.cos(np.linspace(0, 2 * pi,
                                   data.sensorCount() + 1) + p0)[:-1] * r
            y = np.sin(np.linspace(0, 2 * pi,
                                   data.sensorCount() + 1) + p0)[:-1] * r
        else:
            x = np.cos(np.linspace(2 * pi, 0,
                                   data.sensorCount() + 1) + p0)[:-1] * r
            y = np.sin(np.linspace(2 * pi, 0,
                                   data.sensorCount() + 1) + p0)[:-1] * r

        a = np.array([np.arctan2(y[i], x[i]) for i in data['a']])
        b = np.array([np.arctan2(y[i], x[i]) for i in data['b']])
        m = np.array([np.arctan2(y[i], x[i]) for i in data['m']])
        n = np.array([np.arctan2(y[i], x[i]) for i in data['n']])

        a = np.unwrap(a) % (np.pi * 2)
        b = np.unwrap(b) % (np.pi * 2)
        m = np.unwrap(m) % (np.pi * 2)
        n = np.unwrap(n) % (np.pi * 2)

    else:
        a = np.array([ne[int(i)] for i in data('a')])
        b = np.array([ne[int(i)] for i in data('b')])
        m = np.array([ne[int(i)] for i in data('m')])
        n = np.array([ne[int(i)] for i in data('n')])

    if ind is not None:
        a = a[ind]
        b = b[ind]
        m = m[ind]
        n = n[ind]

    anan = np.isnan(a)
    a[anan] = b[anan]
    b[anan] = np.nan
    ab, am, an = np.abs(a - b), np.abs(a - m), np.abs(a - n)
    bm, bn, mn = np.abs(b - m), np.abs(b - n), np.abs(m - n)

    if circular:
        for v in [ab, mn, bm, an]:
            v[v > pi] = 2 * pi - v[v > pi]

    # 2-point (default) 00000
    sep = np.abs(a - m)
    mid = (a + m) / 2

    # 3-point (PD, DP) (now only b==-1 or n==-<1, check also for a and m)
    imn = np.isfinite(n) * np.isnan(b)
    mid[imn] = (m[imn] + n[imn]) / 2
    sep[imn] = np.minimum(am[imn], an[imn]) + 10000 + 100 * (mn[imn]-1) + \
        (np.sign(a[imn]-m[imn])/2+0.5) * 10000
    iab = np.isfinite(b) * np.isnan(n)
    mid[iab] = (a[iab] + b[iab]) / 2  # better 20000 or -10000?
    sep[iab] = np.minimum(am[iab], bm[iab]) + 10000 + 100 * (ab[iab]-1) + \
        (np.sign(a[iab]-n[iab])/2+0.5) * 10000
    #  + 10000*(a-m)

    # 4-point alpha: 30000 (WE) or 4000 (SL)
    iabmn = np.isfinite(a) & np.isfinite(b) & np.isfinite(m) & np.isfinite(n)
    ialfa = np.copy(iabmn)
    ialfa[iabmn] = (ab[iabmn] >= mn[iabmn] + 2)  # old
    mnmid = (m[iabmn] + n[iabmn]) / 2
    ialfa[iabmn] = np.sign((a[iabmn] - mnmid) * (b[iabmn] - mnmid)) < 0

    mid[ialfa] = (m[ialfa] + n[ialfa]) / 2
    spac = np.minimum(bn[ialfa], bm[ialfa])
    abmn3 = np.round((3 * mn[ialfa] - ab[ialfa]) * 10000) / 10000
    sep[ialfa] = spac + (mn[ialfa]-1)*100*(abmn3 != 0) + \
        30000 + (abmn3 < 0)*10000
    # gradient

    # %% 4-point beta
    ibeta = np.copy(iabmn)
    ibeta[iabmn] = (bm[iabmn] >= mn[iabmn]) & (~ialfa[iabmn])

    if circular:
        # print(ab[ibeta])
        ibeta = np.copy(iabmn)

        def _averageAngle(vs):
            sumsin = 0
            sumcos = 0

            for v in vs:
                sumsin += np.sin(v)
                sumcos += np.cos(v)

            return np.arctan2(sumsin, sumcos)

        abC = _averageAngle([a[ibeta], b[ibeta]])
        mnC = _averageAngle([m[ibeta], n[ibeta]])

        mid[ibeta] = _averageAngle([abC, mnC])

        # special case when dipoles are completely opposite
        iOpp = abs(abs((mnC - abC)) - np.pi) < 1e-3
        mid[iOpp] = _averageAngle([b[iOpp], m[iOpp]])

        minAb = min(ab[ibeta])
        sep[ibeta] = 50000 + (np.round(ab[ibeta]/minAb)) * 100 + \
            np.round(np.minimum(np.minimum(am[ibeta], an[ibeta]),
                                np.minimum(bm[ibeta], bn[ibeta])) / minAb)
    else:
        mid[ibeta] = (a[ibeta] + b[ibeta] + m[ibeta] + n[ibeta]) / 4

        sep[ibeta] = 50000 + (ab[ibeta] - 1) * 100 + np.minimum(
            np.minimum(am[ibeta], an[ibeta]), np.minimum(bm[ibeta], bn[ibeta]))

    # %% 4-point gamma
    # multiply with electrode distance and add first position
    if not circular:
        mid *= de
        mid += x0
    return mid, sep
Example #59
0
    def showRayPaths(self, model=None, ax=None, **kwargs):
        """Show ray paths for `model` or last model for which the Jacobian was
        calculated.

        Parameters
        ----------
        model : array
            Velocity model for which to calculate and visualize ray paths (the
            default is model for last Jacobian calculation in self.velocity).
        ax : matplotlib.axes
            Axes for the plot (the default is None).
        **kwargs : type
            Additional arguments passed to LineCollection (alpha, linewidths,
            color, linestyles).

        Returns
        -------
        ax : matplotlib.axes object
        cb : matplotlib.colorbar object (only if model is provided)

        Examples
        --------
        >>> # No reason to import matplotlib
        >>> import pygimli as pg
        >>> from pygimli.physics import Refraction
        >>> from pygimli.physics.traveltime import createRAData
        >>>
        >>> x, y = 8, 6
        >>> mesh = pg.createGrid(x, y)
        >>> data = createRAData([(0,0)] + [(x, i) for i in range(y)], shotdistance=y+1)
        >>> data.set("t", pg.RVector(data.size(), 1.0))
        >>> rst = Refraction()
        >>> rst.setDataContainer(data)
        Data: Sensors: 7 data: 6
        >>> rst.setMesh(mesh, 5)
        >>> ax, cb = rst.showRayPaths()
        """
        cbar = None
        if model is None and self.velocity is None:
            pg.info("No previous inversion result found and no model given.",
                    "Using homogeneous slowness model.")
            self.velocity = pg.RVector(self.mesh.cellCount(), 1.0)
            self.fop.createJacobian(1. / self.velocity)

        if model is not None:
            if self.velocity is not None:
                if not np.allclose(model, self.velocity):
                    self.fop.createJacobian(1 / model)

            ax, cbar = self.showResult(ax=ax, val=model)
            _ = kwargs.setdefault("color", "w")
            _ = kwargs.setdefault("alpha", 0.5)
            _ = kwargs.setdefault("linewidths", 0.8)
        else:
            ax = self.showMesh(ax=ax)

        # Due to different numbering scheme of way matrix
        _, shots = np.unique(self.dataContainer("s"), return_inverse=True)
        _, receivers = np.unique(self.dataContainer("g"), return_inverse=True)

        # Collecting way segments for all shot/receiver combinations
        segs = []
        for s, g in zip(shots, receivers):
            wi = self.fop.way(s, g)
            points = self.fop.mesh().positions(withSecNodes=True)[wi]
            segs.append(np.column_stack((pg.x(points), pg.y(points))))

        line_segments = LineCollection(segs, **kwargs)
        ax.add_collection(line_segments)
        return ax, cbar
Example #60
0
    fig, a = plt.subplots()
    drawMesh(a, mesh)
    pg.show(mesh, axes=a, data=l[0])

    cells = fwd.mesh().cells()
    active_cells = [cells[i] for i in range(mesh.cellCount()) if l[0][i]]
#    active_cells.append(cells[2044])
    for c in active_cells:
        pos = c.center()
        gradient = 2000*c.grad(pos, fwd.timefields[0])
        dx, dy = gradient.x(), gradient.y()
        a.text(pos.x(), pos.y(), str(c.id()))
        a.arrow(pos.x(), pos.y(), dx, dy)

    ray = fwd.poslist
    a.plot(pg.x(ray), pg.y(ray), 'm-*', )
    plt.show()

    # look at if next gradient contradicts the previous
    # if so, then follow the interface instead (line segment to next node)
    # this will stop when the gradients are more aligned.

#    drawMesh(a, mesh)
#    drawField(a, mesh, fwd.timefields[0], True, 'Spectral')
#    drawStreamLines(a, mesh, fwd.timefields[0], nx=50, ny=50)

    # some stats:
    diff_rms = np.sqrt(np.sum(delta_t**2)/len(delta_t))
    print("RMS of difference: {}".format(diff_rms))
    print("Mean of difference: {}".format(np.mean(delta_t)))
    print("Standard dev of difference: {}".format(np.std(delta_t)))