Ejemplo n.º 1
0
from pygimli.solver import solve
"""
"""
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import animation

from pygimli.viewer import show
from pygimli.viewer.mpl import drawStreams

import time

grid = pg.createGrid(x=np.linspace(-1.0, 1.0, 31),
                     y=np.linspace(-1.0, 1.0, 31))

vals = pg.Vector(grid.cellCount(), 1.)
for c in grid.cells():
    if abs(c.center()[0]) < 0.1:
        vals[c.id()] = 10.0

#grid = grid.createP2()
times = np.arange(0, 2, 1. / 20)
#material?

neumannBC = [
    [1, -0.5],  # left
    [2, 0.5]
]  # right

dirichletBC = [
    [3, lambda b, t: 1.0 + np.cos(2.0 * np.pi * t)],  # top
Ejemplo n.º 2
0
 def transMult(self, b):
     ret = pg.Vector(self.cols())
     print("TestMatrix::transMult")
     return ret
Ejemplo n.º 3
0
y = np.arange(-20, 0.0, dx)[::-1]

mesh = pg.createGrid(x=x, y=y)
mesh = createMesh2()
print(mesh)

h = pg.math.median(mesh.boundarySizes())

v1 = 1000
v2 = 3000
tmax = 10.1 / v1

z = 2.
f0 = 1000.0  # A low wavelength of 50 Hz

velocities = pg.Vector(mesh.cellCount(), v1)

for c in mesh.cells():
    velocities[c.id()] = v1
    if c.center()[1] < -z:
        velocities[c.id()] = v2

dt = h * 0.5 / max(velocities)
times = np.arange(0.0, tmax, dt)
print(mesh, "h:", h, "dt:", dt, "n_t", len(times))

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

solutionName = 'uGridBig-' + str(dt) + '-' + str(h)

nx = len(x)
if __name__ == '__main__':
    nlay = 4  # number of layers
    lam = 200.  # (initial) regularization parameter
    errPerc = 3.  # relative error of 3 percent
    ab2 = np.logspace(-1, 2, 50)  # AB/2 distance (current electrodes)
    mn2 = ab2 / 3.  # MN/2 distance (potential electrodes)
    f = pg.DC1dModelling(nlay, ab2, mn2)
    synres = [100., 500., 20., 800.]  # synthetic resistivity
    synthk = [0.5, 3.5, 6.]  # synthetic thickness (nlay-th layer is infinite)
    rhoa = f(synthk + synres)
    rhoa = rhoa * (pg.randn(len(rhoa)) * errPerc / 100. + 1.)
    transLog = pg.RTransLog()
    inv = LSQRInversion(rhoa, f, transLog, transLog, True)
    inv.setRelativeError(errPerc / 100)
    startModel = pg.cat(pg.Vector(nlay - 1, 5),
                        pg.Vector(nlay, pg.median(rhoa)))
    print(inv.response())
    inv.setModel(startModel)
    inv.setMarquardtScheme()
    inv.setLambda(1000)
    G = pg.RMatrix(rows=1, cols=len(startModel))
    for i in range(3):
        G[0][i] = 1
    c = pg.Vector(1, pg.sum(synthk))
    inv.setParameterConstraints(G, c, 100)
    # print("Start", inv.chi2(), inv.relrms(), pg.sum(inv.model()(0, nlay-1)))
    if 0:
        for i in range(10):
            inv.oneStep()
            print(i, inv.chi2(), inv.relrms(), pg.sum(inv.model()(0,
Ejemplo n.º 5
0
    def fitDebyeModel(self,
                      ePhi=0.001,
                      lam=1e3,
                      lamFactor=0.8,
                      mint=None,
                      maxt=None,
                      nt=None,
                      new=True,
                      showFit=False,
                      cType=1,
                      verbose=False):
        """Fit a (smooth) continuous Debye model (Debye decomposition).

        Parameters
        ----------
        ePhi : float
            absolute error of phase angle
        lam : float
            regularization parameter
        lamFactor : float
            regularization factor for subsequent iterations
        mint/maxt : float
            minimum/maximum tau values to use (else automatically from f)
        nt : int
            number of tau values (default number of frequencies * 2)
        new : bool
            new implementation (experimental)
        showFit : bool
            show fit
        cType : int
            constraint type (1/2=smoothness 1st/2nd order, 0=minimum norm)
        """
        nf = len(self.f)
        if mint is None:
            mint = .1 / max(self.f)
        if maxt is None:
            maxt = .5 / min(self.f)
        if nt is None:
            nt = nf * 2
        # discretize tau, setup DD and perform DD inversion
        self.tau = np.logspace(log10(mint), log10(maxt), nt)
        phi = self.phi
        tLin, tLog, tM = pg.trans.Trans(), pg.trans.TransLog(
        ), pg.trans.TransLog()
        # pg.trans.TransLogLU(0., 1.)
        if new:
            reNorm, imNorm = self.zNorm()
            fDD = DebyeComplex(self.f, self.tau)
            Znorm = pg.cat(reNorm, imNorm)
            IDD = pg.core.Inversion(Znorm, fDD, tLog, tM, False)
            IDD.setAbsoluteError(max(Znorm) * 0.003 + ePhi)
        else:
            fDD = DebyePhi(self.f, self.tau)
            IDD = pg.core.Inversion(phi, fDD, tLin, tM, True)
            IDD.setAbsoluteError(ePhi)  # 1 mrad

        fDD.regionManager().setConstraintType(cType)
        IDD.stopAtChi1(False)
        startModel = pg.Vector(nt, 0.01)
        IDD.setModel(startModel)
        IDD.setLambda(lam)
        IDD.setLambdaFactor(lamFactor)
        self.mDD = IDD.run()
        IDD.echoStatus()
        if new:
            print("ARMS=", IDD.absrms(), "RRMS=",
                  IDD.absrms() / max(Znorm) * 100)
            resp = np.array(IDD.response())
            respRe = resp[:nf]
            respIm = resp[nf:]
            respC = ((1 - respRe) + respIm * 1j) * max(self.amp)
            self.phiDD = np.angle(respC)
            self.ampDD = np.abs(respC)
            if showFit:
                fig, ax = self.showData(znorm=True, nrows=3)
                self.fig['DebyeFit'] = fig
                ax[0].plot(self.f, respRe, 'r-')
                ax[1].plot(self.f, respIm, 'r-')
                ax[2].semilogx(self.tau, self.mDD, 'r-')
                ax[2].set_xlim(max(self.tau), min(self.tau))
                ax[2].set_ylim(0., max(self.mDD))
                ax[2].grid(True)
                ax[2].set_xlabel(r'$\tau$ (s)')
                ax[2].set_ylabel('$m$ (-)')

        else:
            self.phiDD = IDD.response()
            if showFit:
                fig, ax = self.showData(nrows=3)
                self.fig['DebyeSpectrum'] = fig
                ax[2].semilogx(self.tau, self.mDD, 'r-')
Ejemplo n.º 6
0
 def thkVel(self, model):
     """Return thickness and velocity vectors from model."""
     thk = pg.cat(pg.Vector(1, self.d0), model(0, self.nlay - 1))
     relvel = model(self.nlay - 1, self.nlay * 2 - 1)
     vel = self.v0 * np.cumprod(pg.cat(pg.Vector(1, 1.0), relvel))
     return thk, vel
Ejemplo n.º 7
0
 def startModel(self):
     return pg.Vector(self.nc_, 0.5)
print("Number of electrodes:", ertData.sensorCount())
print(ertData)

rstData = pg.DataContainer("rst.data", "s g")
print("Number of shot/receivers:", rstData.sensorCount())
maxrst = pg.max(pg.x(rstData.sensors()))

idx = []
for i, sensor in enumerate(ertData.sensors()):
    if sensor[0] >= 50.0:
        idx.append(i)

ertData.removeSensorIdx(idx)
ertData.removeInvalid()
ertData.removeUnusedSensors()
ertData.set("err", pg.Vector(ertData.size(), erte))
ertData.save("ert_filtered.data")

rstData.set("err", pg.Vector(rstData.size(), rste))
#
# # Remove two data points with high v_a at zero-offset
# Calculate offset
px = pg.x(rstData.sensorPositions())
gx = np.array([px[int(g)] for g in rstData("g")])
sx = np.array([px[int(s)] for s in rstData("s")])
offset = np.absolute(gx - sx)
va = offset / rstData("t")
rstData.markInvalid((offset < 5) & (va > 800))
#
# # Remove shot 27, too high apparent velocities
rstData.markInvalid(np.isclose(rstData("s"), 27))
Ejemplo n.º 9
0
import pygimli as pg

# log = logging.getLogger('pyGIMLi')

# logging.basicConfig(level=logging.DEBUG,
#                     format='%(asctime)s - %(name)s - ' + \
#                            '%(levelname)s - %(message)s',
#                     datefmt='%m/%d/%Y %H:%M:%S',
#                     #filename='example.log'
#                     )
pg.version()

# test pygimli log
pg.info("Start numeric log test." + str(pg.log(pg.Vector(1, 1.))))
pg.setVerbose(True)
pg.verbose("some verbose notes")
pg.warn("Start warning test.")


def testTraceback1():
    def testTraceback2():
        pg.error("Start error test.: int", 1, " vec", pg.Vector(2))
    testTraceback2()


testTraceback1()


@pg.v
def testVerboseDecorator1():
    pg.verbose('testVerboseDecorator1 should be seen even if verbose is false')
Ejemplo n.º 10
0
def diff(v):
    """Calculate approximate derivative.

    Calculate approximate derivative from v as d = [v_1-v_0, v2-v_1, ...]

    Parameters
    ----------
    v : array(N) | pg.core.R3Vector(N)
        Array of double values or positions

    Returns
    -------
    d : [type(v)](N-1) |
        derivative array

    Examples
    --------
    >>> import pygimli as pg
    >>> from pygimli.utils import diff
    >>> p = pg.core.R3Vector(4)
    >>> p[0] = [0.0, 0.0]
    >>> p[1] = [0.0, 1.0]
    >>> print(diff(p)[0])
    RVector3: (0.0, 1.0, 0.0)
    >>> print(diff(p)[1])
    RVector3: (0.0, -1.0, 0.0)
    >>> print(diff(p)[2])
    RVector3: (0.0, 0.0, 0.0)
    >>> p = pg.Vector(3)
    >>> p[0] = 0.0
    >>> p[1] = 1.0
    >>> p[2] = 2.0
    >>> print(diff(p))
    2 [1.0, 1.0]
    """
    d = None

    if isinstance(v, np.ndarray):
        if v.ndim == 2:
            if v.shape[1] < 4:
                # v = pg.core.R3Vector(v.T)
                vt = v.copy()
                v = pg.core.R3Vector(len(vt))
                for i, vi in enumerate(vt):
                    v.setVal(pg.RVector3(vi), i)
            else:
                v = pg.core.R3Vector(v)
        else:
            v = pg.Vector(v)
    elif isinstance(v, list):
        v = pg.core.R3Vector(v)

    if isinstance(v, pg.core.R3Vector) or isinstance(
            v, pg.core.stdVectorRVector3):
        d = pg.core.R3Vector(len(v) - 1)
    else:
        d = pg.Vector(len(v) - 1)

    for i, _ in enumerate(d):
        d[i] = v[i + 1] - v[i]
    return d
Ejemplo n.º 11
0
def rand(n, minVal=0.0, maxVal=1.0):
    """Create RVector of length n with normally distributed random numbers."""
    r = pg.Vector(n)
    pg.rand(r, minVal, maxVal)
    return r
Ejemplo n.º 12
0
def grange(start, end, dx=0, n=0, log=False):
    """Create array with possible increasing spacing.

    Create either array from start step-wise filled with dx until end reached
    [start, end] (like np.array with defined end).
    Fill the array from start to end with n steps.
    [start, end] (like np.linespace)
    Fill the array from start to end with n steps but logarithmic increasing,
    dx will be ignored.

    Parameters
    ----------
    start: float
        First value of the resulting array
    end: float
        Last value of the resulting array
    dx: float
        Linear step length, n will be ignored
    n: int
        Amount of steps
    log: bool
        Logarithmic increasing range of length = n from start to end.
        dx will be ignored.
    Examples
    --------
    >>> from pygimli.utils import grange
    >>> v1 = grange(start=0, end=10, dx=3)
    >>> v2 = grange(start=0, end=10, n=3)
    >>> print(v1)
    4 [0.0, 3.0, 6.0, 9.0]
    >>> print(v2)
    3 [0.0, 5.0, 10.0]

    Returns
    -------
    ret: :gimliapi:`GIMLI::RVector`
        Return resulting array
    """
    s = float(start)
    e = float(end)
    d = float(dx)

    if dx != 0 and not log:
        if end < start and dx > 0:
            # print("grange: decreasing range but increasing dx, swap dx sign")
            d = -d
        if end > start and dx < 0:
            # print("grange: increasing range but decreasing dx, swap dx sign")
            d = -d
        ret = pg.Vector(range(int(floor(abs((e - s) / d)) + 1)))
        ret *= d
        ret += s
        return ret

    elif n > 0:
        if not log:
            return grange(start, end, dx=(e - s) / (n - 1))
        else:
            return pg.core.increasingRange(start, end, n)[1:]
    else:
        raise Exception('Either dx or n have to be given.')
Ejemplo n.º 13
0
def streamlineDir(mesh,
                  field,
                  startCoord,
                  dLengthSteps,
                  dataMesh=None,
                  maxSteps=1000,
                  down=True,
                  verbose=False,
                  coords=(0, 1)):
    """
        down = -1, up = 1, both = 0
    """
    xd = []
    yd = []
    vd = []

    pot = None
    vx = None
    vy = None
    isVectorData = False

    if isinstance(field, pg.core.R3Vector):
        field = field.array()

    if hasattr(field[0], '__len__'):
        if abs(max(field[:, 0])) == 0 and abs(max(field[:, 1]) == 0):
            raise BaseException("No data range streamline: min/max == ",
                                min(field[:, 0]))

        vx = pg.Vector(field[:, 0])
        vy = pg.Vector(field[:, 1])

        isVectorData = True
    else:
        if min(field) == max(field):
            raise BaseException(
                "No scalar data range for any gradients "
                " to draw a streamline: min/max == ", min(field))

        if dataMesh is not None:
            if len(field) == dataMesh.nodeCount():
                pot = pg.Vector(field)
            elif len(field) == dataMesh.cellCount():
                pot = pg.core.cellDataToPointData(dataMesh, field)
            else:
                raise BaseException(
                    "Data length (%i) for streamline is "
                    "neighter nodeCount (%i) nor cellCount (%i)" %
                    (len(field), dataMesh.nodeCount(), dataMesh.nodeCount()))
        else:
            if len(field) == mesh.nodeCount():
                pot = pg.Vector(field)
            elif len(field) == mesh.cellCount():
                pot = pg.core.cellDataToPointData(mesh, field)
            else:
                raise BaseException(
                    "Data length (%i) for streamline is "
                    "neighter nodeCount (%i) nor cellCount (%i)" %
                    (len(field), mesh.nodeCount(), mesh.nodeCount()))

    direction = 1
    if down:
        direction = -1

    # search downward
    pos = pg.RVector3(startCoord)
    c = mesh.findCell(startCoord)
    dLength = c.center().dist(c.node(0).pos()) / dLengthSteps

    # stream line starting point
    if c is not None:
        xd.append(pos[coords[0]])
        yd.append(pos[coords[1]])
        vd.append(-1)

    lastC = c
    lastU = -direction * 1e99

    d = None
    while c is not None and len(xd) < maxSteps:

        # valid .. temporary check if there is already a stream within the cell
        if not c.valid():
            break

        if isVectorData:
            u = 0.
            if len(vx) == mesh.cellCount():
                d = pg.RVector3(vx[c.id()], vy[c.id()])
            elif len(vx) == mesh.nodeCount():
                d = pg.RVector3(c.pot(pos, vx), c.pot(pos, vy))
            elif dataMesh:
                cd = dataMesh.findCell(pos)
                if cd is None:
                    raise BaseException("Cannot find " + str(pos) +
                                        " dataMesh")
                if len(vx) == dataMesh.cellCount():
                    d = pg.RVector3(vx[cd.id()], vy[cd.id()])
                elif len(vx) == dataMesh.nodeCount() and \
                        len(vy) == dataMesh.nodeCount():
                    d = pg.RVector3(cd.pot(pos, vx), cd.pot(pos, vy))
                else:
                    print(dataMesh)
                    print(len(vx), len(vy))
                    raise BaseException("data size wrong")
            else:
                print(mesh, len(vx), len(vy))
                raise Exception("Data length neightor node size or cell size.")
        else:
            if dataMesh:
                cd = dataMesh.findCell(pos)
                if not cd:
                    break

                d = cd.grad(pos, pot)
                u = cd.pot(pos, pot)
            else:
                d = c.grad(pos, pot)
                u = c.pot(pos, pot)
        # print "cell:", c.id(), u
        # always go u down
        dAbs = d.length()
        if dAbs == 0.0:
            print(
                d,
                "check this in streamlineDir(",
            )
            break

        if down:
            if u > lastU:
                break
        else:
            if u < lastU:
                break

        # * min(1.0, ((startCoord - pos).length()))
        pos += direction * d / dAbs * dLength
        c = mesh.findCell(pos, False)

        # Change cell here .. set old cell to be processed
        if c is not None:

            xd.append(pos[coords[0]])
            yd.append(pos[coords[1]])
            # set the stating value here
            if vd[0] == -1:
                vd[0] = dAbs
            vd.append(dAbs)

            # If the new cell is different from the current we move into the
            # new cell and make the last to be invalid ..
            # the last active contains a stream element
            if c.id() != lastC.id():
                lastC.setValid(False)
                lastC = c
                dLength = c.center().dist(c.node(0).pos()) / dLengthSteps
        else:
            # There is no new cell .. the last active contains a stream element
            lastC.setValid(False)

        lastU = u
        if verbose:
            print(pos, u)

    # Stream line has stopped and the current cell (if there is one) ..
    # .. contains a stream element
    if c is not None:

        c.setValid(False)

    if down:
        xd.reverse(), yd.reverse(), vd.reverse()

    return xd, yd, vd
Ejemplo n.º 14
0
        print('Create response', str(par))
        time.sleep(1)
        return par * 3.0

    def response_mt(self, par, i=0):
        """
            this need to be implemented as read only function!
            don't use self.mapModel until this is changed into a read only 
            version
        """
        print('Create response_mt(' + str(i) + ')', str(par))
        time.sleep(1)
        return par * 2.0


nPars = 4
m = pg.Vector(nPars, 1)

fop = TestModelling(nPars, verbose=True)

fop.setMultiThreadJacobian(1)
pg.tic()
fop.createJacobian(m)
pg.toc()
print(fop.jacobian())

fop.setMultiThreadJacobian(4)
pg.tic()
fop.createJacobian(m)
pg.toc()
print(fop.jacobian())
Ejemplo n.º 15
0
                cMax=1e-2,
                nLevs=4,
                cMap='viridis')
ax, _ = pg.show(mesh,
                data=pg.abs(vel),
                logScale=0,
                label='Velocity $v$ in m$/$s')
ax, _ = pg.show(mesh,
                data=vel,
                ax=ax,
                color='black',
                linewidth=0.5,
                dropTol=1e-6)

print('Solve Advection-diffusion equation ...')
S = pg.Vector(mesh.cellCount(), 0.0)
# Fill injection source vector for a fixed injection position
sourceCell = mesh.findCell([-19.1, -4.6])
S[sourceCell.id()] = 1.0 / sourceCell.size()  # g/(l s)
# Choose 800 time steps for 6 days in seconds
t = pg.utils.grange(0, 6 * 24 * 3600, n=800)
# Create dispersitivity, depending on the absolute velocity
dispersion = pg.abs(vel) * 1e-2
# Solve for injection time, but we need velocities on cell nodes
vel = mt.cellDataToNodeData(mesh, vel)
c1 = pg.solver.solveFiniteVolume(mesh,
                                 a=dispersion,
                                 f=S,
                                 vel=vel,
                                 times=t,
                                 uB=[1, 0],
Ejemplo n.º 16
0
 def testTraceback2():
     pg.error("Start error test.: int", 1, " vec", pg.Vector(2))
Ejemplo n.º 17
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)
Ejemplo n.º 18
0
if __name__ == '__main__':
    nlay = 4  # number of layers
    lam = 200.  # (initial) regularization parameter
    errPerc = 3.  # relative error of 3 percent
    ab2 = np.logspace(-1, 2, 50)  # AB/2 distance (current electrodes)
    mn2 = ab2 / 3.  # MN/2 distance (potential electrodes)
    f = pg.DC1dModelling(nlay, ab2, mn2)
    synres = [100., 500., 20., 800.]  # synthetic resistivity
    synthk = [0.5, 3.5, 6.]  # synthetic thickness (nlay-th layer is infinite)
    rhoa = f(synthk + synres)
    rhoa = rhoa * (pg.randn(len(rhoa)) * errPerc / 100. + 1.)
    transLog = pg.RTransLog()
    inv = LSQRInversion(rhoa, f, transLog, transLog, True)
    inv.setRelativeError(errPerc / 100)
    startModel = pg.cat(
        pg.Vector(nlay - 1, 5), pg.Vector(nlay, pg.median(rhoa)))
    print(inv.response())
    inv.setModel(startModel)
    inv.setMarquardtScheme()
    inv.setLambda(1000)
    G = pg.RMatrix(rows=1, cols=len(startModel))
    for i in range(3):
        G[0][i] = 1
    c = pg.Vector(1, pg.sum(synthk))
    inv.setParameterConstraints(G, c, 100)
    # print("Start", inv.chi2(), inv.relrms(), pg.sum(inv.model()(0, nlay-1)))
    if 0:
        for i in range(10):
            inv.oneStep()
            print(i, inv.chi2(), inv.relrms(), pg.sum(inv.model()(0,
                                                                  nlay - 1)))
Ejemplo n.º 19
0
def fillEmptyToCellArray(mesh, vals, slope=True):
    """
    Prolongate empty cell values to complete cell attributes.

    It is possible to have zero values that are filled with appropriate
    attributes. This function tries to fill empty values successively by
    prolongation of the non-zeros.

    Parameters
    ----------
    mesh : :gimliapi:`GIMLI::Mesh`
        For each cell of mesh a value will be returned.

    vals : array
        Array of size cellCount().

    Returns
    -------
    atts : array
        Array of length mesh.cellCount()

    Examples
    --------
    >>> import pygimli as pg
    >>> import numpy as np
    >>> import matplotlib.pyplot as plt
    >>>
    >>> # Create a mesh with 3 layers and an outer region for extrapolation
    >>> layers = pg.meshtools.createWorld([0,-50],[100,0], layers=[-15,-35])
    >>> inner = pg.meshtools.createMesh(layers, area=3)
    >>> mesh = pg.meshtools.appendTriangleBoundary(inner, xbound=120, ybound=50,
    ...                                            area=20, marker=0)
    >>>
    >>> # Create data for the inner region only
    >>> layer_vals = [20,30,50]
    >>> data = np.array(layer_vals)[inner.cellMarkers() - 1]
    >>>
    >>> # The following fails since len(data) != mesh.cellCount(), extrapolate
    >>> # pg.show(mesh, data)
    >>>
    >>> # Create data vector, where zeros fill the outer region
    >>> data_with_outer = np.array([0] + layer_vals)[mesh.cellMarkers()]
    >>>
    >>> # Actual extrapolation
    >>> extrapolated_data = pg.meshtools.fillEmptyToCellArray(mesh,
    ...                                  data_with_outer, slope=False)
    >>> extrapolated_data_with_slope = pg.meshtools.fillEmptyToCellArray(mesh, 
    ...                                 data_with_outer, slope=True)
    >>>
    >>> # Visualization
    >>> fig, (ax1, ax2, ax3) = plt.subplots(1,3, figsize=(10,8), sharey=True)
    >>> _ = pg.show(mesh, data_with_outer, ax=ax1, cMin=0)
    >>> _ = pg.show(mesh, extrapolated_data, ax=ax2, cMin=0)
    >>> _ = pg.show(mesh, extrapolated_data_with_slope, ax=ax3, cMin=0)
    >>> _ = ax1.set_title("Original data")
    >>> _ = ax2.set_title("Extrapolated with slope=False")
    >>> _ = ax3.set_title("Extrapolated with slope=True")
    """
    # atts = pg.Vector(mesh.cellCount(), 0.0)  # not used
    # oldAtts = mesh.cellAttributes()  # not used
    mesh.setCellAttributes(vals)
    mesh.createNeighborInfos()
    # std::vector< Cell * >
    # empties = []

    if slope:
        # search all cells with empty neighbors
        ids = pg.find(mesh.cellAttributes() != 0.0)

        for c in mesh.cells(ids):
            for i in range(c.neighborCellCount()):
                nc = c.neighborCell(i)

                if nc:
                    if nc.attribute() == 0.0:
                        # c.setAttribute(99999)

                        b = pg.core.findCommonBoundary(c, nc)
                        # search along a slope
                        pos = b.center() - b.norm() * 1000.
                        sf = pg.Vector()
                        startCell = c

                        while startCell:

                            startCell.shape().isInside(pos, sf, False)
                            nextC = startCell.neighborCell(sf)
                            if nextC:
                                if nextC.attribute() == 0.0:
                                    nextC.setAttribute(c.attribute())
                                else:
                                    break

                            startCell = nextC

    vals = mesh.cellAttributes()
    mesh.prolongateEmptyCellsValues(vals, background=-9e99)
    mesh.setCellAttributes(vals)
    return vals
Ejemplo n.º 20
0
# stream lines. By default, the drawStreams method draws one segment of a
# stream line per cell of the mesh. This can be a little confusing for dense
# meshes so we can give a second (coarse) mesh as a new cell base to draw the
# streams. If `drawStreams` gets scalar data, the gradients will be calculated.
gridCoarse = pg.createGrid(x=np.linspace(-10.0, 10.0, 20),
                           y=np.linspace(-15.0, .0, 20))
drawStreams(ax, mesh, u, coarseMesh=gridCoarse, color='Black')

###############################################################################
# We know the exact solution so we can compare it to the numerical results.
# Unfortunately, the point source singularity does not allow a good integration
# measure for the accuracy of the resulting field so we just look for the
# differences.
#
uAna = pg.Vector(
    list(
        map(lambda p__: uAnalytical(p__, sourcePosA, k, sigma),
            mesh.positions())))
uAna -= pg.Vector(
    list(
        map(lambda p__: uAnalytical(p__, sourcePosB, k, sigma),
            mesh.positions())))

ax = pg.show(mesh,
             data=pg.abs(uAna - u),
             cMap="Reds",
             orientation='horizontal',
             label='|$u_{exact}$ -$u$|',
             logScale=True,
             cMin=1e-7,
             cMax=1e-1,
             contourLines=False,
Ejemplo n.º 21
0
 def test_RVector(self):
     """ implemented in custom_rvalue.cpp"""
     a = pg.Vector(10)
     self.assertEqual(a.size(), 10.0)
     self.assertEqual(sum(a), 0.0)
Ejemplo n.º 22
0
def drawStreamLine_(ax,
                    mesh,
                    c,
                    data,
                    dataMesh=None,
                    linewidth=1.0,
                    dropTol=0.0,
                    **kwargs):
    """Draw a single streamline.

    Draw a single streamline into a given mesh for given data stating at
    the center of cell c.
    The Streamline will be enlarged until she reached a cell that
    already contains a streamline.

    TODO
        linewidth and color depends on absolute velocity
        or background color saturation

    Parameters
    ----------
    ax : matplotlib.ax
        ax to draw into
    mesh : :gimliapi:`GIMLI::Mesh`
        2d mesh
    c : :gimliapi:`GIMLI::Cell`
        Start point is c.center()
    data : iterable float | [float, float]
        If data is an array (per cell or node) gradients are calculated
        otherwise the data will be interpreted as vector field per nodes or
        cell centers.
    dataMesh : :gimliapi:`GIMLI::Mesh` [None]
        Optional mesh for the data. If you want high resolution
        data to plot on coarse draw mesh.
    linewidth : float [1.0]
        Streamline linewidth
    dropTol : float [0.0]
        Don't draw stream lines with velocity lower than drop tolerance.

    Keyword Arguments
    -----------------
    **kwargs
        arrowSize: int
            Size of the arrow's head.
        arrowColor: str
            Color of the arrow's head.
        Additional kwargs are being forwarded to mpl.LineCollection, mpl.Polygon
    """
    x, y, v = streamline(mesh,
                         data,
                         startCoord=c.center(),
                         dLengthSteps=5,
                         dataMesh=dataMesh,
                         maxSteps=10000,
                         verbose=False,
                         coords=[0, 1])

    if 'color' not in kwargs:
        kwargs['color'] = 'black'

    arrowSize = kwargs.pop('arrowSize', 12)
    arrowColor = kwargs.pop('arrowColor', 'black')

    lines = None

    if len(x) > 2:
        points = np.array([x, y]).T.reshape(-1, 1, 2)

        segments = np.concatenate([points[:-1], points[1:]], axis=1)

        lwidths = pg.Vector(len(v), linewidth)
        lwidths[pg.find(pg.Vector(v) < dropTol)] = 0.0

        lines = mpl.collections.LineCollection(segments,
                                               linewidths=lwidths,
                                               **kwargs)
        ax.add_collection(lines)

        # probably the limits are wrong without plot call
        # lines = ax.plot(x, y, **kwargs)
        # updateAxes_(ax, lines)
        # ax.plot(x, y, '.-', color='black', **kwargs)
    if len(x) > 3:
        xmid = int(len(x) / 2)
        ymid = int(len(y) / 2)
        dx = x[xmid + 1] - x[xmid]
        dy = y[ymid + 1] - y[ymid]
        c = mesh.findCell([x[xmid], y[ymid]])

        if v[xmid] > dropTol:

            absArrowSize = True
            if absArrowSize:
                ax.annotate(
                    '',
                    xytext=(x[xmid] - dx, y[ymid] - dy),
                    xy=(x[xmid], y[ymid]),
                    arrowprops=dict(arrowstyle="-|>", color=arrowColor),
                    size=arrowSize,
                    **kwargs,
                )
            else:
                ax.arrow(x[xmid],
                         y[ymid],
                         dx,
                         dy,
                         shape='full',
                         lw=0,
                         length_includes_head=True,
                         fc=arrowColor,
                         head_width=.35,
                         **kwargs)

            # dx90 = -dy
            # dy90 = dx
            # aLen = 3
            # aWid = 1
            # xy = list(zip([x[xmid] + dx90*aWid, x[xmid] + dx*aLen,
            #                x[xmid] - dx90*aWid],
            #               [y[ymid] + dy90*aWid, y[ymid] + dy*aLen,
            #                y[ymid] - dy90*aWid]))

            # arrow = mpl.patches.Polygon(xy, ls=None, lw=0, closed=True,
            #                             **kwargs)
            #ax.add_patch(arrow)

    return lines
    def oneStep(self):
        """One inversion step."""
        model = self.model()
        if len(self.response()) != len(self.data()):
            self.setResponse(self.forwardOperator().response(model))

        self.forwardOperator().createJacobian(model)
        self.checkTransFunctions()
        tD = self.transData()
        tM = self.transModel()
        nData = self.data().size()
        #        nModel = len(model)
        self.A = pg.matrix.BlockMatrix(
        )  # to be filled with scaled J and C matrices
        # part 1: data part
        J = self.forwardOperator().jacobian()
        # self.dScale = 1.0 / pg.log(self.error()+1.0)
        self.dScale = 1.0 / (tD.deriv(self.data()) * self.error() *
                             self.data())
        self.leftJ = tD.deriv(self.response()) * self.dScale
        #        self.leftJ = self.dScale / tD.deriv(self.response())
        self.rightJ = 1.0 / tM.deriv(model)
        self.JJ = pg.matrix.MultLeftRightMatrix(J, self.leftJ, self.rightJ)
        #        self.A.addMatrix(self.JJ, 0, 0)
        self.mat1 = self.A.addMatrix(self.JJ)
        self.A.addMatrixEntry(self.mat1, 0, 0)
        # part 2: normal constraints
        self.checkConstraints()
        self.C = self.forwardOperator().constraints()
        self.leftC = pg.Vector(self.C.rows(), 1.0)
        self.rightC = pg.Vector(self.C.cols(), 1.0)
        self.CC = pg.matrix.MultLeftRightMatrix(self.C, self.leftC,
                                                self.rightC)
        self.mat2 = self.A.addMatrix(self.CC)
        lam = self.getLambda()
        self.A.addMatrixEntry(self.mat2, nData, 0, sqrt(lam))
        # % part 3: parameter constraints
        if self.G is not None:
            self.rightG = 1.0 / tM.deriv(model)
            self.GG = pg.matrix.MultRightMatrix(self.G, self.rightG)
            self.mat3 = self.A.addMatrix(self.GG)
            nConst = self.C.rows()
            self.A.addMatrixEntry(self.mat3, nData + nConst, 0, sqrt(self.my))
        self.A.recalcMatrixSize()
        # right-hand side vector
        deltaD = (tD.fwd(self.data()) - tD.fwd(self.response())) * self.dScale
        deltaC = -(self.CC * tM.fwd(model) * sqrt(lam))
        deltaC *= 1.0 - self.localRegularization()  # operates on DeltaM only
        rhs = pg.cat(deltaD, deltaC)
        if self.G is not None:
            deltaG = (self.c - self.G * model) * sqrt(self.my)
            rhs = pg.cat(pg.cat(deltaD, deltaC), deltaG)

        dM = lsqr(self.A, rhs)
        tau, responseLS = self.lineSearchInter(dM)
        if tau < 0.1:  # did not work out
            tau = self.lineSearchQuad(dM, responseLS)
        if tau > 0.9:  # save time and take 1
            tau = 1.0
        else:
            self.forwardOperator().response(self.model())

        if tau < 0.1:  # still not working
            tau = 0.1  # tra a small value

        self.setModel(tM.update(self.model(), dM * tau))
        # print("model", min(self.model()), max(self.model()))
        if tau == 1.0:
            self.setResponse(responseLS)
        else:  # compute new response
            self.setResponse(self.forwardOperator().response(self.model()))

        self.setLambda(self.getLambda() * self.lambdaFactor())
        return True
Ejemplo n.º 24
0
def drawModel(ax,
              mesh,
              data=None,
              tri=False,
              rasterized=False,
              cMin=None,
              cMax=None,
              logScale=False,
              xlabel=None,
              ylabel=None,
              fitView=True,
              verbose=False,
              **kwargs):
    """Draw a 2d mesh and color the cell by the data.

    Parameters
    ----------
    ax : mpl axis instance, optional
        Axis instance where the mesh is plotted (default is current axis).
    mesh : :gimliapi:`GIMLI::Mesh`
        The plotted mesh to browse through.
    data : array, optional
        Data to draw. Should either equal numbers of cells or nodes of the
        corresponding `mesh`.
    tri : boolean, optional
        use MPL tripcolor (experimental)
    rasterized : boolean, optional
        Rasterize mesh patches to reduce file size and avoid zooming artifacts
        in some PDF viewers.
    fitView : bool [True]
        Adjust ax limits to mesh bounding box.

    Keyword Arguments
    -----------------
    **kwargs
        Additional kwargs forwarded to the draw functions and mpl methods,
        respectively.

    Returns
    -------
    gci : matplotlib graphics object

    Examples
    --------
    >>> import numpy as np
    >>> import matplotlib.pyplot as plt
    >>> import pygimli as pg
    >>> from pygimli.viewer.mpl import drawModel
    >>> n = np.linspace(0, -2, 11)
    >>> mesh = pg.createGrid(x=n, y=n)
    >>> mx = pg.x(mesh.cellCenter())
    >>> my = pg.y(mesh.cellCenter())
    >>> data = np.cos(1.5 * mx) * np.sin(1.5 * my)
    >>> fig, ax = plt.subplots()
    >>> drawModel(ax, mesh, data)
    <matplotlib.collections.PolyCollection object at ...>
    """
    # deprecated .. remove me
    if 'cMap' in kwargs or 'cmap' in kwargs:
        pg.warn('cMap|cmap argument is deprecated for draw functions. ' +
                'Please use show or customize a colorbar.')
    # deprecated .. remove me

    if mesh.nodeCount() == 0:
        pg.error("drawModel: The mesh is empty.", mesh)

    if tri or 'shading' in kwargs:
        gci = drawField(ax,
                        mesh,
                        data,
                        cMin=cMin,
                        cMax=cMax,
                        logScale=logScale,
                        **kwargs)
    else:
        gci = pg.viewer.mpl.createMeshPatches(ax,
                                              mesh,
                                              rasterized=rasterized,
                                              verbose=verbose)
        ax.add_collection(gci)

        if data is None:
            data = pg.Vector(mesh.cellCount())

        if len(data) != mesh.cellCount():
            print(data, mesh)
            pg.info("drawModel have wrong data length .. " +
                    " indexing data from cellMarkers()")
            viewdata = data[mesh.cellMarkers()]
        else:
            viewdata = data

        pg.viewer.mpl.setMappableData(gci,
                                      viewdata,
                                      cMin=cMin,
                                      cMax=cMax,
                                      logScale=logScale,
                                      **kwargs)

    gci.set_antialiased(True)
    gci.set_linewidths(0.1)
    gci.set_edgecolors("face")

    if xlabel is not None:
        ax.set_xlabel(xlabel)

    if ylabel is not None:
        ax.set_ylabel(ylabel)

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

    updateAxes_(ax)
    return gci
Ejemplo n.º 25
0
 def mult(self, b):
     ret = pg.Vector(self.rows())
     print("TestMatrix::mult")
     return ret
Ejemplo n.º 26
0
# based on LAPACK (numpy.linalg). The inverse square root is defined by
#
# .. math::
#
#     \textbf{C}_\text{M}^{-0.5} = \textbf{Q}\textbf{D}^{-0.5}\textbf{Q}^{T}
#
# In order to avoid a matrix inverse (square root), a special matrix is derived
# that does the decomposition and stores the eigenvectors and eigenvalues values.
# A multiplication is done by multiplying with Q and scaling with the diagonal D.
# This matrix is implemented in the :mod:`pygimli.matrix` module
# by the class :py:mod:`pg.matrix.Cm05Matrix`

Cm05 = pg.matrix.Cm05Matrix(CM)
# %%
# However, this matrix does not return a zero vector for a constant vector
out = Cm05 * pg.Vector(mesh.cellCount(), 1.0)
print(min(out), max(out))

# %%
# as desired for a roughness operator. Therefore, an additional matrix called
# :py:mod:`pg.matrix.GeostatisticalConstraintsMatrix`
# was implemented where this spur is corrected for.
# It is, like the correlation matrix, created by a mesh, a list of correlation
# lengths I, a dip angle# that distorts the x/y plane and a strike angle
# towards the third direction.
#
C = pg.matrix.GeostatisticConstraintsMatrix(mesh=mesh, I=5)

# %%
# In order to extract a certain column, we generate a vector with a single 1
vec = pg.Vector(mesh.cellCount())
Ejemplo n.º 27
0
 def response(self, model):
     print("TestModelling::response")
     res = pg.Vector(1, 1.0)
     return res
    S[N, N+1] += -aW
    S[N, N] += aW

    rhs[0] += uDir[0]
    rhs[N+1] += uDir[1]

    return S, rhs
    
x = np.linspace(.0, 1.0, 11)
dx = x[1]-x[0]

grid = pg.createGrid(x=x)
N = grid.cellCount()

# force vector per cell
f = pg.Vector(grid.cellCount(), 0.0)
# diffusions coefficient
a = pg.Vector(grid.cellCount(), 2.1)
# velocity per cell [x-direction]
v = pg.Vector(grid.cellCount(), 20.1)

print('Peclet-number:', v[0]/(a[0] / dx))
        
ud0=0
udN=1

def uAna(x, L, v, D):
    """
        u = \frac{1 - \e(-v_x x / D)}{1 - \e(-v_x L / D)}

        Check for -v -- herleiten
Ejemplo n.º 29
0
 def createDefaultStartModel(self, models):
     sm = pg.Vector()
     for i, f in enumerate(self._fops1D):
         sm = pg.cat(sm, f.createDefaultStartModel(models[i]))
     return sm
Ejemplo n.º 30
0
 def createStartModel(self, dataVals):
     return pg.Vector([1.0, 3.0])