mirror of
https://github.com/wassname/simpeg.git
synced 2026-06-28 12:46:09 +08:00
157 lines
5.5 KiB
Python
157 lines
5.5 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 faceDiv():
|
|
doc = "Construct the 3D Divergence operator on Faces."
|
|
|
|
def fget(self):
|
|
if(self._faceDiv is None):
|
|
# The number of cell centers in each direction
|
|
n = [hk.size for hk in self.h]
|
|
# Compute faceDivergence operator on faces
|
|
dd = [ddx(k) for k 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._faceDiv = sdiag(1/V)*D*sdiag(S)
|
|
|
|
return self._faceDiv
|
|
return locals()
|
|
_faceDiv = None
|
|
faceDiv = property(**faceDiv())
|
|
|
|
def nodalGrad():
|
|
doc = "Construct the 3D nodal gradient operator."
|
|
|
|
def fget(self):
|
|
if(self._nodalGrad 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._nodalGrad = sdiag(1/L)*G
|
|
return self._nodalGrad
|
|
return locals()
|
|
_nodalGrad = None
|
|
nodalGrad = property(**nodalGrad())
|
|
|
|
def edgeCurl():
|
|
doc = "Construct the 3D curl operator."
|
|
|
|
def fget(self):
|
|
if(self._edgeCurl 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._edgeCurl = sdiag(1/S)*(C*sdiag(L))
|
|
return self._edgeCurl
|
|
return locals()
|
|
_edgeCurl = None
|
|
edgeCurl = property(**edgeCurl())
|
|
|
|
def faceAve():
|
|
doc = "Construct the 3D averaging operator on cell faces to cell centers."
|
|
|
|
def fget(self):
|
|
if(self._faceAve 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._faceAve = sparse.hstack(kron3(speye(n3), speye(n2), av1),
|
|
kron3(speye(n3), av2, speye(n3)),
|
|
kron3(av3, speye(n2), speye(n3)), format="csr")
|
|
return self._faceAve
|
|
return locals()
|
|
_faceAve = None
|
|
faceAve = property(**faceAve())
|
|
|
|
def edgeAve():
|
|
doc = "Construct the 3D averaging operator on cell edges."
|
|
|
|
def fget(self):
|
|
if(self._edgeAve 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._edgeAve = sparse.hstack(kron3(av3, av2, speye(n1)),
|
|
kron3(av3, speye(n2), av1),
|
|
kron3(speye(n3), av2, av1), format="csr")
|
|
return self._edgeAve
|
|
return locals()
|
|
_edgeAve = None
|
|
edgeAve = property(**edgeAve())
|