# &= \mathbf{u_e^T M_e} (\sigma) \mathbf{ C_{fe} \, v_f} \;\;\;\; (\vec{u} \;\textrm{on faces and} \; \vec{v} \; \textrm{on edges} ) # # **With the operators constructed below, you can compute all of the # aforementioned inner products.** # # Make basic mesh h = np.ones(10) mesh = TensorMesh([h, h, h]) sig = np.random.rand(mesh.nC) # isotropic Sig = np.random.rand(mesh.nC, 6) # anisotropic # Inner product matricies Mc = sdiag(mesh.vol * sig) # Inner product matrix (centers) # Mn = mesh.getNodalInnerProduct(sig) # Inner product matrix (nodes) (*functionality pending*) Me = mesh.getEdgeInnerProduct(sig) # Inner product matrix (edges) Mf = mesh.getFaceInnerProduct(sig) # Inner product matrix for tensor (faces) # Differential operators Gne = mesh.nodalGrad # Nodes to edges gradient mesh.setCellGradBC(['neumann', 'dirichlet', 'neumann']) # Set boundary conditions Gcf = mesh.cellGrad # Cells to faces gradient D = mesh.faceDiv # Faces to centers divergence Cef = mesh.edgeCurl # Edges to faces curl Cfe = mesh.edgeCurl.T # Faces to edges curl # EXAMPLE: (u, sig*Curl*v) fig = plt.figure(figsize=(9, 5)) ax1 = fig.add_subplot(121)
def getFDEMProblem(fdemType, comp, SrcList, freq, useMu=False, verbose=False): cs = 10.0 ncx, ncy, ncz = 0, 0, 0 npad = 8 hx = [(cs, npad, -1.3), (cs, ncx), (cs, npad, 1.3)] hy = [(cs, npad, -1.3), (cs, ncy), (cs, npad, 1.3)] hz = [(cs, npad, -1.3), (cs, ncz), (cs, npad, 1.3)] mesh = TensorMesh([hx, hy, hz], ["C", "C", "C"]) if useMu is True: mapping = [("sigma", maps.ExpMap(mesh)), ("mu", maps.IdentityMap(mesh))] else: mapping = maps.ExpMap(mesh) x = ( np.array([ np.linspace(-5.0 * cs, -2.0 * cs, 3), np.linspace(5.0 * cs, 2.0 * cs, 3) ]) + cs / 4.0 ) # don't sample right by the source, slightly off alignment from either staggered grid XYZ = utils.ndgrid(x, x, np.linspace(-2.0 * cs, 2.0 * cs, 5)) Rx0 = getattr(fdem.Rx, "Point" + comp[0]) if comp[-1] == "r": real_or_imag = "real" elif comp[-1] == "i": real_or_imag = "imag" rx0 = Rx0(XYZ, comp[1], real_or_imag) Src = [] for SrcType in SrcList: if SrcType == "MagDipole": Src.append( fdem.Src.MagDipole([rx0], frequency=freq, location=np.r_[0.0, 0.0, 0.0])) elif SrcType == "MagDipole_Bfield": Src.append( fdem.Src.MagDipole_Bfield([rx0], frequency=freq, location=np.r_[0.0, 0.0, 0.0])) elif SrcType == "CircularLoop": Src.append( fdem.Src.CircularLoop([rx0], frequency=freq, location=np.r_[0.0, 0.0, 0.0])) elif SrcType == "LineCurrent": Src.append( fdem.Src.LineCurrent( [rx0], frequency=freq, location=np.array([[0.0, 0.0, 0.0], [20.0, 0.0, 0.0]]), )) elif SrcType == "RawVec": if fdemType == "e" or fdemType == "b": S_m = np.zeros(mesh.nF) S_e = np.zeros(mesh.nE) S_m[utils.closestPoints(mesh, [0.0, 0.0, 0.0], "Fz") + np.sum(mesh.vnF[:1])] = 1e-3 S_e[utils.closestPoints(mesh, [0.0, 0.0, 0.0], "Ez") + np.sum(mesh.vnE[:1])] = 1e-3 Src.append( fdem.Src.RawVec([rx0], freq, S_m, mesh.getEdgeInnerProduct() * S_e)) elif fdemType == "h" or fdemType == "j": S_m = np.zeros(mesh.nE) S_e = np.zeros(mesh.nF) S_m[utils.closestPoints(mesh, [0.0, 0.0, 0.0], "Ez") + np.sum(mesh.vnE[:1])] = 1e-3 S_e[utils.closestPoints(mesh, [0.0, 0.0, 0.0], "Fz") + np.sum(mesh.vnF[:1])] = 1e-3 Src.append( fdem.Src.RawVec([rx0], freq, mesh.getEdgeInnerProduct() * S_m, S_e)) if verbose: print(" Fetching {0!s} problem".format((fdemType))) if fdemType == "e": survey = fdem.Survey(Src) prb = fdem.Simulation3DElectricField(mesh, sigmaMap=mapping) elif fdemType == "b": survey = fdem.Survey(Src) prb = fdem.Simulation3DMagneticFluxDensity(mesh, sigmaMap=mapping) elif fdemType == "j": survey = fdem.Survey(Src) prb = fdem.Simulation3DCurrentDensity(mesh, sigmaMap=mapping) elif fdemType == "h": survey = fdem.Survey(Src) prb = fdem.Simulation3DMagneticField(mesh, sigmaMap=mapping) else: raise NotImplementedError() prb.pair(survey) try: from pymatsolver import Pardiso prb.solver = Pardiso except ImportError: prb.solver = SolverLU # prb.solver_opts = dict(check_accuracy=True) return prb
# matricies are generally diagonal; except for in the fully anisotropic case # where the inner product matrix contains a significant number of non-diagonal # entries. # # Create a single 3D cell h = np.ones(1) mesh = TensorMesh([h, h, h]) # Define 6 constitutive parameters for the cell sig1, sig2, sig3, sig4, sig5, sig6 = 6, 5, 4, 3, 2, 1 # Isotropic case sig = sig1 * np.ones((1, 1)) sig_tensor_1 = np.diag(sig1 * np.ones(3)) Me1 = mesh.getEdgeInnerProduct(sig) # Edges inner product matrix Mf1 = mesh.getFaceInnerProduct(sig) # Faces inner product matrix # Diagonal anisotropic sig = np.c_[sig1, sig2, sig3] sig_tensor_2 = np.diag(np.array([sig1, sig2, sig3])) Me2 = mesh.getEdgeInnerProduct(sig) Mf2 = mesh.getFaceInnerProduct(sig) # Full anisotropic sig = np.c_[sig1, sig2, sig3, sig4, sig5, sig6] sig_tensor_3 = np.diag(np.array([sig1, sig2, sig3])) sig_tensor_3[(0, 1), (1, 0)] = sig4 sig_tensor_3[(0, 2), (2, 0)] = sig5 sig_tensor_3[(1, 2), (2, 1)] = sig6 Me3 = mesh.getEdgeInnerProduct(sig)
-0.5 * np.sum(xy**2, axis=1) / sig**2) # Create a tensor mesh that is sufficiently large h = 0.1 * np.ones(100) mesh = TensorMesh([h, h], 'CC') # Define center point and standard deviation sig = 1.5 # Evaluate inner-product using edge-defined discrete variables vx = fcn_x(mesh.gridEx, sig) vy = fcn_y(mesh.gridEy, sig) v = np.r_[vx, vy] Me = mesh.getEdgeInnerProduct() # Edge inner product matrix ipe = np.dot(v, Me * v) # Evaluate inner-product using face-defined discrete variables vx = fcn_x(mesh.gridFx, sig) vy = fcn_y(mesh.gridFy, sig) v = np.r_[vx, vy] Mf = mesh.getFaceInnerProduct() # Edge inner product matrix ipf = np.dot(v, Mf * v) # The analytic solution of (v, v) ipt = np.pi * sig**2
# map from centers to faces. In this case, we must impose boundary conditions # on the discrete gradient operator because it cannot use locations outside # the mesh to evaluate the gradient on the boundary. If done correctly, the # inner product is computed using an inner product matrix (:math:`\mathbf{M_f}`) # for quantities living on cell faces, e.g.: # # .. math:: # (\vec{u} , \nabla \phi) \approx \mathbf{u^T M_f G_c \phi} # # Make basic mesh h = np.ones(10) mesh = TensorMesh([h, h, h]) # Items required to perform u.T*(Me*Gn*phi) Me = mesh.getEdgeInnerProduct() # Basic inner product matrix (edges) Gn = mesh.nodalGrad # Nodes to edges gradient # Items required to perform u.T*(Mf*Gc*phi) Mf = mesh.getFaceInnerProduct() # Basic inner product matrix (faces) mesh.setCellGradBC(["neumann", "dirichlet", "neumann"]) # Set boundary conditions Gc = mesh.cellGrad # Cells to faces gradient # Plot Sparse Representation fig = plt.figure(figsize=(5, 6)) ax1 = fig.add_subplot(121) ax1.spy(Me * Gn, markersize=0.5) ax1.set_title("Me*Gn")