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()
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]
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]
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
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()
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
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
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
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)
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)
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
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
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
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
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())
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())
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
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()
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)
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()
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)
(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])
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()
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
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
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
(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()
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)
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
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.
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
# 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
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
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)
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()
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
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)
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
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)
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
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)
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
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)
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
# 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