Пример #1
0
def testShapefunctions( ):
    poly = g.Mesh( 3 )
    n0 = poly.createNode( 0.0, 0.0, 0.0 )
    n1 = poly.createNode( 1.0, 0.0, 0.0 )
    n2 = poly.createNode( 0.0, 1.0, 0.0 )
    n3 = poly.createNode( 0.0, 0.0, 0.5 )

    poly.createTetrahedron( n0, n1, n2, n3 )
    prism = poly.createP2Mesh()
            
    
    u = g.RVector( prism.nodeCount(), 0.0 ) 
    u[ 5 ] = 1.0
    prism.addExportData( "u", u )
    
    #n3 = poly.createNode( 1.0, 1.0, 0.0 )
    #poly.createTriangle( n0, n1, n3 )
    #prism = g.createMesh3D( poly, g.asvector( np.linspace( 0, -1, 2 ) ) )
    #prism.exportVTK( "prism" )

    
    
    #mesh2 = g.createMesh2D( g.asvector( np.linspace( 0, 1, 10 ) ), 
                            #g.asvector( np.linspace( 0, 1, 10 ) ) )
                                
    #mesh2 = mesh2.createH2Mesh()
                            
    #g.interpolate( prism, mesh2 )
        
    #ax = g.viewer.showMesh( mesh2, mesh2.exportData('u'), filled = True, showLater = True )
        
    mesh3 = g.createMesh3D( g.asvector( np.linspace( 0, 1, 11 ) ), 
                            g.asvector( np.linspace( 0, 1, 11 ) ), 
                            g.asvector( np.linspace( 0, 1, 11 ) ) )

    grads = g.stdVectorRVector3( )
    c = prism.cell( 0 )
    uc = g.RVector( mesh3.nodeCount() )
    
    for n in mesh3.nodes():
        p = c.shape().xyz( n.pos() )
        
        if not c.shape().isInside( p ):
            grads.append( g.RVector3( 0.0, 0.0, 0.0 ) )
            uc[ n.id() ] = 0.0
            continue
        
        uc[ n.id() ] = c.pot( p, u )
        print uc[ n.id() ]
        gr = c.grad( p, u )
        grads.append( gr )
        
    g.interpolate( prism, mesh3 )
    mesh3.addExportData( 'ua', uc )

    mesh3.exportVTK( "prismHex", grads )
    
    
    P.show()
Пример #2
0
    def computeTravelTimes(self, slowness, allSensors=True):
        """Compute the travel times and fill data and time matrix
        for later use of response and Jacobian, respectively.
        For response only active sources are needed, for Jacobian we need all.
        """
        # mesh = self.mesh()  # better but for now input mesh
        mesh = self.mesh_
        data = self.data_
        param_markers = np.unique(mesh.cellMarkers())
        param_count = len(param_markers)
        if len(slowness) == mesh.cellCount():
            self.mapModel(slowness)
        elif len(slowness) == param_count:
            # map the regions in the mesh to slowness
            slow_map = pg.stdMapF_F()
            min_reg_num = min(param_markers)
            for i, si in enumerate(slowness):
                slow_map.insert(float(i+min_reg_num), si)

            mesh.mapCellAttributes(slow_map)
        else:
            raise ValueError("Wrong no of parameters. Mesh size: {}, no "
                             "of regions: {}, and number of slowness values:"
                             "{}".format(self.mesh().cellCount(), param_count,
                                         len(slowness)))

        times = pg.RVector(self.nNodes, 0.)
        upTags = np.zeros(self.nNodes)
        downTags = np.zeros(mesh.nodeCount())
        for iSource in range(self.nSensors):
            # initial condition (reset vectors)
            times *= 0.0
            upTags *= 0
            downwind = set()
            source = self.data_.sensorPosition(iSource)
            cell = self.mesh_.findCell(source)
            # fill in nodes around source using local smoothness
            for i, n in enumerate(cell.nodes()):
                times[n.id()] = cell.attribute() * n.pos().distance(source)
                upTags[n.id()] = 1
            for i, n in enumerate(cell.nodes()):
                tmpNodes = pg.commonNodes(n.cellSet())
                for nn in tmpNodes:
                    if not upTags[nn.id()] and not downTags[nn.id()]:
                        downwind.add(nn)
                        downTags[nn.id()] = 1

            while len(downwind) > 0:  # start fast marching
                fastMarch(self.mesh_, downwind, times, upTags, downTags)

            self.dataMatrix[iSource] = pg.interpolate(mesh, times,
                                                      data.sensorPositions())
            self.timeMatrix[iSource] = pg.interpolate(mesh, times,
                                                      self.midPoints)

            sensor_idx = data("g")[data("s") == iSource]
Пример #3
0
    def computeTravelTimes(self, slowness, allSensors=True):
        """Compute the travel times and fill data and time matrix
        for later use of response and Jacobian, respectively.
        For response only active sources are needed, for Jacobian we need all.
        """
        # mesh = self.mesh()  # better but for now input mesh
        mesh = self.mesh_
        data = self.data_
        param_markers = np.unique(mesh.cellMarkers())
        param_count = len(param_markers)
        if len(slowness) == mesh.cellCount():
            self.mapModel(slowness)
        elif len(slowness) == param_count:
            # map the regions in the mesh to slowness
            slow_map = pg.stdMapF_F()
            min_reg_num = min(param_markers)
            for i, si in enumerate(slowness):
                slow_map.insert(float(i + min_reg_num), si)

            mesh.mapCellAttributes(slow_map)
        else:
            raise ValueError("Wrong no of parameters. Mesh size: {}, no "
                             "of regions: {}, and number of slowness values:"
                             "{}".format(self.mesh().cellCount(), param_count,
                                         len(slowness)))

        times = pg.RVector(self.nNodes, 0.)
        upTags = np.zeros(self.nNodes)
        downTags = np.zeros(mesh.nodeCount())
        for iSource in range(self.nSensors):
            # initial condition (reset vectors)
            times *= 0.0
            upTags *= 0
            downwind = set()
            source = self.data_.sensorPosition(iSource)
            cell = self.mesh_.findCell(source)
            # fill in nodes around source using local smoothness
            for i, n in enumerate(cell.nodes()):
                times[n.id()] = cell.attribute() * n.pos().distance(source)
                upTags[n.id()] = 1
            for i, n in enumerate(cell.nodes()):
                tmpNodes = pg.commonNodes(n.cellSet())
                for nn in tmpNodes:
                    if not upTags[nn.id()] and not downTags[nn.id()]:
                        downwind.add(nn)
                        downTags[nn.id()] = 1

            while len(downwind) > 0:  # start fast marching
                fastMarch(self.mesh_, downwind, times, upTags, downTags)

            self.dataMatrix[iSource] = pg.interpolate(mesh, times,
                                                      data.sensorPositions())
            self.timeMatrix[iSource] = pg.interpolate(mesh, times,
                                                      self.midPoints)

            sensor_idx = data("g")[data("s") == iSource]
Пример #4
0
def linear_interpolation(inmesh, indata, outmesh):
    """ Linear interpolation using `pg.interpolate()` """
    outdata = pg.Vector()  # empty
    pg.interpolate(srcMesh=inmesh, inVec=indata,
                   destPos=outmesh.cellCenters(), outVec=outdata)

    # alternatively you can use the interpolation matrix
    outdata = inmesh.interpolationMatrix(outmesh.cellCenters()) * \
              pg.core.cellDataToPointData(inmesh, indata)
    return outdata
Пример #5
0
def testShapefunctions():
    poly = g.Mesh(3)
    n0 = poly.createNode(0.0, 0.0, 0.0)
    n1 = poly.createNode(1.0, 0.0, 0.0)
    n2 = poly.createNode(0.0, 1.0, 0.0)
    n3 = poly.createNode(0.0, 0.0, 0.5)

    poly.createTetrahedron(n0, n1, n2, n3)
    prism = poly.createP2Mesh()

    u = g.RVector(prism.nodeCount(), 0.0)
    u[5] = 1.0
    prism.addExportData("u", u)

    #n3 = poly.createNode( 1.0, 1.0, 0.0 )
    #poly.createTriangle( n0, n1, n3 )
    #prism = g.createMesh3D( poly, g.asvector( np.linspace( 0, -1, 2 ) ) )
    #prism.exportVTK( "prism" )

    #mesh2 = g.createMesh2D( g.asvector( np.linspace( 0, 1, 10 ) ),
    #g.asvector( np.linspace( 0, 1, 10 ) ) )

    #mesh2 = mesh2.createH2Mesh()

    #g.interpolate( prism, mesh2 )

    #ax = g.viewer.showMesh( mesh2, mesh2.exportData('u'), filled = True, showLater = True )

    mesh3 = g.createMesh3D(g.asvector(np.linspace(0, 1, 11)),
                           g.asvector(np.linspace(0, 1, 11)),
                           g.asvector(np.linspace(0, 1, 11)))

    grads = g.stdVectorRVector3()
    c = prism.cell(0)
    uc = g.RVector(mesh3.nodeCount())

    for n in mesh3.nodes():
        p = c.shape().xyz(n.pos())

        if not c.shape().isInside(p):
            grads.append(g.RVector3(0.0, 0.0, 0.0))
            uc[n.id()] = 0.0
            continue

        uc[n.id()] = c.pot(p, u)
        print uc[n.id()]
        gr = c.grad(p, u)
        grads.append(gr)

    g.interpolate(prism, mesh3)
    mesh3.addExportData('ua', uc)

    mesh3.exportVTK("prismHex", grads)

    P.show()
Пример #6
0
def resistivityArchie(rBrine,
                      porosity,
                      a=1.0,
                      m=2.0,
                      S=1.0,
                      n=2.0,
                      mesh=None,
                      meshI=None):
    """
    .. math::
        \rho = a\rho_{\text{Brine}}\phi^{-m}\S_w^{-n}

    * :math:`\rho` - the electrical conductivity of the fluid saturated rock
    * :math:`\rho_{\text{Brine}}` - electrical conductivity of the brine
    * :math:`\phi` - porosity 0.0 --1.0
    * :math:`a` - tortuosity factor. (common 1)
    * :math:`m` - cementation exponent of the rock
            (usually in the range 1.3 -- 2.5 for sandstones)
    * :math:`n` - is the saturation exponent (usually close to 2)

    """
    rB = None

    if rBrine.ndim == 1:
        rB = pg.RMatrix(1, len(rBrine))
        rB[0] = parseArgToArray(rBrine, mesh.cellCount(), mesh)
    elif rBrine.ndim == 2:
        rB = pg.RMatrix(len(rBrine), len(rBrine[0]))
        for i in range(len(rBrine)):
            rB[i] = rBrine[i]

    porosity = parseArgToArray(porosity, mesh.cellCount(), mesh)
    a = parseArgToArray(a, mesh.cellCount(), mesh)
    m = parseArgToArray(m, mesh.cellCount(), mesh)
    S = parseArgToArray(S, mesh.cellCount(), mesh)
    n = parseArgToArray(n, mesh.cellCount(), mesh)

    r = pg.RMatrix(len(rBrine), len(rBrine[0]))
    for i in range(len(r)):
        r[i] = rB[i] * a * porosity**(-m) * S**(-n)

    rI = pg.RMatrix(len(r), meshI.cellCount())
    if meshI:
        pg.interpolate(mesh, r, meshI.cellCenters(), rI)

    for i in range(len(rI)):
        rI[i] = pg.solver.fillEmptyToCellArray(meshI, rI[i])

    return rI
Пример #7
0
    def create_mesh(self, frame, step=7.5, extent=None):
        """
        create a grid mesh and populate the mesh with the frame data
        Args:
            frame:
            step:
            extent:
        Returns:

        """
        if extent is None:
            y, x = frame.shape
        else:
            x = extent[1]
            y = extent[3]

        self.mesh_fine = mt.createGrid(numpy.arange(0, x, step=1),
                                       numpy.arange(0, y, step=1))
        self.data_fine = mt.nodeDataToCellData(self.mesh_fine, frame.ravel())

        self.mesh = mt.createGrid(numpy.arange(0, x + step, step=step),
                                  numpy.arange(0, y + step, step=step))
        self.data = pg.interpolate(srcMesh=self.mesh_fine, inVec=self.data_fine,
                                   destPos=self.mesh.cellCenters()).array()
        return self.mesh, self.data
Пример #8
0
def permeabiltyEngelhardtPitter(poro, q=3.5, s=5e-3,
                                mesh=None, meshI=None):
    r"""
    For sand and sandstones
    
    .. math:: 
        k & = 2\cdot 10^7 \frac{\phi^2}{(1-\phi)^2}* \frac{1}{S^2} \\
        S & = q\cdot s \\
        s & = \sum_{i=1}(\frac{P_i}{r_i})
        
    * :math:`\phi` - poro 0.0 --1.0
    * :math:`S` - in cm^-1  specific surface in cm^2/cm^3
    * :math:`q` - (3 for spheres, > 3 shape differ from sphere)
        3.5 sand
    * :math:`s` - in cm^-1 (s = 1/r for particles with homogeneous radii r)
    * :math:`P_i` - Particle ration with radii :math:`r_i` on 1cm^3 Sample
    
    Returns
    -------
    k :
        in Darcy
    """
    poro = parseArgToArray(poro, mesh.cellCount(), mesh)
    q = parseArgToArray(q, mesh.cellCount(), mesh)
    s = parseArgToArray(s, mesh.cellCount(), mesh)
    
    S = q * s
    k = 2e7 * (poro**2 / (1.0-poro)**2) * 1.0/S**2 * physics.constants.Darcy
        
    if meshI:
        k = pg.interpolate(mesh, k, meshI.cellCenters()) 
        k = pg.solver.fillEmptyToCellArray(meshI, k)
    return k
Пример #9
0
        def _testP2_(mesh, show=False):
            """ Laplace u = 2 solves u = x² for u(r=0)=0 and u(r=1)=1
                Test for u == exact x² for P2 base functions
            """
            meshp2 = mesh.createP2()
            u = pg.solve(meshp2, f=-2, bc={'Dirichlet': [[1, 0], [2, 1]]})

            # find test pos different from node pos
            meshTests = mesh.createH2()
            meshTests = meshTests.createH2()

            c = [c.center() for c in meshTests.cells()]
            startPos = meshTests.node(0).pos()

            if mesh.dim() == 2:
                c = [b.center() for b in meshTests.boundaries(meshTests.boundaryMarkers()==4)]

            c.sort(key=lambda c_: c_.distance(startPos))
            ui = pg.interpolate(meshp2, u, c)
            xi = pg.utils.cumDist(c) + startPos.distance(c[0])       

            if show:
                pg.plt.plot(xi, ui)
                pg.plt.plot(xi, xi**2)
                pg.wait()
            
            np.testing.assert_allclose(ui, xi**2)
Пример #10
0
    def test_Interpolate(self):
        grid = pg.createGrid(x=[0.0, 1.0], y=[0.0, 1.0])
        u = pg.RVector(grid.nodeCount(), 1.)

        # test with pg.interpolate
        queryPos = [0.2, 0.2]
        uI = pg.interpolate(srcMesh=grid,
                            inVec=u,
                            destPos=[queryPos, queryPos])

        np.testing.assert_allclose(uI[0], 1.)

        # test manual interpolation
        c = grid.findCell(queryPos)
        uI = c.pot(queryPos, u)
        np.testing.assert_allclose(uI, 1.)

        # test with manual interpolationMatrix generation
        I = pg.RSparseMapMatrix(1, grid.nodeCount())
        cI = c.N(c.shape().rst(queryPos))
        for i in range(c.nodeCount()):
            I.addVal(0, c.node(i).id(), cI[i])

        uI = I.mult(u)
        np.testing.assert_allclose(uI[0], 1)

        # test with automatic interpolationMatrix generation
        I = grid.interpolationMatrix([[0.0, 0.0], [1.0, 0.0], [1.0, 1.0],
                                      [0.0, 1.0]])
        uI = I * u
        np.testing.assert_allclose(uI, u)
Пример #11
0
        def _testP2_(mesh, show=False):
            """ Laplace u = 2 solves u = x² for u(r=0)=0 and u(r=1)=1
                Test for u == exact x² for P2 base functions
            """
            meshp2 = mesh.createP2()
            u = pg.solve(meshp2, f=-2, bc={'Dirichlet': [[1, 0], [2, 1]]})

            # find test pos different from node pos
            meshTests = mesh.createH2()
            meshTests = meshTests.createH2()

            c = [c.center() for c in meshTests.cells()]
            startPos = meshTests.node(0).pos()

            if mesh.dim() == 2:
                c = [b.center() for b in meshTests.boundaries(meshTests.boundaryMarkers()==4)]

            c.sort(key=lambda c_: c_.distance(startPos))
            ui = pg.interpolate(meshp2, u, c)
            xi = pg.utils.cumDist(c) + startPos.distance(c[0])       

            if show:
                pg.plt.plot(xi, ui)
                pg.plt.plot(xi, xi**2)
                pg.wait()
            
            np.testing.assert_allclose(ui, xi**2)
Пример #12
0
def resistivityArchie(rBrine, porosity, a=1.0, m=2.0, S=1.0, n=2.0,
                      mesh=None, meshI=None):
    """
    .. math::
        \rho = a\rho_{\text{Brine}}\phi^{-m}\S_w^{-n}

    * :math:`\rho` - the electrical conductivity of the fluid saturated rock
    * :math:`\rho_{\text{Brine}}` - electrical conductivity of the brine
    * :math:`\phi` - porosity 0.0 --1.0
    * :math:`a` - tortuosity factor. (common 1)
    * :math:`m` - cementation exponent of the rock
            (usually in the range 1.3 -- 2.5 for sandstones)
    * :math:`n` - is the saturation exponent (usually close to 2)

    """
    rB = None

    if rBrine.ndim == 1:
        rB = pg.RMatrix(1, len(rBrine))
        rB[0] = parseArgToArray(rBrine, mesh.cellCount(), mesh)
    elif rBrine.ndim == 2:
        rB = pg.RMatrix(len(rBrine), len(rBrine[0]))
        for i in range(len(rBrine)):
            rB[i] = rBrine[i]

    porosity = parseArgToArray(porosity, mesh.cellCount(), mesh)
    a = parseArgToArray(a, mesh.cellCount(), mesh)
    m = parseArgToArray(m, mesh.cellCount(), mesh)
    S = parseArgToArray(S, mesh.cellCount(), mesh)
    n = parseArgToArray(n, mesh.cellCount(), mesh)

    r = pg.RMatrix(len(rBrine), len(rBrine[0]))
    for i in range(len(r)):
        r[i] = rB[i] * a * porosity**(-m) * S**(-n)

    rI = pg.RMatrix(len(r), meshI.cellCount())
    if meshI:
        pg.interpolate(mesh, r, meshI.cellCenters(), rI)

    for i in range(len(rI)):
        rI[i] = pg.solver.fillEmptyToCellArray(meshI, rI[i])

    return rI
Пример #13
0
def hydraulicConductivity(perm, visc=1.0, dens=1.0, mesh=None, meshI=None):
    perm = parseArgToArray(perm, mesh.cellCount(), mesh)
    visc = parseArgToArray(visc, mesh.cellCount(), mesh)
    dens = parseArgToArray(dens, mesh.cellCount(), mesh)

    k = perm * dens / visc * pg.physics.constants.g

    if meshI:
        k = pg.interpolate(mesh, k, meshI.cellCenters())
        k = pg.solver.fillEmptyToCellArray(meshI, k)
    return k
Пример #14
0
def hydraulicConductivity(perm, visc=1.0, dens=1.0,
                          mesh=None, meshI=None):
    perm = parseArgToArray(perm, mesh.cellCount(), mesh)
    visc = parseArgToArray(visc, mesh.cellCount(), mesh)
    dens = parseArgToArray(dens, mesh.cellCount(), mesh)
    
    k = perm * dens/visc * pg.physics.constants.g
    
    if meshI:
        k = pg.interpolate(mesh, k, meshI.cellCenters()) 
        k = pg.solver.fillEmptyToCellArray(meshI, k)
    return k
Пример #15
0
def makeInterpVector(data, dMesh, bPolyMesh, t=None):
    import pygimli as pg
    import numpy as np
    print('Interpolation data to mesh...')
    if "Time" in data and len(np.unique(data.Time)) > 1:
        if t is not None:
            if t in np.unique(data.Time):
                print('Using specified time value: ', t)
                dataCol = data['MINIT'][data['Time'] == t].values
                dInterp = pg.interpolate(dMesh, dataCol,
                                         bPolyMesh.cellCenter())
                print('Done')
                return dInterp, None
            else:
                print('Value not found. No interpolation done...')
                return None, None
        else:
            print('Multiple times found')
            times = np.zeros([
                int(len(data) / len(np.unique(data.Time))),
                len(np.unique(data.Time))
            ])
            dInterp = np.zeros(
                [bPolyMesh.cellCount(),
                 len(np.unique(data.Time))])
            for i, t in enumerate(np.unique(data.Time)):
                print("Converting time to data vector:", t)
                times[:, i] = data['MINIT'][data['Time'] == t].as_matrix()
                dInterp[:, i] = pg.interpolate(dMesh, times[:, i],
                                               bPolyMesh.cellCenter())
            print('Done')
            return dInterp, times
    else:
        dInterp = pg.interpolate(dMesh, data['dataCol'],
                                 bPolyMesh.cellCenter())
        print('Done')
        return dInterp, None
Пример #16
0
def permeabilityEngelhardtPitter(poro, q=3.5, s=5e-3,
                                 mesh=None, meshI=None):
    r"""Empirical model for porosity to hydraulic permeability.

    Postulated for sand and sandstones. :cite:`EngelhardtPit1955`

    .. math::
        k & = 2\cdot 10^7 \frac{\phi^2}{(1-\phi)^2}* \frac{1}{S^2} \\
        S & = q\cdot s \\
        s & = \sum_{i=1}(\frac{P_i}{r_i})

    * :math:`\phi` - poro 0.0 --1.0
    * :math:`q` - (3 for spheres, > 3 shape differ from sphere)
        3.5 sand
    * :math:`s` - in cm^-1 (s = 1/r for particles with homogeneous radii r)
    * :math:`P_i` - Particle ration with radii :math:`r_i` on 1cm^3 Sample
    * :math:`S` - in cm^-1  specific surface in cm^2/cm^3

    Parameters
    ----------

    Returns
    -------
    k :
        in Darcy
    """
    poro = pg.solver.parseArgToArray(poro, mesh.cellCount(), mesh)
    q = pg.solver.parseArgToArray(q, mesh.cellCount(), mesh)
    s = pg.solver.parseArgToArray(s, mesh.cellCount(), mesh)

    st = q * s
    k = 2e7 * (poro**2 / (1.0-poro)**2) * 1.0/st**2 * \
        pg.physics.Constants.Darcy

    if meshI is not None:
        k = pg.interpolate(mesh, k, meshI.cellCenters())
        k = pg.meshtools.fillEmptyToCellArray(meshI, k)
    return k
Пример #17
0
def nodeDataToCellData(mesh, data):
    """Convert node data to cell data.

    Convert node data to cell data via interpolation to cell centers.

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

    data : iterable [float]
        Data of len mesh.nodeCount().
        TODO complex, R3Vector, ndarray

    Examples
    --------
    """
    if len(data) != mesh.nodeCount():
        raise BaseException("Dimension mismatch, expecting nodeCount(): " +
                            str(mesh.nodeCount()) +
                            "got: " + str(len(data)), str(len(data[0])))

    return pg.interpolate(mesh, data, mesh.cellCenters())
Пример #18
0
def nodeDataToCellData(mesh, data):
    """Convert node data to cell data.

    Convert node data to cell data via interpolation to cell centers.

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

    data : iterable [float]
        Data of len mesh.nodeCount().
        TODO complex, R3Vector, ndarray

    Examples
    --------
    """
    if len(data) != mesh.nodeCount():
        raise BaseException("Dimension mismatch, expecting nodeCount(): " +
                            str(mesh.nodeCount()) +
                            "got: " + str(len(data)), str(len(data[0])))

    return pg.interpolate(mesh, data, destPos=mesh.cellCenters())
Пример #19
0
def permeabilityEngelhardtPitter(poro, q=3.5, s=5e-3, mesh=None, meshI=None):
    r"""Empirical model for porosity to hydraulic permeability.

    Postulated for sand and sandstones. :cite:`EngelhardtPit1955`

    .. math::
        k & = 2\cdot 10^7 \frac{\phi^2}{(1-\phi)^2}* \frac{1}{S^2} \\
        S & = q\cdot s \\
        s & = \sum_{i=1}(\frac{P_i}{r_i})

    * :math:`\phi` - poro 0.0 --1.0
    * :math:`q` - (3 for spheres, > 3 shape differ from sphere)
        3.5 sand
    * :math:`s` - in cm^-1 (s = 1/r for particles with homogeneous radii r)
    * :math:`P_i` - Particle ration with radii :math:`r_i` on 1cm^3 Sample
    * :math:`S` - in cm^-1  specific surface in cm^2/cm^3

    Parameters
    ----------

    Returns
    -------
    k :
        in Darcy
    """
    poro = pg.solver.parseArgToArray(poro, mesh.cellCount(), mesh)
    q = pg.solver.parseArgToArray(q, mesh.cellCount(), mesh)
    s = pg.solver.parseArgToArray(s, mesh.cellCount(), mesh)

    st = q * s
    k = 2e7 * (poro**2 / (1.0-poro)**2) * 1.0/st**2 * \
        pg.physics.Constants.Darcy

    if meshI is not None:
        k = pg.interpolate(mesh, k, meshI.cellCenters())
        k = pg.solver.fillEmptyToCellArray(meshI, k)
    return k
Пример #20
0
print(time.time() - tic, "s")

###############################################################################
# First, we plot the traveltime field and streamlines
fig, ax = plt.subplots(figsize=(10, 5))
drawMesh(ax, mesh)
ax.set_xlabel('x [m]')
ax.set_ylabel('y [m]')
pg.show(mesh, times, cMap='Spectral', fillContour=True, ax=ax)
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, zlay, v[0], v[1])
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()
Пример #21
0
    def computeTravelTimes(self, slowness, calcOthers=False):
        """Compute the travel times and fill data and time matrix
        for later use of response and Jacobian, respectively.
        For response only active sources are needed, for Jacobian all.
        """
        mesh = self.mesh()
        nNodes = mesh.nodeCount()
        midPoints = self.mesh().cellCenters()
        param_markers = np.unique(mesh.cellMarkers())
        param_count = len(param_markers)
        data = self.data()
        if len(slowness) == mesh.cellCount():
            mesh.setCellAttributes(slowness)
            # self.mapModel(slowness)
        elif len(slowness) == param_count:
            # map the regions in the mesh to slowness
            slow_map = pg.stdMapF_F()
            min_reg_num = min(param_markers)
            for i, si in enumerate(slowness):
                slow_map.insert(float(i+min_reg_num), si)

            mesh.mapCellAttributes(slow_map)
        else:
            raise ValueError("Wrong no of parameters. Mesh size: {}, no "
                             "of regions: {}, and number of slowness values:"
                             "{}".format(mesh.cellCount(), param_count,
                                         len(slowness)))

        times = pg.RVector(nNodes, 0.)
        upTags = np.zeros(nNodes)
        downTags = np.zeros(nNodes)
        sourceIndices = np.unique(data("s"))
        if calcOthers:
            ns = len(sourceIndices)
            geophoneIndices = np.setxor1d(np.arange(data.sensorCount()),
                                          sourceIndices)
            sourceIndices = geophoneIndices
#            geophoneIndices = np.unique(data("g"))
            if self.debug:
                print("{:d}-{:d}={:d}".format(
                    data.sensorCount(), ns, len(sourceIndices)))
#        if self.debug:  # resize not working
#            self.solution().resize(self.mesh().nodeCount(), self.nSensors)
#            print(self.solution().rows(), self.solution().cols())
        for iSource in np.array(sourceIndices, dtype=int):
            if self.debug:
                print(iSource)
            # initial condition (reset vectors)
            times *= 0.0
            upTags *= 0
            downTags *= 0
            downwind = set()
            source = data.sensorPosition(int(iSource))
            cell = mesh.findCell(source)
            # fill in nodes around source using local smoothness
            for i, n in enumerate(cell.nodes()):
                times[n.id()] = cell.attribute() * n.pos().distance(source)
                upTags[n.id()] = 1
            for i, n in enumerate(cell.nodes()):
                tmpNodes = pg.commonNodes(n.cellSet())
                for nn in tmpNodes:
                    if not upTags[nn.id()] and not downTags[nn.id()]:
                        downwind.add(nn)
                        downTags[nn.id()] = 1

            while len(downwind) > 0:  # start fast marching
                fastMarch(mesh, downwind, times, upTags, downTags)

            self.dataMatrix[iSource] = pg.interpolate(
                mesh, times, destPos=data.sensorPositions())
            self.timeMatrix[iSource] = pg.interpolate(
                mesh, times, destPos=midPoints)

            if self.debug:
                print(self.solution().rows(), self.solution().cols())
                print(len(times), self.mesh())
                self.solution()[int(iSource)] = times
                self.solution().setCol(int(iSource), times)
Пример #22
0
    def response(self, model):
        """Solve forward task.

        Create apparent resistivity values for a given resistivity distribution
        for self.mesh.
        """
        mesh = self.mesh()

        nDof = mesh.nodeCount()
        nEle = len(self.electrodes)
        nData = self.data.size()

        self.resistivity = res = self.createMappedModel(model, -1.0)

        if self.verbose():
            print("Calculate response for model:", min(res), max(res))

        rMin = self.electrodes[0].dist(self.electrodes[1]) / 2.0
        rMax = self.electrodes[0].dist(self.electrodes[-1]) * 2.0

        k, w = self.getIntegrationWeights(rMin, rMax)

        self.k = k
        self.w = w

        rhs = self.createRHS(mesh, self.electrodes)

        # store all potential fields
        u = np.zeros((nEle, nDof))
        self.subPotentials = [pg.RMatrix(nEle, nDof) for i in range(len(k))]
        for i, ki in enumerate(k):
            uE = pg.solve(mesh,
                          a=1. / res,
                          b=(ki * ki) / res,
                          f=rhs,
                          bc={'Robin': self.mixedBC},
                          userData={
                              'sourcePos': self.electrodes,
                              'k': ki
                          },
                          verbose=False,
                          stat=0,
                          debug=False,
                          ret=self.subPotentials[i])
            u += w[i] * uE
        # collect potential matrix,
        # i.e., potential for all electrodes and all injections
        pM = np.zeros((nEle, nEle))

        for i in range(nEle):
            pM[i] = pg.interpolate(mesh, u[i, :], destPos=self.electrodes)

        # collect resistivity values for all 4 pole measurements
        r = np.zeros(nData)

        for i in range(nData):
            iA = int(self.data('a')[i])
            iB = int(self.data('b')[i])
            iM = int(self.data('m')[i])
            iN = int(self.data('n')[i])

            uAB = pM[iA] - pM[iB]
            r[i] = uAB[iM] - uAB[iN]

        self.lastResponse = r * self.data('k')

        if self.verbose():
            print("Resp: ", min(self.lastResponse), max(self.lastResponse))

        return self.lastResponse
def linear_interpolation(inmesh, indata, outmesh):
    """ Linear interpolation using `pg.interpolate()` """
    outdata = pg.RVector()  # empty
    pg.interpolate(srcMesh=inmesh, inVec=indata,
                   destPos=outmesh.cellCenters(), outVec=outdata)
    return outdata
vB = np.array(list(map(lambda p_: [ (2.*p_[1] *(1.0 -p_[0]**2)),
                                   (-2.*p_[0] *(1.0 -p_[1]**2))],
                       mesh.boundaryCenters())))
drawStreams(ax2, mesh, vC)

f = pg.RVector(mesh.cellCount(), 0.0)
##f[mesh.findCell([-0.75, 0.75]).id()]=1000.0


uMesh = solveFiniteVolume(mesh, a=1./Peclet, f=f, vel=vB, 
                          uBoundary=dirichletBC,
                          duBoundary=neumannBC,
                          scheme=scheme)
show(mesh, data=uMesh, 
     logScale=False, interpolate=1, tri=1,
     colorBar=True, axes=ax2)

xi = np.linspace(0.2, 0.8, 81)
uG = pg.interpolate(grid, uGrid, x=x)
uM = pg.interpolate(mesh, uMesh, x=x)
plt.figure()
plt.plot(x, uG, label='outlet ' + scheme + '(grid)')
plt.plot(x, uM, label='outlet ' + scheme + '(mesh)')
#plt.plot(x, 1. + np.tanh(10 * (2 * x + 1.)) )
plt.plot(-x, 1. + np.tanh(10 * (2 * x + 1.)), label='inlet-exact')
plt.legend()
plt.xlim([0,1])


pg.showNow()
Пример #25
0
    def computeTravelTimes(self, slowness, calcOthers=False):
        """Compute the travel times and fill data and time matrix
        for later use of response and Jacobian, respectively.
        For response only active sources are needed, for Jacobian all.
        """
        mesh = self.mesh()
        nNodes = mesh.nodeCount()
        midPoints = self.mesh().cellCenters()
        param_markers = np.unique(mesh.cellMarkers())
        param_count = len(param_markers)
        data = self.data()
        if len(slowness) == mesh.cellCount():
            mesh.setCellAttributes(slowness)
            # self.mapModel(slowness)
        elif len(slowness) == param_count:
            # map the regions in the mesh to slowness
            slow_map = pg.stdMapF_F()
            min_reg_num = min(param_markers)
            for i, si in enumerate(slowness):
                slow_map.insert(float(i + min_reg_num), si)

            mesh.mapCellAttributes(slow_map)
        else:
            raise ValueError("Wrong no of parameters. Mesh size: {}, no "
                             "of regions: {}, and number of slowness values:"
                             "{}".format(mesh.cellCount(), param_count,
                                         len(slowness)))

        times = pg.RVector(nNodes, 0.)
        upTags = np.zeros(nNodes)
        downTags = np.zeros(nNodes)
        sourceIndices = np.unique(data("s"))
        if calcOthers:
            ns = len(sourceIndices)
            geophoneIndices = np.setxor1d(np.arange(data.sensorCount()),
                                          sourceIndices)
            sourceIndices = geophoneIndices
            #            geophoneIndices = np.unique(data("g"))
            if self.debug:
                print("{:d}-{:d}={:d}".format(data.sensorCount(), ns,
                                              len(sourceIndices)))


#        if self.debug:  # resize not working
#            self.solution().resize(self.mesh().nodeCount(), self.nSensors)
#            print(self.solution().rows(), self.solution().cols())
        for iSource in np.array(sourceIndices, dtype=int):
            if self.debug:
                print(iSource)
            # initial condition (reset vectors)
            times *= 0.0
            upTags *= 0
            downTags *= 0
            downwind = set()
            source = data.sensorPosition(int(iSource))
            cell = mesh.findCell(source)
            # fill in nodes around source using local smoothness
            for i, n in enumerate(cell.nodes()):
                times[n.id()] = cell.attribute() * n.pos().distance(source)
                upTags[n.id()] = 1
            for i, n in enumerate(cell.nodes()):
                tmpNodes = pg.commonNodes(n.cellSet())
                for nn in tmpNodes:
                    if not upTags[nn.id()] and not downTags[nn.id()]:
                        downwind.add(nn)
                        downTags[nn.id()] = 1

            while len(downwind) > 0:  # start fast marching
                fastMarch(mesh, downwind, times, upTags, downTags)

            self.dataMatrix[iSource] = pg.interpolate(
                mesh, times, destPos=data.sensorPositions())
            self.timeMatrix[iSource] = pg.interpolate(mesh,
                                                      times,
                                                      destPos=midPoints)

            if self.debug:
                print(self.solution().rows(), self.solution().cols())
                print(len(times), self.mesh())
                self.solution()[int(iSource)] = times
                self.solution().setCol(int(iSource), times)
Пример #26
0
            (np.sinh(kp * (1. + y)/2) + np.sinh(kp * (1. - y)/2))
        ret += s
    return (1. - x**2) / 2 - 16. / (np.pi**3) * ret


###############################################################################
# To compare the different results the in detail we interpolate our solution
# along a probe line through the domain.
#

x = np.linspace(-1.0, 1.0, 100)

probe = np.zeros((len(x), 3))
probe[:, 0] = x

uH1 = pg.interpolate(srcMesh=grid, inVec=u, destPos=probe)
uH2 = pg.interpolate(srcMesh=gridh2, inVec=uh, destPos=probe)
uP2 = pg.interpolate(srcMesh=gridp2, inVec=up, destPos=probe)

plt.figure()
plt.plot(x,
         np.array(list(map(uAna, probe))),
         'black',
         linewidth=2,
         label='analytical')
plt.plot(x, uH1, label='linear (H1)')
plt.plot(x, uH2, label='linear (H2)')
plt.plot(x, uP2, label='quadratic (P2)')

plt.xlim([-0.4, 0.4])
plt.ylim([0.25, 0.3])
Пример #27
0
    def response(self, model):
        """Solve forward task.

        Create apparent resistivity values for a given resistivity distribution
        for self.mesh.
        """
        mesh = self.mesh()

        nDof = mesh.nodeCount()
        nEle = len(self.electrodes)
        nData = self.data.size()
 
        self.resistivity = res = self.createMappedModel(model, -1.0)

        if self.verbose():
            print("Calculate response for model:", min(res), max(res))

        rMin = self.electrodes[0].dist(self.electrodes[1]) / 2.0
        rMax = self.electrodes[0].dist(self.electrodes[-1]) * 2.0

        k, w = self.getIntegrationWeights(rMin, rMax)

        self.k = k
        self.w = w

        rhs = self.createRHS(mesh, self.electrodes)

        # store all potential fields
        u = np.zeros((nEle, nDof))
        self.subPotentials = [pg.RMatrix(nEle, nDof) for i in range(len(k))]

        for i, ki in enumerate(k):
            ws = {'u': self.subPotentials[i]}

            uE = pg.solve(mesh, a=1./res, b=-(ki * ki)/res, f=rhs,
                          bc={'Robin': self.mixedBC},
                          userData={'sourcePos': self.electrodes, 'k': ki},
                          verbose=self.verbose(), stats=0, debug=False,
                          ws=ws,
                          )
            u += w[i] * uE

        # collect potential matrix,
        # i.e., potential for all electrodes and all injections
        pM = np.zeros((nEle, nEle))

        for i in range(nEle):
            pM[i] = pg.interpolate(mesh, u[i, :], destPos=self.electrodes)
        # collect resistivity values for all 4 pole measurements
        r = np.zeros(nData)

        for i in range(nData):
            iA = int(self.data('a')[i])
            iB = int(self.data('b')[i])
            iM = int(self.data('m')[i])
            iN = int(self.data('n')[i])

            uAB = pM[iA] - pM[iB]
            r[i] = uAB[iM] - uAB[iN]

        self.lastResponse = r * self.data('k')

        if self.verbose():
            print("Resp: ", min(self.lastResponse), max(self.lastResponse))

        return self.lastResponse
ert = ERTManager()

# Create suitable mesh for ert forward calculation
# NOTE: In the published results paraMaxCellSize=1.0 was used, which is
# increased here to allow testing on Continuous Integration services.
meshERTFWD = mt.createParaMesh(ertScheme,
                               quality=33.5,
                               paraMaxCellSize=2.0,
                               paraDX=0.2,
                               boundaryMaxCellSize=50,
                               smooth=[1, 10],
                               paraBoundary=30)
pg.show(meshERTFWD)

res = pg.RVector()
pg.interpolate(mesh, rhotrue, meshERTFWD.cellCenters(), res)
res = mt.fillEmptyToCellArray(meshERTFWD, res, slope=True)
ert.setMesh(meshERTFWD)
ert.fop.createRefinedForwardMesh()
ertData = ert.simulate(meshERTFWD,
                       res,
                       ertScheme,
                       noiseLevel=0.05,
                       noiseAbs=0.0)
ertData.save("erttrue.dat")
ert.setData(ertData)
ert.setMesh(meshERTFWD)
ert.inv.setData(ertData("rhoa"))

pg.boxprint("Simulate traveltimes")
meshRSTFWD = pg.Mesh()
Пример #29
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
Пример #30
0
def RUN_ERT(concentration, porosity, dc_dp, sim_time):
    ''' Computes resisitivity (rhoa) and the derivative of the resisitivity to the
        calibrated parameters (drhoa_dp)
        drhoa_dp = drhoa_dc * dc_dp'''

    start_total = time.time()

    cell_conc = pg.meshtools.nodeDataToCellData(meshTD, concentration)

    #FROM SALT MASS FRACTION TO SALT CONCENTRATION TO WATER CONDUCTIVITY
    csw = 5.5  #[S/m]
    cfw = 0.005  #[mS/m]
    #Normalized salt_mass fraction for conversion to water EC.
    salt_mass = cell_conc / max(cell_conc)
    conductivity = (salt_mass * csw) + (1 - salt_mass) * cfw

    #PETROPHYSICS: FROM WATER CONDUCTIVITY TO BULK RESISTIVITY
    m = 1.3
    resistivity_bulk = 1. / conductivity * porosity**(-m)
    rhob = pg.core.RVector(meshERT.cellCount())
    pg.interpolate(meshTD, resistivity_bulk, meshERT.cellCenters(), rhob)
    rhob = pg.meshtools.fillEmptyToCellArray(meshERT, rhob)

    #SIMULATION OF ERT ACQUISITION USING BULK RESISTIVITY MODEL
    print('Acquisition...')
    start_acq = time.time()
    smFileName = findERTscheme(sim_time)
    sm = pb.DataContainerERT(smFileName)
    fERT = pb.DCSRMultiElectrodeModelling(meshERT, sm)
    RM = fERT.regionManager()
    RM.region(1).setBackground(True)
    rhoa = fERT.response(rhob)
    end_acq = time.time()
    print("Time to create acquisition: " + str(end_acq - start_acq) +
          " seconds")

    start_createJ = time.time()
    fERT.createJacobian(rhob)
    end_createJ = time.time()
    print("Time to create the jacobian: " + str(end_createJ - start_createJ) +
          " seconds")

    start_convertJ = time.time()
    jacobian = gmat2numpy(fERT.jacobian())
    end_convertJ = time.time()
    print("Time to convert jacobian to numpy array " +
          str(end_convertJ - start_convertJ) + " seconds")

    interpMat = interpolant()

    start_interp = time.time()
    outdata = np.apply_along_axis(interpolate_jacobian,
                                  1,
                                  jacobian,
                                  interpolant=interpMat)
    end_interp = time.time()
    print("Time to interpolate jacobian by axes (interpolant as arg): " +
          str(end_interp - start_interp) + "seconds")

    drhoa_drhob = np.array(outdata)
    drhoa_drhob = drhoa_drhob.reshape(sm.size(), meshTD.nodeCount())

    #ANALYTICAL COMPUTATION TO ACCOUNT FOR PETROPHYSICAL TRANSFORMATION.
    node_por = pg.meshtools.cellDataToNodeData(meshTD, np.array(porosity))
    for i in range(sm.size()):
        drhoa_drhob[
            i, :] = drhoa_drhob[i, :] * (1 / (np.power(node_por, -(1) * m)))

    for i in range(sm.size()):
        drhoa_drhob[i, :] = drhoa_drhob[i, :] * (csw - cfw)

    drhoa_dp = drhoa_drhob.dot(dc_dp)

    end_total = time.time()
    print("Total simulation time: " + str((end_total - start_total) / 60) +
          ' minutes')

    return np.array(rhoa), drhoa_dp
Пример #31
0
def drawMeshPotential(ax, mesh, u, x=[-10.0, 50.0], z=[-50.0, 0.0],
                      dx=1, nLevs=20, title=None,
                      verbose=False, maskZero=False):
    """
    Give drawField a try ..

    should be better. Draw the potential that is associated to a mesh
    """
    raise ('do not use')
    swatch = pg.Stopwatch(True)
    if (verbose):
        print(("start interpolation:", swatch.duration(True)))

    xg = createLinLevs(x[0], x[1], int((x[1] - x[0]) / dx))
    yg = createLinLevs(z[0], z[1], int((z[1] - z[0]) / dx))
    X,Y = np.meshgrid(xg, yg)

    uI = pg.interpolate(mesh, u
                    , pg.asvector(list(X.flat))
                    , pg.RVector(len(Y.flat), 0.0)
                    , pg.asvector(list(Y.flat)), verbose)

    if (verbose):
        print(("interpolation:", swatch.duration(True)))

    zi = np.asarray(uI)
    if maskZero:
        zi = np.ma.masked_where(zi <= 0.0, zi)
    Z = zi.reshape(X.shape)

    maxZ = max(min(zi), max(zi))
    epsZ = min(abs(zi))

    if min(zi) < 0:
        potLevs = np.linspace(-maxZ, -epsZ, nLevs/2.)
        print(potLevs)
        potLevs = np.hstack((potLevs, potLevs[::-1] * -1.))
    else:
        potLevs = np.linspace(0, maxZ, nLevs)

    #print(potLevs)
    linestyles = ['solid'] * len(potLevs)

    gci = ax.contourf(X, Y, Z, potLevs)
    ax.contour(X, Y, Z, potLevs, colors='white', linewidths=0.3,
               linestyles=linestyles)
    ax.set_aspect('equal')

    ax.set_xlim(x)
    ax.set_ylim(z)

    ax.set_ylabel('Depth [m]')
    ax.set_xlabel('$x$ [m]')

    if title is not None:
        ax.set_title(title)

    if (verbose):
        print(("time:", swatch.duration(True)))

    print("fixing 'Depth' to be positive values")
    ticks = ax.yaxis.get_majorticklocs()
    tickLabels=[]

    for t in ticks:
        tickLabels.append(str(int(abs(t))))
        ax.set_yticklabels(tickLabels)

    return gci
Пример #32
0
            (np.sinh(kp * (1. + y)/2) + np.sinh(kp * (1. - y)/2))
        ret += s
    return (1. - x**2)/2 - 16./(np.pi**3) * ret


###############################################################################
# To compare the different results the in detail we interpolate our solution
# along a probe line through the domain.
#

x = np.linspace(-1.0, 1.0, 100)

probe = np.zeros((len(x), 3))
probe[:, 0] = x

uH1 = pg.interpolate(srcMesh=grid, inVec=u, destPos=probe)
uH2 = pg.interpolate(srcMesh=gridh2, inVec=uh, destPos=probe)
uP2 = pg.interpolate(srcMesh=gridp2, inVec=up, destPos=probe)

plt.figure()
plt.plot(x, np.array(list(map(uAna, probe))), 'black', linewidth=2,
         label='analytical')
plt.plot(x, uH1, label='linear (H1)')
plt.plot(x, uH2, label='linear (H2)')
plt.plot(x, uP2, label='quadratic (P2)')

plt.xlim([-0.4, 0.4])
plt.ylim([0.25, 0.3])
plt.legend()

plt.show()
Пример #33
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)
Пример #34
0
def resistivityArchie(rFluid,
                      porosity,
                      a=1.0,
                      m=2.0,
                      sat=1.0,
                      n=2.0,
                      mesh=None,
                      meshI=None,
                      fill=None,
                      show=False):
    r"""Resistivity of rock for the petrophysical model from Archies law.

    Calculates resistivity of rock for the petrophysical model from
    Archie's law. :cite:`Archie1942`

    .. math::
        \rho = a\rho_{\text{fl}}\phi^{-m} S^{-n}

    * :math:`\rho` - the electrical resistivity of the fluid saturated rock in
      :math:`\Omega\text{m}`
    * :math:`\rho_{\text{fl}}` - rFluid: electrical resistivity of the fluid in
      :math:`\Omega\text{m}`
    * :math:`\phi` - porosity 0.0 --1.0
    * :math:`S` - fluid saturation 0.0 --1.0 [sat]
    * :math:`a` - Tortuosity factor. (common 1)
    * :math:`m` - Cementation exponent of the rock (usually in the
      range 1.3 -- 2.5 for sandstones)
    * :math:`n` - is the saturation exponent (usually close to 2)

    If mesh is not None the resulting values are calculated for each cell of
    the mesh.
    All parameter can be scalar, array of length mesh.cellCount()
    or callable(pg.cell). If rFluid is non-steady n-step distribution
    than rFluid can be a matrix of size(n, mesh.cellCount())
    If meshI is not None the result is interpolated to meshI.cellCenters()
    and prolonged (if fill ==1).

    Notes
    -----
        We experience some unstable nonlinear behavior.
        Until this is clarified all results are rounded to the precision 1e-6.

    Examples
    --------
    >>> #

    WRITEME
    """
    phi = porosity
    if isinstance(porosity, list):
        phi = np.array(porosity)

    if mesh is None:
        return rFluid * a * phi**(-m) * sat**(-n)

    rB = None

    if isinstance(rFluid, float):
        rB = pg.RMatrix(1, mesh.cellCount())
        rB[0] = pg.solver.parseArgToArray(rFluid, mesh.cellCount(), mesh)

    elif isinstance(rFluid, pg.RVector):
        rB = pg.RMatrix(1, len(rFluid))
        rB[0] = pg.solver.parseArgToArray(rFluid, mesh.cellCount(), mesh)

    elif hasattr(rFluid, 'ndim') and rFluid.ndim == 1:
        rB = pg.RMatrix(1, len(rFluid))
        rB[0] = pg.solver.parseArgToArray(rFluid, mesh.cellCount(), mesh)

    elif hasattr(rFluid, 'ndim') and rFluid.ndim == 2:
        rB = pg.RMatrix(len(rFluid), len(rFluid[0]))
        for i, rFi in enumerate(rFluid):
            rB[i] = rFi

    phi = pg.solver.parseArgToArray(phi, mesh.cellCount(), mesh)
    a = pg.solver.parseArgToArray(a, mesh.cellCount(), mesh)
    m = pg.solver.parseArgToArray(m, mesh.cellCount(), mesh)
    S = pg.solver.parseArgToArray(sat, mesh.cellCount(), mesh)
    n = pg.solver.parseArgToArray(n, mesh.cellCount(), mesh)

    if show:
        pg.show(mesh, S, label='S')
        pg.show(mesh, phi, label='p')
        pg.wait()

    r = pg.RMatrix(len(rB), len(rB[0]))
    for i, _ in enumerate(r):
        r[i] = rB[i] * a * phi**(-m) * S**(-n)

    r.round(1e-6)

    if meshI is None:
        if len(r) == 1:
            return r[0].copy()
        return r

    rI = pg.RMatrix(len(r), meshI.cellCount())
    if meshI:
        pg.interpolate(mesh, r, meshI.cellCenters(), rI)

    if fill:
        for i, ri_ in enumerate(rI):
            # slope == True produce unstable behavior .. check!!!!!!
            rI[i] = mt.fillEmptyToCellArray(meshI, ri_, slope=False)

    rI.round(1e-6)

    if len(rI) == 1:
        # copy here because of missing refcounter TODO
        return rI[0].array()
    return rI
Пример #35
0
print(time.time() - tic, "s")

###############################################################################
# First, we plot the traveltime field and streamlines
fig, ax = plt.subplots(figsize=(10, 5))
drawMesh(ax, mesh)
ax.set_xlabel('x [m]')
ax.set_ylabel('y [m]')
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.
Пример #36
0
def calcSeismics(meshIn, vP):
    """Do seismic computations."""
    meshSeis = meshIn.createH2()
    meshSeis = mt.appendTriangleBoundary(meshSeis,
                                         xbound=25,
                                         ybound=22.0,
                                         marker=1,
                                         quality=32.0,
                                         area=0.3,
                                         smooth=True,
                                         markerBoundary=1,
                                         isSubSurface=False,
                                         verbose=False)
    print(meshSeis)
    meshSeis = meshSeis.createH2()
    meshSeis = meshSeis.createH2()
    # meshSeis = meshSeis.createP2()

    meshSeis.smooth(1, 1, 1, 4)
    vP = pg.interpolate(meshIn, vP, meshSeis.cellCenters())

    mesh = meshSeis
    vP = pg.solver.fillEmptyToCellArray(mesh, vP)

    print(mesh)
    # ax, cbar = pg.show(mesh, data=vP)
    # pg.show(mesh, axes=ax)

    geophPointsX = np.arange(-19, 19.1, 1)
    geophPoints = np.vstack((geophPointsX, np.zeros(len(geophPointsX)))).T
    sourcePos = geophPoints[4]

    c = mesh.findCell(sourcePos)
    h1 = pg.findBoundary(c.boundaryNodes(0)).size()
    h2 = pg.findBoundary(c.boundaryNodes(1)).size()
    h3 = pg.findBoundary(c.boundaryNodes(2)).size()
    print([h1, h2, h3])
    h = pg.math.median([h1, h2, h3])

    # h = pg.math.median(mesh.boundarySizes())
    f0scale = 0.25
    cfl = 0.5
    dt = cfl * h / max(vP)
    print("Courant-Friedrich-Lewy number:", cfl)

    tmax = 40. / min(vP)
    times = np.arange(0.0, tmax, dt)

    solutionName = createCacheName('seis', mesh, times) + "cfl-" + str(cfl)
    try:
        # u = pg.load(solutionName + '.bmat')
        uI = pg.load(solutionName + 'I.bmat')
    except Exception as e:
        print(e)
        f0 = f0scale * 1. / dt
        print("h:", round(h, 2), "dt:", round(dt, 5), "1/dt:",
              round(1 / dt, 1), "f0", round(f0, 2), "Wavelength: ",
              round(max(vP) / f0, 2), " m")

        uSource = ricker(times, f0, t0=1. / f0)

        plt.figure()
        plt.plot(times, uSource, '-*')
        plt.show(block=0)
        plt.pause(0.01)
        u = solvePressureWave(mesh,
                              vP,
                              times,
                              sourcePos=sourcePos,
                              uSource=uSource,
                              verbose=10)

        u.save(solutionName)
        uI = pg.Matrix()
        print("interpolate node to cell data ... ")
        pg.interpolate(mesh, u, mesh.cellCenters(), uI)
        print("... done")
        uI.save(solutionName + 'I')

#    nodes = [mesh.findNearestNode(p) for p in geophPoints]
#    fig = plt.figure()
#    axs = fig.add_subplot(1,1,1)
#    drawSeismogramm(axs, mesh, u, nodes, dt, i=None)
#    plt.show()

    dpi = 92
    scale = 1
    fig = plt.figure(facecolor='white',
                     figsize=(scale * 800 / dpi, scale * 490 / dpi),
                     dpi=dpi)
    ax = fig.add_subplot(1, 1, 1)
    gci = pg.viewer.mpl.drawModel(ax,
                                  mesh,
                                  data=uI[0],
                                  cMin=-1,
                                  cMax=1,
                                  cmap='bwr')
    pg.viewer.mpl.drawMeshBoundaries(ax, meshIn, hideMesh=1)
    ax.set_xlim((-20, 20))
    ax.set_ylim((-15, 0))
    ax.set_ylabel('Depth [m]')
    ax.set_xlabel('$x$ [m]')

    ticks = ax.yaxis.get_majorticklocs()
    tickLabels = []
    for t in ticks:
        tickLabels.append(str(int(abs(t))))

    ax.set_yticklabels(tickLabels)

    plt.tight_layout()

    #    ax, cbar = pg.show(mesh, data=vP)
    #    pg.showNow()
    #    ax = fig.add_subplot(1,1,1)

    def animate(i):
        i = i * 5
        if i > len(uI) - 1:
            return
        print("Frame:", i, "/", len(uI))
        ui = uI[i]
        ui = ui / max(pg.abs(ui))
        ui = pg.logDropTol(ui, 1e-2)
        cMax = max(pg.abs(ui))

        pg.viewer.mpl.setMappableData(gci,
                                      ui,
                                      cMin=-cMax,
                                      cMax=cMax,
                                      logScale=False)
        # plt.pause(0.001)

    anim = animation.FuncAnimation(fig,
                                   animate,
                                   frames=int(len(uI) / 5),
                                   interval=0.001,
                                   repeat=0)  # , blit=True)
    out = 'seis' + str(f0scale) + "cfl-" + str(cfl)
    anim.save(out + ".mp4",
              writer=None,
              fps=20,
              dpi=dpi,
              codec=None,
              bitrate=24 * 1024,
              extra_args=None,
              metadata=None,
              extra_anim=None,
              savefig_kwargs=None)
    try:
        print("create frames ... ")
        os.system('mkdir -p anim-' + out)
        os.system('ffmpeg -i ' + out + '.mp4 anim-' + out + '/movie%d.jpg')
    except:
        pass
Пример #37
0
#     Obs_IP, dataABMN=  FU.PrepareMALMData('./raw_data/' + inputfileMALM, Rec=False, DevErr=1,
#                                MinV=1, MaxRc=1, Kfact=1, MinMaxAppRes=1,
#                                SwE=False, gIP=gateIP,
#                                valid=None) # remove reciprocal from original dataset
#     coordE_f = []
#     for i, mi in enumerate(Obs['m']):
#         if mi==Nfix:
#            mi=Obs['n'][i]
#         id_coordE_f = np.where(mi+1==coordE[:,0])[0]
#         coordE_f.append(coordE[id_coordE_f[0],:])
#     coordE_f = np.array(coordE_f)

#%% foward modelling of homogeneous medium
# interpolate to MALM fwd mesh
if invERT:
    rho_fwd = pg.interpolate(mesh3d_fwd, mesh3d_inv, model, method='spline')
    rhomap = rho_fwd.array()
    id0 = np.where(rho_fwd.array() <= 0)
    rhomap[id0] = 0.1
else:
    model = waterRes
    rhomap = [[1, waterRes], [2, waterRes]]

#%% foward modelling of Green's functions
# mk_full_malm --> 3rd file = simulated green functions (simulated data to compare with observation data)
# SeqFullMALM= MR.mk_full_malm(dataABMN-1,
#                              VRTe = range(len(sensors),
#                                           len(sensors)+len(VRTEpos)),
#                              mesh=mesh3d_fwd,
#                              R3=False) # output .shm with sensors
Пример #38
0
                  uBoundary=[gridp2.findBoundaryByMarker(1,5), 0.0],
                  verbose=True)

"""
.. image:: PLOT2RST.current_figure
    :scale: 50

To analyse the solution in detail we use a numpy Nx2 matrix containing the x and y values, and the interpolation function.
"""

x = np.linspace(-1.0, 1.0, 100)

probe = np.zeros((len(x), 3))
probe[:, 0] = x

uH1 = pg.interpolate(mesh=grid, data=u, pos=probe)
uH2 = pg.interpolate(mesh=gridh2, data=uh, pos=probe)
uP2 = pg.interpolate(mesh=gridp2, data=up, pos=probe)

plt.figure()
plt.plot(x, uH1, label='linear (H1)')
plt.plot(x, uH2, label='linear (H2)')
plt.plot(x, uP2, label='quadratic (P2)')

plt.legend()


"""
.. image:: PLOT2RST.current_figure
    :scale: 50
Пример #39
0
    def test_Interpolate(self):
        grid = pg.createGrid(x=[0.0, 1.0], y=[0.0, 1.0])
        u = pg.RVector(grid.nodeCount(), 1.)

        # test with pg.interpolate
        queryPos = [0.2, 0.2]
        uI = pg.interpolate(srcMesh=grid,
                            inVec=u,
                            destPos=[queryPos, queryPos])

        np.testing.assert_allclose(uI[0], 1.)

        # test manual interpolation
        c = grid.findCell(queryPos)
        uI = c.pot(queryPos, u)
        np.testing.assert_allclose(uI, 1.)

        # test with manual interpolationMatrix generation
        I = pg.RSparseMapMatrix(1, grid.nodeCount())
        cI = c.N(c.shape().rst(queryPos))
        for i in range(c.nodeCount()):
            I.addVal(0, c.node(i).id(), cI[i])

        uI = I.mult(u)
        np.testing.assert_allclose(uI[0], 1)

        # test with automatic interpolationMatrix generation
        I = grid.interpolationMatrix([[0.0, 0.0], [1.0, 0.0], [1.0, 1.0],
                                      [0.0, 1.0]])
        uI = I * u
        np.testing.assert_allclose(uI, u)

        # api test https://github.com/gimli-org/gimli/issues/131
        x = np.linspace(grid.xmin(), grid.xmax(), 11)
        np.testing.assert_allclose(
            pg.interpolate(grid, pg.x(grid.positions()), x), x)
        np.testing.assert_allclose(
            pg.interpolate(grid, pg.x(grid.positions()), x=x), x)
        np.testing.assert_allclose(
            pg.interpolate(grid, pg.x(grid.positions()), x, x * 0.), x)
        np.testing.assert_allclose(
            pg.interpolate(grid, pg.x(grid.positions()), x=x, y=x * 0), x)
        np.testing.assert_allclose(
            pg.interpolate(grid, pg.x(grid.positions()), x, x * 0, x * 0), x)
        np.testing.assert_allclose(
            pg.interpolate(grid, pg.x(grid.positions()), x=x, y=x * 0,
                           z=x * 0), x)
        x = pg.Vector(x)
        np.testing.assert_allclose(
            pg.interpolate(grid, pg.x(grid.positions()), x), x)
        np.testing.assert_allclose(
            pg.interpolate(grid, pg.x(grid.positions()), x=x), x)
        np.testing.assert_allclose(
            pg.interpolate(grid, pg.x(grid.positions()), x, x * 0.), x)
        np.testing.assert_allclose(
            pg.interpolate(grid, pg.x(grid.positions()), x=x, y=x * 0), x)
        np.testing.assert_allclose(
            pg.interpolate(grid, pg.x(grid.positions()), x, x * 0, x * 0), x)
        np.testing.assert_allclose(
            pg.interpolate(grid, pg.x(grid.positions()), x=x, y=x * 0,
                           z=x * 0), x)
Пример #40
0
    def response(self, model):
        """Solve forward task.

        Create apparent resistivity values for a given resistivity distribution
        for self.mesh.
        """
        ### NOTE TODO can't be MT until mixed boundary condition depends on
        ### self.resistivity
        pg.tic()
        if not self.data.allNonZero('k'):
            pg.error('Need valid geometric factors: "k".')
            pg.warn('Fallback "k" values to -sign("rhoa")')
            self.data.set('k', -pg.math.sign(self.data('rhoa')))

        mesh = self.mesh()

        nDof = mesh.nodeCount()
        elecs = self.data.sensorPositions()

        nEle = len(elecs)
        nData = self.data.size()

        self.resistivity = res = self.createMappedModel(model, -1.0)

        if self.verbose:
            print("Calculate response for model:", min(res), max(res))

        rMin = elecs[0].dist(elecs[1]) / 2.0
        rMax = elecs[0].dist(elecs[-1]) * 2.0

        k, w = self.getIntegrationWeights(rMin, rMax)

        self.k = k
        self.w = w

        # pg.show(mesh, res, label='res')
        # pg.wait()

        rhs = self.createRHS(mesh, elecs)

        # store all potential fields
        u = np.zeros((nEle, nDof))
        self.subPotentials = [pg.Matrix(nEle, nDof) for i in range(len(k))]

        for i, ki in enumerate(k):
            ws = dict()
            uE = pg.solve(mesh,
                          a=1. / res,
                          b=-(ki * ki) / res,
                          f=rhs,
                          bc={'Robin': ['*', self.mixedBC]},
                          userData={
                              'sourcePos': elecs,
                              'k': ki
                          },
                          verbose=False,
                          stats=0,
                          debug=False)
            self.subPotentials[i] = uE
            u += w[i] * uE

        # collect potential matrix,
        # i.e., potential for all electrodes and all injections
        pM = np.zeros((nEle, nEle))

        for i in range(nEle):
            pM[i] = pg.interpolate(mesh, u[i, :], destPos=elecs)

        # collect resistivity values for all 4 pole measurements
        r = np.zeros(nData)

        for i in range(nData):
            iA = int(self.data('a')[i])
            iB = int(self.data('b')[i])
            iM = int(self.data('m')[i])
            iN = int(self.data('n')[i])

            uAB = pM[iA] - pM[iB]
            r[i] = uAB[iM] - uAB[iN]

        self.lastResponse = r * self.data('k')

        if self.verbose:
            print("Resp min/max: {0} {1} {2}s".format(min(self.lastResponse),
                                                      max(self.lastResponse),
                                                      pg.dur()))

        return self.lastResponse
#dgz, dggz = solveGravimetry(mesh, dDensity=density,
                            #pnts=pnts, complete=1)

#print(min(dgz), max(dgz))

duz = np.zeros(len(pnts))
dux = np.zeros(len(pnts))
for i,p in enumerate(pnts):
    c = mesh.findCell(p)
    g = c.grad(p, u)
    print(c, p, g)
    dux[i] =  g[0] * 4.0 * np.pi # wo kommen die 4 pi her?
    duz[i] = -g[1] * 4.0 * np.pi # wo kommen die 4 pi her?

uI = pg.interpolate(mesh, u, pnts)

plt.plot(pg.x(pnts), dux, label='dux')
plt.plot(pg.x(pnts), duz, label='duz')
plt.plot(pg.x(pnts), pg.sqrt(dux*dux + duz*duz), label='du')

dgz, dggz = solveGravimetry(circ, dDensity=1000,
                            pnts=pnts, complete=1)

    
plt.plot(pg.x(pnts), dgz[:,0], label='dgx')
plt.plot(pg.x(pnts), dgz[:,2], label='dgz')
plt.plot(pg.x(pnts), np.sqrt(dgz[:,0]**2 + dgz[:,1]**2 + dgz[:,2]**2), label='dg')


print(dux/dgz[:,0])
                       mesh.cellCenters())))

vB = np.array(list(map(lambda p_: [ (2.*p_[1] *(1.0 -p_[0]**2)),
                                   (-2.*p_[0] *(1.0 -p_[1]**2))],
                       mesh.boundaryCenters())))
drawStreams(ax2, mesh, vC)

f = pg.RVector(mesh.cellCount(), 0.0)
##f[mesh.findCell([-0.75, 0.75]).id()]=1000.0


uMesh = solveFiniteVolume(mesh, a=1./Peclet, f=f, vel=vB, 
                          uBoundary=dirichletBC,
                          duBoundary=neumannBC,
                          scheme=scheme)
show(mesh, data=uMesh, 
     logScale=False, interpolate=1, tri=1,
     colorBar=True, axes=ax2)

xi = np.linspace(0.2, 0.8, 81)
uG = pg.interpolate(grid, uGrid, x=x)
uM = pg.interpolate(mesh, uMesh, x=x)
plt.figure()
plt.plot(x, uG, label='outlet ' + scheme + '(grid)')
plt.plot(x, uM, label='outlet ' + scheme + '(mesh)')
#plt.plot(x, 1. + np.tanh(10 * (2 * x + 1.)) )
plt.plot(-x, 1. + np.tanh(10 * (2 * x + 1.)), label='inlet-exact')
plt.legend()
plt.xlim([0,1])

pg.wait()
Пример #43
0
def appendBoundaryGrid(grid,
                       xbound=None,
                       ybound=None,
                       zbound=None,
                       marker=1,
                       isSubSurface=True,
                       **kwargs):
    """ Return a copy of grid surrounded by boundary grid.

    Note that the input grid needs to be a 2d or 3d grid with quad/hex cells.

    TODO
    ----
        * preserve inner boundaries
        * add subsurface setting

    Args
    ----
    grid: :gimliapi:`GIMLI::Mesh`
        2D or 3D Mesh that must contain structured quads or hex cells
    xbound: iterable of type float [None]
        Needed for 2D or 3D grid prolongation and will be added on the left side in opposit order and on the right side in normal order.
    ybound: iterable of type float [None]
        Needed for 2D or 3D grid prolongation and will be added (2D bottom, 3D fron) in opposit order and (2D top, 3D back) in normal order.
    zbound: iterable of type float [None]
        Needed for 3D grid prolongation and will be added the bottom side in opposit order on the top side in normal order.
    marker: int [1]
        Cellmarker for the cells in the boundary region
    isSubSurface : boolean, optional
        Apply boundary conditions suitable for geo-simulaion and prolongate
        mesh to the surface if necessary, e.i., no boundary on top of the grid.
    Examples
    --------
    >>> import pygimli as pg
    >>> import pygimli.meshtools as mt
    >>> grid = mt.createGrid(5,5)
    ...
    >>> g1 = mt.appendBoundaryGrid(grid,
    ...                            xbound=[1, 3, 6],
    ...                            ybound=[1, 3, 6],
    ...                            marker=2,
    ...                            isSubSurface=False)
    >>> ax,_ = pg.show(g1, markers=True, showMesh=True)
    >>> grid = mt.createGrid(5,5,5)
    ...
    >>> g2 = mt.appendBoundaryGrid(grid,
    ...                            xbound=[1, 3, 6],
    ...                            ybound=[1, 3, 6],
    ...                            zbound=[1, 3, 6],
    ...                            marker=2,
    ...                            isSubSurface=False)
    >>> ax, _ = pg.show(g2, g2.cellMarkers(), hold=True, opacity=0.5);
    """
    if isSubSurface:
        pg.critical('Implement me')

    def _concat(v, vBound):
        if (not pg.isArray(vBound)):
            pg.critical("please give bound array")

        v = np.append(-np.array(vBound)[::-1] + v[0], v)
        v = np.append(v, v[-1] + np.array(vBound))
        return v

    x = None
    y = None
    z = None

    if grid.dim() > 1:
        if grid.dim() == 2:
            if any([c.nodeCount() != 4 for c in grid.cells()]):
                pg.critical("Grid have other cells than quads. "
                            "Can't refine it with a grid")

        x = pg.utils.unique(pg.x(grid))
        y = pg.utils.unique(pg.y(grid))
        x = _concat(x, xbound)
        y = _concat(y, ybound)

        if grid.dim() == 3:
            if any([c.nodeCount() != 8 for c in grid.cells()]):
                pg.critical("Grid have other cells than hex's. "
                            "Can't refine it with a grid")

            z = pg.utils.unique(pg.z(grid))
            z = _concat(z, zbound)

    mesh = pg.meshtools.createGrid(x=x, y=y, z=z, marker=marker)

    mesh.setCellMarkers(
        pg.interpolate(grid,
                       grid.cellMarkers(),
                       mesh.cellCenters(),
                       fallback=marker))
    return mesh
Пример #44
0
pre = None
vel = None

for i in range(0, len(multigridArea)):
    if i == 0:
        mesh, velBoundary, preBoundary, a, maxIter = modelBuilder(
            multigridArea[0])
        pre = np.zeros(mesh.cellCount())
        vel = np.zeros((mesh.cellCount(), 3))
    else:
        #mesh1 = mesh.createH2()
        mesh1, velBoundary, preBoundary, a, maxIter = modelBuilder(
            multigridArea[i])
        a = pg.RVector(mesh1.cellCount(), 1.0)

        pre = pg.interpolate(mesh, pre, mesh1.cellCenter())
        vx0 = pg.interpolate(mesh, vel[:, 0], mesh1.cellCenter())
        vy0 = pg.interpolate(mesh, vel[:, 1], mesh1.cellCenter())
        vel = np.vstack([vx0, vy0]).T
        mesh = mesh1

    print("Cells: ", mesh.cellCount(), multigridArea[i])
    vel, pre, pCNorm, divVNorm = pg.solver.solveStokes(mesh,
                                                       viscosity=a,
                                                       velBoundary=velBoundary,
                                                       preBoundary=preBoundary,
                                                       pre0=pre,
                                                       vel0=vel,
                                                       maxIter=maxIter,
                                                       tol=1e-2,
                                                       verbose=1)
Пример #45
0
    def streamlines(coordObs, Obs, model, mesh=None, **kwargs):
        """
        Current streamlines; interpolate model from mesh_inv to new mesh to build streamlines
        takes the gradient of the potential and multiply it by the interpolated resistivity model
        -------
        - mesh: mesh to compute the quiver plot
    
        """
        mesh_inv = []  # medium conductivity
        for key, value in kwargs.items():
            if key == 'Xaxis':
                Xaxis = value
            if key == 'mesh_inv':
                mesh_inv = value
            if key == 'date':
                date = value

        xn = 30
        yn = 30

        xx = np.linspace(min(coordObs[:, 0]), max(coordObs[:, 0]), xn)
        yy = np.linspace(min(coordObs[:, 1]), max(coordObs[:, 1]), yn)

        xx, yy = np.meshgrid(xx, yy)
        points = np.transpose(np.vstack((coordObs[:, 0], coordObs[:, 1])))
        print(len(points))
        print(len(Obs))

        if mesh is None:
            mesh = pg.createGrid(x=np.linspace(min(coordObs[:, 0]),
                                               max(coordObs[:, 0]), xn),
                                 y=np.linspace(min(coordObs[:, 1]),
                                               max(coordObs[:, 1]), yn))

        u_interp = interpolate.griddata(points, Obs, (xx, yy), method='cubic')
        uu = np.reshape(u_interp, [xn * yn])
        #uu = pg.interpolate(mesh, (xx, yy), Obs, method='spline')

        if isinstance(model, float):
            stream = -pg.solver.grad(mesh, uu) * (1 / model)
            #jj = -uu*(1/model)
        else:
            res = pg.interpolate(mesh, mesh_inv, model, method='spline')

            # pg.show(mesh, data=res, notebook=True, savefig='model_interpolated.png')

            # plotter, _ = pg.show(mesh_inv, data=model,
            #                      alpha=0.9, hold=True, notebook=True)
            # plotter.view_xy()
            # plotter.show()
            # plotter.screenshot('model3d.png')

            #jj = -uu*(1/res).array()
            stream = -pg.solver.grad(mesh, uu) * (1 / res).array()[:, None]

        if kwargs.get('vmin'):
            vmin = kwargs.get('vmin')
        else:
            vmin = min(Obs)

        if kwargs.get('vmax'):
            vmax = kwargs.get('vmax')
        else:
            vmax = max(Obs)

        if kwargs.get('ax'):
            ax = kwargs.get('ax')
        else:
            fig, ax = plt.subplots()

        sc = ax.scatter(coordObs[:, 0],
                        coordObs[:, 1],
                        c=Obs,
                        cmap='coolwarm',
                        s=5e2,
                        vmin=vmin,
                        vmax=vmax)  # norm=matplotlib.colors.Normalize()
        cbar = plt.colorbar(sc, ax=ax)
        cbar.set_label('V')
        ax.set_ylabel('y [m]', fontsize=15)
        ax.set_xlabel('x [m]', fontsize=15)

        if len(kwargs.get('sensors')) > 0:
            sensors = kwargs.get('sensors')
            ax.scatter(sensors[:, 0],
                       sensors[:, 1],
                       color='k',
                       marker='.',
                       label='pot. elec')
            for i in range(len(sensors[:, 0])):
                ax.annotate(str(i + 1), (sensors[i, 0], sensors[i, 1]))
            if kwargs.get('A'):
                A = kwargs.get('A')
                ax.scatter(sensors[A, 0],
                           sensors[A, 1],
                           color='y',
                           marker='^',
                           label='A. elec',
                           s=5e2)
            if kwargs.get('B'):
                B = kwargs.get('B')
                ax.scatter(sensors[B, 0],
                           sensors[B, 1],
                           color='y',
                           marker='v',
                           label='B. elec',
                           s=5e2)
            if kwargs.get('Nfix'):
                Nfix = kwargs.get('Nfix')
                ax.scatter(sensors[Nfix, 0],
                           sensors[Nfix, 1],
                           color='g',
                           marker='v',
                           label='Nfix. elec')

        if kwargs.get('gridCoarse'):
            gridCoarse = pg.createGrid(x=np.linspace(min(sensors[:, 0]),
                                                     max(sensors[:, 0]),
                                                     xn / 2),
                                       y=np.linspace(min(sensors[:, 1]),
                                                     max(sensors[:, 1]),
                                                     yn / 2))

        drawStreams(ax,
                    mesh,
                    stream,
                    color='green',
                    quiver=True,
                    linewidth=6.0)

        # save for TL analysis

        #j = -pg.solver.grad(mesh, uu) * (1/Res)
        #ax, _ = pg.show(mesh, hold=True, alpha=0.3)
        #drawStreams(ax, mesh, j)

        return mesh, uu, model
Пример #46
0
print(multigridArea)

pre = None
vel = None
    
for i in range(0, len(multigridArea)):
    if i == 0:
        mesh, velBoundary, preBoundary, a, maxIter = modelBuilder(multigridArea[0])
        pre = np.zeros(mesh.cellCount())
        vel = np.zeros((mesh.cellCount(), 3))
    else:
        #mesh1 = mesh.createH2()
        mesh1, velBoundary, preBoundary, a, maxIter = modelBuilder(multigridArea[i])
        a = pg.RVector(mesh1.cellCount(), 1.0)
         
        pre = pg.interpolate(mesh, pre, mesh1.cellCenter())
        vx0 = pg.interpolate(mesh, vel[:,0], mesh1.cellCenter())
        vy0 = pg.interpolate(mesh, vel[:,1], mesh1.cellCenter())
        vel = np.vstack([vx0, vy0]).T
        mesh = mesh1
    
    print("Cells: ", mesh.cellCount(), multigridArea[i])
    vel, pre, pCNorm, divVNorm = pg.solver.solveStokes(mesh, 
                                                       viscosity=a,
                                                       velBoundary=velBoundary, 
                                                       preBoundary=preBoundary,
                                                       pre0=pre,
                                                       vel0=vel,
                                                       maxIter=maxIter,
                                                       tol=1e-2,
                                                       verbose=1)
Пример #47
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
Пример #48
0
        tmpNodes = pg.commonNodes(n.cellSet())
        for nn in tmpNodes:
            if not upTags[nn.id()] and not downTags[nn.id()]:
                downwind.add(nn)
                downTags[nn.id()] = 1

    # start fast marching
    tic = time.time()
    while len(downwind) > 0:
        fastMarch(mesh, downwind, times, upTags, downTags)

    print(time.time() - tic, "s")

    # compare with analytical solution along the x axis
    x = np.arange(0., 100., 0.5)
    t = pg.interpolate(mesh, times, pg.asvector(x), x * 0., x * 0.)
    tdirect = x / v[0]  # direct wave
    alfa = asin(v[0] / v[1])  # critically refracted wave angle
    xreflec = tan(alfa) * zlay * 2.  # first critically refracted
    trefrac = (x - xreflec) / v[1] + xreflec * v[1] / v[0]**2
    tana = np.where(trefrac < tdirect, trefrac, tdirect)  # minimum of both
    print("min(dt)=",
          min(t - tana) * 1000,
          "ms max(dt)=",
          max(t - tana) * 1000,
          "ms")

    # plot traveltime field, a few lines
    fig = plt.figure()
    a = fig.add_subplot(211)
    drawMesh(a, mesh)
Пример #49
0
def resistivityArchie(rFluid, porosity, a=1.0, m=2.0, S=1.0, n=2.0,
                      mesh=None, meshI=None, fill=None):
    r"""
    Return resistivity of rock for the petrophysical model from Archies law.
    
    .. math:: 
        \rho = a\rho_{\text{fl}}\phi^{-m}\S^{-n}
        
    * :math:`\rho` - the electrical resistivity of the fluid saturated rock in :math:`\Omega\text{m}`
    * :math:`\rho_{\text{fl}}` - rFluid: electrical resistivity of the fluid in :math:`\Omega\text{m}`
    * :math:`\phi` - porosity 0.0 --1.0
    * :math:`S`    - fluid saturation 0.0 --1.0
    * :math:`a` - Tortuosity factor. (common 1)
    * :math:`m` - Cementation exponent of the rock (usually in the range 1.3 -- 2.5 for sandstones)
    * :math:`n` - is the saturation exponent (usually close to 2)
     
    If mesh is not None the resulting values are calculated for each cell of 
    the mesh. 
    All parameter can be scalar, array of length mesh.cellCount() 
    or callable(pg.cell). If rFluid is non-steady n-step distribution 
    than rFluid can be a matrix of size(n, mesh.cellCount())
    If meshI is not None the result is interpolated to meshI.cellCenters() 
    and prolonged (if fill ==1).
    
    Note
    ----
    We experience some unstable nonlinear behavior.
    Until this is clarified all results are rounded to the precision 1e-6.
     
    Examples
    --------
    
    WRITEME
     
     
    """
    phi = porosity
    if type(porosity) is list:
        phi = np.array(porosity)
    
    if mesh == None:
        return rFluid * a * phi**(-m) * S**(-n)
    
    rB = None
    
    if type(rFluid) == float:
        rB = pg.RMatrix(1, mesh.cellCount())
        rB[0] = pg.solver.parseArgToArray(rFluid, mesh.cellCount(), mesh)
        
    elif rFluid.ndim == 1:
        rB = pg.RMatrix(1, len(rFluid))
        rB[0] = pg.solver.parseArgToArray(rFluid, mesh.cellCount(), mesh)
        
    elif rFluid.ndim == 2:
        rB = pg.RMatrix(len(rFluid), len(rFluid[0]))
        for i in range(len(rFluid)):
            rB[i] = rFluid[i]
     
    phi = pg.solver.parseArgToArray(phi, mesh.cellCount(), mesh)
    a = pg.solver.parseArgToArray(a, mesh.cellCount(), mesh)
    m = pg.solver.parseArgToArray(m, mesh.cellCount(), mesh)
    S = pg.solver.parseArgToArray(S, mesh.cellCount(), mesh)
    n = pg.solver.parseArgToArray(n, mesh.cellCount(), mesh)
    
    r = pg.RMatrix(len(rB), len(rB[0]))
    for i in range(len(r)):
        r[i] = rB[i] * a * phi**(-m) * S**(-n)
        
    r.round(1e-6)
    #print('rc:', min(np.array(r).flatten()), max(np.array(r).flatten()), np.mean(np.array(r).flatten()))        
    if meshI == None:
        if len(r) == 1:
            return r[0].copy()
        return r
    
    rI = pg.RMatrix(len(r), meshI.cellCount())
    if meshI:
        pg.interpolate(mesh, r, meshI.cellCenters(), rI) 
        
    #print('rd0:', min(np.array(rI).flatten()), max(np.array(rI).flatten()), np.mean(np.array(rI).flatten()))        
    
    if fill:
        for i in range(len(rI)):
            # slope == True produce unstable behavior .. check!!!!!!
            
            rI[i] = pg.solver.fillEmptyToCellArray(meshI, rI[i], slope=False)
        
    #print('rd1:', min(np.array(rI).flatten()), max(np.array(rI).flatten()), np.mean(np.array(rI).flatten()))        
    rI.round(1e-6)
    
    #print('rd2:', min(np.array(rI).flatten()), max(np.array(rI).flatten()), np.mean(np.array(rI).flatten()))        
    #print(rI)
    if len(rI) == 1:
        return rI[0]
    return rI
Пример #50
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)
Пример #51
0
def calcSeismics(meshIn, vP):
    """Do seismic computations."""
    meshSeis = meshIn.createH2()
    meshSeis = mt.appendTriangleBoundary(
            meshSeis, xbound=25, ybound=22.0, marker=1, quality=32.0, area=0.3,
            smooth=True, markerBoundary=1, isSubSurface=False, verbose=False)
    print(meshSeis)
    meshSeis = meshSeis.createH2()
    meshSeis = meshSeis.createH2()
    # meshSeis = meshSeis.createP2()

    meshSeis.smooth(1, 1, 1, 4)
    vP = pg.interpolate(meshIn, vP, meshSeis.cellCenters())

    mesh = meshSeis
    vP = pg.solver.fillEmptyToCellArray(mesh, vP)

    print(mesh)
    # ax, cbar = pg.show(mesh, data=vP)
    # pg.show(mesh, axes=ax)

    geophPointsX = np.arange(-19, 19.1, 1)
    geophPoints = np.vstack((geophPointsX, np.zeros(len(geophPointsX)))).T
    sourcePos = geophPoints[4]

    c = mesh.findCell(sourcePos)
    h1 = pg.findBoundary(c.boundaryNodes(0)).size()
    h2 = pg.findBoundary(c.boundaryNodes(1)).size()
    h3 = pg.findBoundary(c.boundaryNodes(2)).size()
    print([h1, h2, h3])
    h = pg.median([h1, h2, h3])

    # h = pg.median(mesh.boundarySizes())
    f0scale = 0.25
    cfl = 0.5
    dt = cfl * h / max(vP)
    print("Courant-Friedrich-Lewy number:", cfl)

    tmax = 40./min(vP)
    times = np.arange(0.0, tmax, dt)

    solutionName = createCacheName('seis', mesh, times) + "cfl-" + str(cfl)
    try:
        # u = pg.load(solutionName + '.bmat')
        uI = pg.load(solutionName + 'I.bmat')
    except Exception as e:
        print(e)
        f0 = f0scale * 1./dt
        print("h:", round(h, 2),
              "dt:", round(dt, 5),
              "1/dt:", round(1/dt, 1),
              "f0", round(f0, 2),
              "Wavelength: ", round(max(vP)/f0, 2), " m")

        uSource = ricker(times, f0, t0=1./f0)

        plt.figure()
        plt.plot(times, uSource, '-*')
        plt.show(block=0)
        plt.pause(0.01)
        u = solvePressureWave(mesh, vP, times, sourcePos=sourcePos,
                              uSource=uSource, verbose=10)

        u.save(solutionName)
        uI = pg.RMatrix()
        print("interpolate node to cell data ... ")
        pg.interpolate(mesh, u, mesh.cellCenters(), uI)
        print("... done")
        uI.save(solutionName+'I')

#    nodes = [mesh.findNearestNode(p) for p in geophPoints]
#    fig = plt.figure()
#    axs = fig.add_subplot(1,1,1)
#    drawSeismogramm(axs, mesh, u, nodes, dt, i=None)
#    plt.show()

    dpi = 92
    scale = 1
    fig = plt.figure(facecolor='white',
                     figsize=(scale*800/dpi, scale*490/dpi), dpi=dpi)
    ax = fig.add_subplot(1, 1, 1)
    gci = pg.mplviewer.drawModel(ax, mesh, data=uI[0],
                                 cMin=-1, cMax=1, cmap='bwr')
    pg.mplviewer.drawMeshBoundaries(ax, meshIn, hideMesh=1)
    ax.set_xlim((-20, 20))
    ax.set_ylim((-15, 0))
    ax.set_ylabel('Depth [m]')
    ax.set_xlabel('$x$ [m]')

    ticks = ax.yaxis.get_majorticklocs()
    tickLabels = []
    for t in ticks:
        tickLabels.append(str(int(abs(t))))

    ax.set_yticklabels(tickLabels)

    plt.tight_layout()
#    ax, cbar = pg.show(mesh, data=vP)
#    pg.showNow()
#    ax = fig.add_subplot(1,1,1)

    def animate(i):
        i = i*5
        if i > len(uI)-1:
            return
        print("Frame:", i, "/", len(uI))
        ui = uI[i]
        ui = ui / max(pg.abs(ui))
        ui = pg.logDropTol(ui, 1e-2)
        cMax = max(pg.abs(ui))

        pg.mplviewer.setMappableData(gci, ui,
                                     cMin=-cMax, cMax=cMax,
                                     logScale=False)
        # plt.pause(0.001)

    anim = animation.FuncAnimation(fig, animate,
                                   frames=int(len(uI)/5),
                                   interval=0.001, repeat=0)  # , blit=True)
    out = 'seis' + str(f0scale) + "cfl-" + str(cfl)
    anim.save(out + ".mp4", writer=None, fps=20, dpi=dpi, codec=None,
              bitrate=24*1024, extra_args=None, metadata=None,
              extra_anim=None, savefig_kwargs=None)
    try:
        print("create frames ... ")
        os.system('mkdir -p anim-' + out)
        os.system('ffmpeg -i ' + out + '.mp4 anim-' + out + '/movie%d.jpg')
    except:
        pass
Пример #52
0
def resistivityArchie(rFluid, porosity, a=1.0, m=2.0, sat=1.0, n=2.0,
                      mesh=None, meshI=None, fill=None, show=False):
    r"""Resistivity of rock for the petrophysical model from Archies law.

    Calculates resistivity of rock for the petrophysical model from
    Archie's law. :cite:`Archie1942`

    .. math::
        \rho = a\rho_{\text{fl}}\phi^{-m} S^{-n}

    * :math:`\rho` - the electrical resistivity of the fluid saturated rock in
      :math:`\Omega\text{m}`
    * :math:`\rho_{\text{fl}}` - rFluid: electrical resistivity of the fluid in
      :math:`\Omega\text{m}`
    * :math:`\phi` - porosity 0.0 --1.0
    * :math:`S` - fluid saturation 0.0 --1.0 [sat]
    * :math:`a` - Tortuosity factor. (common 1)
    * :math:`m` - Cementation exponent of the rock (usually in the
      range 1.3 -- 2.5 for sandstones)
    * :math:`n` - is the saturation exponent (usually close to 2)

    If mesh is not None the resulting values are calculated for each cell of
    the mesh.
    All parameter can be scalar, array of length mesh.cellCount()
    or callable(pg.cell). If rFluid is non-steady n-step distribution
    than rFluid can be a matrix of size(n, mesh.cellCount())
    If meshI is not None the result is interpolated to meshI.cellCenters()
    and prolonged (if fill ==1).

    Notes
    -----
        We experience some unstable nonlinear behavior.
        Until this is clarified all results are rounded to the precision 1e-6.

    Examples
    --------
    >>> #

    WRITEME
    """
    phi = porosity
    if isinstance(porosity, list):
        phi = np.array(porosity)

    if mesh is None:
        return rFluid * a * phi**(-m) * sat**(-n)

    rB = None

    if isinstance(rFluid, float):
        rB = pg.RMatrix(1, mesh.cellCount())
        rB[0] = pg.solver.parseArgToArray(rFluid, mesh.cellCount(), mesh)

    elif isinstance(rFluid, pg.RVector):
        rB = pg.RMatrix(1, len(rFluid))
        rB[0] = pg.solver.parseArgToArray(rFluid, mesh.cellCount(), mesh)

    elif hasattr(rFluid, 'ndim') and rFluid.ndim == 1:
        rB = pg.RMatrix(1, len(rFluid))
        rB[0] = pg.solver.parseArgToArray(rFluid, mesh.cellCount(), mesh)

    elif hasattr(rFluid, 'ndim') and rFluid.ndim == 2:
        rB = pg.RMatrix(len(rFluid), len(rFluid[0]))
        for i, rFi in enumerate(rFluid):
            rB[i] = rFi

    phi = pg.solver.parseArgToArray(phi, mesh.cellCount(), mesh)
    a = pg.solver.parseArgToArray(a, mesh.cellCount(), mesh)
    m = pg.solver.parseArgToArray(m, mesh.cellCount(), mesh)
    S = pg.solver.parseArgToArray(sat, mesh.cellCount(), mesh)
    n = pg.solver.parseArgToArray(n, mesh.cellCount(), mesh)

    if show:
        pg.show(mesh, S, label='S')
        pg.show(mesh, phi, label='p')
        pg.wait()

    r = pg.RMatrix(len(rB), len(rB[0]))
    for i, _ in enumerate(r):
        r[i] = rB[i] * a * phi**(-m) * S**(-n)

    r.round(1e-6)

    if meshI is None:
        if len(r) == 1:
            return r[0].copy()
        return r

    rI = pg.RMatrix(len(r), meshI.cellCount())
    if meshI:
        pg.interpolate(mesh, r, meshI.cellCenters(), rI)

    if fill:
        for i, ri_ in enumerate(rI):
            # slope == True produce unstable behavior .. check!!!!!!
            rI[i] = mt.fillEmptyToCellArray(meshI, ri_, slope=False)

    rI.round(1e-6)

    if len(rI) == 1:
        # copy here because of missing refcounter TODO
        return rI[0].array()
    return rI
#     Obs_IP, dataABMN=  FU.PrepareMALMData('./raw_data/' + inputfileMALM, Rec=False, DevErr=1,
#                                MinV=1, MaxRc=1, Kfact=1, MinMaxAppRes=1,
#                                SwE=False, gIP=gateIP,
#                                valid=None) # remove reciprocal from original dataset
#     coordE_f = []
#     for i, mi in enumerate(Obs['m']):
#         if mi==Nfix:
#            mi=Obs['n'][i]
#         id_coordE_f = np.where(mi+1==coordE[:,0])[0]
#         coordE_f.append(coordE[id_coordE_f[0],:])
#     coordE_f = np.array(coordE_f)

#%% foward modelling of homogeneous medium
# interpolate to MALM fwd mesh
if invERT:
    rho_fwd = pg.interpolate(mesh3d_fwd, mesh3d_inv, model, method='spline')
    rhomap = rho_fwd.array()
    id0 = np.where(rho_fwd.array() <= 0)
    rhomap[id0] = 0.1
else:
    model = waterRes
    rhomap = [[1, waterRes], [2, waterRes]]

#%% foward modelling of Green's functions
# mk_full_malm --> 3rd file = simulated green functions (simulated data to compare with observation data)
SeqFullMALM = MR.mk_full_malm(dataABMN - 1,
                              VRTe=range(len(sensors),
                                         len(sensors) + len(VRTEpos)),
                              mesh=mesh3d_fwd,
                              R3=False)  # output .shm with sensors