def mixedBC(self, boundary, userData): """Apply mixed boundary conditions.""" if boundary.marker() != pg.MARKER_BOUND_MIXED: return 0 sourcePos = pg.center(userData['sourcePos']) k = userData['k'] r1 = boundary.center() - sourcePos # Mirror on surface at depth=0 r2 = boundary.center() - pg.RVector3(1.0, -1.0, 1.0) * sourcePos r1A = r1.abs() r2A = r2.abs() rho = 1. if self.resistivity is not None: rho = self.resistivity[boundary.leftCell().id()] n = boundary.norm() if r1A > 1e-12 and r2A > 1e-12: if (pg.besselK0(r1A * k) + pg.besselK0(r2A * k)) > 1e-12: return 1./rho * k * (r1.dot(n) / r1A * pg.besselK1(r1A * k) + r2.dot(n) / r2A * pg.besselK1(r2A * k)) /\ (pg.besselK0(r1A * k) + pg.besselK0(r2A * k)) else: return 0. else: return 0.
def uAnalytical(p, sourcePos, k): """Calculates the analytical solution for the 2.5D geoelectrical problem. Solves the 2.5D geoelectrical problem for one wave number k. It calculates the normalized (for injection current 1 A and sigma=1 S/m) potential at position p for a current injection at position sourcePos. Injection at the subsurface is recognized via mirror sources along the surface at depth=0. Parameters ---------- p : pg.Pos Position for the sought potential sourcePos : pg.Pos Current injection position. k : float Wave number Returns ------- u : float Solution u(p) """ r1A = (p - sourcePos).abs() # Mirror on surface at depth=0 r2A = (p - pg.RVector3(1.0, -1.0, 1.0) * sourcePos).abs() if r1A > 1e-12 and r2A > 1e-12: return (pg.besselK0(r1A * k) + pg.besselK0(r2A * k)) / (2.0 * np.pi) else: return 0.
def uAnalytical(p, sourcePos, k): r1A = (p - sourcePos).abs() # Mirror on surface at depth=0 r2A = (p - pg.RVector3(1.0, -1.0, 1.0) * sourcePos).abs() # need rho here!!!!!!!!!!!!!!!!!!!!!!!!!!!1 if r1A > 1e-12 and r2A > 1e-12: return (pg.besselK0(r1A * k) + pg.besselK0(r2A *k)) / (2.0 * np.pi) else: return 0.
def uAnalytical(p, sourcePos, k): r1A = (p - sourcePos).abs() # Mirror on surface at depth=0 r2A = (p - pg.RVector3(1.0, -1.0, 1.0) * sourcePos).abs() # need rho here!!!!!!!!!!!!!!!!!!!!!!!!!!!1 if r1A > 1e-12 and r2A > 1e-12: return (pg.besselK0(r1A * k) + pg.besselK0(r2A * k)) / (2.0 * np.pi) else: return 0.
def uAnalytical(self, p, sourcePos, k): """Calculate analytical potential for homogeneous halfspace using a standard sigma = 1 [S/m] that can be scaled. """ r1A = (p - sourcePos).abs() # Mirror on surface at depth=0 r2A = (p - pg.RVector3(1.0, -1.0, 1.0) * sourcePos).abs() if r1A > 1e-12 and r2A > 1e-12: return (pg.besselK0(r1A * k) + pg.besselK0(r2A * k)) / \ (2.0 * np.pi) else: return 0.
def mixedBC(boundary, userData): sourcePos = userData['sourcePos'] k = userData['k'] r1 = boundary.center() - sourcePos # Mirror on surface at depth=0 r2 = boundary.center() - pg.RVector3(1.0, -1.0, 1.0) * sourcePos r1A = r1.abs() r2A = r2.abs() n = boundary.norm() # need rho here !!!!!!!!!!!!!!!!!!!!!!!!!!!1 if r1A > 1e-12 and r2A > 1e-12: return k * ((r1.dot(n)) / r1A * pg.besselK1(r1A * k) + (r2.dot(n)) / r2A * pg.besselK1(r2A * k)) / \ (pg.besselK0(r1A * k) + pg.besselK0(r2A * k)) else: return 0.
def mixedBC(boundary, userData): """Mixed boundary conditions. Define the derivative of the analytical solution regarding the outer normal direction :math:`\vec{n}`. So we can define the value for the Neumann type Boundary conditions for the boundaries in the subsurface. """ sourcePos = userData['sourcePos'] k = userData['k'] r1 = boundary.center() - sourcePos # Mirror on surface at depth=0 r2 = boundary.center() - pg.RVector3(1.0, -1.0, 1.0) * sourcePos r1A = r1.abs() r2A = r2.abs() n = boundary.norm() if r1A > 1e-12 and r2A > 1e-12: return k * ((r1.dot(n)) / r1A * pg.besselK1(r1A * k) + (r2.dot(n)) / r2A * pg.besselK1(r2A * k)) / \ (pg.besselK0(r1A * k) + pg.besselK0(r2A * k)) else: return 0.