Beispiel #1
0
def lineIntegralZ_WonBevis(p1, p2):
    r"""TODO WRITEME.

    :cite:`WonBev1987`

    Returns
    -------
        g = -grad u =(Fx, 0.0, Fz), dFz(Fzx, Fzy, Fzz)
    """
    dg = pg.RVector3(0.0, 0.0, 0.0)
    dgz = pg.RVector3(0.0, 0.0, 0.0)
    pg.lineIntegralZ_WonBevis(p1, p2, dg, dgz)
    return np.asarray((dg[0], dg[1], dg[2])), \
           np.asarray((dgz[0], dgz[1], dgz[2]))
Beispiel #2
0
def solveGravimetry(mesh, dDensity=None, pnts=None, complete=False):
    r"""Solve gravimetric response.

    2D with :py:mod:`pygimli.physics.gravimetry.lineIntegralZ_WonBevis`

    3D with :py:mod:`pygimli.physics.gravimetry.gravMagBoundarySinghGup`

    TOWRITE

    Parameters
    ----------
    mesh : :gimliapi:`GIMLI::Mesh`
        2d or 3d mesh with or without cells.

    dDensity : float | array
        Density difference.

        * float -- solve for positive boundary marker only.
            Assuming one inhomogeneity.
        * [[int, float]] -- solve for multiple positive boundaries TOIMPL
        * array -- solve for one delta density value per cell
        * None -- return per cell kernel matrix G TOIMPL

    pnts : [[x_i, y_i]]
        List of measurement positions.

    complete : bool [False]
        If True return whole solution or matrix for [dgx, dgy, dgz] and ...
        TODO

    Returns
    -------
    """
    if pnts is None:
        pnts = [[0.0, 0.0]]

    mesh.createNeighbourInfos()

    Gdg = None
    Gdgz = None
    dg = None
    dgz = None

    if complete:
        Gdg = np.zeros((len(pnts), mesh.cellCount(), 3))
        Gdgz = np.zeros((len(pnts), mesh.cellCount(), 3))
        dg = np.zeros((len(pnts), 3))
        dgz = np.zeros((len(pnts), 3))
    else:
        dg = np.zeros(len(pnts))
        Gdg = np.zeros((len(pnts), mesh.cellCount()))

    dgi = None
    dgzi = None

    for i, p in enumerate(pnts):
        mesh.translate(-pg.RVector3(p))

        for b in mesh.boundaries():
            if b.marker() != 0 or hasattr(dDensity, '__len__') or \
                    dDensity is None:

                if mesh.dimension() == 2:
                    # tic = time.time()
                    if complete:
                        dgi, dgzi = lineIntegralZ_WonBevis(b.node(0).pos(),
                                                           b.node(1).pos())
#                        times.append(time.time() - tic)
                        dgi *= -2.0
                        dgzi *= -2.0
                    else:
                        dgi = pg.lineIntegralZ_WonBevis(b.node(0).pos(),
                                                        b.node(1).pos())
                        dgi *= -2.0 * G
                else:
                    if complete:
                        dgi, dgzi = gravMagBoundarySinghGup(b)
                    else:
                        raise Exception("TOIMPL")

                if complete:
                    dgi *= [1.0, 1.0, -1.0]
                    dgi *= -G
                    dgzi *= -G

                if hasattr(dDensity, '__len__') or dDensity is None:
                    cl = b.leftCell()
                    cr = b.rightCell()

                    if cl:
                        Gdg[i][cl.id()] += dgi
                        if complete:
                            Gdgz[i][cl.id()] += dgzi
                    if cr:
                        Gdg[i][cr.id()] -= dgi
                        if complete:
                            Gdgz[i][cr.id()] -= dgzi
                else:
                    dg[i] += dgi * dDensity
                    if complete:
                        dgz[i] += dgzi * dDensity

        mesh.translate(pg.RVector3(p))

#    import matplotlib.pyplot as plt
#    print("times:", sum(times), np.mean(times))
#    plt.plot(times)

    if dDensity is None:
        if complete:
            return Gdg.transpose([0, 2, 1]), Gdgz.transpose([0, 2, 1])
        return Gdg
    elif hasattr(dDensity, '__len__'):
        if complete:
            dg = Gdg.transpose([0, 2, 1]).dot(dDensity)
            dgz = Gdgz.transpose([0, 2, 1]).dot(dDensity)
            return dg, dgz
        else:
            return Gdg.dot(dDensity)

    if complete:
        return dg, dgz
    return dg
Beispiel #3
0
def lineIntegralZ_WonBevis(p1, p2):
    """
    WonBevis1987.

    Returns
    -------
        g = -grad u =(Fx, 0.0, Fz), dFz(Fzx, Fzy, Fzz)
    """
    dg = pg.RVector3(0.0, 0.0, 0.0)
    dgz = pg.RVector3(0.0, 0.0, 0.0)
    pg.lineIntegralZ_WonBevis(p1, p2, dg, dgz)
    return np.asarray((dg[0], dg[1], dg[2])), np.asarray(
        (dgz[0], dgz[1], dgz[2]))

    x1 = p1[0]
    z1 = p1[1]
    x2 = p2[0]
    z2 = p2[1]

    x21 = x2 - x1
    z21 = z2 - z1
    z21s = z21 * z21
    x21s = x21 * x21

    xz12 = x1 * z2 - x2 * z1

    if x1 == 0. and z1 == 0.:
        return np.asarray((0.0, 0.0, 0.0)), np.asarray((0.0, 0.0, 0.0))
    if x2 == 0. and z2 == 0.:
        return np.asarray((0.0, 0.0, 0.0)), np.asarray((0.0, 0.0, 0.0))

    theta1 = np.arctan2(z1, x1)
    theta2 = np.arctan2(z2, x2)

    r1s = x1 * x1 + z1 * z1
    r2s = x2 * x2 + z2 * z2
    r1 = np.sqrt(r1s)
    r2 = np.sqrt(r2s)

    r21s = x21s + z21s
    R2 = r21s

    rln = np.log(r2 / r1)

    p = (xz12 / r21s) * \
        ((x1 * x21 - z1 * z21) / r1s - (x2 * x21 - z2 * z21) / r2s)
    q = (xz12 / r21s) * \
        ((x1 * z21 + z1 * x21) / r1s - (x2 * z21 + z2 * x21) / r2s)

    Fz = 0.0
    Fx = 0.0
    Fzx = 0.0  # dFz/dx
    Fzz = 0.0  # dFz/dz

    if np.sign(z1) != np.sign(z2):
        if (x1 * z2 < x2 * z1) and z2 >= 0.0:
            theta1 = theta1 + 2. * np.pi

        if (x1 * z2 > x2 * z1) and z1 >= 0.0:
            theta2 = theta2 + 2. * np.pi

    if x1 * z2 == x2 * z1:
        return np.asarray((0., 0.0, 0.)), np.asarray((0., 0.0, 0.))

    th12 = (theta1 - theta2)

    if abs(x21) < 1e-4:
        # print("case 3")
        Fz = x1 * rln
        Fx = 0.0
        Fzz = -p
        Fzx = q - z21s / r21s * rln
        # print(Zz, Zx, R2, x1, z1, x2, z2)

    else:  # default
        B = z21 / x21
        A = (x21 * xz12) / R2

        Fz = A * (th12 + B * rln)
        Fx = A * (-th12 * B + rln)
        z21dx21 = z21 / x21
#        z21x21 = z21 * x21

        fz = (th12 + z21dx21 * rln) / r21s

        Fzz = -p + x21s * fz
        Fzx = q - x21 * z21 * fz

        # // check this!!!
        # fx = (th12 * z21dx21 - rln)/r21s

    # print(np.asarray((Fx, 0.0, Fz)), np.asarray((Fzx, 0.0, Fzz)))
    return np.asarray((Fx, 0.0, Fz)), np.asarray((Fzx, 0.0, Fzz))