mirror of
https://github.com/wassname/simpeg.git
synced 2026-06-28 08:24:06 +08:00
ef557beb84
This is under the DiffOperators class, which can be inherited with BaseMesh to any Mesh Object. Cell area and other dimension calculations are included in the TensorMesh class. Wrote unit tests for cell vol, area, and edges.
157 lines
5.3 KiB
Python
157 lines
5.3 KiB
Python
import numpy as np
|
|
from scipy import sparse
|
|
from sputils import ddx, sdiag, speye, kron3, spzeros, av
|
|
|
|
|
|
class DiffOperators(object):
|
|
"""
|
|
Class creates the differential operators that you need!
|
|
"""
|
|
def __init__(self):
|
|
raise Exception('You should use a Mesh class.')
|
|
|
|
def DIV():
|
|
doc = "Construct the 3D divergence operator on Faces."
|
|
|
|
def fget(self):
|
|
if(self._DIV is None):
|
|
# The number of cell centers in each direction
|
|
n = [x.size for x in self.h]
|
|
# Compute divergence operator on faces
|
|
dd = [ddx(x) for x in n]
|
|
if(self.dim == 1):
|
|
D = dd[0]
|
|
elif(self.dim == 2):
|
|
D1 = sparse.kron(speye(n[1]), dd[0])
|
|
D2 = sparse.kron(dd[1], speye(n[0]))
|
|
D = sparse.hstack((D1, D2), format="csr")
|
|
elif(self.dim == 3):
|
|
D1 = kron3(speye(n[2]), speye(n[1]), dd[0])
|
|
D2 = kron3(speye(n[2]), dd[1], speye(n[0]))
|
|
D3 = kron3(dd[2], speye(n[1]), speye(n[0]))
|
|
D = sparse.hstack((D1, D2, D3), format="csr")
|
|
# Compute areas of cell faces
|
|
S = self.area
|
|
# Compute cell volumes
|
|
V = self.vol
|
|
self._DIV = sdiag(1/V)*D*sdiag(S)
|
|
|
|
return self._DIV
|
|
return locals()
|
|
_DIV = None
|
|
DIV = property(**DIV())
|
|
|
|
def GRAD():
|
|
doc = "Construct the 3D nodal gradient operator."
|
|
|
|
def fget(self):
|
|
if(self._GRAD is None):
|
|
# The number of cell centers in each direction
|
|
n1 = np.size(self.hx)
|
|
n2 = np.size(self.hy)
|
|
n3 = np.size(self.hz)
|
|
|
|
# Compute lengths of cell edges
|
|
L = self.edge
|
|
|
|
# Compute divergence operator on faces
|
|
d1 = ddx(n1)
|
|
d2 = ddx(n2)
|
|
d3 = ddx(n3)
|
|
D1 = kron3(speye(n3+1), speye(n2+1), d1)
|
|
D2 = kron3(speye(n3+1), d2, speye(n1+1))
|
|
D3 = kron3(d3, speye(n2+1), speye(n1+1))
|
|
|
|
G = sparse.vstack((D1, D2, D3), format="csr")
|
|
self._GRAD = sdiag(1/L)*G
|
|
return self._GRAD
|
|
return locals()
|
|
_GRAD = None
|
|
GRAD = property(**GRAD())
|
|
|
|
def CURL():
|
|
doc = "Construct the 3D curl operator."
|
|
|
|
def fget(self):
|
|
if(self._CURL is None):
|
|
# The number of cell centers in each direction
|
|
n1 = np.size(self.hx)
|
|
n2 = np.size(self.hy)
|
|
n3 = np.size(self.hz)
|
|
|
|
# Compute lengths of cell edges
|
|
L = self.edge
|
|
|
|
# Compute areas of cell faces
|
|
S = self.area
|
|
|
|
# Compute divergence operator on faces
|
|
d1 = ddx(n1)
|
|
d2 = ddx(n2)
|
|
d3 = ddx(n3)
|
|
|
|
D32 = kron3(d3, speye(n2), speye(n1+1))
|
|
D23 = kron3(speye(n3), d2, speye(n1+1))
|
|
D31 = kron3(d3, speye(n2+1), speye(n1))
|
|
D13 = kron3(speye(n3), speye(n2+1), d1)
|
|
D21 = kron3(speye(n3+1), d2, speye(n1))
|
|
D12 = kron3(speye(n3+1), speye(n2), d1)
|
|
|
|
O1 = spzeros(np.shape(D32)[0], np.shape(D31)[1])
|
|
O2 = spzeros(np.shape(D31)[0], np.shape(D32)[1])
|
|
O3 = spzeros(np.shape(D21)[0], np.shape(D13)[1])
|
|
|
|
C = sparse.vstack((sparse.hstack((O1, -D32, D23)),
|
|
sparse.hstack((D31, O2, -D13)),
|
|
sparse.hstack((-D21, D12, O3))), format="csr")
|
|
|
|
self._CURL = sdiag(1/S)*(C*sdiag(L))
|
|
return self._CURL
|
|
return locals()
|
|
_CURL = None
|
|
CURL = property(**CURL())
|
|
|
|
def AVE_F():
|
|
doc = "Construct the 3D averaging operator on cell faces."
|
|
|
|
def fget(self):
|
|
if(self._AVE_F is None):
|
|
# The number of cell centers in each direction
|
|
n1 = np.size(self.hx)
|
|
n2 = np.size(self.hy)
|
|
n3 = np.size(self.hz)
|
|
|
|
av1 = av(n1)
|
|
av2 = av(n2)
|
|
av3 = av(n3)
|
|
|
|
self._AVE_F = sparse.hstack(kron3(speye(n3), speye(n2), av1),
|
|
kron3(speye(n3), av2, speye(n3)),
|
|
kron3(av3, speye(n2), speye(n3)), format="csr")
|
|
return self._AVE_F
|
|
return locals()
|
|
_AVE_F = None
|
|
AVE_F = property(**AVE_F())
|
|
|
|
def AVE_E():
|
|
doc = "Construct the 3D averaging operator on cell edges."
|
|
|
|
def fget(self):
|
|
if(self._AVE_E is None):
|
|
# The number of cell centers in each direction
|
|
n1 = np.size(self.hx)
|
|
n2 = np.size(self.hy)
|
|
n3 = np.size(self.hz)
|
|
|
|
av1 = av(n1)
|
|
av2 = av(n2)
|
|
av3 = av(n3)
|
|
|
|
self._AVE_E = sparse.hstack(kron3(av3, av2, speye(n1)),
|
|
kron3(av3, speye(n2), av1),
|
|
kron3(speye(n3), av2, av1), format="csr")
|
|
return self._AVE_E
|
|
return locals()
|
|
_AVE_E = None
|
|
AVE_E = property(**AVE_E())
|