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]))
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
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))