mirror of
https://github.com/wassname/simpeg.git
synced 2026-10-29 13:40:11 +08:00
Merge branch 'master' of https://bitbucket.org/rcockett/simpeg
This commit is contained in:
commit
f359e70662
27 files changed
+759
-230
No files matched your search
@@ -0,0 +1,205 @@
|
||||
import numpy as np
|
||||
|
||||
|
||||
class BaseMesh(object):
|
||||
"""BaseMesh does all the counting you don't want to do.
|
||||
|
||||
x0 origin ndarray (dim, )
|
||||
n number of cells ndarray (dim, )
|
||||
dim dimension of mesh int 1, 2, or 3
|
||||
|
||||
nCx num cells in x dir int
|
||||
nCy num cells in y dir int
|
||||
nCz num cells in z dir int
|
||||
nC total number of cells int
|
||||
|
||||
nNx num nodes in x dir int
|
||||
nNy num nodes in y dir int
|
||||
nNz num nodes in z dir int
|
||||
nN total number of nodes int
|
||||
|
||||
nEx num edges in x dir ndarray [nEx_x, nEx_y, nEx_z]
|
||||
nEy num edges in y dir ndarray [nEy_x, nEy_y, nEy_z]
|
||||
nEz num edges in z dir ndarray [nEz_x, nEz_y, nEz_z]
|
||||
nE total number of edges ndarray (dim, )
|
||||
|
||||
nFx num faces in x dir ndarray [nFx_x, nFx_y, nFx_z]
|
||||
nFy num faces in y dir ndarray [nFy_x, nFy_y, nFy_z]
|
||||
nFz num faces in z dir ndarray [nFz_x, nFz_y, nFz_z]
|
||||
nF total number of faces ndarray (dim, )
|
||||
|
||||
"""
|
||||
def __init__(self, n, x0=None):
|
||||
|
||||
# Check inputs
|
||||
if x0 is None:
|
||||
x0 = np.zeros(len(n))
|
||||
|
||||
if not len(n) == len(x0):
|
||||
raise Exception("Dimension mismatch. x0 != len(n)")
|
||||
|
||||
if len(n) > 3:
|
||||
raise Exception("Dimensions higher than 3 are not supported.")
|
||||
|
||||
# Ensure x0 & n are 1D vectors
|
||||
self._n = np.array(n, dtype=int).ravel()
|
||||
self._x0 = np.array(x0).ravel()
|
||||
self._dim = len(n)
|
||||
|
||||
def x0():
|
||||
doc = "Origin of the mesh"
|
||||
fget = lambda self: self._x0
|
||||
return locals()
|
||||
x0 = property(**x0())
|
||||
|
||||
def n():
|
||||
doc = "Number of Cells in each dimension (array of integers)"
|
||||
fget = lambda self: self._n
|
||||
return locals()
|
||||
n = property(**n())
|
||||
|
||||
def dim():
|
||||
doc = "The dimension of the mesh (1, 2, or 3)."
|
||||
fget = lambda self: self._dim
|
||||
return locals()
|
||||
dim = property(**dim())
|
||||
|
||||
def nCx():
|
||||
doc = "Number oc cells in the x direction"
|
||||
fget = lambda self: self.n[0]
|
||||
return locals()
|
||||
nCx = property(**nCx())
|
||||
|
||||
def nCy():
|
||||
doc = "Number of cells in the y direction"
|
||||
|
||||
def fget(self):
|
||||
if self.dim > 1:
|
||||
return self.n[1]
|
||||
else:
|
||||
return None
|
||||
return locals()
|
||||
nCy = property(**nCy())
|
||||
|
||||
def nCz():
|
||||
doc = "Number of cells in the z direction"
|
||||
|
||||
def fget(self):
|
||||
if self.dim > 2:
|
||||
return self.n[2]
|
||||
else:
|
||||
return None
|
||||
return locals()
|
||||
nCz = property(**nCz())
|
||||
|
||||
def nC():
|
||||
doc = "Total number of cells"
|
||||
fget = lambda self: np.prod(self.n)
|
||||
return locals()
|
||||
nC = property(**nC())
|
||||
|
||||
def nNx():
|
||||
doc = "Number of nodes in the x-direction"
|
||||
fget = lambda self: self.nCx + 1
|
||||
return locals()
|
||||
nNx = property(**nNx())
|
||||
|
||||
def nNy():
|
||||
doc = "Number of noes in the y-direction"
|
||||
|
||||
def fget(self):
|
||||
if self.dim > 1:
|
||||
return self.n[1] + 1
|
||||
else:
|
||||
return None
|
||||
return locals()
|
||||
nNy = property(**nNy())
|
||||
|
||||
def nNz():
|
||||
doc = "Number of nodes in the z-direction"
|
||||
|
||||
def fget(self):
|
||||
if self.dim > 2:
|
||||
return self.n[2] + 1
|
||||
else:
|
||||
return None
|
||||
return locals()
|
||||
nNz = property(**nNz())
|
||||
|
||||
def nN():
|
||||
doc = "Total number of nodes"
|
||||
fget = lambda self: self.n + 1
|
||||
return locals()
|
||||
nN = property(**nN())
|
||||
|
||||
def nEx():
|
||||
doc = "Number of x-edges"
|
||||
fget = lambda self: np.array([x for x in [self.nCx, self.nNy, self.nNz] if not x is None])
|
||||
return locals()
|
||||
nEx = property(**nEx())
|
||||
|
||||
def nEy():
|
||||
doc = "Number of y-edges"
|
||||
|
||||
def fget(self):
|
||||
if self.dim > 1:
|
||||
return np.array([x for x in [self.nNx, self.nCy, self.nNz] if not x is None])
|
||||
else:
|
||||
return None
|
||||
return locals()
|
||||
nEy = property(**nEy())
|
||||
|
||||
def nEz():
|
||||
doc = "Number of z-edges"
|
||||
|
||||
def fget(self):
|
||||
if self.dim > 2:
|
||||
return np.array([x for x in [self.nNx, self.nNy, self.nCz] if not x is None])
|
||||
else:
|
||||
return None
|
||||
return locals()
|
||||
nEz = property(**nEz())
|
||||
|
||||
def nE():
|
||||
doc = "Total number of edges"
|
||||
fget = lambda self: np.array([np.prod(x) for x in [self.nEx, self.nEy, self.nEz] if not x is None])
|
||||
return locals()
|
||||
nE = property(**nE())
|
||||
|
||||
def nFx():
|
||||
doc = "Number of x-faces"
|
||||
fget = lambda self: np.array([x for x in [self.nNx, self.nCy, self.nCz] if not x is None])
|
||||
return locals()
|
||||
nFx = property(**nFx())
|
||||
|
||||
def nFy():
|
||||
doc = "Number of y-faces"
|
||||
|
||||
def fget(self):
|
||||
if self.dim > 1:
|
||||
return np.array([x for x in [self.nCx, self.nNy, self.nCz] if not x is None])
|
||||
else:
|
||||
return None
|
||||
return locals()
|
||||
nFy = property(**nFy())
|
||||
|
||||
def nFz():
|
||||
doc = "Number of z-faces"
|
||||
|
||||
def fget(self):
|
||||
if self.dim > 2:
|
||||
return np.array([x for x in [self.nCx, self.nCy, self.nNz] if not x is None])
|
||||
else:
|
||||
return None
|
||||
return locals()
|
||||
nFz = property(**nFz())
|
||||
|
||||
def nF():
|
||||
doc = "Total number of faces in each dimension"
|
||||
fget = lambda self: np.array([np.prod(x) for x in [self.nFx, self.nFy, self.nFz] if not x is None])
|
||||
return locals()
|
||||
nF = property(**nF())
|
||||
|
||||
if __name__ == '__main__':
|
||||
m = BaseMesh([3, 2, 4])
|
||||
print m.n
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
-130
@@ -1,130 +0,0 @@
|
||||
import numpy as np
|
||||
|
||||
|
||||
class Mesh(object):
|
||||
"""docstring for Mesh"""
|
||||
def __init__(self, h):
|
||||
|
||||
if type(h) != list:
|
||||
raise Exception("Type of h must be a list variable. e.g. [5, 4, 2] or [[1,1,1],[0.5,0.5]]")
|
||||
|
||||
if np.sum([np.size(x) for x in h]) == len(h):
|
||||
# We have specified a shorthand for the mesh e.g. [5, 4, 2]
|
||||
# We will recreate the h, such that it lies on the unit cube/square/line
|
||||
domain = 1. # (must be a float)
|
||||
h = [np.ones(x)*(domain/x) for x in h]
|
||||
|
||||
dim = len(h)
|
||||
|
||||
if dim > 1 and np.all([len(np.shape(x)) > 1 and np.shape(x)[1] > 1 for x in h]):
|
||||
# The h has internal structure, and is not a vector
|
||||
# Thus, we must be describing the verticies of the mesh
|
||||
# Hence, the mesh is a Logically Orthogonal Mesh
|
||||
self.meshType = 'LOM'
|
||||
else:
|
||||
# Could add other checks, but here the default is a rectangular mesh
|
||||
self.meshType = 'RECT'
|
||||
|
||||
if self.meshType != 'LOM':
|
||||
# Ensure that the h is a numpy array, with shape: (n,)
|
||||
h = [np.array(x).ravel() for x in h]
|
||||
|
||||
# Define the number of nodes
|
||||
if self.meshType == 'LOM':
|
||||
self._nnodes = np.array(np.shape(h[0]))
|
||||
else:
|
||||
self._nnodes = np.array([len(x) for x in h]) + 1
|
||||
|
||||
self._nc = self._nnodes - 1
|
||||
self._ncells = np.prod(self._nc)
|
||||
self._h = h
|
||||
self._dim = dim
|
||||
|
||||
m = self._nnodes
|
||||
if dim == 1:
|
||||
self._nfaces = np.prod(m)
|
||||
self._nedges = np.prod(m)
|
||||
elif dim == 2:
|
||||
self._nfx = m - [0, 1]
|
||||
self._nfy = m - [1, 0]
|
||||
self._nex = m - [1, 0]
|
||||
self._ney = m - [0, 1]
|
||||
|
||||
self._nfaces = [np.prod(self.nfx), np.prod(self.nfy)]
|
||||
self._nedges = [np.prod(self.nex), np.prod(self.ney)]
|
||||
elif dim == 3:
|
||||
self._nfx = m - [0, 1, 1]
|
||||
self._nfy = m - [1, 0, 1]
|
||||
self._nfz = m - [1, 1, 0]
|
||||
self._nex = m - [1, 0, 0]
|
||||
self._ney = m - [0, 1, 0]
|
||||
self._nez = m - [0, 0, 1]
|
||||
|
||||
self._nfaces = [np.prod(self.nfx), np.prod(self.nfy), np.prod(self.nfz)]
|
||||
self._nedges = [np.prod(self.nex), np.prod(self.ney), np.prod(self.nez)]
|
||||
|
||||
def dim():
|
||||
doc = "The dimension of the mesh: 1, 2, or 3"
|
||||
fget = lambda self: self._dim
|
||||
return locals()
|
||||
dim = property(**dim())
|
||||
|
||||
def nc():
|
||||
doc = "Number of cells in each direction of the mesh"
|
||||
fget = lambda self: self._nc
|
||||
return locals()
|
||||
nc = property(**nc())
|
||||
|
||||
def ncells():
|
||||
doc = "Number of cells in the mesh"
|
||||
fget = lambda self: self._ncells
|
||||
return locals()
|
||||
ncells = property(**ncells())
|
||||
|
||||
def nfaces():
|
||||
doc = "Number of faces in each direction of the mesh"
|
||||
fget = lambda self: self._nfaces
|
||||
return locals()
|
||||
nfaces = property(**nfaces())
|
||||
|
||||
def nedges():
|
||||
doc = "Number of edges in each direction of the mesh"
|
||||
fget = lambda self: self._nedges
|
||||
return locals()
|
||||
nedges = property(**nedges())
|
||||
|
||||
def nfx():
|
||||
doc = "Number of faces in the x direction of the mesh"
|
||||
fget = lambda self: self._nfx if self.dim > 1 else None
|
||||
return locals()
|
||||
nfx = property(**nfx())
|
||||
|
||||
def nfy():
|
||||
doc = "Number of faces in the y direction of the mesh"
|
||||
fget = lambda self: self._nfy if self.dim > 1 else None
|
||||
return locals()
|
||||
nfy = property(**nfy())
|
||||
|
||||
def nfz():
|
||||
doc = "Number of faces in the z direction of the mesh"
|
||||
fget = lambda self: self._nfz if self.dim > 2 else None
|
||||
return locals()
|
||||
nfz = property(**nfz())
|
||||
|
||||
def nex():
|
||||
doc = "Number of edges in the x direction of the mesh"
|
||||
fget = lambda self: self._nex if self.dim > 1 else None
|
||||
return locals()
|
||||
nex = property(**nex())
|
||||
|
||||
def ney():
|
||||
doc = "Number of edges in the y direction of the mesh"
|
||||
fget = lambda self: self._ney if self.dim > 1 else None
|
||||
return locals()
|
||||
ney = property(**ney())
|
||||
|
||||
def nez():
|
||||
doc = "Number of edges in the z direction of the mesh"
|
||||
fget = lambda self: self._nez if self.dim > 2 else None
|
||||
return locals()
|
||||
nez = property(**nez())
|
||||
@@ -0,0 +1,144 @@
|
||||
import numpy as np
|
||||
from utils import ndgrid
|
||||
|
||||
|
||||
class TensorGrid(object):
|
||||
"""
|
||||
Define nodal, cell-centered and staggered tensor grids for 1, 2 and 3
|
||||
dimensions.
|
||||
|
||||
This class is inherited by TensorMesh
|
||||
"""
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def vectorNx():
|
||||
doc = "Nodal grid vector (1D) in the x direction."
|
||||
fget = lambda self: np.r_[0., self.hx.cumsum()] + self.x0[0]
|
||||
return locals()
|
||||
vectorNx = property(**vectorNx())
|
||||
|
||||
def vectorNy():
|
||||
doc = "Nodal grid vector (1D) in the y direction."
|
||||
fget = lambda self: None if self.dim < 2 else np.r_[0., self.hy.cumsum()] + self.x0[1]
|
||||
return locals()
|
||||
vectorNy = property(**vectorNy())
|
||||
|
||||
def vectorNz():
|
||||
doc = "Nodal grid vector (1D) in the z direction."
|
||||
fget = lambda self: None if self.dim < 3 else np.r_[0., self.hz.cumsum()] + self.x0[2]
|
||||
return locals()
|
||||
vectorNz = property(**vectorNz())
|
||||
|
||||
def vectorCCx():
|
||||
doc = "Cell-centered grid vector (1D) in the x direction."
|
||||
fget = lambda self: np.r_[0, self.hx[:-1].cumsum()] + self.hx*0.5 + self.x0[0]
|
||||
return locals()
|
||||
vectorCCx = property(**vectorCCx())
|
||||
|
||||
def vectorCCy():
|
||||
doc = "Cell-centered grid vector (1D) in the y direction."
|
||||
fget = lambda self: None if self.dim < 2 else np.r_[0, self.hy[:-1].cumsum()] + self.hy*0.5 + self.x0[1]
|
||||
return locals()
|
||||
vectorCCy = property(**vectorCCy())
|
||||
|
||||
def vectorCCz():
|
||||
doc = "Cell-centered grid vector (1D) in the z direction."
|
||||
fget = lambda self: None if self.dim < 3 else np.r_[0, self.hz[:-1].cumsum()] + self.hz*0.5 + self.x0[2]
|
||||
return locals()
|
||||
vectorCCz = property(**vectorCCz())
|
||||
|
||||
def gridCC():
|
||||
doc = "Cell-centered grid."
|
||||
|
||||
def fget(self):
|
||||
if self._gridCC is None:
|
||||
self._gridCC = ndgrid([x for x in [self.vectorCCx, self.vectorCCy, self.vectorCCz] if not x is None])
|
||||
return self._gridCC
|
||||
return locals()
|
||||
_gridCC = None # Store grid by default
|
||||
gridCC = property(**gridCC())
|
||||
|
||||
def gridN():
|
||||
doc = "Nodal grid."
|
||||
|
||||
def fget(self):
|
||||
if self._gridN is None:
|
||||
self._gridN = ndgrid([x for x in [self.vectorNx, self.vectorNy, self.vectorNz] if not x is None])
|
||||
return self._gridN
|
||||
return locals()
|
||||
_gridN = None # Store grid by default
|
||||
gridN = property(**gridN())
|
||||
|
||||
def gridFx():
|
||||
doc = "Face staggered grid in the x direction."
|
||||
|
||||
def fget(self):
|
||||
if self._gridFx is None:
|
||||
self._gridFx = ndgrid([x for x in [self.vectorNx, self.vectorCCy, self.vectorCCz] if not x is None])
|
||||
return self._gridFx
|
||||
return locals()
|
||||
_gridFx = None # Store grid by default
|
||||
gridFx = property(**gridFx())
|
||||
|
||||
def gridFy():
|
||||
doc = "Face staggered grid in the y direction."
|
||||
|
||||
def fget(self):
|
||||
if self._gridFy is None:
|
||||
self._gridFy = ndgrid([x for x in [self.vectorCCx, self.vectorNy, self.vectorCCz] if not x is None])
|
||||
return self._gridFy
|
||||
return locals()
|
||||
_gridFy = None # Store grid by default
|
||||
gridFy = property(**gridFy())
|
||||
|
||||
def gridFz():
|
||||
doc = "Face staggered grid in the z direction."
|
||||
|
||||
def fget(self):
|
||||
if self._gridFz is None:
|
||||
self._gridFz = ndgrid([x for x in [self.vectorCCx, self.vectorCCy, self.vectorNz] if not x is None])
|
||||
return self._gridFz
|
||||
return locals()
|
||||
_gridFz = None # Store grid by default
|
||||
gridFz = property(**gridFz())
|
||||
|
||||
def gridEx():
|
||||
doc = "Edge staggered grid in the x direction."
|
||||
|
||||
def fget(self):
|
||||
if self._gridEx is None:
|
||||
self._gridEx = ndgrid([x for x in [self.vectorCCx, self.vectorNy, self.vectorNz] if not x is None])
|
||||
return self._gridEx
|
||||
return locals()
|
||||
_gridEx = None # Store grid by default
|
||||
gridEx = property(**gridEx())
|
||||
|
||||
def gridEy():
|
||||
doc = "Edge staggered grid in the y direction."
|
||||
|
||||
def fget(self):
|
||||
if self._gridEy is None:
|
||||
self._gridEy = ndgrid([x for x in [self.vectorNx, self.vectorCCy, self.vectorNz] if not x is None])
|
||||
return self._gridEy
|
||||
return locals()
|
||||
_gridEy = None # Store grid by default
|
||||
gridEy = property(**gridEy())
|
||||
|
||||
def gridEz():
|
||||
doc = "Edge staggered grid in the z direction."
|
||||
|
||||
def fget(self):
|
||||
if self._gridEz is None:
|
||||
self._gridEz = ndgrid([x for x in [self.vectorNx, self.vectorNy, self.vectorCCz] if not x is None])
|
||||
return self._gridEz
|
||||
return locals()
|
||||
_gridEz = None # Store grid by default
|
||||
gridEz = property(**gridEz())
|
||||
|
||||
def getBoundaryIndex(self, gridType):
|
||||
"""Needed for faces edges and cells"""
|
||||
pass
|
||||
|
||||
def getCellNumbering(self):
|
||||
pass
|
||||
@@ -0,0 +1,82 @@
|
||||
import numpy as np
|
||||
from BaseMesh import BaseMesh
|
||||
from TensorGrid import TensorGrid
|
||||
from TensorView import TensorView
|
||||
|
||||
|
||||
class TensorMesh(BaseMesh, TensorGrid, TensorView):
|
||||
"""
|
||||
TensorMesh is a mesh class that deals with tensor product meshes.
|
||||
|
||||
Any Mesh that has a constant width along the entire axis
|
||||
such that it can defined by a single width vector, called 'h'.
|
||||
|
||||
e.g.
|
||||
|
||||
hx = np.array([1,1,1])
|
||||
hy = np.array([1,2])
|
||||
hz = np.array([1,1,1,1])
|
||||
|
||||
mesh = TensorMesh([hx, hy, hz])
|
||||
|
||||
"""
|
||||
def __init__(self, h, x0=None):
|
||||
super(TensorMesh, self).__init__(np.array([len(x) for x in h]), x0)
|
||||
|
||||
assert len(h) == len(x0), "Dimension mismatch. x0 != len(h)"
|
||||
|
||||
for i, h_i in enumerate(h):
|
||||
assert type(h_i) == np.ndarray, ("h[%i] is not a numpy array." % i)
|
||||
|
||||
# Ensure h contains 1D vectors
|
||||
self._h = [x.ravel() for x in h]
|
||||
|
||||
def h():
|
||||
doc = "h is a list containing the cell widths of the tensor mesh in each dimension."
|
||||
fget = lambda self: self._h
|
||||
return locals()
|
||||
h = property(**h())
|
||||
|
||||
def hx():
|
||||
doc = "Width of cells in the x direction"
|
||||
fget = lambda self: self._h[0]
|
||||
return locals()
|
||||
hx = property(**hx())
|
||||
|
||||
def hy():
|
||||
doc = "Width of cells in the y direction"
|
||||
fget = lambda self: None if self.dim < 2 else self._h[1]
|
||||
return locals()
|
||||
hy = property(**hy())
|
||||
|
||||
def hz():
|
||||
doc = "Width of cells in the z direction"
|
||||
fget = lambda self: None if self.dim < 3 else self._h[2]
|
||||
return locals()
|
||||
hz = property(**hz())
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
print('Welcome to tensor mesh!')
|
||||
|
||||
testDim = 1
|
||||
h1 = 0.3*np.ones((1, 7))
|
||||
h1[:, 0] = 0.5
|
||||
h1[:, -1] = 0.6
|
||||
h2 = .5 * np.ones((1, 4))
|
||||
h3 = .4 * np.ones((1, 6))
|
||||
x0 = np.zeros((3, 1))
|
||||
|
||||
if testDim == 1:
|
||||
h = [h1]
|
||||
x0 = x0[0]
|
||||
elif testDim == 2:
|
||||
h = [h1, h2]
|
||||
x0 = x0[0:2]
|
||||
else:
|
||||
h = [h1, h2, h3]
|
||||
|
||||
I = np.linspace(0, 1, 8)
|
||||
M = TensorMesh(h, x0)
|
||||
|
||||
xn = M.plotGrid()
|
||||
@@ -0,0 +1,96 @@
|
||||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
from mpl_toolkits.mplot3d import Axes3D
|
||||
|
||||
|
||||
class TensorView(object):
|
||||
"""
|
||||
Provides viewing functions for TensorMesh
|
||||
|
||||
This class is inherited by TensorMesh
|
||||
"""
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def plotImage(self, I):
|
||||
|
||||
if self.dim == 1:
|
||||
fig = plt.figure(1)
|
||||
fig.clf()
|
||||
ax = plt.subplot(111)
|
||||
if np.size(I) == self.n[0]:
|
||||
print 'cell-centered image'
|
||||
xx = self.gridCC
|
||||
ax.plot(xx[0], I, 'ro')
|
||||
elif np.size(I) == self.n[0]+1:
|
||||
print 'nodal image'
|
||||
xx = self.gridN
|
||||
ax.plot(xx[0], I, 'bs')
|
||||
|
||||
fig.show()
|
||||
|
||||
def plotGrid(self):
|
||||
"""Plot the nodal, cell-centered and staggered grids for 1,2 and 3 dimensions."""
|
||||
if self.dim == 1:
|
||||
fig = plt.figure(1)
|
||||
fig.clf()
|
||||
ax = plt.subplot(111)
|
||||
xn = self.gridN
|
||||
xc = self.gridCC
|
||||
print xn
|
||||
ax.hold(True)
|
||||
ax.plot(xn, np.ones(np.shape(xn)), 'bs')
|
||||
ax.plot(xc, np.ones(np.shape(xc)), 'ro')
|
||||
ax.plot(xn, np.ones(np.shape(xn)), 'k--')
|
||||
ax.grid(True)
|
||||
ax.hold(False)
|
||||
ax.set_xlabel('x1')
|
||||
fig.show()
|
||||
elif self.dim == 2:
|
||||
fig = plt.figure(2)
|
||||
fig.clf()
|
||||
ax = plt.subplot(111)
|
||||
xn = self.gridN
|
||||
xc = self.gridCC
|
||||
xs1 = self.gridFx
|
||||
xs2 = self.gridFy
|
||||
|
||||
ax.hold(True)
|
||||
ax.plot(xn[:, 0], xn[:, 1], 'bs')
|
||||
ax.plot(xc[:, 0], xc[:, 1], 'ro')
|
||||
ax.plot(xs1[:, 0], xs1[:, 1], 'g>')
|
||||
ax.plot(xs2[:, 0], xs2[:, 1], 'g^')
|
||||
ax.grid(True)
|
||||
ax.hold(False)
|
||||
ax.set_xlabel('x1')
|
||||
ax.set_ylabel('x2')
|
||||
fig.show()
|
||||
elif self.dim == 3:
|
||||
fig = plt.figure(3)
|
||||
fig.clf()
|
||||
ax = fig.add_subplot(111, projection='3d')
|
||||
xn = self.gridN
|
||||
xc = self.gridCC
|
||||
xfs1 = self.gridFx
|
||||
xfs2 = self.gridFy
|
||||
xfs3 = self.gridFz
|
||||
|
||||
xes1 = self.gridEx
|
||||
xes2 = self.gridEy
|
||||
xes3 = self.gridEz
|
||||
|
||||
ax.hold(True)
|
||||
ax.plot(xn[:, 0], xn[:, 1], 'bs', zs=xn[:, 2])
|
||||
ax.plot(xc[:, 0], xc[:, 1], 'ro', zs=xc[:, 2])
|
||||
ax.plot(xfs1[:, 0], xfs1[:, 1], 'g>', zs=xfs1[:, 2])
|
||||
ax.plot(xfs2[:, 0], xfs2[:, 1], 'g<', zs=xfs2[:, 2])
|
||||
ax.plot(xfs3[:, 0], xfs3[:, 1], 'g^', zs=xfs3[:, 2])
|
||||
ax.plot(xes1[:, 0], xes1[:, 1], 'k>', zs=xes1[:, 2])
|
||||
ax.plot(xes2[:, 0], xes2[:, 1], 'k<', zs=xes2[:, 2])
|
||||
ax.plot(xes3[:, 0], xes3[:, 1], 'k^', zs=xes3[:, 2])
|
||||
ax.grid(True)
|
||||
ax.hold(False)
|
||||
ax.set_xlabel('x1')
|
||||
ax.set_ylabel('x2')
|
||||
ax.set_zlabel('x3')
|
||||
fig.show()
|
||||
@@ -1,3 +0,0 @@
|
||||
# init.py
|
||||
|
||||
from test_mesh import *
|
||||
@@ -0,0 +1,11 @@
|
||||
import glob
|
||||
import unittest
|
||||
|
||||
# This code will run all tests in directory named test_*.py
|
||||
|
||||
test_file_strings = glob.glob('test_*.py')
|
||||
module_strings = [str[0:len(str)-3] for str in test_file_strings]
|
||||
suites = [unittest.defaultTestLoader.loadTestsFromName(str) for str
|
||||
in module_strings]
|
||||
testSuite = unittest.TestSuite(suites)
|
||||
text_runner = unittest.TextTestRunner().run(testSuite)
|
||||
@@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
python -m unittest discover
|
||||
@@ -0,0 +1,88 @@
|
||||
import unittest
|
||||
import sys
|
||||
sys.path.append('../')
|
||||
from BaseMesh import BaseMesh
|
||||
import numpy as np
|
||||
|
||||
|
||||
class TestBaseMesh(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.mesh = BaseMesh([6, 2, 3])
|
||||
|
||||
def test_meshDimensions(self):
|
||||
self.assertTrue(self.mesh.dim, 3)
|
||||
|
||||
def test_mesh_nc(self):
|
||||
self.assertTrue(np.all(self.mesh.n == [6, 2, 3]))
|
||||
|
||||
def test_mesh_nc_xyz(self):
|
||||
x = np.all(self.mesh.nCx == 6)
|
||||
y = np.all(self.mesh.nCy == 2)
|
||||
z = np.all(self.mesh.nCz == 3)
|
||||
|
||||
self.assertTrue(np.all([x, y, z]))
|
||||
|
||||
def test_mesh_nf(self):
|
||||
x = np.all(self.mesh.nFx == [7, 2, 3])
|
||||
y = np.all(self.mesh.nFy == [6, 3, 3])
|
||||
z = np.all(self.mesh.nFz == [6, 2, 4])
|
||||
|
||||
self.assertTrue(np.all([x, y, z]))
|
||||
|
||||
def test_mesh_ne(self):
|
||||
x = np.all(self.mesh.nEx == [6, 3, 4])
|
||||
y = np.all(self.mesh.nEy == [7, 2, 4])
|
||||
z = np.all(self.mesh.nEz == [7, 3, 3])
|
||||
|
||||
self.assertTrue(np.all([x, y, z]))
|
||||
|
||||
def test_mesh_numbers(self):
|
||||
c = self.mesh.nC == 36
|
||||
f = np.all(self.mesh.nF == [42, 54, 48])
|
||||
e = np.all(self.mesh.nE == [72, 56, 63])
|
||||
|
||||
self.assertTrue(np.all([c, f, e]))
|
||||
|
||||
|
||||
class TestMeshNumbers2D(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.mesh = BaseMesh([6, 2])
|
||||
|
||||
def test_meshDimensions(self):
|
||||
self.assertTrue(self.mesh.dim, 2)
|
||||
|
||||
def test_mesh_nc(self):
|
||||
self.assertTrue(np.all(self.mesh.n == [6, 2]))
|
||||
|
||||
def test_mesh_nc_xyz(self):
|
||||
x = np.all(self.mesh.nCx == 6)
|
||||
y = np.all(self.mesh.nCy == 2)
|
||||
z = self.mesh.nCz is None
|
||||
|
||||
self.assertTrue(np.all([x, y, z]))
|
||||
|
||||
def test_mesh_nf(self):
|
||||
x = np.all(self.mesh.nFx == [7, 2])
|
||||
y = np.all(self.mesh.nFy == [6, 3])
|
||||
z = self.mesh.nFz is None
|
||||
|
||||
self.assertTrue(np.all([x, y, z]))
|
||||
|
||||
def test_mesh_ne(self):
|
||||
x = np.all(self.mesh.nEx == [6, 3])
|
||||
y = np.all(self.mesh.nEy == [7, 2])
|
||||
z = self.mesh.nEz is None
|
||||
|
||||
self.assertTrue(np.all([x, y, z]))
|
||||
|
||||
def test_mesh_numbers(self):
|
||||
c = self.mesh.nC == 12
|
||||
f = np.all(self.mesh.nF == [14, 18])
|
||||
e = np.all(self.mesh.nE == [18, 14])
|
||||
|
||||
self.assertTrue(np.all([c, f, e]))
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
@@ -1,74 +0,0 @@
|
||||
import unittest
|
||||
import sys
|
||||
sys.path.append('../')
|
||||
from Mesh import Mesh
|
||||
import numpy as np
|
||||
|
||||
|
||||
class TestMeshNumbers3D(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.mesh = Mesh([6, 2, 3])
|
||||
|
||||
def test_meshDimensions(self):
|
||||
self.assertTrue(self.mesh.dim, 3)
|
||||
|
||||
def test_mesh_nc(self):
|
||||
self.assertTrue(np.all(self.mesh.nc == [6, 2, 3]))
|
||||
|
||||
def test_mesh_nf(self):
|
||||
x = np.all(self.mesh.nfx == [7, 2, 3])
|
||||
y = np.all(self.mesh.nfy == [6, 3, 3])
|
||||
z = np.all(self.mesh.nfz == [6, 2, 4])
|
||||
|
||||
self.assertTrue(np.all([x, y, z]))
|
||||
|
||||
def test_mesh_ne(self):
|
||||
x = np.all(self.mesh.nex == [6, 3, 4])
|
||||
y = np.all(self.mesh.ney == [7, 2, 4])
|
||||
z = np.all(self.mesh.nez == [7, 3, 3])
|
||||
|
||||
self.assertTrue(np.all([x, y, z]))
|
||||
|
||||
def test_mesh_numbers(self):
|
||||
c = self.mesh.ncells == 36
|
||||
f = np.all(self.mesh.nfaces == [42, 54, 48])
|
||||
e = np.all(self.mesh.nedges == [72, 56, 63])
|
||||
|
||||
self.assertTrue(np.all([c, f, e]))
|
||||
|
||||
|
||||
class TestMeshNumbers2D(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.mesh = Mesh([6, 2])
|
||||
|
||||
def test_meshDimensions(self):
|
||||
self.assertTrue(self.mesh.dim, 2)
|
||||
|
||||
def test_mesh_nc(self):
|
||||
self.assertTrue(np.all(self.mesh.nc == [6, 2]))
|
||||
|
||||
def test_mesh_nf(self):
|
||||
x = np.all(self.mesh.nfx == [7, 2])
|
||||
y = np.all(self.mesh.nfy == [6, 3])
|
||||
z = self.mesh.nfz is None
|
||||
|
||||
self.assertTrue(np.all([x, y, z]))
|
||||
|
||||
def test_mesh_ne(self):
|
||||
x = np.all(self.mesh.nex == [6, 3])
|
||||
y = np.all(self.mesh.ney == [7, 2])
|
||||
z = self.mesh.nez is None
|
||||
|
||||
self.assertTrue(np.all([x, y, z]))
|
||||
|
||||
def test_mesh_numbers(self):
|
||||
c = self.mesh.ncells == 12
|
||||
f = np.all(self.mesh.nfaces == [14, 18])
|
||||
e = np.all(self.mesh.nedges == [18, 14])
|
||||
|
||||
self.assertTrue(np.all([c, f, e]))
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
@@ -0,0 +1,34 @@
|
||||
import numpy as np
|
||||
import unittest
|
||||
import sys
|
||||
sys.path.append('../')
|
||||
from TensorMesh import TensorMesh
|
||||
|
||||
|
||||
class TestSequenceFunctions(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
a = np.array([1, 1, 1])
|
||||
b = np.array([1, 2])
|
||||
x0 = np.array([3, 5])
|
||||
self.mesh2 = TensorMesh([a, b], x0)
|
||||
|
||||
def test_vectorN_2D(self):
|
||||
testNx = np.array([3, 4, 5, 6])
|
||||
testNy = np.array([5, 6, 8])
|
||||
|
||||
xtest = np.all(self.mesh2.vectorNx == testNx)
|
||||
ytest = np.all(self.mesh2.vectorNy == testNy)
|
||||
self.assertTrue(xtest and ytest)
|
||||
|
||||
def test_vectorCC_2D(self):
|
||||
testNx = np.array([3.5, 4.5, 5.5])
|
||||
testNy = np.array([5.5, 7])
|
||||
|
||||
xtest = np.all(self.mesh2.vectorCCx == testNx)
|
||||
ytest = np.all(self.mesh2.vectorCCy == testNy)
|
||||
self.assertTrue(xtest and ytest)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
@@ -0,0 +1,53 @@
|
||||
import numpy as np
|
||||
import unittest
|
||||
import sys
|
||||
sys.path.append('../')
|
||||
from utils import mkvc, ndgrid
|
||||
|
||||
|
||||
class TestSequenceFunctions(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.a = np.array([1, 2, 3])
|
||||
self.b = np.array([1, 2])
|
||||
self.c = np.array([1, 2, 3, 4])
|
||||
|
||||
def test_mkvc1(self):
|
||||
x = mkvc(self.a)
|
||||
self.assertTrue(x.shape, (3,))
|
||||
|
||||
def test_mkvc2(self):
|
||||
x = mkvc(self.a, 2)
|
||||
self.assertTrue(x.shape, (3, 1))
|
||||
|
||||
def test_mkvc3(self):
|
||||
x = mkvc(self.a, 3)
|
||||
self.assertTrue(x.shape, (3, 1, 1))
|
||||
|
||||
def test_ndgrid_2D(self):
|
||||
XY = ndgrid([self.a, self.b])
|
||||
|
||||
X1_test = np.array([1, 2, 3, 1, 2, 3])
|
||||
X2_test = np.array([1, 1, 1, 2, 2, 2])
|
||||
|
||||
xtest = np.all(XY[:, 0] == X1_test)
|
||||
ytest = np.all(XY[:, 1] == X2_test)
|
||||
|
||||
self.assertTrue(xtest and ytest)
|
||||
|
||||
def test_ndgrid_3D(self):
|
||||
XYZ = ndgrid([self.a, self.b, self.c])
|
||||
|
||||
X1_test = np.array([1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3])
|
||||
X2_test = np.array([1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2])
|
||||
X3_test = np.array([1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4])
|
||||
|
||||
xtest = np.all(XYZ[:, 0] == X1_test)
|
||||
ytest = np.all(XYZ[:, 1] == X2_test)
|
||||
ztest = np.all(XYZ[:, 2] == X3_test)
|
||||
|
||||
self.assertTrue(xtest and ytest and ztest)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
+43
-23
@@ -1,4 +1,5 @@
|
||||
from numpy import *
|
||||
import numpy as np
|
||||
|
||||
|
||||
def diff(A, d):
|
||||
@@ -43,35 +44,54 @@ def ave(A, d):
|
||||
print('d must be 1,2 or 3')
|
||||
|
||||
|
||||
def reshapeF(sp, d):
|
||||
return reshape(sp, d, 'F')
|
||||
def reshapeF(x, size):
|
||||
return np.reshape(x, size, order='F')
|
||||
|
||||
|
||||
def mkvc(A):
|
||||
return reshape(A, [size(A), 1], 'F').flatten()
|
||||
def mkvc(x, numDims=1):
|
||||
"""Creates a vector with the number of dimension specified
|
||||
|
||||
e.g.:
|
||||
|
||||
a = np.array(1,2,3)
|
||||
|
||||
mkvc(a, 1).shape
|
||||
> (3, )
|
||||
|
||||
mkvc(a, 2).shape
|
||||
> (3, 1)
|
||||
|
||||
mkvc(a, 3).shape
|
||||
> (3, 1, 1)
|
||||
|
||||
"""
|
||||
assert type(x) == np.ndarray, "Vector must be a numpy array"
|
||||
|
||||
if numDims == 1:
|
||||
return x.flatten(order='F')
|
||||
elif numDims == 2:
|
||||
return x.flatten(order='F')[:, np.newaxis]
|
||||
elif numDims == 3:
|
||||
return x.flatten(order='F')[:, np.newaxis, np.newaxis]
|
||||
|
||||
|
||||
def ndgrid(x, y, z):
|
||||
def ndgrid(*args):
|
||||
"""Form tensorial grid for 1, 2 and 3 dimensions. Return X1,X2,X3 arrays depending on the dimension"""
|
||||
|
||||
n1 = size(x)
|
||||
n2 = size(y)
|
||||
n3 = size(z)
|
||||
X = zeros([n1, n2, n3])
|
||||
Y = zeros([n1, n2, n3])
|
||||
Z = zeros([n1, n2, n3])
|
||||
for i in range(0, n2):
|
||||
for j in range(0, n3):
|
||||
X[:, i, j] = x
|
||||
# you can either pass a list [x1, x2, x3] or each seperately
|
||||
if type(args[0]) == list:
|
||||
xin = args[0]
|
||||
else:
|
||||
xin = args
|
||||
|
||||
for i in range(0, n1):
|
||||
for j in range(0, n3):
|
||||
Y[i, :, j] = y
|
||||
|
||||
for i in range(0, n1):
|
||||
for j in range(0, n2):
|
||||
Z[i, j, :] = z
|
||||
|
||||
return (X, Y, Z)
|
||||
if len(xin) == 1:
|
||||
return xin
|
||||
elif len(xin) == 2:
|
||||
X2, X1 = [mkvc(x) for x in np.broadcast_arrays(mkvc(xin[1], 1), mkvc(xin[0], 2))]
|
||||
return np.c_[X1, X2]
|
||||
elif len(xin) == 3:
|
||||
X3, X2, X1 = [mkvc(x) for x in np.broadcast_arrays(mkvc(xin[2], 1), mkvc(xin[1], 2), mkvc(xin[0], 3))]
|
||||
return np.c_[X1, X2, X3]
|
||||
|
||||
|
||||
def ind2sub(shape, ind):
|
||||
|
||||
Reference in new issue
Block a user