You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
In the following discretization, $\sigma$ and $\phi$ will be discretized on the cell-centers and the flux, $j$, will be on the faces.
We will use the weak formulation to discretize the DC resistivity equation.
{: icare="<5"}
from SimPEG import *
M = Mesh.TensorMesh([10,10])
Discretizing Equation
For equation \ref{dc2} the integration with a general face function $\vec{f}$ results in:
We will first look at the left-side of this equation. The matrial property $\boldsymbol{\sigma}$ and the flux $\mathbf{j}$ live in different locations on the mesh. Therefore, we have to do some linear interpolation for $\boldsymbol{\sigma}$.
$\mathbf{A}_v^{f2cc}$ is an averaging matrix that takes you from faces to cell-centers, $\circ$ is a Hadamard product. A Hadamard product indicates point wise multiplication or equivalently:
We will use the Divergence theorem,
$\int_\Omega \nabla \cdot \mathbf{F} , dv = \oint_{\partial \Omega} \mathbf{F} \cdot \mathbf{n} , ds $,
in the last integral:
$$\left(\nabla\phi,\vec{f}\right) =
\int \nabla \phi \cdot \vec{f} dv =
Here $\mathbf{B}$ must take into account the direction of the normal (which points out of the face), so we need some $\pm1$ in the right places.
For a 1D mesh $\mathbf{B}$ would have the form:
However, we may want to enforce Neumann boundary conditions on $\mathbf{j}$, which requires a few tweaks in our matrix equations. We can do this using projection matrices!
D = M.faceDiv
Boundary conditions on $j$
Boundary conditions are often important to consider, in a DC resistivity survey we may create a domain that is sufficiently padded to assume that at the boundaries the flux into or out of the domain is zero. If this is the case, we can reduce the number of unknowns in equation \ref{dc1disc}. To illustrate the separation of the fluxes on the boundary $\mathbf{j}{bc}$ and the fluxes inside the domain $\mathbf{j}{in}$, we will use a simple 1D example.
Figure 1: Small one dimensional mesh, showing location of $\mathbf{j}$, $\boldsymbol{\sigma}$, and $\boldsymbol{\phi}$
The discretization for the divergence for this example is:
Where $h$ is the cell width, which in this case is constant and can be separated from the stencil matrix of $\pm 1$.
Notice here that we can separate out the fluxes on the boundaries.
Care needs to be taken when putting these equations together to ensure that the boundary conditions match. The natural boundary conditions that occur in this system using a cell-centered discretization are homogeneous Dirichlet ($\phi = 0 \in \partial \Omega$). In the DC resistivity problem, however, we are often interested in homogeneous Neumann boundary conditions ($j = 0 \in \partial \Omega$).
In equation \ref{discDC2} we need to make sure that the divergence that we apply on the general face function $\mathbf{f}^\top$ match those of the DC resistivity equations. Here we will rewrite the integration and make a few notes:
In this case we note that $\vec{f}\cdot\vec{n} = 0 \in \partial\Omega$ and the $\nabla\cdot\vec{f}$ must enforce the correct boundary conditions. In the discretized form this translates to using the projected divergence matrix and dropping the boundary condition term for $\boldsymbol{\phi}_{bc}$. We can plug the projected divergence matrix into equation \ref{discDC2} and rearrange to solve for $\mathbf{j}$:
Here we know $\mathbf{j}_{bc}$ is zero on all of the boundaries, so we will drop that term, and multiply on the left by a $\text{diag}(\mathbf{v})$ to make the matrix symmetric.
{:note: The matrix has a null space of a constant vector! This is expected with homogeneous Neumann boundary conditions, but we need to not forget about this when we are solving the matrix system.}
from SimPEG import *
M = Mesh.TensorMesh([60,60,10])
Pbc, Pin, Pout = M.getBCProjWF('neumann')
V = Utils.sdiag(M.vol)
Msig = M.getFaceInnerProduct()
MsigI = Utils.sdInv(Msig)
Din = M.faceDiv*Pin.T*Pin
A = V*Din*MsigI*Din.T*V
q = np.zeros(M.vnC)
q[[30,30],[20,40],5] = [-1,1]
q = -V*Utils.mkvc(q)
phi = Solver(A).solve(q)
# Plot it!
figsize(10,6)
M.plotSlice(-Din.T*phi,'F',normal='Z',view='vec')
xlim([0,1]); ylim([0,1])