Esempio n. 1
0
def _checkAccuracy(A, b, X, accuracyTol):
    nrm = np.linalg.norm(mkvc(A*X - b), np.inf)
    nrm_b = np.linalg.norm(mkvc(b), np.inf)
    if nrm_b > 0:
        nrm /= nrm_b
    if nrm > accuracyTol:
        msg = '### SolverWarning ###: Accuracy on solve is above tolerance: %e > %e' % (nrm, accuracyTol)
        print msg
        warnings.warn(msg, RuntimeWarning)
Esempio n. 2
0
def _checkAccuracy(A, b, X, accuracyTol):
    nrm = np.linalg.norm(mkvc(A * X - b), np.inf)
    nrm_b = np.linalg.norm(mkvc(b), np.inf)
    if nrm_b > 0:
        nrm /= nrm_b
    if nrm > accuracyTol:
        msg = '### SolverWarning ###: Accuracy on solve is above tolerance: {0:e} > {1:e}'.format(
            nrm, accuracyTol)
        print msg
        warnings.warn(msg, RuntimeWarning)
Esempio n. 3
0
def surface2ind_topo(mesh, topo, gridLoc='CC'):
# def genActiveindfromTopo(mesh, topo):
    """
    Get active indices from topography
    """


    if mesh.dim == 3:
        from scipy.interpolate import NearestNDInterpolator
        Ftopo = NearestNDInterpolator(topo[:,:2], topo[:,2])

        if gridLoc == 'CC':
            XY = ndgrid(mesh.vectorCCx, mesh.vectorCCy)
            Zcc = mesh.gridCC[:,2].reshape((np.prod(mesh.vnC[:2]), mesh.nCz), order='F')

            gridTopo = Ftopo(XY)
            actind = [gridTopo[ixy] <= Zcc[ixy,:] for ixy in range(np.prod(mesh.vnC[0]))]
            actind = np.hstack(actind)

        elif gridLoc == 'N':

            XY = ndgrid(mesh.vectorNx, mesh.vectorNy)
            gridTopo = Ftopo(XY).reshape(mesh.vnN[:2], order='F')

            if mesh._meshType not in ['TENSOR', 'CYL', 'BASETENSOR']:
                raise NotImplementedError('Nodal surface2ind_topo not implemented for %s mesh'%mesh._meshType)

            Nz = mesh.vectorNz[1:] # TODO: this will only work for tensor meshes
            actind = np.array([False]*mesh.nC).reshape(mesh.vnC, order='F')

            for ii in range(mesh.nCx):
                for jj in range(mesh.nCy):
                     actind[ii,jj,:] = [np.all(gridTopo[ii:ii+2, jj:jj+2] >= Nz[kk]) for kk in range(len(Nz)) ]

    elif mesh.dim == 2:
        from scipy.interpolate import interp1d
        Ftopo = interp1d(topo[:,0], topo[:,1])

        if gridLoc == 'CC':
            gridTopo = Ftopo(mesh.gridCC[:,0])
            actind = mesh.gridCC[:,1] <= gridTopo

        elif gridLoc == 'N':

            gridTopo = Ftopo(mesh.vectorNx)
            if mesh._meshType not in ['TENSOR', 'CYL', 'BASETENSOR']:
                raise NotImplementedError('Nodal surface2ind_topo not implemented for %s mesh'%mesh._meshType)

            Ny = mesh.vectorNy[1:] # TODO: this will only work for tensor meshes
            actind = np.array([False]*mesh.nC).reshape(mesh.vnC, order='F')

            for ii in range(mesh.nCx):
                actind[ii,:] = [np.all(gridTopo[ii:ii+2] > Ny[kk]) for kk in range(len(Ny)) ]

    else:
        raise NotImplementedError('surface2ind_topo not implemented for 1D mesh')

    return mkvc(actind)
Esempio n. 4
0
def layeredModel(ccMesh, layerTops, layerValues):
    """
        Define a layered model from layerTops (z-positive up)

        :param numpy.array ccMesh: cell-centered mesh
        :param numpy.array layerTops: z-locations of the tops of each layer
        :param numpy.array layerValue: values of the property to assign for each layer (starting at the top) 
        :rtype: numpy.array
        :return: M, layered model on the mesh 
    """

    descending = np.linalg.norm(sorted(layerTops, reverse=True) -
                                layerTops) < 1e-20

    # TODO: put an error check to make sure that there is an ordering... needs to work with inf elts
    # assert ascending or descending, "Layers must be listed in either ascending or descending order"

    # start from bottom up
    if not descending:
        zprop = np.hstack([mkvc(layerTops, 2), mkvc(layerValues, 2)])
        zprop.sort(axis=0)
        layerTops, layerValues = zprop[::-1, 0], zprop[::-1, 1]

    # put in vector form
    layerTops, layerValues = mkvc(layerTops), mkvc(layerValues)

    # initialize with bottom layer
    dim = ccMesh.shape[1]
    if dim == 3:
        z = ccMesh[:, 2]
    elif dim == 2:
        z = ccMesh[:, 1]
    elif dim == 1:
        z = ccMesh[:, 0]

    model = np.zeros(ccMesh.shape[0])

    for i, top in enumerate(layerTops):
        zind = z <= top
        model[zind] = layerValues[i]

    return model
Esempio n. 5
0
def layeredModel(ccMesh, layerTops, layerValues):
    """
        Define a layered model from layerTops (z-positive up)

        :param numpy.array ccMesh: cell-centered mesh
        :param numpy.array layerTops: z-locations of the tops of each layer
        :param numpy.array layerValue: values of the property to assign for each layer (starting at the top) 
        :rtype: numpy.array
        :return: M, layered model on the mesh 
    """

    descending = np.linalg.norm(sorted(layerTops, reverse=True) - layerTops) < 1e-20

    # TODO: put an error check to make sure that there is an ordering... needs to work with inf elts 
    # assert ascending or descending, "Layers must be listed in either ascending or descending order"

    # start from bottom up
    if not descending:
        zprop = np.hstack([mkvc(layerTops,2),mkvc(layerValues,2)])
        zprop.sort(axis=0)
        layerTops, layerValues  = zprop[::-1,0], zprop[::-1,1]

    # put in vector form
    layerTops, layerValues = mkvc(layerTops), mkvc(layerValues)

    # initialize with bottom layer
    dim = ccMesh.shape[1]
    if dim == 3:
        z = ccMesh[:,2]
    elif dim == 2:
        z = ccMesh[:,1]
    elif dim == 1:
        z = ccMesh[:,0]

    model = np.zeros(ccMesh.shape[0])

    for i, top in enumerate(layerTops):
        zind = z <= top 
        model[zind] = layerValues[i]

    return model 
Esempio n. 6
0
def defineBlock(ccMesh,p0,p1,vals=[0,1]):
    """
        Build a block with the conductivity specified by condVal.  Returns an array.
        vals[0]  conductivity of the block
        vals[1]  conductivity of the ground
    """
    sigma = np.zeros(ccMesh.shape[0]) + vals[1]
    ind   = getIndicesBlock(p0,p1,ccMesh)

    sigma[ind] = vals[0]

    return mkvc(sigma)
Esempio n. 7
0
def defineBlock(ccMesh, p0, p1, vals=[0, 1]):
    """
        Build a block with the conductivity specified by condVal.  Returns an array.
        vals[0]  conductivity of the block
        vals[1]  conductivity of the ground
    """
    sigma = np.zeros(ccMesh.shape[0]) + vals[1]
    ind = getIndicesBlock(p0, p1, ccMesh)

    sigma[ind] = vals[0]

    return mkvc(sigma)
Esempio n. 8
0
def scalarConductivity(ccMesh, pFunction):
    """
    Define the distribution conductivity in the mesh according to the
    analytical expression given in pFunction
    """
    dim = np.size(ccMesh[0, :])
    CC = [ccMesh[:, 0]]
    if dim > 1: CC.append(ccMesh[:, 1])
    if dim > 2: CC.append(ccMesh[:, 2])

    sigma = pFunction(*CC)

    return mkvc(sigma)
Esempio n. 9
0
def interpmat(locs, x, y=None, z=None):
    """
        Local interpolation computed for each receiver point in turn

        :param numpy.ndarray loc: Location of points to interpolate to
        :param numpy.ndarray x: Tensor vector of 1st dimension of grid.
        :param numpy.ndarray y: Tensor vector of 2nd dimension of grid. None by default.
        :param numpy.ndarray z: Tensor vector of 3rd dimension of grid. None by default.
        :rtype: scipy.sparse.csr.csr_matrix
        :return: Interpolation matrix

        .. plot::

            import SimPEG
            import numpy as np
            import matplotlib.pyplot as plt
            locs = np.random.rand(50)*0.8+0.1
            x = np.linspace(0,1,7)
            dense = np.linspace(0,1,200)
            fun = lambda x: np.cos(2*np.pi*x)
            Q = SimPEG.Utils.interpmat(locs, x)
            plt.plot(x, fun(x), 'bs-')
            plt.plot(dense, fun(dense), 'y:')
            plt.plot(locs, Q*fun(x), 'mo')
            plt.plot(locs, fun(locs), 'rx')
            plt.show()

    """

    npts = locs.shape[0]
    locs = locs.astype(float)
    x = x.astype(float)
    if y is None and z is None:
        shape = [
            x.size,
        ]
        inds, vals = _interpmat1D(mkvc(locs), x)
    elif z is None:
        y = y.astype(float)
        shape = [x.size, y.size]
        inds, vals = _interpmat2D(locs, x, y)
    else:
        y = y.astype(float)
        z = z.astype(float)
        shape = [x.size, y.size, z.size]
        inds, vals = _interpmat3D(locs, x, y, z)

    I = np.repeat(range(npts), 2**len(shape))
    J = sub2ind(shape, inds)
    Q = sp.csr_matrix((vals, (I, J)), shape=(npts, np.prod(shape)))
    return Q
Esempio n. 10
0
def interpmat(locs, x, y=None, z=None):
    """
        Local interpolation computed for each receiver point in turn

        :param numpy.ndarray loc: Location of points to interpolate to
        :param numpy.ndarray x: Tensor vector of 1st dimension of grid.
        :param numpy.ndarray y: Tensor vector of 2nd dimension of grid. None by default.
        :param numpy.ndarray z: Tensor vector of 3rd dimension of grid. None by default.
        :rtype: scipy.sparse.csr_matrix
        :return: Interpolation matrix

        .. plot::

            import SimPEG
            import numpy as np
            import matplotlib.pyplot as plt
            locs = np.random.rand(50)*0.8+0.1
            x = np.linspace(0,1,7)
            dense = np.linspace(0,1,200)
            fun = lambda x: np.cos(2*np.pi*x)
            Q = SimPEG.Utils.interpmat(locs, x)
            plt.plot(x, fun(x), 'bs-')
            plt.plot(dense, fun(dense), 'y:')
            plt.plot(locs, Q*fun(x), 'mo')
            plt.plot(locs, fun(locs), 'rx')
            plt.show()

    """

    npts = locs.shape[0]
    locs = locs.astype(float)
    x = x.astype(float)
    if y is None and z is None:
        shape = [x.size,]
        inds, vals = _interpmat1D(mkvc(locs), x)
    elif z is None:
        y = y.astype(float)
        shape = [x.size, y.size]
        inds, vals = _interpmat2D(locs, x, y)
    else:
        y = y.astype(float)
        z = z.astype(float)
        shape = [x.size, y.size, z.size]
        inds, vals = _interpmat3D(locs, x, y, z)

    I = np.repeat(range(npts),2**len(shape))
    J = sub2ind(shape,inds)
    Q = sp.csr_matrix((vals,(I, J)),
                      shape=(npts, np.prod(shape)))
    return Q
Esempio n. 11
0
def scalarConductivity(ccMesh,pFunction):
    """
    Define the distribution conductivity in the mesh according to the
    analytical expression given in pFunction
    """
    dim = np.size(ccMesh[0,:])
    CC = [ccMesh[:,0]]
    if dim>1: CC.append(ccMesh[:,1])
    if dim>2: CC.append(ccMesh[:,2])


    sigma = pFunction(*CC)

    return mkvc(sigma)
Esempio n. 12
0
def writeUBCTensorModel(fileName, mesh, model):
    """
        Writes a model associated with a SimPEG TensorMesh
        to a UBC-GIF format model file.

        :param str fileName: File to write to
        :param simpeg.Mesh.TensorMesh mesh: The mesh
        :param numpy.ndarray model: The model
    """

    # Reshape model to a matrix
    modelMat = mesh.r(model,'CC','CC','M')
    # Transpose the axes
    modelMatT = modelMat.transpose((2,0,1))
    # Flip z to positive down
    modelMatTR = mkvc(modelMatT[::-1,:,:])

    np.savetxt(fileName, modelMatTR.ravel())
Esempio n. 13
0
def readUBCTensorModel(fileName, mesh):
    """
        Read UBC 3DTensor mesh model and generate 3D Tensor mesh model in simpeg

        Input:
        :param fileName, path to the UBC GIF mesh file to read
        :param mesh, TensorMesh object, mesh that coresponds to the model 

        Output:
        :return numpy array, model with TensorMesh ordered
    """
    f = open(fileName, 'r')
    model = np.array(map(float, f.readlines()))
    f.close()
    model = np.reshape(model, (mesh.nCz, mesh.nCx, mesh.nCy), order = 'F')
    model = model[::-1,:,:]
    model = np.transpose(model, (1, 2, 0))
    model = mkvc(model)

    return model
Esempio n. 14
0
def defineTwoLayers(ccMesh,depth,vals=None):
    """
    Define a two layered model.  Depth of the first layer must be specified.
    CondVals vector with the conductivity values of the layers.  Eg:

    Convention to number the layers::

        <----------------------------|------------------------------------>
        0                          depth                                 zf
             1st layer                       2nd layer
    """
    if vals is None:
        vals = [0,1]
    sigma = np.zeros(ccMesh.shape[0]) + vals[1]

    dim = np.size(ccMesh[0,:])

    p0 = np.zeros(dim)
    p1 = np.zeros(dim)

    # Identify 1st cell centered reference point
    p0[0] = ccMesh[0,0]
    if dim>1: p0[1] = ccMesh[0,1]
    if dim>2: p0[2] = ccMesh[0,2]

    # Identify the last cell-centered reference point
    p1[0] = ccMesh[-1,0]
    if dim>1: p1[1] = ccMesh[-1,1]
    if dim>2: p1[2] = ccMesh[-1,2]

    # The depth is always defined on the last one.
    p1[len(p1)-1] -= depth

    ind   = getIndicesBlock(p0,p1,ccMesh)

    sigma[ind] = vals[0];

    return mkvc(sigma)
Esempio n. 15
0
def surface2ind_topo(mesh, topo, gridLoc='CC'):
    # def genActiveindfromTopo(mesh, topo):
    """
    Get active indices from topography
    """

    if mesh.dim == 3:
        from scipy.interpolate import NearestNDInterpolator
        Ftopo = NearestNDInterpolator(topo[:, :2], topo[:, 2])

        if gridLoc == 'CC':
            XY = ndgrid(mesh.vectorCCx, mesh.vectorCCy)
            Zcc = mesh.gridCC[:, 2].reshape((np.prod(mesh.vnC[:2]), mesh.nCz),
                                            order='F')

            gridTopo = Ftopo(XY)
            actind = [
                gridTopo[ixy] <= Zcc[ixy, :]
                for ixy in range(np.prod(mesh.vnC[0]))
            ]
            actind = np.hstack(actind)

        elif gridLoc == 'N':

            XY = ndgrid(mesh.vectorNx, mesh.vectorNy)
            gridTopo = Ftopo(XY).reshape(mesh.vnN[:2], order='F')

            if mesh._meshType not in ['TENSOR', 'CYL', 'BASETENSOR']:
                raise NotImplementedError(
                    'Nodal surface2ind_topo not implemented for {0!s} mesh'.
                    format(mesh._meshType))

            Nz = mesh.vectorNz[
                1:]  # TODO: this will only work for tensor meshes
            actind = np.array([False] * mesh.nC).reshape(mesh.vnC, order='F')

            for ii in range(mesh.nCx):
                for jj in range(mesh.nCy):
                    actind[ii, jj, :] = [
                        np.all(gridTopo[ii:ii + 2, jj:jj + 2] >= Nz[kk])
                        for kk in range(len(Nz))
                    ]

    elif mesh.dim == 2:
        from scipy.interpolate import interp1d
        Ftopo = interp1d(topo[:, 0], topo[:, 1])

        if gridLoc == 'CC':
            gridTopo = Ftopo(mesh.gridCC[:, 0])
            actind = mesh.gridCC[:, 1] <= gridTopo

        elif gridLoc == 'N':

            gridTopo = Ftopo(mesh.vectorNx)
            if mesh._meshType not in ['TENSOR', 'CYL', 'BASETENSOR']:
                raise NotImplementedError(
                    'Nodal surface2ind_topo not implemented for {0!s} mesh'.
                    format(mesh._meshType))

            Ny = mesh.vectorNy[
                1:]  # TODO: this will only work for tensor meshes
            actind = np.array([False] * mesh.nC).reshape(mesh.vnC, order='F')

            for ii in range(mesh.nCx):
                actind[ii, :] = [
                    np.all(gridTopo[ii:ii + 2] > Ny[kk])
                    for kk in range(len(Ny))
                ]

    else:
        raise NotImplementedError(
            'surface2ind_topo not implemented for 1D mesh')

    return mkvc(actind)
Esempio n. 16
0
def faceInfo(xyz, A, B, C, D, average=True, normalizeNormals=True):
    """
    function [N] = faceInfo(y,A,B,C,D)

       Returns the averaged normal, area, and edge lengths for a given set of faces.

       If average option is FALSE then N is a cell array {nA,nB,nC,nD}


    Input:
       xyz          - X,Y,Z vertex vector
       A,B,C,D      - vert index of the face (counter clockwize)

    Options:
       average      - [true]/false, toggles returning all normals or the average

    Output:
       N            - average face normal or {nA,nB,nC,nD} if average = false
       area         - average face area
       edgeLengths  - exact edge Lengths, 4 column vector [AB, BC, CD, DA]

    see also testFaceNormal testFaceArea

    @author Rowan Cockett

    Last modified on: 2013/07/26

    """
    assert type(average) is bool, 'average must be a boolean'
    assert type(normalizeNormals) is bool, 'normalizeNormals must be a boolean'
    # compute normal that is pointing away from you.
    #
    #    A -------A-B------- B
    #    |                   |
    #    |                   |
    #   D-A       (X)       B-C
    #    |                   |
    #    |                   |
    #    D -------C-D------- C

    AB = xyz[B, :] - xyz[A, :]
    BC = xyz[C, :] - xyz[B, :]
    CD = xyz[D, :] - xyz[C, :]
    DA = xyz[A, :] - xyz[D, :]

    def cross(X, Y):
        return np.c_[X[:, 1] * Y[:, 2] - X[:, 2] * Y[:, 1],
                     X[:, 2] * Y[:, 0] - X[:, 0] * Y[:, 2],
                     X[:, 0] * Y[:, 1] - X[:, 1] * Y[:, 0]]

    nA = cross(AB, DA)
    nB = cross(BC, AB)
    nC = cross(CD, BC)
    nD = cross(DA, CD)

    length = lambda x: np.sqrt(x[:, 0]**2 + x[:, 1]**2 + x[:, 2]**2)
    normalize = lambda x: x / np.kron(np.ones(
        (1, x.shape[1])), mkvc(length(x), 2))
    if average:
        # average the normals at each vertex.
        N = (nA + nB + nC + nD) / 4  # this is intrinsically weighted by area
        # normalize
        N = normalize(N)
    else:
        if normalizeNormals:
            N = [normalize(nA), normalize(nB), normalize(nC), normalize(nD)]
        else:
            N = [nA, nB, nC, nD]

    # Area calculation
    #
    # Approximate by 4 different triangles, and divide by 2.
    # Each triangle is one half of the length of the cross product
    #
    # So also could be viewed as the average parallelogram.
    #
    # TODO: This does not compute correctly for concave quadrilaterals
    area = (length(nA) + length(nB) + length(nC) + length(nD)) / 4

    return N, area
Esempio n. 17
0
def faceInfo(xyz, A, B, C, D, average=True, normalizeNormals=True):
    """
    function [N] = faceInfo(y,A,B,C,D)

       Returns the averaged normal, area, and edge lengths for a given set of faces.

       If average option is FALSE then N is a cell array {nA,nB,nC,nD}


    Input:
       xyz          - X,Y,Z vertex vector
       A,B,C,D      - vert index of the face (counter clockwize)

    Options:
       average      - [true]/false, toggles returning all normals or the average

    Output:
       N            - average face normal or {nA,nB,nC,nD} if average = false
       area         - average face area
       edgeLengths  - exact edge Lengths, 4 column vector [AB, BC, CD, DA]

    see also testFaceNormal testFaceArea

    @author Rowan Cockett

    Last modified on: 2013/07/26

    """
    assert type(average) is bool, 'average must be a boolean'
    assert type(normalizeNormals) is bool, 'normalizeNormals must be a boolean'
    # compute normal that is pointing away from you.
    #
    #    A -------A-B------- B
    #    |                   |
    #    |                   |
    #   D-A       (X)       B-C
    #    |                   |
    #    |                   |
    #    D -------C-D------- C

    AB = xyz[B, :] - xyz[A, :]
    BC = xyz[C, :] - xyz[B, :]
    CD = xyz[D, :] - xyz[C, :]
    DA = xyz[A, :] - xyz[D, :]

    def cross(X, Y):
        return np.c_[X[:, 1]*Y[:, 2] - X[:, 2]*Y[:, 1],
                     X[:, 2]*Y[:, 0] - X[:, 0]*Y[:, 2],
                     X[:, 0]*Y[:, 1] - X[:, 1]*Y[:, 0]]

    nA = cross(AB, DA)
    nB = cross(BC, AB)
    nC = cross(CD, BC)
    nD = cross(DA, CD)

    length = lambda x: np.sqrt(x[:, 0]**2 + x[:, 1]**2 + x[:, 2]**2)
    normalize = lambda x: x/np.kron(np.ones((1, x.shape[1])), mkvc(length(x), 2))
    if average:
        # average the normals at each vertex.
        N = (nA + nB + nC + nD)/4  # this is intrinsically weighted by area
        # normalize
        N = normalize(N)
    else:
        if normalizeNormals:
            N = [normalize(nA), normalize(nB), normalize(nC), normalize(nD)]
        else:
            N = [nA, nB, nC, nD]

    # Area calculation
    #
    # Approximate by 4 different triangles, and divide by 2.
    # Each triangle is one half of the length of the cross product
    #
    # So also could be viewed as the average parallelogram.
    #
    # TODO: This does not compute correctly for concave quadrilaterals
    area = (length(nA)+length(nB)+length(nC)+length(nD))/4

    return N, area